iOS Core Bluetooth Not asking for Pair

Mangesh picture Mangesh · Jul 31, 2013 · Viewed 11.4k times · Source

In My recent project, I need to communicate a Hardware (Bluetooth Low energy).I have implement all the delegate methods code. I am able to Connect hardware and device, But I am not getting pairing alert (Attached screen shot). Why not it is asking for pairing? Thank you.

  #import "BTWCentralConnectionManager.h"

    @implementation BTWCentralConnectionManager

    @synthesize cbcManager;

    @synthesize discoveredPeripheral;

    @synthesize findMeServiceCharacteristic;

    @synthesize findMeService;

    @synthesize delegate=_delegate;

    static NSString *kFindMeServiceUUID=@"1802";

    static NSString *kFindMeCharacteristicUUID=@"2A06";

    static BTWCentralConnectionManager* connectionManager = nil;

    +(BTWCentralConnectionManager *)sharedConnectionManager{

    @synchronized(self)

    {

        if (!connectionManager){

            connectionManager=[[self alloc] init];


        }

        return connectionManager;

    }

    return nil;

}


    -(void)findMe {

    Byte code=0x02;

    if(self.discoveredPeripheral){

        [self.discoveredPeripheral writeValue:[NSData dataWithBytes:&code length:1] forCharacteristic:self.findMeServiceCharacteristic type:CBCharacteristicWriteWithoutResponse];


    }else{

        UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"Test" message:@"Invalid Charactersitcs" delegate:nil cancelButtonTitle:nil     otherButtonTitles:@"OK", nil];

        [alertView show];

        alertView=nil;

    }
}

-(void)searchForDevices{

    self.cbcManager=[[CBCentralManager alloc] initWithDelegate:self queue:nil];

}

    -(void)connect {

    NSDictionary* connectOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey];


    [self.cbcManager connectPeripheral:self.discoveredPeripheral options:connectOptions];

}

    -(void)disconnect{

    [self cleanup];

}


- (void)centralManagerDidUpdateState:(CBCentralManager *)central {

    switch (central.state) {

        case CBCentralManagerStatePoweredOn:{

            [self.cbcManager scanForPeripheralsWithServices:@[ [CBUUID UUIDWithString:kFindMeServiceUUID] ] options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @NO }];

        }

            break;

            // Scans for any peripheral

        default:{

            UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"Test" message:@"Cental Manager did change state" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];

            [alertView show];

            alertView=nil;

        }

            break;
    }

}


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

    // Stops scanning for peripheral

    [self.cbcManager stopScan];


    if (self.discoveredPeripheral != peripheral) {

        self.discoveredPeripheral = peripheral;

        [self.delegate didDeviceDiscoverd:self.discoveredPeripheral.name];

    }

}

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{

    [self.delegate didDeviceConnectionFailed:error];

    [self cleanup];
}


- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{

    [self.delegate didDeviceConnected];

    [self.discoveredPeripheral setDelegate:self];

    [self.discoveredPeripheral discoverServices:@[[CBUUID UUIDWithString:kFindMeServiceUUID]]];

}


- (void)peripheral:(CBPeripheral *)aPeripheral didDiscoverServices:(NSError *)error {

    if (error) {

        NSString *strMsg=[NSString stringWithFormat:@"didDiscoverServices: %@",  error];

        UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"Test" message:strMsg 
delegate:nil cancelButtonTitle:nil     otherButtonTitles:@"OK", nil];

        [alertView show];

        alertView=nil;

        [self cleanup];

        return;

    }

    for (CBService *service in aPeripheral.services) {

        if ([service.UUID isEqual:[CBUUID UUIDWithString:kFindMeServiceUUID]]) {

            self.findMeService=service;

            [self.discoveredPeripheral discoverCharacteristics:@[[CBUUID UUIDWithString:kFindMeCharacteristicUUID]] forService:self.findMeService];

        }

    }

}

