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 ///////////////////////////////////////////////////////////////////////////////
New(const RTPSessionInfoForFirewallExchange & aRTPSessionInfo)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
Construct()55 void PVFirewallPacketExchanger::Construct()
56 {
57 CreateMemAllocators();
58 }
59
CreateMemAllocators()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
~PVFirewallPacketExchanger()72 PVFirewallPacketExchanger::~PVFirewallPacketExchanger()
73 {
74 DestroyMemoryAllocators();
75 }
76
DestroyMemoryAllocators()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
Allocate(PVMFSharedMediaDataPtr & aFireWallPkt,OsclSharedPtr<PVMFMediaDataImpl> & aMediaDataImpl,const int aSize)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
ComposeFirewallPacket(PVMFJitterBufferFireWallPacketFormat aFormat,uint32 aPacketCnt,PVMFPortInterface * & aRTPJitterBufferPort,PVMFSharedMediaMsgPtr & aSharedMediaMsg)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
GetRTPSessionInfo() const174 const RTPSessionInfoForFirewallExchange& PVFirewallPacketExchanger::GetRTPSessionInfo() const
175 {
176 return iRTPSessionInfoForFirewallExchange;
177 }
178
SetRTPSessionInfo(const RTPSessionInfoForFirewallExchange & aRTPSessionInfo)179 void PVFirewallPacketExchanger::SetRTPSessionInfo(const RTPSessionInfoForFirewallExchange& aRTPSessionInfo)
180 {
181 iRTPSessionInfoForFirewallExchange.ipRTPDataJitterBufferPort = aRTPSessionInfo.ipRTPDataJitterBufferPort;
182 iRTPSessionInfoForFirewallExchange.iSSRC = aRTPSessionInfo.iSSRC;
183 }
184
185 ///////////////////////////////////////////////////////////////////////////////
186 //PVFirewallPacketExchangeImpl
187 ///////////////////////////////////////////////////////////////////////////////
New(PVMFJitterBufferFireWallPacketInfo & aFireWallPacketExchangeInfo,PVMFJBEventNotifier & aEventNotifier,PVMFJitterBufferMiscObserver * aObserver)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
Construct()203 void PVFirewallPacketExchangeImpl::Construct()
204 {
205 ipDataPathLoggerFireWall = PVLogger::GetLoggerObject("PVFirewallPacketExchangeImpl");
206 }
207
~PVFirewallPacketExchangeImpl()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
SetRTPSessionInfoForFirewallExchange(const RTPSessionInfoForFirewallExchange & aRTPSessionInfo)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
InitiateFirewallPacketExchange()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
CancelFirewallPacketExchange()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
ProcessCallback(CLOCK_NOTIFICATION_INTF_TYPE aClockNotificationInterfaceType,uint32 aCallBkId,const OsclAny * aContext,PVMFStatus aStatus)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
SendFirewallPackets()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