struct btd_gatt_client *btd_gatt_client_new(struct btd_device *device) { struct btd_gatt_client *client; struct gatt_db *db; if (!device) return NULL; db = btd_device_get_gatt_db(device); if (!db) return NULL; client = new0(struct btd_gatt_client, 1); if (!client) return NULL; client->services = queue_new(); if (!client->services) { free(client); return NULL; } client->device = device; ba2str(device_get_address(device), client->devaddr); client->db = gatt_db_ref(db); return client; }
struct bt_gatt_server *bt_gatt_server_new(struct gatt_db *db, struct bt_att *att, uint16_t mtu) { struct bt_gatt_server *server; if (!att || !db) return NULL; server = new0(struct bt_gatt_server, 1); if (!server) return NULL; server->db = gatt_db_ref(db); server->att = bt_att_ref(att); server->mtu = MAX(mtu, BT_ATT_DEFAULT_LE_MTU); server->max_prep_queue_len = DEFAULT_MAX_PREP_QUEUE_LEN; server->prep_queue = queue_new(); if (!server->prep_queue) { bt_gatt_server_free(server); return NULL; } if (!gatt_server_register_att_handlers(server)) { bt_gatt_server_free(server); return NULL; } return bt_gatt_server_ref(server); }
static int gap_accept(struct btd_service *service) { struct btd_device *device = btd_service_get_device(service); struct gatt_db *db = btd_device_get_gatt_db(device); struct bt_gatt_client *client = btd_device_get_gatt_client(device); struct gas *gas = btd_service_get_user_data(service); char addr[18]; bt_uuid_t gap_uuid; ba2str(device_get_address(device), addr); DBG("GAP profile accept (%s)", addr); if (!gas) { error("GAP service not handled by profile"); return -1; } gas->db = gatt_db_ref(db); gas->client = bt_gatt_client_ref(client); /* Handle the GAP services */ bt_uuid16_create(&gap_uuid, GAP_UUID16); gatt_db_foreach_service(db, &gap_uuid, foreach_gap_service, gas); if (!gas->attr) { error("GAP attribute not found"); gas_reset(gas); return -1; } btd_service_connecting_complete(service, 0); return 0; }
struct gatt_db *gatt_db_new(void) { struct gatt_db *db; db = new0(struct gatt_db, 1); db->services = queue_new(); db->notify_list = queue_new(); db->next_handle = 0x0001; return gatt_db_ref(db); }
static void notify_service_changed(struct gatt_db *db, struct gatt_db_service *service, bool added) { struct notify_data data; if (queue_isempty(db->notify_list)) return; data.attr = service->attributes[0]; data.added = added; gatt_db_ref(db); queue_foreach(db->notify_list, handle_notify, &data); gatt_db_unref(db); }
static int gap_driver_accept(struct btd_service *service) { struct btd_device *device = btd_service_get_device(service); struct gatt_db *db = btd_device_get_gatt_db(device); struct bt_gatt_client *client = btd_device_get_gatt_client(device); struct gas *gas; GSList *l; char addr[18]; bt_uuid_t gap_uuid; ba2str(device_get_address(device), addr); DBG("GAP profile accept (%s)", addr); l = g_slist_find_custom(devices, device, cmp_device); if (!l) { error("GAP service not handled by profile"); return -1; } gas = l->data; /* Clean-up any old client/db and acquire the new ones */ gas->attr = NULL; gatt_db_unregister(gas->db, gas->db_id); gatt_db_unref(gas->db); bt_gatt_client_unref(gas->client); gas->db = gatt_db_ref(db); gas->client = bt_gatt_client_ref(client); gas->db_id = gatt_db_register(db, service_added, service_removed, gas, NULL); /* Handle the GAP services */ bt_uuid16_create(&gap_uuid, GAP_UUID16); gatt_db_foreach_service(db, &gap_uuid, foreach_gap_service, gas); return 0; }