Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BLE upgrades #8724

Merged
merged 18 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Updated Eddystone URL (not complete)
  • Loading branch information
PilnyTomas authored and me-no-dev committed Oct 5, 2023
commit 371dea46a2cb3e7239dd69d90b76f8bf716ccb23
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
EddystoneURL beacon by BeeGee
EddystoneURL frame specification https://github.com/google/eddystone/blob/master/eddystone-url/README.md

Upgraded on: Feb 20, 2023
By: Tomas Pilny
*/

/*
Expand All @@ -27,8 +29,17 @@

#include "esp_sleep.h"

#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up
RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory
String URL[] = {"http://www.espressif.com/", // prefix 0x00, suffix 0x00
"https://www.texas.gov", // prefix 0x01, suffix 0x0D
"http://en.mapy.cz", // prefix 0x02, no valid suffix
"https://arduino.cc", // prefix 0x03, no valid suffix
"google.com", // URL without specified prefix - the function will assume default prefix "http://www." = 0x00
"diginfo.tv", // URL without specified prefix - the function will assume default prefix "http://www." = 0x00
"http://www.URLsAbove17BytesAreNotAllowed.com", // Too long URL - setSmartURL() will return 0 = ERR
};
#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up
#define BEACON_POWER ESP_PWR_LVL_N12
RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory
RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memory

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

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

static const char *eddystone_url_prefix_subs[] = {
"http://www.",
"https://www.",
"http://",
"https://",
"urn:uuid:",
NULL
};

static const char *eddystone_url_suffix_subs[] = {
".com/",
".org/",
".edu/",
".net/",
".info/",
".biz/",
".gov/",
".com",
".org",
".edu",
".net",
".info",
".biz",
".gov",
NULL
};

static int string_begin_with(const char *str, const char *prefix)
{
int prefix_len = strlen(prefix);
if (strncmp(prefix, str, prefix_len) == 0)
{
return prefix_len;
}
return 0;
}

void setBeacon()
int setBeacon()
{
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
BLEAdvertisementData oScanResponseData = BLEAdvertisementData();

const char url[] = "https://d.giesecke.tk";

int scheme_len, ext_len = 1, i, idx, url_idx;
char *ret_data;
int url_len = strlen(url);

ret_data = (char *)calloc(1, url_len + 13);

ret_data[0] = 2; // Len
ret_data[1] = 0x01; // Type Flags
ret_data[2] = 0x06; // GENERAL_DISC_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04
ret_data[3] = 3; // Len
ret_data[4] = 0x03; // Type 16-Bit UUID
ret_data[5] = 0xAA; // Eddystone UUID 2 -> 0xFEAA LSB
ret_data[6] = 0xFE; // Eddystone UUID 1 MSB
ret_data[7] = 19; // Length of Beacon Data
ret_data[8] = 0x16; // Type Service Data
ret_data[9] = 0xAA; // Eddystone UUID 2 -> 0xFEAA LSB
ret_data[10] = 0xFE; // Eddystone UUID 1 MSB
ret_data[11] = 0x10; // Eddystone Frame Type
ret_data[12] = 0xF4; // Beacons TX power at 0m

i = 0, idx = 13, url_idx = 0;

//replace prefix
scheme_len = 0;
while (eddystone_url_prefix_subs[i] != NULL)
{
if ((scheme_len = string_begin_with(url, eddystone_url_prefix_subs[i])) > 0)
{
ret_data[idx] = i;
idx++;
url_idx += scheme_len;
break;
}
i++;
BLEEddystoneURL EddystoneURL;

EddystoneURL.setPower(BEACON_POWER); // This is only information about the power. The actual power is set by `BLEDevice::setPower(BEACON_POWER)`
if(EddystoneURL.setSmartURL(URL[bootcount%(sizeof(URL)/sizeof(URL[0]))])){
String frame = EddystoneURL.getFrame();
std::string data(EddystoneURL.getFrame().c_str(), frame.length());
oAdvertisementData.addData(data);
oScanResponseData.setName("ESP32 URLBeacon");
pAdvertising->setAdvertisementData(oAdvertisementData);
pAdvertising->setScanResponseData(oScanResponseData);
return 1; // OK
}else{
Serial.println("Smart URL set ERR");
return 0; // ERR
}
while (url_idx < url_len)
{
i = 0;
ret_data[idx] = url[url_idx];
ext_len = 1;
while (eddystone_url_suffix_subs[i] != NULL)
{
if ((ext_len = string_begin_with(&url[url_idx], eddystone_url_suffix_subs[i])) > 0)
{
ret_data[idx] = i;
break;
}
else
{
ext_len = 1; //inc 1
}
i++;
}
url_idx += ext_len;
idx++;
}
ret_data[7] = idx - 8;

Serial.printf("struct size %d url size %d reported len %d\n",
url_len + 13,
url_len, ret_data[7]);

Serial.printf("URL in data %s\n", &ret_data[13]);

std::string eddyStoneData(ret_data);

oAdvertisementData.addData(eddyStoneData);
oScanResponseData.setName("URLBeacon");
pAdvertising->setAdvertisementData(oAdvertisementData);
pAdvertising->setScanResponseData(oScanResponseData);
}

void setup()
{

Serial.begin(115200);
gettimeofday(&now, NULL);

Serial.printf("start ESP32 %lu\n", bootcount++);

Serial.printf("deep sleep (%llds since last reset, %llds since last boot)\n", now.tv_sec, now.tv_sec - last);
Serial.printf("Start ESP32 %lu\n", bootcount++);
Serial.printf("Deep sleep (%llds since last reset, %llds since last boot)\n", now.tv_sec, now.tv_sec - last);

last = now.tv_sec;

// Create the BLE Device
BLEDevice::init("URLBeacon");

BLEDevice::setPower(ESP_PWR_LVL_N12);
BLEDevice::setPower(BEACON_POWER);

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

pAdvertising = BLEDevice::getAdvertising();

setBeacon();
// Start advertising
pAdvertising->start();
Serial.println("Advertizing started...");
delay(10000);
pAdvertising->stop();
Serial.printf("enter deep sleep\n");
if(setBeacon()){
// Start advertising
pAdvertising->start();
Serial.println("Advertising started...");
delay(10000);
pAdvertising->stop();
}
Serial.println("Enter deep sleep");
bootcount++;
esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION);
Serial.printf("in deep sleep\n");
}

void loop()
Expand Down
Loading