static void l2cap_send_reject(struct bt_conn *conn, uint8_t ident, uint16_t reason, void *data, uint8_t data_len) { struct bt_l2cap_cmd_reject *rej; struct bt_l2cap_sig_hdr *hdr; struct net_buf *buf; buf = bt_l2cap_create_pdu(&le_sig); if (!buf) { return; } hdr = net_buf_add(buf, sizeof(*hdr)); hdr->code = BT_L2CAP_CMD_REJECT; hdr->ident = ident; hdr->len = sys_cpu_to_le16(sizeof(*rej) + data_len); rej = net_buf_add(buf, sizeof(*rej)); rej->reason = sys_cpu_to_le16(reason); if (data) { memcpy(net_buf_add(buf, data_len), data, data_len); } bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf); }
static int att_read_type(struct bt_conn *conn, struct bt_gatt_discover_params *params) { struct net_buf *buf; struct bt_att_read_type_req *req; uint16_t *value; buf = bt_att_create_pdu(conn, BT_ATT_OP_READ_TYPE_REQ, sizeof(*req)); if (!buf) { return -ENOMEM; } req = net_buf_add(buf, sizeof(*req)); req->start_handle = sys_cpu_to_le16(params->start_handle); req->end_handle = sys_cpu_to_le16(params->end_handle); value = net_buf_add(buf, sizeof(*value)); if (params->type == BT_GATT_DISCOVER_INCLUDE) *value = sys_cpu_to_le16(BT_UUID_GATT_INCLUDE_VAL); else *value = sys_cpu_to_le16(BT_UUID_GATT_CHRC_VAL); BT_DBG("start_handle 0x%04x end_handle 0x%04x", params->start_handle, params->end_handle); return gatt_send(conn, buf, att_read_type_rsp, params, NULL); }
int bt_l2cap_update_conn_param(struct bt_conn *conn, const struct bt_le_conn_param *param) { struct bt_l2cap_sig_hdr *hdr; struct bt_l2cap_conn_param_req *req; struct net_buf *buf; buf = bt_l2cap_create_pdu(&le_sig); if (!buf) { return -ENOBUFS; } hdr = net_buf_add(buf, sizeof(*hdr)); hdr->code = BT_L2CAP_CONN_PARAM_REQ; hdr->ident = get_ident(); hdr->len = sys_cpu_to_le16(sizeof(*req)); req = net_buf_add(buf, sizeof(*req)); req->min_interval = sys_cpu_to_le16(param->interval_min); req->max_interval = sys_cpu_to_le16(param->interval_max); req->latency = sys_cpu_to_le16(param->latency); req->timeout = sys_cpu_to_le16(param->timeout); bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf); return 0; }
static inline void encode_hdr(struct bt_monitor_hdr *hdr, u16_t opcode, u16_t len) { struct bt_monitor_ts32 *ts; hdr->opcode = sys_cpu_to_le16(opcode); hdr->flags = 0; ts = (void *)hdr->ext; ts->type = BT_MONITOR_TS32; ts->ts32 = sys_cpu_to_le32(k_uptime_get() * 10); hdr->hdr_len = sizeof(*ts); encode_drops(hdr, BT_MONITOR_COMMAND_DROPS, &drops.cmd); encode_drops(hdr, BT_MONITOR_EVENT_DROPS, &drops.evt); encode_drops(hdr, BT_MONITOR_ACL_TX_DROPS, &drops.acl_tx); encode_drops(hdr, BT_MONITOR_ACL_RX_DROPS, &drops.acl_rx); #if defined(CONFIG_BT_BREDR) encode_drops(hdr, BT_MONITOR_SCO_TX_DROPS, &drops.sco_tx); encode_drops(hdr, BT_MONITOR_SCO_RX_DROPS, &drops.sco_rx); #endif encode_drops(hdr, BT_MONITOR_OTHER_DROPS, &drops.other); hdr->data_len = sys_cpu_to_le16(4 + hdr->hdr_len + len); }
int bt_l2cap_chan_disconnect(struct bt_l2cap_chan *chan) { struct bt_conn *conn = chan->conn; struct net_buf *buf; struct bt_l2cap_disconn_req *req; struct bt_l2cap_le_chan *ch; if (!conn) { return -ENOTCONN; } if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && conn->type == BT_CONN_TYPE_BR) { return bt_l2cap_br_chan_disconnect(chan); } ch = BT_L2CAP_LE_CHAN(chan); BT_DBG("chan %p scid 0x%04x dcid 0x%04x", chan, ch->rx.cid, ch->tx.cid); ch->chan.ident = get_ident(); buf = l2cap_create_le_sig_pdu(BT_L2CAP_DISCONN_REQ, ch->chan.ident, sizeof(*req)); req = net_buf_add(buf, sizeof(*req)); req->dcid = sys_cpu_to_le16(ch->tx.cid); req->scid = sys_cpu_to_le16(ch->rx.cid); l2cap_chan_send_req(ch, buf, L2CAP_DISC_TIMEOUT); bt_l2cap_chan_set_state(chan, BT_L2CAP_DISCONNECT); return 0; }
static void l2cap_chan_update_credits(struct bt_l2cap_le_chan *chan) { struct net_buf *buf; struct bt_l2cap_le_credits *ev; uint16_t credits; /* Only give more credits if it went bellow the defined threshold */ if (k_sem_count_get(&chan->rx.credits) > L2CAP_LE_CREDITS_THRESHOLD(chan->rx.init_credits)) { goto done; } /* Restore credits */ credits = chan->rx.init_credits - k_sem_count_get(&chan->rx.credits); l2cap_chan_rx_give_credits(chan, credits); buf = l2cap_create_le_sig_pdu(BT_L2CAP_LE_CREDITS, get_ident(), sizeof(*ev)); ev = net_buf_add(buf, sizeof(*ev)); ev->cid = sys_cpu_to_le16(chan->rx.cid); ev->credits = sys_cpu_to_le16(credits); bt_l2cap_send(chan->chan.conn, BT_L2CAP_CID_LE_SIG, buf); done: BT_DBG("chan %p credits %u", chan, k_sem_count_get(&chan->rx.credits)); }
static uint8_t read_group_cb(const struct bt_gatt_attr *attr, void *user_data) { struct read_group_data *data = user_data; struct bt_att *att = data->att; struct bt_conn *conn = att->chan.conn; int read; /* Update group end_handle if attribute is not a service */ if (bt_uuid_cmp(attr->uuid, BT_UUID_GATT_PRIMARY) && bt_uuid_cmp(attr->uuid, BT_UUID_GATT_SECONDARY)) { if (data->group && attr->handle > data->group->end_handle) { data->group->end_handle = sys_cpu_to_le16(attr->handle); } return BT_GATT_ITER_CONTINUE; } /* If Group Type don't match skip */ if (bt_uuid_cmp(attr->uuid, data->uuid)) { data->group = NULL; return BT_GATT_ITER_CONTINUE; } BT_DBG("handle 0x%04x", attr->handle); /* Stop if there is no space left */ if (data->rsp->len && att->chan.tx.mtu - data->buf->len < data->rsp->len) { return BT_GATT_ITER_STOP; } /* Fast foward to next group position */ data->group = net_buf_add(data->buf, sizeof(*data->group)); /* Initialize group handle range */ data->group->start_handle = sys_cpu_to_le16(attr->handle); data->group->end_handle = sys_cpu_to_le16(attr->handle); /* Read attribute value and store in the buffer */ read = attr->read(conn, attr, data->buf->data + data->buf->len, att->chan.tx.mtu - data->buf->len, 0); if (read < 0) { /* TODO: Handle read errors */ return BT_GATT_ITER_STOP; } if (!data->rsp->len) { /* Set len to be the first group found */ data->rsp->len = read + sizeof(*data->group); } else if (data->rsp->len != read + sizeof(*data->group)) { /* All groups entries should have the same size */ data->buf->len -= sizeof(*data->group); return false; } net_buf_add(data->buf, read); /* Continue to find the end handle */ return BT_GATT_ITER_CONTINUE; }
static uint8_t find_type_cb(const struct bt_gatt_attr *attr, void *user_data) { struct find_type_data *data = user_data; struct bt_att *att = data->att; struct bt_conn *conn = att->chan.conn; int read; uint8_t uuid[16]; /* Skip secondary services */ if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_SECONDARY)) { data->group = NULL; return BT_GATT_ITER_CONTINUE; } /* Update group end_handle if not a primary service */ if (bt_uuid_cmp(attr->uuid, BT_UUID_GATT_PRIMARY)) { if (data->group && attr->handle > data->group->end_handle) { data->group->end_handle = sys_cpu_to_le16(attr->handle); } return BT_GATT_ITER_CONTINUE; } BT_DBG("handle 0x%04x", attr->handle); /* stop if there is no space left */ if (att->chan.tx.mtu - data->buf->len < sizeof(*data->group)) { return BT_GATT_ITER_STOP; } /* Read attribute value and store in the buffer */ read = attr->read(conn, attr, uuid, sizeof(uuid), 0); if (read < 0) { /* * Since we don't know if it is the service with requested UUID, * we cannot respond with an error to this request. */ data->group = NULL; return BT_GATT_ITER_CONTINUE; } /* Check if data matches */ if (read != data->value_len || memcmp(data->value, uuid, read)) { data->group = NULL; return BT_GATT_ITER_CONTINUE; } /* If service has been found, error should be cleared */ data->err = 0x00; /* Fast foward to next item position */ data->group = net_buf_add(data->buf, sizeof(*data->group)); data->group->start_handle = sys_cpu_to_le16(attr->handle); data->group->end_handle = sys_cpu_to_le16(attr->handle); /* continue to find the end_handle */ return BT_GATT_ITER_CONTINUE; }
static void le_conn_param_update_req(struct bt_l2cap *l2cap, uint8_t ident, struct net_buf *buf) { struct bt_conn *conn = l2cap->chan.chan.conn; const struct bt_le_conn_param *param; uint16_t min, max, latency, timeout; bool params_valid; struct bt_l2cap_sig_hdr *hdr; struct bt_l2cap_conn_param_rsp *rsp; struct bt_l2cap_conn_param_req *req = (void *)buf->data; if (buf->len < sizeof(*req)) { BT_ERR("Too small LE conn update param req"); return; } if (conn->role != BT_HCI_ROLE_MASTER) { l2cap_send_reject(conn, ident, BT_L2CAP_REJ_NOT_UNDERSTOOD, NULL, 0); return; } min = sys_le16_to_cpu(req->min_interval); max = sys_le16_to_cpu(req->max_interval); latency = sys_le16_to_cpu(req->latency); timeout = sys_le16_to_cpu(req->timeout); param = BT_LE_CONN_PARAM(min, max, latency, timeout); BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x timeout: 0x%4.4x", min, max, latency, timeout); buf = bt_l2cap_create_pdu(&le_sig); if (!buf) { return; } params_valid = bt_le_conn_params_valid(min, max, latency, timeout); hdr = net_buf_add(buf, sizeof(*hdr)); hdr->code = BT_L2CAP_CONN_PARAM_RSP; hdr->ident = ident; hdr->len = sys_cpu_to_le16(sizeof(*rsp)); rsp = net_buf_add(buf, sizeof(*rsp)); if (params_valid) { rsp->result = sys_cpu_to_le16(BT_L2CAP_CONN_PARAM_ACCEPTED); } else { rsp->result = sys_cpu_to_le16(BT_L2CAP_CONN_PARAM_REJECTED); } bt_l2cap_send(l2cap->chan.chan.conn, BT_L2CAP_CID_LE_SIG, buf); if (params_valid) { bt_conn_le_conn_update(conn, param); } }
void bt_l2cap_send(struct bt_conn *conn, uint16_t cid, struct net_buf *buf) { struct bt_l2cap_hdr *hdr; hdr = net_buf_push(buf, sizeof(*hdr)); hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr)); hdr->cid = sys_cpu_to_le16(cid); bt_conn_send(conn, buf); }
static uint8_t *generate_addressing_fields(struct net_if *iface, struct ieee802154_fcf_seq *fs, struct ieee802154_frame_params *params, uint8_t *p_buf) { struct ieee802154_address_field *af; struct ieee802154_address *src_addr; if (fs->fc.dst_addr_mode != IEEE802154_ADDR_MODE_NONE) { af = (struct ieee802154_address_field *)p_buf; af->plain.pan_id = params->dst.pan_id; if (fs->fc.dst_addr_mode == IEEE802154_ADDR_MODE_SHORT) { af->plain.addr.short_addr = sys_cpu_to_le16(params->dst.short_addr); p_buf += IEEE802154_PAN_ID_LENGTH + IEEE802154_SHORT_ADDR_LENGTH; } else { sys_memcpy_swap(af->plain.addr.ext_addr, params->dst.ext_addr, IEEE802154_EXT_ADDR_LENGTH); p_buf += IEEE802154_PAN_ID_LENGTH + IEEE802154_EXT_ADDR_LENGTH; } } if (fs->fc.src_addr_mode == IEEE802154_ADDR_MODE_NONE) { return p_buf; } af = (struct ieee802154_address_field *)p_buf; if (!fs->fc.pan_id_comp) { af->plain.pan_id = params->pan_id; src_addr = &af->plain.addr; p_buf += IEEE802154_PAN_ID_LENGTH; } else { src_addr = &af->comp.addr; } if (fs->fc.src_addr_mode == IEEE802154_ADDR_MODE_SHORT) { src_addr->short_addr = sys_cpu_to_le16(params->short_addr); p_buf += IEEE802154_SHORT_ADDR_LENGTH; } else { sys_memcpy_swap(src_addr->ext_addr, iface->link_addr.addr, IEEE802154_EXT_ADDR_LENGTH); p_buf += IEEE802154_EXT_ADDR_LENGTH; } return p_buf; }
static void le_disconn_req(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_disconn_req *req = (void *)buf->data; struct bt_l2cap_disconn_rsp *rsp; struct bt_l2cap_sig_hdr *hdr; uint16_t scid, dcid; if (buf->len < sizeof(*req)) { BT_ERR("Too small LE conn req packet size"); return; } dcid = sys_le16_to_cpu(req->dcid); scid = sys_le16_to_cpu(req->scid); BT_DBG("scid 0x%04x dcid 0x%04x", dcid, scid); chan = l2cap_remove_tx_cid(conn, scid); if (!chan) { struct bt_l2cap_cmd_reject_cid_data data; data.scid = req->scid; data.dcid = req->dcid; l2cap_send_reject(conn, ident, BT_L2CAP_REJ_INVALID_CID, &data, sizeof(data)); return; } buf = bt_l2cap_create_pdu(&le_sig); if (!buf) { return; } hdr = net_buf_add(buf, sizeof(*hdr)); hdr->code = BT_L2CAP_DISCONN_RSP; hdr->ident = ident; hdr->len = sys_cpu_to_le16(sizeof(*rsp)); rsp = net_buf_add(buf, sizeof(*rsp)); rsp->dcid = sys_cpu_to_le16(chan->rx.cid); rsp->scid = sys_cpu_to_le16(chan->tx.cid); l2cap_chan_del(&chan->chan); bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf); }
static uint8_t find_info_cb(const struct bt_gatt_attr *attr, void *user_data) { struct find_info_data *data = user_data; struct bt_att *att = data->att; BT_DBG("handle 0x%04x", attr->handle); /* Initialize rsp at first entry */ if (!data->rsp) { data->rsp = net_buf_add(data->buf, sizeof(*data->rsp)); data->rsp->format = (attr->uuid->type == BT_UUID_TYPE_16) ? BT_ATT_INFO_16 : BT_ATT_INFO_128; } switch (data->rsp->format) { case BT_ATT_INFO_16: if (attr->uuid->type != BT_UUID_TYPE_16) { return BT_GATT_ITER_STOP; } /* Fast foward to next item position */ data->info16 = net_buf_add(data->buf, sizeof(*data->info16)); data->info16->handle = sys_cpu_to_le16(attr->handle); data->info16->uuid = sys_cpu_to_le16(BT_UUID_16(attr->uuid)->val); if (att->chan.tx.mtu - data->buf->len > sizeof(*data->info16)) { return BT_GATT_ITER_CONTINUE; } break; case BT_ATT_INFO_128: if (attr->uuid->type != BT_UUID_TYPE_128) { return BT_GATT_ITER_STOP; } /* Fast foward to next item position */ data->info128 = net_buf_add(data->buf, sizeof(*data->info128)); data->info128->handle = sys_cpu_to_le16(attr->handle); memcpy(data->info128->uuid, BT_UUID_128(attr->uuid)->val, sizeof(data->info128->uuid)); if (att->chan.tx.mtu - data->buf->len > sizeof(*data->info128)) { return BT_GATT_ITER_CONTINUE; } } return BT_GATT_ITER_STOP; }
static inline void encode_hdr(struct bt_monitor_hdr *hdr, uint16_t opcode, uint16_t len) { uint32_t ts32; hdr->hdr_len = sizeof(hdr->type) + sizeof(hdr->ts32); hdr->data_len = sys_cpu_to_le16(4 + hdr->hdr_len + len); hdr->opcode = sys_cpu_to_le16(opcode); hdr->flags = 0; /* Extended header */ hdr->type = BT_MONITOR_TS32; ts32 = k_uptime_get() * 10; hdr->ts32 = sys_cpu_to_le32(ts32); }
static ssize_t read_stepcadence_feature(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { uint16_t rsc_feature = 0; if (on_ble_rscs_get_stride_lenth() >= 0) { rsc_feature |= 1; } if (on_ble_rscs_get_total_distance() >= 0) { rsc_feature |= 2; } if (on_ble_rscs_get_walk_run() >= 0) { rsc_feature |= 4; } #ifdef CONFIG_BLE_RSCS_MULTIPLE_SENSOR_LOCATION_SUPPORT rsc_feature |= 10; #endif /* other optional elements not yet implemented * - calibration procedure supported: * rsc_feature |= 8; */ rsc_feature = sys_cpu_to_le16(rsc_feature); return bt_gatt_attr_read(conn, attr, buf, len, offset, &rsc_feature, sizeof(rsc_feature)); }
int bt_gatt_write_without_response(struct bt_conn *conn, uint16_t handle, const void *data, uint16_t length, bool sign) { struct net_buf *buf; struct bt_att_write_cmd *cmd; if (!conn || !handle) { return -EINVAL; } if (sign && write_signed_allowed(conn)) { buf = bt_att_create_pdu(conn, BT_ATT_OP_SIGNED_WRITE_CMD, sizeof(*cmd) + length + 12); } else { buf = bt_att_create_pdu(conn, BT_ATT_OP_WRITE_CMD, sizeof(*cmd) + length); } if (!buf) { return -ENOMEM; } cmd = net_buf_add(buf, sizeof(*cmd)); cmd->handle = sys_cpu_to_le16(handle); memcpy(cmd->value, data, length); net_buf_add(buf, length); BT_DBG("handle 0x%04x length %u", handle, length); return gatt_send(conn, buf, NULL, NULL, NULL); }
static void generate_current_time(uint8_t *buf) { uint16_t year; /* 'Exact Time 256' contains 'Day Date Time' which contains * 'Date Time' - characteristic contains fields for: * year, month, day, hours, minutes and seconds. */ year = sys_cpu_to_le16(2015); memcpy(buf, &year, 2); /* year */ buf[2] = 5; /* months starting from 1 */ buf[3] = 30; /* day */ buf[4] = 12; /* hours */ buf[5] = 45; /* minutes */ buf[6] = 30; /* seconds */ /* 'Day of Week' part of 'Day Date Time' */ buf[7] = 1; /* day of week starting from 1 */ /* 'Fractions 256 part of 'Exact Time 256' */ buf[8] = 0; /* Adjust reason */ buf[9] = 0; /* No update, change, etc */ }
ssize_t on_gap_rd_ppcp(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { /* Default values */ struct gap_ppcp ppcp; ppcp.interval_min = sys_cpu_to_le16(MIN_CONN_INTERVAL); ppcp.interval_max = sys_cpu_to_le16(MAX_CONN_INTERVAL); ppcp.slave_latency = sys_cpu_to_le16(SLAVE_LATENCY); ppcp.link_sup_to = sys_cpu_to_le16(CONN_SUP_TIMEOUT); return bt_gatt_attr_read(conn, attr, buf, len, offset, &ppcp, sizeof(ppcp)); }
int bt_gatt_attr_read_ccc(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { struct _bt_gatt_ccc *ccc = attr->user_data; uint16_t value; size_t i; for (i = 0; i < ccc->cfg_len; i++) { if (bt_addr_le_cmp(&ccc->cfg[i].peer, &conn->le.dst)) { continue; } value = sys_cpu_to_le16(ccc->cfg[i].value); break; } /* Default to disable if there is no cfg for the peer */ if (i == ccc->cfg_len) { value = 0x0000; } return bt_gatt_attr_read(conn, attr, buf, len, offset, &value, sizeof(value)); }
int bt_gatt_write(struct bt_conn *conn, uint16_t handle, uint16_t offset, const void *data, uint16_t length, bt_gatt_rsp_func_t func) { struct net_buf *buf; struct bt_att_write_req *req; if (!conn || !handle || !func) { return -EINVAL; } /* Use Prepare Write if offset is set or Long Write is required */ if (offset || length > (bt_att_get_mtu(conn) - sizeof(*req) - 1)) { return gatt_prepare_write(conn, handle, offset, data, length, func); } buf = bt_att_create_pdu(conn, BT_ATT_OP_WRITE_REQ, sizeof(*req) + length); if (!buf) { return -ENOMEM; } req = net_buf_add(buf, sizeof(*req)); req->handle = sys_cpu_to_le16(handle); memcpy(req->value, data, length); net_buf_add(buf, length); BT_DBG("handle 0x%04x length %u", handle, length); return gatt_send(conn, buf, att_write_rsp, func, NULL); }
int bt_gatt_read(struct bt_conn *conn, struct bt_gatt_read_params *params) { struct net_buf *buf; struct bt_att_read_req *req; if (!conn || !params || !params->handle || !params->func || !params->destroy) { return -EINVAL; } if (params->offset) { return gatt_read_blob(conn, params); } buf = bt_att_create_pdu(conn, BT_ATT_OP_READ_REQ, sizeof(*req)); if (!buf) { return -ENOMEM; } req = net_buf_add(buf, sizeof(*req)); req->handle = sys_cpu_to_le16(params->handle); BT_DBG("handle 0x%04x", params->handle); return gatt_send(conn, buf, att_read_rsp, params, NULL); }
static void le_conn_param_update_req(struct bt_l2cap *l2cap, uint8_t ident, struct net_buf *buf) { struct bt_conn *conn = l2cap->chan.chan.conn; struct bt_le_conn_param param; struct bt_l2cap_conn_param_rsp *rsp; struct bt_l2cap_conn_param_req *req = (void *)buf->data; bool accepted; if (buf->len < sizeof(*req)) { BT_ERR("Too small LE conn update param req"); return; } if (conn->role != BT_HCI_ROLE_MASTER) { l2cap_send_reject(conn, ident, BT_L2CAP_REJ_NOT_UNDERSTOOD, NULL, 0); return; } param.interval_min = sys_le16_to_cpu(req->min_interval); param.interval_max = sys_le16_to_cpu(req->max_interval); param.latency = sys_le16_to_cpu(req->latency); param.timeout = sys_le16_to_cpu(req->timeout); BT_DBG("min 0x%04x max 0x%04x latency: 0x%04x timeout: 0x%04x", param.interval_min, param.interval_max, param.latency, param.timeout); buf = l2cap_create_le_sig_pdu(BT_L2CAP_CONN_PARAM_RSP, ident, sizeof(*rsp)); accepted = le_param_req(conn, ¶m); rsp = net_buf_add(buf, sizeof(*rsp)); if (accepted) { rsp->result = sys_cpu_to_le16(BT_L2CAP_CONN_PARAM_ACCEPTED); } else { rsp->result = sys_cpu_to_le16(BT_L2CAP_CONN_PARAM_REJECTED); } bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf); if (accepted) { bt_conn_le_conn_update(conn, ¶m); } }
static int apds9960_ambient_setup(struct device *dev, int gain) { struct apds9960_data *data = dev->driver_data; u16_t th; /* ADC value */ if (i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_ATIME_REG, APDS9960_DEFAULT_ATIME)) { LOG_ERR("Default integration time not set for ADC"); return -EIO; } /* ALS Gain */ if (i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_CONTROL_REG, APDS9960_CONTROL_AGAIN, (gain & APDS9960_AGAIN_64X))) { LOG_ERR("Ambient Gain is not set"); return -EIO; } th = sys_cpu_to_le16(APDS9960_DEFAULT_AILT); if (i2c_burst_write(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_INT_AILTL_REG, (u8_t *)&th, sizeof(th))) { LOG_ERR("ALS low threshold not set"); return -EIO; } th = sys_cpu_to_le16(APDS9960_DEFAULT_AIHT); if (i2c_burst_write(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_INT_AIHTL_REG, (u8_t *)&th, sizeof(th))) { LOG_ERR("ALS low threshold not set"); return -EIO; } /* Enable ALS */ if (i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_ENABLE_REG, APDS9960_ENABLE_AEN, APDS9960_ENABLE_AEN)) { LOG_ERR("ALS is not enabled"); return -EIO; } return 0; }
static ssize_t read_appearance(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { uint16_t appearance = sys_cpu_to_le16(gap_appearance); return bt_gatt_attr_read(conn, attr, buf, len, offset, &appearance, sizeof(appearance)); }
static ssize_t read_u16(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { const uint16_t *u16 = attr->user_data; uint16_t value = sys_cpu_to_le16(*u16); return bt_gatt_attr_read(conn, attr, buf, len, offset, &value, sizeof(value)); }
int bt_l2cap_update_conn_param(struct bt_conn *conn, const struct bt_le_conn_param *param) { struct bt_l2cap_conn_param_req *req; struct net_buf *buf; buf = l2cap_create_le_sig_pdu(BT_L2CAP_CONN_PARAM_REQ, get_ident(), sizeof(*req)); req = net_buf_add(buf, sizeof(*req)); req->min_interval = sys_cpu_to_le16(param->interval_min); req->max_interval = sys_cpu_to_le16(param->interval_max); req->latency = sys_cpu_to_le16(param->latency); req->timeout = sys_cpu_to_le16(param->timeout); bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf); return 0; }
int bt_gatt_attr_read_cep(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { struct bt_gatt_cep *value = attr->user_data; uint16_t props = sys_cpu_to_le16(value->properties); return bt_gatt_attr_read(conn, attr, buf, len, offset, &props, sizeof(props)); }
static int gatt_read_blob(struct bt_conn *conn, struct bt_gatt_read_params *params) { struct net_buf *buf; struct bt_att_read_blob_req *req; buf = bt_att_create_pdu(conn, BT_ATT_OP_READ_BLOB_REQ, sizeof(*req)); if (!buf) { return -ENOMEM; } req = net_buf_add(buf, sizeof(*req)); req->handle = sys_cpu_to_le16(params->handle); req->offset = sys_cpu_to_le16(params->offset); BT_DBG("handle 0x%04x offset 0x%04x", params->handle, params->offset); return gatt_send(conn, buf, att_read_rsp, params, NULL); }
int bt_l2cap_chan_disconnect(struct bt_l2cap_chan *chan) { struct bt_conn *conn = chan->conn; struct net_buf *buf; struct bt_l2cap_disconn_req *req; struct bt_l2cap_sig_hdr *hdr; struct bt_l2cap_le_chan *ch; if (!conn) { return -ENOTCONN; } #if defined(CONFIG_BLUETOOTH_BREDR) if (conn->type == BT_CONN_TYPE_BR) { return bt_l2cap_br_chan_disconnect(chan); } #endif /* CONFIG_BLUETOOTH_BREDR */ ch = LE_CHAN(chan); BT_DBG("chan %p scid 0x%04x dcid 0x%04x", chan, ch->rx.cid, ch->tx.cid); buf = bt_l2cap_create_pdu(&le_sig); if (!buf) { BT_ERR("Unable to send L2CP disconnect request"); return -ENOMEM; } hdr = net_buf_add(buf, sizeof(*hdr)); hdr->code = BT_L2CAP_DISCONN_REQ; hdr->ident = get_ident(); hdr->len = sys_cpu_to_le16(sizeof(*req)); req = net_buf_add(buf, sizeof(*req)); req->dcid = sys_cpu_to_le16(ch->tx.cid); req->scid = sys_cpu_to_le16(ch->rx.cid); bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf); return 0; }
static int att_find_info(struct bt_conn *conn, struct bt_gatt_discover_params *params) { struct net_buf *buf; struct bt_att_find_info_req *req; buf = bt_att_create_pdu(conn, BT_ATT_OP_FIND_INFO_REQ, sizeof(*req)); if (!buf) { return -ENOMEM; } req = net_buf_add(buf, sizeof(*req)); req->start_handle = sys_cpu_to_le16(params->start_handle); req->end_handle = sys_cpu_to_le16(params->end_handle); BT_DBG("start_handle 0x%04x end_handle 0x%04x", params->start_handle, params->end_handle); return gatt_send(conn, buf, att_find_info_rsp, params, NULL); }