1414#include < BLEEddystoneTLM.h>
1515#include < BLEBeacon.h>
1616
17- #define ENDIAN_CHANGE_U16 (x ) ((((x)&0xFF00 ) >> 8 ) + (((x)&0xFF ) << 8 ))
18-
1917int scanTime = 5 ; // In seconds
2018BLEScan *pBLEScan;
2119
@@ -37,58 +35,66 @@ class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
3735 Serial.println (devUUID.toString ().c_str ());
3836 Serial.println (" " );
3937 }
40- else
38+
39+ if (advertisedDevice.haveManufacturerData () == true )
4140 {
42- if (advertisedDevice.haveManufacturerData () == true )
43- {
44- std::string strManufacturerData = advertisedDevice.getManufacturerData ();
41+ std::string strManufacturerData = advertisedDevice.getManufacturerData ();
4542
46- uint8_t cManufacturerData[100 ];
47- strManufacturerData.copy ((char *)cManufacturerData, strManufacturerData.length (), 0 );
43+ uint8_t cManufacturerData[100 ];
44+ strManufacturerData.copy ((char *)cManufacturerData, strManufacturerData.length (), 0 );
4845
49- if (strManufacturerData.length () == 25 && cManufacturerData[0 ] == 0x4C && cManufacturerData[1 ] == 0x00 )
50- {
51- Serial.println (" Found an iBeacon!" );
52- BLEBeacon oBeacon = BLEBeacon ();
53- oBeacon.setData (strManufacturerData);
54- Serial.printf (" iBeacon Frame\n " );
55- Serial.printf (" ID: %04X Major: %d Minor: %d UUID: %s Power: %d\n " , oBeacon.getManufacturerId (), ENDIAN_CHANGE_U16 (oBeacon.getMajor ()), ENDIAN_CHANGE_U16 (oBeacon.getMinor ()), oBeacon.getProximityUUID ().toString ().c_str (), oBeacon.getSignalPower ());
56- }
57- else
46+ if (strManufacturerData.length () == 25 && cManufacturerData[0 ] == 0x4C && cManufacturerData[1 ] == 0x00 )
47+ {
48+ Serial.println (" Found an iBeacon!" );
49+ BLEBeacon oBeacon = BLEBeacon ();
50+ oBeacon.setData (strManufacturerData);
51+ Serial.printf (" iBeacon Frame\n " );
52+ Serial.printf (" ID: %04X Major: %d Minor: %d UUID: %s Power: %d\n " , oBeacon.getManufacturerId (), ENDIAN_CHANGE_U16 (oBeacon.getMajor ()), ENDIAN_CHANGE_U16 (oBeacon.getMinor ()), oBeacon.getProximityUUID ().toString ().c_str (), oBeacon.getSignalPower ());
53+ }
54+ else
55+ {
56+ Serial.println (" Found another manufacturers beacon!" );
57+ Serial.printf (" strManufacturerData: %d " , strManufacturerData.length ());
58+ for (int i = 0 ; i < strManufacturerData.length (); i++)
5859 {
59- Serial.println (" Found another manufacturers beacon!" );
60- Serial.printf (" strManufacturerData: %d " , strManufacturerData.length ());
61- for (int i = 0 ; i < strManufacturerData.length (); i++)
62- {
63- Serial.printf (" [%X]" , cManufacturerData[i]);
64- }
65- Serial.printf (" \n " );
60+ Serial.printf (" [%X]" , cManufacturerData[i]);
6661 }
62+ Serial.printf (" \n " );
6763 }
68- return ;
6964 }
7065
7166 uint8_t *payLoad = advertisedDevice.getPayload ();
67+ // search for Eddystone Service Data in the advertising payload
68+ // *payload shall point to eddystone data or to its end when not found
69+ const uint8_t serviceDataEddystone[3 ] = {0x16 , 0xAA , 0xFE }; // it has Eddystone BLE UUID
70+ const size_t payLoadLen = advertisedDevice.getPayloadLength ();
71+ uint8_t *payLoadEnd = payLoad + payLoadLen - 1 ; // address of the end of payLoad space
72+ while (payLoad < payLoadEnd) {
73+ if (payLoad[1 ] == serviceDataEddystone[0 ] && payLoad[2 ] == serviceDataEddystone[1 ] && payLoad[3 ] == serviceDataEddystone[2 ]) {
74+ // found!
75+ payLoad += 4 ;
76+ break ;
77+ }
78+ payLoad += *payLoad + 1 ; // payLoad[0] has the field Length
79+ }
7280
73- BLEUUID checkUrlUUID = (uint16_t )0xfeaa ;
74-
75- if (advertisedDevice.getServiceUUID ().equals (checkUrlUUID))
81+ if (payLoad < payLoadEnd) // Eddystone Service Data and respective BLE UUID were found
7682 {
77- if (payLoad[ 11 ] == 0x10 )
83+ if (* payLoad == 0x10 )
7884 {
7985 Serial.println (" Found an EddystoneURL beacon!" );
8086 BLEEddystoneURL foundEddyURL = BLEEddystoneURL ();
81- std::string eddyContent ((char *)&payLoad[11 ]); // incomplete EddystoneURL struct!
82-
83- foundEddyURL.setData (eddyContent);
87+ uint8_t URLLen = *(payLoad - 4 ) - 3 ; // Get Field Length less 3 bytes (type and UUID)
88+ foundEddyURL.setData (std::string ((char *)payLoad, URLLen));
8489 std::string bareURL = foundEddyURL.getURL ();
8590 if (bareURL[0 ] == 0x00 )
8691 {
87- size_t payLoadLen = advertisedDevice. getPayloadLength ();
92+ // dumps all bytes in advertising payload
8893 Serial.println (" DATA-->" );
94+ uint8_t *payLoad = advertisedDevice.getPayload ();
8995 for (int idx = 0 ; idx < payLoadLen; idx++)
9096 {
91- Serial.printf (" 0x%08X " , payLoad[idx]);
97+ Serial.printf (" 0x%02X " , payLoad[idx]);
9298 }
9399 Serial.println (" \n Invalid Data" );
94100 return ;
@@ -98,30 +104,19 @@ class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
98104 Serial.printf (" Decoded URL: %s\n " , foundEddyURL.getDecodedURL ().c_str ());
99105 Serial.printf (" TX power %d\n " , foundEddyURL.getPower ());
100106 Serial.println (" \n " );
101- }
102- else if (payLoad[ 11 ] == 0x20 )
107+ }
108+ else if (* payLoad == 0x20 )
103109 {
104110 Serial.println (" Found an EddystoneTLM beacon!" );
105- BLEEddystoneTLM foundEddyURL = BLEEddystoneTLM ();
106- std::string eddyContent ((char *)&payLoad[11 ]); // incomplete EddystoneURL struct!
107-
108- eddyContent = " 01234567890123" ;
109-
110- for (int idx = 0 ; idx < 14 ; idx++)
111- {
112- eddyContent[idx] = payLoad[idx + 11 ];
113- }
114-
115- foundEddyURL.setData (eddyContent);
116- Serial.printf (" Reported battery voltage: %dmV\n " , foundEddyURL.getVolt ());
117- Serial.printf (" Reported temperature from TLM class: %.2fC\n " , (double )foundEddyURL.getTemp ());
118- int temp = (int )payLoad[16 ] + (int )(payLoad[15 ] << 8 );
119- float calcTemp = temp / 256 .0f ;
120- Serial.printf (" Reported temperature from data: %.2fC\n " , calcTemp);
121- Serial.printf (" Reported advertise count: %d\n " , foundEddyURL.getCount ());
122- Serial.printf (" Reported time since last reboot: %ds\n " , foundEddyURL.getTime ());
111+
112+ BLEEddystoneTLM eddystoneTLM;
113+ eddystoneTLM.setData (std::string ((char *)payLoad, 14 ));
114+ Serial.printf (" Reported battery voltage: %dmV\n " , eddystoneTLM.getVolt ());
115+ Serial.printf (" Reported temperature: %.2f°C (raw data=0x%04X)\n " , eddystoneTLM.getTemp (), eddystoneTLM.getRawTemp ());
116+ Serial.printf (" Reported advertise count: %d\n " , eddystoneTLM.getCount ());
117+ Serial.printf (" Reported time since last reboot: %ds\n " , eddystoneTLM.getTime ());
123118 Serial.println (" \n " );
124- Serial.print (foundEddyURL .toString ().c_str ());
119+ Serial.print (eddystoneTLM .toString ().c_str ());
125120 Serial.println (" \n " );
126121 }
127122 }
0 commit comments