1 /*
2 * Copyright (c) 2024 Nordic Semiconductor
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define LOG_MODULE_NAME app_fw_update
8 #define LOG_LEVEL LOG_LEVEL_DBG
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
11
12 #include <zephyr/net/lwm2m.h>
13 #include <zephyr/sys/crc.h>
14 #include "lwm2m_engine.h"
15
16 static uint8_t firmware_buf[64];
17 static uint32_t crc;
18
19 /* Array with supported PULL firmware update protocols */
20 static uint8_t supported_protocol[1];
21
firmware_update_cb(uint16_t obj_inst_id,uint8_t * args,uint16_t args_len)22 static int firmware_update_cb(uint16_t obj_inst_id,
23 uint8_t *args, uint16_t args_len)
24 {
25 LOG_INF("UPDATE, (CRC %u)", crc);
26
27 lwm2m_set_u8(&LWM2M_OBJ(5, 0, 3), STATE_IDLE);
28 lwm2m_set_u8(&LWM2M_OBJ(5, 0, 5), RESULT_SUCCESS);
29 return 0;
30 }
31
firmware_get_buf(uint16_t obj_inst_id,uint16_t res_id,uint16_t res_inst_id,size_t * data_len)32 static void *firmware_get_buf(uint16_t obj_inst_id, uint16_t res_id,
33 uint16_t res_inst_id, size_t *data_len)
34 {
35 *data_len = sizeof(firmware_buf);
36 return firmware_buf;
37 }
38
firmware_block_received_cb(uint16_t obj_inst_id,uint16_t res_id,uint16_t res_inst_id,uint8_t * data,uint16_t data_len,bool last_block,size_t total_size,size_t offset)39 static int firmware_block_received_cb(uint16_t obj_inst_id, uint16_t res_id,
40 uint16_t res_inst_id, uint8_t *data,
41 uint16_t data_len, bool last_block,
42 size_t total_size, size_t offset)
43 {
44 if (offset == 0) {
45 crc = crc32_ieee(data, data_len);
46 } else {
47 crc = crc32_ieee_update(crc, data, data_len);
48 }
49 LOG_INF("FIRMWARE: BLOCK RECEIVED: offset:%zd len:%u last_block:%d crc: %u",
50 offset, data_len, last_block, crc);
51
52 /* Add extra delay so short block-wise may timeout */
53 k_sleep(K_MSEC(100));
54 return 0;
55 }
56
firmware_cancel_cb(const uint16_t obj_inst_id)57 static int firmware_cancel_cb(const uint16_t obj_inst_id)
58 {
59 LOG_INF("FIRMWARE: Update canceled");
60 return 0;
61 }
62
init_firmware_update(void)63 static int init_firmware_update(void)
64 {
65 /* setup data buffer for block-wise transfer */
66 lwm2m_register_pre_write_callback(&LWM2M_OBJ(5, 0, 0), firmware_get_buf);
67 lwm2m_firmware_set_write_cb(firmware_block_received_cb);
68
69 /* register cancel callback */
70 lwm2m_firmware_set_cancel_cb(firmware_cancel_cb);
71 lwm2m_firmware_set_update_cb(firmware_update_cb);
72
73 lwm2m_create_res_inst(&LWM2M_OBJ(5, 0, 8, 0));
74 lwm2m_set_res_buf(&LWM2M_OBJ(5, 0, 8, 0), &supported_protocol[0],
75 sizeof(supported_protocol[0]),
76 sizeof(supported_protocol[0]), 0);
77
78 return 0;
79 }
80 LWM2M_APP_INIT(init_firmware_update);
81