OSDN Git Service

Implementation of net_test_bluedroid as a GTest.
authorJoshua Schwarz <joshuaschwarz@google.com>
Thu, 27 Aug 2015 21:15:26 +0000 (14:15 -0700)
committerJoshua Schwarz <joshuaschwarz@google.com>
Mon, 31 Aug 2015 19:08:13 +0000 (12:08 -0700)
Change-Id: If9fc9a26fe58858a107b8ad6ac9f1e757ba07f90

21 files changed:
test/gtest_net_test_bluedroid/Android.mk [new file with mode: 0644]
test/gtest_net_test_bluedroid/base.h [new file with mode: 0644]
test/gtest_net_test_bluedroid/cases/adapter.c [new file with mode: 0644]
test/gtest_net_test_bluedroid/cases/cases.c [new file with mode: 0644]
test/gtest_net_test_bluedroid/cases/cases.h [new file with mode: 0644]
test/gtest_net_test_bluedroid/cases/gatt.c [new file with mode: 0644]
test/gtest_net_test_bluedroid/cases/pan.c [new file with mode: 0644]
test/gtest_net_test_bluedroid/cases/rfcomm.c [new file with mode: 0644]
test/gtest_net_test_bluedroid/main.cpp [new file with mode: 0644]
test/gtest_net_test_bluedroid/support/adapter.c [new file with mode: 0644]
test/gtest_net_test_bluedroid/support/adapter.h [new file with mode: 0644]
test/gtest_net_test_bluedroid/support/callbacks.c [new file with mode: 0644]
test/gtest_net_test_bluedroid/support/callbacks.h [new file with mode: 0644]
test/gtest_net_test_bluedroid/support/gatt.c [new file with mode: 0644]
test/gtest_net_test_bluedroid/support/gatt.h [new file with mode: 0644]
test/gtest_net_test_bluedroid/support/hal.c [new file with mode: 0644]
test/gtest_net_test_bluedroid/support/hal.h [new file with mode: 0644]
test/gtest_net_test_bluedroid/support/pan.c [new file with mode: 0644]
test/gtest_net_test_bluedroid/support/pan.h [new file with mode: 0644]
test/gtest_net_test_bluedroid/support/rfcomm.c [new file with mode: 0644]
test/gtest_net_test_bluedroid/support/rfcomm.h [new file with mode: 0644]

