--- /dev/null
+#
+# Copyright (C) 2015 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := gtest_net_test_bluedroid
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/../../
+
+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 \
+ main.cpp
+
+LOCAL_SHARED_LIBRARIES += \
+ liblog \
+ libhardware \
+ libhardware_legacy \
+ libcutils
+
+LOCAL_STATIC_LIBRARIES += \
+ libbtcore \
+ libosi
+
+LOCAL_CFLAGS += -Wall -Wno-unused-parameter -Wno-missing-field-initializers -Werror
+
+LOCAL_MULTILIB := 32
+
+include $(BUILD_NATIVE_TEST)
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 <malloc.h>
+#include <stdio.h>
+#include <stdbool.h>
+#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>
+
+#ifndef ARRAY_SIZE
+# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
+#define TASSERT(c, ...) if (!(c)) { fprintf(stderr, "%s:%d: ", __func__, __LINE__); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); return false; }
+
+extern const bt_interface_t *bt_interface;
+extern bt_bdaddr_t bt_remote_bdaddr;
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 "support/adapter.h"
+#include "support/callbacks.h"
+#include "btcore/include/property.h"
+
+bool adapter_enable_disable() {
+ int error;
+
+ CALL_AND_WAIT(error = bt_interface->enable(), adapter_state_changed);
+ TASSERT(error == BT_STATUS_SUCCESS, "Error enabling Bluetooth: %d", error);
+ TASSERT(adapter_get_state() == BT_STATE_ON, "Adapter did not turn on.");
+
+ CALL_AND_WAIT(error = bt_interface->disable(), adapter_state_changed);
+ TASSERT(error == BT_STATUS_SUCCESS, "Error disabling Bluetooth: %d", error);
+ TASSERT(adapter_get_state() == BT_STATE_OFF, "Adapter did not turn off.");
+
+ return true;
+}
+
+bool adapter_repeated_enable_disable() {
+ int i;
+ for (i = 0; i < 10; ++i) {
+ if (!adapter_enable_disable()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool adapter_set_name() {
+ int error;
+ bt_property_t *name = property_new_name("set_name");
+
+ CALL_AND_WAIT(error = bt_interface->set_adapter_property(name), adapter_properties);
+ TASSERT(error == BT_STATUS_SUCCESS, "Error setting device name.");
+ TASSERT(adapter_get_property_count() == 1, "Expected 1 adapter property change, found %d instead.", adapter_get_property_count());
+ TASSERT(adapter_get_property(BT_PROPERTY_BDNAME), "The Bluetooth name property did not change.");
+ TASSERT(property_equals(adapter_get_property(BT_PROPERTY_BDNAME), name), "Bluetooth name '%s' does not match test value", property_as_name(adapter_get_property(BT_PROPERTY_BDNAME))->name);
+
+ property_free(name);
+
+ return true;
+}
+
+bool adapter_get_name() {
+ int error;
+ bt_property_t *name = property_new_name("get_name");
+
+ CALL_AND_WAIT(bt_interface->set_adapter_property(name), adapter_properties);
+ CALL_AND_WAIT(error = bt_interface->get_adapter_property(BT_PROPERTY_BDNAME), adapter_properties);
+ TASSERT(error == BT_STATUS_SUCCESS, "Error getting device name.");
+ TASSERT(adapter_get_property_count() == 1, "Expected 1 adapter property change, found %d instead.", adapter_get_property_count());
+ TASSERT(adapter_get_property(BT_PROPERTY_BDNAME), "The Bluetooth name property did not change.");
+ TASSERT(property_equals(adapter_get_property(BT_PROPERTY_BDNAME), name), "Bluetooth name '%s' does not match test value", property_as_name(adapter_get_property(BT_PROPERTY_BDNAME))->name);
+
+ property_free(name);
+ return true;
+}
+
+bool adapter_start_discovery() {
+ int error;
+
+ CALL_AND_WAIT(error = bt_interface->start_discovery(), discovery_state_changed);
+ TASSERT(error == BT_STATUS_SUCCESS, "Error calling start_discovery: %d", error);
+ TASSERT(adapter_get_discovery_state() == BT_DISCOVERY_STARTED, "Unable to start discovery.");
+
+ return true;
+}
+
+bool adapter_cancel_discovery() {
+ int error;
+
+ CALL_AND_WAIT(bt_interface->start_discovery(), discovery_state_changed);
+ CALL_AND_WAIT(error = bt_interface->cancel_discovery(), discovery_state_changed);
+ TASSERT(error == BT_STATUS_SUCCESS, "Error calling cancel_discovery: %d", error);
+ TASSERT(adapter_get_discovery_state() == BT_DISCOVERY_STOPPED, "Unable to stop discovery.");
+
+ return true;
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 "cases/cases.h"
+
+TEST_CASE_DECL(adapter_enable_disable);
+TEST_CASE_DECL(adapter_repeated_enable_disable);
+TEST_CASE_DECL(adapter_set_name);
+TEST_CASE_DECL(adapter_get_name);
+TEST_CASE_DECL(adapter_start_discovery);
+TEST_CASE_DECL(adapter_cancel_discovery);
+
+TEST_CASE_DECL(rfcomm_connect);
+TEST_CASE_DECL(rfcomm_repeated_connect);
+
+TEST_CASE_DECL(pan_enable);
+TEST_CASE_DECL(pan_connect);
+TEST_CASE_DECL(pan_disconnect);
+TEST_CASE_DECL(pan_quick_reconnect);
+
+TEST_CASE_DECL(gatt_client_register);
+TEST_CASE_DECL(gatt_client_scan);
+TEST_CASE_DECL(gatt_client_advertise);
+TEST_CASE_DECL(gatt_server_register);
+TEST_CASE_DECL(gatt_server_build);
+
+// 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)
+};
+
+// The normal test suite is run with the adapter enabled.
+const test_case_t test_suite[] = {
+ TEST_CASE(adapter_set_name),
+ TEST_CASE(adapter_get_name),
+ TEST_CASE(adapter_start_discovery),
+ TEST_CASE(adapter_cancel_discovery),
+
+ TEST_CASE(rfcomm_connect),
+ TEST_CASE(rfcomm_repeated_connect),
+
+ TEST_CASE(pan_enable),
+ TEST_CASE(pan_connect),
+ TEST_CASE(pan_disconnect),
+
+ TEST_CASE(gatt_client_register),
+ TEST_CASE(gatt_client_scan),
+ TEST_CASE(gatt_client_advertise),
+ TEST_CASE(gatt_server_register),
+ TEST_CASE(gatt_server_build)
+};
+
+const size_t sanity_suite_size = ARRAY_SIZE(sanity_suite);
+const size_t test_suite_size = ARRAY_SIZE(test_suite);
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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"
+
+#define TEST_CASE_DECL(x) bool x()
+#define TEST_CASE(x) { x, #x }
+
+typedef struct {
+ bool (*function)();
+ const char *function_name;
+} test_case_t;
+
+extern const test_case_t test_suite[];
+extern const test_case_t sanity_suite[];
+extern const size_t test_suite_size;
+extern const size_t sanity_suite_size;
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "base.h"
+#include "support/gatt.h"
+#include "support/callbacks.h"
+
+#define DEFAULT_RANDOM_SEED 42
+
+static void create_random_uuid(bt_uuid_t *uuid, int seed) {
+ srand(seed < 0 ? time(NULL) : seed);
+ int i;
+ for (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.
+ bt_uuid_t gatt_client_uuid;
+ create_random_uuid(&gatt_client_uuid, DEFAULT_RANDOM_SEED);
+ CALL_AND_WAIT(gatt_interface->client->register_client(&gatt_client_uuid), btgattc_register_app_cb);
+ TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error registering GATT client 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;
+}
+
+bool gatt_client_advertise() {
+ TASSERT(gatt_interface != NULL, "Null GATT interface.");
+
+ // Registers a new client app.
+ bt_uuid_t gatt_client_uuid;
+ create_random_uuid(&gatt_client_uuid, DEFAULT_RANDOM_SEED);
+ CALL_AND_WAIT(gatt_interface->client->register_client(&gatt_client_uuid), btgattc_register_app_cb);
+ TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error registering GATT client app callback.");
+
+ // Starts advertising.
+ CALL_AND_WAIT(gatt_interface->client->listen(gatt_get_client_interface(), true), btgattc_advertise_cb);
+ TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error starting BLE advertisement.");
+
+ // Stops advertising.
+ CALL_AND_WAIT(gatt_interface->client->listen(gatt_get_client_interface(), false), btgattc_advertise_cb);
+ TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error stopping BLE advertisement.");
+
+ // Unregisters gatt server. No callback is expected.
+ gatt_interface->client->unregister_client(gatt_get_client_interface());
+
+ return true;
+}
+
+bool gatt_server_register() {
+ TASSERT(gatt_interface != NULL, "Null GATT interface.");
+
+ // Registers gatt server.
+ bt_uuid_t gatt_server_uuid;
+ create_random_uuid(&gatt_server_uuid, DEFAULT_RANDOM_SEED);
+ CALL_AND_WAIT(gatt_interface->server->register_server(&gatt_server_uuid), btgatts_register_app_cb);
+ TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error registering GATT server app callback.");
+
+ // Unregisters gatt server. No callback is expected.
+ gatt_interface->server->unregister_server(gatt_get_server_interface());
+ return true;
+}
+
+bool gatt_server_build() {
+ TASSERT(gatt_interface != NULL, "Null GATT interface.");
+
+ // Registers gatt server.
+ bt_uuid_t gatt_server_uuid;
+ create_random_uuid(&gatt_server_uuid, DEFAULT_RANDOM_SEED);
+ CALL_AND_WAIT(gatt_interface->server->register_server(&gatt_server_uuid), btgatts_register_app_cb);
+ TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error registering GATT server app callback.");
+
+ // Service UUID.
+ btgatt_srvc_id_t srvc_id;
+ srvc_id.id.inst_id = 0; // there is only one instance of this service.
+ srvc_id.is_primary = 1; // this service is primary.
+ create_random_uuid(&srvc_id.id.uuid, -1);
+
+ // Characteristics UUID.
+ bt_uuid_t char_uuid;
+ create_random_uuid(&char_uuid, -1);
+
+ // Descriptor UUID.
+ bt_uuid_t desc_uuid;
+ create_random_uuid(&desc_uuid, -1);
+
+ // Adds service.
+ int server_if = gatt_get_server_interface();
+ CALL_AND_WAIT(gatt_interface->server->add_service(server_if, &srvc_id, 4 /* # handles */), btgatts_service_added_cb);
+ TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error adding service.");
+
+ // Adds characteristics.
+ int srvc_handle = gatt_get_service_handle();
+ CALL_AND_WAIT(gatt_interface->server->add_characteristic(server_if, srvc_handle, &char_uuid, 0x10 /* notification */, 0x01 /* read only */), btgatts_characteristic_added_cb);
+ TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error adding characteristics.");
+
+ // Adds descriptor.
+ CALL_AND_WAIT(gatt_interface->server->add_descriptor(server_if, srvc_handle, &desc_uuid, 0x01), btgatts_descriptor_added_cb);
+ TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error adding descriptor.");
+
+ // Starts server.
+ CALL_AND_WAIT(gatt_interface->server->start_service(server_if, srvc_handle, 2 /*BREDR/LE*/), btgatts_service_started_cb);
+ TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error starting server.");
+
+ // Stops server.
+ CALL_AND_WAIT(gatt_interface->server->stop_service(server_if, srvc_handle), btgatts_service_stopped_cb);
+ TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error stopping server.");
+
+ // Deletes service.
+ CALL_AND_WAIT(gatt_interface->server->delete_service(server_if, srvc_handle), btgatts_service_deleted_cb);
+ TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error deleting service.");
+
+ // Unregisters gatt server. No callback is expected.
+ gatt_interface->server->unregister_server(server_if);
+
+ return true;
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 "support/callbacks.h"
+#include "support/pan.h"
+
+static const int local_role = BTPAN_ROLE_PANU;
+static const int remote_role = BTPAN_ROLE_PANNAP;
+
+bool pan_enable() {
+ int error;
+
+ // PAN is enabled by default, wait for the first control state change
+ // with default parameters set. We don't want to verify the result since
+ // the implementation could have set any parameters.
+ WAIT(pan_control_state_changed);
+
+ // Call enable explicitly and verify that the parameters match what we just set.
+ CALL_AND_WAIT(error = pan_interface->enable(local_role), pan_control_state_changed);
+ TASSERT(error == BT_STATUS_SUCCESS, "Error enabling PAN: %d", error);
+ TASSERT(pan_get_control_state() == BTPAN_STATE_ENABLED, "Control state is disabled.");
+ TASSERT(pan_get_local_role() == local_role, "Unexpected local role: %d", pan_get_local_role());
+ TASSERT(pan_get_error() == BT_STATUS_SUCCESS, "Error in control callback: %d", pan_get_error());
+
+ return true;
+}
+
+bool pan_connect() {
+ int error;
+
+ if (!pan_enable()) {
+ return false;
+ }
+
+ CALL_AND_WAIT(error = pan_interface->connect(&bt_remote_bdaddr, local_role, remote_role), pan_connection_state_changed);
+ TASSERT(error == BT_STATUS_SUCCESS, "Error connecting to remote host: %d", error);
+ TASSERT(pan_get_error() == BT_STATUS_SUCCESS, "Error connecting to BT device: %d", pan_get_error());
+ TASSERT(pan_get_connection_state() == BTPAN_STATE_CONNECTING, "Invalid PAN state after connect: %d", pan_get_connection_state());
+ TASSERT(pan_get_local_role() == local_role, "Incorrect local role: %d", pan_get_local_role());
+ TASSERT(pan_get_remote_role() == remote_role, "Incorrect remote role: %d", pan_get_remote_role());
+
+ WAIT(pan_connection_state_changed);
+ TASSERT(pan_get_error() == BT_STATUS_SUCCESS, "Error connecting to BT device: %d", pan_get_error());
+ TASSERT(pan_get_connection_state() == BTPAN_STATE_CONNECTED, "Invalid PAN state after connect: %d", pan_get_connection_state());
+ TASSERT(pan_get_local_role() == local_role, "Incorrect local role: %d", pan_get_local_role());
+ TASSERT(pan_get_remote_role() == remote_role, "Incorrect remote role: %d", pan_get_remote_role());
+
+ return true;
+}
+
+bool pan_disconnect() {
+ int error;
+
+ if (!pan_connect()) {
+ return false;
+ }
+
+ CALL_AND_WAIT(error = pan_interface->disconnect(&bt_remote_bdaddr), pan_connection_state_changed);
+ TASSERT(error == BT_STATUS_SUCCESS, "Error disconnecting from remote host: %d", error);
+ TASSERT(pan_get_error() == BT_STATUS_SUCCESS, "Error disconnecting from BT device: %d", pan_get_error());
+ TASSERT(pan_get_connection_state() == BTPAN_STATE_DISCONNECTING, "Invalid PAN state after disconnect: %d", pan_get_connection_state());
+
+ WAIT(pan_connection_state_changed);
+ TASSERT(pan_get_error() == BT_STATUS_SUCCESS, "Error disconnecting from BT device: %d", pan_get_error());
+ TASSERT(pan_get_connection_state() == BTPAN_STATE_DISCONNECTED, "Invalid PAN state after disconnect: %d", pan_get_connection_state());
+
+ return true;
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 <sys/socket.h>
+#include <unistd.h>
+
+#include "base.h"
+#include "support/callbacks.h"
+#include "support/rfcomm.h"
+
+static const bt_uuid_t HFP_AG_UUID = {{ 0x00, 0x00, 0x11, 0x1F, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }};
+static const char HANDSHAKE_COMMAND[] = "AT+BRSF=29\r";
+static const char HANDSHAKE_RESPONSE[] = "OK\r\n";
+
+static bool handshake(int fd) {
+ TASSERT(write(fd, HANDSHAKE_COMMAND, sizeof(HANDSHAKE_COMMAND)) == sizeof(HANDSHAKE_COMMAND), "Unable to send HFP handshake.");
+
+ char response[256] = { 0 };
+ size_t total = 0;
+ while (!strstr(response, HANDSHAKE_RESPONSE) && total < sizeof(response)) {
+ ssize_t len = read(fd, response + total, sizeof(response) - total);
+ TASSERT(len != -1 && len != 0, "Unable to read complete response from socket.");
+ total += len;
+ }
+ TASSERT(strstr(response, HANDSHAKE_RESPONSE) != NULL, "No valid response from HFP audio gateway.");
+ return true;
+}
+
+bool rfcomm_connect() {
+ int fd;
+ int error;
+
+ error = socket_interface->connect(&bt_remote_bdaddr, BTSOCK_RFCOMM, (const uint8_t *)&HFP_AG_UUID, 0, &fd, 0);
+ TASSERT(error == BT_STATUS_SUCCESS, "Error creating RFCOMM socket: %d", error);
+ TASSERT(fd != -1, "Error creating RFCOMM socket: invalid fd");
+
+ int channel;
+ sock_connect_signal_t signal;
+ TASSERT(read(fd, &channel, sizeof(channel)) == sizeof(channel), "Channel not read from RFCOMM socket.");
+ TASSERT(read(fd, &signal, sizeof(signal)) == sizeof(signal), "Connection signal not read from RFCOMM socket.");
+
+ TASSERT(!memcmp(&signal.bd_addr, &bt_remote_bdaddr, sizeof(bt_bdaddr_t)), "Connected to a different bdaddr than expected.");
+ TASSERT(channel == signal.channel, "Inconsistent channels returned: %d and %d", channel, signal.channel);
+
+ if (!handshake(fd))
+ return false;
+
+ close(fd);
+ return true;
+}
+
+bool rfcomm_repeated_connect() {
+ static const int max_iterations = 128;
+
+ int i;
+ for (i = 0; i < max_iterations; ++i) {
+ TASSERT(rfcomm_connect(), "Connection failed on attempt %d/%d", i, max_iterations);
+ }
+
+ return true;
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 <cutils/properties.h>
+#include <gtest/gtest.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+extern "C" {
+ #include "base.h"
+ #include "btcore/include/bdaddr.h"
+ #include "cases/cases.h"
+ #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"
+}
+
+static const char *CONFIG_FILE_PATH = "/data/misc/bluedroid/bt_config.conf";
+
+const bt_interface_t *bt_interface;
+bt_bdaddr_t bt_remote_bdaddr;
+
+class CommsTest : public ::testing::Test {
+ protected : CommsTest() { }
+ ~CommsTest() { }
+ virtual void SetUp() {
+ callbacks_init();
+ }
+ virtual void TearDown() {
+ callbacks_cleanup();
+ }
+};
+
+void first_time_setup() {
+ config_t *config = config_new(CONFIG_FILE_PATH);
+ if (!config) {
+ printf("Error: unable to open stack config file.\n");
+ FAIL();
+ }
+ for (const config_section_node_t *node = config_section_begin(config); node != config_section_end(config); node = config_section_next(node)) {
+ const char *name = config_section_name(node);
+ if (config_has_key(config, name, "LinkKey") && string_to_bdaddr(name, &bt_remote_bdaddr)) {
+ break;
+ }
+ }
+ config_free(config);
+ if (bdaddr_is_empty(&bt_remote_bdaddr)) {
+ printf("Error: unable to find paired device in config file.\n");
+ FAIL();
+ } else if (!hal_open(callbacks_get_adapter_struct())) {
+ printf("Unable to open Bluetooth HAL.\n");
+ FAIL();
+ } else if (!btsocket_init()) {
+ printf("Unable to initialize Bluetooth sockets.\n");
+ FAIL();
+ } else if (!pan_init()) {
+ printf("Unable to initialize PAN.\n");
+ FAIL();
+ } else if (!gatt_init()) {
+ printf("Unable to initialize GATT.\n");
+ FAIL();
+ }
+}
+
+void setup() {
+ CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
+}
+
+void cleanup() {
+ CALL_AND_WAIT(bt_interface->disable(), adapter_state_changed);
+}
+
+TEST_F(CommsTest, initial_setup) {
+ first_time_setup();
+}
+
+TEST_F(CommsTest, adapter_enable_disable) {
+ EXPECT_TRUE(sanity_suite[0].function());
+}
+
+TEST_F(CommsTest, adapter_repeated_enable_disable) {
+ EXPECT_TRUE(sanity_suite[1].function());
+}
+
+TEST_F(CommsTest, adapter_set_name) {
+ setup();
+ EXPECT_TRUE(test_suite[0].function());
+ cleanup();
+}
+
+TEST_F(CommsTest, adapter_get_name) {
+ setup();
+ EXPECT_TRUE(test_suite[1].function());
+ cleanup();
+}
+
+TEST_F(CommsTest, adapter_start_discovery) {
+ setup();
+ EXPECT_TRUE(test_suite[2].function());
+ cleanup();
+}
+
+TEST_F(CommsTest, adapter_cancel_discovery) {
+ setup();
+ EXPECT_TRUE(test_suite[3].function());
+ cleanup();
+}
+
+TEST_F(CommsTest, rfcomm_connect) {
+ setup();
+ EXPECT_TRUE(test_suite[4].function());
+ cleanup();
+}
+
+TEST_F(CommsTest, rfcomm_repeated_connect) {
+ setup();
+ EXPECT_TRUE(test_suite[5].function());
+ cleanup();
+}
+
+TEST_F(CommsTest, pan_enable) {
+ setup();
+ EXPECT_TRUE(test_suite[6].function());
+ cleanup();
+}
+
+TEST_F(CommsTest, pan_connect) {
+ setup();
+ EXPECT_TRUE(test_suite[7].function());
+ cleanup();
+}
+
+TEST_F(CommsTest, pan_disconnect) {
+ setup();
+ EXPECT_TRUE(test_suite[8].function());
+ cleanup();
+}
+
+TEST_F(CommsTest, gatt_client_register) {
+ setup();
+ EXPECT_TRUE(test_suite[9].function());
+ cleanup();
+}
+
+TEST_F(CommsTest, gatt_client_scan) {
+ setup();
+ EXPECT_TRUE(test_suite[10].function());
+ cleanup();
+}
+
+TEST_F(CommsTest, gatt_client_advertise) {
+ setup();
+ EXPECT_TRUE(test_suite[11].function());
+ cleanup();
+}
+
+TEST_F(CommsTest, gatt_server_register) {
+ setup();
+ EXPECT_TRUE(test_suite[12].function());
+ cleanup();
+}
+
+TEST_F(CommsTest, gatt_server_build) {
+ setup();
+ EXPECT_TRUE(test_suite[13].function());
+ cleanup();
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 "btcore/include/property.h"
+#include "support/adapter.h"
+#include "support/callbacks.h"
+
+static bt_state_t state;
+static int property_count = 0;
+static bt_property_t *properties = NULL;
+static bt_discovery_state_t discovery_state;
+static bt_acl_state_t acl_state;
+static bt_bond_state_t bond_state;
+
+bt_state_t adapter_get_state() {
+ return state;
+}
+
+int adapter_get_property_count() {
+ return property_count;
+}
+
+bt_property_t *adapter_get_property(bt_property_type_t type) {
+ int i;
+ for (i = 0; i < property_count; ++i) {
+ if (properties[i].type == type) {
+ return &properties[i];
+ }
+ }
+
+ return NULL;
+}
+
+bt_discovery_state_t adapter_get_discovery_state() {
+ return discovery_state;
+}
+
+bt_acl_state_t adapter_get_acl_state() {
+ return acl_state;
+}
+
+// Returns the device bond state.
+bt_bond_state_t adapter_get_bond_state() {
+ return bond_state;
+}
+
+// callback
+void acl_state_changed(bt_status_t status, bt_bdaddr_t *remote_bd_addr, bt_acl_state_t state) {
+ acl_state = state;
+ CALLBACK_RET();
+}
+
+// callback
+void adapter_state_changed(bt_state_t new_state) {
+ state = new_state;
+ CALLBACK_RET();
+}
+
+// callback
+void adapter_properties(bt_status_t status,
+ int num_properties,
+ bt_property_t *new_properties) {
+ property_free_array(properties, property_count);
+ properties = property_copy_array(new_properties, num_properties);
+ property_count = num_properties;
+
+ CALLBACK_RET();
+}
+
+// callback
+void bond_state_changed(bt_status_t status,
+ bt_bdaddr_t *bdaddr,
+ bt_bond_state_t state) {
+ bond_state = state;
+ CALLBACK_RET();
+}
+
+// callback
+void device_found(int num_properties, bt_property_t *properties) {
+ CALLBACK_RET();
+}
+
+// callback
+void discovery_state_changed(bt_discovery_state_t state) {
+ discovery_state = state;
+ CALLBACK_RET();
+}
+
+// callback
+void remote_device_properties(bt_status_t status, bt_bdaddr_t *bd_addr,
+ int num_properties, bt_property_t *properties) {
+ CALLBACK_RET();
+}
+
+// callback
+void ssp_request(
+ bt_bdaddr_t *remote_bd_addr,
+ bt_bdname_t *bd_name,
+ uint32_t cod,
+ bt_ssp_variant_t pairing_variant,
+ uint32_t pass_key) {
+
+ CALLBACK_RET();
+}
+
+// callback
+void thread_evt(bt_cb_thread_evt evt) {
+ CALLBACK_RET();
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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"
+
+bt_state_t adapter_get_state();
+int adapter_get_property_count();
+bt_property_t *adapter_get_property(bt_property_type_t type);
+bt_discovery_state_t adapter_get_discovery_state();
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 "support/callbacks.h"
+
+// Bluetooth callbacks
+void acl_state_changed(bt_status_t status, bt_bdaddr_t *remote_bd_addr, bt_acl_state_t state);
+void adapter_properties(bt_status_t status, int num_properties, bt_property_t *properties);
+void adapter_state_changed(bt_state_t state);
+void bond_state_changed(bt_status_t status, bt_bdaddr_t *remote_bd_addr, bt_bond_state_t state);
+
+void device_found(int num_properties, bt_property_t *properties);
+void discovery_state_changed(bt_discovery_state_t state);
+void remote_device_properties(bt_status_t status, bt_bdaddr_t *bd_addr, int num_properties, bt_property_t *properties);
+void ssp_request(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name, uint32_t cod, bt_ssp_variant_t pairing_variant, uint32_t pass_key);
+void thread_evt(bt_cb_thread_evt evt);
+
+// PAN callbacks
+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;
+ sem_t semaphore;
+} callback_data[] = {
+ // Adapter callbacks
+ { "adapter_state_changed" },
+ { "adapter_properties" },
+ { "remote_device_properties" },
+ { "device_found" },
+ { "discovery_state_changed" },
+ {},
+ { "ssp_request" },
+ { "bond_state_changed" },
+ { "acl_state_changed" },
+ { "thread_evt" },
+ {},
+ {},
+
+ // 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 = {
+ sizeof(bt_callbacks_t),
+ adapter_state_changed, // adapter_state_changed_callback
+ adapter_properties, // adapter_properties_callback
+ remote_device_properties, // remote_device_properties_callback
+ device_found, // device_found_callback
+ discovery_state_changed, // discovery_state_changed_callback
+ NULL, // pin_request_callback
+ ssp_request, // ssp_request_callback
+ bond_state_changed, // bond_state_changed_callback
+ acl_state_changed, // acl_state_changed_callback
+ thread_evt, // callback_thread_event
+ NULL, // dut_mode_recv_callback
+ NULL, // le_test_mode_callback
+ NULL,
+};
+
+static btpan_callbacks_t pan_callbacks = {
+ sizeof(btpan_callbacks_t),
+ pan_control_state_changed, // btpan_control_state_callback
+ 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() {
+ size_t i;
+ for (i = 0; i < ARRAY_SIZE(callback_data); ++i) {
+ sem_init(&callback_data[i].semaphore, 0, 0);
+ }
+}
+
+void callbacks_cleanup() {
+ size_t i;
+ for (i = 0; i < ARRAY_SIZE(callback_data); ++i) {
+ sem_destroy(&callback_data[i].semaphore);
+ }
+}
+
+bt_callbacks_t *callbacks_get_adapter_struct() {
+ return &bt_callbacks;
+}
+
+btpan_callbacks_t *callbacks_get_pan_struct() {
+ return &pan_callbacks;
+}
+
+btgatt_callbacks_t *callbacks_get_gatt_struct() {
+ return &gatt_callbacks;
+}
+
+sem_t *callbacks_get_semaphore(const char *name) {
+ size_t i;
+ for (i = 0; i < ARRAY_SIZE(callback_data); ++i) {
+ if (callback_data[i].name && !strcmp(name, callback_data[i].name)) {
+ return &callback_data[i].semaphore;
+ }
+ }
+ return NULL;
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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"
+
+#include <semaphore.h>
+
+#define WAIT(callback) \
+ do { \
+ sem_t *semaphore = callbacks_get_semaphore(#callback); \
+ sem_wait(semaphore); \
+ } while (0)
+
+#define CALL_AND_WAIT(expression, callback) \
+ do { \
+ sem_t *semaphore = callbacks_get_semaphore(#callback); \
+ while (!sem_trywait(semaphore)); \
+ expression; \
+ sem_wait(semaphore); \
+ } while(0)
+
+// To be called from every exit point of the callback. This macro
+// takes 0 or 1 arguments, the return value of the callback.
+#define CALLBACK_RET(...) do { \
+ sem_t *semaphore = callbacks_get_semaphore(__func__); \
+ sem_post(semaphore); \
+ return __VA_ARGS__; \
+ } while (0)
+
+void callbacks_init();
+void callbacks_cleanup();
+
+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);
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 bt_bdaddr_t remote_bd_addr;
+static int gatt_client_interface;
+static int gatt_server_interface;
+static int gatt_service_handle;
+static int gatt_included_service_handle;
+static int gatt_characteristic_handle;
+static int gatt_descriptor_handle;
+static int gatt_connection_id;
+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_connection_id() {
+ return gatt_connection_id;
+}
+
+int gatt_get_client_interface() {
+ return gatt_client_interface;
+}
+
+int gatt_get_server_interface() {
+ return gatt_server_interface;
+}
+
+int gatt_get_service_handle() {
+ return gatt_service_handle;
+}
+
+int gatt_get_included_service_handle() {
+ return gatt_included_service_handle;
+}
+
+int gatt_get_characteristic_handle() {
+ return gatt_characteristic_handle;
+}
+
+int gatt_get_descriptor_handle() {
+ return gatt_descriptor_handle;
+}
+
+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) {
+ gatt_status = status;
+ gatt_client_interface = client_if;
+ CALLBACK_RET();
+}
+
+// GATT server callbacks
+void btgatts_register_app_cb(int status, int server_if, bt_uuid_t *uuid) {
+ gatt_status = status;
+ gatt_server_interface = server_if;
+ CALLBACK_RET();
+}
+
+void btgatts_connection_cb(int conn_id, int server_if, int connected, bt_bdaddr_t *bda) {
+ gatt_connection_id = conn_id;
+ int i;
+ for (i = 0; i < 6; ++i) {
+ remote_bd_addr.address[i] = bda->address[i];
+ }
+ CALLBACK_RET();
+}
+
+void btgatts_service_added_cb(int status, int server_if, btgatt_srvc_id_t *srvc_id, int srvc_handle) {
+ gatt_status = status;
+ gatt_server_interface = server_if;
+ gatt_service_handle = srvc_handle;
+ CALLBACK_RET();
+}
+
+void btgatts_included_service_added_cb(int status, int server_if, int srvc_handle, int incl_srvc_handle) {
+ gatt_status = status;
+ gatt_server_interface = server_if;
+ gatt_service_handle = srvc_handle;
+ gatt_included_service_handle = 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) {
+ gatt_status = status;
+ gatt_server_interface = server_if;
+ gatt_service_handle = srvc_handle;
+ gatt_characteristic_handle = 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) {
+ gatt_status = status;
+ gatt_server_interface = server_if;
+ gatt_service_handle = srvc_handle;
+ gatt_descriptor_handle = descr_handle;
+ CALLBACK_RET();
+}
+
+void btgatts_service_started_cb(int status, int server_if, int srvc_handle) {
+ gatt_status = status;
+ gatt_server_interface = server_if;
+ gatt_service_handle = srvc_handle;
+ CALLBACK_RET();
+}
+
+void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle) {
+ gatt_status = status;
+ gatt_server_interface = server_if;
+ gatt_service_handle = srvc_handle;
+ CALLBACK_RET();
+}
+
+void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle) {
+ gatt_status = status;
+ gatt_server_interface = server_if;
+ gatt_service_handle = 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();
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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_connection_id();
+int gatt_get_client_interface();
+int gatt_get_server_interface();
+int gatt_get_service_handle();
+int gatt_get_included_service_handle();
+int gatt_get_characteristic_handle();
+int gatt_get_descriptor_handle();
+int gatt_get_status();
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 <signal.h>
+#include <time.h>
+
+#include "base.h"
+#include "support/hal.h"
+#include "osi/include/hash_functions.h"
+#include "osi/include/hash_map.h"
+
+#define TIMER_BUCKET_COUNT 4
+
+static bool set_wake_alarm(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data);
+static int acquire_wake_lock(const char *lock_name);
+static int release_wake_lock(const char *lock_name);
+
+static const bluetooth_device_t *bt_device;
+
+static bt_os_callouts_t callouts = {
+ sizeof(bt_os_callouts_t),
+ set_wake_alarm,
+ acquire_wake_lock,
+ release_wake_lock,
+};
+
+bool hal_open(bt_callbacks_t *callbacks) {
+ hw_module_t *module;
+ if (hw_get_module(BT_STACK_MODULE_ID, (hw_module_t const **)&module)) {
+ return false;
+ }
+
+ hw_device_t *device;
+ if (module->methods->open(module, BT_STACK_MODULE_ID, &device)) {
+ return false;
+ }
+
+ bt_device = (bluetooth_device_t *)device;
+ bt_interface = bt_device->get_bluetooth_interface();
+ if (!bt_interface) {
+ bt_device->common.close((hw_device_t *)&bt_device->common);
+ bt_device = NULL;
+ return false;
+ }
+
+ bool success = (bt_interface->init(callbacks) == BT_STATUS_SUCCESS);
+ success = success && (bt_interface->set_os_callouts(&callouts) == BT_STATUS_SUCCESS);
+ return success;
+}
+
+void hal_close() {
+ if (bt_interface) {
+ bt_interface->cleanup();
+ bt_interface = NULL;
+ }
+
+ if (bt_device) {
+ bt_device->common.close((hw_device_t *)&bt_device->common);
+ bt_device = NULL;
+ }
+}
+
+static bool set_wake_alarm(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data) {
+ static hash_map_t *timers;
+
+ if (!timers) {
+ timers = hash_map_new(TIMER_BUCKET_COUNT, hash_function_pointer, NULL, NULL, NULL);
+ }
+
+ timer_t *timer = hash_map_get(timers, cb);
+ if (!timer) {
+ timer = malloc(sizeof(timer_t));
+ hash_map_set(timers, cb, timer);
+
+ struct sigevent sigevent;
+ memset(&sigevent, 0, sizeof(sigevent));
+ sigevent.sigev_notify = SIGEV_THREAD;
+ sigevent.sigev_notify_function = (void (*)(union sigval))cb;
+ sigevent.sigev_value.sival_ptr = data;
+ timer_create(CLOCK_MONOTONIC, &sigevent, timer);
+ }
+
+ struct itimerspec new_value;
+ new_value.it_value.tv_sec = delay_millis / 1000;
+ new_value.it_value.tv_nsec = (delay_millis % 1000) * 1000 * 1000;
+ new_value.it_interval.tv_sec = 0;
+ new_value.it_interval.tv_nsec = 0;
+ timer_settime(*timer, 0, &new_value, NULL);
+
+ return true;
+}
+
+static int acquire_wake_lock(const char *lock_name) {
+ return BT_STATUS_SUCCESS;
+}
+
+static int release_wake_lock(const char *lock_name) {
+ return BT_STATUS_SUCCESS;
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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"
+
+bool hal_open(bt_callbacks_t *callbacks);
+void hal_close();
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 "support/callbacks.h"
+#include "support/pan.h"
+
+const btpan_interface_t *pan_interface;
+
+static btpan_control_state_t pan_control_state;
+static btpan_connection_state_t pan_connection_state;
+static int pan_local_role;
+static int pan_remote_role;
+static bt_status_t pan_error;
+static char *pan_ifname;
+
+bool pan_init() {
+ pan_interface = bt_interface->get_profile_interface(BT_PROFILE_PAN_ID);
+ return pan_interface->init(callbacks_get_pan_struct()) == BT_STATUS_SUCCESS;
+}
+
+btpan_control_state_t pan_get_control_state() {
+ return pan_control_state;
+}
+
+btpan_connection_state_t pan_get_connection_state() {
+ return pan_connection_state;
+}
+
+int pan_get_local_role() {
+ return pan_local_role;
+}
+
+int pan_get_remote_role() {
+ return pan_remote_role;
+}
+
+bt_status_t pan_get_error() {
+ return pan_error;
+}
+
+// callback
+void pan_control_state_changed(btpan_control_state_t state, bt_status_t error, int local_role, const char *ifname) {
+ free(pan_ifname);
+
+ pan_control_state = state;
+ pan_local_role = local_role;
+ pan_error = error;
+ pan_ifname = strdup(ifname);
+
+ CALLBACK_RET();
+}
+
+// callback
+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) {
+ pan_connection_state = state;
+ pan_error = error;
+ pan_local_role = local_role;
+ pan_remote_role = remote_role;
+ CALLBACK_RET();
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 btpan_interface_t *pan_interface;
+
+bool pan_init();
+
+btpan_control_state_t pan_get_control_state();
+btpan_connection_state_t pan_get_connection_state();
+int pan_get_local_role();
+int pan_get_remote_role();
+bt_status_t pan_get_error();
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 "support/callbacks.h"
+#include "support/rfcomm.h"
+
+const btsock_interface_t *socket_interface;
+
+bool btsocket_init(void) {
+ socket_interface = bt_interface->get_profile_interface(BT_PROFILE_SOCKETS_ID);
+ return socket_interface != NULL;
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 btsock_interface_t *socket_interface;
+
+bool btsocket_init(void);