| /* |
| * |
| * BlueZ - Bluetooth protocol stack for Linux |
| * |
| * Copyright (C) 2018 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. |
| * |
| * |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include <config.h> |
| #endif |
| |
| #include <ctype.h> |
| #include <stdio.h> |
| #include <unistd.h> |
| |
| #include <ell/ell.h> |
| |
| #include "src/shared/shell.h" |
| #include "src/shared/mainloop.h" |
| |
| #include "mesh/mesh.h" |
| #include "mesh/net.h" |
| |
| #define PROMPT COLOR_BLUE "[btmesh]" COLOR_OFF "# " |
| |
| static struct bt_mesh *mesh; |
| |
| static const struct option main_options[] = { |
| { "index", 1, 0, 'i' }, |
| { "config", 1, 0, 'c' }, |
| { "save", 1, 0, 's' }, |
| { 0, 0, 0, 0 } |
| }; |
| |
| static const char *index_option; |
| static const char *config_option; |
| static const char *save_option; |
| |
| static const char **optargs[] = { |
| &index_option, |
| &config_option, |
| &save_option, |
| }; |
| |
| static const char *help[] = { |
| "Specify adapter index", |
| "Specify input configuration file", |
| "Specify output configuration file" |
| }; |
| |
| static const struct bt_shell_opt opt = { |
| .options = main_options, |
| .optno = sizeof(main_options) / sizeof(struct option), |
| .optstr = "i:c:s:", |
| .optarg = optargs, |
| .help = help, |
| }; |
| |
| static int get_arg_on_off(int argc, char *argv[]) |
| { |
| if (!strcmp(argv[1], "on") || !strcmp(argv[1], "yes")) |
| return 1; |
| |
| if (!strcmp(argv[1], "off") || !strcmp(argv[1], "no")) |
| return 0; |
| |
| bt_shell_printf("Invalid argument %s\n", argv[1]); |
| return -1; |
| } |
| |
| static void cmd_beacon(int argc, char *argv[]) |
| { |
| bool res; |
| int enable; |
| |
| enable = get_arg_on_off(argc, argv); |
| if (enable < 0) |
| return; |
| |
| res = mesh_net_set_beacon_mode(mesh_get_net(mesh), enable); |
| if (res) |
| bt_shell_printf("Local beacon mode is %s\n", |
| enable > 0 ? "enabled" : "disabled"); |
| else |
| bt_shell_printf("Failed to set local beacon mode to %s\n", |
| enable > 0 ? "enabled" : "disabled"); |
| } |
| |
| static const struct bt_shell_menu main_menu = { |
| .name = "main", |
| .entries = { |
| { "beacon", "<enable>", cmd_beacon, "Enable/disable beaconing"}, |
| { } }, |
| }; |
| |
| static int get_index(const char *arg) |
| { |
| if (strlen(arg) > 3 && !strncasecmp(arg, "hci", 3)) |
| return atoi(&arg[3]); |
| else |
| return atoi(arg); |
| } |
| |
| static void ell_event(int fd, uint32_t events, void *user_data) |
| { |
| int timeout = l_main_prepare(); |
| |
| l_main_iterate(timeout); |
| } |
| |
| int main(int argc, char *argv[]) |
| { |
| int index; |
| int fd; |
| int status; |
| |
| l_log_set_stderr(); |
| l_debug_enable("*"); |
| |
| if (!l_main_init()) |
| return -1; |
| |
| bt_shell_init(argc, argv, &opt); |
| bt_shell_set_menu(&main_menu); |
| |
| if (!index_option) { |
| bt_shell_usage(); |
| return 0; |
| } |
| |
| if (config_option) |
| l_info("Reading local configuration from %s\n", config_option); |
| |
| if (save_option) |
| l_info("Saving local configuration to %s\n", save_option); |
| |
| bt_shell_set_prompt(PROMPT); |
| |
| index = get_index(index_option); |
| |
| l_info("Starting mesh on hci%d\n", index); |
| |
| mesh = mesh_create(index); |
| if (!mesh || !mesh_load_config(mesh, config_option)) { |
| l_info("Failed to create mesh\n"); |
| bt_shell_cleanup(); |
| return EXIT_FAILURE; |
| } |
| |
| if (save_option) |
| mesh_set_output(mesh, save_option); |
| |
| fd = l_main_get_epoll_fd(); |
| mainloop_add_fd(fd, EPOLLIN, ell_event, NULL, NULL); |
| |
| status = bt_shell_attach(fileno(stdin)); |
| bt_shell_run(); |
| |
| mesh_unref(mesh); |
| l_main_exit(); |
| |
| return status; |
| } |