diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index e97888b2b..d3cfb4019 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -2413,7 +2413,13 @@ ble_gap_conn_create_tx(uint8_t own_addr_type, * @param cb_arg The optional argument to pass to the callback * function. * - * @return 0 on success; nonzero on failure. + * @return 0 on success; + * BLE_HS_EALREADY if a connection attempt is + * already in progress; + * BLE_HS_EBUSY if initiating a connection is not + * possible because scanning is in progress; + * BLE_HS_EDONE if the specified peer is already connected; + * Other nonzero on error. */ int ble_gap_connect(uint8_t own_addr_type, @@ -2475,6 +2481,12 @@ ble_gap_connect(uint8_t own_addr_type, } } + /* Verify peer not already connected. */ + if (ble_hs_conn_find_by_addr(peer_addr_type, peer_addr) != NULL) { + rc = BLE_HS_EDONE; + goto done; + } + /* XXX: Verify conn_params. */ rc = ble_hs_id_use_addr(own_addr_type); diff --git a/nimble/host/src/ble_hs_conn.c b/nimble/host/src/ble_hs_conn.c index ebf65aae0..a3d504945 100644 --- a/nimble/host/src/ble_hs_conn.c +++ b/nimble/host/src/ble_hs_conn.c @@ -258,7 +258,7 @@ ble_hs_conn_find_assert(uint16_t conn_handle) } struct ble_hs_conn * -ble_hs_conn_find_by_addr(uint8_t addr_type, uint8_t *addr) +ble_hs_conn_find_by_addr(uint8_t addr_type, const uint8_t *addr) { #if !NIMBLE_BLE_CONNECT return NULL; diff --git a/nimble/host/src/ble_hs_conn_priv.h b/nimble/host/src/ble_hs_conn_priv.h index 3dfa5cf6e..1a96b3c27 100644 --- a/nimble/host/src/ble_hs_conn_priv.h +++ b/nimble/host/src/ble_hs_conn_priv.h @@ -85,7 +85,8 @@ void ble_hs_conn_insert(struct ble_hs_conn *conn); void ble_hs_conn_remove(struct ble_hs_conn *conn); struct ble_hs_conn *ble_hs_conn_find(uint16_t conn_handle); struct ble_hs_conn *ble_hs_conn_find_assert(uint16_t conn_handle); -struct ble_hs_conn *ble_hs_conn_find_by_addr(uint8_t addr_type, uint8_t *addr); +struct ble_hs_conn *ble_hs_conn_find_by_addr(uint8_t addr_type, + const uint8_t *addr); struct ble_hs_conn *ble_hs_conn_find_by_idx(int idx); int ble_hs_conn_exists(uint16_t conn_handle); struct ble_hs_conn *ble_hs_conn_first(void); diff --git a/nimble/host/test/src/ble_gap_test.c b/nimble/host/test/src/ble_gap_test.c index 85556e78f..983a892d5 100644 --- a/nimble/host/test/src/ble_gap_test.c +++ b/nimble/host/test/src/ble_gap_test.c @@ -920,6 +920,27 @@ TEST_CASE(ble_gap_test_case_conn_gen_already) TEST_ASSERT(rc == BLE_HS_EALREADY); } +TEST_CASE(ble_gap_test_case_conn_gen_done) +{ + static const struct ble_gap_conn_params conn_params = { 0 }; + static const uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 }; + int rc; + + ble_gap_test_util_init(); + + /* Successfully connect to the peer. */ + ble_hs_test_util_create_conn(2, peer_addr, ble_gap_test_util_connect_cb, + NULL); + + /* Ensure host indicates BLE_HS_EDONE if we try to connect to the same + * peer. + */ + rc = ble_gap_connect(BLE_ADDR_TYPE_PUBLIC, BLE_ADDR_TYPE_PUBLIC, + peer_addr, BLE_HS_FOREVER, &conn_params, + ble_gap_test_util_connect_cb, NULL); + TEST_ASSERT(rc == BLE_HS_EDONE); +} + TEST_CASE(ble_gap_test_case_conn_gen_busy) { static const struct ble_gap_disc_params disc_params = { 0 }; @@ -950,6 +971,7 @@ TEST_SUITE(ble_gap_test_suite_conn_gen) ble_gap_test_case_conn_gen_bad_args(); ble_gap_test_case_conn_gen_dflt_params(); ble_gap_test_case_conn_gen_already(); + ble_gap_test_case_conn_gen_done(); ble_gap_test_case_conn_gen_busy(); } diff --git a/nimble/host/test/src/ble_gatt_write_test.c b/nimble/host/test/src/ble_gatt_write_test.c index d3b77d22d..da6f23ac4 100644 --- a/nimble/host/test/src/ble_gatt_write_test.c +++ b/nimble/host/test/src/ble_gatt_write_test.c @@ -735,8 +735,6 @@ TEST_CASE(ble_gatt_write_test_reliable_oom) /* Initiate a write reliable procedure. */ ble_hs_test_util_attr_from_flat(&mattr, &attr); - ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), - NULL, NULL); off = 0; rc = ble_gattc_write_reliable(2, &mattr, 1, ble_gatt_write_test_reliable_cb_good, NULL);