Exemple #1
0
static int bt_hci_connect_le_cancel(struct bt_conn *conn)
{
	int err;

	if (conn->timeout) {
		fiber_delayed_start_cancel(conn->timeout);
		conn->timeout = NULL;

		/* Drop the reference took by timeout fiber */
		bt_conn_unref(conn);
	}

	err = bt_hci_cmd_send(BT_HCI_OP_LE_CREATE_CONN_CANCEL, NULL);
	if (err) {
		return err;
	}

	return 0;
}
Exemple #2
0
int bt_conn_le_conn_update(struct bt_conn *conn,
			   const struct bt_le_conn_param *param)
{
	struct hci_cp_le_conn_update *conn_update;
	struct net_buf *buf;

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_CONN_UPDATE,
				sizeof(*conn_update));
	if (!buf) {
		return -ENOBUFS;
	}

	conn_update = net_buf_add(buf, sizeof(*conn_update));
	memset(conn_update, 0, sizeof(*conn_update));
	conn_update->handle = sys_cpu_to_le16(conn->handle);
	conn_update->conn_interval_min = sys_cpu_to_le16(param->interval_min);
	conn_update->conn_interval_max = sys_cpu_to_le16(param->interval_max);
	conn_update->conn_latency = sys_cpu_to_le16(param->latency);
	conn_update->supervision_timeout = sys_cpu_to_le16(param->timeout);

	return bt_hci_cmd_send(BT_HCI_OP_LE_CONN_UPDATE, buf);
}
Exemple #3
0
static int bt_hci_disconnect(struct bt_conn *conn, uint8_t reason)
{
	struct net_buf *buf;
	struct bt_hci_cp_disconnect *disconn;
	int err;

	buf = bt_hci_cmd_create(BT_HCI_OP_DISCONNECT, sizeof(*disconn));
	if (!buf) {
		return -ENOBUFS;
	}

	disconn = net_buf_add(buf, sizeof(*disconn));
	disconn->handle = sys_cpu_to_le16(conn->handle);
	disconn->reason = reason;

	err = bt_hci_cmd_send(BT_HCI_OP_DISCONNECT, buf);
	if (err) {
		return err;
	}

	bt_conn_set_state(conn, BT_CONN_DISCONNECT);

	return 0;
}
Exemple #4
0
int bt_le_adv_start(const struct bt_le_adv_param *param,
			const struct bt_data *ad, size_t ad_len,
			const struct bt_data *sd, size_t sd_len)
{
	int err;
	struct nble_gap_adv_params set_param = {0};
	struct nble_gap_ad_data_params data;

	if (!valid_adv_param(param)) {
		return -EINVAL;
	}

	memset(&data, 0, sizeof(data));

	if (atomic_test_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING)) {
		return -EALREADY;
	}

	err = set_advertise_disable();
	if (err) {
		return err;
	}
	err = set_ad(&data.ad, ad, ad_len);
	if (err) {
		return err;
	}

	/*
	 * Don't bother with scan response if the advertising type isn't
	 * a scannable one.
	 */
	if (param->type == BT_LE_ADV_IND || param->type == BT_LE_ADV_SCAN_IND) {
		err = set_ad(&data.sd, sd, sd_len);
		if (err) {
			return err;
		}
	}
	nble_gap_set_adv_data_req(&data);

	/* Timeout is handled by application timer */
	set_param.timeout = 0;
	/* forced to none currently (no whitelist support) */
	set_param.filter_policy = 0;
	set_param.interval_max = param->interval_max;
	set_param.interval_min = param->interval_min;
	set_param.type = param->type;
	nble_gap_set_adv_params_req(&set_param);

#if 0
	if (param->addr_type == BT_LE_ADV_ADDR_NRPA) {
		err = le_set_nrpa();
		if (err) {
			net_buf_unref(buf);
			return err;
		}

		set_param->own_addr_type = BT_ADDR_LE_RANDOM;
	} else {
		set_param->own_addr_type = BT_ADDR_LE_PUBLIC;
	}

	bt_hci_cmd_send(BT_HCI_OP_LE_SET_ADV_PARAMETERS, buf);
#endif

	err = set_advertise_enable();
	if (err) {
		return err;
	}

	atomic_set_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING);

	return 0;
}
Exemple #5
0
static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
			 uint8_t filter_dup)
{
	struct nble_gap_scan_params params = {
			.interval = interval,
			.window = window,
			.scan_type = scan_type,
	};

#ifdef NOT_USED_FOR_NOW
	struct net_buf *buf, *rsp;
	struct bt_hci_cp_le_set_scan_params *set_param;
	struct bt_hci_cp_le_set_scan_enable *scan_enable;
	int err;

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_SCAN_PARAMS,
				sizeof(*set_param));
	if (!buf) {
		return -ENOBUFS;
	}


	set_param = net_buf_add(buf, sizeof(*set_param));
	memset(set_param, 0, sizeof(*set_param));
	set_param->scan_type = scan_type;

	/* for the rest parameters apply default values according to
	 *  spec 4.2, vol2, part E, 7.8.10
	 */
	set_param->interval = sys_cpu_to_le16(interval);
	set_param->window = sys_cpu_to_le16(window);
	set_param->filter_policy = 0x00;

	if (scan_type == BT_HCI_LE_SCAN_ACTIVE) {
		err = le_set_nrpa();
		if (err) {
			net_buf_unref(buf);
			return err;
		}

		set_param->addr_type = BT_ADDR_LE_RANDOM;
	} else {
		set_param->addr_type = BT_ADDR_LE_PUBLIC;
	}

	bt_hci_cmd_send(BT_HCI_OP_LE_SET_SCAN_PARAMS, buf);
	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_SCAN_ENABLE,
				sizeof(*scan_enable));
	if (!buf) {
		return -ENOBUFS;
	}

	scan_enable = net_buf_add(buf, sizeof(*scan_enable));
	memset(scan_enable, 0, sizeof(*scan_enable));
	scan_enable->filter_dup = filter_dup;
	scan_enable->enable = BT_HCI_LE_SCAN_ENABLE;

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_SCAN_ENABLE, buf, &rsp);
	if (err) {
		return err;
	}
	/* Update scan state in case of success (0) status */
	err = rsp->data[0];
	if (!err) {
		atomic_set_bit(bt_dev.flags, BT_DEV_SCANNING);
	}

	net_buf_unref(rsp);
#endif

	nble_gap_start_scan_req(&params);

	return 0;
}