int read_header(ch16_header* header, uint32_t size, uint8_t* data) { if(header->magic != 0x36314843) { fprintf(stderr,"Invalid magic number\n"); fprintf(stderr,"Found: 0x%x, Expected: 0x%x\n", header->magic, 0x36314843); return 0; } if(header->reserved != 0) { fprintf(stderr,"Reserved not 0\n"); return 0; } if(header->rom_size != size - sizeof(ch16_header)) { fprintf(stderr,"Incorrect size reported\n"); fprintf(stderr,"Found: 0x%x, Expected: 0x%x\n", header->rom_size, (uint32_t)(size - sizeof(ch16_header))); return 0; } crc_t crc = crc_init(); crc = crc_update(crc,data,size-sizeof(ch16_header)); crc = crc_finalize(crc); if(header->crc32_sum != crc) { fprintf(stderr,"Incorrect CRC32 checksum\n"); fprintf(stderr,"Found: 0x%x, Expected: 0x%x\n", header->crc32_sum, crc); return 0; } return 1; }
SDC_ERRORCode sdc_check_message(FIL* df, DWORD ofs) { SDC_ERRORCode sdc_ret; DWORD saved_ofs = sdc_fp_index; crc_t crcd, crcd_calc; uint8_t rd[sizeof(GENERIC_message)]; unsigned int bytes_read; sdc_ret = sdc_set_fp_index(df, ofs) ; if(sdc_ret != SDC_OK) { return sdc_ret; } sdc_ret = sdc_f_read(df, rd, sizeof(GENERIC_message), &bytes_read); if(sdc_ret != SDC_OK) { return sdc_ret; } sdc_ret = sdc_f_read(df, &crcd, sizeof(crc_t), &bytes_read); if(sdc_ret != SDC_OK) { return sdc_ret; } // calc checksum crcd_calc = crc_init(); crcd_calc = crc_update(crcd_calc, (const unsigned char*) &rd, sizeof(GENERIC_message)); crcd_calc = crc_finalize(crcd_calc); if(crcd != crcd_calc) { SDCDEBUG("%s: No valid checksum in data. Data: %u\tvs.\tCalc: %u\r\n", __func__, crcd, crcd_calc); sdc_ret = sdc_set_fp_index(df, saved_ofs) ; if(sdc_ret != SDC_OK) { return sdc_ret; } return SDC_CHECKSUM_ERROR; } sdc_ret = sdc_set_fp_index(df, saved_ofs) ; if(sdc_ret != SDC_OK) { return sdc_ret; } return SDC_OK; }
crc_t ChecksummedPacket::computeChecksum() const { crc_t c = crc_init(); c = crc_update(c, reinterpret_cast<const unsigned char *>(&packet), sizeof(Packet)); c = crc_update(c, reinterpret_cast<const unsigned char *>(&order), sizeof(uint64_t)); c = crc_finalize(c); return c; }
int recieveint_rs485(int *value) { totalBytesRead += ecrobot_read_rs485(raw, totalBytesRead, (INT_SIZE+1) - totalBytesRead); if (totalBytesRead != (INT_SIZE+1)) return 0; crc_t crcRecieved = (crc_t)raw[0]; U8 rawInt[INT_SIZE]; rawInt[0] = raw[1]; rawInt[1] = raw[2]; rawInt[2] = raw[3]; rawInt[3] = raw[4]; crc_t crc; crc = crc_init(); crc = crc_update(crc, (unsigned char *)rawInt, INT_SIZE); crc = crc_finalize(crc); if (crc != crcRecieved) { print_str(0,0,"CRC errors = "); display_int(++crc_errors, 0); display_update(); //We reboot the network interface ecrobot_term_rs485(); ecrobot_init_rs485(NETWORK_SPEED); totalBytesRead = 0; return 0; } // We convert the raw bytes to an int *value = 0; for (int i = INT_SIZE-1; i > -1 ; i--) { int temp = 0; temp += rawInt[i]; temp <<= (8 * i); *value += temp; } totalBytesRead = 0; // print_clear_line(5); // display_update(); // display_goto_xy(0,5); // display_int(*value, 0); // display_update(); return 1; }
/** * Read current packet from current file. Pad the packet with PAD_CHAR if the * file has less than PACKET_SIZE bytes left to read. * * @return the number of bytes read from the file */ size_t Xmodem::readPacket() { size_t bytesRead = fileRead(_packet, PACKET_SIZE); for (size_t i = bytesRead; i < PACKET_SIZE; i++) { _packet[i] = PAD_CHAR; } _crc = crc_init(); _crc = crc_update(_crc, _packet, PACKET_SIZE); _crc = crc_finalize(_crc); return bytesRead; }
void build_header(ch16_header* header, uint8_t spec_ver, uint32_t rom_size, uint16_t start_addr, uint8_t* data) { if(header == NULL) { fprintf(stderr,"Null pointer exception ***(build_header)"); exit(1); } // Magic number 'CH16' header->magic = 0x36314843; // Reserved, always 0 header->reserved = 0x00; // Spec version header->spec_ver = spec_ver; // Rom size header->rom_size = rom_size; // Start address header->start_addr = start_addr; // Calculate CRC crc_t crc = crc_init(); crc = crc_update(crc,data,rom_size); crc = crc_finalize(crc); header->crc32_sum = crc; }
//Build a string and check its CRC with a predefined value. //The string will go through ascii characters 32-126, which are typable on the keyboard //Once every possibility has been used, the string expands in size (by shifting the null character over) int main(void) { char str[100]; time_t t0, t1; crc_t crc; int i, j, k, l; double timediff; t0 = time(0); for(i=1; i<100; i++) { str[i] = '\0'; for(j=0; j<i; j++) { str[j] = 32; } while((unsigned char)str[i-1] <= 127) { //check, increment any thats above the ascii table for(j=0;j<i-1;j++) { if((unsigned char)str[j] >= 127) { str[j] = 32; str[j+1] = str[j+1] + 1; } } crc = crc_init(); crc = crc_update(crc, (unsigned char *)str, i); crc = crc_finalize(crc); if((unsigned long) 0xe6e5c283 == crc) { //CRC('123456789') = 0xcbf43926, CRC('b6e98880913adcb24108621903b25f76') = 0xe6e5c283, put in the one you are looking for t1 = time(0); timediff = difftime(t1,t0); printf("time = %f seconds, string = %s value = 0x%lx\n", timediff, str, (unsigned long)crc); system("PAUSE"); return; } str[0] = str[0] + 1; } } system("PAUSE"); return 0; }
void send_buffered_ints_rs485() { if (buffer_count_elements(&sendBuffer) > 0) { struct Candy* candy = buffer_dequeue(&sendBuffer); // We convert the int to an array of 4 bytes int value = candy->rpmTicksStamp; U8 buffer[INT_SIZE]; buffer[0] = (U8)value; value >>= 8; buffer[1] = (U8)value; value >>= 8; buffer[2] = (U8)value; value >>= 8; buffer[3] = (U8)value; // We calculate the checksum for the 4 bytes crc_t crc; crc = crc_init(); crc = crc_update(crc, (unsigned char *)buffer, INT_SIZE); crc = crc_finalize(crc); // We pack all the bytes in one array and sends it U8 toSend[INT_SIZE + 1]; toSend[0] = (U8)crc; toSend[1] = buffer[0]; toSend[2] = buffer[1]; toSend[3] = buffer[2]; toSend[4] = buffer[3]; ecrobot_send_rs485(toSend, 0, INT_SIZE+1); } }
int conditional_access_section_read(conditional_access_section_t *cas, uint8_t *buf, size_t buf_len, uint32_t payload_unit_start_indicator, psi_table_buffer_t *catBuffer) { if (cas == NULL || buf == NULL) { SAFE_REPORT_TS_ERR(-1); return 0; } bs_t *b = NULL; if (!payload_unit_start_indicator && catBuffer->buffer == NULL) { // this TS packet is not start of table, and we have no cached table data LOG_WARN ("conditional_access_section_read: payload_unit_start_indicator not set and no cached data"); return 0; } if (payload_unit_start_indicator) { uint8_t payloadStartPtr = buf[0]; buf += (payloadStartPtr + 1); buf_len -= (payloadStartPtr + 1); LOG_DEBUG_ARGS ("conditional_access_section_read: payloadStartPtr = %d", payloadStartPtr); } // check for pat spanning multiple TS packets if (catBuffer->buffer != NULL) { LOG_DEBUG_ARGS ("conditional_access_section_read: catBuffer detected: catBufferAllocSz = %d, catBufferUsedSz = %d", catBuffer->bufferAllocSz, catBuffer->bufferUsedSz); size_t numBytesToCopy = buf_len; if (buf_len > (catBuffer->bufferAllocSz - catBuffer->bufferUsedSz)) { numBytesToCopy = catBuffer->bufferAllocSz - catBuffer->bufferUsedSz; } LOG_DEBUG_ARGS ("conditional_access_section_read: copying %d bytes to catBuffer", numBytesToCopy); memcpy (catBuffer->buffer + catBuffer->bufferUsedSz, buf, numBytesToCopy); catBuffer->bufferUsedSz += numBytesToCopy; if (catBuffer->bufferUsedSz < catBuffer->bufferAllocSz) { LOG_DEBUG ("conditional_access_section_read: catBuffer not yet full -- returning"); return 0; } b = bs_new(catBuffer->buffer, catBuffer->bufferUsedSz); } else { b = bs_new(buf, buf_len); } cas->table_id = bs_read_u8(b); if (cas->table_id != conditional_access_section) { LOG_ERROR_ARGS("Table ID in CAT is 0x%02X instead of expected 0x%02X", cas->table_id, conditional_access_section); reportAddErrorLogArgs("Table ID in CAT is 0x%02X instead of expected 0x%02X", cas->table_id, conditional_access_section); SAFE_REPORT_TS_ERR(-30); resetPSITableBuffer(catBuffer); bs_free (b); return 0; } // read byte 0 cas->section_syntax_indicator = bs_read_u1(b); if (!cas->section_syntax_indicator) { LOG_ERROR("section_syntax_indicator not set in CAT"); reportAddErrorLog("section_syntax_indicator not set in CAT"); SAFE_REPORT_TS_ERR(-31); resetPSITableBuffer(catBuffer); bs_free (b); return 0; } bs_skip_u(b, 3); // TODO read the zero bit, check it to be zero cas->section_length = bs_read_u(b, 12); if (cas->section_length > 1021) // max CAT length { LOG_ERROR_ARGS("CAT section length is 0x%02X, larger than maximum allowed 0x%02X", cas->section_length, MAX_SECTION_LEN); reportAddErrorLogArgs("CAT section length is 0x%02X, larger than maximum allowed 0x%02X", cas->section_length, MAX_SECTION_LEN); SAFE_REPORT_TS_ERR(-32); resetPSITableBuffer(catBuffer); bs_free (b); return 0; } if (cas->section_length > bs_bytes_left(b)) { LOG_DEBUG ("conditional_access_section_read: Detected section spans more than one TS packet -- allocating buffer"); if (catBuffer->buffer != NULL) { // should never get here LOG_ERROR ("conditional_access_section_read: unexpected catBufffer"); reportAddErrorLog ("conditional_access_section_read: unexpected catBufffer"); resetPSITableBuffer(catBuffer); } catBuffer->bufferAllocSz = cas->section_length + 3; catBuffer->buffer = (uint8_t *)calloc (cas->section_length + 3, 1); memcpy (catBuffer->buffer, buf, buf_len); catBuffer->bufferUsedSz = buf_len; bs_free (b); return 0; } // read bytes 1-2 bs_read_u16(b); // read bytes 3,4 bs_skip_u(b, 2); cas->version_number = bs_read_u(b, 5); cas->current_next_indicator = bs_read_u1(b); if (!cas->current_next_indicator) LOG_WARN("This CAT is not yet applicable/n"); // read byte 5 cas->section_number = bs_read_u8(b); cas->last_section_number = bs_read_u8(b); if (cas->section_number != 0 || cas->last_section_number != 0) LOG_WARN("Multi-section CAT is not supported yet/n"); // read bytes 6,7 read_descriptor_loop(cas->descriptors, b, cas->section_length - 5 - 4 ); // explanation: section_length gives us the length from the end of section_length // we used 5 bytes for the mandatory section fields, and will use another 4 bytes for CRC // the remaining bytes contain descriptors, most probably only one // again, it's much shorter in C :-) cas->CRC_32 = bs_read_u32(b); // check CRC crc_t cas_crc = crc_init(); cas_crc = crc_update(cas_crc, buf, bs_pos(b) - 4); cas_crc = crc_finalize(cas_crc); if (cas_crc != cas->CRC_32) { LOG_ERROR_ARGS("CAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", cas->CRC_32, cas_crc); reportAddErrorLogArgs("CAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", cas->CRC_32, cas_crc); SAFE_REPORT_TS_ERR(-33); resetPSITableBuffer(catBuffer); bs_free (b); return 0; } bs_free(b); resetPSITableBuffer(catBuffer); return 1; }
int program_association_section_read(program_association_section_t *pas, uint8_t *buf, size_t buf_len, uint32_t payload_unit_start_indicator, psi_table_buffer_t *patBuffer) { vqarray_t *programs; int num_programs = 0; if (pas == NULL || buf == NULL) { SAFE_REPORT_TS_ERR(-1); return 0; } bs_t *b = NULL; if (!payload_unit_start_indicator && patBuffer->buffer == NULL) { // this TS packet is not start of table, and we have no cached table data LOG_WARN ("program_association_section_read: payload_unit_start_indicator not set and no cached data"); return 0; } if (payload_unit_start_indicator) { uint8_t payloadStartPtr = buf[0]; buf += (payloadStartPtr + 1); buf_len -= (payloadStartPtr + 1); LOG_DEBUG_ARGS ("program_association_section_read: payloadStartPtr = %d", payloadStartPtr); } // check for pat spanning multiple TS packets if (patBuffer->buffer != NULL) { LOG_DEBUG_ARGS ("program_association_section_read: patBuffer detected: patBufferAllocSz = %d, patBufferUsedSz = %d", patBuffer->bufferAllocSz, patBuffer->bufferUsedSz); size_t numBytesToCopy = buf_len; if (buf_len > (patBuffer->bufferAllocSz - patBuffer->bufferUsedSz)) { numBytesToCopy = patBuffer->bufferAllocSz - patBuffer->bufferUsedSz; } LOG_DEBUG_ARGS ("program_association_section_read: copying %d bytes to patBuffer", numBytesToCopy); memcpy (patBuffer->buffer + patBuffer->bufferUsedSz, buf, numBytesToCopy); patBuffer->bufferUsedSz += numBytesToCopy; if (patBuffer->bufferUsedSz < patBuffer->bufferAllocSz) { LOG_DEBUG ("program_association_section_read: patBuffer not yet full -- returning"); return 0; } b = bs_new(patBuffer->buffer, patBuffer->bufferUsedSz); } else { b = bs_new(buf, buf_len); } pas->table_id = bs_read_u8(b); if (pas->table_id != program_association_section) { LOG_ERROR_ARGS("Table ID in PAT is 0x%02X instead of expected 0x%02X", pas->table_id, program_association_section); reportAddErrorLogArgs("Table ID in PAT is 0x%02X instead of expected 0x%02X", pas->table_id, program_association_section); SAFE_REPORT_TS_ERR(-30); resetPSITableBuffer(patBuffer); bs_free (b); return 0; } // read byte 0 pas->section_syntax_indicator = bs_read_u1(b); if (!pas->section_syntax_indicator) { LOG_ERROR("section_syntax_indicator not set in PAT"); reportAddErrorLog("section_syntax_indicator not set in PAT"); SAFE_REPORT_TS_ERR(-31); resetPSITableBuffer(patBuffer); bs_free (b); return 0; } bs_skip_u(b, 3); // TODO read the zero bit, check it to be zero pas->section_length = bs_read_u(b, 12); if (pas->section_length > MAX_SECTION_LEN) { LOG_ERROR_ARGS("PAT section length is 0x%02X, larger than maximum allowed 0x%02X", pas->section_length, MAX_SECTION_LEN); reportAddErrorLogArgs("PAT section length is 0x%02X, larger than maximum allowed 0x%02X", pas->section_length, MAX_SECTION_LEN); SAFE_REPORT_TS_ERR(-32); resetPSITableBuffer(patBuffer); bs_free (b); return 0; } if (pas->section_length > bs_bytes_left(b)) { LOG_DEBUG ("program_association_section_read: Detected section spans more than one TS packet -- allocating buffer"); if (patBuffer->buffer != NULL) { // should never get here LOG_ERROR ("program_association_section_read: unexpected patBufffer"); reportAddErrorLog ("program_association_section_read: unexpected patBufffer"); resetPSITableBuffer(patBuffer); } patBuffer->bufferAllocSz = pas->section_length + 3; patBuffer->buffer = (uint8_t *)calloc (pas->section_length + 3, 1); memcpy (patBuffer->buffer, buf, buf_len); patBuffer->bufferUsedSz = buf_len; bs_free (b); return 0; } // read bytes 1,2 pas->transport_stream_id = bs_read_u16(b); // read bytes 3,4 bs_skip_u(b, 2); pas->version_number = bs_read_u(b, 5); pas->current_next_indicator = bs_read_u1(b); if (!pas->current_next_indicator) LOG_WARN("This PAT is not yet applicable/n"); // read byte 5 pas->section_number = bs_read_u8(b); pas->last_section_number = bs_read_u8(b); if (pas->section_number != 0 || pas->last_section_number != 0) LOG_WARN("Multi-section PAT is not supported yet/n"); // read bytes 6,7 num_programs = (pas->section_length - 5 - 4) / 4; // Programs listed in the PAT // explanation: section_length gives us the length from the end of section_length // we used 5 bytes for the mandatory section fields, and will use another 4 bytes for CRC // the remaining bytes contain program information, which is 4 bytes per iteration // It's much shorter in C :-) // Read the program loop, but ignore the NIT PID "program" programs = vqarray_new(); for (uint32_t i = 0; i < num_programs; i++) { program_info_t *prog = malloc(sizeof(program_info_t)); prog->program_number = bs_read_u16(b); if (prog->program_number == 0) { // Skip the NIT PID program (not a real program) free(prog); bs_skip_u(b, 16); continue; } bs_skip_u(b, 3); prog->program_map_PID = bs_read_u(b, 13); vqarray_add(programs, (vqarray_elem_t*)prog); } // This is our true number of programs pas->_num_programs = vqarray_length(programs); if (pas->_num_programs > 1) LOG_WARN_ARGS("%zd programs found, but only SPTS is fully supported. Patches are welcome.", pas->_num_programs); // Copy form our vqarray into the native array pas->programs = malloc(pas->_num_programs * sizeof(program_info_t)); for (uint32_t i = 0; i < pas->_num_programs; i++) { program_info_t* prog = (program_info_t*)vqarray_pop(programs); pas->programs[i] = *prog; free(prog); } vqarray_free(programs); pas->CRC_32 = bs_read_u32(b); // check CRC crc_t pas_crc = crc_init(); pas_crc = crc_update(pas_crc, buf, bs_pos(b) - 4); pas_crc = crc_finalize(pas_crc); if (pas_crc != pas->CRC_32) { LOG_ERROR_ARGS("PAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pas->CRC_32, pas_crc); reportAddErrorLogArgs("PAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pas->CRC_32, pas_crc); SAFE_REPORT_TS_ERR(-33); resetPSITableBuffer(patBuffer); bs_free (b); return 0; } else { // LOG_DEBUG("PAT CRC_32 checked successfully"); // don't enable unless you want to see this every ~100ms } bs_free(b); resetPSITableBuffer(patBuffer); return 1; }
int program_map_section_read(program_map_section_t *pms, uint8_t *buf, size_t buf_size, uint32_t payload_unit_start_indicator, psi_table_buffer_t *pmtBuffer) { LOG_DEBUG ("program_map_section_read -- entering"); if (pms == NULL || buf == NULL) { SAFE_REPORT_TS_ERR(-1); return 0; } bs_t *b = NULL; if (!payload_unit_start_indicator && pmtBuffer->buffer == NULL) { // this TS packet is not start of table, and we have no cached table data LOG_WARN ("program_map_section_read: payload_unit_start_indicator not set and no cached data"); return 0; } if (payload_unit_start_indicator) { uint8_t payloadStartPtr = buf[0]; buf += (payloadStartPtr + 1); buf_size -= (payloadStartPtr + 1); LOG_DEBUG_ARGS ("program_map_section_read: payloadStartPtr = %d", payloadStartPtr); } // check for pmt spanning multiple TS packets if (pmtBuffer->buffer != NULL) { LOG_DEBUG_ARGS ("program_map_section_read: pmtBuffer detected: pmtBufferAllocSz = %d, pmtBufferUsedSz = %d", pmtBuffer->bufferAllocSz, pmtBuffer->bufferUsedSz); size_t numBytesToCopy = buf_size; if (buf_size > (pmtBuffer->bufferAllocSz - pmtBuffer->bufferUsedSz)) { numBytesToCopy = pmtBuffer->bufferAllocSz - pmtBuffer->bufferUsedSz; } LOG_DEBUG_ARGS ("program_map_section_read: copying %d bytes to pmtBuffer", numBytesToCopy); memcpy (pmtBuffer->buffer + pmtBuffer->bufferUsedSz, buf, numBytesToCopy); pmtBuffer->bufferUsedSz += numBytesToCopy; if (pmtBuffer->bufferUsedSz < pmtBuffer->bufferAllocSz) { LOG_DEBUG ("program_map_section_read: pmtBuffer not yet full -- returning"); return 0; } b = bs_new(pmtBuffer->buffer, pmtBuffer->bufferUsedSz); } else { b = bs_new(buf, buf_size); } pms->table_id = bs_read_u8(b); if (pms->table_id != TS_program_map_section) { LOG_ERROR_ARGS("Table ID in PMT is 0x%02X instead of expected 0x%02X", pms->table_id, TS_program_map_section); reportAddErrorLogArgs("Table ID in PMT is 0x%02X instead of expected 0x%02X", pms->table_id, TS_program_map_section); SAFE_REPORT_TS_ERR(-40); resetPSITableBuffer(pmtBuffer); bs_free (b); return 0; } pms->section_syntax_indicator = bs_read_u1(b); if (!pms->section_syntax_indicator) { LOG_ERROR("section_syntax_indicator not set in PMT"); reportAddErrorLog("section_syntax_indicator not set in PMT"); SAFE_REPORT_TS_ERR(-41); resetPSITableBuffer(pmtBuffer); bs_free (b); return 0; } bs_skip_u(b, 3); pms->section_length = bs_read_u(b, 12); if (pms->section_length > MAX_SECTION_LEN) { LOG_ERROR_ARGS("PMT section length is 0x%02X, larger than maximum allowed 0x%02X", pms->section_length, MAX_SECTION_LEN); reportAddErrorLogArgs("PMT section length is 0x%02X, larger than maximum allowed 0x%02X", pms->section_length, MAX_SECTION_LEN); SAFE_REPORT_TS_ERR(-42); resetPSITableBuffer(pmtBuffer); bs_free (b); return 0; } if (pms->section_length > bs_bytes_left(b)) { LOG_DEBUG ("program_map_section_read: Detected section spans more than one TS packet -- allocating buffer"); if (pmtBuffer->buffer != NULL) { // should never get here LOG_ERROR ("program_map_section_read: unexpected pmtBufffer"); reportAddErrorLog ("program_map_section_read: unexpected pmtBufffer"); resetPSITableBuffer(pmtBuffer); } pmtBuffer->bufferAllocSz = pms->section_length + 3; pmtBuffer->buffer = (uint8_t *)calloc (pms->section_length + 3, 1); memcpy (pmtBuffer->buffer, buf, buf_size); pmtBuffer->bufferUsedSz = buf_size; bs_free (b); return 0; } int section_start = bs_pos(b); // bytes 0,1 pms->program_number = bs_read_u16(b); // byte 2; bs_skip_u(b, 2); pms->version_number = bs_read_u(b, 5); pms->current_next_indicator = bs_read_u1(b); if (!pms->current_next_indicator) LOG_WARN("This PMT is not yet applicable/n"); // bytes 3,4 pms->section_number = bs_read_u8(b); pms->last_section_number = bs_read_u8(b); if (pms->section_number != 0 || pms->last_section_number != 0) { LOG_ERROR("Multi-section PMT is not allowed/n"); reportAddErrorLog("Multi-section PMT is not allowed/n"); SAFE_REPORT_TS_ERR(-43); resetPSITableBuffer(pmtBuffer); bs_free (b); return 0; } bs_skip_u(b, 3); pms->PCR_PID = bs_read_u(b, 13); if (pms->PCR_PID < GENERAL_PURPOSE_PID_MIN || pms->PCR_PID > GENERAL_PURPOSE_PID_MAX) { LOG_ERROR_ARGS("PCR PID has invalid value 0x%02X", pms->PCR_PID); reportAddErrorLogArgs("PCR PID has invalid value 0x%02X", pms->PCR_PID); SAFE_REPORT_TS_ERR(-44); resetPSITableBuffer(pmtBuffer); bs_free (b); return 0; } // printf ("PCR PID = %d\n", pms->PCR_PID); bs_skip_u(b, 4); pms->program_info_length = bs_read_u(b, 12); if (pms->program_info_length > MAX_PROGRAM_INFO_LEN) { LOG_ERROR_ARGS("PMT program info length is 0x%02X, larger than maximum allowed 0x%02X", pms->program_info_length, MAX_PROGRAM_INFO_LEN); reportAddErrorLogArgs("PMT program info length is 0x%02X, larger than maximum allowed 0x%02X", pms->program_info_length, MAX_PROGRAM_INFO_LEN); SAFE_REPORT_TS_ERR(-45); resetPSITableBuffer(pmtBuffer); bs_free (b); return 0; } read_descriptor_loop(pms->descriptors, b, pms->program_info_length); while (!bs_eof(b) && pms->section_length - (bs_pos(b) - section_start) > 4) // account for CRC { elementary_stream_info_t *es = es_info_new(); es_info_read(es, b); vqarray_add(pms->es_info, es); } pms->CRC_32 = bs_read_u32(b); // check CRC crc_t pas_crc = crc_init(); pas_crc = crc_update(pas_crc, b->start, bs_pos(b) - 4); pas_crc = crc_finalize(pas_crc); if (pas_crc != pms->CRC_32) { LOG_ERROR_ARGS("PMT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pms->CRC_32, pas_crc); reportAddErrorLogArgs("PMT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pms->CRC_32, pas_crc); SAFE_REPORT_TS_ERR(-46); resetPSITableBuffer(pmtBuffer); bs_free (b); return 0; } else { // LOG_DEBUG("PMT CRC_32 checked successfully"); } int bytes_read = bs_pos(b); bs_free(b); resetPSITableBuffer(pmtBuffer); return bytes_read; }
uint8_t lux_hal_crc_ok(){ return crc_finalize(crc) == 0x2144DF1C; }
void lux_hal_write_crc(uint8_t* ptr){ crc = crc_finalize(crc); memcpy(ptr, &crc, 4); }
conditional_access_section_t* conditional_access_section_read(uint8_t* buf, size_t buf_len) { g_return_val_if_fail(buf, NULL); if (!buf_len) { g_critical("Buffer for program association section is empty."); return NULL; } uint8_t offset = buf[0] + 1; if (offset > buf_len) { g_critical("Invalid pointer field %"PRIu8" in PAT", offset - 1); return NULL; } conditional_access_section_t* cas = conditional_access_section_new(); bitreader_new_stack(b, buf + offset, buf_len - offset); if (!section_header_read((mpeg2ts_section_t*)cas, b)) { goto fail; } if (cas->table_id != TABLE_ID_CONDITIONAL_ACCESS_SECTION) { g_critical("Table ID in CAT is 0x%02X instead of expected 0x%02X", cas->table_id, TABLE_ID_CONDITIONAL_ACCESS_SECTION); goto fail; } // 18-bits of reserved value bitreader_read_uint16(b); bitreader_skip_bits(b, 2); cas->version_number = bitreader_read_bits(b, 5); cas->current_next_indicator = bitreader_read_bit(b); cas->section_number = bitreader_read_uint8(b); cas->last_section_number = bitreader_read_uint8(b); if (cas->section_number != 0 || cas->last_section_number != 0) { g_warning("Multi-section CAT is not supported yet"); } if (cas->section_length < 9) { g_critical("Invalid CAT section length, %"PRIu16" is not long enough to hold required data.", cas->section_length); goto fail; } if (!read_descriptors(b, cas->section_length - 5 - 4, &cas->descriptors, &cas->descriptors_len)) { goto fail; } // explanation: section_length gives us the length from the end of section_length // we used 5 bytes for the mandatory section fields, and will use another 4 bytes for CRC // the remaining bytes contain descriptors, most probably only one cas->crc_32 = bitreader_read_uint32(b); if (b->error || cas->section_length + 3 - 4 > b->len) { g_critical("Invalid Program Map Section length."); goto fail; } // check CRC crc_t crc = crc_init(); crc = crc_update(crc, b->data, cas->section_length + 3 - 4); crc = crc_finalize(crc); if (crc != cas->crc_32) { g_critical("CAT CRC_32 should be 0x%08X, but calculated as 0x%08X", cas->crc_32, crc); goto fail; } cleanup: return cas; fail: conditional_access_section_unref(cas); cas = NULL; goto cleanup; }
memcpy(ptr, &packet->destination, sizeof packet->destination); ptr += sizeof packet->destination; memcpy(ptr, &packet->command, sizeof packet->command); ptr += sizeof packet->command; memcpy(ptr, &packet->index, sizeof packet->index); ptr += sizeof packet->index; memcpy(ptr, &packet->payload, packet->payload_length); ptr += packet->payload_length; crc_t crc = crc_init(); crc = crc_update(crc, tmp, ptr - tmp); crc = crc_finalize(crc); packet->crc = crc; memcpy(ptr, &crc, sizeof packet->crc); ptr += sizeof packet->crc; n = cobs_encode(tmp, ptr - tmp, buffer); if(n < 0) return n; //buffer[n++] = 0; // Double null bytes buffer[n++] = 0; return n; // success } static int unframe(uint8_t * raw_data, int raw_len, struct lux_packet * packet) { uint8_t tmp[2048]; int len;
program_association_section_t* program_association_section_read(uint8_t* buf, size_t buf_len) { g_return_val_if_fail(buf, NULL); if (!buf_len) { g_critical("Buffer for program association section is empty."); return NULL; } uint8_t offset = buf[0] + 1; if (offset > buf_len) { g_critical("Invalid pointer field %"PRIu8" in PAT", offset - 1); return NULL; } program_association_section_t* pas = program_association_section_new(); bitreader_new_stack(b, buf + offset, buf_len - offset); if (!section_header_read((mpeg2ts_section_t*)pas, b)) { goto fail; } if (pas->table_id != TABLE_ID_PROGRAM_ASSOCIATION_SECTION) { g_critical("Table ID in PAT is 0x%02X instead of expected 0x%02X", pas->table_id, TABLE_ID_PROGRAM_ASSOCIATION_SECTION); goto fail; } pas->transport_stream_id = bitreader_read_uint16(b); // Reserved bits bitreader_skip_bits(b, 2); pas->version_number = bitreader_read_bits(b, 5); pas->current_next_indicator = bitreader_read_bit(b); pas->section_number = bitreader_read_uint8(b); pas->last_section_number = bitreader_read_uint8(b); if(pas->section_number != 0 || pas->last_section_number != 0) { g_warning("Multi-section PAT is not supported yet"); } // section_length gives us the length from the end of section_length // we used 5 bytes for the mandatory section fields, and will use another 4 bytes for CRC // the remaining bytes contain program information, which is 4 bytes per iteration if (pas->section_length < 9) { g_critical("Invalid PAT, section_length of %"PRIu16" is not long enoough to hold require data.", pas->section_length); goto fail; } pas->num_programs = (pas->section_length - 5 - 4) / 4; pas->programs = malloc(pas->num_programs * sizeof(program_info_t)); for (size_t i = 0; i < pas->num_programs; ++i) { pas->programs[i].program_number = bitreader_read_uint16(b); bitreader_skip_bits(b, 3); // reserved pas->programs[i].program_map_pid = bitreader_read_bits(b, 13); } pas->crc_32 = bitreader_read_uint32(b); if (b->error || pas->section_length + 3 - 4 > b->len) { g_critical("Invalid Program Association Section length."); goto fail; } // check CRC crc_t pas_crc = crc_init(); pas_crc = crc_update(pas_crc, b->data, pas->section_length + 3 - 4); pas_crc = crc_finalize(pas_crc); if (pas_crc != pas->crc_32) { g_critical("PAT CRC_32 should be 0x%08X, but calculated as 0x%08X", pas->crc_32, pas_crc); goto fail; } cleanup: return pas; fail: program_association_section_unref(pas); pas = NULL; goto cleanup; }
program_map_section_t* program_map_section_read(uint8_t* buf, size_t buf_len) { g_return_val_if_fail(buf, NULL); if (!buf_len) { g_critical("Buffer for program map section is empty."); return NULL; } uint8_t offset = buf[0] + 1; if (offset > buf_len) { g_critical("Invalid pointer field %"PRIu8" in PMT", offset - 1); return NULL; } program_map_section_t* pms = program_map_section_new(); bitreader_new_stack(b, buf + offset, buf_len - offset); GPtrArray* es_info = NULL; if (!section_header_read((mpeg2ts_section_t*)pms, b)) { goto fail; } if (pms->table_id != TABLE_ID_PROGRAM_MAP_SECTION) { g_critical("Table ID in PMT is 0x%02X instead of expected 0x%02X", pms->table_id, TABLE_ID_PROGRAM_MAP_SECTION); goto fail; } pms->program_number = bitreader_read_uint16(b); // reserved bitreader_skip_bits(b, 2); pms->version_number = bitreader_read_bits(b, 5); pms->current_next_indicator = bitreader_read_bit(b); pms->section_number = bitreader_read_uint8(b); pms->last_section_number = bitreader_read_uint8(b); if (pms->section_number != 0 || pms->last_section_number != 0) { g_critical("Multi-section PMT is not allowed"); } // reserved bitreader_skip_bits(b, 3); pms->pcr_pid = bitreader_read_bits(b, 13); if (pms->pcr_pid < GENERAL_PURPOSE_PID_MIN || pms->pcr_pid > GENERAL_PURPOSE_PID_MAX) { g_critical("PCR PID has invalid value 0x%02X", pms->pcr_pid); goto fail; } // reserved bitreader_skip_bits(b, 4); uint16_t program_info_length = bitreader_read_bits(b, 12); if (program_info_length > MAX_PROGRAM_INFO_LEN) { g_critical("PMT program info length is 0x%02X, larger than maximum allowed 0x%02X", program_info_length, MAX_PROGRAM_INFO_LEN); goto fail; } if (!read_descriptors(b, program_info_length, &pms->descriptors, &pms->descriptors_len)) { goto fail; } es_info = g_ptr_array_new(); while (bitreader_bytes_left(b) > 4) { // account for CRC elementary_stream_info_t* es = es_info_read(b); if (!es) { goto fail; } g_ptr_array_add(es_info, es); } if (bitreader_bytes_left(b) != 4) { g_critical("CRC missing in PMT"); goto fail; } pms->es_info_len = es_info->len; pms->es_info = (elementary_stream_info_t**)g_ptr_array_free(es_info, false); es_info = NULL; pms->crc_32 = bitreader_read_uint32(b); if (b->error || pms->section_length + 3 - 4 > b->len) { g_critical("Invalid Program Map Section length."); goto fail; } // check CRC crc_t pms_crc = crc_init(); pms_crc = crc_update(pms_crc, b->data, pms->section_length + 3 - 4); pms_crc = crc_finalize(pms_crc); if (pms_crc != pms->crc_32) { g_critical("PMT CRC_32 should be 0x%08X, but calculated as 0x%08X", pms->crc_32, pms_crc); goto fail; } cleanup: return pms; fail: program_map_section_unref(pms); if (es_info) { g_ptr_array_set_free_func(es_info, (GDestroyNotify)es_info_free); g_ptr_array_free(es_info, true); } pms = NULL; goto cleanup; }
crc_t message_crc(message *msg) { crc_t c = crc_init(); // crc everything except the last crc field c = crc_update(c, (void *)msg, ((void *)&(msg->crc)) - ((void*)msg)); return crc_finalize(c); }
int program_association_section_read(program_association_section_t *pas, uint8_t *buf, size_t buf_len) { if (pas == NULL || buf == NULL) { SAFE_REPORT_TS_ERR(-1); return 0; } bs_t *b = bs_new(buf, buf_len); pas->table_id = bs_read_u8(b); if (pas->table_id != program_association_section) { LOG_ERROR_ARGS("Table ID in PAT is 0x%02X instead of expected 0x%02X", pas->table_id, program_association_section); SAFE_REPORT_TS_ERR(-30); return 0; } // read byte 0 pas->section_syntax_indicator = bs_read_u1(b); if (!pas->section_syntax_indicator) { LOG_ERROR("section_syntax_indicator not set in PAT"); SAFE_REPORT_TS_ERR(-31); return 0; } bs_skip_u(b, 3); // TODO read the zero bit, check it to be zero pas->section_length = bs_read_u(b, 12); if (pas->section_length > MAX_SECTION_LEN) { LOG_ERROR_ARGS("PAT section length is 0x%02X, larger than maximum allowed 0x%02X", pas->section_length, MAX_SECTION_LEN); SAFE_REPORT_TS_ERR(-32); return 0; } // read bytes 1,2 pas->transport_stream_id = bs_read_u16(b); // read bytes 3,4 bs_skip_u(b, 2); pas->version_number = bs_read_u(b, 5); pas->current_next_indicator = bs_read_u1(b); if (!pas->current_next_indicator) LOG_WARN("This PAT is not yet applicable/n"); // read byte 5 pas->section_number = bs_read_u8(b); pas->last_section_number = bs_read_u8(b); if (pas->section_number != 0 || pas->last_section_number != 0) LOG_WARN("Multi-section PAT is not supported yet/n"); // read bytes 6,7 pas->_num_programs = (pas->section_length - 5 - 4) / 4; // explanation: section_length gives us the length from the end of section_length // we used 5 bytes for the mandatory section fields, and will use another 4 bytes for CRC // the remaining bytes contain program information, which is 4 bytes per iteration // It's much shorter in C :-) if (pas->_num_programs > 1) LOG_WARN_ARGS("%zd programs found, but only SPTS is fully supported. Patches are welcome.", pas->_num_programs); pas->programs = malloc(pas->_num_programs * sizeof(program_info_t)); for (uint32_t i = 0; i < pas->_num_programs; i++) { pas->programs[i].program_number = bs_read_u16(b); bs_skip_u(b, 3); pas->programs[i].program_map_PID = bs_read_u(b, 13); } pas->CRC_32 = bs_read_u32(b); // check CRC crc_t pas_crc = crc_init(); pas_crc = crc_update(pas_crc, buf, bs_pos(b) - 4); pas_crc = crc_finalize(pas_crc); if (pas_crc != pas->CRC_32) { LOG_ERROR_ARGS("PAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pas->CRC_32, pas_crc); SAFE_REPORT_TS_ERR(-33); return 0; } else { LOG_DEBUG("PAT CRC_32 checked successfully"); } bs_free(b); return 1; }
/** * C main function. * * \return 0 on success, != 0 on error. *****************************************************************************/ int main(int argc, char *argv[]) { printf("Broadcom platform based LG Digital TV NVRAM editor\n"); printf("Version 0.0.5 by xeros (openlgtv.org.ru) 04.11.2012\n\n"); crc_t crc; get_config(argc, argv); /*if (strlen(file) == 0) { file="/tmp/nvram"; }*/ finput = fopen(file, "rb"); if (finput) { ninput = fread(str, sizeof(str), 1, finput); ninput = fread(num1a, 1, 1, finput); ninput = fread(num2a, 1, 1, finput); ninput = fread(num3a, 1, 1, finput); ninput = fread(num4a, 1, 1, finput); fclose(finput); } else { printf("%s %s\n", "error opening input file for read:", file); return 1; } printf("Input file: %s\n\n", file); debug_status=str[NVRAM_DEBUG_STATUS]; baudrate=str[NVRAM_BAUDRATE]; lang1a=str[NVRAM_LANG1+2]; lang1b=str[NVRAM_LANG1+1]; lang1c=str[NVRAM_LANG1]; lang2a=str[NVRAM_LANG2+2]; lang2b=str[NVRAM_LANG2+1]; lang2c=str[NVRAM_LANG2]; char model[NVRAM_MODEL_LEN]; char serial[NVRAM_SERIAL_LEN]; int nr; for (nr = 0; nr <= NVRAM_MODEL_LEN; nr++) { model[nr]=str[NVRAM_MODEL+nr]; } printf("Model name: %s\n", model); for (nr = 0; nr <= NVRAM_SERIAL_LEN; nr++) { serial[nr]=str[NVRAM_SERIAL+nr]; } printf("Serial number: %s\n", serial); printf("Lang1: %c%c%c\n", (char) lang1a, (char) lang1b, (char) lang1c); printf("Lang2: %c%c%c\n", (char) lang2a, (char) lang2b, (char) lang2c); /* printf("Debug status offset: %x\n", NVRAM_DEBUG_STATUS-((NVRAM_DEBUG_STATUS/NVRAM_BLOCK_DATA_SIZE)*NVRAM_BLOCK_HEADER_SIZE)); printf("Debug status offset: %x\n", get_offset(NVRAM_DEBUG_STATUS)); */ if (debug_status < 3) { printf("Platform: MSTAR Saturn7\n"); } else { if (debug_status < 6) { printf("Platform: Broadcom BCM3549/3556\n"); } else { printf("Platform: UNKNOWN!\n"); } } /* printf(" NVM_ID_BASE : \t\t 0x%x \t\t %i \t %i\n", NVM_ID_BASE, NVM_ID_BASE, NVM_ID_SIZE ); printf(" NVM_HEADER_BASE : \t 0x%x \t\t %i \t %i\n", NVM_HEADER_BASE, NVM_HEADER_BASE, NVM_HEADER_SIZE ); printf(" TNVM_MAGIC_BASE : \t 0x%x \t\t %i \t %i\n", TNVM_MAGIC_BASE, TNVM_MAGIC_BASE, TNVM_MAGIC_SIZE ); printf(" SYS_DB_BASE : \t\t 0x%x \t\t %i \t %i\n", SYS_DB_BASE, SYS_DB_BASE, SYS_DB_SIZE ); printf(" ANA_DB_BASE : \t\t 0x%x \t\t %i \t %i\n", ANA_DB_BASE, ANA_DB_BASE, ANA_DB_SIZE ); printf(" TOOL_OPTION_DB_BASE : \t 0x%x \t\t %i\n", TOOL_OPTION_DB_BASE, TOOL_OPTION_DB_BASE ); printf(" FACTORY_DB_BASE : \t 0x%x \t\t %i\n", FACTORY_DB_BASE, FACTORY_DB_BASE ); printf(" UI_DB_BASE : \t\t 0x%x \t\t %i\n", UI_DB_BASE, UI_DB_BASE ); printf(" UI_EXPERT_DB_BASE : \t 0x%x \t %i\n", UI_EXPERT_DB_BASE, UI_EXPERT_DB_BASE ); printf(" CH_DB_BASE : \t\t 0x%x \t %i\n", CH_DB_BASE, CH_DB_BASE ); printf(" BT_DB_BASE : \t\t 0x%x \t %i\n", BT_DB_BASE, BT_DB_BASE ); printf(" EMP_DB_BASE : \t\t 0x%x \t %i\n", EMP_DB_BASE, EMP_DB_BASE ); printf(" ACAP_DB_BASE : \t 0x%x \t %i\n", ACAP_DB_BASE, ACAP_DB_BASE ); printf(" THX_DB_BASE : \t\t 0x%x \t %i\n", THX_DB_BASE, THX_DB_BASE ); printf(" NVRAM_SIZE : \t\t 0x%x \t %i\n", NVRAM_SIZE, NVRAM_SIZE ); printf("NVRAM OFFSETS:\n"); printf(" NVM_ID_BASE : \t\t 0x%x \t\t %i \t %i\n", get_offset(NVM_ID_BASE), NVM_ID_BASE, NVM_ID_SIZE ); printf(" NVM_HEADER_BASE : \t 0x%x \t\t %i \t %i\n", get_offset(NVM_HEADER_BASE), NVM_HEADER_BASE, NVM_HEADER_SIZE ); printf(" TNVM_MAGIC_BASE : \t 0x%x \t\t %i \t %i\n", get_offset(TNVM_MAGIC_BASE), TNVM_MAGIC_BASE, TNVM_MAGIC_SIZE ); printf(" SYS_DB_BASE : \t\t 0x%x \t\t %i \t %i\n", get_offset(SYS_DB_BASE), SYS_DB_BASE, SYS_DB_SIZE ); printf(" ANA_DB_BASE : \t\t 0x%x \t\t %i \t %i\n", get_offset(ANA_DB_BASE), ANA_DB_BASE, ANA_DB_SIZE ); printf(" TOOL_OPTION_DB_BASE : \t 0x%x \t\t %i\n", get_offset(TOOL_OPTION_DB_BASE), TOOL_OPTION_DB_BASE ); printf(" FACTORY_DB_BASE : \t 0x%x \t\t %i\n", get_offset(FACTORY_DB_BASE), FACTORY_DB_BASE ); printf(" UI_DB_BASE : \t\t 0x%x \t\t %i\n", get_offset(UI_DB_BASE), UI_DB_BASE ); printf(" UI_EXPERT_DB_BASE : \t 0x%x \t %i\n", get_offset(UI_EXPERT_DB_BASE), UI_EXPERT_DB_BASE ); printf(" CH_DB_BASE : \t\t 0x%x \t %i\n", get_offset(CH_DB_BASE), CH_DB_BASE ); printf(" BT_DB_BASE : \t\t 0x%x \t %i\n", get_offset(BT_DB_BASE), BT_DB_BASE ); printf(" EMP_DB_BASE : \t\t 0x%x \t %i\n", get_offset(EMP_DB_BASE), EMP_DB_BASE ); printf(" ACAP_DB_BASE : \t 0x%x \t %i\n", get_offset(ACAP_DB_BASE), ACAP_DB_BASE ); printf(" THX_DB_BASE : \t\t 0x%x \t %i\n", get_offset(THX_DB_BASE), THX_DB_BASE ); printf(" NVRAM_SIZE : \t\t 0x%x \t %i\n", get_size(NVRAM_SIZE), NVRAM_SIZE ); printf(" NVMDRV_TOTAL_SIZE : \t\t 0x%x \t %i \t %i\n", get_size(NVMDRV_TOTAL_SIZE), get_size(NVMDRV_TOTAL_SIZE), NVMDRV_TOTAL_SIZE ); */ if ((debug_status > 5) || (baudrate > 7)) { printf("NVRAM DUMP IS WRONG!\nPoweroff and poweron TV to get good one (do not use reboot) or use yours older NVRAM dump!\n"); return -1; } string *debug_status_type = &DEBUG_STATES[debug_status]; string *baudrate_type = &BAUDRATE_STATES[baudrate]; printf("Debug status: %s (%i)\n", *debug_status_type, debug_status); printf("Baudrate: %s bps (%i)\n", *baudrate_type, baudrate); crc = crc_init(); crc = crc_update(crc, (unsigned char *)str, sizeof(str)); crc = crc_finalize(crc); if (verbose) { print_params(); } int i; //for(i = 0;i < 133120;++i) //printf("%c", ((char *)str)[i]); char buffer[5]; sprintf(buffer, "%lx", (long unsigned int)crc); //char buffer2[5]; //sprintf(buffer2, "%lx", str2); char* num1 = substring(buffer, 6, 2); char* num2 = substring(buffer, 4, 2); char* num3 = substring(buffer, 2, 2); char* num4 = substring(buffer, 0, 2); printf("\n"); char crc1[9], crc2[9]; int ret = sprintf(crc1, "%02x%02x%02x%02x", *num1a, *num2a, *num3a, *num4a); int ret2 = sprintf(crc2, "%s%s%s%s", num1, num2, num3, num4); printf("Read CRC: %s\n", crc1); printf("Calculated CRC: %s\n", crc2); if (strcmp(crc1, crc2)) { printf("\nChecksum is WRONG!\n\n"); write_ofile=1; } else { printf("\nChecksum is OK!\n\n"); } if ((debug_status_changed == 1) && (debug_status < 3) && (debug_status_new > 2)) { printf("ERROR: Debug Status value should be 0-2 for Saturn 7 platform\n"); return -1; } if ((debug_status_changed == 1) && ((debug_status > 2) && (debug_status < 6)) && ((debug_status_new < 3) || (debug_status_new > 5))) { printf("ERROR: Debug Status value should be 3-5 for Broadcom platform\n"); return -1; } if (debug_status_new < 6) { string *debug_status_old = &DEBUG_STATES[str[NVRAM_DEBUG_STATUS]]; string *debug_status_str = &DEBUG_STATES[debug_status_new]; debug_status=debug_status_new; printf("Changing debug status from %s to %s ...\n", *debug_status_old, *debug_status_str); str[NVRAM_DEBUG_STATUS]=debug_status; recalculate_crc=1; } if ((baudrate_changed == 1) && (baudrate_new > 7)) { printf("ERROR: Baudrate values should be 0-7 range\n"); return -1; } if ((baudrate_new < 8)) { string *baudrate_old = &BAUDRATE_STATES[str[NVRAM_BAUDRATE]]; string *baudrate_str = &BAUDRATE_STATES[baudrate_new]; baudrate=baudrate_new; printf("Changing baudrate from %s to %s ...\n", *baudrate_old, *baudrate_str); str[NVRAM_BAUDRATE]=baudrate; recalculate_crc=1; } if (recalculate_crc == 1) { crc = crc_init(); crc = crc_update(crc, (unsigned char *)str, sizeof(str)); crc = crc_finalize(crc); sprintf(buffer, "%lx", (long unsigned int)crc); num1 = substring(buffer, 6, 2); num2 = substring(buffer, 4, 2); num3 = substring(buffer, 2, 2); num4 = substring(buffer, 0, 2); printf("\nRecalculated CRC: %s %s %s %s\n\n", num1, num2, num3, num4); write_ofile=1; } if (write_ofile == 1) { if (debug_status < 3) { str_out_size=NVRAM_FULL_SIZE_S7; } else { str_out_size=NVRAM_FULL_SIZE_BCM; } //printf("Trying to write changed file to %s ...\n", ofile); finput = fopen(file, "rb"); if (finput) { //ninput = fread(str_out, sizeof(str_out), 1, finput); ninput = fread(str_out, str_out_size, 1, finput); int num1x; int num2x; int num3x; int num4x; sscanf(num1, "%x", &num1x); sscanf(num2, "%x", &num2x); sscanf(num3, "%x", &num3x); sscanf(num4, "%x", &num4x); str_out[NVRAM_DEBUG_STATUS]=debug_status; str_out[NVRAM_BAUDRATE]=baudrate; str_out[sizeof(str) + 0 ] = num1x; str_out[sizeof(str) + 1 ] = num2x; str_out[sizeof(str) + 2 ] = num3x; str_out[sizeof(str) + 3 ] = num4x; foutput = fopen(ofile, "wb"); if (foutput) { //noutput = fwrite(str_out, 1, sizeof(str_out), foutput); noutput = fwrite(str_out, 1, str_out_size, foutput); fclose(foutput); printf("File: %s saved.\n", ofile); printf("\nTo commit changes, flash the %s file to nvram partition and reboot TV (do not use power button for that)!\n", ofile); } else { printf("%s %s\n", "error opening file to write to: ", ofile); return 1; } } else { printf("%s %s\n", "error opening input file: ", file); return 1; } } //free(buffer); free(num1); free(num2); free(num3); free(num4); return 0; }
int program_map_section_read(program_map_section_t *pms, uint8_t *buf, size_t buf_size) { if (pms == NULL || buf == NULL) { SAFE_REPORT_TS_ERR(-1); return 0; } bs_t *b = bs_new(buf, buf_size); pms->table_id = bs_read_u8(b); if (pms->table_id != TS_program_map_section) { LOG_ERROR_ARGS("Table ID in PMT is 0x%02X instead of expected 0x%02X", pms->table_id, TS_program_map_section); SAFE_REPORT_TS_ERR(-40); return 0; } pms->section_syntax_indicator = bs_read_u1(b); if (!pms->section_syntax_indicator) { LOG_ERROR("section_syntax_indicator not set in PMT"); SAFE_REPORT_TS_ERR(-41); return 0; } bs_skip_u(b, 3); pms->section_length = bs_read_u(b, 12); if (pms->section_length > MAX_SECTION_LEN) { LOG_ERROR_ARGS("PMT section length is 0x%02X, larger than maximum allowed 0x%02X", pms->section_length, MAX_SECTION_LEN); SAFE_REPORT_TS_ERR(-42); return 0; } int section_start = bs_pos(b); // bytes 0,1 pms->program_number = bs_read_u16(b); // byte 2; bs_skip_u(b, 2); pms->version_number = bs_read_u(b, 5); pms->current_next_indicator = bs_read_u1(b); if (!pms->current_next_indicator) LOG_WARN("This PMT is not yet applicable/n"); // bytes 3,4 pms->section_number = bs_read_u8(b); pms->last_section_number = bs_read_u8(b); if (pms->section_number != 0 || pms->last_section_number != 0) { LOG_ERROR("Multi-section PMT is not allowed/n"); SAFE_REPORT_TS_ERR(-43); return 0; } bs_skip_u(b, 3); pms->PCR_PID = bs_read_u(b, 13); if (pms->PCR_PID < GENERAL_PURPOSE_PID_MIN || pms->PCR_PID > GENERAL_PURPOSE_PID_MAX) { LOG_ERROR_ARGS("PCR PID has invalid value 0x%02X", pms->PCR_PID); SAFE_REPORT_TS_ERR(-44); return 0; } bs_skip_u(b, 4); pms->program_info_length = bs_read_u(b, 12); if (pms->program_info_length > MAX_PROGRAM_INFO_LEN) { LOG_ERROR_ARGS("PMT program info length is 0x%02X, larger than maximum allowed 0x%02X", pms->program_info_length, MAX_PROGRAM_INFO_LEN); SAFE_REPORT_TS_ERR(-45); return 0; } read_descriptor_loop(pms->descriptors, b, pms->program_info_length); while (pms->section_length - (bs_pos(b) - section_start) > 4) { // account for CRC elementary_stream_info_t *es = es_info_new(); es_info_read(es, b); vqarray_add(pms->es_info, es); } pms->CRC_32 = bs_read_u32(b); // check CRC crc_t pas_crc = crc_init(); pas_crc = crc_update(pas_crc, buf, bs_pos(b) - 4); pas_crc = crc_finalize(pas_crc); if (pas_crc != pms->CRC_32) { LOG_ERROR_ARGS("PMT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pms->CRC_32, pas_crc); SAFE_REPORT_TS_ERR(-46); return 0; } else { LOG_DEBUG("PMT CRC_32 checked successfully"); } int bytes_read = bs_pos(b); bs_free(b); return bytes_read; }
static void sdc_log_data(eventid_t id) { static const int32_t mpu_downsample = 30; static const int32_t mpl_downsample = 30; //static const int32_t adis_downsample = 20; static int32_t mpu_count = 0; static int32_t mpl_count = 0; //static int32_t adis_count = 0; bool write_log = false; uint32_t bw; FRESULT f_ret; SDC_ERRORCode sdc_ret; if(id == SENSOR_LOG_START) { fs_stop = false; return; } if(fs_ready && !datafile_state.sd_log_opened ) { f_ret = f_stat(sdc_log_data_file, &datafile_state.DATAFil_info); if(f_ret) { SDCLOGDBG("fail stat on file\r\n"); } SDCLOGDBG("file size of %s is: %d\r\n", sdc_log_data_file, datafile_state.DATAFil_info.fsize); // open an existing log file for writing f_ret = f_open(&datafile_state.DATAFil, sdc_log_data_file, FA_OPEN_EXISTING | FA_READ | FA_WRITE ); if(f_ret) { // try again.... SDCLOGDBG("open existing failed ret: %d\r\n", f_ret); chThdSleepMilliseconds(500); f_ret = f_open(&datafile_state.DATAFil, sdc_log_data_file, FA_OPEN_EXISTING | FA_READ | FA_WRITE ); } if (f_ret) { SDCLOGDBG("failed to open existing %s return %d\r\n",sdc_log_data_file, f_ret); // ok...try creating the file f_ret = f_open(&datafile_state.DATAFil, sdc_log_data_file, FA_CREATE_ALWAYS | FA_WRITE ); if(f_ret) { // try again SDCLOGDBG("open new file ret: %d\r\n", f_ret); f_ret = f_open(&datafile_state.DATAFil, sdc_log_data_file, FA_CREATE_ALWAYS | FA_WRITE ); } if (f_ret) { datafile_state.sd_log_opened = false; } else { datafile_state.sd_log_opened = true; } } else { SDCLOGDBG("Opened existing file OK.\r\n"); /* Seek to end of data if first line is good data */ sdc_ret = sdc_seek_eod(&datafile_state.DATAFil); if(sdc_ret == SDC_OK) { SDCLOGDBG("found eod marker. %lu\r\n", sdc_fp_index); } else { SDCLOGDBG("no eod marker. %lu\r\n", sdc_fp_index); sdc_reset_fp_index(); } datafile_state.sd_log_opened = true; datafile_state.write_errors = 0; } } if (fs_ready && datafile_state.sd_log_opened) { crc_t crc16; RTCTime timenow; int rc; datafile_state.log_data.mh.index = datafile_state.log_sequence++; // timestamp timenow.h12 = 1; rc = psas_rtc_get_unix_time( &RTCD1, &timenow) ; if (rc == -1) { SDCLOGDBG( "%s: psas_rtc time read errors: %d\r\n",__func__, rc); } datafile_state.log_data.logtime.tv_time = timenow.tv_time; datafile_state.log_data.logtime.tv_msec = timenow.tv_msec; psas_rtc_to_psas_ts(&datafile_state.log_data.mh.ts, &timenow); //SDCLOGDBG("%d ", id); switch(id) { case MPU9150: if(mpu_count++ > mpu_downsample) { //SDCLOGDBG("u"); strncpy(datafile_state.log_data.mh.ID, mpuid, sizeof(datafile_state.log_data.mh.ID)); memcpy(&datafile_state.log_data.data, (void*) &mpu9150_current_read, sizeof(MPU9150_read_data) ); datafile_state.log_data.mh.data_length = sizeof(MPU9150_read_data); mpu_count = 0; write_log = true; } break; case MPL3115A2: if(mpl_count++ > mpl_downsample) { //SDCLOGDBG("l"); strncpy(datafile_state.log_data.mh.ID, mplid, sizeof(datafile_state.log_data.mh.ID)); memcpy(&datafile_state.log_data.data, (void*) &mpl3115a2_current_read, sizeof(MPL3115A2_read_data) ); datafile_state.log_data.mh.data_length = sizeof(MPL3115A2_read_data); mpl_count = 0; write_log = true; } break; case ADIS16405: /* *strncpy(datafile_state.log_data.mh.ID, adisid, sizeof(datafile_state.log_data.mh.ID)); *memcpy(&datafile_state.log_data.data, (void*) &adis16405_burst_data, sizeof(ADIS16405_burst_data) ); *datafile_state.log_data.mh.data_length = sizeof(ADIS16405_burst_data); */ break; case SENSOR_LOG_HALT: f_ret = f_close(&datafile_state.DATAFil); if(f_ret) { // try again.... SDCLOGDBG("close existing failed ret: %d\r\n", f_ret); chThdSleepMilliseconds(5); f_ret = f_close(&datafile_state.DATAFil); } datafile_state.sd_log_opened = false; fs_stop = true; break; default: break; } if(write_log) { sdc_ret = sdc_write_log_message(&datafile_state.DATAFil, &datafile_state.log_data, &bw) ; if(sdc_ret != SDC_OK ) { ++datafile_state.write_errors; } // calc checksum crc16 = crc_init(); crc16 = crc_update(crc16, (const unsigned char*) &datafile_state.log_data, sizeof(GENERIC_message)); crc16 = crc_finalize(crc16); sdc_ret = sdc_write_checksum(&datafile_state.DATAFil, &crc16, &bw) ; if(sdc_ret != SDC_OK ) { ++datafile_state.write_errors; SDCLOGDBG("checksum write error %d\r\n", datafile_state.write_errors); } #ifdef DEBUG_SDCLOG if((sdc_fp_index - sdc_fp_index_old) > 100000) { if(datafile_state.write_errors !=0) { SDCLOGDBG("E%d", datafile_state.write_errors); } else { SDCLOGDBG("x"); } sdc_fp_index_old = sdc_fp_index; } #endif write_log = false; } } else { if(datafile_state.sd_log_opened) { f_ret = f_close(&datafile_state.DATAFil); // might be redundant if card removed....\sa f_sync SDCLOGDBG( "close file ret: %d\r\n", f_ret); datafile_state.sd_log_opened = false; } } }