2
2
EddystoneURL beacon by BeeGee
3
3
EddystoneURL frame specification https://github.com/google/eddystone/blob/master/eddystone-url/README.md
4
4
5
+ Upgraded on: Feb 20, 2023
6
+ By: Tomas Pilny
5
7
*/
6
8
7
9
/*
27
29
28
30
#include " esp_sleep.h"
29
31
30
- #define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up
31
- RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory
32
+ String URL[] = {" http://www.espressif.com/" , // prefix 0x00, suffix 0x00
33
+ " https://www.texas.gov" , // prefix 0x01, suffix 0x0D
34
+ " http://en.mapy.cz" , // prefix 0x02, no valid suffix
35
+ " https://arduino.cc" , // prefix 0x03, no valid suffix
36
+ " google.com" , // URL without specified prefix - the function will assume default prefix "http://www." = 0x00
37
+ " diginfo.tv" , // URL without specified prefix - the function will assume default prefix "http://www." = 0x00
38
+ " http://www.URLsAbove17BytesAreNotAllowed.com" , // Too long URL - setSmartURL() will return 0 = ERR
39
+ };
40
+ #define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up
41
+ #define BEACON_POWER ESP_PWR_LVL_N12
42
+ RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory
32
43
RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memory
33
44
34
45
// See the following for generating UUIDs:
@@ -38,153 +49,57 @@ struct timeval now;
38
49
39
50
#define BEACON_UUID " 8ec76ea3-6668-48da-9866-75be8bc86f4d" // UUID 1 128-Bit (may use linux tool uuidgen or random numbers via https://www.uuidgenerator.net/)
40
51
41
- static const char *eddystone_url_prefix_subs[] = {
42
- " http://www." ,
43
- " https://www." ,
44
- " http://" ,
45
- " https://" ,
46
- " urn:uuid:" ,
47
- NULL
48
- };
49
-
50
- static const char *eddystone_url_suffix_subs[] = {
51
- " .com/" ,
52
- " .org/" ,
53
- " .edu/" ,
54
- " .net/" ,
55
- " .info/" ,
56
- " .biz/" ,
57
- " .gov/" ,
58
- " .com" ,
59
- " .org" ,
60
- " .edu" ,
61
- " .net" ,
62
- " .info" ,
63
- " .biz" ,
64
- " .gov" ,
65
- NULL
66
- };
67
-
68
- static int string_begin_with (const char *str, const char *prefix)
69
- {
70
- int prefix_len = strlen (prefix);
71
- if (strncmp (prefix, str, prefix_len) == 0 )
72
- {
73
- return prefix_len;
74
- }
75
- return 0 ;
76
- }
77
-
78
- void setBeacon ()
52
+ int setBeacon ()
79
53
{
80
54
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData ();
81
55
BLEAdvertisementData oScanResponseData = BLEAdvertisementData ();
82
56
83
- const char url[] = " https://d.giesecke.tk" ;
84
-
85
- int scheme_len, ext_len = 1 , i, idx, url_idx;
86
- char *ret_data;
87
- int url_len = strlen (url);
88
-
89
- ret_data = (char *)calloc (1 , url_len + 13 );
90
-
91
- ret_data[0 ] = 2 ; // Len
92
- ret_data[1 ] = 0x01 ; // Type Flags
93
- ret_data[2 ] = 0x06 ; // GENERAL_DISC_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04
94
- ret_data[3 ] = 3 ; // Len
95
- ret_data[4 ] = 0x03 ; // Type 16-Bit UUID
96
- ret_data[5 ] = 0xAA ; // Eddystone UUID 2 -> 0xFEAA LSB
97
- ret_data[6 ] = 0xFE ; // Eddystone UUID 1 MSB
98
- ret_data[7 ] = 19 ; // Length of Beacon Data
99
- ret_data[8 ] = 0x16 ; // Type Service Data
100
- ret_data[9 ] = 0xAA ; // Eddystone UUID 2 -> 0xFEAA LSB
101
- ret_data[10 ] = 0xFE ; // Eddystone UUID 1 MSB
102
- ret_data[11 ] = 0x10 ; // Eddystone Frame Type
103
- ret_data[12 ] = 0xF4 ; // Beacons TX power at 0m
104
-
105
- i = 0 , idx = 13 , url_idx = 0 ;
106
-
107
- // replace prefix
108
- scheme_len = 0 ;
109
- while (eddystone_url_prefix_subs[i] != NULL )
110
- {
111
- if ((scheme_len = string_begin_with (url, eddystone_url_prefix_subs[i])) > 0 )
112
- {
113
- ret_data[idx] = i;
114
- idx++;
115
- url_idx += scheme_len;
116
- break ;
117
- }
118
- i++;
57
+ BLEEddystoneURL EddystoneURL;
58
+
59
+ EddystoneURL.setPower (BEACON_POWER); // This is only information about the power. The actual power is set by `BLEDevice::setPower(BEACON_POWER)`
60
+ if (EddystoneURL.setSmartURL (URL[bootcount%(sizeof (URL)/sizeof (URL[0 ]))])){
61
+ String frame = EddystoneURL.getFrame ();
62
+ std::string data (EddystoneURL.getFrame ().c_str (), frame.length ());
63
+ oAdvertisementData.addData (data);
64
+ oScanResponseData.setName (" ESP32 URLBeacon" );
65
+ pAdvertising->setAdvertisementData (oAdvertisementData);
66
+ pAdvertising->setScanResponseData (oScanResponseData);
67
+ return 1 ; // OK
68
+ }else {
69
+ Serial.println (" Smart URL set ERR" );
70
+ return 0 ; // ERR
119
71
}
120
- while (url_idx < url_len)
121
- {
122
- i = 0 ;
123
- ret_data[idx] = url[url_idx];
124
- ext_len = 1 ;
125
- while (eddystone_url_suffix_subs[i] != NULL )
126
- {
127
- if ((ext_len = string_begin_with (&url[url_idx], eddystone_url_suffix_subs[i])) > 0 )
128
- {
129
- ret_data[idx] = i;
130
- break ;
131
- }
132
- else
133
- {
134
- ext_len = 1 ; // inc 1
135
- }
136
- i++;
137
- }
138
- url_idx += ext_len;
139
- idx++;
140
- }
141
- ret_data[7 ] = idx - 8 ;
142
-
143
- Serial.printf (" struct size %d url size %d reported len %d\n " ,
144
- url_len + 13 ,
145
- url_len, ret_data[7 ]);
146
-
147
- Serial.printf (" URL in data %s\n " , &ret_data[13 ]);
148
-
149
- std::string eddyStoneData (ret_data);
150
-
151
- oAdvertisementData.addData (eddyStoneData);
152
- oScanResponseData.setName (" URLBeacon" );
153
- pAdvertising->setAdvertisementData (oAdvertisementData);
154
- pAdvertising->setScanResponseData (oScanResponseData);
155
72
}
156
73
157
74
void setup ()
158
75
{
159
-
160
76
Serial.begin (115200 );
161
77
gettimeofday (&now, NULL );
162
78
163
- Serial.printf (" start ESP32 %lu\n " , bootcount++);
164
-
165
- Serial.printf (" deep sleep (%llds since last reset, %llds since last boot)\n " , now.tv_sec , now.tv_sec - last);
79
+ Serial.printf (" Start ESP32 %lu\n " , bootcount++);
80
+ Serial.printf (" Deep sleep (%llds since last reset, %llds since last boot)\n " , now.tv_sec , now.tv_sec - last);
166
81
167
82
last = now.tv_sec ;
168
83
169
84
// Create the BLE Device
170
85
BLEDevice::init (" URLBeacon" );
171
-
172
- BLEDevice::setPower (ESP_PWR_LVL_N12);
86
+ BLEDevice::setPower (BEACON_POWER);
173
87
174
88
// Create the BLE Server
175
89
// BLEServer *pServer = BLEDevice::createServer(); // <-- no longer required to instantiate BLEServer, less flash and ram usage
176
90
177
91
pAdvertising = BLEDevice::getAdvertising ();
178
92
179
- setBeacon ();
180
- // Start advertising
181
- pAdvertising->start ();
182
- Serial.println (" Advertizing started..." );
183
- delay (10000 );
184
- pAdvertising->stop ();
185
- Serial.printf (" enter deep sleep\n " );
93
+ if (setBeacon ()){
94
+ // Start advertising
95
+ pAdvertising->start ();
96
+ Serial.println (" Advertising started..." );
97
+ delay (10000 );
98
+ pAdvertising->stop ();
99
+ }
100
+ Serial.println (" Enter deep sleep" );
101
+ bootcount++;
186
102
esp_deep_sleep (1000000LL * GPIO_DEEP_SLEEP_DURATION);
187
- Serial.printf (" in deep sleep\n " );
188
103
}
189
104
190
105
void loop ()
0 commit comments