Skip to content

Commit 52b6e84

Browse files
committed
Updated Eddystone URL
1 parent 8d4cb8d commit 52b6e84

File tree

2 files changed

+26
-51
lines changed

2 files changed

+26
-51
lines changed

libraries/BLE/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.ino

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,17 @@
2828
#include "BLEEddystoneURL.h"
2929

3030
#include "esp_sleep.h"
31-
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
31+
char unprintable[] = {0x01, 0xFF, 0xDE, 0xAD};
32+
String URL[] = {
33+
"http://www.espressif.com/", // prefix 0x00, suffix 0x00
34+
"https://www.texas.gov", // prefix 0x01, suffix 0x0D
35+
"http://en.mapy.cz", // prefix 0x02, no valid suffix
36+
"https://arduino.cc", // prefix 0x03, no valid suffix
37+
"google.com", // URL without specified prefix - the function will assume default prefix "http://www." = 0x00
38+
"diginfo.tv", // URL without specified prefix - the function will assume default prefix "http://www." = 0x00
39+
// "http://www.URLsAbove17BytesAreNotAllowed.com", // Too long URL - setSmartURL() will return 0 = ERR
40+
// "", // Empty string - setSmartURL() will return 0 = ERR
41+
// String(unprintable), // Unprintable characters / corrupted String - setSmartURL() will return 0 = ERR
3942
};
4043
#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up
4144
#define BEACON_POWER ESP_PWR_LVL_N12
@@ -47,15 +50,15 @@ RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memo
4750
BLEAdvertising *pAdvertising;
4851
struct timeval now;
4952

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/)
53+
std::string BEACON_UUID("8ec76ea3-6668-48da-9866-75be8bc86f4d"); // UUID v1 128-Bit (may use linux tool uuidgen or random numbers via https://www.uuidgenerator.net/)
5154

