MHEG5  18.9.0
MHEG5 Documentation
glue_dsmcc.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2013 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  *******************************************************************************/
25 /*---includes for this file--------------------------------------------------*/
26 #include "stb_os.h"
27 #include "glue_memory.h"
28 #include "glue_debug.h"
29 #include "glue_queue.h"
30 #include "glue_main.h"
31 #include "dsm_client.h"
32 #include "dsm_control.h"
33 #include "mh5queue.h"
34 #include "mh5control.h"
35 #include "mh5display.h"
36 #include "dvb_service.h"
37 #ifdef MULTI_OSD_LANGS
38 #include "dvb_misc.h"
39 #else
40 #include "dvb_native.h"
41 #endif
42 #include "glue_dsmcc.h"
43 #include "glue_events.h"
44 #ifdef INCLUDE_DSM_FG
45 #include "mh5filegroup.h"
46 #include "mh5fileorm.h"
47 #endif
48 
49 /*---constant definitions for this file--------------------------------------*/
50 
51 #define DBC_ID_SSU 0x000A
52 #define DBC_ID_MHEG5 0x0106
53 #define DBC_ID_OAD 0x0111
54 #define DBC_ID_HBBTV 0x0123
55 #define DBC_ID_MHP0 0x00F0
56 #define DBC_ID_MHP1 0x00F1
57 
58 #define MHEG_NETBOOT_DESC 0x01
59 #define MHEG_SERVICE_DESC 0x02
60 
61 #define DBC_PREF_NONE 0x0000
62 #define DBC_PREF_MHEG5 0x0100
63 //#define DBC_APP_TYPE_MHEG5 0x0008
64 //#define DBC_APP_TYPE_HBBTV 0x0010
65 #define INVALID_ATAG 0xFFFF
66 #define LIFECYCLE_EVENT_ID 0xFFFF
67 #define INVALID_NB 0xFF
68 
69 #define MAX_PATH_NAME_SIZE 65
70 
71 #ifndef DSMCC_SECTION_CACHE_64K_BUFFERS
72 #define DSMCC_SECTION_CACHE_64K_BUFFERS 16
73 #endif
74 
75 #ifndef DSMCC_WORKING_4K_BUFFER_POOL
76 #define DSMCC_WORKING_4K_BUFFER_POOL 180
77 #endif
78 #ifdef MULTI_OSD_LANGS
79 #define MAX_LANG_CODES 4
80 #else
81 #define MAX_LANG_CODES 1
82 #define DVB_MhegOsdLanguageCodes MhegOsdLanguageCodes
83 #endif
84 
85 /*---local typedef structs for this file-------------------------------------*/
86 
87 typedef struct s_dbc_app
88 {
89  struct s_dbc_app *next;
96 } S_DBC_APP;
97 
98 typedef struct s_service_dbc
99 {
103 } S_SERVICE_DBC;
104 
105 /*---local (static) variable declarations for this file----------------------*/
106 /* (internal variables declared static to make them local) */
107 
108 static H_DsmControl dsmccControl = NULL;
109 static const S_STRING null_str = { 0, NULL };
110 
111 static S_SERVICE_DBC *service_dbcs = NULL;
112 static S_DBC_APP *temp_apps = NULL;
113 static H_DsmEvent lifecycle_ehdl = 0;
114 static U32BIT boot_carousel_id = INVALID_CAROUSEL_ID;
115 static void *dbc_mutex = 0;
116 
117 /*------------------- Local function definitions ----------------------------*/
118 
119 #ifndef MULTI_OSD_LANGS
121 {
122  U8BIT lang[4] = { 0, 0, 0, 0 };
123  if (DVB_MhegGetOSDLanguage(lang) == MHERR_OK)
124  {
125  *langcodes = (lang[0]<<16)|(lang[1]<<8)|lang[2];
126  return 1;
127  }
128  return 0;
129 }
130 #endif
131 
132 static S_SERVICE_DBC* FindServiceDbc( U16BIT service_id )
133 {
134  S_SERVICE_DBC *sdbc = service_dbcs;
135  while (sdbc != NULL && sdbc->service_id != service_id)
136  {
137  sdbc = sdbc->next;
138  }
139  return sdbc;
140 }
141 
142 static H_PmtRef ParsePmtStartup( U16BIT service_id )
143 {
144  S_SERVICE_DBC *sdbc;
145  DBGTRACE(TSERVICE,"****> service_id=%d",service_id)
146  if (service_id == MHEG5GetVideoSid()
147  || service_id == MHEG5GetAudioSid()
148  || service_id == MHEG5DefaultServiceId())
149  {
150  MHEG5RefreshStreams(service_id);
151  }
152  STB_OSMutexLock(dbc_mutex);
153  sdbc = FindServiceDbc( service_id );
154  if (sdbc == NULL)
155  {
156  sdbc = STB_MemAlloc( sizeof(S_SERVICE_DBC));
157  if (sdbc != NULL)
158  {
159  sdbc->service_id = service_id;
160  sdbc->dbc_apps = NULL;
161  sdbc->next = service_dbcs;
162  service_dbcs = sdbc;
163  }
164  }
165  return (H_PmtRef)sdbc;
166 }
167 
168 static S_DBC_APP* FindDbcApp( S_SERVICE_DBC *dbc, U32BIT carouselId )
169 {
170  S_DBC_APP *app;
171  if (dbc == NULL)
172  {
173  app = NULL;
174  }
175  else
176  {
177  app = dbc->dbc_apps;
178  while (app != NULL && app->carouselId != carouselId)
179  {
180  app = app->next;
181  }
182  }
183  return app;
184 }
185 
186 static S_DBC_APP* CreateDbcApp( U32BIT carouselId, U32BIT appId )
187 {
188  S_DBC_APP *app;
189  app = STB_MemAlloc( sizeof(S_DBC_APP));
190  if (app != NULL)
191  {
192  app->carouselId = carouselId;
193  app->appId = appId;
195  app->nb_version = INVALID_NB;
196  app->nb_action = INVALID_NB;
197  app->nb_info.zlen = 0;
198  app->nb_info.zptr = NULL;
199  app->next = temp_apps;
200  temp_apps = app;
201  }
202  return app;
203 }
204 
205 static S_DBC_APP* RemoveDbcApp( S_SERVICE_DBC *dbc, U32BIT carouselId )
206 {
207  S_DBC_APP *app, **pApp;
208  if (dbc == NULL)
209  {
210  app = NULL;
211  }
212  else
213  {
214  app = dbc->dbc_apps;
215  pApp = &(dbc->dbc_apps);
216  while (app != NULL)
217  {
218  if (app->carouselId == carouselId)
219  {
220  *pApp = app->next;
221  break;
222  }
223  pApp = &(app->next);
224  app = app->next;
225  }
226  }
227  return app;
228 }
229 
230 static void ClearDbcApps( S_SERVICE_DBC *dbc )
231 {
232  S_DBC_APP *app, *nxt;
233  app = dbc->dbc_apps;
234  while (app != NULL)
235  {
236  nxt = app->next;
237  STB_MemFree( app );
238  app = nxt;
239  }
240  dbc->dbc_apps = NULL;
241 }
242 
243 static void ClearServiceDbcs( void )
244 {
245  S_SERVICE_DBC *dbc, *nxt;
246  dbc = service_dbcs;
247  while (dbc != NULL)
248  {
249  nxt = dbc->next;
250  ClearDbcApps( dbc );
251  STB_MemFree( dbc );
252  dbc = nxt;
253  }
254  service_dbcs = NULL;
255 }
256 
262 static void ParseMhegDescriptors( S_DBC_APP *app, U8BIT *dptr, U16BIT dlen )
263 {
264  U8BIT *dptr_end, tag, len;
265  U8BIT nb_len = 0, *nb_ptr;
266  FUNCTION_START(ParseMhegDescriptors)
267  dptr_end = dptr + dlen;
268  while (dptr < dptr_end)
269  {
270  tag = *dptr++;
271  len = *dptr++;
272  switch (tag)
273  {
274  case MHEG_NETBOOT_DESC:
275  /* Network boot info sub-descriptor */
276  app->nb_version = dptr[0];
277  app->nb_action = dptr[1];
278  if (len > 2)
279  {
280  nb_len = len - 2;
281  nb_ptr = &dptr[2];
282  }
283  DBGTRACE(TSERVICE, " nb_version=0x%x nb_action=0x%x nb_length=0x%x", app->nb_version, app->nb_action, nb_len )
284  break;
285 
286  case MHEG_SERVICE_DESC:
287  /* Service boot info sub-descriptor */
288  app->associationTag = dptr[0] << 8 | dptr[1];
289  DBGTRACE(TSERVICE, " SERVICE-BOOT-INFO: assoc_tag=0x%x", app->associationTag)
290  break;
291 
292  default:
293  DBGTRACE(TERROR, "Unknown Mheg tag 0x%x", tag);
294  }
295  dptr += len;
296  }
297  if (nb_len)
298  {
299  app->nb_info = MH5GlueStringCreate( nb_len, nb_ptr );
300  }
301  FUNCTION_FINISH(ParseMhegDescriptors)
302 }
303 
304 static void LifecycleFunc( void *userData, U8BIT *name, U32BIT dataLen, U8BIT *dataPtr )
305 {
306  DBGTRACE(TALWAYS, " ***************************** Rebooting! ")
307 
308  // Strictly, clearing the PMT in cache is not required by MHEG spec,
309  // but DTG's NDT009 test has lifecycle event just before PMT change
310  // and test fails if gets earlier PMT.
311  // Clearing of the cached PMT here, makes some sense, but...
312  // DTG HD test version 7.50 to 7.80 has such bad timing between LC event and PMT change,
313  // that even this (not too unreasonable bodge) does not always 'fix' it. See Squish #3748.
314  DSMCC_SiqCacheClearPmt( dsmccControl, MHEG5DefaultServiceId() );
315 
316  MHEG5_Reboot();
317 }
318 
323 void StopLifecycle(void)
324 {
325  if (lifecycle_ehdl != 0)
326  {
327  DBGTRACE(TSERVICE, "clear Lifecycle")
328  DSMCC_ClientEventUnsubscribe(dsmccControl, lifecycle_ehdl);
329  lifecycle_ehdl = 0;
330  }
331 }
332 
333 static void StartLifecycle( U16BIT atag )
334 {
335  static U16BIT lastatag = INVALID_ATAG;
336  if (lastatag != atag)
337  {
338  DBGTRACE(TSERVICE, "clear Lifecycle atag=0x%x", lastatag)
339  StopLifecycle();
340  }
341  if (lifecycle_ehdl == 0)
342  {
343  DBGTRACE(TSERVICE, "Starting Lifecycle listen on atag=0x%x", atag)
344  if (DSMCC_ClientEventSubscribeId( dsmccControl, atag, LIFECYCLE_EVENT_ID,
345  LifecycleFunc, NULL, &lifecycle_ehdl ))
346  {
347  TRACE(TERROR, (""))
348  }
349  else
350  {
351  lastatag = atag;
352  }
353  }
354 }
355 
361 static void ProcessMhegDescriptorChange( S_DBC_APP *oldapp, S_DBC_APP *newapp )
362 {
363  if (newapp == NULL)
364  {
365  DBGTRACE(TERROR, "No new application")
366  }
367  else
368  {
369  DBGTRACE(TSERVICE, "updated application, LC-atag=0x%x nbact=%d nbver=%d oldapp=%p",
370  newapp->associationTag, newapp->nb_action, newapp->nb_version, oldapp)
371  if (newapp->associationTag != INVALID_ATAG)
372  {
373  StartLifecycle( newapp->associationTag );
374  }
375  if (oldapp == NULL ||
376  newapp->nb_version != oldapp->nb_version)
377  {
378  switch (newapp->nb_action)
379  {
380  case 0x01:
382  {
383  MHEG5_Reboot();
384  break;
385  }
386  /*else fall tho, and send netboot to CI App */
387  case 0x02:
388  DBGTRACE(TSERVICE, "Send EE_NETWORK_BOOT_INFO")
390  break;
391  default:;
392  }
393  }
394  }
395 }
396 
397 static void ParsePmtFinished(H_PmtRef pmtref)
398 {
399  S_DBC_APP *oldapp, *nxtapp;
400  S_SERVICE_DBC *sdbc = (S_SERVICE_DBC *)pmtref;
401 
402  DBGTRACE(TSERVICE, "<*** sid=%d boot_cid=%d",sdbc->service_id,boot_carousel_id)
403  oldapp = sdbc->dbc_apps;
404  while (oldapp != NULL)
405  {
406  /* there is no longer a data_broadcast id for apps (with carousel id) */
407  nxtapp = oldapp->next;
408  if (boot_carousel_id == oldapp->carouselId &&
410  {
411  DBGTRACE(TALWAYS, " ***************************** Rebooting! ")
412  MHEG5_Reboot();
413  boot_carousel_id = INVALID_CAROUSEL_ID;
414  }
415  MH5GlueStringFree( &oldapp->nb_info );
416  STB_MemFree( oldapp );
417  oldapp = nxtapp;
418  }
419  sdbc->dbc_apps = temp_apps;
420  temp_apps = NULL;
421  STB_OSMutexUnlock(dbc_mutex);
422 }
423 
436 static U32BIT ParseDataBcastId( H_PmtRef pmtref, U32BIT carouselId,
437  U8BIT *dbcPtr, U8BIT dbcLen )
438 {
439  U32BIT pref = DBC_PREF_NONE;
440  U16BIT dbcId, appType;
441  U8BIT *dptr_end, *dptr;
442  U8BIT app_len;
443  U16BIT boot_priority = 0;
444  S_SERVICE_DBC *dbc;
445  S_DBC_APP *oldapp, *newapp;
446 
447  FUNCTION_START(ParseDataBcastId)
448 
449  dptr = dbcPtr;
450  dptr_end = dptr + dbcLen;
451  dbcId = dptr[0] << 8 | dptr[1];
452  dptr += 2;
453  switch (dbcId)
454  {
455  case DBC_ID_MHEG5:
456  dbc = (S_SERVICE_DBC *)pmtref;
457  assert( dbc != NULL ); /* SiqProcessPmt ensures this */
458  oldapp = RemoveDbcApp(dbc, carouselId);
459  newapp = NULL;
460  while (dptr < dptr_end)
461  {
462  appType = dptr[0] << 8 | dptr[1];
463  dptr += 2;
464  boot_priority = DBC_PREF_MHEG5 + *dptr;
465  dptr++;
466  app_len = *dptr++;
467  switch (appType)
468  {
469  case 0x0505:
470  case 0x0101:
471  if (pref < boot_priority)
472  {
473  pref = boot_priority;
474  }
475  /* now fall through to 0x0000 app type */
476  case 0x0000: /* this is when no auto-boot app is present, see DBook7 A, C.1 */
477  assert( newapp == NULL );
478  newapp = CreateDbcApp(carouselId, (dbcId << 16) | appType);
479  if (newapp == NULL)
480  {
481  DBGTRACE(TERROR, "Memory failure")
482  }
483  else
484  {
485  DBGTRACE(TSERVICE, "MHEG app type 0x%x (bp=%x)",appType,boot_priority)
486  ParseMhegDescriptors( newapp, dptr, app_len );
487  }
488  break;
489 
490  default:
491  DBGTRACE(TERROR, "Unsupported MHEG app type 0x%x", appType);
492  }
493  dptr += app_len;
494  }
495  if (dbc->service_id == MHEG5DefaultServiceId())
496  {
497  /* Pmt Update on current service */
498  if (DSMCC_CurrentCarouselId(dsmccControl) == carouselId)
499  {
500  DBGTRACE(TSERVICE, "carouselId=%d",carouselId)
501  ProcessMhegDescriptorChange( oldapp, newapp );
502  }
503  }
504  if (oldapp != NULL)
505  {
506  MH5GlueStringFree( &oldapp->nb_info );
507  STB_MemFree( oldapp );
508  }
509  break;
510 
511  default:
512  DBGTRACE(TERROR, "Unsupported Data Broadcast ID 0x%x", dbcId);
513  }
514  FUNCTION_FINISH(ParseDataBcastId)
515  return pref;
516 }
517 
518 /*------------------- Global function definitions ---------------------------*/
519 
520 
521 
522 
527 static U32BIT MH5GlueSiqCurrentApplicationId(void)
528 {
529  S_SERVICE_DBC *sdbc;
530  S_DBC_APP *app;
531  U32BIT id;
532  id = DSMCC_CurrentCarouselId(dsmccControl);
533  STB_OSMutexLock(dbc_mutex);
534  sdbc = FindServiceDbc( MHEG5DefaultServiceId() );
535  DBGTRACE(TSERVICE, "sid=%d,cid=%d", MHEG5DefaultServiceId(), id)
536  app = FindDbcApp( sdbc, id );
537  if (app == NULL)
538  {
539  DBGTRACE(TERROR, "No current app")
540  id = 0;
541  }
542  else
543  {
544  id = app->appId;
545  }
546  STB_OSMutexUnlock(dbc_mutex);
547  DBGTRACE(TSERVICE, "appId=0x%x", id)
548  return id;
549 }
550 
557 {
558  S_DBC_APP *app;
559  S_SERVICE_DBC *sdbc;
561  BOOLEAN result;
562  carouselId = DSMCC_CurrentCarouselId(dsmccControl);
563  STB_OSMutexLock(dbc_mutex);
564  sdbc = FindServiceDbc( MHEG5DefaultServiceId() );
565  DBGTRACE(TSERVICE, "sid=%d,cid=%d", MHEG5DefaultServiceId(), carouselId)
566  app = FindDbcApp( sdbc, carouselId );
567  if (app == NULL || app->nb_action == INVALID_NB)
568  {
569  DBGTRACE(TERROR, "No app (%p) or no net boot desc", app)
570  result = FALSE;
571  }
572  else
573  {
574  DBGTRACE(TSERVICE, "nb_info=%d %s", app->nb_info.zlen, app->nb_info.zptr) *
575  nbinfo = app->nb_info;
576  result = TRUE;
577  }
578  STB_OSMutexUnlock(dbc_mutex);
579  return result;
580 }
581 
586 static void MH5GlueSiqNewBootCarousel( U32BIT carouselId )
587 {
588  S_DBC_APP *app;
589  U16BIT atag;
590  DBGTRACE(TSERVICE, "sid=%d,cid=%d", MHEG5DefaultServiceId(), carouselId)
591  STB_OSMutexLock(dbc_mutex);
592  app = FindDbcApp( FindServiceDbc( MHEG5DefaultServiceId() ), carouselId );
593  if (app != NULL)
594  {
595  atag = app->associationTag;
596  DBGTRACE(TSERVICE, "LC-atag=0x%x", atag)
597  }
598  else
599  {
600  atag = INVALID_ATAG;
601  }
602  STB_OSMutexUnlock(dbc_mutex);
603  if (atag != INVALID_ATAG)
604  {
605  StartLifecycle( atag );
606  }
607 }
608 
609 static void CarouselLoadEvent( H_ObjCarousel carouselRef, E_OCLoadStatus status, U32BIT carouselId )
610 {
611  S_MhegMessage msg;
612  DBGTRACE(TMHBOOT|TDSMFG, " ( 0x%x, %d, 0x%x )", carouselRef, status, carouselId )
613 
614  switch (status)
615  {
616  case OC_LOAD_BOOTED:
617  TRACE(TMHBOOT, ("OC_LOAD_BOOTED"));
618  if (boot_carousel_id == INVALID_CAROUSEL_ID)
619  {
620  boot_carousel_id = carouselId;
621  MH5GlueSiqNewBootCarousel( carouselId );
622  }
624  msg.data_type = DT_VALUE;
625  msg.data.dsmEvent.hCarousel = carouselRef;
626  VQ_PutMsg(&msg, PRTY_HIGH);
627  break;
628 
629  case OC_LOAD_ABORTED_TIMEOUT:
630  case OC_LOAD_ABORTED_PATH_ERROR:
631  case OC_LOAD_ABORTED_ERROR:
632  TRACE(TERROR, ("OC_LOAD_ABORTED_... %d", status));
634  msg.data_type = DT_NONE;
635  VQ_PutMsg(&msg, PRTY_HIGH);
636  break;
637 
638  case OC_LOAD_COMPLETED:
639  TRACE(TMHBOOT, ("OC_LOAD_COMPLETED"));
641  msg.data_type = DT_VALUE;
642  msg.data.dsmEvent.hCarousel = carouselRef;
643  VQ_PutMsg(&msg, PRTY_HIGH);
644  break;
645 
646  #ifdef INCLUDE_DSM_FG
647  case OC_FILE_GROUP_LIST_LOADED:
648  TRACE(TMHBOOT, ("OC_FILE_GROUP_LIST_LOADED"));
650  msg.data_type = DT_VALUE;
651  msg.data.dsmEvent.hCarousel = carouselRef;
652  VQ_PutMsg(&msg, PRTY_HIGH);
653  break;
654 
655  case OC_FILE_GROUP_LIST_CHANGE:
656  TRACE(TMHBOOT, ("OC_FILE_GROUP_LIST_CHANGE"));
658  msg.data_type = DT_VALUE;
659  msg.data.dsmEvent.hCarousel = carouselRef;
660  VQ_PutMsg(&msg, PRTY_HIGH);
661  break;
662 
663  case OC_FILE_GROUP_VERS_CHANGE:
664  TRACE(TMHBOOT, ("OC_FILE_GROUP_VERS_CHANGE"));
666  msg.data_type = DT_VALUE;
667  msg.data.dsmEvent.hCarousel = carouselRef;
668  VQ_PutMsg(&msg, PRTY_HIGH);
669  break;
670  #endif
671 
672  case OC_LOAD_ABORTED_UNLOAD:
673  TRACE(TMHBOOT, ("OC_LOAD_ABORTED_UNLOAD"));
674  if (boot_carousel_id == carouselId)
675  {
676  boot_carousel_id = INVALID_CAROUSEL_ID;
677  }
679  msg.data_type = DT_VALUE;
680  msg.data.dsmEvent.hCarousel = carouselRef;
681  VQ_PutMsg(&msg, PRTY_HIGH);
682  break;
683 
684  case OC_LOAD_IN_PROGRESS:
685  default:
686  TRACE(TERROR, ("Ignore status %d", status));
687  break;
688  }
689 }
690 
692 {
693  E_MhegErr err;
694  S_DsmccConfig config;
695 
696  err = MHERR_OK;
697 
698  config.taskPriority = taskPriority - 1;
699 
700  config.sectionBuffPoolSize = DSMCC_WORKING_4K_BUFFER_POOL;
701 
702  config.sectionBuffCacheSize = DSMCC_SECTION_CACHE_64K_BUFFERS;
703 
704  config.memAlloc = STB_MemAlloc;
705  config.memFree = STB_MemFree;
706 
707  config.parsePmtInit = ParsePmtStartup;
708  config.parseDataBroadcastId = ParseDataBcastId;
709  config.parsePmtDone = ParsePmtFinished;
710 
711  config.carouselLoad = CarouselLoadEvent;
712 
713  config.notifyAitInfo = NULL;
714  config.obtainSiDirect = FALSE;
715 
716  dbc_mutex = STB_OSCreateMutex();
717  if (dbc_mutex == NULL)
718  {
720  }
721  else
722  {
723  dsmccControl = DSMCC_Open( &config );
724  if (dsmccControl == NULL)
725  {
726  STB_OSDeleteMutex(dbc_mutex);
728  }
729  }
730  return err;
731 }
732 
734 {
735  DSMCC_Close( dsmccControl );
736  STB_OSDeleteMutex(dbc_mutex);
737 }
738 
740 {
741  if (clear)
742  {
743  DBGTRACE(TSERVICE, "tid=0x%x", pDvbLoc->transport_stream_id );
744  STB_OSMutexLock(dbc_mutex);
745  ClearServiceDbcs();
746  STB_OSMutexUnlock(dbc_mutex);
747  }
748  if (!DSMCC_Start( dsmccControl, pDvbLoc, carouselId, DVB_MhegGetDemuxPath()))
749  {
750  /* This may be a failed NDT. Sensible to clear down and try again (and this time: autoboot) */
751  DSMCC_Stop( dsmccControl, RST_MODE_FORCE );
753  if (!DSMCC_Start( dsmccControl, pDvbLoc, INVALID_CAROUSEL_ID, DVB_MhegGetDemuxPath()))
754  {
755  return MHERR_OTHER;
756  }
757  }
758  return MHERR_OK;
759 }
760 
761 void MH5GlueDsmccStop( U8BIT action )
762 {
763  if (action == STOP_ACTION_MHEG_TUNE)
764  {
765  DSMCC_Stop( dsmccControl, RST_MODE_PENDING );
766  }
767  else
768  {
769  StopLifecycle();
770  DSMCC_Stop( dsmccControl, RST_MODE_FORCE );
771  }
772 }
773 
774 /*******************************************************************************
775  * @brief Get the DSMCC instance handle.
776  * @return dsmcc instance
777  *******************************************************************************/
779 {
780  return dsmccControl;
781 }
782 
783 static void AutobootClear( void *data )
784 {
786 }
787 
788 static U8BIT* ParseServiceContext( U32BIT size, U8BIT *data, U32BIT languageCode,
789  S_CONTENT *pContent )
790 {
791  U32BIT iso_639_language_code;
792  U8BIT langNum, number_languages;
793  U8BIT initial_object_length;
794  U8BIT *pathname = NULL;
795 
796  TRACE(TMHBOOT, ("lang code %x", languageCode))
797 
798  number_languages = *data++;
799 
800  for (langNum = 0; langNum != number_languages && size > 4; langNum++)
801  {
802  TRACE(TMHBOOT, ("try language %c%c%c", data[0],data[1],data[2]))
803  iso_639_language_code = (U32BIT)data[0];
804  iso_639_language_code = (U32BIT)((iso_639_language_code << 8) | data[1]);
805  iso_639_language_code = (U32BIT)((iso_639_language_code << 8) | data[2]);
806  data += 3;
807  initial_object_length = (U16BIT)*data++;
808  size -= 4;
809  if (size < initial_object_length)
810  {
811  break;
812  }
813  if (iso_639_language_code == languageCode)
814  {
815  pathname = STR_DataAlloc(MAX_PATH_NAME_SIZE);
816  if (pathname)
817  {
818  /* We have found the required language */
819  pathname[0] = '/';
820  pathname[1] = '/';
821  memcpy( pathname + 2, data, initial_object_length );
822  pContent->size = MAX_PATH_NAME_SIZE;
823  pContent->data = pathname;
824  pContent->destroy = AutobootClear;
825  pContent->fs_handle = pathname;
826  TRACE(TMHBOOT, ("Found language %c%c%c path=%s", data[-4],data[-3],data[-2], pathname))
827  }
828  break;
829  }
830  /* Skip Application Boot Context Service List */
831  data += initial_object_length;
832  size -= initial_object_length;
833  }
834  return pathname;
835 }
836 
837 void RunAutoboot( S_CONTENT *pContent )
838 {
839  TRACE(TMHBOOT, ("%p",pContent->data))
840  MHEG5engineStart(pContent->data, FALSE, FALSE);
841  if (pContent->destroy)
842  {
843  pContent->destroy( pContent->fs_handle );
844  }
845 }
846 
847 static void ServiceContextComplete( E_FsStatus status, S_CONTENT *content )
848 {
849  S_MhegMessage msg;
850  if (status == FS_STATUS_OK)
851  {
852  msg.data.content.size = 0;
853  msg.data.content.data = NULL;
854  msg.data.content.destroy = NULL;
855  if (content->data != NULL && content->size > 4)
856  {
857  U32BIT langcodes[MAX_LANG_CODES+1];
858  U8BIT langcode_num, id;
859  langcode_num = DVB_MhegOsdLanguageCodes(langcodes,MAX_LANG_CODES);
860  langcodes[langcode_num] = ISO_639_LANG_CODE_UND;
861  langcode_num++;
862  for (id = 0; id != langcode_num; id++)
863  {
864  if (ParseServiceContext(content->size, content->data, langcodes[id], &msg.data.content) != NULL)
865  {
866  break;
867  }
868  }
869  }
870  if (content->destroy)
871  {
872  content->destroy( content->fs_handle );
873  }
875  msg.data_type = DT_CONTENT;
876  if (VQ_PutMsg( &msg, PRTY_NORMAL ) != MHERR_OK)
877  {
878  TRACE(TERROR, ("VQ_PutMsg failed"));
879  if (msg.data.content.destroy)
880  {
882  }
883  }
884  }
885  else
886  {
887  MHEG5AutoPathComplete( status );
888  }
889 }
890 
898 {
899  E_FsStatus retval;
900  U32BIT appId;
901  S_CONTENT dsmcontent;
902  S_CONTENT pathcontent;
903 
904  appId = MH5GlueSiqCurrentApplicationId();
905  if ((appId >> 16) != 0x0106)
906  {
907  /* PMT is not signalling carousel with MHEG - could be for HBBTV */
908  TRACE(TMHBOOT, ("Not MHEG data_broadcast_id 0x%x", (appId >> 16)))
910  }
911  else
912  {
913  /* DSMCC_ClientLoadObject uses content's 'size' parameter as means of passing ServiceID for Service context */
914  dsmcontent.size = appId;
915 
916  retval = DSMCC_ClientLoadObject( MHEG5_DsmccInstance(), (U8BIT *)"", /* NULL pathname for SRG object */
917  LOAD_FLAGS_REQUEST_SERVICE_CONTEXT_BIT | LOAD_FLAGS_DEFAULT,
918  ServiceContextComplete, &dsmcontent );
919  TRACE(TFILE|TMHBOOT, ("rtn=%d", retval))
920  if (retval == FS_STATUS_OK)
921  {
922  pathcontent.size = 0;
923  pathcontent.data = NULL;
924  pathcontent.destroy = NULL;
925  if (dsmcontent.data != NULL && dsmcontent.size > 4)
926  {
927  U32BIT langcodes[MAX_LANG_CODES+1];
928  U8BIT langcode_num, id;
929  langcode_num = DVB_MhegOsdLanguageCodes(langcodes,MAX_LANG_CODES);
930  langcodes[langcode_num] = ISO_639_LANG_CODE_UND;
931  langcode_num++;
932  for (id = 0; id != langcode_num; id++)
933  {
934  if (ParseServiceContext(dsmcontent.size, dsmcontent.data, langcodes[id], &pathcontent) != NULL)
935  {
936  break;
937  }
938  }
939  }
940  if (dsmcontent.destroy)
941  {
942  /* Now can unload SRG object */
943  dsmcontent.destroy( dsmcontent.fs_handle );
944  }
945  RunAutoboot( &pathcontent );
946  }
947  else
948  {
949  /* An error ocurred */
950  TRACE(TERROR, ("retval is %d", retval));
951  MHEG5AutoPathComplete( retval );
952  }
953  }
954 }
955 
956 void MH5GlueDsmccReboot( void )
957 {
958  DSMCC_Reboot( dsmccControl );
959 }
960 
Implement MHEG5 engine control functions (i.e. start/stop etc)
void StopLifecycle(void)
Clear MHEG Lifecycle Event listening.
Definition: glue_dsmcc.c:323
void MH5GlueDsmccStop(U8BIT action)
Definition: glue_dsmcc.c:761
E_MhegErr VQ_PutMsg(S_MhegMessage *pMsg, E_PRIORITY priority)
Post event or section message on queue. Copies data into queue.
Definition: glue_queue.c:248
#define FUNCTION_FINISH(name)
Definition: glue_debug.h:143
void MHEG5engineStart(U8BIT *app_name, BOOLEAN isCi, BOOLEAN special)
Start the engine with the initial application.
Definition: mh5control.c:447
#define MAX_PATH_NAME_SIZE
Definition: glue_dsmcc.c:69
F_MSG_PROCESS proc_msg_func
Definition: glue_queue.h:198
F_DESTROY destroy
Definition: fs_types.h:56
S_STRING MH5GlueStringCreate(U32BIT size, U8BIT *data)
Definition: glue_memory.c:956
U32BIT size
Definition: fs_types.h:54
void MHEG5NotifyCarouselLoaded(S_DsmccEvent *param)
Definition: mh5control.c:1037
File acceleration for Australia and Souh Africa.
Interface functions to DSM-CC instance for MHEG5.
U16BIT MHEG5GetVideoSid(void)
Definition: mh5display.c:2352
H_ObjCarousel hCarousel
Definition: glue_queue.h:87
#define DBGTRACE(...)
Definition: glue_debug.h:126
const char * data
Definition: mh5gate.c:56
void MHEG5RefreshStreams(U16BIT service_id)
Definition: mh5control.c:1211
#define MAX_LANG_CODES
Definition: glue_dsmcc.c:81
void MH5GlueDsmccMHEGInitialBoot(void)
Causes the autoboot application to be launched. The component must be in the correct state (DSM-CC bo...
Definition: glue_dsmcc.c:897
U16BIT service_id
Definition: glue_dsmcc.c:101
void FG_NotifyListChanged(S_DsmccEvent *param)
Tell File Group that File Groups have changed in Object Carousel&#39;s SRG User Info. ...
void STB_MemFree(void *ptr)
Releases previously allocated memory.
U8BIT nb_action
Definition: glue_dsmcc.c:94
Debug tracing.
#define MHEG_SERVICE_DESC
Definition: glue_dsmcc.c:59
void STB_OSDeleteMutex(void *mutex)
Delete a mutex.
MHEG5 queue.
unsigned char * STR_DataAlloc(unsigned int size)
Definition: glue_memory.c:596
void MH5GlueDsmccReboot(void)
Definition: glue_dsmcc.c:956
void MHEG5NotifyCarouselBooted(S_DsmccEvent *param)
Definition: mh5control.c:564
void MHEG5NotifyCarouselUnload(S_DsmccEvent *param)
Definition: mh5control.c:1061
struct s_service_dbc S_SERVICE_DBC
void MHEG5_SendEngineEvent(E_ENGINE_EVENT engineEvent)
Send MHEG app an engine event from an external task.
Definition: glue_events.c:376
S_DBC_APP * dbc_apps
Definition: glue_dsmcc.c:102
U8BIT * zptr
Definition: dtvstring.h:31
#define DSMCC_SECTION_CACHE_64K_BUFFERS
Definition: glue_dsmcc.c:72
void MH5GlueStringFree(S_STRING *pStr)
Definition: glue_memory.c:986
U16BIT transport_stream_id
Definition: dvblocator.h:33
#define INVALID_NB
Definition: glue_dsmcc.c:67
E_MhegErr
Definition: mherrors.h:28
S_STRING nb_info
Definition: glue_dsmcc.c:95
#define DBC_PREF_MHEG5
Definition: glue_dsmcc.c:62
void(* F_MSG_PROCESS)(void *data)
Function to Process voyager message.
Definition: glue_queue.h:70
#define MHEG_NETBOOT_DESC
Definition: glue_dsmcc.c:58
#define DBC_ID_MHEG5
Definition: glue_dsmcc.c:52
uint8_t U8BIT
Definition: techtype.h:82
#define LIFECYCLE_EVENT_ID
Definition: glue_dsmcc.c:66
DMXREF DVB_MhegGetDemuxPath(void)
Retrieve demux resource reference.
void MH5GlueDsmccClose(void)
Definition: glue_dsmcc.c:733
E_MhegErr MHEG5_Reboot(void)
Reboots MHGE5 Engine This function has the same effect as calling these two: MHEG5_Stop( STOP_ACTION_...
Definition: glue_main.c:956
Memory functions.
DVB Service information functions are required by MHEG5 engine. All required functions should be non-...
void STB_OSMutexUnlock(void *mutex)
Unlock a mutex (a.k.a. &#39;leave&#39;, &#39;signal&#39; or &#39;release&#39;)
void * MHEG5_DsmccInstance(void)
Get the DSMCC instance handle.
Definition: glue_dsmcc.c:778
E_MhegErr MH5GlueDsmccOpen(U32BIT taskPriority)
Definition: glue_dsmcc.c:691
void * STB_MemAlloc(U32BIT memSize)
Allocates the specified number of bytes.
U16BIT associationTag
Definition: glue_dsmcc.c:92
void MHEG5StartReboot(void *dummy)
Definition: mh5control.c:1164
struct s_dbc_app * next
Definition: glue_dsmcc.c:89
U16BIT MHEG5GetAudioSid(void)
Definition: mh5display.c:2357
void STR_DataFree(unsigned char *data, unsigned int size)
Definition: glue_memory.c:668
#define DBC_PREF_NONE
Definition: glue_dsmcc.c:61
void MHEG5AutoPathComplete(E_FsStatus result)
Definition: mh5control.c:586
Native language, reminder and banner functions for South Africa profile.
void * STB_OSCreateMutex(void)
Create a mutex.
Event handling. Implementation of a combined queue for events and actions. This is the eventsystem wh...
int len
Definition: mh5gate.c:57
BOOLEAN MH5GlueSiqNetBootInfo(S_STRING *nbinfo)
Get current MHEG net boot info existance and nb info string.
Definition: glue_dsmcc.c:556
#define ISO_639_LANG_CODE_UND
Definition: mh5control.h:38
#define INVALID_ATAG
Definition: glue_dsmcc.c:65
E_DATA_TYPE data_type
Definition: glue_queue.h:199
BOOLEAN MHEG5engineIsCiAppRunning(void)
Definition: mh5control.c:1158
struct s_dbc_app S_DBC_APP
uint16_t U16BIT
Definition: techtype.h:84
struct s_service_dbc * next
Definition: glue_dsmcc.c:100
S_CONTENT content
Definition: glue_queue.h:202
U32BIT appId
Definition: glue_dsmcc.c:91
U32BIT carouselId
Definition: glue_dsmcc.c:90
#define DVB_MhegOsdLanguageCodes
Definition: glue_dsmcc.c:82
File interface functions to DSMCC component.
#define FALSE
Definition: techtype.h:68
void STB_OSMutexLock(void *mutex)
Lock a mutex (a.k.a. &#39;enter&#39;, &#39;wait&#39; or &#39;get&#39;).
U8BIT nb_version
Definition: glue_dsmcc.c:93
U16BIT MHEG5DefaultServiceId(void)
Definition: glue_main.c:1191
#define DSMCC_WORKING_4K_BUFFER_POOL
Definition: glue_dsmcc.c:76
U8BIT * data
Definition: fs_types.h:55
U8BIT BOOLEAN
Definition: techtype.h:99
U32BIT zlen
Definition: dtvstring.h:30
#define TRUE
Definition: techtype.h:69
void MHEG5engineDsmTerminate(void)
Force the engine to terminate any DSM-CC based MHEG application.
Definition: mh5control.c:831
U8BIT MhegOsdLanguageCodes(U32BIT *langcodes, U8BIT max)
Definition: glue_dsmcc.c:120
void RunAutoboot(S_CONTENT *pContent)
Definition: glue_dsmcc.c:837
S_DsmccEvent dsmEvent
Definition: glue_queue.h:215
References: [1] UK1 Profile - Digital Terrestrial Television - Requirements for interoperability (The...
Implement generic MHEG5-display functions - independent from the OSD These are generic functions used...
FS_HANDLE fs_handle
Definition: fs_types.h:57
union s_mhg_message::@13 data
#define FUNCTION_START(name)
Definition: glue_debug.h:142
void FG_NotifyVersionChanged(S_DsmccEvent *param)
Tell File Group of version changed for File Group(s) in Object Carousel&#39;s SRG User Info...
void FG_NotifyListLoaded(S_DsmccEvent *param)
Tell File Group that File Groups have loaded in Object Carousel&#39;s SRG User Info.
uint32_t U32BIT
Definition: techtype.h:86
E_MhegErr DVB_MhegGetOSDLanguage(U8BIT *language)
Return the language of the native UI (menu etc.) as a three character code as defined by ISO 639-2...
E_FsStatus
Definition: fs_types.h:34
E_MhegErr MH5GlueDsmccStart(S_DVB_LOCATOR *pDvbLoc, U32BIT carouselId, BOOLEAN clear)
Definition: glue_dsmcc.c:739
#define TRACE(t, x)
Definition: glue_debug.h:118
Header file - Function prototypes for operating system.