| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- // SPDX-License-Identifier: LGPL-2.1-or-later
- /*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2013-2014 Intel Corporation. All rights reserved.
- *
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #define _GNU_SOURCE
- #include <stdio.h>
- #include <errno.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <string.h>
- #include <libgen.h>
- #include <poll.h>
- #include <sys/wait.h>
- #include <sys/param.h>
- #include <sys/socket.h>
- #include <sys/un.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #ifndef WAIT_ANY
- #define WAIT_ANY (-1)
- #endif
- #include "src/shared/mainloop.h"
- static char exec_dir[PATH_MAX];
- static pid_t daemon_pid = -1;
- static pid_t snoop_pid = -1;
- static void run_valgrind(char *prg_name)
- {
- char *prg_argv[6];
- char *prg_envp[3];
- prg_argv[0] = "/usr/bin/valgrind";
- prg_argv[1] = "--leak-check=full";
- prg_argv[2] = "--track-origins=yes";
- prg_argv[3] = prg_name;
- prg_argv[4] = "-d";
- prg_argv[5] = NULL;
- prg_envp[0] = "G_SLICE=always-malloc";
- prg_envp[1] = "G_DEBUG=gc-friendly";
- prg_envp[2] = NULL;
- execve(prg_argv[0], prg_argv, prg_envp);
- }
- static void run_bluetoothd(char *prg_name)
- {
- char *prg_argv[3];
- char *prg_envp[1];
- prg_argv[0] = prg_name;
- prg_argv[1] = "-d";
- prg_argv[2] = NULL;
- prg_envp[0] = NULL;
- execve(prg_argv[0], prg_argv, prg_envp);
- }
- static void ctl_start(void)
- {
- char prg_name[PATH_MAX + 11];
- pid_t pid;
- snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir, "bluetoothd");
- printf("Starting %s\n", prg_name);
- pid = fork();
- if (pid < 0) {
- perror("Failed to fork new process");
- return;
- }
- if (pid == 0) {
- run_valgrind(prg_name);
- /* Fallback to no valgrind if running with valgind failed */
- run_bluetoothd(prg_name);
- exit(0);
- }
- printf("New process %d created\n", pid);
- daemon_pid = pid;
- }
- static void snoop_start(void)
- {
- char prg_name[PATH_MAX + 17];
- char *prg_argv[3];
- char *prg_envp[1];
- pid_t pid;
- snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir,
- "bluetoothd-snoop");
- prg_argv[0] = prg_name;
- prg_argv[1] = "/tmp/btsnoop_hci.log";
- prg_argv[2] = NULL;
- prg_envp[0] = NULL;
- printf("Starting %s\n", prg_name);
- pid = fork();
- if (pid < 0) {
- perror("Failed to fork new process");
- return;
- }
- if (pid == 0) {
- execve(prg_argv[0], prg_argv, prg_envp);
- exit(0);
- }
- printf("New process %d created\n", pid);
- snoop_pid = pid;
- }
- static void snoop_stop(void)
- {
- printf("Stoping %s/%s\n", exec_dir, "bluetoothd-snoop");
- kill(snoop_pid, SIGTERM);
- }
- static void system_socket_callback(int fd, uint32_t events, void *user_data)
- {
- char buf[4096];
- ssize_t len;
- if (events & (EPOLLERR | EPOLLHUP)) {
- mainloop_remove_fd(fd);
- return;
- }
- len = read(fd, buf, sizeof(buf));
- if (len < 0)
- return;
- printf("Received %s\n", buf);
- if (!strcmp(buf, "bluetooth.start=daemon")) {
- if (daemon_pid > 0)
- return;
- ctl_start();
- } else if (!strcmp(buf, "bluetooth.start=snoop")) {
- if (snoop_pid > 0)
- return;
- snoop_start();
- } else if (!strcmp(buf, "bluetooth.stop=snoop")) {
- if (snoop_pid > 0)
- snoop_stop();
- }
- }
- static void signal_callback(int signum, void *user_data)
- {
- switch (signum) {
- case SIGINT:
- case SIGTERM:
- mainloop_quit();
- break;
- case SIGCHLD:
- while (1) {
- pid_t pid;
- int status;
- pid = waitpid(WAIT_ANY, &status, WNOHANG);
- if (pid < 0 || pid == 0)
- break;
- printf("Process %d terminated with status=%d\n",
- pid, status);
- if (pid == daemon_pid)
- daemon_pid = -1;
- else if (pid == snoop_pid)
- snoop_pid = -1;
- }
- break;
- }
- }
- int main(int argc, char *argv[])
- {
- const char SYSTEM_SOCKET_PATH[] = "\0android_system";
- struct sockaddr_un addr;
- int fd;
- mainloop_init();
- printf("Android system emulator ver %s\n", VERSION);
- snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0]));
- fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
- if (fd < 0) {
- perror("Failed to create system socket");
- return EXIT_FAILURE;
- }
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH));
- if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- perror("Failed to bind system socket");
- close(fd);
- return EXIT_FAILURE;
- }
- mainloop_add_fd(fd, EPOLLIN, system_socket_callback, NULL, NULL);
- /* Make sure bluetoothd creates files with proper permissions */
- umask(0177);
- return mainloop_run_with_signal(signal_callback, NULL);
- }
|