static int set_advertise_disable(void) { #if 0 struct net_buf *buf; int err; #endif if (!atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) { return 0; } #if 0 buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_ENABLE, 1); if (!buf) { return -ENOBUFS; } net_buf_add_u8(buf, BT_HCI_LE_ADV_DISABLE); err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL); if (err) { return err; } #endif nble_gap_stop_adv_req(NULL); atomic_clear_bit(bt_dev.flags, BT_DEV_ADVERTISING); return 0; }
static int bt_hci_connect_br_cancel(struct bt_conn *conn) { struct bt_hci_cp_connect_cancel *cp; struct bt_hci_rp_connect_cancel *rp; struct net_buf *buf, *rsp; int err; buf = bt_hci_cmd_create(BT_HCI_OP_CONNECT_CANCEL, sizeof(*cp)); if (!buf) { return -ENOBUFS; } cp = net_buf_add(buf, sizeof(*cp)); memcpy(&cp->bdaddr, &conn->br.dst, sizeof(cp->bdaddr)); err = bt_hci_cmd_send_sync(BT_HCI_OP_CONNECT_CANCEL, buf, &rsp); if (err) { return err; } rp = (void *)rsp->data; err = rp->status ? -EIO : 0; net_buf_unref(rsp); return err; }
struct bt_conn *bt_conn_create_br(const bt_addr_t *peer, const struct bt_br_conn_param *param) { struct bt_hci_cp_connect *cp; struct bt_conn *conn; struct net_buf *buf; conn = bt_conn_lookup_addr_br(peer); if (conn) { switch (conn->state) { return conn; case BT_CONN_CONNECT: case BT_CONN_CONNECTED: return conn; default: bt_conn_unref(conn); return NULL; } } conn = bt_conn_add_br(peer); if (!conn) { return NULL; } buf = bt_hci_cmd_create(BT_HCI_OP_CONNECT, sizeof(*cp)); if (!buf) { bt_conn_unref(conn); return NULL; } cp = net_buf_add(buf, sizeof(*cp)); memset(cp, 0, sizeof(*cp)); memcpy(&cp->bdaddr, peer, sizeof(cp->bdaddr)); cp->packet_type = sys_cpu_to_le16(0xcc18); /* DM1 DH1 DM3 DH5 DM5 DH5 */ cp->pscan_rep_mode = 0x02; /* R2 */ cp->allow_role_switch = param->allow_role_switch ? 0x01 : 0x00; cp->clock_offset = 0x0000; /* TODO used cached clock offset */ if (bt_hci_cmd_send_sync(BT_HCI_OP_CONNECT, buf, NULL) < 0) { bt_conn_unref(conn); return NULL; } bt_conn_set_state(conn, BT_CONN_CONNECT); conn->role = BT_CONN_ROLE_MASTER; return conn; }
static int ssp_confirm_reply(struct bt_conn *conn) { struct bt_hci_cp_user_confirm_reply *cp; struct net_buf *buf; BT_DBG(""); buf = bt_hci_cmd_create(BT_HCI_OP_USER_CONFIRM_REPLY, sizeof(*cp)); if (!buf) { return -ENOBUFS; } cp = net_buf_add(buf, sizeof(*cp)); bt_addr_copy(&cp->bdaddr, &conn->br.dst); return bt_hci_cmd_send_sync(BT_HCI_OP_USER_CONFIRM_REPLY, buf, NULL); }
static int pin_code_neg_reply(const bt_addr_t *bdaddr) { struct bt_hci_cp_pin_code_neg_reply *cp; struct net_buf *buf; BT_DBG(""); buf = bt_hci_cmd_create(BT_HCI_OP_PIN_CODE_NEG_REPLY, sizeof(*cp)); if (!buf) { return -ENOBUFS; } cp = net_buf_add(buf, sizeof(*cp)); bt_addr_copy(&cp->bdaddr, bdaddr); return bt_hci_cmd_send_sync(BT_HCI_OP_PIN_CODE_NEG_REPLY, buf, NULL); }
static int ssp_passkey_reply(struct bt_conn *conn, unsigned int passkey) { struct bt_hci_cp_user_passkey_reply *cp; struct net_buf *buf; BT_DBG(""); buf = bt_hci_cmd_create(BT_HCI_OP_USER_PASSKEY_REPLY, sizeof(*cp)); if (!buf) { return -ENOBUFS; } cp = net_buf_add(buf, sizeof(*cp)); bt_addr_copy(&cp->bdaddr, &conn->br.dst); cp->passkey = sys_cpu_to_le32(passkey); return bt_hci_cmd_send_sync(BT_HCI_OP_USER_PASSKEY_REPLY, buf, NULL); }
static int conn_auth(struct bt_conn *conn) { struct bt_hci_cp_auth_requested *auth; struct net_buf *buf; BT_DBG(""); buf = bt_hci_cmd_create(BT_HCI_OP_AUTH_REQUESTED, sizeof(*auth)); if (!buf) { return -ENOBUFS; } auth = net_buf_add(buf, sizeof(*auth)); auth->handle = sys_cpu_to_le16(conn->handle); atomic_set_bit(conn->flags, BT_CONN_BR_PAIRING_INITIATOR); return bt_hci_cmd_send_sync(BT_HCI_OP_AUTH_REQUESTED, buf, NULL); }
static int bt_hci_stop_scanning(void) { #ifdef NOT_USED_FOR_NOW struct net_buf *buf, *rsp; struct bt_hci_cp_le_set_scan_enable *scan_enable; int err; if (!atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING)) { return -EALREADY; } 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 = BT_HCI_LE_SCAN_FILTER_DUP_DISABLE; scan_enable->enable = BT_HCI_LE_SCAN_DISABLE; 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_clear_bit(bt_dev.flags, BT_DEV_SCANNING); } net_buf_unref(rsp); return err; #endif nble_gap_stop_scan_req(); return 0; }
static int pin_code_reply(struct bt_conn *conn, const char *pin, uint8_t len) { struct bt_hci_cp_pin_code_reply *cp; struct net_buf *buf; BT_DBG(""); buf = bt_hci_cmd_create(BT_HCI_OP_PIN_CODE_REPLY, sizeof(*cp)); if (!buf) { return -ENOBUFS; } cp = net_buf_add(buf, sizeof(*cp)); bt_addr_copy(&cp->bdaddr, &conn->br.dst); cp->pin_len = len; strncpy(cp->pin_code, pin, sizeof(cp->pin_code)); return bt_hci_cmd_send_sync(BT_HCI_OP_PIN_CODE_REPLY, buf, NULL); }
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); }
int bt_conn_le_start_encryption(struct bt_conn *conn, uint64_t rand, uint16_t ediv, const uint8_t *ltk, size_t len) { struct bt_hci_cp_le_start_encryption *cp; struct net_buf *buf; buf = bt_hci_cmd_create(BT_HCI_OP_LE_START_ENCRYPTION, sizeof(*cp)); if (!buf) { return -ENOBUFS; } cp = net_buf_add(buf, sizeof(*cp)); cp->handle = sys_cpu_to_le16(conn->handle); cp->rand = rand; cp->ediv = ediv; memcpy(cp->ltk, ltk, len); if (len < sizeof(cp->ltk)) { memset(cp->ltk + len, 0, sizeof(cp->ltk) - len); } return bt_hci_cmd_send_sync(BT_HCI_OP_LE_START_ENCRYPTION, buf, NULL); }
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; }
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; }