由于加密问题,Android蓝牙文件无法写入描述符

时间:2015-10-19 08:50:48

标签: android bluetooth bluetooth-lowenergy

我正在尝试确定使用蓝牙低功耗与支持BLE的设备进行通信的应用程序出了什么问题。令人抓狂的部分是,问题只出现在某些设备上,例如来自Europa的Motorola Moto G3和来自中国的Samsung S5,而它与Europa的三星S5,Europa的HTC One M7和中国的MI W3都能正常工作。

当它不起作用时,一切都在成功写入描述符后停止,因为从不调用相应的onDescritorWrite(...)回调。据推测,它与未能设置加密有关(下面的完整日志):

W/bt-btif (18797): btif_gatt_set_encryption_cb() - Encryption failed (1)

我已经通过了通常的事情,比如确保蓝牙事件被发布到主线程上的处理程序,现在我需要新的想法来尝试解决这个问题...

我的日志捕获命令:

adb logcat | grep 'BLEService\|BluetoothGatt\|BtGatt\|bt\-'

日志输出:

D/BtGatt.GattService(18797): registerClient() - UUID=9a90904a-84e8-4f30-9b10-de78ac49f236
D/BtGatt.GattService(18797): onClientRegistered() - UUID=9a90904a-84e8-4f30-9b10-de78ac49f236, clientIf=5
D/BtGatt.GattService(18797): start scan with filters
D/BtGatt.ScanManager(18797): handling starting scan
D/BtGatt.GattService(18797): onScanFilterEnableDisabled() - clientIf=5, status=0, action=1
D/BtGatt.ScanManager(18797): callback done for clientIf - 5 status - 0
D/BtGatt.GattService(18797): onScanFilterParamsConfigured() - clientIf=5, status=0, action=0, availableSpace=15
D/BtGatt.ScanManager(18797): callback done for clientIf - 5 status - 0
D/BtGatt.ScanManager(18797): configureRegularScanParams() - queue=1
D/BtGatt.ScanManager(18797): configureRegularScanParams() - ScanSetting Scan mode=2 mLastConfiguredScanSetting=-2147483648
E/bt-btm  (18797): Device already in IRK list
D/BtGatt.GattService(18797): stopScan() - queue size =1
D/BtGatt.GattService(18797): onScanFilterParamsConfigured() - clientIf=5, status=0, action=1, availableSpace=16
D/BtGatt.ScanManager(18797): callback done for clientIf - 5 status - 0
D/BtGatt.ScanManager(18797): stop scan
D/BtGatt.ScanManager(18797): configureRegularScanParams() - queue=0
D/BtGatt.ScanManager(18797): configureRegularScanParams() - ScanSetting Scan mode=-2147483648 mLastConfiguredScanSetting=2
D/BtGatt.ScanManager(18797): configureRegularScanParams() - queue emtpy, scan stopped
D/BtGatt.GattService(18797): unregisterClient() - clientIf=5
V/BLEService(21323):  - connecting....
D/BluetoothGatt(21323): connect() - device: F4:B8:5E:51:A2:87, auto: false
D/BluetoothGatt(21323): registerApp()
D/BluetoothGatt(21323): registerApp() - UUID=4b8c32a4-4a74-49ff-a43f-a769c8200ab8
D/BtGatt.GattService(18797): registerClient() - UUID=4b8c32a4-4a74-49ff-a43f-a769c8200ab8
D/BtGatt.GattService(18797): onClientRegistered() - UUID=4b8c32a4-4a74-49ff-a43f-a769c8200ab8, clientIf=5
D/BluetoothGatt(21323): onClientRegistered() - status=0 clientIf=5
D/BtGatt.GattService(18797): clientConnect() - address=F4:B8:5E:51:A2:87, isDirect=true
E/bt-btm  (18797): Device already in IRK list
W/bt-btm  (18797): btm_acl_created hci_handle=4 link_role=0  transport=2
W/bt-btif (18797): info:x0
W/bt-l2cap(18797): L2CA_SetDesireRole() new:x1, disallow_switch:0
D/BtGatt.GattService(18797): client onConnected() - clientIf=5, connId=5, address=F4:B8:5E:51:A2:87
D/BluetoothGatt(21323): onClientConnectionState() - status=0 clientIf=5 device=F4:B8:5E:51:A2:87
V/BLEService(21323): Service have changed with old status: 0 and new status: 2
V/BLEService(21323):  - discovering....
D/BluetoothGatt(21323): discoverServices() - device: F4:B8:5E:51:A2:87
D/BtGatt.GattService(18797): discoverServices() - address=F4:B8:5E:51:A2:87, connId=5
D/BtGatt.GattService(18797): onSearchCompleted() - connId=5, status=0
D/BluetoothGatt(21323): onSearchComplete() = Device=F4:B8:5E:51:A2:87 Status=0
V/BLEService(21323): Service have discovered with status: 0
V/BLEService(21323):  - discovered....
D/BluetoothGatt(21323): setCharacteristicNotification() - uuid: f048abf6-3315-4d59-bad7-7e23ac18ee85 enable: true
D/BtGatt.GattService(18797): registerForNotification() - address=F4:B8:5E:51:A2:87 enable: true
D/BtGatt.GattService(18797): onRegisterForNotifications() - address=null, status=0, registered=1, charUuid=f048abf6-3315-4d59-bad7-7e23ac18ee85
I/BTConnectionReceiver(21037): onReceive(context, Intent { act=android.bluetooth.device.action.ACL_CONNECTED flg=0x4000010 cmp=com.google.android.googlequicksearchbox/com.google.android.search.core.service.BluetoothConnectionReceiver (has extras) }, [BluetoothDevice: address=F4:B8:5E:51:A2:87, alias=null, name=BLEDevice, majorDeviceClass=7936, deviceClass=7936]
I/BluetoothClassifier(21037): Bluetooth Device Name: BLEDevice
W/bt-btif (18797): btif_gatt_set_encryption_cb() - Encryption failed (1)
W/bt-smp  (18797): io_cap = 4
W/bt-smp  (18797): new io_cap = 4 p_cb->loc_enc_size = 16
E/bt-smp  (18797): LTK ready
W/bt-smp  (18797): smp_send_enc_info
W/bt-smp  (18797): smp_send_id_info
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=2 
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=2 
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=16 
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=16 
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=16 
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=2 
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=2 
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=16 
W/bt-btif (18797): bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0008
W/bt-btif (18797): bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0008
W/bt-btif (18797): bta_gattc_conn_cback() - cif=5 connected=0 conn_id=5 reason=0x0008
E/bt-btm  (18797): btm_sec_disconnected - Clearing Pending flag

如果有经验的人可以帮我解决这个问题,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

BLE处理代码的重构揭示了一些处理不当的步骤,这使实际问题蒙上阴影。

正确处理每个步骤允许调用onDescriptorWrite回调,状态为BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION,由日志指示。

当收到状态BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION时,您需要注册绑定事件,以便一旦绑定结束就可以重试:

final IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
context.registerReceiver(receiver, filter);

接收者(BroadcastReceiver的子类)包含这样的内容:

@Override
public void onReceive(Context context, Intent intent) {
    final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
    final int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
    final int previousBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);
    final String action = intent.getAction();

    if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action) && bondState == BluetoothDevice.BOND_BONDED) {
        // retry
    }
}