Получение неизвестной ошибки при записи данных на BLE в iOS

Я пытаюсь разработать приложение iOS, которое обнаруживает устройство BLE и должно вызвать команду записи . Я могу успешно подключиться к устройству BLE и обнаружить его сервис и характеристики. Но я получаю неизвестную ошибку во время записи данных на подключенном периферийном устройстве. Ниже приведен код, который я написал:

Disovered Характеристика:

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
  NSArray     *characteristics    = [service characteristics];

  if (peripheral != self.peripheral) {
    NSLog(@"Wrong Peripheral.n");
    return ;
  }

 if (error != nil) {
    NSLog(@"Error %@n", error);
    return ;
  }

  for (CBCharacteristic *characteristic in characteristics) {

if ([[characteristic UUID] isEqual:RWT_POSITION_CHAR_UUID]) {
  self.positionCharacteristic = characteristic;
   }
 }
}

вот функция для записи данных на устройстве BLE

- (void)writeCommand{

// See if characteristic has been discovered before writing to it
if (!self.positionCharacteristic) {
    return;
}
NSString *cmd1=@"CQ+WHORUr";

 NSData *dataToWrite = [cmd1 dataUsingEncoding:NSUTF8StringEncoding];

CBCharacteristic *chr = self.positionCharacteristic;
NSLog(@"%@,%lu...%@",chr.UUID,chr.properties,chr);



NSInteger dataSize = [[NSByteCountFormatter stringFromByteCount:dataToWrite.length countStyle:NSByteCountFormatterCountStyleFile] integerValue];
if (dataSize > 130) {
    NSLog(@"Cannot send more than 130 bytes");
}
else
{
    [self.peripheral writeValue:dataToWrite forCharacteristic:self.positionCharacteristic type:CBCharacteristicWriteWithResponse];

    }

}

- (void)peripheral:(CBPeripheral *)peripheral
didWriteValueForCharacteristic:(CBCharacteristic *)characteristic
         error:(NSError *)error
{
    if (error)
    {
        NSLog(@"Error writing characteristic value: %@",[error      localizedDescription]);
    }
    else
    {
        NSLog(@"Successfuly writing characteristic value");
    }
}

In "didwritevalueforcharacteristic" метод делегата я получаю ниже ошибки:

ошибка записи характеристическое значение: неизвестная ошибка.

может кто-нибудь помочь мне с этим? что может быть причиной этой ошибки?

также, если я пытаюсь определить характеристику для отправки данных на устройстве BLE, например:

 CBMutableCharacteristic *writeChar=[[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:@"ffe1"] properties:CBCharacteristicPropertyWriteWithoutResponse|CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsWriteable|CBAttributePermissionsReadable];
int8_t cmd=*[cmd1 UTF8String];

NSData *data = [NSData dataWithBytes:&cmd length:sizeof(cmd)];

NSInteger dataSize = [[NSByteCountFormatter stringFromByteCount:dataToWrite.length countStyle:NSByteCountFormatterCountStyleFile] integerValue];
if (dataSize > 130) {
    NSLog(@"Cannot send more than 130 bytes");
}
else
{
    [self.peripheral writeValue:dataToWrite forCharacteristic:writeChar type:CBCharacteristicWriteWithResponse];
    //        [self.peripheral writeValue:dataToWrite forCharacteristic:writeChar type:CBCharacteristicWriteWithResponse];
}

затем я получаю эту ошибку:

**CoreBluetooth[WARNING] CBMutableCharacteristic: 0x1552a270 UUID = Unknown (<ffe1>),Value = (null), Properties = 0x14, Permissions = 0x3, Descriptors = (null), SubscribedCentrals = (
)> is not a valid characteristic for peripheral <CBPeripheral: 0x15549930 identifier = FC71890D-9F71-5E16-086D-D491E1EF7599, Name = " DEMOBLE1", state = connected**

3 ответов


когда вы пишете данные, которые вы запрашиваете ответ (CBCharacteristicWriteWithResponse).

запись завершится неудачей, если характеристика, которую вы пишете, не имеет свойства CBCharacteristicPropertyWrite set, но поддерживает только запись без ответа (CBCharacteristicPropertyWriteWithoutResponse).

