简体   繁体   English

如何以编程方式处理BLE外设从iOS设备中删除配对

[英]How to Programmatically Handle BLE Peripheral Removing Pairing from iOS Device

With an iOS app running in Central mode, and a BLE peripheral (eg the BLE113) with encrypted GATT characteristics - when the iOS app scans for and connects to the peripheral, it will automatically request a pairing when it discovers encrypted GATT characteristics. iOS应用程序以中央模式运行,BLE外围设备(例如BLE113)具有加密的GATT特性 - 当iOS应用程序扫描并连接到外围设备时,它会在发现加密的GATT特征时自动请求配对。

If the iOS device and BLE peripheral each stay paired, everything is fine. 如果iOS设备和BLE外围设备都保持配对,一切都很好。

However, how does one handle the case where the BLE peripheral removes all of it's bonding information internally, without informing the iOS device that it's deleting the pairing keys? 但是,如何处理BLE外设在内部删除所有绑定信息的情况,而不通知iOS设备它正在删除配对键?

iOS CoreBluetooth commands will just fail. iOS CoreBluetooth命令将失败。

Is there anything that can be done programmatically to fix this problem? 有什么可以通过编程方式来解决这个问题吗? Either re-request a pairing, or unpair the iOS side? 要么重新请求配对,要么取消配对iOS端?

iOS is pretty restricted with Bluetooth - so I can't see much of a good solution, other than to detect when writes fail, and ask the user to unpair manually (which is lame) iOS受蓝牙限制很多 - 所以我看不到很多好的解决方案,除了检测写入失败时,还要求用户手动取消配对(这是蹩脚的)

I was finally able to solve this one, and it turns out, you don't even need to unpair!!! 我终于能够解决这个了,事实证明,你甚至不需要取消配对!

I wrote about my experiences here: 我在这里写了我的经历:

http://www.sureshjoshi.com/embedded/bgscript-pairing-hell/ and here: http://community.silabs.com/t5/Wireless/Bonding-issues-with-BLE121/mp/163221#M10850 http://www.sureshjoshi.com/embedded/bgscript-pairing-hell/和这里: http//community.silabs.com/t5/Wireless/Bonding-issues-with-BLE121/mp/163221#M10850

Essentially, from the firmware side, you can re-request an encryption when the device discovers that the pairing doesn't occur immediately. 实质上,从固件方面,当设备发现配对不会立即发生时,您可以重新请求加密。 For BGScript, here is the pertinent code: 对于BGScript,这是相关的代码:

event sm_bonding_fail(handle, result) 
# If bonding fails, handle it gracefully based on the following possible results:
# - 0x018B - Out of bonds (no space left, all 8 bonding slots taken)
# - 0x0205 - Authentication failure (shouldn't happen with "just works" mode, but might otherwise)
# - 0x0206 - Pin or key missing (probably local or remote device is missing the key, but not both)
# - 0x0301 - Passkey entry failed (also shouldn't happen in "just works" mode unless bonding is cancelled)
# - 0x0302 - OOB data not available (only occurs if OOB is required and not supported on both ends)
# - 0x0303 - Authentication requirements (I/O capabilities required but not supported)
# - 0x0304 - Confirm value failed (PIN entry/comparison attempted but failed)
# - 0x0305 - Pairing not supported (also occurs if bond info removed from remote device but not local module)
# - 0x0306 - Encryption key size (key size insufficient to meet security requirements)
# - 0x0307 - Command not supported (SMP command is not supported on this device)
# - 0x0308 - Unspecified reason (may occur if bond info is present remotely but not locally)
# - 0x0309 - Repeated attempts (too little time has elapsed since last pairing/security request)
# - 0x030A - Invalid parameters (bad parameters sent during pairing/bonding process)

# NOTE: The most common cases:
# - 0x018B, which means you ran out of space and must remove at least one bond in order to bond again
# - 0x0206, which typically means the pairing info was removed on the remote device but not locally
# - 0x0301, which typically means the user cancelled the pairing request or entered the wrong passkey
# - 0x0305, which is like 0x0206 but is often generated instead if the remote device is a smartphone
# - 0x0308, which typically means the pairing info was removed on the local device but not remotely
if result = $018b then
    # Only solved by removing bonds - requires the user to reset the bonds...
end if

if result = $0301 then
    # Usually solved simply by trying again
    # Seems to solve most problems on iOS
    # On Android, pairing rejected a few times if Android deleted pairing without informing device
    call sm_encrypt_start(0, 1)
end if

if result = $0305 || result = $0206 then
    # Remove local bonding info first, then the remote device needs to reconnect
    # If current_bond_handle is $ff, that means we don't have a bonding handle - so not much we can do
    if current_bond_handle != $ff then
        call sm_delete_bonding(current_bond_handle)
    end if

    # Sometimes takes a few tries
    call connection_disconnect(0)
end if

if result = $0308 then
    # Remove remote bonding info first, then the remote device needs to reconnect
    # Android can recover automatically, iOS cannot
    # Instead of disconnecting, just force a re-encryption... Usually works
    call sm_encrypt_start(0, 1)
end if
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM