Esempio n. 1
0
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;
}
Esempio n. 2
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);
}
Esempio n. 3
0
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);
    }
}
Esempio n. 4
0
File: main.c Progetto: wosayttn/aos
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();
	}
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
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;
	}
}
Esempio n. 8
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);
}
Esempio n. 9
0
/* 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));
	}
}
Esempio n. 10
0
void bt_mesh_beacon_disable(void)
{
    if (!bt_mesh.ivu_initiator) {
        k_delayed_work_cancel(&beacon_timer);
    }
}
Esempio n. 11
0
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);
	}
}