| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- // SPDX-License-Identifier: Apache-2.0
- /*
- * Copyright (C) 2013 Intel Corporation
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #define _GNU_SOURCE
- #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 <getopt.h>
- #include "if-main.h"
- #include "terminal.h"
- #include "pollhandler.h"
- #include "history.h"
- static void process_line(char *line_buffer);
- const struct interface *interfaces[] = {
- &audio_if,
- &sco_if,
- &bluetooth_if,
- &av_if,
- &rc_if,
- &gatt_if,
- &gatt_client_if,
- &gatt_server_if,
- &hf_if,
- &hh_if,
- &pan_if,
- &hl_if,
- &sock_if,
- #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
- &hf_client_if,
- &mce_if,
- &ctrl_rc_if,
- &av_sink_if,
- #endif
- NULL
- };
- static struct method commands[];
- struct method *get_method(struct method *methods, const char *name)
- {
- while (strcmp(methods->name, "") != 0) {
- if (strcmp(methods->name, name) == 0)
- return methods;
- methods++;
- }
- return NULL;
- }
- /* function returns interface of given name or NULL if not found */
- const struct interface *get_interface(const char *name)
- {
- int i;
- for (i = 0; interfaces[i] != NULL; ++i) {
- if (strcmp(interfaces[i]->name, name) == 0)
- break;
- }
- return interfaces[i];
- }
- 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;
- }
- static void help_print_interface(const struct interface *i)
- {
- struct method *m;
- for (m = i->methods; strcmp(m->name, "") != 0; m++)
- haltest_info("%s %s %s\n", i->name, m->name,
- (m->help ? m->help : ""));
- }
- /* Help completion */
- static void help_c(int argc, const char **argv, enum_func *enum_func,
- void **user)
- {
- if (argc == 2)
- *enum_func = interface_name;
- }
- /* Help execution */
- static void help_p(int argc, const char **argv)
- {
- const struct method *m = commands;
- const struct interface **ip = interfaces;
- const struct interface *i;
- if (argc == 1) {
- terminal_print("haltest allows to call Android HAL methods.\n");
- terminal_print("\nAvailable commands:\n");
- while (0 != strcmp(m->name, "")) {
- terminal_print("\t%s %s\n", m->name,
- (m->help ? m->help : ""));
- m++;
- }
- terminal_print("\nAvailable interfaces to use:\n");
- while (NULL != *ip) {
- terminal_print("\t%s\n", (*ip)->name);
- ip++;
- }
- terminal_print("\nTo get help on methods for each interface type:\n");
- terminal_print("\n\thelp <inerface>\n");
- terminal_print("\nBasic scenario:\n\tbluetooth init\n");
- terminal_print("\tbluetooth enable\n\tbluetooth start_discovery\n");
- terminal_print("\tbluetooth get_profile_interface handsfree\n");
- terminal_print("\thandsfree init\n\n");
- return;
- }
- i = get_interface(argv[1]);
- if (i == NULL) {
- haltest_error("No such interface\n");
- return;
- }
- help_print_interface(i);
- }
- /* quit/exit execution */
- static void quit_p(int argc, const char **argv)
- {
- char cleanup_audio[] = "audio cleanup";
- close_hw_bt_dev();
- process_line(cleanup_audio);
- exit(0);
- }
- static int fd_stack[10];
- static int fd_stack_pointer = 0;
- static void stdin_handler(struct pollfd *pollfd);
- static void process_file(const char *name)
- {
- int fd = open(name, O_RDONLY);
- if (fd < 0) {
- haltest_error("Can't open file: %s for reading\n", name);
- return;
- }
- if (fd_stack_pointer >= 10) {
- haltest_error("To many open files\n");
- close(fd);
- return;
- }
- fd_stack[fd_stack_pointer++] = fd;
- poll_unregister_fd(fd_stack[fd_stack_pointer - 2], stdin_handler);
- poll_register_fd(fd_stack[fd_stack_pointer - 1], POLLIN, stdin_handler);
- }
- static void source_p(int argc, const char **argv)
- {
- if (argc < 2) {
- haltest_error("No file specified");
- return;
- }
- process_file(argv[1]);
- }
- /* Commands available without interface */
- static struct method commands[] = {
- STD_METHODCH(help, "[<interface>]"),
- STD_METHOD(quit),
- METHOD("exit", quit_p, NULL, NULL),
- STD_METHODH(source, "<file>"),
- END_METHOD
- };
- /* Gets comman by name */
- struct method *get_command(const char *name)
- {
- return get_method(commands, name);
- }
- /* Function to enumerate interface names */
- const char *interface_name(void *v, int i)
- {
- return interfaces[i] ? interfaces[i]->name : NULL;
- }
- /* Function to enumerate command and interface names */
- const char *command_name(void *v, int i)
- {
- int cmd_cnt = NELEM(commands);
- if (i >= cmd_cnt)
- return interface_name(v, i - cmd_cnt);
- else
- return commands[i].name;
- }
- /*
- * This function changes input parameter line_buffer so it has
- * null termination after each token (due to strtok)
- * Output argv is filled with pointers to arguments
- * returns number of tokens parsed - argc
- */
- static int command_line_to_argv(char *line_buffer, char *argv[], int argv_size)
- {
- static const char *token_breaks = "\r\n\t ";
- char *token;
- int argc = 0;
- token = strtok(line_buffer, token_breaks);
- while (token != NULL && argc < (int) argv_size) {
- argv[argc++] = token;
- token = strtok(NULL, token_breaks);
- }
- return argc;
- }
- static void process_line(char *line_buffer)
- {
- char *argv[50];
- int argc;
- int i = 0;
- struct method *m;
- argc = command_line_to_argv(line_buffer, argv, 50);
- if (argc < 1)
- return;
- while (interfaces[i] != NULL) {
- if (strcmp(interfaces[i]->name, argv[0])) {
- i++;
- continue;
- }
- if (argc < 2 || strcmp(argv[1], "?") == 0) {
- help_print_interface(interfaces[i]);
- return;
- }
- m = get_method(interfaces[i]->methods, argv[1]);
- if (m != NULL) {
- m->func(argc, (const char **) argv);
- return;
- }
- haltest_error("No function %s found\n", argv[1]);
- return;
- }
- /* No interface, try commands */
- m = get_command(argv[0]);
- if (m == NULL)
- haltest_error("No such command %s\n", argv[0]);
- else
- m->func(argc, (const char **) argv);
- }
- /* called when there is something on stdin */
- static void stdin_handler(struct pollfd *pollfd)
- {
- char buf[10];
- if (pollfd->revents & POLLIN) {
- int count = read(fd_stack[fd_stack_pointer - 1], buf, 10);
- if (count > 0) {
- int i;
- for (i = 0; i < count; ++i)
- terminal_process_char(buf[i], process_line);
- return;
- }
- }
- if (fd_stack_pointer > 1)
- poll_register_fd(fd_stack[fd_stack_pointer - 2], POLLIN,
- stdin_handler);
- if (fd_stack_pointer > 0) {
- poll_unregister_fd(fd_stack[--fd_stack_pointer], stdin_handler);
- if (fd_stack[fd_stack_pointer])
- close(fd_stack[fd_stack_pointer]);
- }
- }
- static void usage(void)
- {
- printf("haltest Android Bluetooth HAL testing tool\n"
- "Usage:\n");
- printf("\thaltest [options]\n");
- printf("options:\n"
- "\t-i --ivi Initialize only IVI interfaces\n"
- "\t-n, --no-init Don't initialize any interfaces\n"
- "\t-v --version Print version\n"
- "\t-h, --help Show help options\n");
- }
- static void print_version(void)
- {
- printf("haltest version %s\n", VERSION);
- }
- static const struct option main_options[] = {
- { "no-init", no_argument, NULL, 'n' },
- { "ivi", no_argument, NULL, 'i' },
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'v' },
- { NULL }
- };
- static bool no_init = false;
- static bool ivi_only = false;
- static void parse_command_line(int argc, char *argv[])
- {
- for (;;) {
- int opt;
- opt = getopt_long(argc, argv, "inhv", main_options, NULL);
- if (opt < 0)
- break;
- switch (opt) {
- case 'n':
- no_init = true;
- break;
- case 'i':
- ivi_only = true;
- break;
- case 'h':
- usage();
- exit(0);
- case 'v':
- print_version();
- exit(0);
- default:
- putchar('\n');
- exit(-1);
- break;
- }
- }
- }
- static const char * const interface_names[] = {
- BT_PROFILE_HANDSFREE_ID,
- BT_PROFILE_ADVANCED_AUDIO_ID,
- BT_PROFILE_AV_RC_ID,
- BT_PROFILE_HEALTH_ID,
- BT_PROFILE_HIDHOST_ID,
- BT_PROFILE_PAN_ID,
- BT_PROFILE_GATT_ID,
- BT_PROFILE_SOCKETS_ID,
- NULL
- };
- static const char * const ivi_interface_inames[] = {
- #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
- BT_PROFILE_HANDSFREE_CLIENT_ID,
- BT_PROFILE_MAP_CLIENT_ID,
- BT_PROFILE_AV_RC_CTRL_ID,
- BT_PROFILE_ADVANCED_AUDIO_SINK_ID,
- #endif
- NULL
- };
- static void init(const char * const *inames)
- {
- const struct method *m;
- const char *argv[4];
- char init_audio[] = "audio init";
- char init_sco[] = "sco init";
- char init_bt[] = "bluetooth init";
- uint32_t i;
- process_line(init_audio);
- process_line(init_sco);
- process_line(init_bt);
- m = get_interface_method("bluetooth", "get_profile_interface");
- while (*inames) {
- argv[2] = *inames;
- m->func(3, argv);
- inames++;
- }
- /* Init what is available to init */
- for (i = 3; i < NELEM(interfaces) - 1; ++i) {
- m = get_interface_method(interfaces[i]->name, "init");
- if (m != NULL)
- m->func(2, argv);
- }
- }
- int main(int argc, char **argv)
- {
- struct stat rcstat;
- parse_command_line(argc, argv);
- terminal_setup();
- if (!no_init) {
- if (ivi_only)
- init(ivi_interface_inames);
- else
- init(interface_names);
- }
- history_restore(".haltest_history");
- fd_stack[fd_stack_pointer++] = 0;
- /* Register command line handler */
- poll_register_fd(0, POLLIN, stdin_handler);
- if (stat(".haltestrc", &rcstat) == 0 && (rcstat.st_mode & S_IFREG) != 0)
- process_file(".haltestrc");
- poll_dispatch_loop();
- return 0;
- }
|