diff --git a/components/bluetooth/ble_profiles/esp/ble_ota/src/nimble_ota.c b/components/bluetooth/ble_profiles/esp/ble_ota/src/nimble_ota.c index d8f105e37..e4b482234 100644 --- a/components/bluetooth/ble_profiles/esp/ble_ota/src/nimble_ota.c +++ b/components/bluetooth/ble_profiles/esp/ble_ota/src/nimble_ota.c @@ -86,7 +86,8 @@ static uint16_t receive_fw_val; static uint16_t ota_status_val; static uint16_t command_val; static uint16_t custom_val; - +static uint16_t sector_crc = 0; +static uint16_t crc16_cal = 0; static int esp_ble_ota_gap_event(struct ble_gap_event *event, void *arg); static esp_ble_ota_char_t @@ -99,6 +100,7 @@ esp_ble_ota_notification_data(uint16_t conn_handle, uint16_t attr_handle, uint8_ /*---------------------------------------------------- * Common api's *----------------------------------------------------*/ +static uint16_t crc16_ccitt_update(uint16_t crc16, uint8_t *buf, int len);//Crc with crc16 input void ble_store_config_init(void); static uint16_t @@ -128,9 +130,12 @@ esp_ble_ota_write_chr(struct os_mbuf *om) err = os_mbuf_copydata(om, 3, pargs.data_in_len, pargs.data_in); if (om->om_data[2] == 0xff) { + uint8_t crc1 = pargs.data_in[pargs.data_in_len - 2]; + uint8_t crc2 = pargs.data_in[pargs.data_in_len - 1]; + sector_crc = crc2 << 8 | crc1; pargs.data_in_len -= SECTOR_END_ID; } - + crc16_cal = crc16_ccitt_update(crc16_cal, pargs.data_in, pargs.data_in_len); err = esp_encrypted_img_decrypt_data(decrypt_handle_cmp, &pargs); if (err != ESP_OK && err != ESP_ERR_NOT_FINISHED) { return; @@ -211,7 +216,6 @@ esp_ble_ota_write_chr(struct os_mbuf *om) #endif if (om->om_data[2] == 0xff) { cur_packet = 0; - cur_sector++; ESP_LOGD(TAG, "DEBUG: recv %" PRIu32 " sector", cur_sector); goto sector_end; } else { @@ -221,18 +225,38 @@ esp_ble_ota_write_chr(struct os_mbuf *om) return; sector_end: + // Check crc + #ifndef CONFIG_PRE_ENC_OTA + crc16_cal = crc16_ccitt(fw_buf, fw_buf_offset - 2); + sector_crc = fw_buf[fw_buf_offset - 1] << 8 | fw_buf[fw_buf_offset - 2]; + #endif + bool match = (sector_crc == crc16_cal ? true : false); + ESP_LOGD(TAG, "DEBUG : Get crc is %d ,cal crc is %d ,reseult is %d", sector_crc, crc16_cal, match); + sector_crc = 0; + crc16_cal = 0; + if (match){ + cur_sector++; if (fw_buf_offset < ota_block_size) { esp_ble_ota_recv_fw_handler(fw_buf, fw_buf_offset); } else { esp_ble_ota_recv_fw_handler(fw_buf, 4096); } + } fw_buf_offset = 0; memset(fw_buf, 0x0, ota_block_size); cmd_ack[0] = om->om_data[0]; cmd_ack[1] = om->om_data[1]; - cmd_ack[2] = 0x00; //success + if (match){ + cmd_ack[2] = 0x00; // success + }else + { + cmd_ack[2] = 0x01; // crc error + // Request the sector again + cmd_ack[4] = cur_sector & 0xff; + cmd_ack[5] = (cur_sector & 0xff00) >> 8; + } cmd_ack[3] = 0x00; crc16 = crc16_ccitt(cmd_ack, 18); cmd_ack[18] = crc16 & 0xff; @@ -262,6 +286,29 @@ static uint16_t crc16_ccitt(const unsigned char *buf, int len) return crc16; } +static uint16_t crc16_ccitt_update(uint16_t crc16, uint8_t *buf, int len) +{ + int32_t i; + + while (len--) + { + crc16 ^= *buf++ << 8; + + for (i = 0; i < 8; i++) + { + if (crc16 & 0x8000) + { + crc16 = (crc16 << 1) ^ 0x1021; + } + else + { + crc16 = crc16 << 1; + } + } + } + + return crc16; +} void esp_ble_ota_set_fw_length(uint32_t length) {