5255
int setBeacon()
5356
{
5457
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
5558
BLEAdvertisementData oScanResponseData = BLEAdvertisementData();
5659

5760
BLEEddystoneURL EddystoneURL;
58-
61+
EddystoneURL.setUUID(BLEUUID(BEACON_UUID));
5962
EddystoneURL.setPower(BEACON_POWER); // This is only information about the power. The actual power is set by `BLEDevice::setPower(BEACON_POWER)`
6063
if(EddystoneURL.setSmartURL(URL[bootcount%(sizeof(URL)/sizeof(URL[0]))])){
6164
String frame = EddystoneURL.getFrame();

libraries/BLE/src/BLEEddystoneURL.cpp

Lines changed: 13 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -76,33 +76,14 @@ std::string BLEEddystoneURL::getData() {
7676

7777
String BLEEddystoneURL::getFrame() {
7878
BLEHeadder[7] = lengthURL + 5; // Fill in real: Type + 2B UUID + Frame Type + Tx power + URL (note: the Byte holding the length does not count itself)
79-
//Serial.printf("BLEHeadder[7](%d) = sizeof(BLEHeadder)(%d) + lengthURL(%d)\n", BLEHeadder[7], sizeof(BLEHeadder), lengthURL);
80-
8179
String frame(BLEHeadder, sizeof(BLEHeadder));
82-
/*
83-
Serial.printf("BLEHeadder:\n");
84-
for(int i = 0; i < frame.length(); ++i){
85-
Serial.printf("[%d] 0x%02X=%d='%c'\n",i , frame.c_str()[i],frame.c_str()[i],frame.c_str()[i]);
86-
}
87-
Serial.printf("m_eddystoneData.advertisedTxPower = 0x%02X=%d:\nm_eddystoneData.url:\n", m_eddystoneData.advertisedTxPower, m_eddystoneData.advertisedTxPower);
88-
for(int i = 0; i < lengthURL; ++i){
89-
Serial.printf("[%d] 0x%02X=%d='%c'\n",i , m_eddystoneData.url[i],m_eddystoneData.url[i],m_eddystoneData.url[i]);
90-
}
91-
*/
92-
9380
frame += String((char*) &m_eddystoneData, lengthURL+1); // + 1 for TX power
94-
/*
95-
Serial.println("Returning frame:");
96-
for(int i = 0; i < frame.length(); ++i){
97-
Serial.printf("[%d] 0x%02X=%d='%c'\n",i , frame.c_str()[i],frame.c_str()[i],frame.c_str()[i]);
98-
}
99-
*/
81+
10082
return frame;
10183
} // getFrame
10284

103-
// TODO test his change !!!
10485
BLEUUID BLEEddystoneURL::getUUID() {
105-
uint16_t uuid = (((uint16_t)BLEHeadder[10]) << 8) & BLEHeadder[9];
86+
uint16_t uuid = (((uint16_t)BLEHeadder[10]) << 8) | BLEHeadder[9];
10687
return BLEUUID(uuid);
10788
} // getUUID
10889

@@ -123,7 +104,6 @@ String BLEEddystoneURL::getPrefix(){
123104
}
124105

125106
String BLEEddystoneURL::getSuffix(){
126-
log_d("suffix = m_eddystoneData.url[%d] 0x%02X", lengthURL-1, m_eddystoneData.url[lengthURL-1]);
127107
if(m_eddystoneData.url[lengthURL-1] <= 0x0D){
128108
return EDDYSTONE_URL_SUFFIX[m_eddystoneData.url[lengthURL-1]];
129109
}else{
@@ -133,9 +113,6 @@ String BLEEddystoneURL::getSuffix(){
133113

134114
std::string BLEEddystoneURL::getDecodedURL() {
135115
std::string decodedURL = "";
136-
log_d("prefix = m_eddystoneData.url[0] 0x%02X",m_eddystoneData.url[0]);
137-
log_e("prefix type m_eddystoneData.url[0]=%d", m_eddystoneData.url[0]); // this is actually debug
138-
139116
decodedURL += std::string(getPrefix().c_str());
140117
if(decodedURL.length() == 0){ // No prefix extracted - interpret byte [0] as character
141118
decodedURL += m_eddystoneData.url[0];
@@ -165,7 +142,6 @@ void BLEEddystoneURL::setData(std::string data) {
165142
lengthURL = data.length() - (sizeof(m_eddystoneData) - sizeof(m_eddystoneData.url));
166143
} // setData
167144

168-
// TODO test his change !!!
169145
void BLEEddystoneURL::setUUID(BLEUUID l_uuid) {
170146
uint16_t beaconUUID = l_uuid.getNative()->uuid.uuid16;
171147
BLEHeadder[10] = beaconUUID >> 8;
@@ -221,11 +197,21 @@ void BLEEddystoneURL::setURL(std::string url) {
221197
} // setURL
222198

223199
int BLEEddystoneURL::setSmartURL(String url) {
200+
if(url.length() == 0){
201+
log_e("URL String has 0 length");
202+
return 0; // ERROR
203+
}
204+
for(auto character : url){
205+
if(!isPrintable(character)){
206+
log_e("URL contains unprintable character(s)");
207+
return 0; // ERROR
208+
}
209+
}
224210
bool hasPrefix = false;
225211
bool hasSuffix = false;
226212
m_eddystoneData.url[0] = 0x00; // Init with default prefix "http://www."
227213
uint8_t suffix = 0x0E; // Init with empty string
228-
log_d("encode url \"%s\" with length %d", url.c_str(), url.length());
214+
log_d("Encode url \"%s\" with length %d", url.c_str(), url.length());
229215
for(uint8_t i = 0; i < 4; ++i){
230216
//log_d("check if substr \"%s\" == prefix \"%s\" ", url.substring(0, EDDYSTONE_URL_PREFIX[i].length()), EDDYSTONE_URL_PREFIX[i]);
231217
if(url.substring(0, EDDYSTONE_URL_PREFIX[i].length()) == EDDYSTONE_URL_PREFIX[i]){
@@ -246,7 +232,6 @@ int BLEEddystoneURL::setSmartURL(String url) {
246232
size_t found_pos = std_url.find(std_suffix);
247233
//log_d("check if in url \"%s\" can find suffix \"%s\": found_pos = %d", std_url.c_str(), std_suffix.c_str(), found_pos);
248234
if(found_pos != std::string::npos){
249-
log_d("Found suffix 0x%02X = \"%s\" at position %d", i, EDDYSTONE_URL_SUFFIX[i], found_pos);
250235
hasSuffix = true;
251236
suffix = i;
252237
break;
@@ -255,30 +240,17 @@ int BLEEddystoneURL::setSmartURL(String url) {
255240

256241
size_t baseUrlLen = url.length() - (hasPrefix ? EDDYSTONE_URL_PREFIX[m_eddystoneData.url[0]].length() : 0) - EDDYSTONE_URL_SUFFIX[suffix].length();
257242
lengthURL = baseUrlLen + 1 + (hasSuffix ? 1 : 0);
258-
Serial.printf("Original URL has length %dB - prefix 1 Byte - suffix len (%d)B = base url len %dB\n=> complete url len with prefix and suffix =%d\n", url.length(), EDDYSTONE_URL_SUFFIX[suffix].length(), baseUrlLen, lengthURL); // debug
259243
if(lengthURL > 18){
260244
log_e("Encoded URL is too long %d B - max 18 B", lengthURL);
261245
return 0; // ERROR
262246
}
263247
String baseUrl = url.substring((hasPrefix ? EDDYSTONE_URL_PREFIX[m_eddystoneData.url[0]].length() : 0), baseUrlLen+(hasPrefix ? EDDYSTONE_URL_PREFIX[m_eddystoneData.url[0]].length() : 0));
264-
Serial.printf("Prefix #%02X = \"%s\", length =%d\n", m_eddystoneData.url[0], EDDYSTONE_URL_PREFIX[m_eddystoneData.url[0]].c_str(), EDDYSTONE_URL_PREFIX[m_eddystoneData.url[0]].length()); // debug
265-
Serial.printf("Base URL and length %d = : \"%s\"\n", baseUrlLen, baseUrl.c_str()); // debug
266248
memcpy((void*)(m_eddystoneData.url+1), (void*)baseUrl.c_str(), baseUrl.length()); // substr for Arduino String
267249

268250
if(hasSuffix){
269-
Serial.printf("Put suffix on position m_eddystoneData.url[%d] value %d = : \"%s\"\n", 1+baseUrlLen, suffix, EDDYSTONE_URL_SUFFIX[suffix].c_str()); // debug
270251
m_eddystoneData.url[1+baseUrlLen] = suffix;
271252
}
272253

273-
Serial.printf("[0] 0x%02X = \"%s\" prefix\n", m_eddystoneData.url[0], EDDYSTONE_URL_PREFIX[m_eddystoneData.url[0]].c_str());
274-
for(int i = 1; i < baseUrlLen+1; ++i){
275-
Serial.printf("[%d] 0x%02X = \'%c\'\n",i , m_eddystoneData.url[i], m_eddystoneData.url[i]);
276-
}
277-
if(hasSuffix){
278-
Serial.printf("[%d] 0x%02X = \"%s\" suffix\n", lengthURL-1, m_eddystoneData.url[lengthURL-1], EDDYSTONE_URL_SUFFIX[m_eddystoneData.url[lengthURL-1]].c_str());
279-
}
280-
281-
282254
return 1; // OK
283255
} // setSmartURL
284256

0 commit comments

Comments
 (0)