if ((self.positionCharacteristic.properties & CBCharacteristicPropertyWrite) == CBCharacteristicPropertyWrite) {
    // Responses are available, so write with response.
    [self.peripheral writeValue:dataToWrite forCharacteristic:self.positionCharacteristic type:CBCharacteristicWriteWithResponse];
}
else if ((self.positionCharacteristic.properties & CBCharacteristicPropertyWriteWithoutResponse) == CBCharacteristicPropertyWriteWithoutResponse) {
    // Responses are not available.
    // Write with response is going to fail, so write without response.
    [self.peripheral writeValue:dataToWrite forCharacteristic:self.positionCharacteristic type:CBCharacteristicWriteWithoutResponse];
}

Я видел эту ошибку при разработке приложения iOS (Как Центрального) и прошивки устройства BLE (как периферийного). Это произойдет, когда я изменю/изменю характеристики на периферии BLE.

iOS, похоже, кэширует информацию об услугах и характеристиках после подключения. Я смог решить эту проблему, обновив адрес Bluetooth периферийного устройства всякий раз, когда я буду создавать/загружать новую прошивку на устройство.


прежде всего, вы используете CBCentralManager, да?

убедитесь, что вы делаете это правильным образом:

  1. использовать CBCentralManager

    self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    
  2. определить, когда периферийное подключен

    - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
    {
    
        if (connectedDevice) // make sure you disconnect previous device
            [self.centralManager cancelPeripheralConnection:connectedDevice];
    
        connectedDevice = [peripheral retain];
        connectedDevice.delegate = self;
        [connectedDevice discoverServices:nil]; // this will discover all kind of services
    }
    
  3. если что-то было не так во время подключения, вы найдете здесь (например, низкий заряд батареи)

    - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
        NSLog(@"Did fail to connect: %@",error.description);
        connectedDevice = nil;
    }
    
  4. что-то пошло не так с успешно подключенным BLE (например, низкий заряд батареи, пользователь выключил устройство)

    - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
        NSLog(@"Disconnected: %@",error.description);
        connectedDevice = nil;
    }
    
  5. здесь вы можете найти доступные услуги

    - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
        NSLog([NSString stringWithFormat:@"%@",[advertisementData description]]);
    }
    

6.

    - (void)centralManagerDidUpdateState:(CBCentralManager *)central{
        NSString *messtoshow;

        switch (central.state) {
            case CBCentralManagerStatePoweredOn:
            {
                [NSString stringWithFormat:@"Bluetooth is currently powered on and available to use."];

                CBUUID *heartRate = [CBUUID UUIDWithString:HRM_SERVICE_UUID];
                CBUUID *batteryLevel = [CBUUID UUIDWithString:BATTERY_LIFE_SERVICE_UUID];

                NSDictionary *scanOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];

                [self.centralManager scanForPeripheralsWithServices:[NSArray arrayWithObjects:heartRate,batteryLevel,nil] options:scanOptions];
                break;
            }

        }
    }
  1. теперь вы можете реализовать CBPeripheralDelegate методы

    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
    {
        for (CBService *service in peripheral.services) {
            NSLog(@"Discovered service: %@", service.UUID);
            [peripheral discoverCharacteristics:nil forService:service];
        }
    }
    
    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
    {
        if ([service.UUID isEqual:[CBUUID UUIDWithString:HRM_SERVICE_UUID]])  {
            for (CBCharacteristic *aChar in service.characteristics)
            {
                if ([aChar.UUID isEqual:[CBUUID UUIDWithString:HRM_MEASUREMENT_CHARACTERISTIC_UUID]]) {
                    [connectedDevice setNotifyValue:YES forCharacteristic:aChar];
                }
            }
        }
    
        if ([service.UUID isEqual:[CBUUID UUIDWithString:BATTERY_LIFE_SERVICE_UUID]])  {
            for (CBCharacteristic *aChar in service.characteristics)
            {
                if ([aChar.UUID isEqual:[CBUUID UUIDWithString:BATTERY_LEVEL_CHARACTERISTIC_UUID]]) {
                    [connectedDevice readValueForCharacteristic:aChar];
                }
            }
        }
    }
    
    - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
    {
        NSError* err = nil;
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:HRM_MEASUREMENT_CHARACTERISTIC_UUID]]) {
                NSData *data = [characteristic value];
        }
    
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:BATTERY_LEVEL_CHARACTERISTIC_UUID]]) { 
    
        }
    }
    

это должно работать нормально. Я реализовал это таким же образом, и нет никаких проблем. Надеюсь, это поможет.