Add bthost, a simple BLE GATT server.
This is accessible via Unix socket.
It only has a couple of interesting features:
* Built in support for large blob attributes (>512 octets)
* Attribute caching (avoid frame-level IO for IPC clients)
Some string utilies are taken from modp_b64 and Chromium base.
Bug: 21076037
Change-Id: I6a29959159de76f8dd68d6bbaabe2100daabb6fa
diff --git a/service/main.cpp b/service/main.cpp
new file mode 100644
index 0000000..a818f74
--- /dev/null
+++ b/service/main.cpp
@@ -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.
+//
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define LOG_TAG "BtHost"
+#include "osi/include/log.h"
+// For system properties
+// TODO(icoolidge): abstraction or non-cutils stub.
+#include <cutils/properties.h>
+// For init socket environment variable decode
+// TODO(icoolidge): abstraction or remove.
+#include <cutils/sockets.h>
+
+#include "core_stack.h"
+#include "host.h"
+
+namespace {
+
+const char kDisableProperty[] = "persist.bluetooth.disable";
+const char kSocketFromInit[] = "bluetooth";
+
+} // namespace
+
+int main() {
+ 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;
+ }
+
+ int server_socket = android_get_control_socket(kSocketFromInit);
+ if (server_socket == -1) {
+ LOG_ERROR("failed to get socket from init");
+ return EXIT_FAILURE;
+ }
+
+ status = listen(server_socket, SOMAXCONN);
+ if (status == -1) {
+ LOG_ERROR("listen failed: %s", strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ bluetooth::CoreStack bt;
+ bt.Initialize();
+
+ // TODO(icoolidge): accept simultaneous clients
+ while (true) {
+ int client_socket = accept4(server_socket, nullptr, nullptr, SOCK_NONBLOCK);
+ if (status == -1) {
+ LOG_ERROR("accept failed: %s", strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ LOG_INFO("client connected: %d", client_socket);
+ bluetooth::Host bluetooth_host(client_socket, &bt);
+ bluetooth_host.EventLoop();
+ }
+
+ close(server_socket);
+ return EXIT_SUCCESS;
+}