From e5171a391016659cc6c902571829e6fed3f44664 Mon Sep 17 00:00:00 2001 From: Suvendhu Hansa Date: Thu, 2 Nov 2023 08:31:42 +0000 Subject: [PATCH] Added SelfTestDiagnostics() --- libbbfdm/dmcommon.c | 35 +++---- libbbfdm/dmtree/tr181/device.c | 3 + libbbfdm/dmtree/tr181/deviceinfo.c | 2 +- libbbfdm/dmtree/tr181/selftest.c | 146 +++++++++++++++++++++++++++++ libbbfdm/dmtree/tr181/selftest.h | 21 +++++ 5 files changed, 190 insertions(+), 17 deletions(-) create mode 100644 libbbfdm/dmtree/tr181/selftest.c create mode 100644 libbbfdm/dmtree/tr181/selftest.h diff --git a/libbbfdm/dmcommon.c b/libbbfdm/dmcommon.c index 8d064198..bc2e9211 100644 --- a/libbbfdm/dmcommon.c +++ b/libbbfdm/dmcommon.c @@ -167,26 +167,29 @@ static long upload_file(const char *file_path, const char *url, const char *user if (strncmp(url, FILE_URI, strlen(FILE_URI)) == 0) { char dst_path[2046] = {0}; - snprintf(dst_path, sizeof(dst_path), "%s", url+strlen(FILE_URI)); - FILE *fp = fopen(file_path, "r"); - if (fp == NULL) { + char buff[BUFSIZ] = {0}; + FILE *sfp, *dfp; + int n, count=0; + + sfp = fopen(file_path, "rb"); + if (sfp == NULL) { return -1; } - fseek(fp, 0, SEEK_END); - unsigned int length = ftell(fp); - fseek(fp, 0, SEEK_SET); - fclose(fp); - - char buff[length]; - memset(buff, 0, length); - - if (dm_file_to_buf(file_path, buff, length) > 0) { - if (dm_buf_to_file(buff, dst_path) < 0) - res_code = -1; - } else { - res_code = -1; + snprintf(dst_path, sizeof(dst_path), "%s", url+strlen(FILE_URI)); + dfp = fopen(dst_path, "wb"); + if (dfp == NULL) { + fclose(sfp); + return -1; } + + while ((n = fread(buff, 1, BUFSIZ, sfp)) != 0) { + fwrite(buff, 1, n, dfp); + count+=n; + } + + fclose(sfp); + fclose(dfp); } else { CURL *curl = curl_easy_init(); if (curl) { diff --git a/libbbfdm/dmtree/tr181/device.c b/libbbfdm/dmtree/tr181/device.c index 629aa751..9b34bf01 100644 --- a/libbbfdm/dmtree/tr181/device.c +++ b/libbbfdm/dmtree/tr181/device.c @@ -43,6 +43,7 @@ #include "ssh.h" #include "userinterface.h" #include "packetcapture.h" +#include "selftest.h" /************************************************************* * GET & SET PARAM @@ -131,6 +132,7 @@ DMOBJ tDeviceObj[] = { {"SSH", &DMREAD, NULL, NULL, "file:/etc/config/dropbear", NULL, NULL, NULL, tSSHObj, tSSHParams, NULL, BBFDM_BOTH, NULL}, {"UserInterface", &DMREAD, NULL, NULL, "file:/etc/config/userinterface", NULL, NULL, NULL, tUIHTTPAccessObj, tUIParams, NULL, BBFDM_BOTH, NULL}, {"PacketCaptureDiagnostics", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tPacketCaptureObj, tPacketCaptureParams, NULL, BBFDM_CWMP, NULL}, +{"SelfTestDiagnostics", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tSelfTestParams, NULL, BBFDM_CWMP, NULL}, {0} }; @@ -141,6 +143,7 @@ DMLEAF tDeviceParams[] = { {"Reboot()", &DMSYNC, DMT_COMMAND, NULL, operate_Device_Reboot, BBFDM_USP}, {"FactoryReset()", &DMSYNC, DMT_COMMAND, NULL, operate_Device_FactoryReset, BBFDM_USP}, {"PacketCaptureDiagnostics()", &DMASYNC, DMT_COMMAND, get_operate_args_packetCapture, operate_Device_packetCapture, BBFDM_USP}, +{"SelfTestDiagnostics()", &DMASYNC, DMT_COMMAND, get_operate_args_SelfTest, operate_Device_SelfTest, BBFDM_USP}, //{"Boot!", &DMREAD, DMT_EVENT, NULL, NULL, BBFDM_USP}, {0} }; diff --git a/libbbfdm/dmtree/tr181/deviceinfo.c b/libbbfdm/dmtree/tr181/deviceinfo.c index 4c8b7deb..63b9efcd 100644 --- a/libbbfdm/dmtree/tr181/deviceinfo.c +++ b/libbbfdm/dmtree/tr181/deviceinfo.c @@ -1564,7 +1564,7 @@ DMLEAF tDeviceInfoProcessStatusProcessParams[] = { DMLEAF tDeviceInfoVendorLogFileParams[] = { /* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/ {"Alias", &DMWRITE, DMT_STRING, get_vlf_alias, set_vlf_alias, BBFDM_BOTH, DM_FLAG_UNIQUE}, -{"Name", &DMREAD, DMT_STRING, get_vlf_name, NULL, BBFDM_BOTH, DM_FLAG_UNIQUE}, +{"Name", &DMREAD, DMT_STRING, get_vlf_name, NULL, BBFDM_BOTH, DM_FLAG_UNIQUE|DM_FLAG_LINKER}, {"MaximumSize", &DMREAD, DMT_UNINT, get_vlf_max_size, NULL, BBFDM_BOTH}, {"Persistent", &DMREAD, DMT_BOOL, get_vlf_persistent, NULL, BBFDM_BOTH}, {"Upload()", &DMASYNC, DMT_COMMAND, get_operate_args_DeviceInfoVendorLogFile_Upload, operate_DeviceInfoVendorLogFile_Upload, BBFDM_USP}, diff --git a/libbbfdm/dmtree/tr181/selftest.c b/libbbfdm/dmtree/tr181/selftest.c new file mode 100644 index 00000000..bf9d7eda --- /dev/null +++ b/libbbfdm/dmtree/tr181/selftest.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2023 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: Suvendhu Hansa + * + */ + +#include + +#include "dmcommon.h" +#include "selftest.h" + +#define DIAG_BIN "/usr/sbin/self-diagnostics" + +static char *get_selftest_log_instance(struct dmctx *ctx) +{ + char *file_name = NULL; + char *path = NULL; + + struct uci_section *s = get_origin_section_from_config("system", "system", "self_test_log"); + if (s == NULL) + goto err; + + dmuci_get_value_by_section_string(s, "log_file", &file_name); + if (DM_STRLEN(file_name) == 0) + goto err; + + adm_entry_get_reference_param(ctx, "Device.DeviceInfo.VendorLogFile.*.Name", file_name, &path); + +err: + return dmstrdup(path ? path : ""); +} + +/************************************************************* +* OPERATE COMMAND +**************************************************************/ +static operation_args device_self_test_args = { + .out = (const char *[]) { + "Status", + "Results", + NULL + } +}; + +int get_operate_args_SelfTest(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&device_self_test_args; + return 0; +} + +int operate_Device_SelfTest(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char cmd[512] = {0}; + char output[512] = {0}; + + snprintf(cmd, sizeof(cmd), "sh %s", DIAG_BIN); + + FILE *pp = popen(cmd, "r"); + if (pp != NULL) { + fgets(output, sizeof(output), pp); + pclose(pp); + } else { + goto err; + } + + // truncate the new line char from end + remove_new_line(output); + + if (!file_exists(output)) + goto err; + + /* Add in vendor log */ + struct uci_section *s = get_origin_section_from_config("system", "system", "self_test_log"); + if (s == NULL) { + dmuci_add_section("system", "system", &s); + dmuci_rename_section_by_section(s, "self_test_log"); + } + + dmuci_set_value_by_section(s, "log_file", output); + dmuci_commit_package("system"); + + /* Get self test log instance */ + char *result = get_selftest_log_instance(ctx); + + add_list_parameter(ctx, dmstrdup("Status"), dmstrdup("Complete"), DMT_TYPE[DMT_STRING], NULL); + add_list_parameter(ctx, dmstrdup("Results"), result, DMT_TYPE[DMT_STRING], NULL); + + if (ctx->dm_type != BBFDM_USP) { + set_diagnostics_option("selftest", "DiagnosticState", "Complete"); + dmuci_commit_package_bbfdm(DMMAP_DIAGNOSTIGS); + } + + return 0; + +err: + add_list_parameter(ctx, dmstrdup("Status"), dmstrdup("Error_Internal"), DMT_TYPE[DMT_STRING], NULL); + if (ctx->dm_type != BBFDM_USP) { + set_diagnostics_option("selftest", "DiagnosticState", "Error"); + dmuci_commit_package_bbfdm(DMMAP_DIAGNOSTIGS); + } + + return USP_FAULT_COMMAND_FAILURE; +} + +/************************************************************* +* GET & SET PARAM +**************************************************************/ +static int get_SelfTest_DiagnosticsState(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = get_diagnostics_option_fallback_def("selftest", "DiagnosticState", "None"); + return 0; +} + +static int set_SelfTest_DiagnosticsState(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, value, -1, -1, DiagnosticsState, NULL)) + return FAULT_9007; + break; + case VALUESET: + if (DM_LSTRCMP(value, "Requested") == 0) + set_diagnostics_option("selftest", "DiagnosticState", value); + } + return 0; +} + +static int get_SelfTest_Results(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = get_selftest_log_instance(ctx); + return 0; +} + +/********************************************************************************************************************************** +* OBJ & LEAF DEFINITION +***********************************************************************************************************************************/ +DMLEAF tSelfTestParams[] = { +/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ +{"DiagnosticsState", &DMWRITE, DMT_STRING, get_SelfTest_DiagnosticsState, set_SelfTest_DiagnosticsState, BBFDM_CWMP}, +{"Results", &DMREAD, DMT_STRING, get_SelfTest_Results, NULL, BBFDM_CWMP}, +{0} +}; diff --git a/libbbfdm/dmtree/tr181/selftest.h b/libbbfdm/dmtree/tr181/selftest.h new file mode 100644 index 00000000..fb07c70e --- /dev/null +++ b/libbbfdm/dmtree/tr181/selftest.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2023 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: Suvendhu Hansa + */ + +#ifndef __SELFTEST_H +#define __SELFTEST_H + +#include "libbbfdm-api/dmcommon.h" + +extern DMLEAF tSelfTestParams[]; + +int get_operate_args_SelfTest(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value); +int operate_Device_SelfTest(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action); +#endif +