| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130 |
- // SPDX-License-Identifier: LGPL-2.1-or-later
- /*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2019-2020 Intel Corporation. All rights reserved.
- *
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <stdio.h>
- #include <stdbool.h>
- #include <ell/ell.h>
- #include "src/shared/shell.h"
- #include "src/shared/util.h"
- #include "mesh/mesh-defs.h"
- #include "mesh/util.h"
- #include "mesh/crypto.h"
- #include "tools/mesh/util.h"
- #include "tools/mesh/model.h"
- #include "tools/mesh/keys.h"
- #include "tools/mesh/mesh-db.h"
- #include "tools/mesh/remote.h"
- #include "tools/mesh/config-model.h"
- #include "tools/mesh/cfgcli.h"
- #define MIN_COMPOSITION_LEN 16
- #define NO_RESPONSE 0xFFFFFFFF
- /* Default timeout for getting a response to a sent config command (seconds) */
- #define DEFAULT_TIMEOUT 2
- struct cfg_cmd {
- uint32_t opcode;
- uint32_t rsp;
- const char *desc;
- };
- struct pending_req {
- struct l_timeout *timer;
- const struct cfg_cmd *cmd;
- uint16_t addr;
- };
- static struct l_queue *requests;
- static struct l_queue *groups;
- static void *send_data;
- static model_send_msg_func_t send_msg;
- static delete_remote_func_t mgr_del_remote;
- static void *key_data;
- static key_send_func_t send_key_msg;
- static uint32_t rsp_timeout = DEFAULT_TIMEOUT;
- static uint16_t target = UNASSIGNED_ADDRESS;
- static uint32_t parms[8];
- static struct cfg_cmd cmds[] = {
- { OP_APPKEY_ADD, OP_APPKEY_STATUS, "AppKeyAdd" },
- { OP_APPKEY_DELETE, OP_APPKEY_STATUS, "AppKeyDelete" },
- { OP_APPKEY_GET, OP_APPKEY_LIST, "AppKeyGet" },
- { OP_APPKEY_LIST, NO_RESPONSE, "AppKeyList" },
- { OP_APPKEY_STATUS, NO_RESPONSE, "AppKeyStatus" },
- { OP_APPKEY_UPDATE, OP_APPKEY_STATUS, "AppKeyUpdate" },
- { OP_DEV_COMP_GET, OP_DEV_COMP_STATUS, "DeviceCompositionGet" },
- { OP_DEV_COMP_STATUS, NO_RESPONSE, "DeviceCompositionStatus" },
- { OP_CONFIG_BEACON_GET, OP_CONFIG_BEACON_STATUS, "BeaconGet" },
- { OP_CONFIG_BEACON_SET, OP_CONFIG_BEACON_STATUS, "BeaconSet" },
- { OP_CONFIG_BEACON_STATUS, NO_RESPONSE, "BeaconStatus" },
- { OP_CONFIG_DEFAULT_TTL_GET, OP_CONFIG_DEFAULT_TTL_STATUS,
- "DefaultTTLGet" },
- { OP_CONFIG_DEFAULT_TTL_SET, OP_CONFIG_DEFAULT_TTL_STATUS,
- "DefaultTTLSet" },
- { OP_CONFIG_DEFAULT_TTL_STATUS, NO_RESPONSE, "DefaultTTLStatus" },
- { OP_CONFIG_FRIEND_GET, OP_CONFIG_FRIEND_STATUS, "FriendGet" },
- { OP_CONFIG_FRIEND_SET, OP_CONFIG_FRIEND_STATUS, "FrienSet" },
- { OP_CONFIG_FRIEND_STATUS, NO_RESPONSE, "FriendStatus" },
- { OP_CONFIG_PROXY_GET, OP_CONFIG_PROXY_STATUS, "ProxyGet" },
- { OP_CONFIG_PROXY_SET, OP_CONFIG_PROXY_STATUS, "ProxySet" },
- { OP_CONFIG_PROXY_STATUS, NO_RESPONSE, "ProxyStatus" },
- { OP_CONFIG_KEY_REFRESH_PHASE_GET, OP_CONFIG_KEY_REFRESH_PHASE_STATUS,
- "KeyRefreshPhaseGet" },
- { OP_CONFIG_KEY_REFRESH_PHASE_SET, OP_CONFIG_KEY_REFRESH_PHASE_STATUS,
- "KeyRefreshPhaseSet" },
- { OP_CONFIG_KEY_REFRESH_PHASE_STATUS, NO_RESPONSE,
- "KeyRefreshPhaseStatus" },
- { OP_CONFIG_MODEL_PUB_GET, OP_CONFIG_MODEL_PUB_STATUS, "ModelPubGet" },
- { OP_CONFIG_MODEL_PUB_SET, OP_CONFIG_MODEL_PUB_STATUS, "ModelPubSet" },
- { OP_CONFIG_MODEL_PUB_STATUS, NO_RESPONSE, "ModelPubStatus" },
- { OP_CONFIG_MODEL_PUB_VIRT_SET, OP_CONFIG_MODEL_PUB_STATUS,
- "ModelPubVirtualSet" },
- { OP_CONFIG_MODEL_SUB_ADD, OP_CONFIG_MODEL_SUB_STATUS, "ModelSubAdd" },
- { OP_CONFIG_MODEL_SUB_DELETE, OP_CONFIG_MODEL_SUB_STATUS,
- "ModelSubDelete" },
- { OP_CONFIG_MODEL_SUB_DELETE_ALL, OP_CONFIG_MODEL_SUB_STATUS,
- "ModelSubDeleteAll" },
- { OP_CONFIG_MODEL_SUB_OVERWRITE, OP_CONFIG_MODEL_SUB_STATUS,
- "ModelSubOverwrite" },
- { OP_CONFIG_MODEL_SUB_STATUS, NO_RESPONSE, "ModelSubStatus" },
- { OP_CONFIG_MODEL_SUB_VIRT_ADD, OP_CONFIG_MODEL_SUB_STATUS,
- "ModelSubVirtAdd" },
- { OP_CONFIG_MODEL_SUB_VIRT_DELETE, OP_CONFIG_MODEL_SUB_STATUS,
- "ModelSubVirtDelete" },
- { OP_CONFIG_MODEL_SUB_VIRT_OVERWRITE, OP_CONFIG_MODEL_SUB_STATUS,
- "ModelSubVirtOverwrite" },
- { OP_CONFIG_NETWORK_TRANSMIT_GET, OP_CONFIG_NETWORK_TRANSMIT_STATUS,
- "NetworkTransmitGet" },
- { OP_CONFIG_NETWORK_TRANSMIT_SET, OP_CONFIG_NETWORK_TRANSMIT_STATUS,
- "NetworkTransmitSet" },
- { OP_CONFIG_NETWORK_TRANSMIT_STATUS, NO_RESPONSE,
- "NetworkTransmitStatus" },
- { OP_CONFIG_RELAY_GET, OP_CONFIG_RELAY_STATUS, "RelayGet" },
- { OP_CONFIG_RELAY_SET, OP_CONFIG_RELAY_STATUS, "RelaySet" },
- { OP_CONFIG_RELAY_STATUS, NO_RESPONSE, "RelayStatus" },
- { OP_CONFIG_MODEL_SUB_GET, OP_CONFIG_MODEL_SUB_LIST, "ModelSubGet" },
- { OP_CONFIG_MODEL_SUB_LIST, NO_RESPONSE, "ModelSubList" },
- { OP_CONFIG_VEND_MODEL_SUB_GET, OP_CONFIG_VEND_MODEL_SUB_LIST,
- "VendorModelSubGet" },
- { OP_CONFIG_VEND_MODEL_SUB_LIST, NO_RESPONSE, "VendorModelSubList" },
- { OP_CONFIG_POLL_TIMEOUT_LIST, OP_CONFIG_POLL_TIMEOUT_STATUS,
- "PollTimeoutList" },
- { OP_CONFIG_POLL_TIMEOUT_STATUS, NO_RESPONSE, "PollTimeoutStatus" },
- { OP_CONFIG_HEARTBEAT_PUB_GET, OP_CONFIG_HEARTBEAT_PUB_STATUS,
- "HeartbeatPubGet" },
- { OP_CONFIG_HEARTBEAT_PUB_SET, OP_CONFIG_HEARTBEAT_PUB_STATUS,
- "HeartbeatPubSet" },
- { OP_CONFIG_HEARTBEAT_PUB_STATUS, NO_RESPONSE, "HeartbeatPubStatus" },
- { OP_CONFIG_HEARTBEAT_SUB_GET, OP_CONFIG_HEARTBEAT_SUB_STATUS,
- "HeartbeatSubGet" },
- { OP_CONFIG_HEARTBEAT_SUB_SET, OP_CONFIG_HEARTBEAT_SUB_STATUS,
- "HeartbeatSubSet" },
- { OP_CONFIG_HEARTBEAT_SUB_STATUS, NO_RESPONSE, "HeartbeatSubStatus" },
- { OP_MODEL_APP_BIND, OP_MODEL_APP_STATUS, "ModelAppBind" },
- { OP_MODEL_APP_STATUS, NO_RESPONSE, "ModelAppStatus" },
- { OP_MODEL_APP_UNBIND, OP_MODEL_APP_STATUS, "ModelAppUnbind" },
- { OP_NETKEY_ADD, OP_NETKEY_STATUS, "NetKeyAdd" },
- { OP_NETKEY_DELETE, OP_NETKEY_STATUS, "NetKeyDelete" },
- { OP_NETKEY_GET, OP_NETKEY_LIST, "NetKeyGet" },
- { OP_NETKEY_LIST, NO_RESPONSE, "NetKeyList" },
- { OP_NETKEY_STATUS, NO_RESPONSE, "NetKeyStatus" },
- { OP_NETKEY_UPDATE, OP_NETKEY_STATUS, "NetKeyUpdate" },
- { OP_NODE_IDENTITY_GET, OP_NODE_IDENTITY_STATUS, "NodeIdentityGet" },
- { OP_NODE_IDENTITY_SET, OP_NODE_IDENTITY_STATUS, "NodeIdentitySet" },
- { OP_NODE_IDENTITY_STATUS, NO_RESPONSE, "NodeIdentityStatus" },
- { OP_NODE_RESET, OP_NODE_RESET_STATUS, "NodeReset" },
- { OP_NODE_RESET_STATUS, NO_RESPONSE, "NodeResetStatus" },
- { OP_MODEL_APP_GET, OP_MODEL_APP_LIST, "ModelAppGet" },
- { OP_MODEL_APP_LIST, NO_RESPONSE, "ModelAppList" },
- { OP_VEND_MODEL_APP_GET, OP_VEND_MODEL_APP_LIST, "VendorModelAppGet" },
- { OP_VEND_MODEL_APP_LIST, NO_RESPONSE, "VendorModelAppList" }
- };
- static const struct cfg_cmd *get_cmd(uint32_t opcode)
- {
- uint32_t n;
- for (n = 0; n < L_ARRAY_SIZE(cmds); n++) {
- if (opcode == cmds[n].opcode)
- return &cmds[n];
- }
- return NULL;
- }
- static const char *opcode_str(uint32_t opcode)
- {
- const struct cfg_cmd *cmd;
- cmd = get_cmd(opcode);
- if (!cmd)
- return "Unknown";
- return cmd->desc;
- }
- static void reset_remote_node(uint16_t addr)
- {
- uint8_t ele_cnt = remote_del_node(addr);
- bt_shell_printf("Remote removed (primary %4.4x)\n", addr);
- if (ele_cnt && mgr_del_remote)
- mgr_del_remote(addr, ele_cnt);
- }
- static void free_request(void *a)
- {
- struct pending_req *req = a;
- l_timeout_remove(req->timer);
- l_free(req);
- }
- static struct pending_req *get_req_by_rsp(uint16_t addr, uint32_t rsp)
- {
- const struct l_queue_entry *entry;
- entry = l_queue_get_entries(requests);
- for (; entry; entry = entry->next) {
- struct pending_req *req = entry->data;
- if (req->addr == addr && req->cmd->rsp == rsp)
- return req;
- }
- return NULL;
- }
- static void wait_rsp_timeout(struct l_timeout *timeout, void *user_data)
- {
- struct pending_req *req = user_data;
- bt_shell_printf("No response for \"%s\" from %4.4x\n",
- req->cmd->desc, req->addr);
- /* Node reset case: delete the remote even if there is no response */
- if (req->cmd->opcode == OP_NODE_RESET)
- reset_remote_node(req->addr);
- l_queue_remove(requests, req);
- free_request(req);
- }
- static void add_request(uint32_t opcode)
- {
- struct pending_req *req;
- const struct cfg_cmd *cmd;
- cmd = get_cmd(opcode);
- if (!cmd)
- return;
- req = l_new(struct pending_req, 1);
- req->cmd = cmd;
- req->addr = target;
- req->timer = l_timeout_create(rsp_timeout,
- wait_rsp_timeout, req, NULL);
- l_queue_push_tail(requests, req);
- }
- static uint32_t print_mod_id(uint8_t *data, bool vendor, const char *offset)
- {
- uint32_t mod_id;
- if (!vendor) {
- mod_id = get_le16(data);
- bt_shell_printf("%sModel ID\t%4.4x \"%s\"\n",
- offset, mod_id, sig_model_string(mod_id));
- mod_id = VENDOR_ID_MASK | mod_id;
- } else {
- mod_id = get_le16(data + 2);
- bt_shell_printf("%sModel ID\t%4.4x %4.4x\n", offset,
- get_le16(data), mod_id);
- mod_id = get_le16(data) << 16 | mod_id;
- }
- return mod_id;
- }
- static void print_composition(uint8_t *data, uint16_t len)
- {
- uint16_t features;
- int i = 0;
- bt_shell_printf("Received composion:\n");
- /* skip page -- We only support Page Zero */
- data++;
- len--;
- bt_shell_printf("\tCID: %4.4x", get_le16(&data[0]));
- bt_shell_printf("\tPID: %4.4x", get_le16(&data[2]));
- bt_shell_printf("\tVID: %4.4x", get_le16(&data[4]));
- bt_shell_printf("\tCRPL: %4.4x", get_le16(&data[6]));
- features = get_le16(&data[8]);
- data += 10;
- len -= 10;
- bt_shell_printf("\tFeature support:\n");
- bt_shell_printf("\t\trelay: %s\n", (features & FEATURE_RELAY) ?
- "yes" : "no");
- bt_shell_printf("\t\tproxy: %s\n", (features & FEATURE_PROXY) ?
- "yes" : "no");
- bt_shell_printf("\t\tfriend: %s\n", (features & FEATURE_FRIEND) ?
- "yes" : "no");
- bt_shell_printf("\t\tlpn: %s\n", (features & FEATURE_LPN) ?
- "yes" : "no");
- while (len) {
- uint8_t m, v;
- bt_shell_printf("\t Element %d:\n", i);
- bt_shell_printf("\t\tlocation: %4.4x\n", get_le16(data));
- data += 2;
- len -= 2;
- m = *data++;
- v = *data++;
- len -= 2;
- if (m)
- bt_shell_printf("\t\tSIG defined models:\n");
- while (len >= 2 && m--) {
- print_mod_id(data, false, "\t\t ");
- data += 2;
- len -= 2;
- }
- if (v)
- bt_shell_printf("\t\t Vendor defined models:\n");
- while (len >= 4 && v--) {
- print_mod_id(data, true, "\t\t ");
- data += 4;
- len -= 4;
- }
- i++;
- }
- }
- static void print_pub(uint16_t ele_addr, uint32_t mod_id,
- struct model_pub *pub)
- {
- bt_shell_printf("\tElement: %4.4x\n", ele_addr);
- bt_shell_printf("\tPub Addr: %4.4x\n", pub->u.addr);
- if (mod_id < VENDOR_ID_MASK)
- bt_shell_printf("\tModel: %8.8x\n", mod_id);
- else
- bt_shell_printf("\tModel: %4.4x\n",
- (uint16_t) (mod_id & ~VENDOR_ID_MASK));
- bt_shell_printf("\tApp Key Idx: %u (0x%3.3x)\n", pub->app_idx,
- pub->app_idx);
- bt_shell_printf("\tTTL: %2.2x\n", pub->ttl);
- }
- static void print_sub_list(uint16_t addr, bool is_vendor, uint8_t *data,
- uint16_t len)
- {
- uint16_t i;
- bt_shell_printf("\nNode %4.4x Subscription List status %s\n",
- addr, mesh_status_str(data[0]));
- bt_shell_printf("Element Addr\t%4.4x\n", get_le16(data + 1));
- print_mod_id(data + 3, is_vendor, "");
- i = (is_vendor ? 7 : 5);
- bt_shell_printf("Subscriptions:\n");
- for (; i < len; i += 2)
- bt_shell_printf("\t\t%4.4x\n ", get_le16(data + i));
- }
- static void print_appkey_list(uint16_t len, uint8_t *data)
- {
- uint16_t app_idx;
- bt_shell_printf("AppKeys:\n");
- while (len >= 3) {
- app_idx = l_get_le16(data) & 0xfff;
- bt_shell_printf("\t%u (0x%3.3x)\n", app_idx, app_idx);
- app_idx = l_get_le16(data + 1) >> 4;
- bt_shell_printf("\t%u (0x%3.3x)\n", app_idx, app_idx);
- data += 3;
- len -= 3;
- }
- if (len == 2) {
- app_idx = l_get_le16(data) & 0xfff;
- bt_shell_printf("\t %u (0x%3.3x)\n", app_idx, app_idx);
- }
- }
- static bool match_group_addr(const void *a, const void *b)
- {
- const struct mesh_group *grp = a;
- uint16_t addr = L_PTR_TO_UINT(b);
- return grp->addr == addr;
- }
- static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data,
- uint16_t len)
- {
- uint32_t opcode, mod_id;
- const struct cfg_cmd *cmd;
- uint16_t app_idx, net_idx, addr, ele_addr, features;
- struct mesh_group *grp;
- struct model_pub pub;
- int n;
- struct pending_req *req;
- bool saved = false;
- if (mesh_opcode_get(data, len, &opcode, &n)) {
- len -= n;
- data += n;
- } else
- return false;
- bt_shell_printf("Received %s (len %u)\n", opcode_str(opcode), len);
- req = get_req_by_rsp(src, opcode);
- if (req) {
- cmd = req->cmd;
- l_queue_remove(requests, req);
- free_request(req);
- } else
- cmd = NULL;
- switch (opcode) {
- default:
- return false;
- case OP_DEV_COMP_STATUS:
- if (len < MIN_COMPOSITION_LEN)
- return true;
- print_composition(data, len);
- saved = mesh_db_node_set_composition(src, data, len);
- if (saved)
- remote_set_composition(src, true);
- break;
- case OP_APPKEY_STATUS:
- if (len != 4)
- return true;
- bt_shell_printf("Node %4.4x AppKey status %s\n", src,
- mesh_status_str(data[0]));
- net_idx = get_le16(data + 1) & 0xfff;
- app_idx = get_le16(data + 2) >> 4;
- bt_shell_printf("NetKey\t%u (0x%3.3x)\n", net_idx, net_idx);
- bt_shell_printf("AppKey\t%u (0x%3.3x)\n", app_idx, app_idx);
- if (data[0] != MESH_STATUS_SUCCESS)
- return true;
- if (!cmd)
- return true;
- if (cmd->opcode == OP_APPKEY_ADD)
- saved = remote_add_app_key(src, app_idx, true);
- else if (cmd->opcode == OP_APPKEY_DELETE)
- saved = remote_del_app_key(src, app_idx);
- else if (cmd->opcode == OP_APPKEY_UPDATE)
- saved = remote_update_app_key(src, app_idx, true, true);
- break;
- case OP_APPKEY_LIST:
- if (len < 3)
- return true;
- bt_shell_printf("AppKey List (node %4.4x) Status %s\n",
- src, mesh_status_str(data[0]));
- net_idx = l_get_le16(&data[1]);
- bt_shell_printf("NetKey %u (0x%3.3x)\n", net_idx, net_idx);
- len -= 3;
- if (data[0] != MESH_STATUS_SUCCESS)
- return true;
- data += 3;
- print_appkey_list(len, data);
- return true;
- case OP_NETKEY_STATUS:
- if (len != 3)
- return true;
- bt_shell_printf("Node %4.4x NetKey status %s\n", src,
- mesh_status_str(data[0]));
- net_idx = get_le16(data + 1) & 0xfff;
- bt_shell_printf("\tNetKey %u (0x%3.3x)\n", net_idx, net_idx);
- if (data[0] != MESH_STATUS_SUCCESS)
- return true;
- if (!cmd)
- return true;
- if (cmd->opcode == OP_NETKEY_ADD)
- saved = remote_add_net_key(src, net_idx, true);
- else if (cmd->opcode == OP_NETKEY_DELETE)
- saved = remote_del_net_key(src, net_idx);
- else if (cmd->opcode == OP_NETKEY_UPDATE)
- saved = remote_update_net_key(src, net_idx, true, true);
- break;
- case OP_NETKEY_LIST:
- if (len < 2)
- return true;
- bt_shell_printf("NetKey List (node %4.4x):\n", src);
- while (len >= 3) {
- net_idx = l_get_le16(data) & 0xfff;
- bt_shell_printf("\t%u (0x%3.3x)\n", net_idx, net_idx);
- net_idx = l_get_le16(data + 1) >> 4;
- bt_shell_printf("\t%u (0x%3.3x)\n", net_idx, net_idx);
- data += 3;
- len -= 3;
- }
- if (len == 2) {
- net_idx = l_get_le16(data) & 0xfff;
- bt_shell_printf("\t %u (0x%3.3x)\n", net_idx, net_idx);
- }
- return true;
- case OP_CONFIG_KEY_REFRESH_PHASE_STATUS:
- if (len != 4)
- return true;
- bt_shell_printf("Node %4.4x Key Refresh Phase status %s\n", src,
- mesh_status_str(data[0]));
- net_idx = get_le16(data + 1) & 0xfff;
- bt_shell_printf("\tNetKey %u (0x%3.3x)\n", net_idx, net_idx);
- bt_shell_printf("\tKR Phase %2.2x\n", data[3]);
- if (data[0] != MESH_STATUS_SUCCESS)
- return true;
- if (data[3] != KEY_REFRESH_PHASE_NONE)
- return true;
- saved = remote_finish_key_refresh(src, net_idx);
- break;
- case OP_MODEL_APP_STATUS:
- if (len != 7 && len != 9)
- return true;
- bt_shell_printf("Node %4.4x: Model App status %s\n", src,
- mesh_status_str(data[0]));
- addr = get_le16(data + 1);
- app_idx = get_le16(data + 3);
- bt_shell_printf("Element Addr\t%4.4x\n", addr);
- mod_id = print_mod_id(data + 5, len == 9, "");
- bt_shell_printf("AppIdx\t\t%u (0x%3.3x)\n ", app_idx, app_idx);
- if (data[0] != MESH_STATUS_SUCCESS || !cmd)
- return true;
- if (cmd->opcode == OP_MODEL_APP_BIND)
- saved = mesh_db_node_model_bind(src, addr, len == 9,
- mod_id, app_idx);
- else
- saved = mesh_db_node_model_unbind(src, addr, len == 9,
- mod_id, app_idx);
- break;
- case OP_NODE_IDENTITY_STATUS:
- if (len != 4)
- return true;
- bt_shell_printf("NetIdx %4.4x, NodeIdState 0x%02x, status %s\n",
- get_le16(data + 1), data[3],
- mesh_status_str(data[0]));
- return true;
- case OP_CONFIG_BEACON_STATUS:
- if (len != 1)
- return true;
- bt_shell_printf("Node %4.4x: Config Beacon Status 0x%02x\n",
- src, data[0]);
- saved = mesh_db_node_set_beacon(src, data[0] != 0);
- break;
- case OP_CONFIG_RELAY_STATUS:
- if (len != 2)
- return true;
- bt_shell_printf("Node %4.4x: Relay 0x%02x, cnt %d, steps %d\n",
- src, data[0], data[1] & 0x7, data[1] >> 3);
- saved = mesh_db_node_set_relay(src, data[0], data[1] & 7,
- ((data[1] >> 3) + 1) * 10);
- break;
- case OP_CONFIG_PROXY_STATUS:
- if (len != 1)
- return true;
- bt_shell_printf("Node %4.4x Proxy state 0x%02x\n",
- src, data[0]);
- saved = mesh_db_node_set_proxy(src, data[0]);
- break;
- case OP_CONFIG_DEFAULT_TTL_STATUS:
- if (len != 1)
- return true;
- bt_shell_printf("Node %4.4x Default TTL %d\n", src, data[0]);
- saved = mesh_db_node_set_ttl(src, data[0]);
- break;
- case OP_CONFIG_MODEL_PUB_STATUS:
- if (len != 12 && len != 14)
- return true;
- bt_shell_printf("\nNode %4.4x Publication status %s\n",
- src, mesh_status_str(data[0]));
- if (data[0] != MESH_STATUS_SUCCESS)
- return true;
- ele_addr = get_le16(data + 1);
- mod_id = print_mod_id(data + 10, len == 14, "");
- pub.u.addr = get_le16(data + 3);
- pub.app_idx = get_le16(data + 5);
- pub.cred = ((pub.app_idx & 0x1000) != 0);
- pub.app_idx &= 0x3ff;
- pub.ttl = data[7];
- pub.prd_steps = (data[8] & 0x3f);
- print_pub(ele_addr, mod_id, &pub);
- switch (data[8] >> 6) {
- case 0:
- pub.prd_res = 100;
- break;
- case 2:
- pub.prd_res = 10;
- break;
- case 1:
- pub.prd_res = 10000;
- break;
- case 3:
- pub.prd_res = 600000;
- break;
- }
- pub.rtx_cnt = data[9] & 0x7;
- pub.rtx_interval = ((data[9] >> 3) + 1) * 50;
- bt_shell_printf("Rexmit count\t%d\n", pub.rtx_cnt);
- bt_shell_printf("Rexmit steps\t%d\n", pub.rtx_interval);
- if (IS_VIRTUAL(pub.u.addr)) {
- grp = l_queue_find(groups, match_group_addr,
- L_UINT_TO_PTR(pub.u.addr));
- if (!grp) {
- bt_shell_printf("Unknown virtual group\n");
- return true;
- }
- memcpy(pub.u.label, grp->label, sizeof(pub.u.label));
- }
- saved = mesh_db_node_model_set_pub(src, ele_addr, len == 14,
- mod_id, &pub,
- IS_VIRTUAL(pub.u.addr));
- break;
- /* Per Mesh Profile 4.3.2.19 */
- case OP_CONFIG_MODEL_SUB_STATUS:
- if (len != 7 && len != 9)
- return true;
- bt_shell_printf("\nNode %4.4x Subscription status %s\n",
- src, mesh_status_str(data[0]));
- ele_addr = get_le16(data + 1);
- addr = get_le16(data + 3);
- bt_shell_printf("Element Addr\t%4.4x\n", ele_addr);
- mod_id = print_mod_id(data + 5, len == 9, "");
- bt_shell_printf("Subscr Addr\t%4.4x\n", addr);
- grp = l_queue_find(groups, match_group_addr,
- L_UINT_TO_PTR(addr));
- if (data[0] != MESH_STATUS_SUCCESS || !cmd)
- return true;
- switch (cmd->opcode) {
- default:
- return true;
- case OP_CONFIG_MODEL_SUB_ADD:
- saved = mesh_db_node_model_add_sub(src, ele_addr,
- len == 9, mod_id, addr);
- break;
- case OP_CONFIG_MODEL_SUB_DELETE:
- saved = mesh_db_node_model_del_sub(src, ele_addr,
- len == 9, mod_id, addr);
- break;
- case OP_CONFIG_MODEL_SUB_OVERWRITE:
- saved = mesh_db_node_model_overwrt_sub(src, ele_addr,
- len == 9, mod_id, addr);
- break;
- case OP_CONFIG_MODEL_SUB_DELETE_ALL:
- saved = mesh_db_node_model_del_sub_all(src, ele_addr,
- len == 9, mod_id);
- break;
- case OP_CONFIG_MODEL_SUB_VIRT_ADD:
- if (grp)
- saved = mesh_db_node_model_add_sub_virt(src,
- ele_addr, len == 9,
- mod_id, grp->label);
- break;
- case OP_CONFIG_MODEL_SUB_VIRT_DELETE:
- if (grp)
- saved = mesh_db_node_model_del_sub_virt(src,
- ele_addr, len == 9,
- mod_id, grp->label);
- break;
- case OP_CONFIG_MODEL_SUB_VIRT_OVERWRITE:
- if (grp)
- saved = mesh_db_node_model_overwrt_sub_virt(src,
- ele_addr, len == 9,
- mod_id, grp->label);
- break;
- }
- break;
- /* Per Mesh Profile 4.3.2.27 */
- case OP_CONFIG_MODEL_SUB_LIST:
- if (len < 5)
- return true;
- print_sub_list(src, false, data, len);
- return true;
- case OP_CONFIG_VEND_MODEL_SUB_LIST:
- if (len < 7)
- return true;
- print_sub_list(src, true, data, len);
- return true;
- /* Per Mesh Profile 4.3.2.50 */
- case OP_MODEL_APP_LIST:
- if (len < 5)
- return true;
- bt_shell_printf("\nNode %4.4x Model AppIdx status %s\n",
- src, mesh_status_str(data[0]));
- bt_shell_printf("Element Addr\t%4.4x\n", get_le16(data + 1));
- bt_shell_printf("Model ID\t%4.4x\n", get_le16(data + 3));
- data += 5;
- len -= 5;
- print_appkey_list(len, data);
- return true;
- case OP_VEND_MODEL_APP_LIST:
- if (len < 7)
- return true;
- bt_shell_printf("\nNode %4.4x Vendor Model AppIdx status %s\n",
- src, mesh_status_str(data[0]));
- if (data[0] != MESH_STATUS_SUCCESS)
- return true;
- bt_shell_printf("Element Addr\t%4.4x\n", get_le16(data + 1));
- print_mod_id(data + 3, true, "");
- data += 7;
- len -= 7;
- print_appkey_list(len, data);
- return true;
- /* Per Mesh Profile 4.3.2.63 */
- case OP_CONFIG_HEARTBEAT_PUB_STATUS:
- if (len != 10)
- return true;
- bt_shell_printf("\nNode %4.4x Heartbeat publish status %s\n",
- src, mesh_status_str(data[0]));
- if (data[0] != MESH_STATUS_SUCCESS)
- return true;
- addr = get_le16(data + 1);
- bt_shell_printf("Destination\t%4.4x\n", addr);
- bt_shell_printf("CountLog\t\t%2.2x\n", data[3]);
- bt_shell_printf("PeriodLog\t\t%2.2x\n", data[4]);
- bt_shell_printf("TTL\t\t%2.2x\n", data[5]);
- features = get_le16(data + 6);
- bt_shell_printf("Features\t%4.4x\n", features);
- net_idx = get_le16(data + 8);
- bt_shell_printf("Net_Idx\t%u (0x%3.3x)\n", net_idx, net_idx);
- saved = mesh_db_node_set_hb_pub(src, addr, net_idx, data[4],
- data[5], features);
- break;
- /* Per Mesh Profile 4.3.2.66 */
- case OP_CONFIG_HEARTBEAT_SUB_STATUS:
- if (len != 9)
- return true;
- bt_shell_printf("\nNode %4.4x Heartbeat subscribe status %s\n",
- src, mesh_status_str(data[0]));
- if (data[0] != MESH_STATUS_SUCCESS)
- return true;
- ele_addr = get_le16(data + 1);
- bt_shell_printf("Source\t\t%4.4x\n", ele_addr);
- addr = get_le16(data + 3);
- bt_shell_printf("Destination\t%4.4x\n", addr);
- bt_shell_printf("Period\t\t%2.2x\n", data[5]);
- bt_shell_printf("Count\t\t%2.2x\n", data[6]);
- bt_shell_printf("Min Hops\t%2.2x\n", data[7]);
- bt_shell_printf("Max Hops\t%2.2x\n", data[8]);
- saved = mesh_db_node_set_hb_sub(src, ele_addr, addr);
- break;
- /* Per Mesh Profile 4.3.2.71 */
- case OP_CONFIG_NETWORK_TRANSMIT_STATUS:
- if (len != 1)
- return true;
- bt_shell_printf("Node %4.4x: Net transmit cnt %d, steps %d\n",
- src, data[0] & 7, data[0] >> 3);
- saved = mesh_db_node_set_net_transmit(src, data[0] & 7,
- ((data[0] >> 3) + 1) * 10);
- break;
- /* Per Mesh Profile 4.3.2.54 */
- case OP_NODE_RESET_STATUS:
- bt_shell_printf("Node %4.4x is reset\n", src);
- reset_remote_node(src);
- return true;
- /* Per Mesh Profile 4.3.2.57 */
- case OP_CONFIG_FRIEND_STATUS:
- if (len != 1)
- return true;
- bt_shell_printf("Node %4.4x Friend state 0x%02x\n",
- src, data[0]);
- saved = mesh_db_node_set_friend(src, data[0]);
- break;
- }
- if (!saved)
- bt_shell_printf("Warning: Configuration not updated\n");
- return true;
- }
- static uint16_t put_model_id(uint8_t *buf, uint32_t *args, bool vendor)
- {
- uint16_t n = 2;
- if (vendor) {
- put_le16(args[1], buf);
- buf += 2;
- n = 4;
- }
- put_le16(args[0], buf);
- return n;
- }
- static uint32_t read_input_parameters(int argc, char *argv[])
- {
- uint32_t i;
- if (!argc)
- return 0;
- --argc;
- ++argv;
- if (!argc || argv[0][0] == '\0')
- return 0;
- for (i = 0; i < L_ARRAY_SIZE(parms) && i < (uint32_t) argc; i++) {
- if (sscanf(argv[i], "%x", &parms[i]) != 1)
- break;
- }
- return i;
- }
- static int compare_group_addr(const void *a, const void *b, void *user_data)
- {
- const struct mesh_group *grp0 = a;
- const struct mesh_group *grp1 = b;
- if (grp0->addr < grp1->addr)
- return -1;
- if (grp0->addr > grp1->addr)
- return 1;
- return 0;
- }
- static void print_virtual_not_found(uint16_t addr)
- {
- bt_shell_printf("Virtual group with hash %4.4x not found\n", addr);
- bt_shell_printf("To see available, use \"group-list\"\n");
- bt_shell_printf("To create new, use \"virt-add\"\n");
- }
- static struct mesh_group *add_group(uint16_t addr)
- {
- struct mesh_group *grp;
- if (!IS_GROUP(addr) || addr >= FIXED_GROUP_LOW)
- return NULL;
- grp = l_queue_find(groups, match_group_addr, L_UINT_TO_PTR(addr));
- if (grp)
- return grp;
- grp = l_new(struct mesh_group, 1);
- grp->addr = addr;
- l_queue_insert(groups, grp, compare_group_addr, NULL);
- mesh_db_add_group(grp);
- return grp;
- }
- static void cmd_timeout_set(int argc, char *argv[])
- {
- if (read_input_parameters(argc, argv) != 1)
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- rsp_timeout = parms[0];
- bt_shell_printf("Timeout to wait for remote node's response: %d secs\n",
- rsp_timeout);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_dst_set(int argc, char *argv[])
- {
- uint32_t dst;
- char *end;
- dst = strtol(argv[1], &end, 16);
- if (end != (argv[1] + 4)) {
- bt_shell_printf("Bad unicast address %s: "
- "expected format 4 digit hex\n", argv[1]);
- target = UNASSIGNED_ADDRESS;
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- bt_shell_printf("Configuring node %4.4x\n", dst);
- target = dst;
- set_menu_prompt("config", argv[1]);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static bool config_send(uint8_t *buf, uint16_t len, uint32_t opcode)
- {
- const struct cfg_cmd *cmd;
- bool res;
- if (IS_UNASSIGNED(target)) {
- bt_shell_printf("Destination not set\n");
- return false;
- }
- cmd = get_cmd(opcode);
- if (!cmd)
- return false;
- if (get_req_by_rsp(target, cmd->rsp)) {
- bt_shell_printf("Another command is pending\n");
- return false;
- }
- res = send_msg(send_data, target, APP_IDX_DEV_REMOTE, buf, len);
- if (!res)
- bt_shell_printf("Failed to send \"%s\"\n", opcode_str(opcode));
- if (cmd->rsp != NO_RESPONSE)
- add_request(opcode);
- return res;
- }
- static void cmd_default(uint32_t opcode)
- {
- uint16_t n;
- uint8_t msg[32];
- n = mesh_opcode_set(opcode, msg);
- if (!config_send(msg, n, opcode))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_composition_get(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[32];
- n = mesh_opcode_set(OP_DEV_COMP_GET, msg);
- /* By default, use page 0 */
- msg[n++] = (read_input_parameters(argc, argv) == 1) ? parms[0] : 0;
- if (!config_send(msg, n, OP_DEV_COMP_GET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_netkey_del(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[32];
- if (IS_UNASSIGNED(target)) {
- bt_shell_printf("Destination not set\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- n = mesh_opcode_set(OP_NETKEY_DELETE, msg);
- if (read_input_parameters(argc, argv) != 1) {
- bt_shell_printf("Bad arguments %s\n", argv[1]);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- put_le16(parms[0], msg + n);
- n += 2;
- if (!config_send(msg, n, OP_NETKEY_DELETE))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_kr_phase_get(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[32];
- if (IS_UNASSIGNED(target)) {
- bt_shell_printf("Destination not set\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- n = mesh_opcode_set(OP_CONFIG_KEY_REFRESH_PHASE_GET, msg);
- if (read_input_parameters(argc, argv) != 1)
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- put_le16(parms[0], msg + n);
- n += 2;
- if (!config_send(msg, n, OP_CONFIG_KEY_REFRESH_PHASE_GET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_kr_phase_set(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[32];
- uint8_t phase;
- if (IS_UNASSIGNED(target)) {
- bt_shell_printf("Destination not set\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- n = mesh_opcode_set(OP_CONFIG_KEY_REFRESH_PHASE_SET, msg);
- if (read_input_parameters(argc, argv) != 2)
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- if (parms[1] != KEY_REFRESH_PHASE_TWO &&
- parms[1] != KEY_REFRESH_PHASE_THREE) {
- bt_shell_printf("Invalid KR transition value %u\n", parms[1]);
- bt_shell_printf("Allowed values: 2 or 3\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- if (!keys_get_net_key_phase((uint16_t) parms[0], &phase)) {
- bt_shell_printf("Subnet KR state not found\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- if (phase != (parms[1] % KEY_REFRESH_PHASE_THREE)) {
- bt_shell_printf("Subnet's phase must be updated first!\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- put_le16(parms[0], msg + n);
- n += 2;
- msg[n++] = parms[1];
- if (!config_send(msg, n, OP_CONFIG_KEY_REFRESH_PHASE_SET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_appkey_del(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[32];
- uint16_t app_idx, net_idx;
- if (IS_UNASSIGNED(target)) {
- bt_shell_printf("Destination not set\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- n = mesh_opcode_set(OP_APPKEY_DELETE, msg);
- if (read_input_parameters(argc, argv) != 1) {
- bt_shell_printf("Bad arguments %s\n", argv[1]);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- app_idx = (uint16_t) parms[0];
- net_idx = keys_get_bound_key(app_idx);
- /* Pack bound NetKey and AppKey into 3 octets */
- msg[n] = net_idx;
- msg[n + 1] = ((net_idx >> 8) & 0xf) | ((app_idx << 4) & 0xf0);
- msg[n + 2] = app_idx >> 4;
- n += 3;
- if (!config_send(msg, n, OP_APPKEY_DELETE))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_appkey_get(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[32];
- if (IS_UNASSIGNED(target)) {
- bt_shell_printf("Destination not set\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- n = mesh_opcode_set(OP_APPKEY_GET, msg);
- if (read_input_parameters(argc, argv) != 1) {
- bt_shell_printf("Bad arguments %s\n", argv[1]);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- put_le16(parms[0], msg + n);
- n += 2;
- if (!config_send(msg, n, OP_APPKEY_GET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_key_add(uint32_t opcode, int argc, char *argv[])
- {
- uint16_t key_idx;
- bool is_appkey, update;
- const struct cfg_cmd *cmd;
- if (IS_UNASSIGNED(target)) {
- bt_shell_printf("Destination not set\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- if (!send_key_msg) {
- bt_shell_printf("Send key callback not set\n");
- return;
- }
- if (read_input_parameters(argc, argv) != 1) {
- bt_shell_printf("Bad arguments %s\n", argv[1]);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- cmd = get_cmd(opcode);
- if (!cmd)
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- if (get_req_by_rsp(target, cmd->rsp)) {
- bt_shell_printf("Another key command is pending\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- key_idx = (uint16_t) parms[0];
- update = (opcode == OP_NETKEY_UPDATE || opcode == OP_APPKEY_UPDATE);
- is_appkey = (opcode == OP_APPKEY_ADD || opcode == OP_APPKEY_UPDATE);
- if (!send_key_msg(key_data, target, key_idx, is_appkey, update))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- add_request(opcode);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_netkey_add(int argc, char *argv[])
- {
- cmd_key_add(OP_NETKEY_ADD, argc, argv);
- }
- static void cmd_netkey_update(int argc, char *argv[])
- {
- cmd_key_add(OP_NETKEY_UPDATE, argc, argv);
- }
- static void cmd_appkey_add(int argc, char *argv[])
- {
- cmd_key_add(OP_APPKEY_ADD, argc, argv);
- }
- static void cmd_appkey_update(int argc, char *argv[])
- {
- cmd_key_add(OP_APPKEY_UPDATE, argc, argv);
- }
- static void cmd_bind(uint32_t opcode, int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[32];
- uint32_t parm_cnt;
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 3 && parm_cnt != 4) {
- bt_shell_printf("Bad arguments\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- if (!remote_has_composition(target)) {
- bt_shell_printf("Node composition is unknown\n");
- bt_shell_printf("Call \"get-composition\" first\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- n = mesh_opcode_set(opcode, msg);
- put_le16(parms[0], msg + n);
- n += 2;
- put_le16(parms[1], msg + n);
- n += 2;
- n += put_model_id(msg + n, &parms[2], parm_cnt == 4);
- if (!config_send(msg, n, opcode))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_add_binding(int argc, char *argv[])
- {
- cmd_bind(OP_MODEL_APP_BIND, argc, argv);
- }
- static void cmd_del_binding(int argc, char *argv[])
- {
- cmd_bind(OP_MODEL_APP_UNBIND, argc, argv);
- }
- static void cmd_beacon_set(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[2 + 1];
- uint32_t parm_cnt;
- n = mesh_opcode_set(OP_CONFIG_BEACON_SET, msg);
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 1) {
- bt_shell_printf("bad arguments\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- msg[n++] = parms[0];
- if (!config_send(msg, n, OP_CONFIG_BEACON_SET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_beacon_get(int argc, char *argv[])
- {
- cmd_default(OP_CONFIG_BEACON_GET);
- }
- static void cmd_ident_set(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[2 + 3 + 4];
- uint32_t parm_cnt;
- n = mesh_opcode_set(OP_NODE_IDENTITY_SET, msg);
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 2) {
- bt_shell_printf("bad arguments\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- put_le16(parms[0], msg + n);
- n += 2;
- msg[n++] = parms[1];
- if (!config_send(msg, n, OP_NODE_IDENTITY_SET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_ident_get(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[2 + 2 + 4];
- uint32_t parm_cnt;
- n = mesh_opcode_set(OP_NODE_IDENTITY_GET, msg);
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 1) {
- bt_shell_printf("bad arguments\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- put_le16(parms[0], msg + n);
- n += 2;
- if (!config_send(msg, n, OP_NODE_IDENTITY_GET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_proxy_set(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[2 + 1];
- uint32_t parm_cnt;
- n = mesh_opcode_set(OP_CONFIG_PROXY_SET, msg);
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 1) {
- bt_shell_printf("bad arguments");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- msg[n++] = parms[0];
- if (!config_send(msg, n, OP_CONFIG_PROXY_SET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_proxy_get(int argc, char *argv[])
- {
- cmd_default(OP_CONFIG_PROXY_GET);
- }
- static void cmd_relay_set(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[2 + 2 + 4];
- uint32_t parm_cnt;
- n = mesh_opcode_set(OP_CONFIG_RELAY_SET, msg);
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 3) {
- bt_shell_printf("bad arguments\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- msg[n++] = parms[0];
- msg[n++] = parms[1] | (parms[2] << 3);
- if (!config_send(msg, n, OP_CONFIG_RELAY_SET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_relay_get(int argc, char *argv[])
- {
- cmd_default(OP_CONFIG_RELAY_GET);
- }
- static void cmd_ttl_set(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[32];
- uint32_t parm_cnt;
- parm_cnt = read_input_parameters(argc, argv);
- if (!parm_cnt || parms[0] > TTL_MASK) {
- bt_shell_printf("Bad TTL value\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- n = mesh_opcode_set(OP_CONFIG_DEFAULT_TTL_SET, msg);
- msg[n++] = parms[0];
- if (!config_send(msg, n, OP_CONFIG_DEFAULT_TTL_SET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_pub_set(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[48];
- uint32_t parm_cnt;
- struct mesh_group *grp;
- uint32_t opcode;
- uint16_t pub_addr;
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 6 && parm_cnt != 7) {
- bt_shell_printf("Bad arguments\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- if (parms[1] > ALL_NODES_ADDRESS) {
- bt_shell_printf("Bad publication address %x\n", parms[1]);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- if (!remote_has_composition(target)) {
- bt_shell_printf("Node composition is unknown\n");
- bt_shell_printf("Call \"get-composition\" first\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- pub_addr = parms[1];
- grp = l_queue_find(groups, match_group_addr, L_UINT_TO_PTR(pub_addr));
- if (!grp)
- grp = add_group(pub_addr);
- if (!grp && IS_VIRTUAL(pub_addr)) {
- print_virtual_not_found(pub_addr);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- opcode = (!IS_VIRTUAL(pub_addr)) ? OP_CONFIG_MODEL_PUB_SET :
- OP_CONFIG_MODEL_PUB_VIRT_SET;
- n = mesh_opcode_set(opcode, msg);
- put_le16(parms[0], msg + n);
- n += 2;
- /* Publish address */
- if (!IS_VIRTUAL(pub_addr)) {
- put_le16(pub_addr, msg + n);
- n += 2;
- } else {
- memcpy(msg + n, grp->label, 16);
- n += 16;
- }
- /* AppKey index + credential (set to 0) */
- put_le16(parms[2], msg + n);
- n += 2;
- /* TTL */
- msg[n++] = DEFAULT_TTL;
- /* Publish period step count and step resolution */
- msg[n++] = parms[3];
- /* Publish retransmit count & interval steps */
- msg[n++] = parms[4];
- /* Model Id */
- n += put_model_id(msg + n, &parms[5], parm_cnt == 7);
- if (!config_send(msg, n, opcode))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_pub_get(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[32];
- uint32_t parm_cnt;
- n = mesh_opcode_set(OP_CONFIG_MODEL_PUB_GET, msg);
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 2 && parm_cnt != 3) {
- bt_shell_printf("Bad arguments: %s\n", argv[1]);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- /* Element Address */
- put_le16(parms[0], msg + n);
- n += 2;
- /* Model Id */
- n += put_model_id(msg + n, &parms[1], parm_cnt == 3);
- if (!config_send(msg, n, OP_CONFIG_MODEL_PUB_GET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void subscription_cmd(int argc, char *argv[], uint32_t opcode)
- {
- uint16_t n;
- uint8_t msg[32];
- uint32_t parm_cnt;
- struct mesh_group *grp;
- uint16_t sub_addr;
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 3 && parm_cnt != 4) {
- bt_shell_printf("Bad arguments: %s\n", argv[1]);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- if ((!IS_GROUP(parms[1]) || IS_ALL_NODES(parms[1])) &&
- !IS_VIRTUAL(parms[1])) {
- bt_shell_printf("Bad subscription address %x\n", parms[1]);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- if (!remote_has_composition(target)) {
- bt_shell_printf("Node composition is unknown\n");
- bt_shell_printf("Call \"get-composition\" first\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- sub_addr = parms[1];
- grp = l_queue_find(groups, match_group_addr, L_UINT_TO_PTR(sub_addr));
- if (!grp && IS_VIRTUAL(sub_addr)) {
- print_virtual_not_found(sub_addr);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- if (!grp && opcode != OP_CONFIG_MODEL_SUB_DELETE)
- grp = add_group(sub_addr);
- if (IS_VIRTUAL(sub_addr)) {
- if (opcode == OP_CONFIG_MODEL_SUB_ADD)
- opcode = OP_CONFIG_MODEL_SUB_VIRT_ADD;
- else if (opcode == OP_CONFIG_MODEL_SUB_DELETE)
- opcode = OP_CONFIG_MODEL_SUB_VIRT_DELETE;
- else if (opcode == OP_CONFIG_MODEL_SUB_OVERWRITE)
- opcode = OP_CONFIG_MODEL_SUB_VIRT_OVERWRITE;
- }
- n = mesh_opcode_set(opcode, msg);
- /* Element Address */
- put_le16(parms[0], msg + n);
- n += 2;
- /* Subscription Address */
- if (!IS_VIRTUAL(sub_addr)) {
- put_le16(sub_addr, msg + n);
- n += 2;
- } else {
- memcpy(msg + n, grp->label, 16);
- n += 16;
- }
- /* Model ID */
- n += put_model_id(msg + n, &parms[2], parm_cnt == 4);
- if (!config_send(msg, n, opcode))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_sub_add(int argc, char *argv[])
- {
- subscription_cmd(argc, argv, OP_CONFIG_MODEL_SUB_ADD);
- }
- static void cmd_sub_del(int argc, char *argv[])
- {
- subscription_cmd(argc, argv, OP_CONFIG_MODEL_SUB_DELETE);
- }
- static void cmd_sub_ovwrt(int argc, char *argv[])
- {
- subscription_cmd(argc, argv, OP_CONFIG_MODEL_SUB_OVERWRITE);
- }
- static void cmd_sub_del_all(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[32];
- uint32_t parm_cnt;
- n = mesh_opcode_set(OP_CONFIG_MODEL_SUB_DELETE_ALL, msg);
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 2 && parm_cnt != 3) {
- bt_shell_printf("Bad arguments: %s\n", argv[1]);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- /* Element Address */
- put_le16(parms[0], msg + n);
- n += 2;
- /* Model ID */
- n += put_model_id(msg + n, &parms[1], parm_cnt == 3);
- if (!config_send(msg, n, OP_CONFIG_MODEL_SUB_DELETE_ALL))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_sub_get(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[32];
- uint32_t parm_cnt;
- bool vendor;
- uint32_t opcode;
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 2 && parm_cnt != 3) {
- bt_shell_printf("Bad arguments: %s\n", argv[1]);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- vendor = (parm_cnt == 3);
- opcode = !vendor ? OP_CONFIG_MODEL_SUB_GET :
- OP_CONFIG_VEND_MODEL_SUB_GET;
- n = mesh_opcode_set(opcode, msg);
- /* Element Address */
- put_le16(parms[0], msg + n);
- n += 2;
- /* Model ID */
- n += put_model_id(msg + n, &parms[1], vendor);
- if (!config_send(msg, n, opcode))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_mod_appidx_get(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[32];
- uint32_t parm_cnt;
- bool vendor;
- uint32_t opcode;
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 2 && parm_cnt != 3) {
- bt_shell_printf("Bad arguments: %s\n", argv[1]);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- vendor = (parm_cnt == 3);
- opcode = !vendor ? OP_MODEL_APP_GET : OP_VEND_MODEL_APP_GET;
- n = mesh_opcode_set(opcode, msg);
- /* Element Address */
- put_le16(parms[0], msg + n);
- n += 2;
- /* Model ID */
- n += put_model_id(msg + n, &parms[1], vendor);
- if (!config_send(msg, n, opcode))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_hb_pub_set(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[32];
- uint32_t parm_cnt;
- n = mesh_opcode_set(OP_CONFIG_HEARTBEAT_PUB_SET, msg);
- if (!l_queue_find(groups, match_group_addr, L_UINT_TO_PTR(parms[1])))
- add_group(parms[1]);
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 6) {
- bt_shell_printf("Bad arguments: %s\n", argv[1]);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- /* Per Mesh Profile 4.3.2.62 */
- /* Publish address */
- put_le16(parms[0], msg + n);
- n += 2;
- /* Count Log */
- msg[n++] = parms[1];
- /* Period Log */
- msg[n++] = parms[2];
- /* Heartbeat TTL */
- msg[n++] = parms[3];
- /* Features */
- put_le16(parms[4], msg + n);
- n += 2;
- /* NetKey Index */
- put_le16(parms[5], msg + n);
- n += 2;
- if (!config_send(msg, n, OP_CONFIG_HEARTBEAT_PUB_SET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_hb_pub_get(int argc, char *argv[])
- {
- cmd_default(OP_CONFIG_HEARTBEAT_PUB_GET);
- }
- static void cmd_hb_sub_set(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[32];
- uint32_t parm_cnt;
- if (IS_UNASSIGNED(target)) {
- bt_shell_printf("Destination not set\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- n = mesh_opcode_set(OP_CONFIG_HEARTBEAT_SUB_SET, msg);
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 3) {
- bt_shell_printf("Bad arguments: %s\n", argv[1]);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- if (!l_queue_find(groups, match_group_addr, L_UINT_TO_PTR(parms[1])))
- add_group(parms[1]);
- /* Per Mesh Profile 4.3.2.65 */
- /* Source address */
- put_le16(parms[0], msg + n);
- n += 2;
- /* Destination address */
- put_le16(parms[1], msg + n);
- n += 2;
- /* Period log */
- msg[n++] = parms[2];
- if (!config_send(msg, n, OP_CONFIG_HEARTBEAT_SUB_SET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_hb_sub_get(int argc, char *argv[])
- {
- cmd_default(OP_CONFIG_HEARTBEAT_SUB_GET);
- }
- static void cmd_ttl_get(int argc, char *argv[])
- {
- cmd_default(OP_CONFIG_DEFAULT_TTL_GET);
- }
- static void cmd_network_transmit_get(int argc, char *argv[])
- {
- cmd_default(OP_CONFIG_NETWORK_TRANSMIT_GET);
- }
- static void cmd_network_transmit_set(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[2 + 1];
- uint32_t parm_cnt;
- n = mesh_opcode_set(OP_CONFIG_NETWORK_TRANSMIT_SET, msg);
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 2) {
- bt_shell_printf("bad arguments\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- msg[n++] = parms[0] | (parms[1] << 3);
- if (!config_send(msg, n, OP_CONFIG_NETWORK_TRANSMIT_SET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_friend_set(int argc, char *argv[])
- {
- uint16_t n;
- uint8_t msg[2 + 1];
- uint32_t parm_cnt;
- n = mesh_opcode_set(OP_CONFIG_FRIEND_SET, msg);
- parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 1) {
- bt_shell_printf("bad arguments");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- msg[n++] = parms[0];
- if (!config_send(msg, n, OP_CONFIG_FRIEND_SET))
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_friend_get(int argc, char *argv[])
- {
- cmd_default(OP_CONFIG_FRIEND_GET);
- }
- static void cmd_node_reset(int argc, char *argv[])
- {
- uint16_t n, i;
- uint8_t msg[8];
- struct pending_req *req;
- if (IS_UNASSIGNED(target)) {
- bt_shell_printf("Destination not set\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- /* Cannot remet self */
- if (target == 0x0001) {
- bt_shell_printf("Resetting self not allowed\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- n = mesh_opcode_set(OP_NODE_RESET, msg);
- req = l_new(struct pending_req, 1);
- req->addr = target;
- req->cmd = get_cmd(OP_NODE_RESET);
- /*
- * As a courtesy to the remote node, send the reset command
- * several times. Treat this as a single request with a longer
- * response timeout.
- */
- req->timer = l_timeout_create(rsp_timeout * 2,
- wait_rsp_timeout, req, NULL);
- l_queue_push_tail(requests, req);
- for (i = 0; i < 5; i++)
- send_msg(send_data, target, APP_IDX_DEV_REMOTE, msg, n);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- static void cmd_netkey_get(int argc, char *argv[])
- {
- cmd_default(OP_NETKEY_GET);
- }
- static void print_group(void *a, void *b)
- {
- struct mesh_group *grp = a;
- char buf[33];
- if (!IS_VIRTUAL(grp->addr)) {
- bt_shell_printf("\tGroup addr: %4.4x\n", grp->addr);
- return;
- }
- hex2str(grp->label, 16, buf, sizeof(buf));
- bt_shell_printf("\tVirtual addr: %4.4x, label: %s\n", grp->addr, buf);
- }
- static void cmd_add_virt(int argc, char *argv[])
- {
- struct mesh_group *grp, *tmp;
- uint8_t max_tries = 3;
- grp = l_new(struct mesh_group, 1);
- retry:
- l_getrandom(grp->label, 16);
- mesh_crypto_virtual_addr(grp->label, &grp->addr);
- /* For simplicity sake, avoid labels that map to the same hash */
- tmp = l_queue_find(groups, match_group_addr, L_UINT_TO_PTR(grp->addr));
- if (!tmp) {
- l_queue_insert(groups, grp, compare_group_addr, NULL);
- print_group(grp, NULL);
- mesh_db_add_group(grp);
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- max_tries--;
- if (max_tries)
- goto retry;
- l_free(grp);
- bt_shell_printf("Failed to generate unique label. Try again.");
- bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- static void cmd_list_groups(int argc, char *argv[])
- {
- l_queue_foreach(groups, print_group, NULL);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- static bool tx_setup(model_send_msg_func_t send_func, void *user_data)
- {
- if (!send_func)
- return false;
- send_msg = send_func;
- send_data = user_data;
- return true;
- }
- static const struct bt_shell_menu cfg_menu = {
- .name = "config",
- .desc = "Configuration Model Submenu",
- .entries = {
- {"target", "<unicast>", cmd_dst_set,
- "Set target node to configure"},
- {"timeout", "<seconds>", cmd_timeout_set,
- "Set response timeout (seconds)"},
- {"composition-get", "[page_num]", cmd_composition_get,
- "Get composition data"},
- {"netkey-add", "<net_idx>", cmd_netkey_add,
- "Add NetKey"},
- {"netkey-update", "<net_idx>", cmd_netkey_update,
- "Update NetKey"},
- {"netkey-del", "<net_idx>", cmd_netkey_del,
- "Delete NetKey"},
- {"netkey-get", NULL, cmd_netkey_get,
- "List NetKeys known to the node"},
- {"kr-phase-get", "<net_idx>", cmd_kr_phase_get,
- "Get Key Refresh phase of a NetKey"},
- {"kr-phase-set", "<net_idx> <phase>", cmd_kr_phase_set,
- "Set Key Refresh phase transition of a NetKey"},
- {"appkey-add", "<app_idx>", cmd_appkey_add,
- "Add AppKey"},
- {"appkey-update", "<app_idx>", cmd_appkey_update,
- "Add AppKey"},
- {"appkey-del", "<app_idx>", cmd_appkey_del,
- "Delete AppKey"},
- {"appkey-get", "<net_idx>", cmd_appkey_get,
- "List AppKeys bound to the NetKey"},
- {"bind", "<ele_addr> <app_idx> <model_id> [vendor_id]", cmd_add_binding,
- "Bind AppKey to a model"},
- {"unbind", "<ele_addr> <app_idx> <model_id> [vendor_id]",
- cmd_del_binding,
- "Remove AppKey from a model"},
- {"mod-appidx-get", "<ele_addr> <model_id> [vendor_id]",
- cmd_mod_appidx_get,
- "Get model app_idx"},
- {"ttl-set", "<ttl>", cmd_ttl_set,
- "Set default TTL"},
- {"ttl-get", NULL, cmd_ttl_get,
- "Get default TTL"},
- {"pub-set", "<ele_addr> <pub_addr> <app_idx> <per (step|res)> "
- "<re-xmt (cnt|per)> <model_id> [vendor_id]",
- cmd_pub_set,
- "Set publication"},
- {"pub-get", "<ele_addr> <model_id> [vendor_id]", cmd_pub_get,
- "Get publication"},
- {"proxy-set", "<proxy>", cmd_proxy_set,
- "Set proxy state"},
- {"proxy-get", NULL, cmd_proxy_get,
- "Get proxy state"},
- {"ident-set", "<net_idx> <state>", cmd_ident_set,
- "Set node identity state"},
- {"ident-get", "<net_idx>", cmd_ident_get,
- "Get node identity state"},
- {"beacon-set", "<state>", cmd_beacon_set,
- "Set node identity state"},
- {"beacon-get", NULL, cmd_beacon_get,
- "Get node beacon state"},
- {"relay-set", "<relay> <rexmt count> <rexmt steps>", cmd_relay_set,
- "Set relay"},
- {"relay-get", NULL, cmd_relay_get,
- "Get relay"},
- {"friend-set", "<state>", cmd_friend_set,
- "Set friend state"},
- {"friend-get", NULL, cmd_friend_get,
- "Get friend state"},
- {"network-transmit-get", NULL, cmd_network_transmit_get,
- "Get network transmit state"},
- {"network-transmit-set", "<count> <steps>", cmd_network_transmit_set,
- "Set network transmit state"},
- {"hb-pub-set", "<pub_addr> <count> <period> <ttl> <features> <net_idx>",
- cmd_hb_pub_set,
- "Set heartbeat publish"},
- {"hb-pub-get", NULL, cmd_hb_pub_get,
- "Get heartbeat publish"},
- {"hb-sub-set", "<src_addr> <dst_addr> <period>", cmd_hb_sub_set,
- "Set heartbeat subscribe"},
- {"hb-sub-get", NULL, cmd_hb_sub_get,
- "Get heartbeat subscribe"},
- {"virt-add", NULL, cmd_add_virt, "Generate and add a virtual label"},
- {"group-list", NULL, cmd_list_groups,
- "Display existing group addresses and virtual labels"},
- {"sub-add", "<ele_addr> <sub_addr> <model_id> [vendor]",
- cmd_sub_add, "Add subscription"},
- {"sub-del", "<ele_addr> <sub_addr> <model_id> [vendor]",
- cmd_sub_del, "Delete subscription"},
- {"sub-wrt", "<ele_addr> <sub_addr> <model_id> [vendor]",
- cmd_sub_ovwrt, "Overwrite subscription"},
- {"sub-del-all", "<ele_addr> <model_id> [vendor]", cmd_sub_del_all,
- "Delete subscription"},
- {"sub-get", "<ele_addr> <model_id> [vendor]", cmd_sub_get,
- "Get subscription"},
- {"node-reset", NULL, cmd_node_reset,
- "Reset a node and remove it from network"},
- {} },
- };
- static struct model_info cli_info = {
- .ops = {
- .set_send_func = tx_setup,
- .set_pub_func = NULL,
- .recv = msg_recvd,
- .bind = NULL,
- .pub = NULL
- },
- .mod_id = CONFIG_CLIENT_MODEL_ID,
- .vendor_id = VENDOR_ID_INVALID
- };
- struct model_info *cfgcli_init(key_send_func_t key_send,
- delete_remote_func_t del_node, void *user_data)
- {
- if (!key_send)
- return NULL;
- send_key_msg = key_send;
- key_data = user_data;
- mgr_del_remote = del_node;
- requests = l_queue_new();
- groups = mesh_db_load_groups();
- bt_shell_add_submenu(&cfg_menu);
- return &cli_info;
- }
- void cfgcli_cleanup(void)
- {
- l_queue_destroy(requests, free_request);
- l_queue_destroy(groups, l_free);
- }
|