void gatt_db_unref(struct gatt_db *db) { if (!db) return; if (__sync_sub_and_fetch(&db->ref_count, 1)) return; gatt_db_destroy(db); }
static void server_destroy(struct server *server) { timeout_remove(server->hr_timeout_id); bt_gatt_server_unref(server->gatt); gatt_db_destroy(server->db); }
static struct server *server_create(int fd, uint16_t mtu, bool hr_visible) { struct server *server; struct bt_att *att; size_t name_len = strlen(test_device_name); server = new0(struct server, 1); if (!server) { fprintf(stderr, "Failed to allocate memory for server\n"); return NULL; } att = bt_att_new(fd); if (!att) { fprintf(stderr, "Failed to initialze ATT transport layer\n"); goto fail; } if (!bt_att_set_close_on_unref(att, true)) { fprintf(stderr, "Failed to set up ATT transport layer\n"); goto fail; } if (!bt_att_register_disconnect(att, att_disconnect_cb, NULL, NULL)) { fprintf(stderr, "Failed to set ATT disconnect handler\n"); goto fail; } server->name_len = name_len + 1; server->device_name = malloc(name_len + 1); if (!server->device_name) { fprintf(stderr, "Failed to allocate memory for device name\n"); goto fail; } memcpy(server->device_name, test_device_name, name_len); server->device_name[name_len] = '\0'; server->fd = fd; server->db = gatt_db_new(); if (!server->db) { fprintf(stderr, "Failed to create GATT database\n"); goto fail; } server->gatt = bt_gatt_server_new(server->db, att, mtu); if (!server->gatt) { fprintf(stderr, "Failed to create GATT server\n"); goto fail; } server->hr_visible = hr_visible; if (verbose) { bt_att_set_debug(att, att_debug_cb, "att: ", NULL); bt_gatt_server_set_debug(server->gatt, gatt_debug_cb, "server: ", NULL); } /* Random seed for generating fake Heart Rate measurements */ srand(time(NULL)); /* bt_gatt_server already holds a reference */ bt_att_unref(att); populate_db(server); return server; fail: gatt_db_destroy(server->db); free(server->device_name); bt_att_unref(att); free(server); return NULL; }