| 1 | /*************************************************************** |
|---|
| 2 | ** |
|---|
| 3 | ** Broadcom Corp. Confidential |
|---|
| 4 | ** Copyright 2003-2008 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_ntt.c |
|---|
| 12 | ** Description: function that parses the NTT table sections. |
|---|
| 13 | ** |
|---|
| 14 | ** Created: 03/08/2001 |
|---|
| 15 | ** |
|---|
| 16 | ** REVISION: |
|---|
| 17 | ** |
|---|
| 18 | ** $Log: $ |
|---|
| 19 | ** |
|---|
| 20 | ** |
|---|
| 21 | ****************************************************************/ |
|---|
| 22 | #include "si.h" |
|---|
| 23 | #include "si_os.h" |
|---|
| 24 | #include "si_dbg.h" |
|---|
| 25 | #include "si_util.h" |
|---|
| 26 | #include "si_list.h" |
|---|
| 27 | #include "si_ntt_sns.h" |
|---|
| 28 | #include "si_ntt.h" |
|---|
| 29 | #include "si_descriptors.h" |
|---|
| 30 | |
|---|
| 31 | |
|---|
| 32 | unsigned char NTT_SNS_version_number; |
|---|
| 33 | unsigned char NTT_SNS_last_section_number; |
|---|
| 34 | unsigned long NTT_SNS_section_mask[8]; |
|---|
| 35 | unsigned long NTT_SNS_Language_Code; |
|---|
| 36 | static SI_NTT_SNS_Callback_t *s_sns_cb = NULL; |
|---|
| 37 | void SI_NTT_Init(SI_NTT_SNS_Callback_t *cb, unsigned char iNTT_SNS_version_number) |
|---|
| 38 | { |
|---|
| 39 | unsigned long i; |
|---|
| 40 | s_sns_cb = cb; |
|---|
| 41 | SI_NTT_SNS_Init(s_sns_cb); |
|---|
| 42 | NTT_SNS_version_number = iNTT_SNS_version_number; |
|---|
| 43 | for (i=0; i<8; i++) |
|---|
| 44 | NTT_SNS_section_mask[i] = 0; |
|---|
| 45 | } |
|---|
| 46 | |
|---|
| 47 | /********************************************************************* |
|---|
| 48 | Function : SI_NTT_Get |
|---|
| 49 | Description : Return the version numbers and masks. |
|---|
| 50 | Input : none. |
|---|
| 51 | Output : version number and pointers to section masks. |
|---|
| 52 | **********************************************************************/ |
|---|
| 53 | bool SI_NTT_SNS_Complete(void) |
|---|
| 54 | { |
|---|
| 55 | return (SI_Chk_Section_complete(NTT_SNS_section_mask,NTT_SNS_last_section_number) == SI_SUCCESS); |
|---|
| 56 | } |
|---|
| 57 | |
|---|
| 58 | /********************************************************************* |
|---|
| 59 | Function : SI_NTT_parse |
|---|
| 60 | Description : Function to parse the NTT table. |
|---|
| 61 | Input : unsigned char * table: point to the current NTT table section. |
|---|
| 62 | Output : SI_RET_CODE. |
|---|
| 63 | **********************************************************************/ |
|---|
| 64 | SI_RET_CODE SI_NTT_parse (unsigned char * table) |
|---|
| 65 | { |
|---|
| 66 | unsigned long temp; |
|---|
| 67 | unsigned long section_length; |
|---|
| 68 | unsigned char table_subtype; |
|---|
| 69 | unsigned long desc_tag, len; |
|---|
| 70 | unsigned char version_number, section_number, last_section_number; |
|---|
| 71 | unsigned char *current, *crc_start; |
|---|
| 72 | int found_rdd; |
|---|
| 73 | /* unsigned long desc_len; |
|---|
| 74 | int i, j; */ |
|---|
| 75 | |
|---|
| 76 | found_rdd = 0; |
|---|
| 77 | SI_DBG_PRINT(E_SI_DBG_MSG,("NTT Table received.\n")); |
|---|
| 78 | |
|---|
| 79 | temp = *table; |
|---|
| 80 | if (temp != SI_NTT_TABLE_ID) |
|---|
| 81 | { |
|---|
| 82 | SI_DBG_PRINT(E_SI_ERR_MSG,("NTT Table ID error!!! %x\n", temp)); |
|---|
| 83 | return SI_TABLE_ID_ERROR; |
|---|
| 84 | } |
|---|
| 85 | |
|---|
| 86 | /* calculate and check section length. */ |
|---|
| 87 | section_length = SI_Construct_Data(table, |
|---|
| 88 | NTT_SECTION_LENGTH_BYTE_INDX, |
|---|
| 89 | NTT_SECTION_LENGTH_BYTE_NUM, |
|---|
| 90 | NTT_SECTION_LENGTH_SHIFT, |
|---|
| 91 | NTT_SECTION_LENGTH_MASK); |
|---|
| 92 | section_length += NTT_SECTION_LENGTH_BYTE_INDX+NTT_SECTION_LENGTH_BYTE_NUM; |
|---|
| 93 | if (section_length > SI_NORMAL_SECTION_LENGTH) |
|---|
| 94 | { |
|---|
| 95 | SI_DBG_PRINT(E_SI_ERR_MSG,("NTT Table section length error!!! %x\n", section_length)); |
|---|
| 96 | return SI_SECTION_LENGTH_ERROR; |
|---|
| 97 | } |
|---|
| 98 | |
|---|
| 99 | /* We do the CRC check here to verify the contents of this section. */ |
|---|
| 100 | if (SI_CRC32_Check(table, section_length) != SI_SUCCESS) |
|---|
| 101 | { |
|---|
| 102 | SI_DBG_PRINT(E_SI_ERR_MSG,("NTT Table section CRC error!!!\n")); |
|---|
| 103 | return SI_CRC_ERROR; |
|---|
| 104 | } |
|---|
| 105 | |
|---|
| 106 | /* check protocol version. It should be zero for now. */ |
|---|
| 107 | temp = SI_Construct_Data(table, |
|---|
| 108 | NTT_PROTOCOL_VERSION_BYTE_INDX, |
|---|
| 109 | NTT_PROTOCOL_VERSION_BYTE_NUM, |
|---|
| 110 | NTT_PROTOCOL_VERSION_SHIFT, |
|---|
| 111 | NTT_PROTOCOL_VERSION_MASK); |
|---|
| 112 | if (temp != SI_CURRENT_PROTOCOL_VERSION) |
|---|
| 113 | { |
|---|
| 114 | SI_DBG_PRINT(E_SI_ERR_MSG,("NTT Table PROTOCOL version error!!! %x\n", temp)); |
|---|
| 115 | return SI_PROTOCOL_VER_ERROR; |
|---|
| 116 | } |
|---|
| 117 | |
|---|
| 118 | /* we just need to handle SNS. Ignore others now. */ |
|---|
| 119 | table_subtype = SI_Construct_Data(table, |
|---|
| 120 | NTT_TABLE_SUBTYPE_BYTE_INDX, |
|---|
| 121 | NTT_TABLE_SUBTYPE_BYTE_NUM, |
|---|
| 122 | NTT_TABLE_SUBTYPE_SHIFT, |
|---|
| 123 | NTT_TABLE_SUBTYPE_MASK); |
|---|
| 124 | if (table_subtype != NTT_SNS_SUBTYPE) |
|---|
| 125 | { |
|---|
| 126 | SI_DBG_PRINT(E_SI_ERR_MSG,("We can only handle SNS of NTT right now.\n")); |
|---|
| 127 | return SI_TABLE_ID_ERROR; |
|---|
| 128 | } |
|---|
| 129 | |
|---|
| 130 | /* we get a SNS record. see if we have any table level |
|---|
| 131 | descriptors for revision dectection. */ |
|---|
| 132 | current = table + NTT_TABLE_SUBTYPE_BYTE_INDX + NTT_TABLE_SUBTYPE_BYTE_NUM; |
|---|
| 133 | |
|---|
| 134 | /* point to the start of table level descriptor. */ |
|---|
| 135 | current = SI_NTT_SNS_Pointer(current); |
|---|
| 136 | crc_start = table + section_length - SI_CRC_LENGTH; |
|---|
| 137 | |
|---|
| 138 | SI_DBG_PRINT(E_SI_ERR_MSG,("table %x, current %x, crc_start %x\n", table, current, crc_start)); |
|---|
| 139 | /* go through all descriptors. */ |
|---|
| 140 | while ((unsigned long)current < (unsigned long)crc_start) |
|---|
| 141 | { |
|---|
| 142 | desc_tag = *(current++); |
|---|
| 143 | len = *(current++); |
|---|
| 144 | switch(desc_tag) |
|---|
| 145 | { |
|---|
| 146 | case SI_DESC_REVISION_DETECTION: |
|---|
| 147 | /* we got a revision dectection descriptor. */ |
|---|
| 148 | found_rdd = 1; |
|---|
| 149 | SI_DBG_PRINT(E_SI_DBG_MSG,("NTT SNS revision detection descriptors found.\n")); |
|---|
| 150 | version_number = SI_Construct_Data( current, |
|---|
| 151 | DESC_REV_DECTECT_VER_NUM_BYTE_INDEX, |
|---|
| 152 | DESC_REV_DECTECT_VER_NUM_BYTE_NUM, |
|---|
| 153 | DESC_REV_DECTECT_VER_NUM_SHIFT, |
|---|
| 154 | DESC_REV_DECTECT_VER_NUM_MASK); |
|---|
| 155 | section_number = SI_Construct_Data( current, |
|---|
| 156 | DESC_REV_DECTECT_SEC_NUM_BYTE_INDEX, |
|---|
| 157 | DESC_REV_DECTECT_SEC_NUM_BYTE_NUM, |
|---|
| 158 | DESC_REV_DECTECT_SEC_NUM_SHIFT, |
|---|
| 159 | DESC_REV_DECTECT_SEC_NUM_MASK); |
|---|
| 160 | last_section_number = SI_Construct_Data( current, |
|---|
| 161 | DESC_REV_DECTECT_LAST_SEC_NUM_BYTE_INDEX, |
|---|
| 162 | DESC_REV_DECTECT_LAST_SEC_NUM_BYTE_NUM, |
|---|
| 163 | DESC_REV_DECTECT_LAST_SEC_NUM_SHIFT, |
|---|
| 164 | DESC_REV_DECTECT_LAST_SEC_NUM_MASK); |
|---|
| 165 | NTT_SNS_last_section_number = last_section_number; |
|---|
| 166 | if (version_number == NTT_SNS_version_number) |
|---|
| 167 | { |
|---|
| 168 | /* same version number, check section mask. */ |
|---|
| 169 | if (SI_Chk_Section_mask(NTT_SNS_section_mask, section_number)) |
|---|
| 170 | return SI_SUCCESS; /* no need to update. */ |
|---|
| 171 | } |
|---|
| 172 | else |
|---|
| 173 | { |
|---|
| 174 | /* different CDS version, init the CDS table and section mask .*/ |
|---|
| 175 | SI_NTT_SNS_Free_List(); |
|---|
| 176 | NTT_SNS_version_number = version_number; |
|---|
| 177 | SI_Init_Section_Mask(NTT_SNS_section_mask, last_section_number); |
|---|
| 178 | } |
|---|
| 179 | /* update the mask */ |
|---|
| 180 | SI_Set_Section_mask(NTT_SNS_section_mask, section_number); |
|---|
| 181 | break; |
|---|
| 182 | |
|---|
| 183 | default: |
|---|
| 184 | SI_DBG_PRINT(E_SI_WRN_MSG,("NTT SNS table descriptor %x received! Ignoring!\n", desc_tag)); |
|---|
| 185 | break; |
|---|
| 186 | } |
|---|
| 187 | |
|---|
| 188 | /* update pointer. */ |
|---|
| 189 | current += len; |
|---|
| 190 | } |
|---|
| 191 | |
|---|
| 192 | /* check for desc length. */ |
|---|
| 193 | if ((unsigned long)current != (unsigned long)crc_start) |
|---|
| 194 | { |
|---|
| 195 | SI_DBG_PRINT(E_SI_ERR_MSG,("NTT Table length error!!!\n")); |
|---|
| 196 | return SI_SECTION_LENGTH_ERROR; |
|---|
| 197 | } |
|---|
| 198 | |
|---|
| 199 | #ifdef CONFIG_RDD_REQUIRED |
|---|
| 200 | if (found_rdd == 0) |
|---|
| 201 | { |
|---|
| 202 | SI_DBG_PRINT(E_SI_ERR_MSG,("Revistion Detection Descriptor is required!!!\n")); |
|---|
| 203 | return SI_DESCRIPTOR_ERROR; |
|---|
| 204 | } |
|---|
| 205 | #endif |
|---|
| 206 | |
|---|
| 207 | /* we either need to update the channel table or we don't have a revision detection. */ |
|---|
| 208 | NTT_SNS_Language_Code = SI_Construct_Data(table, |
|---|
| 209 | NTT_ISO_639_CODE_BYTE_INDX, |
|---|
| 210 | NTT_ISO_639_CODE_BYTE_NUM, |
|---|
| 211 | NTT_ISO_639_CODE_SHIFT, |
|---|
| 212 | NTT_ISO_639_CODE_MASK); |
|---|
| 213 | |
|---|
| 214 | current = table + NTT_TABLE_SUBTYPE_BYTE_INDX + NTT_TABLE_SUBTYPE_BYTE_NUM; |
|---|
| 215 | return SI_NTT_SNS_Parse(current,NTT_SNS_Language_Code); |
|---|
| 216 | } |
|---|
| 217 | |
|---|