static void export_char(struct gatt_db_attribute *attr, void *user_data) { struct characteristic *charac; struct export_data *data = user_data; struct service *service = data->root; if (data->failed) return; charac = characteristic_create(attr, service); if (!charac) goto fail; if (!create_descriptors(attr, charac)) { unregister_characteristic(charac); goto fail; } queue_push_tail(service->chrcs, charac); if (charac->ext_props_handle) queue_push_tail(service->pending_ext_props, charac); return; fail: data->failed = true; }
unsigned int bt_att_send(struct bt_att *att, uint8_t opcode, const void *pdu, uint16_t length, bt_att_response_func_t callback, void *user_data, bt_att_destroy_func_t destroy) { struct att_send_op *op; bool result; if (!att || !att->io) return 0; op = create_att_send_op(att, opcode, pdu, length, callback, user_data, destroy); if (!op) return 0; if (att->next_send_id < 1) att->next_send_id = 1; op->id = att->next_send_id++; /* Add the op to the correct queue based on its type */ switch (op->type) { case ATT_OP_TYPE_REQ: result = queue_push_tail(att->req_queue, op); break; case ATT_OP_TYPE_IND: result = queue_push_tail(att->ind_queue, op); break; case ATT_OP_TYPE_CMD: case ATT_OP_TYPE_NOT: case ATT_OP_TYPE_UNKNOWN: case ATT_OP_TYPE_RSP: case ATT_OP_TYPE_CONF: default: result = queue_push_tail(att->write_queue, op); break; } if (!result) { free(op->pdu); free(op); return 0; } wakeup_writer(att); return op->id; }
static void export_service(struct gatt_db_attribute *attr, void *user_data) { struct btd_gatt_client *client = user_data; struct service *service; if (gatt_db_service_get_claimed(attr)) return; service = service_create(attr, client); if (!service) return; if (!create_characteristics(attr, service)) { error("Exporting characteristics failed"); unregister_service(service); return; } queue_push_tail(client->services, service); /* * Asynchronously update the "Characteristics" property of the service. * If there are any pending reads to obtain the value of the "Extended * Properties" descriptor then wait until they are complete. */ if (!service->chrcs_ready && queue_isempty(service->pending_ext_props)) service->idle_id = g_idle_add(set_chrcs_ready, service); }
static struct health_device *create_device(struct health_app *app, const uint8_t *addr) { struct health_device *dev; if (!app) return NULL; /* create device and push it to devices queue */ dev = new0(struct health_device, 1); if (!dev) return NULL; android2bdaddr(addr, &dev->dst); dev->channels = queue_new(); if (!dev->channels) { free_health_device(dev); return NULL; } if (!queue_push_tail(app->devices, dev)) { free_health_device(dev); return NULL; } dev->app_id = app->id; return dev; }
unsigned int mgmt_register(struct mgmt *mgmt, uint16_t event, uint16_t index, mgmt_notify_func_t callback, void *user_data, mgmt_destroy_func_t destroy) { struct mgmt_notify *notify; if (!mgmt || !event) return 0; notify = new0(struct mgmt_notify, 1); if (!notify) return 0; notify->event = event; notify->index = index; notify->callback = callback; notify->destroy = destroy; notify->user_data = user_data; if (mgmt->next_notify_id < 1) mgmt->next_notify_id = 1; notify->id = mgmt->next_notify_id++; if (!queue_push_tail(mgmt->notify_list, notify)) { free(notify); return 0; } return notify->id; }
static void find_information(void *data, void *user_data) { struct find_information_data *search_data = user_data; struct gatt_db_service *service = data; struct gatt_db_attribute *attribute; int i; if (!service->active) return; /* Check if service is in range */ if ((service->attributes[0]->handle + service->num_handles - 1) < search_data->start_handle) return; for (i = 0; i < service->num_handles; i++) { attribute = service->attributes[i]; if (!attribute) continue; if (attribute->handle < search_data->start_handle) continue; if (attribute->handle > search_data->end_handle) return; queue_push_tail(search_data->queue, attribute); } }
bool hfp_gw_register(struct hfp_gw *hfp, hfp_result_func_t callback, const char *prefix, void *user_data, hfp_destroy_func_t destroy) { struct cmd_handler *handler; handler = new0(struct cmd_handler, 1); if (!handler) return false; handler->callback = callback; handler->user_data = user_data; handler->prefix = strdup(prefix); if (!handler->prefix) { free(handler); return false; } if (queue_find(hfp->cmd_handlers, match_handler_prefix, handler->prefix)) { destroy_cmd_handler(handler); return false; } handler->destroy = destroy; return queue_push_tail(hfp->cmd_handlers, handler); }
unsigned int bt_att_register_disconnect(struct bt_att *att, bt_att_disconnect_func_t callback, void *user_data, bt_att_destroy_func_t destroy) { struct att_disconn *disconn; if (!att || !att->io) return 0; disconn = new0(struct att_disconn, 1); if (!disconn) return 0; disconn->callback = callback; disconn->destroy = destroy; disconn->user_data = user_data; if (att->next_reg_id < 1) att->next_reg_id = 1; disconn->id = att->next_reg_id++; if (!queue_push_tail(att->disconn_list, disconn)) { free(disconn); return 0; } return disconn->id; }
static bool prep_data_new(struct bt_gatt_server *server, uint16_t handle, uint16_t offset, uint16_t length, uint8_t *value) { struct prep_write_data *prep_data; prep_data = new0(struct prep_write_data, 1); if (!append_prep_data(prep_data, handle, length, value)) { prep_write_data_destroy(prep_data); return false; } prep_data->server = server; prep_data->handle = handle; prep_data->offset = offset; /* * Handle is the value handle. We need characteristic declaration * handle which in BlueZ is handle_value -1 */ prep_data->reliable_supported = is_reliable_write_supported(server, handle - 1); queue_push_tail(server->prep_queue, prep_data); return true; }
unsigned int mgmt_reply(struct mgmt *mgmt, uint16_t opcode, uint16_t index, uint16_t length, const void *param, mgmt_request_func_t callback, void *user_data, mgmt_destroy_func_t destroy) { struct mgmt_request *request; if (!mgmt) return 0; request = create_request(opcode, index, length, param, callback, user_data, destroy); if (!request) return 0; if (mgmt->next_request_id < 1) mgmt->next_request_id = 1; request->id = mgmt->next_request_id++; if (!queue_push_tail(mgmt->reply_queue, request)) { free(request->buf); free(request); return 0; } wakeup_writer(mgmt); return request->id; }
unsigned int bt_att_register(struct bt_att *att, uint8_t opcode, bt_att_notify_func_t callback, void *user_data, bt_att_destroy_func_t destroy) { struct att_notify *notify; if (!att || !callback || !att->io) return 0; notify = new0(struct att_notify, 1); if (!notify) return 0; notify->opcode = opcode; notify->callback = callback; notify->destroy = destroy; notify->user_data = user_data; if (att->next_reg_id < 1) att->next_reg_id = 1; notify->id = att->next_reg_id++; if (!queue_push_tail(att->notify_list, notify)) { free(notify); return 0; } return notify->id; }
unsigned int gatt_db_register(struct gatt_db *db, gatt_db_attribute_cb_t service_added, gatt_db_attribute_cb_t service_removed, void *user_data, gatt_db_destroy_func_t destroy) { struct notify *notify; if (!db || !(service_added || service_removed)) return 0; notify = new0(struct notify, 1); notify->service_added = service_added; notify->service_removed = service_removed; notify->destroy = destroy; notify->user_data = user_data; if (db->next_notify_id < 1) db->next_notify_id = 1; notify->id = db->next_notify_id++; if (!queue_push_tail(db->notify_list, notify)) { free(notify); return 0; } return notify->id; }
static void read_by_type(void *data, void *user_data) { struct read_by_type_data *search_data = user_data; struct gatt_db_service *service = data; struct gatt_db_attribute *attribute; int i; if (!service->active) return; for (i = 0; i < service->num_handles; i++) { attribute = service->attributes[i]; if (!attribute) continue; if (attribute->handle < search_data->start_handle) continue; if (attribute->handle > search_data->end_handle) return; if (bt_uuid_cmp(&search_data->uuid, &attribute->uuid)) continue; queue_push_tail(search_data->queue, attribute); } }
unsigned int bt_hci_register(struct bt_hci *hci, uint8_t event, bt_hci_callback_func_t callback, void *user_data, bt_hci_destroy_func_t destroy) { struct evt *evt; if (!hci) return 0; evt = new0(struct evt, 1); if (!evt) return 0; evt->event = event; if (hci->next_evt_id < 1) hci->next_evt_id = 1; evt->id = hci->next_evt_id++; evt->callback = callback; evt->destroy = destroy; evt->user_data = user_data; if (!queue_push_tail(hci->evt_list, evt)) { free(evt); return 0; } return evt->id; }
void test_queue_is_empty(void) { Queue *queue; queue = queue_new(); assert(queue_is_empty(queue)); queue_push_head(queue, &variable1); assert(!queue_is_empty(queue)); queue_pop_head(queue); assert(queue_is_empty(queue)); queue_push_tail(queue, &variable1); assert(!queue_is_empty(queue)); queue_pop_tail(queue); assert(queue_is_empty(queue)); queue_free(queue); }
static struct health_channel *create_channel(struct health_app *app, uint8_t mdep_index, struct health_device *dev) { struct mdep_cfg *mdep; struct health_channel *channel; static unsigned int channel_id = 1; DBG("mdep %u", mdep_index); if (!dev || !app) return NULL; mdep = queue_find(app->mdeps, match_mdep_by_id, INT_TO_PTR(mdep_index)); if (!mdep) { if (mdep_index == MDEP_ECHO) { mdep = new0(struct mdep_cfg, 1); if (!mdep) return NULL; /* Leave other configuration zeroes */ mdep->id = MDEP_ECHO; if (!queue_push_tail(app->mdeps, mdep)) { free_mdep_cfg(mdep); return NULL; } } else return NULL;
static void bt_health_register_app(const void *buf, uint16_t len) { const struct hal_cmd_health_reg_app *cmd = buf; struct hal_rsp_health_reg_app rsp; struct health_app *app; uint16_t off; uint16_t app_name_len, provider_len, srv_name_len, srv_descr_len; char *app_name, *provider = NULL, *srv_name = NULL, *srv_descr = NULL; DBG(""); if (len != sizeof(*cmd) + cmd->len || cmd->app_name_off > cmd->provider_name_off || cmd->provider_name_off > cmd->service_name_off || cmd->service_name_off > cmd->service_descr_off || cmd->service_descr_off > cmd->len) { error("health: Invalid register app command, terminating"); raise(SIGTERM); return; } app_name = (char *) cmd->data; app_name_len = cmd->provider_name_off - cmd->app_name_off; off = app_name_len; provider_len = cmd->service_name_off - off; if (provider_len > 0) provider = (char *) cmd->data + off; off += provider_len; srv_name_len = cmd->service_descr_off - off; if (srv_name_len > 0) srv_name = (char *) cmd->data + off; off += srv_name_len; srv_descr_len = cmd->len - off; if (srv_descr_len > 0) srv_descr = (char *) cmd->data + off; app = create_health_app(app_name, provider, srv_name, srv_descr, cmd->num_of_mdep); if (!app) goto fail; if (!queue_push_tail(apps, app)) goto fail; rsp.app_id = app->id; ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_REG_APP, sizeof(rsp), &rsp, -1); return; fail: free_health_app(app); ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_MDEP, HAL_STATUS_FAILED); }
bool gatt_db_attribute_write(struct gatt_db_attribute *attrib, uint16_t offset, const uint8_t *value, size_t len, uint8_t opcode, struct bt_att *att, gatt_db_attribute_write_t func, void *user_data) { if (!attrib || !func) return false; if (attrib->write_func) { struct pending_write *p; p = new0(struct pending_write, 1); p->attrib = attrib; p->id = ++attrib->write_id; p->timeout_id = timeout_add(ATTRIBUTE_TIMEOUT, write_timeout, p, NULL); p->func = func; p->user_data = user_data; queue_push_tail(attrib->pending_writes, p); attrib->write_func(attrib, p->id, offset, value, len, opcode, att, attrib->user_data); return true; } /* Nothing to write just skip */ if (len == 0) goto done; /* For values stored in db allocate on demand */ if (!attrib->value || offset >= attrib->value_len || len > (unsigned) (attrib->value_len - offset)) { void *buf; buf = realloc(attrib->value, len + offset); if (!buf) return false; attrib->value = buf; /* Init data in the first allocation */ if (!attrib->value_len) memset(attrib->value, 0, offset); attrib->value_len = len + offset; } memcpy(&attrib->value[offset], value, len); done: func(attrib, 0, user_data); return true; }
void test_queue_push_tail(void) { Queue *queue; int i; queue = queue_new(); /* Add some values */ for (i=0; i<1000; ++i) { queue_push_tail(queue, &variable1); queue_push_tail(queue, &variable2); queue_push_tail(queue, &variable3); queue_push_tail(queue, &variable4); } assert(!queue_is_empty(queue)); /* Check values come out of the head properly */ assert(queue_pop_head(queue) == &variable1); assert(queue_pop_head(queue) == &variable2); assert(queue_pop_head(queue) == &variable3); assert(queue_pop_head(queue) == &variable4); /* Check values come back out of the tail properly */ assert(queue_pop_tail(queue) == &variable4); assert(queue_pop_tail(queue) == &variable3); assert(queue_pop_tail(queue) == &variable2); assert(queue_pop_tail(queue) == &variable1); queue_free(queue); /* Test behavior when running out of memory. */ queue = queue_new(); alloc_test_set_limit(0); assert(!queue_push_tail(queue, &variable1)); queue_free(queue); }
struct queue *get_avrcp_tests(void) { uint16_t i = 0; list = queue_new(); for (; i < sizeof(test_cases) / sizeof(test_cases[0]); ++i) queue_push_tail(list, &test_cases[i]); return list; }
struct queue *get_bluetooth_tests(void) { uint16_t i = 0; list = queue_new(); for (; i < sizeof(test_cases) / sizeof(test_cases[0]); ++i) if (!queue_push_tail(list, &test_cases[i])) return NULL; return list; }
edges_list read_edges() { guint first = 0, last = 0, capacity = 0; edge e = NULL; edges_list edges = NULL; edges = queue_new(); while(scanf("%u %u %u\n", &first, &last, &capacity) != EOF){ e = make_edge(first, last, capacity, 0, false); queue_push_tail(edges, e); } return edges; }
static void new_index(struct timeval *tv, uint16_t index, const void *data, uint16_t size) { const struct btsnoop_opcode_new_index *ni = data; struct hci_dev *dev; dev = dev_alloc(index); if (!dev) return; dev->type = ni->type; memcpy(dev->bdaddr, ni->bdaddr, 6); queue_push_tail(dev_list, dev); }
static bool io_write_callback(struct io *io, void *user_data) { struct bt_hci *hci = user_data; struct cmd *cmd; cmd = queue_pop_head(hci->cmd_queue); if (cmd) { send_command(hci, cmd->opcode, cmd->data, cmd->size); queue_push_tail(hci->rsp_queue, cmd); } hci->writer_active = false; return false; }
static DBusMessage *register_advertisement(DBusConnection *conn, DBusMessage *msg, void *user_data) { struct btd_advertising *manager = user_data; DBusMessageIter args; struct advertisement *ad; struct dbus_obj_match match; uint8_t instance; DBG("RegisterAdvertisement"); if (!dbus_message_iter_init(msg, &args)) return btd_error_invalid_args(msg); if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) return btd_error_invalid_args(msg); dbus_message_iter_get_basic(&args, &match.path); match.owner = dbus_message_get_sender(msg); if (queue_find(manager->ads, match_advertisement, &match)) return btd_error_already_exists(msg); instance = util_get_uid(&manager->instance_bitmap, manager->max_ads); if (!instance) return btd_error_failed(msg, "Maximum advertisements reached"); dbus_message_iter_next(&args); if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) return btd_error_invalid_args(msg); ad = advertisement_create(conn, msg, match.path); if (!ad) return btd_error_failed(msg, "Failed to register advertisement"); DBG("Registered advertisement at path %s", match.path); ad->instance = instance; ad->manager = manager; queue_push_tail(manager->ads, ad); return NULL; }
unsigned int bt_hci_send(struct bt_hci *hci, uint16_t opcode, const void *data, uint8_t size, bt_hci_callback_func_t callback, void *user_data, bt_hci_destroy_func_t destroy) { struct cmd *cmd; if (!hci) return 0; cmd = new0(struct cmd, 1); if (!cmd) return 0; cmd->opcode = opcode; cmd->size = size; if (cmd->size > 0) { cmd->data = malloc(cmd->size); if (!cmd->data) { free(cmd); return 0; } memcpy(cmd->data, data, cmd->size); } if (hci->next_cmd_id < 1) hci->next_cmd_id = 1; cmd->id = hci->next_cmd_id++; cmd->callback = callback; cmd->destroy = destroy; cmd->user_data = user_data; if (!queue_push_tail(hci->cmd_queue, cmd)) { free(cmd->data); free(cmd); return 0; } wakeup_writer(hci); return cmd->id; }
static struct hci_dev *dev_lookup(uint16_t index) { struct hci_dev *dev; dev = queue_find(dev_list, dev_match_index, UINT_TO_PTR(index)); if (!dev) { fprintf(stderr, "Creating new device for unknown index\n"); dev = dev_alloc(index); if (!dev) return NULL; queue_push_tail(dev_list, dev); } return dev; }
static void export_desc(struct gatt_db_attribute *attr, void *user_data) { struct descriptor *desc; struct export_data *data = user_data; struct characteristic *charac = data->root; if (data->failed) return; desc = descriptor_create(attr, charac); if (!desc) { data->failed = true; return; } queue_push_tail(charac->descs, desc); }
static struct id_pair *store_id(GAttrib *attrib, unsigned int org_id, unsigned int pend_id) { struct id_pair *t; t = new0(struct id_pair, 1); if (!t) return NULL; t->org_id = org_id; t->pend_id = pend_id; if (queue_push_tail(attrib->track_ids, t)) return t; return NULL; }
bool hfp_hf_send_command(struct hfp_hf *hfp, hfp_response_func_t resp_cb, void *user_data, const char *format, ...) { va_list ap; char *fmt; int len; struct cmd_response *cmd; if (!hfp || !format || !resp_cb) return false; if (asprintf(&fmt, "%s\r", format) < 0) return false; cmd = new0(struct cmd_response, 1); if (!cmd) { free(fmt); return false; } va_start(ap, format); len = ringbuf_vprintf(hfp->write_buf, fmt, ap); va_end(ap); free(fmt); if (len < 0) { free(cmd); return false; } cmd->resp_cb = resp_cb; cmd->user_data = user_data; if (!queue_push_tail(hfp->cmd_queue, cmd)) { ringbuf_drain(hfp->write_buf, len); free(cmd); return false; } hf_wakeup_writer(hfp); return true; }