iOS Corebluetooth services never discovered, but are visible in advertisingData of delegate method

bluetooth-lowenergy, core-bluetooth, ios, objective-c

Solution

Regarding your code: do you implement the `peripheral:didDiscoverServices:` callback, and how do you handle it? In the simplest case it should be something like this:

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
  /* Find all characteristics for all discovered services */
  for (CBService *service in peripheral.services)
  {
    [peripheral discoverCharacteristics:nil forService:service];
  }
}

In addition, what's in the advertisement data and what is provided are two different stories. The peripheral can advertise any services even those that are not provided I can easily start advertisement in iOS like this:

NSDictionary *data = @{CBAdvertisementDataServiceUUIDsKey:
        @[[CBUUID UUIDWithString:@"180D"], [CBUUID UUIDWithString:@"FFBC"]]};
[peripheralManager startAdvertising:data];

Without adding any of these services.

I suggest you try to discover the peripheral first with a working app, like the BLEUtility or BLExplr and see if the peripheral is really providing those services.

Problem

I am using iOS 6 Corebluetooth with Alert Notification service. The services don't show up in peripheral for some reason, althought the advertisingData in delegate method looks correct. Here is the delegate method: ``` (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI { bool ourGuy = NO; NSLog(@"DATA: %@", advertisementData); NSArray *keys = [advertisementData allKeys]; for (int i = 0; i < [keys count]; ++i) { id key = [keys objectAtIndex: i]; NSString *keyName = (NSString *) key; NSObject *value = [advertisementData objectForKey: key]; if ([value isKindOfClass: [NSArray class]]) { printf(" key: %s\n", [keyName cStringUsingEncoding: NSUTF8StringEncoding]); if ([keyName isEqualToString: @"kCBAdvDataServiceUUIDs"] ){ NSArray *values = (NSArray *) value; for (int j = 0; j < [values count]; ++j) { if ([[values objectAtIndex: j] isKindOfClass: [CBUUID class]]) { CBUUID *uuid = [values objectAtIndex: j]; NSString *uuidString = [uuid representativeString]; NSLog(@"FOUND SERVICE UUID %@", uuidString); if ([uuidString isEqualToString:kalertNotificationServiceUUIDString]){ NSLog(@"Connecting"); if (![foundPeripherals containsObject:peripheral]) { ourGuy = YES; } } } else { const char *valueString = [[value description] cStringUsingEncoding: NSUTF8StringEncoding]; printf(" value(%d): %s\n", j, valueString); } } } } else { const char *valueString = [[value description] cStringUsingEncoding: NSUTF8StringEncoding]; printf(" key: %s, value: %s\n", [keyName cStringUsingEncoding: NSUTF8StringEncoding], valueString); } } if (ourGuy){ [foundPeripherals addObject:peripheral]; peripheral.delegate = self; [centralManager connectPeripheral:peripheral options:nil]; } } ``` Here is what the log looks like: ``` 2013-08-25 23:30:17.417 myControl[688:907] DATA: { kCBAdvDataLocalName = myTEST; kCBAdvDataServiceUUIDs = ( "Unknown (<1811>)", "Unknown (<180f>)" ); } key: kCBAdvDataServiceUUIDs 2013-08-25 23:30:17.419 myControl[688:907] FOUND SERVICE UUID 1811 2013-08-25 23:30:17.421 myControl[688:907] Connecting 2013-08-25 23:30:17.422 myControl[688:907] FOUND SERVICE UUID 180f key: kCBAdvDataLocalName, value: myTEST key: kCBAdvDataTxPowerLevel, value: -8 ``` The delegate method for the service discovery: ``` - (void) peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{ for (int i=0; i < peripheral.services.count; i++) { CBService *s = [peripheral.services objectAtIndex:i]; NSLog(@" UUUID %@", [s.UUID representativeString]); // [peripheral discoverCharacteristics:nil forService:s]; } } ``` The log from that method: ``` 2013-08-25 23:30:18.266 myControl[688:907] UUUID 1800 2013-08-25 23:30:18.269 myControl[688:907] UUUID 1801 ``` These are two UUIDs for the BLE GATT and GAP. Services for the peripheral that are seen in advertisementData never show up. What am I doing wrong?

Original source