gn-build: Add bluetooth-service target

This patch makes the Bluetooth system service (service/) buildable using GN:

1. Added new BUILD.gn file for service/
2. Added conditional compilation for global config paths, with TODOs for
generalizing them later.
3. Added a shim for loading the Bluetooth library that calls hw_get_module on
Android and explicitly calls dlopen on OS_GENERIC.
4. Fixed compile warnings and errors.
5. Did some minor clean up in gatt_server.cpp for better readability.

Bug: 22124644
Change-Id: I3226537a3a5211a6762651a35707638df29956b0
diff --git a/BUILD.gn b/BUILD.gn
index 10cefaa..c9c55eb 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1,4 +1,5 @@
 #
+#
 #  Copyright (C) 2015 Google, Inc.
 #
 #  Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,5 +25,7 @@
 group("bluetooth") {
   deps = [
     "//main:bluetooth.default",
+    "//service:bluetoothtbd",
+    "//vendor_libs:vendor-libs"
   ]
 }
diff --git a/btcore/Android.mk b/btcore/Android.mk
index 50006d4..4863790 100644
--- a/btcore/Android.mk
+++ b/btcore/Android.mk
@@ -32,6 +32,7 @@
     src/bdaddr.c \
     src/counter.c \
     src/device_class.c \
+    src/hal_util.c \
     src/module.c \
     src/osi_module.c \
     src/property.c \
diff --git a/btcore/BUILD.gn b/btcore/BUILD.gn
index 56719ad..624733b 100644
--- a/btcore/BUILD.gn
+++ b/btcore/BUILD.gn
@@ -19,6 +19,7 @@
     "src/bdaddr.c",
     "src/counter.c",
     "src/device_class.c",
+    "src/hal_util.c",
     "src/module.c",
     "src/property.c",
     "src/uuid.c",
diff --git a/btcore/include/hal_util.h b/btcore/include/hal_util.h
new file mode 100644
index 0000000..8456a71
--- /dev/null
+++ b/btcore/include/hal_util.h
@@ -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);
diff --git a/btcore/src/hal_util.c b/btcore/src/hal_util.c
new file mode 100644
index 0000000..c2bf880
--- /dev/null
+++ b/btcore/src/hal_util.c
@@ -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)
+}
diff --git a/btif/src/btif_config.c b/btif/src/btif_config.c
index d926f8a..0dc95b8 100644
--- a/btif/src/btif_config.c
+++ b/btif/src/btif_config.c
@@ -38,7 +38,12 @@
 #include "osi/include/log.h"
 #include "osi/include/osi.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;
 
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c
index 7ff8163..23b51dd 100644
--- a/btif/src/btif_core.c
+++ b/btif/src/btif_core.c
@@ -75,8 +75,13 @@
 ************************************************************************************/
 
 #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
diff --git a/btif/src/btif_storage.c b/btif/src/btif_storage.c
index 079ecf0..9e99901 100644
--- a/btif/src/btif_storage.c
+++ b/btif/src/btif_storage.c
@@ -57,6 +57,7 @@
 **  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"
@@ -78,7 +79,12 @@
 #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"
diff --git a/build/secondary/third_party/libchrome/BUILD.gn b/build/secondary/third_party/libchrome/BUILD.gn
index 62884b8..4d1b6bd 100644
--- a/build/secondary/third_party/libchrome/BUILD.gn
+++ b/build/secondary/third_party/libchrome/BUILD.gn
@@ -224,5 +224,5 @@
     "-Wno-sign-promo",
   ]
 
-  libs = [ "-levent", "-levent_core" ]
+  libs = [ "-levent", "-levent_core", "-lpthread" ]
 }
diff --git a/main/BUILD.gn b/main/BUILD.gn
index a80e31d..37cafbe 100644
--- a/main/BUILD.gn
+++ b/main/BUILD.gn
@@ -74,5 +74,5 @@
     "//utils",
   ]
 
-  libs = [ "-lpthread", "-lrt", "-ldl" ]
+  libs = [ "-ldl", "-lpthread", "-lresolv", "-lrt", "-lz" ]
 }
