static void bas_discovered_cb(uint8_t status, GSList *chars, void *user_data) { struct gatt_request *req = user_data; struct bt_bas *bas = req->user_data; struct gatt_char *chr; uint16_t start, end; bt_uuid_t uuid; destroy_gatt_req(req); if (status) { error("Battery: %s", att_ecode2str(status)); return; } chr = chars->data; bas->handle = chr->value_handle; DBG("Battery handle: 0x%04x", bas->handle); read_char(bas, bas->attrib, bas->handle, read_value_cb, bas); start = chr->value_handle + 1; end = bas->primary->range.end; bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID); discover_desc(bas, bas->attrib, start, end, &uuid, discover_descriptor_cb, bas); }
static void configure_deviceinfo_cb(uint8_t status, GSList *characteristics, void *user_data) { struct gatt_request *req = user_data; struct bt_dis *d = req->user_data; GSList *l; destroy_gatt_req(req); if (status != 0) { error("Discover deviceinfo characteristics: %s", att_ecode2str(status)); return; } for (l = characteristics; l; l = l->next) { struct gatt_char *c = l->data; if (strcmp(c->uuid, PNPID_UUID) == 0) { d->handle = c->value_handle; read_char(d, d->attrib, d->handle, read_pnpid_cb, d); break; } } }
static void ccc_read_cb(guint8 status, const guint8 *pdu, guint16 len, gpointer user_data) { struct gatt_request *req = user_data; struct bt_bas *bas = req->user_data; destroy_gatt_req(req); if (status != 0) { error("Error reading CCC value: %s", att_ecode2str(status)); return; } write_ccc(bas, bas->attrib, bas->ccc_handle, bas); }
static void discover_descriptor_cb(uint8_t status, GSList *descs, void *user_data) { struct gatt_request *req = user_data; struct bt_scpp *scan = req->user_data; struct gatt_desc *desc; destroy_gatt_req(req); if (status != 0) { error("Discover descriptors failed: %s", att_ecode2str(status)); return; } /* There will be only one descriptor on list and it will be CCC */ desc = descs->data; write_ccc(scan, scan->attrib, desc->handle, scan); }
static void discover_descriptor_cb(uint8_t status, GSList *descs, void *user_data) { struct gatt_request *req = user_data; struct bt_bas *bas = req->user_data; struct gatt_desc *desc; destroy_gatt_req(req); if (status != 0) { error("Discover descriptors failed: %s", att_ecode2str(status)); return; } /* There will be only one descriptor on list and it will be CCC */ desc = descs->data; bas->ccc_handle = desc->handle; read_char(bas, bas->attrib, desc->handle, ccc_read_cb, bas); }
static void ccc_written_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { struct gatt_request *req = user_data; struct bt_bas *bas = req->user_data; destroy_gatt_req(req); if (status != 0) { error("Write Scan Refresh CCC failed: %s", att_ecode2str(status)); return; } DBG("Battery Level: notification enabled"); bas->id = g_attrib_register(bas->attrib, ATT_OP_HANDLE_NOTIFY, bas->handle, notification_cb, bas, NULL); }
static void ccc_written_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { struct gatt_request *req = user_data; struct bt_scpp *scan = req->user_data; destroy_gatt_req(req); if (status != 0) { error("Write Scan Refresh CCC failed: %s", att_ecode2str(status)); return; } DBG("Scan Refresh: notification enabled"); scan->refresh_cb_id = g_attrib_register(scan->attrib, ATT_OP_HANDLE_NOTIFY, scan->refresh_handle, refresh_value_cb, scan, NULL); }
static void iwin_discovered_cb(uint8_t status, GSList *chars, void *user_data) { struct gatt_request *req = user_data; struct bt_scpp *scan = req->user_data; struct gatt_char *chr; destroy_gatt_req(req); if (status) { error("Discover Scan Interval Window: %s", att_ecode2str(status)); return; } chr = chars->data; scan->iwhandle = chr->value_handle; DBG("Scan Interval Window handle: 0x%04x", scan->iwhandle); write_scan_params(scan->attrib, scan->iwhandle, scan->interval, scan->window); }
static void refresh_discovered_cb(uint8_t status, GSList *chars, void *user_data) { struct gatt_request *req = user_data; struct bt_scpp *scan = req->user_data; struct gatt_char *chr; uint16_t start, end; bt_uuid_t uuid; destroy_gatt_req(req); if (status) { error("Scan Refresh %s", att_ecode2str(status)); return; } if (!chars) { DBG("Scan Refresh not supported"); return; } chr = chars->data; DBG("Scan Refresh handle: 0x%04x", chr->value_handle); start = chr->value_handle + 1; end = scan->primary->range.end; if (start > end) return; scan->refresh_handle = chr->value_handle; bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID); discover_desc(scan, scan->attrib, start, end, &uuid, discover_descriptor_cb, user_data); }
static void read_pnpid_cb(guint8 status, const guint8 *pdu, guint16 len, gpointer user_data) { struct gatt_request *req = user_data; struct bt_dis *dis = req->user_data; uint8_t value[PNP_ID_SIZE]; ssize_t vlen; destroy_gatt_req(req); if (status != 0) { error("Error reading PNP_ID value: %s", att_ecode2str(status)); return; } vlen = dec_read_resp(pdu, len, value, sizeof(value)); if (vlen < 0) { error("Error reading PNP_ID: Protocol error"); return; } if (vlen < 7) { error("Error reading PNP_ID: Invalid pdu length received"); return; } dis->source = value[0]; dis->vendor = get_le16(&value[1]); dis->product = get_le16(&value[3]); dis->version = get_le16(&value[5]); DBG("source: 0x%02X vendor: 0x%04X product: 0x%04X version: 0x%04X", dis->source, dis->vendor, dis->product, dis->version); if (dis->notify) dis->notify(dis->source, dis->vendor, dis->product, dis->version, dis->notify_data); }
static void cancel_gatt_req(struct gatt_request *req) { if (g_attrib_cancel(req->bas->attrib, req->id)) destroy_gatt_req(req); }