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
next prev 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).