/* 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)
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 */
{
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);
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)
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>"),