diff --git a/obuspa/Config.in b/obuspa/Config.in index b47685796..a9e975d91 100644 --- a/obuspa/Config.in +++ b/obuspa/Config.in @@ -1,3 +1,4 @@ +if PACKAGE_obuspa config OBUSPA_MTP_ENABLE_MQTT bool "Enable MQTT as mtp protocol" default y @@ -61,4 +62,4 @@ config OBUSPA_CWMP_DATAMODEL_SUPPORT help Expose Device.USPAgent., Device.STOMP., Device.MQTT.Client. objects over ubus to make it available to bbfdm for CWMP access - +endif diff --git a/obuspa/Makefile b/obuspa/Makefile index 597d7121a..7b7e5bea4 100644 --- a/obuspa/Makefile +++ b/obuspa/Makefile @@ -5,13 +5,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=obuspa -PKG_VERSION:=9.0.0.24 +PKG_VERSION:=9.0.4.1 LOCAL_DEV:=0 ifneq ($(LOCAL_DEV),1) PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/obuspa.git -PKG_SOURCE_VERSION:=2d48b1525f7a2b72b61da6ce4cb306a6aa52d4c8 +PKG_SOURCE_VERSION:=dc55cf10a8682c61b01acf45b9c0481173abbe5e PKG_MAINTAINER:=Vivek Dutta PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz PKG_MIRROR_HASH:=skip @@ -120,7 +120,6 @@ define Package/obuspa/install $(INSTALL_DATA) ./files/etc/config/obuspa $(1)/etc/config/ $(INSTALL_DATA) ./files/etc/users/roles/*.json $(1)/etc/users/roles/ $(INSTALL_DATA) ./files/etc/obuspa/usp_utils.sh $(1)/etc/obuspa/ - $(INSTALL_DATA) ./files/etc/obuspa/transient_dm.json $(1)/etc/obuspa/ echo "$(CONFIG_BBF_VENDOR_PREFIX)" > $(1)/etc/obuspa/vendor_prefix $(INSTALL_BIN) ./files/etc/uci-defaults/01-fix-upgrade-uci $(1)/etc/uci-defaults/ $(INSTALL_BIN) ./files/etc/uci-defaults/60-generate-ctrust-defaults $(1)/etc/uci-defaults/ diff --git a/obuspa/Readme.md b/obuspa/Readme.md new file mode 100644 index 000000000..d66c3389a --- /dev/null +++ b/obuspa/Readme.md @@ -0,0 +1,9 @@ +# Obuspa patch management + +As a part of obuspa integration, patch files used to manage changes in obuspa core files. + +| Patch series | Remarks | +| ------------ | ------- | +| 00 - series | Up-streamable features/bugs | +| 10 - series | ubus-integration optimizations | +| 20 - series | deployment specific | diff --git a/obuspa/files/etc/config/obuspa b/obuspa/files/etc/config/obuspa index a8faeaf7a..008368b7c 100644 --- a/obuspa/files/etc/config/obuspa +++ b/obuspa/files/etc/config/obuspa @@ -2,7 +2,7 @@ config obuspa 'global' option enabled '1' option debug '1' option dhcp_discovery '1' - option log_level '2' + option log_level '3' option prototrace '0' option db_file '/etc/obuspa/usp.db' #option max_group_sep '2' diff --git a/obuspa/files/etc/obuspa/transient_dm.json b/obuspa/files/etc/obuspa/transient_dm.json deleted file mode 100644 index 021e5d21a..000000000 --- a/obuspa/files/etc/obuspa/transient_dm.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dmcaching_exclude": [ - "Device.DeviceInfo.ProcessStatus.Process." - ] -} diff --git a/obuspa/patches/0020-fix_segfault_invalid_uds.patch b/obuspa/patches/0001-fix_segfault_invalid_uds.patch similarity index 100% rename from obuspa/patches/0020-fix_segfault_invalid_uds.patch rename to obuspa/patches/0001-fix_segfault_invalid_uds.patch diff --git a/obuspa/patches/0021-fix_e2e_session_init.patch b/obuspa/patches/0002-fix_e2e_session_init.patch similarity index 69% rename from obuspa/patches/0021-fix_e2e_session_init.patch rename to obuspa/patches/0002-fix_e2e_session_init.patch index ca60b99d6..2476b8d15 100644 --- a/obuspa/patches/0021-fix_e2e_session_init.patch +++ b/obuspa/patches/0002-fix_e2e_session_init.patch @@ -1,6 +1,8 @@ ---- a/src/core/device_controller.c -+++ b/src/core/device_controller.c -@@ -4282,6 +4282,14 @@ int ProcessControllerAdded(int cont_inst +Index: obuspa-9.0.0.25/src/core/device_controller.c +=================================================================== +--- obuspa-9.0.0.25.orig/src/core/device_controller.c ++++ obuspa-9.0.0.25/src/core/device_controller.c +@@ -4210,6 +4210,14 @@ int ProcessControllerAdded(int cont_inst goto exit; } @@ -15,7 +17,7 @@ // Exit if unable to get the object instance numbers present in this controller's MTP table USP_SNPRINTF(path, sizeof(path), "%s.%d.MTP", device_cont_root, cont_instance); err = DATA_MODEL_GetInstances(path, &iv); -@@ -4323,14 +4331,6 @@ int ProcessControllerAdded(int cont_inst +@@ -4251,14 +4259,6 @@ int ProcessControllerAdded(int cont_inst DEVICE_MQTT_UpdateControllerTopics(); #endif diff --git a/obuspa/patches/0002-supress-group-get-error.patch b/obuspa/patches/0002-supress-group-get-error.patch deleted file mode 100644 index 72b9de5ed..000000000 --- a/obuspa/patches/0002-supress-group-get-error.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/src/core/cli_server.c -+++ b/src/core/cli_server.c -@@ -785,10 +785,6 @@ int ExecuteCli_Get(char *arg1, char *arg - USP_ASSERT(gge->value != NULL); - SendCliResponse("%s => %s\n", gge->path, gge->value); - } -- else -- { -- SendCliResponse("ERROR: %d retrieving %s (%s)\n", gge->err_code, gge->path, gge->err_msg); -- } - } - - GROUP_GET_VECTOR_Destroy(&ggv); diff --git a/obuspa/patches/0010-Return-error-when-XSI-compliant-strerror_r-fails-in-.patch b/obuspa/patches/0003-Return-error-when-XSI-compliant-strerror_r-fails-in-.patch similarity index 100% rename from obuspa/patches/0010-Return-error-when-XSI-compliant-strerror_r-fails-in-.patch rename to obuspa/patches/0003-Return-error-when-XSI-compliant-strerror_r-fails-in-.patch diff --git a/obuspa/patches/0007-bdc_csv_format.patch b/obuspa/patches/0004-bulkdata_extn.patch similarity index 70% rename from obuspa/patches/0007-bdc_csv_format.patch rename to obuspa/patches/0004-bulkdata_extn.patch index 8d8fd3c75..ed2168212 100644 --- a/obuspa/patches/0007-bdc_csv_format.patch +++ b/obuspa/patches/0004-bulkdata_extn.patch @@ -1,18 +1,21 @@ +diff --git a/src/core/bdc_exec.c b/src/core/bdc_exec.c +index dc30a98..6a2938b 100644 --- a/src/core/bdc_exec.c +++ b/src/core/bdc_exec.c -@@ -548,11 +548,19 @@ int StartSendingReport(bdc_connection_t +@@ -548,10 +548,25 @@ int StartSendingReport(bdc_connection_t *bc) // Set the list of headers bc->headers = NULL; - bc->headers = curl_slist_append(bc->headers, "Content-Type: application/json; charset=UTF-8"); -- if (bc->flags & BDC_FLAG_HEADER_OBJ_HIER) +- bc->headers = curl_slist_append(bc->headers, "BBF-Report-Format: NameValuePair"); ++ ++ + if (bc->flags & BDC_FLAG_HEADER_OBJ_HIER) { + bc->headers = curl_slist_append(bc->headers, "Content-Type: application/json; charset=UTF-8"); - bc->headers = curl_slist_append(bc->headers, "BBF-Report-Format: ObjectHierarchy"); -- else ++ bc->headers = curl_slist_append(bc->headers, "BBF-Report-Format: ObjectHierarchy"); + } else if (bc->flags & BDC_FLAG_HEADER_NAME_VAL) { + bc->headers = curl_slist_append(bc->headers, "Content-Type: application/json; charset=UTF-8"); - bc->headers = curl_slist_append(bc->headers, "BBF-Report-Format: NameValuePair"); ++ bc->headers = curl_slist_append(bc->headers, "BBF-Report-Format: NameValuePair"); + } else if (bc->flags & BDC_FLAG_HEADER_PER_COL) { + bc->headers = curl_slist_append(bc->headers, "Content-Type: text/csv; charset=UTF-8"); + bc->headers = curl_slist_append(bc->headers, "BBF-Report-Format: ParameterPerColumn"); @@ -20,59 +23,69 @@ + bc->headers = curl_slist_append(bc->headers, "Content-Type: text/csv; charset=UTF-8"); + bc->headers = curl_slist_append(bc->headers, "BBF-Report-Format: ParameterPerRow"); + } - ++ if (bc->flags & BDC_FLAG_GZIP) { ++ curl_easy_setopt(curl_ctx, CURLOPT_ACCEPT_ENCODING, "gzip"); + bc->headers = curl_slist_append(bc->headers, "Content-Encoding: gzip"); + } + +diff --git a/src/core/bdc_exec.h b/src/core/bdc_exec.h +index 8c259c5..6322221 100644 --- a/src/core/bdc_exec.h +++ b/src/core/bdc_exec.h -@@ -53,6 +53,9 @@ void BDC_EXEC_ScheduleExit(void); +@@ -53,6 +53,8 @@ void BDC_EXEC_ScheduleExit(void); #define BDC_FLAG_PUT 0x00000001 // If set, HTTP PUT should be used instead of HTTP POST when sending the report to the BDC server #define BDC_FLAG_GZIP 0x00000002 // If set, the reports contants are Gzipped #define BDC_FLAG_DATE_HEADER 0x00000004 // If set, the date header should be included in the HTTP post. --#define BDC_FLAG_HEADER_OBJ_HIER 0x00000008 // If set, report format in header would be ObjectHierarchy otherwise NameValuePair +- +- +#define BDC_FLAG_HEADER_OBJ_HIER 0x00000008 // If set, report format in header would be json ObjectHierarchy +#define BDC_FLAG_HEADER_NAME_VAL 0x00000010 // If set, report format in header would be json NameValuePair +#define BDC_FLAG_HEADER_PER_ROW 0x00000020 // If set, report format in header would be csv ParameterPerRow +#define BDC_FLAG_HEADER_PER_COL 0x00000040 // If set, report format in header would be csv ParameterPerColumn - #endif +diff --git a/src/core/device_bulkdata.c b/src/core/device_bulkdata.c +index 915b282..f799793 100755 --- a/src/core/device_bulkdata.c +++ b/src/core/device_bulkdata.c -@@ -70,9 +70,12 @@ +@@ -70,8 +70,12 @@ //------------------------------------------------------------------------------ // Definitions for formats that we support -#define BULKDATA_ENCODING_TYPE "JSON" +-#define BULKDATA_JSON_REPORT_FORMAT "NameValuePair" +#define BULKDATA_ENCODING_TYPE_JSON "JSON" +#define BULKDATA_ENCODING_TYPE_CSV "CSV" - #define BULKDATA_JSON_REPORT_FORMAT_NAME_VALUE "NameValuePair" - #define BULKDATA_JSON_REPORT_FORMAT_OBJ_HIER "ObjectHierarchy" ++#define BULKDATA_JSON_REPORT_FORMAT_NAME_VALUE "NameValuePair" ++#define BULKDATA_JSON_REPORT_FORMAT_OBJ_HIER "ObjectHierarchy" +#define BULKDATA_CSV_REPORT_FORMAT_PER_COLUMN "ParameterPerColumn" +#define BULKDATA_CSV_REPORT_FORMAT_PER_ROW "ParameterPerRow" // Definitions for Device.BulkData.Profile.{i}.JSONEncoding.ReportTimestamp -@@ -156,6 +159,7 @@ static char *profile_push_event_args[] = +@@ -161,6 +165,7 @@ static char *profile_push_event_args[] = typedef struct { int num_retained_failed_reports; + char encoding_type[10]; - char report_timestamp[33]; - char url[1025]; - char username[257]; -@@ -164,6 +168,11 @@ typedef struct + #ifdef ENABLE_MQTT + char mqtt_reference[254]; // relates to Device.BulkData.Profile.{i}.MQTT.Reference + char mqtt_publish_topic[254]; // relates to Device.BulkData.Profile.{i}.MQTT.PublishTopic +@@ -171,6 +176,12 @@ typedef struct + char password[257]; + char compression[9]; char method[9]; - bool use_date_header; - char report_format[20]; ++ char report_format[20]; + char field_separator[10]; + char row_separator[10]; + char escape_char[10]; + char csv_format[20]; + char row_timestamp[33]; + bool use_date_header; } profile_ctrl_params_t; - //------------------------------------------------------------------------------ -@@ -211,6 +220,7 @@ int Validate_BulkDataEncodingType(dm_req +@@ -219,6 +230,7 @@ int Validate_BulkDataEncodingType(dm_req_t *req, char *value); int Validate_BulkDataReportingInterval(dm_req_t *req, char *value); int Validate_BulkDataReference(dm_req_t *req, char *value); int Validate_BulkDataReportFormat(dm_req_t *req, char *value); @@ -80,25 +93,26 @@ int Validate_BulkDataReportTimestamp(dm_req_t *req, char *value); int Validate_BulkDataCompression(dm_req_t *req, char *value); int Validate_BulkDataHTTPMethod(dm_req_t *req, char *value); -@@ -239,6 +249,8 @@ bulkdata_profile_t *bulkdata_find_profil +@@ -246,7 +258,8 @@ bulkdata_profile_t *bulkdata_find_free_profile(void); + bulkdata_profile_t *bulkdata_find_profile(int profile_id); int bulkdata_calc_report_map(bulkdata_profile_t *bp, kv_vector_t *report_map); int bulkdata_reduce_to_alt_name(char *spec, char *path, char *alt_name, char *out_buf, int buf_len); - char *bulkdata_generate_json_report(bulkdata_profile_t *bp, char *report_timestamp, char *report_format); -+char *bulkdata_generate_csv_report(bulkdata_profile_t *bp, char *field_separator, char *row_separator, -+ char *escape_char, char *csv_format, char *row_timestamp); +-char *bulkdata_generate_json_report(bulkdata_profile_t *bp, char *report_timestamp); ++char *bulkdata_generate_json_report(bulkdata_profile_t *bp, char *report_timestamp, char *report_format); ++char *bulkdata_generate_csv_report(bulkdata_profile_t *bp, char *field_separator, char *row_separator, char *escape_char, char *csv_format, char *row_timestamp); unsigned char *bulkdata_compress_report(profile_ctrl_params_t *ctrl, char *input_buf, int input_len, int *p_output_len); int bulkdata_schedule_sending_http_report(profile_ctrl_params_t *ctrl, bulkdata_profile_t *bp, unsigned char *json_report, int report_len); int bulkdata_start_profile(bulkdata_profile_t *bp); -@@ -253,6 +265,8 @@ char *bulkdata_platform_calc_uri_query_s +@@ -261,6 +274,8 @@ char *bulkdata_platform_calc_uri_query_string(kv_vector_t *escaped_map); int bulkdata_platform_get_param_refs(int profile_id, param_ref_vector_t *param_refs); void bulkdata_expand_param_ref(param_ref_entry_t *pr, group_get_vector_t *ggv); void bulkdata_append_to_result_map(param_ref_entry_t *pr, group_get_vector_t *ggv, kv_vector_t *report_map); +void append_string_to_target(char *str, char **output); +char *csv_encode(const char *str); - - /*********************************************************************//** - ** -@@ -285,7 +299,7 @@ int DEVICE_BULKDATA_Init(void) + #ifdef ENABLE_MQTT + int Validate_BulkDataMqttReference(dm_req_t *req, char *value); + void bulkdata_process_profile_mqtt(bulkdata_profile_t *bp); +@@ -298,7 +313,7 @@ int DEVICE_BULKDATA_Init(void) err |= USP_REGISTER_VendorParam_ReadOnly("Device.BulkData.Status", Get_BulkDataGlobalStatus, DM_STRING); err |= USP_REGISTER_Param_Constant("Device.BulkData.MinReportingInterval", BULKDATA_MINIMUM_REPORTING_INTERVAL_STR, DM_UINT); err |= USP_REGISTER_Param_SupportedList("Device.BulkData.Protocols", bdc_protocols, NUM_ELEM(bdc_protocols)); @@ -107,7 +121,7 @@ err |= USP_REGISTER_Param_Constant("Device.BulkData.ParameterWildCardSupported", "true", DM_BOOL); err |= USP_REGISTER_Param_Constant("Device.BulkData.MaxNumberOfProfiles", BULKDATA_MAX_PROFILES_STR, DM_INT); err |= USP_REGISTER_Param_Constant("Device.BulkData.MaxNumberOfParameterReferences", "-1", DM_INT); -@@ -300,7 +314,7 @@ int DEVICE_BULKDATA_Init(void) +@@ -313,7 +328,7 @@ int DEVICE_BULKDATA_Init(void) err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.Name", "", NULL, NULL, DM_STRING); err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.NumberOfRetainedFailedReports", "0", Validate_NumberOfRetainedFailedReports, NULL, DM_INT); err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.Protocol", BULKDATA_PROTOCOL_HTTP, Validate_BulkDataProtocol, NULL, DM_STRING); @@ -116,8 +130,12 @@ err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.ReportingInterval", "86400", Validate_BulkDataReportingInterval, NotifyChange_BulkDataReportingInterval, DM_UINT); err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.TimeReference", UNKNOWN_TIME_STR, NULL, NotifyChange_BulkDataTimeReference, DM_DATETIME); -@@ -315,6 +329,13 @@ int DEVICE_BULKDATA_Init(void) - err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.JSONEncoding.ReportFormat", BULKDATA_JSON_REPORT_FORMAT_NAME_VALUE, Validate_BulkDataReportFormat, NULL, DM_STRING); +@@ -325,9 +340,16 @@ int DEVICE_BULKDATA_Init(void) + err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.Parameter.{i}.Reference", "", Validate_BulkDataReference, NULL, DM_STRING); + + // Device.BulkData.Profile.{i}.JSONEncoding +- err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.JSONEncoding.ReportFormat", BULKDATA_JSON_REPORT_FORMAT, Validate_BulkDataReportFormat, NULL, DM_STRING); ++ err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.JSONEncoding.ReportFormat", BULKDATA_JSON_REPORT_FORMAT_NAME_VALUE, Validate_BulkDataReportFormat, NULL, DM_STRING); err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.JSONEncoding.ReportTimestamp", BULKDATA_JSON_TIMESTAMP_FORMAT_EPOCH, Validate_BulkDataReportTimestamp, NULL, DM_STRING); + // Device.BulkData.Profile.{i}.CSVEncoding @@ -130,23 +148,37 @@ // Device.BulkData.Profile.{i}.HTTP err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.HTTP.URL", "", NULL, NotifyChange_BulkDataURL, DM_STRING); err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.HTTP.Username", "", NULL, NULL, DM_STRING); -@@ -594,9 +615,10 @@ int Validate_BulkDataProtocol(dm_req_t * +@@ -613,9 +635,10 @@ int Validate_BulkDataProtocol(dm_req_t *req, char *value) int Validate_BulkDataEncodingType(dm_req_t *req, char *value) { // Exit if trying to set a value outside of the range we accept - if (strcmp(value, BULKDATA_ENCODING_TYPE) != 0) -+ if (strcmp(value, BULKDATA_ENCODING_TYPE_JSON) != 0 && strcmp(value, BULKDATA_ENCODING_TYPE_CSV) != 0) - { +- { - USP_ERR_SetMessage("%s: Only EncodingType supported is '%s'", __FUNCTION__, BULKDATA_ENCODING_TYPE); ++ if (strcmp(value, BULKDATA_ENCODING_TYPE_JSON) != 0 && strcmp(value, BULKDATA_ENCODING_TYPE_CSV) != 0) ++ { + USP_ERR_SetMessage("%s: Only EncodingType supported are '%s,%s'", __FUNCTION__, + BULKDATA_ENCODING_TYPE_JSON, BULKDATA_ENCODING_TYPE_CSV); return USP_ERR_INVALID_VALUE; } -@@ -713,6 +735,32 @@ int Validate_BulkDataReportFormat(dm_req - - /*********************************************************************//** - ** +@@ -719,9 +742,36 @@ int Validate_BulkDataReference(dm_req_t *req, char *value) + int Validate_BulkDataReportFormat(dm_req_t *req, char *value) + { + // Exit if trying to set a value outside of the range we accept +- if (strcmp(value, BULKDATA_JSON_REPORT_FORMAT) != 0) ++ if (strcmp(value, BULKDATA_JSON_REPORT_FORMAT_NAME_VALUE) != 0 && ++ strcmp(value, BULKDATA_JSON_REPORT_FORMAT_OBJ_HIER) != 0) ++ { ++ USP_ERR_SetMessage("%s: Supported JSON Report Formats are '%s', '%s'", __FUNCTION__, BULKDATA_JSON_REPORT_FORMAT_NAME_VALUE, BULKDATA_JSON_REPORT_FORMAT_OBJ_HIER); ++ return USP_ERR_INVALID_VALUE; ++ } ++ ++ return USP_ERR_OK; ++} ++ ++/*********************************************************************//** ++** +** Validate_BulkDataCSVReportFormat +** +** Validates Device.BulkData.Profile.{i}.CSVEncoding.ReportFormat @@ -162,21 +194,14 @@ + // Exit if trying to set a value outside of the range we accept + if (strcmp(value, BULKDATA_CSV_REPORT_FORMAT_PER_COLUMN) != 0 && + strcmp(value, BULKDATA_CSV_REPORT_FORMAT_PER_ROW) != 0) -+ { + { +- USP_ERR_SetMessage("%s: Only JSON Report Format supported is '%s'", __FUNCTION__, BULKDATA_JSON_REPORT_FORMAT); + USP_ERR_SetMessage("%s: Only JSON Report Format supported are '%s', '%s'", __FUNCTION__, + BULKDATA_CSV_REPORT_FORMAT_PER_COLUMN, BULKDATA_CSV_REPORT_FORMAT_PER_ROW); -+ return USP_ERR_INVALID_VALUE; -+ } -+ -+ return USP_ERR_OK; -+} -+ -+/*********************************************************************//** -+** - ** Validate_BulkDataReportTimestamp - ** - ** Validates Device.BulkData.Profile.{i}.JSONEncoding.ReportTimestamp -@@ -2004,6 +2052,14 @@ int bulkdata_platform_get_profile_contro + return USP_ERR_INVALID_VALUE; + } + +@@ -2052,6 +2102,14 @@ int bulkdata_platform_get_profile_control_params(bulkdata_profile_t *bp, profile return err; } @@ -191,7 +216,7 @@ // Exit if unable to get ReportTimestamp USP_SNPRINTF(path, sizeof(path), "Device.BulkData.Profile.%d.JSONEncoding.ReportTimestamp", bp->profile_id); err = DATA_MODEL_GetParameterValue(path, ctrl_params->report_timestamp, sizeof(ctrl_params->report_timestamp), 0); -@@ -2020,6 +2076,46 @@ int bulkdata_platform_get_profile_contro +@@ -2060,6 +2118,54 @@ int bulkdata_platform_get_profile_control_params(bulkdata_profile_t *bp, profile return err; } @@ -235,10 +260,18 @@ + return err; + } + - return USP_ERR_OK; - } - -@@ -2256,7 +2352,7 @@ void bulkdata_process_profile_http(bulkd ++ // Exit if unable to get ReportFormat ++ USP_SNPRINTF(path, sizeof(path), "Device.BulkData.Profile.%d.JSONEncoding.ReportFormat", bp->profile_id); ++ err = DATA_MODEL_GetParameterValue(path, ctrl_params->report_format, sizeof(ctrl_params->report_format), 0); ++ if (err != USP_ERR_OK) ++ { ++ return err; ++ } ++ + #ifdef ENABLE_MQTT + { + char protocol[32]; +@@ -2333,7 +2439,7 @@ void bulkdata_process_profile_http(bulkdata_profile_t *bp) { int err; report_t *cur_report; @@ -247,11 +280,11 @@ profile_ctrl_params_t ctrl; unsigned char *compressed_report; int compressed_len; -@@ -2295,10 +2391,23 @@ void bulkdata_process_profile_http(bulkd +@@ -2372,10 +2478,23 @@ void bulkdata_process_profile_http(bulkdata_profile_t *bp) } // Exit if unable to generate the report -- json_report = bulkdata_generate_json_report(bp, ctrl.report_timestamp, ctrl.report_format); +- json_report = bulkdata_generate_json_report(bp, ctrl.report_timestamp); - if (json_report == NULL) - { - USP_ERR_SetMessage("%s: bulkdata_generate_json_report failed", __FUNCTION__); @@ -275,7 +308,7 @@ return; } -@@ -2307,14 +2416,14 @@ void bulkdata_process_profile_http(bulkd +@@ -2384,14 +2503,14 @@ void bulkdata_process_profile_http(bulkdata_profile_t *bp) USP_LOG_Info("BULK DATA: using compression method=%s", ctrl.compression); if (enable_protocol_trace) { @@ -294,15 +327,15 @@ } // NOTE: From this point on, only the compressed_report exists -@@ -2344,9 +2453,15 @@ void bulkdata_process_profile_usp_event( +@@ -2421,8 +2540,15 @@ void bulkdata_process_profile_usp_event(bulkdata_profile_t *bp) kv_vector_t event_args; kv_pair_t kv; report_t *cur_report; - char *json_report; + char report_timestamp[33]; ++ char report_format[20]; + char *report; + char encoding_type[10] = {0}; - char report_timestamp[33] = {0}; - char report_format[20] = {0}; + char field_separator[10]; + char row_separator[10]; + char escape_char[10]; @@ -311,7 +344,7 @@ // Exit if the MTP has not been connected to successfully after bootup // This is to prevent BDC events being enqueued before the Boot! event is sent (the Boot! event is only sent after successfully connecting to the MTP). -@@ -2355,20 +2470,62 @@ void bulkdata_process_profile_usp_event( +@@ -2431,13 +2557,63 @@ void bulkdata_process_profile_usp_event(bulkdata_profile_t *bp) goto exit; } @@ -320,19 +353,15 @@ - err = DATA_MODEL_GetParameterValue(path, report_timestamp, sizeof(report_timestamp), 0); - if (err != USP_ERR_OK) - { +- return; +- } + // Exit if unable to get EncodingType + USP_SNPRINTF(path, sizeof(path), "Device.BulkData.Profile.%d.EncodingType", bp->profile_id); + err = DATA_MODEL_GetParameterValue(path, encoding_type, sizeof(encoding_type), 0); + if (err != USP_ERR_OK) { - return; - } - -- // Exit if unable to get ReportFormat -- USP_SNPRINTF(path, sizeof(path), "Device.BulkData.Profile.%d.JSONEncoding.ReportFormat", bp->profile_id); -- err = DATA_MODEL_GetParameterValue(path, report_format, sizeof(report_format), 0); -- if (err != USP_ERR_OK) -- { -- return; ++ return; ++ } ++ + if (strcmp(encoding_type, BULKDATA_ENCODING_TYPE_JSON) == 0) { + // Exit if unable to get ReportTimestamp + USP_SNPRINTF(path, sizeof(path), "Device.BulkData.Profile.%d.JSONEncoding.ReportTimestamp", bp->profile_id); @@ -382,15 +411,14 @@ + if (err != USP_ERR_OK) { + return; + } - } ++ } // When sending via USP events, only one report is ever sent in each USP event -@@ -2388,10 +2545,16 @@ void bulkdata_process_profile_usp_event( + // So ensure all retained reports are removed. NOTE: Clearing the reports here is only necessary when switching protocol from HTTP to USP event, and where HTTP had some unsent reports +@@ -2455,11 +2631,17 @@ void bulkdata_process_profile_usp_event(bulkdata_profile_t *bp) + } bp->num_retained_reports = 1; - // Exit if unable to generate the report -- json_report = bulkdata_generate_json_report(bp, report_timestamp, report_format); -- if (json_report == NULL) + if (strcmp(encoding_type, BULKDATA_ENCODING_TYPE_JSON) == 0) { + report = bulkdata_generate_json_report(bp, report_timestamp, report_format); + } else { @@ -398,14 +426,17 @@ + csv_format, row_timestamp); + } + + // Exit if unable to generate the report +- json_report = bulkdata_generate_json_report(bp, report_timestamp); +- if (json_report == NULL) + if (report == NULL) { - USP_ERR_SetMessage("%s: bulkdata_generate_json_report failed", __FUNCTION__); -+ USP_ERR_SetMessage("%s: bulkdata failed to generate report", __FUNCTION__); ++ USP_ERR_SetMessage("%s: bulkdata_generate_report failed", __FUNCTION__); return; } -@@ -2399,15 +2562,15 @@ void bulkdata_process_profile_usp_event( +@@ -2467,15 +2649,15 @@ void bulkdata_process_profile_usp_event(bulkdata_profile_t *bp) // Construct event_args manually to avoid the overhead of a malloc and copy of the report in KV_VECTOR_Add() kv.key = "Data"; @@ -424,10 +455,194 @@ // From the point of view of this code, the report(s) have been successfully sent, so don't retain them // NOTE: Sending of the reports successfully is delegated to the USP notification retry mechanism -@@ -2869,6 +3032,319 @@ char *bulkdata_generate_json_report(bulk +@@ -2547,7 +2729,7 @@ void bulkdata_process_profile_mqtt(bulkdata_profile_t *bp) + } - /*********************************************************************//** + // Exit if unable to generate the report +- report = bulkdata_generate_json_report(bp, ctrl.report_timestamp); ++ report = bulkdata_generate_json_report(bp, ctrl.report_timestamp, ctrl.report_format); + if (report == NULL) + { + USP_ERR_SetMessage("%s: bulkdata_generate_json_report failed", __FUNCTION__); +@@ -2762,7 +2944,7 @@ int bulkdata_reduce_to_alt_name(char *spec, char *path, char *alt_name, char *ou + ** \return pointer to NULL terminated dynamically allocated buffer containing the serialized report to send ** + **************************************************************************/ +-char *bulkdata_generate_json_report(bulkdata_profile_t *bp, char *report_timestamp) ++char *bulkdata_generate_json_name_value_pair_report(bulkdata_profile_t *bp, char *report_timestamp) + { + JsonNode *top; // top of report + JsonNode *array; // array of reports (retained + current) +@@ -2867,6 +3049,483 @@ char *bulkdata_generate_json_report(bulkdata_profile_t *bp, char *report_timesta + return result; + } + ++static char *create_json_obj_hier_report(bulkdata_profile_t *bp, char *report_timestamp) ++{ ++ JsonNode *top; // top of report ++ JsonNode *array; // array of reports (retained + current) ++ JsonNode *element; // element of json array, containing an individual report ++ JsonNode *temp; ++ char *param_path; ++ char *param_type_value; ++ char param_type; ++ char *param_value; ++ kv_vector_t *report_map; ++ report_t *report; ++ double value_as_number; ++ long long value_as_ll; ++ unsigned long long value_as_ull; ++ bool value_as_bool; ++ int i, j; ++ char buf[32]; ++ kv_pair_t *kv; ++ int err; ++ char *result; ++ ++ top = json_mkobject(); ++ array = json_mkarray(); ++ ++ // Iterate over all reports adding them to the JSON array ++ for (i=0; i < bp->num_retained_reports; i++) ++ { ++ report = &bp->reports[i]; ++ report_map = &report->report_map; ++ ++ // Add Collection time to each json report element (only if specified and not 'None') ++ element = json_mkobject(); ++ if (strcmp(report_timestamp, "Unix-Epoch")==0) ++ { ++ json_append_member(element, "CollectionTime", json_mknumber(report->collection_time)); ++ } ++ else if (strcmp(report_timestamp, "ISO-8601")==0) ++ { ++ result = iso8601_from_unix_time(report->collection_time, buf, sizeof(buf)); ++ if (result != NULL) ++ { ++ json_append_member(element, "CollectionTime", json_mkstring(buf)); ++ } ++ } ++ ++ temp = element; ++ // Iterate over each parameter, adding it to the json element. Take account of the parameter's type ++ for (j=0; j < report_map->num_entries; j++) ++ { ++ char buff[2056] = {0}; ++ char *pch = NULL, *pchr = NULL, *argv[128] = {0}; ++ int n = 0; ++ ++ kv = &report_map->vector[j]; ++ param_path = kv->key; ++ param_type_value = kv->value; ++ param_type = param_type_value[0]; // First character denotes the type of the parameter ++ param_value = ¶m_type_value[1]; // Subsequent characters contain the parameter's value ++ ++ strncpy(buff, param_path, sizeof(buff)); ++ for (pch = strtok_r(buff, ".", &pchr); pch != NULL; pch = strtok_r(NULL, ".", &pchr)) { ++ int idx; ++ JsonNode *obj = element; ++ argv[n] = pch; ++ ++ for (idx = 0; idx <= n; idx++) { ++ if (obj == NULL) ++ break; ++ obj = json_find_member(obj, argv[idx]); ++ } ++ ++ if (obj) ++ temp = obj; ++ else { ++ if (pchr != NULL && *pchr != '\0') { ++ // It is a DMOBJ ++ JsonNode *new = json_mkobject(); ++ json_append_member(temp, pch, new); ++ temp = new; ++ } else { ++ // It is a DMPARAM ++ switch (param_type) ++ { ++ case 'S': ++ json_append_member(temp, pch, json_mkstring(param_value) ); ++ break; ++ ++ case 'U': ++ value_as_ull = strtoull(param_value, NULL, 10); ++ json_append_member(temp, pch, json_mkulonglong(value_as_ull) ); ++ break; ++ ++ case 'L': ++ value_as_ll = strtoll(param_value, NULL, 10); ++ json_append_member(temp, pch, json_mklonglong(value_as_ll) ); ++ break; ++ ++ case 'N': ++ value_as_number = atof(param_value); ++ json_append_member(temp, pch, json_mknumber(value_as_number) ); ++ break; ++ ++ case 'B': ++ err = TEXT_UTILS_StringToBool(param_value, &value_as_bool); ++ if (err == USP_ERR_OK) ++ { ++ json_append_member(temp, pch, json_mkbool(value_as_bool) ); ++ } ++ break; ++ ++ default: ++ USP_ERR_SetMessage("%s: Invalid JSON parameter type ('%c') in report map for %s", __FUNCTION__, param_type_value[0], param_path); ++ break; ++ } ++ } ++ } ++ n++; ++ } ++ } ++ ++ // Add the json element to the json array ++ json_append_element(array, element); ++ } ++ ++ // Finally add the array to the report top level ++ json_append_member(top, "Report", array); ++ ++ // Serialize the JSON tree ++ result = json_stringify(top, " "); ++ ++ // Clean up the JSON tree ++ json_delete(top); // Other JsonNodes which are children of this top level tree will be deleted ++ ++ return result; ++} ++ ++/*********************************************************************//** ++** ++** bulkdata_generate_json_report ++** ++** Generates a JSON name-value pair or object-hierarchy format report ++** NOTE: The report contains all retained failed reports, as well as the current report ++** See TR-157 section A.4.2 (end) for an example, and section A.3.5.2 for layout of content containing failed report transmissions ++** ++** \param bp - pointer to bulk data profile containing all reports (current and retained) ++** \param report_timestamp - value of Device.BulkData.Profile.{i}.JSONEncoding.ReportTimestamp ++** ++** \return pointer to NULL terminated dynamically allocated buffer containing the serialized report to send ++** ++**************************************************************************/ ++char *bulkdata_generate_json_report(bulkdata_profile_t *bp, char *report_timestamp, char *report_format) ++{ ++ char *result = NULL; ++ ++ if (strcmp(report_format, BULKDATA_JSON_REPORT_FORMAT_NAME_VALUE) == 0) { ++ result = bulkdata_generate_json_name_value_pair_report(bp, report_timestamp); ++ } else if (strcmp(report_format, BULKDATA_JSON_REPORT_FORMAT_OBJ_HIER) == 0) { ++ result = create_json_obj_hier_report(bp, report_timestamp); ++ } ++ ++ return result; ++} ++ ++/*********************************************************************//** ++** +** safe_asprintf +** +** Wrapper around asprintf that calls terminate in case of error @@ -739,18 +954,13 @@ + return output; +} + -+/*********************************************************************//** -+** - ** bulkdata_compress_report + /*********************************************************************//** ** - ** Compresses the report to send -@@ -3020,9 +3496,18 @@ int bulkdata_schedule_sending_http_repor + ** bulkdata_compress_report +@@ -3070,6 +3729,20 @@ int bulkdata_schedule_sending_http_report(profile_ctrl_params_t *ctrl, bulkdata_ flags |= BDC_FLAG_DATE_HEADER; } -- if (strcmp(ctrl->report_format, BULKDATA_JSON_REPORT_FORMAT_OBJ_HIER) == 0) -- { -- flags |= BDC_FLAG_HEADER_OBJ_HIER; + if (strcmp(ctrl->encoding_type, BULKDATA_ENCODING_TYPE_JSON) == 0) { + if (strcmp(ctrl->report_format, BULKDATA_JSON_REPORT_FORMAT_OBJ_HIER) == 0) { + flags |= BDC_FLAG_HEADER_OBJ_HIER; @@ -763,6 +973,8 @@ + } else { + flags |= BDC_FLAG_HEADER_PER_ROW; + } - } - ++ } ++ // Exit if failed to post a message to BDC thread + // NOTE: Ownership of full_url, query_string, report, username and password passes to BDC_EXEC + err = BDC_EXEC_PostReportToSend(bp->profile_id, full_url, query_string, username, password, report, report_len, flags); diff --git a/obuspa/patches/0005-optimise_ubus_calls_cli.patch b/obuspa/patches/0005-optimise_ubus_calls_cli.patch deleted file mode 100644 index d9ea9de66..000000000 --- a/obuspa/patches/0005-optimise_ubus_calls_cli.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/src/core/data_model.c -+++ b/src/core/data_model.c -@@ -160,6 +160,7 @@ int SetVendorParam(dm_node_t *node, char - double_link_t *FindLinkToFirstObject(double_linked_list_t *list); - int OverrideNodeType(dm_node_t *node, dm_node_type_t type, char *schema_path, dm_instances_t *inst); - -+extern bool is_running_cli_local_command; - /*********************************************************************//** - ** - ** DATA_MODEL_Init -@@ -267,7 +268,9 @@ int DATA_MODEL_Init(void) - } - - // Set the default values of OUI, Serial Number and (LocalAgent) EndpointID, and cache EndpointID -+ if (is_running_cli_local_command == false) { - err = DEVICE_LOCAL_AGENT_SetDefaults(); -+ } - if (err != USP_ERR_OK) - { - return err; diff --git a/obuspa/patches/0006-bdc_json_obj_hierarchy.patch b/obuspa/patches/0006-bdc_json_obj_hierarchy.patch deleted file mode 100644 index 510ebe375..000000000 --- a/obuspa/patches/0006-bdc_json_obj_hierarchy.patch +++ /dev/null @@ -1,366 +0,0 @@ ---- a/src/core/bdc_exec.c -+++ b/src/core/bdc_exec.c -@@ -549,9 +549,14 @@ int StartSendingReport(bdc_connection_t - // Set the list of headers - bc->headers = NULL; - bc->headers = curl_slist_append(bc->headers, "Content-Type: application/json; charset=UTF-8"); -- bc->headers = curl_slist_append(bc->headers, "BBF-Report-Format: NameValuePair"); -+ if (bc->flags & BDC_FLAG_HEADER_OBJ_HIER) -+ bc->headers = curl_slist_append(bc->headers, "BBF-Report-Format: ObjectHierarchy"); -+ else -+ bc->headers = curl_slist_append(bc->headers, "BBF-Report-Format: NameValuePair"); -+ - if (bc->flags & BDC_FLAG_GZIP) - { -+ curl_easy_setopt(curl_ctx, CURLOPT_ACCEPT_ENCODING, "gzip"); - bc->headers = curl_slist_append(bc->headers, "Content-Encoding: gzip"); - } - ---- a/src/core/bdc_exec.h -+++ b/src/core/bdc_exec.h -@@ -53,6 +53,6 @@ void BDC_EXEC_ScheduleExit(void); - #define BDC_FLAG_PUT 0x00000001 // If set, HTTP PUT should be used instead of HTTP POST when sending the report to the BDC server - #define BDC_FLAG_GZIP 0x00000002 // If set, the reports contants are Gzipped - #define BDC_FLAG_DATE_HEADER 0x00000004 // If set, the date header should be included in the HTTP post. -- -+#define BDC_FLAG_HEADER_OBJ_HIER 0x00000008 // If set, report format in header would be ObjectHierarchy otherwise NameValuePair - - #endif ---- a/src/core/device_bulkdata.c -+++ b/src/core/device_bulkdata.c -@@ -71,7 +71,8 @@ - //------------------------------------------------------------------------------ - // Definitions for formats that we support - #define BULKDATA_ENCODING_TYPE "JSON" --#define BULKDATA_JSON_REPORT_FORMAT "NameValuePair" -+#define BULKDATA_JSON_REPORT_FORMAT_NAME_VALUE "NameValuePair" -+#define BULKDATA_JSON_REPORT_FORMAT_OBJ_HIER "ObjectHierarchy" - - - // Definitions for Device.BulkData.Profile.{i}.JSONEncoding.ReportTimestamp -@@ -162,6 +163,7 @@ typedef struct - char compression[9]; - char method[9]; - bool use_date_header; -+ char report_format[20]; - } profile_ctrl_params_t; - - //------------------------------------------------------------------------------ -@@ -236,7 +238,7 @@ bulkdata_profile_t *bulkdata_find_free_p - bulkdata_profile_t *bulkdata_find_profile(int profile_id); - int bulkdata_calc_report_map(bulkdata_profile_t *bp, kv_vector_t *report_map); - int bulkdata_reduce_to_alt_name(char *spec, char *path, char *alt_name, char *out_buf, int buf_len); --char *bulkdata_generate_json_report(bulkdata_profile_t *bp, char *report_timestamp); -+char *bulkdata_generate_json_report(bulkdata_profile_t *bp, char *report_timestamp, char *report_format); - unsigned char *bulkdata_compress_report(profile_ctrl_params_t *ctrl, char *input_buf, int input_len, int *p_output_len); - int bulkdata_schedule_sending_http_report(profile_ctrl_params_t *ctrl, bulkdata_profile_t *bp, unsigned char *json_report, int report_len); - int bulkdata_start_profile(bulkdata_profile_t *bp); -@@ -310,7 +312,7 @@ int DEVICE_BULKDATA_Init(void) - err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.Parameter.{i}.Reference", "", Validate_BulkDataReference, NULL, DM_STRING); - - // Device.BulkData.Profile.{i}.JSONEncoding -- err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.JSONEncoding.ReportFormat", BULKDATA_JSON_REPORT_FORMAT, Validate_BulkDataReportFormat, NULL, DM_STRING); -+ err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.JSONEncoding.ReportFormat", BULKDATA_JSON_REPORT_FORMAT_NAME_VALUE, Validate_BulkDataReportFormat, NULL, DM_STRING); - err |= USP_REGISTER_DBParam_ReadWrite("Device.BulkData.Profile.{i}.JSONEncoding.ReportTimestamp", BULKDATA_JSON_TIMESTAMP_FORMAT_EPOCH, Validate_BulkDataReportTimestamp, NULL, DM_STRING); - - // Device.BulkData.Profile.{i}.HTTP -@@ -698,9 +700,11 @@ int Validate_BulkDataReference(dm_req_t - int Validate_BulkDataReportFormat(dm_req_t *req, char *value) - { - // Exit if trying to set a value outside of the range we accept -- if (strcmp(value, BULKDATA_JSON_REPORT_FORMAT) != 0) -+ if (strcmp(value, BULKDATA_JSON_REPORT_FORMAT_NAME_VALUE) != 0 && -+ strcmp(value, BULKDATA_JSON_REPORT_FORMAT_OBJ_HIER) != 0) - { -- USP_ERR_SetMessage("%s: Only JSON Report Format supported is '%s'", __FUNCTION__, BULKDATA_JSON_REPORT_FORMAT); -+ USP_ERR_SetMessage("%s: Only JSON Report Format supported are '%s', '%s'", __FUNCTION__, -+ BULKDATA_JSON_REPORT_FORMAT_NAME_VALUE, BULKDATA_JSON_REPORT_FORMAT_OBJ_HIER); - return USP_ERR_INVALID_VALUE; - } - -@@ -2008,6 +2012,14 @@ int bulkdata_platform_get_profile_contro - return err; - } - -+ // Exit if unable to get ReportFormat -+ USP_SNPRINTF(path, sizeof(path), "Device.BulkData.Profile.%d.JSONEncoding.ReportFormat", bp->profile_id); -+ err = DATA_MODEL_GetParameterValue(path, ctrl_params->report_format, sizeof(ctrl_params->report_format), 0); -+ if (err != USP_ERR_OK) -+ { -+ return err; -+ } -+ - return USP_ERR_OK; - } - -@@ -2283,7 +2295,7 @@ void bulkdata_process_profile_http(bulkd - } - - // Exit if unable to generate the report -- json_report = bulkdata_generate_json_report(bp, ctrl.report_timestamp); -+ json_report = bulkdata_generate_json_report(bp, ctrl.report_timestamp, ctrl.report_format); - if (json_report == NULL) - { - USP_ERR_SetMessage("%s: bulkdata_generate_json_report failed", __FUNCTION__); -@@ -2333,7 +2345,8 @@ void bulkdata_process_profile_usp_event( - kv_pair_t kv; - report_t *cur_report; - char *json_report; -- char report_timestamp[33]; -+ char report_timestamp[33] = {0}; -+ char report_format[20] = {0}; - - // Exit if the MTP has not been connected to successfully after bootup - // This is to prevent BDC events being enqueued before the Boot! event is sent (the Boot! event is only sent after successfully connecting to the MTP). -@@ -2350,6 +2363,14 @@ void bulkdata_process_profile_usp_event( - return; - } - -+ // Exit if unable to get ReportFormat -+ USP_SNPRINTF(path, sizeof(path), "Device.BulkData.Profile.%d.JSONEncoding.ReportFormat", bp->profile_id); -+ err = DATA_MODEL_GetParameterValue(path, report_format, sizeof(report_format), 0); -+ if (err != USP_ERR_OK) -+ { -+ return; -+ } -+ - // When sending via USP events, only one report is ever sent in each USP event - // So ensure all retained reports are removed. NOTE: Clearing the reports here is only necessary when switching protocol from HTTP to USP event, and where HTTP had some unsent reports - bulkdata_clear_retained_reports(bp); -@@ -2367,7 +2388,7 @@ void bulkdata_process_profile_usp_event( - bp->num_retained_reports = 1; - - // Exit if unable to generate the report -- json_report = bulkdata_generate_json_report(bp, report_timestamp); -+ json_report = bulkdata_generate_json_report(bp, report_timestamp, report_format); - if (json_report == NULL) - { - USP_ERR_SetMessage("%s: bulkdata_generate_json_report failed", __FUNCTION__); -@@ -2579,21 +2600,7 @@ int bulkdata_reduce_to_alt_name(char *sp - return USP_ERR_OK; - } - --/*********************************************************************//** --** --** bulkdata_generate_json_report --** --** Generates a JSON name-value pair format report --** NOTE: The report contains all retained failed reports, as well as the current report --** See TR-157 section A.4.2 (end) for an example, and section A.3.5.2 for layout of content containing failed report transmissions --** --** \param bp - pointer to bulk data profile containing all reports (current and retained) --** \param report_timestamp - value of Device.BulkData.Profile.{i}.JSONEncoding.ReportTimestamp --** --** \return pointer to NULL terminated dynamically allocated buffer containing the serialized report to send --** --**************************************************************************/ --char *bulkdata_generate_json_report(bulkdata_profile_t *bp, char *report_timestamp) -+static char *create_json_name_value_pair_report(bulkdata_profile_t *bp, char *report_timestamp) - { - JsonNode *top; // top of report - JsonNode *array; // array of reports (retained + current) -@@ -2608,7 +2615,6 @@ char *bulkdata_generate_json_report(bulk - long long value_as_ll; - unsigned long long value_as_ull; - bool value_as_bool; -- char *result; - int i, j; - char buf[32]; - kv_pair_t *kv; -@@ -2631,7 +2637,7 @@ char *bulkdata_generate_json_report(bulk - } - else if (strcmp(report_timestamp, "ISO-8601")==0) - { -- result = iso8601_from_unix_time(report->collection_time, buf, sizeof(buf)); -+ char *result = iso8601_from_unix_time(report->collection_time, buf, sizeof(buf)); - if (result != NULL) - { - json_append_member(element, "CollectionTime", json_mkstring(buf)); -@@ -2690,11 +2696,174 @@ char *bulkdata_generate_json_report(bulk - json_append_member(top, "Report", array); - - // Serialize the JSON tree -- result = json_stringify(top, " "); -+ char *output = json_stringify(top, " "); - - // Clean up the JSON tree - json_delete(top); // Other JsonNodes which are children of this top level tree will be deleted - -+ return output; -+} -+ -+static char *create_json_obj_hier_report(bulkdata_profile_t *bp, char *report_timestamp) -+{ -+ JsonNode *top; // top of report -+ JsonNode *array; // array of reports (retained + current) -+ JsonNode *element; // element of json array, containing an individual report -+ JsonNode *temp; -+ char *param_path; -+ char *param_type_value; -+ char param_type; -+ char *param_value; -+ kv_vector_t *report_map; -+ report_t *report; -+ double value_as_number; -+ long long value_as_ll; -+ unsigned long long value_as_ull; -+ bool value_as_bool; -+ int i, j; -+ char buf[32]; -+ kv_pair_t *kv; -+ int err; -+ -+ top = json_mkobject(); -+ array = json_mkarray(); -+ -+ // Iterate over all reports adding them to the JSON array -+ for (i=0; i < bp->num_retained_reports; i++) -+ { -+ report = &bp->reports[i]; -+ report_map = &report->report_map; -+ -+ // Add Collection time to each json report element (only if specified and not 'None') -+ element = json_mkobject(); -+ if (strcmp(report_timestamp, "Unix-Epoch")==0) -+ { -+ json_append_member(element, "CollectionTime", json_mknumber(report->collection_time)); -+ } -+ else if (strcmp(report_timestamp, "ISO-8601")==0) -+ { -+ char *result = iso8601_from_unix_time(report->collection_time, buf, sizeof(buf)); -+ if (result != NULL) -+ { -+ json_append_member(element, "CollectionTime", json_mkstring(buf)); -+ } -+ } -+ -+ temp = element; -+ // Iterate over each parameter, adding it to the json element. Take account of the parameter's type -+ for (j=0; j < report_map->num_entries; j++) -+ { -+ char buff[2056] = {0}; -+ char *pch = NULL, *pchr = NULL, *argv[128] = {0}; -+ int n = 0; -+ -+ kv = &report_map->vector[j]; -+ param_path = kv->key; -+ param_type_value = kv->value; -+ param_type = param_type_value[0]; // First character denotes the type of the parameter -+ param_value = ¶m_type_value[1]; // Subsequent characters contain the parameter's value -+ -+ strncpy(buff, param_path, sizeof(buff)); -+ for (pch = strtok_r(buff, ".", &pchr); pch != NULL; pch = strtok_r(NULL, ".", &pchr)) { -+ int idx; -+ JsonNode *obj = element; -+ argv[n] = pch; -+ -+ for (idx = 0; idx <= n; idx++) { -+ if (obj == NULL) -+ break; -+ obj = json_find_member(obj, argv[idx]); -+ } -+ -+ if (obj) -+ temp = obj; -+ else { -+ if (pchr != NULL && *pchr != '\0') { -+ // It is a DMOBJ -+ JsonNode *new = json_mkobject(); -+ json_append_member(temp, pch, new); -+ temp = new; -+ } else { -+ // It is a DMPARAM -+ switch (param_type) -+ { -+ case 'S': -+ json_append_member(temp, pch, json_mkstring(param_value) ); -+ break; -+ -+ case 'U': -+ value_as_ull = strtoull(param_value, NULL, 10); -+ json_append_member(temp, pch, json_mkulonglong(value_as_ull) ); -+ break; -+ -+ case 'L': -+ value_as_ll = strtoll(param_value, NULL, 10); -+ json_append_member(temp, pch, json_mklonglong(value_as_ll) ); -+ break; -+ -+ case 'N': -+ value_as_number = atof(param_value); -+ json_append_member(temp, pch, json_mknumber(value_as_number) ); -+ break; -+ -+ case 'B': -+ err = TEXT_UTILS_StringToBool(param_value, &value_as_bool); -+ if (err == USP_ERR_OK) -+ { -+ json_append_member(temp, pch, json_mkbool(value_as_bool) ); -+ } -+ break; -+ -+ default: -+ USP_ERR_SetMessage("%s: Invalid JSON parameter type ('%c') in report map for %s", __FUNCTION__, param_type_value[0], param_path); -+ break; -+ } -+ } -+ } -+ n++; -+ } -+ } -+ -+ // Add the json element to the json array -+ json_append_element(array, element); -+ } -+ -+ // Finally add the array to the report top level -+ json_append_member(top, "Report", array); -+ -+ // Serialize the JSON tree -+ char *output = json_stringify(top, " "); -+ -+ // Clean up the JSON tree -+ json_delete(top); // Other JsonNodes which are children of this top level tree will be deleted -+ -+ return output; -+} -+ -+/*********************************************************************//** -+** -+** bulkdata_generate_json_report -+** -+** Generates a JSON name-value pair or object-hierarchy format report -+** NOTE: The report contains all retained failed reports, as well as the current report -+** See TR-157 section A.4.2 (end) for an example, and section A.3.5.2 for layout of content containing failed report transmissions -+** -+** \param bp - pointer to bulk data profile containing all reports (current and retained) -+** \param report_timestamp - value of Device.BulkData.Profile.{i}.JSONEncoding.ReportTimestamp -+** -+** \return pointer to NULL terminated dynamically allocated buffer containing the serialized report to send -+** -+**************************************************************************/ -+char *bulkdata_generate_json_report(bulkdata_profile_t *bp, char *report_timestamp, char *report_format) -+{ -+ char *result = NULL; -+ -+ if (strcmp(report_format, BULKDATA_JSON_REPORT_FORMAT_NAME_VALUE) == 0) { -+ result = create_json_name_value_pair_report(bp, report_timestamp); -+ } else if (strcmp(report_format, BULKDATA_JSON_REPORT_FORMAT_OBJ_HIER) == 0) { -+ result = create_json_obj_hier_report(bp, report_timestamp); -+ } -+ - return result; - } - -@@ -2851,6 +3020,11 @@ int bulkdata_schedule_sending_http_repor - flags |= BDC_FLAG_DATE_HEADER; - } - -+ if (strcmp(ctrl->report_format, BULKDATA_JSON_REPORT_FORMAT_OBJ_HIER) == 0) -+ { -+ flags |= BDC_FLAG_HEADER_OBJ_HIER; -+ } -+ - // Exit if failed to post a message to BDC thread - // NOTE: Ownership of full_url, query_string, report, username and password passes to BDC_EXEC - err = BDC_EXEC_PostReportToSend(bp->profile_id, full_url, query_string, username, password, report, report_len, flags); diff --git a/obuspa/patches/0022-use-datamodel-caching.patch b/obuspa/patches/0022-use-datamodel-caching.patch deleted file mode 100644 index dabb84830..000000000 --- a/obuspa/patches/0022-use-datamodel-caching.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- a/src/core/cli_server.c -+++ b/src/core/cli_server.c -@@ -753,6 +753,15 @@ int ExecuteCli_Get(char *arg1, char *arg - } - #endif - -+ char *path[2] = {0}; -+ -+ path[0] = arg1; -+ if (arg1 == NULL) { -+ vendor_create_dm_cache(path, 0); -+ } else { -+ vendor_create_dm_cache(path, 1); -+ } -+ - // Exit if unable to get a list of all parameters referenced by the expression - STR_VECTOR_Init(¶ms); - INT_VECTOR_Init(&group_ids); ---- a/src/core/data_model.h -+++ b/src/core/data_model.h -@@ -371,5 +371,6 @@ bool DM_PRIV_IsChildOf(char *path, dm_no - bool DM_PRIV_IsChildNodeOf(dm_node_t *node, dm_node_t *parent_node); - bool DM_PRIV_AreAllChildrenGroupId(dm_node_t *parent, int group_id); - -+int vendor_create_dm_cache(char *paths[], int num_paths); - #endif - ---- a/src/core/handle_get.c -+++ b/src/core/handle_get.c -@@ -123,6 +123,7 @@ void MSG_HANDLER_HandleGet(Usp__Msg *usp - goto exit; - } - -+ vendor_create_dm_cache(path_exprs, num_path_expr); - // Calculate the number of hierarchical levels to traverse in the data model when performing partial path resolution - // NOTE: protocol buffer has depth as an unsigned quantity, but internally we use a signed number, so limit range to that of a signed number - depth = usp->body->request->get->max_depth; diff --git a/obuspa/patches/0004-suppress-notification-logs.patch b/obuspa/patches/1000-suppress-logs.patch similarity index 51% rename from obuspa/patches/0004-suppress-notification-logs.patch rename to obuspa/patches/1000-suppress-logs.patch index 9eca84750..dc2af7ecd 100644 --- a/obuspa/patches/0004-suppress-notification-logs.patch +++ b/obuspa/patches/1000-suppress-logs.patch @@ -1,5 +1,22 @@ ---- a/src/core/data_model.c -+++ b/src/core/data_model.c +Index: obuspa-9.0.4.1/src/core/cli_server.c +=================================================================== +--- obuspa-9.0.4.1.orig/src/core/cli_server.c ++++ obuspa-9.0.4.1/src/core/cli_server.c +@@ -715,10 +715,6 @@ int ExecuteCli_Get(str_vector_t *args) + USP_ASSERT(gge->value != NULL); + SendCliResponse("%s => %s\n", gge->path, gge->value); + } +- else +- { +- SendCliResponse("ERROR: %d retrieving %s (%s)\n", gge->err_code, gge->path, gge->err_msg); +- } + } + + GROUP_GET_VECTOR_Destroy(&ggv); +Index: obuspa-9.0.4.1/src/core/data_model.c +=================================================================== +--- obuspa-9.0.4.1.orig/src/core/data_model.c ++++ obuspa-9.0.4.1/src/core/data_model.c @@ -1316,7 +1316,7 @@ int DATA_MODEL_NotifyInstanceAdded(char // Exit if instance already exists - nothing to do if (exists) diff --git a/obuspa/patches/1001-use-datamodel-caching.patch b/obuspa/patches/1001-use-datamodel-caching.patch new file mode 100644 index 000000000..c0d2961a0 --- /dev/null +++ b/obuspa/patches/1001-use-datamodel-caching.patch @@ -0,0 +1,62 @@ +Index: obuspa-9.0.4.1/src/core/cli_server.c +=================================================================== +--- obuspa-9.0.4.1.orig/src/core/cli_server.c ++++ obuspa-9.0.4.1/src/core/cli_server.c +@@ -501,6 +501,7 @@ int CLI_SERVER_ExecuteCliCommand(char *c + SendCliResponse("WARNING: Discarding unused args: %s\n", args.vector[cli_cmd->max_args+1]); + } + ++ vendor_create_dm_cache(NULL, 0); + // Process command + err = cli_cmd->exec_cmd(&args); + print_help = false; +@@ -683,6 +684,13 @@ int ExecuteCli_Get(str_vector_t *args) + } + #endif + ++ if (arg1 != NULL) { ++ char *path[2] = {0}; ++ ++ path[0] = arg1; ++ vendor_create_dm_cache(path, 1); ++ } ++ + // Exit if unable to get a list of all parameters referenced by the expression + STR_VECTOR_Init(¶ms); + INT_VECTOR_Init(&group_ids); +Index: obuspa-9.0.4.1/src/core/data_model.h +=================================================================== +--- obuspa-9.0.4.1.orig/src/core/data_model.h ++++ obuspa-9.0.4.1/src/core/data_model.h +@@ -370,5 +370,6 @@ int DM_PRIV_ReRegister_DBParam_Default(c + bool DM_PRIV_IsChildNodeOf(dm_node_t *node, dm_node_t *parent_node); + void DM_PRIV_GetAllEventsAndCommands(dm_node_t *node, str_vector_t *events, str_vector_t *commands); + ++int vendor_create_dm_cache(char *paths[], int num_paths); + #endif + +Index: obuspa-9.0.4.1/src/core/handle_get.c +=================================================================== +--- obuspa-9.0.4.1.orig/src/core/handle_get.c ++++ obuspa-9.0.4.1/src/core/handle_get.c +@@ -123,6 +123,7 @@ void MSG_HANDLER_HandleGet(Usp__Msg *usp + goto exit; + } + ++ vendor_create_dm_cache(path_exprs, num_path_expr); + // Calculate the number of hierarchical levels to traverse in the data model when performing partial path resolution + // NOTE: protocol buffer has depth as an unsigned quantity, but internally we use a signed number, so limit range to that of a signed number + depth = usp->body->request->get->max_depth; +Index: obuspa-9.0.4.1/src/core/msg_handler.c +=================================================================== +--- obuspa-9.0.4.1.orig/src/core/msg_handler.c ++++ obuspa-9.0.4.1/src/core/msg_handler.c +@@ -862,6 +862,8 @@ int HandleUspMessage(Usp__Msg *usp, char + MSG_HANDLER_UspMsgTypeToString(usp->header->msg_type), + iso8601_cur_time(buf, sizeof(buf)) ); + ++ // Drop the cached data before processing next message ++ vendor_create_dm_cache(NULL, 0); + // Process the message + cur_msg_type = usp_msg_type; + switch(usp_msg_type) diff --git a/obuspa/patches/0001-validate-controller-mtp.patch b/obuspa/patches/2001-validate-controller-mtp.patch similarity index 84% rename from obuspa/patches/0001-validate-controller-mtp.patch rename to obuspa/patches/2001-validate-controller-mtp.patch index 8cab2e908..fdb44b5d9 100644 --- a/obuspa/patches/0001-validate-controller-mtp.patch +++ b/obuspa/patches/2001-validate-controller-mtp.patch @@ -1,5 +1,7 @@ ---- a/src/core/device.h -+++ b/src/core/device.h +Index: obuspa-9.0.4.1/src/core/device.h +=================================================================== +--- obuspa-9.0.4.1.orig/src/core/device.h ++++ obuspa-9.0.4.1/src/core/device.h @@ -338,6 +338,10 @@ void DEVICE_CONTROLLER_SetInheritedRole( int DEVICE_CONTROLLER_CountEnabledWebsockClientConnections(void); #endif @@ -11,8 +13,10 @@ #ifndef REMOVE_USP_BROKER int DEVICE_SUBSCRIPTION_RouteNotification(Usp__Msg *usp, int instance); bool DEVICE_SUBSCRIPTION_MarkVendorLayerSubs(int broker_instance, subs_notify_t notify_type, char *path, int group_id); ---- a/src/core/device_controller.c -+++ b/src/core/device_controller.c +Index: obuspa-9.0.4.1/src/core/device_controller.c +=================================================================== +--- obuspa-9.0.4.1.orig/src/core/device_controller.c ++++ obuspa-9.0.4.1/src/core/device_controller.c @@ -967,6 +967,78 @@ int DEVICE_CONTROLLER_QueueBinaryMessage return USP_ERR_OK; } @@ -92,9 +96,11 @@ /*********************************************************************//** ** ** DEVICE_CONTROLLER_IsMTPConfigured ---- a/src/core/msg_handler.c -+++ b/src/core/msg_handler.c -@@ -1210,6 +1210,15 @@ int ValidateUspRecord(UspRecord__Record +Index: obuspa-9.0.4.1/src/core/msg_handler.c +=================================================================== +--- obuspa-9.0.4.1.orig/src/core/msg_handler.c ++++ obuspa-9.0.4.1/src/core/msg_handler.c +@@ -1219,6 +1219,15 @@ int ValidateUspRecord(UspRecord__Record usp_service_instance = USP_BROKER_GetUspServiceInstance(rec->from_id, 0); #endif diff --git a/obuspa/patches/0011-max_controllers.patch b/obuspa/patches/2002-max_controllers.patch similarity index 81% rename from obuspa/patches/0011-max_controllers.patch rename to obuspa/patches/2002-max_controllers.patch index 2f9c4eeb0..cd3841894 100644 --- a/obuspa/patches/0011-max_controllers.patch +++ b/obuspa/patches/2002-max_controllers.patch @@ -1,6 +1,8 @@ ---- a/src/core/mqtt.c -+++ b/src/core/mqtt.c -@@ -256,6 +256,8 @@ void MqttSubscriptionDestroy(mqtt_subscr +Index: obuspa-9.0.4.1/src/core/mqtt.c +=================================================================== +--- obuspa-9.0.4.1.orig/src/core/mqtt.c ++++ obuspa-9.0.4.1/src/core/mqtt.c +@@ -258,6 +258,8 @@ void MqttSubscriptionDestroy(mqtt_subscr #define DEFINE_MQTT_TrustCertVerifyCallbackIndex(index) \ int MQTT_TrustCertVerifyCallback_##index (int preverify_ok, X509_STORE_CTX *x509_ctx) \ {\ @@ -9,7 +11,7 @@ return DEVICE_SECURITY_TrustCertVerifyCallbackWithCertChain(preverify_ok, x509_ctx, &mqtt_clients[index].cert_chain);\ } -@@ -266,6 +268,11 @@ DEFINE_MQTT_TrustCertVerifyCallbackIndex +@@ -268,6 +270,11 @@ DEFINE_MQTT_TrustCertVerifyCallbackIndex DEFINE_MQTT_TrustCertVerifyCallbackIndex(2); DEFINE_MQTT_TrustCertVerifyCallbackIndex(3); DEFINE_MQTT_TrustCertVerifyCallbackIndex(4); @@ -21,7 +23,7 @@ // Add more, with incrementing indexes here, if you change MAX_MQTT_CLIENTS //------------------------------------------------------------------------------------ -@@ -276,10 +283,15 @@ ssl_verify_callback_t* mqtt_verify_callb +@@ -278,10 +285,15 @@ ssl_verify_callback_t* mqtt_verify_callb MQTT_TrustCertVerifyCallbackIndex(2), MQTT_TrustCertVerifyCallbackIndex(3), MQTT_TrustCertVerifyCallbackIndex(4),