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/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;
}