diff --git a/test/gtest_net_test_bluedroid/Android.mk b/test/gtest_net_test_bluedroid/Android.mk
new file mode 100644 (file)
index 0000000..e55766b
--- /dev/null
@@ -0,0 +1,55 @@
+#
+#  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)
diff --git a/test/gtest_net_test_bluedroid/base.h b/test/gtest_net_test_bluedroid/base.h
new file mode 100644 (file)
index 0000000..7f33867
--- /dev/null
@@ -0,0 +1,39 @@
+/******************************************************************************
+ *
+ *  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;
diff --git a/test/gtest_net_test_bluedroid/cases/adapter.c b/test/gtest_net_test_bluedroid/cases/adapter.c
new file mode 100644 (file)
index 0000000..2d20084
--- /dev/null
@@ -0,0 +1,97 @@
+/******************************************************************************
+ *
+ *  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;
+}
diff --git a/test/gtest_net_test_bluedroid/cases/cases.c b/test/gtest_net_test_bluedroid/cases/cases.c
new file mode 100644 (file)
index 0000000..99fd348
--- /dev/null
@@ -0,0 +1,71 @@
+/******************************************************************************
+ *
+ *  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);
diff --git a/test/gtest_net_test_bluedroid/cases/cases.h b/test/gtest_net_test_bluedroid/cases/cases.h
new file mode 100644 (file)
index 0000000..9606b20
--- /dev/null
@@ -0,0 +1,34 @@
+/******************************************************************************
+ *
+ *  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;
diff --git a/test/gtest_net_test_bluedroid/cases/gatt.c b/test/gtest_net_test_bluedroid/cases/gatt.c
new file mode 100644 (file)
index 0000000..a38f7d6
--- /dev/null
@@ -0,0 +1,154 @@
+/******************************************************************************
+ *
+ *  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;
+}
diff --git a/test/gtest_net_test_bluedroid/cases/pan.c b/test/gtest_net_test_bluedroid/cases/pan.c
new file mode 100644 (file)
index 0000000..157bd81
--- /dev/null
@@ -0,0 +1,84 @@
+/******************************************************************************
+ *
+ *  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;
+}
diff --git a/test/gtest_net_test_bluedroid/cases/rfcomm.c b/test/gtest_net_test_bluedroid/cases/rfcomm.c
new file mode 100644 (file)
index 0000000..6cb2793
--- /dev/null
@@ -0,0 +1,76 @@
+/******************************************************************************
+ *
+ *  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;
+}
diff --git a/test/gtest_net_test_bluedroid/main.cpp b/test/gtest_net_test_bluedroid/main.cpp
new file mode 100644 (file)
index 0000000..3de1420
--- /dev/null
@@ -0,0 +1,186 @@
+/******************************************************************************
+ *
+ *  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();
+}
diff --git a/test/gtest_net_test_bluedroid/support/adapter.c b/test/gtest_net_test_bluedroid/support/adapter.c
new file mode 100644 (file)
index 0000000..34ce107
--- /dev/null
@@ -0,0 +1,126 @@
+/******************************************************************************
+ *
+ *  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();
+}
diff --git a/test/gtest_net_test_bluedroid/support/adapter.h b/test/gtest_net_test_bluedroid/support/adapter.h
new file mode 100644 (file)
index 0000000..cae90da
--- /dev/null
@@ -0,0 +1,26 @@
+/******************************************************************************
+ *
+ *  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();
diff --git a/test/gtest_net_test_bluedroid/support/callbacks.c b/test/gtest_net_test_bluedroid/support/callbacks.c
new file mode 100644 (file)
index 0000000..4ad3bf6
--- /dev/null
@@ -0,0 +1,244 @@
+/******************************************************************************
+ *
+ *  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;
+}
diff --git a/test/gtest_net_test_bluedroid/support/callbacks.h b/test/gtest_net_test_bluedroid/support/callbacks.h
new file mode 100644 (file)
index 0000000..de92f15
--- /dev/null
@@ -0,0 +1,53 @@
+/******************************************************************************
+ *
+ *  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);
diff --git a/test/gtest_net_test_bluedroid/support/gatt.c b/test/gtest_net_test_bluedroid/support/gatt.c
new file mode 100644 (file)
index 0000000..31a28f2
--- /dev/null
@@ -0,0 +1,231 @@
+/******************************************************************************
+ *
+ *  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();
+}
diff --git a/test/gtest_net_test_bluedroid/support/gatt.h b/test/gtest_net_test_bluedroid/support/gatt.h
new file mode 100644 (file)
index 0000000..2ef5433
--- /dev/null
@@ -0,0 +1,33 @@
+/******************************************************************************
+ *
+ *  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();
diff --git a/test/gtest_net_test_bluedroid/support/hal.c b/test/gtest_net_test_bluedroid/support/hal.c
new file mode 100644 (file)
index 0000000..89f609b
--- /dev/null
@@ -0,0 +1,114 @@
+/******************************************************************************
+ *
+ *  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;
+}
diff --git a/test/gtest_net_test_bluedroid/support/hal.h b/test/gtest_net_test_bluedroid/support/hal.h
new file mode 100644 (file)
index 0000000..ccf6267
--- /dev/null
@@ -0,0 +1,24 @@
+/******************************************************************************
+ *
+ *  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();
diff --git a/test/gtest_net_test_bluedroid/support/pan.c b/test/gtest_net_test_bluedroid/support/pan.c
new file mode 100644 (file)
index 0000000..2865e81
--- /dev/null
@@ -0,0 +1,76 @@
+/******************************************************************************
+ *
+ *  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();
+}
diff --git a/test/gtest_net_test_bluedroid/support/pan.h b/test/gtest_net_test_bluedroid/support/pan.h
new file mode 100644 (file)
index 0000000..69dd4a9
--- /dev/null
@@ -0,0 +1,31 @@
+/******************************************************************************
+ *
+ *  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();
diff --git a/test/gtest_net_test_bluedroid/support/rfcomm.c b/test/gtest_net_test_bluedroid/support/rfcomm.c
new file mode 100644 (file)
index 0000000..c9d15e4
--- /dev/null
@@ -0,0 +1,28 @@
+/******************************************************************************
+ *
+ *  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;
+}
diff --git a/test/gtest_net_test_bluedroid/support/rfcomm.h b/test/gtest_net_test_bluedroid/support/rfcomm.h
new file mode 100644 (file)
index 0000000..1c2de7b
--- /dev/null
@@ -0,0 +1,25 @@
+/******************************************************************************
+ *
+ *  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);