- (void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{

    if(error){

        NSString *strMsg=[NSString stringWithFormat:@"didDiscoverCharacteristicsForService: %@",  error];

        UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"Test" message:strMsg delegate:nil cancelButtonTitle:nil     otherButtonTitles:@"OK", nil];

        [alertView show];

        alertView=nil;

    }

    for(CBCharacteristic *character in [service characteristics])
    {

        if([[service UUID] isEqual:[CBUUID UUIDWithString:kFindMeServiceUUID]] &&
           [[character UUID] isEqual:[CBUUID UUIDWithString:kFindMeCharacteristicUUID]])
        {

            NSString *strMsg=[NSString stringWithFormat:@"didDiscoverCharacteristicsForService: %@",  character];

            UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"Test" message:strMsg delegate:nil cancelButtonTitle:nil     otherButtonTitles:@"OK", nil];

            [alertView show];

            alertView=nil;

            self.findMeServiceCharacteristic = character;

        }
    }
}


- (void) peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error

{

    NSString *strMsg=[NSString stringWithFormat:@"Did update value for characteristic %@, new value: %@, error: %@", characteristic, [characteristic value], error];

    UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"Test" message:strMsg delegate:nil cancelButtonTitle:nil     otherButtonTitles:@"OK", nil];

    [alertView show];

    alertView=nil;


}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {

    if (error) {

        NSLog(@"Error changing notification state: %@", error.localizedDescription);

    }


    // Exits if it's not the transfer characteristic

    if (![characteristic.UUID isEqual:[CBUUID UUIDWithString:kFindMeCharacteristicUUID]]) {

        return;

    }


    NSString *strMsg=[NSString stringWithFormat:@"didUpdateNotificationStateForCharacteristic %@, reason: %@", characteristic, error];

    UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"Test" message:strMsg delegate:nil cancelButtonTitle:nil     otherButtonTitles:@"OK", nil];

    [alertView show];


    alertView=nil;

}

- (void) peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error

{

    if (error)

    {

        NSString *strMsg=[NSString stringWithFormat:@"Failed to write value for characteristic %@, reason: %@", characteristic, error];

        UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"Test" message:strMsg delegate:nil cancelButtonTitle:nil     otherButtonTitles:@"OK", nil];

        [alertView show];

        alertView=nil;

    }
    else
    {
        NSString *strMsg=[NSString stringWithFormat:@"Did write value for characterstic %@, new value: %@", characteristic, [characteristic value]];

        UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"Test" message:strMsg delegate:nil cancelButtonTitle:nil     otherButtonTitles:@"OK", nil];

        [alertView show];

        alertView=nil;

    }
}

- (void)cleanup

{

    if (!self.discoveredPeripheral.isConnected) {

        return;

    }

    if (self.discoveredPeripheral.services != nil) {

        for (CBService *service in self.discoveredPeripheral.services) {

            if (service.characteristics != nil) {

                for (CBCharacteristic *characteristic in service.characteristics) {

                    if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kFindMeServiceUUID]]) {

                        if (characteristic.isNotifying) {

                            [self.discoveredPeripheral setNotifyValue:NO forCharacteristic:characteristic];

                            return;

                        }

                    }

                }

            }
        }
    }
    [self.cbcManager cancelPeripheralConnection:self.discoveredPeripheral];
    [self.delegate didDeviceDisconnected];
}
@end
`

Answer

koshyyyk picture koshyyyk · Aug 14, 2013

If I understand you right you can write a value successfully to a characteristic but you don't get a pairing request.

The pairing is triggered by the peripheral. Meaning the peripheral has to refuse the write or read request of your central to a characteristic. Your central gets the refusal "unauthorized authentication" and then tries to pair with the peripheral and showing the pairing alert pop up you are waiting for. This is all done by core bluetooth automatically. The only thing you need to do is change the characteristics options and permissions in your peripheral. This is the apple sample code to trigger a pairing:

emailCharacteristic = [[CBMutableCharacteristic alloc]
    initWithType:emailCharacteristicUUID
    properties:CBCharacteristicPropertyRead
    | CBCharacteristicPropertyNotifyEncryptionRequired
    value:nil permissions:CBAttributePermissionsReadEncryptionRequired];

source: CoreBluetooth_concepts iOS7 preview

Also check out the WWDC 2012 advanced core bluetooth video at 28 minutes they explain the concept of pairing.