mirror of
https://github.com/Lurkars/esp-ena.git
synced 2026-05-08 20:10:37 +02:00
moved to configurable components, added SSD1306 support
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef _ena_BEACON_H_
|
||||
#define _ena_BEACON_H_
|
||||
|
||||
#define ENA_BEACON_LOG "ESP-ENA-beacon" // TAG for Logging
|
||||
#define ENA_BEACON_TRESHOLD (CONFIG_ENA_BEACON_TRESHOLD) // meet for longer than 5 minutes
|
||||
|
||||
/**
|
||||
* @brief check temporary beacon for threshold or expiring
|
||||
*
|
||||
* This function checks all current temporary beacons if the contact threshold is
|
||||
* reached or if the temporary contact can be discarded.
|
||||
*
|
||||
* @param[in] unix_timestamp current time as UNIX timestamp to compate
|
||||
*
|
||||
*/
|
||||
void ena_beacons_temp_refresh(uint32_t unix_timestamp);
|
||||
|
||||
/**
|
||||
* @brief handle new beacon received from a BLE scan
|
||||
*
|
||||
* This function gets called when a running BLE scan received a new ENA payload.
|
||||
* On already detected RPI this will update just the timestamp and RSSI.
|
||||
*
|
||||
* @param[in] unix_timestamp UNIX timestamp when beacon was made
|
||||
* @param[in] rpi received RPI from scanned payload
|
||||
* @param[in] aem received AEM from scanned payload
|
||||
* @param[in] rssi measured RSSI on scan
|
||||
*
|
||||
*/
|
||||
void ena_beacon(uint32_t unix_timestamp, uint8_t *rpi, uint8_t *aem, int rssi);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef _ena_BLUETOOTH_ADVERTISE_H_
|
||||
#define _ena_BLUETOOTH_ADVERTISE_H_
|
||||
|
||||
#define ENA_ADVERTISE_LOG "ESP-ENA-advertise" // TAG for Logging
|
||||
#define ENA_BLUETOOTH_TAG_DATA (0x1A) // Data for BLE payload TAG
|
||||
|
||||
/**
|
||||
* @brief Start BLE advertising
|
||||
*/
|
||||
void ena_bluetooth_advertise_start(void);
|
||||
|
||||
/**
|
||||
* @brief Set payload for BLE advertising
|
||||
*
|
||||
* This will set the payload for based on given ENIN and TEK.
|
||||
*
|
||||
* Source documents (Section: Advertising Payload)
|
||||
*
|
||||
* https://blog.google/documents/70/Exposure_Notification_-_Bluetooth_Specification_v1.2.2.pdf
|
||||
*
|
||||
* https://covid19-static.cdn-apple.com/applications/covid19/current/static/detection-tracing/pdf/ExposureNotification-BluetoothSpecificationv1.2.pdf
|
||||
*
|
||||
* @param[in] enin ENIN defining the start of the tek vadility. This should be the ENIN for the current timestamp
|
||||
* @param[in] tek pointer to the TEK used to encrypt the payload.
|
||||
*/
|
||||
void ena_bluetooth_advertise_set_payload(uint32_t enin, uint8_t *tek);
|
||||
|
||||
/**
|
||||
* @brief Stop BLE advertising
|
||||
*/
|
||||
void ena_bluetooth_advertise_stop(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef _ena_BLUETOOTH_SCAN_H_
|
||||
#define _ena_BLUETOOTH_SCAN_H_
|
||||
|
||||
#define ENA_SCAN_LOG "ESP-ENA-scan" // TAG for Logging
|
||||
#define ENA_SCANNING_TIME (CONFIG_ENA_SCANNING_TIME) // time how long a scan should run
|
||||
#define ENA_SCANNING_INTERVAL (CONFIG_ENA_SCANNING_INTERVAL) // interval for next scan to happen
|
||||
|
||||
/**
|
||||
* @brief status of BLE scan
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ENA_SCAN_STATUS_SCANNING = 0, // scan is running
|
||||
ENA_SCAN_STATUS_NOT_SCANNING, // scan is not running
|
||||
ENA_SCAN_STATUS_WAITING, // scan is not running but stopped manually
|
||||
} ena_bluetooth_scan_status;
|
||||
|
||||
/**
|
||||
* @brief initialize the BLE scanning
|
||||
*
|
||||
*/
|
||||
void ena_bluetooth_scan_init(void);
|
||||
|
||||
/**
|
||||
* @brief start BLE scanning for a given duration
|
||||
*
|
||||
* Source documents (Section: Scanning Behavior)
|
||||
*
|
||||
* https://blog.google/documents/70/Exposure_Notification_-_Bluetooth_Specification_v1.2.2.pdf
|
||||
*
|
||||
* https://covid19-static.cdn-apple.com/applications/covid19/current/static/detection-tracing/pdf/ExposureNotification-BluetoothSpecificationv1.2.pdf
|
||||
*
|
||||
* @param[in] duration duration of the scan in seconds
|
||||
*/
|
||||
void ena_bluetooth_scan_start(uint32_t duration);
|
||||
|
||||
/**
|
||||
* @brief stop a running BLE scanning
|
||||
*/
|
||||
void ena_bluetooth_scan_stop(void);
|
||||
|
||||
/**
|
||||
* @brief return the current scanning status
|
||||
*
|
||||
* @return
|
||||
* current scan status
|
||||
*/
|
||||
int ena_bluetooth_scan_get_status(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,120 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef _ena_CRYPTO_H_
|
||||
#define _ena_CRYPTO_H_
|
||||
|
||||
#define ENA_TIME_WINDOW (600) // time window every 10 minutes
|
||||
#define ENA_KEY_LENGTH (16) // key length
|
||||
#define ENA_AEM_METADATA_LENGTH (4) // size of metadata
|
||||
#define ENA_TEK_ROLLING_PERIOD (CONFIG_ENA_TEK_ROLLING_PERIOD) // TEKRollingPeriod
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* @brief initialize cryptography
|
||||
*
|
||||
* This initialize the cryptography by setting up entropy.
|
||||
*/
|
||||
void ena_crypto_init(void);
|
||||
|
||||
/**
|
||||
* @brief calculate ENIntervalNumber (ENIN) for given UNIX timestamp
|
||||
*
|
||||
* Source documents (Section: ENIntervalNumber)
|
||||
*
|
||||
* https://blog.google/documents/69/Exposure_Notification_-_Cryptography_Specification_v1.2.1.pdf
|
||||
*
|
||||
* https://covid19-static.cdn-apple.com/applications/covid19/current/static/detection-tracing/pdf/ExposureNotification-CryptographySpecificationv1.2.pdf
|
||||
*
|
||||
*
|
||||
* @param[in] unix_timestamp UNIX Timestamp to calculate ENIN for
|
||||
*
|
||||
* @return
|
||||
* ENIN for given timestamp
|
||||
*/
|
||||
uint32_t ena_crypto_enin(uint32_t unix_timestamp);
|
||||
|
||||
/**
|
||||
* @brief calculate a new random Temporary Exposure Key (TEK)
|
||||
*
|
||||
* Source documents (Section: Temporary Exposure Key)
|
||||
*
|
||||
* https://blog.google/documents/69/Exposure_Notification_-_Cryptography_Specification_v1.2.1.pdf
|
||||
*
|
||||
* https://covid19-static.cdn-apple.com/applications/covid19/current/static/detection-tracing/pdf/ExposureNotification-CryptographySpecificationv1.2.pdf
|
||||
*
|
||||
* @param[out] tek pointer to the new TEK
|
||||
*/
|
||||
void ena_crypto_tek(uint8_t *tek);
|
||||
|
||||
/**
|
||||
* @brief calculate a new Rolling Proximity Identifier Key (RPIK) with given TEK
|
||||
*
|
||||
* Source documents (Section: Rolling Proximity Identifier Key)
|
||||
*
|
||||
* https://blog.google/documents/69/Exposure_Notification_-_Cryptography_Specification_v1.2.1.pdf
|
||||
*
|
||||
* https://covid19-static.cdn-apple.com/applications/covid19/current/static/detection-tracing/pdf/ExposureNotification-CryptographySpecificationv1.2.pdf
|
||||
*
|
||||
* @param[out] rpik pointer to the new RPIK
|
||||
* @param[in] tek TEK for calculating RPIK
|
||||
*/
|
||||
void ena_crypto_rpik(uint8_t *rpik, uint8_t *tek);
|
||||
|
||||
/**
|
||||
* @brief calculate a new Rolling Proximity Identifier with given RPIK and ENIN
|
||||
*
|
||||
* Source documents (Section: Rolling Proximity Identifier)
|
||||
*
|
||||
* https://blog.google/documents/69/Exposure_Notification_-_Cryptography_Specification_v1.2.1.pdf
|
||||
*
|
||||
* https://covid19-static.cdn-apple.com/applications/covid19/current/static/detection-tracing/pdf/ExposureNotification-CryptographySpecificationv1.2.pdf
|
||||
*
|
||||
* @param[out] rpi pointer to the new RPI
|
||||
* @param[in] rpik RPIK for encrypting RPI
|
||||
* @param[in] enin ENIN to encrypt in RPI
|
||||
*/
|
||||
void ena_crypto_rpi(uint8_t *rpi, uint8_t *rpik, uint32_t enin);
|
||||
|
||||
/**
|
||||
* @brief calculate a new Associated Encrypted Metadata Key (AEMK) with given TEK
|
||||
*
|
||||
* Source documents (Section: Associated Encrypted Metadata Key)
|
||||
*
|
||||
* https://blog.google/documents/69/Exposure_Notification_-_Cryptography_Specification_v1.2.1.pdf
|
||||
*
|
||||
* https://covid19-static.cdn-apple.com/applications/covid19/current/static/detection-tracing/pdf/ExposureNotification-CryptographySpecificationv1.2.pdf
|
||||
*
|
||||
* @param[out] aemk pointer to the new AEMK
|
||||
* @param[in] tek TEK for calculating AEMK
|
||||
*/
|
||||
void ena_crypto_aemk(uint8_t *aemk, uint8_t *tek);
|
||||
|
||||
/**
|
||||
* @brief create Associated Encrypted Metadata (AEM) with given AEMK along the RPI
|
||||
*
|
||||
* Source documents (Section: Associated Encrypted Metadata)
|
||||
*
|
||||
* https://blog.google/documents/69/Exposure_Notification_-_Cryptography_Specification_v1.2.1.pdf
|
||||
*
|
||||
* https://covid19-static.cdn-apple.com/applications/covid19/current/static/detection-tracing/pdf/ExposureNotification-CryptographySpecificationv1.2.pdf
|
||||
*
|
||||
* @param[out] aem pointer to the new AEM
|
||||
* @param[in] aemk AEMK for encrypting AEM
|
||||
* @param[in] rpi RPI for encrypting AEM
|
||||
* @param[in] power_level BLE power level to encrypt in AEM
|
||||
*/
|
||||
void ena_crypto_aem(uint8_t *aem, uint8_t *aemk, uint8_t *rpi, uint8_t power_level);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,221 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef _ena_STORAGE_H_
|
||||
#define _ena_STORAGE_H_
|
||||
|
||||
#include "ena-crypto.h"
|
||||
|
||||
#define ENA_STORAGE_LOG "ESP-ENA-storage" // TAG for Logging
|
||||
#define ENA_STORAGE_PARTITION_NAME (CONFIG_ENA_STORAGE_PARTITION_NAME) // name of partition to use for storing
|
||||
#define ENA_STORAGE_START_ADDRESS (CONFIG_ENA_STORAGE_START_ADDRESS) // start address of storage
|
||||
#define ENA_STORAGE_TEK_MAX (CONFIG_ENA_STORAGE_TEK_MAX) // Period of storing TEKs // length of a stored beacon -> RPI keysize + AEM size + 4 Bytes for ENIN + 4 Bytes for RSSI
|
||||
#define ENA_STORAGE_TEMP_BEACONS_MAX (CONFIG_ENA_STORAGE_TEMP_BEACONS_MAX) // Maximum number of temporary stored beacons
|
||||
|
||||
/**
|
||||
* @brief structure for TEK
|
||||
*/
|
||||
typedef struct __attribute__((__packed__))
|
||||
{
|
||||
uint8_t key_data[ENA_KEY_LENGTH]; // key data for encryption
|
||||
uint32_t enin; // ENIN marking start of validity
|
||||
uint8_t rolling_period; // period after validity start to mark key as expired
|
||||
} ena_tek_t;
|
||||
|
||||
/**
|
||||
* @brief sturcture for storing a temporary beacon
|
||||
*/
|
||||
typedef struct __attribute__((__packed__))
|
||||
{
|
||||
uint8_t rpi[ENA_KEY_LENGTH]; // received RPI of beacon
|
||||
uint8_t aem[ENA_AEM_METADATA_LENGTH]; // received AEM of beacon
|
||||
uint32_t timestamp_first; // timestamp of first recognition
|
||||
uint32_t timestamp_last; // timestamp of last recognition
|
||||
int rssi; // average measured RSSI
|
||||
} ena_temp_beacon_t;
|
||||
|
||||
/**
|
||||
* @brief sturcture for permanently storing a beacon after threshold reached
|
||||
*/
|
||||
typedef struct __attribute__((__packed__))
|
||||
{
|
||||
uint8_t rpi[ENA_KEY_LENGTH]; // received RPI of beacon
|
||||
uint8_t aem[ENA_AEM_METADATA_LENGTH]; // received AEM of beacon
|
||||
uint32_t timestamp; // timestamp of last recognition
|
||||
int rssi; // average measured RSSI
|
||||
} ena_beacon_t;
|
||||
|
||||
/**
|
||||
* @brief read bytes at given address
|
||||
*
|
||||
* @param[in] address the address to read bytes from
|
||||
* @param[out] data pointer to write the read data
|
||||
* @param[in] size how many bytes to read
|
||||
*/
|
||||
void ena_storage_read(size_t address, void *data, size_t size);
|
||||
|
||||
/**
|
||||
* @brief store bytes at given address
|
||||
*
|
||||
* @param[in] address the address to write bytes to
|
||||
* @param[in] data pointer to the data to write
|
||||
* @param[in] size how many bytes to write
|
||||
*/
|
||||
void ena_storage_write(size_t address, void *data, size_t size);
|
||||
|
||||
/**
|
||||
* @brief deletes bytes at given address and shift other data back
|
||||
*
|
||||
* @param[in] address the address to delete from
|
||||
* @param[in] end_address the address to mark end of shift
|
||||
* @param[in] size how many bytes to delete
|
||||
*/
|
||||
void ena_storage_shift_delete(size_t address, size_t end_address, size_t size);
|
||||
|
||||
/**
|
||||
* @brief get last stored TEK
|
||||
*
|
||||
* @param[out] tek pointer to write last TEK to
|
||||
*
|
||||
* @return
|
||||
* total number of TEKs stored
|
||||
*/
|
||||
uint32_t ena_storage_read_last_tek(ena_tek_t *tek);
|
||||
|
||||
/**
|
||||
* @brief store given TEK
|
||||
*
|
||||
* This will store the given TEK as new TEK.
|
||||
*
|
||||
* @param[in] tek the tek to store
|
||||
*/
|
||||
void ena_storage_write_tek(ena_tek_t *tek);
|
||||
|
||||
/**
|
||||
* @brief get number of stored temporary beacons
|
||||
*
|
||||
* @return
|
||||
* total number of temporary beacons stored
|
||||
*/
|
||||
uint32_t ena_storage_temp_beacons_count(void);
|
||||
|
||||
/**
|
||||
* @brief get temporary beacon at given index
|
||||
*
|
||||
* @param[in] index the index of the temporary beacon to read
|
||||
* @param[out] beacon pointer to temporary to write to
|
||||
*/
|
||||
void ena_storage_get_temp_beacon(uint32_t index, ena_temp_beacon_t *beacon);
|
||||
|
||||
/**
|
||||
* @brief store temporary beacon
|
||||
*
|
||||
* @param[in] beacon new temporary beacon to store
|
||||
*
|
||||
* @return
|
||||
* index of new stored beacon
|
||||
*/
|
||||
uint32_t ena_storage_add_temp_beacon(ena_temp_beacon_t *beacon);
|
||||
|
||||
/**
|
||||
* @brief store temporary beacon at given index
|
||||
*
|
||||
* @param[in] index the index of the temporary beacon to overwrite
|
||||
* @param[in] beacon temporary beacon to store
|
||||
*/
|
||||
void ena_storage_set_temp_beacon(uint32_t index, ena_temp_beacon_t *beacon);
|
||||
|
||||
/**
|
||||
* @brief remove temporary beacon at given index
|
||||
*
|
||||
* @param[in] index the index of the temporary beacon to remove
|
||||
*/
|
||||
void ena_storage_remove_temp_beacon(uint32_t index);
|
||||
|
||||
/**
|
||||
* @brief get number of permanently stored beacons
|
||||
*
|
||||
* @return
|
||||
* total number of beacons stored
|
||||
*/
|
||||
uint32_t ena_storage_beacons_count(void);
|
||||
|
||||
/**
|
||||
* @brief get permanently stored beacon at given index
|
||||
*
|
||||
* @param[in] index the index of the beacon to read
|
||||
* @param[out] beacon pointer to to write to
|
||||
*/
|
||||
void ena_storage_get_beacon(uint32_t index, ena_beacon_t *beacon);
|
||||
|
||||
/**
|
||||
* @brief permanently store beacon
|
||||
*
|
||||
* @param[in] beacon new beacon to permanently store
|
||||
*/
|
||||
void ena_storage_add_beacon(ena_beacon_t *beacon);
|
||||
|
||||
/**
|
||||
* @brief erase the storage
|
||||
*
|
||||
* This function completely deletes all stored data and resets the counters
|
||||
* of TEKs, temporary beacon and beacon to zero.
|
||||
*/
|
||||
void ena_storage_erase(void);
|
||||
|
||||
/**
|
||||
* @brief erase all stored TEKs
|
||||
*
|
||||
* This function deletes all stored TEKs and resets counter to zero.
|
||||
*/
|
||||
void ena_storage_erase_tek(void);
|
||||
|
||||
/**
|
||||
* @brief erase all stored temporary beacons
|
||||
*
|
||||
* This function deletes all stored temporary beacons and resets counter to zero.
|
||||
*/
|
||||
void ena_storage_erase_temporary_beacon(void);
|
||||
|
||||
/**
|
||||
* @brief erase all permanently stored beacons
|
||||
*
|
||||
* This function deletes all stored beacons and resets counter to zero.
|
||||
*/
|
||||
void ena_storage_erase_beacon(void);
|
||||
|
||||
/**
|
||||
* @brief dump all stored TEKs to serial output
|
||||
*
|
||||
* This function prints all stored TEKs to serial output in
|
||||
* the following CSV format: #,enin,tek
|
||||
*/
|
||||
void ena_storage_dump_tek(void);
|
||||
|
||||
/**
|
||||
* @brief dump all stored temporary beacons to serial output
|
||||
*
|
||||
* This function prints all stored temporary beacons to serial output in
|
||||
* the following CSV format: #,timestamp_first,timestamp_last,rpi,aem,rssi
|
||||
*/
|
||||
void ena_storage_dump_temp_beacons(void);
|
||||
|
||||
/**
|
||||
* @brief dump all stored beacons to serial output
|
||||
*
|
||||
* This function prints all stored beacons to serial output in
|
||||
* the following CSV format: #,timestamp,rpi,aem,rssi
|
||||
*/
|
||||
void ena_storage_dump_beacons(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef _ena_H_
|
||||
#define _ena_H_
|
||||
|
||||
#define ENA_LOG "ESP-ENA" // TAG for Logging
|
||||
#define ENA_BT_ROTATION_TIMEOUT_INTERVAL (CONFIG_ENA_BT_ROTATION_TIMEOUT_INTERVAL) // change advertising payload and therefore the BT address
|
||||
#define ENA_BT_RANDOMIZE_ROTATION_TIMEOUT_INTERVAL (CONFIG_ENA_BT_RANDOMIZE_ROTATION_TIMEOUT_INTERVAL) // random intervall change for BT address change
|
||||
|
||||
/**
|
||||
* @brief Start Exposure Notification API
|
||||
*
|
||||
* This initializes the complete stack of ESP_ENA. It will initialize BLE module and
|
||||
* starting a task for managing advertising and scanning processes.
|
||||
*
|
||||
*/
|
||||
void ena_start(void);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user