diff --git a/main/bte_main.c b/main/bte_main.c
index f165f52..ba8b172 100644
--- a/main/bte_main.c
+++ b/main/bte_main.c
@@ -62,8 +62,13 @@
 
 /* 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
diff --git a/main/stack_config.c b/main/stack_config.c
index 53dda72..cbc1c71 100644
--- a/main/stack_config.c
+++ b/main/stack_config.c
@@ -35,7 +35,12 @@
 // 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(LOG_TAG, "%s attempt to load stack conf from %s", __func__, path);
diff --git a/osi/BUILD.gn b/osi/BUILD.gn
index 3284aaf..5139dc0 100644
--- a/osi/BUILD.gn
+++ b/osi/BUILD.gn
@@ -32,6 +32,7 @@
     "src/list.c",
     "src/non_repeating_timer.c",
     "src/reactor.c",
+    "src/ringbuffer.c",
     "src/semaphore.c",
     "src/socket.c",
 
@@ -65,6 +66,7 @@
     "test/hash_map_test.cpp",
     "test/list_test.cpp",
     "test/reactor_test.cpp",
+    "test/ringbuffer_test.cpp",
     "test/thread_test.cpp",
   ]
 
diff --git a/service/Android.mk b/service/Android.mk
index a946d51..64856d1 100644
--- a/service/Android.mk
+++ b/service/Android.mk
@@ -39,8 +39,9 @@
 
 LOCAL_CFLAGS += -std=c++11
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := bthost
+LOCAL_MODULE := bluetoothtbd
 LOCAL_REQUIRED_MODULES = bluetooth.default
+LOCAL_STATIC_LIBRARIES += libbtcore
 LOCAL_SHARED_LIBRARIES += \
 	libchrome \
 	libcutils \
diff --git a/service/BUILD.gn b/service/BUILD.gn
new file mode 100644
index 0000000..4beeaed
--- /dev/null
+++ b/service/BUILD.gn
@@ -0,0 +1,40 @@
+#
+#  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.
+#
+
+executable("bluetoothtbd") {
+  sources = [
+    "a2dp_source.cpp",
+    "core_stack.cpp",
+    "gatt_server.cpp",
+    "host.cpp",
+    "logging_helpers.cpp",
+    "main.cpp",
+    "uuid.cpp"
+  ]
+
+  include_dirs = [
+    "//",
+    "//third_party/libchrome"
+  ]
+
+  deps = [
+    "//btcore",
+    "//third_party/libchrome:base",
+    "//third_party/modp_b64",
+  ]
+
+  libs = [ "-ldl", "-lpthread", "-lrt" ]
+}
diff --git a/service/a2dp_source.cpp b/service/a2dp_source.cpp
index ea01188..1b21cc1 100644
--- a/service/a2dp_source.cpp
+++ b/service/a2dp_source.cpp
@@ -26,12 +26,12 @@
 
 void ConnectionStateCallback(btav_connection_state_t state,
                              UNUSED_ATTR bt_bdaddr_t *bd_addr) {
-  LOG_INFO("%s: %s", __func__, BtAvConnectionStateText(state));
+  LOG_INFO(LOG_TAG, "%s: %s", __func__, BtAvConnectionStateText(state));
 }
 
 void AudioStateCallback(btav_audio_state_t state,
                         UNUSED_ATTR bt_bdaddr_t *bd_addr) {
-  LOG_INFO("%s: %s", __func__, BtAvAudioStateText(state));
+  LOG_INFO(LOG_TAG, "%s: %s", __func__, BtAvAudioStateText(state));
 }
 
 void AudioConfigCallback(UNUSED_ATTR bt_bdaddr_t *bd_addr,
diff --git a/service/core_stack.cpp b/service/core_stack.cpp
index 5e63c36..f5f94f3 100644
--- a/service/core_stack.cpp
+++ b/service/core_stack.cpp
@@ -18,18 +18,25 @@
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <time.h>
 
 #include <condition_variable>
 #include <mutex>
 #include <string>
 
-#define LOG_TAG "bt_bluetooth_base"
-#include "osi/include/log.h"
+#include <hardware/bluetooth.h>
+#include <hardware/hardware.h>
 
-#include "hardware/bluetooth.h"
-#include "hardware/hardware.h"
+// TODO(armansito): Remove this line and use base/logging.h instead.
+#define LOG_TAG "bluetooth_daemon"
+
 #include "logging_helpers.h"
+
+extern "C" {
+#include "btcore/include/hal_util.h"
+#include "osi/include/log.h"
 #include "osi/include/osi.h"
+}  // extern "C"
 
 namespace {
 
@@ -185,7 +192,7 @@
 
   // Load the bluetooth module.
   const hw_module_t *module;
-  int status = hw_get_module(BT_HARDWARE_MODULE_ID, &module);
+  int status = hal_util_load_bt_library(&module);
   if (status) {
     LOG_ERROR(LOG_TAG, "Error getting bluetooth module");
     return false;
diff --git a/service/gatt_server.cpp b/service/gatt_server.cpp
index 03aa545..f2f56e2 100644
--- a/service/gatt_server.cpp
+++ b/service/gatt_server.cpp
@@ -47,7 +47,27 @@
 const int kNumBlueDroidHandles = 60;
 
 // TODO(icoolidge): Support multiple instances
-static bluetooth::gatt::ServerInternals *internal = nullptr;
+// 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 };
 
@@ -71,6 +91,10 @@
   ServerInternals();
   ~ServerInternals();
   int Initialize(CoreStack *bt);
+  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;
@@ -106,14 +130,14 @@
   LOG_INFO(LOG_TAG, "%s: status:%d server_if:%d app_uuid:%p", __func__, status,
            server_if, app_uuid);
 
-  internal->server_if = server_if;
+  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;
 
-  bt_status_t btstat = internal->gatt->server->add_service(
+  g_internal->gatt->server->add_service(
       server_if, &service_id, kNumBlueDroidHandles);
 }
 
@@ -122,20 +146,20 @@
   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(internal->lock);
-  internal->server_if = server_if;
-  internal->service_handle = srvc_handle;
-  internal->service_id = *srvc_id;
+  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.
-  internal->api_synchronize.notify_one();
+  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(internal->lock);
+  std::lock_guard<std::mutex> lock(g_internal->lock);
 
-  bluetooth::gatt::Characteristic &ch = internal->characteristics[attr_handle];
+  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 &&
@@ -169,7 +193,7 @@
   response.attr_value.handle = attr_handle;
   response.attr_value.offset = attribute_offset_octets;
   response.attr_value.auth_req = 0;
-  internal->gatt->server->send_response(conn_id, trans_id, 0, &response);
+  g_internal->gatt->server->send_response(conn_id, trans_id, 0, &response);
 }
 
 void RequestWriteCallback(int conn_id, int trans_id, bt_bdaddr_t *bda,
@@ -183,32 +207,34 @@
       __func__, conn_id, addr.c_str(), trans_id, attr_handle, attribute_offset,
       length, need_rsp, is_prep);
 
-  std::lock_guard<std::mutex> lock(internal->lock);
+  std::lock_guard<std::mutex> lock(g_internal->lock);
 
-  bluetooth::gatt::Characteristic &ch = internal->characteristics[attr_handle];
+  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 = internal->controlled_blobs.find(attr_handle);
+  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 != internal->controlled_blobs.end() && ch.blob.size() == 1u) {
-    internal->characteristics[target_blob->second].blob_section = ch.blob[0];
+  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(internal->pipefd[kPipeWriteEnd], attr_uuid.data(),
+    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.
-    internal->last_write = ch.uuid;
+    g_internal->last_write = ch.uuid;
   }
 
   // Respond only if needed.
@@ -222,7 +248,7 @@
   // 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);
-  internal->gatt->server->send_response(conn_id, trans_id, 0, &response);
+  g_internal->gatt->server->send_response(conn_id, trans_id, 0, &response);
 }
 
 void RequestExecWriteCallback(int conn_id, int trans_id, bt_bdaddr_t *bda,
@@ -234,16 +260,17 @@
   // This 'response' data is unused for ExecWriteResponses.
   // It is only used to pass BlueDroid argument validation.
   btgatt_response_t response = {};
-  internal->gatt->server->send_response(conn_id, trans_id, 0, &response);
+  g_internal->gatt->server->send_response(conn_id, trans_id, 0, &response);
 
   if (!exec_write)
     return;
 
-  std::lock_guard<std::mutex> lock(internal->lock);
+  std::lock_guard<std::mutex> lock(g_internal->lock);
   // Communicate the attribute UUID as notification of a write update.
   const bluetooth::Uuid::Uuid128Bit uuid =
-      internal->last_write.GetFullBigEndian();
-  int status = write(internal->pipefd[kPipeWriteEnd], uuid.data(), uuid.size());
+      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));
 }
@@ -254,28 +281,28 @@
   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) {
-    internal->connections.insert(conn_id);
+    g_internal->connections.insert(conn_id);
   } else if (connected == 0) {
-    internal->connections.erase(conn_id);
+    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__, 
+      "%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(internal->lock);
+  std::lock_guard<std::mutex> lock(g_internal->lock);
 
-  internal->uuid_to_attribute[id] = char_handle;
-  internal->characteristics[char_handle].uuid = id;
-  internal->characteristics[char_handle].blob_section = 0;
+  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.
-  internal->api_synchronize.notify_one();
+  g_internal->api_synchronize.notify_one();
 }
 
 void DescriptorAddedCallback(int status, int server_if, bt_uuid_t *uuid,
@@ -293,10 +320,10 @@
   // 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 = internal->service_id.id.uuid;
+  bt_uuid_t client_id = g_internal->service_id.id.uuid;
   ++client_id.uu[15];
 
-  bt_status_t btstat = internal->gatt->client->register_client(&client_id);
+  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__);
   }
@@ -305,10 +332,10 @@
 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]);
-  internal->client_if = client_if;
+  g_internal->client_if = client_if;
 
   // Setup our advertisement. This has no callback.
-  bt_status_t btstat = internal->gatt->client->set_adv_data(
+  bt_status_t btstat = g_internal->gatt->client->set_adv_data(
       client_if, false, /* beacon, not scan response */
       false,            /* name */
       false,            /* no txpower */
