static void report_map_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { struct hog_device *hogdev = user_data; uint8_t value[HOG_REPORT_MAP_MAX_SIZE]; struct uhid_event ev; uint16_t vendor_src, vendor, product, version; ssize_t vlen; int i; if (status != 0) { error("Report Map read failed: %s", att_ecode2str(status)); return; } vlen = dec_read_resp(pdu, plen, value, sizeof(value)); if (vlen < 0) { error("ATT protocol error"); return; } DBG("Report MAP:"); for (i = 0; i < vlen; i++) { switch (value[i]) { case 0x85: case 0x86: case 0x87: hogdev->prepend_id = TRUE; } if (i % 2 == 0) { if (i + 1 == vlen) DBG("\t %02x", value[i]); else DBG("\t %02x %02x", value[i], value[i + 1]); } } vendor_src = btd_device_get_vendor_src(hogdev->device); vendor = btd_device_get_vendor(hogdev->device); product = btd_device_get_product(hogdev->device); version = btd_device_get_version(hogdev->device); DBG("DIS information: vendor_src=0x%X, vendor=0x%X, product=0x%X, " "version=0x%X", vendor_src, vendor, product, version); /* create uHID device */ memset(&ev, 0, sizeof(ev)); ev.type = UHID_CREATE; strcpy((char *) ev.u.create.name, "bluez-hog-device"); ev.u.create.vendor = vendor; ev.u.create.product = product; ev.u.create.version = version; ev.u.create.country = hogdev->bcountrycode; ev.u.create.bus = BUS_BLUETOOTH; ev.u.create.rd_data = value; ev.u.create.rd_size = vlen; if (write(hogdev->uhid_fd, &ev, sizeof(ev)) < 0) error("Failed to create uHID device: %s", strerror(errno)); }
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { uint8_t value[plen]; ssize_t vlen; int i; GString *s; if (status != 0) { printf("Characteristic value/descriptor read failed: %s\n", att_ecode2str(status)); goto label; } vlen = dec_read_resp(pdu, plen, value, sizeof(value)); if (vlen < 0) { printf("Protocol error\n"); goto label; } s = g_string_new("Characteristic value/descriptor: "); for (i = 0; i < vlen; i++) { g_string_append_printf(s, "%02x ", value[i]); } printf("%s\n", s->str); g_string_free(s, TRUE); label: g_main_loop_quit(event_loop); return; }
static void resolve_included_uuid_cb(uint8_t status, const uint8_t *pdu, uint16_t len, gpointer user_data) { struct included_uuid_query *query = user_data; struct included_discovery *isd = query->isd; struct gatt_included *incl = query->included; unsigned int err = status; bt_uuid_t uuid; size_t buflen; uint8_t *buf; if (err) goto done; buf = g_attrib_get_buffer(isd->attrib, &buflen); if (dec_read_resp(pdu, len, buf, buflen) != 16) { err = ATT_ECODE_IO; goto done; } uuid = att_get_uuid128(buf); bt_uuid_to_string(&uuid, incl->uuid, sizeof(incl->uuid)); isd->includes = g_slist_append(isd->includes, incl); done: if (err) g_free(incl); if (isd->err == 0) isd->err = err; isd_unref(isd); g_free(query); }
static void read_feature_cb(guint8 status, const guint8 *pdu, guint16 len, gpointer user_data) { struct csc *csc = user_data; uint8_t value[2]; ssize_t vlen; if (status) { error("CSC Feature read failed: %s", att_ecode2str(status)); return; } vlen = dec_read_resp(pdu, len, value, sizeof(value)); if (vlen < 0) { error("Protocol error"); return; } if (vlen != sizeof(value)) { error("Invalid value length for CSC Feature"); return; } csc->feature = get_le16(value); if ((csc->feature & MULTI_SENSOR_LOC_SUPPORT) && (csc->locations == NULL)) read_supported_locations(csc); }
static void read_sensor_location_cb(guint8 status, const guint8 *pdu, guint16 len, gpointer user_data) { struct heartrate *hr = user_data; uint8_t value; ssize_t vlen; if (status != 0) { error("Body Sensor Location read failed: %s", att_ecode2str(status)); return; } vlen = dec_read_resp(pdu, len, &value, sizeof(value)); if (vlen < 0) { error("Protocol error"); return; } if (vlen != sizeof(value)) { error("Invalid length for Body Sensor Location"); return; } hr->has_location = TRUE; hr->location = value; }
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { uint8_t value[ATT_MAX_MTU]; int i, vlen; if (status != 0) { printf("Characteristic value/descriptor read failed: %s\n", att_ecode2str(status)); goto done; } if (!dec_read_resp(pdu, plen, value, &vlen)) { printf("Protocol error\n"); goto done; } printf("\nCharacteristic value/descriptor: "); for (i = 0; i < vlen; i++) printf("%02x ", value[i]); done: printf("\n%s", get_prompt()); fflush(stdout); }
static void read_location_cb(guint8 status, const guint8 *pdu, guint16 len, gpointer user_data) { struct csc *csc = user_data; uint8_t value; ssize_t vlen; if (status) { error("Sensor Location read failed: %s", att_ecode2str(status)); return; } vlen = dec_read_resp(pdu, len, &value, sizeof(value)); if (vlen < 0) { error("Protocol error"); return; } if (vlen != sizeof(value)) { error("Invalid value length for Sensor Location"); return; } csc->has_location = TRUE; csc->location = value; g_dbus_emit_property_changed(btd_get_dbus_connection(), device_get_path(csc->dev), CYCLINGSPEED_INTERFACE, "Location"); }
static void proto_mode_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { struct hog_device *hogdev = user_data; uint8_t value; ssize_t vlen; if (status != 0) { error("Protocol Mode characteristic read failed: %s", att_ecode2str(status)); return; } vlen = dec_read_resp(pdu, plen, &value, sizeof(value)); if (vlen < 0) { error("ATT protocol error"); return; } if (value == HOG_PROTO_MODE_BOOT) { uint8_t nval = HOG_PROTO_MODE_REPORT; DBG("HoG device 0x%04X is operating in Boot Procotol Mode", hogdev->id); gatt_write_cmd(hogdev->attrib, hogdev->proto_mode_handle, &nval, sizeof(nval), NULL, NULL); } else if (value == HOG_PROTO_MODE_REPORT) DBG("HoG device 0x%04X is operating in Report Protocol Mode", hogdev->id); }
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { uint8_t value[ATT_MAX_MTU]; ssize_t vlen; int i; if (status != 0) { g_printerr("Characteristic value/descriptor read failed: %s\n", att_ecode2str(status)); goto done; } vlen = dec_read_resp(pdu, plen, value, sizeof(value)); if (vlen < 0) { g_printerr("Protocol error\n"); goto done; } g_print("Characteristic value/descriptor: "); for (i = 0; i < vlen; i++) g_print("%02x ", value[i]); g_print("\n"); done: if (opt_listen == FALSE) g_main_loop_quit(event_loop); }
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { uint8_t value[plen]; ssize_t vlen; int i; GString *s; if (status != 0) { error("Characteristic value/descriptor read failed: %s\n", att_ecode2str(status)); return; } vlen = dec_read_resp(pdu, plen, value, sizeof(value)); if (vlen < 0) { error("Protocol error\n"); return; } //rl_printf("%d\n",vlen); //rl_printf("%d\n",value[0]); //s = g_string_new("Characteristic value/descriptor: "); for (i = 0; i < vlen; i++) { //data[i] = value[i]; //g_string_append_printf(s, "%02x ", value[i]); } //pocessing_data(data); //rl_printf("%s\n", s->str); //g_string_free(s, TRUE); }
static void read_pnpid_cb(guint8 status, const guint8 *pdu, guint16 len, gpointer user_data) { struct characteristic *ch = user_data; uint8_t value[ATT_MAX_MTU]; int vlen; if (status != 0) { error("Error reading PNP_ID value: %s", att_ecode2str(status)); return; } if (!dec_read_resp(pdu, len, value, &vlen)) { error("Error reading PNP_ID: Protocol error"); return; } if (vlen < 7) { error("Error reading PNP_ID: Invalid pdu length received"); return; } device_set_pnpid(ch->d->dev, value[0], att_get_u16(&value[1]), att_get_u16(&value[3]), att_get_u16(&value[5])); }
static void read_pnpid_cb(guint8 status, const guint8 *pdu, guint16 len, gpointer user_data) { struct characteristic *ch = user_data; uint8_t value[PNP_ID_SIZE]; ssize_t vlen; 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; } btd_device_set_pnpid(ch->d->dev, value[0], get_le16(&value[1]), get_le16(&value[3]), get_le16(&value[5])); }
static void info_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { struct hog_device *hogdev = user_data; uint8_t value[HID_INFO_SIZE]; ssize_t vlen; if (status != 0) { error("HID Information read failed: %s", att_ecode2str(status)); return; } vlen = dec_read_resp(pdu, plen, value, sizeof(value)); if (vlen != 4) { error("ATT protocol error"); return; } hogdev->bcdhid = get_le16(&value[0]); hogdev->bcountrycode = value[2]; hogdev->flags = value[3]; DBG("bcdHID: 0x%04X bCountryCode: 0x%02X Flags: 0x%02X", hogdev->bcdhid, hogdev->bcountrycode, hogdev->flags); }
static void char_read_single_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { uint8_t value[plen]; ssize_t vlen; if (status != 0) { resp_error_comm(status); return; } if ((pdu != NULL) && (plen >= 1)) { if (pdu[0] == ATT_OP_READ_RESP) vlen = dec_read_resp(pdu, plen, value, sizeof(value)); else vlen = dec_read_blob_resp(pdu, plen, value, sizeof(value)); } else { vlen = -EINVAL; } if (vlen < 0) { resp_error(err_PROTO_ERR); return; } resp_begin(rsp_READ); send_data(value, vlen); resp_end(); }
void read_by_hnd_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { uint8_t data[plen]; ssize_t vlen; cb_ctx_t *cb_ctx = user_data; printf_dbg("[CB] IN read_by_hnd_cb\n"); if (status) { cb_ctx->cb_ret_val = BL_REQUEST_FAIL_ERROR; sprintf(cb_ctx->cb_ret_msg, "Read by handle callback: Failure: %s\n", att_ecode2str(status)); goto error; } if (data == NULL) { cb_ctx->cb_ret_val = BL_MALLOC_ERROR; strcpy(cb_ctx->cb_ret_msg, "Read by handle callback: Malloc error\n"); goto error; } vlen = dec_read_resp(pdu, plen, data, sizeof(data)); if (vlen < 0) { cb_ctx->cb_ret_val = BL_PROTOCOL_ERROR; strcpy(cb_ctx->cb_ret_msg, "Read by handle callback: Protocol error\n"); goto error; } cb_ctx->cb_ret_pointer = bl_value_new(NULL, 0, vlen, data); if (cb_ctx->cb_ret_pointer == NULL) { cb_ctx->cb_ret_val = BL_MALLOC_ERROR; strcpy(cb_ctx->cb_ret_msg, "Read by handle callback: Malloc error\n"); } cb_ctx->cb_ret_val = BL_NO_ERROR; goto exit; error: if (cb_ctx->cb_ret_pointer) free(cb_ctx->cb_ret_pointer); exit: g_mutex_unlock(&cb_ctx->pending_cb_mtx); printf_dbg("[CB] OUT read_by_hnd_cb\n"); }
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { if (status != 0) { error("Characteristic value/descriptor read failed: %s\n", att_ecode2str(status)); return; } uint8_t value[plen]; ssize_t vlen = dec_read_resp(pdu, plen, value, sizeof(value)); if (vlen < 0) { error("Protocol error\n"); return; } handle_vehicle_msg_response(value, vlen); }
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { uint8_t value[plen]; ssize_t vlen; if (status != 0) { resp_error(err_COMM_ERR); // Todo: status return; } vlen = dec_read_resp(pdu, plen, value, sizeof(value)); if (vlen < 0) { resp_error(err_COMM_ERR); return; } resp_begin(rsp_READ); send_data(value, vlen); resp_end(); }
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 tx_power_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { uint8_t value[ATT_MAX_MTU]; int vlen; if (status != 0) { DBG("Tx Power Level read failed: %s", att_ecode2str(status)); return; } if (!dec_read_resp(pdu, plen, value, &vlen)) { DBG("Protocol error"); return; } if (vlen != 1) { DBG("Invalid length for TX Power value: %d", vlen); return; } DBG("Tx Power Level: %02x", (int8_t) value[0]); }
//callback function for when we receive a ble message static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { uint8_t value[plen]; ssize_t vlen; if (status != 0) { printf("Characteristic value/descriptor read failed: %s\n", att_ecode2str(status)); ble_disconnect(); return; } vlen = dec_read_resp(pdu, plen, value, sizeof(value)); if (vlen < 0) { printf("Protocol error\n"); ble_disconnect(); return; } ble_read_val = value; ble_read_len = vlen; ble_read = 1; }
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { uint8_t value[ATT_MAX_MTU]; int i, vlen; if (status != 0) { printf("Characteristic value/descriptor read failed: %s\n", att_ecode2str(status)); return; } if (!dec_read_resp(pdu, plen, value, &vlen)) { printf("Protocol error\n"); return; } printf("\nCharacteristic value/descriptor: "); for (i = 0; i < vlen; i++) printf("%02x ", value[i]); printf("\n"); rl_forced_update_display(); }
static void tx_power_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { uint8_t value[TX_POWER_SIZE]; ssize_t vlen; if (status != 0) { DBG("Tx Power Level read failed: %s", att_ecode2str(status)); return; } vlen = dec_read_resp(pdu, plen, value, sizeof(value)); if (vlen < 0) { DBG("Protocol error"); return; } if (vlen != 1) { DBG("Invalid length for TX Power value: %zd", vlen); return; } DBG("Tx Power Level: %02x", (int8_t) value[0]); }
static void report_map_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { struct hog_device *hogdev = user_data; struct btd_adapter *adapter = device_get_adapter(hogdev->device); uint8_t value[HOG_REPORT_MAP_MAX_SIZE]; struct uhid_event ev; uint16_t vendor_src, vendor, product, version; ssize_t vlen; char itemstr[20]; /* 5x3 (data) + 4 (continuation) + 1 (null) */ int i, err; if (status != 0) { error("Report Map read failed: %s", att_ecode2str(status)); return; } vlen = dec_read_resp(pdu, plen, value, sizeof(value)); if (vlen < 0) { error("ATT protocol error"); return; } DBG("Report MAP:"); for (i = 0; i < vlen;) { ssize_t ilen = 0; bool long_item = false; if (get_descriptor_item_info(&value[i], vlen - i, &ilen, &long_item)) { /* Report ID is short item with prefix 100001xx */ if (!long_item && (value[i] & 0xfc) == 0x84) hogdev->has_report_id = TRUE; DBG("\t%s", item2string(itemstr, &value[i], ilen)); i += ilen; } else { error("Report Map parsing failed at %d", i); /* Just print remaining items at once and break */ DBG("\t%s", item2string(itemstr, &value[i], vlen - i)); break; } } vendor_src = btd_device_get_vendor_src(hogdev->device); vendor = btd_device_get_vendor(hogdev->device); product = btd_device_get_product(hogdev->device); version = btd_device_get_version(hogdev->device); DBG("DIS information: vendor_src=0x%X, vendor=0x%X, product=0x%X, " "version=0x%X", vendor_src, vendor, product, version); /* create uHID device */ memset(&ev, 0, sizeof(ev)); ev.type = UHID_CREATE; if (device_name_known(hogdev->device)) device_get_name(hogdev->device, (char *) ev.u.create.name, sizeof(ev.u.create.name)); else strcpy((char *) ev.u.create.name, "bluez-hog-device"); ba2str(btd_adapter_get_address(adapter), (char *) ev.u.create.phys); ba2str(device_get_address(hogdev->device), (char *) ev.u.create.uniq); ev.u.create.vendor = vendor; ev.u.create.product = product; ev.u.create.version = version; ev.u.create.country = hogdev->bcountrycode; ev.u.create.bus = BUS_BLUETOOTH; ev.u.create.rd_data = value; ev.u.create.rd_size = vlen; err = bt_uhid_send(hogdev->uhid, &ev); if (err < 0) { error("bt_uhid_send: %s", strerror(-err)); return; } bt_uhid_register(hogdev->uhid, UHID_OUTPUT, forward_report, hogdev); bt_uhid_register(hogdev->uhid, UHID_SET_REPORT, set_report, hogdev); bt_uhid_register(hogdev->uhid, UHID_GET_REPORT, get_report, hogdev); }
static void report_map_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { struct bt_hog *hog = user_data; uint8_t value[HOG_REPORT_MAP_MAX_SIZE]; struct uhid_event ev; ssize_t vlen; char itemstr[20]; /* 5x3 (data) + 4 (continuation) + 1 (null) */ int i, err; GError *gerr = NULL; if (status != 0) { error("Report Map read failed: %s", att_ecode2str(status)); return; } vlen = dec_read_resp(pdu, plen, value, sizeof(value)); if (vlen < 0) { error("ATT protocol error"); return; } DBG("Report MAP:"); for (i = 0; i < vlen;) { ssize_t ilen = 0; bool long_item = false; if (get_descriptor_item_info(&value[i], vlen - i, &ilen, &long_item)) { /* Report ID is short item with prefix 100001xx */ if (!long_item && (value[i] & 0xfc) == 0x84) hog->has_report_id = TRUE; DBG("\t%s", item2string(itemstr, &value[i], ilen)); i += ilen; } else { error("Report Map parsing failed at %d", i); /* Just print remaining items at once and break */ DBG("\t%s", item2string(itemstr, &value[i], vlen - i)); break; } } /* create uHID device */ memset(&ev, 0, sizeof(ev)); ev.type = UHID_CREATE; bt_io_get(g_attrib_get_channel(hog->attrib), &gerr, BT_IO_OPT_SOURCE, ev.u.create.phys, BT_IO_OPT_DEST, ev.u.create.uniq, BT_IO_OPT_INVALID); if (gerr) { error("Failed to connection details: %s", gerr->message); g_error_free(gerr); return; } strcpy((char *) ev.u.create.name, hog->name); ev.u.create.vendor = hog->vendor; ev.u.create.product = hog->product; ev.u.create.version = hog->version; ev.u.create.country = hog->bcountrycode; ev.u.create.bus = BUS_BLUETOOTH; ev.u.create.rd_data = value; ev.u.create.rd_size = vlen; err = bt_uhid_send(hog->uhid, &ev); if (err < 0) { error("bt_uhid_send: %s", strerror(-err)); return; } bt_uhid_register(hog->uhid, UHID_OUTPUT, forward_report, hog); bt_uhid_register(hog->uhid, UHID_FEATURE, forward_report, hog); }