diff --git a/android/gatt.c b/android/gatt.c
index 741dc38..a2314e0 100644
--- a/android/gatt.c
+++ b/android/gatt.c
"CONNECTED",
};
-typedef enum {
- APP_CLIENT,
- APP_SERVER,
-} gatt_app_type_t;
-
struct pending_trans_data {
unsigned int id;
uint8_t opcode;
int32_t id;
uint8_t uuid[16];
- gatt_app_type_t type;
+ gatt_type_t type;
/* Valid for client applications */
struct queue *notifications;
+
+ gatt_conn_cb_t func;
};
struct element_id {
* too. So remove all elements and then destroy queue.
*/
- if (app->type == APP_CLIENT)
+ if (app->type == GATT_CLIENT)
while (queue_peek_head(app->notifications)) {
struct notification_data *notification;
free(app);
}
-static int register_app(const uint8_t *uuid, gatt_app_type_t app_type)
+static struct gatt_app *register_app(const uint8_t *uuid, gatt_type_t type)
{
static int32_t application_id = 1;
struct gatt_app *app;
if (queue_find(gatt_apps, match_app_by_uuid, uuid)) {
error("gatt: app uuid is already on list");
- return 0;
+ return NULL;
}
app = new0(struct gatt_app, 1);
return 0;
}
- app->type = app_type;
+ app->type = type;
- if (app->type == APP_CLIENT) {
+ if (app->type == GATT_CLIENT) {
app->notifications = queue_new();
if (!app->notifications) {
error("gatt: couldn't allocate notifications queue");
destroy_gatt_app(app);
- return 0;
+ return NULL;
}
}
if (!queue_push_head(gatt_apps, app)) {
error("gatt: Cannot push app on the list");
destroy_gatt_app(app);
- return 0;
+ return NULL;
}
- if ((app->type == APP_SERVER) &&
+ if ((app->type == GATT_SERVER) &&
!queue_push_tail(listen_apps, INT_TO_PTR(app->id))) {
error("gatt: Cannot push server on the list");
destroy_gatt_app(app);
- return 0;
+ return NULL;
}
- return app->id;
+ return app;
}
static void handle_client_register(const void *buf, uint16_t len)
{
const struct hal_cmd_gatt_client_register *cmd = buf;
struct hal_ev_gatt_client_register_client ev;
+ struct gatt_app *app;
DBG("");
memset(&ev, 0, sizeof(ev));
- ev.client_if = register_app(cmd->uuid, APP_CLIENT);
+ app = register_app(cmd->uuid, GATT_CLIENT);
- if (ev.client_if)
+ if (app) {
+ ev.client_if = app->id;
ev.status = GATT_SUCCESS;
- else
+ } else
ev.status = GATT_FAILURE;
/* We should send notification with given in cmd UUID */
{
struct hal_ev_gatt_client_disconnect ev;
+ if (connection->app->func) {
+ connection->app->func(&connection->device->bdaddr, -ENOTCONN,
+ connection->device->attrib);
+ return;
+ }
+
ev.client_if = connection->app->id;
ev.conn_id = connection->id;
ev.status = status;
{
struct hal_ev_gatt_client_connect ev;
+ if (connection->app->func) {
+ connection->app->func(&connection->device->bdaddr,
+ status == GATT_SUCCESS ? 0 : -ENOTCONN,
+ connection->device->attrib);
+ return;
+ }
+
ev.client_if = connection->app->id;
ev.conn_id = connection->id;
ev.status = status;
{
struct hal_ev_gatt_server_connection ev;
+ if (connection->app->func) {
+ connection->app->func(&connection->device->bdaddr,
+ connected ? 0 : -ENOTCONN,
+ connection->device->attrib);
+ return;
+ }
+
ev.server_if = connection->app->id;
ev.conn_id = connection->id;
ev.connected = connected;
static void send_app_disconnect_notify(struct app_connection *connection,
int32_t status)
{
- if (connection->app->type == APP_CLIENT)
+ if (connection->app->type == GATT_CLIENT)
send_client_disconnection_notify(connection, status);
else
send_server_connection_notify(connection, !!status);
static void send_app_connect_notify(struct app_connection *connection,
int32_t status)
{
- if (connection->app->type == APP_CLIENT)
+ if (connection->app->type == GATT_CLIENT)
send_client_connection_notify(connection, status);
- else
+ else if (connection->app->type == GATT_SERVER)
send_server_connection_notify(connection, !status);
}
switch (cmd->command) {
case GATT_CLIENT_TEST_CMD_ENABLE:
if (cmd->u1) {
- if (!test_client_if)
- test_client_if = register_app(TEST_UUID,
- APP_CLIENT);
+ if (!test_client_if) {
+ app = register_app(TEST_UUID, GATT_CLIENT);
+ if (app)
+ test_client_if = app->id;
+ }
if (test_client_if)
status = HAL_STATUS_SUCCESS;
{
const struct hal_cmd_gatt_server_register *cmd = buf;
struct hal_ev_gatt_server_register ev;
+ struct gatt_app *app;
DBG("");
memset(&ev, 0, sizeof(ev));
- ev.server_if = register_app(cmd->uuid, APP_SERVER);
+ app = register_app(cmd->uuid, GATT_SERVER);
- if (ev.server_if)
+ if (app) {
+ ev.server_if = app->id;
ev.status = GATT_SUCCESS;
- else
+ } else
ev.status = GATT_FAILURE;
memcpy(ev.uuid, cmd->uuid, sizeof(ev.uuid));
bt_crypto_unref(crypto);
crypto = NULL;
}
+
+
+unsigned int bt_gatt_register_app(const char *uuid, gatt_type_t type,
+ gatt_conn_cb_t func)
+{
+ struct gatt_app *app;
+ bt_uuid_t uuid128;
+
+ bt_string_to_uuid(&uuid128, uuid);
+ app = register_app((void *) &uuid128.value.u128, type);
+ if (!app)
+ return 0;
+
+ app->func = func;
+
+ return app->id;
+}
+
+bool bt_gatt_unregister_app(unsigned int id)
+{
+ uint8_t status;
+
+ status = unregister_app(id);
+
+ return status != HAL_STATUS_FAILED;
+}
+
+bool bt_gatt_connect_app(unsigned int id, const bdaddr_t *addr)
+{
+ uint8_t status;
+
+ status = handle_connect(id, addr);
+
+ return status != HAL_STATUS_FAILED;
+}
+
+bool bt_gatt_disconnect_app(unsigned int id, const bdaddr_t *addr)
+{
+ struct app_connection match;
+ struct app_connection *conn;
+ struct gatt_device *device;
+ struct gatt_app *app;
+
+ app = find_app_by_id(id);
+ if (!app)
+ return false;
+
+ device = find_device_by_addr(addr);
+ if (!device)
+ return false;
+
+ match.device = device;
+ match.app = app;
+
+ conn = queue_find(app_connections, match_connection_by_device_and_app,
+ &match);
+ if (!conn)
+ return false;
+
+ trigger_disconnection(conn);
+
+ return true;
+}
diff --git a/android/gatt.h b/android/gatt.h
index d4392d9..5ba9161 100644
--- a/android/gatt.h
+++ b/android/gatt.h
bool bt_gatt_register(struct ipc *ipc, const bdaddr_t *addr);
void bt_gatt_unregister(void);
+
+
+typedef enum {
+ GATT_CLIENT,
+ GATT_SERVER,
+} gatt_type_t;
+
+typedef void (*gatt_conn_cb_t)(const bdaddr_t *addr, int err, void *attrib);
+
+unsigned int bt_gatt_register_app(const char *uuid, gatt_type_t type,
+ gatt_conn_cb_t func);
+bool bt_gatt_unregister_app(unsigned int id);
+
+bool bt_gatt_connect_app(unsigned int id, const bdaddr_t *addr);
+bool bt_gatt_disconnect_app(unsigned int id, const bdaddr_t *addr);