48 #define MAX_CICAM_BRANDS 126 52 #define DBG_CC(x, ...) STB_SPDebugWrite( "%s:%d " x, __FUNCTION__, __LINE__, ##__VA_ARGS__); 54 #define DBG_CC(x, ...) 59 #define DBG_REC(x, ...) STB_SPDebugWrite( x, ##__VA_ARGS__ ); 61 #define DBG_REC(x, ...) 78 BOOLEAN sdt_acquisition_complete;
79 BOOLEAN free_ci_mode_flag;
80 BOOLEAN match_brand_flag;
81 U8BIT number_of_entries;
82 U16BIT entries[MAX_CICAM_BRANDS];
90 E_CI_AUTH_STATUS auth_status;
92 U16BIT program_number;
95 U16BIT cicam_brand_id;
108 U16BIT record_service_id;
110 E_STB_CI_OPERATING_MODE operating_mode;
111 S_STB_CI_URI recording_uri;
112 U8BIT recording_licence_status;
113 U8BIT *recording_licence;
114 U16BIT recording_licence_len;
115 U8BIT record_age_rating;
116 U8BIT record_private_data[CIP_PIN_PRIVATE_DATA_SIZE];
117 S_STB_CI_DATE pin_event_date;
118 S_STB_CI_TIME pin_event_time;
119 U8BIT record_pin_status;
121 BOOLEAN pin_caps_requested;
122 BOOLEAN pin_caps_received;
123 E_STB_CI_PIN_CAPS pin_caps;
124 S_STB_CI_DATE pin_date;
125 S_STB_CI_TIME pin_time;
129 BOOLEAN play_pin_sent;
130 U16BIT play_service_id;
131 S_STB_CI_URI playback_uri;
132 U8BIT playback_licence_status;
133 U8BIT *playback_licence;
134 U16BIT playback_licence_len;
140 static S_CI_PROTECTION ci_protection_info = {FALSE, FALSE, FALSE, 0, {0}};
142 static void *cicc_mutex;
145 static BOOLEAN IsServiceAllowed(
S_SLOT_STATE *slot_state,
146 U8BIT *ci_protection_descriptor);
147 static void ParseCiProtectionDescriptor(U8BIT *ci_protection_descriptor);
148 static void ApplyURIv1(S_STB_CI_URI *uri, BOOLEAN playback);
149 static void ApplyURIv2(S_STB_CI_URI *uri, BOOLEAN playback);
150 static void ApplyInvalidURI(
void);
151 static void PackUri(S_STB_CI_URI *uri, U8BIT buffer[CIP_URI_LEN]);
152 static void UnpackUri(U8BIT buffer[CIP_URI_LEN], S_STB_CI_URI *uri);
178 slot_info = FindSlot(slot_id);
179 if (slot_info != NULL)
181 DBGPRINT(
"CAM already inserted to slot %d! Inconsistent state!", slot_id);
186 if (slot_info != NULL)
188 slot_info->ready = FALSE;
189 slot_info->disabled = FALSE;
190 slot_info->slot_id = slot_id;
191 slot_info->auth_status = CI_AUTH_NONE;
192 slot_info->cicam_brand_id = 0x0000;
193 slot_info->program_number = 0xFFFF;
194 slot_info->play_service_id = 0xFFFF;
195 slot_info->record_service_id = 0xFFFF;
197 slot_info->recording = FALSE;
198 slot_info->op_mode_set = FALSE;
199 slot_info->operating_mode = STB_CI_MODE_UNATTENDED_RECORDING;
200 slot_info->recording_licence = NULL;
201 slot_info->recording_licence_len = 0;
202 slot_info->pin_caps_requested = FALSE;
203 slot_info->pin_caps_received = FALSE;
204 slot_info->pin_caps = STB_CI_PIN_CAPS_NONE;
205 slot_info->play_pin_sent = FALSE;
206 slot_info->playback_licence = NULL;
207 slot_info->playback_licence_len = 0;
210 slot_info->next = cicc_slots;
211 cicc_slots = slot_info;
214 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_CI, EV_TYPE_CI_INSERT, &slot_id,
sizeof(slot_id));
235 slot = FindSlot(slot_id);
239 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_CI, EV_TYPE_CI_SLOT_STATUS_UPDATED, &slot_id,
sizeof slot_id);
260 slot = FindSlot(slot_id);
263 slot->disabled = TRUE;
266 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_CI, EV_TYPE_CI_REMOVE, &slot_id,
sizeof(slot_id));
287 if (slot->slot_id == slot_id)
290 if (slot->recording_licence != NULL)
293 slot->recording_licence = NULL;
295 if (slot->playback_licence != NULL)
298 slot->playback_licence = NULL;
303 pslot = &(slot->next);
326 slot = FindSlot(slot_id);
358 slot = FindSlot(slot_id);
359 if (slot != NULL && slot->ready)
361 allowed = IsServiceAllowed(slot, ci_prot_desc);
383 slot = FindSlot(slot_id);
384 if (slot != NULL && slot->ready)
386 auth = (slot->auth_status == CI_AUTH_SUCCESS)? TRUE : FALSE;
401 U8BIT slot_id, num_slots;
402 U8BIT
id[CIP_CICAM_ID_LEN];
404 FUNCTION_START(FindSlotForCicamId);
405 num_slots = STB_CIGetSlotCount();
406 for (slot_id = 0; slot_id != num_slots; slot_id++)
408 if (STB_CIGetCicamId(slot_id,
id))
410 if (memcmp(
id, cicam_id, CIP_CICAM_ID_LEN) == 0)
417 if (slot_id == num_slots)
419 slot_id = INVALID_RES_ID;
421 FUNCTION_FINISH(FindSlotForCicamId);
437 DBGPRINT(
"%s", complete ?
"TRUE" :
"FALSE")
438 ci_protection_info.sdt_acquisition_complete = complete;
450 U8BIT raw_uri[CIP_URI_LEN])
456 memset(raw_uri, 0, CIP_URI_LEN);
458 slot_state = FindSlot(slot_id);
459 if ((slot_state != NULL) && (slot_state->program_number == service_id))
461 DBGPRINT(
"Found URI for service_id = %d", service_id)
462 PackUri(&slot_state->uri, raw_uri);
481 memset(raw_uri, 0x00, CIP_URI_LEN);
498 U32BIT retention_limit;
505 UnpackUri(raw_uri, &uri);
506 if ((uri.protocol_version == 0x01) || (uri.protocol_version == 0x02))
508 if (uri.rl_copy_control_info == 0x0)
511 retention_limit = 90;
513 else if (uri.rl_copy_control_info == 0x1)
516 retention_limit = 6 * 60;
518 else if (uri.rl_copy_control_info == 0x2)
521 retention_limit = 12 * 60;
525 if (uri.protocol_version == 0x01)
528 retention_limit = (uri.rl_copy_control_info - 2) * 24 * 60;
530 else if (uri.rl_copy_control_info != 0xff)
533 retention_limit = (uri.rl_copy_control_info - 2) * 24 * 60;
540 return retention_limit;
553 UnpackUri(raw_uri, &uri);
555 switch (uri.protocol_version)
558 ApplyURIv1(&uri, FALSE);
562 ApplyURIv2(&uri, FALSE);
584 UnpackUri(raw_uri, &uri);
586 switch (uri.protocol_version)
589 ApplyURIv1(&uri, TRUE);
593 ApplyURIv2(&uri, TRUE);
618 slot_info = cicc_slots;
619 while (slot_info != NULL)
621 if (slot_info->program_number == service_id)
629 slot_info = slot_info->next;
652 U8BIT path, tuner_path;
656 DBG_CC(
"State: %s, CICAM brand ID: %04x",
657 state == STB_CI_CC_START ?
"STB_CI_CC_START" :
658 state == STB_CI_CC_VERIFIED ?
"STB_CI_CC_VERIFIED" :
659 state == STB_CI_CC_CERT_EXPIRED ?
"STB_CI_CC_CERT_EXPIRED" :
660 state == STB_CI_CC_PROTOCOL_ERROR ?
"STB_CI_CC_PROTOCOL_ERROR" :
661 state == STB_CI_CC_AUTH_ERROR ?
"STB_CI_CC_AUTH_ERROR" :
662 "UNKNOWN", cicam_brand_id)
664 slot_state = FindSlot(slot_id);
665 if (slot_state != NULL)
667 if (STB_CIGetContentControlVersion(slot_id) >= 2)
669 if (!slot_state->pin_caps_requested)
671 DBG_CC(
"%s(%u): Requesting PIN capabilities", __FUNCTION__, slot_id)
673 slot_state->pin_caps_received = FALSE;
675 if (STB_CIRequestPinCaps(slot_id))
677 slot_state->pin_caps_requested = TRUE;
682 DBG_CC(
"%s(%u): Failed to request PIN capabilities", __FUNCTION__, slot_id)
690 case STB_CI_CC_START:
692 slot_state->auth_status = CI_AUTH_IN_PROGRESS;
701 STB_CIRouteTS(tuner_path, slot_state->slot_id, TRUE);
706 case STB_CI_CC_AUTH_ERROR:
707 case STB_CI_CC_STATUS_AUTHENTICATION_FAILED:
708 case STB_CI_CC_PROTOCOL_ERROR:
710 slot_state->auth_status = CI_AUTH_FAIL;
713 case STB_CI_CC_VERIFIED:
715 slot_state->auth_status = CI_AUTH_SUCCESS;
716 slot_state->cicam_brand_id = cicam_brand_id;
726 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_CI, EV_TYPE_CI_SLOT_STATUS_UPDATED, &slot_id,
sizeof slot_id);
744 slot_state = FindSlot(slot_id);
745 if (slot_state != NULL)
747 DBGPRINT(
"Storing URI for program_number = %d", program_number)
748 DBGPRINT(
"URI = {pv=%d, aps=%d, emi=%d, ict=%d, rct=%d, dot=%d, rl=%d",
749 uri->protocol_version,
750 uri->aps_copy_control_info,
751 uri->emi_copy_control_info,
752 uri->ict_copy_control_info,
753 uri->rct_copy_control_info,
754 uri->dot_copy_control_info,
755 uri->rl_copy_control_info)
756 slot_state->program_number = program_number;
757 slot_state->uri = *uri;
759 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_CI, EV_TYPE_CI_URI_UPDATED, &slot_id,
sizeof(slot_id));
779 U8BIT
STB_CINotifySRM(U8BIT slot_id, E_STB_SRM_DATA_TYPE srm_type, U8BIT *data, U16BIT len)
782 E_STB_AV_SRM_REPLY srm_reply;
785 USE_UNWANTED_PARAM(slot_id);
787 if (srm_type == STB_CI_SRM_HDCP)
796 rc = STB_CI_SRM_HOST_BUSY;
798 case SRM_NOT_REQUIRED:
799 rc = STB_CI_SRM_NOT_REQUIRED;
803 DBGPRINT(
"Unexpected reply 0x%x", srm_reply)
804 rc = STB_CI_SRM_HOST_BUSY;
810 rc = STB_CI_SRM_NO_CC_SUPPORT;
834 void STB_CINotifyPinCaps(U8BIT slot_id, E_STB_CI_PIN_CAPS capability,
835 S_STB_CI_DATE *pin_date, S_STB_CI_TIME *pin_time,
840 FUNCTION_START(STB_CINotifyPinCaps);
842 DBG_CC(
"(slot=%u, caps=%u, rating=%u)", slot_id, capability, rating)
844 if ((slot_state = FindSlot(slot_id)) != NULL)
846 if (slot_state->pin_caps_requested)
848 slot_state->age_rating = rating;
849 slot_state->pin_caps = capability;
850 slot_state->pin_caps_received = TRUE;
851 slot_state->pin_date = *pin_date;
852 slot_state->pin_time = *pin_time;
857 DBG_CC(
"%s(%u): PIN capabilities weren't requested!", __FUNCTION__, slot_id)
862 FUNCTION_FINISH(STB_CINotifyPinCaps);
882 DBG_CC(
"(slot=%u, pin=\"%s\")", slot_id, pin_data)
884 if (((slot_state = FindSlot(slot_id)) != NULL) &&
885 slot_state->pin_caps_received && (slot_state->pin_caps != STB_CI_PIN_CAPS_NONE))
887 slot_state->play_pin_sent = FALSE;
888 retval = STB_CISendPinCmd(slot_id, pin_data);
910 void STB_CINotifyPinReply(U8BIT slot_id, E_STB_CI_PIN_STATUS status)
914 FUNCTION_START(STB_CINotifyPinReply);
916 DBG_CC(
"(slot=%u, status=%d)", slot_id, status)
918 if ((slot_state = FindSlot(slot_id)) != NULL)
921 if (slot_state->play_pin_sent)
923 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_CI, EV_TYPE_CI_PLAYBACK_PIN_STATUS,
924 &status,
sizeof(E_STB_CI_PIN_STATUS));
929 &status,
sizeof(E_STB_CI_PIN_STATUS));
933 FUNCTION_FINISH(STB_CINotifyPinReply);
955 void STB_CINotifyPinEvent(U8BIT slot_id, U16BIT program_number,
956 E_STB_CI_PIN_STATUS status, U8BIT rating,
957 S_STB_CI_DATE *event_date, S_STB_CI_TIME *event_time,
958 U8BIT private_data[CIP_PIN_PRIVATE_DATA_SIZE])
962 FUNCTION_START(STB_CINotifyPinEvent);
964 DBG_CC(
"(slot=%u, program=%u, status=%u, date=%u/%u/%u, time=%u:%02u:%02u, rating=%u)",
965 slot_id, program_number, status, event_date->day, event_date->month,
966 event_date->year, event_time->hour, event_time->minute, event_time->second, rating)
968 if ((slot_state = FindSlot(slot_id)) != NULL)
971 if (slot_state->recording && (program_number == slot_state->record_service_id))
975 slot_state->record_pin_status = status;
976 slot_state->record_age_rating = rating;
977 slot_state->pin_event_date = *event_date;
978 slot_state->pin_event_time = *event_time;
979 memcpy(slot_state->record_private_data, private_data, CIP_PIN_PRIVATE_DATA_SIZE);
981 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_CI, EV_TYPE_CI_RECORD_PIN, &slot_id,
sizeof(slot_id));
985 FUNCTION_FINISH(STB_CINotifyPinEvent);
1001 U8BIT **private_data, U16BIT *date_code, U8BIT *hour, U8BIT *min, U8BIT *sec)
1010 if ((slot_state = FindSlot(slot_id)) != NULL)
1012 if (slot_state->recording)
1014 *status = slot_state->record_pin_status;
1015 *age_rating = slot_state->record_age_rating;
1016 *private_data = slot_state->record_private_data;
1017 *date_code = slot_state->pin_event_date.mjd;
1018 *hour = slot_state->pin_event_time.hour;
1019 *min = slot_state->pin_event_time.minute;
1020 *sec = slot_state->pin_event_time.second;
1046 DBG_REC(
"%s(slot=%u, age=%u)", __FUNCTION__, slot_id, age_rating)
1048 if ((slot_state = FindSlot(slot_id)) != NULL)
1050 slot_state->play_pin_sent = TRUE;
1051 retval = STB_CISendPinPlayback(slot_id, age_rating, private_data);
1071 DBG_REC(
"%s(slot=%u, mode=%s, service_id=%u)", __FUNCTION__, slot_id,
1072 ((mode == STB_CI_MODE_WATCH_AND_BUFFER) ?
"WATCH_AND_BUFFER" :
1073 (mode == STB_CI_MODE_TIMESHIFT) ?
"TIMESHIFT" :
1074 (mode == STB_CI_MODE_UNATTENDED_RECORDING) ?
"UNATTENDED" :
"UNKNOWN!"), service_id)
1076 if (mode <= STB_CI_MODE_UNATTENDED_RECORDING)
1078 if ((slot_state = FindSlot(slot_id)) != NULL)
1081 if ((STB_CIGetContentControlVersion(slot_id) >= 2) &&
1082 (!slot_state->op_mode_set || (mode != slot_state->operating_mode)))
1084 DBG_REC(
"%s: Current mode %s", __FUNCTION__,
1085 ((slot_state->operating_mode == STB_CI_MODE_WATCH_AND_BUFFER) ?
"WATCH_AND_BUFFER" :
1086 (slot_state->operating_mode == STB_CI_MODE_TIMESHIFT) ?
"TIMESHIFT" :
1087 (slot_state->operating_mode == STB_CI_MODE_UNATTENDED_RECORDING) ?
"UNATTENDED" :
"UNKNOWN!"))
1090 if (slot_state->recording == TRUE)
1092 slot_state->op_mode_set = STB_CIChangeOperatingMode(slot_id, mode, service_id);
1096 slot_state->operating_mode = mode;
1118 DBG_REC(
"%s(slot=%u, program=%u, pin=\"%s\")", __FUNCTION__, slot_id, program_number, pin_string)
1120 if ((slot_state = FindSlot(slot_id)) != NULL)
1122 slot_state->recording = TRUE;
1123 slot_state->record_service_id = program_number;
1126 if ((STB_CIGetContentControlVersion(slot_id) >= 2) &&
1127 slot_state->pin_caps_received && (slot_state->pin_caps != STB_CI_PIN_CAPS_NONE))
1129 DBG_REC(
"%s(%u): Asking CAM to start recording in %s mode using pin \"%s\"",
1130 __FUNCTION__, slot_id,
1131 ((slot_state->operating_mode == STB_CI_MODE_WATCH_AND_BUFFER) ?
"WATCH_AND_BUFFER" :
1132 (slot_state->operating_mode == STB_CI_MODE_TIMESHIFT) ?
"TIMESHIFT" :
1133 (slot_state->operating_mode == STB_CI_MODE_UNATTENDED_RECORDING) ?
"UNATTENDED" :
"UNKNOWN"),
1136 retval = STB_CISendRecordStart(slot_id, slot_state->operating_mode, program_number, pin_string);
1139 DBG_REC(
"%s(%u): Failed to send record start to CAM", __FUNCTION__, slot_id)
1140 slot_state->recording = FALSE;
1141 slot_state->record_service_id = 0xFFFF;
1147 DBG_REC(
"%s(%u): No need to ask CAM, recording can start", __FUNCTION__, slot_id)
1149 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_CI, EV_TYPE_CI_RECORD_START, &slot_id,
sizeof(slot_id));
1177 DBG_REC(
"%s(slot=%u, status=%u)", __FUNCTION__, slot_id, status)
1179 if (status == STB_CI_CC_STATUS_OK)
1182 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_CI, EV_TYPE_CI_RECORD_START, &slot_id,
sizeof(slot_id));
1187 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_CI, EV_TYPE_CI_RECORD_START_FAILED, &slot_id,
sizeof(slot_id));
1218 U8BIT licence_status, S_STB_CI_URI *uri,
1219 U8BIT *licence, U16BIT licence_len)
1225 USE_UNWANTED_PARAM(licence_status);
1227 DBG_REC(
"%s(slot=%u, program=%u, licence_status=%u, uri=%p, licence=%p, licence_len=%u)",
1228 __FUNCTION__, slot_id, program_number, licence_status, uri, licence, licence_len)
1230 if ((slot_state = FindSlot(slot_id)) != NULL)
1232 if (slot_state->recording && (slot_state->record_service_id == program_number))
1235 slot_state->recording_uri = *uri;
1237 if ((slot_state->recording_licence != NULL) &&
1238 (slot_state->recording_licence_len != licence_len))
1242 slot_state->recording_licence = NULL;
1243 slot_state->recording_licence_len = 0;
1247 if (slot_state->recording_licence == NULL)
1249 if ((slot_state->recording_licence =
STB_GetMemory(licence_len)) != NULL)
1251 slot_state->recording_licence_len = licence_len;
1255 if (slot_state->recording_licence != NULL)
1257 slot_state->recording_licence_status = licence_status;
1259 memcpy(slot_state->recording_licence, licence, licence_len);
1262 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_CI, EV_TYPE_CI_RECORD_LICENCE_UPDATED, &slot_id,
1269 if (!slot_state->recording)
1271 DBG_REC(
"%s(%u): Slot isn't being used for recording", __FUNCTION__, slot_id)
1275 DBG_REC(
"%s(%u): Slot is recording program %u", __FUNCTION__, slot_id, slot_state->record_service_id)
1293 U8BIT raw_uri[CIP_URI_LEN])
1302 if ((slot_state = FindSlot(slot_id)) != NULL)
1304 licence = slot_state->recording_licence;
1305 *licence_status = slot_state->recording_licence_status;
1306 *licence_len = slot_state->recording_licence_len;
1307 PackUri(&slot_state->recording_uri, raw_uri);
1332 DBG_REC(
"%s(slot=%u, program=%u, licence=%p, licence_len=%u)", __FUNCTION__, slot_id,
1333 program_number, licence, licence_len)
1337 if ((slot_state = FindSlot(slot_id)) != NULL)
1339 slot_state->play_service_id = program_number;
1340 retval = STB_CISendPlaybackLicense(slot_id, program_number, licence, licence_len);
1343 slot_state->play_service_id = 0xFFFF;
1344 DBG_REC(
"%s(%u): Failed to send playback licence", __FUNCTION__, slot_id)
1378 U8BIT licence_status, S_STB_CI_URI *uri,
1379 U8BIT *licence, U16BIT licence_len)
1385 USE_UNWANTED_PARAM(licence_status);
1387 DBG_REC(
"%s(slot=%u, program=%u, licence_status=%u, uri=%p, licence=%p, licence_len=%u)",
1388 __FUNCTION__, slot_id, program_number, licence_status, uri, licence, licence_len)
1390 if ((slot_state = FindSlot(slot_id)) != NULL)
1392 if (slot_state->play_service_id == program_number)
1395 slot_state->playback_uri = *uri;
1397 if ((slot_state->playback_licence != NULL) &&
1398 (slot_state->playback_licence_len != licence_len))
1402 slot_state->playback_licence = NULL;
1403 slot_state->playback_licence_len = 0;
1407 if (slot_state->playback_licence == NULL)
1409 if ((slot_state->playback_licence =
STB_GetMemory(licence_len)) != NULL)
1411 slot_state->playback_licence_len = licence_len;
1415 if (slot_state->playback_licence != NULL)
1417 slot_state->playback_licence_status = licence_status;
1419 memcpy(slot_state->playback_licence, licence, licence_len);
1422 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_CI, EV_TYPE_CI_PLAYBACK_LICENCE_UPDATED, &slot_id,
1428 DBG_REC(
"%s(%u): Slot is playing program %u", __FUNCTION__, slot_id, slot_state->play_service_id)
1444 U8BIT raw_uri[CIP_URI_LEN])
1453 if ((slot_state = FindSlot(slot_id)) != NULL)
1455 licence = slot_state->playback_licence;
1456 *licence_status = slot_state->playback_licence_status;
1457 *licence_len = slot_state->playback_licence_len;
1458 PackUri(&slot_state->playback_uri, raw_uri);
1488 DBG_REC(
"%s(slot=%u, licence_status=%u, play_count=%u)", __FUNCTION__, slot_id, licence_status,
1491 USE_UNWANTED_PARAM(slot_id);
1492 USE_UNWANTED_PARAM(licence_status);
1493 USE_UNWANTED_PARAM(play_count);
1516 DBG_REC(
"%s(slot=%u, status=%u)", __FUNCTION__, slot_id, status)
1518 USE_UNWANTED_PARAM(slot_id);
1519 USE_UNWANTED_PARAM(status);
1538 DBG_REC(
"%s(slot=%u)", __FUNCTION__, slot_id)
1540 if ((slot_state = FindSlot(slot_id)) != NULL)
1542 if (slot_state->recording)
1544 if ((STB_CIGetContentControlVersion(slot_id) >= 2) &&
1545 slot_state->pin_caps_received && (slot_state->pin_caps != STB_CI_PIN_CAPS_NONE))
1547 DBG_REC(
"%s(%u): Sending record stop to CAM", __FUNCTION__, slot_id)
1550 retval = STB_CISendRecordStop(slot_id, slot_state->record_service_id);
1554 DBG_REC(
"%s(%u): Failed to send record stop to CAM", __FUNCTION__, slot_id)
1560 DBG_REC(
"%s(%u): No need to inform CAM", __FUNCTION__, slot_id)
1564 slot_state->recording = FALSE;
1591 DBG_REC(
"%s(slot=%u, status=%u)", __FUNCTION__, slot_id, status)
1593 USE_UNWANTED_PARAM(slot_id);
1594 USE_UNWANTED_PARAM(status);
1606 slot_info = cicc_slots;
1607 while (slot_info != NULL)
1609 if (slot_info->slot_id == slot_id)
1611 if (slot_info->disabled)
1617 slot_info = slot_info->next;
1633 static BOOLEAN IsServiceAllowed(
S_SLOT_STATE *slot_state,
1634 U8BIT *ci_protection_descriptor)
1639 FUNCTION_START(IsServiceAllowed);
1643 if (ci_protection_info.sdt_acquisition_complete)
1645 ParseCiProtectionDescriptor(ci_protection_descriptor);
1646 if (ci_protection_info.free_ci_mode_flag == FALSE)
1649 DBGPRINT(
"free_ci_mode_flag == FALSE: allowed = TRUE")
1652 else if (slot_state->auth_status == CI_AUTH_SUCCESS)
1654 if (ci_protection_info.match_brand_flag == FALSE)
1657 DBGPRINT(
"CI+ only, no brand matching, authenticated: allowed = TRUE")
1662 for (i = 0; i < ci_protection_info.number_of_entries; i++)
1664 if (slot_state->cicam_brand_id == ci_protection_info.entries[i])
1667 DBGPRINT(
"CI+ only, brand found: allowed = TRUE")
1681 FUNCTION_FINISH(IsServiceAllowed);
1691 static void ParseCiProtectionDescriptor(U8BIT *ci_protection_descriptor)
1696 U8BIT number_of_entries;
1700 FUNCTION_START(ParseCiProtectionDescriptor);
1702 if (ci_protection_descriptor == NULL)
1705 DBGPRINT(
"ci_protection_descriptor == NULL: no restriction")
1706 ci_protection_info.free_ci_mode_flag = FALSE;
1707 ci_protection_info.match_brand_flag = FALSE;
1708 ci_protection_info.number_of_entries = 0;
1713 d = ci_protection_descriptor;
1717 DBGPRINT(
"ci_protection_descriptor: tag=%x, len=%d", tag, len)
1719 ci_protection_info.free_ci_mode_flag = TRUE;
1720 ci_protection_info.match_brand_flag = TRUE;
1721 ci_protection_info.number_of_entries = 0;
1723 if (tag == 0xCE && len >= 1)
1726 if (((d[2] >> 7) & 0x1) == 0x0)
1728 ci_protection_info.free_ci_mode_flag = FALSE;
1732 ci_protection_info.free_ci_mode_flag = TRUE;
1735 if (((d[2] >> 6) & 0x1) == 0x0)
1737 ci_protection_info.match_brand_flag = FALSE;
1741 ci_protection_info.match_brand_flag = TRUE;
1742 ci_protection_info.number_of_entries = 0;
1748 number_of_entries = d[3];
1749 DBGPRINT(
"number_of_entries = %d", number_of_entries)
1750 entry = ci_protection_info.entries;
1752 while (ci_protection_info.number_of_entries < number_of_entries &&
1755 *entry = d[2 + offset] << 8 | d[2 + offset + 1];
1757 ci_protection_info.number_of_entries++;
1766 FUNCTION_FINISH(ParseCiProtectionDescriptor);
1775 static void ApplyURIv1(S_STB_CI_URI *uri, BOOLEAN playback)
1777 U8BIT aps, emi, rct, ict;
1780 memset(&cp, 0,
sizeof cp);
1785 aps = uri->aps_copy_control_info;
1786 emi = uri->emi_copy_control_info;
1787 rct = uri->rct_copy_control_info;
1788 ict = uri->ict_copy_control_info;
1792 cp.macrovision_set = TRUE;
1793 cp.macrovision = ((rct || emi) * 3) & aps;
1798 cp.aps = ((emi != 0) * 3) & aps;
1801 cp.cgms_a_set = TRUE;
1805 if ((rct == 0) && (emi == 0x2))
1835 cp.scms = emi & 0x1;
1851 static void ApplyURIv2(S_STB_CI_URI *uri, BOOLEAN playback)
1853 U8BIT aps, emi, rct, ict;
1856 memset(&cp, 0,
sizeof cp);
1861 aps = uri->aps_copy_control_info;
1862 emi = uri->emi_copy_control_info;
1863 rct = uri->rct_copy_control_info;
1864 ict = uri->ict_copy_control_info;
1868 cp.macrovision_set = TRUE;
1869 cp.macrovision = ((rct || emi) * 3) & aps;
1874 cp.aps = ((emi != 0) * 3) & aps;
1877 cp.cgms_a_set = TRUE;
1881 if ((rct == 0) && (emi == 0x2))
1911 cp.scms = emi & 0x1;
1916 cp.dot = uri->dot_copy_control_info;
1926 static void ApplyInvalidURI(
void)
1930 memset(&cp, 0,
sizeof cp);
1940 static void PackUri(S_STB_CI_URI *uri, U8BIT buffer[CIP_URI_LEN])
1942 FUNCTION_START(PackUri);
1944 memset(buffer, 0x00, CIP_URI_LEN);
1948 if (uri->protocol_version == 0x01)
1953 buffer[1] |= (uri->aps_copy_control_info & 0x3) << 6;
1954 buffer[1] |= (uri->emi_copy_control_info & 0x3) << 4;
1955 buffer[1] |= (uri->ict_copy_control_info & 0x1) << 3;
1956 buffer[1] |= (uri->rct_copy_control_info & 0x1) << 2;
1959 buffer[2] |= 0xc0 << 6;
1960 buffer[2] |= (uri->rl_copy_control_info & 0x3f);
1963 buffer[3] = buffer[4] = buffer[5] = buffer[6] = buffer[7] = 0xff;
1965 else if (uri->protocol_version == 0x02)
1970 buffer[1] |= (uri->aps_copy_control_info & 0x3) << 6;
1971 buffer[1] |= (uri->emi_copy_control_info & 0x3) << 4;
1972 buffer[1] |= (uri->ict_copy_control_info & 0x1) << 3;
1974 if ((uri->emi_copy_control_info & 0x03) == 0x00)
1976 buffer[1] |= (uri->rct_copy_control_info & 0x1) << 2;
1982 if ((uri->emi_copy_control_info & 0x03) == 0x03)
1984 buffer[1] |= (uri->dot_copy_control_info & 0x01);
1985 buffer[2] = uri->rl_copy_control_info & 0xfe;
1989 buffer[3] = buffer[4] = buffer[5] = buffer[6] = buffer[7] = 0xff;
1993 FUNCTION_FINISH(PackUri);
2002 static void UnpackUri(U8BIT buffer[CIP_URI_LEN], S_STB_CI_URI *uri)
2004 FUNCTION_START(UnpackUri);
2006 if (buffer[0] == 0x01)
2009 uri->protocol_version = buffer[0];
2011 uri->aps_copy_control_info = (buffer[1] >> 6) & 0x3;
2012 uri->emi_copy_control_info = (buffer[1] >> 4) & 0x3;
2013 uri->ict_copy_control_info = (buffer[1] >> 3) & 0x1;
2014 uri->rct_copy_control_info = (buffer[1] >> 2) & 0x1;
2016 uri->rl_copy_control_info = buffer[2] & 0x3f;
2018 else if (buffer[0] == 0x02)
2021 uri->protocol_version = buffer[0];
2023 uri->aps_copy_control_info = (buffer[1] >> 6) & 0x3;
2024 uri->emi_copy_control_info = (buffer[1] >> 4) & 0x3;
2025 uri->ict_copy_control_info = (buffer[1] >> 3) & 0x1;
2026 uri->rct_copy_control_info = (buffer[1] >> 2) & 0x1;
2027 uri->dot_copy_control_info = buffer[1] & 0x1;
2029 uri->rl_copy_control_info = buffer[2] & 0xfe;
2034 uri->protocol_version = 0x00;
2037 FUNCTION_FINISH(UnpackUri);
void STB_CiCcSetRecordOperatingMode(U8BIT slot_id, U32BIT mode, U16BIT service_id)
Sets the record operating mode for the given slot id.
BOOLEAN STB_CiCcSendRecordStop(U8BIT slot_id)
Called by the app when a recording is stopped or completes.
U8BIT * STB_CiCcGetPlaybackLicence(U8BIT slot_id, U8BIT *licence_status, U16BIT *licence_len, U8BIT raw_uri[CIP_URI_LEN])
Returns the last licence received from the CAM during playback.
void STB_CiKeysDisable(U8BIT slot_id)
Disable CC keys for slot, as CAM is being removed.
void STB_CINotifyURI(U8BIT slot_id, U16BIT program_number, S_STB_CI_URI *uri)
Handle URI (usage rules information)
U8BIT * STB_CiCcGetRecordingLicence(U8BIT slot_id, U8BIT *licence_status, U16BIT *licence_len, U8BIT raw_uri[CIP_URI_LEN])
Returns the last licence received from the CAM when recording.
void * STB_GetMemory(U32BIT bytes)
Attempts to allocate memory from the heap.
BOOLEAN STB_CiCcSendPin(U8BIT slot_id, U8BIT *pin_data)
Called by the host to check whether a CAM pin is valid. An STB_EVENT_CI_PIN_STATUS event will be sent...
BOOLEAN STB_CiCcSendRecordStart(U8BIT slot_id, U16BIT program_number, U8BIT *pin_string)
Called by the app when a recording is to be started on a CA protected service.
void STB_CiCcNotifyModuleRemove(U8BIT slot_id)
Notify module removal.
void STB_CiCcApplyUsageRulesInfoForPlayback(U8BIT *raw_uri)
Apply the given Usage Rules Information for playback.
BOOLEAN STB_CiCcGetRecordingPinInfo(U8BIT slot_id, U8BIT *status, U8BIT *age_rating, U8BIT **private_data, U16BIT *date_code, U8BIT *hour, U8BIT *min, U8BIT *sec)
Returns the information to be stored with a pin event when recording.
Header file - macros and function prototypes for public use.
void STB_CINotifyRecordStartStatus(U8BIT slot_id, U8BIT status)
void STB_CINotifyRecordStopStatus(U8BIT slot_id, U8BIT status)
BOOLEAN STB_CiCcAuthenticated(U8BIT slot_id)
Tell whether the CI slot has been authenticated.
BOOLEAN STB_CiCcIsHDCPRequired(U16BIT service_id)
Tell whether the given service requires HDCP.
Header file - Function prototypes for A/V control.
U32BIT STB_CiCcGetRetentionLimit(U8BIT raw_uri[CIP_URI_LEN])
Return the retention limit given a packed URI.
BOOLEAN STB_CiCcIsSlotReady(U8BIT slot_id)
Return whether CI slot is ready.
void STB_OSMutexUnlock(void *mutex)
Unlock a mutex (a.k.a. 'leave', 'signal' or 'release')
E_STB_AV_SRM_REPLY STB_AVApplySRM(U8BIT path, U8BIT *data, U32BIT len)
Apply System Renewability Message (SRM) to HDCP function.
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.
void STB_CINotifyModeChangeStatus(U8BIT slot_id, U8BIT status)
void STB_CINotifyLicenseStatus(U8BIT slot_id, U8BIT licence_status, U8BIT play_count)
U8BIT STB_DPGetLivePath(void)
Returns the ID of the decode path being used for live viewing.
void STB_CiCcApplyUsageRulesInfo(U8BIT raw_uri[CIP_URI_LEN])
Apply the given Usage Rules Information.
void STB_CiCcGetDefaultUsageRulesInfo(U8BIT raw_uri[CIP_URI_LEN])
Sets the default URI values into the given array. The URI requires HDCP.
void STB_FreeMemory(void *addr)
Releases previously allocated heap memory.
void STB_CiKeysInitialise(void)
CI descrambler keys support initialise.
Debug functions header file.
BOOLEAN STB_CiCcIsServiceAllowed(U8BIT slot_id, U8BIT *ci_prot_desc)
Tell whether the service is allowed. This function checks whether the CI Protection Descriptor allows...
void STB_OSMutexLock(void *mutex)
Lock a mutex (a.k.a. 'enter', 'wait' or 'get').
void STB_CiCaInitialise(void)
CI conditional access support initialise.
U8BIT STB_DPGetPathTuner(U8BIT path)
Returns the tuner ID acquired by the given decode path.
void STB_CINotifyModuleReady(U8BIT slot_id, BOOLEAN ci_plus, U32BIT mask)
Notify module insertion.
Header file - Function prototypes for Event Reporting.
void STB_CiKeysRemove(U8BIT slot_id)
Process CAM removal from slot for CI Keys support.
CI Content Control support - internal header.
void STB_CINotifyPlaybackLicense(U8BIT slot_id, U16BIT program_number, U8BIT licence_status, S_STB_CI_URI *uri, U8BIT *licence, U16BIT licence_len)
void STB_CiCaDisable(U8BIT slot_id)
Disable CA for slot, as CAM is being removed.
Header file - Function prototypes for operating system.
System Wide Global Technical Data Type Definitions.
void STB_CiCaRemove(U8BIT slot_id)
Process CAM removal from slot for CA support.
void STB_CiCcSetSDTAcquisitionStatus(BOOLEAN complete)
To implement the first part of the diagram in Figure 10.2: Shunning Operation of ci-plus_specificatio...
U8BIT STB_CiCcFindSlotForCicamId(U8BIT cicam_id[CIP_CICAM_ID_LEN])
Checks CAMs in all slots to find the one with the given CAM id.
Header file - Function prototypes for heap memory.
void * STB_OSCreateMutex(void)
Create a mutex.
void STB_CiCcNotifyModuleInsert(U8BIT slot_id)
Notify module insertion.
void STB_CINotifyProgress(U8BIT slot_id, E_STB_CI_CC_STATE state, U16BIT cicam_brand_id)
Notify content control progress.
void STB_CINotifyRecordingLicense(U8BIT slot_id, U16BIT program_number, U8BIT licence_status, S_STB_CI_URI *uri, U8BIT *licence, U16BIT licence_len)
void STB_CiCcRemove(U8BIT slot_id)
Handle CAM removal from slot.
U8BIT STB_CINotifySRM(U8BIT slot_id, E_STB_SRM_DATA_TYPE srm_type, U8BIT *data, U16BIT len)
This function is called by the CI+ stack to send an SRM (System Renewability Message) to the host...
BOOLEAN STB_CiCcSendPlaybackLicence(U8BIT slot_id, U16BIT program_number, U8BIT *licence, U16BIT licence_len)
Sends a CICAM licence to a module during playback, which will result in a modified licence being noti...
void STB_CiCcGetUsageRulesInfo(U8BIT slot_id, U16BIT service_id, U8BIT raw_uri[CIP_URI_LEN])
Return the current URI for the given service.
void STB_CiCcInitialise(void)
CI content control support initialise.
BOOLEAN STB_CiCcSendPinPlayback(U8BIT slot_id, U8BIT age_rating, U8BIT *private_data)
Sends a pin event to the CAM during playback.
void STB_AVSetCopyProtection(S_STB_AV_COPY_PROTECTION *copy_protection)
Apply the specified copy protection. This function is used for CI+.