0
votes

I am building an iOS app (in Swift) that acts as both a Core Bluetooth peripheral and central. I need to determine the txPower of the peripheral but I don't necessarily need to send it to the other device's central (though that would be great); I would be happy just determining the txPower of the peripheral on the sending device itself.

I know that I can determine txPower from Manufacturer Specific Data, but I have not been able to figure out how to read my device's Manufacturer Specific Data, and the advertisingData my central is picking up only includes the peripheral's UUID, not the Manufacturer Specific Data.

This is how I set up my peripheral:

peripheral = CBPeripheralManager(delegate: self, queue: nil)
myService = CBMutableService(type: CBUUID(string: "109F17E4-EF68-43FC-957D-502BB0EFCF47"), primary: true)
peripheral.addService(myService)

This is how I set up my central:

centralManager.scanForPeripheralsWithServices([myCustomServiceUUID], options: nil)

Then in peripheralManagerDidUpdateState:

    if peripheral.state == CBPeripheralManagerState.PoweredOn {

        self.peripheral.startAdvertising([CBAdvertisementDataServiceUUIDsKey: [myService.UUID] ])}

... in centralManagerDidUpdateState:

    if central.state == CBCentralManagerState.PoweredOn {

        centralManager.scanForPeripheralsWithServices([myCustomServiceUUID], options: [
            CBCentralManagerScanOptionAllowDuplicatesKey : NSNumber(bool: true)
            ])}

And the resulting advertisementData NSDictionary in didDiscoverPeripheral delegate is:

["kCBAdvDataServiceUUIDs": (
"109F17E4-EF68-43FC-957D-502BB0EFCF47"), "kCBAdvDataIsConnectable": 1]

Again, any solution that allows me to add the Manufacturer Specific Data in my peripheral's advertising packet, or allows me to read the peripheral's Manufacturer Specific Data or txPower on the sending device would be truly awesome. Thanks so much in advance!

2
i am creating code to find the distance of BLE device . and i am getting few data in advertisement . not the kCBAdvDataTxPowerLevel key . so how to find the TxPower value ? have you figure it out yet ? or any other way of finding it ?Moxarth

2 Answers

3
votes
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI

Using this method, you can get all the data which are the peripheral is advertising.

Try to look what you are getting in response. This will allow you to read data.

NSString * abc = [RSSI stringValue] ;

NSLog(@" \n I see an advertisement with \n identifer: %@, \n state: %@ , \n name: %@, \n services: %@, \n RSSI : %@ \n ,\n description: %@ \n",
          [peripheral identifier],
          [peripheral state],
          [peripheral name],
          [peripheral services],
          abc,
          [advertisementData description]);

In advertisementData description log , you will get the key with its value like this description:

{
    kCBAdvDataIsConnectable = 1;
    kCBAdvDataLocalName = givenName;
    kCBAdvDataManufacturerData = <given data>;
    kCBAdvDataServiceUUIDs = (0536);
    kCBAdvDataTxPowerLevel = some value ;
}

Hope you got what you are looking for.

txpower is what you will be advertising from device under CBAdvertisementDataTxPowerLevelKey. Look for this

CB_EXTERN NSString * const CBAdvertisementDataTxPowerLevelKey;
1
votes

From my experience, it is not possible to get the TX power level or any manufacturer data at all from other iOS peripherals using the CoreBluetooth API, because it is stripped away from the scan result you receive on the didDiscoverPeripheral callback. You can however get the RSSI value of the peripheral, maybe you can use that depending on what you want to achieve.

I'm not sure how you would want to determine the TX power level from the manufacturer data though. The BLE specification defines a seperate characteristic for it.

Hope this helps!