54 #define DBG_HC(x, ...) STB_SPDebugWrite( "%s:%d " x, __FUNCTION__, __LINE__, ##__VA_ARGS__); 56 #define DBG_HC(x, ...) 59 #define DBG_ERR(x, ...) STB_SPDebugWrite( "ERROR %s:%d" x, __FUNCTION__, __LINE__, ##__VA_ARGS__); 61 #define DTAG_DEL_SYS_DVBT 0x5a 62 #define DTAG_DEL_SYS_DVBT2 0x04 63 #define DTAG_DEL_SYS_DVBC 0x44 64 #define DTAG_DEL_SYS_DVBC2 0x0d 65 #define DTAG_DEL_SYS_DVBS 0x43 66 #define DTAG_DEL_SYS_DVBS2 0x79 67 #define DTAG_EXT_DESC 0x7f 85 static void *cihc_mutex;
91 static void* FindService(U16BIT net_id, U16BIT onet_id, U16BIT ts_id, U16BIT sid);
92 static void* FindTransport(U16BIT net_id, U16BIT onet_id, U16BIT ts_id);
126 if (FindHcState(module) != NULL)
128 DBG_ERR(
"(%u) HC module already exists", module)
133 if (hc_state == NULL)
135 DBG_ERR(
"(%u) Memory alloc failed", module)
139 hc_state->module = module;
140 hc_state->tune_started = FALSE;
141 hc_state->ask_release = FALSE;
142 hc_state->next = cihc_list;
143 cihc_list = hc_state;
148 owner_info.owner = RES_OWNER_CIPLUS;
149 owner_info.data = &module;
150 owner_info.data_size =
sizeof(module);
155 DBG_HC(
"(%u): Acquired ownership of path %u", module, path)
160 DBG_HC(
"(%u): Couldn't acquire ownership of path %u", module, path)
167 DBG_HC(
"(%u): No live path", module)
191 phc_state= &cihc_list;
192 hc_state = cihc_list;
193 while (hc_state != NULL)
195 if (hc_state->module == module)
203 DBG_HC(
"(%u): Releasing ownership of path %u (slot_id=%u)", module, path,
STB_DPGetPathCISlot(path))
205 if (hc_state->ask_release)
210 reply_data.module = module;
211 reply_data.reply = 0;
212 reply_data.path = path;
213 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_CI, EV_TYPE_CI_RELEASE_REPLY, &reply_data,
sizeof(reply_data));
218 *phc_state = hc_state->next;
222 phc_state = &(hc_state->next);
223 hc_state = hc_state->next;
243 DBG_HC(
"(%u)", module)
245 hc_state = FindHcState(module);
246 if (hc_state != NULL)
248 if (!hc_state->ask_release)
250 hc_state->ask_release = TRUE;
251 retval = STB_CIAskRelease(module);
255 DBG_HC(
"(%u): already asked to release HC session", module)
286 DBG_HC(
"(%u, reply=%u)", module, release_reply)
288 hc_state = FindHcState(module);
289 if (hc_state != NULL)
291 if (!hc_state->ask_release)
293 DBG_HC(
"(%u): Host hasn't asked for release", module)
300 reply_data.path = path;
301 reply_data.module = module;
302 reply_data.reply = release_reply;
304 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_CI, EV_TYPE_CI_RELEASE_REPLY, &reply_data,
sizeof(reply_data));
307 hc_state->ask_release = FALSE;
321 void ACI_HcTune(U32BIT module, U16BIT nid, U16BIT onid, U16BIT tsid, U16BIT sid)
328 DBG_HC(
"(%u, nid=%u, onid=%u, tid=%u, sid=%u)", module, nid, onid, tsid, sid)
330 hc_state = FindHcState(module);
331 if (hc_state == NULL)
333 DBG_ERR(
"(%u): host control module not recognised",module)
334 STB_CITuneReply(module, STB_CI_TUNE_BAD_PARAMETER);
338 if (hc_state->tune_started)
341 DBG_HC(
"(%u): Tuner is already tuning", module)
342 STB_CITuneReply(module, STB_CI_TUNE_TUNER_BUSY);
348 target = FindTransport(nid, onid, tsid);
351 DBG_HC(
"(%u): Failed to find transport", module)
352 STB_CITuneReply(module, STB_CI_TUNE_SERVICE_NOT_FOUND);
356 hc_state->tune_started = TRUE;
362 target = FindService(nid, onid, tsid, sid);
365 DBG_HC(
"(%u): Failed to find service", module)
366 STB_CITuneReply(module, STB_CI_TUNE_SERVICE_NOT_FOUND);
370 hc_state->tune_started = TRUE;
397 U16BIT desc_loop_len, U8BIT *desc_loop, U8BIT *pmt, E_CIP_TUNE_FLAGS flags)
408 DBG_HC(
"(%u, service_id=%u, desc_loop_len=%u, pmt=%p)", module, service_id, desc_loop_len, pmt)
410 hc_state = FindHcState(module);
411 if (hc_state != NULL)
413 if (!hc_state->tune_started)
415 if ((desc_loop_len > 0) && (desc_loop != NULL))
422 if ((service_id == 0) || (service_id != ((pmt[3] << 8) + pmt[4])) ||
426 STB_CITuneReply(module, STB_CI_TUNE_BAD_PARAMETER);
433 memset(&tune_del_sys, 0,
sizeof(tune_del_sys));
434 while ((desc_loop_len > 0) && tune_valid)
439 dlen = desc_loop[1] + 2;
443 case DTAG_DEL_SYS_DVBT:
444 case DTAG_DEL_SYS_DVBS:
445 case DTAG_DEL_SYS_DVBC:
447 DBG_HC(
"%s delivery descriptor", (dtag == DTAG_DEL_SYS_DVBT) ?
"DTAG_DEL_SYS_DVBT" :
448 (dtag == DTAG_DEL_SYS_DVBS) ?
"DTAG_DEL_SYS_DVBS" :
449 (dtag == DTAG_DEL_SYS_DVBC) ?
"DTAG_DEL_SYS_DVBC" :
"Unknown")
450 if (tune_del_sys.desc == NULL)
455 DBG_HC(
"could not parse delivery descriptor")
456 STB_CITuneReply(module, STB_CI_TUNE_BAD_PARAMETER);
463 DBG_HC(
"(%u): Skipping additional delivery desc, dtag=0x%02x", module, dtag)
469 DBG_HC(
"(%u): Service desc", module)
471 &tune_del_sys.service_name))
474 if (provider != NULL)
482 DBG_HC(
"(%u): Short event desc", module)
484 if (tune_del_sys.event_desc != NULL)
486 tune_del_sys.event_desc->desc_data = (U8BIT *)(tune_del_sys.event_desc + 1);
487 memcpy(tune_del_sys.event_desc->desc_data, desc_loop, dlen);
488 tune_del_sys.event_desc->next = NULL;
494 DBG_HC(
"(%u): Component desc", module)
498 DBG_HC(
"(%u): Parental rating desc", module)
502 DBG_HC(
"(%u): Content desc", module)
507 DBG_HC(
"Skipping unhandled descriptor 0x%02x, len %u bytes", dtag, dlen);
512 desc_loop_len -= dlen;
517 hc_state->tune_started = TRUE;
519 tune_del_sys.service_id = service_id;
520 tune_del_sys.pmt = pmt;
528 DBG_ERR(
"(%u): descriptor loop invalid (%p,%u)",module, desc_loop, desc_loop_len)
529 STB_CITuneReply(module, STB_CI_TUNE_BAD_PARAMETER);
534 DBG_HC(
"(%u): Tuner is already tuning", module)
535 STB_CITuneReply(module, STB_CI_TUNE_TUNER_BUSY);
540 DBG_ERR(
"(%u): host control module not recognised",module)
541 STB_CITuneReply(module, STB_CI_TUNE_BAD_PARAMETER);
561 hc_state = FindHcState(module);
562 if (hc_state == NULL)
564 DBG_ERR(
"(%u): host control module not recognised",module)
565 STB_CITuneReply(module, STB_CI_TUNE_BAD_PARAMETER);
569 if (hc_state->tune_started)
572 DBG_HC(
"(%u): Tuner is already tuning", module)
573 STB_CITuneReply(module, STB_CI_TUNE_TUNER_BUSY);
577 hc_state->tune_started = TRUE;
598 DBG_HC(
"(mod=%u, status=%u)", module, status)
600 hc_state = FindHcState(module);
601 if (hc_state != NULL)
604 if (hc_state->tune_started)
606 hc_state->tune_started = FALSE;
607 DBG_HC(
"(%u, status=%s)", module,
608 (status == STB_CI_TUNE_OK) ?
"CIP_TUNER_LOCKED" :
609 (status == STB_CI_TUNE_TUNER_NOT_LOCKING) ?
"CIP_TUNER_NOTLOCKED" :
610 (status == STB_CI_TUNE_TUNER_BUSY) ?
"CIP_TUNER_BUSY" :
611 (status == STB_CI_TUNE_UNSUPPORTED_SYSTEM) ?
"CIP_TUNER_UNSUPPORTED_SYSTEM" :
612 (status == STB_CI_TUNE_BAD_PARAMETER) ?
"CIP_TUNER_BAD_PARAM" :
613 (status == STB_CI_TUNE_SERVICE_NOT_FOUND) ?
"CIP_TUNER_SERVICE_NOT_FOUND" :
614 (status == STB_CI_TUNE_UNDEFINED_ERROR) ?
"CIP_TUNER_UNDEFINED_ERROR" :
"unknown (returning UNDEFINED_ERROR)")
615 (void)STB_CITuneReply(module, status);
619 DBG_HC(
"(%u): already asked to release HC session", module)
645 hc_state = cihc_list;
646 while (hc_state != NULL)
648 if (module == hc_state->module)
650 if (hc_state->disabled)
656 hc_state = hc_state->next;
670 static void* FindService(U16BIT net_id, U16BIT onet_id, U16BIT ts_id, U16BIT sid)
674 FUNCTION_START(FindService);
678 while (service != NULL)
681 if ((service->serv_id == sid) &&
682 (service->transport->tran_id == ts_id) &&
683 (service->transport->orig_net_id == onet_id) &&
684 ((net_id == 0) || (service->transport->network->net_id == net_id)))
692 FUNCTION_FINISH(FindService);
704 static void* FindTransport(U16BIT net_id, U16BIT onet_id, U16BIT ts_id)
708 FUNCTION_START(FindTransport);
712 while (transport != NULL)
715 if ((transport->tran_id == ts_id) &&
716 (transport->orig_net_id == onet_id) &&
717 ((net_id == 0) || (transport->network->net_id == net_id)))
725 FUNCTION_FINISH(FindTransport);
void ACI_HcTuneService(U32BIT module, void *s_ptr, E_CIP_TUNE_FLAGS flags)
Handle tune to service request from the CAM.
CI plus support functions.
void * STB_GetMemory(U32BIT bytes)
Attempts to allocate memory from the heap.
U8BIT STB_DPGetPathCISlot(U8BIT path)
Returns the CI slot id associated with the given path.
BOOLEAN STB_CiCcAuthenticated(U8BIT slot_id)
Tell whether authenticated CI+ module is in the slot.
Application database control.
BOOLEAN ACI_PathOwnedByModule(U8BIT path, U32BIT module)
Checks whether path is owned by CI module.
void * STB_AppGetMemory(U32BIT bytes)
Attempts to allocate memory from the application heap.
BOOLEAN ACI_HcAskRelease(U32BIT module)
Ask the module to restore replaced PIDs and to close the session with the host control resource...
void STB_SIReleaseStringDesc(SI_STRING_DESC *desc)
Frees the memory used by the descriptor specified.
BOOLEAN ACI_HcTuneReply(U32BIT module, E_STB_CI_TUNE_STATUS status)
Send status of tune operation to the CAM host control module.
void ACI_HcInitialise(void)
Initialise CI Host Control support.
void ACI_TuneToService(U32BIT module, void *s_ptr, E_CIP_TUNE_FLAGS flags)
Schedule a tune to a service.
void ACI_TuneToDelSysDesc(U32BIT module, S_CIP_TUNE_DEL_SYS_DESC *tune, E_CIP_TUNE_FLAGS flags)
Tune to a service/transport defined by a delivery system descriptor, possibly with PMT data...
void STB_OSMutexUnlock(void *mutex)
Unlock a mutex (a.k.a. 'leave', 'signal' or 'release')
void STB_ERSendEvent(BOOLEAN latched, BOOLEAN repeat, U16BIT path_class, U16BIT type, void *data, U32BIT data_size)
Sends an event to event reporting control module.
Application level CI Host Control functions.
U8BIT STB_DPGetNumPaths(void)
Returns the maximum number of decode paths.
U8BIT STB_DPGetLivePath(void)
Returns the ID of the decode path being used for live viewing.
ADB_TRANSPORT_REC * DBDEF_GetNextTransportRec(ADB_TRANSPORT_REC *t_ptr)
Returns the transport following the one given. If the argument is NULL then the first transport will ...
void STB_FreeMemory(void *addr)
Releases previously allocated heap memory.
BOOLEAN STB_SIParseDelSysDesc(U8BIT *data, SI_DELIVERY_SYS_DESC_TYPE *type, SI_DELIVERY_SYS_DESC **desc)
Parses and allocates a system delivery descriptor which should be freed by calling STB_SIReleaseDelSy...
BOOLEAN STB_SIParseServiceDescriptor(U8BIT *data, U8BIT *type, SI_STRING_DESC **provider, SI_STRING_DESC **name)
Parses a service descriptor, tag 0x48, allocating SI strings that must be freed using STB_SIReleaseSt...
void DBDEF_ReleaseAccess(void)
Releases access to the app's database.
U16BIT ADB_GetServiceLcn(void *s_ptr)
Returns the logical channel number assigned to the given service.
Debug functions header file.
void STB_OSMutexLock(void *mutex)
Lock a mutex (a.k.a. 'enter', 'wait' or 'get').
ADB_SERVICE_REC * DBDEF_GetNextServiceRec(ADB_SERVICE_REC *s_ptr)
Returns the service after the one given. If NULL is passed then the first service in the list is retu...
Application level CI - internal functions.
Header file - Function prototypes for Event Reporting.
void DBDEF_RequestAccess(void)
Requests access to the app's database.
void ACI_HcTune(U32BIT module, U16BIT nid, U16BIT onid, U16BIT tsid, U16BIT sid)
Handle Tune request from the CAM.
Application stb layer control.
Header file - Function prototypes for operating system.
System Wide Global Technical Data Type Definitions.
void ACI_HcTuneBroadcastRequest(U32BIT module, U16BIT service_id, U16BIT desc_loop_len, U8BIT *desc_loop, U8BIT *pmt, E_CIP_TUNE_FLAGS flags)
This function is used by the CI+ stack to request that the host tunes to a transport stream using the...
void ACI_HcNotifyHostControlSessionClosed(U32BIT module)
This function is used by the CI stack to notify the host that a session with the host control resourc...
BOOLEAN ACTL_ReleasePathOwnership(U8BIT path, E_STB_DP_RES_OWNER owner)
Releases ownership of the path, and frees any associated data, if the given owner is the path's owner...
void ACI_TuneToTransport(U32BIT module, void *t_ptr)
Schedule a tune to a transport.
void ACI_HcAskReleaseReply(U32BIT module, U8BIT release_reply)
This function is called by the CI+ stack to send the reply of a release request to the host...
Header file - Function prototypes for heap memory.
void ACI_HcNotifyHostControlSession(U32BIT module)
This function is used by the CI stack to notify the host that a session with the host countrol resour...
void * STB_OSCreateMutex(void)
Create a mutex.
BOOLEAN ACTL_AcquirePathOwnership(U8BIT path, S_ACTL_OWNER_INFO *owner_info)
Attempts to take ownership of the given path (used by CI+)