/*************************************************************************** * Copyright (c) 2003-2008, Broadcom Corporation * All Rights Reserved * Confidential Property of Broadcom Corporation * * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. * * $brcm_Workfile: $ * $brcm_Revision: $ * $brcm_Date: $ * * Module Description: cvt processing module * * Revision History: * * $brcm_Log: $ * * ***************************************************************************/ #include "bstd.h" #include "bdbg.h" #include "dsmcc.h" #include "bapp_util.h" BDBG_MODULE(dsmcc); #define CODE_VERSION_TABLE2_TAG 0x9f9c05 #define CODE_VERSION_TABLE1_TAG 0x9f9c02 #define D_VENDOR_ID 0x345678 #define D_HARDWARE_VERSION_ID 0x00550055 int cvt_parse(void * c, size_t msg_size, struct cvt_info_t * cvt) { int res; int i, j; size_t cvt_lenght; size_t cvt_tag; int cvt_type; size_t num_descr; size_t descr_tag; size_t descr_len; size_t download_type_command; uint8_t number_of_cv_certificates; struct bit_state_t bs; bs.data = (unsigned char*)c; bs.bindex = 0; if(0xD9 != get_bits(8, &bs)){ res = 1; goto ExitFunc; } get_bits(4, &bs); cvt_lenght = get_bits(12, &bs); cvt_tag = get_bits_aligned(24, &bs); switch(cvt_tag){ case CODE_VERSION_TABLE1_TAG: cvt_type = 1; break; case CODE_VERSION_TABLE2_TAG: cvt_type = 2; break; default: res = 2; goto ExitFunc; } /* skip length_field */ if(0 == get_bits(1, &bs)){ get_bits(7, &bs); }else{ i = get_bits(7, &bs); while(0 != i--){ get_bits(8, &bs); } } if(2 == cvt_type){ cvt->protocol_version = get_bits(8, &bs); cvt->configuration_count_change = get_bits(8, &bs); } num_descr = get_bits(8, &bs); for(i = 0; i < num_descr; i++){ descr_tag = get_bits(8, &bs); switch(descr_tag){ case 0x0: /* vendor id */ descr_len = get_bits(8, &bs); if(3 != descr_len){ res = 4; goto ExitFunc; } cvt->vendor_id = get_bits_aligned(24, &bs); break; case 0x1: /* hardware version id */ descr_len = get_bits(8, &bs); if(4 != descr_len){ res = 4; goto ExitFunc; } cvt->hardware_version_id = get_bits_aligned(32, &bs); break; default: /* consume unknown descriptor */ descr_len = get_bits(8, &bs); for(j = descr_len; j > 0; j--){ get_bits(8, &bs); } } } download_type_command = get_bits(8, &bs); if(download_type_command > 1){ /* 0 = immediate, 1 = deferred */ res = 6; goto ExitFunc; } if(2 == cvt_type){ cvt->location_type = get_bits(8, &bs); switch(cvt->location_type){ case 0: cvt->source_ID = get_bits(16, &bs); break; case 1: cvt->frequency_vector = get_bits(16, &bs); cvt->modulation_type = get_bits(8, &bs); get_bits(3, &bs); cvt->pid = get_bits(13, &bs); break; case 2: cvt->frequency_vector = get_bits(16, &bs); cvt->modulation_type = get_bits(8, &bs); cvt->program_number = get_bits(16, &bs); break; default: res = 7; goto ExitFunc; } }else{ cvt->location_type = 1; cvt->frequency_vector = get_bits(16, &bs); cvt->modulation_type = get_bits(8, &bs); get_bits(3, &bs); cvt->pid = get_bits(13, &bs); } cvt->code_file_name_length = get_bits(8, &bs); for(i = 0 ; i < cvt->code_file_name_length; i++){ cvt->code_file_name[i] = get_bits(8, &bs); } if(2 == cvt_type){ number_of_cv_certificates = get_bits(8, &bs); if(0 != number_of_cv_certificates){ res = 8; goto ExitFunc; } } res = 0; ExitFunc: return res; } int dsmcc_dii_parse(void * data, size_t msg_size, struct dii_info_t * dii) { struct bit_state_t bs; uint8_t table_id; uint16_t section_length; uint16_t compatibility_descriptor_length; int res; bs.data = (unsigned char *)data; bs.bindex = 0; table_id = get_bits(8, &bs); get_bits(4, &bs); section_length = get_bits(12, &bs); get_bits(16, &bs); /* table_id_extension */ get_bits(2, &bs); if(0 != get_bits(5, &bs)){ res = 1; goto ExitFunc; } get_bits(1, &bs); /* current_next_indicator */ if(0 != get_bits(8, &bs)){ /* section_number */ res = 2; goto ExitFunc; } if(0 != get_bits(8, &bs)){ /* last_section_number */ res = 2; goto ExitFunc; } if(0x11 != get_bits(8, &bs)){ /* protocolDiscriminator */ res = 3; goto ExitFunc; } if(0x03 != get_bits(8, &bs)){ /* DsmccType */ res = 4; goto ExitFunc; } if(0x1002 != get_bits(16, &bs)){ /* MessageId */ res = 5; goto ExitFunc; } dii->transaction_id = get_bits_aligned(32, &bs); get_bits(8, &bs); if(0 != get_bits(8, &bs)){ /* adaptationLength */ res = 8; goto ExitFunc; } dii->message_length = get_bits(16, &bs); dii->download_id = get_bits_aligned(32, &bs); dii->block_size = get_bits(16, &bs); get_bits(8, &bs); /* windowSize */ get_bits(8, &bs); /* ackPeriod */ get_bits_aligned(32, &bs); /* tCDownloadWindow */ dii->download_scenario = get_bits_aligned(32, &bs); /* skip compatibilityDescriptor */ compatibility_descriptor_length = get_bits(16, &bs); bs.bindex = bs.bindex + (compatibility_descriptor_length * 8); dii->number_of_modules = get_bits(16, &bs); dii->bs.bindex = bs.bindex; dii->bs.data = bs.data; res = 0; ExitFunc: return res; } int dsmcc_dii_next_module(struct dii_info_t * dii, struct dii_module_t * diim) { struct bit_state_t bs; int i; int res; bs.data = dii->bs.data; bs.bindex = dii->bs.bindex; diim->module_id = get_bits(16, &bs); diim->module_size = get_bits_aligned(32, &bs); diim->module_version = get_bits(8, &bs); diim->module_info_length = get_bits(8, &bs); for(i = 0; i < diim->module_info_length; i++){ diim->module_info_byte[i] = get_bits(8, &bs); } dii->bs.bindex = bs.bindex; dii->bs.data = bs.data; res = 0; return res; } int dsmcc_ddb_parse(void * data, size_t msg_length, struct ddb_info_t * ddb) { struct bit_state_t bs; uint8_t table_id; uint16_t section_length; uint8_t version_number; uint8_t section_number; uint8_t last_section_number; int res; bs.data = (unsigned char *)data; bs.bindex = 0; table_id = get_bits(8, &bs); get_bits(4, &bs); section_length = get_bits(12, &bs); get_bits(16, &bs); /* table_id_extension */ get_bits(2, &bs); version_number = get_bits(5, &bs); get_bits(1, &bs); /* current_next_indicator */ section_number = get_bits(8, &bs); last_section_number = get_bits(8, &bs); if(0x11 != get_bits(8, &bs)){ /* ProtocolDiscriminator */ res = 4; goto ExitFunc; } if(0x03 != get_bits(8, &bs)){ /* DsmccType */ res = 5; goto ExitFunc; } if(0x1003 != get_bits(16, &bs)){ /* MessageId */ res = 6; goto ExitFunc; } ddb->download_id = get_bits_aligned(32, &bs); get_bits(8, &bs); /* reserved */ if(0 != get_bits(8, &bs)){ /* AdaptationLength */ res = 7; goto ExitFunc; } ddb->message_length = get_bits(16, &bs); /* DownloadDataBlock starts here */ ddb->module_id = get_bits(16, &bs); ddb->module_version = get_bits(8, &bs); get_bits(8, &bs); /* reserved */ ddb->block_number = get_bits(16, &bs); if(section_number != (ddb->block_number & 0xFF)){ res = 8; goto ExitFunc; } ddb->data_length = ddb->message_length - 6; ddb->data_bytes = data + (bs.bindex >> 3); res = 0; ExitFunc: return res; }