Skip to content

Commit a83d7a2

Browse files
committed
feat(zigbee): Add newest version of OTA handler
1 parent 331375a commit a83d7a2

File tree

2 files changed

+137
-68
lines changed

2 files changed

+137
-68
lines changed

libraries/Zigbee/src/ZigbeeEP.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class ZigbeeEP {
108108
return _allow_multiple_binding;
109109
}
110110

111-
void addOTAClient(uint32_t file_version = 0x01010101, uint16_t manufacturer = 0x1001, uint16_t image_type = 0x1011,
111+
void addOTAClient(uint32_t file_version = 0x01010100, uint16_t manufacturer = 0x1001, uint16_t image_type = 0x1011,
112112
uint32_t downloaded_file_ver = 0x01010101, uint16_t hw_version = 0x0101, uint8_t max_data_size = 223);
113113
void requestOTAUpdate();
114114

libraries/Zigbee/src/ZigbeeHandlers.cpp

Lines changed: 136 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -219,80 +219,149 @@ static esp_err_t zb_window_covering_movement_resp_handler(const esp_zb_zcl_windo
219219
return ESP_OK;
220220
}
221221

222-
static esp_err_t zb_ota_upgrade_status_handler(const esp_zb_zcl_ota_upgrade_value_message_t *message)
222+
//OTA Upgrade
223+
#define OTA_ELEMENT_HEADER_LEN 6 /* OTA element format header size include tag identifier and length field */
224+
225+
/**
226+
* @name Enumeration for the tag identifier denotes the type and format of the data within the element
227+
* @anchor esp_ota_element_tag_id_t
228+
*/
229+
typedef enum esp_ota_element_tag_id_e {
230+
UPGRADE_IMAGE = 0x0000, /*!< Upgrade image */
231+
} esp_ota_element_tag_id_t;
232+
233+
static const esp_partition_t *s_ota_partition = NULL;
234+
static esp_ota_handle_t s_ota_handle = 0;
235+
static bool s_tagid_received = false;
236+
237+
static esp_err_t esp_element_ota_data(uint32_t total_size, const void *payload, uint16_t payload_size, void **outbuf, uint16_t *outlen)
223238
{
224-
static const esp_partition_t *s_ota_partition = NULL;
225-
static esp_ota_handle_t s_ota_handle = 0;
239+
static uint16_t tagid = 0;
240+
void *data_buf = NULL;
241+
uint16_t data_len;
226242

227-
static uint32_t total_size = 0;
228-
static uint32_t offset = 0;
229-
static int64_t start_time = 0;
230-
esp_err_t ret = ESP_OK;
243+
if (!s_tagid_received) {
244+
uint32_t length = 0;
245+
if (!payload || payload_size <= OTA_ELEMENT_HEADER_LEN) {
246+
log_e("Invalid element format");
247+
return ESP_ERR_INVALID_ARG;
248+
}
231249

232-
if (message->info.status == ESP_ZB_ZCL_STATUS_SUCCESS) {
233-
switch (message->upgrade_status) {
234-
case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_START:
235-
log_i("Zigbee OTA - Upgrade start");
236-
start_time = esp_timer_get_time();
237-
s_ota_partition = esp_ota_get_next_update_partition(NULL);
238-
assert(s_ota_partition);
239-
ret = esp_ota_begin(s_ota_partition, 0, &s_ota_handle);
240-
if(ret == ESP_OK) {
241-
log_i("Zigbee OTA - OTA partition begin");
242-
} else {
243-
log_e("Zigbee OTA - Failed to begin OTA partition, status: %s", esp_err_to_name(ret));
244-
return ret;
245-
}
246-
break;
247-
case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_RECEIVE:
248-
total_size = message->ota_header.image_size;
249-
offset += message->payload_size;
250-
log_i("Zigbee OTA - Client receives data: progress [%ld/%ld]", offset, total_size);
251-
if (message->payload_size && message->payload) {
252-
ret = esp_ota_write(s_ota_handle, (const void *)message->payload, message->payload_size);
253-
if(ret == ESP_OK) {
254-
log_i("Zigbee OTA - Write OTA data to partition");
255-
} else {
256-
log_e("Zigbee OTA - Failed to write OTA data to partition, status: %s", esp_err_to_name(ret));
250+
tagid = *(const uint16_t *)payload;
251+
length = *(const uint32_t *)(payload + sizeof(tagid));
252+
if ((length + OTA_ELEMENT_HEADER_LEN) != total_size) {
253+
log_e("Invalid element length [%ld/%ld]", length, total_size);
254+
return ESP_ERR_INVALID_ARG;
255+
}
256+
257+
s_tagid_received = true;
258+
259+
data_buf = (void *)(payload + OTA_ELEMENT_HEADER_LEN);
260+
data_len = payload_size - OTA_ELEMENT_HEADER_LEN;
261+
} else {
262+
data_buf = (void *)payload;
263+
data_len = payload_size;
264+
}
265+
266+
switch (tagid) {
267+
case UPGRADE_IMAGE:
268+
*outbuf = data_buf;
269+
*outlen = data_len;
270+
break;
271+
default:
272+
log_e("Unsupported element tag identifier %d", tagid);
273+
return ESP_ERR_INVALID_ARG;
274+
break;
275+
}
276+
277+
return ESP_OK;
278+
}
279+
280+
static esp_err_t zb_ota_upgrade_status_handler(const esp_zb_zcl_ota_upgrade_value_message_t *message)
281+
{
282+
static uint32_t total_size = 0;
283+
static uint32_t offset = 0;
284+
static int64_t start_time = 0;
285+
esp_err_t ret = ESP_OK;
286+
287+
if (message->info.status == ESP_ZB_ZCL_STATUS_SUCCESS) {
288+
switch (message->upgrade_status) {
289+
case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_START:
290+
log_i("Zigbee - OTA upgrade start");
291+
start_time = esp_timer_get_time();
292+
s_ota_partition = esp_ota_get_next_update_partition(NULL);
293+
assert(s_ota_partition);
294+
#if CONFIG_ZB_DELTA_OTA
295+
ret = esp_delta_ota_begin(s_ota_partition, 0, &s_ota_handle);
296+
#else
297+
ret = esp_ota_begin(s_ota_partition, 0, &s_ota_handle);
298+
#endif
299+
if(ret != ESP_OK) {
300+
log_e("Zigbee - Failed to begin OTA partition, status: %s", esp_err_to_name(ret));
257301
return ret;
258302
}
303+
break;
304+
case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_RECEIVE:
305+
total_size = message->ota_header.image_size;
306+
offset += message->payload_size;
307+
log_i("Zigbee - OTA Client receives data: progress [%ld/%ld]", offset, total_size);
308+
if (message->payload_size && message->payload) {
309+
uint16_t payload_size = 0;
310+
void *payload = NULL;
311+
ret = esp_element_ota_data(total_size, message->payload, message->payload_size, &payload, &payload_size);
312+
if(ret != ESP_OK) {
313+
log_e("Zigbee - Failed to element OTA data, status: %s", esp_err_to_name(ret));
314+
return ret;
315+
}
316+
#if CONFIG_ZB_DELTA_OTA
317+
ret = esp_delta_ota_write(s_ota_handle, payload, payload_size);
318+
#else
319+
ret = esp_ota_write(s_ota_handle, (const void *)payload, payload_size);
320+
#endif
321+
if(ret != ESP_OK) {
322+
log_e("Zigbee - Failed to write OTA data to partition, status: %s", esp_err_to_name(ret));
323+
return ret;
324+
}
325+
}
326+
break;
327+
case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_APPLY:
328+
log_i("Zigbee - OTA upgrade apply");
329+
break;
330+
case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_CHECK:
331+
ret = offset == total_size ? ESP_OK : ESP_FAIL;
332+
offset = 0;
333+
total_size = 0;
334+
s_tagid_received = false;
335+
log_i("Zigbee - OTA upgrade check status: %s", esp_err_to_name(ret));
336+
break;
337+
case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_FINISH:
338+
log_i("Zigbee - OTA Finish");
339+
log_i("Zigbee - OTA Information: version: 0x%lx, manufacturer code: 0x%x, image type: 0x%x, total size: %ld bytes, cost time: %lld ms,",
340+
message->ota_header.file_version, message->ota_header.manufacturer_code, message->ota_header.image_type,
341+
message->ota_header.image_size, (esp_timer_get_time() - start_time) / 1000);
342+
#if CONFIG_ZB_DELTA_OTA
343+
ret = esp_delta_ota_end(s_ota_handle);
344+
#else
345+
ret = esp_ota_end(s_ota_handle);
346+
#endif
347+
if(ret != ESP_OK) {
348+
log_e("Zigbee - Failed to end OTA partition, status: %s", esp_err_to_name(ret));
349+
return ret;
350+
}
351+
ret = esp_ota_set_boot_partition(s_ota_partition);
352+
if(ret != ESP_OK) {
353+
log_e("Zigbee - Failed to set OTA boot partition, status: %s", esp_err_to_name(ret));
354+
return ret;
355+
}
356+
log_w("Zigbee - Prepare to restart system");
357+
esp_restart();
358+
break;
359+
default:
360+
log_i("Zigbee - OTA status: %d", message->upgrade_status);
361+
break;
259362
}
260-
break;
261-
case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_APPLY:
262-
log_i("Zigbee OTA - Upgrade apply");
263-
break;
264-
case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_CHECK:
265-
ret = offset == total_size ? ESP_OK : ESP_FAIL;
266-
log_i("Zigbee OTA - Upgrade check status: %s", esp_err_to_name(ret));
267-
break;
268-
case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_FINISH:
269-
log_i("Zigbee OTA - Finish");
270-
log_i("Zigbee OTA - Information: version: 0x%lx, manufacturer code: 0x%x, image type: 0x%x, total size: %ld bytes, cost time: %lld ms",
271-
message->ota_header.file_version, message->ota_header.manufacturer_code, message->ota_header.image_type,
272-
message->ota_header.image_size, (esp_timer_get_time() - start_time) / 1000);
273-
ret = esp_ota_end(s_ota_handle);
274-
if(ret == ESP_OK) {
275-
log_i("Zigbee OTA - OTA partition end");
276-
} else {
277-
log_e("Zigbee OTA - Failed to end OTA partition, status: %s", esp_err_to_name(ret));
278-
return ret;
279-
}
280-
ret = esp_ota_set_boot_partition(s_ota_partition);
281-
if(ret == ESP_OK) {
282-
log_i("Zigbee OTA - Set OTA boot partition");
283-
} else {
284-
log_e("Zigbee OTA - Failed to set OTA boot partition, status: %s", esp_err_to_name(ret));
285-
return ret;
286-
}
287-
log_w("Zigbee OTA - Prepare to restart system");
288-
esp_restart();
289-
break;
290-
default:
291-
log_i("Zigbee OTA - Status: %d", message->upgrade_status);
292-
break;
293363
}
294-
}
295-
return ret;
364+
return ret;
296365
}
297366

298367
static esp_err_t zb_ota_upgrade_query_image_resp_handler(const esp_zb_zcl_ota_upgrade_query_image_resp_message_t *message)

0 commit comments

Comments
 (0)