From 7d991d89be0e84ab181142656340df5d2c4d0271 Mon Sep 17 00:00:00 2001 From: Sukru Senli Date: Tue, 20 Apr 2021 19:19:26 +0200 Subject: [PATCH] move bulkdata, twamp and udpechoserver to their individual repos --- bulkdata/Makefile | 16 +- bulkdata/src/Makefile | 23 - bulkdata/src/buci.c | 265 ------ bulkdata/src/buci.h | 31 - bulkdata/src/bulkdata.c | 144 --- bulkdata/src/bulkdata.h | 18 - bulkdata/src/bulkdata.md | 105 --- bulkdata/src/common.c | 450 --------- bulkdata/src/common.h | 69 -- bulkdata/src/config.c | 523 ----------- bulkdata/src/config.h | 103 -- bulkdata/src/datamodel.c | 1293 -------------------------- bulkdata/src/datamodel.h | 29 - bulkdata/src/http.c | 196 ---- bulkdata/src/http.h | 37 - bulkdata/src/log.c | 57 -- bulkdata/src/log.h | 28 - bulkdata/src/report.c | 336 ------- bulkdata/src/report.h | 24 - bulkdata/src/times.c | 62 -- bulkdata/src/times.h | 19 - twamp/Makefile | 16 +- twamp/src/Makefile | 23 - twamp/src/datamodel.c | 302 ------ twamp/src/datamodel.h | 17 - twamp/src/twamp.c | 858 ----------------- twamp/src/twamp.h | 237 ----- twamp/src/twamp.md | 57 -- twamp/src/twamplog.c | 55 -- twamp/src/twamplog.h | 27 - twamp/src/twamptimestamp.c | 195 ---- twamp/src/twampuci.c | 266 ------ twamp/src/twampuci.h | 34 - udpechoserver/Makefile | 20 +- udpechoserver/src/Makefile | 23 - udpechoserver/src/datamodel.c | 213 ----- udpechoserver/src/datamodel.h | 17 - udpechoserver/src/udpechoserver.c | 230 ----- udpechoserver/src/udpechoserver.h | 56 -- udpechoserver/src/udpechoserver.md | 40 - udpechoserver/src/udpechoserverlog.c | 55 -- udpechoserver/src/udpechoserverlog.h | 27 - udpechoserver/src/udpechoserveruci.c | 182 ---- udpechoserver/src/udpechoserveruci.h | 25 - 44 files changed, 35 insertions(+), 6768 deletions(-) delete mode 100644 bulkdata/src/Makefile delete mode 100644 bulkdata/src/buci.c delete mode 100644 bulkdata/src/buci.h delete mode 100644 bulkdata/src/bulkdata.c delete mode 100644 bulkdata/src/bulkdata.h delete mode 100644 bulkdata/src/bulkdata.md delete mode 100644 bulkdata/src/common.c delete mode 100644 bulkdata/src/common.h delete mode 100644 bulkdata/src/config.c delete mode 100644 bulkdata/src/config.h delete mode 100644 bulkdata/src/datamodel.c delete mode 100644 bulkdata/src/datamodel.h delete mode 100644 bulkdata/src/http.c delete mode 100644 bulkdata/src/http.h delete mode 100644 bulkdata/src/log.c delete mode 100644 bulkdata/src/log.h delete mode 100644 bulkdata/src/report.c delete mode 100644 bulkdata/src/report.h delete mode 100644 bulkdata/src/times.c delete mode 100644 bulkdata/src/times.h delete mode 100644 twamp/src/Makefile delete mode 100644 twamp/src/datamodel.c delete mode 100644 twamp/src/datamodel.h delete mode 100644 twamp/src/twamp.c delete mode 100644 twamp/src/twamp.h delete mode 100644 twamp/src/twamp.md delete mode 100644 twamp/src/twamplog.c delete mode 100644 twamp/src/twamplog.h delete mode 100644 twamp/src/twamptimestamp.c delete mode 100644 twamp/src/twampuci.c delete mode 100644 twamp/src/twampuci.h delete mode 100644 udpechoserver/src/Makefile delete mode 100644 udpechoserver/src/datamodel.c delete mode 100644 udpechoserver/src/datamodel.h delete mode 100644 udpechoserver/src/udpechoserver.c delete mode 100644 udpechoserver/src/udpechoserver.h delete mode 100644 udpechoserver/src/udpechoserver.md delete mode 100644 udpechoserver/src/udpechoserverlog.c delete mode 100644 udpechoserver/src/udpechoserverlog.h delete mode 100644 udpechoserver/src/udpechoserveruci.c delete mode 100644 udpechoserver/src/udpechoserveruci.h diff --git a/bulkdata/Makefile b/bulkdata/Makefile index 413a12d32..6e81f975c 100755 --- a/bulkdata/Makefile +++ b/bulkdata/Makefile @@ -10,8 +10,18 @@ include $(TOPDIR)/rules.mk PKG_NAME:=bulkdata PKG_VERSION:=1.0.0 +PKG_SOURCE_VERSION:=4ac9d7a7e90f5de5f43d6bf3d1a844114a46b134 +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/bulkdata.git + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz +PKG_MIRROR_HASH:=skip +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_LICENSE:=GPL-2.0-only +PKG_LICENSE_FILES:=LICENSE + include $(INCLUDE_DIR)/package.mk define Package/$(PKG_NAME) @@ -26,10 +36,6 @@ define Package/$(PKG_NAME)/description BBF BulkData Collection endef -define Build/Prepare - $(CP) ./src/* $(PKG_BUILD_DIR)/ -endef - TARGET_CFLAGS += \ -D_GNU_SOURCE @@ -41,4 +47,4 @@ define Package/$(PKG_NAME)/install $(CP) ./files/* $(1)/ endef -$(eval $(call BuildPackage,$(PKG_NAME))) \ No newline at end of file +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/bulkdata/src/Makefile b/bulkdata/src/Makefile deleted file mode 100644 index 93b578877..000000000 --- a/bulkdata/src/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -PROG = bulkdatad -LIB = libbulkdata.so - -PROG_OBJS = bulkdata.o common.o config.o http.o log.o report.o times.o buci.o -LIB_OBJS = datamodel.o - -PROG_CFLAGS = $(CFLAGS) -Wall -Werror -fPIC -PROG_LDFLAGS = $(LDFLAGS) -lubus -luci -lubox -ljson-c -lcurl -lblobmsg_json -lbbfdm -lbbf_api -LIB_LDFLAGS = $(LDFLAGS) -lbbf_api - -%.o: %.c - $(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $< - -all: $(PROG) $(LIB) - -$(PROG): $(PROG_OBJS) - $(CC) $(PROG_CFLAGS) -o $@ $^ $(PROG_LDFLAGS) - -$(LIB): $(LIB_OBJS) - $(CC) $(PROG_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^ - -clean: - rm -f *.o $(PROG) $(LIB) diff --git a/bulkdata/src/buci.c b/bulkdata/src/buci.c deleted file mode 100644 index 1d876520c..000000000 --- a/bulkdata/src/buci.c +++ /dev/null @@ -1,265 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "buci.h" - -struct uci_context *uci_ctx = NULL; - -int buci_init(void) -{ - uci_ctx = uci_alloc_context(); - if (!uci_ctx) { - return -1; - } - return 0; -} - -int buci_fini(void) -{ - if (uci_ctx) { - uci_free_context(uci_ctx); - } - - return 0; -} - -static bool buci_validate_section(const char *str) -{ - if (!*str) - return false; - - for (; *str; str++) { - unsigned char c = *str; - - if (isalnum(c) || c == '_') - continue; - - return false; - } - return true; -} - -static int buci_init_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value) -{ - memset(ptr, 0, sizeof(struct uci_ptr)); - - /* value */ - if (value) { - ptr->value = value; - } - ptr->package = package; - if (!ptr->package) - goto error; - - ptr->section = section; - if (!ptr->section) { - ptr->target = UCI_TYPE_PACKAGE; - goto lastval; - } - - ptr->option = option; - if (!ptr->option) { - ptr->target = UCI_TYPE_SECTION; - goto lastval; - } else { - ptr->target = UCI_TYPE_OPTION; - } - -lastval: - if (ptr->section && !buci_validate_section(ptr->section)) - ptr->flags |= UCI_LOOKUP_EXTENDED; - - return 0; - -error: - return -1; -} - -struct uci_section *buci_walk_section(char *package, char *section_type, struct uci_section *prev_section) -{ - struct uci_ptr ptr; - struct uci_element *e; - struct uci_section *next_section; - - if (section_type == NULL) { - if (prev_section) { - e = &prev_section->e; - if (e->list.next == &prev_section->package->sections) - return NULL; - e = container_of(e->list.next, struct uci_element, list); - next_section = uci_to_section(e); - return next_section; - } - else { - if (buci_init_ptr(uci_ctx, &ptr, package, NULL, NULL, NULL)) { - return NULL; - } - if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK) { - return NULL; - } - if (ptr.p->sections.next == &ptr.p->sections) - return NULL; - e = container_of(ptr.p->sections.next, struct uci_element, list); - next_section = uci_to_section(e); - - return next_section; - } - } - else { - struct uci_list *ul, *shead = NULL; - - if (prev_section) { - ul = &prev_section->e.list; - shead = &prev_section->package->sections; - } - else { - if (buci_init_ptr(uci_ctx, &ptr, package, NULL, NULL, NULL)) { - return NULL; - } - if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK) { - return NULL; - } - ul = &ptr.p->sections; - shead = &ptr.p->sections; - } - while (ul->next != shead) { - e = container_of(ul->next, struct uci_element, list); - next_section = uci_to_section(e); - if (strcmp(next_section->type, section_type) == 0) - return next_section; - ul = ul->next; - } - return NULL; - } - return NULL; -} - -void buci_print_list(struct uci_list *uh, char **val, char *delimiter) -{ - struct uci_element *e; - static char buffer[512]; - char *buf = buffer; - *buf = '\0'; - - uci_foreach_element(uh, e) { - if (*buf) { - strcat(buf, delimiter); - strcat(buf, e->name); - } - else { - strcpy(buf, e->name); - } - } - *val = buf; -} - -struct uci_element *buci_lookup_list(struct uci_list *list, const char *name) -{ - struct uci_element *e; - - uci_foreach_element(list, e) { - if (!strcmp(e->name, name)) - return e; - } - return NULL; -} - -int uci_lookup_ptr_bysection(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_section *section, char *option, char *value) -{ - struct uci_element *e; - memset(ptr, 0, sizeof(struct uci_ptr)); - - ptr->package = section->package->e.name; - ptr->section = section->e.name; - ptr->option = option; - ptr->value = value; - ptr->flags |= UCI_LOOKUP_DONE; - - ptr->p = section->package; - ptr->s = section; - - if (ptr->option) { - e = buci_lookup_list(&ptr->s->options, ptr->option); - if (!e) - return UCI_OK; - ptr->o = uci_to_option(e); - ptr->last = e; - ptr->target = UCI_TYPE_OPTION; - } - else { - ptr->last = &ptr->s->e; - ptr->target = UCI_TYPE_SECTION; - } - - ptr->flags |= UCI_LOOKUP_COMPLETE; - - return UCI_OK; -} - -char *buci_get_value_bysection(struct uci_section *section, char *option) -{ - struct uci_ptr ptr; - char *val = ""; - - if (uci_lookup_ptr_bysection(uci_ctx, &ptr, section, option, NULL) != UCI_OK) { - return val; - } - - if (!ptr.o) - return val; - - if(ptr.o->type == UCI_TYPE_LIST) { - buci_print_list(&ptr.o->v.list, &val, " "); - return val; - } - - if (ptr.o->v.string) - return ptr.o->v.string; - else - return val; -} - -char *buci_get_value(char *package, char *section, char *option) -{ - struct uci_ptr ptr; - char *val = ""; - - if (!section || !option) - return val; - - if (buci_init_ptr(uci_ctx, &ptr, package, section, option, NULL)) { - return val; - } - if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK) { - return val; - } - - if (!ptr.o) - return val; - - if(ptr.o->type == UCI_TYPE_LIST) { - buci_print_list(&ptr.o->v.list, &val, " "); - return val; - } - - if (ptr.o->v.string) - return ptr.o->v.string; - else - return val; -} diff --git a/bulkdata/src/buci.h b/bulkdata/src/buci.h deleted file mode 100644 index d39468e97..000000000 --- a/bulkdata/src/buci.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* -*/ - -#ifndef __BUCI_H -#define __BUCI_H - -#include - -int buci_init(void); -int buci_fini(void); -struct uci_section *buci_walk_section(char *package, char *section_type, struct uci_section *prev_section); -void buci_print_list(struct uci_list *uh, char **val, char *delimiter); -struct uci_element *buci_lookup_list(struct uci_list *list, const char *name); -int uci_lookup_ptr_bysection(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_section *section, char *option, char *value); -char *buci_get_value_bysection(struct uci_section *section, char *option); -char *buci_get_value(char *package, char *section, char *option); - -#define buci_foreach_section(package, section_type, section) \ - for (section = buci_walk_section(package, section_type, NULL); \ - section != NULL; \ - section = buci_walk_section(package, section_type, section)) - -#endif //__BUCI_H diff --git a/bulkdata/src/bulkdata.c b/bulkdata/src/bulkdata.c deleted file mode 100644 index 892cea0a5..000000000 --- a/bulkdata/src/bulkdata.c +++ /dev/null @@ -1,144 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* Omar Kallel -*/ - -#include -#include -#include - -#include "http.h" -#include "config.h" -#include "log.h" -#include "common.h" -#include "report.h" -#include "times.h" -#include "bulkdata.h" - -struct bulkdata bulkdata_main = {0}; -int profiles_number = 0; - -void bulkdata_profile_cb(struct uloop_timeout *timeout); - -int get_retry_period(int min) -{ - srand(time(NULL)); - return rand()%min + min; -} - -static void bulkdata_run_profiles(struct bulkdata *bulkdata) -{ - unsigned int next_period; - int i = 0; - - for (i = 0; i < profiles_number; i++) { - bulkdata->profile[i].utimer.cb = bulkdata_profile_cb; - LIST_HEAD(failedreports); - bulkdata->profile[i].failed_reports = &failedreports; - next_period = get_next_period(bulkdata->profile[i].time_reference, bulkdata->profile[i].reporting_interval); - bulkdata_log(SINFO, "The session of profile_id %d will be start in %d sec", bulkdata->profile[i].profile_id, next_period); - uloop_timeout_set(&bulkdata->profile[i].utimer, next_period * 1000); - } -} - -int http_send_report(struct profile *profile, char *report) -{ - char *msg_in = NULL; - int http_code; - - http_client_init(profile); - bulkdata_log(SINFO, "Send the report of profile_id %d to Bulkdata Collector", profile->profile_id); - http_code = http_send_message(profile, report, strlen(report), &msg_in); - http_client_exit(); - return http_code; -} - -void bulkdata_profile_cb(struct uloop_timeout *timeout) -{ - struct profile *profile; - unsigned int http_code, retry_period; - char *report = NULL; - - profile = container_of(timeout, struct profile, utimer); - time_t now = time(NULL); - - bulkdata_log(SINFO, "New session of profile_id %d started", profile->profile_id); - if(profile->retry_count == 0 || profile->next_retry > now || !profile->http_retry_enable) //Perdiodic execution - create_encoding_bulkdata_report(profile, &report); - else - create_failed_report(profile, &report); - - bulkdata_log(SDEBUG, "The content of the profile_id report %d is :\n==========\n%s\n==========\n", profile->profile_id, report); - http_code= http_send_report(profile, report); - if(http_code != 200){ - if(profile->retry_count == 0 || profile->next_retry > now || !profile->http_retry_enable) { //Perdiodic execution - retry_period = get_retry_period(profile->http_retry_minimum_wait_interval); - profile->next_period = now + profile->reporting_interval; - profile->next_retry = now + retry_period; - profile->retry_count = 1; - profile->min_retry = profile->http_retry_minimum_wait_interval * 2; - if((profile->next_retry < profile->next_period) && profile->http_retry_enable) { - bulkdata_log(SINFO, "Retry session of profile_id %d in %d sec", profile->profile_id, retry_period); - uloop_timeout_set(timeout, 1000 * retry_period); - } - else { - bulkdata_log(SINFO, "Start New session of profile_id %d in %d sec", profile->profile_id, profile->reporting_interval); - uloop_timeout_set(timeout, 1000 * profile->reporting_interval); - } - } else { //Retry execution - retry_period= get_retry_period(profile->min_retry); - profile->min_retry*=2; - profile->next_retry+=retry_period; - profile->retry_count++; - if(profile->next_retry < profile->next_period) { - bulkdata_log(SINFO, "Retry session of profile_id %d in %d sec", profile->profile_id, retry_period); - uloop_timeout_set(timeout, 1000 * retry_period); - } - else { - bulkdata_log(SINFO, "Retry session of profile_id %d in %d sec", profile->profile_id, (profile->next_period-profile->next_retry+retry_period)); - uloop_timeout_set(timeout, 1000 * (profile->next_period-profile->next_retry+retry_period)); - } - } - if(profile->new_report){ - bulkdata_add_failed_report(profile, profile->new_report); - FREE(profile->new_report); - } - FREE(report); - } else { - if(profile->retry_count == 0 || profile->next_retry > now || !profile->http_retry_enable) { - bulkdata_log(SINFO, "Start New session of profile_id %d in %d sec", profile->profile_id, profile->reporting_interval); - uloop_timeout_set(timeout, 1000 * profile->reporting_interval); - } - else { - bulkdata_log(SINFO, "Retry session of profile_id %d in %d sec", profile->profile_id, (profile->next_period-profile->next_retry)); - uloop_timeout_set(timeout, 1000 * (profile->next_period-profile->next_retry)); - } - FREE(profile->new_report); - FREE(report); - empty_failed_reports_list(profile); - profile->retry_count= 0; - } -} - -int main(void) -{ - struct bulkdata *bulkdata = &bulkdata_main; - if (bulkdata_config_init(bulkdata) == -1) - return -1; - bulkdata_log(SINFO, "Start bulkdatad daemon"); - - uloop_init(); - bulkdata_run_profiles(bulkdata); - uloop_run(); - uloop_done(); - - bulkdata_config_fini(bulkdata); - bulkdata_log(SINFO, "Stop bulkdatad daemon"); - return 0; -} diff --git a/bulkdata/src/bulkdata.h b/bulkdata/src/bulkdata.h deleted file mode 100644 index 42c6a9968..000000000 --- a/bulkdata/src/bulkdata.h +++ /dev/null @@ -1,18 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* -*/ - -#ifndef __BULKDATA_H -#define __BULKDATA_H - -extern struct bulkdata bulkdata_main; -extern int profiles_number; - -#endif /* __BULKDATA_H */ diff --git a/bulkdata/src/bulkdata.md b/bulkdata/src/bulkdata.md deleted file mode 100644 index 4cedf9059..000000000 --- a/bulkdata/src/bulkdata.md +++ /dev/null @@ -1,105 +0,0 @@ -# README # - -bulkdatad is an implementation of The HTTP bulk data collection mechanism which is an extended feature of CPE and other agents implementing TR-069(CWMP) or TR-369(USP), defined by the Broadband Forum. It provides a means by which an Auto-Configuration Server (ACS), or USP Controller, can configure an agent to periodically send a JSON or CSV formatted set of Device information to an HTTP server running a data collection application. - -## Configuration File ## - -The bulkdatad UCI configuration is located in **'/etc/config/bulkdata'**, and contains 4 sections: **bulkdata**, **profile**, **profile\_parameter** and **profile\_http\_request\_uri\_parameter**. - -``` -config bulkdata 'bulkdata' - option enable '0' - option log_level '3' - -config profile - option profile_id '1' - option enable '0' - option csv_encoding_row_time_stamp 'unix' - option json_encoding_report_time_stamp 'unix' - option http_retry_minimum_wait_interval '5' - option http_retry_interval_multiplier '2000' - -config profile_parameter - option profile_id '1' - option name '' - option reference '' - -config profile_http_request_uri_parameter - option profile_id '1' - option name '' - option reference '' -``` - -### bulkdata section ### - -It defines **bulkdata configuration**: enable and log\_level. - -| Name | Type | Description | -| ----------- | ------- | ----------------------------------------------------------------------------------------------- | -| `enable` | boolean | Enables the BulkData feature if set to **1**. | -| `log_level` | integer | Specifies the log type to use, by default **'INFO'**. The possible types are **'EMERG', 'ALERT', 'CRITIC' ,'ERROR', 'WARNING', 'NOTICE', 'INFO' and 'DEBUG'**. | - -### profile section ### - -It defines **the profile section configuration**: enable, name,... The possible options for **profile** section are listed below: - -| Name | Type | Description | -| ---------------------------------- | ------- | ---------------------------------------------- | -| `profile_id` | integer | The profile id to use. | -| `enable` | boolean | If set to **1**, enables the bulkdata profile. | -| `name` | string | The name of the profile. | -| `nbre_of_retained_failed_reports` | integer | The number of failed reports to be retained and transmitted at the end of the current reporting interval. | -| `protocol` | string | The protocol used for the collection profile. | -| `encoding_type` | string | The encoding type used for the collection profile. | -| `reporting_interval` | integer | The reporting interval in seconds. | -| `time_reference` | integer | The time reference to determine when the profile will be transmitted to the ACS collector. | -| `csv_encoding_field_separator` | string | The field separator to use when encoding CSV data. | -| `csv_encoding_row_separator` | string | The row separator to use when encoding CSV data. | -| `csv_encoding_escape_character` | string | The escape character to use when encoding CSV data. | -| `csv_encoding_report_format` | string | Describes how reports will be formatted. Two possible formats are supported: **'ParameterPerRow' and 'ParameterPerColumn'**. | -| `csv_encoding_row_time_stamp` | string | The format of the timestamp to use for data inserted into the row. The row time stamp supported are **'Unix-Epoch', 'ISO-8601' and 'None'**. | -| `json_encoding_report_format` | string | Describes the report format. The supported report formats are **'ObjectHierarchy' and 'NameValuePair'**. | -| `json_encoding_report_time_stamp` | string | The format of the timestamp to use for the JSON Object named "CollectionTime". The supported timestamp are **'Unix-Epoch', 'ISO-8601' and 'None'**. | -| `http_url` | string | The URL of the collection server. | -| `http_username` | string | The username of the collection server. | -| `http_password` | string | The password of the collection server. | -| `http_compression` | string | The HTTP Compression mechanism used by the collection server. The supported compression mechanism are **'GZIP', 'Compress' and 'Deflate'**. | -| `http_method` | string | The HTTP method used by the collection server. Two methods are supported: **'POST' and 'PUT'**. | -| `http_use_date_header` | boolean | If set to **1**, the CPE encodes the HTTP Date Header. | -| `http_retry_enable` | boolean | If set to **1**, the CPE retries unsuccessful attempts to transfer data. | -| `http_retry_minimum_wait_interval` | integer | The data transfer retry wait interval. | -| `http_retry_interval_multiplier` | integer | The retry interval multiplier. | -| `http_persist_across_reboot` | boolean | If set to **1**, failed data transfers must be persisted across reboots. | - -### profile_parameter section ### - -It defines **the profile\_parameter section configuration**: profile\_id, name, reference. - -| Name | Type | Description | -| ------------ | ------- | --------------------------------------- | -| `profile_id` | integer | The id of the used profile. | -| `name` | string | The name of the profile parameter. | -| `reference` | string | The reference of the profile parameter. | - -### profile_http_request_uri_parameter section ### - -It defines **the profile\_http\_request\_uri\_parameter section configuration**: profile\_id, name, reference. - -| Name | Type | Description | -| ------------ | ------- | --------------------------------------- | -| `profile_id` | integer | The id of the used profile. | -| `name` | string | The name of the Request-URI parameter. | -| `reference` | string | The reference of the profile parameter. | - -## Dependencies ## - -To successfully build bulkdatad, the following libraries are needed: - -| Dependency | Link | License | -| ----------- | ------------------------------------------- | -------------- | -| libuci | https://git.openwrt.org/project/uci.git | LGPL 2.1 | -| libubox | https://git.openwrt.org/project/libubox.git | BSD | -| libjson-c | https://s3.amazonaws.com/json-c_releases | MIT | -| libcurl | https://dl.uxnr.de/mirror/curl | MIT | -| libbbfdm | https://dev.iopsys.eu/iopsys/bbf.git | LGPL 2.1 | - diff --git a/bulkdata/src/common.c b/bulkdata/src/common.c deleted file mode 100644 index 252fa7553..000000000 --- a/bulkdata/src/common.c +++ /dev/null @@ -1,450 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* Omar Kallel -*/ - -#include "common.h" - -static pathnode *head = NULL; -static pathnode *temphead = NULL; - -int bulkdata_dm_ctx_init(struct dmctx *ctx) -{ - struct bulkdata *bulkdata = &bulkdata_main; - dm_ctx_init(ctx, bulkdata->instance_mode); - return 0; -} - -int bulkdata_dm_ctx_clean(struct dmctx *ctx) -{ - dm_ctx_clean(ctx); - return 0; -} - -static char **str_split(const char* str, const char* delim, size_t* numtokens) -{ - char *s = strdup(str); - size_t tokens_alloc = 1; - size_t tokens_used = 0; - char **tokens = calloc(tokens_alloc, sizeof(char*)); - char *token, *strtok_ctx; - for (token = strtok_r(s, delim, &strtok_ctx); token != NULL; token = strtok_r(NULL, delim, &strtok_ctx)) { - if (tokens_used == tokens_alloc) { - tokens_alloc *= 2; - tokens = realloc(tokens, tokens_alloc * sizeof(char*)); - } - tokens[tokens_used++] = strdup(token); - } - // cleanup - if (tokens_used == 0) { - FREE(tokens); - } else { - tokens = realloc(tokens, tokens_used * sizeof(char*)); - } - *numtokens = tokens_used; - FREE(s); - return tokens; -} - -static bool bulkdata_match(const char *string, const char *pattern) -{ - regex_t re; - if (regcomp(&re, pattern, REG_EXTENDED) != 0) return 0; - int status = regexec(&re, string, 0, NULL, 0); - regfree(&re); - if (status != 0) return false; - return true; -} - -static bool is_res_required(char *str, int *start, int *len) -{ - char temp_char[NAME_MAX] = {'\0'}; - - if (bulkdata_match(str, GLOB_CHAR)) { - int s_len = strlen(str); - int b_len = s_len, p_len = s_len; - - char *star = strchr(str, '*'); - if(star) - s_len = star - str; - *start = MIN(MIN(s_len, p_len), b_len); - if (*start == s_len) - *len = 1; - - strncpy(temp_char, str+*start, *len); - - if (bulkdata_match(temp_char, "[*+]+")) - return true; - } - *start = strlen(str); - return false; -} - -static void insert(char *data, bool active) -{ - pathnode *link = (pathnode*) calloc(1, sizeof(pathnode)); - if(!link) { - return; - } - - link->ref_path = data; - - if(active) { - link->next = head; - head = link; - } else { - link->next = temphead; - temphead = link; - } -} - -static void swap_heads(void) -{ - pathnode *temp = head; - head = temphead; - temphead = temp; -} - -static void deleteList(void) -{ - pathnode *ptr = head, *temp; - while(ptr != NULL) { - temp = ptr; - free(ptr->ref_path); - if(ptr->next != NULL) { - ptr = ptr->next; - } else { - ptr = NULL; - } - free(temp); - } - head = NULL; - swap_heads(); -} - -void bulkdata_add_data_to_list(struct list_head *dup_list, char *name, char *value, char *type) -{ - struct resultsnode *link; - link = calloc(1, sizeof(struct resultsnode)); - list_add_tail(&link->list, dup_list); - link->name = strdup(name); - link->data = strdup(value); - link->type = strdup(type); -} - -void bulkdata_delete_data_from_list(struct resultsnode *link) -{ - list_del(&link->list); - FREE(link->name); - FREE(link->data); - FREE(link->type); - FREE(link); -} - -void bulkdata_free_data_from_list(struct list_head *dup_list) -{ - struct resultsnode *link; - while (dup_list->next != dup_list) { - link = list_entry(dup_list->next, struct resultsnode, list); - bulkdata_delete_data_from_list(link); - } -} - -static bool bulkdata_get(int operation, char *path, struct dmctx *dm_ctx) -{ - int fault = 0; - - switch(operation) { - case CMD_GET_NAME: - fault = dm_entry_param_method(dm_ctx, CMD_GET_NAME, path, "true", NULL); - break; - case CMD_GET_VALUE: - fault = dm_entry_param_method(dm_ctx, CMD_GET_VALUE, path, NULL, NULL); - break; - default: - return false; - } - - if (dm_ctx->list_fault_param.next != &dm_ctx->list_fault_param) { - return false; - } - if (fault) { - return false; - } - return true; -} - -char *bulkdata_get_value_param(char *path) -{ - struct dmctx ctx = {0}; - struct dm_parameter *n; - char *value = NULL; - - bulkdata_dm_ctx_init(&ctx); - if(bulkdata_get(CMD_GET_VALUE, path, &ctx)) { - list_for_each_entry(n, &ctx.list_parameter, list) { - value = strdup(n->data); - break; - } - } - bulkdata_dm_ctx_clean(&ctx); - return value; -} - -void bulkdata_get_value(char *path, struct list_head *list) -{ - struct dmctx ctx = {0}; - struct dm_parameter *n; - - bulkdata_dm_ctx_init(&ctx); - if(bulkdata_get(CMD_GET_VALUE, path, &ctx)) { - list_for_each_entry(n, &ctx.list_parameter, list) { - bulkdata_add_data_to_list(list, n->name, n->data, n->type); - } - } - bulkdata_dm_ctx_clean(&ctx); -} - -bool bulkdata_get_name(char *path) -{ - struct dmctx ctx = {0}; - struct dm_parameter *n; - bool ret = false; - - bulkdata_dm_ctx_init(&ctx); - if(bulkdata_get(CMD_GET_NAME, path, &ctx)) { - list_for_each_entry(n, &ctx.list_parameter, list) { - insert(strdup(n->name), false); - } - ret = true; - } - bulkdata_dm_ctx_clean(&ctx); - return ret; -} - -static void fill_node_path(void) -{ - pathnode *p=head; - while(p!=NULL) { - bulkdata_get_name(p->ref_path); - p=p->next; - } - deleteList(); -} - -static void bulkdata_filter_results(char *path, int start, int end) -{ - int startpos = start, m_index = 0, m_len = 0; - char *pp = path + startpos; - char exp[NAME_MAX] = {'\0'}; - - if(start >= end) { - return; - } - - if(!is_res_required(pp, &m_index, &m_len)) { - //append rest of the path to the final list - if(pp == path ) { - insert(strdup(pp), true); - return; - } - - pathnode *p = head; - while(p != NULL) { - char name[NAME_MAX] = {'\0'}; - strcpy(name, p->ref_path); - strcat(name, pp); - insert(strdup(name), false); - p = p->next; - } - deleteList(); - return; - } - - // Get the string before the match - char name[NAME_MAX]={'\0'}; - strncpy(name, pp, m_index); - - pathnode *p = head; - if(p == NULL) { - insert(strdup(name), false); - } - - while(p != NULL) { - char ref_name[NAME_MAX] = {'\0'}; - sprintf(ref_name, "%s%s", p->ref_path, name); - insert(strdup(ref_name), false); - p = p->next; - } - deleteList(); - - startpos += m_index; - strncpy(exp, pp+m_index, m_len); - pp = path + startpos; - fill_node_path(); - startpos += 2; - bulkdata_filter_results(path, startpos, end); -} - -static void bulkdata_parse_results(struct list_head *list) -{ - pathnode *p = head; - while(p != NULL) { - bulkdata_get_value(p->ref_path, list); - p = p->next; - } - deleteList(); -} - -void bulkdata_get_value_results(char *path, struct list_head *list) -{ - bulkdata_filter_results(path, 0, strlen(path)); - bulkdata_parse_results(list); -} - -char *create_request_url(struct profile *profile) -{ - int i = 0, http_uri_number = profile->profile_http_request_uri_parameter_number; - char *value, *uri_param = NULL, *uri_tmp = NULL, *http_url = NULL; - - for (i = 0; i < http_uri_number; i++) - { - if((profile->profile_http_uri_parameter[i].reference == NULL) || (profile->profile_http_uri_parameter[i].name == NULL)) - continue; - value = bulkdata_get_value_param(profile->profile_http_uri_parameter[i].reference); - if(!uri_param) { - asprintf(&uri_param, "&%s=%s", profile->profile_http_uri_parameter[i].name, value); - free(value); - } - else { - uri_tmp = strdup(uri_param); - free(uri_param); - asprintf(&uri_param, "%s&%s=%s", uri_tmp, profile->profile_http_uri_parameter[i].name, value); - free(value); - free(uri_tmp); - } - } - if(uri_param) { - asprintf(&http_url, "%s%s", profile->http_url, uri_param); - free(uri_param); - } else { - asprintf(&http_url, "%s", profile->http_url); - } - return http_url; -} - -char *get_bulkdata_profile_parameter_name(char *paramref, char *paramname, char *param) -{ - char **paramarr, *idx1 = NULL, *idx2 = NULL, *res = NULL, *instance = NULL, *tmp = NULL, *retparam = NULL, *s = NULL; - int i, j = 0; - size_t length; - - if(paramname == NULL || strlen(paramname) <= 0) - return strdup(param); - paramarr = str_split(paramref, "*", &length); - res = strdup(paramname); - for(i = 0; i < length; i++) { - if(i == length - 1) - break; - j++; - idx1 = strstr(param, paramarr[i]); - idx2 = strstr(param, paramarr[i+1]); - instance = (char*)calloc(idx2 - idx1 - strlen(paramarr[i]) + 1, sizeof(char)); - memcpy(instance, idx1 + strlen(paramarr[i]), idx2 - idx1 - strlen(paramarr[i])); - tmp = strdup(res); - FREE(res); - asprintf(&res, "%s.%s", tmp, instance); - FREE(tmp); - FREE(instance); - } - if ((s = strstr(param,paramarr[j]) ) != NULL && strlen(s) == strlen(paramarr[j])) - asprintf(&retparam, "%s", res); - else - asprintf(&retparam, "%s.%s", res, strstr(param, paramarr[j]) + strlen(paramarr[j])); - - FREE(res); - for(int k = 0; k < length; k++) - FREE(paramarr[k]); - FREE(paramarr); - - return retparam; -} - -void append_string_to_string(char *strappend, char **target) -{ - char *tmp = NULL; - - if(strappend == NULL || strlen(strappend) <= 0) - return; - if(*target == NULL || strlen(*target) <= 0) { - *target = strdup(strappend); - return; - } else { - tmp = strdup(*target); - FREE(*target); - } - asprintf(target, "%s%s", tmp, strappend); - FREE(tmp); -} - -void bulkdata_add_failed_report(struct profile *profile, char *freport) -{ - struct failed_reports *report, *retreport, *rtmp; - - if(profile->nbre_failed_reports < profile->nbre_of_retained_failed_reports || profile->nbre_of_retained_failed_reports < 0) { - profile->nbre_failed_reports++; - } else { - list_for_each_entry_safe(retreport, rtmp, profile->failed_reports, list) { - bulkdata_delete_failed_report(retreport); - break; - } - } - report = calloc(1, sizeof(struct failed_reports)); - list_add_tail(&report->list, profile->failed_reports); - report->freport= strdup(freport); -} - -void bulkdata_delete_failed_report(struct failed_reports *report) -{ - if(report != NULL) { - list_del(&report->list); - FREE(report->freport); - FREE(report); - } -} - -struct failed_reports* empty_failed_reports_list(struct profile *profile) -{ - struct failed_reports *report, *rtmp; - - if(list_empty(profile->failed_reports)) - return NULL; - list_for_each_entry_safe(report, rtmp, profile->failed_reports, list) { - list_del(&report->list); - FREE(report->freport); - FREE(report); - } - return NULL; -} - -void add_failed_reports_to_report_csv(struct profile *profile, char **report, int isnext) -{ - struct failed_reports *retreport = NULL; - int j = 0; - - if(list_empty(profile->failed_reports)) - return; - list_for_each_entry(retreport, profile->failed_reports, list) { - if(!j && isnext) { - j = 1; - continue; - } - append_string_to_string(retreport->freport, report); - } -} diff --git a/bulkdata/src/common.h b/bulkdata/src/common.h deleted file mode 100644 index 7b3e98226..000000000 --- a/bulkdata/src/common.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* -*/ - -#ifndef __COMMON_H -#define __COMMON_H - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "config.h" -#include "log.h" -#include "bulkdata.h" - -typedef struct pathnode { - char *ref_path; - struct pathnode *next; -} pathnode; - -typedef struct resultsnode { - struct list_head list; - char *name; - char *data; - char *type; -} resultsnode; - -struct failed_reports { - struct list_head list; - char *freport; -}; - -#define GLOB_CHAR "[[+*]+" - -int bulkdata_dm_ctx_init(struct dmctx *ctx); -int bulkdata_dm_ctx_clean(struct dmctx *ctx); - -char *bulkdata_get_value_param(char *path); -void bulkdata_get_value(char *path, struct list_head *list); - -void bulkdata_free_data_from_list(struct list_head *dup_list); -void bulkdata_get_value_results(char *path, struct list_head *list); -char *create_request_url(struct profile *profile); -char *get_bulkdata_profile_parameter_name(char *paramref, char *paramname, char *param); -void append_string_to_string(char *strappend, char **target); -void bulkdata_add_failed_report(struct profile *profile, char *freport); -void bulkdata_delete_failed_report(struct failed_reports *report); - -struct failed_reports *empty_failed_reports_list(struct profile *profile); -void add_failed_reports_to_report_csv(struct profile *profile, char **report, int isnext); - -#endif //__COMMON_H diff --git a/bulkdata/src/config.c b/bulkdata/src/config.c deleted file mode 100644 index ad73ff193..000000000 --- a/bulkdata/src/config.c +++ /dev/null @@ -1,523 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* Omar Kallel -*/ - -#include -#include -#include -#include -#include - -#include "log.h" -#include "config.h" -#include "buci.h" -#include "common.h" -#include "bulkdata.h" - -int get_log_level_config(struct bulkdata *bulkdata) -{ - char *value = NULL; - - buci_init(); - value = buci_get_value("bulkdata", "bulkdata", "log_level"); - if(value != NULL && *value != '\0') - bulkdata->log_level = atoi(value); - else - bulkdata->log_level = DEFAULT_LOGLEVEL; - bulkdata_log(SDEBUG,"Log Level of Bulkdata is : %d", bulkdata->log_level); - buci_fini(); - return 0; -} - -int get_amd_version_config(struct bulkdata *bulkdata) -{ - char *value = NULL; - - buci_init(); - value = buci_get_value("cwmp", "cpe", "amd_version"); - if(value != NULL && *value != '\0') - bulkdata->amd_version = atoi(value); - else - bulkdata->amd_version = DEFAULT_AMD_VERSION; - bulkdata_log(SDEBUG,"CWMP Amendment Version is : %d", bulkdata->amd_version); - buci_fini(); - return 0; -} - -int get_instance_mode_config(struct bulkdata *bulkdata) -{ - char *value = NULL; - - buci_init(); - value = buci_get_value("cwmp", "cpe", "instance_mode"); - if(value != NULL && *value != '\0') { - if(!strcmp(value, "InstanceNumber")) - bulkdata->instance_mode = INSTANCE_MODE_NUMBER; - else - bulkdata->instance_mode = INSTANCE_MODE_ALIAS; - } - else - bulkdata->instance_mode = DEFAULT_INSTANCE_MODE; - bulkdata_log(SDEBUG,"CWMP Instance Mode is : %d", bulkdata->instance_mode); - buci_fini(); - - return 0; -} - -int get_device_id_config(struct bulkdata *bulkdata) -{ - struct dmctx dmctx = {0}; - - bulkdata_dm_ctx_init(&dmctx); - bulkdata->device_id.manufacturer_oui = bulkdata_get_value_param("Device.DeviceInfo.ManufacturerOUI"); - bulkdata->device_id.product_class = bulkdata_get_value_param("Device.DeviceInfo.ProductClass"); - bulkdata->device_id.serial_number = bulkdata_get_value_param("Device.DeviceInfo.SerialNumber"); - bulkdata_dm_ctx_clean(&dmctx); - - return 0; -} - -int load_profile_config(struct bulkdata *bulkdata, struct uci_section *s, int i) -{ - char *value = NULL; - - value = buci_get_value_bysection(s, "profile_id"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].profile_id = atoi(value); - value = NULL; - bulkdata_log(SDEBUG,"The profile_id of profile_id %d is : %d", i, bulkdata->profile[i].profile_id); - } else - return -1; - - value = buci_get_value_bysection(s, "nbre_of_retained_failed_reports"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].nbre_of_retained_failed_reports = atoi(value); - value = NULL; - bulkdata_log(SDEBUG,"The nombre of retained failed reports of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].nbre_of_retained_failed_reports); - } - - value = buci_get_value_bysection(s, "protocol"); - if(value != NULL && *value != '\0' && strcasecmp(value, "http")==0) { - bulkdata->profile[i].protocol = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The protocol of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].protocol); - } else - return -1; - - value = buci_get_value_bysection(s, "encoding_type"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].encoding_type = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The encoding type of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].encoding_type); - } else - return -1; - - value = buci_get_value_bysection(s, "reporting_interval"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].reporting_interval = atoi(value); - value = NULL; - bulkdata_log(SDEBUG,"The reporting interval of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].reporting_interval); - } else - return -1; - - value = buci_get_value_bysection(s, "time_reference"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].time_reference = atoi(value); - value = NULL; - bulkdata_log(SDEBUG,"The time reference of profile_id %d is : %ld", bulkdata->profile[i].profile_id, bulkdata->profile[i].time_reference); - } else - return -1; - - value = buci_get_value_bysection(s, "csv_encoding_field_separator"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].csv_encoding_field_separator = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The csv encoding field separator of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_field_separator); - } else - return -1; - - value = buci_get_value_bysection(s, "csv_encoding_row_separator"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].csv_encoding_row_separator = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The csv encoding row separator of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_row_separator); - } else - return -1; - - value = buci_get_value_bysection(s, "csv_encoding_escape_character"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].csv_encoding_escape_character = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The csv encoding escape character of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_escape_character); - } - - value = buci_get_value_bysection(s, "csv_encoding_report_format"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].csv_encoding_report_format = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The csv encoding report format of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_report_format); - } else - return -1; - - value = buci_get_value_bysection(s, "csv_encoding_row_time_stamp"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].csv_encoding_row_time_stamp = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The csv encoding row time stamp of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_row_time_stamp); - } else - return -1; - - value = buci_get_value_bysection(s, "json_encoding_report_format"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].json_encoding_report_format = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The json encoding report format of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].json_encoding_report_format); - } else - return -1; - - value = buci_get_value_bysection(s, "json_encoding_report_time_stamp"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].json_encoding_report_time_stamp = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The json encoding report time stamp of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].json_encoding_report_time_stamp); - } else - return -1; - - value = buci_get_value_bysection(s, "http_url"); - if(value != NULL && *value != '\0') { - char *url = NULL; - asprintf(&url, "%s?oui=%s&pc=%s&sn=%s", value, bulkdata->device_id.manufacturer_oui, bulkdata->device_id.serial_number, bulkdata->device_id.serial_number); - bulkdata->profile[i].http_url = strdup(url); - free(url); - value = NULL; - bulkdata_log(SDEBUG,"The HTTP url of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_url); - } else - return -1; - - value = buci_get_value_bysection(s, "http_username"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].http_username = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The HTTP username of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_username); - } else { - bulkdata->profile[i].http_username = NULL; - } - - value = buci_get_value_bysection(s, "http_password"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].http_password = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The HTTP password of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_password); - } else { - bulkdata->profile[i].http_password = NULL; - } - - value = buci_get_value_bysection(s, "http_compression"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].http_compression = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The HTTP compression of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_compression); - } else - return -1; - - value = buci_get_value_bysection(s, "http_method"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].http_method = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The HTTP method of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_method); - } else - return -1; - - value = buci_get_value_bysection(s, "http_use_date_header"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].http_use_date_header = atoi(value); - value = NULL; - bulkdata_log(SDEBUG,"The HTTP use date header of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_use_date_header); - } - - value = buci_get_value_bysection(s, "http_retry_enable"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].http_retry_enable = atoi(value); - value = NULL; - bulkdata_log(SDEBUG,"The HTTP retry enable of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_retry_enable); - } else - return -1; - - value = buci_get_value_bysection(s, "http_retry_minimum_wait_interval"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].http_retry_minimum_wait_interval = atoi(value); - value = NULL; - bulkdata_log(SDEBUG,"The HTTP retry minimum wait interval of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_retry_minimum_wait_interval); - } - - value = buci_get_value_bysection(s, "http_retry_interval_multiplier"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].http_retry_interval_multiplier = atoi(value); - value = NULL; - bulkdata_log(SDEBUG,"The HTTP retry interval multiplier of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_retry_interval_multiplier); - } - - value = buci_get_value_bysection(s, "http_persist_across_reboot"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].http_persist_across_reboot = atoi(value); - value = NULL; - bulkdata_log(SDEBUG,"The HTTP persist across reboot of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_persist_across_reboot); - } else - return -1; - - value = buci_get_value_bysection(s, "http_ssl_capath"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].http_ssl_capath = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The HTTP ssl capath of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_ssl_capath); - } else { - bulkdata->profile[i].http_ssl_capath = NULL; - } - - value = buci_get_value_bysection(s, "http_insecure_enable"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].http_insecure_enable = atoi(value); - value = NULL; - bulkdata_log(SDEBUG,"The HTTP insecure enable of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_insecure_enable); - } - - bulkdata->profile[i].retry_count = 0; - bulkdata->profile[i].nbre_failed_reports = 0; - - return 0; -} - -int get_profiles_enable(struct bulkdata *bulkdata) -{ - struct uci_section *s; - char *enable; - int i = 0, nbr_profiles = 0; - - buci_init(); - - buci_foreach_section("bulkdata", "profile", s) { - enable = buci_get_value_bysection(s, "enable"); - if(strcmp(enable, "1") == 0) { - nbr_profiles++; - } - } - - if(nbr_profiles != 0) - bulkdata->profile = calloc(2, sizeof(struct profile)); - - buci_foreach_section("bulkdata", "profile", s) { - enable = buci_get_value_bysection(s, "enable"); - if(strcmp(enable, "1") == 0) { - if(load_profile_config(bulkdata, s, i) == -1) { - bulkdata_log(SCRIT,"Not able to start bulkdata: some required bulkdata configurations in profile must be set"); - return -1; - } - i++; - } - } - profiles_number = nbr_profiles; - - buci_fini(); - return 0; -} - -int load_profile_parameter_config(struct bulkdata *bulkdata, struct uci_section *s, int i, int j) -{ - char *value = NULL; - - value = buci_get_value_bysection(s, "name"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].profile_parameter[j].name = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The parameter name %d of profile_id %d is : %s", j+1, bulkdata->profile[i].profile_id, bulkdata->profile[i].profile_parameter[j].name); - } else { - bulkdata->profile[i].profile_parameter[j].name = NULL; - } - - value = buci_get_value_bysection(s, "reference"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].profile_parameter[j].reference = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The parameter reference %d of profile_id %d is : %s", j+1, bulkdata->profile[i].profile_id, bulkdata->profile[i].profile_parameter[j].reference); - } else - return -1; - - return 0; -} - -int get_profiles_parameters(struct bulkdata *bulkdata) -{ - struct uci_section *s; - char *profile_id; - int i, j, nbr_profile_parameters; - - buci_init(); - - for (i = 0; i < profiles_number; i++) { - j = 0; - nbr_profile_parameters = 0; - buci_foreach_section("bulkdata", "profile_parameter", s) { - profile_id = buci_get_value_bysection(s, "profile_id"); - if(bulkdata->profile[i].profile_id != atoi(profile_id)) - continue; - nbr_profile_parameters++; - if(nbr_profile_parameters == 1) { - bulkdata->profile[i].profile_parameter = calloc(1, sizeof(struct profile_parameter)); - } else { - bulkdata->profile[i].profile_parameter = realloc(bulkdata->profile[i].profile_parameter, nbr_profile_parameters * sizeof(struct profile_parameter)); - } - if(load_profile_parameter_config(bulkdata, s, i, j) == -1) { - bulkdata_log(SCRIT,"Not able to start bulkdata: some required bulkdata configurations in profile_parameter must be set"); - return -1; - } - j++; - } - bulkdata->profile[i].profile_parameter_number = nbr_profile_parameters; - } - - buci_fini(); - return 0; -} - -int load_profile_http_request_uri_parameter_config(struct bulkdata *bulkdata, struct uci_section *s, int i, int j) -{ - char *value = NULL; - - value = buci_get_value_bysection(s, "name"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].profile_http_uri_parameter[j].name = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The HTTP resuest URI parameter name %d of profile_id %d is : %s", j+1, bulkdata->profile[i].profile_id, bulkdata->profile[i].profile_http_uri_parameter[j].name); - } else - return -1; - - value = buci_get_value_bysection(s, "reference"); - if(value != NULL && *value != '\0') { - bulkdata->profile[i].profile_http_uri_parameter[j].reference = strdup(value); - value = NULL; - bulkdata_log(SDEBUG,"The HTTP resuest URI parameter reference %d of profile_id %d is : %s", j+1, bulkdata->profile[i].profile_id, bulkdata->profile[i].profile_http_uri_parameter[j].reference); - } else - return -1; - - return 0; -} - -int get_profile_http_request_uri_parameter(struct bulkdata *bulkdata) -{ - struct uci_section *s; - char *profile_id; - int i, j, nbr_profile_http_request_uri_parameter; - - buci_init(); - - for (i = 0; i < profiles_number; i++) { - j = 0; - nbr_profile_http_request_uri_parameter = 0; - buci_foreach_section("bulkdata", "profile_http_request_uri_parameter", s) { - profile_id = buci_get_value_bysection(s, "profile_id"); - if(bulkdata->profile[i].profile_id != atoi(profile_id)) - continue; - nbr_profile_http_request_uri_parameter++; - if(nbr_profile_http_request_uri_parameter == 1) { - bulkdata->profile[i].profile_http_uri_parameter = calloc(1, sizeof(struct profile_http_request_uri_parameter)); - } else { - bulkdata->profile[i].profile_http_uri_parameter = realloc(bulkdata->profile[i].profile_http_uri_parameter, nbr_profile_http_request_uri_parameter * sizeof(struct profile_http_request_uri_parameter)); - } - if(load_profile_http_request_uri_parameter_config(bulkdata, s, i, j)== -1) { - bulkdata_log(SCRIT,"Not able to start bulkdata: some required bulkdata configurations in profile_http_request_uri_parameter must be set"); - return -1; - } - j++; - } - bulkdata->profile[i].profile_http_request_uri_parameter_number = nbr_profile_http_request_uri_parameter; - } - - buci_fini(); - return 0; -} - -int bulkdata_config_init(struct bulkdata *bulkdata) -{ - get_log_level_config(bulkdata); - get_amd_version_config(bulkdata); - get_instance_mode_config(bulkdata); - get_device_id_config(bulkdata); - if (get_profiles_enable(bulkdata) == -1) - return -1; - if (get_profiles_parameters(bulkdata) == -1) - return -1; - if (get_profile_http_request_uri_parameter(bulkdata) == -1) - return -1; - return 0; -} - -int free_device_id_config(struct bulkdata *bulkdata) -{ - FREE(bulkdata->device_id.manufacturer_oui); - FREE(bulkdata->device_id.product_class); - FREE(bulkdata->device_id.serial_number); - return 0; -} - -int free_profiles_enable(struct bulkdata *bulkdata) -{ - for(int i = 0; i < profiles_number; i++) { - FREE(bulkdata->profile[i].protocol); - FREE(bulkdata->profile[i].encoding_type); - FREE(bulkdata->profile[i].csv_encoding_field_separator); - FREE(bulkdata->profile[i].csv_encoding_row_separator); - FREE(bulkdata->profile[i].csv_encoding_escape_character); - FREE(bulkdata->profile[i].csv_encoding_report_format); - FREE(bulkdata->profile[i].csv_encoding_row_time_stamp); - FREE(bulkdata->profile[i].json_encoding_report_format); - FREE(bulkdata->profile[i].json_encoding_report_time_stamp); - FREE(bulkdata->profile[i].http_url); - FREE(bulkdata->profile[i].http_username); - FREE(bulkdata->profile[i].http_password); - FREE(bulkdata->profile[i].http_compression); - FREE(bulkdata->profile[i].http_method); - FREE(bulkdata->profile[i].http_ssl_capath); - } - FREE(bulkdata->profile); - return 0; -} - -int free_profiles_parameters(struct bulkdata *bulkdata) -{ - for(int i = 0; i < profiles_number; i++) { - for(int j = 0; j < bulkdata->profile[i].profile_parameter_number; j++) { - FREE(bulkdata->profile[i].profile_parameter[j].name); - FREE(bulkdata->profile[i].profile_parameter[j].reference); - } - FREE(bulkdata->profile[i].profile_parameter); - } - return 0; -} - -int free_profile_http_request_uri_parameter(struct bulkdata *bulkdata) -{ - for(int i = 0; i < profiles_number; i++) { - for(int j = 0; j < bulkdata->profile[i].profile_http_request_uri_parameter_number; j++) { - FREE(bulkdata->profile[i].profile_http_uri_parameter[j].name); - FREE(bulkdata->profile[i].profile_http_uri_parameter[j].reference); - } - FREE(bulkdata->profile[i].profile_http_uri_parameter); - } - return 0; -} - -int bulkdata_config_fini(struct bulkdata *bulkdata) -{ - free_device_id_config(bulkdata); - free_profiles_parameters(bulkdata); - free_profile_http_request_uri_parameter(bulkdata); - free_profiles_enable(bulkdata); - return 0; -} diff --git a/bulkdata/src/config.h b/bulkdata/src/config.h deleted file mode 100644 index 4bbb0b1a8..000000000 --- a/bulkdata/src/config.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* -*/ - -#ifndef __CONFIG_H -#define __CONFIG_H - -#include -#include -#include -#include -#include - -#define DEFAULT_AMD_VERSION 2 -#define DEFAULT_INSTANCE_MODE 0 - -typedef struct device_id { - char *manufacturer_oui; - char *product_class; - char *serial_number; -} device_id; - -typedef struct profile_parameter { - int profile_id; - char *name; - char *reference; -} profile_parameter; - -typedef struct profile_http_request_uri_parameter { - int profile_id; - char *name; - char *reference; -} profile_http_request_uri_parameter; - -typedef struct profile { - struct uloop_timeout utimer; - int profile_id; - int nbre_of_retained_failed_reports; - int nbre_failed_reports; - int reporting_interval; - int profile_parameter_number; - int profile_http_request_uri_parameter_number; - int http_retry_minimum_wait_interval; - int http_retry_interval_multiplier; - int min_retry; - int retry_count; - char *protocol; - char *encoding_type; - char *csv_encoding_field_separator; - char *csv_encoding_row_separator; - char *csv_encoding_escape_character; - char *csv_encoding_report_format; - char *csv_encoding_row_time_stamp; - char *json_encoding_report_format; - char *json_encoding_report_time_stamp; - char *http_url; - char *http_username; - char *http_password; - char *http_compression; - char *http_method; - char *http_ssl_capath; - char *new_report; - time_t time_reference; - time_t next_retry; - time_t next_period; - bool http_persist_across_reboot; - bool http_insecure_enable; - bool enable; - bool http_use_date_header; - bool http_retry_enable; - struct profile_parameter *profile_parameter; - struct profile_http_request_uri_parameter *profile_http_uri_parameter; - struct list_head *failed_reports; -} profile; - -typedef struct bulkdata { - struct device_id device_id; - struct profile *profile; - int log_level; - int amd_version; - unsigned int instance_mode; -} bulkdata; - -int bulkdata_config_init(struct bulkdata *bulkdata); -int bulkdata_config_fini(struct bulkdata *bulkdata); - -#ifndef FREE -#define FREE(x) do { if(x) {free(x); x = NULL;} } while (0) -#endif - -#endif //__CONFIG_H - - - - - diff --git a/bulkdata/src/datamodel.c b/bulkdata/src/datamodel.c deleted file mode 100644 index 6bdbb3fb2..000000000 --- a/bulkdata/src/datamodel.c +++ /dev/null @@ -1,1293 +0,0 @@ -/* - * Copyright (C) 2020 iopsys Software Solutions AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * Author: Amin Ben Ramdhane - */ - -#include -#include -#include -#include -#include - -#include "datamodel.h" - -/* ********** DynamicObj ********** */ -DM_MAP_OBJ tDynamicObj[] = { -/* parentobj, nextobject, parameter */ -{"Device.", tDeviceBulkDataObj, NULL}, -{0} -}; - -/************************************************************* -* ENTRY METHOD -*************************************************************/ -/*#Device.BulkData.Profile.{i}.!UCI:bulkdata/profile/dmmap_bulkdata*/ -static int browseBulkDataProfileInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - char *inst, *max_inst = NULL; - struct dmmap_dup *p; - LIST_HEAD(dup_list); - - synchronize_specific_config_sections_with_dmmap("bulkdata", "profile", "dmmap_bulkdata", &dup_list); - list_for_each_entry(p, &dup_list, list) { - - inst = handle_update_instance(1, dmctx, &max_inst, update_instance_alias, 3, - p->dmmap_section, "profile_instance", "profile_alias"); - - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p->config_section, inst) == DM_STOP) - break; - } - free_dmmap_config_dup_list(&dup_list); - return 0; -} - -/*#Device.BulkData.Profile.{i}.Parameter.{i}.!UCI:bulkdata/profile_parameter/dmmap_bulkdata*/ -static int browseBulkDataProfileParameterInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - char *inst = NULL, *max_inst = NULL, *prev_profile_id, *prof_id; - struct browse_args browse_args = {0}; - struct dmmap_dup *p = NULL; - - LIST_HEAD(dup_list); - dmuci_get_value_by_section_string((struct uci_section *)prev_data, "profile_id", &prev_profile_id); - synchronize_specific_config_sections_with_dmmap_eq("bulkdata", "profile_parameter", "dmmap_bulkdata", "profile_id", prev_profile_id, &dup_list); - list_for_each_entry(p, &dup_list, list) { - - dmuci_get_value_by_section_string(p->dmmap_section, "profile_id", &prof_id); - if (*prof_id == '\0') - dmuci_set_value_by_section(p->dmmap_section, "profile_id", prev_profile_id); - - browse_args.option = "profile_id"; - browse_args.value = prev_profile_id; - - inst = handle_update_instance(2, dmctx, &max_inst, update_instance_alias, 5, - p->dmmap_section, "parameter_instance", "parameter_alias", - check_browse_section, (void *)&browse_args); - - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p->config_section, inst) == DM_STOP) - break; - } - free_dmmap_config_dup_list(&dup_list); - return 0; -} - -/*#Device.BulkData.Profile.{i}.HTTP.RequestURIParameter.{i}.!UCI:bulkdata/profile_http_request_uri_parameter/dmmap_bulkdata*/ -static int browseBulkDataProfileHTTPRequestURIParameterInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - char *inst = NULL, *max_inst = NULL, *prev_profile_id, *prof_id; - struct browse_args browse_args = {0}; - struct dmmap_dup *p = NULL; - - LIST_HEAD(dup_list); - dmuci_get_value_by_section_string((struct uci_section *)prev_data, "profile_id", &prev_profile_id); - synchronize_specific_config_sections_with_dmmap_eq("bulkdata", "profile_http_request_uri_parameter", "dmmap_bulkdata", "profile_id", prev_profile_id, &dup_list); - list_for_each_entry(p, &dup_list, list) { - - dmuci_get_value_by_section_string(p->dmmap_section, "profile_id", &prof_id); - if (*prof_id == '\0') - dmuci_set_value_by_section(p->dmmap_section, "profile_id", prev_profile_id); - - browse_args.option = "profile_id"; - browse_args.value = prev_profile_id; - - inst = handle_update_instance(2, dmctx, &max_inst, update_instance_alias, 5, - p->dmmap_section, "requesturiparameter_instance", "requesturiparameter_alias", - check_browse_section, (void *)&browse_args); - - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p->config_section, inst) == DM_STOP) - break; - } - free_dmmap_config_dup_list(&dup_list); - return 0; -} - -/************************************************************* -* ADD & DEL OBJ -*************************************************************/ -static int addObjBulkDataProfile(char *refparam, struct dmctx *ctx, void *data, char **instance) -{ - struct uci_section *profile, *dmmap_bulkdata; - char prof_id[16], *last_inst = NULL; - - last_inst = get_last_instance_bbfdm("dmmap_bulkdata", "profile", "profile_instance"); - snprintf(prof_id, sizeof(prof_id), "%d", last_inst ? atoi(last_inst)+1 : 1); - - dmuci_add_section("bulkdata", "profile", &profile); - dmuci_set_value_by_section(profile, "profile_id", prof_id); - dmuci_set_value_by_section(profile, "enable", "0"); - dmuci_set_value_by_section(profile, "nbre_of_retained_failed_reports", "0"); - dmuci_set_value_by_section(profile, "protocol", "http"); - dmuci_set_value_by_section(profile, "reporting_interval", "86400"); - dmuci_set_value_by_section(profile, "time_reference", "0"); - dmuci_set_value_by_section(profile, "csv_encoding_field_separator", ","); - dmuci_set_value_by_section(profile, "csv_encoding_row_separator", " "); - dmuci_set_value_by_section(profile, "csv_encoding_escape_character", """); - dmuci_set_value_by_section(profile, "csv_encoding_report_format", "­column"); - dmuci_set_value_by_section(profile, "csv_encoding_row_time_stamp", "unix"); - dmuci_set_value_by_section(profile, "json_encoding_report_format", "objecthierarchy"); - dmuci_set_value_by_section(profile, "json_encoding_report_time_stamp", "unix"); - dmuci_set_value_by_section(profile, "http_compression", "none"); - dmuci_set_value_by_section(profile, "http_method", "post"); - dmuci_set_value_by_section(profile, "http_use_date_header", "1"); - dmuci_set_value_by_section(profile, "http_retry_enable", "0"); - dmuci_set_value_by_section(profile, "http_retry_minimum_wait_interval", "5"); - dmuci_set_value_by_section(profile, "http_persist_across_reboot", "0"); - - dmuci_add_section_bbfdm("dmmap_bulkdata", "profile", &dmmap_bulkdata); - dmuci_set_value_by_section(dmmap_bulkdata, "section_name", section_name(profile)); - *instance = update_instance(last_inst, 2, dmmap_bulkdata, "profile_instance"); - - return 0; -} - -static int delObjBulkDataProfile(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) -{ - struct uci_section *s = NULL, *dmmap_section = NULL, *stmp = NULL; - char *prev_profile_id; - - switch (del_action) { - case DEL_INST: - dmuci_get_value_by_section_string((struct uci_section *)data, "profile_id", &prev_profile_id); - - // Profile Parameter section - uci_foreach_option_eq_safe("bulkdata", "profile_parameter", "profile_id", prev_profile_id, stmp, s) { - - // Dmmap Profile Parameter section - get_dmmap_section_of_config_section("dmmap_bulkdata", "profile_parameter", section_name(s), &dmmap_section); - dmuci_delete_by_section(dmmap_section, NULL, NULL); - - dmuci_delete_by_section(s, NULL, NULL); - } - - // Profile HTTP Request URI Parameter section - uci_foreach_option_eq_safe("bulkdata", "profile_http_request_uri_parameter", "profile_id", prev_profile_id, stmp, s) { - - // dmmap Profile HTTP Request URI Parameter section - get_dmmap_section_of_config_section("dmmap_bulkdata", "profile_http_request_uri_parameter", section_name(s), &dmmap_section); - dmuci_delete_by_section(dmmap_section, NULL, NULL); - - dmuci_delete_by_section(s, NULL, NULL); - } - - // dmmap Profile section - get_dmmap_section_of_config_section("dmmap_bulkdata", "profile", section_name((struct uci_section *)data), &dmmap_section); - dmuci_delete_by_section(dmmap_section, NULL, NULL); - - // Profile section - dmuci_delete_by_section((struct uci_section *)data, NULL, NULL); - return 0; - case DEL_ALL: - // Profile Parameter section - uci_foreach_sections_safe("bulkdata", "profile_parameter", stmp, s) { - dmuci_delete_by_section(s, NULL, NULL); - } - - // dmmap Profile Parameter section - uci_path_foreach_sections_safe(bbfdm, "dmmap_bulkdata", "profile_parameter", stmp, s) { - dmuci_delete_by_section(s, NULL, NULL); - } - - // Profile HTTP Request URI Parameter section - uci_foreach_sections_safe("bulkdata", "profile_http_request_uri_parameter", stmp, s) { - dmuci_delete_by_section(s, NULL, NULL); - } - - // dmmap Profile HTTP Request URI Parameter section - uci_path_foreach_sections_safe(bbfdm, "dmmap_bulkdata", "profile_http_request_uri_parameter", stmp, s) { - dmuci_delete_by_section(s, NULL, NULL); - } - - // Profile section - uci_foreach_sections_safe("bulkdata", "profile", stmp, s) { - dmuci_delete_by_section(s, NULL, NULL); - } - - // dmmap Profile section - uci_path_foreach_sections_safe(bbfdm, "dmmap_bulkdata", "profile", stmp, s) { - dmuci_delete_by_section(s, NULL, NULL); - } - - return 0; - } - return 0; -} - -static int addObjBulkDataProfileParameter(char *refparam, struct dmctx *ctx, void *data, char **instance) -{ - struct uci_section *profile_parameter, *dmmap_bulkdata; - char *last_inst, *prev_profile_id; - struct browse_args browse_args = {0}; - - dmuci_get_value_by_section_string((struct uci_section *)data, "profile_id", &prev_profile_id); - - last_inst = get_last_instance_lev2_bbfdm_dmmap_opt("dmmap_bulkdata", "profile_parameter", "parameter_instance", "profile_id", prev_profile_id); - - dmuci_add_section("bulkdata", "profile_parameter", &profile_parameter); - dmuci_set_value_by_section(profile_parameter, "profile_id", prev_profile_id); - - browse_args.option = "profile_id"; - browse_args.value = prev_profile_id; - - dmuci_add_section_bbfdm("dmmap_bulkdata", "profile_parameter", &dmmap_bulkdata); - dmuci_set_value_by_section(dmmap_bulkdata, "section_name", section_name(profile_parameter)); - dmuci_set_value_by_section(dmmap_bulkdata, "profile_id", prev_profile_id); - - *instance = update_instance(last_inst, 5, dmmap_bulkdata, "parameter_instance", NULL, check_browse_section, (void *)&browse_args); - - return 0; -} - -static int delObjBulkDataProfileParameter(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) -{ - struct uci_section *s = NULL, *stmp = NULL; - char *prev_profile_id; - - switch (del_action) { - case DEL_INST: - get_dmmap_section_of_config_section("dmmap_bulkdata", "profile_parameter", section_name((struct uci_section *)data), &s); - dmuci_delete_by_section(s, NULL, NULL); - dmuci_delete_by_section((struct uci_section *)data, NULL, NULL); - return 0; - case DEL_ALL: - dmuci_get_value_by_section_string((struct uci_section *)data, "profile_id", &prev_profile_id); - - // Profile Parameter section - uci_foreach_option_eq_safe("bulkdata", "profile_parameter", "profile_id", prev_profile_id, stmp, s) { - dmuci_delete_by_section(s, NULL, NULL); - } - - // dmmap Profile Parameter section - uci_path_foreach_option_eq_safe(bbfdm, "dmmap_bulkdata", "profile_parameter", "profile_id", prev_profile_id, stmp, s) { - dmuci_delete_by_section(s, NULL, NULL); - } - - return 0; - } - return 0; -} - -static int addObjBulkDataProfileHTTPRequestURIParameter(char *refparam, struct dmctx *ctx, void *data, char **instance) -{ - struct uci_section *profile_http_request_uri_parameter, *dmmap_bulkdata; - char *last_inst, *prev_profile_id; - struct browse_args browse_args = {0}; - - dmuci_get_value_by_section_string((struct uci_section *)data, "profile_id", &prev_profile_id); - - last_inst = get_last_instance_lev2_bbfdm_dmmap_opt("dmmap_bulkdata", "profile_http_request_uri_parameter", "requesturiparameter_instance", "profile_id", prev_profile_id); - - dmuci_add_section("bulkdata", "profile_http_request_uri_parameter", &profile_http_request_uri_parameter); - dmuci_set_value_by_section(profile_http_request_uri_parameter, "profile_id", prev_profile_id); - - browse_args.option = "profile_id"; - browse_args.value = prev_profile_id; - - dmuci_add_section_bbfdm("dmmap_bulkdata", "profile_http_request_uri_parameter", &dmmap_bulkdata); - dmuci_set_value_by_section(dmmap_bulkdata, "section_name", section_name(profile_http_request_uri_parameter)); - dmuci_set_value_by_section(dmmap_bulkdata, "profile_id", prev_profile_id); - - *instance = update_instance(last_inst, 5, dmmap_bulkdata, "requesturiparameter_instance", NULL, check_browse_section, (void *)&browse_args); - - return 0; -} - -static int delObjBulkDataProfileHTTPRequestURIParameter(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) -{ - struct uci_section *s = NULL, *stmp = NULL; - char *prev_profile_id; - - switch (del_action) { - case DEL_INST: - get_dmmap_section_of_config_section("dmmap_bulkdata", "profile_http_request_uri_parameter", section_name((struct uci_section *)data), &s); - dmuci_delete_by_section(s, NULL, NULL); - dmuci_delete_by_section((struct uci_section *)data, NULL, NULL); - return 0; - case DEL_ALL: - dmuci_get_value_by_section_string((struct uci_section *)data, "profile_id", &prev_profile_id); - - // Profile Parameter section - uci_foreach_option_eq_safe("bulkdata", "profile_http_request_uri_parameter", "profile_id", prev_profile_id, stmp, s) { - dmuci_delete_by_section(s, NULL, NULL); - } - - // dmmap Profile Parameter section - uci_path_foreach_option_eq_safe(bbfdm, "dmmap_bulkdata", "profile_http_request_uri_parameter", "profile_id", prev_profile_id, stmp, s) { - dmuci_delete_by_section(s, NULL, NULL); - } - - return 0; - } - return 0; -} - -/************************************************************* -* GET & SET PARAM -*************************************************************/ -/*#Device.BulkData.Enable!UCI:bulkdata/bulkdata,bulkdata/enable*/ -static int get_BulkData_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = dmuci_get_option_value_fallback_def("bulkdata", "bulkdata", "enable", "1"); - return 0; -} - -static int set_BulkData_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - bool b; - - switch (action) { - case VALUECHECK: - if (dm_validate_boolean(value)) - return FAULT_9007; - break; - case VALUESET: - string_to_bool(value, &b); - dmuci_set_value("bulkdata", "bulkdata", "enable", b ? "1" : "0"); - break; - } - return 0; -} - -/*#Device.BulkData.Status!UCI:bulkdata/bulkdata,bulkdata/enable*/ -static int get_BulkData_Status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_option_value_string("bulkdata", "bulkdata", "enable", value); - if (strcmp(*value, "1") == 0) - *value = "Enabled"; - else - *value = "Disabled"; - return 0; -} - -static int get_BulkData_MinReportingInterval(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = "0"; - return 0; -} - -static int get_BulkData_Protocols(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = "HTTP"; - return 0; -} - -static int get_BulkData_EncodingTypes(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = "JSON,CSV"; - return 0; -} - -static int get_BulkData_ParameterWildCardSupported(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = "1"; - return 0; -} - -static int get_BulkData_MaxNumberOfProfiles(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = "-1"; - return 0; -} - -static int get_BulkData_MaxNumberOfParameterReferences(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = "-1"; - return 0; -} - -/*#Device.BulkData.ProfileNumberOfEntries!UCI:bulkdata/profile/*/ -static int get_BulkData_ProfileNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - struct uci_section *s = NULL; - int cnt = 0; - - uci_foreach_sections("bulkdata", "profile", s) { - cnt++; - } - dmasprintf(value, "%d", cnt); - return 0; -} - -/*#Device.BulkData.Profile.{i}.Enable!UCI:bulkdata/profile,@i-1/enable*/ -static int get_BulkDataProfile_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = dmuci_get_value_by_section_fallback_def((struct uci_section *)data, "enable", "1"); - return 0; -} - -static int set_BulkDataProfile_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - bool b; - - switch (action) { - case VALUECHECK: - if (dm_validate_boolean(value)) - return FAULT_9007; - break; - case VALUESET: - string_to_bool(value, &b); - dmuci_set_value_by_section((struct uci_section *)data, "enable", b ? "1" : "0"); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.Alias!UCI:dmmap_bulkdata/profile,@i-1/profile_alias*/ -static int get_BulkDataProfile_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - struct uci_section *dmmap_section = NULL; - - get_dmmap_section_of_config_section("dmmap_bulkdata", "profile", section_name((struct uci_section *)data), &dmmap_section); - dmuci_get_value_by_section_string(dmmap_section, "profile_alias", value); - if ((*value)[0] == '\0') - dmasprintf(value, "cpe-%s", instance); - return 0; -} - -static int set_BulkDataProfile_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - struct uci_section *dmmap_section = NULL; - - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, 64, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - get_dmmap_section_of_config_section("dmmap_bulkdata", "profile", section_name((struct uci_section *)data), &dmmap_section); - dmuci_set_value_by_section(dmmap_section, "profile_alias", value); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.Name!UCI:bulkdata/profile,@i-1/name*/ -static int get_BulkDataProfile_Name(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "name", value); - return 0; -} - -static int set_BulkDataProfile_Name(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, 255, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "name", value); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.NumberOfRetainedFailedReports!UCI:bulkdata/profile,@i-1/nbre_of_retained_failed_reports*/ -static int get_BulkDataProfile_NumberOfRetainedFailedReports(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "nbre_of_retained_failed_reports", value); - return 0; -} - -static int set_BulkDataProfile_NumberOfRetainedFailedReports(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_int(value, RANGE_ARGS{{"-1",NULL}}, 1)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "nbre_of_retained_failed_reports", value); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.Protocol!UCI:bulkdata/profile,@i-1/protocol*/ -static int get_BulkDataProfile_Protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "protocol", value); - if (strcmp(*value, "http") == 0) - *value = "HTTP"; - return 0; -} - -static int set_BulkDataProfile_Protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, -1, BulkDataProtocols, NULL)) - return FAULT_9007; - break; - case VALUESET: - if(strcmp(value, "HTTP") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "protocol", "http"); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.EncodingType!UCI:bulkdata/profile,@i-1/encoding_type*/ -static int get_BulkDataProfile_EncodingType(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "encoding_type", value); - if(strcmp(*value, "json") == 0) - *value = "JSON"; - else if(strcmp(*value, "csv") == 0) - *value = "CSV"; - return 0; -} - -static int set_BulkDataProfile_EncodingType(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, -1, EncodingTypes, NULL)) - return FAULT_9007; - break; - case VALUESET: - if(strcmp(value, "JSON") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "encoding_type", "json"); - else if(strcmp(value, "CSV") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "encoding_type", "csv"); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.ReportingInterval!UCI:bulkdata/profile,@i-1/reporting_interval*/ -static int get_BulkDataProfile_ReportingInterval(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = dmuci_get_value_by_section_fallback_def((struct uci_section *)data, "reporting_interval", "86400"); - return 0; -} - -static int set_BulkDataProfile_ReportingInterval(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_unsignedInt(value, RANGE_ARGS{{"1",NULL}}, 1)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "reporting_interval", value); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.TimeReference!UCI:bulkdata/profile,@i-1/time_reference*/ -static int get_BulkDataProfile_TimeReference(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - time_t time_value; - - dmuci_get_value_by_section_string((struct uci_section *)data, "time_reference", value); - if ((*value)[0] != '0' && (*value)[0] != '\0') { - time_value = atoi(*value); - char s_now[sizeof "AAAA-MM-JJTHH:MM:SSZ"]; - strftime(s_now, sizeof s_now, "%Y-%m-%dT%H:%M:%SZ", localtime(&time_value)); - *value = dmstrdup(s_now); - } else { - *value = "0001-01-01T00:00:00Z"; - } - return 0; -} - -static int set_BulkDataProfile_TimeReference(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - struct tm tm; - char buf[16]; - - switch (action) { - case VALUECHECK: - if (dm_validate_dateTime(value)) - return FAULT_9007; - break; - case VALUESET: - if (!(strptime(value, "%Y-%m-%dT%H:%M:%S", &tm))) - break; - snprintf(buf, sizeof(buf), "%ld", mktime(&tm)); - dmuci_set_value_by_section((struct uci_section *)data, "time_reference", buf); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.ParameterNumberOfEntries!UCI:bulkdata/profile_parameter,false/false*/ -static int get_BulkDataProfile_ParameterNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - char *profile_id, *curr_profile_id; - struct uci_section *s = NULL; - int cnt = 0; - - dmuci_get_value_by_section_string((struct uci_section *)data, "profile_id", &curr_profile_id); - uci_foreach_sections("bulkdata", "profile_parameter", s) { - dmuci_get_value_by_section_string(s, "profile_id", &profile_id); - if(strcmp(curr_profile_id, profile_id) != 0) - continue; - cnt++; - } - dmasprintf(value, "%d", cnt); - return 0; -} - -/*#Device.BulkData.Profile.{i}.Parameter.{i}.Name!UCI:bulkdata/profile_parameter,@i-1/name*/ -static int get_BulkDataProfileParameter_Name(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "name", value); - return 0; -} - -static int set_BulkDataProfileParameter_Name(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, 64, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "name", value); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.Parameter.{i}.Reference!UCI:bulkdata/profile_parameter,@i-1/reference*/ -static int get_BulkDataProfileParameter_Reference(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "reference", value); - return 0; -} - -static int set_BulkDataProfileParameter_Reference(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, 256, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "reference", value); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.CSVEncoding.FieldSeparator!UCI:bulkdata/profile,@i-1/csv_encoding_field_separator*/ -static int get_BulkDataProfileCSVEncoding_FieldSeparator(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "csv_encoding_field_separator", value); - return 0; -} - -static int set_BulkDataProfileCSVEncoding_FieldSeparator(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, -1, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "csv_encoding_field_separator", value); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.CSVEncoding.RowSeparator!UCI:bulkdata/profile,@i-1/csv_encoding_row_separator*/ -static int get_BulkDataProfileCSVEncoding_RowSeparator(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "csv_encoding_row_separator", value); - return 0; -} - -static int set_BulkDataProfileCSVEncoding_RowSeparator(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, -1, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - if((strcmp(value, " ") == 0) || (strcmp(value, " ") == 0)) - dmuci_set_value_by_section((struct uci_section *)data, "csv_encoding_row_separator", value); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.CSVEncoding.EscapeCharacter!UCI:bulkdata/profile,@i-1/csv_encoding_escape_character*/ -static int get_BulkDataProfileCSVEncoding_EscapeCharacter(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "csv_encoding_escape_character", value); - return 0; -} - -static int set_BulkDataProfileCSVEncoding_EscapeCharacter(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, -1, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - if(strcmp(value, """) == 0) - dmuci_set_value_by_section((struct uci_section *)data, "csv_encoding_escape_character", value); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.CSVEncoding.ReportFormat!UCI:bulkdata/profile,@i-1/csv_encoding_report_format*/ -static int get_BulkDataProfileCSVEncoding_ReportFormat(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "csv_encoding_report_format", value); - if(strcmp(*value, "row") == 0) - *value = "ParameterPerRow"; - else if(strcmp(*value, "column") == 0) - *value = "ParameterPerColumn"; - return 0; -} - -static int set_BulkDataProfileCSVEncoding_ReportFormat(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, -1, CSVReportFormat, NULL)) - return FAULT_9007; - break; - case VALUESET: - if(strcmp(value, "ParameterPerRow") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "csv_encoding_report_format", "row"); - else if(strcmp(value, "ParameterPerColumn") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "csv_encoding_report_format", "column"); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.CSVEncoding.RowTimestamp!UCI:bulkdata/profile,@i-1/csv_encoding_row_time_stamp*/ -static int get_BulkDataProfileCSVEncoding_RowTimestamp(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "csv_encoding_row_time_stamp", value); - if(strcmp(*value, "unix") == 0) - *value = "Unix-Epoch"; - else if(strcmp(*value, "iso8601") == 0) - *value = "ISO-8601"; - else if(strcmp(*value, "none") == 0) - *value = "None"; - return 0; -} - -static int set_BulkDataProfileCSVEncoding_RowTimestamp(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, -1, RowTimestamp, NULL)) - return FAULT_9007; - break; - case VALUESET: - if(strcmp(value, "Unix-Epoch") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "csv_encoding_row_time_stamp", "unix"); - else if(strcmp(value, "ISO-8601") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "csv_encoding_row_time_stamp", "iso8601"); - else if(strcmp(value, "None") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "csv_encoding_row_time_stamp", "none"); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.JSONEncoding.ReportFormat!UCI:bulkdata/profile,@i-1/json_encoding_report_format*/ -static int get_BulkDataProfileJSONEncoding_ReportFormat(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "json_encoding_report_format", value); - if(strcmp(*value, "objecthierarchy") == 0) - *value = "ObjectHierarchy"; - else if(strcmp(*value, "namevaluepair") == 0) - *value = "NameValuePair"; - return 0; -} - -static int set_BulkDataProfileJSONEncoding_ReportFormat(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, -1, JSONReportFormat, NULL)) - return FAULT_9007; - break; - case VALUESET: - if(strcmp(value, "ObjectHierarchy") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "json_encoding_report_format", "objecthierarchy"); - else if(strcmp(value, "NameValuePair") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "json_encoding_report_format", "namevaluepair"); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.JSONEncoding.ReportTimestamp!UCI:bulkdata/profile,@i-1/json_encoding_report_time_stamp*/ -static int get_BulkDataProfileJSONEncoding_ReportTimestamp(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "json_encoding_report_time_stamp", value); - if(strcmp(*value, "unix") == 0) - *value = "Unix-Epoch"; - else if(strcmp(*value, "iso8601") == 0) - *value = "ISO-8601"; - else if(strcmp(*value, "none") == 0) - *value = "None"; - return 0; -} - -static int set_BulkDataProfileJSONEncoding_ReportTimestamp(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, -1, RowTimestamp, NULL)) - return FAULT_9007; - break; - case VALUESET: - if(strcmp(value, "Unix-Epoch") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "json_encoding_report_time_stamp", "unix"); - else if(strcmp(value, "ISO-8601") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "json_encoding_report_time_stamp", "iso8601"); - else if(strcmp(value, "None") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "json_encoding_report_time_stamp", "none"); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.HTTP.URL!UCI:bulkdata/profile,@i-1/http_url*/ -static int get_BulkDataProfileHTTP_URL(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "http_url", value); - return 0; -} - -static int set_BulkDataProfileHTTP_URL(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, 1024, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "http_url", value); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.HTTP.Username!UCI:bulkdata/profile,@i-1/http_username*/ -static int get_BulkDataProfileHTTP_Username(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "http_username", value); - return 0; -} - -static int set_BulkDataProfileHTTP_Username(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, 256, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "http_username", value); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.HTTP.Password!UCI:bulkdata/profile,@i-1/http_password*/ -static int get_BulkDataProfileHTTP_Password(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = ""; - return 0; -} - -static int set_BulkDataProfileHTTP_Password(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, 256, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "http_password", value); - break; - } - return 0; -} - -static int get_BulkDataProfileHTTP_CompressionsSupported(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = "GZIP,Compress,Deflate"; - return 0; -} - -/*#Device.BulkData.Profile.{i}.HTTP.Compression!UCI:bulkdata/profile,@i-1/http_compression*/ -static int get_BulkDataProfileHTTP_Compression(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "http_compression", value); - if(strcmp(*value, "gzip") == 0) - *value = "GZIP"; - else if(strcmp(*value, "compress") == 0) - *value = "Compress"; - else if(strcmp(*value, "deflate") == 0) - *value = "Deflate"; - return 0; -} - -static int set_BulkDataProfileHTTP_Compression(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, -1, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - if(strcmp(value, "GZIP") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "http_compression", "gzip"); - else if(strcmp(value, "Compress") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "http_compression", "compress"); - else if(strcmp(value, "Deflate") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "http_compression", "deflate"); - break; - } - return 0; -} - -static int get_BulkDataProfileHTTP_MethodsSupported(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = "POST,PUT"; - return 0; -} - -/*#Device.BulkData.Profile.{i}.HTTP.Method!UCI:bulkdata/profile,@i-1/http_method*/ -static int get_BulkDataProfileHTTP_Method(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "http_method", value); - if(strcmp(*value, "post") == 0) - *value = "POST"; - else if(strcmp(*value, "put") == 0) - *value = "PUT"; - return 0; -} - -static int set_BulkDataProfileHTTP_Method(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, -1, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - if(strcmp(value, "POST") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "http_method", "post"); - else if(strcmp(value, "PUT") == 0) - dmuci_set_value_by_section((struct uci_section *)data, "http_method", "put"); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.HTTP.UseDateHeader!UCI:bulkdata/profile,@i-1/http_use_date_header*/ -static int get_BulkDataProfileHTTP_UseDateHeader(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = dmuci_get_value_by_section_fallback_def((struct uci_section *)data, "http_use_date_header", "1"); - return 0; -} - -static int set_BulkDataProfileHTTP_UseDateHeader(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - bool b; - - switch (action) { - case VALUECHECK: - if (dm_validate_boolean(value)) - return FAULT_9007; - break; - case VALUESET: - string_to_bool(value, &b); - dmuci_set_value_by_section((struct uci_section *)data, "http_use_date_header", b ? "1" : "0"); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.HTTP.RetryEnable!UCI:bulkdata/profile,@i-1/http_retry_enable*/ -static int get_BulkDataProfileHTTP_RetryEnable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = dmuci_get_value_by_section_fallback_def((struct uci_section *)data, "http_retry_enable", "1"); - return 0; -} - -static int set_BulkDataProfileHTTP_RetryEnable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - bool b; - - switch (action) { - case VALUECHECK: - if (dm_validate_boolean(value)) - return FAULT_9007; - break; - case VALUESET: - string_to_bool(value, &b); - dmuci_set_value_by_section((struct uci_section *)data, "http_retry_enable", b ? "1" : "0"); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.HTTP.RetryMinimumWaitInterval!UCI:bulkdata/profile,@i-1/http_retry_minimum_wait_interval*/ -static int get_BulkDataProfileHTTP_RetryMinimumWaitInterval(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = dmuci_get_value_by_section_fallback_def((struct uci_section *)data, "http_retry_minimum_wait_interval", "5"); - return 0; -} - -static int set_BulkDataProfileHTTP_RetryMinimumWaitInterval(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_unsignedInt(value, RANGE_ARGS{{"1","65535"}}, 1)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "http_retry_minimum_wait_interval", value); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.HTTP.RetryIntervalMultiplier!UCI:bulkdata/profile,@i-1/http_retry_interval_multiplier*/ -static int get_BulkDataProfileHTTP_RetryIntervalMultiplier(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = dmuci_get_value_by_section_fallback_def((struct uci_section *)data, "http_retry_interval_multiplier", "2000"); - return 0; -} - -static int set_BulkDataProfileHTTP_RetryIntervalMultiplier(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_unsignedInt(value, RANGE_ARGS{{"1000","65535"}}, 1)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "http_retry_interval_multiplier", value); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.HTTP.RequestURIParameterNumberOfEntries!UCI:bulkdata/profile_http_request_uri_parameter,false/false*/ -static int get_BulkDataProfileHTTP_RequestURIParameterNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - char *profile_id, *curr_profile_id; - struct uci_section *s = NULL; - int cnt = 0; - - dmuci_get_value_by_section_string((struct uci_section *)data, "profile_id", &curr_profile_id); - uci_foreach_sections("bulkdata", "profile_http_request_uri_parameter", s) { - dmuci_get_value_by_section_string(s, "profile_id", &profile_id); - if(strcmp(curr_profile_id, profile_id) != 0) - continue; - cnt++; - } - dmasprintf(value, "%d", cnt); - return 0; -} - -/*#Device.BulkData.Profile.{i}.HTTP.PersistAcrossReboot!UCI:bulkdata/profile,@i-1/http_persist_across_reboot*/ -static int get_BulkDataProfileHTTP_PersistAcrossReboot(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = dmuci_get_value_by_section_fallback_def((struct uci_section *)data, "http_persist_across_reboot", "1"); - return 0; -} - -static int set_BulkDataProfileHTTP_PersistAcrossReboot(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - bool b; - - switch (action) { - case VALUECHECK: - if (dm_validate_boolean(value)) - return FAULT_9007; - break; - case VALUESET: - string_to_bool(value, &b); - dmuci_set_value_by_section((struct uci_section *)data, "http_persist_across_reboot", b ? "1" : "0"); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.HTTP.RequestURIParameter.{i}.Name!UCI:bulkdata/profile_http_request_uri_parameter,@i-1/name*/ -static int get_BulkDataProfileHTTPRequestURIParameter_Name(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "name", value); - return 0; -} - -static int set_BulkDataProfileHTTPRequestURIParameter_Name(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, 64, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "name", value); - break; - } - return 0; -} - -/*#Device.BulkData.Profile.{i}.HTTP.RequestURIParameter.{i}.Reference!UCI:bulkdata/profile_http_request_uri_parameter,@i-1/reference*/ -static int get_BulkDataProfileHTTPRequestURIParameter_Reference(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "reference", value); - return 0; -} - -static int set_BulkDataProfileHTTPRequestURIParameter_Reference(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, 256, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "reference", value); - break; - } - return 0; -} - -/* *** Device.BulkData. *** */ -DMOBJ tDeviceBulkDataObj[] = { -/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ -{"BulkData", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tBulkDataObj, tBulkDataParams, NULL, BBFDM_BOTH}, -{0} -}; - -DMOBJ tBulkDataObj[] = { -/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ -{"Profile", &DMWRITE, addObjBulkDataProfile, delObjBulkDataProfile, NULL, browseBulkDataProfileInst, NULL, NULL, tBulkDataProfileObj, tBulkDataProfileParams, NULL, BBFDM_BOTH, LIST_KEY{"Alias", NULL}}, -{0} -}; - -DMLEAF tBulkDataParams[] = { -/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ -{"Enable", &DMWRITE, DMT_BOOL, get_BulkData_Enable, set_BulkData_Enable, BBFDM_BOTH}, -{"Status", &DMREAD, DMT_STRING, get_BulkData_Status, NULL, BBFDM_BOTH}, -{"MinReportingInterval", &DMREAD, DMT_UNINT, get_BulkData_MinReportingInterval, NULL, BBFDM_BOTH}, -{"Protocols", &DMREAD, DMT_STRING, get_BulkData_Protocols, NULL, BBFDM_BOTH}, -{"EncodingTypes", &DMREAD, DMT_STRING, get_BulkData_EncodingTypes, NULL, BBFDM_BOTH}, -{"ParameterWildCardSupported", &DMREAD, DMT_BOOL, get_BulkData_ParameterWildCardSupported, NULL, BBFDM_BOTH}, -{"MaxNumberOfProfiles", &DMREAD, DMT_INT, get_BulkData_MaxNumberOfProfiles, NULL, BBFDM_BOTH}, -{"MaxNumberOfParameterReferences", &DMREAD, DMT_INT, get_BulkData_MaxNumberOfParameterReferences, NULL, BBFDM_BOTH}, -{"ProfileNumberOfEntries", &DMREAD, DMT_UNINT, get_BulkData_ProfileNumberOfEntries, NULL, BBFDM_BOTH}, -{0} -}; - -/* *** Device.BulkData.Profile.{i}. *** */ -DMOBJ tBulkDataProfileObj[] = { -/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ -{"Parameter", &DMWRITE, addObjBulkDataProfileParameter, delObjBulkDataProfileParameter, NULL, browseBulkDataProfileParameterInst, NULL, NULL, NULL, tBulkDataProfileParameterParams, NULL, BBFDM_BOTH}, -{"CSVEncoding", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tBulkDataProfileCSVEncodingParams, NULL, BBFDM_BOTH}, -{"JSONEncoding", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tBulkDataProfileJSONEncodingParams, NULL, BBFDM_BOTH}, -{"HTTP", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tBulkDataProfileHTTPObj, tBulkDataProfileHTTPParams, NULL, BBFDM_BOTH}, -{0} -}; - -DMLEAF tBulkDataProfileParams[] = { -/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ -{"Enable", &DMWRITE, DMT_BOOL, get_BulkDataProfile_Enable, set_BulkDataProfile_Enable, BBFDM_BOTH}, -{"Alias", &DMWRITE, DMT_STRING, get_BulkDataProfile_Alias, set_BulkDataProfile_Alias, BBFDM_BOTH}, -{"Name", &DMWRITE, DMT_STRING, get_BulkDataProfile_Name, set_BulkDataProfile_Name, BBFDM_BOTH}, -{"NumberOfRetainedFailedReports", &DMWRITE, DMT_INT, get_BulkDataProfile_NumberOfRetainedFailedReports, set_BulkDataProfile_NumberOfRetainedFailedReports, BBFDM_BOTH}, -{"Protocol", &DMWRITE, DMT_STRING, get_BulkDataProfile_Protocol, set_BulkDataProfile_Protocol, BBFDM_BOTH}, -{"EncodingType", &DMWRITE, DMT_STRING, get_BulkDataProfile_EncodingType, set_BulkDataProfile_EncodingType, BBFDM_BOTH}, -{"ReportingInterval", &DMWRITE, DMT_UNINT, get_BulkDataProfile_ReportingInterval, set_BulkDataProfile_ReportingInterval, BBFDM_BOTH}, -{"TimeReference", &DMWRITE, DMT_TIME, get_BulkDataProfile_TimeReference, set_BulkDataProfile_TimeReference, BBFDM_BOTH}, -{"ParameterNumberOfEntries", &DMREAD, DMT_UNINT, get_BulkDataProfile_ParameterNumberOfEntries, NULL, BBFDM_BOTH}, -//{"StreamingHost", &DMWRITE, DMT_STRING, get_BulkDataProfile_StreamingHost, set_BulkDataProfile_StreamingHost, BBFDM_BOTH}, -//{"StreamingPort", &DMWRITE, DMT_UNINT, get_BulkDataProfile_StreamingPort, set_BulkDataProfile_StreamingPort, BBFDM_BOTH}, -//{"StreamingSessionID", &DMWRITE, DMT_UNINT, get_BulkDataProfile_StreamingSessionID, set_BulkDataProfile_StreamingSessionID, BBFDM_BOTH}, -//{"FileTransferURL", &DMWRITE, DMT_STRING, get_BulkDataProfile_FileTransferURL, set_BulkDataProfile_FileTransferURL, BBFDM_BOTH}, -//{"FileTransferUsername", &DMWRITE, DMT_STRING, get_BulkDataProfile_FileTransferUsername, set_BulkDataProfile_FileTransferUsername, BBFDM_BOTH}, -//{"FileTransferPassword", &DMWRITE, DMT_STRING, get_BulkDataProfile_FileTransferPassword, set_BulkDataProfile_FileTransferPassword, BBFDM_BOTH}, -//{"ControlFileFormat", &DMWRITE, DMT_STRING, get_BulkDataProfile_ControlFileFormat, set_BulkDataProfile_ControlFileFormat, BBFDM_BOTH}, -//{"Controller", &DMREAD, DMT_STRING, get_BulkDataProfile_Controller, NULL, BBFDM_USP}, -{0} -}; - -/* *** Device.BulkData.Profile.{i}.Parameter.{i}. *** */ -DMLEAF tBulkDataProfileParameterParams[] = { -/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ -{"Name", &DMWRITE, DMT_STRING, get_BulkDataProfileParameter_Name, set_BulkDataProfileParameter_Name, BBFDM_BOTH}, -{"Reference", &DMWRITE, DMT_STRING, get_BulkDataProfileParameter_Reference, set_BulkDataProfileParameter_Reference, BBFDM_BOTH}, -{0} -}; - -/* *** Device.BulkData.Profile.{i}.CSVEncoding. *** */ -DMLEAF tBulkDataProfileCSVEncodingParams[] = { -/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ -{"FieldSeparator", &DMWRITE, DMT_STRING, get_BulkDataProfileCSVEncoding_FieldSeparator, set_BulkDataProfileCSVEncoding_FieldSeparator, BBFDM_BOTH}, -{"RowSeparator", &DMWRITE, DMT_STRING, get_BulkDataProfileCSVEncoding_RowSeparator, set_BulkDataProfileCSVEncoding_RowSeparator, BBFDM_BOTH}, -{"EscapeCharacter", &DMWRITE, DMT_STRING, get_BulkDataProfileCSVEncoding_EscapeCharacter, set_BulkDataProfileCSVEncoding_EscapeCharacter, BBFDM_BOTH}, -{"ReportFormat", &DMWRITE, DMT_STRING, get_BulkDataProfileCSVEncoding_ReportFormat, set_BulkDataProfileCSVEncoding_ReportFormat, BBFDM_BOTH}, -{"RowTimestamp", &DMWRITE, DMT_STRING, get_BulkDataProfileCSVEncoding_RowTimestamp, set_BulkDataProfileCSVEncoding_RowTimestamp, BBFDM_BOTH}, -{0} -}; - -/* *** Device.BulkData.Profile.{i}.JSONEncoding. *** */ -DMLEAF tBulkDataProfileJSONEncodingParams[] = { -/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ -{"ReportFormat", &DMWRITE, DMT_STRING, get_BulkDataProfileJSONEncoding_ReportFormat, set_BulkDataProfileJSONEncoding_ReportFormat, BBFDM_BOTH}, -{"ReportTimestamp", &DMWRITE, DMT_STRING, get_BulkDataProfileJSONEncoding_ReportTimestamp, set_BulkDataProfileJSONEncoding_ReportTimestamp, BBFDM_BOTH}, -{0} -}; - -/* *** Device.BulkData.Profile.{i}.HTTP. *** */ -DMOBJ tBulkDataProfileHTTPObj[] = { -/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ -{"RequestURIParameter", &DMWRITE, addObjBulkDataProfileHTTPRequestURIParameter, delObjBulkDataProfileHTTPRequestURIParameter, NULL, browseBulkDataProfileHTTPRequestURIParameterInst, NULL, NULL, NULL, tBulkDataProfileHTTPRequestURIParameterParams, NULL, BBFDM_BOTH}, -{0} -}; - -DMLEAF tBulkDataProfileHTTPParams[] = { -/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ -{"URL", &DMWRITE, DMT_STRING, get_BulkDataProfileHTTP_URL, set_BulkDataProfileHTTP_URL, BBFDM_BOTH}, -{"Username", &DMWRITE, DMT_STRING, get_BulkDataProfileHTTP_Username, set_BulkDataProfileHTTP_Username, BBFDM_BOTH}, -{"Password", &DMWRITE, DMT_STRING, get_BulkDataProfileHTTP_Password, set_BulkDataProfileHTTP_Password, BBFDM_BOTH}, -{"CompressionsSupported", &DMREAD, DMT_STRING, get_BulkDataProfileHTTP_CompressionsSupported, NULL, BBFDM_BOTH}, -{"Compression", &DMWRITE, DMT_STRING, get_BulkDataProfileHTTP_Compression, set_BulkDataProfileHTTP_Compression, BBFDM_BOTH}, -{"MethodsSupported", &DMREAD, DMT_STRING, get_BulkDataProfileHTTP_MethodsSupported, NULL, BBFDM_BOTH}, -{"Method", &DMWRITE, DMT_STRING, get_BulkDataProfileHTTP_Method, set_BulkDataProfileHTTP_Method, BBFDM_BOTH}, -{"UseDateHeader", &DMWRITE, DMT_BOOL, get_BulkDataProfileHTTP_UseDateHeader, set_BulkDataProfileHTTP_UseDateHeader, BBFDM_BOTH}, -{"RetryEnable", &DMWRITE, DMT_BOOL, get_BulkDataProfileHTTP_RetryEnable, set_BulkDataProfileHTTP_RetryEnable, BBFDM_BOTH}, -{"RetryMinimumWaitInterval", &DMWRITE, DMT_UNINT, get_BulkDataProfileHTTP_RetryMinimumWaitInterval, set_BulkDataProfileHTTP_RetryMinimumWaitInterval, BBFDM_BOTH}, -{"RetryIntervalMultiplier", &DMWRITE, DMT_UNINT, get_BulkDataProfileHTTP_RetryIntervalMultiplier, set_BulkDataProfileHTTP_RetryIntervalMultiplier, BBFDM_BOTH}, -{"RequestURIParameterNumberOfEntries", &DMREAD, DMT_UNINT, get_BulkDataProfileHTTP_RequestURIParameterNumberOfEntries, NULL, BBFDM_BOTH}, -{"PersistAcrossReboot", &DMWRITE, DMT_BOOL, get_BulkDataProfileHTTP_PersistAcrossReboot, set_BulkDataProfileHTTP_PersistAcrossReboot, BBFDM_BOTH}, -{0} -}; - -/* *** Device.BulkData.Profile.{i}.HTTP.RequestURIParameter.{i}. *** */ -DMLEAF tBulkDataProfileHTTPRequestURIParameterParams[] = { -/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ -{"Name", &DMWRITE, DMT_STRING, get_BulkDataProfileHTTPRequestURIParameter_Name, set_BulkDataProfileHTTPRequestURIParameter_Name, BBFDM_BOTH}, -{"Reference", &DMWRITE, DMT_STRING, get_BulkDataProfileHTTPRequestURIParameter_Reference, set_BulkDataProfileHTTPRequestURIParameter_Reference, BBFDM_BOTH}, -{0} -}; - - diff --git a/bulkdata/src/datamodel.h b/bulkdata/src/datamodel.h deleted file mode 100644 index 79bac3565..000000000 --- a/bulkdata/src/datamodel.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2020 iopsys Software Solutions AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * Author: Amin Ben Ramdhane - */ - -#ifndef _BULKDATA_H_ -#define _BULKDATA_H_ - -#include - -extern DMOBJ tDeviceBulkDataObj[]; -extern DMOBJ tBulkDataObj[]; -extern DMLEAF tBulkDataParams[]; -extern DMOBJ tBulkDataProfileObj[]; -extern DMLEAF tBulkDataProfileParams[]; -extern DMLEAF tBulkDataProfileParameterParams[]; -extern DMLEAF tBulkDataProfileCSVEncodingParams[]; -extern DMLEAF tBulkDataProfileJSONEncodingParams[]; -extern DMOBJ tBulkDataProfileHTTPObj[]; -extern DMLEAF tBulkDataProfileHTTPParams[]; -extern DMLEAF tBulkDataProfileHTTPRequestURIParameterParams[]; - -#endif //__BULKDATA_H_ - diff --git a/bulkdata/src/http.c b/bulkdata/src/http.c deleted file mode 100644 index 0d271502f..000000000 --- a/bulkdata/src/http.c +++ /dev/null @@ -1,196 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* Omar Kallel -*/ - -#include "http.h" - -static struct http_client http_c; -static CURL *curl; - -int http_client_init(struct profile *profile) -{ - char *url = create_request_url(profile); - if(url) { - asprintf(&http_c.url, "%s", url); - free(url); - } - bulkdata_log(SINFO, "ACS url: %s", http_c.url); - - curl_global_init(CURL_GLOBAL_SSL); - curl = curl_easy_init(); - if (!curl) return -1; - - return 0; -} - -void http_client_exit(void) -{ - FREE(http_c.url); - - if (http_c.header_list) { - curl_slist_free_all(http_c.header_list); - http_c.header_list = NULL; - } - - curl_easy_cleanup(curl); - curl_global_cleanup(); - -} - -static size_t http_get_response(void *buffer, size_t size, size_t rxed, char **msg_in) -{ - char *c; - - if (asprintf(&c, "%s%.*s", *msg_in, (int) (size * rxed), (char *)buffer) == -1) { - FREE(*msg_in); - return -1; - } - - free(*msg_in); - *msg_in = c; - - return size * rxed; -} - -int http_send_message(struct profile *profile, char *msg_out, int msg_out_len, char **msg_in) -{ - CURLcode res; - long http_code = 0; - char errbuf[CURL_ERROR_SIZE]; - - http_c.header_list = NULL; - http_c.header_list = curl_slist_append(http_c.header_list, "User-Agent: iopsys-bulkdata"); - if (!http_c.header_list) return -1; - - if (profile->http_use_date_header) { - if (bulkdata_get_time() != NULL) { - http_c.header_list = curl_slist_append(http_c.header_list, bulkdata_get_time()); - if (!http_c.header_list) return -1; - } - } - - if (strcmp(profile->encoding_type, "json") == 0) { - http_c.header_list = curl_slist_append(http_c.header_list, "Content-Type: application/json; charset=\"utf-8\""); - if (!http_c.header_list) return -1; - - if(strcmp (profile->json_encoding_report_format, "objecthierarchy") == 0) { - http_c.header_list = curl_slist_append(http_c.header_list, "BBF-Report-Format: \"ObjectHierarchy\""); - if (!http_c.header_list) return -1; - } else if(strcmp(profile->json_encoding_report_format, "namevaluepair") == 0) { - http_c.header_list = curl_slist_append(http_c.header_list, "BBF-Report-Format: \"NameValuePair\""); - if (!http_c.header_list) return -1; - } - } else if(strcmp(profile->encoding_type, "csv") == 0) { - http_c.header_list = curl_slist_append(http_c.header_list, "Content-Type: text/csv; charset=\"utf-8\""); - if (!http_c.header_list) return -1; - - if(strcmp (profile->csv_encoding_report_format, "row") == 0) { - http_c.header_list = curl_slist_append(http_c.header_list, "BBF-Report-Format: \"ParameterPerRow\""); - if (!http_c.header_list) return -1; - } else if(strcmp (profile->csv_encoding_report_format, "column") == 0) { - http_c.header_list = curl_slist_append(http_c.header_list, "BBF-Report-Format: \"ParameterPerColumn\""); - if (!http_c.header_list) return -1; - } - } - - curl_easy_setopt(curl, CURLOPT_URL, http_c.url); - curl_easy_setopt(curl, CURLOPT_USERNAME, profile->http_username); - curl_easy_setopt(curl, CURLOPT_PASSWORD, profile->http_password); - curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC|CURLAUTH_DIGEST); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, HTTP_TIMEOUT); - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, HTTP_TIMEOUT); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(curl, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL); - curl_easy_setopt(curl, CURLOPT_NOBODY, 0); - - if(strcasecmp(profile->http_compression, "gzip") == 0) { - curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip"); - http_c.header_list = curl_slist_append(http_c.header_list, "Content-Encoding: gzip"); - } else if(strcasecmp(profile->http_compression, "compress") == 0) { - curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "compress"); - http_c.header_list = curl_slist_append(http_c.header_list, "Content-Encoding: compress"); - } else if(strcasecmp(profile->http_compression, "deflate") == 0) { - curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "deflate"); - http_c.header_list = curl_slist_append(http_c.header_list, "Content-Encoding: deflate"); - } - - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_c.header_list); - if(strcasecmp(profile->http_method, "put") == 0) - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, msg_out); - if (msg_out) - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) msg_out_len); - else - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 0); - - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_get_response); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, msg_in); - - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf); - - if (profile->http_ssl_capath) - curl_easy_setopt(curl, CURLOPT_CAPATH, profile->http_ssl_capath); - if (profile->http_insecure_enable) { - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); - } - *msg_in = (char *) calloc (1, sizeof(char)); - - res = curl_easy_perform(curl); - - if(res != CURLE_OK) { - size_t len = strlen(errbuf); - if(len) { - if (errbuf[len - 1] == '\n') errbuf[len - 1] = '\0'; - bulkdata_log(SCRIT, "libcurl: (%d) %s", res, errbuf); - } else { - bulkdata_log(SCRIT, "libcurl: (%d) %s", res, curl_easy_strerror(res)); - } - } - - if (!strlen(*msg_in)) - FREE(*msg_in); - - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); - if(http_code == 200) - bulkdata_log(SINFO, "Receive HTTP 200 OK from Bulkdata Collector"); - else if(http_code == 401) - bulkdata_log(SINFO, "Receive HTTP 401 Unauthorized from Bulkdata Collector"); - else if(http_code == 204) - bulkdata_log(SINFO, "Receive HTTP 204 No Content from Bulkdata Collector"); - else - bulkdata_log(SINFO, "Receive HTTP %d from Bulkdata Collector", http_code); - - if(http_code == 415) - { - strcpy(profile->http_compression, "None"); - goto error; - } - if (http_code != 200 && http_code != 204) - goto error; - - curl_easy_reset(curl); - if (http_c.header_list) { - curl_slist_free_all(http_c.header_list); - http_c.header_list = NULL; - } - - if (res) goto error; - - return http_code; - -error: - FREE(*msg_in); - if (http_c.header_list) { - curl_slist_free_all(http_c.header_list); - http_c.header_list = NULL; - } - return -1; -} diff --git a/bulkdata/src/http.h b/bulkdata/src/http.h deleted file mode 100644 index 272d706a9..000000000 --- a/bulkdata/src/http.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* -*/ - -#ifndef __HTTP_H -#define __HTTP_H - -#include -#include -#include -#include -#include -#include "config.h" -#include "log.h" -#include "times.h" -#include "common.h" - -#define HTTP_TIMEOUT 30 - -struct http_client -{ - struct curl_slist *header_list; - char *url; -}; - -int http_client_init(struct profile *profile); -void http_client_exit(void); -int http_send_message(struct profile *profile, char *msg_out, int msg_out_len, char **msg_in); - -#endif //__HTTP_H diff --git a/bulkdata/src/log.c b/bulkdata/src/log.c deleted file mode 100644 index 388241d7d..000000000 --- a/bulkdata/src/log.c +++ /dev/null @@ -1,57 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* -*/ - -#include -#include -#include -#include -#include - -#include "bulkdata.h" -#include "config.h" -#include "log.h" - -static const int log_syslogmap[] = { - [SCRIT] = LOG_CRIT, - [SWARNING] = LOG_WARNING, - [SNOTICE] = LOG_NOTICE, - [SINFO] = LOG_INFO, - [SDEBUG] = LOG_DEBUG -}; - -static const char* log_str[] = { - [SCRIT] = "CRITICAL", - [SWARNING] = "WARNING", - [SNOTICE] = "NOTICE", - [SINFO] = "INFO", - [SDEBUG] = "DEBUG" -}; - -void bulkdata_log(int priority, const char *format, ...) -{ - va_list vl; - - if (priority <= bulkdata_main.log_level) { - time_t t = time(NULL); - struct tm tm = *localtime(&t); - va_start(vl, format); - printf("%d-%02d-%02d %02d:%02d:%02d [bulkdata] %s - ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, log_str[priority]); - vprintf(format, vl); - va_end(vl); - printf("\n"); - - openlog("bulkdata", 0, LOG_DAEMON); - va_start(vl, format); - vsyslog(log_syslogmap[priority], format, vl); - va_end(vl); - closelog(); - } -} diff --git a/bulkdata/src/log.h b/bulkdata/src/log.h deleted file mode 100644 index 869b7438b..000000000 --- a/bulkdata/src/log.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* -*/ - -#ifndef __LOG_H -#define __LOG_H - -#define DEFAULT_LOGLEVEL SINFO - -enum bulkdata_log_level_enum { - SCRIT, - SWARNING, - SNOTICE, - SINFO, - SDEBUG, - __MAX_SLOG -}; - -void bulkdata_log(int priority, const char *format, ...); - -#endif //__LOG_H diff --git a/bulkdata/src/report.c b/bulkdata/src/report.c deleted file mode 100644 index 74dd0ad4a..000000000 --- a/bulkdata/src/report.c +++ /dev/null @@ -1,336 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* Author: Omar Kallel -* -*/ - -#include "report.h" - -static void add_new_json_obj(json_object *json_obj, char *name, char *data, char *type) -{ - json_object *jobj; - if(strstr(type, "unsignedInt") || strstr(type, "int") || strstr(type, "long")) - jobj = json_object_new_int64(atoi(data)); - else if(strstr(type, "bool")) - jobj = json_object_new_boolean(atoi(data)); - else - jobj = json_object_new_string(data); - - json_object_object_add(json_obj, name, jobj); -} - -static void create_json_bulkdata_report_object_hierarchy(struct profile *profile, char **report) -{ - struct json_object *json_obj, *json_obj1, *json_obj2; - struct resultsnode *p; - int i, j, profile_param_number = profile->profile_parameter_number; - char *param_name, *result, *pch, *pchr, *collection_time = NULL; - char buf[1024] = {0}; - - json_obj = json_object_new_object(); - get_time_stamp(profile->json_encoding_report_time_stamp, &collection_time); - if(collection_time) { - if(strcmp(profile->json_encoding_report_time_stamp, "iso8601") == 0) - json_object_object_add(json_obj, "CollectionTime", json_object_new_string(collection_time)); - else - json_object_object_add(json_obj, "CollectionTime", json_object_new_int64(atoi(collection_time))); - free(collection_time); - } - json_obj2 = json_obj; - for (i = 0; i < profile_param_number; i++) { - LIST_HEAD(results_list); - bulkdata_get_value_results(profile->profile_parameter[i].reference, &results_list); - list_for_each_entry(p, &results_list, list) { - char *argv[128] = {0}; - j = 0; - param_name = get_bulkdata_profile_parameter_name(profile->profile_parameter[i].reference, profile->profile_parameter[i].name, p->name); - strcpy(buf, param_name); - for (pch = strtok_r(buf, ".", &pchr); pch != NULL; pch = strtok_r(NULL, ".", &pchr)) { - argv[j] = pch; - json_obj1 = (json_object *)bbf_api_dmjson_select_obj(json_obj, argv); - if (json_obj1) - json_obj2 = json_obj1; - else { - if (pchr != NULL && *pchr != '\0') { - json_object *new_obj = json_object_new_object(); - json_object_object_add(json_obj2, pch, new_obj); - json_obj2 = new_obj; - } - else - add_new_json_obj(json_obj2, pch, p->data, p->type); - } - j++; - } - } - bulkdata_free_data_from_list(&results_list); - FREE(param_name); - } - result = (char *)json_object_to_json_string_ext(json_obj, JSON_C_TO_STRING_PRETTY); - *report = strdup(result); - json_object_put(json_obj); -} - -static void create_json_bulkdata_report_name_value_pair(struct profile *profile, char **report) -{ - struct json_object *json_obj; - struct resultsnode *p; - char *param_name, *result, *collection_time = NULL; - int i = 0, profile_param_number = profile->profile_parameter_number; - - json_obj = json_object_new_object(); - get_time_stamp(profile->json_encoding_report_time_stamp, &collection_time); - if(collection_time) { - if(strcmp(profile->json_encoding_report_time_stamp, "iso8601") == 0) - json_object_object_add(json_obj, "CollectionTime", json_object_new_string(collection_time)); - else - json_object_object_add(json_obj, "CollectionTime", json_object_new_int64(atoi(collection_time))); - free(collection_time); - } - for (i = 0; i < profile_param_number; i++) { - LIST_HEAD(results_list); - bulkdata_get_value_results(profile->profile_parameter[i].reference, &results_list); - list_for_each_entry(p, &results_list, list) { - param_name = get_bulkdata_profile_parameter_name(profile->profile_parameter[i].reference, profile->profile_parameter[i].name, p->name); - add_new_json_obj(json_obj, param_name, p->data, p->type); - FREE(param_name); - } - bulkdata_free_data_from_list(&results_list); - } - result = (char *)json_object_to_json_string_ext(json_obj, JSON_C_TO_STRING_PRETTY); - *report = strdup(result); - json_object_put(json_obj); -} - -static void add_failed_reports_to_report_json(struct profile *profile, char *new_report, char **report, int isnext) -{ - json_object *json_obj, *json_array, *json_string; - struct failed_reports *retreport = NULL; - char *msgout = NULL; - int j = 0; - - json_obj = json_object_new_object(); - json_array = json_object_new_array(); - json_object_object_add(json_obj,"Report", json_array); - - if(list_empty(profile->failed_reports)) - goto new_report; - - list_for_each_entry(retreport, profile->failed_reports, list) { - if(!j && isnext) { - j = 1; - continue; - } - json_string = json_tokener_parse(retreport->freport); - json_object_array_add(json_array, json_string); - } - -new_report : - if(new_report) { - json_string = json_tokener_parse(new_report); - json_object_array_add(json_array, json_string); - } - - msgout = (char *)json_object_to_json_string_ext(json_obj, JSON_C_TO_STRING_PRETTY); - *report = strdup(msgout); - json_object_put(json_obj); -} - -static void create_report_json(char *new_report, char **report) -{ - json_object *json_obj, *json_array, *json_string; - char *msgout = NULL; - - json_obj = json_object_new_object(); - json_array = json_object_new_array(); - json_object_object_add(json_obj,"Report", json_array); - - if(new_report) { - json_string = json_tokener_parse(new_report); - json_object_array_add(json_array, json_string); - } - - msgout = (char *)json_object_to_json_string_ext(json_obj, JSON_C_TO_STRING_PRETTY); - *report = strdup(msgout); - json_object_put(json_obj); -} - -int create_json_bulkdata_report(struct profile *profile, char **report) -{ - /* - * create json msg of current report - * parse failed reports list and add it to the report - * then add new report to the report - */ - char *msgout; - - profile->new_report = NULL; - if(strcmp(profile->json_encoding_report_format, "objecthierarchy") == 0) { - create_json_bulkdata_report_object_hierarchy(profile, &msgout); - } else if(strcmp(profile->json_encoding_report_format, "namevaluepair") == 0) { - create_json_bulkdata_report_name_value_pair(profile, &msgout); - } - - if(profile->nbre_of_retained_failed_reports != 0) { - if(profile->nbre_failed_reports >= profile->nbre_of_retained_failed_reports && profile->nbre_of_retained_failed_reports > 0) - add_failed_reports_to_report_json(profile, msgout, report, 1); - else - add_failed_reports_to_report_json(profile, msgout, report, 0); - } else { - create_report_json(msgout, report); - } - - append_string_to_string(msgout, &profile->new_report); - FREE(msgout); - return 0; -} - -int create_csv_bulkdata_report(struct profile *profile, char **report) -{ - /* - * create csv msg of current report - * parse failed reports list and add it to the report - */ - int i; - struct resultsnode *p; - char *str1 = NULL, *str2 = NULL, *str = NULL, *paramprofilename, *timestamp = NULL, *type = NULL, rowseparator = '\0', separator = '\0'; - - if(strcmp(profile->csv_encoding_row_separator, " ") == 0) - rowseparator = '\n'; - else if(strcmp(profile->csv_encoding_row_separator, " ") == 0) - rowseparator = '\r'; - - if(profile->csv_encoding_field_separator) - separator = profile->csv_encoding_field_separator[0]; - - get_time_stamp(profile->csv_encoding_row_time_stamp, ×tamp); - /* - * Create header ReportTimestamp,ParameterName,ParameterValue,ParameterType in case of ParameterPerRow - */ - if(strcmp(profile->csv_encoding_report_format, "row") == 0) { - if(timestamp == NULL) - asprintf(&str, "ParameterName%cParameterValue%cParameterType%c", separator, separator, rowseparator); - else - asprintf(&str, "ReportTimestamp%cParameterName%cParameterValue%cParameterType%c", separator, separator, separator, rowseparator); - append_string_to_string(str, report); - FREE(str); - if(profile->nbre_of_retained_failed_reports != 0) { - if(profile->nbre_failed_reports >= profile->nbre_of_retained_failed_reports && profile->nbre_of_retained_failed_reports > 0) - add_failed_reports_to_report_csv(profile, report, 1); - else - add_failed_reports_to_report_csv(profile, report, 0); - } - } - if(strcmp(profile->csv_encoding_report_format, "column") == 0 && timestamp != NULL) { - if(profile->nbre_of_retained_failed_reports != 0) { - if(profile->nbre_failed_reports >= profile->nbre_of_retained_failed_reports && profile->nbre_of_retained_failed_reports > 0) - add_failed_reports_to_report_csv(profile, report, 1); - else - add_failed_reports_to_report_csv(profile, report, 0); - } - append_string_to_string("ReportTimestamp", &str1); - append_string_to_string(timestamp, &str2); - } - - /* - * Add New reports - */ - profile->new_report = NULL; - for(i = 0; i < profile->profile_parameter_number; i++) { - LIST_HEAD(results_list); - bulkdata_get_value_results(profile->profile_parameter[i].reference, &results_list); - list_for_each_entry(p, &results_list, list) { - paramprofilename = get_bulkdata_profile_parameter_name(profile->profile_parameter[i].reference, profile->profile_parameter[i].name, p->name); - if(strcmp(profile->csv_encoding_report_format, "row") == 0) { - type = strstr(p->type, ":"); - if(timestamp == NULL) - asprintf(&str, "%s%c%s%c%s%c", paramprofilename, separator, p->data, separator, type+1, rowseparator); - else - asprintf(&str, "%s%c%s%c%s%c%s%c", timestamp, separator, paramprofilename, separator, p->data, separator, type+1, rowseparator); - append_string_to_string(str, report); - append_string_to_string(str, &profile->new_report); - FREE(str); - } else if(strcmp(profile->csv_encoding_report_format, "column") == 0) { - if(str1 == NULL || strlen(str1) <= 0) - asprintf(&str, "%s", paramprofilename); - else - asprintf(&str, "%c%s", separator, paramprofilename); - append_string_to_string(str, &str1); - FREE(str); - if(str2 == NULL || strlen(str2) <= 0) - asprintf(&str, "%s", p->data); - else - asprintf(&str, "%c%s", separator, p->data); - append_string_to_string(str, &str2); - FREE(str); - } - FREE(paramprofilename); - } - bulkdata_free_data_from_list(&results_list); - } - if(strcmp(profile->csv_encoding_report_format, "column") == 0) { - asprintf(&str, "%c", rowseparator); - append_string_to_string(str, &str1); - append_string_to_string(str, &str2); - append_string_to_string(str1, report); - append_string_to_string(str2, report); - append_string_to_string(str1, &profile->new_report); - append_string_to_string(str2, &profile->new_report); - } - FREE(str); - FREE(str1); - FREE(str2); - FREE(timestamp); - return 0; -} - -static void create_json_failed_report(struct profile *profile, char **report) -{ - add_failed_reports_to_report_json(profile, NULL, report, 0); -} - -static void create_csv_failed_report(struct profile *profile, char **report) -{ - char rowseparator = '\0', separator = '\0', *timestamp = NULL; - - if(strcmp(profile->csv_encoding_row_separator, " ") == 0) { - rowseparator = '\n'; - } else if(strcmp(profile->csv_encoding_row_separator, " ") == 0) { - rowseparator = '\r'; - } - - if(profile->csv_encoding_field_separator) - separator = profile->csv_encoding_field_separator[0]; - - get_time_stamp(profile->csv_encoding_row_time_stamp, ×tamp); - if(strcmp(profile->csv_encoding_report_format, "row") == 0) { - if(timestamp == NULL) - asprintf(report, "ParameterName%cParameterValue%cParameterType%c", separator, separator, rowseparator); - else - asprintf(report, "ReportTimestamp%cParameterName%cParameterValue%cParameterType%c", separator, separator, separator, rowseparator); - } - add_failed_reports_to_report_csv(profile, report, 0); -} - -void create_encoding_bulkdata_report(struct profile *profile, char **report) -{ - if(strcasecmp(profile->encoding_type, "json") == 0) { - create_json_bulkdata_report(profile, report); - } else if(strcasecmp(profile->encoding_type, "csv") == 0) { - create_csv_bulkdata_report(profile, report); - } -} - -void create_failed_report(struct profile *profile, char **report) -{ - if(strcasecmp(profile->encoding_type, "json") == 0) { - create_json_failed_report(profile, report); - } else if(strcasecmp(profile->encoding_type, "csv") == 0) { - create_csv_failed_report(profile, report); - } -} diff --git a/bulkdata/src/report.h b/bulkdata/src/report.h deleted file mode 100644 index e419224ef..000000000 --- a/bulkdata/src/report.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* Author: Omar Kallel -* -*/ - -#ifndef __REPORT_H_ -#define __REPORT_H_ - -#include -#include "common.h" -#include "times.h" -#include "config.h" - -void create_encoding_bulkdata_report(struct profile *profile, char **report); -void create_failed_report(struct profile *profile, char **report); - -#endif /* __REPORT_H_ */ diff --git a/bulkdata/src/times.c b/bulkdata/src/times.c deleted file mode 100644 index c8d00158d..000000000 --- a/bulkdata/src/times.c +++ /dev/null @@ -1,62 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* -*/ - -#include -#include -#include - -#include "times.h" - -const char *bulkdata_get_time(void) -{ - static char local_time[64]; - - time_t t_time = time(NULL); - struct tm *t_tm = localtime(&t_time); - if (t_tm == NULL) - return NULL; - - if (strftime(local_time, sizeof(local_time),"Date: %a, %d %b %Y %X%z GMT", t_tm) == 0) - return NULL; - - return local_time; -} - -void get_time_stamp(const char *format, char **timestamp) -{ - time_t now = time(NULL); - - if (strcmp(format, "unix") == 0) { - asprintf(timestamp, "%ld", now); - } else if (strcmp(format, "iso8601") == 0) { - char buf[32] = {0}; - struct tm *ts = localtime(&now); - strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%Z", ts); - asprintf(timestamp, "%s", buf); - } else - timestamp = NULL; -} - -unsigned int get_next_period(time_t time_reference, int reporting_interval) -{ - unsigned int next_period; - time_t now = time(NULL); - - if (now > time_reference) - next_period = reporting_interval - ((now - time_reference) % reporting_interval); - else - next_period = (time_reference - now) % reporting_interval; - - if (next_period == 0) - next_period = reporting_interval; - - return next_period; -} diff --git a/bulkdata/src/times.h b/bulkdata/src/times.h deleted file mode 100644 index 49e81a58c..000000000 --- a/bulkdata/src/times.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* -*/ - -#ifndef __TIMES_H -#define __TIMES_H - -const char *bulkdata_get_time(void); -void get_time_stamp(const char *format, char **timestamp); -unsigned int get_next_period(time_t time_reference, int reporting_interval); - -#endif /* __TIMES_H */ diff --git a/twamp/Makefile b/twamp/Makefile index 1513523f6..f259a9025 100755 --- a/twamp/Makefile +++ b/twamp/Makefile @@ -10,8 +10,18 @@ include $(TOPDIR)/rules.mk PKG_NAME:=twamp PKG_VERSION:=1.0.0 +PKG_SOURCE_VERSION:=f6e914508aa1f7458f87bd68026f56262595d9a5 +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/twamp.git + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz +PKG_MIRROR_HASH:=skip +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_LICENSE:=GPL-2.0-only +PKG_LICENSE_FILES:=LICENSE + include $(INCLUDE_DIR)/package.mk define Package/$(PKG_NAME) @@ -26,10 +36,6 @@ define Package/$(PKG_NAME)/description BBF twamp feature endef -define Build/Prepare - $(CP) ./src/* $(PKG_BUILD_DIR)/ -endef - TARGET_CFLAGS += \ -D_GNU_SOURCE @@ -41,4 +47,4 @@ define Package/$(PKG_NAME)/install $(CP) ./files/* $(1)/ endef -$(eval $(call BuildPackage,$(PKG_NAME))) \ No newline at end of file +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/twamp/src/Makefile b/twamp/src/Makefile deleted file mode 100644 index 85f55c577..000000000 --- a/twamp/src/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -PROG = twampd -LIB = libtwamp.so - -PROG_OBJS = twamp.o twamplog.o twampuci.o twamptimestamp.o -LIB_OBJS = datamodel.o - -PROG_CFLAGS = $(CFLAGS) -Wall -Werror -fPIC -PROG_LDFLAGS = $(LDFLAGS) -luci -LIB_LDFLAGS = $(LDFLAGS) -lbbf_api - -%.o: %.c - $(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $< - -all: $(PROG) $(LIB) - -$(PROG): $(PROG_OBJS) - $(CC) $(PROG_CFLAGS) -o $@ $^ $(PROG_LDFLAGS) - -$(LIB): $(LIB_OBJS) - $(CC) $(PROG_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^ - -clean: - rm -f *.o $(PROG) $(LIB) diff --git a/twamp/src/datamodel.c b/twamp/src/datamodel.c deleted file mode 100644 index 8298337c3..000000000 --- a/twamp/src/datamodel.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (C) 2020 iopsys Software Solutions AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * Author: Amin Ben Ramdhane - */ - -#include -#include -#include -#include -#include - -#include "datamodel.h" - -/* ********** DynamicObj ********** */ -DM_MAP_OBJ tDynamicObj[] = { -/* parentobj, nextobject, parameter */ -{"Device.IP.Interface.{i}.", tDeviceTWAMPReflectorObj, NULL}, -{0} -}; - -static char *get_last_instance_with_option(char *package, char *section, char *option, char *val, char *opt_inst) -{ - struct uci_section *s; - char *inst = NULL; - - uci_foreach_option_eq(package, section, option, val, s) { - inst = update_instance(inst, 2, s, opt_inst); - } - return inst; -} - -static char *get_last_id(char *package, char *section) -{ - struct uci_section *s; - char *id; - int cnt = 0; - - uci_foreach_sections(package, section, s) { - cnt++; - } - dmasprintf(&id, "%d", cnt+1); - return id; -} - -static int addObjIPInterfaceTWAMPReflector(char *refparam, struct dmctx *ctx, void *data, char **instance) -{ - struct uci_section *connection = NULL; - - char *last_inst = get_last_instance_with_option("twamp", "twamp_reflector", "interface", section_name((struct uci_section *)data), "twamp_inst"); - char *id = get_last_id("twamp", "twamp_reflector"); - - dmuci_add_section("twamp", "twamp_reflector", &connection); - dmasprintf(instance, "%d", last_inst ? atoi(last_inst)+1 : 1); - dmuci_set_value_by_section(connection, "twamp_inst", *instance); - dmuci_set_value_by_section(connection, "id", id); - dmuci_set_value_by_section(connection, "enable", "0"); - dmuci_set_value_by_section(connection, "interface", section_name((struct uci_section *)data)); - dmuci_set_value_by_section(connection, "port", "862"); - dmuci_set_value_by_section(connection, "max_ttl", "1"); - return 0; -} - -static int delObjIPInterfaceTWAMPReflector(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) -{ - int found = 0; - struct uci_section *s, *ss = NULL; - char *interface; - - switch (del_action) { - case DEL_INST: - dmuci_delete_by_section((struct uci_section *)data, NULL, NULL); - return 0; - case DEL_ALL: - uci_foreach_sections("twamp", "twamp_reflector", s) { - dmuci_get_value_by_section_string(s, "interface", &interface); - if (strcmp(interface, section_name((struct uci_section *)data)) != 0) - continue; - if (found != 0) { - dmuci_delete_by_section(ss, NULL, NULL); - } - ss = s; - found++; - } - if (ss != NULL) { - dmuci_delete_by_section(ss, NULL, NULL); - } - return 0; - } - return 0; -} - -static int get_IPInterfaceTWAMPReflector_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = dmuci_get_value_by_section_fallback_def((struct uci_section *)data, "enable", "1"); - return 0; -} - -static int set_IPInterfaceTWAMPReflector_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - bool b; - struct uci_section *s; - char *interface, *device, *id, *ipv4addr = ""; - json_object *res, *jobj; - - switch (action) { - case VALUECHECK: - if (dm_validate_boolean(value)) - return FAULT_9007; - break; - case VALUESET: - string_to_bool(value, &b); - if(b) { - dmuci_get_value_by_section_string((struct uci_section *)data, "interface", &interface); - dmuci_get_value_by_section_string((struct uci_section *)data, "id", &id); - dmuci_set_value_by_section((struct uci_section *)data, "enable", "1"); - dmuci_set_value("twamp", "twamp", "id", id); - uci_foreach_sections("network", "interface", s) { - if(strcmp(section_name(s), interface) != 0) - continue; - dmuci_get_value_by_section_string(s, "ipaddr", &ipv4addr); - break; - } - if (ipv4addr[0] == '\0') { - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", interface, String}}, 1, &res); - if (res) { - jobj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv4-address"); - ipv4addr = dmjson_get_value(jobj, 1, "address"); - if (ipv4addr[0] == '\0') - dmuci_set_value_by_section((struct uci_section *)data, "ip_version", "6"); - else - dmuci_set_value_by_section((struct uci_section *)data, "ip_version", "4"); - } - } else - dmuci_set_value_by_section((struct uci_section *)data, "ip_version", "4"); - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", interface, String}}, 1, &res); - if (res) { - device = dmjson_get_value(res, 1, "device"); - dmuci_set_value_by_section((struct uci_section *)data, "device", device); - } - dmuci_set_value_by_section((struct uci_section *)data, "device", get_device(interface)); - } else { - dmuci_set_value_by_section((struct uci_section *)data, "enable", "0"); - } - break; - } - return 0; -} - -static int get_IPInterfaceTWAMPReflector_Status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - char *enable; - - dmuci_get_value_by_section_string((struct uci_section *)data, "enable", &enable); - if (strcmp(enable, "1") == 0) - *value = "Active"; - else - *value = "Disabled"; - return 0; -} - -static int get_IPInterfaceTWAMPReflector_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "twamp_alias", value); - if ((*value)[0] == '\0') - dmasprintf(value, "cpe-%s", instance); - return 0; -} - -static int set_IPInterfaceTWAMPReflector_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, 64, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "twamp_alias", value); - break; - } - return 0; -} - -static int get_IPInterfaceTWAMPReflector_Port(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = dmuci_get_value_by_section_fallback_def((struct uci_section *)data, "port", "862"); - return 0; -} - -static int set_IPInterfaceTWAMPReflector_Port(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_unsignedInt(value, RANGE_ARGS{{NULL,"65535"}}, 1)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "port", value); - break; - } - return 0; -} - -static int get_IPInterfaceTWAMPReflector_MaximumTTL(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = dmuci_get_value_by_section_fallback_def((struct uci_section *)data, "max_ttl", "1"); - return 0; -} - -static int set_IPInterfaceTWAMPReflector_MaximumTTL(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_unsignedInt(value, RANGE_ARGS{{"1","255"}}, 1)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "max_ttl", value); - break; - } - return 0; -} - -static int get_IPInterfaceTWAMPReflector_IPAllowedList(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "ip_list", value); - return 0; -} - -static int set_IPInterfaceTWAMPReflector_IPAllowedList(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string_list(value, -1, -1, 255, -1, -1, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "ip_list", value); - break; - } - return 0; -} - -static int get_IPInterfaceTWAMPReflector_PortAllowedList(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string((struct uci_section *)data, "port_list", value); - return 0; -} - -static int set_IPInterfaceTWAMPReflector_PortAllowedList(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string_list(value, -1, -1, 255, -1, -1, NULL, NULL)) - return FAULT_9007; - break; - case VALUESET: - dmuci_set_value_by_section((struct uci_section *)data, "port_list", value); - break; - } - return 0; -} - -static int browseIPInterfaceTWAMPReflectorInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - struct uci_section *s = NULL; - char *inst = NULL, *max_inst = NULL; - - uci_foreach_option_eq("twamp", "twamp_reflector", "interface", section_name((struct uci_section *)prev_data), s) { - - inst = handle_update_instance(2, dmctx, &max_inst, update_instance_alias, 3, - s, "twamp_inst", "twamp_alias"); - - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)s, inst) == DM_STOP) - break; - } - return 0; -} - -/* *** Device.IP.Interface.{i}. *** */ -DMOBJ tDeviceTWAMPReflectorObj[] = { -/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ -{"TWAMPReflector", &DMWRITE, addObjIPInterfaceTWAMPReflector, delObjIPInterfaceTWAMPReflector, NULL, browseIPInterfaceTWAMPReflectorInst, NULL, NULL, NULL, tIPInterfaceTWAMPReflectorParams, NULL, BBFDM_BOTH, LIST_KEY{"Alias", "Port", NULL}}, -{0} -}; - -/* *** Device.IP.Interface.{i}.TWAMPReflector.{i}. *** */ -DMLEAF tIPInterfaceTWAMPReflectorParams[] = { -/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ -{"Enable", &DMWRITE, DMT_BOOL, get_IPInterfaceTWAMPReflector_Enable, set_IPInterfaceTWAMPReflector_Enable, BBFDM_BOTH}, -{"Status", &DMREAD, DMT_STRING, get_IPInterfaceTWAMPReflector_Status, NULL, BBFDM_BOTH}, -{"Alias", &DMWRITE, DMT_STRING, get_IPInterfaceTWAMPReflector_Alias, set_IPInterfaceTWAMPReflector_Alias, BBFDM_BOTH}, -{"Port", &DMWRITE, DMT_UNINT, get_IPInterfaceTWAMPReflector_Port, set_IPInterfaceTWAMPReflector_Port, BBFDM_BOTH}, -{"MaximumTTL", &DMWRITE, DMT_UNINT, get_IPInterfaceTWAMPReflector_MaximumTTL, set_IPInterfaceTWAMPReflector_MaximumTTL, BBFDM_BOTH}, -{"IPAllowedList", &DMWRITE, DMT_STRING, get_IPInterfaceTWAMPReflector_IPAllowedList, set_IPInterfaceTWAMPReflector_IPAllowedList, BBFDM_BOTH}, -{"PortAllowedList", &DMWRITE, DMT_STRING, get_IPInterfaceTWAMPReflector_PortAllowedList, set_IPInterfaceTWAMPReflector_PortAllowedList, BBFDM_BOTH}, -{0} -}; diff --git a/twamp/src/datamodel.h b/twamp/src/datamodel.h deleted file mode 100644 index baeb08f22..000000000 --- a/twamp/src/datamodel.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2020 iopsys Software Solutions AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * Author: Amin Ben Ramdhane - */ - -#ifndef _TWAMP_H_ -#define _TWAMP_H_ - -extern DMOBJ tDeviceTWAMPReflectorObj[]; -extern DMLEAF tIPInterfaceTWAMPReflectorParams[]; - -#endif //_TWAMP_H_ diff --git a/twamp/src/twamp.c b/twamp/src/twamp.c deleted file mode 100644 index 7e05bbcf9..000000000 --- a/twamp/src/twamp.c +++ /dev/null @@ -1,858 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* -* Name: Emma Mirică -* Project: TWAMP Protocol -* Class: OSS -* Email: emma.mirica@cti.pub.ro -* Contributions: stephanDB -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "twamp.h" -#include "twamplog.h" -#include "twampuci.h" - -struct twamp_config cur_twamp_conf = {0}; -TWAMPTimestamp ZeroT = { 0, 0 }; - -struct active_session { - int socket; - RequestSession req; - uint16_t server_oct; - uint32_t sid_addr; - TWAMPTimestamp sid_time; - uint32_t sid_rand; - uint32_t seq_nb; - uint32_t snd_nb; - uint32_t fw_msg; - uint32_t fw_lst_msg; -}; - -struct client_info { - ClientStatus status; - int socket; - struct sockaddr_in addr; - struct sockaddr_in6 addr6; - int mode; - int sess_no; - struct timeval shutdown_time; - struct active_session sessions[MAX_SESSIONS_PER_CLIENT]; -}; - -static int fd_max = 0; -static enum Mode authmode = kModeUnauthenticated; -static int used_sockets = 0; -static fd_set read_fds; -static int socket_family = AF_INET; - -static int check_ipv4_address(char *ip, char *maskstr, char *address) -{ - struct sockaddr_in sa = {0}; - unsigned long netaddress, maxaddress; - unsigned long mask = ~((1 << (32 - atoi(maskstr))) - 1); - inet_pton(AF_INET, address, &(sa.sin_addr)); - netaddress = (ntohl(sa.sin_addr.s_addr) & mask); - sa.sin_addr.s_addr = 0; - inet_pton(AF_INET, ip, &(sa.sin_addr)); - maxaddress = (ntohl(sa.sin_addr.s_addr) & mask); - if (maxaddress == netaddress) - return 1; - return 0; -} - -static char *check_ipv6_address_active(char *ip) -{ - unsigned char buf[sizeof(struct in6_addr)]; - char str[INET6_ADDRSTRLEN], *res; - int s; - - s = inet_pton(AF_INET6, ip, buf); - if (s <= 0) { - if (s == 0) - twamp_log(SCRIT, "Not in presentation format"); - else - twamp_log(SCRIT, "inet_pton"); - return ""; - } - if (inet_ntop(AF_INET6, buf, str, INET6_ADDRSTRLEN) == NULL) { - twamp_log(SCRIT, "inet_ntop"); - return ""; - } - res = strdup(str); - return res; -} - -static int check_ipv6_address(char *ip, char *maskstr, char *address) -{ - struct sockaddr_in6 sa = {0}; - unsigned long netaddress, maxaddress; - unsigned long mask = ~((1 << (128 - atoi(maskstr))) - 1); - inet_pton(AF_INET6, address, &(sa.sin6_addr)); - netaddress = (ntohl((uint32_t)sa.sin6_addr.s6_addr) & mask); - inet_pton(AF_INET6, ip, &(sa.sin6_addr)); - maxaddress = (ntohl((uint32_t)sa.sin6_addr.s6_addr) & mask); - if (maxaddress == netaddress) - return 1; - return 0; -} - -static int check_ip_address_allowed(char *address) -{ - char *pch, *spch, *ip, *mask, *str, *addr; - - for (pch = strtok_r(cur_twamp_conf.ip_list, ",", &spch); pch != NULL; pch = strtok_r(NULL, ",", &spch)) - { - if(strstr(pch, ".")) { - if(strstr(pch, "/")) { - ip = strtok_r(pch, "/", &str); - mask = strtok_r(NULL, "", &str); - if(check_ipv4_address(ip, mask, address)) - return 1; - continue; - } - if (strcmp(pch, address) == 0) - return 1; - } else { - addr = check_ipv6_address_active(address); - if(strstr(pch, "/")) { - ip = strtok_r(pch, "/", &str); - mask = strtok_r(NULL, "", &str); - ip = check_ipv6_address_active(ip); - if(check_ipv6_address(ip, mask, addr)) - return 1; - continue; - } - pch = check_ipv6_address_active(pch); - if (strcmp(pch, addr) == 0) - return 1; - } - } - return 0; -} - -static int check_port_allowed(int port) -{ - char *pch, *spch, *min, *max, *str; - - for (pch = strtok_r(cur_twamp_conf.port_list, ",", &spch); pch != NULL; pch = strtok_r(NULL, ",", &spch)) - { - if(strstr(pch, "-")) { - min = strtok_r(pch, "-", &str); - max = strtok_r(NULL, "", &str); - if(port >= atoi(min) && port <= atoi(max)) - return 1; - continue; - } - if (port == atoi(pch)) - return 1; - } - return 0; -} - -/* The cleanup_client function will close every connection (TWAMP-Control ot TWAMP-Test that this server has with the client defined by the client_infor - * structure received as a parameter. - */ -static void cleanup_client(struct client_info *client) -{ - char str_client[INET6_ADDRSTRLEN]; - inet_ntop(socket_family, (socket_family == AF_INET6) ? (void*) &(client->addr6.sin6_addr) : (void*) &(client->addr.sin_addr), str_client, sizeof(str_client)); - twamp_log(SINFO, "Cleanup client %s", str_client); - FD_CLR(client->socket, &read_fds); - close(client->socket); - used_sockets--; - int i; - for (i = 0; i < client->sess_no; i++) - /* If socket is -1 the session has already been closed */ - if (client->sessions[i].socket > 0) { - FD_CLR(client->sessions[i].socket, &read_fds); - close(client->sessions[i].socket); - client->sessions[i].socket = -1; - used_sockets--; - } - memset(client, 0, sizeof(struct client_info)); - client->status = kOffline; -} - -/* The TWAMP server can only accept max_clients and it will recycle the positions for the available clients. */ -static int find_empty_client(struct client_info *clients, int max_clients) -{ - int i; - for (i = 0; i < max_clients; i++) - if (clients[i].status == kOffline) - return i; - return -1; -} - -/* Sends a ServerGreeting message to the Control-Client after the TCP connection has been established. */ -static int send_greeting(uint16_t mode_mask, struct client_info *client) -{ - int socket = client->socket; - - char str_client[INET6_ADDRSTRLEN]; /* String for Client IP address */ - inet_ntop(socket_family, (socket_family == AF_INET6) ? (void*) &(client->addr6.sin6_addr) : (void*) &(client->addr.sin_addr), str_client, sizeof(str_client)); - - int i; - ServerGreeting greet; - memset(&greet, 0, sizeof(greet)); - greet.Modes = htonl(client->mode & mode_mask); - for (i = 0; i < 16; i++) - greet.Challenge[i] = rand() % 16; - for (i = 0; i < 16; i++) - greet.Salt[i] = rand() % 16; - greet.Count = htonl(1 << 10); - - int rv = send(socket, &greet, sizeof(greet), 0); - if (rv < 0) { - twamp_log(SCRIT,"Failed to send ServerGreeting message"); - cleanup_client(client); - } else if ((authmode & 0x000F) == 0) { - twamp_log(SCRIT,"Sent ServerGreeting message with Mode 0! Abort"); - cleanup_client(client); - } else { - twamp_log(SINFO,"Sent ServerGreeting message to %s", str_client); - } - return rv; -} - -/* After a ServerGreeting the Control-Client should respond with a SetUpResponse. This function treats this message */ -static int receive_greet_response(struct client_info *client) -{ - int socket = client->socket; - char str_client[INET6_ADDRSTRLEN]; /* String for Client IP address */ - inet_ntop(socket_family, (socket_family == AF_INET6)? (void*) &(client->addr6.sin6_addr) : (void*) &(client->addr.sin_addr), str_client, sizeof(str_client)); - - SetUpResponse resp; - memset(&resp, 0, sizeof(resp)); - int rv = recv(socket, &resp, sizeof(resp), 0); - if (rv <= 32) { - twamp_log(SCRIT,"Failed to receive SetUpResponse"); - cleanup_client(client); - } else { - twamp_log(SINFO, "Received SetUpResponse message from %s with mode %d", str_client, ntohl(resp.Mode)); - if ((ntohl(resp.Mode) & client->mode & 0x000F) == 0) { - twamp_log(SCRIT,"The client does not support any usable Mode"); - rv = 0; - } - client->mode = ntohl(resp.Mode); - } - return rv; -} - -/* Sent a ServerStart message to the Control-Client to endthe TWAMP-Control session establishment phase */ -static int send_start_serv(struct client_info *client, TWAMPTimestamp StartTime) -{ - int socket = client->socket; - - char str_client[INET6_ADDRSTRLEN]; - inet_ntop(socket_family, (socket_family == AF_INET6)? (void*) &(client->addr6.sin6_addr) : (void*) &(client->addr.sin_addr), str_client, sizeof(str_client)); - - ServerStart msg; - memset(&msg, 0, sizeof(msg)); - if ((StartTime.integer == 0) && (StartTime.fractional == 0)) { - msg.Accept = kAspectNotSupported; - } else { - msg.Accept = kOK; - } - msg.StartTime = StartTime; - int rv = send(socket, &msg, sizeof(msg), 0); - if (rv <= 0) { - twamp_log(SCRIT,"Failed to send ServerStart message"); - cleanup_client(client); - } else { - client->status = kConfigured; - twamp_log(SINFO, "ServerStart message sent to %s", str_client); - if (msg.Accept == kAspectNotSupported) { - cleanup_client(client); - } - } - return rv; -} - -/* Sends a StartACK for the StartSessions message */ -static int send_start_ack(struct client_info *client) -{ - char str_client[INET6_ADDRSTRLEN]; - inet_ntop(socket_family, (socket_family == AF_INET6)? (void*) &(client->addr6.sin6_addr) : (void*) &(client->addr.sin_addr), str_client, sizeof(str_client)); - StartACK ack; - memset(&ack, 0, sizeof(ack)); - ack.Accept = kOK; - int rv = send(client->socket, &ack, sizeof(ack), 0); - if (rv <= 0) { - twamp_log(SCRIT,"Failed to send StartACK message"); - } else - twamp_log(SINFO,"StartACK message sent to %s", str_client); - return rv; -} - -/* This function treats the case when a StartSessions is received from the Control-Client to start a number of TWAMP-Test sessions */ -static int receive_start_sessions(struct client_info *client) -{ - int i; - int rv = send_start_ack(client); - if (rv <= 0) - return rv; - - /* Now it can receive packets on the TWAMP-Test sockets */ - for (i = 0; i < client->sess_no; i++) { - FD_SET(client->sessions[i].socket, &read_fds); - if (fd_max < client->sessions[i].socket) - fd_max = client->sessions[i].socket; - } - client->status = kTesting; - return rv; -} - -/* This functions treats the case when a StopSessions is received from the Control-Client to end all the Test sessions. */ -static int receive_stop_sessions(struct client_info *client) -{ - /* If a StopSessions message was received, it can still receive Test packets until the timeout has expired */ - gettimeofday(&client->shutdown_time, NULL); - return 0; -} - -/* Computes the response to a RequestTWSession message */ -static int send_accept_session(struct client_info *client, RequestSession * req) -{ - char str_client[INET6_ADDRSTRLEN]; /* String for Client IP address */ - AcceptSession acc; - memset(&acc, 0, sizeof(acc)); - - inet_ntop(socket_family, (socket_family == AF_INET6)? (void*) &(client->addr6.sin6_addr) : (void*) &(client->addr.sin_addr), str_client, sizeof(str_client)); - - - /* Check if there are any slots available */ - if ((used_sockets < 64) && (client->sess_no < MAX_SESSIONS_PER_CLIENT)) { - int testfd = socket(socket_family, SOCK_DGRAM, 0); - if (testfd < 0) { - twamp_log(SCRIT,"Error opening socket"); - return -1; - } - - int check_time = CHECK_TIMES; - if(socket_family == AF_INET6) { - struct sockaddr_in6 local_addr; - memset(&local_addr, 0, sizeof(local_addr)); - local_addr.sin6_family = AF_INET6; - local_addr.sin6_addr = in6addr_any; - local_addr.sin6_port = req->ReceiverPort; - - while (check_time-- && bind(testfd, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) - local_addr.sin6_port = htons(20000 + rand() % 1000); - - if (check_time > 0) { - req->ReceiverPort = local_addr.sin6_port; - } - } else { - struct sockaddr_in local_addr; - memset(&local_addr, 0, sizeof(local_addr)); - local_addr.sin_family = AF_INET; - local_addr.sin_addr.s_addr = htonl(INADDR_ANY); - local_addr.sin_port = req->ReceiverPort; - - while (check_time-- && bind(testfd, (struct sockaddr *)&local_addr, sizeof(struct sockaddr)) < 0) - local_addr.sin_port = htons(20000 + rand() % 1000); - - if (check_time > 0) { - req->ReceiverPort = local_addr.sin_port; - } - } - - if (check_time > 0) { - acc.Accept = kOK; - acc.Port = req->ReceiverPort; - client->sessions[client->sess_no].socket = testfd; - client->sessions[client->sess_no].req = *req; - /* SID construction */ - memcpy(acc.SID, &req->ReceiverAddress, 4); - TWAMPTimestamp sidtime = get_timestamp(); - memcpy(&acc.SID[4], &sidtime, 8); - int k; - for (k = 0; k < 4; k++) - acc.SID[12 + k] = rand() % 256; - memcpy(&client->sessions[client->sess_no].sid_addr, &acc.SID, 4); - client->sessions[client->sess_no].sid_time = sidtime; - memcpy(&client->sessions[client->sess_no].sid_rand, &acc.SID[12], 4); - - twamp_log(SINFO, "SID: 0x%04X.%04X.%04X.%04X", - ntohl(client->sessions[client->sess_no].sid_addr), - ntohl(client->sessions[client->sess_no].sid_time.integer), - ntohl(client->sessions[client->sess_no].sid_time.fractional), - ntohl(client->sessions[client->sess_no].sid_rand)); - - /* Set socket options */ - set_socket_option(testfd, cur_twamp_conf.max_ttl); - set_socket_tos(testfd, (client->sessions[client->sess_no].req.TypePDescriptor << 2)); - - client->sess_no++; - - } else { - twamp_log(SINFO, "kTemporaryResourceLimitation: check_time [%d]", check_time); - acc.Accept = kTemporaryResourceLimitation; - acc.Port = 0; - } - - } else { - twamp_log(SINFO, "kTemporaryResourceLimitation: used_sockets [%d], sess_no [%d]", used_sockets, client->sess_no); - acc.Accept = kTemporaryResourceLimitation; - acc.Port = 0; - } - - int rv = send(client->socket, &acc, sizeof(acc), 0); - return rv; -} - -/* This function treats the case when a RequestTWSession is received */ -static int receive_request_session(struct client_info *client, RequestSession * req) -{ - char str_client[INET6_ADDRSTRLEN]; /* String for Client IP address */ - - if(socket_family == AF_INET6) { - inet_ntop(AF_INET6, &(client->addr6.sin6_addr), str_client, sizeof(str_client)); - twamp_log(SINFO, "Server received RequestTWSession message"); - } else { - char str_server[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &(client->addr.sin_addr), str_client, INET_ADDRSTRLEN); - struct in_addr se_addr; - se_addr.s_addr = req->ReceiverAddress; - inet_ntop(AF_INET, &(se_addr), str_server, INET_ADDRSTRLEN); - twamp_log(SINFO, "Server %s received RequestTWSession message with port %d", str_server, ntohs(req->ReceiverPort)); - } - /* Check port test packets if its allowed by PortAllowedList parameter */ - if(cur_twamp_conf.port_list[0] != '\0') { - if(!check_port_allowed(ntohs(req->ReceiverPort))) { - twamp_log(SINFO, "Port %d is not allowed", ntohs(req->ReceiverPort)); - return -1; - } - } - - int rv = send_accept_session(client, req); - if (rv <= 0) { - twamp_log(SCRIT,"Failed to send the Accept-Session message"); - } - return rv; -} - -/* This function will receive a TWAMP-Test packet and will send a response. In TWAMP the Session-Sender (in our case the Control-Client, meaning the - * TWAMP-Client) is always sending TWAMP-Test packets and the Session-Reflector (Server) is receiving TWAMP-Test packets. - */ -static int receive_test_message(struct client_info *client, int session_index) -{ - struct sockaddr_in addr; - struct sockaddr_in6 addr6; - socklen_t len = sizeof(addr); - char str_client[INET6_ADDRSTRLEN]; - - inet_ntop(socket_family, (socket_family == AF_INET6)? (void*) &(client->addr6.sin6_addr) : (void*) &(client->addr.sin_addr), str_client, sizeof(str_client)); - - ReflectorUPacket pack_reflect; - memset(&pack_reflect, 0, sizeof(pack_reflect)); - - SenderUPacket pack; - memset(&pack, 0, sizeof(pack)); - - /* New for recvmsg */ - struct msghdr *message = malloc(sizeof(struct msghdr)); - struct cmsghdr *c_msg; - char *control_buffer = malloc(TST_PKT_SIZE); - uint16_t control_length = TST_PKT_SIZE; - - memset(message, 0, sizeof(*message)); - message->msg_name = (socket_family == AF_INET6)? (void*)&addr6: (void*)&addr; - message->msg_namelen = len; - message->msg_iov = malloc(sizeof(struct iovec)); - message->msg_iov->iov_base = &pack; - message->msg_iov->iov_len = TST_PKT_SIZE; - message->msg_iovlen = 1; - message->msg_control = control_buffer; - message->msg_controllen = control_length; - - int rv = recvmsg(client->sessions[session_index].socket, message, 0); - pack_reflect.receive_time = get_timestamp(); - - char str_server[INET6_ADDRSTRLEN]; /* String for Client IP address */ - - inet_ntop(socket_family, (socket_family == AF_INET6)? (void*) &(addr6.sin6_addr) : (void*) &(addr.sin_addr), str_server, sizeof(str_server)); - if (rv <= 0) { - twamp_log(SCRIT,"Failed to receive TWAMP-Test packet"); - return rv; - } else if (rv < 14) { - twamp_log(SCRIT,"Short TWAMP-Test packet"); - return rv; - } - - /* Get TTL/TOS values from IP header */ - uint8_t fw_ttl = 0; - uint8_t fw_tos = 0; - - for (c_msg = CMSG_FIRSTHDR(message); c_msg; c_msg = (CMSG_NXTHDR(message, c_msg))) { - if ((c_msg->cmsg_level == IPPROTO_IP && c_msg->cmsg_type == IP_TTL) || (c_msg->cmsg_level == IPPROTO_IPV6 && c_msg->cmsg_type == IPV6_HOPLIMIT)) { - fw_ttl = *(int *)CMSG_DATA(c_msg); - } else if (c_msg->cmsg_level == IPPROTO_IP && c_msg->cmsg_type == IP_TOS) { - fw_tos = *(int *)CMSG_DATA(c_msg); - } else { - twamp_log(SINFO, "Warning, unexpected data of level %i and type %i", c_msg->cmsg_level, c_msg->cmsg_type); - } - } - - twamp_log(SINFO, "Received TWAMP-Test message from %s", inet_ntoa(addr.sin_addr)); - pack_reflect.seq_number = htonl(client->sessions[session_index].seq_nb++); - pack_reflect.error_estimate = htons(0x8001); // Sync = 1, Multiplier = 1 - pack_reflect.sender_seq_number = pack.seq_number; - pack_reflect.sender_time = pack.time; - pack_reflect.sender_error_estimate = pack.error_estimate; - pack_reflect.sender_ttl = fw_ttl; // Copy from the IP header packet from Sender - if ((client->mode & kModeDSCPECN) == kModeDSCPECN) { - pack_reflect.sender_tos = fw_tos; // Copy from the IP header packet from Sender - } - - if(socket_family == AF_INET6) { - addr.sin_port = client->sessions[session_index].req.SenderPort; - } else { - addr6.sin6_port = client->sessions[session_index].req.SenderPort; - } - /* FW Loss Calculation */ - - if (client->sessions[session_index].fw_msg == 0) { - client->sessions[session_index].fw_msg = 1; - /* Response packet for TOS with ECN */ - if ((fw_tos & 0x03) > 0) { - uint8_t ecn_tos = (fw_tos & 0x03) - (((fw_tos & 0x2) >> 1) & (fw_tos & 0x1)); - set_socket_tos(client->sessions[session_index].socket, (client->sessions[session_index].req.TypePDescriptor << 2) + ecn_tos); - } - } else { - client->sessions[session_index].fw_msg = client->sessions[session_index].fw_msg + ntohl(pack.seq_number) - client->sessions[session_index].snd_nb; - client->sessions[session_index].fw_lst_msg = client->sessions[session_index].fw_lst_msg + ntohl(pack.seq_number) - client->sessions[session_index].snd_nb - 1; - } - client->sessions[session_index].snd_nb = ntohl(pack.seq_number); - - /* Response packet */ - pack_reflect.time = get_timestamp(); - - if(socket_family == AF_INET6) { - if (rv < 41) { - rv = sendto(client->sessions[session_index].socket, &pack_reflect, 41, 0, (struct sockaddr *)&addr6, sizeof(addr6)); - } else { - rv = sendto(client->sessions[session_index].socket, &pack_reflect, rv, 0, (struct sockaddr *)&addr6, sizeof(addr6)); - } - } else { - if (rv < 41) { - rv = sendto(client->sessions[session_index].socket, &pack_reflect, 41, 0, (struct sockaddr *)&addr, sizeof(addr)); - } else { - rv = sendto(client->sessions[session_index].socket, &pack_reflect, rv, 0, (struct sockaddr *)&addr, sizeof(addr)); - } - } - - if (rv <= 0) { - twamp_log(SCRIT,"Failed to send TWAMP-Test packet"); - } - - /* Print the FW metrics */ - print_metrics_server(str_client, socket_family == AF_INET6 ? ntohs(addr6.sin6_port): ntohs(addr.sin_port), ntohs(client->sessions[session_index].req.ReceiverPort), (client->sessions[session_index].req.TypePDescriptor << 2), fw_tos, &pack_reflect); - - if ((client->sessions[session_index].fw_msg % 10) == 0) { - twamp_log(SINFO,"FW Lost packets: %u/%u", client->sessions[session_index].fw_lst_msg, client->sessions[session_index].fw_msg); - twamp_log(SINFO,"FW Loss Ratio: %3.2f%%", (float)100 * client->sessions[session_index].fw_lst_msg / client->sessions[session_index].fw_msg); - //printf("FW Lost packets: %u/%u, FW Loss Ratio: %3.2f%%\n", client->sessions[session_index].fw_lst_msg, client->sessions[session_index].fw_msg, (float)100 * client->sessions[session_index].fw_lst_msg / client->sessions[session_index].fw_msg); - } - return rv; -} - -int twamp_connect(void) -{ - int listenfd, newsockfd; - struct client_info clients[MAX_CLIENTS]; - struct sockaddr_in client_addr; - struct sockaddr_in6 client_addr6; - int rv; - - /* Obtain start server time in TWAMP format */ - TWAMPTimestamp StartTime = get_timestamp(); - - if(cur_twamp_conf.ip_version == 4) - socket_family = AF_INET; - else - socket_family = AF_INET6; - - listenfd = socket(socket_family, SOCK_STREAM, 0); - if (listenfd < 0) { - twamp_log(SCRIT,"Error opening socket"); - return -1; - } - - int ret = setsockopt(listenfd, SOL_SOCKET, SO_BINDTODEVICE, cur_twamp_conf.device, strlen(cur_twamp_conf.device)+1); - if(ret) { - twamp_log(SCRIT,"Error on setsockopt with ret %d", ret); - return -1; - } - - if(socket_family == AF_INET6) { - /* Set Server address and bind on the TWAMP port */ - struct sockaddr_in6 serv_addr; - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin6_family = AF_INET6; - serv_addr.sin6_addr = in6addr_any; - serv_addr.sin6_port = htons(cur_twamp_conf.port); - - if (bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { - twamp_log(SCRIT,"Error on binding"); - return -1; - } - } else { - /* Set Server address and bind on the TWAMP port */ - struct sockaddr_in serv_addr; - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); - serv_addr.sin_port = htons(cur_twamp_conf.port); - - if (bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) < 0) { - twamp_log(SCRIT,"Error on binding"); - return -1; - } - } - - used_sockets++; - - /* Start listening on the TWAMP port for new TWAMP-Control connections */ - if (listen(listenfd, MAX_CLIENTS)) { - twamp_log(SCRIT,"Error on listen"); - return -1; - } - - FD_ZERO(&read_fds); - FD_SET(listenfd, &read_fds); - fd_max = listenfd; - - memset(clients, 0, MAX_CLIENTS * sizeof(struct client_info)); - fd_set tmp_fds; - FD_ZERO(&tmp_fds); - - while (1) { - tmp_fds = read_fds; - if (select(fd_max + 1, &tmp_fds, NULL, NULL, NULL) < 0) { - twamp_log(SCRIT,"Error in select"); - close(listenfd); - return -1; - } - - /* If an event happened on the listenfd, then a new TWAMP-Control connection is received */ - if (FD_ISSET(listenfd, &tmp_fds)) { - uint32_t client_len = (socket_family == AF_INET6)? sizeof(client_addr6) : sizeof(client_addr); - if ((newsockfd = accept(listenfd, (socket_family == AF_INET6) ? (struct sockaddr *)&client_addr6 : (struct sockaddr *)&client_addr, &client_len)) < 0) { - twamp_log(SCRIT,"Error in accept"); - } else { - /* Add a new client if there are any slots available */ - int pos = find_empty_client(clients, MAX_CLIENTS); - uint16_t mode_mask = 0; - if (pos != -1) { - clients[pos].status = kConnected; - clients[pos].socket = newsockfd; - clients[pos].addr = client_addr; - clients[pos].addr6 = client_addr6; - clients[pos].mode = authmode; - clients[pos].sess_no = 0; - used_sockets++; - FD_SET(newsockfd, &read_fds); - if (newsockfd > fd_max) - fd_max = newsockfd; - mode_mask = 0x01FF; - } - - char str_client[INET6_ADDRSTRLEN]; /* String for Client IP address */ - inet_ntop(socket_family, (socket_family == AF_INET6) ? (void*) &(clients[pos].addr6.sin6_addr) : (void*) &(clients[pos].addr.sin_addr), str_client, sizeof(str_client)); - twamp_log(SINFO,"Receive a TCP connection from %s", str_client); - /* Check ip test packets if its allowed by IPAllowedList parameter */ - if(cur_twamp_conf.ip_list[0] != '\0') { - if(!check_ip_address_allowed(str_client)) { - twamp_log(SINFO, "IP Address %d is not allowed", str_client); - close(listenfd); - return -1; - } - } - rv = send_greeting(mode_mask, &clients[pos]); - } - } - - /* Receives other packets from the established TWAMP-Control sessions */ - uint8_t buffer[4096]; - int i, j; - for (i = 0; i < MAX_CLIENTS; i++) - /* It can only receive TWAMP-Control messages from Online clients */ - if (clients[i].status != kOffline) - if (FD_ISSET(clients[i].socket, &tmp_fds)) { - switch (clients[i].status) { - case kConnected: - /* If a TCP session has been established and a ServerGreeting has been sent, wait for the SetUpResponse and finish the TWAMP-Control setup */ - rv = receive_greet_response(&clients[i]); - if (rv > 32) { - rv = send_start_serv(&clients[i], StartTime); - } else { - rv = send_start_serv(&clients[i], ZeroT); - } - break; - case kConfigured: - /* Reset the buffer to receive a new message */ - memset(buffer, 0, 4096); - rv = recv(clients[i].socket, buffer, 4096, 0); - if (rv <= 0) { - cleanup_client(&clients[i]); - break; - } - /* Check the message received: It can only be StartSessions or RequestTWSession */ - switch (buffer[0]) { - case kStartSessions: - rv = receive_start_sessions(&clients[i]); - break; - case kRequestTWSession: - rv = receive_request_session(&clients[i], (RequestSession *) buffer); - break; - default: - break; - } - - if (rv <= 0) - cleanup_client(&clients[i]); - break; - case kTesting: - /* In this state can only receive a StopSessions msg */ - memset(buffer, 0, 4096); - rv = recv(clients[i].socket, buffer, 4096, 0); - if (rv <= 0) { - cleanup_client(&clients[i]); - break; - } - if (buffer[0] == kStopSessions) { - rv = receive_stop_sessions(&clients[i]); - } - break; - default: - break; - } - } - - /* Check for TWAMP-Test packets */ - for (i = 0; i < MAX_CLIENTS; i++) { - struct timeval current; - gettimeofday(¤t, NULL); - - if (clients[i].status == kTesting) { - uint8_t has_active_test_sessions = 0; - for (j = 0; j < clients[i].sess_no; j++) { - rv = get_actual_shutdown(¤t, &clients[i].shutdown_time, &clients[i].sessions[j].req.Timeout); - if (rv > 0) { - has_active_test_sessions = 1; - if (FD_ISSET(clients[i].sessions[j].socket, &tmp_fds)) { - rv = receive_test_message(&clients[i], j); - } - } else { - FD_CLR(clients[i].sessions[j].socket, &read_fds); - close(clients[i].sessions[j].socket); - used_sockets--; - clients[i].sessions[j].socket = -1; - - /* print loss result */ - twamp_log(SINFO, "Session: %u, FW Lost packets: %u/%u, FW Loss Ratio: %3.2f%%", j, clients[i].sessions[j].fw_lst_msg, clients[i].sessions[j].fw_msg, (float)100 * clients[i].sessions[j].fw_lst_msg / clients[i].sessions[j].fw_msg); - - } - } - if (!has_active_test_sessions) { - memset(&clients[i].shutdown_time, 0, sizeof(clients[i].shutdown_time)); - clients[i].sess_no = 0; - clients[i].status = kConfigured; - } - } - } - } - return 0; -} - -char *get_twamp_reflector_option(char *instance, char *option) -{ - struct uci_section *s; - char *v, *twamp_id; - - dmuci_foreach_section("twamp", "twamp_reflector", s) { - twamp_id = dmuci_get_value_bysection(s, "id"); - if(strcmp(twamp_id, instance) == 0) - { - v = dmuci_get_value_bysection(s, option); - return v; - } - } - v = ""; - return v; -} - -int twamp_init(void) -{ - char *id, *value = NULL; - int a; - - value = dmuci_get_value("twamp", "twamp", "log_level"); - if(value != NULL && *value != '\0') { - a = atoi(value); - cur_twamp_conf.loglevel = a; - } - else - cur_twamp_conf.loglevel = DEFAULT_LOGLEVEL; - twamp_log(SDEBUG,"TWAMP Reflector Log Level:%d", cur_twamp_conf.loglevel); - - id = dmuci_get_value("twamp", "twamp", "id"); - cur_twamp_conf.enable = atoi(get_twamp_reflector_option(id, "enable")); - cur_twamp_conf.interface = strdup(get_twamp_reflector_option(id, "interface")); - cur_twamp_conf.device = strdup(get_twamp_reflector_option(id, "device")); - cur_twamp_conf.ip_version = atoi(get_twamp_reflector_option(id, "ip_version")); - cur_twamp_conf.port = atoi(get_twamp_reflector_option(id, "port")); - cur_twamp_conf.max_ttl = atoi(get_twamp_reflector_option(id, "max_ttl")); - cur_twamp_conf.ip_list = strdup(get_twamp_reflector_option(id, "ip_list")); - cur_twamp_conf.port_list = strdup(get_twamp_reflector_option(id, "port_list")); - - twamp_log(SDEBUG,"TWAMP Reflector Enable: %d", cur_twamp_conf.enable); - twamp_log(SDEBUG,"TWAMP Reflector Interface: %s", cur_twamp_conf.interface); - twamp_log(SDEBUG,"TWAMP Reflector Device: %s", cur_twamp_conf.device); - twamp_log(SDEBUG,"TWAMP Reflector Port: %d", cur_twamp_conf.port); - twamp_log(SDEBUG,"TWAMP Reflector MaximumTTL: %d", cur_twamp_conf.max_ttl); - twamp_log(SDEBUG,"TWAMP Reflector IPAllowedList: %s", cur_twamp_conf.ip_list); - twamp_log(SDEBUG,"TWAMP Reflector PortAllowedList: %s", cur_twamp_conf.port_list); - - return 0; -} - -void twamp_exit(void) -{ - free(cur_twamp_conf.interface); - free(cur_twamp_conf.device); - free(cur_twamp_conf.ip_list); - free(cur_twamp_conf.port_list); -} - -int main(int argc, char *argv[]) -{ - dmuci_init(); - twamp_init(); - dmuci_fini(); - twamp_log(SINFO,"START TWAMP Reflector"); - - twamp_connect(); - - twamp_exit(); - twamp_log(SINFO,"EXIT TWAMP Reflector"); - return 0; -} diff --git a/twamp/src/twamp.h b/twamp/src/twamp.h deleted file mode 100644 index df1b34efc..000000000 --- a/twamp/src/twamp.h +++ /dev/null @@ -1,237 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* -* Name: Emma Mirică -* Project: TWAMP Protocol -* Class: OSS -* Email: emma.mirica@cti.pub.ro -* Contributions: stephanDB -* -*/ - -/* - * The following logical-model will be implemented: - * - * +----------------+ +-------------------+ - * | Control-Client |<--TWAMP-Control-->| Server | - * | | | | - * | Session-Sender |<--TWAMP-Test----->| Session-Reflector | - * +----------------+ +-------------------+ - * - */ - -#ifndef _TWAMP_H__ -#define _TWAMP_H__ - -#include -#include -#include -#include - -#define CHECK_TIMES 100 -#define LOSTTIME 2 /* SECONDS - Timeout for TWAMP test packet */ -#define MAX_CLIENTS 10 -#define MAX_SESSIONS_PER_CLIENT 10 - -enum CommandNumber { - kReserved, - kForbidden, - kStartSessions, - kStopSessions, - kReserved4, - kRequestTWSession, - kExperimentation -}; - -enum Mode { - kModeReserved = 0, - kModeUnauthenticated = 1, - kModeAuthenticated = 2, - kModeEncrypted = 4, - kModeHybrid = 8, /* Unauthenticated test, encrypted control */ - kModeIndividual = 16, - kModeReflectOctets = 32, - KModeSymmetrical = 64, - KModeIKEv2Derived = 128, - kModeDSCPECN = 256 -}; - -enum AcceptCode { - kOK, - kFailure, - kInternalError, - kAspectNotSupported, - kPermanentResourceLimitation, - kTemporaryResourceLimitation -}; - -typedef enum { - kOffline = 0, - kConnected, - kConfigured, - kTesting -} ClientStatus; - -typedef struct twamp_timestamp { - uint32_t integer; - uint32_t fractional; -} TWAMPTimestamp; - -/*****************************************/ -/* */ -/* TWAMP-Control specific messages */ -/* */ -/*****************************************/ - -/* First messsage sent by the Server to the Control-Client to establish a connection */ -typedef struct server_greeting { - uint8_t Unused[12]; - /* Modes = bit-wise OR between Mode values - * First 23 bits MUST be zero in TWAMP (29 in first version)*/ - uint32_t Modes; - uint8_t Challenge[16]; /* Random sequence of bytes generated by the server */ - uint8_t Salt[16]; - uint32_t Count; /* MUST be a power of 2. Minimum 1024 */ - uint8_t MBZ[12]; -} ServerGreeting; - -/* The Control-Client's response to the Server's greeting */ -typedef struct control_client_greeting_response { - uint32_t Mode; /* if 0 -> the Server does not wish to communicate */ - uint8_t KeyID[80]; - uint8_t Token[64]; - uint8_t ClientIV[16]; -} SetUpResponse; - -/* The Server sends a start message to conclude the TWAMP-Control session */ -typedef struct server_start { - uint8_t MBZ1[15]; - uint8_t Accept; /* 0 means Continue. See 3.3 of RFC 4656 */ - uint8_t ServerIV[16]; - TWAMPTimestamp StartTime; /* TWAMPTimestamp; 0 if Accept is NonZero. */ - uint8_t MBZ2[8]; -} ServerStart; - -/* The Control-Client sends a RequestSession packet for each TWAMP-Test session */ -typedef struct request_session { - uint8_t Type; /* 5 / CommandNumber */ - uint8_t IPVN; /* MBZ | IPVN */ - uint8_t ConfSender; /* 0 */ - uint8_t ConfReceiver; /* 0 */ - uint32_t SlotsNo; /* 0 */ - uint32_t PacketsNo; /* 0 */ - uint16_t SenderPort; - uint16_t ReceiverPort; - uint32_t SenderAddress; - uint8_t MBZ1[12]; /* Sender Address Cont */ - uint32_t ReceiverAddress; - uint8_t MBZ2[12]; /* Receiver Address Cont */ - uint8_t SID[16]; /* 0 */ - uint32_t PaddingLength; - TWAMPTimestamp StartTime; - TWAMPTimestamp Timeout; - uint32_t TypePDescriptor; - uint16_t OctetsToBeReflected; - uint16_t PadLenghtToReflect; - uint8_t MBZ3[4]; - uint8_t HMAC[16]; -} RequestSession; - -/* The Server's response to the RequestSession packet */ -typedef struct accept_session_packet { - uint8_t Accept; /* 3 if not supported */ - uint8_t MBZ1; - uint16_t Port; - uint8_t SID[16]; /* Generated by server */ - //uint16_t ReflectedOctets; - //uint16_t ServerOctets; - uint8_t MBZ2[8]; - uint8_t HMAC[16]; -} AcceptSession; - -/* The Control-Client sends a StartSessions message to start all accepted TWAMP-Test sessions */ -typedef struct start_message1 { - uint8_t Type; /* 2 */ - uint8_t MBZ[15]; - uint8_t HMAC[16]; -} StartSessions; - -/* When it receives a StartSessions, the Server responds with a StartACK */ -typedef struct start_ack { - uint8_t Accept; - uint8_t MBZ[15]; - uint8_t HMAC[16]; -} StartACK; - -/* The Control-Client sends a StopSessions message to stop all active TWAMP-Test sessions */ -typedef struct twamp_stop { - uint8_t Type; /* 3 */ - uint8_t Accept; - uint8_t MBZ1[2]; - uint32_t SessionsNo; - uint8_t MBZ2[8]; - uint8_t HMAC[16]; -} StopSessions; - -/*****************************************/ -/* */ -/* TWAMP-Test specific messages */ -/* */ -/*****************************************/ -#define TST_PKT_SIZE 1472 //1472 (MTU 1514) - -/* Session-Sender TWAMP-Test packet for Unauthenticated mode */ -typedef struct test_packet { - uint32_t seq_number; - TWAMPTimestamp time; - uint16_t error_estimate; - uint8_t padding[TST_PKT_SIZE - 14]; -} SenderUPacket; - -/* Session-Reflector TWAMP-Test packet for Unauthenticated mode */ -typedef struct reflector_unauth_packet { - uint32_t seq_number; - TWAMPTimestamp time; - uint16_t error_estimate; - uint8_t mbz1[2]; - TWAMPTimestamp receive_time; - uint32_t sender_seq_number; - TWAMPTimestamp sender_time; - uint16_t sender_error_estimate; - uint8_t mbz2[2]; - uint8_t sender_ttl; - uint8_t sender_tos; - uint8_t padding[TST_PKT_SIZE - 42]; -} ReflectorUPacket; - -struct twamp_config -{ - bool enable; - char *interface; - char *device; - int ip_version; - int port; - int max_ttl; - char *ip_list; - char *port_list; - int loglevel; -}; - -extern struct twamp_config cur_twamp_conf; - -void timeval_to_timestamp(const struct timeval *tv, TWAMPTimestamp * ts); -void timestamp_to_timeval(const TWAMPTimestamp * ts, struct timeval *tv); -uint64_t get_usec(const TWAMPTimestamp * ts); -TWAMPTimestamp get_timestamp(); -int get_actual_shutdown(const struct timeval *tv, const struct timeval *ts, const TWAMPTimestamp * t); -void print_metrics_server(char *addr_cl, uint16_t snd_port, uint16_t rcv_port, uint8_t snd_tos, uint8_t fw_tos, const ReflectorUPacket * pack); -void set_socket_option(int socket, uint8_t ip_ttl); -void set_socket_tos(int socket, uint8_t ip_tos); - -#endif /* _TWAMP_H__ */ diff --git a/twamp/src/twamp.md b/twamp/src/twamp.md deleted file mode 100644 index f09047eea..000000000 --- a/twamp/src/twamp.md +++ /dev/null @@ -1,57 +0,0 @@ -# README # - -twampd is an implementation of the Two-Way Active Measurement Protocol (TWAMP) reflector. - - -## Configuration File ## - -The twampd UCI configuration is located in **'/etc/config/twamp'**, and contains 2 sections the **twamp** and the **twamp\_reflector**. - -``` -config twamp 'twamp' - option id '1' - option log_level '3' - -config twamp_reflector - option id '1' - option enable '' - option interface '' - option device '' - option ip_version '' - option port '' - option max_ttl '' - option ip_list '' - option port_list '' -``` - -### twamp section ### - -It defines **the twamp configuration**: id, log_level. The possible options for **twamp** section are: - -| Name | Type | Description | -| --------- | ------- | ------------------------------------------- | -| `id` | integer | Specifies the id of TWAMP reflector to use. | -| `log_level` | integer | Specifies the log type to use, by default **'INFO'**. The possible types are **'EMERG', 'ALERT', 'CRITIC' ,'ERROR', 'WARNING', 'NOTICE', 'INFO' and 'DEBUG'**. | - -### twamp_reflector section ### - -It describes **the twamp reflector configuration**: id, ip\_version, etc... The possible options for **twamp_reflector** section are: - -| Name | Type | Description | -| ---------- | ------- | ------------------------------ | -| `id` | integer | Specifies the TWAMP id to use. | -| `enable` | boolean | If set to **1**, it enables the TWAMP reflector. | -| `ip_version` | integer | Specifies the IP version to use, **4** by default. The possible versions are **4** and **6**. | -| `port` | integer | Specifies the port to listen on. | -| `max_ttl` | integer | Specifies the maximum TTL of a received packet, that the TWAMP reflector will reflect to the TWAMP controller. | -| `ip_list` | string | Specifies the allowed source IP addresses and subnets to handle test packets. | -| `port_list` | string | Specifies the range of source ports allowed to use for twamp\_reflector tests. | - -## Dependencies ## - -To successfully build twampd, the following libraries are needed: - -| Dependency | Link | License | -| ----------- | ------------------------------------------- | -------------- | -| libuci | https://git.openwrt.org/project/uci.git | LGPL 2.1 | - diff --git a/twamp/src/twamplog.c b/twamp/src/twamplog.c deleted file mode 100644 index ec26800c0..000000000 --- a/twamp/src/twamplog.c +++ /dev/null @@ -1,55 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -*/ - -#include -#include -#include -#include -#include "twamplog.h" -#include "twamp.h" -#define DEBUG - -static const int log_syslogmap[] = { - [SCRIT] = LOG_CRIT, - [SWARNING] = LOG_WARNING, - [SNOTICE] = LOG_NOTICE, - [SINFO] = LOG_INFO, - [SDEBUG] = LOG_DEBUG -}; - -static const char* log_str[] = { - [SCRIT] = "CRITICAL", - [SWARNING] = "WARNING", - [SNOTICE] = "NOTICE", - [SINFO] = "INFO", - [SDEBUG] = "DEBUG" -}; - -void twamp_log(int priority, const char *format, ...) -{ - va_list vl; - - if (priority <= cur_twamp_conf.loglevel) { -#ifdef DEBUG - time_t t = time(NULL); - struct tm tm = *localtime(&t); - va_start(vl, format); - printf("%d-%02d-%02d %02d:%02d:%02d [twamp] %s - ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, log_str[priority]); - vprintf(format, vl); - va_end(vl); - printf("\n"); -#endif - openlog("twamp", 0, LOG_DAEMON); - va_start(vl, format); - vsyslog(log_syslogmap[priority], format, vl); - va_end(vl); - closelog(); - } -} diff --git a/twamp/src/twamplog.h b/twamp/src/twamplog.h deleted file mode 100644 index 9566fdc10..000000000 --- a/twamp/src/twamplog.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -*/ - -#ifndef _TWAMPLOG_H_ -#define _TWAMPLOG_H_ - -#define DEFAULT_LOGLEVEL SINFO - -enum udpechoserver_log_level_enum { - SCRIT, - SWARNING, - SNOTICE, - SINFO, - SDEBUG, - __MAX_SLOG -}; - -void twamp_log(int priority, const char *format, ...); - -#endif /* _TWAMPLOG_H_ */ diff --git a/twamp/src/twamptimestamp.c b/twamp/src/twamptimestamp.c deleted file mode 100644 index c2b7896f4..000000000 --- a/twamp/src/twamptimestamp.c +++ /dev/null @@ -1,195 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -* -* Name: Emma Mirică -* Project: TWAMP Protocol -* Class: OSS -* Email: emma.mirica@cti.pub.ro -* Contributions: stephanDB -* -*/ - -#include -#include -#include -#include -#include -#include "twamp.h" -#include "twamplog.h" - -void timeval_to_timestamp(const struct timeval *tv, TWAMPTimestamp * ts) -{ - if (!tv || !ts) - return; - - /* Unix time to NTP */ - ts->integer = tv->tv_sec + 2208988800uL; - ts->fractional = (uint32_t) ((double)tv->tv_usec * ((double)(1uLL << 32) - / (double)1e6)); - - ts->integer = htonl(ts->integer); - ts->fractional = htonl(ts->fractional); -} - -void timestamp_to_timeval(const TWAMPTimestamp * ts, struct timeval *tv) -{ - if (!tv || !ts) - return; - - TWAMPTimestamp ts_host_ord; - - ts_host_ord.integer = ntohl(ts->integer); - ts_host_ord.fractional = ntohl(ts->fractional); - - /* NTP to Unix time */ - tv->tv_sec = ts_host_ord.integer - 2208988800uL; - tv->tv_usec = (uint32_t) (double)ts_host_ord.fractional * (double)1e6 / (double)(1uLL << 32); -} - -TWAMPTimestamp get_timestamp() -{ - struct timeval tv; - gettimeofday(&tv, NULL); - TWAMPTimestamp ts; - timeval_to_timestamp(&tv, &ts); - return ts; -} - -uint64_t get_usec(const TWAMPTimestamp * ts) -{ - struct timeval tv; - timestamp_to_timeval(ts, &tv); - - return tv.tv_sec * 1000000 + tv.tv_usec; -} - -int get_actual_shutdown(const struct timeval *tv, const struct timeval *ts, - const TWAMPTimestamp * t) -{ - /* If ts is 0 then no StopSessions message was received */ - if ((ts->tv_sec * 1000000 + ts->tv_usec) == 0) - return 1; - /* Else compute time difference */ - uint64_t current = tv->tv_sec * 1000000 + tv->tv_usec; - uint64_t shutdown = ts->tv_sec * 1000000 + ts->tv_usec; - uint64_t timeout = get_usec(t); - - /* This should be ok, as no difference is computed */ - if (current > shutdown + timeout) - return 1; - return 0; -} - -void print_metrics_server(char *addr_cl, uint16_t snd_port, uint16_t rcv_port, - uint8_t snd_tos, uint8_t fw_tos, - const ReflectorUPacket * pack) -{ - - /* Compute timestamps in usec */ - uint64_t t_sender_usec1 = get_usec(&pack->sender_time); - uint64_t t_receive_usec1 = get_usec(&pack->receive_time); - uint64_t t_reflsender_usec1 = get_usec(&pack->time); - - /* Compute delays */ - int64_t fwd1 = t_receive_usec1 - t_sender_usec1; - int64_t intd1 = t_reflsender_usec1 - t_receive_usec1; - char sync1 = 'Y'; - if (fwd1 < 0) { - sync1 = 'N'; - } - - /* Sequence number */ - uint32_t snd_nb = ntohl(pack->sender_seq_number); - uint32_t rcv_nb = ntohl(pack->seq_number); - - /* Sender TOS with ECN from FW TOS */ - snd_tos = snd_tos + (fw_tos & 0x3) - (((fw_tos & 0x2) >> 1) & (fw_tos & 0x1)); - - /* Print different metrics */ - twamp_log(SINFO,"Snd@: %s", addr_cl); - twamp_log(SINFO,"Time: %.0f", (double)t_sender_usec1 * 1e-3); - twamp_log(SINFO,"Snd#: %d", snd_nb); - twamp_log(SINFO,"Rcv#: %d", rcv_nb); - twamp_log(SINFO,"SndPt: %d", snd_port); - twamp_log(SINFO,"RcvPt: %d", rcv_port); - twamp_log(SINFO,"Sync: %c", sync1); - twamp_log(SINFO,"TTL: %d", pack->sender_ttl); - twamp_log(SINFO,"SndTOS: %d", snd_tos); - twamp_log(SINFO,"FW_TOS: %d", fw_tos); - twamp_log(SINFO,"Int D: %.3f", (double)intd1 * 1e-3); -} - -void set_socket_option(int socket, uint8_t ip_ttl) -{ - /* Set socket options : timeout, IPTTL, IP_RECVTTL, IP_RECVTOS */ - uint8_t One = 1; - int result; - - /* Set Timeout */ - struct timeval timeout = { LOSTTIME, 0 }; //set timeout for 2 seconds - - /* Set receive UDP message timeout value */ -#ifdef SO_RCVTIMEO - result = setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, - (char *)&timeout, sizeof(struct timeval)); - if (result != 0) { - twamp_log(SDEBUG, "[PROBLEM] Cannot set the timeout value for reception.\n"); - } -#else - twamp_log(SDEBUG, "No way to set the timeout value for incoming packets on that platform.\n"); -#endif - - /* Set IPTTL value to twamp standard: 255 */ -#ifdef IP_TTL - result = setsockopt(socket, IPPROTO_IP, IP_TTL, &ip_ttl, sizeof(ip_ttl)); - if (result != 0) { - twamp_log(SDEBUG, "[PROBLEM] Cannot set the TTL value for emission.\n"); - } -#else - twamp_log(SDEBUG, "No way to set the TTL value for leaving packets on that platform.\n"); -#endif - - /* Set receive IP_TTL option */ -#ifdef IP_RECVTTL - result = setsockopt(socket, IPPROTO_IP, IP_RECVTTL, &One, sizeof(One)); - if (result != 0) { - twamp_log(SDEBUG, "[PROBLEM] Cannot set the socket option for TTL reception.\n"); - } -#else - twamp_log(SDEBUG, "No way to ask for the TTL of incoming packets on that platform.\n"); -#endif - - /* Set receive IP_TOS option */ -#ifdef IP_RECVTOS - result = setsockopt(socket, IPPROTO_IP, IP_RECVTOS, &One, sizeof(One)); - if (result != 0) { - twamp_log(SDEBUG, "[PROBLEM] Cannot set the socket option for TOS reception.\n"); - } -#else - twamp_log(SDEBUG, "No way to ask for the TOS of incoming packets on that platform.\n"); -#endif - -} - -void set_socket_tos(int socket, uint8_t ip_tos) -{ - /* Set socket options : IP_TOS */ - int result; - - /* Set IP TOS value */ -#ifdef IP_TOS - result = setsockopt(socket, IPPROTO_IP, IP_TOS, &ip_tos, sizeof(ip_tos)); - if (result != 0) { - twamp_log(SDEBUG, "[PROBLEM] Cannot set the TOS value for emission.\n"); - } -#else - twamp_log(SDEBUG, "No way to set the TOS value for leaving packets on that platform.\n"); -#endif - -} diff --git a/twamp/src/twampuci.c b/twamp/src/twampuci.c deleted file mode 100644 index fee4a409e..000000000 --- a/twamp/src/twampuci.c +++ /dev/null @@ -1,266 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "twampuci.h" - -struct uci_context *uci_ctx; - -int dmuci_init(void) -{ - uci_ctx = uci_alloc_context(); - if (!uci_ctx) { - return -1; - } - return 0; -} - -int dmuci_fini(void) -{ - if (uci_ctx) { - uci_free_context(uci_ctx); - } - - return 0; -} - -static bool dmuci_validate_section(const char *str) -{ - if (!*str) - return false; - - for (; *str; str++) { - unsigned char c = *str; - - if (isalnum(c) || c == '_') - continue; - - return false; - } - return true; -} - -static int dmuci_init_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value) -{ - memset(ptr, 0, sizeof(struct uci_ptr)); - - /* value */ - if (value) { - ptr->value = value; - } - ptr->package = package; - if (!ptr->package) - goto error; - - ptr->section = section; - if (!ptr->section) { - ptr->target = UCI_TYPE_PACKAGE; - goto lastval; - } - - ptr->option = option; - if (!ptr->option) { - ptr->target = UCI_TYPE_SECTION; - goto lastval; - } else { - ptr->target = UCI_TYPE_OPTION; - } - -lastval: - if (ptr->section && !dmuci_validate_section(ptr->section)) - ptr->flags |= UCI_LOOKUP_EXTENDED; - - return 0; - -error: - return -1; -} - -struct uci_section *dmuci_walk_section(char *package, char *section_type, struct uci_section *prev_section) -{ - struct uci_ptr ptr; - struct uci_element *e; - struct uci_section *next_section; - - if (section_type == NULL) { - if (prev_section) { - e = &prev_section->e; - if (e->list.next == &prev_section->package->sections) - return NULL; - e = container_of(e->list.next, struct uci_element, list); - next_section = uci_to_section(e); - return next_section; - } - else { - if (dmuci_init_ptr(uci_ctx, &ptr, package, NULL, NULL, NULL)) { - return NULL; - } - if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK) { - return NULL; - } - if (ptr.p->sections.next == &ptr.p->sections) - return NULL; - e = container_of(ptr.p->sections.next, struct uci_element, list); - next_section = uci_to_section(e); - - return next_section; - } - } - else { - struct uci_list *ul; - struct uci_list *shead = NULL; - - if (prev_section) { - ul = &prev_section->e.list; - shead = &prev_section->package->sections; - } - else { - if (dmuci_init_ptr(uci_ctx, &ptr, package, NULL, NULL, NULL)) { - return NULL; - } - if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK) { - return NULL; - } - ul = &ptr.p->sections; - shead = &ptr.p->sections; - } - while (ul->next != shead) { - e = container_of(ul->next, struct uci_element, list); - next_section = uci_to_section(e); - if (strcmp(next_section->type, section_type) == 0) - return next_section; - ul = ul->next; - } - return NULL; - } - return NULL; -} - -void dmuci_print_list(struct uci_list *uh, char **val, char *delimiter) -{ - struct uci_element *e; - static char buffer[512]; - char *buf = buffer; - *buf = '\0'; - - uci_foreach_element(uh, e) { - if (*buf) { - strcat(buf, delimiter); - strcat(buf, e->name); - } - else { - strcpy(buf, e->name); - } - } - *val = buf; -} - -struct uci_element *dmuci_lookup_list(struct uci_list *list, const char *name) -{ - struct uci_element *e; - - uci_foreach_element(list, e) { - if (!strcmp(e->name, name)) - return e; - } - return NULL; -} - -int uci_lookup_ptr_bysection(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_section *section, char *option, char *value) -{ - struct uci_element *e; - memset(ptr, 0, sizeof(struct uci_ptr)); - - ptr->package = section->package->e.name; - ptr->section = section->e.name; - ptr->option = option; - ptr->value = value; - ptr->flags |= UCI_LOOKUP_DONE; - - ptr->p = section->package; - ptr->s = section; - - if (ptr->option) { - e = dmuci_lookup_list(&ptr->s->options, ptr->option); - if (!e) - return UCI_OK; - ptr->o = uci_to_option(e); - ptr->last = e; - ptr->target = UCI_TYPE_OPTION; - } - else { - ptr->last = &ptr->s->e; - ptr->target = UCI_TYPE_SECTION; - } - - ptr->flags |= UCI_LOOKUP_COMPLETE; - - return UCI_OK; -} - -char *dmuci_get_value_bysection(struct uci_section *section, char *option) -{ - struct uci_ptr ptr; - char *val = ""; - - if (uci_lookup_ptr_bysection(uci_ctx, &ptr, section, option, NULL) != UCI_OK) { - return val; - } - - if (!ptr.o) - return val; - - if(ptr.o->type == UCI_TYPE_LIST) { - dmuci_print_list(&ptr.o->v.list, &val, " "); - return val; - } - - if (ptr.o->v.string) - return ptr.o->v.string; - else - return val; -} - -char *dmuci_get_value(char *package, char *section, char *option) -{ - struct uci_ptr ptr; - char *val = ""; - - if (!section || !option) - return val; - - if (dmuci_init_ptr(uci_ctx, &ptr, package, section, option, NULL)) { - return val; - } - if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK) { - return val; - } - - if (!ptr.o) - return val; - - if(ptr.o->type == UCI_TYPE_LIST) { - dmuci_print_list(&ptr.o->v.list, &val, " "); - return val; - } - - if (ptr.o->v.string) - return ptr.o->v.string; - else - return val; -} diff --git a/twamp/src/twampuci.h b/twamp/src/twampuci.h deleted file mode 100644 index b97663928..000000000 --- a/twamp/src/twampuci.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -*/ - -#ifndef _TWAMPUCI_H__ -#define _TWAMPUCI_H__ - -#include -#include -#include -#include - - -int dmuci_init(void); -int dmuci_fini(void); -struct uci_section *dmuci_walk_section(char *package, char *section_type, struct uci_section *prev_section); -void dmuci_print_list(struct uci_list *uh, char **val, char *delimiter); -struct uci_element *dmuci_lookup_list(struct uci_list *list, const char *name); -int uci_lookup_ptr_bysection(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_section *section, char *option, char *value); -char *dmuci_get_value_bysection(struct uci_section *section, char *option); -char *dmuci_get_value(char *package, char *section, char *option); - -#define dmuci_foreach_section(package, section_type, section) \ - for (section = dmuci_walk_section(package, section_type, NULL); \ - section != NULL; \ - section = dmuci_walk_section(package, section_type, section)) - -#endif /* _TWAMPUCI_H__ */ diff --git a/udpechoserver/Makefile b/udpechoserver/Makefile index 9a3b3c6a3..494adfbc5 100755 --- a/udpechoserver/Makefile +++ b/udpechoserver/Makefile @@ -10,24 +10,30 @@ include $(TOPDIR)/rules.mk PKG_NAME:=udpechoserver PKG_VERSION:=1.0.0 +PKG_SOURCE_VERSION:=a3f0860f4268482f9ec9dad0c67745f615293fca +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/udpechoserver.git + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz +PKG_MIRROR_HASH:=skip +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_LICENSE:=GPL-2.0-only +PKG_LICENSE_FILES:=LICENSE + include $(INCLUDE_DIR)/package.mk define Package/$(PKG_NAME) SECTION:=utils CATEGORY:=Utilities SUBMENU:=TRx69 - TITLE:=BBF udp echo server + TITLE:=BBF UDP Echo Server DEPENDS:=+libuci +libbbf_api endef define Package/$(PKG_NAME)/description - BBF UDP_echo_server -endef - -define Build/Prepare - $(CP) ./src/* $(PKG_BUILD_DIR)/ + BBF UDP Echo Server endef TARGET_CFLAGS += \ @@ -41,4 +47,4 @@ define Package/$(PKG_NAME)/install $(CP) ./files/* $(1)/ endef -$(eval $(call BuildPackage,$(PKG_NAME))) \ No newline at end of file +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/udpechoserver/src/Makefile b/udpechoserver/src/Makefile deleted file mode 100644 index 7e04d1558..000000000 --- a/udpechoserver/src/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -PROG = udpechoserverd -LIB = libudpechoserver.so - -PROG_OBJS = udpechoserver.o udpechoserverlog.o udpechoserveruci.o -LIB_OBJS = datamodel.o - -PROG_CFLAGS = $(CFLAGS) -Wall -Werror -fPIC -PROG_LDFLAGS = $(LDFLAGS) -luci -LIB_LDFLAGS = $(LDFLAGS) -lbbf_api - -%.o: %.c - $(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $< - -all: $(PROG) $(LIB) - -$(PROG): $(PROG_OBJS) - $(CC) $(PROG_CFLAGS) -o $@ $^ $(PROG_LDFLAGS) - -$(LIB): $(LIB_OBJS) - $(CC) $(PROG_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^ - -clean: - rm -f *.o $(PROG) $(LIB) diff --git a/udpechoserver/src/datamodel.c b/udpechoserver/src/datamodel.c deleted file mode 100644 index 28b8aae4f..000000000 --- a/udpechoserver/src/datamodel.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2020 iopsys Software Solutions AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * Author: Amin Ben Ramdhane - */ - -#include -#include -#include -#include -#include - -#include "datamodel.h" - -/* ********** DynamicObj ********** */ -DM_MAP_OBJ tDynamicObj[] = { -/* parentobj, nextobject, parameter */ -{"Device.IP.Diagnostics.", tDeviceUDPEchoConfigObj, NULL}, -{0} -}; - -static int get_IPDiagnosticsUDPEchoConfig_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = dmuci_get_option_value_fallback_def("udpechoserver", "udpechoserver", "enable", "1"); - return 0; -} - -static int set_IPDiagnosticsUDPEchoConfig_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - bool b; - char file[32] = "/var/state/udpechoserver"; - - switch (action) { - case VALUECHECK: - if (dm_validate_boolean(value)) - return FAULT_9007; - return 0; - case VALUESET: - string_to_bool(value, &b); - if (b) { - if( access( file, F_OK ) != -1 ) - dmcmd("/bin/rm", 1, file); - dmuci_set_value("udpechoserver", "udpechoserver", "enable", "1"); - } else - dmuci_set_value("udpechoserver", "udpechoserver", "enable", "0"); - return 0; - } - return 0; -} - -static int get_IPDiagnosticsUDPEchoConfig_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_option_value_string("udpechoserver", "udpechoserver", "interface", value); - return 0; -} - -static int set_IPDiagnosticsUDPEchoConfig_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, 256, NULL, NULL)) - return FAULT_9007; - return 0; - case VALUESET: - dmuci_set_value("udpechoserver", "udpechoserver", "interface", value); - return 0; - } - return 0; -} - -static int get_IPDiagnosticsUDPEchoConfig_SourceIPAddress(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_option_value_string("udpechoserver", "udpechoserver", "address", value); - return 0; -} - -static int set_IPDiagnosticsUDPEchoConfig_SourceIPAddress(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, 45, NULL, IPAddress)) - return FAULT_9007; - return 0; - case VALUESET: - dmuci_set_value("udpechoserver", "udpechoserver", "address", value); - return 0; - } - return 0; -} - -static int get_IPDiagnosticsUDPEchoConfig_UDPPort(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = dmuci_get_option_value_fallback_def("udpechoserver", "udpechoserver", "server_port", "0"); - return 0; -} - -static int set_IPDiagnosticsUDPEchoConfig_UDPPort(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_unsignedInt(value, RANGE_ARGS{{NULL,NULL}}, 1)) - return FAULT_9007; - return 0; - case VALUESET: - dmuci_set_value("udpechoserver", "udpechoserver", "server_port", value); - return 0; - } - return 0; -} - -static int get_IPDiagnosticsUDPEchoConfig_EchoPlusEnabled(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = dmuci_get_option_value_fallback_def("udpechoserver", "udpechoserver", "plus", "1"); - return 0; -} - -static int set_IPDiagnosticsUDPEchoConfig_EchoPlusEnabled(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - bool b; - - switch (action) { - case VALUECHECK: - if (dm_validate_boolean(value)) - return FAULT_9007; - return 0; - case VALUESET: - string_to_bool(value, &b); - dmuci_set_value("udpechoserver", "udpechoserver", "plus", b ? "1" : "0"); - return 0; - } - return 0; -} - -static int get_IPDiagnosticsUDPEchoConfig_EchoPlusSupported(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = "true"; - return 0; -} - -static inline char *udpechoconfig_get(char *option, char *def) -{ - char *tmp; - varstate_get_value_string("udpechoserver", "udpechoserver", option, &tmp); - if(tmp && tmp[0] == '\0') - return dmstrdup(def); - else - return tmp; -} - -static int get_IPDiagnosticsUDPEchoConfig_PacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = udpechoconfig_get("PacketsReceived", "0"); - return 0; -} - -static int get_IPDiagnosticsUDPEchoConfig_PacketsResponded(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = udpechoconfig_get("PacketsResponded", "0"); - return 0; -} - -static int get_IPDiagnosticsUDPEchoConfig_BytesReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = udpechoconfig_get("BytesReceived", "0"); - return 0; -} - -static int get_IPDiagnosticsUDPEchoConfig_BytesResponded(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = udpechoconfig_get("BytesResponded", "0"); - return 0; -} - -static int get_IPDiagnosticsUDPEchoConfig_TimeFirstPacketReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = udpechoconfig_get("TimeFirstPacketReceived", "0001-01-01T00:00:00.000000Z"); - return 0; -} - -static int get_IPDiagnosticsUDPEchoConfig_TimeLastPacketReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = udpechoconfig_get("TimeLastPacketReceived", "0001-01-01T00:00:00.000000Z"); - return 0; -} - -/* *** Device.IP.Diagnostics. *** */ -DMOBJ tDeviceUDPEchoConfigObj[] = { -/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ -{"UDPEchoConfig", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tIPDiagnosticsUDPEchoConfigParams, NULL, BBFDM_BOTH}, -{0} -}; - -/* *** Device.IP.Diagnostics.UDPEchoConfig. *** */ -DMLEAF tIPDiagnosticsUDPEchoConfigParams[] = { -/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ -{"Enable", &DMWRITE, DMT_BOOL, get_IPDiagnosticsUDPEchoConfig_Enable, set_IPDiagnosticsUDPEchoConfig_Enable, BBFDM_BOTH}, -{"Interface", &DMWRITE, DMT_STRING, get_IPDiagnosticsUDPEchoConfig_Interface, set_IPDiagnosticsUDPEchoConfig_Interface, BBFDM_BOTH}, -{"SourceIPAddress", &DMWRITE, DMT_STRING, get_IPDiagnosticsUDPEchoConfig_SourceIPAddress, set_IPDiagnosticsUDPEchoConfig_SourceIPAddress, BBFDM_BOTH}, -{"UDPPort", &DMWRITE, DMT_UNINT, get_IPDiagnosticsUDPEchoConfig_UDPPort, set_IPDiagnosticsUDPEchoConfig_UDPPort, BBFDM_BOTH}, -{"EchoPlusEnabled", &DMWRITE, DMT_BOOL, get_IPDiagnosticsUDPEchoConfig_EchoPlusEnabled, set_IPDiagnosticsUDPEchoConfig_EchoPlusEnabled, BBFDM_BOTH}, -{"EchoPlusSupported", &DMREAD, DMT_BOOL, get_IPDiagnosticsUDPEchoConfig_EchoPlusSupported, NULL, BBFDM_BOTH}, -{"PacketsReceived", &DMREAD, DMT_UNINT, get_IPDiagnosticsUDPEchoConfig_PacketsReceived, NULL, BBFDM_BOTH}, -{"PacketsResponded", &DMREAD, DMT_UNINT, get_IPDiagnosticsUDPEchoConfig_PacketsResponded, NULL, BBFDM_BOTH}, -{"BytesReceived", &DMREAD, DMT_UNINT, get_IPDiagnosticsUDPEchoConfig_BytesReceived, NULL, BBFDM_BOTH}, -{"BytesResponded", &DMREAD, DMT_UNINT, get_IPDiagnosticsUDPEchoConfig_BytesResponded, NULL, BBFDM_BOTH}, -{"TimeFirstPacketReceived", &DMREAD, DMT_TIME, get_IPDiagnosticsUDPEchoConfig_TimeFirstPacketReceived, NULL, BBFDM_BOTH}, -{"TimeLastPacketReceived", &DMREAD, DMT_TIME, get_IPDiagnosticsUDPEchoConfig_TimeLastPacketReceived, NULL, BBFDM_BOTH}, -{0} -}; diff --git a/udpechoserver/src/datamodel.h b/udpechoserver/src/datamodel.h deleted file mode 100644 index 2c258d006..000000000 --- a/udpechoserver/src/datamodel.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2020 iopsys Software Solutions AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * Author: Amin Ben Ramdhane - */ - -#ifndef _UDPECHOSERVER_H_ -#define _UDPECHOSERVER_H_ - -extern DMOBJ tDeviceUDPEchoConfigObj[]; -extern DMLEAF tIPDiagnosticsUDPEchoConfigParams[]; - -#endif //_UDPECHOSERVER_H_ diff --git a/udpechoserver/src/udpechoserver.c b/udpechoserver/src/udpechoserver.c deleted file mode 100644 index da2781eae..000000000 --- a/udpechoserver/src/udpechoserver.c +++ /dev/null @@ -1,230 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "udpechoserver.h" -#include "udpechoserverlog.h" -#include "udpechoserveruci.h" - -struct udpechoserver_config cur_udpechoserver_conf = {0}; -struct udpechoserver_result cur_udpechoserver_result={0}; - -static void set_udpechoserver_stats(void) -{ - char PacketsReceived[8], PacketsResponded[8], BytesReceived[8], BytesResponded[8]; - - sprintf(PacketsReceived, "%d", cur_udpechoserver_result.PacketsReceived); - sprintf(PacketsResponded, "%d", cur_udpechoserver_result.PacketsResponded); - sprintf(BytesReceived, "%d", cur_udpechoserver_result.BytesReceived); - sprintf(BytesResponded, "%d", cur_udpechoserver_result.BytesResponded); - - dmuci_init(); - dmuci_set_value_state("udpechoserver", "udpechoserver", "PacketsReceived", PacketsReceived); - dmuci_set_value_state("udpechoserver", "udpechoserver", "PacketsResponded", PacketsResponded); - dmuci_set_value_state("udpechoserver", "udpechoserver", "BytesReceived", BytesReceived); - dmuci_set_value_state("udpechoserver", "udpechoserver", "BytesResponded", BytesResponded); - dmuci_set_value_state("udpechoserver", "udpechoserver", "TimeFirstPacketReceived", cur_udpechoserver_result.TimeFirstPacket); - dmuci_set_value_state("udpechoserver", "udpechoserver", "TimeLastPacketReceived", cur_udpechoserver_result.TimeLastPacket); - dmuci_fini(); -} - -int udpechoserver_connect(void) -{ - int sock, fromlen, n, ret; - struct sockaddr_in server, from; - struct timeval tv_recv, tv_reply; - struct tm lt; - char buf[1024]; - char str[INET_ADDRSTRLEN]; - char s_now[default_date_size]; - struct udpechoserver_plus *plus; - - memset(&cur_udpechoserver_result, 0, sizeof(cur_udpechoserver_result)); - - sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock < 0) { - udpechoserver_log(SCRIT,"Socket error = %d", sock); - return -1; - } - - bzero(&server, sizeof(server)); - server.sin_family=AF_INET; - server.sin_addr.s_addr=INADDR_ANY; - server.sin_port=htons(cur_udpechoserver_conf.server_port); - - if (bind(sock, (struct sockaddr *)&server, sizeof(server)) > 0) { - udpechoserver_log(SCRIT,"Error in bind function"); - return -1; - } - - udpechoserver_log(SINFO,"CONNECT UDPECHOSERVER"); - - while(true) - { - fromlen = sizeof(from); - n = recvfrom(sock, buf, 1024, 0, (struct sockaddr *)&from, (socklen_t *)&fromlen); - if (n < 0) - udpechoserver_log(SCRIT,"Error in receive message"); - - inet_ntop(AF_INET, &(from.sin_addr.s_addr), str, INET_ADDRSTRLEN); - udpechoserver_log(SINFO,"UDPECHOSERVER receive massage from %s with data size is %d Bytes", str, n); - - if(cur_udpechoserver_conf.address && cur_udpechoserver_conf.address[0] != '\0') { - if(strcmp(cur_udpechoserver_conf.address, str) != 0) { - udpechoserver_log(SINFO,"UDPECHOSERVER can not respond to a UDP echo from this source IP address %s", str); - continue; - } - } - - gettimeofday(&tv_recv, NULL); - if(cur_udpechoserver_result.TimeFirstPacketReceived.tv_sec == 0 && cur_udpechoserver_result.TimeFirstPacketReceived.tv_usec == 0) - cur_udpechoserver_result.TimeFirstPacketReceived = tv_recv; - cur_udpechoserver_result.TimeLastPacketReceived = tv_recv; - cur_udpechoserver_result.PacketsReceived++; - cur_udpechoserver_result.BytesReceived+=n; - (void) localtime_r(&(cur_udpechoserver_result.TimeFirstPacketReceived.tv_sec), <); - strftime(s_now, sizeof s_now, "%Y-%m-%dT%H:%M:%S", <); - sprintf(cur_udpechoserver_result.TimeFirstPacket,"%s.%06ld", s_now, (long) cur_udpechoserver_result.TimeFirstPacketReceived.tv_usec); - (void) localtime_r(&(cur_udpechoserver_result.TimeLastPacketReceived.tv_sec), <); - strftime(s_now, sizeof s_now, "%Y-%m-%dT%H:%M:%S", <); - sprintf(cur_udpechoserver_result.TimeLastPacket,"%s.%06ld", s_now, (long) cur_udpechoserver_result.TimeLastPacketReceived.tv_usec); - - if(cur_udpechoserver_conf.plus) { - if(n >= sizeof(struct udpechoserver_plus)) { - plus = (struct udpechoserver_plus *)buf; - plus->TestRespSN = htonl(cur_udpechoserver_result.TestRespSN); - plus->TestRespRecvTimeStamp = htonl(tv_recv.tv_sec*1000000+tv_recv.tv_usec); - plus->TestRespReplyFailureCount = htonl(cur_udpechoserver_result.TestRespReplyFailureCount); - gettimeofday(&tv_reply, NULL); - plus->TestRespReplyTimeStamp = htonl(tv_reply.tv_sec*1000000+tv_reply.tv_usec); - } - } - - ret = sendto(sock, buf, n, 0, (struct sockaddr *)&from, fromlen); - if (n != ret) { - cur_udpechoserver_result.TestRespReplyFailureCount++; - udpechoserver_log(SCRIT,"Error in send massage"); - } - else { - cur_udpechoserver_result.TestRespSN++; - cur_udpechoserver_result.PacketsResponded++; - cur_udpechoserver_result.BytesResponded+=ret; - } - udpechoserver_log(SINFO,"UDPECHOSERVER sent massage to %s with data size is %d Bytes", str, ret); - - set_udpechoserver_stats(); - - udpechoserver_log(SDEBUG,"UDPECHOSERVER Stats : PacketsReceived = %d", cur_udpechoserver_result.PacketsReceived); - udpechoserver_log(SDEBUG,"UDPECHOSERVER Stats : PacketsResponded = %d", cur_udpechoserver_result.PacketsResponded); - udpechoserver_log(SDEBUG,"UDPECHOSERVER Stats : BytesReceived = %d", cur_udpechoserver_result.BytesReceived); - udpechoserver_log(SDEBUG,"UDPECHOSERVER Stats : BytesResponded = %d", cur_udpechoserver_result.BytesResponded); - udpechoserver_log(SDEBUG,"UDPECHOSERVER Stats : TestRespReplyFailureCount = %d", cur_udpechoserver_result.TestRespReplyFailureCount); - udpechoserver_log(SDEBUG,"UDPECHOSERVER Stats : TimeFirstPacketReceived = %s", cur_udpechoserver_result.TimeFirstPacket); - udpechoserver_log(SDEBUG,"UDPECHOSERVER Stats : TimeLastPacketReceived = %s", cur_udpechoserver_result.TimeLastPacket); - } -} - -int udpechoserver_init(void) -{ - char *value = NULL; - int a; - - value = dmuci_get_value("udpechoserver", "udpechoserver", "log_level"); - if(value != NULL && *value != '\0') { - a = atoi(value); - cur_udpechoserver_conf.loglevel = a; - } - else - cur_udpechoserver_conf.loglevel = DEFAULT_LOGLEVEL; - udpechoserver_log(SDEBUG,"Log Level of UDP ECHO SERVER is :%d", cur_udpechoserver_conf.loglevel); - - value = dmuci_get_value("udpechoserver", "udpechoserver", "enable"); - if(value != NULL && *value != '\0') { - if ((strcasecmp(value,"true")==0) || (strcmp(value,"1")==0)) { - cur_udpechoserver_conf.enable = true; - udpechoserver_log(SDEBUG,"UDP echo server is Enabled"); - } - } - - value = dmuci_get_value("udpechoserver", "udpechoserver", "interface"); - if(value != NULL && *value != '\0') { - if (cur_udpechoserver_conf.interface != NULL) - free(cur_udpechoserver_conf.interface); - cur_udpechoserver_conf.interface = strdup(value); - udpechoserver_log(SDEBUG,"UDP echo server interface is :%s", cur_udpechoserver_conf.interface); - } - else { - cur_udpechoserver_conf.interface = strdup(""); - udpechoserver_log(SDEBUG,"UDP echo server interface is empty"); - } - - value = dmuci_get_value("udpechoserver", "udpechoserver", "address"); - if(value != NULL && *value != '\0') { - if (cur_udpechoserver_conf.address != NULL) - free(cur_udpechoserver_conf.address); - cur_udpechoserver_conf.address = strdup(value); - udpechoserver_log(SDEBUG,"UDP echo server address is :%s", cur_udpechoserver_conf.address); - } - else { - cur_udpechoserver_conf.address = strdup(""); - udpechoserver_log(SDEBUG,"UDP echo server address is empty"); - } - - value = dmuci_get_value("udpechoserver", "udpechoserver", "server_port"); - if(value != NULL && *value != '\0') { - a = atoi(value); - cur_udpechoserver_conf.server_port = a; - udpechoserver_log(SDEBUG,"UDP echo server port is :%d", cur_udpechoserver_conf.server_port); - } - - value = dmuci_get_value("udpechoserver", "udpechoserver", "plus"); - if(value != NULL && *value != '\0') { - if ((strcasecmp(value,"true")==0) || (strcmp(value,"1")==0)) { - cur_udpechoserver_conf.plus = true; - udpechoserver_log(SDEBUG,"UDP echo server plus is Enabled"); - } - else { - cur_udpechoserver_conf.plus = false; - udpechoserver_log(SDEBUG,"UDP echo server plus is Disabled"); - } - } - return 0; -} - -void udpechoserver_exit(void) -{ - free(cur_udpechoserver_conf.address); - free(cur_udpechoserver_conf.interface); -} - -int main(void) -{ - dmuci_init(); - udpechoserver_init(); - dmuci_fini(); - udpechoserver_log(SINFO,"START UDPECHOSERVER"); - - udpechoserver_connect(); - - udpechoserver_exit(); - udpechoserver_log(SINFO,"EXIT UDPECHOSERVER"); - return 0; -} diff --git a/udpechoserver/src/udpechoserver.h b/udpechoserver/src/udpechoserver.h deleted file mode 100644 index b51315226..000000000 --- a/udpechoserver/src/udpechoserver.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -*/ - -#ifndef _UDPECHOSERVER_H__ -#define _UDPECHOSERVER_H__ - -#include -#include - -#define default_date_format "AAAA-MM-JJTHH:MM:SS.000000Z" -#define default_date_size sizeof(default_date_format) + 1 - -struct udpechoserver_config -{ - bool enable; - char *interface; - char *address; - int server_port; - bool plus; - int loglevel; -}; - -struct udpechoserver_plus -{ - unsigned int TestGenSN; - unsigned int TestRespSN; - unsigned int TestRespRecvTimeStamp; - unsigned int TestRespReplyTimeStamp; - unsigned int TestRespReplyFailureCount; -}; - -struct udpechoserver_result -{ - unsigned int TestRespSN; - unsigned int TestRespReplyFailureCount; - unsigned int PacketsReceived; - unsigned int PacketsResponded; - unsigned int BytesReceived; - unsigned int BytesResponded; - struct timeval TimeFirstPacketReceived; - struct timeval TimeLastPacketReceived; - char TimeFirstPacket[default_date_size]; - char TimeLastPacket[default_date_size]; -}; - -extern struct udpechoserver_config cur_udpechoserver_conf; -extern struct udpechoserver_result cur_udpechoserver_result; - -#endif /* _UDPECHOSERVER_H__ */ diff --git a/udpechoserver/src/udpechoserver.md b/udpechoserver/src/udpechoserver.md deleted file mode 100644 index 3cd2beafc..000000000 --- a/udpechoserver/src/udpechoserver.md +++ /dev/null @@ -1,40 +0,0 @@ -# README # - -udpechoserverd is an implementation of udp echo server to perform the UDP Echo Service and UDP Echo Plus Service. - -## Configuration File ## - -The udpechoserverd UCI configuration is located in **'/etc/config/udpechoserver'** and contains only one section: **udpechoserver**. - -``` -config udpechoserver 'udpechoserver' - option enable '0' - option interface '' - option address '' - option server_port '' - option plus '0' - option log_level '3' -``` - -### udpechoserver section ### - -It defines **the udpechoserver configuration** such as enable, interface, address, etc... Possible options to be used in **the udpechoserver** section are listed in the table below. - -| Name | Type | Description | -| ------------- | ------- | ------------------------------------------------- | -| `enable` | boolean | If set to **1**, UDP Echo Server will be enabled. | -| `interface` | string | Specifies the interface on which the CPE MUST listen and receive UDP echo requests. | -| `address` | string | Specifies the source IP address which can make an UDP echo requests. | -| `server_port` | integer | The UDP port on which the UDP Echo server MUST listen and respond to UDP echo requests. | -| `plus` | boolean | If set to **1**, the CPE will perform necessary packet processing for UDP Echo Plus packets. | -| `log_level` | integer | Specifies the log type to use, by default it is set to **'INFO'**. The possible types are **'EMERG', 'ALERT', 'CRITIC' ,'ERROR', 'WARNING', 'NOTICE', 'INFO' and 'DEBUG'**. | - - -## Dependencies ## - -To successfully build udpechoserverd, the following libraries are needed: - -| Dependency | Link | License | -| ----------- | ------------------------------------------- | -------------- | -| libuci | https://git.openwrt.org/project/uci.git | LGPL 2.1 | - diff --git a/udpechoserver/src/udpechoserverlog.c b/udpechoserver/src/udpechoserverlog.c deleted file mode 100644 index 18949fe37..000000000 --- a/udpechoserver/src/udpechoserverlog.c +++ /dev/null @@ -1,55 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -*/ - -#include -#include -#include -#include -#include "udpechoserverlog.h" -#include "udpechoserver.h" -#define DEBUG - -static const int log_syslogmap[] = { - [SCRIT] = LOG_CRIT, - [SWARNING] = LOG_WARNING, - [SNOTICE] = LOG_NOTICE, - [SINFO] = LOG_INFO, - [SDEBUG] = LOG_DEBUG -}; - -static const char* log_str[] = { - [SCRIT] = "CRITICAL", - [SWARNING] = "WARNING", - [SNOTICE] = "NOTICE", - [SINFO] = "INFO", - [SDEBUG] = "DEBUG" -}; - -void udpechoserver_log(int priority, const char *format, ...) -{ - va_list vl; - - if (priority <= cur_udpechoserver_conf.loglevel) { -#ifdef DEBUG - time_t t = time(NULL); - struct tm tm = *localtime(&t); - va_start(vl, format); - printf("%d-%02d-%02d %02d:%02d:%02d [udpechoserver] %s - ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, log_str[priority]); - vprintf(format, vl); - va_end(vl); - printf("\n"); -#endif - openlog("udpechoserver", 0, LOG_DAEMON); - va_start(vl, format); - vsyslog(log_syslogmap[priority], format, vl); - va_end(vl); - closelog(); - } -} diff --git a/udpechoserver/src/udpechoserverlog.h b/udpechoserver/src/udpechoserverlog.h deleted file mode 100644 index c95c2d9a3..000000000 --- a/udpechoserver/src/udpechoserverlog.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -*/ - -#ifndef _UDPECHOSERVERLOG_H_ -#define _UDPECHOSERVERLOG_H_ - -#define DEFAULT_LOGLEVEL SINFO - -enum udpechoserver_log_level_enum { - SCRIT, - SWARNING, - SNOTICE, - SINFO, - SDEBUG, - __MAX_SLOG -}; - -void udpechoserver_log(int priority, const char *format, ...); - -#endif /* _UDPECHOSERVERLOG_H_ */ diff --git a/udpechoserver/src/udpechoserveruci.c b/udpechoserver/src/udpechoserveruci.c deleted file mode 100644 index 72b343b01..000000000 --- a/udpechoserver/src/udpechoserveruci.c +++ /dev/null @@ -1,182 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -*/ - -#include -#include -#include -#include "udpechoserveruci.h" - -static struct uci_context *uci_ctx = NULL; -static struct uci_context *uci_ctx_state = NULL; - -int dmuci_init(void) -{ - uci_ctx = uci_alloc_context(); - if (!uci_ctx) { - return -1; - } - uci_ctx_state = uci_alloc_context(); - if (!uci_ctx_state) { - return -1; - } - uci_add_delta_path(uci_ctx_state, uci_ctx_state->savedir); - uci_set_savedir(uci_ctx_state, VAR_STATE); - return 0; -} - -int dmuci_fini(void) -{ - if (uci_ctx) { - uci_free_context(uci_ctx); - } - if (uci_ctx_state) { - uci_free_context(uci_ctx_state); - } - uci_ctx = NULL; - uci_ctx_state = NULL; - return 0; -} - -static bool dmuci_validate_section(const char *str) -{ - if (!*str) - return false; - - for (; *str; str++) { - unsigned char c = *str; - - if (isalnum(c) || c == '_') - continue; - - return false; - } - return true; -} - -static int dmuci_init_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value) -{ - memset(ptr, 0, sizeof(struct uci_ptr)); - - /* value */ - if (value) { - ptr->value = value; - } - ptr->package = package; - if (!ptr->package) - goto error; - - ptr->section = section; - if (!ptr->section) { - ptr->target = UCI_TYPE_PACKAGE; - goto lastval; - } - - ptr->option = option; - if (!ptr->option) { - ptr->target = UCI_TYPE_SECTION; - goto lastval; - } else { - ptr->target = UCI_TYPE_OPTION; - } - -lastval: - if (ptr->section && !dmuci_validate_section(ptr->section)) - ptr->flags |= UCI_LOOKUP_EXTENDED; - - return 0; - -error: - return -1; -} - -void dmuci_print_list(struct uci_list *uh, char **val, char *delimiter) -{ - struct uci_element *e; - static char buffer[512]; - char *buf = buffer; - *buf = '\0'; - - uci_foreach_element(uh, e) { - if (*buf) { - strcat(buf, delimiter); - strcat(buf, e->name); - } - else { - strcpy(buf, e->name); - } - } - *val = buf; -} - -char *dmuci_get_value(char *package, char *section, char *option) -{ - struct uci_ptr ptr; - char *val = ""; - - if (!section || !option) - return val; - - if (dmuci_init_ptr(uci_ctx, &ptr, package, section, option, NULL)) { - return val; - } - if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK) { - return val; - } - - if (!ptr.o) - return val; - - if(ptr.o->type == UCI_TYPE_LIST) { - dmuci_print_list(&ptr.o->v.list, &val, " "); - return val; - } - - if (ptr.o->v.string) - return ptr.o->v.string; - else - return val; -} - -char *dmuci_set_value(char *package, char *section, char *option, char *value) -{ - struct uci_ptr ptr; - int ret = UCI_OK; - - if (!section) - return ""; - - if (dmuci_init_ptr(uci_ctx, &ptr, package, section, option, value)) { - return ""; - } - if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK) { - return ""; - } - - uci_set(uci_ctx, &ptr); - - if (ret == UCI_OK) - ret = uci_save(uci_ctx, ptr.p); - - if (ptr.o && ptr.o->v.string) - return ptr.o->v.string; - - return ""; -} - -/************************* /var/state ***************************/ -char *dmuci_set_value_state(char *package, char *section, char *option, char *value) -{ - char *val; - struct uci_context *save_uci_ctx = uci_ctx; - uci_ctx = uci_ctx_state; - val = dmuci_set_value(package, section, option, value); - uci_ctx = save_uci_ctx; - return val; -} diff --git a/udpechoserver/src/udpechoserveruci.h b/udpechoserver/src/udpechoserveruci.h deleted file mode 100644 index e2fb30091..000000000 --- a/udpechoserver/src/udpechoserveruci.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Copyright (C) 2020 iopsys Software Solutions AB -* Author: Amin Ben Ramdhane -*/ - -#ifndef _UDPECHOSERVERUCI_H__ -#define _UDPECHOSERVERUCI_H__ - -#include - -#define VAR_STATE "/var/state" - -int dmuci_init(void); -int dmuci_fini(void); -void dmuci_print_list(struct uci_list *uh, char **val, char *delimiter); -char *dmuci_get_value(char *package, char *section, char *option); -char *dmuci_set_value(char *package, char *section, char *option, char *value); -char *dmuci_set_value_state(char *package, char *section, char *option, char *value); - -#endif /* _UDPECHOSERVERUCI_H__ */