Is there any way to modify CBAdvertisementDataManufacturerDataKey from CBPeripheralManager? I understand I can get the CBAdvertisementDataManufacturerDataKey from CBCentralManager.
The reason I want to do this is because I want the peripheral to advertise a 10-byte value without resorting to having the central connect to it, discover services, and then reading a characteristic which would contain the 10-byte value.
No, this is currently not possible as of iOS 7. The Manufacturer Data is reserved by Apple and is unmodifiable (at least on non-jailbroken devices). If you were writing the firmware for your own peripheral, this would not be a problem. But since the CoreBluetooth api is a layer above Apple's actual implementation of the iOS ble firmware, we face the limitations of what they actually expose. You may consider advertising you own custom service and displaying the same value you would have put in the manufacturer data, however.
Related
According to iOS documentation, when an iOS application that utilizes BLE as a peripheral moves to background mode, peripheral name is not advertised and all service UUIDs are placed in a special ‘overflow’ area, they can be discovered only by an iOS device which is explicitly scanning for them.
I sniffed the BLE packets sent over the air when application is in background. There is no local name and service UUID data. There is an 'overflow' area which encodes the service UUID. A brief discussion can be found here: https://github.com/crownstone/bluenet-ios-basic-localization/blob/master/BROADCASTING_AS_BEACON.md
I wish to know if there is any way we can determine the actual service UUID being advertised from the data in 'overflow' area. iOS documentation states that when an app is advertising as BLE peripheral in background, another iOS app can find it by explicitly specifying the service UUIDs to scan for. So, there must be a way to figure out the actual UUID from overflow data.
Any pointers on this would be helpful.
No. The data in the overflow area is hashed (sending several 128-bit UUIDs would be much too large for an advertising packet). I don't believe the hash is documented, but I strongly suspect that it's based on a Bloom filter, so that Apple can probabilistically pack a unlimited number of UUIDs into the very limited space of an advertising packet.
The upside of all of this is that it means the data isn't there in the advertising packet (and really can't be). You will need to connect to the device to discover its services.
I have MFi device which uses BLE for control and Classic Bluetooth for audio streaming.
In the App, i use coreBluetooth framework to scan BLE and EAAccessory framework to scan Classic Bluetooth.
I don't want the BLE of target device to be connected if its Classic Bluetooth is not yet connected. So i need to know which EAAccessory is corresponding to target CBPeripheral.
I am familiar with coreBluetooth, there is UUID string to identify the CBPeripheral. But it looks not exist in EAAccessory.
I have an idea but not sure: maybe firmware side can config EAAccessory's serial number and CBPeripheral's manufacture data in advertisement data with the same
serial number, so that App side can check if they are the same.
Dose anyone knows the general way to implement this in App side and firmware side?
I really do not think there is s relationship between the 2. BT and BTLE are managed by different chip at peripheral side and phone side.
Usually in BT you use the MAC address to identify the peripheral on BTLE side the MAC address is not used anymore since iOS at the first connection give its own identifier to the peripheral.
What you can do is probably at firmware side, by exposing a service with a characteristic that somehow relate the 2.
UPDATE AFTER COMMENT
I see, as far as I know there a best practice doesn't exist.The worst part is that you have to handle connections differently, mostly due to how connection are made on iOS side. While on the BLE you can choose a not encrypted connection that would not require paring or bonding, on BT side I guess that bonding is required.
Probably the most simple flow would be, user bond the BT device. Once you are in the app and detect the connected BT device, use a scan method for detect BLE companion device by filtering for a specific service id that your device exposes, once you do that you can also filter discoveries using BLE name without still making a connection.
Adv packet are restricted in size (29 usable byte) but you can also use the scan response (31 byte), that exposes some additional properties such as manufacturer data that will be exposed in a dictionary (kCBAdvDataManufacturerData).
Once you know that is the correct device you can start a connection, that does not require pair or bond but is NOT encrypted (Pair and Bond will require the user to accept the connection inside your app).
We are developing an app which needs to scan for beacons in the background. This requires us for iOS to specify a service UUID while scanning. See Apple documentation:
Apps that have specified the bluetooth-central background mode are allowed to scan while in the background. That said, they must explicitly scan for one or more services by specifying them in the serviceUUIDs parameter. The CBCentralManagerOptionShowPowerAlertKey scan option is ignored while scanning in the background.
We are using a Raspberry Pi with a bluetooth adapter to send a beacon signal (conforming the AltBeacon spec). Unfortunately we are not able to find out how the service UUID should be set in the BLE Advertising PDU, is it part of the Bluetooth specification or part of the Manufacturer specific data structure? We did find examples for setting the service UUID for when you use an iOS device as beacon, but since we are using a generic bluetooth adapter we cannot use that.
Could anyone clarify us how and where the service UUID should be set in the beacon transmission?
is it part of the Bluetooth specification or part of the Manufacturer specific data structure?
the later.
generally when you setting the advertising parameters, you can set the UUID(or name, tx power, etc) to it.
I need to provide communication via Bluetooth Low Energy 4.0 between iOS-device from one side and certain peripheral device, which has bluetooth-module onboard.
Peripheral device was assembled with DORJI DBM01 bluetooth LE 4.0 module which allow to communicate with it using one characteristic with READ property (UUID = 0xFFF4) and one characteristic with WRITE property (UUID = 0xFFF1). Technical manual of DORJI DBM01 is here: http://dorji.com/docs/data/DBM01.pdf
I succeeded in establishing bluetooth LE connection between iOS-device (using Core Bluetooth Framework) and described above peripheral device, but characteristic with READ property doesn't have a property of notify (CBCharacteristicPropertyNotify in Core Bluetooth Framework). So I have to use some kind of infinite loop to scan and read new information from characteristic with READ property (by calling method of CBPeripheral instance - readValueForCharacteristic:) instead of subscribing to a characteristing value (by calling method setNotifyValue:forCharacteristic:).
Is it possible to add notify property to read characteristic of peripheral device (for instance, by engineer who built peripheral device or adding some low-level code which run on peripheral device) or notify property is an integral part of BLE-module (DORJI DBM01) and it can't be added without using another BLE-module?
The DBM01 is based on a Texas Instruments CC2540, like many other BLE-to-serial modules, which do implement notifications, so technically, it is definitely possible to do it.
However, this requires the firmware of the DBM01 to support it, and you'll of course have the issue of upgrading said firmware in existing modules. Unless there are undocumented features on the module, I doubt there would be a way to change the behaviour of the module without touching the firmware.
Another option could be (but that really depends on your scenario) to switch the central and peripheral roles, so that the iOS app would be notified when the BLE module writes data. As I understand it, this needs to be done in hardware (the level on a specific pin needs to be changed).
I'm looking for a way to be able to track another BTLE-enabled iOS device using mine, while within range. Basically, one device would have to log it's geolocation info, and then send it periodically to the other device, using BTLE.
How would I be able to do this? In general, I haven't been able to find much info on how to send and receive messages via BTLE, so any help in that category would be great. I've seen this answer already, but it didn't help me much, and I'm wondering if anything has changed since then.
If not possible through Apple's built-in framework, do you know of any external ones that would allow for this?
Long, long, long, longgg story short, but here ya go:
On one iOS device, adopt both the CBCentralManager and CBPeripheralManager. The CBCentralManager is responsible for connecting to external peripherals and maintaining that connection. The CBPeripheralManager will be what you'll use to read/write from the iOS device that your using a peripheral.
On the other iOS device, adopt just the CBPeripheralManager. You'll need add all the services and characteristics into the CBPeripheralManager that are stated in the GATT profile. Check out developer.bluetooth.org. These services and characteristics are necessary in order to connect from one device to the other.
In addition to just the gatt characteristics and services, you'll need to add in a custom service with a characteristic that you store your location data.
Check out the docs but for CBPeripheralManager in particularly you'll need to utilize
-(void) peripheralManager:(BLEPeripheralManager*)mgr requiresResponseToWriteRequests:(NSArray*)requests;
and
-(void) peripheralManager:(BLEPeripheralManager*)mgr requiresResponseToReadRequest:(CBATTRequest*)request;
in order to pass the location data between devices..Sorry for the brief overview, but there's just way too much to write up quickly.