1 /*
2  * Copyright (c) 2020 Linumiz
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/mgmt/hawkbit/hawkbit.h>
9 #include <zephyr/mgmt/hawkbit/config.h>
10 #include <zephyr/mgmt/hawkbit/autohandler.h>
11 #include <zephyr/mgmt/hawkbit/event.h>
12 #include <zephyr/dfu/mcuboot.h>
13 #include <zephyr/sys/printk.h>
14 #include <zephyr/sys/reboot.h>
15 #include <zephyr/logging/log.h>
16 #include <zephyr/data/json.h>
17 
18 #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
19 #include <zephyr/net/tls_credentials.h>
20 #include "ca_certificate.h"
21 #endif
22 
23 LOG_MODULE_REGISTER(main);
24 
25 #ifdef CONFIG_HAWKBIT_CUSTOM_ATTRIBUTES
26 struct hawkbit_cfg_data {
27 	const char *VIN;
28 	const char *customAttr;
29 };
30 
31 struct hawkbit_cfg {
32 	const char *mode;
33 	struct hawkbit_cfg_data data;
34 };
35 
36 static const struct json_obj_descr json_cfg_data_descr[] = {
37 	JSON_OBJ_DESCR_PRIM(struct hawkbit_cfg_data, VIN, JSON_TOK_STRING),
38 	JSON_OBJ_DESCR_PRIM(struct hawkbit_cfg_data, customAttr, JSON_TOK_STRING),
39 };
40 
41 static const struct json_obj_descr json_cfg_descr[] = {
42 	JSON_OBJ_DESCR_PRIM(struct hawkbit_cfg, mode, JSON_TOK_STRING),
43 	JSON_OBJ_DESCR_OBJECT(struct hawkbit_cfg, data, json_cfg_data_descr),
44 };
45 
hawkbit_new_config_data_cb(const char * device_id,uint8_t * buffer,const size_t buffer_size)46 int hawkbit_new_config_data_cb(const char *device_id, uint8_t *buffer, const size_t buffer_size)
47 {
48 	struct hawkbit_cfg cfg = {
49 		.mode = "merge",
50 		.data.VIN = device_id,
51 		.data.customAttr = "Hello World!",
52 	};
53 
54 	return json_obj_encode_buf(json_cfg_descr, ARRAY_SIZE(json_cfg_descr), &cfg, buffer,
55 				   buffer_size);
56 }
57 #endif /* CONFIG_HAWKBIT_CUSTOM_ATTRIBUTES */
58 
59 #ifdef CONFIG_HAWKBIT_EVENT_CALLBACKS
hawkbit_event_cb(struct hawkbit_event_callback * cb,enum hawkbit_event_type event)60 void hawkbit_event_cb(struct hawkbit_event_callback *cb, enum hawkbit_event_type event)
61 {
62 	LOG_INF("hawkBit event: %d", event);
63 
64 	switch (event) {
65 	case HAWKBIT_EVENT_START_RUN:
66 		LOG_INF("Run of hawkBit started");
67 		break;
68 
69 	case HAWKBIT_EVENT_END_RUN:
70 		LOG_INF("Run of hawkBit ended");
71 		break;
72 
73 	default:
74 		break;
75 	}
76 }
77 
78 static HAWKBIT_EVENT_CREATE_CALLBACK(hb_event_cb_start, hawkbit_event_cb, HAWKBIT_EVENT_START_RUN);
79 static HAWKBIT_EVENT_CREATE_CALLBACK(hb_event_cb_end, hawkbit_event_cb, HAWKBIT_EVENT_END_RUN);
80 #endif /* CONFIG_HAWKBIT_EVENT_CALLBACKS */
81 
main(void)82 int main(void)
83 {
84 	int ret = -1;
85 
86 	LOG_INF("hawkBit sample app started");
87 	LOG_INF("Image build time: " __DATE__ " " __TIME__);
88 
89 #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
90 	tls_credential_add(CA_CERTIFICATE_TAG, TLS_CREDENTIAL_CA_CERTIFICATE,
91 			   ca_certificate, sizeof(ca_certificate));
92 #endif
93 #ifdef CONFIG_HAWKBIT_CUSTOM_ATTRIBUTES
94 	ret = hawkbit_set_custom_data_cb(hawkbit_new_config_data_cb);
95 	if (ret < 0) {
96 		LOG_ERR("Failed to set custom data callback");
97 	}
98 #endif /* CONFIG_HAWKBIT_CUSTOM_ATTRIBUTES */
99 
100 #ifdef CONFIG_HAWKBIT_EVENT_CALLBACKS
101 	hawkbit_event_add_callback(&hb_event_cb_start);
102 	hawkbit_event_add_callback(&hb_event_cb_end);
103 #endif /* CONFIG_HAWKBIT_EVENT_CALLBACKS */
104 
105 	ret = hawkbit_init();
106 	if (ret < 0) {
107 		LOG_ERR("Failed to init hawkBit");
108 	}
109 
110 #ifdef CONFIG_HAWKBIT_SET_SETTINGS_RUNTIME
111 	hawkbit_set_server_addr(CONFIG_HAWKBIT_SERVER);
112 	hawkbit_set_server_port(CONFIG_HAWKBIT_PORT);
113 #endif
114 
115 #if defined(CONFIG_HAWKBIT_POLLING)
116 	LOG_INF("Starting hawkBit polling mode");
117 	hawkbit_autohandler(true);
118 #endif
119 
120 #if defined(CONFIG_HAWKBIT_MANUAL)
121 	LOG_INF("Starting hawkBit manual mode");
122 
123 	switch (hawkbit_probe()) {
124 	case HAWKBIT_UNCONFIRMED_IMAGE:
125 		LOG_ERR("Image is unconfirmed");
126 		LOG_ERR("Rebooting to previous confirmed image");
127 		LOG_ERR("If this image is flashed using a hardware tool");
128 		LOG_ERR("Make sure that it is a confirmed image");
129 		k_sleep(K_SECONDS(1));
130 		sys_reboot(SYS_REBOOT_WARM);
131 		break;
132 
133 	case HAWKBIT_NO_UPDATE:
134 		LOG_INF("No update found");
135 		break;
136 
137 	case HAWKBIT_UPDATE_INSTALLED:
138 		LOG_INF("Update installed");
139 		break;
140 
141 	case HAWKBIT_PROBE_IN_PROGRESS:
142 		LOG_INF("hawkBit is already running");
143 		break;
144 
145 	default:
146 		break;
147 	}
148 
149 #endif
150 	return 0;
151 }
152