diff --git a/.gitignore b/.gitignore index b5e3776..ce6f7a1 100644 --- a/.gitignore +++ b/.gitignore @@ -46,4 +46,5 @@ massif-* .pio .vscode -.DS_Store \ No newline at end of file +.DS_Store +/.idea diff --git a/include/bloom.h b/include/bloom.h deleted file mode 100644 index e7c3d7d..0000000 --- a/include/bloom.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef BLOOM_H -#define BLOOM_H - -#include "ens/storage.h" -#include "exposure-notification.h" - -typedef struct { - uint8_t* data; - size_t size; -} bloom_filter_t; - -/** - * Initialize the bloom filter on basis of the already registerred records. - */ -bloom_filter_t* bloom_init(size_t size); - -void bloom_destroy(bloom_filter_t* bloom); - -// TODO lome: maybe only use RPI (should be sufficient) -void bloom_add_record(bloom_filter_t* bloom, ENIntervalIdentifier* rpi); - -// TODO lome: maybe only use RPI (should be sufficient) -bool bloom_probably_has_record(bloom_filter_t* bloom, ENIntervalIdentifier* rpi); - -#endif diff --git a/include/contacts.h b/include/contacts.h deleted file mode 100644 index a31a707..0000000 --- a/include/contacts.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2020 Olaf Landsiedel - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef CONTACTS_H -#define CONTACTS_H - -#include -#include - -#include "covid.h" -#include "covid_types.h" -#include "ens/storage.h" -#include "exposure-notification.h" - -typedef struct { - ENIntervalIdentifier interval_identifier; - int met; - time_t search_start; - time_t search_end; -} __packed infected_for_interval_ident_ctx_t; - -typedef struct { - ENPeriodKey periodKey; - time_t start; - int met; -} __packed period_key_information_t; - -typedef int (*test_func_t)(infected_for_interval_ident_ctx_t* infectedIntervals, int count); - -void print_key(_ENBaseKey* key); -void print_rpi(rolling_proximity_identifier_t* rpi); -void print_aem(associated_encrypted_metadata_t* aem); - -/** - * Register a new record in the system. This includes adding it to the storage and adding it to the bloom filter. - * - * @param record record to add - * @returns 0 in case of success, -ERRNO in case of an error - */ -int register_record(record_t* record); - -/** - * Initialize the contacts module. - */ -int init_contacts(); - -/** - * Check for a list of specified interval identifiers, whether they were probably met or not. - * @param ctx list of interval identifiers to check - * @param count amount of identifiers to check - * @return the amount of met intervals, -ERRNO on error - */ -int check_possible_contacts_for_intervals(infected_for_interval_ident_ctx_t* ctx, int count); - -/** - * Check for a list of specified period keys, whether they were probably met or not. - * @param ctx list of period keys and their meta information to check - * @param count amount of period keys to check - * @return -ERRNO on error, 0 otherwise - */ -int check_possible_contacts_for_periods(period_key_information_t periodKeyInformation[], int count); - -#endif diff --git a/include/covid.h b/include/covid.h deleted file mode 100644 index 69ae240..0000000 --- a/include/covid.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2020 Olaf Landsiedel - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef COVID_H -#define COVID_H - -#include - -#include "exposure-notification.h" - -typedef struct period{ - ENPeriodKey periodKey; - ENIntervalNumber periodInterval; -} __packed period_t; - -int init_covid(); -int do_covid(); - -bool get_infection(); -void set_infection(bool _infected); -unsigned int get_period_cnt_if_infected(); -period_t* get_period_if_infected(unsigned int id, size_t* size); - -int get_index_by_interval(ENIntervalNumber periodInterval); - - -void print_periods(); -#endif \ No newline at end of file diff --git a/include/covid_types.h b/include/covid_types.h deleted file mode 100644 index f643ff3..0000000 --- a/include/covid_types.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2020 Olaf Landsiedel - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef COVID_TYPES_H -#define COVID_TYPES_H - -#include -#include -#include - -#define COVID_ROLLING_PROXIMITY_IDENTIFIER_LEN 16 - -typedef ENIntervalIdentifier rolling_proximity_identifier_t; - -typedef struct bt_metadata { - uint8_t version; - uint8_t tx_power; - uint8_t rsv1; - uint8_t rsv2; -} __packed bt_metadata_t; - -// typedef struct bt_metadata bt_metadata_t; - -typedef struct associated_encrypted_metadata { - uint8_t data[sizeof(bt_metadata_t)]; -} __packed associated_encrypted_metadata_t; - -typedef uint8_t rssi_t; - -#endif diff --git a/include/display.h b/include/display.h deleted file mode 100644 index 3443a6c..0000000 --- a/include/display.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef DISPLAY_H -#define DISPLAY_H - -/** - * @brief Initializes all display elements and adds them to the canvas. - * - * @return int - */ -int init_display(); - -/** - * @brief Updates all information on the display using the get functions, defined by `display.c`. Alternatively the - * values of the displayed elements can be set explicitly via set `display_set_`-functions. - * - * @return int - */ -int update_display(); - -/** - * @brief This is the entry point for the display thread. It peridocially updates the display and handles input events. - * - */ -void display_thread(void*, void*, void*); - -/** - * @brief Displays a message at the bottom of the display. The message will persist until it is removed expicitly, by calling `display_set_message("")`. - * - * @param msg A pointer to the string that should be displayed - * @return int - */ -int display_set_message(char* msg); - -/** - * @brief Sets the on display clock. The time should have the format `h * 100 + m`. So `display_set_time(1145)` sets the clock to 11:45. - * - * @param time A number representation of the time - * @return int - */ -int display_set_time(int time); - -/** - * @brief Set the battery level percentage. - * - * @param bat The battery level in percent - * @return int - */ -int display_set_bat(int bat); - -/** - * @brief Set the non-volatile memory state. - * - * @param mem The occupied memory in percent - * @return int - */ -int display_set_mem(int mem); - -/** - * @brief Set the number of total registered contacts in the last 14 days. - * - * @param contacts The number of contacts - * @return int - */ -int display_set_contacts(int contacts); - -/** - * @brief Set the number of contacts that were tested positively on Covid and registered in the last 14 days. - * - * @param risk_contacts The number of risk contacts - * @return int - */ -int display_set_risk_contacts(int risk_contacts); - -#endif \ No newline at end of file diff --git a/include/ens/ens_error.h b/include/ens/ens_error.h deleted file mode 100644 index fca37ca..0000000 --- a/include/ens/ens_error.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef ENS_ERROR_H -#define ENS_ERROR_H - -#define ENS_INTERR 1 // internal error -#define ENS_NOENT 2 // entry not found or invalid -#define ENS_DELENT 3 // entry got deleted -#define ENS_ADDRINU 4 // address alread in use or corrupt -#define ENS_INVARG 5 // invalid argument - -#endif \ No newline at end of file diff --git a/include/ens/records.h b/include/ens/records.h deleted file mode 100644 index e8ec035..0000000 --- a/include/ens/records.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2021 Louis Meyer and Patrick Rathje - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ENS_RECORDS_H -#define ENS_RECORDS_H - -#include "sequencenumber.h" -#include "storage.h" - -typedef struct record_iterator { - /** - * @internal - */ - record_t current; - /** - * @internal - */ - record_sequence_number_t sn_next; - /** - * @internal - */ - record_sequence_number_t sn_end; // the last sn to include - /** - * @internal - */ - uint8_t finished; -} record_iterator_t; - -// Also uses start and end from storage if NULL pointers given -// iterate over a sequence number range of records (Null will select the latest and newest for start / end) -// automatically -int ens_records_iterator_init_range(record_iterator_t* iterator, - record_sequence_number_t* opt_start, - record_sequence_number_t* opt_end); - -// TODO: Do we guarantee that higher sequence numbers have at least our timestamp and lower sequence numbers up to our -// timestamp? -int ens_records_iterator_init_timerange(record_iterator_t* iterator, time_t* ts_start, time_t* ts_end); - -record_t* ens_records_iterator_next(record_iterator_t* iter); - -int ens_record_iterator_clear(record_iterator_t* iter); - -// TODO: Is a callback the easiest thing to do? -> now it is the iterator :) -// TODO: should we really indicated the last record by sending a NULL pointer? -typedef uint8_t (*ens_record_iterator_cb_t)(const record_t* record, void* userdata); - -enum { - ENS_RECORD_ITER_STOP, // STOP the iteration, this would not result in a NULL callback after the end is reached - ENS_RECORD_ITER_CONTINUE, // CONTINUE the iteration, this results in a NULL callback after the end is reached -}; - -// TODO: this function could be made asynchronous to handle delays in contact_storage reads?! -// TODO: How can we handle iteration while records are being added or deleted? (should be safe as long as the -// load_record function is thread safe?!) -uint8_t ens_records_iterate_with_callback(record_iterator_t* iter, ens_record_iterator_cb_t cb, void* userdata); - -#endif diff --git a/include/ens/storage.h b/include/ens/storage.h deleted file mode 100644 index f6a2c3d..0000000 --- a/include/ens/storage.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef CONTACT_STORAGE_H -#define CONTACT_STORAGE_H - -#include - -#include "covid_types.h" -#include "sequencenumber.h" - -typedef uint64_t storage_id_t; - -typedef struct record { - record_sequence_number_t sn; // TODO: Convert Sequence Number - uint32_t timestamp; // TODO: Seconds from january first 2000 (UTC+0) - rssi_t rssi; // TODO: Check correct - rolling_proximity_identifier_t rolling_proximity_identifier; - associated_encrypted_metadata_t associated_encrypted_metadata; -} __packed record_t; - -typedef struct stored_records_information { - record_sequence_number_t oldest_contact; - uint32_t count; -} stored_records_information_t; - -/** - * Initializes the contact storage component - * @param clean flag for indicating, if storage shall be init with clean state - * - * @return 0 for success - */ -int init_record_storage(bool clean); - -/** - * Reset state of record storage. - */ -void reset_record_storage(); - -/** - * Loads the record with number sn into the destination struct - * @param dest - * @param sn - * @return 0 in case of success - */ -int load_record(record_t* dest, record_sequence_number_t sn); - -/** - * Stores the record from src with number sn, increases latest sequence number - * @param sn - * @param src - * @return 0 in case of success - */ -int add_record(record_t* src); - -/** - * Deletes the record from storage with number sn - * @param sn the sequence number to delete - * @return 0 in case of success - */ -int delete_record(record_sequence_number_t sn); - -/** - * TODO: How to handle if none is available? - * @return The latest available sequence number (Caution: can actually be lower than the oldes in case of a - * wrap-around!) - */ -record_sequence_number_t get_latest_sequence_number(); - -/** - * TODO: How to handle if none is available? - * @return The oldest available sequence number - */ -record_sequence_number_t get_oldest_sequence_number(); - -/** - * @return The amount of contacts, usually get_latest_sequence_number() - get_oldest_sequence_number() - */ -uint32_t get_num_records(); - -int get_sequence_number_interval(record_sequence_number_t* oldest, record_sequence_number_t* latest); - -#endif diff --git a/include/export.pb-c.h b/include/export.pb-c.h deleted file mode 100644 index 83505fa..0000000 --- a/include/export.pb-c.h +++ /dev/null @@ -1,355 +0,0 @@ -/* Generated by the protocol buffer compiler. DO NOT EDIT! */ -/* Generated from: export.proto */ - -#ifndef PROTOBUF_C_export_2eproto__INCLUDED -#define PROTOBUF_C_export_2eproto__INCLUDED - -#include - -PROTOBUF_C__BEGIN_DECLS - -#if PROTOBUF_C_VERSION_NUMBER < 1000000 -# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. -#elif 1004000 < PROTOBUF_C_MIN_COMPILER_VERSION -# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. -#endif - - -typedef struct TemporaryExposureKeyExport TemporaryExposureKeyExport; -typedef struct SignatureInfo SignatureInfo; -typedef struct TemporaryExposureKey TemporaryExposureKey; -typedef struct TEKSignatureList TEKSignatureList; -typedef struct TEKSignature TEKSignature; - - -/* --- enums --- */ - -/* - * Data type representing why this key was published. - */ -typedef enum _TemporaryExposureKey__ReportType { - /* - * Never returned by the client API. - */ - TEMPORARY_EXPOSURE_KEY__REPORT_TYPE__UNKNOWN = 0, - TEMPORARY_EXPOSURE_KEY__REPORT_TYPE__CONFIRMED_TEST = 1, - TEMPORARY_EXPOSURE_KEY__REPORT_TYPE__CONFIRMED_CLINICAL_DIAGNOSIS = 2, - TEMPORARY_EXPOSURE_KEY__REPORT_TYPE__SELF_REPORT = 3, - TEMPORARY_EXPOSURE_KEY__REPORT_TYPE__RECURSIVE = 4, - /* - * Used to revoke a key, never returned by client API. - */ - TEMPORARY_EXPOSURE_KEY__REPORT_TYPE__REVOKED = 5 - PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(TEMPORARY_EXPOSURE_KEY__REPORT_TYPE) -} TemporaryExposureKey__ReportType; - -/* --- messages --- */ - -/* - * Protobuf definition for exports of confirmed temporary exposure keys. - * The full file format is documented under "Exposure Key Export File Format - * and Verification" at https://www.google.com/covid19/exposurenotifications/ - * These files have a 16-byte, space-padded header before the protobuf data - * starts. They will be contained in a zip archive, alongside a signature - * file verifying the contents. - */ -struct TemporaryExposureKeyExport -{ - ProtobufCMessage base; - /* - * Time window of keys in this file based on arrival to server, in UTC - * seconds. start_timestamp, end_timestamp, and batch_num must be unique - * at any given snapshot of the index for a server. If multiple - * files are used for a specific time period, and batch_num/batch_size - * are both 1 (See below), then offsetting the end_timestamp is the - * suggested method for forcing uniqueness. - */ - protobuf_c_boolean has_start_timestamp; - uint64_t start_timestamp; - protobuf_c_boolean has_end_timestamp; - uint64_t end_timestamp; - /* - * Region for which these keys came from (e.g., country) - */ - char *region; - /* - * E.g., Batch 2 of 10. Ordinal, 1-based numbering. - * Note: Not yet supported on iOS. Use values of 1 for both. - */ - protobuf_c_boolean has_batch_num; - int32_t batch_num; - protobuf_c_boolean has_batch_size; - int32_t batch_size; - /* - * Information about signatures - * If there are multiple entries, they must be ordered in descending - * time order by signing key effective time (most recent one first). - * There is a limit of 10 signature infos per export file (mobile OS may - * not check anything after that). - */ - size_t n_signature_infos; - SignatureInfo **signature_infos; - /* - * The TemporaryExposureKeys for initial release of keys. - * Keys should be included in this list for initial release, - * whereas revised or revoked keys should go in revised_keys. - */ - size_t n_keys; - TemporaryExposureKey **keys; - /* - * TemporaryExposureKeys that have changed status. - * Keys should be included in this list if they have changed status - * or have been revoked. - */ - size_t n_revised_keys; - TemporaryExposureKey **revised_keys; -}; -#define TEMPORARY_EXPOSURE_KEY_EXPORT__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&temporary_exposure_key_export__descriptor) \ - , 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0,NULL, 0,NULL, 0,NULL } - - -struct SignatureInfo -{ - ProtobufCMessage base; - /* - * Key version for rollovers - * Must be in character class [a-zA-Z0-9_]. E.g., 'v1' - */ - char *verification_key_version; - /* - * Alias with which to identify public key to be used for verification - * Must be in character class [a-zA-Z0-9_] - * For cross-compatibility with Apple, use MCC - * (https://en.wikipedia.org/wiki/Mobile_country_code). - */ - char *verification_key_id; - /* - * ASN.1 OID for Algorithm Identifier. Supported algorithms are - * either 1.2.840.10045.4.3.2 or 1.2.840.10045.4.3.4 - */ - char *signature_algorithm; -}; -#define SIGNATURE_INFO__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&signature_info__descriptor) \ - , NULL, NULL, NULL } - - -struct TemporaryExposureKey -{ - ProtobufCMessage base; - /* - * Key of infected user - */ - protobuf_c_boolean has_key_data; - ProtobufCBinaryData key_data; - /* - * Varying risks associated with exposure depending on type of verification - * Ignored by the v1.5 client API when report_type is set. - */ - protobuf_c_boolean has_transmission_risk_level PROTOBUF_C__DEPRECATED; - int32_t transmission_risk_level PROTOBUF_C__DEPRECATED; - /* - * The interval number since epoch for which a key starts - */ - protobuf_c_boolean has_rolling_start_interval_number; - int32_t rolling_start_interval_number; - /* - * Increments of 10 minutes describing how long a key is valid - */ - /* - * defaults to 24 hours - */ - protobuf_c_boolean has_rolling_period; - int32_t rolling_period; - /* - * Type of diagnosis associated with a key. - */ - protobuf_c_boolean has_report_type; - TemporaryExposureKey__ReportType report_type; - /* - * Number of days elapsed between symptom onset and the TEK being used. - * E.g. 2 means TEK is 2 days after onset of symptoms. - */ - protobuf_c_boolean has_days_since_onset_of_symptoms; - int32_t days_since_onset_of_symptoms; -}; -#define TEMPORARY_EXPOSURE_KEY__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&temporary_exposure_key__descriptor) \ - , 0, {0,NULL}, 0, 0, 0, 0, 0, 144, 0, TEMPORARY_EXPOSURE_KEY__REPORT_TYPE__UNKNOWN, 0, 0 } - - -struct TEKSignatureList -{ - ProtobufCMessage base; - /* - * When there are multiple signatures, they must be sorted in time order - * by first effective date for the signing key in descending order. - * The most recent effective signing key must appear first. - * There is a limit of 10 signature infos per export file (mobile OS may - * not check anything after that). - */ - size_t n_signatures; - TEKSignature **signatures; -}; -#define TEKSIGNATURE_LIST__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&teksignature_list__descriptor) \ - , 0,NULL } - - -struct TEKSignature -{ - ProtobufCMessage base; - /* - * Info about the signing key, version, algorithm, etc. - */ - SignatureInfo *signature_info; - /* - * E.g., Batch 2 of 10 - * Must match fields from TemporaryExposureKeyExport, see - * documentation on that message. - */ - protobuf_c_boolean has_batch_num; - int32_t batch_num; - protobuf_c_boolean has_batch_size; - int32_t batch_size; - /* - * Signature in X9.62 format (ASN.1 SEQUENCE of two INTEGER fields) - */ - protobuf_c_boolean has_signature; - ProtobufCBinaryData signature; -}; -#define TEKSIGNATURE__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&teksignature__descriptor) \ - , NULL, 0, 0, 0, 0, 0, {0,NULL} } - - -/* TemporaryExposureKeyExport methods */ -void temporary_exposure_key_export__init - (TemporaryExposureKeyExport *message); -size_t temporary_exposure_key_export__get_packed_size - (const TemporaryExposureKeyExport *message); -size_t temporary_exposure_key_export__pack - (const TemporaryExposureKeyExport *message, - uint8_t *out); -size_t temporary_exposure_key_export__pack_to_buffer - (const TemporaryExposureKeyExport *message, - ProtobufCBuffer *buffer); -TemporaryExposureKeyExport * - temporary_exposure_key_export__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void temporary_exposure_key_export__free_unpacked - (TemporaryExposureKeyExport *message, - ProtobufCAllocator *allocator); -/* SignatureInfo methods */ -void signature_info__init - (SignatureInfo *message); -size_t signature_info__get_packed_size - (const SignatureInfo *message); -size_t signature_info__pack - (const SignatureInfo *message, - uint8_t *out); -size_t signature_info__pack_to_buffer - (const SignatureInfo *message, - ProtobufCBuffer *buffer); -SignatureInfo * - signature_info__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void signature_info__free_unpacked - (SignatureInfo *message, - ProtobufCAllocator *allocator); -/* TemporaryExposureKey methods */ -void temporary_exposure_key__init - (TemporaryExposureKey *message); -size_t temporary_exposure_key__get_packed_size - (const TemporaryExposureKey *message); -size_t temporary_exposure_key__pack - (const TemporaryExposureKey *message, - uint8_t *out); -size_t temporary_exposure_key__pack_to_buffer - (const TemporaryExposureKey *message, - ProtobufCBuffer *buffer); -TemporaryExposureKey * - temporary_exposure_key__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void temporary_exposure_key__free_unpacked - (TemporaryExposureKey *message, - ProtobufCAllocator *allocator); -/* TEKSignatureList methods */ -void teksignature_list__init - (TEKSignatureList *message); -size_t teksignature_list__get_packed_size - (const TEKSignatureList *message); -size_t teksignature_list__pack - (const TEKSignatureList *message, - uint8_t *out); -size_t teksignature_list__pack_to_buffer - (const TEKSignatureList *message, - ProtobufCBuffer *buffer); -TEKSignatureList * - teksignature_list__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void teksignature_list__free_unpacked - (TEKSignatureList *message, - ProtobufCAllocator *allocator); -/* TEKSignature methods */ -void teksignature__init - (TEKSignature *message); -size_t teksignature__get_packed_size - (const TEKSignature *message); -size_t teksignature__pack - (const TEKSignature *message, - uint8_t *out); -size_t teksignature__pack_to_buffer - (const TEKSignature *message, - ProtobufCBuffer *buffer); -TEKSignature * - teksignature__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void teksignature__free_unpacked - (TEKSignature *message, - ProtobufCAllocator *allocator); -/* --- per-message closures --- */ - -typedef void (*TemporaryExposureKeyExport_Closure) - (const TemporaryExposureKeyExport *message, - void *closure_data); -typedef void (*SignatureInfo_Closure) - (const SignatureInfo *message, - void *closure_data); -typedef void (*TemporaryExposureKey_Closure) - (const TemporaryExposureKey *message, - void *closure_data); -typedef void (*TEKSignatureList_Closure) - (const TEKSignatureList *message, - void *closure_data); -typedef void (*TEKSignature_Closure) - (const TEKSignature *message, - void *closure_data); - -/* --- services --- */ - - -/* --- descriptors --- */ - -extern const ProtobufCMessageDescriptor temporary_exposure_key_export__descriptor; -extern const ProtobufCMessageDescriptor signature_info__descriptor; -extern const ProtobufCMessageDescriptor temporary_exposure_key__descriptor; -extern const ProtobufCEnumDescriptor temporary_exposure_key__report_type__descriptor; -extern const ProtobufCMessageDescriptor teksignature_list__descriptor; -extern const ProtobufCMessageDescriptor teksignature__descriptor; - -PROTOBUF_C__END_DECLS - - -#endif /* PROTOBUF_C_export_2eproto__INCLUDED */ diff --git a/include/extract_keys.h b/include/extract_keys.h deleted file mode 100644 index 5e25364..0000000 --- a/include/extract_keys.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef EXTRACT_KEYS_H -#define EXTRACT_KEYS_H - -#include "export.pb-c.h" - -/** - * @brief Process a key. This function could trigger the comparision between the key and those registered by the ENS. - * - * @param key A pointer to the Exposure key data structure - */ -void process_key(TemporaryExposureKey* key); - -/** - * @brief Generates a protocol buffer containing dummy keys. - * - * @param buffer_pointer A pointer to the pointer which will be used to reference the buffer externally. This will be - * set to the memory area allocated to store the protocol buffer. - * @param num_keys The number of keys that will be generated - * @return size_t The size of the protocol buffer - */ -size_t generate_keys(uint8_t** buffer_pointer, int num_keys); - -/** - * @brief Unpacks the protocol buffer and iterates the `process_key` function over all keys. - * - * @param buf a pointer to the buffer - * @param buf_size the size of the buffer in bytes - * @return int - */ -int unpack_keys(uint8_t* buf, size_t buf_size); - -/** - * @brief Generates an protocol buffer with a specified number of keys and measures the time to execute `unpack_keys`, - * which unpacks the protocol buffer and iterates `process_key` over the keys. - * - * @param num_keys the number of keys that will be created - * @return int - */ -int test_unpacking(int num_keys); - -#endif \ No newline at end of file diff --git a/include/gatt_service.h b/include/gatt_service.h deleted file mode 100644 index 7e7c797..0000000 --- a/include/gatt_service.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2020 Olaf Landsiedel - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef GATT_SERVICE_H -#define GATT_SERVICE_H - -int init_gatt(void); -int do_gatt(void); - -#endif diff --git a/include/record_storage.h b/include/record_storage.h new file mode 100644 index 0000000..9e457a8 --- /dev/null +++ b/include/record_storage.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2020 Olaf Landsiedel + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef RECORD_STORAGE_H +#define RECORD_STORAGE_H + +#include +#include "utility/sequencenumber.h" +#include + + + +/** + * RECORD STORAGE + */ +typedef uint64_t storage_id_t; + +typedef struct bt_metadata { + uint8_t version; + uint8_t tx_power; + uint8_t rsv1; + uint8_t rsv2; +} __packed bt_metadata_t; + +typedef struct associated_encrypted_metadata { + uint8_t data[sizeof(bt_metadata_t)]; +} __packed associated_encrypted_metadata_t; + +typedef struct record { + record_sequence_number_t sn; // TODO: Convert Sequence Number + uint32_t timestamp; // TODO: Seconds from january first 2000 (UTC+0) + uint8_t rssi; // TODO: Check correct + ENIntervalIdentifier rolling_proximity_identifier; + associated_encrypted_metadata_t associated_encrypted_metadata; +} __packed record_t; + +typedef struct stored_records_information { + record_sequence_number_t oldest_contact; + uint32_t count; +} stored_records_information_t; + +/** + * Initializes the contact storage component + * @param clean flag for indicating, if storage shall be init with clean state + * + * @return 0 for success + */ +int record_storage_init(bool clean); + +/** + * Reset state of record storage. + */ +void reset_record_storage(); + +/** + * Loads the record with number sn into the destination struct + * @param dest + * @param sn + * @return 0 in case of success + */ +int load_record(record_t* dest, record_sequence_number_t sn); + +/** + * Stores the record from src with number sn, increases latest sequence number + * @param sn + * @param src + * @return 0 in case of success + */ +int add_record(record_t* src); + +/** + * Deletes the record from storage with number sn + * @param sn the sequence number to delete + * @return 0 in case of success + */ +int delete_record(record_sequence_number_t sn); + +/** + * TODO: How to handle if none is available? + * @return The latest available sequence number (Caution: can actually be lower than the oldes in case of a + * wrap-around!) + */ +record_sequence_number_t get_latest_sequence_number(); + +/** + * TODO: How to handle if none is available? + * @return The oldest available sequence number + */ +record_sequence_number_t get_oldest_sequence_number(); + +/** + * @return The amount of contacts, usually get_latest_sequence_number() - get_oldest_sequence_number() + */ +uint32_t get_num_records(); + +int get_sequence_number_interval(record_sequence_number_t* oldest, record_sequence_number_t* latest); + +/** + * RECORD ITERATOR + */ +typedef struct record_iterator { + /** + * @internal + */ + record_t current; + /** + * @internal + */ + record_sequence_number_t sn_next; + /** + * @internal + */ + record_sequence_number_t sn_end; // the last sn to include + /** + * @internal + */ + uint8_t finished; +} record_iterator_t; + +// Also uses start and end from storage if NULL pointers given +// iterate over a sequence number range of records (Null will select the latest and newest for start / end) +// automatically +int ens_records_iterator_init_range(record_iterator_t* iterator, + record_sequence_number_t* opt_start, + record_sequence_number_t* opt_end); + +// TODO: Do we guarantee that higher sequence numbers have at least our timestamp and lower sequence numbers up to our +// timestamp? +int ens_records_iterator_init_timerange(record_iterator_t* iterator, time_t* ts_start, time_t* ts_end); + +record_t* ens_records_iterator_next(record_iterator_t* iter); + +int ens_record_iterator_clear(record_iterator_t* iter); + +// TODO: Is a callback the easiest thing to do? -> now it is the iterator :) +// TODO: should we really indicated the last record by sending a NULL pointer? +typedef uint8_t (*ens_record_iterator_cb_t)(const record_t* record, void* userdata); + +enum { + ENS_RECORD_ITER_STOP, // STOP the iteration, this would not result in a NULL callback after the end is reached + ENS_RECORD_ITER_CONTINUE, // CONTINUE the iteration, this results in a NULL callback after the end is reached +}; + +// TODO: this function could be made asynchronous to handle delays in contact_storage reads?! +// TODO: How can we handle iteration while records are being added or deleted? (should be safe as long as the +// load_record function is thread safe?!) +uint8_t ens_records_iterate_with_callback(record_iterator_t* iter, ens_record_iterator_cb_t cb, void* userdata); + +#endif \ No newline at end of file diff --git a/include/sync_service.h b/include/sync_service.h new file mode 100644 index 0000000..7a9fad6 --- /dev/null +++ b/include/sync_service.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2020 Olaf Landsiedel + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SYNC_SERVICE_H +#define SYNC_SERVICE_H + +int sync_service_init(void); +int sync_service_run(void); + +#endif diff --git a/include/tek_storage.h b/include/tek_storage.h new file mode 100644 index 0000000..e508020 --- /dev/null +++ b/include/tek_storage.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 Olaf Landsiedel + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef tek_storage_H +#define tek_storage_H + +#include +#include +#include "utility/sequencenumber.h" +#include "record_storage.h" + +typedef struct tek { + uint32_t timestamp; // Seconds from january first 2000 (UTC+0) + ENPeriodKey tek; // the temporary exposure key +} __packed tek_t; + +/** + * Initializes the contact storage component + * @param clean flag for indicating, if storage shall be init with clean state + * + * @return 0 for success + */ +int tek_storage_init(bool clean); + +int tek_storage_add(tek_t* src); +int tek_storage_delete(tek_t* src); + +/** + * Returns 0 on success, else non zero (if none available) + */ +int tek_storage_get_latest_at_ts(tek_t* dest, uint32_t timestamp); + +#endif \ No newline at end of file diff --git a/include/io.h b/include/tracing.h similarity index 53% rename from include/io.h rename to include/tracing.h index f2499a8..91a908b 100644 --- a/include/io.h +++ b/include/tracing.h @@ -1,14 +1,13 @@ -/* io.h - Application main entry point */ - /* * Copyright (c) 2020 Olaf Landsiedel * * SPDX-License-Identifier: Apache-2.0 */ -#ifndef IO_H -#define IO_H +#ifndef TRACING_H +#define TRACING_H -int init_io(); +int tracing_init(void); +int tracing_run(void); #endif \ No newline at end of file diff --git a/include/util.h b/include/util.h deleted file mode 100644 index 79c2e6e..0000000 --- a/include/util.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef UTIL_H -#define UTIL_H - -// TODO: We should use timeutil_sync - -// return the current unix timestamp in seconds -uint32_t time_get_unix_seconds(); - -#endif // UTIL_H \ No newline at end of file diff --git a/include/ens/ens_fs.h b/include/utility/ens_fs.h similarity index 91% rename from include/ens/ens_fs.h rename to include/utility/ens_fs.h index 3e9cc6a..72588d8 100644 --- a/include/ens/ens_fs.h +++ b/include/utility/ens_fs.h @@ -7,6 +7,12 @@ #include #include +#define ENS_INTERR 1 // internal error +#define ENS_NOENT 2 // entry not found or invalid +#define ENS_DELENT 3 // entry got deleted +#define ENS_ADDRINU 4 // address alread in use or corrupt +#define ENS_INVARG 5 // invalid argument + typedef struct ens_fs { /** * Flash area for this file system. diff --git a/include/ens/sequencenumber.h b/include/utility/sequencenumber.h similarity index 100% rename from include/ens/sequencenumber.h rename to include/utility/sequencenumber.h diff --git a/include/utility/util.h b/include/utility/util.h new file mode 100644 index 0000000..0740b93 --- /dev/null +++ b/include/utility/util.h @@ -0,0 +1,16 @@ +#ifndef UTIL_H +#define UTIL_H + +#include +#include "../record_storage.h" // TODO: this dependency is not great... + +// TODO: We should use timeutil_sync + +// return the current unix timestamp in seconds +uint32_t time_get_unix_seconds(); + +void print_key(_ENBaseKey* key); +void print_rpi(ENIntervalIdentifier* rpi); +void print_aem(associated_encrypted_metadata_t* aem); + +#endif // UTIL_H \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index f5ac943..c00fb1d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -16,7 +16,7 @@ platform = nordicnrf52@7.0.0 board = nrf52840_dk framework = zephyr monitor_speed = 115200 -upload_protocol = jlink +;upload_protocol = jlink test_ignore = test_desktop build_flags = -Iinclude/tls_config @@ -28,12 +28,12 @@ lib_deps = prathje/exposure-notification @ ^0.1 lib_ignore = mbedtls -src_filter = -<../src/main_test.c> +;src_filter = -<../src/main_test.c> -[env:nrf52840_dk_test] -src_filter = -<../src/main.c> -extends = env:nrf52840_dk -board = nrf52840_mdk +;[env:nrf52840_dk_test] +;src_filter = -<../src/main.c> +;extends = env:nrf52840_dk +;board = nrf52840_mdk [env:nrf52840_mdk] diff --git a/src/bloom.c b/src/bloom.c deleted file mode 100644 index 4787ed3..0000000 --- a/src/bloom.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "bloom.h" -#include "ens/storage.h" -#include "exposure-notification.h" - -bloom_filter_t* bloom_init(size_t size) { - bloom_filter_t* bloom = k_calloc(1, sizeof(bloom_filter_t)); - if (!bloom) { - return NULL; - } - bloom->size = size; - bloom->data = k_calloc(size, sizeof(uint8_t)); - if (!bloom->data) { - bloom->size = 0; - k_free(bloom); - return NULL; - } - return bloom; -} - -void bloom_destroy(bloom_filter_t* bloom) { - if (bloom) { - k_free(bloom->data); - k_free(bloom); - } -} - -void bloom_add_record(bloom_filter_t* bloom, ENIntervalIdentifier* rpi) { - uint8_t* data = bloom->data; - for (int i = 0; i < sizeof(*rpi); i += 2) { - uint32_t hash = (rpi->b[i] << 8) | rpi->b[i + 1]; - hash %= bloom->size * 8; - data[hash / 8] |= 1 << (hash % 8); - } -} - -bool bloom_probably_has_record(bloom_filter_t* bloom, ENIntervalIdentifier* rpi) { - uint8_t* data = bloom->data; - for (int i = 0; i < sizeof(*rpi); i += 2) { - uint32_t hash = (rpi->b[i] << 8) | rpi->b[i + 1]; - hash %= bloom->size * 8; - if (!(data[hash / 8] & (1 << (hash % 8)))) { - return false; - } - } - return true; -} diff --git a/src/contacts.c b/src/contacts.c deleted file mode 100644 index c69526d..0000000 --- a/src/contacts.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (c) 2020 Olaf Landsiedel - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include "bloom.h" -#include "contacts.h" -#include "covid.h" -#include "covid_types.h" -#include "ens/records.h" -#include "ens/storage.h" -#include "exposure-notification.h" - -// #define CONFIG_INTERVAL_SPREAD 100 - -void print_key(_ENBaseKey* key) { - for (int i = 0; i < sizeof(key->b); i++) { - printk("%02x", key->b[i]); - } -} - -void print_rpi(rolling_proximity_identifier_t* rpi) { - for (int i = 0; i < sizeof(rolling_proximity_identifier_t); i++) { - printk("%02x", rpi->b[i]); - } -} - -void print_aem(associated_encrypted_metadata_t* aem) { - for (int i = 0; i < sizeof(associated_encrypted_metadata_t); i++) { - printk("%02x", aem->data[i]); - } -} - -int register_record(record_t* record) { - return add_record(record); -} - -/** - * Simple implementation, where an iterator is created for every element in the passed arrray. - */ -int get_number_of_infected_for_multiple_intervals_simple(infected_for_interval_ident_ctx_t* ctx, int count) { - record_iterator_t iterator; - for (int i = 0; i < count; i++) { - if (!ctx[i].met) { - continue; - } - ctx[i].met = 0; - int rc = ens_records_iterator_init_timerange(&iterator, &ctx[i].search_start, &ctx[i].search_end); - if (rc) { - // on error, skip this rpi - continue; - } - record_t* current; - while ((current = ens_records_iterator_next(&iterator))) { - if (memcmp(&(current->rolling_proximity_identifier), &ctx[i].interval_identifier, - sizeof(rolling_proximity_identifier_t)) == 0) { - ctx[i].met++; - } - } - } - return 0; -} - -/** - * Fill the bloom filter with all stored records. - */ -void fill_bloom_with_stored_records(bloom_filter_t* bloom) { - // init iterator for filling bloom filter - record_iterator_t iterator; - int rc = ens_records_iterator_init_timerange(&iterator, NULL, NULL); - if (rc) { - printk("init iterator failed0 (err %d)\n", rc); - return; - } - - // fill bloom filter with records - record_t* current; - while ((current = ens_records_iterator_next(&iterator))) { - bloom_add_record(bloom, &(current->rolling_proximity_identifier)); - } -} - -/** - * Fill the bloom filter with flash records and test passed RPIs against it. - */ -int64_t bloom_filter(infected_for_interval_ident_ctx_t* ctx, int count) { - bloom_filter_t* bloom = bloom_init(get_num_records() * 2); - if (!bloom) { - printk("bloom init failed\n"); - return -1; - } - - fill_bloom_with_stored_records(bloom); - - // test bloom performance - for (int i = 0; i < count; i++) { - if (bloom_probably_has_record(bloom, &ctx[i].interval_identifier)) { - ctx[i].met++; - } - } - bloom_destroy(bloom); - - return get_number_of_infected_for_multiple_intervals_simple(ctx, count); -} - -//////////////////// -// FILL TEST DATA // -//////////////////// - -static ENPeriodKey infectedPeriodKey = { - .b = {0x75, 0xc7, 0x34, 0xc6, 0xdd, 0x1a, 0x78, 0x2d, 0xe7, 0xa9, 0x65, 0xda, 0x5e, 0xb9, 0x31, 0x25}}; -static ENPeriodKey dummyPeriodKey = { - .b = {0x89, 0xa7, 0x34, 0xc6, 0xdd, 0x1a, 0x14, 0xda, 0xe7, 0x00, 0x65, 0xda, 0x6a, 0x9b, 0x13, 0x52}}; -static ENPeriodKey testKey = { - .b = {0x89, 0xa7, 0x72, 0xc6, 0xdd, 0x10, 0x14, 0xda, 0xe7, 0x00, 0x65, 0xda, 0x8a, 0x9b, 0x13, 0x52}}; - -static ENPeriodIdentifierKey infectedPik; -static ENPeriodIdentifierKey dummyPik; -static ENPeriodIdentifierKey testPik; - -void fill_test_rki_data(infected_for_interval_ident_ctx_t* infectedIntervals, int count) { - int totalTime = EN_TEK_ROLLING_PERIOD * EN_INTERVAL_LENGTH; - int stepSize = totalTime / count; - for (int i = 0; i < count; i++) { - int intervalNumber = (i * stepSize) / EN_INTERVAL_LENGTH; - en_derive_interval_identifier(&infectedIntervals[i].interval_identifier, &infectedPik, intervalNumber); - infectedIntervals[i].met = 0; - infectedIntervals[i].search_start = i < 3 ? 0 : (i - 2) * stepSize; - infectedIntervals[i].search_end = (i + 2) * stepSize; - } -} - -//////////////////// -// MEASURING FUNC // -//////////////////// - -void measure_perf(infected_for_interval_ident_ctx_t testIntervals[], int count) { - const char* label = "bloom filter"; - printk("---------------------------\n'%s': starting measurement\n", label); - - // fill_test_rki_data(infectedIntervals, count); - - // setup our ordered array with met RPIs - printk("Starting measurements with %d RPIs to seach and an infection rate of %d\n", count, - CONFIG_TEST_INFECTED_RATE); - - timing_t start_time, end_time; - uint64_t total_cycles; - uint64_t total_ns; - - timing_init(); - timing_start(); - start_time = timing_counter_get(); - - check_possible_contacts_for_intervals(testIntervals, count); - - end_time = timing_counter_get(); - - total_cycles = timing_cycles_get(&start_time, &end_time); - total_ns = timing_cycles_to_ns(total_cycles); - - timing_stop(); - - printk("\n'%s' took %lld ms\n---------------------------\n", label, total_ns / 1000000); -} - -void check_results(infected_for_interval_ident_ctx_t testIntervals[], int count) { - int counter = 0; - for (int i = 0; i < count / 2; i++) { - counter += CONFIG_TEST_RECORDS_PER_INTERVAL * CONFIG_TEST_INFECTED_RATE; - int met = counter / 100; - counter %= 100; - if (testIntervals[i].met != met) { - printk("interval %d should have been met %d times (met %d)\n", i, met, testIntervals[i].met); - return; - } - } - - for (int j = count / 2; j < count; j++) { - if (testIntervals[j].met) { - printk("infected interval should not have been met (interval %d)\n", j); - return; - } - } - printk("all results are as expected!\n"); -} - -int reverse_bloom_filter(infected_for_interval_ident_ctx_t* ctx, int count) { - bloom_filter_t* bloom = bloom_init(count * 2); - if (!bloom) { - printk("bloom init failed\n"); - return -1; - } - - // init bloom filter with passed records - for (int i = 0; i < count; i++) { - bloom_add_record(bloom, &ctx[i].interval_identifier); - } - - int rc = 0; - - // init iterator over the entire storage - record_iterator_t iterator; - rc = ens_records_iterator_init_timerange(&iterator, NULL, NULL); - if (rc) { - printk("init iterator failed (err %d)\n", rc); - goto cleanup; - } - - record_t* current; - while ((current = ens_records_iterator_next(&iterator))) { - if (bloom_probably_has_record(bloom, &(current->rolling_proximity_identifier))) { - for (int i = 0; i < count; i++) { - if (memcmp(&(current->rolling_proximity_identifier), &ctx[i].interval_identifier, - sizeof(current->rolling_proximity_identifier)) == 0) { - ctx[i].met++; - } - } - } - } - -cleanup: - // destroy bloom filter after things are finished - bloom_destroy(bloom); - return rc; -} - -//////////////////// -// SETUP DATA // -//////////////////// - -void setup_test_data(infected_for_interval_ident_ctx_t testIntervals[], int count) { - en_derive_period_identifier_key(&infectedPik, &infectedPeriodKey); - en_derive_period_identifier_key(&dummyPik, &dummyPeriodKey); - en_derive_period_identifier_key(&testPik, &testKey); - - int counter = 0; - for (int i = 0; i < EN_TEK_ROLLING_PERIOD; i++) { - record_t infectedRecord; - record_t dummyRecord; - en_derive_interval_identifier((ENIntervalIdentifier*)&infectedRecord.rolling_proximity_identifier, &infectedPik, - i); - en_derive_interval_identifier((ENIntervalIdentifier*)&dummyRecord.rolling_proximity_identifier, &dummyPik, i); - - for (int j = 0; j < CONFIG_TEST_RECORDS_PER_INTERVAL; j++) { - counter += CONFIG_TEST_INFECTED_RATE; - record_t* curRecord; - if (counter >= 100) { - counter -= 100; - curRecord = &infectedRecord; - } else { - curRecord = &dummyRecord; - } - curRecord->timestamp = i * EN_INTERVAL_LENGTH + j * (EN_INTERVAL_LENGTH / CONFIG_TEST_RECORDS_PER_INTERVAL); - int rc = add_record(curRecord); - if (rc) { - printk("err %d\n", rc); - } - } - } - - for (int i = 0; i < count / 2; i++) { - en_derive_interval_identifier(&testIntervals[i].interval_identifier, &infectedPik, i); - testIntervals[i].met = 0; - testIntervals[i].search_start = MAX(0, (i * EN_INTERVAL_LENGTH - 2 * 60 * 60)); - testIntervals[i].search_end = i * EN_INTERVAL_LENGTH + 2 * 60 * 60; - - int j = i + count / 2; - en_derive_interval_identifier(&testIntervals[j].interval_identifier, &testPik, i); - testIntervals[j].met = 0; - testIntervals[j].search_start = MAX(0, (i * EN_INTERVAL_LENGTH - 2 * 60 * 60)); - testIntervals[j].search_end = i * EN_INTERVAL_LENGTH + 2 * 60 * 60; - } -} - -int init_contacts() { -#if CONFIG_CONTACTS_PERFORM_RISC_CHECK_TEST - static infected_for_interval_ident_ctx_t testIntervals[EN_TEK_ROLLING_PERIOD * 2]; - - reset_record_storage(); - setup_test_data(testIntervals, EN_TEK_ROLLING_PERIOD * 2); - - measure_perf(testIntervals, EN_TEK_ROLLING_PERIOD * 2); - check_results(testIntervals, EN_TEK_ROLLING_PERIOD * 2); -#endif - return 0; -} - -int check_possible_contacts_for_intervals(infected_for_interval_ident_ctx_t* ctx, int count) { -#if CONFIG_CONTACTS_BLOOM_REVERSE - return reverse_bloom_filter(ctx, count); -#else - return bloom_filter(ctx, count); -#endif -} - -int check_possible_contacts_for_periods(period_key_information_t periodKeyInformation[], int count) { - for (int i = 0; i < count; i++) { - static infected_for_interval_ident_ctx_t intervalIdents[EN_TEK_ROLLING_PERIOD]; - int periodStart = en_get_interval_number(periodKeyInformation[i].start); - for (int interval = 0; interval < EN_TEK_ROLLING_PERIOD; interval++) { - en_derive_interval_identifier(&intervalIdents[interval].interval_identifier, - &periodKeyInformation[i].periodKey, periodStart + interval); - } - int rc = check_possible_contacts_for_intervals(intervalIdents, 0); - if (rc < 0) { - return rc; - } - periodKeyInformation[i].met = rc; - } - return 0; -} diff --git a/src/display.c b/src/display.c deleted file mode 100644 index e5cfd1a..0000000 --- a/src/display.c +++ /dev/null @@ -1,258 +0,0 @@ -#if CONFIG_DISPLAY -#include -#include -#include -#endif -#include -#include -#include - -#include "display.h" - -K_THREAD_STACK_DEFINE(display_stack_area, 5000); - -#if CONFIG_DISPLAY -const struct device* display_dev; -lv_obj_t* display_center_pane; -lv_obj_t* display_top_bar; -lv_obj_t* display_bot_bar; -lv_obj_t* display_contacts_label; -lv_obj_t* display_risk_contacts_label; -lv_obj_t* risk_contacts_button; -lv_obj_t* display_clock_label; -lv_obj_t* display_battery_label; -lv_obj_t* display_memory_label; -lv_obj_t* display_msg_label; -lv_style_t green_button_style; -lv_style_t yellow_button_style; -lv_style_t red_button_style; -#endif - - -int get_battery_percentage() { - // TODO: Implement - return 0; -} - -int get_memory_percentage() { - // TODO: Implement - return 0; -} - -int get_time() { - // TODO: Implement - return 0; -} - -int get_contacts() { - // TODO: Implement - return 0; -} - -int get_risk_contacts() { - // TODO: Implement - return 0; -} - -#if CONFIG_DISPLAY - -void display_thread(void* arg1, void* arg2, void* arg3) { - static uint32_t sleep_time; - while (1) { - sleep_time = lv_task_handler(); - update_display(); - k_msleep(sleep_time); - } -} - -int init_styles() { - lv_style_init(&green_button_style); - lv_style_init(&yellow_button_style); - lv_style_init(&red_button_style); - - // Properties for all styles - lv_style_set_bg_opa(&green_button_style, LV_STATE_DEFAULT, LV_OPA_COVER); - lv_style_set_pad_top(&green_button_style, LV_STATE_DEFAULT, 10); - lv_style_set_pad_bottom(&green_button_style, LV_STATE_DEFAULT, 10); - lv_style_set_pad_left(&green_button_style, LV_STATE_DEFAULT, 10); - lv_style_set_pad_right(&green_button_style, LV_STATE_DEFAULT, 10); - lv_style_set_border_width(&green_button_style, LV_STATE_DEFAULT, 1); - lv_style_set_radius(&green_button_style, LV_STATE_DEFAULT, 10); - - lv_style_copy(&yellow_button_style, &green_button_style); - lv_style_copy(&red_button_style, &green_button_style); - - // Set different colors - lv_style_set_bg_color(&green_button_style, LV_STATE_DEFAULT, LV_COLOR_GREEN); - lv_style_set_text_color(&green_button_style, LV_STATE_DEFAULT, LV_COLOR_WHITE); - lv_style_set_bg_color(&yellow_button_style, LV_STATE_DEFAULT, LV_COLOR_YELLOW); - lv_style_set_text_color(&yellow_button_style, LV_STATE_DEFAULT, LV_COLOR_BLACK); - lv_style_set_bg_color(&red_button_style, LV_STATE_DEFAULT, LV_COLOR_RED); - lv_style_set_text_color(&red_button_style, LV_STATE_DEFAULT, LV_COLOR_WHITE); - - return 0; -} - -int update_display() { - display_set_contacts(get_contacts()); - display_set_risk_contacts(get_risk_contacts()); - display_set_time(get_time()); - display_set_bat(get_battery_percentage()); - display_set_mem(get_memory_percentage()); - - lv_task_handler(); - - return 0; -} - -int init_display() { - init_styles(); - - display_dev = device_get_binding(CONFIG_LVGL_DISPLAY_DEV_NAME); - - if (display_dev == NULL) { - printk("device not found. Aborting test."); - return -1; - } - - display_top_bar = lv_cont_create(lv_scr_act(), NULL); - lv_obj_set_width(display_top_bar, lv_obj_get_width(lv_scr_act())); - lv_cont_set_layout(display_top_bar, LV_LAYOUT_PRETTY_TOP); - - display_bot_bar = lv_cont_create(lv_scr_act(), NULL); - lv_obj_set_width(display_bot_bar, lv_obj_get_width(lv_scr_act())); - lv_cont_set_layout(display_bot_bar, LV_LAYOUT_PRETTY_BOTTOM); - - display_center_pane = lv_cont_create(lv_scr_act(), NULL); - lv_obj_align(display_center_pane, display_top_bar, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0); - lv_obj_set_width(display_center_pane, lv_obj_get_width(lv_scr_act())); - lv_obj_set_height(display_center_pane, lv_obj_get_height(lv_scr_act()) - lv_obj_get_height(display_top_bar) - lv_obj_get_height(display_bot_bar)); - lv_cont_set_layout(display_center_pane, LV_LAYOUT_COLUMN_MID); - - lv_obj_align(display_bot_bar, display_center_pane, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0); - - display_contacts_label = lv_label_create(display_center_pane, NULL); - lv_obj_set_height_margin(display_contacts_label, 20); - lv_label_set_text(display_contacts_label, ""); - - if (IS_ENABLED(CONFIG_LVGL_POINTER_KSCAN)) { - risk_contacts_button = lv_btn_create(display_center_pane, NULL); - lv_btn_set_fit(risk_contacts_button, LV_FIT_TIGHT); - display_risk_contacts_label = lv_label_create(risk_contacts_button, NULL); - } else { - display_risk_contacts_label = lv_label_create(display_center_pane, NULL); - } - - lv_obj_set_height_margin(display_risk_contacts_label, 20); - lv_label_set_text(display_risk_contacts_label, ""); - - display_memory_label = lv_label_create(display_top_bar, NULL); - lv_obj_set_width_margin(display_memory_label, 10); - lv_label_set_text(display_memory_label, ""); - - display_clock_label = lv_label_create(display_top_bar, NULL); - lv_obj_set_width_margin(display_clock_label, 10); - lv_label_set_text(display_clock_label, ""); - - display_battery_label = lv_label_create(display_top_bar, NULL); - lv_obj_set_width_margin(display_battery_label, 10); - lv_label_set_text(display_battery_label, ""); - - display_msg_label = lv_label_create(display_bot_bar, NULL); - lv_label_set_text(display_msg_label, ""); - - static struct k_thread display_thread_data; - k_thread_create(&display_thread_data, display_stack_area, K_THREAD_STACK_SIZEOF(display_stack_area), display_thread, NULL, NULL, NULL, 0, 0, K_NO_WAIT); - - display_blanking_off(display_dev); - - return 0; -} - -int display_set_message(char* msg) { - lv_label_set_text(display_msg_label, msg); - return 0; -} - -int display_set_time(int time) { - lv_label_set_text_fmt(display_clock_label, "%d:%d", time / 100, time % 100) - return 0; -} - -int display_set_bat(int bat) { - lv_label_set_text_fmt(display_battery_label, "Bat: %d%%", bat); - return 0; -} - -int display_set_mem(int mem) { - lv_label_set_text_fmt(display_memory_label, "Mem: %d%%", mem); - return 0; -} - -int display_set_contacts(int contacts) { - lv_label_set_text_fmt(display_contacts_label, "Number of contacts: %d,\nfrom which", contacts); - return 0; -} - -int display_set_risk_contacts(int risk_contacts) { - lv_label_set_text_fmt(display_risk_contacts_label, "%d are risk contacts.", risk_contacts); - - if (risk_contacts == 0) { - // Set Button green - lv_obj_reset_style_list(risk_contacts_button, LV_OBJ_PART_MAIN); - lv_obj_add_style(risk_contacts_button, LV_BTN_PART_MAIN, &green_button_style); - } else if (risk_contacts < 5) { - // Set Button yellow - lv_obj_reset_style_list(risk_contacts_button, LV_OBJ_PART_MAIN); - lv_obj_add_style(risk_contacts_button, LV_BTN_PART_MAIN, &yellow_button_style); - } else { - // Set Button red - lv_obj_reset_style_list(risk_contacts_button, LV_OBJ_PART_MAIN); - lv_obj_add_style(risk_contacts_button, LV_BTN_PART_MAIN, &red_button_style); - } - return 0; -} - -#else - -void display_thread(void* arg1, void* arg2, void* arg3) { - // Do nothing -} - -int init_styles() { - return 0; -} - -int update_display() { - return 0; -} - -int init_display() { - return 0; -} - -int display_set_message(char* msg) { - return 0; -} - -int display_set_time(int time) { - return 0; -} - -int display_set_bat(int bat) { - return 0; -} - -int display_set_mem(int mem) { - return 0; -} - -int display_set_contacts(int contacts) { - return 0; -} - -int display_set_risk_contacts(int risk_contacts) { - return 0; -} - -#endif diff --git a/src/ens/records.c b/src/ens/records.c deleted file mode 100644 index 6eeadff..0000000 --- a/src/ens/records.c +++ /dev/null @@ -1,208 +0,0 @@ -#include - -#include -#include "covid_types.h" -#include "ens/ens_error.h" -#include "ens/records.h" -#include "ens/sequencenumber.h" -#include "ens/storage.h" - -int ens_records_iterator_init_range(record_iterator_t* iterator, - record_sequence_number_t* opt_start, - record_sequence_number_t* opt_end) { - // prevent any changes during initialization - int rc = get_sequence_number_interval(&iterator->sn_next, &iterator->sn_end); - if (rc == 0) { - iterator->finished = false; - - // we override start and end with the optional values - if (opt_start) { - iterator->sn_next = *opt_start; - } - if (opt_end) { - iterator->sn_end = *opt_end; - } - } else { - iterator->finished = true; - } - - return 0; -} - -int64_t get_timestamp_for_sn(record_sequence_number_t sn) { - record_t rec; - if (load_record(&rec, sn) == 0) { - return rec.timestamp; - } else { - return -1; - } -} - -enum record_timestamp_search_mode { - RECORD_TIMESTAMP_SEARCH_MODE_MIN, - RECORD_TIMESTAMP_SEARCH_MODE_MAX, -}; - -/** - * Find an entry via binary search for the timestamp. - * - * @param record pointer to the location, where the found sn shall be stored - * @param target timestamp for which to find the nearest entry for - * @param greater flag for indicating, if the loaded sn shall correspond to a greater (1) or smaller (0) timestamp - */ -int find_sn_via_binary_search(record_sequence_number_t* sn_dest, - uint32_t target, - enum record_timestamp_search_mode search_mode) { - record_sequence_number_t start_sn; - record_sequence_number_t end_sn; - - // prevent any changes during binary search initialization - - int rc = get_sequence_number_interval(&start_sn, &end_sn); - - if (rc) { - return rc; - } - - record_sequence_number_t last_sn = - start_sn; // used to check if ran into issues, e.g. could not load the entry or rounding errors - - while (!sn_equal(start_sn, end_sn)) { - // calculate the sn in the middle between start and end - record_sequence_number_t cur_sn = sn_get_middle_sn(start_sn, end_sn); - - if (sn_equal(cur_sn, last_sn)) { - // if we already checked this entry -> we reduce our boundaries and try again - // this also solves issues with rounding - // TODO: This is not the best way... - if (search_mode == RECORD_TIMESTAMP_SEARCH_MODE_MIN) { - int64_t start_ts = get_timestamp_for_sn(start_sn); - if (start_ts == -1 || start_ts < target) { - // we could not load this entry or this entry is strictly smaller than our target - start_sn = sn_increment(start_sn); // we can safely increment as start_sn < end_sn - } else { - // we actually found the wanted entry! - end_sn = start_sn; // this will break our loop - } - } else { - // we search for the biggest value among them - int64_t end_ts = get_timestamp_for_sn(end_sn); - if (end_ts == -1 || end_ts > target) { - // we could not load this entry or this entry is strictly bigger than our target - end_sn = sn_decrement(end_sn); // we can safely decrement as start_sn < end_sn - } else { - // we actually found the wanted entry! - start_sn = end_sn; // this will break our loop - } - } - } else { - int64_t mid_ts = get_timestamp_for_sn(cur_sn); - - if (mid_ts >= 0) { - if (target < mid_ts) { - end_sn = cur_sn; - } else if (target > mid_ts) { - start_sn = cur_sn; - } else { - // target == mid_ts - if (search_mode == RECORD_TIMESTAMP_SEARCH_MODE_MIN) { - // we search for the smallest value among them -> look before this item - end_sn = cur_sn; - } else { - // we search for the biggest value among them -> look after this item - start_sn = cur_sn; - } - } - } else { - // some errors -> we keep the current sn and try to narrow our boundaries - } - } - last_sn = cur_sn; - } - - *sn_dest = start_sn; // == end_sn - - return 0; -} - -// TODO: This iterator does neither check if the sequence numbers wrapped around while iteration. As a result, first -// results could have later timestamps than following entries -int ens_records_iterator_init_timerange(record_iterator_t* iterator, time_t* ts_start, time_t* ts_end) { - record_sequence_number_t oldest_sn = 0; - record_sequence_number_t newest_sn = 0; - - // assure that *ts_end > *ts_start - if (ts_start && ts_end && *ts_end < *ts_start) { - return 1; - } - - if (ts_start) { - int rc = find_sn_via_binary_search(&oldest_sn, *ts_start, RECORD_TIMESTAMP_SEARCH_MODE_MIN); - if (rc) { - return rc; - } - } else { - oldest_sn = get_oldest_sequence_number(); - } - - if (ts_end) { - int rc = find_sn_via_binary_search(&newest_sn, *ts_end, RECORD_TIMESTAMP_SEARCH_MODE_MAX); - if (rc) { - return rc; - } - } else { - newest_sn = get_latest_sequence_number(); - } - - return ens_records_iterator_init_range(iterator, &oldest_sn, &newest_sn); -} - -record_t* ens_records_iterator_next(record_iterator_t* iter) { - record_t* next = NULL; - - while (next == NULL && !iter->finished) { - record_t contact; - // try to load the next contact - int res = load_record(&contact, iter->sn_next); - - if (!res) { - next = &iter->current; - memcpy(next, &contact, sizeof(record_t)); - } - - if (sn_equal(iter->sn_next, iter->sn_end)) { - iter->finished = true; // this iterator will finish after this execution - } else { - // increase the current sn - iter->sn_next = sn_increment(iter->sn_next); - } - } - - return next; -} - -int ens_record_iterator_clear(record_iterator_t* iter) { - // clear all relevant fields in the iterator - iter->finished = true; - iter->sn_next = 0; - iter->sn_end = 0; - memset(&iter->current, 0, sizeof(iter->current)); - return 0; -} - -uint8_t ens_records_iterate_with_callback(record_iterator_t* iter, ens_record_iterator_cb_t cb, void* userdata) { - record_t* cur = ens_records_iterator_next(iter); - bool cont = true; - - while (cur != NULL && cont) { - int cb_res = cb(cur, userdata); - if (cb_res == ENS_RECORD_ITER_STOP) { - cont = false; - } - } - - if (cont) { - cb(NULL, userdata); // we call the callback one last time but with null data - } - return 0; -} diff --git a/src/export.pb-c.c b/src/export.pb-c.c deleted file mode 100644 index f364feb..0000000 --- a/src/export.pb-c.c +++ /dev/null @@ -1,682 +0,0 @@ -/* Generated by the protocol buffer compiler. DO NOT EDIT! */ -/* Generated from: export.proto */ - -/* Do not generate deprecated warnings for self */ -#ifndef PROTOBUF_C__NO_DEPRECATED -#define PROTOBUF_C__NO_DEPRECATED -#endif - -#include "export.pb-c.h" -void temporary_exposure_key_export__init - (TemporaryExposureKeyExport *message) -{ - static const TemporaryExposureKeyExport init_value = TEMPORARY_EXPOSURE_KEY_EXPORT__INIT; - *message = init_value; -} -size_t temporary_exposure_key_export__get_packed_size - (const TemporaryExposureKeyExport *message) -{ - assert(message->base.descriptor == &temporary_exposure_key_export__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); -} -size_t temporary_exposure_key_export__pack - (const TemporaryExposureKeyExport *message, - uint8_t *out) -{ - assert(message->base.descriptor == &temporary_exposure_key_export__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); -} -size_t temporary_exposure_key_export__pack_to_buffer - (const TemporaryExposureKeyExport *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &temporary_exposure_key_export__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); -} -TemporaryExposureKeyExport * - temporary_exposure_key_export__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (TemporaryExposureKeyExport *) - protobuf_c_message_unpack (&temporary_exposure_key_export__descriptor, - allocator, len, data); -} -void temporary_exposure_key_export__free_unpacked - (TemporaryExposureKeyExport *message, - ProtobufCAllocator *allocator) -{ - if(!message) - return; - assert(message->base.descriptor == &temporary_exposure_key_export__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); -} -void signature_info__init - (SignatureInfo *message) -{ - static const SignatureInfo init_value = SIGNATURE_INFO__INIT; - *message = init_value; -} -size_t signature_info__get_packed_size - (const SignatureInfo *message) -{ - assert(message->base.descriptor == &signature_info__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); -} -size_t signature_info__pack - (const SignatureInfo *message, - uint8_t *out) -{ - assert(message->base.descriptor == &signature_info__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); -} -size_t signature_info__pack_to_buffer - (const SignatureInfo *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &signature_info__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); -} -SignatureInfo * - signature_info__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (SignatureInfo *) - protobuf_c_message_unpack (&signature_info__descriptor, - allocator, len, data); -} -void signature_info__free_unpacked - (SignatureInfo *message, - ProtobufCAllocator *allocator) -{ - if(!message) - return; - assert(message->base.descriptor == &signature_info__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); -} -void temporary_exposure_key__init - (TemporaryExposureKey *message) -{ - static const TemporaryExposureKey init_value = TEMPORARY_EXPOSURE_KEY__INIT; - *message = init_value; -} -size_t temporary_exposure_key__get_packed_size - (const TemporaryExposureKey *message) -{ - assert(message->base.descriptor == &temporary_exposure_key__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); -} -size_t temporary_exposure_key__pack - (const TemporaryExposureKey *message, - uint8_t *out) -{ - assert(message->base.descriptor == &temporary_exposure_key__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); -} -size_t temporary_exposure_key__pack_to_buffer - (const TemporaryExposureKey *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &temporary_exposure_key__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); -} -TemporaryExposureKey * - temporary_exposure_key__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (TemporaryExposureKey *) - protobuf_c_message_unpack (&temporary_exposure_key__descriptor, - allocator, len, data); -} -void temporary_exposure_key__free_unpacked - (TemporaryExposureKey *message, - ProtobufCAllocator *allocator) -{ - if(!message) - return; - assert(message->base.descriptor == &temporary_exposure_key__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); -} -void teksignature_list__init - (TEKSignatureList *message) -{ - static const TEKSignatureList init_value = TEKSIGNATURE_LIST__INIT; - *message = init_value; -} -size_t teksignature_list__get_packed_size - (const TEKSignatureList *message) -{ - assert(message->base.descriptor == &teksignature_list__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); -} -size_t teksignature_list__pack - (const TEKSignatureList *message, - uint8_t *out) -{ - assert(message->base.descriptor == &teksignature_list__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); -} -size_t teksignature_list__pack_to_buffer - (const TEKSignatureList *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &teksignature_list__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); -} -TEKSignatureList * - teksignature_list__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (TEKSignatureList *) - protobuf_c_message_unpack (&teksignature_list__descriptor, - allocator, len, data); -} -void teksignature_list__free_unpacked - (TEKSignatureList *message, - ProtobufCAllocator *allocator) -{ - if(!message) - return; - assert(message->base.descriptor == &teksignature_list__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); -} -void teksignature__init - (TEKSignature *message) -{ - static const TEKSignature init_value = TEKSIGNATURE__INIT; - *message = init_value; -} -size_t teksignature__get_packed_size - (const TEKSignature *message) -{ - assert(message->base.descriptor == &teksignature__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); -} -size_t teksignature__pack - (const TEKSignature *message, - uint8_t *out) -{ - assert(message->base.descriptor == &teksignature__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); -} -size_t teksignature__pack_to_buffer - (const TEKSignature *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &teksignature__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); -} -TEKSignature * - teksignature__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (TEKSignature *) - protobuf_c_message_unpack (&teksignature__descriptor, - allocator, len, data); -} -void teksignature__free_unpacked - (TEKSignature *message, - ProtobufCAllocator *allocator) -{ - if(!message) - return; - assert(message->base.descriptor == &teksignature__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); -} -static const ProtobufCFieldDescriptor temporary_exposure_key_export__field_descriptors[8] = -{ - { - "start_timestamp", - 1, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_FIXED64, - offsetof(TemporaryExposureKeyExport, has_start_timestamp), - offsetof(TemporaryExposureKeyExport, start_timestamp), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "end_timestamp", - 2, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_FIXED64, - offsetof(TemporaryExposureKeyExport, has_end_timestamp), - offsetof(TemporaryExposureKeyExport, end_timestamp), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "region", - 3, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_STRING, - 0, /* quantifier_offset */ - offsetof(TemporaryExposureKeyExport, region), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "batch_num", - 4, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_INT32, - offsetof(TemporaryExposureKeyExport, has_batch_num), - offsetof(TemporaryExposureKeyExport, batch_num), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "batch_size", - 5, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_INT32, - offsetof(TemporaryExposureKeyExport, has_batch_size), - offsetof(TemporaryExposureKeyExport, batch_size), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "signature_infos", - 6, - PROTOBUF_C_LABEL_REPEATED, - PROTOBUF_C_TYPE_MESSAGE, - offsetof(TemporaryExposureKeyExport, n_signature_infos), - offsetof(TemporaryExposureKeyExport, signature_infos), - &signature_info__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "keys", - 7, - PROTOBUF_C_LABEL_REPEATED, - PROTOBUF_C_TYPE_MESSAGE, - offsetof(TemporaryExposureKeyExport, n_keys), - offsetof(TemporaryExposureKeyExport, keys), - &temporary_exposure_key__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "revised_keys", - 8, - PROTOBUF_C_LABEL_REPEATED, - PROTOBUF_C_TYPE_MESSAGE, - offsetof(TemporaryExposureKeyExport, n_revised_keys), - offsetof(TemporaryExposureKeyExport, revised_keys), - &temporary_exposure_key__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, -}; -static const unsigned temporary_exposure_key_export__field_indices_by_name[] = { - 3, /* field[3] = batch_num */ - 4, /* field[4] = batch_size */ - 1, /* field[1] = end_timestamp */ - 6, /* field[6] = keys */ - 2, /* field[2] = region */ - 7, /* field[7] = revised_keys */ - 5, /* field[5] = signature_infos */ - 0, /* field[0] = start_timestamp */ -}; -static const ProtobufCIntRange temporary_exposure_key_export__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 8 } -}; -const ProtobufCMessageDescriptor temporary_exposure_key_export__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "TemporaryExposureKeyExport", - "TemporaryExposureKeyExport", - "TemporaryExposureKeyExport", - "", - sizeof(TemporaryExposureKeyExport), - 8, - temporary_exposure_key_export__field_descriptors, - temporary_exposure_key_export__field_indices_by_name, - 1, temporary_exposure_key_export__number_ranges, - (ProtobufCMessageInit) temporary_exposure_key_export__init, - NULL,NULL,NULL /* reserved[123] */ -}; -static const ProtobufCFieldDescriptor signature_info__field_descriptors[3] = -{ - { - "verification_key_version", - 3, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_STRING, - 0, /* quantifier_offset */ - offsetof(SignatureInfo, verification_key_version), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "verification_key_id", - 4, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_STRING, - 0, /* quantifier_offset */ - offsetof(SignatureInfo, verification_key_id), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "signature_algorithm", - 5, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_STRING, - 0, /* quantifier_offset */ - offsetof(SignatureInfo, signature_algorithm), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, -}; -static const unsigned signature_info__field_indices_by_name[] = { - 2, /* field[2] = signature_algorithm */ - 1, /* field[1] = verification_key_id */ - 0, /* field[0] = verification_key_version */ -}; -static const ProtobufCIntRange signature_info__number_ranges[1 + 1] = -{ - { 3, 0 }, - { 0, 3 } -}; -const ProtobufCMessageDescriptor signature_info__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "SignatureInfo", - "SignatureInfo", - "SignatureInfo", - "", - sizeof(SignatureInfo), - 3, - signature_info__field_descriptors, - signature_info__field_indices_by_name, - 1, signature_info__number_ranges, - (ProtobufCMessageInit) signature_info__init, - NULL,NULL,NULL /* reserved[123] */ -}; -static const ProtobufCEnumValue temporary_exposure_key__report_type__enum_values_by_number[6] = -{ - { "UNKNOWN", "TEMPORARY_EXPOSURE_KEY__REPORT_TYPE__UNKNOWN", 0 }, - { "CONFIRMED_TEST", "TEMPORARY_EXPOSURE_KEY__REPORT_TYPE__CONFIRMED_TEST", 1 }, - { "CONFIRMED_CLINICAL_DIAGNOSIS", "TEMPORARY_EXPOSURE_KEY__REPORT_TYPE__CONFIRMED_CLINICAL_DIAGNOSIS", 2 }, - { "SELF_REPORT", "TEMPORARY_EXPOSURE_KEY__REPORT_TYPE__SELF_REPORT", 3 }, - { "RECURSIVE", "TEMPORARY_EXPOSURE_KEY__REPORT_TYPE__RECURSIVE", 4 }, - { "REVOKED", "TEMPORARY_EXPOSURE_KEY__REPORT_TYPE__REVOKED", 5 }, -}; -static const ProtobufCIntRange temporary_exposure_key__report_type__value_ranges[] = { -{0, 0},{0, 6} -}; -static const ProtobufCEnumValueIndex temporary_exposure_key__report_type__enum_values_by_name[6] = -{ - { "CONFIRMED_CLINICAL_DIAGNOSIS", 2 }, - { "CONFIRMED_TEST", 1 }, - { "RECURSIVE", 4 }, - { "REVOKED", 5 }, - { "SELF_REPORT", 3 }, - { "UNKNOWN", 0 }, -}; -const ProtobufCEnumDescriptor temporary_exposure_key__report_type__descriptor = -{ - PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, - "TemporaryExposureKey.ReportType", - "ReportType", - "TemporaryExposureKey__ReportType", - "", - 6, - temporary_exposure_key__report_type__enum_values_by_number, - 6, - temporary_exposure_key__report_type__enum_values_by_name, - 1, - temporary_exposure_key__report_type__value_ranges, - NULL,NULL,NULL,NULL /* reserved[1234] */ -}; -static const int32_t temporary_exposure_key__rolling_period__default_value = 144; -static const ProtobufCFieldDescriptor temporary_exposure_key__field_descriptors[6] = -{ - { - "key_data", - 1, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_BYTES, - offsetof(TemporaryExposureKey, has_key_data), - offsetof(TemporaryExposureKey, key_data), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "transmission_risk_level", - 2, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_INT32, - offsetof(TemporaryExposureKey, has_transmission_risk_level), - offsetof(TemporaryExposureKey, transmission_risk_level), - NULL, - NULL, - 0 | PROTOBUF_C_FIELD_FLAG_DEPRECATED, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "rolling_start_interval_number", - 3, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_INT32, - offsetof(TemporaryExposureKey, has_rolling_start_interval_number), - offsetof(TemporaryExposureKey, rolling_start_interval_number), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "rolling_period", - 4, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_INT32, - offsetof(TemporaryExposureKey, has_rolling_period), - offsetof(TemporaryExposureKey, rolling_period), - NULL, - &temporary_exposure_key__rolling_period__default_value, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "report_type", - 5, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_ENUM, - offsetof(TemporaryExposureKey, has_report_type), - offsetof(TemporaryExposureKey, report_type), - &temporary_exposure_key__report_type__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "days_since_onset_of_symptoms", - 6, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_SINT32, - offsetof(TemporaryExposureKey, has_days_since_onset_of_symptoms), - offsetof(TemporaryExposureKey, days_since_onset_of_symptoms), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, -}; -static const unsigned temporary_exposure_key__field_indices_by_name[] = { - 5, /* field[5] = days_since_onset_of_symptoms */ - 0, /* field[0] = key_data */ - 4, /* field[4] = report_type */ - 3, /* field[3] = rolling_period */ - 2, /* field[2] = rolling_start_interval_number */ - 1, /* field[1] = transmission_risk_level */ -}; -static const ProtobufCIntRange temporary_exposure_key__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 6 } -}; -const ProtobufCMessageDescriptor temporary_exposure_key__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "TemporaryExposureKey", - "TemporaryExposureKey", - "TemporaryExposureKey", - "", - sizeof(TemporaryExposureKey), - 6, - temporary_exposure_key__field_descriptors, - temporary_exposure_key__field_indices_by_name, - 1, temporary_exposure_key__number_ranges, - (ProtobufCMessageInit) temporary_exposure_key__init, - NULL,NULL,NULL /* reserved[123] */ -}; -static const ProtobufCFieldDescriptor teksignature_list__field_descriptors[1] = -{ - { - "signatures", - 1, - PROTOBUF_C_LABEL_REPEATED, - PROTOBUF_C_TYPE_MESSAGE, - offsetof(TEKSignatureList, n_signatures), - offsetof(TEKSignatureList, signatures), - &teksignature__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, -}; -static const unsigned teksignature_list__field_indices_by_name[] = { - 0, /* field[0] = signatures */ -}; -static const ProtobufCIntRange teksignature_list__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 1 } -}; -const ProtobufCMessageDescriptor teksignature_list__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "TEKSignatureList", - "TEKSignatureList", - "TEKSignatureList", - "", - sizeof(TEKSignatureList), - 1, - teksignature_list__field_descriptors, - teksignature_list__field_indices_by_name, - 1, teksignature_list__number_ranges, - (ProtobufCMessageInit) teksignature_list__init, - NULL,NULL,NULL /* reserved[123] */ -}; -static const ProtobufCFieldDescriptor teksignature__field_descriptors[4] = -{ - { - "signature_info", - 1, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_MESSAGE, - 0, /* quantifier_offset */ - offsetof(TEKSignature, signature_info), - &signature_info__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "batch_num", - 2, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_INT32, - offsetof(TEKSignature, has_batch_num), - offsetof(TEKSignature, batch_num), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "batch_size", - 3, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_INT32, - offsetof(TEKSignature, has_batch_size), - offsetof(TEKSignature, batch_size), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "signature", - 4, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_BYTES, - offsetof(TEKSignature, has_signature), - offsetof(TEKSignature, signature), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, -}; -static const unsigned teksignature__field_indices_by_name[] = { - 1, /* field[1] = batch_num */ - 2, /* field[2] = batch_size */ - 3, /* field[3] = signature */ - 0, /* field[0] = signature_info */ -}; -static const ProtobufCIntRange teksignature__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 4 } -}; -const ProtobufCMessageDescriptor teksignature__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "TEKSignature", - "TEKSignature", - "TEKSignature", - "", - sizeof(TEKSignature), - 4, - teksignature__field_descriptors, - teksignature__field_indices_by_name, - 1, teksignature__number_ranges, - (ProtobufCMessageInit) teksignature__init, - NULL,NULL,NULL /* reserved[123] */ -}; diff --git a/src/extract_keys.c b/src/extract_keys.c deleted file mode 100644 index 8742fed..0000000 --- a/src/extract_keys.c +++ /dev/null @@ -1,115 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include "export.pb-c.h" -#include "extract_keys.h" - -#define KEY_SIZE 16 - -void process_key(TemporaryExposureKey* key) { - // TODO: Implement -} - -size_t generate_keys(uint8_t** buffer_pointer, int num_keys) { - // Initialize the key export data structure - TemporaryExposureKeyExport export = TEMPORARY_EXPOSURE_KEY_EXPORT__INIT; - - TemporaryExposureKey** key_ptrs = (TemporaryExposureKey**)k_malloc(sizeof(TemporaryExposureKey*) * num_keys); - if (key_ptrs == NULL) { - printk("Could not allocate memory for pointers\n"); - return 0; - } - export.batch_num = 1; - export.batch_size = 1; - - // Initialize the keys and their data - uint8_t key_data[KEY_SIZE]; - for (int i = 0; i < KEY_SIZE; i++) { - key_data[i] = 0xFF; - } - TemporaryExposureKey key = TEMPORARY_EXPOSURE_KEY__INIT; - key.key_data.data = key_data; - key.key_data.len = KEY_SIZE; - key.has_key_data = true; - - // All pointers will point to the same key. The protocol buffer will still have n keys encoded - for (int i = 0; i < num_keys; i++) { - key_ptrs[i] = &key; - } - export.n_keys = num_keys; - export.keys = key_ptrs; - - // Check size allocate memory and pack the buffer - size_t required_buffer = temporary_exposure_key_export__get_packed_size(&export); - uint8_t* buffer = (uint8_t*) k_malloc(required_buffer); - if (buffer == NULL) { - printk("Could not allocate memory for buffer\n"); - return 0; - } - *buffer_pointer = buffer; - if (buffer != NULL) { - size_t buf_size = temporary_exposure_key_export__pack(&export, buffer); - k_free(key_ptrs); - return buf_size; - } else { - printk("Buffer too small to serialize %d keys. %d bytes necessary\n", num_keys, required_buffer); - return 0; - } -} - -int unpack_keys(uint8_t* buf, size_t buf_size) { - // Unpack protocol buffer - printk("Buf size: %d\n", buf_size); - TemporaryExposureKeyExport* export = temporary_exposure_key_export__unpack(NULL, buf_size, buf); - if (export == NULL) { - printk("error unpacking incoming message\n"); - return -2; - } - - // Iterate over new keys - for (int i = 0; i < export->n_keys; i++) { - TemporaryExposureKey* key = export->keys[i]; - process_key(key); - } - - // Iterate over revised keys - for (int i = 0; i < export->n_revised_keys; i++) { - TemporaryExposureKey* key = export->revised_keys[i]; - process_key(key); - } - return 0; -} - -int test_unpacking(int num_keys) { - // Prepare time measurement - timing_t start_time, end_time; - uint64_t total_cycles; - uint64_t total_ns; - - // Generate Buffer - uint8_t* buffer; - size_t buffer_size = generate_keys(&buffer, num_keys); - - // Test unpacking - timing_init(); - timing_start(); - if (buffer_size) { - start_time = timing_counter_get(); - unpack_keys(buffer, buffer_size); - end_time = timing_counter_get(); - } - - // Calculate measurements - total_cycles = timing_cycles_get(&start_time, &end_time); - total_ns = timing_cycles_to_ns(total_cycles); - printk("\nUnpacking %d keys took %lld us\n\n", num_keys, total_ns / 1000); - timing_stop(); - - k_free(buffer); - return 0; -} \ No newline at end of file diff --git a/src/gatt-service.c b/src/gatt-service.c deleted file mode 100644 index 3215391..0000000 --- a/src/gatt-service.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2020 Olaf Landsiedel - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "covid.h" -#include "contacts.h" - -#define DEVICE_NAME CONFIG_BT_DEVICE_NAME -#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1) - -static const struct bt_data ad[] = { - BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), - /* My Service UUID (same as above) */ - BT_DATA_BYTES(BT_DATA_UUID128_ALL, - 0x06, 0x51, 0xC7, 0x9E, 0xAD, 0xA7, 0x42, 0xEA, - 0x98, 0x6A, 0x9F, 0x69, 0x79, 0x0D, 0x11, 0xF2), -}; - -static void connected(struct bt_conn *conn, uint8_t err) -{ - - if (err) { - printk("Connection failed (err 0x%02x)\n", err); - } else { - printk("Connected\n"); - } -} - -static void disconnected(struct bt_conn *conn, uint8_t reason) -{ - printk("Disconnected (reason 0x%02x)\n", reason); -} - -static struct bt_conn_cb conn_callbacks = { - .connected = connected, - .disconnected = disconnected, -}; - - -static void auth_cancel(struct bt_conn *conn) -{ - char addr[BT_ADDR_LE_STR_LEN]; - - bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); - - printk("Pairing cancelled: %s\n", addr); -} - -static struct bt_conn_auth_cb auth_cb_display = { - .cancel = auth_cancel, -}; - -int init_gatt(void) -{ - bt_conn_cb_register(&conn_callbacks); - bt_conn_auth_cb_register(&auth_cb_display); - - return 0; -} - -#if CONFIG_BT - -int do_gatt(void){ - //printk("gatt start\n"); - int err; - - err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0); - if (err) { - printk("Advertising failed to start (err %d)\n", err); - return err; - } - - k_sleep(K_SECONDS(1)); - - err = bt_le_adv_stop(); - if (err) { - printk("Advertising failed to stop (err %d)\n", err); - return err; - } - - //printk("gatt end\n"); - return 0; -} - -#else - -int do_gatt(void) { - return 0; -} - -#endif \ No newline at end of file diff --git a/src/io.c b/src/io.c deleted file mode 100644 index 8f4a92b..0000000 --- a/src/io.c +++ /dev/null @@ -1,189 +0,0 @@ -/* io.c - Application main entry point */ - -/* - * Copyright (c) 2020 Olaf Landsiedel - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -#include -#include -#include - -#include "covid.h" -#include "io.h" - -/* - * Devicetree helper macro which gets the 'flags' cell from a 'gpios' - * property, or returns 0 if the property has no 'flags' cell. - */ - -#define FLAGS_OR_ZERO(node) \ - COND_CODE_1(DT_PHA_HAS_CELL(node, gpios, flags), \ - (DT_GPIO_FLAGS(node, gpios)), \ - (0)) - -/* - * Get button configuration from the devicetree sw0 alias. - * - * At least a GPIO device and pin number must be provided. The 'flags' - * cell is optional. - */ - -#ifndef NATIVE_POSIX -//on my NRF board this is button 1 -#define SW0_NODE DT_ALIAS(sw0) - -#if DT_NODE_HAS_STATUS(SW0_NODE, okay) -#define SW0_GPIO_LABEL DT_GPIO_LABEL(SW0_NODE, gpios) -#define SW0_GPIO_PIN DT_GPIO_PIN(SW0_NODE, gpios) -#define SW0_GPIO_FLAGS (GPIO_INPUT | FLAGS_OR_ZERO(SW0_NODE)) -#else -#error "Unsupported board: sw0 devicetree alias is not defined" -#define SW0_GPIO_LABEL "" -#define SW0_GPIO_PIN 0 -#define SW0_GPIO_FLAGS 0 -#endif - -//on my NRF board this is button 2 -#define SW1_NODE DT_ALIAS(sw1) - -#if DT_NODE_HAS_STATUS(SW1_NODE, okay) -#define SW1_GPIO_LABEL DT_GPIO_LABEL(SW1_NODE, gpios) -#define SW1_GPIO_PIN DT_GPIO_PIN(SW1_NODE, gpios) -#define SW1_GPIO_FLAGS (GPIO_INPUT | FLAGS_OR_ZERO(SW1_NODE)) -#else -#error "Unsupported board: sw1 devicetree alias is not defined" -#define SW1_GPIO_LABEL "" -#define SW1_GPIO_PIN 0 -#define SW1_GPIO_FLAGS 0 -#endif - -/* The devicetree node identifier for the "led0" alias. */ -#define LED0_NODE DT_ALIAS(led0) - -#if DT_NODE_HAS_STATUS(LED0_NODE, okay) -#define LED0 DT_GPIO_LABEL(LED0_NODE, gpios) -#define PIN DT_GPIO_PIN(LED0_NODE, gpios) -#if DT_PHA_HAS_CELL(LED0_NODE, gpios, flags) -#define FLAGS DT_GPIO_FLAGS(LED0_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 LED0 "" -#define PIN 0 -#endif -#endif - -#ifndef FLAGS -#define FLAGS 0 -#endif - - -static struct gpio_callback button_0_cb_data; -static struct gpio_callback button_1_cb_data; - -#ifndef NATIVE_POSIX - -void button_0_pressed(struct device *dev, struct gpio_callback *cb, uint32_t pins){ - set_infection(true); - gpio_pin_set(dev, PIN, (int)1); - printk("Button 0 (=infected) pressed at %" PRIu32 "\n", k_cycle_get_32()); -} - -void button_1_pressed(struct device *dev, struct gpio_callback *cb, uint32_t pins){ - set_infection(false); - gpio_pin_set(dev, PIN, (int)0); - printk("Button 1 (=healthy) pressed at %" PRIu32 "\n", k_cycle_get_32()); -} - -int init_io(){ - struct device *button0, *button1; - int err = 0; - //struct device *led; - - button0 = device_get_binding(SW0_GPIO_LABEL); - if (button0 == NULL) { - printk("Error: didn't find %s device\n", SW0_GPIO_LABEL); - return -1; - } - button1 = device_get_binding(SW1_GPIO_LABEL); - if (button1 == NULL) { - printk("Error: didn't find %s device\n", SW1_GPIO_LABEL); - return -1; - } - - err = gpio_pin_configure(button0, SW0_GPIO_PIN, SW0_GPIO_FLAGS); - if (err != 0) { - printk("Error %d: failed to configure %s pin %d\n", - err, SW0_GPIO_LABEL, SW0_GPIO_PIN); - return err; - } - - err = gpio_pin_configure(button1, SW1_GPIO_PIN, SW1_GPIO_FLAGS); - if (err != 0) { - printk("Error %d: failed to configure %s pin %d\n", - err, SW1_GPIO_LABEL, SW1_GPIO_PIN); - return err; - } - - - err = gpio_pin_interrupt_configure(button0, - SW0_GPIO_PIN, - GPIO_INT_EDGE_TO_ACTIVE); - if (err != 0) { - printk("Error %d: failed to configure interrupt on %s pin %d\n", - err, SW0_GPIO_LABEL, SW0_GPIO_PIN); - return err; - } - - err = gpio_pin_interrupt_configure(button1, - SW1_GPIO_PIN, - GPIO_INT_EDGE_TO_ACTIVE); - if (err != 0) { - printk("Error %d: failed to configure interrupt on %s pin %d\n", - err, SW1_GPIO_LABEL, SW1_GPIO_PIN); - return err; - } - - gpio_init_callback(&button_0_cb_data, button_0_pressed, BIT(SW0_GPIO_PIN)); - gpio_add_callback(button0, &button_0_cb_data); - printk("Set up button at %s pin %d\n", SW0_GPIO_LABEL, SW0_GPIO_PIN); - - gpio_init_callback(&button_1_cb_data, button_1_pressed, BIT(SW1_GPIO_PIN)); - gpio_add_callback(button1, &button_1_cb_data); - printk("Set up button at %s pin %d\n", SW1_GPIO_LABEL, SW1_GPIO_PIN); - - struct device *dev; - dev = device_get_binding(LED0); - if (dev == NULL) { - return -1; - } - - err = gpio_pin_configure(dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS); - if (err < 0) { - printk("Error %d: failed to configure leds\n", err); - return err; - } - //Turn LED 0 off - gpio_pin_set(dev, PIN, (int)0); - return 0; -} - -#else - -void button_0_pressed(struct device *dev, struct gpio_callback *cb, uint32_t pins) { - // Do nothing -} - -void button_1_pressed(struct device *dev, struct gpio_callback *cb, uint32_t pins) { - // Do nothing -} - -int init_io(){ - return 0; -} - -#endif diff --git a/src/main.c b/src/main.c index 75f193b..23ec9e1 100644 --- a/src/main.c +++ b/src/main.c @@ -6,62 +6,41 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + #include #include #include -#include "bloom.h" -#include "contacts.h" -#include "covid.h" -#include "covid_types.h" -#include "display.h" -#include "ens/storage.h" -#include "exposure-notification.h" -#include "extract_keys.h" -#include "gatt_service.h" -#include "io.h" +#include "record_storage.h" +#include "tek_storage.h" +#include "sync_service.h" +#include "tracing.h" void main(void) { - #if CONFIG_TEST_UNPACK_KEYS - for (int i = 0; i < CONFIG_TEST_UNPACK_KEYS_N; i++) { - test_unpacking(1 << i); - } - #endif int err = 0; - printk("Starting Covid Contact Tracer\n"); + printk("Starting Contact-Tracing Wristband...\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) { - printk("Cyrpto init failed (err %d)\n", err); + printk("Crypto init failed (err %d)\n", err); return; } -#endif -#if CONFIG_FLASH - err = init_record_storage(false); + err = record_storage_init(false); if (err) { - printk("init storage failed (err %d)\n", err); + printk("init record storage failed (err %d)\n", err); return; } - err = init_contacts(); + err = tek_storage_init(false); if (err) { - printk("init contacts failed (err %d)\n", err); - return; - } -#endif - - err = init_io(); - if (err) { - printk("Button init failed (err %d)\n", err); + printk("init key storage failed (err %d)\n", err); return; } -#if CONFIG_BT /* Initialize the Bluetooth Subsystem */ err = bt_enable(NULL); if (err) { @@ -69,29 +48,24 @@ void main(void) { return; } - printk("Bluetooth initialized\n"); - - err = init_gatt(); + /* Initialize the Tracing Subsystem */ + err = tracing_init(); if (err) { - printk("init gatt failed(err %d)\n", err); - return; - } -#endif - - err = init_covid(); - if (err) { - printk("init covid failed (err %d)\n", err); + printk("Tracing init failed (err %d)\n", err); return; } - printk("init display\n"); - err = init_display(); + /* Initialize the Gatt Subsystem */ + err = sync_service_init(); if (err) { - printk("init display failed (err %d)\n", err); + printk("Sync Service init failed (err %d)\n", err); + return; } + printk("Components initialized! Starting Tracing and Gatt...\n"); + do { - do_covid(); - do_gatt(); + tracing_run(); + sync_service_run(); } while (1); -} +} \ No newline at end of file diff --git a/src/main_test.c b/src/main_test.c index b0b664c..8d5d58e 100644 --- a/src/main_test.c +++ b/src/main_test.c @@ -9,10 +9,10 @@ #include #include - -void main(void) { +void main_test(void) { while(1) { printk("Hello World!\n"); + k_msleep(1000); } } diff --git a/src/ens/storage.c b/src/record_storage.c similarity index 52% rename from src/ens/storage.c rename to src/record_storage.c index d3df970..25e4487 100644 --- a/src/ens/storage.c +++ b/src/record_storage.c @@ -6,11 +6,10 @@ #include #include #include +#include -#include "ens/ens_error.h" -#include "ens/ens_fs.h" -#include "ens/sequencenumber.h" -#include "ens/storage.h" +#include "utility/ens_fs.h" +#include "record_storage.h" #define STORED_CONTACTS_INFO_ID 0 @@ -59,7 +58,7 @@ int save_storage_information() { return rc; } -int init_record_storage(bool clean) { +int record_storage_init(bool clean) { int rc = 0; struct flash_pages_info info; // define the nvs file system @@ -231,3 +230,207 @@ int get_sequence_number_interval(record_sequence_number_t* oldest, record_sequen uint32_t get_num_records() { return record_information.count; } + + + + + +int ens_records_iterator_init_range(record_iterator_t* iterator, + record_sequence_number_t* opt_start, + record_sequence_number_t* opt_end) { + // prevent any changes during initialization + int rc = get_sequence_number_interval(&iterator->sn_next, &iterator->sn_end); + if (rc == 0) { + iterator->finished = false; + + // we override start and end with the optional values + if (opt_start) { + iterator->sn_next = *opt_start; + } + if (opt_end) { + iterator->sn_end = *opt_end; + } + } else { + iterator->finished = true; + } + + return 0; +} + +int64_t get_timestamp_for_sn(record_sequence_number_t sn) { + record_t rec; + if (load_record(&rec, sn) == 0) { + return rec.timestamp; + } else { + return -1; + } +} + +enum record_timestamp_search_mode { + RECORD_TIMESTAMP_SEARCH_MODE_MIN, + RECORD_TIMESTAMP_SEARCH_MODE_MAX, +}; + +/** + * Find an entry via binary search for the timestamp. + * + * @param record pointer to the location, where the found sn shall be stored + * @param target timestamp for which to find the nearest entry for + * @param greater flag for indicating, if the loaded sn shall correspond to a greater (1) or smaller (0) timestamp + */ +int find_sn_via_binary_search(record_sequence_number_t* sn_dest, + uint32_t target, + enum record_timestamp_search_mode search_mode) { + record_sequence_number_t start_sn; + record_sequence_number_t end_sn; + + // prevent any changes during binary search initialization + + int rc = get_sequence_number_interval(&start_sn, &end_sn); + + if (rc) { + return rc; + } + + record_sequence_number_t last_sn = + start_sn; // used to check if ran into issues, e.g. could not load the entry or rounding errors + + while (!sn_equal(start_sn, end_sn)) { + // calculate the sn in the middle between start and end + record_sequence_number_t cur_sn = sn_get_middle_sn(start_sn, end_sn); + + if (sn_equal(cur_sn, last_sn)) { + // if we already checked this entry -> we reduce our boundaries and try again + // this also solves issues with rounding + // TODO: This is not the best way... + if (search_mode == RECORD_TIMESTAMP_SEARCH_MODE_MIN) { + int64_t start_ts = get_timestamp_for_sn(start_sn); + if (start_ts == -1 || start_ts < target) { + // we could not load this entry or this entry is strictly smaller than our target + start_sn = sn_increment(start_sn); // we can safely increment as start_sn < end_sn + } else { + // we actually found the wanted entry! + end_sn = start_sn; // this will break our loop + } + } else { + // we search for the biggest value among them + int64_t end_ts = get_timestamp_for_sn(end_sn); + if (end_ts == -1 || end_ts > target) { + // we could not load this entry or this entry is strictly bigger than our target + end_sn = sn_decrement(end_sn); // we can safely decrement as start_sn < end_sn + } else { + // we actually found the wanted entry! + start_sn = end_sn; // this will break our loop + } + } + } else { + int64_t mid_ts = get_timestamp_for_sn(cur_sn); + + if (mid_ts >= 0) { + if (target < mid_ts) { + end_sn = cur_sn; + } else if (target > mid_ts) { + start_sn = cur_sn; + } else { + // target == mid_ts + if (search_mode == RECORD_TIMESTAMP_SEARCH_MODE_MIN) { + // we search for the smallest value among them -> look before this item + end_sn = cur_sn; + } else { + // we search for the biggest value among them -> look after this item + start_sn = cur_sn; + } + } + } else { + // some errors -> we keep the current sn and try to narrow our boundaries + } + } + last_sn = cur_sn; + } + + *sn_dest = start_sn; // == end_sn + + return 0; +} + +// TODO: This iterator does neither check if the sequence numbers wrapped around while iteration. As a result, first +// results could have later timestamps than following entries +int ens_records_iterator_init_timerange(record_iterator_t* iterator, time_t* ts_start, time_t* ts_end) { + record_sequence_number_t oldest_sn = 0; + record_sequence_number_t newest_sn = 0; + + // assure that *ts_end > *ts_start + if (ts_start && ts_end && *ts_end < *ts_start) { + return 1; + } + + if (ts_start) { + int rc = find_sn_via_binary_search(&oldest_sn, *ts_start, RECORD_TIMESTAMP_SEARCH_MODE_MIN); + if (rc) { + return rc; + } + } else { + oldest_sn = get_oldest_sequence_number(); + } + + if (ts_end) { + int rc = find_sn_via_binary_search(&newest_sn, *ts_end, RECORD_TIMESTAMP_SEARCH_MODE_MAX); + if (rc) { + return rc; + } + } else { + newest_sn = get_latest_sequence_number(); + } + + return ens_records_iterator_init_range(iterator, &oldest_sn, &newest_sn); +} + +record_t* ens_records_iterator_next(record_iterator_t* iter) { + record_t* next = NULL; + + while (next == NULL && !iter->finished) { + record_t contact; + // try to load the next contact + int res = load_record(&contact, iter->sn_next); + + if (!res) { + next = &iter->current; + memcpy(next, &contact, sizeof(record_t)); + } + + if (sn_equal(iter->sn_next, iter->sn_end)) { + iter->finished = true; // this iterator will finish after this execution + } else { + // increase the current sn + iter->sn_next = sn_increment(iter->sn_next); + } + } + + return next; +} + +int ens_record_iterator_clear(record_iterator_t* iter) { + // clear all relevant fields in the iterator + iter->finished = true; + iter->sn_next = 0; + iter->sn_end = 0; + memset(&iter->current, 0, sizeof(iter->current)); + return 0; +} + +uint8_t ens_records_iterate_with_callback(record_iterator_t* iter, ens_record_iterator_cb_t cb, void* userdata) { + record_t* cur = ens_records_iterator_next(iter); + bool cont = true; + + while (cur != NULL && cont) { + int cb_res = cb(cur, userdata); + if (cb_res == ENS_RECORD_ITER_STOP) { + cont = false; + } + } + + if (cont) { + cb(NULL, userdata); // we call the callback one last time but with null data + } + return 0; +} \ No newline at end of file diff --git a/src/sync_service.c b/src/sync_service.c new file mode 100644 index 0000000..a6ae4c1 --- /dev/null +++ b/src/sync_service.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020 Olaf Landsiedel + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +int sync_service_init(void) { + return 0; // TODO! +} + +int sync_service_run(void) { + return 0; +} \ No newline at end of file diff --git a/src/tek_storage.c b/src/tek_storage.c new file mode 100644 index 0000000..68b7cae --- /dev/null +++ b/src/tek_storage.c @@ -0,0 +1,26 @@ +#include +#include "tek_storage.h" + +int tek_storage_init(bool clean) { + return 0; +} + +int tek_storage_add(tek_t* src) { + // TODO + return -1; +} + +int tek_storage_delete(tek_t* src) { + // TODO + return -1; +} + +/** + * Returns 0 on success, else non zero (if none available) + * TODO: This is not really implemented... + */ +int tek_storage_get_latest_at_ts(tek_t* dest, uint32_t timestamp) { + dest->timestamp = timestamp; + memset(&dest->tek, 0, sizeof(dest->tek)); + return 0; +} \ No newline at end of file diff --git a/src/covid.c b/src/tracing.c similarity index 66% rename from src/covid.c rename to src/tracing.c index c3001a5..7e432f9 100644 --- a/src/covid.c +++ b/src/tracing.c @@ -15,21 +15,29 @@ #include #include "exposure-notification.h" -#include "covid_types.h" -#include "contacts.h" -#include "covid.h" -#include "ens/storage.h" +#include "tracing.h" +#include "record_storage.h" -#include "util.h" +#include "utility/util.h" + +#define COVID_ENS (0xFD6F) + +typedef ENIntervalIdentifier ENIntervalIdentifier; + + + + + +typedef struct period{ + ENPeriodKey periodKey; + ENIntervalNumber periodInterval; +} __packed period_t; -#ifndef COVID_MEASURE_PERFORMANCE -#define COVID_MEASURE_PERFORMANCE 0 -#endif typedef struct covid_adv_svd { uint16_t ens; - rolling_proximity_identifier_t rolling_proximity_identifier; + ENIntervalIdentifier rolling_proximity_identifier; associated_encrypted_metadata_t associated_encrypted_metadata; } __packed covid_adv_svd_t; @@ -40,8 +48,6 @@ const static bt_metadata_t bt_metadata = { .rsv2 = 0, }; -#define COVID_ENS (0xFD6F) - static covid_adv_svd_t covid_adv_svd = { .ens = COVID_ENS, //do not initialiuze the rest of the packet, will write this later @@ -80,15 +86,15 @@ static void scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type, str covid_adv_svd_t *rx_adv = (covid_adv_svd_t *)buf->data; if (rx_adv->ens == COVID_ENS) { - printk("Attempting to store contact...\n"); - record_t contact; + printk("Attempting to store record...\n"); + record_t record; uint32_t timestamp = time_get_unix_seconds(); - memcpy(&contact.rssi, &rssi, sizeof(contact.rssi)); - memcpy(&contact.associated_encrypted_metadata, &rx_adv->associated_encrypted_metadata, sizeof(contact.associated_encrypted_metadata)); - memcpy(&contact.rolling_proximity_identifier, &rx_adv->rolling_proximity_identifier, sizeof(contact.rolling_proximity_identifier)); - memcpy(&contact.timestamp, ×tamp, sizeof(contact.timestamp)); - int rc = register_record(&contact); - printk("Contact stored (err %d)\n", rc); + memcpy(&record.rssi, &rssi, sizeof(record.rssi)); + memcpy(&record.associated_encrypted_metadata, &rx_adv->associated_encrypted_metadata, sizeof(record.associated_encrypted_metadata)); + memcpy(&record.rolling_proximity_identifier, &rx_adv->rolling_proximity_identifier, sizeof(record.rolling_proximity_identifier)); + memcpy(&record.timestamp, ×tamp, sizeof(record.timestamp)); + int rc = add_record(&record); + printk("Record stored (err %d)\n", rc); } } net_buf_simple_pull(buf, len - 1); //consume the rest, note we already consumed one byte via net_buf_simple_pull_u8(buf) @@ -167,120 +173,6 @@ static void new_period_key(time_t currentTime) #endif } -#if COVID_MEASURE_PERFORMANCE -static void measure_performance() -{ - - u32_t runs = 100; - u32_t start_time; - u32_t cycles_spent; - u32_t nanoseconds_spent; - - ENPeriodKey pk; - - ENPeriodIdentifierKey pik; - ENIntervalIdentifier intervalIdentifier; - ENIntervalNumber intervalNumber = 2642976; - ENIntervalIdentifier id; - ENPeriodMetadataEncryptionKey pmek; - unsigned char metadata[4] = {0x40, 0x08, 0x00, 0x00}; - unsigned char encryptedMetadata[sizeof(metadata)] = {0}; - - printk("\n----------------------------------------\n"); - printk("MEASURING PERFORMANCE\n"); - - // Measure en_generate_period_key - { - start_time = k_cycle_get_32(); - - for (int i = 0; i < runs; i++) - { - en_generate_period_key(&pk); - } - - nanoseconds_spent = SYS_CLOCK_HW_CYCLES_TO_NS(k_cycle_get_32() - start_time); - printk("en_generate_period_key %d ns\n", nanoseconds_spent/runs); - } - - // Measure en_derive_period_identifier_key - { - start_time = k_cycle_get_32(); - - for (int i = 0; i < runs; i++) - { - en_derive_period_identifier_key(&pik, &pk); - } - - nanoseconds_spent = SYS_CLOCK_HW_CYCLES_TO_NS(k_cycle_get_32() - start_time); - printk("en_derive_period_identifier_key %d ns\n", nanoseconds_spent/runs); - } - - // Measure en_derive_interval_identifier - { - start_time = k_cycle_get_32(); - - for (int i = 0; i < runs; i++) - { - en_derive_interval_identifier(&intervalIdentifier, &pik, intervalNumber); - } - - nanoseconds_spent = SYS_CLOCK_HW_CYCLES_TO_NS(k_cycle_get_32() - start_time); - printk("en_derive_interval_identifier %d ns\n", nanoseconds_spent/runs); - } - - // Measure en_derive_period_metadata_encryption_key - { - start_time = k_cycle_get_32(); - - for (int i = 0; i < runs; i++) - { - en_derive_period_metadata_encryption_key(&pmek, &pk); - } - - nanoseconds_spent = SYS_CLOCK_HW_CYCLES_TO_NS(k_cycle_get_32() - start_time); - printk("en_derive_period_metadata_encryption_key %d ns\n", nanoseconds_spent/runs); - } - - // Measure en_encrypt_interval_metadata - { - start_time = k_cycle_get_32(); - - for (int i = 0; i < runs; i++) - { - en_encrypt_interval_metadata(&pmek, &intervalIdentifier, metadata, encryptedMetadata, sizeof(metadata)); - } - - nanoseconds_spent = SYS_CLOCK_HW_CYCLES_TO_NS(k_cycle_get_32() - start_time); - printk("en_encrypt_interval_metadata %d ns\n", nanoseconds_spent/runs); - } - - // Measure Full key generation - { - start_time = k_cycle_get_32(); - - for (int i = 0; i < runs; i++) - { - ENPeriodKey pk; - en_generate_period_key(&pk); - ENPeriodIdentifierKey ik; - en_derive_period_identifier_key(&ik, &pk); - - for(int iv = 0; iv < EN_TEK_ROLLING_PERIOD; iv++) { - ENIntervalNumber intervalNumber = en_get_interval_number(iv); - ENIntervalIdentifier id; - en_derive_interval_identifier(&id, &ik, intervalNumber); - } - } - - nanoseconds_spent = SYS_CLOCK_HW_CYCLES_TO_NS(k_cycle_get_32() - start_time); - printk("Full key generation %d ns\n", nanoseconds_spent/runs); - } - - printk("\FINISHED\n"); - printk("----------------------------------------\n\n"); -} -#endif - //To be called when new keys are needed static void check_keys(struct k_work *work) { @@ -314,10 +206,10 @@ static void check_keys(struct k_work *work) printk("Time: %u, ", currentTime); printk("Interval: %u, ", currentInterval); printk("TEK: "); - print_rpi((rolling_proximity_identifier_t *)&periods[current_period_index].periodKey); + print_rpi((ENIntervalIdentifier *)&periods[current_period_index].periodKey); printk(", "); printk("RPI: "); - print_rpi((rolling_proximity_identifier_t *)&intervalIdentifier); + print_rpi((ENIntervalIdentifier *)&intervalIdentifier); printk(", "); printk("AEM: "); print_aem(&encryptedMetadata); @@ -325,7 +217,7 @@ static void check_keys(struct k_work *work) // lock, so we can be sure to only advertise correct packages k_mutex_lock(&key_change_lock, K_FOREVER); - memcpy(&covid_adv_svd.rolling_proximity_identifier, &intervalIdentifier, sizeof(rolling_proximity_identifier_t)); + memcpy(&covid_adv_svd.rolling_proximity_identifier, &intervalIdentifier, sizeof(ENIntervalIdentifier)); memcpy(&covid_adv_svd.associated_encrypted_metadata, &encryptedMetadata, sizeof(associated_encrypted_metadata_t)); k_mutex_unlock(&key_change_lock); @@ -351,7 +243,7 @@ static const struct bt_le_scan_param scan_param = { #define KEY_CHECK_INTERVAL (K_MSEC(EN_INTERVAL_LENGTH * 1000 / 10)) -int init_covid() +int tracing_init() { #if COVID_MEASURE_PERFORMANCE @@ -383,7 +275,7 @@ int init_covid() return 0; } -int do_covid() +int tracing_run() { //printk("covid start\n"); @@ -445,17 +337,3 @@ period_t *get_period_if_infected(unsigned int id, size_t *size) *size = sizeof(period_t); return &periods[id]; } - -int get_index_by_interval(ENIntervalNumber periodInterval) -{ - int index = 0; - while (index < NUM_PERIOD_KEYS || index < period_cnt) - { - if (periods[index].periodInterval == periodInterval) - { - return index; - } - index++; - } - return -1; -} diff --git a/src/util.c b/src/util.c deleted file mode 100644 index 7de6b88..0000000 --- a/src/util.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "time.h" -#include -// TODO: this is very basic atm -uint32_t time_get_unix_seconds() { - return k_uptime_get() / 1000; -} \ No newline at end of file diff --git a/src/ens/ens_fs.c b/src/utility/ens_fs.c similarity index 99% rename from src/ens/ens_fs.c rename to src/utility/ens_fs.c index 924e5ae..a8c85d2 100644 --- a/src/ens/ens_fs.c +++ b/src/utility/ens_fs.c @@ -6,8 +6,7 @@ #include #include -#include "ens/ens_error.h" -#include "ens/ens_fs.h" +#include "utility/ens_fs.h" #define SEED 42 diff --git a/src/ens/sequencenumber.c b/src/utility/sequencenumber.c similarity index 96% rename from src/ens/sequencenumber.c rename to src/utility/sequencenumber.c index 79ea3d8..99eed06 100644 --- a/src/ens/sequencenumber.c +++ b/src/utility/sequencenumber.c @@ -1,4 +1,4 @@ -#include "ens/sequencenumber.h" +#include "utility/sequencenumber.h" #define SN_MASK 0xffffff diff --git a/src/utility/util.c b/src/utility/util.c new file mode 100644 index 0000000..e13fbb1 --- /dev/null +++ b/src/utility/util.c @@ -0,0 +1,27 @@ +#include "time.h" +#include +#include "utility/util.h" + + +// TODO: this is very basic atm +uint32_t time_get_unix_seconds() { + return k_uptime_get() / 1000; +} + +void print_key(_ENBaseKey* key) { + for (int i = 0; i < sizeof(key->b); i++) { + printk("%02x", key->b[i]); + } +} + +void print_rpi(ENIntervalIdentifier* rpi) { + for (int i = 0; i < sizeof(ENIntervalIdentifier); i++) { + printk("%02x", rpi->b[i]); + } +} + +void print_aem(associated_encrypted_metadata_t* aem) { + for (int i = 0; i < sizeof(associated_encrypted_metadata_t); i++) { + printk("%02x", aem->data[i]); + } +} \ No newline at end of file