6
votes

I'm actually to exchange informations between an iPhone and an iPad using Corebluetooth.

My iPhone act as the Central and my iPad as the Peripheral.

I'm advertizing my service but on my central when i'm going through the :

peripheral:didDiscoverServices:

the peripheral.services that I get in that method is empty.

and some seconds after i'm disconnecting from the peripheral with this error :

DISCONNECT-ERROR desc : Error Domain=CBErrorDomain Code=7 "The specified device has disconnected from us." UserInfo=0x16e60f90 {NSLocalizedDescription=The specified device has disconnected from us.}

I don't know what is going on.

EDIT:

on the Central side I have this :

-(void)startScanning{
    [super startScanning];
    // Scan for devices
    [self.centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:PERIPHERAL_SERVICE_UUID]] options:nil];
}

#pragma mark Peripheral Delegate

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
    if (error) {
        [self cleanup];
        return;
    }

    for (CBService *service in peripheral.services) {
        [peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:NEW_COMMANDS_NOTIFIER_CHARACTERISTICS_UUID]] forService:service];
    }
    // Discover other characteristics
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    if (error) {
        [self cleanup];
        return;
    }

    for (CBCharacteristic *characteristic in service.characteristics) {
        if (self.commandsFromIpadCharacteristic != characteristic) {
            self.commandsFromIpadCharacteristic = characteristic;
        }
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:NEW_COMMANDS_NOTIFIER_CHARACTERISTICS_UUID]]) {
            [peripheral setNotifyValue:YES forCharacteristic:characteristic];

        }
    }
}

On the Peripheral side I have :

#pragma mark CBPeripheralManagerDelegate

- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
    if (peripheral.state != CBPeripheralManagerStatePoweredOn) {
        return;
    }

    if (peripheral.state == CBPeripheralManagerStatePoweredOn) {
        self.datasFromIphoneCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:NEW_DATAS_FROM_IPHONE_CHARACTERISTICS_UUID] properties:CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsWriteable];
        self.commandNotifierCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:NEW_COMMANDS_NOTIFIER_CHARACTERISTICS_UUID] properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable];

        CBMutableService *transferService = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:PERIPHERAL_SERVICE_UUID] primary:YES];

        transferService.characteristics = @[self.datasFromIphoneCharacteristic, self.commandNotifierCharacteristic];

        [self.peripheralManager addService:transferService];

        [self.peripheralManager startAdvertising:@{CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:PERIPHERAL_SERVICE_UUID]]}];
    }
}


- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error {

    if (error) {
        NSLog(@"Error advertising: %@", [error localizedDescription]);
    }
}

- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic {
    if (characteristic == self.commandNotifierCharacteristic){
        // on envoie le message au delegate
        if([[self delegate] respondsToSelector:@selector(iPhoneIsConnectedToIpad:)]) {
            [[self delegate] iPhoneIsConnectedToIpad:YES];
        }
    }
}

-(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic{
    if (characteristic == self.commandNotifierCharacteristic){
        // on envoie le message au delegate
        if([[self delegate] respondsToSelector:@selector(iPhoneIsConnectedToIpad:)]) {
            [[self delegate] iPhoneIsConnectedToIpad:NO];
        }
    }
}

EDIT ANSWER :

I found the problem, In the centralManager:didConnectPeripheral: I wasn't calling the right service UUID with [peripheral discoverServices:]. Thank you for your help :).

1
Can you show some of your code?Yazid
I just added some codeDragna
Will have a look. Btw, have you tried power-cycling the devices? This might not solve the disconnects, but sometimes an empty services list could be related to bluetooth caching.Yazid
Can you also post your other CBCentralManager methods (didDiscoverPeripheral, didConnectPeripheral, etc)? Also, for your CBPeripheralManager, it's best practice to only call startAdvertising once your services are confirmed to be setup. You should implement the didAddService delegate method and do it there.Yazid
Add the code from didConnectTommy Devoy

1 Answers

3
votes

I found the problem, In the centralManager:didConnectPeripheral: I wasn't calling the right service UUID with [peripheral discoverServices:]. Thank you for your help :).