* [PATCHv3 1/8] android/ipc-tester: Skeleton for ipc negative tester
2014-01-15 12:42 [PATCHv3 0/8] IPC negative tester Jakub Tyszkowski
@ 2014-01-15 12:42 ` Jakub Tyszkowski
2014-01-15 12:42 ` [PATCHv3 2/8] android/ipc-tester: Run daemon in separate process Jakub Tyszkowski
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Jakub Tyszkowski @ 2014-01-15 12:42 UTC (permalink / raw)
To: linux-bluetooth
Add skeleton for ipc negative testing.
---
.gitignore | 1 +
android/Makefile.am | 17 +++++
android/ipc-tester.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 222 insertions(+)
create mode 100644 android/ipc-tester.c
diff --git a/.gitignore b/.gitignore
index ac76fe2..73a68e1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -113,4 +113,5 @@ android/system-emulator
android/bluetoothd
android/haltest
android/android-tester
+android/ipc-tester
android/bluetoothd-snoop
diff --git a/android/Makefile.am b/android/Makefile.am
index 7806f79..67877b3 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -119,6 +119,23 @@ android_android_tester_LDFLAGS = -pthread -ldl
plugin_LTLIBRARIES += android/audio.a2dp.default.la
+noinst_PROGRAMS += android/ipc-tester
+
+android_ipc_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
+ emulator/bthost.h emulator/bthost.c \
+ src/shared/io.h src/shared/io-glib.c \
+ src/shared/queue.h src/shared/queue.c \
+ src/shared/util.h src/shared/util.c \
+ src/shared/mgmt.h src/shared/mgmt.c \
+ src/shared/hciemu.h src/shared/hciemu.c \
+ src/shared/tester.h src/shared/tester.c \
+ android/hal-utils.h android/hal-utils.c \
+ android/ipc-tester.c
+
+android_ipc_tester_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android
+
+android_ipc_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
+
android_audio_a2dp_default_la_SOURCES = android/audio-msg.h \
android/hal-audio.c \
android/hardware/audio.h \
diff --git a/android/ipc-tester.c b/android/ipc-tester.c
new file mode 100644
index 0000000..9a1b4b0
--- /dev/null
+++ b/android/ipc-tester.c
@@ -0,0 +1,204 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2014 Intel Corporation. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <unistd.h>
+
+#include <glib.h>
+
+#include "lib/bluetooth.h"
+#include "lib/mgmt.h"
+
+#include "src/shared/tester.h"
+#include "src/shared/mgmt.h"
+#include "src/shared/hciemu.h"
+
+
+struct test_data {
+ struct mgmt *mgmt;
+ uint16_t mgmt_index;
+ struct hciemu *hciemu;
+ enum hciemu_type hciemu_type;
+};
+
+static void read_info_callback(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct mgmt_rp_read_info *rp = param;
+ char addr[18];
+ uint16_t manufacturer;
+ uint32_t supported_settings, current_settings;
+
+ tester_print("Read Info callback");
+ tester_print(" Status: 0x%02x", status);
+
+ if (status || !param) {
+ tester_pre_setup_failed();
+ return;
+ }
+
+ ba2str(&rp->bdaddr, addr);
+ manufacturer = btohs(rp->manufacturer);
+ supported_settings = btohl(rp->supported_settings);
+ current_settings = btohl(rp->current_settings);
+
+ tester_print(" Address: %s", addr);
+ tester_print(" Version: 0x%02x", rp->version);
+ tester_print(" Manufacturer: 0x%04x", manufacturer);
+ tester_print(" Supported settings: 0x%08x", supported_settings);
+ tester_print(" Current settings: 0x%08x", current_settings);
+ tester_print(" Class: 0x%02x%02x%02x",
+ rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
+ tester_print(" Name: %s", rp->name);
+ tester_print(" Short name: %s", rp->short_name);
+
+ if (strcmp(hciemu_get_address(data->hciemu), addr)) {
+ tester_pre_setup_failed();
+ return;
+ }
+
+ tester_pre_setup_complete();
+}
+
+static void index_added_callback(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+
+ tester_print("Index Added callback");
+ tester_print(" Index: 0x%04x", index);
+
+ data->mgmt_index = index;
+
+ mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL,
+ read_info_callback, NULL, NULL);
+}
+
+static void index_removed_callback(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+
+ tester_print("Index Removed callback");
+ tester_print(" Index: 0x%04x", index);
+
+ if (index != data->mgmt_index)
+ return;
+
+ mgmt_unregister_index(data->mgmt, data->mgmt_index);
+
+ mgmt_unref(data->mgmt);
+ data->mgmt = NULL;
+
+ tester_post_teardown_complete();
+}
+
+static void read_index_list_callback(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+
+ tester_print("Read Index List callback");
+ tester_print(" Status: 0x%02x", status);
+
+ if (status || !param) {
+ tester_pre_setup_failed();
+ return;
+ }
+
+ mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
+ index_added_callback, NULL, NULL);
+
+ mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
+ index_removed_callback, NULL, NULL);
+
+ data->hciemu = hciemu_new(data->hciemu_type);
+ if (!data->hciemu) {
+ tester_warn("Failed to setup HCI emulation");
+ tester_pre_setup_failed();
+ return;
+ }
+
+ tester_print("New hciemu instance created");
+}
+
+static void test_pre_setup(const void *data)
+{
+ struct test_data *test_data = tester_get_data();
+
+ if (!tester_use_debug())
+ fclose(stderr);
+
+ test_data->mgmt = mgmt_new_default();
+ if (!test_data->mgmt) {
+ tester_warn("Failed to setup management interface");
+ tester_pre_setup_failed();
+ return;
+ }
+
+ mgmt_send(test_data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
+ NULL, read_index_list_callback, NULL, NULL);
+}
+
+static void test_post_teardown(const void *data)
+{
+ struct test_data *test_data = tester_get_data();
+
+ hciemu_unref(test_data->hciemu);
+ test_data->hciemu = NULL;
+}
+
+static void setup(const void *data)
+{
+ tester_setup_failed();
+}
+
+static void teardown(const void *data)
+{
+ tester_teardown_complete();
+}
+
+static void ipc_send_tc(const void *data)
+{
+}
+
+#define test_bredrle(name, data, test_setup, test, test_teardown) \
+ do { \
+ struct test_data *user; \
+ user = g_malloc0(sizeof(struct test_data)); \
+ if (!user) \
+ break; \
+ user->hciemu_type = HCIEMU_TYPE_BREDRLE; \
+ tester_add_full(name, data, test_pre_setup, test_setup, \
+ test, test_teardown, test_post_teardown, \
+ 3, user, g_free); \
+ } while (0)
+
+int main(int argc, char *argv[])
+{
+ tester_init(&argc, &argv);
+
+ test_bredrle("Test Dummy", NULL, setup, ipc_send_tc, teardown);
+
+ return tester_run();
+}
--
1.8.5.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCHv3 2/8] android/ipc-tester: Run daemon in separate process
2014-01-15 12:42 [PATCHv3 0/8] IPC negative tester Jakub Tyszkowski
2014-01-15 12:42 ` [PATCHv3 1/8] android/ipc-tester: Skeleton for ipc " Jakub Tyszkowski
@ 2014-01-15 12:42 ` Jakub Tyszkowski
2014-01-15 12:42 ` [PATCHv3 3/8] android/ipc-tester: Add IPC initialization Jakub Tyszkowski
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Jakub Tyszkowski @ 2014-01-15 12:42 UTC (permalink / raw)
To: linux-bluetooth
This patch adds new process waiting to run daemon when needed.
---
android/ipc-tester.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 123 insertions(+), 1 deletion(-)
diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index 9a1b4b0..d920ccf 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)
{
@@ -168,13 +180,121 @@ static void test_post_teardown(const void *data)
test_data->hciemu = NULL;
}
+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)
{
- tester_setup_failed();
+ struct test_data *test_data = tester_get_data();
+ int signal_fd[2];
+ char buf[1024];
+ pid_t pid;
+ int len;
+
+ if (pipe(signal_fd)) {
+ tester_setup_failed();
+ return;
+ }
+
+ pid = fork();
+
+ if (pid < 0) {
+ close(signal_fd[0]);
+ close(signal_fd[1]);
+ tester_setup_failed();
+ return;
+ }
+
+ 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]);
+ tester_setup_failed();
+ return;
+ }
}
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();
}
@@ -196,6 +316,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_bredrle("Test Dummy", NULL, setup, ipc_send_tc, teardown);
--
1.8.5.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCHv3 3/8] android/ipc-tester: Add IPC initialization
2014-01-15 12:42 [PATCHv3 0/8] IPC negative tester Jakub Tyszkowski
2014-01-15 12:42 ` [PATCHv3 1/8] android/ipc-tester: Skeleton for ipc " Jakub Tyszkowski
2014-01-15 12:42 ` [PATCHv3 2/8] android/ipc-tester: Run daemon in separate process Jakub Tyszkowski
@ 2014-01-15 12:42 ` Jakub Tyszkowski
2014-01-15 12:42 ` [PATCHv3 4/8] android/ipc-tester: Add daemon shutdown handler Jakub Tyszkowski
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Jakub Tyszkowski @ 2014-01-15 12:42 UTC (permalink / raw)
To: linux-bluetooth
This patch adds IPC mechanism initialization.
The deamon is being started and IPC socket connection is established.
---
android/ipc-tester.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 122 insertions(+)
diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index d920ccf..b76be32 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -23,6 +23,8 @@
#include <stdlib.h>
#include <unistd.h>
+#include <errno.h>
+#include <poll.h>
#include <sys/socket.h>
#include <sys/types.h>
@@ -38,6 +40,8 @@
#include "src/shared/mgmt.h"
#include "src/shared/hciemu.h"
+#include "hal-msg.h"
+#include <cutils/properties.h>
#define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
#define EMULATOR_SIGNAL "emulator_started"
@@ -50,8 +54,14 @@ struct test_data {
pid_t bluetoothd_pid;
};
+#define CONNECT_TIMEOUT (5 * 1000)
+#define SERVICE_NAME "bluetoothd"
+
static char exec_dir[PATH_MAX + 1];
+static int cmd_sk = -1;
+static int notif_sk = -1;
+
static void read_info_callback(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
@@ -246,6 +256,109 @@ failed:
close(fd);
}
+static int accept_connection(int sk)
+{
+ int err;
+ struct pollfd pfd;
+ int new_sk;
+
+ memset(&pfd, 0 , sizeof(pfd));
+ pfd.fd = sk;
+ pfd.events = POLLIN;
+
+ err = poll(&pfd, 1, CONNECT_TIMEOUT);
+ if (err < 0) {
+ err = errno;
+ tester_warn("Failed to poll: %d (%s)", err, strerror(err));
+ return -errno;
+ }
+
+ if (err == 0) {
+ tester_warn("bluetoothd connect timeout");
+ return -errno;
+ }
+
+ new_sk = accept(sk, NULL, NULL);
+ if (new_sk < 0) {
+ err = errno;
+ tester_warn("Failed to accept socket: %d (%s)",
+ err, strerror(err));
+ return -errno;
+ }
+
+ return new_sk;
+}
+
+static bool init_ipc(void)
+{
+ struct sockaddr_un addr;
+
+ int sk;
+ int err;
+
+ sk = socket(AF_LOCAL, SOCK_SEQPACKET, 0);
+ if (sk < 0) {
+ err = errno;
+ tester_warn("Failed to create socket: %d (%s)", err,
+ strerror(err));
+ return false;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+
+ memcpy(addr.sun_path, BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH));
+
+ if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ err = errno;
+ tester_warn("Failed to bind socket: %d (%s)", err,
+ strerror(err));
+ close(sk);
+ return false;
+ }
+
+ if (listen(sk, 2) < 0) {
+ err = errno;
+ tester_warn("Failed to listen on socket: %d (%s)", err,
+ strerror(err));
+ close(sk);
+ return false;
+ }
+
+ /* Start Android Bluetooth daemon service */
+ if (property_set("ctl.start", SERVICE_NAME) < 0) {
+ tester_warn("Failed to start service %s", SERVICE_NAME);
+ close(sk);
+ return false;
+ }
+
+ cmd_sk = accept_connection(sk);
+ if (cmd_sk < 0) {
+ close(sk);
+ return false;
+ }
+
+ notif_sk = accept_connection(sk);
+ if (notif_sk < 0) {
+ close(sk);
+ close(cmd_sk);
+ cmd_sk = -1;
+ return false;
+ }
+
+ tester_print("bluetoothd connected");
+
+ close(sk);
+
+ return true;
+}
+
+static void cleanup_ipc(void)
+{
+ close(cmd_sk);
+ cmd_sk = -1;
+}
+
static void setup(const void *data)
{
struct test_data *test_data = tester_get_data();
@@ -286,12 +399,21 @@ static void setup(const void *data)
tester_setup_failed();
return;
}
+ if (!init_ipc()) {
+ tester_warn("Cannot initialize IPC mechanism!");
+ tester_setup_failed();
+ return;
+ }
+
+ /* TODO: register modules */
}
static void teardown(const void *data)
{
struct test_data *test_data = tester_get_data();
+ cleanup_ipc();
+
if (test_data->bluetoothd_pid)
waitpid(test_data->bluetoothd_pid, NULL, 0);
--
1.8.5.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCHv3 4/8] android/ipc-tester: Add daemon shutdown handler
2014-01-15 12:42 [PATCHv3 0/8] IPC negative tester Jakub Tyszkowski
` (2 preceding siblings ...)
2014-01-15 12:42 ` [PATCHv3 3/8] android/ipc-tester: Add IPC initialization Jakub Tyszkowski
@ 2014-01-15 12:42 ` Jakub Tyszkowski
2014-01-15 12:42 ` [PATCHv3 5/8] android/ipc-tester: Add sending test data with ipc Jakub Tyszkowski
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Jakub Tyszkowski @ 2014-01-15 12:42 UTC (permalink / raw)
To: linux-bluetooth
Handle daemon shutdown asynchronously.
---
android/ipc-tester.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index b76be32..9be7208 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -52,6 +52,7 @@ struct test_data {
struct hciemu *hciemu;
enum hciemu_type hciemu_type;
pid_t bluetoothd_pid;
+ bool setup_done;
};
#define CONNECT_TIMEOUT (5 * 1000)
@@ -359,6 +360,44 @@ static void cleanup_ipc(void)
cmd_sk = -1;
}
+static gboolean check_for_daemon(gpointer user_data)
+{
+ int status;
+ struct test_data *data = user_data;
+
+ if ((waitpid(data->bluetoothd_pid, &status, WNOHANG))
+ != data->bluetoothd_pid)
+ return true;
+
+ if (WIFEXITED(status)) {
+ tester_test_passed();
+ } else if (WIFSIGNALED(status)) {
+ switch (WTERMSIG(status)) {
+ case SIGTERM:
+ if (data->setup_done)
+ tester_test_passed();
+ else
+ tester_setup_failed();
+ break;
+ case SIGSEGV:
+ tester_warn("Daemon died with segmentation fault");
+ goto failed;
+ default:
+ tester_warn("Bad signal received %d", status);
+ goto failed;
+ }
+ }
+
+ return true;
+
+failed:
+ if (data->setup_done)
+ tester_test_failed();
+ else
+ tester_setup_failed();
+ return false;
+}
+
static void setup(const void *data)
{
struct test_data *test_data = tester_get_data();
@@ -399,6 +438,10 @@ static void setup(const void *data)
tester_setup_failed();
return;
}
+
+ g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, check_for_daemon, test_data,
+ NULL);
+
if (!init_ipc()) {
tester_warn("Cannot initialize IPC mechanism!");
tester_setup_failed();
@@ -406,6 +449,8 @@ static void setup(const void *data)
}
/* TODO: register modules */
+
+ test_data->setup_done = true;
}
static void teardown(const void *data)
--
1.8.5.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCHv3 5/8] android/ipc-tester: Add sending test data with ipc
2014-01-15 12:42 [PATCHv3 0/8] IPC negative tester Jakub Tyszkowski
` (3 preceding siblings ...)
2014-01-15 12:42 ` [PATCHv3 4/8] android/ipc-tester: Add daemon shutdown handler Jakub Tyszkowski
@ 2014-01-15 12:42 ` Jakub Tyszkowski
2014-01-15 12:42 ` [PATCHv3 6/8] android/ipc-tester: Register services Jakub Tyszkowski
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Jakub Tyszkowski @ 2014-01-15 12:42 UTC (permalink / raw)
To: linux-bluetooth
This patch adds some data structures used to send data with ipc during test setup
and run stage.
---
android/ipc-tester.c | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index 9be7208..9ffb584 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -55,6 +55,18 @@ struct test_data {
bool setup_done;
};
+struct ipc_data {
+ void *buffer;
+ size_t len;
+};
+
+struct generic_data {
+ struct ipc_data ipc_data;
+
+ unsigned int num_services;
+ int init_services[];
+};
+
#define CONNECT_TIMEOUT (5 * 1000)
#define SERVICE_NAME "bluetoothd"
@@ -467,6 +479,13 @@ static void teardown(const void *data)
static void ipc_send_tc(const void *data)
{
+ const struct generic_data *generic_data = data;
+ const struct ipc_data *ipc_data = &generic_data->ipc_data;
+
+ if (ipc_data->len) {
+ if (write(cmd_sk, ipc_data->buffer, ipc_data->len) < 0)
+ tester_test_failed();
+ }
}
#define test_bredrle(name, data, test_setup, test, test_teardown) \
@@ -481,13 +500,22 @@ static void ipc_send_tc(const void *data)
3, user, g_free); \
} while (0)
+static const struct generic_data dummy_data = {
+ .ipc_data = {
+ .buffer = "",
+ .len = 1,
+ },
+ .init_services = {HAL_SERVICE_ID_BLUETOOTH},
+ .num_services = 1,
+};
+
int main(int argc, char *argv[])
{
snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0]));
tester_init(&argc, &argv);
- test_bredrle("Test Dummy", NULL, setup, ipc_send_tc, teardown);
+ test_bredrle("Test Dummy", &dummy_data, setup, ipc_send_tc, teardown);
return tester_run();
}
--
1.8.5.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCHv3 6/8] android/ipc-tester: Register services
2014-01-15 12:42 [PATCHv3 0/8] IPC negative tester Jakub Tyszkowski
` (4 preceding siblings ...)
2014-01-15 12:42 ` [PATCHv3 5/8] android/ipc-tester: Add sending test data with ipc Jakub Tyszkowski
@ 2014-01-15 12:42 ` Jakub Tyszkowski
2014-01-15 12:42 ` [PATCHv3 7/8] android/ipc-tester: Add basic test cases for IPC's daemon site Jakub Tyszkowski
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Jakub Tyszkowski @ 2014-01-15 12:42 UTC (permalink / raw)
To: linux-bluetooth
This patch adds basic bluetooth service registration during setup procedure.
Without this daemon would reject commands for not registered services.
---
android/ipc-tester.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 47 insertions(+), 1 deletion(-)
diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index 9ffb584..5901c78 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -410,13 +410,53 @@ failed:
return false;
}
+struct regmod_msg {
+ struct hal_hdr header;
+ struct hal_cmd_register_module cmd;
+} __attribute__((packed));
+
+static bool setup_module(int service_id)
+{
+ struct hal_hdr response;
+ struct hal_hdr expected_response;
+
+ struct regmod_msg btmodule_msg = {
+ .header = {
+ .service_id = HAL_SERVICE_ID_CORE,
+ .opcode = HAL_OP_REGISTER_MODULE,
+ .len = sizeof(struct hal_cmd_register_module),
+ },
+ .cmd = {
+ .service_id = service_id,
+ },
+ };
+
+ if (write(cmd_sk, &btmodule_msg, sizeof(btmodule_msg)) < 0)
+ goto fail;
+
+ if (read(cmd_sk, &response, sizeof(response)) < 0)
+ goto fail;
+
+ expected_response = btmodule_msg.header;
+ expected_response.len = 0;
+
+ if (memcmp(&response, &expected_response, sizeof(response)) == 0)
+ return true;
+
+fail:
+ tester_warn("Module registration failed.");
+ return false;
+}
+
static void setup(const void *data)
{
+ const struct generic_data *generic_data = data;
struct test_data *test_data = tester_get_data();
int signal_fd[2];
char buf[1024];
pid_t pid;
int len;
+ unsigned int i;
if (pipe(signal_fd)) {
tester_setup_failed();
@@ -460,9 +500,15 @@ static void setup(const void *data)
return;
}
- /* TODO: register modules */
+ tester_print("Will init %d services.", generic_data->num_services);
+
+ for (i = 0; i < generic_data->num_services; i++)
+ if (!setup_module(generic_data->init_services[i]))
+ tester_setup_failed();
test_data->setup_done = true;
+
+ tester_setup_complete();
}
static void teardown(const void *data)
--
1.8.5.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCHv3 7/8] android/ipc-tester: Add basic test cases for IPC's daemon site
2014-01-15 12:42 [PATCHv3 0/8] IPC negative tester Jakub Tyszkowski
` (5 preceding siblings ...)
2014-01-15 12:42 ` [PATCHv3 6/8] android/ipc-tester: Register services Jakub Tyszkowski
@ 2014-01-15 12:42 ` Jakub Tyszkowski
2014-01-15 12:42 ` [PATCHv3 8/8] androi/ipc-tester: Add more cases for malformed data Jakub Tyszkowski
2014-01-15 16:04 ` [PATCHv3 0/8] IPC negative tester Szymon Janc
8 siblings, 0 replies; 10+ messages in thread
From: Jakub Tyszkowski @ 2014-01-15 12:42 UTC (permalink / raw)
To: linux-bluetooth
This patch add first few test cases checking for proper daemon
termination in case of receiving invalid IPC data.
---
android/ipc-tester.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 117 insertions(+), 3 deletions(-)
diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index 5901c78..72200d8 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -546,11 +546,113 @@ static void ipc_send_tc(const void *data)
3, user, g_free); \
} while (0)
-static const struct generic_data dummy_data = {
+struct regmod_msg register_bt_msg = {
+ .header = {
+ .service_id = HAL_SERVICE_ID_CORE,
+ .opcode = HAL_OP_REGISTER_MODULE,
+ .len = sizeof(struct hal_cmd_register_module),
+ },
+ .cmd = {
+ .service_id = HAL_SERVICE_ID_CORE,
+ },
+};
+
+static const struct generic_data to_small_data = {
.ipc_data = {
- .buffer = "",
+ /* valid header and payload */
+ .buffer = ®ister_bt_msg,
+ /* but write only incomplete header */
.len = 1,
},
+ .init_services = {},
+ .num_services = 0,
+};
+
+struct regmod_msg register_bt_malformed_size_msg = {
+ .header = {
+ .service_id = HAL_SERVICE_ID_CORE,
+ .opcode = HAL_OP_REGISTER_MODULE,
+ /* wrong payload size declared */
+ .len = sizeof(struct hal_cmd_register_module) - 1,
+ },
+ .cmd = {
+ .service_id = HAL_SERVICE_ID_CORE,
+ },
+};
+
+static const struct generic_data malformed_data = {
+ .ipc_data = {
+ /* use malformed msg - wrong size declared */
+ .buffer = ®ister_bt_malformed_size_msg,
+ /* but write proper size */
+ .len = sizeof(register_bt_malformed_size_msg),
+ },
+ .init_services = {HAL_SERVICE_ID_BLUETOOTH},
+ .num_services = 1,
+};
+
+struct hal_hdr enable_unknown_service_hdr = {
+ .service_id = HAL_SERVICE_ID_MAX + 1,
+ .opcode = HAL_OP_REGISTER_MODULE,
+ .len = 0,
+};
+
+static const struct generic_data enable_unknown_service_data = {
+ .ipc_data = {
+ /* enable invalid service */
+ .buffer = &enable_unknown_service_hdr,
+ .len = sizeof(enable_unknown_service_hdr),
+ },
+ .init_services = {HAL_SERVICE_ID_BLUETOOTH},
+ .num_services = 1,
+};
+
+struct hal_hdr enable_bt_service_hdr = {
+ .service_id = HAL_SERVICE_ID_BLUETOOTH,
+ .opcode = HAL_OP_ENABLE,
+ .len = 0,
+};
+
+static const struct generic_data enable_unregistered_service_data = {
+ .ipc_data = {
+ /* valid msg */
+ .buffer = &enable_bt_service_hdr,
+ /* send the whole thing */
+ .len = sizeof(enable_bt_service_hdr),
+ },
+ /* but don't register it before enabling */
+ .init_services = {},
+ .num_services = 0,
+};
+
+struct hal_hdr invalid_opcode_hdr = {
+ .service_id = HAL_SERVICE_ID_BLUETOOTH,
+ .opcode = 0x16,
+ .len = 0,
+};
+
+static const struct generic_data invalid_opcode_data = {
+ .ipc_data = {
+ /* valid msg */
+ .buffer = &invalid_opcode_hdr,
+ /* send the whole thing */
+ .len = sizeof(invalid_opcode_hdr),
+ },
+ .init_services = {HAL_SERVICE_ID_BLUETOOTH},
+ .num_services = 1,
+};
+
+struct hal_hdr invalid_msg_size_hdr = {
+ .service_id = HAL_SERVICE_ID_BLUETOOTH,
+ .opcode = HAL_OP_CREATE_BOND,
+ .len = 0,
+};
+
+static const struct generic_data invalid_msg_size_data = {
+ .ipc_data = {
+ .buffer = &invalid_msg_size_hdr,
+ .len = sizeof(invalid_msg_size_hdr),
+ },
.init_services = {HAL_SERVICE_ID_BLUETOOTH},
.num_services = 1,
};
@@ -561,7 +663,19 @@ int main(int argc, char *argv[])
tester_init(&argc, &argv);
- test_bredrle("Test Dummy", &dummy_data, setup, ipc_send_tc, teardown);
+ test_bredrle("To small data", &to_small_data,
+ setup, ipc_send_tc, teardown);
+ test_bredrle("Malformed data (wrong payload declared)", &malformed_data,
+ setup, ipc_send_tc, teardown);
+ test_bredrle("Invalid service", &enable_unknown_service_data,
+ setup, ipc_send_tc, teardown);
+ test_bredrle("Enable unregistered service",
+ &enable_unregistered_service_data,
+ setup, ipc_send_tc, teardown);
+ test_bredrle("Invalid opcode", &invalid_opcode_data,
+ setup, ipc_send_tc, teardown);
+ test_bredrle("Invalid msg size for opcode", &invalid_msg_size_data,
+ setup, ipc_send_tc, teardown);
return tester_run();
}
--
1.8.5.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCHv3 8/8] androi/ipc-tester: Add more cases for malformed data
2014-01-15 12:42 [PATCHv3 0/8] IPC negative tester Jakub Tyszkowski
` (6 preceding siblings ...)
2014-01-15 12:42 ` [PATCHv3 7/8] android/ipc-tester: Add basic test cases for IPC's daemon site Jakub Tyszkowski
@ 2014-01-15 12:42 ` Jakub Tyszkowski
2014-01-15 16:04 ` [PATCHv3 0/8] IPC negative tester Szymon Janc
8 siblings, 0 replies; 10+ messages in thread
From: Jakub Tyszkowski @ 2014-01-15 12:42 UTC (permalink / raw)
To: linux-bluetooth
This patch adds tests for more types of possible data malformations.
---
android/ipc-tester.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index 72200d8..046b794 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -591,6 +591,48 @@ static const struct generic_data malformed_data = {
.num_services = 1,
};
+static const struct generic_data malformed_data2 = {
+ .ipc_data = {
+ /* use proper msg */
+ .buffer = ®ister_bt_msg,
+ /* but write incomplete */
+ .len = sizeof(register_bt_msg) - 1,
+ },
+ .init_services = {HAL_SERVICE_ID_BLUETOOTH},
+ .num_services = 1,
+};
+
+struct malformed_data3_struct {
+ struct regmod_msg valid_msg;
+ int redundant_data;
+} __attribute__((packed));
+
+static struct malformed_data3_struct malformed_data3_msg = {
+ /* valid register service message */
+ .valid_msg = {
+ .header = {
+ .service_id = HAL_SERVICE_ID_CORE,
+ .opcode = HAL_OP_REGISTER_MODULE,
+ .len = sizeof(struct hal_cmd_register_module),
+ },
+ .cmd = {
+ .service_id = HAL_SERVICE_ID_CORE,
+ },
+ },
+ /* plus redundant data */
+ . redundant_data = 666,
+};
+
+static const struct generic_data malformed_data3 = {
+ .ipc_data = {
+ /* use malformed msg */
+ .buffer = &malformed_data3_msg,
+ .len = sizeof(malformed_data3_msg),
+ },
+ .init_services = {HAL_SERVICE_ID_BLUETOOTH},
+ .num_services = 1,
+};
+
struct hal_hdr enable_unknown_service_hdr = {
.service_id = HAL_SERVICE_ID_MAX + 1,
.opcode = HAL_OP_REGISTER_MODULE,
@@ -667,6 +709,10 @@ int main(int argc, char *argv[])
setup, ipc_send_tc, teardown);
test_bredrle("Malformed data (wrong payload declared)", &malformed_data,
setup, ipc_send_tc, teardown);
+ test_bredrle("Malformed data2 (undersized msg)", &malformed_data2,
+ setup, ipc_send_tc, teardown);
+ test_bredrle("Malformed data3 (oversized msg)", &malformed_data3,
+ setup, ipc_send_tc, teardown);
test_bredrle("Invalid service", &enable_unknown_service_data,
setup, ipc_send_tc, teardown);
test_bredrle("Enable unregistered service",
--
1.8.5.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCHv3 0/8] IPC negative tester
2014-01-15 12:42 [PATCHv3 0/8] IPC negative tester Jakub Tyszkowski
` (7 preceding siblings ...)
2014-01-15 12:42 ` [PATCHv3 8/8] androi/ipc-tester: Add more cases for malformed data Jakub Tyszkowski
@ 2014-01-15 16:04 ` Szymon Janc
8 siblings, 0 replies; 10+ messages in thread
From: Szymon Janc @ 2014-01-15 16:04 UTC (permalink / raw)
To: Jakub Tyszkowski; +Cc: linux-bluetooth
Hi Jakub,
On Wednesday 15 of January 2014 13:42:29 Jakub Tyszkowski wrote:
> Following patchset adds IPC negative tester framework with few test cases
> checking IPC's behaviour on daemon side. Expected daemon's behaviour is to
> shut down gracefully in case of receiving invalid IPC data.
>
> v2 changes:
> * fixed few indentation issues
> * fixed missing __attribute__((packed))
> * fixed amount of data written for 'malformed data' test case
> * fixed opcode for 'invalid service' test case
> * added patch(8) with more 'malformed data' cases
>
> v3 changes:
> * changed license to GPL
> * changed 'ipc-negative-tester' name to 'ipc-tester'
>
> Jakub Tyszkowski (8):
> android/ipc-tester: Skeleton for ipc negative tester
> android/ipc-tester: Run daemon in separate process
> android/ipc-tester: Add IPC initialization
> android/ipc-tester: Add daemon shutdown handler
> android/ipc-tester: Add sending test data with ipc
> android/ipc-tester: Register services
> android/ipc-tester: Add basic test cases for IPC's daemon site
> androi/ipc-tester: Add more cases for malformed data
>
> .gitignore | 1 +
> android/Makefile.am | 17 ++
> android/ipc-tester.c | 727 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 745 insertions(+)
> create mode 100644 android/ipc-tester.c
>
> --
> 1.8.5.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Please send V4 with changes we discussed off-line.
--
Best regards,
Szymon Janc
^ permalink raw reply [flat|nested] 10+ messages in thread