mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
obuspa: Add support of bulkdata json obj-hierarchy report
This commit is contained in:
parent
6a8734ad4f
commit
44c6d5e7e6
2 changed files with 373 additions and 1 deletions
|
|
@ -5,7 +5,7 @@
|
|||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=obuspa
|
||||
PKG_VERSION:=7.0.0.7
|
||||
PKG_VERSION:=7.0.0.8
|
||||
|
||||
LOCAL_DEV:=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
|
|
|
|||
372
obuspa/patches/0006-bdc_json_obj_hierarchy.patch
Normal file
372
obuspa/patches/0006-bdc_json_obj_hierarchy.patch
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
diff --git a/src/core/bdc_exec.c b/src/core/bdc_exec.c
|
||||
index 6b5c11d..3670361 100644
|
||||
--- a/src/core/bdc_exec.c
|
||||
+++ b/src/core/bdc_exec.c
|
||||
@@ -548,9 +548,14 @@ 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");
|
||||
- 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");
|
||||
}
|
||||
|
||||
diff --git a/src/core/bdc_exec.h b/src/core/bdc_exec.h
|
||||
index c58c6d5..ff37a2d 100644
|
||||
--- 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
|
||||
diff --git a/src/core/device_bulkdata.c b/src/core/device_bulkdata.c
|
||||
index 5b1aff2..a7d1b3e 100755
|
||||
--- a/src/core/device_bulkdata.c
|
||||
+++ b/src/core/device_bulkdata.c
|
||||
@@ -68,7 +68,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
|
||||
@@ -159,6 +160,7 @@ typedef struct
|
||||
char compression[9];
|
||||
char method[9];
|
||||
bool use_date_header;
|
||||
+ char report_format[20];
|
||||
} profile_ctrl_params_t;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -233,7 +235,7 @@ 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 *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);
|
||||
@@ -307,7 +309,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
|
||||
@@ -661,9 +663,11 @@ 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: 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;
|
||||
}
|
||||
|
||||
@@ -1974,6 +1978,14 @@ int bulkdata_platform_get_profile_control_params(bulkdata_profile_t *bp, profile
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2249,7 +2261,7 @@ 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);
|
||||
+ 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__);
|
||||
@@ -2299,7 +2311,8 @@ void bulkdata_process_profile_usp_event(bulkdata_profile_t *bp)
|
||||
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).
|
||||
@@ -2316,6 +2329,14 @@ void bulkdata_process_profile_usp_event(bulkdata_profile_t *bp)
|
||||
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);
|
||||
@@ -2333,7 +2354,7 @@ 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);
|
||||
+ 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__);
|
||||
@@ -2545,21 +2566,7 @@ int bulkdata_reduce_to_alt_name(char *spec, char *path, char *alt_name, char *ou
|
||||
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)
|
||||
@@ -2574,7 +2581,6 @@ char *bulkdata_generate_json_report(bulkdata_profile_t *bp, char *report_timesta
|
||||
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;
|
||||
@@ -2597,7 +2603,7 @@ char *bulkdata_generate_json_report(bulkdata_profile_t *bp, char *report_timesta
|
||||
}
|
||||
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));
|
||||
@@ -2656,11 +2662,174 @@ char *bulkdata_generate_json_report(bulkdata_profile_t *bp, char *report_timesta
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2817,6 +2986,11 @@ 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;
|
||||
+ }
|
||||
+
|
||||
// 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);
|
||||
Loading…
Add table
Reference in a new issue