1 /*
2  * Copyright (c) 2020 Linumiz
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdlib.h>
8 #include <zephyr/shell/shell.h>
9 #include <zephyr/drivers/flash.h>
10 #include <zephyr/dfu/mcuboot.h>
11 #include <zephyr/dfu/flash_img.h>
12 #include <zephyr/mgmt/hawkbit/hawkbit.h>
13 #include <zephyr/mgmt/hawkbit/config.h>
14 #include <zephyr/mgmt/hawkbit/autohandler.h>
15 #include "hawkbit_firmware.h"
16 #include "hawkbit_device.h"
17 
18 LOG_MODULE_DECLARE(hawkbit, CONFIG_HAWKBIT_LOG_LEVEL);
19 
cmd_run(const struct shell * sh,size_t argc,char ** argv)20 static void cmd_run(const struct shell *sh, size_t argc, char **argv)
21 {
22 	ARG_UNUSED(argc);
23 	ARG_UNUSED(argv);
24 
25 	LOG_INF("Run started from %s", sh->name);
26 	shell_info(sh, "Starting hawkBit run...");
27 
28 	hawkbit_autohandler(false);
29 
30 	switch (hawkbit_autohandler_wait(UINT32_MAX,
31 					 K_MSEC(CONFIG_HAWKBIT_SHELL_AUTOHANDLER_TIMEOUT))) {
32 	case HAWKBIT_UNCONFIRMED_IMAGE:
33 		shell_error(sh, "Image is unconfirmed."
34 				"Rebooting to revert back to previous confirmed image");
35 		break;
36 
37 	case HAWKBIT_NO_UPDATE:
38 		shell_info(sh, "No update found");
39 		break;
40 
41 	case HAWKBIT_UPDATE_INSTALLED:
42 		shell_info(sh, "Update installed");
43 		break;
44 
45 	case HAWKBIT_DOWNLOAD_ERROR:
46 		shell_error(sh, "Download error");
47 		break;
48 
49 	case HAWKBIT_NETWORKING_ERROR:
50 		shell_error(sh, "Networking error");
51 		break;
52 
53 	case HAWKBIT_METADATA_ERROR:
54 		shell_error(sh, "Metadata error");
55 		break;
56 
57 	case HAWKBIT_NOT_INITIALIZED:
58 		shell_error(sh, "hawkBit not initialized");
59 		break;
60 
61 	case HAWKBIT_NO_RESPONSE:
62 		shell_info(sh, "hawkBit is still running, see log for more information");
63 		break;
64 
65 	default:
66 		shell_error(sh, "Invalid response");
67 		break;
68 	}
69 	k_sleep(K_MSEC(1));
70 }
71 
cmd_info(const struct shell * sh,size_t argc,char * argv)72 static int cmd_info(const struct shell *sh, size_t argc, char *argv)
73 {
74 	ARG_UNUSED(argc);
75 	ARG_UNUSED(argv);
76 
77 	char device_id[DEVICE_ID_HEX_MAX_SIZE] = {0},
78 	     firmware_version[BOOT_IMG_VER_STRLEN_MAX] = {0};
79 
80 	hawkbit_get_firmware_version(firmware_version, BOOT_IMG_VER_STRLEN_MAX);
81 	hawkbit_get_device_identity(device_id, DEVICE_ID_HEX_MAX_SIZE);
82 
83 	shell_print(sh, "Action id: %d", hawkbit_get_action_id());
84 	shell_print(sh, "Unique device id: %s", device_id);
85 	shell_print(sh, "Firmware Version: %s", firmware_version);
86 	shell_print(sh, "Server address: %s", hawkbit_get_server_addr());
87 	shell_print(sh, "Server port: %d", hawkbit_get_server_port());
88 	shell_print(sh, "DDI security token: %s",
89 		    (IS_ENABLED(CONFIG_HAWKBIT_DDI_NO_SECURITY)
90 			     ? "<disabled>"
91 			     : hawkbit_get_ddi_security_token()));
92 
93 	return 0;
94 }
95 
cmd_init(const struct shell * sh,size_t argc,char * argv)96 static int cmd_init(const struct shell *sh, size_t argc, char *argv)
97 {
98 	ARG_UNUSED(argc);
99 	ARG_UNUSED(argv);
100 
101 	shell_info(sh, "Init hawkBit ...");
102 
103 	hawkbit_init();
104 
105 	return 0;
106 }
107 
cmd_reset(const struct shell * sh,size_t argc,char * argv)108 static int cmd_reset(const struct shell *sh, size_t argc, char *argv)
109 {
110 	ARG_UNUSED(argc);
111 	ARG_UNUSED(argv);
112 
113 	int ret = hawkbit_reset_action_id();
114 
115 	shell_print(sh, "Reset action id %s", (ret == 0) ? "success" : "failed");
116 
117 	return 0;
118 }
119 
120 #ifdef CONFIG_HAWKBIT_SET_SETTINGS_RUNTIME
121 
cmd_set_addr(const struct shell * sh,size_t argc,char ** argv)122 static int cmd_set_addr(const struct shell *sh, size_t argc, char **argv)
123 {
124 	if (argc < 2) {
125 		shell_error(sh, "Invalid number of arguments");
126 		return -EINVAL;
127 	}
128 
129 	hawkbit_set_server_addr(argv[1]);
130 
131 	return 0;
132 }
133 
cmd_set_port(const struct shell * sh,size_t argc,char ** argv)134 static int cmd_set_port(const struct shell *sh, size_t argc, char **argv)
135 {
136 	if (argc < 2) {
137 		shell_error(sh, "Invalid number of arguments");
138 		return -EINVAL;
139 	}
140 
141 	hawkbit_set_server_port(atoi(argv[1]));
142 
143 	return 0;
144 }
145 
146 #ifndef CONFIG_HAWKBIT_DDI_NO_SECURITY
cmd_set_token(const struct shell * sh,size_t argc,char ** argv)147 static int cmd_set_token(const struct shell *sh, size_t argc, char **argv)
148 {
149 	if (argc < 2) {
150 		shell_error(sh, "Invalid number of arguments");
151 		return -EINVAL;
152 	}
153 
154 	hawkbit_set_ddi_security_token(argv[1]);
155 
156 	return 0;
157 }
158 #endif /* CONFIG_HAWKBIT_DDI_NO_SECURITY */
159 
160 SHELL_STATIC_SUBCMD_SET_CREATE(
161 	sub_hawkbit_set,
162 	SHELL_CMD(addr, NULL, "Set hawkBit server address", cmd_set_addr),
163 	SHELL_CMD(port, NULL, "Set hawkBit server port", cmd_set_port),
164 #ifndef CONFIG_HAWKBIT_DDI_NO_SECURITY
165 	SHELL_CMD(ddi_token, NULL, "Set hawkBit DDI Security token", cmd_set_token),
166 #endif
167 	SHELL_SUBCMD_SET_END);
168 #endif /* CONFIG_HAWKBIT_SET_SETTINGS_RUNTIME */
169 
170 SHELL_STATIC_SUBCMD_SET_CREATE(
171 	sub_hawkbit,
172 	SHELL_CMD(info, NULL, "Dump hawkBit information", cmd_info),
173 	SHELL_CMD(init, NULL, "Initialize hawkBit", cmd_init),
174 	SHELL_CMD(run, NULL, "Trigger an hawkBit update run", cmd_run),
175 	SHELL_CMD(reset, NULL, "Reset the hawkBit action id", cmd_reset),
176 #ifdef CONFIG_HAWKBIT_SET_SETTINGS_RUNTIME
177 	SHELL_CMD(set, &sub_hawkbit_set, "Set hawkBit settings", NULL),
178 #endif
179 	SHELL_SUBCMD_SET_END);
180 
181 SHELL_CMD_REGISTER(hawkbit, &sub_hawkbit, "hawkBit commands", NULL);
182