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 discover_char_cb(uint8_t status, GSList *chars, void *user_data) { struct heartrate *hr = user_data; if (status) { error("Discover HRS characteristics failed: %s", att_ecode2str(status)); return; } for (; chars; chars = chars->next) { struct gatt_char *c = chars->data; if (g_strcmp0(c->uuid, HEART_RATE_MEASUREMENT_UUID) == 0) { struct gatt_char *c_next = (chars->next ? chars->next->data : NULL); hr->attionotid = g_attrib_register(hr->attrib, ATT_OP_HANDLE_NOTIFY, c->value_handle, notify_handler, hr, NULL); discover_measurement_ccc(hr, c, c_next); } else if (g_strcmp0(c->uuid, BODY_SENSOR_LOCATION_UUID) == 0) { DBG("Body Sensor Location supported"); gatt_read_char(hr->attrib, c->value_handle, read_sensor_location_cb, hr); } else if (g_strcmp0(c->uuid, HEART_RATE_CONTROL_POINT_UUID) == 0) { DBG("Heart Rate Control Point supported"); hr->hrcp_val_handle = c->value_handle; } } }
static void exchange_mtu_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { uint16_t mtu; if (status != 0) { printf("Exchange MTU Request failed: %s\n", att_ecode2str(status)); goto done; } if (!dec_mtu_resp(pdu, plen, &mtu)) { printf("Protocol error\n"); goto done; } mtu = MIN(mtu, opt_mtu); /* Set new value for MTU in client */ if (g_attrib_set_mtu(attrib, mtu)) printf("MTU was exchanged successfully: %d\n", mtu); else printf("Error exchanging MTU\n"); done: printf("\r%s", get_prompt()); fflush(stdout); }
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 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 refresh_discovered_cb(uint8_t status, GSList *chars, void *user_data) { struct scan *scan = user_data; struct gatt_char *chr; uint16_t start, end; bt_uuid_t uuid; 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->range.end; if (start > end) return; scan->refresh_handle = chr->value_handle; bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID); gatt_discover_desc(scan->attrib, start, end, &uuid, discover_descriptor_cb, user_data); }
static void external_service_char_cb(uint8_t status, GSList *chars, void *user_data) { struct bt_hog *hog = user_data; struct gatt_primary *primary = hog->primary; struct report *report; GSList *l; if (status != 0) { const char *str = att_ecode2str(status); DBG("Discover external service characteristic failed: %s", str); return; } for (l = chars; l; l = g_slist_next(l)) { struct gatt_char *chr, *next; uint16_t start, end; chr = l->data; next = l->next ? l->next->data : NULL; DBG("0x%04x UUID: %s properties: %02x", chr->handle, chr->uuid, chr->properties); report = report_new(hog, chr); start = chr->value_handle + 1; end = (next ? next->handle - 1 : primary->range.end); discover_report(hog->attrib, start, end, report); } }
static void external_service_char_cb(uint8_t status, GSList *chars, void *user_data) { struct hog_device *hogdev = user_data; struct gatt_primary *prim = hogdev->hog_primary; struct report *report; GSList *l; if (status != 0) { const char *str = att_ecode2str(status); DBG("Discover external service characteristic failed: %s", str); return; } for (l = chars; l; l = g_slist_next(l)) { struct gatt_char *chr, *next; uint16_t start, end; chr = l->data; next = l->next ? l->next->data : NULL; DBG("0x%04x UUID: %s properties: %02x", chr->handle, chr->uuid, chr->properties); report = g_new0(struct report, 1); report->hogdev = hogdev; report->decl = g_memdup(chr, sizeof(*chr)); hogdev->reports = g_slist_append(hogdev->reports, report); start = chr->value_handle + 1; end = (next ? next->handle - 1 : prim->range.end); discover_descriptor(hogdev->attrib, start, end, report); } }
static void report_reference_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { struct report *report = user_data; if (status != 0) { error("Read Report Reference descriptor failed: %s", att_ecode2str(status)); return; } if (plen != 3) { error("Malformed ATT read response"); return; } report->id = pdu[1]; report->type = pdu[2]; DBG("Report ID: 0x%02x Report type: 0x%02x", pdu[1], pdu[2]); /* Enable notifications only for Input Reports */ if (report->type == HOG_REPORT_TYPE_INPUT) gatt_read_char(report->hog->attrib, report->ccc_handle, ccc_read_cb, report); }
static void discover_report_cb(uint8_t status, GSList *descs, void *user_data) { struct report *report = user_data; struct bt_hog *hog = report->hog; if (status != 0) { error("Discover report descriptors failed: %s", att_ecode2str(status)); return; } for ( ; descs; descs = descs->next) { struct gatt_desc *desc = descs->data; switch (desc->uuid16) { case GATT_CLIENT_CHARAC_CFG_UUID: report->ccc_handle = desc->handle; break; case GATT_REPORT_REFERENCE: gatt_read_char(hog->attrib, desc->handle, report_reference_cb, report); break; } } }
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 external_service_char_cb(GSList *chars, guint8 status, gpointer user_data) { struct hog_device *hogdev = user_data; struct report *report; GSList *l; if (status != 0) { const char *str = att_ecode2str(status); DBG("Discover external service characteristic failed: %s", str); return; } for (l = chars; l; l = g_slist_next(l)) { struct gatt_char *chr, *next; chr = l->data; next = l->next ? l->next->data : NULL; DBG("0x%04x UUID: %s properties: %02x", chr->handle, chr->uuid, chr->properties); report = g_new0(struct report, 1); report->hogdev = hogdev; report->decl = g_memdup(chr, sizeof(*chr)); hogdev->reports = g_slist_append(hogdev->reports, report); discover_descriptor(hogdev->attrib, chr, next, report); } }
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 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 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; } s = g_string_new("Characteristic value/descriptor: "); for (i = 0; i < vlen; i++) g_string_append_printf(s, "%02x ", value[i]); rl_printf("%s\n", s->str); g_string_free(s, TRUE); }
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_by_uuid_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { struct att_data_list *list; int i; GString *s; if (status != 0) { error("Read characteristics by UUID failed: %s\n", att_ecode2str(status)); return; } list = dec_read_by_type_resp(pdu, plen); if (list == NULL) return; s = g_string_new(NULL); for (i = 0; i < list->num; i++) { uint8_t *value = list->data[i]; int j; g_string_printf(s, "handle: 0x%04x \t value: ", att_get_u16(value)); value += 2; for (j = 0; j < list->len - 2; j++, value++) g_string_append_printf(s, "%02x ", *value); rl_printf("%s\n", s->str); } att_data_list_free(list); g_string_free(s, TRUE); }
static void external_report_reference_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { struct hog_device *hogdev = user_data; uint16_t uuid16; bt_uuid_t uuid; if (status != 0) { error("Read External Report Reference descriptor failed: %s", att_ecode2str(status)); return; } if (plen != 3) { error("Malformed ATT read response"); return; } uuid16 = get_le16(&pdu[1]); DBG("External report reference read, external report characteristic " "UUID: 0x%04x", uuid16); bt_uuid16_create(&uuid, uuid16); gatt_discover_char(hogdev->attrib, 0x0001, 0xffff, &uuid, external_service_char_cb, hogdev); }
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 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 configure_deviceinfo_cb(GSList *characteristics, guint8 status, gpointer user_data) { struct deviceinfo *d = user_data; GSList *l; 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; struct characteristic *ch; ch = g_new0(struct characteristic, 1); ch->attr.handle = c->handle; ch->attr.properties = c->properties; ch->attr.value_handle = c->value_handle; memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1); ch->d = d; d->chars = g_slist_append(d->chars, ch); process_deviceinfo_char(ch); } }
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 char_read_by_uuid_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { struct att_data_list *list; int i; if (status != 0) { g_printerr("Read characteristics by UUID failed: %s\n", att_ecode2str(status)); goto done; } list = dec_read_by_type_resp(pdu, plen); if (list == NULL) goto done; for (i = 0; i < list->num; i++) { uint8_t *value = list->data[i]; int j; g_print("handle: 0x%04x \t value: ", get_le16(value)); value += 2; for (j = 0; j < list->len - 2; j++, value++) g_print("%02x ", *value); g_print("\n"); } att_data_list_free(list); done: g_main_loop_quit(event_loop); }
static void discover_ccc_cb(uint8_t status, GSList *descs, void *user_data) { struct heartrate *hr = user_data; struct gatt_desc *desc; uint8_t attr_val[2]; char *msg; if (status != 0) { error("Discover Heart Rate Measurement descriptors failed: %s", att_ecode2str(status)); return; } /* There will be only one descriptor on list and it will be CCC */ desc = descs->data; hr->measurement_ccc_handle = desc->handle; if (g_slist_length(hr->hradapter->watchers) == 0) { put_le16(0x0000, attr_val); msg = g_strdup("Disable measurement"); } else { put_le16(GATT_CLIENT_CHARAC_CFG_NOTIF_BIT, attr_val); msg = g_strdup("Enable measurement"); } gatt_write_char(hr->attrib, desc->handle, attr_val, sizeof(attr_val), char_write_cb, msg); }
void write_req_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { cb_ctx_t *cb_ctx = user_data; printf_dbg("[CB] IN write_req_cb\n"); if (status) { cb_ctx->cb_ret_val = BL_REQUEST_FAIL_ERROR; sprintf(cb_ctx->cb_ret_msg, "Write request callback: Failure: %s\n", att_ecode2str(status)); goto end; } if (!dec_write_resp(pdu, plen) && !dec_exec_write_resp(pdu, plen)) { cb_ctx->cb_ret_val = BL_PROTOCOL_ERROR; printf("Write request callback: Protocol error\n"); goto end; } cb_ctx->cb_ret_val = BL_NO_ERROR; strcpy(cb_ctx->cb_ret_msg, "Write request callback: Success\n"); end: g_mutex_unlock(&cb_ctx->pending_cb_mtx); printf_dbg("[CB] OUT write_req_cb\n"); }
void read_by_uuid_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { struct att_data_list *list; GSList *bl_value_list = NULL; cb_ctx_t *cb_ctx = user_data; printf_dbg("[CB] IN read_by_uuid_cb\n"); if (status) { cb_ctx->cb_ret_val = BL_REQUEST_FAIL_ERROR; sprintf(cb_ctx->cb_ret_msg, "Read by uuid callback: Failure: %s\n", att_ecode2str(status)); goto error; } list = dec_read_by_type_resp(pdu, plen); if (list == NULL) { strcpy(cb_ctx->cb_ret_msg, "Read by uuid callback: Nothing found\n"); cb_ctx->cb_ret_val = BL_NO_ERROR; goto error; } for (int i = 0; i < list->num; i++) { bl_value_t *bl_value = bl_value_new(NULL, att_get_u16(list->data[i]), list->len - 2, list->data[i] + 2); if (bl_value == NULL) { cb_ctx->cb_ret_val = BL_MALLOC_ERROR; strcpy(cb_ctx->cb_ret_msg, "Read by uuid callback: Malloc error\n"); goto error; } // Add it to the value list if (bl_value_list == NULL) { bl_value_list = g_slist_alloc(); if (bl_value_list == NULL) { cb_ctx->cb_ret_val = BL_MALLOC_ERROR; strcpy(cb_ctx->cb_ret_msg, "Read by uuid callback: Malloc error\n"); goto error; } bl_value_list->data = bl_value; } else { bl_value_list = g_slist_append(bl_value_list, bl_value); } } att_data_list_free(list); cb_ctx->cb_ret_pointer = bl_value_list; cb_ctx->cb_ret_val = BL_NO_ERROR; goto exit; error: if (bl_value_list) bl_value_list_free(bl_value_list); exit: g_mutex_unlock(&cb_ctx->pending_cb_mtx); printf_dbg("[CB] OUT read_by_uuid_cb\n"); }
void primary_all_cb(GSList *services, guint8 status, gpointer user_data) { GSList *l = NULL; GSList *bl_primary_list = NULL; printf_dbg("[CB] IN Primary_all_cb\n"); if (status) { cb_ret_val = BL_REQUEST_FAIL_ERROR; sprintf(cb_ret_msg, "Primary callback: Failure: %s\n", att_ecode2str(status)); goto error; } if (services == NULL) { cb_ret_val = BL_NO_ERROR; strcpy(cb_ret_msg, "Primary callback: Nothing found\n"); goto exit; } for (l = services; l; l = l->next) { struct gatt_primary *prim = l->data; bl_primary_t *bl_primary = bl_primary_new(prim->uuid, prim->changed, prim->range.start, prim->range.end); g_free(prim); if (bl_primary == NULL) { cb_ret_val = BL_MALLOC_ERROR; strcpy(cb_ret_msg, "Primary callback: Malloc error\n"); goto error; } if (bl_primary_list == NULL) { bl_primary_list = g_slist_alloc(); if (bl_primary_list == NULL) { cb_ret_val = BL_MALLOC_ERROR; strcpy(cb_ret_msg, "Primary callback: Malloc error\n"); goto error; } bl_primary_list->data = bl_primary; } else { bl_primary_list = g_slist_append(bl_primary_list, bl_primary); } } cb_ret_val = BL_NO_ERROR; cb_ret_pointer = bl_primary_list; strcpy(cb_ret_msg, "Primary callback: Sucess\n"); goto exit; error: if (bl_primary_list) bl_primary_list_free(bl_primary_list); exit: if (l) g_slist_free(l); g_mutex_unlock(pending_callback); printf_dbg("[CB] OUT primary_all_cb\n"); }
void char_by_uuid_cb(GSList *characteristics, guint8 status, gpointer user_data) { GSList *l = NULL; GSList *bl_char_list = NULL; cb_ctx_t *cb_ctx = user_data; printf_dbg(" IN char_by_uuid\n"); if (status) { cb_ctx->cb_ret_val = BL_REQUEST_FAIL_ERROR; sprintf(cb_ctx->cb_ret_msg, "Characteristic by UUID callback: Failure: %s\n", att_ecode2str(status)); goto error; } for (l = characteristics; l; l = l->next) { // Extract data struct gatt_char *chars = l->data; bl_char_t *bl_char = bl_char_new(chars->uuid, chars->handle, chars->properties, chars->value_handle); // Add it to the characteristic if (bl_char == NULL) { cb_ctx->cb_ret_val = BL_MALLOC_ERROR; strcpy(cb_ctx->cb_ret_msg, "Characteristic by UUID callback: Malloc error\n"); goto error; } // Append it to the list if (bl_char_list == NULL) { bl_char_list = g_slist_alloc(); if (bl_char_list == NULL) { cb_ctx->cb_ret_val = BL_MALLOC_ERROR; strcpy(cb_ctx->cb_ret_msg, "Characteristic by UUID callback: Malloc error\n"); goto error; } bl_char_list->data = bl_char; } else { bl_char_list = g_slist_append(bl_char_list, bl_char); } } cb_ctx->cb_ret_val = BL_NO_ERROR; cb_ctx->cb_ret_pointer = bl_char_list; goto exit; error: if (bl_char_list) bl_char_list_free(bl_char_list); exit: if (l) g_slist_free(l); g_mutex_unlock(&cb_ctx->pending_cb_mtx); printf_dbg("OUT char_by_uuid\n"); }
static void output_written_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { if (status != 0) { error("Write output report failed: %s", att_ecode2str(status)); return; } }
void primary_by_uuid_cb(GSList *ranges, guint8 status, gpointer user_data) { GSList *l; GSList *bl_primary_list = NULL; cb_ctx_t *cb_ctx = user_data; printf_dbg("IN primary_by_uuid_cb\n"); if (status) { cb_ctx->cb_ret_val = BL_REQUEST_FAIL_ERROR; sprintf(cb_ctx->cb_ret_msg, "Primary by UUID callback: Failure: %s\n", att_ecode2str(status)); goto error; } if (ranges == NULL) { cb_ctx->cb_ret_val = BL_NO_ERROR; strcpy(cb_ctx->cb_ret_msg, "Primary by UUID callback: Nothing found\n"); goto exit; } for (l = ranges; l; l = l->next) { struct att_range *range = l->data; bl_primary_t *bl_primary = bl_primary_new(NULL, 0, range->start, range->end); free(range); if (bl_primary == NULL) { cb_ctx->cb_ret_val = BL_MALLOC_ERROR; strcpy(cb_ctx->cb_ret_msg, "Primary by UUID callback: Malloc error\n"); goto error; } if (bl_primary_list == NULL) { bl_primary_list = g_slist_alloc(); if (bl_primary_list == NULL) { cb_ctx->cb_ret_val = BL_MALLOC_ERROR; strcpy(cb_ctx->cb_ret_msg, "Primary by UUID callback: Malloc error\n"); goto error; } bl_primary_list->data = bl_primary; } else { bl_primary_list = g_slist_append(bl_primary_list, bl_primary); } } cb_ctx->cb_ret_val = BL_NO_ERROR; cb_ctx->cb_ret_pointer = bl_primary_list; goto exit; error: if (bl_primary_list) bl_primary_list_free(bl_primary_list); exit: g_mutex_unlock(&cb_ctx->pending_cb_mtx); printf_dbg("OUT primary_by_uuid_cb\n"); }