31 #include "dsm_client.h" 32 #include "dsm_control.h" 37 #ifdef MULTI_OSD_LANGS 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 58 #define MHEG_NETBOOT_DESC 0x01 59 #define MHEG_SERVICE_DESC 0x02 61 #define DBC_PREF_NONE 0x0000 62 #define DBC_PREF_MHEG5 0x0100 65 #define INVALID_ATAG 0xFFFF 66 #define LIFECYCLE_EVENT_ID 0xFFFF 67 #define INVALID_NB 0xFF 69 #define MAX_PATH_NAME_SIZE 65 71 #ifndef DSMCC_SECTION_CACHE_64K_BUFFERS 72 #define DSMCC_SECTION_CACHE_64K_BUFFERS 16 75 #ifndef DSMCC_WORKING_4K_BUFFER_POOL 76 #define DSMCC_WORKING_4K_BUFFER_POOL 180 78 #ifdef MULTI_OSD_LANGS 79 #define MAX_LANG_CODES 4 81 #define MAX_LANG_CODES 1 82 #define DVB_MhegOsdLanguageCodes MhegOsdLanguageCodes 92 U16BIT associationTag;
108 static H_DsmControl dsmccControl = NULL;
109 static const S_STRING null_str = { 0, NULL };
113 static H_DsmEvent lifecycle_ehdl = 0;
114 static U32BIT boot_carousel_id = INVALID_CAROUSEL_ID;
115 static void *dbc_mutex = 0;
119 #ifndef MULTI_OSD_LANGS 120 U8BIT MhegOsdLanguageCodes(U32BIT *langcodes, U8BIT max)
122 U8BIT lang[4] = { 0, 0, 0, 0 };
125 *langcodes = (lang[0]<<16)|(lang[1]<<8)|lang[2];
135 while (sdbc != NULL && sdbc->service_id != service_id)
142 static H_PmtRef ParsePmtStartup( U16BIT service_id )
145 DBGTRACE(TSERVICE,
"****> service_id=%d",service_id)
146 if (service_id == MHEG5GetVideoSid()
147 || service_id == MHEG5GetAudioSid()
148 || service_id == MHEG5DefaultServiceId())
150 MHEG5RefreshStreams(service_id);
153 sdbc = FindServiceDbc( service_id );
159 sdbc->service_id = service_id;
160 sdbc->dbc_apps = NULL;
161 sdbc->next = service_dbcs;
165 return (H_PmtRef)sdbc;
178 while (app != NULL && app->carouselId != carouselId)
186 static S_DBC_APP* CreateDbcApp( U32BIT carouselId, U32BIT appId )
192 app->carouselId = carouselId;
194 app->associationTag = INVALID_ATAG;
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;
215 pApp = &(dbc->dbc_apps);
218 if (app->carouselId == carouselId)
240 dbc->dbc_apps = NULL;
243 static void ClearServiceDbcs(
void )
262 static void ParseMhegDescriptors(
S_DBC_APP *app, U8BIT *dptr, U16BIT dlen )
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)
274 case MHEG_NETBOOT_DESC:
276 app->nb_version = dptr[0];
277 app->nb_action = dptr[1];
283 DBGTRACE(TSERVICE,
" nb_version=0x%x nb_action=0x%x nb_length=0x%x", app->nb_version, app->nb_action, nb_len )
286 case MHEG_SERVICE_DESC:
288 app->associationTag = dptr[0] << 8 | dptr[1];
289 DBGTRACE(TSERVICE,
" SERVICE-BOOT-INFO: assoc_tag=0x%x", app->associationTag)
293 DBGTRACE(TERROR,
"Unknown Mheg tag 0x%x", tag);
299 app->nb_info = MH5GlueStringCreate( nb_len, nb_ptr );
301 FUNCTION_FINISH(ParseMhegDescriptors)
304 static void LifecycleFunc(
void *userData, U8BIT *name, U32BIT dataLen, U8BIT *dataPtr )
306 DBGTRACE(TALWAYS,
" ***************************** Rebooting! ")
314 DSMCC_SiqCacheClearPmt( dsmccControl, MHEG5DefaultServiceId() );
325 if (lifecycle_ehdl != 0)
327 DBGTRACE(TSERVICE,
"clear Lifecycle")
328 DSMCC_ClientEventUnsubscribe(dsmccControl, lifecycle_ehdl);
333 static void StartLifecycle( U16BIT atag )
335 static U16BIT lastatag = INVALID_ATAG;
336 if (lastatag != atag)
338 DBGTRACE(TSERVICE,
"clear Lifecycle atag=0x%x", lastatag)
341 if (lifecycle_ehdl == 0)
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 ))
365 DBGTRACE(TERROR,
"No new application")
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)
373 StartLifecycle( newapp->associationTag );
375 if (oldapp == NULL ||
376 newapp->nb_version != oldapp->nb_version)
378 switch (newapp->nb_action)
388 DBGTRACE(TSERVICE,
"Send EE_NETWORK_BOOT_INFO")
397 static void ParsePmtFinished(H_PmtRef pmtref)
402 DBGTRACE(TSERVICE,
"<*** sid=%d boot_cid=%d",sdbc->service_id,boot_carousel_id)
403 oldapp = sdbc->dbc_apps;
404 while (oldapp != NULL)
407 nxtapp = oldapp->next;
408 if (boot_carousel_id == oldapp->carouselId &&
409 sdbc->service_id == MHEG5DefaultServiceId())
411 DBGTRACE(TALWAYS,
" ***************************** Rebooting! ")
413 boot_carousel_id = INVALID_CAROUSEL_ID;
415 MH5GlueStringFree( &oldapp->nb_info );
419 sdbc->dbc_apps = temp_apps;
436 static U32BIT ParseDataBcastId( H_PmtRef pmtref, U32BIT carouselId,
437 U8BIT *dbcPtr, U8BIT dbcLen )
439 U32BIT pref = DBC_PREF_NONE;
440 U16BIT dbcId, appType;
441 U8BIT *dptr_end, *dptr;
443 U16BIT boot_priority = 0;
447 FUNCTION_START(ParseDataBcastId)
450 dptr_end = dptr + dbcLen;
451 dbcId = dptr[0] << 8 | dptr[1];
457 assert( dbc != NULL );
458 oldapp = RemoveDbcApp(dbc, carouselId);
460 while (dptr < dptr_end)
462 appType = dptr[0] << 8 | dptr[1];
464 boot_priority = DBC_PREF_MHEG5 + *dptr;
471 if (pref < boot_priority)
473 pref = boot_priority;
477 assert( newapp == NULL );
478 newapp = CreateDbcApp(carouselId, (dbcId << 16) | appType);
481 DBGTRACE(TERROR,
"Memory failure")
485 DBGTRACE(TSERVICE,
"MHEG app type 0x%x (bp=%x)",appType,boot_priority)
486 ParseMhegDescriptors( newapp, dptr, app_len );
491 DBGTRACE(TERROR,
"Unsupported MHEG app type 0x%x", appType);
495 if (dbc->service_id == MHEG5DefaultServiceId())
498 if (DSMCC_CurrentCarouselId(dsmccControl) == carouselId)
500 DBGTRACE(TSERVICE,
"carouselId=%d",carouselId)
501 ProcessMhegDescriptorChange( oldapp, newapp );
506 MH5GlueStringFree( &oldapp->nb_info );
512 DBGTRACE(TERROR,
"Unsupported Data Broadcast ID 0x%x", dbcId);
514 FUNCTION_FINISH(ParseDataBcastId)
527 static U32BIT MH5GlueSiqCurrentApplicationId(
void)
532 id = DSMCC_CurrentCarouselId(dsmccControl);
534 sdbc = FindServiceDbc( MHEG5DefaultServiceId() );
535 DBGTRACE(TSERVICE,
"sid=%d,cid=%d", MHEG5DefaultServiceId(),
id)
536 app = FindDbcApp( sdbc,
id );
539 DBGTRACE(TERROR,
"No current app")
547 DBGTRACE(TSERVICE,
"appId=0x%x",
id)
562 carouselId = DSMCC_CurrentCarouselId(dsmccControl);
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)
569 DBGTRACE(TERROR,
"No app (%p) or no net boot desc", app)
574 DBGTRACE(TSERVICE,
"nb_info=%d %s", app->nb_info.zlen, app->nb_info.zptr) *
575 nbinfo = app->nb_info;
586 static void MH5GlueSiqNewBootCarousel( U32BIT carouselId )
590 DBGTRACE(TSERVICE,
"sid=%d,cid=%d", MHEG5DefaultServiceId(), carouselId)
592 app = FindDbcApp( FindServiceDbc( MHEG5DefaultServiceId() ), carouselId );
595 atag = app->associationTag;
596 DBGTRACE(TSERVICE,
"LC-atag=0x%x", atag)
603 if (atag != INVALID_ATAG)
605 StartLifecycle( atag );
609 static void CarouselLoadEvent( H_ObjCarousel carouselRef, E_OCLoadStatus status, U32BIT carouselId )
612 DBGTRACE(TMHBOOT|TDSMFG,
" ( 0x%x, %d, 0x%x )", carouselRef, status, carouselId )
617 TRACE(TMHBOOT, (
"OC_LOAD_BOOTED"));
618 if (boot_carousel_id == INVALID_CAROUSEL_ID)
620 boot_carousel_id = carouselId;
621 MH5GlueSiqNewBootCarousel( carouselId );
623 msg.proc_msg_func = (
F_MSG_PROCESS)MHEG5NotifyCarouselBooted;
624 msg.data_type = DT_VALUE;
625 msg.data.dsmEvent.hCarousel = carouselRef;
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));
633 msg.proc_msg_func = MHEG5StartReboot;
634 msg.data_type = DT_NONE;
638 case OC_LOAD_COMPLETED:
639 TRACE(TMHBOOT, (
"OC_LOAD_COMPLETED"));
640 msg.proc_msg_func = (
F_MSG_PROCESS)MHEG5NotifyCarouselLoaded;
641 msg.data_type = DT_VALUE;
642 msg.data.dsmEvent.hCarousel = carouselRef;
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;
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;
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;
672 case OC_LOAD_ABORTED_UNLOAD:
673 TRACE(TMHBOOT, (
"OC_LOAD_ABORTED_UNLOAD"));
674 if (boot_carousel_id == carouselId)
676 boot_carousel_id = INVALID_CAROUSEL_ID;
678 msg.proc_msg_func = (
F_MSG_PROCESS)MHEG5NotifyCarouselUnload;
679 msg.data_type = DT_VALUE;
680 msg.data.dsmEvent.hCarousel = carouselRef;
684 case OC_LOAD_IN_PROGRESS:
686 TRACE(TERROR, (
"Ignore status %d", status));
691 E_MhegErr MH5GlueDsmccOpen( U32BIT taskPriority )
694 S_DsmccConfig config;
698 config.taskPriority = taskPriority - 1;
700 config.sectionBuffPoolSize = DSMCC_WORKING_4K_BUFFER_POOL;
702 config.sectionBuffCacheSize = DSMCC_SECTION_CACHE_64K_BUFFERS;
707 config.parsePmtInit = ParsePmtStartup;
708 config.parseDataBroadcastId = ParseDataBcastId;
709 config.parsePmtDone = ParsePmtFinished;
711 config.carouselLoad = CarouselLoadEvent;
713 config.notifyAitInfo = NULL;
714 config.obtainSiDirect = FALSE;
717 if (dbc_mutex == NULL)
719 err = MHERR_SYSTEM_RESOURCE_MUTEX;
723 dsmccControl = DSMCC_Open( &config );
724 if (dsmccControl == NULL)
727 err = MHERR_DSMCC_INSTANCE_CREATE;
733 void MH5GlueDsmccClose(
void)
735 DSMCC_Close( dsmccControl );
739 E_MhegErr MH5GlueDsmccStart(
S_DVB_LOCATOR *pDvbLoc, U32BIT carouselId, BOOLEAN clear )
743 DBGTRACE(TSERVICE,
"tid=0x%x", pDvbLoc->transport_stream_id );
751 DSMCC_Stop( dsmccControl, RST_MODE_FORCE );
761 void MH5GlueDsmccStop( U8BIT action )
763 if (action == STOP_ACTION_MHEG_TUNE)
765 DSMCC_Stop( dsmccControl, RST_MODE_PENDING );
770 DSMCC_Stop( dsmccControl, RST_MODE_FORCE );
783 static void AutobootClear(
void *data )
785 STR_DataFree( data, MAX_PATH_NAME_SIZE );
788 static U8BIT* ParseServiceContext( U32BIT size, U8BIT *data, U32BIT languageCode,
791 U32BIT iso_639_language_code;
792 U8BIT langNum, number_languages;
793 U8BIT initial_object_length;
794 U8BIT *pathname = NULL;
796 TRACE(TMHBOOT, (
"lang code %x", languageCode))
798 number_languages = *data++;
800 for (langNum = 0; langNum != number_languages && size > 4; langNum++)
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]);
807 initial_object_length = (U16BIT)*data++;
809 if (size < initial_object_length)
813 if (iso_639_language_code == languageCode)
815 pathname = STR_DataAlloc(MAX_PATH_NAME_SIZE);
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))
831 data += initial_object_length;
832 size -= initial_object_length;
839 TRACE(TMHBOOT, (
"%p",pContent->data))
841 if (pContent->destroy)
843 pContent->destroy( pContent->fs_handle );
847 static void ServiceContextComplete( E_FsStatus status,
S_CONTENT *content )
850 if (status == FS_STATUS_OK)
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)
857 U32BIT langcodes[MAX_LANG_CODES+1];
858 U8BIT langcode_num, id;
860 langcodes[langcode_num] = ISO_639_LANG_CODE_UND;
862 for (
id = 0;
id != langcode_num;
id++)
864 if (ParseServiceContext(content->size, content->data, langcodes[
id], &msg.data.content) != NULL)
870 if (content->destroy)
872 content->destroy( content->fs_handle );
875 msg.data_type = DT_CONTENT;
876 if (
VQ_PutMsg( &msg, PRTY_NORMAL ) != MHERR_OK)
878 TRACE(TERROR, (
"VQ_PutMsg failed"));
879 if (msg.data.content.destroy)
881 msg.data.content.destroy( msg.data.content.fs_handle );
887 MHEG5AutoPathComplete( status );
904 appId = MH5GlueSiqCurrentApplicationId();
905 if ((appId >> 16) != 0x0106)
908 TRACE(TMHBOOT, (
"Not MHEG data_broadcast_id 0x%x", (appId >> 16)))
909 MHEG5AutoPathComplete( FS_STATUS_NONE );
914 dsmcontent.size = appId;
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)
922 pathcontent.size = 0;
923 pathcontent.data = NULL;
924 pathcontent.destroy = NULL;
925 if (dsmcontent.data != NULL && dsmcontent.size > 4)
927 U32BIT langcodes[MAX_LANG_CODES+1];
928 U8BIT langcode_num, id;
930 langcodes[langcode_num] = ISO_639_LANG_CODE_UND;
932 for (
id = 0;
id != langcode_num;
id++)
934 if (ParseServiceContext(dsmcontent.size, dsmcontent.data, langcodes[
id], &pathcontent) != NULL)
940 if (dsmcontent.destroy)
943 dsmcontent.destroy( dsmcontent.fs_handle );
945 RunAutoboot( &pathcontent );
950 TRACE(TERROR, (
"retval is %d", retval));
951 MHEG5AutoPathComplete( retval );
956 void MH5GlueDsmccReboot(
void )
958 DSMCC_Reboot( dsmccControl );
Implement MHEG5 engine control functions (i.e. start/stop etc)
void StopLifecycle(void)
Clear MHEG Lifecycle Event listening.
E_MhegErr VQ_PutMsg(S_MhegMessage *pMsg, E_PRIORITY priority)
Post event or section message on queue. Copies data into queue.
void MHEG5engineStart(U8BIT *app_name, BOOLEAN isCi, BOOLEAN special)
Start the engine with the initial application.
File acceleration for Australia and Souh Africa.
Interface functions to DSM-CC instance for MHEG5.
void MH5GlueDsmccMHEGInitialBoot(void)
Causes the autoboot application to be launched. The component must be in the correct state (DSM-CC bo...
void FG_NotifyListChanged(S_DsmccEvent *param)
Tell File Group that File Groups have changed in Object Carousel's SRG User Info. ...
void STB_MemFree(void *ptr)
Releases previously allocated memory.
void STB_OSDeleteMutex(void *mutex)
Delete a mutex.
void MHEG5_SendEngineEvent(E_ENGINE_EVENT engineEvent)
Send MHEG app an engine event from an external task.
void(* F_MSG_PROCESS)(void *data)
Function to Process voyager message.
DMXREF DVB_MhegGetDemuxPath(void)
Retrieve demux resource reference.
E_MhegErr MHEG5_Reboot(void)
Reboots MHGE5 Engine This function has the same effect as calling these two: MHEG5_Stop( STOP_ACTION_...
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. 'leave', 'signal' or 'release')
void * MHEG5_DsmccInstance(void)
Get the DSMCC instance handle.
void * STB_MemAlloc(U32BIT memSize)
Allocates the specified number of bytes.
Native language, reminder and banner functions for South Africa profile.
U8BIT DVB_MhegOsdLanguageCodes(U32BIT *langcodes, U8BIT max)
Return the language of the native UI (menu etc.) as a list of language codes in 32 bit integer form...
void * STB_OSCreateMutex(void)
Create a mutex.
Event handling. Implementation of a combined queue for events and actions. This is the eventsystem wh...
BOOLEAN MH5GlueSiqNetBootInfo(S_STRING *nbinfo)
Get current MHEG net boot info existance and nb info string.
BOOLEAN MHEG5engineIsCiAppRunning(void)
File interface functions to DSMCC component.
void STB_OSMutexLock(void *mutex)
Lock a mutex (a.k.a. 'enter', 'wait' or 'get').
void MHEG5engineDsmTerminate(void)
Force the engine to terminate any DSM-CC based MHEG application.
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...
void FG_NotifyVersionChanged(S_DsmccEvent *param)
Tell File Group of version changed for File Group(s) in Object Carousel's SRG User Info...
void FG_NotifyListLoaded(S_DsmccEvent *param)
Tell File Group that File Groups have loaded in Object Carousel's SRG User Info.
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...
Header file - Function prototypes for operating system.