ucloud-iot-device-sdk-c/samples/ota/ota_sample.c

203 lines
5.5 KiB
C

/*
* Copyright (C) 2012-2019 UCloud. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include "uiot_export.h"
#include "uiot_import.h"
#include "uiot_export_ota.h"
#define UIOT_MY_PRODUCT_SN "PRODUCT_SN"
#define UIOT_MY_DEVICE_SN "DEVICE_SN"
#define UIOT_MY_DEVICE_SECRET "DEVICE_SECRET"
#define OTA_BUF_LEN (1024)
static void event_handler(void *pClient, void *handle_context, MQTTEventMsg *msg)
{
switch(msg->event_type) {
case MQTT_EVENT_UNDEF:
LOG_INFO("undefined event occur.\n");
break;
case MQTT_EVENT_DISCONNECT:
LOG_INFO("MQTT disconnect.\n");
break;
case MQTT_EVENT_RECONNECT:
LOG_INFO("MQTT reconnect.\n");
break;
case MQTT_EVENT_SUBSCRIBE_SUCCESS:
LOG_INFO("subscribe success.\n");
break;
case MQTT_EVENT_SUBSCRIBE_TIMEOUT:
LOG_INFO("subscribe wait ack timeout.\n");
break;
case MQTT_EVENT_SUBSCRIBE_NACK:
LOG_INFO("subscribe nack.\n");
break;
case MQTT_EVENT_PUBLISH_SUCCESS:
LOG_INFO("publish success.\n");
break;
case MQTT_EVENT_PUBLISH_TIMEOUT:
LOG_INFO("publish timeout.\n");
break;
case MQTT_EVENT_PUBLISH_NACK:
LOG_INFO("publish nack.\n");
break;
default:
LOG_INFO("Should NOT arrive here.\n");
break;
}
}
static int _setup_connect_init_params(MQTTInitParams* initParams)
{
initParams->device_sn = UIOT_MY_DEVICE_SN;
initParams->product_sn = UIOT_MY_PRODUCT_SN;
initParams->device_secret = UIOT_MY_DEVICE_SECRET;
initParams->command_timeout = UIOT_MQTT_COMMAND_TIMEOUT;
initParams->keep_alive_interval = UIOT_MQTT_KEEP_ALIVE_INTERNAL;
initParams->auto_connect_enable = 1;
initParams->event_handler.h_fp = event_handler;
return SUCCESS_RET;
}
int main(int argc, char **argv)
{
int rc;
int ota_over = 0;
bool upgrade_fetch_success = true;
// 用于存放云端下发的固件版本
char msg_version[33];
FILE *fp;
char buf_ota[OTA_BUF_LEN];
MQTTInitParams init_params = DEFAULT_MQTT_INIT_PARAMS;
rc = _setup_connect_init_params(&init_params);
if (rc != SUCCESS_RET) {
return rc;
}
void *client = IOT_MQTT_Construct(&init_params);
if (client != NULL) {
LOG_INFO("MQTT Construct Success");
} else {
LOG_ERROR("MQTT Construct Failed");
return FAILURE_RET;
}
void *h_ota = IOT_OTA_Init(UIOT_MY_PRODUCT_SN, UIOT_MY_DEVICE_SN, client);
if (NULL == h_ota) {
LOG_ERROR("init OTA failed");
return FAILURE_RET;
}
/* Must report version first */
if (IOT_OTA_ReportVersion(h_ota, "1.0.0") < 0) {
LOG_ERROR("report OTA version failed");
return FAILURE_RET;
}
if (IOT_OTA_RequestFirmware(h_ota, "1.0.0") < 0) {
LOG_ERROR("Request firmware failed");
return FAILURE_RET;
}
if (NULL == (fp = fopen("ota.bin", "wb+"))) {
LOG_ERROR("open file failed");
return FAILURE_RET;
}
do {
uint32_t firmware_valid;
LOG_INFO("wait for ota upgrade command...");
IOT_MQTT_Yield(client, 100);
if (IOT_OTA_IsFetching(h_ota)) {
char version[33], md5sum[33];
uint32_t size_downloaded, size_file;
do {
int len = IOT_OTA_FetchYield(h_ota, buf_ota, OTA_BUF_LEN, 1);
if (len > 0) {
if (1 != fwrite(buf_ota, len, 1, fp)) {
LOG_ERROR("write data to file failed");
upgrade_fetch_success = false;
break;
}
} else if (len < 0) {
LOG_ERROR("download fail rc=%d", len);
upgrade_fetch_success = false;
break;
}
/* get OTA information */
IOT_OTA_Ioctl(h_ota, OTA_IOCTL_FETCHED_SIZE, &size_downloaded, 4);
IOT_OTA_Ioctl(h_ota, OTA_IOCTL_FILE_SIZE, &size_file, 4);
IOT_OTA_Ioctl(h_ota, OTA_IOCTL_MD5SUM, md5sum, 33);
IOT_OTA_Ioctl(h_ota, OTA_IOCTL_VERSION, version, 33);
IOT_OTA_Ioctl(h_ota, OTA_IOCTL_VERSION, msg_version, 33);
IOT_MQTT_Yield(client, 100);
} while (!IOT_OTA_IsFetchFinish(h_ota));
/* Must check MD5 match or not */
if (upgrade_fetch_success) {
IOT_OTA_Ioctl(h_ota, OTA_IOCTL_CHECK_FIRMWARE, &firmware_valid, 4);
if (0 == firmware_valid) {
LOG_ERROR("The firmware is invalid");
upgrade_fetch_success = false;
} else {
LOG_INFO("The firmware is valid");
upgrade_fetch_success = true;
}
}
ota_over = 1;
}
HAL_SleepMs(2000);
} while(!ota_over);
if (upgrade_fetch_success)
{
HAL_SleepMs(1000);
IOT_OTA_ReportSuccess(h_ota, msg_version);
}
fclose(fp);
IOT_OTA_Destroy(h_ota);
IOT_MQTT_Destroy(&client);
return 0;
}