Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 280
Stpn Avatar asked Nov 02 '22 16:11

Stpn


1 Answers

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.

like image 73
allprog Avatar answered Nov 12 '22 16:11

allprog