mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2025-12-10 07:44:39 +01:00
Added support for Device.DeviceInfo.Reboots. object
This commit is contained in:
parent
5aa1298df5
commit
a813bf2715
5 changed files with 489 additions and 0 deletions
74
docs/guide/libbbfdm_DeviceInfo_Reboots.md
Normal file
74
docs/guide/libbbfdm_DeviceInfo_Reboots.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# Design for Reboot Data Model
|
||||
|
||||
In TR-181 version 2.18, a new object, Device.DeviceInfo.Reboots, was introduced to track and monitor reboot operations. This object provides details such as reboot reasons, counts, timestamps, and more, offering a comprehensive view of the device's state. It simplifies diagnostics and troubleshooting for applications and processes running on the device.
|
||||
|
||||
Currently, there is no standard configuration mapping to this object. However, we propose introducing a custom config called `deviceinfo` to manage this information effectively.
|
||||
|
||||
The idea is to maintain a 1-to-1 mapping between the parameters and UCI config. To achieve this, we need to create an `init.d` service script that generates a UCI section each time the boot() function is called. Essentially, when the boot() function is executed, it will check the `/tmp/reset_reason` file for specific markers, such as (reset reason) and (reset triggered), to identify the cause of the last boot. And based on these markers, it will calculate the required counter for data model parameters and commit the changes in `deviceinfo.globals` section. Furthermore, if necessary, it will create a UCI reboot section by checking `deviceinfo.globals.max_reboot_entries` and adjusting the config accordingly.
|
||||
|
||||
This approach ensures that the data model maps directly to UCI config as closely as possible, eliminating the need for any adjustments at the data model layer.
|
||||
|
||||
## Parameter Mapping Details
|
||||
|
||||
- Device.DeviceInfo.Reboots.BootCount: Maps to deviceinfo.globals.boot_count. This value is determined based on the marker (reset triggered: defaultreset) defined in `/tmp/reset_reason` file.
|
||||
- Device.DeviceInfo.Reboots.CurrentVersionBootCount: Maps to deviceinfo.globals.curr_version_boot_count. This value is determined based on the marker (reset triggered: upgrade) defined in `/tmp/reset_reason` file.
|
||||
- Device.DeviceInfo.Reboots.WatchdogBootCount: Maps to deviceinfo.globals.watchdog_boot_count. This value is determined based on the marker (reset reason: WATCHDOG) defined in `/tmp/reset_reason` file.
|
||||
- Device.DeviceInfo.Reboots.ColdBootCount:
|
||||
- Device.DeviceInfo.Reboots.WarmBootCount:
|
||||
- Device.DeviceInfo.Reboots.MaxRebootEntries: Maps to deviceinfo.globals.max_reboot_entries. Possible values include {-1, 0, etc..}. Each case will be handled internally by bbfdm and default value is 3 and maximum reboot entry supported is 255.
|
||||
- Device.DeviceInfo.Reboots.RebootNumberOfEntries: This is an internal bbfdm mechanism used to count the number of reboot entries.
|
||||
- Device.DeviceInfo.Reboots.RemoveAllReboots(): An internal bbfdm API to remove all reboot sections.
|
||||
- Device.DeviceInfo.Reboots.Reboot.{i}.: Each reboot entry is stored in a 'reboot' section.
|
||||
- Device.DeviceInfo.Reboots.Reboot.{i}.Alias: Maps to deviceinfo.reboot[i].alias. This is managed internally by bbfdm.
|
||||
- Device.DeviceInfo.Reboots.Reboot.{i}.TimeStamp: Maps to deviceinfo.reboot[i].time_stamp. This value is based on system uptime.
|
||||
- Device.DeviceInfo.Reboots.Reboot.{i}.FirmwareUpdated: Maps to deviceinfo.reboot[i].firmware_updated.
|
||||
- Device.DeviceInfo.Reboots.Reboot.{i}.Cause: Maps to deviceinfo.reboot[i].cause. Possible values include {LocalReboot, RemoteReboot, FactoryReset, LocalFactoryReset, RemoteFactoryReset}.
|
||||
- Device.DeviceInfo.Reboots.Reboot.{i}.Reason: Maps to deviceinfo.reboot[i].reason. This value is determined based on the marker (reset reason) defined in `/tmp/reset_reason` file.
|
||||
- Device.DeviceInfo.Reboots.Reboot.{i}.Remove(): An internal bbfdm API to remove the current 'reboot' section.
|
||||
|
||||
|
||||
## Example Configuration
|
||||
|
||||
Below is an example of the configuration file:
|
||||
|
||||
```bash
|
||||
cat /etc/config/deviceinfo
|
||||
|
||||
config globals 'globals'
|
||||
option boot_count '2'
|
||||
option curr_version_boot_count '4'
|
||||
option watchdog_boot_count '3'
|
||||
option cold_boot_count '2'
|
||||
option warm_boot_count '2'
|
||||
option max_reboot_entries '3'
|
||||
|
||||
config reboot 'reboot_1'
|
||||
option alias 'cpe-1'
|
||||
option time_stamp '2024-09-22T20:34:45Z'
|
||||
option firmware_updated '0'
|
||||
option cause 'RemoteReboot'
|
||||
option reason 'REBOOT'
|
||||
|
||||
config reboot 'reboot_2'
|
||||
option alias 'cpe-2'
|
||||
option time_stamp '2024-09-22T21:55:09Z'
|
||||
option firmware_updated '0'
|
||||
option cause 'LocalReboot'
|
||||
option reason 'POR_RESET'
|
||||
|
||||
config reboot 'reboot_3'
|
||||
option alias 'cpe-3'
|
||||
option time_stamp '2024-09-23T04:11:24Z'
|
||||
option firmware_updated '1'
|
||||
option cause 'LocalReboot'
|
||||
option reason 'upgrade'
|
||||
|
||||
config reboot 'reboot_4'
|
||||
option alias 'cpe-4'
|
||||
option time_stamp '2024-09-23T04:15:53Z'
|
||||
option firmware_updated '0'
|
||||
option cause 'RemoteFactoryReset'
|
||||
option reason 'REBOOT'
|
||||
|
||||
```
|
||||
|
||||
|
|
@ -875,6 +875,24 @@ static int browseProcessEntriesInst(struct dmctx *dmctx, DMNODE *parent_node, vo
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int browseDeviceInfoRebootsRebootInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
|
||||
{
|
||||
struct dm_data curr_data = {0};
|
||||
struct uci_section *s = NULL;
|
||||
char *inst = NULL;
|
||||
|
||||
uci_foreach_sections("deviceinfo", "reboot", s) {
|
||||
|
||||
curr_data.config_section = s;
|
||||
|
||||
inst = handle_instance(dmctx, parent_node, s, "reboot_instance", "reboot_alias");
|
||||
|
||||
if (DM_LINK_INST_OBJ(dmctx, parent_node, &curr_data, inst) == DM_STOP)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* GET & SET PARAM
|
||||
**************************************************************/
|
||||
|
|
@ -1521,6 +1539,97 @@ static int get_process_state(char* refparam, struct dmctx *ctx, void *data, char
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int get_DeviceInfoReboots_BootCount(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
dmuci_get_option_value_string("deviceinfo", "globals", "boot_count", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_DeviceInfoReboots_CurrentVersionBootCount(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
dmuci_get_option_value_string("deviceinfo", "globals", "curr_version_boot_count", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_DeviceInfoReboots_WatchdogBootCount(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
dmuci_get_option_value_string("deviceinfo", "globals", "watchdog_boot_count", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_DeviceInfoReboots_ColdBootCount(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
dmuci_get_option_value_string("deviceinfo", "globals", "cold_boot_count", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_DeviceInfoReboots_WarmBootCount(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
dmuci_get_option_value_string("deviceinfo", "globals", "warm_boot_count", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_DeviceInfoReboots_MaxRebootEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = dmuci_get_option_value_fallback_def("deviceinfo", "globals", "max_reboot_entries", "3");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_DeviceInfoReboots_MaxRebootEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||
{
|
||||
switch (action) {
|
||||
case VALUECHECK:
|
||||
if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1",NULL}}, 1))
|
||||
return FAULT_9007;
|
||||
break;
|
||||
case VALUESET:
|
||||
//TODO
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_DeviceInfoReboots_RebootNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
int cnt = get_number_of_entries(ctx, data, instance, browseDeviceInfoRebootsRebootInst);
|
||||
dmasprintf(value, "%d", cnt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_DeviceInfoRebootsReboot_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
return bbf_get_alias(ctx, ((struct dm_data *)data)->config_section, "reboot_alias", instance, value);
|
||||
}
|
||||
|
||||
static int set_DeviceInfoRebootsReboot_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||
{
|
||||
return bbf_set_alias(ctx, ((struct dm_data *)data)->config_section, "reboot_alias", instance, value);
|
||||
}
|
||||
|
||||
static int get_DeviceInfoRebootsReboot_TimeStamp(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "time_stamp", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_DeviceInfoRebootsReboot_FirmwareUpdated(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "firmware_updated", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_DeviceInfoRebootsReboot_Cause(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "cause", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_DeviceInfoRebootsReboot_Reason(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "reason", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* OPERATE COMMANDS
|
||||
*************************************************************/
|
||||
|
|
@ -1694,6 +1803,14 @@ static int get_operate_args_DeviceInfoFirmwareImage_Activate(char *refparam, str
|
|||
|
||||
void _exec_reboot(const void *arg1, void *arg2)
|
||||
{
|
||||
char config_name[16] = {0};
|
||||
|
||||
snprintf(config_name, sizeof(config_name), "%s", "deviceinfo");
|
||||
|
||||
// Set last_reboot_cause to 'RemoteReboot' because the upcoming reboot will be initiated by USP Operate
|
||||
dmuci_set_value(config_name, "globals", "last_reboot_cause", "RemoteReboot");
|
||||
dmuci_commit_package(config_name);
|
||||
|
||||
sleep(3);
|
||||
dmubus_call_set("rpc-sys", "reboot", UBUS_ARGS{0}, 0);
|
||||
sleep(5); // Wait for reboot to happen
|
||||
|
|
@ -1701,6 +1818,10 @@ void _exec_reboot(const void *arg1, void *arg2)
|
|||
dmubus_call_set("system", "reboot", UBUS_ARGS{0}, 0);
|
||||
sleep(5); // Wait for reboot
|
||||
BBF_ERR("Reboot call failed!!!");
|
||||
|
||||
// Set last_reboot_cause to empty because there is a problem in the system reboot
|
||||
dmuci_set_value(config_name, "globals", "last_reboot_cause", "");
|
||||
dmuci_commit_package(config_name);
|
||||
}
|
||||
|
||||
static int operate_DeviceInfoFirmwareImage_Activate(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||
|
|
@ -1810,6 +1931,22 @@ static int operate_DeviceInfoFirmwareImage_Activate(char *refparam, struct dmctx
|
|||
return res ? USP_FAULT_COMMAND_FAILURE : 0;
|
||||
}
|
||||
|
||||
static int operate_DeviceInfoReboots_RemoveAllReboots(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||
{
|
||||
struct uci_section *s = NULL, *tmp_s = NULL;
|
||||
|
||||
uci_foreach_sections_safe("deviceinfo", "reboot", tmp_s, s) {
|
||||
dmuci_delete_by_section(s, NULL, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int operate_DeviceInfoRebootsReboot_Remove(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||
{
|
||||
dmuci_delete_by_section(((struct dm_data *)data)->config_section, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************
|
||||
* OBJ & LEAF DEFINITION
|
||||
***********************************************************************************************************************************/
|
||||
|
|
@ -1822,6 +1959,7 @@ DMOBJ tDeviceInfoObj[] = {
|
|||
{"Processor", &DMREAD, NULL, NULL, NULL, browseDeviceInfoProcessorInst, NULL, NULL, NULL, tDeviceInfoProcessorParams, NULL, BBFDM_BOTH, NULL},
|
||||
{"SupportedDataModel", &DMREAD, NULL, NULL, NULL, browseDeviceInfoSupportedDataModelInst, NULL, NULL, NULL, tDeviceInfoSupportedDataModelParams, NULL, BBFDM_CWMP, NULL},
|
||||
{"FirmwareImage", &DMREAD, NULL, NULL, "file:/usr/libexec/rpcd/fwbank", browseDeviceInfoFirmwareImageInst, NULL, NULL, NULL, tDeviceInfoFirmwareImageParams, NULL, BBFDM_BOTH, NULL},
|
||||
{"Reboots", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDeviceInfoRebootsObj, tDeviceInfoRebootsParams, NULL, BBFDM_USP, NULL},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
@ -1934,3 +2072,35 @@ DMLEAF tDeviceInfoFirmwareImageParams[] = {
|
|||
{"Activate()", &DMASYNC, DMT_COMMAND, get_operate_args_DeviceInfoFirmwareImage_Activate, operate_DeviceInfoFirmwareImage_Activate, BBFDM_USP},
|
||||
{0}
|
||||
};
|
||||
|
||||
/* *** Device.DeviceInfo.Reboots. *** */
|
||||
DMOBJ tDeviceInfoRebootsObj[] = {
|
||||
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys */
|
||||
{"Reboot", &DMREAD, NULL, NULL, NULL, browseDeviceInfoRebootsRebootInst, NULL, NULL, NULL, tDeviceInfoRebootsRebootParams, NULL, BBFDM_USP, NULL},
|
||||
{0}
|
||||
};
|
||||
|
||||
DMLEAF tDeviceInfoRebootsParams[] = {
|
||||
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type */
|
||||
{"BootCount", &DMREAD, DMT_UNINT, get_DeviceInfoReboots_BootCount, NULL, BBFDM_USP},
|
||||
{"CurrentVersionBootCount", &DMREAD, DMT_UNINT, get_DeviceInfoReboots_CurrentVersionBootCount, NULL, BBFDM_USP},
|
||||
{"WatchdogBootCount", &DMREAD, DMT_UNINT, get_DeviceInfoReboots_WatchdogBootCount, NULL, BBFDM_USP},
|
||||
{"ColdBootCount", &DMREAD, DMT_UNINT, get_DeviceInfoReboots_ColdBootCount, NULL, BBFDM_USP},
|
||||
{"WarmBootCount", &DMREAD, DMT_UNINT, get_DeviceInfoReboots_WarmBootCount, NULL, BBFDM_USP},
|
||||
{"MaxRebootEntries", &DMWRITE, DMT_INT, get_DeviceInfoReboots_MaxRebootEntries, set_DeviceInfoReboots_MaxRebootEntries, BBFDM_USP},
|
||||
{"RebootNumberOfEntries", &DMREAD, DMT_UNINT, get_DeviceInfoReboots_RebootNumberOfEntries, NULL, BBFDM_USP},
|
||||
{"RemoveAllReboots()", &DMASYNC, DMT_COMMAND, NULL, operate_DeviceInfoReboots_RemoveAllReboots, BBFDM_USP},
|
||||
{0}
|
||||
};
|
||||
|
||||
/* *** Device.DeviceInfo.Reboots.Reboot.{i}. *** */
|
||||
DMLEAF tDeviceInfoRebootsRebootParams[] = {
|
||||
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type */
|
||||
{"Alias", &DMWRITE, DMT_STRING, get_DeviceInfoRebootsReboot_Alias, set_DeviceInfoRebootsReboot_Alias, BBFDM_USP},
|
||||
{"TimeStamp", &DMREAD, DMT_TIME, get_DeviceInfoRebootsReboot_TimeStamp, NULL, BBFDM_USP},
|
||||
{"FirmwareUpdated", &DMREAD, DMT_BOOL, get_DeviceInfoRebootsReboot_FirmwareUpdated, NULL, BBFDM_USP},
|
||||
{"Cause", &DMREAD, DMT_STRING, get_DeviceInfoRebootsReboot_Cause, NULL, BBFDM_USP},
|
||||
{"Reason", &DMREAD, DMT_STRING, get_DeviceInfoRebootsReboot_Reason, NULL, BBFDM_USP},
|
||||
{"Remove()", &DMASYNC, DMT_COMMAND, NULL, operate_DeviceInfoRebootsReboot_Remove, BBFDM_USP},
|
||||
{0}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@ extern DMLEAF tDeviceInfoProcessStatusProcessParams[];
|
|||
extern DMLEAF tDeviceInfoProcessorParams[];
|
||||
extern DMLEAF tDeviceInfoSupportedDataModelParams[];
|
||||
extern DMLEAF tDeviceInfoFirmwareImageParams[];
|
||||
extern DMOBJ tDeviceInfoRebootsObj[];
|
||||
extern DMLEAF tDeviceInfoRebootsParams[];
|
||||
extern DMLEAF tDeviceInfoRebootsRebootParams[];
|
||||
|
||||
void _exec_reboot(const void *arg1, void *arg2);
|
||||
#endif
|
||||
|
|
|
|||
36
test/files/etc/config/deviceinfo
Normal file
36
test/files/etc/config/deviceinfo
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
config globals 'globals'
|
||||
option boot_count '2'
|
||||
option curr_version_boot_count '4'
|
||||
option watchdog_boot_count '3'
|
||||
option cold_boot_count '2'
|
||||
option warm_boot_count '2'
|
||||
option max_reboot_entries '3'
|
||||
|
||||
config reboot
|
||||
option alias 'cpe-1'
|
||||
option time_stamp '2024-09-22T20:34:45Z'
|
||||
option firmware_updated '0'
|
||||
option cause 'RemoteReboot'
|
||||
option reason 'REBOOT'
|
||||
|
||||
config reboot
|
||||
option alias 'cpe-2'
|
||||
option time_stamp '2024-09-22T21:55:09Z'
|
||||
option firmware_updated '0'
|
||||
option cause 'LocalReboot'
|
||||
option reason 'POR_RESET'
|
||||
|
||||
config reboot
|
||||
option alias 'cpe-3'
|
||||
option time_stamp '2024-09-23T04:11:24Z'
|
||||
option firmware_updated '1'
|
||||
option cause 'LocalReboot'
|
||||
option reason 'upgrade'
|
||||
|
||||
config reboot
|
||||
option alias 'cpe-4'
|
||||
option time_stamp '2024-09-23T04:15:53Z'
|
||||
option firmware_updated '0'
|
||||
option cause 'RemoteFactoryReset'
|
||||
option reason 'REBOOT'
|
||||
206
utilities/files/usr/share/bbfdm/scripts/bbf_reboot_handler.sh
Executable file
206
utilities/files/usr/share/bbfdm/scripts/bbf_reboot_handler.sh
Executable file
|
|
@ -0,0 +1,206 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Script to handle Reboots Object
|
||||
#
|
||||
# Copyright © 2024 IOPSYS Software Solutions AB
|
||||
# Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
|
||||
#
|
||||
|
||||
. /lib/functions.sh
|
||||
|
||||
RESET_REASON_PATH="/tmp/reset_reason"
|
||||
MAX_RETRIES=3
|
||||
RETRY_DELAY=1
|
||||
|
||||
log() {
|
||||
echo "$@" | logger -t bbf_reboot -p info
|
||||
}
|
||||
|
||||
reset_option_counter() {
|
||||
local option_name=$1
|
||||
local option_value=$2
|
||||
uci_set "deviceinfo" "globals" "${option_name}" "${option_value}"
|
||||
}
|
||||
|
||||
increment_option_counter() {
|
||||
local option_name=$1
|
||||
local option_value=$(uci_get "deviceinfo" "globals" "${option_name}" "0")
|
||||
local counter=$((option_value + 1))
|
||||
uci_set "deviceinfo" "globals" "${option_name}" "$counter"
|
||||
}
|
||||
|
||||
get_boot_trigger() {
|
||||
local trigger
|
||||
trigger=$(grep "triggered" ${RESET_REASON_PATH} | cut -d ':' -f2 | xargs)
|
||||
echo "${trigger}"
|
||||
}
|
||||
|
||||
get_boot_reason() {
|
||||
local reason
|
||||
reason=$(grep "reason" ${RESET_REASON_PATH} | cut -d ':' -f2 | xargs)
|
||||
echo "${reason}"
|
||||
}
|
||||
|
||||
calculate_boot_time() {
|
||||
# Get current time and uptime in seconds
|
||||
local current_time uptime_seconds boot_time boot_time_formatted
|
||||
|
||||
current_time=$(date +%s)
|
||||
uptime_seconds=$(awk '{print $1}' /proc/uptime | cut -d. -f1)
|
||||
|
||||
# Calculate the boot time by subtracting the uptime from the current time
|
||||
boot_time=$((current_time - uptime_seconds))
|
||||
|
||||
# Convert the boot time to a human-readable format
|
||||
boot_time_formatted=$(date -d "@$boot_time" +"%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
echo "${boot_time_formatted}"
|
||||
}
|
||||
|
||||
boot_reason_message() {
|
||||
# Generate a human-readable message based on the boot reason and trigger
|
||||
local trigger reason
|
||||
|
||||
trigger=$(get_boot_trigger)
|
||||
|
||||
if [ -n "${trigger}" ]; then
|
||||
case "${trigger}" in
|
||||
"defaultreset")
|
||||
echo "FACTORY RESET"
|
||||
;;
|
||||
"upgrade")
|
||||
echo "FIRMWARE UPGRADE"
|
||||
;;
|
||||
*)
|
||||
echo "${trigger}"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
reason=$(get_boot_reason)
|
||||
case "${reason}" in
|
||||
"POR_RESET")
|
||||
echo "POWER ON RESET"
|
||||
;;
|
||||
*)
|
||||
echo "${reason}"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
create_reboot_section() {
|
||||
local trigger=$1
|
||||
local reboot_sec
|
||||
|
||||
reboot_sec="reboot_$(date +%Y%m%d%H%M%S)"
|
||||
uci_add "deviceinfo" "reboot" "${reboot_sec}"
|
||||
uci_set "deviceinfo" "${reboot_sec}" "time_stamp" "$(calculate_boot_time)"
|
||||
|
||||
if [ "${trigger}" = "upgrade" ]; then
|
||||
uci_set "deviceinfo" "${reboot_sec}" "firmware_updated" "1"
|
||||
else
|
||||
uci_set "deviceinfo" "${reboot_sec}" "firmware_updated" "0"
|
||||
fi
|
||||
|
||||
if [ "${trigger}" = "defaultreset" ]; then
|
||||
uci_set "deviceinfo" "${reboot_sec}" "cause" "FactoryReset"
|
||||
else
|
||||
local last_reboot_cause
|
||||
last_reboot_cause=$(uci_get "deviceinfo" "globals" "last_reboot_cause" "LocalReboot")
|
||||
uci_set "deviceinfo" "${reboot_sec}" "cause" "${last_reboot_cause}"
|
||||
uci_set "deviceinfo" "globals" "last_reboot_cause" ""
|
||||
fi
|
||||
|
||||
uci_set "deviceinfo" "${reboot_sec}" "reason" "$(boot_reason_message)"
|
||||
}
|
||||
|
||||
handle_reboot_action() {
|
||||
local trigger reason max_reboot_entries retry_count reboot_sec_num
|
||||
|
||||
retry_count=0
|
||||
|
||||
# Retry fetching the reset reason file
|
||||
while [ ! -f "${RESET_REASON_PATH}" ] && [ $retry_count -lt $MAX_RETRIES ]; do
|
||||
log "Warning: '${RESET_REASON_PATH}' not found. Attempt $((retry_count + 1)) of ${MAX_RETRIES}"
|
||||
sleep $RETRY_DELAY
|
||||
retry_count=$((retry_count + 1))
|
||||
done
|
||||
|
||||
if [ ! -f "${RESET_REASON_PATH}" ]; then
|
||||
log "Error: '${RESET_REASON_PATH}' is not generated after ${MAX_RETRIES} attempts!!!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
uci_load "deviceinfo"
|
||||
|
||||
trigger=$(get_boot_trigger)
|
||||
reason=$(get_boot_reason)
|
||||
|
||||
# Reset or increment boot counter based on trigger
|
||||
if [ "${trigger}" = "defaultreset" ]; then
|
||||
## Reset all counters ##
|
||||
reset_option_counter "boot_count" "1"
|
||||
reset_option_counter "curr_version_boot_count" "0"
|
||||
reset_option_counter "watchdog_boot_count" "0"
|
||||
reset_option_counter "cold_boot_count" "0"
|
||||
reset_option_counter "warm_boot_count" "0"
|
||||
else
|
||||
# Incrementing boot counter
|
||||
increment_option_counter "boot_count"
|
||||
fi
|
||||
|
||||
# Reset or increment current version boot counter based on trigger
|
||||
if [ "${trigger}" = "upgrade" ]; then
|
||||
# Resetting current version boot counter
|
||||
reset_option_counter "curr_version_boot_count" "1"
|
||||
else
|
||||
# Incrementing current version boot counter
|
||||
increment_option_counter "curr_version_boot_count"
|
||||
fi
|
||||
|
||||
# Increment watchdog boot counter if the reason indicates a watchdog reset
|
||||
if echo "${reason}" | grep -qi "watchdog"; then
|
||||
# Incrementing watchdog boot counter
|
||||
increment_option_counter "watchdog_boot_count"
|
||||
fi
|
||||
|
||||
# Increment cold or warm boot counter based on the reason
|
||||
if [ "${reason}" = "POR_RESET" ]; then
|
||||
increment_option_counter "cold_boot_count"
|
||||
else
|
||||
increment_option_counter "warm_boot_count"
|
||||
fi
|
||||
|
||||
# Get the max reboot entries
|
||||
max_reboot_entries=$(uci_get "deviceinfo" "globals" "max_reboot_entries" "3")
|
||||
|
||||
if [ "${max_reboot_entries}" -eq 0 ]; then
|
||||
# Commit the UCI changes to persist the configuration
|
||||
uci_commit "deviceinfo"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ $max_reboot_entries -gt 0 ]; then
|
||||
# Calculate the number of reboot sections in the config
|
||||
reboot_sec_num=$(uci -q show deviceinfo | grep "=reboot" | wc -l)
|
||||
|
||||
# Delete excess reboot sections if they exceed the max reboot entries
|
||||
if [ "${reboot_sec_num}" -ge "${max_reboot_entries}" ]; then
|
||||
local diff=$((reboot_sec_num - max_reboot_entries + 1))
|
||||
|
||||
for i in $(seq 1 $diff); do
|
||||
uci_remove "deviceinfo" "@reboot[0]"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create a new reboot section with the current boot information
|
||||
create_reboot_section "${trigger}"
|
||||
|
||||
# Commit the UCI changes to persist the configuration
|
||||
uci_commit "deviceinfo"
|
||||
}
|
||||
|
||||
# Run the main function
|
||||
handle_reboot_action
|
||||
exit 0
|
||||
Loading…
Add table
Reference in a new issue