3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2013-2014 Intel Corporation. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
37 #include <sys/param.h>
38 #include <sys/socket.h>
40 #include <sys/types.h>
47 #include "src/shared/mainloop.h"
49 static char exec_dir[PATH_MAX];
51 static pid_t daemon_pid = -1;
52 static pid_t snoop_pid = -1;
54 static void run_valgrind(char *prg_name)
59 prg_argv[0] = "/usr/bin/valgrind";
60 prg_argv[1] = "--leak-check=full";
61 prg_argv[2] = "--track-origins=yes";
62 prg_argv[3] = prg_name;
66 prg_envp[0] = "G_SLICE=always-malloc";
67 prg_envp[1] = "G_DEBUG=gc-friendly";
70 execve(prg_argv[0], prg_argv, prg_envp);
73 static void run_bluetoothd(char *prg_name)
78 prg_argv[0] = prg_name;
84 execve(prg_argv[0], prg_argv, prg_envp);
87 static void ctl_start(void)
89 char prg_name[PATH_MAX];
92 snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir, "bluetoothd");
94 printf("Starting %s\n", prg_name);
98 perror("Failed to fork new process");
103 run_valgrind(prg_name);
105 /* Fallback to no valgrind if running with valgind failed */
106 run_bluetoothd(prg_name);
110 printf("New process %d created\n", pid);
115 static void snoop_start(void)
117 char prg_name[PATH_MAX];
122 snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir,
125 prg_argv[0] = prg_name;
126 prg_argv[1] = "/tmp/btsnoop_hci.log";
131 printf("Starting %s\n", prg_name);
135 perror("Failed to fork new process");
140 execve(prg_argv[0], prg_argv, prg_envp);
144 printf("New process %d created\n", pid);
149 static void snoop_stop(void)
151 printf("Stoping %s/%s\n", exec_dir, "bluetoothd-snoop");
153 kill(snoop_pid, SIGTERM);
156 static void system_socket_callback(int fd, uint32_t events, void *user_data)
161 if (events & (EPOLLERR | EPOLLHUP)) {
162 mainloop_remove_fd(fd);
166 len = read(fd, buf, sizeof(buf));
170 printf("Received %s\n", buf);
172 if (!strcmp(buf, "bluetooth.start=daemon")) {
177 } else if (!strcmp(buf, "bluetooth.start=snoop")) {
182 } else if (!strcmp(buf, "bluetooth.stop=snoop")) {
188 static void signal_callback(int signum, void *user_data)
200 pid = waitpid(WAIT_ANY, &status, WNOHANG);
201 if (pid < 0 || pid == 0)
204 printf("Process %d terminated with status=%d\n",
207 if (pid == daemon_pid)
209 else if (pid == snoop_pid)
216 int main(int argc, char *argv[])
218 const char SYSTEM_SOCKET_PATH[] = "\0android_system";
220 struct sockaddr_un addr;
226 sigaddset(&mask, SIGINT);
227 sigaddset(&mask, SIGTERM);
228 sigaddset(&mask, SIGCHLD);
230 mainloop_set_signal(&mask, signal_callback, NULL, NULL);
232 printf("Android system emulator ver %s\n", VERSION);
234 snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0]));
236 fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
238 perror("Failed to create system socket");
242 memset(&addr, 0, sizeof(addr));
243 addr.sun_family = AF_UNIX;
244 memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH));
246 if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
247 perror("Failed to bind system socket");
252 mainloop_add_fd(fd, EPOLLIN, system_socket_callback, NULL, NULL);
254 /* Make sure bluetoothd creates files with proper permissions */
257 return mainloop_run();