| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328 |
- // SPDX-License-Identifier: LGPL-2.1-or-later
- /*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2019 Intel Corporation. All rights reserved.
- *
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #define _GNU_SOURCE
- #include <assert.h>
- #include <ctype.h>
- #include <dbus/dbus.h>
- #include <errno.h>
- #include <libgen.h>
- #include <stdio.h>
- #include <time.h>
- #include <sys/stat.h>
- #include <ell/ell.h>
- #include "src/shared/shell.h"
- #include "src/shared/util.h"
- #include "mesh/mesh.h"
- #include "mesh/mesh-defs.h"
- #include "tools/mesh/agent.h"
- #include "tools/mesh/cfgcli.h"
- #include "tools/mesh/keys.h"
- #include "tools/mesh/mesh-db.h"
- #include "tools/mesh/model.h"
- #include "tools/mesh/remote.h"
- #define PROMPT_ON COLOR_BLUE "[mesh-cfgclient]" COLOR_OFF "# "
- #define PROMPT_OFF "Waiting to connect to bluetooth-meshd..."
- #define CFG_SRV_MODEL 0x0000
- #define CFG_CLI_MODEL 0x0001
- #define UNPROV_SCAN_MAX_SECS 300
- #define DEFAULT_START_ADDRESS 0x00aa
- #define DEFAULT_MAX_ADDRESS (VIRTUAL_ADDRESS_LOW - 1)
- #define DEFAULT_NET_INDEX 0x0000
- #define MAX_CRPL_SIZE 0x7fff
- #define DEFAULT_CFG_FILE "config_db.json"
- #define DEFAULT_EXPORT_FILE "export_db.json"
- struct meshcfg_el {
- const char *path;
- uint8_t index;
- uint16_t mods[2];
- };
- struct meshcfg_app {
- const char *path;
- const char *agent_path;
- struct meshcfg_el ele;
- uint16_t cid;
- uint16_t pid;
- uint16_t vid;
- uint16_t crpl;
- uint8_t uuid[16];
- };
- struct meshcfg_node {
- const char *path;
- struct l_dbus_proxy *proxy;
- struct l_dbus_proxy *mgmt_proxy;
- union {
- uint64_t u64;
- uint8_t u8[8];
- } token;
- };
- struct unprov_device {
- time_t last_seen;
- int16_t rssi;
- uint8_t uuid[16];
- };
- struct generic_request {
- uint32_t arg1;
- uint32_t arg2;
- uint32_t arg3;
- uint8_t *data1;
- uint8_t *data2;
- const char *str;
- };
- static struct l_dbus *dbus;
- static struct l_queue *node_proxies;
- static struct l_dbus_proxy *net_proxy;
- static struct meshcfg_node *local;
- static struct model_info *cfgcli;
- static struct l_queue *devices;
- static bool prov_in_progress;
- static const char * const caps[] = {"static-oob",
- "push",
- "twist",
- "blink",
- "beep",
- "vibrate",
- "public-oob",
- "out-alpha",
- "in-alpha",
- "out-numeric",
- "in-numeric"};
- static bool have_config;
- static struct meshcfg_app app = {
- .path = "/mesh/cfgclient",
- .agent_path = "/mesh/cfgclient/agent",
- .cid = 0x05f1,
- .pid = 0x0002,
- .vid = 0x0001,
- .crpl = MAX_CRPL_SIZE,
- .ele = {
- .path = "/mesh/cfgclient/ele0",
- .index = 0,
- .mods = {CFG_SRV_MODEL, CFG_CLI_MODEL}
- }
- };
- static const struct option options[] = {
- { "config", required_argument, 0, 'c' },
- { "address-start", required_argument, 0, 'a' },
- { "address-range", required_argument, 0, 'r' },
- { "net-index", required_argument, 0, 'n' },
- { 0, 0, 0, 0 }
- };
- static const char *address_opt;
- static const char *range_opt;
- static const char *net_idx_opt;
- static const char *config_opt;
- static uint32_t iv_index;
- static uint16_t low_addr;
- static uint16_t high_addr;
- static uint16_t prov_net_idx;
- static const char *cfg_fname;
- static const char **optargs[] = {
- &config_opt,
- &address_opt,
- &range_opt,
- &net_idx_opt,
- };
- static const char *help[] = {
- "Configuration file",
- "Starting unicast address for remote nodes",
- "Net index for provisioning subnet"
- };
- static const struct bt_shell_opt opt = {
- .options = options,
- .optno = sizeof(options) / sizeof(struct option),
- .optstr = "c:a:n:",
- .optarg = optargs,
- .help = help,
- };
- static const char *dbus_err_args = "org.freedesktop.DBus.Error.InvalidArgs";
- static const char *dbus_err_fail = "org.freedesktop.DBus.Error.Failed";
- static const char *dbus_err_support = "org.freedesktop.DBus.Error.NotSupported";
- static bool parse_argument_on_off(int argc, char *argv[], bool *value)
- {
- if (!strcmp(argv[1], "on") || !strcmp(argv[1], "yes")) {
- *value = TRUE;
- return TRUE;
- }
- if (!strcmp(argv[1], "off") || !strcmp(argv[1], "no")) {
- *value = FALSE;
- return TRUE;
- }
- bt_shell_printf("Invalid argument %s\n", argv[1]);
- return FALSE;
- }
- static bool match_device_uuid(const void *a, const void *b)
- {
- const struct unprov_device *dev = a;
- const uint8_t *uuid = b;
- return (memcmp(dev->uuid, uuid, 16) == 0);
- }
- static void print_device(void *a, void *b)
- {
- const struct unprov_device *dev = a;
- struct tm *tm = localtime(&dev->last_seen);
- char buf[80];
- char *str;
- assert(strftime(buf, sizeof(buf), "%c", tm));
- str = l_util_hexstring_upper(dev->uuid, sizeof(dev->uuid));
- bt_shell_printf("UUID: %s, RSSI %d, Seen: %s\n",
- str, dev->rssi, buf);
- l_free(str);
- }
- struct send_data {
- const char *ele_path;
- bool rmt;
- bool is_dev_key;
- uint16_t dst;
- uint16_t idx;
- uint8_t *data;
- uint16_t len;
- };
- struct key_data {
- const char *ele_path;
- uint16_t dst;
- uint16_t idx;
- uint16_t net_idx;
- bool update;
- };
- static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
- const char *key, const char *signature,
- const void *data)
- {
- if (!builder)
- return;
- l_dbus_message_builder_enter_dict(builder, "sv");
- l_dbus_message_builder_append_basic(builder, 's', key);
- l_dbus_message_builder_enter_variant(builder, signature);
- l_dbus_message_builder_append_basic(builder, signature[0], data);
- l_dbus_message_builder_leave_variant(builder);
- l_dbus_message_builder_leave_dict(builder);
- }
- static void append_byte_array(struct l_dbus_message_builder *builder,
- unsigned char *data, unsigned int len)
- {
- unsigned int i;
- l_dbus_message_builder_enter_array(builder, "y");
- for (i = 0; i < len; i++)
- l_dbus_message_builder_append_basic(builder, 'y', &(data[i]));
- l_dbus_message_builder_leave_array(builder);
- }
- static void send_msg_setup(struct l_dbus_message *msg, void *user_data)
- {
- struct send_data *req = user_data;
- struct l_dbus_message_builder *builder;
- builder = l_dbus_message_builder_new(msg);
- l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
- l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
- if (req->is_dev_key)
- l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
- l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
- /* Options */
- l_dbus_message_builder_enter_array(builder, "{sv}");
- l_dbus_message_builder_enter_dict(builder, "sv");
- l_dbus_message_builder_leave_dict(builder);
- l_dbus_message_builder_leave_array(builder);
- /* Data */
- append_byte_array(builder, req->data, req->len);
- l_dbus_message_builder_finalize(builder);
- l_dbus_message_builder_destroy(builder);
- }
- static bool send_msg(void *user_data, uint16_t dst, uint16_t idx,
- uint8_t *data, uint16_t len)
- {
- struct send_data *req;
- uint16_t net_idx_tx = idx;
- bool is_dev_key;
- const char *method_name;
- is_dev_key = (idx == APP_IDX_DEV_REMOTE || idx == APP_IDX_DEV_LOCAL);
- method_name = is_dev_key ? "DevKeySend" : "Send";
- if (is_dev_key) {
- net_idx_tx = remote_get_subnet_idx(dst);
- if (net_idx_tx == NET_IDX_INVALID)
- return false;
- }
- req = l_new(struct send_data, 1);
- req->ele_path = user_data;
- req->dst = dst;
- req->idx = net_idx_tx;
- req->data = data;
- req->len = len;
- req->rmt = (idx == APP_IDX_DEV_REMOTE);
- req->is_dev_key = is_dev_key;
- return l_dbus_proxy_method_call(local->proxy, method_name,
- send_msg_setup, NULL, req, l_free) != 0;
- }
- static void send_key_setup(struct l_dbus_message *msg, void *user_data)
- {
- struct key_data *req = user_data;
- struct l_dbus_message_builder *builder;
- builder = l_dbus_message_builder_new(msg);
- l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
- l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
- l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
- l_dbus_message_builder_append_basic(builder, 'q', &req->net_idx);
- l_dbus_message_builder_append_basic(builder, 'b', &req->update);
- l_dbus_message_builder_finalize(builder);
- l_dbus_message_builder_destroy(builder);
- }
- static bool send_key(void *user_data, uint16_t dst, uint16_t key_idx,
- bool is_appkey, bool update)
- {
- struct key_data *req;
- uint16_t net_idx;
- const char *method_name = (!is_appkey) ? "AddNetKey" : "AddAppKey";
- net_idx = remote_get_subnet_idx(dst);
- if (net_idx == NET_IDX_INVALID) {
- bt_shell_printf("Node %4.4x not found\n", dst);
- return false;
- }
- if (!is_appkey && !keys_subnet_exists(key_idx)) {
- bt_shell_printf("Local NetKey %u (0x%3.3x) not found\n",
- key_idx, key_idx);
- return false;
- }
- if (is_appkey && (keys_get_bound_key(key_idx) == NET_IDX_INVALID)) {
- bt_shell_printf("Local AppKey %u (0x%3.3x) not found\n",
- key_idx, key_idx);
- return false;
- }
- req = l_new(struct key_data, 1);
- req->ele_path = user_data;
- req->dst = dst;
- req->idx = key_idx;
- req->net_idx = net_idx;
- req->update = update;
- return l_dbus_proxy_method_call(local->proxy, method_name,
- send_key_setup, NULL, req, l_free) != 0;
- }
- static void delete_node_setup(struct l_dbus_message *msg, void *user_data)
- {
- struct generic_request *req = user_data;
- uint16_t primary;
- uint8_t ele_cnt;
- primary = (uint16_t) req->arg1;
- ele_cnt = (uint8_t) req->arg2;
- l_dbus_message_set_arguments(msg, "qy", primary, ele_cnt);
- }
- static void delete_node(uint16_t primary, uint8_t ele_cnt)
- {
- struct generic_request *req;
- if (!local || !local->proxy || !local->mgmt_proxy) {
- bt_shell_printf("Node is not attached\n");
- return;
- }
- req = l_new(struct generic_request, 1);
- req->arg1 = primary;
- req->arg2 = ele_cnt;
- l_dbus_proxy_method_call(local->mgmt_proxy, "DeleteRemoteNode",
- delete_node_setup, NULL, req, l_free);
- }
- static void client_init(void)
- {
- cfgcli = cfgcli_init(send_key, delete_node, (void *) app.ele.path);
- cfgcli->ops.set_send_func(send_msg, (void *) app.ele.path);
- }
- static bool caps_getter(struct l_dbus *dbus,
- struct l_dbus_message *message,
- struct l_dbus_message_builder *builder,
- void *user_data)
- {
- uint32_t i;
- if (!l_dbus_message_builder_enter_array(builder, "s"))
- return false;
- for (i = 0; i < L_ARRAY_SIZE(caps); i++)
- l_dbus_message_builder_append_basic(builder, 's', caps[i]);
- l_dbus_message_builder_leave_array(builder);
- return true;
- }
- static void agent_input_done(oob_type_t type, void *buf, uint16_t len,
- void *user_data)
- {
- struct l_dbus_message *msg = user_data;
- struct l_dbus_message *reply = NULL;
- struct l_dbus_message_builder *builder;
- uint32_t val_u32;
- uint8_t oob_data[64];
- switch (type) {
- case NONE:
- case OUTPUT:
- default:
- break;
- case ASCII:
- if (len > 8) {
- bt_shell_printf("Bad input length\n");
- break;
- }
- /* Fall Through */
- case HEXADECIMAL:
- if (len > sizeof(oob_data)) {
- bt_shell_printf("Bad input length\n");
- break;
- }
- memset(oob_data, 0, sizeof(oob_data));
- memcpy(oob_data, buf, len);
- reply = l_dbus_message_new_method_return(msg);
- builder = l_dbus_message_builder_new(reply);
- append_byte_array(builder, oob_data, len);
- l_dbus_message_builder_finalize(builder);
- l_dbus_message_builder_destroy(builder);
- break;
- case DECIMAL:
- if (len > 8) {
- bt_shell_printf("Bad input length\n");
- break;
- }
- val_u32 = l_get_be32(buf);
- reply = l_dbus_message_new_method_return(msg);
- l_dbus_message_set_arguments(reply, "u", val_u32);
- break;
- }
- if (!reply)
- reply = l_dbus_message_new_error(msg, dbus_err_fail, NULL);
- l_dbus_send(dbus, reply);
- }
- struct requested_action {
- const char *action;
- const char *description;
- };
- static struct requested_action display_numeric_table[] = {
- { "push", "Push remote button %d times"},
- { "twist", "Twist remote nob %d times"},
- { "in-numeric", "Enter %d on remote device"},
- { "out-numeric", "Enter %d on remote device"}
- };
- static struct requested_action prompt_numeric_table[] = {
- { "blink", "Enter the number of times remote LED blinked"},
- { "beep", "Enter the number of times remote device beeped"},
- { "vibrate", "Enter the number of times remote device vibrated"},
- { "in-numeric", "Enter the number displayed on remote device"},
- { "out-numeric", "Enter the number displayed on remote device"}
- };
- static int get_action(char *str, bool prompt)
- {
- struct requested_action *action_table;
- size_t len;
- int i, sz;
- if (!str)
- return -1;
- if (prompt) {
- len = strlen(str);
- sz = L_ARRAY_SIZE(prompt_numeric_table);
- action_table = prompt_numeric_table;
- } else {
- len = strlen(str);
- sz = L_ARRAY_SIZE(display_numeric_table);
- action_table = display_numeric_table;
- }
- for (i = 0; i < sz; ++i)
- if (len == strlen(action_table[i].action) &&
- !strcmp(str, action_table[i].action))
- return i;
- return -1;
- }
- static struct l_dbus_message *disp_numeric_call(struct l_dbus *dbus,
- struct l_dbus_message *msg,
- void *user_data)
- {
- char *str;
- uint32_t n;
- int action_index;
- if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
- l_error("Cannot parse \"DisplayNumeric\" arguments");
- return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
- }
- action_index = get_action(str, false);
- if (action_index < 0)
- return l_dbus_message_new_error(msg, dbus_err_support, NULL);
- str = l_strdup_printf(display_numeric_table[action_index].description,
- n);
- bt_shell_printf(COLOR_YELLOW "%s\n" COLOR_OFF, str);
- l_free(str);
- return l_dbus_message_new_method_return(msg);
- }
- static struct l_dbus_message *disp_string_call(struct l_dbus *dbus,
- struct l_dbus_message *msg,
- void *user_data)
- {
- const char *prompt = "Enter AlphaNumeric code on remote device:";
- char *str;
- if (!l_dbus_message_get_arguments(msg, "s", &str)) {
- l_error("Cannot parse \"DisplayString\" arguments");
- return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
- }
- bt_shell_printf(COLOR_YELLOW "%s %s\n" COLOR_OFF, prompt, str);
- return l_dbus_message_new_method_return(msg);
- }
- static struct l_dbus_message *prompt_numeric_call(struct l_dbus *dbus,
- struct l_dbus_message *msg,
- void *user_data)
- {
- char *str;
- int action_index;
- const char *desc;
- if (!l_dbus_message_get_arguments(msg, "s", &str)) {
- l_error("Cannot parse \"PromptNumeric\" arguments");
- return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
- }
- action_index = get_action(str, true);
- if (action_index < 0)
- return l_dbus_message_new_error(msg, dbus_err_support, NULL);
- desc = prompt_numeric_table[action_index].description;
- l_dbus_message_ref(msg);
- agent_input_request(DECIMAL, 8, desc, agent_input_done, msg);
- return NULL;
- }
- static struct l_dbus_message *prompt_public_call(struct l_dbus *dbus,
- struct l_dbus_message *msg,
- void *user_data)
- {
- l_dbus_message_ref(msg);
- agent_input_request(HEXADECIMAL, 64, "Enter 512 bit Public Key",
- agent_input_done, msg);
- return NULL;
- }
- static struct l_dbus_message *prompt_static_call(struct l_dbus *dbus,
- struct l_dbus_message *msg,
- void *user_data)
- {
- char *str;
- if (!l_dbus_message_get_arguments(msg, "s", &str) || !str) {
- l_error("Cannot parse \"PromptStatic\" arguments");
- return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
- }
- if (!strcmp(str, "in-alpha") || !strcmp(str, "out-alpha")) {
- l_dbus_message_ref(msg);
- agent_input_request(ASCII, 8, "Enter displayed Ascii code",
- agent_input_done, msg);
- } else if (!strcmp(str, "static-oob")) {
- l_dbus_message_ref(msg);
- agent_input_request(HEXADECIMAL, 16, "Enter Static Key",
- agent_input_done, msg);
- } else
- return l_dbus_message_new_error(msg, dbus_err_support, NULL);
- return NULL;
- }
- static void setup_agent_iface(struct l_dbus_interface *iface)
- {
- l_dbus_interface_property(iface, "Capabilities", 0, "as", caps_getter,
- NULL);
- /* TODO: Other properties */
- l_dbus_interface_method(iface, "DisplayString", 0, disp_string_call,
- "", "s", "value");
- l_dbus_interface_method(iface, "DisplayNumeric", 0, disp_numeric_call,
- "", "su", "type", "number");
- l_dbus_interface_method(iface, "PromptNumeric", 0, prompt_numeric_call,
- "u", "s", "number", "type");
- l_dbus_interface_method(iface, "PromptStatic", 0, prompt_static_call,
- "ay", "s", "data", "type");
- l_dbus_interface_method(iface, "PublicKey", 0, prompt_public_call,
- "ay", "", "data");
- }
- static bool register_agent(void)
- {
- if (!l_dbus_register_interface(dbus, MESH_PROVISION_AGENT_INTERFACE,
- setup_agent_iface, NULL, false)) {
- l_error("Unable to register agent interface");
- return false;
- }
- if (!l_dbus_register_object(dbus, app.agent_path, NULL, NULL,
- MESH_PROVISION_AGENT_INTERFACE, NULL, NULL)) {
- l_error("Failed to register object %s", app.agent_path);
- return false;
- }
- if (!l_dbus_object_add_interface(dbus, app.agent_path,
- L_DBUS_INTERFACE_PROPERTIES, NULL)) {
- l_error("Failed to add interface %s",
- L_DBUS_INTERFACE_PROPERTIES);
- return false;
- }
- return true;
- }
- static void try_set_node_proxy(void *a, void *b)
- {
- struct l_dbus_proxy *proxy = a;
- const char *interface = l_dbus_proxy_get_interface(proxy);
- const char *path = l_dbus_proxy_get_path(proxy);
- if (strcmp(local->path, path))
- return;
- if (!strcmp(interface, MESH_MANAGEMENT_INTERFACE))
- local->mgmt_proxy = proxy;
- else if (!strcmp(interface, MESH_NODE_INTERFACE))
- local->proxy = proxy;
- }
- static void attach_node_reply(struct l_dbus_proxy *proxy,
- struct l_dbus_message *msg, void *user_data)
- {
- struct meshcfg_node *node = user_data;
- struct l_dbus_message_iter iter_cfg;
- uint32_t ivi;
- if (l_dbus_message_is_error(msg)) {
- const char *name;
- l_dbus_message_get_error(msg, &name, NULL);
- l_error("Failed to attach node: %s", name);
- goto fail;
- }
- if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
- &local->path, &iter_cfg))
- goto fail;
- bt_shell_printf("Attached with path %s\n", local->path);
- /* Populate node's proxies */
- l_queue_foreach(node_proxies, try_set_node_proxy, node);
- /* Remove from orphaned proxies list */
- if (local->proxy)
- l_queue_remove(node_proxies, local->proxy);
- if (local->mgmt_proxy)
- l_queue_remove(node_proxies, local->mgmt_proxy);
- /* Inititalize config client model */
- client_init();
- if (l_dbus_proxy_get_property(local->proxy, "IvIndex", "u", &ivi) &&
- ivi != iv_index) {
- iv_index = ivi;
- mesh_db_set_iv_index(ivi);
- remote_clear_rejected_addresses(ivi);
- }
- return;
- fail:
- l_free(node);
- node = NULL;
- }
- static void attach_node_setup(struct l_dbus_message *msg, void *user_data)
- {
- l_dbus_message_set_arguments(msg, "ot", app.path,
- l_get_be64(local->token.u8));
- }
- static void create_net_reply(struct l_dbus_proxy *proxy,
- struct l_dbus_message *msg, void *user_data)
- {
- if (l_dbus_message_is_error(msg)) {
- const char *name;
- l_dbus_message_get_error(msg, &name, NULL);
- l_error("Failed to create network: %s", name);
- return;
- }
- }
- static void create_net_setup(struct l_dbus_message *msg, void *user_data)
- {
- struct l_dbus_message_builder *builder;
- /* Generate random UUID */
- l_uuid_v4(app.uuid);
- builder = l_dbus_message_builder_new(msg);
- l_dbus_message_builder_append_basic(builder, 'o', app.path);
- append_byte_array(builder, app.uuid, 16);
- l_dbus_message_builder_finalize(builder);
- l_dbus_message_builder_destroy(builder);
- }
- static void cmd_create_network(int argc, char *argv[])
- {
- if (have_config) {
- l_error("Mesh network configuration exists (%s)", cfg_fname);
- return;
- }
- l_dbus_proxy_method_call(net_proxy, "CreateNetwork", create_net_setup,
- create_net_reply, NULL,
- NULL);
- }
- static void scan_reply(struct l_dbus_proxy *proxy, struct l_dbus_message *msg,
- void *user_data)
- {
- if (l_dbus_message_is_error(msg)) {
- const char *name;
- l_dbus_message_get_error(msg, &name, NULL);
- l_error("Failed to start unprovisioned scan: %s", name);
- return;
- }
- bt_shell_printf("Unprovisioned scan started\n");
- }
- static void scan_setup(struct l_dbus_message *msg, void *user_data)
- {
- uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
- struct l_dbus_message_builder *builder;
- builder = l_dbus_message_builder_new(msg);
- l_dbus_message_builder_enter_array(builder, "{sv}");
- append_dict_entry_basic(builder, "Seconds", "q", &secs);
- l_dbus_message_builder_leave_array(builder);
- l_dbus_message_builder_finalize(builder);
- l_dbus_message_builder_destroy(builder);
- }
- static void cmd_scan_unprov(int argc, char *argv[])
- {
- uint32_t secs = 0;
- bool enable;
- if (!local || !local->proxy || !local->mgmt_proxy) {
- bt_shell_printf("Node is not attached\n");
- return;
- }
- if (parse_argument_on_off(argc, argv, &enable) == FALSE) {
- bt_shell_printf("Failed to parse input\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- if (argc == 3)
- sscanf(argv[2], "%u", &secs);
- if (secs > UNPROV_SCAN_MAX_SECS)
- secs = UNPROV_SCAN_MAX_SECS;
- if (enable)
- l_dbus_proxy_method_call(local->mgmt_proxy, "UnprovisionedScan",
- scan_setup, scan_reply,
- L_UINT_TO_PTR(secs), NULL);
- else
- l_dbus_proxy_method_call(local->mgmt_proxy,
- "UnprovisionedScanCancel",
- NULL, NULL, NULL, NULL);
- }
- static uint8_t *parse_key(struct l_dbus_message_iter *iter, uint16_t id,
- const char *name)
- {
- uint8_t *val;
- uint32_t len;
- if (!l_dbus_message_iter_get_fixed_array(iter, &val, &len)
- || len != 16) {
- bt_shell_printf("Failed to parse %s %4.4x\n", name, id);
- return NULL;
- }
- return val;
- }
- static bool parse_app_keys(struct l_dbus_message_iter *iter, uint16_t net_idx,
- void *user_data)
- {
- struct l_dbus_message_iter app_keys, app_key, opts;
- uint16_t app_idx;
- if (!l_dbus_message_iter_get_variant(iter, "a(qaya{sv})", &app_keys))
- return false;
- while (l_dbus_message_iter_next_entry(&app_keys, &app_idx, &app_key,
- &opts)) {
- struct l_dbus_message_iter var;
- uint8_t *val, *old_val = NULL;
- const char *key;
- val = parse_key(&app_key, app_idx, "AppKey");
- if (!val)
- return false;
- while (l_dbus_message_iter_next_entry(&opts, &key, &var)) {
- if (!strcmp(key, "OldKey")) {
- if (!l_dbus_message_iter_get_variant(&var, "ay",
- &app_key))
- return false;
- old_val = parse_key(&app_key, app_idx,
- "old NetKey");
- if (!old_val)
- return false;
- }
- }
- mesh_db_set_app_key(user_data, net_idx, app_idx, val, old_val);
- }
- return true;
- }
- static bool parse_net_keys(struct l_dbus_message_iter *iter, void *user_data)
- {
- struct l_dbus_message_iter net_keys, net_key, opts;
- uint16_t idx;
- if (!l_dbus_message_iter_get_variant(iter, "a(qaya{sv})", &net_keys))
- return false;
- while (l_dbus_message_iter_next_entry(&net_keys, &idx, &net_key,
- &opts)) {
- struct l_dbus_message_iter var;
- uint8_t *val, *old_val = NULL;
- uint8_t phase = KEY_REFRESH_PHASE_NONE;
- const char *key;
- val = parse_key(&net_key, idx, "NetKey");
- if (!val)
- return false;
- while (l_dbus_message_iter_next_entry(&opts, &key, &var)) {
- if (!strcmp(key, "AppKeys")) {
- if (!parse_app_keys(&var, idx, user_data))
- return false;
- } else if (!strcmp(key, "Phase")) {
- if (!l_dbus_message_iter_get_variant(&var, "y",
- &phase))
- return false;
- } else if (!strcmp(key, "OldKey")) {
- if (!l_dbus_message_iter_get_variant(&var, "ay",
- &net_key))
- return false;
- old_val = parse_key(&net_key, idx,
- "old NetKey");
- if (!old_val)
- return false;
- }
- }
- mesh_db_set_net_key(user_data, idx, val, old_val, phase);
- }
- return true;
- }
- static bool parse_dev_keys(struct l_dbus_message_iter *iter, void *user_data)
- {
- struct l_dbus_message_iter keys, dev_key;
- uint16_t unicast;
- if (!l_dbus_message_iter_get_variant(iter, "a(qay)", &keys))
- return false;
- while (l_dbus_message_iter_next_entry(&keys, &unicast, &dev_key)) {
- uint8_t *data;
- data = parse_key(&dev_key, unicast, "Device Key");
- if (!data)
- return false;
- mesh_db_set_device_key(user_data, unicast, data);
- }
- return true;
- }
- static void export_keys_reply(struct l_dbus_proxy *proxy,
- struct l_dbus_message *msg, void *user_data)
- {
- struct l_dbus_message_iter iter, var;
- char *cfg_dir = NULL, *fname = NULL;
- const char *key;
- bool is_error = true;
- if (l_dbus_message_is_error(msg)) {
- const char *name;
- l_dbus_message_get_error(msg, &name, NULL);
- bt_shell_printf("Failed to export keys: %s", name);
- goto done;
- }
- if (!l_dbus_message_get_arguments(msg, "a{sv}", &iter)) {
- bt_shell_printf("Malformed ExportKeys reply");
- goto done;
- }
- while (l_dbus_message_iter_next_entry(&iter, &key, &var)) {
- if (!strcmp(key, "NetKeys")) {
- if (!parse_net_keys(&var, user_data))
- goto done;
- } else if (!strcmp(key, "DevKeys")) {
- if (!parse_dev_keys(&var, user_data))
- goto done;
- }
- }
- is_error = false;
- cfg_dir = l_strdup(cfg_fname);
- cfg_dir = dirname(cfg_dir);
- fname = l_strdup_printf("%s/%s", cfg_dir, DEFAULT_EXPORT_FILE);
- done:
- if (mesh_db_finish_export(is_error, user_data, fname)) {
- if (!is_error)
- bt_shell_printf("Config DB is exported to %s\n", fname);
- }
- l_free(cfg_dir);
- l_free(fname);
- }
- static void cmd_export_db(int argc, char *argv[])
- {
- void *cfg_export;
- if (!local || !local->proxy || !local->mgmt_proxy) {
- bt_shell_printf("Node is not attached\n");
- return;
- }
- /* Generate a properly formatted DB from the local config */
- cfg_export = mesh_db_prepare_export();
- if (!cfg_export) {
- bt_shell_printf("Failed to prepare config db\n");
- return;
- }
- /* Export the keys from the daemon */
- l_dbus_proxy_method_call(local->mgmt_proxy, "ExportKeys", NULL,
- export_keys_reply, cfg_export, NULL);
- }
- static void cmd_list_unprov(int argc, char *argv[])
- {
- bt_shell_printf(COLOR_YELLOW "Unprovisioned devices:\n" COLOR_OFF);
- l_queue_foreach(devices, print_device, NULL);
- }
- static void cmd_list_nodes(int argc, char *argv[])
- {
- remote_print_all();
- }
- static void cmd_keys(int argc, char *argv[])
- {
- keys_print_keys();
- }
- static void free_generic_request(void *data)
- {
- struct generic_request *req = data;
- l_free(req->data1);
- l_free(req->data2);
- l_free(req);
- }
- static void import_node_reply(struct l_dbus_proxy *proxy,
- struct l_dbus_message *msg, void *user_data)
- {
- struct generic_request *req = user_data;
- uint16_t primary, net_idx;
- uint8_t ele_cnt;
- if (l_dbus_message_is_error(msg)) {
- const char *name;
- l_dbus_message_get_error(msg, &name, NULL);
- l_error("Failed to import remote node: %s", name);
- return;
- }
- net_idx = (uint16_t) req->arg1;
- primary = (uint16_t) req->arg2;
- ele_cnt = (uint8_t) req->arg3;
- remote_add_node(req->data1, primary, ele_cnt, net_idx);
- }
- static void import_node_setup(struct l_dbus_message *msg, void *user_data)
- {
- struct generic_request *req = user_data;
- uint16_t primary;
- uint8_t ele_cnt;
- struct l_dbus_message_builder *builder;
- primary = (uint16_t) req->arg2;
- ele_cnt = (uint8_t) req->arg3;
- builder = l_dbus_message_builder_new(msg);
- l_dbus_message_builder_append_basic(builder, 'q', &primary);
- l_dbus_message_builder_append_basic(builder, 'y', &ele_cnt);
- append_byte_array(builder, req->data2, 16);
- l_dbus_message_builder_finalize(builder);
- l_dbus_message_builder_destroy(builder);
- }
- static void cmd_import_node(int argc, char *argv[])
- {
- struct generic_request *req;
- size_t sz;
- if (!local || !local->proxy || !local->mgmt_proxy) {
- bt_shell_printf("Node is not attached\n");
- return;
- }
- if (argc < 6) {
- bt_shell_printf("UUID, element count and device key");
- bt_shell_printf("Unicast, element count and device key");
- bt_shell_printf("are required\n");
- return;
- }
- req = l_new(struct generic_request, 1);
- /* Device UUID */
- req->data1 = l_util_from_hexstring(argv[1], &sz);
- if (!req->data1 || sz != 16 || !l_uuid_is_valid(req->data1)) {
- l_error("Failed to generate UUID array from %s", argv[1]);
- goto fail;
- }
- /* NetKey Index*/
- if (sscanf(argv[2], "%04x", &req->arg1) != 1)
- goto fail;
- /* Unicast of the primary element */
- if (sscanf(argv[3], "%04x", &req->arg2) != 1)
- goto fail;
- /* Number of elements */
- if (sscanf(argv[4], "%u", &req->arg3) != 1)
- goto fail;
- /* DevKey */
- req->data2 = l_util_from_hexstring(argv[5], &sz);
- if (!req->data2 || sz != 16) {
- l_error("Failed to generate DevKey array from %s", argv[5]);
- goto fail;
- }
- l_dbus_proxy_method_call(local->mgmt_proxy, "ImportRemoteNode",
- import_node_setup, import_node_reply,
- req, free_generic_request);
- return;
- fail:
- free_generic_request(req);
- }
- static void subnet_set_phase_reply(struct l_dbus_proxy *proxy,
- struct l_dbus_message *msg, void *user_data)
- {
- struct generic_request *req = user_data;
- uint16_t net_idx;
- uint8_t phase;
- if (l_dbus_message_is_error(msg)) {
- const char *name;
- l_dbus_message_get_error(msg, &name, NULL);
- l_error("Failed to set subnet phase: %s", name);
- return;
- }
- net_idx = (uint16_t) req->arg1;
- phase = (uint8_t) req->arg2;
- if (phase == KEY_REFRESH_PHASE_THREE)
- phase = KEY_REFRESH_PHASE_NONE;
- keys_set_net_key_phase(net_idx, phase, true);
- }
- static void subnet_set_phase_setup(struct l_dbus_message *msg, void *user_data)
- {
- struct generic_request *req = user_data;
- uint16_t net_idx;
- uint8_t phase;
- net_idx = (uint16_t) req->arg1;
- phase = (uint8_t) req->arg2;
- l_dbus_message_set_arguments(msg, "qy", net_idx, phase);
- }
- static void cmd_subnet_set_phase(int argc, char *argv[])
- {
- struct generic_request *req;
- if (!local || !local->proxy || !local->mgmt_proxy) {
- bt_shell_printf("Node is not attached\n");
- return;
- }
- if (argc < 3) {
- bt_shell_printf("NetKey index and phase are required\n");
- return;
- }
- req = l_new(struct generic_request, 1);
- if (sscanf(argv[1], "%04x", &req->arg1) != 1)
- goto fail;
- if (sscanf(argv[2], "%d", &req->arg2) != 1)
- goto fail;
- l_dbus_proxy_method_call(local->mgmt_proxy, "SetKeyPhase",
- subnet_set_phase_setup,
- subnet_set_phase_reply, req, l_free);
- return;
- fail:
- l_free(req);
- }
- static void mgr_key_reply(struct l_dbus_proxy *proxy,
- struct l_dbus_message *msg, void *user_data)
- {
- struct generic_request *req = user_data;
- uint16_t idx = (uint16_t) req->arg1;
- const char *method = req->str;
- if (l_dbus_message_is_error(msg)) {
- const char *name;
- l_dbus_message_get_error(msg, &name, NULL);
- l_error("Method %s returned error: %s", method, name);
- bt_shell_printf("Method %s returned error: %s\n", method, name);
- return;
- }
- if (!strcmp("CreateSubnet", method)) {
- keys_add_net_key(idx);
- mesh_db_add_net_key(idx);
- } else if (!strcmp("DeleteSubnet", method)) {
- keys_del_net_key(idx);
- mesh_db_del_net_key(idx);
- } else if (!strcmp("UpdateSubnet", method)) {
- keys_set_net_key_phase(idx, KEY_REFRESH_PHASE_ONE, true);
- } else if (!strcmp("DeleteAppKey", method)) {
- keys_del_app_key(idx);
- mesh_db_del_app_key(idx);
- }
- }
- static void mgr_key_setup(struct l_dbus_message *msg, void *user_data)
- {
- struct generic_request *req = user_data;
- uint16_t idx = (uint16_t) req->arg1;
- l_dbus_message_set_arguments(msg, "q", idx);
- }
- static void mgr_key_cmd(int argc, char *argv[], const char *method_name)
- {
- struct generic_request *req;
- if (!local || !local->proxy || !local->mgmt_proxy) {
- bt_shell_printf("Node is not attached\n");
- return;
- }
- if (argc < 2) {
- bt_shell_printf("Missing required arguments\n");
- return;
- }
- req = l_new(struct generic_request, 1);
- if (sscanf(argv[1], "%04x", &req->arg1) != 1) {
- l_free(req);
- return;
- }
- req->str = method_name;
- l_dbus_proxy_method_call(local->mgmt_proxy, method_name,
- mgr_key_setup, mgr_key_reply,
- req, l_free);
- }
- static void cmd_delete_appkey(int argc, char *argv[])
- {
- mgr_key_cmd(argc, argv, "DeleteAppKey");
- }
- static void cmd_update_appkey(int argc, char *argv[])
- {
- mgr_key_cmd(argc, argv, "UpdateAppKey");
- }
- static void cmd_delete_subnet(int argc, char *argv[])
- {
- mgr_key_cmd(argc, argv, "DeleteSubnet");
- }
- static void cmd_update_subnet(int argc, char *argv[])
- {
- mgr_key_cmd(argc, argv, "UpdateSubnet");
- }
- static void cmd_create_subnet(int argc, char *argv[])
- {
- mgr_key_cmd(argc, argv, "CreateSubnet");
- }
- static void add_key_reply(struct l_dbus_proxy *proxy,
- struct l_dbus_message *msg, void *user_data)
- {
- struct generic_request *req = user_data;
- uint16_t net_idx, app_idx;
- const char *method = req->str;
- if (l_dbus_message_is_error(msg)) {
- const char *name;
- l_dbus_message_get_error(msg, &name, NULL);
- l_error("%s failed: %s", method, name);
- return;
- }
- net_idx = (uint16_t) req->arg1;
- if (!strcmp(method, "ImportSubnet")) {
- keys_add_net_key(net_idx);
- mesh_db_add_net_key(net_idx);
- return;
- }
- app_idx = (uint16_t) req->arg2;
- keys_add_app_key(net_idx, app_idx);
- mesh_db_add_app_key(net_idx, app_idx);
- }
- static void import_appkey_setup(struct l_dbus_message *msg, void *user_data)
- {
- struct generic_request *req = user_data;
- uint16_t net_idx, app_idx;
- struct l_dbus_message_builder *builder;
- net_idx = (uint16_t) req->arg1;
- app_idx = (uint16_t) req->arg2;
- builder = l_dbus_message_builder_new(msg);
- l_dbus_message_builder_append_basic(builder, 'q', &net_idx);
- l_dbus_message_builder_append_basic(builder, 'q', &app_idx);
- append_byte_array(builder, req->data1, 16);
- l_dbus_message_builder_finalize(builder);
- l_dbus_message_builder_destroy(builder);
- }
- static void cmd_import_appkey(int argc, char *argv[])
- {
- struct generic_request *req;
- size_t sz;
- if (!local || !local->proxy || !local->mgmt_proxy) {
- bt_shell_printf("Node is not attached\n");
- return;
- }
- if (argc < 4) {
- bt_shell_printf("Netkey and AppKey indices and");
- bt_shell_printf("key value are required\n");
- return;
- }
- req = l_new(struct generic_request, 1);
- if (sscanf(argv[1], "%04x", &req->arg1) != 1)
- goto fail;
- if (sscanf(argv[2], "%04x", &req->arg2) != 1)
- goto fail;
- req->data1 = l_util_from_hexstring(argv[3], &sz);
- if (!req->data1 || sz != 16) {
- l_error("Failed to generate key array from %s", argv[3]);
- goto fail;
- }
- req->str = "ImportAppKey";
- l_dbus_proxy_method_call(local->mgmt_proxy, "ImportAppKey",
- import_appkey_setup, add_key_reply,
- req, free_generic_request);
- return;
- fail:
- free_generic_request(req);
- }
- static void import_subnet_setup(struct l_dbus_message *msg, void *user_data)
- {
- struct generic_request *req = user_data;
- uint16_t net_idx;
- struct l_dbus_message_builder *builder;
- net_idx = (uint16_t) req->arg1;
- builder = l_dbus_message_builder_new(msg);
- l_dbus_message_builder_append_basic(builder, 'q', &net_idx);
- append_byte_array(builder, req->data1, 16);
- l_dbus_message_builder_finalize(builder);
- l_dbus_message_builder_destroy(builder);
- }
- static void cmd_import_subnet(int argc, char *argv[])
- {
- struct generic_request *req;
- size_t sz;
- if (!local || !local->proxy || !local->mgmt_proxy) {
- bt_shell_printf("Node is not attached\n");
- return;
- }
- if (argc < 3) {
- bt_shell_printf("NetKey index and value are required\n");
- return;
- }
- req = l_new(struct generic_request, 1);
- if (sscanf(argv[1], "%04x", &req->arg1) != 1)
- goto fail;
- req->data1 = l_util_from_hexstring(argv[2], &sz);
- if (!req->data1 || sz != 16) {
- l_error("Failed to generate key array from %s", argv[2]);
- goto fail;
- }
- req->str = "ImportSubnet";
- l_dbus_proxy_method_call(local->mgmt_proxy, "ImportSubnet",
- import_subnet_setup, add_key_reply,
- req, free_generic_request);
- return;
- fail:
- free_generic_request(req);
- }
- static void create_appkey_setup(struct l_dbus_message *msg, void *user_data)
- {
- struct generic_request *req = user_data;
- uint16_t net_idx, app_idx;
- net_idx = (uint16_t) req->arg1;
- app_idx = (uint16_t) req->arg2;
- l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
- }
- static void cmd_create_appkey(int argc, char *argv[])
- {
- struct generic_request *req;
- if (!local || !local->proxy || !local->mgmt_proxy) {
- bt_shell_printf("Node is not attached\n");
- return;
- }
- if (argc < 3) {
- bt_shell_printf("AppKey index is required\n");
- return;
- }
- req = l_new(struct generic_request, 1);
- if (sscanf(argv[1], "%04x", &req->arg1) != 1)
- goto fail;
- if (sscanf(argv[2], "%04x", &req->arg2) != 1)
- goto fail;
- req->str = "CreateAppKey";
- l_dbus_proxy_method_call(local->mgmt_proxy, "CreateAppKey",
- create_appkey_setup, add_key_reply,
- req, l_free);
- return;
- fail:
- l_free(req);
- }
- static void add_node_reply(struct l_dbus_proxy *proxy,
- struct l_dbus_message *msg, void *user_data)
- {
- if (l_dbus_message_is_error(msg)) {
- const char *name;
- prov_in_progress = false;
- l_dbus_message_get_error(msg, &name, NULL);
- l_error("Failed to start provisioning: %s", name);
- return;
- }
- bt_shell_printf("Provisioning started\n");
- }
- static void add_node_setup(struct l_dbus_message *msg, void *user_data)
- {
- char *str = user_data;
- size_t sz;
- unsigned char *uuid;
- struct l_dbus_message_builder *builder;
- uuid = l_util_from_hexstring(str, &sz);
- if (!uuid || sz != 16 || !l_uuid_is_valid(uuid)) {
- l_error("Failed to generate UUID array from %s", str);
- return;
- }
- builder = l_dbus_message_builder_new(msg);
- append_byte_array(builder, uuid, 16);
- l_dbus_message_builder_enter_array(builder, "{sv}");
- /* TODO: populate with options when defined */
- l_dbus_message_builder_leave_array(builder);
- l_dbus_message_builder_finalize(builder);
- l_dbus_message_builder_destroy(builder);
- l_free(uuid);
- }
- static void cmd_start_prov(int argc, char *argv[])
- {
- if (!local || !local->proxy || !local->mgmt_proxy) {
- bt_shell_printf("Node is not attached\n");
- return;
- }
- if (prov_in_progress) {
- bt_shell_printf("Provisioning is already in progress\n");
- return;
- }
- if (!argv[1] || (strlen(argv[1]) != 32)) {
- bt_shell_printf(COLOR_RED "Requires UUID\n" COLOR_RED);
- return;
- }
- if (l_dbus_proxy_method_call(local->mgmt_proxy, "AddNode",
- add_node_setup, add_node_reply,
- argv[1], NULL))
- prov_in_progress = true;
- }
- static const struct bt_shell_menu main_menu = {
- .name = "main",
- .entries = {
- { "create", "[unicast_range_low]", cmd_create_network,
- "Create new mesh network with one initial node" },
- { "discover-unprovisioned", "<on/off> [seconds]", cmd_scan_unprov,
- "Look for devices to provision" },
- { "appkey-create", "<net_idx> <app_idx>", cmd_create_appkey,
- "Create a new local AppKey" },
- { "appkey-import", "<net_idx> <app_idx> <key>", cmd_import_appkey,
- "Import a new local AppKey" },
- { "appkey-update", "<app_idx>", cmd_update_appkey,
- "Update local AppKey" },
- { "appkey-delete", "<app_idx>", cmd_delete_appkey,
- "Delete local AppKey" },
- { "subnet-create", "<net_idx>", cmd_create_subnet,
- "Create a new local subnet (NetKey)" },
- { "subnet-import", "<net_idx> <key>", cmd_import_subnet,
- "Import a new local subnet (NetKey)" },
- { "subnet-update", "<net_idx>", cmd_update_subnet,
- "Update local subnet (NetKey)" },
- { "subnet-delete", "<net_idx>", cmd_delete_subnet,
- "Delete local subnet (NetKey)" },
- { "subnet-set-phase", "<net_idx> <phase>", cmd_subnet_set_phase,
- "Set subnet (NetKey) phase" },
- { "list-unprovisioned", NULL, cmd_list_unprov,
- "List unprovisioned devices" },
- { "provision", "<uuid>", cmd_start_prov,
- "Initiate provisioning"},
- { "node-import", "<uuid> <net_idx> <primary> <ele_count> <dev_key>",
- cmd_import_node,
- "Import an externally provisioned remote node"},
- { "list-nodes", NULL, cmd_list_nodes,
- "List remote mesh nodes"},
- { "keys", NULL, cmd_keys,
- "List available keys"},
- { "export-db", NULL, cmd_export_db,
- "Export mesh configuration database"},
- { } },
- };
- static void proxy_added(struct l_dbus_proxy *proxy, void *user_data)
- {
- const char *interface = l_dbus_proxy_get_interface(proxy);
- const char *path = l_dbus_proxy_get_path(proxy);
- bt_shell_printf("Proxy added: %s (%s)\n", interface, path);
- if (!strcmp(interface, MESH_NETWORK_INTERFACE)) {
- net_proxy = proxy;
- /*
- * If mesh network configuration has been read from
- * storage, attach the provisioner/config-client node.
- */
- if (local)
- l_dbus_proxy_method_call(net_proxy, "Attach",
- attach_node_setup,
- attach_node_reply, NULL,
- NULL);
- return;
- }
- if (!strcmp(interface, MESH_MANAGEMENT_INTERFACE)) {
- if (local && local->path) {
- if (!strcmp(local->path, path))
- local->mgmt_proxy = proxy;
- } else
- l_queue_push_tail(node_proxies, proxy);
- return;
- }
- if (!strcmp(interface, MESH_NODE_INTERFACE)) {
- if (local && local->path) {
- if (!strcmp(local->path, path))
- local->proxy = proxy;
- } else
- l_queue_push_tail(node_proxies, proxy);
- }
- }
- static void proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
- {
- const char *interface = l_dbus_proxy_get_interface(proxy);
- const char *path = l_dbus_proxy_get_path(proxy);
- bt_shell_printf("Proxy removed: %s (%s)\n", interface, path);
- if (!strcmp(interface, MESH_NETWORK_INTERFACE)) {
- bt_shell_printf("Mesh removed, terminating.\n");
- l_main_quit();
- return;
- }
- if (!strcmp(interface, MESH_NODE_INTERFACE)) {
- if (local && local->path && !strcmp(local->path, path))
- local->proxy = NULL;
- l_queue_remove(node_proxies, proxy);
- return;
- }
- if (!strcmp(interface, MESH_MANAGEMENT_INTERFACE)) {
- if (local && local->path && !strcmp(local->path, path))
- local->mgmt_proxy = NULL;
- l_queue_remove(node_proxies, proxy);
- }
- }
- static void build_model(struct l_dbus_message_builder *builder, uint16_t mod_id,
- bool pub_enable, bool sub_enable)
- {
- l_dbus_message_builder_enter_struct(builder, "qa{sv}");
- l_dbus_message_builder_append_basic(builder, 'q', &mod_id);
- l_dbus_message_builder_enter_array(builder, "{sv}");
- append_dict_entry_basic(builder, "Subscribe", "b", &sub_enable);
- append_dict_entry_basic(builder, "Publish", "b", &pub_enable);
- l_dbus_message_builder_leave_array(builder);
- l_dbus_message_builder_leave_struct(builder);
- }
- static bool mod_getter(struct l_dbus *dbus,
- struct l_dbus_message *message,
- struct l_dbus_message_builder *builder,
- void *user_data)
- {
- l_dbus_message_builder_enter_array(builder, "(qa{sv})");
- build_model(builder, app.ele.mods[0], false, false);
- build_model(builder, app.ele.mods[1], false, false);
- l_dbus_message_builder_leave_array(builder);
- return true;
- }
- static bool vmod_getter(struct l_dbus *dbus,
- struct l_dbus_message *message,
- struct l_dbus_message_builder *builder,
- void *user_data)
- {
- l_dbus_message_builder_enter_array(builder, "(qqa{sv})");
- l_dbus_message_builder_leave_array(builder);
- return true;
- }
- static bool ele_idx_getter(struct l_dbus *dbus,
- struct l_dbus_message *message,
- struct l_dbus_message_builder *builder,
- void *user_data)
- {
- l_dbus_message_builder_append_basic(builder, 'y', &app.ele.index);
- return true;
- }
- static struct l_dbus_message *dev_msg_recv_call(struct l_dbus *dbus,
- struct l_dbus_message *msg,
- void *user_data)
- {
- struct l_dbus_message_iter iter;
- uint16_t src, idx;
- uint8_t *data;
- uint32_t n;
- bool rmt;
- if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
- &iter)) {
- l_error("Cannot parse received message");
- return l_dbus_message_new_error(msg, dbus_err_args, NULL);
- }
- if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
- l_error("Cannot parse received message: data");
- return l_dbus_message_new_error(msg, dbus_err_args, NULL);
- }
- bt_shell_printf("Received dev key message (len %u):", n);
- /* Pass to the configuration client */
- if (cfgcli && cfgcli->ops.recv)
- cfgcli->ops.recv(src, APP_IDX_DEV_REMOTE, data, n);
- return l_dbus_message_new_method_return(msg);
- }
- static void setup_ele_iface(struct l_dbus_interface *iface)
- {
- /* Properties */
- l_dbus_interface_property(iface, "Index", 0, "y", ele_idx_getter,
- NULL);
- l_dbus_interface_property(iface, "VendorModels", 0, "a(qqa{sv})",
- vmod_getter, NULL);
- l_dbus_interface_property(iface, "Models", 0, "a(qa{sv})", mod_getter,
- NULL);
- /* Methods */
- l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
- dev_msg_recv_call, "", "qbqay", "source",
- "remote", "net_index", "data");
- /* TODO: Other methods */
- }
- static struct l_dbus_message *scan_result_call(struct l_dbus *dbus,
- struct l_dbus_message *msg,
- void *user_data)
- {
- struct l_dbus_message_iter iter, opts;
- int16_t rssi;
- uint32_t n;
- uint8_t *prov_data;
- char *str;
- struct unprov_device *dev;
- const char *sig = "naya{sv}";
- if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
- l_error("Cannot parse scan results");
- return l_dbus_message_new_error(msg, dbus_err_args, NULL);
- }
- if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
- n < 16) {
- l_error("Cannot parse scan result: data");
- return l_dbus_message_new_error(msg, dbus_err_args, NULL);
- }
- bt_shell_printf("Scan result:\n");
- bt_shell_printf("\t" COLOR_GREEN "rssi = %d\n" COLOR_OFF, rssi);
- str = l_util_hexstring_upper(prov_data, 16);
- bt_shell_printf("\t" COLOR_GREEN "UUID = %s\n" COLOR_OFF, str);
- l_free(str);
- if (n >= 18) {
- str = l_util_hexstring_upper(prov_data + 16, 2);
- bt_shell_printf("\t" COLOR_GREEN "OOB = %s\n" COLOR_OFF, str);
- l_free(str);
- }
- if (n >= 22) {
- str = l_util_hexstring_upper(prov_data + 18, 4);
- bt_shell_printf("\t" COLOR_GREEN "URI Hash = %s\n" COLOR_OFF,
- str);
- l_free(str);
- }
- /* TODO: Handle the rest of provisioning data if present */
- dev = l_queue_find(devices, match_device_uuid, prov_data);
- if (!dev) {
- dev = l_new(struct unprov_device, 1);
- memcpy(dev->uuid, prov_data, sizeof(dev->uuid));
- /* TODO: timed self-destructor */
- l_queue_push_tail(devices, dev);
- }
- /* Update with the latest rssi */
- dev->rssi = rssi;
- dev->last_seen = time(NULL);
- return l_dbus_message_new_method_return(msg);
- }
- static struct l_dbus_message *req_prov_call(struct l_dbus *dbus,
- struct l_dbus_message *msg,
- void *user_data)
- {
- uint8_t cnt;
- uint16_t unicast;
- struct l_dbus_message *reply;
- if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
- l_error("Cannot parse request for prov data");
- return l_dbus_message_new_error(msg, dbus_err_args, NULL);
- }
- unicast = remote_get_next_unicast(low_addr, high_addr, cnt);
- if (unicast == 0) {
- l_error("Failed to allocate addresses for %u elements\n", cnt);
- return l_dbus_message_new_error(msg,
- "org.freedesktop.DBus.Error."
- "Failed to allocate address", NULL);
- }
- bt_shell_printf("Assign addresses for %u elements\n", cnt);
- reply = l_dbus_message_new_method_return(msg);
- l_dbus_message_set_arguments(reply, "qq", prov_net_idx, unicast);
- return reply;
- }
- static void remove_device(uint8_t *uuid)
- {
- struct unprov_device *dev;
- dev = l_queue_remove_if(devices, match_device_uuid, uuid);
- l_free(dev);
- }
- static struct l_dbus_message *add_node_cmplt_call(struct l_dbus *dbus,
- struct l_dbus_message *msg,
- void *user_data)
- {
- struct l_dbus_message_iter iter;
- int16_t unicast;
- uint8_t cnt;
- uint32_t n;
- uint8_t *uuid;
- if (!prov_in_progress)
- return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
- prov_in_progress = false;
- if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
- l_error("Cannot parse add node complete message");
- return l_dbus_message_new_error(msg, dbus_err_args, NULL);
- }
- if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
- n != 16) {
- l_error("Cannot parse add node complete message: uuid");
- return l_dbus_message_new_error(msg, dbus_err_args, NULL);
- }
- remote_add_node(uuid, unicast, cnt, prov_net_idx);
- bt_shell_printf("Provisioning done:\n");
- remote_print_node(unicast);
- remove_device(uuid);
- if (!mesh_db_add_node(uuid, cnt, unicast, prov_net_idx))
- l_error("Failed to store new remote node");
- return l_dbus_message_new_method_return(msg);
- }
- static struct l_dbus_message *add_node_fail_call(struct l_dbus *dbus,
- struct l_dbus_message *msg,
- void *user_data)
- {
- struct l_dbus_message_iter iter;
- uint32_t n;
- uint8_t *uuid;
- char *str, *reason;
- if (!prov_in_progress)
- return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
- prov_in_progress = false;
- if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
- l_error("Cannot parse add node failed message");
- return l_dbus_message_new_error(msg, dbus_err_args, NULL);
- }
- if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
- n != 16) {
- l_error("Cannot parse add node failed message: uuid");
- return l_dbus_message_new_error(msg, dbus_err_args, NULL);
- }
- bt_shell_printf("Provisioning failed:\n");
- str = l_util_hexstring_upper(uuid, 16);
- bt_shell_printf("\t" COLOR_RED "UUID = %s\n" COLOR_OFF, str);
- l_free(str);
- bt_shell_printf("\t" COLOR_RED "%s\n" COLOR_OFF, reason);
- remove_device(uuid);
- return l_dbus_message_new_method_return(msg);
- }
- static void setup_prov_iface(struct l_dbus_interface *iface)
- {
- l_dbus_interface_method(iface, "ScanResult", 0, scan_result_call, "",
- "naya{sv}", "rssi", "data", "options");
- l_dbus_interface_method(iface, "RequestProvData", 0, req_prov_call,
- "qq", "y", "net_index", "unicast", "count");
- l_dbus_interface_method(iface, "AddNodeComplete", 0,
- add_node_cmplt_call, "", "ayqy",
- "uuid", "unicast", "count");
- l_dbus_interface_method(iface, "AddNodeFailed", 0, add_node_fail_call,
- "", "ays", "uuid", "reason");
- }
- static bool cid_getter(struct l_dbus *dbus,
- struct l_dbus_message *message,
- struct l_dbus_message_builder *builder,
- void *user_data)
- {
- l_dbus_message_builder_append_basic(builder, 'q', &app.cid);
- return true;
- }
- static bool pid_getter(struct l_dbus *dbus,
- struct l_dbus_message *message,
- struct l_dbus_message_builder *builder,
- void *user_data)
- {
- l_dbus_message_builder_append_basic(builder, 'q', &app.pid);
- return true;
- }
- static bool vid_getter(struct l_dbus *dbus,
- struct l_dbus_message *message,
- struct l_dbus_message_builder *builder,
- void *user_data)
- {
- l_dbus_message_builder_append_basic(builder, 'q', &app.vid);
- return true;
- }
- static bool crpl_getter(struct l_dbus *dbus,
- struct l_dbus_message *message,
- struct l_dbus_message_builder *builder,
- void *user_data)
- {
- l_dbus_message_builder_append_basic(builder, 'q', &app.crpl);
- return true;
- }
- static void attach_node(void *user_data)
- {
- l_dbus_proxy_method_call(net_proxy, "Attach", attach_node_setup,
- attach_node_reply, NULL,
- NULL);
- }
- static struct l_dbus_message *join_complete(struct l_dbus *dbus,
- struct l_dbus_message *message,
- void *user_data)
- {
- char *str;
- uint64_t tmp;
- if (!l_dbus_message_get_arguments(message, "t", &tmp))
- return l_dbus_message_new_error(message, dbus_err_args, NULL);
- local = l_new(struct meshcfg_node, 1);
- local->token.u64 = l_get_be64(&tmp);
- str = l_util_hexstring(&local->token.u8[0], 8);
- bt_shell_printf("Created new node with token %s\n", str);
- l_free(str);
- if (!mesh_db_create(cfg_fname, local->token.u8,
- "Mesh Config Client Network")) {
- l_free(local);
- local = NULL;
- return l_dbus_message_new_error(message, dbus_err_fail, NULL);
- }
- keys_add_net_key(PRIMARY_NET_IDX);
- mesh_db_add_net_key(PRIMARY_NET_IDX);
- remote_add_node(app.uuid, 0x0001, 1, PRIMARY_NET_IDX);
- mesh_db_add_node(app.uuid, 0x0001, 1, PRIMARY_NET_IDX);
- mesh_db_add_provisioner("BlueZ mesh-cfgclient", app.uuid,
- low_addr, high_addr,
- GROUP_ADDRESS_LOW, GROUP_ADDRESS_HIGH);
- l_idle_oneshot(attach_node, NULL, NULL);
- return l_dbus_message_new_method_return(message);
- }
- static void property_changed(struct l_dbus_proxy *proxy, const char *name,
- struct l_dbus_message *msg, void *user_data)
- {
- const char *interface = l_dbus_proxy_get_interface(proxy);
- const char *path = l_dbus_proxy_get_path(proxy);
- if (strcmp(path, local->path))
- return;
- bt_shell_printf("Property changed: %s %s %s\n", name, path, interface);
- if (!strcmp(interface, "org.bluez.mesh.Node1")) {
- if (!strcmp(name, "IvIndex")) {
- uint32_t ivi;
- if (!l_dbus_message_get_arguments(msg, "u", &ivi))
- return;
- bt_shell_printf("New IV Index: %u\n", ivi);
- iv_index = ivi;
- mesh_db_set_iv_index(ivi);
- remote_clear_rejected_addresses(ivi);
- }
- }
- }
- static void setup_app_iface(struct l_dbus_interface *iface)
- {
- l_dbus_interface_property(iface, "CompanyID", 0, "q", cid_getter,
- NULL);
- l_dbus_interface_property(iface, "VersionID", 0, "q", vid_getter,
- NULL);
- l_dbus_interface_property(iface, "ProductID", 0, "q", pid_getter,
- NULL);
- l_dbus_interface_property(iface, "CRPL", 0, "q", crpl_getter, NULL);
- l_dbus_interface_method(iface, "JoinComplete", 0, join_complete,
- "", "t", "token");
- /* TODO: Methods */
- }
- static bool register_app(void)
- {
- if (!l_dbus_register_interface(dbus, MESH_APPLICATION_INTERFACE,
- setup_app_iface, NULL, false)) {
- l_error("Failed to register interface %s",
- MESH_APPLICATION_INTERFACE);
- return false;
- }
- if (!l_dbus_register_interface(dbus, MESH_PROVISIONER_INTERFACE,
- setup_prov_iface, NULL, false)) {
- l_error("Failed to register interface %s",
- MESH_PROVISIONER_INTERFACE);
- return false;
- }
- if (!l_dbus_register_object(dbus, app.path, NULL, NULL,
- MESH_APPLICATION_INTERFACE, NULL,
- MESH_PROVISIONER_INTERFACE, NULL,
- NULL)) {
- l_error("Failed to register object %s", app.path);
- return false;
- }
- if (!register_agent())
- return false;
- if (!l_dbus_register_interface(dbus, MESH_ELEMENT_INTERFACE,
- setup_ele_iface, NULL, false)) {
- l_error("Failed to register interface %s",
- MESH_ELEMENT_INTERFACE);
- return false;
- }
- if (!l_dbus_register_object(dbus, app.ele.path, NULL, NULL,
- MESH_ELEMENT_INTERFACE, NULL, NULL)) {
- l_error("Failed to register object %s", app.ele.path);
- return false;
- }
- if (!l_dbus_object_add_interface(dbus, app.path,
- L_DBUS_INTERFACE_OBJECT_MANAGER,
- NULL)) {
- l_error("Failed to add interface %s",
- L_DBUS_INTERFACE_OBJECT_MANAGER);
- return false;
- }
- return true;
- }
- static void client_ready(struct l_dbus_client *client, void *user_data)
- {
- bt_shell_printf("D-Bus client ready\n");
- if (!register_app())
- bt_shell_quit(EXIT_FAILURE);
- bt_shell_attach(fileno(stdin));
- }
- static void client_connected(struct l_dbus *dbus, void *user_data)
- {
- bt_shell_printf("D-Bus client connected\n");
- bt_shell_set_prompt(PROMPT_ON);
- }
- static void client_disconnected(struct l_dbus *dbus, void *user_data)
- {
- bt_shell_printf("D-Bus client disconnected, exit\n");
- bt_shell_quit(EXIT_SUCCESS);
- }
- static void ready_callback(void *user_data)
- {
- bt_shell_printf("Connected to D-Bus\n");
- if (!l_dbus_object_manager_enable(dbus, "/"))
- bt_shell_printf("Failed to register the ObjectManager\n");
- }
- static bool setup_cfg_storage(void)
- {
- struct stat st;
- if (!config_opt) {
- char *home;
- char *mesh_dir;
- home = getenv("XDG_CONFIG_HOME");
- if (home) {
- mesh_dir = l_strdup_printf("%s/meshcfg", home);
- } else {
- home = getenv("HOME");
- if (!home) {
- l_error("\"HOME\" not set\n");
- return false;
- }
- mesh_dir = l_strdup_printf("%s/.config/meshcfg", home);
- }
- if (!mesh_dir)
- return false;
- if (stat(mesh_dir, &st) == 0) {
- if (!S_ISDIR(st.st_mode)) {
- l_error("%s not a directory", mesh_dir);
- return false;
- }
- } else if (errno == ENOENT) {
- if (mkdir(mesh_dir, 0700) != 0)
- return false;
- } else {
- perror("Cannot open config directory");
- return false;
- }
- cfg_fname = l_strdup_printf("%s/%s", mesh_dir,
- DEFAULT_CFG_FILE);
- l_free(mesh_dir);
- } else {
- cfg_fname = l_strdup_printf("%s", config_opt);
- }
- if (stat(cfg_fname, &st) == -1) {
- if (errno == ENOENT) {
- l_warn("\nWarning: config file \"%s\" not found",
- cfg_fname);
- return true;
- }
- perror("\nFailed to open config file");
- return false;
- }
- have_config = true;
- return true;
- }
- static bool read_mesh_config(void)
- {
- uint16_t range_l, range_h;
- if (!mesh_db_load(cfg_fname)) {
- l_error("Failed to load config from %s", cfg_fname);
- return false;
- }
- local = l_new(struct meshcfg_node, 1);
- if (!mesh_db_get_token(local->token.u8)) {
- l_error("Failed to read the provisioner's token ID");
- l_error("Check config file %s", cfg_fname);
- l_free(local);
- local = NULL;
- return false;
- }
- l_info("Mesh configuration loaded from %s", cfg_fname);
- if (mesh_db_get_addr_range(&range_l, &range_h)) {
- low_addr = range_l;
- high_addr = range_h;
- }
- iv_index = mesh_db_get_iv_index();
- return true;
- }
- int main(int argc, char *argv[])
- {
- struct l_dbus_client *client;
- uint32_t val;
- int status;
- bt_shell_init(argc, argv, &opt);
- bt_shell_set_menu(&main_menu);
- l_log_set_stderr();
- if (address_opt && sscanf(address_opt, "%04x", &val) == 1)
- low_addr = (uint16_t) val;
- if (low_addr > DEFAULT_MAX_ADDRESS) {
- l_error("Invalid start address");
- bt_shell_cleanup();
- return EXIT_FAILURE;
- }
- if (!low_addr)
- low_addr = DEFAULT_START_ADDRESS;
- if (range_opt && sscanf(address_opt, "%04x", &val) == 1) {
- if (val == 0) {
- l_error("Invalid address range");
- bt_shell_cleanup();
- return EXIT_FAILURE;
- }
- /* Inclusive */
- high_addr = low_addr + val - 1;
- }
- if (!high_addr || high_addr > DEFAULT_MAX_ADDRESS)
- high_addr = DEFAULT_MAX_ADDRESS;
- if (net_idx_opt && sscanf(net_idx_opt, "%04x", &val) == 1)
- prov_net_idx = (uint16_t) val;
- else
- prov_net_idx = DEFAULT_NET_INDEX;
- if (!setup_cfg_storage()) {
- bt_shell_cleanup();
- return EXIT_FAILURE;
- }
- if (have_config && !read_mesh_config()) {
- bt_shell_cleanup();
- return EXIT_FAILURE;
- }
- bt_shell_set_prompt(PROMPT_OFF);
- dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
- l_dbus_set_ready_handler(dbus, ready_callback, NULL, NULL);
- client = l_dbus_client_new(dbus, BLUEZ_MESH_NAME, "/org/bluez/mesh");
- l_dbus_client_set_connect_handler(client, client_connected, NULL, NULL);
- l_dbus_client_set_disconnect_handler(client, client_disconnected, NULL,
- NULL);
- l_dbus_client_set_proxy_handlers(client, proxy_added, proxy_removed,
- property_changed, NULL, NULL);
- l_dbus_client_set_ready_handler(client, client_ready, NULL, NULL);
- node_proxies = l_queue_new();
- devices = l_queue_new();
- status = bt_shell_run();
- l_dbus_client_destroy(client);
- l_dbus_destroy(dbus);
- cfgcli_cleanup();
- return status;
- }
|