diff --git a/drivers/nble/conn.c b/drivers/nble/conn.c index 25168e69bc8..8585065155d 100644 --- a/drivers/nble/conn.c +++ b/drivers/nble/conn.c @@ -135,10 +135,84 @@ int bt_conn_disconnect(struct bt_conn *conn, uint8_t reason) return -ENOSYS; } +static inline bool bt_le_conn_params_valid(uint16_t min, uint16_t max, + uint16_t latency, uint16_t timeout) +{ + if (min > max || min < 6 || max > 3200) { + return false; + } + + /* Limits according to BT Core spec 4.2 [Vol 2, Part E, 7.8.12] */ + if (timeout < 10 || timeout > 3200 || + (2 * timeout) < ((1 + latency) * max * 5)) { + return false; + } + + /* Limits according to BT Core spec 4.2 [Vol 6, Part B, 4.5.1] */ + if (latency > 499 || ((latency + 1) * max) > (timeout * 4)) { + return false; + } + + return true; +} + struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer, const struct bt_le_conn_param *param) { - return NULL; + struct nble_gap_connect_req_params req; + struct bt_conn *conn; + + if (!bt_le_conn_params_valid(param->interval_min, param->interval_max, + param->latency, param->timeout)) { + return NULL; + } + + conn = bt_conn_lookup_addr_le(peer); + if (conn) { + return conn; + } + + conn = conn_new(); + if (!conn) { + BT_ERR("Unable to create new bt_conn object"); + return NULL; + } + + /* Update connection parameters */ + bt_addr_le_copy(&conn->dst, peer); + conn->latency = param->latency; + conn->timeout = param->timeout; + + /* Construct parameters to NBLE */ + bt_addr_le_copy(&req.bda, peer); + + req.conn_params.interval_min = param->interval_min; + req.conn_params.interval_max = param->interval_max; + req.conn_params.slave_latency = param->latency; + req.conn_params.link_sup_to = param->timeout; + + req.scan_params.interval = BT_GAP_SCAN_FAST_INTERVAL; + req.scan_params.window = BT_GAP_SCAN_FAST_WINDOW; + /* Use passive scanning */ + req.scan_params.active = 0; + /* Do not use whitelist */ + req.scan_params.selective = 0; + /* Disable timeout */ + req.scan_params.timeout = 0; + + nble_gap_connect_req(&req, conn); + + return conn; +} + +void on_nble_gap_connect_rsp(const struct nble_response *rsp) +{ + if (rsp->status) { + BT_ERR("Connect failed, status %d", rsp->status); + return; + } + + BT_DBG("conn %p", rsp->user_data); } int bt_conn_security(struct bt_conn *conn, bt_security_t sec)