hci: return command disallowed in gap_connect() without emitting connection complete

This commit is contained in:
Matthias Ringwald 2023-11-22 15:12:58 +01:00
parent 92f8d6b610
commit 9cb529638d
2 changed files with 26 additions and 36 deletions

View File

@ -45,6 +45,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- -
### Changed ### Changed
- HCI: simplified implicit SCO flow control - HCI: simplified implicit SCO flow control
- HCI: return ERROR_CODE_COMMAND_DISALLOWED for outgoing connections in gap_connect
- AVRCP: shorten default SDP Service and Provider Names - AVRCP: shorten default SDP Service and Provider Names
- GATT Client: emit query complete event for gatt_client_discover_characteristic_descriptors in next run loop iteration - GATT Client: emit query complete event for gatt_client_discover_characteristic_descriptors in next run loop iteration
- HFP: report HFP Version 1.9 in SDP record - HFP: report HFP Version 1.9 in SDP record

View File

@ -8244,51 +8244,40 @@ void gap_set_scan_phys(uint8_t phys){
hci_stack->le_scan_phys = phys & 0x05; hci_stack->le_scan_phys = phys & 0x05;
} }
uint8_t gap_connect(const bd_addr_t addr, bd_addr_type_t addr_type){ uint8_t gap_connect(const bd_addr_t addr, bd_addr_type_t addr_type) {
// disallow le connection if outgoing already active
if (hci_is_le_connection_type(addr_type) && hci_stack->le_connecting_request != LE_CONNECTING_IDLE){
log_error("le connect already active");
return ERROR_CODE_COMMAND_DISALLOWED;
}
hci_connection_t * conn = hci_connection_for_bd_addr_and_type(addr, addr_type); hci_connection_t * conn = hci_connection_for_bd_addr_and_type(addr, addr_type);
if (!conn){ if (conn == NULL) {
// disallow if le connection is already outgoing
if (hci_is_le_connection_type(addr_type) && hci_stack->le_connecting_request != LE_CONNECTING_IDLE){
log_error("le connection already active");
return ERROR_CODE_COMMAND_DISALLOWED;
}
log_info("gap_connect: no connection exists yet, creating context");
conn = create_connection_for_bd_addr_and_type(addr, addr_type, HCI_ROLE_MASTER); conn = create_connection_for_bd_addr_and_type(addr, addr_type, HCI_ROLE_MASTER);
if (!conn){ if (conn == false){
// alloc failed
log_info("gap_connect: failed to alloc hci_connection_t"); log_info("gap_connect: failed to alloc hci_connection_t");
return BTSTACK_MEMORY_ALLOC_FAILED; // don't sent packet to controller return BTSTACK_MEMORY_ALLOC_FAILED;
} }
} else {
// set le connecting state switch (conn->state) {
if (hci_is_le_connection_type(addr_type)){ case RECEIVED_DISCONNECTION_COMPLETE:
hci_stack->le_connecting_request = LE_CONNECTING_DIRECT; // connection was just disconnected, reset state and allow re-connect
conn->role = HCI_ROLE_MASTER;
break;
default:
return ERROR_CODE_COMMAND_DISALLOWED;
} }
conn->state = SEND_CREATE_CONNECTION;
log_info("gap_connect: send create connection next");
hci_run();
return ERROR_CODE_SUCCESS;
} }
if (!hci_is_le_connection(conn) || // set le connecting state
(conn->state == SEND_CREATE_CONNECTION) || if (hci_is_le_connection_type(addr_type)){
(conn->state == SENT_CREATE_CONNECTION)) { hci_stack->le_connecting_request = LE_CONNECTING_DIRECT;
hci_emit_le_connection_complete(conn->address_type, conn->address, 0, ERROR_CODE_COMMAND_DISALLOWED);
log_error("gap_connect: classic connection or connect is already being created");
return GATT_CLIENT_IN_WRONG_STATE;
} }
// check if connection was just disconnected // trigger connect
if (conn->state == RECEIVED_DISCONNECTION_COMPLETE){ log_info("gap_connect: send create connection next");
log_info("gap_connect: send create connection (again)"); conn->state = SEND_CREATE_CONNECTION;
conn->state = SEND_CREATE_CONNECTION;
hci_run();
return ERROR_CODE_SUCCESS;
}
log_info("gap_connect: context exists with state %u", conn->state);
hci_emit_le_connection_complete(conn->address_type, conn->address, conn->con_handle, ERROR_CODE_SUCCESS);
hci_run(); hci_run();
return ERROR_CODE_SUCCESS; return ERROR_CODE_SUCCESS;
} }