OSDN Git Service

Add a simple classic peer
authorZach Johnson <zachoverflow@google.com>
Wed, 5 Nov 2014 05:43:33 +0000 (21:43 -0800)
committerAndre Eisenbach <eisenbach@google.com>
Mon, 16 Mar 2015 23:51:41 +0000 (16:51 -0700)
device/Android.mk
device/include/classic/peer.h [new file with mode: 0644]
device/src/classic/peer.c [new file with mode: 0644]
device/test/classic/peer_test.cpp [new file with mode: 0644]
doc/log_tags.md
test/run_unit_tests.sh

index b6050aa..18b19dd 100644 (file)
@@ -32,6 +32,7 @@ LOCAL_C_INCLUDES := \
     $(bdroid_C_INCLUDES)
 
 LOCAL_SRC_FILES := \
+    src/classic/peer.c \
     src/controller.c
 
 LOCAL_CFLAGS := $(bdroid_CFLAGS)
@@ -42,3 +43,24 @@ LOCAL_SHARED_LIBRARIES := libc liblog
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 
 include $(BUILD_STATIC_LIBRARY)
+
+#####################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/.. \
+    $(LOCAL_PATH)/../osi/include \
+    $(bdroid_C_INCLUDES)
+
+LOCAL_SRC_FILES := \
+    ../osi/test/AllocationTestHarness.cpp \
+    ./test/classic/peer_test.cpp
+
+LOCAL_CFLAGS := -Wall -Werror $(bdroid_CFLAGS)
+LOCAL_MODULE := net_test_device
+LOCAL_MODULE_TAGS := tests
+LOCAL_SHARED_LIBRARIES := liblog libdl
+LOCAL_STATIC_LIBRARIES := libbtdevice libbtcore libosi libcutils
+
+include $(BUILD_NATIVE_TEST)
diff --git a/device/include/classic/peer.h b/device/include/classic/peer.h
new file mode 100644 (file)
index 0000000..069be72
--- /dev/null
@@ -0,0 +1,34 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Google, Inc.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#pragma once
+
+#include "btcore/include/bdaddr.h"
+
+static const char CLASSIC_PEER_MODULE[] = "classic_peer_module";
+
+typedef struct classic_peer_t classic_peer_t;
+
+// Returns a classic_peer_t for the provided |address|. If the peer
+// already exists, that instance is returned. Otherwise a classic_peer_t
+// is constructed for that |address| and then returned. |address| may not
+// be NULL.
+classic_peer_t *classic_peer_by_address(bt_bdaddr_t *address);
+
+// Returns the bluetooth address of the |peer|. |peer| may not be NULL.
+const bt_bdaddr_t *classic_peer_get_address(classic_peer_t *peer);
diff --git a/device/src/classic/peer.c b/device/src/classic/peer.c
new file mode 100644 (file)
index 0000000..6d1a7b5
--- /dev/null
@@ -0,0 +1,120 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Google, Inc.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#define LOG_TAG "bt_classic_peer"
+
+#include <assert.h>
+#include <cutils/log.h>
+#include <pthread.h>
+#include <stdbool.h>
+
+#include "btcore/include/module.h"
+#include "device/include/classic/peer.h"
+#include "osi/include/allocator.h"
+#include "osi/include/future.h"
+#include "osi/include/hash_map.h"
+#include "osi/include/osi.h"
+
+struct classic_peer_t {
+  bt_bdaddr_t address;
+};
+
+static const size_t number_of_address_buckets = 42;
+
+static bool initialized;
+static pthread_mutex_t bag_of_peers_lock;
+static hash_map_t *peers_by_address;
+
+static bool bdaddr_equality_fn(const void *x, const void *y);
+
+// Module lifecycle functions
+
+static future_t *init(void) {
+  peers_by_address = hash_map_new(
+    number_of_address_buckets,
+    hash_function_bdaddr,
+    NULL,
+    osi_free,
+    bdaddr_equality_fn);
+
+  pthread_mutex_init(&bag_of_peers_lock, NULL);
+
+  initialized = true;
+  return NULL;
+}
+
+static future_t *clean_up(void) {
+  initialized = false;
+
+  hash_map_free(peers_by_address);
+  peers_by_address = NULL;
+
+  pthread_mutex_destroy(&bag_of_peers_lock);
+  return NULL;
+}
+
+const module_t classic_peer_module = {
+  .name = CLASSIC_PEER_MODULE,
+  .init = init,
+  .start_up = NULL,
+  .shut_down = NULL,
+  .clean_up = clean_up,
+  .dependencies = {
+    NULL
+  }
+};
+
+// Interface functions
+
+classic_peer_t *classic_peer_by_address(bt_bdaddr_t *address) {
+  assert(initialized);
+  assert(address != NULL);
+
+  classic_peer_t *peer = hash_map_get(peers_by_address, address);
+
+  if (!peer) {
+    pthread_mutex_lock(&bag_of_peers_lock);
+
+    // Make sure it didn't get added in the meantime
+    peer = hash_map_get(peers_by_address, address);
+    if (peer)
+      goto done;
+
+    // Splice in a new peer struct on behalf of the caller.
+    peer = osi_calloc(sizeof(classic_peer_t));
+    peer->address = *address;
+    hash_map_set(peers_by_address, &peer->address, peer);
+
+    pthread_mutex_unlock(&bag_of_peers_lock);
+  }
+
+done:
+  return peer;
+}
+
+const bt_bdaddr_t *classic_peer_get_address(classic_peer_t *peer) {
+  assert(peer != NULL);
+  return &peer->address;
+}
+
+// Internal functions
+
+// Wrapper for bdaddr_equals used in the hash map of peers by address
+static bool bdaddr_equality_fn(const void *x, const void *y) {
+  return bdaddr_equals((bt_bdaddr_t *)x, (bt_bdaddr_t *)y);
+}
diff --git a/device/test/classic/peer_test.cpp b/device/test/classic/peer_test.cpp
new file mode 100644 (file)
index 0000000..9f8b9ac
--- /dev/null
@@ -0,0 +1,86 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Google, Inc.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#include <gtest/gtest.h>
+
+#include "osi/test/AllocationTestHarness.h"
+
+extern "C" {
+#include "btcore/include/bdaddr.h"
+#include "btcore/include/module.h"
+#include "device/include/classic/peer.h"
+
+extern const module_t classic_peer_module;
+}
+
+class ClassicPeerTest : public AllocationTestHarness {
+  protected:
+    virtual void SetUp() {
+      AllocationTestHarness::SetUp();
+
+      module_management_start();
+      module_init(&classic_peer_module);
+    }
+
+    virtual void TearDown() {
+      module_clean_up(&classic_peer_module);
+      module_management_stop();
+
+      AllocationTestHarness::TearDown();
+    }
+};
+
+TEST_F(ClassicPeerTest, test_basic_get) {
+  bt_bdaddr_t test_address;
+  string_to_bdaddr("12:34:56:78:9A:BC", &test_address);
+
+  classic_peer_t *peer = classic_peer_by_address(&test_address);
+
+  EXPECT_TRUE(peer != NULL);
+  // The stored address should be a copy (different memory address)
+  EXPECT_NE(&test_address, classic_peer_get_address(peer));
+  EXPECT_TRUE(bdaddr_equals(&test_address, classic_peer_get_address(peer)));
+}
+
+TEST_F(ClassicPeerTest, test_multi_get_are_same) {
+  bt_bdaddr_t test_address;
+  string_to_bdaddr("12:34:56:78:9A:BC", &test_address);
+
+  classic_peer_t *peer = classic_peer_by_address(&test_address);
+  classic_peer_t *peer_again = classic_peer_by_address(&test_address);
+
+  EXPECT_TRUE(peer != NULL);
+  EXPECT_TRUE(peer_again != NULL);
+  EXPECT_EQ(peer, peer_again);
+}
+
+TEST_F(ClassicPeerTest, test_multi_get_different) {
+  bt_bdaddr_t test_address0;
+  bt_bdaddr_t test_address1;
+  string_to_bdaddr("12:34:56:78:9A:BC", &test_address0);
+  string_to_bdaddr("42:42:42:42:42:42", &test_address1);
+
+  classic_peer_t *peer0 = classic_peer_by_address(&test_address0);
+  classic_peer_t *peer1 = classic_peer_by_address(&test_address1);
+
+  EXPECT_TRUE(peer0 != NULL);
+  EXPECT_TRUE(peer1 != NULL);
+  EXPECT_TRUE(bdaddr_equals(&test_address0, classic_peer_get_address(peer0)));
+  EXPECT_TRUE(bdaddr_equals(&test_address1, classic_peer_get_address(peer1)));
+}
+
index 0e37e70..9524d51 100644 (file)
@@ -8,6 +8,7 @@ This document lists all of the log tags used by bluedroid.
 * bta_sys_main
 * bt_btif_config
 * bt_btif_config_transcode
+* bt_classic_peer
 * bte_conf
 * BtGatt.btif
 * BtGatt.btif_test
index a8a66ba..cb79d87 100755 (executable)
@@ -2,6 +2,7 @@
 
 known_tests=(
   net_test_btcore
+  net_test_device
   net_test_hci
   net_test_osi
 )