From patchwork Wed Jan 17 14:34:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Herbrechtsmeier X-Patchwork-Id: 862292 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=googlegroups.com (client-ip=2a00:1450:4010:c07::23e; helo=mail-lf0-x23e.google.com; envelope-from=swupdate+bncbdn7dbh5yqibbt567xjakgqef7ledgi@googlegroups.com; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.b="J8N22zP5"; dkim-atps=neutral Received: from mail-lf0-x23e.google.com (mail-lf0-x23e.google.com [IPv6:2a00:1450:4010:c07::23e]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zM8lj69Rtz9s71 for ; Thu, 18 Jan 2018 01:36:01 +1100 (AEDT) Received: by mail-lf0-x23e.google.com with SMTP id q6sf6154869lfi.23 for ; Wed, 17 Jan 2018 06:36:01 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1516199759; cv=pass; d=google.com; s=arc-20160816; b=b6NiSOXE4hJSwXG/22dStZ5TYmdv62zkd4Ubw0Kjr/6noUtv/ES7OutBA+NqI4ipoo pJGN/pVzb4qQV+OfA+0geOUAPwCQnve40XzDZ+9huRtq7HzjSI8MZS8qSgck1J8GLNkM JnvPsvYaj6iamNxlS94hAK/OlLspiJedDanSkgPUCjd0zVwS+f4RjiXcWfkNoM8Tqmu9 ONdZGebEWA89m+CtmKo56qyPmHfihMQAw+Dlp4eMwz8r7nKacjlHoO4ItSMAH7eoh39S NRrbynXW0AokGQbvX9rZEMNYqkzK45+8jn5+4hCkxDKvIFeA7s917tm99IU2mwN9j7gx HzLQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:arc-authentication-results :arc-message-signature:mime-version:sender:dkim-signature :arc-authentication-results; bh=wNU5b920Ltrci4G4YqkX/4DbCIBVKzfjxtbC85tJG4w=; b=GtLt6zcbaYPuB1HI933R4r6pj+mLmBYAObUTi5GDJfNqFWwQeDTvZ2H1EMKBJdINP5 sMHJo/S/2NYFsSo/vKi6neBMhPXvUfL/X5OQRAVALKaX5TXZl5UUGTzNoePt1Fz8Nllu 2pVOXTeY4PALlj+OFe0AQFzhVxcXVLKOPUbgFOeG/4SKgIqp56lslvXNQ7uApvxuX59L OvHtPcaSTFyZ1p0so7Qm3PIroEei7cQ4pQbiidSIPCtJD3TPgAMiXybuAV62wS5cBSVk IG7LfvoBSZ1rKCFbapa/gOM+ncRV++9zQ3KQLURnQG9Z6NQHx4XCGqcOikT0PgSnIrhO mD9g== ARC-Authentication-Results: i=2; gmr-mx.google.com; spf=neutral (google.com: 85.13.157.12 is neither permitted nor denied by best guess record for domain of stefan@herbrechtsmeier.net) smtp.mailfrom=stefan@herbrechtsmeier.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20161025; h=sender:mime-version:from:to:cc:subject:date:message-id:in-reply-to :references:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-subscribe:list-unsubscribe; bh=wNU5b920Ltrci4G4YqkX/4DbCIBVKzfjxtbC85tJG4w=; b=J8N22zP5lTPAfcjVhz/qB1amTaWy3ThslBi7udoyRokss+x2rtb3pvHcOzNEXzlB87 YNsnHwNYOZ35luQdqLBJ2enXba2rF3OKPBFLvR4iOyC6vESZVTeboA7HMz3EzheqtGvy jTdO4lswcpk1PXet8EfpK744daoOBHm791VfQL3SiMl1OM9PO7bbCRTmmuJ6D0wmEKck LBvxsOfpvA+04BjZ0cuiTy3pLys2tqeNscugx8JQNAa4BcAXl/Vgn23N7u+37e414UWX dkJIw2cfNvQmCm4DjNbiCkZ9MCPn92U/VJwj3dqm9xDHJZIwog8fBMZduaheq0igCDSy 1uYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=sender:x-gm-message-state:mime-version:from:to:cc:subject:date :message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-spam-checked-in-group:list-post:list-help:list-archive :list-subscribe:list-unsubscribe; bh=wNU5b920Ltrci4G4YqkX/4DbCIBVKzfjxtbC85tJG4w=; b=mUbzia5/yDLklR7A1GPZlWxUJ96kq41hIFpqllUbEtUp0fwUtlQrYOqfAyluu98v4y URDP1Z2xNcOvn3yVkuhrsJ6UqmowIFNaOCLklPVaIwwkA4ZGLBGJyEnDKh9fNW8Rrb2U rp1iKXb4+SDRp3EoWYmu1awujOWAfAqZoLVGprYX/CWrGsLX4lid/bFxfMG/9VqkNCtm P3k85N51zdgWFsoGM+8BNOk9WMIRIwEnkdSbV4QZAvb2viRGsJebQiXTMUxgDbu5vloj ajXvMYSL24fFVaF21e4rbgimH5gZYfjdrdRddfeiU6YLvY1NKdFmnBRmAzrylgDR+5Hd Enyg== Sender: swupdate@googlegroups.com X-Gm-Message-State: AKwxytcaXWY9C6xY1yS2e28IcPU9Bm9Ibze8xn9UMRHG45HdNUaehttG nkPlXl5Jc/du2JoOEH7JqJE= X-Google-Smtp-Source: ACJfBov6Xv9jA3OJjiLI6YmKt2LRRyJRJbyrnaNVEUxzqnA09jMsY3CbPrjAr2Fl9Ab9cmtnl5roEQ== X-Received: by 10.25.24.166 with SMTP id 38mr52436lfy.7.1516199759143; Wed, 17 Jan 2018 06:35:59 -0800 (PST) MIME-Version: 1.0 X-BeenThere: swupdate@googlegroups.com Received: by 10.46.34.1 with SMTP id i1ls718908lji.14.gmail; Wed, 17 Jan 2018 06:35:58 -0800 (PST) X-Received: by 10.46.69.136 with SMTP id s130mr806052lja.10.1516199758578; Wed, 17 Jan 2018 06:35:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516199758; cv=none; d=google.com; s=arc-20160816; b=zOQKVTtk/S6WlBDkC9HOl6UdckK1kSDNUbGXij0pfoI+dVmFLjZBfrDVot59mvK1sK 5JSNtES29nNjsa93j770BcpI83L8nZKoFEcC9tXK9AA+W55xJ9FgRMrdiI+3DomgbB67 jZmFRlHfPyndGlIYm0K49M2TrwLg+qpfNQ/z7c+r9RNVxHtL1T4QNFstB22As8TycTz6 GOeVKPLu3lwej7uMRdLVHx4P7R9bYtUmXxRpkA7AvL8M1FMdWxLiHMIcmLt2tiRSwWgd iJuRy6SOvIx4tGDwoGVD27vHsXBBkX2xr3krTGSbJX0I/liXf1nV8zh7IB7uIQKOiT+E 01+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=ENgOEF5SUss0l9joEwkGxuVhtq2DXMyonz7/KlZh7L0=; b=rW7GPLPG1XnRvF0ExfAa2hDr4DM9QGQDZC4EcAyzI+W4fboz0aek0YbUWiDwhMjwwX y8v2obpmtJ81H97PixHmxs1uo/fA8kNMTciiQvlbiDGkL7Kt0jjdgn5qs5KM2Ky3QN3G bmYWjOFc/zg8LXD85GBw1oyVFSfKWa8HBouIUOyvbhKMsP62q12Gf4O/JdtlKuiByqtg m28HyFqCKSED+I5ilHi3pw34BkqaN2YZbNCKT9rXcASx/ao1OY89JQkwcZ+28j3BOJ58 5lkOa39QDicGvuS2uIuveQAqCpgEsE/SjxMBWlEgCTgwzrWaUxnzSblR7RlrBwVtqP66 XTfw== ARC-Authentication-Results: i=1; gmr-mx.google.com; spf=neutral (google.com: 85.13.157.12 is neither permitted nor denied by best guess record for domain of stefan@herbrechtsmeier.net) smtp.mailfrom=stefan@herbrechtsmeier.net Received: from dd41138.kasserver.com (dd41138.kasserver.com. [85.13.157.12]) by gmr-mx.google.com with ESMTPS id b10si451244lfe.4.2018.01.17.06.35.58 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 17 Jan 2018 06:35:58 -0800 (PST) Received-SPF: neutral (google.com: 85.13.157.12 is neither permitted nor denied by best guess record for domain of stefan@herbrechtsmeier.net) client-ip=85.13.157.12; Received: from WS08941.weidmueller.com (unknown [217.244.7.16]) by dd41138.kasserver.com (Postfix) with ESMTPSA id 84BB311A0698; Wed, 17 Jan 2018 15:35:57 +0100 (CET) From: stefan@herbrechtsmeier.net To: swupdate@googlegroups.com Cc: Stefan Herbrechtsmeier Subject: [swupdate] [PATCH v2 3/5] parser: Replace properties array with a group of properties Date: Wed, 17 Jan 2018 15:34:04 +0100 Message-Id: <1516199646-5607-3-git-send-email-stefan@herbrechtsmeier.net> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516199646-5607-1-git-send-email-stefan@herbrechtsmeier.net> References: <1516199646-5607-1-git-send-email-stefan@herbrechtsmeier.net> X-Original-Sender: stefan@herbrechtsmeier.net X-Original-Authentication-Results: gmr-mx.google.com; spf=neutral (google.com: 85.13.157.12 is neither permitted nor denied by best guess record for domain of stefan@herbrechtsmeier.net) smtp.mailfrom=stefan@herbrechtsmeier.net Precedence: list Mailing-list: list swupdate@googlegroups.com; contact swupdate+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: swupdate@googlegroups.com X-Google-Group-Id: 605343134186 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , From: Stefan Herbrechtsmeier Signed-off-by: Stefan Herbrechtsmeier Reviewed-by: Stefano Babic Tested-by: Stefano Babic --- Changes in v3: - Suppress build warning if libconfig or libjson are disabled - Suppress build warning if both libconfig and libjson are disabled - Update the documentation of the SWU forwarder - Add an array to the documentation example of SWU forwarder Changes in v2: - Check name and value inside add_properties_cb function to skip NULL values - Add support for properties with value arrays corelib/parsing_library.c | 16 ++++++++++++++++ corelib/parsing_library_libconfig.c | 24 ++++++++++++++++++++++++ corelib/parsing_library_libjson.c | 31 +++++++++++++++++++++++++++++++ doc/source/handlers.rst | 12 +++++------- include/parselib.h | 9 +++++++++ parser/parser.c | 35 +++++++++++++++-------------------- 6 files changed, 100 insertions(+), 27 deletions(-) diff --git a/corelib/parsing_library.c b/corelib/parsing_library.c index 5d30f2d..767d30d 100644 --- a/corelib/parsing_library.c +++ b/corelib/parsing_library.c @@ -62,6 +62,22 @@ void *get_child(parsertype p, void *e, const char *name) return NULL; } +void iterate_field(parsertype p, void *e, iterate_callback cb, void *data) +{ + switch (p) { + case LIBCFG_PARSER: + iterate_field_libconfig(e, cb, data); + break; + case JSON_PARSER: + iterate_field_json(e, cb, data); + break; + default: + (void)e; + (void)cb; + (void)data; + } +} + void *get_elem_from_idx(parsertype p, void *node, int idx) { switch (p) { diff --git a/corelib/parsing_library_libconfig.c b/corelib/parsing_library_libconfig.c index 0664712..415116b 100644 --- a/corelib/parsing_library_libconfig.c +++ b/corelib/parsing_library_libconfig.c @@ -47,6 +47,30 @@ void *get_child_libconfig(void *e, const char *name) return config_setting_get_member(e, name); } +void iterate_field_libconfig(config_setting_t *e, iterate_callback cb, void *data) +{ + config_setting_t *entry, *elem; + const char *str; + int i, j; + + if (!cb) + return; + + for (i = 0; i < config_setting_length(e); i++) { + entry = config_setting_get_elem(e, i); + if (!config_setting_length(entry)) { + str = config_setting_get_string(entry); + cb(entry->name, str, data); + } else { + for (j = 0; j < config_setting_length(entry); j++) { + elem = config_setting_get_elem(entry, j); + str = config_setting_get_string(elem); + cb(entry->name, str, data); + } + } + } +} + void get_field_cfg(config_setting_t *e, const char *path, void *dest) { config_setting_t *elem; diff --git a/corelib/parsing_library_libjson.c b/corelib/parsing_library_libjson.c index 844aca9..e24d1e9 100644 --- a/corelib/parsing_library_libjson.c +++ b/corelib/parsing_library_libjson.c @@ -51,6 +51,37 @@ void *get_child_json(json_object *e, const char *path) return node; } +void iterate_field_json(json_object *e, iterate_callback cb, void *data) +{ + json_object *subnode; + const char *str; + int i; + + if (!cb || json_object_get_type(e) != json_type_object) + return; + + json_object_object_foreach(e, key, node) { + switch (json_object_get_type(node)) { + case json_type_string: + str = json_object_get_string(node); + cb(key, str, data); + break; + case json_type_array: + for (i = 0; i < json_object_array_length(node); i++) { + subnode = json_object_array_get_idx(node, i); + if (json_object_get_type(subnode) != json_type_string) + continue; + + str = json_object_get_string(subnode); + cb(key, str, data); + } + break; + default: + break; + } + } +} + const char *get_field_string_json(json_object *e, const char *path) { const char *str; diff --git a/doc/source/handlers.rst b/doc/source/handlers.rst index 74bf94a..a27647f 100644 --- a/doc/source/handlers.rst +++ b/doc/source/handlers.rst @@ -321,8 +321,8 @@ is connected to the network and the "slaves" are hidden to the external world. The master is then the only interface to the world. A general SWU can contain embedded SWU images as single artifacts, and the SWU handler will forward it to the devices listed in the description of the artifact. -The handler can have a list of "url" properties. Each url is the address of a -secondary board where SWUpdate is running with webserver activated. +The handler can have a single "url" properties entry with an array of urls. Each url +is the address of a secondary board where SWUpdate is running with webserver activated. The SWU handler expects to talk with SWUpdate's embedded webserver. This helps to update systems where an old version of SWUpdate is running, because the embedded webserver is a common feature present in all versions. @@ -340,9 +340,7 @@ the SWU forwarder: filename = "image.swu"; type = "swuforward"; - properties: ( - { - name = "url"; - value = "http://192.168.178.41:8080"; - }); + properties: { + url = ["http://192.168.178.41:8080", "http://192.168.178.42:8080"]; + }; }); diff --git a/include/parselib.h b/include/parselib.h index e189751..f53dd00 100644 --- a/include/parselib.h +++ b/include/parselib.h @@ -15,6 +15,9 @@ typedef enum { JSON_PARSER } parsertype; +typedef void (*iterate_callback)(const char *name, const char *value, + void *data); + #ifdef CONFIG_LIBCONFIG #include #define LIBCONFIG_VERSION ((LIBCONFIG_VER_MAJOR << 16) | \ @@ -26,6 +29,8 @@ typedef enum { void get_value_libconfig(const config_setting_t *e, void *dest); void get_field_cfg(config_setting_t *e, const char *path, void *dest); void *get_child_libconfig(void *e, const char *name); +void iterate_field_libconfig(config_setting_t *e, iterate_callback cb, + void *data); const char *get_field_string_libconfig(config_setting_t *e, const char *path); #else @@ -35,6 +40,7 @@ const char *get_field_string_libconfig(config_setting_t *e, const char *path); #define find_node_libconfig(cfg, field, swcfg) (NULL) #define get_field_string_libconfig(e, path) (NULL) #define get_child_libconfig(e, name) (NULL) +#define iterate_field_libconfig(e, cb, data) { } #define get_field_cfg(e, path, dest) #endif @@ -45,6 +51,7 @@ const char *get_field_string_json(json_object *e, const char *path); void get_value_json(json_object *e, void *dest); void get_field_json(json_object *e, const char *path, void *dest); void *get_child_json(json_object *e, const char *name); +void iterate_field_json(json_object *e, iterate_callback cb, void *data); json_object *find_json_recursive_node(json_object *root, const char **names); json_object *json_get_key(json_object *json_root, const char *key); const char *json_get_value(struct json_object *json_root, @@ -56,6 +63,7 @@ char *json_get_data_url(json_object *json_root, const char *key); #define find_node_json(a, b, c) (NULL) #define get_field_string_json(e, path) (NULL) #define get_child_json(e, name) (NULL) +#define iterate_field_json(e, cb, data) { } #define get_field_json(e, path, dest) #define json_object_object_get_ex(a,b,c) (0) #define json_object_array_get_idx(a, b) (0) @@ -70,6 +78,7 @@ void get_field_string_with_size(parsertype p, void *e, const char *path, int get_array_length(parsertype p, void *root); void *get_elem_from_idx(parsertype p, void *node, int idx); void *get_child(parsertype p, void *node, const char *name); +void iterate_field(parsertype p, void *e, iterate_callback cb, void *data); void get_field(parsertype p, void *e, const char *path, void *dest); int exist_field_string(parsertype p, void *e, const char *path); void get_hash_value(parsertype p, void *elem, unsigned char *hash); diff --git a/parser/parser.c b/parser/parser.c index 2e9208d..f07559d 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -140,32 +140,27 @@ static void *find_node(parsertype p, void *root, const char *node, return NULL; } -static void add_properties(parsertype p, void *node, struct img_type *image) +static void add_properties_cb(const char *name, const char *value, void *data) { + struct img_type *image = (struct img_type *)data; - void *properties, *prop; - int count, i; + if (!name || !value) + return; + + TRACE("\t\tProperty %s: %s", name, value); + if (dict_insert_value(&image->properties, (char *)name, (char *)value)) + ERROR("Property not stored, skipping..."); +} + +static void add_properties(parsertype p, void *node, struct img_type *image) +{ + void *properties; properties = get_child(p, node, "properties"); if (properties) { - count = get_array_length(p, properties); - - TRACE("Found %d properties for %s:", count, image->fname); - - for (i = 0; i < count; i++) { - char key[255]; - char value[255]; - prop = get_elem_from_idx(p, properties, i); - GET_FIELD_STRING(p, prop, "name", key); - GET_FIELD_STRING(p, prop, "value", value); - TRACE("\t\tProperty %d: name=%s val=%s ", i, - key, - value - ); - if (dict_insert_value(&image->properties, key, value)) - ERROR("Property not stored, skipping..."); + TRACE("Found properties for %s:", image->fname); - } + iterate_field(p, properties, add_properties_cb, image); } }