blob: 46bff4aefe3fbe6018eaf39f71821c78cc9873cf [file] [log] [blame]
Ian Coolidge611fcf92015-06-03 17:20:30 -07001//
2// Copyright (C) 2015 Google, Inc.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
Arman Ugurayf2d64342015-07-08 15:47:39 -070016
Ian Coolidge611fcf92015-06-03 17:20:30 -070017#include <errno.h>
18#include <stdio.h>
19#include <stdlib.h>
Arman Ugurayf2d64342015-07-08 15:47:39 -070020#include <sys/socket.h>
21#include <sys/un.h>
22#include <unistd.h>
Ian Coolidge611fcf92015-06-03 17:20:30 -070023
Marie Janssen49120dc2015-07-07 16:47:20 -070024#define LOG_TAG "bt_host"
Ian Coolidge611fcf92015-06-03 17:20:30 -070025// For system properties
26// TODO(icoolidge): abstraction or non-cutils stub.
Arman Ugurayf2d64342015-07-08 15:47:39 -070027#if !defined(OS_GENERIC)
Ian Coolidge611fcf92015-06-03 17:20:30 -070028#include <cutils/properties.h>
Arman Ugurayf2d64342015-07-08 15:47:39 -070029#endif // !defined(OS_GENERIC)
Ian Coolidge611fcf92015-06-03 17:20:30 -070030
31#include "core_stack.h"
32#include "host.h"
Miao Chou10969122015-06-09 17:39:46 -070033#include "osi/include/log.h"
34#include "osi/include/socket_utils/sockets.h"
Ian Coolidge611fcf92015-06-03 17:20:30 -070035
36namespace {
37
Arman Ugurayf2d64342015-07-08 15:47:39 -070038// TODO(armansito): None of these should be hardcoded here. Instead, pass these
39// via commandline.
Ian Coolidge611fcf92015-06-03 17:20:30 -070040const char kDisableProperty[] = "persist.bluetooth.disable";
41const char kSocketFromInit[] = "bluetooth";
Arman Ugurayf2d64342015-07-08 15:47:39 -070042const char kUnixIpcSocketPath[] = "bluetooth-ipc-socket";
Ian Coolidge611fcf92015-06-03 17:20:30 -070043
44} // namespace
45
46int main() {
Arman Ugurayf2d64342015-07-08 15:47:39 -070047 // TODO(armansito): Move all of the IPC connection establishment into its own
48 // class. Here we should only need to initialize and start the main
49 // MessageLoop and the CoreStack instance.
50 int status;
51
52#if !defined(OS_GENERIC)
Ian Coolidge611fcf92015-06-03 17:20:30 -070053 char disable_value[PROPERTY_VALUE_MAX];
Arman Ugurayf2d64342015-07-08 15:47:39 -070054 status = property_get(kDisableProperty, disable_value, nullptr);
Ian Coolidge611fcf92015-06-03 17:20:30 -070055 if (status && !strcmp(disable_value, "1")) {
Marie Janssen49120dc2015-07-07 16:47:20 -070056 LOG_INFO(LOG_TAG, "%s", "service disabled");
Ian Coolidge611fcf92015-06-03 17:20:30 -070057 return EXIT_SUCCESS;
58 }
59
Miao Chou10969122015-06-09 17:39:46 -070060 int server_socket = osi_android_get_control_socket(kSocketFromInit);
Arman Ugurayf2d64342015-07-08 15:47:39 -070061 if (server_socket < 0) {
Marie Janssendb554582015-06-26 14:53:46 -070062 LOG_ERROR(LOG_TAG, "failed to get socket from init");
Ian Coolidge611fcf92015-06-03 17:20:30 -070063 return EXIT_FAILURE;
64 }
Arman Ugurayf2d64342015-07-08 15:47:39 -070065#else // defined(OS_GENERIC)
66 int server_socket = socket(PF_UNIX, SOCK_SEQPACKET, 0);
67 if (server_socket < 0) {
68 LOG_ERROR(LOG_TAG, "failed to open domain socket for IPC");
69 return EXIT_FAILURE;
70 }
71
72 // TODO(armansito): This is opens the door to potentially unlinking files in
73 // the current directory that we're not supposed to. For now we will have an
74 // assumption that the daemon runs in a sandbox but we should generally do
75 // this properly.
76 //
77 // Also, the daemon should clean this up properly as it shuts down.
78 unlink(kUnixIpcSocketPath);
79
80 struct sockaddr_un address;
81 memset(&address, 0, sizeof(address));
82 address.sun_family = AF_UNIX;
83 strncpy(address.sun_path, kUnixIpcSocketPath, sizeof(address.sun_path) - 1);
84
85 if (bind(server_socket, (struct sockaddr*)&address, sizeof(address)) < 0) {
86 LOG_ERROR(LOG_TAG, "Failed to bind IPC socket to address");
87 return EXIT_FAILURE;
88 }
89
90#endif // !defined(OS_GENERIC)
Ian Coolidge611fcf92015-06-03 17:20:30 -070091
92 status = listen(server_socket, SOMAXCONN);
Arman Ugurayf2d64342015-07-08 15:47:39 -070093 if (status < 0) {
Marie Janssendb554582015-06-26 14:53:46 -070094 LOG_ERROR(LOG_TAG, "listen failed: %s", strerror(errno));
Ian Coolidge611fcf92015-06-03 17:20:30 -070095 return EXIT_FAILURE;
96 }
97
98 bluetooth::CoreStack bt;
99 bt.Initialize();
100
101 // TODO(icoolidge): accept simultaneous clients
102 while (true) {
103 int client_socket = accept4(server_socket, nullptr, nullptr, SOCK_NONBLOCK);
104 if (status == -1) {
Marie Janssendb554582015-06-26 14:53:46 -0700105 LOG_ERROR(LOG_TAG, "accept failed: %s", strerror(errno));
Ian Coolidge611fcf92015-06-03 17:20:30 -0700106 return EXIT_FAILURE;
107 }
108
Marie Janssen49120dc2015-07-07 16:47:20 -0700109 LOG_INFO(LOG_TAG, "client connected: %d", client_socket);
Ian Coolidge611fcf92015-06-03 17:20:30 -0700110 bluetooth::Host bluetooth_host(client_socket, &bt);
111 bluetooth_host.EventLoop();
112 }
113
114 close(server_socket);
Arman Ugurayf2d64342015-07-08 15:47:39 -0700115
Ian Coolidge611fcf92015-06-03 17:20:30 -0700116 return EXIT_SUCCESS;
117}