Skip to content

Commit 8d4cb8d

Browse files
committed
Updated Eddystone URL (not complete)
1 parent a3df941 commit 8d4cb8d

File tree

3 files changed

+315
-237
lines changed

3 files changed

+315
-237
lines changed

libraries/BLE/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.ino

Lines changed: 40 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
EddystoneURL beacon by BeeGee
33
EddystoneURL frame specification https://github.com/google/eddystone/blob/master/eddystone-url/README.md
44
5+
Upgraded on: Feb 20, 2023
6+
By: Tomas Pilny
57
*/
68

79
/*
@@ -27,8 +29,17 @@
2729

2830
#include "esp_sleep.h"
2931

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
3243
RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memory
3344

3445
// See the following for generating UUIDs:
@@ -38,153 +49,57 @@ struct timeval now;
3849

3950
#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/)
4051

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()
7953
{
8054
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
8155
BLEAdvertisementData oScanResponseData = BLEAdvertisementData();
8256

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
11971
}
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);
15572
}
15673

15774
void setup()
15875
{
159-
16076
Serial.begin(115200);
16177
gettimeofday(&now, NULL);
16278

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);
16681

16782
last = now.tv_sec;
16883

16984
// Create the BLE Device
17085
BLEDevice::init("URLBeacon");
171-
172-
BLEDevice::setPower(ESP_PWR_LVL_N12);
86+
BLEDevice::setPower(BEACON_POWER);
17387

17488
// Create the BLE Server
17589
// BLEServer *pServer = BLEDevice::createServer(); // <-- no longer required to instantiate BLEServer, less flash and ram usage
17690

17791
pAdvertising = BLEDevice::getAdvertising();
17892

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++;
186102
esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION);
187-
Serial.printf("in deep sleep\n");
188103
}
189104

190105
void loop()

0 commit comments

Comments
 (0)