Open gerryilagan opened 6 years ago
I'm also trying to turn my ESP32 into iBeacon, but no luck with your edit too. Share your sketch please.
Thank you in advance.
@31337Ghost If you are trying to discover iBeacon with iPhone then it may be hard or even not possible. You need to do more google search about that.
https://github.com/chegewara/esp32-tests-library/blob/master/arduino/iBeacon/iBeacon.ino
@chegewara had googled much and got only valid packet structure description, and working (not checked by me) implementation on RaspberryPi. Now i checked closer @gerryilagan issue and its looks like there some ENDIAN stuff is missed in BLEBeacon::setProximityUUID
. Also in your suggested example there are myBeacon.setManufacturerId(0x4c00)
, but as i can assume bytes order is wrong, because later value would be ENDIAN_CHANGE_U16, so the right way is to left manufacturerId by default (for Apple valid iBeacon) m_beaconData.manufacturerId = 0x4c00;
In conclusion, according to https://os.mbed.com/blog/entry/BLE-Beacons-URIBeacon-AltBeacons-iBeacon/
My advertised packet (got from iOS scanner app):
004c0215 a134d0b2 1da21ba7 c94ce8e0 0c9f7a2d 00050058 c5
is almost ok, except first 5 bytes (because BLE Scanner app not shows them).
Then i checked BLEAdvertisementData::getPayload()
and got 02 01 07 1A FF 00 4C 02 15 A1 34 D0 B2 1D A2 1B A7 C9 4C E8 E0 0C 9F 7A 2D 00 05 00 58 C5
with 3d byte differed from datasheets 06
. I made advertisementData.setFlags(0x06)
and packet became valid 02 01 06 1A FF 00 4C 02 15 A1 34 D0 B2 1D A2 1B A7 C9 4C E8 E0 0C 9F 7A 2D 00 05 00 58 C5
but still iBeacon scanner (including macOS one, which do not need specified UUID) cant recognise ESP32 as iBeacon. Same time iOS app LightBlue (and others) shows that ESP32 is Connectable YES. Any ideas?
Got it working on iPhone:
myBeacon.setManufacturerId(0x4c00);
...
advertisementData.setFlags(0x1A);
Full code: https://pastebin.com/0Zh07Zzn
Im glad you made it and thanks for sharing with us. Flag 0x1a is odd, but what to expect from iPhone?
@31337Ghost That's what I basically changed on my sketch plus edited the BLEUUID code I mentioned above since a BLE scan on both the iPhone and Android apps I use show a reversed UUID.
I've also noticed, upon checking the received data from the apps, that the advertising data seems to be duplicated instead of being padded with zeroes at the end of the advertising packet. Other iBeacons show the area as padded zeroes which is logical since the data ends at the power byte at the end of the advertising packet.
Upon checking the structure of the advertising packet on the library, the structure seems to end at the power byte so the code that memcpy the data to the structure would only copy data up to that location. Since the whole area is more than the length of the structure, some other memory parts is being included that is causing the duplicate copy of the advertising packet -- this is just a logical guess since I stopped investigating at the structure.
@chegewara can you point me to the file where the iBeacon flags used are defined. I've checked other beacons and they seem to have the same flags. But I tried leaving the flags unchanged from the example code and it still works. I just want to find out why 0x1a is the value from the other iBeacon apps.
When I receive my iBeacons from Radius Networks, I'll try to compare the data from their Beacons.
Some insights about the Advertising flags:
The code that produces the 0x07:
advertisementData.setFlags(ESP_BLE_ADV_FLAG_LIMIT_DISC | ESP_BLE_ADV_FLAG_GEN_DISC |
ESP_BLE_ADV_FLAG_BREDR_NOT_SPT);
07 # Flags value 0x07 = 000000111
bit 4 (OFF) Simultaneous LE and BR/EDR to Same Device Capable (Host)
bit 3 (OFF) Simultaneous LE and BR/EDR to Same Device Capable (controller)
bit 2 (ON) BR/EDR Not Supported
bit 1 (ON) LE General Discoverable Mode
bit 0 (ON) LE Limited Discoverable Mode
Puzzled as to why General and Limited needs to be set at the same time. Aren't they mutually exclusive modes?
Here's the flags set by 0x1A on other Beacons:
1A # Flags value 0x1A = 000011010
bit 4 (ON) Simultaneous LE and BR/EDR to Same Device Capable (Host)
bit 3 (ON) Simultaneous LE and BR/EDR to Same Device Capable (controller)
bit 2 (OFF) BR/EDR Not Supported
bit 1 (ON) LE General Discoverable Mode
bit 0 (OFF) LE Limited Discoverable Mode
Setting Bit 4 and Bit 3 makes sense if the Bluetooth device can do BLE and BR/EDR both as a Peripheral and a Central device.
So Bit 2 has to be OFF since the Bluetooth device supports BR/EDR as defined from flags Bit 4,3
Notice how Bit 1 is ON while Bit 0 is OFF
Oh guys, I'd just tried put back flag to 0x06 and 0x07 and both of them works fine. BTW does it possible to run server mode and send iBeacon advertises simultaneously?
ADD: Yes, it is: https://pastebin.com/CNZLtLNK Works like a charm, while not connected its advertising iBeacon, while connected also works as suggested. Great lib, thanks everyone!
esp32 is capable of using classic bleutooth and LE at the same time. I did not try it though, but options in menuconfig lets you do that. Also some discussions about memory releasing lets me thing that its possible. Since i never used classic bluetooth on esp32 i dont know which of this flags can be set:
bit 4 (OFF) Simultaneous LE and BR/EDR to Same Device Capable (Host)
bit 3 (OFF) Simultaneous LE and BR/EDR to Same Device Capable (controller)
Just have to say one more thing. This library is mentioned only to use with bluetooth LE which means bit 2 should be set, and bits 3 and 4 should be 0.
Hi All, Same problem here, I´m using the Beacon example bundled with the ESP32 Arduino 1.0.1 libraries and the UUID broadcasted is reversed, I´m using iOS with the App Noteacons, also tried with my own code and the beacon cannot be detected until I reverse the UUID coded into the .ino file.
`else if (value.length() == 36) { // If the length of the string is 36 bytes then we will assume it is a long hex string in // UUID format. m_uuid.len = ESP_UUID_LEN_128; int n = 0; for(int i=0;i<value.length();){ if(value.c_str()[i] == '-') i++; uint8_t MSB = value.c_str()[i]; uint8_t LSB = value.c_str()[i+1];
if(MSB > '9') MSB -= 7;
if(LSB > '9') LSB -= 7;
m_uuid.uuid.uuid128[n++] = ((MSB&0x0F) <<4) | (LSB & 0x0F);
//( 15- n++) = reversed the uuid for the ibeacon
i+=2;
}`
https://github.com/adityathakekar/ESP32_BLE_Arduino/blob/master/src/BLEUUID.cpp
(15- n++) reverses the uuid
I'm currently using 0.49 of ESP32 Arduino and have gotten iBeacon working on my ESP32 board.
The UUID value that I am getting is in reversed order when scanned using the Locate app on iOS and the BluetoothLE Scanner on Android.
Some debugging has led me to a sscanf line of code in the file BLEUUID.cpp:
sscanf(value.c_str(), "%2x%2x%2x%2x-%2x%2x-%2x%2x-%2x%2x-%2x%2x%2x%2x%2x%2x", &vals[15], &vals[14], &vals[13], &vals[12], &vals[11], &vals[10], &vals[9], &vals[8], &vals[7], &vals[6], &vals[5], &vals[4], &vals[3], &vals[2], &vals[1], &vals[0] );
When I reverse the order of the offsets of the variable vals (instead of 15 to 0, I made it 0 to 15), the UUID on my ESP32 source code becomes the same as the one being read by the two mobile apps.
kindly check the above code
The problem with @adityathakekar solution is that when we remove the "15-" the address of the iBeacon appears correct but if you use some "services" them the service UUID appears reversed
I found that way to solve without having to change the code in Kolban classes
when you set the proximity uuid in your code:
BLEBeacon oBeacon = BLEBeacon(); oBeacon.setManufacturerId(0x4C00); oBeacon.setProximityUUID(BLEUUID(BEACON_UUID));
Instead of using the above code, use the following:
BLEBeacon oBeacon = BLEBeacon(); oBeacon.setManufacturerId(0x4C00); BLEUUID bleUUID = BLEUUID(BEACON_UUID) ; bleUUID = bleUUID.to128(); oBeacon.setProximityUUID(BLEUUID( bleUUID.getNative()->uuid.uuid128, 16, true ));
This will fix the reversed Ibeacon address and if you use a service it will keep the uuid correct
[]s
I found that way to solve without having to change the code in Kolban classes
when you set the proximity uuid in your code:
BLEBeacon oBeacon = BLEBeacon(); oBeacon.setManufacturerId(0x4C00); oBeacon.setProximityUUID(BLEUUID(BEACON_UUID));
Instead of using the above code, use the following:
BLEBeacon oBeacon = BLEBeacon(); oBeacon.setManufacturerId(0x4C00); BLEUUID bleUUID = BLEUUID(BEACON_UUID) ; bleUUID = bleUUID.to128(); oBeacon.setProximityUUID(BLEUUID( bleUUID.getNative()->uuid.uuid128, 16, true ));
This will fix the reversed Ibeacon address and if you use a service it will keep the uuid correct
[]s
Thanks a lot for your revert. Will implement it in ESP32.
I just came here to say that after a morning of pulling my hair out trying to get an ESP32 to behave as an iBeacon I stumble across @31337Ghost and @bonadio 's contributions. Thanks to both of you.
I'm currently using 0.49 of ESP32 Arduino and have gotten iBeacon working on my ESP32 board.
The UUID value that I am getting is in reversed order when scanned using the Locate app on iOS and the BluetoothLE Scanner on Android.
Some debugging has led me to a sscanf line of code in the file BLEUUID.cpp:
sscanf(value.c_str(), "%2x%2x%2x%2x-%2x%2x-%2x%2x-%2x%2x-%2x%2x%2x%2x%2x%2x", &vals[15], &vals[14], &vals[13], &vals[12], &vals[11], &vals[10], &vals[9], &vals[8], &vals[7], &vals[6], &vals[5], &vals[4], &vals[3], &vals[2], &vals[1], &vals[0] );
When I reverse the order of the offsets of the variable vals (instead of 15 to 0, I made it 0 to 15), the UUID on my ESP32 source code becomes the same as the one being read by the two mobile apps.