linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ 3/6] android/gatt: Make application API public
Date: Mon,  2 Jun 2014 20:50:04 +0300	[thread overview]
Message-ID: <1401731407-10352-3-git-send-email-luiz.dentz@gmail.com> (raw)
In-Reply-To: <1401731407-10352-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This in future gonna be used by HoG to receive connection notifications.
---
 android/gatt.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++-----------
 android/gatt.h |  15 ++++++
 2 files changed, 130 insertions(+), 28 deletions(-)

diff --git a/android/gatt.c b/android/gatt.c
index 429181f..a893407 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -87,11 +87,6 @@ static const char const *device_state_str[] = {
 	"CONNECTED",
 };
 
-typedef enum {
-	APP_CLIENT,
-	APP_SERVER,
-} gatt_app_type_t;
-
 struct pending_trans_data {
 	unsigned int id;
 	uint8_t opcode;
@@ -101,13 +96,15 @@ struct gatt_app {
 	int32_t id;
 	uint8_t uuid[16];
 
-	gatt_app_type_t type;
+	gatt_type_t type;
 
 	/* Valid for client applications */
 	struct queue *notifications;
 
 	/* Transaction data valid for server application */
 	struct pending_trans_data trans_id;
+
+	gatt_conn_cb_t func;
 };
 
 struct element_id {
@@ -617,7 +614,7 @@ static void destroy_gatt_app(void *data)
 	 * 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;
 
@@ -630,14 +627,14 @@ static void destroy_gatt_app(void *data)
 	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);
@@ -646,14 +643,14 @@ static int register_app(const uint8_t *uuid, gatt_app_type_t app_type)
 		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;
 		}
 	}
 
@@ -664,33 +661,35 @@ static int register_app(const uint8_t *uuid, gatt_app_type_t app_type)
 	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 */
@@ -708,6 +707,12 @@ static void send_client_disconnection_notify(struct app_connection *connection,
 {
 	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;
@@ -716,6 +721,7 @@ static void send_client_disconnection_notify(struct app_connection *connection,
 
 	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT,
 				HAL_EV_GATT_CLIENT_DISCONNECT, sizeof(ev), &ev);
+
 }
 
 static void send_client_connection_notify(struct app_connection *connection,
@@ -723,6 +729,13 @@ static void send_client_connection_notify(struct app_connection *connection,
 {
 	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;
@@ -738,6 +751,13 @@ static void send_server_connection_notify(struct app_connection *connection,
 {
 	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;
@@ -751,7 +771,7 @@ static void send_server_connection_notify(struct app_connection *connection,
 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);
@@ -760,9 +780,9 @@ static void send_app_disconnect_notify(struct app_connection *connection,
 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);
 }
 
@@ -3510,9 +3530,11 @@ static void handle_client_test_command(const void *buf, uint16_t len)
 	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;
@@ -3557,16 +3579,18 @@ 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_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));
@@ -5746,3 +5770,66 @@ void bt_gatt_unregister(void)
 	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_client(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
@@ -23,3 +23,18 @@
 
 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);
-- 
1.9.0


  parent reply	other threads:[~2014-06-02 17:50 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-02 17:50 [PATCH BlueZ 1/6] android/hog: Add copy to HoG implementation from input plugin Luiz Augusto von Dentz
2014-06-02 17:50 ` [PATCH BlueZ 2/6] android/hog: Strip dependencies " Luiz Augusto von Dentz
2014-06-02 17:50 ` Luiz Augusto von Dentz [this message]
2014-06-02 17:50 ` [PATCH BlueZ 4/6] android/bluetooth: Add bt_is_device_le function Luiz Augusto von Dentz
2014-06-02 17:50 ` [PATCH BlueZ 5/6] android/hog: Add support to auto discover primary if not set Luiz Augusto von Dentz
2014-06-02 17:50 ` [PATCH BlueZ 6/6] android/hidhost: Add support for HoG Luiz Augusto von Dentz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1401731407-10352-3-git-send-email-luiz.dentz@gmail.com \
    --to=luiz.dentz@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).