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 // ----------------------------------------------------------------------
19 //
20 // This Software is an original work of authorship of PacketVideo Corporation.
21 // Portions of the Software were developed in collaboration with NTT DoCoMo,
22 // Inc. or were derived from the public domain or materials licensed from
23 // third parties. Title and ownership, including all intellectual property
24 // rights in and to the Software shall remain with PacketVideo Corporation
25 // and NTT DoCoMo, Inc.
26 //
27 // -----------------------------------------------------------------------
28 /*****************************************************************************/
29 /* file name : tsc_mt.cpp */
30 /* file contents : Terminal State Control routine */
31 /* draw : '96.10.04 */
32 /*---------------------------------------------------------------------------*/
33 /* amendment */
34 /* Copyright (C) 1996 NTT DoCoMo */
35 /*****************************************************************************/
36 #include "tsc_mt.h"
37 #include "tsc_sub.h" /* Sub Routine Information Header */
38 #include "cpvh223multiplex.h"
39 #include "tsc_component.h"
40
41
42 #define TSC_FM_H263_MTE 5
43 #define TSC_FM_MAX_MTE TSC_FM_H263_MTE
44 #define FIRST_MUX_ENTRY_NUMBER TSC_FM_MAX_MTE + 1
45 #define LAST_MUX_ENTRY_NUMBER 14
46
ClearVars()47 void TSC_mt::ClearVars()
48 {
49 iToBeDeletedMuxEntryNumbers.clear();
50 iOutMtSn = 0;
51 iPendingMtSn = 0;
52 }
53
DeleteMuxEntry(uint32 aNum)54 void TSC_mt::DeleteMuxEntry(uint32 aNum)
55 {
56 iToBeDeletedMuxEntryNumbers.push_back(aNum);
57 }
58
InitVarsSession()59 void TSC_mt::InitVarsSession()
60 {
61 // Initialize available multiplex entry numbers
62 iAvailableMuxEntryNumbers.clear();
63 for (int ii = TSC_FM_MAX_MTE + 1; ii <= LAST_MUX_ENTRY_NUMBER; ii++)
64 {
65 iAvailableMuxEntryNumbers.push_back(ii);
66 }
67 iOutMtSn = 0;
68 iPendingMtSn = 0;
69 }
70
MuxTableSendComplete(uint32 sn)71 bool TSC_mt::MuxTableSendComplete(uint32 sn)
72 {
73 if ((uint32)iPendingMtSn != sn)
74 {
75 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
76 (0,
77 "TSC_mt::MuxTableSendComplete Outdated multipex entry send sn(%d), last sn(%d)",
78 sn, iPendingMtSn));
79 return false;
80 }
81 iPendingMtSn = -1;
82 return true;
83 }
84
85
CheckMtTrf(Oscl_Vector<CodecCapabilityInfo *,OsclMemAllocator> aOutCodecList,Oscl_Vector<H324ChannelParameters,PVMFTscAlloc> * aOutgoingChannelConfig)86 bool TSC_mt::CheckMtTrf(Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator> aOutCodecList,
87 Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>* aOutgoingChannelConfig)
88 {
89 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
90 (0, "TSC_mt::CheckMtTrf"));
91 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
92 (0,
93 "TSC_mt::CheckMtTrf codec list size(%d), num h223 channels(%d)",
94 aOutCodecList.size(), iH223->GetNumChannels(OUTGOING)));
95 unsigned num_channels = (aOutgoingChannelConfig) ?
96 aOutgoingChannelConfig->size() : 0;
97 num_channels = aOutCodecList.size() < num_channels ?
98 aOutCodecList.size() : num_channels;
99 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
100 (0, "TSC_mt::CheckMtTrf num opened h223 channels(%d)", num_channels));
101 return (iH223->GetNumChannels(OUTGOING) >= num_channels) ? true : false;
102 }
103
104
105 /*****************************************************************************/
106 /* function name : Tsc_MtTrfRps */
107 /* function outline : Tsc_MtTrfRps procedure */
108 /* function discription : Tsc_MtTrfRps( void ) */
109 /* input data : None */
110 /* output data : None */
111 /* draw time : '96.10.09 */
112 /*---------------------------------------------------------------------------*/
113 /* amendent career (x) : */
114 /* */
115 /* Copyright (C) 1996 NTT DoCoMo */
116 /*****************************************************************************/
MtTrfRps(uint32 sequenceNumber,PS_MuxDescriptor pMux)117 void TSC_mt::MtTrfRps(uint32 sequenceNumber, PS_MuxDescriptor pMux)
118 {
119 S_ControlMsgHeader infHeader;
120
121 Tsc_SendDataSet(&infHeader,
122 H245_PRIMITIVE,
123 E_PtvId_Mt_Trf_Rps,
124 sequenceNumber,
125 0,
126 (uint8*)pMux,
127 sizeof(S_MuxDescriptor));
128
129 // Primitive Send
130 iH245->DispatchControlMessage(&infHeader);
131
132 return;
133 }
134
135
136 /*****************************************************************************/
137 /* function name : Tsc_MtRjtReq */
138 /* function outline : Tsc_MtRjtReq procedure */
139 /* function discription : Tsc_MtRjtReq( pReceiveInf ) */
140 /* input data : PS_ControlMsgHeader */
141 /* output data : None */
142 /* draw time : '96.10.09 */
143 /*---------------------------------------------------------------------------*/
144 /* amendent career (x) : */
145 /* */
146 /* Copyright (C) 1996 NTT DoCoMo */
147 /*****************************************************************************/
MtRjtReq()148 void TSC_mt::MtRjtReq()
149 {
150 S_ControlMsgHeader infHeader;
151 S_MeRejectCause parameter;
152
153 // REJECT.request primitive - Parameter[CAUSE]
154 parameter.index = 1;
155
156 Tsc_SendDataSet(&infHeader,
157 H245_PRIMITIVE,
158 E_PtvId_Mt_Rjt_Req,
159 0,
160 0,
161 (uint8*)¶meter,
162 sizeof(S_MeRejectCause));
163
164 // Primitive Send
165 iH245->DispatchControlMessage(&infHeader);
166 }
167
GenerateCombinedDescriptor(uint8 entry_num,TPVChannelId lcn1,unsigned lcn1_size,TPVChannelId lcn2)168 CPVMultiplexEntryDescriptor* TSC_mt::GenerateCombinedDescriptor(uint8 entry_num,
169 TPVChannelId lcn1,
170 unsigned lcn1_size,
171 TPVChannelId lcn2)
172 {
173 PS_MultiplexEntryDescriptor h245_desc =
174 (PS_MultiplexEntryDescriptor)OSCL_DEFAULT_MALLOC(sizeof(S_MultiplexEntryDescriptor));
175 h245_desc->multiplexTableEntryNumber = entry_num;
176 h245_desc->option_of_elementList = true;
177 h245_desc->size_of_elementList = 2;
178
179 h245_desc->elementList =
180 (PS_MultiplexElement)OSCL_DEFAULT_MALLOC(2 * sizeof(S_MultiplexElement));
181 oscl_memset(h245_desc->elementList, 0, 2 * sizeof(S_MultiplexElement));
182 PS_MultiplexElement elem = h245_desc->elementList;
183 elem->muxType.index = 0;
184 elem->muxType.logicalChannelNumber = (uint16)lcn1;
185 elem->muxType.size = 1;
186 elem->repeatCount.index = 0;
187 elem->repeatCount.finite = (uint16)lcn1_size;
188
189 elem++;
190 elem->muxType.index = 0;
191 elem->muxType.logicalChannelNumber = (uint16)lcn2;
192 elem->muxType.size = 1;
193 elem->repeatCount.index = 1;
194 CPVMultiplexEntryDescriptor* ret = CPVMultiplexEntryDescriptor::NewL(h245_desc, 128);
195 Delete_MultiplexEntryDescriptor(h245_desc);
196 OSCL_DEFAULT_FREE(h245_desc);
197 return ret;
198 }
199
200
SendMuxTableForLcn(TPVChannelId lcn)201 uint32 TSC_mt::SendMuxTableForLcn(TPVChannelId lcn)
202 {
203 S_ControlMsgHeader infHeader;
204 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
205 (0, "TSC_mt::SendMuxTableForLcn lcn(%d)", lcn));
206 CPVMultiplexEntryDescriptorVector descriptors;
207 if (iAvailableMuxEntryNumbers.size() == 0)
208 {
209 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
210 (0, "TSC_mt::SendMuxTableForLcn Ran out of mux table entries"));
211 OSCL_LEAVE(PVMFErrNoResources);
212 }
213 int entry_num = iAvailableMuxEntryNumbers[0];
214 iAvailableMuxEntryNumbers.erase(iAvailableMuxEntryNumbers.begin());
215 CPVMultiplexEntryDescriptor* desc =
216 iTSCcomponent->GenerateSingleDescriptor((uint8)entry_num, lcn);
217 descriptors.push_back(desc);
218 iH223->SetOutgoingMuxDescriptors(descriptors);
219
220 PS_MuxDescriptor mux_descriptor =
221 (PS_MuxDescriptor)OSCL_DEFAULT_MALLOC(sizeof(S_MuxDescriptor));
222 oscl_memset(mux_descriptor, 0, sizeof(S_MuxDescriptor));
223 mux_descriptor->size_of_multiplexEntryDescriptors = 1;
224 mux_descriptor->multiplexEntryDescriptors = desc->GetH245descriptor();
225
226 Tsc_SendDataSet(&infHeader,
227 H245_PRIMITIVE,
228 E_PtvId_Mt_Trf_Req,
229 0,
230 0,
231 (uint8*)mux_descriptor,
232 sizeof(S_MuxDescriptor));
233 // Primitive Send
234 iH245->DispatchControlMessage(&infHeader);
235
236 OSCL_DEFAULT_FREE(mux_descriptor);
237 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
238 (0,
239 "TSC_mt::SendMuxTableForLcn lcn(%d), mt sn(%d), mt num(%d)",
240 lcn, iOutMtSn, entry_num));
241 return entry_num;
242 }
243
ReleaseMuxTables()244 void TSC_mt::ReleaseMuxTables()
245 {
246 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
247 (0, "TSC_mt::ReleaseMuxTable "));
248 S_ControlMsgHeader infHeader;
249 if (iToBeDeletedMuxEntryNumbers.size() == 0)
250 {
251 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
252 (0, "TSC_mt::ReleaseMuxTable No MT entries to be released"));
253 return;
254 }
255 unsigned mem_size = sizeof(S_MuxDescriptor) +
256 iToBeDeletedMuxEntryNumbers.size() * sizeof(S_MultiplexEntryDescriptor);
257 uint8* mem_ptr = (uint8*)OSCL_DEFAULT_MALLOC(mem_size);
258 if (mem_ptr == NULL)
259 {
260 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
261 (0, "TSC_mt::ReleaseMuxTable ERROR: Memory allocation failed."));
262 return;
263 }
264 oscl_memset(mem_ptr, 0, mem_size);
265 PS_MuxDescriptor mux_descriptor = (PS_MuxDescriptor)mem_ptr;
266 mux_descriptor->size_of_multiplexEntryDescriptors =
267 iToBeDeletedMuxEntryNumbers.size();
268 mux_descriptor->multiplexEntryDescriptors =
269 (PS_MultiplexEntryDescriptor)(mem_ptr + sizeof(S_MuxDescriptor));
270 for (unsigned ii = 0; ii < iToBeDeletedMuxEntryNumbers.size(); ++ii)
271 {
272 uint8 mt_num = (uint8)iToBeDeletedMuxEntryNumbers[ii];
273 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
274 (0,
275 "TSC_mt::ReleaseMuxTable Deleting Entry number=%d, sn=%d",
276 mt_num, iOutMtSn));
277 iH223->RemoveOutgoingMuxDescriptor(mt_num);
278 mux_descriptor->multiplexEntryDescriptors[ii].option_of_elementList =
279 false;
280 mux_descriptor->multiplexEntryDescriptors[ii].multiplexTableEntryNumber =
281 (int8)mt_num;
282 iAvailableMuxEntryNumbers.push_back(mt_num);
283 }
284
285 Tsc_SendDataSet(&infHeader,
286 H245_PRIMITIVE,
287 E_PtvId_Mt_Trf_Req,
288 0,
289 0,
290 (uint8*)mux_descriptor,
291 sizeof(S_MuxDescriptor));
292 // Primitive Send
293 iH245->DispatchControlMessage(&infHeader);
294 OSCL_DEFAULT_FREE(mem_ptr);
295 iPendingMtSn = iOutMtSn++;
296 iToBeDeletedMuxEntryNumbers.clear();
297 }
298
299 /**
300 * Generates and send multiplex table entries for all logical channels for which MT state is idle/pending
301 **/
MtTrfReq(OlcList & aOlcs)302 void TSC_mt::MtTrfReq(OlcList& aOlcs)
303 {
304 S_ControlMsgHeader infHeader;
305 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
306 (0, "TSC_mt::MtTrfReq"));
307 CPVMultiplexEntryDescriptorVector descriptors;
308 CPVMultiplexEntryDescriptor* desc = NULL;
309 Oscl_Vector<OlcParam*, OsclMemAllocator> olc_list;
310 unsigned num_pending = aOlcs.FindOutgoingOlcsByMtState(MT_IDLE | MT_PENDING,
311 olc_list);
312
313 if (num_pending == 0)
314 {
315 // No mux entries to send
316 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
317 (0, "TSC_mt::MtTrfReq No mux entries to send"));
318 return;
319 }
320
321 if (iAvailableMuxEntryNumbers.size() < num_pending)
322 {
323 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
324 (0,
325 "TSC_mt::MtTrfReq Ran out of mux table entries - needed(%d), have(%d)",
326 num_pending, iAvailableMuxEntryNumbers.size()));
327 OSCL_LEAVE(PVMFErrNoResources);
328 }
329
330 for (unsigned lcn = 0; lcn < num_pending; ++lcn)
331 {
332 int entry_num = iAvailableMuxEntryNumbers[0];
333 iAvailableMuxEntryNumbers.erase(iAvailableMuxEntryNumbers.begin());
334 TPVChannelId channel_id = (olc_list[lcn]->GetDirection() == OUTGOING) ?
335 olc_list[lcn]->GetChannelId() :
336 olc_list[lcn]->GetReverseParams()->GetChannelId();
337 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
338 (0, "TSC_mt::MtTrfReq Descriptor for lcn(%d)=%d", channel_id, entry_num));
339 desc = iTSCcomponent->GenerateSingleDescriptor((uint8)entry_num, channel_id);
340 descriptors.push_back(desc);
341 olc_list[lcn]->SetMtState(MT_PENDING);
342 olc_list[lcn]->SetMtSn(iOutMtSn);
343 olc_list[lcn]->SetMtNum(entry_num);
344 }
345 iH223->SetOutgoingMuxDescriptors(descriptors);
346
347 PS_MultiplexEntryDescriptor temp = NULL;
348 PS_MuxDescriptor mux_descriptor =
349 (PS_MuxDescriptor)OSCL_DEFAULT_MALLOC(sizeof(S_MuxDescriptor));
350 oscl_memset(mux_descriptor, 0, sizeof(S_MuxDescriptor));
351 mux_descriptor->size_of_multiplexEntryDescriptors = descriptors.size();
352 mux_descriptor->multiplexEntryDescriptors =
353 (PS_MultiplexEntryDescriptor)OSCL_DEFAULT_MALLOC(
354 sizeof(S_MultiplexEntryDescriptor) *
355 mux_descriptor->size_of_multiplexEntryDescriptors);
356 oscl_memset(mux_descriptor->multiplexEntryDescriptors,
357 0,
358 sizeof(S_MultiplexEntryDescriptor) *
359 mux_descriptor->size_of_multiplexEntryDescriptors);
360 PS_MultiplexEntryDescriptor cur_desc =
361 mux_descriptor->multiplexEntryDescriptors;
362 Oscl_Vector<PS_MultiplexEntryDescriptor, PVMFTscAlloc> to_be_deleted;
363
364 for (unsigned num = 0; num < descriptors.size(); ++num)
365 {
366 temp = Copy_MultiplexEntryDescriptor(
367 descriptors[num]->GetH245descriptor());
368 oscl_memcpy(cur_desc, temp, sizeof(S_MultiplexEntryDescriptor));
369 cur_desc++;
370 to_be_deleted.push_back(temp);
371 }
372
373 Tsc_SendDataSet(&infHeader,
374 H245_PRIMITIVE,
375 E_PtvId_Mt_Trf_Req,
376 0,
377 0,
378 (uint8*)mux_descriptor,
379 sizeof(S_MuxDescriptor));
380 // Primitive Send
381 iH245->DispatchControlMessage(&infHeader);
382
383 while (to_be_deleted.size())
384 {
385 PS_MultiplexEntryDescriptor desc = to_be_deleted.back();
386 Delete_MultiplexEntryDescriptor(desc);
387 OSCL_DEFAULT_FREE(desc);
388 to_be_deleted.pop_back();
389 }
390 OSCL_DEFAULT_FREE(mux_descriptor->multiplexEntryDescriptors);
391 OSCL_DEFAULT_FREE(mux_descriptor);
392
393 iPendingMtSn = iOutMtSn++;
394 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
395 (0, "TSC_mt::MtTrfReq iOutMtSn(%d)", iOutMtSn));
396 }
397