diff --git a/android/Android.mk b/android/Android.mk
index 6931c9c..88cb960 100644
--- a/android/Android.mk
+++ b/android/Android.mk
client/terminal.c \
client/history.c \
client/textconv.c \
+ client/if-bt.c \
LOCAL_SHARED_LIBRARIES := libhardware
diff --git a/android/client/haltest.c b/android/client/haltest.c
index de98079..6dcabbc 100644
--- a/android/client/haltest.c
+++ b/android/client/haltest.c
*/
#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
#include <poll.h>
#include <unistd.h>
+#include "if-main.h"
#include "terminal.h"
#include "pollhandler.h"
+#include "history.h"
+
+const struct interface *interfaces[] = {
+ &bluetooth_if,
+ NULL
+};
+
+int haltest_error(const char *format, ...)
+{
+ va_list args;
+ int ret;
+ va_start(args, format);
+ ret = terminal_vprint(format, args);
+ va_end(args);
+ return ret;
+}
+
+int haltest_info(const char *format, ...)
+{
+ va_list args;
+ int ret;
+ va_start(args, format);
+ ret = terminal_vprint(format, args);
+ va_end(args);
+ return ret;
+}
+
+int haltest_warn(const char *format, ...)
+{
+ va_list args;
+ int ret;
+ va_start(args, format);
+ ret = terminal_vprint(format, args);
+ va_end(args);
+ return ret;
+}
/*
* This function changes input parameter line_buffer so it has
{
char *argv[10];
int argc;
+ int i = 0;
+ int j;
argc = command_line_to_argv(line_buffer, argv, 10);
+ if (argc < 1)
+ return;
+
+ while (interfaces[i] != NULL) {
+ if (strcmp(interfaces[i]->name, argv[0])) {
+ i++;
+ continue;
+ }
+ if (argc < 2 || strcmp(argv[1], "?") == 0) {
+ j = 0;
+ while (strcmp(interfaces[i]->methods[j].name, "")) {
+ haltest_info("%s %s\n", argv[0],
+ interfaces[i]->methods[j].name);
+ ++j;
+ }
+ return;
+ }
+ j = 0;
+ while (strcmp(interfaces[i]->methods[j].name, "")) {
+ if (strcmp(interfaces[i]->methods[j].name, argv[1])) {
+ j++;
+ continue;
+ }
+ interfaces[i]->methods[j].func(argc,
+ (const char **)argv);
+ break;
+ }
+ if (strcmp(interfaces[i]->methods[j].name, "") == 0)
+ printf("No function %s found\n", argv[1]);
+ break;
+ }
- /* TODO: process command line */
+ if (interfaces[i] == NULL)
+ printf("No such interface %s\n", argv[0]);
}
/* called when there is something on stdin */
int main(int argc, char **argv)
{
terminal_setup();
+ history_restore(".haltest_history");
/* Register command line handler */
poll_register_fd(0, POLLIN, stdin_handler);
diff --git a/android/client/if-bt.c b/android/client/if-bt.c
new file mode 100644
index 0000000..a0a4bd9
--- /dev/null
+++ b/android/client/if-bt.c
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "if-main.h"
+
+const bt_interface_t *if_bluetooth;
+
+static char *bdaddr2str(const bt_bdaddr_t *bd_addr)
+{
+ static char buf[18];
+
+ return bt_bdaddr_t2str(bd_addr, buf);
+}
+
+static char *btuuid2str(const bt_uuid_t *uuid)
+{
+ static char buf[39];
+
+ return bt_uuid_t2str(uuid, buf);
+}
+
+static bt_scan_mode_t str2btscanmode(const char *str)
+{
+ bt_scan_mode_t v = str2bt_scan_mode_t(str);
+
+ if ((int) v != -1)
+ return v;
+
+ haltest_warn("WARN: %s cannot convert %s\n", __func__, str);
+ return (bt_scan_mode_t) atoi(str);
+}
+
+static bt_ssp_variant_t str2btsspvariant(const char *str)
+{
+ bt_ssp_variant_t v = str2bt_ssp_variant_t(str);
+
+ if ((int) v != -1)
+ return v;
+
+ haltest_warn("WARN: %s cannot convert %s\n", __func__, str);
+ return (bt_ssp_variant_t) atoi(str);
+}
+
+static bt_property_type_t str2btpropertytype(const char *str)
+{
+ bt_property_type_t v = str2bt_property_type_t(str);
+
+ if ((int) v != -1)
+ return v;
+
+ haltest_warn("WARN: %s cannot convert %s\n", __func__, str);
+ return (bt_property_type_t) atoi(str);
+}
+
+static char *btproperty2str(bt_property_t property)
+{
+ static char buf[4096];
+ char *p;
+
+ p = buf + sprintf(buf, "type=%s len=%d val=",
+ bt_property_type_t2str(property.type), property.len);
+
+ switch (property.type) {
+ case BT_PROPERTY_BDNAME:
+ case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
+ sprintf(p, "%*s", property.len,
+ ((bt_bdname_t *) property.val)->name);
+ break;
+
+ case BT_PROPERTY_BDADDR:
+ sprintf(p, "%s", bdaddr2str((bt_bdaddr_t *) property.val));
+ break;
+
+ case BT_PROPERTY_CLASS_OF_DEVICE:
+ sprintf(p, "%06x", *((int *) property.val));
+ break;
+
+ case BT_PROPERTY_TYPE_OF_DEVICE:
+ sprintf(p, "%s", bt_device_type_t2str(
+ *((bt_device_type_t *) property.val)));
+ break;
+
+ case BT_PROPERTY_REMOTE_RSSI:
+ sprintf(p, "%d", *((char *) property.val));
+ break;
+
+ case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ sprintf(p, "%s",
+ bt_scan_mode_t2str(*((bt_scan_mode_t *) property.val)));
+ break;
+
+ case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ sprintf(p, "%d", *((int *) property.val));
+ break;
+
+ case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
+ {
+ int count = property.len / sizeof(bt_bdaddr_t);
+ char *ptr = property.val;
+
+ strcat(p, "{");
+
+ while (count--) {
+ strcat(p, bdaddr2str((bt_bdaddr_t *) ptr));
+ if (count)
+ strcat(p, ", ");
+ ptr += sizeof(bt_bdaddr_t);
+ }
+
+ strcat(p, "}");
+
+ }
+ break;
+
+ case BT_PROPERTY_UUIDS:
+ {
+ int count = property.len / sizeof(bt_uuid_t);
+ char *ptr = property.val;
+
+ strcat(p, "{");
+
+ while (count--) {
+ strcat(p, btuuid2str((bt_uuid_t *) ptr));
+ if (count)
+ strcat(p, ", ");
+ ptr += sizeof(bt_uuid_t);
+ }
+
+ strcat(p, "}");
+
+ }
+ break;
+
+ case BT_PROPERTY_SERVICE_RECORD:
+ {
+ bt_service_record_t *rec = property.val;
+
+ sprintf(p, "{%s, %d, %s}", btuuid2str(&rec->uuid),
+ rec->channel, rec->name);
+ }
+ break;
+
+ default:
+ sprintf(p, "%p", property.val);
+ }
+
+ return buf;
+}
+
+static void dump_properties(int num_properties, bt_property_t *properties)
+{
+ int i;
+
+ for (i = 0; i < num_properties; i++) {
+ /*
+ * properities sometimes come unaligned hence memcp to
+ * aligned buffer
+ */
+ bt_property_t prop;
+ memcpy(&prop, properties + i, sizeof(prop));
+
+ haltest_info("prop: %s\n", btproperty2str(prop));
+ }
+}
+
+static void adapter_state_changed_cb(bt_state_t state)
+{
+ haltest_info("%s: state=%s\n", __func__, bt_state_t2str(state));
+}
+
+static void adapter_properties_cb(bt_status_t status,
+ int num_properties, bt_property_t *properties)
+{
+ haltest_info("%s: status=%s num_properties=%d\n",
+ __func__, bt_status_t2str(status), num_properties);
+
+ dump_properties(num_properties, properties);
+}
+
+static void remote_device_properties_cb(bt_status_t status,
+ bt_bdaddr_t *bd_addr, int num_properties, bt_property_t *properties)
+{
+ haltest_info("%s: status=%s bd_addr=%s num_properties=%d\n",
+ __func__, bt_status_t2str(status), bdaddr2str(bd_addr),
+ num_properties);
+
+ dump_properties(num_properties, properties);
+}
+
+static void device_found_cb(int num_properties, bt_property_t *properties)
+{
+ haltest_info("%s: num_properties=%d\n", __func__, num_properties);
+
+ dump_properties(num_properties, properties);
+}
+
+static void discovery_state_changed_cb(bt_discovery_state_t state)
+{
+ haltest_info("%s: state=%s\n", __func__,
+ bt_discovery_state_t2str(state));
+}
+
+static void pin_request_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name,
+ uint32_t cod)
+{
+ haltest_info("%s: remote_bd_addr=%s bd_name=%s cod=%06x\n", __func__,
+ bdaddr2str(remote_bd_addr), bd_name->name, cod);
+}
+
+static void ssp_request_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name,
+ uint32_t cod, bt_ssp_variant_t pairing_variant,
+ uint32_t pass_key)
+{
+ haltest_info("%s: remote_bd_addr=%s bd_name=%s cod=%06x pairing_variant=%s pass_key=%d\n",
+ __func__, bdaddr2str(remote_bd_addr), bd_name->name, cod,
+ bt_ssp_variant_t2str(pairing_variant), pass_key);
+}
+
+static void bond_state_changed_cb(bt_status_t status,
+ bt_bdaddr_t *remote_bd_addr,
+ bt_bond_state_t state)
+{
+ haltest_info("%s: status=%s remote_bd_addr=%s state=%s\n", __func__,
+ bt_status_t2str(status), bdaddr2str(remote_bd_addr),
+ bt_bond_state_t2str(state));
+}
+
+static void acl_state_changed_cb(bt_status_t status,
+ bt_bdaddr_t *remote_bd_addr,
+ bt_acl_state_t state)
+{
+ haltest_info("%s: status=%s remote_bd_addr=%s state=%s\n", __func__,
+ bt_status_t2str(status), bdaddr2str(remote_bd_addr),
+ bt_acl_state_t2str(state));
+}
+
+static void thread_evt_cb(bt_cb_thread_evt evt)
+{
+ haltest_info("%s: evt=%s\n", __func__, bt_cb_thread_evt2str(evt));
+}
+
+static void dut_mode_recv_cb(uint16_t opcode, uint8_t *buf, uint8_t len)
+{
+ haltest_info("%s\n", __func__);
+}
+
+static void le_test_mode_cb(bt_status_t status, uint16_t num_packets)
+{
+ haltest_info("%s %s %d\n", __func__, bt_state_t2str(status),
+ num_packets);
+}
+
+static bt_callbacks_t bt_callbacks = {
+ .size = sizeof(bt_callbacks),
+ .adapter_state_changed_cb = adapter_state_changed_cb,
+ .adapter_properties_cb = adapter_properties_cb,
+ .remote_device_properties_cb = remote_device_properties_cb,
+ .device_found_cb = device_found_cb,
+ .discovery_state_changed_cb = discovery_state_changed_cb,
+ .pin_request_cb = pin_request_cb,
+ .ssp_request_cb = ssp_request_cb,
+ .bond_state_changed_cb = bond_state_changed_cb,
+ .acl_state_changed_cb = acl_state_changed_cb,
+ .thread_evt_cb = thread_evt_cb,
+ .dut_mode_recv_cb = dut_mode_recv_cb,
+ .le_test_mode_cb = le_test_mode_cb
+};
+
+static void init_p(int argc, const char **argv)
+{
+ int err;
+ const hw_module_t *module;
+ hw_device_t *device;
+
+ err = hw_get_module(BT_HARDWARE_MODULE_ID, &module);
+ if (err) {
+ haltest_error("he_get_module returned %d\n", err);
+ return;
+ }
+
+ err = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
+ if (err) {
+ haltest_error("module->methods->open returned %d\n", err);
+ return;
+ }
+
+ if_bluetooth =
+ ((bluetooth_device_t *) device)->get_bluetooth_interface();
+ if (!if_bluetooth) {
+ haltest_error("get_bluetooth_interface returned NULL\n");
+ return;
+ }
+
+ EXEC(if_bluetooth->init, &bt_callbacks);
+}
+
+static void cleanup_p(int argc, const char **argv)
+{
+ RETURN_IF_NULL(if_bluetooth);
+
+ EXECV(if_bluetooth->cleanup);
+
+ if_bluetooth = NULL;
+}
+
+static void enable_p(int argc, const char **argv)
+{
+ RETURN_IF_NULL(if_bluetooth);
+
+ EXEC(if_bluetooth->enable);
+}
+
+static void disable_p(int argc, const char **argv)
+{
+ RETURN_IF_NULL(if_bluetooth);
+
+ EXEC(if_bluetooth->disable);
+}
+
+static void get_adapter_properties_p(int argc, const char **argv)
+{
+ RETURN_IF_NULL(if_bluetooth);
+
+ EXEC(if_bluetooth->get_adapter_properties);
+}
+
+static void get_adapter_property_p(int argc, const char **argv)
+{
+ int type = str2btpropertytype(argv[2]);
+
+ RETURN_IF_NULL(if_bluetooth);
+
+ EXEC(if_bluetooth->get_adapter_property, type);
+}
+
+static void set_adapter_property_p(int argc, const char **argv)
+{
+ bt_property_t property;
+ bt_scan_mode_t mode;
+ int timeout;
+
+ RETURN_IF_NULL(if_bluetooth);
+
+ property.type = str2btpropertytype(argv[2]);
+
+ switch (property.type) {
+ case BT_PROPERTY_BDNAME:
+ property.len = strlen(argv[3]) + 1;
+ property.val = (char *) argv[3];
+ break;
+
+ case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ mode = str2btscanmode(argv[3]);
+ property.len = sizeof(bt_scan_mode_t);
+ property.val = &mode;
+ break;
+
+ case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ timeout = atoi(argv[3]);
+ property.val = &timeout;
+ property.len = sizeof(timeout);
+ break;
+
+ default:
+ haltest_error("Invalid property %s\n", argv[3]);
+ return;
+ }
+
+ EXEC(if_bluetooth->set_adapter_property, &property);
+}
+
+static void get_remote_device_properties_p(int argc, const char **argv)
+{
+ bt_bdaddr_t addr;
+
+ RETURN_IF_NULL(if_bluetooth);
+
+ str2bt_bdaddr_t(argv[2], &addr);
+
+ EXEC(if_bluetooth->get_remote_device_properties, &addr);
+}
+
+static void get_remote_device_property_p(int argc, const char **argv)
+{
+ bt_property_type_t type;
+ bt_bdaddr_t addr;
+
+ RETURN_IF_NULL(if_bluetooth);
+
+ str2bt_bdaddr_t(argv[2], &addr);
+ type = str2btpropertytype(argv[3]);
+
+ EXEC(if_bluetooth->get_remote_device_property, &addr, type);
+}
+
+static void set_remote_device_property_p(int argc, const char **argv)
+{
+ bt_property_t property;
+ bt_bdaddr_t addr;
+
+ RETURN_IF_NULL(if_bluetooth);
+
+ str2bt_bdaddr_t(argv[2], &addr);
+ property.type = str2btpropertytype(argv[3]);
+
+ switch (property.type) {
+ case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
+ property.len = strlen(argv[4]);
+ property.val = (char *) argv[4];
+ break;
+
+ default:
+ return;
+ }
+
+ EXEC(if_bluetooth->set_remote_device_property, &addr, &property);
+}
+
+static void get_remote_service_record_p(int argc, const char **argv)
+{
+ bt_bdaddr_t addr;
+ bt_uuid_t uuid;
+
+ RETURN_IF_NULL(if_bluetooth);
+
+ str2bt_bdaddr_t(argv[2], &addr);
+ str2bt_uuid_t(argv[3], &uuid);
+
+ EXEC(if_bluetooth->get_remote_service_record, &addr, &uuid);
+}
+
+static void get_remote_services_p(int argc, const char **argv)
+{
+ bt_bdaddr_t addr;
+
+ RETURN_IF_NULL(if_bluetooth);
+
+ str2bt_bdaddr_t(argv[2], &addr);
+
+ EXEC(if_bluetooth->get_remote_services, &addr);
+}
+
+static void start_discovery_p(int argc, const char **argv)
+{
+ RETURN_IF_NULL(if_bluetooth);
+
+ EXEC(if_bluetooth->start_discovery);
+}
+
+static void cancel_discovery_p(int argc, const char **argv)
+{
+ RETURN_IF_NULL(if_bluetooth);
+
+ EXEC(if_bluetooth->cancel_discovery);
+}
+
+static void create_bond_p(int argc, const char **argv)
+{
+ bt_bdaddr_t addr;
+
+ RETURN_IF_NULL(if_bluetooth);
+
+ str2bt_bdaddr_t(argv[2], &addr);
+
+ EXEC(if_bluetooth->create_bond, &addr);
+}
+
+static void remove_bond_p(int argc, const char **argv)
+{
+ bt_bdaddr_t addr;
+
+ RETURN_IF_NULL(if_bluetooth);
+
+ str2bt_bdaddr_t(argv[2], &addr);
+
+ EXEC(if_bluetooth->remove_bond, &addr);
+}
+
+static void cancel_bond_p(int argc, const char **argv)
+{
+ bt_bdaddr_t addr;
+
+ RETURN_IF_NULL(if_bluetooth);
+
+ str2bt_bdaddr_t(argv[2], &addr);
+
+ EXEC(if_bluetooth->cancel_bond, &addr);
+}
+
+static void pin_reply_p(int argc, const char **argv)
+{
+ bt_bdaddr_t addr;
+ bt_pin_code_t pin;
+ int pin_len = 0;
+ int accept;
+
+ RETURN_IF_NULL(if_bluetooth);
+
+ if (argc < 3) {
+ haltest_error("No address specified\n");
+ return;
+ }
+ str2bt_bdaddr_t(argv[2], &addr);
+
+ if (argc >= 4) {
+ accept = 1;
+ pin_len = strlen(argv[3]);
+ memcpy(pin.pin, argv[3], pin_len);
+ }
+
+ EXEC(if_bluetooth->pin_reply, &addr, accept, pin_len, &pin);
+}
+
+static void ssp_reply_p(int argc, const char **argv)
+{
+ bt_bdaddr_t addr;
+ bt_ssp_variant_t var;
+ int accept;
+ int passkey;
+
+ RETURN_IF_NULL(if_bluetooth);
+
+ if (argc < 3) {
+ haltest_error("No address specified\n");
+ return;
+ }
+ str2bt_bdaddr_t(argv[2], &addr);
+ if (argc < 4) {
+ haltest_error("No ssp variant specified\n");
+ return;
+ }
+ var = str2btsspvariant(argv[3]);
+ if (argc < 5) {
+ haltest_error("No accept value specified\n");
+ return;
+ }
+ accept = atoi(argv[4]);
+ passkey = 0;
+
+ if (accept && var == BT_SSP_VARIANT_PASSKEY_ENTRY && argc >= 5)
+ passkey = atoi(argv[4]);
+
+ EXEC(if_bluetooth->ssp_reply, &addr, var, accept, passkey);
+}
+
+static void get_profile_interface_p(int argc, const char **argv)
+{
+ const char *id = argv[2];
+ const void **pif = NULL;
+ const void *dummy = NULL;
+
+ RETURN_IF_NULL(if_bluetooth);
+
+ if (strcmp(BT_PROFILE_HANDSFREE_ID, id) == 0)
+ pif = &dummy; /* TODO: chenge when if_hf is there */
+ else if (strcmp(BT_PROFILE_ADVANCED_AUDIO_ID, id) == 0)
+ pif = &dummy; /* TODO: chenge when if_av is there */
+ else if (strcmp(BT_PROFILE_HEALTH_ID, id) == 0)
+ pif = &dummy; /* TODO: chenge when if_hl is there */
+ else if (strcmp(BT_PROFILE_SOCKETS_ID, id) == 0)
+ pif = &dummy; /* TODO: chenge when if_sock is there */
+ else if (strcmp(BT_PROFILE_HIDHOST_ID, id) == 0)
+ pif = &dummy; /* TODO: chenge when if_hh is there */
+ else if (strcmp(BT_PROFILE_PAN_ID, id) == 0)
+ pif = &dummy; /* TODO: chenge when if_pan is there */
+ else if (strcmp(BT_PROFILE_AV_RC_ID, id) == 0)
+ pif = &dummy; /* TODO: chenge when if_rc is there */
+ else
+ haltest_error("%s is not correct for get_profile_interface\n",
+ id);
+
+ if (pif != NULL) {
+ *pif = if_bluetooth->get_profile_interface(id);
+ haltest_info("get_profile_interface(%s) : %p\n", id, *pif);
+ }
+}
+
+static void dut_mode_configure_p(int argc, const char **argv)
+{
+ uint8_t mode;
+
+ RETURN_IF_NULL(if_bluetooth);
+
+ mode = strtol(argv[2], NULL, 0);
+
+ EXEC(if_bluetooth->dut_mode_configure, mode);
+}
+
+static struct method methods[] = {
+ STD_METHOD(init),
+ STD_METHOD(cleanup),
+ STD_METHOD(enable),
+ STD_METHOD(disable),
+ STD_METHOD(get_adapter_properties),
+ STD_METHOD(get_adapter_property),
+ STD_METHOD(set_adapter_property),
+ STD_METHOD(get_remote_device_properties),
+ STD_METHOD(get_remote_device_property),
+ STD_METHOD(set_remote_device_property),
+ STD_METHOD(get_remote_service_record),
+ STD_METHOD(get_remote_services),
+ STD_METHOD(start_discovery),
+ STD_METHOD(cancel_discovery),
+ STD_METHOD(create_bond),
+ STD_METHOD(remove_bond),
+ STD_METHOD(cancel_bond),
+ STD_METHOD(pin_reply),
+ STD_METHOD(ssp_reply),
+ STD_METHOD(get_profile_interface),
+ STD_METHOD(dut_mode_configure),
+ END_METHOD
+};
+
+const struct interface bluetooth_if = {
+ .name = "adapter",
+ .methods = methods
+};
diff --git a/android/client/if-main.h b/android/client/if-main.h
new file mode 100644
index 0000000..9cac7ef
--- /dev/null
+++ b/android/client/if-main.h
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/un.h>
+#include <poll.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_av.h>
+#include <hardware/bt_hh.h>
+#include <hardware/bt_pan.h>
+#include <hardware/bt_sock.h>
+#include <hardware/bt_hf.h>
+#include <hardware/bt_hl.h>
+#include <hardware/bt_rc.h>
+
+#include "textconv.h"
+
+/* Interfaces from hal that can be populated during application lifetime */
+extern const bt_interface_t *if_bluetooth;
+
+/*
+ * Structure defines top level interfaces that can be used in test tool
+ * this will contain values as: adapter, av, gatt, sock, pan...
+ */
+struct interface {
+ const char *name; /* interface name */
+ struct method *methods; /* methods available for this interface */
+};
+
+extern const struct interface bluetooth_if;
+
+/* Interfaces that will show up in tool (first part of command line) */
+extern const struct interface *interfaces[];
+
+#define METHOD(name, func) {name, func}
+#define STD_METHOD(m) {#m, m##_p}
+#define END_METHOD {"", NULL}
+
+/*
+ * Function to parse argument for function, argv[0] and argv[1] are already
+ * parsed before this function is called and contain interface and method name
+ * up to argc - 1 arguments are finished and should be used to decide which
+ * function enumeration function to return
+ */
+typedef void (*parse_and_call)(int argc, const char **argv);
+
+/*
+ * For each method there is name and two functions to parse command line
+ * and call proper hal function on.
+ */
+struct method {
+ const char *name;
+ parse_and_call func;
+};
+
+int haltest_error(const char *format, ...);
+int haltest_info(const char *format, ...);
+int haltest_warn(const char *format, ...);
+
+/* Helper macro for executing function on interface and printing BT_STATUS */
+#define EXEC(f, ...) \
+ { \
+ int err = f(__VA_ARGS__); \
+ haltest_info("%s: %s\n", #f, bt_status_t2str(err)); \
+ }
+
+/* Helper macro for executing void function on interface */
+#define EXECV(f, ...) \
+ { \
+ (void) f(__VA_ARGS__); \
+ haltest_info("%s: void\n", #f); \
+ }
+
+#define RETURN_IF_NULL(x) \
+ do { if (!x) { haltest_error("%s is NULL\n", #x); return; } } while (0)