void ble_hs_atomic_conn_insert(struct ble_hs_conn *conn) { ble_hs_lock(); ble_hs_conn_insert(conn); ble_hs_unlock(); }
void ble_sm_sc_dhkey_check_rx(uint16_t conn_handle, uint8_t op, struct os_mbuf **om, struct ble_sm_result *res) { struct ble_sm_dhkey_check cmd; struct ble_sm_proc *proc; struct ble_sm_proc *prev; res->app_status = ble_hs_mbuf_pullup_base(om, BLE_SM_DHKEY_CHECK_SZ); if (res->app_status != 0) { res->enc_cb = 1; res->sm_err = BLE_SM_ERR_UNSPECIFIED; return; } ble_sm_dhkey_check_parse((*om)->om_data, (*om)->om_len, &cmd); BLE_SM_LOG_CMD(0, "dhkey check", conn_handle, ble_sm_dhkey_check_log, &cmd); ble_hs_lock(); proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_DHKEY_CHECK, -1, &prev); if (proc == NULL) { res->app_status = BLE_HS_ENOENT; } else { ble_sm_dhkey_check_process(proc, &cmd, res); } ble_hs_unlock(); }
/** * Sets the device's random address. The address type (static vs. * non-resolvable private) is inferred from the most-significant byte of the * address. The address is specified in host byte order (little-endian!). * * @param rnd_addr The random address to set. * * @return 0 on success; * BLE_HS_EINVAL if the specified address is not a * valid static random or non-resolvable * private address. * Other nonzero on error. */ int ble_hs_id_set_rnd(const uint8_t *rnd_addr) { uint8_t addr_type_byte; int rc; ble_hs_lock(); addr_type_byte = rnd_addr[5] & 0xc0; if (addr_type_byte != 0x00 && addr_type_byte != 0xc0) { rc = BLE_HS_EINVAL; goto done; } rc = ble_hs_hci_util_set_random_addr(rnd_addr); if (rc != 0) { goto done; } memcpy(ble_hs_id_rnd, rnd_addr, 6); rc = 0; done: ble_hs_unlock(); return rc; }
int ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **om) { struct ble_att_mtu_cmd rsp; struct ble_l2cap_chan *chan; uint16_t mtu; int rc; mtu = 0; rc = ble_hs_misc_pullup_base(om, BLE_ATT_MTU_CMD_SZ); if (rc == 0) { ble_att_mtu_cmd_parse((*om)->om_data, (*om)->om_len, &rsp); ble_hs_lock(); rc = ble_att_conn_chan_find(conn_handle, NULL, &chan); if (rc == 0) { ble_att_set_peer_mtu(chan, rsp.bamc_mtu); mtu = ble_l2cap_chan_mtu(chan); } ble_hs_unlock(); } ble_gattc_rx_mtu(conn_handle, rc, mtu); return rc; }
void ble_hs_id_set_pub(const uint8_t *pub_addr) { ble_hs_lock(); memcpy(ble_hs_id_pub, pub_addr, 6); ble_hs_unlock(); }
int ble_att_clt_tx_mtu(uint16_t conn_handle, struct ble_att_mtu_cmd *req) { struct ble_l2cap_chan *chan; struct ble_hs_conn *conn; struct os_mbuf *txom; int rc; if (req->bamc_mtu < BLE_ATT_MTU_DFLT) { return BLE_HS_EINVAL; } rc = ble_att_clt_build_mtu_req(req, &txom); if (rc != 0) { return rc; } rc = ble_att_clt_tx_req(conn_handle, txom); if (rc != 0) { return rc; } ble_hs_lock(); rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); if (rc == 0) { chan->blc_flags |= BLE_L2CAP_CHAN_F_TXED_MTU; } ble_hs_unlock(); return rc; }
int ble_hs_atomic_conn_delete(uint16_t conn_handle) { struct ble_hs_conn *conn; ble_hs_lock(); conn = ble_hs_conn_find(conn_handle); if (conn != NULL) { ble_hs_conn_remove(conn); ble_hs_conn_free(conn); } ble_hs_unlock(); return conn != NULL ? 0 : BLE_HS_ENOTCONN; }
static int ble_os_test_misc_conn_exists(uint16_t conn_handle) { struct ble_hs_conn *conn; ble_hs_lock(); if (conn_handle == BLE_HS_CONN_HANDLE_NONE) { conn = ble_hs_conn_first(); } else { conn = ble_hs_conn_find(conn_handle); } ble_hs_unlock(); return conn != NULL; }
/** * Retrieves one of the device's identity addresses. The device can have two * identity addresses: one public and one random. The id_addr_type argument * specifies which of these two addresses to retrieve. * * @param id_addr_type The type of identity address to retrieve. * Valid values are: * o BLE_ADDR_TYPE_PUBLIC * o BLE_ADDR_TYPE_RANDOM * @param out_id_addr On success, the requested identity address is * copied into this buffer. The buffer must * be at least six bytes in size. * @param out_is_nrpa On success, the pointed-to value indicates * whether the retrieved address is a * non-resolvable private address. * * @return 0 on success; * BLE_HS_EINVAL if an invalid address type was * specified; * BLE_HS_ENOADDR if the device does not have an * identity address of the requested type; * Other BLE host core code on error. */ int ble_hs_id_copy_addr(uint8_t id_addr_type, uint8_t *out_id_addr, int *out_is_nrpa) { const uint8_t *addr; int rc; ble_hs_lock(); rc = ble_hs_id_addr(id_addr_type, &addr, out_is_nrpa); if (rc == 0) { memcpy(out_id_addr, addr, 6); } ble_hs_unlock(); return rc; }
int ble_hs_atomic_conn_flags(uint16_t conn_handle, ble_hs_conn_flags_t *out_flags) { struct ble_hs_conn *conn; int rc; ble_hs_lock(); conn = ble_hs_conn_find(conn_handle); if (conn == NULL) { rc = BLE_HS_ENOTCONN; } else { rc = 0; *out_flags = conn->bhc_flags; } ble_hs_unlock(); return rc; }
uint16_t ble_att_mtu(uint16_t conn_handle) { struct ble_l2cap_chan *chan; struct ble_hs_conn *conn; uint16_t mtu; ble_hs_lock(); ble_att_conn_chan_find(conn_handle, &conn, &chan); if (chan != NULL) { mtu = ble_l2cap_chan_mtu(chan); } else { mtu = 0; } ble_hs_unlock(); return mtu; }
static int ble_att_clt_tx_req_flags(uint16_t conn_handle, struct os_mbuf *txom, ble_hs_conn_flags_t flags_on_success) { struct ble_l2cap_chan *chan; struct ble_hs_conn *conn; uint16_t total_len; uint16_t mtu; int extra_len; int rc; BLE_HS_DBG_ASSERT_EVAL(txom->om_len >= 1); ble_att_inc_tx_stat(txom->om_data[0]); ble_hs_lock(); rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); if (rc == 0) { /* Reduce the size of the transmission to fit the connection's ATT * MTU. */ total_len = OS_MBUF_PKTLEN(txom); mtu = ble_l2cap_chan_mtu(chan); extra_len = total_len - mtu; if (extra_len > 0) { os_mbuf_adj(txom, -extra_len); } rc = ble_l2cap_tx(conn, chan, txom); txom = NULL; if (rc == 0) { conn->bhc_flags |= flags_on_success; } } ble_hs_unlock(); os_mbuf_free_chain(txom); return rc; }
static int ble_l2cap_sig_tx(uint16_t conn_handle, struct os_mbuf *txom) { struct ble_l2cap_chan *chan; struct ble_hs_conn *conn; int rc; STATS_INC(ble_l2cap_stats, sig_tx); ble_hs_lock(); rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG, &conn, &chan); if (rc == 0) { rc = ble_l2cap_tx(conn, chan, txom); } ble_hs_unlock(); return rc; }
void ble_sm_sc_public_key_rx(uint16_t conn_handle, uint8_t op, struct os_mbuf **om, struct ble_sm_result *res) { struct ble_sm_public_key cmd; struct ble_sm_proc *proc; struct ble_sm_proc *prev; uint8_t ioact; int rc; res->app_status = ble_hs_mbuf_pullup_base(om, BLE_SM_PUBLIC_KEY_SZ); if (res->app_status != 0) { res->enc_cb = 1; return; } res->app_status = ble_sm_sc_ensure_keys_generated(); if (res->app_status != 0) { res->enc_cb = 1; res->sm_err = BLE_SM_ERR_UNSPECIFIED; return; } ble_sm_public_key_parse((*om)->om_data, (*om)->om_len, &cmd); BLE_SM_LOG_CMD(0, "public key", conn_handle, ble_sm_public_key_log, &cmd); ble_hs_lock(); proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_PUBLIC_KEY, -1, &prev); if (proc == NULL) { res->app_status = BLE_HS_ENOENT; res->sm_err = BLE_SM_ERR_UNSPECIFIED; } else { proc->pub_key_peer = cmd; rc = ble_sm_alg_gen_dhkey(proc->pub_key_peer.x, proc->pub_key_peer.y, ble_sm_sc_priv_key.u32, proc->dhkey); if (rc != 0) { res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_DHKEY); res->sm_err = BLE_SM_ERR_DHKEY; res->enc_cb = 1; } else { if (proc->flags & BLE_SM_PROC_F_INITIATOR) { proc->state = BLE_SM_PROC_STATE_CONFIRM; ioact = ble_sm_sc_io_action(proc); if (ble_sm_ioact_state(ioact) == proc->state) { res->passkey_params.action = ioact; } if (ble_sm_proc_can_advance(proc) && ble_sm_sc_initiator_txes_confirm(proc)) { res->execute = 1; } } else { res->execute = 1; } } } ble_hs_unlock(); }
/** * Called when a data packet is received from the controller. This function * consumes the supplied mbuf, regardless of the outcome. * * @param om The incoming data packet, beginning with the * HCI ACL data header. * * @return 0 on success; nonzero on failure. */ int ble_hs_hci_evt_acl_process(struct os_mbuf *om) { struct hci_data_hdr hci_hdr; struct ble_hs_conn *conn; ble_l2cap_rx_fn *rx_cb; uint16_t conn_handle; int reject_cid; int rc; rc = ble_hs_hci_util_data_hdr_strip(om, &hci_hdr); if (rc != 0) { goto err; } #if (BLETEST_THROUGHPUT_TEST == 0) BLE_HS_LOG(DEBUG, "ble_hs_hci_evt_acl_process(): conn_handle=%u pb=%x " "len=%u data=", BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc), BLE_HCI_DATA_PB(hci_hdr.hdh_handle_pb_bc), hci_hdr.hdh_len); ble_hs_log_mbuf(om); BLE_HS_LOG(DEBUG, "\n"); #endif if (hci_hdr.hdh_len != OS_MBUF_PKTHDR(om)->omp_len) { rc = BLE_HS_EBADDATA; goto err; } conn_handle = BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc); ble_hs_lock(); conn = ble_hs_conn_find(conn_handle); if (conn == NULL) { /* Peer not connected; quietly discard packet. */ rc = BLE_HS_ENOTCONN; reject_cid = -1; } else { /* Forward ACL data to L2CAP. */ rc = ble_l2cap_rx(conn, &hci_hdr, om, &rx_cb, &reject_cid); om = NULL; } ble_hs_unlock(); switch (rc) { case 0: /* Final fragment received. */ BLE_HS_DBG_ASSERT(rx_cb != NULL); rc = rx_cb(conn->bhc_rx_chan); ble_l2cap_forget_rx(conn, conn->bhc_rx_chan); break; case BLE_HS_EAGAIN: /* More fragments on the way. */ break; default: if (reject_cid != -1) { ble_l2cap_sig_reject_invalid_cid_tx(conn_handle, 0, 0, reject_cid); } goto err; } return 0; err: os_mbuf_free_chain(om); return rc; }