40 #define DBC_ID_SSU 0x000A
41 #define DBC_ID_MHEG5 0x0106
42 #define DBC_ID_OAD 0x0111
43 #define DBC_ID_HBBTV 0x0123
44 #define DBC_ID_MHP0 0x00F0
45 #define DBC_ID_MHP1 0x00F1
47 #define DVB_OUI 0x00015A
80 APP_TYP_MHEG5 = 0x0008,
81 APP_TYP_HBBTV = 0x0010,
86 CAROUSEL_ID_DESCRIPTOR = 0x13,
87 DEFERRED_ASSOC_DESCRIPTOR = 0x15,
88 STREAM_ID_DESCRIPTOR = 0x52,
89 DATA_BROADCAST_ID_DESCRIPTOR = 0x66,
90 APP_SIGNALLING_DESCRIPTOR = 0x6f
93 typedef struct s_SsuInfo *P_SsuInfo;
95 typedef struct s_SsuInfo
105 typedef struct s_PmtStream
116 typedef struct s_Deferred
125 typedef struct s_SiqPmtTable
129 S_Deferred *deferreds;
130 S_PmtStream *streams;
151 U16BIT pid, U8BIT *dptr, U8BIT *dend )
154 FUNCTION_START(ParseForAitInfo)
159 DBGLOG(DS_PMT,
" dtag=0x%x dlen=%d, data=0x%x 0x%x 0x%x 0x%x", dtag, dlen, dptr[0], dptr[1], dptr[2], dptr[3])
160 if (dtag == APP_SIGNALLING_DESCRIPTOR)
164 siq->setup.notifyAitInfo( sid, pid, UNKNOWN_AIT_TYPE, UNKNOWN_AIT_VERS );
170 siq->setup.notifyAitInfo( sid, pid, ((dptr[0] & 0x7f) << 8) + dptr[1], dptr[2] & 0x1f );
178 FUNCTION_FINISH(ParseForAitInfo)
181 void ParseSystemSoftwareUpdateInfo(
S_SiqInstance *siq, S_PmtStream *pStream, U8BIT *dptr, U8BIT dlen, U8BIT **pxtr_ptr )
186 FUNCTION_START(ParseSystemSoftwareUpdateInfo)
188 pSsuInfo = (P_SsuInfo)*pxtr_ptr;
190 oui = (oui << 8) | *dptr++;
191 oui = (oui << 8) | *dptr++;
193 pSsuInfo->type = (E_SsuUpdType)(*dptr & 0x0f);
195 pSsuInfo->hasVers = (*dptr & 0x20)? TRUE : FALSE;
196 pSsuInfo->version = *dptr & 0x1F;
199 pSsuInfo->selectorLen = slen;
203 memcpy(pSsuInfo+1,dptr,slen);
205 pSsuInfo->next = pStream->ssuInfo;
206 pStream->ssuInfo = pSsuInfo;
207 slen +=
sizeof(S_SsuInfo) + 3;
210 FUNCTION_FINISH(ParseSystemSoftwareUpdateInfo)
218 static U16BIT ParseForDataBroadcastIds(
S_SiqInstance *siq, H_PmtRef pmtref,
219 S_PmtStream *pStream, U8BIT *dptr, U8BIT *dend, U8BIT **pxtr_ptr )
221 U16BIT prefer, preferred;
224 FUNCTION_START(ParseForDataBroadcastIds)
230 if (dtag == DATA_BROADCAST_ID_DESCRIPTOR)
232 dbcId = dptr[0] << 8 | dptr[1];
233 if (dbcId == DBC_ID_SSU)
235 pStream->dbcId = dbcId;
236 ParseSystemSoftwareUpdateInfo( siq, pStream, dptr+3, *(dptr+2), pxtr_ptr );
238 else if (pStream->carouselId != INVALID_CAROUSEL_ID &&
239 siq->setup.parseDataBroadcastId != NULL && dbcId != 0)
241 DBGLOG(DS_PMT,
"numtags=%d dbcId=%x",pStream->numtags,dbcId)
242 prefer = (U16BIT)siq->setup.parseDataBroadcastId( pmtref, pStream->carouselId, dptr, dlen );
243 if (preferred < prefer)
246 pStream->dbcId = dbcId;
252 FUNCTION_FINISH(ParseForDataBroadcastIds)
261 static U16BIT GetDataBroadcastExtraSize( U8BIT *dptr, U8BIT *dend )
265 U8BIT dlen, dtag, slen;
270 if (dtag == DATA_BROADCAST_ID_DESCRIPTOR)
272 dbcId = dptr[0] << 8 | dptr[1];
276 slen =
sizeof(S_SsuInfo) + dptr[8] + 3;
294 static U16BIT CountStreamIdDesc( U8BIT *dptr, U8BIT *dend )
302 if (dtag == STREAM_ID_DESCRIPTOR)
316 static U16BIT GetComponentTags( U8BIT *dptr, U8BIT *dend, U8BIT *ctags )
324 if (dtag == STREAM_ID_DESCRIPTOR)
326 ctags[count] = *dptr;
339 static U32BIT GetCarouselInfo( U8BIT *dptr, U8BIT *dend )
341 U32BIT carouselId = INVALID_CAROUSEL_ID;
347 if (dtag == CAROUSEL_ID_DESCRIPTOR)
377 static U16BIT DeferredSize( U8BIT *dptr, U8BIT *dend, U8BIT *pNum )
380 U8BIT dlen, dtag, num = 0;
385 if (dtag == DEFERRED_ASSOC_DESCRIPTOR)
388 size +=
sizeof(S_Deferred) + *dptr;
402 static U16BIT ParseDeferreds( U8BIT *dptr, U8BIT *dend, S_Deferred *pDeferred, U16BIT *atags )
411 if (dtag == DEFERRED_ASSOC_DESCRIPTOR && dlen > 8)
413 pDeferred->numAssocTags = *dptr / 2;
414 pDeferred->assocTags = atags;
416 for (i = pDeferred->numAssocTags; i--; atags++)
418 *atags = (dptr[0] << 8) | dptr[1];
423 pDeferred->transportId = (dptr[0] << 8) | dptr[1];
425 pDeferred->serviceId = (dptr[0] << 8) | dptr[1];
427 pDeferred->origNetId = (dptr[0] << 8) | dptr[1];
446 S_SiqPmtTable *pmt_table;
447 S_PmtStream *stream_ptr;
449 U8BIT *dptr, *section_end, *dloop_end, *ctags, *xtr_ptr;
450 U8BIT num_streams, num_deferred;
452 U16BIT section_len, dloop_len;
453 U16BIT pid, size, sid, cnt, xtr_size;
455 FUNCTION_START(PMT_CreateTable)
458 section_len = (dptr[1] << 8 | dptr[2]) & 0xfff;
459 dloop_len = (dptr[10] << 8 | dptr[11]) & 0xfff;
461 sid = dptr[3] << 8 | dptr[4];
463 DBGLOG(DS_PMT,
"sid=0x%x tid=0x%x sec_len=%d first desc len=%d", sid,
464 *data, section_len, dloop_len )
466 section_end = data + section_len - 4;
469 dloop_end = dptr + dloop_len;
471 size =
sizeof(S_SiqPmtTable) + DeferredSize( dptr, dloop_end, &num_deferred );
478 while (dptr < section_end)
482 pid = ((dptr[3] & 0x0f) << 8) | dptr[4];
484 dloop_end = dptr + pid;
487 case ST_MHEG:
case ST_DATA_A:
488 ERRLOG(
" Unhandled stream type=0x%x", stream_type)
496 size +=
sizeof(S_PmtStream);
504 cnt = CountStreamIdDesc(dptr, dloop_end);
505 dbsz = GetDataBroadcastExtraSize(dptr, dloop_end);
508 size +=
sizeof(S_PmtStream) + cnt;
519 pmt_table = (S_SiqPmtTable *)siq->setup.memAlloc( size );
520 if (pmt_table == NULL)
522 ERRLOG(
"Memory failure")
526 memset( pmt_table, 0, size );
527 pmt_table->deferreds = (S_Deferred *)(pmt_table + 1);
528 pmt_table->num_deferred = num_deferred;
529 stream_ptr = (S_PmtStream *)(pmt_table->deferreds + num_deferred);
530 pmt_table->streams = stream_ptr;
531 pmt_table->num_streams = num_streams;
532 xtr_ptr= (U8BIT*)(stream_ptr + num_streams);
533 ctags = xtr_ptr + xtr_size;
535 if (siq->setup.parsePmtInit)
538 pmtref = siq->setup.parsePmtInit( sid );
550 dloop_end = dptr + dloop_len;
552 ctags += ParseDeferreds( dptr, dloop_end, pmt_table->deferreds, (U16BIT *)ctags );
558 while (dptr < section_end)
561 pid = ((dptr[1] & 0x1f) << 8) | dptr[2];
562 dloop_len = ((dptr[3] & 0x0f) << 8) | dptr[4];
564 dloop_end = dptr + dloop_len;
568 DBGLOG(DS_PMT,
"; strm typ=0x%x", stream_type)
572 DBGLOG(DS_PMT,
"[%d] stream typ=PRIVATE pid=0x%x func=%p", num_streams, stream_type, pid, siq->setup.notifyAitInfo)
573 if (siq->setup.notifyAitInfo)
575 DBGLOG(DS_PMT,
" bytes=%d, data=0x%x 0x%x 0x%x 0x%x", dloop_end - dptr, dptr[0], dptr[1], dptr[2], dptr[3])
576 ParseForAitInfo(siq, sid, pid, dptr, dloop_end);
582 stream_ptr->dbcId = DBC_ID_SSU;
583 stream_ptr->carouselId = INVALID_CAROUSEL_ID;
584 stream_ptr->pid = pid;
590 DBGLOG(DS_PMT,
"[%d] stream typ=0x%x pid=0x%x", num_streams, stream_type, pid)
591 cnt = GetComponentTags(dptr, dloop_end, ctags);
594 stream_ptr->numtags = cnt;
595 stream_ptr->cTags = ctags;
596 stream_ptr->carouselId = GetCarouselInfo( dptr, dloop_end );
597 DBGLOG(DS_PMT,
"cnt=%u, ctags[0]=%u crslId=0x%x", cnt, ctags[0], stream_ptr->carouselId)
601 DBGLOG(DS_PMT,
"no ctags")
603 stream_ptr->bootPref = ParseForDataBroadcastIds( siq, pmtref, stream_ptr, dptr, dloop_end, &xtr_ptr );
604 if (cnt || stream_ptr->dbcId == DBC_ID_SSU)
607 stream_ptr->pid = pid;
608 DBGLOG(DS_PMT,
"crsl-id=0x%x bootPref=0x%x", stream_ptr->carouselId, stream_ptr->bootPref)
613 DBGLOG(DS_PMT,
"dbcId=0x%x",stream_ptr->dbcId)
618 if (siq->setup.parsePmtDone)
621 siq->setup.parsePmtDone( pmtref );
623 DBGLOG(DS_PMT,
"table=%p", pmt_table )
625 FUNCTION_FINISH(PMT_CreateTable)
639 DBGLOG(DS_PMT,
"table=%p", table )
640 siq->setup.memFree( table );
652 static void PmtDsmccPid(
S_SiqInstance *siq, S_SiqPmtTable *pmt,
657 FUNCTION_START(PmtDsmccPid);
659 for (cnt = pmt->num_streams; cnt--; sptr++)
661 for (i = 0; i != sptr->numtags; i++)
663 if (sptr->cTags[i] == (assocTag & 0xFF))
665 pResult->kind = SIQUERY_PID;
666 pResult->data.pid = sptr->pid;
671 FUNCTION_FINISH(PmtDsmccPid);
682 static void PmtCarouselInfo(
S_SiqInstance *siq, S_SiqPmtTable *pmt,
687 FUNCTION_START(PmtCarouselInfo);
689 for (cnt = pmt->num_streams; cnt--; sptr++)
691 if (sptr->dbcId != DBC_ID_SSU)
693 for (i = 0; i != sptr->numtags; i++)
695 if (sptr->cTags[i] == cTag)
697 pResult->kind = SIQUERY_CAROUSEL_INFO;
698 pResult->data.carouselInfo.pid = sptr->pid;
699 pResult->data.carouselInfo.associationTag = cTag;
700 pResult->data.carouselInfo.carouselId = sptr->carouselId;
701 pResult->data.carouselInfo.next = NULL;
707 FUNCTION_FINISH(PmtCarouselInfo);
718 static void PmtCarousel(
S_SiqInstance *siq, S_SiqPmtTable *pmt,
723 FUNCTION_START(PmtCarousel)
725 for (i = 0; i != pmt->num_streams; i++, sptr++)
727 if (sptr->carouselId == carouselId)
729 pResult->kind = SIQUERY_CAROUSEL;
730 pResult->data.carouselInfo.pid = sptr->pid;
731 pResult->data.carouselInfo.associationTag = sptr->cTags[0];
732 pResult->data.carouselInfo.carouselId = carouselId;
733 pResult->data.carouselInfo.next = NULL;
734 DBGLOG(DS_QUERY,
" strm[%d] ctag=0x%x crslid=0x%x", i, sptr->cTags[0], carouselId)
738 FUNCTION_FINISH(PmtCarousel);
748 static
void PmtFindCarousel(
S_SiqInstance *siq, H_SiqPmtTable pmt,
753 FUNCTION_START(PmtFindCarousel)
755 for (i = 0; i != pmt->num_streams; i++, sptr++)
757 if (sptr->carouselId != INVALID_CAROUSEL_ID)
759 pResult->kind = SIQUERY_FIND_CAROUSEL;
760 pResult->data.carouselInfo.pid = sptr->pid;
761 pResult->data.carouselInfo.associationTag = sptr->cTags[0];
762 pResult->data.carouselInfo.carouselId = sptr->carouselId;
763 pResult->data.carouselInfo.next = NULL;
764 DBGLOG(DS_QUERY,
" strm[%d] ctag=0x%x crslid=0x%x", i, sptr->cTags[0], sptr->carouselId)
768 FUNCTION_FINISH(PmtFindCarousel);
779 static
void PmtBootCarousel(
S_SiqInstance *siq, S_SiqPmtTable *pmt,
783 U16BIT i, bootPref = 0;
784 FUNCTION_START(PmtBootCarousel)
786 for (i = 0; i != pmt->num_streams; i++, sptr++)
788 if (sptr->dbcId != DBC_ID_SSU && bootPref < sptr->bootPref)
790 bootPref = sptr->bootPref;
791 ASSERT( sptr->carouselId != INVALID_CAROUSEL_ID );
792 pResult->kind = SIQUERY_BOOT_CAROUSEL;
793 pResult->data.carouselInfo.pid = sptr->pid;
794 pResult->data.carouselInfo.associationTag = sptr->cTags[0];
795 pResult->data.carouselInfo.carouselId = sptr->carouselId;
796 pResult->data.carouselInfo.next = NULL;
797 DBGLOG(DS_QUERY,
" strm[%d] ctag=0x%x crslid=0x%x", i, sptr->cTags[0], sptr->carouselId)
800 FUNCTION_FINISH(PmtBootCarousel)
811 static void PmtSsuCarousel(
S_SiqInstance *siq, S_SiqPmtTable *pmt,
818 FUNCTION_START(PmtSsuCarousel)
821 for (i = 0; i != pmt->num_streams; i++, sptr++)
823 ssuInfo = sptr->ssuInfo;
824 while (ssuInfo != NULL)
828 if ((ssuInfo->oui == oui || ssuInfo->oui == DVB_OUI) &&
829 (!ssuInfo->selectorLen || siq->setup.parseSsuSelectorBytes((U8BIT*)(ssuInfo+1),ssuInfo->selectorLen)))
831 if (pCrslInfo == NULL)
833 pResult->kind = SIQUERY_SSU_CAROUSEL;
834 pCrslInfo = &pResult->data.carouselInfo;
839 if (pCrslInfo->next == NULL)
841 ERRLOG(
"mem fail for extra carousel info")
844 pCrslInfo = pCrslInfo->next;
846 pCrslInfo->pid = sptr->pid;
847 pCrslInfo->carouselId = ssuInfo->oui;
848 pCrslInfo->next = NULL;
849 if (sptr->numtags == 0)
851 pCrslInfo->associationTag = INVALID_ASSOCIATION_TAG;
855 pCrslInfo->associationTag = sptr->cTags[0];
857 DBGLOG(DS_QUERY,
" strm[%d] ctag=0x%x crslid=0x%x", i, pCrslInfo->associationTag, oui)
859 ssuInfo = ssuInfo->next;
862 if (pResult->kind == SIRESULT_FAILURE && pmt->num_streams == 1)
865 if (sptr->dbcId == DBC_ID_SSU && sptr->carouselId == INVALID_CAROUSEL_ID && sptr->ssuInfo == NULL)
867 pResult->kind = SIQUERY_SSU_CAROUSEL;
868 pResult->data.carouselInfo.pid = sptr->pid;
869 pResult->data.carouselInfo.carouselId = oui;
870 pResult->data.carouselInfo.associationTag = INVALID_ASSOCIATION_TAG;
871 pResult->data.carouselInfo.next = NULL;
874 FUNCTION_FINISH(PmtSsuCarousel);
885 static void PmtDeferredService(
S_SiqInstance *siq, S_SiqPmtTable *pmt, U16BIT assocTag,
892 FUNCTION_START(PmtDeferredService)
893 num_deferred = pmt->num_deferred;
894 for (ds = pmt->deferreds; num_deferred--; ds++)
896 atags = ds->assocTags;
897 for (ndx = ds->numAssocTags; ndx--; atags++)
899 if (*atags == assocTag)
901 pResult->kind = SIQUERY_DEFERRED_SERVICE;
902 pResult->data.deferredService.transport_stream_id = ds->transportId;
903 pResult->data.deferredService.service_id = ds->serviceId;
904 pResult->data.deferredService.original_network_id = ds->origNetId;
910 FUNCTION_FINISH(PmtDeferredService)
924 pResult->kind = SIRESULT_FAILURE;
925 switch (pQuery->kind)
928 DBGLOG(DS_QUERY,
"PID serviceId=0x%x assocTag=0x%x", pQuery->serviceId, pQuery->associationTag)
929 PmtDsmccPid(siq, hpmt, pQuery->associationTag, pResult);
932 case SIQUERY_BOOT_CAROUSEL:
933 DBGLOG(DS_QUERY,
"Boot Carousel serviceId=0x%x", pQuery->serviceId)
934 PmtBootCarousel(siq, hpmt, pResult);
937 case SIQUERY_FIND_CAROUSEL:
938 DBGLOG(DS_QUERY,
"Find Carousel serviceId=0x%x", pQuery->serviceId)
939 PmtFindCarousel(siq, hpmt, pResult);
942 case SIQUERY_CAROUSEL_INFO:
943 DBGLOG(DS_QUERY,
"Carousel id=0x%x serviceId=0x%x", (
int)pQuery->dataId, pQuery->serviceId)
944 PmtCarouselInfo(siq, hpmt, (U8BIT)pQuery->dataId, pResult);
947 case SIQUERY_CAROUSEL:
948 DBGLOG(DS_QUERY,
"Carousel id=0x%x serviceId=0x%x", (
int)pQuery->dataId, pQuery->serviceId)
949 PmtCarousel(siq, hpmt, pQuery->dataId, pResult);
952 case SIQUERY_DEFERRED_SERVICE:
953 DBGLOG(DS_QUERY,
"Deferred serviceId=0x%x assocTag=0x%x", pQuery->serviceId, pQuery->associationTag)
954 PmtDeferredService(siq, hpmt, pQuery->associationTag, pResult);
957 case SIQUERY_SSU_CAROUSEL:
958 DBGLOG(DS_QUERY,
"Carousel id=0x%x serviceId=0x%x", (
int)pQuery->dataId, pQuery->serviceId)
959 PmtSsuCarousel(siq, hpmt, pQuery->dataId, pResult);
962 case SIQUERY_SSU_PID:
964 pResult->kind = SIQUERY_SSU_PID;
965 pResult->data.carouselInfo.pid = pQuery->serviceId;
966 pResult->data.carouselInfo.carouselId = INVALID_CAROUSEL_ID;
967 pResult->data.carouselInfo.associationTag = INVALID_ASSOCIATION_TAG;
971 case SIQUERY_PIDLIST:
972 ERRLOG(
"NOT supported %d", pQuery->kind);
988 H_SiqPmtTable pNewTable, U16BIT serviceId )
990 S_PmtStream *pOldStream, *pNewStream;
995 ASSERT(pOldTable != NULL)
996 ASSERT(pNewTable != NULL)
998 pOldStream = pOldTable->streams;
999 for (i = pOldTable->num_streams; i--; pOldStream++)
1001 carouselId = pOldStream->carouselId;
1002 pNewStream = pNewTable->streams;
1003 for (j = pNewTable->num_streams; j--; pNewStream++)
1005 if (carouselId == pNewStream->carouselId)
1008 carouselId = INVALID_CAROUSEL_ID;
1012 if (carouselId != INVALID_CAROUSEL_ID)
H_SiqPmtTable SIQ_PmtCreateTable(S_SiqInstance *siq, U8BIT *data)
Create PMT structure for monitoring (life-cycle, NB_Info)
void SIQ_PmtDestroyTable(S_SiqInstance *siq, H_SiqPmtTable table)
Destroy PMT structure created by PMT_CreateTable.
Main API to DSM-CC core layer (provided functions and required callbacks).
Service Information Query: debug definitions.
void SIQ_PmtCheckTableChange(S_SiqInstance *siq, H_SiqPmtTable pOldTable, H_SiqPmtTable pNewTable, U16BIT serviceId)
For each carousel Id in old table, search through new table to see if it still exists. If not, tell DSM-CC. Then tell DSM-CC that PMT has been updated.
Service Information Query: PMT parsing functions.
void SIQ_PmtProcessQuery(S_SiqInstance *siq, P_SIQueryRequest pQuery, H_SiqPmtTable hpmt, P_SIQueryResult pResult)
Retrieve Information required by Query request from SIQ's PMT table.
Service Information Query: main definitions.
E_DscError CDSM_SysProcessSIChangeEvent(H_DsmCoreInst instance, E_SIChangeEvent evnt, U16BIT service_id, U32BIT carousel_id)
Notify that the SI for the indicated service has changed Changes should be notified in the following ...