Loading system/stack/btm/btm_sec.cc +93 −51 Original line number Original line Diff line number Diff line Loading @@ -1045,42 +1045,71 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, p_ref_data, sec_act); p_ref_data, sec_act); } } tBTM_STATUS rc = BTM_SUCCESS; tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); if (!p_dev_rec || if (p_dev_rec == nullptr) { (transport == BT_TRANSPORT_BR_EDR && LOG_ERROR("Unable to set encryption for unknown device"); p_dev_rec->hci_handle == HCI_INVALID_HANDLE) || return BTM_WRONG_MODE; (transport == BT_TRANSPORT_LE && } p_dev_rec->ble_hci_handle == HCI_INVALID_HANDLE)) { /* Connection should be up and runnning */ BTM_TRACE_WARNING("Security Manager: BTM_SetEncryption not connected"); switch (transport) { case BT_TRANSPORT_BR_EDR: if (p_dev_rec->hci_handle == HCI_INVALID_HANDLE) { LOG_WARN( "Security Manager: BTM_SetEncryption not connected peer:%s " "transport:%s", PRIVATE_ADDRESS(bd_addr), bt_transport_text(transport).c_str()); if (p_callback) if (p_callback) (*p_callback)(&bd_addr, transport, p_ref_data, BTM_WRONG_MODE); (*p_callback)(&bd_addr, transport, p_ref_data, BTM_WRONG_MODE); return BTM_WRONG_MODE; return (BTM_WRONG_MODE); } if (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED) { LOG_DEBUG( "Security Manager: BTM_SetEncryption already encrypted peer:%s " "transport:%s", PRIVATE_ADDRESS(bd_addr), bt_transport_text(transport).c_str()); if (*p_callback) (*p_callback)(&bd_addr, transport, p_ref_data, BTM_SUCCESS); return BTM_SUCCESS; } } break; if (transport == BT_TRANSPORT_BR_EDR && case BT_TRANSPORT_LE: (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)) { if (p_dev_rec->ble_hci_handle == HCI_INVALID_HANDLE) { BTM_TRACE_EVENT("Security Manager: BTM_SetEncryption already encrypted"); LOG_WARN( "Security Manager: BTM_SetEncryption not connected peer:%s " "transport:%s", PRIVATE_ADDRESS(bd_addr), bt_transport_text(transport).c_str()); if (p_callback) (*p_callback)(&bd_addr, transport, p_ref_data, BTM_WRONG_MODE); return BTM_WRONG_MODE; } if (p_dev_rec->sec_flags & BTM_SEC_LE_ENCRYPTED) { LOG_DEBUG( "Security Manager: BTM_SetEncryption already encrypted peer:%s " "transport:%s", PRIVATE_ADDRESS(bd_addr), bt_transport_text(transport).c_str()); if (*p_callback) if (*p_callback) (*p_callback)(&bd_addr, transport, p_ref_data, BTM_SUCCESS); (*p_callback)(&bd_addr, transport, p_ref_data, BTM_SUCCESS); return (BTM_SUCCESS); return BTM_SUCCESS; } break; default: LOG_ERROR("Unknown transport"); break; } } /* enqueue security request if security is active */ /* enqueue security request if security is active */ if (p_dev_rec->p_callback || (p_dev_rec->sec_state != BTM_SEC_STATE_IDLE)) { if (p_dev_rec->p_callback || (p_dev_rec->sec_state != BTM_SEC_STATE_IDLE)) { BTM_TRACE_WARNING( LOG_WARN("Security Manager: BTM_SetEncryption busy, enqueue request"); "Security Manager: BTM_SetEncryption busy, enqueue request"); if (btm_sec_queue_encrypt_request(bd_addr, transport, p_callback, if (btm_sec_queue_encrypt_request(bd_addr, transport, p_callback, p_ref_data, sec_act)) { p_ref_data, sec_act)) { LOG_INFO("Queued start encryption"); return BTM_CMD_STARTED; return BTM_CMD_STARTED; } else { } else { LOG_WARN("Unable to enqueue start encryption request"); if (p_callback) if (p_callback) (*p_callback)(&bd_addr, transport, p_ref_data, BTM_NO_RESOURCES); (*p_callback)(&bd_addr, transport, p_ref_data, BTM_NO_RESOURCES); return BTM_NO_RESOURCES; return BTM_NO_RESOURCES; Loading @@ -1093,38 +1122,51 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT); (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT); p_dev_rec->is_originator = false; p_dev_rec->is_originator = false; BTM_TRACE_API( LOG_DEBUG( "Security Manager: BTM_SetEncryption Handle:%d State:%d Flags:0x%x " "Security Manager: BTM_SetEncryption classic_handle:0x%04x " "Required:0x%x, p_dev_rec=%p, p_callback=%p", "ble_handle:0x%04x state:%d flags:0x%x " p_dev_rec->hci_handle, p_dev_rec->sec_state, p_dev_rec->sec_flags, "required:0x%x p_callback=%c", p_dev_rec->security_required, p_dev_rec, p_callback); p_dev_rec->hci_handle, p_dev_rec->ble_hci_handle, p_dev_rec->sec_state, p_dev_rec->sec_flags, p_dev_rec->security_required, (p_callback) ? 'T' : 'F'); if (transport == BT_TRANSPORT_LE) { tBTM_STATUS rc = BTM_SUCCESS; switch (transport) { case BT_TRANSPORT_LE: if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE)) { if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE)) { rc = btm_ble_set_encryption(bd_addr, sec_act, rc = btm_ble_set_encryption(bd_addr, sec_act, L2CA_GetBleConnRole(bd_addr)); L2CA_GetBleConnRole(bd_addr)); } else { } else { rc = BTM_WRONG_MODE; rc = BTM_WRONG_MODE; BTM_TRACE_WARNING("%s: cannot call btm_ble_set_encryption, p is NULL", LOG_WARN("cannot call btm_ble_set_encryption, p is NULL"); __func__); } } } else { break; case BT_TRANSPORT_BR_EDR: rc = btm_sec_execute_procedure(p_dev_rec); rc = btm_sec_execute_procedure(p_dev_rec); break; default: LOG_ERROR("Unknown transport"); break; } } if (rc != BTM_CMD_STARTED && rc != BTM_BUSY) { switch (rc) { case BTM_CMD_STARTED: case BTM_BUSY: break; default: if (p_callback) { if (p_callback) { BTM_TRACE_DEBUG( LOG_DEBUG("Executing encryption callback peer:%s transport:%s", "%s: clearing p_callback=%p, p_dev_rec=%p, transport=%d, " PRIVATE_ADDRESS(bd_addr), "bd_addr=%s", bt_transport_text(transport).c_str()); __func__, p_callback, p_dev_rec, transport, p_dev_rec->p_callback = nullptr; bd_addr.ToString().c_str()); p_dev_rec->p_callback = NULL; (*p_callback)(&bd_addr, transport, p_dev_rec->p_ref_data, rc); (*p_callback)(&bd_addr, transport, p_dev_rec->p_ref_data, rc); } } break; } } return rc; return (rc); } } bool BTM_SecIsSecurityPending(const RawAddress& bd_addr) { bool BTM_SecIsSecurityPending(const RawAddress& bd_addr) { Loading system/stack/test/btm/stack_btm_test.cc +22 −0 Original line number Original line Diff line number Diff line Loading @@ -334,3 +334,25 @@ TEST_F(StackBtmWithInitFreeTest, btm_sec_encrypt_change) { wipe_secrets_and_remove(device_record); wipe_secrets_and_remove(device_record); } } TEST_F(StackBtmWithInitFreeTest, BTM_SetEncryption) { const RawAddress bd_addr = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); const tBT_TRANSPORT transport{BT_TRANSPORT_LE}; tBTM_SEC_CALLBACK* p_callback{nullptr}; tBTM_BLE_SEC_ACT sec_act{BTM_BLE_SEC_ENCRYPT}; // No device ASSERT_EQ(BTM_WRONG_MODE, BTM_SetEncryption(bd_addr, transport, p_callback, nullptr, sec_act)); // With device tBTM_SEC_DEV_REC* device_record = btm_sec_allocate_dev_rec(); ASSERT_NE(nullptr, device_record); device_record->bd_addr = bd_addr; device_record->hci_handle = 0x1234; ASSERT_EQ(BTM_WRONG_MODE, BTM_SetEncryption(bd_addr, transport, p_callback, nullptr, sec_act)); wipe_secrets_and_remove(device_record); } Loading
system/stack/btm/btm_sec.cc +93 −51 Original line number Original line Diff line number Diff line Loading @@ -1045,42 +1045,71 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, p_ref_data, sec_act); p_ref_data, sec_act); } } tBTM_STATUS rc = BTM_SUCCESS; tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); if (!p_dev_rec || if (p_dev_rec == nullptr) { (transport == BT_TRANSPORT_BR_EDR && LOG_ERROR("Unable to set encryption for unknown device"); p_dev_rec->hci_handle == HCI_INVALID_HANDLE) || return BTM_WRONG_MODE; (transport == BT_TRANSPORT_LE && } p_dev_rec->ble_hci_handle == HCI_INVALID_HANDLE)) { /* Connection should be up and runnning */ BTM_TRACE_WARNING("Security Manager: BTM_SetEncryption not connected"); switch (transport) { case BT_TRANSPORT_BR_EDR: if (p_dev_rec->hci_handle == HCI_INVALID_HANDLE) { LOG_WARN( "Security Manager: BTM_SetEncryption not connected peer:%s " "transport:%s", PRIVATE_ADDRESS(bd_addr), bt_transport_text(transport).c_str()); if (p_callback) if (p_callback) (*p_callback)(&bd_addr, transport, p_ref_data, BTM_WRONG_MODE); (*p_callback)(&bd_addr, transport, p_ref_data, BTM_WRONG_MODE); return BTM_WRONG_MODE; return (BTM_WRONG_MODE); } if (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED) { LOG_DEBUG( "Security Manager: BTM_SetEncryption already encrypted peer:%s " "transport:%s", PRIVATE_ADDRESS(bd_addr), bt_transport_text(transport).c_str()); if (*p_callback) (*p_callback)(&bd_addr, transport, p_ref_data, BTM_SUCCESS); return BTM_SUCCESS; } } break; if (transport == BT_TRANSPORT_BR_EDR && case BT_TRANSPORT_LE: (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)) { if (p_dev_rec->ble_hci_handle == HCI_INVALID_HANDLE) { BTM_TRACE_EVENT("Security Manager: BTM_SetEncryption already encrypted"); LOG_WARN( "Security Manager: BTM_SetEncryption not connected peer:%s " "transport:%s", PRIVATE_ADDRESS(bd_addr), bt_transport_text(transport).c_str()); if (p_callback) (*p_callback)(&bd_addr, transport, p_ref_data, BTM_WRONG_MODE); return BTM_WRONG_MODE; } if (p_dev_rec->sec_flags & BTM_SEC_LE_ENCRYPTED) { LOG_DEBUG( "Security Manager: BTM_SetEncryption already encrypted peer:%s " "transport:%s", PRIVATE_ADDRESS(bd_addr), bt_transport_text(transport).c_str()); if (*p_callback) if (*p_callback) (*p_callback)(&bd_addr, transport, p_ref_data, BTM_SUCCESS); (*p_callback)(&bd_addr, transport, p_ref_data, BTM_SUCCESS); return (BTM_SUCCESS); return BTM_SUCCESS; } break; default: LOG_ERROR("Unknown transport"); break; } } /* enqueue security request if security is active */ /* enqueue security request if security is active */ if (p_dev_rec->p_callback || (p_dev_rec->sec_state != BTM_SEC_STATE_IDLE)) { if (p_dev_rec->p_callback || (p_dev_rec->sec_state != BTM_SEC_STATE_IDLE)) { BTM_TRACE_WARNING( LOG_WARN("Security Manager: BTM_SetEncryption busy, enqueue request"); "Security Manager: BTM_SetEncryption busy, enqueue request"); if (btm_sec_queue_encrypt_request(bd_addr, transport, p_callback, if (btm_sec_queue_encrypt_request(bd_addr, transport, p_callback, p_ref_data, sec_act)) { p_ref_data, sec_act)) { LOG_INFO("Queued start encryption"); return BTM_CMD_STARTED; return BTM_CMD_STARTED; } else { } else { LOG_WARN("Unable to enqueue start encryption request"); if (p_callback) if (p_callback) (*p_callback)(&bd_addr, transport, p_ref_data, BTM_NO_RESOURCES); (*p_callback)(&bd_addr, transport, p_ref_data, BTM_NO_RESOURCES); return BTM_NO_RESOURCES; return BTM_NO_RESOURCES; Loading @@ -1093,38 +1122,51 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT); (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT); p_dev_rec->is_originator = false; p_dev_rec->is_originator = false; BTM_TRACE_API( LOG_DEBUG( "Security Manager: BTM_SetEncryption Handle:%d State:%d Flags:0x%x " "Security Manager: BTM_SetEncryption classic_handle:0x%04x " "Required:0x%x, p_dev_rec=%p, p_callback=%p", "ble_handle:0x%04x state:%d flags:0x%x " p_dev_rec->hci_handle, p_dev_rec->sec_state, p_dev_rec->sec_flags, "required:0x%x p_callback=%c", p_dev_rec->security_required, p_dev_rec, p_callback); p_dev_rec->hci_handle, p_dev_rec->ble_hci_handle, p_dev_rec->sec_state, p_dev_rec->sec_flags, p_dev_rec->security_required, (p_callback) ? 'T' : 'F'); if (transport == BT_TRANSPORT_LE) { tBTM_STATUS rc = BTM_SUCCESS; switch (transport) { case BT_TRANSPORT_LE: if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE)) { if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE)) { rc = btm_ble_set_encryption(bd_addr, sec_act, rc = btm_ble_set_encryption(bd_addr, sec_act, L2CA_GetBleConnRole(bd_addr)); L2CA_GetBleConnRole(bd_addr)); } else { } else { rc = BTM_WRONG_MODE; rc = BTM_WRONG_MODE; BTM_TRACE_WARNING("%s: cannot call btm_ble_set_encryption, p is NULL", LOG_WARN("cannot call btm_ble_set_encryption, p is NULL"); __func__); } } } else { break; case BT_TRANSPORT_BR_EDR: rc = btm_sec_execute_procedure(p_dev_rec); rc = btm_sec_execute_procedure(p_dev_rec); break; default: LOG_ERROR("Unknown transport"); break; } } if (rc != BTM_CMD_STARTED && rc != BTM_BUSY) { switch (rc) { case BTM_CMD_STARTED: case BTM_BUSY: break; default: if (p_callback) { if (p_callback) { BTM_TRACE_DEBUG( LOG_DEBUG("Executing encryption callback peer:%s transport:%s", "%s: clearing p_callback=%p, p_dev_rec=%p, transport=%d, " PRIVATE_ADDRESS(bd_addr), "bd_addr=%s", bt_transport_text(transport).c_str()); __func__, p_callback, p_dev_rec, transport, p_dev_rec->p_callback = nullptr; bd_addr.ToString().c_str()); p_dev_rec->p_callback = NULL; (*p_callback)(&bd_addr, transport, p_dev_rec->p_ref_data, rc); (*p_callback)(&bd_addr, transport, p_dev_rec->p_ref_data, rc); } } break; } } return rc; return (rc); } } bool BTM_SecIsSecurityPending(const RawAddress& bd_addr) { bool BTM_SecIsSecurityPending(const RawAddress& bd_addr) { Loading
system/stack/test/btm/stack_btm_test.cc +22 −0 Original line number Original line Diff line number Diff line Loading @@ -334,3 +334,25 @@ TEST_F(StackBtmWithInitFreeTest, btm_sec_encrypt_change) { wipe_secrets_and_remove(device_record); wipe_secrets_and_remove(device_record); } } TEST_F(StackBtmWithInitFreeTest, BTM_SetEncryption) { const RawAddress bd_addr = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); const tBT_TRANSPORT transport{BT_TRANSPORT_LE}; tBTM_SEC_CALLBACK* p_callback{nullptr}; tBTM_BLE_SEC_ACT sec_act{BTM_BLE_SEC_ENCRYPT}; // No device ASSERT_EQ(BTM_WRONG_MODE, BTM_SetEncryption(bd_addr, transport, p_callback, nullptr, sec_act)); // With device tBTM_SEC_DEV_REC* device_record = btm_sec_allocate_dev_rec(); ASSERT_NE(nullptr, device_record); device_record->bd_addr = bd_addr; device_record->hci_handle = 0x1234; ASSERT_EQ(BTM_WRONG_MODE, BTM_SetEncryption(bd_addr, transport, p_callback, nullptr, sec_act)); wipe_secrets_and_remove(device_record); }