summaryrefslogtreecommitdiff
path: root/peripheral/main.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2015-04-28 09:19:12 -0700
committerMarcel Holtmann <marcel@holtmann.org>2015-04-28 09:19:12 -0700
commitaa93fed41057c92bd4767ed85d18483b40ea87b5 (patch)
tree01480b48710c22733e0c586921c7371718229d03 /peripheral/main.c
parent1c01a9f3183c19ce14d8d4db7f545499e2cac4a2 (diff)
downloadbluez-aa93fed41057c92bd4767ed85d18483b40ea87b5.tar.gz
peripheral: Add initial code for btsensor application
Diffstat (limited to 'peripheral/main.c')
-rw-r--r--peripheral/main.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/peripheral/main.c b/peripheral/main.c
new file mode 100644
index 000000000..d7e10f3d3
--- /dev/null
+++ b/peripheral/main.c
@@ -0,0 +1,247 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#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[])
+{
+ sigset_t mask;
+ int exit_status;
+
+ if (getpid() == 1 && getppid() == 0)
+ is_init = true;
+
+ mainloop_init();
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGINT);
+ sigaddset(&mask, SIGTERM);
+ sigaddset(&mask, SIGCHLD);
+
+ mainloop_set_signal(&mask, signal_callback, NULL, NULL);
+
+ 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();
+
+ if (is_init)
+ attach_stop();
+
+ gap_stop();
+ log_close();
+
+ return exit_status;
+}