@@ -324,7 +351,7 @@
 
   // TODO(icoolidge): Deprecated, use multi-adv interface.
   // This calls back to ListenCallback.
-  btstat = internal->gatt->client->listen(client_if, true);
+  btstat = g_internal->gatt->client->listen(client_if, true);
   if (btstat != BT_STATUS_SUCCESS) {
     LOG_ERROR(LOG_TAG, "Failed to start listening");
   }
@@ -333,30 +360,30 @@
 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(internal->lock);
-  internal->api_synchronize.notify_one();
+  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__, 
+  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(internal->lock);
-  internal->api_synchronize.notify_one();
+  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(internal->lock);
-  internal->scan_results[addr] = rssi;
+  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__, 
+  LOG_INFO(LOG_TAG, "%s: conn_id:%d status:%d client_if:%d %s", __func__,
       conn_id, status, client_if, addr.c_str());
 }
 
@@ -472,6 +499,15 @@
   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),
@@ -500,7 +536,7 @@
     LOG_ERROR(LOG_TAG, "Error creating internals");
     return false;
   }
-  internal = internal_.get();
+  g_internal = internal_.get();
 
   std::unique_lock<std::mutex> lock(internal_->lock);
   int status = internal_->Initialize(bt);
@@ -543,7 +579,7 @@
   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(
+  bt_status_t btstat = internal_->gatt->client->set_adv_data(
       internal_->client_if, false, /* beacon, not scan response */
       transmit_name,               /* name */
       false,                       /* no txpower */
@@ -574,7 +610,7 @@
   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(
+  bt_status_t btstat = internal_->gatt->client->set_adv_data(
       internal_->client_if, true, /* scan response */
       transmit_name,              /* name */
       false,                      /* no txpower */
@@ -591,50 +627,53 @@
   return true;
 }
 
-bool Server::AddCharacteristic(const Uuid &id, int properties, int permissions) {
-  bt_uuid_t char_id = id.GetBlueDroid();
-
-  std::unique_lock<std::mutex> lock(internal->lock);
-  bt_status_t btstat = internal->gatt->server->add_characteristic(
-      internal->server_if, internal->service_handle, &char_id, properties,
-      permissions);
+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;
+  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) {
-  bt_uuid_t char_id = id.GetBlueDroid();
-  bt_uuid_t ctrl_id = control_id.GetBlueDroid();
-
-  std::unique_lock<std::mutex> lock(internal->lock);
+  std::unique_lock<std::mutex> lock(internal_->lock);
 
   // First, add the primary attribute (characteristic value)
-  bt_status_t btstat = internal->gatt->server->add_characteristic(
-      internal->server_if, internal->service_handle, &char_id, properties,
-      permissions);
-  internal->api_synchronize.wait(lock);
+  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.
-  const int kControlPermissions = kPermissionRead | kPermissionWrite;
-  const int kControlProperties = kPropertyRead | kPropertyWrite;
-
-  btstat = internal->gatt->server->add_characteristic(
-      internal->server_if, internal->service_handle, &ctrl_id,
-      kControlProperties, kControlPermissions);
-  internal->api_synchronize.wait(lock);
+  btstat = internal_->AddCharacteristic(
+      control_id,
+      kPermissionRead | kPermissionWrite,
+      kPropertyRead | kPropertyWrite);
+  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;
+  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];
+  Characteristic &ctrl = internal_->characteristics[control_attribute];
   ctrl.next_blob.clear();
   ctrl.next_blob.push_back(0);
   ctrl.next_blob_pending = true;
@@ -647,6 +686,11 @@
   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;
 }
@@ -655,6 +699,11 @@
   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;
 }
@@ -685,18 +734,18 @@
 
 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];
