mirror of
https://github.com/Lurkars/esp-ena.git
synced 2024-11-22 10:06:11 +01:00
prepare interface, moved from loop to tasks, replace loops with memcpy, fixed shift_deletion
This commit is contained in:
parent
7bdbe82914
commit
30be89fedb
@ -5,9 +5,11 @@
|
||||
Implementation of the Covid-19 Exposure Notification API by Apple and Google on an ESP32 (with ESP-IDF).
|
||||
More information about the Covid-19 Exposure Notification at [Apple](https://www.apple.com/covid19/contacttracing/) and [Google](https://www.google.com/covid19/exposurenotifications/). This is meant for people without smartphone or without smartphones with Apples/Googles implementation.
|
||||
|
||||
[Demo Video](https://twitter.com/Lurkars/status/1282223547579019264)
|
||||
|
||||
This implementation covers for now the BLE part including the cryptography specifications needed (see Bluetooth Specifications and Cryptography Specifications documents in the links above):
|
||||
* send tokens
|
||||
* store send tokens on flash (last 14 tokens)
|
||||
* store TEKs on flash (last 14 tokens)
|
||||
* receive tokens
|
||||
* received tokens are stored after 5 minutes threshold (storage is limited, ~100k tokens can be stored)
|
||||
|
||||
@ -23,7 +25,7 @@ Extensions planned:
|
||||
* delete tokens
|
||||
* show status
|
||||
* report infection?
|
||||
* receive infected token list for Germany (will test [Corona Warn App](https://github.com/corona-warn-app))
|
||||
* receive infected token list (will test [Corona Warn App](https://github.com/corona-warn-app))
|
||||
* send infected status (will test [Corona Warn App](https://github.com/corona-warn-app))
|
||||
* battery support
|
||||
* 3d print case
|
||||
|
@ -1,4 +1,4 @@
|
||||
idf_component_register(
|
||||
SRCS "ena-detection.c" "ena-storage.c" "ena-crypto.c" "main.c" "ena.c" "ena-bluetooth-scan.c" "ena-bluetooth-advertise.c" "ena-detection.c"
|
||||
SRCS "ena-detection.c" "ena-storage.c" "ena-crypto.c" "main.c" "ena.c" "ena-bluetooth-scan.c" "ena-bluetooth-advertise.c" "ena-detection.c" "ena-interface.c"
|
||||
INCLUDE_DIRS ""
|
||||
)
|
||||
|
@ -19,7 +19,7 @@ void ena_bluetooth_advertise_start(void)
|
||||
ESP_ERROR_CHECK(esp_ble_gap_start_advertising(&ena_adv_params));
|
||||
}
|
||||
|
||||
void ena_bluetooth_advertise_set_payload(uint32_t enin, uint8_t tek[])
|
||||
void ena_bluetooth_advertise_set_payload(uint32_t enin, uint8_t *tek)
|
||||
{
|
||||
uint8_t rpik[ENA_KEY_LENGTH] = {0};
|
||||
uint8_t rpi[ENA_KEY_LENGTH] = {0};
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
void ena_bluetooth_advertise_start(void);
|
||||
|
||||
void ena_bluetooth_advertise_set_payload(uint32_t enin, uint8_t tek[]);
|
||||
void ena_bluetooth_advertise_set_payload(uint32_t enin, uint8_t *tek);
|
||||
|
||||
void ena_bluetooth_advertise_stop(void);
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
@ -10,6 +9,8 @@
|
||||
|
||||
static int scan_status = ENA_SCAN_STATUS_NOT_SCANNING;
|
||||
|
||||
static const uint16_t ENA_SERVICE_UUID = 0xFD6F;
|
||||
|
||||
static esp_ble_scan_params_t ena_scan_params = {
|
||||
.scan_type = BLE_SCAN_TYPE_ACTIVE,
|
||||
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
|
||||
@ -34,36 +35,25 @@ void ena_bluetooth_scan_event_callback(esp_gap_ble_cb_event_t event, esp_ble_gap
|
||||
case ESP_GAP_BLE_SCAN_RESULT_EVT:
|
||||
if (p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT)
|
||||
{
|
||||
if (p->scan_rst.adv_data_len < 28)
|
||||
uint8_t service_uuid_length = 0;
|
||||
uint8_t *service_uuid_data = esp_ble_resolve_adv_data(p->scan_rst.ble_adv, 0x03, &service_uuid_length);
|
||||
// check for ENA Service UUID
|
||||
if (service_uuid_length == sizeof(ENA_SERVICE_UUID) && memcmp(service_uuid_data, &ENA_SERVICE_UUID, service_uuid_length) == 0)
|
||||
{
|
||||
// adv_data too short for exposure notification
|
||||
uint8_t service_data_length = 0;
|
||||
uint8_t *service_data = esp_ble_resolve_adv_data(p->scan_rst.ble_adv, 0x16, &service_data_length);
|
||||
if (service_data_length != (sizeof(ENA_SERVICE_UUID) + ENA_KEY_LENGTH + ENA_AEM_METADATA_LENGTH)) {
|
||||
ESP_LOGW(ENA_SCAN_LOG, "received ENA Service with invalid payload");
|
||||
break;
|
||||
}
|
||||
|
||||
int flag_offset = 0;
|
||||
// received payload from Google does not contain flag specified in Bluetooth Specification!? So check for length and then add offset
|
||||
if (p->scan_rst.adv_data_len == 31)
|
||||
{
|
||||
// data contains flag
|
||||
flag_offset = 3;
|
||||
}
|
||||
|
||||
// check for ENA Service UUID: (after flag 0x03 0x03 0x6f 0xfd for ENA service)
|
||||
if (p->scan_rst.ble_adv[0 + flag_offset] == 0x3 && p->scan_rst.ble_adv[1 + flag_offset] == 0x3 && p->scan_rst.ble_adv[2 + flag_offset] == 0x6f && p->scan_rst.ble_adv[3 + flag_offset] == 0xfd)
|
||||
{
|
||||
uint8_t rpi[ENA_KEY_LENGTH] = {0};
|
||||
for (int i = 0; i < ENA_KEY_LENGTH; i++)
|
||||
{
|
||||
rpi[i] = p->scan_rst.ble_adv[i + 8 + flag_offset];
|
||||
}
|
||||
|
||||
uint8_t aem[ENA_AEM_METADATA_LENGTH] = {0};
|
||||
for (int i = 0; i < ENA_AEM_METADATA_LENGTH; i++)
|
||||
{
|
||||
aem[i] = p->scan_rst.ble_adv[i + ENA_KEY_LENGTH + 8 + flag_offset];
|
||||
}
|
||||
|
||||
uint8_t *rpi = malloc(ENA_KEY_LENGTH);
|
||||
memcpy(rpi, &service_data[sizeof(ENA_SERVICE_UUID)], ENA_KEY_LENGTH);
|
||||
uint8_t *aem = malloc(ENA_AEM_METADATA_LENGTH);
|
||||
memcpy(aem, &service_data[sizeof(ENA_SERVICE_UUID) + ENA_KEY_LENGTH], ENA_AEM_METADATA_LENGTH);
|
||||
ena_detection((uint32_t)time(NULL), rpi, aem, p->scan_rst.rssi);
|
||||
free(rpi);
|
||||
free(aem);
|
||||
}
|
||||
}
|
||||
else if (p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_CMPL_EVT)
|
||||
|
@ -33,7 +33,7 @@ uint32_t ena_crypto_enin(uint32_t unix_epoch_time)
|
||||
return unix_epoch_time / ENA_TIME_WINDOW;
|
||||
}
|
||||
|
||||
void ena_crypto_tek(uint8_t tek[])
|
||||
void ena_crypto_tek(uint8_t *tek)
|
||||
{
|
||||
int ret;
|
||||
if ((ret = mbedtls_ctr_drbg_random(&ctr_drbg, tek, ENA_KEY_LENGTH)) != 0)
|
||||
@ -42,15 +42,15 @@ void ena_crypto_tek(uint8_t tek[])
|
||||
}
|
||||
}
|
||||
|
||||
void ena_crypto_rpik(uint8_t rpik[], uint8_t tek[])
|
||||
void ena_crypto_rpik(uint8_t *rpik, uint8_t *tek)
|
||||
{
|
||||
const uint8_t rpik_info[] = "EN-RPIK";
|
||||
mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), NULL, 0, tek, ENA_KEY_LENGTH, rpik_info, sizeof(rpik_info), rpik, ENA_KEY_LENGTH);
|
||||
}
|
||||
|
||||
void ena_crypto_rpi(uint8_t rpi[], uint8_t rpik[], uint32_t enin)
|
||||
void ena_crypto_rpi(uint8_t *rpi, uint8_t *rpik, uint32_t enin)
|
||||
{
|
||||
uint8_t padded_data[ENA_KEY_LENGTH] = "EN-RPI";
|
||||
uint8_t padded_data[] = "EN-RPI";
|
||||
padded_data[12] = (enin & 0x000000ff);
|
||||
padded_data[13] = (enin & 0x0000ff00) >> 8;
|
||||
padded_data[14] = (enin & 0x00ff0000) >> 16;
|
||||
@ -63,13 +63,13 @@ void ena_crypto_rpi(uint8_t rpi[], uint8_t rpik[], uint32_t enin)
|
||||
mbedtls_aes_free(&aes);
|
||||
}
|
||||
|
||||
void ena_crypto_aemk(uint8_t aemk[], uint8_t tek[])
|
||||
void ena_crypto_aemk(uint8_t *aemk, uint8_t *tek)
|
||||
{
|
||||
uint8_t aemkInfo[] = "EN-AEMK";
|
||||
mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), NULL, 0, tek, ENA_KEY_LENGTH, aemkInfo, sizeof(aemkInfo), aemk, ENA_KEY_LENGTH);
|
||||
}
|
||||
|
||||
void ena_crypto_aem(uint8_t aem[], uint8_t aemk[], uint8_t rpi[], uint8_t power_level)
|
||||
void ena_crypto_aem(uint8_t *aem, uint8_t *aemk, uint8_t *rpi, uint8_t power_level)
|
||||
{
|
||||
uint8_t metadata[ENA_AEM_METADATA_LENGTH];
|
||||
metadata[0] = 0b01000000;
|
||||
|
@ -35,26 +35,26 @@ uint32_t ena_crypto_enin(uint32_t seconds);
|
||||
/**
|
||||
* calculate a new random Temporary Exposure Key (TEK)
|
||||
*/
|
||||
void ena_crypto_tek(uint8_t tek[]);
|
||||
void ena_crypto_tek(uint8_t *tek);
|
||||
|
||||
/**
|
||||
* calculate a new Rolling Proximity Identifier Key (RPIK) with given TEK
|
||||
*/
|
||||
void ena_crypto_rpik(uint8_t rpik[], uint8_t tek[]);
|
||||
void ena_crypto_rpik(uint8_t *rpik, uint8_t *tek);
|
||||
|
||||
/**
|
||||
* calculate a new Rolling Proximity Identifier with given RPIK and ENIN
|
||||
*/
|
||||
void ena_crypto_rpi(uint8_t rpi[], uint8_t rpik[], uint32_t enin);
|
||||
void ena_crypto_rpi(uint8_t *rpi, uint8_t *rpik, uint32_t enin);
|
||||
|
||||
/**
|
||||
* calculate a new Associated Encrypted Metadata Key (AEMK) with given TEK
|
||||
*/
|
||||
void ena_crypto_aemk(uint8_t aemk[], uint8_t tek[]);
|
||||
void ena_crypto_aemk(uint8_t *aemk, uint8_t *tek);
|
||||
|
||||
/**
|
||||
* create Associated Encrypted Metadata (AEM) with given AEMK along the RPI
|
||||
*/
|
||||
void ena_crypto_aem(uint8_t aem[], uint8_t aemk[], uint8_t rpi[], uint8_t power_level);
|
||||
void ena_crypto_aem(uint8_t *aem, uint8_t *aemk, uint8_t *rpi, uint8_t power_level);
|
||||
|
||||
#endif
|
@ -13,7 +13,7 @@ static uint32_t temp_detection_timestamp_first[ENA_STOARGE_TEMP_DETECTIONS_MAX]
|
||||
static uint32_t temp_detection_timestamp_last[ENA_STOARGE_TEMP_DETECTIONS_MAX] = {0};
|
||||
static int temp_detection_rssi_last[ENA_STOARGE_TEMP_DETECTIONS_MAX] = {0};
|
||||
|
||||
int ena_get_temp_detection_index(uint8_t rpi[], uint8_t aem[])
|
||||
int ena_get_temp_detection_index(uint8_t *rpi, uint8_t *aem)
|
||||
{
|
||||
for (int i = 0; i < temp_detections_count; i++)
|
||||
{
|
||||
@ -53,6 +53,7 @@ void ena_detections_temp_refresh(uint32_t unix_timestamp)
|
||||
for (int i = 0; i < temp_detections_count; i++)
|
||||
{
|
||||
ena_storage_read_temp_detection(i, &temp_detection_timestamp_first[i], temp_detection_rpi[i], temp_detection_aem[i], &temp_detection_rssi_last[i]);
|
||||
temp_detection_timestamp_last[i] = temp_detection_timestamp_first[i];
|
||||
}
|
||||
|
||||
// DEBUG dump
|
||||
@ -61,7 +62,7 @@ void ena_detections_temp_refresh(uint32_t unix_timestamp)
|
||||
ena_storage_dump_detections();
|
||||
}
|
||||
|
||||
void ena_detection(uint32_t unix_timestamp, uint8_t rpi[], uint8_t aem[], int rssi)
|
||||
void ena_detection(uint32_t unix_timestamp, uint8_t *rpi, uint8_t *aem, int rssi)
|
||||
{
|
||||
uint32_t detection_index = ena_get_temp_detection_index(rpi, aem);
|
||||
|
||||
|
@ -14,6 +14,6 @@
|
||||
|
||||
void ena_detections_temp_refresh(uint32_t unix_timestamp);
|
||||
|
||||
void ena_detection(uint32_t unix_timestamp, uint8_t rpi[], uint8_t aem[], int rssi);
|
||||
void ena_detection(uint32_t unix_timestamp, uint8_t *rpi, uint8_t *aem, int rssi);
|
||||
|
||||
#endif
|
65
main/ena-interface.c
Normal file
65
main/ena-interface.c
Normal file
@ -0,0 +1,65 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "driver/touch_pad.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "ena-interface.h"
|
||||
|
||||
static int interface_state = ENA_INTERFACE_STATE_MENU;
|
||||
|
||||
static bool touch_status[TOUCH_PAD_MAX] = {0};
|
||||
static ena_interface_touch_callback touch_callbacks[TOUCH_PAD_MAX];
|
||||
|
||||
void ena_interface_register_touch_callback(int touch_pad, ena_interface_touch_callback callback)
|
||||
{
|
||||
touch_callbacks[touch_pad] = callback;
|
||||
};
|
||||
|
||||
void ena_interface_run(void *pvParameter)
|
||||
{
|
||||
uint16_t touch_value;
|
||||
bool touch_status_current[4] = {0};
|
||||
while (1)
|
||||
{
|
||||
for (int i = 0; i < TOUCH_PAD_MAX; i++)
|
||||
{
|
||||
|
||||
touch_pad_read_filtered(i, &touch_value);
|
||||
touch_status_current[i] = touch_value < TOUCHPAD_TOUCH_THRESHOLD;
|
||||
|
||||
if (!touch_status[i] & touch_status_current[i] && touch_callbacks[i] != NULL)
|
||||
{
|
||||
(*touch_callbacks[i])();
|
||||
}
|
||||
touch_status[i] = touch_status_current[i];
|
||||
}
|
||||
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
void ena_interface_start(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(touch_pad_init());
|
||||
ESP_ERROR_CHECK(touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V));
|
||||
ESP_ERROR_CHECK(touch_pad_set_trigger_mode(TOUCH_TRIGGER_BELOW));
|
||||
ESP_ERROR_CHECK(touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD));
|
||||
ESP_ERROR_CHECK(touch_pad_config(TOUCH_PAD_ESC, TOUCHPAD_TOUCH_THRESHOLD));
|
||||
ESP_ERROR_CHECK(touch_pad_config(TOUCH_PAD_OK, TOUCHPAD_TOUCH_THRESHOLD));
|
||||
ESP_ERROR_CHECK(touch_pad_config(TOUCH_PAD_UP, TOUCHPAD_TOUCH_THRESHOLD));
|
||||
ESP_ERROR_CHECK(touch_pad_config(TOUCH_PAD_DOWN, TOUCHPAD_TOUCH_THRESHOLD));
|
||||
xTaskCreate(&ena_interface_run, "ena_interface_run", configMINIMAL_STACK_SIZE, NULL, 5, NULL);
|
||||
}
|
||||
|
||||
int ena_interface_get_state(void)
|
||||
{
|
||||
return interface_state;
|
||||
}
|
||||
|
||||
void ena_interface_set_state(ena_inerface_state state)
|
||||
{
|
||||
interface_state = state;
|
||||
}
|
43
main/ena-interface.h
Normal file
43
main/ena-interface.h
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Interface for different operations
|
||||
*
|
||||
*/
|
||||
#include "driver/touch_pad.h"
|
||||
|
||||
#ifndef _ena_INTERFACE_H_
|
||||
#define _ena_INTERFACE_H_
|
||||
|
||||
#define ENA_INTERFACE_LOG "ESP-ENA-interface" // TAG for Logging
|
||||
|
||||
#define TOUCHPAD_FILTER_TOUCH_PERIOD (10)
|
||||
#define TOUCHPAD_TOUCH_THRESHOLD (600)
|
||||
|
||||
#define TOUCH_PAD_ESC (TOUCH_PAD_NUM0)
|
||||
#define TOUCH_PAD_OK (TOUCH_PAD_NUM6)
|
||||
#define TOUCH_PAD_UP (TOUCH_PAD_NUM4)
|
||||
#define TOUCH_PAD_DOWN (TOUCH_PAD_NUM3)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ENA_INTERFACE_STATE_IDLE = 0,
|
||||
ENA_INTERFACE_STATE_MENU,
|
||||
ENA_INTERFACE_STATE_SET_YEAR,
|
||||
ENA_INTERFACE_STATE_SET_MONTH,
|
||||
ENA_INTERFACE_STATE_SET_DAY,
|
||||
ENA_INTERFACE_STATE_SET_HOUR,
|
||||
ENA_INTERFACE_STATE_SET_MINUTE,
|
||||
ENA_INTERFACE_STATE_SET_SECONDS,
|
||||
ENA_INTERFACE_STATE_STATUS,
|
||||
} ena_inerface_state;
|
||||
|
||||
typedef void (*ena_interface_touch_callback)(void);
|
||||
|
||||
void ena_interface_register_touch_callback(int touch_pad, ena_interface_touch_callback callback);
|
||||
|
||||
int ena_interface_get_state(void);
|
||||
|
||||
void ena_interface_set_state(ena_inerface_state state);
|
||||
|
||||
void ena_interface_start(void);
|
||||
|
||||
#endif
|
@ -23,7 +23,7 @@ void ena_storage_read(size_t address, uint8_t *data, size_t size)
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "END ena_storage_read");
|
||||
}
|
||||
|
||||
void ena_storage_write(size_t address, uint8_t data[], size_t size)
|
||||
void ena_storage_write(size_t address, uint8_t *data, size_t size)
|
||||
{
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "START ena_storage_write");
|
||||
const esp_partition_t *partition = esp_partition_find_first(
|
||||
@ -36,7 +36,7 @@ void ena_storage_write(size_t address, uint8_t data[], size_t size)
|
||||
if (address + size > (block_num + 1) * BLOCK_SIZE)
|
||||
{
|
||||
|
||||
ESP_LOGI(ENA_STORAGE_LOG, "overflow block at address %u with size %d (block %d)", address, size, block_num);
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "overflow block at address %u with size %d (block %d)", address, size, block_num);
|
||||
const size_t block1_address = address;
|
||||
const size_t block2_address = (block_num + 1) * BLOCK_SIZE;
|
||||
const size_t data2_size = address + size - block2_address;
|
||||
@ -44,18 +44,12 @@ void ena_storage_write(size_t address, uint8_t data[], size_t size)
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "block1_address %d, block1_size %d (block %d)", block1_address, data1_size, block_num);
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "block2_address %d, block2_size %d (block %d)", block2_address, data2_size, block_num + 1);
|
||||
uint8_t *data1 = malloc(data1_size);
|
||||
for (int i = 0; i < data1_size; i++)
|
||||
{
|
||||
data1[i] = data[i];
|
||||
}
|
||||
uint8_t *data2 = malloc(data2_size);
|
||||
for (int i = 0; i < data2_size; i++)
|
||||
{
|
||||
data2[i] = data[data1_size + i];
|
||||
}
|
||||
|
||||
memcpy(data1, data, data1_size);
|
||||
ena_storage_write(block1_address, data1, data1_size);
|
||||
free(data1);
|
||||
|
||||
uint8_t *data2 = malloc(data2_size);
|
||||
memcpy(data2, &data[data1_size], data2_size);
|
||||
ena_storage_write(block2_address, data2, data2_size);
|
||||
free(data2);
|
||||
}
|
||||
@ -74,10 +68,8 @@ void ena_storage_write(size_t address, uint8_t data[], size_t size)
|
||||
vTaskDelay(1);
|
||||
ESP_ERROR_CHECK(esp_partition_erase_range(partition, block_start, BLOCK_SIZE));
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
buffer[block_address + i] = data[i];
|
||||
}
|
||||
memcpy(&buffer[block_address], data, size);
|
||||
|
||||
ESP_ERROR_CHECK(esp_partition_write(partition, block_start, buffer, BLOCK_SIZE));
|
||||
free(buffer);
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "write data at %u", address);
|
||||
@ -86,53 +78,69 @@ void ena_storage_write(size_t address, uint8_t data[], size_t size)
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "END ena_storage_write");
|
||||
}
|
||||
|
||||
void ena_storage_shift_delete(size_t address, size_t size)
|
||||
void ena_storage_shift_delete(size_t address, size_t end_address, size_t size)
|
||||
{
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "START ena_storage_shift_delete");
|
||||
|
||||
int block_num_start = address / BLOCK_SIZE;
|
||||
// split if size extends block
|
||||
if (address + size > (block_num_start + 1) * BLOCK_SIZE)
|
||||
{
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "overflow block at address %u with size %d (block %d)", address, size, block_num_start);
|
||||
const size_t block1_address = address;
|
||||
const size_t block2_address = (block_num_start + 1) * BLOCK_SIZE;
|
||||
const size_t data2_size = address + size - block2_address;
|
||||
const size_t data1_size = size - data2_size;
|
||||
ena_storage_shift_delete(block1_address, end_address, data1_size);
|
||||
ena_storage_shift_delete(block2_address, end_address - data1_size, data2_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
const esp_partition_t *partition = esp_partition_find_first(
|
||||
ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARTITION_NAME);
|
||||
assert(partition);
|
||||
|
||||
const int block_num = address / BLOCK_SIZE;
|
||||
|
||||
// split if size extends block TODO this does not work like this!!! Shift puts data back to first block!
|
||||
if (address + size > (block_num + 1) * BLOCK_SIZE)
|
||||
int block_num_end = end_address / BLOCK_SIZE;
|
||||
size_t block_start = address - block_num_start * BLOCK_SIZE;
|
||||
while (block_num_end >= block_num_start)
|
||||
{
|
||||
const int block1_address = address;
|
||||
const int block2_address = (block_num + 1) * BLOCK_SIZE;
|
||||
const int data2_size = address + size - block2_address;
|
||||
const int data1_size = size - data2_size;
|
||||
ena_storage_shift_delete(block1_address, data1_size);
|
||||
ena_storage_shift_delete(block2_address, data2_size);
|
||||
|
||||
uint8_t *buffer = malloc(BLOCK_SIZE);
|
||||
ESP_ERROR_CHECK(esp_partition_read(partition, block_num_start * BLOCK_SIZE, buffer, BLOCK_SIZE));
|
||||
vTaskDelay(1);
|
||||
// shift inside buffer
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "shift block %d from %u to %u with size %u", block_num_start, (block_start + size), block_start, (BLOCK_SIZE - block_start - size));
|
||||
memcpy(&buffer[block_start], &buffer[block_start + size], BLOCK_SIZE - block_start - size);
|
||||
if (block_num_end > block_num_start)
|
||||
{
|
||||
uint8_t *buffer_next_block = malloc(BLOCK_SIZE);
|
||||
|
||||
ESP_ERROR_CHECK(esp_partition_read(partition, (block_num_start + 1) * BLOCK_SIZE, buffer_next_block, BLOCK_SIZE));
|
||||
vTaskDelay(1);
|
||||
// shift from next block
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "shift next block size %u", size);
|
||||
memcpy(&buffer[BLOCK_SIZE - size], &buffer_next_block[0], size);
|
||||
free(buffer_next_block);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int block_start = block_num * BLOCK_SIZE;
|
||||
const int block_address = address - block_start;
|
||||
uint8_t *buffer = malloc(BLOCK_SIZE);
|
||||
ESP_ERROR_CHECK(esp_partition_read(partition, block_start, buffer, BLOCK_SIZE));
|
||||
vTaskDelay(1);
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "shift block from %u to %u with size %u (move %u)", block_address, block_address + size, size, BLOCK_SIZE - address + size);
|
||||
// shift manually
|
||||
for (int i = block_address + size; i < BLOCK_SIZE; i++)
|
||||
{
|
||||
buffer[i - size] = buffer[i];
|
||||
// fill end with zeros
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "fill with zeros %u", size);
|
||||
memset(&buffer[BLOCK_SIZE - size], 0, size);
|
||||
}
|
||||
|
||||
for (int i = BLOCK_SIZE - size; i < BLOCK_SIZE; i++)
|
||||
{
|
||||
buffer[i] = 0;
|
||||
}
|
||||
// memmove seems to lead to corrupt heap memory!
|
||||
// memmove(&buffer[block_address], &buffer[block_address + size], BLOCK_SIZE - address + size);
|
||||
ESP_ERROR_CHECK(esp_partition_erase_range(partition, block_start, BLOCK_SIZE));
|
||||
ESP_ERROR_CHECK(esp_partition_write(partition, block_start, buffer, BLOCK_SIZE));
|
||||
ESP_ERROR_CHECK(esp_partition_erase_range(partition, block_num_start * BLOCK_SIZE, BLOCK_SIZE));
|
||||
ESP_ERROR_CHECK(esp_partition_write(partition, block_num_start * BLOCK_SIZE, buffer, BLOCK_SIZE));
|
||||
free(buffer);
|
||||
|
||||
block_num_start++;
|
||||
block_start = 0;
|
||||
}
|
||||
}
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "END ena_storage_shift_delete");
|
||||
}
|
||||
|
||||
void ena_storage_write_tek(uint32_t enin, uint8_t tek[])
|
||||
void ena_storage_write_tek(uint32_t enin, uint8_t *tek)
|
||||
{
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "START ena_storage_write_tek");
|
||||
uint8_t tek_count = ena_storage_read_u8(ENA_STORAGE_TEK_COUNT_ADDRESS);
|
||||
@ -169,7 +177,7 @@ uint32_t ena_storage_read_enin(void)
|
||||
return result;
|
||||
}
|
||||
|
||||
void ena_storage_read_tek(uint8_t tek[])
|
||||
void ena_storage_read_tek(uint8_t *tek)
|
||||
{
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "START ena_storage_read_tek");
|
||||
uint8_t tek_count = ena_storage_read_u8(ENA_STORAGE_TEK_COUNT_ADDRESS);
|
||||
@ -195,7 +203,7 @@ uint32_t ena_storage_temp_detections_count(void)
|
||||
return count;
|
||||
}
|
||||
|
||||
uint32_t ena_storage_write_temp_detection(uint32_t timestamp, uint8_t rpi[], uint8_t aem[], int rssi)
|
||||
uint32_t ena_storage_write_temp_detection(uint32_t timestamp, uint8_t *rpi, uint8_t *aem, int rssi)
|
||||
{
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "START ena_storage_write_temp_detection");
|
||||
uint32_t count = ena_storage_temp_detections_count() + 1;
|
||||
@ -224,7 +232,7 @@ uint32_t ena_storage_write_temp_detection(uint32_t timestamp, uint8_t rpi[], uin
|
||||
return count - 1;
|
||||
}
|
||||
|
||||
void ena_storage_read_temp_detection(uint32_t index, uint32_t *timestamp, uint8_t rpi[], uint8_t aem[], int *rssi)
|
||||
void ena_storage_read_temp_detection(uint32_t index, uint32_t *timestamp, uint8_t *rpi, uint8_t *aem, int *rssi)
|
||||
{
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "START ena_storage_read_temp_detection");
|
||||
size_t address = ENA_STORAGE_TEMP_DETECTIONS_START_ADDRESS + index * ENA_STORAGE_DETECTION_LENGTH;
|
||||
@ -247,9 +255,9 @@ void ena_storage_remove_temp_detection(uint32_t index)
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "START ena_storage_remove_temp_detection");
|
||||
size_t address = ENA_STORAGE_TEMP_DETECTIONS_START_ADDRESS + index * ENA_STORAGE_DETECTION_LENGTH;
|
||||
|
||||
ena_storage_shift_delete(address, ENA_STORAGE_DETECTION_LENGTH);
|
||||
|
||||
uint32_t count = ena_storage_temp_detections_count();
|
||||
ena_storage_shift_delete(address, ENA_STORAGE_TEMP_DETECTIONS_START_ADDRESS + count * ENA_STORAGE_DETECTION_LENGTH, ENA_STORAGE_DETECTION_LENGTH);
|
||||
|
||||
count--;
|
||||
ena_storage_write_u32(ENA_STORAGE_TEMP_DETECTIONS_COUNT_ADDRESS, count);
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "remove temp detection: %u", index);
|
||||
@ -265,7 +273,7 @@ uint32_t ena_storage_detections_count(void)
|
||||
return count;
|
||||
}
|
||||
|
||||
void ena_storage_write_detection(uint32_t timestamp, uint8_t rpi[], uint8_t aem[], int rssi)
|
||||
void ena_storage_write_detection(uint32_t timestamp, uint8_t *rpi, uint8_t *aem, int rssi)
|
||||
{
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "START ena_storage_write_detection");
|
||||
ESP_LOG_BUFFER_HEXDUMP(ENA_STORAGE_LOG, rpi, ENA_KEY_LENGTH, ESP_LOG_DEBUG);
|
||||
@ -286,7 +294,7 @@ void ena_storage_write_detection(uint32_t timestamp, uint8_t rpi[], uint8_t aem[
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "END ena_storage_write_detection");
|
||||
}
|
||||
|
||||
void ena_storage_read_detection(uint32_t index, uint32_t *timestamp, uint8_t rpi[], uint8_t aem[], int *rssi)
|
||||
void ena_storage_read_detection(uint32_t index, uint32_t *timestamp, uint8_t *rpi, uint8_t *aem, int *rssi)
|
||||
{
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "START ena_storage_read_detection");
|
||||
size_t address = ENA_STORAGE_DETECTIONS_START_ADDRESS + index * ENA_STORAGE_DETECTION_LENGTH;
|
||||
@ -374,7 +382,7 @@ void ena_storage_erase(void)
|
||||
ESP_LOGD(ENA_STORAGE_LOG, "END ena_storage_erase");
|
||||
}
|
||||
|
||||
void ena_storage_dump_hash_array(uint8_t data[], size_t size)
|
||||
void ena_storage_dump_hash_array(uint8_t *data, size_t size)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
|
@ -16,7 +16,6 @@
|
||||
#define ENA_STORAGE_DETECTIONS_COUNT_ADDRESS (ENA_STORAGE_TEMP_DETECTIONS_COUNT_ADDRESS + ENA_STORAGE_DETECTION_LENGTH * ENA_STOARGE_TEMP_DETECTIONS_MAX) // starting address for detections COUNT (offset from max. stored temporary detections)
|
||||
#define ENA_STORAGE_DETECTIONS_START_ADDRESS (ENA_STORAGE_DETECTIONS_COUNT_ADDRESS + 4) // starting address of detections
|
||||
|
||||
|
||||
/**
|
||||
* read bytes at given address
|
||||
*/
|
||||
@ -25,17 +24,17 @@ void ena_storage_read(size_t address, uint8_t *data, size_t size);
|
||||
/**
|
||||
* store bytes at given address
|
||||
*/
|
||||
void ena_storage_write(size_t address, uint8_t data[], size_t size);
|
||||
void ena_storage_write(size_t address, uint8_t *data, size_t size);
|
||||
|
||||
/**
|
||||
* deletes bytes at given address and shift other data back
|
||||
*/
|
||||
void ena_storage_shift_delete(size_t address, size_t size);
|
||||
void ena_storage_shift_delete(size_t address, size_t end_address, size_t size);
|
||||
|
||||
/**
|
||||
* store TEK with ENIN
|
||||
*/
|
||||
void ena_storage_write_tek(uint32_t enin, uint8_t tek[]);
|
||||
void ena_storage_write_tek(uint32_t enin, uint8_t *tek);
|
||||
|
||||
/**
|
||||
* get last stored ENIN
|
||||
@ -45,7 +44,7 @@ uint32_t ena_storage_read_enin(void);
|
||||
/**
|
||||
* get last stored TEK
|
||||
*/
|
||||
void ena_storage_read_tek(uint8_t tek[]);
|
||||
void ena_storage_read_tek(uint8_t *tek);
|
||||
|
||||
/**
|
||||
* get number of stored temporary detections
|
||||
@ -57,12 +56,12 @@ uint32_t ena_storage_temp_detections_count(void);
|
||||
*
|
||||
* returns index
|
||||
*/
|
||||
uint32_t ena_storage_write_temp_detection(uint32_t timestamp, uint8_t rpi[], uint8_t aem[], int rssi);
|
||||
uint32_t ena_storage_write_temp_detection(uint32_t timestamp, uint8_t *rpi, uint8_t *aem, int rssi);
|
||||
|
||||
/**
|
||||
* get temporary detection (RPI + AEM + RSSI with UNIX timestamp) at given index
|
||||
*/
|
||||
void ena_storage_read_temp_detection(uint32_t index, uint32_t *timestamp, uint8_t rpi[], uint8_t aem[], int *rssi);
|
||||
void ena_storage_read_temp_detection(uint32_t index, uint32_t *timestamp, uint8_t *rpi, uint8_t *aem, int *rssi);
|
||||
|
||||
/**
|
||||
* remove temporary detection at given index
|
||||
@ -77,12 +76,12 @@ uint32_t ena_storage_detections_count(void);
|
||||
/**
|
||||
* store detection (RPI + AEM + RSSI with ENIN)
|
||||
*/
|
||||
void ena_storage_write_detection(uint32_t timestamp, uint8_t rpi[], uint8_t aem[], int rssi);
|
||||
void ena_storage_write_detection(uint32_t timestamp, uint8_t *rpi, uint8_t *aem, int rssi);
|
||||
|
||||
/**
|
||||
* get detection (RPI + AEM + RSSI with ENIN) at given index
|
||||
*/
|
||||
void ena_storage_read_detection(uint32_t index, uint32_t *enin, uint8_t rpi[], uint8_t aem[], int *rssi);
|
||||
void ena_storage_read_detection(uint32_t index, uint32_t *enin, uint8_t *rpi, uint8_t *aem, int *rssi);
|
||||
|
||||
uint8_t ena_storage_read_u8(size_t address);
|
||||
|
||||
|
107
main/ena.c
107
main/ena.c
@ -2,6 +2,10 @@
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_bt.h"
|
||||
@ -20,7 +24,49 @@
|
||||
static uint32_t last_enin; // last ENIN
|
||||
static uint8_t tek[ENA_KEY_LENGTH] = {0}; // current TEK
|
||||
|
||||
void ena_init(void)
|
||||
void ena_run(void *pvParameter)
|
||||
{
|
||||
uint32_t unix_timestamp = 0;
|
||||
uint32_t current_enin = 0;
|
||||
while (1)
|
||||
{
|
||||
unix_timestamp = (uint32_t)time(NULL);
|
||||
current_enin = ena_crypto_enin(unix_timestamp);
|
||||
if (current_enin - last_enin >= ENA_TEK_ROLLING_PERIOD)
|
||||
{
|
||||
ena_crypto_tek(tek);
|
||||
ena_storage_write_tek(current_enin, tek);
|
||||
last_enin = current_enin;
|
||||
}
|
||||
|
||||
// change RPI
|
||||
if (unix_timestamp % ENA_TIME_WINDOW == 0)
|
||||
{
|
||||
if (ena_bluetooth_scan_get_status() == ENA_SCAN_STATUS_SCANNING)
|
||||
{
|
||||
ena_bluetooth_scan_stop();
|
||||
}
|
||||
ena_bluetooth_advertise_stop();
|
||||
ena_bluetooth_advertise_set_payload(current_enin, tek);
|
||||
ena_bluetooth_advertise_start();
|
||||
if (ena_bluetooth_scan_get_status() == ENA_SCAN_STATUS_WAITING)
|
||||
{
|
||||
ena_bluetooth_scan_start(ENA_SCANNING_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
// scan
|
||||
if (unix_timestamp % ENA_SCANNING_INTERVAL == 0 && ena_bluetooth_scan_get_status() == ENA_SCAN_STATUS_NOT_SCANNING)
|
||||
{
|
||||
ena_bluetooth_scan_start(ENA_SCANNING_TIME);
|
||||
}
|
||||
|
||||
// one second loop correct?!
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
void ena_start(void)
|
||||
{
|
||||
// init NVS for BLE
|
||||
esp_err_t ret;
|
||||
@ -30,13 +76,30 @@ void ena_init(void)
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
}
|
||||
|
||||
// init BLE
|
||||
if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE)
|
||||
{
|
||||
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg));
|
||||
ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE));
|
||||
while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED)
|
||||
{
|
||||
ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE));
|
||||
}
|
||||
|
||||
if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED)
|
||||
{
|
||||
ESP_ERROR_CHECK(esp_bluedroid_init());
|
||||
}
|
||||
if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_INITIALIZED)
|
||||
{
|
||||
ESP_ERROR_CHECK(esp_bluedroid_enable());
|
||||
}
|
||||
|
||||
// new bluetooth address nesseccary?
|
||||
uint8_t bt_address[ESP_BD_ADDR_LEN];
|
||||
@ -77,41 +140,7 @@ void ena_init(void)
|
||||
ena_bluetooth_advertise_start();
|
||||
// initial scan on every start
|
||||
ena_bluetooth_scan_start(ENA_SCANNING_TIME);
|
||||
}
|
||||
|
||||
void ena_run(void)
|
||||
{
|
||||
uint32_t unix_timestamp = (uint32_t)time(NULL);
|
||||
uint32_t current_enin = ena_crypto_enin(unix_timestamp);
|
||||
if (current_enin - last_enin >= ENA_TEK_ROLLING_PERIOD)
|
||||
{
|
||||
ena_crypto_tek(tek);
|
||||
ena_storage_write_tek(current_enin, tek);
|
||||
last_enin = current_enin;
|
||||
}
|
||||
|
||||
// change RPI
|
||||
if (unix_timestamp % ENA_TIME_WINDOW == 0)
|
||||
{
|
||||
|
||||
//
|
||||
|
||||
if (ena_bluetooth_scan_get_status() == ENA_SCAN_STATUS_SCANNING)
|
||||
{
|
||||
ena_bluetooth_scan_stop();
|
||||
}
|
||||
ena_bluetooth_advertise_stop();
|
||||
ena_bluetooth_advertise_set_payload(current_enin, tek);
|
||||
ena_bluetooth_advertise_start();
|
||||
if (ena_bluetooth_scan_get_status() == ENA_SCAN_STATUS_WAITING)
|
||||
{
|
||||
ena_bluetooth_scan_start(ENA_SCANNING_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
// scan
|
||||
if (unix_timestamp % ENA_SCANNING_INTERVAL == 0 && ena_bluetooth_scan_get_status() == ENA_SCAN_STATUS_NOT_SCANNING)
|
||||
{
|
||||
ena_bluetooth_scan_start(ENA_SCANNING_TIME);
|
||||
}
|
||||
|
||||
// what is a good stack size here?
|
||||
xTaskCreate(&ena_run, "ena_run", configMINIMAL_STACK_SIZE * 4, NULL, 5, NULL);
|
||||
}
|
||||
|
@ -6,11 +6,8 @@
|
||||
#ifndef _ena_H_
|
||||
#define _ena_H_
|
||||
|
||||
|
||||
#define ENA_LOG "ESP-ENA" // TAG for Logging
|
||||
|
||||
void ena_init(void);
|
||||
|
||||
void ena_run(void);
|
||||
void ena_start(void);
|
||||
|
||||
#endif
|
12
main/main.c
12
main/main.c
@ -21,6 +21,7 @@
|
||||
|
||||
#include "ena.h"
|
||||
#include "ena-storage.h"
|
||||
#include "ena-interface.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
@ -33,13 +34,6 @@ void app_main(void)
|
||||
esp_log_level_set(ENA_STORAGE_LOG, ESP_LOG_INFO);
|
||||
ena_storage_erase(); // only needed on first start! TODO automatically check
|
||||
|
||||
ena_init();
|
||||
|
||||
// one second loop enough?
|
||||
while (1)
|
||||
{
|
||||
ena_run();
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
ena_interface_start();
|
||||
ena_start();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user