diff --git a/build_native.sh b/build_native.sh new file mode 100755 index 0000000..ba82273 --- /dev/null +++ b/build_native.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +rm -rf zephyr/build +cp .pio/libdeps/nrf52840_dk/exposure-notification/*/exposure-notification.* src +west build -b native_posix_64 zephyr -- -DCMAKE_C_FLAGS="-DNATIVE_POSIX -I../include/tls_config" +rm src/exposure-notification.c src/exposure-notification.h +echo "Run ./build/zephyr/zephyr.elf --bt-dev=hci0" \ No newline at end of file diff --git a/src/contacts.c b/src/contacts.c index 21e8902..bfccc65 100644 --- a/src/contacts.c +++ b/src/contacts.c @@ -41,3 +41,171 @@ void print_aem(associated_encrypted_metadata_t* aem){ printk("%02x", aem->data[i]); } } +<<<<<<< HEAD +======= + +contact_t* find_contact(rolling_proximity_identifier_t* rpi, associated_encrypted_metadata_t* aem){ + for( int i = 0; i < contact_count; i++ ){ + //print_rpi(&contacts[i].rolling_proximity_identifier); + //print_aem(&contacts[i].associated_encrypted_metadata); + if ( memcmp(&contacts[i].rolling_proximity_identifier, rpi, sizeof(rolling_proximity_identifier_t)) == 0 && + memcmp(&contacts[i].associated_encrypted_metadata, aem, sizeof(associated_encrypted_metadata_t)) == 0 ) { + return &contacts[i]; + } + } + return NULL; +} + +int check_add_contact(uint32_t contact_time, rolling_proximity_identifier_t* rpi, associated_encrypted_metadata_t* aem, int8_t rssi){ + contact_t* contact = find_contact(rpi, aem); + if( contact == NULL ){ + if( contact_count >= MAX_CONTACTS ){ + printk("out of contact buffers\n"); + return -1; + } + printk("adding contact: rpi "); + print_rpi(rpi); + printk(" aem "); + print_aem(aem); + printk(" rssi %i \n", rssi); + + contacts[contact_count].most_recent_contact_time = contact_time; + contacts[contact_count].first_contact_time = contact_time; + contacts[contact_count].cnt = 1; + contacts[contact_count].max_rssi = rssi; + memcpy(&contacts[contact_count].rolling_proximity_identifier, rpi, sizeof(rolling_proximity_identifier_t)); + memcpy(&contacts[contact_count].associated_encrypted_metadata, aem, sizeof(associated_encrypted_metadata_t)); + contact_count++; + } else { + contact->most_recent_contact_time = contact_time; + if( contacts->cnt < 0xFFFF ){ //avoid overflows + contacts->cnt++; + } + if( rssi > contact->max_rssi ){ + contact->max_rssi = rssi; + } + // printk("update contact: rpi "); + // print_rpi(rpi); + // printk(" aem "); + // print_aem(aem); + // printk(" rssi %i, cnt %i \n", rssi, contacts->cnt); + } + return 0; +} + + + +//10 minutes are over and we got new keys. Time to also sort our short term contacts and move them to long-term log +//TODO: move long-term storage to flash, as we have limited space in RAM +void key_change(int current_period_index){ + if(current_period_index >= PERIODS){ + printk("error, current periods index %i too large", current_period_index); + return; + } + if(current_period_index != period_index){ + //printk("new period index\n"); + period_index = current_period_index; + period_contacts[period_index].cnt = 0; + } + + //check all short-term contacts (as long as we have space in our long-term storage) + for( int i = 0; i < contact_count && period_contacts[period_index].cnt < MAX_PERIOD_CONTACTS; i++){ + //printk("check contact %i, duration %i\n", i, contacts[i].most_recent_contact_time - contacts[i].first_contact_time); + int index = period_contacts[period_index].cnt; + if( (contacts[i].most_recent_contact_time - contacts[i].first_contact_time) > (EN_INTERVAL_LENGTH / 2)){ + period_contacts[period_index].period_contacts[index].duration = contacts[i].most_recent_contact_time - contacts[i].first_contact_time; + period_contacts[period_index].period_contacts[index].cnt = contacts[i].cnt; + period_contacts[period_index].period_contacts[index].max_rssi = contacts[i].max_rssi; + memcpy(&period_contacts[period_index].period_contacts[index].rolling_proximity_identifier, &contacts[i].rolling_proximity_identifier, sizeof(rolling_proximity_identifier_t)); + memcpy(&period_contacts[period_index].period_contacts[index].associated_encrypted_metadata, &contacts[i].associated_encrypted_metadata, sizeof(associated_encrypted_metadata_t)); + + printk("store contact %i as exposure %i: rpi ", i, period_contacts[period_index].cnt); + print_rpi(&period_contacts[period_index].period_contacts[index].rolling_proximity_identifier); + printk(" aem "); + print_aem(&period_contacts[period_index].period_contacts[index].associated_encrypted_metadata); + printk(" max rssi %i, cnt %u, duration %u\n", period_contacts[period_index].period_contacts[index].max_rssi, period_contacts[period_index].period_contacts[index].cnt, period_contacts[period_index].period_contacts[index].duration); + period_contacts[period_index].cnt++; + } + } + contact_count = 0; +} + +#ifndef NATIVE_POSIX +/* The devicetree node identifier for the "led1" alias. */ +#define LED1_NODE DT_ALIAS(led1) + +#if DT_NODE_HAS_STATUS(LED1_NODE, okay) +#define LED1 DT_GPIO_LABEL(LED1_NODE, gpios) +#define PIN DT_GPIO_PIN(LED1_NODE, gpios) +#if DT_PHA_HAS_CELL(LED1_NODE, gpios, flags) +#define FLAGS DT_GPIO_FLAGS(LED1_NODE, gpios) +#endif +#else +/* A build error here means your board isn't set up to blink an LED. */ +#error "Unsupported board: led0 devicetree alias is not defined" +#define LED1 "" +#define PIN 0 +#endif +#endif + +#ifndef FLAGS +#define FLAGS 0 +#endif + +struct device *dev; + +void add_infected_key(period_t* period){ + + //printk("Interval: %u\n", period->periodInterval); + //printk("RPI: "); print_rpi((rolling_proximity_identifier_t*)&period->periodKey); printk("\n"); + next_infected_key_id++; + //find correct "day", TODO: also check a bit before and after + int index = get_index_by_interval(period->periodInterval); + if( index < 0 ){ + printk("Exposure check: period %i not found\n", period->periodInterval); + return; + } + for( int i = 0; i < EN_TEK_ROLLING_PERIOD; i++){ + static ENIntervalIdentifier intervalIdentifier; + en_derive_interval_identifier(&intervalIdentifier, &period->periodKey, period->periodInterval + i); + //go through all long-term contacts for this day and check if I have seen the intervalIdentifier + for( int j = 0; j < period_contacts[index].cnt; j++){ + int ret = memcmp(&period_contacts[index].period_contacts[j].rolling_proximity_identifier, &intervalIdentifier, sizeof(rolling_proximity_identifier_t)); + if( ret == 0 ){ + printk("Found exposure: rpi "); + print_rpi(&period_contacts[index].period_contacts[j].rolling_proximity_identifier); + printk(" aem "); + print_aem(&period_contacts[index].period_contacts[j].associated_encrypted_metadata); + printk(" max rssi %i, cnt %u, duration %u\n", period_contacts[index].period_contacts[j].max_rssi, period_contacts[index].period_contacts[j].cnt, period_contacts[index].period_contacts[j].duration); + #ifndef NATIVE_POSIX + gpio_pin_set(dev, PIN, (int)1); + #endif + } + } + } + +} + +uint32_t get_next_infected_key_id(){ + return next_infected_key_id; +} + +void init_contacts(){ + contact_count = 0; + period_index = 0; + + #ifndef NATIVE_POSIX + dev = device_get_binding(LED1); + if (dev == NULL) { + return; + } + + int ret = gpio_pin_configure(dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS); + if (ret < 0) { + return; + } + + gpio_pin_set(dev, PIN, (int)0); + #endif +} +>>>>>>> 523dcb2 (Enable native build) diff --git a/src/covid.c b/src/covid.c index f96cc2c..84abebe 100644 --- a/src/covid.c +++ b/src/covid.c @@ -149,7 +149,8 @@ static void test_against_fixtures(void) } static void new_period_key(time_t currentTime) -{ +{ + #ifndef NATIVE_POSIX printk("\n----------------------------------------\n\n"); printk("\n----------------------------------------\n\n"); printk("*** New Period\n"); @@ -158,6 +159,7 @@ static void new_period_key(time_t currentTime) printk("periodInterval %u\n", periods[current_period_index].periodInterval); en_generate_period_key(&periods[current_period_index].periodKey); period_cnt++; + #endif } #if COVID_MEASURE_PERFORMANCE @@ -360,7 +362,9 @@ int init_covid() check_keys(NULL); int err = 0; + #ifndef NATIVE_POSIX err = bt_le_scan_start(&scan_param, scan_cb); + #endif if (err) { printk("Starting scanning failed (err %d)\n", err); @@ -376,7 +380,9 @@ int do_covid() //printk("covid start\n"); int err = 0; + #ifndef NATIVE_POSIX err = bt_le_adv_start(BT_LE_ADV_NCONN, ad, ARRAY_SIZE(ad), NULL, 0); + #endif if (err) { @@ -386,7 +392,10 @@ int do_covid() k_sleep(K_SECONDS(10)); + #ifndef NATIVE_POSIX err = bt_le_adv_stop(); + #endif + if (err) { printk("Advertising failed to stop (err %d)\n", err); diff --git a/src/io.c b/src/io.c index aed6679..a968c6c 100644 --- a/src/io.c +++ b/src/io.c @@ -31,6 +31,7 @@ * cell is optional. */ +#ifndef NATIVE_POSIX //on my NRF board this is button 1 #define SW0_NODE DT_ALIAS(sw0) @@ -74,6 +75,7 @@ #define LED0 "" #define PIN 0 #endif +#endif #ifndef FLAGS #define FLAGS 0 @@ -84,18 +86,23 @@ static struct gpio_callback button_0_cb_data; static struct gpio_callback button_1_cb_data; void button_0_pressed(struct device *dev, struct gpio_callback *cb, uint32_t pins){ + #ifndef NATIVE_POSIX set_infection(true); gpio_pin_set(dev, PIN, (int)1); printk("Button 0 (=infected) pressed at %" PRIu32 "\n", k_cycle_get_32()); + #endif } void button_1_pressed(struct device *dev, struct gpio_callback *cb, uint32_t pins){ + #ifndef NATIVE_POSIX set_infection(false); gpio_pin_set(dev, PIN, (int)0); printk("Button 1 (=healthy) pressed at %" PRIu32 "\n", k_cycle_get_32()); + #endif } int init_io(){ + #ifndef NATIVE_POSIX struct device *button0, *button1; int err = 0; //struct device *led; @@ -165,5 +172,6 @@ int init_io(){ } //Turn LED 0 off gpio_pin_set(dev, PIN, (int)0); + #endif return 0; } \ No newline at end of file diff --git a/src/main.c b/src/main.c index 750c56a..8338f4a 100644 --- a/src/main.c +++ b/src/main.c @@ -23,6 +23,7 @@ void main(void) { printk("Starting Covid Contact Tracer\n"); // first init everything + #ifndef NATIVE_POSIX // Use custom randomization as the mbdet_tls context initialization messes with the Zeyhr BLE stack. err = en_init(sys_csrand_get); if (err) { @@ -35,6 +36,7 @@ void main(void) { printk("init storage failed (err %d)\n", err); return; } + #endif err = init_io(); if (err) { @@ -42,20 +44,39 @@ void main(void) { return; } +<<<<<<< HEAD /* Initialize the Bluetooth Subsystem */ err = bt_enable(NULL); if (err) { printk("Bluetooth init failed (err %d)\n", err); return; } +======= + #ifndef NATIVE_POSIX + /* Initialize the Bluetooth Subsystem */ + err = bt_enable(NULL); + if (err) { + printk("Bluetooth init failed (err %d)\n", err); + return; + } +>>>>>>> 523dcb2 (Enable native build) printk("Bluetooth initialized\n"); +<<<<<<< HEAD err = init_gatt(); if (err) { printk("init gatt failed(err %d)\n", err); return; } +======= + err = init_gatt(); + if (err) { + printk("init gatt failed(err %d)\n", err); + return; + } + #endif +>>>>>>> 523dcb2 (Enable native build) err = init_covid(); if (err) { diff --git a/zephyr/prj.conf b/zephyr/prj.conf index fc7e154..88b6a48 100644 --- a/zephyr/prj.conf +++ b/zephyr/prj.conf @@ -38,4 +38,24 @@ CONFIG_NORDIC_QSPI_NOR=y # configuration options for MX25R64 flash device CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 # max contacts, that can be stored -CONFIG_ENS_MAX_CONTACTS=65536 \ No newline at end of file +CONFIG_ENS_MAX_CONTACTS=65536 +CONFIG_SDL_DISPLAY_DEV_NAME="DISPLAY" +CONFIG_SDL_DISPLAY_X_RES=240 +CONFIG_SDL_DISPLAY_Y_RES=240 + +CONFIG_KSCAN=y +CONFIG_LVGL_POINTER_KSCAN=y +CONFIG_LVGL_HOR_RES_MAX=240 +CONFIG_LVGL_VER_RES_MAX=240 +CONFIG_LVGL_DPI=100 + + +CONFIG_DISPLAY=y +CONFIG_DISPLAY_LOG_LEVEL_ERR=y + +CONFIG_LOG=y +CONFIG_LVGL=y +CONFIG_LVGL_USE_LABEL=y +CONFIG_LVGL_USE_CONT=y +CONFIG_LVGL_USE_BTN=y +CONFIG_LVGL_USE_THEME_MATERIAL=y