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

128
9

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

Обнаруженная характеристика:

- (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+WHORU\r";

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(@"Successfully writing characteristic value");
}
}

В методе делегата 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**

спросил(а) 2015-02-18T09:56:00+03:00 5 лет, 5 месяцев назад
1
Решение
124

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


Запись не удастся, если у характеристики, которую вы пишете, не установлено свойство CBCharacteristicPropertyWrite, но поддерживает только записи без ответа (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];
}

ответил(а) 2015-02-19T12:05:00+03:00 5 лет, 5 месяцев назад
57

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

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

ответил(а) 2015-02-18T10:38:00+03:00 5 лет, 5 месяцев назад
40

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


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


    Используйте CBCentralManager


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

    Обнаружение, когда подключено периферийное устройство


    - (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
    }


    Если что-то не так во время соединения, вы найдете здесь (например, батарея с низким уровнем заряда)


    - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
    NSLog(@"Did fail to connect: %@",error.description);
    connectedDevice = nil;
    }

    Что-то пошло не так с успешно подключенным BLE (например, батарея разряжена, пользователь выключил устройство)


    - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
    NSLog(@"Disconnected: %@",error.description);
    connectedDevice = nil;
    }

    Здесь вы можете найти доступные службы


    - (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;
}

}
}


С этого момента вы можете реализовать методы 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]]) {

}
}


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

ответил(а) 2015-02-18T11:19:00+03:00 5 лет, 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема