diff --git a/examples/bluetooth/ble_eddystone/main/esp_eddystone_api.c b/examples/bluetooth/ble_eddystone/main/esp_eddystone_api.c index 333913bd7..20fffb2e6 100644 --- a/examples/bluetooth/ble_eddystone/main/esp_eddystone_api.c +++ b/examples/bluetooth/ble_eddystone/main/esp_eddystone_api.c @@ -57,19 +57,43 @@ static const char* eddystone_url_encoding[14] = { ".gov" }; +/****************** Eddystone-UID ************** +Byte offset Field Description + 0 Frame Type Value = 0x00 + 1 Ranging Data Calibrated Tx power at 0 m + 2 NID[0] 10-byte Namespace + 3 NID[1] + 4 NID[2] + 5 NID[3] + 6 NID[4] + 7 NID[5] + 8 NID[6] + 9 NID[7] + 10 NID[8] + 11 NID[9] + 12 BID[0] 6-byte Instance + 13 BID[1] + 14 BID[2] + 15 BID[3] + 16 BID[4] + 17 BID[5] + 18 RFU Reserved for future use, must be0x00 + 19 RFU Reserved for future use, must be0x00 +*********************************************/ /* decode and store received UID */ static esp_err_t esp_eddystone_uid_received(const uint8_t* buf, uint8_t len, esp_eddystone_result_t* res) { uint8_t pos = 0; - if(len+4 != EDDYSTONE_UID_FRAME_LEN) { + //1-byte Ranging Data + 10-byte Namespace + 6-byte Instance + if((len != EDDYSTONE_UID_DATA_LEN) && (len != (EDDYSTONE_UID_RFU_LEN+EDDYSTONE_UID_DATA_LEN))) { //ERROR:uid len wrong return -1; } res->inform.uid.ranging_data = buf[pos++]; - for(int i=0; i<10; i++) { + for(int i=0; iinform.uid.namespace_id[i] = buf[pos++]; } - for(int i=0; i<6; i++) { + for(int i=0; iinform.uid.instance_id[i] = buf[pos++]; } return 0; @@ -94,26 +118,53 @@ static char* esp_eddystone_resolve_url_scheme(const uint8_t *url_start, const ui return url_buf; } +/************************** Eddystone-URL ************* +Frame Specification + Byte offset Field Description + 0 Frame Type Value = 0x10 + 1 TX Power Calibrated Tx power at 0 m + 2 URL Scheme Encoded Scheme Prefix + 3+ Encoded URL Length 1-17 +*******************************************************/ /* decode and store received URL, the pointer url_res points to the resolved url */ static esp_err_t esp_eddystone_url_received(const uint8_t* buf, uint8_t len, esp_eddystone_result_t* res) { char *url_res = NULL; uint8_t pos = 0; - if(len-1 > EDDYSTONE_URL_MAX_LEN) { + if(len-EDDYSTONE_URL_TX_POWER_LEN > EDDYSTONE_URL_MAX_LEN) { //ERROR:too long url return -1; } res->inform.url.tx_power = buf[pos++]; url_res = esp_eddystone_resolve_url_scheme(buf+pos, buf+len-1); memcpy(&res->inform.url.url, url_res, strlen(url_res)); + res->inform.url.url[strlen(url_res)] = '\0'; return 0; } +/****************** eddystone-tlm *************** + * Unencrypted TLM Frame Specification +Byte offset Field Description + 0 Frame Type Value = 0x20 + 1 Version TLM version, value = 0x00 + 2 VBATT[0] Battery voltage, 1 mV/bit + 3 VBATT[1] + 4 TEMP[0] Beacon temperature + 5 TEMP[1] + 6 ADV_CNT[0] Advertising PDU count + 7 ADV_CNT[1] + 8 ADV_CNT[2] + 9 ADV_CNT[3] + 10 SEC_CNT[0] Time since power-on or reboot + 11 SEC_CNT[1] + 12 SEC_CNT[2] + 13 SEC_CNT[3] +************************************************/ /* decode and store received TLM */ static esp_err_t esp_eddystone_tlm_received(const uint8_t* buf, uint8_t len, esp_eddystone_result_t* res) { uint8_t pos = 0; - if(len+4 > EDDYSTONE_TLM_FRAME_LEN) { + if(len > EDDYSTONE_TLM_DATA_LEN) { //ERROR:TLM too long return -1; } @@ -156,10 +207,16 @@ static esp_err_t esp_eddystone_get_inform(const uint8_t* buf, uint8_t len, esp_e esp_err_t esp_eddystone_decode(const uint8_t* buf, uint8_t len, esp_eddystone_result_t* res) { - static uint8_t pos=0; + if (len == 0 || buf == NULL || res == NULL) { + return -1; + } + uint8_t pos=0; while(res->common.srv_data_type != EDDYSTONE_SERVICE_UUID) { pos++; + if(pos >= len ) { + return -1; + } uint8_t ad_type = buf[pos++]; switch(ad_type) { diff --git a/examples/bluetooth/ble_eddystone/main/esp_eddystone_protocol.h b/examples/bluetooth/ble_eddystone/main/esp_eddystone_protocol.h index 5c286c928..15ae07a98 100644 --- a/examples/bluetooth/ble_eddystone/main/esp_eddystone_protocol.h +++ b/examples/bluetooth/ble_eddystone/main/esp_eddystone_protocol.h @@ -19,10 +19,25 @@ #define EDDYSTONE_FRAME_TYPE_URL 0x10 #define EDDYSTONE_FRAME_TYPE_TLM 0x20 #define EDDYSTONE_FRAME_TYPE_EID 0x30 - -#define EDDYSTONE_UID_FRAME_LEN 0x17 -#define EDDYSTONE_TLM_FRAME_LEN 0x11 -#define EDDYSTONE_URL_MAX_LEN 18 +//UID +#define EDDYSTONE_UID_RANG_DATA_LEN 1 +#define EDDYSTONE_UID_NAMESPACE_LEN 10 +#define EDDYSTONE_UID_INSTANCE_LEN 6 +#define EDDYSTONE_UID_RFU_LEN 2 +#define EDDYSTONE_UID_DATA_LEN (EDDYSTONE_UID_RANG_DATA_LEN + EDDYSTONE_UID_NAMESPACE_LEN + EDDYSTONE_UID_INSTANCE_LEN) +//TLM +#define EDDYSTONE_TLM_VERSION_LEN 1 +#define EDDYSTONE_TLM_BATTERY_VOLTAGE_LEN 2 +#define EDDYSTONE_TLM_TEMPERATURE_LEN 2 +#define EDDYSTONE_TLM_ADV_COUNT_LEN 4 +#define EDDYSTONE_TLM_TIME_LEN 4 +#define EDDYSTONE_TLM_DATA_LEN (EDDYSTONE_TLM_VERSION_LEN + EDDYSTONE_TLM_BATTERY_VOLTAGE_LEN + \ +EDDYSTONE_TLM_TEMPERATURE_LEN + EDDYSTONE_TLM_ADV_COUNT_LEN + EDDYSTONE_TLM_TIME_LEN) +//URL +#define EDDYSTONE_URL_SCHEME_LEN 1 +#define EDDYSTONE_URL_ENCODED_MAX_LEN 17 +#define EDDYSTONE_URL_MAX_LEN (EDDYSTONE_URL_SCHEME_LEN + EDDYSTONE_URL_ENCODED_MAX_LEN) +#define EDDYSTONE_URL_TX_POWER_LEN 1 /* Eddystone UID frame */