1 /*
2    This example code is in the Public Domain (or CC0 licensed, at your option.)
3 
4    Unless required by applicable law or agreed to in writing, this
5    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
6    CONDITIONS OF ANY KIND, either express or implied.
7 */
8 
9 #ifndef __ESP_EDDYSTONE_PROTOCOL_H__
10 #define __ESP_EDDYSTONE_PROTOCOL_H__
11 
12 #include "stdbool.h"
13 #include "stdint.h"
14 
15 /* Eddystone definitions */
16 #define EDDYSTONE_SERVICE_UUID          0xFEAA
17 
18 #define EDDYSTONE_FRAME_TYPE_UID        0x00
19 #define EDDYSTONE_FRAME_TYPE_URL        0x10
20 #define EDDYSTONE_FRAME_TYPE_TLM        0x20
21 #define EDDYSTONE_FRAME_TYPE_EID        0x30
22 //UID
23 #define EDDYSTONE_UID_RANG_DATA_LEN     1
24 #define EDDYSTONE_UID_NAMESPACE_LEN     10
25 #define EDDYSTONE_UID_INSTANCE_LEN      6
26 #define EDDYSTONE_UID_RFU_LEN           2
27 #define EDDYSTONE_UID_DATA_LEN         (EDDYSTONE_UID_RANG_DATA_LEN + EDDYSTONE_UID_NAMESPACE_LEN + EDDYSTONE_UID_INSTANCE_LEN)
28 //TLM
29 #define EDDYSTONE_TLM_VERSION_LEN          1
30 #define EDDYSTONE_TLM_BATTERY_VOLTAGE_LEN  2
31 #define EDDYSTONE_TLM_TEMPERATURE_LEN      2
32 #define EDDYSTONE_TLM_ADV_COUNT_LEN        4
33 #define EDDYSTONE_TLM_TIME_LEN             4
34 #define EDDYSTONE_TLM_DATA_LEN             (EDDYSTONE_TLM_VERSION_LEN + EDDYSTONE_TLM_BATTERY_VOLTAGE_LEN + \
35 EDDYSTONE_TLM_TEMPERATURE_LEN + EDDYSTONE_TLM_ADV_COUNT_LEN + EDDYSTONE_TLM_TIME_LEN)
36 //URL
37 #define EDDYSTONE_URL_SCHEME_LEN        1
38 #define EDDYSTONE_URL_ENCODED_MAX_LEN   17
39 #define EDDYSTONE_URL_MAX_LEN           (EDDYSTONE_URL_SCHEME_LEN + EDDYSTONE_URL_ENCODED_MAX_LEN)
40 #define EDDYSTONE_URL_TX_POWER_LEN      1
41 
42 
43 /* Eddystone UID frame */
44 typedef struct {
45     int8_t    ranging_data;     /*<! calibrated Tx power at 0m */
46     uint8_t   namespace_id[10];
47     uint8_t   instance_id[6];
48     uint8_t   reserved[2];
49 } __attribute__((packed))esp_eddystone_uid_t;
50 
51 /* Eddystone URL frame */
52 typedef struct {
53     int8_t    tx_power;         /*<! calibrated Tx power at 0m */
54     uint8_t   url_scheme;       /*<! encoded scheme prefix */
55     uint8_t   encoded_url[0];   /*<! length 1-17 */
56 } __attribute__((packed))esp_eddystone_url_t;
57 
58 /* Eddystone TLM frame */
59 typedef struct {
60     uint8_t    version;        /*<! TLM version,0x00 for now */
61     uint16_t   batt;           /*<! battery voltage, 1mV/bit */
62     uint16_t   temp;           /*<! beacon temperature */
63     uint32_t   adv_count;      /*<! adv pdu count since power-on or reboot */
64     uint32_t   time;           /*<! time sence power-on or reboot, a 0.1 second resolution counter */
65 } __attribute__((packed)) esp_eddystone_tlm_t;
66 
67 /*  AD Structure of flags */
68 typedef struct {
69     uint8_t     len;
70     uint8_t     type;
71     uint8_t     flags;
72 } __attribute__((packed)) esp_eddystone_flags_t;
73 
74 /* AD Structure of complete 16-bit service uuid */
75 typedef struct {
76     uint8_t     len;
77     uint8_t     type;
78     uint16_t    uuid;       /*<! complete list of 16-bit service UUIDs data type value */
79 } __attribute__((packed)) esp_eddystone_uuid_t;
80 
81 /* AD Structure of eddystone frame*/
82 typedef struct {
83     uint8_t     len;        /*<! length of eddystone data */
84     uint8_t     type;       /*<! service data type,must be 0x16 */
85     uint16_t    uuid;       /*<! 16-bit eddystone uuid */
86     uint8_t     frame_type;
87     union {
88         esp_eddystone_uid_t     uid;
89         esp_eddystone_url_t     url;
90         esp_eddystone_tlm_t     tlm;
91     } u[0];
92 } __attribute__((packed)) esp_eddystone_frame_t;
93 
94 /* eddystone packet type */
95 typedef struct {
96     esp_eddystone_flags_t   flags;
97     esp_eddystone_uuid_t    uuid;
98     esp_eddystone_frame_t   frame;
99 } __attribute__((packed)) esp_eddystone_packet_t;
100 
101 /*
102  * URLs are written only with the graphic printable characters of the US-ASCII coded character set.
103  * The octets 00-20 and 7F-FF hexadecimal are not used.
104  * See “Excluded US-ASCII Characters” in RFC 2936.
105  *
106  */
esp_eddystone_is_char_invalid(int ch)107 static inline bool esp_eddystone_is_char_invalid(int ch)
108 {
109     return (ch >= 0x00 && ch <= 0x20) || (ch >= 0x7f && ch <= 0xff);
110 }
111 
112 #endif /* __ESP_EDDYSTONE_PROTOCOL_H__ */
113