DSMCC  17.9.0
 All Data Structures Files Functions Typedefs
dsm_control.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2004 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
24 /*---includes for this file--------------------------------------------------*/
25 #include <string.h>
26 #include <stdlib.h>
27 
28 #include "stb_os.h"
29 
30 #include "cldsmcc.h"
31 #ifndef NDEBUG
32 #include "cldsmdbg.h"
33 #endif
34 #include "dsfm.h"
35 #include "dsiq.h"
36 #include "sbm.h"
37 #include "stbsipmt.h"
38 #include "dm_debug.h"
39 #include "dsm_control.h"
40 #include "dsm_main.h"
41 #include "dsm_si.h"
42 #include "dsmcc_version.h"
43 
44 /*---constant definitions for this file--------------------------------------*/
45 
46 #define MAIN_STACK_SIZE 0x2000
47 #define TIMER_RESOLUTION 100
48 #define RESTART_TIME 200
49 
50 #define START_MAGIC 0xDEED
51 #define CLDSM_MAGIC 0xBADE
52 #define ERA_BITS 4
53 #define ERA_SHIFT (32 - ERA_BITS)
54 #define ERA_LAST ((1 << ERA_BITS) - 1)
55 #define ERA_FIRST 0x00
56 
57 #if defined(NDEBUG) && !defined(DSM_DBG_MASK)
58 #define DSM_DBG_MASK 0
59 #endif
60 
61 #define GETENV_DSMDBG(mskitem) \
62  strcpy(mskptr,#mskitem); \
63  value = getenv(envname); \
64  if (value != NULL) { \
65  if (atoi(value) == 1) mask |= mskitem; \
66  else mask &= ~mskitem; }
67 
68 /*---local typedef structs for this file-------------------------------------*/
69 
70 typedef enum
71 {
72  QP_TOP,
73  QP_HIGH,
74  QP_LOW,
75  QP_TOTAL
76 } E_Q_PRIORITY;
77 
78 typedef enum
79 {
80  DSM_MSG_PAT_DATA,
81  DSM_MSG_PMT_DATA = 0x02,
82  /* above items are equal to Table ID,
83  * and below start with values above max Table Id */
84  DSM_MSG_NEW_SECTION = 0x100,
85  DSM_MSG_CACHE_SECTION,
86  DSM_MSG_UPDATE_FILTER,
87  DSM_MSG_PMT_REMOVED,
88  DSM_MSG_CLOSE_DOWN
89 } E_DsmMsgType;
90 
91 typedef enum
92 {
93  BL_WAITING,
94  BL_BOOTING,
95  BL_LOADED,
96  BL_FAILED
97 } E_STATUS;
98 
99 typedef struct s_PmtInfo
100 {
101  U16BIT xid;
102  U8BIT version;
103  U8BIT reserved;
104 } S_TableInfo;
105 
106 typedef struct s_DsmMessage
107 {
108  E_DsmMsgType type;
109  U8BIT *pSection;
110  union
111  {
112  void *hBuffer;
113  S_TableInfo tinfo;
114  } u;
115 } S_Message;
116 
117 typedef struct s_timer
118 {
119  struct s_timer *next;
120  U32BIT trigger;
121  U_PARAM handle;
122  U_PARAM usrData;
123 } S_Timer;
124 
125 typedef struct s_msgqueue
126 {
127  void *mutex;
128  S_Message *begin;
129  S_Message *write;
130  S_Message *read;
131  S_Message *ends;
132 } S_MsgQueue;
133 
134 typedef struct s_DsmControl
135 {
136  S_DsmApi api;
137 
138  void *timerMtx;
139  void *task;
140  void *q_count_sema;
141 
142  S_MsgQueue queues[QP_TOTAL];
143  S_Timer *timers;
144 
145  H_DsmControl next;
146  H_SiqInstance siq;
147  H_SfmInstance sfm;
148  H_SbmInstance sbm;
149  H_DsiInstance dsi;
150 
151 #ifndef NDEBUG
152  U32BIT debugMask;
153 #endif
154  H_DsmCarousel carousel;
155  U32BIT couId;
156  U32BIT restart;
157  U16BIT counter;
158 
159  U16BIT transId;
160  U16BIT networkId;
161  U16BIT serviceId;
162 
163  U8BIT sikind;
164  U8BIT status;
165  DMXREF dmxref;
166 } S_DsmControl;
167 
168 /*---local (static) variable declarations for this file----------------------*/
169 /* (internal variables declared static to make them local) */
170 
171 #ifndef NDEBUG
172 unsigned int gDebugState = DSM_DBG_MASK;
173 #endif
174 
175 S_DsmControl *instanceHead = NULL;
176 
177 static BOOLEAN DsmStart( H_DsmControl dsmctrl, U16BIT serviceId, U32BIT couId, U8BIT sikind );
178 static void DsmRestart( H_DsmControl dsmctrl, U16BIT serviceId );
179 
180 /*------------------- Local function definitions ----------------------------*/
181 
182 static BOOLEAN QueueWrite( S_MsgQueue *queue, S_Message *pmsg )
183 {
184  BOOLEAN result;
185  S_Message *next;
186  STB_OSMutexLock(queue->mutex);
187  next = queue->write;
188  next++;
189  if (next == queue->ends)
190  {
191  next = queue->begin;
192  }
193  if (next == queue->read)
194  {
195  result = FALSE;
196  }
197  else
198  {
199  *(queue->write) = *pmsg;
200  queue->write = next;
201  result = TRUE;
202  }
203  STB_OSMutexUnlock(queue->mutex);
204  return result;
205 }
206 
207 static BOOLEAN QueueRead( S_MsgQueue *queue, S_Message *pmsg )
208 {
209  BOOLEAN result;
210  S_Message *next;
211  STB_OSMutexLock(queue->mutex);
212  if (queue->read == queue->write)
213  {
214  result = FALSE;
215  }
216  else
217  {
218  next = queue->read;
219  *pmsg = *next;
220  next++;
221  if (next == queue->ends)
222  {
223  next = queue->begin;
224  }
225  queue->read = next;
226  result = TRUE;
227  }
228  STB_OSMutexUnlock(queue->mutex);
229  return result;
230 }
231 
232 static U16BIT CheckTimers( S_DsmControl *dsmctrl, U32BIT now )
233 {
234  S_Timer *pTimer;
235  U16BIT restartid;
236  U16BIT timeout;
237  U8BIT era;
238  restartid = 0;
239  era = now >> ERA_SHIFT;
240  timeout = TIMEOUT_NEVER;
241  switch (era)
242  {
243  case ERA_LAST:
244  STB_OSMutexLock(dsmctrl->timerMtx);
245  pTimer = dsmctrl->timers;
246  while (pTimer != NULL && pTimer->trigger <= now &&
247  (pTimer->trigger >> ERA_SHIFT) != ERA_FIRST)
248  {
249  dsmctrl->timers = pTimer->next;
250  STB_OSMutexUnlock(dsmctrl->timerMtx);
251  if ((pTimer->handle.u32 >> 16) == CLDSM_MAGIC)
252  {
253  STB_OSMutexLock(dsmctrl->api.mutex);
254  CDSM_SysProcessTimerEvent(dsmctrl->api.cldsm, pTimer->usrData.ptr, TIMER_TRIGGERED, pTimer->handle.ptr);
255  STB_OSMutexUnlock(dsmctrl->api.mutex);
256  }
257  else if ((pTimer->handle.u32 >> 16) == START_MAGIC)
258  {
259  restartid = pTimer->usrData.u16;
260  }
261  dsmctrl->api.memFree(pTimer);
262  STB_OSMutexLock(dsmctrl->timerMtx);
263  pTimer = dsmctrl->timers;
264  }
265  STB_OSMutexUnlock(dsmctrl->timerMtx);
266  if (pTimer != NULL)
267  {
268  timeout = (U16BIT)((S32BIT)pTimer->trigger - (S32BIT)now);
269  }
270  break;
271 
272  case ERA_FIRST:
273  STB_OSMutexLock(dsmctrl->timerMtx);
274  pTimer = dsmctrl->timers;
275  while (pTimer != NULL &&
276  (pTimer->trigger <= now || (pTimer->trigger >> ERA_SHIFT) == ERA_LAST))
277  {
278  dsmctrl->timers = pTimer->next;
279  STB_OSMutexUnlock(dsmctrl->timerMtx);
280  if ((pTimer->handle.u32 >> 16) == CLDSM_MAGIC)
281  {
282  STB_OSMutexLock(dsmctrl->api.mutex);
283  CDSM_SysProcessTimerEvent(dsmctrl->api.cldsm, pTimer->usrData.ptr, TIMER_TRIGGERED, pTimer->handle.ptr);
284  STB_OSMutexUnlock(dsmctrl->api.mutex);
285  }
286  else if ((pTimer->handle.u32 >> 16) == START_MAGIC)
287  {
288  restartid = pTimer->usrData.u16;
289  }
290  dsmctrl->api.memFree(pTimer);
291  STB_OSMutexLock(dsmctrl->timerMtx);
292  pTimer = dsmctrl->timers;
293  }
294  STB_OSMutexUnlock(dsmctrl->timerMtx);
295  if (pTimer != NULL)
296  {
297  timeout = (U16BIT)(pTimer->trigger - now);
298  }
299  break;
300 
301  default:
302  STB_OSMutexLock(dsmctrl->timerMtx);
303  pTimer = dsmctrl->timers;
304  while (pTimer != NULL && pTimer->trigger <= now)
305  {
306  dsmctrl->timers = pTimer->next;
307  STB_OSMutexUnlock(dsmctrl->timerMtx);
308  if ((pTimer->handle.u32 >> 16) == CLDSM_MAGIC)
309  {
310  STB_OSMutexLock(dsmctrl->api.mutex);
311  CDSM_SysProcessTimerEvent(dsmctrl->api.cldsm, pTimer->usrData.ptr, TIMER_TRIGGERED, pTimer->handle.ptr);
312  STB_OSMutexUnlock(dsmctrl->api.mutex);
313  }
314  else if ((pTimer->handle.u32 >> 16) == START_MAGIC)
315  {
316  restartid = pTimer->usrData.u16;
317  }
318  dsmctrl->api.memFree(pTimer);
319  STB_OSMutexLock(dsmctrl->timerMtx);
320  pTimer = dsmctrl->timers;
321  }
322  STB_OSMutexUnlock(dsmctrl->timerMtx);
323  if (pTimer != NULL)
324  {
325  timeout = (U16BIT)(pTimer->trigger - now);
326  }
327  }
328  if (restartid != 0)
329  {
330  DsmRestart(dsmctrl, (U16BIT)restartid);
331  }
332  return timeout;
333 }
334 
335 static void DsmMain(void *arg)
336 {
337  S_DsmControl *dsmctrl = (S_DsmControl *)arg;
338  S_MsgQueue *queues = dsmctrl->queues;
339  void *apimutex = dsmctrl->api.mutex;
340  S_Message msg;
341  U32BIT si_time, now;
342  U16BIT sema_timeout;
343  BOOLEAN closing = FALSE;
344 
345  FUNCTION_START(DsmMain);
346 
347  sema_timeout = TIMEOUT_NEVER;
348  si_time = 0xFFFFFFFF;
349 
350  while (!closing)
351  {
352  if (STB_OSSemaphoreWaitTimeout(dsmctrl->q_count_sema, sema_timeout))
353  {
354  if (QueueRead(queues + QP_TOP, &msg) ||
355  QueueRead(queues + QP_HIGH, &msg) ||
356  QueueRead(queues + QP_LOW, &msg))
357  {
358  switch (msg.type)
359  {
360  case DSM_MSG_PAT_DATA:
361  {
362  STB_OSMutexLock(apimutex);
363  SIQ_UpdatePat( dsmctrl->siq, msg.pSection );
364  STB_OSMutexUnlock(apimutex);
365  SBM_ReleaseBuffer( dsmctrl->sbm, msg.pSection );
366  if (dsmctrl->dsi)
367  {
368  if (dsmctrl->status == (U8BIT)BL_WAITING)
369  {
370  DsmStart( dsmctrl, dsmctrl->serviceId, dsmctrl->couId, dsmctrl->sikind );
371  }
372  si_time = DSI_CheckRequests( dsmctrl->dsi, STB_OSGetClockMilliseconds());
373  }
374  break;
375  }
376  case DSM_MSG_PMT_DATA:
377  {
378  H_SiqPmtTable table;
379  table = SIQ_ParsePmt( dsmctrl->siq, msg.pSection );
380  SBM_ReleaseBuffer( dsmctrl->sbm, msg.pSection );
381  STB_OSMutexLock(apimutex);
382  SIQ_ProcessPmt( dsmctrl->siq, table, msg.u.tinfo.xid, msg.u.tinfo.version );
383  STB_OSMutexUnlock(apimutex);
384  if (dsmctrl->dsi)
385  {
386  si_time = DSI_CheckRequests( dsmctrl->dsi, STB_OSGetClockMilliseconds());
387  }
388  break;
389  }
390  case DSM_MSG_PMT_REMOVED:
391  {
392  STB_OSMutexLock(apimutex);
393  SIQ_ServiceRemoved( dsmctrl->siq, msg.u.tinfo.xid );
394  STB_OSMutexUnlock(apimutex);
395  break;
396  }
397  case DSM_MSG_NEW_SECTION:
398  case DSM_MSG_CACHE_SECTION:
399  {
400  STB_OSMutexLock(apimutex);
401  SFM_ProcessSection( dsmctrl->sfm, msg.pSection, msg.u.hBuffer );
402  STB_OSMutexUnlock(apimutex);
403  if (msg.type == DSM_MSG_NEW_SECTION)
404  {
405  SBM_ReleaseBuffer( dsmctrl->sbm, msg.pSection );
406  }
407  break;
408  }
409  case DSM_MSG_UPDATE_FILTER:
410  {
411  SFM_FilterUpdate( dsmctrl->sfm, msg.u.hBuffer );
412  break;
413  }
414  case DSM_MSG_CLOSE_DOWN:
415  closing = TRUE;
416  }
417  }
418  }
420  if (now > si_time)
421  {
422  ASSERT(dsmctrl->dsi);
423  si_time = DSI_CheckRequests( dsmctrl->dsi, now );
424  }
425  sema_timeout = CheckTimers(dsmctrl, now);
426  if (now + sema_timeout > si_time)
427  {
428  sema_timeout = (U16BIT)(si_time - now);
429  }
430  }
431  /* flush queues */
432  while (STB_OSSemaphoreWaitTimeout( dsmctrl->q_count_sema, 0 ))
433  {
434  if (QueueRead(queues + QP_TOP, &msg) ||
435  QueueRead(queues + QP_HIGH, &msg) ||
436  QueueRead(queues + QP_LOW, &msg))
437  {
438  switch (msg.type)
439  {
440  case DSM_MSG_NEW_SECTION:
441  case DSM_MSG_PMT_DATA:
442  case DSM_MSG_PAT_DATA:
443  {
444  SBM_ReleaseBuffer( dsmctrl->sbm, msg.pSection );
445  break;
446  }
447  case DSM_MSG_PMT_REMOVED:
448  case DSM_MSG_CACHE_SECTION:
449  case DSM_MSG_CLOSE_DOWN:
450  case DSM_MSG_UPDATE_FILTER:
451  {
452  break;
453  }
454  }
455  }
456  }
457  dsmctrl->task = NULL;
458  FUNCTION_FINISH(DsmMain);
459 }
460 
461 static void ProcessPmt( S_DsmControl *dsmctrl, U16BIT serviceId, U8BIT *pmt )
462 {
463  S_Message msg;
464  U16BIT len;
465  if (pmt == NULL)
466  {
467  msg.type = DSM_MSG_PMT_REMOVED;
468  msg.u.tinfo.xid = serviceId;
469  if (!QueueWrite(dsmctrl->queues + QP_TOP, &msg))
470  {
471  ERRPRINT("failed to add to Q")
472  }
473  else
474  {
475  STB_OSSemaphoreSignal(dsmctrl->q_count_sema);
476  }
477  }
478  else if (SIQ_RequirePmt(dsmctrl->siq, pmt, &msg.u.tinfo.xid, &msg.u.tinfo.version) == SIQ_UPDATE)
479  {
480  ASSERT(msg.u.tinfo.xid == serviceId);
481  msg.pSection = SBM_AllocateBuffer( dsmctrl->sbm, pmt[1] );
482  if (msg.pSection == NULL)
483  {
484  ERRPRINT("failed to alloc buffer")
485  }
486  else
487  {
488  msg.type = DSM_MSG_PMT_DATA;
489  len = ((pmt[1] << 8 | pmt[2]) & 0xfff) + 3;
490  memcpy(msg.pSection, pmt, len);
491  if (!QueueWrite(dsmctrl->queues + QP_TOP, &msg))
492  {
493  ERRPRINT("failed to add to Q")
494  SBM_ReleaseBuffer( dsmctrl->sbm, msg.pSection );
495  }
496  else
497  {
498  STB_OSSemaphoreSignal(dsmctrl->q_count_sema);
499  }
500  }
501  }
502 }
503 
504 static void DvbPmtCallback( U16BIT serviceId, U8BIT *pmt )
505 {
506  S_DsmControl *dsmctrl;
507  FUNCTION_START(UpdateFilter)
508  dsmctrl = instanceHead;
509  while (dsmctrl != NULL)
510  {
511  if (dsmctrl->status != (U8BIT)BL_WAITING &&
512  dsmctrl->dsi == NULL && dsmctrl->siq && dsmctrl->task)
513  {
514  /* This instance is using pmt updates from DVB */
515  ProcessPmt(dsmctrl, serviceId, pmt);
516  }
517  dsmctrl = dsmctrl->next;
518  }
519  FUNCTION_FINISH(UpdateFilter)
520 }
521 
522 static BOOLEAN UsingPmtsFromDvb( void )
523 {
524  S_DsmControl *dsmctrl;
525  FUNCTION_START(UsingPmtsFromDvb)
526  dsmctrl = instanceHead;
527  while (dsmctrl != NULL)
528  {
529  if (dsmctrl->dsi == NULL)
530  {
531  /* This instance is using pmt updates from DVB */
532  return TRUE;
533  }
534  dsmctrl = dsmctrl->next;
535  }
536  FUNCTION_FINISH(UsingPmtsFromDvb)
537  return FALSE;
538 }
539 
540 static void ProcessDsi( DMXREF demux, U16BIT nbytes, PIDFILT pfid )
541 {
542  S_Message emsg;
543  S_DsmControl *dsmctrl;
544  U8BIT header[SECTION_HEADER_LENGTH];
545  U16BIT sectionLen;
546  if (STB_DMXCopyPIDFilterSect(demux, header, SECTION_HEADER_LENGTH, pfid))
547  {
548  sectionLen = (((header[1] & 0x0F) << 8) | header[2]) + 3;
549  if (nbytes != sectionLen)
550  {
551  ERRPRINT("Length mis-match for section (bytes=%#x != data1=%#x,data2=%#x)",
552  nbytes, header[1], header[2] )
553  }
554  else
555  {
556  dsmctrl = instanceHead;
557  while (dsmctrl != NULL)
558  {
559  if (dsmctrl->dsi != NULL && demux == dsmctrl->dmxref)
560  {
561  if (DSI_RequireTable(dsmctrl->dsi, header, &emsg.u.tinfo.xid, &emsg.u.tinfo.version))
562  {
563  emsg.type = (E_DsmMsgType)*header;
564  emsg.pSection = SBM_AllocateBuffer( dsmctrl->sbm, header[1] );
565  if (emsg.pSection == NULL)
566  {
567  ERRPRINT("failed to alloc buffer")
568  }
569  else
570  {
571  if (!STB_DMXCopyPIDFilterSect(demux, emsg.pSection, sectionLen, pfid) ||
572  !QueueWrite(dsmctrl->queues + QP_TOP, &emsg))
573  {
574  ERRPRINT("failed to add to Q")
575  SBM_ReleaseBuffer( dsmctrl->sbm, emsg.pSection );
576  }
577  else
578  {
579  STB_OSSemaphoreSignal(dsmctrl->q_count_sema);
580  }
581  }
582  }
583  }
584  dsmctrl = dsmctrl->next;
585  }
586  }
587  }
588 }
589 
603 static void ProcessSection( DMXREF demux, U16BIT nbytes, PIDFILT pfid )
604 {
605  S_Message emsg;
606  E_SFM_STATUS status;
607  S_MsgQueue *queue;
608  S_DsmControl *dsmctrl;
609  U8BIT header[SECTION_HEADER_LENGTH];
610  U16BIT sectionLen;
611  FUNCTION_START(ProcessSection)
612  if (STB_DMXCopyPIDFilterSect(demux, header, SECTION_HEADER_LENGTH, pfid))
613  {
614  sectionLen = (((header[1] & 0x0F) << 8) | header[2]) + 3;
615  if (*header < 0x3B || *header > 0x3D)
616  {
617  ERRPRINT("Bad table id=0x%x", *header)
618  }
619  else if (nbytes < sectionLen)
620  {
621  ERRPRINT("Demux not providing enough bytes for section (bytes=%#x != data1=%#x,data2=%#x)",
622  nbytes, header[1], header[2] )
623  }
624  else
625  {
626  dsmctrl = instanceHead;
627  while (dsmctrl != NULL)
628  {
629  if (demux == dsmctrl->dmxref)
630  {
631  status = SFM_RequireSection( dsmctrl->sfm, pfid, header, &emsg.u.hBuffer );
632  switch (status)
633  {
634  case SFM_UPDATE_CACHE:
635  emsg.pSection = SFM_CacheBuffer( dsmctrl->sfm, emsg.u.hBuffer );
636  if (emsg.pSection == NULL)
637  {
638  ERRPRINT("SFM_CacheBuffer failed for %#x", emsg.u.hBuffer)
639  }
640  else
641  {
642  STB_DMXCopyPIDFilterSect(demux, emsg.pSection, sectionLen, pfid);
643  if (nbytes != sectionLen && CDSM_UtilCalculateCRC(emsg.pSection, sectionLen))
644  {
645  SFM_CacheReleaseBuffer( dsmctrl->sfm, emsg.pSection, emsg.u.hBuffer );
646  }
647  }
648  /* fall through */
649 
650  case SFM_ERROR:
651  case SFM_IGNORE:
652  queue = NULL;
653  break;
654 
655  case SFM_UPDATE_LOW:
656  queue = &dsmctrl->queues[QP_LOW];
657  break;
658 
659  case SFM_UPDATE_HIGH:
660  queue = &dsmctrl->queues[QP_HIGH];
661  break;
662  }
663  if (queue != NULL)
664  {
665  emsg.pSection = SBM_AllocateBuffer( dsmctrl->sbm, header[1] );
666  if (emsg.pSection == NULL)
667  {
668  ERRPRINT("Memory failure for size=%#x", sectionLen)
669  }
670  else
671  {
672  emsg.type = DSM_MSG_NEW_SECTION;
673  if (!STB_DMXCopyPIDFilterSect(demux, emsg.pSection, sectionLen, pfid) ||
674  (nbytes != sectionLen && CDSM_UtilCalculateCRC(emsg.pSection, sectionLen)) ||
675  !QueueWrite(queue, &emsg))
676  {
677  SBM_ReleaseBuffer( dsmctrl->sbm, emsg.pSection );
678  }
679  else
680  {
681  STB_OSSemaphoreSignal(dsmctrl->q_count_sema);
682  }
683  }
684  }
685  }
686  dsmctrl = dsmctrl->next;
687  }
688  }
689  }
690  FUNCTION_FINISH(ProcessSection)
691 }
692 
705 static void CacheMatch( H_SfmInstance sfm, U8BIT *pSection,
706  void *hBuffer, E_SFM_STATUS status )
707 {
708  S_Message emsg;
709  S_DsmControl *dsmctrl;
710  FUNCTION_START(CacheMatch)
711  dsmctrl = instanceHead;
712  while (dsmctrl != NULL)
713  {
714  if (dsmctrl->sfm == sfm)
715  {
716  emsg.pSection = pSection;
717  emsg.u.hBuffer = hBuffer;
718  emsg.type = DSM_MSG_CACHE_SECTION;
719  switch (status)
720  {
721  default:
722  break;
723 
724  case SFM_UPDATE_LOW:
725  if (!QueueWrite(dsmctrl->queues + QP_LOW, &emsg))
726  {
727  ERRPRINT("")
728  }
729  else
730  {
731  STB_OSSemaphoreSignal(dsmctrl->q_count_sema);
732  }
733  break;
734 
735  case SFM_UPDATE_HIGH:
736  if (!QueueWrite(dsmctrl->queues + QP_HIGH, &emsg))
737  {
738  ERRPRINT("")
739  }
740  else
741  {
742  STB_OSSemaphoreSignal(dsmctrl->q_count_sema);
743  }
744  break;
745  }
746  break;
747  }
748  dsmctrl = dsmctrl->next;
749  }
750  FUNCTION_FINISH(CacheMatch)
751 }
752 
761 static void UpdateFilter( H_SfmInstance sfm, H_DmxPidFilter hPF )
762 {
763  S_Message emsg;
764  S_DsmControl *dsmctrl;
765  FUNCTION_START(UpdateFilter)
766  dsmctrl = instanceHead;
767  while (dsmctrl != NULL)
768  {
769  if (dsmctrl->sfm == sfm)
770  {
771  emsg.pSection = NULL;
772  emsg.u.hBuffer = hPF;
773  emsg.type = DSM_MSG_UPDATE_FILTER;
774  if (!QueueWrite(dsmctrl->queues + QP_TOP, &emsg))
775  {
776  ERRPRINT("")
777  }
778  else
779  {
780  STB_OSSemaphoreSignal(dsmctrl->q_count_sema);
781  }
782  break;
783  }
784  dsmctrl = dsmctrl->next;
785  }
786  FUNCTION_FINISH(UpdateFilter)
787 }
788 
789 U32BIT StubRequestTable( void *pmtref, U16BIT pid, U16BIT xid, U8BIT tid )
790 {
791  return 0x55000000 | (U32BIT)(tid << 16) | xid;
792 }
793 
794 static void StubCancelTable( void *ref, U32BIT rid )
795 {
796 }
797 
802 static H_SiqInstance CreateSiq( S_DsmccConfig *config, void *pmtref )
803 {
804  S_SiqSetup setup;
805 
806  setup.memAlloc = config->memAlloc;
807  setup.memFree = config->memFree;
808 
809  if (!(config->controlFlags & GET_PMT_DIRECT_FROM_HW_FLAG))
810  {
811  setup.dvpRequestTable = StubRequestTable;
812  setup.dvpCancelTable = StubCancelTable;
813  if (!UsingPmtsFromDvb())
814  {
815  STB_SIRegisterPmtObserver( DvbPmtCallback );
816  }
817  }
818  else
819  {
820  setup.dvpRequestTable = (F_DvpRequestTable)DSI_RequestTable;
821  setup.dvpCancelTable = (F_DvpCancelTable)DSI_CancelTable;
822  }
823  setup.pmtref = pmtref;
824 
825  setup.parsePmtInit = config->parsePmtInit;
826  setup.parsePmtDone = config->parsePmtDone;
827  setup.parseDataBroadcastId = config->parseDataBroadcastId;
828  setup.parseSsuSelectorBytes = config->parseSsuSelectorBytes;
829 
830  setup.notifyAitInfo = config->notifyAitInfo;
831 
832 #ifndef NDEBUG
833  setup.errPrintf = (F_Printf)STB_SPDebugNoCnWrite;
834  if (gDebugState & DS_ALL)
835  {
836  setup.dbgPrintf = (F_Printf)STB_SPDebugNoCnWrite;
837  setup.dbgState = gDebugState & DS_ALL;
838  }
839  else
840 #endif
841  {
842  #if DSM_DP_LEVEL >= 2
843  setup.dbgPrintf = (F_Printf)STB_SPDebugNoCnWrite;
844  #else
845  setup.dbgPrintf = DBG_DebugPrintf;
846  #endif
847  setup.dbgState = 0;
848  }
849 
850  return SIQ_CreateInstance( &setup );
851 }
852 
857 static void DestroySiq( H_SiqInstance siq )
858 {
859  SIQ_DestroyInstance( siq );
860 }
861 
866 static H_SfmInstance CreateSfm( S_DsmccConfig *config )
867 {
868  S_SfmSetup setup;
869  H_SfmInstance sfm;
870 
871  setup.sfmMutex = STB_OSCreateMutex();
872  if (setup.sfmMutex == NULL)
873  {
874  ERRPRINT("")
875  sfm = NULL;
876  }
877  else
878  {
879  setup.cacheMutex = STB_OSCreateMutex();
880  if (setup.cacheMutex == NULL)
881  {
882  STB_OSDeleteMutex( setup.sfmMutex );
883  ERRPRINT("")
884  sfm = NULL;
885  }
886  else
887  {
888  setup.bufferMutex = STB_OSCreateMutex();
889  if (setup.bufferMutex == NULL)
890  {
891  STB_OSDeleteMutex( setup.cacheMutex );
892  STB_OSDeleteMutex( setup.sfmMutex );
893  ERRPRINT("")
894  sfm = NULL;
895  }
896  else
897  {
898  setup.memAlloc = config->memAlloc;
899  setup.memFree = config->memFree;
900 
901  setup.mutexLock = STB_OSMutexLock;
902  setup.mutexUnlock = STB_OSMutexUnlock;
903 
904  setup.hwFilterCallback = ProcessSection;
905 
906  setup.updateFilter = UpdateFilter;
907 
908  setup.maxPidFilters = 4;
909  setup.maxSecFiltersPerPid = 1;
910 
911  setup.sectionBuffCacheSize = config->sectionBuffCacheSize;
912 
913  if (setup.sectionBuffCacheSize)
914  {
915  setup.cacheMatch = CacheMatch;
916  }
917  setup.maxAvailableSectionFilters = NUM_SECTION_FILTERS_DEFAULT;
918 
919  #ifndef NDEBUG
920  setup.errPrintf = (F_Printf)STB_SPDebugNoCnWrite;
921  if (gDebugState & DF_ALL)
922  {
923  setup.dbgPrintf = (F_Printf)STB_SPDebugNoCnWrite;
924  setup.dbgState = gDebugState & DF_ALL;
925  }
926  else
927  #endif
928  {
929  #if DSM_DP_LEVEL >= 2
930  setup.dbgPrintf = (F_Printf)STB_SPDebugNoCnWrite;
931  #else
932  setup.dbgPrintf = DBG_DebugPrintf;
933  #endif
934  setup.dbgState = 0;
935  }
936 
937  sfm = SFM_CreateInstance( &setup );
938  }
939  }
940  }
941  return sfm;
942 }
943 
948 static void DestroySfm( H_SfmInstance sfm )
949 {
950  void *sfmMutex;
951  void *cacheMutex;
952  void *bufferMutex;
953  if (sfm != NULL)
954  {
955  SFM_DestroyInstance( sfm, &sfmMutex, &cacheMutex, &bufferMutex );
956  STB_OSDeleteMutex( bufferMutex );
957  STB_OSDeleteMutex( cacheMutex );
958  STB_OSDeleteMutex( sfmMutex );
959  }
960 }
961 
962 static E_DscError StartTimer( H_DsmControl dsmctrl, U16BIT magic,
963  U32BIT timePeriod, void *clDsmTmrUserData, void **pTimerHandle )
964 {
965  S_Timer *pNewTimer, **ppTimer;
966  U32BIT trigger, tval;
967  U16BIT counter;
968  E_DscError err;
969  U8BIT era;
970 
971  pNewTimer = dsmctrl->api.memAlloc(sizeof(S_Timer));
972  if (pNewTimer == NULL)
973  {
974  *pTimerHandle = NULL;
975  err = CLDSM_ERR_ALLOC_FAILED;
976  }
977  else
978  {
979  trigger = STB_OSGetClockMilliseconds() + timePeriod;
980  pNewTimer->trigger = trigger;
981  pNewTimer->usrData.ptr = clDsmTmrUserData;
982  era = trigger >> ERA_SHIFT;
983  STB_OSMutexLock(dsmctrl->timerMtx);
984  dsmctrl->counter++;
985  counter = dsmctrl->counter;
986  pNewTimer->handle.u32 = (((U32BIT)magic) << 16) | (U32BIT)counter;
987  counter = 0;
988  ppTimer = &dsmctrl->timers;
989  while (*ppTimer != NULL)
990  {
991  tval = (*ppTimer)->trigger;
992  if (tval > trigger &&
993  (era != ERA_FIRST || (tval >> ERA_SHIFT) != ERA_LAST))
994  {
995  break;
996  }
997  counter++;
998  ppTimer = &((*ppTimer)->next);
999  }
1000  pNewTimer->next = *ppTimer;
1001  *ppTimer = pNewTimer;
1002  STB_OSMutexUnlock(dsmctrl->timerMtx);
1003  if (counter == 0)
1004  {
1005  STB_OSSemaphoreSignal(dsmctrl->q_count_sema);
1006  }
1007  *pTimerHandle = pNewTimer->handle.ptr;
1008  err = CLDSM_OK;
1009  }
1010  return err;
1011 }
1012 
1013 static E_DscError StartTimerFunc( H_DsmControl dsmctrl,
1014  U32BIT timePeriod, void *clDsmTmrUserData, void **pTimerHandle )
1015 {
1016  return StartTimer(dsmctrl, CLDSM_MAGIC, timePeriod, clDsmTmrUserData, pTimerHandle);
1017 }
1018 
1019 static void StopTimer( H_DsmControl dsmctrl, U32BIT handle )
1020 {
1021  S_Timer *pTimer, **ppTimer;
1022  STB_OSMutexLock(dsmctrl->timerMtx);
1023  ppTimer = &dsmctrl->timers;
1024  while (*ppTimer != NULL)
1025  {
1026  pTimer = *ppTimer;
1027  if (handle == pTimer->handle.u32)
1028  {
1029  *ppTimer = pTimer->next;
1030  dsmctrl->api.memFree(pTimer);
1031  break;
1032  }
1033  ppTimer = &(pTimer->next);
1034  }
1035  STB_OSMutexUnlock(dsmctrl->timerMtx);
1036 }
1037 
1038 static void StopTimerFunc( H_DsmControl dsmctrl, void *timerHandle )
1039 {
1040  U_PARAM th;
1041  th.ptr = timerHandle;
1042  StopTimer( dsmctrl, th.u32 );
1043 }
1044 
1045 static void dsmccErrorFunc( E_DscError err, void *args )
1046 {
1047 }
1048 
1049 static H_DsiInstance CreateDsi( S_DsmControl *dsmctrl, S_DsmccConfig *config)
1050 {
1051  H_DsiInstance dsi;
1052  dsi = DSI_CreateInstance(dsmctrl, ProcessDsi, config);
1053  dsmctrl->dsi = dsi;
1054  return dsi;
1055 }
1056 
1057 void DestroyDsi( S_DsmControl *dsmctrl )
1058 {
1059  if (dsmctrl->dsi != NULL)
1060  {
1061  DSI_DestroyInstance( dsmctrl->dsi );
1062  dsmctrl->dsi = NULL;
1063  }
1064 }
1065 
1066 static H_DsmCoreInst CreateDsmcc( S_DsmControl *dsmctrl, S_DsmccConfig *config )
1067 {
1068  S_DsmSetup setup;
1069  void *memContext = NULL;
1070  E_DscError cldsmErr = CLDSM_OK;
1071  H_DsmCoreInst cldsm;
1072 
1073 #ifndef NDEBUG
1074  CDSM_SetPrintFuncs( DBG_ErrorPrintf, DBG_WarnPrintf, DBG_DebugPrintf, DBG_InfoPrintf );
1075  CDSM_SetPrintState( gDebugState );
1076 #endif
1077 
1078  setup.siqInstance = CreateSiq( config, dsmctrl->dsi );
1079  if (setup.siqInstance == NULL)
1080  {
1081  cldsm = NULL;
1082  }
1083  else
1084  {
1085  setup.sfmInstance = CreateSfm( config );
1086  if (setup.sfmInstance == NULL)
1087  {
1088  if (!(config->controlFlags & GET_PMT_DIRECT_FROM_HW_FLAG) &&
1089  !UsingPmtsFromDvb())
1090  {
1091  STB_SIUnregisterPmtObserver( DvbPmtCallback );
1092  }
1093  DestroySiq( setup.siqInstance );
1094  cldsm = NULL;
1095  }
1096  else
1097  {
1098  /* Set up the callback functions provided by the DSM-CC component. */
1099  setup.allocFunc = config->memAlloc;
1100  setup.freeFunc = config->memFree;
1101 
1102  setup.errorFunc = dsmccErrorFunc;
1103 
1104  setup.startTimerFunc = StartTimerFunc;
1105  setup.stopTimerFunc = StopTimerFunc;
1106 
1107  setup.addSectionFilterFunc = SFM_DsmccFilterAdd;
1108  setup.delSectionFilterFunc = SFM_DsmccFilterDelete;
1109  setup.sfPriorityChangeFunc = SFM_DsmccFilterPriorityChange;
1110 
1111  setup.startSIQueryFunc = SIQ_RequestQueryStart;
1112  setup.stopSIQueryFunc = SIQ_RequestQueryStop;
1113  setup.subscribeSIChangeFunc = SIQ_ServiceInfoChangeSubscribe;
1114  setup.unsubscribeSIChangeFunc = SIQ_ServiceInfoChangeUnsubscribe;
1115 
1116  setup.notifyCarouselLoadEventFunc = config->carouselLoad;
1117  setup.notifyObjectLoadEventFunc = DsmccObjectLoadEventFunc;
1118  setup.notifyStreamEventFunc = DsmccStreamEventFunc;
1119  setup.progressFunc = NULL;
1120  setup.dsmControl = dsmctrl;
1121 
1122  setup.ssuFuncs = config->ssuFuncs;
1123 
1124  /* Set other values to suggested defaults */
1125  setup.memMgrSetup = NULL;
1126  setup.maxAvailableSectionFilters = NUM_SECTION_FILTERS_DEFAULT;
1127  setup.timeUnitResolution = TIMER_RESOLUTION;
1128  setup.storeSIQueryResults = TRUE;
1129  setup.turboCaching = (config->controlFlags & DISABLE_AUTO_CACHING_FLAG) ? FALSE : TRUE;
1130  setup.multipleSsuDownloads = FALSE;
1131  setup.notifyDeferredServiceFunc = NULL;
1132  setup.maxMemorySize = DSMCC_DEFAULT_CACHE_SIZE;
1133  /* Create an dsmctrl of the DSM-CC component. */
1134  cldsmErr = CDSM_SysCreate( &setup, &cldsm, &memContext );
1135 
1136  if (cldsmErr == CLDSM_OK)
1137  {
1138  SIQ_SetDsmInstance( setup.siqInstance, cldsm );
1139  SFM_SetDsmInstance( setup.sfmInstance, cldsm );
1140  dsmctrl->api.cldsm = cldsm;
1141  dsmctrl->sfm = setup.sfmInstance;
1142  dsmctrl->siq = setup.siqInstance;
1143  dsmctrl->debugMask = gDebugState;
1144  CDSM_SetDebugState(cldsm, gDebugState & DD_ALL);
1145  }
1146  else
1147  {
1148  DestroySfm( setup.sfmInstance );
1149  if (!(config->controlFlags & GET_PMT_DIRECT_FROM_HW_FLAG) &&
1150  !UsingPmtsFromDvb())
1151  {
1152  STB_SIUnregisterPmtObserver( DvbPmtCallback );
1153  }
1154  DestroySiq( setup.siqInstance );
1155  cldsm = NULL;
1156  }
1157  }
1158  }
1159  return cldsm;
1160 }
1161 
1162 static void DestroyDsmcc( S_DsmControl *dsmctrl )
1163 {
1164  E_DscError err = CLDSM_OK;
1165  H_SiqInstance siqInstance;
1166  H_SfmInstance sfmInstance;
1167 
1168  err = CDSM_SysReset( dsmctrl->api.cldsm, RST_MODE_FORCE );
1169  if (err)
1170  {
1171  ERRPRINT("err=%d", err)
1172  }
1173  err = CDSM_SysDestroy(dsmctrl->api.cldsm, &siqInstance, &sfmInstance);
1174  if (err == CLDSM_OK)
1175  {
1176  dsmctrl->api.cldsm = NULL;
1177 
1178  ASSERT(dsmctrl->sfm == sfmInstance);
1179  dsmctrl->sfm = NULL;
1180  DestroySfm( sfmInstance );
1181 
1182  ASSERT(dsmctrl->siq == siqInstance);
1183  dsmctrl->siq = NULL;
1184  DestroySiq( siqInstance );
1185 
1186  if (dsmctrl->dsi != NULL)
1187  {
1188  DestroyDsi( dsmctrl );
1189  }
1190  else if (!UsingPmtsFromDvb())
1191  {
1192  STB_SIUnregisterPmtObserver( DvbPmtCallback );
1193  }
1194  }
1195  else
1196  {
1197  ERRPRINT("err=%d", err)
1198  }
1199 }
1200 
1205 static void DestroySecBuff( H_SbmInstance sbm )
1206 {
1207  void *bufferMutex;
1208  if (sbm != NULL)
1209  {
1210  SBM_DestroyInstance( sbm, &bufferMutex );
1211  STB_OSDeleteMutex( bufferMutex );
1212  }
1213 }
1214 
1219 static H_SbmInstance CreateSecBuff( S_DsmControl *dsmctrl, U16BIT size )
1220 {
1221  S_SbmSetup setup;
1222  H_SbmInstance sbm;
1223  setup.mtx_sem = STB_OSCreateMutex();
1224  if (setup.mtx_sem == NULL)
1225  {
1226  ERRPRINT("")
1227  sbm = NULL;
1228  }
1229  else
1230  {
1231  setup.memAlloc = dsmctrl->api.memAlloc;
1232  setup.memFree = dsmctrl->api.memFree;
1233  setup.lock = STB_OSMutexLock;
1234  setup.unlock = STB_OSMutexUnlock;
1235  setup.bufferSize = ((size + 15) >> 4);
1236  sbm = SBM_CreateInstance( &setup );
1237  if (sbm == NULL)
1238  {
1239  STB_OSDeleteMutex(setup.mtx_sem);
1240  }
1241  else
1242  {
1243  dsmctrl->sbm = sbm;
1244  }
1245  }
1246  return sbm;
1247 }
1248 
1249 static void DestoryResources( S_DsmControl *dsmctrl )
1250 {
1251  int i;
1252  if (dsmctrl->sbm != NULL)
1253  {
1254  DestroySecBuff( dsmctrl->sbm );
1255  dsmctrl->sbm = NULL;
1256  }
1257  for (i = 0; i != QP_TOTAL; i++)
1258  {
1259  if (dsmctrl->queues[i].mutex != NULL)
1260  {
1261  STB_OSDeleteMutex(dsmctrl->queues[i].mutex);
1262  }
1263  }
1264  if (dsmctrl->q_count_sema != NULL)
1265  {
1266  STB_OSDeleteSemaphore(dsmctrl->q_count_sema);
1267  dsmctrl->q_count_sema = NULL;
1268  }
1269  if (dsmctrl->timerMtx != NULL)
1270  {
1271  STB_OSDeleteMutex(dsmctrl->timerMtx);
1272  dsmctrl->timerMtx = NULL;
1273  }
1274  if (dsmctrl->api.mutex != NULL)
1275  {
1276  STB_OSDeleteMutex(dsmctrl->api.mutex);
1277  dsmctrl->api.mutex = NULL;
1278  }
1279 }
1280 
1281 static BOOLEAN CreateResources( S_DsmControl *dsmctrl, U16BIT size )
1282 {
1283  S_Message *pmsg;
1284  int i;
1285  BOOLEAN result;
1286  dsmctrl->api.mutex = STB_OSCreateMutex();
1287  if (dsmctrl->api.mutex == NULL)
1288  {
1289  ERRPRINT("")
1290  result = FALSE;
1291  }
1292  else
1293  {
1294  dsmctrl->timerMtx = STB_OSCreateMutex();
1295  if (dsmctrl->timerMtx == NULL)
1296  {
1297  STB_OSDeleteMutex(dsmctrl->api.mutex);
1298  dsmctrl->api.mutex = NULL;
1299  ERRPRINT("")
1300  result = FALSE;
1301  }
1302  else
1303  {
1304  dsmctrl->q_count_sema = STB_OSCreateCountSemaphore(0);
1305  if (dsmctrl->q_count_sema == NULL)
1306  {
1307  ERRPRINT("")
1308  result = FALSE;
1309  }
1310  else
1311  {
1312  result = TRUE;
1313  pmsg = (S_Message *)(dsmctrl + 1);
1314  for (i = 0; i != QP_TOTAL; i++)
1315  {
1316  dsmctrl->queues[i].mutex = STB_OSCreateMutex();
1317  if (dsmctrl->queues[i].mutex == NULL)
1318  {
1319  ERRPRINT("")
1320  result = FALSE;
1321  break;
1322  }
1323  dsmctrl->queues[i].begin = pmsg;
1324  dsmctrl->queues[i].write = pmsg;
1325  dsmctrl->queues[i].read = pmsg;
1326  pmsg += size * (i + 1);
1327  dsmctrl->queues[i].ends = pmsg;
1328  }
1329  if (i == QP_TOTAL && !CreateSecBuff(dsmctrl, size))
1330  {
1331  result = FALSE;
1332  }
1333  }
1334  if (!result)
1335  {
1336  DestoryResources(dsmctrl);
1337  }
1338  }
1339  }
1340  return result;
1341 }
1342 
1343 static BOOLEAN DsmStart( H_DsmControl dsmctrl, U16BIT serviceId, U32BIT couId, U8BIT sikind )
1344 {
1345  E_DscError err;
1346  BOOLEAN result = FALSE;
1347 
1348  dsmctrl->carousel = NULL;
1349  dsmctrl->restart = 0;
1350  dsmctrl->counter = 0;
1351  dsmctrl->sikind = sikind;
1352  dsmctrl->status = (U8BIT)BL_BOOTING;
1353  STB_OSMutexLock(dsmctrl->api.mutex);
1354  if (sikind == SIQUERY_SSU_PID)
1355  {
1356  err = CDSM_SysSetCurrService(dsmctrl->api.cldsm, dsmctrl->networkId, dsmctrl->transId, 0);
1357  }
1358  else
1359  {
1360  err = CDSM_SysSetCurrService(dsmctrl->api.cldsm, dsmctrl->networkId, dsmctrl->transId, serviceId);
1361  }
1362  if (err == CLDSM_OK)
1363  {
1364  err = CDSM_LoadCarousel( dsmctrl->api.cldsm, serviceId, couId,
1365  (E_SIQueryKind)sikind, &dsmctrl->carousel );
1366  if (err == CLDSM_OK)
1367  {
1368  DBGPRINT(DM_CONTROL, "OK %p", dsmctrl)
1369  result = TRUE;
1370  dsmctrl->status = (U8BIT)BL_LOADED;
1371  }
1372  else if (err != CLDSM_ERR_SI_QUERY_FAILED || couId != INVALID_CAROUSEL_ID)
1373  {
1374  ERRPRINT("err=%d", err)
1375  CDSM_SysSetCurrService( dsmctrl->api.cldsm, 0, 0, 0 );
1376  dsmctrl->status = (U8BIT)BL_FAILED;
1377  }
1378  }
1379  STB_OSMutexUnlock(dsmctrl->api.mutex);
1380  if (err == CLDSM_ERR_SI_QUERY_FAILED && couId == INVALID_CAROUSEL_ID)
1381  {
1382  U_PARAM th;
1383  DBGPRINT(DM_CONTROL, "Schedule re-start %p", dsmctrl)
1384  dsmctrl->status = (U16BIT)BL_FAILED;
1385  th.u16 = serviceId;
1386  StartTimer(dsmctrl, START_MAGIC, RESTART_TIME, th.ptr, &th.ptr);
1387  dsmctrl->restart = th.u32;
1388  result = TRUE;
1389  }
1390  return result;
1391 }
1392 
1393 static void DsmRestart( H_DsmControl dsmctrl, U16BIT serviceId )
1394 {
1395  E_DscError err;
1396  U16BIT sid;
1397  dsmctrl->restart = 0;
1398  STB_OSMutexLock(dsmctrl->api.mutex);
1399  sid = CDSM_SysCurrServiceId(dsmctrl->api.cldsm);
1400  if (sid != serviceId)
1401  {
1402  err = CLDSM_ERR_NO_CURRENT_SERVICE_SET;
1403  }
1404  else if (CDSM_CurrentCarousel(dsmctrl->api.cldsm) != NULL)
1405  {
1406  err = CLDSM_ERR_CAROUSELS_STILL_LOADED;
1407  }
1408  else
1409  {
1410  err = CDSM_LoadCarousel( dsmctrl->api.cldsm, serviceId, INVALID_CAROUSEL_ID,
1411  SIQUERY_BOOT_CAROUSEL, &dsmctrl->carousel );
1412  if (err == CLDSM_OK)
1413  {
1414  DBGPRINT(DM_CONTROL, "srvId=%d", serviceId)
1415  dsmctrl->status = (U8BIT)BL_LOADED;
1416  }
1417  else if (err == CLDSM_ERR_SI_QUERY_FAILED)
1418  {
1419  DBGPRINT(DM_CONTROL, "srvId=%d err=%d", serviceId, err)
1420  }
1421  else
1422  {
1423  ERRPRINT("srvId=%d err=%d", serviceId, err)
1424  }
1425  }
1426  STB_OSMutexUnlock(dsmctrl->api.mutex);
1427  if (err == CLDSM_ERR_SI_QUERY_FAILED)
1428  {
1429  U_PARAM th;
1430  th.u16 = serviceId;
1431  StartTimer(dsmctrl, START_MAGIC, RESTART_TIME, th.ptr, &th.ptr);
1432  dsmctrl->restart = th.u32;
1433  }
1434 }
1435 
1436 static BOOLEAN DsiStart( H_DsmControl dsmctrl, U16BIT serviceId, U32BIT couId, U8BIT sikind )
1437 {
1438  BOOLEAN result;
1439 
1440  DBGPRINT(DM_CONTROL, "%p sid=%d", dsmctrl, serviceId)
1441 
1442  ASSERT(dsmctrl->dsi);
1443 
1444  dsmctrl->serviceId = serviceId;
1445  dsmctrl->couId = couId;
1446  dsmctrl->sikind = sikind;
1447  dsmctrl->status = (U8BIT)BL_WAITING;
1448  result = DSI_Start( dsmctrl->dsi, dsmctrl->transId, dsmctrl->dmxref );
1449  if (result)
1450  {
1451  U32BIT count = 600;
1452  /* Wait for boot process to start loading carousel (for upto 3 secs) */
1453  while (dsmctrl->status == (U8BIT)BL_WAITING || dsmctrl->status == (U8BIT)BL_BOOTING)
1454  {
1455  STB_OSTaskDelay(5);
1456  count--;
1457  if (!count)
1458  break;
1459  }
1460  result = (dsmctrl->status == (U8BIT)BL_LOADED) ? TRUE : FALSE;
1461  }
1462  return result;
1463 }
1464 
1465 #ifndef NDEBUG
1466 
1472 static void DebugInstanceSetMask(H_DsmControl dsmctrl, U32BIT mask)
1473 {
1474  FUNCTION_START(DebugInstanceSetMask)
1475  if (dsmctrl->debugMask != mask)
1476  {
1477  ERRPRINT("dsmctrl %p; mask %x",dsmctrl,mask)
1478  dsmctrl->debugMask = mask;
1479  CDSM_SetDebugState(dsmctrl->api.cldsm, mask & DD_ALL);
1480  #if DSM_DP_LEVEL >= 2
1481  SFM_SetDebugState(dsmctrl->sfm, mask & DF_ALL);
1482  SIQ_SetDebugState(dsmctrl->siq, mask & DS_ALL);
1483  #else
1484  SFM_SetDebugConfig(dsmctrl->sfm,
1485  (F_Printf)STB_SPDebugNoCnWrite,
1486  (F_Printf)STB_SPDebugNoCnWrite,
1487  mask & DF_ALL);
1488  SIQ_SetDebugConfig(dsmctrl->siq,
1489  (F_Printf)STB_SPDebugNoCnWrite,
1490  (F_Printf)STB_SPDebugNoCnWrite,
1491  mask & DS_ALL);
1492  #endif
1493  }
1494  FUNCTION_FINISH(DebugInstanceSetMask)
1495 }
1496 #endif
1497 
1498 
1499 
1500 /*------------------- Global function definitions ---------------------------*/
1501 
1507 H_DsmControl DSMCC_Open( S_DsmccConfig *config )
1508 {
1509  S_DsmControl *dsmctrl;
1510  U16BIT i, msz, size;
1511  size = config->sectionBuffPoolSize;
1512  size *= sizeof(S_Message);
1513  for (i = 1, msz = 0; i != (QP_TOTAL + 1); i++)
1514  {
1515  msz += size * i;
1516  }
1517  dsmctrl = config->memAlloc(sizeof(S_DsmControl) + msz);
1518  if (dsmctrl != NULL)
1519  {
1520  memset(dsmctrl, 0, sizeof(S_DsmControl));
1521  dsmctrl->api.memAlloc = config->memAlloc;
1522  dsmctrl->api.memFree = config->memFree;
1523  if (!CreateResources(dsmctrl, config->sectionBuffPoolSize))
1524  {
1525  ERRPRINT("")
1526  config->memFree( dsmctrl );
1527  dsmctrl = NULL;
1528  }
1529  else if ((config->controlFlags & GET_PMT_DIRECT_FROM_HW_FLAG) &&
1530  !CreateDsi(dsmctrl, config))
1531  {
1532  ERRPRINT("")
1533  DestoryResources( dsmctrl );
1534  config->memFree( dsmctrl );
1535  dsmctrl = NULL;
1536  }
1537  else if (!CreateDsmcc(dsmctrl, config))
1538  {
1539  ERRPRINT("")
1540  if (config->controlFlags & GET_PMT_DIRECT_FROM_HW_FLAG)
1541  {
1542  DestroyDsi( dsmctrl );
1543  }
1544  else if (!UsingPmtsFromDvb())
1545  {
1546  STB_SIUnregisterPmtObserver( DvbPmtCallback );
1547  }
1548  DestoryResources( dsmctrl );
1549  config->memFree( dsmctrl );
1550  dsmctrl = NULL;
1551  }
1552  else
1553  {
1554  dsmctrl->task = STB_OSCreateTask( DsmMain, (void *)dsmctrl, MAIN_STACK_SIZE,
1555  (U8BIT)config->taskPriority, (U8BIT *)"DsmMain" );
1556  if (dsmctrl->task)
1557  {
1558  DBGPRINT(DM_CONTROL, "OK %p", dsmctrl)
1559  dsmctrl->next = instanceHead;
1560  instanceHead = dsmctrl;
1561  }
1562  else
1563  {
1564  ERRPRINT("")
1565  DestroyDsmcc( dsmctrl );
1566  DestoryResources( dsmctrl );
1567  config->memFree( dsmctrl );
1568  dsmctrl = NULL;
1569  }
1570  }
1571  }
1572  return dsmctrl;
1573 }
1574 
1580 void DSMCC_Close(H_DsmControl dsmctrl)
1581 {
1582  S_Message emsg;
1583  S_DsmControl **pDsmctrl;
1584  if (dsmctrl != NULL)
1585  {
1586  pDsmctrl = &instanceHead;
1587  while (*pDsmctrl != NULL)
1588  {
1589  if (*pDsmctrl == dsmctrl)
1590  {
1591  DBGPRINT(DM_CONTROL, "%p", dsmctrl)
1592 
1593  /* Stop Task */
1594  emsg.type = DSM_MSG_CLOSE_DOWN;
1595  while (!QueueWrite(dsmctrl->queues + QP_TOP, &emsg))
1596  {
1597  STB_OSTaskDelay(7);
1598  }
1599  STB_OSSemaphoreSignal(dsmctrl->q_count_sema);
1600  while (dsmctrl->task != NULL)
1601  {
1602  STB_OSTaskDelay(7);
1603  }
1604  *pDsmctrl = dsmctrl->next;
1605  DestroyDsmcc( dsmctrl );
1606  DestoryResources( dsmctrl );
1607  dsmctrl->api.memFree( dsmctrl );
1608  break;
1609  }
1610  pDsmctrl = &((*pDsmctrl)->next);
1611  }
1612  }
1613 }
1614 
1636 BOOLEAN DSMCC_Start( H_DsmControl dsmctrl, S_DvbLocator *locator,
1637  U32BIT boot_carousel_id, DMXREF dmxref )
1638 {
1639  DSMCC_SetTunedTransportInfo( dsmctrl, locator->original_network_id,
1640  locator->transport_stream_id, dmxref );
1641  return DSMCC_StartFs( dsmctrl, locator->service_id, boot_carousel_id );
1642 }
1643 
1653 void DSMCC_SetTunedTransportInfo( H_DsmControl dsmctrl, U16BIT onet_id,
1654  U16BIT tran_id, DMXREF dmxref )
1655 {
1656  DBGPRINT(DM_CONTROL, "%p onet=%x tran=%x dmx=%x",
1657  dsmctrl, onet_id, tran_id, dmxref)
1658 
1659  SFM_SetDemuxHandle( dsmctrl->sfm, dmxref );
1660  dsmctrl->dmxref = dmxref;
1661  dsmctrl->transId = tran_id;
1662  dsmctrl->networkId = onet_id;
1663 
1664  SIQ_TransportChanged( dsmctrl->siq, onet_id, tran_id );
1665 }
1666 
1688 BOOLEAN DSMCC_StartFs( H_DsmControl dsmctrl, U16BIT service_id, U32BIT carousel_id )
1689 {
1690  BOOLEAN result;
1691  U8BIT sikind;
1692  DBGPRINT(DM_CONTROL, "%p sid=%d cid=%d", dsmctrl, service_id, carousel_id)
1693  switch (carousel_id)
1694  {
1695  case INVALID_CAROUSEL_ID:
1696  sikind = (U8BIT)SIQUERY_BOOT_CAROUSEL;
1697  break;
1698 
1699  case UNKNOWN_CAROUSEL_ID:
1700  sikind = (U8BIT)SIQUERY_FIND_CAROUSEL;
1701  break;
1702 
1703  default:
1704  sikind = (U8BIT)SIQUERY_CAROUSEL;
1705  }
1706  if (service_id == CDSM_SysCurrServiceId( dsmctrl->api.cldsm ))
1707  {
1708  ERRPRINT("%p already on service Id=%d", dsmctrl, service_id)
1709  result = FALSE;
1710  }
1711  else if (dsmctrl->dsi)
1712  {
1713  result = DsiStart( dsmctrl, service_id, carousel_id, sikind );
1714  }
1715  else
1716  {
1717  result = DsmStart( dsmctrl, service_id, carousel_id, sikind );
1718  }
1719  return result;
1720 }
1721 
1731 BOOLEAN DSMCC_StartSsu( H_DsmControl dsmctrl, U16BIT service_id, U32BIT oui )
1732 {
1733  BOOLEAN result;
1734 
1735  DBGPRINT(DM_CONTROL, "%p sid=%d oui=%x", dsmctrl, service_id, oui)
1736  if (service_id == CDSM_SysCurrServiceId( dsmctrl->api.cldsm ))
1737  {
1738  ERRPRINT("%p already on service Id=%d", dsmctrl, service_id)
1739  result = FALSE;
1740  }
1741  else if (dsmctrl->dsi)
1742  {
1743  result = DsiStart( dsmctrl, service_id, oui, (U8BIT)SIQUERY_SSU_CAROUSEL );
1744  }
1745  else
1746  {
1747  result = DsmStart( dsmctrl, service_id, oui, (U8BIT)SIQUERY_SSU_CAROUSEL );
1748  }
1749  return result;
1750 }
1751 
1761 BOOLEAN DSMCC_StartSsuWithPid( H_DsmControl dsmctrl, U16BIT pid, U32BIT oui )
1762 {
1763  BOOLEAN result;
1764 
1765  DBGPRINT(DM_CONTROL, "%p pid=%d oui=%x", dsmctrl, pid, oui)
1766  if (dsmctrl->dsi)
1767  {
1768  result = DsiStart( dsmctrl, pid, oui, (U8BIT)SIQUERY_SSU_PID );
1769  }
1770  else
1771  {
1772  result = DsmStart( dsmctrl, pid, oui, (U8BIT)SIQUERY_SSU_PID );
1773  }
1774  return result;
1775 }
1776 
1783 void DSMCC_Stop( H_DsmControl dsmctrl, E_DsmRstMode mode )
1784 {
1785  E_DscError err;
1786 
1787  STB_OSMutexLock(dsmctrl->api.mutex);
1788 
1789  DBGPRINT(DM_CONTROL, "%p sid=%d boot_crsl=%p curr_crsl=%p", dsmctrl,
1790  CDSM_SysCurrServiceId(dsmctrl->api.cldsm),
1791  dsmctrl->carousel,
1792  CDSM_CurrentCarousel(dsmctrl->api.cldsm))
1793  if (dsmctrl->carousel != NULL)
1794  {
1795  //is dsmctrl->carousel == CDSM_CurrentCarousel(dsmctrl->api.cldsm) ?
1796  err = CDSM_UnloadCarousel( dsmctrl->api.cldsm, CDSM_CurrentCarousel(dsmctrl->api.cldsm), mode );
1797  if (err != CLDSM_OK)
1798  {
1799  ERRPRINT("err=%d", err)
1800  }
1801  }
1802  if (dsmctrl->status != (U8BIT)BL_WAITING && dsmctrl->restart != 0)
1803  {
1804  StopTimer( dsmctrl, dsmctrl->restart );
1805  dsmctrl->restart = 0;
1806  }
1807  err = CDSM_SysSetCurrService( dsmctrl->api.cldsm, 0, 0, 0 );
1808  if (err != CLDSM_OK)
1809  {
1810  ERRPRINT("err=%d", err)
1811  }
1812  err = CDSM_SysReset( dsmctrl->api.cldsm, mode );
1813  if (err != CLDSM_OK)
1814  {
1815  ERRPRINT("err=%d", err)
1816  }
1817  STB_OSMutexUnlock(dsmctrl->api.mutex);
1818 
1819  dsmctrl->status = (U8BIT)BL_WAITING;
1820  if (dsmctrl->dsi)
1821  {
1822  DSI_Stop( dsmctrl->dsi );
1823  }
1824  SFM_CacheClear( dsmctrl->sfm );
1825 }
1826 
1833 void DSMCC_Reboot( H_DsmControl dsmctrl )
1834 {
1835  H_ObjCarousel hOC;
1836  E_DscError err;
1837  U16BIT serviceId;
1838 
1839  if (dsmctrl->status != (U16BIT)BL_WAITING && dsmctrl->restart != 0)
1840  {
1841  StopTimer( dsmctrl, dsmctrl->restart );
1842  dsmctrl->restart = 0;
1843  }
1844  STB_OSMutexLock(dsmctrl->api.mutex);
1845  serviceId = CDSM_SysCurrServiceId( dsmctrl->api.cldsm );
1846  if (serviceId == 0)
1847  {
1848  err = CLDSM_ERR_NO_CURRENT_SERVICE_SET;
1849  ERRPRINT("%p serviceId=%d", dsmctrl, serviceId)
1850  }
1851  else
1852  {
1853  hOC = CDSM_CurrentCarousel(dsmctrl->api.cldsm);
1854  DBGPRINT(DM_CONTROL, "%p sid=%d c_crsl=%p", dsmctrl, serviceId, hOC)
1855  if (hOC != NULL)
1856  {
1857  err = CDSM_UnloadCarousel( dsmctrl->api.cldsm, hOC, RST_MODE_FORCE );
1858  if (err != CLDSM_OK)
1859  {
1860  ERRPRINT("err=%d", err)
1861  }
1862  SFM_CacheClear(dsmctrl->sfm);
1863  }
1864  err = CDSM_LoadCarousel( dsmctrl->api.cldsm, serviceId, INVALID_CAROUSEL_ID,
1865  SIQUERY_BOOT_CAROUSEL, &dsmctrl->carousel );
1866  if (err != CLDSM_OK)
1867  {
1868  ERRPRINT("err=%d", err)
1869  }
1870  }
1871  STB_OSMutexUnlock(dsmctrl->api.mutex);
1872  if (err == CLDSM_ERR_SI_QUERY_FAILED)
1873  {
1874  U_PARAM th;
1875  dsmctrl->status = (U16BIT)BL_FAILED;
1876  th.u16 = serviceId;
1877  StartTimer(dsmctrl, START_MAGIC, RESTART_TIME, th.ptr, &th.ptr);
1878  dsmctrl->restart = th.u32;
1879  }
1880 }
1881 
1887 H_ObjCarousel DSMCC_CurrentCarousel( H_DsmControl dsmctrl )
1888 {
1889  H_ObjCarousel hOC;
1890  STB_OSMutexLock(dsmctrl->api.mutex);
1891  hOC = CDSM_CurrentCarousel(dsmctrl->api.cldsm);
1892  STB_OSMutexUnlock(dsmctrl->api.mutex);
1893  return hOC;
1894 }
1895 
1901 U32BIT DSMCC_CurrentCarouselId( H_DsmControl dsmctrl )
1902 {
1903  U32BIT cid = 0;
1904  STB_OSMutexLock(dsmctrl->api.mutex);
1905  if (CDSM_GetCarouselId( dsmctrl->api.cldsm, CDSM_CurrentCarousel(dsmctrl->api.cldsm), &cid ) != CLDSM_OK)
1906  {
1907  ERRPRINT("")
1908  }
1909  STB_OSMutexUnlock(dsmctrl->api.mutex);
1910  return cid;
1911 }
1912 
1920 BOOLEAN DSMCC_SetCurrentCarousel(H_DsmControl dsmctrl, H_ObjCarousel hOC)
1921 {
1922  BOOLEAN result;
1923  STB_OSMutexLock(dsmctrl->api.mutex);
1924  if (CDSM_SetCurrentCarousel( dsmctrl->api.cldsm, hOC ) == CLDSM_OK)
1925  {
1926  DBGPRINT(DM_CONTROL, "%p c_crsl=%p", dsmctrl, hOC)
1927  result = TRUE;
1928  }
1929  else
1930  {
1931  ERRPRINT("")
1932  result = FALSE;
1933  }
1934  STB_OSMutexUnlock(dsmctrl->api.mutex);
1935  return result;
1936 }
1937 
1945 void DSMCC_UnloadCarousel(H_DsmControl dsmctrl, H_ObjCarousel hOC, E_DsmRstMode mode)
1946 {
1947  E_DscError err;
1948  DBGPRINT(DM_CONTROL, "crsl=%p mode=%d", hOC, mode)
1949  STB_OSMutexLock(dsmctrl->api.mutex);
1950  err = CDSM_UnloadCarousel( dsmctrl->api.cldsm, hOC, mode );
1951  STB_OSMutexUnlock(dsmctrl->api.mutex);
1952  if (err != CLDSM_OK)
1953  {
1954  ERRPRINT("Unload Carousel err %d", err)
1955  }
1956  else
1957  {
1958  SFM_CacheClear(dsmctrl->sfm);
1959  }
1960 }
1961 
1970 void DSMCC_SsuUnloadModule( H_DsmControl dsmctrl, H_DsmCarousel hCarousel,
1971  U32BIT moduleRef )
1972 {
1973  E_DscError err;
1974  DBGPRINT(DM_CONTROL, "crsl=%p", hCarousel)
1975  STB_OSMutexLock(dsmctrl->api.mutex);
1976  err = CDSM_UnloadModule( dsmctrl->api.cldsm, hCarousel, moduleRef );
1977  STB_OSMutexUnlock(dsmctrl->api.mutex);
1978  if (err != CLDSM_OK)
1979  {
1980  ERRPRINT("Unload Carousel err %d", err)
1981  }
1982 }
1983 
1984 
1995 void DSMCC_SetFileSystemCacheLimit( H_DsmControl dsmctrl, U32BIT cacheSize )
1996 {
1997  STB_OSMutexLock(dsmctrl->api.mutex);
1998  CDSM_SysSetMemoryMax( dsmctrl->api.cldsm, cacheSize );
1999  STB_OSMutexUnlock(dsmctrl->api.mutex);
2000 }
2001 
2008 void DSMCC_SiqCacheClearPmt( H_DsmControl dsmctrl, U16BIT serviceId )
2009 {
2010  DBGPRINT(DM_CONTROL, "sid=%d", serviceId)
2011  STB_OSMutexLock(dsmctrl->api.mutex);
2012  SIQ_CacheClearPmt( dsmctrl->siq, serviceId );
2013  STB_OSMutexUnlock(dsmctrl->api.mutex);
2014 }
2015 
2020 const char* DSMCC_VersionString(void)
2021 {
2022  return DSMCC_VER_STRING;
2023 }
2024 
2031 H_DsmControl DSMCC_FindInstance( U16BIT serviceId, DMXREF dmxref )
2032 {
2033  S_DsmControl *dsmctrl;
2034  FUNCTION_START(DSMCC_FindInstance)
2035  dsmctrl = instanceHead;
2036  while (dsmctrl != NULL)
2037  {
2038  if (dsmctrl->dmxref == dmxref && CDSM_SysCurrServiceId(dsmctrl->api.cldsm) == serviceId)
2039  {
2040  break;
2041  }
2042  dsmctrl = dsmctrl->next;
2043  }
2044  FUNCTION_FINISH(DSMCC_FindInstance)
2045  return dsmctrl;
2046 }
2047 
2053 {
2054 #ifndef NDEBUG
2055  return gDebugState;
2056 #else
2057  return 0;
2058 #endif
2059 }
2060 
2066 void DSMCC_DebugSetMask(U32BIT mask)
2067 {
2068 #ifndef NDEBUG
2069  S_DsmControl *dsmctrl;
2070  FUNCTION_START(DSMCC_DebugSetMask)
2071 
2072  gDebugState = mask;
2073  CDSM_SetPrintState( gDebugState & DD_ALL );
2074 
2075  dsmctrl = instanceHead;
2076  while (dsmctrl != NULL)
2077  {
2078  DebugInstanceSetMask(dsmctrl, mask);
2079  dsmctrl = dsmctrl->next;
2080  }
2081  FUNCTION_FINISH(DSMCC_DebugSetMask)
2082 #else
2083  USE_UNWANTED_PARAM(mask);
2084 #endif
2085 }
2086 
2087 U32BIT DebugInstanceGetMask(H_DsmControl dsmctrl)
2088 {
2089  return dsmctrl->debugMask;
2090 }
2091 
2097 U32BIT DSMCC_DebugInstanceGetMask(H_DsmControl instance)
2098 {
2099 #ifndef NDEBUG
2100  S_DsmControl *dsmctrl;
2101  dsmctrl = instanceHead;
2102  while (dsmctrl != NULL)
2103  {
2104  if (dsmctrl == instance)
2105  {
2106  return dsmctrl->debugMask;
2107  }
2108  dsmctrl = dsmctrl->next;
2109  }
2110 #else
2111  USE_UNWANTED_PARAM(instance);
2112 #endif
2113  return 0;
2114 }
2115 
2122 void DSMCC_DebugInstanceSetMask(H_DsmControl instance, U32BIT mask)
2123 {
2124 #ifndef NDEBUG
2125  S_DsmControl *dsmctrl;
2126  FUNCTION_START(DSMCC_DebugInstanceSetMask)
2127 
2128  ERRPRINT("(instance %p, mask %x)",instance, mask)
2129  dsmctrl = instanceHead;
2130  while (dsmctrl != NULL)
2131  {
2132  if (dsmctrl == instance)
2133  {
2134  DebugInstanceSetMask(dsmctrl, mask);
2135  break;
2136  }
2137  dsmctrl = dsmctrl->next;
2138  }
2139  FUNCTION_FINISH(DSMCC_DebugInstanceSetMask)
2140 #else
2141  USE_UNWANTED_PARAM(instance);
2142  USE_UNWANTED_PARAM(mask);
2143 #endif
2144 }
2145 
2146 
2154 void DSMCC_DebugInstanceEnable(H_DsmControl dsmctrl, const char *rootname)
2155 {
2156 #if defined(NDEBUG) && defined(DEBUG_USE_GETENV)
2157  char envname[64];
2158  char *mskptr;
2159  char *value;
2160  U32BIT mask;
2161 
2162  strcpy(envname,rootname);
2163  mskptr = envname + strlen(rootname);
2164 
2165  mask = dsmctrl->debugMask;
2166  /* Query environment variables "<rootname>_<maskname>" */
2167  GETENV_DSMDBG(DD_GEN )
2168  GETENV_DSMDBG(DD_OC )
2169  GETENV_DSMDBG(DD_SF )
2170  GETENV_DSMDBG(DD_TIMER )
2171  GETENV_DSMDBG(DD_SE )
2172  GETENV_DSMDBG(DD_LM )
2173  GETENV_DSMDBG(DD_OBJ )
2174  GETENV_DSMDBG(DD_DC )
2175  GETENV_DSMDBG(DD_QUERY )
2176  GETENV_DSMDBG(DD_MOD )
2177  GETENV_DSMDBG(DD_ALL )
2178  GETENV_DSMDBG(DS_MAIN )
2179  GETENV_DSMDBG(DS_QUERY )
2180  GETENV_DSMDBG(DS_CACHE )
2181  GETENV_DSMDBG(DS_PMT )
2182  GETENV_DSMDBG(DS_PAT )
2183  GETENV_DSMDBG(DS_FUNC )
2184  GETENV_DSMDBG(DS_ALL )
2185  GETENV_DSMDBG(DF_MAIN )
2186  GETENV_DSMDBG(DF_FILTER )
2187  GETENV_DSMDBG(DF_CACHE )
2188  GETENV_DSMDBG(DF_HWSF )
2189  GETENV_DSMDBG(DF_ALL )
2190  GETENV_DSMDBG(DM_SI )
2191  GETENV_DSMDBG(DM_CONTROL)
2192  GETENV_DSMDBG(DM_CLIENT )
2193  DBGPRINT(DM_CONTROL, "mask=%x",mask)
2194  DebugInstanceSetMask(dsmctrl, mask);
2195 #else /*DEBUG_USE_GETENV*/
2196  USE_UNWANTED_PARAM(dsmctrl);
2197  USE_UNWANTED_PARAM(rootname);
2198 #endif /*DEBUG_USE_GETENV*/
2199 }
2200 
U32BIT STB_OSGetClockMilliseconds(void)
Get Current Computer Clock Time.
void SIQ_ServiceRemoved(H_SiqInstance siq, U16BIT serviceId)
Inform SIQ when a service has been removed from PAT. Not required if PAT is supplied to SIQ...
Definition: siq_cache.c:409
void * SFM_DsmccFilterAdd(H_SfmInstance sfm, P_SecFilter pFilter, H_DscSFRef dsmSfRef)
Add DSM-CC section filter. Called by DSM-CC component, and given in clDsmSysCreate setup...
Definition: sfm_filter.c:959
DSM-CC API functions to control DSM-CC instance.
void SFM_CacheClear(H_SfmInstance sfm)
Clear all SFM cached section data. Not required to be called, if setup had sectionBuffCacheSize set t...
Definition: sfm_cache.c:541
E_DscError CDSM_GetCarouselId(H_DsmCoreInst instance, H_DsmCarousel carouselHandle, U32BIT *pCarouselId)
Retrieve Carousel Id for the loaded DSM-CC Object Carousel.
void SIQ_ServiceInfoChangeUnsubscribe(H_SiqInstance siq, U16BIT serviceId)
Unsubscribe component to previously subscribed service change or alteration updates. Called by DSM-CC component, and given in clDsmSysCreate setup.
BOOLEAN STB_DMXCopyPIDFilterSect(DMXREF dmx, U8BIT *buffer, U16BIT size, PIDFILT pfid)
Copies a filtered section to caller's buffer.
void SFM_SetDsmInstance(H_SfmInstance sfm, H_DsmCoreInst dsmcc)
Set instance handle for DSM-CC that SFM is supporting.
Definition: sfm_main.c:220
void SIQ_RequestQueryStop(H_SiqInstance siq, void *queryHandle, H_SIQueryRef clDsmSIQueryRef)
Stop DSM-CC query request. Called by DSM-CC component, and given in clDsmSysCreate setup...
E_SFM_STATUS SFM_RequireSection(H_SfmInstance sfm, PIDFILT pfid, U8BIT *pHeader, void **phBuffer)
This function performs minimal checking of section header data to find out whether SFM requires this ...
Definition: sfm_main.c:257
void STB_OSTaskDelay(U16BIT timeout)
Delay Task for Specifed Time Period.
void DSMCC_DebugSetMask(U32BIT mask)
Set the DSMCC debug mask.
Definition: dsm_control.c:2066
U32BIT DSI_RequestTable(H_DsiInstance dsi, U16BIT pid, U16BIT xid, U8BIT tid)
Request Table data. It supplies Table soon after the call to this function, and then, whenever the Table version changes. This state continues until DSI_CancelTable is called.
Definition: dsm_si.c:284
H_DsmCarousel CDSM_CurrentCarousel(H_DsmCoreInst instance)
Retrieve handle to the current carousel for DSM-CC Instance.
Internal header for DSM-CC si support.
void STB_OSDeleteMutex(void *mutex)
Delete a mutex.
void SFM_DsmccFilterDelete(H_SfmInstance sfm, void *filterHandle, H_DscSFRef dsmSfRef)
Delete DSM-CC section filter. Called by DSM-CC component, and given in clDsmSysCreate setup...
Definition: sfm_filter.c:1026
BOOLEAN DSI_RequireTable(H_DsiInstance dsi, U8BIT *hdr, U16BIT *pXid, U8BIT *pVer)
Check whether SI table section data is required.
Definition: dsm_si.c:439
U8BIT * SBM_AllocateBuffer(H_SbmInstance sbm, U8BIT size1)
Allocate buffer for a DVB section.
Definition: sbm.c:369
H_SiqInstance SIQ_CreateInstance(S_SiqSetup *pSetup)
Create SIQ instance.
Definition: siq_main.c:67
E_DscError CDSM_SetCurrentCarousel(H_DsmCoreInst instance, H_DsmCarousel carouselHandle)
Sets current carousel for DSM-CC Instance.
H_ObjCarousel DSMCC_CurrentCarousel(H_DsmControl dsmctrl)
Get currently loaded carousel handle.
Definition: dsm_control.c:1887
BOOLEAN DSMCC_Start(H_DsmControl dsmctrl, S_DvbLocator *locator, U32BIT boot_carousel_id, DMXREF dmxref)
Start DSM-CC controling instance. This will start search for a boot carousel on service specified by ...
Definition: dsm_control.c:1636
BOOLEAN DSMCC_StartFs(H_DsmControl dsmctrl, U16BIT service_id, U32BIT carousel_id)
Start DSM-CC controlling instance. This must follow call to DSMCC_SetTunedTransportInfo. The function will start search for an Object Carousel on the specified service. The search depends on the value given 'carousel_id' parameter. When carousel id is set to INVALID_CAROUSEL_ID, DSM-CC will attempt to start on a carousel which the client recognises in callback function 'parseDataBroadcastId'. Even when the PMT does not contain a recognised data broadcast id, this function will return TRUE, and the DSM-CC will keep searching. When the carousel id is set to a specific value or UNKNOWN_CAROUSEL_ID and a carousel of the required ID is not present, either this function will return FALSE or 'carouselLoad' callback will be passed a result of OC_LOAD_ABORTED_ERROR. When carousel id is set to UNKNOWN_CAROUSEL_ID, DSM-CC will attempt to start on whatever carousel is signalled in PMT for that service.
Definition: dsm_control.c:1688
void SIQ_TransportChanged(H_SiqInstance siq, U16BIT origNetworkId, U16BIT transportId)
Inform SIQ when tuning to another transport stream. Not required if PAT is supplied to SIQ...
Definition: siq_cache.c:391
void SFM_DsmccFilterPriorityChange(H_SfmInstance sfm, void *filterHandle, H_DscSFRef dsmSfRef, E_SFPriority priority)
Change DSM-CC section filter priority Called by DSM-CC component, and given in clDsmSysCreate setup...
Definition: sfm_filter.c:1128
H_SbmInstance SBM_CreateInstance(S_SbmSetup *pSetup)
Create Section Buffer Manager instance, using setup structure.
Definition: sbm.c:457
E_DscError CDSM_SysProcessTimerEvent(H_DsmCoreInst instance, void *clDsmTmrUserData, E_TimerStatus status, void *timerHandle)
Definition: clDsmMain.c:916
void DSI_CancelTable(H_DsiInstance dsi, U32BIT rid)
Cancel request for table data made by DSI_RequestTable()
Definition: dsm_si.c:337
void DSMCC_SetTunedTransportInfo(H_DsmControl dsmctrl, U16BIT onet_id, U16BIT tran_id, DMXREF dmxref)
Inform DSMCC instance of the tuned transport details. This must be called before calling DSMCC_StartF...
Definition: dsm_control.c:1653
void SFM_SetDemuxHandle(H_SfmInstance sfm, DMXREF demux)
Set handle to be passed to F_DvpFilterSetup and F_DvpFilterRemove.
Definition: sfm_main.c:233
E_DscError CDSM_UnloadModule(H_DsmCoreInst idp, H_DsmCarousel hCarousel, U32BIT moduleRef)
Unload SSU module. To be called once the client has finished saving this module data.
Internal header for DSM-CC control module.
DSM Debug API header.
U8BIT * SFM_CacheBuffer(H_SfmInstance sfm, void *hBuffer)
Get section data buffer pointer in SFM's cache for the handle. This should only be called after SFM_R...
Definition: sfm_cache.c:702
void SFM_DestroyInstance(H_SfmInstance sfm, void **pSfmMtx, void **pCchMtx, void **pBufMtx)
Destroy Section Filter Manager instance, and return mutexes so that they may be destroyed by client...
Definition: sfm_main.c:161
BOOLEAN DSMCC_StartSsu(H_DsmControl dsmctrl, U16BIT service_id, U32BIT oui)
Start DSM-CC controling instance. This must follow call to DSMCC_SetTunedTransportInfo. The function will start loading Update Carousel for SSU on specified service.
Definition: dsm_control.c:1731
U32BIT DSI_CheckRequests(H_DsiInstance dsi, U32BIT now)
Check outstanding PMT (and PAT) requests to see whether any need to be refreshed. ...
Definition: dsm_si.c:373
void DSI_Stop(H_DsiInstance dsi)
Stop getting SI data from Demux.
Definition: dsm_si.c:253
void SIQ_SetDebugConfig(H_SiqInstance siq, F_Printf errPrintf, F_Printf dbgPrintf, U32BIT dbgState)
Set Debug config for SIQ.
Definition: siq_main.c:126
void STB_OSMutexUnlock(void *mutex)
Unlock a mutex (a.k.a. 'leave', 'signal' or 'release')
E_DscError CDSM_LoadCarousel(H_DsmCoreInst instance, U16BIT service_id, U32BIT carousel_id, E_SIQueryKind kind, H_DsmCarousel *pclDsmCarouselHandle)
Request load of a DSM-CC Object Carousel (service domain).
H_SfmInstance SFM_CreateInstance(S_SfmSetup *pSetup)
Create Section Filter Manager instance, using setup structure.
Definition: sfm_main.c:62
void SIQ_ProcessPmt(H_SiqInstance siq, H_SiqPmtTable hNewTable, U16BIT serviceId, U8BIT version)
Provide PMT section data to SIQ. It assumes CRC has been checked and is passing valid PMT sections So...
Definition: siq_cache.c:509
void SFM_FilterUpdate(H_SfmInstance sfm, H_DmxPidFilter hPF)
Update SFM PID filter to configure HW for latest requirements.
Definition: sfm_filter.c:1075
void SIQ_SetDebugState(H_SiqInstance siq, U32BIT dbgState)
Set Debug state for SIQ.
Definition: siq_main.c:141
Dsmcc's Section Filter Manager API.
U32BIT DSMCC_DebugInstanceGetMask(H_DsmControl instance)
Get the DSMCC debug mask for instance.
Definition: dsm_control.c:2097
H_DsmControl DSMCC_Open(S_DsmccConfig *config)
Open DSM-CC and create controling instance.
Definition: dsm_control.c:1507
void SBM_DestroyInstance(H_SbmInstance sbm, void **pBufMtx)
Destroy Section Filter Manager instance, and return mutexes so that they may be destroyed by client...
Definition: sbm.c:517
H_DsmControl DSMCC_FindInstance(U16BIT serviceId, DMXREF dmxref)
Find DSMCC instance that has beed started on specified service.
Definition: dsm_control.c:2031
void DSMCC_SetFileSystemCacheLimit(H_DsmControl dsmctrl, U32BIT cacheSize)
Set limit of DSMCC dynamic memory usage for file system caching This function overrides the default s...
Definition: dsm_control.c:1995
void * STB_OSCreateMutex(void)
Create a mutex.
Main API to DSM-CC core layer (provided functions and required callbacks).
void CDSM_SysSetMemoryMax(H_DsmCoreInst instance, U32BIT maxMemory)
Set maximum memory usage.
Definition: clDsmMain.c:772
void SBM_ReleaseBuffer(H_SbmInstance sbm, U8BIT *buffer)
Release DVB section buffer allocated with SBM_AllocateBuffer.
Definition: sbm.c:432
E_DscError CDSM_UnloadCarousel(H_DsmCoreInst instance, H_DsmCarousel clDsmCarouselHandle, E_DsmRstMode mode)
Unload (or cancel the requested load of) a DSM-CC Object Carousel (service domain). The client MUST first unload all objects before calling this function (which implies it must also have previously closed and/or unsubscribed any events on any loaded objects). If there are any active object loads in the carousel when clDsmUnloadCarousel is called then the unload will not be executed and an error returned. If the carousel is in the process of loading and/or booting the load operation will be aborted (and the notifyCarouselLoadEventFunc callback made with status OC_LOAD_ABORTED_UNLOAD). Any carousel load request that returned a valid CDSM_CarouselHandle(ie. did not generate an error at clDsmLoadCarousel call time), must be explicitly unloaded via clDsmUnloadCarousel. This is necessary, whether the carousel was successfully loaded or the load was aborted due to timeout or error. Once unload is called for a carousel, the clDsmCarouselHandle is no longer valid and must not be used by the client/calling env. If it needs to access the carousel subsequently it must re-load it and get a new clDsmCarouselHandle value. To forcefully destroy loaded objects and/or carousels (eg. where the handles may be unknown/lost) then clDsmReset can be used with force switches. Note that this physically deletes them from the cache whereas unloading (objects or carousels) does not. CALLBACKS THAT MAY BE INITIATED DURING THIS CALL: delSectionFilterFunc stopTimerFunc stopSIQueryFunc unsubscribeSIChange notifyCarouselLoadEventFunc.
Section Buffer Manager (for use by Section Filter Manager and client) Provides mechanism to allocate ...
BOOLEAN STB_OSSemaphoreWaitTimeout(void *semaphore, U16BIT timeout)
Wait on Semaphore for Set Time Period in an Attempt to Acquire.
void DSMCC_SiqCacheClearPmt(H_DsmControl dsmctrl, U16BIT serviceId)
Clear cached PMT for particular service.
Definition: dsm_control.c:2008
Dsmcc's Service Information Query API.
void DSMCC_Stop(H_DsmControl dsmctrl, E_DsmRstMode mode)
Stop DSM-CC controling instance. Causes all carousels to unload.
Definition: dsm_control.c:1783
void DSMCC_DebugInstanceEnable(H_DsmControl dsmctrl, const char *rootname)
Enable DSMCC debug for an instance, by reading environment variables with name format: <rootname>_<ma...
Definition: dsm_control.c:2154
H_SiqPmtTable SIQ_ParsePmt(H_SiqInstance siq, U8BIT *pmt)
Provide PMT section data to SIQ. It assumes CRC has been checked and is passing valid PMT sections So...
Definition: siq_cache.c:494
void SIQ_CacheClearPmt(H_SiqInstance siq, U16BIT serviceId)
Clear cached PMT information.
Definition: siq_cache.c:595
void SFM_CacheReleaseBuffer(H_SfmInstance sfm, U8BIT *pSection, void *hBuffer)
Release Cache buffer allocated by SFM_CacheBuffer.
Definition: sfm_cache.c:725
Definition: sbm.h:37
BOOLEAN DSMCC_SetCurrentCarousel(H_DsmControl dsmctrl, H_ObjCarousel hOC)
Set current carousel. This does not unload any previously loaded carousels.
Definition: dsm_control.c:1920
void SIQ_DestroyInstance(H_SiqInstance siq)
Destroy instance created by SIQ_CreateInstance.
Definition: siq_main.c:152
void SIQ_UpdatePat(H_SiqInstance siq, U8BIT *dptr)
Provide SIQ with latest PAT data. Calling this function is optional. However, if not used...
Definition: siq_cache.c:301
void SFM_SetDebugConfig(H_SfmInstance sfm, F_Printf errPrintf, F_Printf dbgPrintf, U32BIT dbgState)
This allows controlling software to reconfigure SFM debug output.
Definition: sfm_main.c:192
void DSMCC_Reboot(H_DsmControl dsmctrl)
Reboot DSM-CC controling instance. Causes all carousels to unload and initiate search for boot carous...
Definition: dsm_control.c:1833
E_DscError SIQ_ServiceInfoChangeSubscribe(H_SiqInstance siq, U16BIT serviceId)
Subscribe a component to receive notification of any changes or alterations to the service informatio...
void DSMCC_DebugInstanceSetMask(H_DsmControl instance, U32BIT mask)
Set the DSMCC debug mask.
Definition: dsm_control.c:2122
void SFM_ProcessSection(H_SfmInstance sfm, U8BIT *pSection, void *hBuffer)
Process required section buffer. This should only be called after SFM_RequireSection has returned SFM...
Definition: sfm_main.c:299
E_DscError CDSM_SysSetCurrService(H_DsmCoreInst instance, U16BIT original_network_id, U16BIT transport_stream_id, U16BIT service_id)
Set/notify the current service (initially and when changing it). This MUST be called initially (ie...
Definition: clDsmMain.c:819
void SIQ_SetDsmInstance(H_SiqInstance siq, H_DsmCoreInst dsm)
Set instance handle for DSM-CC that SIQ is supporting.
Definition: siq_main.c:176
void STB_OSMutexLock(void *mutex)
Lock a mutex (a.k.a. 'enter', 'wait' or 'get').
void DsmccObjectLoadEventFunc(H_DsmObject objectHandle, E_ObjLoadStatus status, H_ObjUserData pUserData)
Callback function provided to DSM-CC library. Object load events are passed to this callback by the D...
Definition: dsm_client.c:506
U32BIT DSMCC_CurrentCarouselId(H_DsmControl dsmctrl)
Get currently loaded carousel ID.
Definition: dsm_control.c:1901
void CDSM_SetPrintFuncs(F_Printf errorFunc, F_Printf warnFunc, F_Printf debugFunc, F_Printf infoFunc)
Sets debug print functions for four different levels of detail. Any of these parameters can be set to...
Definition: clDsmMain.c:145
H_DsiInstance DSI_CreateInstance(H_DsmControl ctrl, F_FILTER_CALLBACK cbfunc, S_DsmccConfig *config)
Create instance of DSI.
Definition: dsm_si.c:197
E_SIQ_STATUS SIQ_RequirePmt(H_SiqInstance siq, U8BIT *pmt, U16BIT *pSid, U8BIT *pVer)
Ask SIQ whether PMT section data is required. It assumes CRC has been checked and is passing valid PM...
Definition: siq_cache.c:433
API to register PMT Observer with DVB SI task.
BOOLEAN DSMCC_StartSsuWithPid(H_DsmControl dsmctrl, U16BIT pid, U32BIT oui)
Start DSM-CC controling instance. This must follow call to DSMCC_SetTunedTransportInfo. The function will start loading Update Carousel for SSU on a single specified PID.
Definition: dsm_control.c:1761
E_DscError CDSM_SysReset(H_DsmCoreInst instance, E_DsmRstMode mode)
Reset DSM-CC Core Layer instance. Resets conditions to the same state as after CDSM_SysCreate(ie. keeps setup parameters). In normal operation the client MUST first unsubscribe all events, close and and unload all objects and unload all carousels before calling this function. This will have also stopped/deleted all associated system resources (ie. SI queries, timers, SI change monitors, section filters). If any client transactions or system transactions are still active when clDsmReset is called the reset will not be executed and an error returned. NB. The calling environment (system side) must acknowledge stop commands for SI Queries and timers (via processSIQueryEvent, processTimerEvent) and that these may occur asynchronously (ie. after a delay). This means that there may still be some active system transactions for some time after all objects and carousels are unloaded. FORCING RESET IN ERROR CONDITIONS: If all client and system transactions are apparently completed but still returns an error (eg. because handles are unknown/lost or system resource stop requests are not acknowledged) then clDsmReset can be called with appropriate force switches to clear the error condition. Any client transaction errors must first be cleared before system transaction errors can be cleared and both force switches cannot be set at the same time. NB. Only use force switches in known error conditions. It is potentially fatal (may cause illegal memory access) to call the functions: streamEventUnsubscribe, unloadObject, unloadCarousel, processSIQueryEvent, processTimerEvent with old/stale handles after clDsmReset has been forced. CALLBACKS THAT MAY BE INITIATED DURING THIS CALL: deleteSectionFilter stopTimer stopSIQuery unsubscribeSIChange.
Definition: clDsmMain.c:669
E_DscError CDSM_SysDestroy(H_DsmCoreInst instance, H_SiqInstance *pSiqInst, H_SfmInstance *pSfmInst)
Destroy DSM-CC Core Layer instance. De-allocates all 'static' memory used by the instance (via freeFu...
Definition: clDsmMain.c:467
void DSMCC_Close(H_DsmControl dsmctrl)
Close DSM-CC controling instance, and destroy all resources.
Definition: dsm_control.c:1580
const char * DSMCC_VersionString(void)
Returns version major.minor.patch as string.
Definition: dsm_control.c:2020
void CDSM_SetDebugState(H_DsmCoreInst dsm, U32BIT dbgMask)
Set Debug mask for core DSM.
Definition: clDsmMain.c:169
U32BIT(* F_DvpRequestTable)(void *ref, U16BIT pid, U16BIT xid, U8BIT tid)
SIQ requests table data - normally PMT, but could be UNT. Table data should be given to appropriate f...
Definition: dsiq.h:57
void * STB_OSCreateTask(void(*function)(void *), void *param, U32BIT stack, U8BIT priority, U8BIT *name)
Create a New Task to the calling process. Upon success, the created task runs on its own stack...
void DSI_DestroyInstance(H_DsiInstance dsi)
Destroy instance created by SIQ_CreateInstance.
Definition: dsm_si.c:229
void DSMCC_UnloadCarousel(H_DsmControl dsmctrl, H_ObjCarousel hOC, E_DsmRstMode mode)
Unload specified Carousel.
Definition: dsm_control.c:1945
void STB_SPDebugNoCnWrite(const char *format,...)
Writes debug string to the serial port without <CR><LF>
void * STB_OSCreateCountSemaphore(U32BIT value)
Create a counting semaphore.
void SFM_SetDebugState(H_SfmInstance sfm, U32BIT dbgState)
This allows controlling software to reconfigure SFM debug output.
Definition: sfm_main.c:209
BOOLEAN DSI_Start(H_DsiInstance dsi, U16BIT transId, DMXREF dmxref)
Start getting SI data from Demux.
Definition: dsm_si.c:242
void(* F_DvpCancelTable)(void *ref, U32BIT rid)
Cancel request for Table data made by F_DvpRequestTable()
Definition: dsiq.h:65
void STB_OSDeleteSemaphore(void *semaphore)
Delete a Semaphore.
void CDSM_SetPrintState(U32BIT state)
Sets debug print state to select areas of debug.
Definition: clDsmMain.c:156
E_DscError SIQ_RequestQueryStart(H_SiqInstance siq, P_SIQueryRequest pQuery, H_SIQueryRef clDsmSIQueryRef, void *clDsmSIUserData, P_SIQueryResult pResult)
Start DSM-CC query request. Called by DSM-CC component, and given in clDsmSysCreate setup...
void STB_OSSemaphoreSignal(void *semaphore)
Signal a Semaphore to Release it by decrementing its counter.
U32BIT DSMCC_DebugGetMask(void)
Get the DSMCC debug mask.
Definition: dsm_control.c:2052
void DSMCC_SsuUnloadModule(H_DsmControl dsmctrl, H_DsmCarousel hCarousel, U32BIT moduleRef)
Unload SSU module. To be called once the client has finished saving this modules data. This is needed to.
Definition: dsm_control.c:1970
Function prototypes for operating system.