BLE iOS将数据发送到Android gattServer外设:writeValue:forCharacteristic:type不起作用

时间:2019-03-24 16:03:21

标签: bluetooth-lowenergy core-bluetooth gatt android-ble bluetooth-gatt

我正在尝试将android用作BLE外围设备(gatt服务器)。我能够获得它的广告,并且当某些特征发生更改时,我可以收到iOS应用程序的重新通知,但是我在执行简单的writeValue时遇到了麻烦。

在iOS上,我有:

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    if (!error) {
        for(int i = 0; i < service.characteristics.count; i++) { //Show every one
            CBCharacteristic *c = [service.characteristics objectAtIndex:i];
            if ([[c.UUID UUIDString] rangeOfString:@"43FF0001"].location!=NSNotFound){
                self.shot_detected_characteristic = c;
                [peripheral setNotifyValue:YES forCharacteristic:self.shot_detected_characteristic];
            }else if ([[c.UUID UUIDString] rangeOfString:@"43FF0002"].location!=NSNotFound){
                self.display_characteristic = c;
                [self writeValue:@"ABC" forCharacteristic:c onPeripheral:peripheral];
            }
            NSLog(@"characteristic uuid: %@", [c.UUID UUIDString]);
        }
    } else {
        NSLog(@"Characteristic discovery unsuccessful");
    }
}
-(IBAction*) sendData {
    CBPeripheral *p = [peripherals lastObject];
    [self writeValue:@"ABC" forCharacteristic:self.display_characteristic onPeripheral:p];
}
-(void) writeValue:(NSString*)value forCharacteristic:(CBCharacteristic*)c onPeripheral:(CBPeripheral *)p {
    NSData *d = [value dataUsingEncoding:NSUTF8StringEncoding];
    if (c.properties & CBCharacteristicPropertyWrite) {
        NSLog(@"Write with response"); //I am getting this message
        [p writeValue:d forCharacteristic:c type:CBCharacteristicWriteWithResponse];
    }else{
        NSLog(@"Unable to write");
    }
}

在Android方面,我有:

private BluetoothManager bluetoothManager;
private BluetoothGattServer gattServer;

private BluetoothGattCharacteristic displayCharacteristic;

private BluetoothDevice connected_device;
private BluetoothLeAdvertiser advertiser;

private void setupBLEService() {
    bluetoothManager = (android.bluetooth.BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE);

    if( ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
    }

    gattServer = bluetoothManager.openGattServer(this, gattServerCallback);

    String uuid_string = "92D9D153-9BE6-43FF-9672-3E2904628B9D";

    BluetoothGattService service = new BluetoothGattService(UUID.fromString(uuid_string), BluetoothGattService.SERVICE_TYPE_PRIMARY);

    shotDetectedCharacteristic = new BluetoothGattCharacteristic(
            UUID.fromString("43FF0001-9BE6-43FF-9672-3E2904628B9D"),
            BluetoothGattCharacteristic.PROPERTY_BROADCAST | BluetoothGattCharacteristic.PROPERTY_NOTIFY | BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE,
            BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);

    BluetoothGattDescriptor gD = new BluetoothGattDescriptor(UUID.fromString(NOTIFICATION_DESCRIPTOR), BluetoothGattDescriptor.PERMISSION_WRITE | BluetoothGattDescriptor.PERMISSION_READ);
    shotDetectedCharacteristic.addDescriptor(gD);
    service.addCharacteristic(shotDetectedCharacteristic);

    displayCharacteristic = new BluetoothGattCharacteristic(
            UUID.fromString("43FF0002-2BE5-46FE-9162-1D2905728B9B"),
            BluetoothGattCharacteristic.PROPERTY_BROADCAST | BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE,
            BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
    service.addCharacteristic(displayCharacteristic);

    gattServer.addService(service);
}

private BluetoothGattServerCallback gattServerCallback = new BluetoothGattServerCallback() {
    @Override
    public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
        super.onConnectionStateChange(device, status, newState);
        if (newState == 2){
            connected_device = device;
            advertiser.stopAdvertising(new AdvertiseCallback() {});
        }
        Log.i("chase", "Connection state changed: "+newState);
    }
    @Override
    public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
        super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
        long millis = System.currentTimeMillis();
        characteristic.setValue( ""+millis );
        Log.i("chase", "reading: "+millis);
        gattServer.sendResponse(device, requestId, 2, offset, characteristic.getValue());
    }
    @Override
    public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
        Log.i("chase", "characteristic write request");
        super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
        characteristic.setValue(value);
        gattServer.sendResponse(device, requestId, 2, offset, characteristic.getValue());
        if (characteristic == displayCharacteristic){
            //TODO: UPDATE DISPLAY
            Log.i("chase", "display write request: "+value.toString());
        }else
            Log.i("chase", "char write request: "+value.toString());
    }
    ...
}

我认为问题出在iOS方面的原因是我下载了nrf Connect应用程序,并且能够使用nrf connect成功写入android特性。或者至少进入BluetoothGattServerCallback#onCharacteristicWriteRequest中的日志语句。 但是,我还编写了与BLE芯片接口的应用程序,而用[p writeValue:d forCharacteristic:c type:CBCharacteristicWriteWithResponse];编写NSData从未遇到任何麻烦。在此先感谢您提供任何有关如何解决此问题的帮助或想法。

更新: 当我说那行不通的时候。我根本没有收到任何错误消息。 [p writeValue:d forCharacteristic:c type:CBCharacteristicWriteWithResponse];被调用,并且android端没有对BluetoothGattServerCallback#onCharacteristicWriteRequest的任何调用,而ios端没有了对-(void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error;的任何回调。

但是,我确实得到了一些有趣的东西。如果我注释掉ios行: //[peripheral setNotifyValue:YES forCharacteristic:self.shot_detected_characteristic]; 然后,我执行呼叫Android的onCharacteristicWriteRequest,并确实回调了didWriteValueForCharacteristic(我收到一条错误消息,该消息无法编写,但我认为我可以解决(至少我得到了一些东西)。 我订阅的是有关其他特征的通知,但是订阅的是同一服务,并且由于某种原因,这使我无法针对其他特征写数据。

0 个答案:

没有答案