@@ -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
298367static 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