14
14
#include < BLEEddystoneTLM.h>
15
15
#include < BLEBeacon.h>
16
16
17
- #define ENDIAN_CHANGE_U16 (x ) ((((x)&0xFF00 ) >> 8 ) + (((x)&0xFF ) << 8 ))
18
-
19
17
int scanTime = 5 ; // In seconds
20
18
BLEScan *pBLEScan;
21
19
@@ -37,58 +35,66 @@ class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
37
35
Serial.println (devUUID.toString ().c_str ());
38
36
Serial.println (" " );
39
37
}
40
- else
38
+
39
+ if (advertisedDevice.haveManufacturerData () == true )
41
40
{
42
- if (advertisedDevice.haveManufacturerData () == true )
43
- {
44
- std::string strManufacturerData = advertisedDevice.getManufacturerData ();
41
+ std::string strManufacturerData = advertisedDevice.getManufacturerData ();
45
42
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 );
48
45
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++)
58
59
{
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]);
66
61
}
62
+ Serial.printf (" \n " );
67
63
}
68
- return ;
69
64
}
70
65
71
66
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
+ }
72
80
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
76
82
{
77
- if (payLoad[ 11 ] == 0x10 )
83
+ if (* payLoad == 0x10 )
78
84
{
79
85
Serial.println (" Found an EddystoneURL beacon!" );
80
86
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));
84
89
std::string bareURL = foundEddyURL.getURL ();
85
90
if (bareURL[0 ] == 0x00 )
86
91
{
87
- size_t payLoadLen = advertisedDevice. getPayloadLength ();
92
+ // dumps all bytes in advertising payload
88
93
Serial.println (" DATA-->" );
94
+ uint8_t *payLoad = advertisedDevice.getPayload ();
89
95
for (int idx = 0 ; idx < payLoadLen; idx++)
90
96
{
91
- Serial.printf (" 0x%08X " , payLoad[idx]);
97
+ Serial.printf (" 0x%02X " , payLoad[idx]);
92
98
}
93
99
Serial.println (" \n Invalid Data" );
94
100
return ;
@@ -98,30 +104,19 @@ class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
98
104
Serial.printf (" Decoded URL: %s\n " , foundEddyURL.getDecodedURL ().c_str ());
99
105
Serial.printf (" TX power %d\n " , foundEddyURL.getPower ());
100
106
Serial.println (" \n " );
101
- }
102
- else if (payLoad[ 11 ] == 0x20 )
107
+ }
108
+ else if (* payLoad == 0x20 )
103
109
{
104
110
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 ());
123
118
Serial.println (" \n " );
124
- Serial.print (foundEddyURL .toString ().c_str ());
119
+ Serial.print (eddystoneTLM .toString ().c_str ());
125
120
Serial.println (" \n " );
126
121
}
127
122
}
0 commit comments