int mrb_read_irep(mrb_state *mrb, const char *bin) { int ret = MRB_DUMP_OK, i, n, nirep, sirep; uint32_t len = 0; unsigned char *src; rite_binary_header bin_header; if ((mrb == NULL) || (bin == NULL)) { return MRB_DUMP_INVALID_ARGUMENT; } src = (unsigned char*)bin; sirep = mrb->irep_len; //Read File Header Section nirep = read_rite_header(mrb, src, &bin_header); if (nirep < 0) return nirep; src += sizeof(bin_header) + MRB_DUMP_SIZE_OF_SHORT; //header + crc //Read Binary Data Section for (n=0,i=sirep; n<nirep; n++,i++) { src += MRB_DUMP_SIZE_OF_LONG; //record ren ret = read_rite_irep_record(mrb, src, &len); if (ret != MRB_DUMP_OK) goto error_exit; src += len; } if (0 != bin_to_uint32(src)) { //dummy record len ret = MRB_DUMP_GENERAL_FAILURE; } error_exit: if (ret != MRB_DUMP_OK) { for (n=0,i=sirep; i<mrb->irep_len; n++,i++) { if (mrb->irep[i]) { if (mrb->irep[i]->iseq) mrb_free(mrb, mrb->irep[i]->iseq); if (mrb->irep[i]->pool) mrb_free(mrb, mrb->irep[i]->pool); if (mrb->irep[i]->syms) mrb_free(mrb, mrb->irep[i]->syms); mrb_free(mrb, mrb->irep[i]); } } // mrb->irep_len = sirep; return ret; } return sirep + hex_to_uint8(bin_header.sirep); }
/** * \brief Parse a RAW command [Level 1] * \param tokens Command tokens. * \param cmd Cmd structure. * \return The error result. */ static TuxDrvError parse_raw_command(tokens_t tokens, delay_cmd_t *cmd) { TuxDrvError ret = E_TUXDRV_INVALIDCOMMAND; int r = 0; int i; for (i = 0; i < TUX_SEND_LENGTH; i++) { if (hex_to_uint8(tokens[i + 1], &cmd->raw_parameters.raw[i])) { r++; } } if (r == TUX_SEND_LENGTH) { ret = E_TUXDRV_NOERROR; } return ret; }
void process_cmd(void) { uart_putstr("Processing command: "); uart_putstr(cmdbuf); UART_PUTS("\r\n"); if ((cmdbuf[0] == 'w') && (strlen(cmdbuf) == 5)) { if (enable_write_eeprom) { uint16_t adr = hex_to_byte((uint8_t)cmdbuf[1]) * 16 + hex_to_byte((uint8_t)cmdbuf[2]); uint8_t val = hex_to_uint8((uint8_t *)cmdbuf, 3); UART_PUTF2("Writing data 0x%x to EEPROM pos 0x%x.\r\n", val, adr); eeprom_write_byte((uint8_t *)adr, val); } else { UART_PUTS("Ignoring EEPROM write, since write mode is DISABLED.\r\n"); } } else if ((cmdbuf[0] == 'r') && (strlen(cmdbuf) == 3)) { uint16_t adr = hex_to_byte((uint8_t)cmdbuf[1]) * 16 + hex_to_byte((uint8_t)cmdbuf[2]); uint8_t val = eeprom_read_byte((uint8_t *)adr); UART_PUTF2("EEPROM value at position 0x%x is 0x%x.\r\n", adr, val); } else if ((cmdbuf[0] == 's') && (strlen(cmdbuf) > 4)) { strcpy(sendbuf, cmdbuf + 1); send_data_avail = true; } else { UART_PUTS("Unknown command.\r\n"); } }
int main(void) { uint8_t aes_key_nr; uint8_t loop = 0; uint8_t loop2 = 0; // delay 1s to avoid further communication with uart or RFM12 when my programmer resets the MC after 500ms... _delay_ms(1000); util_init(); check_eeprom_compatibility(DEVICETYPE_BASESTATION); request_queue_init(); // read packetcounter, increase by cycle and write back packetcounter = e2p_generic_get_packetcounter() + PACKET_COUNTER_WRITE_CYCLE; e2p_generic_set_packetcounter(packetcounter); // read device specific config aes_key_count = e2p_basestation_get_aeskeycount(); device_id = e2p_generic_get_deviceid(); uart_init(); UART_PUTS("\r\n"); UART_PUTF4("smarthomatic Base Station v%u.%u.%u (%08lx)\r\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_HASH); UART_PUTS("(c) 2012..2014 Uwe Freese, www.smarthomatic.org\r\n"); UART_PUTF("Device ID: %u\r\n", device_id); UART_PUTF("Packet counter: %lu\r\n", packetcounter); UART_PUTF("AES key count: %u\r\n", aes_key_count); UART_PUTS("Waiting for incoming data. Press h for help.\r\n\r\n"); led_blink(500, 500, 3); rfm12_init(); sei(); // ENCODE TEST (Move to unit test some day...) /* uint8_t testlen = 32; uint8_t aes_key_num = 0; memset(&bufx[0], 0, sizeof(bufx)); bufx[0] = 0xff; bufx[1] = 0xb0; bufx[2] = 0xa0; bufx[3] = 0x3f; bufx[4] = 0x01; bufx[5] = 0x70; bufx[6] = 0x00; bufx[7] = 0x0c; bufx[8] = 0xa8; bufx[9] = 0x00; bufx[10] = 0x20; bufx[20] = 0x20; eeprom_read_block (aes_key, (uint8_t *)(EEPROM_AESKEYS_BYTE + aes_key_num * 32), 32); UART_PUTS("Using AES key "); print_bytearray((uint8_t *)aes_key, 32); UART_PUTS("Before encryption: "); print_bytearray(bufx, testlen); uint8_t aes_byte_count = aes256_encrypt_cbc(bufx, testlen); UART_PUTF("byte count = %u\r\n", aes_byte_count); UART_PUTS("After encryption: "); print_bytearray(bufx, aes_byte_count); aes256_decrypt_cbc(bufx, aes_byte_count); UART_PUTS("After decryption: "); print_bytearray(bufx, testlen); while(1); */ while (42) { if (rfm12_rx_status() == STATUS_COMPLETE) { uint8_t len = rfm12_rx_len(); if ((len == 0) || (len % 16 != 0)) { UART_PUTF("Received garbage (%u bytes not multiple of 16): ", len); print_bytearray(bufx, len); } else // try to decrypt with all keys stored in EEPROM { bool crcok = false; for (aes_key_nr = 0; aes_key_nr < aes_key_count ; aes_key_nr++) { memcpy(bufx, rfm12_rx_buffer(), len); /*if (aes_key_nr == 0) { UART_PUTS("Before decryption: "); print_bytearray(bufx, len); }*/ e2p_basestation_get_aeskey(aes_key_nr, aes_key); //UART_PUTS("Trying AES key 2 "); //print_bytearray((uint8_t *)aes_key, 32); aes256_decrypt_cbc(bufx, len); //UART_PUTS("Decrypted bytes: "); //print_bytearray(bufx, len); crcok = pkg_header_check_crc32(len); if (crcok) { //UART_PUTS("CRC correct, AES key found!\r\n"); UART_PUTF("Received (AES key %u): ", aes_key_nr); print_bytearray(bufx, len); decode_data(len); break; } } if (!crcok) { UART_PUTS("Received garbage (CRC wrong after decryption): "); memcpy(bufx, rfm12_rx_buffer(), len); print_bytearray(bufx, len); } UART_PUTS("\r\n"); } //uart_hexdump((char *)bufcontents, rfm12_rx_len()); //UART_PUTS("\r\n"); // tell the implementation that the buffer can be reused for the next data. rfm12_rx_clear(); } // send data, if waiting in send buffer if (send_data_avail) { uint8_t i; // set AES key nr aes_key_nr = hex_to_uint8((uint8_t *)cmdbuf, 1); //UART_PUTF("AES KEY = %u\r\n", aes_key_nr); // init packet buffer memset(&bufx[0], 0, sizeof(bufx)); // set message type uint8_t message_type = hex_to_uint8((uint8_t *)cmdbuf, 3); pkg_header_set_messagetype(message_type); pkg_header_adjust_offset(); //UART_PUTF("MessageType = %u\r\n", message_type); uint8_t string_offset_data = 0; /* UART_PUTS("sKK00RRRRGGMM.............Get\r\n"); UART_PUTS("sKK01RRRRGGMMDD...........Set\r\n"); UART_PUTS("sKK02RRRRGGMMDD...........SetGet\r\n"); UART_PUTS("sKK08GGMMDD...............Status\r\n"); UART_PUTS("sKK09SSSSPPPPPPEE.........Ack\r\n"); UART_PUTS("sKK0ASSSSPPPPPPEEGGMMDD...AckStatus\r\n"); */ // set header extension fields to the values given as hex string in the user input switch (message_type) { case MESSAGETYPE_GET: case MESSAGETYPE_SET: case MESSAGETYPE_SETGET: pkg_headerext_common_set_receiverid(hex_to_uint16((uint8_t *)cmdbuf, 5)); pkg_headerext_common_set_messagegroupid(hex_to_uint8((uint8_t *)cmdbuf, 9)); pkg_headerext_common_set_messageid(hex_to_uint8((uint8_t *)cmdbuf, 11)); string_offset_data = 12; break; case MESSAGETYPE_STATUS: pkg_headerext_common_set_messagegroupid(hex_to_uint8((uint8_t *)cmdbuf, 5)); pkg_headerext_common_set_messageid(hex_to_uint8((uint8_t *)cmdbuf, 7)); string_offset_data = 8; break; case MESSAGETYPE_ACK: pkg_headerext_common_set_acksenderid(hex_to_uint16((uint8_t *)cmdbuf, 5)); pkg_headerext_common_set_ackpacketcounter(hex_to_uint24((uint8_t *)cmdbuf, 9)); pkg_headerext_common_set_error(hex_to_uint8((uint8_t *)cmdbuf, 15)); // fallthrough! case MESSAGETYPE_ACKSTATUS: pkg_headerext_common_set_messagegroupid(hex_to_uint8((uint8_t *)cmdbuf, 17)); pkg_headerext_common_set_messageid(hex_to_uint8((uint8_t *)cmdbuf, 19)); string_offset_data = 20; break; } uint8_t data_len_raw = 0; // copy message data, which exists in all packets except in Get and Ack packets if ((message_type != MESSAGETYPE_GET) && (message_type != MESSAGETYPE_ACK)) { uint8_t data_len_raw = (strlen(cmdbuf) - 1 - string_offset_data) / 2; //UART_PUTF("Data bytes = %u\r\n", data_len_raw); uint8_t start = __HEADEROFFSETBITS / 8; uint8_t shift = __HEADEROFFSETBITS % 8; // copy message data, using __HEADEROFFSETBITS value and string_offset_data for (i = 0; i < data_len_raw; i++) { uint8_t val = hex_to_uint8((uint8_t *)cmdbuf, string_offset_data + 2 * i + 1); array_write_UIntValue(start + i, shift, 8, val, bufx); } } // round packet length to x * 16 bytes uint8_t packet_len = ((uint16_t)__HEADEROFFSETBITS + (uint16_t)data_len_raw * 8) / 8; packet_len = ((packet_len - 1) / 16 + 1) * 16; // send packet which doesn't require an acknowledge immediately if ((message_type != MESSAGETYPE_GET) && (message_type != MESSAGETYPE_SET) && (message_type != MESSAGETYPE_SETGET)) { send_packet(aes_key_nr, packet_len); } else // enqueue request (don't send immediately) { // header size = 9 bytes! if (queue_request(pkg_headerext_common_get_receiverid(), message_type, aes_key_nr, bufx + 9, packet_len - 9)) { UART_PUTF("Request added to queue (%u bytes packet).\r\n", packet_len); } else { UART_PUTS("Warning! Request queue full. Packet will not be sent.\r\n"); } print_request_queue(); } // clear cmdbuf to receive more input from UART send_data_avail = false; rfm12_tick(); led_blink(200, 0, 1); } // flash LED every second to show the device is alive if (loop == 50) { led_blink(10, 10, 1); loop = 0; request_t* request = find_request_to_repeat(packetcounter + 1); if (request != 0) // if request to repeat was found in queue { UART_PUTS("Repeating request.\r\n"); send_packet((*request).aes_key, (*request).data_bytes + 9); // header size = 9 bytes! print_request_queue(); } // Auto-send something for debugging purposes... if (loop2 == 50) { //strcpy(cmdbuf, "s000102828300"); //send_data_avail = true; loop2 = 0; } else { loop2++; } } else { _delay_ms(20); } rfm12_tick(); loop++; process_rxbuf(); if (uart_timeout > 0) { uart_timeout--; if (uart_timeout == 0) { UART_PUTS("*** UART user timeout. Input was ignored. ***\r\n"); } } } // never called // aes256_done(&aes_ctx); }
int main ( void ) { uint8_t aes_key_nr; uint8_t loop = 0; uint8_t loop2 = 0; uint8_t data[22]; sbi(LED_DDR, LED_PIN); // delay 1s to avoid further communication with uart or RFM12 when my programmer resets the MC after 500ms... _delay_ms(1000); request_queue_init(); // read packetcounter, increase by cycle and write back packetcounter = eeprom_read_dword((uint32_t*)EEPROM_POS_PACKET_COUNTER) + PACKET_COUNTER_WRITE_CYCLE; eeprom_write_dword((uint32_t*)0, packetcounter); uart_init(true); UART_PUTS ("\r\n"); UART_PUTS ("Open Home Control Base Station V1.0\r\n"); UART_PUTS ("(c) 2012 Uwe Freese, www.open-home-control.com\r\n"); UART_PUTF ("Packet counter: %lu\r\n", packetcounter); UART_PUTS ("Waiting for incoming data. Press h for help.\r\n"); rfm12_init(); sei(); // ENCODE TEST /* uint8_t testlen = 64; eeprom_read_block (aes_key, (uint8_t *)EEPROM_POS_AES_KEY, 32); UART_PUTS("Using AES key "); printbytearray((uint8_t *)aes_key, 32); UART_PUTS("Before encryption: "); printbytearray(bufx, testlen); unsigned long crc = crc32(bufx, testlen); UART_PUTF("CRC32 is %lx (added as last 4 bytes)\r\n", crc); UART_PUTS("1\r\n"); crc = crc32(bufx, testlen - 4); UART_PUTS("2\r\n"); setBuf32(testlen - 4, crc); UART_PUTS("Before encryption (CRC added): "); printbytearray(bufx, testlen); UART_PUTS("1\r\n"); uint8_t aes_byte_count = aes256_encrypt_cbc(bufx, testlen); UART_PUTS("2\r\n"); UART_PUTS("After encryption: "); printbytearray(bufx, aes_byte_count); UART_PUTF("String len = %u\r\n", aes_byte_count); UART_PUTS("1\r\n"); aes256_decrypt_cbc(bufx, aes_byte_count); UART_PUTS("2\r\n"); UART_PUTS("After decryption: "); printbytearray(bufx, testlen); crc = getBuf32(testlen - 4); UART_PUTF("CRC32 is %lx (last 4 bytes from decrypted message)\r\n", crc); printbytearray(bufx, testlen); UART_PUTS("After decryption (CRC removed): "); printbytearray(bufx, testlen); UART_PUTF("String len = %u\r\n", testlen); while(1); */ while (42) { if (rfm12_rx_status() == STATUS_COMPLETE) { uint8_t len = rfm12_rx_len(); if ((len == 0) || (len % 16 != 0)) { UART_PUTF("Received garbage (%u bytes not multiple of 16): ", len); printbytearray(bufx, len); } else // try to decrypt with all keys stored in EEPROM { uint32_t assumed_crc; uint32_t actual_crc; for(aes_key_nr = 0; aes_key_nr < AES_KEY_EEPROM_COUNT ; aes_key_nr++) { //strncpy((char *)bufx, (char *)rfm12_rx_buffer(), len); memcpy(bufx, rfm12_rx_buffer(), len); /*if (aes_key_nr == 0) { UART_PUTS("Before decryption: "); printbytearray(bufx, len); }*/ eeprom_read_block (aes_key, (uint8_t *)(EEPROM_POS_AES_KEY + aes_key_nr * 32), 32); //UART_PUTS("Trying AES key "); //printbytearray((uint8_t *)aes_key, 32); aes256_decrypt_cbc(bufx, len); //UART_PUTS("Decrypted bytes: "); //printbytearray(bufx, len); assumed_crc = getBuf32(len - 4); actual_crc = crc32(bufx, len - 4); //UART_PUTF("Received CRC32 would be %lx\r\n", assumed_crc); //UART_PUTF("Re-calculated CRC32 is %lx\r\n", actual_crc); if (assumed_crc == actual_crc) { //UART_PUTS("CRC correct, AES key found!\r\n"); UART_PUTF("Received (AES key %u): ", aes_key_nr); printbytearray(bufx, len - 4); decode_data(len - 4); break; } } if (assumed_crc != actual_crc) { UART_PUTS("Received garbage (CRC wrong after decryption).\r\n"); } UART_PUTS("\r\n"); } //uart_hexdump((char *)bufcontents, rfm12_rx_len()); //UART_PUTS("\r\n"); // tell the implementation that the buffer can be reused for the next data. rfm12_rx_clear(); } // send data, if waiting in send buffer if (send_data_avail) { uint8_t i; uint8_t data_len_raw = strlen(sendbuf) / 2 - 2; // round data length to 6 + 16 bytes (including padding bytes) uint8_t data_len = (((data_len_raw + 9) / 16) + 1) * 16 - 10; // set aes key nr aes_key_nr = hex_to_uint8((uint8_t *)sendbuf, 0); //UART_PUTF("AES KEY = %u\r\n", aes_key_nr); // set command id uint8_t command_id = hex_to_uint8((uint8_t *)sendbuf, 2); // set data for (i = 0; i < data_len_raw; i++) { data[i] = hex_to_uint8((uint8_t *)sendbuf, 4 + 2 * i); } // set padding bytes for (i = data_len_raw; i < data_len; i++) { data[i] = 0; } // send status packet immediately (command IDs are less than 128) if (command_id < 128) { // set command id bufx[5] = command_id; // set data memcpy(bufx + 6, data, data_len); send_packet(aes_key_nr, data_len); } else // enqueue request (don't send immediately) { if (queue_request(data[0], command_id, aes_key_nr, data + 1)) { UART_PUTS("Adding request to queue.\r\n"); } else { UART_PUTS("Warning! Request queue full. Packet will not be sent.\r\n"); } print_request_queue(); } // clear send text buffer send_data_avail = false; rfm12_tick(); led_blink(200, 0, 1); } // flash LED every second to show the device is alive if (loop == 50) { led_blink(10, 10, 1); loop = 0; if (set_repeat_request(packetcounter + 1)) // if request to repeat was found in queue { UART_PUTS("Repeating request.\r\n"); send_packet(0, 6); print_request_queue(); } // Auto-send something for debugging purposes... if (loop2 == 50) { //strcpy(sendbuf, "008c0001003d"); //send_data_avail = true; loop2 = 0; } else { loop2++; } } else { _delay_ms(20); } rfm12_tick(); loop++; process_rxbuf(); if (uart_timeout > 0) { uart_timeout--; if (uart_timeout == 0) { UART_PUTS("*** UART user timeout. Input was ignored. ***\r\n"); } } } // never called // aes256_done(&aes_ctx); }
static int load_rite_irep_record(mrb_state *mrb, RiteFILE* rfp, unsigned char* dst, uint32_t* len) { int i; uint32_t blocklen; uint16_t offset, tt, pdl, snl, clen; unsigned char hex2[2], hex4[4], hex8[8], hcrc[4]; unsigned char *pStart; char *char_buf; uint16_t buf_size =0; buf_size = MRB_DUMP_DEFAULT_STR_LEN; if ((char_buf = mrb_malloc(mrb, buf_size)) == 0) goto error_exit; pStart = dst; //IREP HEADER BLOCK *dst = rite_fgetc(rfp, TRUE); //record identifier if (*dst != RITE_IREP_IDENFIFIER) return MRB_DUMP_INVALID_IREP; dst += sizeof(unsigned char); *dst = rite_fgetc(rfp, TRUE); //class or module dst += sizeof(unsigned char); rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //number of local variable dst += hex_to_bin16(dst, hex4); rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //number of register variable dst += hex_to_bin16(dst, hex4); rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //offset of isec block offset = hex_to_uint16(hex4); rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //header CRC memset( char_buf, '\0', buf_size); rite_fgets(rfp, (unsigned char*)char_buf, (offset - (MRB_DUMP_SIZE_OF_SHORT * RITE_FILE_HEX_SIZE)), TRUE); //class or module name hex_to_str(char_buf, (char*)(dst + MRB_DUMP_SIZE_OF_SHORT + MRB_DUMP_SIZE_OF_SHORT), &clen); //class or module name dst += uint16_to_bin((MRB_DUMP_SIZE_OF_SHORT/*crc*/ + clen), (char*)dst); //offset of isec block dst += hex_to_bin16(dst, hcrc); //header CRC dst += clen; //ISEQ BLOCK rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //iseq length dst += hex_to_bin32(dst, hex8); blocklen = hex_to_uint32(hex8); for (i=0; i<blocklen; i++) { rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //iseq dst += hex_to_bin32(dst, hex8); } rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //iseq CRC dst += hex_to_bin16(dst, hcrc); //POOL BLOCK rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //pool length dst += hex_to_bin32(dst, hex8); blocklen = hex_to_uint32(hex8); for (i=0; i<blocklen; i++) { rite_fgets(rfp, hex2, sizeof(hex2), TRUE); //TT dst += hex_to_bin8(dst, hex2); tt = hex_to_uint8(hex2); rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //pool data length pdl = hex_to_uint16(hex4); if ( pdl > buf_size - 1) { buf_size = pdl + 1; if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0) goto error_exit; } memset(char_buf, '\0', buf_size); rite_fgets(rfp, (unsigned char*)char_buf, pdl, FALSE); //pool hex_to_str(char_buf, (char*)(dst + MRB_DUMP_SIZE_OF_SHORT), &clen); dst += uint16_to_bin(clen, (char*)dst); dst += clen; } rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //pool CRC dst += hex_to_bin16(dst, hcrc); //SYMS BLOCK rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //syms length dst += hex_to_bin32(dst, hex8); blocklen = hex_to_uint32(hex8); for (i=0; i<blocklen; i++) { rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //symbol name length snl = hex_to_uint16(hex4); if (snl == MRB_DUMP_NULL_SYM_LEN) { dst += uint16_to_bin(snl, (char*)dst); continue; } if ( snl > buf_size - 1) { buf_size = snl + 1; if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0) goto error_exit; } memset(char_buf, '\0', buf_size); rite_fgets(rfp, (unsigned char*)char_buf, snl, FALSE); //symbol name hex_to_str(char_buf, (char*)(dst + MRB_DUMP_SIZE_OF_SHORT), &clen); dst += uint16_to_bin(clen, (char*)dst); dst += clen; } rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //syms CRC dst += hex_to_bin16(dst, hcrc); *len = dst - pStart; error_exit: if (char_buf) mrb_free(mrb, char_buf); return MRB_DUMP_OK; }
// Process the user command now contained in the cmdbuf array. void process_cmd(void) { uart_putstr("Processing command: "); uart_putstr(cmdbuf); UART_PUTS("\r\n"); if ((cmdbuf[0] == 'w') && (strlen(cmdbuf) == 5)) // E2P write command { if (enable_write_eeprom) { uint16_t adr = hex_to_uint8((uint8_t *)cmdbuf, 1); uint8_t val = hex_to_uint8((uint8_t *)cmdbuf, 3); UART_PUTF2("Writing data 0x%x to EEPROM pos 0x%x.\r\n", val, adr); eeprom_write_byte((uint8_t *)adr, val); } else { UART_PUTS("Ignoring EEPROM write, since write mode is DISABLED.\r\n"); } } else if ((cmdbuf[0] == 'r') && (strlen(cmdbuf) == 3)) // E2P read command { uint16_t adr = hex_to_uint8((uint8_t *)cmdbuf, 1); uint8_t val = eeprom_read_byte((uint8_t *)adr); UART_PUTF2("EEPROM value at position 0x%x is 0x%x.\r\n", adr, val); } else if ((cmdbuf[0] == 's') && (strlen(cmdbuf) > 6)) // "send" command { send_data_avail = true; } else if ((cmdbuf[0] == 'c') && (strlen(cmdbuf) > 14)) // "send" command with CRC { uint8_t len = strlen(cmdbuf); // Warning! The following two lines were originally in the reverse order. // This obviously should not change anything. // But the "avr-gcc (GCC) 4.7.2" on my linux machine produced a firmware // which resulted in a wrong "calculated_crc" (whereas the // "avr-gcc (WinAVR 20100110) 4.3.3" on my Windows machine didn't). // I could recalculate the calculated_crc a 2nd time, call a UART_PUTS // or some other commands, which all produced a firmware which did not // have this issue. It's unknown why the GCC 4.7.2 produced this // wrong output. // Current workaround: I reversed the following two lines. uint32_t given_crc = hex_to_uint32((uint8_t *)cmdbuf, len - 8); uint32_t calculated_crc = crc32((uint8_t *)cmdbuf, len - 8); if (calculated_crc != given_crc) { UART_PUTF("CRC Error! %08lx does not match. Ignoring command.\r\n", calculated_crc); } else { cmdbuf[len - 8] = 0; // strip CRC from command send_data_avail = true; } } else { UART_PUTS("Unknown command.\r\n"); } }