+  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) {
+  for (auto connection : internal_->connections) {
     char dummy = 0;
-    internal_->gatt->server->send_indication(internal->server_if,
+    internal_->gatt->server->send_indication(internal_->server_if,
                                              attribute_id,
                                              connection,
                                              sizeof(dummy),
diff --git a/service/gatt_server.h b/service/gatt_server.h
index 2328395..c61399a 100644
--- a/service/gatt_server.h
+++ b/service/gatt_server.h
@@ -53,7 +53,10 @@
 // A mapping from string bluetooth addresses to RSSI measurements.
 typedef std::unordered_map<std::string, int> ScanResults;
 
-class ServerInternals;
+// 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,
diff --git a/service/host.cpp b/service/host.cpp
index a6bc375..af3c2c5 100644
--- a/service/host.cpp
+++ b/service/host.cpp
@@ -26,12 +26,12 @@
 
 #include <algorithm>
 
+#include <base/base64.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/string_split.h>
+
 #define LOG_TAG "bt_bluetooth_host"
 #include "osi/include/log.h"
-
-#include "base/base64.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
 #include "core_stack.h"
 #include "gatt_server.h"
 #include "uuid.h"
@@ -178,7 +178,7 @@
                               const std::string& advertise_uuids,
                               const std::string& advertise_data,
                               const std::string& transmit_name) {
-  LOG_INFO("%s: service:%s uuids:%s data:%s", __func__, service_uuid.c_str(),
+  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;
@@ -232,7 +232,7 @@
     LOG_ERROR(LOG_TAG, "Error reading datagram size: %s", strerror(errno));
     return false;
   } else if (0 == size) {
-    LOG_INFO("%s:%d: Connection closed", __func__, __LINE__);
+    LOG_INFO(LOG_TAG, "%s:%d: Connection closed", __func__, __LINE__);
     return false;
   }
 
@@ -242,7 +242,7 @@
     LOG_ERROR(LOG_TAG, "Error reading IPC: %s", strerror(errno));
     return false;
   } else if (0 == size) {
-    LOG_INFO("%s:%d: Connection closed", __func__, __LINE__);
+    LOG_INFO(LOG_TAG, "%s:%d: Connection closed", __func__, __LINE__);
     return false;
   }
 
diff --git a/service/main.cpp b/service/main.cpp
index cb536eb..46bff4a 100644
--- a/service/main.cpp
+++ b/service/main.cpp
@@ -13,14 +13,20 @@
 //  See the License for the specific language governing permissions and
 //  limitations under the License.
 //
+
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
 
 #define LOG_TAG "bt_host"
 // For system properties
 // TODO(icoolidge): abstraction or non-cutils stub.
+#if !defined(OS_GENERIC)
 #include <cutils/properties.h>
+#endif  // !defined(OS_GENERIC)
 
 #include "core_stack.h"
 #include "host.h"
@@ -29,27 +35,62 @@
 
 namespace {
 
+// TODO(armansito): None of these should be hardcoded here. Instead, pass these
+// via commandline.
 const char kDisableProperty[] = "persist.bluetooth.disable";
 const char kSocketFromInit[] = "bluetooth";
+const char kUnixIpcSocketPath[] = "bluetooth-ipc-socket";
 
 }  // namespace
 
 int main() {
+  // TODO(armansito): Move all  of the IPC connection establishment into its own
+  // class. Here we should only need to initialize and start the main
+  // MessageLoop and the CoreStack instance.
+  int status;
+
+#if !defined(OS_GENERIC)
   char disable_value[PROPERTY_VALUE_MAX];
-  int status = property_get(kDisableProperty, disable_value, nullptr);
+  status = property_get(kDisableProperty, disable_value, nullptr);
   if (status && !strcmp(disable_value, "1")) {
     LOG_INFO(LOG_TAG, "%s", "service disabled");
     return EXIT_SUCCESS;
   }
 
   int server_socket = osi_android_get_control_socket(kSocketFromInit);
-  if (server_socket == -1) {
+  if (server_socket < 0) {
     LOG_ERROR(LOG_TAG, "failed to get socket from init");
     return EXIT_FAILURE;
   }
+#else  // defined(OS_GENERIC)
+  int server_socket = socket(PF_UNIX, SOCK_SEQPACKET, 0);
+  if (server_socket < 0) {
+    LOG_ERROR(LOG_TAG, "failed to open domain socket for IPC");
+    return EXIT_FAILURE;
+  }
+
+  // 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.
+  //
+  // Also, the daemon should clean this up properly as it shuts down.
+  unlink(kUnixIpcSocketPath);
+
+  struct sockaddr_un address;
+  memset(&address, 0, sizeof(address));
+  address.sun_family = AF_UNIX;
+  strncpy(address.sun_path, kUnixIpcSocketPath, sizeof(address.sun_path) - 1);
+
+  if (bind(server_socket, (struct sockaddr*)&address, sizeof(address)) < 0) {
+    LOG_ERROR(LOG_TAG, "Failed to bind IPC socket to address");
+    return EXIT_FAILURE;
+  }
+
+#endif  // !defined(OS_GENERIC)
 
   status = listen(server_socket, SOMAXCONN);
-  if (status == -1) {
+  if (status < 0) {
     LOG_ERROR(LOG_TAG, "listen failed: %s", strerror(errno));
     return EXIT_FAILURE;
   }
@@ -71,5 +112,6 @@
   }
 
   close(server_socket);
+
   return EXIT_SUCCESS;
 }
diff --git a/service/uuid.cpp b/service/uuid.cpp
index 13e21a1..c48ba5e 100644
--- a/service/uuid.cpp
+++ b/service/uuid.cpp
@@ -24,8 +24,8 @@
 
 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};
+  id_ = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+         0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb}};
 }
 
 Uuid::Uuid() {