blob: c312d85db06b23cc6ad70b2a61ddac8fb8ed3370 [file] [log] [blame]
/*
*
* 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;
}