diff --git a/examples/Central/iBeaconExplorer/iBeaconExplorer.ino b/examples/Central/iBeaconExplorer/iBeaconExplorer.ino new file mode 100644 index 00000000..1421ac3f --- /dev/null +++ b/examples/Central/iBeaconExplorer/iBeaconExplorer.ino @@ -0,0 +1,70 @@ +#include + +void setup() { + Serial.begin(9600); + while (!Serial); + + // begin initialization + if (!BLE.begin()) { + Serial.println("starting BLE failed!"); + + while (1); + } + + Serial.println("BLE Central scan"); + + // start scanning for peripheral + BLE.scan(); +} + +void loop() { + // check if a peripheral has been discovered + BLEDevice peripheral = BLE.available(); + + if (!peripheral) { + return; + } + if (!peripheral.hasManufacturerData()) { + return; + } + + String manufacturerData = peripheral.manufacturerData(); + if (manufacturerData.length() < 25 * 2) { + return; + } + if (manufacturerData.substring(0, 8) != "4c000215") { + return; + } + + // Discovered an iBeacon + Serial.println("Discovered an iBeacon"); + Serial.println("-----------------------"); + + // UUID + String id = manufacturerData.substring(8, 16) + "-"; + id += manufacturerData.substring(16, 20) + "-"; + id += manufacturerData.substring(20, 24) + "-"; + id += manufacturerData.substring(24, 28) + "-"; + id += manufacturerData.substring(28, 40); + Serial.print("UUID: "); + Serial.println(id); + + // Major ID + char buf[5]; + manufacturerData.substring(40, 44).toCharArray(buf, 5); + int major = (int)strtol(buf, NULL, 16); + Serial.print("Major ID: "); + Serial.println(major); + + // Minor ID + manufacturerData.substring(44, 48).toCharArray(buf, 5); + int minor = (int)strtol(buf, NULL, 16); + Serial.print("Minor ID: "); + Serial.println(minor); + + // RSSI + Serial.print("RSSI: "); + Serial.println(peripheral.rssi()); + + Serial.println(); +} diff --git a/src/BLEDevice.cpp b/src/BLEDevice.cpp index fa806104..ae4fa14d 100644 --- a/src/BLEDevice.cpp +++ b/src/BLEDevice.cpp @@ -19,6 +19,7 @@ #include "utility/ATT.h" #include "utility/BLEUuid.h" +#include "utility/BLEManufacturerData.h" #include "utility/HCI.h" #include "remote/BLERemoteDevice.h" @@ -85,6 +86,11 @@ bool BLEDevice::hasLocalName() const return (localName().length() > 0); } +bool BLEDevice::hasManufacturerData() const +{ + return (manufacturerData().length() > 0); +} + bool BLEDevice::hasAdvertisedServiceUuid() const { return hasAdvertisedServiceUuid(0); @@ -146,6 +152,25 @@ String BLEDevice::localName() const return localName; } +String BLEDevice::manufacturerData() const +{ + String manufacturerData = ""; + + for (int i = 0; i < _eirDataLength;) { + int eirLength = _eirData[i++]; + int eirType = _eirData[i++]; + + if (eirType == 0xFF) { + manufacturerData = BLEManufacturerData::manufacturerDataToString(&_eirData[i], eirLength); + break; + } + + i += (eirLength - 1); + } + + return manufacturerData; +} + String BLEDevice::advertisedServiceUuid() const { return advertisedServiceUuid(0); diff --git a/src/BLEDevice.h b/src/BLEDevice.h index cbe79c71..3e98446b 100644 --- a/src/BLEDevice.h +++ b/src/BLEDevice.h @@ -50,12 +50,14 @@ class BLEDevice { virtual String address() const; bool hasLocalName() const; - + bool hasManufacturerData() const; + bool hasAdvertisedServiceUuid() const; bool hasAdvertisedServiceUuid(int index) const; int advertisedServiceUuidCount() const; String localName() const; + String manufacturerData() const; String advertisedServiceUuid() const; String advertisedServiceUuid(int index) const; diff --git a/src/utility/BLEManufacturerData.cpp b/src/utility/BLEManufacturerData.cpp new file mode 100644 index 00000000..f880782c --- /dev/null +++ b/src/utility/BLEManufacturerData.cpp @@ -0,0 +1,40 @@ +/* + This file is part of the ArduinoBLE library. + Copyright (c) 2018 Arduino SA. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include + +#include "BLEManufacturerData.h" + +const char* BLEManufacturerData::manufacturerDataToString(const uint8_t* data, uint8_t length) +{ + static char manufacturerData[32 * 2 + 1]; + char* c = manufacturerData; + + for (int i = 0; i < length - 1; i++) { + uint8_t b = data[i]; + + utoa(b >> 4, c++, 16); + utoa(b & 0x0f, c++, 16); + } + + *c = '\0'; + + return manufacturerData; +} diff --git a/src/utility/BLEManufacturerData.h b/src/utility/BLEManufacturerData.h new file mode 100644 index 00000000..87f4b581 --- /dev/null +++ b/src/utility/BLEManufacturerData.h @@ -0,0 +1,31 @@ +/* + This file is part of the ArduinoBLE library. + Copyright (c) 2018 Arduino SA. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _BLE_MANUFACTURER_DATA_H_ +#define _BLE_MANUFACTURER_DATA_H_ + +#include + +class BLEManufacturerData +{ +public: + static const char* manufacturerDataToString(const uint8_t* data, uint8_t length); +}; + +#endif