summaryrefslogtreecommitdiff
path: root/android/ipc-tester.c
diff options
context:
space:
mode:
authorJakub Tyszkowski <jakub.tyszkowski@tieto.com>2014-01-20 10:36:01 +0100
committerSzymon Janc <szymon.janc@gmail.com>2014-01-20 23:23:27 +0100
commite82c8804f36441e82ae7965c349785c4ca21b775 (patch)
treee15646d81dfd24d66ae9a33d08cce8a93e35562b /android/ipc-tester.c
parent8cc27935d397758c529668d614671ad7b9eeae2e (diff)
downloadbluez-e82c8804f36441e82ae7965c349785c4ca21b775.tar.gz
android/ipc-tester: Run daemon in separate process
This patch adds new process waiting to run daemon when needed.
Diffstat (limited to 'android/ipc-tester.c')
-rw-r--r--android/ipc-tester.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index 021919eb3..c8d1f0bbb 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -21,8 +21,14 @@
*
*/
+#include <stdlib.h>
#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/un.h>
+#include <libgen.h>
#include <glib.h>
#include "lib/bluetooth.h"
@@ -33,13 +39,19 @@
#include "src/shared/hciemu.h"
+#define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
+#define EMULATOR_SIGNAL "emulator_started"
+
struct test_data {
struct mgmt *mgmt;
uint16_t mgmt_index;
struct hciemu *hciemu;
enum hciemu_type hciemu_type;
+ pid_t bluetoothd_pid;
};
+static char exec_dir[PATH_MAX + 1];
+
static void read_info_callback(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
@@ -170,14 +182,123 @@ static void test_post_teardown(const void *data)
}
}
+static void bluetoothd_start(int hci_index)
+{
+ char prg_name[PATH_MAX + 1];
+ char index[8];
+ char *prg_argv[4];
+
+ snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir, "bluetoothd");
+ snprintf(index, sizeof(index), "%d", hci_index);
+
+ prg_argv[0] = prg_name;
+ prg_argv[1] = "-i";
+ prg_argv[2] = index;
+ prg_argv[3] = NULL;
+
+ if (!tester_use_debug())
+ fclose(stderr);
+
+ execve(prg_argv[0], prg_argv, NULL);
+}
+
+static void emulator(int pipe, int hci_index)
+{
+ static const char SYSTEM_SOCKET_PATH[] = "\0android_system";
+ char buf[1024];
+ struct sockaddr_un addr;
+ struct timeval tv;
+ int fd;
+ ssize_t len;
+
+ fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ if (fd < 0)
+ goto failed;
+
+ tv.tv_sec = WAIT_FOR_SIGNAL_TIME;
+ tv.tv_usec = 0;
+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
+
+ 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");
+ goto failed;
+ }
+
+ len = write(pipe, EMULATOR_SIGNAL, sizeof(EMULATOR_SIGNAL));
+
+ if (len != sizeof(EMULATOR_SIGNAL))
+ goto failed;
+
+ memset(buf, 0, sizeof(buf));
+
+ len = read(fd, buf, sizeof(buf));
+ if (len <= 0 || (strcmp(buf, "ctl.start=bluetoothd")))
+ goto failed;
+
+ close(pipe);
+ close(fd);
+ bluetoothd_start(hci_index);
+
+failed:
+ close(pipe);
+ close(fd);
+}
+
static void setup(const void *data)
{
+ struct test_data *test_data = tester_get_data();
+ int signal_fd[2];
+ char buf[1024];
+ pid_t pid;
+ int len;
+
+ if (pipe(signal_fd))
+ goto failed;
+
+ pid = fork();
+
+ if (pid < 0) {
+ close(signal_fd[0]);
+ close(signal_fd[1]);
+ goto failed;
+ }
+
+ if (pid == 0) {
+ if (!tester_use_debug())
+ fclose(stderr);
+
+ close(signal_fd[0]);
+ emulator(signal_fd[1], test_data->mgmt_index);
+ exit(0);
+ }
+
+ close(signal_fd[1]);
+ test_data->bluetoothd_pid = pid;
+
+ len = read(signal_fd[0], buf, sizeof(buf));
+ if (len <= 0 || (strcmp(buf, EMULATOR_SIGNAL))) {
+ close(signal_fd[0]);
+ goto failed;
+ }
+
+ return;
+
+failed:
tester_setup_failed();
test_post_teardown(data);
}
static void teardown(const void *data)
{
+ struct test_data *test_data = tester_get_data();
+
+ if (test_data->bluetoothd_pid)
+ waitpid(test_data->bluetoothd_pid, NULL, 0);
+
tester_teardown_complete();
}
@@ -199,6 +320,8 @@ static void ipc_send_tc(const void *data)
int main(int argc, char *argv[])
{
+ snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0]));
+
tester_init(&argc, &argv);
test_generic("Test Dummy", NULL, setup, ipc_send_tc, teardown);