From: Jerzy Kasenberg <jerzy.kasenberg@tieto.com>
To: <linux-bluetooth@vger.kernel.org>
Cc: Jerzy Kasenberg <jerzy.kasenberg@tieto.com>
Subject: [PATCH 10/10] android/client: Add GATT server methods
Date: Thu, 31 Oct 2013 11:45:15 +0100 [thread overview]
Message-ID: <1383216315-30627-11-git-send-email-jerzy.kasenberg@tieto.com> (raw)
In-Reply-To: <1383216315-30627-1-git-send-email-jerzy.kasenberg@tieto.com>
This patch implements GATT server method calls.
---
android/client/if-gatt.c | 256 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 246 insertions(+), 10 deletions(-)
diff --git a/android/client/if-gatt.c b/android/client/if-gatt.c
index a262b90..e90e58b 100644
--- a/android/client/if-gatt.c
+++ b/android/client/if-gatt.c
@@ -579,6 +579,9 @@ static const btgatt_client_callbacks_t btgatt_client_callbacks = {
/* BT-GATT Server callbacks */
+/* Cache server_if and conn_id for tab completion */
+static char server_if_str[20];
+
/* Callback invoked in response to register_server */
static void gatts_register_server_cb(int status, int server_if,
bt_uuid_t *app_uuid)
@@ -599,6 +602,7 @@ static void gatts_connection_cb(int conn_id, int server_if, int connected,
haltest_info("%s: conn_id=%d server_if=%d connected=%d bda=%s\n",
__func__, conn_id, server_if, connected,
bt_bdaddr_t2str(bda, last_addr));
+ snprintf(conn_id_str, sizeof(conn_id_str), "%d", conn_id);
}
/* Callback invoked in response to create_service */
@@ -607,6 +611,8 @@ static void gatts_service_added_cb(int status, int server_if,
{
char buf[MAX_SRVC_ID_STR_LEN];
+ snprintf(server_if_str, sizeof(server_if_str), "%d", server_if);
+
haltest_info("%s: status=%d server_if=%d srvc_id=%s handle=%x\n",
__func__, status, server_if,
btgatt_srvc_id_t2str(srvc_id, buf), srvc_handle);
@@ -1392,78 +1398,308 @@ const struct interface gatt_client_if = {
static void gatts_register_server_p(int argc, const char *argv[])
{
+ bt_uuid_t uuid;
+
+ RETURN_IF_NULL(if_gatt);
+
+ /* uuid */
+ if (argc <= 2)
+ gatt_str2bt_uuid_t("bed4babe", -1, &uuid);
+ else
+ gatt_str2bt_uuid_t(argv[2], -1, &uuid);
+
+ EXEC(if_gatt->server->register_server, &uuid);
}
/* unregister_server */
+static void gatts_unregister_server_c(int argc, const char **argv,
+ enum_func *enum_func, void **user)
+{
+ if (argc == 3) {
+ *user = server_if_str;
+ *enum_func = enum_one_string;
+ }
+}
+
static void gatts_unregister_server_p(int argc, const char *argv[])
{
+ int server_if;
+
+ RETURN_IF_NULL(if_gatt);
+ VERIFY_SERVER_IF(2, server_if);
+
+ EXEC(if_gatt->server->unregister_server, server_if);
}
/* connect */
+static void gatts_connect_c(int argc, const char **argv, enum_func *enum_func,
+ void **user)
+{
+ if (argc == 3) {
+ *user = server_if_str;
+ *enum_func = enum_one_string;
+ } else if (argc == 4) {
+ *user = NULL;
+ *enum_func = enum_devices;
+ }
+}
+
static void gatts_connect_p(int argc, const char *argv[])
{
+ int server_if;
+ bt_bdaddr_t bd_addr;
+ int is_direct = 1;
+
+ RETURN_IF_NULL(if_gatt);
+ VERIFY_SERVER_IF(2, server_if);
+ VERIFY_ADDR_ARG(3, &bd_addr);
+
+ /* is_direct */
+ if (argc > 4)
+ is_direct = atoi(argv[4]);
+
+ EXEC(if_gatt->server->connect, server_if, &bd_addr, is_direct);
}
/* disconnect */
+static void gatts_disconnect_c(int argc, const char **argv,
+ enum_func *enum_func, void **user)
+{
+ if (argc == 3) {
+ *user = server_if_str;
+ *enum_func = enum_one_string;
+ } else if (argc == 4) {
+ *user = last_addr;
+ *enum_func = enum_one_string;
+ } else if (argc == 5) {
+ *user = conn_id_str;
+ *enum_func = enum_one_string;
+ }
+}
+
static void gatts_disconnect_p(int argc, const char *argv[])
{
+ int server_if;
+ bt_bdaddr_t bd_addr;
+ int conn_id;
+
+ RETURN_IF_NULL(if_gatt);
+ VERIFY_SERVER_IF(2, server_if);
+ VERIFY_ADDR_ARG(3, &bd_addr);
+ VERIFY_CONN_ID(4, conn_id);
+
+ EXEC(if_gatt->server->disconnect, server_if, &bd_addr, conn_id);
}
/* add_service */
+/* Same completion as gatts_unregister_server_c */
+#define gatts_add_service_c gatts_unregister_server_c
+
static void gatts_add_service_p(int argc, const char *argv[])
{
+ int server_if;
+ btgatt_srvc_id_t srvc_id;
+ int num_handles;
+
+ RETURN_IF_NULL(if_gatt);
+ VERIFY_SERVER_IF(2, server_if);
+ VERIFY_SRVC_ID(3, &srvc_id);
+
+ /* num handles */
+ if (argc <= 4) {
+ haltest_error("No num_handles specified\n");
+ return;
+ }
+ num_handles = atoi(argv[4]);
+
+ EXEC(if_gatt->server->add_service, server_if, &srvc_id, num_handles);
}
/* add_included_service */
+/* Same completion as gatts_unregister_server_c */
+#define gatts_add_included_service_c gatts_unregister_server_c
+
static void gatts_add_included_service_p(int argc, const char *argv[])
{
+ int server_if;
+ int service_handle;
+ int included_handle;
+
+ RETURN_IF_NULL(if_gatt);
+ VERIFY_SERVER_IF(2, server_if);
+ VERIFY_SERVICE_HANDLE(3, service_handle);
+ VERIFY_HANDLE(4, included_handle);
+
+ EXEC(if_gatt->server->add_included_service, server_if, service_handle,
+ included_handle);
}
/* add_characteristic */
+/* Same completion as gatts_unregister_server_c */
+#define gatts_add_characteristic_c gatts_unregister_server_c
+
static void gatts_add_characteristic_p(int argc, const char *argv[])
{
+ int server_if;
+ int service_handle;
+ int properties;
+ int permissions;
+ bt_uuid_t uuid;
+
+ RETURN_IF_NULL(if_gatt);
+ VERIFY_SERVER_IF(2, server_if);
+ VERIFY_SERVICE_HANDLE(3, service_handle);
+ VERIFY_UUID(4, &uuid);
+
+ /* properties */
+ if (argc <= 5) {
+ haltest_error("No properties specified\n");
+ return;
+ }
+ properties = atoi(argv[5]);
+
+ /* permissions */
+ if (argc <= 6) {
+ haltest_error("No permissions specified\n");
+ return;
+ }
+ permissions = atoi(argv[6]);
+
+ EXEC(if_gatt->server->add_characteristic, server_if, service_handle,
+ &uuid, properties, permissions);
}
/* add_descriptor */
+/* Same completion as gatts_unregister_server_c */
+#define gatts_add_descriptor_c gatts_unregister_server_c
+
static void gatts_add_descriptor_p(int argc, const char *argv[])
{
+ int server_if;
+ int service_handle;
+ int permissions;
+ bt_uuid_t uuid;
+
+ RETURN_IF_NULL(if_gatt);
+ VERIFY_SERVER_IF(2, server_if);
+ VERIFY_SERVICE_HANDLE(3, service_handle);
+ VERIFY_UUID(4, &uuid);
+
+ /* permissions */
+ if (argc <= 5) {
+ haltest_error("No permissions specified\n");
+ return;
+ }
+ permissions = atoi(argv[5]);
+
+ EXEC(if_gatt->server->add_descriptor, server_if, service_handle, &uuid,
+ permissions);
}
/* start_service */
+/* Same completion as gatts_unregister_server_c */
+#define gatts_start_service_c gatts_unregister_server_c
+
static void gatts_start_service_p(int argc, const char *argv[])
{
+ int server_if;
+ int service_handle;
+ int transport;
+
+ RETURN_IF_NULL(if_gatt);
+ VERIFY_SERVER_IF(2, server_if);
+ VERIFY_SERVICE_HANDLE(3, service_handle);
+
+ /* transport */
+ if (argc <= 4) {
+ haltest_error("No transport specified\n");
+ return;
+ }
+ transport = atoi(argv[4]);
+
+ EXEC(if_gatt->server->start_service, server_if, service_handle,
+ transport);
}
/* stop_service */
+/* Same completion as gatts_unregister_server_c */
+#define gatts_stop_service_c gatts_unregister_server_c
+
static void gatts_stop_service_p(int argc, const char *argv[])
{
+ int server_if;
+ int service_handle;
+
+ RETURN_IF_NULL(if_gatt);
+ VERIFY_SERVER_IF(2, server_if);
+ VERIFY_SERVICE_HANDLE(3, service_handle);
+
+ EXEC(if_gatt->server->stop_service, server_if, service_handle);
}
/* delete_service */
+/* Same completion as gatts_unregister_server_c */
+#define gatts_delete_service_c gatts_unregister_server_c
+
static void gatts_delete_service_p(int argc, const char *argv[])
{
+ int server_if;
+ int service_handle;
+
+ RETURN_IF_NULL(if_gatt);
+ VERIFY_SERVER_IF(2, server_if);
+ VERIFY_SERVICE_HANDLE(3, service_handle);
+
+ EXEC(if_gatt->server->delete_service, server_if, service_handle);
}
/* send_indication */
static void gatts_send_indication_p(int argc, const char *argv[])
{
+ int server_if;
+ int attr_handle;
+ int conn_id;
+ int confirm;
+ char data[200];
+ int len = 0;
+
+ RETURN_IF_NULL(if_gatt);
+ VERIFY_SERVER_IF(2, server_if);
+ VERIFY_HANDLE(3, attr_handle);
+ VERIFY_CONN_ID(4, conn_id);
+
+ /* confirm */
+ if (argc <= 5) {
+ haltest_error("No transport specified\n");
+ return;
+ }
+ confirm = atoi(argv[5]);
+
+ if (argc > 6) {
+ len = strlen(argv[6]);
+ scan_field(argv[6], len, (uint8_t *) data, sizeof(data));
+ }
+
+ EXEC(if_gatt->server->send_indication, server_if, attr_handle, conn_id,
+ len, confirm, data);
}
/* send_response */
static void gatts_send_response_p(int argc, const char *argv[])
{
+ haltest_warn("%s is not implemented yet\n", __func__);
}
#define GATTS_METHODH(n, h) METHOD(#n, gatts_##n##_p, NULL, h)
@@ -1471,19 +1707,19 @@ static void gatts_send_response_p(int argc, const char *argv[])
static struct method server_methods[] = {
GATTS_METHODH(register_server, "[<uuid>]"),
- GATTS_METHODH(unregister_server, "<server_if>"),
- GATTS_METHODH(connect, "<server_if> <addr> [<is_direct>]"),
- GATTS_METHODH(disconnect, "<server_if> <addr> <conn_id>"),
- GATTS_METHODH(add_service, "<server_if> <srvc_id> <num_handles>"),
- GATTS_METHODH(add_included_service,
+ GATTS_METHODCH(unregister_server, "<server_if>"),
+ GATTS_METHODCH(connect, "<server_if> <addr> [<is_direct>]"),
+ GATTS_METHODCH(disconnect, "<server_if> <addr> <conn_id>"),
+ GATTS_METHODCH(add_service, "<server_if> <srvc_id> <num_handles>"),
+ GATTS_METHODCH(add_included_service,
"<server_if> <service_handle> <included_handle>"),
- GATTS_METHODH(add_characteristic,
+ GATTS_METHODCH(add_characteristic,
"<server_if> <service_handle> <uuid> <properites> <permissions>"),
- GATTS_METHODH(add_descriptor, "<server_if> <uuid> <permissions>"),
- GATTS_METHODH(start_service,
+ GATTS_METHODCH(add_descriptor, "<server_if> <uuid> <permissions>"),
+ GATTS_METHODCH(start_service,
"<server_if> <service_handle> <transport>"),
- GATTS_METHODH(stop_service, "<server_if> <service_handle>"),
- GATTS_METHODH(delete_service, "<server_if> <service_handle>"),
+ GATTS_METHODCH(stop_service, "<server_if> <service_handle>"),
+ GATTS_METHODCH(delete_service, "<server_if> <service_handle>"),
GATTS_METHODH(send_indication,
"<server_if> <attr_handle> <conn_id> <confirm> [<data>]"),
GATTS_METHODH(send_response, "<conn_id> <trans_id> <status>"),
--
1.7.9.5
next prev parent reply other threads:[~2013-10-31 10:45 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-31 10:45 [PATCH 00/10] Add GATT support to haltest Jerzy Kasenberg
2013-10-31 10:45 ` [PATCH 01/10] android/client: Add skeleton for GATT interface Jerzy Kasenberg
2013-10-31 10:45 ` [PATCH 02/10] android/client: Add GATT client callbacks code Jerzy Kasenberg
2013-10-31 10:45 ` [PATCH 03/10] android/client: Add complex GATT type formating Jerzy Kasenberg
2013-10-31 10:45 ` [PATCH 04/10] android/client: Add init/cleanup for GATT Jerzy Kasenberg
2013-10-31 10:45 ` [PATCH 05/10] android/client: Add helper macros to verify args Jerzy Kasenberg
2013-10-31 10:45 ` [PATCH 06/10] android/client: Add GATT client method calls Jerzy Kasenberg
2013-10-31 10:45 ` [PATCH 07/10] android/client: Add GATT complex type parsing Jerzy Kasenberg
2013-10-31 10:45 ` [PATCH 08/10] android/client: Add tab completion to GATT client Jerzy Kasenberg
2013-10-31 10:45 ` [PATCH 09/10] android/client: Add GATT server callbacks code Jerzy Kasenberg
2013-10-31 10:45 ` Jerzy Kasenberg [this message]
2013-10-31 14:03 ` [PATCH 00/10] Add GATT support to haltest Johan Hedberg
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=1383216315-30627-11-git-send-email-jerzy.kasenberg@tieto.com \
--to=jerzy.kasenberg@tieto.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