在特征上设置通知会导致无效句柄错误



使用CoreBluetooth,我想将数据从iPhone发送到Mac。为此,我编写了类似iPhone为'Peripheral'和Mac为'Central'的代码。

它工作得很好,但有时它直接断开连接,然后不断地连接和断开。

有时当它试图重新连接时,在Central中它直接调用'didDisconnectPeripheral'委托方法。但有时它会在'didUpdateNotificationStateForCharacteristic'中出现错误"句柄无效"。

我参考了网上所有的链接。但是我不能解决这个问题。我以为iPhone是在存储蓝牙缓存

请建议解决"句柄无效"错误的解决方案。

下面是一些重要的方法。

对于外围设备,我编写了如下代码:

在Appdelegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.peripheral = [[PeripheralServerObject alloc] init];
self.peripheral.serviceUUID = [CBUUID UUIDWithString:@"4w24"];
return YES;
}

//To Check Bluetooth State
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
    switch (peripheral.state) {
        case CBPeripheralManagerStatePoweredOn:
            [self enableService];
            break;
        case CBPeripheralManagerStatePoweredOff: {
            [self disableService];
            break;
        }
}
// To Add characteristics to Service
- (void)enableService
{
[self.peripheral removeAllServices];
 self.service = [[CBMutableService alloc]
                    initWithType:self.serviceUUID primary:YES];
self.authChar =
        [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:@"a86e"]
                                           properties:CBCharacteristicPropertyNotify
                                                value:nil
                                          permissions:CBAttributePermissionsReadable];

self.respChar =
        [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:@"a86f"]
                                           properties:CBCharacteristicPropertyWriteWithoutResponse
                                                value:nil
                                          permissions:CBAttributePermissionsWriteable];
self.service.characteristics = @[ self.authChar, self.respChar ];
    // Add the service to the peripheral manager.
    [self.peripheral addService:self.service];
}
//Peripheral Manager delegate method will be called after adding service.
- (void)peripheralManager:(CBPeripheralManager *)peripheral
            didAddService:(CBService *)service
                    error:(NSError *)error {
    [self startAdvertising];
}
//To disable service 
- (void)disableService
{
 [self.peripheral stopAdvertising];
 [self.peripheral removeAllServices];
}
//To enable a service again.
-(void)refreshService {
    [self disableService];
    [self enableService];
}

If central subscribes the characteristic, then the below peripheral delegate method will be called. In this I implemented code to send data
- (void)peripheralManager:(CBPeripheralManager *)peripheral
                  central:(CBCentral *)central
didSubscribeToCharacteristic:(CBCharacteristic *)characteristic {
    self.dataTimer = [NSTimer scheduledTimerWithTimeInterval:10.0
                                                      target:self
                                                    selector:@selector(sendData)
                                                    userInfo:nil
                                                     repeats:YES];
}
- (void)sendData
{
Here I am sending data like [Apple's BTLE Example Code][1]  
}

//If unsubscribed then I am invalidating timer and refreshing service
- (void)peripheralManager:(CBPeripheralManager *)peripheral
                  central:(CBCentral *)central
didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic {
    if (self.dataTimer)
        [self.dataTimer invalidate];
    [self refreshService];
}

对于Mac,我写了一个外围委托方法。

//I enables the notification for "a860" Characteristic.
- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverCharacteristicsForService:(CBService *)service
error:(NSError *)error {
     CBUUID * authUUID = [CBUUID UUIDWithString:@"a86e"];
       for (CBCharacteristic *characteristic in service.characteristics) {
        if ([characteristic.UUID isEqual:authUUID]) {
         }
        [self.connectedPeripheral setNotifyValue:YES
                                   forCharacteristic:characteristic];
         }
}
-(void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
   if (error) {
   Here I am getting error sometimes "The handle is invalid".
    }
}

我最近遇到了同样的问题。我找到的唯一解决方案是重新启动蓝牙(将蓝牙关闭并重新打开)。

在我的情况下,这是蓝牙设备的变化(在DFU模式下重新启动它)总是导致这个问题,所以我最终向用户显示一个警报,以重新启动蓝牙。监听centralManagerDidUpdateState:的Off and then Powered back On状态事件,以确定是否重新启动。

最新更新