| 1 | /*************************************************************** |
|---|
| 2 | ** |
|---|
| 3 | ** Broadcom Corp. Confidential |
|---|
| 4 | ** Copyright 2003-2012 Broadcom Corp. All Rights Reserved. |
|---|
| 5 | ** |
|---|
| 6 | ** THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED |
|---|
| 7 | ** SOFTWARE LICENSE AGREEMENT BETWEEN THE USER AND BROADCOM. |
|---|
| 8 | ** YOU HAVE NO RIGHT TO USE OR EXPLOIT THIS MATERIAL EXCEPT |
|---|
| 9 | ** SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. |
|---|
| 10 | ** |
|---|
| 11 | ** File: si_ntm.c |
|---|
| 12 | ** Description: function that parses the NTM table sections. |
|---|
| 13 | ** |
|---|
| 14 | ** Created: 03/08/2001 |
|---|
| 15 | ** 02/01/2012 modified for A56 support |
|---|
| 16 | ** |
|---|
| 17 | ** REVISION: |
|---|
| 18 | ** |
|---|
| 19 | ** $Log: $ |
|---|
| 20 | ** |
|---|
| 21 | ** |
|---|
| 22 | ****************************************************************/ |
|---|
| 23 | #include "si.h" |
|---|
| 24 | #include "si_os.h" |
|---|
| 25 | #include "si_dbg.h" |
|---|
| 26 | #include "si_util.h" |
|---|
| 27 | #include "si_list.h" |
|---|
| 28 | #include "si_descriptors.h" |
|---|
| 29 | #include "si_transmission_medium.h" |
|---|
| 30 | |
|---|
| 31 | #include "si_ntm.h" |
|---|
| 32 | #include "si_ntm_snt.h" |
|---|
| 33 | |
|---|
| 34 | unsigned char NTM_SNT_version_number; |
|---|
| 35 | unsigned char NTM_SNT_last_section_number; |
|---|
| 36 | unsigned long NTM_SNT_section_mask[8]; |
|---|
| 37 | unsigned long NTM_SNT_Language_Code; |
|---|
| 38 | static SI_NTM_SNT_Callback_t *s_snt_cb = NULL; |
|---|
| 39 | |
|---|
| 40 | void SI_NTM_Init( |
|---|
| 41 | SI_NTM_SNT_Callback_t *cb, |
|---|
| 42 | unsigned char iNTM_SNT_version_number |
|---|
| 43 | ) |
|---|
| 44 | { |
|---|
| 45 | int i; |
|---|
| 46 | |
|---|
| 47 | s_snt_cb = cb; |
|---|
| 48 | SI_NTM_SNT_Init(s_snt_cb); |
|---|
| 49 | NTM_SNT_version_number = iNTM_SNT_version_number; |
|---|
| 50 | for (i=0; i<8; i++) |
|---|
| 51 | NTM_SNT_section_mask[i] = 0; |
|---|
| 52 | } |
|---|
| 53 | |
|---|
| 54 | /********************************************************************* |
|---|
| 55 | Function : SI_NTM_Get |
|---|
| 56 | Description : Return the version numbers and masks. |
|---|
| 57 | Input : none. |
|---|
| 58 | Output : version number and pointers to section masks. |
|---|
| 59 | **********************************************************************/ |
|---|
| 60 | bool SI_NTM_SNT_Complete(void) |
|---|
| 61 | { |
|---|
| 62 | return (SI_Chk_Section_complete(NTM_SNT_section_mask,NTM_SNT_last_section_number) == SI_SUCCESS); |
|---|
| 63 | } |
|---|
| 64 | |
|---|
| 65 | /********************************************************************* |
|---|
| 66 | Function : SI_NTM_parse |
|---|
| 67 | Description : Function to parse the NTM table. |
|---|
| 68 | Input : unsigned char * table: point to the current NTM table section. |
|---|
| 69 | Output : SI_RET_CODE. |
|---|
| 70 | **********************************************************************/ |
|---|
| 71 | SI_RET_CODE SI_NTM_parse (unsigned char * table) |
|---|
| 72 | { |
|---|
| 73 | unsigned long temp; |
|---|
| 74 | unsigned long section_length; |
|---|
| 75 | unsigned char table_type; |
|---|
| 76 | unsigned long desc_tag, len; |
|---|
| 77 | unsigned char version_number, section_number, last_section_number; |
|---|
| 78 | unsigned char *current, *crc_start; |
|---|
| 79 | int found_rdd; |
|---|
| 80 | |
|---|
| 81 | found_rdd = 0; |
|---|
| 82 | SI_DBG_PRINT(E_SI_DBG_MSG,("NTM Table received.\n")); |
|---|
| 83 | |
|---|
| 84 | temp = *table; |
|---|
| 85 | if (temp != SI_NTM_TABLE_ID) |
|---|
| 86 | { |
|---|
| 87 | SI_DBG_PRINT(E_SI_ERR_MSG,("NTM Table ID error!!! %x\n", temp)); |
|---|
| 88 | return SI_TABLE_ID_ERROR; |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | /* calculate and check section length. */ |
|---|
| 92 | section_length = SI_Construct_Data(table, |
|---|
| 93 | NTM_SECTION_LENGTH_BYTE_INDX, |
|---|
| 94 | NTM_SECTION_LENGTH_BYTE_NUM, |
|---|
| 95 | NTM_SECTION_LENGTH_SHIFT, |
|---|
| 96 | NTM_SECTION_LENGTH_MASK); |
|---|
| 97 | section_length += NTM_SECTION_LENGTH_BYTE_INDX+NTM_SECTION_LENGTH_BYTE_NUM; |
|---|
| 98 | if (section_length > SI_NORMAL_SECTION_LENGTH) |
|---|
| 99 | { |
|---|
| 100 | SI_DBG_PRINT(E_SI_ERR_MSG,("NTM Table section length error!!! %x\n", section_length)); |
|---|
| 101 | return SI_SECTION_LENGTH_ERROR; |
|---|
| 102 | } |
|---|
| 103 | |
|---|
| 104 | /* We do the CRC check here to verify the contents of this section. */ |
|---|
| 105 | if (SI_CRC32_Check(table, section_length) != SI_SUCCESS) |
|---|
| 106 | { |
|---|
| 107 | SI_DBG_PRINT(E_SI_ERR_MSG,("NTM Table section CRC error!!!\n")); |
|---|
| 108 | return SI_CRC_ERROR; |
|---|
| 109 | } |
|---|
| 110 | |
|---|
| 111 | /* check protocol version. It should be zero for now. */ |
|---|
| 112 | temp = SI_Construct_Data(table, |
|---|
| 113 | NTM_PROTOCOL_VERSION_BYTE_INDX, |
|---|
| 114 | NTM_PROTOCOL_VERSION_BYTE_NUM, |
|---|
| 115 | NTM_PROTOCOL_VERSION_SHIFT, |
|---|
| 116 | NTM_PROTOCOL_VERSION_MASK); |
|---|
| 117 | if (temp != SI_CURRENT_PROTOCOL_VERSION) |
|---|
| 118 | { |
|---|
| 119 | SI_DBG_PRINT(E_SI_ERR_MSG,("NTM Table PROTOCOL version error!!! %x\n", temp)); |
|---|
| 120 | return SI_PROTOCOL_VER_ERROR; |
|---|
| 121 | } |
|---|
| 122 | |
|---|
| 123 | /* currently just support cable */ |
|---|
| 124 | temp = SI_Construct_Data(table, |
|---|
| 125 | NTM_TRANSMISSION_MEDIUM_CODE_BYTE_INDX, |
|---|
| 126 | NTM_TRANSMISSION_MEDIUM_CODE_BYTE_NUM, |
|---|
| 127 | NTM_TRANSMISSION_MEDIUM_CODE_SHIFT, |
|---|
| 128 | NTM_TRANSMISSION_MEDIUM_CODE_MASK); |
|---|
| 129 | if (TRANSMISSION_MEDIUM_CABLE != temp) { |
|---|
| 130 | SI_DBG_PRINT(E_SI_ERR_MSG,("Unsupported transmission medium type %d\n", temp)); |
|---|
| 131 | return SI_NOT_SUPPORTED_ERROR; |
|---|
| 132 | } |
|---|
| 133 | |
|---|
| 134 | /* RLQ, TODO support MNT, RRT and RST? */ |
|---|
| 135 | table_type = SI_Construct_Data(table, |
|---|
| 136 | NTM_TABLE_TYPE_BYTE_INDX, |
|---|
| 137 | NTM_TABLE_TYPE_BYTE_NUM, |
|---|
| 138 | NTM_TABLE_TYPE_SHIFT, |
|---|
| 139 | NTM_TABLE_TYPE_MASK); |
|---|
| 140 | if (table_type != NTM_TT_SNT) |
|---|
| 141 | { |
|---|
| 142 | #ifdef USE_SCTE65_SI |
|---|
| 143 | /* SCTE65 use different table type for SNT */ |
|---|
| 144 | if (6 != table_type) |
|---|
| 145 | #endif |
|---|
| 146 | { |
|---|
| 147 | SI_DBG_PRINT(E_SI_ERR_MSG,("We can only handle SNT of NTM right now.\n")); |
|---|
| 148 | return SI_TABLE_TYPE_ERROR; |
|---|
| 149 | } |
|---|
| 150 | } |
|---|
| 151 | |
|---|
| 152 | /* we get a SNT record. see if we have any table level |
|---|
| 153 | descriptors for revision dectection. */ |
|---|
| 154 | current = table + NTM_TABLE_TYPE_BYTE_INDX + NTM_TABLE_TYPE_BYTE_NUM; |
|---|
| 155 | |
|---|
| 156 | /* point to the start of table level descriptor. */ |
|---|
| 157 | current = SI_NTM_SNT_Pointer(current); |
|---|
| 158 | crc_start = table + section_length - SI_CRC_LENGTH; |
|---|
| 159 | |
|---|
| 160 | SI_DBG_PRINT(E_SI_ERR_MSG,("table %x, current %x, crc_start %x\n", table, current, crc_start)); |
|---|
| 161 | /* go through all descriptors. */ |
|---|
| 162 | while ((unsigned long)current < (unsigned long)crc_start) |
|---|
| 163 | { |
|---|
| 164 | desc_tag = *(current++); |
|---|
| 165 | len = *(current++); |
|---|
| 166 | switch(desc_tag) |
|---|
| 167 | { |
|---|
| 168 | case SI_DESC_REVISION_DETECTION: |
|---|
| 169 | /* we got a revision dectection descriptor. */ |
|---|
| 170 | found_rdd = 1; |
|---|
| 171 | SI_DBG_PRINT(E_SI_DBG_MSG,("NTM SNT revision detection descriptors found.\n")); |
|---|
| 172 | version_number = SI_Construct_Data( current, |
|---|
| 173 | DESC_REV_DECTECT_VER_NUM_BYTE_INDEX, |
|---|
| 174 | DESC_REV_DECTECT_VER_NUM_BYTE_NUM, |
|---|
| 175 | DESC_REV_DECTECT_VER_NUM_SHIFT, |
|---|
| 176 | DESC_REV_DECTECT_VER_NUM_MASK); |
|---|
| 177 | section_number = SI_Construct_Data( current, |
|---|
| 178 | DESC_REV_DECTECT_SEC_NUM_BYTE_INDEX, |
|---|
| 179 | DESC_REV_DECTECT_SEC_NUM_BYTE_NUM, |
|---|
| 180 | DESC_REV_DECTECT_SEC_NUM_SHIFT, |
|---|
| 181 | DESC_REV_DECTECT_SEC_NUM_MASK); |
|---|
| 182 | last_section_number = SI_Construct_Data( current, |
|---|
| 183 | DESC_REV_DECTECT_LAST_SEC_NUM_BYTE_INDEX, |
|---|
| 184 | DESC_REV_DECTECT_LAST_SEC_NUM_BYTE_NUM, |
|---|
| 185 | DESC_REV_DECTECT_LAST_SEC_NUM_SHIFT, |
|---|
| 186 | DESC_REV_DECTECT_LAST_SEC_NUM_MASK); |
|---|
| 187 | NTM_SNT_last_section_number = last_section_number; |
|---|
| 188 | if (version_number == NTM_SNT_version_number) |
|---|
| 189 | { |
|---|
| 190 | /* same version number, check section mask. */ |
|---|
| 191 | if (SI_Chk_Section_mask(NTM_SNT_section_mask, section_number)) |
|---|
| 192 | return SI_SUCCESS; /* no need to update. */ |
|---|
| 193 | } |
|---|
| 194 | else |
|---|
| 195 | { |
|---|
| 196 | /* different CDS version, init the CDS table and section mask .*/ |
|---|
| 197 | SI_NTM_SNT_Free_List(); |
|---|
| 198 | NTM_SNT_version_number = version_number; |
|---|
| 199 | SI_Init_Section_Mask(NTM_SNT_section_mask, last_section_number); |
|---|
| 200 | } |
|---|
| 201 | /* update the mask */ |
|---|
| 202 | SI_Set_Section_mask(NTM_SNT_section_mask, section_number); |
|---|
| 203 | break; |
|---|
| 204 | |
|---|
| 205 | default: |
|---|
| 206 | SI_DBG_PRINT(E_SI_WRN_MSG,("NTM SNT table descriptor %x received! Ignoring!\n", desc_tag)); |
|---|
| 207 | break; |
|---|
| 208 | } |
|---|
| 209 | |
|---|
| 210 | /* update pointer. */ |
|---|
| 211 | current += len; |
|---|
| 212 | } |
|---|
| 213 | |
|---|
| 214 | /* check for desc length. */ |
|---|
| 215 | if ((unsigned long)current != (unsigned long)crc_start) |
|---|
| 216 | { |
|---|
| 217 | SI_DBG_PRINT(E_SI_ERR_MSG,("NTM Table length error!!!\n")); |
|---|
| 218 | return SI_SECTION_LENGTH_ERROR; |
|---|
| 219 | } |
|---|
| 220 | |
|---|
| 221 | if (found_rdd == 0) |
|---|
| 222 | { |
|---|
| 223 | #ifdef CONFIG_RDD_REQUIRED |
|---|
| 224 | SI_DBG_PRINT(E_SI_ERR_MSG,("Revistion Detection Descriptor is required!!!\n")); |
|---|
| 225 | return SI_DESCRIPTOR_ERROR; |
|---|
| 226 | #else |
|---|
| 227 | /* if there is no version descriptor, set complete flag then */ |
|---|
| 228 | NTM_SNT_last_section_number = 0; |
|---|
| 229 | SI_Set_Section_mask(NTM_SNT_section_mask, 0); |
|---|
| 230 | #endif |
|---|
| 231 | } |
|---|
| 232 | |
|---|
| 233 | /* we either need to update the channel table or we don't have a revision detection. */ |
|---|
| 234 | NTM_SNT_Language_Code = SI_Construct_Data(table, |
|---|
| 235 | NTM_ISO_639_CODE_BYTE_INDX, |
|---|
| 236 | NTM_ISO_639_CODE_BYTE_NUM, |
|---|
| 237 | NTM_ISO_639_CODE_SHIFT, |
|---|
| 238 | NTM_ISO_639_CODE_MASK); |
|---|
| 239 | |
|---|
| 240 | current = table + NTM_TABLE_TYPE_BYTE_INDX + NTM_TABLE_TYPE_BYTE_NUM; |
|---|
| 241 | return SI_NTM_SNT_Parse(current,NTM_SNT_Language_Code); |
|---|
| 242 | } |
|---|
| 243 | |
|---|