static void read_cb(bool success, uint8_t att_ecode, const uint8_t *value, uint16_t length, void *user_data) { int i; if (!success) { PRLOG("\nRead request failed: %s (0x%02x)\n", ecode_to_string(att_ecode), att_ecode); return; } printf("\nRead value"); if (length == 0) { PRLOG(": 0 bytes\n"); return; } printf(" (%u bytes): ", length); for (i = 0; i < length; i++) printf("%02x ", value[i]); PRLOG("\n"); }
static void gatt_svc_chngd_ccc_write_cb(struct gatt_db_attribute *attrib, unsigned int id, uint16_t offset, const uint8_t *value, size_t len, uint8_t opcode, struct bt_att *att, void *user_data) { struct server *server = user_data; uint8_t ecode = 0; PRLOG("Service Changed CCC Write called\n"); if (!value || len != 2) { ecode = BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN; goto done; } if (offset) { ecode = BT_ATT_ERROR_INVALID_OFFSET; goto done; } if (value[0] == 0x00) server->svc_chngd_enabled = false; else if (value[0] == 0x02) server->svc_chngd_enabled = true; else ecode = 0x80; PRLOG("Service Changed Enabled: %s\n", server->svc_chngd_enabled ? "true" : "false"); done: gatt_db_attribute_write_result(attrib, id, ecode); }
static void write_cb(bool success, uint8_t att_ecode, void *user_data) { if (success) { PRLOG("\nWrite successful\n"); } else { PRLOG("\nWrite failed: 0x%02x\n", att_ecode); } }
static void write_cb(bool success, uint8_t att_ecode, void *user_data) { if (success) { PRLOG("\nWrite successful\n"); } else { PRLOG("\nWrite failed: %s (0x%02x)\n", ecode_to_string(att_ecode), att_ecode); } }
static void register_notify_cb(uint16_t att_ecode, void *user_data) { if (att_ecode) { PRLOG("Failed to register notify handler " "- error code: 0x%02x\n", att_ecode); return; } PRLOG("Registered notify handler!\n"); }
static void register_notify_cb(unsigned int id, uint16_t att_ecode, void *user_data) { if (!id) { PRLOG("Failed to register notify handler " "- error code: 0x%02x\n", att_ecode); return; } PRLOG("Registered notify handler with id: %u\n", id); }
static void write_long_cb(bool success, bool reliable_error, uint8_t att_ecode, void *user_data) { if (success) { PRLOG("Write successful\n"); } else if (reliable_error) { PRLOG("Reliable write not verified\n"); } else { PRLOG("Write failed: 0x%02x\n", att_ecode); } }
static void ready_cb(bool success, uint8_t att_ecode, void *user_data) { struct client *cli = user_data; if (!success) { PRLOG("GATT discovery procedures failed - error code: 0x%02x\n", att_ecode); return; } PRLOG("GATT discovery procedures complete\n"); print_services(cli); print_prompt(); }
static void cmd_register_notify(struct client *cli, char *cmd_str) { char *argv[2]; int argc = 0; uint16_t value_handle; unsigned int id; char *endptr = NULL; if (!bt_gatt_client_is_ready(cli->gatt)) { printf("GATT client not initialized\n"); return; } if (!parse_args(cmd_str, 1, argv, &argc) || argc != 1) { register_notify_usage(); return; } value_handle = strtol(argv[0], &endptr, 0); if (!endptr || *endptr != '\0' || !value_handle) { printf("Invalid value handle: %s\n", argv[0]); return; } id = bt_gatt_client_register_notify(cli->gatt, value_handle, register_notify_cb, notify_cb, NULL, NULL); if (!id) { printf("Failed to register notify handler\n"); return; } PRLOG("Registering notify handler with id: %u\n", id); }
static void att_debug_cb(const char *str, void *user_data) { const char *prefix = user_data; PRLOG(COLOR_BOLDGRAY "%s" COLOR_BOLDWHITE "%s\n" COLOR_OFF, prefix, str); }
static void hr_control_point_write_cb(struct gatt_db_attribute *attrib, unsigned int id, uint16_t offset, const uint8_t *value, size_t len, uint8_t opcode, struct bt_att *att, void *user_data) { struct server *server = user_data; uint8_t ecode = 0; if (!value || len != 1) { ecode = BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN; goto done; } if (offset) { ecode = BT_ATT_ERROR_INVALID_OFFSET; goto done; } if (value[0] == 1) { PRLOG("HR: Energy Expended value reset\n"); server->hr_energy_expended = 0; } done: gatt_db_attribute_write_result(attrib, id, ecode); }
static void service_changed_cb(uint16_t start_handle, uint16_t end_handle, void *user_data) { struct client *cli = user_data; struct bt_gatt_service_iter iter; const bt_gatt_service_t *service; if (!bt_gatt_service_iter_init(&iter, cli->gatt)) { PRLOG("Failed to initialize service iterator\n"); return; } printf("\nService Changed handled - start: 0x%04x end: 0x%04x\n", start_handle, end_handle); if (!bt_gatt_service_iter_next_by_handle(&iter, start_handle, &service)) return; print_service(service); while (bt_gatt_service_iter_next(&iter, &service)) { if (service->start_handle >= end_handle) break; print_service(service); } print_prompt(); }
static void gap_device_name_read_cb(struct gatt_db_attribute *attrib, unsigned int id, uint16_t offset, uint8_t opcode, struct bt_att *att, void *user_data) { struct server *server = user_data; uint8_t error = 0; size_t len = 0; const uint8_t *value = NULL; PRLOG("GAP Device Name Read called\n"); len = server->name_len; if (offset > len) { error = BT_ATT_ERROR_INVALID_OFFSET; goto done; } len -= offset; value = len ? &server->device_name[offset] : NULL; done: gatt_db_attribute_read_result(attrib, id, error, value, len); }
static void gatt_service_changed_cb(struct gatt_db_attribute *attrib, unsigned int id, uint16_t offset, uint8_t opcode, struct bt_att *att, void *user_data) { PRLOG("Service Changed Read called\n"); gatt_db_attribute_read_result(attrib, id, 0, NULL, 0); }
static void read_multiple_cb(bool success, uint8_t att_ecode, const uint8_t *value, uint16_t length, void *user_data) { int i; if (!success) { PRLOG("\nRead multiple request failed: 0x%02x\n", att_ecode); return; } printf("\nRead multiple value (%u bytes):", length); for (i = 0; i < length; i++) printf("%02x ", value[i]); PRLOG("\n"); }
// Spawn a new thread. void xthread::spawn(void * actualFunc, void * arg) { PRLOG("%d: Spawning ....\n", getpid()); // Make context ctx.makeContext((void *)&xthread::threadRun, actualFunc, arg); // set the parent to current thread. parent = process::getInstance().getCurrent(); parent->setUnBounded(); }
static void notify_cb(uint16_t value_handle, const uint8_t *value, uint16_t length, void *user_data) { int i; printf("\n\tHandle Value Not/Ind: 0x%04x - ", value_handle); if (length == 0) { PRLOG("(0 bytes)\n"); return; } printf("(%u bytes): ", length); for (i = 0; i < length; i++) printf("%02x ", value[i]); PRLOG("\n"); }
static void hr_msrmt_ccc_write_cb(struct gatt_db_attribute *attrib, unsigned int id, uint16_t offset, const uint8_t *value, size_t len, uint8_t opcode, struct bt_att *att, void *user_data) { struct server *server = user_data; uint8_t ecode = 0; if (!value || len != 2) { ecode = BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN; goto done; } if (offset) { ecode = BT_ATT_ERROR_INVALID_OFFSET; goto done; } if (value[0] == 0x00) server->hr_msrmt_enabled = false; else if (value[0] == 0x01) { if (server->hr_msrmt_enabled) { PRLOG("HR Measurement Already Enabled\n"); goto done; } server->hr_msrmt_enabled = true; } else ecode = 0x80; PRLOG("HR: Measurement Enabled: %s\n", server->hr_msrmt_enabled ? "true" : "false"); update_hr_msrmt_simulation(server); done: gatt_db_attribute_write_result(attrib, id, ecode); }
static void log_service_event(struct gatt_db_attribute *attr, const char *str) { char uuid_str[MAX_LEN_UUID_STR]; bt_uuid_t uuid; uint16_t start, end; gatt_db_attribute_get_service_uuid(attr, &uuid); bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str)); gatt_db_attribute_get_service_handles(attr, &start, &end); PRLOG("%s - UUID: %s start: 0x%04x end: 0x%04x\n", str, uuid_str, start, end); }
static void gap_device_name_ext_prop_read_cb(struct gatt_db_attribute *attrib, unsigned int id, uint16_t offset, uint8_t opcode, struct bt_att *att, void *user_data) { uint8_t value[2]; PRLOG("Device Name Extended Properties Read called\n"); value[0] = BT_GATT_CHRC_EXT_PROP_RELIABLE_WRITE; value[1] = 0; gatt_db_attribute_read_result(attrib, id, 0, value, sizeof(value)); }
static void print_services_by_handle(struct client *cli, uint16_t handle) { struct bt_gatt_service_iter iter; const bt_gatt_service_t *service; if (!bt_gatt_service_iter_init(&iter, cli->gatt)) { PRLOG("Failed to initialize service iterator\n"); return; } printf("\n"); while (bt_gatt_service_iter_next_by_handle(&iter, handle, &service)) print_service(service); }
static void gatt_svc_chngd_ccc_read_cb(struct gatt_db_attribute *attrib, unsigned int id, uint16_t offset, uint8_t opcode, struct bt_att *att, void *user_data) { struct server *server = user_data; uint8_t value[2]; PRLOG("Service Changed CCC Read called\n"); value[0] = server->svc_chngd_enabled ? 0x02 : 0x00; value[1] = 0x00; gatt_db_attribute_read_result(attrib, id, 0, value, sizeof(value)); }
static void print_services_by_uuid(struct client *cli, const bt_uuid_t *uuid) { struct bt_gatt_service_iter iter; const bt_gatt_service_t *service; if (!bt_gatt_service_iter_init(&iter, cli->gatt)) { PRLOG("Failed to initialize service iterator\n"); return; } printf("\n"); while (bt_gatt_service_iter_next_by_uuid(&iter, uuid->value.u128.data, &service)) print_service(service); }
static void gap_device_name_write_cb(struct gatt_db_attribute *attrib, unsigned int id, uint16_t offset, const uint8_t *value, size_t len, uint8_t opcode, struct bt_att *att, void *user_data) { struct server *server = user_data; uint8_t error = 0; PRLOG("GAP Device Name Write called\n"); /* If the value is being completely truncated, clean up and return */ if (!(offset + len)) { free(server->device_name); server->device_name = NULL; server->name_len = 0; goto done; } /* Implement this as a variable length attribute value. */ if (offset > server->name_len) { error = BT_ATT_ERROR_INVALID_OFFSET; goto done; } if (offset + len != server->name_len) { uint8_t *name; name = realloc(server->device_name, offset + len); if (!name) { error = BT_ATT_ERROR_INSUFFICIENT_RESOURCES; goto done; } server->device_name = name; server->name_len = offset + len; } if (value) memcpy(server->device_name + offset, value, len); done: gatt_db_attribute_write_result(attrib, id, error); }
static void print_service(const bt_gatt_service_t *service) { struct bt_gatt_characteristic_iter iter; const bt_gatt_characteristic_t *chrc; size_t i; if (!bt_gatt_characteristic_iter_init(&iter, service)) { PRLOG("Failed to initialize characteristic iterator\n"); return; } printf(COLOR_RED "service" COLOR_OFF " - start: 0x%04x, " "end: 0x%04x, uuid: ", service->start_handle, service->end_handle); print_uuid(service->uuid); while (bt_gatt_characteristic_iter_next(&iter, &chrc)) { printf("\t " COLOR_YELLOW "charac" COLOR_OFF " - start: 0x%04x, end: 0x%04x, " "value: 0x%04x, props: 0x%02x, uuid: ", chrc->start_handle, chrc->end_handle, chrc->value_handle, chrc->properties); print_uuid(chrc->uuid); for (i = 0; i < chrc->num_descs; i++) { printf("\t\t " COLOR_MAGENTA "descr" COLOR_OFF " - handle: 0x%04x, uuid: ", chrc->descs[i].handle); print_uuid(chrc->descs[i].uuid); } } printf("\n"); }
static void conf_cb(void *user_data) { PRLOG("Received confirmation\n"); }
static void gatt_debug_cb(const char *str, void *user_data) { const char *prefix = user_data; PRLOG(COLOR_GREEN "%s%s\n" COLOR_OFF, prefix, str); }