1
2 #include <string.h>
3 #include "MsCommon.h"
4
5
6 #include "hdi_121.h"
7 #include "nsk_dbg.h"
8 #include "apiDMX.h"
9 #include "nsk2hdi_header.h"
10
11
12 /*****************************************************************************\
13 \Definitions
14 \*****************************************************************************/
15 #define MDL_ECMFLT_OK 1
16 #define MDL_ECMFLT_FAIL 2
17 #define MDL_ECMFLT_INVALID_REQUEST 3
18 #define ECMFLT_TASK_STACK_SIZE 16*1024
19
20 #define ECMBufferSize 188
21
22 #define ECMDMX_BufferSize ECMBufferSize*100
23
24 #define ECMPacketArrive 0x10000
25 #define ECMBufOverFlow 0x100000
26
27 #define ECMRecvieBuf 10
28
29 #define MaximumConnection 2
30
31 #define MaximumDmxId 128
32
33 #define ECMStopFlag 0xFF
34
35 #define EcmTmpBufSize 10*1024
36
37
38 /*****************************************************************************\
39 \ local variables
40 \*****************************************************************************/
41 static MS_U8 _u8EcmFltIsInit = FALSE;
42
43 static MS_S32 _s32ECMFLTMutexId = -1;
44 static MS_S32 _s32ECMFLTEventId = -1;
45 static MS_S32 _s32ECMDFLTTaskId = -1;
46
47 static void* _pECMDFLTTaskStack;
48 //static MS_U8 _u8ECMDFLT_StackBuffer[ECMFLT_TASK_STACK_SIZE];
49
50 static MS_U16 Pids[MaximumDmxId];
51 static MS_U8 *ECMAllocBuf[MaximumDmxId];
52 static MS_U16 ECM_Connection[MaximumDmxId];
53 static MS_U8 ECMBufCnt[MaximumDmxId];
54 static MS_U8 *pECMBufBack[MaximumDmxId][ECMRecvieBuf];
55 static MS_U8 ECMFlags[MaximumDmxId][2];
56
57
58 //prepare larger buffer first...
59 static MS_U8 TmpBuf[EcmTmpBufSize];
60 static MS_U8 last_ecm_polarity[2] = {2,2};
61
62 static MS_BOOL XConnFileInFlag[2] = {FALSE,FALSE};
63 static NDS_USHORT _gecm_pid[2] = {0x0,0x0};
64
65 static MS_U32 _bEcm_log = FALSE;
66
67 static NDS_UBYTE *plastECM;
68
69
70 /*****************************************************************************\
71 \ global variables
72 \*****************************************************************************/
73
74
75 /*****************************************************************************\
76 \ local functions
77 \*****************************************************************************/
data_dump(MS_U8 * pu8Buf,MS_U32 BufSize)78 void data_dump(MS_U8* pu8Buf, MS_U32 BufSize)
79 {
80 MS_U32 i ;
81
82 for( i = 0 ; i < BufSize ; i ++ ){
83 if((i%16) == 0 ) printf("\n");
84 printf("%02X ",*(pu8Buf + i));
85 }
86 }
87
_NSK2_ECMDFLT_Isr_Proc(void)88 static void _NSK2_ECMDFLT_Isr_Proc(void)
89 {
90
91 MS_U32 u32Events;
92 MS_U8 DmxIdSect;
93 MS_U8* pu8Read;
94 MS_U8* pu8Write;
95 MS_U8 ecm_polarity;
96 MS_U8* pu8VARead;
97 MS_U32 DataLen, DataRmn;
98 MS_U8* pu8Ptr;
99 MS_U16 connection;
100
101 while (1)
102 {
103 //NSK_TRACE(("ECMDFLT_Isr_Proc wait Event\n"));
104 MsOS_WaitEvent(_s32ECMFLTEventId, 0xFFFFFFFF /*ECMFLT_STATES_GROUP*/, &u32Events, E_OR_CLEAR, MSOS_WAIT_FOREVER /*1000*/ );
105
106 //NSK_TRACE(("u32Event = %x\n",u32Events));
107 MsOS_ObtainMutex(_s32ECMFLTMutexId,MSOS_WAIT_FOREVER);
108
109
110 DmxIdSect = (u32Events & 0xff);
111 connection = ((u32Events>>8) & 0xff);
112 //NSK_TRACE(("DmxIdSect:%x, connection = %x\n",DmxIdSect,connection));
113
114 if( ECMFlags[DmxIdSect][0] == ECMStopFlag )
115 {
116 NSK_TRACE(("ECM already stop\n"));
117 goto ProcEnd;
118 }
119
120 // Get Buffer Read Pointer.
121 MApi_DMX_SectReadGet(DmxIdSect, (MS_PHY*)(&pu8Read));
122 //NSK_TRACE(("Read pointer = 0x%08lx\n", (MS_U32)pu8Read));
123
124 // Get Buffer Write Pointer.
125 MApi_DMX_SectWriteGet(DmxIdSect, (MS_PHY*)(&pu8Write));
126 //NSK_TRACE(("Write pointer = 0x%08lx\n", (MS_U32)pu8Write));
127
128
129 if ((pu8Write- pu8Read) == 0 )
130 {
131 NSK_TRACE(("\n !! No Section Get - Wait timeout \n" ));
132 }
133 else
134 {
135 //NSK_TRACE(("bytes need to be readed = %x\n",((MS_U32)pu8Write- (MS_U32)pu8Read)));
136 //memcpy(_u8ECMBuf, (void *)MsOS_PA2KSEG1((MS_U32)pu8Read), 188);
137
138 #if 1 // temp, Jeff
139 MsOS_ReadMemory();
140 //DMA_Api for user to Copy data from HW section Buffer into user data Buffer.
141 MApi_DMX_CopyData(DmxIdSect,TmpBuf,EcmTmpBufSize,&DataLen,&DataRmn,NULL);
142 #endif
143
144 //NSK_TRACE(("copy data length = %x, data remain = %x\n",DataLen,DataRmn));
145
146 if(DataRmn!=0)
147 {
148 MApi_DMX_CopyData(DmxIdSect,&TmpBuf[DataLen],EcmTmpBufSize,&DataLen,&DataRmn,NULL);
149 //NSK_TRACE(("2. copy data length = %x, data remain = %x\n",DataLen,DataRmn));
150 }
151
152 pu8VARead = (MS_U8 *)TmpBuf;
153
154 //NSK_TRACE(("first six bytes are (%x,%x,%x,%x,%x,%x)\n",pu8VARead[0],pu8VARead[1],pu8VARead[2],pu8VARead[3],pu8VARead[4],pu8VARead[5]));
155 ecm_polarity = 0;
156
157 //printf("Read[5]=%x,len=%d\n",pu8VARead[5],((MS_U32)pu8Write- (MS_U32)pu8Read) );
158 if (pu8VARead[5] == 0x80)
159 {
160 ecm_polarity = NSK2HDX_EVEN_ECM; // EVEN
161 }
162 else if (pu8VARead[5] == 0x81)
163 {
164 ecm_polarity = NSK2HDX_ODD_ECM; // ODD
165 }
166 else
167 {
168 printf("there is error at packet data,%x\n",DmxIdSect);
169 goto ProcEnd;
170 //NDS_ASSERT(FALSE, , "[%s]-[%d]\n", __FUNCTION__, __LINE__);
171 }
172
173
174 if( ECMFlags[DmxIdSect][ecm_polarity] == 0 )
175 {
176 if(last_ecm_polarity[DmxIdSect] != ecm_polarity)
177 {
178 ECMFlags[DmxIdSect][ecm_polarity] = 1;
179 last_ecm_polarity[DmxIdSect] = ecm_polarity;
180 ECMBufCnt[DmxIdSect] ++;
181
182 pu8Ptr = MApi_NSK2_AllocateMemory(180*2, TRUE /*CACHED*/);
183 if(pu8Ptr == NULL)
184 {
185 NSK_ERROR(("null pointer from allocate memory\n"));
186 continue;
187 }
188 pECMBufBack[DmxIdSect][ECMBufCnt[DmxIdSect]] = pu8Ptr;
189
190 memcpy(pu8Ptr,&pu8VARead[8],180);
191
192 //printf("call NSK2HDX_EcmArrived, conn = %x, polarity = %x, DmxIdSect = %x\n",connection,ecm_polarity,DmxIdSect);
193 //printf("call NSK2HDX_EcmArrived, conn = %x, polarity = %x, DmxIdSect = %x\n",connection,ecm_polarity,DmxIdSect);
194 //printf("polarity=%x, ",ecm_polarity);
195 //printf("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",pu8Ptr[0],pu8Ptr[1],pu8Ptr[2],pu8Ptr[3],pu8Ptr[4],pu8Ptr[5],pu8Ptr[6],pu8Ptr[7],pu8Ptr[8],pu8Ptr[9]);
196 //printf("before calling ecm arrive = %d\n",MsOS_GetSystemTime());
197 //connection needs to modify....
198 NSK2HDX_EcmArrived(connection, Pids[DmxIdSect], (NDS_UBYTE *)pu8Ptr/* RPC SIZECONST(256) */, ecm_polarity /*polarity*/);
199 //printf("end of NSK2HDX_EcmArrived\n");
200 //printf("end of calling ecm arrive = %d\n",MsOS_GetSystemTime());
201 //NSK2Util_PrintPacket(&pu8VARead[0],188);
202 }
203 }
204 }
205
206 ProcEnd:
207 MsOS_ReleaseMutex(_s32ECMFLTMutexId);
208
209 } // Task while loop
210 }
211
212
213
214 // Data callback function for event setting.
215 // Callback function inform user thread the section status.
216 // If in Polling mode, user thread need to polling filter status by themselves.
_NSK2_ECMDFLT_DataCb(MS_U8 u8DmxId,DMX_EVENT enFilterStatus)217 static void _NSK2_ECMDFLT_DataCb(MS_U8 u8DmxId, DMX_EVENT enFilterStatus)
218 {
219 MS_U8 connection;
220
221 if(enFilterStatus == DMX_EVENT_DATA_READY)
222 {
223 //MsOS_DelayTaskUs(1000);
224 connection = ECM_Connection[u8DmxId];
225 //printf("ecm buffer DATA_READY, u8DmxId = %x, connection = %x\n",u8DmxId,connection);
226 MsOS_SetEvent(_s32ECMFLTEventId, ( (u8DmxId) | (connection<<8) | ECMPacketArrive) );
227
228 //this delay is to separate the same ID cause the event error....
229 MsOS_DelayTask(1);
230 }
231 else if(enFilterStatus == DMX_EVENT_BUF_OVERFLOW)
232 {
233 printf("ecm buffer overflow\n");
234 MApi_DMX_Stop(u8DmxId);
235 MApi_DMX_Start(u8DmxId);
236 }
237 }
238
239 /*****************************************************************************\
240 \ global functions
241 \*****************************************************************************/
242
243
NSK2HDX_SetEcmLog(MS_U32 * bEn)244 MS_U32 NSK2HDX_SetEcmLog(MS_U32 *bEn)
245 {
246 _bEcm_log = *bEn;
247 return TRUE;
248 }
249
250 //use our tsp to do ecm filter...
251 //so, the function body is porting on middleware directly...
252
NSK2_ECMFLT_Init(void)253 MS_U32 NSK2_ECMFLT_Init(void)
254 {
255 //NSK_TRACE(("enter NSK2_ECMFLT_Init\n"));
256 if(_u8EcmFltIsInit == FALSE)
257 {
258 //NSK_TRACE(("CreateEventGroup\n"));
259 _s32ECMFLTEventId = MsOS_CreateEventGroup("ECMFLT_Event");
260 if (_s32ECMFLTEventId < 0)
261 {
262 NSK_ERROR(("CreateEvent fail\n"));
263 return MDL_ECMFLT_FAIL;
264 }
265 //NSK_TRACE(("_s32ECMFLTEventId = %d\n",_s32ECMFLTEventId));
266
267 _s32ECMFLTMutexId = MsOS_CreateMutex(E_MSOS_FIFO, "ECMFLT_Mutex", MSOS_PROCESS_SHARED);
268 if (_s32ECMFLTMutexId < 0)
269 {
270 NSK_ERROR(("CreateMutex fail\n"));
271 MsOS_DeleteEventGroup(_s32ECMFLTEventId);
272 return MDL_ECMFLT_FAIL;
273 }
274
275 _pECMDFLTTaskStack = MApi_NSK2_AllocateMemory(ECMFLT_TASK_STACK_SIZE, TRUE); //_u8ECMDFLT_StackBuffer;
276 if(_pECMDFLTTaskStack == NULL)
277 {
278 NSK_ERROR(("null pointer from allocate memory\n"));
279
280 return FALSE;
281 }
282 _s32ECMDFLTTaskId = MsOS_CreateTask((TaskEntry)_NSK2_ECMDFLT_Isr_Proc,
283 (MS_U32)NULL,
284 E_TASK_PRI_HIGH/*E_TASK_PRI_HIGH*/,
285 TRUE,
286 NULL,
287 ECMFLT_TASK_STACK_SIZE,
288 "ECMFLT_ISR_Task");
289 if (_s32ECMDFLTTaskId < 0)
290 {
291 NSK_ERROR(("CreateTask fail\n"));
292 MsOS_DeleteEventGroup(_s32ECMFLTEventId);
293 MsOS_DeleteMutex(_s32ECMFLTMutexId);
294 return MDL_ECMFLT_FAIL;
295 }
296 _u8EcmFltIsInit = TRUE;
297 }
298 else
299 {
300 //NSK_TRACE(("EMMFlt had been initialed\n"));
301 }
302
303
304 MS_U16 i;
305
306 for(i=0;i<MaximumDmxId;i++)
307 {
308 ECM_Connection[i]=0xff;
309 }
310
311 NSK2HDX_SetEcmHwInfo(ECMRecvieBuf);
312 return MDL_ECMFLT_OK;
313 }
314
315
NSK2HDX_RequestEcm(NDS_ULONG x_connection,NDS_USHORT ecm_pid)316 NDS_STATUS32 NSK2HDX_RequestEcm(NDS_ULONG x_connection, NDS_USHORT ecm_pid)
317 {
318 NSK_TRACE(("enxter NSK2HDX_RequestEcm\n"));
319 NSK_TRACE(("x_connection = %x, ecm_pid = %x\n",x_connection,ecm_pid));
320
321 MS_U8 pattern[16], mask[16], nmask[16];
322 MS_U8 DmxIdSect;
323 DMX_FILTER_TYPE FilterType;
324 MS_U8* pu8BufAddr;
325 DMX_Flt_info FltInfo;
326 MS_U16 u16Pid = ecm_pid;
327
328 memset(pattern,0x0,16);
329 memset(mask,0x0,16);
330 memset(nmask,0x0,16);
331
332
333 if(x_connection == 1) //file In
334 {
335 //char FileName[50]="NSK2_D_EcmFilter.mpg";
336 if(XConnFileInFlag[x_connection] == FALSE)
337 {
338 XConnFileInFlag[x_connection] = TRUE;
339 _gecm_pid[x_connection] = ecm_pid;
340 }
341 else
342 {
343 if(ecm_pid == _gecm_pid[x_connection])
344 return NSK2HDX_OK;
345 }
346
347 //FilterType = DMX_FILTER_TYPE_PACKET | DMX_FILTER_SOURCE_TYPE_FILE;
348 FilterType = MApi_NSK2_EcmGetFilterType(x_connection);
349
350 //MS_U32 pPktSize = 188;
351 //appDemo_DmxFileIn_Start(FileName,&pPktSize);
352 }
353 else //Live In if x_connection==0
354 {
355 if(XConnFileInFlag[x_connection] == FALSE)
356 {
357 XConnFileInFlag[x_connection] = TRUE;
358 _gecm_pid[x_connection] = ecm_pid;
359 }
360 else
361 {
362 if(ecm_pid == _gecm_pid[x_connection])
363 return NSK2HDX_OK;
364 }
365
366 //FilterType = DMX_FILTER_TYPE_PACKET | DMX_FILTER_SOURCE_TYPE_LIVE;
367 FilterType = MApi_NSK2_EcmGetFilterType(x_connection);
368 }
369
370
371 // Allocate a Filter and set Filter Basic Type
372 if (DMX_FILTER_STATUS_OK != MApi_DMX_Open(FilterType, &DmxIdSect))
373 {
374 NSK_ERROR(("[%s] Allocate filter fail \n",__FUNCTION__));
375 }
376
377 NSK_TRACE(("Req DmxIdSect = %x \n",DmxIdSect));
378
379 // Here we use pre-defined physical address of reserved section buffer.
380 // [Note] The section buffe MUST be continus in physical address space.(for DMA usage)
381
382 pu8BufAddr = (MS_U8*)MApi_NSK2_AllocateMemory(ECMDMX_BufferSize, FALSE);
383 if(pu8BufAddr == NULL)
384 {
385 NSK_ERROR(("null pointer from allocate memory\n"));
386 return NSK2HDX_FAIL;
387 }
388 memset(pu8BufAddr, 0 , ECMDMX_BufferSize);
389
390 // Transfer Virtual Address to Phisical Hardware Address
391 // Section buffer is structed as ring buffer, keep 4 pointer of start,end ,read and write.
392 FltInfo.Info.SectInfo.SectBufAddr = MsOS_VA2PA((MS_VIRT)pu8BufAddr);
393
394 //NSK_TRACE(("Physical Address = %08lx\n" ,FltInfo.Info.SectInfo.SectBufAddr));
395 // Set buffer size
396 FltInfo.Info.SectInfo.SectBufSize = ECMDMX_BufferSize;
397 //NSK_TRACE(("Size = %08lx\n" ,FltInfo.Info.SectInfo.SectBufSize));
398
399
400 FltInfo.Info.SectInfo.SectMode = DMX_SECT_MODE_CONTI;
401
402 // <DMX_EVENT_DATA_READY/DMX_EVENT_BUF_OVERFLOW>
403 // Event trigger condition for driver, Driver will call ap's callback < CallBack Mode Type2 >
404 FltInfo.Info.SectInfo.Event = DMX_EVENT_DATA_READY | DMX_EVENT_BUF_OVERFLOW | DMX_EVENT_CB_SELF ;
405
406 // Set the pointer of the event CB function into Demux driver
407 FltInfo.Info.SectInfo.pNotify = &_NSK2_ECMDFLT_DataCb;
408
409 // Set Advanced Filter infomation
410 if (DMX_FILTER_STATUS_OK != MApi_DMX_Info( DmxIdSect, &FltInfo, &FilterType, TRUE))
411 {
412 NSK_ERROR(("[%s] MApi_DMX_Info fail \n",__FUNCTION__));
413 }
414
415 // Set Filter PID --> Section PID
416 if (DMX_FILTER_STATUS_OK != MApi_DMX_Pid( DmxIdSect , &u16Pid , TRUE))
417 {
418 NSK_ERROR(("[%s] MApi_DMX_Pid fail \n",__FUNCTION__));
419 }
420
421 //keep PIDs, buffer.
422 Pids[DmxIdSect] = u16Pid;
423 ECMAllocBuf[DmxIdSect] = pu8BufAddr;
424
425 //printf("Alloc ECM BUF:%x \n",ECMAllocBuf[DmxIdSect]);
426 ECM_Connection[DmxIdSect] = x_connection;
427
428
429 ECMBufCnt[DmxIdSect] = 0;
430 ECMFlags[DmxIdSect][0] = ECMFlags[DmxIdSect][1] = 0;
431 last_ecm_polarity[DmxIdSect] = 2;
432
433
434
435 // Reset Section filter and section Buffer status;
436 MApi_DMX_SectReset(DmxIdSect);
437
438
439 // Set Section Match pattern
440 // The Match pattern is used for Getting specific section
441 // Pattern[16] = Pattern for match
442 // Mask[16] = Match Mask : set 1 for match / 0 for ignore
443 MApi_DMX_SectPatternSet(DmxIdSect, pattern, mask, nmask, 16);
444
445
446 // Start Filter and record section into Section Buffer.
447 if (DMX_FILTER_STATUS_OK!= MApi_DMX_Start(DmxIdSect))
448 {
449 NSK_ERROR(("enable section filter fail\n"));
450 }
451
452 NSK_TRACE(("leave NSK2HDX_RequestEcm\n"));
453
454 return NSK2HDX_OK;
455 }
456
457
NSK2HDX_StopEcm(NDS_ULONG x_connection,NDS_USHORT ecm_pid)458 NDS_STATUS32 NSK2HDX_StopEcm(NDS_ULONG x_connection, NDS_USHORT ecm_pid)
459 {
460
461 MsOS_ObtainMutex(_s32ECMFLTMutexId,MSOS_WAIT_FOREVER);
462
463 //NSK_TRACE(("enxter NSK2HDX_StopEcm\n"));
464 NSK_TRACE(("x_connection = %x, ecm_pid = %x\n",x_connection,ecm_pid));
465
466 MS_U16 DmxIdSect = 0;
467
468 MS_U16 FoundInList[0xff]={0};
469 MS_U8 Founded = 0;
470
471 XConnFileInFlag[x_connection] = FALSE;
472
473 #if 0
474 if(x_connection == 1)
475 {
476 appDemo_DmxFileIn_Stop();
477 }
478 #endif
479 //it needs to free DMX filter.......
480
481 for(DmxIdSect = 0 ; DmxIdSect<MaximumDmxId; DmxIdSect++)
482 {
483 //printf("Q_DmxIdSect:%x\n",ECM_Connection[DmxIdSect]);
484 }
485
486 for(DmxIdSect = 0 ; DmxIdSect<MaximumDmxId; DmxIdSect++)
487 {
488 //printf("Q_Pids[DmxIdSect]:%x\n",Pids[DmxIdSect]);
489 }
490
491 for(DmxIdSect = 0 ; DmxIdSect<MaximumDmxId; DmxIdSect++)
492 {
493 if ((ECM_Connection[DmxIdSect] == x_connection) && (ecm_pid == Pids[DmxIdSect]))
494 {
495 ECM_Connection[DmxIdSect] = 0xff;
496 FoundInList[DmxIdSect] = 1;
497 Founded = 1;
498 NSK_TRACE(("DmxIdSect found is = %d\n",DmxIdSect));
499 break;
500 }
501 }
502
503
504 if(Founded == 0)
505 {
506 NSK_ERROR(("can't find pid to stop\n"));
507 MsOS_ReleaseMutex(_s32ECMFLTMutexId);
508 return NSK2HDX_INVALID_REQUEST;
509 }
510 else
511 {
512 NSK_TRACE(("DmxIdSect = %x\n",DmxIdSect));
513 }
514
515
516 for(DmxIdSect = 0 ; DmxIdSect<MaximumDmxId; DmxIdSect++)
517 {
518 if( FoundInList[DmxIdSect] == 1)
519 {
520 // Stop Filter
521 MApi_DMX_Stop(DmxIdSect);
522 MApi_DMX_Close(DmxIdSect);
523
524 Pids[DmxIdSect] = 0xffff;
525
526 // Free Filter.
527 //MApi_DMX_Close(DmxIdSect);
528
529 Pids[DmxIdSect] = 0xffff;
530 ECMBufCnt[DmxIdSect] = 0;
531 ECMFlags[DmxIdSect][0] = ECMFlags[DmxIdSect][1] = ECMStopFlag;
532
533 //free allocate buffer...Jeff, need to implement
534 //MsOS_FreeMemory((MS_U8*)ECMAllocBuf[DmxIdSect], gs32NonCachedPoolID);
535 }
536
537 }
538 NSK_TRACE(("leave NSK2HDX_StopEcm\n"));
539
540 MsOS_ReleaseMutex(_s32ECMFLTMutexId);
541
542 return NSK2HDX_OK;
543 }
NSK2HDX_EcmProcessingFinished(NDS_USHORT ecm_pid,NDS_UBYTE * ecm_buf,NDS_UBYTE polarity)544 NDS_STATUS32 NSK2HDX_EcmProcessingFinished(NDS_USHORT ecm_pid, NDS_UBYTE *ecm_buf/* RPC SIZECONST(256) */, NDS_UBYTE polarity)
545 {
546 NSK_TRACE(("ecm_buf = 0x%p, ecm_pid = 0x%x, polarity = 0x%x\n",ecm_buf,ecm_pid,polarity));
547
548 MS_U8 DmxIdSect = 0;
549 MS_U8 i,found_in_list;
550
551 found_in_list=0;
552 //it needs to free DMX filter.......
553
554 for(DmxIdSect = 0 ; DmxIdSect<MaximumDmxId; DmxIdSect++)
555 {
556 for(i=0;i<ECMRecvieBuf;i++)
557 {
558 if(ecm_buf == pECMBufBack[DmxIdSect][i])
559 {
560 pECMBufBack[DmxIdSect][i] = 0;
561 found_in_list = 1;
562 break;
563 }
564 }
565 if(found_in_list == 1)
566 {
567 break;
568 }
569 }
570
571
572 //printf("Free DmxIdSect:%x\n",DmxIdSect);
573
574 ECMBufCnt[DmxIdSect] --;
575 ECMFlags[DmxIdSect][polarity] = 0;
576
577 if(plastECM != ecm_buf) //patch double release bug of verifier lib, 2014Dec15
578 MApi_NSK2_FreeMemory(ecm_buf, TRUE);
579
580 plastECM = ecm_buf;
581
582 NSK_TRACE(("leave NSK2HDX_EcmProcessingFinished\n"));
583
584 return NSK2HDX_OK;
585 }
586