From 07a245dd1ab6e0f0a215ff3b1e35ab5f3d52e1d9 Mon Sep 17 00:00:00 2001 From: Jakub Tyszkowski Date: Mon, 28 Apr 2014 15:32:00 +0200 Subject: [PATCH] android/gatt: Use common struct for client and server applications This will allow to handle client and server connection using the same connection logic. --- android/gatt.c | 165 ++++++++++++++++++++++++++----------------------- 1 file changed, 89 insertions(+), 76 deletions(-) diff --git a/android/gatt.c b/android/gatt.c index 4a7be5509..11612e6be 100644 --- a/android/gatt.c +++ b/android/gatt.c @@ -68,15 +68,19 @@ static const char const *device_state_str[] = { "CONNECTED", }; -struct gatt_client { - int32_t id; - uint8_t uuid[16]; - struct queue *notifications; -}; +typedef enum { + APP_CLIENT, + APP_SERVER, +} gatt_app_type_t; -struct gatt_server { +struct gatt_app { int32_t id; uint8_t uuid[16]; + + gatt_app_type_t type; + + /* Valid for client applications */ + struct queue *notifications; }; struct element_id { @@ -136,7 +140,7 @@ struct gatt_device { struct connection { struct gatt_device *device; - struct gatt_client *client; + struct gatt_app *app; int32_t id; }; @@ -242,7 +246,7 @@ static void destroy_service(void *data) static bool match_client_by_uuid(const void *data, const void *user_data) { const uint8_t *exp_uuid = user_data; - const struct gatt_client *client = data; + const struct gatt_app *client = data; return !memcmp(exp_uuid, client->uuid, sizeof(client->uuid)); } @@ -250,7 +254,7 @@ static bool match_client_by_uuid(const void *data, const void *user_data) static bool match_server_by_uuid(const void *data, const void *user_data) { const uint8_t *exp_uuid = user_data; - const struct gatt_server *server = data; + const struct gatt_app *server = data; return !memcmp(exp_uuid, server->uuid, sizeof(server->uuid)); } @@ -258,7 +262,7 @@ static bool match_server_by_uuid(const void *data, const void *user_data) static bool match_client_by_id(const void *data, const void *user_data) { int32_t exp_id = PTR_TO_INT(user_data); - const struct gatt_client *client = data; + const struct gatt_app *client = data; return client->id == exp_id; } @@ -266,17 +270,17 @@ static bool match_client_by_id(const void *data, const void *user_data) static bool match_server_by_id(const void *data, const void *user_data) { int32_t exp_id = PTR_TO_INT(user_data); - const struct gatt_server *server = data; + const struct gatt_app *server = data; return server->id == exp_id; } -static struct gatt_client *find_client_by_id(int32_t id) +static struct gatt_app *find_client_by_id(int32_t id) { return queue_find(gatt_clients, match_client_by_id, INT_TO_PTR(id)); } -static struct gatt_server *find_server_by_id(int32_t id) +static struct gatt_app *find_server_by_id(int32_t id) { return queue_find(gatt_servers, match_server_by_id, INT_TO_PTR(id)); } @@ -323,13 +327,13 @@ static bool match_connection_by_id(const void *data, const void *user_data) return conn->id == id; } -static bool match_connection_by_device_and_client(const void *data, +static bool match_connection_by_device_and_app(const void *data, const void *user_data) { const struct connection *conn = data; const struct connection *match = user_data; - return conn->device == match->device && conn->client == match->client; + return conn->device == match->device && conn->app == match->app; } static struct connection *find_connection_by_id(int32_t conn_id) @@ -346,12 +350,12 @@ static bool match_connection_by_device(const void *data, const void *user_data) return conn->device == dev; } -static bool match_connection_by_client(const void *data, const void *user_data) +static bool match_connection_by_app(const void *data, const void *user_data) { const struct connection *conn = data; - const struct gatt_client *client = user_data; + const struct gatt_app *app = user_data; - return conn->client == client; + return conn->app == app; } static struct gatt_device *find_device_by_addr(const bdaddr_t *addr) @@ -453,14 +457,13 @@ static bool match_char_by_element_id(const void *data, const void *user_data) static void destroy_notification(void *data) { struct notification_data *notification = data; - struct gatt_client *client; + struct gatt_app *app; if (--notification->ref) return; - client = notification->conn->client; - queue_remove_if(client->notifications, match_notification, - notification); + app = notification->conn->app; + queue_remove_if(app->notifications, match_notification, notification); free(notification); } @@ -528,7 +531,7 @@ static void connection_cleanup(struct gatt_device *device) static void destroy_gatt_client(void *data) { - struct gatt_client *client = data; + struct gatt_app *client = data; /* First we want to get all notifications and unregister them. * We don't pass unregister_notification to queue_destroy, @@ -549,7 +552,7 @@ static void destroy_gatt_client(void *data) static void destroy_gatt_server(void *data) { - struct gatt_server *server = data; + struct gatt_app *server = data; free(server); } @@ -558,7 +561,7 @@ 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_client *client; + struct gatt_app *client; static int32_t client_cnt = 1; uint8_t status; @@ -572,7 +575,8 @@ static void handle_client_register(const void *buf, uint16_t len) goto failed; } - client = new0(struct gatt_client, 1); + client = new0(struct gatt_app, 1); + client->type = APP_CLIENT; if (!client) { error("gatt: cannot allocate memory for registering client"); status = HAL_STATUS_NOMEM; @@ -623,7 +627,7 @@ static void send_client_disconnection_notify(struct connection *connection, { struct hal_ev_gatt_client_disconnect ev; - ev.client_if = connection->client->id; + ev.client_if = connection->app->id; ev.conn_id = connection->id; ev.status = status; @@ -638,7 +642,7 @@ static void send_client_connection_notify(struct connection *connection, { struct hal_ev_gatt_client_connect ev; - ev.client_if = connection->client->id; + ev.client_if = connection->app->id; ev.conn_id = connection->id; ev.status = status; @@ -648,16 +652,20 @@ static void send_client_connection_notify(struct connection *connection, sizeof(ev), &ev); } -static void send_client_disconnect_notify(struct connection *connection, +static void send_app_disconnect_notify(struct connection *connection, int32_t status) { - send_client_disconnection_notify(connection, status); + if (connection->app->type == APP_CLIENT) + send_client_disconnection_notify(connection, status); + /* TODO: handle APP_SERVER */ } -static void send_client_connect_notify(struct connection *connection, +static void send_app_connect_notify(struct connection *connection, int32_t status) { - send_client_connection_notify(connection, status); + if (connection->app->type == APP_CLIENT) + send_client_connection_notify(connection, status); + /* TODO: handle APP_SERVER */ } static void disconnect_notify_by_device(void *data, void *user_data) @@ -669,10 +677,10 @@ static void disconnect_notify_by_device(void *data, void *user_data) return; if (dev->state == DEVICE_CONNECTED) - send_client_disconnect_notify(conn, GATT_SUCCESS); + send_app_disconnect_notify(conn, GATT_SUCCESS); else if (dev->state == DEVICE_CONNECT_INIT || dev->state == DEVICE_CONNECT_READY) - send_client_connect_notify(conn, GATT_FAILURE); + send_app_connect_notify(conn, GATT_FAILURE); } static void destroy_device(void *data) @@ -937,13 +945,13 @@ struct connect_data { int32_t status; }; -static void send_client_connect_notifications(void *data, void *user_data) +static void send_app_connect_notifications(void *data, void *user_data) { struct connection *conn = data; struct connect_data *con_data = user_data; if (conn->device == con_data->dev) - send_client_connect_notify(conn, con_data->status); + send_app_connect_notify(conn, con_data->status); } static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data) @@ -988,7 +996,7 @@ static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data) reply: data.dev = dev; data.status = status; - queue_foreach(client_connections, send_client_connect_notifications, + queue_foreach(client_connections, send_app_connect_notifications, &data); device_unref(dev); @@ -1141,7 +1149,7 @@ static struct gatt_device *create_device(const bdaddr_t *addr) } static struct connection *create_connection(struct gatt_device *device, - struct gatt_client *client) + struct gatt_app *app) { struct connection *new_conn; static int32_t last_conn_id = 1; @@ -1152,9 +1160,9 @@ static struct connection *create_connection(struct gatt_device *device, return NULL; /* Make connection id unique to connection record - * (client, device) pair. + * (app, device) pair. */ - new_conn->client = client; + new_conn->app = app; new_conn->id = last_conn_id++; if (!queue_push_head(client_connections, new_conn)) { @@ -1174,23 +1182,23 @@ static void trigger_disconnection(struct connection *connection) { /* Notify client */ if (queue_remove(client_connections, connection)) - send_client_disconnect_notify(connection, GATT_SUCCESS); + send_app_disconnect_notify(connection, GATT_SUCCESS); destroy_connection(connection); } -static void client_disconnect_devices(struct gatt_client *client) +static void app_disconnect_devices(struct gatt_app *client) { struct connection *conn; /* find every connection for client record and trigger disconnect */ - conn = queue_remove_if(client_connections, match_connection_by_client, + conn = queue_remove_if(client_connections, match_connection_by_app, client); while (conn) { trigger_disconnection(conn); conn = queue_remove_if(client_connections, - match_connection_by_client, client); + match_connection_by_app, client); } } @@ -1201,7 +1209,7 @@ static bool trigger_connection(struct connection *connection) device_set_state(connection->device, DEVICE_CONNECT_INIT); break; case DEVICE_CONNECTED: - send_client_connect_notify(connection, GATT_SUCCESS); + send_app_connect_notify(connection, GATT_SUCCESS); break; default: break; @@ -1222,7 +1230,7 @@ static void handle_client_unregister(const void *buf, uint16_t len) { const struct hal_cmd_gatt_client_unregister *cmd = buf; uint8_t status; - struct gatt_client *cl; + struct gatt_app *cl; DBG(""); @@ -1235,7 +1243,7 @@ static void handle_client_unregister(const void *buf, uint16_t len) /* Check if there is any connect request or connected device * for this client. If so, remove this client from those lists. */ - client_disconnect_devices(cl); + app_disconnect_devices(cl); destroy_gatt_client(cl); status = HAL_STATUS_SUCCESS; } @@ -1244,33 +1252,37 @@ static void handle_client_unregister(const void *buf, uint16_t len) HAL_OP_GATT_CLIENT_UNREGISTER, status); } -static struct connection *find_connection_by_addr_and_client_id(bdaddr_t *addr, - int32_t client_id) +static struct connection *find_conn(const bdaddr_t *addr, int32_t app_id, + int32_t app_type) { struct connection conn_match; struct gatt_device *dev = NULL; - struct gatt_client *client; + struct gatt_app *app; - /* Check if client is registered */ - client = find_client_by_id(client_id); - if (!client) { - error("gatt: Client id %d not found", client_id); + /* Check if app is registered */ + if (app_type == APP_CLIENT) + app = find_client_by_id(app_id); + else + app = find_server_by_id(app_id); + + if (!app) { + error("gatt: Client id %d not found", app_id); return NULL; } /* Check if device is known */ dev = find_device_by_addr(addr); if (!dev) { - error("gatt: Client id %d not found", client_id); + error("gatt: Client id %d not found", app_id); return NULL; } conn_match.device = dev; - conn_match.client = client; + conn_match.app = app; return queue_find(client_connections, - match_connection_by_device_and_client, - &conn_match); + match_connection_by_device_and_app, + &conn_match); } static void handle_client_connect(const void *buf, uint16_t len) @@ -1279,7 +1291,7 @@ static void handle_client_connect(const void *buf, uint16_t len) struct connection conn_match; struct connection *conn; struct gatt_device *device; - struct gatt_client *client; + struct gatt_app *client; bdaddr_t addr; uint8_t status; @@ -1303,10 +1315,10 @@ static void handle_client_connect(const void *buf, uint16_t len) } conn_match.device = device; - conn_match.client = client; + conn_match.app = client; conn = queue_find(client_connections, - match_connection_by_device_and_client, + match_connection_by_device_and_app, &conn_match); if (!conn) { conn = create_connection(device, client); @@ -2878,7 +2890,7 @@ static void handle_client_register_for_notification(const void *buf, android2bdaddr(&cmd->bdaddr, &addr); - conn = find_connection_by_addr_and_client_id(&addr, cmd->client_if); + conn = find_conn(&addr, cmd->client_if, APP_CLIENT); if (!conn) { status = HAL_STATUS_FAILED; goto failed; @@ -2912,7 +2924,7 @@ static void handle_client_register_for_notification(const void *buf, sizeof(notification->service)); notification->conn = conn; - if (queue_find(conn->client->notifications, match_notification, + if (queue_find(conn->app->notifications, match_notification, notification)) { free(notification); status = HAL_STATUS_SUCCESS; @@ -2951,7 +2963,7 @@ static void handle_client_register_for_notification(const void *buf, */ notification->ref = 2; - if (!queue_push_tail(conn->client->notifications, notification)) { + if (!queue_push_tail(conn->app->notifications, notification)) { unregister_notification(notification); status = HAL_STATUS_FAILED; goto failed; @@ -2983,7 +2995,7 @@ static void handle_client_deregister_for_notification(const void *buf, android2bdaddr(&cmd->bdaddr, &addr); - conn = find_connection_by_addr_and_client_id(&addr, cmd->client_if); + conn = find_conn(&addr, cmd->client_if, APP_CLIENT); if (!conn) { status = HAL_STATUS_FAILED; goto failed; @@ -2995,7 +3007,7 @@ static void handle_client_deregister_for_notification(const void *buf, memcpy(¬if.service, &cmd->srvc_id, sizeof(notif.service)); notif.conn = conn; - notification = queue_find(conn->client->notifications, + notification = queue_find(conn->app->notifications, match_notification, ¬if); if (!notification) { status = HAL_STATUS_FAILED; @@ -3082,7 +3094,7 @@ static void handle_server_register(const void *buf, uint16_t len) { const struct hal_cmd_gatt_server_register *cmd = buf; struct hal_ev_gatt_server_register ev; - struct gatt_server *server; + struct gatt_app *server; static int32_t server_cnt = 1; uint32_t status; @@ -3096,7 +3108,8 @@ static void handle_server_register(const void *buf, uint16_t len) goto failed; } - server = new0(struct gatt_server, 1); + server = new0(struct gatt_app, 1); + server->type = APP_SERVER; if (!server) { error("gatt: Cannot allocate memory for registering server"); status = HAL_STATUS_NOMEM; @@ -3136,7 +3149,7 @@ static void handle_server_unregister(const void *buf, uint16_t len) { const struct hal_cmd_gatt_server_unregister *cmd = buf; uint8_t status; - struct gatt_server *server; + struct gatt_app *server; DBG(""); @@ -3175,7 +3188,7 @@ static void handle_server_add_service(const void *buf, uint16_t len) { const struct hal_cmd_gatt_server_add_service *cmd = buf; char uuidstr[MAX_LEN_UUID_STR]; - struct gatt_server *server; + struct gatt_app *server; struct element_id srvc_id; uint8_t status; @@ -3205,7 +3218,7 @@ failed: static void handle_server_add_included_service(const void *buf, uint16_t len) { const struct hal_cmd_gatt_server_add_inc_service *cmd = buf; - struct gatt_server *server; + struct gatt_app *server; uint8_t status; DBG(""); @@ -3232,7 +3245,7 @@ static void handle_server_add_characteristic(const void *buf, uint16_t len) { const struct hal_cmd_gatt_server_add_characteristic *cmd = buf; char uuidstr[MAX_LEN_UUID_STR]; - struct gatt_server *server; + struct gatt_app *server; bt_uuid_t char_uuid; uint8_t status; @@ -3264,7 +3277,7 @@ static void handle_server_add_descriptor(const void *buf, uint16_t len) { const struct hal_cmd_gatt_server_add_descriptor *cmd = buf; char uuidstr[MAX_LEN_UUID_STR]; - struct gatt_server *server; + struct gatt_app *server; bt_uuid_t descr_uuid; uint8_t status; @@ -3294,7 +3307,7 @@ failed: static void handle_server_start_service(const void *buf, uint16_t len) { const struct hal_cmd_gatt_server_start_service *cmd = buf; - struct gatt_server *server; + struct gatt_app *server; uint8_t status; DBG(""); @@ -3321,7 +3334,7 @@ failed: static void handle_server_stop_service(const void *buf, uint16_t len) { const struct hal_cmd_gatt_server_stop_service *cmd = buf; - struct gatt_server *server; + struct gatt_app *server; uint8_t status; DBG(""); @@ -3347,7 +3360,7 @@ failed: static void handle_server_delete_service(const void *buf, uint16_t len) { const struct hal_cmd_gatt_server_delete_service *cmd = buf; - struct gatt_server *server; + struct gatt_app *server; uint8_t status; DBG(""); -- 2.47.3