| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- // SPDX-License-Identifier: LGPL-2.1-or-later
- /*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2015 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 <stdbool.h>
- #include <signal.h>
- #include <string.h>
- #include <poll.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <sys/mount.h>
- #ifndef WAIT_ANY
- #define WAIT_ANY (-1)
- #endif
- #include "src/shared/mainloop.h"
- #include "peripheral/efivars.h"
- #include "peripheral/attach.h"
- #include "peripheral/gap.h"
- #include "peripheral/log.h"
- static bool is_init = false;
- static pid_t shell_pid = -1;
- static const struct {
- const char *target;
- const char *linkpath;
- } dev_table[] = {
- { "/proc/self/fd", "/dev/fd" },
- { "/proc/self/fd/0", "/dev/stdin" },
- { "/proc/self/fd/1", "/dev/stdout" },
- { "/proc/self/fd/2", "/dev/stderr" },
- { }
- };
- static const struct {
- const char *fstype;
- const char *target;
- const char *options;
- unsigned long flags;
- } mount_table[] = {
- { "sysfs", "/sys", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
- { "proc", "/proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
- { "devtmpfs", "/dev", NULL, MS_NOSUID|MS_STRICTATIME },
- { "efivarfs", "/sys/firmware/efi/efivars",
- NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
- { "pstore", "/sys/fs/pstore", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
- { }
- };
- static void prepare_filesystem(void)
- {
- int i;
- if (!is_init)
- return;
- for (i = 0; mount_table[i].fstype; i++) {
- struct stat st;
- if (lstat(mount_table[i].target, &st) < 0) {
- printf("Creating %s\n", mount_table[i].target);
- mkdir(mount_table[i].target, 0755);
- }
- printf("Mounting %s to %s\n", mount_table[i].fstype,
- mount_table[i].target);
- if (mount(mount_table[i].fstype,
- mount_table[i].target,
- mount_table[i].fstype,
- mount_table[i].flags, NULL) < 0)
- perror("Failed to mount filesystem");
- }
- for (i = 0; dev_table[i].target; i++) {
- printf("Linking %s to %s\n", dev_table[i].linkpath,
- dev_table[i].target);
- if (symlink(dev_table[i].target, dev_table[i].linkpath) < 0)
- perror("Failed to create device symlink");
- }
- }
- static void run_shell(void)
- {
- pid_t pid;
- printf("Starting shell\n");
- pid = fork();
- if (pid < 0) {
- perror("Failed to fork new process");
- return;
- }
- if (pid == 0) {
- char *prg_argv[] = { "/bin/sh", NULL };
- char *prg_envp[] = { NULL };
- execve(prg_argv[0], prg_argv, prg_envp);
- exit(0);
- }
- printf("PID %d created\n", pid);
- shell_pid = pid;
- }
- static void exit_shell(void)
- {
- shell_pid = -1;
- if (!is_init) {
- mainloop_quit();
- return;
- }
- run_shell();
- }
- 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;
- if (WIFEXITED(status)) {
- printf("PID %d exited (status=%d)\n",
- pid, WEXITSTATUS(status));
- if (pid == shell_pid)
- exit_shell();
- } else if (WIFSIGNALED(status)) {
- printf("PID %d terminated (signal=%d)\n",
- pid, WTERMSIG(status));
- if (pid == shell_pid)
- exit_shell();
- }
- }
- break;
- }
- }
- int main(int argc, char *argv[])
- {
- int exit_status;
- if (getpid() == 1 && getppid() == 0)
- is_init = true;
- mainloop_init();
- printf("Bluetooth periperhal ver %s\n", VERSION);
- prepare_filesystem();
- if (is_init) {
- uint8_t addr[6];
- if (efivars_read("BluetoothStaticAddress", NULL,
- addr, 6) < 0) {
- printf("Generating new persistent static address\n");
- addr[0] = rand();
- addr[1] = rand();
- addr[2] = rand();
- addr[3] = 0x34;
- addr[4] = 0x12;
- addr[5] = 0xc0;
- efivars_write("BluetoothStaticAddress",
- EFIVARS_NON_VOLATILE |
- EFIVARS_BOOTSERVICE_ACCESS |
- EFIVARS_RUNTIME_ACCESS,
- addr, 6);
- }
- gap_set_static_address(addr);
- run_shell();
- }
- log_open();
- gap_start();
- if (is_init)
- attach_start();
- exit_status = mainloop_run_with_signal(signal_callback, NULL);
- if (is_init)
- attach_stop();
- gap_stop();
- log_close();
- return exit_status;
- }
|