int bt_conn_le_param_update(struct bt_conn *conn, const struct bt_le_conn_param *param) { struct nble_gap_conn_update_req req; /* Check if there's a need to update conn params */ if (conn->interval >= param->interval_min && conn->interval <= param->interval_max) { return -EALREADY; } /* Cancel any pending update */ k_delayed_work_cancel(&conn->update_work); if (!bt_le_conn_params_valid(param->interval_min, param->interval_max, param->latency, param->timeout)) { return -EINVAL; } req.conn_handle = conn->handle; req.params.interval_min = param->interval_min; req.params.interval_max = param->interval_max; req.params.slave_latency = param->latency; req.params.link_sup_to = param->timeout; nble_gap_conn_update_req(&req); return 0; }
static inline void unset_dhcpv4_on_iface(struct net_if *iface) { if (!iface) { return; } iface->dhcpv4.state = NET_DHCPV4_INIT; iface->dhcpv4.attempts = 0; iface->dhcpv4.lease_time = 0; iface->dhcpv4.renewal_time = 0; memset(iface->dhcpv4.server_id.s4_addr, 0, 4); memset(iface->dhcpv4.server_id.s4_addr, 0, 4); memset(iface->dhcpv4.requested_ip.s4_addr, 0, 4); k_delayed_work_cancel(&iface->dhcpv4_timeout); k_delayed_work_cancel(&iface->dhcpv4_t1_timer); }
void bt_mesh_beacon_ivu_initiator(bool enable) { bt_mesh.ivu_initiator = enable; if (enable) { k_work_submit(&beacon_timer.work); } else if (bt_mesh_beacon_get() == BT_MESH_BEACON_DISABLED) { k_delayed_work_cancel(&beacon_timer); } }
void bt_mesh_reset(void) { if (!provisioned) { return; } bt_mesh_comp_unprovision(); bt_mesh.iv_index = 0; bt_mesh.seq = 0; bt_mesh.iv_update = 0; bt_mesh.pending_update = 0; bt_mesh.valid = 0; bt_mesh.last_update = 0; bt_mesh.ivu_initiator = 0; k_delayed_work_cancel(&bt_mesh.ivu_complete); bt_mesh_cfg_reset(); bt_mesh_rx_reset(); bt_mesh_tx_reset(); if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { bt_mesh_lpn_disable(true); } if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { bt_mesh_friend_clear_net_idx(BT_MESH_KEY_ANY); } if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { bt_mesh_proxy_gatt_disable(); } memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key)); memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl)); provisioned = false; bt_mesh_scan_disable(); bt_mesh_beacon_disable(); if (IS_ENABLED(CONFIG_BT_MESH_PROV)) { bt_mesh_prov_reset(); } }
static void l2cap_chan_send_req(struct bt_l2cap_le_chan *chan, struct net_buf *buf, int32_t timeout) { /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part A] page 126: * * The value of this timer is implementation-dependent but the minimum * initial value is 1 second and the maximum initial value is 60 * seconds. One RTX timer shall exist for each outstanding signaling * request, including each Echo Request. The timer disappears on the * final expiration, when the response is received, or the physical * link is lost. */ if (timeout) { k_delayed_work_submit(&chan->chan.rtx_work, timeout); } else { k_delayed_work_cancel(&chan->chan.rtx_work); } bt_l2cap_send(chan->chan.conn, BT_L2CAP_CID_LE_SIG, buf); }
static void h5_send(const u8_t *payload, u8_t type, int len) { u8_t hdr[4]; int i; hexdump("<= ", payload, len); (void)memset(hdr, 0, sizeof(hdr)); /* Set ACK for outgoing packet and stop delayed work */ H5_SET_ACK(hdr, h5.tx_ack); k_delayed_work_cancel(&ack_work); if (reliable_packet(type)) { H5_SET_RELIABLE(hdr); H5_SET_SEQ(hdr, h5.tx_seq); h5.tx_seq = (h5.tx_seq + 1) % 8; } H5_SET_TYPE(hdr, type); H5_SET_LEN(hdr, len); /* Calculate CRC */ hdr[3] = ~((hdr[0] + hdr[1] + hdr[2]) & 0xff); h5_print_header(hdr, "TX: <"); uart_poll_out(h5_dev, SLIP_DELIMITER); for (i = 0; i < 4; i++) { h5_slip_byte(hdr[i]); } for (i = 0; i < len; i++) { h5_slip_byte(payload[i]); } uart_poll_out(h5_dev, SLIP_DELIMITER); }
static void l2cap_chan_destroy(struct bt_l2cap_chan *chan) { struct bt_l2cap_le_chan *ch = BT_L2CAP_LE_CHAN(chan); struct net_buf *buf; BT_DBG("chan %p cid 0x%04x", ch, ch->rx.cid); /* Cancel ongoing work */ k_delayed_work_cancel(&chan->rtx_work); /* Remove buffers on the TX queue */ while ((buf = net_buf_get(&ch->tx_queue, K_NO_WAIT))) { net_buf_unref(buf); } /* Destroy segmented SDU if it exists */ if (ch->_sdu) { net_buf_unref(ch->_sdu); ch->_sdu = NULL; ch->_sdu_len = 0; } }
void on_nble_gap_disconnect_evt(const struct nble_gap_disconnect_evt *ev) { struct bt_conn *conn; conn = bt_conn_lookup_handle(ev->conn_handle); if (!conn) { BT_ERR("Unable to find conn for handle %u", ev->conn_handle); return; } BT_DBG("conn %p handle %u", conn, ev->conn_handle); conn->state = BT_CONN_DISCONNECTED; notify_disconnected(conn); /* Cancel Connection Update if it is pending */ k_delayed_work_cancel(&conn->update_work); /* Drop the reference given by lookup_handle() */ bt_conn_unref(conn); /* Drop the initial reference from conn_new() */ bt_conn_unref(conn); }
/* TODO: Handles only DHCPv4 OFFER and ACK messages */ static inline void handle_dhcpv4_reply(struct net_if *iface, uint8_t msg_type) { /* * Check for previous state, reason behind this check is, if client * receives multiple OFFER messages, first one will be handled. * Rest of the replies are discarded. */ if (iface->dhcpv4.state == NET_DHCPV4_DISCOVER) { if (msg_type != NET_DHCPV4_OFFER) { NET_DBG("Reply not handled %d", msg_type); return; } /* Send DHCPv4 Request Message */ k_delayed_work_cancel(&iface->dhcpv4_timeout); send_request(iface, false); } else if (iface->dhcpv4.state == NET_DHCPV4_REQUEST || iface->dhcpv4.state == NET_DHCPV4_RENEWAL) { if (msg_type != NET_DHCPV4_ACK) { NET_DBG("Reply not handled %d", msg_type); return; } k_delayed_work_cancel(&iface->dhcpv4_timeout); switch (iface->dhcpv4.state) { case NET_DHCPV4_REQUEST: NET_INFO("Received: %s", net_sprint_ipv4_addr( &iface->dhcpv4.requested_ip)); if (!net_if_ipv4_addr_add(iface, &iface->dhcpv4.requested_ip, NET_ADDR_DHCP, iface->dhcpv4.lease_time)) { NET_DBG("Failed to add IPv4 addr to iface %p", iface); return; } break; case NET_DHCPV4_RENEWAL: /* TODO: if the renewal is success, update only * vlifetime on iface */ break; default: break; } iface->dhcpv4.attempts = 0; iface->dhcpv4.state = NET_DHCPV4_ACK; /* Start renewal time */ k_delayed_work_init(&iface->dhcpv4_t1_timer, dhcpv4_t1_timeout); k_delayed_work_submit(&iface->dhcpv4_t1_timer, get_dhcpv4_renewal_time(iface)); } }
void bt_mesh_beacon_disable(void) { if (!bt_mesh.ivu_initiator) { k_delayed_work_cancel(&beacon_timer); } }
static void le_conn_rsp(struct bt_l2cap *l2cap, uint8_t ident, struct net_buf *buf) { struct bt_conn *conn = l2cap->chan.chan.conn; struct bt_l2cap_le_chan *chan; struct bt_l2cap_le_conn_rsp *rsp = (void *)buf->data; uint16_t dcid, mtu, mps, credits, result; if (buf->len < sizeof(*rsp)) { BT_ERR("Too small LE conn rsp packet size"); return; } dcid = sys_le16_to_cpu(rsp->dcid); mtu = sys_le16_to_cpu(rsp->mtu); mps = sys_le16_to_cpu(rsp->mps); credits = sys_le16_to_cpu(rsp->credits); result = sys_le16_to_cpu(rsp->result); BT_DBG("dcid 0x%04x mtu %u mps %u credits %u result 0x%04x", dcid, mtu, mps, credits, result); /* Keep the channel in case of security errors */ if (result == BT_L2CAP_SUCCESS || result == BT_L2CAP_ERR_AUTHENTICATION || result == BT_L2CAP_ERR_ENCRYPTION) { chan = l2cap_lookup_ident(conn, ident); } else { chan = l2cap_remove_ident(conn, ident); } if (!chan) { BT_ERR("Cannot find channel for ident %u", ident); return; } /* Cancel RTX work */ k_delayed_work_cancel(&chan->chan.rtx_work); /* Reset ident since it got a response */ chan->chan.ident = 0; switch (result) { case BT_L2CAP_SUCCESS: chan->tx.cid = dcid; chan->tx.mtu = mtu; chan->tx.mps = mps; /* Update state */ bt_l2cap_chan_set_state(&chan->chan, BT_L2CAP_CONNECTED); if (chan->chan.ops && chan->chan.ops->connected) { chan->chan.ops->connected(&chan->chan); } /* Give credits */ l2cap_chan_tx_give_credits(chan, credits); l2cap_chan_rx_give_credits(chan, chan->rx.init_credits); break; case BT_L2CAP_ERR_AUTHENTICATION: case BT_L2CAP_ERR_ENCRYPTION: /* If security needs changing wait it to be completed */ if (l2cap_change_security(chan, result) == 0) { return; } l2cap_detach_chan(conn, &chan->chan); default: bt_l2cap_chan_del(&chan->chan); } }