1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 #ifndef PVMF_JB_FIREWALL_PKTS_IMPL_H_INCLUDED 19 #include "pvmf_jb_firewall_pkts_impl.h" 20 #endif 21 22 #ifndef OSCL_EXCEPTION_H_INCLUDED 23 #include "oscl_exception.h" 24 #endif 25 26 #ifndef OSCL_BIN_STREAM_H_INCLUDED 27 #include "oscl_bin_stream.h" 28 #endif 29 30 #ifndef PVMF_JB_JITTERBUFFERMISC_H_INCLUDED 31 #include "pvmf_jb_jitterbuffermisc.h" 32 #endif 33 34 /////////////////////////////////////////////////////////////////////////////// 35 //PVFirewallPacketExchanger 36 /////////////////////////////////////////////////////////////////////////////// 37 PVFirewallPacketExchanger* PVFirewallPacketExchanger::New(const RTPSessionInfoForFirewallExchange& aRTPSessionInfo) 38 { 39 int32 err = OsclErrNone; 40 PVFirewallPacketExchanger* pExchanger = NULL; 41 OSCL_TRY(err, 42 pExchanger = OSCL_NEW(PVFirewallPacketExchanger, (aRTPSessionInfo)); 43 pExchanger->Construct(); 44 ); 45 46 if (pExchanger && OsclErrNone != err) 47 { 48 OSCL_DELETE(pExchanger); 49 pExchanger = NULL; 50 } 51 52 return pExchanger; 53 } 54 55 void PVFirewallPacketExchanger::Construct() 56 { 57 CreateMemAllocators(); 58 } 59 60 void PVFirewallPacketExchanger::CreateMemAllocators() 61 { 62 ipMediaDataAlloc = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (PVMF_JITTER_BUFFER_NODE_FIREWALL_PKT_MEMPOOL_SIZE)); 63 ipMediaDataImplAlloc = OSCL_NEW(PVMFSimpleMediaBufferCombinedAlloc, (ipMediaDataAlloc)); 64 ipMediaMsgAlloc = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (PVMF_JITTER_BUFFER_NODE_FIREWALL_PKT_MEMPOOL_SIZE, PVMF_JITTER_BUFFER_NODE_MEDIA_MSG_SIZE)); 65 66 if (!(ipMediaDataAlloc && ipMediaDataImplAlloc && ipMediaMsgAlloc)) 67 { 68 OSCL_LEAVE(PVMFErrNoMemory); 69 } 70 } 71 72 PVFirewallPacketExchanger::~PVFirewallPacketExchanger() 73 { 74 DestroyMemoryAllocators(); 75 } 76 77 void PVFirewallPacketExchanger::DestroyMemoryAllocators() 78 { 79 if (ipMediaMsgAlloc) 80 { 81 OSCL_DELETE(ipMediaMsgAlloc); 82 ipMediaMsgAlloc = NULL; 83 } 84 85 if (ipMediaDataImplAlloc) 86 { 87 OSCL_DELETE(ipMediaDataImplAlloc); 88 ipMediaDataImplAlloc = NULL; 89 } 90 91 if (ipMediaDataAlloc) 92 { 93 OSCL_DELETE(ipMediaDataAlloc); 94 ipMediaDataAlloc = NULL; 95 } 96 } 97 98 bool PVFirewallPacketExchanger::Allocate(PVMFSharedMediaDataPtr& aFireWallPkt, OsclSharedPtr<PVMFMediaDataImpl>& aMediaDataImpl, const int aSize) 99 { 100 int32 err = OsclErrNone; 101 OSCL_TRY(err, 102 aMediaDataImpl = ipMediaDataImplAlloc->allocate(aSize); 103 aFireWallPkt = PVMFMediaData::createMediaData(aMediaDataImpl, 104 ipMediaMsgAlloc); 105 ); 106 if (err != OsclErrNone) 107 { 108 return false; 109 } 110 return true; 111 } 112 113 bool PVFirewallPacketExchanger::ComposeFirewallPacket(PVMFJitterBufferFireWallPacketFormat aFormat, uint32 aPacketCnt, PVMFPortInterface*& aRTPJitterBufferPort, PVMFSharedMediaMsgPtr& aSharedMediaMsg) 114 { 115 PVMFSharedMediaMsgPtr fireWallMsg; 116 PVMFSharedMediaDataPtr fireWallPkt; 117 OsclSharedPtr<PVMFMediaDataImpl> mediaDataImpl; 118 119 if (aFormat == PVMF_JB_FW_PKT_FORMAT_PV) 120 { 121 bool retval = Allocate(fireWallPkt, mediaDataImpl, PVMF_JITTER_BUFFER_NODE_MAX_FIREWALL_PKT_SIZE); 122 123 if (retval == false) 124 { 125 return retval; 126 } 127 128 fireWallPkt->setMediaFragFilledLen(0, PVMF_JITTER_BUFFER_NODE_MAX_FIREWALL_PKT_SIZE); 129 130 OsclRefCounterMemFrag refCntMemFrag; 131 mediaDataImpl->getMediaFragment(0, refCntMemFrag); 132 133 OsclMemoryFragment memFrag = refCntMemFrag.getMemFrag(); 134 OsclBinOStreamBigEndian outstream; 135 136 outstream.Attach(1, &memFrag); 137 138 outstream << aPacketCnt; 139 outstream << iRTPSessionInfoForFirewallExchange.iSSRC; 140 } 141 else 142 { 143 bool retval = Allocate(fireWallPkt, mediaDataImpl, PVMF_JITTER_BUFFER_NODE_MAX_RTP_FIREWALL_PKT_SIZE); 144 145 if (retval == false) 146 { 147 return retval; 148 } 149 150 fireWallPkt->setMediaFragFilledLen(0, PVMF_JITTER_BUFFER_NODE_MAX_RTP_FIREWALL_PKT_SIZE); 151 152 OsclRefCounterMemFrag refCntMemFrag; 153 mediaDataImpl->getMediaFragment(0, refCntMemFrag); 154 155 OsclMemoryFragment memFrag = refCntMemFrag.getMemFrag(); 156 oscl_memset(memFrag.ptr, 0, memFrag.len); 157 158 OsclBinOStreamBigEndian outstream; 159 outstream.Attach(1, &memFrag); 160 161 //Skip to start of SSRC 162 outstream.seekFromCurrentPosition(8); 163 164 //fill in the SSRC 165 outstream << iRTPSessionInfoForFirewallExchange.iSSRC; 166 } 167 168 convertToPVMFMediaMsg(aSharedMediaMsg, fireWallPkt); 169 170 aRTPJitterBufferPort = iRTPSessionInfoForFirewallExchange.ipRTPDataJitterBufferPort; 171 return true; 172 } 173 174 const RTPSessionInfoForFirewallExchange& PVFirewallPacketExchanger::GetRTPSessionInfo() const 175 { 176 return iRTPSessionInfoForFirewallExchange; 177 } 178 179 void PVFirewallPacketExchanger::SetRTPSessionInfo(const RTPSessionInfoForFirewallExchange& aRTPSessionInfo) 180 { 181 iRTPSessionInfoForFirewallExchange.ipRTPDataJitterBufferPort = aRTPSessionInfo.ipRTPDataJitterBufferPort; 182 iRTPSessionInfoForFirewallExchange.iSSRC = aRTPSessionInfo.iSSRC; 183 } 184 185 /////////////////////////////////////////////////////////////////////////////// 186 //PVFirewallPacketExchangeImpl 187 /////////////////////////////////////////////////////////////////////////////// 188 OSCL_EXPORT_REF PVFirewallPacketExchangeImpl* PVFirewallPacketExchangeImpl::New(PVMFJitterBufferFireWallPacketInfo& aFireWallPacketExchangeInfo, PVMFJBEventNotifier& aEventNotifier, PVMFJitterBufferMiscObserver* aObserver) 189 { 190 int32 err = OsclErrNone; 191 PVFirewallPacketExchangeImpl* pFirewallpacketExchangeImpl = NULL; 192 OSCL_TRY(err, 193 pFirewallpacketExchangeImpl = OSCL_NEW(PVFirewallPacketExchangeImpl, (aFireWallPacketExchangeInfo, aEventNotifier, aObserver)); 194 pFirewallpacketExchangeImpl->Construct(); 195 ); 196 if (OsclErrNone != err && pFirewallpacketExchangeImpl) 197 { 198 OSCL_DELETE(pFirewallpacketExchangeImpl); 199 } 200 return pFirewallpacketExchangeImpl; 201 } 202 203 void PVFirewallPacketExchangeImpl::Construct() 204 { 205 ipDataPathLoggerFireWall = PVLogger::GetLoggerObject("PVFirewallPacketExchangeImpl"); 206 } 207 208 OSCL_EXPORT_REF PVFirewallPacketExchangeImpl::~PVFirewallPacketExchangeImpl() 209 { 210 Oscl_Vector<PVFirewallPacketExchanger*, OsclMemAllocator>::iterator iter; 211 for (iter = iFirewallPacketExchangers.begin(); iter != iFirewallPacketExchangers.end(); iter++) 212 { 213 OSCL_DELETE(*iter); 214 *iter = NULL; 215 } 216 } 217 218 OSCL_EXPORT_REF void PVFirewallPacketExchangeImpl::SetRTPSessionInfoForFirewallExchange(const RTPSessionInfoForFirewallExchange& aRTPSessionInfo) 219 { 220 Oscl_Vector<PVFirewallPacketExchanger*, OsclMemAllocator>::const_iterator iter; 221 for (iter = iFirewallPacketExchangers.begin(); iter != iFirewallPacketExchangers.end(); ++iter) 222 { 223 if ((*iter)->GetRTPSessionInfo().ipRTPDataJitterBufferPort == aRTPSessionInfo.ipRTPDataJitterBufferPort) 224 { 225 (*iter)->SetRTPSessionInfo(aRTPSessionInfo); 226 return; 227 } 228 } 229 230 PVFirewallPacketExchanger* pFirewallPacketExchanger = PVFirewallPacketExchanger::New(aRTPSessionInfo); 231 if (pFirewallPacketExchanger) 232 iFirewallPacketExchangers.push_back(pFirewallPacketExchanger); 233 } 234 235 OSCL_EXPORT_REF PVMFStatus PVFirewallPacketExchangeImpl::InitiateFirewallPacketExchange() 236 { 237 iNumAttemptsDone = 0; 238 if (iNumAttemptsDone < iFireWallPacketExchangeInfo.iNumAttempts) 239 { 240 SendFirewallPackets(); 241 } 242 else 243 { 244 ipObserver->MediaReceivingChannelPrepared(true); 245 } 246 return PVMFSuccess; 247 } 248 249 OSCL_EXPORT_REF PVMFStatus PVFirewallPacketExchangeImpl::CancelFirewallPacketExchange() 250 { 251 if (iCallBackPending) 252 { 253 PVMFJBEventNotificationRequestInfo requestInfo(CLOCK_NOTIFICATION_INTF_TYPE_NONDECREASING, this, NULL); 254 irEventNotifier.CancelCallBack(requestInfo, iCallBackId); 255 iCallBackId = 0; 256 iCallBackPending = false; 257 } 258 iNumAttemptsDone = 0; 259 return PVMFSuccess; 260 } 261 262 void PVFirewallPacketExchangeImpl::ProcessCallback(CLOCK_NOTIFICATION_INTF_TYPE aClockNotificationInterfaceType, uint32 aCallBkId, const OsclAny* aContext, PVMFStatus aStatus) 263 { 264 OSCL_UNUSED_ARG(aClockNotificationInterfaceType); 265 OSCL_UNUSED_ARG(aContext); 266 if (PVMFSuccess == aStatus) 267 { 268 if (aCallBkId == iCallBackId) 269 { 270 iCallBackPending = false; 271 SendFirewallPackets(); 272 } 273 } 274 else 275 { 276 //Log it <Assert?> 277 } 278 } 279 280 void PVFirewallPacketExchangeImpl::SendFirewallPackets() 281 { 282 Oscl_Vector<PVFirewallPacketExchanger*, OsclMemAllocator>::iterator iter; 283 for (iter = iFirewallPacketExchangers.begin(); iter != iFirewallPacketExchangers.end(); iter++) 284 { 285 PVFirewallPacketExchanger* pFirewallpacketExchanger = *iter; 286 PVMFPortInterface* pPortInterface = NULL; 287 PVMFSharedMediaMsgPtr sharedMediaMsgPtr; 288 bool packetComposed = pFirewallpacketExchanger->ComposeFirewallPacket(iFireWallPacketExchangeInfo.iFormat, iNumAttemptsDone, pPortInterface, sharedMediaMsgPtr); 289 if (packetComposed) 290 { 291 ipObserver->MessageReadyToSend(pPortInterface, sharedMediaMsgPtr); 292 } 293 else 294 { 295 PVMF_JB_LOG_FW((0, "PVFirewallPacketExchangeImpl::SendFirewallPackets - packet composition failed")); 296 OSCL_LEAVE(PVMFErrNoResources); 297 } 298 } 299 ++iNumAttemptsDone; 300 301 if (iNumAttemptsDone < iFireWallPacketExchangeInfo.iNumAttempts) 302 { 303 PVMFJBEventNotificationRequestInfo requestInfo(CLOCK_NOTIFICATION_INTF_TYPE_NONDECREASING, this, NULL); 304 irEventNotifier.RequestCallBack(requestInfo, iFireWallPacketExchangeInfo.iServerRoundTripDelayInMS, iCallBackId); 305 iCallBackPending = true; 306 } 307 else 308 { 309 ipObserver->MediaReceivingChannelPrepared(true); 310 } 311 } 312