Adds BLE tests to bdtest.
Change-Id: Idcdc01339f0e8a14b6fedf27545566e7efdf53c2
diff --git a/test/suite/Android.mk b/test/suite/Android.mk
index 4ab021f..3caec79 100644
--- a/test/suite/Android.mk
+++ b/test/suite/Android.mk
@@ -27,10 +27,12 @@
LOCAL_SRC_FILES := \
cases/adapter.c \
cases/cases.c \
+ cases/gatt.c \
cases/pan.c \
cases/rfcomm.c \
support/adapter.c \
support/callbacks.c \
+ support/gatt.c \
support/hal.c \
support/pan.c \
support/rfcomm.c \
diff --git a/test/suite/base.h b/test/suite/base.h
index 97963a5..0aa7979 100644
--- a/test/suite/base.h
+++ b/test/suite/base.h
@@ -23,6 +23,7 @@
#include <string.h>
#include <hardware/bluetooth.h>
+#include <hardware/bt_gatt.h>
#include <hardware/bt_pan.h>
#include <hardware/bt_sock.h>
#include <hardware/hardware.h>
diff --git a/test/suite/cases/cases.c b/test/suite/cases/cases.c
index 9dfcb70..10f98a2 100644
--- a/test/suite/cases/cases.c
+++ b/test/suite/cases/cases.c
@@ -34,10 +34,13 @@
TEST_CASE_DECL(pan_disconnect);
TEST_CASE_DECL(pan_quick_reconnect);
+TEST_CASE_DECL(gatt_client_register);
+TEST_CASE_DECL(gatt_client_scan);
+
// These are run with the Bluetooth adapter disabled.
const test_case_t sanity_suite[] = {
TEST_CASE(adapter_enable_disable),
- TEST_CASE(adapter_repeated_enable_disable),
+ TEST_CASE(adapter_repeated_enable_disable)
};
// The normal test suite is run with the adapter enabled.
@@ -53,6 +56,9 @@
TEST_CASE(pan_enable),
TEST_CASE(pan_connect),
TEST_CASE(pan_disconnect),
+
+ TEST_CASE(gatt_client_register),
+ TEST_CASE(gatt_client_scan)
};
const size_t sanity_suite_size = ARRAY_SIZE(sanity_suite);
diff --git a/test/suite/cases/gatt.c b/test/suite/cases/gatt.c
new file mode 100644
index 0000000..f7d8f35
--- /dev/null
+++ b/test/suite/cases/gatt.c
@@ -0,0 +1,42 @@
+#include <stdlib.h>
+#include <time.h>
+
+#include "base.h"
+#include "support/gatt.h"
+#include "support/callbacks.h"
+
+bt_uuid_t app_uuid;
+
+static void assign_random_app_uuid(bt_uuid_t *uuid) {
+ srand(time(NULL));
+ for (int i = 0; i < 16; ++i) {
+ uuid->uu[i] = (uint8_t) (rand() % 256);
+ }
+}
+
+bool gatt_client_register() {
+ TASSERT(gatt_interface != NULL, "Null GATT interface.");
+
+ // Registers gatt client.
+ assign_random_app_uuid(&app_uuid);
+ gatt_interface->client->register_client(&app_uuid);
+ CALL_AND_WAIT(gatt_interface->client->register_client(&app_uuid), btgattc_register_app_cb);
+ TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error registering GATT app callback.");
+
+ // Unregisters gatt client. No callback is expected.
+ gatt_interface->client->unregister_client(gatt_get_client_interface());
+
+ return true;
+}
+
+bool gatt_client_scan() {
+ TASSERT(gatt_interface != NULL, "Null GATT interface.");
+
+ // Starts BLE scan. NB: This test assumes there is a BLE beacon advertising nearby.
+ CALL_AND_WAIT(gatt_interface->client->scan(true), btgattc_scan_result_cb);
+
+ // Ends BLE scan. No callback is expected.
+ gatt_interface->client->scan(false);
+
+ return true;
+}
diff --git a/test/suite/main.c b/test/suite/main.c
index 233bf0c..24cb862 100644
--- a/test/suite/main.c
+++ b/test/suite/main.c
@@ -27,6 +27,7 @@
#include "osi/include/config.h"
#include "support/callbacks.h"
#include "support/hal.h"
+#include "support/gatt.h"
#include "support/pan.h"
#include "support/rfcomm.h"
@@ -175,6 +176,11 @@
return 3;
}
+ if (!gatt_init()) {
+ printf("Unable to initialize GATT.\n");
+ return 4;
+ }
+
watchdog_running = true;
pthread_create(&watchdog_thread, NULL, watchdog_fn, NULL);
diff --git a/test/suite/support/callbacks.c b/test/suite/support/callbacks.c
index 9c5f083..bbec5d2 100644
--- a/test/suite/support/callbacks.c
+++ b/test/suite/support/callbacks.c
@@ -35,6 +35,40 @@
void pan_connection_state_changed(btpan_connection_state_t state, bt_status_t error, const bt_bdaddr_t *bd_addr, int local_role, int remote_role);
void pan_control_state_changed(btpan_control_state_t state, int local_role, bt_status_t error, const char *ifname);
+// GATT client callbacks
+void btgattc_register_app_cb(int status, int clientIf, bt_uuid_t *app_uuid);
+void btgattc_scan_result_cb(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data);
+void btgattc_open_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda);
+void btgattc_close_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda);
+void btgattc_search_complete_cb(int conn_id, int status);
+void btgattc_search_result_cb(int conn_id, btgatt_srvc_id_t *srvc_id);
+void btgattc_get_characteristic_cb(int conn_id, int status, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, int char_prop);
+void btgattc_get_descriptor_cb(int conn_id, int status, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *descr_id);
+void btgattc_get_included_service_cb(int conn_id, int status, btgatt_srvc_id_t *srvc_id, btgatt_srvc_id_t *incl_srvc_id);
+void btgattc_register_for_notification_cb(int conn_id, int registered, int status, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id);
+void btgattc_notify_cb(int conn_id, btgatt_notify_params_t *p_data);
+void btgattc_read_characteristic_cb(int conn_id, int status, btgatt_read_params_t *p_data);
+void btgattc_write_characteristic_cb(int conn_id, int status, btgatt_write_params_t *p_data);
+void btgattc_execute_write_cb(int conn_id, int status);
+void btgattc_read_descriptor_cb(int conn_id, int status, btgatt_read_params_t *p_data);
+void btgattc_write_descriptor_cb(int conn_id, int status, btgatt_write_params_t *p_data);
+void btgattc_remote_rssi_cb(int client_if,bt_bdaddr_t* bda, int rssi, int status);
+void btgattc_advertise_cb(int status, int client_if);
+
+// GATT server callbacks
+void btgatts_register_app_cb(int status, int server_if, bt_uuid_t *uuid);
+void btgatts_connection_cb(int conn_id, int server_if, int connected, bt_bdaddr_t *bda);
+void btgatts_service_added_cb(int status, int server_if, btgatt_srvc_id_t *srvc_id, int srvc_handle);
+void btgatts_included_service_added_cb(int status, int server_if, int srvc_handle, int incl_srvc_handle);
+void btgatts_characteristic_added_cb(int status, int server_if, bt_uuid_t *char_id, int srvc_handle, int char_handle);
+void btgatts_descriptor_added_cb(int status, int server_if, bt_uuid_t *descr_id, int srvc_handle, int descr_handle);
+void btgatts_service_started_cb(int status, int server_if, int srvc_handle);
+void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle);
+void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle);
+void btgatts_request_read_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, int attr_handle, int offset, bool is_long);
+void btgatts_request_write_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, int attr_handle, int offset, int length, bool need_rsp, bool is_prep, uint8_t* value);
+void btgatts_request_exec_write_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, int exec_write);
+void btgatts_response_confirmation_cb(int status, int handle);
static struct {
const char *name;
@@ -57,6 +91,48 @@
// PAN callbacks
{ "pan_control_state_changed" },
{ "pan_connection_state_changed" },
+
+ // GATT client callbacks
+ { "btgattc_register_app_cb" },
+ { "btgattc_scan_result_cb" },
+ { "btgattc_open_cb" },
+ { "btgattc_close_cb" },
+ { "btgattc_search_complete_cb" },
+ { "btgattc_search_result_cb" },
+ { "btgattc_get_characteristic_cb" },
+ { "btgattc_get_descriptor_cb" },
+ { "btgattc_get_included_service_cb" },
+ { "btgattc_register_for_notification_cb" },
+ { "btgattc_notify_cb" },
+ { "btgattc_read_characteristic_cb" },
+ { "btgattc_write_characteristic_cb" },
+ { "btgattc_execute_write_cb" },
+ { "btgattc_read_descriptor_cb" },
+ { "btgattc_write_descriptor_cb" },
+ { "btgattc_remote_rssi_cb" },
+ { "btgattc_advertise_cb" },
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+
+ // GATT server callbacks
+ { "btgatts_register_app_cb" },
+ { "btgatts_connection_cb" },
+ { "btgatts_service_added_cb" },
+ { "btgatts_included_service_added_cb" },
+ { "btgatts_characteristic_added_cb" },
+ { "btgatts_descriptor_added_cb" },
+ { "btgatts_service_started_cb" },
+ { "btgatts_service_stopped_cb" },
+ { "btgatts_service_deleted_cb" },
+ { "btgatts_request_read_cb" },
+ { "btgatts_request_write_cb" },
+ { "btgatts_request_exec_write_cb" },
+ { "btgatts_response_confirmation_cb" },
+
};
static bt_callbacks_t bt_callbacks = {
@@ -82,6 +158,55 @@
pan_connection_state_changed, // btpan_connection_state_callback
};
+static const btgatt_client_callbacks_t gatt_client_callbacks = {
+ btgattc_register_app_cb,
+ btgattc_scan_result_cb,
+ btgattc_open_cb,
+ btgattc_close_cb,
+ btgattc_search_complete_cb,
+ btgattc_search_result_cb,
+ btgattc_get_characteristic_cb,
+ btgattc_get_descriptor_cb,
+ btgattc_get_included_service_cb,
+ btgattc_register_for_notification_cb,
+ btgattc_notify_cb,
+ btgattc_read_characteristic_cb,
+ btgattc_write_characteristic_cb,
+ btgattc_read_descriptor_cb,
+ btgattc_write_descriptor_cb,
+ btgattc_execute_write_cb,
+ btgattc_remote_rssi_cb,
+ btgattc_advertise_cb,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+static const btgatt_server_callbacks_t gatt_server_callbacks = {
+ btgatts_register_app_cb,
+ btgatts_connection_cb,
+ btgatts_service_added_cb,
+ btgatts_included_service_added_cb,
+ btgatts_characteristic_added_cb,
+ btgatts_descriptor_added_cb,
+ btgatts_service_started_cb,
+ btgatts_service_stopped_cb,
+ btgatts_service_deleted_cb,
+ btgatts_request_read_cb,
+ btgatts_request_write_cb,
+ btgatts_request_exec_write_cb,
+ btgatts_response_confirmation_cb
+};
+
+static btgatt_callbacks_t gatt_callbacks = {
+ sizeof(btgatt_callbacks_t),
+ &gatt_client_callbacks,
+ &gatt_server_callbacks
+};
+
void callbacks_init() {
for (size_t i = 0; i < ARRAY_SIZE(callback_data); ++i) {
sem_init(&callback_data[i].semaphore, 0, 0);
@@ -102,6 +227,10 @@
return &pan_callbacks;
}
+btgatt_callbacks_t *callbacks_get_gatt_struct() {
+ return &gatt_callbacks;
+}
+
sem_t *callbacks_get_semaphore(const char *name) {
for (size_t i = 0; i < ARRAY_SIZE(callback_data); ++i) {
if (callback_data[i].name && !strcmp(name, callback_data[i].name)) {
diff --git a/test/suite/support/callbacks.h b/test/suite/support/callbacks.h
index 102e13f..e01de39 100644
--- a/test/suite/support/callbacks.h
+++ b/test/suite/support/callbacks.h
@@ -49,4 +49,5 @@
bt_callbacks_t *callbacks_get_adapter_struct();
btpan_callbacks_t *callbacks_get_pan_struct();
+btgatt_callbacks_t *callbacks_get_gatt_struct();
sem_t *callbacks_get_semaphore(const char *name);
diff --git a/test/suite/support/gatt.c b/test/suite/support/gatt.c
new file mode 100644
index 0000000..3538b74
--- /dev/null
+++ b/test/suite/support/gatt.c
@@ -0,0 +1,167 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+#include "base.h"
+#include "btcore/include/bdaddr.h"
+#include "support/callbacks.h"
+#include "support/gatt.h"
+
+const btgatt_interface_t *gatt_interface;
+static int gatt_client_interface;
+static int gatt_status;
+
+bool gatt_init() {
+ gatt_interface = bt_interface->get_profile_interface(BT_PROFILE_GATT_ID);
+ return gatt_interface->init(callbacks_get_gatt_struct()) == BT_STATUS_SUCCESS;
+}
+
+int gatt_get_client_interface() {
+ return gatt_client_interface;
+}
+
+int gatt_get_status() {
+ return gatt_status;
+}
+
+// GATT client callbacks
+void btgattc_register_app_cb(int status, int clientIf, bt_uuid_t *app_uuid) {
+ gatt_status = status;
+ gatt_client_interface = clientIf;
+ CALLBACK_RET();
+}
+
+void btgattc_scan_result_cb(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data) {
+ CALLBACK_RET();
+}
+
+void btgattc_open_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda) {
+ CALLBACK_RET();
+}
+
+void btgattc_close_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda) {
+ CALLBACK_RET();
+}
+
+void btgattc_search_complete_cb(int conn_id, int status) {
+ CALLBACK_RET();
+}
+
+void btgattc_search_result_cb(int conn_id, btgatt_srvc_id_t *srvc_id) {
+ CALLBACK_RET();
+}
+
+void btgattc_get_characteristic_cb(int conn_id, int status, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, int char_prop) {
+ CALLBACK_RET();
+}
+
+void btgattc_get_descriptor_cb(int conn_id, int status, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *descr_id) {
+ CALLBACK_RET();
+}
+
+void btgattc_get_included_service_cb(int conn_id, int status, btgatt_srvc_id_t *srvc_id, btgatt_srvc_id_t *incl_srvc_id) {
+ CALLBACK_RET();
+}
+
+void btgattc_register_for_notification_cb(int conn_id, int registered, int status, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id) {
+ CALLBACK_RET();
+}
+
+void btgattc_notify_cb(int conn_id, btgatt_notify_params_t *p_data) {
+ CALLBACK_RET();
+}
+
+void btgattc_read_characteristic_cb(int conn_id, int status, btgatt_read_params_t *p_data) {
+ CALLBACK_RET();
+}
+
+void btgattc_write_characteristic_cb(int conn_id, int status, btgatt_write_params_t *p_data) {
+ CALLBACK_RET();
+}
+
+void btgattc_execute_write_cb(int conn_id, int status) {
+ CALLBACK_RET();
+}
+
+void btgattc_read_descriptor_cb(int conn_id, int status, btgatt_read_params_t *p_data) {
+ CALLBACK_RET();
+}
+
+void btgattc_write_descriptor_cb(int conn_id, int status, btgatt_write_params_t *p_data) {
+ CALLBACK_RET();
+}
+
+void btgattc_remote_rssi_cb(int client_if,bt_bdaddr_t* bda, int rssi, int status) {
+ CALLBACK_RET();
+}
+
+void btgattc_advertise_cb(int status, int client_if) {
+ CALLBACK_RET();
+}
+
+// GATT server callbacks
+void btgatts_register_app_cb(int status, int server_if, bt_uuid_t *uuid) {
+ CALLBACK_RET();
+}
+
+void btgatts_connection_cb(int conn_id, int server_if, int connected, bt_bdaddr_t *bda) {
+ CALLBACK_RET();
+}
+
+void btgatts_service_added_cb(int status, int server_if, btgatt_srvc_id_t *srvc_id, int srvc_handle) {
+ CALLBACK_RET();
+}
+
+void btgatts_included_service_added_cb(int status, int server_if, int srvc_handle, int incl_srvc_handle) {
+ CALLBACK_RET();
+}
+
+void btgatts_characteristic_added_cb(int status, int server_if, bt_uuid_t *char_id, int srvc_handle, int char_handle) {
+ CALLBACK_RET();
+}
+
+void btgatts_descriptor_added_cb(int status, int server_if, bt_uuid_t *descr_id, int srvc_handle, int descr_handle) {
+ CALLBACK_RET();
+}
+
+void btgatts_service_started_cb(int status, int server_if, int srvc_handle) {
+ CALLBACK_RET();
+}
+
+void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle) {
+ CALLBACK_RET();
+}
+
+void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle) {
+ CALLBACK_RET();
+}
+
+void btgatts_request_read_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, int attr_handle, int offset, bool is_long) {
+ CALLBACK_RET();
+}
+
+void btgatts_request_write_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, int attr_handle, int offset, int length, bool need_rsp, bool is_prep, uint8_t* value) {
+ CALLBACK_RET();
+}
+
+void btgatts_request_exec_write_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, int exec_write) {
+ CALLBACK_RET();
+}
+
+void btgatts_response_confirmation_cb(int status, int handle) {
+ CALLBACK_RET();
+}
\ No newline at end of file
diff --git a/test/suite/support/gatt.h b/test/suite/support/gatt.h
new file mode 100644
index 0000000..e5a61f2
--- /dev/null
+++ b/test/suite/support/gatt.h
@@ -0,0 +1,27 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+#pragma once
+
+#include "base.h"
+
+extern const btgatt_interface_t *gatt_interface;
+
+bool gatt_init();
+int gatt_get_client_interface();
+int gatt_get_status();
\ No newline at end of file