OSDN Git Service

am 3a464232: am ee8592f4: am b7460434: Fix memory corruption of BLE whitelist hashmap
authorNitin Arora <niarora@codeaurora.org>
Tue, 25 Aug 2015 23:37:37 +0000 (23:37 +0000)
committerAndroid Git Automerger <android-git-automerger@android.com>
Tue, 25 Aug 2015 23:37:37 +0000 (23:37 +0000)
* commit '3a464232611595913e0773d215a8e5199f3f9093':
  Fix memory corruption of BLE whitelist hashmap

267 files changed:
.gitignore [new file with mode: 0644]
.gn [new file with mode: 0644]
Android.mk
BUILD.gn [new file with mode: 0644]
HACKING [new file with mode: 0644]
audio_a2dp_hw/Android.mk
audio_a2dp_hw/BUILD.gn [new file with mode: 0644]
audio_a2dp_hw/audio_a2dp_hw.c
bta/BUILD.gn [new file with mode: 0644]
bta/ag/bta_ag_main.c
bta/ag/bta_ag_sco.c
bta/av/bta_av_act.c
bta/av/bta_av_main.c
bta/dm/bta_dm_act.c
bta/dm/bta_dm_api.c
bta/dm/bta_dm_int.h
bta/dm/bta_dm_pm.c
bta/gatt/bta_gattc_act.c [changed mode: 0755->0644]
bta/gatt/bta_gattc_cache.c
bta/gatt/bta_gattc_utils.c
bta/hf_client/bta_hf_client_main.c
bta/hh/bta_hh_api.c
bta/hh/bta_hh_le.c
bta/hl/bta_hl_sdp.c
bta/hl/bta_hl_utils.c
bta/include/bta_api.h
bta/jv/bta_jv_act.c
bta/sdp/bta_sdp_act.c
bta/sys/bta_sys_main.c
btcore/Android.mk
btcore/BUILD.gn [new file with mode: 0644]
btcore/include/hal_util.h [new file with mode: 0644]
btcore/src/counter.c
btcore/src/hal_util.c [new file with mode: 0644]
btcore/src/module.c
btif/BUILD.gn [new file with mode: 0644]
btif/co/bta_hh_co.c
btif/co/bta_hl_co.c
btif/include/btif_common.h
btif/include/btif_gatt_multi_adv_util.h
btif/include/btif_gatt_util.h
btif/include/btif_hl.h
btif/include/btif_profile_queue.h
btif/include/btif_sm.h
btif/include/btif_sock_l2cap.h
btif/include/btif_sock_sdp.h
btif/include/btif_sock_thread.h
btif/include/btif_sock_util.h
btif/include/btif_storage.h
btif/include/stack_manager.h
btif/src/bluetooth.c
btif/src/btif_av.c
btif/src/btif_config.c
btif/src/btif_config_transcode.cpp
btif/src/btif_core.c
btif/src/btif_dm.c
btif/src/btif_gatt.c
btif/src/btif_gatt_client.c
btif/src/btif_gatt_multi_adv_util.c
btif/src/btif_gatt_server.c
btif/src/btif_gatt_test.c
btif/src/btif_gatt_util.c
btif/src/btif_hf.c
btif/src/btif_hf_client.c
btif/src/btif_hh.c
btif/src/btif_hl.c
btif/src/btif_mce.c
btif/src/btif_media_task.c
btif/src/btif_pan.c
btif/src/btif_profile_queue.c
btif/src/btif_rc.c
btif/src/btif_sdp.c
btif/src/btif_sdp_server.c
btif/src/btif_sm.c
btif/src/btif_sock.c
btif/src/btif_sock_l2cap.c
btif/src/btif_sock_rfc.c
btif/src/btif_sock_sco.c
btif/src/btif_sock_sdp.c
btif/src/btif_sock_thread.c
btif/src/btif_sock_util.c
btif/src/btif_storage.c
btif/src/btif_util.c
btif/src/stack_manager.c
build/BUILD.gn [new file with mode: 0644]
build/config/BUILDCONFIG.gn [new file with mode: 0644]
build/secondary/third_party/gtest/BUILD.gn [new file with mode: 0644]
build/secondary/third_party/libchrome/BUILD.gn [new file with mode: 0644]
build/secondary/third_party/tinyxml2/BUILD.gn [new file with mode: 0644]
build/toolchain/gcc/BUILD.gn [new file with mode: 0644]
device/BUILD.gn [new file with mode: 0644]
device/src/classic/peer.c
device/src/controller.c
embdrv/sbc/BUILD.gn [new file with mode: 0644]
gki/BUILD.gn [new file with mode: 0644]
gki/common/gki.h
gki/ulinux/gki_ulinux.c
hci/Android.mk
hci/BUILD.gn [new file with mode: 0644]
hci/include/hci_audio.h
hci/src/btsnoop.c
hci/src/btsnoop_net.c
hci/src/hci_audio.c
hci/src/hci_hal_h4.c
hci/src/hci_hal_mct.c
hci/src/hci_inject.c
hci/src/hci_layer.c
hci/src/hci_packet_parser.c
hci/src/low_power_manager.c
hci/src/packet_fragmenter.c
hci/src/vendor.c
include/bt_target.h
main/Android.mk
main/BUILD.gn [new file with mode: 0644]
main/bte_conf.c
main/bte_logmsg.c
main/bte_main.c
main/stack_config.c
osi/Android.mk
osi/BUILD.gn [new file with mode: 0644]
osi/include/allocator.h
osi/include/atomic.h [deleted file]
osi/include/fixed_queue.h
osi/include/hash_map.h
osi/include/hash_map_utils.h [new file with mode: 0644]
osi/include/log.h
osi/include/osi.h
osi/include/socket_utils/socket_local.h [new file with mode: 0644]
osi/include/socket_utils/sockets.h [new file with mode: 0644]
osi/src/alarm.c
osi/src/allocation_tracker.c
osi/src/allocator.c
osi/src/array.c
osi/src/buffer.c
osi/src/config.c
osi/src/data_dispatcher.c
osi/src/eager_reader.c
osi/src/fixed_queue.c
osi/src/future.c
osi/src/hash_map.c
osi/src/hash_map_utils.c [new file with mode: 0644]
osi/src/reactor.c
osi/src/semaphore.c
osi/src/socket.c
osi/src/socket_utils/README [new file with mode: 0644]
osi/src/socket_utils/socket_local_client.c [new file with mode: 0644]
osi/src/socket_utils/socket_local_server.c [new file with mode: 0644]
osi/src/thread.c
osi/test/allocator_test.cpp [new file with mode: 0644]
osi/test/atomic_test.cpp [deleted file]
osi/test/hash_map_utils_test.cpp [new file with mode: 0644]
profile/src/manager.c
service/Android.mk [new file with mode: 0644]
service/BUILD.gn [new file with mode: 0644]
service/adapter.cpp [new file with mode: 0644]
service/adapter.h [new file with mode: 0644]
service/adapter_state.cpp [new file with mode: 0644]
service/adapter_state.h [new file with mode: 0644]
service/client/main.cpp [new file with mode: 0644]
service/daemon.cpp [new file with mode: 0644]
service/daemon.h [new file with mode: 0644]
service/gatt_server.cpp [new file with mode: 0644]
service/gatt_server.h [new file with mode: 0644]
service/hal/bluetooth_interface.cpp [new file with mode: 0644]
service/hal/bluetooth_interface.h [new file with mode: 0644]
service/hal/fake_bluetooth_interface.cpp [new file with mode: 0644]
service/hal/fake_bluetooth_interface.h [new file with mode: 0644]
service/ipc/binder/IBluetooth.cpp [new file with mode: 0644]
service/ipc/binder/IBluetooth.h [new file with mode: 0644]
service/ipc/binder/IBluetoothCallback.cpp [new file with mode: 0644]
service/ipc/binder/IBluetoothCallback.h [new file with mode: 0644]
service/ipc/binder/bluetooth_binder_server.cpp [new file with mode: 0644]
service/ipc/binder/bluetooth_binder_server.h [new file with mode: 0644]
service/ipc/binder/ipc_handler_binder.cpp [new file with mode: 0644]
service/ipc/binder/ipc_handler_binder.h [new file with mode: 0644]
service/ipc/binder/remote_callback_list.h [new file with mode: 0644]
service/ipc/ipc_handler.cpp [new file with mode: 0644]
service/ipc/ipc_handler.h [new file with mode: 0644]
service/ipc/ipc_handler_unix.cpp [new file with mode: 0644]
service/ipc/ipc_handler_unix.h [new file with mode: 0644]
service/ipc/ipc_manager.cpp [new file with mode: 0644]
service/ipc/ipc_manager.h [new file with mode: 0644]
service/ipc/unix_ipc_host.cpp [new file with mode: 0644]
service/ipc/unix_ipc_host.h [new file with mode: 0644]
service/logging_helpers.cpp [new file with mode: 0644]
service/logging_helpers.h [new file with mode: 0644]
service/main.cpp [new file with mode: 0644]
service/settings.cpp [new file with mode: 0644]
service/settings.h [new file with mode: 0644]
service/switches.h [new file with mode: 0644]
service/test/adapter_unittest.cpp [new file with mode: 0644]
service/test/fake_hal_util.cpp [new file with mode: 0644]
service/test/ipc_unix_unittest.cpp [new file with mode: 0644]
service/test/mock_daemon.h [new file with mode: 0644]
service/test/settings_unittest.cpp [new file with mode: 0644]
service/test/stub_ipc_handler_binder.cpp [new file with mode: 0644]
service/test/uuid_unittest.cpp [new file with mode: 0644]
service/util/atomic_string.cpp [new file with mode: 0644]
service/util/atomic_string.h [new file with mode: 0644]
service/uuid.cpp [new file with mode: 0644]
service/uuid.h [new file with mode: 0644]
stack/BUILD.gn [new file with mode: 0644]
stack/a2dp/a2d_sbc.c
stack/avdt/avdt_ccb.c
stack/avdt/avdt_scb.c
stack/bnep/bnep_utils.c
stack/btm/btm_acl.c
stack/btm/btm_ble.c
stack/btm/btm_ble_adv_filter.c
stack/btm/btm_ble_bgconn.c
stack/btm/btm_ble_gap.c
stack/btm/btm_dev.c
stack/btm/btm_devctl.c
stack/btm/btm_pm.c
stack/btm/btm_sec.c
stack/btu/btu_hcif.c
stack/btu/btu_init.c
stack/btu/btu_task.c
stack/gap/gap_conn.c
stack/gatt/gatt_attr.c
stack/hid/hidh_conn.c
stack/include/avrc_defs.h
stack/include/btm_ble_api.h
stack/include/l2c_api.h
stack/l2cap/l2c_api.c
stack/l2cap/l2c_ble.c
stack/l2cap/l2c_main.c
stack/l2cap/l2cap_client.c
stack/rfcomm/port_api.c
stack/rfcomm/rfc_utils.c
stack/sdp/sdp_api.c
stack/sdp/sdp_utils.c
stack/srvc/srvc_dis.c
stack/srvc/srvc_dis_int.h
test/bluedroidtest/Android.mk
udrv/BUILD.gn [new file with mode: 0644]
udrv/ulinux/uipc.c
utils/BUILD.gn [new file with mode: 0644]
utils/src/bt_utils.c
vendor_libs/BUILD.gn [new file with mode: 0644]
vendor_libs/linux/Android.mk [new file with mode: 0644]
vendor_libs/linux/BUILD.gn [new file with mode: 0644]
vendor_libs/linux/bt_vendor_linux.c [new file with mode: 0644]
vendor_libs/test_vendor_lib/Android.mk [new file with mode: 0644]
vendor_libs/test_vendor_lib/BUILD.gn [new file with mode: 0644]
vendor_libs/test_vendor_lib/data/controller_properties.json [new file with mode: 0644]
vendor_libs/test_vendor_lib/include/command_packet.h [new file with mode: 0644]
vendor_libs/test_vendor_lib/include/dual_mode_controller.h [new file with mode: 0644]
vendor_libs/test_vendor_lib/include/event_packet.h [new file with mode: 0644]
vendor_libs/test_vendor_lib/include/hci_transport.h [new file with mode: 0644]
vendor_libs/test_vendor_lib/include/packet.h [new file with mode: 0644]
vendor_libs/test_vendor_lib/include/packet_stream.h [new file with mode: 0644]
vendor_libs/test_vendor_lib/include/test_channel_transport.h [new file with mode: 0644]
vendor_libs/test_vendor_lib/include/vendor_manager.h [new file with mode: 0644]
vendor_libs/test_vendor_lib/scripts/build_and_run.sh [new file with mode: 0755]
vendor_libs/test_vendor_lib/scripts/test_channel.py [new file with mode: 0644]
vendor_libs/test_vendor_lib/src/bt_vendor.cc [new file with mode: 0644]
vendor_libs/test_vendor_lib/src/command_packet.cc [new file with mode: 0644]
vendor_libs/test_vendor_lib/src/dual_mode_controller.cc [new file with mode: 0644]
vendor_libs/test_vendor_lib/src/event_packet.cc [new file with mode: 0644]
vendor_libs/test_vendor_lib/src/hci_transport.cc [new file with mode: 0644]
vendor_libs/test_vendor_lib/src/packet.cc [new file with mode: 0644]
vendor_libs/test_vendor_lib/src/packet_stream.cc [new file with mode: 0644]
vendor_libs/test_vendor_lib/src/test_channel_transport.cc [new file with mode: 0644]
vendor_libs/test_vendor_lib/src/vendor_manager.cc [new file with mode: 0644]
vendor_libs/test_vendor_lib/test/hci_transport_unittest.cc [new file with mode: 0644]
vendor_libs/test_vendor_lib/test/packet_stream_unittest.cc [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..92b837b
--- /dev/null
@@ -0,0 +1,3 @@
+buildtools
+out
+third_party
diff --git a/.gn b/.gn
new file mode 100644 (file)
index 0000000..947ebac
--- /dev/null
+++ b/.gn
@@ -0,0 +1,22 @@
+#
+#  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.
+#
+
+# This file is used by the GN meta build system to find the root of the source
+# tree and to set startup options. For documentation on the values set in this
+# file, run "gn help dotfile" at the command line.
+
+buildconfig = "//build/config/BUILDCONFIG.gn"
+secondary_source = "//build/secondary/"
index c5d3d16..36b5807 100644 (file)
@@ -17,9 +17,11 @@ ifneq ($(TARGET_BUILD_VARIANT),user)
 bdroid_CFLAGS += -DBLUEDROID_DEBUG
 endif
 
+bdroid_CFLAGS += -DEXPORT_SYMBOL="__attribute__((visibility(\"default\")))"
+
 bdroid_CFLAGS += \
+  -fvisibility=hidden \
   -Wall \
-  -Wno-unused-parameter \
   -Wunused-but-set-variable \
   -UNDEBUG \
   -DLOG_NDEBUG=1
diff --git a/BUILD.gn b/BUILD.gn
new file mode 100644 (file)
index 0000000..c89829f
--- /dev/null
+++ b/BUILD.gn
@@ -0,0 +1,30 @@
+#
+#  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.
+#
+
+# This is the root build file for GN. GN will start processing by loading this
+# file, and recursively load all dependencies until all dependencies are either
+# resolved or known not to exist (which will cause the build to fail). So if
+# you add a new build file, there must be some path of dependencies from this
+# file to your new one or GN won't know about it.
+
+# This pulls in main/BUILD.gn and all of its dependencies.
+group("bluetooth") {
+  deps = [
+    "//main:bluetooth.default",
+    "//service:bluetoothtbd",
+    "//vendor_libs:vendor-libs"
+  ]
+}
diff --git a/HACKING b/HACKING
new file mode 100644 (file)
index 0000000..bf54503
--- /dev/null
+++ b/HACKING
@@ -0,0 +1,44 @@
+Building with GN+ninja
+======================
+
+system/bt is buildable using the GN and and ninja buildtools from the Chromium
+project. After setting up these tools, several third_party packages need to be
+set up to build the stack. It's a simple matter of copying (or sym-linking) some
+packages out of AOSP into "system/bt/third_party":
+
+From AOSP:
+1. "platform/external/libevent" => third_party/libevent. The relevant
+  headers here are "event.h" and "event-config.h". event-config.h from
+  external/libevent is only compatible on Android; this means that you will need
+  to generate a new one based on the current platform. Please follow the
+  instructions in external/libevent/README.android for instructions on how to
+  generate this file.
+2. "platform/external/libchrome" => third_party/libchrome. After that, remove
+the BUILD.gn file that's in libchrome/base. This is a legacy file that only
+works inside the Chromium project and we're using our own from secondary build
+sources.
+3. "platform/external/modp_b64" => third_party/modp_b64
+4. "platform/external/tinyxml2" => third_party/tinyxml2
+
+From Chromium:
+1. "src/testing/gtest" => third_party/gtest
+
+You will also need a fresh checkout of platform/hardware/libhardware and
+platform/system/core for some include dependencies.
+
+BUILD.gn files for all of these packages have already been set up under
+"system/bt/build/secondary/third_party" (note: we don't have a BUILD.gn file for
+modp_b64 since it comes with its own; as the package was imported into AOSP from
+Chromium). To build, run:
+
+1. 'gn args out/Default': This will prompt you to fill the contents of your
+"args.gn" file. Set the two following variables:
+  a. libhw_include_path=<path to your "platform/hardware/libhardware/include">
+  b. core_include_path=<path to your "platform/system/core/include">
+
+Once done, this will create the *.ninja files for the entire project.
+
+2. 'ninja -C out/Default all': This will build all targets (the shared library,
+executables, tests, etc) and put them in out/Default (or whatever you named the
+output directory. To build an individual target, replace "all" with the target
+of your choice, e.g. 'ninja -C out/Default net_test_osi'.
index 959c255..e745d0c 100644 (file)
@@ -15,7 +15,8 @@ LOCAL_CFLAGS += -std=c99 $(bdroid_CFLAGS)
 LOCAL_MODULE := audio.a2dp.default
 LOCAL_MODULE_RELATIVE_PATH := hw
 
-LOCAL_SHARED_LIBRARIES := libcutils liblog
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_STATIC_LIBRARIES := libosi
 
 LOCAL_MODULE_TAGS := optional
 
diff --git a/audio_a2dp_hw/BUILD.gn b/audio_a2dp_hw/BUILD.gn
new file mode 100644 (file)
index 0000000..2c5024a
--- /dev/null
@@ -0,0 +1,27 @@
+#
+#  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.
+#
+
+shared_library("audio.a2dp.default") {
+  sources = [
+    "audio_a2dp_hw.c"
+  ]
+
+  include_dirs = [
+    "include",
+    "//",
+    "//utils/include",
+  ]
+}
index d0b36a0..4c8eca5 100644 (file)
  *
  *****************************************************************************/
 
+#define LOG_TAG "bt_a2dp_hw"
+
 #include <errno.h>
+#include <fcntl.h>
 #include <inttypes.h>
 #include <pthread.h>
 #include <stdint.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/poll.h>
 #include <sys/errno.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
 #include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/un.h>
 #include <unistd.h>
-#include <fcntl.h>
-#include <cutils/str_parms.h>
-#include <cutils/sockets.h>
 
-#include <system/audio.h>
 #include <hardware/audio.h>
-
 #include <hardware/hardware.h>
+#include <system/audio.h>
+
 #include "audio_a2dp_hw.h"
 #include "bt_utils.h"
-
-#define LOG_TAG "bt_a2dp_hw"
+#include "osi/include/hash_map.h"
+#include "osi/include/hash_map_utils.h"
 #include "osi/include/log.h"
+#include "osi/include/socket_utils/sockets.h"
 
 /*****************************************************************************
 **  Constants & Macros
 
 #define CASE_RETURN_STR(const) case const: return #const;
 
-#define FNLOG()             LOG_VERBOSE("%s", __FUNCTION__);
-#define DEBUG(fmt, ...)     LOG_VERBOSE("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
-#define INFO(fmt, ...)      LOG_INFO("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
-#define ERROR(fmt, ...)     LOG_ERROR("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
+#define FNLOG()             LOG_VERBOSE(LOG_TAG, "%s", __FUNCTION__);
+#define DEBUG(fmt, ...)     LOG_VERBOSE(LOG_TAG, "%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
+#define INFO(fmt, ...)      LOG_INFO(LOG_TAG, "%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
+#define ERROR(fmt, ...)     LOG_ERROR(LOG_TAG, "%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
 
 #define ASSERTC(cond, msg, val) if (!(cond)) {ERROR("### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, val);}
 
@@ -199,14 +200,13 @@ static int skt_connect(char *path, size_t buffer_sz)
 {
     int ret;
     int skt_fd;
-    struct sockaddr_un remote;
     int len;
 
     INFO("connect to %s (sz %zu)", path, buffer_sz);
 
     skt_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
 
-    if(socket_local_client_connect(skt_fd, path,
+    if(osi_socket_local_client_connect(skt_fd, path,
             ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0)
     {
         ERROR("failed to connect (%s)", strerror(errno));
@@ -235,8 +235,6 @@ static int skt_connect(char *path, size_t buffer_sz)
 static int skt_read(int fd, void *p, size_t len)
 {
     int read;
-    struct pollfd pfd;
-    struct timespec ts;
 
     FNLOG();
 
@@ -368,7 +366,6 @@ static int check_a2dp_ready(struct a2dp_stream_common *common)
 
 static int a2dp_read_audio_config(struct a2dp_stream_common *common)
 {
-    char cmd = A2DP_CTRL_GET_AUDIO_CONFIG;
     uint32_t sample_rate;
     uint8_t channel_count;
 
@@ -659,8 +656,8 @@ static audio_format_t out_get_format(const struct audio_stream *stream)
 
 static int out_set_format(struct audio_stream *stream, audio_format_t format)
 {
+    UNUSED(stream);
     UNUSED(format);
-    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
     DEBUG("setting format not yet supported (0x%x)", format);
     return -ENOSYS;
 }
@@ -683,8 +680,8 @@ static int out_standby(struct audio_stream *stream)
 
 static int out_dump(const struct audio_stream *stream, int fd)
 {
+    UNUSED(stream);
     UNUSED(fd);
-    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
     FNLOG();
     return 0;
 }
@@ -692,63 +689,55 @@ static int out_dump(const struct audio_stream *stream, int fd)
 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
 {
     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
-    struct str_parms *parms;
-    char keyval[16];
-    int retval;
-    int status = 0;
 
     INFO("state %d", out->common.state);
 
-    parms = str_parms_create_str(kvpairs);
+    hash_map_t *params = hash_map_utils_new_from_string_params(kvpairs);
+    int status = 0;
+
+    if (!params)
+      return status;
+
+    pthread_mutex_lock(&out->common.lock);
 
     /* dump params */
-    str_parms_dump(parms);
+    hash_map_utils_dump_string_keys_string_values(params);
 
-    retval = str_parms_get_str(parms, "closing", keyval, sizeof(keyval));
+    char *keyval = (char *)hash_map_get(params, "closing");
 
-    if (retval >= 0)
+    if (keyval && strcmp(keyval, "true") == 0)
     {
-        if (strcmp(keyval, "true") == 0)
-        {
-            DEBUG("stream closing, disallow any writes");
-            pthread_mutex_lock(&out->common.lock);
-            out->common.state = AUDIO_A2DP_STATE_STOPPING;
-            pthread_mutex_unlock(&out->common.lock);
-        }
+        DEBUG("stream closing, disallow any writes");
+        out->common.state = AUDIO_A2DP_STATE_STOPPING;
     }
 
-    retval = str_parms_get_str(parms, "A2dpSuspended", keyval, sizeof(keyval));
+    keyval = (char *)hash_map_get(params, "A2dpSuspended");
 
-    if (retval >= 0)
+    if (keyval && strcmp(keyval, "true") == 0)
     {
-        pthread_mutex_lock(&out->common.lock);
-        if (strcmp(keyval, "true") == 0)
-        {
-            if (out->common.state == AUDIO_A2DP_STATE_STARTED)
-                status = suspend_audio_datapath(&out->common, false);
-        }
-        else
-        {
-            /* Do not start the streaming automatically. If the phone was streaming
-             * prior to being suspended, the next out_write shall trigger the
-             * AVDTP start procedure */
-            if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED)
-                out->common.state = AUDIO_A2DP_STATE_STANDBY;
-            /* Irrespective of the state, return 0 */
-        }
-        pthread_mutex_unlock(&out->common.lock);
+        if (out->common.state == AUDIO_A2DP_STATE_STARTED)
+            status = suspend_audio_datapath(&out->common, false);
+    }
+    else
+    {
+        /* Do not start the streaming automatically. If the phone was streaming
+         * prior to being suspended, the next out_write shall trigger the
+         * AVDTP start procedure */
+        if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED)
+            out->common.state = AUDIO_A2DP_STATE_STANDBY;
+        /* Irrespective of the state, return 0 */
     }
 
-    str_parms_destroy(parms);
+    pthread_mutex_unlock(&out->common.lock);
+    hash_map_free(params);
 
     return status;
 }
 
 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
 {
+    UNUSED(stream);
     UNUSED(keys);
-    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
-
     FNLOG();
 
     /* add populating param here */
@@ -1019,7 +1008,6 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
     struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
     struct a2dp_stream_out *out;
     int ret = 0;
-    int i;
     UNUSED(address);
     UNUSED(handle);
     UNUSED(devices);
@@ -1127,24 +1115,20 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
 static char * adev_get_parameters(const struct audio_hw_device *dev,
                                   const char *keys)
 {
-    struct str_parms *parms;
     UNUSED(dev);
 
     FNLOG();
 
-    parms = str_parms_create_str(keys);
-
-    str_parms_dump(parms);
-
-    str_parms_destroy(parms);
+    hash_map_t *params = hash_map_utils_new_from_string_params(keys);
+    hash_map_utils_dump_string_keys_string_values(params);
+    hash_map_free(params);
 
     return strdup("");
 }
 
 static int adev_init_check(const struct audio_hw_device *dev)
 {
-    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device*)dev;
-
+    UNUSED(dev);
     FNLOG();
 
     return 0;
@@ -1325,7 +1309,6 @@ static int adev_open(const hw_module_t* module, const char* name,
                      hw_device_t** device)
 {
     struct a2dp_audio_device *adev;
-    int ret;
 
     INFO(" adev_open in A2dp_hw module");
     FNLOG();
diff --git a/bta/BUILD.gn b/bta/BUILD.gn
new file mode 100644 (file)
index 0000000..756a80d
--- /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.
+#
+
+static_library("bta") {
+  sources = [
+    "ag/bta_ag_act.c",
+    "ag/bta_ag_api.c",
+    "ag/bta_ag_at.c",
+    "ag/bta_ag_cfg.c",
+    "ag/bta_ag_ci.c",
+    "ag/bta_ag_cmd.c",
+    "ag/bta_ag_main.c",
+    "ag/bta_ag_rfc.c",
+    "ag/bta_ag_sco.c",
+    "ag/bta_ag_sdp.c",
+    "ar/bta_ar.c",
+    "av/bta_av_aact.c",
+    "av/bta_av_act.c",
+    "av/bta_av_api.c",
+    "av/bta_av_cfg.c",
+    "av/bta_av_ci.c",
+    "av/bta_av_main.c",
+    "av/bta_av_sbc.c",
+    "av/bta_av_ssm.c",
+    "dm/bta_dm_act.c",
+    "dm/bta_dm_api.c",
+    "dm/bta_dm_cfg.c",
+    "dm/bta_dm_ci.c",
+    "dm/bta_dm_main.c",
+    "dm/bta_dm_pm.c",
+    "dm/bta_dm_sco.c",
+    "gatt/bta_gattc_act.c",
+    "gatt/bta_gattc_api.c",
+    "gatt/bta_gattc_cache.c",
+    "gatt/bta_gattc_ci.c",
+    "gatt/bta_gattc_main.c",
+    "gatt/bta_gattc_utils.c",
+    "gatt/bta_gatts_act.c",
+    "gatt/bta_gatts_api.c",
+    "gatt/bta_gatts_main.c",
+    "gatt/bta_gatts_utils.c",
+    "hf_client/bta_hf_client_act.c",
+    "hf_client/bta_hf_client_api.c",
+    "hf_client/bta_hf_client_at.c",
+    "hf_client/bta_hf_client_cmd.c",
+    "hf_client/bta_hf_client_main.c",
+    "hf_client/bta_hf_client_rfc.c",
+    "hf_client/bta_hf_client_sdp.c",
+    "hf_client/bta_hf_client_sco.c",
+    "hh/bta_hh_act.c",
+    "hh/bta_hh_api.c",
+    "hh/bta_hh_cfg.c",
+    "hh/bta_hh_le.c",
+    "hh/bta_hh_main.c",
+    "hh/bta_hh_utils.c",
+    "hl/bta_hl_act.c",
+    "hl/bta_hl_api.c",
+    "hl/bta_hl_ci.c",
+    "hl/bta_hl_main.c",
+    "hl/bta_hl_sdp.c",
+    "hl/bta_hl_utils.c",
+    "jv/bta_jv_act.c",
+    "jv/bta_jv_api.c",
+    "jv/bta_jv_cfg.c",
+    "jv/bta_jv_main.c",
+    "mce/bta_mce_act.c",
+    "mce/bta_mce_api.c",
+    "mce/bta_mce_cfg.c",
+    "mce/bta_mce_main.c",
+    "pan/bta_pan_act.c",
+    "pan/bta_pan_api.c",
+    "pan/bta_pan_ci.c",
+    "pan/bta_pan_main.c",
+    "sdp/bta_sdp.c",
+    "sdp/bta_sdp_act.c",
+    "sdp/bta_sdp_api.c",
+    "sdp/bta_sdp_cfg.c",
+    "sys/bta_sys_conn.c",
+    "sys/bta_sys_main.c",
+    "sys/utl.c",
+  ]
+
+  include_dirs = [
+    "dm",
+    "hh",
+    "include",
+    "sys",
+    "//",
+    "//btcore/include",
+    "//gki/common",
+    "//gki/ulinux",
+    "//hci/include",
+    "//include",
+    "//stack/include",
+    "//stack/btm",
+    "//osi/include",
+    "//udrv/include",
+    "//utils/include",
+    "//vnd/include",
+  ]
+}
index b550191..a3c1784 100644 (file)
@@ -321,7 +321,7 @@ static tBTA_AG_SCB *bta_ag_scb_alloc(void)
             p_scb->codec_updated = FALSE;
 #endif
             /* set up timers */
-            p_scb->act_timer.param = (UINT32) p_scb;
+            p_scb->act_timer.param = p_scb;
             p_scb->act_timer.p_cback = bta_ag_timer_cback;
 #if (BTM_WBS_INCLUDED == TRUE)
             /* set eSCO mSBC setting to T2 as the preferred */
@@ -650,7 +650,7 @@ void bta_ag_collision_cback (tBTA_SYS_CONN_STATUS status, UINT8 id,
 
         /* Start timer to han */
         p_scb->colli_timer.p_cback = (TIMER_CBACK*)&bta_ag_colli_timer_cback;
-        p_scb->colli_timer.param = (INT32)p_scb;
+        p_scb->colli_timer.param = p_scb;
         bta_sys_start_timer(&p_scb->colli_timer, 0, BTA_AG_COLLISION_TIMER);
         p_scb->colli_tmr_on = TRUE;
     }
index af6c9bc..c7b3023 100644 (file)
@@ -693,7 +693,7 @@ void bta_ag_codec_negotiate(tBTA_AG_SCB *p_scb)
 
         /* Start timer to handle timeout */
         p_scb->cn_timer.p_cback = (TIMER_CBACK*)&bta_ag_cn_timer_cback;
-        p_scb->cn_timer.param = (INT32)p_scb;
+        p_scb->cn_timer.param = p_scb;
         bta_sys_start_timer(&p_scb->cn_timer, 0, BTA_AG_CODEC_NEGO_TIMEOUT);
     }
     else
index 75e0900..75dbb10 100644 (file)
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_bta_av"
+
 #include "bt_target.h"
+
 #if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
 
 #include <string.h>
+
+#include "avdt_api.h"
 #include "bta_av_api.h"
 #include "bta_av_int.h"
-#include "avdt_api.h"
-#include "utl.h"
 #include "l2c_api.h"
 #include "osi/include/list.h"
+#include "osi/include/osi.h"
+#include "utl.h"
+
 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
 #include "bta_ar_api.h"
 #endif
 
-#define LOG_TAG "bt_bta_av"
 #include "osi/include/log.h"
 
 /*****************************************************************************
@@ -138,7 +143,6 @@ void bta_av_del_rc(tBTA_AV_RCB *p_rcb)
     }
 }
 
-
 /*******************************************************************************
 **
 ** Function         bta_av_close_all_rc
@@ -330,7 +334,6 @@ UINT8 bta_av_rc_create(tBTA_AV_CB *p_cb, UINT8 role, UINT8 shdl, UINT8 lidx)
     /* note: BTA_AV_FEAT_RCTG = AVRC_CT_TARGET, BTA_AV_FEAT_RCCT = AVRC_CT_CONTROL */
     ccb.control = p_cb->features & (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_RCCT | AVRC_CT_PASSIVE);
 
-
     if (AVRC_Open(&rc_handle, &ccb, bda) != AVRC_SUCCESS)
         return BTA_AV_RC_HANDLE_NONE;
 
@@ -504,7 +507,7 @@ void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
             p_scb->rc_handle = p_data->rc_conn_chg.handle;
             APPL_TRACE_DEBUG("bta_av_rc_opened shdl:%d, srch %d", i + 1, p_scb->rc_handle);
             shdl = i+1;
-            LOG_INFO("%s allow incoming AVRCP connections:%d", __func__, p_scb->use_rc);
+            LOG_INFO(LOG_TAG, "%s allow incoming AVRCP connections:%d", __func__, p_scb->use_rc);
             bta_sys_stop_timer(&p_scb->timer);
             disc = p_scb->hndl;
             break;
@@ -518,7 +521,6 @@ void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
         return;
     }
 
-
     if (p_cb->rcb[i].lidx == (BTA_AV_NUM_LINKS + 1) && shdl != 0)
     {
         /* rc is opened on the RC only ACP channel, but is for a specific
@@ -577,7 +579,6 @@ void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
 
 }
 
-
 /*******************************************************************************
 **
 ** Function         bta_av_rc_remote_cmd
@@ -714,8 +715,6 @@ void bta_av_rc_free_msg (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
     UNUSED(p_data);
 }
 
-
-
 /*******************************************************************************
 **
 ** Function         bta_av_chk_notif_evt_id
@@ -835,7 +834,6 @@ tBTA_AV_EVT bta_av_proc_meta_cmd(tAVRC_RESPONSE  *p_rc_rsp, tBTA_AV_RC_MSG *p_ms
             }
             break;
 
-
         case AVRC_PDU_REGISTER_NOTIFICATION:
             /* make sure the event_id is implemented */
             p_rc_rsp->rsp.status = bta_av_chk_notif_evt_id (p_vendor);
@@ -855,7 +853,6 @@ tBTA_AV_EVT bta_av_proc_meta_cmd(tAVRC_RESPONSE  *p_rc_rsp, tBTA_AV_RC_MSG *p_ms
     return evt;
 }
 
-
 /*******************************************************************************
 **
 ** Function         bta_av_rc_msg
@@ -1151,7 +1148,6 @@ void bta_av_stream_chg(tBTA_AV_SCB *p_scb, BOOLEAN started)
     }
 }
 
-
 /*******************************************************************************
 **
 ** Function         bta_av_conn_chg
@@ -1222,7 +1218,6 @@ void bta_av_conn_chg(tBTA_AV_DATA *p_data)
                 bta_av_cb.audio_open_cnt++;
             }
 
-
             APPL_TRACE_DEBUG("rc_acp_handle:%d rc_acp_idx:%d", p_cb->rc_acp_handle, p_cb->rc_acp_idx);
             /* check if the AVRCP ACP channel is already connected */
             if(p_lcb && p_cb->rc_acp_handle != BTA_AV_RC_HANDLE_NONE && p_cb->rc_acp_idx)
@@ -1467,7 +1462,11 @@ void bta_av_sig_chg(tBTA_AV_DATA *p_data)
                         /* Possible collision : need to avoid outgoing processing while the timer is running */
                         p_cb->p_scb[xx]->coll_mask = BTA_AV_COLL_INC_TMR;
 
-                        p_cb->acp_sig_tmr.param = (UINT32)xx;
+                        // TODO(armansito): Why is this variable called "xx" and
+                        // why is it a signed integer? The callback reinterprets
+                        // it as a UINT8 and then reassigns it as param that
+                        // way, so should this be unsigned?
+                        p_cb->acp_sig_tmr.param = INT_TO_PTR(xx);
                         p_cb->acp_sig_tmr.p_cback = (TIMER_CBACK*)&bta_av_acp_sig_timer_cback;
                         bta_sys_start_timer(&p_cb->acp_sig_tmr, 0, BTA_AV_ACP_SIG_TIME_VAL);
                     }
@@ -1564,7 +1563,7 @@ void bta_av_sig_timer(tBTA_AV_DATA *p_data)
 *******************************************************************************/
 static void bta_av_acp_sig_timer_cback (TIMER_LIST_ENT *p_tle)
 {
-    UINT8   inx = (UINT8)p_tle->param;
+    UINT8   inx = PTR_TO_UINT(p_tle->param);
     tBTA_AV_CB  *p_cb = &bta_av_cb;
     tBTA_AV_SCB *p_scb = NULL;
     tBTA_AV_API_OPEN  *p_buf;
@@ -1587,7 +1586,7 @@ static void bta_av_acp_sig_timer_cback (TIMER_LIST_ENT *p_tle)
                     /* We are still doing SDP. Run the timer again. */
                     p_scb->coll_mask |= BTA_AV_COLL_INC_TMR;
 
-                    p_cb->acp_sig_tmr.param = (UINT32)inx;
+                    p_cb->acp_sig_tmr.param = UINT_TO_PTR(inx);
                     p_cb->acp_sig_tmr.p_cback = (TIMER_CBACK *)&bta_av_acp_sig_timer_cback;
                     bta_sys_start_timer(&p_cb->acp_sig_tmr, 0, BTA_AV_ACP_SIG_TIME_VAL);
                 }
index 9a40929..d3aa79f 100644 (file)
@@ -22,6 +22,8 @@
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_bta_av"
+
 #include <assert.h>
 #include <string.h>
 
 #include "osi/include/log.h"
 
 #if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
+#include "bta_av_co.h"
 #include "bta_av_int.h"
-#include "utl.h"
 #include "l2c_api.h"
 #include "l2cdefs.h"
-#include "bta_av_co.h"
+#include "utl.h"
+
 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
 #include "bta_ar_api.h"
 #endif
@@ -167,7 +170,6 @@ static void bta_av_sco_chg_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8
                                  app_id, BD_ADDR peer_addr);
 static void bta_av_sys_rs_cback (tBTA_SYS_CONN_STATUS status,UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
 
-
 /* action functions */
 const tBTA_AV_NSM_ACT bta_av_nsm_act[] =
 {
@@ -397,25 +399,6 @@ static tBTA_AV_SCB * bta_av_alloc_scb(tBTA_AV_CHNL chnl)
 }
 
 /*******************************************************************************
-**
-** Function         bta_av_free_scb
-**
-** Description      free stream control block,
-**
-**
-** Returns          void
-**
-*******************************************************************************/
-static void bta_av_free_scb(tBTA_AV_SCB *p_scb)
-{
-    // NOTE(google) This free currently is not called
-    assert(p_scb != NULL);
-
-    list_free(p_scb->a2d_list);
-    GKI_freebuf(p_scb);
-}
-
-/*******************************************************************************
 *******************************************************************************/
 void bta_av_conn_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
 {
@@ -1125,7 +1108,7 @@ BOOLEAN bta_av_link_role_ok(tBTA_AV_SCB *p_scb, UINT8 bits)
 
     if (BTM_GetRole(p_scb->peer_addr, &role) == BTM_SUCCESS)
     {
-        LOG_INFO("%s hndl:x%x role:%d conn_audio:x%x bits:%d features:x%x",
+        LOG_INFO(LOG_TAG, "%s hndl:x%x role:%d conn_audio:x%x bits:%d features:x%x",
                 __func__, p_scb->hndl, role, bta_av_cb.conn_audio, bits,
                 bta_av_cb.features);
         if (BTM_ROLE_MASTER != role && (A2D_BitsSet(bta_av_cb.conn_audio) > bits || (bta_av_cb.features & BTA_AV_FEAT_MASTER)))
@@ -1281,7 +1264,6 @@ void bta_av_sm_execute(tBTA_AV_CB *p_cb, UINT16 event, tBTA_AV_DATA *p_data)
     }
 }
 
-
 /*******************************************************************************
 **
 ** Function         bta_av_hdl_event
@@ -1332,7 +1314,6 @@ BOOLEAN bta_av_hdl_event(BT_HDR *p_msg)
     return TRUE;
 }
 
-
 /*****************************************************************************
 **  Debug Functions
 *****************************************************************************/
index eb49637..353c853 100644 (file)
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_bta_dm"
+
+#include <string.h>
+
 #include "bt_target.h"
 #include "bt_types.h"
-#include "gki.h"
-#include "bta_sys.h"
 #include "bta_api.h"
-#include "bta_dm_int.h"
 #include "bta_dm_co.h"
+#include "bta_dm_int.h"
+#include "bta_sys.h"
 #include "btm_api.h"
 #include "btm_int.h"
 #include "btu.h"
-#include "sdp_api.h"
-#include "l2c_api.h"
-#include "utl.h"
 #include "gap_api.h"    /* For GAP_BleReadPeerPrefConnParams */
-#include <string.h>
-
-#define LOG_TAG "bt_bta_dm"
+#include "gki.h"
+#include "l2c_api.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
+#include "sdp_api.h"
+#include "utl.h"
 
 #if (GAP_INCLUDED == TRUE)
 #include "gap_api.h"
@@ -449,7 +451,7 @@ void bta_dm_disable (tBTA_DM_MSG *p_data)
     else
     {
         bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK*)&bta_dm_disable_timer_cback;
-        bta_dm_cb.disable_timer.param = 0;
+        bta_dm_cb.disable_timer.param = INT_TO_PTR(0);
         bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 5000);
     }
 
@@ -477,7 +479,7 @@ static void bta_dm_disable_timer_cback (TIMER_LIST_ENT *p_tle)
 
     APPL_TRACE_EVENT(" bta_dm_disable_timer_cback trial %d ", p_tle->param);
 
-    if(BTM_GetNumAclLinks() && p_tle->param == 0)
+    if(BTM_GetNumAclLinks() && PTR_TO_INT(p_tle->param) == 0)
     {
         for(i=0; i<bta_dm_cb.device_list.count; i++)
         {
@@ -493,7 +495,7 @@ static void bta_dm_disable_timer_cback (TIMER_LIST_ENT *p_tle)
         if (trigger_disc)
         {
             bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK*)&bta_dm_disable_timer_cback;
-            bta_dm_cb.disable_timer.param = 1;
+            bta_dm_cb.disable_timer.param = INT_TO_PTR(1);
             bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 1500);
         }
     }
@@ -2100,7 +2102,6 @@ static void bta_dm_find_services ( BD_ADDR bd_addr)
 {
 
     tSDP_UUID    uuid;
-    UINT16       num_attrs = 1;
     tBTA_DM_MSG *p_msg;
 
     memset (&uuid, 0, sizeof(tSDP_UUID));
@@ -2116,7 +2117,7 @@ static void bta_dm_find_services ( BD_ADDR bd_addr)
                 /* try to search all services by search based on L2CAP UUID */
                 if(bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK )
                 {
-                    LOG_INFO("%s services_to_search=%08x", __func__, bta_dm_search_cb.services_to_search);
+                    LOG_INFO(LOG_TAG, "%s services_to_search=%08x", __func__, bta_dm_search_cb.services_to_search);
                     if (bta_dm_search_cb.services_to_search & BTA_RES_SERVICE_MASK)
                     {
                         uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[0];
@@ -2170,7 +2171,7 @@ static void bta_dm_find_services ( BD_ADDR bd_addr)
                     memcpy(&uuid, &bta_dm_search_cb.uuid, sizeof(tSDP_UUID));
                 }
 
-                LOG_INFO("%s search UUID = %04x", __func__, uuid.uu.uuid16);
+                LOG_INFO(LOG_TAG, "%s search UUID = %04x", __func__, uuid.uu.uuid16);
                 SDP_InitDiscoveryDb (bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 1, &uuid, 0, NULL);
 
                 memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
@@ -4408,8 +4409,6 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
     tBTM_STATUS status = BTM_SUCCESS;
     tBTA_DM_SEC sec_event;
     char *p_name = NULL;
-    UINT8 i;
-    tBT_DEVICE_TYPE dev_type;
 
     if (!bta_dm_cb.p_sec_cback)
         return BTM_NOT_AUTHORIZED;
@@ -4850,7 +4849,7 @@ void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data)
     tBTA_STATUS status = BTA_FAILURE;
 
     if (BTM_BleWriteAdvData(p_data->ble_set_adv_data.data_mask,
-                        (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg) == BTM_SUCCESS)
+                        (tBTM_BLE_ADV_DATA *)&p_data->ble_set_adv_data.adv_cfg) == BTM_SUCCESS)
     {
         status = BTA_SUCCESS;
     }
@@ -4873,7 +4872,7 @@ void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data)
     tBTA_STATUS status = BTA_FAILURE;
 
     if(BTM_BleWriteScanRsp(p_data->ble_set_adv_data.data_mask,
-                        (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg) == BTM_SUCCESS)
+                        (tBTM_BLE_ADV_DATA *)&p_data->ble_set_adv_data.adv_cfg) == BTM_SUCCESS)
     {
         status = BTA_SUCCESS;
     }
@@ -4991,7 +4990,7 @@ void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data)
         btm_status = BTM_BleCfgAdvInstData(p_data->ble_multi_adv_data.inst_id,
                         p_data->ble_multi_adv_data.is_scan_rsp,
                         p_data->ble_multi_adv_data.data_mask,
-                        (tBTM_BLE_ADV_DATA*)p_data->ble_multi_adv_data.p_data);
+                        (tBTM_BLE_ADV_DATA*)&p_data->ble_multi_adv_data.data);
     }
 
     if(BTM_CMD_STARTED != btm_status)
@@ -5491,7 +5490,7 @@ static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id)
         APPL_TRACE_ERROR("%s out of room to accomodate more service ids ble_raw_size = %d ble_raw_used = %d", __FUNCTION__,bta_dm_search_cb.ble_raw_size, bta_dm_search_cb.ble_raw_used );
     }
 
-    LOG_INFO("%s service_id_uuid_len=%d ", __func__, service_id.uuid.len);
+    LOG_INFO(LOG_TAG, "%s service_id_uuid_len=%d ", __func__, service_id.uuid.len);
     if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE)
     {
 
index 061e7ff..7acac47 100644 (file)
@@ -1027,18 +1027,15 @@ void BTA_DmSetBleAdvParams (UINT16 adv_int_min, UINT16 adv_int_max,
 void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv_cfg,
                             tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback)
 {
-    tBTA_DM_API_SET_ADV_CONFIG  *p_msg;
-
-    if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *)
-        GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
-    {
-        p_msg->hdr.event = BTA_DM_API_BLE_SET_ADV_CONFIG_EVT;
-        p_msg->data_mask = data_mask;
-        p_msg->p_adv_data_cback = p_adv_data_cback;
-        p_msg->p_adv_cfg = p_adv_cfg;
-
-        bta_sys_sendmsg(p_msg);
-    }
+  tBTA_DM_API_SET_ADV_CONFIG *p_msg = GKI_getbuf(sizeof(*p_msg));
+  if (!p_msg) return;
+
+  memset(p_msg, 0, sizeof(*p_msg));
+  p_msg->hdr.event = BTA_DM_API_BLE_SET_ADV_CONFIG_EVT;
+  p_msg->data_mask = data_mask;
+  p_msg->p_adv_data_cback = p_adv_data_cback;
+  memcpy(&p_msg->adv_cfg, p_adv_cfg, sizeof(p_msg->adv_cfg));
+  bta_sys_sendmsg(p_msg);
 }
 
 /*******************************************************************************
@@ -1055,18 +1052,15 @@ void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv
 extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv_cfg,
                                  tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback)
 {
-    tBTA_DM_API_SET_ADV_CONFIG  *p_msg;
-
-    if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *)
-        GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
-    {
-        p_msg->hdr.event = BTA_DM_API_BLE_SET_SCAN_RSP_EVT;
-        p_msg->data_mask = data_mask;
-        p_msg->p_adv_data_cback = p_adv_data_cback;
-        p_msg->p_adv_cfg = p_adv_cfg;
-
-        bta_sys_sendmsg(p_msg);
-    }
+  tBTA_DM_API_SET_ADV_CONFIG *p_msg = GKI_getbuf(sizeof(*p_msg));
+  if (!p_msg) return;
+
+  memset(p_msg, 0, sizeof(*p_msg));
+  p_msg->hdr.event = BTA_DM_API_BLE_SET_SCAN_RSP_EVT;
+  p_msg->data_mask = data_mask;
+  p_msg->p_adv_data_cback = p_adv_data_cback;
+  memcpy(&p_msg->adv_cfg, p_adv_cfg, sizeof(p_msg->adv_cfg));
+  bta_sys_sendmsg(p_msg);
 }
 
 /*******************************************************************************
@@ -1609,22 +1603,16 @@ void BTA_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
                             tBTA_BLE_AD_MASK data_mask,
                             tBTA_BLE_ADV_DATA *p_data)
 {
-    tBTA_DM_API_BLE_MULTI_ADV_DATA    *p_msg;
-    UINT16      len =  sizeof(tBTA_DM_API_BLE_MULTI_ADV_DATA) ;
-
-    APPL_TRACE_API ("BTA_BleCfgAdvInstData");
-
-    if ((p_msg = (tBTA_DM_API_BLE_MULTI_ADV_DATA *) GKI_getbuf(len)) != NULL)
-    {
-          memset(p_msg, 0, len);
-          p_msg->hdr.event     = BTA_DM_API_BLE_MULTI_ADV_DATA_EVT;
-          p_msg->inst_id      = inst_id;
-          p_msg->is_scan_rsp  = is_scan_rsp;
-          p_msg->data_mask     = data_mask;
-          p_msg->p_data        = p_data;
-
-          bta_sys_sendmsg(p_msg);
-    }
+  tBTA_DM_API_BLE_MULTI_ADV_DATA *p_msg = GKI_getbuf(sizeof(*p_msg));
+  if (!p_msg) return;
+
+  memset(p_msg, 0, sizeof(*p_msg));
+  p_msg->hdr.event = BTA_DM_API_BLE_MULTI_ADV_DATA_EVT;
+  p_msg->inst_id = inst_id;
+  p_msg->is_scan_rsp = is_scan_rsp;
+  p_msg->data_mask = data_mask;
+  memcpy(&p_msg->data, p_data, sizeof(p_msg->data));
+  bta_sys_sendmsg(p_msg);
 }
 
 /*******************************************************************************
index 80b00f1..9fa7d61 100644 (file)
@@ -528,7 +528,7 @@ typedef struct
     UINT8                   inst_id;
     BOOLEAN                 is_scan_rsp;
     tBTA_BLE_AD_MASK        data_mask;
-    tBTA_BLE_ADV_DATA      *p_data;
+    tBTA_BLE_ADV_DATA       data;
 }tBTA_DM_API_BLE_MULTI_ADV_DATA;
 
 typedef struct
@@ -541,7 +541,7 @@ typedef struct
 {
     BT_HDR                  hdr;
     UINT32                  data_mask;
-    tBTA_BLE_ADV_DATA       *p_adv_cfg;
+    tBTA_BLE_ADV_DATA       adv_cfg;
     tBTA_SET_ADV_DATA_CMPL_CBACK    *p_adv_data_cback;
 }tBTA_DM_API_SET_ADV_CONFIG;
 
index f90b441..d1742dc 100644 (file)
@@ -343,7 +343,6 @@ static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id,
 {
 
     UINT8 i,j;
-    UINT16 policy_setting;
     UINT8 *p = NULL;
     tBTA_DM_PEER_DEVICE *p_dev;
 
old mode 100755 (executable)
new mode 100644 (file)
index 70e9d23..c6975c1
  *  machine.
  *
  ******************************************************************************/
-#define LOG_TAG "bt_bta_gattc"
 
-#include "bt_target.h"
+#define LOG_TAG "bt_bta_gattc"
 
-#include "utl.h"
-#include "gki.h"
-#include "bta_sys.h"
+#include <string.h>
 
+#include "bt_target.h"
 #include "bta_gattc_int.h"
+#include "bta_sys.h"
+#include "btif/include/btif_debug_conn.h"
+#include "gki.h"
 #include "l2c_api.h"
+#include "osi/include/log.h"
+#include "utl.h"
 
 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
 #include "bta_hh_int.h"
 #endif
 
-#include "btif/include/btif_debug_conn.h"
-
-#include <string.h>
-
-#include "osi/include/log.h"
-
 #if BTA_GATT_INCLUDED && BLE_INCLUDED == TRUE
 
 /*****************************************************************************
@@ -122,7 +119,6 @@ static void bta_gattc_enable(tBTA_GATTC_CB *p_cb)
     }
 }
 
-
 /*******************************************************************************
 **
 ** Function         bta_gattc_disable
@@ -187,7 +183,6 @@ void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
     tBTA_GATTC_INT_START_IF  *p_buf;
     tBTA_GATT_STATUS         status = BTA_GATT_NO_RESOURCES;
 
-
     APPL_TRACE_DEBUG("bta_gattc_register state %d",p_cb->state);
     memset(&cb_data, 0, sizeof(cb_data));
     cb_data.reg_oper.status = BTA_GATT_NO_RESOURCES;
@@ -774,7 +769,6 @@ void bta_gattc_close_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
         cb_data.close.status    = BTA_GATT_ERROR;
         cb_data.close.reason    = BTA_GATT_CONN_NONE;
 
-
         (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data);
     }
 }
@@ -1465,7 +1459,6 @@ void bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
 
     utl_freebuf((void **)&p_clcb->p_q_cmd);
 
-
     if (p_data->p_cmpl  &&  p_data->status == BTA_GATT_OK)
         p_clcb->p_srcb->mtu  = p_data->p_cmpl->mtu;
 
@@ -2339,7 +2332,7 @@ void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
                 /* if listen to all */
                 else
                 {
-                    LOG_DEBUG("Listen For All now");
+                    LOG_DEBUG(LOG_TAG, "Listen For All now");
                     /* go through all connected device and send
                     callback for all connected slave connection */
                     bta_gattc_process_listen_all(p_msg->api_listen.client_if);
index cd68cbc..6a4b9bf 100644 (file)
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_bta_gattc"
+
 #include "bt_target.h"
 
 #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
 
 #include <string.h>
-#include "utl.h"
-#include "gki.h"
-#include "bta_sys.h"
-#include "sdp_api.h"
-#include "sdpdefs.h"
+
 #include "bta_gattc_int.h"
+#include "bta_sys.h"
 #include "btm_api.h"
 #include "btm_ble_api.h"
-
-#define LOG_TAG "bt_bta_gattc"
+#include "gki.h"
 #include "osi/include/log.h"
+#include "sdp_api.h"
+#include "sdpdefs.h"
+#include "utl.h"
 
 static void bta_gattc_char_dscpt_disc_cmpl(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb);
 static tBTA_GATT_STATUS bta_gattc_sdp_service_disc(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb);
@@ -601,7 +602,7 @@ static void bta_gattc_explore_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
         }
     }
     /* no service found at all, the end of server discovery*/
-    LOG_WARN("%s no more services found", __func__);
+    LOG_WARN(LOG_TAG, "%s no more services found", __func__);
 
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
     bta_gattc_display_cache_server(p_srvc_cb->p_srvc_cache);
index c8648b9..3c11ffb 100644 (file)
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_bta_gattc"
+
 #include "bt_target.h"
 
 #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
 
 #include <string.h>
 
+#include "bta_gattc_int.h"
+#include "bta_sys.h"
 #include "btcore/include/bdaddr.h"
 #include "btif/include/btif_util.h"
 #include "gki.h"
-#include "utl.h"
-#include "bta_sys.h"
-#include "bta_gattc_int.h"
 #include "l2c_api.h"
+#include "utl.h"
 
-#define LOG_TAG "bt_bta_gattc"
 /*****************************************************************************
 **  Constants
 *****************************************************************************/
 
-
 static const UINT8  base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
     0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 
@@ -861,7 +861,6 @@ tBTA_GATTC_CONN * bta_gattc_conn_find(BD_ADDR remote_bda)
     return NULL;
 }
 
-
 /*******************************************************************************
 **
 ** Function         bta_gattc_conn_find_alloc
index 27c00cb..e582963 100644 (file)
 
 #include <string.h>
 #include <stdlib.h>
+
+// TODO(armansito): cutils/properties.h is only being used to pull-in runtime
+// settings on Android. Remove this conditional include once we have a generic
+// way to obtain system properties.
+#if !defined(OS_GENERIC)
 #include <cutils/properties.h>
+#endif  // !defined(OS_GENERIC)
+
 #include "bt_utils.h"
 #include "bta_api.h"
 #include "bta_sys.h"
@@ -372,7 +379,12 @@ void bta_hf_client_collision_cback (tBTA_SYS_CONN_STATUS status, UINT8 id,
 *******************************************************************************/
 static void bta_hf_client_api_enable(tBTA_HF_CLIENT_DATA *p_data)
 {
+    // TODO(armansito): For non-Android systems we need a common method of
+    // loading system properties. Remove the conditionally compiled code once we
+    // have that in place.
+#if !defined(OS_GENERIC)
     char value[PROPERTY_VALUE_MAX];
+#endif  // !defined(OS_GENERIC)
 
     /* initialize control block */
     memset(&bta_hf_client_cb, 0, sizeof(tBTA_HF_CLIENT_CB));
@@ -380,12 +392,17 @@ static void bta_hf_client_api_enable(tBTA_HF_CLIENT_DATA *p_data)
     /* store callback function */
     bta_hf_client_cb.p_cback = p_data->api_enable.p_cback;
 
+    // TODO(armansito): For non-Android systems we need a common method of
+    // loading system properties. Remove the conditionally compiled code once we
+    // have that in place.
+#if !defined(OS_GENERIC)
     /* check if mSBC support enabled */
     property_get("ro.bluetooth.hfp.ver", value, "0");
     if (strcmp(value,"1.6") == 0)
     {
        bta_hf_client_cb.msbc_enabled = TRUE;
     }
+#endif  // !defined(OS_GENERIC)
 
     bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
 
index 1fdbc29..a6a8ecf 100644 (file)
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_bta_hh"
+
+#include "bta_hh_api.h"
+
 #include "bt_target.h"
 
 #if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stdio.h>
 
-#include "bta_hh_api.h"
 #include "bta_hh_int.h"
 #include "l2c_api.h"
-#include "utl.h"
-
-#define LOG_TAG "bt_bta_hh"
 #include "osi/include/log.h"
+#include "utl.h"
 
 /*****************************************************************************
 **  Constants
@@ -68,7 +69,7 @@ void BTA_HhEnable(tBTA_SEC sec_mask, tBTA_HH_CBACK *p_cback)
     /* register with BTA system manager */
     bta_sys_register(BTA_ID_HH, &bta_hh_reg);
 
-    LOG_INFO("%s sec_mask:0x%x p_cback:%p", __func__, sec_mask, p_cback);
+    LOG_INFO(LOG_TAG, "%s sec_mask:0x%x p_cback:%p", __func__, sec_mask, p_cback);
     p_buf = (tBTA_HH_API_ENABLE *)GKI_getbuf((UINT16)sizeof(tBTA_HH_API_ENABLE));
 
     if (p_buf != NULL)
index 48b0610..ecc9f97 100644 (file)
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_bta_hh"
+
 #include "bta_api.h"
 #include "bta_hh_int.h"
 
 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
 
-#include "bta_api.h"
 #include <string.h>
+
+#include "bta_api.h"
+#include "bta_gatt_api.h"
+#include "bta_hh_co.h"
 #include "btm_api.h"
 #include "btm_ble_api.h"
-#include "bta_hh_co.h"
-#include "bta_gatt_api.h"
-#include "srvc_api.h"
 #include "btm_int.h"
-#include "utl.h"
-
-#define LOG_TAG "bt_bta_hh"
 #include "osi/include/log.h"
+#include "srvc_api.h"
+#include "utl.h"
 
 #ifndef BTA_HH_LE_RECONN
 #define BTA_HH_LE_RECONN    TRUE
@@ -629,7 +630,7 @@ tBTA_HH_STATUS bta_hh_le_read_char_dscrpt(tBTA_HH_DEV_CB *p_cb, UINT16 srvc_uuid
     else
     {
 #if BTA_HH_DEBUG == TRUE
-      LOG_WARN("%s No descriptor exists: %s(0x%04x)", __func__,
+      LOG_WARN(LOG_TAG, "%s No descriptor exists: %s(0x%04x)", __func__,
           bta_hh_uuid_to_str(char_descp_uuid), char_descp_uuid);
 #endif
     }
@@ -1142,7 +1143,7 @@ void bta_hh_le_expl_rpt(tBTA_HH_DEV_CB *p_dev_cb,
     }
     while (1);
 
-    LOG_INFO("%s all BLE reports searched", __func__);
+    LOG_INFO(LOG_TAG, "%s all BLE reports searched", __func__);
     bta_hh_le_read_rpt_ref_descr(p_dev_cb,
                                  &p_dev_cb->hid_srvc[p_dev_cb->cur_srvc_index].report[0]);
 
index f5b3fd1..f6cb909 100644 (file)
@@ -50,7 +50,7 @@ BOOLEAN bta_hl_fill_sup_feature_list( const tSDP_DISC_ATTR  *p_attr,
         {
             return(FALSE);
         }
-        SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
+
         item_cnt=0;
 
         for (p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr && (item_cnt < 4) ; p_sattr = p_sattr->p_next_attr)
index 0a0f326..3fa142b 100644 (file)
@@ -1170,8 +1170,6 @@ BOOLEAN bta_hl_find_mcl_idx(UINT8 app_idx, BD_ADDR p_bd_addr, UINT8 *p_mcl_idx)
 
     for (i=0; i < BTA_HL_NUM_MCLS ; i ++)
     {
-        BTA_HL_GET_MCL_CB_PTR(app_idx, i);
-
         if (bta_hl_cb.acb[app_idx].mcb[i].in_use &&
             (!memcmp (bta_hl_cb.acb[app_idx].mcb[i].bd_addr, p_bd_addr, BD_ADDR_LEN)))
         {
index a470d1a..6977e5c 100644 (file)
@@ -342,67 +342,28 @@ typedef struct
 #define BTA_DM_BLE_AD_BIT_RANDOM_ADDR     BTM_BLE_AD_BIT_RANDOM_ADDR
 #define BTA_DM_BLE_AD_BIT_SERVICE_128     BTM_BLE_AD_BIT_SERVICE_128      /*128-bit Service UUIDs*/
 
-typedef  tBTM_BLE_AD_MASK  tBTA_BLE_AD_MASK;
-
-/* slave preferred connection interval range */
-typedef struct
-{
-    UINT16  low;
-    UINT16  hi;
-
-}tBTA_BLE_INT_RANGE;
-
-/* Service tag supported in the device */
-typedef struct
-{
-    UINT8       num_service;
-    BOOLEAN     list_cmpl;
-    UINT16      *p_uuid;
-}tBTA_BLE_SERVICE;
-
-
-typedef struct
-{
-    UINT8       len;
-    UINT8      *p_val;
-}tBTA_BLE_MANU;
-
-typedef struct
-{
-    UINT8       adv_type;
-    UINT8       len;
-    UINT8       *p_val;     /* number of len byte */
-}tBTA_BLE_PROP_ELEM;
-
-/* vendor proprietary adv type */
-typedef struct
-{
-    UINT8                   num_elem;
-    tBTA_BLE_PROP_ELEM      *p_elem;
-}tBTA_BLE_PROPRIETARY;
-
-typedef struct
-{
-    tBT_UUID    service_uuid;
-    UINT8       len;
-    UINT8      *p_val;
-}tBTA_BLE_SERVICE_DATA;
-
+typedef tBTM_BLE_AD_MASK tBTA_BLE_AD_MASK;
+typedef tBTM_BLE_INT_RANGE tBTA_BLE_INT_RANGE;
+typedef tBTM_BLE_SERVICE tBTA_BLE_SERVICE;
+typedef tBTM_BLE_PROP_ELEM tBTA_BLE_PROP_ELEM;
+typedef tBTM_BLE_PROPRIETARY tBTA_BLE_PROPRIETARY;
+typedef tBTM_BLE_MANU tBTA_BLE_MANU;
+typedef tBTM_BLE_SERVICE_DATA tBTA_BLE_SERVICE_DATA;
 typedef tBTM_BLE_128SERVICE tBTA_BLE_128SERVICE;
 typedef tBTM_BLE_32SERVICE  tBTA_BLE_32SERVICE;
 
 typedef struct
 {
     tBTA_BLE_INT_RANGE      int_range;          /* slave prefered conn interval range */
-    tBTA_BLE_MANU           *p_manu;            /* manufacturer data */
-    tBTA_BLE_SERVICE        *p_services;        /* 16 bits services */
-    tBTA_BLE_128SERVICE     *p_services_128b;   /* 128 bits service */
-    tBTA_BLE_32SERVICE      *p_service_32b;     /* 32 bits Service UUID */
-    tBTA_BLE_SERVICE        *p_sol_services;    /* 16 bits services Solicitation UUIDs */
-    tBTA_BLE_32SERVICE      *p_sol_service_32b; /* List of 32 bit Service Solicitation UUIDs */
-    tBTA_BLE_128SERVICE     *p_sol_service_128b;/* List of 128 bit Service Solicitation UUIDs */
-    tBTA_BLE_PROPRIETARY    *p_proprietary;     /* proprietary data */
-    tBTA_BLE_SERVICE_DATA   *p_service_data;    /* service data */
+    tBTA_BLE_MANU           manu;            /* manufacturer data */
+    tBTA_BLE_SERVICE        services;        /* 16 bits services */
+    tBTA_BLE_128SERVICE     services_128b;   /* 128 bits service */
+    tBTA_BLE_32SERVICE      service_32b;     /* 32 bits Service UUID */
+    tBTA_BLE_SERVICE        sol_services;    /* 16 bits services Solicitation UUIDs */
+    tBTA_BLE_32SERVICE      sol_service_32b; /* List of 32 bit Service Solicitation UUIDs */
+    tBTA_BLE_128SERVICE     sol_service_128b;/* List of 128 bit Service Solicitation UUIDs */
+    tBTA_BLE_PROPRIETARY    proprietary;     /* proprietary data */
+    tBTA_BLE_SERVICE_DATA   service_data;    /* service data */
     UINT16                  appearance;         /* appearance data */
     UINT8                   flag;
     UINT8                   tx_power;
index 2ad86a1..5e44992 100644 (file)
@@ -25,6 +25,7 @@
 #include <arpa/inet.h>
 #include <pthread.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "osi/include/allocator.h"
 #include "bt_types.h"
 #include "sdp_api.h"
 #include "l2c_api.h"
 #include "port_api.h"
-#include <string.h>
 #include "rfcdefs.h"
 #include "avct_api.h"
 #include "avdt_api.h"
 #include "gap_api.h"
 #include "l2c_api.h"
 
+#include "osi/include/osi.h"
+
 
 /* one of these exists for each client */
 struct fc_client {
@@ -75,22 +77,6 @@ struct fc_channel {
 static struct fc_client *fc_clients;
 static struct fc_channel *fc_channels;
 static uint32_t fc_next_id;
-static pthread_once_t fc_init_once = PTHREAD_ONCE_INIT;
-
-
-static void fc_init_work(void)
-{
-    fc_clients = NULL;
-    fc_channels = NULL;
-    fc_next_id = 0;
-
-    //more init here if needed...
-}
-
-static void fc_init(void)
-{
-    pthread_once(&fc_init_once,  fc_init_work);
-}
 
 
 static void fcchan_conn_chng_cbk(UINT16 chan, BD_ADDR bd_addr, BOOLEAN connected,
@@ -546,8 +532,6 @@ static tBTA_JV_PM_CB *bta_jv_alloc_set_pm_profile_cb(UINT32 jv_handle, tBTA_JV_P
             /* rfc handle bd addr retrieval requires core stack handle */
             if (bRfcHandle)
             {
-                UINT32 hi = ((jv_handle & BTA_JV_RFC_HDL_MASK) & ~BTA_JV_RFCOMM_MASK) - 1;
-                UINT32 si = BTA_JV_RFC_HDL_TO_SIDX(jv_handle);
                 for (j = 0; j < BTA_JV_MAX_RFC_CONN; j++)
                 {
                     if (jv_handle == bta_jv_cb.port_cb[j].handle)
@@ -872,7 +856,6 @@ static inline tBT_UUID shorten_sdp_uuid(const tBT_UUID* u)
 static void bta_jv_start_discovery_cback(UINT16 result, void * user_data)
 {
     tBTA_JV_STATUS status;
-    UINT8          old_sdp_act = bta_jv_cb.sdp_active;
 
     APPL_TRACE_DEBUG("bta_jv_start_discovery_cback res: 0x%x", result);
 
@@ -1232,7 +1215,6 @@ void bta_jv_l2cap_start_server(tBTA_JV_MSG *p_data)
     tL2CAP_CFG_INFO cfg;
     tBTA_JV_L2CAP_START evt_data;
     tBTA_JV_API_L2CAP_SERVER *ls = &(p_data->l2cap_server);
-    INT32   use_etm = FALSE;
     UINT8 chan_mode_mask = GAP_FCR_CHAN_OPT_BASIC;
     tL2CAP_ERTM_INFO    *ertm_info = NULL;
 
@@ -1673,7 +1655,7 @@ static int find_rfc_pcb(void* user_data, tBTA_JV_RFC_CB **cb, tBTA_JV_PCB **pcb)
             return 1;
         }
     }
-    APPL_TRACE_DEBUG("find_rfc_pcb: cannot find rfc_cb from user data:%d", (UINT32)user_data);
+    APPL_TRACE_DEBUG("find_rfc_pcb: cannot find rfc_cb from user data: %u", PTR_TO_UINT(user_data));
     return 0;
 }
 
@@ -1708,38 +1690,6 @@ void bta_jv_rfcomm_close(tBTA_JV_MSG *p_data)
 
 /*******************************************************************************
 **
-** Function     bta_jv_get_num_rfc_listen
-**
-** Description  when a RFCOMM connection goes down, make sure that there's only
-**              one port stays listening on this scn.
-**
-** Returns
-**
-*******************************************************************************/
-static UINT8 bta_jv_get_num_rfc_listen(tBTA_JV_RFC_CB *p_cb)
-{
-    UINT8   listen=1;
-
-    if (p_cb->max_sess > 1)
-    {
-        listen = 0;
-        for (UINT8 i=0; i<p_cb->max_sess; i++)
-        {
-            if (p_cb->rfc_hdl[i] != 0)
-            {
-                const tBTA_JV_PCB *p_pcb = &bta_jv_cb.port_cb[p_cb->rfc_hdl[i] - 1];
-                if (BTA_JV_ST_SR_LISTEN == p_pcb->state)
-                {
-                    listen++;
-                }
-            }
-        }
-    }
-    return listen;
-}
-
-/*******************************************************************************
-**
 ** Function     bta_jv_port_mgmt_sr_cback
 **
 ** Description  callback for port mamangement function of rfcomm
@@ -2558,7 +2508,6 @@ static void fcchan_conn_chng_cbk(UINT16 chan, BD_ADDR bd_addr, BOOLEAN connected
 static void fcchan_data_cbk(UINT16 chan, BD_ADDR bd_addr, BT_HDR *p_buf)
 {
     tBTA_JV evt_data;
-    tBTA_JV evt_open;
     struct fc_channel *tc;
     struct fc_client *t = NULL;
     tBTA_JV_L2CAP_CBACK *sock_cback = NULL;
@@ -2689,7 +2638,6 @@ void bta_jv_l2cap_start_server_le(tBTA_JV_MSG *p_data)
     tBTA_JV_API_L2CAP_SERVER *ss = &(p_data->l2cap_server);
     tBTA_JV_L2CAP_START evt_data;
     struct fc_client *t;
-    uint16_t handle;
 
     evt_data.handle = GAP_INVALID_HANDLE;
     evt_data.status = BTA_JV_FAILURE;
index f3e6005..7755c04 100644 (file)
@@ -94,11 +94,9 @@ static inline tBT_UUID shorten_sdp_uuid(const tBT_UUID* u)
 
 static void bta_create_mns_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
 {
-    tSDP_DISCOVERY_DB *db = p_bta_sdp_cfg->p_sdp_db;
     tSDP_DISC_ATTR *p_attr;
     tSDP_PROTOCOL_ELEM pe;
     UINT16 pversion = 0;
-    UINT8 offset = 0;
     record->mns.hdr.type = SDP_TYPE_MAP_MNS;
     record->mns.hdr.service_name_length = 0;
     record->mns.hdr.service_name = NULL;
@@ -136,7 +134,6 @@ static void bta_create_mns_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_RE
 
 static void bta_create_mas_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
 {
-    tSDP_DISCOVERY_DB *db = p_bta_sdp_cfg->p_sdp_db;
     tSDP_DISC_ATTR *p_attr;
     tSDP_PROTOCOL_ELEM pe;
     UINT16 pversion = -1;
@@ -190,7 +187,6 @@ static void bta_create_mas_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_RE
 
 static void bta_create_pse_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
 {
-    tSDP_DISCOVERY_DB *db = p_bta_sdp_cfg->p_sdp_db;
     tSDP_DISC_ATTR *p_attr;
     UINT16 pversion;
     tSDP_PROTOCOL_ELEM pe;
@@ -237,7 +233,6 @@ static void bta_create_pse_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_RE
 
 static void bta_create_ops_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
 {
-    tSDP_DISCOVERY_DB *db = p_bta_sdp_cfg->p_sdp_db;
     tSDP_DISC_ATTR *p_attr, *p_sattr;
     tSDP_PROTOCOL_ELEM pe;
     UINT16 pversion = -1;
@@ -350,9 +345,7 @@ static void bta_create_sap_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_RE
 
 static void bta_create_raw_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
 {
-    tSDP_DISCOVERY_DB *db = p_bta_sdp_cfg->p_sdp_db;
     tSDP_DISC_ATTR *p_attr;
-    UINT16 pversion;
     tSDP_PROTOCOL_ELEM pe;
 
     record->hdr.type = SDP_TYPE_RAW;
@@ -393,7 +386,6 @@ static void bta_sdp_search_cback(UINT16 result, void * user_data)
     tSDP_DISC_REC *p_rec = NULL;
     tBTA_SDP_SEARCH_COMP evt_data = {0}; // We need to zero-initialize
     tBTA_SDP_STATUS status = BTA_SDP_FAILURE;
-    UINT16 uuid16 = 0;
     int count = 0;
     tBT_UUID su;
     APPL_TRACE_DEBUG("%s() -  res: 0x%x", __func__, result);
index a5b53b9..3625a88 100644 (file)
  *  This is the main implementation file for the BTA system manager.
  *
  ******************************************************************************/
+
 #define LOG_TAG "bt_bta_sys_main"
 
 #include <assert.h>
+#include <pthread.h>
 #include <string.h>
 
-#include "osi/include/alarm.h"
-#include "btm_api.h"
 #include "bta_api.h"
 #include "bta_sys.h"
 #include "bta_sys_int.h"
-
-#include "osi/include/fixed_queue.h"
+#include "btm_api.h"
 #include "gki.h"
-#include "osi/include/hash_map.h"
-#include "osi/include/osi.h"
+#include "osi/include/alarm.h"
+#include "osi/include/fixed_queue.h"
 #include "osi/include/hash_functions.h"
+#include "osi/include/hash_map.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 #include "osi/include/thread.h"
+#include "utl.h"
+
 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
 #include "bta_ar_api.h"
 #endif
-#include "utl.h"
 
 /* system manager control block definition */
 #if BTA_DYNAMIC_MEMORY == FALSE
@@ -634,7 +636,7 @@ void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms) {
 
   alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle);
   if (alarm == NULL) {
-    LOG_ERROR("%s unable to create alarm.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create alarm.", __func__);
     return;
   }
 
@@ -676,7 +678,7 @@ void bta_sys_stop_timer(TIMER_LIST_ENT *p_tle) {
 
   alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle);
   if (alarm == NULL) {
-    LOG_DEBUG("%s expected alarm was not in bta alarm hash map.", __func__);
+    LOG_DEBUG(LOG_TAG, "%s expected alarm was not in bta alarm hash map.", __func__);
     return;
   }
   alarm_cancel(alarm);
index 50006d4..aa07cbe 100644 (file)
 
 LOCAL_PATH := $(call my-dir)
 
-include $(CLEAR_VARS)
-
-# osi/include/atomic.h depends on gcc atomic functions
-LOCAL_CLANG := false
-
-LOCAL_C_INCLUDES := \
-    $(LOCAL_PATH)/include \
-    $(LOCAL_PATH)/../osi/include \
-    $(LOCAL_PATH)/..
-
-LOCAL_SRC_FILES := \
+# Common variables
+# ========================================================
+btcoreCommonSrc := \
     src/bdaddr.c \
     src/counter.c \
     src/device_class.c \
+    src/hal_util.c \
     src/module.c \
     src/osi_module.c \
     src/property.c \
     src/uuid.c
 
+btcoreCommonTestSrc := \
+    ./test/bdaddr_test.cpp \
+    ./test/counter_test.cpp \
+    ./test/device_class_test.cpp \
+    ./test/property_test.cpp \
+    ./test/uuid_test.cpp \
+    ../osi/test/AllocationTestHarness.cpp
+
+btcoreCommonIncludes := \
+    $(LOCAL_PATH)/include \
+    $(LOCAL_PATH)/../osi/include \
+    $(LOCAL_PATH)/..
+
+# libbtcore static library for target
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_CLANG_CFLAGS += -Wno-error=typedef-redefinition
+LOCAL_C_INCLUDES := $(btcoreCommonIncludes)
+LOCAL_SRC_FILES := $(btcoreCommonSrc)
 LOCAL_CFLAGS := -std=c99 $(bdroid_CFLAGS)
 LOCAL_MODULE := libbtcore
 LOCAL_MODULE_TAGS := optional
 LOCAL_SHARED_LIBRARIES := libc liblog
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
-
 include $(BUILD_STATIC_LIBRARY)
 
-#####################################################
-
+# libbtcore static library for host
+# ========================================================
+ifeq ($(HOST_OS),linux)
 include $(CLEAR_VARS)
+LOCAL_CLANG_CFLAGS += -Wno-error=typedef-redefinition
+LOCAL_C_INCLUDES := $(btcoreCommonIncludes)
+LOCAL_SRC_FILES := $(btcoreCommonSrc)
+# TODO(armansito): Setting _GNU_SOURCE isn't very platform-independent but
+# should be compatible for a Linux host OS. We should figure out what to do for
+# a non-Linux host OS.
+LOCAL_CFLAGS := -std=c99 $(bdroid_CFLAGS) -D_GNU_SOURCE
+LOCAL_MODULE := libbtcore-host
+LOCAL_MODULE_TAGS := optional
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+include $(BUILD_HOST_STATIC_LIBRARY)
+endif
 
-# osi/include/atomic.h depends on gcc atomic functions
-LOCAL_CLANG := false
-
-LOCAL_C_INCLUDES := \
-    $(LOCAL_PATH)/include \
-    $(LOCAL_PATH)/..
-
-LOCAL_SRC_FILES := \
-    ./test/bdaddr_test.cpp \
-    ./test/counter_test.cpp \
-    ./test/device_class_test.cpp \
-    ./test/property_test.cpp \
-    ./test/uuid_test.cpp \
-    ../osi/test/AllocationTestHarness.cpp
+# Note: It's good to get the tests compiled both for the host and the target so
+# we get to test with both Bionic libc and glibc
 
+# libbtcore unit tests for target
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_CLANG_CFLAGS += -Wno-error=typedef-redefinition
+LOCAL_C_INCLUDES := $(btcoreCommonIncludes)
+LOCAL_SRC_FILES := $(btcoreCommonTestSrc)
 LOCAL_CFLAGS := -Wall -Werror -Werror=unused-variable
 LOCAL_MODULE := net_test_btcore
-
 LOCAL_MODULE_TAGS := tests
 LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_STATIC_LIBRARIES := libbtcore libosi
-
 include $(BUILD_NATIVE_TEST)
+
+# libbtcore unit tests for host
+# ========================================================
+ifeq ($(HOST_OS),linux)
+include $(CLEAR_VARS)
+LOCAL_CLANG_CFLAGS += -Wno-error=typedef-redefinition
+LOCAL_C_INCLUDES := $(btcoreCommonIncludes)
+LOCAL_SRC_FILES := $(btcoreCommonTestSrc)
+LOCAL_CFLAGS := -Wall -Werror -Werror=unused-variable
+LOCAL_MODULE := net_test_btcore
+LOCAL_MODULE_TAGS := tests
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_STATIC_LIBRARIES := libbtcore-host libosi-host
+include $(BUILD_HOST_NATIVE_TEST)
+endif
diff --git a/btcore/BUILD.gn b/btcore/BUILD.gn
new file mode 100644 (file)
index 0000000..624733b
--- /dev/null
@@ -0,0 +1,58 @@
+#
+#  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.
+#
+
+static_library("btcore") {
+  sources = [
+    "src/bdaddr.c",
+    "src/counter.c",
+    "src/device_class.c",
+    "src/hal_util.c",
+    "src/module.c",
+    "src/property.c",
+    "src/uuid.c",
+  ]
+
+  include_dirs = [
+    "include",
+    "//osi/include",
+    "//",
+  ]
+}
+
+executable("net_test_btcore") {
+  testonly = true
+  sources = [
+    "test/bdaddr_test.cpp",
+    "test/counter_test.cpp",
+    "test/device_class_test.cpp",
+    "test/property_test.cpp",
+    "test/uuid_test.cpp",
+    "//osi/test/AllocationTestHarness.cpp",
+  ]
+
+  include_dirs = [
+    "include",
+    "//",
+  ]
+
+  deps = [
+    "//btcore",
+    "//osi",
+    "//third_party/gtest:gtest_main",
+  ]
+
+  libs = [ "-lpthread", "-lrt", "-ldl" ]
+}
diff --git a/btcore/include/hal_util.h b/btcore/include/hal_util.h
new file mode 100644 (file)
index 0000000..8456a71
--- /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
+
+struct hw_module_t;
+
+// Loads the Bluetooth library. If OS_GENERIC is defined, this function looks
+// explicitly for libbluetooth.default.so and loads it. On Android, this calls
+// the hw_get_module routine with the Bluetooth stack module id.
+int hal_util_load_bt_library(const struct hw_module_t **module);
index 08aa518..e1f3da4 100644 (file)
 #include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <stdatomic.h>
 #include <string.h>
 #include <sys/eventfd.h>
 
-#include "osi/include/allocator.h"
-#include "osi/include/atomic.h"
 #include "btcore/include/counter.h"
-#include "osi/include/hash_map.h"
-#include "osi/include/list.h"
 #include "btcore/include/module.h"
-#include "osi/include/osi.h"
+#include "osi/include/allocator.h"
 #include "osi/include/hash_functions.h"
+#include "osi/include/hash_map.h"
+#include "osi/include/list.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 #include "osi/include/socket.h"
 #include "osi/include/thread.h"
 
 typedef int (*handler_t)(socket_t * socket);
 
 typedef struct counter_t {
-  atomic_s64_t val;
+  _Atomic(int64_t) val;
 } counter_t;
 
 typedef struct hash_element_t {
@@ -123,12 +125,12 @@ static future_t *counter_init(void) {
   hash_map_counter_ = hash_map_new(COUNTER_NUM_BUCKETS, hash_function_string,
       NULL, hash_element_free_, NULL);
   if (hash_map_counter_ == NULL) {
-    LOG_ERROR("%s unable to allocate resources", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate resources", __func__);
     return future_new_immediate(FUTURE_FAIL);
   }
 
   if (!counter_socket_open()) {
-    LOG_ERROR("%s unable to open counter port", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to open counter port", __func__);
     return future_new_immediate(FUTURE_FAIL);
   }
   return future_new_immediate(FUTURE_SUCCESS);
@@ -142,7 +144,7 @@ static future_t *counter_clean_up(void) {
   return future_new_immediate(FUTURE_SUCCESS);
 }
 
-module_t counter_module = {
+EXPORT_SYMBOL module_t counter_module = {
   .name = COUNTER_MODULE,
   .init = counter_init,
   .start_up = NULL,
@@ -155,17 +157,14 @@ void counter_set(const char *name, counter_data_t val) {
   assert(name != NULL);
   counter_t *counter = name_to_counter_(name);
   if (counter)
-    atomic_store_s64(&counter->val, val);
+    atomic_store(&counter->val, val);
 }
 
 void counter_add(const char *name, counter_data_t val) {
   assert(name != NULL);
   counter_t *counter = name_to_counter_(name);
   if (counter) {
-    if (val == 1)
-      atomic_inc_prefix_s64(&counter->val);
-    else
-      atomic_add_s64(&counter->val, val);
+    atomic_fetch_add(&counter->val, val);
   }
 }
 
@@ -185,7 +184,7 @@ static counter_t *counter_new_(counter_data_t initial_val) {
   if (!counter) {
     return NULL;
   }
-  atomic_store_s64(&counter->val, initial_val);
+  atomic_store(&counter->val, initial_val);
   return counter;
 }
 
@@ -221,13 +220,13 @@ static counter_t *name_to_counter_(const char *name) {
 
   counter = counter_new_(0);
   if (!counter) {
-    LOG_ERROR("%s unable to create new counter name:%s", __func__, name);
+    LOG_ERROR(LOG_TAG, "%s unable to create new counter name:%s", __func__, name);
     goto exit;
   }
 
   hash_element_t *element = hash_element_new_();
   if (!element) {
-    LOG_ERROR("%s unable to create counter element name:%s", __func__, name);
+    LOG_ERROR(LOG_TAG, "%s unable to create counter element name:%s", __func__, name);
     counter_free_(counter);
     counter = NULL;
     goto exit;
@@ -236,7 +235,7 @@ static counter_t *name_to_counter_(const char *name) {
   element->key = name;
   element->val = counter;
   if (!hash_map_set(hash_map_counter_, name, counter)) {
-    LOG_ERROR("%s unable to set new counter into hash map name:%s", __func__, name);
+    LOG_ERROR(LOG_TAG, "%s unable to set new counter into hash map name:%s", __func__, name);
     hash_element_free_(element);
     counter_free_(counter);
     counter = NULL;
@@ -263,28 +262,28 @@ static bool counter_socket_open(void) {
 
   clients_ = list_new(client_free);
   if (!clients_) {
-    LOG_ERROR("%s unable to create counter clients list", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create counter clients list", __func__);
     goto error;
   }
 
   thread_ = thread_new("counter_socket");
   if (!thread_) {
-    LOG_ERROR("%s unable to create counter thread", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create counter thread", __func__);
     goto error;
   }
 
   listen_socket_ = socket_new();
   if (!listen_socket_) {
-    LOG_ERROR("%s unable to create listen socket", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create listen socket", __func__);
     goto error;
   }
 
   if (!socket_listen(listen_socket_, LISTEN_PORT)) {
-    LOG_ERROR("%s unable to setup listen socket", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to setup listen socket", __func__);
     goto error;
   }
 
-  LOG_INFO("%s opened counter server socket", __func__);
+  LOG_INFO(LOG_TAG, "%s opened counter server socket", __func__);
   socket_register(listen_socket_, thread_get_reactor(thread_), NULL, accept_ready, NULL);
   return true;
 
@@ -302,7 +301,7 @@ static void counter_socket_close(void) {
   thread_ = NULL;
   clients_ = NULL;
 
-  LOG_INFO("%s closed counter server socket", __func__);
+  LOG_INFO(LOG_TAG, "%s closed counter server socket", __func__);
 }
 
 static bool monitor_counter_iter_cb(const char *name, counter_data_t val, void *context) {
@@ -324,14 +323,14 @@ static void accept_ready(socket_t *socket, UNUSED_ATTR void *context) {
   assert(socket != NULL);
   assert(socket == listen_socket_);
 
-  LOG_INFO("%s accepted OSI monitor socket", __func__);
+  LOG_INFO(LOG_TAG, "%s accepted OSI monitor socket", __func__);
   socket = socket_accept(socket);
   if (!socket)
     return;
 
   client_t *client = (client_t *)osi_calloc(sizeof(client_t));
   if (!client) {
-    LOG_ERROR("%s unable to allocate memory for client", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for client", __func__);
     socket_free(socket);
     return;
   }
@@ -339,7 +338,7 @@ static void accept_ready(socket_t *socket, UNUSED_ATTR void *context) {
   client->socket = socket;
 
   if (!list_append(clients_, client)) {
-    LOG_ERROR("%s unable to add client to list", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to add client to list", __func__);
     client_free(client);
     return;
   }
diff --git a/btcore/src/hal_util.c b/btcore/src/hal_util.c
new file mode 100644 (file)
index 0000000..c2bf880
--- /dev/null
@@ -0,0 +1,92 @@
+//
+//  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.
+//
+
+#define LOG_TAG "hal_util"
+
+#include <hardware/bluetooth.h>
+#include <hardware/hardware.h>
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <string.h>
+
+#include "btcore/include/hal_util.h"
+#include "osi/include/log.h"
+
+#if defined(OS_GENERIC)
+
+// TODO(armansito): All logging macros should include __func__ by default (see
+// Bug: 22671731)
+#define HULOGERR(fmt, args...) \
+    LOG_ERROR(LOG_TAG, "[%s] failed to load the Bluetooth library: " fmt, \
+              __func__, ## args)
+
+// TODO(armansito): It might be better to pass the library name in a more
+// generic manner as opposed to hard-coding it here.
+static const char kBluetoothLibraryName[] = "libbluetooth.default.so";
+
+static int load_bt_library(const struct hw_module_t **module) {
+  const char *id = BT_STACK_MODULE_ID;
+
+  // Always try to load the default Bluetooth stack on GN builds.
+  void *handle = dlopen(kBluetoothLibraryName, RTLD_NOW);
+  if (!handle) {
+    char const *err_str = dlerror();
+    HULOGERR("%s", err_str ? err_str : "error unknown");
+    goto error;
+  }
+
+  // Get the address of the struct hal_module_info.
+  const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
+  struct hw_module_t *hmi = (struct hw_module_t *)dlsym(handle, sym);
+  if (!hmi) {
+    HULOGERR("%s", sym);
+    goto error;
+  }
+
+  // Check that the id matches.
+  if (strcmp(id, hmi->id) != 0) {
+    HULOGERR("id=%s does not match HAL module ID: %s", id, hmi->id);
+    goto error;
+  }
+
+  hmi->dso = handle;
+
+  // Success.
+  LOG_INFO(
+      LOG_TAG, "[%s] loaded HAL id=%s path=%s hmi=%p handle=%p",
+      __func__, id, kBluetoothLibraryName, hmi, handle);
+
+  *module = hmi;
+  return 0;
+
+error:
+  *module = NULL;
+  if (handle)
+    dlclose(handle);
+
+  return -EINVAL;
+}
+
+#endif  // defined(OS_GENERIC)
+
+int hal_util_load_bt_library(const struct hw_module_t **module) {
+#if defined(OS_GENERIC)
+  return load_bt_library(module);
+#else  // !defined(OS_GENERIC)
+  return hw_get_module(BT_STACK_MODULE_ID, module);
+#endif  // defined(OS_GENERIC)
+}
index 745a368..341bc82 100644 (file)
 #include <pthread.h>
 #include <string.h>
 
-#include "osi/include/allocator.h"
-#include "osi/include/hash_map.h"
 #include "btcore/include/module.h"
-#include "osi/include/osi.h"
+#include "osi/include/allocator.h"
 #include "osi/include/hash_functions.h"
+#include "osi/include/hash_map.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 
 typedef enum {
   MODULE_STATE_NONE = 0,
@@ -79,7 +79,7 @@ bool module_init(const module_t *module) {
   assert(get_module_state(module) == MODULE_STATE_NONE);
 
   if (!call_lifecycle_function(module->init)) {
-    LOG_ERROR("%s failed to initialize \"%s\"", __func__, module->name);
+    LOG_ERROR(LOG_TAG, "%s failed to initialize \"%s\"", __func__, module->name);
     return false;
   }
 
@@ -96,7 +96,7 @@ bool module_start_up(const module_t *module) {
   assert(get_module_state(module) == MODULE_STATE_INITIALIZED || module->init == NULL);
 
   if (!call_lifecycle_function(module->start_up)) {
-    LOG_ERROR("%s failed to start up \"%s\"", __func__, module->name);
+    LOG_ERROR(LOG_TAG, "%s failed to start up \"%s\"", __func__, module->name);
     return false;
   }
 
@@ -115,7 +115,7 @@ void module_shut_down(const module_t *module) {
     return;
 
   if (!call_lifecycle_function(module->shut_down))
-    LOG_ERROR("%s found \"%s\" reported failure during shutdown. Continuing anyway.", __func__, module->name);
+    LOG_ERROR(LOG_TAG, "%s found \"%s\" reported failure during shutdown. Continuing anyway.", __func__, module->name);
 
   set_module_state(module, MODULE_STATE_INITIALIZED);
 }
@@ -131,7 +131,7 @@ void module_clean_up(const module_t *module) {
     return;
 
   if (!call_lifecycle_function(module->clean_up))
-    LOG_ERROR("%s found \"%s\" reported failure during cleanup. Continuing anyway.", __func__, module->name);
+    LOG_ERROR(LOG_TAG, "%s found \"%s\" reported failure during cleanup. Continuing anyway.", __func__, module->name);
 
   set_module_state(module, MODULE_STATE_NONE);
 }
diff --git a/btif/BUILD.gn b/btif/BUILD.gn
new file mode 100644 (file)
index 0000000..cee6c03
--- /dev/null
@@ -0,0 +1,89 @@
+#
+#  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.
+#
+
+static_library("btif") {
+  sources = [
+    "src/btif_av.c",
+    "src/btif_config.c",
+    "src/btif_config_transcode.cpp",
+    "src/btif_core.c",
+    "src/btif_debug.c",
+    "src/btif_debug_btsnoop.c",
+    "src/btif_debug_conn.c",
+    "src/btif_dm.c",
+    "src/btif_gatt.c",
+    "src/btif_gatt_client.c",
+    "src/btif_gatt_multi_adv_util.c",
+    "src/btif_gatt_server.c",
+    "src/btif_gatt_test.c",
+    "src/btif_gatt_util.c",
+    "src/btif_hf.c",
+    "src/btif_hf_client.c",
+    "src/btif_hh.c",
+    "src/btif_hl.c",
+    "src/btif_mce.c",
+    "src/btif_media_task.c",
+    "src/btif_pan.c",
+    "src/btif_profile_queue.c",
+    "src/btif_rc.c",
+    "src/btif_sdp.c",
+    "src/btif_sdp_server.c",
+    "src/btif_sm.c",
+    "src/btif_sock.c",
+    "src/btif_sock_l2cap.c",
+    "src/btif_sock_rfc.c",
+    "src/btif_sock_sco.c",
+    "src/btif_sock_sdp.c",
+    "src/btif_sock_thread.c",
+    "src/btif_sock_util.c",
+    "src/btif_storage.c",
+    "src/btif_util.c",
+    "src/stack_manager.c",
+  ]
+
+  # BTIF callouts
+  sources += [
+    "co/bta_ag_co.c",
+    "co/bta_dm_co.c",
+    "co/bta_av_co.c",
+    "co/bta_hh_co.c",
+    "co/bta_hl_co.c",
+    "co/bta_pan_co.c",
+    "co/bta_gattc_co.c",
+    "co/bta_gatts_co.c",
+  ]
+
+  include_dirs = [
+    "include",
+    "//",
+    "//audio_a2dp_hw",
+    "//bta/include",
+    "//bta/sys",
+    "//btcore/include",
+    "//embdrv/sbc/encoder/include",
+    "//gki/common",
+    "//hci/include",
+    "//osi/include",
+    "//stack/a2dp",
+    "//stack/btm",
+    "//stack/include",
+    "//third_party/tinyxml2",
+    "//include",
+    "//udrv/include",
+    "//utils/include",
+    "//vnd/include",
+  ]
+}
index 31dfde1..063326a 100644 (file)
@@ -532,8 +532,6 @@ tBTA_HH_RPT_CACHE_ENTRY * bta_hh_le_co_cache_load (BD_ADDR remote_bda,
 {
     UNUSED(app_id);
 
-    unsigned idx = 0;
-
     bdstr_t bdstr;
     sprintf(bdstr, "%02x:%02x:%02x:%02x:%02x:%02x",
         remote_bda[0], remote_bda[1], remote_bda[2],
index 9aa91f7..c06ad5c 100644 (file)
  *
  ******************************************************************************/
 
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <errno.h>
 #include <string.h>
-#include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/types.h>
 #include <sys/un.h>
 #include <time.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <cutils/sockets.h>
+
 #include "bta_api.h"
-#include "btm_api.h"
-#include "bta_sys.h"
 #include "bta_hl_api.h"
-#include "bta_hl_co.h"
 #include "bta_hl_ci.h"
+#include "bta_hl_co.h"
+#include "bta_sys.h"
 #include "btif_hl.h"
 #include "btif_util.h"
-
+#include "btm_api.h"
 
 /*****************************************************************************
 **  Constants and Data Types
index 7e8c506..bbf837c 100644 (file)
 #define BTIF_COMMON_H
 
 #include <stdlib.h>
+
 #include <hardware/bluetooth.h>
 
 #include "bt_types.h"
 #include "bta_api.h"
 #include "osi.h"
-
-#ifndef LOG_TAG
-#error "LOG_TAG not defined, please add in .c file prior to including bt_common.h"
-#endif
-
 #include "osi/include/log.h"
 
 /*******************************************************************************
 **  Constants & Macros
 ********************************************************************************/
 
-#define ASSERTC(cond, msg, val) if (!(cond)) { LOG_ERROR( \
+#define ASSERTC(cond, msg, val) if (!(cond)) { LOG_ERROR(LOG_TAG, \
     "### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, val);}
 
 /* Calculate start of event enumeration; id is top 8 bits of event */
index f9d4a8d..de5d86b 100644 (file)
  *
  ******************************************************************************/
 
-
-#ifndef BTIF_GATT_MULTI_ADV_UTIL_H
-#define BTIF_GATT_MULTI_ADV_UTIL_H
+#pragma once
 
 #include <hardware/bluetooth.h>
+
 #include "bta_api.h"
 
 #define CLNT_IF_IDX 0
@@ -50,27 +49,27 @@ typedef struct
     uint8_t* p_service_uuid;
 } btif_adv_data_t;
 
+
 typedef struct
 {
-    BOOLEAN is_scan_rsp;
     UINT8 client_if;
-    UINT16 service_uuid_len;
     tBTA_BLE_AD_MASK mask;
     tBTA_BLE_ADV_DATA data;
     tBTA_BLE_ADV_PARAMS param;
     TIMER_LIST_ENT tle_limited_timer;
     int timeout_s;
-}btgatt_multi_adv_inst_cb;
+} btgatt_multi_adv_inst_cb;
 
 typedef struct
 {
-     INT8 *clntif_map;
+    INT8 *clntif_map;
     // Includes the stored data for standard LE instance
     btgatt_multi_adv_inst_cb *inst_cb;
 
 } btgatt_multi_adv_common_data;
 
 extern btgatt_multi_adv_common_data *btif_obtain_multi_adv_data_cb();
+
 extern void btif_gattc_incr_app_count(void);
 extern void btif_gattc_decr_app_count(void);
 extern int btif_multi_adv_add_instid_map(int client_if, int inst_id,
@@ -92,6 +91,4 @@ extern void btif_gattc_adv_data_packager(int client_if, bool set_scan_rsp,
                 char* service_uuid, btif_adv_data_t *p_multi_adv_inst);
 extern void btif_gattc_adv_data_cleanup(const btif_adv_data_t* adv);
 void btif_multi_adv_timer_ctrl(int client_if, TIMER_CBACK cb);
-#endif
-
 
index e080cd7..af217c2 100644 (file)
  *
  ******************************************************************************/
 
-
 #ifndef BTIF_GATT_UTIL_H
 #define BTIF_GATT_UTIL_H
 
-#include "bta_api.h"
+#include <hardware/bluetooth.h>
+#include <hardware/bt_gatt.h>
+
+#include "bta/include/bta_gatt_api.h"
 
 void btif_to_bta_uuid(tBT_UUID *p_dest, bt_uuid_t *p_src);
 void btif_to_bta_gatt_id(tBTA_GATT_ID *p_dest, btgatt_gatt_id_t *p_src);
index c4d8e81..51eaaf5 100644 (file)
 #ifndef BTIF_HL_H
 #define BTIF_HL_H
 
+#include <hardware/bluetooth.h>
+
+#include "bta_hl_api.h"
+#include "gki.h"
+
 /*******************************************************************************
 **  Constants & Macros
 ********************************************************************************/
@@ -39,8 +44,6 @@
 #define BTIF_HL_CCH_NUM_FILTER_ELEMS            3
 #define BTIF_HL_APPLICATION_NAME_LEN          512
 
-
-
 /*******************************************************************************
 **  Type definitions and return values
 ********************************************************************************/
@@ -277,7 +280,6 @@ typedef struct
     int                     fd;
 } btif_hl_send_chan_state_cb_t;
 
-
 typedef struct
 {
     UINT8 app_idx;
@@ -294,7 +296,6 @@ typedef union
     btif_hl_update_mdl_t    update_mdl;
 } btif_hl_evt_cb_t;
 
-
 /*******************************************************************************
 **  Functions
 ********************************************************************************/
index f28daac..5cc3d0a 100644 (file)
@@ -27,6 +27,8 @@
 #ifndef BTIF_PROFILE_QUEUE_H
 #define BTIF_PROFILE_QUEUE_H
 
+#include <hardware/bluetooth.h>
+
 typedef bt_status_t (*btif_connect_cb_t) (bt_bdaddr_t *bda, uint16_t uuid);
 
 bt_status_t btif_queue_connect(uint16_t uuid, const bt_bdaddr_t *bda, btif_connect_cb_t connect_cb);
index baad0d9..b4caf9e 100644 (file)
 #ifndef BTIF_SM_H
 #define BTIF_SM_H
 
+#include <hardware/bluetooth.h>
+
+#include "stack/include/bt_types.h"
+
 /*****************************************************************************
 **  Constants & Macros
 ******************************************************************************/
@@ -35,7 +39,6 @@
 #define BTIF_SM_ENTER_EVT 0xFFFF
 #define BTIF_SM_EXIT_EVT  0xFFFE
 
-
 /*****************************************************************************
 **  Type definitions and return values
 ******************************************************************************/
@@ -44,7 +47,6 @@ typedef UINT32 btif_sm_event_t;
 typedef void* btif_sm_handle_t;
 typedef BOOLEAN(*btif_sm_handler_t)(btif_sm_event_t event, void *data);
 
-
 /*****************************************************************************
 **  Functions
 **
index 9425dc9..065aa48 100644 (file)
@@ -5,11 +5,10 @@
 #ifndef BTIF_SOCK_L2CAP_H
 #define BTIF_SOCK_L2CAP_H
 
-
+#include <hardware/bluetooth.h>
 
 #define L2CAP_MASK_FIXED_CHANNEL    0x10000
 
-
 bt_status_t btsock_l2cap_init(int handle);
 bt_status_t btsock_l2cap_cleanup();
 bt_status_t btsock_l2cap_listen(const char* name, int channel,
index 9c09b0f..7353cc9 100644 (file)
@@ -20,6 +20,8 @@
 #define BTIF_SOCK_SDP_H
 
 #include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
 
 static const uint8_t  UUID_OBEX_OBJECT_PUSH[] = {0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
                                                  0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
index 1b5e241..b81c494 100644 (file)
@@ -20,6 +20,8 @@
 #define BTIF_SOCK_THREAD_H
 
 #include <stdbool.h>
+
+#include <hardware/bluetooth.h>
 #include <hardware/bt_sock.h>
 
 /*******************************************************************************
index eff18d2..eb915f9 100644 (file)
@@ -27,7 +27,7 @@
 #ifndef BTIF_SOCK_UTIL_H
 #define BTIF_SOCK_UTIL_H
 
-#include "osi/include/log.h"
+#include <stdint.h>
 
 void dump_bin(const char* title, const char* data, int size);
 
index 54dc5d6..758436f 100644 (file)
@@ -19,6 +19,9 @@
 #ifndef BTIF_STORAGE_H
 #define BTIF_STORAGE_H
 
+#include <hardware/bluetooth.h>
+
+#include "bt_target.h"
 #include "bt_types.h"
 
 /*******************************************************************************
index 1cb87fe..08f7f00 100644 (file)
@@ -19,6 +19,7 @@
 #pragma once
 
 #include "future.h"
+#include <stdbool.h>
 
 typedef struct {
   void (*init_stack)(void);
index 3213221..48d66d4 100644 (file)
  *
  ***********************************************************************************/
 
+#define LOG_NDDEBUG 0
+#define LOG_TAG "bt_bluedroid"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
 #include <hardware/bluetooth.h>
+#include <hardware/bt_av.h>
+#include <hardware/bt_gatt.h>
 #include <hardware/bt_hf.h>
 #include <hardware/bt_hf_client.h>
-#include <hardware/bt_av.h>
-#include <hardware/bt_sock.h>
 #include <hardware/bt_hh.h>
 #include <hardware/bt_hl.h>
-#include <hardware/bt_pan.h>
 #include <hardware/bt_mce.h>
-#include <hardware/bt_gatt.h>
+#include <hardware/bt_pan.h>
 #include <hardware/bt_rc.h>
 #include <hardware/bt_sdp.h>
+#include <hardware/bt_sock.h>
 
-#define LOG_NDDEBUG 0
-#define LOG_TAG "bt_bluedroid"
-
+#include "bt_utils.h"
 #include "btif_api.h"
 #include "btif_debug.h"
 #include "btsnoop.h"
 #include "btsnoop_mem.h"
-#include "bt_utils.h"
-#include "osi/include/osi.h"
 #include "osi/include/allocation_tracker.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 #include "stack_manager.h"
 #include "btif_config.h"
 
@@ -120,7 +120,7 @@ static bool interface_ready(void) {
 *****************************************************************************/
 
 static int init(bt_callbacks_t *callbacks) {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
 
   if (interface_ready())
     return BT_STATUS_DONE;
@@ -136,7 +136,7 @@ static int init(bt_callbacks_t *callbacks) {
 }
 
 static int enable(void) {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
 
   if (!interface_ready())
     return BT_STATUS_NOT_READY;
@@ -318,7 +318,7 @@ static void dump(int fd)
 
 static const void* get_profile_interface (const char *profile_id)
 {
-    LOG_INFO("get_profile_interface %s", profile_id);
+    LOG_INFO(LOG_TAG, "get_profile_interface %s", profile_id);
 
     /* sanity check */
     if (interface_ready() == FALSE)
@@ -368,7 +368,7 @@ static const void* get_profile_interface (const char *profile_id)
 
 int dut_mode_configure(uint8_t enable)
 {
-    LOG_INFO("dut_mode_configure");
+    LOG_INFO(LOG_TAG, "dut_mode_configure");
 
     /* sanity check */
     if (interface_ready() == FALSE)
@@ -379,7 +379,7 @@ int dut_mode_configure(uint8_t enable)
 
 int dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len)
 {
-    LOG_INFO("dut_mode_send");
+    LOG_INFO(LOG_TAG, "dut_mode_send");
 
     /* sanity check */
     if (interface_ready() == FALSE)
@@ -391,7 +391,7 @@ int dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len)
 #if BLE_INCLUDED == TRUE
 int le_test_mode(uint16_t opcode, uint8_t* buf, uint8_t len)
 {
-    LOG_INFO("le_test_mode");
+    LOG_INFO(LOG_TAG, "le_test_mode");
 
     /* sanity check */
     if (interface_ready() == FALSE)
@@ -403,7 +403,7 @@ int le_test_mode(uint16_t opcode, uint8_t* buf, uint8_t len)
 
 int config_hci_snoop_log(uint8_t enable)
 {
-    LOG_INFO("config_hci_snoop_log");
+    LOG_INFO(LOG_TAG, "config_hci_snoop_log");
 
     if (!interface_ready())
         return BT_STATUS_NOT_READY;
@@ -488,12 +488,11 @@ static int open_bluetooth_stack(const struct hw_module_t *module, UNUSED_ATTR ch
   return 0;
 }
 
-
 static struct hw_module_methods_t bt_stack_module_methods = {
     .open = open_bluetooth_stack,
 };
 
-struct hw_module_t HAL_MODULE_INFO_SYM = {
+EXPORT_SYMBOL struct hw_module_t HAL_MODULE_INFO_SYM = {
     .tag = HARDWARE_MODULE_TAG,
     .version_major = 1,
     .version_minor = 0,
index 5715748..016c4b8 100644 (file)
@@ -16,7 +16,6 @@
  *
  ******************************************************************************/
 
-
 /*****************************************************************************
  *
  *  Filename:      btif_av.c
  *
  *****************************************************************************/
 
+#include "btif_av.h"
+
 #include <assert.h>
 #include <string.h>
 
-#include <hardware/bluetooth.h>
 #include <system/audio.h>
-#include "hardware/bt_av.h"
-#include "osi/include/allocator.h"
-
-#define LOG_TAG "bt_btif_av"
+#include <hardware/bluetooth.h>
+#include <hardware/bt_av.h>
 
-#include "btif_av.h"
-#include "btif_util.h"
-#include "btif_profile_queue.h"
+#include "bt_utils.h"
 #include "bta_api.h"
 #include "btif_media.h"
-#include "bta_av_api.h"
-#include "gki.h"
+#include "btif_profile_queue.h"
+#include "btif_util.h"
 #include "btu.h"
-#include "bt_utils.h"
+#include "gki.h"
+#include "osi/include/allocator.h"
 
 /*****************************************************************************
 **  Constants & Macros
@@ -329,7 +326,7 @@ static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
 
             BTIF_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV");
             memset(&tle_av_open_on_rc, 0, sizeof(tle_av_open_on_rc));
-            tle_av_open_on_rc.param = (UINT32)btif_initiate_av_open_tmr_hdlr;
+            tle_av_open_on_rc.param = btif_initiate_av_open_tmr_hdlr;
             btu_start_timer(&tle_av_open_on_rc, BTU_TTYPE_USER_FUNC,
                             BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS);
             btif_rc_handler(event, p_data);
@@ -494,7 +491,6 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data
    return TRUE;
 }
 
-
 /*****************************************************************************
 **
 ** Function        btif_av_state_closing_handler
@@ -565,7 +561,6 @@ static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data
    return TRUE;
 }
 
-
 /*****************************************************************************
 **
 ** Function     btif_av_state_opened_handler
index 19482ef..42bcbb8 100644 (file)
 
 #define LOG_TAG "bt_btif_config"
 
+#include "btif_config.h"
+
 #include <assert.h>
 #include <ctype.h>
 #include <pthread.h>
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 
-#include "osi/include/alarm.h"
-#include "osi/include/allocator.h"
+#include "bt_types.h"
 #include "btcore/include/bdaddr.h"
-#include "btif_config.h"
+#include "btcore/include/module.h"
 #include "btif_config_transcode.h"
 #include "btif_util.h"
+#include "osi/include/alarm.h"
+#include "osi/include/allocator.h"
 #include "osi/include/compat.h"
 #include "osi/include/config.h"
-#include "btcore/include/module.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 
-#include "bt_types.h"
-
+// TODO(armansito): Find a better way than searching by a hardcoded path.
+#if defined(OS_GENERIC)
+static const char *CONFIG_FILE_PATH = "bt_config.conf";
+#else  // !defined(OS_GENERIC)
 static const char *CONFIG_FILE_PATH = "/data/misc/bluedroid/bt_config.conf";
+#endif  // defined(OS_GENERIC)
 static const char *LEGACY_CONFIG_FILE_PATH = "/data/misc/bluedroid/bt_config.xml";
 static const period_ms_t CONFIG_SETTLE_PERIOD_MS = 3000;
 
@@ -60,7 +66,7 @@ bool btif_get_device_type(const BD_ADDR bd_addr, int *p_device_type)
     if (!btif_config_get_int(bd_addr_str, "DevType", p_device_type))
         return FALSE;
 
-    LOG_DEBUG("%s: Device [%s] type %d", __FUNCTION__, bd_addr_str, *p_device_type);
+    LOG_DEBUG(LOG_TAG, "%s: Device [%s] type %d", __FUNCTION__, bd_addr_str, *p_device_type);
     return TRUE;
 }
 
@@ -78,7 +84,7 @@ bool btif_get_address_type(const BD_ADDR bd_addr, int *p_addr_type)
     if (!btif_config_get_int(bd_addr_str, "AddrType", p_addr_type))
         return FALSE;
 
-    LOG_DEBUG("%s: Device [%s] address type %d", __FUNCTION__, bd_addr_str, *p_addr_type);
+    LOG_DEBUG(LOG_TAG, "%s: Device [%s] address type %d", __FUNCTION__, bd_addr_str, *p_addr_type);
     return TRUE;
 }
 
@@ -92,13 +98,13 @@ static future_t *init(void) {
   pthread_mutex_init(&lock, NULL);
   config = config_new(CONFIG_FILE_PATH);
   if (!config) {
-    LOG_WARN("%s unable to load config file; attempting to transcode legacy file.", __func__);
+    LOG_WARN(LOG_TAG, "%s unable to load config file; attempting to transcode legacy file.", __func__);
     config = btif_config_transcode(LEGACY_CONFIG_FILE_PATH);
     if (!config) {
-      LOG_WARN("%s unable to transcode legacy file, starting unconfigured.", __func__);
+      LOG_WARN(LOG_TAG, "%s unable to transcode legacy file, starting unconfigured.", __func__);
       config = config_new_empty();
       if (!config) {
-        LOG_ERROR("%s unable to allocate a config object.", __func__);
+        LOG_ERROR(LOG_TAG, "%s unable to allocate a config object.", __func__);
         goto error;
       }
     }
@@ -112,7 +118,7 @@ static future_t *init(void) {
   // write back to disk.
   alarm_timer = alarm_new();
   if (!alarm_timer) {
-    LOG_ERROR("%s unable to create alarm.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create alarm.", __func__);
     goto error;
   }
 
@@ -143,7 +149,7 @@ static future_t *clean_up(void) {
   return future_new_immediate(FUTURE_SUCCESS);
 }
 
-const module_t btif_config_module = {
+EXPORT_SYMBOL const module_t btif_config_module = {
   .name = BTIF_CONFIG_MODULE,
   .init = init,
   .start_up = NULL,
index e9d859e..e8bd1a2 100644 (file)
@@ -31,19 +31,19 @@ extern "C" config_t *btif_config_transcode(const char *xml_filename) {
   XMLDocument document;
   int error = document.LoadFile(xml_filename);
   if (error != XML_SUCCESS) {
-    LOG_ERROR("%s unable to load XML file '%s': %d", __func__, xml_filename, error);
+    LOG_ERROR(LOG_TAG, "%s unable to load XML file '%s': %d", __func__, xml_filename, error);
     return NULL;
   }
 
   XMLElement *rootElement = document.RootElement();
   if (!rootElement) {
-    LOG_ERROR("%s unable to find root element; assuming corrupted config file.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to find root element; assuming corrupted config file.", __func__);
     return NULL;
   }
 
   config_t *config = config_new_empty();
   if (!config) {
-    LOG_ERROR("%s unable to allocate config object.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate config object.", __func__);
     return NULL;
   }
 
index 0ff9651..5990a93 100644 (file)
@@ -26,8 +26,9 @@
  *
  ***********************************************************************************/
 
+#define LOG_TAG "bt_btif_core"
+
 #include <ctype.h>
-#include <cutils/properties.h>
 #include <dirent.h>
 #include <fcntl.h>
 #include <hardware/bluetooth.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-
-#define LOG_TAG "bt_btif_core"
-#include "btcore/include/bdaddr.h"
+#include <unistd.h>
+
+/**
+ * TODO(armansito): On OSs other than Android, the sys/properties.h system
+ * does not exist. Remove this conditional include once we have a generic way
+ * to obtain system properties.
+ */
+#if !defined(OS_GENERIC)
+#include <cutils/properties.h>
+#endif  /* !defined(OS_GENERIC) */
 
 #include "bdaddr.h"
 #include "bt_utils.h"
 #include "btif_api.h"
 #include "btif_av.h"
 #include "btif_config.h"
+#include "btif_config.h"
 #include "btif_pan.h"
 #include "btif_profile_queue.h"
-#include "btif_config.h"
 #include "btif_sock.h"
 #include "btif_storage.h"
 #include "btif_util.h"
 #include "btu.h"
 #include "device/include/controller.h"
+#include "gki.h"
 #include "osi/include/fixed_queue.h"
 #include "osi/include/future.h"
-#include "gki.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
-#include "stack_manager.h"
+#include "osi/include/osi.h"
 #include "osi/include/thread.h"
+#include "stack_manager.h"
 
 /************************************************************************************
 **  Constants & Macros
 ************************************************************************************/
 
 #ifndef BTE_DID_CONF_FILE
+// TODO(armansito): Find a better way than searching by a hardcoded path.
+#if defined(OS_GENERIC)
+#define BTE_DID_CONF_FILE "bt_did.conf"
+#else  // !defined(OS_GENERIC)
 #define BTE_DID_CONF_FILE "/etc/bluetooth/bt_did.conf"
-#endif
+#endif  // defined(OS_GENERIC)
+#endif  // BTE_DID_CONF_FILE
 
 /************************************************************************************
 **  Local type definitions
@@ -335,6 +348,13 @@ static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr)
     char val[PROPERTY_VALUE_MAX] = {0};
     uint8_t valid_bda = FALSE;
     int val_size = 0;
+
+  /**
+   * TODO(armansito): On OSs other than Android, the sys/properties.h system
+   * does not exist. Remove this conditional include once we have a generic way
+   * to obtain system properties.
+   */
+#if !defined(OS_GENERIC)
     const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0};
 
     /* Get local bdaddr storage path from property */
@@ -379,6 +399,7 @@ static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr)
     if (!valid_bda) {
         valid_bda = btif_fetch_property(FACTORY_BT_ADDR_PROPERTY, local_addr);
     }
+#endif  /* !defined(OS_GENERIC) */
 
     /* Generate new BDA if necessary */
     if (!valid_bda)
@@ -401,8 +422,16 @@ static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr)
         BTIF_TRACE_DEBUG("No preset BDA. Generating BDA: %s for prop %s",
              (char*)bdstr, PERSIST_BDADDR_PROPERTY);
 
+
+  /**
+   * TODO(armansito): On OSs other than Android, the sys/properties.h system
+   * does not exist. Remove this conditional include once we have a generic way
+   * to obtain system properties.
+   */
+#if !defined(OS_GENERIC)
         if (property_set(PERSIST_BDADDR_PROPERTY, (char*)bdstr) < 0)
             BTIF_TRACE_ERROR("Failed to set random BDA in prop %s",PERSIST_BDADDR_PROPERTY);
+#endif  /* !defined(OS_GENERIC) */
     }
 
     //save the bd address to config file
@@ -438,7 +467,7 @@ bt_status_t btif_init_bluetooth() {
 
   bt_jni_workqueue_thread = thread_new(BT_JNI_WORKQUEUE_NAME);
   if (bt_jni_workqueue_thread == NULL) {
-    LOG_ERROR("%s Unable to create thread %s", __func__, BT_JNI_WORKQUEUE_NAME);
+    LOG_ERROR(LOG_TAG, "%s Unable to create thread %s", __func__, BT_JNI_WORKQUEUE_NAME);
     goto error_exit;
   }
 
@@ -859,9 +888,6 @@ static void execute_storage_request(UINT16 event, char *p_param)
                 local_le_features.version_supported = cmn_vsc_cb.version_supported;
                 local_le_features.total_trackable_advertisers =
                     cmn_vsc_cb.total_trackable_advertisers;
-
-                local_le_features.extended_scan_support = cmn_vsc_cb.extended_scan_support > 0;
-                local_le_features.debug_logging_supported = cmn_vsc_cb.debug_logging_supported > 0;
                 memcpy(prop.val, &local_le_features, prop.len);
                 #endif
             }
index dcee736..6ba33f8 100644 (file)
@@ -27,6 +27,8 @@
 
 #define LOG_TAG "bt_btif_dm"
 
+#include "btif_dm.h"
+
 #include <assert.h>
 #include <signal.h>
 #include <stdio.h>
 
 #include <hardware/bluetooth.h>
 
+/**
+ * TODO(armansito): cutils/properties.h is only being used to pull-in runtime
+ * settings on Android. Remove this conditional include once we have a generic
+ * way to obtain system properties.
+ */
+#if !defined(OS_GENERIC)
 #include <cutils/properties.h>
-#include "gki.h"
-#include "btu.h"
-#include "btcore/include/bdaddr.h"
-#include "bta_api.h"
+#endif  /* !defined(OS_GENERIC) */
+
+#include "bdaddr.h"
+#include "bta_gatt_api.h"
 #include "btif_api.h"
-#include "btif_util.h"
-#include "btif_dm.h"
-#include "btif_storage.h"
-#include "btif_hh.h"
 #include "btif_config.h"
+#include "btif_hh.h"
 #include "btif_sdp.h"
+#include "btif_storage.h"
+#include "btif_util.h"
+#include "btu.h"
+#include "gki.h"
 #include "bta_gatt_api.h"
 #include "device/include/interop.h"
 #include "include/stack_config.h"
 #include "osi/include/log.h"
 #include "osi/include/allocator.h"
+#include "osi/include/log.h"
+#include "stack_config.h"
 #include "stack/btm/btm_int.h"
 
 /******************************************************************************
@@ -71,7 +82,6 @@
 #define COD_AV_PORTABLE_AUDIO               0x041C
 #define COD_AV_HIFI_AUDIO                   0x0428
 
-
 #define BTIF_DM_DEFAULT_INQ_MAX_RESULTS     0
 #define BTIF_DM_DEFAULT_INQ_MAX_DURATION    10
 #define BTIF_DM_MAX_SDP_ATTEMPTS_AFTER_PAIRING 2
@@ -117,7 +127,6 @@ typedef struct
 #endif
 } btif_dm_pairing_cb_t;
 
-
 typedef struct
 {
     UINT8       ir[BT_OCTET16_LEN];
@@ -178,8 +187,6 @@ static skip_sdp_entry_t sdp_blacklist[] = {{76}}; //Apple Mouse and Keyboard
 /* This flag will be true if HCI_Inquiry is in progress */
 static BOOLEAN btif_dm_inquiry_in_progress = FALSE;
 
-
-
 /************************************************************************************
 **  Static variables
 ************************************************************************************/
@@ -221,7 +228,6 @@ extern bt_status_t btif_sdp_execute_service(BOOLEAN b_enable);
 extern int btif_hh_connect(bt_bdaddr_t *bd_addr);
 extern void bta_gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16);
 
-
 /******************************************************************************
 **  Functions
 ******************************************************************************/
@@ -383,7 +389,7 @@ BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod)
                                sizeof(uint32_t), &remote_cod);
     if (btif_storage_get_remote_device_property((bt_bdaddr_t *)remote_bdaddr, &prop_name) == BT_STATUS_SUCCESS)
     {
-        LOG_INFO("%s remote_cod = 0x%08x cod = 0x%08x", __func__, remote_cod, cod);
+        LOG_INFO(LOG_TAG, "%s remote_cod = 0x%08x cod = 0x%08x", __func__, remote_cod, cod);
         if ((remote_cod & 0x7ff) == cod)
             return TRUE;
     }
@@ -450,7 +456,6 @@ BOOLEAN check_sdp_bl(const bt_bdaddr_t *remote_bdaddr)
     bt_property_t prop_name;
     bt_remote_version_t info;
 
-
     if (remote_bdaddr == NULL)
         return FALSE;
 
@@ -458,8 +463,6 @@ BOOLEAN check_sdp_bl(const bt_bdaddr_t *remote_bdaddr)
     BTM_ReadRemoteVersion(*(BD_ADDR*)remote_bdaddr, &lmp_ver,
                     &manufacturer, &lmp_subver);
 
-
-
  /* if not available yet, try fetching from config database */
     BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_REMOTE_VERSION_INFO,
                             sizeof(bt_remote_version_t), &info);
@@ -480,7 +483,6 @@ BOOLEAN check_sdp_bl(const bt_bdaddr_t *remote_bdaddr)
     return FALSE;
 }
 
-
 static void bond_state_changed(bt_status_t status, bt_bdaddr_t *bd_addr, bt_bond_state_t state)
 {
     // Send bonding state only once - based on outgoing/incoming we may receive duplicates
@@ -530,7 +532,7 @@ static void btif_update_remote_version_property(bt_bdaddr_t *p_bd)
     btm_status = BTM_ReadRemoteVersion(*(BD_ADDR*)p_bd, &lmp_ver,
                           &mfct_set, &lmp_subver);
 
-    LOG_DEBUG("remote version info [%s]: %x, %x, %x", bdaddr_to_string(p_bd, bdstr, sizeof(bdstr)),
+    LOG_DEBUG(LOG_TAG, "remote version info [%s]: %x, %x, %x", bdaddr_to_string(p_bd, bdstr, sizeof(bdstr)),
                lmp_ver, mfct_set, lmp_subver);
 
     if (btm_status == BTM_SUCCESS)
@@ -547,7 +549,6 @@ static void btif_update_remote_version_property(bt_bdaddr_t *p_bd)
     }
 }
 
-
 static void btif_update_remote_properties(BD_ADDR bd_addr, BD_NAME bd_name,
                                           DEV_CLASS dev_class, tBT_DEVICE_TYPE device_type)
 {
@@ -995,7 +996,7 @@ static void btif_dm_ssp_cfm_req_evt(tBTA_DM_SP_CFM_REQ *p_ssp_cfm_req)
     cod = devclass2uint(p_ssp_cfm_req->dev_class);
 
     if (cod == 0) {
-        LOG_DEBUG("%s cod is 0, set as unclassified", __func__);
+        LOG_DEBUG(LOG_TAG, "%s cod is 0, set as unclassified", __func__);
         cod = COD_UNCLASSIFIED;
     }
 
@@ -1030,7 +1031,7 @@ static void btif_dm_ssp_key_notif_evt(tBTA_DM_SP_KEY_NOTIF *p_ssp_key_notif)
     cod = devclass2uint(p_ssp_key_notif->dev_class);
 
     if (cod == 0) {
-        LOG_DEBUG("%s cod is 0, set as unclassified", __func__);
+        LOG_DEBUG(LOG_TAG, "%s cod is 0, set as unclassified", __func__);
         cod = COD_UNCLASSIFIED;
     }
 
@@ -1104,14 +1105,14 @@ static void btif_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
 
         if (check_sdp_bl(&bd_addr) && check_cod_hid(&bd_addr, COD_HID_MAJOR))
         {
-            LOG_WARN("%s:skip SDP", __FUNCTION__);
+            LOG_WARN(LOG_TAG, "%s:skip SDP", __FUNCTION__);
             skip_sdp = TRUE;
         }
         if(!pairing_cb.is_local_initiated && skip_sdp)
         {
             bond_state_changed(status, &bd_addr, state);
 
-            LOG_WARN("%s: Incoming HID Connection",__FUNCTION__);
+            LOG_WARN(LOG_TAG, "%s: Incoming HID Connection",__FUNCTION__);
             bt_property_t prop;
             bt_bdaddr_t bd_addr;
             bt_uuid_t  uuid;
@@ -1295,7 +1296,7 @@ static void btif_dm_search_devices_evt (UINT16 event, char *p_param)
             cod = devclass2uint (p_search_data->inq_res.dev_class);
 
             if (cod == 0) {
-                LOG_DEBUG("%s cod is 0, set as unclassified", __func__);
+                LOG_DEBUG(LOG_TAG, "%s cod is 0, set as unclassified", __func__);
                 cod = COD_UNCLASSIFIED;
             }
 
@@ -1310,7 +1311,6 @@ static void btif_dm_search_devices_evt (UINT16 event, char *p_param)
                 /* TODO:  Get the service list and check to see which uuids we got and send it back to the client. */
             }
 
-
             {
                 bt_property_t properties[5];
                 bt_device_type_t dev_type;
@@ -1466,7 +1466,7 @@ static void btif_dm_search_services_evt(UINT16 event, char *p_param)
                  {
                       char temp[256];
                       uuid_to_string_legacy((bt_uuid_t*)(p_data->disc_res.p_uuid_list + (i*MAX_UUID_SIZE)), temp);
-                      LOG_INFO("%s index:%d uuid:%s", __func__, i, temp);
+                      LOG_INFO(LOG_TAG, "%s index:%d uuid:%s", __func__, i, temp);
                  }
             }
 
@@ -1533,7 +1533,7 @@ static void btif_dm_search_services_evt(UINT16 event, char *p_param)
                 }
 
                 uuid_to_string_legacy(&uuid, temp);
-                LOG_INFO("%s uuid:%s", __func__, temp);
+                LOG_INFO(LOG_TAG, "%s uuid:%s", __func__, temp);
 
                 bdcpy(bd_addr.address, p_data->disc_ble_res.bd_addr);
                 prop.type = BT_PROPERTY_UUIDS;
@@ -2675,7 +2675,6 @@ void btif_dm_proc_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap, tBTA_OOB_DATA *
     UNUSED (p_io_cap);
     UNUSED (p_oob_data);
 
-
     BTIF_TRACE_DEBUG("+%s: p_auth_req=%d", __FUNCTION__, *p_auth_req);
     if(pairing_cb.is_local_initiated)
     {
@@ -2736,6 +2735,12 @@ void btif_dm_set_oob_for_io_req(tBTA_OOB_DATA  *p_oob_data)
 #ifdef BTIF_DM_OOB_TEST
 void btif_dm_load_local_oob(void)
 {
+  /**
+   * TODO(armansito): On OSs other than Android, the sys/properties.h system
+   * does not exist. Remove this conditional include once we have a generic way
+   * to obtain system properties.
+   */
+#if !defined(OS_GENERIC)
     char prop_oob[PROPERTY_VALUE_MAX];
     property_get("service.brcm.bt.oob", prop_oob, "3");
     BTIF_TRACE_DEBUG("btif_dm_load_local_oob prop_oob = %s",prop_oob);
@@ -2748,14 +2753,21 @@ void btif_dm_load_local_oob(void)
             BTIF_TRACE_DEBUG("btif_dm_load_local_oob: read OOB, call BTA_DmLocalOob()");
             BTA_DmLocalOob();
         }
-#else
+#else  /* (BTM_OOB_INCLUDED != TRUE) */
         BTIF_TRACE_ERROR("BTM_OOB_INCLUDED is FALSE!!(btif_dm_load_local_oob)");
-#endif
+#endif  /* (BTM_OOB_INCLUDED == TRUE) */
     }
+#endif  /* !defined(OS_GENERIC) */
 }
 
 void btif_dm_proc_loc_oob(BOOLEAN valid, BT_OCTET16 c, BT_OCTET16 r)
 {
+  /**
+   * TODO(armansito): On OSs other than Android, the sys/properties.h system
+   * does not exist. Remove this conditional include once we have a generic way
+   * to obtain system properties.
+   */
+#if !defined(OS_GENERIC)
     FILE *fp;
     char *path_a = "/data/misc/bluedroid/LOCAL/a.key";
     char *path_b = "/data/misc/bluedroid/LOCAL/b.key";
@@ -2791,9 +2803,17 @@ void btif_dm_proc_loc_oob(BOOLEAN valid, BT_OCTET16 c, BT_OCTET16 r)
             }
         }
     }
+#endif  /* !defined(OS_GENERIC) */
 }
+
 BOOLEAN btif_dm_proc_rmt_oob(BD_ADDR bd_addr,  BT_OCTET16 p_c, BT_OCTET16 p_r)
 {
+  /**
+   * TODO(armansito): On OSs other than Android, the sys/properties.h system
+   * does not exist. Remove this conditional include once we have a generic way
+   * to obtain system properties.
+   */
+#if !defined(OS_GENERIC)
     char t[128];
     FILE *fp;
     char *path_a = "/data/misc/bluedroid/LOCAL/a.key";
@@ -2844,6 +2864,9 @@ BOOLEAN btif_dm_proc_rmt_oob(BD_ADDR bd_addr,  BT_OCTET16 p_c, BT_OCTET16 p_r)
     }
     BTIF_TRACE_DEBUG("btif_dm_proc_rmt_oob result=%d",result);
     return result;
+#else  /* defined(OS_GENERIC) */
+    return FALSE;
+#endif  /* !defined(OS_GENERIC) */
 }
 #endif /*  BTIF_DM_OOB_TEST */
 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
@@ -2941,8 +2964,6 @@ static void btif_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
     bond_state_changed(status, &bd_addr, state);
 }
 
-
-
 void    btif_dm_load_ble_local_keys(void)
 {
     memset(&ble_local_key_cb, 0, sizeof(btif_dm_local_key_cb_t));
@@ -3010,7 +3031,6 @@ void btif_dm_save_ble_bonding_keys(void)
                                          sizeof(tBTM_LE_PID_KEYS));
     }
 
-
     if (pairing_cb.ble.is_pcsrk_key_rcvd)
     {
         btif_storage_add_ble_bonding_key(&bd_addr,
@@ -3019,7 +3039,6 @@ void btif_dm_save_ble_bonding_keys(void)
                                          sizeof(tBTM_LE_PCSRK_KEYS));
     }
 
-
     if (pairing_cb.ble.is_lenc_key_rcvd)
     {
         btif_storage_add_ble_bonding_key(&bd_addr,
@@ -3046,7 +3065,6 @@ void btif_dm_save_ble_bonding_keys(void)
 
 }
 
-
 void btif_dm_remove_ble_bonding_keys(void)
 {
     bt_bdaddr_t bd_addr;
@@ -3057,7 +3075,6 @@ void btif_dm_remove_ble_bonding_keys(void)
     btif_storage_remove_ble_bonding_keys(&bd_addr);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btif_dm_ble_sec_req_evt
@@ -3107,8 +3124,6 @@ void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ *p_ble_req)
               BT_SSP_VARIANT_CONSENT, 0);
 }
 
-
-
 /*******************************************************************************
 **
 ** Function         btif_dm_ble_passkey_req_evt
@@ -3253,6 +3268,12 @@ void btif_dm_read_energy_info()
 }
 
 static char* btif_get_default_local_name() {
+  /**
+   * TODO(armansito): On OSs other than Android, the sys/properties.h system
+   * does not exist. Remove this conditional include once we have a generic way
+   * to obtain system properties.
+   */
+#if !defined(OS_GENERIC)
     if (btif_default_local_name[0] == '\0')
     {
         int max_len = sizeof(btif_default_local_name) - 1;
@@ -3268,5 +3289,6 @@ static char* btif_get_default_local_name() {
         }
         btif_default_local_name[max_len] = '\0';
     }
+#endif  /* !defined(OS_GENERIC) */
     return btif_default_local_name;
 }
index 50ebaee..ccb1704 100644 (file)
@@ -16,7 +16,6 @@
  *
  ******************************************************************************/
 
-
 /*******************************************************************************
  *
  *  Filename:      btif_gatt.c
  *
  *******************************************************************************/
 
+#define LOG_TAG "bt_btif_gatt"
+
+#include <errno.h>
 #include <hardware/bluetooth.h>
 #include <hardware/bt_gatt.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <errno.h>
 #include <string.h>
 
-#define LOG_TAG "bt_btif_gatt"
-
 #include "btif_common.h"
 #include "btif_util.h"
 
 
 #include "bta_api.h"
 #include "bta_gatt_api.h"
-#include "btif_storage.h"
-
 #include "btif_gatt.h"
 #include "btif_gatt_util.h"
+#include "btif_storage.h"
 
 const btgatt_callbacks_t *bt_gatt_callbacks = NULL;
 
index f70f2bb..a15dbf8 100644 (file)
@@ -16,7 +16,6 @@
  *
  ******************************************************************************/
 
-
 /*******************************************************************************
  *
  *  Filename:      btif_gatt_client.c
  *
  *******************************************************************************/
 
+#define LOG_TAG "bt_btif_gattc"
+
+#include <errno.h>
 #include <hardware/bluetooth.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <errno.h>
 #include <string.h>
 
-#define LOG_TAG "bt_btif_gattc"
-
 #include "btcore/include/bdaddr.h"
 #include "btif_common.h"
 #include "btif_util.h"
 
 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
 
-#include "btif_gatt_multi_adv_util.h"
 #include <hardware/bt_gatt.h>
+
 #include "bta_api.h"
 #include "bta_gatt_api.h"
-#include "btif_storage.h"
 #include "btif_config.h"
-
+#include "btif_dm.h"
 #include "btif_gatt.h"
+#include "btif_gatt_multi_adv_util.h"
 #include "btif_gatt_util.h"
-#include "btif_dm.h"
 #include "btif_storage.h"
-
+#include "btif_storage.h"
 #include "osi/include/log.h"
 #include "vendor_api.h"
 
 
 #define CHECK_BTGATT_INIT() if (bt_gatt_callbacks == NULL)\
     {\
-        LOG_WARN("%s: BTGATT not initialized", __FUNCTION__);\
+        LOG_WARN(LOG_TAG, "%s: BTGATT not initialized", __FUNCTION__);\
         return BT_STATUS_NOT_READY;\
     } else {\
-        LOG_VERBOSE("%s", __FUNCTION__);\
+        LOG_VERBOSE(LOG_TAG, "%s", __FUNCTION__);\
     }
 
 #define BLE_RESOLVE_ADDR_MSB                 0x40   /* bit7, bit6 is 01 to be resolvable random */
@@ -151,7 +149,6 @@ typedef struct
     btgatt_batch_reports  read_reports;
 } btgatt_batch_track_cb_t;
 
-
 typedef tBTA_DM_BLE_PF_FILT_PARAMS btgatt_adv_filt_param_t;
 
 typedef struct
@@ -247,7 +244,7 @@ static uint8_t rssi_request_client_if;
 static bt_status_t btif_gattc_multi_adv_disable(int client_if);
 static void btif_multi_adv_stop_cb(void *p_tle)
 {
-    int client_if = ((TIMER_LIST_ENT*)p_tle)->data;
+    int client_if = PTR_TO_INT(((TIMER_LIST_ENT*)p_tle)->data);
     btif_gattc_multi_adv_disable(client_if); // Does context switch
 }
 
@@ -401,7 +398,7 @@ static void btif_gattc_add_remote_bdaddr (BD_ADDR p_bda, uint8_t addr_type)
             memcpy(p_dev_cb->remote_dev[i].bd_addr.address, p_bda, BD_ADDR_LEN);
             p_dev_cb->addr_type = addr_type;
             p_dev_cb->remote_dev[i].in_use = TRUE;
-            LOG_VERBOSE("%s device added idx=%d", __FUNCTION__, i  );
+            LOG_VERBOSE(LOG_TAG, "%s device added idx=%d", __FUNCTION__, i  );
             break;
         }
     }
@@ -412,7 +409,7 @@ static void btif_gattc_add_remote_bdaddr (BD_ADDR p_bda, uint8_t addr_type)
         memcpy(p_dev_cb->remote_dev[i].bd_addr.address, p_bda, BD_ADDR_LEN);
         p_dev_cb->addr_type = addr_type;
         p_dev_cb->remote_dev[i].in_use = TRUE;
-        LOG_VERBOSE("%s device overwrite idx=%d", __FUNCTION__, i  );
+        LOG_VERBOSE(LOG_TAG, "%s device overwrite idx=%d", __FUNCTION__, i  );
         p_dev_cb->next_storage_idx++;
         if (p_dev_cb->next_storage_idx >= BTIF_GATT_MAX_OBSERVED_DEV)
                p_dev_cb->next_storage_idx = 0;
@@ -453,7 +450,7 @@ static void btif_gattc_update_properties ( btif_gattc_cb_t *p_btif_cb )
         memcpy(bdname.name, p_eir_remote_name, remote_name_len);
         bdname.name[remote_name_len]='\0';
 
-        LOG_DEBUG("%s BLE device name=%s len=%d dev_type=%d", __FUNCTION__, bdname.name,
+        LOG_DEBUG(LOG_TAG, "%s BLE device name=%s len=%d dev_type=%d", __FUNCTION__, bdname.name,
               remote_name_len, p_btif_cb->device_type  );
         btif_dm_update_ble_remote_properties( p_btif_cb->bd_addr.address,   bdname.name,
                                                p_btif_cb->device_type);
@@ -464,7 +461,7 @@ static void btif_gattc_update_properties ( btif_gattc_cb_t *p_btif_cb )
 
 static void btif_gattc_upstreams_evt(uint16_t event, char* p_param)
 {
-    LOG_VERBOSE("%s: Event %d", __FUNCTION__, event);
+    LOG_VERBOSE(LOG_TAG, "%s: Event %d", __FUNCTION__, event);
 
     tBTA_GATTC *p_data = (tBTA_GATTC*) p_param;
     switch (event)
@@ -606,7 +603,7 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param)
         }
 
         case BTA_GATTC_ACL_EVT:
-            LOG_DEBUG("BTA_GATTC_ACL_EVT: status = %d", p_data->status);
+            LOG_DEBUG(LOG_TAG, "BTA_GATTC_ACL_EVT: status = %d", p_data->status);
             /* Ignore for now */
             break;
 
@@ -843,7 +840,7 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param)
         }
 
         default:
-            LOG_ERROR("%s: Unhandled event (%d)!", __FUNCTION__, event);
+            LOG_ERROR(LOG_TAG, "%s: Unhandled event (%d)!", __FUNCTION__, event);
             break;
     }
 
@@ -1158,7 +1155,7 @@ static void btgattc_handle_event(uint16_t event, char* p_param)
     btif_gattc_cb_t* p_cb = (btif_gattc_cb_t*) p_param;
     if (!p_cb) return;
 
-    LOG_VERBOSE("%s: Event %d", __FUNCTION__, event);
+    LOG_VERBOSE(LOG_TAG, "%s: Event %d", __FUNCTION__, event);
 
     switch (event)
     {
@@ -1551,7 +1548,7 @@ static void btgattc_handle_event(uint16_t event, char* p_param)
                 }
 
                 default:
-                    LOG_ERROR("%s: Unknown filter type (%d)!", __FUNCTION__, p_cb->action);
+                    LOG_ERROR(LOG_TAG, "%s: Unknown filter type (%d)!", __FUNCTION__, p_cb->action);
                     break;
             }
             break;
@@ -1668,7 +1665,7 @@ static void btgattc_handle_event(uint16_t event, char* p_param)
                     btif_obtain_multi_adv_data_cb();
                 BTA_BleCfgAdvInstData(
                     (UINT8)inst_id,
-                    p_multi_adv_data_cb->inst_cb[cbindex].is_scan_rsp,
+                    p_adv_data->set_scan_rsp,
                     p_multi_adv_data_cb->inst_cb[cbindex].mask,
                     &p_multi_adv_data_cb->inst_cb[cbindex].data);
             }
@@ -1754,7 +1751,7 @@ static void btgattc_handle_event(uint16_t event, char* p_param)
         }
 
         default:
-            LOG_ERROR("%s: Unknown event (%d)!", __FUNCTION__, event);
+            LOG_ERROR(LOG_TAG, "%s: Unknown event (%d)!", __FUNCTION__, event);
             break;
     }
 
@@ -2350,7 +2347,6 @@ static bt_status_t btif_gattc_test_command(int command, btgatt_test_params_t* pa
     return btif_gattc_test_command_impl(command, params);
 }
 
-
 const btgatt_client_interface_t btgattClientInterface = {
     btif_gattc_register_app,
     btif_gattc_unregister_app,
index 63bca08..3eb9304 100644 (file)
@@ -16,7 +16,6 @@
  *
  ******************************************************************************/
 
-
 /*******************************************************************************
  *
  *  Filename:      btif_gatt_multi_adv_util.c
  *
  *******************************************************************************/
 
+#define LOG_TAG "bt_btif_gatt"
+
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+
 #include "btu.h"
 #include "bt_target.h"
 
-#define LOG_TAG "bt_btif_gatt"
 #if (BLE_INCLUDED == TRUE)
 
-#include "btif_gatt_multi_adv_util.h"
-#include "btif_common.h"
+#include <hardware/bluetooth.h>
 #include <hardware/bt_gatt.h>
+
 #include "bta_gatt_api.h"
+#include "btif_common.h"
+#include "btif_gatt_multi_adv_util.h"
 #include "btif_gatt_util.h"
 
 /*******************************************************************************
@@ -213,7 +217,6 @@ int btif_gattc_obtain_idx_for_datacb(int value, int clnt_inst_index)
     return INVALID_ADV_INST;
 }
 
-
 void btif_gattc_adv_data_packager(int client_if, bool set_scan_rsp,
                 bool include_name, bool include_txpower, int min_interval, int max_interval,
                 int appearance, int manufacturer_len, char* manufacturer_data,
@@ -264,18 +267,18 @@ void btif_gattc_adv_data_cleanup(const btif_adv_data_t* adv)
         GKI_freebuf(adv->p_manufacturer_data);
 }
 
-
 BOOLEAN btif_gattc_copy_datacb(int cbindex, const btif_adv_data_t *p_adv_data,
                                BOOLEAN bInstData) {
     btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
     if (NULL == p_multi_adv_data_cb || cbindex < 0)
        return false;
 
-    BTIF_TRACE_DEBUG("%s", __FUNCTION__);
-    memset(&p_multi_adv_data_cb->inst_cb[cbindex].data, 0, sizeof(tBTA_BLE_ADV_DATA));
+    BTIF_TRACE_DEBUG("%s", __func__);
+
+    memset(&p_multi_adv_data_cb->inst_cb[cbindex].data, 0,
+           sizeof(p_multi_adv_data_cb->inst_cb[cbindex].data));
     p_multi_adv_data_cb->inst_cb[cbindex].mask = 0;
 
-    p_multi_adv_data_cb->inst_cb[cbindex].is_scan_rsp = p_adv_data->set_scan_rsp ? 1 : 0;
     if (!p_adv_data->set_scan_rsp)
     {
          p_multi_adv_data_cb->inst_cb[cbindex].mask = BTM_BLE_AD_BIT_FLAGS;
@@ -331,63 +334,32 @@ BOOLEAN btif_gattc_copy_datacb(int cbindex, const btif_adv_data_t *p_adv_data,
         p_multi_adv_data_cb->inst_cb[cbindex].data.appearance = p_adv_data->appearance;
     }
 
-    if (p_adv_data->manufacturer_len > 0 && p_adv_data->p_manufacturer_data != NULL)
+    if (p_adv_data->manufacturer_len > 0 &&
+        p_adv_data->p_manufacturer_data != NULL &&
+        p_adv_data->manufacturer_len < MAX_SIZE_MANUFACTURER_DATA)
     {
-         p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu =
-                            GKI_getbuf(sizeof(tBTA_BLE_MANU));
-         if (p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu != NULL)
-         {
-            p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->p_val =
-                            GKI_getbuf(p_adv_data->manufacturer_len);
-            if (p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->p_val != NULL)
-            {
-                 p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_MANU;
-                 p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->len =
-                                p_adv_data->manufacturer_len;
-                 memcpy(p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->p_val,
-                    p_adv_data->p_manufacturer_data, p_adv_data->manufacturer_len);
-            }
-         }
+      p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_MANU;
+      p_multi_adv_data_cb->inst_cb[cbindex].data.manu.len =
+          p_adv_data->manufacturer_len;
+      memcpy(&p_multi_adv_data_cb->inst_cb[cbindex].data.manu.val,
+             p_adv_data->p_manufacturer_data, p_adv_data->manufacturer_len);
     }
 
-    tBTA_BLE_PROP_ELEM *p_elem_service_data = NULL;
-    if (p_adv_data->service_data_len > 0 && p_adv_data->p_service_data != NULL)
+    if (p_adv_data->service_data_len > 0 &&
+        p_adv_data->p_service_data != NULL &&
+        p_adv_data->service_data_len < MAX_SIZE_PROPRIETARY_ELEMENT)
     {
-         BTIF_TRACE_DEBUG("%s - In service_data", __FUNCTION__);
-         p_elem_service_data = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM));
-         if (p_elem_service_data != NULL)
-         {
-             p_elem_service_data->p_val = GKI_getbuf(p_adv_data->service_data_len);
-             if (p_elem_service_data->p_val != NULL)
-             {
-                 p_elem_service_data->adv_type = BTM_BLE_AD_TYPE_SERVICE_DATA;
-                 p_elem_service_data->len = p_adv_data->service_data_len;
-                 memcpy(p_elem_service_data->p_val, p_adv_data->p_service_data,
-                             p_adv_data->service_data_len);
-             } else {
-                     GKI_freebuf(p_elem_service_data);
-                     p_elem_service_data = NULL;
-               }
-         }
-    }
+      BTIF_TRACE_DEBUG("%s - In service_data", __func__);
+      tBTA_BLE_PROPRIETARY *p_prop = &p_multi_adv_data_cb->inst_cb[cbindex].data.proprietary;
+      p_prop->num_elem = 1;
 
-    if (NULL != p_elem_service_data)
-    {
-        p_multi_adv_data_cb->inst_cb[cbindex].data.p_proprietary =
-                                                   GKI_getbuf(sizeof(tBTA_BLE_PROPRIETARY));
-        if (NULL != p_multi_adv_data_cb->inst_cb[cbindex].data.p_proprietary)
-        {
-            tBTA_BLE_PROP_ELEM *p_elem = NULL;
-            tBTA_BLE_PROPRIETARY *p_prop = p_multi_adv_data_cb->inst_cb[cbindex].data.p_proprietary;
-            p_prop->num_elem = 0;
-            p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_PROPRIETARY;
-            p_prop->num_elem = 1;
-            p_prop->p_elem = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM) * p_prop->num_elem);
-            p_elem = p_prop->p_elem;
-            if (NULL != p_elem)
-                memcpy(p_elem++, p_elem_service_data, sizeof(tBTA_BLE_PROP_ELEM));
-            GKI_freebuf(p_elem_service_data);
-        }
+      tBTA_BLE_PROP_ELEM *p_elem = &p_prop->elem[0];
+      p_elem->adv_type = BTM_BLE_AD_TYPE_SERVICE_DATA;
+      p_elem->len = p_adv_data->service_data_len;
+      memcpy(p_elem->val, p_adv_data->p_service_data,
+             p_adv_data->service_data_len);
+
+      p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_PROPRIETARY;
     }
 
     if (p_adv_data->service_uuid_len && p_adv_data->p_service_uuid)
@@ -408,22 +380,17 @@ BOOLEAN btif_gattc_copy_datacb(int cbindex, const btif_adv_data_t *p_adv_data,
              {
                 case (LEN_UUID_16):
                 {
-                  if (NULL == p_multi_adv_data_cb->inst_cb[cbindex].data.p_services)
+                  if (p_multi_adv_data_cb->inst_cb[cbindex].data.services.num_service == 0)
                   {
-                      p_multi_adv_data_cb->inst_cb[cbindex].data.p_services =
-                                                          GKI_getbuf(sizeof(tBTA_BLE_SERVICE));
-                      p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->list_cmpl = FALSE;
-                      p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->num_service = 0;
-                      p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->p_uuid =
-                              GKI_getbuf(p_adv_data->service_uuid_len / LEN_UUID_128 * LEN_UUID_16);
-                      p_uuid_out16 = p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->p_uuid;
+                      p_multi_adv_data_cb->inst_cb[cbindex].data.services.list_cmpl = FALSE;
+                      p_uuid_out16 = p_multi_adv_data_cb->inst_cb[cbindex].data.services.uuid;
                   }
 
-                  if (NULL != p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->p_uuid)
+                  if (p_multi_adv_data_cb->inst_cb[cbindex].data.services.num_service < MAX_16BIT_SERVICES)
                   {
-                     BTIF_TRACE_DEBUG("%s - In 16-UUID_data", __FUNCTION__);
+                     BTIF_TRACE_DEBUG("%s - In 16-UUID_data", __func__);
                      p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_SERVICE;
-                     ++p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->num_service;
+                     ++p_multi_adv_data_cb->inst_cb[cbindex].data.services.num_service;
                      *p_uuid_out16++ = bt_uuid.uu.uuid16;
                   }
                   break;
@@ -431,22 +398,17 @@ BOOLEAN btif_gattc_copy_datacb(int cbindex, const btif_adv_data_t *p_adv_data,
 
                 case (LEN_UUID_32):
                 {
-                   if (NULL == p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b)
+                   if (p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.num_service == 0)
                    {
-                      p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b =
-                                                          GKI_getbuf(sizeof(tBTA_BLE_32SERVICE));
-                      p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b->list_cmpl = FALSE;
-                      p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b->num_service = 0;
-                      p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b->p_uuid =
-                             GKI_getbuf(p_adv_data->service_uuid_len / LEN_UUID_128 * LEN_UUID_32);
-                      p_uuid_out32 = p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b->p_uuid;
+                      p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.list_cmpl = FALSE;
+                      p_uuid_out32 = p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.uuid;
                    }
 
-                   if (NULL != p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b->p_uuid)
+                   if (p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.num_service < MAX_32BIT_SERVICES)
                    {
-                      BTIF_TRACE_DEBUG("%s - In 32-UUID_data", __FUNCTION__);
+                      BTIF_TRACE_DEBUG("%s - In 32-UUID_data", __func__);
                       p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_SERVICE_32;
-                      ++p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b->num_service;
+                      ++p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.num_service;
                       *p_uuid_out32++ = bt_uuid.uu.uuid32;
                    }
                    break;
@@ -455,24 +417,28 @@ BOOLEAN btif_gattc_copy_datacb(int cbindex, const btif_adv_data_t *p_adv_data,
                 case (LEN_UUID_128):
                 {
                    /* Currently, only one 128-bit UUID is supported */
-                   if (NULL == p_multi_adv_data_cb->inst_cb[cbindex].data.p_services_128b)
+                   if (p_multi_adv_data_cb->inst_cb[cbindex].data.services_128b.num_service == 0)
                    {
-                      p_multi_adv_data_cb->inst_cb[cbindex].data.p_services_128b =
-                                                          GKI_getbuf(sizeof(tBTA_BLE_128SERVICE));
-                      if (NULL != p_multi_adv_data_cb->inst_cb[cbindex].data.p_services_128b)
-                      {
-                         BTIF_TRACE_DEBUG("%s - In 128-UUID_data", __FUNCTION__);
-                         p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_SERVICE_128;
-                         memcpy(p_multi_adv_data_cb->inst_cb[cbindex].data.p_services_128b->uuid128,
-                                                         bt_uuid.uu.uuid128, LEN_UUID_128);
-                         BTIF_TRACE_DEBUG("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", bt_uuid.uu.uuid128[0],
-                            bt_uuid.uu.uuid128[1],bt_uuid.uu.uuid128[2], bt_uuid.uu.uuid128[3],
-                            bt_uuid.uu.uuid128[4],bt_uuid.uu.uuid128[5],bt_uuid.uu.uuid128[6],
-                            bt_uuid.uu.uuid128[7],bt_uuid.uu.uuid128[8],bt_uuid.uu.uuid128[9],
-                            bt_uuid.uu.uuid128[10],bt_uuid.uu.uuid128[11],bt_uuid.uu.uuid128[12],
-                            bt_uuid.uu.uuid128[13],bt_uuid.uu.uuid128[14],bt_uuid.uu.uuid128[15]);
-                         p_multi_adv_data_cb->inst_cb[cbindex].data.p_services_128b->list_cmpl = TRUE;
-                      }
+                     BTIF_TRACE_DEBUG("%s - In 128-UUID_data", __FUNCTION__);
+                     p_multi_adv_data_cb->inst_cb[cbindex].mask |=
+                         BTM_BLE_AD_BIT_SERVICE_128;
+                     memcpy(p_multi_adv_data_cb->inst_cb[cbindex]
+                                .data.services_128b.uuid128,
+                            bt_uuid.uu.uuid128, LEN_UUID_128);
+                     BTIF_TRACE_DEBUG(
+                         "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x",
+                         bt_uuid.uu.uuid128[0], bt_uuid.uu.uuid128[1],
+                         bt_uuid.uu.uuid128[2], bt_uuid.uu.uuid128[3],
+                         bt_uuid.uu.uuid128[4], bt_uuid.uu.uuid128[5],
+                         bt_uuid.uu.uuid128[6], bt_uuid.uu.uuid128[7],
+                         bt_uuid.uu.uuid128[8], bt_uuid.uu.uuid128[9],
+                         bt_uuid.uu.uuid128[10], bt_uuid.uu.uuid128[11],
+                         bt_uuid.uu.uuid128[12], bt_uuid.uu.uuid128[13],
+                         bt_uuid.uu.uuid128[14], bt_uuid.uu.uuid128[15]);
+                     ++p_multi_adv_data_cb->inst_cb[cbindex]
+                           .data.services_128b.num_service;
+                     p_multi_adv_data_cb->inst_cb[cbindex]
+                         .data.services_128b.list_cmpl = TRUE;
                    }
                    break;
                 }
@@ -523,7 +489,7 @@ void btif_gattc_cleanup_inst_cb(int inst_id, BOOLEAN stop_timer)
         STD_ADV_INSTID : btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
     if (cbindex < 0) return;
 
-    BTIF_TRACE_DEBUG("Cleaning up multi_inst_cb for inst_id %d, cbindex %d", inst_id, cbindex);
+    BTIF_TRACE_DEBUG("%s: inst_id %d, cbindex %d", __func__, inst_id, cbindex);
     btif_gattc_cleanup_multi_inst_cb(&p_multi_adv_data_cb->inst_cb[cbindex], stop_timer);
 }
 
@@ -541,64 +507,7 @@ void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_multi_inst_cb,
         p_multi_inst_cb->tle_limited_timer.in_use = 0;
     }
 
-    // Manufacturer data cleanup
-    if (p_multi_inst_cb->data.p_manu != NULL)
-    {
-        btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_manu->p_val);
-        btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_manu);
-    }
-
-    // Proprietary data cleanup
-    if (p_multi_inst_cb->data.p_proprietary != NULL)
-    {
-        int i = 0;
-        tBTA_BLE_PROP_ELEM *p_elem = p_multi_inst_cb->data.p_proprietary->p_elem;
-        while (i++ != p_multi_inst_cb->data.p_proprietary->num_elem
-            && p_elem)
-        {
-            btif_gattc_cleanup((void**) &p_elem->p_val);
-            ++p_elem;
-        }
-
-        btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_proprietary->p_elem);
-        btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_proprietary);
-    }
-
-    // Service list cleanup
-    if (p_multi_inst_cb->data.p_services != NULL)
-    {
-        btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_services->p_uuid);
-        btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_services);
-    }
-
-    // Service data cleanup
-    if (p_multi_inst_cb->data.p_service_data != NULL)
-    {
-        btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_data->p_val);
-        btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_data);
-    }
-
-    btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_services_128b);
-
-    if (p_multi_inst_cb->data.p_service_32b != NULL)
-    {
-        btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_32b->p_uuid);
-        btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_32b);
-    }
-
-    if (p_multi_inst_cb->data.p_sol_services != NULL)
-    {
-        btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_services->p_uuid);
-        btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_services);
-    }
-
-    if (p_multi_inst_cb->data.p_sol_service_32b != NULL)
-    {
-        btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_service_32b->p_uuid);
-        btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_service_32b);
-    }
-
-    btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_service_128b);
+    memset(&p_multi_inst_cb->data, 0, sizeof(p_multi_inst_cb->data));
 }
 
 void btif_gattc_cleanup(void** buf)
@@ -633,8 +542,8 @@ void btif_multi_adv_timer_ctrl(int client_if, TIMER_CBACK cb)
                 btu_stop_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer);
 
             memset(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer, 0, sizeof(TIMER_LIST_ENT));
-            p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.param = (UINT32)cb;
-            p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.data = (UINT32)client_if;
+            p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.param = cb;
+            p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.data = INT_TO_PTR(client_if);
             btu_start_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer,
                     BTU_TTYPE_USER_FUNC, p_multi_adv_data_cb->inst_cb[cbindex].timeout_s);
         }
index b071b65..a1650c9 100644 (file)
@@ -16,7 +16,6 @@
  *
  ******************************************************************************/
 
-
 /************************************************************************************
  *
  *  Filename:      btif_gatt_server.c
  *
  ***********************************************************************************/
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_gatt.h>
+#define LOG_TAG "bt_btif_gatt"
+
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <errno.h>
 #include <string.h>
 
-#define LOG_TAG "bt_btif_gatt"
+#include <hardware/bluetooth.h>
+#include <hardware/bt_gatt.h>
 
 #include "btif_common.h"
 #include "btif_util.h"
 
 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
 
-#include "gki.h"
 #include "bta_api.h"
 #include "bta_gatt_api.h"
-#include "btif_dm.h"
-#include "btif_storage.h"
 #include "btif_config.h"
-
+#include "btif_dm.h"
 #include "btif_gatt.h"
 #include "btif_gatt_util.h"
+#include "btif_storage.h"
+#include "gki.h"
 #include "osi/include/log.h"
 
 /************************************************************************************
 
 #define CHECK_BTGATT_INIT() if (bt_gatt_callbacks == NULL)\
     {\
-        LOG_WARN("%s: BTGATT not initialized", __FUNCTION__);\
+        LOG_WARN(LOG_TAG, "%s: BTGATT not initialized", __FUNCTION__);\
         return BT_STATUS_NOT_READY;\
     } else {\
-        LOG_VERBOSE("%s", __FUNCTION__);\
+        LOG_VERBOSE(LOG_TAG, "%s", __FUNCTION__);\
     }
 
-
 typedef enum {
     BTIF_GATTS_REGISTER_APP = 2000,
     BTIF_GATTS_UNREGISTER_APP,
@@ -107,14 +105,12 @@ typedef struct
 
 } __attribute__((packed)) btif_gatts_cb_t;
 
-
 /************************************************************************************
 **  Static variables
 ************************************************************************************/
 
 extern const btgatt_callbacks_t *bt_gatt_callbacks;
 
-
 /************************************************************************************
 **  Static functions
 ************************************************************************************/
@@ -169,7 +165,7 @@ static void btapp_gatts_free_req_data(UINT16 event, tBTA_GATTS *p_data)
 
 static void btapp_gatts_handle_cback(uint16_t event, char* p_param)
 {
-    LOG_VERBOSE("%s: Event %d", __FUNCTION__, event);
+    LOG_VERBOSE(LOG_TAG, "%s: Event %d", __FUNCTION__, event);
 
     tBTA_GATTS *p_data = (tBTA_GATTS*)p_param;
     switch (event)
@@ -344,11 +340,11 @@ static void btapp_gatts_handle_cback(uint16_t event, char* p_param)
         case BTA_GATTS_OPEN_EVT:
         case BTA_GATTS_CANCEL_OPEN_EVT:
         case BTA_GATTS_CLOSE_EVT:
-            LOG_DEBUG("%s: Empty event (%d)!", __FUNCTION__, event);
+            LOG_DEBUG(LOG_TAG, "%s: Empty event (%d)!", __FUNCTION__, event);
             break;
 
         default:
-            LOG_ERROR("%s: Unhandled event (%d)!", __FUNCTION__, event);
+            LOG_ERROR(LOG_TAG, "%s: Unhandled event (%d)!", __FUNCTION__, event);
             break;
     }
 
@@ -368,7 +364,7 @@ static void btgatts_handle_event(uint16_t event, char* p_param)
     btif_gatts_cb_t* p_cb = (btif_gatts_cb_t*)p_param;
     if (!p_cb) return;
 
-    LOG_VERBOSE("%s: Event %d", __FUNCTION__, event);
+    LOG_VERBOSE(LOG_TAG, "%s: Event %d", __FUNCTION__, event);
 
     switch (event)
     {
@@ -508,7 +504,7 @@ static void btgatts_handle_event(uint16_t event, char* p_param)
         }
 
         default:
-            LOG_ERROR("%s: Unknown event (%d)!", __FUNCTION__, event);
+            LOG_ERROR(LOG_TAG, "%s: Unknown event (%d)!", __FUNCTION__, event);
             break;
     }
 }
index 4ccf5b0..349674e 100644 (file)
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_btif_gatt"
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_gatt.h>
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <errno.h>
 #include <string.h>
 
-#define LOG_TAG "bt_btif_gatt"
+#include <hardware/bluetooth.h>
+#include <hardware/bt_gatt.h>
 
 #include "btif_common.h"
 #include "btif_util.h"
 
 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
 
-#include "bta_api.h"
 #include "bta_gatt_api.h"
-#include "btif_storage.h"
 #include "bte_appl.h"
-
+#include "btif_dm.h"
 #include "btif_gatt.h"
 #include "btif_gatt_util.h"
-#include "btif_dm.h"
-
+#include "btif_storage.h"
 #include "gatt_api.h"
 #include "osi/include/log.h"
 
@@ -108,14 +105,14 @@ static void btif_test_connect_cback(tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_i
     UNUSED(reason);
     UNUSED (transport);
 
-    LOG_DEBUG("%s: conn_id=%d, connected=%d", __FUNCTION__, conn_id, connected);
+    LOG_DEBUG(LOG_TAG, "%s: conn_id=%d, connected=%d", __FUNCTION__, conn_id, connected);
     test_cb.conn_id = connected ? conn_id : 0;
 }
 
 static void btif_test_command_complete_cback(UINT16 conn_id, tGATTC_OPTYPE op,
                                 tGATT_STATUS status, tGATT_CL_COMPLETE *p_data)
 {
-    LOG_DEBUG ("%s: op_code=0x%02x, conn_id=0x%x. status=0x%x",
+    LOG_DEBUG(LOG_TAG, "%s: op_code=0x%02x, conn_id=0x%x. status=0x%x",
             __FUNCTION__, op, conn_id, status);
 
     switch (op)
@@ -132,62 +129,61 @@ static void btif_test_command_complete_cback(UINT16 conn_id, tGATTC_OPTYPE op,
             break;
 
         default:
-            LOG_DEBUG ("%s: Unknown op_code (0x%02x)", __FUNCTION__, op);
+            LOG_DEBUG(LOG_TAG, "%s: Unknown op_code (0x%02x)", __FUNCTION__, op);
             break;
     }
 }
 
-
 static void btif_test_discovery_result_cback(UINT16 conn_id, tGATT_DISC_TYPE disc_type,
                                            tGATT_DISC_RES *p_data)
 {
     char    str_buf[50];
     UNUSED(conn_id);
 
-    LOG_DEBUG("------ GATT Discovery result %-22s -------", disc_name[disc_type]);
-    LOG_DEBUG("      Attribute handle: 0x%04x (%d)", p_data->handle, p_data->handle);
+    LOG_DEBUG(LOG_TAG, "------ GATT Discovery result %-22s -------", disc_name[disc_type]);
+    LOG_DEBUG(LOG_TAG, "      Attribute handle: 0x%04x (%d)", p_data->handle, p_data->handle);
 
     if (disc_type != GATT_DISC_CHAR_DSCPT) {
-        LOG_DEBUG("        Attribute type: %s", format_uuid(p_data->type, str_buf));
+        LOG_DEBUG(LOG_TAG, "        Attribute type: %s", format_uuid(p_data->type, str_buf));
     }
 
     switch (disc_type)
     {
         case GATT_DISC_SRVC_ALL:
-            LOG_DEBUG("          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
+            LOG_DEBUG(LOG_TAG, "          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
                   p_data->handle, p_data->value.group_value.e_handle,
                   p_data->handle, p_data->value.group_value.e_handle);
-            LOG_DEBUG("          Service UUID: %s",
+            LOG_DEBUG(LOG_TAG, "          Service UUID: %s",
                     format_uuid(p_data->value.group_value.service_type, str_buf));
             break;
 
         case GATT_DISC_SRVC_BY_UUID:
-            LOG_DEBUG("          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
+            LOG_DEBUG(LOG_TAG, "          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
                   p_data->handle, p_data->value.handle,
                   p_data->handle, p_data->value.handle);
             break;
 
         case GATT_DISC_INC_SRVC:
-            LOG_DEBUG("          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
+            LOG_DEBUG(LOG_TAG, "          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
                   p_data->value.incl_service.s_handle, p_data->value.incl_service.e_handle,
                   p_data->value.incl_service.s_handle, p_data->value.incl_service.e_handle);
-            LOG_DEBUG("          Service UUID: %s",
+            LOG_DEBUG(LOG_TAG, "          Service UUID: %s",
                   format_uuid(p_data->value.incl_service.service_type, str_buf));
             break;
 
         case GATT_DISC_CHAR:
-            LOG_DEBUG("            Properties: 0x%02x",
+            LOG_DEBUG(LOG_TAG, "            Properties: 0x%02x",
                   p_data->value.dclr_value.char_prop);
-            LOG_DEBUG("   Characteristic UUID: %s",
+            LOG_DEBUG(LOG_TAG, "   Characteristic UUID: %s",
                   format_uuid(p_data->value.dclr_value.char_uuid, str_buf));
             break;
 
         case GATT_DISC_CHAR_DSCPT:
-            LOG_DEBUG("       Descriptor UUID: %s", format_uuid(p_data->type, str_buf));
+            LOG_DEBUG(LOG_TAG, "       Descriptor UUID: %s", format_uuid(p_data->type, str_buf));
             break;
     }
 
-    LOG_DEBUG("-----------------------------------------------------------");
+    LOG_DEBUG(LOG_TAG, "-----------------------------------------------------------");
 }
 
 static void btif_test_discovery_complete_cback(UINT16 conn_id,
@@ -196,7 +192,7 @@ static void btif_test_discovery_complete_cback(UINT16 conn_id,
 {
     UNUSED(conn_id);
     UNUSED(disc_type);
-    LOG_DEBUG("%s: status=%d", __FUNCTION__, status);
+    LOG_DEBUG(LOG_TAG, "%s: status=%d", __FUNCTION__, status);
 }
 
 static tGATT_CBACK btif_test_callbacks =
@@ -219,7 +215,7 @@ bt_status_t btif_gattc_test_command_impl(uint16_t command, btgatt_test_params_t*
     switch(command) {
         case 0x01: /* Enable */
         {
-            LOG_DEBUG("%s: ENABLE - enable=%d", __FUNCTION__, params->u1);
+            LOG_DEBUG(LOG_TAG, "%s: ENABLE - enable=%d", __FUNCTION__, params->u1);
             if (params->u1)
             {
                 tBT_UUID app_uuid = {LEN_UUID_128,{0xAE}};
@@ -234,7 +230,7 @@ bt_status_t btif_gattc_test_command_impl(uint16_t command, btgatt_test_params_t*
 
         case 0x02: /* Connect */
         {
-            LOG_DEBUG("%s: CONNECT - device=%02x:%02x:%02x:%02x:%02x:%02x (dev_type=%d, addr_type=%d)",
+            LOG_DEBUG(LOG_TAG, "%s: CONNECT - device=%02x:%02x:%02x:%02x:%02x:%02x (dev_type=%d, addr_type=%d)",
                 __FUNCTION__,
                 params->bda1->address[0], params->bda1->address[1],
                 params->bda1->address[2], params->bda1->address[3],
@@ -246,14 +242,14 @@ bt_status_t btif_gattc_test_command_impl(uint16_t command, btgatt_test_params_t*
 
             if ( !GATT_Connect(test_cb.gatt_if, params->bda1->address, TRUE, BT_TRANSPORT_LE) )
             {
-                LOG_ERROR("%s: GATT_Connect failed!", __FUNCTION__);
+                LOG_ERROR(LOG_TAG, "%s: GATT_Connect failed!", __FUNCTION__);
             }
             break;
         }
 
         case 0x03: /* Disconnect */
         {
-            LOG_DEBUG("%s: DISCONNECT - conn_id=%d", __FUNCTION__, test_cb.conn_id);
+            LOG_DEBUG(LOG_TAG, "%s: DISCONNECT - conn_id=%d", __FUNCTION__, test_cb.conn_id);
             GATT_Disconnect(test_cb.conn_id);
             break;
         }
@@ -266,7 +262,7 @@ bt_status_t btif_gattc_test_command_impl(uint16_t command, btgatt_test_params_t*
 
             if (params->u1 >= GATT_DISC_MAX)
             {
-                LOG_ERROR("%s: DISCOVER - Invalid type (%d)!", __FUNCTION__, params->u1);
+                LOG_ERROR(LOG_TAG, "%s: DISCOVER - Invalid type (%d)!", __FUNCTION__, params->u1);
                 return 0;
             }
 
@@ -274,7 +270,7 @@ bt_status_t btif_gattc_test_command_impl(uint16_t command, btgatt_test_params_t*
             param.e_handle = params->u3;
             btif_to_bta_uuid(&param.service, params->uuid1);
 
-            LOG_DEBUG("%s: DISCOVER (%s), conn_id=%d, uuid=%s, handles=0x%04x-0x%04x",
+            LOG_DEBUG(LOG_TAG, "%s: DISCOVER (%s), conn_id=%d, uuid=%s, handles=0x%04x-0x%04x",
                   __FUNCTION__, disc_name[params->u1], test_cb.conn_id,
                   format_uuid(param.service, buf), params->u2, params->u3);
             GATTC_Discover(test_cb.conn_id, params->u1, &param);
@@ -282,7 +278,7 @@ bt_status_t btif_gattc_test_command_impl(uint16_t command, btgatt_test_params_t*
         }
 
         case 0xF0: /* Pairing configuration */
-            LOG_DEBUG("%s: Setting pairing config auth=%d, iocaps=%d, keys=%d/%d/%d",
+            LOG_DEBUG(LOG_TAG, "%s: Setting pairing config auth=%d, iocaps=%d, keys=%d/%d/%d",
                   __FUNCTION__, params->u1, params->u2, params->u3, params->u4,
                   params->u5);
 
@@ -294,7 +290,7 @@ bt_status_t btif_gattc_test_command_impl(uint16_t command, btgatt_test_params_t*
             break;
 
         default:
-            LOG_ERROR("%s: UNKNOWN TEST COMMAND 0x%02x", __FUNCTION__, command);
+            LOG_ERROR(LOG_TAG, "%s: UNKNOWN TEST COMMAND 0x%02x", __FUNCTION__, command);
             break;
     }
     return 0;
index 5d5e4bf..16d843f 100644 (file)
  *
  ******************************************************************************/
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_gatt.h>
+#define LOG_TAG "bt_btif_gatt"
+
+#include "btif_gatt_util.h"
+
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <errno.h>
 #include <string.h>
 
-#define LOG_TAG "bt_btif_gatt"
+#include <hardware/bluetooth.h>
+#include <hardware/bt_gatt.h>
 
-#include "btcore/include/bdaddr.h"
+#include "bdaddr.h"
 #include "bta_api.h"
 #include "bta_gatt_api.h"
 #include "bta_jv_api.h"
-#include "btif_storage.h"
-#include "btif_config.h"
-
 #include "btif_common.h"
+#include "btif_config.h"
 #include "btif_dm.h"
-#include "btif_util.h"
 #include "btif_gatt.h"
-#include "btif_gatt_util.h"
+#include "btif_storage.h"
+#include "btif_util.h"
 #include "gki.h"
 
 #if BTA_GATT_INCLUDED == TRUE
@@ -103,7 +104,7 @@ void btif_to_bta_uuid(tBT_UUID *p_dest, bt_uuid_t *p_src)
             break;
 
         default:
-            LOG_ERROR("%s: Unknown UUID length %d!", __FUNCTION__, p_dest->len);
+            LOG_ERROR(LOG_TAG, "%s: Unknown UUID length %d!", __FUNCTION__, p_dest->len);
             break;
     }
 }
@@ -193,12 +194,11 @@ void bta_to_btif_uuid(bt_uuid_t *p_dest, tBT_UUID *p_src)
             break;
 
         default:
-            LOG_ERROR("%s: Unknown UUID length %d!", __FUNCTION__, p_src->len);
+            LOG_ERROR(LOG_TAG, "%s: Unknown UUID length %d!", __FUNCTION__, p_src->len);
             break;
     }
 }
 
-
 void bta_to_btif_gatt_id(btgatt_gatt_id_t *p_dest, tBTA_GATT_ID *p_src)
 {
     p_dest->inst_id = p_src->inst_id;
@@ -212,7 +212,6 @@ void bta_to_btif_srvc_id(btgatt_srvc_id_t *p_dest, tBTA_GATT_SRVC_ID *p_src)
     p_dest->is_primary = p_src->is_primary;
 }
 
-
 /*******************************************************************************
  * Utility functions
  *******************************************************************************/
@@ -258,7 +257,7 @@ uint16_t set_read_value(btgatt_read_params_t *p_dest, tBTA_GATTC_READ *p_src)
         default:
             if (( p_src->status == BTA_GATT_OK ) &&(p_src->p_value != NULL))
             {
-                LOG_INFO("%s unformat.len = %d ", __FUNCTION__, p_src->p_value->unformat.len);
+                LOG_INFO(LOG_TAG, "%s unformat.len = %d ", __FUNCTION__, p_src->p_value->unformat.len);
                 p_dest->value.len = p_src->p_value->unformat.len;
                 if ( p_src->p_value->unformat.len > 0  && p_src->p_value->unformat.p_value != NULL )
                 {
index d5470d7..74910a3 100644 (file)
  *
  ***********************************************************************************/
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_hf.h>
+#define LOG_TAG "bt_btif_hf"
+
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 
-#define LOG_TAG "bt_btif_hf"
-#include "btif_common.h"
-#include "btif_util.h"
-#include "btif_profile_queue.h"
+#include <hardware/bluetooth.h>
+#include <hardware/bt_hf.h>
 
-#include "btcore/include/bdaddr.h"
 #include "bta_ag_api.h"
+#include "btcore/include/bdaddr.h"
+#include "btif_common.h"
+#include "btif_profile_queue.h"
+#include "btif_util.h"
 
 /************************************************************************************
 **  Constants & Macros
@@ -163,7 +165,6 @@ typedef struct _btif_hf_cb
 
 static btif_hf_cb_t btif_hf_cb[BTIF_HF_NUM_CB];
 
-
 /************************************************************************************
 **  Static functions
 ************************************************************************************/
@@ -375,7 +376,6 @@ static bt_status_t btif_hf_check_if_slc_connected()
 **
 *****************************************************************************/
 
-
 /*******************************************************************************
 **
 ** Function         btif_hf_upstreams_evt
@@ -661,7 +661,6 @@ static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG *p_data)
     ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btif_in_hf_generic_evt
@@ -698,7 +697,6 @@ static void btif_in_hf_generic_evt(UINT16 event, char *p_param)
     }
 }
 
-
 /*******************************************************************************
 **
 ** Function         btif_hf_init
@@ -1174,7 +1172,6 @@ static bt_status_t at_response(bthf_at_response_t response_code,
         return BT_STATUS_SUCCESS;
     }
 
-
     return BT_STATUS_FAIL;
 }
 
index ee78a8a..0419013 100644 (file)
  *
  ***********************************************************************************/
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_hf_client.h>
+#define LOG_TAG "bt_btif_hfc"
+
 #include <stdlib.h>
 #include <string.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_hf_client.h>
+
+/**
+ * TODO(armansito): On OSs other than Android, the sys/properties.h system
+ * does not exist. Remove this conditional include once we have a generic way
+ * to obtain system properties.
+ */
+#if !defined(OS_GENERIC)
 #include <cutils/properties.h>
+#endif  /* !defined(OS_GENERIC) */
 
-#define LOG_TAG "bt_btif_hfc"
-#include "btif_common.h"
-#include "btif_util.h"
-#include "btif_profile_queue.h"
 #include "bt_utils.h"
-#include "btcore/include/bdaddr.h"
 #include "bta_hf_client_api.h"
+#include "btcore/include/bdaddr.h"
+#include "btif_common.h"
+#include "btif_profile_queue.h"
+#include "btif_util.h"
 
 /************************************************************************************
 **  Constants & Macros
 **  Static variables
 ************************************************************************************/
 static bthf_client_callbacks_t *bt_hf_client_callbacks = NULL;
-char   btif_hf_client_version[PROPERTY_VALUE_MAX];
 static UINT32 btif_hf_client_features = 0;
 
+/**
+ * TODO(armansito): On OSs other than Android, the sys/properties.h system
+ * does not exist. Since that is how the HFP version is currently obtained, on
+ * systems other than Android, hardcode 1.5 as the profile version for now,
+ * until there is a generic way to obtain these configuration properties.
+ */
+#if defined(OS_GENERIC)
+const char btif_hf_client_version[] = "1.5";
+#else  /* !defined(OS_GENERIC) */
+char btif_hf_client_version[PROPERTY_VALUE_MAX];
+#endif  /* defined(OS_GENERIC) */
 
 #define CHECK_BTHF_CLIENT_INIT() if (bt_hf_client_callbacks == NULL)\
     {\
@@ -115,7 +135,6 @@ typedef struct
 
 static btif_hf_client_cb_t btif_hf_client_cb;
 
-
 /************************************************************************************
 **  Static functions
 ************************************************************************************/
@@ -937,7 +956,14 @@ bt_status_t btif_hf_client_execute_service(BOOLEAN b_enable)
 {
     BTIF_TRACE_EVENT("%s enable:%d", __FUNCTION__, b_enable);
 
+/**
+ * TODO(armansito): On OSs other than Android, the sys/properties.h system
+ * does not exist. Since that is how the HFP version is currently obtained, on
+ * systems other than Android we're hardcoding the version to 1.5 above.
+ */
+#if !defined(OS_GENERIC)
     property_get("ro.bluetooth.hfp.ver", btif_hf_client_version, "1.5");
+#endif  /* !defined(OS_GENERIC) */
 
      if (b_enable)
      {
index 3b9220a..f668143 100644 (file)
  *
  *
  ***********************************************************************************/
-#include <hardware/bluetooth.h>
-#include <hardware/bt_hh.h>
+
+#define LOG_TAG "bt_btif_hh"
+
+#include "btif_hh.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
-
-#define LOG_TAG "bt_btif_hh"
+#include <unistd.h>
 
 #include "bta_api.h"
-#include "bta_hh_api.h"
-#include "btif_storage.h"
-
 #include "btif_common.h"
+#include "btif_storage.h"
 #include "btif_util.h"
-#include "btif_hh.h"
 #include "gki.h"
 #include "l2c_api.h"
 #include "osi/include/log.h"
@@ -74,7 +73,6 @@ static int btif_hh_keylockstates=0; //The current key state of each key
 
 #define BTIF_TIMEOUT_VUP_SECS   3
 
-
 #ifndef BTUI_HH_SECURITY
 #define BTUI_HH_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
 #endif
@@ -91,14 +89,11 @@ typedef enum
     BTIF_HH_VUP_REQ_EVT
 } btif_hh_req_evt_t;
 
-
 /************************************************************************************
 **  Constants & Macros
 ************************************************************************************/
 #define BTIF_HH_SERVICES    (BTA_HID_SERVICE_MASK)
 
-
-
 /************************************************************************************
 **  Local type definitions
 ************************************************************************************/
@@ -127,7 +122,6 @@ static tHID_KB_LIST hid_kb_numlock_on_list[] =
     "Logitech MX5500 Keyboard"}
 };
 
-
 #define CHECK_BTHH_INIT() if (bt_hh_callbacks == NULL)\
     {\
         BTIF_TRACE_WARNING("BTHH: %s: BTHH not initialized", __FUNCTION__);\
@@ -138,8 +132,6 @@ static tHID_KB_LIST hid_kb_numlock_on_list[] =
         BTIF_TRACE_EVENT("BTHH: %s", __FUNCTION__);\
     }
 
-
-
 /************************************************************************************
 **  Static functions
 ************************************************************************************/
@@ -168,7 +160,6 @@ static void sync_lockstate_on_connect(btif_hh_device_t *p_dev);
 //static void hh_update_keyboard_lockstates(btif_hh_device_t *p_dev);
 void btif_hh_tmr_hdlr(TIMER_LIST_ENT *tle);
 
-
 /************************************************************************************
 **  Functions
 ************************************************************************************/
@@ -433,7 +424,7 @@ void btif_hh_start_vup_timer(bt_bdaddr_t *bd_addr)
     {
         BTIF_TRACE_DEBUG("Start VUP timer ");
         memset(&p_dev->vup_timer, 0, sizeof(TIMER_LIST_ENT));
-        p_dev->vup_timer.param = (UINT32)btif_hh_tmr_hdlr;
+        p_dev->vup_timer.param = btif_hh_tmr_hdlr;
         btu_start_timer(&p_dev->vup_timer, BTU_TTYPE_USER_FUNC,
                         BTIF_TIMEOUT_VUP_SECS);
     }
@@ -501,7 +492,7 @@ void btif_hh_remove_device(bt_bdaddr_t bd_addr)
     btif_hh_device_t       *p_dev;
     btif_hh_added_device_t *p_added_dev;
 
-    LOG_INFO("%s: bda = %02x:%02x:%02x:%02x:%02x:%02x", __FUNCTION__,
+    LOG_INFO(LOG_TAG, "%s: bda = %02x:%02x:%02x:%02x:%02x:%02x", __FUNCTION__,
          bd_addr.address[0], bd_addr.address[1], bd_addr.address[2], bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]);
 
     for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
@@ -543,7 +534,6 @@ void btif_hh_remove_device(bt_bdaddr_t bd_addr)
     }
 }
 
-
 BOOLEAN btif_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO* dest , tBTA_HH_DEV_DSCP_INFO* src)
 {
     dest->descriptor.dl_len = 0;
@@ -567,7 +557,6 @@ BOOLEAN btif_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO* dest , tBTA_HH_DEV_DSCP_INF
     return TRUE;
 }
 
-
 /*******************************************************************************
 **
 ** Function         btif_hh_virtual_unplug
@@ -715,7 +704,6 @@ void btif_hh_setreport(btif_hh_device_t *p_dev, bthh_report_type_t r_type, UINT1
 **
 *****************************************************************************/
 
-
 /*******************************************************************************
 **
 ** Function         btif_hh_upstreams_evt
@@ -924,7 +912,7 @@ static void btif_hh_upstreams_evt(UINT16 event, char* p_param)
                 return;
             }
             if (p_dev->fd < 0) {
-                LOG_ERROR("BTA_HH_GET_DSCP_EVT: Error, failed to find the uhid driver...");
+                LOG_ERROR(LOG_TAG, "BTA_HH_GET_DSCP_EVT: Error, failed to find the uhid driver...");
                 return;
             }
             {
@@ -1031,7 +1019,6 @@ static void btif_hh_upstreams_evt(UINT16 event, char* p_param)
                      p_data->dev_info.bda[3], p_data->dev_info.bda[4], p_data->dev_info.bda[5]);
                 break;
 
-
         case BTA_HH_VC_UNPLUG_EVT:
                 BTIF_TRACE_DEBUG("BTA_HH_VC_UNPLUG_EVT: status = %d, handle = %d",
                      p_data->dev_status.status, p_data->dev_status.handle);
@@ -1066,11 +1053,9 @@ static void btif_hh_upstreams_evt(UINT16 event, char* p_param)
                 break;
 
         case BTA_HH_API_ERR_EVT  :
-                LOG_INFO("BTA_HH API_ERR");
+                LOG_INFO(LOG_TAG, "BTA_HH API_ERR");
                 break;
 
-
-
             default:
                 BTIF_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event);
                 break;
@@ -1320,7 +1305,6 @@ static bt_status_t virtual_unplug (bt_bdaddr_t *bd_addr)
     return BT_STATUS_SUCCESS;
 }
 
-
 /*******************************************************************************
 **
 ** Function         set_info
@@ -1359,7 +1343,7 @@ static bt_status_t set_info (bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info )
     dscp_info.descriptor.dsc_list = (UINT8 *) GKI_getbuf(dscp_info.descriptor.dl_len);
     if (dscp_info.descriptor.dsc_list == NULL)
     {
-        LOG_ERROR("%s: Failed to allocate DSCP for CB", __FUNCTION__);
+        LOG_ERROR(LOG_TAG, "%s: Failed to allocate DSCP for CB", __FUNCTION__);
         return BT_STATUS_FAIL;
     }
     memcpy(dscp_info.descriptor.dsc_list, &(hid_info.dsc_list), hid_info.dl_len);
@@ -1450,7 +1434,6 @@ static bt_status_t set_protocol (bt_bdaddr_t *bd_addr, bthh_protocol_mode_t prot
         BTA_HhSetProtoMode(p_dev->dev_handle, protocolMode);
     }
 
-
     return BT_STATUS_SUCCESS;
 }
 
@@ -1480,7 +1463,6 @@ static bt_status_t get_report (bt_bdaddr_t *bd_addr, bthh_report_type_t reportTy
         return BT_STATUS_FAIL;
     }
 
-
     p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
     if (p_dev == NULL) {
         BTIF_TRACE_ERROR("%s: Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.",
@@ -1520,7 +1502,6 @@ static bt_status_t set_report (bt_bdaddr_t *bd_addr, bthh_report_type_t reportTy
     BTIF_TRACE_DEBUG("addr = %02X:%02X:%02X:%02X:%02X:%02X",
          (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
 
-
     if (btif_hh_cb.status == BTIF_HH_DISABLED) {
         BTIF_TRACE_ERROR("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status);
         return BT_STATUS_FAIL;
@@ -1553,7 +1534,7 @@ static bt_status_t set_report (bt_bdaddr_t *bd_addr, bthh_report_type_t reportTy
         memset(hexbuf, 0, len);
         //TODO
         hex_bytes_filled = ascii_2_hex(report, len, hexbuf);
-        LOG_INFO("Hex bytes filled, hex value: %d", hex_bytes_filled);
+        LOG_INFO(LOG_TAG, "Hex bytes filled, hex value: %d", hex_bytes_filled);
         if (hex_bytes_filled) {
             BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf);
             if (p_buf == NULL) {
@@ -1638,7 +1619,6 @@ static bt_status_t send_data (bt_bdaddr_t *bd_addr, char* data)
     }
 }
 
-
 /*******************************************************************************
 **
 ** Function         cleanup
index 9d0c0d7..5fb669c 100644 (file)
  ***********************************************************************************/
 #define LOG_TAG "bt_btif_hl"
 
+#include "btif_hl.h"
+
 #include <assert.h>
 #include <ctype.h>
-#include <cutils/sockets.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <hardware/bluetooth.h>
-#include <hardware/bt_hl.h>
 #include <pthread.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/poll.h>
+#include <sys/prctl.h>
 #include <sys/select.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/un.h>
 #include <time.h>
 #include <unistd.h>
-#include <pthread.h>
-#include <signal.h>
-#include <ctype.h>
-#include <sys/select.h>
-#include <sys/poll.h>
-#include <sys/prctl.h>
-#include <cutils/sockets.h>
-#include <cutils/log.h>
 
-#include <hardware/bluetooth.h>
 #include <hardware/bt_hl.h>
 
-#include "btif_common.h"
-#include "btif_util.h"
-#include "gki.h"
 #include "bta_api.h"
-#include "bta_hl_api.h"
 #include "btif_common.h"
-#include "btif_hl.h"
 #include "btif_storage.h"
 #include "btif_util.h"
 #include "btu.h"
-#include "gki.h"
-#include "osi/include/list.h"
 #include "mca_api.h"
+#include "osi/include/list.h"
 #include "osi/include/log.h"
 
 #define MAX_DATATYPE_SUPPORTED 8
@@ -128,7 +113,6 @@ static void btif_hl_proc_cb_evt(UINT16 event, char* p_param);
         ASSERTC(0, "Callback is NULL", 0);  \
     }
 
-
 #define BTIF_HL_CALL_CBACK(P_CB, P_CBACK, ...)\
      if((p_btif_hl_cb->state != BTIF_HL_STATE_DISABLING) &&\
          (p_btif_hl_cb->state != BTIF_HL_STATE_DISABLED))  \
@@ -141,7 +125,6 @@ static void btif_hl_proc_cb_evt(UINT16 event, char* p_param);
         }                                                  \
     }
 
-
 #define CHECK_BTHL_INIT() if (bt_hl_callbacks == NULL)\
     {\
         BTIF_TRACE_WARNING("BTHL: %s: BTHL not initialized", __FUNCTION__);\
@@ -152,7 +135,6 @@ static void btif_hl_proc_cb_evt(UINT16 event, char* p_param);
         BTIF_TRACE_EVENT("BTHL: %s", __FUNCTION__);\
     }
 
-
 static const btif_hl_data_type_cfg_t data_type_table[] = {
     /* Data Specilization                   Ntx     Nrx (from Bluetooth SIG's HDP whitepaper)*/
     {BTIF_HL_DATA_TYPE_PULSE_OXIMETER,      9216,   256},
@@ -358,7 +340,7 @@ void btif_hl_start_cch_timer(UINT8 app_idx, UINT8 mcl_idx)
     {
         BTIF_TRACE_DEBUG("Start CCH timer ");
         memset(&p_mcb->cch_timer, 0, sizeof(TIMER_LIST_ENT));
-        p_mcb->cch_timer.param = (UINT32)btif_hl_tmr_hdlr;
+        p_mcb->cch_timer.param = btif_hl_tmr_hdlr;
         btu_start_timer(&p_mcb->cch_timer, BTU_TTYPE_USER_FUNC,
                         BTIF_TIMEOUT_CCH_NO_DCH_SECS);
     }
@@ -512,7 +494,6 @@ static void btif_hl_clean_pcb(btif_hl_pending_chan_cb_t *p_pcb)
     memset(p_pcb, 0 , sizeof(btif_hl_pending_chan_cb_t));
 }
 
-
 /*******************************************************************************
 **
 ** Function      btif_hl_clean_mdl_cb
@@ -530,7 +511,6 @@ static void btif_hl_clean_mdl_cb(btif_hl_mdl_cb_t *p_dcb)
     memset(p_dcb, 0 , sizeof(btif_hl_mdl_cb_t));
 }
 
-
 /*******************************************************************************
 **
 ** Function      btif_hl_reset_mcb
@@ -548,7 +528,6 @@ static void btif_hl_clean_mcl_cb(UINT8 app_idx, UINT8 mcl_idx)
     memset(p_mcb, 0, sizeof(btif_hl_mcl_cb_t));
 }
 
-
 /*******************************************************************************
 **
 ** Function      btif_hl_find_sdp_idx_using_mdep_filter
@@ -669,7 +648,6 @@ BOOLEAN btif_hl_is_reconnect_possible(UINT8 app_idx, UINT8 mcl_idx,  int mdep_cf
     tBTA_HL_MDEP_ID      peer_mdep_id = p_dch_open_api->peer_mdep_id;
     UINT8                mdl_idx;
 
-
     BTIF_TRACE_DEBUG("%s app_idx=%d mcl_idx=%d mdep_cfg_idx=%d",
                       __FUNCTION__, app_idx, mcl_idx, mdep_cfg_idx  );
     switch (local_cfg)
@@ -998,7 +976,6 @@ BOOLEAN btif_hl_cch_open(UINT8 app_id, BD_ADDR bd_addr, UINT16 ctrl_psm,
     return status;
 }
 
-
 /*******************************************************************************
 **
 ** Function      btif_hl_find_mdl_idx_using_handle
@@ -1123,7 +1100,6 @@ BOOLEAN btif_hl_find_channel_id_using_mdl_id(UINT8 app_idx, tBTA_HL_MDL_ID mdl_i
     return found;
 }
 
-
 /*******************************************************************************
 **
 ** Function      btif_hl_find_mdl_idx_using_handle
@@ -1169,7 +1145,6 @@ BOOLEAN btif_hl_find_mdl_idx_using_handle(tBTA_HL_MDL_HANDLE mdl_handle,
         }
     }
 
-
     BTIF_TRACE_EVENT("%s found=%d app_idx=%d mcl_idx=%d mdl_idx=%d  ",
                       __FUNCTION__,found,i,j,k );
     return found;
@@ -1194,7 +1169,6 @@ static BOOLEAN btif_hl_find_peer_mdep_id(UINT8 app_id, BD_ADDR bd_addr,
     BOOLEAN             found = FALSE;
     tBTA_HL_MDEP_ROLE   peer_mdep_role;
 
-
     BTIF_TRACE_DEBUG("%s app_id=%d local_mdep_role=%d, data_type=%d",
                       __FUNCTION__, app_id, local_mdep_role, data_type);
 
@@ -1203,7 +1177,6 @@ static BOOLEAN btif_hl_find_peer_mdep_id(UINT8 app_id, BD_ADDR bd_addr,
                       bd_addr[2],  bd_addr[3],
                       bd_addr[4],  bd_addr[5]);
 
-
     BTIF_TRACE_DEBUG("local_mdep_role=%d", local_mdep_role);
     BTIF_TRACE_DEBUG("data_type=%d", data_type);
 
@@ -1214,10 +1187,9 @@ static BOOLEAN btif_hl_find_peer_mdep_id(UINT8 app_id, BD_ADDR bd_addr,
 
     if (btif_hl_find_app_idx(app_id, &app_idx) )
     {
-        BTIF_HL_GET_APP_CB_PTR(app_idx);
         if (btif_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx))
         {
-            p_mcb  =BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+            p_mcb BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
 
             BTIF_TRACE_DEBUG("app_idx=%d mcl_idx=%d",app_idx, mcl_idx);
             BTIF_TRACE_DEBUG("valid_spd_idx=%d sdp_idx=%d",p_mcb->valid_sdp_idx, p_mcb->sdp_idx);
@@ -1227,7 +1199,7 @@ static BOOLEAN btif_hl_find_peer_mdep_id(UINT8 app_id, BD_ADDR bd_addr,
                 num_mdeps = p_rec->num_mdeps;
                 BTIF_TRACE_DEBUG("num_mdeps=%d", num_mdeps);
 
-                for (i=0; i< num_mdeps; i++)
+                for (i = 0; i < num_mdeps; i++)
                 {
                     BTIF_TRACE_DEBUG("p_rec->mdep_cfg[%d].mdep_role=%d",i, p_rec->mdep_cfg[i].mdep_role);
                     BTIF_TRACE_DEBUG("p_rec->mdep_cfg[%d].data_type =%d",i, p_rec->mdep_cfg[i].data_type );
@@ -1281,8 +1253,6 @@ static  BOOLEAN btif_hl_find_mdep_cfg_idx(UINT8 app_idx,  tBTA_HL_MDEP_ID local_
     return found;
 }
 
-
-
 /*******************************************************************************
 **
 ** Function      btif_hl_find_mcl_idx
@@ -1310,7 +1280,6 @@ BOOLEAN btif_hl_find_mcl_idx(UINT8 app_idx, BD_ADDR p_bd_addr, UINT8 *p_mcl_idx)
         }
     }
 
-
     BTIF_TRACE_DEBUG("%s found=%d idx=%d",__FUNCTION__, found, i);
     return found;
 }
@@ -1484,7 +1453,6 @@ UINT16  btif_hl_get_max_tx_apdu_size(tBTA_HL_MDEP_ROLE mdep_role,
             max_tx_apdu_size = BTIF_HL_DEFAULT_SRC_RX_APDU_SIZE;
         }
 
-
     }
 
     BTIF_TRACE_DEBUG("%s mdep_role=%d data_type=0x%4x size=%d",
@@ -1492,7 +1460,6 @@ UINT16  btif_hl_get_max_tx_apdu_size(tBTA_HL_MDEP_ROLE mdep_role,
     return max_tx_apdu_size;
 }
 
-
 /*******************************************************************************
 **
 ** Function      btif_hl_get_max_rx_apdu_size
@@ -1531,7 +1498,6 @@ UINT16  btif_hl_get_max_rx_apdu_size(tBTA_HL_MDEP_ROLE mdep_role,
         }
     }
 
-
     BTIF_TRACE_DEBUG("%s mdep_role=%d data_type=0x%4x size=%d",
                       __FUNCTION__, mdep_role, data_type, max_rx_apdu_size);
 
@@ -1673,7 +1639,6 @@ static void btif_hl_init_next_channel_id(void){
     btif_hl_cb.next_channel_id = 1;
 }
 
-
 /*******************************************************************************
 **
 ** Function      btif_hl_find_app_idx_using_handle
@@ -2102,7 +2067,6 @@ static BOOLEAN btif_hl_find_avail_app_idx(UINT8 *p_idx){
     return found;
 }
 
-
 /*******************************************************************************
 **
 ** Function         btif_hl_proc_dereg_cfm
@@ -2199,7 +2163,6 @@ void btif_hl_set_chan_cb_state(UINT8 app_idx, UINT8 mcl_idx, btif_hl_chan_cb_sta
         BTIF_TRACE_DEBUG("%s state %d--->%d",__FUNCTION__, cur_state, state);
     }
 
-
 }
 /*******************************************************************************
 **
@@ -2447,7 +2410,6 @@ static BOOLEAN btif_hl_proc_sdp_query_cfm(tBTA_HL *p_data){
     return status;
 }
 
-
 /*******************************************************************************
 **
 ** Function         btif_hl_proc_cch_open_ind
@@ -2592,8 +2554,6 @@ static BOOLEAN btif_hl_proc_cch_open_cfm(tBTA_HL *p_data)
         BTIF_TRACE_DEBUG("app_idx=%d", app_idx);
         if (btif_hl_find_mcl_idx(app_idx, p_data->cch_open_cfm.bd_addr, &mcl_idx))
         {
-            BTIF_HL_GET_APP_CB_PTR(app_idx);
-
             p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
             BTIF_TRACE_DEBUG("mcl_idx=%d, mcl_handle=%d", mcl_idx,p_data->cch_open_cfm.mcl_handle);
             p_mcb->mcl_handle = p_data->cch_open_cfm.mcl_handle;
@@ -2657,7 +2617,6 @@ static void btif_hl_proc_cch_close_ind(tBTA_HL *p_data)
     btif_hl_clean_mcb_using_handle(p_data->cch_close_ind.mcl_handle);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btif_hl_proc_cch_close_cfm
@@ -2779,9 +2738,6 @@ static void btif_hl_proc_dch_open_ind(tBTA_HL *p_data)
 
     if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_open_ind.mcl_handle, orig_app_idx, &mcl_idx ))
     {
-        BTIF_HL_GET_APP_CB_PTR(orig_app_idx);
-        BTIF_HL_GET_MCL_CB_PTR(orig_app_idx, mcl_idx);
-
         if (btif_hl_find_avail_mdl_idx(orig_app_idx, mcl_idx, &mdl_idx))
         {
             p_dcb = BTIF_HL_GET_MDL_CB_PTR(orig_app_idx, mcl_idx, mdl_idx);
@@ -2858,8 +2814,6 @@ static BOOLEAN btif_hl_proc_dch_open_cfm(tBTA_HL *p_data)
 
     if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_open_cfm.mcl_handle, app_idx, &mcl_idx ))
     {
-        BTIF_HL_GET_APP_CB_PTR(app_idx);
-        BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
         p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
 
         if (btif_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx))
@@ -2932,8 +2886,6 @@ static BOOLEAN btif_hl_proc_dch_reconnect_cfm(tBTA_HL *p_data)
 
     if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_reconnect_cfm.mcl_handle, app_idx, &mcl_idx ))
     {
-        BTIF_HL_GET_APP_CB_PTR(app_idx);
-        BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
         p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
 
         if (btif_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx))
@@ -3011,7 +2963,6 @@ static void btif_hl_proc_dch_reconnect_ind(tBTA_HL *p_data)
         p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
         BTIF_TRACE_DEBUG("btif_hl_proc_dch_reconnect_ind: app_idx = %d, mcl_idx = %d",
                                 app_idx, mcl_idx);
-        BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
 
         if (btif_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx))
         {
@@ -3119,7 +3070,6 @@ static void btif_hl_proc_dch_close_cfm(tBTA_HL *p_data)
     }
 }
 
-
 /*******************************************************************************
 **
 ** Function         btif_hl_proc_abort_ind
@@ -3229,7 +3179,6 @@ static void btif_hl_proc_dch_cong_ind(tBTA_HL *p_data)
 
     BTIF_TRACE_DEBUG("btif_hl_proc_dch_cong_ind");
 
-
     if (btif_hl_find_mdl_idx_using_handle(p_data->dch_cong_ind.mdl_handle, &app_idx, &mcl_idx, &mdl_idx))
     {
         p_dcb =BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
@@ -3262,7 +3211,6 @@ static void btif_hl_proc_reg_request(UINT8 app_idx, UINT8  app_id,
         BTA_HlRegister(app_id, p_reg_param, btif_hl_cback);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btif_hl_proc_cb_evt
@@ -3280,9 +3228,6 @@ static void btif_hl_proc_cb_evt(UINT16 event, char* p_param){
     BOOLEAN                         send_chan_cb=TRUE;
     tBTA_HL_REG_PARAM               reg_param;
     btif_hl_app_cb_t                *p_acb;
-    bthl_app_reg_state_t            reg_state = BTHL_APP_REG_STATE_REG_FAILED;
-    UINT8                           preg_idx;
-    bt_status_t                     bt_status;
 
     BTIF_TRACE_DEBUG("%s event %d", __FUNCTION__, event);
     btif_hl_display_calling_process_name();
@@ -3453,7 +3398,6 @@ static void btif_hl_upstreams_evt(UINT16 event, char* p_param){
 
             break;
 
-
         case BTA_HL_CCH_OPEN_CFM_EVT:
             BTIF_TRACE_DEBUG("Rcv BTA_HL_CCH_OPEN_CFM_EVT");
             BTIF_TRACE_DEBUG("app_id=%d,app_handle=%d mcl_handle=%d status =%d",
@@ -3542,7 +3486,6 @@ static void btif_hl_upstreams_evt(UINT16 event, char* p_param){
             }
             break;
 
-
         case BTA_HL_CCH_OPEN_IND_EVT:
             BTIF_TRACE_DEBUG("Rcv BTA_HL_CCH_OPEN_IND_EVT");
             BTIF_TRACE_DEBUG("app_handle=%d mcl_handle=%d",
@@ -3617,7 +3560,6 @@ static void btif_hl_upstreams_evt(UINT16 event, char* p_param){
                               p_data->dch_reconnect_cfm.mdl_id,
                               p_data->dch_reconnect_cfm.mtu);
 
-
             if (p_data->dch_reconnect_cfm.status == BTA_HL_STATUS_OK)
             {
                 status = btif_hl_proc_dch_reconnect_cfm(p_data);
@@ -3697,7 +3639,6 @@ static void btif_hl_upstreams_evt(UINT16 event, char* p_param){
             /* not supported */
             break;
 
-
         case BTA_HL_DCH_RECONNECT_IND_EVT:
             BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_RECONNECT_IND_EVT");
 
@@ -3883,7 +3824,6 @@ static void btif_hl_upstreams_ctrl_evt(UINT16 event, char* p_param){
             {
                 btif_hl_set_state(BTIF_HL_STATE_ENABLED);
 
-
                 for (i=0; i < BTA_HL_NUM_APPS ; i ++)
                 {
                     p_acb = BTIF_HL_GET_APP_CB_PTR(i);
@@ -3972,7 +3912,6 @@ static bt_status_t connect_channel(int app_id, bt_bdaddr_t *bd_addr, int mdep_cf
     BTIF_TRACE_EVENT("%s", __FUNCTION__);
     btif_hl_display_calling_process_name();
 
-
     for (i=0; i<6; i++)
     {
         bda[i] = (UINT8) bd_addr->address[i];
@@ -4071,7 +4010,6 @@ static bt_status_t destroy_channel(int channel_id){
     BTIF_TRACE_EVENT("%s channel_id=0x%08x", __FUNCTION__, channel_id);
     btif_hl_display_calling_process_name();
 
-
     if (btif_hl_if_channel_setup_pending(channel_id, &app_idx, &mcl_idx))
     {
         btif_hl_dch_abort(app_idx, mcl_idx);
@@ -4163,7 +4101,6 @@ static bt_status_t unregister_application(int app_id){
     if (btif_hl_find_app_idx(((UINT8)app_id), &app_idx))
     {
         evt_param.unreg.app_idx = app_idx;
-        BTIF_HL_GET_APP_CB_PTR(app_idx);
         reg_counter --;
         len = sizeof(btif_hl_unreg_t);
         status = btif_transfer_context (btif_hl_proc_cb_evt, BTIF_HL_UNREG_APP,
@@ -4218,7 +4155,6 @@ static bt_status_t register_application(bthl_reg_param_t *p_reg_param, int *app_
     p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
     p_acb->in_use = TRUE;
 
-
     p_acb->app_id = btif_hl_get_next_app_id();
 
     if (p_reg_param->application_name != NULL )
@@ -4393,9 +4329,6 @@ BOOLEAN  btif_hl_delete_mdl_cfg(UINT8 mdep_id, UINT8 item_idx){
 
     if(btif_hl_find_app_idx_using_mdepId(mdep_id,&app_idx))
     {
-
-        BTIF_HL_GET_APP_CB_PTR(app_idx);
-
         p_mdl = BTIF_HL_GET_MDL_CFG_PTR(app_idx, item_idx);
         if (p_mdl)
         {
@@ -4469,7 +4402,6 @@ static const bthl_interface_t bthlInterface = {
     cleanup,
 };
 
-
 /*******************************************************************************
 **
 ** Function         btif_hl_get_interface
@@ -5048,7 +4980,7 @@ void btif_hl_soc_thread_init(void){
     BTIF_TRACE_DEBUG("%s", __FUNCTION__);
     soc_queue = list_new(NULL);
     if (soc_queue == NULL)
-        LOG_ERROR("%s unable to allocate resources for thread", __func__);
+        LOG_ERROR(LOG_TAG, "%s unable to allocate resources for thread", __func__);
     select_thread_id = create_thread(btif_hl_select_thread, NULL);
 }
 /*******************************************************************************
index c50ef8b..fd73b0a 100644 (file)
  *
  ***********************************************************************************/
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_mce.h>
+#define LOG_TAG "bt_btif_mce"
+
 #include <stdlib.h>
 #include <string.h>
 
-#define LOG_TAG "bt_btif_mce"
-#include "btif_common.h"
-#include "btif_util.h"
-#include "btif_profile_queue.h"
-#include "bta_api.h"
-#include "bta_mce_api.h"
+#include <hardware/bluetooth.h>
+#include <hardware/bt_mce.h>
 
 #include "bt_types.h"
+#include "bta_api.h"
+#include "bta_mce_api.h"
 #include "btcore/include/bdaddr.h"
+#include "btif_common.h"
+#include "btif_profile_queue.h"
+#include "btif_util.h"
 
 /*****************************************************************************
 **  Static variables
index b6f3f0c..9c18365 100644 (file)
 #define LOG_TAG "bt_btif_media"
 
 #include <assert.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <dlfcn.h>
+#include <errno.h>
 #include <fcntl.h>
-#include <unistd.h>
 #include <pthread.h>
 #include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
 #include <sys/time.h>
-#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
 
-#include "bt_target.h"
-#include "osi/include/fixed_queue.h"
-#include "gki.h"
-#include "bta_api.h"
-#include "btu.h"
-#include "bta_sys.h"
-#include "bta_sys_int.h"
+#include <hardware/bluetooth.h>
 
-#include "bta_av_api.h"
 #include "a2d_api.h"
-#include "a2d_sbc.h"
 #include "a2d_int.h"
-#include "bta_av_sbc.h"
+#include "a2d_sbc.h"
+#include "audio_a2dp_hw.h"
+#include "bt_target.h"
+#include "bta_api.h"
+#include "bta_av_api.h"
 #include "bta_av_ci.h"
-#include "l2c_api.h"
-
+#include "bta_av_sbc.h"
+#include "bta_sys.h"
+#include "bta_sys_int.h"
+#include "btif_av.h"
 #include "btif_av_co.h"
 #include "btif_media.h"
-
+#include "btif_sm.h"
+#include "btif_util.h"
+#include "btu.h"
+#include "gki.h"
+#include "l2c_api.h"
 #include "osi/include/alarm.h"
+#include "osi/include/fixed_queue.h"
 #include "osi/include/log.h"
 #include "osi/include/thread.h"
 
 #include "sbc_encoder.h"
 #endif
 
-#include <hardware/bluetooth.h>
-#include "audio_a2dp_hw.h"
-#include "btif_av.h"
-#include "btif_sm.h"
-#include "btif_util.h"
 #if (BTA_AV_SINK_INCLUDED == TRUE)
 #include "oi_codec_sbc.h"
 #include "oi_status.h"
 #endif
-#include "stdio.h"
-#include <dlfcn.h>
 
 #if (BTA_AV_SINK_INCLUDED == TRUE)
 OI_CODEC_SBC_DECODER_CONTEXT context;
@@ -1180,7 +1177,7 @@ static void btif_media_task_aa_handle_uipc_rx_rdy(void)
     btif_media_aa_prep_2_send(0xFF);
 
     /* send it */
-    LOG_VERBOSE("btif_media_task_aa_handle_uipc_rx_rdy calls bta_av_ci_src_data_ready");
+    LOG_VERBOSE(LOG_TAG, "btif_media_task_aa_handle_uipc_rx_rdy calls bta_av_ci_src_data_ready");
     bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
 }
 #endif
@@ -1251,7 +1248,7 @@ static void btif_media_flush_q(BUFFER_Q *p_q)
 static void btif_media_thread_handle_cmd(fixed_queue_t *queue, UNUSED_ATTR void *context)
 {
     BT_HDR *p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
-    LOG_VERBOSE("btif_media_thread_handle_cmd : %d %s", p_msg->event,
+    LOG_VERBOSE(LOG_TAG, "btif_media_thread_handle_cmd : %d %s", p_msg->event,
              dump_media_event(p_msg->event));
 
     switch (p_msg->event)
@@ -1296,7 +1293,7 @@ static void btif_media_thread_handle_cmd(fixed_queue_t *queue, UNUSED_ATTR void
         APPL_TRACE_ERROR("ERROR in %s unknown event %d", __func__, p_msg->event);
     }
     GKI_freebuf(p_msg);
-    LOG_VERBOSE("%s: %s DONE", __func__, dump_media_event(p_msg->event));
+    LOG_VERBOSE(LOG_TAG, "%s: %s DONE", __func__, dump_media_event(p_msg->event));
 }
 
 #if (BTA_AV_SINK_INCLUDED == TRUE)
@@ -1948,7 +1945,7 @@ static void btif_media_task_aa_handle_start_decoding(void) {
 
   btif_media_cb.decode_alarm = alarm_new();
   if (!btif_media_cb.decode_alarm) {
-    LOG_ERROR("%s unable to allocate decode alarm.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate decode alarm.", __func__);
     return;
   }
 
@@ -2164,7 +2161,7 @@ static void btif_media_task_aa_start_tx(void)
 
     btif_media_cb.media_alarm = alarm_new();
     if (!btif_media_cb.media_alarm) {
-      LOG_ERROR("%s unable to allocate media alarm.", __func__);
+      LOG_ERROR(LOG_TAG, "%s unable to allocate media alarm.", __func__);
       return;
     }
 
@@ -2257,7 +2254,7 @@ static UINT8 btif_get_num_aa_frame(void)
             }
             btif_media_cb.media_feeding_state.pcm.counter -= result*pcm_bytes_per_frame;
 
-            LOG_VERBOSE("WRITE %d FRAMES", result);
+            LOG_VERBOSE(LOG_TAG, "WRITE %d FRAMES", result);
         }
         break;
 
@@ -2662,7 +2659,7 @@ static void btif_media_send_aa_frame(void)
     }
 
     /* send it */
-    LOG_VERBOSE("btif_media_send_aa_frame : send %d frames", nb_frame_2_send);
+    LOG_VERBOSE(LOG_TAG, "btif_media_send_aa_frame : send %d frames", nb_frame_2_send);
     bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
 }
 
index c3dec2a..13ada4e 100644 (file)
  *
  *
  ***********************************************************************************/
-#include <hardware/bluetooth.h>
-#include <hardware/bt_pan.h>
+
+#define LOG_TAG "bt_btif_pan"
+
 #include <assert.h>
-#include <string.h>
-#include <signal.h>
 #include <ctype.h>
-#include <sys/select.h>
-#include <sys/poll.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/if_ether.h>
+#include <linux/if_tun.h>
+#include <linux/sockios.h>
+#include <net/if.h>
 #include <netdb.h>
+#include <netinet/in.h>
+#include <signal.h>
 #include <stdio.h>
 #include <string.h>
-#include <errno.h>
-#include <fcntl.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <sys/prctl.h>
+#include <sys/select.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
-#include <net/if.h>
-#include <linux/sockios.h>
-#include <sys/prctl.h>
-#include <linux/if_tun.h>
-#include <linux/if_ether.h>
+#include <unistd.h>
 
-#define LOG_TAG "bt_btif_pan"
-#include "btif_common.h"
-#include "btif_util.h"
-#include "btm_api.h"
-#include "btcore/include/bdaddr.h"
-#include "device/include/controller.h"
+#include <hardware/bluetooth.h>
+#include <hardware/bt_pan.h>
 
 #include "bta_api.h"
 #include "bta_pan_api.h"
+#include "btcore/include/bdaddr.h"
+#include "btif_common.h"
+#include "btif_pan_internal.h"
 #include "btif_sock_thread.h"
 #include "btif_sock_util.h"
-#include "btif_pan_internal.h"
+#include "btif_util.h"
+#include "btm_api.h"
+#include "device/include/controller.h"
 #include "gki.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 
 #define FORWARD_IGNORE        1
 #define FORWARD_SUCCESS       0
@@ -389,7 +392,7 @@ void btpan_set_flow_control(BOOLEAN enable) {
     btpan_cb.flow = enable;
     if (enable) {
         btsock_thread_add_fd(pan_pth, btpan_cb.tap_fd, 0, SOCK_THREAD_FD_RD, 0);
-        bta_dmexecutecallback(btu_exec_tap_fd_read, (void *)btpan_cb.tap_fd);
+        bta_dmexecutecallback(btu_exec_tap_fd_read, INT_TO_PTR(btpan_cb.tap_fd));
     }
 }
 
@@ -445,7 +448,7 @@ int btpan_tap_send(int tap_fd, const BD_ADDR src, const BD_ADDR dst, UINT16 prot
         memcpy(packet, &eth_hdr, sizeof(tETH_HDR));
         if (len > TAP_MAX_PKT_WRITE_LEN)
         {
-            LOG_ERROR("btpan_tap_send eth packet size:%d is exceeded limit!", len);
+            LOG_ERROR(LOG_TAG, "btpan_tap_send eth packet size:%d is exceeded limit!", len);
             return -1;
         }
         memcpy(packet + sizeof(tETH_HDR), buf, len);
@@ -607,7 +610,7 @@ static void bta_pan_callback_transfer(UINT16 event, char *p_param)
                 bt_status_t status;
                 btpan_conn_t *conn = btpan_find_conn_handle(p_data->open.handle);
 
-                LOG_VERBOSE("%s pan connection open status: %d", __func__, p_data->open.status);
+                LOG_VERBOSE(LOG_TAG, "%s pan connection open status: %d", __func__, p_data->open.status);
                 if (p_data->open.status == BTA_PAN_SUCCESS)
                 {
                     state = BTPAN_STATE_CONNECTED;
@@ -631,7 +634,7 @@ static void bta_pan_callback_transfer(UINT16 event, char *p_param)
             {
                 btpan_conn_t* conn = btpan_find_conn_handle(p_data->close.handle);
 
-                LOG_INFO("%s: event = BTA_PAN_CLOSE_EVT handle %d", __FUNCTION__, p_data->close.handle);
+                LOG_INFO(LOG_TAG, "%s: event = BTA_PAN_CLOSE_EVT handle %d", __FUNCTION__, p_data->close.handle);
 
                 if (conn && conn->handle >= 0)
                 {
@@ -659,7 +662,7 @@ static void bta_pan_callback(tBTA_PAN_EVT event, tBTA_PAN *p_data)
 #define IS_EXCEPTION(e) ((e) & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL))
 static void btu_exec_tap_fd_read(void *p_param) {
     struct pollfd ufd;
-    int fd = (int)p_param;
+    int fd = PTR_TO_INT(p_param);
 
     if (fd == INVALID_FD || fd != btpan_cb.tap_fd)
         return;
@@ -758,5 +761,5 @@ static void btpan_tap_fd_signaled(int fd, int type, int flags, uint32_t user_id)
         btpan_tap_close(fd);
         btif_pan_close_all_conns();
     } else if (flags & SOCK_THREAD_FD_RD)
-        bta_dmexecutecallback(btu_exec_tap_fd_read, (void *)fd);
+        bta_dmexecutecallback(btu_exec_tap_fd_read, INT_TO_PTR(fd));
 }
index 86025ef..505394a 100644 (file)
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_btif_queue"
+
+#include "btif_profile_queue.h"
+
 #include <assert.h>
 #include <string.h>
-#include <hardware/bluetooth.h>
-#include <string.h>
 
-#define LOG_TAG "bt_btif_queue"
 #include "btif_common.h"
-#include "btif_profile_queue.h"
 #include "gki.h"
-#include "osi/include/list.h"
 #include "osi/include/allocator.h"
+#include "osi/include/list.h"
 #include "stack_manager.h"
 
 /*******************************************************************************
@@ -76,7 +76,7 @@ static void queue_int_add(connect_node_t *p_param) {
 
     for (const list_node_t *node = list_begin(connect_queue); node != list_end(connect_queue); node = list_next(node)) {
         if (((connect_node_t *)list_node(node))->uuid == p_param->uuid) {
-            LOG_INFO("%s dropping duplicate connect request for uuid: %04x", __func__, p_param->uuid);
+            LOG_INFO(LOG_TAG, "%s dropping duplicate connect request for uuid: %04x", __func__, p_param->uuid);
             return;
         }
     }
@@ -160,7 +160,6 @@ bt_status_t btif_queue_connect_next(void) {
     return p_head->connect_cb(&p_head->bda, p_head->uuid);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btif_queue_release
index 1b5696c..a2074b3 100644 (file)
@@ -16,7 +16,6 @@
  *
  ******************************************************************************/
 
-
 /*****************************************************************************
  *
  *  Filename:      btif_rc.c
  *  Description:   Bluetooth AVRC implementation
  *
  *****************************************************************************/
-#include <hardware/bluetooth.h>
+
+#define LOG_TAG "bt_btif_avrc"
+
 #include <fcntl.h>
+#include <pthread.h>
 #include <string.h>
+#include <unistd.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_rc.h>
+
+#include "avrc_defs.h"
 #include "bta_api.h"
 #include "bta_av_api.h"
-#include "avrc_defs.h"
-#include "gki.h"
-
-#define LOG_TAG "bt_btif_avrc"
+#include "btif_av.h"
 #include "btif_common.h"
 #include "btif_util.h"
-#include "btif_av.h"
-#include "hardware/bt_rc.h"
+#include "gki.h"
 #include "uinput.h"
 
 /*****************************************************************************
@@ -131,7 +135,6 @@ typedef struct
     rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION];
 } rc_device_t;
 
-
 rc_device_t device;
 
 #define MAX_UINPUT_PATHS 3
@@ -217,7 +220,6 @@ static btrc_ctrl_callbacks_t *bt_rc_ctrl_callbacks = NULL;
 extern BOOLEAN btif_hf_call_terminated_recently();
 extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
 
-
 /*****************************************************************************
 **  Functions
 ******************************************************************************/
@@ -402,7 +404,6 @@ void handle_rc_features()
 #endif
 }
 
-
 /***************************************************************************
  *  Function       handle_rc_connect
  *
@@ -681,7 +682,6 @@ void handle_uid_changed_notification(tBTA_AV_META_MSG *pmeta_msg, tAVRC_COMMAND
 
 }
 
-
 /***************************************************************************
  *  Function       handle_rc_metamsg_cmd
  *
@@ -1184,7 +1184,6 @@ static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8
 
 }
 
-
 /*******************************************************************************
 **
 ** Function         btif_rc_upstreams_rsp_evt
@@ -1479,7 +1478,6 @@ static bt_status_t set_volume(uint8_t volume)
     return status;
 }
 
-
 /***************************************************************************
 **
 ** Function         register_volumechange
@@ -1524,7 +1522,6 @@ static void register_volumechange (UINT8 lbl)
         BTIF_TRACE_ERROR("%s failed to build command:%d",__FUNCTION__,BldResp);
 }
 
-
 /***************************************************************************
 **
 ** Function         handle_rc_metamsg_rsp
@@ -1601,7 +1598,6 @@ static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg)
                                 pmeta_msg->label);
 }
 
-
 /***************************************************************************
 **
 ** Function         cleanup
@@ -1851,7 +1847,6 @@ bt_status_t  get_transaction(rc_transaction_t **ptransaction)
     return result;
 }
 
-
 /*******************************************************************************
 **
 ** Function         release_transaction
index f728605..08980e9 100644 (file)
  *
  ***********************************************************************************/
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_sdp.h>
+#define LOG_TAG "bt_btif_sdp"
+
 #include <stdlib.h>
 #include <string.h>
 
-#define LOG_TAG "BTIF_SDP"
-#include "btif_common.h"
-#include "btif_util.h"
-#include "btif_profile_queue.h"
+#include <hardware/bluetooth.h>
+#include <hardware/bt_sdp.h>
+
 #include "bta_api.h"
 #include "bta_sdp_api.h"
+#include "btif_common.h"
+#include "btif_profile_queue.h"
+#include "btif_util.h"
 
 /*****************************************************************************
 **  Functions implemented in sdp_server.c
@@ -52,7 +54,6 @@ int get_sdp_records_size(bluetooth_sdp_record* in_record, int count);
 void copy_sdp_records(bluetooth_sdp_record* in_records,
         bluetooth_sdp_record* out_records, int count);
 
-
 /*****************************************************************************
 **  Static variables
 ******************************************************************************/
@@ -108,12 +109,12 @@ static void sdp_dm_cback(tBTA_SDP_EVT event, tBTA_SDP *p_data, void *user_data)
         }
         case BTA_SDP_CREATE_RECORD_USER_EVT:
         {
-            on_create_record_event((int)user_data);
+            on_create_record_event(PTR_TO_INT(user_data));
             break;
         }
         case BTA_SDP_REMOVE_RECORD_USER_EVT:
         {
-            on_remove_record_event((int)user_data);
+            on_remove_record_event(PTR_TO_INT(user_data));
             break;
         }
         default:
@@ -144,10 +145,8 @@ static bt_status_t deinit()
     return BT_STATUS_SUCCESS;
 }
 
-
 static bt_status_t search(bt_bdaddr_t *bd_addr, const uint8_t *uuid)
 {
-    bdstr_t bdstr;
     tSDP_UUID sdp_uuid;
     sdp_uuid.len = 16;
     memcpy(sdp_uuid.uu.uuid128, uuid, sizeof(sdp_uuid.uu.uuid128));
index 5be23f0..d02dfa0 100644 (file)
  *
  ***********************************************************************************/
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_sdp.h>
+#define LOG_TAG "bt_btif_sdp_server"
+
+#include <pthread.h>
 #include <stdlib.h>
 #include <string.h>
-#include <pthread.h>
 
-#define LOG_TAG "BTIF_SDP_SERVER"
-#include "allocator.h"
-#include "btif_common.h"
-#include "btif_util.h"
+#include <hardware/bluetooth.h>
+#include <hardware/bt_sdp.h>
+
 #include "bta_sdp_api.h"
 #include "bta_sys.h"
-#include "utl.h"
+#include "btif_common.h"
 #include "btif_sock_util.h"
+#include "btif_util.h"
+#include "osi/include/allocator.h"
+#include "utl.h"
 
 static pthread_mutex_t sdp_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 
@@ -184,7 +186,6 @@ void copy_sdp_records(bluetooth_sdp_record* in_records,
  *   user2_ptr. */
 static int alloc_sdp_slot(bluetooth_sdp_record* in_record) {
     int i;
-    char* tmp_ptr = NULL;
     int record_size = get_sdp_records_size(in_record, 1);
     bluetooth_sdp_record* record = osi_malloc(record_size);
 
@@ -271,7 +272,6 @@ static void set_sdp_handle(int id, int handle) {
     BTIF_TRACE_DEBUG("%s() id=%d to handle=0x%08x", __FUNCTION__, id, handle);
 }
 
-
 bt_status_t create_sdp_record(bluetooth_sdp_record *record, int* record_handle) {
     int handle;
 
@@ -281,7 +281,7 @@ bt_status_t create_sdp_record(bluetooth_sdp_record *record, int* record_handle)
     if(handle < 0)
         return BT_STATUS_FAIL;
 
-    BTA_SdpCreateRecordByUser((void*) handle);
+    BTA_SdpCreateRecordByUser(INT_TO_PTR(handle));
 
     *record_handle = handle;
 
@@ -298,14 +298,13 @@ bt_status_t remove_sdp_record(int record_id) {
 
     /* Pass the actual record handle */
     if(handle > 0) {
-        BTA_SdpRemoveRecordByUser((void*) handle);
+        BTA_SdpRemoveRecordByUser(INT_TO_PTR(handle));
         return BT_STATUS_SUCCESS;
     }
     BTIF_TRACE_DEBUG("Sdp Server %s - record already removed - or never created", __FUNCTION__);
     return BT_STATUS_FAIL;
 }
 
-
 /******************************************************************************
  * CALLBACK FUNCTIONS
  * Called in BTA context to create/remove SDP records.
@@ -621,7 +620,6 @@ static int add_pbaps_sdp(const bluetooth_sdp_pse_record* rec)
     return sdp_handle;
 }
 
-
 /* Create a OPP Server SDP record based on information stored in a bluetooth_sdp_ops_record */
 static int add_opps_sdp(const bluetooth_sdp_ops_record* rec)
 {
@@ -778,4 +776,3 @@ static int add_saps_sdp(const bluetooth_sdp_sap_record* rec)
     }
     return sdp_handle;
 }
-
index 61409ae..7e6eafb 100644 (file)
@@ -16,7 +16,6 @@
  *
  ******************************************************************************/
 
-
 /*****************************************************************************
  *
  *  Filename:      btif_sm.c
 
 #define LOG_TAG "bt_btif"
 
-#include <hardware/bluetooth.h>
+#include "btif_sm.h"
 
-#include "osi/include/allocator.h"
 #include "btif_common.h"
-#include "btif_sm.h"
 #include "gki.h"
-
-/*****************************************************************************
-**  Constants & Macros
-******************************************************************************/
-
+#include "osi/include/allocator.h"
 
 /*****************************************************************************
 **  Local type definitions
@@ -48,18 +41,6 @@ typedef struct {
 } btif_sm_cb_t;
 
 /*****************************************************************************
-**  Static variables
-******************************************************************************/
-
-/*****************************************************************************
-**  Static functions
-******************************************************************************/
-
-/*****************************************************************************
-**  Externs
-******************************************************************************/
-
-/*****************************************************************************
 **  Functions
 ******************************************************************************/
 
index c441eeb..4ffbb45 100644 (file)
 #define LOG_TAG "bt_btif_sock"
 
 #include <assert.h>
+
 #include <hardware/bluetooth.h>
 #include <hardware/bt_sock.h>
 
 #include "bta_api.h"
 #include "btif_common.h"
+#include "btif_sock_l2cap.h"
 #include "btif_sock_rfc.h"
 #include "btif_sock_sco.h"
-#include "btif_sock_thread.h"
-#include "btif_sock_l2cap.h"
 #include "btif_sock_sdp.h"
+#include "btif_sock_thread.h"
 #include "btif_util.h"
 #include "osi/include/thread.h"
 
@@ -58,32 +59,32 @@ bt_status_t btif_sock_init(void) {
   btsock_thread_init();
   thread_handle = btsock_thread_create(btsock_signaled, NULL);
   if (thread_handle == -1) {
-    LOG_ERROR("%s unable to create btsock_thread.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create btsock_thread.", __func__);
     goto error;
   }
 
   bt_status_t status = btsock_rfc_init(thread_handle);
   if (status != BT_STATUS_SUCCESS) {
-    LOG_ERROR("%s error initializing RFCOMM sockets: %d", __func__, status);
+    LOG_ERROR(LOG_TAG, "%s error initializing RFCOMM sockets: %d", __func__, status);
     goto error;
   }
 
   status = btsock_l2cap_init(thread_handle);
   if (status != BT_STATUS_SUCCESS) {
-    LOG_ERROR("%s error initializing L2CAP sockets: %d", __func__, status);
+    LOG_ERROR(LOG_TAG, "%s error initializing L2CAP sockets: %d", __func__, status);
     goto error;
   }
 
   thread = thread_new("btif_sock");
   if (!thread) {
-    LOG_ERROR("%s error creating new thread.", __func__);
+    LOG_ERROR(LOG_TAG, "%s error creating new thread.", __func__);
     btsock_rfc_cleanup();
     goto error;
   }
 
   status = btsock_sco_init(thread);
   if (status != BT_STATUS_SUCCESS) {
-    LOG_ERROR("%s error initializing SCO sockets: %d", __func__, status);
+    LOG_ERROR(LOG_TAG, "%s error initializing SCO sockets: %d", __func__, status);
     btsock_rfc_cleanup();
     goto error;
   }
@@ -136,7 +137,7 @@ static bt_status_t btsock_listen(btsock_type_t type, const char *service_name, c
       break;
 
     default:
-      LOG_ERROR("%s unknown/unsupported socket type: %d", __func__, type);
+      LOG_ERROR(LOG_TAG, "%s unknown/unsupported socket type: %d", __func__, type);
       status = BT_STATUS_UNSUPPORTED;
       break;
   }
@@ -165,7 +166,7 @@ static bt_status_t btsock_connect(const bt_bdaddr_t *bd_addr, btsock_type_t type
       break;
 
     default:
-      LOG_ERROR("%s unknown/unsupported socket type: %d", __func__, type);
+      LOG_ERROR(LOG_TAG, "%s unknown/unsupported socket type: %d", __func__, type);
       status = BT_STATUS_UNSUPPORTED;
       break;
   }
index 04c5b67..db58263 100644 (file)
 * limitations under the License.
 */
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_sock.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/socket.h>
+#define LOG_TAG "bt_btif_sock"
+
+#include "btif_sock_l2cap.h"
+
 #include <errno.h>
-#include <sys/ioctl.h>
 #include <pthread.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <hardware/bt_sock.h>
 
-#define LOG_TAG "BTIF_SOCK"
 #include "osi/include/allocator.h"
-#include "btif_common.h"
-#include "btif_util.h"
+#include "osi/include/log.h"
 
+#include "bt_target.h"
 #include "bta_api.h"
-#include "btif_sock_thread.h"
+#include "bta_jv_api.h"
+#include "bta_jv_co.h"
+#include "btif_common.h"
 #include "btif_sock_sdp.h"
+#include "btif_sock_thread.h"
 #include "btif_sock_util.h"
-#include "btif_sock_l2cap.h"
-#include "l2cdefs.h"
-
-#include "bt_target.h"
-#include "gki.h"
-#include "hcimsgs.h"
-#include "sdp_api.h"
-#include "btu.h"
+#include "btif_util.h"
 #include "btm_api.h"
 #include "btm_int.h"
-#include "bta_jv_api.h"
-#include "bta_jv_co.h"
-#include "port_api.h"
+#include "btu.h"
+#include "gki.h"
+#include "hcimsgs.h"
 #include "l2c_api.h"
+#include "l2cdefs.h"
+#include "port_api.h"
+#include "sdp_api.h"
 
-#include <cutils/log.h>
-#include <hardware/bluetooth.h>
 #define asrt(s) if (!(s)) APPL_TRACE_ERROR("## %s assert %s failed at line:%d ##",__FUNCTION__, \
         #s, __LINE__)
 
-static pthread_mutex_t slot_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
-
-
 struct packet {
     struct packet *next, *prev;
     uint32_t len;
@@ -85,7 +83,7 @@ typedef struct l2cap_socket {
     unsigned               connected        :1;  //is connected?
     unsigned               outgoing_congest :1;  //should we hold?
     unsigned               server_psm_sent  :1;  //The server shall only send PSM once.
-}l2cap_socket;
+} l2cap_socket;
 
 static bt_status_t btSock_start_l2cap_server_l(l2cap_socket *sock);
 
@@ -185,12 +183,12 @@ static char packet_put_tail_l(l2cap_socket *sock, const void *data, uint32_t len
     struct packet *p = packet_alloc((const uint8_t*)data, len);
 
     if (sock->bytes_buffered >= L2CAP_MAX_RX_BUFFER) {
-        ALOGE("packet_put_tail_l: buffer overflow");
+        LOG_ERROR(LOG_TAG, "packet_put_tail_l: buffer overflow");
         return FALSE;
     }
 
     if (!p) {
-        ALOGE("packet_put_tail_l: unable to allocate packet...");
+        LOG_ERROR(LOG_TAG, "packet_put_tail_l: unable to allocate packet...");
         return FALSE;
     }
 
@@ -221,7 +219,6 @@ static char is_inited(void)
 {
     char ret;
 
-
     pthread_mutex_lock(&state_lock);
     ret = pth != -1;
     pthread_mutex_unlock(&state_lock);
@@ -290,13 +287,6 @@ static void btsock_l2cap_free_l(l2cap_socket *sock)
     osi_free(sock);
 }
 
-static void btsock_l2cap_free(l2cap_socket *sock)
-{
-    pthread_mutex_lock(&state_lock);
-    btsock_l2cap_free_l(sock);
-    pthread_mutex_unlock(&state_lock);
-}
-
 static l2cap_socket *btsock_l2cap_alloc_l(const char *name, const bt_bdaddr_t *addr,
         char is_server, int flags)
 {
@@ -369,18 +359,6 @@ fail_alloc:
     return NULL;
 }
 
-static l2cap_socket *btsock_l2cap_alloc(const char *name, const bt_bdaddr_t *addr,
-        char is_server, int flags)
-{
-    l2cap_socket *ret;
-
-    pthread_mutex_lock(&state_lock);
-    ret = btsock_l2cap_alloc_l(name, addr, is_server, flags);
-    pthread_mutex_unlock(&state_lock);
-
-    return ret;
-}
-
 bt_status_t btsock_l2cap_init(int handle)
 {
     APPL_TRACE_DEBUG("btsock_l2cap_init...");
@@ -539,7 +517,7 @@ static void on_srv_l2cap_le_connect_l(tBTA_JV_L2CAP_LE_OPEN *p_open, l2cap_socke
 
         //if we do not set a callback, this socket will be dropped */
         *(p_open->p_p_cback) = (void*)btsock_l2cap_cbk;
-        *(p_open->p_user_data) = (void*)accept_rs->id;
+        *(p_open->p_user_data) = UINT_TO_PTR(accept_rs->id);
 
         //start monitor the socket
         btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_EXCEPTION, sock->id);
@@ -694,8 +672,6 @@ static void on_l2cap_write_fixed_done(void* req_id, uint32_t id)
     pthread_mutex_unlock(&state_lock);
 }
 
-
-
 static void on_l2cap_data_ind(tBTA_JV *evt, uint32_t id)
 {
     l2cap_socket *sock;
@@ -720,7 +696,6 @@ static void on_l2cap_data_ind(tBTA_JV *evt, uint32_t id)
 
         } else {
 
-            tBTA_JV_DATA_IND *p_data_ind = &evt->data_ind;
             UINT8 buffer[L2CAP_MAX_SDU_LENGTH];
             UINT32  count;
 
@@ -744,29 +719,29 @@ static void on_l2cap_data_ind(tBTA_JV *evt, uint32_t id)
 
 static void btsock_l2cap_cbk(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
 {
-    int rc;
+    uint32_t sock_id = PTR_TO_UINT(user_data);
 
     switch (event) {
     case BTA_JV_L2CAP_START_EVT:
-        on_srv_l2cap_listen_started(&p_data->l2c_start, (uint32_t)user_data);
+        on_srv_l2cap_listen_started(&p_data->l2c_start, sock_id);
         break;
 
     case BTA_JV_L2CAP_CL_INIT_EVT:
-        on_cl_l2cap_init(&p_data->l2c_cl_init, (uint32_t)user_data);
+        on_cl_l2cap_init(&p_data->l2c_cl_init, sock_id);
         break;
 
     case BTA_JV_L2CAP_OPEN_EVT:
-        on_l2cap_connect(p_data, (uint32_t)user_data);
-        BTA_JvSetPmProfile(p_data->l2c_open.handle,BTA_JV_PM_ID_1,BTA_JV_CONN_OPEN);
+        on_l2cap_connect(p_data, sock_id);
+        BTA_JvSetPmProfile(p_data->l2c_open.handle, BTA_JV_PM_ID_1,BTA_JV_CONN_OPEN);
         break;
 
     case BTA_JV_L2CAP_CLOSE_EVT:
-        APPL_TRACE_DEBUG("BTA_JV_L2CAP_CLOSE_EVT: user_data:%d", (uint32_t)user_data);
-        on_l2cap_close(&p_data->l2c_close, (uint32_t)user_data);
+        APPL_TRACE_DEBUG("BTA_JV_L2CAP_CLOSE_EVT: id: %u", sock_id);
+        on_l2cap_close(&p_data->l2c_close, sock_id);
         break;
 
     case BTA_JV_L2CAP_DATA_IND_EVT:
-        on_l2cap_data_ind(p_data, (uint32_t)user_data);
+        on_l2cap_data_ind(p_data, sock_id);
         APPL_TRACE_DEBUG("BTA_JV_L2CAP_DATA_IND_EVT");
         break;
 
@@ -779,21 +754,21 @@ static void btsock_l2cap_cbk(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data
         break;
 
     case BTA_JV_L2CAP_WRITE_EVT:
-        APPL_TRACE_DEBUG("BTA_JV_L2CAP_WRITE_EVT id: %d", (int)user_data);
-        on_l2cap_write_done((void*)p_data->l2c_write.req_id, (uint32_t)user_data);
+        APPL_TRACE_DEBUG("BTA_JV_L2CAP_WRITE_EVT: id: %u", sock_id);
+        on_l2cap_write_done(UINT_TO_PTR(p_data->l2c_write.req_id), sock_id);
         break;
 
     case BTA_JV_L2CAP_WRITE_FIXED_EVT:
-        APPL_TRACE_DEBUG("BTA_JV_L2CAP_WRITE_FIXED_EVT id: %d", (int)user_data);
-        on_l2cap_write_fixed_done((void*)p_data->l2c_write_fixed.req_id, (uint32_t)user_data);
+        APPL_TRACE_DEBUG("BTA_JV_L2CAP_WRITE_FIXED_EVT: id: %u", sock_id);
+        on_l2cap_write_fixed_done(UINT_TO_PTR(p_data->l2c_write_fixed.req_id), sock_id);
         break;
 
     case BTA_JV_L2CAP_CONG_EVT:
-        on_l2cap_outgoing_congest(&p_data->l2c_cong, (uint32_t)user_data);
+        on_l2cap_outgoing_congest(&p_data->l2c_cong, sock_id);
         break;
 
     default:
-        APPL_TRACE_ERROR("unhandled event %d, slot id:%d", event, (uint32_t)user_data);
+        APPL_TRACE_ERROR("unhandled event %d, slot id: %u", event, sock_id);
         break;
     }
 }
@@ -852,7 +827,7 @@ static bt_status_t btSock_start_l2cap_server_l(l2cap_socket *sock) {
     if (sock->fixed_chan) {
 
         if (BTA_JvL2capStartServerLE(sock->security, 0, NULL, sock->channel,
-                L2CAP_DEFAULT_MTU, NULL, btsock_l2cap_cbk, (void*)sock->id)
+                L2CAP_DEFAULT_MTU, NULL, btsock_l2cap_cbk, UINT_TO_PTR(sock->id))
                 != BTA_JV_SUCCESS)
             stat = BT_STATUS_FAIL;
 
@@ -860,12 +835,12 @@ static bt_status_t btSock_start_l2cap_server_l(l2cap_socket *sock) {
         /* If we have a channel specified in the request, just start the server,
          * else we request a PSM and start the server after we receive a PSM. */
         if(sock->channel < 0) {
-            if(BTA_JvGetChannelId(BTA_JV_CONN_TYPE_L2CAP, (void*)sock->id, 0)
+            if(BTA_JvGetChannelId(BTA_JV_CONN_TYPE_L2CAP, UINT_TO_PTR(sock->id), 0)
                     != BTA_JV_SUCCESS)
                 stat = BT_STATUS_FAIL;
         } else {
             if (BTA_JvL2capStartServer(sock->security, 0, &obex_l2c_etm_opt,
-                    sock->channel, L2CAP_MAX_SDU_LENGTH, &cfg, btsock_l2cap_cbk, (void*)sock->id)
+                    sock->channel, L2CAP_MAX_SDU_LENGTH, &cfg, btsock_l2cap_cbk, UINT_TO_PTR(sock->id))
                     != BTA_JV_SUCCESS)
                 stat = BT_STATUS_FAIL;
         }
@@ -921,13 +896,13 @@ static bt_status_t btsock_l2cap_listen_or_connect(const char *name, const bt_bda
         if (fixed_chan) {
             if (BTA_JvL2capConnectLE(sock->security, 0, NULL, channel,
                     L2CAP_DEFAULT_MTU, NULL, sock->addr.address, btsock_l2cap_cbk,
-                    (void*)sock->id) != BTA_JV_SUCCESS)
+                    UINT_TO_PTR(sock->id)) != BTA_JV_SUCCESS)
                 stat = BT_STATUS_FAIL;
 
         } else {
             if (BTA_JvL2capConnect(sock->security, 0, &obex_l2c_etm_opt,
                     channel, L2CAP_MAX_SDU_LENGTH, &cfg, sock->addr.address,
-                    btsock_l2cap_cbk, (void*)sock->id) != BTA_JV_SUCCESS)
+                    btsock_l2cap_cbk, UINT_TO_PTR(sock->id)) != BTA_JV_SUCCESS)
                 stat = BT_STATUS_FAIL;
         }
     }
@@ -1027,21 +1002,28 @@ void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id)
                          * be wrong
                          * UPDATE: Since we are responsible for freeing the buffer in the
                          * write_complete_ind, it is OK to use malloc. */
-
                         int count = recv(fd, buffer, L2CAP_MAX_SDU_LENGTH,
                                 MSG_NOSIGNAL | MSG_DONTWAIT);
                         APPL_TRACE_DEBUG("btsock_l2cap_signaled - %d bytes received from socket",
                                 count);
+
+                        // TODO(armansito): |buffer|, which is created above via
+                        // malloc, is being cast below to UINT32 to be used as
+                        // the |req_id| parameter of BTA_JvL2capWriteFixed and
+                        // BTA_JvL2capWrite. The "id" then gets freed in an
+                        // obscure callback elsewhere. We need to watch out for
+                        // this type of unsafe practice, as this is error prone
+                        // and difficult to follow.
                         if (sock->fixed_chan) {
                             if(BTA_JvL2capWriteFixed(sock->channel, (BD_ADDR*)&sock->addr,
-                                    (UINT32)buffer, btsock_l2cap_cbk, buffer, count,
-                                    (void *)user_id) != BTA_JV_SUCCESS) {
+                                    PTR_TO_UINT(buffer), btsock_l2cap_cbk, buffer, count,
+                                    UINT_TO_PTR(user_id)) != BTA_JV_SUCCESS) {
                                 // On fail, free the buffer
                                 on_l2cap_write_fixed_done(buffer, user_id);
                             }
                         } else {
-                            if(BTA_JvL2capWrite(sock->handle, (UINT32)buffer, buffer, count,
-                                    (void *)user_id) != BTA_JV_SUCCESS) {
+                            if(BTA_JvL2capWrite(sock->handle, PTR_TO_UINT(buffer), buffer, count,
+                                    UINT_TO_PTR(user_id)) != BTA_JV_SUCCESS) {
                                 // On fail, free the buffer
                                 on_l2cap_write_done(buffer, user_id);
                             }
@@ -1068,5 +1050,3 @@ void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id)
     pthread_mutex_unlock(&state_lock);
 }
 
-
-
index f80ed56..ee04588 100644 (file)
 #include <assert.h>
 #include <errno.h>
 #include <features.h>
-#include <hardware/bluetooth.h>
-#include <hardware/bt_sock.h>
+#include <pthread.h>
 #include <string.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/types.h>
-#include <pthread.h>
+#include <unistd.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_sock.h>
 
-#include "bta_api.h"
 #include "bt_target.h"
+#include "bta_api.h"
 #include "bta_jv_api.h"
 #include "bta_jv_co.h"
 #include "btif_common.h"
 #include "btif_sock_sdp.h"
 #include "btif_sock_thread.h"
 #include "btif_sock_util.h"
-/* The JV interface can have only one user, hence we need to call a few
- * L2CAP functions from this file. */
-#include "btif_sock_l2cap.h"
-
-
 #include "btif_util.h"
 #include "btm_api.h"
 #include "btm_int.h"
 #include "hcimsgs.h"
 #include "osi/include/compat.h"
 #include "osi/include/list.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 #include "port_api.h"
 #include "sdp_api.h"
 
+/* The JV interface can have only one user, hence we need to call a few
+ * L2CAP functions from this file. */
+#include "btif_sock_l2cap.h"
+
 #define MAX_RFC_CHANNEL 30  // Maximum number of RFCOMM channels (1-30 inclusive).
 #define MAX_RFC_SESSION 7   // Maximum number of devices we can have an RFCOMM connection with.
 
@@ -147,7 +148,7 @@ static rfc_slot_t *find_rfc_slot_by_id(uint32_t id) {
     if (rfc_slots[i].id == id)
       return &rfc_slots[i];
 
-  LOG_ERROR("%s unable to find RFCOMM slot id: %d", __func__, id);
+  LOG_ERROR(LOG_TAG, "%s unable to find RFCOMM slot id: %d", __func__, id);
   return NULL;
 }
 
@@ -183,13 +184,13 @@ static rfc_slot_t *alloc_rfc_slot(const bt_bdaddr_t *addr, const char *name, con
 
   rfc_slot_t *slot = find_free_slot();
   if (!slot) {
-    LOG_ERROR("%s unable to find free RFCOMM slot.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to find free RFCOMM slot.", __func__);
     return NULL;
   }
 
   int fds[2] = { INVALID_FD, INVALID_FD };
   if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) == -1) {
-    LOG_ERROR("%s error creating socketpair: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s error creating socketpair: %s", __func__, strerror(errno));
     return NULL;
   }
 
@@ -226,7 +227,7 @@ static rfc_slot_t *alloc_rfc_slot(const bt_bdaddr_t *addr, const char *name, con
 static rfc_slot_t *create_srv_accept_rfc_slot(rfc_slot_t *srv_rs, const bt_bdaddr_t *addr, int open_handle, int new_listen_handle) {
   rfc_slot_t *accept_rs = alloc_rfc_slot(addr, srv_rs->service_name, srv_rs->service_uuid, srv_rs->scn, 0, false);
   if (!accept_rs) {
-    LOG_ERROR("%s unable to allocate RFCOMM slot.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate RFCOMM slot.", __func__);
     return NULL;
   }
 
@@ -283,11 +284,11 @@ bt_status_t btsock_rfc_listen(const char *service_name, const uint8_t *service_u
 
   rfc_slot_t *slot = alloc_rfc_slot(NULL, service_name, service_uuid, channel, flags, true);
   if (!slot) {
-    LOG_ERROR("%s unable to allocate RFCOMM slot.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate RFCOMM slot.", __func__);
     goto out;
   }
   APPL_TRACE_DEBUG("BTA_JvGetChannelId: service_name: %s - channel: %d", service_name, channel);
-  BTA_JvGetChannelId(BTA_JV_CONN_TYPE_RFCOMM, (void*) slot->id, channel);
+  BTA_JvGetChannelId(BTA_JV_CONN_TYPE_RFCOMM, UINT_TO_PTR(slot->id), channel);
   *sock_fd = slot->app_fd;    // Transfer ownership of fd to caller.
   /*TODO:
    * We are leaking one of the app_fd's - either the listen socket, or the connection socket.
@@ -322,20 +323,20 @@ bt_status_t btsock_rfc_connect(const bt_bdaddr_t *bd_addr, const uint8_t *servic
 
   rfc_slot_t *slot = alloc_rfc_slot(bd_addr, NULL, service_uuid, channel, flags, false);
   if (!slot) {
-    LOG_ERROR("%s unable to allocate RFCOMM slot.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate RFCOMM slot.", __func__);
     goto out;
   }
 
   if (is_uuid_empty(service_uuid)) {
     tBTA_JV_STATUS ret = BTA_JvRfcommConnect(slot->security, slot->role, slot->scn, slot->addr.address, rfcomm_cback, (void *)(uintptr_t)slot->id);
     if (ret != BTA_JV_SUCCESS) {
-      LOG_ERROR("%s unable to initiate RFCOMM connection: %d", __func__, ret);
+      LOG_ERROR(LOG_TAG, "%s unable to initiate RFCOMM connection: %d", __func__, ret);
       cleanup_rfc_slot(slot);
       goto out;
     }
 
     if (!send_app_scn(slot)) {
-      LOG_ERROR("%s unable to send channel number.", __func__);
+      LOG_ERROR(LOG_TAG, "%s unable to send channel number.", __func__);
       cleanup_rfc_slot(slot);
       goto out;
     }
@@ -514,7 +515,7 @@ static void on_cli_rfc_connect(tBTA_JV_RFCOMM_OPEN *p_open, uint32_t id) {
   if (send_app_connect_signal(slot->fd, &slot->addr, slot->scn, 0, -1))
     slot->f.connected = true;
   else
-    LOG_ERROR("%s unable to send connect completion signal to caller.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to send connect completion signal to caller.", __func__);
 
 out:;
   pthread_mutex_unlock(&slot_lock);
@@ -595,14 +596,14 @@ static void *rfcomm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data) {
       break;
 
     default:
-      LOG_ERROR("%s unhandled event %d, slot id: %zi", __func__, event, (uintptr_t)user_data);
+      LOG_ERROR(LOG_TAG, "%s unhandled event %d, slot id: %zi", __func__, event, (uintptr_t)user_data);
       break;
   }
   return new_user_data;
 }
 
 static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data) {
-  uint32_t id = (uintptr_t)user_data;
+  uint32_t id = PTR_TO_UINT(user_data);
   switch(event) {
     case BTA_JV_GET_SCN_EVT:
     {
@@ -628,13 +629,13 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data) {
         } else {
           if(rs->is_service_uuid_valid == true) {
             // We already have data for SDP record, create it (RFC-only profiles)
-            BTA_JvCreateRecordByUser((void *)rs->id);
+            BTA_JvCreateRecordByUser(UINT_TO_PTR(rs->id));
           } else {
             APPL_TRACE_DEBUG("is_service_uuid_valid==false - don't set SDP-record, "
                     "just start the RFCOMM server", rs->id);
             //now start the rfcomm server after sdp & channel # assigned
             BTA_JvRfcommStartServer(rs->security, rs->role, rs->scn, MAX_RFC_SESSION,
-                    rfcomm_cback, (void*)rs->id);
+                    rfcomm_cback, UINT_TO_PTR(rs->id));
           }
         }
       } else if(rs) {
@@ -682,7 +683,7 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data) {
           }
         } else if (slot) {
           // TODO(sharvil): this is really a logic error and we should probably assert.
-          LOG_ERROR("%s SDP response returned but RFCOMM slot %d did not request SDP record.", __func__, id);
+          LOG_ERROR(LOG_TAG, "%s SDP response returned but RFCOMM slot %d did not request SDP record.", __func__, id);
         }
       } else if (slot) {
         cleanup_rfc_slot(slot);
@@ -725,7 +726,7 @@ static sent_status_t send_data_to_app(int fd, BT_HDR *p_buf) {
   if (sent == -1) {
     if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
       return SENT_NONE;
-    LOG_ERROR("%s error writing RFCOMM data back to app: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s error writing RFCOMM data back to app: %s", __func__, strerror(errno));
     return SENT_FAILED;
   }
 
@@ -789,7 +790,7 @@ void btsock_rfc_signaled(UNUSED_ATTR int fd, int flags, uint32_t user_id) {
         pthread_mutex_unlock(&slot_lock);
         BTA_JvRfcommWrite(slot->rfc_handle, slot->id);
     } else {
-      LOG_ERROR("%s socket signaled for read while disconnected, slot: %d, channel: %d", __func__, slot->id, slot->scn);
+      LOG_ERROR(LOG_TAG, "%s socket signaled for read while disconnected, slot: %d, channel: %d", __func__, slot->id, slot->scn);
       need_close = true;
     }
   }
@@ -797,7 +798,7 @@ void btsock_rfc_signaled(UNUSED_ATTR int fd, int flags, uint32_t user_id) {
   if (flags & SOCK_THREAD_FD_WR) {
     // App is ready to receive more data, tell stack to enable data flow.
     if (!slot->f.connected || !flush_incoming_que_on_wr_signal(slot)) {
-      LOG_ERROR("%s socket signaled for write while disconnected (or write failure), slot: %d, channel: %d", __func__, slot->id, slot->scn);
+      LOG_ERROR(LOG_TAG, "%s socket signaled for write while disconnected (or write failure), slot: %d, channel: %d", __func__, slot->id, slot->scn);
       need_close = true;
     }
   }
@@ -862,7 +863,7 @@ int bta_co_rfc_data_outgoing_size(void *user_data, int *size) {
   if (ioctl(slot->fd, FIONREAD, size) == 0) {
     ret = true;
   } else {
-    LOG_ERROR("%s unable to determine bytes remaining to be read on fd %d: %s", __func__, slot->fd, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to determine bytes remaining to be read on fd %d: %s", __func__, slot->fd, strerror(errno));
     cleanup_rfc_slot(slot);
   }
 
@@ -884,7 +885,7 @@ int bta_co_rfc_data_outgoing(void *user_data, uint8_t *buf, uint16_t size) {
   if(received == size) {
     ret = true;
   } else {
-    LOG_ERROR("%s error receiving RFCOMM data from app: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s error receiving RFCOMM data from app: %s", __func__, strerror(errno));
     cleanup_rfc_slot(slot);
   }
 
index 9012527..359a85e 100644 (file)
 
 #include <assert.h>
 #include <errno.h>
-#include <hardware/bluetooth.h>
-#include <hardware/bt_sock.h>
+#include <pthread.h>
 #include <string.h>
 #include <sys/socket.h>
 #include <sys/types.h>
+#include <unistd.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_sock.h>
 
 #include "btif_common.h"
 #include "osi/include/allocator.h"
 #include "osi/include/list.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 #include "osi/include/socket.h"
 #include "osi/include/thread.h"
 
@@ -141,25 +144,25 @@ static sco_socket_t *sco_socket_establish_locked(bool is_listening, const bt_bda
   sco_socket_t *sco_socket = NULL;
 
   if (socketpair(AF_LOCAL, SOCK_STREAM, 0, pair) == -1) {
-    LOG_ERROR("%s unable to allocate socket pair: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to allocate socket pair: %s", __func__, strerror(errno));
     goto error;
   }
 
   sco_socket = sco_socket_new();
   if (!sco_socket) {
-    LOG_ERROR("%s unable to allocate new SCO socket.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate new SCO socket.", __func__);
     goto error;
   }
 
   tBTM_STATUS status = BTM_CreateSco((uint8_t *)bd_addr, !is_listening, sco_parameters.packet_types, &sco_socket->sco_handle, connect_completed_cb, disconnect_completed_cb);
   if (status != BTM_CMD_STARTED) {
-    LOG_ERROR("%s unable to create SCO socket: %d", __func__, status);
+    LOG_ERROR(LOG_TAG, "%s unable to create SCO socket: %d", __func__, status);
     goto error;
   }
 
   socket_t *socket = socket_new_from_fd(pair[1]);
   if (!socket) {
-    LOG_ERROR("%s unable to allocate socket from file descriptor %d.", __func__, pair[1]);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate socket from file descriptor %d.", __func__, pair[1]);
     goto error;
   }
 
@@ -223,18 +226,18 @@ static void connection_request_cb(tBTM_ESCO_EVT event, tBTM_ESCO_EVT_DATA *data)
   int client_fd = INVALID_FD;
 
   if (!sco_socket) {
-    LOG_ERROR("%s unable to find sco_socket for handle: %hu", __func__, conn_data->sco_inx);
+    LOG_ERROR(LOG_TAG, "%s unable to find sco_socket for handle: %hu", __func__, conn_data->sco_inx);
     goto error;
   }
 
   if (sco_socket != listen_sco_socket) {
-    LOG_ERROR("%s received connection request on non-listening socket handle: %hu", __func__, conn_data->sco_inx);
+    LOG_ERROR(LOG_TAG, "%s received connection request on non-listening socket handle: %hu", __func__, conn_data->sco_inx);
     goto error;
   }
 
   sco_socket_t *new_sco_socket = sco_socket_establish_locked(true, NULL, &client_fd);
   if (!new_sco_socket) {
-    LOG_ERROR("%s unable to allocate new sco_socket.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate new sco_socket.", __func__);
     goto error;
   }
 
@@ -250,7 +253,7 @@ static void connection_request_cb(tBTM_ESCO_EVT event, tBTM_ESCO_EVT_DATA *data)
   connect_signal.status = 0;
 
   if (socket_write_and_transfer_fd(sco_socket->socket, &connect_signal, sizeof(connect_signal), client_fd) != sizeof(connect_signal)) {
-    LOG_ERROR("%s unable to send new file descriptor to listening socket.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to send new file descriptor to listening socket.", __func__);
     goto error;
   }
 
@@ -273,7 +276,7 @@ static void connect_completed_cb(uint16_t sco_handle) {
 
   sco_socket_t *sco_socket = sco_socket_find_locked(sco_handle);
   if (!sco_socket) {
-    LOG_ERROR("%s SCO socket not found on connect for handle: %hu", __func__, sco_handle);
+    LOG_ERROR(LOG_TAG, "%s SCO socket not found on connect for handle: %hu", __func__, sco_handle);
     goto out;
   }
 
@@ -296,7 +299,7 @@ static void disconnect_completed_cb(uint16_t sco_handle) {
 
   sco_socket_t *sco_socket = sco_socket_find_locked(sco_handle);
   if (!sco_socket) {
-    LOG_ERROR("%s SCO socket not found on disconnect for handle: %hu", __func__, sco_handle);
+    LOG_ERROR(LOG_TAG, "%s SCO socket not found on disconnect for handle: %hu", __func__, sco_handle);
     goto out;
   }
 
index c737013..9d9321d 100644 (file)
 
 #define LOG_TAG "bt_btif_sock_sdp"
 
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
+#include "btif_sock_sdp.h"
+
 #include <errno.h>
+#include <sys/socket.h>
+#include <sys/types.h>
 
 #include <hardware/bluetooth.h>
 #include <hardware/bt_sock.h>
 
+#include "../bta/pb/bta_pbs_int.h"
+#include "../include/bta_op_api.h"
+#include "bt_target.h"
+#include "bta_api.h"
+#include "bta_jv_api.h"
 #include "btif_common.h"
-#include "btif_util.h"
 #include "btif_sock_util.h"
-#include "bta_api.h"
-#include "bt_target.h"
+#include "btif_util.h"
+#include "btm_api.h"
+#include "btm_int.h"
+#include "btu.h"
 #include "gki.h"
 #include "hcimsgs.h"
 #include "sdp_api.h"
-#include "btu.h"
-#include "btm_api.h"
-#include "btm_int.h"
-#include "btif_sock_sdp.h"
 #include "utl.h"
-#include "../bta/pb/bta_pbs_int.h"
-#include "../include/bta_op_api.h"
-#include "bta_jv_api.h"
 
 // This module provides an abstraction on top of the lower-level SDP database
 // code for registration and discovery of various bluetooth sockets.
@@ -93,8 +91,6 @@ static const tBTA_OP_FMT bta_ops_obj_fmt[OBEX_PUSH_NUM_FORMATS] = {
                           | BTA_OP_ANY_MASK)
 #endif
 
-
-
 #define RESERVED_SCN_PBS 19
 #define RESERVED_SCN_OPS 12
 
@@ -202,7 +198,6 @@ static int add_sdp_by_uuid(const char *name,  const uint8_t *uuid,
                        1, &type, &type_len, &type_buf_ptr))
     goto error;
 
-
   APPL_TRACE_DEBUG("add_sdp_by_uuid: service registered successfully, "
                    "service_name: %s, handle: 0x%08x", name, handle);
   return handle;
index 459aeba..e9e745c 100644 (file)
  *
  ***********************************************************************************/
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_sock.h>
+#define LOG_TAG "bt_btif_sock"
 
-//bta_jv_co_rfc_data
-#include <stdio.h>
-#include <stdlib.h>
+#include "btif_sock_thread.h"
+
+#include <alloca.h>
+#include <ctype.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <features.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-#include <sys/types.h>
+#include <sys/poll.h>
+#include <sys/select.h>
 #include <sys/socket.h>
+#include <sys/types.h>
 #include <sys/un.h>
 #include <time.h>
-#include <fcntl.h>
 #include <unistd.h>
-#include <signal.h>
-#include <pthread.h>
-#include <ctype.h>
-
-#include <sys/select.h>
-#include <sys/poll.h>
-#include <cutils/sockets.h>
-#include <alloca.h>
-
-#define LOG_TAG "bt_btif_sock"
-#include "btif_common.h"
-#include "btif_util.h"
-
 
 #include "bta_api.h"
+#include "btif_common.h"
 #include "btif_sock.h"
-#include "btif_sock_thread.h"
 #include "btif_sock_util.h"
+#include "btif_util.h"
+#include "osi/include/socket_utils/sockets.h"
 
 #define asrt(s) if(!(s)) APPL_TRACE_ERROR("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__)
 #define print_events(events) do { \
@@ -102,8 +97,6 @@ typedef struct {
 } thread_slot_t;
 static thread_slot_t ts[MAX_THREAD];
 
-
-
 static void *sock_poll_thread(void *arg);
 static inline void close_cmd_fd(int h);
 
@@ -129,7 +122,7 @@ static inline int create_server_socket(const char* name)
     if(s < 0)
         return -1;
     APPL_TRACE_DEBUG("covert name to android abstract name:%s", name);
-    if(socket_local_server_bind(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT) >= 0)
+    if(osi_socket_local_server_bind(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT) >= 0)
     {
         if(listen(s, 5) == 0)
         {
@@ -148,7 +141,7 @@ static inline int connect_server_socket(const char* name)
     if(s < 0)
         return -1;
     set_socket_blocking(s, TRUE);
-    if(socket_local_client_connect(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) >= 0)
+    if(osi_socket_local_client_connect(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) >= 0)
     {
         APPL_TRACE_DEBUG("connected to local socket:%s, fd:%d", name, s);
         return s;
index baa3ed3..ab2fd7a 100644 (file)
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_btif_sock"
 
-/************************************************************************************
- *
- *  Filename:      btif_hf.c
- *
- *  Description:   Handsfree Profile Bluetooth Interface
- *
- *
- ***********************************************************************************/
-#include <hardware/bluetooth.h>
-#include <hardware/bt_sock.h>
+#include "btif_sock_util.h"
+
+#include <arpa/inet.h>
 #include <errno.h>
-#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-#include <sys/types.h>
+#include <sys/ioctl.h>
 #include <sys/socket.h>
+#include <sys/types.h>
 #include <sys/un.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <stdlib.h>
-#include <errno.h>
 #include <unistd.h>
-#include <sys/ioctl.h>
-
-#include <cutils/sockets.h>
-#include <netinet/tcp.h>
 
+#include <hardware/bluetooth.h>
+#include <hardware/bt_sock.h>
 
-#define LOG_TAG "bt_btif_sock"
-#include "btif_common.h"
-#include "btif_util.h"
-
+#include "bt_target.h"
 #include "bta_api.h"
-#include "btif_sock_thread.h"
+#include "bta_jv_api.h"
+#include "bta_jv_co.h"
+#include "btif_common.h"
 #include "btif_sock_sdp.h"
-
-#include "bt_target.h"
-#include "gki.h"
-#include "hcimsgs.h"
-#include "sdp_api.h"
-#include "btu.h"
+#include "btif_sock_thread.h"
+#include "btif_util.h"
 #include "btm_api.h"
 #include "btm_int.h"
-#include "bta_jv_api.h"
-#include "bta_jv_co.h"
-#include "port_api.h"
+#include "btu.h"
+#include "gki.h"
+#include "hcimsgs.h"
 #include "osi/include/log.h"
+#include "port_api.h"
+#include "sdp_api.h"
 
 #define asrt(s) if(!(s)) BTIF_TRACE_ERROR("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__)
 
-
 int sock_send_all(int sock_fd, const uint8_t* buf, int len)
 {
     int s = len;
@@ -163,8 +150,6 @@ int sock_send_fd(int sock_fd, const uint8_t* buf, int len, int send_fd)
     return ret_len;
 }
 
-
-#define PRINT(s) __android_log_write(ANDROID_LOG_DEBUG, NULL, s)
 static const char* hex_table = "0123456789abcdef";
 static inline void byte2hex(const char* data, char** str)
 {
@@ -189,7 +174,7 @@ void dump_bin(const char* title, const char* data, int size)
     char *line;
     int i, j, addr;
     const int width = 16;
-    LOG_DEBUG("%s, size:%d, dump started {", title, size);
+    LOG_DEBUG(LOG_TAG, "%s, size:%d, dump started {", title, size);
     if(size <= 0)
         return;
     //write offset
@@ -206,7 +191,7 @@ void dump_bin(const char* title, const char* data, int size)
         *line++ = ' ';
     }
     *line = 0;
-    PRINT(line_buff);
+    LOG_DEBUG(LOG_TAG, "%s", line_buff);
 
     for(i = 0; i < size / width; i++)
     {
@@ -227,7 +212,7 @@ void dump_bin(const char* title, const char* data, int size)
         //wirte the end of line
         *line = 0;
         //output the line
-        PRINT(line_buff);
+        LOG_DEBUG(LOG_TAG, "%s", line_buff);
     }
     //last line of left over if any
     int leftover = size % width;
@@ -255,8 +240,8 @@ void dump_bin(const char* title, const char* data, int size)
         //write the end of line
         *line = 0;
         //output the line
-        PRINT(line_buff);
+        LOG_DEBUG(LOG_TAG, "%s", line_buff);
     }
-    LOG_DEBUG("%s, size:%d, dump ended }", title, size);
+    LOG_DEBUG(LOG_TAG, "%s, size:%d, dump ended }", title, size);
 }
 
index 687af94..976260b 100644 (file)
  *
  *
  */
+
+#define LOG_TAG "bt_btif_storage"
+
+#include "btif_storage.h"
+
+#include <alloca.h>
 #include <assert.h>
+#include <ctype.h>
 #include <stdlib.h>
-#include <time.h>
 #include <string.h>
-#include <ctype.h>
-#include <alloca.h>
-
-
-#include <hardware/bluetooth.h>
-#include "btif_config.h"
-#define LOG_TAG "bt_btif_storage"
+#include <time.h>
 
+#include "bta_hh_api.h"
+#include "btcore/include/bdaddr.h"
 #include "btif_api.h"
-#include "btif_storage.h"
+#include "btif_config.h"
+#include "btif_hh.h"
 #include "btif_util.h"
-#include "btcore/include/bdaddr.h"
+#include "gki.h"
 #include "osi/include/allocator.h"
 #include "osi/include/compat.h"
 #include "osi/include/config.h"
-#include "gki.h"
-#include "osi/include/osi.h"
-#include "bta_hh_api.h"
-#include "btif_hh.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 
 /************************************************************************************
 **  Constants & Macros
 ************************************************************************************/
 
+// TODO(armansito): Find a better way than using a hardcoded path.
 #define BTIF_STORAGE_PATH_BLUEDROID "/data/misc/bluedroid"
 
 //#define BTIF_STORAGE_PATH_ADAPTER_INFO "adapter_info"
 #define BTIF_STORAGE_KEY_ADAPTER_SCANMODE "ScanMode"
 #define BTIF_STORAGE_KEY_ADAPTER_DISC_TIMEOUT "DiscoveryTimeout"
 
-
-#define BTIF_AUTO_PAIR_CONF_FILE  "/etc/bluetooth/auto_pair_devlist.conf"
+#if defined(OS_GENERIC)
+// TODO(armansito): Find a better way than searching by a hardcoded path.
+#define BTIF_AUTO_PAIR_CONF_FILE "auto_pair_devlist.conf"
+#else  // !defined(OS_GENERIC)
+#define BTIF_AUTO_PAIR_CONF_FILE "/etc/bluetooth/auto_pair_devlist.conf"
+#endif  // defined(OS_GENERIC)
 #define BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST "AutoPairBlacklist"
 #define BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_ADDR "AddressBlacklist"
 #define BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_EXACTNAME "ExactNameBlacklist"
@@ -87,7 +92,6 @@
 
 #define BTIF_AUTO_PAIR_CONF_VALUE_SEPARATOR ","
 
-
 /* This is a local property to add a device found */
 #define BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP 0xFF
 
                                          STORAGE_HID_DESC_LEN_SIZE+ 1 +\
                                          STORAGE_HID_DESC_MAX_SIZE+ 1 )
 
-
 /* currently remote services is the potentially largest entry */
 #define BTIF_STORAGE_MAX_LINE_SZ BTIF_REMOTE_SERVICES_ENTRY_SIZE_MAX
 
-
 /* check against unv max entry size at compile time */
 #if (BTIF_STORAGE_ENTRY_MAX_SIZE > UNV_MAXLINE_LENGTH)
     #error "btif storage entry size exceeds unv max line size"
 #endif
 
-
 #define BTIF_STORAGE_HL_APP          "hl_app"
 #define BTIF_STORAGE_HL_APP_CB       "hl_app_cb"
 #define BTIF_STORAGE_HL_APP_DATA     "hl_app_data_"
@@ -641,7 +642,7 @@ bt_status_t btif_storage_get_adapter_property(bt_property_t *property)
         uint32_t i;
 
         tBTA_SERVICE_MASK service_mask = btif_get_enabled_services_mask();
-        LOG_INFO("%s service_mask:0x%x", __FUNCTION__, service_mask);
+        LOG_INFO(LOG_TAG, "%s service_mask:0x%x", __FUNCTION__, service_mask);
         for (i=0; i < BTA_MAX_SERVICE_ID; i++)
         {
             /* This should eventually become a function when more services are enabled */
@@ -1198,7 +1199,6 @@ bt_status_t btif_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add,
 {
     int device_type;
     int addr_type;
-    UINT32 i;
     bt_bdaddr_t bd_addr;
     BD_ADDR bta_bd_addr;
     bool device_added = false;
@@ -1483,7 +1483,6 @@ bt_status_t btif_storage_read_hl_apps_cb(char *value, int value_size)
     return bt_status;
 }
 
-
 /*******************************************************************************
 **
 ** Function         btif_storage_load_autopair_device_list
@@ -1510,7 +1509,7 @@ bt_status_t btif_storage_load_autopair_device_list() {
 
     config_t *config = config_new(BTIF_AUTO_PAIR_CONF_FILE);
     if (!config) {
-        LOG_ERROR("%s failed to open auto pair blacklist conf file '%s'.", __func__, BTIF_AUTO_PAIR_CONF_FILE);
+        LOG_ERROR(LOG_TAG, "%s failed to open auto pair blacklist conf file '%s'.", __func__, BTIF_AUTO_PAIR_CONF_FILE);
         return BT_STATUS_FAIL;
     }
 
index 42576eb..eb94eee 100644 (file)
  *
  ***********************************************************************************/
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_hf.h>
-#include <hardware/bt_av.h>
+#define LOG_TAG "bt_btif_util"
+
+#include "btif_util.h"
+
+#include <ctype.h>
 #include <netinet/in.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 
+#include <hardware/bt_av.h>
 
-#define LOG_TAG "bt_btif_util"
-#include "btif_common.h"
-#include "bta_api.h"
-#include "gki.h"
-#include "btu.h"
-#include "bte.h"
-#include "btif_dm.h"
-#include "btif_util.h"
+#include "avrc_defs.h"
 #include "bta_ag_api.h"
+#include "bta_api.h"
 #include "bta_av_api.h"
-#include "bta_hh_api.h"
 #include "bta_hf_client_api.h"
-#include "avrc_defs.h"
+#include "bta_hh_api.h"
+#include "bte.h"
+#include "btif_common.h"
+#include "btif_dm.h"
+#include "btu.h"
+#include "gki.h"
 
 /************************************************************************************
 **  Constants & Macros
@@ -191,7 +191,6 @@ int ascii_2_hex (char *p_ascii, int len, UINT8 *p_hex)
     return (x);
 }
 
-
 const char* dump_dm_search_event(UINT16 event)
 {
     switch(event)
@@ -209,7 +208,6 @@ const char* dump_dm_search_event(UINT16 event)
      }
 }
 
-
 const char* dump_property_type(bt_property_type_t type)
 {
     switch(type)
@@ -364,7 +362,6 @@ const char* dump_hh_event(UINT16 event)
      }
 }
 
-
 const char* dump_hf_conn_state(UINT16 event)
 {
     switch(event)
@@ -407,7 +404,6 @@ const char* dump_thread_evt(bt_cb_thread_evt evt)
     }
 }
 
-
 const char* dump_hf_audio_state(UINT16 event)
 {
     switch(event)
index 817e46f..0f80657 100644 (file)
 
 #define LOG_TAG "bt_stack_manager"
 
+#include "stack_manager.h"
+
 #include <hardware/bluetooth.h>
 
+#include "btcore/include/module.h"
+#include "btcore/include/osi_module.h"
 #include "btif_api.h"
 #include "btif_common.h"
 #include "device/include/controller.h"
-#include "btcore/include/module.h"
-#include "btcore/include/osi_module.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 #include "osi/include/semaphore.h"
-#include "stack_manager.h"
 #include "osi/include/thread.h"
 
 // Temp includes
@@ -108,7 +109,7 @@ static void event_init_stack(void *context) {
 
 static void ensure_stack_is_initialized(void) {
   if (!stack_is_initialized) {
-    LOG_WARN("%s found the stack was uninitialized. Initializing now.", __func__);
+    LOG_WARN(LOG_TAG, "%s found the stack was uninitialized. Initializing now.", __func__);
     // No semaphore needed since we are calling it directly
     event_init_stack(NULL);
   }
@@ -117,13 +118,13 @@ static void ensure_stack_is_initialized(void) {
 // Synchronous function to start up the stack
 static void event_start_up_stack(UNUSED_ATTR void *context) {
   if (stack_is_running) {
-    LOG_DEBUG("%s stack already brought up.", __func__);
+    LOG_DEBUG(LOG_TAG, "%s stack already brought up.", __func__);
     return;
   }
 
   ensure_stack_is_initialized();
 
-  LOG_DEBUG("%s is bringing up the stack.", __func__);
+  LOG_DEBUG(LOG_TAG, "%s is bringing up the stack.", __func__);
   hack_future = future_new();
 
   // Include this for now to put btif config into a shutdown-able state
@@ -137,18 +138,18 @@ static void event_start_up_stack(UNUSED_ATTR void *context) {
   }
 
   stack_is_running = true;
-  LOG_DEBUG("%s finished", __func__);
+  LOG_DEBUG(LOG_TAG, "%s finished", __func__);
   btif_thread_post(event_signal_stack_up, NULL);
 }
 
 // Synchronous function to shut down the stack
 static void event_shut_down_stack(UNUSED_ATTR void *context) {
   if (!stack_is_running) {
-    LOG_DEBUG("%s stack is already brought down.", __func__);
+    LOG_DEBUG(LOG_TAG, "%s stack is already brought down.", __func__);
     return;
   }
 
-  LOG_DEBUG("%s is bringing down the stack.", __func__);
+  LOG_DEBUG(LOG_TAG, "%s is bringing down the stack.", __func__);
   hack_future = future_new();
   stack_is_running = false;
 
@@ -158,13 +159,13 @@ static void event_shut_down_stack(UNUSED_ATTR void *context) {
   future_await(hack_future);
   module_shut_down(get_module(CONTROLLER_MODULE)); // Doesn't do any work, just puts it in a restartable state
 
-  LOG_DEBUG("%s finished.", __func__);
+  LOG_DEBUG(LOG_TAG, "%s finished.", __func__);
   btif_thread_post(event_signal_stack_down, NULL);
 }
 
 static void ensure_stack_is_not_running(void) {
   if (stack_is_running) {
-    LOG_WARN("%s found the stack was still running. Bringing it down now.", __func__);
+    LOG_WARN(LOG_TAG, "%s found the stack was still running. Bringing it down now.", __func__);
     event_shut_down_stack(NULL);
   }
 }
@@ -172,13 +173,13 @@ static void ensure_stack_is_not_running(void) {
 // Synchronous function to clean up the stack
 static void event_clean_up_stack(UNUSED_ATTR void *context) {
   if (!stack_is_initialized) {
-    LOG_DEBUG("%s found the stack already in a clean state.", __func__);
+    LOG_DEBUG(LOG_TAG, "%s found the stack already in a clean state.", __func__);
     return;
   }
 
   ensure_stack_is_not_running();
 
-  LOG_DEBUG("%s is cleaning up the stack.", __func__);
+  LOG_DEBUG(LOG_TAG, "%s is cleaning up the stack.", __func__);
   hack_future = future_new();
   stack_is_initialized = false;
 
@@ -189,7 +190,7 @@ static void event_clean_up_stack(UNUSED_ATTR void *context) {
   future_await(hack_future);
   module_clean_up(get_module(OSI_MODULE));
   module_management_stop();
-  LOG_DEBUG("%s finished.", __func__);
+  LOG_DEBUG(LOG_TAG, "%s finished.", __func__);
 }
 
 static void event_signal_stack_up(UNUSED_ATTR void *context) {
@@ -209,7 +210,7 @@ static void ensure_manager_initialized(void) {
 
   management_thread = thread_new("stack_manager");
   if (!management_thread) {
-    LOG_ERROR("%s unable to create stack management thread.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create stack management thread.", __func__);
     return;
   }
 }
diff --git a/build/BUILD.gn b/build/BUILD.gn
new file mode 100644 (file)
index 0000000..fb20a34
--- /dev/null
@@ -0,0 +1,77 @@
+#
+#  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.
+#
+
+declare_args() {
+  # Include path for hardware/bluetooth.h
+  libhw_include_path = ""
+  core_include_path = ""
+}
+
+config("default_include_dirs") {
+  # TODO(armansito): Remove "core_include_path" once the cutils includes have
+  # been removed.
+  assert(libhw_include_path != "", "libhardware_include_path build argument wasn't provided.")
+  assert(core_include_path != "", "core_include_path build argument wasn't provided.")
+  include_dirs = [
+    libhw_include_path,
+    core_include_path,
+  ]
+}
+
+config("linux") {
+  # TODO(keybuk): AndroidConfig.h or equivalent
+
+  cflags = [
+    "-Wall",
+    "-Werror",
+    "-g",
+    "-O0",
+    "-fpic",
+    "-fdata-sections",
+    "-ffunction-sections",
+    "-fvisibility=hidden",
+  ]
+
+  cflags_c = [
+    "-std=c99"
+  ]
+
+  cflags_cc = [
+    "-std=c++11",
+    "-fno-exceptions",
+  ]
+
+  defines = [
+    "_FORTIFY_SOURCE=2",
+    "_GNU_SOURCE",
+    "HAS_NO_BDROID_BUILDCFG",
+    "LOG_NDEBUG=1",
+    "EXPORT_SYMBOL=__attribute__((visibility(\"default\")))",
+
+    # This is a macro to that can be used by source code to detect if the
+    # current build is done by GN or via Android.mk. This is a temporary
+    # workaround until we can remove all Android-specific dependencies.
+    "OS_GENERIC",
+  ]
+}
+
+config("pic") {
+  cflags = [ "-fPIC" ]
+}
+
+config("gc") {
+  ldflags = [ "-Wl,--gc-sections" ]
+}
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
new file mode 100644 (file)
index 0000000..419d62f
--- /dev/null
@@ -0,0 +1,49 @@
+#
+#  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.
+#
+
+set_default_toolchain("//build/toolchain/gcc")
+
+set_defaults("executable") {
+  configs = [
+    "//build:linux",
+    "//build:gc",
+    "//build:default_include_dirs",
+  ]
+}
+
+set_defaults("shared_library") {
+  configs = [
+    "//build:linux",
+    "//build:gc",
+    "//build:default_include_dirs",
+  ]
+}
+
+set_defaults("source_set") {
+  configs = [
+    "//build:linux",
+    "//build:gc",
+    "//build:default_include_dirs",
+  ]
+}
+
+set_defaults("static_library") {
+  configs = [
+    "//build:linux",
+    "//build:gc",
+    "//build:default_include_dirs",
+  ]
+}
diff --git a/build/secondary/third_party/gtest/BUILD.gn b/build/secondary/third_party/gtest/BUILD.gn
new file mode 100644 (file)
index 0000000..c1112d9
--- /dev/null
@@ -0,0 +1,77 @@
+#
+#  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.
+#
+
+config("gtest_config") {
+  # Gtest headers need to be able to find themselves.
+  include_dirs = [ "include" ]
+
+  defines = [ "GTEST_HAS_RTTI=0" ]
+}
+
+config("gtest_direct_config") {
+  visibility = [ ":*" ]
+  defines = [ "UNIT_TEST" ]
+}
+
+static_library("gtest") {
+  testonly = true
+  sources = [
+    "include/gtest/gtest-death-test.h",
+    "include/gtest/gtest-message.h",
+    "include/gtest/gtest-param-test.h",
+    "include/gtest/gtest-printers.h",
+    "include/gtest/gtest-spi.h",
+    "include/gtest/gtest-test-part.h",
+    "include/gtest/gtest-typed-test.h",
+    "include/gtest/gtest.h",
+    "include/gtest/gtest_pred_impl.h",
+    "include/gtest/internal/gtest-death-test-internal.h",
+    "include/gtest/internal/gtest-filepath.h",
+    "include/gtest/internal/gtest-internal.h",
+    "include/gtest/internal/gtest-linked_ptr.h",
+    "include/gtest/internal/gtest-param-util-generated.h",
+    "include/gtest/internal/gtest-param-util.h",
+    "include/gtest/internal/gtest-port.h",
+    "include/gtest/internal/gtest-string.h",
+    "include/gtest/internal/gtest-tuple.h",
+    "include/gtest/internal/gtest-type-util.h",
+
+    "src/gtest-all.cc",
+    "src/gtest-death-test.cc",
+    "src/gtest-filepath.cc",
+    "src/gtest-internal-inl.h",
+    "src/gtest-port.cc",
+    "src/gtest-printers.cc",
+    "src/gtest-test-part.cc",
+    "src/gtest-typed-test.cc",
+    "src/gtest.cc",
+  ]
+
+  include_dirs = [ "." ]
+
+  all_dependent_configs = [ ":gtest_config" ]
+  public_configs = [ ":gtest_direct_config" ]
+}
+
+source_set("gtest_main") {
+  testonly = true
+  sources = [
+    "src/gtest_main.cc",
+  ]
+  deps = [
+    ":gtest",
+  ]
+}
diff --git a/build/secondary/third_party/libchrome/BUILD.gn b/build/secondary/third_party/libchrome/BUILD.gn
new file mode 100644 (file)
index 0000000..4d1b6bd
--- /dev/null
@@ -0,0 +1,228 @@
+#
+#  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.
+#
+
+source_set("base_sources") {
+  sources = [
+    "base/allocator/type_profiler_control.cc",
+    "base/at_exit.cc",
+    "base/atomic_ref_count.h",
+    "base/atomic_sequence_num.h",
+    "base/atomicops.h",
+    "base/atomicops_internals_x86_gcc.cc",
+    "base/base64.cc",
+    "base/base64.h",
+    "base/base_export.h",
+    "base/base_switches.cc",
+    "base/bind_helpers.cc",
+    "base/build_time.cc",
+    "base/callback_helpers.cc",
+    "base/callback_internal.cc",
+    "base/command_line.cc",
+    "base/cpu.cc",
+    "base/debug/alias.cc",
+    "base/debug/debugger.cc",
+    "base/debug/debugger_posix.cc",
+    "base/debug/stack_trace.cc",
+    "base/debug/stack_trace_posix.cc",
+    "base/debug/task_annotator.cc",
+    "base/environment.cc",
+    "base/files/file.cc",
+    "base/files/file_enumerator.cc",
+    "base/files/file_enumerator_posix.cc",
+    "base/files/file_path.cc",
+    "base/files/file_path_constants.cc",
+    "base/files/file_path_watcher.cc",
+    "base/files/file_path_watcher_linux.cc",
+    "base/files/file_posix.cc",
+    "base/files/file_tracing.cc",
+    "base/files/file_util.cc",
+    "base/files/file_util_linux.cc",
+    "base/files/file_util_posix.cc",
+    "base/files/important_file_writer.cc",
+    "base/files/scoped_file.cc",
+    "base/files/scoped_temp_dir.cc",
+    "base/guid.cc",
+    "base/guid_posix.cc",
+    "base/hash.cc",
+    "base/json/json_parser.cc",
+    "base/json/json_reader.cc",
+    "base/json/json_string_value_serializer.cc",
+    "base/json/json_writer.cc",
+    "base/json/string_escape.cc",
+    "base/lazy_instance.cc",
+    "base/location.cc",
+    "base/logging.cc",
+    "base/md5.cc",
+    "base/memory/ref_counted.cc",
+    "base/memory/ref_counted_memory.cc",
+    "base/memory/singleton.cc",
+    "base/memory/weak_ptr.cc",
+    "base/message_loop/incoming_task_queue.cc",
+    "base/message_loop/message_loop.cc",
+    "base/message_loop/message_loop_proxy.cc",
+    "base/message_loop/message_loop_proxy_impl.cc",
+    "base/message_loop/message_pump.cc",
+    "base/message_loop/message_pump_default.cc",
+    "base/message_loop/message_pump_libevent.cc",
+    "base/metrics/bucket_ranges.cc",
+    "base/metrics/field_trial.cc",
+    "base/metrics/histogram_base.cc",
+    "base/metrics/histogram.cc",
+    "base/metrics/histogram_samples.cc",
+    "base/metrics/histogram_snapshot_manager.cc",
+    "base/metrics/sample_map.cc",
+    "base/metrics/sample_vector.cc",
+    "base/metrics/sparse_histogram.cc",
+    "base/metrics/statistics_recorder.cc",
+    "base/pending_task.cc",
+    "base/pickle.cc",
+    "base/posix/file_descriptor_shuffle.cc",
+    "base/posix/safe_strerror.cc",
+    "base/posix/unix_domain_socket_linux.cc",
+    "base/process/internal_linux.cc",
+    "base/process/kill.cc",
+    "base/process/kill_posix.cc",
+    "base/process/launch.cc",
+    "base/process/launch_posix.cc",
+    "base/process/process_handle_linux.cc",
+    "base/process/process_handle_posix.cc",
+    "base/process/process_iterator.cc",
+    "base/process/process_iterator_linux.cc",
+    "base/process/process_metrics.cc",
+    "base/process/process_metrics_linux.cc",
+    "base/process/process_metrics_posix.cc",
+    "base/process/process_posix.cc",
+    "base/profiler/alternate_timer.cc",
+    "base/profiler/scoped_profile.cc",
+    "base/profiler/scoped_tracker.cc",
+    "base/profiler/tracked_time.cc",
+    "base/rand_util.cc",
+    "base/rand_util_posix.cc",
+    "base/run_loop.cc",
+    "base/sequence_checker_impl.cc",
+    "base/sequenced_task_runner.cc",
+    "base/sha1_portable.cc",
+    "base/strings/safe_sprintf.cc",
+    "base/strings/string16.cc",
+    "base/strings/string_number_conversions.cc",
+    "base/strings/string_piece.cc",
+    "base/strings/stringprintf.cc",
+    "base/strings/string_split.cc",
+    "base/strings/string_util.cc",
+    "base/strings/string_util_constants.cc",
+    "base/strings/sys_string_conversions_posix.cc",
+    "base/strings/utf_string_conversions.cc",
+    "base/strings/utf_string_conversion_utils.cc",
+    "base/synchronization/cancellation_flag.cc",
+    "base/synchronization/condition_variable_posix.cc",
+    "base/synchronization/lock.cc",
+    "base/synchronization/lock_impl_posix.cc",
+    "base/synchronization/waitable_event_posix.cc",
+    "base/sync_socket_posix.cc",
+    "base/sys_info.cc",
+    # TODO(armansito): For our GN builds these platform-specific implementations
+    # don't really make that much sense but instead of removing the line I'm
+    # commenting it out in case we want to re-add it later (it's included in the
+    # libchrome Android.mk).
+    #"sys_info_chromeos.cc",
+    "base/sys_info_linux.cc",
+    "base/sys_info_posix.cc",
+    "base/task/cancelable_task_tracker.cc",
+    "base/task_runner.cc",
+    "base/third_party/dmg_fp/dtoa.cc",
+    "base/third_party/dmg_fp/g_fmt.cc",
+    "base/third_party/dynamic_annotations/dynamic_annotations.c",
+    "base/third_party/icu/icu_utf.cc",
+    "base/third_party/nspr/prtime.cc",
+    "base/third_party/superfasthash/superfasthash.c",
+    "base/threading/non_thread_safe_impl.cc",
+    "base/threading/platform_thread_internal_posix.cc",
+    "base/threading/platform_thread_linux.cc",
+    "base/threading/platform_thread_posix.cc",
+    "base/threading/post_task_and_reply_impl.cc",
+    "base/threading/sequenced_worker_pool.cc",
+    "base/threading/simple_thread.cc",
+    "base/threading/thread.cc",
+    "base/threading/thread_checker_impl.cc",
+    "base/threading/thread_collision_warner.cc",
+    "base/threading/thread_id_name_manager.cc",
+    "base/threading/thread_local_posix.cc",
+    "base/threading/thread_local_storage.cc",
+    "base/threading/thread_local_storage_posix.cc",
+    "base/threading/thread_restrictions.cc",
+    "base/threading/worker_pool.cc",
+    "base/threading/worker_pool_posix.cc",
+    "base/thread_task_runner_handle.cc",
+    "base/time/clock.cc",
+    "base/time/default_clock.cc",
+    "base/time/default_tick_clock.cc",
+    "base/timer/elapsed_timer.cc",
+    "base/timer/timer.cc",
+    "base/time/tick_clock.cc",
+    "base/time/time.cc",
+    "base/time/time_posix.cc",
+    "base/trace_event/malloc_dump_provider.cc",
+    "base/trace_event/memory_allocator_dump.cc",
+    "base/trace_event/memory_allocator_dump_guid.cc",
+    "base/trace_event/memory_dump_manager.cc",
+    "base/trace_event/memory_dump_session_state.cc",
+    "base/trace_event/process_memory_dump.cc",
+    "base/trace_event/process_memory_maps.cc",
+    "base/trace_event/process_memory_maps_dump_provider.cc",
+    "base/trace_event/process_memory_totals.cc",
+    "base/trace_event/process_memory_totals_dump_provider.cc",
+    "base/trace_event/trace_config.cc",
+    "base/trace_event/trace_event_argument.cc",
+    "base/trace_event/trace_event_impl.cc",
+    "base/trace_event/trace_event_impl_constants.cc",
+    "base/trace_event/trace_event_memory.cc",
+    "base/trace_event/trace_event_memory_overhead.cc",
+    "base/trace_event/trace_event_synthetic_delay.cc",
+    "base/tracked_objects.cc",
+    "base/tracking_info.cc",
+    "base/values.cc",
+    "base/vlog.cc",
+  ]
+
+  defines = [ "BASE_IMPLEMENTATION" ]
+
+  include_dirs = [
+    "//",
+    "//third_party/libchrome",
+    "//third_party/libchrome/base",
+    "//third_party/modp_b64",
+  ]
+}
+
+static_library("base") {
+  deps = [
+    ":base_sources",
+  ]
+
+  cflags = [
+    "-Wno-char-subscripts",
+    "-Wno-missing-field-initializers",
+    "-Wno-unused-function",
+    "-Wno-unused_parameter",
+  ]
+  cflags_cc = [
+    "-Wno-deprecated-register",
+    "-Wno-non-virtual-dtor",
+    "-Wno-sign-promo",
+  ]
+
+  libs = [ "-levent", "-levent_core", "-lpthread" ]
+}
diff --git a/build/secondary/third_party/tinyxml2/BUILD.gn b/build/secondary/third_party/tinyxml2/BUILD.gn
new file mode 100644 (file)
index 0000000..335960b
--- /dev/null
@@ -0,0 +1,23 @@
+#
+#  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.
+#
+
+static_library("tinyxml2") {
+  sources = [
+    "tinyxml2.cpp"
+  ]
+
+  include_dirs = [ "." ]
+}
diff --git a/build/toolchain/gcc/BUILD.gn b/build/toolchain/gcc/BUILD.gn
new file mode 100644 (file)
index 0000000..ecf9057
--- /dev/null
@@ -0,0 +1,96 @@
+#
+#  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.
+#
+cc = "gcc"
+cxx = "g++"
+
+toolchain("gcc") {
+  tool("cc") {
+    depfile = "{{output}}.d"
+    command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
+    depsformat = "gcc"
+    description = "CC {{output}}"
+    outputs = [
+      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
+    ]
+  }
+
+  tool("cxx") {
+    depfile = "{{output}}.d"
+    command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
+    depsformat = "gcc"
+    description = "CXX {{output}}"
+    outputs = [
+      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
+    ]
+  }
+
+  tool("alink") {
+    rspfile = "{{output}}.rsp"
+    command = "rm -f {{output}} && ar rcs {{output}} @$rspfile"
+    description = "AR {{target_output_name}}{{output_extension}}"
+    rspfile_content = "{{inputs}}"
+    outputs = [
+      "{{target_out_dir}}/{{target_output_name}}{{output_extension}}",
+    ]
+    default_output_extension = ".a"
+
+    output_prefix = "lib"
+  }
+
+  tool("solink") {
+    soname = "{{target_output_name}}{{output_extension}}"  # e.g. "libfoo.so".
+    rspfile = soname + ".rsp"
+
+    command = "$cxx -shared {{ldflags}} -o $soname -Wl,-soname=$soname @$rspfile"
+    rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}"
+
+    description = "SOLINK $soname"
+
+    # Use this for {{output_extension}} expansions unless a target manually
+    # overrides it (in which case {{output_extension}} will be what the target
+    # specifies).
+    default_output_extension = ".so"
+
+    outputs = [
+      soname,
+    ]
+    link_output = soname
+    depend_output = soname
+
+    output_prefix = "lib"
+  }
+
+  tool("link") {
+    outfile = "{{target_output_name}}{{output_extension}}"
+    rspfile = "$outfile.rsp"
+    command = "$cxx {{ldflags}} -o $outfile -Wl,--start-group @$rspfile {{solibs}} -Wl,--end-group {{libs}}"
+    description = "LINK $outfile"
+    rspfile_content = "{{inputs}}"
+    outputs = [
+      outfile,
+    ]
+  }
+
+  tool("stamp") {
+    command = "touch {{output}}"
+    description = "STAMP {{output}}"
+  }
+
+  tool("copy") {
+    command = "cp -af {{source}} {{output}}"
+    description = "COPY {{source}} {{output}}"
+  }
+}
diff --git a/device/BUILD.gn b/device/BUILD.gn
new file mode 100644 (file)
index 0000000..1ca0288
--- /dev/null
@@ -0,0 +1,54 @@
+#
+#  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.
+#
+
+static_library("device") {
+  sources = [
+    "src/classic/peer.c",
+    "src/controller.c"
+  ]
+
+  include_dirs = [
+    "//",
+    "//btcore/include",
+    "//gki/common",
+    "//hci/include",
+    "//include",
+    "//osi/include",
+    "//stack/include",
+  ]
+}
+
+executable("net_test_device") {
+  testonly = true
+  sources = [
+    "//osi/test/AllocationTestHarness.cpp",
+    "test/classic/peer_test.cpp",
+  ]
+
+  include_dirs = [
+    "//",
+    "//osi/include",
+  ]
+
+  deps = [
+    "//device",
+    "//btcore",
+    "//osi",
+    "//third_party/gtest:gtest_main",
+  ]
+
+  libs = [ "-lpthread", "-lrt", "-ldl" ]
+}
index 6d1a7b5..1bab300 100644 (file)
 
 #define LOG_TAG "bt_classic_peer"
 
+#include "device/include/classic/peer.h"
+
 #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"
@@ -68,7 +69,7 @@ static future_t *clean_up(void) {
   return NULL;
 }
 
-const module_t classic_peer_module = {
+EXPORT_SYMBOL const module_t classic_peer_module = {
   .name = CLASSIC_PEER_MODULE,
   .init = init,
   .start_up = NULL,
index 1938f09..0041df8 100644 (file)
 
 #define LOG_TAG "bt_controller"
 
+#include "device/include/controller.h"
+
 #include <assert.h>
-#include <stdbool.h>
 
-#include "btcore/include/bdaddr.h"
 #include "bt_types.h"
-#include "device/include/controller.h"
 #include "btcore/include/event_mask.h"
-#include "osi/include/future.h"
-#include "hcimsgs.h"
-#include "hci/include/hci_layer.h"
-#include "hci/include/hci_packet_factory.h"
-#include "hci/include/hci_packet_parser.h"
 #include "btcore/include/module.h"
-#include "stack/include/btm_ble_api.h"
 #include "btcore/include/version.h"
+#include "hcimsgs.h"
+#include "osi/include/future.h"
+#include "stack/include/btm_ble_api.h"
 
 const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\x00\x06\x7f" };
 
@@ -250,7 +246,7 @@ static future_t *shut_down(void) {
   return future_new_immediate(FUTURE_SUCCESS);
 }
 
-const module_t controller_module = {
+EXPORT_SYMBOL const module_t controller_module = {
   .name = CONTROLLER_MODULE,
   .init = NULL,
   .start_up = start_up,
diff --git a/embdrv/sbc/BUILD.gn b/embdrv/sbc/BUILD.gn
new file mode 100644 (file)
index 0000000..7c9387c
--- /dev/null
@@ -0,0 +1,64 @@
+#
+#  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.
+#
+
+source_set("sbc_decoder") {
+  sources = [
+    "decoder/srce/alloc.c",
+    "decoder/srce/bitalloc.c",
+    "decoder/srce/bitalloc-sbc.c",
+    "decoder/srce/bitstream-decode.c",
+    "decoder/srce/decoder-oina.c",
+    "decoder/srce/decoder-private.c",
+    "decoder/srce/decoder-sbc.c",
+    "decoder/srce/dequant.c",
+    "decoder/srce/framing.c",
+    "decoder/srce/framing-sbc.c",
+    "decoder/srce/oi_codec_version.c",
+    "decoder/srce/synthesis-8-generated.c",
+    "decoder/srce/synthesis-dct8.c",
+    "decoder/srce/synthesis-sbc.c",
+  ]
+
+  include_dirs = [
+    "decoder/include",
+  ]
+}
+
+source_set("sbc_encoder") {
+  sources = [
+    "encoder/srce/sbc_analysis.c",
+    "encoder/srce/sbc_dct.c",
+    "encoder/srce/sbc_dct_coeffs.c",
+    "encoder/srce/sbc_enc_bit_alloc_mono.c",
+    "encoder/srce/sbc_enc_bit_alloc_ste.c",
+    "encoder/srce/sbc_enc_coeffs.c",
+    "encoder/srce/sbc_encoder.c",
+    "encoder/srce/sbc_packing.c",
+  ]
+
+  include_dirs = [
+    "encoder/include",
+    "//include",
+    "//stack/include",
+  ]
+}
+
+static_library("sbc") {
+  deps = [
+    ":sbc_decoder",
+    ":sbc_encoder",
+  ]
+}
diff --git a/gki/BUILD.gn b/gki/BUILD.gn
new file mode 100644 (file)
index 0000000..95993ac
--- /dev/null
@@ -0,0 +1,30 @@
+#
+#  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.
+#
+
+static_library("gki") {
+  sources = [
+    "common/gki_buffer.c",
+    "ulinux/gki_ulinux.c",
+  ]
+
+  include_dirs = [
+    "common",
+    "ulinux",
+    "//",
+    "//include",
+    "//stack/include",
+  ]
+}
index cf1c48c..f0df9e3 100644 (file)
@@ -27,7 +27,7 @@ static const char GKI_MODULE[] = "gki_module";
 */
 typedef void (TIMER_CBACK)(void *p_tle);
 #ifndef TIMER_PARAM_TYPE
-#define TIMER_PARAM_TYPE    UINT32
+#define TIMER_PARAM_TYPE void*
 #endif
 /* Define a timer list entry
 */
index 72ad479..c8e9953 100644 (file)
@@ -51,7 +51,7 @@ static future_t *clean_up(void) {
 }
 
 // Temp module until GKI dies
-const module_t gki_module = {
+EXPORT_SYMBOL const module_t gki_module = {
   .name = GKI_MODULE,
   .init = init,
   .start_up = NULL,
index af87285..a36d6b7 100644 (file)
@@ -44,6 +44,7 @@ LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 include $(BUILD_STATIC_LIBRARY)
 
 #####################################################
+ifeq (,$(strip $(SANITIZE_TARGET)))
 include $(CLEAR_VARS)
 
 LOCAL_C_INCLUDES := \
@@ -78,3 +79,4 @@ LOCAL_SHARED_LIBRARIES := liblog libdl
 LOCAL_STATIC_LIBRARIES := libbt-hci libosi libcutils libbtcore
 
 include $(BUILD_NATIVE_TEST)
+endif # SANITIZE_TARGET
diff --git a/hci/BUILD.gn b/hci/BUILD.gn
new file mode 100644 (file)
index 0000000..c199ff0
--- /dev/null
@@ -0,0 +1,77 @@
+#
+#  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.
+#
+
+static_library("hci") {
+  sources = [
+    "src/btsnoop.c",
+    "src/btsnoop_mem.c",
+    "src/btsnoop_net.c",
+    "src/buffer_allocator.c",
+    "src/hci_audio.c",
+    "src/hci_hal.c",
+    "src/hci_hal_h4.c",
+    "src/hci_hal_mct.c",
+    "src/hci_inject.c",
+    "src/hci_layer.c",
+    "src/hci_packet_factory.c",
+    "src/hci_packet_parser.c",
+    "src/low_power_manager.c",
+    "src/packet_fragmenter.c",
+    "src/vendor.c",
+  ]
+
+  include_dirs = [
+    "include",
+    "//",
+    "//include",
+    "//btcore/include",
+    "//gki/common",
+    "//osi/include",
+    "//stack/include",
+  ]
+}
+
+executable("net_test_hci") {
+  testonly = true
+  sources = [
+    "//osi/test/AllocationTestHarness.cpp",
+    "//osi/test/AlarmTestHarness.cpp",
+    "test/hci_hal_h4_test.cpp",
+    "test/hci_hal_mct_test.cpp",
+    "test/hci_layer_test.cpp",
+    "test/low_power_manager_test.cpp",
+    "test/packet_fragmenter_test.cpp",
+  ]
+
+  include_dirs = [
+    "//",
+    "//include",
+    "//btcore/include",
+    "//hci/include",
+    "//osi/include",
+    "//osi/test",
+    "//stack/include",
+  ]
+
+  deps = [
+    "//hci",
+    "//osi",
+    "//btcore",
+    "//third_party/gtest:gtest_main",
+  ]
+
+  libs = [ "-lpthread", "-lrt", "-ldl" ]
+}
index 6e8063a..3eb1d61 100644 (file)
@@ -18,6 +18,8 @@
 
 #pragma once
 
+#include <stdint.h>
+
 // Audio state definitions.
 typedef enum {
     SCO_STATE_OFF = 0,      // Audio is off.
index d859e68..42f9674 100644 (file)
@@ -32,9 +32,9 @@
 #include <sys/time.h>
 #include <unistd.h>
 
+#include "bt_types.h"
 #include "hci/include/btsnoop.h"
 #include "hci/include/btsnoop_mem.h"
-#include "bt_types.h"
 #include "hci_layer.h"
 #include "osi/include/log.h"
 #include "stack_config.h"
@@ -80,7 +80,7 @@ static future_t *shut_down(void) {
   return NULL;
 }
 
-const module_t btsnoop_module = {
+EXPORT_SYMBOL const module_t btsnoop_module = {
   .name = BTSNOOP_MODULE,
   .init = NULL,
   .start_up = start_up,
@@ -166,12 +166,12 @@ static void update_logging() {
       char last_log_path[PATH_MAX];
       snprintf(last_log_path, PATH_MAX, "%s.%llu", log_path, btsnoop_timestamp());
       if (!rename(log_path, last_log_path) && errno != ENOENT)
-        LOG_ERROR("%s unable to rename '%s' to '%s': %s", __func__, log_path, last_log_path, strerror(errno));
+        LOG_ERROR(LOG_TAG, "%s unable to rename '%s' to '%s': %s", __func__, log_path, last_log_path, strerror(errno));
     }
 
     logfile_fd = open(log_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
     if (logfile_fd == INVALID_FD) {
-      LOG_ERROR("%s unable to open '%s': %s", __func__, log_path, strerror(errno));
+      LOG_ERROR(LOG_TAG, "%s unable to open '%s': %s", __func__, log_path, strerror(errno));
       is_logging = false;
       return;
     }
index c601da8..f797558 100644 (file)
 #include <sys/prctl.h>
 #include <sys/socket.h>
 #include <sys/types.h>
+#include <unistd.h>
 
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 
 static void safe_close_(int *fd);
 static void *listen_fn_(void *context);
@@ -47,9 +48,9 @@ static int client_socket_ = -1;
 void btsnoop_net_open() {
   listen_thread_valid_ = (pthread_create(&listen_thread_, NULL, listen_fn_, NULL) == 0);
   if (!listen_thread_valid_) {
-    LOG_ERROR("%s pthread_create failed: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s pthread_create failed: %s", __func__, strerror(errno));
   } else {
-    LOG_DEBUG("initialized");
+    LOG_DEBUG(LOG_TAG, "initialized");
   }
 }
 
@@ -78,13 +79,13 @@ static void *listen_fn_(UNUSED_ATTR void *context) {
 
   listen_socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
   if (listen_socket_ == -1) {
-    LOG_ERROR("%s socket creation failed: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s socket creation failed: %s", __func__, strerror(errno));
     goto cleanup;
   }
 
   int enable = 1;
   if (setsockopt(listen_socket_, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)) == -1) {
-    LOG_ERROR("%s unable to set SO_REUSEADDR: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to set SO_REUSEADDR: %s", __func__, strerror(errno));
     goto cleanup;
   }
 
@@ -93,12 +94,12 @@ static void *listen_fn_(UNUSED_ATTR void *context) {
   addr.sin_addr.s_addr = htonl(LOCALHOST_);
   addr.sin_port = htons(LISTEN_PORT_);
   if (bind(listen_socket_, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
-    LOG_ERROR("%s unable to bind listen socket: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to bind listen socket: %s", __func__, strerror(errno));
     goto cleanup;
   }
 
   if (listen(listen_socket_, 10) == -1) {
-    LOG_ERROR("%s unable to listen: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to listen: %s", __func__, strerror(errno));
     goto cleanup;
   }
 
@@ -108,7 +109,7 @@ static void *listen_fn_(UNUSED_ATTR void *context) {
       if (errno == EINVAL || errno == EBADF) {
         break;
       }
-      LOG_WARN("%s error accepting socket: %s", __func__, strerror(errno));
+      LOG_WARN(LOG_TAG, "%s error accepting socket: %s", __func__, strerror(errno));
       continue;
     }
 
index 63def16..ec126b8 100644 (file)
 
 #define LOG_TAG "bt_hci_audio"
 
-#include <stdint.h>
+#include "hci/include/hci_audio.h"
 
 #include "hci/include/bt_vendor_lib.h"
-#include "hci/include/hci_audio.h"
 #include "hci/include/vendor.h"
 #include "osi/include/log.h"
 
 void set_audio_state(uint16_t handle, sco_codec_t codec, sco_state_t state)
 {
-    LOG_INFO("%s handle:%d codec:0x%x state:%d", __func__, handle, codec, state);
+    LOG_INFO(LOG_TAG, "%s handle:%d codec:0x%x state:%d", __func__, handle, codec, state);
 
     bt_vendor_op_audio_state_t audio_state;
 
index 4fc4274..2310a7d 100644 (file)
 #include <assert.h>
 #include <errno.h>
 #include <string.h>
+#include <unistd.h>
 
-#include "osi/include/eager_reader.h"
 #include "hci_hal.h"
-#include "osi/include/osi.h"
+#include "osi/include/eager_reader.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 #include "osi/include/reactor.h"
 #include "vendor.h"
 
@@ -57,26 +58,26 @@ static bool hal_init(const hci_hal_callbacks_t *upper_callbacks, thread_t *upper
 }
 
 static bool hal_open() {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
   // TODO(zachoverflow): close if already open / or don't reopen (maybe at the hci layer level)
 
   int fd_array[CH_MAX];
   int number_of_ports = vendor->send_command(VENDOR_OPEN_USERIAL, &fd_array);
 
   if (number_of_ports != 1) {
-    LOG_ERROR("%s opened the wrong number of ports: got %d, expected 1.", __func__, number_of_ports);
+    LOG_ERROR(LOG_TAG, "%s opened the wrong number of ports: got %d, expected 1.", __func__, number_of_ports);
     goto error;
   }
 
   uart_fd = fd_array[0];
   if (uart_fd == INVALID_FD) {
-    LOG_ERROR("%s unable to open the uart serial port.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to open the uart serial port.", __func__);
     goto error;
   }
 
   uart_stream = eager_reader_new(uart_fd, &allocator_malloc, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, "hci_single_channel");
   if (!uart_stream) {
-    LOG_ERROR("%s unable to create eager reader for the uart serial port.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create eager reader for the uart serial port.", __func__);
     goto error;
   }
 
@@ -91,7 +92,7 @@ error:
 }
 
 static void hal_close() {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
 
   eager_reader_free(uart_stream);
   vendor->send_command(VENDOR_CLOSE_USERIAL, NULL);
@@ -100,13 +101,13 @@ static void hal_close() {
 
 static size_t read_data(serial_data_type_t type, uint8_t *buffer, size_t max_size, bool block) {
   if (type < DATA_TYPE_ACL || type > DATA_TYPE_EVENT) {
-    LOG_ERROR("%s invalid data type: %d", __func__, type);
+    LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type);
     return 0;
   } else if (!stream_has_interpretation) {
-    LOG_ERROR("%s with no valid stream intepretation.", __func__);
+    LOG_ERROR(LOG_TAG, "%s with no valid stream intepretation.", __func__);
     return 0;
   } else if (current_data_type != type) {
-    LOG_ERROR("%s with different type than existing interpretation.", __func__);
+    LOG_ERROR(LOG_TAG, "%s with different type than existing interpretation.", __func__);
     return 0;
   }
 
@@ -115,9 +116,9 @@ static size_t read_data(serial_data_type_t type, uint8_t *buffer, size_t max_siz
 
 static void packet_finished(serial_data_type_t type) {
   if (!stream_has_interpretation)
-    LOG_ERROR("%s with no existing stream interpretation.", __func__);
+    LOG_ERROR(LOG_TAG, "%s with no existing stream interpretation.", __func__);
   else if (current_data_type != type)
-    LOG_ERROR("%s with different type than existing interpretation.", __func__);
+    LOG_ERROR(LOG_TAG, "%s with different type than existing interpretation.", __func__);
 
   stream_has_interpretation = false;
 }
@@ -127,7 +128,7 @@ static uint16_t transmit_data(serial_data_type_t type, uint8_t *data, uint16_t l
   assert(length > 0);
 
   if (type < DATA_TYPE_COMMAND || type > DATA_TYPE_SCO) {
-    LOG_ERROR("%s invalid data type: %d", __func__, type);
+    LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type);
     return 0;
   }
 
@@ -142,7 +143,7 @@ static uint16_t transmit_data(serial_data_type_t type, uint8_t *data, uint16_t l
     ssize_t ret = write(uart_fd, data + transmitted_length, length);
     switch (ret) {
       case -1:
-        LOG_ERROR("In %s, error writing to the uart serial port: %s", __func__, strerror(errno));
+        LOG_ERROR(LOG_TAG, "In %s, error writing to the uart serial port: %s", __func__, strerror(errno));
         goto done;
       case 0:
         // If we wrote nothing, don't loop more because we
@@ -175,11 +176,11 @@ static void event_uart_has_bytes(eager_reader_t *reader, UNUSED_ATTR void *conte
   } else {
     uint8_t type_byte;
     if (eager_reader_read(reader, &type_byte, 1, true) == 0) {
-      LOG_ERROR("%s could not read HCI message type", __func__);
+      LOG_ERROR(LOG_TAG, "%s could not read HCI message type", __func__);
       return;
     }
     if (type_byte < DATA_TYPE_ACL || type_byte > DATA_TYPE_EVENT) {
-      LOG_ERROR("%s Unknown HCI message type. Dropping this byte 0x%x, min %x, max %x", __func__, type_byte, DATA_TYPE_ACL, DATA_TYPE_EVENT);
+      LOG_ERROR(LOG_TAG, "%s Unknown HCI message type. Dropping this byte 0x%x, min %x, max %x", __func__, type_byte, DATA_TYPE_ACL, DATA_TYPE_EVENT);
       return;
     }
 
index 9b3707c..33d0251 100644 (file)
 #include <assert.h>
 #include <errno.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "bt_vendor_lib.h"
-#include "osi/include/eager_reader.h"
 #include "hci_hal.h"
-#include "osi/include/osi.h"
+#include "osi/include/eager_reader.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 #include "osi/include/reactor.h"
 #include "vendor.h"
 
@@ -59,48 +60,48 @@ static bool hal_init(const hci_hal_callbacks_t *upper_callbacks, thread_t *upper
 }
 
 static bool hal_open() {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
   // TODO(zachoverflow): close if already open / or don't reopen (maybe at the hci layer level)
 
   int number_of_ports = vendor->send_command(VENDOR_OPEN_USERIAL, &uart_fds);
 
   if (number_of_ports != 2 && number_of_ports != 4) {
-    LOG_ERROR("%s opened the wrong number of ports: got %d, expected 2 or 4.", __func__, number_of_ports);
+    LOG_ERROR(LOG_TAG, "%s opened the wrong number of ports: got %d, expected 2 or 4.", __func__, number_of_ports);
     goto error;
   }
 
-  LOG_INFO("%s got uart fds: CMD=%d, EVT=%d, ACL_OUT=%d, ACL_IN=%d",
+  LOG_INFO(LOG_TAG, "%s got uart fds: CMD=%d, EVT=%d, ACL_OUT=%d, ACL_IN=%d",
       __func__, uart_fds[CH_CMD], uart_fds[CH_EVT], uart_fds[CH_ACL_OUT], uart_fds[CH_ACL_IN]);
 
   if (uart_fds[CH_CMD] == INVALID_FD) {
-    LOG_ERROR("%s unable to open the command uart serial port.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to open the command uart serial port.", __func__);
     goto error;
   }
 
   if (uart_fds[CH_EVT] == INVALID_FD) {
-    LOG_ERROR("%s unable to open the event uart serial port.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to open the event uart serial port.", __func__);
     goto error;
   }
 
   if (uart_fds[CH_ACL_OUT] == INVALID_FD) {
-    LOG_ERROR("%s unable to open the acl-out uart serial port.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to open the acl-out uart serial port.", __func__);
     goto error;
   }
 
   if (uart_fds[CH_ACL_IN] == INVALID_FD) {
-    LOG_ERROR("%s unable to open the acl-in uart serial port.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to open the acl-in uart serial port.", __func__);
     goto error;
   }
 
   event_stream = eager_reader_new(uart_fds[CH_EVT], &allocator_malloc, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, "hci_mct");
   if (!event_stream) {
-    LOG_ERROR("%s unable to create eager reader for the event uart serial port.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create eager reader for the event uart serial port.", __func__);
     goto error;
   }
 
   acl_stream = eager_reader_new(uart_fds[CH_ACL_IN], &allocator_malloc, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, "hci_mct");
   if (!event_stream) {
-    LOG_ERROR("%s unable to create eager reader for the acl-in uart serial port.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create eager reader for the acl-in uart serial port.", __func__);
     goto error;
   }
 
@@ -115,7 +116,7 @@ error:;
 }
 
 static void hal_close() {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
 
   eager_reader_free(event_stream);
   eager_reader_free(acl_stream);
@@ -132,7 +133,7 @@ static size_t read_data(serial_data_type_t type, uint8_t *buffer, size_t max_siz
     return eager_reader_read(event_stream, buffer, max_size, block);
   }
 
-  LOG_ERROR("%s invalid data type: %d", __func__, type);
+  LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type);
   return 0;
 }
 
@@ -147,7 +148,7 @@ static uint16_t transmit_data(serial_data_type_t type, uint8_t *data, uint16_t l
     return transmit_data_on(uart_fds[CH_CMD], data, length);
   }
 
-  LOG_ERROR("%s invalid data type: %d", __func__, type);
+  LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type);
   return 0;
 }
 
@@ -162,7 +163,7 @@ static uint16_t transmit_data_on(int fd, uint8_t *data, uint16_t length) {
     ssize_t ret = write(fd, data + transmitted_length, length);
     switch (ret) {
       case -1:
-        LOG_ERROR("In %s, error writing to the serial port with fd %d: %s", __func__, fd, strerror(errno));
+        LOG_ERROR(LOG_TAG, "In %s, error writing to the serial port with fd %d: %s", __func__, fd, strerror(errno));
         return transmitted_length;
       case 0:
         // If we wrote nothing, don't loop more because we
index a17a3d3..ea25fd0 100644 (file)
 
 #define LOG_TAG "bt_hci_inject"
 
+#include "hci_inject.h"
+
 #include <assert.h>
 #include <errno.h>
 #include <string.h>
 
-#include "osi/include/allocator.h"
 #include "bt_types.h"
 #include "buffer_allocator.h"
-#include "hci_inject.h"
 #include "hci_layer.h"
+#include "osi/include/allocator.h"
 #include "osi/include/list.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 #include "osi/include/socket.h"
 #include "osi/include/thread.h"
 
@@ -110,7 +111,7 @@ static int hci_packet_to_event(hci_packet_t packet) {
     case HCI_PACKET_SCO_DATA:
       return MSG_STACK_TO_HC_HCI_SCO;
     default:
-      LOG_ERROR("%s unsupported packet type: %d", __func__, packet);
+      LOG_ERROR(LOG_TAG, "%s unsupported packet type: %d", __func__, packet);
       return -1;
   }
 }
@@ -125,7 +126,7 @@ static void accept_ready(socket_t *socket, UNUSED_ATTR void *context) {
 
   client_t *client = (client_t *)osi_calloc(sizeof(client_t));
   if (!client) {
-    LOG_ERROR("%s unable to allocate memory for client.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for client.", __func__);
     socket_free(socket);
     return;
   }
@@ -133,7 +134,7 @@ static void accept_ready(socket_t *socket, UNUSED_ATTR void *context) {
   client->socket = socket;
 
   if (!list_append(clients, client)) {
-    LOG_ERROR("%s unable to add client to list.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to add client to list.", __func__);
     client_free(client);
     return;
   }
@@ -176,7 +177,7 @@ static void read_ready(UNUSED_ATTR socket_t *socket, void *context) {
       memcpy(buf->data, buffer + 3, packet_len);
       hci->transmit_downward(buf->event, buf);
     } else {
-      LOG_ERROR("%s dropping injected packet of length %zu", __func__, packet_len);
+      LOG_ERROR(LOG_TAG, "%s dropping injected packet of length %zu", __func__, packet_len);
     }
 
     size_t remainder = client->buffer_size - frame_len;
index 5138ce6..c4ef5f2 100644 (file)
 
 #define LOG_TAG "bt_hci"
 
+#include "hci_layer.h"
+
 #include <assert.h>
-#include <cutils/properties.h>
-#include <string.h>
+#include <pthread.h>
 #include <signal.h>
 #include <string.h>
 #include <sys/types.h>
+#include <unistd.h>
 
-#include "buffer_allocator.h"
+// TODO(armansito): cutils/properties.h is only being used to pull-in runtime
+// settings on Android. Remove this conditional include once we have a generic
+// way to obtain system properties.
+#if !defined(OS_GENERIC)
+#include <cutils/properties.h>
+#endif  // !defined(OS_GENERIC)
+
+#include "btcore/include/module.h"
 #include "btsnoop.h"
-#include "osi/include/fixed_queue.h"
-#include "osi/include/future.h"
-#include "hcidefs.h"
-#include "hcimsgs.h"
+#include "buffer_allocator.h"
 #include "hci_hal.h"
-#include "hci_internals.h"
 #include "hci_inject.h"
-#include "hci_layer.h"
-#include "osi/include/list.h"
+#include "hci_internals.h"
+#include "hcidefs.h"
+#include "hcimsgs.h"
 #include "low_power_manager.h"
-#include "btcore/include/module.h"
-#include "osi/include/non_repeating_timer.h"
-#include "osi/include/osi.h"
+#include "osi/include/list.h"
 #include "osi/include/log.h"
-#include "packet_fragmenter.h"
+#include "osi/include/non_repeating_timer.h"
 #include "osi/include/reactor.h"
+#include "packet_fragmenter.h"
 #include "vendor.h"
 
 // TODO(zachoverflow): remove this hack extern
@@ -165,7 +170,7 @@ static waiting_command_t *get_waiting_command(command_opcode_t opcode);
 // Module lifecycle functions
 
 static future_t *start_up(void) {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
 
   // The host is only allowed to send at most one command initially,
   // as per the Bluetooth spec, Volume 2, Part E, 4.4 (Command Flow Control)
@@ -175,16 +180,23 @@ static future_t *start_up(void) {
 
   pthread_mutex_init(&commands_pending_response_lock, NULL);
 
+  // TODO(armansito): cutils/properties.h is only being used to pull-in runtime
+  // settings on Android. Remove this conditional include once we have a generic
+  // way to obtain system properties. For now, always use the default timeout on
+  // non-Android builds.
+  period_ms_t startup_timeout_ms = DEFAULT_STARTUP_TIMEOUT_MS;
+
+#if !defined(OS_GENERIC)
   // Grab the override startup timeout ms, if present.
-  period_ms_t startup_timeout_ms;
   char timeout_prop[PROPERTY_VALUE_MAX];
   if (!property_get("bluetooth.enable_timeout_ms", timeout_prop, STRING_VALUE_OF(DEFAULT_STARTUP_TIMEOUT_MS))
       || (startup_timeout_ms = atoi(timeout_prop)) < 100)
     startup_timeout_ms = DEFAULT_STARTUP_TIMEOUT_MS;
+#endif  // !defined(OS_GENERIC)
 
   startup_timer = non_repeating_timer_new(startup_timeout_ms, startup_timer_expired, NULL);
   if (!startup_timer) {
-    LOG_ERROR("%s unable to create startup timer.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create startup timer.", __func__);
     goto error;
   }
 
@@ -193,37 +205,37 @@ static future_t *start_up(void) {
 
   epilog_timer = non_repeating_timer_new(EPILOG_TIMEOUT_MS, epilog_timer_expired, NULL);
   if (!epilog_timer) {
-    LOG_ERROR("%s unable to create epilog timer.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create epilog timer.", __func__);
     goto error;
   }
 
   command_response_timer = non_repeating_timer_new(COMMAND_PENDING_TIMEOUT, command_timed_out, NULL);
   if (!command_response_timer) {
-    LOG_ERROR("%s unable to create command response timer.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create command response timer.", __func__);
     goto error;
   }
 
   command_queue = fixed_queue_new(SIZE_MAX);
   if (!command_queue) {
-    LOG_ERROR("%s unable to create pending command queue.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create pending command queue.", __func__);
     goto error;
   }
 
   packet_queue = fixed_queue_new(SIZE_MAX);
   if (!packet_queue) {
-    LOG_ERROR("%s unable to create pending packet queue.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create pending packet queue.", __func__);
     goto error;
   }
 
   thread = thread_new("hci_thread");
   if (!thread) {
-    LOG_ERROR("%s unable to create thread.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create thread.", __func__);
     goto error;
   }
 
   commands_pending_response = list_new(NULL);
   if (!commands_pending_response) {
-    LOG_ERROR("%s unable to create list for commands pending response.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create list for commands pending response.", __func__);
     goto error;
   }
 
@@ -248,7 +260,7 @@ static future_t *start_up(void) {
 
   int power_state = BT_VND_PWR_OFF;
 #if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE)
-  LOG_WARN("%s not turning off the chip before turning on.", __func__);
+  LOG_WARN(LOG_TAG, "%s not turning off the chip before turning on.", __func__);
   // So apparently this hack was needed in the past because a Wingray kernel driver
   // didn't handle power off commands in a powered off state correctly.
 
@@ -263,7 +275,7 @@ static future_t *start_up(void) {
   vendor->send_command(VENDOR_CHIP_POWER_CONTROL, &power_state);
 
   startup_future = future_new();
-  LOG_DEBUG("%s starting async portion", __func__);
+  LOG_DEBUG(LOG_TAG, "%s starting async portion", __func__);
   thread_post(thread, event_finish_startup, NULL);
   return startup_future;
 error:;
@@ -272,7 +284,7 @@ error:;
 }
 
 static future_t *shut_down() {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
 
   hci_inject->close();
 
@@ -317,7 +329,7 @@ static future_t *shut_down() {
   return NULL;
 }
 
-const module_t hci_module = {
+EXPORT_SYMBOL const module_t hci_module = {
   .name = HCI_MODULE,
   .init = NULL,
   .start_up = start_up,
@@ -332,7 +344,7 @@ const module_t hci_module = {
 // Interface functions
 
 static void do_postload() {
-  LOG_DEBUG("%s posting postload work item", __func__);
+  LOG_DEBUG(LOG_TAG, "%s posting postload work item", __func__);
   thread_post(thread, event_postload, NULL);
 }
 
@@ -347,7 +359,7 @@ static void transmit_command(
     void *context) {
   waiting_command_t *wait_entry = osi_calloc(sizeof(waiting_command_t));
   if (!wait_entry) {
-    LOG_ERROR("%s couldn't allocate space for wait entry.", __func__);
+    LOG_ERROR(LOG_TAG, "%s couldn't allocate space for wait entry.", __func__);
     return;
   }
 
@@ -388,7 +400,7 @@ static void transmit_downward(data_dispatcher_type_t type, void *data) {
   if (type == MSG_STACK_TO_HC_HCI_CMD) {
     // TODO(zachoverflow): eliminate this call
     transmit_command((BT_HDR *)data, NULL, NULL, NULL);
-    LOG_WARN("%s legacy transmit of command. Use transmit_command instead.", __func__);
+    LOG_WARN(LOG_TAG, "%s legacy transmit of command. Use transmit_command instead.", __func__);
   } else {
     fixed_queue_enqueue(packet_queue, data);
   }
@@ -397,13 +409,13 @@ static void transmit_downward(data_dispatcher_type_t type, void *data) {
 // Start up functions
 
 static void event_finish_startup(UNUSED_ATTR void *context) {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
   hal->open();
   vendor->send_async_command(VENDOR_CONFIGURE_FIRMWARE, NULL);
 }
 
 static void firmware_config_callback(UNUSED_ATTR bool success) {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
   firmware_is_configured = true;
   non_repeating_timer_cancel(startup_timer);
 
@@ -412,7 +424,7 @@ static void firmware_config_callback(UNUSED_ATTR bool success) {
 }
 
 static void startup_timer_expired(UNUSED_ATTR void *context) {
-  LOG_ERROR("%s", __func__);
+  LOG_ERROR(LOG_TAG, "%s", __func__);
   future_ready(startup_future, FUTURE_FAIL);
   startup_future = NULL;
 }
@@ -420,7 +432,7 @@ static void startup_timer_expired(UNUSED_ATTR void *context) {
 // Postload functions
 
 static void event_postload(UNUSED_ATTR void *context) {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
   if(vendor->send_async_command(VENDOR_CONFIGURE_SCO, NULL) == -1) {
     // If couldn't configure sco, we won't get the sco configuration callback
     // so go pretend to do it now
@@ -430,7 +442,7 @@ static void event_postload(UNUSED_ATTR void *context) {
 }
 
 static void sco_config_callback(UNUSED_ATTR bool success) {
-  LOG_INFO("%s postload finished.", __func__);
+  LOG_INFO(LOG_TAG, "%s postload finished.", __func__);
 }
 
 // Epilog functions
@@ -440,12 +452,12 @@ static void event_epilog(UNUSED_ATTR void *context) {
 }
 
 static void epilog_finished_callback(UNUSED_ATTR bool success) {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
   thread_stop(thread);
 }
 
 static void epilog_timer_expired(UNUSED_ATTR void *context) {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
   thread_stop(thread);
 }
 
@@ -506,17 +518,17 @@ static void command_timed_out(UNUSED_ATTR void *context) {
   pthread_mutex_lock(&commands_pending_response_lock);
 
   if (list_is_empty(commands_pending_response)) {
-    LOG_ERROR("%s with no commands pending response", __func__);
+    LOG_ERROR(LOG_TAG, "%s with no commands pending response", __func__);
   } else {
     waiting_command_t *wait_entry = list_front(commands_pending_response);
     pthread_mutex_unlock(&commands_pending_response_lock);
 
     // We shouldn't try to recover the stack from this command timeout.
     // If it's caused by a software bug, fix it. If it's a hardware bug, fix it.
-    LOG_ERROR("%s hci layer timeout waiting for response to a command. opcode: 0x%x", __func__, wait_entry->opcode);
+    LOG_ERROR(LOG_TAG, "%s hci layer timeout waiting for response to a command. opcode: 0x%x", __func__, wait_entry->opcode);
   }
 
-  LOG_ERROR("%s restarting the bluetooth process.", __func__);
+  LOG_ERROR(LOG_TAG, "%s restarting the bluetooth process.", __func__);
   usleep(10000);
   kill(getpid(), SIGKILL);
 }
@@ -551,7 +563,7 @@ static void hal_says_data_ready(serial_data_type_t type) {
           incoming->buffer = (BT_HDR *)buffer_allocator->alloc(buffer_size);
 
           if (!incoming->buffer) {
-            LOG_ERROR("%s error getting buffer for incoming packet of type %d and size %zd", __func__, type, buffer_size);
+            LOG_ERROR(LOG_TAG, "%s error getting buffer for incoming packet of type %d and size %zd", __func__, type, buffer_size);
             // Can't read any more of this current packet, so jump out
             incoming->state = incoming->bytes_remaining == 0 ? BRAND_NEW : IGNORE;
             break;
@@ -591,7 +603,7 @@ static void hal_says_data_ready(serial_data_type_t type) {
 
         break;
       case FINISHED:
-        LOG_ERROR("%s the state machine should not have been left in the finished state.", __func__);
+        LOG_ERROR(LOG_TAG, "%s the state machine should not have been left in the finished state.", __func__);
         break;
     }
 
@@ -645,7 +657,7 @@ static bool filter_incoming_event(BT_HDR *packet) {
 
     wait_entry = get_waiting_command(opcode);
     if (!wait_entry)
-      LOG_WARN("%s command complete event with no matching command. opcode: 0x%x.", __func__, opcode);
+      LOG_WARN(LOG_TAG, "%s command complete event with no matching command. opcode: 0x%x.", __func__, opcode);
     else if (wait_entry->complete_callback)
       wait_entry->complete_callback(packet, wait_entry->context);
     else if (wait_entry->complete_future)
@@ -662,7 +674,7 @@ static bool filter_incoming_event(BT_HDR *packet) {
 
     wait_entry = get_waiting_command(opcode);
     if (!wait_entry)
-      LOG_WARN("%s command status event with no matching command. opcode: 0x%x", __func__, opcode);
+      LOG_WARN(LOG_TAG, "%s command status event with no matching command. opcode: 0x%x", __func__, opcode);
     else if (wait_entry->status_callback)
       wait_entry->status_callback(status, wait_entry->command, wait_entry->context);
 
@@ -699,7 +711,7 @@ static void dispatch_reassembled(BT_HDR *packet) {
   if (upwards_data_queue) {
     fixed_queue_enqueue(upwards_data_queue, packet);
   } else {
-    LOG_ERROR("%s had no queue to place upwards data packet in. Dropping it on the floor.", __func__);
+    LOG_ERROR(LOG_TAG, "%s had no queue to place upwards data packet in. Dropping it on the floor.", __func__);
     buffer_allocator->free(packet);
   }
 }
@@ -715,7 +727,7 @@ static serial_data_type_t event_to_data_type(uint16_t event) {
   else if (event == MSG_STACK_TO_HC_HCI_CMD)
     return DATA_TYPE_COMMAND;
   else
-    LOG_ERROR("%s invalid event type, could not translate 0x%x", __func__, event);
+    LOG_ERROR(LOG_TAG, "%s invalid event type, could not translate 0x%x", __func__, event);
 
   return 0;
 }
@@ -750,7 +762,7 @@ static void init_layer_interface() {
     // there's only one instance of the hci interface.
     interface.event_dispatcher = data_dispatcher_new("hci_layer");
     if (!interface.event_dispatcher) {
-      LOG_ERROR("%s could not create upward dispatcher.", __func__);
+      LOG_ERROR(LOG_TAG, "%s could not create upward dispatcher.", __func__);
       return;
     }
 
index b9f4080..8470c3f 100644 (file)
 
 #define LOG_TAG "bt_hci"
 
+#include "hci_packet_parser.h"
+
 #include <assert.h>
 
 #include "buffer_allocator.h"
-#include "bt_types.h"
-#include "hcimsgs.h"
 #include "hci_layer.h"
-#include "hci_packet_parser.h"
+#include "hcimsgs.h"
 #include "osi/include/log.h"
 
 static const command_opcode_t NO_OPCODE_CHECKING = 0;
@@ -109,7 +109,7 @@ static void parse_read_local_extended_features_response(
     assert(*page_number_ptr < feature_pages_count);
     STREAM_TO_ARRAY(feature_pages[*page_number_ptr].as_array, stream, (int)sizeof(bt_device_features_t));
   } else {
-    LOG_ERROR("%s() - WARNING: READING EXTENDED FEATURES FAILED. "
+    LOG_ERROR(LOG_TAG, "%s() - WARNING: READING EXTENDED FEATURES FAILED. "
                 "THIS MAY INDICATE A FIRMWARE/CONTROLLER ISSUE.", __func__);
   }
 
index 9435e4f..ff5ce9b 100644 (file)
 
 #define LOG_TAG "bt_low_power_manager"
 
+#include "low_power_manager.h"
+
 #include <assert.h>
 #include <stdint.h>
 
 #include "osi/include/alarm.h"
-#include "low_power_manager.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 #include "osi/include/thread.h"
 #include "vendor.h"
 
@@ -83,7 +84,7 @@ static void init(thread_t *post_thread) {
 
   idle_alarm = alarm_new();
   if (!idle_alarm) {
-    LOG_ERROR("%s could not create idle alarm.", __func__);
+    LOG_ERROR(LOG_TAG, "%s could not create idle alarm.", __func__);
   }
 
   reset_state();
@@ -97,7 +98,7 @@ static void cleanup() {
 
 static void post_command(low_power_command_t command) {
   if (command > LPM_WAKE_DEASSERT) {
-    LOG_ERROR("%s unknown low power command %d", __func__, command);
+    LOG_ERROR(LOG_TAG, "%s unknown low power command %d", __func__, command);
     return;
   }
 
@@ -132,18 +133,18 @@ static void transmit_done() {
 static void enable(bool enable) {
   if (state == LPM_DISABLING) {
     if (enable)
-      LOG_ERROR("%s still processing prior disable request, cannot enable.", __func__);
+      LOG_ERROR(LOG_TAG, "%s still processing prior disable request, cannot enable.", __func__);
     else
-      LOG_WARN("%s still processing prior disable request, ignoring new request to disable.", __func__);
+      LOG_WARN(LOG_TAG, "%s still processing prior disable request, ignoring new request to disable.", __func__);
   } else if (state == LPM_ENABLING) {
     if (enable)
-      LOG_ERROR("%s still processing prior enable request, ignoring new request to enable.", __func__);
+      LOG_ERROR(LOG_TAG, "%s still processing prior enable request, ignoring new request to enable.", __func__);
     else
-      LOG_WARN("%s still processing prior enable request, cannot disable.", __func__);
+      LOG_WARN(LOG_TAG, "%s still processing prior enable request, cannot disable.", __func__);
   } else if (state == LPM_ENABLED && enable) {
-    LOG_INFO("%s already enabled.", __func__);
+    LOG_INFO(LOG_TAG, "%s already enabled.", __func__);
   } else if (state == LPM_DISABLED && !enable) {
-    LOG_INFO("%s already disabled.", __func__);
+    LOG_INFO(LOG_TAG, "%s already disabled.", __func__);
   } else {
     uint8_t command = enable ? BT_VND_LPM_ENABLE : BT_VND_LPM_DISABLE;
     state = enable ? LPM_ENABLING : LPM_DISABLING;
index de63668..6dfebe2 100644 (file)
 
 #define LOG_TAG "bt_hci_packet_fragmenter"
 
+#include "packet_fragmenter.h"
+
 #include <assert.h>
 #include <string.h>
 
 #include "buffer_allocator.h"
 #include "device/include/controller.h"
-#include "osi/include/hash_map.h"
 #include "hci_internals.h"
-#include "hci_layer.h"
-#include "packet_fragmenter.h"
-#include "osi/include/osi.h"
 #include "osi/include/hash_functions.h"
+#include "osi/include/hash_map.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 
 #define APPLY_CONTINUATION_FLAG(handle) (((handle) & 0xCFFF) | 0x1000)
 #define APPLY_START_FLAG(handle) (((handle) & 0xCFFF) | 0x2000)
@@ -139,7 +139,7 @@ static void reassemble_and_dispatch(UNUSED_ATTR BT_HDR *packet) {
 
     if (boundary_flag == START_PACKET_BOUNDARY) {
       if (partial_packet) {
-        LOG_WARN("%s found unfinished packet for handle with start packet. Dropping old.", __func__);
+        LOG_WARN(LOG_TAG, "%s found unfinished packet for handle with start packet. Dropping old.", __func__);
 
         hash_map_erase(partial_packets, (void *)(uintptr_t)handle);
         buffer_allocator->free(partial_packet);
@@ -148,7 +148,7 @@ static void reassemble_and_dispatch(UNUSED_ATTR BT_HDR *packet) {
       uint16_t full_length = l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE;
       if (full_length <= packet->len) {
         if (full_length < packet->len)
-          LOG_WARN("%s found l2cap full length %d less than the hci length %d.", __func__, l2cap_length, packet->len);
+          LOG_WARN(LOG_TAG, "%s found l2cap full length %d less than the hci length %d.", __func__, l2cap_length, packet->len);
 
         callbacks->reassembled(packet);
         return;
@@ -171,7 +171,7 @@ static void reassemble_and_dispatch(UNUSED_ATTR BT_HDR *packet) {
       buffer_allocator->free(packet);
     } else {
       if (!partial_packet) {
-        LOG_WARN("%s got continuation for unknown packet. Dropping it.", __func__);
+        LOG_WARN(LOG_TAG, "%s got continuation for unknown packet. Dropping it.", __func__);
         buffer_allocator->free(packet);
         return;
       }
@@ -179,7 +179,7 @@ static void reassemble_and_dispatch(UNUSED_ATTR BT_HDR *packet) {
       packet->offset = HCI_ACL_PREAMBLE_SIZE;
       uint16_t projected_offset = partial_packet->offset + (packet->len - HCI_ACL_PREAMBLE_SIZE);
       if (projected_offset > partial_packet->len) { // len stores the expected length
-        LOG_WARN("%s got packet which would exceed expected length of %d. Truncating.", __func__, partial_packet->len);
+        LOG_WARN(LOG_TAG, "%s got packet which would exceed expected length of %d. Truncating.", __func__, partial_packet->len);
         packet->len = partial_packet->len - partial_packet->offset;
         projected_offset = partial_packet->len;
       }
index 2e220e4..ace76b3 100644 (file)
 
 #define LOG_TAG "bt_vendor"
 
+#include "vendor.h"
+
 #include <assert.h>
 #include <dlfcn.h>
 
 #include "buffer_allocator.h"
-#include "bt_vendor_lib.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
-#include "vendor.h"
+#include "osi/include/osi.h"
 
 #define LAST_VENDOR_OPCODE_VALUE VENDOR_DO_EPILOG
 
@@ -51,21 +51,21 @@ static bool vendor_open(
 
   lib_handle = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
   if (!lib_handle) {
-    LOG_ERROR("%s unable to open %s: %s", __func__, VENDOR_LIBRARY_NAME, dlerror());
+    LOG_ERROR(LOG_TAG, "%s unable to open %s: %s", __func__, VENDOR_LIBRARY_NAME, dlerror());
     goto error;
   }
 
   lib_interface = (bt_vendor_interface_t *)dlsym(lib_handle, VENDOR_LIBRARY_SYMBOL_NAME);
   if (!lib_interface) {
-    LOG_ERROR("%s unable to find symbol %s in %s: %s", __func__, VENDOR_LIBRARY_SYMBOL_NAME, VENDOR_LIBRARY_NAME, dlerror());
+    LOG_ERROR(LOG_TAG, "%s unable to find symbol %s in %s: %s", __func__, VENDOR_LIBRARY_SYMBOL_NAME, VENDOR_LIBRARY_NAME, dlerror());
     goto error;
   }
 
-  LOG_INFO("alloc value %p", lib_callbacks.alloc);
+  LOG_INFO(LOG_TAG, "alloc value %p", lib_callbacks.alloc);
 
   int status = lib_interface->init(&lib_callbacks, (unsigned char *)local_bdaddr);
   if (status) {
-    LOG_ERROR("%s unable to initialize vendor library: %d", __func__, status);
+    LOG_ERROR(LOG_TAG, "%s unable to initialize vendor library: %d", __func__, status);
     goto error;
   }
 
@@ -109,7 +109,7 @@ static void set_callback(vendor_async_opcode_t opcode, vendor_cb callback) {
 // Called back from vendor library when the firmware configuration
 // completes.
 static void firmware_config_cb(bt_vendor_op_result_t result) {
-  LOG_INFO("firmware callback");
+  LOG_INFO(LOG_TAG, "firmware callback");
   vendor_cb callback = callbacks[VENDOR_CONFIGURE_FIRMWARE];
   assert(callback != NULL);
   callback(result == BT_VND_OP_RESULT_SUCCESS);
@@ -119,7 +119,7 @@ static void firmware_config_cb(bt_vendor_op_result_t result) {
 // SCO configuration request. This should only happen during the
 // postload process.
 static void sco_config_cb(bt_vendor_op_result_t result) {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
   vendor_cb callback = callbacks[VENDOR_CONFIGURE_SCO];
   assert(callback != NULL);
   callback(result == BT_VND_OP_RESULT_SUCCESS);
@@ -128,7 +128,7 @@ static void sco_config_cb(bt_vendor_op_result_t result) {
 // Called back from vendor library to indicate status of previous
 // LPM enable/disable request.
 static void low_power_mode_cb(bt_vendor_op_result_t result) {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
   vendor_cb callback = callbacks[VENDOR_SET_LPM_MODE];
   assert(callback != NULL);
   callback(result == BT_VND_OP_RESULT_SUCCESS);
@@ -149,7 +149,7 @@ static void sco_audiostate_cb(bt_vendor_op_result_t result)
 {
     uint8_t status = (result == BT_VND_OP_RESULT_SUCCESS) ? 0 : 1;
 
-    LOG_INFO("sco_audiostate_cb(status: %d)",status);
+    LOG_INFO(LOG_TAG, "sco_audiostate_cb(status: %d)",status);
 }
 
 // Called by vendor library when it needs an HCI buffer.
@@ -180,7 +180,7 @@ static uint8_t transmit_cb(UNUSED_ATTR uint16_t opcode, void *buffer, tINT_CMD_C
 // completed. It is safe to call vendor_interface->cleanup() after
 // this callback has been received.
 static void epilog_cb(bt_vendor_op_result_t result) {
-  LOG_INFO("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s", __func__);
   vendor_cb callback = callbacks[VENDOR_DO_EPILOG];
   assert(callback != NULL);
   callback(result == BT_VND_OP_RESULT_SUCCESS);
index f712d2c..57ff43d 100644 (file)
 
 
 #ifndef TIMER_PARAM_TYPE
-#define TIMER_PARAM_TYPE    UINT32
+#define TIMER_PARAM_TYPE void*
 #endif
 
 /******************************************************************************
index ff7b4a5..7a7fb77 100644 (file)
@@ -130,7 +130,6 @@ LOCAL_SHARED_LIBRARIES := \
     libcutils \
     libdl \
     liblog \
-    libpower \
     libz
 
 LOCAL_STATIC_LIBRARIES := \
diff --git a/main/BUILD.gn b/main/BUILD.gn
new file mode 100644 (file)
index 0000000..37cafbe
--- /dev/null
@@ -0,0 +1,78 @@
+#
+#  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.
+#
+
+shared_library("bluetooth.default") {
+  # HAL layer
+  sources = [
+    "//btif/src/bluetooth.c",
+  ]
+
+  # platform specific
+  sources += [
+    "bte_main.c",
+    "bte_init.c",
+    "bte_logmsg.c",
+    "bte_conf.c",
+    "stack_config.c",
+  ]
+
+  include_dirs = [
+    "//",
+    "//bta/include",
+    "//bta/sys",
+    "//bta/dm",
+    "//btcore/include",
+    "//osi/include",
+    "//gki/common",
+    "//gki/ulinux",
+    "//include",
+    "//stack/include",
+    "//stack/l2cap",
+    "//stack/a2dp",
+    "//stack/btm",
+    "//stack/avdt",
+    "//hci",
+    "//hci/include",
+    "//udrv/include",
+    "//btif/include",
+    "//btif/co",
+    "//hci/includ",
+    "//vnd/include",
+    "//brcm/include",
+    "//embdrv/sbc/encoder/include",
+    "//embdrv/sbc/decoder/include",
+    "//audio_a2dp_hw",
+    "//utils/include",
+  ]
+
+  deps = [
+    "//audio_a2dp_hw:audio.a2dp.default",
+    "//bta",
+    "//btcore",
+    "//btif",
+    "//device",
+    "//embdrv/sbc",
+    "//gki",
+    "//hci",
+    "//osi",
+    "//stack",
+    "//third_party/tinyxml2",
+    "//udrv",
+    "//utils",
+  ]
+
+  libs = [ "-ldl", "-lpthread", "-lresolv", "-lrt", "-lz" ]
+}
index 2bf61da..ff4691e 100644 (file)
@@ -33,11 +33,11 @@ void bte_load_ble_conf(const char* path)
 {
   assert(path != NULL);
 
-  LOG_INFO("%s attempt to load ble stack conf from %s", __func__, path);
+  LOG_INFO(LOG_TAG, "%s attempt to load ble stack conf from %s", __func__, path);
 
   config_t *config = config_new(path);
   if (!config) {
-    LOG_INFO("%s file >%s< not found", __func__, path);
+    LOG_INFO(LOG_TAG, "%s file >%s< not found", __func__, path);
     return;
   }
 
@@ -45,7 +45,7 @@ void bte_load_ble_conf(const char* path)
   if(*ble_adv_tx_power) {
     sscanf(ble_adv_tx_power, "%d,%d,%d,%d,%d", btm_ble_tx_power, btm_ble_tx_power + 1, btm_ble_tx_power + 2,
                                                btm_ble_tx_power + 3, btm_ble_tx_power + 4);
-    LOG_INFO("loaded btm_ble_tx_power: %d, %d, %d, %d, %d", (char)btm_ble_tx_power[0], (char)btm_ble_tx_power[1],
+    LOG_INFO(LOG_TAG, "loaded btm_ble_tx_power: %d, %d, %d, %d, %d", (char)btm_ble_tx_power[0], (char)btm_ble_tx_power[1],
                                         btm_ble_tx_power[2], btm_ble_tx_power[3], btm_ble_tx_power[4]);
   }
   config_free(config);
@@ -59,7 +59,7 @@ void bte_load_did_conf(const char *p_path) {
 
     config_t *config = config_new(p_path);
     if (!config) {
-        LOG_ERROR("%s unable to load DID config '%s'.", __func__, p_path);
+        LOG_ERROR(LOG_TAG, "%s unable to load DID config '%s'.", __func__, p_path);
         return;
     }
 
@@ -68,7 +68,7 @@ void bte_load_did_conf(const char *p_path) {
         snprintf(section_name, sizeof(section_name), "DID%d", i);
 
         if (!config_has_section(config, section_name)) {
-            LOG_DEBUG("%s no section named %s.", __func__, section_name);
+            LOG_DEBUG(LOG_TAG, "%s no section named %s.", __func__, section_name);
             break;
         }
 
@@ -84,23 +84,23 @@ void bte_load_did_conf(const char *p_path) {
 
         if (record.vendor_id_source != DI_VENDOR_ID_SOURCE_BTSIG &&
             record.vendor_id_source != DI_VENDOR_ID_SOURCE_USBIF) {
-            LOG_ERROR("%s invalid vendor id source %d; ignoring DID record %d.", __func__, record.vendor_id_source, i);
+            LOG_ERROR(LOG_TAG, "%s invalid vendor id source %d; ignoring DID record %d.", __func__, record.vendor_id_source, i);
             continue;
         }
 
-        LOG_DEBUG("Device ID record %d : %s", i, (record.primary_record ? "primary" : "not primary"));
-        LOG_DEBUG("  vendorId            = %04x", record.vendor);
-        LOG_DEBUG("  vendorIdSource      = %04x", record.vendor_id_source);
-        LOG_DEBUG("  product             = %04x", record.product);
-        LOG_DEBUG("  version             = %04x", record.version);
-        LOG_DEBUG("  clientExecutableURL = %s", record.client_executable_url);
-        LOG_DEBUG("  serviceDescription  = %s", record.service_description);
-        LOG_DEBUG("  documentationURL    = %s", record.documentation_url);
+        LOG_DEBUG(LOG_TAG, "Device ID record %d : %s", i, (record.primary_record ? "primary" : "not primary"));
+        LOG_DEBUG(LOG_TAG, "  vendorId            = %04x", record.vendor);
+        LOG_DEBUG(LOG_TAG, "  vendorIdSource      = %04x", record.vendor_id_source);
+        LOG_DEBUG(LOG_TAG, "  product             = %04x", record.product);
+        LOG_DEBUG(LOG_TAG, "  version             = %04x", record.version);
+        LOG_DEBUG(LOG_TAG, "  clientExecutableURL = %s", record.client_executable_url);
+        LOG_DEBUG(LOG_TAG, "  serviceDescription  = %s", record.service_description);
+        LOG_DEBUG(LOG_TAG, "  documentationURL    = %s", record.documentation_url);
 
         uint32_t record_handle;
         tBTA_STATUS status = BTA_DmSetLocalDiRecord(&record, &record_handle);
         if (status != BTA_SUCCESS) {
-            LOG_ERROR("%s unable to set device ID record %d: error %d.", __func__, i, status);
+            LOG_ERROR(LOG_TAG, "%s unable to set device ID record %d: error %d.", __func__, i, status);
         }
     }
 
index 3258f47..1ec4e8b 100644 (file)
@@ -16,6 +16,8 @@
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_bte"
+
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/time.h>
 #include <time.h>
 
-#include "bte.h"
+#include "avrc_api.h"
 #include "bta_api.h"
+#include "bte.h"
+#include "btm_api.h"
 #include "btu.h"
-#include "osi/include/config.h"
+#include "gap_api.h"
 #include "gki.h"
 #include "l2c_api.h"
+#include "osi/include/config.h"
+#include "osi/include/log.h"
 #include "osi/include/log.h"
+#include "port_api.h"
+#include "sdp_api.h"
 #include "stack_config.h"
 
-#include "port_api.h"
-#if (AVDT_INCLUDED==TRUE)
-#include "avdt_api.h"
-#endif
-#include "avrc_api.h"
 #if (AVDT_INCLUDED==TRUE)
 #include "avdt_api.h"
 #endif
 #if (BNEP_INCLUDED==TRUE)
 #include "bnep_api.h"
 #endif
-#include "btm_api.h"
-#include "gap_api.h"
 #if (PAN_INCLUDED==TRUE)
 #include "pan_api.h"
 #endif
-#include "sdp_api.h"
-
 #if (BLE_INCLUDED==TRUE)
 #include "gatt_api.h"
 #include "smp_api.h"
 #endif
 
-#define LOGI0(t,s) __android_log_write(ANDROID_LOG_INFO, t, s)
-#define LOGD0(t,s) __android_log_write(ANDROID_LOG_DEBUG, t, s)
-#define LOGW0(t,s) __android_log_write(ANDROID_LOG_WARN, t, s)
-#define LOGE0(t,s) __android_log_write(ANDROID_LOG_ERROR, t, s)
-
 #ifndef DEFAULT_CONF_TRACE_LEVEL
 #define DEFAULT_CONF_TRACE_LEVEL BT_TRACE_LEVEL_WARNING
 #endif
@@ -184,20 +178,20 @@ void LogMsg(uint32_t trace_set_mask, const char *fmt_str, ...) {
 
   switch ( TRACE_GET_TYPE(trace_set_mask) ) {
     case TRACE_TYPE_ERROR:
-      LOGE0(bt_layer_tags[trace_layer], buffer);
+      LOG_ERROR(bt_layer_tags[trace_layer], "%s", buffer);
       break;
     case TRACE_TYPE_WARNING:
-      LOGW0(bt_layer_tags[trace_layer], buffer);
+      LOG_WARN(bt_layer_tags[trace_layer], "%s", buffer);
       break;
     case TRACE_TYPE_API:
     case TRACE_TYPE_EVENT:
-      LOGI0(bt_layer_tags[trace_layer], buffer);
+      LOG_INFO(bt_layer_tags[trace_layer], "%s", buffer);
       break;
     case TRACE_TYPE_DEBUG:
-      LOGD0(bt_layer_tags[trace_layer], buffer);
+      LOG_DEBUG(bt_layer_tags[trace_layer], "%s", buffer);
       break;
     default:
-      LOGE0(bt_layer_tags[trace_layer], buffer);      /* we should never get this */
+      LOG_ERROR(bt_layer_tags[trace_layer], "%s", buffer);      /* we should never get this */
       break;
   }
 }
@@ -228,7 +222,7 @@ static void load_levels_from_config(const config_t *config) {
   assert(config != NULL);
 
   for (tBTTRC_FUNC_MAP *functions = &bttrc_set_level_map[0]; functions->trc_name; ++functions) {
-    LOG_INFO("BTE_InitTraceLevels -- %s", functions->trc_name);
+    LOG_INFO(LOG_TAG, "BTE_InitTraceLevels -- %s", functions->trc_name);
     int value = config_get_int(config, CONFIG_DEFAULT_SECTION, functions->trc_name, -1);
     if (value != -1)
       functions->trace_level = value;
@@ -241,7 +235,7 @@ static void load_levels_from_config(const config_t *config) {
 static future_t *init(void) {
   const stack_config_t *stack_config = stack_config_get_interface();
   if (!stack_config->get_trace_config_enabled()) {
-    LOG_INFO("[bttrc] using compile default trace settings");
+    LOG_INFO(LOG_TAG, "using compile default trace settings");
     return NULL;
   }
 
@@ -249,7 +243,7 @@ static future_t *init(void) {
   return NULL;
 }
 
-const module_t bte_logmsg_module = {
+EXPORT_SYMBOL const module_t bte_logmsg_module = {
   .name = BTE_LOGMSG_MODULE,
   .init = init,
   .start_up = NULL,
index d08d6f6..753cb7c 100644 (file)
 #define LOG_TAG "bt_main"
 
 #include <assert.h>
-#include <cutils/properties.h>
 #include <fcntl.h>
-#include <hardware/bluetooth.h>
 #include <pthread.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <time.h>
 
-#include "osi/include/alarm.h"
-#include "bta_api.h"
+#include <hardware/bluetooth.h>
+
 #include "bt_hci_bdroid.h"
-#include "bte.h"
-#include "btif_common.h"
-#include "btu.h"
-#include "btsnoop.h"
 #include "bt_utils.h"
+#include "bta_api.h"
 #include "btcore/include/counter.h"
 #include "btcore/include/module.h"
+#include "bte.h"
+#include "btif_common.h"
+#include "btsnoop.h"
+#include "btu.h"
+#include "gki.h"
+#include "hci_layer.h"
+#include "osi/include/alarm.h"
 #include "osi/include/fixed_queue.h"
 #include "osi/include/future.h"
-#include "gki.h"
 #include "osi/include/hash_functions.h"
 #include "osi/include/hash_map.h"
-#include "hci_layer.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
-#include "stack_config.h"
+#include "osi/include/osi.h"
 #include "osi/include/thread.h"
+#include "stack_config.h"
 
 /*******************************************************************************
 **  Constants & Macros
 
 /* Run-time configuration file for BLE*/
 #ifndef BTE_BLE_STACK_CONF_FILE
+// TODO(armansito): Find a better way than searching by a hardcoded path.
+#if defined(OS_GENERIC)
+#define BTE_BLE_STACK_CONF_FILE "ble_stack.conf"
+#else  // !defined(OS_GENERIC)
 #define BTE_BLE_STACK_CONF_FILE "/etc/bluetooth/ble_stack.conf"
-#endif
+#endif  // defined(OS_GENERIC)
+#endif  // BT_BLE_STACK_CONF_FILE
 
 /******************************************************************************
 **  Variables
@@ -100,11 +105,11 @@ void bte_main_boot_entry(void)
 
     hci = hci_layer_get_interface();
     if (!hci)
-      LOG_ERROR("%s could not get hci layer interface.", __func__);
+      LOG_ERROR(LOG_TAG, "%s could not get hci layer interface.", __func__);
 
     btu_hci_msg_queue = fixed_queue_new(SIZE_MAX);
     if (btu_hci_msg_queue == NULL) {
-      LOG_ERROR("%s unable to allocate hci message queue.", __func__);
+      LOG_ERROR(LOG_TAG, "%s unable to allocate hci message queue.", __func__);
       return;
     }
 
@@ -213,7 +218,7 @@ void bte_main_enable_lpm(BOOLEAN enable)
 **
 ** Function         bte_main_lpm_allow_bt_device_sleep
 **
-** Description      BTE MAIN API - Allow BT controller goest to sleep
+** Description      BTE MAIN API - Allow the BT controller to go to sleep
 **
 ** Returns          None
 **
index 6e1431e..cbc1c71 100644 (file)
 
 #define LOG_TAG "bt_stack_config"
 
+#include "stack_config.h"
+
 #include <assert.h>
 
 #include "osi/include/future.h"
-#include "stack_config.h"
 #include "osi/include/log.h"
 
 const char *BTSNOOP_LOG_PATH_KEY = "BtSnoopFileName";
@@ -34,14 +35,19 @@ static config_t *config;
 // Module lifecycle functions
 
 static future_t *init() {
+// TODO(armansito): Find a better way than searching by a hardcoded path.
+#if defined(OS_GENERIC)
+  const char *path = "bt_stack.conf";
+#else  // !defined(OS_GENERIC)
   const char *path = "/etc/bluetooth/bt_stack.conf";
+#endif  // defined(OS_GENERIC)
   assert(path != NULL);
 
-  LOG_INFO("%s attempt to load stack conf from %s", __func__, path);
+  LOG_INFO(LOG_TAG, "%s attempt to load stack conf from %s", __func__, path);
 
   config = config_new(path);
   if (!config) {
-    LOG_INFO("%s file >%s< not found", __func__, path);
+    LOG_INFO(LOG_TAG, "%s file >%s< not found", __func__, path);
     return future_new_immediate(FUTURE_FAIL);
   }
 
@@ -53,7 +59,7 @@ static future_t *clean_up() {
   return future_new_immediate(FUTURE_SUCCESS);
 }
 
-const module_t stack_config_module = {
+EXPORT_SYMBOL const module_t stack_config_module = {
   .name = STACK_CONFIG_MODULE,
   .init = init,
   .start_up = NULL,
index 52dc2cf..f2f5af4 100644 (file)
 
 LOCAL_PATH := $(call my-dir)
 
-include $(CLEAR_VARS)
-
-# osi/include/atomic.h depends on gcc atomic functions
-LOCAL_CLANG := false
-
-LOCAL_C_INCLUDES := \
-    $(LOCAL_PATH)/include \
-    $(LOCAL_PATH)/..
+# Common variables
+# ========================================================
 
-LOCAL_SRC_FILES := \
+# TODO(mcchou): Remove socket_utils sources after platform specific
+# dependencies are abstracted.
+btosiCommonSrc := \
     ./src/alarm.c \
     ./src/allocation_tracker.c \
     ./src/allocator.c \
     ./src/array.c \
     ./src/buffer.c \
+    ./src/compat.c \
     ./src/config.c \
     ./src/data_dispatcher.c \
     ./src/eager_reader.c \
@@ -40,56 +37,103 @@ LOCAL_SRC_FILES := \
     ./src/future.c \
     ./src/hash_functions.c \
     ./src/hash_map.c \
+    ./src/hash_map_utils.c \
     ./src/list.c \
     ./src/non_repeating_timer.c \
     ./src/reactor.c \
     ./src/ringbuffer.c \
     ./src/semaphore.c \
     ./src/socket.c \
+    ./src/socket_utils/socket_local_client.c \
+    ./src/socket_utils/socket_local_server.c \
     ./src/thread.c
 
-LOCAL_CFLAGS := -std=c99 -Wall -Werror -UNDEBUG
-# Many .h files have redefined typedefs
-LOCAL_CLANG_CFLAGS += -Wno-error=typedef-redefinition
-LOCAL_MODULE := libosi
-LOCAL_MODULE_TAGS := optional
-LOCAL_SHARED_LIBRARIES := libc liblog
-LOCAL_MODULE_CLASS := STATIC_LIBRARIES
-
-include $(BUILD_STATIC_LIBRARY)
-
-#####################################################
-
-include $(CLEAR_VARS)
-
-# osi/include/atomic.h depends on gcc atomic functions
-LOCAL_CLANG := false
-
-LOCAL_C_INCLUDES := \
-    $(LOCAL_PATH)/include \
-    $(LOCAL_PATH)/..
-
-LOCAL_SRC_FILES := \
+btosiCommonTestSrc := \
     ./test/AlarmTestHarness.cpp \
     ./test/AllocationTestHarness.cpp \
     ./test/alarm_test.cpp \
     ./test/allocation_tracker_test.cpp \
+    ./test/allocator_test.cpp \
     ./test/array_test.cpp \
-    ./test/atomic_test.cpp \
     ./test/config_test.cpp \
     ./test/data_dispatcher_test.cpp \
     ./test/eager_reader_test.cpp \
     ./test/future_test.cpp \
     ./test/hash_map_test.cpp \
+    ./test/hash_map_utils_test.cpp \
     ./test/list_test.cpp \
     ./test/reactor_test.cpp \
     ./test/ringbuffer_test.cpp \
     ./test/thread_test.cpp
 
+btosiCommonIncludes := \
+    $(LOCAL_PATH)/include \
+    $(LOCAL_PATH)/.. \
+    $(LOCAL_PATH)/../utils/include
+
+btosiCommonCFlags := -std=c99 -Wall -Werror -UNDEBUG -fvisibility=hidden
+
+# libosi static library for target
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_C_INCLUDES := $(btosiCommonIncludes)
+LOCAL_SRC_FILES := $(btosiCommonSrc)
+LOCAL_CFLAGS := $(btosiCommonCFlags)
+# Many .h files have redefined typedefs
+LOCAL_CLANG_CFLAGS += -Wno-error=typedef-redefinition
+LOCAL_MODULE := libosi
+LOCAL_MODULE_TAGS := optional
+LOCAL_SHARED_LIBRARIES := libc liblog
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+include $(BUILD_STATIC_LIBRARY)
+
+# libosi static library for host
+# ========================================================
+ifeq ($(HOST_OS),linux)
+include $(CLEAR_VARS)
+LOCAL_C_INCLUDES := $(btosiCommonIncludes)
+LOCAL_SRC_FILES := $(btosiCommonSrc)
+# TODO(armansito): Setting _GNU_SOURCE isn't very platform-independent but
+# should be compatible for a Linux host OS. We should figure out what to do for
+# a non-Linux host OS.
+LOCAL_CFLAGS := \
+       $(btosiCommonCFlags) \
+       -D_GNU_SOURCE
+# Many .h files have redefined typedefs
+LOCAL_CLANG_CFLAGS += -Wno-error=typedef-redefinition
+LOCAL_MODULE := libosi-host
+LOCAL_MODULE_TAGS := optional
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+include $(BUILD_HOST_STATIC_LIBRARY)
+endif
+
+# Note: It's good to get the tests compiled both for the host and the target so
+# we get to test with both Bionic libc and glibc
+
+# libosi unit tests for target
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_C_INCLUDES := $(btosiCommonIncludes)
+LOCAL_SRC_FILES := $(btosiCommonTestSrc)
 LOCAL_CFLAGS := -Wall -UNDEBUG
 LOCAL_MODULE := net_test_osi
 LOCAL_MODULE_TAGS := tests
 LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_STATIC_LIBRARIES := libosi
-
 include $(BUILD_NATIVE_TEST)
+
+# libosi unit tests for host
+# ========================================================
+ifeq ($(HOST_OS),linux)
+include $(CLEAR_VARS)
+LOCAL_C_INCLUDES := $(btosiCommonIncludes)
+LOCAL_SRC_FILES := $(btosiCommonTestSrc)
+LOCAL_CFLAGS := -Wall -UNDEBUG
+LOCAL_LDLIBS := -lrt -lpthread
+LOCAL_MODULE := net_test_osi
+LOCAL_MODULE_TAGS := tests
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_STATIC_LIBRARIES := libosi-host
+include $(BUILD_HOST_NATIVE_TEST)
+endif
diff --git a/osi/BUILD.gn b/osi/BUILD.gn
new file mode 100644 (file)
index 0000000..af72693
--- /dev/null
@@ -0,0 +1,87 @@
+#
+#  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.
+#
+
+static_library("osi") {
+  sources = [
+    "src/alarm.c",
+    "src/allocation_tracker.c",
+    "src/allocator.c",
+    "src/array.c",
+    "src/buffer.c",
+    "src/compat.c",
+    "src/config.c",
+    "src/data_dispatcher.c",
+    "src/eager_reader.c",
+    "src/fixed_queue.c",
+    "src/future.c",
+    "src/hash_functions.c",
+    "src/hash_map.c",
+    "src/hash_map_utils.c",
+    "src/list.c",
+    "src/non_repeating_timer.c",
+    "src/reactor.c",
+    "src/ringbuffer.c",
+    "src/semaphore.c",
+    "src/socket.c",
+
+    # TODO(mcchou): Remove these sources after platform specific
+    # dependencies are abstracted.
+    "src/socket_utils/socket_local_client.c",
+    "src/socket_utils/socket_local_server.c",
+
+    "src/thread.c",
+  ]
+
+  include_dirs = [
+    "include",
+    "//",
+    "//utils/include",
+  ]
+}
+
+executable("net_test_osi") {
+  testonly = true
+  sources = [
+    "test/AlarmTestHarness.cpp",
+    "test/AllocationTestHarness.cpp",
+    "test/alarm_test.cpp",
+    "test/allocation_tracker_test.cpp",
+    "test/allocator_test.cpp",
+    "test/array_test.cpp",
+    "test/config_test.cpp",
+    "test/data_dispatcher_test.cpp",
+    "test/eager_reader_test.cpp",
+    "test/future_test.cpp",
+    "test/hash_map_test.cpp",
+    "test/hash_map_utils_test.cpp",
+    "test/list_test.cpp",
+    "test/reactor_test.cpp",
+    "test/ringbuffer_test.cpp",
+    "test/thread_test.cpp",
+  ]
+
+  include_dirs = [
+    "include",
+    "//",
+  ]
+
+  deps = [
+    "//osi",
+    "//third_party/gtest:gtest_main",
+  ]
+
+  libs = [ "-lpthread", "-lrt" ]
+}
index 20f4b66..ffbcb9a 100644 (file)
@@ -34,6 +34,7 @@ extern const allocator_t allocator_malloc;
 extern const allocator_t allocator_calloc;
 
 char *osi_strdup(const char *str);
+char *osi_strndup(const char *str, size_t len);
 
 void *osi_malloc(size_t size);
 void *osi_calloc(size_t size);
diff --git a/osi/include/atomic.h b/osi/include/atomic.h
deleted file mode 100644 (file)
index a38c9c4..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/******************************************************************************
- *
- *  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 <stdbool.h>
-#include <stdint.h>
-
-// Set of atomic operations to work on data structures.
-// The atomic type data should only be manipulated by these functions.
-// This uses the gcc built in functions.
-//  gcc doc section 6.50 "Built-in functions for memory model aware atomic operations"
-//
-// Data types:
-// atomic_<name>_t
-//
-// e.g.
-//  atomic_s32_t for a signed 32 bit integer.
-//  atomic_u32_t for an unsigned 32 bit integer.
-//
-// Functions:
-// atomic_<operation>_<name>(atomic_t *, ...)
-//
-// e.g.
-//  uint32_t atomic_dec_prefix_u32(volatile atomic_u32_t *atomic)
-//
-// The prefix/postfix classification corresponds which value is returned
-// from the function call, the old or the new one.
-
-#if defined(GCC_VERSION) && GCC_VERSION < 40700
-#warning "Atomics not supported"
-#endif
-
-#define ATOMIC_TYPE(name, type) \
-  struct atomic_##name { \
-    type _val; \
-}; \
-typedef struct atomic_##name atomic_##name##_t;
-
-#define ATOMIC_STORE(name, type, sz) \
-static inline void atomic_store_##name(volatile atomic_##name##_t *atomic, type val) { \
-  __atomic_store_##sz(&atomic->_val, val, __ATOMIC_SEQ_CST); \
-}
-
-#define ATOMIC_LOAD(name, type, sz) \
-static inline type atomic_load_##name(volatile atomic_##name##_t *atomic) { \
-  return __atomic_load_##sz(&atomic->_val, __ATOMIC_SEQ_CST); \
-}
-
-// Returns value after operation, e.g. new value
-#define ATOMIC_INC_PREFIX(name, type, sz) \
-static inline type atomic_inc_prefix_##name(volatile atomic_##name##_t *atomic) { \
-  return __atomic_add_fetch_##sz(atomic, 1, __ATOMIC_SEQ_CST); \
-}
-
-// Returns value after operation, e.g. new value
-#define ATOMIC_DEC_PREFIX(name, type, sz) \
-static inline type atomic_dec_prefix_##name(volatile atomic_##name##_t *atomic) { \
-  return __atomic_sub_fetch_##sz(atomic, 1, __ATOMIC_SEQ_CST); \
-}
-
-// Returns value before operation, e.g. old value
-#define ATOMIC_INC_POSTFIX(name, type, sz) \
-static inline type atomic_inc_postfix_##name(volatile atomic_##name##_t *atomic) { \
-  return __atomic_fetch_add_##sz(atomic, 1, __ATOMIC_SEQ_CST); \
-}
-
-// Returns value before operation, e.g. old value
-#define ATOMIC_DEC_POSTFIX(name, type, sz) \
-static inline type atomic_dec_postfix_##name(volatile atomic_##name##_t *atomic) { \
-  return __atomic_fetch_sub_##sz(atomic, 1, __ATOMIC_SEQ_CST); \
-}
-
-// Returns value after operation, e.g. new value
-#define ATOMIC_ADD(name, type, sz) \
-static inline type atomic_add_##name(volatile atomic_##name##_t *atomic, type val) { \
-  return __atomic_add_fetch_##sz(atomic, val, __ATOMIC_SEQ_CST); \
-}
-
-// Returns value after operation, e.g. new value
-#define ATOMIC_SUB(name, type, sz) \
-static inline type atomic_sub_##name(volatile atomic_##name##_t *atomic, type val) { \
-  return __atomic_sub_fetch_##sz(atomic, val, __ATOMIC_SEQ_CST); \
-}
-
-#define ATOMIC_MAKE(name, type, sz) \
-  ATOMIC_TYPE(name, type) \
-  ATOMIC_STORE(name, type, sz) \
-  ATOMIC_LOAD(name, type, sz) \
-  ATOMIC_INC_PREFIX(name, type, sz) \
-  ATOMIC_DEC_PREFIX(name, type, sz) \
-  ATOMIC_INC_POSTFIX(name, type, sz) \
-  ATOMIC_DEC_POSTFIX(name, type, sz) \
-  ATOMIC_ADD(name, type, sz) \
-  ATOMIC_SUB(name, type, sz)
-
-ATOMIC_MAKE(s32, int32_t, 4)
-ATOMIC_MAKE(u32, uint32_t, 4)
-ATOMIC_MAKE(s64, int64_t, 8)
-ATOMIC_MAKE(u64, uint64_t, 8)
index 5c32ac7..52862bf 100644 (file)
@@ -19,6 +19,7 @@
 #pragma once
 
 #include <stdbool.h>
+#include <stdlib.h>
 
 struct fixed_queue_t;
 typedef struct fixed_queue_t fixed_queue_t;
index 3d06dd7..422fd39 100644 (file)
@@ -19,6 +19,7 @@
 #pragma once
 
 #include <stdbool.h>
+#include <stddef.h>
 #include <stdint.h>
 
 struct hash_map_t;
@@ -38,7 +39,7 @@ typedef bool (*hash_map_iter_cb)(hash_map_entry_t *hash_entry, void *context);
 
 typedef bool (*key_equality_fn)(const void *x, const void *y);
 
-typedef void (*key_free_fn)(void *data);
+typedef void (*key_free_fn)(void *key);
 typedef void (*data_free_fn)(void *data);
 
 // Returns a new, empty hash_map. Returns NULL if not enough memory could be allocated
diff --git a/osi/include/hash_map_utils.h b/osi/include/hash_map_utils.h
new file mode 100644 (file)
index 0000000..783a5af
--- /dev/null
@@ -0,0 +1,37 @@
+/******************************************************************************
+ *
+ *  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 "osi/include/hash_map.h"
+
+// Creates a hash map based on the |params| string containing key and value
+// pairs.  Pairs are expected in the form "key=value" separated by the ';'
+// character.  Both ';' and '=' characters are invalid in keys or values.
+// |params| cannot be NULL, is not modified and is owned by the caller.
+// Examples:
+//   "key0=value10;key1=value1;" -> map: [key0]="value0" [key1]="value1"
+//   "key0=;key1=value1;"        -> map: [key0]="" [key1]="value1"
+//   "=value0;key1=value1;"      -> map: [key1]="value1"
+// A new hash map or NULL is returned and is owned by the caller.
+hash_map_t *hash_map_utils_new_from_string_params(const char *params);
+
+// Dumps the contents of the hash_map to the log for debugging purposes.
+// If |map| is not NULL, all entries of |map| will be dumped, otherwise nothing
+// will be dumped. Note that this function does not take the ownership of |map|.
+void hash_map_utils_dump_string_keys_string_values(hash_map_t *map);
index a5de1cf..738462e 100644 (file)
 
 #pragma once
 
+/*
+ * TODO(armansito): Work-around until we figure out a way to generate logs in a
+ * platform-independent manner.
+ */
+#if defined(OS_GENERIC)
+
+/* syslog didn't work well here since we would be redefining LOG_DEBUG. */
+#include <stdio.h>
+
+#define LOGWRAPPER(tag, fmt, args...) fprintf(stderr, "%s: " fmt "\n", tag, ## args)
+
+#define LOG_VERBOSE(...) LOGWRAPPER(__VA_ARGS__)
+#define LOG_DEBUG(...) LOGWRAPPER(__VA_ARGS__)
+#define LOG_INFO(...) LOGWRAPPER(__VA_ARGS__)
+#define LOG_WARN(...) LOGWRAPPER(__VA_ARGS__)
+#define LOG_ERROR(...) LOGWRAPPER(__VA_ARGS__)
+
+#else  /* !defined(OS_GENERIC) */
+
 #include <cutils/log.h>
 
-#define LOG_VERBOSE(...) ALOGV(__VA_ARGS__)
-#define LOG_DEBUG(...)   ALOGD(__VA_ARGS__)
-#define LOG_INFO(...)    ALOGI(__VA_ARGS__)
-#define LOG_WARN(...)    ALOGW(__VA_ARGS__)
-#define LOG_ERROR(...)   ALOGE(__VA_ARGS__)
+#if LOG_NDEBUG
+#define LOG_VERBOSE(...) ((void)0)
+#else  // LOG_NDEBUG
+#define LOG_VERBOSE(tag, fmt, args...) ALOG(LOG_VERBOSE, tag, fmt, ## args)
+#endif  // !LOG_NDEBUG
+#define LOG_DEBUG(tag, fmt, args...)   ALOG(LOG_DEBUG, tag, fmt, ## args )
+#define LOG_INFO(tag, fmt, args...)    ALOG(LOG_INFO, tag, fmt, ## args)
+#define LOG_WARN(tag, fmt, args...)    ALOG(LOG_WARN, tag, fmt, ## args)
+#define LOG_ERROR(tag, fmt, args...)   ALOG(LOG_ERROR, tag, fmt, ## args)
+
+#endif  /* defined(OS_GENERIC) */
index c035bf8..73a8db1 100644 (file)
 #define DUMMY_COUNTER(c) CONCAT(__osi_dummy_, c)
 #define DUMMY_PTR DUMMY_COUNTER(__COUNTER__)
 
+// base/macros.h defines a COMPILE_ASSERT macro to the C++11 keyword
+// "static_assert" (it undef's COMPILE_ASSERT before redefining it).
+// C++ code that includes base and osi/include/osi.h can thus easily default to
+// the definition from libbase but we should check here to avoid compile errors.
+#ifndef COMPILE_ASSERT
 #define COMPILE_ASSERT(x) char * DUMMY_PTR = !(x)
+#endif  // COMPILE_ASSERT
 
 typedef uint32_t timeout_t;
+
+// Macros for safe integer to pointer conversion. In the C language, data is
+// commonly cast to opaque pointer containers and back for generic parameter
+// passing in callbacks. These macros should be used sparingly in new code
+// (never in C++ code). Whenever integers need to be passed as a pointer, use
+// these macros.
+#define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
+#define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u)))
+
+#define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
+#define INT_TO_PTR(i) ((void *) ((intptr_t) (i)))
diff --git a/osi/include/socket_utils/socket_local.h b/osi/include/socket_utils/socket_local.h
new file mode 100644 (file)
index 0000000..1471b00
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * 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
+
+#define FILESYSTEM_SOCKET_PREFIX "/tmp/"
+#define ANDROID_RESERVED_SOCKET_PREFIX "/dev/socket/"
+
+/*
+ * Set up a given sockaddr_un, to have it refer to the given
+ * name in the given namespace. The namespace must be one
+ * of <code>ANDROID_SOCKET_NAMESPACE_ABSTRACT</code>,
+ * <code>ANDROID_SOCKET_NAMESPACE_RESERVED</code>, or
+ * <code>ANDROID_SOCKET_NAMESPACE_FILESYSTEM</code>. Upon success,
+ * the pointed at sockaddr_un is filled in and the pointed at
+ * socklen_t is set to indicate the final length. This function
+ * will fail if the namespace is invalid (not one of the indicated
+ * constants) or if the name is too long.
+ *
+ * @return 0 on success or -1 on failure
+ */
+int osi_socket_make_sockaddr_un(const char *name, int namespaceId,
+                                struct sockaddr_un *p_addr, socklen_t *alen);
diff --git a/osi/include/socket_utils/sockets.h b/osi/include/socket_utils/sockets.h
new file mode 100644 (file)
index 0000000..5f0ac3a
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * 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 <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+
+#define ANDROID_SOCKET_ENV_PREFIX "ANDROID_SOCKET_"
+#define ANDROID_SOCKET_DIR "/dev/socket"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * osi_android_get_control_socket - simple helper function to get the file
+ * descriptor of our init-managed Unix domain socket. `name' is the name of the
+ * socket, as given in init.rc. Returns -1 on error.
+ *
+ * This is inline and not in libcutils proper because we want to use this in
+ * third-party daemons with minimal modification.
+ */
+static inline int osi_android_get_control_socket(const char *name) {
+  char key[64];
+  snprintf(key, sizeof(key), ANDROID_SOCKET_ENV_PREFIX "%s", name);
+
+  const char *val = getenv(key);
+  if (!val) {
+    return -1;
+  }
+
+  errno = 0;
+  int fd = strtol(val, NULL, 10);
+  if (errno) {
+    return -1;
+  }
+
+  return fd;
+}
+
+/*
+ * See also android.os.LocalSocketAddress.Namespace
+ */
+// Linux "abstract" (non-filesystem) namespace
+#define ANDROID_SOCKET_NAMESPACE_ABSTRACT 0
+// Android "reserved" (/dev/socket) namespace
+#define ANDROID_SOCKET_NAMESPACE_RESERVED 1
+// Normal filesystem namespace
+#define ANDROID_SOCKET_NAMESPACE_FILESYSTEM 2
+
+extern int osi_socket_local_server(const char *name, int namespaceId, int type);
+extern int osi_socket_local_server_bind(int s, const char *name,
+                                        int namespaceId);
+extern int osi_socket_local_client_connect(int fd, const char *name,
+                                           int namespaceId, int type);
+extern int osi_socket_local_client(const char *name, int namespaceId, int type);
+
+#ifdef __cplusplus
+}
+#endif
index 761c6f3..8774769 100644 (file)
 
 #define LOG_TAG "bt_osi_alarm"
 
+#include "osi/include/alarm.h"
+
 #include <assert.h>
 #include <errno.h>
-#include <hardware/bluetooth.h>
 #include <inttypes.h>
 #include <malloc.h>
-#include <string.h>
+#include <pthread.h>
 #include <signal.h>
+#include <string.h>
 #include <time.h>
 
-#include "osi/include/alarm.h"
+#include <hardware/bluetooth.h>
+
 #include "osi/include/allocator.h"
 #include "osi/include/list.h"
 #include "osi/include/log.h"
@@ -42,7 +45,7 @@ struct alarm_t {
   // a guarantee to its caller that the callback will not be in progress when it
   // returns.
   pthread_mutex_t callback_lock;
-  period_ms_t created;
+  period_ms_t creation_time;
   period_ms_t period;
   period_ms_t deadline;
   bool is_periodic;
@@ -91,7 +94,7 @@ alarm_t *alarm_new(void) {
 
   alarm_t *ret = osi_calloc(sizeof(alarm_t));
   if (!ret) {
-    LOG_ERROR("%s unable to allocate memory for alarm.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for alarm.", __func__);
     goto error;
   }
 
@@ -99,13 +102,13 @@ alarm_t *alarm_new(void) {
   // within the callback function of the alarm.
   int error = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
   if (error) {
-    LOG_ERROR("%s unable to create a recursive mutex: %s", __func__, strerror(error));
+    LOG_ERROR(LOG_TAG, "%s unable to create a recursive mutex: %s", __func__, strerror(error));
     goto error;
   }
 
   error = pthread_mutex_init(&ret->callback_lock, &attr);
   if (error) {
-    LOG_ERROR("%s unable to initialize mutex: %s", __func__, strerror(error));
+    LOG_ERROR(LOG_TAG, "%s unable to initialize mutex: %s", __func__, strerror(error));
     goto error;
   }
 
@@ -155,7 +158,7 @@ static void alarm_set_internal(alarm_t *alarm, period_ms_t period, alarm_callbac
 
   pthread_mutex_lock(&monitor);
 
-  alarm->created = now();
+  alarm->creation_time = now();
   alarm->is_periodic = is_periodic;
   alarm->period = period;
   alarm->callback = cb;
@@ -215,7 +218,7 @@ static bool lazy_initialize(void) {
 
   alarms = list_new(NULL);
   if (!alarms) {
-    LOG_ERROR("%s unable to allocate alarm list.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate alarm list.", __func__);
     return false;
   }
 
@@ -224,20 +227,20 @@ static bool lazy_initialize(void) {
   sigevent.sigev_notify = SIGEV_THREAD;
   sigevent.sigev_notify_function = (void (*)(union sigval))timer_callback;
   if (timer_create(CLOCK_ID, &sigevent, &timer) == -1) {
-    LOG_ERROR("%s unable to create timer: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to create timer: %s", __func__, strerror(errno));
     return false;
   }
 
   alarm_expired = semaphore_new(0);
   if (!alarm_expired) {
-    LOG_ERROR("%s unable to create alarm expired semaphore", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create alarm expired semaphore", __func__);
     return false;
   }
 
   callback_thread_active = true;
   callback_thread = thread_new("alarm_callbacks");
   if (!callback_thread) {
-    LOG_ERROR("%s unable to create alarm callback thread.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create alarm callback thread.", __func__);
     return false;
   }
 
@@ -250,7 +253,7 @@ static period_ms_t now(void) {
 
   struct timespec ts;
   if (clock_gettime(CLOCK_ID, &ts) == -1) {
-    LOG_ERROR("%s unable to get current time: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to get current time: %s", __func__, strerror(errno));
     return 0;
   }
 
@@ -267,7 +270,7 @@ static void schedule_next_instance(alarm_t *alarm, bool force_reschedule) {
 
   // Calculate the next deadline for this alarm
   period_ms_t just_now = now();
-  period_ms_t ms_into_period = alarm->is_periodic ? ((just_now - alarm->created) % alarm->period) : 0;
+  period_ms_t ms_into_period = alarm->is_periodic ? ((just_now - alarm->creation_time) % alarm->period) : 0;
   alarm->deadline = just_now + (alarm->period - ms_into_period);
 
   // Add it into the timer list sorted by deadline (earliest deadline first).
@@ -305,7 +308,7 @@ static void reschedule_root_alarm(void) {
     if (!timer_set) {
       int status = bt_os_callouts->acquire_wake_lock(WAKE_LOCK_ID);
       if (status != BT_STATUS_SUCCESS) {
-        LOG_ERROR("%s unable to acquire wake lock: %d", __func__, status);
+        LOG_ERROR(LOG_TAG, "%s unable to acquire wake lock: %d", __func__, status);
         goto done;
       }
     }
@@ -314,7 +317,7 @@ static void reschedule_root_alarm(void) {
     wakeup_time.it_value.tv_nsec = (next->deadline % 1000) * 1000000LL;
   } else {
     if (!bt_os_callouts->set_wake_alarm(next_expiration, true, timer_callback, NULL))
-      LOG_ERROR("%s unable to set wake alarm for %" PRId64 "ms.", __func__, next_expiration);
+      LOG_ERROR(LOG_TAG, "%s unable to set wake alarm for %" PRId64 "ms.", __func__, next_expiration);
   }
 
 done:
@@ -324,7 +327,7 @@ done:
   }
 
   if (timer_settime(timer, TIMER_ABSTIME, &wakeup_time, NULL) == -1)
-    LOG_ERROR("%s unable to set timer: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to set timer: %s", __func__, strerror(errno));
 
   // If next expiration was in the past (e.g. short timer that got context switched)
   // then the timer might have diarmed itself. Detect this case and work around it
@@ -339,7 +342,7 @@ done:
     struct itimerspec time_to_expire;
     timer_gettime(timer, &time_to_expire);
     if (time_to_expire.it_value.tv_sec == 0 && time_to_expire.it_value.tv_nsec == 0) {
-      LOG_ERROR("%s alarm expiration too close for posix timers, switching to guns", __func__);
+      LOG_ERROR(LOG_TAG, "%s alarm expiration too close for posix timers, switching to guns", __func__);
       semaphore_post(alarm_expired);
     }
   }
@@ -395,5 +398,5 @@ static void callback_dispatch(UNUSED_ATTR void *context) {
     pthread_mutex_unlock(&alarm->callback_lock);
   }
 
-  LOG_DEBUG("%s Callback thread exited", __func__);
+  LOG_DEBUG(LOG_TAG, "%s Callback thread exited", __func__);
 }
index 761e58d..1815be9 100644 (file)
 
 #define LOG_TAG "bt_osi_allocation_tracker"
 
+#include "osi/include/allocation_tracker.h"
+
 #include <assert.h>
 #include <pthread.h>
-#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include "osi/include/allocation_tracker.h"
 #include "osi/include/allocator.h"
 #include "osi/include/hash_functions.h"
 #include "osi/include/hash_map.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 
 typedef struct {
   uint8_t allocator_id;
@@ -147,7 +147,7 @@ void *allocation_tracker_notify_alloc(uint8_t allocator_id, void *ptr, size_t re
   return return_ptr;
 }
 
-void *allocation_tracker_notify_free(uint8_t allocator_id, void *ptr) {
+void *allocation_tracker_notify_free(UNUSED_ATTR uint8_t allocator_id, void *ptr) {
   if (!allocations || !ptr)
     return ptr;
 
@@ -159,8 +159,8 @@ void *allocation_tracker_notify_free(uint8_t allocator_id, void *ptr) {
   assert(allocation->allocator_id == allocator_id); // Must be from the same allocator
   allocation->freed = true;
 
-  const char *beginning_canary = ((char *)ptr) - canary_size;
-  const char *end_canary = ((char *)ptr) + allocation->size;
+  UNUSED_ATTR const char *beginning_canary = ((char *)ptr) - canary_size;
+  UNUSED_ATTR const char *end_canary = ((char *)ptr) + allocation->size;
 
   for (size_t i = 0; i < canary_size; i++) {
     assert(beginning_canary[i] == canary[i]);
@@ -180,7 +180,7 @@ static bool allocation_entry_freed_checker(hash_map_entry_t *entry, void *contex
   allocation_t *allocation = (allocation_t *)entry->data;
   if (!allocation->freed) {
     *((size_t *)context) += allocation->size; // Report back the unfreed byte count
-    LOG_ERROR("%s found unfreed allocation. address: 0x%zx size: %zd bytes", __func__, (uintptr_t)allocation->ptr, allocation->size);
+    LOG_ERROR(LOG_TAG, "%s found unfreed allocation. address: 0x%zx size: %zd bytes", __func__, (uintptr_t)allocation->ptr, allocation->size);
   }
 
   return true;
index 7ebeb5e..ceb1618 100644 (file)
@@ -15,7 +15,6 @@
  *  limitations under the License.
  *
  ******************************************************************************/
-
 #include <stdlib.h>
 #include <string.h>
 
@@ -29,13 +28,32 @@ char *osi_strdup(const char *str) {
   size_t real_size = allocation_tracker_resize_for_canary(size);
 
   char *new_string = allocation_tracker_notify_alloc(
-    alloc_allocator_id,
-    malloc(real_size),
-    size);
+      alloc_allocator_id,
+      malloc(real_size),
+      size);
+  if (!new_string)
+    return NULL;
+
+  memcpy(new_string, str, size);
+  return new_string;
+}
+
+char *osi_strndup(const char *str, size_t len) {
+  size_t size = strlen(str);
+  if (len < size)
+    size = len;
+
+  size_t real_size = allocation_tracker_resize_for_canary(size + 1);
+
+  char *new_string = allocation_tracker_notify_alloc(
+      alloc_allocator_id,
+      malloc(real_size),
+      size + 1);
   if (!new_string)
     return NULL;
 
   memcpy(new_string, str, size);
+  new_string[size] = '\0';
   return new_string;
 }
 
index c2ef1bc..8291dbb 100644 (file)
 
 #define LOG_TAG "bt_osi_array"
 
+#include "osi/include/array.h"
+
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "osi/include/allocator.h"
-#include "osi/include/array.h"
 #include "osi/include/log.h"
 
 struct array_t {
@@ -43,7 +44,7 @@ array_t *array_new(size_t element_size) {
 
   array_t *array = osi_calloc(sizeof(array_t) + element_size * INTERNAL_ELEMENTS);
   if (!array) {
-    LOG_ERROR("%s unable to allocate memory for array with elements of size %zu.", __func__, element_size);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for array with elements of size %zu.", __func__, element_size);
     return NULL;
   }
 
@@ -87,7 +88,7 @@ bool array_append_ptr(array_t *array, void *data) {
   assert(data != NULL);
 
   if (array->length == array->capacity && !grow(array)) {
-    LOG_ERROR("%s unable to grow array past current capacity of %zu elements of size %zu.", __func__, array->capacity, array->element_size);
+    LOG_ERROR(LOG_TAG, "%s unable to grow array past current capacity of %zu elements of size %zu.", __func__, array->capacity, array->element_size);
     return false;
   }
 
index ebf51aa..cbd1e23 100644 (file)
 
 #define LOG_TAG "bt_osi_buffer"
 
+#include "osi/include/buffer.h"
+
 #include <assert.h>
 #include <stdint.h>
 
 #include "osi/include/allocator.h"
-#include "osi/include/buffer.h"
 #include "osi/include/log.h"
 
 struct buffer_t {
@@ -37,7 +38,7 @@ buffer_t *buffer_new(size_t size) {
 
   buffer_t *buffer = osi_calloc(sizeof(buffer_t) + size);
   if (!buffer) {
-    LOG_ERROR("%s unable to allocate buffer of %zu bytes.", __func__, size);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate buffer of %zu bytes.", __func__, size);
     return NULL;
   }
 
@@ -60,7 +61,7 @@ buffer_t *buffer_new_slice(const buffer_t *buf, size_t slice_size) {
 
   buffer_t *ret = osi_calloc(sizeof(buffer_t));
   if (!ret) {
-    LOG_ERROR("%s unable to allocate new buffer for slice of length %zu.", __func__, slice_size);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate new buffer for slice of length %zu.", __func__, slice_size);
     return NULL;
   }
 
index 11a5baf..2488a70 100644 (file)
 
 #define LOG_TAG "bt_osi_config"
 
+#include "osi/include/config.h"
+
 #include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 #include <sys/stat.h>
 
 #include "osi/include/allocator.h"
-#include "osi/include/config.h"
 #include "osi/include/list.h"
 #include "osi/include/log.h"
 
@@ -61,13 +63,13 @@ static entry_t *entry_find(const config_t *config, const char *section, const ch
 config_t *config_new_empty(void) {
   config_t *config = osi_calloc(sizeof(config_t));
   if (!config) {
-    LOG_ERROR("%s unable to allocate memory for config_t.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for config_t.", __func__);
     goto error;
   }
 
   config->sections = list_new(section_free);
   if (!config->sections) {
-    LOG_ERROR("%s unable to allocate list for sections.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate list for sections.", __func__);
     goto error;
   }
 
@@ -87,7 +89,7 @@ config_t *config_new(const char *filename) {
 
   FILE *fp = fopen(filename, "rt");
   if (!fp) {
-    LOG_ERROR("%s unable to open file '%s': %s", __func__, filename, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to open file '%s': %s", __func__, filename, strerror(errno));
     config_free(config);
     return NULL;
   }
@@ -253,7 +255,7 @@ bool config_save(const config_t *config, const char *filename) {
 
   char *temp_filename = osi_calloc(strlen(filename) + 5);
   if (!temp_filename) {
-    LOG_ERROR("%s unable to allocate memory for filename.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for filename.", __func__);
     return false;
   }
 
@@ -262,7 +264,7 @@ bool config_save(const config_t *config, const char *filename) {
 
   FILE *fp = fopen(temp_filename, "wt");
   if (!fp) {
-    LOG_ERROR("%s unable to write file '%s': %s", __func__, temp_filename, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to write file '%s': %s", __func__, temp_filename, strerror(errno));
     goto error;
   }
 
@@ -285,12 +287,12 @@ bool config_save(const config_t *config, const char *filename) {
 
   // Change the file's permissions to Read/Write by User and Group
   if (chmod(temp_filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) == -1) {
-    LOG_ERROR("%s unable to change file permissions '%s': %s", __func__, filename, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to change file permissions '%s': %s", __func__, filename, strerror(errno));
     goto error;
   }
 
   if (rename(temp_filename, filename) == -1) {
-    LOG_ERROR("%s unable to commit file '%s': %s", __func__, filename, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to commit file '%s': %s", __func__, filename, strerror(errno));
     goto error;
   }
 
@@ -338,7 +340,7 @@ static void config_parse(FILE *fp, config_t *config) {
     if (*line_ptr == '[') {
       size_t len = strlen(line_ptr);
       if (line_ptr[len - 1] != ']') {
-        LOG_DEBUG("%s unterminated section name on line %d.", __func__, line_num);
+        LOG_DEBUG(LOG_TAG, "%s unterminated section name on line %d.", __func__, line_num);
         continue;
       }
       strncpy(section, line_ptr + 1, len - 2);
@@ -346,7 +348,7 @@ static void config_parse(FILE *fp, config_t *config) {
     } else {
       char *split = strchr(line_ptr, '=');
       if (!split) {
-        LOG_DEBUG("%s no key/value separator found on line %d.", __func__, line_num);
+        LOG_DEBUG(LOG_TAG, "%s no key/value separator found on line %d.", __func__, line_num);
         continue;
       }
 
index 3186737..659769b 100644 (file)
 
 #define LOG_TAG "bt_osi_data_dispatcher"
 
+#include "osi/include/data_dispatcher.h"
+
 #include <assert.h>
 
 #include "osi/include/allocator.h"
-#include "osi/include/data_dispatcher.h"
 #include "osi/include/hash_functions.h"
 #include "osi/include/hash_map.h"
 #include "osi/include/osi.h"
@@ -40,19 +41,19 @@ data_dispatcher_t *data_dispatcher_new(const char *name) {
 
   data_dispatcher_t *ret = osi_calloc(sizeof(data_dispatcher_t));
   if (!ret) {
-    LOG_ERROR("%s unable to allocate memory for new data dispatcher.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for new data dispatcher.", __func__);
     goto error;
   }
 
   ret->dispatch_table = hash_map_new(DEFAULT_TABLE_BUCKETS, hash_function_naive, NULL, NULL, NULL);
   if (!ret->dispatch_table) {
-    LOG_ERROR("%s unable to create dispatch table.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create dispatch table.", __func__);
     goto error;
   }
 
   ret->name = osi_strdup(name);
   if (!ret->name) {
-    LOG_ERROR("%s unable to duplicate provided name.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to duplicate provided name.", __func__);
     goto error;
   }
 
@@ -100,7 +101,7 @@ bool data_dispatcher_dispatch(data_dispatcher_t *dispatcher, data_dispatcher_typ
   if (queue)
     fixed_queue_enqueue(queue, data);
   else
-    LOG_WARN("%s has no handler for type (%zd) in data dispatcher named: %s", __func__, type, dispatcher->name);
+    LOG_WARN(LOG_TAG, "%s has no handler for type (%zd) in data dispatcher named: %s", __func__, type, dispatcher->name);
 
   return queue != NULL;
 }
index 63b190e..78d6eac 100644 (file)
 
 #define LOG_TAG "bt_osi_eager_reader"
 
+#include "osi/include/eager_reader.h"
+
 #include <assert.h>
 #include <errno.h>
-#include <stddef.h>
 #include <string.h>
 #include <sys/eventfd.h>
+#include <unistd.h>
 
-#include "osi/include/allocator.h"
-#include "osi/include/eager_reader.h"
 #include "osi/include/fixed_queue.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 #include "osi/include/reactor.h"
 #include "osi/include/thread.h"
 
@@ -78,7 +78,7 @@ eager_reader_t *eager_reader_new(
 
   eager_reader_t *ret = osi_calloc(sizeof(eager_reader_t));
   if (!ret) {
-    LOG_ERROR("%s unable to allocate memory for new eager_reader.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for new eager_reader.", __func__);
     goto error;
   }
 
@@ -87,7 +87,7 @@ eager_reader_t *eager_reader_new(
 
   ret->bytes_available_fd = eventfd(0, 0);
   if (ret->bytes_available_fd == INVALID_FD) {
-    LOG_ERROR("%s unable to create output reading semaphore.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create output reading semaphore.", __func__);
     goto error;
   }
 
@@ -95,13 +95,13 @@ eager_reader_t *eager_reader_new(
 
   ret->buffers = fixed_queue_new(max_buffer_count);
   if (!ret->buffers) {
-    LOG_ERROR("%s unable to create buffers queue.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create buffers queue.", __func__);
     goto error;
   }
 
   ret->inbound_read_thread = thread_new(thread_name);
   if (!ret->inbound_read_thread) {
-    LOG_ERROR("%s unable to make reading thread.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to make reading thread.", __func__);
     goto error;
   }
 
@@ -178,7 +178,7 @@ size_t eager_reader_read(eager_reader_t *reader, uint8_t *buffer, size_t max_siz
   // Find out how many bytes we have available in our various buffers.
   eventfd_t bytes_available;
   if (eventfd_read(reader->bytes_available_fd, &bytes_available) == -1) {
-    LOG_ERROR("%s unable to read semaphore for output data.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to read semaphore for output data.", __func__);
     return 0;
   }
 
@@ -206,7 +206,7 @@ size_t eager_reader_read(eager_reader_t *reader, uint8_t *buffer, size_t max_siz
 
   bytes_available -= bytes_consumed;
   if (eventfd_write(reader->bytes_available_fd, bytes_available) == -1) {
-    LOG_ERROR("%s unable to write back bytes available for output data.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to write back bytes available for output data.", __func__);
   }
 
   return bytes_consumed;
@@ -233,7 +233,7 @@ static void inbound_data_waiting(void *context) {
 
   data_buffer_t *buffer = (data_buffer_t *)reader->allocator->alloc(reader->buffer_size + sizeof(data_buffer_t));
   if (!buffer) {
-    LOG_ERROR("%s couldn't aquire memory for inbound data buffer.", __func__);
+    LOG_ERROR(LOG_TAG, "%s couldn't aquire memory for inbound data buffer.", __func__);
     return;
   }
 
@@ -251,9 +251,9 @@ static void inbound_data_waiting(void *context) {
     eventfd_write(reader->bytes_available_fd, bytes_read);
   } else {
     if (bytes_read == 0)
-      LOG_WARN("%s fd said bytes existed, but none were found.", __func__);
+      LOG_WARN(LOG_TAG, "%s fd said bytes existed, but none were found.", __func__);
     else
-      LOG_WARN("%s unable to read from file descriptor: %s", __func__, strerror(errno));
+      LOG_WARN(LOG_TAG, "%s unable to read from file descriptor: %s", __func__, strerror(errno));
 
     reader->allocator->free(buffer);
   }
index 009e185..4ab5b92 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <assert.h>
 #include <pthread.h>
-#include <stdlib.h>
 
 #include "osi/include/allocator.h"
 #include "osi/include/fixed_queue.h"
index be140ad..e91cdb3 100644 (file)
 
 #define LOG_TAG "bt_osi_future"
 
+#include "osi/include/future.h"
+
 #include <assert.h>
 
 #include "osi/include/allocator.h"
-#include "osi/include/future.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 #include "osi/include/semaphore.h"
 
 struct future_t {
@@ -37,13 +38,13 @@ static void future_free(future_t *future);
 future_t *future_new(void) {
   future_t *ret = osi_calloc(sizeof(future_t));
   if (!ret) {
-    LOG_ERROR("%s unable to allocate memory for return value.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for return value.", __func__);
     goto error;
   }
 
   ret->semaphore = semaphore_new(0);
   if (!ret->semaphore) {
-    LOG_ERROR("%s unable to allocate memory for the semaphore.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for the semaphore.", __func__);
     goto error;
   }
 
@@ -57,7 +58,7 @@ error:;
 future_t *future_new_immediate(void *value) {
   future_t *ret = osi_calloc(sizeof(future_t));
   if (!ret) {
-    LOG_ERROR("%s unable to allocate memory for return value.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for return value.", __func__);
     goto error;
   }
 
index 6d36ec3..c483948 100644 (file)
@@ -21,6 +21,7 @@
 #include <hash_map.h>
 
 #include "osi/include/allocator.h"
+#include "osi/include/osi.h"
 
 struct hash_map_t;
 
@@ -138,7 +139,7 @@ bool hash_map_set(hash_map_t *hash_map, const void *key, void *data) {
 
   if (hash_map_entry) {
     // Calls hash_map callback to delete the hash_map_entry.
-    bool rc = list_remove(hash_bucket_list, hash_map_entry);
+    UNUSED_ATTR bool rc = list_remove(hash_bucket_list, hash_map_entry);
     assert(rc == true);
   } else {
     hash_map->hash_size++;
diff --git a/osi/src/hash_map_utils.c b/osi/src/hash_map_utils.c
new file mode 100644 (file)
index 0000000..a7b3eec
--- /dev/null
@@ -0,0 +1,104 @@
+/******************************************************************************
+ *
+ *  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.
+ *
+ ******************************************************************************/
+#define LOG_TAG "hash_map_utils"
+
+#include "osi/include/hash_map_utils.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include "osi/include/allocator.h"
+#include "osi/include/hash_functions.h"
+#include "osi/include/hash_map.h"
+#include "osi/include/log.h"
+#include "osi/include/osi.h"
+
+static bool string_equals(const void *key_a, const void *key_b);
+static bool dump_entry(hash_map_entry_t *entry, UNUSED_ATTR void *context);
+
+static const size_t BUCKETS_NUM = 5;
+
+hash_map_t *hash_map_utils_new_from_string_params(const char *params) {
+  assert(params != NULL);
+
+  hash_map_t *map = hash_map_new(BUCKETS_NUM, hash_function_string, osi_free,
+                                 osi_free, string_equals);
+  if (!map)
+    return NULL;
+
+  char *str = osi_strdup(params);
+  if (!str)
+    return NULL;
+
+  LOG_VERBOSE(LOG_TAG, "%s: source string: '%s'", __func__, str);
+
+  // Parse |str| and add extracted key-and-value pair(s) in |map|.
+  int items = 0;
+  char *tmpstr;
+  char *kvpair = strtok_r(str, ";", &tmpstr);
+  while (kvpair && *kvpair) {
+    char *eq = strchr(kvpair, '=');
+
+    if (eq == kvpair)
+      goto next_pair;
+
+    char *key;
+    char *value;
+    if (eq) {
+      key = osi_strndup(kvpair, eq - kvpair);
+
+      // The increment of |eq| moves |eq| to the beginning of the value.
+      ++eq;
+      value = (*eq != '\0') ? osi_strdup(eq) : osi_strdup("");
+    } else {
+      key = osi_strdup(kvpair);
+      value = osi_strdup("");
+    }
+
+    hash_map_set(map, key, value);
+
+    items++;
+next_pair:
+    kvpair = strtok_r(NULL, ";", &tmpstr);
+  }
+
+  if (!items)
+    LOG_VERBOSE(LOG_TAG, "%s: no items found in string\n", __func__);
+
+  osi_free(str);
+  return map;
+}
+
+void hash_map_utils_dump_string_keys_string_values(hash_map_t *map) {
+  if (!map) {
+    LOG_VERBOSE( LOG_TAG, "%s: the given map is NULL\n", __func__);
+    return;
+  }
+  hash_map_foreach(map, dump_entry, NULL);
+}
+
+static bool string_equals(const void *key_a, const void *key_b) {
+  return !strcmp(key_a, key_b);
+}
+
+static bool dump_entry(hash_map_entry_t *entry, UNUSED_ATTR void *context) {
+  hash_map_entry_t *hash_map_entry = (hash_map_entry_t *)entry;
+  LOG_INFO(LOG_TAG, "key: '%s' value: '%s'\n", (char *)hash_map_entry->key,
+           (char *)hash_map_entry->data);
+  return true;
+}
index 08b5098..b216fec 100644 (file)
@@ -18,6 +18,8 @@
 
 #define LOG_TAG "bt_osi_reactor"
 
+#include "osi/include/reactor.h"
+
 #include <assert.h>
 #include <errno.h>
 #include <pthread.h>
 #include <string.h>
 #include <sys/epoll.h>
 #include <sys/eventfd.h>
+#include <unistd.h>
 
 #include "osi/include/allocator.h"
 #include "osi/include/list.h"
 #include "osi/include/log.h"
-#include "osi/include/reactor.h"
 
 #if !defined(EFD_SEMAPHORE)
 #  define EFD_SEMAPHORE (1 << 0)
@@ -70,20 +72,20 @@ reactor_t *reactor_new(void) {
 
   ret->epoll_fd = epoll_create(MAX_EVENTS);
   if (ret->epoll_fd == INVALID_FD) {
-    LOG_ERROR("%s unable to create epoll instance: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to create epoll instance: %s", __func__, strerror(errno));
     goto error;
   }
 
   ret->event_fd = eventfd(0, 0);
   if (ret->event_fd == INVALID_FD) {
-    LOG_ERROR("%s unable to create eventfd: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to create eventfd: %s", __func__, strerror(errno));
     goto error;
   }
 
   pthread_mutex_init(&ret->list_lock, NULL);
   ret->invalidation_list = list_new(NULL);
   if (!ret->invalidation_list) {
-    LOG_ERROR("%s unable to allocate object invalidation list.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate object invalidation list.", __func__);
     goto error;
   }
 
@@ -92,7 +94,7 @@ reactor_t *reactor_new(void) {
   event.events = EPOLLIN;
   event.data.ptr = NULL;
   if (epoll_ctl(ret->epoll_fd, EPOLL_CTL_ADD, ret->event_fd, &event) == -1) {
-    LOG_ERROR("%s unable to register eventfd with epoll set: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to register eventfd with epoll set: %s", __func__, strerror(errno));
     goto error;
   }
 
@@ -138,7 +140,7 @@ reactor_object_t *reactor_register(reactor_t *reactor,
 
   reactor_object_t *object = (reactor_object_t *)osi_calloc(sizeof(reactor_object_t));
   if (!object) {
-    LOG_ERROR("%s unable to allocate reactor object: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to allocate reactor object: %s", __func__, strerror(errno));
     return NULL;
   }
 
@@ -158,7 +160,7 @@ reactor_object_t *reactor_register(reactor_t *reactor,
   event.data.ptr = object;
 
   if (epoll_ctl(reactor->epoll_fd, EPOLL_CTL_ADD, fd, &event) == -1) {
-    LOG_ERROR("%s unable to register fd %d to epoll set: %s", __func__, fd, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to register fd %d to epoll set: %s", __func__, fd, strerror(errno));
     pthread_mutex_destroy(&object->lock);
     osi_free(object);
     return NULL;
@@ -181,7 +183,7 @@ bool reactor_change_registration(reactor_object_t *object,
   event.data.ptr = object;
 
   if (epoll_ctl(object->reactor->epoll_fd, EPOLL_CTL_MOD, object->fd, &event) == -1) {
-    LOG_ERROR("%s unable to modify interest set for fd %d: %s", __func__, object->fd, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to modify interest set for fd %d: %s", __func__, object->fd, strerror(errno));
     return false;
   }
 
@@ -199,7 +201,7 @@ void reactor_unregister(reactor_object_t *obj) {
   reactor_t *reactor = obj->reactor;
 
   if (epoll_ctl(reactor->epoll_fd, EPOLL_CTL_DEL, obj->fd, NULL) == -1)
-    LOG_ERROR("%s unable to unregister fd %d from epoll set: %s", __func__, obj->fd, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to unregister fd %d from epoll set: %s", __func__, obj->fd, strerror(errno));
 
   if (reactor->is_running && pthread_equal(pthread_self(), reactor->run_thread)) {
     reactor->object_removed = true;
@@ -245,7 +247,7 @@ static reactor_status_t run_reactor(reactor_t *reactor, int iterations) {
     } while (ret == -1 && errno == EINTR);
 
     if (ret == -1) {
-      LOG_ERROR("%s error in epoll_wait: %s", __func__, strerror(errno));
+      LOG_ERROR(LOG_TAG, "%s error in epoll_wait: %s", __func__, strerror(errno));
       reactor->is_running = false;
       return REACTOR_STATUS_ERROR;
     }
index 5ee9926..8693c9c 100644 (file)
 
 #define LOG_TAG "bt_osi_semaphore"
 
+#include "osi/include/semaphore.h"
+
 #include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <malloc.h>
 #include <string.h>
 #include <sys/eventfd.h>
+#include <unistd.h>
 
 #include "osi/include/allocator.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
-#include "osi/include/semaphore.h"
+#include "osi/include/osi.h"
 
 #if !defined(EFD_SEMAPHORE)
 #  define EFD_SEMAPHORE (1 << 0)
@@ -43,7 +45,7 @@ semaphore_t *semaphore_new(unsigned int value) {
   if (ret) {
     ret->fd = eventfd(value, EFD_SEMAPHORE);
     if (ret->fd == INVALID_FD) {
-      LOG_ERROR("%s unable to allocate semaphore: %s", __func__, strerror(errno));
+      LOG_ERROR(LOG_TAG, "%s unable to allocate semaphore: %s", __func__, strerror(errno));
       osi_free(ret);
       ret = NULL;
     }
@@ -66,7 +68,7 @@ void semaphore_wait(semaphore_t *semaphore) {
 
   uint64_t value;
   if (eventfd_read(semaphore->fd, &value) == -1)
-    LOG_ERROR("%s unable to wait on semaphore: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to wait on semaphore: %s", __func__, strerror(errno));
 }
 
 bool semaphore_try_wait(semaphore_t *semaphore) {
@@ -75,11 +77,11 @@ bool semaphore_try_wait(semaphore_t *semaphore) {
 
   int flags = fcntl(semaphore->fd, F_GETFL);
   if (flags == -1) {
-    LOG_ERROR("%s unable to get flags for semaphore fd: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to get flags for semaphore fd: %s", __func__, strerror(errno));
     return false;
   }
   if (fcntl(semaphore->fd, F_SETFL, flags | O_NONBLOCK) == -1) {
-    LOG_ERROR("%s unable to set O_NONBLOCK for semaphore fd: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to set O_NONBLOCK for semaphore fd: %s", __func__, strerror(errno));
     return false;
   }
 
@@ -88,7 +90,7 @@ bool semaphore_try_wait(semaphore_t *semaphore) {
     return false;
 
   if (fcntl(semaphore->fd, F_SETFL, flags) == -1)
-    LOG_ERROR("%s unable to resetore flags for semaphore fd: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to resetore flags for semaphore fd: %s", __func__, strerror(errno));
   return true;
 }
 
@@ -97,7 +99,7 @@ void semaphore_post(semaphore_t *semaphore) {
   assert(semaphore->fd != INVALID_FD);
 
   if (eventfd_write(semaphore->fd, 1ULL) == -1)
-    LOG_ERROR("%s unable to post to semaphore: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to post to semaphore: %s", __func__, strerror(errno));
 }
 
 int semaphore_get_fd(const semaphore_t *semaphore) {
index 91f084e..90fbb97 100644 (file)
@@ -18,6 +18,8 @@
 
 #define LOG_TAG "bt_osi_socket"
 
+#include "osi/include/socket.h"
+
 #include <asm/ioctls.h>
 #include <assert.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
-#include <sys/types.h>
 #include <unistd.h>
 
 #include "osi/include/allocator.h"
-#include "osi/include/osi.h"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 #include "osi/include/reactor.h"
-#include "osi/include/socket.h"
 
 // The IPv4 loopback address: 127.0.0.1
 static const in_addr_t LOCALHOST_ = 0x7f000001;
@@ -51,19 +51,19 @@ static void internal_write_ready(void *context);
 socket_t *socket_new(void) {
   socket_t *ret = (socket_t *)osi_calloc(sizeof(socket_t));
   if (!ret) {
-    LOG_ERROR("%s unable to allocate memory for socket.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for socket.", __func__);
     goto error;
   }
 
   ret->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
   if (ret->fd == INVALID_FD) {
-    LOG_ERROR("%s unable to create socket: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to create socket: %s", __func__, strerror(errno));
     goto error;
   }
 
   int enable = 1;
   if (setsockopt(ret->fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)) == -1) {
-    LOG_ERROR("%s unable to set SO_REUSEADDR: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to set SO_REUSEADDR: %s", __func__, strerror(errno));
     goto error;
   }
 
@@ -81,7 +81,7 @@ socket_t *socket_new_from_fd(int fd) {
 
   socket_t *ret = (socket_t *)osi_calloc(sizeof(socket_t));
   if (!ret) {
-    LOG_ERROR("%s unable to allocate memory for socket.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for socket.", __func__);
     return NULL;
   }
 
@@ -106,12 +106,12 @@ bool socket_listen(const socket_t *socket, port_t port) {
   addr.sin_addr.s_addr = htonl(LOCALHOST_);
   addr.sin_port = htons(port);
   if (bind(socket->fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
-    LOG_ERROR("%s unable to bind socket to port %u: %s", __func__, port, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to bind socket to port %u: %s", __func__, port, strerror(errno));
     return false;
   }
 
   if (listen(socket->fd, 10) == -1) {
-    LOG_ERROR("%s unable to listen on port %u: %s", __func__, port, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to listen on port %u: %s", __func__, port, strerror(errno));
     return false;
   }
 
@@ -123,14 +123,14 @@ socket_t *socket_accept(const socket_t *socket) {
 
   int fd = accept(socket->fd, NULL, NULL);
   if (fd == INVALID_FD) {
-    LOG_ERROR("%s unable to accept socket: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to accept socket: %s", __func__, strerror(errno));
     return NULL;
   }
 
   socket_t *ret = (socket_t *)osi_calloc(sizeof(socket_t));
   if (!ret) {
     close(fd);
-    LOG_ERROR("%s unable to allocate memory for socket.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for socket.", __func__);
     return NULL;
   }
 
diff --git a/osi/src/socket_utils/README b/osi/src/socket_utils/README
new file mode 100644 (file)
index 0000000..8616447
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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.
+ */
+
+The sources in this folder re-implement some of the sources in libcutils/sockets
+to provide a short-term solution eliminating libcutils dependency from
+system/bt. Once a long-term platform-independent abstraction is presented, these
+sources and the corresponding headers should be removed.
+
+Note that only a part of the source files are pulled from libcutils/sockets, and
+"osi_" prefix is added to all functions. The developers who want to pull sockets
+sources other than the existing ones must put the sources in this folder and
+refactor the functions as well.
+
+The current sources include:
+
+[Headers]
+ - osi/include/socket_utils/sockets.h
+ - osi/include/socket_utils/socket_local.h
+[Source files]
+ - osi/src/socket_utils/socket_local_client.c
+ - osi/src/socket_utils/socket_local_server.c
+
+Please update the above list if adding more sources.
diff --git a/osi/src/socket_utils/socket_local_client.c b/osi/src/socket_utils/socket_local_client.c
new file mode 100644 (file)
index 0000000..ccfe743
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * 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 <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "osi/include/osi.h"
+#include "osi/include/socket_utils/sockets.h"
+#include "osi/include/socket_utils/socket_local.h"
+
+#define LISTEN_BACKLOG 4
+
+/* Documented in header file. */
+int osi_socket_make_sockaddr_un(const char *name, int namespaceId,
+                                struct sockaddr_un *p_addr, socklen_t *alen) {
+  memset(p_addr, 0, sizeof(*p_addr));
+  size_t namelen;
+
+  switch (namespaceId) {
+    case ANDROID_SOCKET_NAMESPACE_ABSTRACT:
+#if defined(__linux__)
+      namelen = strlen(name);
+
+      // Test with length +1 for the *initial* '\0'.
+      if ((namelen + 1) > sizeof(p_addr->sun_path)) {
+        goto error;
+      }
+
+      /*
+       * Note: The path in this case is *not* supposed to be
+       * '\0'-terminated. ("man 7 unix" for the gory details.)
+       */
+
+      p_addr->sun_path[0] = 0;
+      memcpy(p_addr->sun_path + 1, name, namelen);
+#else
+      /* this OS doesn't have the Linux abstract namespace */
+
+      namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX);
+      /* unix_path_max appears to be missing on linux */
+      if (namelen >
+          sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) {
+        goto error;
+      }
+
+      strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX);
+      strcat(p_addr->sun_path, name);
+#endif
+      break;
+
+    case ANDROID_SOCKET_NAMESPACE_RESERVED:
+      namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX);
+      /* unix_path_max appears to be missing on linux */
+      if (namelen >
+          sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) {
+        goto error;
+      }
+
+      strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX);
+      strcat(p_addr->sun_path, name);
+      break;
+
+    case ANDROID_SOCKET_NAMESPACE_FILESYSTEM:
+      namelen = strlen(name);
+      /* unix_path_max appears to be missing on linux */
+      if (namelen >
+          sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) {
+        goto error;
+      }
+
+      strcpy(p_addr->sun_path, name);
+      break;
+    default:
+      // invalid namespace id
+      return -1;
+  }
+
+  p_addr->sun_family = AF_LOCAL;
+  *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
+  return 0;
+error:
+  return -1;
+}
+
+/**
+ * connect to peer named "name" on fd
+ * returns same fd or -1 on error.
+ * fd is not closed on error. that's your job.
+ *
+ * Used by AndroidSocketImpl
+ */
+int osi_socket_local_client_connect(int fd, const char *name, int namespaceId,
+                                    int type UNUSED_ATTR) {
+  struct sockaddr_un addr;
+  socklen_t alen;
+  int err;
+
+  err = osi_socket_make_sockaddr_un(name, namespaceId, &addr, &alen);
+
+  if (err < 0) {
+    goto error;
+  }
+
+  if (connect(fd, (struct sockaddr *)&addr, alen) < 0) {
+    goto error;
+  }
+
+  return fd;
+
+error:
+  return -1;
+}
+
+/**
+ * connect to peer named "name"
+ * returns fd or -1 on error
+ */
+int osi_socket_local_client(const char *name, int namespaceId, int type) {
+  int s;
+
+  s = socket(AF_LOCAL, type, 0);
+  if (s < 0) return -1;
+
+  if (0 > osi_socket_local_client_connect(s, name, namespaceId, type)) {
+    close(s);
+    return -1;
+  }
+
+  return s;
+}
diff --git a/osi/src/socket_utils/socket_local_server.c b/osi/src/socket_utils/socket_local_server.c
new file mode 100644 (file)
index 0000000..466cc1c
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2006, The Android Open Source Project
+ *
+ * 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 <errno.h>
+#include <netinet/in.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/select.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "osi/include/socket_utils/sockets.h"
+#include "osi/include/socket_utils/socket_local.h"
+
+#define LISTEN_BACKLOG 4
+
+/* Only the bottom bits are really the socket type; there are flags too. */
+#define SOCK_TYPE_MASK 0xf
+
+/**
+ * Binds a pre-created socket(AF_LOCAL) 's' to 'name'
+ * returns 's' on success, -1 on fail
+ *
+ * Does not call listen()
+ */
+int osi_socket_local_server_bind(int s, const char *name, int namespaceId) {
+  struct sockaddr_un addr;
+  socklen_t alen;
+  int n;
+  int err;
+
+  err = osi_socket_make_sockaddr_un(name, namespaceId, &addr, &alen);
+
+  if (err < 0) {
+    return -1;
+  }
+
+/* basically: if this is a filesystem path, unlink first */
+#if !defined(__linux__)
+  if (1) {
+#else
+  if (namespaceId == ANDROID_SOCKET_NAMESPACE_RESERVED ||
+      namespaceId == ANDROID_SOCKET_NAMESPACE_FILESYSTEM) {
+#endif
+    /*ignore ENOENT*/
+    unlink(addr.sun_path);
+  }
+
+  n = 1;
+  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
+
+  if (bind(s, (struct sockaddr *)&addr, alen) < 0) {
+    return -1;
+  }
+
+  return s;
+}
+
+/** Open a server-side UNIX domain datagram socket in the Linux non-filesystem
+ *  namespace
+ *
+ *  Returns fd on success, -1 on fail
+ */
+int osi_socket_local_server(const char *name, int namespace, int type) {
+  int err;
+  int s;
+
+  s = socket(AF_LOCAL, type, 0);
+  if (s < 0) return -1;
+
+  err = osi_socket_local_server_bind(s, name, namespace);
+
+  if (err < 0) {
+    close(s);
+    return -1;
+  }
+
+  if ((type & SOCK_TYPE_MASK) == SOCK_STREAM) {
+    int ret;
+
+    ret = listen(s, LISTEN_BACKLOG);
+
+    if (ret < 0) {
+      close(s);
+      return -1;
+    }
+  }
+
+  return s;
+}
index c6c8979..9410acb 100644 (file)
@@ -18,6 +18,8 @@
 
 #define LOG_TAG "bt_osi_thread"
 
+#include "osi/include/thread.h"
+
 #include <assert.h>
 #include <errno.h>
 #include <malloc.h>
@@ -32,7 +34,6 @@
 #include "osi/include/log.h"
 #include "osi/include/reactor.h"
 #include "osi/include/semaphore.h"
-#include "osi/include/thread.h"
 
 struct thread_t {
   bool is_joined;
@@ -140,7 +141,7 @@ bool thread_post(thread_t *thread, thread_fn func, void *context) {
   // or when the item is removed from the queue for dispatch.
   work_item_t *item = (work_item_t *)osi_malloc(sizeof(work_item_t));
   if (!item) {
-    LOG_ERROR("%s unable to allocate memory: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to allocate memory: %s", __func__, strerror(errno));
     return false;
   }
   item->func = func;
@@ -178,7 +179,7 @@ static void *run_thread(void *start_arg) {
   assert(thread != NULL);
 
   if (prctl(PR_SET_NAME, (unsigned long)thread->name) == -1) {
-    LOG_ERROR("%s unable to set thread name: %s", __func__, strerror(errno));
+    LOG_ERROR(LOG_TAG, "%s unable to set thread name: %s", __func__, strerror(errno));
     start->error = errno;
     semaphore_post(start->start_sem);
     return NULL;
@@ -207,7 +208,7 @@ static void *run_thread(void *start_arg) {
   }
 
   if (count > fixed_queue_capacity(thread->work_queue))
-    LOG_DEBUG("%s growing event queue on shutdown.", __func__);
+    LOG_DEBUG(LOG_TAG, "%s growing event queue on shutdown.", __func__);
 
   return NULL;
 }
diff --git a/osi/test/allocator_test.cpp b/osi/test/allocator_test.cpp
new file mode 100644 (file)
index 0000000..19c175b
--- /dev/null
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ *  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 <cstring>
+
+#include <gtest/gtest.h>
+
+#include "AllocationTestHarness.h"
+
+extern "C" {
+#include "osi/include/allocator.h"
+}
+
+class AllocatorTest : public AllocationTestHarness {};
+
+TEST_F(AllocatorTest, test_osi_strndup) {
+  char str[] = "IloveBluetooth";
+  size_t len = strlen(str);
+  char *copy_str = NULL;
+
+  // len == 0
+  copy_str = osi_strndup(str, 0);
+  EXPECT_EQ(0, strcmp(copy_str, ""));
+  osi_free(copy_str);
+
+  // len == strlen(str)
+  copy_str = osi_strndup(str, len);
+  EXPECT_EQ(0, strcmp(str, copy_str));
+  osi_free(copy_str);
+
+  // len < strlen(str)
+  copy_str = osi_strndup(str, len - 5);
+  EXPECT_EQ(0, strcmp("IloveBlue", copy_str));
+  osi_free(copy_str);
+
+  // len > strlen(str)
+  copy_str = osi_strndup(str, len + 5);
+  EXPECT_EQ(0, strcmp(str, copy_str));
+  osi_free(copy_str);
+}
diff --git a/osi/test/atomic_test.cpp b/osi/test/atomic_test.cpp
deleted file mode 100644 (file)
index b0039ab..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-#include <gtest/gtest.h>
-
-extern "C" {
-#include "atomic.h"
-}
-
-const static size_t ATOMIC_DATA_MAX = 2;
-const static int ATOMIC_MAX_THREADS = 20;
-
-struct atomic_test_s32_s {
-  pthread_t pthread_id;
-  int thread_num;
-  int max_val;
-  atomic_s32_t *data;
-};
-
-void *atomic_thread(void *context) {
-  struct atomic_test_s32_s *at = (struct atomic_test_s32_s *)context;
-  for (int i = 0; i < at->max_val; i++) {
-    usleep(1);
-    atomic_inc_prefix_s32(&at->data[i]);
-  }
-  return NULL;
-}
-
-void *atomic_thread_inc_dec(void *context) {
-  struct atomic_test_s32_s *at = (struct atomic_test_s32_s *)context;
-  for (int i = 0; i < at->max_val; i++) {
-    usleep(1);
-    atomic_inc_prefix_s32(&at->data[i]);
-    usleep(1);
-    atomic_dec_prefix_s32(&at->data[i]);
-  }
-  return NULL;
-}
-
-TEST(AtomicTest, test_store_load_s32) {
-  atomic_s32_t data;
-
-  atomic_store_s32(&data, -1);
-  EXPECT_EQ(-1, atomic_load_s32(&data));
-
-  atomic_store_s32(&data, 0);
-  EXPECT_EQ(0, atomic_load_s32(&data));
-
-  atomic_store_s32(&data, 1);
-  EXPECT_EQ(1, atomic_load_s32(&data));
-
-  atomic_store_s32(&data, 2);
-  EXPECT_EQ(2, atomic_load_s32(&data));
-}
-
-TEST(AtomicTest, test_store_load_u32) {
-  atomic_u32_t data;
-
-  atomic_store_u32(&data, -1);
-  EXPECT_EQ((uint32_t)-1, atomic_load_u32(&data));
-
-  atomic_store_u32(&data, 0);
-  EXPECT_EQ((uint32_t)0, atomic_load_u32(&data));
-
-  atomic_store_u32(&data, 1);
-  EXPECT_EQ((uint32_t)1, atomic_load_u32(&data));
-
-  atomic_store_u32(&data, 2);
-  EXPECT_EQ((uint32_t)2, atomic_load_u32(&data));
-}
-
-TEST(AtomicTest, test_inc_dec_s32) {
-  atomic_s32_t data;
-
-  atomic_store_s32(&data, 0);
-  EXPECT_EQ(0, atomic_load_s32(&data));
-
-  int32_t val = atomic_inc_prefix_s32(&data);
-  EXPECT_EQ(1, atomic_load_s32(&data));
-  EXPECT_EQ(1, val);
-
-  val = atomic_inc_prefix_s32(&data);
-  EXPECT_EQ(2, atomic_load_s32(&data));
-  EXPECT_EQ(2, val);
-
-  val = atomic_inc_prefix_s32(&data);
-  EXPECT_EQ(3, atomic_load_s32(&data));
-  EXPECT_EQ(3, val);
-
-  val = atomic_dec_prefix_s32(&data);
-  EXPECT_EQ(2, val);
-
-  val = atomic_dec_prefix_s32(&data);
-  EXPECT_EQ(1, val);
-  val = atomic_dec_prefix_s32(&data);
-  EXPECT_EQ(0, val);
-  val = atomic_dec_prefix_s32(&data);
-  EXPECT_EQ(-1, val);
-}
-
-TEST(AtomicTest, test_inc_dec_u32) {
-  atomic_u32_t data;
-
-  atomic_store_u32(&data, 0);
-  EXPECT_EQ((unsigned)0, atomic_load_u32(&data));
-
-  uint32_t val = atomic_inc_prefix_u32(&data);
-  EXPECT_EQ((unsigned)1, atomic_load_u32(&data));
-  EXPECT_EQ((unsigned)1, val);
-
-  val = atomic_inc_prefix_u32(&data);
-  EXPECT_EQ((unsigned)2, atomic_load_u32(&data));
-  EXPECT_EQ((unsigned)2, val);
-
-  val = atomic_inc_prefix_u32(&data);
-  EXPECT_EQ((unsigned)3, atomic_load_u32(&data));
-  EXPECT_EQ((unsigned)3, val);
-
-  val = atomic_dec_prefix_u32(&data);
-  EXPECT_EQ((unsigned)2, val);
-
-  val = atomic_dec_prefix_u32(&data);
-  EXPECT_EQ((unsigned)1, val);
-  val = atomic_dec_prefix_u32(&data);
-  EXPECT_EQ((unsigned)0, val);
-  val = atomic_dec_prefix_u32(&data);
-  EXPECT_EQ((unsigned)-1, val);
-}
-
-TEST(AtomicTest, test_atomic_inc_thread) {
-  struct atomic_test_s32_s atomic_test[ATOMIC_MAX_THREADS];
-  atomic_s32_t data[ATOMIC_DATA_MAX];
-
-  memset(&atomic_test, 0, sizeof(atomic_test));
-  memset(data, 0, sizeof(data));
-
-  for (unsigned int i = 0; i < ATOMIC_DATA_MAX; i++) {
-    EXPECT_EQ(0, data[i]._val);
-  }
-
-  for (int i = 0; i < ATOMIC_MAX_THREADS; i++) {
-    atomic_test[i].thread_num = i;
-    atomic_test[i].max_val = ATOMIC_DATA_MAX;
-    atomic_test[i].data = data;
-    pthread_create(&atomic_test[i].pthread_id, NULL, atomic_thread, &atomic_test[i]);
-  }
-
-  for (int i = 0; i < ATOMIC_MAX_THREADS; i++) {
-    int rc = pthread_join(atomic_test[i].pthread_id, NULL);
-    EXPECT_EQ(0, rc);
-  }
-
-  for (unsigned int i = 0; i < ATOMIC_DATA_MAX; i++) {
-    EXPECT_EQ(1 * ATOMIC_MAX_THREADS, data[i]._val);
-  }
-}
-
-TEST(AtomicTest, test_atomic_inc_thread_single) {
-  struct atomic_test_s32_s atomic_test[ATOMIC_MAX_THREADS];
-  atomic_s32_t data;
-
-  memset(&atomic_test, 0, sizeof(atomic_test));
-  memset(&data, 0, sizeof(data));
-
-  EXPECT_EQ(0, data._val);
-
-  for (int i = 0; i < ATOMIC_MAX_THREADS; i++) {
-    atomic_test[i].thread_num = i;
-    atomic_test[i].max_val = 1;
-    atomic_test[i].data = &data;
-    pthread_create(&atomic_test[i].pthread_id, NULL, atomic_thread_inc_dec, &atomic_test[i]);
-  }
-
-  for (int i = 0; i < ATOMIC_MAX_THREADS; i++) {
-    int rc = pthread_join(atomic_test[i].pthread_id, NULL);
-    EXPECT_EQ(0, rc);
-  }
-  EXPECT_EQ(0, data._val);
-}
-
-TEST(AtomicTest, test_store_load_s64) {
-  atomic_s64_t data;
-
-  atomic_store_s64(&data, -1);
-  EXPECT_EQ(-1, atomic_load_s64(&data));
-
-  atomic_store_s64(&data, 0);
-  EXPECT_EQ(0, atomic_load_s64(&data));
-
-  atomic_store_s64(&data, 1);
-  EXPECT_EQ(1, atomic_load_s64(&data));
-
-  atomic_store_s64(&data, 2);
-  EXPECT_EQ(2, atomic_load_s64(&data));
-}
-
-TEST(AtomicTest, test_inc_dec_s64) {
-  atomic_s64_t data;
-
-  atomic_store_s64(&data, 0);
-  EXPECT_EQ(0, atomic_load_s64(&data));
-
-  int64_t val = atomic_inc_prefix_s64(&data);
-  EXPECT_EQ(1, atomic_load_s64(&data));
-  EXPECT_EQ(1, val);
-
-  val = atomic_inc_prefix_s64(&data);
-  EXPECT_EQ(2, atomic_load_s64(&data));
-  EXPECT_EQ(2, val);
-
-  val = atomic_inc_prefix_s64(&data);
-  EXPECT_EQ(3, atomic_load_s64(&data));
-  EXPECT_EQ(3, val);
-
-  val = atomic_dec_prefix_s64(&data);
-  EXPECT_EQ(2, val);
-
-  val = atomic_dec_prefix_s64(&data);
-  EXPECT_EQ(1, val);
-  val = atomic_dec_prefix_s64(&data);
-  EXPECT_EQ(0, val);
-  val = atomic_dec_prefix_s64(&data);
-  EXPECT_EQ(-1, val);
-
-  // Mutating using postfix.
-  val = atomic_inc_postfix_s64(&data);
-  EXPECT_EQ(0, atomic_load_s64(&data));
-  EXPECT_EQ(-1, val);
-
-  val = atomic_inc_postfix_s64(&data);
-  EXPECT_EQ(1, atomic_load_s64(&data));
-  EXPECT_EQ(0, val);
-
-  val = atomic_inc_postfix_s64(&data);
-  EXPECT_EQ(2, atomic_load_s64(&data));
-  EXPECT_EQ(1, val);
-
-  val = atomic_dec_postfix_s64(&data);
-  EXPECT_EQ(2, val);
-
-  val = atomic_dec_postfix_s64(&data);
-  EXPECT_EQ(1, val);
-  val = atomic_dec_postfix_s64(&data);
-  EXPECT_EQ(0, val);
-  val = atomic_dec_postfix_s64(&data);
-  EXPECT_EQ(-1, val);
-  EXPECT_EQ(-2, atomic_load_s64(&data));
-}
-
-TEST(AtomicTest, test_add_sub_u64) {
-  atomic_u64_t data;
-
-  atomic_store_u64(&data, 0);
-  EXPECT_EQ((unsigned)0, atomic_load_u64(&data));
-
-  uint64_t val = atomic_add_u64(&data, 0xffff);
-  EXPECT_EQ((unsigned)0xffff, atomic_load_u64(&data));
-  EXPECT_EQ((unsigned)0xffff, val);
-
-  val = atomic_add_u64(&data, 0xffff);
-  EXPECT_EQ((unsigned)(2 * 0xffff), atomic_load_u64(&data));
-  EXPECT_EQ((unsigned)(2 * 0xffff), val);
-
-  val = atomic_add_u64(&data, 0xffff);
-  EXPECT_EQ((unsigned)(3 * 0xffff), atomic_load_u64(&data));
-  EXPECT_EQ((unsigned)(3 * 0xffff), val);
-  EXPECT_NE((unsigned)(3 * 0xfff0), val);
-
-  val = atomic_sub_u64(&data, 0xffff);
-  EXPECT_EQ((unsigned)(2 * 0xffff), val);
-
-  val = atomic_sub_u64(&data, 0);
-  EXPECT_EQ((unsigned)(2 * 0xffff), val);
-  val = atomic_sub_u64(&data, 0xffff);
-  EXPECT_EQ((unsigned)(1 * 0xffff), val);
-
-  val = atomic_sub_u64(&data, 0xffff);
-  EXPECT_EQ((unsigned)0, val);
-}
-
-
diff --git a/osi/test/hash_map_utils_test.cpp b/osi/test/hash_map_utils_test.cpp
new file mode 100644 (file)
index 0000000..fa3ff07
--- /dev/null
@@ -0,0 +1,122 @@
+/******************************************************************************
+ *
+ *  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 <cstring>
+
+#include <gtest/gtest.h>
+
+#include "AllocationTestHarness.h"
+
+extern "C" {
+#include "osi/include/hash_map.h"
+#include "osi/include/hash_map_utils.h"
+#include "osi/include/allocator.h"
+}
+
+class HashMapUtilsTest : public AllocationTestHarness {
+ protected:
+  virtual void SetUp() {
+    AllocationTestHarness::SetUp();
+    map = NULL;
+  }
+  virtual void TearDown() {
+    hash_map_free(map);
+    AllocationTestHarness::TearDown();
+  }
+
+  hash_map_t *map;
+};
+
+TEST_F(HashMapUtilsTest, test_empty_string_params) {
+  char params[] = "";
+  map = hash_map_utils_new_from_string_params(params);
+  EXPECT_TRUE(hash_map_is_empty(map));
+}
+
+TEST_F(HashMapUtilsTest, test_semicolons) {
+  char params[] = ";;;";
+  map = hash_map_utils_new_from_string_params(params);
+  EXPECT_TRUE(hash_map_is_empty(map));
+}
+
+TEST_F(HashMapUtilsTest, test_equal_sign_in_value) {
+  char params[] = "keyOfSomething=value=OfSomething";
+  char key[] = "keyOfSomething";
+  char value[] = "value=OfSomething";
+  map = hash_map_utils_new_from_string_params(params);
+  EXPECT_EQ(1u, hash_map_size(map));
+  EXPECT_EQ(0, strcmp(value, (char *)hash_map_get(map, key)));
+}
+
+TEST_F(HashMapUtilsTest, test_two_pairs_with_same_key) {
+  char params[] = "key=valu0;key=value1";
+  char key[] = "key";
+  char value1[] = "value1";
+  map = hash_map_utils_new_from_string_params(params);
+  EXPECT_EQ(1u, hash_map_size(map));
+  EXPECT_EQ(0, strcmp(value1, (char *)hash_map_get(map, key)));
+}
+
+TEST_F(HashMapUtilsTest, test_one_key_value_pair_without_semicolon) {
+  char params[] = "keyOfSomething=valueOfSomething";
+  char key[] = "keyOfSomething";
+  char value[] = "valueOfSomething";
+  map = hash_map_utils_new_from_string_params(params);
+  EXPECT_EQ(1u, hash_map_size(map));
+  EXPECT_EQ(0, strcmp(value, (char *)hash_map_get(map, key)));
+}
+
+TEST_F(HashMapUtilsTest, test_one_key_value_pair_with_semicolon) {
+  char params[] = "keyOfSomething=valueOfSomething;";
+  char key[] = "keyOfSomething";
+  char value[] = "valueOfSomething";
+  map = hash_map_utils_new_from_string_params(params);
+  EXPECT_EQ(1u, hash_map_size(map));
+  EXPECT_EQ(0, strcmp(value, (char *)hash_map_get(map, key)));
+}
+
+TEST_F(HashMapUtilsTest, test_one_pair_with_empty_value) {
+  char params[] = "keyOfSomething=;";
+  char key[] = "keyOfSomething";
+  char value[] = "";
+  map = hash_map_utils_new_from_string_params(params);
+  EXPECT_EQ(1u, hash_map_size(map));
+  EXPECT_EQ(0, strcmp(value, (char *)hash_map_get(map, key)));
+}
+
+TEST_F(HashMapUtilsTest, test_one_pair_with_empty_key) {
+  char params[] = "=valueOfSomething;";
+  map = hash_map_utils_new_from_string_params(params);
+  EXPECT_TRUE(hash_map_is_empty(map));
+}
+
+TEST_F(HashMapUtilsTest, test_two_key_value_pairs) {
+  char params[] = "key0=value0;key1=value1;";
+  char key0[] = "key0";
+  char value0[] = "value0";
+  char key1[] = "key1";
+  char value1[] = "value1";
+  map = hash_map_utils_new_from_string_params(params);
+  EXPECT_EQ(2u, hash_map_size(map));
+  EXPECT_EQ(0, strcmp(value0, (char *)hash_map_get(map, key0)));
+  EXPECT_EQ(0, strcmp(value1, (char *)hash_map_get(map, key1)));
+}
+
+TEST_F(HashMapUtilsTest, test_dump_null_map) {
+  hash_map_t *map = NULL;
+  hash_map_utils_dump_string_keys_string_values(map);
+}
index 9e56b65..6e3d45c 100644 (file)
@@ -57,7 +57,7 @@ static future_t *clean_up(void) {
   return NULL;
 }
 
-const module_t profile_manager_module = {
+EXPORT_SYMBOL const module_t profile_manager_module = {
   .name = PROFILE_MANAGER_MODULE,
   .init = init,
   .start_up = NULL,
diff --git a/service/Android.mk b/service/Android.mk
new file mode 100644 (file)
index 0000000..ae42010
--- /dev/null
@@ -0,0 +1,103 @@
+#
+#  Copyright (C) 2015 Google
+#
+#  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)
+
+# Common variables
+# ========================================================
+btserviceCommonSrc := \
+       adapter.cpp \
+       adapter_state.cpp \
+       daemon.cpp \
+       gatt_server.cpp \
+       hal/bluetooth_interface.cpp \
+       ipc/ipc_handler.cpp \
+       ipc/ipc_handler_unix.cpp \
+       ipc/ipc_manager.cpp \
+       ipc/unix_ipc_host.cpp \
+       logging_helpers.cpp \
+       settings.cpp \
+       util/atomic_string.cpp \
+       uuid.cpp
+
+btserviceBinderSrc := \
+       ipc/binder/bluetooth_binder_server.cpp \
+       ipc/binder/IBluetooth.cpp \
+       ipc/binder/IBluetoothCallback.cpp \
+       ipc/binder/ipc_handler_binder.cpp
+
+btserviceCommonIncludes := $(LOCAL_PATH)/../
+
+# Native system service for target
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+       $(btserviceBinderSrc) \
+       $(btserviceCommonSrc) \
+       main.cpp
+LOCAL_C_INCLUDES += $(btserviceCommonIncludes)
+LOCAL_CFLAGS += -std=c++11
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := bluetoothtbd
+LOCAL_REQUIRED_MODULES = bluetooth.default
+LOCAL_STATIC_LIBRARIES += libbtcore
+LOCAL_SHARED_LIBRARIES += \
+       libbinder \
+       libchrome \
+       libcutils \
+       libhardware \
+       liblog \
+       libutils
+include $(BUILD_EXECUTABLE)
+
+# Native system service unittests for host
+# ========================================================
+ifeq ($(HOST_OS),linux)
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+       $(btserviceCommonSrc) \
+       hal/fake_bluetooth_interface.cpp \
+       test/adapter_unittest.cpp \
+       test/fake_hal_util.cpp \
+       test/ipc_unix_unittest.cpp \
+       test/settings_unittest.cpp \
+       test/stub_ipc_handler_binder.cpp \
+       test/uuid_unittest.cpp
+LOCAL_C_INCLUDES += $(btserviceCommonIncludes)
+LOCAL_CFLAGS += -std=c++11
+LOCAL_LDLIBS += -lrt
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := bt_service_unittests
+LOCAL_SHARED_LIBRARIES += libchrome-host
+LOCAL_STATIC_LIBRARIES += libgmock_host liblog
+include $(BUILD_HOST_NATIVE_TEST)
+endif
+
+# Native system service CLI for target
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+       $(btserviceBinderSrc) \
+       adapter_state.cpp \
+       client/main.cpp
+LOCAL_C_INCLUDES += $(btserviceCommonIncludes)
+LOCAL_CFLAGS += -std=c++11
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := bluetooth-cli
+LOCAL_SHARED_LIBRARIES += \
+       libbinder \
+       libchrome \
+       libutils
+include $(BUILD_EXECUTABLE)
diff --git a/service/BUILD.gn b/service/BUILD.gn
new file mode 100644 (file)
index 0000000..b0bc6be
--- /dev/null
@@ -0,0 +1,80 @@
+#
+#  Copyright (C) 2015 Google
+#
+#  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.
+#
+
+source_set("service") {
+  sources = [
+    "a2dp_source.cpp",
+    "core_stack.cpp",
+    "daemon.cpp",
+    "gatt_server.cpp",
+    "ipc/ipc_handler.cpp",
+    "ipc/ipc_handler_unix.cpp",
+    "ipc/ipc_manager.cpp",
+    "ipc/unix_ipc_host.cpp",
+    "logging_helpers.cpp",
+    "settings.cpp",
+    "uuid.cpp"
+  ]
+
+  include_dirs = [
+    "//",
+    "//third_party/libchrome"
+  ]
+}
+
+executable("bluetoothtbd") {
+  sources = [
+    "main.cpp"
+  ]
+
+  deps = [
+    ":service",
+    "//btcore",
+    "//third_party/libchrome:base",
+    "//third_party/modp_b64"
+  ]
+
+  include_dirs = [
+    "//",
+    "//third_party/libchrome"
+  ]
+
+  libs = [ "-ldl", "-lpthread", "-lrt" ]
+}
+
+executable("service_unittests") {
+  testonly = true
+  sources = [
+    "test/fake_hal_util.cpp",
+    "test/ipc_unix_unittest.cpp",
+    "test/settings_unittest.cpp",
+    "test/uuid_unittest.cpp",
+  ]
+
+  include_dirs = [
+    "//",
+    "//third_party/gmock/include",
+    "//third_party/libchrome"
+  ]
+
+  deps = [
+    ":service",
+    "//third_party/gmock:gmock_main",
+    "//third_party/gtest:gtest_main",
+    "//third_party/libchrome:base",
+    "//third_party/modp_b64",
+  ]
+}
diff --git a/service/adapter.cpp b/service/adapter.cpp
new file mode 100644 (file)
index 0000000..aba6c4c
--- /dev/null
@@ -0,0 +1,236 @@
+//
+//  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 "service/adapter.h"
+
+#include <base/logging.h>
+
+#include "service/logging_helpers.h"
+
+namespace bluetooth {
+
+// static
+const char Adapter::kDefaultAddress[] = "00:00:00:00:00:00";
+// static
+const char Adapter::kDefaultName[] = "not-initialized";
+
+void Adapter::Observer::OnAdapterStateChanged(Adapter* adapter,
+                                              AdapterState prev_state,
+                                              AdapterState new_state) {
+  // Default implementation does nothing
+}
+
+Adapter::Adapter()
+    : state_(ADAPTER_STATE_OFF),
+      address_(kDefaultAddress),
+      name_(kDefaultName) {
+  hal::BluetoothInterface::Get()->AddObserver(this);
+  hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_properties();
+}
+
+Adapter::~Adapter() {
+  hal::BluetoothInterface::Get()->RemoveObserver(this);
+}
+
+void Adapter::AddObserver(Observer* observer) {
+  std::lock_guard<std::mutex> lock(observers_lock_);
+  observers_.AddObserver(observer);
+}
+
+void Adapter::RemoveObserver(Observer* observer) {
+  std::lock_guard<std::mutex> lock(observers_lock_);
+  observers_.RemoveObserver(observer);
+}
+
+AdapterState Adapter::GetState() const {
+  return state_.load();
+}
+
+bool Adapter::IsEnabled() const {
+  return state_.load() == ADAPTER_STATE_ON;
+}
+
+bool Adapter::Enable() {
+  AdapterState current_state = GetState();
+  if (current_state != ADAPTER_STATE_OFF) {
+    LOG(INFO) << "Adapter not disabled - state: "
+              << AdapterStateToString(current_state);
+    return false;
+  }
+
+  // Set the state before calling enable() as there might be a race between here
+  // and the AdapterStateChangedCallback.
+  state_ = ADAPTER_STATE_TURNING_ON;
+  NotifyAdapterStateChanged(current_state, state_);
+
+  int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable();
+  if (status != BT_STATUS_SUCCESS) {
+    LOG(ERROR) << "Failed to enable Bluetooth - status: "
+               << BtStatusText((const bt_status_t)status);
+    state_ = ADAPTER_STATE_OFF;
+    NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_ON, state_);
+    return false;
+  }
+
+  return true;
+}
+
+bool Adapter::Disable() {
+  if (!IsEnabled()) {
+    LOG(INFO) << "Adapter is not enabled";
+    return false;
+  }
+
+  AdapterState current_state = GetState();
+
+  // Set the state before calling enable() as there might be a race between here
+  // and the AdapterStateChangedCallback.
+  state_ = ADAPTER_STATE_TURNING_OFF;
+  NotifyAdapterStateChanged(current_state, state_);
+
+  int status = hal::BluetoothInterface::Get()->GetHALInterface()->disable();
+  if (status != BT_STATUS_SUCCESS) {
+    LOG(ERROR) << "Failed to disable Bluetooth - status: "
+               << BtStatusText((const bt_status_t)status);
+    state_ = current_state;
+    NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_OFF, state_);
+    return false;
+  }
+
+  return true;
+}
+
+std::string Adapter::GetName() const {
+  return name_.Get();
+}
+
+bool Adapter::SetName(const std::string& name) {
+  bt_bdname_t hal_name;
+  size_t max_name_len = sizeof(hal_name.name);
+
+  // Include the \0 byte in size measurement.
+  if (name.length() >= max_name_len) {
+    LOG(ERROR) << "Given name \"" << name << "\" is larger than maximum allowed"
+               << " size: " << max_name_len;
+    return false;
+  }
+
+  strncpy(reinterpret_cast<char*>(hal_name.name), name.c_str(),
+          name.length() + 1);
+
+  VLOG(1) << "Setting adapter name: " << name;
+
+  if (!SetAdapterProperty(BT_PROPERTY_BDNAME, &hal_name, sizeof(hal_name))) {
+    LOG(ERROR) << "Failed to set adapter name: " << name;
+    return false;
+  }
+
+  return true;
+}
+
+std::string Adapter::GetAddress() const {
+  return address_.Get();
+}
+
+void Adapter::AdapterStateChangedCallback(bt_state_t state) {
+  LOG(INFO) << "Adapter state changed: " << BtStateText(state);
+
+  AdapterState prev_state = GetState();
+
+  switch (state) {
+  case BT_STATE_OFF:
+    state_ = ADAPTER_STATE_OFF;
+    break;
+
+  case BT_STATE_ON:
+    state_ = ADAPTER_STATE_ON;
+    break;
+
+  default:
+    NOTREACHED();
+  }
+
+  NotifyAdapterStateChanged(prev_state, GetState());
+}
+
+void Adapter::AdapterPropertiesCallback(bt_status_t status,
+                                        int num_properties,
+                                        bt_property_t* properties) {
+  LOG(INFO) << "Adapter properties changed";
+
+  if (status != BT_STATUS_SUCCESS) {
+    LOG(ERROR) << "status: " << BtStatusText(status);
+    return;
+  }
+
+  for (int i = 0; i < num_properties; i++) {
+    bt_property_t* property = properties + i;
+    switch (property->type) {
+      case BT_PROPERTY_BDADDR: {
+        std::string address = BtAddrString(reinterpret_cast<bt_bdaddr_t*>(
+            property->val));
+        LOG(INFO) << "Adapter address changed: " << address;
+        address_.Set(address);
+        break;
+      }
+      case BT_PROPERTY_BDNAME: {
+        bt_bdname_t* hal_name = reinterpret_cast<bt_bdname_t*>(property->val);
+        std::string name = reinterpret_cast<char*>(hal_name->name);
+        LOG(INFO) << "Adapter name changed: " << name;
+        name_.Set(name);
+        break;
+      }
+      default:
+        VLOG(1) << "Unhandled adapter property: "
+                << BtPropertyText(property->type);
+        break;
+    }
+
+    // TODO(armansito): notify others of the updated properties
+  }
+}
+
+bool Adapter::SetAdapterProperty(bt_property_type_t type,
+                                 void* value, int length) {
+  CHECK(length > 0);
+  CHECK(value);
+
+  bt_property_t property;
+  property.len = length;
+  property.val = value;
+  property.type = type;
+
+  int status = hal::BluetoothInterface::Get()->GetHALInterface()->
+      set_adapter_property(&property);
+  if (status != BT_STATUS_SUCCESS) {
+    VLOG(1) << "Failed to set property";
+    return false;
+  }
+
+  return true;
+}
+
+void Adapter::NotifyAdapterStateChanged(AdapterState prev_state,
+                                        AdapterState new_state) {
+  if (prev_state == new_state)
+    return;
+
+  std::lock_guard<std::mutex> lock(observers_lock_);
+  FOR_EACH_OBSERVER(Observer, observers_,
+                    OnAdapterStateChanged(this, prev_state, new_state));
+}
+
+}  // namespace bluetooth
diff --git a/service/adapter.h b/service/adapter.h
new file mode 100644 (file)
index 0000000..dc543fc
--- /dev/null
@@ -0,0 +1,118 @@
+//
+//  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 <atomic>
+#include <mutex>
+#include <string>
+
+#include <base/macros.h>
+#include <base/observer_list.h>
+
+#include "service/adapter_state.h"
+#include "service/hal/bluetooth_interface.h"
+#include "service/util/atomic_string.h"
+
+namespace bluetooth {
+
+// Represents the local Bluetooth adapter.
+class Adapter : hal::BluetoothInterface::Observer {
+ public:
+  // The default values returned before the Adapter is fully initialized and
+  // powered. The complete values for these fields are obtained following a
+  // successful call to "Enable".
+  static const char kDefaultAddress[];
+  static const char kDefaultName[];
+
+  // Observer interface allows other classes to receive notifications from us.
+  // All of the methods in this interface are declared as optional to allow
+  // different layers to process only those events that they are interested in.
+  class Observer {
+   public:
+    virtual ~Observer() = default;
+
+    virtual void OnAdapterStateChanged(Adapter* adapter,
+                                       AdapterState prev_state,
+                                       AdapterState new_state);
+  };
+
+  Adapter();
+  ~Adapter() override;
+
+  // Add or remove an observer.
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
+  // Returns the current Adapter state.
+  AdapterState GetState() const;
+
+  // Returns true, if the adapter radio is current powered.
+  bool IsEnabled() const;
+
+  // Enables Bluetooth. This method will send a request to the Bluetooth adapter
+  // to power up its radio. Returns true, if the request was successfully sent
+  // to the controller, otherwise returns false. A successful call to this
+  // method only means that the enable request has been sent to the Bluetooth
+  // controller and does not imply that the operation itself succeeded.
+  bool Enable();
+
+  // Powers off the Bluetooth radio. Returns true, if the disable request was
+  // successfully sent to the Bluetooth controller.
+  bool Disable();
+
+  // Returns the name currently assigned to the local adapter.
+  std::string GetName() const;
+
+  // Sets the name assigned to the local Bluetooth adapter. This is the name
+  // that the local controller will present to remote devices.
+  bool SetName(const std::string& name);
+
+  // Returns the local adapter addess in string form (XX:XX:XX:XX:XX:XX).
+  std::string GetAddress() const;
+
+ private:
+  // hal::BluetoothInterface::Observer overrides.
+  void AdapterStateChangedCallback(bt_state_t state) override;
+  void AdapterPropertiesCallback(bt_status_t status,
+                                 int num_properties,
+                                 bt_property_t* properties) override;
+
+  // Sends a request to set the given HAL adapter property type and value.
+  bool SetAdapterProperty(bt_property_type_t type, void* value, int length);
+
+  // Helper for invoking observer method.
+  void NotifyAdapterStateChanged(AdapterState prev_state,
+                                 AdapterState new_state);
+
+  // The current adapter state.
+  std::atomic<AdapterState> state_;
+
+  // The Bluetooth device address of the local adapter in string from
+  // (i.e.. XX:XX:XX:XX:XX:XX)
+  util::AtomicString address_;
+
+  // The current local adapter name.
+  util::AtomicString name_;
+
+  // List of observers that are interested in notifications from us.
+  std::mutex observers_lock_;
+  base::ObserverList<Observer> observers_;
+
+  DISALLOW_COPY_AND_ASSIGN(Adapter);
+};
+
+}  // namespace bluetooth
diff --git a/service/adapter_state.cpp b/service/adapter_state.cpp
new file mode 100644 (file)
index 0000000..72b5088
--- /dev/null
@@ -0,0 +1,44 @@
+//
+//  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 "service/adapter_state.h"
+
+namespace bluetooth {
+
+std::string AdapterStateToString(AdapterState state) {
+  switch (state) {
+  case ADAPTER_STATE_DISCONNECTED:
+    return "ADAPTER_STATE_DISCONNECTED";
+  case ADAPTER_STATE_CONNECTING:
+    return "ADAPTER_STATE_CONNECTING";
+  case ADAPTER_STATE_CONNECTED:
+    return "ADAPTER_STATE_CONNECTED";
+  case ADAPTER_STATE_DISCONNECTING:
+    return "ADAPTER_STATE_DISCONNECTING";
+  case ADAPTER_STATE_OFF:
+    return "ADAPTER_STATE_OFF";
+  case ADAPTER_STATE_TURNING_ON:
+    return "ADAPTER_STATE_TURNING_ON";
+  case ADAPTER_STATE_ON:
+    return "ADAPTER_STATE_ON";
+  case ADAPTER_STATE_TURNING_OFF:
+    return "ADAPTER_STATE_TURNING_OFF";
+  default:
+    return "unknown state";
+  }
+}
+
+}  // namespace bluetooth
diff --git a/service/adapter_state.h b/service/adapter_state.h
new file mode 100644 (file)
index 0000000..1b2fbe4
--- /dev/null
@@ -0,0 +1,43 @@
+//
+//  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 <string>
+
+namespace bluetooth {
+
+// Possible Adapter states. The values for each enumration have been copied
+// from frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java.
+// These values need to match their android.bluetooth.BluetoothAdapter
+// counterparts for this to be compatible with the framework, hence we
+// redeclare them here.
+enum AdapterState {
+  ADAPTER_STATE_DISCONNECTED = 0,
+  ADAPTER_STATE_CONNECTING = 1,
+  ADAPTER_STATE_CONNECTED = 2,
+  ADAPTER_STATE_DISCONNECTING = 3,
+  ADAPTER_STATE_OFF = 10,
+  ADAPTER_STATE_TURNING_ON = 11,
+  ADAPTER_STATE_ON = 12,
+  ADAPTER_STATE_TURNING_OFF = 13,
+  ADAPTER_STATE_INVALID = 0xFFFF
+};
+
+// Returns a string for the given Adapter state |state|.
+std::string AdapterStateToString(AdapterState state);
+
+}  // namespace bluetooth
diff --git a/service/client/main.cpp b/service/client/main.cpp
new file mode 100644 (file)
index 0000000..d3cefa1
--- /dev/null
@@ -0,0 +1,258 @@
+//
+//  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 <iostream>
+#include <string>
+
+#include <base/logging.h>
+#include <base/macros.h>
+#include <base/strings/string_split.h>
+#include <base/strings/string_util.h>
+#include <binder/ProcessState.h>
+
+#include "service/adapter_state.h"
+#include "service/ipc/binder/IBluetooth.h"
+#include "service/ipc/binder/IBluetoothCallback.h"
+
+using namespace std;
+
+using android::sp;
+
+using ipc::binder::IBluetooth;
+
+namespace {
+
+#define COLOR_OFF         "\x1B[0m"
+#define COLOR_RED         "\x1B[0;91m"
+#define COLOR_GREEN       "\x1B[0;92m"
+#define COLOR_YELLOW      "\x1B[0;93m"
+#define COLOR_BLUE        "\x1B[0;94m"
+#define COLOR_MAGENTA     "\x1B[0;95m"
+#define COLOR_BOLDGRAY    "\x1B[1;30m"
+#define COLOR_BOLDWHITE   "\x1B[1;37m"
+#define COLOR_BOLDYELLOW  "\x1B[1;93m"
+
+const char kCommandDisable[] = "disable";
+const char kCommandEnable[] = "enable";
+const char kCommandGetState[] = "get-state";
+const char kCommandIsEnabled[] = "is-enabled";
+
+#define CHECK_ARGS_COUNT(args, op, num, msg) \
+  if (!(args.size() op num)) { \
+    PrintError(msg); \
+    return; \
+  }
+#define CHECK_NO_ARGS(args) \
+  CHECK_ARGS_COUNT(args, ==, 0, "Expected no arguments")
+
+// TODO(armansito): Clean up this code. Right now everything is in this
+// monolithic file. We should organize this into different classes for command
+// handling, console output/printing, callback handling, etc.
+// (See http://b/23387611)
+
+// Used to synchronize the printing of the command-line prompt and incoming
+// Binder callbacks.
+std::atomic_bool showing_prompt(false);
+
+void PrintPrompt() {
+  cout << COLOR_BLUE "[FCLI] " COLOR_OFF << flush;
+}
+
+class CLIBluetoothCallback : public ipc::binder::BnBluetoothCallback {
+ public:
+  CLIBluetoothCallback() = default;
+  ~CLIBluetoothCallback() override = default;
+
+  // IBluetoothCallback override:
+  void OnBluetoothStateChange(
+      bluetooth::AdapterState prev_state,
+      bluetooth::AdapterState new_state) override {
+    if (showing_prompt.load())
+      cout << endl;
+    cout << COLOR_BOLDWHITE "Adapter state changed: " COLOR_OFF
+         << COLOR_MAGENTA << AdapterStateToString(prev_state) << COLOR_OFF
+         << COLOR_BOLDWHITE " -> " COLOR_OFF
+         << COLOR_BOLDYELLOW << AdapterStateToString(new_state) << COLOR_OFF
+         << endl << endl;
+    if (showing_prompt.load())
+      PrintPrompt();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CLIBluetoothCallback);
+};
+
+void PrintError(const string& message) {
+  cout << COLOR_RED << message << COLOR_OFF << endl;
+}
+
+void PrintCommandStatus(bool status) {
+  cout << COLOR_BOLDWHITE "Command status: " COLOR_OFF
+       << (status ? (COLOR_GREEN "success") : (COLOR_RED "failure"))
+       << COLOR_OFF << endl << endl;
+}
+
+void PrintFieldAndValue(const string& field, const string& value) {
+  cout << COLOR_BOLDWHITE << field << ": " << COLOR_BOLDYELLOW << value
+       << COLOR_OFF << endl;
+}
+
+void PrintFieldAndBoolValue(const string& field, bool value) {
+  PrintFieldAndValue(field, (value ? "true" : "false"));
+}
+
+void HandleDisable(IBluetooth* bt_iface, const vector<string>& args) {
+  CHECK_NO_ARGS(args);
+  PrintCommandStatus(bt_iface->Disable());
+}
+
+void HandleEnable(IBluetooth* bt_iface, const vector<string>& args) {
+  CHECK_NO_ARGS(args);
+  PrintCommandStatus(bt_iface->Enable());
+}
+
+void HandleGetState(IBluetooth* bt_iface, const vector<string>& args) {
+  CHECK_NO_ARGS(args);
+  bluetooth::AdapterState state = static_cast<bluetooth::AdapterState>(
+      bt_iface->GetState());
+  PrintFieldAndValue("Adapter state", bluetooth::AdapterStateToString(state));
+}
+
+void HandleIsEnabled(IBluetooth* bt_iface, const vector<string>& args) {
+  CHECK_NO_ARGS(args);
+  bool enabled = bt_iface->IsEnabled();
+  PrintFieldAndBoolValue("Adapter enabled", enabled);
+}
+
+void HandleGetLocalAddress(IBluetooth* bt_iface, const vector<string>& args) {
+  CHECK_NO_ARGS(args);
+  string address = bt_iface->GetAddress();
+  PrintFieldAndValue("Adapter address", address);
+}
+
+void HandleSetLocalName(IBluetooth* bt_iface, const vector<string>& args) {
+  CHECK_ARGS_COUNT(args, >=, 1, "No name was given");
+
+  std::string name;
+  for (const auto& arg : args)
+    name += arg + " ";
+
+  base::TrimWhitespaceASCII(name, base::TRIM_TRAILING, &name);
+
+  PrintCommandStatus(bt_iface->SetName(name));
+}
+
+void HandleGetLocalName(IBluetooth* bt_iface, const vector<string>& args) {
+  CHECK_NO_ARGS(args);
+  string name = bt_iface->GetName();
+  PrintFieldAndValue("Adapter name", name);
+}
+
+void HandleAdapterInfo(IBluetooth* bt_iface, const vector<string>& args) {
+  CHECK_NO_ARGS(args);
+
+  cout << COLOR_BOLDWHITE "Adapter Properties: " COLOR_OFF << endl;
+
+  PrintFieldAndValue("\tAddress", bt_iface->GetAddress());
+  PrintFieldAndValue("\tState", bluetooth::AdapterStateToString(
+      static_cast<bluetooth::AdapterState>(bt_iface->GetState())));
+  PrintFieldAndValue("\tName", bt_iface->GetName());
+}
+
+void HandleHelp(IBluetooth* bt_iface, const vector<string>& args);
+
+struct {
+  string command;
+  void (*func)(IBluetooth*, const vector<string>& args);
+  string help;
+} kCommandMap[] = {
+  { "help", HandleHelp, "\t\t\tDisplay this message" },
+  { "disable", HandleDisable, "\t\t\tDisable Bluetooth" },
+  { "enable", HandleEnable, "\t\t\tEnable Bluetooth" },
+  { "get-state", HandleGetState, "\t\tGet the current adapter state" },
+  { "is-enabled", HandleIsEnabled, "\t\tReturn if Bluetooth is enabled" },
+  { "get-local-address", HandleGetLocalAddress,
+    "\tGet the local adapter address" },
+  { "set-local-name", HandleSetLocalName, "\t\tSet the local adapter name" },
+  { "get-local-name", HandleGetLocalName, "\t\tGet the local adapter name" },
+  { "adapter-info", HandleAdapterInfo, "\t\tPrint adapter properties" },
+  {},
+};
+
+void HandleHelp(IBluetooth* /* bt_iface */, const vector<string>& /* args */) {
+  cout << endl;
+  for (int i = 0; kCommandMap[i].func; i++)
+    cout << "\t" << kCommandMap[i].command << kCommandMap[i].help << endl;
+  cout << endl;
+}
+
+}  // namespace
+
+int main() {
+  sp<IBluetooth> bt_iface = IBluetooth::getClientInterface();
+  if (!bt_iface.get()) {
+    LOG(ERROR) << "Failed to obtain handle on IBluetooth";
+    return EXIT_FAILURE;
+  }
+
+  // Initialize the Binder process thread pool. We have to set this up,
+  // otherwise, incoming callbacks from IBluetoothCallback will block the main
+  // thread (in other words, we have to do this as we are a "Binder server").
+  android::ProcessState::self()->startThreadPool();
+
+  // Register Adapter state-change callback
+  sp<CLIBluetoothCallback> callback = new CLIBluetoothCallback();
+  bt_iface->RegisterCallback(callback);
+
+  cout << COLOR_BOLDWHITE << "Fluoride Command-Line Interface\n" << COLOR_OFF
+       << endl
+       << "Type \"help\" to see possible commands.\n"
+       << endl;
+
+  while (true) {
+    string command;
+
+    PrintPrompt();
+
+    showing_prompt = true;
+    getline(cin, command);
+    showing_prompt = false;
+
+    vector<string> args;
+    base::SplitString(command, ' ', &args);
+
+    if (args.empty())
+      continue;
+
+    // The first argument is the command while the remaning are what we pass to
+    // the handler functions.
+    command = args[0];
+    args.erase(args.begin());
+
+    bool command_handled = false;
+    for (int i = 0; kCommandMap[i].func && !command_handled; i++) {
+      if (command == kCommandMap[i].command) {
+        kCommandMap[i].func(bt_iface.get(), args);
+        command_handled = true;
+      }
+    }
+
+    if (!command_handled)
+      cout << "Unrecognized command: " << command << endl;
+  }
+
+  return EXIT_SUCCESS;
+}
diff --git a/service/daemon.cpp b/service/daemon.cpp
new file mode 100644 (file)
index 0000000..7e754f7
--- /dev/null
@@ -0,0 +1,160 @@
+//
+//  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 "service/daemon.h"
+
+#include <memory>
+
+#include <base/logging.h>
+
+#include "service/adapter.h"
+#include "service/hal/bluetooth_interface.h"
+#include "service/ipc/ipc_manager.h"
+#include "service/settings.h"
+
+namespace bluetooth {
+
+namespace {
+
+// The global Daemon instance.
+Daemon* g_daemon = nullptr;
+
+class DaemonImpl : public Daemon {
+ public:
+  DaemonImpl() : initialized_(false) {
+  }
+
+  ~DaemonImpl() override {
+    if (!initialized_)
+      return;
+
+    CleanUpBluetoothStack();
+  }
+
+  void StartMainLoop() override {
+    message_loop_->Run();
+  }
+
+  Settings* GetSettings() const override {
+    return settings_.get();
+  }
+
+  base::MessageLoop* GetMessageLoop() const override {
+    return message_loop_.get();
+  }
+
+ private:
+  void CleanUpBluetoothStack() {
+    // The Adapter object needs to be cleaned up before the HAL interfaces.
+    ipc_manager_.reset();
+    adapter_.reset();
+    hal::BluetoothInterface::CleanUp();
+  }
+
+  bool SetUpIPC() {
+    // If an IPC socket path was given, initialize IPC with it. Otherwise
+    // initialize Binder IPC.
+    if (settings_->UseSocketIPC()) {
+      if (!ipc_manager_->Start(ipc::IPCManager::TYPE_UNIX, nullptr)) {
+        LOG(ERROR) << "Failed to set up UNIX domain-socket IPCManager";
+        return false;
+      }
+    } else if (!ipc_manager_->Start(ipc::IPCManager::TYPE_BINDER, nullptr)) {
+      LOG(ERROR) << "Failed to set up Binder IPCManager";
+      return false;
+    }
+
+    return true;
+  }
+
+  bool Init() override {
+    CHECK(!initialized_);
+    message_loop_.reset(new base::MessageLoop());
+
+    settings_.reset(new Settings());
+    if (!settings_->Init()) {
+      LOG(ERROR) << "Failed to set up Settings";
+      return false;
+    }
+
+    if (!hal::BluetoothInterface::Initialize()) {
+      LOG(ERROR) << "Failed to set up BluetoothInterface";
+      return false;
+    }
+
+    adapter_.reset(new Adapter());
+    ipc_manager_.reset(new ipc::IPCManager(adapter_.get()));
+
+    if (!SetUpIPC()) {
+      CleanUpBluetoothStack();
+      return false;
+    }
+
+    initialized_ = true;
+    LOG(INFO) << "Daemon initialized";
+
+    return true;
+  }
+
+  bool initialized_;
+  std::unique_ptr<base::MessageLoop> message_loop_;
+  std::unique_ptr<Settings> settings_;
+  std::unique_ptr<Adapter> adapter_;
+  std::unique_ptr<ipc::IPCManager> ipc_manager_;
+
+  DISALLOW_COPY_AND_ASSIGN(DaemonImpl);
+};
+
+}  // namespace
+
+// static
+bool Daemon::Initialize() {
+  CHECK(!g_daemon);
+
+  g_daemon = new DaemonImpl();
+  if (g_daemon->Init())
+    return true;
+
+  LOG(ERROR) << "Failed to initialize the Daemon object";
+
+  delete g_daemon;
+  g_daemon = nullptr;
+
+  return false;
+}
+
+// static
+void Daemon::ShutDown() {
+  CHECK(g_daemon);
+  delete g_daemon;
+  g_daemon = nullptr;
+}
+
+// static
+void Daemon::InitializeForTesting(Daemon* test_daemon) {
+  CHECK(test_daemon);
+  CHECK(!g_daemon);
+
+  g_daemon = test_daemon;
+}
+
+// static
+Daemon* Daemon::Get() {
+  CHECK(g_daemon);
+  return g_daemon;
+}
+
+}  // namespace bluetooth
diff --git a/service/daemon.h b/service/daemon.h
new file mode 100644 (file)
index 0000000..c792dfc
--- /dev/null
@@ -0,0 +1,74 @@
+//
+//  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/macros.h>
+#include <base/message_loop/message_loop.h>
+
+namespace ipc {
+class IPCManager;
+}  // namespace ipc
+
+namespace bluetooth {
+
+class CoreStack;
+class Settings;
+
+// The Daemon class is a singleton that represents the root of the ownership
+// hierarchy. The single instance sets up and owns the main event loop, the IPC
+// handlers, global Settings, and the core Bluetooth stack.
+class Daemon {
+ public:
+  // Initializes the daemon. This must be called to at the start of the
+  // application to set up the global daemon instance and everything it manages.
+  // Returns false in case of a failure.
+  static bool Initialize();
+
+  // Cleans up all the resources associated with the global Daemon object.
+  static void ShutDown();
+
+  // Assigns the global Daemon instance for testing. Should only be called from
+  // test code.
+  static void InitializeForTesting(Daemon* test_daemon);
+
+  // Returns the singleton Daemon instance. All classes can interact with the
+  // Daemon, obtain its resources etc using this getter.
+  static Daemon* Get();
+
+  // The global Settings object. All classes have direct access to this through
+  // the Daemon object.
+  virtual Settings* GetSettings() const  = 0;
+
+  // The main event loop. This should be used for any events and delayed tasks
+  // that should be executed on the daemon's main thread.
+  virtual base::MessageLoop* GetMessageLoop() const = 0;
+
+  // Starts the daemon's main loop.
+  virtual void StartMainLoop() = 0;
+
+ protected:
+  Daemon() = default;
+  virtual ~Daemon() = default;
+
+ private:
+  // Internal instance helper called by Initialize().
+  virtual bool Init() = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(Daemon);
+};
+
+}  // namespace bluetooth
diff --git a/service/gatt_server.cpp b/service/gatt_server.cpp
new file mode 100644 (file)
index 0000000..b5efebe
--- /dev/null
@@ -0,0 +1,780 @@
+//
+//  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.
+//
+
+#define LOG_TAG "bt_gatts"
+
+#include "gatt_server.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <array>
+#include <condition_variable>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_gatt.h>
+
+#include "service/hal/bluetooth_interface.h"
+#include "service/logging_helpers.h"
+#include "service/uuid.h"
+
+extern "C" {
+#include "osi/include/log.h"
+#include "osi/include/osi.h"
+}  // extern "C"
+
+namespace {
+
+const size_t kMaxGattAttributeSize = 512;
+// TODO(icoolidge): Difficult to generalize without knowing how many attributes.
+const int kNumBlueDroidHandles = 60;
+
+// TODO(icoolidge): Support multiple instances
+// TODO(armansito): Remove this variable. No point of having this if
+// each bluetooth::gatt::Server instance already keeps a pointer to the
+// ServerInternals that is associated with it (which is much cleaner). It looks
+// like this variable exists because the btif callbacks don't allow the
+// upper-layer to pass user data to them. We could:
+//
+//    1. Fix the btif callbacks so that some sort of continuation can be
+//    attached to a callback. This might be a long shot since the callback
+//    interface doesn't allow more than one caller to register its own callbacks
+//    (which might be what we want though, since this would make the API more
+//    flexible).
+//
+//    2. Allow creation of Server objects using a factory method that returns
+//    the result asynchronously in a base::Callback. The RegisterServerCallback
+//    provides an |app_uuid|, which can be used to store callback structures in
+//    a map and lazily instantiate the Server and invoke the correct callback.
+//    This is a general pattern that we should use throughout the daemon, since
+//    all operations can timeout or fail and this is best reported in an
+//    asynchronous base::Callback.
+//
+static bluetooth::gatt::ServerInternals *g_internal = nullptr;
+
+enum { kPipeReadEnd = 0, kPipeWriteEnd = 1, kPipeNumEnds = 2 };
+
+}  // namespace
+
+namespace bluetooth {
+namespace gatt {
+
+struct Characteristic {
+  UUID uuid;
+  int blob_section;
+  std::vector<uint8_t> blob;
+
+  // Support synchronized blob updates by latching under mutex.
+  std::vector<uint8_t> next_blob;
+  bool next_blob_pending;
+  bool notify;
+};
+
+struct ServerInternals {
+  ServerInternals();
+  ~ServerInternals();
+  int Initialize();
+  bt_status_t AddCharacteristic(
+      const UUID& uuid,
+      int properties,
+      int permissions);
+
+  // This maps API attribute UUIDs to BlueDroid handles.
+  std::map<UUID, int> uuid_to_attribute;
+
+  // The attribute cache, indexed by BlueDroid handles.
+  std::unordered_map<int, Characteristic> characteristics;
+
+  // Associate a control attribute with its value attribute.
+  std::unordered_map<int, int> controlled_blobs;
+
+  ScanResults scan_results;
+
+  UUID last_write;
+  const btgatt_interface_t *gatt;
+  int server_if;
+  int client_if;
+  int service_handle;
+  btgatt_srvc_id_t service_id;
+  std::set<int> connections;
+
+  std::mutex lock;
+  std::condition_variable api_synchronize;
+  int pipefd[kPipeNumEnds];
+};
+
+}  // namespace gatt
+}  // namespace bluetooth
+
+namespace {
+
+/** Callback invoked in response to register_server */
+void RegisterServerCallback(int status, int server_if, bt_uuid_t *app_uuid) {
+  LOG_INFO(LOG_TAG, "%s: status:%d server_if:%d app_uuid:%p", __func__, status,
+           server_if, app_uuid);
+
+  g_internal->server_if = server_if;
+
+  btgatt_srvc_id_t service_id;
+  service_id.id.uuid = *app_uuid;
+  service_id.id.inst_id = 0;
+  service_id.is_primary = true;
+
+  g_internal->gatt->server->add_service(
+      server_if, &service_id, kNumBlueDroidHandles);
+}
+
+void ServiceAddedCallback(int status, int server_if, btgatt_srvc_id_t *srvc_id,
+                          int srvc_handle) {
+  LOG_INFO(LOG_TAG, "%s: status:%d server_if:%d gatt_srvc_id:%u srvc_handle:%d",
+           __func__, status, server_if, srvc_id->id.inst_id, srvc_handle);
+
+  std::lock_guard<std::mutex> lock(g_internal->lock);
+  g_internal->server_if = server_if;
+  g_internal->service_handle = srvc_handle;
+  g_internal->service_id = *srvc_id;
+  // This finishes the Initialize call.
+  g_internal->api_synchronize.notify_one();
+}
+
+void RequestReadCallback(int conn_id, int trans_id, bt_bdaddr_t *bda,
+                         int attr_handle, int attribute_offset_octets,
+                         bool is_long) {
+  std::lock_guard<std::mutex> lock(g_internal->lock);
+
+  bluetooth::gatt::Characteristic &ch = g_internal->characteristics[attr_handle];
+
+  // Latch next_blob to blob on a 'fresh' read.
+  if (ch.next_blob_pending && attribute_offset_octets == 0 &&
+      ch.blob_section == 0) {
+    std::swap(ch.blob, ch.next_blob);
+    ch.next_blob_pending = false;
+  }
+
+  const size_t blob_offset_octets =
+      std::min(ch.blob.size(), ch.blob_section * kMaxGattAttributeSize);
+  const size_t blob_remaining = ch.blob.size() - blob_offset_octets;
+  const size_t attribute_size = std::min(kMaxGattAttributeSize, blob_remaining);
+
+  std::string addr(BtAddrString(bda));
+  LOG_INFO(LOG_TAG,
+      "%s: connection:%d (%s) reading attr:%d attribute_offset_octets:%d "
+      "blob_section:%u (is_long:%u)",
+      __func__, conn_id, addr.c_str(), attr_handle, attribute_offset_octets,
+      ch.blob_section, is_long);
+
+  btgatt_response_t response;
+  response.attr_value.len = 0;
+
+  if (attribute_offset_octets < static_cast<int>(attribute_size)) {
+    std::copy(ch.blob.begin() + blob_offset_octets + attribute_offset_octets,
+              ch.blob.begin() + blob_offset_octets + attribute_size,
+              response.attr_value.value);
+    response.attr_value.len = attribute_size - attribute_offset_octets;
+  }
+
+  response.attr_value.handle = attr_handle;
+  response.attr_value.offset = attribute_offset_octets;
+  response.attr_value.auth_req = 0;
+  g_internal->gatt->server->send_response(conn_id, trans_id, 0, &response);
+}
+
+void RequestWriteCallback(int conn_id, int trans_id, bt_bdaddr_t *bda,
+                          int attr_handle, int attribute_offset, int length,
+                          bool need_rsp, bool is_prep, uint8_t *value) {
+  std::string addr(BtAddrString(bda));
+  LOG_INFO(LOG_TAG,
+      "%s: connection:%d (%s:trans:%d) write attr:%d attribute_offset:%d "
+      "length:%d "
+      "need_resp:%u is_prep:%u",
+      __func__, conn_id, addr.c_str(), trans_id, attr_handle, attribute_offset,
+      length, need_rsp, is_prep);
+
+  std::lock_guard<std::mutex> lock(g_internal->lock);
+
+  bluetooth::gatt::Characteristic &ch =
+      g_internal->characteristics[attr_handle];
+
+  ch.blob.resize(attribute_offset + length);
+
+  std::copy(value, value + length, ch.blob.begin() + attribute_offset);
+
+  auto target_blob = g_internal->controlled_blobs.find(attr_handle);
+  // If this is a control attribute, adjust offset of the target blob.
+  if (target_blob != g_internal->controlled_blobs.end() &&
+      ch.blob.size() == 1u) {
+    g_internal->characteristics[target_blob->second].blob_section = ch.blob[0];
+    LOG_INFO(LOG_TAG, "%s: updating attribute %d blob_section to %u", __func__,
+        target_blob->second, ch.blob[0]);
+  } else if (!is_prep) {
+    // This is a single frame characteristic write.
+    // Notify upwards because we're done now.
+    const bluetooth::UUID::UUID128Bit &attr_uuid = ch.uuid.GetFullBigEndian();
+    int status = write(g_internal->pipefd[kPipeWriteEnd], attr_uuid.data(),
+                       attr_uuid.size());
+    if (-1 == status)
+      LOG_ERROR(LOG_TAG, "%s: write failed: %s", __func__, strerror(errno));
+  } else {
+    // This is a multi-frame characteristic write.
+    // Wait for an 'RequestExecWriteCallback' to notify completion.
+    g_internal->last_write = ch.uuid;
+  }
+
+  // Respond only if needed.
+  if (!need_rsp) return;
+
+  btgatt_response_t response;
+  response.attr_value.handle = attr_handle;
+  response.attr_value.offset = attribute_offset;
+  response.attr_value.len = length;
+  response.attr_value.auth_req = 0;
+  // Provide written data back to sender for the response.
+  // Remote stacks use this to validate the success of the write.
+  std::copy(value, value + length, response.attr_value.value);
+  g_internal->gatt->server->send_response(conn_id, trans_id, 0, &response);
+}
+
+void RequestExecWriteCallback(int conn_id, int trans_id, bt_bdaddr_t *bda,
+                              int exec_write) {
+  std::string addr(BtAddrString(bda));
+  LOG_INFO(LOG_TAG, "%s: connection:%d (%s:trans:%d) exec_write:%d", __func__,
+      conn_id, addr.c_str(), trans_id, exec_write);
+
+  // This 'response' data is unused for ExecWriteResponses.
+  // It is only used to pass BlueDroid argument validation.
+  btgatt_response_t response = {};
+  g_internal->gatt->server->send_response(conn_id, trans_id, 0, &response);
+
+  if (!exec_write)
+    return;
+
+  std::lock_guard<std::mutex> lock(g_internal->lock);
+  // Communicate the attribute UUID as notification of a write update.
+  const bluetooth::UUID::UUID128Bit uuid =
+      g_internal->last_write.GetFullBigEndian();
+  int status = write(g_internal->pipefd[kPipeWriteEnd],
+                     uuid.data(), uuid.size());
+  if (-1 == status)
+    LOG_ERROR(LOG_TAG, "%s: write failed: %s", __func__, strerror(errno));
+}
+
+void ConnectionCallback(int conn_id, int server_if, int connected,
+                        bt_bdaddr_t *bda) {
+  std::string addr(BtAddrString(bda));
+  LOG_INFO(LOG_TAG, "%s: connection:%d server_if:%d connected:%d addr:%s",
+      __func__, conn_id, server_if, connected, addr.c_str());
+  if (connected == 1) {
+    g_internal->connections.insert(conn_id);
+  } else if (connected == 0) {
+    g_internal->connections.erase(conn_id);
+  }
+}
+
+void CharacteristicAddedCallback(int status, int server_if, bt_uuid_t *uuid,
+                                 int srvc_handle, int char_handle) {
+  LOG_INFO(LOG_TAG,
+      "%s: status:%d server_if:%d service_handle:%d char_handle:%d", __func__,
+      status, server_if, srvc_handle, char_handle);
+
+  bluetooth::UUID id(*uuid);
+
+  std::lock_guard<std::mutex> lock(g_internal->lock);
+
+  g_internal->uuid_to_attribute[id] = char_handle;
+  g_internal->characteristics[char_handle].uuid = id;
+  g_internal->characteristics[char_handle].blob_section = 0;
+
+  // This terminates an AddCharacteristic.
+  g_internal->api_synchronize.notify_one();
+}
+
+void DescriptorAddedCallback(int status, int server_if, bt_uuid_t *uuid,
+                             int srvc_handle, int descr_handle) {
+  LOG_INFO(LOG_TAG,
+      "%s: status:%d server_if:%d service_handle:%d uuid[0]:%u "
+      "descr_handle:%d",
+      __func__, status, server_if, srvc_handle, uuid->uu[0], descr_handle);
+}
+
+void ServiceStartedCallback(int status, int server_if, int srvc_handle) {
+  LOG_INFO(LOG_TAG, "%s: status:%d server_if:%d srvc_handle:%d", __func__,
+      status, server_if, srvc_handle);
+
+  // The UUID provided here is unimportant, and is only used to satisfy
+  // BlueDroid.
+  // It must be different than any other registered UUID.
+  bt_uuid_t client_id = g_internal->service_id.id.uuid;
+  ++client_id.uu[15];
+
+  bt_status_t btstat = g_internal->gatt->client->register_client(&client_id);
+  if (btstat != BT_STATUS_SUCCESS) {
+    LOG_ERROR(LOG_TAG, "%s: Failed to register client", __func__);
+  }
+}
+
+void RegisterClientCallback(int status, int client_if, bt_uuid_t *app_uuid) {
+  LOG_INFO(LOG_TAG, "%s: status:%d client_if:%d uuid[0]:%u", __func__, status,
+      client_if, app_uuid->uu[0]);
+  g_internal->client_if = client_if;
+
+  // Setup our advertisement. This has no callback.
+  bt_status_t btstat = g_internal->gatt->client->set_adv_data(
+      client_if, false, /* beacon, not scan response */
+      false,            /* name */
+      false,            /* no txpower */
+      2, 2,             /* interval */
+      0,                /* appearance */
+      0, nullptr,       /* no mfg data */
+      0, nullptr,       /* no service data */
+      0, nullptr /* no service id yet */);
+  if (btstat != BT_STATUS_SUCCESS) {
+    LOG_ERROR(LOG_TAG, "Failed to set advertising data");
+    return;
+  }
+
+  // TODO(icoolidge): Deprecated, use multi-adv interface.
+  // This calls back to ListenCallback.
+  btstat = g_internal->gatt->client->listen(client_if, true);
+  if (btstat != BT_STATUS_SUCCESS) {
+    LOG_ERROR(LOG_TAG, "Failed to start listening");
+  }
+}
+
+void ListenCallback(int status, int client_if) {
+  LOG_INFO(LOG_TAG, "%s: status:%d client_if:%d", __func__, status, client_if);
+  // This terminates a Start call.
+  std::lock_guard<std::mutex> lock(g_internal->lock);
+  g_internal->api_synchronize.notify_one();
+}
+
+void ServiceStoppedCallback(int status, int server_if, int srvc_handle) {
+  LOG_INFO(LOG_TAG, "%s: status:%d server_if:%d srvc_handle:%d", __func__,
+      status, server_if, srvc_handle);
+  // This terminates a Stop call.
+  // TODO(icoolidge): make this symmetric with start
+  std::lock_guard<std::mutex> lock(g_internal->lock);
+  g_internal->api_synchronize.notify_one();
+}
+
+void ScanResultCallback(bt_bdaddr_t *bda, int rssi, uint8_t *adv_data) {
+  std::string addr(BtAddrString(bda));
+  (void)adv_data;
+  std::lock_guard<std::mutex> lock(g_internal->lock);
+  g_internal->scan_results[addr] = rssi;
+}
+
+void ClientConnectCallback(int conn_id, int status, int client_if,
+                           bt_bdaddr_t *bda) {
+  std::string addr(BtAddrString(bda));
+  LOG_INFO(LOG_TAG, "%s: conn_id:%d status:%d client_if:%d %s", __func__,
+      conn_id, status, client_if, addr.c_str());
+}
+
+void ClientDisconnectCallback(int conn_id, int status, int client_if,
+                              bt_bdaddr_t *bda) {
+  std::string addr(BtAddrString(bda));
+  LOG_INFO(LOG_TAG, "%s: conn_id:%d status:%d client_if:%d %s", __func__,
+      conn_id, status, client_if, addr.c_str());
+}
+
+void IndicationSentCallback(UNUSED_ATTR int conn_id,
+                            UNUSED_ATTR int status) {
+  // TODO(icoolidge): what to do
+}
+
+void ResponseConfirmationCallback(UNUSED_ATTR int status,
+                                  UNUSED_ATTR int handle) {
+  // TODO(icoolidge): what to do
+}
+
+const btgatt_server_callbacks_t gatt_server_callbacks = {
+    RegisterServerCallback,
+    ConnectionCallback,
+    ServiceAddedCallback,
+    nullptr, /* included_service_added_cb */
+    CharacteristicAddedCallback,
+    DescriptorAddedCallback,
+    ServiceStartedCallback,
+    ServiceStoppedCallback,
+    nullptr, /* service_deleted_cb */
+    RequestReadCallback,
+    RequestWriteCallback,
+    RequestExecWriteCallback,
+    ResponseConfirmationCallback,
+    IndicationSentCallback,
+    nullptr, /* congestion_cb*/
+    nullptr, /* mtu_changed_cb */
+};
+
+// TODO(eisenbach): Refactor GATT interface to not require servers
+// to refer to the client interface.
+const btgatt_client_callbacks_t gatt_client_callbacks = {
+    RegisterClientCallback,
+    ScanResultCallback,
+    ClientConnectCallback,
+    ClientDisconnectCallback,
+    nullptr, /* search_complete_cb; */
+    nullptr, /* search_result_cb; */
+    nullptr, /* get_characteristic_cb; */
+    nullptr, /* get_descriptor_cb; */
+    nullptr, /* get_included_service_cb; */
+    nullptr, /* register_for_notification_cb; */
+    nullptr, /* notify_cb; */
+    nullptr, /* read_characteristic_cb; */
+    nullptr, /* write_characteristic_cb; */
+    nullptr, /* read_descriptor_cb; */
+    nullptr, /* write_descriptor_cb; */
+    nullptr, /* execute_write_cb; */
+    nullptr, /* read_remote_rssi_cb; */
+    ListenCallback,
+    nullptr, /* configure_mtu_cb; */
+    nullptr, /* scan_filter_cfg_cb; */
+    nullptr, /* scan_filter_param_cb; */
+    nullptr, /* scan_filter_status_cb; */
+    nullptr, /* multi_adv_enable_cb */
+    nullptr, /* multi_adv_update_cb; */
+    nullptr, /* multi_adv_data_cb*/
+    nullptr, /* multi_adv_disable_cb; */
+    nullptr, /* congestion_cb; */
+    nullptr, /* batchscan_cfg_storage_cb; */
+    nullptr, /* batchscan_enb_disable_cb; */
+    nullptr, /* batchscan_reports_cb; */
+    nullptr, /* batchscan_threshold_cb; */
+    nullptr, /* track_adv_event_cb; */
+    nullptr, /* scan_parameter_setup_completed_cb; */
+};
+
+const btgatt_callbacks_t gatt_callbacks = {
+    /** Set to sizeof(btgatt_callbacks_t) */
+    sizeof(btgatt_callbacks_t),
+
+    /** GATT Client callbacks */
+    &gatt_client_callbacks,
+
+    /** GATT Server callbacks */
+    &gatt_server_callbacks};
+
+}  // namespace
+
+namespace bluetooth {
+namespace gatt {
+
+int ServerInternals::Initialize() {
+  // Get the interface to the GATT profile.
+  const bt_interface_t* bt_iface =
+      hal::BluetoothInterface::Get()->GetHALInterface();
+  gatt = reinterpret_cast<const btgatt_interface_t *>(
+      bt_iface->get_profile_interface(BT_PROFILE_GATT_ID));
+  if (!gatt) {
+    LOG_ERROR(LOG_TAG, "Error getting GATT interface");
+    return -1;
+  }
+
+  bt_status_t btstat = gatt->init(&gatt_callbacks);
+  if (btstat != BT_STATUS_SUCCESS) {
+    LOG_ERROR(LOG_TAG, "Failed to initialize gatt interface");
+    return -1;
+  }
+
+  int status = pipe(pipefd);
+  if (status == -1) {
+    LOG_ERROR(LOG_TAG, "pipe creation failed: %s", strerror(errno));
+    return -1;
+  }
+
+  return 0;
+}
+
+bt_status_t ServerInternals::AddCharacteristic(
+    const UUID& uuid,
+    int properties,
+    int permissions) {
+  bt_uuid_t c_uuid = uuid.GetBlueDroid();
+  return gatt->server->add_characteristic(
+      server_if, service_handle, &c_uuid, properties, permissions);
+}
+
+ServerInternals::ServerInternals()
+    : gatt(nullptr),
+      server_if(0),
+      client_if(0),
+      service_handle(0),
+      pipefd{INVALID_FD, INVALID_FD} {}
+
+ServerInternals::~ServerInternals() {
+  if (pipefd[0] != INVALID_FD)
+    close(pipefd[0]);
+  if (pipefd[1] != INVALID_FD)
+    close(pipefd[1]);
+
+  gatt->server->delete_service(server_if, service_handle);
+  gatt->server->unregister_server(server_if);
+  gatt->client->unregister_client(client_if);
+}
+
+Server::Server() : internal_(nullptr) {}
+
+Server::~Server() {}
+
+bool Server::Initialize(const UUID& service_id, int* gatt_pipe) {
+  internal_.reset(new ServerInternals);
+  if (!internal_) {
+    LOG_ERROR(LOG_TAG, "Error creating internals");
+    return false;
+  }
+  g_internal = internal_.get();
+
+  std::unique_lock<std::mutex> lock(internal_->lock);
+  int status = internal_->Initialize();
+  if (status) {
+    LOG_ERROR(LOG_TAG, "Error initializing internals");
+    return false;
+  }
+
+  bt_uuid_t uuid = service_id.GetBlueDroid();
+
+  bt_status_t btstat = internal_->gatt->server->register_server(&uuid);
+  if (btstat != BT_STATUS_SUCCESS) {
+    LOG_ERROR(LOG_TAG, "Failed to register server");
+    return false;
+  }
+
+  internal_->api_synchronize.wait(lock);
+  // TODO(icoolidge): Better error handling.
+  if (internal_->server_if == 0) {
+    LOG_ERROR(LOG_TAG, "Initialization of server failed");
+    return false;
+  }
+
+  *gatt_pipe = internal_->pipefd[kPipeReadEnd];
+  LOG_INFO(LOG_TAG, "Server Initialize succeeded");
+  return true;
+}
+
+bool Server::SetAdvertisement(const std::vector<UUID>& ids,
+                              const std::vector<uint8_t>& service_data,
+                              const std::vector<uint8_t>& manufacturer_data,
+                              bool transmit_name) {
+  std::vector<uint8_t> id_data;
+  auto mutable_manufacturer_data = manufacturer_data;
+  auto mutable_service_data = service_data;
+
+  for (const UUID &id : ids) {
+    const auto le_id = id.GetFullLittleEndian();
+    id_data.insert(id_data.end(), le_id.begin(), le_id.end());
+  }
+
+  std::lock_guard<std::mutex> lock(internal_->lock);
+
+  // Setup our advertisement. This has no callback.
+  bt_status_t btstat = internal_->gatt->client->set_adv_data(
+      internal_->client_if, false, /* beacon, not scan response */
+      transmit_name,               /* name */
+      false,                       /* no txpower */
+      2, 2,                        /* interval */
+      0,                           /* appearance */
+      mutable_manufacturer_data.size(),
+      reinterpret_cast<char *>(mutable_manufacturer_data.data()),
+      mutable_service_data.size(),
+      reinterpret_cast<char *>(mutable_service_data.data()), id_data.size(),
+      reinterpret_cast<char *>(id_data.data()));
+  if (btstat != BT_STATUS_SUCCESS) {
+    LOG_ERROR(LOG_TAG, "Failed to set advertising data");
+    return false;
+  }
+  return true;
+}
+
+bool Server::SetScanResponse(const std::vector<UUID>& ids,
+                             const std::vector<uint8_t>& service_data,
+                             const std::vector<uint8_t>& manufacturer_data,
+                             bool transmit_name) {
+  std::vector<uint8_t> id_data;
+  auto mutable_manufacturer_data = manufacturer_data;
+  auto mutable_service_data = service_data;
+
+  for (const UUID &id : ids) {
+    const auto le_id = id.GetFullLittleEndian();
+    id_data.insert(id_data.end(), le_id.begin(), le_id.end());
+  }
+
+  std::lock_guard<std::mutex> lock(internal_->lock);
+
+  // Setup our advertisement. This has no callback.
+  bt_status_t btstat = internal_->gatt->client->set_adv_data(
+      internal_->client_if, true, /* scan response */
+      transmit_name,              /* name */
+      false,                      /* no txpower */
+      2, 2,                       /* interval */
+      0,                          /* appearance */
+      mutable_manufacturer_data.size(),
+      reinterpret_cast<char *>(mutable_manufacturer_data.data()),
+      mutable_service_data.size(),
+      reinterpret_cast<char *>(mutable_service_data.data()), id_data.size(),
+      reinterpret_cast<char *>(id_data.data()));
+  if (btstat != BT_STATUS_SUCCESS) {
+    LOG_ERROR(LOG_TAG, "Failed to set scan response data");
+    return false;
+  }
+  return true;
+}
+
+bool Server::AddCharacteristic(
+    const UUID &id, int properties, int permissions) {
+  std::unique_lock<std::mutex> lock(internal_->lock);
+  bt_status_t btstat = internal_->AddCharacteristic(
+      id, properties, permissions);
+  if (btstat != BT_STATUS_SUCCESS) {
+    LOG_ERROR(LOG_TAG, "Failed to add characteristic to service: 0x%04x",
+              internal_->service_handle);
+    return false;
+  }
+  internal_->api_synchronize.wait(lock);
+  const int handle = internal_->uuid_to_attribute[id];
+  internal_->characteristics[handle].notify = properties & kPropertyNotify;
+  return true;
+}
+
+bool Server::AddBlob(const UUID &id, const UUID &control_id, int properties,
+                    int permissions) {
+  std::unique_lock<std::mutex> lock(internal_->lock);
+
+  // First, add the primary attribute (characteristic value)
+  bt_status_t btstat = internal_->AddCharacteristic(
+      id, properties, permissions);
+  if (btstat != BT_STATUS_SUCCESS) {
+    LOG_ERROR(LOG_TAG, "Failed to set scan response data");
+    return false;
+  }
+
+  internal_->api_synchronize.wait(lock);
+
+  // Next, add the secondary attribute (blob control).
+  // Control attributes have fixed permissions/properties.
+  btstat = internal_->AddCharacteristic(
+      control_id,
+      kPropertyRead | kPropertyWrite,
+      kPermissionRead | kPermissionWrite);
+  internal_->api_synchronize.wait(lock);
+
+  // Finally, associate the control attribute with the value attribute.
+  // Also, initialize the control attribute to a readable zero.
+  const int control_attribute = internal_->uuid_to_attribute[control_id];
+  const int blob_attribute = internal_->uuid_to_attribute[id];
+  internal_->controlled_blobs[control_attribute] = blob_attribute;
+  internal_->characteristics[blob_attribute].notify =
+      properties & kPropertyNotify;
+
+  Characteristic &ctrl = internal_->characteristics[control_attribute];
+  ctrl.next_blob.clear();
+  ctrl.next_blob.push_back(0);
+  ctrl.next_blob_pending = true;
+  ctrl.blob_section = 0;
+  ctrl.notify = false;
+  return true;
+}
+
+bool Server::Start() {
+  std::unique_lock<std::mutex> lock(internal_->lock);
+  bt_status_t btstat = internal_->gatt->server->start_service(
+      internal_->server_if, internal_->service_handle, GATT_TRANSPORT_LE);
+  if (btstat != BT_STATUS_SUCCESS) {
+    LOG_ERROR(LOG_TAG, "Failed to start service with handle: 0x%04x",
+              internal_->service_handle);
+    return false;
+  }
+  internal_->api_synchronize.wait(lock);
+  return true;
+}
+
+bool Server::Stop() {
+  std::unique_lock<std::mutex> lock(internal_->lock);
+  bt_status_t btstat = internal_->gatt->server->stop_service(
+      internal_->server_if, internal_->service_handle);
+  if (btstat != BT_STATUS_SUCCESS) {
+    LOG_ERROR(LOG_TAG, "Failed to stop service with handle: 0x%04x",
+              internal_->service_handle);
+    return false;
+  }
+  internal_->api_synchronize.wait(lock);
+  return true;
+}
+
+bool Server::ScanEnable() {
+  bt_status_t btstat = internal_->gatt->client->scan(true);
+  if (btstat) {
+    LOG_ERROR(LOG_TAG, "Enable scan failed: %d", btstat);
+    return false;
+  }
+  return true;
+}
+
+bool Server::ScanDisable() {
+  bt_status_t btstat = internal_->gatt->client->scan(false);
+  if (btstat) {
+    LOG_ERROR(LOG_TAG, "Disable scan failed: %d", btstat);
+    return false;
+  }
+  return true;
+}
+
+bool Server::GetScanResults(ScanResults *results) {
+  std::lock_guard<std::mutex> lock(internal_->lock);
+  *results = internal_->scan_results;
+  return true;
+}
+
+bool Server::SetCharacteristicValue(const UUID &id,
+                              const std::vector<uint8_t> &value) {
+  std::lock_guard<std::mutex> lock(internal_->lock);
+  const int attribute_id = internal_->uuid_to_attribute[id];
+  Characteristic &ch = internal_->characteristics[attribute_id];
+  ch.next_blob = value;
+  ch.next_blob_pending = true;
+
+  if (!ch.notify)
+    return true;
+
+  for (auto connection : internal_->connections) {
+    char dummy = 0;
+    internal_->gatt->server->send_indication(internal_->server_if,
+                                             attribute_id,
+                                             connection,
+                                             sizeof(dummy),
+                                             true,
+                                             &dummy);
+  }
+  return true;
+}
+
+bool Server::GetCharacteristicValue(const UUID &id, std::vector<uint8_t> *value) {
+  std::lock_guard<std::mutex> lock(internal_->lock);
+  const int attribute_id = internal_->uuid_to_attribute[id];
+  *value = internal_->characteristics[attribute_id].blob;
+  return true;
+}
+
+}  // namespace gatt
+}  // namespace bluetooth
diff --git a/service/gatt_server.h b/service/gatt_server.h
new file mode 100644 (file)
index 0000000..ff41760
--- /dev/null
@@ -0,0 +1,119 @@
+//
+//  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 <array>
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+#include "hardware/bluetooth.h"
+#include "hardware/bt_gatt.h"
+#include "uuid.h"
+
+namespace bluetooth {
+namespace gatt {
+
+// Attribute permission values
+const int kPermissionRead = 0x1;
+const int kPermissionReadEncrypted = 0x2;
+const int kPermissionReadEncryptedMitm = 0x4;
+const int kPermissionWrite = 0x10;
+const int kPermissionWriteEnecrypted = 0x20;
+const int KPermissionWriteEncryptedMitm = 0x40;
+const int kPermissionWriteSigned = 0x80;
+const int kPermissionWriteSignedMitm = 0x100;
+
+// GATT characteristic properties bit-field values
+const int kPropertyBroadcast = 0x1;
+const int kPropertyRead = 0x2;
+const int kPropertyWriteNoResponse = 0x4;
+const int kPropertyWrite = 0x8;
+const int kPropertyNotify = 0x10;
+const int kPropertyIndicate = 0x20;
+const int kPropertySignedWrite = 0x40;
+const int kPropertyExtendedProps = 0x80;
+
+// A mapping from string bluetooth addresses to RSSI measurements.
+typedef std::unordered_map<std::string, int> ScanResults;
+
+// TODO(armansito): This should be a private internal class though I don't see
+// why we even need this class. Instead it should probably be merged into
+// Server.
+struct ServerInternals;
+
+// Server is threadsafe and internally locked.
+// Asynchronous IO is identified via a gatt_pipe FD,
+// and synchronously read with 'GetCharacteristicValue'
+class Server {
+ public:
+  Server();
+  ~Server();
+
+  // Register GATT interface, initialize internal state,
+  // and open a pipe for characteristic write notification.
+  bool Initialize(const UUID& service_id, int* gatt_pipe);
+
+  // Control the content of service advertisement.
+  bool SetAdvertisement(const std::vector<UUID>& ids,
+                        const std::vector<uint8_t>& service_data,
+                        const std::vector<uint8_t>& manufacturer_data,
+                        bool transmit_name);
+
+  // Control the content of service scan response.
+  bool SetScanResponse(const std::vector<UUID>& ids,
+                       const std::vector<uint8_t>& service_data,
+                       const std::vector<uint8_t>& manufacturer_data,
+                       bool transmit_name);
+
+  // Add an ordinary characteristic for reading and/or writing.
+  bool AddCharacteristic(const UUID &id, int properties, int permissions);
+
+  // Add a special 'blob' characteristic with a corresponding control
+  // attribute to manipulate which part of the blob the attribute represents.
+  bool AddBlob(const UUID &id, const UUID &control_id, int properties,
+               int permissions);
+
+  // Put a new value into a characeteristic.
+  // It will be read from a client starting at the next 0-offset read.
+  bool SetCharacteristicValue(const UUID &id, const std::vector<uint8_t> &value);
+
+  // Get the current value of a characteristic.
+  bool GetCharacteristicValue(const UUID &id, std::vector<uint8_t> *value);
+
+  // Start this service. Activate advertisements, allow connections.
+  // Characteristics should all be created before this.
+  bool Start();
+
+  // Cease advertisements and disallow connections.
+  bool Stop();
+
+  // Enable LE scan. Scan results will be cached internally.
+  bool ScanEnable();
+
+  // Disable LE scan.
+  bool ScanDisable();
+
+  // Copy out the cached scan results.
+  bool GetScanResults(ScanResults *results);
+
+ private:
+  // Internal data.
+  std::unique_ptr<ServerInternals> internal_;
+};
+
+}  // namespace gatt
+}  // namespace bluetooth
diff --git a/service/hal/bluetooth_interface.cpp b/service/hal/bluetooth_interface.cpp
new file mode 100644 (file)
index 0000000..496b148
--- /dev/null
@@ -0,0 +1,290 @@
+//
+//  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 "service/hal/bluetooth_interface.h"
+
+#include <mutex>
+
+#include <base/logging.h>
+#include <base/observer_list.h>
+
+#include "service/logging_helpers.h"
+
+extern "C" {
+#include "btcore/include/hal_util.h"
+}  // extern "C"
+
+using std::lock_guard;
+using std::mutex;
+
+namespace bluetooth {
+namespace hal {
+
+namespace {
+
+// The global BluetoothInterface instance.
+BluetoothInterface* g_bluetooth_interface = nullptr;
+
+// Mutex used by callbacks to access |g_bluetooth_interface|. Since there is no
+// good way to unregister callbacks and since the global instance can be deleted
+// concurrently during shutdown, this lock is used.
+//
+// TODO(armansito): There should be a way to cleanly shut down the Bluetooth
+// stack.
+mutex g_instance_lock;
+
+// Helper for obtaining the observer list. This is forward declared here and
+// defined below since it depends on BluetoothInterfaceImpl.
+base::ObserverList<BluetoothInterface::Observer>* GetObservers();
+
+#define FOR_EACH_BLUETOOTH_OBSERVER(func) \
+  FOR_EACH_OBSERVER(BluetoothInterface::Observer, *GetObservers(), func)
+
+void AdapterStateChangedCallback(bt_state_t state) {
+  lock_guard<mutex> lock(g_instance_lock);
+  if (!g_bluetooth_interface) {
+    LOG(WARNING) << "Callback received after global instance was destroyed";
+    return;
+  }
+
+  VLOG(1) << "Adapter state changed: " << BtStateText(state);
+  FOR_EACH_BLUETOOTH_OBSERVER(AdapterStateChangedCallback(state));
+}
+
+void AdapterPropertiesCallback(bt_status_t status,
+                               int num_properties,
+                               bt_property_t* properties) {
+  lock_guard<mutex> lock(g_instance_lock);
+  if (!g_bluetooth_interface) {
+    LOG(WARNING) << "Callback received after global instance was destroyed";
+    return;
+  }
+
+  VLOG(1) << "Adapter properties changed - status: " << BtStatusText(status)
+          << ", num_properties: " << num_properties;
+  FOR_EACH_BLUETOOTH_OBSERVER(
+      AdapterPropertiesCallback(status, num_properties, properties));
+}
+
+void ThreadEventCallback(bt_cb_thread_evt evt) {
+  VLOG(1) << "ThreadEventCallback" << BtEventText(evt);
+
+  // TODO(armansito): This callback is completely useless to us but btif borks
+  // out if this is not set. Consider making this optional.
+}
+
+bool SetWakeAlarmCallout(uint64_t /* delay_millis */,
+                         bool /* should_wake */,
+                         alarm_cb /* cb */,
+                         void* /* data */) {
+  // TODO(armansito): According to sharvil@, this interface doesn't even need to
+  // exist and can be done entirely from within osi by interfacing directly with
+  // the kernel. Remove these stubs once that's fixed. (See http://b/23390297)
+  return false;
+}
+
+int AcquireWakeLockCallout(const char* /* lock_name */) {
+  // TODO(armansito): According to sharvil@, this interface doesn't even need to
+  // exist and can be done entirely from within osi by interfacing directly with
+  // the kernel. Remove these stubs once that's fixed. (See http://b/23390297)
+  // Lie here and return success so that enabling and disabling the controller
+  // works before this is properly implemented.
+  return BT_STATUS_SUCCESS;
+}
+
+int ReleaseWakeLockCallout(const char* /* lock_name */) {
+  // TODO(armansito): According to sharvil@, this interface doesn't even need to
+  // exist and can be done entirely from within osi by interfacing directly with
+  // the kernel. Remove these stubs once that's fixed. (See http://b/23390297)
+  // Lie here and return success so that enabling and disabling the controller
+  // works before this is properly implemented.
+  return BT_STATUS_SUCCESS;
+}
+
+// The HAL Bluetooth DM callbacks.
+bt_callbacks_t bt_callbacks = {
+  sizeof(bt_callbacks_t),
+  AdapterStateChangedCallback,
+  AdapterPropertiesCallback,
+  nullptr, /* remote_device_properties_cb */
+  nullptr, /* device_found_cb */
+  nullptr, /* discovery_state_changed_cb */
+  nullptr, /* pin_request_cb  */
+  nullptr, /* ssp_request_cb  */
+  nullptr, /* bond_state_changed_cb */
+  nullptr, /* acl_state_changed_cb */
+  ThreadEventCallback,
+  nullptr, /* dut_mode_recv_cb */
+  nullptr, /* le_test_mode_cb */
+  nullptr  /* energy_info_cb */
+};
+
+bt_os_callouts_t bt_os_callouts = {
+  sizeof(bt_os_callouts_t),
+  SetWakeAlarmCallout,
+  AcquireWakeLockCallout,
+  ReleaseWakeLockCallout
+};
+
+}  // namespace
+
+// BluetoothInterface implementation for production.
+class BluetoothInterfaceImpl : public BluetoothInterface {
+ public:
+  BluetoothInterfaceImpl()
+      : hal_iface_(nullptr),
+        hal_adapter_(nullptr) {
+  }
+
+  ~BluetoothInterfaceImpl() override {
+    hal_iface_->cleanup();
+  };
+
+  // BluetoothInterface overrides.
+  void AddObserver(Observer* observer) override {
+    lock_guard<mutex> lock(g_instance_lock);
+    observers_.AddObserver(observer);
+  }
+
+  void RemoveObserver(Observer* observer) override {
+    lock_guard<mutex> lock(g_instance_lock);
+    observers_.RemoveObserver(observer);
+  }
+
+  const bt_interface_t* GetHALInterface() const override {
+    return hal_iface_;
+  }
+
+  const bluetooth_device_t* GetHALAdapter() const override {
+    return hal_adapter_;
+  }
+
+  // Initialize the interface. This loads the shared Bluetooth library and sets
+  // up the callbacks.
+  bool Initialize() {
+    // Load the Bluetooth shared library module.
+    const hw_module_t* module;
+    int status = hal_util_load_bt_library(&module);
+    if (status) {
+      LOG(ERROR) << "Failed to load Bluetooth library";
+      return false;
+    }
+
+    // Open the Bluetooth adapter.
+    hw_device_t* device;
+    status = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
+    if (status) {
+      LOG(ERROR) << "Failed to open the Bluetooth module";
+      return false;
+    }
+
+    hal_adapter_ = reinterpret_cast<bluetooth_device_t*>(device);
+    hal_iface_ = hal_adapter_->get_bluetooth_interface();
+
+    // Initialize the Bluetooth interface. Set up the adapter (Bluetooth DM) API
+    // callbacks.
+    status = hal_iface_->init(&bt_callbacks);
+    if (status != BT_STATUS_SUCCESS) {
+      LOG(ERROR) << "Failed to initialize Bluetooth stack";
+      return false;
+    }
+
+    status = hal_iface_->set_os_callouts(&bt_os_callouts);
+    if (status != BT_STATUS_SUCCESS) {
+      LOG(ERROR) << "Failed to set up Bluetooth OS callouts";
+      return false;
+    }
+
+    return true;
+  }
+
+  base::ObserverList<Observer>* observers() { return &observers_; }
+
+ private:
+  // List of observers that are interested in notifications from us. We're not
+  // using a base::ObserverListThreadSafe, which it posts observer events
+  // automatically on the origin threads, as we want to avoid that overhead and
+  // simply forward the events to the upper layer.
+  base::ObserverList<Observer> observers_;
+
+  // The HAL handle obtained from the shared library. We hold a weak reference
+  // to this since the actual data resides in the shared Bluetooth library.
+  const bt_interface_t* hal_iface_;
+
+  // The HAL handle that represents the underlying Bluetooth adapter. We hold a
+  // weak reference to this since the actual data resides in the shared
+  // Bluetooth library.
+  const bluetooth_device_t* hal_adapter_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothInterfaceImpl);
+};
+
+namespace {
+
+// Helper for obtaining the observer list from the global instance. This
+// function is NOT thread safe.
+base::ObserverList<BluetoothInterface::Observer>* GetObservers() {
+  CHECK(g_bluetooth_interface);
+  return static_cast<BluetoothInterfaceImpl*>(
+      g_bluetooth_interface)->observers();
+}
+
+}  // namespace
+
+// static
+bool BluetoothInterface::Initialize() {
+  lock_guard<mutex> lock(g_instance_lock);
+  CHECK(!g_bluetooth_interface);
+
+  std::unique_ptr<BluetoothInterfaceImpl> impl(new BluetoothInterfaceImpl());
+  if (!impl->Initialize()) {
+    LOG(ERROR) << "Failed to initialize BluetoothInterface";
+    return false;
+  }
+
+  g_bluetooth_interface = impl.release();
+
+  return true;
+}
+
+// static
+void BluetoothInterface::CleanUp() {
+  lock_guard<mutex> lock(g_instance_lock);
+  CHECK(g_bluetooth_interface);
+
+  delete g_bluetooth_interface;
+  g_bluetooth_interface = nullptr;
+}
+
+// static
+BluetoothInterface* BluetoothInterface::Get() {
+  lock_guard<mutex> lock(g_instance_lock);
+  CHECK(g_bluetooth_interface);
+  return g_bluetooth_interface;
+}
+
+// static
+void BluetoothInterface::InitializeForTesting(
+    BluetoothInterface* test_instance) {
+  lock_guard<mutex> lock(g_instance_lock);
+  CHECK(test_instance);
+  CHECK(!g_bluetooth_interface);
+
+  g_bluetooth_interface = test_instance;
+}
+
+}  // namespace hal
+}  // namespace bluetooth
diff --git a/service/hal/bluetooth_interface.h b/service/hal/bluetooth_interface.h
new file mode 100644 (file)
index 0000000..ede9d17
--- /dev/null
@@ -0,0 +1,100 @@
+//
+//  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/macros.h>
+#include <hardware/bluetooth.h>
+
+namespace bluetooth {
+namespace hal {
+
+// This class represents the HAL Bluetooth adapter interface, wrapping around
+// the underlying bt_interface_t structure, its methods, and callbacks. A single
+// instance of this class exists per application and it allows multiple classes
+// to interface with the global HAL interface by multiplexing callbacks among
+// registered clients.
+//
+// This is declared as an abstract interface so that a fake implementation can
+// be injected for testing the upper layer.
+//
+// TODO: (expose callback types directly but via redirection) methods for
+// initialize, clean up, and set for testing.
+class BluetoothInterface {
+ public:
+  // The standard Bluetooth adapter management callback interface. The HAL
+  // interface doesn't allow registering "user data" that carries context beyond
+  // the callback parameters, forcing implementations to deal with global
+  // variables. The Observer interface is to redirect these events to interested
+  // parties in an object-oriented manner.
+  //
+  // TODO(armansito): We should fix this in the HAL.
+  class Observer {
+   public:
+    virtual ~Observer() = default;
+
+    // All of the events below correspond to callbacks defined in
+    // "bt_callbacks_t" in the HAL API definitions.
+
+    virtual void AdapterStateChangedCallback(bt_state_t state) = 0;
+    virtual void AdapterPropertiesCallback(bt_status_t status,
+                                           int num_properties,
+                                           bt_property_t* properties) = 0;
+
+    // TODO(armansito): Complete the list of callbacks.
+  };
+
+  // Initialize and clean up the BluetoothInterface singleton. CleanUp must be
+  // called on the same thread that called Initialize.
+  static bool Initialize();
+  static void CleanUp();
+
+  // Initialize for testing. Use this to inject a test version of
+  // BlueoothInterface. To be used from unit tests only.
+  static void InitializeForTesting(BluetoothInterface* test_instance);
+
+  // Returns the BluetoothInterface singleton. If the interface has not been
+  // initialized, returns nullptr.
+  static BluetoothInterface* Get();
+
+  // Add or remove an observer that is interested in notifications from us.
+  virtual void AddObserver(Observer* observer) = 0;
+  virtual void RemoveObserver(Observer* observer) = 0;
+
+  // The HAL module pointer that represents the standard Bluetooth adapter
+  // management interface. This is implemented in and provided by the shared
+  // Bluetooth library, so this isn't owned by us.
+  //
+  // Upper layers can make bt_interface_t API calls through this structure.
+  // However, DO NOT call the "init" function as this is called and managed by
+  // us. The behavior is undefined if "init" is called directly by upper layers.
+  virtual const bt_interface_t* GetHALInterface() const = 0;
+
+  // The HAL module pointer that represents the underlying Bluetooth adapter.
+  // This is implemented in and provided by the shared Bluetooth library, so
+  // this isn't owned by us.
+  virtual const bluetooth_device_t* GetHALAdapter() const = 0;
+
+ protected:
+  BluetoothInterface() = default;
+  virtual ~BluetoothInterface() = default;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BluetoothInterface);
+};
+
+}  // namespace hal
+}  // namespace bluetooth
diff --git a/service/hal/fake_bluetooth_interface.cpp b/service/hal/fake_bluetooth_interface.cpp
new file mode 100644 (file)
index 0000000..fb4980a
--- /dev/null
@@ -0,0 +1,145 @@
+//
+//  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 "service/hal/fake_bluetooth_interface.h"
+
+namespace bluetooth {
+namespace hal {
+
+namespace {
+
+FakeBluetoothInterface::Manager g_hal_manager;
+
+int FakeHALEnable() {
+  return g_hal_manager.enable_succeed ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
+}
+
+int FakeHALDisable() {
+  return g_hal_manager.disable_succeed ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
+}
+
+int FakeHALGetAdapterProperties() {
+  return BT_STATUS_SUCCESS;
+}
+
+int FakeHALSetAdapterProperty(const bt_property_t* /* property */) {
+  LOG(INFO) << __func__;
+  return (g_hal_manager.set_property_succeed ? BT_STATUS_SUCCESS :
+          BT_STATUS_FAIL);
+}
+
+bt_interface_t fake_bt_iface = {
+  sizeof(bt_interface_t),
+  nullptr, /* init */
+  FakeHALEnable,
+  FakeHALDisable,
+  nullptr, /* cleanup */
+  FakeHALGetAdapterProperties,
+  nullptr, /* get_adapter_property */
+  FakeHALSetAdapterProperty,
+  nullptr, /* get_remote_device_properties */
+  nullptr, /* get_remote_device_property */
+  nullptr, /* set_remote_device_property */
+  nullptr, /* get_remote_service_record */
+  nullptr, /* get_remote_services */
+  nullptr, /* start_discovery */
+  nullptr, /* cancel_discovery */
+  nullptr, /* create_bond */
+  nullptr, /* remove_bond */
+  nullptr, /* cancel_bond */
+  nullptr, /* get_connection_state */
+  nullptr, /* pin_reply */
+  nullptr, /* ssp_reply */
+  nullptr, /* get_profile_interface */
+  nullptr, /* dut_mode_configure */
+  nullptr, /* dut_more_send */
+  nullptr, /* le_test_mode */
+  nullptr, /* config_hci_snoop_log */
+  nullptr, /* set_os_callouts */
+  nullptr, /* read_energy_info */
+  nullptr, /* dump */
+};
+
+}  // namespace
+
+// static
+FakeBluetoothInterface::Manager* FakeBluetoothInterface::GetManager() {
+  return &g_hal_manager;
+}
+
+FakeBluetoothInterface::Manager::Manager()
+    : enable_succeed(false),
+      disable_succeed(false),
+      set_property_succeed(false) {
+}
+
+void FakeBluetoothInterface::NotifyAdapterStateChanged(bt_state_t state) {
+  FOR_EACH_OBSERVER(Observer, observers_, AdapterStateChangedCallback(state));
+}
+
+void FakeBluetoothInterface::NotifyAdapterPropertiesChanged(
+    int num_properties,
+    bt_property_t* properties) {
+  FOR_EACH_OBSERVER(
+      Observer, observers_,
+      AdapterPropertiesCallback(BT_STATUS_SUCCESS, num_properties, properties));
+}
+
+void FakeBluetoothInterface::NotifyAdapterNamePropertyChanged(
+    const std::string& name) {
+  bt_bdname_t hal_name;
+  strncpy(reinterpret_cast<char*>(hal_name.name),
+          name.c_str(),
+          std::min(sizeof(hal_name)-1, name.length()));
+  reinterpret_cast<char*>(hal_name.name)[name.length()] = '\0';
+
+  bt_property_t property;
+  property.len = sizeof(hal_name);
+  property.val = &hal_name;
+  property.type = BT_PROPERTY_BDNAME;
+
+  NotifyAdapterPropertiesChanged(1, &property);
+}
+
+void FakeBluetoothInterface::NotifyAdapterAddressPropertyChanged(
+    const bt_bdaddr_t* address) {
+  bt_property_t property;
+  property.len = sizeof(bt_bdaddr_t);
+  property.val = (void*)address;
+  property.type = BT_PROPERTY_BDADDR;
+
+  NotifyAdapterPropertiesChanged(1, &property);
+}
+
+void FakeBluetoothInterface::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void FakeBluetoothInterface::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+const bt_interface_t* FakeBluetoothInterface::GetHALInterface() const {
+  return &fake_bt_iface;
+}
+
+const bluetooth_device_t* FakeBluetoothInterface::GetHALAdapter() const {
+  // TODO(armansito): Do something meaningful here to simulate test behavior.
+  return nullptr;
+}
+
+}  // namespace hal
+}  // namespace bluetooth
diff --git a/service/hal/fake_bluetooth_interface.h b/service/hal/fake_bluetooth_interface.h
new file mode 100644 (file)
index 0000000..49f424d
--- /dev/null
@@ -0,0 +1,67 @@
+//
+//  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 "service/hal/bluetooth_interface.h"
+
+#include <base/macros.h>
+#include <base/observer_list.h>
+
+namespace bluetooth {
+namespace hal {
+
+class FakeBluetoothInterface : public BluetoothInterface {
+ public:
+  // A Fake HAL Bluetooth interface. This is kept as a global singleton as the
+  // Bluetooth HAL doesn't support anything otherwise.
+  struct Manager {
+    Manager();
+    ~Manager() = default;
+
+    // Values that should be returned from bt_interface_t methods.
+    bool enable_succeed;
+    bool disable_succeed;
+    bool set_property_succeed;
+  };
+
+  // Returns the global Manager.
+  static Manager* GetManager();
+
+  FakeBluetoothInterface() = default;
+  ~FakeBluetoothInterface() override = default;
+
+  // Notifies the observers that the adapter state changed to |state|.
+  void NotifyAdapterStateChanged(bt_state_t state);
+
+  // Triggers an adapter property change event.
+  void NotifyAdapterPropertiesChanged(int num_properties,
+                                      bt_property_t* properties);
+  void NotifyAdapterNamePropertyChanged(const std::string& name);
+  void NotifyAdapterAddressPropertyChanged(const bt_bdaddr_t* address);
+
+  // hal::BluetoothInterface overrides:
+  void AddObserver(Observer* observer) override;
+  void RemoveObserver(Observer* observer) override;
+  const bt_interface_t* GetHALInterface() const override;
+  const bluetooth_device_t* GetHALAdapter() const override;
+
+ private:
+  base::ObserverList<Observer> observers_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothInterface);
+};
+
+}  // namespace hal
+}  // namespace bluetooth
diff --git a/service/ipc/binder/IBluetooth.cpp b/service/ipc/binder/IBluetooth.cpp
new file mode 100644 (file)
index 0000000..dd9781c
--- /dev/null
@@ -0,0 +1,237 @@
+//
+//  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 "service/ipc/binder/IBluetooth.h"
+
+#include <base/logging.h>
+#include <binder/IServiceManager.h>
+#include <binder/Parcel.h>
+
+using android::defaultServiceManager;
+using android::IBinder;
+using android::interface_cast;
+using android::IServiceManager;
+using android::Parcel;
+using android::sp;
+using android::String16;
+
+namespace ipc {
+namespace binder {
+
+// static
+const char IBluetooth::kBluetoothServiceName[] = "bluetooth-service";
+
+// static
+android::sp<IBluetooth> IBluetooth::getClientInterface() {
+  sp<IServiceManager> sm = defaultServiceManager();
+  if (!sm.get()) {
+    LOG(ERROR) << "Failed to obtain a handle to the default Service Manager";
+    return nullptr;
+  }
+
+  sp<IBinder> binder = sm->getService(String16(kBluetoothServiceName));
+  if (!binder.get()) {
+    LOG(ERROR) << "Failed to obtain a handle to the Bluetooth service";
+    return nullptr;
+  }
+
+  sp<IBluetooth> bt_iface = interface_cast<IBluetooth>(binder);
+  if (!bt_iface.get()) {
+    LOG(ERROR) << "Obtained invalid IBinder handle";
+    return nullptr;
+  }
+
+  return bt_iface;
+}
+
+// BnBluetooth (server) implementation
+// ========================================================
+
+android::status_t BnBluetooth::onTransact(
+    uint32_t code,
+    const Parcel& data,
+    Parcel* reply,
+    uint32_t flags) {
+  VLOG(2) << "IBluetooth transaction: " << code;
+  if (!data.checkInterface(this))
+    return android::PERMISSION_DENIED;
+
+  switch (code) {
+    case IS_ENABLED_TRANSACTION: {
+      bool is_enabled = IsEnabled();
+      reply->writeInt32(is_enabled);
+      return android::NO_ERROR;
+    }
+    case GET_STATE_TRANSACTION: {
+      int state = GetState();
+      reply->writeInt32(state);
+      return android::NO_ERROR;
+    }
+    case ENABLE_TRANSACTION: {
+      bool result = Enable();
+      reply->writeInt32(result);
+      return android::NO_ERROR;
+    }
+    case DISABLE_TRANSACTION: {
+      bool result = Disable();
+      reply->writeInt32(result);
+      return android::NO_ERROR;
+    }
+    case GET_ADDRESS_TRANSACTION: {
+      std::string address = GetAddress();
+      reply->writeCString(address.c_str());
+      return android::NO_ERROR;
+    }
+    case GET_UUIDS_TRANSACTION:
+      // TODO(armansito): Figure out how to handle a Java "ParcelUuid" natively.
+      // (see http://b/23316698).
+      return android::INVALID_OPERATION;
+
+    case SET_NAME_TRANSACTION: {
+      std::string name(data.readCString());
+      bool result = SetName(name);
+      reply->writeInt32(result);
+      return android::NO_ERROR;
+    }
+    case GET_NAME_TRANSACTION: {
+      std::string name = GetName();
+      reply->writeCString(name.c_str());
+      return android::NO_ERROR;
+    }
+    case REGISTER_CALLBACK_TRANSACTION: {
+      sp<IBinder> callback = data.readStrongBinder();
+      RegisterCallback(interface_cast<IBluetoothCallback>(callback));
+      return android::NO_ERROR;
+    }
+    case UNREGISTER_CALLBACK_TRANSACTION: {
+      sp<IBinder> callback = data.readStrongBinder();
+      UnregisterCallback(interface_cast<IBluetoothCallback>(callback));
+      return android::NO_ERROR;
+    }
+    default:
+      return BBinder::onTransact(code, data, reply, flags);
+  }
+}
+
+// BpBluetooth (client) implementation
+// ========================================================
+
+BpBluetooth::BpBluetooth(const sp<IBinder>& impl)
+    : BpInterface<IBluetooth>(impl) {
+}
+
+bool BpBluetooth::IsEnabled() {
+  Parcel data, reply;
+
+  data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
+  remote()->transact(IBluetooth::IS_ENABLED_TRANSACTION, data, &reply);
+
+  return reply.readInt32();
+}
+
+int BpBluetooth::GetState() {
+  Parcel data, reply;
+
+  data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
+  remote()->transact(IBluetooth::GET_STATE_TRANSACTION, data, &reply);
+
+  return reply.readInt32();
+}
+
+bool BpBluetooth::Enable() {
+  Parcel data, reply;
+
+  data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
+  remote()->transact(IBluetooth::ENABLE_TRANSACTION, data, &reply);
+
+  return reply.readInt32();
+}
+
+bool BpBluetooth::EnableNoAutoConnect() {
+  Parcel data, reply;
+
+  data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
+  remote()->transact(IBluetooth::ENABLE_NO_AUTO_CONNECT_TRANSACTION,
+                     data, &reply);
+
+  return reply.readInt32();
+}
+
+bool BpBluetooth::Disable() {
+  Parcel data, reply;
+
+  data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
+  remote()->transact(IBluetooth::DISABLE_TRANSACTION, data, &reply);
+
+  return reply.readInt32();
+}
+
+std::string BpBluetooth::GetAddress() {
+  Parcel data, reply;
+
+  data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
+  remote()->transact(IBluetooth::GET_ADDRESS_TRANSACTION, data, &reply);
+
+  return reply.readCString();
+}
+
+std::vector<bluetooth::UUID> BpBluetooth::GetUUIDs() {
+  // TODO(armansito): need to deserialize a parceled java.util.ParcelUUID[] to
+  // std::vector<bluetooth::UUID> here (see http://b/23316698).
+  return std::vector<bluetooth::UUID>();
+}
+
+bool BpBluetooth::SetName(const std::string& name) {
+  Parcel data, reply;
+
+  data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
+  data.writeCString(name.c_str());
+  remote()->transact(IBluetooth::SET_NAME_TRANSACTION, data, &reply);
+
+  return reply.readInt32();
+}
+
+std::string BpBluetooth::GetName() {
+  Parcel data, reply;
+
+  data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
+  remote()->transact(IBluetooth::GET_NAME_TRANSACTION, data, &reply);
+
+  return reply.readCString();
+}
+
+void BpBluetooth::RegisterCallback(const sp<IBluetoothCallback>& callback) {
+  Parcel data, reply;
+
+  data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
+  data.writeStrongBinder(IInterface::asBinder(callback.get()));
+
+  remote()->transact(IBluetooth::REGISTER_CALLBACK_TRANSACTION, data, &reply);
+}
+
+void BpBluetooth::UnregisterCallback(const sp<IBluetoothCallback>& callback) {
+  Parcel data, reply;
+
+  data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
+  data.writeStrongBinder(IInterface::asBinder(callback.get()));
+
+  remote()->transact(IBluetooth::UNREGISTER_CALLBACK_TRANSACTION, data, &reply);
+}
+
+IMPLEMENT_META_INTERFACE(Bluetooth, IBluetooth::kBluetoothServiceName);
+
+}  // namespace binder
+}  // namespace ipc
diff --git a/service/ipc/binder/IBluetooth.h b/service/ipc/binder/IBluetooth.h
new file mode 100644 (file)
index 0000000..a40af70
--- /dev/null
@@ -0,0 +1,193 @@
+//
+//  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 <string>
+#include <vector>
+
+#include <base/macros.h>
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+
+#include "service/ipc/binder/IBluetoothCallback.h"
+#include "service/uuid.h"
+
+namespace ipc {
+namespace binder {
+
+// This class defines the Binder IPC interface for accessing the Bluetooth
+// service. This class was written based on the corresponding AIDL file at
+// /frameworks/base/core/java/android/bluetooth/IBluetooth.aidl.
+//
+// NOTE: KEEP THIS FILE UP-TO-DATE with the corresponding AIDL, otherwise this
+// won't be compatible with the Android framework.
+class IBluetooth : public android::IInterface {
+ public:
+  DECLARE_META_INTERFACE(Bluetooth);
+
+  static const char kBluetoothServiceName[];
+
+  // Transaction codes for interface methods.
+  enum {
+    IS_ENABLED_TRANSACTION = android::IBinder::FIRST_CALL_TRANSACTION,
+    GET_STATE_TRANSACTION,
+    ENABLE_TRANSACTION,
+    ENABLE_NO_AUTO_CONNECT_TRANSACTION,
+    DISABLE_TRANSACTION,
+
+    GET_ADDRESS_TRANSACTION,
+    GET_UUIDS_TRANSACTION,  // TODO(armansito): Support this
+    SET_NAME_TRANSACTION,
+    GET_NAME_TRANSACTION,
+
+    // TODO(armansito): Support the functions below.
+
+    GET_SCAN_MODE_TRANSACTION,
+    SET_SCAN_MODE_TRANSACTION,
+
+    GET_DISCOVERABLE_TIMEOUT_TRANSACTION,
+    SET_DISCOVERABLE_TIMEOUT_TRANSACTION,
+
+    START_DISCOVERY_TRANSACTION,
+    CANCEL_DISCOVERY_TRANSACTION,
+    IS_DISCOVERING_TRANSACTION,
+
+    GET_ADAPTER_CONNECTION_STATE_TRANSACTION,
+    GET_PROFILE_CONNECTION_STATE_TRANSACTION,
+
+    GET_BONDED_DEVICES_TRANSACTION,
+    CREATE_BOND_TRANSACTION,
+    CANCEL_BOND_PROCESS_TRANSACTION,
+    REMOVE_BOND_TRANSACTION,
+    GET_BOND_STATE_TRANSACTION,
+    GET_CONNECTION_STATE_TRANSACTION,
+
+    GET_REMOTE_NAME_TRANSACTION,
+    GET_REMOTE_TYPE_TRANSACTION,
+    GET_REMOTE_ALIAS_TRANSACTION,
+    SET_REMOTE_ALIAS_TRANSACTION,
+    GET_REMOTE_CLASS_TRANSACTION,
+    GET_REMOTE_UUIDS_TRANSACTION,
+    FETCH_REMOTE_UUIDS_TRANSACTION,
+    SDP_SEARCH_TRANSACTION,
+
+    SET_PIN_TRANSACTION,
+    SET_PASSKEY_TRANSACTION,
+    SET_PAIRING_CONFIRMATION_TRANSACTION,
+
+    GET_PHONEBOOK_ACCESS_PERMISSION_TRANSACTION,
+    SET_PHONEBOOK_ACCESS_PERMISSION_TRANSACTION,
+    GET_MESSAGE_ACCESS_PERMISSION_TRANSACTION,
+    SET_MESSAGE_ACCESS_PERMISSION_TRANSACTION,
+    GET_SIM_ACCESS_PERMISSION_TRANSACTION,
+    SET_SIM_ACCESS_PERMISSION_TRANSACTION,
+
+    SEND_CONNECTION_STATE_CHANGE_TRANSACTION,
+
+    REGISTER_CALLBACK_TRANSACTION,
+    UNREGISTER_CALLBACK_TRANSACTION,
+
+    CONNECT_SOCKET_TRANSACTION,
+    CREATE_SOCKET_CHANNEL_TRANSACTION,
+
+    CONFIG_HCI_SNOOP_LOG,
+    FACTORY_RESET_TRANSACTION,
+
+    IS_MULTI_ADVERTISEMENT_SUPPORTED_TRANSACTION,
+    IS_PERIPHERAL_MODE_SUPPORTED_TRANSACTION,
+    IS_OFFLOADED_FILTERING_SUPPORTED_TRANSACTION,
+    IS_OFFLOADED_SCAN_BATCHING_SUPPORTED_TRANSACTION,
+    IS_ACTIVITY_AND_ENERGY_REPORTING_SUPPORTED_TRANSACTION,
+    GET_ACTIVITY_ENERGY_INFO_FROM_CONTROLLER_TRANSACTION,
+    REPORT_ACTIVITY_INFO_TRANSACTION,
+
+    DUMP_TRANSACTION,
+    ON_LE_SERVICE_UP_TRANSACTION,
+    ON_BR_EDR_DOWN_TRANSACTION,
+  };
+
+  // Returns a handle to the IBluetooth Binder from the Android ServiceManager.
+  // Binder client code can use this to make calls to the service.
+  static android::sp<IBluetooth> getClientInterface();
+
+  // Methods declared in IBluetooth.aidl.
+
+  virtual bool IsEnabled() = 0;
+  virtual int GetState() = 0;
+  virtual bool Enable() = 0;
+  virtual bool EnableNoAutoConnect() = 0;
+  virtual bool Disable() = 0;
+
+  virtual std::string GetAddress() = 0;
+  virtual std::vector<bluetooth::UUID> GetUUIDs() = 0;
+  virtual bool SetName(const std::string& name) = 0;
+  virtual std::string GetName() = 0;
+
+  virtual void RegisterCallback(
+      const android::sp<IBluetoothCallback>& callback) = 0;
+  virtual void UnregisterCallback(
+      const android::sp<IBluetoothCallback>& callback) = 0;
+
+  // TODO(armansito): Complete the API definition.
+ private:
+  DISALLOW_COPY_AND_ASSIGN(IBluetooth);
+};
+
+// TODO(armansito): Implement notification for when the process dies.
+
+// The Binder server interface to IBluetooth. A class that implements IBluetooth
+// must inherit from this class.
+class BnBluetooth : public android::BnInterface<IBluetooth> {
+ public:
+  BnBluetooth() = default;
+  virtual ~BnBluetooth() = default;
+
+ private:
+  virtual android::status_t onTransact(
+      uint32_t code,
+      const android::Parcel& data,
+      android::Parcel* reply,
+      uint32_t flags = 0);
+};
+
+// The Binder client interface to IBluetooth.
+class BpBluetooth : public android::BpInterface<IBluetooth> {
+ public:
+  BpBluetooth(const android::sp<android::IBinder>& impl);
+  virtual ~BpBluetooth() = default;
+
+  // IBluetooth overrides:
+  bool IsEnabled() override;
+  int GetState() override;
+  bool Enable() override;
+  bool EnableNoAutoConnect() override;
+  bool Disable() override;
+  std::string GetAddress() override;
+  std::vector<bluetooth::UUID> GetUUIDs() override;
+  bool SetName(const std::string& name) override;
+  std::string GetName() override;
+  void RegisterCallback(
+      const android::sp<IBluetoothCallback>& callback) override;
+  void UnregisterCallback(
+      const android::sp<IBluetoothCallback>& callback) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BpBluetooth);
+};
+
+}  // namespace binder
+}  // namespace ipc
diff --git a/service/ipc/binder/IBluetoothCallback.cpp b/service/ipc/binder/IBluetoothCallback.cpp
new file mode 100644 (file)
index 0000000..7cb4f8d
--- /dev/null
@@ -0,0 +1,86 @@
+//
+//  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 "service/ipc/binder/IBluetoothCallback.h"
+
+#include <base/logging.h>
+#include <binder/Parcel.h>
+
+using android::IBinder;
+using android::Parcel;
+using android::sp;
+
+namespace ipc {
+namespace binder {
+
+// static
+const char IBluetoothCallback::kBluetoothCallbackServiceName[] =
+    "bluetooth-callback-service";
+
+// BnBluetoothCallback (server) implementation
+// ========================================================
+
+android::status_t BnBluetoothCallback::onTransact(
+    uint32_t code,
+    const Parcel& data,
+    Parcel* reply,
+    uint32_t flags) {
+  VLOG(2) << "IBluetoothCallback transaction: " << code;
+  if (!data.checkInterface(this))
+    return android::PERMISSION_DENIED;
+
+  switch (code) {
+    case ON_BLUETOOTH_STATE_CHANGE_TRANSACTION: {
+      int prev_state, new_state;
+      if (data.readInt32(&prev_state) != android::NO_ERROR ||
+          data.readInt32(&new_state) != android::NO_ERROR)
+        return android::NOT_ENOUGH_DATA;
+
+      OnBluetoothStateChange(
+          static_cast<bluetooth::AdapterState>(prev_state),
+          static_cast<bluetooth::AdapterState>(new_state));
+      return android::NO_ERROR;
+    }
+    default:
+      return BBinder::onTransact(code, data, reply, flags);
+  }
+}
+
+// BpBluetoothCallback (client) implementation
+// ========================================================
+
+BpBluetoothCallback::BpBluetoothCallback(const sp<IBinder>& impl)
+  : BpInterface<IBluetoothCallback>(impl) {
+}
+
+void BpBluetoothCallback::OnBluetoothStateChange(
+    bluetooth::AdapterState prev_state,
+    bluetooth::AdapterState new_state) {
+  Parcel data, reply;
+
+  data.writeInterfaceToken(IBluetoothCallback::getInterfaceDescriptor());
+  data.writeInt32(prev_state);
+  data.writeInt32(new_state);
+
+  remote()->transact(IBluetoothCallback::ON_BLUETOOTH_STATE_CHANGE_TRANSACTION,
+                     data, &reply);
+}
+
+IMPLEMENT_META_INTERFACE(BluetoothCallback,
+                         IBluetoothCallback::kBluetoothCallbackServiceName);
+
+}  // namespace binder
+}  // namespace ipc
diff --git a/service/ipc/binder/IBluetoothCallback.h b/service/ipc/binder/IBluetoothCallback.h
new file mode 100644 (file)
index 0000000..3ae60a3
--- /dev/null
@@ -0,0 +1,87 @@
+//
+//  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/macros.h>
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+
+#include "service/adapter_state.h"
+
+namespace ipc {
+namespace binder {
+
+// This class defines the Binder IPC interface for receiving adapter state
+// updates from the Bluetooth service. This class was written based on the
+// corresponding AIDL file at
+// /frameworks/base/core/java/android/bluetooth/IBluetoothCallback.aidl.
+//
+// NOTE: KEEP THIS FILE UP-TO-DATE with the corresponding AIDL, otherwise this
+// won't be compatible with the Android framework.
+class IBluetoothCallback : public android::IInterface {
+ public:
+  DECLARE_META_INTERFACE(BluetoothCallback);
+
+  static const char kBluetoothCallbackServiceName[];
+
+  // Transaction codes for interface methods.
+  enum {
+    ON_BLUETOOTH_STATE_CHANGE_TRANSACTION =
+        android::IBinder::FIRST_CALL_TRANSACTION,
+  };
+
+  virtual void OnBluetoothStateChange(
+      bluetooth::AdapterState prev_state,
+      bluetooth::AdapterState new_state) = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(IBluetoothCallback);
+};
+
+// TODO(armansito): Implement notification for when the process dies.
+
+// The Binder server interface to IBluetoothCallback. A class that implements
+// IBluetoothCallback must inherit from this class.
+class BnBluetoothCallback : public android::BnInterface<IBluetoothCallback> {
+ public:
+  BnBluetoothCallback() = default;
+  virtual ~BnBluetoothCallback() = default;
+
+ private:
+  virtual android::status_t onTransact(
+      uint32_t code,
+      const android::Parcel& data,
+      android::Parcel* reply,
+      uint32_t flags = 0);
+};
+
+// The Binder client interface to IBluetoothCallback.
+class BpBluetoothCallback : public android::BpInterface<IBluetoothCallback> {
+ public:
+  BpBluetoothCallback(const android::sp<android::IBinder>& impl);
+  virtual ~BpBluetoothCallback() = default;
+
+  // IBluetoothCallback override:
+  void OnBluetoothStateChange(bluetooth::AdapterState prev_state,
+                              bluetooth::AdapterState new_state) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BpBluetoothCallback);
+};
+
+}  // namespace binder
+}  // namespace ipc
diff --git a/service/ipc/binder/bluetooth_binder_server.cpp b/service/ipc/binder/bluetooth_binder_server.cpp
new file mode 100644 (file)
index 0000000..3a1631b
--- /dev/null
@@ -0,0 +1,113 @@
+//
+//  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 "service/ipc/binder/bluetooth_binder_server.h"
+
+#include <base/logging.h>
+
+#include "service/adapter.h"
+
+namespace ipc {
+namespace binder {
+
+BluetoothBinderServer::BluetoothBinderServer(bluetooth::Adapter* adapter)
+    : adapter_(adapter) {
+  CHECK(adapter_);
+  adapter_->AddObserver(this);
+}
+
+BluetoothBinderServer::~BluetoothBinderServer() {
+  adapter_->RemoveObserver(this);
+}
+
+// binder::BnBluetooth overrides:
+bool BluetoothBinderServer::IsEnabled() {
+  VLOG(2) << __func__;
+  return adapter_->IsEnabled();
+}
+
+int BluetoothBinderServer::GetState() {
+  VLOG(2) << __func__;
+  return adapter_->GetState();
+}
+
+bool BluetoothBinderServer::Enable() {
+  VLOG(2) << __func__;
+  return adapter_->Enable();
+}
+
+bool BluetoothBinderServer::EnableNoAutoConnect() {
+  VLOG(2) << __func__;
+  // TODO(armansito): Implement.
+  return false;
+}
+
+bool BluetoothBinderServer::Disable() {
+  VLOG(2) << __func__;
+  return adapter_->Disable();
+}
+
+std::string BluetoothBinderServer::GetAddress() {
+  return adapter_->GetAddress();
+}
+
+std::vector<bluetooth::UUID> BluetoothBinderServer::GetUUIDs() {
+  // TODO(armansito): Implement.
+  return std::vector<bluetooth::UUID>();
+}
+
+bool BluetoothBinderServer::SetName(const std::string& name) {
+  return adapter_->SetName(name);
+}
+
+std::string BluetoothBinderServer::GetName() {
+  return adapter_->GetName();
+}
+
+void BluetoothBinderServer::RegisterCallback(
+    const android::sp<IBluetoothCallback>& callback) {
+  VLOG(2) << __func__;
+  if (!callback.get() ) {
+    LOG(ERROR) << "RegisterCallback called with NULL binder. Ignoring.";
+    return;
+  }
+  callbacks_.Register(callback);
+}
+
+void BluetoothBinderServer::UnregisterCallback(
+    const android::sp<IBluetoothCallback>& callback) {
+  VLOG(2) << __func__;
+  if (!callback.get() ) {
+    LOG(ERROR) << "UnregisterCallback called with NULL binder. Ignoring.";
+    return;
+  }
+  callbacks_.Unregister(callback);
+}
+
+void BluetoothBinderServer::OnAdapterStateChanged(
+    bluetooth::Adapter* adapter,
+    bluetooth::AdapterState prev_state,
+    bluetooth::AdapterState new_state) {
+  CHECK_EQ(adapter, adapter_);
+  VLOG(2) << "Received adapter state update - prev: " << prev_state
+          << " new: " << new_state;
+  callbacks_.ForEach([prev_state, new_state](IBluetoothCallback* callback) {
+    callback->OnBluetoothStateChange(prev_state, new_state);
+  });
+}
+
+}  // namespace binder
+}  // namespace ipc
diff --git a/service/ipc/binder/bluetooth_binder_server.h b/service/ipc/binder/bluetooth_binder_server.h
new file mode 100644 (file)
index 0000000..cf0069e
--- /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.
+//
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <base/macros.h>
+
+#include "service/adapter.h"
+#include "service/ipc/binder/IBluetooth.h"
+#include "service/ipc/binder/IBluetoothCallback.h"
+#include "service/ipc/binder/remote_callback_list.h"
+#include "service/uuid.h"
+
+namespace ipc {
+namespace binder {
+
+// Implements the server side of the IBluetooth Binder interface.
+class BluetoothBinderServer : public BnBluetooth,
+                              public bluetooth::Adapter::Observer {
+ public:
+  explicit BluetoothBinderServer(bluetooth::Adapter* adapter);
+  ~BluetoothBinderServer() override;
+
+  // IBluetooth overrides:
+  bool IsEnabled() override;
+  int GetState() override;
+  bool Enable() override;
+  bool EnableNoAutoConnect() override;
+  bool Disable() override;
+
+  std::string GetAddress() override;
+  std::vector<bluetooth::UUID> GetUUIDs() override;
+  bool SetName(const std::string& name) override;
+  std::string GetName() override;
+
+  void RegisterCallback(
+      const android::sp<IBluetoothCallback>& callback) override;
+  void UnregisterCallback(
+      const android::sp<IBluetoothCallback>& callback) override;
+
+  // bluetooth::Adapter::Observer overrides:
+  void OnAdapterStateChanged(bluetooth::Adapter* adapter,
+                             bluetooth::AdapterState prev_state,
+                             bluetooth::AdapterState new_state) override;
+
+ private:
+  // Weak handle on the Adapter.
+  bluetooth::Adapter* adapter_;
+  RemoteCallbackList<IBluetoothCallback> callbacks_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothBinderServer);
+};
+
+}  // namespace binder
+}  // namespace ipc
diff --git a/service/ipc/binder/ipc_handler_binder.cpp b/service/ipc/binder/ipc_handler_binder.cpp
new file mode 100644 (file)
index 0000000..e357157
--- /dev/null
@@ -0,0 +1,82 @@
+//
+//  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 "service/ipc/binder/ipc_handler_binder.h"
+
+#include <base/bind.h>
+#include <base/logging.h>
+#include <base/message_loop/message_loop.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include "service/ipc/binder/bluetooth_binder_server.h"
+
+using android::defaultServiceManager;
+using android::sp;
+using android::status_t;
+using android::String16;
+
+namespace ipc {
+
+IPCHandlerBinder::IPCHandlerBinder(
+    bluetooth::Adapter* adapter,
+    IPCManager::Delegate* delegate)
+    : IPCHandler(adapter, delegate) {
+}
+
+IPCHandlerBinder::~IPCHandlerBinder() {
+}
+
+bool IPCHandlerBinder::Run() {
+  CHECK(adapter());
+
+  // Register the IBluetooth service with the Android ServiceManager.
+  android::sp<binder::BluetoothBinderServer> bt_server =
+      new binder::BluetoothBinderServer(adapter());
+  status_t status = defaultServiceManager()->addService(
+      String16(binder::IBluetooth::kBluetoothServiceName),
+      bt_server);
+  if (status != android::NO_ERROR) {
+    LOG(ERROR) << "Failed to register Bluetooth service with ServiceManager";
+    return false;
+  }
+
+  // Notify the delegate. We do this in the message loop to avoid reentrancy.
+  if (delegate()) {
+    base::MessageLoop::current()->task_runner()->PostTask(
+        FROM_HERE,
+        base::Bind(&IPCHandlerBinder::NotifyStarted, this));
+  }
+
+  android::ProcessState::self()->startThreadPool();
+
+  return true;
+}
+
+void IPCHandlerBinder::Stop() {
+  // TODO(armansito): There are several methods in android::IPCThreadState that
+  // are related to shutting down the threadpool, however I haven't been able to
+  // make them shut things down cleanly. Figure out the right way to stop the
+  // Binder IPC here.
+}
+
+void IPCHandlerBinder::NotifyStarted() {
+  if (delegate())
+    delegate()->OnIPCHandlerStarted(IPCManager::TYPE_BINDER);
+}
+
+}  // namespace ipc
diff --git a/service/ipc/binder/ipc_handler_binder.h b/service/ipc/binder/ipc_handler_binder.h
new file mode 100644 (file)
index 0000000..ef8621b
--- /dev/null
@@ -0,0 +1,46 @@
+//
+//  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/macros.h>
+
+#include "service/ipc/ipc_handler.h"
+#include "service/ipc/ipc_manager.h"
+
+namespace ipc {
+
+// Implements a Binder based IPCHandler.
+class IPCHandlerBinder : public IPCHandler {
+ public:
+  IPCHandlerBinder(bluetooth::Adapter* adapter,
+                   IPCManager::Delegate* delegate);
+  ~IPCHandlerBinder() override;
+
+  // IPCHandler overrides:
+  bool Run() override;
+  void Stop() override;
+
+ private:
+  IPCHandlerBinder() = default;
+
+  // Notify the delegate that IPC has started.
+  void NotifyStarted();
+
+  DISALLOW_COPY_AND_ASSIGN(IPCHandlerBinder);
+};
+
+}  // namespace ipc
diff --git a/service/ipc/binder/remote_callback_list.h b/service/ipc/binder/remote_callback_list.h
new file mode 100644 (file)
index 0000000..33c975d
--- /dev/null
@@ -0,0 +1,203 @@
+//
+//  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 <functional>
+#include <map>
+#include <mutex>
+
+#include <base/logging.h>
+#include <base/macros.h>
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+
+namespace ipc {
+namespace binder {
+
+// Takes care of the grunt work of maintaining a list of remote interfaces,
+// typically for the use of performing registered callbacks from a remote
+// service. This is a native equivalent of the the android.os.RemoteCallbackList
+// Java class. The type "T" must inherit from android::IInterface.
+//
+// TODO(armansito): We need to unit test this class. Right now it's defined as a
+// simple template interface over the native libbinder types directly and we
+// can't compile libbinder for host unless the Binder kernel module is enabled
+// on the system. Figure out whether to:
+//    1) write the Binder test-code in a new target-only executable;
+//    2) conditionally compile into the host-native test suite if the Binder
+//       module is built;
+//    3) provide a test-only static library that re-defines the libbinder
+//       classes as mocks.
+// (See http://b/23386387)
+//
+// TODO(armansito): We should make this class non-final and the template
+// interface abstract, so that code that depends on this can be unit tested
+// against a mock version of this class.
+//
+// TODO(armansito): Consider submitting this class to frameworks/native/binder.
+template<typename T>
+class RemoteCallbackList final {
+ public:
+  RemoteCallbackList() = default;
+  ~RemoteCallbackList();
+
+  // Register and unregister a callback interface. Registering will
+  // automatically start tracking for death notifications in case the remote
+  // process hosting the Binder dies. In such a case, the Binder is
+  // automatically removed from the list.
+  bool Register(const android::sp<T>& callback);
+  bool Unregister(const android::sp<T>& callback);
+
+  // Calls the given function on each of the contained callbacks. The internal
+  // mutex is locked for the duration of the iteration.
+  void ForEach(const std::function<void(T*)>& callback);
+
+ private:
+  class CallbackDeathRecipient : public android::IBinder::DeathRecipient {
+   public:
+    explicit CallbackDeathRecipient(const android::sp<T>& callback,
+                                    RemoteCallbackList* owner);
+
+    android::sp<T> get_callback() const { return callback_; }
+
+    // android::DeathRecipient override:
+    void binderDied(const android::wp<android::IBinder>& who) override;
+
+   private:
+    android::sp<T> callback_;
+    RemoteCallbackList<T>* owner_;  // weak
+  };
+
+  // Typedef for internal map container. This keeps track of a given Binder and
+  // a death receiver associated with it.
+  using CallbackMap = std::map<android::sp<android::IBinder>,
+                               android::sp<CallbackDeathRecipient>>;
+
+  bool UnregisterInternal(typename CallbackMap::iterator iter);
+
+  std::mutex map_lock_;
+  CallbackMap callbacks_;
+
+  DISALLOW_COPY_AND_ASSIGN(RemoteCallbackList);
+};
+
+// Template Implementation details below
+// ========================================================
+
+using android::IBinder;
+using android::IInterface;
+using android::sp;
+using android::wp;
+
+template<typename T>
+RemoteCallbackList<T>::~RemoteCallbackList() {
+  std::lock_guard<std::mutex> lock(map_lock_);
+  for (auto iter = callbacks_.begin(); iter != callbacks_.end(); ++iter)
+    UnregisterInternal(iter);
+}
+
+template<typename T>
+bool RemoteCallbackList<T>::Register(const sp<T>& callback) {
+  std::lock_guard<std::mutex> lock(map_lock_);
+
+  sp<IBinder> binder = IInterface::asBinder(callback.get());
+  if (callbacks_.find(binder) != callbacks_.end()) {
+    VLOG(1) << "Callback list already contains given callback";
+    return false;
+  }
+
+  sp<CallbackDeathRecipient> dr(new CallbackDeathRecipient(callback, this));
+
+  if (binder->linkToDeath(dr) != android::NO_ERROR) {
+    LOG(ERROR) << "Failed to link death recipient to binder";
+    return false;
+  }
+
+  callbacks_[binder] = dr;
+
+  VLOG(1) << "Callback successfully registered";
+
+  return true;
+}
+
+template<typename T>
+bool RemoteCallbackList<T>::Unregister(const sp<T>& callback) {
+  std::lock_guard<std::mutex> lock(map_lock_);
+
+  sp<IBinder> binder = IInterface::asBinder(callback.get());
+  auto iter = callbacks_.find(binder);
+  if (iter == callbacks_.end()) {
+    VLOG(1) << "Given callback not registered";
+    return false;
+  }
+
+  return UnregisterInternal(iter);
+}
+
+template<typename T>
+void RemoteCallbackList<T>::ForEach(const std::function<void(T*)>& callback) {
+  std::lock_guard<std::mutex> lock(map_lock_);
+  for (const auto& iter : callbacks_)
+    callback(iter.second->get_callback().get());
+}
+
+template<typename T>
+bool RemoteCallbackList<T>::UnregisterInternal(
+    typename CallbackMap::iterator iter) {
+  sp<CallbackDeathRecipient> dr = iter->second;
+  callbacks_.erase(iter);
+
+  if (IInterface::asBinder(dr->get_callback().get())->unlinkToDeath(dr) !=
+      android::NO_ERROR) {
+    LOG(ERROR) << "Failed to unlink death recipient from binder";
+    return false;
+  }
+
+  VLOG(1) << "Callback successfully unregistered";
+
+  return true;
+}
+
+template<typename T>
+RemoteCallbackList<T>::CallbackDeathRecipient::CallbackDeathRecipient(
+    const sp<T>& callback,
+    RemoteCallbackList<T>* owner)
+    : callback_(callback),
+      owner_(owner) {
+  CHECK(callback_.get());
+  CHECK(owner_);
+}
+
+template<typename T>
+void RemoteCallbackList<T>::CallbackDeathRecipient::binderDied(
+    const wp<IBinder>& who) {
+  VLOG(1) << "Received binderDied";
+
+  sp<IBinder> binder = IInterface::asBinder(callback_.get());
+  CHECK(who.unsafe_get() == binder.get());
+
+  // Remove the callback but no need to call unlinkToDeath.
+  std::lock_guard<std::mutex> lock(owner_->map_lock_);
+  auto iter = owner_->callbacks_.find(binder);
+  CHECK(iter != owner_->callbacks_.end());
+  owner_->callbacks_.erase(iter);
+
+  VLOG(1) << "Callback from dead process unregistered";
+}
+
+}  // namespace binder
+}  // namespace ipc
diff --git a/service/ipc/ipc_handler.cpp b/service/ipc/ipc_handler.cpp
new file mode 100644 (file)
index 0000000..ffea0ee
--- /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.
+//
+
+#include "service/ipc/ipc_handler.h"
+
+#include <base/logging.h>
+
+namespace ipc {
+
+IPCHandler::IPCHandler(bluetooth::Adapter* adapter,
+                       IPCManager::Delegate* delegate)
+    : adapter_(adapter),
+      delegate_(delegate) {
+  CHECK(adapter_);
+}
+
+IPCHandler::~IPCHandler() {
+}
+
+}  // namespace ipc
diff --git a/service/ipc/ipc_handler.h b/service/ipc/ipc_handler.h
new file mode 100644 (file)
index 0000000..b1029ca
--- /dev/null
@@ -0,0 +1,62 @@
+//
+//  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/macros.h>
+#include <base/memory/ref_counted.h>
+
+#include "service/ipc/ipc_manager.h"
+
+namespace bluetooth {
+class Adapter;
+}  // namespace bluetooth
+
+namespace ipc {
+
+// IPCHandler is an interface that classes implementing different IPC mechanisms
+// must conform to.
+class IPCHandler : public base::RefCountedThreadSafe<IPCHandler> {
+ public:
+  IPCHandler(bluetooth::Adapter* adapter, IPCManager::Delegate* delegate);
+  virtual ~IPCHandler();
+
+  // Initializes and runs the IPC mechanism. Returns true on success, false
+  // otherwise.
+  virtual bool Run() = 0;
+
+  // Stops the IPC mechanism.
+  virtual void Stop() = 0;
+
+ protected:
+  // Getters for private members to allow subclasses to access them in read-only
+  // fashion.
+  bluetooth::Adapter* adapter() const { return adapter_; }
+  IPCManager::Delegate* delegate() const { return delegate_; }
+
+ private:
+  IPCHandler() = default;
+
+  // Weak reference to the global Adapter instance.
+  bluetooth::Adapter* adapter_;
+
+  // The delegate that is interested in notifications from us.
+  IPCManager::Delegate* delegate_;
+
+  DISALLOW_COPY_AND_ASSIGN(IPCHandler);
+};
+
+}  // namespace ipc
diff --git a/service/ipc/ipc_handler_unix.cpp b/service/ipc/ipc_handler_unix.cpp
new file mode 100644 (file)
index 0000000..eaba84d
--- /dev/null
@@ -0,0 +1,215 @@
+//
+//  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 "service/ipc/ipc_handler_unix.h"
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <base/bind.h>
+
+#include "osi/include/socket_utils/sockets.h"
+#include "service/daemon.h"
+#include "service/ipc/unix_ipc_host.h"
+#include "service/settings.h"
+
+namespace ipc {
+
+IPCHandlerUnix::IPCHandlerUnix(bluetooth::Adapter* adapter,
+                               IPCManager::Delegate* delegate)
+    : IPCHandler(adapter, delegate),
+      running_(false),
+      thread_("IPCHandlerUnix"),
+      keep_running_(true) {
+}
+
+IPCHandlerUnix::~IPCHandlerUnix() {
+  // This will only be set if the Settings::create_ipc_socket_path() was
+  // originally provided.
+  if (!socket_path_.empty())
+    unlink(socket_path_.value().c_str());
+}
+
+bool IPCHandlerUnix::Run() {
+  CHECK(!running_);
+
+  const std::string& android_suffix =
+      bluetooth::Daemon::Get()->GetSettings()->android_ipc_socket_suffix();
+  const base::FilePath& path =
+      bluetooth::Daemon::Get()->GetSettings()->create_ipc_socket_path();
+
+  // Both flags cannot be set at the same time.
+  CHECK(android_suffix.empty() || path.empty());
+  if (android_suffix.empty() && path.empty()) {
+    LOG(ERROR) << "No domain socket path provided";
+    return false;
+  }
+
+  CHECK(base::MessageLoop::current());  // An origin event loop is required.
+  origin_task_runner_ = base::MessageLoop::current()->task_runner();
+
+  if (!android_suffix.empty()) {
+    int server_fd = osi_android_get_control_socket(android_suffix.c_str());
+    if (server_fd == -1) {
+      LOG(ERROR) << "Unable to get Android socket from: " << android_suffix;
+      return false;
+    }
+    LOG(INFO) << "Binding to Android server socket:" << android_suffix;
+    socket_.reset(server_fd);
+  } else {
+    LOG(INFO) << "Creating a Unix domain socket:" << path.value();
+
+    // TODO(armansito): This is opens the door to potentially unlinking files in
+    // the current directory that we're not supposed to. For now we will have an
+    // assumption that the daemon runs in a sandbox but we should generally do
+    // this properly.
+    unlink(path.value().c_str());
+
+    base::ScopedFD server_socket(socket(PF_UNIX, SOCK_SEQPACKET, 0));
+    if (!server_socket.is_valid()) {
+      LOG(ERROR) << "Failed to open domain socket for IPC";
+      return false;
+    }
+
+    struct sockaddr_un address;
+    memset(&address, 0, sizeof(address));
+    address.sun_family = AF_UNIX;
+    strncpy(address.sun_path, path.value().c_str(),
+            sizeof(address.sun_path) - 1);
+    if (bind(server_socket.get(), (struct sockaddr*)&address, sizeof(address)) <
+        0) {
+      LOG(ERROR) << "Failed to bind IPC socket to address: " << strerror(errno);
+      return false;
+    }
+
+    socket_.swap(server_socket);
+    socket_path_ = path;
+  }
+
+  CHECK(socket_.is_valid());
+
+  running_ = true;  // Set this here before launching the thread.
+
+  // Start an IO thread and post the listening task.
+  base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
+  if (!thread_.StartWithOptions(options)) {
+    LOG(ERROR) << "Failed to start IPCHandlerUnix thread";
+    running_ = false;
+    return false;
+  }
+
+  thread_.task_runner()->PostTask(
+      FROM_HERE,
+      base::Bind(&IPCHandlerUnix::StartListeningOnThread, this));
+
+  return true;
+}
+
+void IPCHandlerUnix::Stop() {
+  keep_running_ = false;
+
+  // At this moment the listening thread might be blocking on the accept
+  // syscall. Shutdown and close the server socket before joining the thread to
+  // interrupt accept so that the main thread doesn't keep blocking.
+  shutdown(socket_.get(), SHUT_RDWR);
+  socket_.reset();
+
+  // Join and clean up the thread.
+  thread_.Stop();
+
+  // Thread exited. Notify the delegate. Post this on the event loop so that the
+  // callback isn't reentrant.
+  NotifyStoppedOnOriginThread();
+}
+
+void IPCHandlerUnix::StartListeningOnThread() {
+  CHECK(socket_.is_valid());
+  CHECK(adapter());
+  CHECK(running_);
+
+  LOG(INFO) << "Listening to incoming connections";
+
+  int status = listen(socket_.get(), SOMAXCONN);
+  if (status < 0) {
+    LOG(ERROR) << "Failed to listen on domain socket: " << strerror(errno);
+    origin_task_runner_->PostTask(
+        FROM_HERE,
+        base::Bind(&IPCHandlerUnix::ShutDownOnOriginThread, this));
+    return;
+  }
+
+  NotifyStartedOnOriginThread();
+
+  // TODO(armansito): The code below can cause the daemon to run indefinitely if
+  // the thread is joined while it's in the middle of the EventLoop() call. The
+  // EventLoop() won't exit until a client terminates the connection, however
+  // this can be fixed by using the |thread_|'s MessageLoopForIO instead (since
+  // it gets stopped along with the thread).
+  // TODO(icoolidge): accept simultaneous clients
+  while (keep_running_.load()) {
+    int client_socket = accept4(socket_.get(), nullptr, nullptr, SOCK_NONBLOCK);
+    if (client_socket < 0) {
+      LOG(ERROR) << "Failed to accept client connection: " << strerror(errno);
+      continue;
+    }
+
+    LOG(INFO) << "Established client connection: fd=" << client_socket;
+
+    UnixIPCHost ipc_host(client_socket, adapter());
+
+    // TODO(armansito): Use |thread_|'s MessageLoopForIO instead of using a
+    // custom event loop to poll from the socket.
+    ipc_host.EventLoop();
+  }
+}
+
+void IPCHandlerUnix::ShutDownOnOriginThread() {
+  LOG(INFO) << "Shutting down IPCHandlerUnix thread";
+  thread_.Stop();
+  running_ = false;
+
+  NotifyStoppedOnCurrentThread();
+}
+
+void IPCHandlerUnix::NotifyStartedOnOriginThread() {
+  if (!delegate())
+    return;
+
+  origin_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&IPCHandlerUnix::NotifyStartedOnCurrentThread, this));
+}
+
+void IPCHandlerUnix::NotifyStartedOnCurrentThread() {
+  if (delegate())
+    delegate()->OnIPCHandlerStarted(IPCManager::TYPE_UNIX);
+}
+
+void IPCHandlerUnix::NotifyStoppedOnOriginThread() {
+  if (!delegate())
+    return;
+
+  origin_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&IPCHandlerUnix::NotifyStoppedOnCurrentThread, this));
+}
+
+void IPCHandlerUnix::NotifyStoppedOnCurrentThread() {
+  if (delegate())
+    delegate()->OnIPCHandlerStopped(IPCManager::TYPE_UNIX);
+}
+
+}  // namespace ipc
diff --git a/service/ipc/ipc_handler_unix.h b/service/ipc/ipc_handler_unix.h
new file mode 100644 (file)
index 0000000..4b91740
--- /dev/null
@@ -0,0 +1,86 @@
+//
+//  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 <atomic>
+
+#include <base/files/file_path.h>
+#include <base/files/scoped_file.h>
+#include <base/macros.h>
+#include <base/threading/thread.h>
+
+#include "service/ipc/ipc_handler.h"
+#include "service/ipc/ipc_manager.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}  // namespace base
+
+namespace ipc {
+
+// Implements a UNIX domain-socket based IPCHandler
+class IPCHandlerUnix : public IPCHandler {
+ public:
+  IPCHandlerUnix(bluetooth::Adapter* adapter,
+                 IPCManager::Delegate* delegate);
+  ~IPCHandlerUnix() override;
+
+  // IPCHandler overrides:
+  bool Run() override;
+  void Stop() override;
+
+ private:
+  IPCHandlerUnix() = default;
+
+  // Starts listening for incoming connections. Posted on |thread_| by Run().
+  void StartListeningOnThread();
+
+  // Stops the IPC thread. This helper is needed since base::Thread requires
+  // threads to be stopped on the thread that started them.
+  void ShutDownOnOriginThread();
+
+  // Notifies the delegate that we started or stoppedlistening for incoming
+  // connections.
+  void NotifyStartedOnOriginThread();
+  void NotifyStartedOnCurrentThread();
+  void NotifyStoppedOnOriginThread();
+  void NotifyStoppedOnCurrentThread();
+
+  // True, if the IPC mechanism is running.
+  bool running_;
+
+  // The server socket on which we listen to incoming connections.
+  base::ScopedFD socket_;
+
+  // The file path to |socket_|. This is only set if we create and manage the
+  // life time of the socket.
+  base::FilePath socket_path_;
+
+  // We use a dedicated thread for listening to incoming connections and
+  // polling from the socket to avoid blocking the main thread.
+  base::Thread thread_;
+
+  // Whether or not the listening thread should continue to run.
+  std::atomic<bool> keep_running_;
+
+  // The origin thread's task runner.
+  scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_;
+
+  DISALLOW_COPY_AND_ASSIGN(IPCHandlerUnix);
+};
+
+}  // namespace ipc
diff --git a/service/ipc/ipc_manager.cpp b/service/ipc/ipc_manager.cpp
new file mode 100644 (file)
index 0000000..40d57a3
--- /dev/null
@@ -0,0 +1,81 @@
+//
+//  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 "service/ipc/ipc_manager.h"
+
+#include "service/ipc/binder/ipc_handler_binder.h"
+#include "service/ipc/ipc_handler_unix.h"
+
+namespace ipc {
+
+IPCManager::IPCManager(bluetooth::Adapter* adapter)
+    : adapter_(adapter) {
+  CHECK(adapter_);
+}
+
+IPCManager::~IPCManager() {
+  // Don't rely on the handlers getting destroyed since another thread might be
+  // holding a reference to them. Instead, explicitly stop them here.
+  if (BinderStarted())
+    binder_handler_->Stop();
+  if (UnixStarted())
+    unix_handler_->Stop();
+}
+
+bool IPCManager::Start(Type type, Delegate* delegate) {
+  switch (type) {
+  case TYPE_UNIX:
+    if (UnixStarted()) {
+      LOG(ERROR) << "IPCManagerUnix already started.";
+      return false;
+    }
+
+    unix_handler_ = new IPCHandlerUnix(adapter_, delegate);
+    if (!unix_handler_->Run()) {
+      unix_handler_ = nullptr;
+      return false;
+    }
+    return true;
+
+  case TYPE_BINDER:
+    if (BinderStarted()) {
+      LOG(ERROR) << "IPCManagerBinder already started.";
+      return false;
+    }
+
+    binder_handler_ = new IPCHandlerBinder(adapter_, delegate);
+    if (!binder_handler_->Run()) {
+      binder_handler_ = nullptr;
+      return false;
+    }
+    return true;
+
+  default:
+    LOG(ERROR) << "Unsupported IPC type given: " << type;
+  }
+
+  return false;
+}
+
+bool IPCManager::BinderStarted() const {
+  return binder_handler_.get();
+}
+
+bool IPCManager::UnixStarted() const {
+  return unix_handler_.get();
+}
+
+}  // namespace ipc
diff --git a/service/ipc/ipc_manager.h b/service/ipc/ipc_manager.h
new file mode 100644 (file)
index 0000000..bac60aa
--- /dev/null
@@ -0,0 +1,100 @@
+//
+//  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 <memory>
+
+#include <base/macros.h>
+#include <base/memory/ref_counted.h>
+
+namespace bluetooth {
+class Adapter;
+}  // namespace bluetooth
+
+namespace ipc {
+
+class IPCHandler;
+
+// IPCManager is a class for initializing and running supported IPC mechanisms.
+// It manages the life-time of different IPC flavors that are available on the
+// system. There are two flavors: a plain UNIX domain socket based system and
+// one based on the Binder-based android.bluetooth framework.
+class IPCManager {
+ public:
+  // Possible IPC types.
+  enum Type {
+    TYPE_UNIX,  // IPC based on a UNIX domain socket
+    TYPE_BINDER  // IPC based on the Binder
+  };
+
+  // Interface for observing events from an IPC mechanism. These methods will be
+  // called on the thread that started the particular IPC type.
+  class Delegate {
+   public:
+    Delegate() = default;
+    virtual ~Delegate() = default;
+
+    // Called when an IPC mechanism has successfully started and is ready for
+    // client connections.
+    virtual void OnIPCHandlerStarted(Type type) = 0;
+
+    // Called when an IPC mechanism has stopped. This may happen due to an error
+    // in initialization or due to a regular shut down routine.
+    virtual void OnIPCHandlerStopped(Type type) = 0;
+
+   private:
+    DISALLOW_COPY_AND_ASSIGN(Delegate);
+  };
+
+  explicit IPCManager(bluetooth::Adapter* adapter);
+  ~IPCManager();
+
+  // Initialize the underlying IPC handler based on |type|, if that type has not
+  // yet been initialized and returns true on success. Returns false if that
+  // type has already been initialized or an error occurs.
+  //
+  // If TYPE_UNIX is given, the file path to use for the domain socket will be
+  // obtained from the global Settings object. Hence, the Settings object must
+  // have been initialized before calling this method.
+  //
+  // |delegate| must out-live the IPCManager and the underlying handler. Users
+  // can guarantee proper clean up by deallocating |delegate| when or after
+  // Delegate::OnIPCHandlerStopped is called. It is safe to destroy |delegate|
+  // after destroying the IPCManager instance, as the destructor will join and
+  // clean up all underlying threads.
+  bool Start(Type type, Delegate* delegate);
+
+  // Returns true if an IPC type has been initialized.
+  bool BinderStarted() const;
+  bool UnixStarted() const;
+
+ private:
+  IPCManager() = default;
+
+  // Pointers to the different IPC handler classes. These are initialized and
+  // owned by us.
+  scoped_refptr<IPCHandler> binder_handler_;
+  scoped_refptr<IPCHandler> unix_handler_;
+
+  // The Bluetooth adapter instance. This is owned by Daemon so we keep a raw
+  // pointer to it.
+  bluetooth::Adapter* adapter_;
+
+  DISALLOW_COPY_AND_ASSIGN(IPCManager);
+};
+
+}  // namespace ipc
diff --git a/service/ipc/unix_ipc_host.cpp b/service/ipc/unix_ipc_host.cpp
new file mode 100644 (file)
index 0000000..2f801d4
--- /dev/null
@@ -0,0 +1,339 @@
+//
+//  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.
+//
+
+#define LOG_TAG "bt_bluetooth_host"
+
+#include "service/ipc/unix_ipc_host.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <algorithm>
+
+#include <base/base64.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/string_split.h>
+
+#include "osi/include/log.h"
+#include "service/adapter.h"
+#include "service/gatt_server.h"
+#include "service/uuid.h"
+
+using bluetooth::Adapter;
+using bluetooth::UUID;
+
+using namespace bluetooth::gatt;
+
+namespace {
+
+// IPC API is according to:
+// https://docs.google.com/document/d/1eRnku-jAyVU1wGJsLT2CzWi0-8bs2g49s1b3FR_GApM
+const char kSetAdapterNameCommand[] = "set-device-name";
+const char kCreateServiceCommand[] = "create-service";
+const char kDestroyServiceCommand[] = "destroy-service";
+const char kAddCharacteristicCommand[] = "add-characteristic";
+const char kSetCharacteristicValueCommand[] = "set-characteristic-value";
+const char kSetAdvertisementCommand[] = "set-advertisement";
+const char kSetScanResponseCommand[] = "set-scan-response";
+const char kStartServiceCommand[] = "start-service";
+const char kStopServiceCommand[] = "stop-service";
+const char kWriteCharacteristicCommand[] = "write-characteristic";
+
+// Useful values for indexing UnixIPCHost::pfds_
+// Not super general considering that we should be able to support
+// many GATT FDs owned by one UnixIPCHost.
+enum {
+  kFdIpc = 0,
+  kFdGatt = 1,
+  kPossibleFds = 2,
+};
+
+bool TokenBool(const std::string& text) {
+  return text == "true";
+}
+
+}  // namespace
+
+namespace ipc {
+
+UnixIPCHost::UnixIPCHost(int sockfd, Adapter* adapter)
+    : adapter_(adapter), pfds_(1, {sockfd, POLLIN, 0}) {}
+
+UnixIPCHost::~UnixIPCHost() {
+  close(pfds_[0].fd);
+}
+
+bool UnixIPCHost::EventLoop() {
+  while (true) {
+    int status =
+        TEMP_FAILURE_RETRY(ppoll(pfds_.data(), pfds_.size(), nullptr, nullptr));
+    if (status < 1) {
+      LOG_ERROR(LOG_TAG, "ppoll error");
+      return false;
+    }
+
+    if (pfds_[kFdIpc].revents && !OnMessage()) {
+      return false;
+    }
+
+    if (pfds_.size() == kPossibleFds &&
+        pfds_[kFdGatt].revents &&
+        !OnGattWrite()) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool UnixIPCHost::OnSetAdapterName(const std::string& name) {
+  std::string decoded_data;
+  base::Base64Decode(name, &decoded_data);
+  return adapter_->SetName(decoded_data);
+}
+
+bool UnixIPCHost::OnCreateService(const std::string& service_uuid) {
+  gatt_servers_[service_uuid] = std::unique_ptr<Server>(new Server);
+
+  int gattfd;
+  bool status = gatt_servers_[service_uuid]->Initialize(
+          UUID(service_uuid), &gattfd);
+  if (!status) {
+    LOG_ERROR(LOG_TAG, "Failed to initialize bluetooth");
+    return false;
+  }
+  pfds_.resize(kPossibleFds);
+  pfds_[kFdGatt] = {gattfd, POLLIN, 0};
+  return true;
+}
+
+bool UnixIPCHost::OnDestroyService(const std::string& service_uuid) {
+  gatt_servers_.erase(service_uuid);
+  close(pfds_[1].fd);
+  pfds_.resize(1);
+  return true;
+}
+
+bool UnixIPCHost::OnAddCharacteristic(const std::string& service_uuid,
+                               const std::string& characteristic_uuid,
+                               const std::string& control_uuid,
+                               const std::string& options) {
+  std::vector<std::string> option_tokens;
+  base::SplitString(options, '.', &option_tokens);
+
+  int properties_mask = 0;
+  int permissions_mask = 0;
+
+  if (std::find(option_tokens.begin(), option_tokens.end(), "notify") !=
+      option_tokens.end()) {
+    permissions_mask |= kPermissionRead;
+    properties_mask |= kPropertyRead;
+    properties_mask |= kPropertyNotify;
+  }
+  if (std::find(option_tokens.begin(), option_tokens.end(), "read") !=
+      option_tokens.end()) {
+    permissions_mask |= kPermissionRead;
+    properties_mask |= kPropertyRead;
+  }
+  if (std::find(option_tokens.begin(), option_tokens.end(), "write") !=
+      option_tokens.end()) {
+    permissions_mask |= kPermissionWrite;
+    properties_mask |= kPropertyWrite;
+  }
+
+  if (control_uuid.empty()) {
+    gatt_servers_[service_uuid]->AddCharacteristic(
+        UUID(characteristic_uuid), properties_mask, permissions_mask);
+  } else {
+    gatt_servers_[service_uuid]->AddBlob(UUID(characteristic_uuid),
+                                         UUID(control_uuid), properties_mask,
+                                         permissions_mask);
+  }
+  return true;
+}
+
+bool UnixIPCHost::OnSetCharacteristicValue(const std::string& service_uuid,
+                                    const std::string& characteristic_uuid,
+                                    const std::string& value) {
+  std::string decoded_data;
+  base::Base64Decode(value, &decoded_data);
+  std::vector<uint8_t> blob_data(decoded_data.begin(), decoded_data.end());
+  gatt_servers_[service_uuid]->SetCharacteristicValue(UUID(characteristic_uuid),
+                                                      blob_data);
+  return true;
+}
+
+bool UnixIPCHost::OnSetAdvertisement(const std::string& service_uuid,
+                              const std::string& advertise_uuids,
+                              const std::string& advertise_data,
+                              const std::string& manufacturer_data,
+                              const std::string& transmit_name) {
+  LOG_INFO(LOG_TAG, "%s: service:%s uuids:%s data:%s", __func__, service_uuid.c_str(),
+           advertise_uuids.c_str(), advertise_data.c_str());
+
+  std::vector<std::string> advertise_uuid_tokens;
+  base::SplitString(advertise_uuids, '.', &advertise_uuid_tokens);
+
+  // string -> vector<UUID>
+  std::vector<UUID> ids;
+  for (const auto& uuid_token : advertise_uuid_tokens)
+    ids.emplace_back(uuid_token);
+
+  std::string decoded_data;
+  base::Base64Decode(advertise_data, &decoded_data);
+  std::vector<uint8_t> decoded_advertise_data(decoded_data.begin(),
+                                              decoded_data.end());
+
+  base::Base64Decode(manufacturer_data, &decoded_data);
+  std::vector<uint8_t> decoded_manufacturer_data(decoded_data.begin(),
+                                                 decoded_data.end());
+
+  gatt_servers_[service_uuid]->SetAdvertisement(ids, decoded_advertise_data,
+                                                decoded_manufacturer_data,
+                                                TokenBool(transmit_name));
+  return true;
+}
+
+bool UnixIPCHost::OnSetScanResponse(const std::string& service_uuid,
+                             const std::string& scan_response_uuids,
+                             const std::string& scan_response_data,
+                             const std::string& manufacturer_data,
+                             const std::string& transmit_name) {
+  std::vector<std::string> scan_response_uuid_tokens;
+  base::SplitString(scan_response_uuids, '.', &scan_response_uuid_tokens);
+
+  // string -> vector<UUID>
+  std::vector<UUID> ids;
+  for (const auto& uuid_token : scan_response_uuid_tokens)
+    ids.emplace_back(uuid_token);
+
+  std::string decoded_data;
+  base::Base64Decode(scan_response_data, &decoded_data);
+  std::vector<uint8_t> decoded_advertise_data(decoded_data.begin(),
+                                              decoded_data.end());
+
+  base::Base64Decode(manufacturer_data, &decoded_data);
+  std::vector<uint8_t> decoded_manufacturer_data(decoded_data.begin(),
+                                                 decoded_data.end());
+
+  gatt_servers_[service_uuid]->SetScanResponse(ids, decoded_advertise_data,
+                                               decoded_manufacturer_data,
+                                               TokenBool(transmit_name));
+  return true;
+}
+
+bool UnixIPCHost::OnStartService(const std::string& service_uuid) {
+  return gatt_servers_[service_uuid]->Start();
+}
+
+bool UnixIPCHost::OnStopService(const std::string& service_uuid) {
+  return gatt_servers_[service_uuid]->Stop();
+}
+
+bool UnixIPCHost::OnMessage() {
+  std::string ipc_msg;
+  int size = recv(pfds_[kFdIpc].fd, &ipc_msg[0], 0, MSG_PEEK | MSG_TRUNC);
+  if (-1 == size) {
+    LOG_ERROR(LOG_TAG, "Error reading datagram size: %s", strerror(errno));
+    return false;
+  } else if (0 == size) {
+    LOG_INFO(LOG_TAG, "%s:%d: Connection closed", __func__, __LINE__);
+    return false;
+  }
+
+  ipc_msg.resize(size);
+  size = read(pfds_[kFdIpc].fd, &ipc_msg[0], ipc_msg.size());
+  if (-1 == size) {
+    LOG_ERROR(LOG_TAG, "Error reading IPC: %s", strerror(errno));
+    return false;
+  } else if (0 == size) {
+    LOG_INFO(LOG_TAG, "%s:%d: Connection closed", __func__, __LINE__);
+    return false;
+  }
+
+  std::vector<std::string> tokens;
+  base::SplitString(ipc_msg, '|', &tokens);
+  switch (tokens.size()) {
+    case 2:
+      if (tokens[0] == kSetAdapterNameCommand)
+        return OnSetAdapterName(tokens[1]);
+      if (tokens[0] == kCreateServiceCommand)
+        return OnCreateService(tokens[1]);
+      if (tokens[0] == kDestroyServiceCommand)
+        return OnDestroyService(tokens[1]);
+      if (tokens[0] == kStartServiceCommand)
+        return OnStartService(tokens[1]);
+      if (tokens[0] == kStopServiceCommand)
+        return OnStopService(tokens[1]);
+      break;
+    case 4:
+      if (tokens[0] == kSetCharacteristicValueCommand)
+        return OnSetCharacteristicValue(tokens[1], tokens[2], tokens[3]);
+      break;
+    case 5:
+      if (tokens[0] == kAddCharacteristicCommand)
+        return OnAddCharacteristic(tokens[1], tokens[2], tokens[3], tokens[4]);
+      break;
+    case 6:
+      if (tokens[0] == kSetAdvertisementCommand)
+        return OnSetAdvertisement(tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]);
+      if (tokens[0] == kSetScanResponseCommand)
+        return OnSetScanResponse(tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]);
+      break;
+    default:
+      break;
+  }
+
+  LOG_ERROR(LOG_TAG, "Malformed IPC message: %s", ipc_msg.c_str());
+  return false;
+}
+
+bool UnixIPCHost::OnGattWrite() {
+  UUID::UUID128Bit id;
+  int r = read(pfds_[kFdGatt].fd, id.data(), id.size());
+  if (r != id.size()) {
+    LOG_ERROR(LOG_TAG, "Error reading GATT attribute ID");
+    return false;
+  }
+
+  std::vector<uint8_t> value;
+  // TODO(icoolidge): Generalize this for multiple clients.
+  auto server = gatt_servers_.begin();
+  server->second->GetCharacteristicValue(UUID(id), &value);
+  const std::string value_string(value.begin(), value.end());
+  std::string encoded_value;
+  base::Base64Encode(value_string, &encoded_value);
+
+  std::string transmit(kWriteCharacteristicCommand);
+  transmit += "|" + server->first;
+  transmit += "|" + base::HexEncode(id.data(), id.size());
+  transmit += "|" + encoded_value;
+
+  r = write(pfds_[kFdIpc].fd, transmit.data(), transmit.size());
+  if (-1 == r) {
+    LOG_ERROR(LOG_TAG, "Error replying to IPC: %s", strerror(errno));
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace ipc
diff --git a/service/ipc/unix_ipc_host.h b/service/ipc/unix_ipc_host.h
new file mode 100644 (file)
index 0000000..1ebf60a
--- /dev/null
@@ -0,0 +1,107 @@
+//
+//  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 <poll.h>
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "service/gatt_server.h"
+#include "service/uuid.h"
+
+namespace bluetooth {
+class Adapter;
+}  // namespace bluetooth
+
+namespace ipc {
+
+// This implements a single threaded event loop which dispatches
+// reads from a set of FDs (pfds_) to a set of handlers.
+// Reads from the GATT pipe read end will result in a write to
+// to the IPC socket, and vise versa.
+class UnixIPCHost {
+ public:
+  // UnixIPCHost owns the passed sockfd.
+  UnixIPCHost(int sockfd, bluetooth::Adapter* adapter);
+  ~UnixIPCHost();
+
+  // Synchronously handle all events on input FDs.
+  bool EventLoop();
+
+ private:
+  // Handler for IPC message receives.
+  // Decodes protocol and dispatches to another handler.
+  bool OnMessage();
+
+  // Handler for GATT characteristic writes.
+  // Encodes to protocol and transmits IPC.
+  bool OnGattWrite();
+
+  // Applies adapter name changes to stack.
+  bool OnSetAdapterName(const std::string& name);
+
+  // Handles service creation.
+  bool OnCreateService(const std::string& service_uuid);
+
+  // Handles service destruction.
+  bool OnDestroyService(const std::string& service_uuid);
+
+  // Creates a characteristic for a service.
+  bool OnAddCharacteristic(const std::string& service_uuid,
+                           const std::string& characteristic_uuid,
+                           const std::string& control_uuid,
+                           const std::string& options);
+
+  // Sets the value of a characetistic.
+  bool OnSetCharacteristicValue(const std::string& service_uuid,
+                                const std::string& characteristic_uuid,
+                                const std::string& value);
+
+  // Applies settings to service advertisement.
+  bool OnSetAdvertisement(const std::string& service_uuid,
+                          const std::string& advertise_uuids,
+                          const std::string& advertise_data,
+                          const std::string& manufacturer_data,
+                          const std::string& transmit_name);
+
+  // Applies settings to scan response.
+  bool OnSetScanResponse(const std::string& service_uuid,
+                         const std::string& advertise_uuids,
+                         const std::string& advertise_data,
+                         const std::string& manufacturer_data,
+                         const std::string& transmit_name);
+
+  // Starts service (advertisement and connections)
+  bool OnStartService(const std::string& service_uuid);
+
+  // Stops service.
+  bool OnStopService(const std::string& service_uuid);
+
+  // weak reference.
+  bluetooth::Adapter *adapter_;
+
+  // File descripters that we will block against.
+  std::vector<struct pollfd> pfds_;
+
+  // Container for multiple GATT servers. Currently only one is supported.
+  // TODO(icoolidge): support many to one for real.
+  std::unordered_map<std::string, std::unique_ptr<bluetooth::gatt::Server>>
+      gatt_servers_;
+};
+
+}  // namespace ipc
diff --git a/service/logging_helpers.cpp b/service/logging_helpers.cpp
new file mode 100644 (file)
index 0000000..4c00596
--- /dev/null
@@ -0,0 +1,140 @@
+//
+//  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 "logging_helpers.h"
+
+#include <string.h>
+
+#include <string>
+
+#define CASE_RETURN_TEXT(code) \
+  case code:                   \
+    return #code
+
+const char *BtAvConnectionStateText(const btav_connection_state_t state) {
+  switch (state) {
+    CASE_RETURN_TEXT(BTAV_CONNECTION_STATE_DISCONNECTED);
+    CASE_RETURN_TEXT(BTAV_CONNECTION_STATE_CONNECTING);
+    CASE_RETURN_TEXT(BTAV_CONNECTION_STATE_CONNECTED);
+    CASE_RETURN_TEXT(BTAV_CONNECTION_STATE_DISCONNECTING);
+    default:
+      return "Invalid AV connection state";
+  }
+}
+
+const char *BtAvAudioStateText(const btav_audio_state_t state) {
+  switch (state) {
+    CASE_RETURN_TEXT(BTAV_AUDIO_STATE_REMOTE_SUSPEND);
+    CASE_RETURN_TEXT(BTAV_AUDIO_STATE_STOPPED);
+    CASE_RETURN_TEXT(BTAV_AUDIO_STATE_STARTED);
+    default:
+      return "Invalid audio state";
+  }
+}
+
+const char *BtTransportText(const btgatt_transport_t t) {
+  switch(t) {
+    CASE_RETURN_TEXT(GATT_TRANSPORT_AUTO);
+    CASE_RETURN_TEXT(GATT_TRANSPORT_BREDR);
+    CASE_RETURN_TEXT(GATT_TRANSPORT_LE);
+    default:
+      return "unknown transport";
+  }
+}
+
+const char *BtStateText(const bt_state_t state) {
+  switch (state) {
+    CASE_RETURN_TEXT(BT_STATE_OFF);
+    CASE_RETURN_TEXT(BT_STATE_ON);
+    default:
+      return "unknown state code";
+  }
+}
+
+const char *BtScanModeText(const bt_scan_mode_t mode) {
+  switch (mode) {
+    CASE_RETURN_TEXT(BT_SCAN_MODE_NONE);
+    CASE_RETURN_TEXT(BT_SCAN_MODE_CONNECTABLE);
+    CASE_RETURN_TEXT(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+    default:
+      return "unknown scan mode";
+  }
+}
+
+const char *BtStatusText(const bt_status_t status) {
+  switch (status) {
+    CASE_RETURN_TEXT(BT_STATUS_SUCCESS);
+    CASE_RETURN_TEXT(BT_STATUS_FAIL);
+    CASE_RETURN_TEXT(BT_STATUS_NOT_READY);
+    CASE_RETURN_TEXT(BT_STATUS_NOMEM);
+    CASE_RETURN_TEXT(BT_STATUS_DONE);
+    CASE_RETURN_TEXT(BT_STATUS_BUSY);
+    CASE_RETURN_TEXT(BT_STATUS_UNSUPPORTED);
+    CASE_RETURN_TEXT(BT_STATUS_PARM_INVALID);
+    CASE_RETURN_TEXT(BT_STATUS_UNHANDLED);
+    CASE_RETURN_TEXT(BT_STATUS_AUTH_FAILURE);
+    CASE_RETURN_TEXT(BT_STATUS_RMT_DEV_DOWN);
+    CASE_RETURN_TEXT(BT_STATUS_AUTH_REJECTED);
+    default:
+      return "unknown status code";
+  }
+}
+
+const char *BtPropertyText(const bt_property_type_t prop) {
+  switch (prop) {
+    CASE_RETURN_TEXT(BT_PROPERTY_BDNAME);
+    CASE_RETURN_TEXT(BT_PROPERTY_BDADDR);
+    CASE_RETURN_TEXT(BT_PROPERTY_UUIDS);
+    CASE_RETURN_TEXT(BT_PROPERTY_CLASS_OF_DEVICE);
+    CASE_RETURN_TEXT(BT_PROPERTY_TYPE_OF_DEVICE);
+    CASE_RETURN_TEXT(BT_PROPERTY_SERVICE_RECORD);
+    CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_SCAN_MODE);
+    CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_BONDED_DEVICES);
+    CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT);
+    CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_FRIENDLY_NAME);
+    CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_RSSI);
+    CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_VERSION_INFO);
+    CASE_RETURN_TEXT(BT_PROPERTY_LOCAL_LE_FEATURES);
+    CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP);
+    default:
+      return "Invalid property";
+  }
+}
+
+const char *BtEventText(const bt_cb_thread_evt evt) {
+  switch (evt) {
+    CASE_RETURN_TEXT(ASSOCIATE_JVM);
+    CASE_RETURN_TEXT(DISASSOCIATE_JVM);
+    default:
+      return "unknown state code";
+  }
+}
+
+const char *BtAclText(const bt_acl_state_t code) {
+  switch (code) {
+    CASE_RETURN_TEXT(BT_ACL_STATE_CONNECTED);
+    CASE_RETURN_TEXT(BT_ACL_STATE_DISCONNECTED);
+    default:
+      return "unknown ACL code";
+  }
+}
+
+std::string BtAddrString(const bt_bdaddr_t *addr) {
+  char buffer[20];
+  snprintf(buffer, sizeof(buffer), "%02X:%02X:%02X:%02X:%02X:%02X",
+           addr->address[0], addr->address[1], addr->address[2],
+           addr->address[3], addr->address[4], addr->address[5]);
+  return std::string(buffer);
+}
diff --git a/service/logging_helpers.h b/service/logging_helpers.h
new file mode 100644 (file)
index 0000000..6baafa8
--- /dev/null
@@ -0,0 +1,45 @@
+//
+//  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 <string.h>
+
+#include <string>
+
+#include "hardware/bluetooth.h"
+#include "hardware/bt_av.h"
+#include "hardware/bt_gatt_types.h"
+
+const char *BtAvConnectionStateText(const btav_connection_state_t state);
+
+const char *BtAvAudioStateText(const btav_audio_state_t state);
+
+const char *BtTransportText(const btgatt_transport_t t);
+
+const char *BtStateText(const bt_state_t state);
+
+const char *BtScanModeText(const bt_scan_mode_t mode);
+
+const char *BtStatusText(const bt_status_t status);
+
+const char *BtPropertyText(const bt_property_type_t prop);
+
+const char *BtEventText(const bt_cb_thread_evt evt);
+
+const char *BtAclText(const bt_acl_state_t state);
+
+// TODO(icoolidge): Address object.
+std::string BtAddrString(const bt_bdaddr_t *addr);
diff --git a/service/main.cpp b/service/main.cpp
new file mode 100644 (file)
index 0000000..93eb25f
--- /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/at_exit.h>
+#include <base/command_line.h>
+#include <base/files/scoped_file.h>
+
+// For system properties
+// TODO(icoolidge): abstraction or non-cutils stub.
+#if !defined(OS_GENERIC)
+#include <cutils/properties.h>
+#endif  // !defined(OS_GENERIC)
+
+#include "service/daemon.h"
+#include "service/switches.h"
+
+namespace {
+
+// TODO(armansito): None of these should be hardcoded here. Instead, pass these
+// via commandline.
+const char kDisableProperty[] = "persist.bluetooth.disable";
+
+}  // namespace
+
+int main(int argc, char *argv[]) {
+  base::AtExitManager exit_manager;
+  base::CommandLine::Init(argc, argv);
+
+  logging::LoggingSettings log_settings;
+  if (!logging::InitLogging(log_settings)) {
+    LOG(ERROR) << "Failed to set up logging";
+    return EXIT_FAILURE;
+  }
+
+  // TODO(armansito): Initialize base/logging. By default it will dump to stdout
+  // but we might want to change that based on a command-line switch. Figure out
+  // how to route the logging to Android's syslog. Once that's done, we won't
+  // need to use osi/include/log.h anymore.
+
+  // TODO(armansito): Register exit-time clean-up handlers for the IPC sockets.
+  // Register signal handlers.
+  auto command_line = base::CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(bluetooth::switches::kHelpLong) ||
+      command_line->HasSwitch(bluetooth::switches::kHelpShort)) {
+    LOG(INFO) << bluetooth::switches::kHelpMessage;
+    return EXIT_SUCCESS;
+  }
+
+#if !defined(OS_GENERIC)
+  // TODO(armansito): Remove Chromecast specific property out of here. This
+  // should just be obtained from global config.
+  char disable_value[PROPERTY_VALUE_MAX];
+  int status = property_get(kDisableProperty, disable_value, nullptr);
+  if (status && !strcmp(disable_value, "1")) {
+    LOG(INFO) << "service disabled";
+    return EXIT_SUCCESS;
+  }
+#endif  // !defined(OS_GENERIC)
+
+  if (!bluetooth::Daemon::Initialize()) {
+    LOG(ERROR) << "Failed to initialize Daemon";
+    return EXIT_FAILURE;
+  }
+
+  // Start the main event loop.
+  bluetooth::Daemon::Get()->StartMainLoop();
+
+  // The main message loop has exited; clean up the Daemon.
+  bluetooth::Daemon::Get()->ShutDown();
+
+  return EXIT_SUCCESS;
+}
diff --git a/service/settings.cpp b/service/settings.cpp
new file mode 100644 (file)
index 0000000..ee48437
--- /dev/null
@@ -0,0 +1,86 @@
+//
+//  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 "service/settings.h"
+
+#include <base/base_switches.h>
+#include <base/command_line.h>
+#include <base/logging.h>
+
+#include "service/switches.h"
+
+namespace bluetooth {
+
+Settings::Settings()
+    : initialized_(false) {
+}
+
+Settings::~Settings() {
+}
+
+bool Settings::Init() {
+  CHECK(!initialized_);
+  auto command_line = base::CommandLine::ForCurrentProcess();
+  const auto& switches = command_line->GetSwitches();
+
+  for (const auto& iter : switches) {
+    if (iter.first == switches::kCreateIPCSocketPath) {
+      // kCreateIPCSocketPath: An optional argument that initializes an IPC
+      // socket path for IPC.
+      base::FilePath path(iter.second);
+      if (path.empty() || path.EndsWithSeparator()) {
+        LOG(ERROR) << "Invalid IPC create socket path";
+        return false;
+      }
+
+      create_ipc_socket_path_ = path;
+    } else if (iter.first == switches::kAndroidIPCSocketSuffix) {
+      // kAndroidIPCSocketSuffix: An optional argument used to express
+      // a socket that Android init created for us. We bind to this.
+      const std::string& suffix = iter.second;
+      if (suffix.empty()) {
+        LOG(ERROR) << "Invalid Android socket suffix";
+        return false;
+      }
+
+      android_ipc_socket_suffix_ = suffix;
+    }
+    // Check for libbase logging switches. These get processed by
+    // logging::InitLogging directly.
+    else if (iter.first != ::switches::kV) {
+      LOG(ERROR) << "Unexpected command-line switches found";
+      return false;
+    }
+  }
+
+  // Two IPC methods/paths were provided.
+  if (!android_ipc_socket_suffix_.empty() &&
+      !create_ipc_socket_path_.empty()) {
+    LOG(ERROR) << "Too many IPC methods provided";
+    return false;
+  }
+
+  // The daemon has no arguments
+  if (command_line->GetArgs().size()) {
+    LOG(ERROR) << "Unexpected command-line arguments found";
+    return false;
+  }
+
+  initialized_ = true;
+  return true;
+}
+
+}  // namespace bluetooth
diff --git a/service/settings.h b/service/settings.h
new file mode 100644 (file)
index 0000000..4c4ea4f
--- /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.
+//
+
+#pragma once
+
+#include <string>
+
+#include <base/files/file_path.h>
+#include <base/macros.h>
+
+namespace bluetooth {
+
+// The Settings class stores global runtime configurations, such as IPC domain
+// namespace, configuration file locations, and other system properties and
+// flags.
+class Settings {
+ public:
+  // Constant for the "--help" command-line switches.
+  static const char kHelp[];
+
+  Settings();
+  ~Settings();
+
+  // TODO(armansito): Write an instance method for storing things into a file.
+
+  // Initializes the Settings object. This reads the command-line options for
+  // the current process (which must have been initialized using
+  // base::CommandLine) and sets up the initial global settings. Returns false
+  // if there is an error, e.g. if the parameters/switches are malformed.
+  bool Init();
+
+  // If Android init created a server socket for the daemon,
+  // we can retrieve it through this suffix.
+  const std::string& android_ipc_socket_suffix() const {
+    return android_ipc_socket_suffix_;
+  }
+
+  // Path to create a Unix domain socket server for Bluetooth IPC.
+  const base::FilePath& create_ipc_socket_path() const {
+    return create_ipc_socket_path_;
+  }
+
+  // Returns true if domain-socket based IPC should be used. If false, then
+  // Binder IPC must be used.
+  inline bool UseSocketIPC() const {
+    return !android_ipc_socket_suffix().empty() ||
+        !create_ipc_socket_path().empty();
+  }
+
+ private:
+  bool initialized_;
+  std::string android_ipc_socket_suffix_;
+  base::FilePath create_ipc_socket_path_;
+
+  DISALLOW_COPY_AND_ASSIGN(Settings);
+};
+
+}  // namespace bluetooth
diff --git a/service/switches.h b/service/switches.h
new file mode 100644 (file)
index 0000000..af23398
--- /dev/null
@@ -0,0 +1,42 @@
+//
+//  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 <string>
+
+namespace bluetooth {
+namespace switches {
+
+// List of command-line switches used by the daemon.
+const char kHelpLong[] = "help";
+const char kHelpShort[] = "h";
+const char kAndroidIPCSocketSuffix[] = "android-ipc-socket-suffix";
+const char kCreateIPCSocketPath[] = "create-ipc-socket";
+
+const char kHelpMessage[] =
+    "\nBluetooth System Service\n"
+    "\n"
+    "Usage:\n"
+    "\t--help,-h\t\t\tShow this help message\n"
+    "\t--android-ipc-socket-suffix\tSuffix of socket created by Android init. "
+    "Mutually exclusive with --create-ipc-socket.\n"
+    "\t--create-ipc-socket\t\tSocket path created for Unix domain socket based "
+    "IPC. Mutually exclusive with --android-ipc-socket-suffix.\n"
+    "\t--v\t\t\t\tLog verbosity level (e.g. -v=1)\n";
+
+}  // namespace switches
+}  // namespace bluetooth
diff --git a/service/test/adapter_unittest.cpp b/service/test/adapter_unittest.cpp
new file mode 100644 (file)
index 0000000..09d2cfa
--- /dev/null
@@ -0,0 +1,215 @@
+//
+//  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/macros.h>
+#include <gtest/gtest.h>
+
+#include "service/adapter.h"
+#include "service/hal/fake_bluetooth_interface.h"
+
+namespace bluetooth {
+namespace {
+
+class AdapterTest : public ::testing::Test {
+ public:
+  AdapterTest() = default;
+  ~AdapterTest() override = default;
+
+  void SetUp() override {
+    fake_hal_manager_ = hal::FakeBluetoothInterface::GetManager();
+    fake_hal_iface_ = new hal::FakeBluetoothInterface();
+    hal::BluetoothInterface::InitializeForTesting(fake_hal_iface_);
+
+    adapter_.reset(new Adapter());
+  }
+
+  void TearDown() override {
+    adapter_.reset();
+    hal::BluetoothInterface::CleanUp();
+  }
+
+ protected:
+  hal::FakeBluetoothInterface* fake_hal_iface_;
+  hal::FakeBluetoothInterface::Manager* fake_hal_manager_;
+  std::unique_ptr<Adapter> adapter_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AdapterTest);
+};
+
+class TestObserver final : public bluetooth::Adapter::Observer {
+ public:
+  TestObserver(bluetooth::Adapter* adapter)
+      : adapter_(adapter),
+        prev_state_(bluetooth::ADAPTER_STATE_INVALID),
+        cur_state_(bluetooth::ADAPTER_STATE_INVALID) {
+    CHECK(adapter_);
+    adapter_->AddObserver(this);
+  }
+
+  ~TestObserver() override {
+    adapter_->RemoveObserver(this);
+  }
+
+  bluetooth::AdapterState prev_state() const { return prev_state_; }
+  bluetooth::AdapterState cur_state() const { return cur_state_; }
+
+  // bluetooth::Adapter::Observer override:
+  void OnAdapterStateChanged(bluetooth::Adapter* adapter,
+                             bluetooth::AdapterState prev_state,
+                             bluetooth::AdapterState new_state) {
+    ASSERT_EQ(adapter_, adapter);
+    prev_state_ = prev_state;
+    cur_state_ = new_state;
+  }
+
+ private:
+  bluetooth::Adapter* adapter_;
+  bluetooth::AdapterState prev_state_, cur_state_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestObserver);
+};
+
+TEST_F(AdapterTest, IsEnabled) {
+  EXPECT_FALSE(adapter_->IsEnabled());
+
+  fake_hal_iface_->NotifyAdapterStateChanged(BT_STATE_ON);
+  EXPECT_TRUE(adapter_->IsEnabled());
+
+  fake_hal_iface_->NotifyAdapterStateChanged(BT_STATE_OFF);
+  EXPECT_FALSE(adapter_->IsEnabled());
+}
+
+TEST_F(AdapterTest, Enable) {
+  TestObserver observer(adapter_.get());
+
+  EXPECT_FALSE(adapter_->IsEnabled());
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, adapter_->GetState());
+
+  // Enable fails at HAL level
+  EXPECT_FALSE(adapter_->Enable());
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, adapter_->GetState());
+
+  // Enable success
+  fake_hal_manager_->enable_succeed = true;
+  EXPECT_TRUE(adapter_->Enable());
+
+  // Should have received a state update.
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, observer.prev_state());
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_ON, observer.cur_state());
+
+  // Enable fails because not disabled
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_ON, adapter_->GetState());
+  EXPECT_FALSE(adapter_->Enable());
+
+  // Adapter state updates properly
+  fake_hal_iface_->NotifyAdapterStateChanged(BT_STATE_ON);
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, adapter_->GetState());
+
+  // Should have received a state update.
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_ON, observer.prev_state());
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, observer.cur_state());
+
+  // Enable fails because already enabled
+  EXPECT_FALSE(adapter_->Enable());
+}
+
+TEST_F(AdapterTest, Disable) {
+  TestObserver observer(adapter_.get());
+
+  fake_hal_manager_->disable_succeed = true;
+  EXPECT_FALSE(adapter_->IsEnabled());
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, adapter_->GetState());
+
+  // Disable fails because already disabled
+  EXPECT_FALSE(adapter_->Disable());
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, adapter_->GetState());
+
+  // Disable success
+  fake_hal_iface_->NotifyAdapterStateChanged(BT_STATE_ON);
+
+  // Should have received a state update.
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, observer.prev_state());
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, observer.cur_state());
+
+  EXPECT_TRUE(adapter_->Disable());
+
+  // Should have received a state update.
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, observer.prev_state());
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_OFF, observer.cur_state());
+
+  // Disable fails because not enabled
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_OFF, adapter_->GetState());
+  EXPECT_FALSE(adapter_->Disable());
+
+  fake_hal_iface_->NotifyAdapterStateChanged(BT_STATE_ON);
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, adapter_->GetState());
+
+  // Should have received a state update.
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_OFF, observer.prev_state());
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, observer.cur_state());
+
+  // Disable fails at HAL level
+  fake_hal_manager_->disable_succeed = false;
+  EXPECT_FALSE(adapter_->Disable());
+
+  // Should have received a state update. In this case we will receive two
+  // updates: one going from OFF to TURNING_OFF, and one going from TURNING_OFF
+  // back to ON since we failed to initiate the disable operation.
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_OFF, observer.prev_state());
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, observer.cur_state());
+
+  // Update state to OFF. Should receive a state update.
+  fake_hal_iface_->NotifyAdapterStateChanged(BT_STATE_OFF);
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, observer.prev_state());
+  EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, observer.cur_state());
+}
+
+TEST_F(AdapterTest, GetName) {
+  EXPECT_EQ(bluetooth::Adapter::kDefaultName, adapter_->GetName());
+
+  const char kTestAdapterName[] = "Test Adapter Name";
+
+  fake_hal_iface_->NotifyAdapterNamePropertyChanged(kTestAdapterName);
+  EXPECT_EQ(kTestAdapterName, adapter_->GetName());
+}
+
+TEST_F(AdapterTest, SetName) {
+  bt_bdname_t hal_name;
+
+  // Name too large.
+  EXPECT_FALSE(adapter_->SetName(std::string(sizeof(hal_name.name), 'a')));
+
+  // Valid length.
+  EXPECT_FALSE(adapter_->SetName("Test Name"));
+  fake_hal_manager_->set_property_succeed = true;
+  EXPECT_TRUE(adapter_->SetName("Test Name"));
+}
+
+TEST_F(AdapterTest, GetAddress) {
+  EXPECT_EQ(bluetooth::Adapter::kDefaultAddress, adapter_->GetAddress());
+
+  const bt_bdaddr_t kTestAdapterInput = {
+    { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc }
+  };
+  const char kTestAdapterAddressOutput[] = "12:34:56:78:9A:BC";
+
+  fake_hal_iface_->NotifyAdapterAddressPropertyChanged(&kTestAdapterInput);
+  EXPECT_EQ(kTestAdapterAddressOutput, adapter_->GetAddress());
+}
+
+}  // namespace
+}  // namespace bluetooth
diff --git a/service/test/fake_hal_util.cpp b/service/test/fake_hal_util.cpp
new file mode 100644 (file)
index 0000000..d909ad2
--- /dev/null
@@ -0,0 +1,29 @@
+//
+//  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.
+//
+
+extern "C" {
+
+// TODO(armansito): This provides a fake implementation of the function defined
+// in btcore/include/hal_util.h. We have to provide this to prevent having to
+// pull in libbtcore and transitively libhardware as dependencies for the unit
+// tests. Instead of doing it this way, however, we should instead provide a C++
+// class abstraction for this (and all other btif interfaces) that we can mock
+// for testing.
+int hal_util_load_bt_library(const struct hw_module_t** module) {
+  return -1;
+}
+
+}  // extern "C"
diff --git a/service/test/ipc_unix_unittest.cpp b/service/test/ipc_unix_unittest.cpp
new file mode 100644 (file)
index 0000000..600e9b6
--- /dev/null
@@ -0,0 +1,202 @@
+//
+//  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 <memory>
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <base/at_exit.h>
+#include <base/command_line.h>
+#include <base/files/scoped_file.h>
+#include <base/macros.h>
+#include <base/strings/stringprintf.h>
+#include <gtest/gtest.h>
+
+#include "service/adapter.h"
+#include "service/hal/fake_bluetooth_interface.h"
+#include "service/ipc/ipc_manager.h"
+#include "service/settings.h"
+#include "service/test/mock_daemon.h"
+
+
+namespace {
+
+using testing::Return;
+
+const char kTestSocketPath[] = "test_socket_path";
+
+class IPCUnixTest : public ::testing::Test {
+ public:
+  IPCUnixTest() = default;
+  ~IPCUnixTest() override = default;
+
+  void SetUp() override {
+    SetUpCommandLine();
+    ASSERT_TRUE(settings_.Init());
+
+    auto mock_daemon = new bluetooth::testing::MockDaemon();
+
+    ON_CALL(*mock_daemon, GetSettings()).WillByDefault(Return(&settings_));
+    ON_CALL(*mock_daemon, GetMessageLoop())
+        .WillByDefault(Return(&message_loop_));
+
+    bluetooth::Daemon::InitializeForTesting(mock_daemon);
+    bluetooth::hal::BluetoothInterface::InitializeForTesting(
+        new bluetooth::hal::FakeBluetoothInterface());
+
+    adapter_.reset(new bluetooth::Adapter());
+    ipc_manager_.reset(new ipc::IPCManager(adapter_.get()));
+  }
+
+  void TearDown() override {
+    client_fd_.reset();
+    ipc_manager_.reset();
+    adapter_.reset();
+    bluetooth::hal::BluetoothInterface::CleanUp();
+    bluetooth::Daemon::ShutDown();
+    base::CommandLine::Reset();
+  }
+
+  virtual void SetUpCommandLine() {
+    std::string ipc_socket_arg =
+        base::StringPrintf("--create-ipc-socket=%s", kTestSocketPath);
+    const base::CommandLine::CharType* argv[] = {
+      "program", ipc_socket_arg.c_str(),
+    };
+    base::CommandLine::Init(arraysize(argv), argv);
+  }
+
+  void ConnectToTestSocket() {
+    client_fd_.reset(socket(PF_UNIX, SOCK_SEQPACKET, 0));
+    ASSERT_TRUE(client_fd_.is_valid());
+
+    struct sockaddr_un address;
+    memset(&address, 0, sizeof(address));
+    address.sun_family = AF_UNIX;
+    strncpy(address.sun_path, kTestSocketPath, sizeof(address.sun_path) - 1);
+
+    int status = connect(client_fd_.get(), (struct sockaddr *)&address,
+                         sizeof(address));
+    EXPECT_EQ(0, status);
+  }
+
+ protected:
+  base::AtExitManager exit_manager_;
+  base::MessageLoop message_loop_;
+  bluetooth::Settings settings_;
+
+  std::unique_ptr<bluetooth::Adapter> adapter_;
+  std::unique_ptr<ipc::IPCManager> ipc_manager_;
+  base::ScopedFD client_fd_;
+
+  DISALLOW_COPY_AND_ASSIGN(IPCUnixTest);
+};
+
+class IPCUnixTestDisabled : public IPCUnixTest {
+ public:
+  IPCUnixTestDisabled() = default;
+  ~IPCUnixTestDisabled() override = default;
+
+  void SetUpCommandLine() override {
+    // Set up with no --ipc-socket-path
+    const base::CommandLine::CharType* argv[] = { "program" };
+    base::CommandLine::Init(arraysize(argv), argv);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(IPCUnixTestDisabled);
+};
+
+class TestDelegate : public ipc::IPCManager::Delegate,
+                     public base::SupportsWeakPtr<TestDelegate> {
+ public:
+  TestDelegate() : started_count_(0), stopped_count_(0) {
+  }
+
+  void OnIPCHandlerStarted(ipc::IPCManager::Type type) override {
+    ASSERT_EQ(ipc::IPCManager::TYPE_UNIX, type);
+    started_count_++;
+    base::MessageLoop::current()->Quit();
+  }
+
+  void OnIPCHandlerStopped(ipc::IPCManager::Type type) override {
+    ASSERT_EQ(ipc::IPCManager::TYPE_UNIX, type);
+    stopped_count_++;
+    base::MessageLoop::current()->Quit();
+  }
+
+  int started_count() const { return started_count_; }
+  int stopped_count() const { return stopped_count_; }
+
+ private:
+  int started_count_;
+  int stopped_count_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestDelegate);
+};
+
+TEST_F(IPCUnixTestDisabled, StartWithNoSocketPath) {
+  TestDelegate delegate;
+  EXPECT_FALSE(ipc_manager_->Start(ipc::IPCManager::TYPE_UNIX, &delegate));
+  EXPECT_FALSE(ipc_manager_->UnixStarted());
+  EXPECT_EQ(0, delegate.started_count());
+  EXPECT_EQ(0, delegate.stopped_count());
+}
+
+TEST_F(IPCUnixTest, BasicStartAndExit) {
+  TestDelegate delegate;
+  EXPECT_TRUE(ipc_manager_->Start(ipc::IPCManager::TYPE_UNIX, &delegate));
+  EXPECT_TRUE(ipc_manager_->UnixStarted());
+
+  // Run the message loop. We will stop the loop when we receive a delegate
+  // event.
+  message_loop_.Run();
+
+  // We should have received the started event.
+  EXPECT_EQ(1, delegate.started_count());
+  EXPECT_EQ(0, delegate.stopped_count());
+
+  // At this point the thread is blocking on accept and listening for incoming
+  // connections. TearDown should gracefully clean up the thread and the test
+  // should succeed without hanging.
+  ipc_manager_.reset();
+  message_loop_.Run();
+  EXPECT_EQ(1, delegate.stopped_count());
+}
+
+TEST_F(IPCUnixTest, BasicStartAndConnect) {
+  TestDelegate delegate;
+  EXPECT_TRUE(ipc_manager_->Start(ipc::IPCManager::TYPE_UNIX, &delegate));
+  EXPECT_TRUE(ipc_manager_->UnixStarted());
+
+  // Run the message loop. We will stop the loop when we receive a delegate
+  // event.
+  message_loop_.Run();
+
+  // We should have received the started event.
+  EXPECT_EQ(1, delegate.started_count());
+  EXPECT_EQ(0, delegate.stopped_count());
+
+  // IPC successfully started. Now attempt to connect to the socket.
+  ConnectToTestSocket();
+
+  // TODO(armansito): Test that the IPC event loop shuts down cleanly while a
+  // client is connected. Currently this will fail and the fix is to use
+  // MessageLoopForIO rather than a custom event loop.
+}
+
+}  // namespace
diff --git a/service/test/mock_daemon.h b/service/test/mock_daemon.h
new file mode 100644 (file)
index 0000000..a5dd974
--- /dev/null
@@ -0,0 +1,41 @@
+//
+//  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 <gmock/gmock.h>
+
+#include "service/daemon.h"
+
+namespace bluetooth {
+namespace testing {
+
+class MockDaemon : public Daemon {
+ public:
+  MockDaemon() = default;
+  ~MockDaemon() override = default;
+
+  MOCK_CONST_METHOD0(GetSettings, Settings*());
+  MOCK_CONST_METHOD0(GetMessageLoop, base::MessageLoop*());
+  MOCK_METHOD0(StartMainLoop, void());
+  MOCK_METHOD0(Init, bool());
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockDaemon);
+};
+
+}  // namespace testing
+}  // namespace bluetooth
diff --git a/service/test/settings_unittest.cpp b/service/test/settings_unittest.cpp
new file mode 100644 (file)
index 0000000..c06861c
--- /dev/null
@@ -0,0 +1,108 @@
+//
+//  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/at_exit.h>
+#include <base/command_line.h>
+#include <base/macros.h>
+#include <gtest/gtest.h>
+
+#include "service/settings.h"
+#include "service/switches.h"
+
+using bluetooth::Settings;
+using namespace bluetooth::switches;
+
+namespace {
+
+class SettingsTest : public ::testing::Test {
+ public:
+  SettingsTest() = default;
+
+  void TearDown() override {
+    base::CommandLine::Reset();
+  }
+
+ protected:
+  base::AtExitManager exit_manager_;
+  Settings settings_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SettingsTest);
+};
+
+TEST_F(SettingsTest, EmptyCommandLine) {
+  const base::CommandLine::CharType* argv[] = { "program" };
+  base::CommandLine::Init(arraysize(argv), argv);
+  EXPECT_TRUE(settings_.Init());
+}
+
+TEST_F(SettingsTest, UnexpectedSwitches1) {
+  const base::CommandLine::CharType* argv[] = {
+    "program", "--create-ipc-socket=foobar", "--foobarbaz"
+  };
+  base::CommandLine::Init(arraysize(argv), argv);
+  EXPECT_FALSE(settings_.Init());
+}
+
+TEST_F(SettingsTest, UnexpectedSwitches2) {
+  const base::CommandLine::CharType* argv[] = {
+    "program", "--foobarbaz"
+  };
+  base::CommandLine::Init(arraysize(argv), argv);
+  EXPECT_FALSE(settings_.Init());
+}
+
+TEST_F(SettingsTest, UnexpectedArguments1) {
+  const base::CommandLine::CharType* argv[] = {
+    "program", "foobarbaz"
+  };
+  base::CommandLine::Init(arraysize(argv), argv);
+  EXPECT_FALSE(settings_.Init());
+}
+
+TEST_F(SettingsTest, UnexpectedArguments2) {
+  const base::CommandLine::CharType* argv[] = {
+    "program", "--create-ipc-socket=foobar", "foobarbaz"
+  };
+  base::CommandLine::Init(arraysize(argv), argv);
+  EXPECT_FALSE(settings_.Init());
+}
+
+TEST_F(SettingsTest, TooManyIpcOptions) {
+  const base::CommandLine::CharType* argv[] = {
+      "program", "--create-ipc-socket=foobar",
+      "--android-ipc-socket-suffix=foobar"};
+  base::CommandLine::Init(arraysize(argv), argv);
+  EXPECT_FALSE(settings_.Init());
+}
+
+TEST_F(SettingsTest, GoodArgumentsCreateIpc) {
+  const base::CommandLine::CharType* argv[] = {
+    "program", "--create-ipc-socket=foobar"
+  };
+  base::CommandLine::Init(arraysize(argv), argv);
+  EXPECT_TRUE(settings_.Init());
+}
+
+TEST_F(SettingsTest, GoodArgumentsAndroidIpc) {
+  const base::CommandLine::CharType* argv[] = {
+    "program", "--android-ipc-socket-suffix=foobar"
+  };
+  base::CommandLine::Init(arraysize(argv), argv);
+  EXPECT_TRUE(settings_.Init());
+}
+
+}  // namespace
diff --git a/service/test/stub_ipc_handler_binder.cpp b/service/test/stub_ipc_handler_binder.cpp
new file mode 100644 (file)
index 0000000..6f5a13d
--- /dev/null
@@ -0,0 +1,49 @@
+//
+//  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 "service/ipc/binder/ipc_handler_binder.h"
+
+// TODO(armansito): This is a crappy workaround to link IPCHandlerBinder into
+// host-native unit tests. We should instead figure out a way to build Binder
+// unit tests for host.
+
+namespace ipc {
+
+IPCHandlerBinder::IPCHandlerBinder(
+    bluetooth::Adapter* adapter,
+    IPCManager::Delegate* delegate)
+    : IPCHandler(adapter, delegate) {
+  // Stub
+}
+
+IPCHandlerBinder::~IPCHandlerBinder() {
+  // Stub
+}
+
+bool IPCHandlerBinder::Run() {
+  // Stub
+  return false;
+}
+
+void IPCHandlerBinder::Stop() {
+  // Stub
+}
+
+void IPCHandlerBinder::NotifyStarted() {
+  // Stub
+}
+
+}  // namespace
diff --git a/service/test/uuid_unittest.cpp b/service/test/uuid_unittest.cpp
new file mode 100644 (file)
index 0000000..6f828c9
--- /dev/null
@@ -0,0 +1,123 @@
+//
+//  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 <algorithm>
+#include <array>
+#include <stdint.h>
+
+#include <gtest/gtest.h>
+
+#include "service/uuid.h"
+
+using namespace bluetooth;
+
+namespace {
+
+const std::array<uint8_t, UUID::kUUID128Octets> kBtSigBaseUUID = {
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+      0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb, }
+};
+
+}  // namespace
+
+// Verify that an uninitialized UUID is equal
+// To the BT SIG Base UUID.
+TEST(UUIDTest, DefaultUUID) {
+  UUID uuid;
+  ASSERT_TRUE(uuid.GetFullBigEndian() == kBtSigBaseUUID);
+}
+
+// Verify that we initialize a 16-bit UUID in a
+// way consistent with how we read it.
+TEST(UUIDTest, Init16Bit) {
+  auto my_uuid_16 = kBtSigBaseUUID;
+  my_uuid_16[2] = 0xde;
+  my_uuid_16[3] = 0xad;
+  UUID uuid(UUID::UUID16Bit({{ 0xde, 0xad }}));
+  ASSERT_TRUE(uuid.GetFullBigEndian() == my_uuid_16);
+}
+
+// Verify that we initialize a 16-bit UUID in a
+// way consistent with how we read it.
+TEST(UUIDTest, Init16BitString) {
+  auto my_uuid_16 = kBtSigBaseUUID;
+  my_uuid_16[2] = 0xde;
+  my_uuid_16[3] = 0xad;
+  UUID uuid("dead");
+  ASSERT_TRUE(uuid.GetFullBigEndian() == my_uuid_16);
+}
+
+
+// Verify that we initialize a 32-bit UUID in a
+// way consistent with how we read it.
+TEST(UUIDTest, Init32Bit) {
+  auto my_uuid_32 = kBtSigBaseUUID;
+  my_uuid_32[0] = 0xde;
+  my_uuid_32[1] = 0xad;
+  my_uuid_32[2] = 0xbe;
+  my_uuid_32[3] = 0xef;
+  UUID uuid(UUID::UUID32Bit({{ 0xde, 0xad, 0xbe, 0xef }}));
+  ASSERT_TRUE(uuid.GetFullBigEndian() == my_uuid_32);
+}
+
+// Verify correct reading of a 32-bit UUID initialized from string.
+TEST(UUIDTest, Init32BitString) {
+  auto my_uuid_32 = kBtSigBaseUUID;
+  my_uuid_32[0] = 0xde;
+  my_uuid_32[1] = 0xad;
+  my_uuid_32[2] = 0xbe;
+  my_uuid_32[3] = 0xef;
+  UUID uuid("deadbeef");
+  ASSERT_TRUE(uuid.GetFullBigEndian() == my_uuid_32);
+}
+
+// Verify that we initialize a 128-bit UUID in a
+// way consistent with how we read it.
+TEST(UUIDTest, Init128Bit) {
+  auto my_uuid_128 = kBtSigBaseUUID;
+  for (int i = 0; i < static_cast<int>(my_uuid_128.size()); ++i) {
+    my_uuid_128[i] = i;
+  }
+
+  UUID uuid(my_uuid_128);
+  ASSERT_TRUE(uuid.GetFullBigEndian() == my_uuid_128);
+}
+
+// Verify that we initialize a 128-bit UUID in a
+// way consistent with how we read it as LE.
+TEST(UUIDTest, Init128BitLittleEndian) {
+  auto my_uuid_128 = kBtSigBaseUUID;
+  for (int i = 0; i < static_cast<int>(my_uuid_128.size()); ++i) {
+    my_uuid_128[i] = i;
+  }
+
+  UUID uuid(my_uuid_128);
+  std::reverse(my_uuid_128.begin(), my_uuid_128.end());
+  ASSERT_TRUE(uuid.GetFullLittleEndian() == my_uuid_128);
+}
+
+// Verify that we initialize a 128-bit UUID in a
+// way consistent with how we read it.
+TEST(UUIDTest, Init128BitString) {
+  auto my_uuid_128 = kBtSigBaseUUID;
+  for (int i = 0; i < static_cast<int>(my_uuid_128.size()); ++i) {
+    my_uuid_128[i] = i;
+  }
+
+  std::string uuid_text("000102030405060708090A0B0C0D0E0F");
+  ASSERT_TRUE(uuid_text.size() == (16 * 2));
+  UUID uuid(uuid_text);
+  ASSERT_TRUE(uuid.GetFullBigEndian() == my_uuid_128);
+}
diff --git a/service/util/atomic_string.cpp b/service/util/atomic_string.cpp
new file mode 100644 (file)
index 0000000..fe12d7f
--- /dev/null
@@ -0,0 +1,36 @@
+//
+//  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 "service/util/atomic_string.h"
+
+namespace util {
+
+AtomicString::AtomicString(const std::string& str)
+    : str_(str) {
+}
+
+std::string AtomicString::Get() const {
+  std::mutex* mutex = const_cast<std::mutex*>(&lock_);
+  std::lock_guard<std::mutex> lock(*mutex);
+  return str_;
+}
+
+void AtomicString::Set(const std::string& str) {
+  std::lock_guard<std::mutex> lock(lock_);
+  str_ = str;
+}
+
+}  // namespace util
diff --git a/service/util/atomic_string.h b/service/util/atomic_string.h
new file mode 100644 (file)
index 0000000..90e911f
--- /dev/null
@@ -0,0 +1,40 @@
+//
+//  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 <mutex>
+#include <string>
+
+#include <base/macros.h>
+
+namespace util {
+
+// A simple atomic container class for std::string.
+class AtomicString final {
+ public:
+  AtomicString(const std::string& str);
+  ~AtomicString() = default;
+
+  std::string Get() const;
+  void Set(const std::string& str);
+
+ private:
+  std::mutex lock_;
+  std::string str_;
+
+  DISALLOW_COPY_AND_ASSIGN(AtomicString);
+};
+
+}  // namespace util
diff --git a/service/uuid.cpp b/service/uuid.cpp
new file mode 100644 (file)
index 0000000..74009c4
--- /dev/null
@@ -0,0 +1,87 @@
+//
+//  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 "service/uuid.h"
+
+#include <algorithm>
+#include <array>
+#include <stack>
+#include <string>
+
+namespace bluetooth {
+
+void UUID::InitializeDefault() {
+  // Initialize to base bluetooth UUID.
+  id_ = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+         0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb}};
+}
+
+UUID::UUID() {
+  InitializeDefault();
+}
+
+UUID::UUID(const std::string& uuid) {
+  InitializeDefault();
+  const int start_index = uuid.size() == 4 ? 2 : 0;
+  const size_t copy_size = std::min(id_.size(), uuid.size() / 2);
+  for (size_t i = 0; i < copy_size; ++i) {
+    std::string octet_text(uuid, i * 2, 2);
+    id_[start_index + i] = std::stoul(octet_text, 0, 16);
+  }
+}
+
+UUID::UUID(const bt_uuid_t& uuid) {
+  std::reverse_copy(uuid.uu, uuid.uu + sizeof(uuid.uu), id_.begin());
+}
+
+UUID::UUID(const UUID::UUID16Bit& uuid) {
+  InitializeDefault();
+  std::copy(uuid.begin(), uuid.end(), id_.begin() + kUUID16Octets);
+}
+
+UUID::UUID(const UUID::UUID32Bit& uuid) {
+  InitializeDefault();
+  std::copy(uuid.begin(), uuid.end(), id_.begin());
+}
+
+UUID::UUID(const UUID::UUID128Bit& uuid) : id_(uuid) {}
+
+const UUID::UUID128Bit UUID::GetFullBigEndian() const {
+  return id_;
+}
+
+const UUID::UUID128Bit UUID::GetFullLittleEndian() const {
+  UUID::UUID128Bit ret;
+  std::reverse_copy(id_.begin(), id_.end(), ret.begin());
+  return ret;
+}
+
+const bt_uuid_t UUID::GetBlueDroid() const {
+  bt_uuid_t ret;
+  std::reverse_copy(id_.begin(), id_.end(), ret.uu);
+  return ret;
+}
+
+bool UUID::operator<(const UUID& rhs) const {
+  return std::lexicographical_compare(id_.begin(), id_.end(), rhs.id_.begin(),
+                                      rhs.id_.end());
+}
+
+bool UUID::operator==(const UUID& rhs) const {
+  return std::equal(id_.begin(), id_.end(), rhs.id_.begin());
+}
+
+}  // namespace bluetooth
diff --git a/service/uuid.h b/service/uuid.h
new file mode 100644 (file)
index 0000000..929294f
--- /dev/null
@@ -0,0 +1,70 @@
+//
+//  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 <array>
+#include <string>
+
+#include "hardware/bluetooth.h"
+
+namespace bluetooth {
+
+class UUID {
+ public:
+  enum Type {
+    kUUID128Octets = 16,
+    kUUID32Octets = 4,
+    kUUID16Octets = 2,
+  };
+
+  typedef std::array<uint8_t, UUID::kUUID16Octets> UUID16Bit;
+  typedef std::array<uint8_t, UUID::kUUID32Octets> UUID32Bit;
+  typedef std::array<uint8_t, UUID::kUUID128Octets> UUID128Bit;
+
+  // Construct a Bluetooth 'base' UUID.
+  UUID();
+
+  // BlueDroid constructor.
+  explicit UUID(const bt_uuid_t& uuid);
+
+  // String constructor. Only hex ASCII accepted.
+  explicit UUID(const std::string& uuid);
+
+  // std::array variants constructors.
+  explicit UUID(const UUID::UUID16Bit& uuid);
+  explicit UUID(const UUID::UUID32Bit& uuid);
+  explicit UUID(const UUID::UUID128Bit& uuid);
+
+  // Provide the full network-byte-ordered blob.
+  const UUID128Bit GetFullBigEndian() const;
+
+  // Provide blob in Little endian (BlueDroid expects this).
+  const UUID128Bit GetFullLittleEndian() const;
+
+  // Helper for bluedroid LE type.
+  const bt_uuid_t GetBlueDroid() const;
+
+  bool operator<(const UUID& rhs) const;
+  bool operator==(const UUID& rhs) const;
+
+ private:
+  void InitializeDefault();
+  // Network-byte-ordered ID.
+  UUID128Bit id_;
+};
+
+}  // namespace bluetooth
diff --git a/stack/BUILD.gn b/stack/BUILD.gn
new file mode 100644 (file)
index 0000000..f8ea514
--- /dev/null
@@ -0,0 +1,169 @@
+#
+#  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.
+#
+
+static_library("stack") {
+  sources = [
+    "a2dp/a2d_api.c",
+    "a2dp/a2d_sbc.c",
+    "avrc/avrc_api.c",
+    "avrc/avrc_sdp.c",
+    "avrc/avrc_opt.c",
+    "avrc/avrc_bld_tg.c",
+    "avrc/avrc_bld_ct.c",
+    "avrc/avrc_pars_tg.c",
+    "avrc/avrc_pars_ct.c",
+    "avrc/avrc_utils.c",
+    "hid/hidh_api.c",
+    "hid/hidh_conn.c",
+    "bnep/bnep_main.c",
+    "bnep/bnep_utils.c",
+    "bnep/bnep_api.c",
+    "hcic/hciblecmds.c",
+    "hcic/hcicmds.c",
+    "btm/btm_ble.c",
+    "btm/btm_sec.c",
+    "btm/btm_inq.c",
+    "btm/btm_ble_addr.c",
+    "btm/btm_ble_bgconn.c",
+    "btm/btm_main.c",
+    "btm/btm_dev.c",
+    "btm/btm_ble_gap.c",
+    "btm/btm_ble_adv_filter.c",
+    "btm/btm_ble_multi_adv.c",
+    "btm/btm_ble_batchscan.c",
+    "btm/btm_ble_cont_energy.c",
+    "btm/btm_ble_privacy.c",
+    "btm/btm_acl.c",
+    "btm/btm_sco.c",
+    "btm/btm_pm.c",
+    "btm/btm_devctl.c",
+    "rfcomm/rfc_utils.c",
+    "rfcomm/port_rfc.c",
+    "rfcomm/rfc_l2cap_if.c",
+    "rfcomm/rfc_mx_fsm.c",
+    "rfcomm/port_utils.c",
+    "rfcomm/rfc_port_fsm.c",
+    "rfcomm/rfc_port_if.c",
+    "rfcomm/port_api.c",
+    "rfcomm/rfc_ts_frames.c",
+    "mcap/mca_dact.c",
+    "mcap/mca_dsm.c",
+    "mcap/mca_l2c.c",
+    "mcap/mca_main.c",
+    "mcap/mca_csm.c",
+    "mcap/mca_cact.c",
+    "mcap/mca_api.c",
+    "gatt/gatt_sr.c",
+    "gatt/gatt_cl.c",
+    "gatt/gatt_api.c",
+    "gatt/gatt_auth.c",
+    "gatt/gatt_utils.c",
+    "gatt/gatt_main.c",
+    "gatt/att_protocol.c",
+    "gatt/gatt_attr.c",
+    "gatt/gatt_db.c",
+    "avct/avct_api.c",
+    "avct/avct_l2c.c",
+    "avct/avct_lcb.c",
+    "avct/avct_ccb.c",
+    "avct/avct_lcb_act.c",
+    "smp/smp_main.c",
+    "smp/smp_l2c.c",
+    "smp/smp_cmac.c",
+    "smp/smp_utils.c",
+    "smp/smp_act.c",
+    "smp/smp_keys.c",
+    "smp/smp_api.c",
+    "smp/aes.c",
+    "smp/smp_br_main.c",
+    "smp/p_256_curvepara.c",
+    "smp/p_256_ecc_pp.c",
+    "smp/p_256_multprecision.c",
+    "avdt/avdt_ccb.c",
+    "avdt/avdt_scb_act.c",
+    "avdt/avdt_msg.c",
+    "avdt/avdt_ccb_act.c",
+    "avdt/avdt_api.c",
+    "avdt/avdt_scb.c",
+    "avdt/avdt_ad.c",
+    "avdt/avdt_l2c.c",
+    "sdp/sdp_server.c",
+    "sdp/sdp_main.c",
+    "sdp/sdp_db.c",
+    "sdp/sdp_utils.c",
+    "sdp/sdp_api.c",
+    "sdp/sdp_discovery.c",
+    "pan/pan_main.c",
+    "srvc/srvc_battery.c",
+    "srvc/srvc_battery_int.h",
+    "srvc/srvc_dis.c",
+    "srvc/srvc_dis_int.h",
+    "srvc/srvc_eng.c",
+    "srvc/srvc_eng_int.h",
+    "pan/pan_api.c",
+    "pan/pan_utils.c",
+    "btu/btu_hcif.c",
+    "btu/btu_init.c",
+    "btu/btu_task.c",
+    "l2cap/l2c_fcr.c",
+    "l2cap/l2c_ucd.c",
+    "l2cap/l2c_main.c",
+    "l2cap/l2c_api.c",
+    "l2cap/l2c_utils.c",
+    "l2cap/l2c_csm.c",
+    "l2cap/l2c_link.c",
+    "l2cap/l2c_ble.c",
+    "l2cap/l2cap_client.c",
+    "gap/gap_api.c",
+    "gap/gap_ble.c",
+    "gap/gap_conn.c",
+    "gap/gap_utils.c",
+  ]
+
+  include_dirs = [
+    "include",
+    "avct",
+    "btm",
+    "avrc",
+    "l2cap",
+    "avdt",
+    "gatt",
+    "gap",
+    "pan",
+    "bnep",
+    "hid",
+    "sdp",
+    "smp",
+    "srvc",
+    "//btcore/include",
+    "//vnd/include",
+    "//vnd/ble",
+    "//btif/include",
+    "//hci/include",
+    "//include",
+    "//gki/common",
+    "//gki/ulinux",
+    "//osi/include",
+    "//udrv/include",
+    "//rpc/include",
+    "//hcis",
+    "//ctrlr/include",
+    "//bta/include",
+    "//bta/sys",
+    "//utils/include",
+    "//",
+  ]
+}
index 4b786b4..fd7c816 100644 (file)
@@ -284,8 +284,9 @@ tA2D_STATUS A2D_ParsSbcInfo(tA2D_SBC_CIE *p_ie, UINT8 *p_info, BOOLEAN for_caps)
         status = A2D_INVALID_PARAMS;
     else
     {
-        losc    = *p_info++;
-        *p_info++;
+        losc    = *p_info;
+        *p_info += 2;
+
         /* If the function is called for the wrong Media Type or Media Codec Type */
         if(losc != A2D_SBC_INFO_LEN || *p_info != A2D_MEDIA_CT_SBC)
             status = A2D_WRONG_CODEC;
index 09ed39a..0cad57c 100644 (file)
@@ -386,7 +386,7 @@ tAVDT_CCB *avdt_ccb_alloc(BD_ADDR bd_addr)
             memcpy(p_ccb->peer_addr, bd_addr, BD_ADDR_LEN);
             GKI_init_q(&p_ccb->cmd_q);
             GKI_init_q(&p_ccb->rsp_q);
-            p_ccb->timer_entry.param = (UINT32) p_ccb;
+            p_ccb->timer_entry.param = p_ccb;
             AVDT_TRACE_DEBUG("avdt_ccb_alloc %d", i);
             break;
         }
index 696fcca..2a2ab4a 100644 (file)
@@ -620,7 +620,7 @@ tAVDT_SCB *avdt_scb_alloc(tAVDT_CS *p_cs)
 #endif
             }
 #endif
-            p_scb->timer_entry.param = (UINT32) p_scb;
+            p_scb->timer_entry.param = p_scb;
             AVDT_TRACE_DEBUG("avdt_scb_alloc hdl=%d, psc_mask:0x%x", i+1, p_cs->cfg.psc_mask);
             break;
         }
index 1db329d..0cf3b3f 100644 (file)
@@ -120,7 +120,7 @@ tBNEP_CONN *bnepu_allocate_bcb (BD_ADDR p_rem_bda)
         {
             memset ((UINT8 *)p_bcb, 0, sizeof (tBNEP_CONN));
 
-            p_bcb->conn_tle.param = (UINT32) p_bcb;
+            p_bcb->conn_tle.param = p_bcb;
 
             memcpy ((UINT8 *)(p_bcb->rem_bda), (UINT8 *)p_rem_bda, BD_ADDR_LEN);
             p_bcb->handle = xx + 1;
index a6e520a..c8e0e7b 100644 (file)
@@ -796,7 +796,7 @@ void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
                 btsnd_hcic_disconnect(p_dev_rec->hci_handle, HCI_ERR_PEER_USER);
             }
             BTM_TRACE_ERROR("btm_acl_encrypt_change: tBTM_SEC_DEV:0x%x rs_disc_pending=%d",
-                (UINT32)p_dev_rec, p_dev_rec->rs_disc_pending);
+                            PTR_TO_UINT(p_dev_rec), p_dev_rec->rs_disc_pending);
             p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING;     /* reset flag */
         }
 #endif
@@ -1529,7 +1529,7 @@ void btm_acl_role_changed (UINT8 hci_status, BD_ADDR bd_addr, UINT8 new_role)
             btsnd_hcic_disconnect(p_dev_rec->hci_handle, HCI_ERR_PEER_USER);
         }
         BTM_TRACE_ERROR("tBTM_SEC_DEV:0x%x rs_disc_pending=%d",
-                         (UINT32)p_dev_rec, p_dev_rec->rs_disc_pending);
+                        PTR_TO_UINT(p_dev_rec), p_dev_rec->rs_disc_pending);
         p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING;     /* reset flag */
     }
 
index 06694a2..d26632f 100644 (file)
@@ -22,6 +22,9 @@
  *  security functions.
  *
  ******************************************************************************/
+
+#define LOG_TAG "bt_btm_ble"
+
 #include "bt_target.h"
 
 #if BLE_INCLUDED == TRUE
 #include <string.h>
 
 #include "bt_types.h"
-#include "hcimsgs.h"
-#include "btu.h"
-#include "btm_int.h"
-#include "btm_ble_api.h"
-#include "smp_api.h"
-#include "l2c_int.h"
-#include "gap_api.h"
 #include "bt_utils.h"
+#include "btm_ble_api.h"
+#include "btm_int.h"
+#include "btu.h"
 #include "device/include/controller.h"
-
-#define LOG_TAG "bt_btm_ble"
+#include "gap_api.h"
+#include "hcimsgs.h"
+#include "l2c_int.h"
 #include "osi/include/log.h"
+#include "smp_api.h"
 
 #if SMP_INCLUDED == TRUE
 extern BOOLEAN aes_cipher_msg_auth_code(BT_OCTET16 key, UINT8 *input, UINT16 length,
@@ -666,7 +667,6 @@ void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, tBLE_ADDR
     BTM_TRACE_DEBUG ("btm_find_dev_type - device_type = %d addr_type = %d", *p_dev_type , *p_addr_type);
 }
 
-
 /*******************************************************************************
 **
 ** Function         BTM_ReadConnectedTransportAddress
@@ -683,7 +683,6 @@ void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, tBLE_ADDR
 BOOLEAN BTM_ReadConnectedTransportAddress(BD_ADDR remote_bda, tBT_TRANSPORT transport)
 {
     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(remote_bda);
-    tACL_CONN *p = btm_bda_to_acl(remote_bda, transport);
 
     /* if no device can be located, return */
     if (p_dev_rec == NULL)
@@ -825,7 +824,6 @@ BOOLEAN BTM_UseLeLink (BD_ADDR bd_addr)
     return use_le;
 }
 
-
 /*******************************************************************************
 **
 ** Function         BTM_SetBleDataLength
@@ -914,7 +912,6 @@ void btm_ble_rand_enc_complete (UINT8 *p, UINT16 op_code, tBTM_RAND_ENC_CB *p_en
     }
 }
 
-
     #if (SMP_INCLUDED == TRUE)
 
 /*******************************************************************************
@@ -1469,61 +1466,6 @@ void btm_ble_link_encrypted(BD_ADDR bd_addr, UINT8 encr_enable)
 }
 
 /*******************************************************************************
-** Function         btm_enc_proc_ltk
-** Description      send LTK reply when it's ready.
-*******************************************************************************/
-static void btm_enc_proc_ltk(tSMP_ENC *p)
-{
-    UINT8   i;
-    BTM_TRACE_DEBUG ("btm_enc_proc_ltk");
-    if (p && p->param_len == BT_OCTET16_LEN)
-    {
-        for (i = 0; i < (BT_OCTET16_LEN - btm_cb.key_size); i ++)
-            p->param_buf[BT_OCTET16_LEN - i - 1] = 0;
-        btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, p->param_buf);
-    }
-}
-
-/*******************************************************************************
-** Function         btm_enc_proc_slave_y
-** Description      calculate LTK when Y is ready
-*******************************************************************************/
-static void btm_enc_proc_slave_y(tSMP_ENC *p)
-{
-    UINT16  div, y;
-    UINT8   *pp = p->param_buf;
-    tBTM_CB *p_cb = &btm_cb;
-    tSMP_ENC output;
-    tBTM_SEC_DEV_REC *p_dev_rec;
-
-    BTM_TRACE_DEBUG ("btm_enc_proc_slave_y");
-    if (p != NULL)
-    {
-        STREAM_TO_UINT16(y, pp);
-
-        div = p_cb->ediv ^ y;
-        p_dev_rec = btm_find_dev_by_handle (p_cb->enc_handle);
-
-        if ( p_dev_rec &&
-             p_dev_rec->ble.keys.div == div )
-        {
-            BTM_TRACE_DEBUG ("LTK request OK");
-            /* calculating LTK , LTK = E er(div) */
-            SMP_Encrypt(p_cb->devcb.ble_encryption_key_value, BT_OCTET16_LEN, (UINT8 *)&div, 2, &output);
-            btm_enc_proc_ltk(&output);
-        }
-        else
-        {
-            BTM_TRACE_DEBUG ("LTK request failed - send negative reply");
-            btsnd_hcic_ble_ltk_req_neg_reply(p_cb->enc_handle);
-            if (p_dev_rec)
-                btm_ble_link_encrypted(p_dev_rec->bd_addr, 0);
-
-        }
-    }
-}
-
-/*******************************************************************************
 **
 ** Function         btm_ble_ltk_request_reply
 **
@@ -1537,7 +1479,6 @@ void btm_ble_ltk_request_reply(BD_ADDR bda,  BOOLEAN use_stk, BT_OCTET16 stk)
 {
     tBTM_SEC_DEV_REC    *p_rec = btm_find_dev (bda);
     tBTM_CB *p_cb = &btm_cb;
-    tSMP_ENC output;
 
     if (p_rec == NULL)
     {
@@ -1709,7 +1650,7 @@ static void btm_ble_resolve_random_addr_on_conn_cmpl(void * p_rec, void *p_data)
 
     if (match_rec)
     {
-        LOG_INFO("%s matched and resolved random address", __func__);
+        LOG_INFO(LOG_TAG, "%s matched and resolved random address", __func__);
         match = TRUE;
         match_rec->ble.active_addr_type = BTM_BLE_ADDR_RRA;
         memcpy(match_rec->ble.cur_rand_addr, bda, BD_ADDR_LEN);
@@ -1725,7 +1666,7 @@ static void btm_ble_resolve_random_addr_on_conn_cmpl(void * p_rec, void *p_data)
     }
     else
     {
-        LOG_INFO("%s unable to match and resolve random address", __func__);
+        LOG_INFO(LOG_TAG, "%s unable to match and resolve random address", __func__);
     }
 
     btm_ble_connected(bda, handle, HCI_ENCRYPT_MODE_DISABLED, role, bda_type, match);
@@ -1899,8 +1840,6 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced)
     btm_ble_update_mode_operation(role, bda, status);
 }
 
-
-
 /*****************************************************************************
 ** Function btm_ble_create_ll_conn_complete
 **
@@ -2036,7 +1975,6 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data)
                 BTM_TRACE_DEBUG ("unknown event = %d", event);
                 break;
 
-
         }
     }
     else
@@ -2511,7 +2449,6 @@ static void btm_ble_process_ir2(tBTM_RAND_ENC *p)
         memcpy(&btm_cb.devcb.id_keys.ir[8], p->param_buf, BT_OCTET8_LEN);
         /* generate DHK= Eir({0x03, 0x00, 0x00 ...}) */
 
-
         SMP_Encrypt(btm_cb.devcb.id_keys.ir, BT_OCTET16_LEN, &btm_ble_dhk_pt,
                     1, &output);
         btm_ble_process_dhk(&output);
@@ -2648,7 +2585,6 @@ void btm_set_random_address(BD_ADDR random_bda)
     if (adv_mode  == BTM_BLE_ADV_ENABLE)
         btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE);
 
-
 }
 
 /*******************************************************************************
index 74ddddd..333f1f4 100644 (file)
 #define LOG_TAG "bt_btm_ble"
 
 #include <string.h>
+
 #include "bt_target.h"
 
 #if (BLE_INCLUDED == TRUE)
+
 #include "bt_types.h"
-#include "hcimsgs.h"
-#include "btu.h"
-#include "btm_int.h"
 #include "bt_utils.h"
-#include "hcidefs.h"
 #include "btm_ble_api.h"
+#include "btm_int.h"
+#include "btu.h"
 #include "device/include/controller.h"
+#include "hcidefs.h"
+#include "hcimsgs.h"
 
 #define BTM_BLE_ADV_FILT_META_HDR_LENGTH 3
 #define BTM_BLE_ADV_FILT_FEAT_SELN_LEN  13
@@ -47,7 +49,6 @@
 
 #define BTM_BLE_PF_BIT_TO_MASK(x)          (UINT16)(1 << (x))
 
-
 tBTM_BLE_ADV_FILTER_CB btm_ble_adv_filt_cb;
 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
 static const BD_ADDR     na_bda= {0};
@@ -60,7 +61,6 @@ static UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
 #define BTM_BLE_GET_SCAN_PF_ACTION(x)    ((x) & 0x0f)
 #define BTM_BLE_INVALID_COUNTER     0xff
 
-
 /* length of each multi adv sub command */
 #define BTM_BLE_ADV_FILTER_ENB_LEN                       3
 
@@ -502,7 +502,6 @@ tBTM_STATUS btm_ble_update_pf_local_name(tBTM_BLE_SCAN_COND_OP action,
     return st;
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_ble_update_srvc_data_change
@@ -721,7 +720,6 @@ UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
     return BTM_BLE_INVALID_COUNTER;
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_ble_update_addr_filter
@@ -925,7 +923,6 @@ tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action,
     return st;
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_ble_clear_scan_pf_filter
index 2107577..398e6a4 100644 (file)
@@ -522,6 +522,7 @@ BOOLEAN btm_ble_start_select_conn(BOOLEAN start, tBTM_BLE_SEL_CBACK *p_select_cb
 #endif
                 if (!btsnd_hcic_ble_set_scan_enable(TRUE, TRUE)) /* duplicate filtering enabled */
                      return FALSE;
+
                  /* mark up inquiry status flag */
                  p_cb->scan_activity |= BTM_LE_SELECT_CONN_ACTIVE;
                  p_cb->wl_state |= BTM_BLE_WL_SCAN;
index f841148..bceb39b 100644 (file)
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_btm_ble"
+
 #include <string.h>
 #include <stdio.h>
 #include <stddef.h>
 
 #include "bt_types.h"
 #include "bt_utils.h"
-#include "btm_int.h"
 #include "btm_ble_api.h"
+#include "btm_int.h"
 #include "btu.h"
 #include "device/include/controller.h"
-#include "hcimsgs.h"
 #include "gap_api.h"
+#include "hcimsgs.h"
 
 #if BLE_INCLUDED == TRUE
-#include "l2c_int.h"
-
-#include "gattdefs.h"
-#include "gatt_int.h"
 
 #include "btm_ble_int.h"
-#define LOG_TAG "bt_btm_ble"
+#include "gatt_int.h"
+#include "gattdefs.h"
+#include "l2c_int.h"
 #include "osi/include/log.h"
 
 #define BTM_BLE_NAME_SHORT                  0x01
@@ -221,7 +221,6 @@ const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] =
 /* check LE combo state supported */
 #define BTM_LE_STATES_SUPPORTED(x, y, z)      ((x)[(z)] & (y))
 
-
 /*******************************************************************************
 **
 ** Function         BTM_BleUpdateAdvWhitelist
@@ -486,6 +485,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start)
     return status;
 }
 
+#if BLE_VND_INCLUDED == TRUE
 /*******************************************************************************
 **
 ** Function         btm_vsc_brcm_features_complete
@@ -497,7 +497,6 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start)
 *******************************************************************************/
 static void btm_ble_vendor_capability_vsc_cmpl_cback (tBTM_VSC_CMPL *p_vcs_cplt_params)
 {
-#if BLE_VND_INCLUDED == TRUE
     UINT8 status = 0xFF;
     UINT8 *p;
 
@@ -555,15 +554,15 @@ static void btm_ble_vendor_capability_vsc_cmpl_cback (tBTM_VSC_CMPL *p_vcs_cplt_
     if (btm_cb.cmn_ble_vsc_cb.max_irk_list_sz > 0 &&
         controller_get_interface()->get_ble_resolving_list_max_size() == 0)
         btm_ble_resolving_list_init(btm_cb.cmn_ble_vsc_cb.max_irk_list_sz);
-#endif
+#endif  /* (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) */
 
     if (btm_cb.cmn_ble_vsc_cb.tot_scan_results_strg > 0)
         btm_ble_batchscan_init();
 
     if (p_ctrl_le_feature_rd_cmpl_cback != NULL)
         p_ctrl_le_feature_rd_cmpl_cback(status);
-#endif
 }
+#endif  /* BLE_VND_INCLUDED == TRUE */
 
 /*******************************************************************************
 **
@@ -1184,8 +1183,7 @@ tBTM_STATUS BTM_BleWriteScanRsp(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p
     UINT8   rsp_data[BTM_BLE_AD_DATA_LEN],
             *p = rsp_data;
 
-    BTM_TRACE_EVENT (" BTM_BleWriteScanRsp");
-
+    BTM_TRACE_EVENT ("%s: data_mask:%08x", __func__, data_mask);
     if (!controller_get_interface()->supports_ble())
         return BTM_ILLEGAL_VALUE;
 
@@ -1270,7 +1268,7 @@ UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length)
     UINT8 *p = p_adv;
     UINT8 length;
     UINT8 adv_type;
-    BTM_TRACE_API("BTM_CheckAdvData type=0x%02X", type);
+    BTM_TRACE_API("%s: type=0x%02x", __func__, type);
 
     STREAM_TO_UINT8(length, p);
 
@@ -1396,17 +1394,16 @@ UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst,
 #endif
         /* manufacturer data */
         if (len > MIN_ADV_LENGTH && data_mask & BTM_BLE_AD_BIT_MANU &&
-            p_data && p_data->p_manu &&
-            p_data->p_manu->len != 0 && p_data->p_manu->p_val)
+            p_data && p_data->manu.len != 0)
         {
-            if (p_data->p_manu->len > (len - MIN_ADV_LENGTH))
+            if (p_data->manu.len > (len - MIN_ADV_LENGTH))
                 cp_len = len - MIN_ADV_LENGTH;
             else
-                cp_len = p_data->p_manu->len;
+                cp_len = p_data->manu.len;
 
             *p++ = cp_len + 1;
             *p++ = BTM_BLE_AD_TYPE_MANU;
-            ARRAY_TO_STREAM(p, p_data->p_manu->p_val, cp_len);
+            ARRAY_TO_STREAM(p, p_data->manu.val, cp_len);
 
             len -= (cp_len + MIN_ADV_LENGTH);
             data_mask &= ~BTM_BLE_AD_BIT_MANU;
@@ -1424,11 +1421,9 @@ UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst,
         }
         /* 16 bits services */
         if (len > MIN_ADV_LENGTH && data_mask & BTM_BLE_AD_BIT_SERVICE &&
-            p_data && p_data->p_services &&
-            p_data->p_services->num_service != 0 &&
-            p_data->p_services->p_uuid)
+            p_data && p_data->services.num_service != 0)
         {
-            if (p_data->p_services->num_service * LEN_UUID_16 > (len - MIN_ADV_LENGTH))
+            if (p_data->services.num_service * LEN_UUID_16 > (len - MIN_ADV_LENGTH))
             {
                 cp_len = (len - MIN_ADV_LENGTH)/LEN_UUID_16;
                 *p ++ = 1 + cp_len * LEN_UUID_16;
@@ -1436,13 +1431,13 @@ UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst,
             }
             else
             {
-                cp_len = p_data->p_services->num_service;
+                cp_len = p_data->services.num_service;
                 *p++ = 1 + cp_len * LEN_UUID_16;
                 *p++ = BTM_BLE_AD_TYPE_16SRV_CMPL;
             }
             for (i = 0; i < cp_len; i ++)
             {
-                UINT16_TO_STREAM(p, *(p_data->p_services->p_uuid + i));
+                UINT16_TO_STREAM(p, *(p_data->services.uuid + i));
             }
 
             len -= (cp_len * MIN_ADV_LENGTH + MIN_ADV_LENGTH);
@@ -1450,11 +1445,9 @@ UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst,
         }
         /* 32 bits service uuid */
         if (len > MIN_ADV_LENGTH && data_mask & BTM_BLE_AD_BIT_SERVICE_32 &&
-            p_data && p_data->p_service_32b &&
-            p_data->p_service_32b->num_service != 0 &&
-            p_data->p_service_32b->p_uuid)
+            p_data && p_data->service_32b.num_service != 0)
         {
-            if ((p_data->p_service_32b->num_service * LEN_UUID_32) > (len - MIN_ADV_LENGTH))
+            if ((p_data->service_32b.num_service * LEN_UUID_32) > (len - MIN_ADV_LENGTH))
             {
                 cp_len = (len - MIN_ADV_LENGTH)/LEN_UUID_32;
                 *p ++ = 1 + cp_len * LEN_UUID_32;
@@ -1462,13 +1455,13 @@ UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst,
             }
             else
             {
-                cp_len = p_data->p_service_32b->num_service;
+                cp_len = p_data->service_32b.num_service;
                 *p++ = 1 + cp_len * LEN_UUID_32;
                 *p++ = BTM_BLE_AD_TYPE_32SRV_CMPL;
             }
             for (i = 0; i < cp_len; i ++)
             {
-                UINT32_TO_STREAM(p, *(p_data->p_service_32b->p_uuid + i));
+                UINT32_TO_STREAM(p, *(p_data->service_32b.uuid + i));
             }
 
             len -= (cp_len * LEN_UUID_32 + MIN_ADV_LENGTH);
@@ -1476,40 +1469,38 @@ UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst,
         }
         /* 128 bits services */
         if (len >= (MAX_UUID_SIZE + 2) && data_mask & BTM_BLE_AD_BIT_SERVICE_128 &&
-            p_data && p_data->p_services_128b)
+            p_data && p_data->services_128b.num_service)
         {
             *p ++ = 1 + MAX_UUID_SIZE;
-            if (!p_data->p_services_128b->list_cmpl)
+            if (!p_data->services_128b.list_cmpl)
                 *p++ = BTM_BLE_AD_TYPE_128SRV_PART;
             else
                 *p++ = BTM_BLE_AD_TYPE_128SRV_CMPL;
 
-            ARRAY_TO_STREAM(p, p_data->p_services_128b->uuid128, MAX_UUID_SIZE);
+            ARRAY_TO_STREAM(p, p_data->services_128b.uuid128, MAX_UUID_SIZE);
 
             len -= (MAX_UUID_SIZE + MIN_ADV_LENGTH);
             data_mask &= ~BTM_BLE_AD_BIT_SERVICE_128;
         }
         /* 32 bits Service Solicitation UUIDs */
         if (len > MIN_ADV_LENGTH && data_mask & BTM_BLE_AD_BIT_SERVICE_32SOL &&
-            p_data && p_data->p_sol_service_32b &&
-            p_data->p_sol_service_32b->num_service != 0 &&
-            p_data->p_sol_service_32b->p_uuid)
+            p_data->sol_service_32b.num_service != 0)
         {
-            if ((p_data->p_sol_service_32b->num_service * LEN_UUID_32) > (len - MIN_ADV_LENGTH))
+            if ((p_data->sol_service_32b.num_service * LEN_UUID_32) > (len - MIN_ADV_LENGTH))
             {
                 cp_len = (len - MIN_ADV_LENGTH)/LEN_UUID_32;
                 *p ++ = 1 + cp_len * LEN_UUID_32;
             }
             else
             {
-                cp_len = p_data->p_sol_service_32b->num_service;
+                cp_len = p_data->sol_service_32b.num_service;
                 *p++ = 1 + cp_len * LEN_UUID_32;
             }
 
             *p++ = BTM_BLE_AD_TYPE_32SOL_SRV_UUID;
             for (i = 0; i < cp_len; i ++)
             {
-                UINT32_TO_STREAM(p, *(p_data->p_sol_service_32b->p_uuid + i));
+                UINT32_TO_STREAM(p, *(p_data->sol_service_32b.uuid + i));
             }
 
             len -= (cp_len * LEN_UUID_32 + MIN_ADV_LENGTH);
@@ -1517,46 +1508,46 @@ UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst,
         }
         /* 128 bits Solicitation services UUID */
         if (len >= (MAX_UUID_SIZE + MIN_ADV_LENGTH) && data_mask & BTM_BLE_AD_BIT_SERVICE_128SOL &&
-            p_data && p_data->p_sol_service_128b)
+            p_data && p_data->sol_service_128b.num_service)
         {
             *p ++ = 1 + MAX_UUID_SIZE;
             *p++ = BTM_BLE_AD_TYPE_128SOL_SRV_UUID;
-            ARRAY_TO_STREAM(p, p_data->p_sol_service_128b->uuid128, MAX_UUID_SIZE);
+            ARRAY_TO_STREAM(p, p_data->sol_service_128b.uuid128, MAX_UUID_SIZE);
             len -= (MAX_UUID_SIZE + MIN_ADV_LENGTH);
             data_mask &= ~BTM_BLE_AD_BIT_SERVICE_128SOL;
         }
         /* 16bits/32bits/128bits Service Data */
         if (len > MIN_ADV_LENGTH && data_mask & BTM_BLE_AD_BIT_SERVICE_DATA &&
-            p_data && p_data->p_service_data->len != 0 && p_data->p_service_data->p_val)
+            p_data && p_data->service_data.len != 0)
         {
-            if (len  > (p_data->p_service_data->service_uuid.len + MIN_ADV_LENGTH))
+            if (len  > (p_data->service_data.service_uuid.len + MIN_ADV_LENGTH))
             {
-                if (p_data->p_service_data->len > (len - MIN_ADV_LENGTH))
-                    cp_len = len - MIN_ADV_LENGTH- p_data->p_service_data->service_uuid.len;
+                if (p_data->service_data.len > (len - MIN_ADV_LENGTH))
+                    cp_len = len - MIN_ADV_LENGTH- p_data->service_data.service_uuid.len;
                 else
-                    cp_len = p_data->p_service_data->len;
+                    cp_len = p_data->service_data.len;
 
-                *p++ = cp_len + 1 + p_data->p_service_data->service_uuid.len;
-                if (p_data->p_service_data->service_uuid.len == LEN_UUID_16)
+                *p++ = cp_len + 1 + p_data->service_data.service_uuid.len;
+                if (p_data->service_data.service_uuid.len == LEN_UUID_16)
                 {
                     *p++ = BTM_BLE_AD_TYPE_SERVICE_DATA;
-                    UINT16_TO_STREAM(p, p_data->p_service_data->service_uuid.uu.uuid16);
+                    UINT16_TO_STREAM(p, p_data->service_data.service_uuid.uu.uuid16);
                 }
-                else if (p_data->p_service_data->service_uuid.len == LEN_UUID_32)
+                else if (p_data->service_data.service_uuid.len == LEN_UUID_32)
                 {
                     *p++ = BTM_BLE_AD_TYPE_32SERVICE_DATA;
-                    UINT32_TO_STREAM(p, p_data->p_service_data->service_uuid.uu.uuid32);
+                    UINT32_TO_STREAM(p, p_data->service_data.service_uuid.uu.uuid32);
                 }
                 else
                 {
                     *p++ = BTM_BLE_AD_TYPE_128SERVICE_DATA;
-                    ARRAY_TO_STREAM(p, p_data->p_service_data->service_uuid.uu.uuid128,
+                    ARRAY_TO_STREAM(p, p_data->service_data.service_uuid.uu.uuid128,
                                     LEN_UUID_128);
                 }
 
-                ARRAY_TO_STREAM(p, p_data->p_service_data->p_val, cp_len);
+                ARRAY_TO_STREAM(p, p_data->service_data.val, cp_len);
 
-                len -= (cp_len + MIN_ADV_LENGTH + p_data->p_service_data->service_uuid.len);
+                len -= (cp_len + MIN_ADV_LENGTH + p_data->service_data.service_uuid.len);
                 data_mask &= ~BTM_BLE_AD_BIT_SERVICE_DATA;
             }
             else
@@ -1575,18 +1566,18 @@ UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst,
             len -= 6;
             data_mask &= ~BTM_BLE_AD_BIT_INT_RANGE;
         }
-        if (data_mask & BTM_BLE_AD_BIT_PROPRIETARY && p_data && p_data->p_proprietary)
+        if (data_mask & BTM_BLE_AD_BIT_PROPRIETARY && p_data)
         {
-            for (i = 0; i < p_data->p_proprietary->num_elem ; i ++)
+            for (i = 0; i < p_data->proprietary.num_elem; ++i)
             {
-                p_elem = p_data->p_proprietary->p_elem  + i;
+                p_elem = &p_data->proprietary.elem[i];
 
                 if (len >= (MIN_ADV_LENGTH + p_elem->len))/* len byte(1) + ATTR type(1) + Uuid len(2)
                                                           + value length */
                 {
                     *p ++ = p_elem->len + 1; /* Uuid len + value length */
                     *p ++ = p_elem->adv_type;
-                    ARRAY_TO_STREAM(p, p_elem->p_val, p_elem->len);
+                    ARRAY_TO_STREAM(p, p_elem->val, p_elem->len);
 
                     len -= (MIN_ADV_LENGTH + p_elem->len);
                 }
@@ -1703,7 +1694,7 @@ void btm_ble_set_adv_flag(UINT16 connect_mode, UINT16 disc_mode)
 
     btm_ble_update_dmt_flag_bits (&flag, connect_mode, disc_mode);
 
-    LOG_DEBUG("disc_mode %04x", disc_mode);
+    LOG_DEBUG(LOG_TAG, "disc_mode %04x", disc_mode);
     /* update discoverable flag */
     if (disc_mode & BTM_BLE_LIMITED_DISCOVERABLE)
     {
@@ -1924,7 +1915,6 @@ tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode)
     return status;
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_ble_start_inquiry
@@ -2803,7 +2793,7 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt
 
     if ((result = btm_ble_is_discoverable(bda, evt_type, p)) == 0)
     {
-      LOG_WARN("%s device is no longer discoverable so discarding advertising packet pkt",
+      LOG_WARN(LOG_TAG, "%s device is no longer discoverable so discarding advertising packet pkt",
           __func__);
         return;
     }
@@ -3013,7 +3003,6 @@ static BOOLEAN btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR *p_handler, UI
     return rt;
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_ble_start_adv
@@ -3089,7 +3078,6 @@ tBTM_STATUS btm_ble_stop_adv(void)
     return rt;
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_ble_start_slow_adv
@@ -3180,7 +3168,6 @@ void btm_ble_timeout(TIMER_LIST_ENT *p_tle)
     }
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_ble_read_remote_features_complete
@@ -3474,5 +3461,4 @@ BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request_state_mask)
     return rt;
 }
 
-
 #endif  /* BLE_INCLUDED */
index 0189bda..b9befdf 100644 (file)
@@ -482,7 +482,6 @@ void btm_consolidate_dev(tBTM_SEC_DEV_REC *p_target_rec)
 #if BLE_INCLUDED == TRUE
     tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0];
     tBTM_SEC_DEV_REC temp_rec = *p_target_rec;
-    BD_ADDR dummy_bda = {0};
 
     BTM_TRACE_DEBUG("%s", __func__);
 
index 3a70788..896bef5 100644 (file)
@@ -262,9 +262,6 @@ void btm_dev_timeout (TIMER_LIST_ENT  *p_tle)
 *******************************************************************************/
 static void btm_decode_ext_features_page (UINT8 page_number, const UINT8 *p_features)
 {
-    UINT8 last;
-    UINT8 first;
-
     BTM_TRACE_DEBUG ("btm_decode_ext_features_page page: %d", page_number);
     switch (page_number)
     {
index b22b5de..df51e58 100644 (file)
 
 #define LOG_TAG "bt_btm_pm"
 
+#include <stddef.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stdio.h>
-#include <stddef.h>
 
 #include "bt_types.h"
-#include "gki.h"
-#include "hcimsgs.h"
-#include "btu.h"
+#include "bt_utils.h"
 #include "btm_api.h"
 #include "btm_int.h"
-#include "l2c_int.h"
+#include "btu.h"
+#include "gki.h"
 #include "hcidefs.h"
-#include "bt_utils.h"
+#include "hcimsgs.h"
+#include "l2c_int.h"
 #include "osi/include/log.h"
 
 /*****************************************************************************/
@@ -184,7 +184,6 @@ tBTM_STATUS BTM_SetPowerMode (UINT8 pm_id, BD_ADDR remote_bda, tBTM_PM_PWR_MD *p
     tBTM_PM_MODE        mode;
     int                 temp_pm_id;
 
-
     if(pm_id >= BTM_MAX_PM_RECORDS)
         pm_id = BTM_PM_SET_ONLY_ID;
 
@@ -259,8 +258,6 @@ tBTM_STATUS BTM_SetPowerMode (UINT8 pm_id, BD_ADDR remote_bda, tBTM_PM_PWR_MD *p
         return BTM_CMD_STORED;
     }
 
-
-
     return btm_pm_snd_md_req(pm_id, acl_ind, p_mode);
 }
 
@@ -363,7 +360,6 @@ void btm_pm_reset(void)
         cb = btm_cb.pm_reg_db[btm_cb.pm_pend_id].cback;
     }
 
-
     /* clear the register record */
     for(xx=0; xx<BTM_MAX_PM_RECORDS; xx++)
     {
@@ -624,7 +620,7 @@ static tBTM_STATUS btm_pm_snd_md_req(UINT8 pm_id, int link_ind, tBTM_PM_PWR_MD *
     BTM_TRACE_DEBUG("btm_pm_snd_md_req state:0x%x, link_ind: %d", p_cb->state, link_ind);
 #endif  // BTM_PM_DEBUG
 
-    LOG_DEBUG("%s switching from %s to %s.", __func__, mode_to_string(p_cb->state), mode_to_string(md_res.mode));
+    LOG_DEBUG(LOG_TAG, "%s switching from %s to %s.", __func__, mode_to_string(p_cb->state), mode_to_string(md_res.mode));
     switch(md_res.mode)
     {
     case BTM_PM_MD_ACTIVE:
@@ -715,7 +711,6 @@ static void btm_pm_check_stored(void)
     }
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_pm_proc_cmd_status
@@ -802,7 +797,7 @@ void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, U
     p_cb->state     = mode;
     p_cb->interval  = interval;
 
-    LOG_DEBUG("%s switched from %s to %s.", __func__, mode_to_string(old_state), mode_to_string(p_cb->state));
+    LOG_DEBUG(LOG_TAG, "%s switched from %s to %s.", __func__, mode_to_string(old_state), mode_to_string(p_cb->state));
 
     if ((p_lcb = l2cu_find_lcb_by_bd_addr(p->remote_addr, BT_TRANSPORT_BR_EDR)) != NULL)
     {
@@ -846,7 +841,6 @@ void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, U
         }
     }
 
-
     /* notify registered parties */
     for(yy=0; yy<BTM_MAX_PM_RECORDS; yy++)
     {
index 68e9a8e..754608d 100644 (file)
 #include <string.h>
 
 #include "bt_types.h"
+#include "bt_utils.h"
+#include "btm_int.h"
+#include "btu.h"
 #include "device/include/controller.h"
 #include "hcimsgs.h"
-#include "btu.h"
-#include "btm_int.h"
 #include "l2c_int.h"
-#include "bt_utils.h"
 #include "osi/include/log.h"
 
 #if (BT_USE_TRACES == TRUE && BT_TRACE_VERBOSE == FALSE)
@@ -51,7 +51,6 @@
 BOOLEAN (APPL_AUTH_WRITE_EXCEPTION)(BD_ADDR bd_addr);
 #endif
 
-
 /********************************************************************************
 **              L O C A L    F U N C T I O N     P R O T O T Y P E S            *
 *********************************************************************************/
@@ -103,10 +102,8 @@ static UINT16  btm_sec_set_serv_level4_flags (UINT16 cur_security, BOOLEAN is_or
 
 static BOOLEAN btm_sec_queue_encrypt_request  (BD_ADDR bd_addr, tBT_TRANSPORT transport,
                                          tBTM_SEC_CALLBACK *p_callback, void *p_ref_data);
-static void btm_sec_clean_pending_req_queue (BD_ADDR remote_bda, tBT_TRANSPORT transport) ;
 static void btm_sec_check_pending_enc_req (tBTM_SEC_DEV_REC  *p_dev_rec, tBT_TRANSPORT transport,
                                             UINT8 encr_enable);
-static BOOLEAN btm_sec_acceptor_rejects_bonding (tBTM_SEC_DEV_REC *p_dev_rec);
 
 static BOOLEAN btm_sec_use_smp_br_chnl(tBTM_SEC_DEV_REC *p_dev_rec);
 static BOOLEAN btm_sec_is_master(tBTM_SEC_DEV_REC *p_dev_rec);
@@ -236,7 +233,7 @@ BOOLEAN BTM_SecRegister(tBTM_APPL_INFO *p_cb_info)
     BTM_TRACE_EVENT("%s application registered", __func__);
 
 #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
-    LOG_INFO("%s p_cb_info->p_le_callback == 0x%p", __func__, p_cb_info->p_le_callback);
+    LOG_INFO(LOG_TAG, "%s p_cb_info->p_le_callback == 0x%p", __func__, p_cb_info->p_le_callback);
     if (p_cb_info->p_le_callback)
     {
 #if SMP_INCLUDED == TRUE
@@ -251,13 +248,13 @@ BOOLEAN BTM_SecRegister(tBTM_APPL_INFO *p_cb_info)
     }
     else
     {
-      LOG_WARN("%s p_cb_info->p_le_callback == NULL", __func__);
+      LOG_WARN(LOG_TAG, "%s p_cb_info->p_le_callback == NULL", __func__);
     }
 #endif
 
     btm_cb.api = *p_cb_info;
 #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
-     LOG_INFO("%s btm_cb.api.p_le_callback = 0x%p ", __func__, btm_cb.api.p_le_callback);
+     LOG_INFO(LOG_TAG, "%s btm_cb.api.p_le_callback = 0x%p ", __func__, btm_cb.api.p_le_callback);
 #endif
     BTM_TRACE_EVENT("%s application registered", __func__);
     return(TRUE);
@@ -306,7 +303,6 @@ BOOLEAN  BTM_SecAddRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback)
     return(FALSE);
 }
 
-
 /*******************************************************************************
 **
 ** Function         BTM_SecDeleteRmtNameNotifyCallback
@@ -549,7 +545,6 @@ static BOOLEAN btm_sec_set_security_level (CONNECTION_TYPE conn_type, char *p_na
 
     p_srec = &btm_cb.sec_serv_rec[0];
 
-
     for (index = 0; index < BTM_SEC_MAX_SERVICE_RECORDS; index++, p_srec++)
     {
         /* Check if there is already a record for this service */
@@ -721,7 +716,6 @@ static BOOLEAN btm_sec_set_security_level (CONNECTION_TYPE conn_type, char *p_na
 #endif
 #endif
 
-
     return(record_allocated);
 }
 
@@ -989,7 +983,6 @@ tBTM_STATUS btm_sec_bond_by_transport (BD_ADDR bd_addr, tBT_TRANSPORT transport,
 
     BTM_TRACE_DEBUG("btm_sec_bond_by_transport: Transport used %d" , transport);
 
-
     /* Other security process is in progress */
     if (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
     {
@@ -1061,7 +1054,6 @@ tBTM_STATUS btm_sec_bond_by_transport (BD_ADDR bd_addr, tBT_TRANSPORT transport,
     p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED
                                   | BTM_SEC_ROLE_SWITCHED  | BTM_SEC_LINK_KEY_AUTHED);
 
-
     BTM_TRACE_DEBUG ("after update sec_flags=0x%x", p_dev_rec->sec_flags);
     if (!controller_get_interface()->supports_simple_pairing())
     {
@@ -2433,7 +2425,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
             2046 may report HCI_Encryption_Change and L2C Connection Request out of sequence
             because of data path issues. Delay this disconnect a little bit
             */
-            LOG_INFO("%s peer should have initiated security process by now (SM4 to SM4)", __func__);
+            LOG_INFO(LOG_TAG, "%s peer should have initiated security process by now (SM4 to SM4)", __func__);
             p_dev_rec->p_callback        = p_callback;
             p_dev_rec->sec_state         = BTM_SEC_STATE_DELAY_FOR_ENC;
             (*p_callback) (bd_addr, transport, p_ref_data, rc);
@@ -3111,7 +3103,6 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
             p_dev_rec = NULL;
     }
 
-
     /* Commenting out trace due to obf/compilation problems.
     */
 #if (BT_USE_TRACES == TRUE)
@@ -3997,7 +3988,7 @@ static void btm_sec_auth_collision (UINT16 handle)
                 p_dev_rec->sec_state = 0;
 
             btm_cb.p_collided_dev_rec = p_dev_rec;
-            btm_cb.sec_collision_tle.param = (UINT32) btm_sec_collision_timeout;
+            btm_cb.sec_collision_tle.param = UINT_TO_PTR(btm_sec_collision_timeout);
             btu_start_timer (&btm_cb.sec_collision_tle, BTU_TTYPE_USER_FUNC, BT_1SEC_TIMEOUT);
         }
     }
@@ -4493,7 +4484,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
                         /* Start timer with 0 to initiate connection with new LCB */
                         /* because L2CAP will delete current LCB with this event  */
                         btm_cb.p_collided_dev_rec = p_dev_rec;
-                        btm_cb.sec_collision_tle.param = (UINT32) btm_sec_connect_after_reject_timeout;
+                        btm_cb.sec_collision_tle.param = UINT_TO_PTR(btm_sec_connect_after_reject_timeout);
                         btu_start_timer (&btm_cb.sec_collision_tle, BTU_TTYPE_USER_FUNC, 0);
                     }
                     else
@@ -4551,7 +4542,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
                 /* Start timer with 0 to initiate connection with new LCB */
                 /* because L2CAP will delete current LCB with this event  */
                 btm_cb.p_collided_dev_rec = p_dev_rec;
-                btm_cb.sec_collision_tle.param = (UINT32) btm_sec_connect_after_reject_timeout;
+                btm_cb.sec_collision_tle.param = UINT_TO_PTR(btm_sec_connect_after_reject_timeout);
                 btu_start_timer (&btm_cb.sec_collision_tle, BTU_TTYPE_USER_FUNC, 0);
             }
 
@@ -4609,7 +4600,6 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
             p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
             p_dev_rec->sec_flags &= ~ (BTM_SEC_LE_LINK_KEY_KNOWN << bit_shift);
 
-
 #ifdef BRCM_NOT_4_BTE
             /* If we rejected pairing, pass this special result code */
             if (btm_cb.acl_disc_reason == HCI_ERR_HOST_REJECT_SECURITY)
@@ -4788,7 +4778,7 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason)
     p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING;     /* reset flag */
 
 #if BTM_DISC_DURING_RS == TRUE
-    LOG_INFO("%s clearing pending flag handle:%d reason:%d", __func__, handle, reason);
+    LOG_INFO(LOG_TAG, "%s clearing pending flag handle:%d reason:%d", __func__, handle, reason);
     p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING;     /* reset flag */
 #endif
 
@@ -5385,7 +5375,6 @@ void btm_sec_update_clock_offset (UINT16 handle, UINT16 clock_offset)
     p_inq_info->results.clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID;
 }
 
-
 /******************************************************************
 ** S T A T I C     F U N C T I O N S
 *******************************************************************/
@@ -5540,7 +5529,6 @@ static tBTM_STATUS btm_sec_execute_procedure (tBTM_SEC_DEV_REC *p_dev_rec)
     return(BTM_SUCCESS);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_sec_start_get_name
@@ -5602,7 +5590,6 @@ static BOOLEAN btm_sec_start_encryption (tBTM_SEC_DEV_REC *p_dev_rec)
     return(TRUE);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_sec_start_authorization
@@ -5735,7 +5722,6 @@ static tBTM_SEC_SERV_REC *btm_sec_find_first_serv (CONNECTION_TYPE conn_type, UI
     return(NULL);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_sec_find_next_serv
@@ -5765,7 +5751,6 @@ static tBTM_SEC_SERV_REC *btm_sec_find_next_serv (tBTM_SEC_SERV_REC *p_cur)
     return(NULL);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_sec_find_mx_serv
@@ -5808,7 +5793,6 @@ static tBTM_SEC_SERV_REC *btm_sec_find_mx_serv (UINT8 is_originator, UINT16 psm,
     return(NULL);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_sec_collision_timeout
@@ -5900,7 +5884,6 @@ static void btm_restore_mode(void)
     }
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_sec_find_dev_by_sec_state
@@ -5969,7 +5952,6 @@ static void btm_sec_change_pairing_state (tBTM_PAIRING_STATE new_state)
     }
 }
 
-
 /*******************************************************************************
 **
 ** Function         btm_pair_state_descr
@@ -6205,7 +6187,6 @@ void btm_sec_set_peer_sec_caps(tACL_CONN *p_acl_cb, tBTM_SEC_DEV_REC *p_dev_rec)
     BTM_TRACE_API("%s: sm4: 0x%02x, rmt_support_for_secure_connections %d", __FUNCTION__,
                   p_dev_rec->sm4, p_dev_rec->remote_supports_secure_connections);
 
-
     if (p_dev_rec->remote_features_needed)
     {
         BTM_TRACE_EVENT("%s: Now device in SC Only mode, waiting for peer remote features!",
@@ -6220,38 +6201,6 @@ void btm_sec_set_peer_sec_caps(tACL_CONN *p_acl_cb, tBTM_SEC_DEV_REC *p_dev_rec)
 
 /*******************************************************************************
 **
-** Function         btm_sec_clean_pending_req_queue
-**
-** Description      This function cleans up the pending security request when the
-**                  link to the target device dropped.
-**
-** Returns          void
-**
-*******************************************************************************/
-static void btm_sec_clean_pending_req_queue (BD_ADDR remote_bda, tBT_TRANSPORT transport)
-{
-    tBTM_SEC_QUEUE_ENTRY    *p_e;
-    BUFFER_Q                *bq = &btm_cb.sec_pending_q;
-
-    p_e = (tBTM_SEC_QUEUE_ENTRY *)GKI_getfirst(bq);
-
-    if (p_e != NULL)
-    {
-        if (memcmp(p_e->bd_addr, remote_bda, BD_ADDR_LEN) == 0
-#if BLE_INCLUDED == TRUE
-            && p_e->transport == transport
-#endif
-            )
-        {
-            (*p_e->p_callback) (remote_bda, transport, p_e->p_ref_data, BTM_ERR_PROCESSING);
-            GKI_remove_from_queue(bq, (void *)p_e);
-        }
-        p_e = (tBTM_SEC_QUEUE_ENTRY *) GKI_getnext ((void *)p_e);
-    }
-}
-
-/*******************************************************************************
-**
 ** Function         btm_sec_is_serv_level0
 **
 ** Description      This function is called to check if the service corresponding
index 7005772..426749a 100644 (file)
 #define LOG_TAG "bt_btu_hcif"
 
 #include <assert.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stdio.h>
 
-#include "gki.h"
 #include "bt_types.h"
-#include "hcimsgs.h"
-#include "btu.h"
-#include "l2c_int.h"
+#include "bt_utils.h"
 #include "btm_api.h"
 #include "btm_int.h"
-#include "bt_utils.h"
+#include "btu.h"
 #include "device/include/controller.h"
+#include "gki.h"
+#include "hci_layer.h"
+#include "hcimsgs.h"
+#include "l2c_int.h"
 #include "osi.h"
 #include "osi/include/log.h"
-#include "hci_layer.h"
 
 // TODO(zachoverflow): remove this horrible hack
 #include "btu.h"
@@ -200,11 +200,11 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
             btu_hcif_qos_setup_comp_evt (p);
             break;
         case HCI_COMMAND_COMPLETE_EVT:
-            LOG_ERROR("%s should not have received a command complete event. "
+            LOG_ERROR(LOG_TAG, "%s should not have received a command complete event. "
                   "Someone didn't go through the hci transmit_command function.", __func__);
             break;
         case HCI_COMMAND_STATUS_EVT:
-            LOG_ERROR("%s should not have received a command status event. "
+            LOG_ERROR(LOG_TAG, "%s should not have received a command status event. "
                   "Someone didn't go through the hci transmit_command function.", __func__);
             break;
         case HCI_HARDWARE_ERROR_EVT:
@@ -346,7 +346,6 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
     }
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_send_cmd
@@ -389,7 +388,6 @@ void btu_hcif_send_cmd (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_buf)
 #endif
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_send_host_rdy_for_data
@@ -438,7 +436,6 @@ static void btu_hcif_inquiry_comp_evt (UINT8 *p)
     btm_process_inq_complete(status, BTM_BR_INQUIRY_MASK);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_inquiry_result_evt
@@ -529,7 +526,6 @@ static void btu_hcif_connection_comp_evt (UINT8 *p)
 #endif /* BTM_SCO_INCLUDED */
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_connection_request_evt
@@ -563,7 +559,6 @@ static void btu_hcif_connection_request_evt (UINT8 *p)
 #endif /* BTM_SCO_INCLUDED */
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_disconnection_comp_evt
@@ -616,7 +611,6 @@ static void btu_hcif_authentication_comp_evt (UINT8 *p)
     btm_sec_auth_complete (handle, status);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_rmt_name_request_comp_evt
@@ -641,7 +635,6 @@ static void btu_hcif_rmt_name_request_comp_evt (UINT8 *p, UINT16 evt_len)
     btm_sec_rmt_name_request_complete (bd_addr, p, status);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_encryption_change_evt
@@ -719,7 +712,6 @@ static void btu_hcif_read_rmt_version_comp_evt (UINT8 *p)
     btm_read_remote_version_complete (p);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_qos_setup_comp_evt
@@ -747,7 +739,6 @@ static void btu_hcif_qos_setup_comp_evt (UINT8 *p)
     btm_qos_setup_complete(status, handle, &flow);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_esco_connection_comp_evt
@@ -781,7 +772,6 @@ static void btu_hcif_esco_connection_comp_evt (UINT8 *p)
 #endif
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_esco_connection_chg_evt
@@ -866,7 +856,6 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
 #endif
             break;
 
-
         case HCI_READ_INQ_TX_POWER_LEVEL:
             btm_read_linq_tx_power_complete (p);
             break;
@@ -980,7 +969,6 @@ static void btu_hcif_command_complete_evt(BT_HDR *response, void *context)
     fixed_queue_enqueue(btu_hci_msg_queue, event);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_hdl_command_status
@@ -1200,7 +1188,6 @@ static void btu_hcif_hardware_error_evt (UINT8 *p)
         BTM_DeviceReset (NULL);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_flush_occured_evt
@@ -1214,7 +1201,6 @@ static void btu_hcif_flush_occured_evt (void)
 {
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_role_change_evt
@@ -1238,7 +1224,6 @@ static void btu_hcif_role_change_evt (UINT8 *p)
     btm_acl_role_changed(status, bda, role);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_num_compl_data_pkts_evt
@@ -1326,7 +1311,6 @@ static void btu_hcif_pin_code_request_evt (UINT8 *p)
     btm_sec_pin_code_request (bda);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_link_key_request_evt
@@ -1344,7 +1328,6 @@ static void btu_hcif_link_key_request_evt (UINT8 *p)
     btm_sec_link_key_request (bda);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_link_key_notification_evt
@@ -1367,7 +1350,6 @@ static void btu_hcif_link_key_notification_evt (UINT8 *p)
     btm_sec_link_key_notification (bda, key, key_type);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_loopback_command_evt
@@ -1381,7 +1363,6 @@ static void btu_hcif_loopback_command_evt (void)
 {
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_data_buf_overflow_evt
@@ -1395,7 +1376,6 @@ static void btu_hcif_data_buf_overflow_evt (void)
 {
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_max_slots_changed_evt
@@ -1409,7 +1389,6 @@ static void btu_hcif_max_slots_changed_evt (void)
 {
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_read_clock_off_comp_evt
@@ -1440,7 +1419,6 @@ static void btu_hcif_read_clock_off_comp_evt (UINT8 *p)
     btm_sec_update_clock_offset (handle, clock_offset);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_conn_pkt_type_change_evt
@@ -1454,7 +1432,6 @@ static void btu_hcif_conn_pkt_type_change_evt (void)
 {
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_qos_violation_evt
@@ -1472,11 +1449,9 @@ static void btu_hcif_qos_violation_evt (UINT8 *p)
 
     handle = HCID_GET_HANDLE (handle);
 
-
     l2c_link_hci_qos_violation (handle);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_page_scan_mode_change_evt
@@ -1490,7 +1465,6 @@ static void btu_hcif_page_scan_mode_change_evt (void)
 {
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_page_scan_rep_mode_chng_evt
@@ -1536,7 +1510,6 @@ static void btu_hcif_io_cap_request_evt (UINT8 *p)
     btm_io_capabilities_req(p);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_io_cap_response_evt
@@ -1551,7 +1524,6 @@ static void btu_hcif_io_cap_response_evt (UINT8 *p)
     btm_io_capabilities_rsp(p);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_user_conf_request_evt
@@ -1566,7 +1538,6 @@ static void btu_hcif_user_conf_request_evt (UINT8 *p)
     btm_proc_sp_req_evt(BTM_SP_CFM_REQ_EVT, p);
 }
 
-
 /*******************************************************************************
 **
 ** Function         btu_hcif_user_passkey_request_evt
@@ -1658,7 +1629,6 @@ static void btu_hcif_enhanced_flush_complete_evt (void)
 ** End of Simple Pairing Events
 ***********************************************/
 
-
 /**********************************************
 ** BLE Events
 ***********************************************/
index 0888cb5..8e50b65 100644 (file)
 #define LOG_TAG "bt_task"
 
 #include <assert.h>
-
-#include "bt_target.h"
 #include <pthread.h>
 #include <string.h>
-#include "dyn_mem.h"
 
-#include "osi/include/alarm.h"
+#include "bt_target.h"
+#include "btm_int.h"
+#include "btu.h"
 #include "device/include/controller.h"
+#include "dyn_mem.h"
+#include "l2c_int.h"
+#include "osi/include/alarm.h"
 #include "osi/include/fixed_queue.h"
-#include "osi/include/hash_map.h"
-#include "btu.h"
-#include "btm_int.h"
 #include "osi/include/hash_functions.h"
-#include "sdpint.h"
-#include "osi/include/thread.h"
-#include "l2c_int.h"
+#include "osi/include/hash_map.h"
 #include "osi/include/log.h"
+#include "osi/include/thread.h"
+#include "sdpint.h"
 
 #if (BLE_INCLUDED == TRUE)
 #include "gatt_api.h"
@@ -198,7 +197,7 @@ void BTU_StartUp(void)
     return;
 
   error_exit:;
-    LOG_ERROR("%s Unable to allocate resources for bt_workqueue", __func__);
+    LOG_ERROR(LOG_TAG, "%s Unable to allocate resources for bt_workqueue", __func__);
     BTU_ShutDown();
 }
 
index e2b899e..a7861c7 100644 (file)
 #define LOG_TAG "bt_btu_task"
 
 #include <assert.h>
-#include <stdlib.h>
+#include <pthread.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
-#include "osi/include/alarm.h"
 #include "bt_target.h"
 #include "bt_trace.h"
 #include "bt_types.h"
 #include "bt_utils.h"
+#include "btcore/include/module.h"
 #include "btif_common.h"
 #include "btm_api.h"
 #include "btm_int.h"
 #include "btu.h"
-#include "osi/include/fixed_queue.h"
-#include "osi/include/future.h"
+#include "gap_int.h"
 #include "gki.h"
-#include "osi/include/hash_map.h"
 #include "hcimsgs.h"
 #include "l2c_int.h"
-#include "btcore/include/module.h"
-#include "osi/include/osi.h"
+#include "osi/include/alarm.h"
+#include "osi/include/fixed_queue.h"
+#include "osi/include/future.h"
+#include "osi/include/hash_map.h"
 #include "osi/include/log.h"
-#include "sdpint.h"
+#include "osi/include/osi.h"
 #include "osi/include/thread.h"
-
 #include "port_api.h"
 #include "port_ext.h"
-
-#include "gap_int.h"
+#include "sdpint.h"
 
 #if (defined(BNEP_INCLUDED) && BNEP_INCLUDED == TRUE)
 #include "bnep_int.h"
@@ -260,7 +259,7 @@ void btu_task_start_up(UNUSED_ATTR void *context) {
   BT_TRACE(TRACE_LAYER_BTU, TRACE_TYPE_API,
       "btu_task pending for preload complete event");
 
-  LOG_INFO("Bluetooth chip preload is complete");
+  LOG_INFO(LOG_TAG, "Bluetooth chip preload is complete");
 
   BT_TRACE(TRACE_LAYER_BTU, TRACE_TYPE_API,
       "btu_task received preload complete event");
@@ -372,7 +371,6 @@ static void btu_general_alarm_process(TIMER_LIST_ENT *p_tle) {
             break;
 #endif
 
-
 #if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
         case BTU_TTYPE_AVDT_CCB_RET:
         case BTU_TTYPE_AVDT_CCB_RSP:
@@ -461,7 +459,7 @@ void btu_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec) {
 
   alarm_t *alarm = hash_map_get(btu_general_alarm_hash_map, p_tle);
   if (alarm == NULL) {
-    LOG_ERROR("%s Unable to create alarm", __func__);
+    LOG_ERROR(LOG_TAG, "%s Unable to create alarm", __func__);
     return;
   }
   alarm_cancel(alarm);
@@ -492,7 +490,7 @@ void btu_stop_timer(TIMER_LIST_ENT *p_tle) {
   // Get the alarm for the timer list entry.
   alarm_t *alarm = hash_map_get(btu_general_alarm_hash_map, p_tle);
   if (alarm == NULL) {
-    LOG_WARN("%s Unable to find expected alarm in hashmap", __func__);
+    LOG_WARN(LOG_TAG, "%s Unable to find expected alarm in hashmap", __func__);
     return;
   }
   alarm_cancel(alarm);
@@ -541,7 +539,7 @@ void btu_start_quick_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_ti
 
   alarm_t *alarm = hash_map_get(btu_l2cap_alarm_hash_map, p_tle);
   if (alarm == NULL) {
-    LOG_ERROR("%s Unable to create alarm", __func__);
+    LOG_ERROR(LOG_TAG, "%s Unable to create alarm", __func__);
     return;
   }
   alarm_cancel(alarm);
@@ -572,7 +570,7 @@ void btu_stop_quick_timer(TIMER_LIST_ENT *p_tle) {
   // Get the alarm for the timer list entry.
   alarm_t *alarm = hash_map_get(btu_l2cap_alarm_hash_map, p_tle);
   if (alarm == NULL) {
-    LOG_WARN("%s Unable to find expected alarm in hashmap", __func__);
+    LOG_WARN(LOG_TAG, "%s Unable to find expected alarm in hashmap", __func__);
     return;
   }
   alarm_cancel(alarm);
@@ -603,7 +601,7 @@ void btu_start_timer_oneshot(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_
 
   alarm_t *alarm = hash_map_get(btu_oneshot_alarm_hash_map, p_tle);
   if (alarm == NULL) {
-    LOG_ERROR("%s Unable to create alarm", __func__);
+    LOG_ERROR(LOG_TAG, "%s Unable to create alarm", __func__);
     return;
   }
   alarm_cancel(alarm);
@@ -625,7 +623,7 @@ void btu_stop_timer_oneshot(TIMER_LIST_ENT *p_tle) {
   // Get the alarm for the timer list entry.
   alarm_t *alarm = hash_map_get(btu_oneshot_alarm_hash_map, p_tle);
   if (alarm == NULL) {
-    LOG_WARN("%s Unable to find expected alarm in hashmap", __func__);
+    LOG_WARN(LOG_TAG, "%s Unable to find expected alarm in hashmap", __func__);
     return;
   }
   alarm_cancel(alarm);
index 67b8922..6c6c5e7 100644 (file)
@@ -127,7 +127,6 @@ UINT16 GAP_ConnOpen (char *p_serv_name, UINT8 service_id, BOOLEAN is_server,
 {
     tGAP_CCB    *p_ccb;
     UINT16       cid;
-    tBT_UUID    bt_uuid = {2, {GAP_PROTOCOL_ID}};
 
     GAP_TRACE_EVENT ("GAP_CONN - Open Request");
 
@@ -235,7 +234,7 @@ UINT16 GAP_ConnOpen (char *p_serv_name, UINT8 service_id, BOOLEAN is_server,
             p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE;
 
         /* Check if L2CAP started the connection process */
-        if (p_rem_bda && ((cid = L2CA_CONNECT_REQ (p_ccb->psm, p_rem_bda, &p_ccb->ertm_info, &bt_uuid)) != 0))
+        if (p_rem_bda && ((cid = L2CA_CONNECT_REQ (p_ccb->psm, p_rem_bda, &p_ccb->ertm_info)) != 0))
         {
             p_ccb->connection_id = cid;
             return (p_ccb->gap_handle);
@@ -739,7 +738,6 @@ static void gap_connect_ind (BD_ADDR  bd_addr, UINT16 l2cap_cid, UINT16 psm, UIN
 {
     UINT16       xx;
     tGAP_CCB     *p_ccb;
-    tBT_UUID    bt_uuid = {2, {GAP_PROTOCOL_ID}};
 
     /* See if we have a CCB listening for the connection */
     for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
@@ -770,7 +768,7 @@ static void gap_connect_ind (BD_ADDR  bd_addr, UINT16 l2cap_cid, UINT16 psm, UIN
     p_ccb->connection_id = l2cap_cid;
 
     /* Send response to the L2CAP layer. */
-    L2CA_CONNECT_RSP (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK, &p_ccb->ertm_info, &bt_uuid);
+    L2CA_CONNECT_RSP (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK, &p_ccb->ertm_info);
 
     GAP_TRACE_EVENT("GAP_CONN - Rcvd L2CAP conn ind, CID: 0x%x", p_ccb->connection_id);
 
index a175129..659a864 100644 (file)
@@ -485,7 +485,6 @@ static void gatt_cl_start_config_ccc(tGATT_PROFILE_CLCB *p_clcb)
 *******************************************************************************/
 void GATT_ConfigServiceChangeCCC (BD_ADDR remote_bda, BOOLEAN enable, tBT_TRANSPORT transport)
 {
-    UINT16              conn_id = GATT_INVALID_CONN_ID;
     tGATT_PROFILE_CLCB   *p_clcb = gatt_profile_find_clcb_by_bd_addr (remote_bda, transport);
 
     if (p_clcb == NULL)
index 0cc6976..7b3db4a 100644 (file)
@@ -43,6 +43,8 @@
 #include "hidh_int.h"
 #include "bt_utils.h"
 
+#include "osi/include/osi.h"
+
 static UINT8 find_conn_by_cid (UINT16 cid);
 static void hidh_conn_retry (UINT8 dhandle);
 
@@ -301,10 +303,16 @@ static void hidh_l2cif_connect_ind (BD_ADDR  bd_addr, UINT16 l2cap_cid, UINT16 p
 *******************************************************************************/
 void hidh_proc_repage_timeout (TIMER_LIST_ENT *p_tle)
 {
-    hidh_conn_initiate( (UINT8) p_tle->param ) ;
-    hh_cb.devices[p_tle->param].conn_tries++;
-    hh_cb.callback( (UINT8) p_tle->param, hh_cb.devices[p_tle->param].addr,
-                    HID_HDEV_EVT_RETRYING, hh_cb.devices[p_tle->param].conn_tries, NULL ) ;
+    tHID_HOST_DEV_CTB *device;
+    UINT8 dhandle = PTR_TO_UINT(p_tle->param);
+
+    hidh_conn_initiate(dhandle);
+
+    device = &hh_cb.devices[dhandle];
+    device->conn_tries++;
+
+    hh_cb.callback(dhandle, device->addr, HID_HDEV_EVT_RETRYING,
+                   device->conn_tries, NULL ) ;
 }
 
 /*******************************************************************************
@@ -321,11 +329,12 @@ void hidh_sec_check_complete_orig (BD_ADDR bd_addr, tBT_TRANSPORT transport, voi
 {
     tHID_HOST_DEV_CTB *p_dev = (tHID_HOST_DEV_CTB *) p_ref_data;
     UINT8 dhandle;
-    UINT32 reason;
     UNUSED(bd_addr);
     UNUSED (transport);
 
-    dhandle = ((UINT32)p_dev - (UINT32)&(hh_cb.devices[0]))/ sizeof(tHID_HOST_DEV_CTB);
+    // TODO(armansito): This kind of math to determine a device handle is way
+    // too dirty and unnecessary. Why can't |p_dev| store it's handle?
+    dhandle = (PTR_TO_UINT(p_dev) - PTR_TO_UINT(&(hh_cb.devices[0])))/ sizeof(tHID_HOST_DEV_CTB);
     if( res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY )
     {
         HIDH_TRACE_EVENT ("HID-Host Originator security pass.");
@@ -653,7 +662,7 @@ static void hidh_l2cif_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed)
             (hh_cb.devices[dhandle].attr_mask & HID_NORMALLY_CONNECTABLE))
         {
             hh_cb.devices[dhandle].conn_tries = 0;
-            hh_cb.devices[dhandle].conn.timer_entry.param = (UINT32) dhandle;
+            hh_cb.devices[dhandle].conn.timer_entry.param = UINT_TO_PTR(dhandle);
             btu_start_timer (&(hh_cb.devices[dhandle].conn.timer_entry), BTU_TTYPE_HID_HOST_REPAGE_TO, HID_HOST_REPAGE_WIN);
             hh_cb.callback( dhandle,  hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, disc_res, NULL);
         }
@@ -1086,7 +1095,7 @@ static void hidh_conn_retry(  UINT8 dhandle )
     tHID_HOST_DEV_CTB *p_dev = &hh_cb.devices[dhandle];
 
     p_dev->conn.conn_state = HID_CONN_STATE_UNUSED;
-    p_dev->conn.timer_entry.param = (UINT32) dhandle;
+    p_dev->conn.timer_entry.param = UINT_TO_PTR(dhandle);
 #if (HID_HOST_REPAGE_WIN > 0)
     btu_start_timer (&(p_dev->conn.timer_entry), BTU_TTYPE_HID_HOST_REPAGE_TO, HID_HOST_REPAGE_WIN);
 #else
index d6ff8a0..e3e7f6e 100644 (file)
@@ -24,6 +24,8 @@
 #ifndef _AVRC_DEFS_H
 #define _AVRC_DEFS_H
 
+#include "stack/include/bt_types.h"
+
 /*****************************************************************************
 **  constants
 *****************************************************************************/
 #define AVRC_STS_ADDR_PLAYER_CHG 0x16   /* Addressed Player Changed - Register Notification */
 typedef UINT8 tAVRC_STS;
 
-
 /* Define the Capability IDs
 */
 #define AVRC_CAP_COMPANY_ID                     0x02
@@ -864,7 +865,6 @@ typedef union
 #define AVRC_MAX_CHARSET_SIZE       16
 #define AVRC_MAX_ELEM_ATTR_SIZE     8
 
-
 /*****************************************************************************
 **  Metadata transfer Building/Parsing definitions
 *****************************************************************************/
@@ -880,7 +880,6 @@ typedef struct {
     UINT8               *p_str;
 } tAVRC_NAME;
 
-
 #ifndef AVRC_CAP_MAX_NUM_COMP_ID
 #define AVRC_CAP_MAX_NUM_COMP_ID    4
 #endif
@@ -1375,7 +1374,6 @@ typedef struct
     UINT32              num_items;
 } tAVRC_SEARCH_RSP;
 
-
 typedef struct
 {
     UINT8       pdu;
@@ -1413,5 +1411,4 @@ typedef union
     tAVRC_RSP                       add_to_play;            /* AddToNowPlaying */
 } tAVRC_RESPONSE;
 
-
 #endif
index 0a91d5f..cc76fd4 100644 (file)
@@ -387,67 +387,73 @@ typedef struct
 }tBTM_BLE_INT_RANGE;
 
 /* Service tag supported in the device */
+#define MAX_16BIT_SERVICES 16
 typedef struct
 {
     UINT8       num_service;
     BOOLEAN     list_cmpl;
-    UINT16      *p_uuid;
+    UINT16      uuid[MAX_16BIT_SERVICES];
 }tBTM_BLE_SERVICE;
 
 /* 32 bits Service supported in the device */
+#define MAX_32BIT_SERVICES 4
 typedef struct
 {
     UINT8       num_service;
     BOOLEAN     list_cmpl;
-    UINT32      *p_uuid;
+    UINT32      uuid[MAX_32BIT_SERVICES];
 }tBTM_BLE_32SERVICE;
 
 /* 128 bits Service supported in the device */
 typedef struct
 {
+    UINT8       num_service;
     BOOLEAN     list_cmpl;
     UINT8       uuid128[MAX_UUID_SIZE];
 }tBTM_BLE_128SERVICE;
 
+#define MAX_SIZE_MANUFACTURER_DATA 32
 typedef struct
 {
-    UINT8       len;
-    UINT8      *p_val;
+    UINT8 len;
+    UINT8 val[MAX_SIZE_MANUFACTURER_DATA];
 }tBTM_BLE_MANU;
 
-
+#define MAX_SIZE_SERVICE_DATA 32
 typedef struct
 {
     tBT_UUID    service_uuid;
     UINT8       len;
-    UINT8      *p_val;
+    UINT8       val[MAX_SIZE_SERVICE_DATA];
 }tBTM_BLE_SERVICE_DATA;
 
+#define MAX_SIZE_PROPRIETARY_ELEMENT 32
 typedef struct
 {
     UINT8       adv_type;
     UINT8       len;
-    UINT8       *p_val;     /* number of len byte */
+    UINT8       val[MAX_SIZE_PROPRIETARY_ELEMENT];     /* number of len byte */
 }tBTM_BLE_PROP_ELEM;
 
+#define MAX_PROPRIETARY_ELEMENTS 4
 typedef struct
 {
     UINT8                   num_elem;
-    tBTM_BLE_PROP_ELEM      *p_elem;
+    tBTM_BLE_PROP_ELEM      elem[MAX_PROPRIETARY_ELEMENTS];
 }tBTM_BLE_PROPRIETARY;
 
 typedef struct
 {
     tBTM_BLE_INT_RANGE      int_range;      /* slave prefered conn interval range */
-    tBTM_BLE_MANU           *p_manu;           /* manufactuer data */
-    tBTM_BLE_SERVICE        *p_services;       /* services */
-    tBTM_BLE_128SERVICE     *p_services_128b;  /* 128 bits service */
-    tBTM_BLE_32SERVICE      *p_service_32b;     /* 32 bits Service UUID */
-    tBTM_BLE_SERVICE        *p_sol_services;    /* 16 bits services Solicitation UUIDs */
-    tBTM_BLE_32SERVICE      *p_sol_service_32b;    /* List of 32 bit Service Solicitation UUIDs */
-    tBTM_BLE_128SERVICE     *p_sol_service_128b;    /* List of 128 bit Service Solicitation UUIDs */
-    tBTM_BLE_PROPRIETARY    *p_proprietary;
-    tBTM_BLE_SERVICE_DATA   *p_service_data;    /* service data */
+    tBTM_BLE_MANU           manu;           /* manufactuer data */
+    tBTM_BLE_SERVICE        services;       /* services */
+    tBTM_BLE_128SERVICE     services_128b;  /* 128 bits service */
+    tBTM_BLE_32SERVICE      service_32b;     /* 32 bits Service UUID */
+    tBTM_BLE_SERVICE        sol_services;    /* 16 bits services Solicitation UUIDs */
+    tBTM_BLE_32SERVICE      sol_service_32b;    /* List of 32 bit Service Solicitation UUIDs */
+    tBTM_BLE_128SERVICE     sol_service_128b;    /* List of 128 bit Service Solicitation UUIDs */
+    tBTM_BLE_PROPRIETARY    proprietary;
+    tBTM_BLE_SERVICE_DATA   service_data;    /* service data */
     UINT16                  appearance;
     UINT8                   flag;
     UINT8                   tx_power;
index 837dbc8..b431d56 100644 (file)
@@ -319,8 +319,8 @@ typedef struct
 
 #define L2CA_REGISTER(a,b,c)        L2CA_Register(a,(tL2CAP_APPL_INFO *)b)
 #define L2CA_DEREGISTER(a)          L2CA_Deregister(a)
-#define L2CA_CONNECT_REQ(a,b,c,d)   L2CA_ErtmConnectReq(a,b,c)
-#define L2CA_CONNECT_RSP(a,b,c,d,e,f,g) L2CA_ErtmConnectRsp(a,b,c,d,e,f)
+#define L2CA_CONNECT_REQ(a,b,c)   L2CA_ErtmConnectReq(a,b,c)
+#define L2CA_CONNECT_RSP(a,b,c,d,e,f) L2CA_ErtmConnectRsp(a,b,c,d,e,f)
 #define L2CA_CONFIG_REQ(a,b)        L2CA_ConfigReq(a,b)
 #define L2CA_CONFIG_RSP(a,b)        L2CA_ConfigRsp(a,b)
 #define L2CA_DISCONNECT_REQ(a)      L2CA_DisconnectReq(a)
index e01a261..9495729 100644 (file)
 #define LOG_TAG "bt_l2cap"
 
 #include <assert.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stdio.h>
 
-#include "gki.h"
 #include "bt_types.h"
 #include "btcore/include/counter.h"
+#include "btm_api.h"
+#include "btu.h"
+#include "gki.h"
 #include "hcidefs.h"
 #include "hcimsgs.h"
-#include "l2cdefs.h"
 #include "l2c_int.h"
-#include "btu.h"
-#include "btm_api.h"
+#include "l2cdefs.h"
 #include "osi/include/allocator.h"
 #include "osi/include/log.h"
 
@@ -112,8 +112,6 @@ UINT16 L2CA_Register (UINT16 psm, tL2CAP_APPL_INFO *p_cb_info)
     return (vpsm);
 }
 
-
-
 /*******************************************************************************
 **
 ** Function         L2CA_Deregister
@@ -347,7 +345,7 @@ bool L2CA_SetConnectionCallbacks(uint16_t local_cid, const tL2CAP_APPL_INFO *cal
 
   tL2C_CCB *channel_control_block = l2cu_find_ccb_by_cid(NULL, local_cid);
   if (!channel_control_block) {
-    LOG_ERROR("%s no channel control block found for L2CAP LCID=0x%04x.", __func__, local_cid);
+    LOG_ERROR(LOG_TAG, "%s no channel control block found for L2CAP LCID=0x%04x.", __func__, local_cid);
     return false;
   }
 
@@ -359,7 +357,7 @@ bool L2CA_SetConnectionCallbacks(uint16_t local_cid, const tL2CAP_APPL_INFO *cal
   if (!channel_control_block->should_free_rcb) {
     registration_control_block = (tL2C_RCB *)osi_calloc(sizeof(tL2C_RCB));
     if (!registration_control_block) {
-      LOG_ERROR("%s unable to allocate registration control block.", __func__);
+      LOG_ERROR(LOG_TAG, "%s unable to allocate registration control block.", __func__);
       return false;
     }
 
@@ -389,7 +387,6 @@ BOOLEAN L2CA_ConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid,
     return L2CA_ErtmConnectRsp (p_bd_addr, id, lcid, result, status, NULL);
 }
 
-
 /*******************************************************************************
 **
 ** Function         L2CA_ErtmConnectRsp
@@ -475,7 +472,6 @@ BOOLEAN L2CA_ErtmConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 re
     return (TRUE);
 }
 
-
 /*******************************************************************************
 **
 ** Function         L2CA_ConfigReq
@@ -528,7 +524,6 @@ BOOLEAN L2CA_ConfigReq (UINT16 cid, tL2CAP_CFG_INFO *p_cfg)
     return (TRUE);
 }
 
-
 /*******************************************************************************
 **
 ** Function         L2CA_ConfigRsp
@@ -574,7 +569,6 @@ BOOLEAN L2CA_ConfigRsp (UINT16 cid, tL2CAP_CFG_INFO *p_cfg)
     return (TRUE);
 }
 
-
 /*******************************************************************************
 **
 ** Function         L2CA_DisconnectReq
@@ -888,7 +882,6 @@ UINT8 L2CA_SetTraceLevel (UINT8 new_level)
     return (l2cb.l2cap_trace_level);
 }
 
-
 /*******************************************************************************
 **
 ** Function     L2CA_SetDesireRole
@@ -1084,7 +1077,6 @@ BOOLEAN L2CA_SendTestSFrame (UINT16 cid, UINT8 sup_type, UINT8 back_track)
     return (TRUE);
 }
 
-
 /*******************************************************************************
 **
 ** Function         L2CA_SetTxPriority
index 9aff917..93f10fd 100644 (file)
@@ -263,7 +263,6 @@ void l2cble_notify_le_connection (BD_ADDR bda)
 void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
                                UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
 {
-    int i;
     tL2C_LCB            *p_lcb;
     tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_or_alloc_dev (bda);
 
@@ -372,7 +371,6 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
 void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
                                   UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
 {
-    int i;
     tL2C_LCB            *p_lcb;
     tBTM_SEC_DEV_REC    *p_dev_rec;
     UNUSED(type);
@@ -480,9 +478,13 @@ void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE typ
 static void l2cble_start_conn_update (tL2C_LCB *p_lcb)
 {
     UINT16 min_conn_int, max_conn_int, slave_latency, supervision_tout;
-    tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev(p_lcb->remote_bd_addr);
     tACL_CONN *p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE);
 
+    // TODO(armansito): The return value of this call wasn't being used but the
+    // logic of this function might be depending on its side effects. We should
+    // verify if this call is needed at all and remove it otherwise.
+    btm_find_or_alloc_dev(p_lcb->remote_bd_addr);
+
     if (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) return;
 
     if (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE)
index fcc53d5..047815a 100644 (file)
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_l2c_main"
+
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stdio.h>
 
-#include "device/include/controller.h"
-#include "btcore/include/counter.h"
 #include "bt_target.h"
+#include "btcore/include/counter.h"
 #include "btm_int.h"
 #include "btu.h"
+#include "device/include/controller.h"
 #include "gki.h"
 #include "hcimsgs.h"
 #include "l2c_api.h"
@@ -108,7 +110,6 @@ void l2c_bcst_msg( BT_HDR *p_buf, UINT16 psm )
     }
 }
 
-
 /*******************************************************************************
 **
 ** Function         l2c_rcv_acl_data
@@ -678,7 +679,6 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
             }
             break;
 
-
         case L2CAP_CMD_DISC_REQ:
             STREAM_TO_UINT16 (lcid, p);
             STREAM_TO_UINT16 (rcid, p);
@@ -761,7 +761,6 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
 #endif
             }
 
-
 #if (L2CAP_NUM_FIXED_CHNLS > 0)
             if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE)
             {
@@ -837,7 +836,6 @@ void l2c_process_held_packets(BOOLEAN timed_out) {
         btu_start_timer (&l2cb.rcv_hold_tle, BTU_TTYPE_L2CAP_HOLD, BT_1SEC_TIMEOUT);
 }
 
-
 /*******************************************************************************
 **
 ** Function         l2c_init
@@ -867,7 +865,6 @@ void l2c_init (void)
     l2cb.non_flushable_pbf = L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT;
 #endif
 
-
     l2cb.p_free_ccb_first = &l2cb.ccb_pool[0];
     l2cb.p_free_ccb_last  = &l2cb.ccb_pool[MAX_L2CAP_CHANNELS - 1];
 
@@ -903,7 +900,7 @@ void l2c_init (void)
 
     l2cb.rcv_pending_q = list_new(NULL);
     if (l2cb.rcv_pending_q == NULL)
-        LOG_ERROR("%s unable to allocate memory for link layer control block", __func__);
+        LOG_ERROR(LOG_TAG, "%s unable to allocate memory for link layer control block", __func__);
 }
 
 void l2c_free(void) {
index 95b8e01..af7990b 100644 (file)
@@ -18,6 +18,8 @@
 
 #define LOG_TAG "bt_l2cap_client"
 
+#include "stack/include/l2cap_client.h"
+
 #include <assert.h>
 #include <string.h>
 
@@ -28,7 +30,6 @@
 #include "osi/include/list.h"
 #include "osi/include/log.h"
 #include "osi/include/osi.h"
-#include "stack/include/l2cap_client.h"
 #include "stack/include/l2c_api.h"
 
 struct l2cap_client_t {
@@ -92,14 +93,14 @@ l2cap_client_t *l2cap_client_new(const l2cap_client_callbacks_t *callbacks, void
   if (!l2cap_clients) {
     l2cap_clients = list_new(NULL);
     if (!l2cap_clients) {
-      LOG_ERROR("%s unable to allocate space for L2CAP client list.", __func__);
+      LOG_ERROR(LOG_TAG, "%s unable to allocate space for L2CAP client list.", __func__);
       return NULL;
     }
   }
 
   l2cap_client_t *ret = (l2cap_client_t *)osi_calloc(sizeof(l2cap_client_t));
   if (!ret) {
-    LOG_ERROR("%s unable to allocate L2CAP client.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate L2CAP client.", __func__);
     goto error;
   }
 
@@ -109,7 +110,7 @@ l2cap_client_t *l2cap_client_new(const l2cap_client_callbacks_t *callbacks, void
   ret->remote_mtu = L2CAP_MTU_DEFAULT;
   ret->outbound_fragments = list_new(NULL);
   if (!ret) {
-    LOG_ERROR("%s unable to allocate outbound L2CAP fragment list.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to allocate outbound L2CAP fragment list.", __func__);
     goto error;
   }
 
@@ -144,7 +145,7 @@ bool l2cap_client_connect(l2cap_client_t *client, const bt_bdaddr_t *remote_bdad
 
   client->local_channel_id = L2CA_ConnectReq(psm, (uint8_t *)remote_bdaddr);
   if (!client->local_channel_id) {
-    LOG_ERROR("%s unable to create L2CAP connection.", __func__);
+    LOG_ERROR(LOG_TAG, "%s unable to create L2CAP connection.", __func__);
     return false;
   }
 
@@ -156,7 +157,7 @@ void l2cap_client_disconnect(l2cap_client_t *client) {
   assert(client != NULL);
 
   if (client->local_channel_id && !L2CA_DisconnectReq(client->local_channel_id))
-    LOG_ERROR("%s unable to send disconnect message for LCID 0x%04x.", __func__, client->local_channel_id);
+    LOG_ERROR(LOG_TAG, "%s unable to send disconnect message for LCID 0x%04x.", __func__, client->local_channel_id);
 
   client->local_channel_id = 0;
   client->remote_mtu = L2CAP_MTU_DEFAULT;
@@ -194,12 +195,12 @@ static void connect_completed_cb(uint16_t local_channel_id, uint16_t error_code)
 
   l2cap_client_t *client = find(local_channel_id);
   if (!client) {
-    LOG_ERROR("%s unable to find L2CAP client for LCID 0x%04x.", __func__, local_channel_id);
+    LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client for LCID 0x%04x.", __func__, local_channel_id);
     return;
   }
 
   if (error_code != L2CAP_CONN_OK) {
-    LOG_ERROR("%s error connecting L2CAP channel: %d.", __func__, error_code);
+    LOG_ERROR(LOG_TAG, "%s error connecting L2CAP channel: %d.", __func__, error_code);
     client->callbacks.disconnected(client, client->context);
     return;
   }
@@ -207,7 +208,7 @@ static void connect_completed_cb(uint16_t local_channel_id, uint16_t error_code)
   // Use default L2CAP parameters.
   tL2CAP_CFG_INFO desired_parameters = { 0 };
   if (!L2CA_ConfigReq(local_channel_id, &desired_parameters)) {
-    LOG_ERROR("%s error sending L2CAP config parameters.", __func__);
+    LOG_ERROR(LOG_TAG, "%s error sending L2CAP config parameters.", __func__);
     client->callbacks.disconnected(client, client->context);
   }
 }
@@ -217,7 +218,7 @@ static void config_request_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *reques
   l2cap_client_t *client = find(local_channel_id);
 
   if (!client) {
-    LOG_ERROR("%s unable to find L2CAP client matching LCID 0x%04x.", __func__, local_channel_id);
+    LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client matching LCID 0x%04x.", __func__, local_channel_id);
     return;
   }
 
@@ -245,7 +246,7 @@ static void config_request_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *reques
   }
 
   if (!L2CA_ConfigRsp(local_channel_id, &response)) {
-    LOG_ERROR("%s unable to send config response for LCID 0x%04x.", __func__, local_channel_id);
+    LOG_ERROR(LOG_TAG, "%s unable to send config response for LCID 0x%04x.", __func__, local_channel_id);
     l2cap_client_disconnect(client);
     return;
   }
@@ -260,7 +261,7 @@ static void config_completed_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *nego
   l2cap_client_t *client = find(local_channel_id);
 
   if (!client) {
-    LOG_ERROR("%s unable to find L2CAP client matching LCID 0x%04x.", __func__, local_channel_id);
+    LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client matching LCID 0x%04x.", __func__, local_channel_id);
     return;
   }
 
@@ -271,7 +272,7 @@ static void config_completed_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *nego
 
     case L2CAP_CFG_UNACCEPTABLE_PARAMS:
       // TODO: see if we can renegotiate parameters instead of dropping the connection.
-      LOG_WARN("%s dropping L2CAP connection due to unacceptable config parameters.", __func__);
+      LOG_WARN(LOG_TAG, "%s dropping L2CAP connection due to unacceptable config parameters.", __func__);
       l2cap_client_disconnect(client);
       break;
 
@@ -284,7 +285,7 @@ static void config_completed_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *nego
 
     // Failure, no further parameter negotiation possible.
     default:
-      LOG_WARN("%s L2CAP parameter negotiation failed with error code %d.", __func__, negotiated_parameters->result);
+      LOG_WARN(LOG_TAG, "%s L2CAP parameter negotiation failed with error code %d.", __func__, negotiated_parameters->result);
       l2cap_client_disconnect(client);
       break;
   }
@@ -293,7 +294,7 @@ static void config_completed_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *nego
 static void disconnect_request_cb(uint16_t local_channel_id, bool ack_required) {
   l2cap_client_t *client = find(local_channel_id);
   if (!client) {
-    LOG_ERROR("%s unable to find L2CAP client with LCID 0x%04x.", __func__, local_channel_id);
+    LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client with LCID 0x%04x.", __func__, local_channel_id);
     return;
   }
 
@@ -312,7 +313,7 @@ static void disconnect_completed_cb(uint16_t local_channel_id, UNUSED_ATTR uint1
 
   l2cap_client_t *client = find(local_channel_id);
   if (!client) {
-    LOG_ERROR("%s unable to find L2CAP client with LCID 0x%04x.", __func__, local_channel_id);
+    LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client with LCID 0x%04x.", __func__, local_channel_id);
     return;
   }
 
@@ -327,7 +328,7 @@ static void congestion_cb(uint16_t local_channel_id, bool is_congested) {
 
   l2cap_client_t *client = find(local_channel_id);
   if (!client) {
-    LOG_ERROR("%s unable to find L2CAP client matching LCID 0x%04x.", __func__, local_channel_id);
+    LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client matching LCID 0x%04x.", __func__, local_channel_id);
     return;
   }
 
@@ -348,7 +349,7 @@ static void read_ready_cb(uint16_t local_channel_id, BT_HDR *packet) {
 
   l2cap_client_t *client = find(local_channel_id);
   if (!client) {
-    LOG_ERROR("%s unable to find L2CAP client matching LCID 0x%04x.", __func__, local_channel_id);
+    LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client matching LCID 0x%04x.", __func__, local_channel_id);
     return;
   }
 
@@ -412,7 +413,7 @@ static void dispatch_fragments(l2cap_client_t *client) {
         return;
 
       case L2CAP_DW_FAILED:
-        LOG_ERROR("%s error writing data to L2CAP connection LCID 0x%04x; disconnecting.", __func__, client->local_channel_id);
+        LOG_ERROR(LOG_TAG, "%s error writing data to L2CAP connection LCID 0x%04x; disconnecting.", __func__, client->local_channel_id);
         l2cap_client_disconnect(client);
         return;
 
index 73ced16..5fa5013 100644 (file)
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_port_api"
+
+#include "port_api.h"
+
 #include <string.h>
-#include "bt_target.h"
+
 #include "btcore/include/counter.h"
+#include "btm_api.h"
+#include "btm_int.h"
 #include "gki.h"
-#include "rfcdefs.h"
-#include "port_api.h"
+#include "l2c_api.h"
+#include "osi/include/log.h"
 #include "port_int.h"
-#include "btm_int.h"
-#include "btm_api.h"
 #include "rfc_int.h"
-#include "l2c_api.h"
+#include "rfcdefs.h"
 #include "sdp_api.h"
-#include "osi/include/log.h"
 
 /* duration of break in 200ms units */
 #define PORT_BREAK_DURATION     1
 
-#define info(fmt, ...)  LOG_INFO ("%s: " fmt,__FUNCTION__,  ## __VA_ARGS__)
-#define debug(fmt, ...) LOG_DEBUG ("%s: " fmt,__FUNCTION__,  ## __VA_ARGS__)
-#define error(fmt, ...) LOG_ERROR ("## ERROR : %s: " fmt "##",__FUNCTION__,  ## __VA_ARGS__)
-#define asrt(s) if(!(s)) LOG_ERROR ("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__)
+#define info(fmt, ...)  LOG_INFO(LOG_TAG, "%s: " fmt,__FUNCTION__,  ## __VA_ARGS__)
+#define debug(fmt, ...) LOG_DEBUG(LOG_TAG, "%s: " fmt,__FUNCTION__,  ## __VA_ARGS__)
+#define error(fmt, ...) LOG_ERROR(LOG_TAG, "## ERROR : %s: " fmt "##",__FUNCTION__,  ## __VA_ARGS__)
+#define asrt(s) if(!(s)) LOG_ERROR(LOG_TAG, "## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__)
 
 /* Mapping from PORT_* result codes to human readable strings. */
 static const char *result_code_strings[] = {
@@ -229,7 +232,6 @@ int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, BOOLEAN is_server,
     return port_open_continue (p_port);
 }
 
-
 /*******************************************************************************
 **
 ** Function         RFCOMM_RemoveConnection
@@ -445,8 +447,6 @@ int PORT_SetDataCOCallback (UINT16 port_handle, tPORT_DATA_CO_CALLBACK *p_port_c
     return (PORT_SUCCESS);
 }
 
-
-
 /*******************************************************************************
 **
 ** Function         PORT_SetEventMask
@@ -481,7 +481,6 @@ int PORT_SetEventMask (UINT16 port_handle, UINT32 mask)
     return (PORT_SUCCESS);
 }
 
-
 /*******************************************************************************
 **
 ** Function         PORT_CheckConnection
@@ -717,7 +716,6 @@ int PORT_GetState (UINT16 handle, tPORT_STATE *p_settings)
     return (PORT_SUCCESS);
 }
 
-
 /*******************************************************************************
 **
 ** Function         PORT_Control
@@ -803,7 +801,6 @@ int PORT_Control (UINT16 handle, UINT8 signal)
     return (PORT_SUCCESS);
 }
 
-
 /*******************************************************************************
 **
 ** Function         PORT_FlowControl
@@ -961,7 +958,6 @@ int PORT_FlowControl_MaxCredit (UINT16 handle, BOOLEAN enable)
     return (PORT_SUCCESS);
 }
 
-
 /*******************************************************************************
 **
 ** Function         PORT_GetModemStatus
@@ -998,7 +994,6 @@ int PORT_GetModemStatus (UINT16 handle, UINT8 *p_signal)
     return (PORT_SUCCESS);
 }
 
-
 /*******************************************************************************
 **
 ** Function         PORT_ClearError
@@ -1043,7 +1038,6 @@ int PORT_ClearError (UINT16 handle, UINT16 *p_errors, tPORT_STATUS *p_status)
     return (PORT_SUCCESS);
 }
 
-
 /*******************************************************************************
 **
 ** Function         PORT_SendError
@@ -1081,7 +1075,6 @@ int PORT_SendError (UINT16 handle, UINT8 errors)
     return (PORT_SUCCESS);
 }
 
-
 /*******************************************************************************
 **
 ** Function         PORT_GetQueueStatus
@@ -1130,7 +1123,6 @@ int PORT_GetQueueStatus (UINT16 handle, tPORT_STATUS *p_status)
     return (PORT_SUCCESS);
 }
 
-
 /*******************************************************************************
 **
 ** Function         PORT_Purge
@@ -1206,7 +1198,6 @@ int PORT_Purge (UINT16 handle, UINT8 purge_flags)
     return (PORT_SUCCESS);
 }
 
-
 /*******************************************************************************
 **
 ** Function         PORT_ReadData
@@ -1314,7 +1305,6 @@ int PORT_ReadData (UINT16 handle, char *p_data, UINT16 max_len, UINT16 *p_len)
     return (PORT_SUCCESS);
 }
 
-
 /*******************************************************************************
 **
 ** Function         PORT_Read
@@ -1372,7 +1362,6 @@ int PORT_Read (UINT16 handle, BT_HDR **pp_buf)
     return (PORT_SUCCESS);
 }
 
-
 /*******************************************************************************
 **
 ** Function         port_write
@@ -1628,7 +1617,6 @@ int PORT_WriteDataCO (UINT16 handle, int* p_len)
             return (PORT_UNKNOWN_ERROR);
         }
 
-
         RFCOMM_TRACE_EVENT ("PORT_WriteData %d bytes", length);
 
         rc = port_write (p_port, p_buf);
@@ -1658,8 +1646,6 @@ int PORT_WriteDataCO (UINT16 handle, int* p_len)
     return (PORT_SUCCESS);
 }
 
-
-
 /*******************************************************************************
 **
 ** Function         PORT_WriteData
@@ -1784,7 +1770,6 @@ int PORT_WriteData (UINT16 handle, char *p_data, UINT16 max_len, UINT16 *p_len)
     return (PORT_SUCCESS);
 }
 
-
 /*******************************************************************************
 **
 ** Function         PORT_Test
index e2cff28..0014c9b 100644 (file)
@@ -224,7 +224,7 @@ void rfc_timer_start (tRFC_MCB *p_mcb, UINT16 timeout)
 
     RFCOMM_TRACE_EVENT ("rfc_timer_start - timeout:%d", timeout);
 
-    p_tle->param = (UINT32)p_mcb;
+    p_tle->param = p_mcb;
 
     btu_start_timer (p_tle, BTU_TTYPE_RFCOMM_MFC, timeout);
 }
@@ -258,7 +258,7 @@ void rfc_port_timer_start (tPORT *p_port, UINT16 timeout)
 
     RFCOMM_TRACE_EVENT ("rfc_port_timer_start - timeout:%d", timeout);
 
-    p_tle->param = (UINT32)p_port;
+    p_tle->param = p_port;
 
     btu_start_timer (p_tle, BTU_TTYPE_RFCOMM_PORT, timeout);
 }
index 6e84ded..5a69816 100644 (file)
@@ -37,6 +37,8 @@
 #include "sdpint.h"
 #include "btu.h"
 
+#include "osi/include/osi.h"
+
 /**********************************************************************
 **   C L I E N T    F U N C T I O N    P R O T O T Y P E S            *
 ***********************************************************************/
@@ -73,7 +75,7 @@ BOOLEAN SDP_InitDiscoveryDb (tSDP_DISCOVERY_DB *p_db, UINT32 len, UINT16 num_uui
         num_attr > SDP_MAX_ATTR_FILTERS || num_uuid > SDP_MAX_UUID_FILTERS)
     {
         SDP_TRACE_ERROR("SDP_InitDiscoveryDb Illegal param: p_db 0x%x, len %d, num_uuid %d, num_attr %d",
-                         (UINT32)p_db, len, num_uuid, num_attr);
+                        PTR_TO_UINT(p_db), len, num_uuid, num_attr);
 
         return(FALSE);
     }
index 3cf4397..6d7da74 100644 (file)
@@ -122,7 +122,7 @@ tCONN_CB *sdpu_allocate_ccb (void)
         {
             memset (p_ccb, 0, sizeof (tCONN_CB));
 
-            p_ccb->timer_entry.param = (UINT32) p_ccb;
+            p_ccb->timer_entry.param = p_ccb;
 
             return (p_ccb);
         }
index 4a1e1bb..8cfbd70 100644 (file)
  *
  ******************************************************************************/
 
+#define LOG_TAG "bt_srvc"
+
 #include "bt_target.h"
 #include "bt_utils.h"
 #include "gatt_api.h"
 #include "gatt_int.h"
-#include "srvc_eng_int.h"
-#include "srvc_dis_int.h"
-
-#define LOG_TAG "bt_srvc"
 #include "osi/include/log.h"
+#include "srvc_dis_int.h"
+#include "srvc_eng_int.h"
 
 #if BLE_INCLUDED == TRUE
 
@@ -42,8 +42,6 @@
 #define STREAM_TO_UINT64(u64, p) {u64 = (((UINT64)(*(p))) + ((((UINT64)(*((p) + 1)))) << 8) + ((((UINT64)(*((p) + 2)))) << 16) + ((((UINT64)(*((p) + 3)))) << 24) \
                                   + ((((UINT64)(*((p) + 4)))) << 32) + ((((UINT64)(*((p) + 5)))) << 40) + ((((UINT64)(*((p) + 6)))) << 48) + ((((UINT64)(*((p) + 7)))) << 56)); (p) += 8;}
 
-
-
 static const UINT16  dis_attr_uuid[DIS_MAX_CHAR_NUM] =
 {
     GATT_UUID_SYSTEM_ID,
@@ -169,7 +167,6 @@ UINT8 dis_read_attr_value (UINT8 clcb_idx, UINT16 handle, tGATT_VALUE *p_value,
                     }
                     break;
 
-
                 case GATT_UUID_SYSTEM_ID:
                     UINT64_TO_STREAM(p, dis_cb.dis_value.system_id); /* int_min */
                     p_value->len = DIS_SYSTEM_ID_SIZE;
@@ -210,7 +207,7 @@ static void dis_gatt_c_read_dis_value_cmpl(UINT16 conn_id)
 
     if (dis_cb.p_read_dis_cback && p_clcb)
     {
-        LOG_INFO("%s conn_id:%d attr_mask = 0x%04x", __func__, conn_id,
+        LOG_INFO(LOG_TAG, "%s conn_id:%d attr_mask = 0x%04x", __func__, conn_id,
                 p_clcb->dis_value.attr_mask);
 
         (*dis_cb.p_read_dis_cback)(p_clcb->bda, &p_clcb->dis_value);
@@ -339,7 +336,6 @@ void dis_c_cmpl_cback (tSRVC_CLCB *p_clcb, tGATTC_OPTYPE op,
     dis_gatt_c_read_dis_req(conn_id);
 }
 
-
 /*******************************************************************************
 **
 ** Function         DIS_SrInit
@@ -478,7 +474,6 @@ BOOLEAN DIS_ReadDISInfo(BD_ADDR peer_bda, tDIS_READ_CBACK *p_cback, tDIS_ATTR_MA
                       (peer_bda[0]<<24)+(peer_bda[1]<<16)+(peer_bda[2]<<8)+peer_bda[3],
                       (peer_bda[4]<<8)+peer_bda[5], dis_attr_uuid[dis_cb.dis_read_uuid_idx]);
 
-
     GATT_GetConnIdIfConnected(srvc_eng_cb.gatt_if, peer_bda, &conn_id, BT_TRANSPORT_LE);
 
     /* need to enhance it as multiple service is needed */
@@ -494,4 +489,3 @@ BOOLEAN DIS_ReadDISInfo(BD_ADDR peer_bda, tDIS_READ_CBACK *p_cback, tDIS_ATTR_MA
 }
 #endif  /* BLE_INCLUDED */
 
-
index 7457319..67a6468 100644 (file)
 #define SRVC_DIS_INT_H
 
 #include "bt_target.h"
-#include "srvc_api.h"
 #include "gatt_api.h"
+#include "srvc_api.h"
+#include "srvc_eng_int.h"
 
 #define DIS_MAX_CHAR_NUM            9
 
-
 typedef struct
 {
     UINT16      uuid;
@@ -35,8 +35,6 @@ typedef struct
 #define DIS_SYSTEM_ID_SIZE      8
 #define DIS_PNP_ID_SIZE         7
 
-
-
 typedef struct
 {
     tDIS_DB_ENTRY           dis_attr[DIS_MAX_CHAR_NUM];
@@ -54,8 +52,6 @@ typedef struct
     tDIS_ATTR_MASK          request_mask;
 }tDIS_CB;
 
-
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -68,7 +64,6 @@ extern tDIS_CB *dis_cb_ptr;
 #define dis_cb (*dis_cb_ptr)
 #endif
 
-
 extern BOOLEAN dis_valid_handle_range(UINT16 handle);
 extern UINT8 dis_read_attr_value (UINT8 clcb_idx, UINT16 handle, tGATT_VALUE *p_value,
                            BOOLEAN is_long, tGATT_STATUS *p_status);
@@ -77,7 +72,6 @@ extern UINT8 dis_write_attr_value(tGATT_WRITE_REQ * p_data, tGATT_STATUS *p_stat
 extern void dis_c_cmpl_cback (tSRVC_CLCB *p_clcb, tGATTC_OPTYPE op,
                                     tGATT_STATUS status, tGATT_CL_COMPLETE *p_data);
 
-
 #ifdef __cplusplus
 }
 #endif
index 2aa3bb2..b2c612c 100644 (file)
@@ -33,8 +33,7 @@ LOCAL_MODULE_TAGS := eng
 LOCAL_MODULE:= bdt
 
 LOCAL_SHARED_LIBRARIES += libcutils   \
-                          libhardware \
-                          libhardware_legacy
+                          libhardware
 
 LOCAL_MULTILIB := 32
 
diff --git a/udrv/BUILD.gn b/udrv/BUILD.gn
new file mode 100644 (file)
index 0000000..9562e32
--- /dev/null
@@ -0,0 +1,32 @@
+#
+#  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.
+#
+
+source_set("udrv") {
+  sources = [
+    "ulinux/uipc.c"
+  ]
+
+  include_dirs = [
+    "include",
+    "uipc",
+    "//",
+    "//audio_a2dp_hw",
+    "//include",
+    "//gki/common",
+    "//stack/include",
+    "//utils/include",
+  ]
+}
index f3c746e..8cb17af 100644 (file)
  *
  *****************************************************************************/
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <signal.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <pthread.h>
-#include <sys/select.h>
-#include <sys/poll.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <sys/mman.h>
-#include <sys/stat.h>
+#include <sys/poll.h>
 #include <sys/prctl.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <unistd.h>
 
-
-#include "gki.h"
-#include "bt_types.h"
-#include "uipc.h"
-
-#include <cutils/sockets.h>
 #include "audio_a2dp_hw.h"
+#include "bt_types.h"
 #include "bt_utils.h"
+#include "gki.h"
+#include "osi/include/socket_utils/sockets.h"
+#include "uipc.h"
 
 /*****************************************************************************
 **  Constants & Macros
@@ -153,7 +148,7 @@ static inline int create_server_socket(const char* name)
 
     BTIF_TRACE_EVENT("create_server_socket %s", name);
 
-    if(socket_local_server_bind(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT) < 0)
+    if(osi_socket_local_server_bind(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT) < 0)
     {
         BTIF_TRACE_EVENT("socket failed to create (%s)", strerror(errno));
         close(s);
diff --git a/utils/BUILD.gn b/utils/BUILD.gn
new file mode 100644 (file)
index 0000000..2b7dc59
--- /dev/null
@@ -0,0 +1,27 @@
+#
+#  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.
+#
+
+static_library("utils") {
+  sources = [
+    "src/bt_utils.c"
+  ]
+
+  include_dirs = [
+    "include",
+    "//",
+    "//stack/include",
+  ]
+}
index 53a53de..69106a1 100644 (file)
 
 #define LOG_TAG "bt_utils"
 
-#include <cutils/properties.h>
-#include <cutils/sched_policy.h>
+#include "bt_utils.h"
+
 #include <errno.h>
 #include <pthread.h>
-#include <sys/resource.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/resource.h>
 #include <unistd.h>
+
 #include <utils/ThreadDefs.h>
+#include <cutils/sched_policy.h>
+
+// TODO(armansito): cutils/properties.h is only being used to pull-in runtime
+// settings on Android. Remove this conditional include once we have a generic
+// way to obtain system properties.
+#if !defined(OS_GENERIC)
+#include <cutils/properties.h>
+#endif  // !defined(OS_GENERIC)
 
 #include "bt_types.h"
-#include "bt_utils.h"
 #include "btcore/include/module.h"
 #include "osi/include/compat.h"
 #include "osi/include/log.h"
@@ -73,7 +81,7 @@ static future_t *clean_up(void) {
   return NULL;
 }
 
-const module_t bt_utils_module = {
+EXPORT_SYMBOL const module_t bt_utils_module = {
   .name = BT_UTILS_MODULE,
   .init = init,
   .start_up = NULL,
@@ -84,7 +92,10 @@ const module_t bt_utils_module = {
   }
 };
 
-
+// TODO(armansito): Remove this conditional code once there is a generic way
+// to obtain system properties. System properties are only available on
+// Android. Don't do the following check if this is a generic build.
+#if !defined(OS_GENERIC)
 /*****************************************************************************
 **
 ** Function        check_do_scheduling_group
@@ -104,6 +115,7 @@ static void check_do_scheduling_group(void) {
         }
     }
 }
+#endif  // !defined(OS_GENERIC)
 
 /*****************************************************************************
 **
@@ -122,16 +134,23 @@ void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task) {
     pthread_mutex_lock(&gIdxLock);
     g_TaskIdx = high_task;
 
+    // TODO(armansito): Remove this conditional check once we find a solution
+    // for system/core on non-Android platforms.
+#if defined(OS_GENERIC)
+    rc = -1;
+#else  // !defined(OS_GENERIC)
     pthread_once(&g_DoSchedulingGroupOnce[g_TaskIdx], check_do_scheduling_group);
     if (g_DoSchedulingGroup[g_TaskIdx]) {
         // set_sched_policy does not support tid == 0
         rc = set_sched_policy(tid, SP_AUDIO_SYS);
     }
+#endif  // defined(OS_GENERIC)
+
     g_TaskIDs[high_task] = tid;
     pthread_mutex_unlock(&gIdxLock);
 
     if (rc) {
-        LOG_WARN("failed to change sched policy, tid %d, err: %d", tid, errno);
+        LOG_WARN(LOG_TAG, "failed to change sched policy, tid %d, err: %d", tid, errno);
     }
 
     // always use urgent priority for HCI worker thread until we can adjust
@@ -142,7 +161,7 @@ void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task) {
        priority = ANDROID_PRIORITY_URGENT_AUDIO;
 
     if (setpriority(PRIO_PROCESS, tid, priority) < 0) {
-        LOG_WARN("failed to change priority tid: %d to %d", tid, priority);
+        LOG_WARN(LOG_TAG, "failed to change priority tid: %d to %d", tid, priority);
     }
 }
 
@@ -169,7 +188,7 @@ void adjust_priority_a2dp(int start) {
         {
             if (setpriority(PRIO_PROCESS, tid, priority) < 0)
             {
-                LOG_WARN("failed to change priority tid: %d to %d", tid, priority);
+                LOG_WARN(LOG_TAG, "failed to change priority tid: %d to %d", tid, priority);
             }
         }
     }
diff --git a/vendor_libs/BUILD.gn b/vendor_libs/BUILD.gn
new file mode 100644 (file)
index 0000000..a088315
--- /dev/null
@@ -0,0 +1,22 @@
+#
+#  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.
+#
+
+group("vendor-libs") {
+  deps = [
+    "linux:bt-vendor-linux",
+    "test_vendor_lib:test_vendor_lib",
+  ]
+}
diff --git a/vendor_libs/linux/Android.mk b/vendor_libs/linux/Android.mk
new file mode 100644 (file)
index 0000000..4bebb1d
--- /dev/null
@@ -0,0 +1,37 @@
+#
+#  Copyright (C) 2015 Intel Corporation
+#
+#  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)
+
+ifeq ($(BOARD_HAVE_BLUETOOTH_LINUX), true)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+        bt_vendor_linux.c
+
+LOCAL_C_INCLUDES += \
+        $(LOCAL_PATH)/../../
+
+LOCAL_SHARED_LIBRARIES := \
+        libcutils
+
+LOCAL_MODULE := libbt-vendor
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif  # BOARD_HAVE_BLUETOOTH_LINUX
diff --git a/vendor_libs/linux/BUILD.gn b/vendor_libs/linux/BUILD.gn
new file mode 100644 (file)
index 0000000..6026001
--- /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.
+#
+
+shared_library("bt-vendor-linux") {
+  sources = [
+    "bt_vendor_linux.c"
+  ]
+
+  include_dirs = [
+    "//"
+  ]
+}
diff --git a/vendor_libs/linux/bt_vendor_linux.c b/vendor_libs/linux/bt_vendor_linux.c
new file mode 100644 (file)
index 0000000..be4fa7c
--- /dev/null
@@ -0,0 +1,419 @@
+/**********************************************************************
+ *
+ *  Copyright (C) 2015 Intel Corporation
+ *
+ *  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_vendor"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <string.h>
+#include <poll.h>
+
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+#include <cutils/properties.h>
+
+#include "hci/include/bt_vendor_lib.h"
+#include "osi/include/log.h"
+
+#define BTPROTO_HCI     1
+#define HCI_CHANNEL_USER        1
+#define HCI_CHANNEL_CONTROL     3
+#define HCI_DEV_NONE    0xffff
+
+#define RFKILL_TYPE_BLUETOOTH   2
+#define RFKILL_OP_CHANGE_ALL    3
+
+#define MGMT_OP_INDEX_LIST      0x0003
+#define MGMT_EV_INDEX_ADDED     0x0004
+#define MGMT_EV_COMMAND_COMP    0x0001
+#define MGMT_EV_SIZE_MAX        1024
+#define MGMT_EV_POLL_TIMEOUT    3000 /* 3000ms */
+
+#define IOCTL_HCIDEVDOWN        _IOW('H', 202, int)
+
+struct sockaddr_hci {
+  sa_family_t    hci_family;
+  unsigned short hci_dev;
+  unsigned short hci_channel;
+};
+
+struct rfkill_event {
+  uint32_t idx;
+  uint8_t  type;
+  uint8_t  op;
+  uint8_t  soft, hard;
+} __attribute__((packed));
+
+struct mgmt_pkt {
+  uint16_t opcode;
+  uint16_t index;
+  uint16_t len;
+  uint8_t data[MGMT_EV_SIZE_MAX];
+} __attribute__((packed));
+
+struct mgmt_event_read_index {
+  uint16_t cc_opcode;
+  uint8_t status;
+  uint16_t num_intf;
+  uint16_t index[0];
+} __attribute__((packed));
+
+static const bt_vendor_callbacks_t *bt_vendor_callbacks;
+static unsigned char bt_vendor_local_bdaddr[6];
+static int bt_vendor_fd = -1;
+static int hci_interface;
+static int rfkill_en;
+static int bt_hwcfg_en;
+
+static int bt_vendor_init(const bt_vendor_callbacks_t *p_cb,
+                          unsigned char *local_bdaddr)
+{
+  char prop_value[PROPERTY_VALUE_MAX];
+
+  LOG_INFO(LOG_TAG, "%s", __func__);
+
+  if (p_cb == NULL) {
+    LOG_ERROR(LOG_TAG, "init failed with no user callbacks!");
+    return -1;
+  }
+
+  bt_vendor_callbacks = p_cb;
+
+  memcpy(bt_vendor_local_bdaddr, local_bdaddr,
+         sizeof(bt_vendor_local_bdaddr));
+
+  property_get("bluetooth.interface", prop_value, "0");
+
+  errno = 0;
+  if (memcmp(prop_value, "hci", 3))
+    hci_interface = strtol(prop_value, NULL, 10);
+  else
+    hci_interface = strtol(prop_value + 3, NULL, 10);
+  if (errno)
+    hci_interface = 0;
+
+  LOG_INFO(LOG_TAG, "Using interface hci%d", hci_interface);
+
+  property_get("bluetooth.rfkill", prop_value, "0");
+
+  rfkill_en = atoi(prop_value);
+  if (rfkill_en)
+    LOG_INFO(LOG_TAG, "RFKILL enabled");
+
+  bt_hwcfg_en = property_get("bluetooth.hwcfg",
+                             prop_value, NULL) > 0 ? 1 : 0;
+  if (bt_hwcfg_en)
+    LOG_INFO(LOG_TAG, "HWCFG enabled");
+
+  return 0;
+}
+
+static int bt_vendor_hw_cfg(int stop)
+{
+  if (!bt_hwcfg_en)
+    return 0;
+
+  if (stop) {
+    if (property_set("bluetooth.hwcfg", "stop") < 0) {
+      LOG_ERROR(LOG_TAG, "%s cannot stop btcfg service via prop", __func__);
+      return 1;
+    }
+  } else {
+    if (property_set("bluetooth.hwcfg", "start") < 0) {
+      LOG_ERROR(LOG_TAG, "%s cannot start btcfg service via prop", __func__);
+      return 1;
+    }
+  }
+  return 0;
+}
+
+static int bt_vendor_wait_hcidev(void)
+{
+  struct sockaddr_hci addr;
+  struct pollfd fds[1];
+  struct mgmt_pkt ev;
+  int fd;
+  int ret = 0;
+
+  LOG_INFO(LOG_TAG, "%s", __func__);
+
+  fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+  if (fd < 0) {
+    LOG_ERROR(LOG_TAG, "Bluetooth socket error: %s", strerror(errno));
+    return -1;
+  }
+
+  memset(&addr, 0, sizeof(addr));
+  addr.hci_family = AF_BLUETOOTH;
+  addr.hci_dev = HCI_DEV_NONE;
+  addr.hci_channel = HCI_CHANNEL_CONTROL;
+
+  if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+    LOG_ERROR(LOG_TAG, "HCI Channel Control: %s", strerror(errno));
+    close(fd);
+    return -1;
+  }
+
+  fds[0].fd = fd;
+  fds[0].events = POLLIN;
+
+  /* Read Controller Index List Command */
+  ev.opcode = MGMT_OP_INDEX_LIST;
+  ev.index = HCI_DEV_NONE;
+  ev.len = 0;
+  if (write(fd, &ev, 6) != 6) {
+    LOG_ERROR(LOG_TAG, "Unable to write mgmt command: %s", strerror(errno));
+    ret = -1;
+    goto end;
+  }
+
+  while (1) {
+    int n = poll(fds, 1, MGMT_EV_POLL_TIMEOUT);
+    if (n == -1) {
+      LOG_ERROR(LOG_TAG, "Poll error: %s", strerror(errno));
+      ret = -1;
+      break;
+    } else if (n == 0) {
+      LOG_ERROR(LOG_TAG, "Timeout, no HCI device detected");
+      ret = -1;
+      break;
+    }
+
+    if (fds[0].revents & POLLIN) {
+      n = read(fd, &ev, sizeof(struct mgmt_pkt));
+      if (n < 0) {
+        LOG_ERROR(LOG_TAG,
+                  "Error reading control channel");
+        ret = -1;
+        break;
+      }
+
+      if (ev.opcode == MGMT_EV_INDEX_ADDED && ev.index == hci_interface) {
+        goto end;
+      } else if (ev.opcode == MGMT_EV_COMMAND_COMP) {
+        struct mgmt_event_read_index *cc;
+        int i;
+
+        cc = (struct mgmt_event_read_index *)ev.data;
+
+        if (cc->cc_opcode != MGMT_OP_INDEX_LIST || cc->status != 0)
+          continue;
+
+        for (i = 0; i < cc->num_intf; i++) {
+          if (cc->index[i] == hci_interface)
+            goto end;
+        }
+      }
+    }
+  }
+
+end:
+  close(fd);
+  return ret;
+}
+
+static int bt_vendor_open(void *param)
+{
+  int (*fd_array)[] = (int (*)[]) param;
+  int fd;
+
+  LOG_INFO(LOG_TAG, "%s", __func__);
+
+  fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+  if (fd < 0) {
+    LOG_ERROR(LOG_TAG, "socket create error %s", strerror(errno));
+    return -1;
+  }
+
+  (*fd_array)[CH_CMD] = fd;
+  (*fd_array)[CH_EVT] = fd;
+  (*fd_array)[CH_ACL_OUT] = fd;
+  (*fd_array)[CH_ACL_IN] = fd;
+
+  bt_vendor_fd = fd;
+
+  LOG_INFO(LOG_TAG, "%s returning %d", __func__, bt_vendor_fd);
+
+  return 1;
+}
+
+static int bt_vendor_close(void *param)
+{
+  (void)(param);
+
+  LOG_INFO(LOG_TAG, "%s", __func__);
+
+  if (bt_vendor_fd != -1) {
+    close(bt_vendor_fd);
+    bt_vendor_fd = -1;
+  }
+
+  return 0;
+}
+
+static int bt_vendor_rfkill(int block)
+{
+  struct rfkill_event event;
+  int fd, len;
+
+  LOG_INFO(LOG_TAG, "%s", __func__);
+
+  fd = open("/dev/rfkill", O_WRONLY);
+  if (fd < 0) {
+    LOG_ERROR(LOG_TAG, "Unable to open /dev/rfkill");
+    return -1;
+  }
+
+  memset(&event, 0, sizeof(struct rfkill_event));
+  event.op = RFKILL_OP_CHANGE_ALL;
+  event.type = RFKILL_TYPE_BLUETOOTH;
+  event.hard = block;
+  event.soft = block;
+
+  len = write(fd, &event, sizeof(event));
+  if (len < 0) {
+    LOG_ERROR(LOG_TAG, "Failed to change rfkill state");
+    close(fd);
+    return 1;
+  }
+
+  close(fd);
+  return 0;
+}
+
+/* TODO: fw config should thread the device waiting and return immedialty */
+static void bt_vendor_fw_cfg(void)
+{
+  struct sockaddr_hci addr;
+  int fd = bt_vendor_fd;
+
+  LOG_INFO(LOG_TAG, "%s", __func__);
+
+  if (fd == -1) {
+    LOG_ERROR(LOG_TAG, "bt_vendor_fd: %s", strerror(EBADF));
+    goto failure;
+  }
+
+  memset(&addr, 0, sizeof(addr));
+  addr.hci_family = AF_BLUETOOTH;
+  addr.hci_dev = hci_interface;
+  addr.hci_channel = HCI_CHANNEL_USER;
+
+  if (bt_vendor_wait_hcidev()) {
+    LOG_ERROR(LOG_TAG, "HCI interface (%d) not found", hci_interface);
+    goto failure;
+  }
+
+  if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+    LOG_ERROR(LOG_TAG, "socket bind error %s", strerror(errno));
+    goto failure;
+  }
+
+  LOG_INFO(LOG_TAG, "HCI device ready");
+
+  bt_vendor_callbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
+
+  return;
+
+failure:
+  LOG_ERROR(LOG_TAG, "Hardware Config Error");
+  bt_vendor_callbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
+}
+
+static int bt_vendor_op(bt_vendor_opcode_t opcode, void *param)
+{
+  int retval = 0;
+
+  LOG_INFO(LOG_TAG, "%s op %d", __func__, opcode);
+
+  switch (opcode) {
+  case BT_VND_OP_POWER_CTRL:
+    if (!rfkill_en || !param)
+      break;
+
+    if (*((int *)param) == BT_VND_PWR_ON) {
+      retval = bt_vendor_rfkill(0);
+      if (!retval)
+        retval = bt_vendor_hw_cfg(0);
+    } else {
+      retval = bt_vendor_hw_cfg(1);
+      if (!retval)
+        retval = bt_vendor_rfkill(1);
+    }
+
+    break;
+
+  case BT_VND_OP_FW_CFG:
+    bt_vendor_fw_cfg();
+    break;
+
+  case BT_VND_OP_SCO_CFG:
+    bt_vendor_callbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
+    break;
+
+  case BT_VND_OP_USERIAL_OPEN:
+    retval = bt_vendor_open(param);
+    break;
+
+  case BT_VND_OP_USERIAL_CLOSE:
+    retval = bt_vendor_close(param);
+    break;
+
+  case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
+    *((uint32_t *)param) = 3000;
+    retval = 0;
+    break;
+
+  case BT_VND_OP_LPM_SET_MODE:
+    bt_vendor_callbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS);
+    break;
+
+  case BT_VND_OP_LPM_WAKE_SET_STATE:
+    break;
+
+  case BT_VND_OP_SET_AUDIO_STATE:
+    bt_vendor_callbacks->audio_state_cb(BT_VND_OP_RESULT_SUCCESS);
+    break;
+
+  case BT_VND_OP_EPILOG:
+    bt_vendor_callbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
+    break;
+  }
+
+  LOG_INFO(LOG_TAG, "%s op %d retval %d", __func__, opcode, retval);
+
+  return retval;
+}
+
+static void bt_vendor_cleanup(void)
+{
+  LOG_INFO(LOG_TAG, "%s", __func__);
+
+  bt_vendor_callbacks = NULL;
+}
+
+const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
+  sizeof(bt_vendor_interface_t),
+  bt_vendor_init,
+  bt_vendor_op,
+  bt_vendor_cleanup,
+};
diff --git a/vendor_libs/test_vendor_lib/Android.mk b/vendor_libs/test_vendor_lib/Android.mk
new file mode 100644 (file)
index 0000000..fde7789
--- /dev/null
@@ -0,0 +1,69 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+BT_DIR := $(TOP_DIR)system/bt
+
+LOCAL_SRC_FILES := \
+    src/bt_vendor.cc \
+    src/command_packet.cc \
+    src/dual_mode_controller.cc \
+    src/event_packet.cc \
+    src/hci_transport.cc \
+    src/packet.cc \
+    src/packet_stream.cc \
+    src/test_channel_transport.cc \
+    src/vendor_manager.cc
+
+# We pull in gtest because base/files/file_util.h, which is used to read the
+# controller properties file, needs gtest/gtest_prod.h.
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/include \
+    $(BT_DIR) \
+    $(BT_DIR)/hci/include \
+    $(BT_DIR)/osi/include \
+    $(BT_DIR)/stack/include \
+    $(BT_DIR)/third_party/gtest/include
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libchrome
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CFLAGS += -std=c++11
+LOCAL_MODULE := test-vendor
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+
+include $(BUILD_SHARED_LIBRARY)
+
+ifeq ($(HOST_OS), linux)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+    src/command_packet.cc \
+    src/event_packet.cc \
+    src/hci_transport.cc \
+    src/packet.cc \
+    src/packet_stream.cc \
+    test/hci_transport_unittest.cc \
+    test/packet_stream_unittest.cc
+
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/include \
+    $(BT_DIR) \
+    $(BT_DIR)/hci/include \
+    $(BT_DIR)/osi/include \
+    $(BT_DIR)/stack/include
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libchrome-host
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CFLAGS += -std=c++11
+LOCAL_MODULE := test-vendor_test_host
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_HOST_NATIVE_TEST)
+endif
diff --git a/vendor_libs/test_vendor_lib/BUILD.gn b/vendor_libs/test_vendor_lib/BUILD.gn
new file mode 100644 (file)
index 0000000..ac36703
--- /dev/null
@@ -0,0 +1,55 @@
+shared_library("test_vendor_lib") {
+  sources = [
+    "src/bt_vendor.cc",
+    "src/command_packet.cc",
+    "src/dual_mode_controller.cc",
+    "src/event_packet.cc",
+    "src/hci_transport.cc",
+    "src/packet.cc",
+    "src/packet_stream.cc",
+    "src/test_channel_transport.cc",
+    "src/vendor_manager.cc",
+  ]
+
+  include_dirs = [
+    "include",
+    "//",
+    # TODO(dennischeng): Ideally we should need to have the lines below for
+    # indirect includes.
+    "//osi/include",
+    "//stack/include",
+  ]
+}
+
+executable("test_vendor_lib_test") {
+  testonly = true
+  sources = [
+    "src/command_packet.cc",
+    "src/event_packet.cc",
+    "src/packet.cc",
+    "src/packet_stream.cc",
+    "test/hci_transport_unittest.cc",
+    "test/packet_stream_unittest.cc",
+  ]
+
+  include_dirs = [
+    "include",
+    "//",
+    "//btcore/include",
+    "//hci/include",
+    "//osi/include",
+    "//stack/include",
+  ]
+
+  deps = [
+    "//third_party/gtest:gtest_main",
+    "//third_party/libchrome:base",
+    "//vendor_libs/test_vendor_lib",
+  ]
+
+  libs = [
+    "-lpthread",
+    "-lrt",
+    "-ldl",
+  ]
+}
diff --git a/vendor_libs/test_vendor_lib/data/controller_properties.json b/vendor_libs/test_vendor_lib/data/controller_properties.json
new file mode 100644 (file)
index 0000000..32adc52
--- /dev/null
@@ -0,0 +1,13 @@
+{
+  "AclDataPacketSize": "1024",
+  "ScoDataPacketSize": "255",
+  "NumAclDataPackets": "10",
+  "NumScoDataPackets": "10",
+  "Version": "4",
+  "Revision": "0",
+  "LmpPalVersion": "0",
+  "ManufacturerName": "0",
+  "LmpPalSubversion": "0",
+  "MaximumPageNumber": "0",
+  "BdAddress": "123456"
+}
diff --git a/vendor_libs/test_vendor_lib/include/command_packet.h b/vendor_libs/test_vendor_lib/include/command_packet.h
new file mode 100644 (file)
index 0000000..a3ff664
--- /dev/null
@@ -0,0 +1,80 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 <cstdint>
+#include <vector>
+
+#include "base/macros.h"
+#include "vendor_libs/test_vendor_lib/include/packet.h"
+
+namespace test_vendor_lib {
+
+// The following is specified in the Bluetooth Core Specification Version 4.2,
+// Volume 2, Part E, Section 5.4.1 (page 470). Command Packets begin with a 3
+// octet header formatted as follows:
+// - Opcode: 2 octets
+//   - Opcode Group Field (OGF): Upper bits 10-15
+//   - Opcode Command Field (OCF): Lower bits 0-9
+// - Payload size (in octets): 1 octet
+// The header is followed by the payload, which contains command specific
+// parameters and has a maximum size of 255 octets. Valid command opcodes are
+// defined in stack/include/hcidefs.h. The OGF ranges from 0x00 to 0x3F, with
+// 0x3F reserved for vendor-specific debug functions. The OCF ranges from
+// 0x0000 to 0x03FF. Note that the payload size is the size in octets of the
+// command parameters and not the number of parameters. Finally, although the
+// parameters contained in the payload are command specific (including the size
+// and number of parameters), each parameter will be an integer number of octets
+// in size.
+class CommandPacket : public Packet {
+ public:
+  CommandPacket();
+
+  virtual ~CommandPacket() override = default;
+
+  // Returns the command opcode as defined in stack/include/hcidefs.h.
+  // See the Bluetooth Core Specification Version 4.2, Volume 2, Part E,
+  // Section 7 for more information about each HCI commands and for a listing
+  // of their specific opcodes/OGF and OCF values.
+  uint16_t GetOpcode() const;
+
+  // Returns the 6 bit opcode group field that specifies the general category of
+  // the command. The OGF can be one of seven values:
+  // - 0x01: Link control commands
+  // - 0x02: Link policy commands
+  // - 0x03: Controller and baseband commands
+  // - 0x04: Informational parameters commands
+  // - 0x05: Status parameters commands
+  // - 0x06: Testing commands
+  // - 0x08: Low energy controller commands
+  // The upper 2 bits will be zero filled.
+  uint8_t GetOGF() const;
+
+  // Returns the 10 bit opcode command field that specifies an exact command
+  // within an opcode group field. The upper 6 bits will be zero filled.
+  uint16_t GetOCF() const;
+
+  // Size in octets of a command packet header, which consists of a 2 octet
+  // opcode and a 1 octet payload size.
+  static const size_t kCommandHeaderSize = 3;
+
+ private:
+  // Disallow any copies of the singleton to be made.
+  DISALLOW_COPY_AND_ASSIGN(CommandPacket);
+};
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/dual_mode_controller.h b/vendor_libs/test_vendor_lib/include/dual_mode_controller.h
new file mode 100644 (file)
index 0000000..c2c7aa5
--- /dev/null
@@ -0,0 +1,369 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+#include <unordered_map>
+
+#include "base/json/json_value_converter.h"
+#include "base/time/time.h"
+#include "vendor_libs/test_vendor_lib/include/command_packet.h"
+#include "vendor_libs/test_vendor_lib/include/hci_transport.h"
+#include "vendor_libs/test_vendor_lib/include/test_channel_transport.h"
+
+namespace test_vendor_lib {
+
+// Emulates a dual mode BR/EDR + LE controller by maintaining the link layer
+// state machine detailed in the Bluetooth Core Specification Version 4.2,
+// Volume 6, Part B, Section 1.1 (page 30). Provides methods corresponding to
+// commands sent by the HCI. These methods will be registered as callbacks from
+// a controller instance with the HciHandler. To implement a new Bluetooth
+// command, simply add the method declaration below, with return type void and a
+// single const std::vector<uint8_t>& argument. After implementing the
+// method, simply register it with the HciHandler using the SET_HANDLER macro in
+// the controller's default constructor. Be sure to name your method after the
+// corresponding Bluetooth command in the Core Specification with the prefix
+// "Hci" to distinguish it as a controller command.
+class DualModeController {
+ public:
+  class Properties {
+   public:
+    // TODO(dennischeng): Add default initialization and use that to instantiate
+    // a default configured controller if the config file is invalid or not
+    // provided.
+    Properties(const std::string& file_name);
+
+    // Aggregates and returns the result for the Read Local Extended Features
+    // command. This result contains the |maximum_page_number_| property (among
+    // other things not in the Properties object). See the Bluetooth Core
+    // Specification Version 4.2, Volume 2, Part E, Section 7.4.4 (page 792).
+    const std::vector<uint8_t> GetBdAddress();
+
+    // Aggregates and returns the result for the Read Buffer Size command. This
+    // result consists of the |acl_data_packet_size_|, |sco_data_packet_size_|,
+    // |num_acl_data_packets_|, and |num_sco_data_packets_| properties. See the
+    // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.5
+    // (page 794).
+    const std::vector<uint8_t> GetBufferSize();
+
+    // Returns the result for the Read BD_ADDR command. This result is the
+    // |bd_address_| property. See the Bluetooth Core Specification Version
+    // 4.2, Volume 2, Part E, Section 7.4.6 (page 796).
+    const std::vector<uint8_t> GetLocalExtendedFeatures(uint8_t page_number);
+
+    // Returns the result for the Read Local Name command. See the Bluetooth
+    // Core Specification Version 4.2, Volume 2, Part E, Section 7.3.12
+    // (page 664).
+    const std::vector<uint8_t> GetLocalName();
+
+    // Returns the result for the Read Local Supported Commands command. See the
+    // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.2
+    // (page 790).
+    const std::vector<uint8_t> GetLocalSupportedCommands();
+
+    // Aggregates and returns the Read Local Version Information result. This
+    // consists of the |version_|, |revision_|, |lmp_pal_version_|,
+    // |manufacturer_name_|, and |lmp_pal_subversion_|. See the Bluetooth Core
+    // Specification Version 4.2, Volume 2, Part E, Section 7.4.1 (page 788).
+    const std::vector<uint8_t> GetLocalVersionInformation();
+
+    static void RegisterJSONConverter(
+        base::JSONValueConverter<Properties>* converter);
+
+   private:
+    uint16_t acl_data_packet_size_;
+    uint8_t sco_data_packet_size_;
+    uint16_t num_acl_data_packets_;
+    uint16_t num_sco_data_packets_;
+    uint8_t version_;
+    uint16_t revision_;
+    uint8_t lmp_pal_version_;
+    uint16_t manufacturer_name_;
+    uint16_t lmp_pal_subversion_;
+    uint8_t maximum_page_number_;
+    uint8_t local_supported_commands_size_;
+    uint8_t local_name_size_;
+    std::vector<uint8_t> bd_address_;
+  };
+
+  // Sets all of the methods to be used as callbacks in the HciHandler.
+  DualModeController();
+
+  ~DualModeController() = default;
+
+  // Preprocesses the command, primarily checking testh channel hooks. If
+  // possible, dispatches the corresponding controller method corresponding to
+  // carry out the command.
+  void HandleCommand(std::unique_ptr<CommandPacket> command_packet);
+
+  // Dispatches the test channel action corresponding to the command specified
+  // by |name|.
+  void HandleTestChannelCommand(const std::string& name,
+                                const std::vector<std::string>& args);
+
+  // Sets the controller Handle* methods as callbacks for the transport to call
+  // when data is received.
+  void RegisterHandlersWithHciTransport(HciTransport& transport);
+
+  // Sets the test channel handler with the transport dedicated to test channel
+  // communications.
+  void RegisterHandlersWithTestChannelTransport(
+      TestChannelTransport& transport);
+
+  // Sets the callback to be used for sending events back to the HCI.
+  // TODO(dennischeng): Once PostDelayedTask works, get rid of this and only use
+  // |RegisterDelayedEventChannel|.
+  void RegisterEventChannel(
+      std::function<void(std::unique_ptr<EventPacket>)> send_event);
+
+  void RegisterDelayedEventChannel(
+      std::function<void(std::unique_ptr<EventPacket>, base::TimeDelta)>
+          send_event);
+
+  // Controller commands. For error codes, see the Bluetooth Core Specification,
+  // Version 4.2, Volume 2, Part D (page 370).
+
+  // OGF: 0x0003
+  // OCF: 0x0003
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.2
+  void HciReset(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0004
+  // OGF: 0x0005
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4.5
+  void HciReadBufferSize(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x0033
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.39
+  void HciHostBufferSize(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0004
+  // OCF: 0x0001
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4.1
+  void HciReadLocalVersionInformation(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0004
+  // OCF: 0x0009
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4.6
+  void HciReadBdAddr(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0004
+  // OCF: 0x0002
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4.2
+  void HciReadLocalSupportedCommands(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0004
+  // OCF: 0x0004
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4.4
+  void HciReadLocalExtendedFeatures(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x0056
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.59
+  void HciWriteSimplePairingMode(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x006D
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.79
+  void HciWriteLeHostSupport(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x0001
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.1
+  void HciSetEventMask(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x0045
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.50
+   void HciWriteInquiryMode(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x0047
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.52
+   void HciWritePageScanType(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x0043
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.48
+  void HciWriteInquiryScanType(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x0024
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.26
+  void HciWriteClassOfDevice(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x0018
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.16
+  void HciWritePageTimeout(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0002
+  // OCF: 0x000F
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.2.12
+  void HciWriteDefaultLinkPolicySettings(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x0014
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.12
+  void HciReadLocalName(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x0013
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.11
+  void HciWriteLocalName(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x0052
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.56
+  void HciWriteExtendedInquiryResponse(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x0026
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.28
+  void HciWriteVoiceSetting(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x003A
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.45
+    void HciWriteCurrentIacLap(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x001E
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.22
+   void HciWriteInquiryScanActivity(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x001A
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.18
+  void HciWriteScanEnable(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x0005
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.3
+  void HciSetEventFilter(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0001
+  // OCF: 0x0001
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.1.1
+  void HciInquiry(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0001
+  // OCF: 0x0002
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.1.2
+  void HciInquiryCancel(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0003
+  // OCF: 0x0012
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.10
+  void HciDeleteStoredLinkKey(const std::vector<uint8_t>& args);
+
+  // OGF: 0x0001
+  // OCF: 0x0019
+  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.1.19
+  void HciRemoteNameRequest(const std::vector<uint8_t>& args);
+
+  // Test Channel commands:
+
+  // Clears all test channel modifications.
+  void TestChannelClear(const std::vector<std::string>& args);
+
+  // Sets the response delay for events to 0.
+  void TestChannelClearEventDelay(const std::vector<std::string>& args);
+
+  // Discovers a fake device.
+  void TestChannelDiscover(const std::vector<std::string>& args);
+
+  // Causes events to be sent after a delay.
+  void TestChannelSetEventDelay(const std::vector<std::string>& args);
+
+  // Causes all future HCI commands to timeout.
+  void TestChannelTimeoutAll(const std::vector<std::string>& args);
+
+ private:
+  // Current link layer state of the controller.
+  enum State {
+    kStandby,  // Not receiving/transmitting any packets from/to other devices.
+    kInquiry,  // The controller is discovering other nearby devices.
+  };
+
+  enum TestChannelState {
+    kNone,  // The controller is running normally.
+    kTimeoutAll,  // All commands should time out, i.e. send no response.
+    kDelayedResponse,  // Event responses are sent after a delay.
+  };
+
+  // Creates a command complete event and sends it back to the HCI.
+  void SendCommandComplete(uint16_t command_opcode,
+                           const std::vector<uint8_t>& return_parameters) const;
+
+  // Sends a command complete event with no return parameters. This event is
+  // typically sent for commands that can be completed immediately.
+  void SendCommandCompleteSuccess(uint16_t command_opcode) const;
+
+  // Creates a command status event and sends it back to the HCI.
+  void SendCommandStatus(uint8_t status, uint16_t command_opcode) const;
+
+  // Sends a command status event with default event parameters.
+  void SendCommandStatusSuccess(uint16_t command_opcode) const;
+
+  // Sends an inquiry response for a fake device.
+  void SendInquiryResult() const;
+
+  // Sends an extended inquiry response for a fake device.
+  void SendExtendedInquiryResult(const std::string& name,
+                                 const std::string& address) const;
+
+  void SetEventDelay(int64_t delay);
+
+  // Callback provided to send events from the controller back to the HCI.
+  std::function<void(std::unique_ptr<EventPacket>)> send_event_;
+
+  std::function<void(std::unique_ptr<EventPacket>, base::TimeDelta)>
+      send_delayed_event_;
+
+  // Maintains the commands to be registered and used in the HciHandler object.
+  // Keys are command opcodes and values are the callbacks to handle each
+  // command.
+  std::unordered_map<uint16_t, std::function<void(const std::vector<uint8_t>&)>>
+      active_hci_commands_;
+
+  std::unordered_map<std::string,
+                     std::function<void(const std::vector<std::string>&)>>
+      active_test_channel_commands_;
+
+  // Specifies the format of Inquiry Result events to be returned during the
+  // Inquiry command.
+  // 0x00: Standard Inquiry Result event format (default).
+  // 0x01: Inquiry Result format with RSSI.
+  // 0x02 Inquiry Result with RSSI format or Extended Inquiry Result format.
+  // 0x03-0xFF: Reserved.
+  uint8_t inquiry_mode_;
+
+  State state_;
+
+  Properties properties_;
+
+  TestChannelState test_channel_state_;
+
+  DISALLOW_COPY_AND_ASSIGN(DualModeController);
+};
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/event_packet.h b/vendor_libs/test_vendor_lib/include/event_packet.h
new file mode 100644 (file)
index 0000000..30e9224
--- /dev/null
@@ -0,0 +1,161 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 <cstdint>
+#include <memory>
+#include <vector>
+
+#include "base/logging.h"
+#include "vendor_libs/test_vendor_lib/include/packet.h"
+
+namespace test_vendor_lib {
+
+// The following is specified in the Bluetooth Core Specification Version 4.2,
+// Volume 2, Part E, Section 5.4.4 (page 477). Event Packets begin with a 2
+// octet header formatted as follows:
+// - Event code: 1 octet
+// - Payload size (in octets): 1 octet
+// The header is followed by the payload, which contains event specific
+// parameters and has a maximum size of 255 octets. Valid event codes are
+// listed in stack/include/hcidefs.h. They can range from 0x00 to 0xFF, with
+// 0xFF reserved for vendor specific debug events. Note the payload size
+// describes the total size of the event parameters and not the number of
+// parameters. The event parameters contained in the payload will be an integer
+// number of octets in size. Each flavor of event packet is created via a static
+// factory function that takes the event type-specific parameters and returns an
+// initialized event packet from that data.
+class EventPacket : public Packet {
+ public:
+  virtual ~EventPacket() override = default;
+
+  uint8_t GetEventCode() const;
+
+  // Static functions for creating event packets:
+
+  // Creates and returns a command complete event packet. See the Bluetooth
+  // Core Specification Version 4.2, Volume 2, Part E, Section 7.7.14 (page 861)
+  // for more information about the command complete event.
+  // Event Parameters:
+  //   |num_hci_command_packets|
+  //     Indicates the number of HCI command packets the host can send to the
+  //     controller. If |num_hci_command_packets| is 0, the controller would
+  //     like to stop receiving commands from the host (to indicate
+  //     readiness again, the controller sends a command complete event with
+  //     |command_opcode| to 0x0000 (no op) and |num_hci_command_packets| > 1).
+  //   |command_opcode|
+  //     The opcode of the command that caused this event.
+  //   |return_parameters|
+  //     Contains any event specific parameters that should
+  //     be sent to the host.
+  static std::unique_ptr<EventPacket> CreateCommandCompleteEvent(
+      uint8_t num_hci_command_packets, uint16_t command_opcode,
+      const std::vector<uint8_t>& event_return_parameters);
+
+  // Creates and returns a command complete event packet. See the Bluetooth
+  // Core Specification Version 4.2, Volume 2, Part E, Section 7.7.15 (page 862)
+  // for more information about the command complete event.
+  // Event Parameters:
+  //   Status
+  //     0x00: Command currently in pending.
+  //     0x01-0xFF: Command failed.
+  //   |num_hci_command_packets|
+  //     Indicates the number of HCI command packets the host can send to the
+  //     controller. If |num_hci_command_packets| is 0, the controller would
+  //     like to stop receiving commands from the host (to indicate
+  //     readiness again, the controller sends a command complete event with
+  //     |command_opcode| to 0x0000 (no op) and |num_hci_command_packets| > 1).
+  //   |command_opcode|
+  //     The opcode of the command that caused this event.
+  static std::unique_ptr<EventPacket> CreateCommandStatusEvent(
+      uint8_t status, uint8_t num_hci_command_packets, uint16_t command_opcode);
+
+  // Creates and returns an inquiry result event packet. See the Bluetooth
+  // Core Specification Version 4.2, Volume 2, Part E, Section 7.7.2 (page 844)
+  // for more information about the command complete event.
+  // Event Parameters:
+  //   Num Responses (1 octet)
+  //     0xXX: Number of responses from the inquiry.
+  //   Bd Addresses (6 octets * Num Responses)
+  //     0xXXXXXXXXXXX: Bd Address for each device which responded.
+  //   Page Scan Repetition Mode (1 octet * Num Responses)
+  //     0x00: R0
+  //     0x01: R1
+  //     0x02: R2
+  //     0x03-0xFF: Reserved.
+  //   Reserved 1 (1 octet * Num Responses)
+  //     Originally Page Scan Period Mode parameter. No longer in use.
+  //   Reserved 2 (1 octet * Num Responses)
+  //     Originally Page Scan Mode parameter. No longer in use.
+  //   Class of Device (3 octet * Num Responses)
+  //     0xXXXXXX: Class of device.
+  //   Clock Offset (2 octet * Num Responses)
+  //     Bits 14-0: Bits 16-2 of CLKNslave-CLK.
+  //     Bits 15: Reserved.
+  static std::unique_ptr<EventPacket> CreateInquiryResultEvent(
+      uint8_t num_responses, const std::vector<uint8_t>& bd_addresses,
+      const std::vector<uint8_t>& page_scan_repetition_mode,
+      const std::vector<uint8_t>& page_scan_period_mode,
+      const std::vector<uint8_t>& page_scan_mode,
+      const std::vector<uint8_t>& class_of_device,
+      const std::vector<uint8_t>& clock_offset);
+
+  // Creates and returns an inquiry result event packet. See the Bluetooth
+  // Core Specification Version 4.2, Volume 2, Part E, Section 7.7.38 (page 896)
+  // for more information about the command complete event.
+  // Event Parameters:
+  //   Num Responses (1 octet)
+  //     0x01: Always contains a single response.
+  //   Bd Addresses (6 octets * Num Responses)
+  //     0xXXXXXXXXXXX: Bd Address for each device which responded.
+  //   Page Scan Repetition Mode (1 octet * Num Responses)
+  //     0x00: R0
+  //     0x01: R1
+  //     0x02: R2
+  //     0x03-0xFF: Reserved.
+  //   Reserved 1 (1 octet * Num Responses)
+  //     Originally Page Scan Period Mode parameter. No longer in use.
+  //   Class of Device (3 octet * Num Responses)
+  //     0xXXXXXX: Class of device.
+  //   Clock Offset (2 octet * Num Responses)
+  //     Bits 14-0: Bits 16-2 of CLKNslave-CLK.
+  //     Bits 15: Reserved.
+  //   RSSI (1 octet)
+  //     0xXX: Ranges from -127 to +20. Units are dBm.
+  //  Extended Inquiry Response (240 octets)
+  //    Defined in Volumne 2, Part C, Section 8. Also see the Supplement to the
+  //    Bluetooth Core Specificiation for data type definitions and formats.
+  static std::unique_ptr<EventPacket> CreateExtendedInquiryResultEvent(
+      const std::vector<uint8_t>& bd_address,
+      const std::vector<uint8_t>& page_scan_repetition_mode,
+      const std::vector<uint8_t>& page_scan_period_mode,
+      const std::vector<uint8_t>& class_of_device,
+      const std::vector<uint8_t>& clock_offset,
+      const std::vector<uint8_t>& rssi,
+      const std::vector<uint8_t>& extended_inquiry_response);
+
+  // Size in octets of a data packet header, which consists of a 1 octet
+  // event code and a 1 octet payload size.
+  static const size_t kEventHeaderSize = 2;
+
+ private:
+  // Takes in the event parameters in |payload|. These parameters vary by event
+  // and are detailed in the Bluetooth Core Specification.
+  EventPacket(uint8_t event_code, const std::vector<uint8_t>& payload);
+};
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/hci_transport.h b/vendor_libs/test_vendor_lib/include/hci_transport.h
new file mode 100644 (file)
index 0000000..6668aab
--- /dev/null
@@ -0,0 +1,134 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 <functional>
+#include <memory>
+#include <list>
+
+extern "C" {
+#include <sys/epoll.h>
+}  // extern "C"
+
+#include "base/files/scoped_file.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/time/time.h"
+#include "vendor_libs/test_vendor_lib/include/command_packet.h"
+#include "vendor_libs/test_vendor_lib/include/event_packet.h"
+#include "vendor_libs/test_vendor_lib/include/packet.h"
+#include "vendor_libs/test_vendor_lib/include/packet_stream.h"
+
+namespace test_vendor_lib {
+
+// Manages communication channel between HCI and the controller by providing the
+// socketing mechanisms for reading/writing between the HCI and the controller.
+class HciTransport : public base::MessageLoopForIO::Watcher {
+ public:
+  HciTransport();
+
+  virtual ~HciTransport() = default;
+
+  void CloseHciFd();
+
+  void CloseVendorFd();
+
+  int GetHciFd() const;
+
+  int GetVendorFd() const;
+
+  // Creates the underlying socketpair to be used as a communication channel
+  // between the HCI and the vendor library/controller. Returns false if an
+  // error occurs.
+  bool SetUp();
+
+  // Sets the callback that is run when command packets are received.
+  void RegisterCommandHandler(
+      std::function<void(std::unique_ptr<CommandPacket>)> callback);
+
+  // Posts the event onto |outbound_events_| to be written sometime in the
+  // future when the vendor file descriptor is ready for writing.
+  void PostEventResponse(std::unique_ptr<EventPacket> event);
+
+  // Posts the event onto |outbound_events_| after |delay| ms. A call to
+  // |PostEventResponse| with |delay| 0 is equivalent to a call to |PostEvent|.
+  void PostDelayedEventResponse(std::unique_ptr<EventPacket> event,
+                                base::TimeDelta delay);
+
+ private:
+  // Wrapper class for sending events on a delay. The TimeStampedEvent object
+  // takes ownership of a given event packet.
+  class TimeStampedEvent {
+   public:
+    TimeStampedEvent(std::unique_ptr<EventPacket> event, base::TimeDelta delay);
+
+    // Using this constructor is equivalent to calling the 2-argument
+    // constructor with a |delay| of 0. It is used to generate event responses
+    // with no delay.
+    TimeStampedEvent(std::unique_ptr<EventPacket> event);
+
+    const base::TimeTicks& GetTimeStamp() const;
+
+    const EventPacket& GetEvent();
+
+   private:
+    std::shared_ptr<EventPacket> event_;
+
+    // The time associated with the event, indicating the earliest time at which
+    // |event_| will be sent.
+    base::TimeTicks time_stamp_;
+  };
+
+  // base::MessageLoopForIO::Watcher overrides:
+  void OnFileCanReadWithoutBlocking(int fd) override;
+
+  void OnFileCanWriteWithoutBlocking(int fd) override;
+
+  // Reads in a command packet and calls the command ready callback,
+  // |command_handler_|, passing ownership of the command packet to the handler.
+  void ReceiveReadyCommand() const;
+
+  void AddEventToOutboundEvents(std::unique_ptr<TimeStampedEvent> event);
+
+  // Write queue for sending events to the HCI. Event packets are removed from
+  // the queue and written when write-readiness is signalled by the message
+  // loop. After being written, the event packets are destructed.
+  std::list<std::unique_ptr<TimeStampedEvent>> outbound_events_;
+
+  // Callback executed in ReceiveReadyCommand() to pass the incoming command
+  // over to the handler for further processing.
+  std::function<void(std::unique_ptr<CommandPacket>)> command_handler_;
+
+  // For performing packet-based IO.
+  PacketStream packet_stream_;
+
+  // The two ends of the socketpair. |hci_fd_| is handed back to the HCI in
+  // bt_vendor.cc and |vendor_fd_| is used by |packet_stream_| to receive/send
+  // data from/to the HCI. Both file descriptors are owned and managed by the
+  // transport object, although |hci_fd_| can be closed by the HCI in
+  // TestVendorOp().
+  std::unique_ptr<base::ScopedFD> hci_fd_;
+  std::unique_ptr<base::ScopedFD> vendor_fd_;
+
+  // This should remain the last member so it'll be destroyed and invalidate
+  // its weak pointers before any other members are destroyed.
+  base::WeakPtrFactory<HciTransport> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(HciTransport);
+};
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/packet.h b/vendor_libs/test_vendor_lib/include/packet.h
new file mode 100644 (file)
index 0000000..9b3978c
--- /dev/null
@@ -0,0 +1,78 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 <cstdint>
+#include <vector>
+
+extern "C" {
+#include "hci/include/hci_hal.h"
+}  // extern "C"
+
+namespace test_vendor_lib {
+
+// Abstract base class that is subclassed to provide type-specifc accessors on
+// data. Manages said data's memory and guarantees the data's persistence for IO
+// operations.
+class Packet {
+ public:
+  virtual ~Packet() = default;
+
+  // Returns the size in octets of the entire packet, which consists of the type
+  // octet, the header, and the payload.
+  size_t GetPacketSize() const;
+
+  const std::vector<uint8_t>& GetPayload() const;
+
+  uint8_t GetPayloadSize() const;
+
+  const std::vector<uint8_t>& GetHeader() const;
+
+  uint8_t GetHeaderSize() const;
+
+  serial_data_type_t GetType() const;
+
+  // Validates the packet by checking that the payload size in the header is
+  // accurate. If the size is not valid, returns false. Otherwise, the data in
+  // |header| and |payload| is copied into |header_| and |payload_|
+  // respectively. If an error occurs while the data is being copied, the
+  // contents of |header| and |payload| are guaranteed to be preserved. The
+  // packet object will assume ownership of the copied data for its entire
+  // lifetime.
+  bool Encode(const std::vector<uint8_t>& header,
+              const std::vector<uint8_t>& payload);
+
+ protected:
+  // Constructs an empty packet of type |type|. A call to Encode() shall be made
+  // to check and fill in the packet's data.
+  Packet(serial_data_type_t type);
+
+ private:
+  // Underlying containers for storing the actual packet, broken down into the
+  // packet header and the packet payload. Data is copied into the vectors
+  // during the constructor and becomes accessible (read only) to children
+  // through GetHeader() and GetPayload().
+  std::vector<uint8_t> header_;
+
+  std::vector<uint8_t> payload_;
+
+  // The packet type is one of DATA_TYPE_ACL, DATA_TYPE_COMMAND,
+  // DATA_TYPE_EVENT, or DATA_TYPE_SCO.
+  serial_data_type_t type_;
+};
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/packet_stream.h b/vendor_libs/test_vendor_lib/include/packet_stream.h
new file mode 100644 (file)
index 0000000..de0d570
--- /dev/null
@@ -0,0 +1,66 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 <cstdint>
+#include <vector>
+#include <memory>
+
+#include "vendor_libs/test_vendor_lib/include/command_packet.h"
+#include "vendor_libs/test_vendor_lib/include/event_packet.h"
+#include "vendor_libs/test_vendor_lib/include/packet.h"
+
+namespace test_vendor_lib {
+
+// Provides abstractions for IO with Packet objects. Used to receive commands
+// and data from the HCI and to send controller events back to the host.
+class PacketStream {
+ public:
+  PacketStream() = default;
+
+  virtual ~PacketStream() = default;
+
+  // Reads a command packet from the file descriptor at |fd| and returns the
+  // packet back to the caller, along with the responsibility of managing the
+  // packet.
+  std::unique_ptr<CommandPacket> ReceiveCommand(int fd) const;
+
+  // Reads a single octet from |fd| and interprets it as a packet type octet.
+  // Validates the type octet for correctness.
+  serial_data_type_t ReceivePacketType(int fd) const;
+
+  // Sends an event to file descriptor |fd|. The ownership of the event is left
+  // with the caller.
+  bool SendEvent(const EventPacket& event, int fd) const;
+
+ private:
+  // Checks if |type| is in the valid range from DATA_TYPE_COMMAND to
+  // DATA_TYPE_SCO.
+  bool ValidateTypeOctet(serial_data_type_t type) const;
+
+  // Attempts to receive |num_octets_to_receive| into |destination| from |fd|,
+  // returning false if an error occurs.
+  bool ReceiveAll(std::vector<uint8_t>& destination,
+                  size_t num_octets_to_receive, int fd) const;
+
+  // Attempts to send |num_octets_to_send| from |source| to |fd|, returning
+  // false if an error occurs.
+  bool SendAll(const std::vector<uint8_t>& source, size_t num_octets_to_send,
+               int fd) const;
+};
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/test_channel_transport.h b/vendor_libs/test_vendor_lib/include/test_channel_transport.h
new file mode 100644 (file)
index 0000000..600e932
--- /dev/null
@@ -0,0 +1,77 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 <string>
+#include <memory>
+
+#include "base/files/scoped_file.h"
+#include "base/message_loop/message_loop.h"
+
+namespace test_vendor_lib {
+
+// Manages communications between test channel and the controller. Mirrors the
+// HciTransport for the test channel.
+class TestChannelTransport : public base::MessageLoopForIO::Watcher {
+ public:
+  TestChannelTransport(bool enabled, int port);
+
+  ~TestChannelTransport() = default;
+
+  // Waits for a connection request from the test channel program and
+  // allocates the file descriptor to watch for run-time parameters at. This
+  // file descriptor gets stored in |fd_|.
+  bool SetUp();
+
+  int GetFd();
+
+  // Because it imposes a different flow of work, the test channel must be
+  // actively enabled to be used. |enabled_| is set by the vendor manager.
+  bool IsEnabled();
+
+  // Turns the test channel off for use in circumstances where an error occurs
+  // and leaving the channel on would crash Bluetooth (e.g. if the test channel
+  // is unable to bind to its socket, Bluetooth should still start without the
+  // channel enabled).
+  void Disable();
+
+  // Sets the callback that fires when data is read in
+  // |OnFileCanReadWithoutBlocking|.
+  void RegisterCommandHandler(
+      std::function<void(const std::string&, const std::vector<std::string>&)>
+          callback);
+
+ private:
+  // base::MessageLoopForIO::Watcher overrides:
+  void OnFileCanReadWithoutBlocking(int fd) override;
+
+  void OnFileCanWriteWithoutBlocking(int fd) override;
+
+  std::function<void(const std::string&, const std::vector<std::string>&)>
+      command_handler_;
+
+  // File descriptor to watch for test hook data.
+  std::unique_ptr<base::ScopedFD> fd_;
+
+  // TODO(dennischeng): Get port and enabled flag from a config file.
+  int port_;
+  bool enabled_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestChannelTransport);
+};
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/vendor_manager.h b/vendor_libs/test_vendor_lib/include/vendor_manager.h
new file mode 100644 (file)
index 0000000..7190d5e
--- /dev/null
@@ -0,0 +1,118 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread.h"
+#include "base/time/time.h"
+#include "hci/include/bt_vendor_lib.h"
+#include "vendor_libs/test_vendor_lib/include/dual_mode_controller.h"
+#include "vendor_libs/test_vendor_lib/include/event_packet.h"
+#include "vendor_libs/test_vendor_lib/include/hci_transport.h"
+#include "vendor_libs/test_vendor_lib/include/test_channel_transport.h"
+
+#include <memory>
+
+namespace test_vendor_lib {
+
+// Contains the three core objects that make up the test vendor library: the
+// HciTransport for communication, the HciHandler for processing commands, and
+// the Controller for actual command implementations. The VendorManager shall
+// operate as a global singleton and be used in bt_vendor.cc to perform vendor
+// specific operations, via |vendor_callbacks_|, and to provide access to the
+// test controller by setting up a message loop (on another thread) that the HCI
+// will talk to and controller methods will execute on.
+class VendorManager {
+ public:
+  // Functions that operate on the global manager instance. Initialize()
+  // is called by the vendor library's TestVendorInitialize() function to create
+  // the global manager and must be called before Get() and CleanUp().
+  // CleanUp() should be called when a call to TestVendorCleanUp() is made
+  // since the global manager should live throughout the entire time the test
+  // vendor library is in use.
+  static void CleanUp();
+
+  static VendorManager* Get();
+
+  static void Initialize();
+
+  void CloseHciFd();
+
+  int GetHciFd() const;
+
+  const bt_vendor_callbacks_t& GetVendorCallbacks() const;
+
+  // Stores a copy of the vendor specific configuration callbacks passed into
+  // the vendor library from the HCI in TestVendorInit().
+  void SetVendorCallbacks(const bt_vendor_callbacks_t& callbacks);
+
+  // Returns true if |thread_| is able to be started and the
+  // StartingWatchingOnThread() task has been posted to the task runner.
+  bool Run();
+
+ private:
+  VendorManager();
+
+  ~VendorManager() = default;
+
+  // Posts a callback to |thread_|'s task runner. Equivalent to calling
+  // |PostDelayedTask| with a delay of 0.
+  bool PostTask(const base::Closure& task);
+
+  // Posts a callback to be run after |delay| ms (or longer) have passed.
+  bool PostDelayedTask(const base::Closure& task, base::TimeDelta delay);
+
+  // Starts watching for incoming data from the HCI and the test hook.
+  void StartWatchingOnThread();
+
+  // Creates the HCI's communication channel and overrides IO callbacks to
+  // receive and send packets.
+  HciTransport transport_;
+
+  // The controller object that provides implementations of Bluetooth commands.
+  DualModeController controller_;
+
+  // The two test channel objects that perform functions corresponding to the
+  // HciTransport and HciHandler.
+  TestChannelTransport test_channel_transport_;
+
+  // Configuration callbacks provided by the HCI for use in TestVendorOp().
+  bt_vendor_callbacks_t vendor_callbacks_;
+
+  // True if the underlying message loop (in |thread_|) is running.
+  bool running_;
+
+  // Dedicated thread for managing the message loop to receive and send packets
+  // from the HCI and to receive additional parameters from the test hook file
+  // descriptor.
+  base::Thread thread_;
+
+  // Used to handle further watching of the vendor's/test channel's file
+  // descriptor after WatchFileDescriptor() is called.
+  base::MessageLoopForIO::FileDescriptorWatcher hci_watcher_;
+
+  // Used to handle further watching of the test channel's file descriptor after
+  // WatchFileDescriptor() is called.
+  base::MessageLoopForIO::FileDescriptorWatcher test_channel_watcher_;
+
+  // This should remain the last member so it'll be destroyed and invalidate
+  // its weak pointers before any other members are destroyed.
+  base::WeakPtrFactory<VendorManager> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(VendorManager);
+};
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/scripts/build_and_run.sh b/vendor_libs/test_vendor_lib/scripts/build_and_run.sh
new file mode 100755 (executable)
index 0000000..34e0cfe
--- /dev/null
@@ -0,0 +1,127 @@
+#!/bin/bash
+
+#
+# Copyright 2015 The Android Open Source Project
+#
+# 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.
+#
+
+# Builds and pushes the test vendor library to a connected device and starts
+# logcat with project-specific tag filters. If the --test-channel flag is set,
+# logcat is started in a separate process and the test channel is run in the
+# current shell. The kTestChannelEnabled flag must be set in the vendor manager
+# if the test channel is to be used. Also ensure that 'lunch' has been run for
+# the appropriate device.
+
+if [[ "$#" -ne 2 && "$#" -ne 4 ]]; then
+  echo "Usage:"
+  echo "./build_and_run.sh [/path/to/aosp] [device_name] or"
+  echo "./build_and_run.sh [/path/to/aosp] [device_name] --test-channel [port]"
+  exit 1
+fi
+
+# Exit the script if any command fails.
+set -e
+
+# The home directory for AOSP.
+AOSP_ABS=$1
+# The name of the device to build for.
+DEVICE=$2
+
+# The location of Bluetooth within AOSP.
+BT_REL=/system/bt
+BT_ABS=${AOSP_ABS}${BT_REL}
+
+# The location of the test vendor library.
+TEST_VENDOR_LIB_REL=/vendor_libs/test_vendor_lib
+TEST_VENDOR_LIB_ABS=${BT_ABS}${TEST_VENDOR_LIB_REL}
+
+DEVICE_TARGET_REL=/out/target/product
+DEVICE_TARGET_ABS=${AOSP_ABS}${DEVICE_TARGET_REL}
+
+VENDOR_SYMBOLS_REL=/symbols/system/vendor/lib
+VENDOR_SYMBOLS_ABS=${DEVICE_TARGET_ABS}/${DEVICE}/${VENDOR_SYMBOLS_REL}
+
+# The name of the object built by the test vendor library.
+TEST_VENDOR_LIB=test-vendor.so
+# The name of the regular vendor object to be replaced by $TEST_VENDOR_LIB.
+VENDOR_LIB=libbt-vendor.so
+# The config file specifying controller properties.
+CONTROLLER_PROPERTIES=controller_properties.json
+
+if [[ "$#" -eq 4 && $3 == "--test-channel" ]]; then
+  TEST_CHANNEL_PORT=$4
+  TEST_CHANNEL_REL=/scripts
+  TEST_CHANNEL_ABS=${TEST_VENDOR_LIB_ABS}${TEST_CHANNEL_REL}
+
+  # Start logcat in a subshell.
+  x-terminal-emulator -e "scripts/build_and_run.sh ${AOSP_ABS} ${DEVICE}"
+
+  echo "Setting up build environment."
+  cd ${AOSP_ABS}
+  source build/envsetup.sh
+
+  # Forward local port to the same port on the device.
+  echo "Forwarding port ${TEST_CHANNEL_PORT} to device."
+  adb forward tcp:${TEST_CHANNEL_PORT} tcp:${TEST_CHANNEL_PORT}
+
+  # Turn Bluetooth on. Requires user approval via a dialog on the device.
+  echo "Enabling Bluetooth. Please see dialog on device."
+  adb shell am start -a android.bluetooth.adapter.action.REQUEST_ENABLE
+
+  # Start the test channel once Bluetooth is on and logcat has started.
+  read -p "Press [ENTER] once Bluetooth is enabling AND logcat has started."
+
+  # Start the test channel.
+  python ${TEST_CHANNEL_ABS}/test_channel.py localhost ${TEST_CHANNEL_PORT}
+else
+  echo "Setting up build environment."
+  cd ${AOSP_ABS}
+  source build/envsetup.sh
+
+  echo "Navigating to test vendor library: ${TEST_VENDOR_LIB_ABS}"
+  cd ${TEST_VENDOR_LIB_ABS}
+
+  echo "Building test vendor library."
+  mm
+
+  echo "Remounting device rootfs."
+  adb shell mount -o remount,rw /
+  adb remount
+
+  # Replace the actual vendor library with the test vendor library.
+  mv ${DEVICE_TARGET_ABS}/${DEVICE}/system/lib/${TEST_VENDOR_LIB} \
+    ${VENDOR_SYMBOLS_ABS}/${VENDOR_LIB}
+
+  # Push the test vendor library to the device.
+  echo "Pushing the test vendor library to device: $DEVICE"
+  adb push ${VENDOR_SYMBOLS_ABS}/${VENDOR_LIB} /vendor/lib
+
+  echo "Pushing controller properties."
+  adb push ${TEST_VENDOR_LIB_ABS}/data/${CONTROLLER_PROPERTIES} /etc/bluetooth/
+
+  echo "Pushing libevent."
+  adb push ${DEVICE_TARGET_ABS}/${DEVICE}/system/lib/libevent.so /system/lib/
+
+  echo "Pushing libchrome."
+  adb push ${DEVICE_TARGET_ABS}/${DEVICE}/system/lib/libchrome.so /system/lib/
+
+  # Clear logcat.
+  adb logcat -c
+
+  # Run logcat with filters.
+  adb logcat bt_btif:D bt_btif_core:D bt_hci:D bt_main:D bt_vendor:D \
+   bte_logmsg:D command_packet:D dual_mode_controller:D event_packet:D \
+   hci_transport:D hci_handler:D packet:D packet_stream:D \
+   test_channel_transport:D vendor_manager:D *:S
+fi
diff --git a/vendor_libs/test_vendor_lib/scripts/test_channel.py b/vendor_libs/test_vendor_lib/scripts/test_channel.py
new file mode 100644 (file)
index 0000000..cf470f9
--- /dev/null
@@ -0,0 +1,247 @@
+#
+# Copyright 2015 The Android Open Source Project
+#
+# 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.
+#
+
+"""Script for sending testing parameters and commands to a Bluetooth device.
+
+This script provides a simple shell interface for sending data at run-time to a
+Bluetooth device. It is intended to be used in tandem with the test vendor
+library project.
+
+Usage:
+  Option A: Script
+    1. Run build_and_run.sh in scripts/ with the --test-channel flag set and the
+    port to use for the test channel.
+  Option B: Manual
+    1. Choose a port to use for the test channel. Use 'adb forward tcp:<port>
+    tcp:<port>' to forward the port to the device.
+    2. In a separate shell, build and push the test vendor library to the device
+    using the script mentioned in option A (i.e. without the --test-channel flag
+    set).
+    3. Once logcat has started, turn Bluetooth on from the device.
+    4. Run this program, in the shell from step 1,  the port, also from step 1,
+    as arguments.
+"""
+
+#!/usr/bin/env python
+
+import cmd
+import random
+import socket
+import string
+import struct
+import sys
+
+DEVICE_NAME_LENGTH = 6
+DEVICE_ADDRESS_LENGTH = 6
+
+# Used to generate fake device names and addresses during discovery.
+def generate_random_name():
+  return ''.join(random.SystemRandom().choice(string.ascii_uppercase + \
+    string.digits) for _ in range(DEVICE_NAME_LENGTH))
+
+def generate_random_address():
+  return ''.join(random.SystemRandom().choice(string.digits) for _ in \
+    range(DEVICE_ADDRESS_LENGTH))
+
+class Connection(object):
+  """Simple wrapper class for a socket object.
+
+  Attributes:
+    socket: The underlying socket created for the specified address and port.
+  """
+
+  def __init__(self, port):
+    self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    self._socket.connect(('localhost', port))
+
+  def close(self):
+    self._socket.close()
+
+  def send(self, data):
+    self._socket.sendall(data)
+
+class TestChannel(object):
+  """Checks outgoing commands and sends them once verified.
+
+  Attributes:
+    connection: The connection to the test vendor library that commands are sent
+    on.
+  """
+
+  def __init__(self, port):
+    self._connection = Connection(port)
+    self._discovered_devices = DeviceManager()
+
+  def discover_new_device(self, name=None, address=None):
+    device = Device(name, address)
+    self._discovered_devices.add_device(device)
+    return device
+
+  def close(self):
+    self._connection.close()
+
+  def send_command(self, name, args):
+    name_size = len(name)
+    args_size = len(args)
+    self.lint_command(name, args, name_size, args_size)
+    encoded_name = chr(name_size) + name
+    encoded_args = chr(args_size) + ''.join(chr(len(arg)) + arg for arg in args)
+    command = encoded_name + encoded_args
+    self._connection.send(command)
+
+  def lint_command(self, name, args, name_size, args_size):
+    assert name_size == len(name) and args_size == len(args)
+    try:
+      name.encode('utf-8')
+      for arg in args:
+        arg.encode('utf-8')
+    except UnicodeError:
+      print 'Unrecognized characters.'
+      raise
+    if name_size > 255 or args_size > 255:
+      raise ValueError  # Size must be encodable in one octet.
+    for arg in args:
+      if len(arg) > 255:
+        raise ValueError  # Size must be encodable in one octet.
+
+class DeviceManager(object):
+  """Maintains the active fake devices that have been "discovered".
+
+  Attributes:
+    device_list: Maps device addresses (keys) to devices (values).
+  """
+
+  def __init__(self):
+    self.device_list = {}
+
+  def add_device(self, device):
+    self.device_list[device.get_address()] = device
+
+class Device(object):
+  """A fake device to be returned in inquiry and scan results. Note that if an
+  explicit name or address is not provided, a random string of characters
+  is used.
+
+  Attributes:
+    name: The device name for use in extended results.
+    address: The BD address of the device.
+  """
+
+  def __init__(self, name=None, address=None):
+    # TODO(dennischeng): Generate device properties more robustly.
+    self._name = generate_random_name() if name is None else name
+    self._address = generate_random_address() if address is None else address
+
+  def get_name(self):
+    return self._name
+
+  def get_address(self):
+    return self._address
+
+class TestChannelShell(cmd.Cmd):
+  """Shell for sending test channel data to controller.
+
+  Manages the test channel to the controller and defines a set of commands the
+  user can send to the controller as well. These commands are processed parallel
+  to commands sent from the device stack and used to provide additional
+  debugging/testing capabilities.
+
+  Attributes:
+    test_channel: The communication channel to send data to the controller.
+  """
+
+  def __init__(self, test_channel):
+    print 'Type \'help\' for more information.'
+    cmd.Cmd.__init__(self)
+    self._test_channel = test_channel
+
+  def do_clear(self, args):
+    """
+    Arguments: None.
+    Resets the controller to its original, unmodified state.
+    """
+    self._test_channel.send_command('CLEAR', [])
+
+  def do_clear_event_delay(self, args):
+    """
+    Arguments: None.
+    Clears the response delay set by set_event_delay.
+    """
+    self._test_channel.send_command('CLEAR_EVENT_DELAY', args.split())
+
+  def do_discover(self, args):
+    """
+    Arguments: name_1 name_2 ...
+    Sends an inquiry result for named device(s). If no names are provided, a
+    random name is used instead.
+    """
+    if len(args) == 0:
+      args = generate_random_name()
+    device_list = [self._test_channel.discover_new_device(arg) for arg in \
+                   args.split()]
+    device_names_and_addresses = []
+    for device in device_list:
+      device_names_and_addresses.append(device.get_name())
+      device_names_and_addresses.append(device.get_address())
+    self._test_channel.send_command('DISCOVER', device_names_and_addresses)
+
+  def do_set_event_delay(self, args):
+    """
+    Arguments: interval_in_ms
+    Sets the response delay for all event packets sent from the controller back
+    to the HCI.
+    """
+    self._test_channel.send_command('SET_EVENT_DELAY', args.split())
+
+  def do_timeout_all(self, args):
+    """
+    Arguments: None.
+    Causes all HCI commands to timeout.
+    """
+    self._test_channel.send_command('TIMEOUT_ALL', [])
+
+  def do_quit(self, args):
+    """
+    Arguments: None.
+    Exits the test channel.
+    """
+    self._test_channel.send_command('CLOSE_TEST_CHANNEL', [])
+    self._test_channel.close()
+    print 'Goodbye.'
+    return True
+
+def main(argv):
+  if len(argv) != 2:
+    print 'Usage: python test_channel.py [port]'
+    return
+  try:
+    port = int(argv[1])
+  except ValueError:
+    print 'Error parsing port.'
+  else:
+    try:
+      test_channel = TestChannel(port)
+    except socket.error, e:
+      print 'Error connecting to socket: %s' % e
+    except:
+      print 'Error creating test channel (check argument).'
+    else:
+      test_channel_shell = TestChannelShell(test_channel)
+      test_channel_shell.prompt = '$ '
+      test_channel_shell.cmdloop()
+
+if __name__ == '__main__':
+  main(sys.argv)
diff --git a/vendor_libs/test_vendor_lib/src/bt_vendor.cc b/vendor_libs/test_vendor_lib/src/bt_vendor.cc
new file mode 100644 (file)
index 0000000..81538ac
--- /dev/null
@@ -0,0 +1,107 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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_vendor"
+
+#include "vendor_manager.h"
+
+#include "base/logging.h"
+
+extern "C" {
+#include "osi/include/log.h"
+
+#include <unistd.h>
+}  // extern "C"
+
+namespace test_vendor_lib {
+
+// Initializes vendor manager for test controller. |p_cb| are the callbacks to
+// be in TestVendorOp(). |local_bdaddr| points to the address of the Bluetooth
+// device. Returns 0 on success, -1 on error.
+static int TestVendorInitialize(const bt_vendor_callbacks_t* p_cb,
+                                unsigned char* /* local_bdaddr */) {
+  LOG_INFO(LOG_TAG, "Initializing test controller.");
+  CHECK(p_cb);
+
+  VendorManager::Initialize();
+  VendorManager* manager = VendorManager::Get();
+  manager->SetVendorCallbacks(*(const_cast<bt_vendor_callbacks_t*>(p_cb)));
+  return manager->Run() ? 0 : -1;
+}
+
+// Vendor specific operations. |opcode| is the opcode for Bluedroid's vendor op
+// definitions. |param| points to operation specific arguments. Return value is
+// dependent on the operation invoked, or -1 on error.
+static int TestVendorOp(bt_vendor_opcode_t opcode, void* param) {
+  LOG_INFO(LOG_TAG, "Opcode received in vendor library: %d", opcode);
+
+  VendorManager* manager = VendorManager::Get();
+  CHECK(manager);
+
+  switch (opcode) {
+    case BT_VND_OP_POWER_CTRL: {
+      LOG_INFO(LOG_TAG, "Doing op: BT_VND_OP_POWER_CTRL");
+      int* state = static_cast<int*>(param);
+      if (*state == BT_VND_PWR_OFF)
+        LOG_INFO(LOG_TAG, "Turning Bluetooth off.");
+      else if (*state == BT_VND_PWR_ON)
+        LOG_INFO(LOG_TAG, "Turning Bluetooth on.");
+      return 0;
+    }
+
+    // Give the HCI its fd to communicate with the HciTransport.
+    case BT_VND_OP_USERIAL_OPEN: {
+      LOG_INFO(LOG_TAG, "Doing op: BT_VND_OP_USERIAL_OPEN");
+      int* fd_list = static_cast<int*>(param);
+      fd_list[0] = manager->GetHciFd();
+      LOG_INFO(LOG_TAG, "Setting HCI's fd to: %d", fd_list[0]);
+      return 1;
+    }
+
+    // Close the HCI's file descriptor.
+    case BT_VND_OP_USERIAL_CLOSE:
+      LOG_INFO(LOG_TAG, "Doing op: BT_VND_OP_USERIAL_CLOSE");
+      LOG_INFO(LOG_TAG, "Closing HCI's fd (fd: %d)", manager->GetHciFd());
+      manager->CloseHciFd();
+      return 1;
+
+    case BT_VND_OP_FW_CFG:
+      LOG_INFO(LOG_TAG, "Unsupported op: BT_VND_OP_FW_CFG");
+      manager->GetVendorCallbacks().fwcfg_cb(BT_VND_OP_RESULT_FAIL);
+      return -1;
+
+    default:
+      LOG_INFO(LOG_TAG, "Op not recognized.");
+      return -1;
+  }
+  return 0;
+}
+
+// Closes the vendor interface and cleans up the global vendor manager object.
+static void TestVendorCleanUp(void) {
+  LOG_INFO(LOG_TAG, "Cleaning up vendor library.");
+  VendorManager::CleanUp();
+}
+
+}  // namespace test_vendor_lib
+
+// Entry point of DLib.
+const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
+  sizeof(bt_vendor_interface_t),
+  test_vendor_lib::TestVendorInitialize,
+  test_vendor_lib::TestVendorOp,
+  test_vendor_lib::TestVendorCleanUp
+};
diff --git a/vendor_libs/test_vendor_lib/src/command_packet.cc b/vendor_libs/test_vendor_lib/src/command_packet.cc
new file mode 100644 (file)
index 0000000..7197233
--- /dev/null
@@ -0,0 +1,43 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 "command_packet"
+
+#include "vendor_libs/test_vendor_lib/include/command_packet.h"
+
+extern "C" {
+#include "hci/include/hci_hal.h"
+#include "osi/include/log.h"
+#include "stack/include/hcidefs.h"
+}  // extern "C"
+
+namespace test_vendor_lib {
+
+CommandPacket::CommandPacket() : Packet(DATA_TYPE_COMMAND) {}
+
+uint16_t CommandPacket::GetOpcode() const {
+  return 0 | (GetHeader()[0] | (GetHeader()[1] << 8));
+}
+
+uint8_t CommandPacket::GetOGF() const {
+  return HCI_OGF(GetOpcode());
+}
+
+uint16_t CommandPacket::GetOCF() const {
+  return HCI_OCF(GetOpcode());
+}
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/src/dual_mode_controller.cc b/vendor_libs/test_vendor_lib/src/dual_mode_controller.cc
new file mode 100644 (file)
index 0000000..c21d9a5
--- /dev/null
@@ -0,0 +1,561 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 "dual_mode_controller"
+
+#include "vendor_libs/test_vendor_lib/include/dual_mode_controller.h"
+
+#include "base/logging.h"
+#include "base/files/file_util.h"
+#include "base/json/json_reader.h"
+#include "base/values.h"
+#include "vendor_libs/test_vendor_lib/include/event_packet.h"
+#include "vendor_libs/test_vendor_lib/include/hci_transport.h"
+
+extern "C" {
+#include "stack/include/hcidefs.h"
+#include "osi/include/log.h"
+}  // extern "C"
+
+namespace {
+
+// Included in certain events to indicate success (specific to the event
+// context).
+const uint8_t kSuccessStatus = 0;
+
+// The default number encoded in event packets to indicate to the HCI how many
+// command packets it can send to the controller.
+const uint8_t kNumHciCommandPackets = 1;
+
+// The location of the config file loaded to populate controller attributes.
+const std::string kControllerPropertiesFile =
+    "/etc/bluetooth/controller_properties.json";
+
+// Inquiry modes for specifiying inquiry result formats.
+const uint8_t kStandardInquiry = 0x00;
+const uint8_t kRssiInquiry = 0x01;
+const uint8_t kExtendedOrRssiInquiry = 0x02;
+
+// The bd address of another (fake) device.
+const std::vector<uint8_t> kOtherDeviceBdAddress = {6, 5, 4, 3, 2, 1};
+
+// Fake inquiry response for a fake device.
+const std::vector<uint8_t> kPageScanRepetitionMode = {0};
+const std::vector<uint8_t> kPageScanPeriodMode = {0};
+const std::vector<uint8_t> kPageScanMode = {0};
+const std::vector<uint8_t> kClassOfDevice = {1, 2, 3};
+const std::vector<uint8_t> kClockOffset = {1, 2};
+
+void LogCommand(const char* command) {
+  LOG_INFO(LOG_TAG, "Controller performing command: %s", command);
+}
+
+// Functions used by JSONValueConverter to read stringified JSON into Properties
+// object.
+bool ParseUint8t(const base::StringPiece& value, uint8_t* field) {
+  *field = std::stoi(value.as_string());
+  return true;
+}
+
+bool ParseUint16t(const base::StringPiece& value, uint16_t* field) {
+  *field = std::stoi(value.as_string());
+  return true;
+}
+
+bool ParseUint8tVector(const base::StringPiece& value,
+                              std::vector<uint8_t>* field) {
+  for (char& c : value.as_string())
+    field->push_back(c - '0');
+  return true;
+}
+
+}  // namespace
+
+namespace test_vendor_lib {
+
+void DualModeController::SendCommandComplete(
+    uint16_t command_opcode,
+    const std::vector<uint8_t>& return_parameters) const {
+  std::unique_ptr<EventPacket> command_complete =
+      EventPacket::CreateCommandCompleteEvent(
+          kNumHciCommandPackets, command_opcode, return_parameters);
+  send_event_(std::move(command_complete));
+}
+
+void DualModeController::SendCommandCompleteSuccess(
+    uint16_t command_opcode) const {
+  SendCommandComplete(command_opcode, {kSuccessStatus});
+}
+
+void DualModeController::SendCommandStatus(uint8_t status,
+                                           uint16_t command_opcode) const {
+  std::unique_ptr<EventPacket> command_status =
+      EventPacket::CreateCommandStatusEvent(status, kNumHciCommandPackets,
+                                            command_opcode);
+  send_event_(std::move(command_status));
+}
+
+void DualModeController::SendCommandStatusSuccess(
+    uint16_t command_opcode) const {
+  SendCommandStatus(kSuccessStatus, command_opcode);
+}
+
+void DualModeController::SendInquiryResult() const {
+  std::unique_ptr<EventPacket> inquiry_result =
+      EventPacket::CreateInquiryResultEvent(
+          1, kOtherDeviceBdAddress, kPageScanRepetitionMode,
+          kPageScanPeriodMode, kPageScanMode, kClassOfDevice, kClockOffset);
+  send_event_(std::move(inquiry_result));
+}
+
+void DualModeController::SendExtendedInquiryResult(
+    const std::string& name, const std::string& address) const {
+  std::vector<uint8_t> rssi = {0};
+  std::vector<uint8_t> extended_inquiry_data = {name.length() + 1, 0x09};
+  std::copy(name.begin(), name.end(),
+            std::back_inserter(extended_inquiry_data));
+  std::vector<uint8_t> bd_address(address.begin(), address.end());
+  // TODO(dennischeng): Use constants for parameter sizes, here and elsewhere.
+  while (extended_inquiry_data.size() < 240) {
+    extended_inquiry_data.push_back(0);
+  }
+  std::unique_ptr<EventPacket> extended_inquiry_result =
+      EventPacket::CreateExtendedInquiryResultEvent(
+          bd_address, kPageScanRepetitionMode, kPageScanPeriodMode,
+          kClassOfDevice, kClockOffset, rssi, extended_inquiry_data);
+  send_event_(std::move(extended_inquiry_result));
+}
+
+DualModeController::DualModeController()
+    : state_(kStandby),
+      test_channel_state_(kNone),
+      properties_(kControllerPropertiesFile) {
+#define SET_HANDLER(opcode, method) \
+  active_hci_commands_[opcode] =    \
+      std::bind(&DualModeController::method, this, std::placeholders::_1);
+  SET_HANDLER(HCI_RESET, HciReset);
+  SET_HANDLER(HCI_READ_BUFFER_SIZE, HciReadBufferSize);
+  SET_HANDLER(HCI_HOST_BUFFER_SIZE, HciHostBufferSize);
+  SET_HANDLER(HCI_READ_LOCAL_VERSION_INFO, HciReadLocalVersionInformation);
+  SET_HANDLER(HCI_READ_BD_ADDR, HciReadBdAddr);
+  SET_HANDLER(HCI_READ_LOCAL_SUPPORTED_CMDS, HciReadLocalSupportedCommands);
+  SET_HANDLER(HCI_READ_LOCAL_EXT_FEATURES, HciReadLocalExtendedFeatures);
+  SET_HANDLER(HCI_WRITE_SIMPLE_PAIRING_MODE, HciWriteSimplePairingMode);
+  SET_HANDLER(HCI_WRITE_LE_HOST_SUPPORT, HciWriteLeHostSupport);
+  SET_HANDLER(HCI_SET_EVENT_MASK, HciSetEventMask);
+  SET_HANDLER(HCI_WRITE_INQUIRY_MODE, HciWriteInquiryMode);
+  SET_HANDLER(HCI_WRITE_PAGESCAN_TYPE, HciWritePageScanType);
+  SET_HANDLER(HCI_WRITE_INQSCAN_TYPE, HciWriteInquiryScanType);
+  SET_HANDLER(HCI_WRITE_CLASS_OF_DEVICE, HciWriteClassOfDevice);
+  SET_HANDLER(HCI_WRITE_PAGE_TOUT, HciWritePageTimeout);
+  SET_HANDLER(HCI_WRITE_DEF_POLICY_SETTINGS, HciWriteDefaultLinkPolicySettings);
+  SET_HANDLER(HCI_READ_LOCAL_NAME, HciReadLocalName);
+  SET_HANDLER(HCI_CHANGE_LOCAL_NAME, HciWriteLocalName);
+  SET_HANDLER(HCI_WRITE_EXT_INQ_RESPONSE, HciWriteExtendedInquiryResponse);
+  SET_HANDLER(HCI_WRITE_VOICE_SETTINGS, HciWriteVoiceSetting);
+  SET_HANDLER(HCI_WRITE_CURRENT_IAC_LAP, HciWriteCurrentIacLap);
+  SET_HANDLER(HCI_WRITE_INQUIRYSCAN_CFG, HciWriteInquiryScanActivity);
+  SET_HANDLER(HCI_WRITE_SCAN_ENABLE, HciWriteScanEnable);
+  SET_HANDLER(HCI_SET_EVENT_FILTER, HciSetEventFilter);
+  SET_HANDLER(HCI_INQUIRY, HciInquiry);
+  SET_HANDLER(HCI_INQUIRY_CANCEL, HciInquiryCancel);
+  SET_HANDLER(HCI_DELETE_STORED_LINK_KEY, HciDeleteStoredLinkKey);
+  SET_HANDLER(HCI_RMT_NAME_REQUEST, HciRemoteNameRequest);
+#undef SET_HANDLER
+
+#define SET_TEST_HANDLER(command_name, method)  \
+  active_test_channel_commands_[command_name] = \
+      std::bind(&DualModeController::method, this, std::placeholders::_1);
+  SET_TEST_HANDLER("CLEAR", TestChannelClear);
+  SET_TEST_HANDLER("CLEAR_EVENT_DELAY", TestChannelClearEventDelay);
+  SET_TEST_HANDLER("DISCOVER", TestChannelDiscover);
+  SET_TEST_HANDLER("SET_EVENT_DELAY", TestChannelSetEventDelay);
+  SET_TEST_HANDLER("TIMEOUT_ALL", TestChannelTimeoutAll);
+#undef SET_TEST_HANDLER
+}
+
+void DualModeController::RegisterHandlersWithHciTransport(
+    HciTransport& transport) {
+  transport.RegisterCommandHandler(std::bind(&DualModeController::HandleCommand,
+                                             this, std::placeholders::_1));
+}
+
+void DualModeController::RegisterHandlersWithTestChannelTransport(
+    TestChannelTransport& transport) {
+  transport.RegisterCommandHandler(
+      std::bind(&DualModeController::HandleTestChannelCommand, this,
+                std::placeholders::_1, std::placeholders::_2));
+}
+
+void DualModeController::HandleTestChannelCommand(
+    const std::string& name, const std::vector<std::string>& args) {
+  if (active_test_channel_commands_.count(name) == 0)
+    return;
+  active_test_channel_commands_[name](args);
+}
+
+void DualModeController::HandleCommand(
+    std::unique_ptr<CommandPacket> command_packet) {
+  uint16_t opcode = command_packet->GetOpcode();
+  LOG_INFO(LOG_TAG, "Command opcode: 0x%04X, OGF: 0x%04X, OCF: 0x%04X", opcode,
+           command_packet->GetOGF(), command_packet->GetOCF());
+
+  // The command hasn't been registered with the handler yet. There is nothing
+  // to do.
+  if (active_hci_commands_.count(opcode) == 0)
+    return;
+  else if (test_channel_state_ == kTimeoutAll)
+    return;
+  active_hci_commands_[opcode](command_packet->GetPayload());
+}
+
+void DualModeController::RegisterEventChannel(
+    std::function<void(std::unique_ptr<EventPacket>)> callback) {
+  send_event_ = callback;
+}
+
+void DualModeController::RegisterDelayedEventChannel(
+    std::function<void(std::unique_ptr<EventPacket>, base::TimeDelta)>
+        callback) {
+  send_delayed_event_ = callback;
+  SetEventDelay(0);
+}
+
+void DualModeController::SetEventDelay(int64_t delay) {
+  if (delay < 0)
+    delay = 0;
+  send_event_ = std::bind(send_delayed_event_, std::placeholders::_1,
+                          base::TimeDelta::FromMilliseconds(delay));
+}
+
+void DualModeController::TestChannelClear(
+    const std::vector<std::string>& args) {
+  LogCommand("TestChannel Clear");
+  test_channel_state_ = kNone;
+  SetEventDelay(0);
+}
+
+void DualModeController::TestChannelDiscover(
+    const std::vector<std::string>& args) {
+  LogCommand("TestChannel Discover");
+  for (size_t i = 0; i < args.size()-1; i+=2)
+    SendExtendedInquiryResult(args[i], args[i+1]);
+}
+
+void DualModeController::TestChannelTimeoutAll(
+    const std::vector<std::string>& args) {
+  LogCommand("TestChannel Timeout All");
+  test_channel_state_ = kTimeoutAll;
+}
+
+void DualModeController::TestChannelSetEventDelay(
+    const std::vector<std::string>& args) {
+  LogCommand("TestChannel Set Event Delay");
+  test_channel_state_ = kDelayedResponse;
+  SetEventDelay(std::stoi(args[0]));
+}
+
+void DualModeController::TestChannelClearEventDelay(
+    const std::vector<std::string>& args) {
+  LogCommand("TestChannel Clear Event Delay");
+  test_channel_state_ = kNone;
+  SetEventDelay(0);
+}
+
+void DualModeController::HciReset(const std::vector<uint8_t>& /* args */) {
+  LogCommand("Reset");
+  state_ = kStandby;
+  SendCommandCompleteSuccess(HCI_RESET);
+}
+
+void DualModeController::HciReadBufferSize(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Read Buffer Size");
+  SendCommandComplete(HCI_READ_BUFFER_SIZE, properties_.GetBufferSize());
+}
+
+void DualModeController::HciHostBufferSize(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Host Buffer Size");
+  SendCommandCompleteSuccess(HCI_HOST_BUFFER_SIZE);
+}
+
+void DualModeController::HciReadLocalVersionInformation(
+                 const std::vector<uint8_t>& /* args */) {
+  LogCommand("Read Local Version Information");
+  SendCommandComplete(HCI_READ_LOCAL_VERSION_INFO,
+                      properties_.GetLocalVersionInformation());
+}
+
+void DualModeController::HciReadBdAddr(const std::vector<uint8_t>& /* args */) {
+  LogCommand("Read Bd Addr");
+  std::vector<uint8_t> bd_address_with_status = properties_.GetBdAddress();
+  bd_address_with_status.insert(bd_address_with_status.begin(),
+                                kSuccessStatus);
+  SendCommandComplete(HCI_READ_BD_ADDR, bd_address_with_status);
+}
+
+void DualModeController::HciReadLocalSupportedCommands(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Read Local Supported Commands");
+  SendCommandComplete(HCI_READ_LOCAL_SUPPORTED_CMDS,
+                      properties_.GetLocalSupportedCommands());
+}
+
+void DualModeController::HciReadLocalExtendedFeatures(
+    const std::vector<uint8_t>& args) {
+  LogCommand("Read Local Extended Features");
+  SendCommandComplete(HCI_READ_LOCAL_EXT_FEATURES,
+                      properties_.GetLocalExtendedFeatures(args[0]));
+}
+
+void DualModeController::HciWriteSimplePairingMode(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Write Simple Pairing Mode");
+  SendCommandCompleteSuccess(HCI_WRITE_SIMPLE_PAIRING_MODE);
+}
+
+void DualModeController::HciWriteLeHostSupport(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Write Le Host Support");
+  SendCommandCompleteSuccess(HCI_WRITE_LE_HOST_SUPPORT);
+}
+
+void DualModeController::HciSetEventMask(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Set Event Mask");
+  SendCommandCompleteSuccess(HCI_SET_EVENT_MASK);
+}
+
+void DualModeController::HciWriteInquiryMode(const std::vector<uint8_t>& args) {
+  LogCommand("Write Inquiry Mode");
+  CHECK(args.size() == 1);
+  inquiry_mode_ = args[0];
+  SendCommandCompleteSuccess(HCI_WRITE_INQUIRY_MODE);
+}
+
+void DualModeController::HciWritePageScanType(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Write Page Scan Type");
+  SendCommandCompleteSuccess(HCI_WRITE_PAGESCAN_TYPE);
+}
+
+void DualModeController::HciWriteInquiryScanType(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Write Inquiry Scan Type");
+  SendCommandCompleteSuccess(HCI_WRITE_INQSCAN_TYPE);
+}
+
+void DualModeController::HciWriteClassOfDevice(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Write Class Of Device");
+  SendCommandCompleteSuccess(HCI_WRITE_CLASS_OF_DEVICE);
+}
+
+void DualModeController::HciWritePageTimeout(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Write Page Timeout");
+  SendCommandCompleteSuccess(HCI_WRITE_PAGE_TOUT);
+}
+
+void DualModeController::HciWriteDefaultLinkPolicySettings(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Write Default Link Policy Settings");
+  SendCommandCompleteSuccess(HCI_WRITE_DEF_POLICY_SETTINGS);
+}
+
+void DualModeController::HciReadLocalName(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Get Local Name");
+  SendCommandComplete(HCI_READ_LOCAL_NAME, properties_.GetLocalName());
+}
+
+void DualModeController::HciWriteLocalName(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Write Local Name");
+  SendCommandCompleteSuccess(HCI_CHANGE_LOCAL_NAME);
+}
+
+void DualModeController::HciWriteExtendedInquiryResponse(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Write Extended Inquiry Response");
+  SendCommandCompleteSuccess(HCI_WRITE_EXT_INQ_RESPONSE);
+}
+
+void DualModeController::HciWriteVoiceSetting(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Write Voice Setting");
+  SendCommandCompleteSuccess(HCI_WRITE_VOICE_SETTINGS);
+}
+
+void DualModeController::HciWriteCurrentIacLap(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Write Current IAC LAP");
+  SendCommandCompleteSuccess(HCI_WRITE_CURRENT_IAC_LAP);
+}
+
+void DualModeController::HciWriteInquiryScanActivity(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Write Inquiry Scan Activity");
+  SendCommandCompleteSuccess(HCI_WRITE_INQUIRYSCAN_CFG);
+}
+
+void DualModeController::HciWriteScanEnable(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Write Scan Enable");
+  SendCommandCompleteSuccess(HCI_WRITE_SCAN_ENABLE);
+}
+
+void DualModeController::HciSetEventFilter(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Set Event Filter");
+  SendCommandCompleteSuccess(HCI_SET_EVENT_FILTER);
+}
+
+void DualModeController::HciInquiry(const std::vector<uint8_t>& /* args */) {
+  LogCommand("Inquiry");
+  state_ = kInquiry;
+  SendCommandStatusSuccess(HCI_INQUIRY);
+  switch (inquiry_mode_) {
+    case (kStandardInquiry):
+      SendInquiryResult();
+      break;
+
+    case (kRssiInquiry):
+      LOG_INFO(LOG_TAG, "RSSI Inquiry Mode currently not supported.");
+      break;
+
+    case (kExtendedOrRssiInquiry):
+      SendExtendedInquiryResult("FooBar", "123456");
+      break;
+  }
+}
+
+void DualModeController::HciInquiryCancel(
+    const std::vector<uint8_t>& /* args */) {
+  LogCommand("Inquiry Cancel");
+  CHECK(state_ == kInquiry);
+  state_ = kStandby;
+  SendCommandCompleteSuccess(HCI_INQUIRY_CANCEL);
+}
+
+void DualModeController::HciDeleteStoredLinkKey(
+    const std::vector<uint8_t>& args) {
+  LogCommand("Delete Stored Link Key");
+  /* Check the last octect in |args|. If it is 0, delete only the link key for
+   * the given BD_ADDR. If is is 1, delete all stored link keys. */
+  SendCommandComplete(HCI_DELETE_STORED_LINK_KEY, {1});
+}
+
+void DualModeController::HciRemoteNameRequest(
+    const std::vector<uint8_t>& args) {
+  LogCommand("Remote Name Request");
+  SendCommandStatusSuccess(HCI_RMT_NAME_REQUEST);
+}
+
+DualModeController::Properties::Properties(const std::string& file_name)
+    : local_supported_commands_size_(64), local_name_size_(248) {
+  std::string properties_raw;
+  if (!base::ReadFileToString(base::FilePath(file_name), &properties_raw))
+    LOG_INFO(LOG_TAG, "Error reading controller properties from file.");
+
+  scoped_ptr<base::Value> properties_value_ptr =
+      base::JSONReader::Read(properties_raw);
+  if (properties_value_ptr.get() == nullptr)
+    LOG_INFO(LOG_TAG,
+             "Error controller properties may consist of ill-formed JSON.");
+
+  // Get the underlying base::Value object, which is of type
+  // base::Value::TYPE_DICTIONARY, and read it into member variables.
+  base::Value& properties_dictionary = *(properties_value_ptr.get());
+  base::JSONValueConverter<DualModeController::Properties> converter;
+
+  if (!converter.Convert(properties_dictionary, this))
+    LOG_INFO(LOG_TAG,
+             "Error converting JSON properties into Properties object.");
+}
+
+const std::vector<uint8_t> DualModeController::Properties::GetBufferSize() {
+  return std::vector<uint8_t>(
+      {kSuccessStatus, acl_data_packet_size_, acl_data_packet_size_ >> 8,
+       sco_data_packet_size_, num_acl_data_packets_, num_acl_data_packets_ >> 8,
+       num_sco_data_packets_, num_sco_data_packets_ >> 8});
+}
+
+const std::vector<uint8_t>
+DualModeController::Properties::GetLocalVersionInformation() {
+  return std::vector<uint8_t>({kSuccessStatus, version_, revision_,
+                               revision_ >> 8, lmp_pal_version_,
+                               manufacturer_name_, manufacturer_name_ >> 8,
+                               lmp_pal_subversion_, lmp_pal_subversion_ >> 8});
+}
+
+const std::vector<uint8_t> DualModeController::Properties::GetBdAddress() {
+  return bd_address_;
+}
+
+const std::vector<uint8_t>
+DualModeController::Properties::GetLocalExtendedFeatures(uint8_t page_number) {
+  return std::vector<uint8_t>({kSuccessStatus, page_number,
+                               maximum_page_number_, 0xFF, 0xFF, 0xFF, 0xFF,
+                               0xFF, 0xFF, 0xFF, 0xFF});
+}
+
+const std::vector<uint8_t>
+DualModeController::Properties::GetLocalSupportedCommands() {
+  std::vector<uint8_t> local_supported_commands;
+  local_supported_commands.push_back(kSuccessStatus);
+  for (uint8_t i = 0; i < local_supported_commands_size_; ++i)
+    local_supported_commands.push_back(0xFF);
+  return local_supported_commands;
+}
+
+const std::vector<uint8_t> DualModeController::Properties::GetLocalName() {
+  std::vector<uint8_t> local_name;
+  local_name.push_back(kSuccessStatus);
+  for (uint8_t i = 0; i < local_name_size_; ++i)
+    local_name.push_back(0xFF);
+  return local_name;
+}
+
+// static
+void DualModeController::Properties::RegisterJSONConverter(
+    base::JSONValueConverter<DualModeController::Properties>* converter) {
+  // TODO(dennischeng): Use RegisterIntField() here?
+#define REGISTER_UINT8_T(field_name, field) \
+  converter->RegisterCustomField<uint8_t>(  \
+      field_name, &DualModeController::Properties::field, &ParseUint8t);
+#define REGISTER_UINT16_T(field_name, field) \
+  converter->RegisterCustomField<uint16_t>(  \
+      field_name, &DualModeController::Properties::field, &ParseUint16t);
+  REGISTER_UINT16_T("AclDataPacketSize", acl_data_packet_size_);
+  REGISTER_UINT8_T("ScoDataPacketSize", sco_data_packet_size_);
+  REGISTER_UINT16_T("NumAclDataPackets", num_acl_data_packets_);
+  REGISTER_UINT16_T("NumScoDataPackets", num_sco_data_packets_);
+  REGISTER_UINT8_T("Version", version_);
+  REGISTER_UINT16_T("Revision", revision_);
+  REGISTER_UINT8_T("LmpPalVersion", lmp_pal_version_);
+  REGISTER_UINT16_T("ManufacturerName", manufacturer_name_);
+  REGISTER_UINT16_T("LmpPalSubversion", lmp_pal_subversion_);
+  REGISTER_UINT8_T("MaximumPageNumber", maximum_page_number_);
+  converter->RegisterCustomField<std::vector<uint8_t>>(
+      "BdAddress", &DualModeController::Properties::bd_address_,
+      &ParseUint8tVector);
+#undef REGISTER_UINT8_T
+#undef REGISTER_UINT16_T
+}
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/src/event_packet.cc b/vendor_libs/test_vendor_lib/src/event_packet.cc
new file mode 100644 (file)
index 0000000..d003bb1
--- /dev/null
@@ -0,0 +1,131 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 "event_packet"
+
+#define VECTOR_COPY_TO_END(source, destination) \
+  std::copy(source.begin(), source.end(), std::back_inserter(destination));
+
+#include "vendor_libs/test_vendor_lib/include/event_packet.h"
+
+extern "C" {
+#include "osi/include/log.h"
+#include "stack/include/hcidefs.h"
+}  // extern "C"
+
+namespace test_vendor_lib {
+
+EventPacket::EventPacket(uint8_t event_code,
+                         const std::vector<uint8_t>& payload)
+    : Packet(DATA_TYPE_EVENT) {
+  Encode({event_code, static_cast<uint8_t>(payload.size())}, payload);
+}
+
+uint8_t EventPacket::GetEventCode() const {
+  return GetHeader()[0];
+}
+
+// static
+std::unique_ptr<EventPacket> EventPacket::CreateCommandCompleteEvent(
+    uint8_t num_hci_command_packets, uint16_t command_opcode,
+    const std::vector<uint8_t>& event_return_parameters) {
+  size_t payload_size = sizeof(num_hci_command_packets) +
+                        sizeof(command_opcode) + event_return_parameters.size();
+
+  std::vector<uint8_t> payload;
+  payload.reserve(payload_size);
+  payload.push_back(num_hci_command_packets);
+  payload.push_back(command_opcode);
+  payload.push_back(command_opcode >> 8);
+  VECTOR_COPY_TO_END(event_return_parameters, payload);
+
+  return std::unique_ptr<EventPacket>(
+      new EventPacket(HCI_COMMAND_COMPLETE_EVT, payload));
+}
+
+// static
+std::unique_ptr<EventPacket> EventPacket::CreateCommandStatusEvent(
+    uint8_t status, uint8_t num_hci_command_packets, uint16_t command_opcode) {
+  size_t payload_size =
+      sizeof(status) + sizeof(num_hci_command_packets) + sizeof(command_opcode);
+
+  std::vector<uint8_t> payload;
+  payload.reserve(payload_size);
+  payload.push_back(status);
+  payload.push_back(num_hci_command_packets);
+  payload.push_back(command_opcode);
+  payload.push_back(command_opcode >> 8);
+
+  return std::unique_ptr<EventPacket>(
+      new EventPacket(HCI_COMMAND_STATUS_EVT, payload));
+}
+
+//static
+std::unique_ptr<EventPacket> EventPacket::CreateInquiryResultEvent(
+    uint8_t num_responses, const std::vector<uint8_t>& bd_addresses,
+    const std::vector<uint8_t>& page_scan_repetition_mode,
+    const std::vector<uint8_t>& page_scan_period_mode,
+    const std::vector<uint8_t>& page_scan_mode,
+    const std::vector<uint8_t>& class_of_device,
+    const std::vector<uint8_t>& clock_offset) {
+  size_t payload_size = sizeof(num_responses) + bd_addresses.size() +
+                        page_scan_repetition_mode.size() +
+                        page_scan_period_mode.size() + page_scan_mode.size() +
+                        class_of_device.size() + clock_offset.size();
+
+  std::vector<uint8_t> payload;
+  payload.reserve(payload_size);
+  payload.push_back(num_responses);
+  VECTOR_COPY_TO_END(bd_addresses, payload);
+  VECTOR_COPY_TO_END(page_scan_repetition_mode, payload);
+  VECTOR_COPY_TO_END(page_scan_mode, payload);
+  VECTOR_COPY_TO_END(class_of_device, payload);
+  VECTOR_COPY_TO_END(clock_offset, payload);
+
+  return std::unique_ptr<EventPacket>(
+      new EventPacket(HCI_INQUIRY_RESULT_EVT, payload));
+}
+
+//static
+std::unique_ptr<EventPacket> EventPacket::CreateExtendedInquiryResultEvent(
+    const std::vector<uint8_t>& bd_address,
+    const std::vector<uint8_t>& page_scan_repetition_mode,
+    const std::vector<uint8_t>& page_scan_period_mode,
+    const std::vector<uint8_t>& class_of_device,
+    const std::vector<uint8_t>& clock_offset,
+    const std::vector<uint8_t>& rssi,
+    const std::vector<uint8_t>& extended_inquiry_response) {
+  size_t payload_size =
+      1 + bd_address.size() + page_scan_repetition_mode.size() +
+      page_scan_period_mode.size() + class_of_device.size() +
+      clock_offset.size() + rssi.size() + extended_inquiry_response.size();
+
+  std::vector<uint8_t> payload;
+  payload.reserve(payload_size);
+  payload.push_back(1);  // Each extended inquiry result contains one device.
+  VECTOR_COPY_TO_END(bd_address, payload);
+  VECTOR_COPY_TO_END(page_scan_repetition_mode, payload);
+  VECTOR_COPY_TO_END(page_scan_period_mode, payload);
+  VECTOR_COPY_TO_END(class_of_device, payload);
+  VECTOR_COPY_TO_END(clock_offset, payload);
+  VECTOR_COPY_TO_END(rssi, payload);
+  VECTOR_COPY_TO_END(extended_inquiry_response, payload);
+
+  return std::unique_ptr<EventPacket>(
+      new EventPacket(HCI_EXTENDED_INQUIRY_RESULT_EVT, payload));
+}
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/src/hci_transport.cc b/vendor_libs/test_vendor_lib/src/hci_transport.cc
new file mode 100644 (file)
index 0000000..8e64f71
--- /dev/null
@@ -0,0 +1,174 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 "hci_transport"
+
+#include "vendor_libs/test_vendor_lib/include/hci_transport.h"
+
+#include "base/logging.h"
+#include "base/bind.h"
+#include "base/thread_task_runner_handle.h"
+
+extern "C" {
+#include <sys/socket.h>
+
+#include "stack/include/hcidefs.h"
+#include "osi/include/log.h"
+}  // extern "C"
+
+namespace test_vendor_lib {
+
+HciTransport::HciTransport() : weak_ptr_factory_(this) {}
+
+void HciTransport::CloseHciFd() {
+  hci_fd_.reset(nullptr);
+}
+
+void HciTransport::CloseVendorFd() {
+  vendor_fd_.reset(nullptr);
+}
+
+int HciTransport::GetHciFd() const {
+  return hci_fd_->get();
+}
+
+int HciTransport::GetVendorFd() const {
+  return vendor_fd_->get();
+}
+
+bool HciTransport::SetUp() {
+  int socketpair_fds[2];
+  // TODO(dennischeng): Use SOCK_SEQPACKET here.
+  const int success = socketpair(AF_LOCAL, SOCK_STREAM, 0, socketpair_fds);
+  if (success < 0)
+    return false;
+  hci_fd_.reset(new base::ScopedFD(socketpair_fds[0]));
+  vendor_fd_.reset(new base::ScopedFD(socketpair_fds[1]));
+  return true;
+}
+
+void HciTransport::OnFileCanReadWithoutBlocking(int fd) {
+  CHECK(fd == GetVendorFd());
+  LOG_INFO(LOG_TAG, "Event ready in HciTransport on fd: %d.", fd);
+
+  const serial_data_type_t packet_type = packet_stream_.ReceivePacketType(fd);
+  switch (packet_type) {
+    case (DATA_TYPE_COMMAND): {
+      ReceiveReadyCommand();
+      break;
+    }
+
+    case (DATA_TYPE_ACL): {
+      LOG_INFO(LOG_TAG, "ACL data packets not currently supported.");
+      break;
+    }
+
+    case (DATA_TYPE_SCO): {
+      LOG_INFO(LOG_TAG, "SCO data packets not currently supported.");
+      break;
+    }
+
+    // TODO(dennischeng): Add debug level assert here.
+    default: {
+      LOG_INFO(LOG_TAG, "Error received an invalid packet type from the HCI.");
+      break;
+    }
+  }
+}
+
+void HciTransport::ReceiveReadyCommand() const {
+  std::unique_ptr<CommandPacket> command =
+      packet_stream_.ReceiveCommand(GetVendorFd());
+  LOG_INFO(LOG_TAG, "Received command packet.");
+  command_handler_(std::move(command));
+}
+
+void HciTransport::RegisterCommandHandler(
+    std::function<void(std::unique_ptr<CommandPacket>)> callback) {
+  command_handler_ = callback;
+}
+
+void HciTransport::OnFileCanWriteWithoutBlocking(int fd) {
+  CHECK(fd == GetVendorFd());
+  if (!outbound_events_.empty()) {
+    base::TimeTicks current_time = base::TimeTicks::Now();
+    auto it = outbound_events_.begin();
+    // Check outbound events for events that can be sent, i.e. events with a
+    // timestamp before the current time. Stop sending events when
+    // |packet_stream_| fails writing.
+    for (auto it = outbound_events_.begin(); it != outbound_events_.end();) {
+      if ((*it)->GetTimeStamp() > current_time) {
+        ++it;
+        continue;
+      }
+      if (!packet_stream_.SendEvent((*it)->GetEvent(), fd))
+        return;
+      it = outbound_events_.erase(it);
+    }
+  }
+}
+
+void HciTransport::AddEventToOutboundEvents(
+    std::unique_ptr<TimeStampedEvent> event) {
+  outbound_events_.push_back(std::move(event));
+}
+
+void HciTransport::PostEventResponse(std::unique_ptr<EventPacket> event) {
+  AddEventToOutboundEvents(
+      std::make_unique<TimeStampedEvent>(std::move(event)));
+}
+
+void HciTransport::PostDelayedEventResponse(std::unique_ptr<EventPacket> event,
+                                            base::TimeDelta delay) {
+  // TODO(dennischeng): When it becomes available for MessageLoopForIO, use the
+  // thread's task runner to post |PostEventResponse| as a delayed task, being
+  // sure to CHECK the appropriate task runner attributes using
+  // base::ThreadTaskRunnerHandle.
+
+  // The system does not support high resolution timing and the clock could be
+  // as coarse as ~15.6 ms so the event is sent without a delay to avoid
+  // inconsistent event responses.
+  if (!base::TimeTicks::IsHighResolution()) {
+    LOG_INFO(LOG_TAG,
+              "System does not support high resolution timing. Sending event "
+              "without delay.");
+    PostEventResponse(std::move(event));
+  }
+
+  LOG_INFO(LOG_TAG, "Posting event response with delay of %lld ms.",
+           delay.InMilliseconds());
+
+  AddEventToOutboundEvents(
+      std::make_unique<TimeStampedEvent>(std::move(event), delay));
+}
+
+HciTransport::TimeStampedEvent::TimeStampedEvent(
+    std::unique_ptr<EventPacket> event, base::TimeDelta delay)
+    : event_(std::move(event)), time_stamp_(base::TimeTicks::Now() + delay) {}
+
+HciTransport::TimeStampedEvent::TimeStampedEvent(
+    std::unique_ptr<EventPacket> event)
+    : event_(std::move(event)), time_stamp_(base::TimeTicks::UnixEpoch()) {}
+
+const base::TimeTicks& HciTransport::TimeStampedEvent::GetTimeStamp() const {
+  return time_stamp_;
+}
+
+const EventPacket& HciTransport::TimeStampedEvent::GetEvent() {
+  return *(event_.get());
+}
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/src/packet.cc b/vendor_libs/test_vendor_lib/src/packet.cc
new file mode 100644 (file)
index 0000000..4c27301
--- /dev/null
@@ -0,0 +1,69 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 "packet"
+
+#include "vendor_libs/test_vendor_lib/include/packet.h"
+
+#include "base/logging.h"
+
+#include <algorithm>
+
+extern "C" {
+#include "osi/include/log.h"
+}  // extern "C"
+
+namespace test_vendor_lib {
+
+Packet::Packet(serial_data_type_t type) : type_(type) {}
+
+bool Packet::Encode(const std::vector<uint8_t>& header,
+                    const std::vector<uint8_t>& payload) {
+  if (header.back() != payload.size())
+    return false;
+  header_ = header;
+  payload_ = payload;
+  return true;
+}
+
+const std::vector<uint8_t>& Packet::GetHeader() const {
+  // Every packet must have a header.
+  CHECK(GetHeaderSize() > 0);
+  return header_;
+}
+
+uint8_t Packet::GetHeaderSize() const {
+  return header_.size();
+}
+
+size_t Packet::GetPacketSize() const {
+  // Add one for the type octet.
+  return 1 + header_.size() + payload_.size();
+}
+
+const std::vector<uint8_t>& Packet::GetPayload() const {
+  return payload_;
+}
+
+uint8_t Packet::GetPayloadSize() const {
+  return payload_.size();
+}
+
+serial_data_type_t Packet::GetType() const {
+  return type_;
+}
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/src/packet_stream.cc b/vendor_libs/test_vendor_lib/src/packet_stream.cc
new file mode 100644 (file)
index 0000000..0eb768f
--- /dev/null
@@ -0,0 +1,134 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 "packet_stream"
+
+#include "vendor_libs/test_vendor_lib/include/packet_stream.h"
+
+#include "base/logging.h"
+
+extern "C" {
+#include <errno.h>
+#include <unistd.h>
+
+#include "osi/include/log.h"
+}  // extern "C"
+
+namespace test_vendor_lib {
+
+std::unique_ptr<CommandPacket> PacketStream::ReceiveCommand(int fd) const {
+  std::vector<uint8_t> header;
+  std::vector<uint8_t> payload;
+
+  if (!ReceiveAll(header, CommandPacket::kCommandHeaderSize, fd)) {
+    LOG_ERROR(LOG_TAG, "Error: receiving command header.");
+    return std::unique_ptr<CommandPacket>(nullptr);
+  }
+
+  if (!ReceiveAll(payload, header.back(), fd)) {
+    LOG_ERROR(LOG_TAG, "Error: receiving command payload.");
+    return std::unique_ptr<CommandPacket>(nullptr);
+  }
+
+  std::unique_ptr<CommandPacket> command(new CommandPacket());
+  if (!command->Encode(header, payload)) {
+    LOG_ERROR(LOG_TAG, "Error: encoding command packet.");
+    command.reset(nullptr);
+  }
+  return command;
+}
+
+serial_data_type_t PacketStream::ReceivePacketType(int fd) const {
+  LOG_INFO(LOG_TAG, "Receiving packet type.");
+
+  std::vector<uint8_t> raw_type_octet;
+
+  if (!ReceiveAll(raw_type_octet, 1, fd)) {
+    // TODO(dennischeng): Proper error handling.
+    LOG_ERROR(LOG_TAG, "Error: Could not receive packet type.");
+  }
+
+  // Check that the type octet received is in the valid range, i.e. the packet
+  // must be a command or data packet.
+  const serial_data_type_t type =
+      static_cast<serial_data_type_t>(raw_type_octet[0]);
+  if (!ValidateTypeOctet(type)) {
+    // TODO(dennischeng): Proper error handling.
+    LOG_ERROR(LOG_TAG, "Error: Received invalid packet type.");
+  }
+  return type;
+}
+
+bool PacketStream::SendEvent(const EventPacket& event, int fd) const {
+  LOG_INFO(LOG_TAG, "Sending event with event code: 0x%04X",
+           event.GetEventCode());
+  LOG_INFO(LOG_TAG, "Sending event with size: %zu octets",
+           event.GetPacketSize());
+
+  if (!SendAll({static_cast<uint8_t>(event.GetType())}, 1, fd)) {
+    LOG_ERROR(LOG_TAG, "Error: Could not send event type.");
+    return false;
+  }
+
+  if (!SendAll(event.GetHeader(), event.GetHeaderSize(), fd)) {
+    LOG_ERROR(LOG_TAG, "Error: Could not send event header.");
+    return false;
+  }
+
+  if (!SendAll(event.GetPayload(), event.GetPayloadSize(), fd)) {
+    LOG_ERROR(LOG_TAG, "Error: Could not send event payload.");
+    return false;
+  }
+  return true;
+}
+
+bool PacketStream::ValidateTypeOctet(serial_data_type_t type) const {
+  LOG_INFO(LOG_TAG, "Signal octet is 0x%02X.", type);
+  // The only types of packets that should be received from the HCI are command
+  // packets and data packets.
+  return (type >= DATA_TYPE_COMMAND) && (type <= DATA_TYPE_SCO);
+}
+
+bool PacketStream::ReceiveAll(std::vector<uint8_t>& destination,
+                              size_t num_octets_to_receive, int fd) const {
+  destination.resize(num_octets_to_receive);
+  size_t octets_remaining = num_octets_to_receive;
+  while (octets_remaining > 0) {
+    const int num_octets_received =
+        read(fd, &destination[num_octets_to_receive - octets_remaining],
+             octets_remaining);
+    if (num_octets_received < 0)
+      return false;
+    octets_remaining -= num_octets_received;
+  }
+  return true;
+}
+
+bool PacketStream::SendAll(const std::vector<uint8_t>& source,
+                           size_t num_octets_to_send, int fd) const {
+  CHECK(source.size() >= num_octets_to_send);
+  size_t octets_remaining = num_octets_to_send;
+  while (octets_remaining > 0) {
+    const int num_octets_sent = write(
+        fd, &source[num_octets_to_send - octets_remaining], octets_remaining);
+    if (num_octets_sent < 0)
+      return false;
+    octets_remaining -= num_octets_sent;
+  }
+  return true;
+}
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/src/test_channel_transport.cc b/vendor_libs/test_vendor_lib/src/test_channel_transport.cc
new file mode 100644 (file)
index 0000000..0b49711
--- /dev/null
@@ -0,0 +1,138 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 "test_channel_transport"
+
+#include "vendor_libs/test_vendor_lib/include/test_channel_transport.h"
+
+#include "base/logging.h"
+
+extern "C" {
+#include "osi/include/log.h"
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+}  // extern "C"
+
+namespace test_vendor_lib {
+
+TestChannelTransport::TestChannelTransport(bool enabled, int port)
+    : enabled_(enabled), port_(port) {}
+
+bool TestChannelTransport::SetUp() {
+  CHECK(enabled_);
+
+  struct sockaddr_in listen_address, test_channel_address;
+  int sockaddr_in_size = sizeof(struct sockaddr_in);
+  int listen_fd = -1;
+  int accept_fd = -1;
+  memset(&listen_address, 0, sockaddr_in_size);
+  memset(&test_channel_address, 0, sockaddr_in_size);
+
+  if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+    LOG_INFO(LOG_TAG, "Error creating socket for test channel.");
+    return false;
+  }
+
+  LOG_INFO(LOG_TAG, "port: %d", port_);
+  listen_address.sin_family = AF_INET;
+  listen_address.sin_port = htons(port_);
+  listen_address.sin_addr.s_addr = htonl(INADDR_ANY);
+
+  if (bind(listen_fd, reinterpret_cast<sockaddr*>(&listen_address),
+           sockaddr_in_size) < 0) {
+    LOG_INFO(LOG_TAG, "Error binding test channel listener socket to address.");
+    close(listen_fd);
+    return false;
+  }
+
+  if (listen(listen_fd, 1) < 0) {
+    LOG_INFO(LOG_TAG, "Error listening for test channel.");
+    close(listen_fd);
+    return false;
+  }
+
+  if ((accept_fd =
+           accept(listen_fd, reinterpret_cast<sockaddr*>(&test_channel_address),
+                  &sockaddr_in_size)) < 0) {
+    LOG_INFO(LOG_TAG, "Error accepting test channel connection.");
+    close(listen_fd);
+    return false;
+  }
+
+  fd_.reset(new base::ScopedFD(accept_fd));
+  return GetFd() >= 0;
+}
+
+int TestChannelTransport::GetFd() {
+  return fd_->get();
+}
+
+bool TestChannelTransport::IsEnabled() {
+  return enabled_;
+}
+
+// base::MessageLoopForIO::Watcher overrides:
+void TestChannelTransport::OnFileCanReadWithoutBlocking(int fd) {
+  CHECK(fd == GetFd());
+
+  LOG_INFO(LOG_TAG, "Event ready in TestChannelTransport on fd: %d", fd);
+  uint8_t command_name_size = 0;
+  read(fd, &command_name_size, 1);
+  std::vector<uint8_t> command_name_raw;
+  command_name_raw.resize(command_name_size);
+  read(fd, &command_name_raw[0], command_name_size);
+  std::string command_name(command_name_raw.begin(), command_name_raw.end());
+  LOG_INFO(LOG_TAG, "Received command from test channel: %s",
+           command_name.data());
+
+  if (command_name == "CLOSE_TEST_CHANNEL") {
+    fd_.reset(nullptr);
+    return;
+  }
+
+  uint8_t num_args = 0;
+  read(fd, &num_args, 1);
+  LOG_INFO(LOG_TAG, "num_args: %d", num_args);
+  std::vector<std::string> args;
+  for (uint8_t i = 0; i < num_args; ++i) {
+    uint8_t arg_size = 0;
+    read(fd, &arg_size, 1);
+    std::vector<uint8_t> arg;
+    arg.resize(arg_size);
+    read(fd, &arg[0], arg_size);
+    args.push_back(std::string(arg.begin(), arg.end()));
+  }
+
+  for (size_t i = 0; i < args.size(); ++i)
+    LOG_INFO(LOG_TAG, "Command argument %d: %s", i, args[i].data());
+
+  command_handler_(command_name, args);
+}
+
+void TestChannelTransport::OnFileCanWriteWithoutBlocking(int fd) {}
+
+void TestChannelTransport::RegisterCommandHandler(
+    std::function<void(const std::string&, const std::vector<std::string>&)>
+        callback) {
+  command_handler_ = callback;
+}
+
+void TestChannelTransport::Disable() {
+  enabled_ = false;
+}
+
+}  // namespace test_vendor_lib {
diff --git a/vendor_libs/test_vendor_lib/src/vendor_manager.cc b/vendor_libs/test_vendor_lib/src/vendor_manager.cc
new file mode 100644 (file)
index 0000000..f7e640a
--- /dev/null
@@ -0,0 +1,149 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 "vendor_manager"
+
+#include "vendor_manager.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+
+extern "C" {
+#include "osi/include/log.h"
+}  // extern "C"
+
+namespace test_vendor_lib {
+
+VendorManager* g_manager = nullptr;
+
+// static
+void VendorManager::CleanUp() {
+  delete g_manager;
+  g_manager = nullptr;
+}
+
+// static
+VendorManager* VendorManager::Get() {
+  // Initialize should have been called already.
+  CHECK(g_manager);
+  return g_manager;
+}
+
+// static
+void VendorManager::Initialize() {
+  CHECK(!g_manager);
+  g_manager = new VendorManager();
+}
+
+VendorManager::VendorManager()
+    : running_(false),
+      test_channel_transport_(true, 6111),
+      thread_("TestVendorLibrary"),
+      weak_ptr_factory_(this) {}
+
+bool VendorManager::Run() {
+  CHECK(!running_);
+
+  if (!transport_.SetUp()) {
+    LOG_ERROR(LOG_TAG, "Error setting up transport object.");
+    return false;
+  }
+
+  if (test_channel_transport_.IsEnabled()) {
+    LOG_INFO(LOG_TAG, "Test channel is enabled.");
+
+    if (test_channel_transport_.SetUp()) {
+      controller_.RegisterHandlersWithTestChannelTransport(
+          test_channel_transport_);
+    } else {
+      LOG_ERROR(LOG_TAG,
+                "Error setting up test channel object, continuing without it.");
+      test_channel_transport_.Disable();
+    }
+  } else {
+    LOG_INFO(LOG_TAG, "Test channel is disabled.");
+  }
+
+  controller_.RegisterHandlersWithHciTransport(transport_);
+  // TODO(dennischeng): Register PostDelayedEventResponse instead.
+  controller_.RegisterDelayedEventChannel(
+      std::bind(&HciTransport::PostDelayedEventResponse, &transport_,
+                std::placeholders::_1, std::placeholders::_2));
+
+  running_ = true;
+  if (!thread_.StartWithOptions(
+          base::Thread::Options(base::MessageLoop::TYPE_IO, 0))) {
+    LOG_ERROR(LOG_TAG, "Error starting TestVendorLibrary thread.");
+    running_ = false;
+    return false;
+  }
+
+  if (!PostTask(base::Bind(&VendorManager::StartWatchingOnThread,
+                           weak_ptr_factory_.GetWeakPtr()))) {
+    LOG_ERROR(LOG_TAG, "Error posting StartWatchingOnThread to task runner.");
+    running_ = false;
+    return false;
+  }
+
+  return true;
+}
+
+void VendorManager::StartWatchingOnThread() {
+  CHECK(running_);
+  CHECK(base::MessageLoopForIO::IsCurrent());
+
+  if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
+          transport_.GetVendorFd(), true,
+          base::MessageLoopForIO::WATCH_READ_WRITE, &hci_watcher_,
+          &transport_)) {
+    LOG_ERROR(LOG_TAG, "Error watching vendor fd.");
+    return;
+  }
+
+  if (test_channel_transport_.IsEnabled())
+    if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
+            test_channel_transport_.GetFd(), true,
+            base::MessageLoopForIO::WATCH_READ, &test_channel_watcher_,
+            &test_channel_transport_))
+      LOG_ERROR(LOG_TAG, "Error watching test channel fd.");
+}
+
+bool VendorManager::PostTask(const base::Closure& task) {
+  return PostDelayedTask(task, base::TimeDelta::FromMilliseconds(0));
+}
+
+bool VendorManager::PostDelayedTask(const base::Closure& task,
+                                    base::TimeDelta delay) {
+  return thread_.task_runner()->PostDelayedTask(FROM_HERE, task, delay);
+}
+
+void VendorManager::SetVendorCallbacks(const bt_vendor_callbacks_t& callbacks) {
+  vendor_callbacks_ = callbacks;
+}
+
+const bt_vendor_callbacks_t& VendorManager::GetVendorCallbacks() const {
+  return vendor_callbacks_;
+}
+
+void VendorManager::CloseHciFd() {
+  transport_.CloseHciFd();
+}
+
+int VendorManager::GetHciFd() const {
+  return transport_.GetHciFd();
+}
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/test/hci_transport_unittest.cc b/vendor_libs/test_vendor_lib/test/hci_transport_unittest.cc
new file mode 100644 (file)
index 0000000..5887c37
--- /dev/null
@@ -0,0 +1,140 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 "vendor_libs/test_vendor_lib/include/command_packet.h"
+#include "vendor_libs/test_vendor_lib/include/hci_transport.h"
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "base/threading/thread.h"
+
+#include <gtest/gtest.h>
+#include <functional>
+#include <mutex>
+
+extern "C" {
+#include "stack/include/hcidefs.h"
+}  // extern "C"
+
+namespace {
+const std::vector<uint8_t> stub_command({DATA_TYPE_COMMAND,
+                                         static_cast<uint8_t>(HCI_RESET),
+                                         static_cast<uint8_t>(HCI_RESET >> 8),
+                                         0});
+
+const int kMultiIterations = 10000;
+
+void WriteStubCommand(int fd) {
+  write(fd, &stub_command[0], stub_command.size());
+}
+
+}  // namespace
+
+namespace test_vendor_lib {
+
+class HciTransportTest : public ::testing::Test {
+ public:
+  HciTransportTest()
+      : command_callback_count_(0),
+        thread_("HciTransportTest"),
+        weak_ptr_factory_(this) {
+    SetUpTransport();
+    StartThread();
+    PostStartWatchingOnThread();
+  }
+
+  ~HciTransportTest() {
+    transport_.CloseHciFd();
+  }
+
+  void CommandCallback(std::unique_ptr<CommandPacket> command) {
+    ++command_callback_count_;
+    // Ensure that the received packet matches the stub command.
+    EXPECT_EQ(DATA_TYPE_COMMAND, command->GetType());
+    EXPECT_EQ(HCI_RESET, command->GetOpcode());
+    EXPECT_EQ(0, command->GetPayloadSize());
+    transport_.CloseVendorFd();
+  }
+
+  void MultiCommandCallback(std::unique_ptr<CommandPacket> command) {
+    ++command_callback_count_;
+    // Ensure that the received packet matches the stub command.
+    EXPECT_EQ(DATA_TYPE_COMMAND, command->GetType());
+    EXPECT_EQ(HCI_RESET, command->GetOpcode());
+    EXPECT_EQ(0, command->GetPayloadSize());
+    if (command_callback_count_ == kMultiIterations)
+      transport_.CloseVendorFd();
+  }
+
+ protected:
+  // Tracks the number of commands received.
+  int command_callback_count_;
+  base::Thread thread_;
+  HciTransport transport_;
+  base::MessageLoopForIO::FileDescriptorWatcher watcher_;
+  base::WeakPtrFactory<HciTransportTest> weak_ptr_factory_;
+
+ private:
+  // Workaround because ASSERT cannot be used directly in a constructor
+  void SetUpTransport() {
+    ASSERT_TRUE(transport_.SetUp());
+  }
+
+  void StartThread() {
+    ASSERT_TRUE(thread_.StartWithOptions(
+        base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
+  }
+
+  void PostStartWatchingOnThread() {
+    thread_.task_runner()->PostTask(
+        FROM_HERE, base::Bind(&HciTransportTest::StartWatchingOnThread,
+                              weak_ptr_factory_.GetWeakPtr()));
+  }
+
+  void StartWatchingOnThread() {
+    base::MessageLoopForIO* loop =
+        static_cast<base::MessageLoopForIO*>(thread_.message_loop());
+    ASSERT_TRUE(loop);
+    ASSERT_TRUE(loop->WatchFileDescriptor(
+        transport_.GetVendorFd(), true,
+        base::MessageLoopForIO::WATCH_READ_WRITE, &watcher_, &transport_));
+  }
+};
+
+TEST_F(HciTransportTest, SingleCommandCallback) {
+  transport_.RegisterCommandHandler(std::bind(
+      &HciTransportTest::CommandCallback, this, std::placeholders::_1));
+  EXPECT_EQ(0, command_callback_count_);
+  WriteStubCommand(transport_.GetHciFd());
+  thread_.Stop();  // Wait for the command handler to finish.
+  EXPECT_EQ(1, command_callback_count_);
+}
+
+TEST_F(HciTransportTest, MultiCommandCallback) {
+  transport_.RegisterCommandHandler(std::bind(
+      &HciTransportTest::MultiCommandCallback, this, std::placeholders::_1));
+  EXPECT_EQ(0, command_callback_count_);
+  WriteStubCommand(transport_.GetHciFd());
+  for (int i = 1; i < kMultiIterations; ++i)
+    WriteStubCommand(transport_.GetHciFd());
+  thread_.Stop();  // Wait for the command handler to finish.
+  EXPECT_EQ(kMultiIterations, command_callback_count_);
+}
+
+// TODO(dennischeng): Add tests for PostEventResponse and
+// PostDelayedEventResponse.
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/test/packet_stream_unittest.cc b/vendor_libs/test_vendor_lib/test/packet_stream_unittest.cc
new file mode 100644 (file)
index 0000000..3d70ad8
--- /dev/null
@@ -0,0 +1,151 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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 "vendor_libs/test_vendor_lib/include/packet_stream.h"
+#include "vendor_libs/test_vendor_lib/include/command_packet.h"
+#include "vendor_libs/test_vendor_lib/include/event_packet.h"
+#include "vendor_libs/test_vendor_lib/include/packet.h"
+
+#include <gtest/gtest.h>
+#include <cstdint>
+#include <memory>
+#include <vector>
+
+extern "C" {
+#include "hci/include/hci_hal.h"
+#include "stack/include/hcidefs.h"
+
+#include <sys/socket.h>
+}  // extern "C"
+
+namespace {
+const char small_payload[] = "foo bar baz";
+const char large_payload[] =
+  "Aristotle's principles will then be no more principles to him, than those "
+  "of Epicurus and the Stoics: let this diversity of opinions be propounded "
+  "to, and laid before him; he will himself choose, if he be able; if not, "
+  "he will remain in doubt.";
+}  // namespace
+
+namespace test_vendor_lib {
+
+class PacketStreamTest : public ::testing::Test {
+ public:
+  PacketStreamTest() {
+    socketpair(AF_LOCAL, SOCK_STREAM, 0, socketpair_fds_);
+    CheckSocketpairInit();
+  }
+
+  ~PacketStreamTest() {
+    close(socketpair_fds_[0]);
+    close(socketpair_fds_[1]);
+  }
+
+  void CheckedReceiveCommand(const char* payload, uint16_t opcode) {
+    uint8_t payload_size = strlen(payload);
+    std::vector<uint8_t> packet;
+
+    packet.push_back(DATA_TYPE_COMMAND);
+    packet.push_back(opcode);
+    packet.push_back(opcode >> 8);
+    packet.push_back(payload_size);
+
+    // Set the packet's payload.
+    for (int i = 0; i < payload_size; ++i)
+      packet.push_back(payload[i]);
+
+    // Send the packet to |packet_stream_|.
+    write(socketpair_fds_[1], &packet[1], packet.size());
+
+    // Read the command packet.
+    std::unique_ptr<CommandPacket> command =
+        packet_stream_.ReceiveCommand(socketpair_fds_[0]);
+
+    const std::vector<uint8_t> received_payload = command->GetPayload();
+
+    // Validate the packet by checking that it's the appropriate size and then
+    // checking each byte.
+    EXPECT_EQ(packet.size(), command->GetPacketSize());
+    EXPECT_EQ(DATA_TYPE_COMMAND, command->GetType());
+    EXPECT_EQ(opcode, command->GetOpcode());
+    EXPECT_EQ(payload_size, command->GetPayloadSize());
+    for (int i = 0; i < payload_size; ++i)
+      EXPECT_EQ(packet[4 + i], received_payload[i]);
+  }
+
+  void CheckedSendEvent(std::unique_ptr<EventPacket> event) {
+    EXPECT_TRUE(packet_stream_.SendEvent(*(event.get()), socketpair_fds_[0]));
+
+    // Read the packet sent by |packet_stream_|.
+    uint8_t event_header[3];
+    read(socketpair_fds_[1], event_header, 3);
+
+    uint8_t return_parameters_size = event_header[2];
+    uint8_t return_parameters[return_parameters_size];
+    read(socketpair_fds_[1], return_parameters, sizeof(return_parameters));
+
+    const std::vector<uint8_t> expected_payload = event->GetPayload();
+
+    // Validate the packet by checking that it's the
+    // appropriate size and then checking each byte.
+    EXPECT_EQ(event->GetPacketSize(),
+              sizeof(event_header) + sizeof(return_parameters));
+    EXPECT_EQ(DATA_TYPE_EVENT, event_header[0]);
+    EXPECT_EQ(event->GetEventCode(), event_header[1]);
+    EXPECT_EQ(event->GetPayloadSize(), return_parameters_size);
+    for (int i = 0; i < return_parameters_size; ++i)
+      EXPECT_EQ(expected_payload[i], return_parameters[i]);
+  }
+
+ protected:
+  PacketStream packet_stream_;
+
+  int socketpair_fds_[2];
+
+ private:
+  // Workaround because ASSERT cannot be used directly in a constructor
+  void CheckSocketpairInit() {
+    ASSERT_TRUE(socketpair_fds_[0] > 0);
+    ASSERT_TRUE(socketpair_fds_[1] > 0);
+  }
+
+};
+
+TEST_F(PacketStreamTest, ReceivePacketType) {
+  serial_data_type_t command_type = DATA_TYPE_COMMAND;
+  write(socketpair_fds_[1], &command_type, 1);
+  EXPECT_EQ(command_type, packet_stream_.ReceivePacketType(socketpair_fds_[0]));
+}
+
+TEST_F(PacketStreamTest, ReceiveEmptyCommand) {
+  CheckedReceiveCommand("", HCI_RESET);
+}
+
+TEST_F(PacketStreamTest, ReceiveSmallCommand) {
+  CheckedReceiveCommand(small_payload, HCI_RESET);
+}
+
+TEST_F(PacketStreamTest, ReceiveLargeCommand) {
+  CheckedReceiveCommand(large_payload, HCI_RESET);
+}
+
+TEST_F(PacketStreamTest, SendEvent) {
+  const std::vector<uint8_t> return_parameters = {0};
+  CheckedSendEvent(
+      EventPacket::CreateCommandCompleteEvent(1, HCI_RESET, return_parameters));
+}
+
+}  // namespace test_vendor_lib