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; }
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); }
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; }
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; }
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(¶ms); return 0; }