From patchwork Thu Sep 23 03:25:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511901 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B1630C433EF for ; Thu, 23 Sep 2021 03:27:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 888E1610A1 for ; Thu, 23 Sep 2021 03:27:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239049AbhIWD2l (ORCPT ); Wed, 22 Sep 2021 23:28:41 -0400 Received: from mga11.intel.com ([192.55.52.93]:16373 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239035AbhIWD2k (ORCPT ); Wed, 22 Sep 2021 23:28:40 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555893" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555893" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:50 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072324" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:50 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 01/20] tools/mesh-cfgclient: Save provisioner info Date: Wed, 22 Sep 2021 20:25:44 -0700 Message-Id: <20210923032603.50536-2-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This adds "provisioners" property to the config database. The property includes the provisioner's name, UUID of the provisioner device (corresponds to the local node), allocated unicast, group and scene ranges. The current implementation limitations: - only one provisioner in the mesh network is supported, - the unicast range is assumed to be contiguous, - the group range is assumed to be contiguous, - no support for scenes (empty array). --- tools/mesh-cfgclient.c | 5 +- tools/mesh/mesh-db.c | 110 ++++++++++++++++++++++++++++++++++++----- tools/mesh/mesh-db.h | 1 - 3 files changed, 103 insertions(+), 13 deletions(-) diff --git a/tools/mesh-cfgclient.c b/tools/mesh-cfgclient.c index 70553c95c..62dcecb2f 100644 --- a/tools/mesh-cfgclient.c +++ b/tools/mesh-cfgclient.c @@ -1823,13 +1823,16 @@ static struct l_dbus_message *join_complete(struct l_dbus *dbus, return l_dbus_message_new_error(message, dbus_err_fail, NULL); } - mesh_db_set_addr_range(low_addr, high_addr); keys_add_net_key(PRIMARY_NET_IDX); mesh_db_net_key_add(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); diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index 034d7be2b..50fbc18cb 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -245,7 +245,7 @@ static json_object *get_node_by_uuid(json_object *jcfg, uint8_t uuid[16]) const char *str; jentry = json_object_array_get_idx(jarray, i); - if (!json_object_object_get_ex(jentry, "uuid", &jval)) + if (!json_object_object_get_ex(jentry, "UUID", &jval)) return NULL; str = json_object_get_string(jval); @@ -429,7 +429,7 @@ static void load_remotes(json_object *jcfg) if (!jnode) continue; - if (!json_object_object_get_ex(jnode, "uuid", &jval)) + if (!json_object_object_get_ex(jnode, "UUID", &jval)) continue; str = json_object_get_string(jval); @@ -931,7 +931,7 @@ bool mesh_db_add_node(uint8_t uuid[16], uint8_t num_els, uint16_t unicast, if (!jnode) return false; - if (!add_u8_16(jnode, "uuid", uuid)) + if (!add_u8_16(jnode, "UUID", uuid)) goto fail; jelements = init_elements(num_els); @@ -1188,14 +1188,32 @@ bool mesh_db_get_token(uint8_t token[8]) bool mesh_db_get_addr_range(uint16_t *low, uint16_t *high) { - json_object *jlow, *jhigh; + json_object *jprov, *jarray, *jobj, *jlow, *jhigh; const char *str; if (!cfg || !cfg->jcfg) return false; - if (!json_object_object_get_ex(cfg->jcfg, "low", &jlow) || - !json_object_object_get_ex(cfg->jcfg, "high", &jhigh)) + jarray = json_object_object_get(cfg->jcfg, "provisioniers"); + + if (!jarray || json_object_get_type(jarray) != json_type_array) + return false; + + /* Assumption: only one provisioner in the system */ + jprov = json_object_array_get_idx(jarray, 0); + if (!jprov) + return false; + + if (!json_object_object_get_ex(jprov, "allocatedUnicastRange", &jarray)) + return false; + + /* Assumption: only one contiguous range is specified */ + jobj = json_object_array_get_idx(jarray, 0); + if (!jobj) + return false; + + if (!json_object_object_get_ex(jobj, "lowAddress", &jlow) || + !json_object_object_get_ex(jobj, "highAddress", &jhigh)) return false; str = json_object_get_string(jlow); @@ -1209,18 +1227,82 @@ bool mesh_db_get_addr_range(uint16_t *low, uint16_t *high) return true; } -bool mesh_db_set_addr_range(uint16_t low, uint16_t high) +/* + * This is a simplistic implementation onf allocated range, where + * the range is one contiguous chunk of the address space. + */ +static bool add_range(json_object *jobj, const char *keyword, uint16_t low, + uint16_t high) { + json_object *jarray, *jrange; + + jrange = json_object_new_object(); + + if (!write_uint16_hex(jrange, "lowAddress", low)) + goto fail; + + if (!write_uint16_hex(jrange, "highAddress", high)) + goto fail; + + jarray = json_object_new_array(); + if (!jarray) + goto fail; + + json_object_array_add(jarray, jrange); + json_object_object_add(jobj, keyword, jarray); + + return true; + +fail: + json_object_put(jrange); + + return false; +} + +bool mesh_db_add_provisioner(const char *name, uint8_t uuid[16], + uint16_t unicast_low, uint16_t unicast_high, + uint16_t group_low, uint16_t group_high) +{ + json_object *jprovs, *jprov, *jscenes; + if (!cfg || !cfg->jcfg) return false; - if (!write_uint16_hex(cfg->jcfg, "low", low)) + if (!json_object_object_get_ex(cfg->jcfg, "provisioners", &jprovs)) return false; - if (!write_uint16_hex(cfg->jcfg, "high", high)) + if (!jprovs || json_object_get_type(jprovs) != json_type_array) return false; + jprov = json_object_new_object(); + + if (!add_string(jprov, "provisionerName", name)) + goto fail; + + if (!add_u8_16(jprov, "UUID", uuid)) + goto fail; + + if (!add_range(jprov, "allocatedUnicastRange", unicast_low, + unicast_high)) + goto fail; + + if (!add_range(jprov, "allocatedGroupRange", group_low, group_high)) + goto fail; + + /* Scenes are not supported. Just add an empty array */ + jscenes = json_object_new_array(); + if (!jscenes) + goto fail; + + json_object_object_add(jprov, "allocatedSceneRange", jscenes); + + json_object_array_add(jprovs, jprov); + return save_config(); + +fail: + json_object_put(jprov); + return false; } uint32_t mesh_db_get_iv_index(void) @@ -1408,10 +1490,10 @@ bool mesh_db_create(const char *fname, const uint8_t token[8], l_uuid_v4(uuid); - if (!add_u8_16(jcfg, "uuid", uuid)) + if (!add_u8_16(jcfg, "meshUUID", uuid)) goto fail; - if (mesh_name && !add_string(jcfg, "name", mesh_name)) + if (mesh_name && !add_string(jcfg, "meshName", mesh_name)) goto fail; jarray = json_object_new_array(); @@ -1420,6 +1502,12 @@ bool mesh_db_create(const char *fname, const uint8_t token[8], json_object_object_add(jcfg, "nodes", jarray); + jarray = json_object_new_array(); + if (!jarray) + goto fail; + + json_object_object_add(jcfg, "provisioners", jarray); + jarray = json_object_new_array(); if (!jarray) goto fail; diff --git a/tools/mesh/mesh-db.h b/tools/mesh/mesh-db.h index 22518c618..efd579553 100644 --- a/tools/mesh/mesh-db.h +++ b/tools/mesh/mesh-db.h @@ -24,7 +24,6 @@ bool mesh_db_net_key_del(uint16_t idx); bool mesh_db_net_key_phase_set(uint16_t net_idx, uint8_t phase); bool mesh_db_app_key_add(uint16_t net_idx, uint16_t app_idx); bool mesh_db_app_key_del(uint16_t app_idx); -bool mesh_db_set_addr_range(uint16_t low, uint16_t high); bool mesh_db_get_addr_range(uint16_t *low, uint16_t *high); bool mesh_db_add_node(uint8_t uuid[16], uint8_t num_els, uint16_t unicast, From patchwork Thu Sep 23 03:25:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511905 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AA711C433F5 for ; Thu, 23 Sep 2021 03:27:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8613C610A1 for ; Thu, 23 Sep 2021 03:27:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239059AbhIWD2o (ORCPT ); Wed, 22 Sep 2021 23:28:44 -0400 Received: from mga11.intel.com ([192.55.52.93]:16373 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239045AbhIWD2l (ORCPT ); Wed, 22 Sep 2021 23:28:41 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555895" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555895" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:52 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072328" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:51 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 02/20] tools/mesh-cfgclient: Add timestamp to config database Date: Wed, 22 Sep 2021 20:25:45 -0700 Message-Id: <20210923032603.50536-3-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This adds timestamp property to the configuration database. The UTC timestamp format: YYYY-MM-DDThh:mm:ssZ --- tools/mesh/mesh-db.c | 56 +++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index 50fbc18cb..d42587da8 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -3,7 +3,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2019 Intel Corporation. All rights reserved. + * Copyright (C) 2019-2020 Intel Corporation. All rights reserved. * * */ @@ -20,10 +20,9 @@ #include #include #include +#include #include -#include - #include #include @@ -42,13 +41,39 @@ struct mesh_db { json_object *jcfg; char *cfg_fname; uint8_t token[8]; - struct timeval write_time; }; static struct mesh_db *cfg; static const char *bak_ext = ".bak"; static const char *tmp_ext = ".tmp"; +static bool add_string(json_object *jobj, const char *desc, const char *str) +{ + json_object *jstring = json_object_new_string(str); + + if (!jstring) + return false; + + json_object_object_add(jobj, desc, jstring); + return true; +} + +static bool set_timestamp(json_object *jobj) +{ + time_t time_raw; + struct tm *tp; + char buf[80]; + + time(&time_raw); + tp = gmtime(&time_raw); + + strftime(buf, 80, "%FT%TZ", tp); + + json_object_object_del(jobj, "timestamp"); + + return add_string(jobj, "timestamp", buf); +} + static bool save_config_file(const char *fname) { FILE *outfile; @@ -61,6 +86,8 @@ static bool save_config_file(const char *fname) return false; } + set_timestamp(cfg->jcfg); + str = json_object_to_json_string_ext(cfg->jcfg, JSON_C_TO_STRING_PRETTY); @@ -97,8 +124,6 @@ static bool save_config(void) l_free(fname_tmp); l_free(fname_bak); - gettimeofday(&cfg->write_time, NULL); - return result; } @@ -289,17 +314,6 @@ static bool add_u8_16(json_object *jobj, const char *desc, return true; } -static bool add_string(json_object *jobj, const char *desc, const char *str) -{ - json_object *jstring = json_object_new_string(str); - - if (!jstring) - return false; - - json_object_object_add(jobj, desc, jstring); - return true; -} - static bool get_token(json_object *jobj, uint8_t token[8]) { json_object *jval; @@ -726,6 +740,9 @@ bool mesh_db_net_key_add(uint16_t net_idx) if (!write_int(jkey, "phase", KEY_REFRESH_PHASE_NONE)) goto fail; + if (!set_timestamp(jkey)) + goto fail; + json_object_array_add(jarray, jkey); return save_config(); @@ -960,10 +977,7 @@ bool mesh_db_add_node(uint8_t uuid[16], uint8_t num_els, uint16_t unicast, json_object_array_add(jnodes, jnode); - if (!save_config()) - goto fail; - - return true; + return save_config(); fail: json_object_put(jnode); From patchwork Thu Sep 23 03:25:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511903 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05BB8C433FE for ; Thu, 23 Sep 2021 03:27:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DC3FD610A1 for ; Thu, 23 Sep 2021 03:27:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239053AbhIWD2n (ORCPT ); Wed, 22 Sep 2021 23:28:43 -0400 Received: from mga11.intel.com ([192.55.52.93]:16373 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239042AbhIWD2l (ORCPT ); Wed, 22 Sep 2021 23:28:41 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555898" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555898" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:53 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072335" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:52 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 03/20] tools/mesh-cfgclient: Update stored NetKey and AppKey Date: Wed, 22 Sep 2021 20:25:46 -0700 Message-Id: <20210923032603.50536-4-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org NetKeys: - Record additional properties: "name", "minSecurity", "timestamp" AppKeys: - Record additional property: "name" --- tools/mesh/mesh-db.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index d42587da8..5b3c4b2f7 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -517,6 +517,7 @@ static void load_remotes(json_object *jcfg) static bool add_app_key(json_object *jobj, uint16_t net_idx, uint16_t app_idx) { json_object *jkey, *jarray; + char buf[12]; json_object_object_get_ex(jobj, "appKeys", &jarray); if (!jarray || json_object_get_type(jarray) != json_type_array) @@ -524,6 +525,11 @@ static bool add_app_key(json_object *jobj, uint16_t net_idx, uint16_t app_idx) jkey = json_object_new_object(); + snprintf(buf, 12, "AppKey %4.4x", app_idx); + + if (!add_string(jkey, "name", buf)) + goto fail; + if (!write_int(jkey, "boundNetKey", (int)net_idx)) goto fail; @@ -721,6 +727,7 @@ static bool load_keys(json_object *jobj) bool mesh_db_net_key_add(uint16_t net_idx) { json_object *jkey, *jarray; + char buf[12]; if (!cfg || !cfg->jcfg) return false; @@ -734,12 +741,20 @@ bool mesh_db_net_key_add(uint16_t net_idx) jkey = json_object_new_object(); + snprintf(buf, 12, "Subnet %4.4x", net_idx); + + if (!add_string(jkey, "name", buf)) + goto fail; + if (!write_int(jkey, "index", net_idx)) goto fail; if (!write_int(jkey, "phase", KEY_REFRESH_PHASE_NONE)) goto fail; + if (!add_string(jkey, "minSecurity", "secure")) + goto fail; + if (!set_timestamp(jkey)) goto fail; From patchwork Thu Sep 23 03:25:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511907 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 195BCC4332F for ; Thu, 23 Sep 2021 03:27:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EA59A61130 for ; Thu, 23 Sep 2021 03:27:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239056AbhIWD2o (ORCPT ); Wed, 22 Sep 2021 23:28:44 -0400 Received: from mga11.intel.com ([192.55.52.93]:16377 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239046AbhIWD2l (ORCPT ); Wed, 22 Sep 2021 23:28:41 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555900" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555900" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:53 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072340" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:53 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 04/20] tools/mesh-cfgclient: Keep track of updated keys Date: Wed, 22 Sep 2021 20:25:47 -0700 Message-Id: <20210923032603.50536-5-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org --- tools/mesh/cfgcli.c | 33 ++++---- tools/mesh/mesh-db.c | 151 ++++++++++++++++++++++++++++++----- tools/mesh/mesh-db.h | 2 + tools/mesh/remote.c | 182 +++++++++++++++++++++++++++++++++---------- tools/mesh/remote.h | 9 ++- 5 files changed, 299 insertions(+), 78 deletions(-) diff --git a/tools/mesh/cfgcli.c b/tools/mesh/cfgcli.c index d8eee4edc..485d13b5a 100644 --- a/tools/mesh/cfgcli.c +++ b/tools/mesh/cfgcli.c @@ -447,13 +447,12 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, if (!cmd) break; - if (cmd->opcode == OP_APPKEY_ADD) { - if (remote_add_app_key(src, app_idx)) - mesh_db_node_app_key_add(src, app_idx); - } else if (cmd->opcode == OP_APPKEY_DELETE) { - if (remote_del_app_key(src, app_idx)) - mesh_db_node_app_key_del(src, app_idx); - } + if (cmd->opcode == OP_APPKEY_ADD) + remote_add_app_key(src, app_idx, true); + else if (cmd->opcode == OP_APPKEY_DELETE) + remote_del_app_key(src, app_idx); + else if (cmd->opcode == OP_APPKEY_UPDATE) + remote_update_app_key(src, app_idx, true, true); break; @@ -492,13 +491,12 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, if (!cmd) break; - if (cmd->opcode == OP_NETKEY_ADD) { - if (remote_add_net_key(src, net_idx)) - mesh_db_node_net_key_add(src, net_idx); - } else if (cmd->opcode == OP_NETKEY_DELETE) { - if (remote_del_net_key(src, net_idx)) - mesh_db_node_net_key_del(src, net_idx); - } + if (cmd->opcode == OP_NETKEY_ADD) + remote_add_net_key(src, net_idx, true); + else if (cmd->opcode == OP_NETKEY_DELETE) + remote_del_net_key(src, net_idx); + else if (cmd->opcode == OP_NETKEY_UPDATE) + remote_update_net_key(src, net_idx, true, true); break; @@ -534,6 +532,13 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, 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) + remote_finish_key_refresh(src, net_idx); + break; case OP_MODEL_APP_STATUS: diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index 5b3c4b2f7..a57a5d547 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -200,6 +200,38 @@ static bool write_int(json_object *jobj, const char *keyword, int val) return true; } +static bool get_bool(json_object *jobj, const char *keyword, bool *value) +{ + json_object *jvalue; + + if (!json_object_object_get_ex(jobj, keyword, &jvalue)) + return false; + + if (json_object_get_type(jvalue) != json_type_boolean) { + l_error("Error: %s should contain a boolean value\n", + keyword); + return false; + } + + *value = json_object_get_boolean(jvalue); + + return true; +} + +static bool write_bool(json_object *jobj, const char *keyword, bool val) +{ + json_object *jval; + + json_object_object_del(jobj, keyword); + + jval = json_object_new_boolean(val); + if (!jval) + return false; + + json_object_object_add(jobj, keyword, jval); + return true; +} + static json_object *get_key_object(json_object *jarray, uint16_t idx) { int i, sz = json_object_array_length(jarray); @@ -347,6 +379,20 @@ static uint16_t node_parse_key(json_object *jarray, int i) return (uint16_t)idx; } +static bool node_check_key_updated(json_object *jarray, int i, bool *updated) +{ + json_object *jkey; + + jkey = json_object_array_get_idx(jarray, i); + if (!jkey) + return false; + + if (!get_bool(jkey, "updated", updated)) + return false; + + return true; +} + static int compare_group_addr(const void *a, const void *b, void *user_data) { const struct mesh_group *grp0 = a; @@ -483,10 +529,17 @@ static void load_remotes(json_object *jcfg) remote_add_node((const uint8_t *)uuid, unicast, ele_cnt, key_idx); for (j = 1; j < key_cnt; j++) { + bool updated = false; + key_idx = node_parse_key(jarray, j); - if (key_idx != KEY_IDX_INVALID) - remote_add_net_key(unicast, key_idx); + if (key_idx == KEY_IDX_INVALID) + continue; + + remote_add_net_key(unicast, key_idx, false); + + node_check_key_updated(jarray, j, &updated); + remote_update_net_key(unicast, key_idx, updated, false); } json_object_object_get_ex(jnode, "appKeys", &jarray); @@ -496,10 +549,17 @@ static void load_remotes(json_object *jcfg) key_cnt = json_object_array_length(jarray); for (j = 0; j < key_cnt; j++) { + bool updated = false; + key_idx = node_parse_key(jarray, j); - if (key_idx != KEY_IDX_INVALID) - remote_add_app_key(unicast, key_idx); + if (key_idx == KEY_IDX_INVALID) + continue; + + remote_add_app_key(unicast, key_idx, false); + + node_check_key_updated(jarray, j, &updated); + remote_update_app_key(unicast, key_idx, updated, false); } load_composition(jnode, unicast); @@ -554,28 +614,19 @@ static bool add_node_key(json_object *jobj, const char *desc, uint16_t idx) jkey = json_object_new_object(); - if (!write_int(jkey, "index", (int)idx)) { - json_object_put(jkey); - return false; - } + if (!write_int(jkey, "index", (int)idx)) + goto fail; + + if (!write_bool(jkey, "updated", false)) + goto fail; json_object_array_add(jarray, jkey); return save_config(); -} - -bool mesh_db_node_net_key_add(uint16_t unicast, uint16_t idx) -{ - json_object *jnode; - - if (!cfg || !cfg->jcfg) - return false; - jnode = get_node_by_unicast(unicast); - if (!jnode) - return false; - - return add_node_key(jnode, "netKeys", idx); +fail: + json_object_put(jkey); + return false; } bool mesh_db_node_ttl_set(uint16_t unicast, uint8_t ttl) @@ -628,6 +679,20 @@ static bool delete_key(json_object *jobj, const char *desc, uint16_t idx) return save_config(); } +bool mesh_db_node_net_key_add(uint16_t unicast, uint16_t idx) +{ + json_object *jnode; + + if (!cfg || !cfg->jcfg) + return false; + + jnode = get_node_by_unicast(unicast); + if (!jnode) + return false; + + return add_node_key(jnode, "netKeys", idx); +} + bool mesh_db_node_net_key_del(uint16_t unicast, uint16_t net_idx) { json_object *jnode; @@ -642,6 +707,45 @@ bool mesh_db_node_net_key_del(uint16_t unicast, uint16_t net_idx) return delete_key(jnode, "netKeys", net_idx); } +static bool key_update(uint16_t unicast, int16_t idx, bool updated, + const char *desc) +{ + json_object *jnode, *jarray; + int i, sz; + + if (!cfg || !cfg->jcfg) + return false; + + jnode = get_node_by_unicast(unicast); + if (!jnode) + return false; + + if (!json_object_object_get_ex(jnode, desc, &jarray)) + return false; + + sz = json_object_array_length(jarray); + + for (i = 0; i < sz; ++i) { + json_object *jentry; + int val; + + jentry = json_object_array_get_idx(jarray, i); + + if (!get_int(jentry, "index", &val)) + continue; + + if ((val == idx) && write_bool(jentry, "updated", updated)) + return save_config(); + } + + return false; +} + +bool mesh_db_node_net_key_update(uint16_t unicast, uint16_t idx, bool updated) +{ + return key_update(unicast, idx, updated, "netKeys"); +} + bool mesh_db_node_app_key_add(uint16_t unicast, uint16_t idx) { json_object *jnode; @@ -670,6 +774,11 @@ bool mesh_db_node_app_key_del(uint16_t unicast, uint16_t idx) return delete_key(jnode, "appKeys", idx); } +bool mesh_db_node_app_key_update(uint16_t unicast, uint16_t idx, bool updated) +{ + return key_update(unicast, idx, updated, "appKeys"); +} + static bool load_keys(json_object *jobj) { json_object *jarray, *jentry; diff --git a/tools/mesh/mesh-db.h b/tools/mesh/mesh-db.h index efd579553..c1bcb3ae6 100644 --- a/tools/mesh/mesh-db.h +++ b/tools/mesh/mesh-db.h @@ -38,8 +38,10 @@ bool mesh_db_node_set_net_transmit(uint16_t unicast, uint8_t cnt, uint16_t interval); bool mesh_db_node_net_key_add(uint16_t unicast, uint16_t idx); bool mesh_db_node_net_key_del(uint16_t unicast, uint16_t idx); +bool mesh_db_node_net_key_update(uint16_t unicast, uint16_t idx, bool updated); bool mesh_db_node_app_key_add(uint16_t unicast, uint16_t idx); bool mesh_db_node_app_key_del(uint16_t unicast, uint16_t idx); +bool mesh_db_node_app_key_update(uint16_t unicast, uint16_t idx, bool updated); bool mesh_db_node_ttl_set(uint16_t unicast, uint8_t ttl); bool mesh_db_node_write_mode(uint16_t unicast, const char *keyword, int value); bool mesh_db_node_model_binding_add(uint16_t unicast, uint8_t ele, bool vendor, diff --git a/tools/mesh/remote.c b/tools/mesh/remote.c index e60a3681d..5f598cb8b 100644 --- a/tools/mesh/remote.c +++ b/tools/mesh/remote.c @@ -25,6 +25,11 @@ #define abs_diff(a, b) ((a) > (b) ? (a) - (b) : (b) - (a)) +struct remote_key { + uint16_t idx; + bool updated; +}; + struct remote_node { uint16_t unicast; struct l_queue *net_keys; @@ -42,20 +47,6 @@ struct rejected_addr { static struct l_queue *nodes; static struct l_queue *reject_list; -static bool key_present(struct l_queue *keys, uint16_t app_idx) -{ - const struct l_queue_entry *l; - - for (l = l_queue_get_entries(keys); l; l = l->next) { - uint16_t idx = L_PTR_TO_UINT(l->data); - - if (idx == app_idx) - return true; - } - - return false; -} - static int compare_mod_id(const void *a, const void *b, void *user_data) { uint32_t id1 = L_PTR_TO_UINT(a); @@ -102,12 +93,20 @@ static bool match_node_addr(const void *a, const void *b) return false; } +static bool match_key(const void *a, const void *b) +{ + const struct remote_key *key = a; + uint16_t idx = L_PTR_TO_UINT(b); + + return (key->idx == idx); +} + static bool match_bound_key(const void *a, const void *b) { - uint16_t app_idx = L_PTR_TO_UINT(a); + const struct remote_key *app_key = a; uint16_t net_idx = L_PTR_TO_UINT(b); - return (net_idx == keys_get_bound_key(app_idx)); + return (net_idx == keys_get_bound_key(app_key->idx)); } uint8_t remote_del_node(uint16_t unicast) @@ -142,6 +141,7 @@ bool remote_add_node(const uint8_t uuid[16], uint16_t unicast, uint8_t ele_cnt, uint16_t net_idx) { struct remote_node *rmt; + struct remote_key *key; rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(unicast)); if (rmt) @@ -153,7 +153,10 @@ bool remote_add_node(const uint8_t uuid[16], uint16_t unicast, rmt->num_ele = ele_cnt; rmt->net_keys = l_queue_new(); - l_queue_push_tail(rmt->net_keys, L_UINT_TO_PTR(net_idx)); + key = l_new(struct remote_key, 1); + key->idx = net_idx; + + l_queue_push_tail(rmt->net_keys, key); rmt->els = l_new(struct l_queue *, ele_cnt); @@ -161,6 +164,7 @@ bool remote_add_node(const uint8_t uuid[16], uint16_t unicast, nodes = l_queue_new(); l_queue_insert(nodes, rmt, compare_unicast, NULL); + return true; } @@ -188,49 +192,84 @@ bool remote_set_model(uint16_t unicast, uint8_t ele_idx, uint32_t mod_id, return true; } -bool remote_add_net_key(uint16_t addr, uint16_t net_idx) +bool remote_add_net_key(uint16_t addr, uint16_t net_idx, bool save) { struct remote_node *rmt; + struct remote_key *key; rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr)); if (!rmt) return false; - if (key_present(rmt->net_keys, net_idx)) - return false; + if (l_queue_find(rmt->net_keys, match_key, L_UINT_TO_PTR(net_idx))) + return true; - l_queue_push_tail(rmt->net_keys, L_UINT_TO_PTR(net_idx)); - return true; + key = l_new(struct remote_key, 1); + key->idx = net_idx; + + l_queue_push_tail(rmt->net_keys, key); + + if (save) + return mesh_db_node_net_key_add(addr, net_idx); + else + return true; } bool remote_del_net_key(uint16_t addr, uint16_t net_idx) { struct remote_node *rmt; - void *data; + struct remote_key *key; rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr)); if (!rmt) return false; - if (!l_queue_remove(rmt->net_keys, L_UINT_TO_PTR(net_idx))) + key = l_queue_remove_if(rmt->net_keys, match_key, + L_UINT_TO_PTR(net_idx)); + if (!key) return false; - data = l_queue_remove_if(rmt->app_keys, match_bound_key, + mesh_db_node_net_key_del(addr, net_idx); + + l_free(key); + key = l_queue_remove_if(rmt->app_keys, match_bound_key, L_UINT_TO_PTR(net_idx)); - while (data) { - uint16_t app_idx = (uint16_t) L_PTR_TO_UINT(data); - mesh_db_node_app_key_del(rmt->unicast, app_idx); - data = l_queue_remove_if(rmt->app_keys, match_bound_key, + while (key) { + mesh_db_node_app_key_del(rmt->unicast, key->idx); + l_free(key); + + key = l_queue_remove_if(rmt->app_keys, match_bound_key, L_UINT_TO_PTR(net_idx)); } return true; } -bool remote_add_app_key(uint16_t addr, uint16_t app_idx) +bool remote_update_net_key(uint16_t addr, uint16_t net_idx, bool update, + bool save) +{ + struct remote_node *rmt; + struct remote_key *key; + + rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr)); + if (!rmt) + return false; + + key = l_queue_find(rmt->net_keys, match_key, + L_UINT_TO_PTR(net_idx)); + key->updated = update; + + if (save) + return mesh_db_node_net_key_update(addr, net_idx, update); + else + return true; +} + +bool remote_add_app_key(uint16_t addr, uint16_t app_idx, bool save) { struct remote_node *rmt; + struct remote_key *key; rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr)); if (!rmt) @@ -239,44 +278,105 @@ bool remote_add_app_key(uint16_t addr, uint16_t app_idx) if (!rmt->app_keys) rmt->app_keys = l_queue_new(); - if (key_present(rmt->app_keys, app_idx)) - return false; + if (l_queue_find(rmt->app_keys, match_key, L_UINT_TO_PTR(app_idx))) + return true; - l_queue_push_tail(rmt->app_keys, L_UINT_TO_PTR(app_idx)); - return true; + key = l_new(struct remote_key, 1); + key->idx = app_idx; + + l_queue_push_tail(rmt->app_keys, key); + + if (save) + return mesh_db_node_app_key_add(addr, app_idx); + else + return true; } bool remote_del_app_key(uint16_t addr, uint16_t app_idx) { struct remote_node *rmt; + struct remote_key *key; + + rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr)); + if (!rmt) + return false; + + key = l_queue_remove_if(rmt->app_keys, match_key, + L_UINT_TO_PTR(app_idx)); + l_free(key); + + return mesh_db_node_app_key_del(addr, app_idx); +} + +bool remote_update_app_key(uint16_t addr, uint16_t app_idx, bool update, + bool save) +{ + struct remote_node *rmt; + struct remote_key *key; rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr)); if (!rmt) return false; - return l_queue_remove(rmt->app_keys, L_UINT_TO_PTR(app_idx)); + key = l_queue_find(rmt->app_keys, match_key, + L_UINT_TO_PTR(app_idx)); + key->updated = update; + + if (save) + return mesh_db_node_app_key_update(addr, app_idx, update); + else + return true; +} + +void remote_finish_key_refresh(uint16_t addr, uint16_t net_idx) +{ + struct remote_node *rmt; + struct remote_key *key; + const struct l_queue_entry *l; + + rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr)); + if (!rmt) + return; + + if (!remote_update_net_key(addr, net_idx, false, true)) + return; + + l = l_queue_get_entries(rmt->app_keys); + + for (; l; l = l->next) { + key = l->data; + + if (net_idx != keys_get_bound_key(key->idx)) + continue; + + key->updated = false; + + mesh_db_node_app_key_update(addr, key->idx, false); + } + } uint16_t remote_get_subnet_idx(uint16_t addr) { struct remote_node *rmt; - uint32_t net_idx; + struct remote_key *key; rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr)); if (!rmt || l_queue_isempty(rmt->net_keys)) return NET_IDX_INVALID; - net_idx = L_PTR_TO_UINT(l_queue_peek_head(rmt->net_keys)); + key = l_queue_peek_head(rmt->net_keys); - return (uint16_t) net_idx; + return key->idx; } -static void print_key(void *key, void *user_data) +static void print_key(void *data, void *user_data) { - uint16_t idx = L_PTR_TO_UINT(key); + struct remote_key *key = data; - bt_shell_printf("%u (0x%3.3x), ", idx, idx); + bt_shell_printf("%u (0x%3.3x) %s, ", key->idx, key->idx, + key->updated ? ", updated":""); } static void print_model(void *model, void *user_data) diff --git a/tools/mesh/remote.h b/tools/mesh/remote.h index 8ecb097ae..74747689a 100644 --- a/tools/mesh/remote.h +++ b/tools/mesh/remote.h @@ -16,10 +16,15 @@ bool remote_set_model(uint16_t unicast, uint8_t ele_idx, uint32_t mod_id, void remote_add_rejected_address(uint16_t addr, uint32_t iv_index, bool save); void remote_clear_rejected_addresses(uint32_t iv_index); uint16_t remote_get_next_unicast(uint16_t low, uint16_t high, uint8_t ele_cnt); -bool remote_add_net_key(uint16_t addr, uint16_t net_idx); +bool remote_add_net_key(uint16_t addr, uint16_t net_idx, bool save); bool remote_del_net_key(uint16_t addr, uint16_t net_idx); -bool remote_add_app_key(uint16_t addr, uint16_t app_idx); +bool remote_update_net_key(uint16_t addr, uint16_t net_idx, bool update, + bool save); +bool remote_add_app_key(uint16_t addr, uint16_t app_idx, bool save); bool remote_del_app_key(uint16_t addr, uint16_t app_idx); +bool remote_update_app_key(uint16_t addr, uint16_t app_idx, bool update, + bool save); +void remote_finish_key_refresh(uint16_t addr, uint16_t net_idx); uint16_t remote_get_subnet_idx(uint16_t addr); void remote_print_node(uint16_t addr); void remote_print_all(void); From patchwork Thu Sep 23 03:25:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511911 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9F41C433FE for ; Thu, 23 Sep 2021 03:27:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8C4D66113E for ; Thu, 23 Sep 2021 03:27:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239081AbhIWD2r (ORCPT ); Wed, 22 Sep 2021 23:28:47 -0400 Received: from mga11.intel.com ([192.55.52.93]:16373 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239035AbhIWD2o (ORCPT ); Wed, 22 Sep 2021 23:28:44 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555902" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555902" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:54 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072343" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:54 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 05/20] tools/mesh: Add new info to stored remote nodes Date: Wed, 22 Sep 2021 20:25:48 -0700 Message-Id: <20210923032603.50536-6-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org When adding a new remote node into configuration database, initialize additional default properties: "blacklisted": false "security": "secure" "configComplete": false --- tools/mesh/mesh-db.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index a57a5d547..bf9344931 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -1075,7 +1075,18 @@ bool mesh_db_add_node(uint8_t uuid[16], uint8_t num_els, uint16_t unicast, if (!add_u8_16(jnode, "UUID", uuid)) goto fail; + + if (!add_string(jnode, "security", "secure")) + goto fail; + + if (!write_bool(jnode, "blacklisted", false)) + goto fail; + + if (!write_bool(jnode, "configComplete", false)) + goto fail; + jelements = init_elements(num_els); + json_object_object_add(jnode, "elements", jelements); jnetkeys = json_object_new_array(); From patchwork Thu Sep 23 03:25:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511909 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CE492C433EF for ; Thu, 23 Sep 2021 03:27:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AF18361130 for ; Thu, 23 Sep 2021 03:27:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239070AbhIWD2q (ORCPT ); Wed, 22 Sep 2021 23:28:46 -0400 Received: from mga11.intel.com ([192.55.52.93]:16381 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239050AbhIWD2o (ORCPT ); Wed, 22 Sep 2021 23:28:44 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555903" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555903" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:54 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072347" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:54 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 06/20] tools/mesh-cfgclient: Overwrite config values when adding new ones Date: Wed, 22 Sep 2021 20:25:49 -0700 Message-Id: <20210923032603.50536-7-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This changes common utilities used in mesh-db.c to replace old values by default whenever a new value is written. --- tools/mesh/mesh-db.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index bf9344931..f0e0aeb71 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -54,6 +54,9 @@ static bool add_string(json_object *jobj, const char *desc, const char *str) if (!jstring) return false; + /* Overwrite old value if present */ + json_object_object_del(jobj, desc); + json_object_object_add(jobj, desc, jstring); return true; } @@ -69,8 +72,6 @@ static bool set_timestamp(json_object *jobj) strftime(buf, 80, "%FT%TZ", tp); - json_object_object_del(jobj, "timestamp"); - return add_string(jobj, "timestamp", buf); } @@ -190,12 +191,13 @@ static bool write_int(json_object *jobj, const char *keyword, int val) { json_object *jval; - json_object_object_del(jobj, keyword); - jval = json_object_new_int(val); if (!jval) return false; + /* Overwrite old value if present */ + json_object_object_del(jobj, keyword); + json_object_object_add(jobj, keyword, jval); return true; } @@ -222,12 +224,13 @@ static bool write_bool(json_object *jobj, const char *keyword, bool val) { json_object *jval; - json_object_object_del(jobj, keyword); - jval = json_object_new_boolean(val); if (!jval) return false; + /* Overwrite old value if present */ + json_object_object_del(jobj, keyword); + json_object_object_add(jobj, keyword, jval); return true; } @@ -262,6 +265,9 @@ static bool write_uint16_hex(json_object *jobj, const char *desc, if (!jstring) return false; + /* Overwrite old value if present */ + json_object_object_del(jobj, desc); + json_object_object_add(jobj, desc, jstring); return true; } @@ -327,6 +333,9 @@ static bool add_u8_8(json_object *jobj, const char *desc, if (!jstring) return false; + /* Overwrite old value if present */ + json_object_object_del(jobj, desc); + json_object_object_add(jobj, desc, jstring); return true; } @@ -342,6 +351,9 @@ static bool add_u8_16(json_object *jobj, const char *desc, if (!jstring) return false; + /* Overwrite old value if present */ + json_object_object_del(jobj, desc); + json_object_object_add(jobj, desc, jstring); return true; } From patchwork Thu Sep 23 03:25:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511913 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5E4ABC433EF for ; Thu, 23 Sep 2021 03:27:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4327461038 for ; Thu, 23 Sep 2021 03:27:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239083AbhIWD2s (ORCPT ); Wed, 22 Sep 2021 23:28:48 -0400 Received: from mga11.intel.com ([192.55.52.93]:16377 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239054AbhIWD2o (ORCPT ); Wed, 22 Sep 2021 23:28:44 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555905" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555905" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:55 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072352" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:55 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 07/20] tools/mesh-cfgclient: Store remote node's model bindings Date: Wed, 22 Sep 2021 20:25:50 -0700 Message-Id: <20210923032603.50536-8-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Update remote node's model binding after a successful completion of "bind" or "unbind" commands. --- tools/mesh/cfgcli.c | 14 +++- tools/mesh/mesh-db.c | 166 ++++++++++++++++++++++++++++++++++++++++++- tools/mesh/mesh-db.h | 4 +- 3 files changed, 178 insertions(+), 6 deletions(-) diff --git a/tools/mesh/cfgcli.c b/tools/mesh/cfgcli.c index 485d13b5a..c3241a9b7 100644 --- a/tools/mesh/cfgcli.c +++ b/tools/mesh/cfgcli.c @@ -340,7 +340,7 @@ static void print_pub(uint16_t ele_addr, uint32_t mod_id, bt_shell_printf("\tModel: %8.8x\n", mod_id); else bt_shell_printf("\tModel: %4.4x\n", - (uint16_t) (mod_id & 0xffff)); + (uint16_t) (mod_id & ~VENDOR_ID_MASK)); bt_shell_printf("\tApp Key Idx: %u (0x%3.3x)\n", pub->app_idx, pub->app_idx); @@ -552,10 +552,20 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, bt_shell_printf("Element Addr\t%4.4x\n", addr); - print_mod_id(data + 5, len == 9, ""); + 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) + break; + + if (cmd->opcode == OP_MODEL_APP_BIND) + mesh_db_node_model_bind(src, addr, len == 9, mod_id, + app_idx); + else + mesh_db_node_model_unbind(src, addr, len == 9, mod_id, + app_idx); + break; case OP_NODE_IDENTITY_STATUS: diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index f0e0aeb71..da5817acf 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -658,6 +658,162 @@ bool mesh_db_node_ttl_set(uint16_t unicast, uint8_t ttl) return save_config(); } +static json_object *get_element(uint16_t unicast, uint16_t ele_addr) +{ + json_object *jnode, *jarray; + int i, ele_cnt; + + jnode = get_node_by_unicast(unicast); + if (!jnode) + return false; + + if (!json_object_object_get_ex(jnode, "elements", &jarray)) + return NULL; + + if (!jarray || json_object_get_type(jarray) != json_type_array) + return NULL; + + ele_cnt = json_object_array_length(jarray); + + for (i = 0; i < ele_cnt; ++i) { + json_object *jentry, *jval; + int32_t index; + + jentry = json_object_array_get_idx(jarray, i); + if (!json_object_object_get_ex(jentry, "index", &jval)) + return NULL; + + index = json_object_get_int(jval); + if (index > 0xff) + return NULL; + + if (ele_addr == unicast + index) + return jentry; + } + + return NULL; +} + +static json_object *get_model(uint16_t unicast, uint16_t ele_addr, + uint32_t mod_id, bool vendor) +{ + json_object *jelement, *jarray; + int i, sz; + + jelement = get_element(unicast, ele_addr); + if (!jelement) + return false; + + if (!json_object_object_get_ex(jelement, "models", &jarray)) + return NULL; + + if (!jarray || json_object_get_type(jarray) != json_type_array) + return NULL; + + if (!vendor) + mod_id = mod_id & ~VENDOR_ID_MASK; + + sz = json_object_array_length(jarray); + + for (i = 0; i < sz; ++i) { + json_object *jentry, *jval; + uint32_t id, len; + const char *str; + + jentry = json_object_array_get_idx(jarray, i); + if (!json_object_object_get_ex(jentry, "modelId", + &jval)) + return NULL; + + str = json_object_get_string(jval); + len = strlen(str); + if (len != 4 && len != 8) + return NULL; + + if ((len == 4 && vendor) || (len == 8 && !vendor)) + continue; + + if (sscanf(str, "%08x", &id) != 1) + return NULL; + + if (id == mod_id) + return jentry; + } + + return NULL; +} + +static void jarray_int_del(json_object *jarray, int val) +{ + int i, sz = json_object_array_length(jarray); + + for (i = 0; i < sz; ++i) { + json_object *jentry; + + jentry = json_object_array_get_idx(jarray, i); + + if (val == json_object_get_int(jentry)) { + json_object_array_del_idx(jarray, i, 1); + return; + } + } +} + +static bool update_model_int_array(uint16_t unicast, uint16_t ele_addr, + bool vendor, uint32_t mod_id, + int val, const char *keyword, bool add) +{ + json_object *jarray, *jmod, *jvalue; + + if (!cfg || !cfg->jcfg) + return false; + + jmod = get_model(unicast, ele_addr, mod_id, vendor); + if (!jmod) + return false; + + if (!json_object_object_get_ex(jmod, keyword, &jarray)) + return false; + + if (!jarray || json_object_get_type(jarray) != json_type_array) + return false; + + jarray_int_del(jarray, val); + + if (!add) + return true; + + jvalue = json_object_new_int(val); + if (!jvalue) + return false; + + json_object_array_add(jarray, jvalue); + + return save_config(); +} + +bool mesh_db_node_model_bind(uint16_t unicast, uint16_t ele_addr, bool vendor, + uint32_t mod_id, uint16_t app_idx) +{ + char buf[5]; + + snprintf(buf, 5, "%4.4x", app_idx); + + return update_model_int_array(unicast, ele_addr, vendor, mod_id, + (int) app_idx, "bind", true); +} + +bool mesh_db_node_model_unbind(uint16_t unicast, uint16_t ele_addr, bool vendor, + uint32_t mod_id, uint16_t app_idx) +{ + char buf[5]; + + snprintf(buf, 5, "%4.4x", app_idx); + + return update_model_int_array(unicast, ele_addr, vendor, mod_id, + (int) app_idx, "bind", false); +} + static void jarray_key_del(json_object *jarray, int16_t idx) { int i, sz = json_object_array_length(jarray); @@ -1172,7 +1328,7 @@ bool mesh_db_del_node(uint16_t unicast) static json_object *init_model(uint16_t mod_id) { - json_object *jmod; + json_object *jmod, *jarray; jmod = json_object_new_object(); @@ -1181,12 +1337,15 @@ static json_object *init_model(uint16_t mod_id) return NULL; } + jarray = json_object_new_array(); + json_object_object_add(jmod, "bind", jarray); + return jmod; } static json_object *init_vendor_model(uint32_t mod_id) { - json_object *jmod; + json_object *jmod, *jarray; jmod = json_object_new_object(); @@ -1195,6 +1354,9 @@ static json_object *init_vendor_model(uint32_t mod_id) return NULL; } + jarray = json_object_new_array(); + json_object_object_add(jmod, "bind", jarray); + return jmod; } diff --git a/tools/mesh/mesh-db.h b/tools/mesh/mesh-db.h index c1bcb3ae6..c3ee81457 100644 --- a/tools/mesh/mesh-db.h +++ b/tools/mesh/mesh-db.h @@ -44,9 +44,9 @@ bool mesh_db_node_app_key_del(uint16_t unicast, uint16_t idx); bool mesh_db_node_app_key_update(uint16_t unicast, uint16_t idx, bool updated); bool mesh_db_node_ttl_set(uint16_t unicast, uint8_t ttl); bool mesh_db_node_write_mode(uint16_t unicast, const char *keyword, int value); -bool mesh_db_node_model_binding_add(uint16_t unicast, uint8_t ele, bool vendor, +bool mesh_db_node_model_bind(uint16_t unicast, uint16_t ele_addr, bool vendor, uint32_t mod_id, uint16_t app_idx); -bool mesh_db_node_model_binding_del(uint16_t unicast, uint8_t ele, bool vendor, +bool mesh_db_node_model_unbind(uint16_t unicast, uint16_t ele_addr, bool vendor, uint32_t mod_id, uint16_t app_idx); struct l_queue *mesh_db_load_groups(void); bool mesh_db_add_group(struct mesh_group *grp); From patchwork Thu Sep 23 03:25:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511915 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E54DC433F5 for ; Thu, 23 Sep 2021 03:27:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E792E61038 for ; Thu, 23 Sep 2021 03:27:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239007AbhIWD2s (ORCPT ); Wed, 22 Sep 2021 23:28:48 -0400 Received: from mga11.intel.com ([192.55.52.93]:16373 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239042AbhIWD2o (ORCPT ); Wed, 22 Sep 2021 23:28:44 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555910" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555910" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:56 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072356" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:55 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 08/20] tools/mesh-cfgclient: Store remote node's model subs Date: Wed, 22 Sep 2021 20:25:51 -0700 Message-Id: <20210923032603.50536-9-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Update remote node's model subscriptions after a successful completion of "sub-add", "sub-del", "sub-wrt" and "sub-del_all" commands. --- tools/mesh/cfgcli.c | 68 +++++++++++++---- tools/mesh/mesh-db.c | 178 +++++++++++++++++++++++++++++++++++++++++++ tools/mesh/mesh-db.h | 17 +++++ 3 files changed, 250 insertions(+), 13 deletions(-) diff --git a/tools/mesh/cfgcli.c b/tools/mesh/cfgcli.c index c3241a9b7..71bf2e706 100644 --- a/tools/mesh/cfgcli.c +++ b/tools/mesh/cfgcli.c @@ -387,14 +387,21 @@ static void print_appkey_list(uint16_t len, uint8_t *data) } } +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; + uint32_t opcode, mod_id; const struct cfg_cmd *cmd; - uint16_t app_idx, net_idx, addr; - uint16_t ele_addr; - uint32_t mod_id; + uint16_t app_idx, net_idx, addr, ele_addr; + struct mesh_group *grp; struct model_pub pub; int n; struct pending_req *req; @@ -664,10 +671,53 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, addr = get_le16(data + 3); bt_shell_printf("Element Addr\t%4.4x\n", ele_addr); - print_mod_id(data + 5, len == 9, ""); + 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: + mesh_db_node_model_add_sub(src, ele_addr, len == 9, + mod_id, addr); + break; + case OP_CONFIG_MODEL_SUB_DELETE: + mesh_db_node_model_del_sub(src, ele_addr, len == 9, + mod_id, addr); + break; + case OP_CONFIG_MODEL_SUB_OVERWRITE: + mesh_db_node_model_overwrt_sub(src, ele_addr, len == 9, + mod_id, addr); + break; + case OP_CONFIG_MODEL_SUB_DELETE_ALL: + mesh_db_node_model_del_sub_all(src, ele_addr, len == 9, + mod_id); + break; + case OP_CONFIG_MODEL_SUB_VIRT_ADD: + if (grp) + 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) + 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) + 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 */ @@ -820,14 +870,6 @@ static uint32_t read_input_parameters(int argc, char *argv[]) return i; } -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 int compare_group_addr(const void *a, const void *b, void *user_data) { const struct mesh_group *grp0 = a; diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index da5817acf..1b03e2d90 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -814,6 +814,178 @@ bool mesh_db_node_model_unbind(uint16_t unicast, uint16_t ele_addr, bool vendor, (int) app_idx, "bind", false); } +static void jarray_string_del(json_object *jarray, const char *str, size_t len) +{ + int i, sz = json_object_array_length(jarray); + + for (i = 0; i < sz; ++i) { + json_object *jentry; + char *str_entry; + + jentry = json_object_array_get_idx(jarray, i); + str_entry = (char *)json_object_get_string(jentry); + + if (str_entry && (strlen(str_entry) == len) && + !strncmp(str, str_entry, len)) { + json_object_array_del_idx(jarray, i, 1); + return; + } + } +} + +static bool update_model_string_array(uint16_t unicast, uint16_t ele_addr, + bool vendor, uint32_t mod_id, + const char *str, uint32_t len, + const char *keyword, bool add) +{ + json_object *jarray, *jmod, *jstring; + + if (!cfg || !cfg->jcfg) + return false; + + jmod = get_model(unicast, ele_addr, mod_id, vendor); + if (!jmod) + return false; + + if (!json_object_object_get_ex(jmod, keyword, &jarray)) + return false; + + if (!jarray || json_object_get_type(jarray) != json_type_array) + return false; + + jarray_string_del(jarray, str, len); + + if (!add) + return true; + + jstring = json_object_new_string(str); + if (!jstring) + return false; + + json_object_array_add(jarray, jstring); + + return save_config(); +} + +bool mesh_db_node_model_add_sub(uint16_t unicast, uint16_t ele, bool vendor, + uint32_t mod_id, uint16_t addr) +{ + char buf[5]; + + snprintf(buf, 5, "%4.4x", addr); + + return update_model_string_array(unicast, ele, vendor, mod_id, buf, 4, + "subscribe", true); +} + +bool mesh_db_node_model_del_sub(uint16_t unicast, uint16_t ele, bool vendor, + uint32_t mod_id, uint16_t addr) +{ + char buf[5]; + + snprintf(buf, 5, "%4.4x", addr); + + return update_model_string_array(unicast, ele, vendor, mod_id, buf, 4, + "subscribe", false); +} + +bool mesh_db_node_model_add_sub_virt(uint16_t unicast, uint16_t ele, + bool vendor, uint32_t mod_id, + uint8_t *label) +{ + char buf[33]; + + hex2str(label, 16, buf, sizeof(buf)); + + return update_model_string_array(unicast, ele, vendor, mod_id, buf, 32, + "subscribe", true); + +} + +bool mesh_db_node_model_del_sub_virt(uint16_t unicast, uint16_t ele, + bool vendor, uint32_t mod_id, + uint8_t *label) +{ + char buf[33]; + + hex2str(label, 16, buf, sizeof(buf)); + + return update_model_string_array(unicast, ele, vendor, mod_id, buf, 32, + "subscribe", false); +} + +static json_object *delete_subs(uint16_t unicast, uint16_t ele, bool vendor, + uint32_t mod_id) +{ + json_object *jarray, *jmod; + + if (!cfg || !cfg->jcfg) + return NULL; + + jmod = get_model(unicast, ele, mod_id, vendor); + if (!jmod) + return NULL; + + json_object_object_del(jmod, "subscribe"); + + jarray = json_object_new_array(); + if (!jarray) + return NULL; + + json_object_object_add(jmod, "subscribe", jarray); + + return jarray; +} + +bool mesh_db_node_model_del_sub_all(uint16_t unicast, uint16_t ele, bool vendor, + uint32_t mod_id) +{ + + if (!delete_subs(unicast, ele, vendor, mod_id)) + return false; + + return save_config(); +} + +static bool sub_overwrite(uint16_t unicast, uint16_t ele, bool vendor, + uint32_t mod_id, char *buf) +{ + json_object *jarray, *jstring; + + jarray = delete_subs(unicast, ele, vendor, mod_id); + if (!jarray) + return false; + + jstring = json_object_new_string(buf); + if (!jstring) + return false; + + json_object_array_add(jarray, jstring); + + return save_config(); +} + +bool mesh_db_node_model_overwrt_sub(uint16_t unicast, uint16_t ele, bool vendor, + uint32_t mod_id, uint16_t addr) +{ + char buf[5]; + + snprintf(buf, 5, "%4.4x", addr); + + return sub_overwrite(unicast, ele, vendor, mod_id, buf); +} + +bool mesh_db_node_model_overwrt_sub_virt(uint16_t unicast, uint16_t ele, + bool vendor, uint32_t mod_id, + uint8_t *label) +{ + char buf[33]; + + hex2str(label, 16, buf, sizeof(buf)); + + return sub_overwrite(unicast, ele, vendor, mod_id, buf); +} + static void jarray_key_del(json_object *jarray, int16_t idx) { int i, sz = json_object_array_length(jarray); @@ -1340,6 +1512,9 @@ static json_object *init_model(uint16_t mod_id) jarray = json_object_new_array(); json_object_object_add(jmod, "bind", jarray); + jarray = json_object_new_array(); + json_object_object_add(jmod, "subscribe", jarray); + return jmod; } @@ -1357,6 +1532,9 @@ static json_object *init_vendor_model(uint32_t mod_id) jarray = json_object_new_array(); json_object_object_add(jmod, "bind", jarray); + jarray = json_object_new_array(); + json_object_object_add(jmod, "subscribe", jarray); + return jmod; } diff --git a/tools/mesh/mesh-db.h b/tools/mesh/mesh-db.h index c3ee81457..384376cbd 100644 --- a/tools/mesh/mesh-db.h +++ b/tools/mesh/mesh-db.h @@ -48,6 +48,23 @@ bool mesh_db_node_model_bind(uint16_t unicast, uint16_t ele_addr, bool vendor, uint32_t mod_id, uint16_t app_idx); bool mesh_db_node_model_unbind(uint16_t unicast, uint16_t ele_addr, bool vendor, uint32_t mod_id, uint16_t app_idx); +bool mesh_db_node_model_add_sub(uint16_t unicast, uint16_t ele, bool vendor, + uint32_t mod_id, uint16_t addr); +bool mesh_db_node_model_del_sub(uint16_t unicast, uint16_t ele, bool vendor, + uint32_t mod_id, uint16_t addr); +bool mesh_db_node_model_overwrt_sub(uint16_t unicast, uint16_t ele, bool vendor, + uint32_t mod_id, uint16_t addr); +bool mesh_db_node_model_add_sub_virt(uint16_t unicast, uint16_t ele, + bool vendor, uint32_t mod_id, + uint8_t *label); +bool mesh_db_node_model_del_sub_virt(uint16_t unicast, uint16_t ele, + bool vendor, uint32_t mod_id, + uint8_t *label); +bool mesh_db_node_model_overwrt_sub_virt(uint16_t unicast, uint16_t ele, + bool vendor, uint32_t mod_id, + uint8_t *label); +bool mesh_db_node_model_del_sub_all(uint16_t unicast, uint16_t ele, bool vendor, + uint32_t mod_id); struct l_queue *mesh_db_load_groups(void); bool mesh_db_add_group(struct mesh_group *grp); bool mesh_db_add_rejected_addr(uint16_t unicast, uint32_t iv_index); From patchwork Thu Sep 23 03:25:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511917 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2CD91C433EF for ; Thu, 23 Sep 2021 03:27:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 10D1D61130 for ; Thu, 23 Sep 2021 03:27:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239080AbhIWD2t (ORCPT ); Wed, 22 Sep 2021 23:28:49 -0400 Received: from mga11.intel.com ([192.55.52.93]:16381 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239048AbhIWD2o (ORCPT ); Wed, 22 Sep 2021 23:28:44 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555916" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555916" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:56 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072360" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:56 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 09/20] tools/mesh-cfgclient: Disallow model commands w/o composition Date: Wed, 22 Sep 2021 20:25:52 -0700 Message-Id: <20210923032603.50536-10-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org If remote node's composition hasn't been acquired, disallow commands that change model state (that is, bindings, subscriptions, publications). Prompt to run "get-composition" command first. --- tools/mesh/cfgcli.c | 26 ++++++++++++++++++++++++++ tools/mesh/mesh-db.c | 10 ++++++++-- tools/mesh/remote.c | 23 +++++++++++++++++++++++ tools/mesh/remote.h | 2 ++ 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/tools/mesh/cfgcli.c b/tools/mesh/cfgcli.c index 71bf2e706..19a42947e 100644 --- a/tools/mesh/cfgcli.c +++ b/tools/mesh/cfgcli.c @@ -434,6 +434,9 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, if (!mesh_db_node_set_composition(src, data, len)) bt_shell_printf("Failed to save node composition!\n"); + else + remote_set_composition(src, true); + break; case OP_APPKEY_STATUS: @@ -1233,6 +1236,12 @@ static void cmd_bind(uint32_t opcode, int argc, char *argv[]) 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); @@ -1429,6 +1438,12 @@ static void cmd_pub_set(int argc, char *argv[]) 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)); @@ -1523,6 +1538,12 @@ static void subscription_cmd(int argc, char *argv[], uint32_t opcode) 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)); @@ -1722,6 +1743,11 @@ static void cmd_hb_sub_set(int argc, char *argv[]) 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); diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index 1b03e2d90..8445d33f4 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -574,11 +574,17 @@ static void load_remotes(json_object *jcfg) remote_update_app_key(unicast, key_idx, updated, false); } - load_composition(jnode, unicast); + if (!load_composition(jnode, unicast)) + continue; - node_count++; + /* If "crpl" is present, composition's is available */ + jval = NULL; + if (json_object_object_get_ex(jnode, "crpl", &jval) && jval) + remote_set_composition(unicast, true); /* TODO: Add the rest of the configuration */ + + node_count++; } if (node_count != sz) diff --git a/tools/mesh/remote.c b/tools/mesh/remote.c index 5f598cb8b..2f8493f8a 100644 --- a/tools/mesh/remote.c +++ b/tools/mesh/remote.c @@ -35,6 +35,7 @@ struct remote_node { struct l_queue *net_keys; struct l_queue *app_keys; struct l_queue **els; + bool comp; uint8_t uuid[16]; uint8_t num_ele; }; @@ -192,6 +193,28 @@ bool remote_set_model(uint16_t unicast, uint8_t ele_idx, uint32_t mod_id, return true; } +void remote_set_composition(uint16_t addr, bool comp) +{ + struct remote_node *rmt; + + rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr)); + if (!rmt) + return; + + rmt->comp = comp; +} + +bool remote_has_composition(uint16_t addr) +{ + struct remote_node *rmt; + + rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr)); + if (!rmt) + return false; + + return rmt->comp; +} + bool remote_add_net_key(uint16_t addr, uint16_t net_idx, bool save) { struct remote_node *rmt; diff --git a/tools/mesh/remote.h b/tools/mesh/remote.h index 74747689a..2fb0d83ce 100644 --- a/tools/mesh/remote.h +++ b/tools/mesh/remote.h @@ -25,6 +25,8 @@ bool remote_del_app_key(uint16_t addr, uint16_t app_idx); bool remote_update_app_key(uint16_t addr, uint16_t app_idx, bool update, bool save); void remote_finish_key_refresh(uint16_t addr, uint16_t net_idx); +void remote_set_composition(uint16_t addr, bool comp); +bool remote_has_composition(uint16_t addr); uint16_t remote_get_subnet_idx(uint16_t addr); void remote_print_node(uint16_t addr); void remote_print_all(void); From patchwork Thu Sep 23 03:25:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511923 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF06EC4332F for ; Thu, 23 Sep 2021 03:27:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D7D90610A1 for ; Thu, 23 Sep 2021 03:27:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239069AbhIWD2w (ORCPT ); Wed, 22 Sep 2021 23:28:52 -0400 Received: from mga11.intel.com ([192.55.52.93]:16377 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239057AbhIWD2o (ORCPT ); Wed, 22 Sep 2021 23:28:44 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555919" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555919" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:57 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072365" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:57 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 10/20] tools/mesh-cfgclient: Store remote's model publication info Date: Wed, 22 Sep 2021 20:25:53 -0700 Message-Id: <20210923032603.50536-11-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Update remote node's model publication after a successful completion of "pub-set" or "pub-get" commands. --- tools/mesh/cfgcli.c | 42 +++++++++++++++++------ tools/mesh/mesh-db.c | 81 ++++++++++++++++++++++++++++++++++++++++++++ tools/mesh/mesh-db.h | 4 +++ tools/mesh/model.h | 13 ++++--- 4 files changed, 124 insertions(+), 16 deletions(-) diff --git a/tools/mesh/cfgcli.c b/tools/mesh/cfgcli.c index 19a42947e..2766d47ca 100644 --- a/tools/mesh/cfgcli.c +++ b/tools/mesh/cfgcli.c @@ -334,7 +334,7 @@ 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.addr16); + 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); @@ -634,31 +634,51 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, mod_id = print_mod_id(data + 10, len == 14, ""); - pub.u.addr16 = get_le16(data + 3); + 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.period = data[8]; - n = (data[8] & 0x3f); + pub.prd_steps = (data[8] & 0x3f); print_pub(ele_addr, mod_id, &pub); switch (data[8] >> 6) { case 0: - bt_shell_printf("Period\t\t%d ms\n", n * 100); + pub.prd_res = 100; break; case 2: - n *= 10; - /* fall through */ + pub.prd_res = 10; + break; case 1: - bt_shell_printf("Period\t\t%d sec\n", n); + pub.prd_res = 10000; break; case 3: - bt_shell_printf("Period\t\t%d min\n", n * 10); + pub.prd_res = 600000; break; } - bt_shell_printf("Rexmit count\t%d\n", data[9] & 0x7); - bt_shell_printf("Rexmit steps\t%d\n", data[9] >> 3); + bt_shell_printf("Period\t\t%d ms\n", pub.period); + + 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) + return true; + + memcpy(pub.u.label, grp->label, sizeof(pub.u.label)); + + } + + mesh_db_node_model_set_pub(src, ele_addr, len == 14, mod_id, + &pub, IS_VIRTUAL(pub.u.addr)); break; diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index 8445d33f4..f63edd5ae 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -32,6 +32,7 @@ #include "tools/mesh/keys.h" #include "tools/mesh/remote.h" #include "tools/mesh/cfgcli.h" +#include "tools/mesh/model.h" #include "tools/mesh/mesh-db.h" #define KEY_IDX_INVALID NET_IDX_INVALID @@ -992,6 +993,86 @@ bool mesh_db_node_model_overwrt_sub_virt(uint16_t unicast, uint16_t ele, return sub_overwrite(unicast, ele, vendor, mod_id, buf); } +static bool add_transmit_info(json_object *jobj, int cnt, int interval, + const char *desc) +{ + json_object *jtxmt; + + jtxmt = json_object_new_object(); + + if (!write_int(jtxmt, "count", cnt)) + return false; + + if (!write_int(jtxmt, "interval", interval)) + return false; + + json_object_object_add(jobj, desc, jtxmt); + return true; +} + +bool mesh_db_node_model_set_pub(uint16_t unicast, uint16_t ele_addr, + bool vendor, uint32_t mod_id, + struct model_pub *pub, bool virt) +{ + json_object *jmod, *jpub, *jobj = NULL; + + if (!cfg || !cfg->jcfg) + return false; + + jmod = get_model(unicast, ele_addr, mod_id, vendor); + if (!jmod) + return false; + + jpub = json_object_new_object(); + + if (!virt && !write_uint16_hex(jpub, "address", pub->u.addr)) + goto fail; + + if (virt) { + char buf[33]; + + hex2str(pub->u.label, 16, buf, sizeof(buf)); + + if (!add_string(jpub, "address", buf)) + goto fail; + } + + if (!write_int(jpub, "index", pub->app_idx)) + goto fail; + + if (!write_int(jpub, "ttl", pub->ttl)) + goto fail; + + if (!write_int(jpub, "credentials", pub->cred ? 1 : 0)) + goto fail; + + if (!add_transmit_info(jpub, pub->rtx_cnt, pub->rtx_interval, + "retransmit")) + goto fail; + + jobj = json_object_new_object(); + + if (!write_int(jobj, "numberOfSteps", pub->prd_steps)) + goto fail; + + if (!write_int(jobj, "resolution", pub->prd_res)) + goto fail; + + json_object_object_add(jpub, "period", jobj); + + json_object_object_del(jmod, "publish"); + json_object_object_add(jmod, "publish", jpub); + + return save_config(); + +fail: + if (jobj) + json_object_put(jobj); + + json_object_put(jpub); + return false; +} + static void jarray_key_del(json_object *jarray, int16_t idx) { int i, sz = json_object_array_length(jarray); diff --git a/tools/mesh/mesh-db.h b/tools/mesh/mesh-db.h index 384376cbd..885dabe90 100644 --- a/tools/mesh/mesh-db.h +++ b/tools/mesh/mesh-db.h @@ -11,6 +11,7 @@ #include "mesh/mesh-config.h" struct mesh_group; +struct model_pub; bool mesh_db_create(const char *fname, const uint8_t token[8], const char *name); @@ -65,6 +66,9 @@ bool mesh_db_node_model_overwrt_sub_virt(uint16_t unicast, uint16_t ele, uint8_t *label); bool mesh_db_node_model_del_sub_all(uint16_t unicast, uint16_t ele, bool vendor, uint32_t mod_id); +bool mesh_db_node_model_set_pub(uint16_t unicast, uint16_t ele_addr, + bool vendor, uint32_t mod_id, + struct model_pub *pub, bool virt); struct l_queue *mesh_db_load_groups(void); bool mesh_db_add_group(struct mesh_group *grp); bool mesh_db_add_rejected_addr(uint16_t unicast, uint32_t iv_index); diff --git a/tools/mesh/model.h b/tools/mesh/model.h index 7359ea7df..5e20719b2 100644 --- a/tools/mesh/model.h +++ b/tools/mesh/model.h @@ -25,14 +25,17 @@ typedef int (*model_bind_func_t)(uint16_t app_idx, int action); struct model_pub { uint16_t app_idx; + uint16_t period; union { - uint16_t addr16; - uint8_t va_128[16]; + uint16_t addr; + uint8_t label[16]; } u; + bool cred; + uint32_t prd_res; + uint16_t rtx_interval; + uint8_t prd_steps; + uint8_t rtx_cnt; uint8_t ttl; - uint8_t credential; - uint8_t period; - uint8_t retransmit; }; typedef int (*model_pub_func_t)(struct model_pub *pub); From patchwork Thu Sep 23 03:25:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511919 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 797E3C433FE for ; Thu, 23 Sep 2021 03:27:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 57FDC61038 for ; Thu, 23 Sep 2021 03:27:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239088AbhIWD2u (ORCPT ); Wed, 22 Sep 2021 23:28:50 -0400 Received: from mga11.intel.com ([192.55.52.93]:16373 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239058AbhIWD2o (ORCPT ); Wed, 22 Sep 2021 23:28:44 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555921" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555921" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:58 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072372" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:57 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 11/20] tools/mesh-cfgclient: Check the result of config save Date: Wed, 22 Sep 2021 20:25:54 -0700 Message-Id: <20210923032603.50536-12-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org After successful completion of configuration commands that change configuration state of network, the updates are expected to be recorded in configuration file. If for the results are not saved, print a warning message. --- tools/mesh/cfgcli.c | 119 +++++++++++++++++++++++--------------------- tools/mesh/remote.c | 10 ++-- tools/mesh/remote.h | 2 +- 3 files changed, 70 insertions(+), 61 deletions(-) diff --git a/tools/mesh/cfgcli.c b/tools/mesh/cfgcli.c index 2766d47ca..9399228c8 100644 --- a/tools/mesh/cfgcli.c +++ b/tools/mesh/cfgcli.c @@ -405,6 +405,7 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, struct model_pub pub; int n; struct pending_req *req; + bool saved = false; if (mesh_opcode_get(data, len, &opcode, &n)) { len -= n; @@ -428,20 +429,19 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, case OP_DEV_COMP_STATUS: if (len < MIN_COMPOSITION_LEN) - break; + return true; print_composition(data, len); - if (!mesh_db_node_set_composition(src, data, len)) - bt_shell_printf("Failed to save node composition!\n"); - else + saved = mesh_db_node_set_composition(src, data, len); + if (saved) remote_set_composition(src, true); break; case OP_APPKEY_STATUS: if (len != 4) - break; + return true; bt_shell_printf("Node %4.4x AppKey status %s\n", src, mesh_status_str(data[0])); @@ -452,23 +452,22 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, bt_shell_printf("AppKey\t%u (0x%3.3x)\n", app_idx, app_idx); if (data[0] != MESH_STATUS_SUCCESS) - break; + return true; if (!cmd) - break; + return true; if (cmd->opcode == OP_APPKEY_ADD) - remote_add_app_key(src, app_idx, true); + saved = remote_add_app_key(src, app_idx, true); else if (cmd->opcode == OP_APPKEY_DELETE) - remote_del_app_key(src, app_idx); + saved = remote_del_app_key(src, app_idx); else if (cmd->opcode == OP_APPKEY_UPDATE) - remote_update_app_key(src, app_idx, true, true); - + saved = remote_update_app_key(src, app_idx, true, true); break; case OP_APPKEY_LIST: if (len < 3) - break; + return true; bt_shell_printf("AppKey List (node %4.4x) Status %s\n", src, mesh_status_str(data[0])); @@ -478,16 +477,16 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, len -= 3; if (data[0] != MESH_STATUS_SUCCESS) - break; + return true; data += 3; print_appkey_list(len, data); - break; + return true; case OP_NETKEY_STATUS: if (len != 3) - break; + return true; bt_shell_printf("Node %4.4x NetKey status %s\n", src, mesh_status_str(data[0])); @@ -496,23 +495,23 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, bt_shell_printf("\tNetKey %u (0x%3.3x)\n", net_idx, net_idx); if (data[0] != MESH_STATUS_SUCCESS) - break; + return true; if (!cmd) - break; + return true; if (cmd->opcode == OP_NETKEY_ADD) - remote_add_net_key(src, net_idx, true); + saved = remote_add_net_key(src, net_idx, true); else if (cmd->opcode == OP_NETKEY_DELETE) - remote_del_net_key(src, net_idx); + saved = remote_del_net_key(src, net_idx); else if (cmd->opcode == OP_NETKEY_UPDATE) - remote_update_net_key(src, net_idx, true, true); + saved = remote_update_net_key(src, net_idx, true, true); break; case OP_NETKEY_LIST: if (len < 2) - break; + return true; bt_shell_printf("NetKey List (node %4.4x):\n", src); @@ -530,11 +529,11 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, bt_shell_printf("\t %u (0x%3.3x)\n", net_idx, net_idx); } - break; + return true; case OP_CONFIG_KEY_REFRESH_PHASE_STATUS: if (len != 4) - break; + return true; bt_shell_printf("Node %4.4x Key Refresh Phase status %s\n", src, mesh_status_str(data[0])); @@ -546,14 +545,16 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, if (data[0] != MESH_STATUS_SUCCESS) return true; - if (data[3] == KEY_REFRESH_PHASE_NONE) - remote_finish_key_refresh(src, net_idx); + 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) - break; + return true; bt_shell_printf("Node %4.4x: Model App status %s\n", src, mesh_status_str(data[0])); @@ -567,14 +568,14 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, bt_shell_printf("AppIdx\t\t%u (0x%3.3x)\n ", app_idx, app_idx); if (data[0] != MESH_STATUS_SUCCESS || !cmd) - break; + return true; if (cmd->opcode == OP_MODEL_APP_BIND) - mesh_db_node_model_bind(src, addr, len == 9, mod_id, - app_idx); + saved = mesh_db_node_model_bind(src, addr, len == 9, + mod_id, app_idx); else - mesh_db_node_model_unbind(src, addr, len == 9, mod_id, - app_idx); + saved = mesh_db_node_model_unbind(src, addr, len == 9, + mod_id, app_idx); break; @@ -585,7 +586,7 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, bt_shell_printf("NetIdx %4.4x, NodeIdState 0x%02x, status %s\n", get_le16(data + 1), data[3], mesh_status_str(data[0])); - break; + return true; case OP_CONFIG_BEACON_STATUS: if (len != 1) @@ -616,7 +617,7 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, return true; bt_shell_printf("Node %4.4x Default TTL %d\n", src, data[0]); - mesh_db_node_ttl_set(src, data[0]); + saved = mesh_db_node_ttl_set(src, data[0]); break; @@ -670,15 +671,18 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, if (IS_VIRTUAL(pub.u.addr)) { grp = l_queue_find(groups, match_group_addr, L_UINT_TO_PTR(pub.u.addr)); - if (!grp) + if (!grp) { + bt_shell_printf("Unknown virtual group\n"); return true; + } memcpy(pub.u.label, grp->label, sizeof(pub.u.label)); } - mesh_db_node_model_set_pub(src, ele_addr, len == 14, mod_id, - &pub, IS_VIRTUAL(pub.u.addr)); + saved = mesh_db_node_model_set_pub(src, ele_addr, len == 14, + mod_id, &pub, + IS_VIRTUAL(pub.u.addr)); break; @@ -708,34 +712,36 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, default: return true; case OP_CONFIG_MODEL_SUB_ADD: - mesh_db_node_model_add_sub(src, ele_addr, len == 9, - mod_id, addr); + saved = mesh_db_node_model_add_sub(src, ele_addr, + len == 9, mod_id, addr); break; case OP_CONFIG_MODEL_SUB_DELETE: - mesh_db_node_model_del_sub(src, ele_addr, len == 9, - mod_id, addr); + saved = mesh_db_node_model_del_sub(src, ele_addr, + len == 9, mod_id, addr); break; case OP_CONFIG_MODEL_SUB_OVERWRITE: - mesh_db_node_model_overwrt_sub(src, ele_addr, len == 9, - mod_id, addr); + saved = mesh_db_node_model_overwrt_sub(src, ele_addr, + len == 9, mod_id, addr); break; case OP_CONFIG_MODEL_SUB_DELETE_ALL: - mesh_db_node_model_del_sub_all(src, ele_addr, len == 9, - mod_id); + 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) - mesh_db_node_model_add_sub_virt(src, ele_addr, - len == 9, mod_id, grp->label); + 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) - mesh_db_node_model_del_sub_virt(src, ele_addr, - len == 9, mod_id, grp->label); + 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) - mesh_db_node_model_overwrt_sub_virt(src, + saved = mesh_db_node_model_overwrt_sub_virt(src, ele_addr, len == 9, mod_id, grp->label); break; @@ -749,14 +755,14 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, return true; print_sub_list(src, false, data, len); - break; + return true; case OP_CONFIG_VEND_MODEL_SUB_LIST: if (len < 7) return true; print_sub_list(src, true, data, len); - break; + return true; /* Per Mesh Profile 4.3.2.50 */ case OP_MODEL_APP_LIST: @@ -772,8 +778,7 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, data += 5; len -= 5; print_appkey_list(len, data); - - break; + return true; case OP_VEND_MODEL_APP_LIST: if (len < 7) @@ -791,8 +796,7 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, data += 7; len -= 7; print_appkey_list(len, data); - - break; + return true; /* Per Mesh Profile 4.3.2.63 */ case OP_CONFIG_HEARTBEAT_PUB_STATUS: @@ -842,7 +846,7 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, bt_shell_printf("Node %4.4x is reset\n", src); reset_remote_node(src); - break; + return true; /* Per Mesh Profile 4.3.2.57 */ case OP_CONFIG_FRIEND_STATUS: @@ -854,6 +858,9 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, break; } + if (!saved) + bt_shell_printf("Warning: Configuration not updated\n"); + return true; } diff --git a/tools/mesh/remote.c b/tools/mesh/remote.c index 2f8493f8a..dd294fe4d 100644 --- a/tools/mesh/remote.c +++ b/tools/mesh/remote.c @@ -351,18 +351,19 @@ bool remote_update_app_key(uint16_t addr, uint16_t app_idx, bool update, return true; } -void remote_finish_key_refresh(uint16_t addr, uint16_t net_idx) +bool remote_finish_key_refresh(uint16_t addr, uint16_t net_idx) { struct remote_node *rmt; struct remote_key *key; const struct l_queue_entry *l; + bool res = true; rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr)); if (!rmt) - return; + return false; if (!remote_update_net_key(addr, net_idx, false, true)) - return; + return false; l = l_queue_get_entries(rmt->app_keys); @@ -374,9 +375,10 @@ void remote_finish_key_refresh(uint16_t addr, uint16_t net_idx) key->updated = false; - mesh_db_node_app_key_update(addr, key->idx, false); + res &= mesh_db_node_app_key_update(addr, key->idx, false); } + return res; } uint16_t remote_get_subnet_idx(uint16_t addr) diff --git a/tools/mesh/remote.h b/tools/mesh/remote.h index 2fb0d83ce..66457237e 100644 --- a/tools/mesh/remote.h +++ b/tools/mesh/remote.h @@ -24,7 +24,7 @@ bool remote_add_app_key(uint16_t addr, uint16_t app_idx, bool save); bool remote_del_app_key(uint16_t addr, uint16_t app_idx); bool remote_update_app_key(uint16_t addr, uint16_t app_idx, bool update, bool save); -void remote_finish_key_refresh(uint16_t addr, uint16_t net_idx); +bool remote_finish_key_refresh(uint16_t addr, uint16_t net_idx); void remote_set_composition(uint16_t addr, bool comp); bool remote_has_composition(uint16_t addr); uint16_t remote_get_subnet_idx(uint16_t addr); From patchwork Thu Sep 23 03:25:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511921 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DDCE1C433F5 for ; Thu, 23 Sep 2021 03:27:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C6D1961038 for ; Thu, 23 Sep 2021 03:27:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239090AbhIWD2v (ORCPT ); Wed, 22 Sep 2021 23:28:51 -0400 Received: from mga11.intel.com ([192.55.52.93]:16381 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239046AbhIWD2o (ORCPT ); Wed, 22 Sep 2021 23:28:44 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555922" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555922" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:58 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072376" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:58 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 12/20] tools/mesh-cfgclient: Rename mesh-db APIs for consistency Date: Wed, 22 Sep 2021 20:25:55 -0700 Message-Id: <20210923032603.50536-13-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org --- tools/mesh-cfgclient.c | 12 ++++++------ tools/mesh/cfgcli.c | 2 +- tools/mesh/keys.c | 4 ++-- tools/mesh/mesh-db.c | 24 ++++++++++++------------ tools/mesh/mesh-db.h | 26 +++++++++++++------------- tools/mesh/remote.c | 16 ++++++++-------- 6 files changed, 42 insertions(+), 42 deletions(-) diff --git a/tools/mesh-cfgclient.c b/tools/mesh-cfgclient.c index 62dcecb2f..beeb115dc 100644 --- a/tools/mesh-cfgclient.c +++ b/tools/mesh-cfgclient.c @@ -1041,15 +1041,15 @@ static void mgr_key_reply(struct l_dbus_proxy *proxy, if (!strcmp("CreateSubnet", method)) { keys_add_net_key(idx); - mesh_db_net_key_add(idx); + mesh_db_add_net_key(idx); } else if (!strcmp("DeleteSubnet", method)) { keys_del_net_key(idx); - mesh_db_net_key_del(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_app_key_del(idx); + mesh_db_del_app_key(idx); } } @@ -1133,13 +1133,13 @@ static void add_key_reply(struct l_dbus_proxy *proxy, if (!strcmp(method, "ImportSubnet")) { keys_add_net_key(net_idx); - mesh_db_net_key_add(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_app_key_add(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) @@ -1824,7 +1824,7 @@ static struct l_dbus_message *join_complete(struct l_dbus *dbus, } keys_add_net_key(PRIMARY_NET_IDX); - mesh_db_net_key_add(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); diff --git a/tools/mesh/cfgcli.c b/tools/mesh/cfgcli.c index 9399228c8..b30edca19 100644 --- a/tools/mesh/cfgcli.c +++ b/tools/mesh/cfgcli.c @@ -617,7 +617,7 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, return true; bt_shell_printf("Node %4.4x Default TTL %d\n", src, data[0]); - saved = mesh_db_node_ttl_set(src, data[0]); + saved = mesh_db_node_set_ttl(src, data[0]); break; diff --git a/tools/mesh/keys.c b/tools/mesh/keys.c index c08348bff..134c1a10e 100644 --- a/tools/mesh/keys.c +++ b/tools/mesh/keys.c @@ -54,7 +54,7 @@ static void delete_bound_appkey(void *a) { uint32_t idx = L_PTR_TO_UINT(a); - mesh_db_app_key_del(idx); + mesh_db_del_app_key(idx); } void keys_add_net_key(uint16_t net_idx) @@ -102,7 +102,7 @@ void keys_set_net_key_phase(uint16_t net_idx, uint8_t phase, bool save) key->phase = phase; - if (save && !mesh_db_net_key_phase_set(net_idx, phase)) + if (save && !mesh_db_set_net_key_phase(net_idx, phase)) bt_shell_printf("Failed to save updated KR phase\n"); } diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index f63edd5ae..46efb81ea 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -648,7 +648,7 @@ fail: return false; } -bool mesh_db_node_ttl_set(uint16_t unicast, uint8_t ttl) +bool mesh_db_node_set_ttl(uint16_t unicast, uint8_t ttl) { json_object *jnode; @@ -1106,7 +1106,7 @@ static bool delete_key(json_object *jobj, const char *desc, uint16_t idx) return save_config(); } -bool mesh_db_node_net_key_add(uint16_t unicast, uint16_t idx) +bool mesh_db_node_add_net_key(uint16_t unicast, uint16_t idx) { json_object *jnode; @@ -1120,7 +1120,7 @@ bool mesh_db_node_net_key_add(uint16_t unicast, uint16_t idx) return add_node_key(jnode, "netKeys", idx); } -bool mesh_db_node_net_key_del(uint16_t unicast, uint16_t net_idx) +bool mesh_db_node_del_net_key(uint16_t unicast, uint16_t net_idx) { json_object *jnode; @@ -1168,12 +1168,12 @@ static bool key_update(uint16_t unicast, int16_t idx, bool updated, return false; } -bool mesh_db_node_net_key_update(uint16_t unicast, uint16_t idx, bool updated) +bool mesh_db_node_update_net_key(uint16_t unicast, uint16_t idx, bool updated) { return key_update(unicast, idx, updated, "netKeys"); } -bool mesh_db_node_app_key_add(uint16_t unicast, uint16_t idx) +bool mesh_db_node_add_app_key(uint16_t unicast, uint16_t idx) { json_object *jnode; @@ -1187,7 +1187,7 @@ bool mesh_db_node_app_key_add(uint16_t unicast, uint16_t idx) return add_node_key(jnode, "appKeys", idx); } -bool mesh_db_node_app_key_del(uint16_t unicast, uint16_t idx) +bool mesh_db_node_del_app_key(uint16_t unicast, uint16_t idx) { json_object *jnode; @@ -1201,7 +1201,7 @@ bool mesh_db_node_app_key_del(uint16_t unicast, uint16_t idx) return delete_key(jnode, "appKeys", idx); } -bool mesh_db_node_app_key_update(uint16_t unicast, uint16_t idx, bool updated) +bool mesh_db_node_update_app_key(uint16_t unicast, uint16_t idx, bool updated) { return key_update(unicast, idx, updated, "appKeys"); } @@ -1260,7 +1260,7 @@ static bool load_keys(json_object *jobj) return true; } -bool mesh_db_net_key_add(uint16_t net_idx) +bool mesh_db_add_net_key(uint16_t net_idx) { json_object *jkey, *jarray; char buf[12]; @@ -1303,7 +1303,7 @@ fail: return false; } -bool mesh_db_net_key_del(uint16_t net_idx) +bool mesh_db_del_net_key(uint16_t net_idx) { if (!cfg || !cfg->jcfg) return false; @@ -1311,7 +1311,7 @@ bool mesh_db_net_key_del(uint16_t net_idx) return delete_key(cfg->jcfg, "netKeys", net_idx); } -bool mesh_db_net_key_phase_set(uint16_t net_idx, uint8_t phase) +bool mesh_db_set_net_key_phase(uint16_t net_idx, uint8_t phase) { json_object *jval, *jarray, *jkey; @@ -1335,7 +1335,7 @@ bool mesh_db_net_key_phase_set(uint16_t net_idx, uint8_t phase) return save_config(); } -bool mesh_db_app_key_add(uint16_t net_idx, uint16_t app_idx) +bool mesh_db_add_app_key(uint16_t net_idx, uint16_t app_idx) { if (!cfg || !cfg->jcfg) return false; @@ -1346,7 +1346,7 @@ bool mesh_db_app_key_add(uint16_t net_idx, uint16_t app_idx) return save_config(); } -bool mesh_db_app_key_del(uint16_t app_idx) +bool mesh_db_del_app_key(uint16_t app_idx) { if (!cfg || !cfg->jcfg) return false; diff --git a/tools/mesh/mesh-db.h b/tools/mesh/mesh-db.h index 885dabe90..147fbf98c 100644 --- a/tools/mesh/mesh-db.h +++ b/tools/mesh/mesh-db.h @@ -20,13 +20,13 @@ bool mesh_db_load(const char *fname); bool mesh_db_get_token(uint8_t token[8]); bool mesh_db_set_iv_index(uint32_t ivi); uint32_t mesh_db_get_iv_index(void); -bool mesh_db_net_key_add(uint16_t idx); -bool mesh_db_net_key_del(uint16_t idx); -bool mesh_db_net_key_phase_set(uint16_t net_idx, uint8_t phase); -bool mesh_db_app_key_add(uint16_t net_idx, uint16_t app_idx); -bool mesh_db_app_key_del(uint16_t app_idx); -bool mesh_db_get_addr_range(uint16_t *low, uint16_t *high); +bool mesh_db_add_net_key(uint16_t idx); +bool mesh_db_del_net_key(uint16_t idx); +bool mesh_db_set_net_key_phase(uint16_t net_idx, uint8_t phase); +bool mesh_db_add_app_key(uint16_t net_idx, uint16_t app_idx); +bool mesh_db_del_app_key(uint16_t app_idx); +bool mesh_db_get_addr_range(uint16_t *low, uint16_t *high); bool mesh_db_add_node(uint8_t uuid[16], uint8_t num_els, uint16_t unicast, uint16_t net_idx); bool mesh_db_del_node(uint16_t unicast); @@ -37,13 +37,13 @@ bool mesh_db_add_provisioner(const char *name, uint8_t uuid[16], uint16_t group_low, uint16_t group_high); bool mesh_db_node_set_net_transmit(uint16_t unicast, uint8_t cnt, uint16_t interval); -bool mesh_db_node_net_key_add(uint16_t unicast, uint16_t idx); -bool mesh_db_node_net_key_del(uint16_t unicast, uint16_t idx); -bool mesh_db_node_net_key_update(uint16_t unicast, uint16_t idx, bool updated); -bool mesh_db_node_app_key_add(uint16_t unicast, uint16_t idx); -bool mesh_db_node_app_key_del(uint16_t unicast, uint16_t idx); -bool mesh_db_node_app_key_update(uint16_t unicast, uint16_t idx, bool updated); -bool mesh_db_node_ttl_set(uint16_t unicast, uint8_t ttl); +bool mesh_db_node_add_net_key(uint16_t unicast, uint16_t idx); +bool mesh_db_node_del_net_key(uint16_t unicast, uint16_t idx); +bool mesh_db_node_update_net_key(uint16_t unicast, uint16_t idx, bool updated); +bool mesh_db_node_add_app_key(uint16_t unicast, uint16_t idx); +bool mesh_db_node_del_app_key(uint16_t unicast, uint16_t idx); +bool mesh_db_node_update_app_key(uint16_t unicast, uint16_t idx, bool updated); +bool mesh_db_node_set_ttl(uint16_t unicast, uint8_t ttl); bool mesh_db_node_write_mode(uint16_t unicast, const char *keyword, int value); bool mesh_db_node_model_bind(uint16_t unicast, uint16_t ele_addr, bool vendor, uint32_t mod_id, uint16_t app_idx); diff --git a/tools/mesh/remote.c b/tools/mesh/remote.c index dd294fe4d..054da5300 100644 --- a/tools/mesh/remote.c +++ b/tools/mesh/remote.c @@ -233,7 +233,7 @@ bool remote_add_net_key(uint16_t addr, uint16_t net_idx, bool save) l_queue_push_tail(rmt->net_keys, key); if (save) - return mesh_db_node_net_key_add(addr, net_idx); + return mesh_db_node_add_net_key(addr, net_idx); else return true; } @@ -252,14 +252,14 @@ bool remote_del_net_key(uint16_t addr, uint16_t net_idx) if (!key) return false; - mesh_db_node_net_key_del(addr, net_idx); + mesh_db_node_del_net_key(addr, net_idx); l_free(key); key = l_queue_remove_if(rmt->app_keys, match_bound_key, L_UINT_TO_PTR(net_idx)); while (key) { - mesh_db_node_app_key_del(rmt->unicast, key->idx); + mesh_db_node_del_app_key(rmt->unicast, key->idx); l_free(key); key = l_queue_remove_if(rmt->app_keys, match_bound_key, @@ -284,7 +284,7 @@ bool remote_update_net_key(uint16_t addr, uint16_t net_idx, bool update, key->updated = update; if (save) - return mesh_db_node_net_key_update(addr, net_idx, update); + return mesh_db_node_update_net_key(addr, net_idx, update); else return true; } @@ -310,7 +310,7 @@ bool remote_add_app_key(uint16_t addr, uint16_t app_idx, bool save) l_queue_push_tail(rmt->app_keys, key); if (save) - return mesh_db_node_app_key_add(addr, app_idx); + return mesh_db_node_add_app_key(addr, app_idx); else return true; } @@ -328,7 +328,7 @@ bool remote_del_app_key(uint16_t addr, uint16_t app_idx) L_UINT_TO_PTR(app_idx)); l_free(key); - return mesh_db_node_app_key_del(addr, app_idx); + return mesh_db_node_del_app_key(addr, app_idx); } bool remote_update_app_key(uint16_t addr, uint16_t app_idx, bool update, @@ -346,7 +346,7 @@ bool remote_update_app_key(uint16_t addr, uint16_t app_idx, bool update, key->updated = update; if (save) - return mesh_db_node_app_key_update(addr, app_idx, update); + return mesh_db_node_update_app_key(addr, app_idx, update); else return true; } @@ -375,7 +375,7 @@ bool remote_finish_key_refresh(uint16_t addr, uint16_t net_idx) key->updated = false; - res &= mesh_db_node_app_key_update(addr, key->idx, false); + res &= mesh_db_node_update_app_key(addr, key->idx, false); } return res; From patchwork Thu Sep 23 03:25:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511927 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 84945C433FE for ; Thu, 23 Sep 2021 03:27:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6B260610A1 for ; Thu, 23 Sep 2021 03:27:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239098AbhIWD2x (ORCPT ); Wed, 22 Sep 2021 23:28:53 -0400 Received: from mga11.intel.com ([192.55.52.93]:16381 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239061AbhIWD2p (ORCPT ); Wed, 22 Sep 2021 23:28:45 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555924" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555924" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:59 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072380" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:59 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 13/20] tools/mesh-cfgclient: Save remote node feature setting Date: Wed, 22 Sep 2021 20:25:56 -0700 Message-Id: <20210923032603.50536-14-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Save the information for remote node's relay, friend, proxy and secure network beacon settings. --- tools/mesh/cfgcli.c | 14 +++- tools/mesh/mesh-db.c | 160 +++++++++++++++++++++++++++++++++++-------- tools/mesh/mesh-db.h | 5 ++ 3 files changed, 151 insertions(+), 28 deletions(-) diff --git a/tools/mesh/cfgcli.c b/tools/mesh/cfgcli.c index b30edca19..b5f39df18 100644 --- a/tools/mesh/cfgcli.c +++ b/tools/mesh/cfgcli.c @@ -594,6 +594,8 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, 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: @@ -602,6 +604,10 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, 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: @@ -610,6 +616,8 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, 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: @@ -618,7 +626,6 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, 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: @@ -838,6 +845,9 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, 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 */ @@ -855,6 +865,8 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, bt_shell_printf("Node %4.4x Friend state 0x%02x\n", src, data[0]); + + saved = mesh_db_node_set_friend(src, data[0]); break; } diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index 46efb81ea..3290c5b8e 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -137,12 +137,12 @@ static void release_config(void) cfg = NULL; } -static json_object *get_node_by_unicast(uint16_t unicast) +static json_object *get_node_by_unicast(json_object *jcfg, uint16_t unicast) { json_object *jarray; int i, sz; - if (!json_object_object_get_ex(cfg->jcfg, "nodes", &jarray)) + if (!json_object_object_get_ex(jcfg, "nodes", &jarray)) return NULL; if (!jarray || json_object_get_type(jarray) != json_type_array) @@ -655,7 +655,7 @@ bool mesh_db_node_set_ttl(uint16_t unicast, uint8_t ttl) if (!cfg || !cfg->jcfg) return false; - jnode = get_node_by_unicast(unicast); + jnode = get_node_by_unicast(cfg->jcfg, unicast); if (!jnode) return false; @@ -665,12 +665,135 @@ bool mesh_db_node_set_ttl(uint16_t unicast, uint8_t ttl) return save_config(); } +static bool add_transmit_info(json_object *jobj, int cnt, int interval, + const char *desc) +{ + json_object *jtxmt; + + json_object_object_del(jobj, desc); + jtxmt = json_object_new_object(); + + if (!write_int(jtxmt, "count", cnt)) + goto fail; + + if (!write_int(jtxmt, "interval", interval)) + goto fail; + + json_object_object_add(jobj, desc, jtxmt); + return true; + +fail: + json_object_put(jtxmt); + return false; +} + +bool mesh_db_node_set_net_transmit(uint16_t unicast, uint8_t cnt, + uint16_t interval) +{ + json_object *jnode; + + if (!cfg || !cfg->jcfg) + return false; + + jnode = get_node_by_unicast(cfg->jcfg, unicast); + if (!jnode) + return false; + + if (!add_transmit_info(jnode, cnt, interval, "networkTransmit")) + return false; + + return save_config(); +} + +static bool set_feature(json_object *jnode, const char *desc, uint8_t feature) +{ + json_object *jobj; + + if (feature > MESH_MODE_UNSUPPORTED) + return false; + + jobj = json_object_object_get(jnode, "features"); + if (!jobj) { + jobj = json_object_new_object(); + json_object_object_add(jnode, "features", jobj); + } + + if (!write_int(jobj, desc, feature)) + return false; + + return save_config(); +} + +bool mesh_db_node_set_relay(uint16_t unicast, uint8_t relay, uint8_t cnt, + uint16_t interval) +{ + json_object *jnode; + + if (!cfg || !cfg->jcfg) + return false; + + jnode = get_node_by_unicast(cfg->jcfg, unicast); + if (!jnode) + return false; + + if (relay < MESH_MODE_UNSUPPORTED && + !add_transmit_info(jnode, cnt, interval, "relayRetransmit")) + return false; + + return set_feature(jnode, "relay", relay); +} + +bool mesh_db_node_set_proxy(uint16_t unicast, uint8_t proxy) +{ + json_object *jnode; + + if (!cfg || !cfg->jcfg) + return false; + + jnode = get_node_by_unicast(cfg->jcfg, unicast); + if (!jnode) + return false; + + return set_feature(jnode, "proxy", proxy); +} + +bool mesh_db_node_set_friend(uint16_t unicast, uint8_t friend) +{ + json_object *jnode; + + if (!cfg || !cfg->jcfg) + return false; + + jnode = get_node_by_unicast(cfg->jcfg, unicast); + if (!jnode) + return false; + + return set_feature(jnode, "friend", friend); +} + +bool mesh_db_node_set_beacon(uint16_t unicast, bool enabled) +{ + json_object *jnode; + + if (!cfg || !cfg->jcfg) + return false; + + jnode = get_node_by_unicast(cfg->jcfg, unicast); + if (!jnode) + return false; + + if (!write_bool(jnode, "secureNetworkBeacon", enabled)) + return false; + + return save_config(); +} + static json_object *get_element(uint16_t unicast, uint16_t ele_addr) { json_object *jnode, *jarray; int i, ele_cnt; - jnode = get_node_by_unicast(unicast); + jnode = get_node_by_unicast(cfg->jcfg, unicast); if (!jnode) return false; @@ -993,23 +1116,6 @@ bool mesh_db_node_model_overwrt_sub_virt(uint16_t unicast, uint16_t ele, return sub_overwrite(unicast, ele, vendor, mod_id, buf); } -static bool add_transmit_info(json_object *jobj, int cnt, int interval, - const char *desc) -{ - json_object *jtxmt; - - jtxmt = json_object_new_object(); - - if (!write_int(jtxmt, "count", cnt)) - return false; - - if (!write_int(jtxmt, "interval", interval)) - return false; - - json_object_object_add(jobj, desc, jtxmt); - return true; -} - bool mesh_db_node_model_set_pub(uint16_t unicast, uint16_t ele_addr, bool vendor, uint32_t mod_id, struct model_pub *pub, bool virt) @@ -1113,7 +1219,7 @@ bool mesh_db_node_add_net_key(uint16_t unicast, uint16_t idx) if (!cfg || !cfg->jcfg) return false; - jnode = get_node_by_unicast(unicast); + jnode = get_node_by_unicast(cfg->jcfg, unicast); if (!jnode) return false; @@ -1127,7 +1233,7 @@ bool mesh_db_node_del_net_key(uint16_t unicast, uint16_t net_idx) if (!cfg || !cfg->jcfg) return false; - jnode = get_node_by_unicast(unicast); + jnode = get_node_by_unicast(cfg->jcfg, unicast); if (!jnode) return false; @@ -1143,7 +1249,7 @@ static bool key_update(uint16_t unicast, int16_t idx, bool updated, if (!cfg || !cfg->jcfg) return false; - jnode = get_node_by_unicast(unicast); + jnode = get_node_by_unicast(cfg->jcfg, unicast); if (!jnode) return false; @@ -1180,7 +1286,7 @@ bool mesh_db_node_add_app_key(uint16_t unicast, uint16_t idx) if (!cfg || !cfg->jcfg) return false; - jnode = get_node_by_unicast(unicast); + jnode = get_node_by_unicast(cfg->jcfg, unicast); if (!jnode) return false; @@ -1194,7 +1300,7 @@ bool mesh_db_node_del_app_key(uint16_t unicast, uint16_t idx) if (!cfg || !cfg->jcfg) return false; - jnode = get_node_by_unicast(unicast); + jnode = get_node_by_unicast(cfg->jcfg, unicast); if (!jnode) return false; @@ -1635,7 +1741,7 @@ bool mesh_db_node_set_composition(uint16_t unicast, uint8_t *data, uint16_t len) if (!cfg || !cfg->jcfg) return false; - jnode = get_node_by_unicast(unicast); + jnode = get_node_by_unicast(cfg->jcfg, unicast); if (!jnode) return false; diff --git a/tools/mesh/mesh-db.h b/tools/mesh/mesh-db.h index 147fbf98c..b3b0bce79 100644 --- a/tools/mesh/mesh-db.h +++ b/tools/mesh/mesh-db.h @@ -37,6 +37,11 @@ bool mesh_db_add_provisioner(const char *name, uint8_t uuid[16], uint16_t group_low, uint16_t group_high); bool mesh_db_node_set_net_transmit(uint16_t unicast, uint8_t cnt, uint16_t interval); +bool mesh_db_node_set_relay(uint16_t unicast, uint8_t relay, uint8_t cnt, + uint16_t interval); +bool mesh_db_node_set_proxy(uint16_t unicast, uint8_t proxy); +bool mesh_db_node_set_friend(uint16_t unicast, uint8_t friend); +bool mesh_db_node_set_beacon(uint16_t unicast, bool enabled); bool mesh_db_node_add_net_key(uint16_t unicast, uint16_t idx); bool mesh_db_node_del_net_key(uint16_t unicast, uint16_t idx); bool mesh_db_node_update_net_key(uint16_t unicast, uint16_t idx, bool updated); From patchwork Thu Sep 23 03:25:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511929 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 954ADC433EF for ; Thu, 23 Sep 2021 03:27:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7C51161131 for ; Thu, 23 Sep 2021 03:27:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239063AbhIWD2y (ORCPT ); Wed, 22 Sep 2021 23:28:54 -0400 Received: from mga11.intel.com ([192.55.52.93]:16377 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239062AbhIWD2p (ORCPT ); Wed, 22 Sep 2021 23:28:45 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555926" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555926" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:59 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072384" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:26:59 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 14/20] tools/mesh-cfgclient: Store remote's heartbeat sub/pub Date: Wed, 22 Sep 2021 20:25:57 -0700 Message-Id: <20210923032603.50536-15-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Store remote node's heartbeat publication or subscription info upon receiving CONFIG_HEARTBEAT_PUB_STATUS or CONFIG_HEARTBEAT_SUB_STATUS messages when the messages' status code is set to Success. --- tools/mesh/cfgcli.c | 30 +++++++++--- tools/mesh/mesh-db.c | 113 +++++++++++++++++++++++++++++++++++++++++-- tools/mesh/mesh-db.h | 4 ++ 3 files changed, 135 insertions(+), 12 deletions(-) diff --git a/tools/mesh/cfgcli.c b/tools/mesh/cfgcli.c index b5f39df18..2bf1a1503 100644 --- a/tools/mesh/cfgcli.c +++ b/tools/mesh/cfgcli.c @@ -400,7 +400,7 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, { uint32_t opcode, mod_id; const struct cfg_cmd *cmd; - uint16_t app_idx, net_idx, addr, ele_addr; + uint16_t app_idx, net_idx, addr, ele_addr, features; struct mesh_group *grp; struct model_pub pub; int n; @@ -813,13 +813,21 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, bt_shell_printf("\nNode %4.4x Heartbeat publish status %s\n", src, mesh_status_str(data[0])); - bt_shell_printf("Destination\t%4.4x\n", get_le16(data + 1)); - bt_shell_printf("Count\t\t%2.2x\n", data[3]); - bt_shell_printf("Period\t\t%2.2x\n", data[4]); + 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]); - bt_shell_printf("Features\t%4.4x\n", get_le16(data + 6)); + 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 */ @@ -830,12 +838,20 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data, bt_shell_printf("\nNode %4.4x Heartbeat subscribe status %s\n", src, mesh_status_str(data[0])); - bt_shell_printf("Source\t\t%4.4x\n", get_le16(data + 1)); - bt_shell_printf("Destination\t%4.4x\n", get_le16(data + 3)); + 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 */ diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index 3290c5b8e..42ba831d4 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -963,12 +963,24 @@ static void jarray_string_del(json_object *jarray, const char *str, size_t len) } } +static bool add_array_string(json_object *jarray, const char *str) +{ + json_object *jstring; + + jstring = json_object_new_string(str); + if (!jstring) + return false; + + json_object_array_add(jarray, jstring); + return true; +} + static bool update_model_string_array(uint16_t unicast, uint16_t ele_addr, bool vendor, uint32_t mod_id, const char *str, uint32_t len, const char *keyword, bool add) { - json_object *jarray, *jmod, *jstring; + json_object *jarray, *jmod; if (!cfg || !cfg->jcfg) return false; @@ -988,12 +1000,9 @@ static bool update_model_string_array(uint16_t unicast, uint16_t ele_addr, if (!add) return true; - jstring = json_object_new_string(str); - if (!jstring) + if (!add_array_string(jarray, str)) return false; - json_object_array_add(jarray, jstring); - return save_config(); } @@ -1179,6 +1188,100 @@ fail: return false; } +bool mesh_db_node_set_hb_pub(uint16_t unicast, uint16_t dst, uint16_t net_idx, + uint8_t period_log, uint8_t ttl, + uint16_t features) +{ + json_object *jnode, *jpub, *jarray = NULL; + uint32_t period; + + if (!cfg || !cfg->jcfg) + return false; + + if (period_log > 0x12 || ttl > 0x7F) + return false; + + jnode = get_node_by_unicast(cfg->jcfg, unicast); + if (!jnode) + return false; + + jpub = json_object_new_object(); + + if (!write_uint16_hex(jpub, "address", dst)) + goto fail; + + period = period_log ? 1 << (period_log - 1) : 0; + + if (!write_int(jpub, "period", period)) + goto fail; + + if (!write_int(jpub, "ttl", ttl)) + goto fail; + + if (!write_int(jpub, "index", net_idx)) + goto fail; + + jarray = json_object_new_array(); + + if (features & FEATURE_PROXY) + if (!add_array_string(jarray, "proxy")) + goto fail; + + if (features & FEATURE_RELAY) + if (!add_array_string(jarray, "relay")) + goto fail; + + if (features & FEATURE_FRIEND) + if (!add_array_string(jarray, "friend")) + goto fail; + + if (features & FEATURE_LPN) + if (!add_array_string(jarray, "lowPower")) + goto fail; + + json_object_object_add(jpub, "features", jarray); + json_object_object_del(jnode, "heartbeatPub"); + json_object_object_add(jnode, "heartbeatPub", jpub); + + return save_config(); + +fail: + if (jarray) + json_object_put(jarray); + + json_object_put(jpub); + return false; +} + +bool mesh_db_node_set_hb_sub(uint16_t unicast, uint16_t src, uint16_t dst) +{ + json_object *jnode, *jsub; + + if (!cfg || !cfg->jcfg) + return false; + + jnode = get_node_by_unicast(cfg->jcfg, unicast); + if (!jnode) + return false; + + jsub = json_object_new_object(); + + if (!write_uint16_hex(jsub, "source", src)) + goto fail; + + if (!write_uint16_hex(jsub, "destination", dst)) + goto fail; + + json_object_object_del(jnode, "heartbeatSub"); + json_object_object_add(jnode, "heartbeatSub", jsub); + + return save_config(); + +fail: + json_object_put(jsub); + return false; +} + static void jarray_key_del(json_object *jarray, int16_t idx) { int i, sz = json_object_array_length(jarray); diff --git a/tools/mesh/mesh-db.h b/tools/mesh/mesh-db.h index b3b0bce79..16c46c046 100644 --- a/tools/mesh/mesh-db.h +++ b/tools/mesh/mesh-db.h @@ -74,6 +74,10 @@ bool mesh_db_node_model_del_sub_all(uint16_t unicast, uint16_t ele, bool vendor, bool mesh_db_node_model_set_pub(uint16_t unicast, uint16_t ele_addr, bool vendor, uint32_t mod_id, struct model_pub *pub, bool virt); +bool mesh_db_node_set_hb_pub(uint16_t unicast, uint16_t dst, uint16_t net_idx, + uint8_t period_log, uint8_t ttl, + uint16_t features); +bool mesh_db_node_set_hb_sub(uint16_t unicast, uint16_t src, uint16_t dst); struct l_queue *mesh_db_load_groups(void); bool mesh_db_add_group(struct mesh_group *grp); bool mesh_db_add_rejected_addr(uint16_t unicast, uint32_t iv_index); From patchwork Thu Sep 23 03:25:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511925 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0EB87C433F5 for ; Thu, 23 Sep 2021 03:27:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EC18760F48 for ; Thu, 23 Sep 2021 03:27:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239105AbhIWD2x (ORCPT ); Wed, 22 Sep 2021 23:28:53 -0400 Received: from mga11.intel.com ([192.55.52.93]:16373 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239063AbhIWD2p (ORCPT ); Wed, 22 Sep 2021 23:28:45 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555928" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555928" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:27:00 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072389" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:27:00 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 15/20] tools/mesh-cfgclient: Add group parent address for DB compliance Date: Wed, 22 Sep 2021 20:25:58 -0700 Message-Id: <20210923032603.50536-16-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org --- tools/mesh/mesh-db.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index 42ba831d4..0dc811801 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -1590,6 +1590,10 @@ bool mesh_db_add_group(struct mesh_group *grp) goto fail; } + /* Initialize parent group to unassigned address for now*/ + if (!write_uint16_hex(jgroup, "parentAddress", UNASSIGNED_ADDRESS)) + goto fail; + json_object_array_add(jgroups, jgroup); return save_config(); From patchwork Thu Sep 23 03:25:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511935 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D3FBCC433EF for ; Thu, 23 Sep 2021 03:27:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BBF83610A1 for ; Thu, 23 Sep 2021 03:27:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239065AbhIWD24 (ORCPT ); Wed, 22 Sep 2021 23:28:56 -0400 Received: from mga11.intel.com ([192.55.52.93]:16373 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239066AbhIWD2p (ORCPT ); Wed, 22 Sep 2021 23:28:45 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555930" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555930" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:27:01 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072397" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:27:01 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 16/20] doc/mesh-api: Add ExportKeys call Date: Wed, 22 Sep 2021 20:25:59 -0700 Message-Id: <20210923032603.50536-17-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Add description for a new method: ExportKeys() on org.bluez.mesh.Management1 interface. This method is used by the authorized application to export information about network keys, application keys and device keys present in the local key database. --- doc/mesh-api.txt | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/doc/mesh-api.txt b/doc/mesh-api.txt index ce651c801..85de6705e 100644 --- a/doc/mesh-api.txt +++ b/doc/mesh-api.txt @@ -728,6 +728,62 @@ Methods: PossibleErrors: org.bluez.mesh.Error.InvalidArguments + dict ExportKeys(void) + + This method is used by the application to export information + about network keys, application keys and device keys present + in the local key database. + + dict + A dictionary that contains information for the keys + stored in the keyring with the following keys defined: + + NetKeys: + array{struct} net_keys: + + uint16 index + Subnet index + + array{byte}[16] key + + dict: + A dictionary that contains optional + key info with the following keys + defined: + + uint8 Phase + Key Refresh phase of the subnet + + array{byte}[16] OldKey + + array{struct} AppKeys: + + uint16 index + + Application key index + + array{byte}[16] key + + dict: + A dictionary of optional + key info with the + following keys defined: + + array{byte}[16] OldKey + + DevKeys: + array{struct} dev_keys: + + Device Key information for known remote + nodes in the configured Mesh network + + uint16 unicast + + Unicast address of the node's primary + element + + array{byte}[16] key + Mesh Application Hierarchy ========================== Service unique name From patchwork Thu Sep 23 03:26:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511931 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4BA7DC4332F for ; Thu, 23 Sep 2021 03:27:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 30E6D61131 for ; Thu, 23 Sep 2021 03:27:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239085AbhIWD2z (ORCPT ); Wed, 22 Sep 2021 23:28:55 -0400 Received: from mga11.intel.com ([192.55.52.93]:16381 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239045AbhIWD2p (ORCPT ); Wed, 22 Sep 2021 23:28:45 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555932" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555932" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:27:02 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072404" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:27:02 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 17/20] mesh: Implement ExportKeys() method Date: Wed, 22 Sep 2021 20:26:00 -0700 Message-Id: <20210923032603.50536-18-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Add implementation for new method ExportKeys() on org.bluez.mesh.Management1 interface. This method is used by the authorized application to export information about network keys, application keys and device keys present in the local key database. --- mesh/keyring.c | 286 ++++++++++++++++++++++++++++++++++++++++++++++++- mesh/keyring.h | 2 + mesh/manager.c | 35 ++++++ 3 files changed, 322 insertions(+), 1 deletion(-) diff --git a/mesh/keyring.c b/mesh/keyring.c index f27fe4291..4b901643c 100644 --- a/mesh/keyring.c +++ b/mesh/keyring.c @@ -26,6 +26,7 @@ #include "mesh/mesh-defs.h" +#include "mesh/dbus.h" #include "mesh/node.h" #include "mesh/keyring.h" @@ -276,7 +277,6 @@ bool keyring_get_remote_dev_key(struct mesh_node *node, uint16_t unicast, snprintf(key_file, PATH_MAX, "%s%s/%4.4x", node_path, dev_key_dir, unicast); - fd = open(key_file, O_RDONLY); if (fd >= 0) { if (read(fd, dev_key, 16) == 16) @@ -349,3 +349,287 @@ bool keyring_del_remote_dev_key(struct mesh_node *node, uint16_t unicast, return true; } + +static DIR *open_key_dir(const char *node_path, const char *key_dir_name) +{ + char dir_path[PATH_MAX]; + DIR *key_dir; + + if (strlen(node_path) + strlen(key_dir_name) + 1 >= PATH_MAX) + return NULL; + + snprintf(dir_path, PATH_MAX, "%s%s", node_path, key_dir_name); + + key_dir = opendir(dir_path); + if (!key_dir) { + l_error("Failed to open keyring storage directory: %s", + dir_path); + return NULL; + } + + return key_dir; +} + +static int open_key_dir_entry(int dir_fd, struct dirent *entry, + uint8_t fname_len) +{ + if (entry->d_type != DT_REG) + return -1; + + /* Check the file name length */ + if (strlen(entry->d_name) != fname_len) + return -1; + + return openat(dir_fd, entry->d_name, O_RDONLY); +} + +static void append_old_key(struct l_dbus_message_builder *builder, + const uint8_t key[16]) +{ + l_dbus_message_builder_enter_dict(builder, "sv"); + l_dbus_message_builder_append_basic(builder, 's', "OldKey"); + l_dbus_message_builder_enter_variant(builder, "ay"); + dbus_append_byte_array(builder, key, 16); + l_dbus_message_builder_leave_variant(builder); + l_dbus_message_builder_leave_dict(builder); +} + +static void build_app_keys_reply(const char *node_path, + struct l_dbus_message_builder *builder, + uint16_t net_idx, uint8_t phase) +{ + DIR *key_dir; + int key_dir_fd; + struct dirent *entry; + + key_dir = open_key_dir(node_path, app_key_dir); + if (!key_dir) + return; + + key_dir_fd = dirfd(key_dir); + + l_dbus_message_builder_enter_dict(builder, "sv"); + l_dbus_message_builder_append_basic(builder, 's', "AppKeys"); + l_dbus_message_builder_enter_variant(builder, "a(qaya{sv})"); + l_dbus_message_builder_enter_array(builder, "(qaya{sv})"); + + while ((entry = readdir(key_dir)) != NULL) { + struct keyring_app_key key; + int fd = open_key_dir_entry(key_dir_fd, entry, 3); + + if (fd < 0) + continue; + + if (read(fd, &key, sizeof(key)) != sizeof(key) || + key.net_idx != net_idx) { + close(fd); + continue; + } + + close(fd); + + l_dbus_message_builder_enter_struct(builder, "qaya{sv}"); + + l_dbus_message_builder_append_basic(builder, 'q', &key.app_idx); + dbus_append_byte_array(builder, key.new_key, 16); + + l_dbus_message_builder_enter_array(builder, "{sv}"); + + if (phase != KEY_REFRESH_PHASE_NONE) + append_old_key(builder, key.old_key); + + l_dbus_message_builder_leave_array(builder); + l_dbus_message_builder_leave_struct(builder); + } + + l_dbus_message_builder_leave_array(builder); + l_dbus_message_builder_leave_variant(builder); + l_dbus_message_builder_leave_dict(builder); + + closedir(key_dir); +} + +static bool build_net_keys_reply(const char *node_path, + struct l_dbus_message_builder *builder) +{ + DIR *key_dir; + int key_dir_fd; + struct dirent *entry; + bool result = false; + + key_dir = open_key_dir(node_path, net_key_dir); + if (!key_dir) + return false; + + key_dir_fd = dirfd(key_dir); + + l_dbus_message_builder_enter_dict(builder, "sv"); + l_dbus_message_builder_append_basic(builder, 's', "NetKeys"); + l_dbus_message_builder_enter_variant(builder, "a(qaya{sv})"); + l_dbus_message_builder_enter_array(builder, "(qaya{sv})"); + + while ((entry = readdir(key_dir)) != NULL) { + struct keyring_net_key key; + int fd = open_key_dir_entry(key_dir_fd, entry, 3); + + if (fd < 0) + continue; + + if (read(fd, &key, sizeof(key)) != sizeof(key)) { + close(fd); + goto done; + } + + close(fd); + + /* + * If network key is stuck in phase 3, keyring + * write failed and this key info is unreliable. + */ + if (key.phase == KEY_REFRESH_PHASE_THREE) + continue; + + l_dbus_message_builder_enter_struct(builder, "qaya{sv}"); + + l_dbus_message_builder_append_basic(builder, 'q', &key.net_idx); + dbus_append_byte_array(builder, key.new_key, 16); + + l_dbus_message_builder_enter_array(builder, "{sv}"); + + if (key.phase != KEY_REFRESH_PHASE_NONE) { + dbus_append_dict_entry_basic(builder, "Phase", "y", + &key.phase); + append_old_key(builder, key.old_key); + } + + build_app_keys_reply(node_path, builder, key.net_idx, + key.phase); + + l_dbus_message_builder_leave_array(builder); + l_dbus_message_builder_leave_struct(builder); + } + + l_dbus_message_builder_leave_array(builder); + l_dbus_message_builder_leave_variant(builder); + l_dbus_message_builder_leave_dict(builder); + + result = true; +done: + closedir(key_dir); + + return result; + +} + +struct dev_key_entry { + uint16_t unicast; + uint8_t value[16]; +}; + +static bool match_key_value(const void *a, const void *b) +{ + const struct dev_key_entry *key = a; + const uint8_t *value = b; + + return (memcmp(key->value, value, 16) == 0); +} + +static void build_dev_key_entry(void *a, void *b) +{ + struct dev_key_entry *key = a; + struct l_dbus_message_builder *builder = b; + + l_dbus_message_builder_enter_struct(builder, "qay"); + l_dbus_message_builder_append_basic(builder, 'q', &key->unicast); + dbus_append_byte_array(builder, key->value, 16); + l_dbus_message_builder_leave_struct(builder); +} + +static bool build_dev_keys_reply(const char *node_path, + struct l_dbus_message_builder *builder) +{ + DIR *key_dir; + int key_dir_fd; + struct dirent *entry; + struct l_queue *keys; + bool result = false; + + key_dir = open_key_dir(node_path, dev_key_dir); + /* + * There is always at least one device key present for a local node. + * Therefore, return false, if the directory does not exist. + */ + if (!key_dir) + return false; + + key_dir_fd = dirfd(key_dir); + + keys = l_queue_new(); + + while ((entry = readdir(key_dir)) != NULL) { + uint8_t buf[16]; + uint16_t unicast; + struct dev_key_entry *key; + int fd = open_key_dir_entry(key_dir_fd, entry, 4); + + if (fd < 0) + continue; + + if (read(fd, buf, 16) != 16) { + close(fd); + goto done; + } + + close(fd); + + if (sscanf(entry->d_name, "%04hx", &unicast) != 1) + goto done; + + key = l_queue_find(keys, match_key_value, buf); + + if (key) { + if (key->unicast > unicast) + key->unicast = unicast; + continue; + } + + key = l_new(struct dev_key_entry, 1); + key->unicast = unicast; + memcpy(key->value, buf, 16); + l_queue_push_tail(keys, key); + } + + l_dbus_message_builder_enter_dict(builder, "sv"); + l_dbus_message_builder_append_basic(builder, 's', "DevKeys"); + l_dbus_message_builder_enter_variant(builder, "a(qay)"); + l_dbus_message_builder_enter_array(builder, "(qay)"); + + l_queue_foreach(keys, build_dev_key_entry, builder); + + l_dbus_message_builder_leave_array(builder); + l_dbus_message_builder_leave_variant(builder); + l_dbus_message_builder_leave_dict(builder); + + result = true; +done: + l_queue_destroy(keys, l_free); + closedir(key_dir); + + return result; +} + +bool keyring_build_export_keys_reply(struct mesh_node *node, + struct l_dbus_message_builder *builder) +{ + const char *node_path; + + if (!node) + return false; + + node_path = node_get_storage_dir(node); + + if (!build_net_keys_reply(node_path, builder)) + return false; + + return build_dev_keys_reply(node_path, builder); +} diff --git a/mesh/keyring.h b/mesh/keyring.h index c2d38e9ff..ecf62cbc1 100644 --- a/mesh/keyring.h +++ b/mesh/keyring.h @@ -39,3 +39,5 @@ bool keyring_put_remote_dev_key(struct mesh_node *node, uint16_t unicast, uint8_t count, uint8_t dev_key[16]); bool keyring_del_remote_dev_key(struct mesh_node *node, uint16_t unicast, uint8_t count); +bool keyring_build_export_keys_reply(struct mesh_node *node, + struct l_dbus_message_builder *builder); diff --git a/mesh/manager.c b/mesh/manager.c index d70993e3b..e66b1a45b 100644 --- a/mesh/manager.c +++ b/mesh/manager.c @@ -776,6 +776,38 @@ static struct l_dbus_message *set_key_phase_call(struct l_dbus *dbus, return l_dbus_message_new_method_return(msg); } +static struct l_dbus_message *export_keys_call(struct l_dbus *dbus, + struct l_dbus_message *msg, + void *user_data) +{ + const char *sender = l_dbus_message_get_sender(msg); + struct l_dbus_message_builder *builder; + struct l_dbus_message *reply; + struct mesh_node *node = user_data; + + l_debug("Export Keys"); + + if (strcmp(sender, node_get_owner(node))) + return dbus_error(msg, MESH_ERROR_NOT_AUTHORIZED, NULL); + + reply = l_dbus_message_new_method_return(msg); + builder = l_dbus_message_builder_new(reply); + + l_dbus_message_builder_enter_array(builder, "{sv}"); + + if (!keyring_build_export_keys_reply(node, builder)) { + l_dbus_message_builder_destroy(builder); + l_dbus_message_unref(reply); + return dbus_error(msg, MESH_ERROR_FAILED, NULL); + } + + l_dbus_message_builder_leave_array(builder); + l_dbus_message_builder_finalize(builder); + l_dbus_message_builder_destroy(builder); + + return reply; +} + static void setup_management_interface(struct l_dbus_interface *iface) { l_dbus_interface_method(iface, "AddNode", 0, add_node_call, "", @@ -807,6 +839,9 @@ static void setup_management_interface(struct l_dbus_interface *iface) "app_index", "app_key"); l_dbus_interface_method(iface, "SetKeyPhase", 0, set_key_phase_call, "", "qy", "net_index", "phase"); + l_dbus_interface_method(iface, "ExportKeys", 0, export_keys_call, + "a(qaya{sv})a(qay)", "", + "net_keys", "dev_keys"); } bool manager_dbus_init(struct l_dbus *bus) From patchwork Thu Sep 23 03:26:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511933 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29670C433FE for ; Thu, 23 Sep 2021 03:27:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 14B4760F48 for ; Thu, 23 Sep 2021 03:27:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239092AbhIWD2z (ORCPT ); Wed, 22 Sep 2021 23:28:55 -0400 Received: from mga11.intel.com ([192.55.52.93]:16377 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239065AbhIWD2p (ORCPT ); Wed, 22 Sep 2021 23:28:45 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555933" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555933" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:27:03 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072407" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:27:02 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 18/20] tools/mesh-cfgclient: Store UUIDs in standard format Date: Wed, 22 Sep 2021 20:26:01 -0700 Message-Id: <20210923032603.50536-19-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Use standard xxxx-xx-xx-xx-xxxxxxxx format for string representation of mesh and node UUIDs in stored configuration. --- tools/mesh/mesh-db.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index 0dc811801..b45212fc9 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -293,10 +293,11 @@ static bool write_uint32_hex(json_object *jobj, const char *desc, uint32_t val) static json_object *get_node_by_uuid(json_object *jcfg, uint8_t uuid[16]) { json_object *jarray = NULL; - char buf[33]; + char buf[37]; int i, sz; - hex2str(uuid, 16, buf, sizeof(buf)); + if (!l_uuid_to_string(uuid, buf, sizeof(buf))) + return NULL; json_object_object_get_ex(jcfg, "nodes", &jarray); if (!jarray || json_object_get_type(jarray) != json_type_array) @@ -313,7 +314,7 @@ static json_object *get_node_by_uuid(json_object *jcfg, uint8_t uuid[16]) return NULL; str = json_object_get_string(jval); - if (strlen(str) != 32) + if (strlen(str) != 36) continue; if (!strcmp(buf, str)) @@ -506,10 +507,11 @@ static void load_remotes(json_object *jcfg) continue; str = json_object_get_string(jval); - if (strlen(str) != 32) + if (strlen(str) != 36) continue; - str2hex(str, 32, uuid, 16); + if (!l_uuid_from_string(str, uuid)) + continue; if (!json_object_object_get_ex(jnode, "unicastAddress", &jval)) continue; @@ -1698,6 +1700,7 @@ bool mesh_db_add_node(uint8_t uuid[16], uint8_t num_els, uint16_t unicast, { json_object *jnode; json_object *jelements, *jnodes, *jnetkeys, *jappkeys; + char buf[37]; if (!cfg || !cfg->jcfg) return false; @@ -1712,9 +1715,11 @@ bool mesh_db_add_node(uint8_t uuid[16], uint8_t num_els, uint16_t unicast, if (!jnode) return false; - if (!add_u8_16(jnode, "UUID", uuid)) + if (!l_uuid_to_string(uuid, buf, sizeof(buf))) goto fail; + if (!add_string(jnode, "UUID", buf)) + goto fail; if (!add_string(jnode, "security", "secure")) goto fail; @@ -2065,6 +2070,7 @@ bool mesh_db_add_provisioner(const char *name, uint8_t uuid[16], uint16_t group_low, uint16_t group_high) { json_object *jprovs, *jprov, *jscenes; + char buf[37]; if (!cfg || !cfg->jcfg) return false; @@ -2080,7 +2086,10 @@ bool mesh_db_add_provisioner(const char *name, uint8_t uuid[16], if (!add_string(jprov, "provisionerName", name)) goto fail; - if (!add_u8_16(jprov, "UUID", uuid)) + if (!l_uuid_to_string(uuid, buf, sizeof(buf))) + goto fail; + + if (!add_string(jprov, "UUID", buf)) goto fail; if (!add_range(jprov, "allocatedUnicastRange", unicast_low, @@ -2270,6 +2279,7 @@ bool mesh_db_create(const char *fname, const uint8_t token[8], { json_object *jcfg, *jarray; uint8_t uuid[16]; + char buf[37]; if (cfg) return false; @@ -2291,7 +2301,10 @@ bool mesh_db_create(const char *fname, const uint8_t token[8], l_uuid_v4(uuid); - if (!add_u8_16(jcfg, "meshUUID", uuid)) + if (!l_uuid_to_string(uuid, buf, sizeof(buf))) + goto fail; + + if (!add_string(jcfg, "meshUUID", buf)) goto fail; if (mesh_name && !add_string(jcfg, "meshName", mesh_name)) From patchwork Thu Sep 23 03:26:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511939 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD676C433FE for ; Thu, 23 Sep 2021 03:27:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9415A60F48 for ; Thu, 23 Sep 2021 03:27:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239091AbhIWD27 (ORCPT ); Wed, 22 Sep 2021 23:28:59 -0400 Received: from mga11.intel.com ([192.55.52.93]:16373 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239072AbhIWD2q (ORCPT ); Wed, 22 Sep 2021 23:28:46 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555935" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555935" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:27:03 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072410" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:27:03 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 19/20] tools/mesh-cfgclient: Excluded addresses property Date: Wed, 22 Sep 2021 20:26:02 -0700 Message-Id: <20210923032603.50536-20-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org The correct name for a property that contains a list of addresses not allowed in circulation is "networkExclusions" The "excluded" property in "nodes" array entry is used to indicated that this node has been removed from a mesh network and it's address should not be re-used. --- tools/mesh/mesh-db.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index b45212fc9..262a274c7 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -1724,7 +1724,7 @@ bool mesh_db_add_node(uint8_t uuid[16], uint8_t num_els, uint16_t unicast, if (!add_string(jnode, "security", "secure")) goto fail; - if (!write_bool(jnode, "blacklisted", false)) + if (!write_bool(jnode, "excluded", false)) goto fail; if (!write_bool(jnode, "configComplete", false)) @@ -2165,7 +2165,7 @@ static bool load_rejected_addresses(json_object *jobj) json_object *jarray; int i, cnt; - json_object_object_get_ex(jobj, "blacklistedAddresses", &jarray); + json_object_object_get_ex(jobj, "networkExclusions", &jarray); if (!jarray || json_object_get_type(jarray) != json_type_array) return true; @@ -2212,11 +2212,10 @@ bool mesh_db_add_rejected_addr(uint16_t unicast, uint32_t iv_index) if (!cfg || !cfg->jcfg) return false; - json_object_object_get_ex(cfg->jcfg, "blacklistedAddresses", &jarray); + json_object_object_get_ex(cfg->jcfg, "networkExclusions", &jarray); if (!jarray) { jarray = json_object_new_array(); - json_object_object_add(cfg->jcfg, "blacklistedAddresses", - jarray); + json_object_object_add(cfg->jcfg, "networkExclusions", jarray); } idx = get_rejected_by_iv_index(jarray, iv_index); @@ -2261,7 +2260,7 @@ bool mesh_db_clear_rejected(uint32_t iv_index) if (!cfg || !cfg->jcfg) return false; - json_object_object_get_ex(cfg->jcfg, "blacklistedAddresses", &jarray); + json_object_object_get_ex(cfg->jcfg, "networkExclusions", &jarray); if (!jarray || json_object_get_type(jarray) != json_type_array) return false; @@ -2338,7 +2337,7 @@ bool mesh_db_create(const char *fname, const uint8_t token[8], if (!jarray) goto fail; - json_object_object_add(jcfg, "blacklistedAddresses", jarray); + json_object_object_add(jcfg, "networkExclusions", jarray); write_int(jcfg, "ivIndex", 0); From patchwork Thu Sep 23 03:26:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stotland, Inga" X-Patchwork-Id: 12511937 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B014FC433EF for ; Thu, 23 Sep 2021 03:27:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9AE1961038 for ; Thu, 23 Sep 2021 03:27:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239084AbhIWD25 (ORCPT ); Wed, 22 Sep 2021 23:28:57 -0400 Received: from mga11.intel.com ([192.55.52.93]:16381 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239071AbhIWD2q (ORCPT ); Wed, 22 Sep 2021 23:28:46 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10115"; a="220555937" X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="220555937" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:27:04 -0700 X-IronPort-AV: E=Sophos;i="5.85,315,1624345200"; d="scan'208";a="534072414" Received: from jdudwadk-mobl.amr.corp.intel.com (HELO istotlan-desk.intel.com) ([10.212.205.211]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2021 20:27:04 -0700 From: Inga Stotland To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, Inga Stotland Subject: [PATCH BlueZ 20/20] tools/mesh-cfgclient: Export configuration database Date: Wed, 22 Sep 2021 20:26:03 -0700 Message-Id: <20210923032603.50536-21-inga.stotland@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com> References: <20210923032603.50536-1-inga.stotland@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This adds main menu command "export-db". When the command is invoked, JSON configuration object is cloned and trimmed of extraneous properties. Information about netkeys, appkeys and device keys are obtained from bluetooth-meshd by calling ExportKeys() method. The obtained key values are recorded in the export JSON object. --- tools/mesh-cfgclient.c | 195 +++++++++++++++++++++++++++++++++++++++++ tools/mesh/mesh-db.c | 191 ++++++++++++++++++++++++++++++++++++++++ tools/mesh/mesh-db.h | 7 ++ 3 files changed, 393 insertions(+) diff --git a/tools/mesh-cfgclient.c b/tools/mesh-cfgclient.c index beeb115dc..237afbb5f 100644 --- a/tools/mesh-cfgclient.c +++ b/tools/mesh-cfgclient.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,7 @@ #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; @@ -835,6 +837,197 @@ static void cmd_scan_unprov(int argc, char *argv[]) } +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); @@ -1395,6 +1588,8 @@ static const struct bt_shell_menu main_menu = { "List remote mesh nodes"}, { "keys", NULL, cmd_keys, "List available keys"}, + { "export-db", NULL, cmd_export_db, + "Export mesh configuration database"}, { } }, }; diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c index 262a274c7..12055c1a9 100644 --- a/tools/mesh/mesh-db.c +++ b/tools/mesh/mesh-db.c @@ -48,6 +48,13 @@ static struct mesh_db *cfg; static const char *bak_ext = ".bak"; static const char *tmp_ext = ".tmp"; +static const char *js_schema = "http://json-schema.org/draft-04/schema#"; +static const char *schema_id = "http://www.bluetooth.com/specifications/" + "assigned-numbers/mesh-profile/" + "cdb-schema.json#"; +const char *schema_version = "1.0.0"; + + static bool add_string(json_object *jobj, const char *desc, const char *str) { json_object *jstring = json_object_new_string(str); @@ -2412,3 +2419,187 @@ fail: return false; } + +bool mesh_db_set_device_key(void *expt_cfg, uint16_t unicast, uint8_t key[16]) +{ + json_object *jnode; + + if (!expt_cfg) + return false; + + jnode = get_node_by_unicast(expt_cfg, unicast); + if (!jnode) + return false; + + return add_u8_16(jnode, "deviceKey", key); +} + +bool mesh_db_set_net_key(void *expt_cfg, uint16_t idx, uint8_t key[16], + uint8_t *old_key, uint8_t phase) +{ + json_object *jarray, *jkey; + + if (!expt_cfg) + return false; + + json_object_object_get_ex(expt_cfg, "netKeys", &jarray); + if (!jarray || json_object_get_type(jarray) != json_type_array) + return false; + + jkey = get_key_object(jarray, idx); + if (!jkey) + return false; + + if (!write_int(jkey, "phase", phase)) + return false; + + if (!add_u8_16(jkey, "key", key)) + return false; + + if (old_key && !(!add_u8_16(jkey, "oldKey", old_key))) + return false; + + return true; +} + + +bool mesh_db_set_app_key(void *expt_cfg, uint16_t net_idx, uint16_t app_idx, + uint8_t key[16], uint8_t *old_key) +{ + json_object *jarray, *jkey; + + if (!expt_cfg) + return false; + + json_object_object_get_ex(expt_cfg, "appKeys", &jarray); + if (!jarray || json_object_get_type(jarray) != json_type_array) + return false; + + jkey = get_key_object(jarray, app_idx); + if (!jkey) + return false; + + if (!add_u8_16(jkey, "key", key)) + return false; + + if (old_key && !(!add_u8_16(jkey, "oldKey", old_key))) + return false; + + return true; +} + +void *mesh_db_prepare_export(void) +{ + json_object *export = NULL, *jarray; + + if (!cfg || !cfg->jcfg) + return false; + + if (json_object_deep_copy(cfg->jcfg, &export, NULL) != 0) + return NULL; + + /* Delete token */ + json_object_object_del(export, "token"); + + /* Delete IV index */ + json_object_object_del(export, "ivIndex"); + + /* Scenes are not supported. Just add an empty array */ + jarray = json_object_new_array(); + json_object_object_add(export, "scenes", jarray); + + write_bool(export, "partial", false); + + return export; +} + +bool mesh_db_finish_export(bool is_error, void *expt_cfg, const char *fname) +{ + FILE *outfile = NULL; + const char *str, *hdr; + json_object *jhdr = NULL; + bool result = false; + char *pos; + + uint32_t sz; + + if (!expt_cfg) + return false; + + if (is_error) { + json_object_put(expt_cfg); + return true; + } + + if (!fname) + goto done; + + outfile = fopen(fname, "w"); + if (!outfile) { + l_error("Failed to save configuration to %s", fname); + goto done; + } + + jhdr = json_object_new_object(); + if (!add_string(jhdr, "$schema", js_schema)) + goto done; + + if (!add_string(jhdr, "id", schema_id)) + goto done; + + if (!add_string(jhdr, "version", schema_version)) + goto done; + + hdr = json_object_to_json_string_ext(jhdr, JSON_C_TO_STRING_PRETTY | + JSON_C_TO_STRING_NOSLASHESCAPE); + + str = json_object_to_json_string_ext(expt_cfg, JSON_C_TO_STRING_PRETTY | + JSON_C_TO_STRING_NOSLASHESCAPE); + + if (!hdr || !str) + goto done; + + /* + * Write two strings to the output while stripping closing "}" from the + * header string and opening "{" from the config object. + */ + + pos = strrchr(hdr, '}'); + if (!pos) + goto done; + + *pos = '\0'; + + pos = strrchr(hdr, '"'); + if (!pos) + goto done; + + pos[1] = ','; + + if (fwrite(hdr, sizeof(char), strlen(hdr), outfile) < strlen(hdr)) + goto done; + + pos = strchr(str, '{'); + if (!pos || pos[1] == '\0') + goto done; + + pos++; + + sz = strlen(pos); + + if (fwrite(pos, sizeof(char), sz, outfile) < sz) + goto done; + + result = true; + +done: + if (outfile) + fclose(outfile); + + json_object_put(expt_cfg); + + if (jhdr) + json_object_put(jhdr); + + return result; +} diff --git a/tools/mesh/mesh-db.h b/tools/mesh/mesh-db.h index 16c46c046..4b6b2adb3 100644 --- a/tools/mesh/mesh-db.h +++ b/tools/mesh/mesh-db.h @@ -82,3 +82,10 @@ struct l_queue *mesh_db_load_groups(void); bool mesh_db_add_group(struct mesh_group *grp); bool mesh_db_add_rejected_addr(uint16_t unicast, uint32_t iv_index); bool mesh_db_clear_rejected(uint32_t iv_index); +bool mesh_db_set_device_key(void *expt_cfg, uint16_t unicast, uint8_t key[16]); +bool mesh_db_set_net_key(void *expt_cfg, uint16_t idx, uint8_t key[16], + uint8_t *old_key, uint8_t phase); +bool mesh_db_set_app_key(void *expt_cfg, uint16_t net_idx, uint16_t app_idx, + uint8_t key[16], uint8_t *old_key); +void *mesh_db_prepare_export(void); +bool mesh_db_finish_export(bool is_error, void *expt_cfg, const char *fname);