#if ENABLE_MQTT_FUNC
Mqtt_Send_Data();
#endif
- #if ENABLE_SNTP_TIME
- //测试打印系统时间
- time_t now = 0;
- time(&now);
-
- // 使用 localtime_r(线程安全,不会被覆盖)
- struct tm time_info;
- localtime_r(&now, &time_info);
-
- // tm_year + 1900
- ESP_LOGI(MAIN_TAG, "时间: %d-%02d-%02d-%2d-%02d-%02d",
- time_info.tm_year + 1900, // 正确!
- time_info.tm_mon + 1,
- time_info.tm_mday,time_info.tm_hour,time_info.tm_min,time_info.tm_sec);
+ #if ENABLE_SYNC_SNTP_TIME
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+
+ struct tm tm_info;
+ localtime_r(&tv.tv_sec, &tm_info);
+
+ char buf[64];
+ strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm_info);
+
+ ESP_LOGI("TIME", "当前时间:%s", buf);
#endif
+ Https_Ota_Check_TimeOut();
// 在这里添加每秒执行的代码
+ #if ENABLE_HTTPS_OTA_FUNC
ESP_LOGI(MAIN_TAG, "onesec_timer:ota %d ota_cur_status %d %" PRIu32 " bytes",common_setting.https_ota_cfg.https_ota_start_flag,g_ota_status,esp_get_free_heap_size());
-
+ #else
+ ESP_LOGI(MAIN_TAG, "onesec_timer:ota %d %" PRIu32 " bytes",common_setting.https_ota_cfg.https_ota_start_flag,esp_get_free_heap_size());
+ #endif
// 例如:检查状态、发送心跳等
}
+
#if (IOT_ENABLE)
#if (1)
const char* device_name = "PXN-W GTL";
const uint16_t mcu_pid = 0xA00B;
#endif
#endif
+// 加在这里
void Main_Loop_Task(void *pvParameters)
{
Mqtt_Connect_Status_Check();
#endif
- #if ENABLE_SNTP_TIME
+ #if ENABLE_SYNC_SNTP_TIME
wait_for_sntp_sync();
#endif
// heart beat
#endif
-
+
// ESP_LOGI(MAIN_TAG, "chip_id:%s chip_version:%d\n",chip_info.model,chip_info.res);
//等待wifi稳定再去连接wifi
// ESP_LOGI(MAIN_TAG, "[APP] Free memory after wifi: %" PRIu32 " bytes", esp_get_free_heap_size());
#include "https_ota.h"
#include "project_common.h"
#include "user_mqtt.h"
-
+#include "wifi.h"
#if (ENABLE_HTTPS_OTA_FUNC)
static const char *HTTPS_OTA = "HTTPS_OTA";
#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
ota_status_t g_ota_status = OTA_STATUS_IDLE; // 全局OTA状态
+#define HTTPS_OTA_TIMEOUT_TIME 300 //单位s
+
static uint8_t retry_ota_num = 0;
static bool ota_full_failed_flag = false; // 新增:三次失败锁定标记
-#define HTTPS_OTA_RETRY_NUM 3
+static uint16_t ota_timeout_count = 0;
+#define HTTPS_OTA_RETRY_NUM 0
#define OTA_URL_SIZE 255
#define OTA_HTTP_OTA 0 //是否使用http请求ota固件包
return err;
}
+static uint8_t ota_timeout_req = 0; //超时升级失败
//ota升级失败重复升级次数 连续三次都升级不成功不升级了
-
-static void https_ota_task_cb(void *pvParameter)
+esp_https_ota_handle_t https_ota_handle = NULL;
+static void Https_Ota_Task_Cb(void *pvParameter)
{
+ ota_timeout_count = HTTPS_OTA_TIMEOUT_TIME;
Mqtt_Disconnect(); // 关闭MQTTs
// 2. 延迟一下确保资源释放
vTaskDelay(200 / portTICK_PERIOD_MS);
-
+ https_ota_handle=NULL;
ESP_LOGI(HTTPS_OTA, "Starting Advanced OTA example:%s\n",https_ota_url);
g_ota_status = OTA_STATUS_UPGRADING; // 标记升级开始
+ Https_Ota_Status_Set(g_ota_status);
+ vTaskDelay(500 / portTICK_PERIOD_MS);
esp_err_t ota_finish_err = ESP_OK;
esp_http_client_config_t config = {
.url = https_ota_url,
- .timeout_ms = 5000,
+ .timeout_ms = 20000,
.keep_alive_enable = false,
};
#if (!OTA_HTTP_OTA)
ota_config.partial_http_download=true;
#endif
- esp_https_ota_handle_t https_ota_handle = NULL;
esp_err_t err = esp_https_ota_begin(&ota_config, &https_ota_handle);
if (err != ESP_OK) {
ESP_LOGI(HTTPS_OTA, "ESP HTTPS OTA Begin failed");
ESP_LOGI(HTTPS_OTA, "image header verification success");
}
while (1) {
+ if(ota_timeout_req){ //网络不好超时 设置上报状态创建任务失败;还在升级中就退出
+ ota_timeout_req=0;
+ g_ota_status = OTA_STATUS_FAILED; // 也算是失败了 网络太差了升级超时了
+ if(ota_timeout_count)
+ {
+ ESP_LOGI(HTTPS_OTA, "user stop!!!!");
+ }else{
+ ESP_LOGI(HTTPS_OTA, "timeout!!!!");
+ }
+
+ break;
+ }
err = esp_https_ota_perform(https_ota_handle);
+
if (err != ESP_ERR_HTTPS_OTA_IN_PROGRESS) {
ESP_LOGI(HTTPS_OTA, "Image err: %d",err);
break;
// the OTA image was not completely received and user can customise the response to this situation.
ESP_LOGI(HTTPS_OTA, "Complete data was not received. continue ota %d",common_setting.wifi_status.wifi_state);
g_ota_status = OTA_STATUS_FAILED; // ← 失败
- // vTaskDelay(50 / portTICK_PERIOD_MS);
- // if(common_setting.wifi_status.wifi_state == 0)
- // {
- // retry_ota_num=0;
- // common_setting.https_ota_cfg.https_ota_start_flag=0;
- // }else{
- // xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
- // }
+
goto ota_end;
// vTaskDelete(NULL);
} else {
if ((err == ESP_OK) && (ota_finish_err == ESP_OK)) {
ESP_LOGI(HTTPS_OTA, "ESP_HTTPS_OTA upgrade successful. Rebooting ...");
g_ota_status = OTA_STATUS_SUCCESS; //成功
+ ota_timeout_count=0;
+ //成功不走下面失败的
+ uint8_t ret = Https_Ota_Status_Set(g_ota_status);
+
+ //
+ g_ota_status = OTA_STATUS_IDLE;
+ common_setting.https_ota_cfg.https_ota_start_flag = 0;
+ if(!ret)
+ {
+ if(common_setting.wifi_status.wifi_state == 1){
+ xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);
+ }
+ }
+ vTaskDelete(NULL);
} else {
if (ota_finish_err == ESP_ERR_OTA_VALIDATE_FAILED) {
ESP_LOGI(HTTPS_OTA, "Image validation failed, image is corrupted");
}
ESP_LOGI(HTTPS_OTA, "ESP_HTTPS_OTA upgrade failed 0x%x", ota_finish_err);
- // vTaskDelay(50 / portTICK_PERIOD_MS);
- // xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
g_ota_status = OTA_STATUS_FAILED; // ← 失败
- // vTaskDelete(NULL);
goto ota_end;
}
}
ota_end:
- // xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
- // esp_https_ota_abort(https_ota_handle);
- // vTaskDelete(NULL);
-
- esp_https_ota_abort(https_ota_handle);
- //网络断开不在继续升级
- if (retry_ota_num >= HTTPS_OTA_RETRY_NUM || common_setting.wifi_status.wifi_state == 0) {
- ota_full_failed_flag = true;
- common_setting.https_ota_cfg.https_ota_start_flag = 0;
- ESP_LOGE(HTTPS_OTA, "OTA retry %d failed!", HTTPS_OTA_RETRY_NUM);
- xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);//连接mqtt
- } else {
- ESP_LOGW(HTTPS_OTA, "OTA faile retry(%d/%d)", retry_ota_num + 1, HTTPS_OTA_RETRY_NUM);
- xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
+
+ if(https_ota_handle != NULL && g_ota_status != OTA_STATUS_SUCCESS){
+ esp_https_ota_abort(https_ota_handle); //一定要在ota任务没有删除的时候调用 否则会死机 升级成功不能调用这个函数
+ https_ota_handle = NULL;
}
+ ESP_LOGI(HTTPS_OTA, "ESP_HTTPS_OTA upgrade failed");
+ ota_timeout_count=0;
+ // (失败/超时 都在这里发)
+ Https_Ota_Status_Set(g_ota_status);
+ //
+ g_ota_status = OTA_STATUS_IDLE;
+ common_setting.https_ota_cfg.https_ota_start_flag = 0;
+
+ if(common_setting.wifi_status.wifi_state == 1){
+ xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);
+ }
+
+
+ // 删除
vTaskDelete(NULL);
}
//ota版本校验 不一致需要升级 一直不需要升级ota
-uint8_t https_ota_version_check(void)
+uint8_t Https_Ota_Version_Check(void)
{
- return 1;
+ return 0;
}
-void https_ota_start(void)
+void Https_Ota_Start(void)
{
if(g_ota_status != 0 && common_setting.https_ota_cfg.https_ota_start_flag == 1)
{
}
ESP_LOGI(HTTPS_OTA, "ota is start\n");
retry_ota_num=0;
+ ota_timeout_count = 0;
ota_full_failed_flag = false; // 新OTA任务,清空三次失败锁
common_setting.https_ota_cfg.https_ota_start_flag = 1;
xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
}
-
-void https_ota_stop(void)
+void Https_Ota_Stop(void)
{
- ESP_LOGI(HTTPS_OTA, "ota is stop\n");
- retry_ota_num=0;
- ota_full_failed_flag = false; //
- common_setting.https_ota_cfg.https_ota_start_flag = 0;
- xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);
+ if(g_ota_status != OTA_STATUS_SUCCESS && g_ota_status > 0 && common_setting.https_ota_cfg.https_ota_start_flag == 1)
+ {
+ if(!ota_timeout_req){
+ ota_timeout_req = 1;
+ }
+ }
+
}
-void https_ota_task(void)
+
+void Https_Ota_Task(void)
{
if(ota_full_failed_flag)
{
+ retry_ota_num=0;
+ ota_timeout_count = 0;
+ g_ota_status = OTA_STATUS_IDLE;
common_setting.https_ota_cfg.https_ota_start_flag=0;
return;
}
- retry_ota_num++;
- if(retry_ota_num > HTTPS_OTA_RETRY_NUM){ //重试三次ota升级失败后不再升级 后续要重连mqtt
- common_setting.https_ota_cfg.https_ota_start_flag=0;
- retry_ota_num=0;
- xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);//连接mqtt
- return;
+ if(HTTPS_OTA_RETRY_NUM > 0)
+ {
+ retry_ota_num++;
+ if(retry_ota_num > HTTPS_OTA_RETRY_NUM){ //重试三次ota升级失败后不再升级 后续要重连mqtt
+ common_setting.https_ota_cfg.https_ota_start_flag=0;
+ retry_ota_num=0;
+ g_ota_status = OTA_STATUS_IDLE;
+ xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);//连接mqtt
+ return;
+ }
}
- BaseType_t ret = xTaskCreate(&https_ota_task_cb, "https_ota_task", HTTPS_OTA_STACK_SIZE, NULL, 4, NULL);
+
+ BaseType_t ret = xTaskCreate(&Https_Ota_Task_Cb, "https_ota_task", HTTPS_OTA_STACK_SIZE, NULL, 4, NULL);
if(ret !=pdPASS )
{
- xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
- ESP_LOGI(HTTPS_OTA, "task failed\n");
+ if(HTTPS_OTA_RETRY_NUM > 0){
+ xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
+ }
}else{
+
ESP_LOGI(HTTPS_OTA, "task success\n");
}
}
+
+void Https_Ota_Check_TimeOut(void)
+{
+ if(g_ota_status != OTA_STATUS_SUCCESS && g_ota_status > 0 && common_setting.https_ota_cfg.https_ota_start_flag == 1) //一直没有成功
+ {
+ if(ota_timeout_count > 0)
+ {
+ ota_timeout_count--;
+
+ if(ota_timeout_count== 0)
+ {
+ if(!ota_timeout_req){
+ ota_timeout_req=1;
+ }
+ }
+ }
+ }
+
+}
// wifi事件处理函数 断开 连接 获取ip等事件都会进入这个函数
static void ota_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
xEventGroupClearBits(common_event_group, COMMON_HTTPS_OTA_BIT);
vTaskDelay(50 / portTICK_PERIOD_MS);
- https_ota_task();
+ Https_Ota_Task();
+ }
+
+}
+static esp_err_t _https_ota_event_handler(esp_http_client_event_t *evt)
+{
+ switch (evt->event_id) {
+ case HTTP_EVENT_ERROR:
+ ESP_LOGI(HTTPS_OTA, "HTTP_EVENT_ERROR");
+ break;
+ case HTTP_EVENT_ON_CONNECTED:
+ ESP_LOGI(HTTPS_OTA, "HTTP_EVENT_ON_CONNECTED");
+ break;
+ case HTTP_EVENT_HEADER_SENT:
+ ESP_LOGI(HTTPS_OTA, "HTTP_EVENT_HEADER_SENT");
+ break;
+ case HTTP_EVENT_ON_HEADER:
+ // ESP_LOGI(HTTP_TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
+ break;
+ case HTTP_EVENT_ON_DATA:
+ // ESP_LOGI(HTTP_TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
+ // if (!esp_http_client_is_chunked_response(evt->client))
+ // {
+ // printf("%.*s", evt->data_len, (char*)evt->data);
+ // uint8_t *data = (uint8_t*)evt->data;
+ // for(uint32_t i=0;i<evt->data_len;i++)
+ // {
+ // printf("%02x ", *(data++));
+ // }
+ // printf("\n");
+ // }
+ break;
+ case HTTP_EVENT_ON_FINISH:
+ ESP_LOGI(HTTPS_OTA, "HTTP_EVENT_ON_FINISH");
+ break;
+ case HTTP_EVENT_DISCONNECTED:
+ ESP_LOGI(HTTPS_OTA, "HTTP_EVENT_DISCONNECTED");
+ break;
+ case HTTP_EVENT_REDIRECT:
+ ESP_LOGI(HTTPS_OTA, "HTTP_EVENT_REDIRECT");
+ break;
+ }
+ return ESP_OK;
+}
+uint8_t Https_Ota_Status_Set(uint8_t ota_status)
+{
+
+ if(common_setting.wifi_status.wifi_state==0)
+ {
+ return 0;
+ }
+ // http://192.168.66.85:8089/iot/firmware/task/detailadd {
+ // "serialNumber": "PXN1LJ1QUR078E",
+ // "upgradeStatus": 4 升级失败 3升级成功,
+ // "detailMsg": "升级成功"
+ // }
+ esp_http_client_config_t http_config =
+ {
+ .event_handler = _https_ota_event_handler,
+ .disable_auto_redirect = true,
+ .keep_alive_enable = true,
+ };
+ int result = 0;
+ esp_http_client_handle_t http_client = NULL;
+ for(uint8_t retry=0;retry<1;retry++)
+ {
+ result = 0;
+ http_client=NULL;
+
+ const char path[] = "http://192.168.66.85:8089/iot/firmware/task/detailadd";
+
+
+ http_config.url = path;
+ cJSON *pRoot = cJSON_CreateObject();
+
+ if(pRoot == NULL)
+ {
+ ESP_LOGE(HTTPS_OTA, "cJSON_CreateObject fail");
+ result = 3;
+ vTaskDelay(50);
+ continue;
+ }
+ cJSON_AddStringToObject(pRoot, "serialNumber", (const char*)common_storage.net_info.serial_number);
+ if(ota_status == OTA_STATUS_SUCCESS)
+ {
+ cJSON_AddNumberToObject(pRoot,"upgradeStatus", 3);
+ cJSON_AddStringToObject(pRoot, "detailMsg", "升级成功");
+ }else if(ota_status == OTA_STATUS_UPGRADING)
+ {
+ cJSON_AddStringToObject(pRoot, "detailMsg", "升级中");
+ cJSON_AddNumberToObject(pRoot,"upgradeStatus", 5);
+ }
+ else{
+ cJSON_AddStringToObject(pRoot, "detailMsg", "升级失败");
+ cJSON_AddNumberToObject(pRoot,"upgradeStatus", 4);
+ }
+
+
+ char *post_data = cJSON_Print(pRoot);
+ if(strlen(post_data) == 0 && post_data == NULL)//数据为空说明cJSON构建失败
+ {
+ cJSON_Delete(pRoot);
+
+ vTaskDelay(50);
+ continue;
+ }
+ ESP_LOGI(HTTPS_OTA, "put data:%s\n", post_data);
+ ESP_LOGI(HTTPS_OTA, "http_config.url = %s", http_config.url);
+
+ http_client = esp_http_client_init(&http_config);
+ if(http_client == NULL)
+ {
+
+ ESP_LOGI(HTTPS_OTA, "http_config.url = %s", http_config.url);
+ cJSON_free(post_data);
+ cJSON_Delete(pRoot);
+ vTaskDelay(50);
+ continue;
+ }
+ ESP_LOGI(HTTPS_OTA, "http_config.token = %s", (char *)common_storage.net_info.http_token_str);
+ esp_http_client_set_header(http_client, "Authorization", (const char*)common_storage.net_info.http_token_str);
+ esp_http_client_set_method(http_client, HTTP_METHOD_POST);
+ esp_http_client_set_header(http_client, "Content-Type", "application/json");
+
+ esp_http_client_set_post_field(http_client, post_data, strlen(post_data));
+ esp_err_t err = esp_http_client_perform(http_client);
+ if (err == ESP_OK)
+ {
+ int status_code = esp_http_client_get_status_code(http_client);
+ int read_len = esp_http_client_get_content_length(http_client);
+ if(status_code == 200)
+ {
+ result = 1;
+ }
+ else
+ {
+ result = 2;
+ }
+ ESP_LOGI(HTTPS_OTA, "PUT Status = %d, content_length = %d", status_code, read_len);
+ }
+ else
+ {
+ result = 2;
+ ESP_LOGE(HTTPS_OTA, "PUTfailed: %s", esp_err_to_name(err));
+ }
+ cJSON_free(post_data);
+ cJSON_Delete(pRoot);
+ if(http_client != NULL)
+ {
+ esp_http_client_close(http_client);
+ esp_http_client_cleanup(http_client);
+ http_client=NULL;
+ }
+
+
+ // 结果
+ if(result == 1)
+ {
+ break;
+ }
+ vTaskDelay(50);
}
- if(g_ota_status == OTA_STATUS_SUCCESS)
+
+ if(ota_status == OTA_STATUS_SUCCESS)
{
+ Wifi_Stop();//断开wifi
esp_restart();
+ return 1;
}
+ return 0;
}
#endif
extern ota_status_t g_ota_status;
-void https_ota_task(void);
-void Https_Ota_Status_Check(void);
-uint8_t https_ota_version_check(void);
-void https_ota_start(void);
-void https_ota_close_ble_mqtt(void);
-void Https_Ota_Handler_Init(void);
-void https_ota_stop(void);
+void Https_Ota_Task(void);//ota升级任务
+void Https_Ota_Status_Check(void);//是否需要ota升级状态
+uint8_t Https_Ota_Version_Check(void); //固件版本检查
+
+void Https_Ota_Start(void); //开始ota升级
+void Https_Ota_Stop(void);
+void Https_Ota_Handler_Init(void); //ota注册回调
+uint8_t Https_Ota_Status_Set(uint8_t ota_status);//report_ota_status(uint8_t ota_status);
extern char https_ota_url[255];
+void Https_Ota_Check_TimeOut(void); //ota超时检查
+
#endif
#endif
\ No newline at end of file
net_pairing_reply.content[0] = 2;
net_pairing_reply.content[1] = data[4];
net_pairing_reply.content[2] = data[5];
- ESP_LOGI(COMMON_TAG, "net pairing wifi pwd crc32 err:%08x %08x\n", (unsigned int)Crc32_JAMCRC_Cal(&data[38], 64), (unsigned int)*(uint32_t*)&data[102]);
+ ESP_LOGI(COMMON_TAG, "net pairing wifi pwd crc32 err:%08x %08x\n", recv_crc, (unsigned int)*(uint32_t*)&data[102]);
break;
}
net_pairing_reply.content[5] |= 0x00;
common_setting.net_pairing_info.http_url_length = total_len;
common_setting.net_pairing_info.http_url_flag = 1;
+ common_storage.net_info.http_url_flag = 1;
ESP_LOGI(COMMON_TAG, "http crc success: %s net_pairing_reply.content[5]:%02x\n", common_setting.net_pairing_info.http_url,net_pairing_reply.content[5]);
}
else
memset(common_setting.net_pairing_info.http_url, 0x00, HTTP_URL_MAX_LEN+1);
net_pairing_reply.content[5] |= 0x20;
common_setting.net_pairing_info.http_url_flag = 0;
+ common_storage.net_info.http_url_flag = 0;
ESP_LOGI(COMMON_TAG, "http CRC: =%04x recv=%04x 0x%02x\n", calc_crc, packet_crc,net_pairing_reply.content[5]);
}
}
{
token_end=0;
token_end_flag=1;//本次接收的包是token包的第一包
- memset(common_setting.net_pairing_info.http_token, 0x00, NET_PAIRING_INFO_MAX_LEN+1);
+ memset(common_setting.net_pairing_info.http_token, 0x00, NET_PAIRING_INFO_MAX_LEN);
+ memset(common_storage.net_info.http_token_str,0x00,sizeof(common_storage.net_info.http_token_str));
}
//
if(packet_crc == calc_crc)
{
token_end=0;
- net_pairing_reply.content[5] |= 0x00;
+ net_pairing_reply.content[5] |= 0x00;
common_setting.net_pairing_info.http_token_length = total_len;
common_setting.net_pairing_info.http_token_flag = 1;
+
+ memcpy(common_storage.net_info.http_token_str,common_setting.net_pairing_info.http_token,sizeof(common_storage.net_info.http_token_str));
+ common_storage.net_info.http_token_flag =1;
ESP_LOGI(COMMON_TAG, "tokencrc success %s",common_setting.net_pairing_info.http_token);
}
else
memset(common_setting.net_pairing_info.http_token, 0x00, NET_PAIRING_INFO_MAX_LEN);
net_pairing_reply.content[5] |= 0x20;
common_setting.net_pairing_info.http_token_flag = 0;
+ common_storage.net_info.http_token_flag = 0;
ESP_LOGI(COMMON_TAG, "token CRC:=%04x recv=%04x", calc_crc, packet_crc);
}
}
if(packet_crc == calc_crc)
{
common_setting.net_pairing_info.user_id_flag = 1;
+ common_storage.net_info.user_id_flag =1;
net_pairing_reply.content[5] |= 0x00;
ESP_LOGI(COMMON_TAG, "user_id: %s\n",common_setting.net_pairing_info.user_id);
}
// common_setting.net_pairing_info.user_id=0;
memset(common_setting.net_pairing_info.user_id,0,sizeof(common_setting.net_pairing_info.user_id));
common_setting.net_pairing_info.user_id_flag = 0;
+ common_storage.net_info.user_id_flag =0;
// 校验失败
net_pairing_reply.content[5] |= 0x20;
ESP_LOGI(COMMON_TAG, "BLE user id crc16 err:%04x %04x\n",packet_crc, calc_crc);
}
-#if ENABLE_SNTP_TIME
+#if ENABLE_SYNC_SNTP_TIME
#include <time.h>
#include "sntp.h"
{
ESP_LOGI("NTP", "初始化时间同步...");
sntp_setoperatingmode(SNTP_OPMODE_POLL);
- sntp_setservername(0, "ntp.aliyun.com");
+ // sntp_setservername(0, "ntp.aliyun.com");
+ sntp_setservername(0,"pool.ntp.org");
+ sntp_set_sync_mode(SNTP_SYNC_MODE_IMMED); //
sntp_init();
}
-// 等待时间同步完成(官方可靠版)
-static uint8_t sntp_sync = 0;
+// 等待时间同步完成
+static uint8_t sntp_sync_init = 0;//初始化sntp标识 只初始化一次
+//等待同步sntp网络时间
void wait_for_sntp_sync(void)
{
- if(common_setting.wifi_status.wifi_state == 0) //wifi未连接
+ if(common_setting.time_flash_cfg.time_flash) //能读到flash里面的时间说明同步过一次时间不需要同步了
{
+
+ return;
+ }
+ if(common_setting.wifi_status.wifi_state == 0) //wifi未连接
+ {
return;
}
- if(sntp_sync) //同步一次不在同步
+ if(sntp_sync_init) //
{
return;
}
- sntp_sync=1;
- initialize_sntp();
+ sntp_sync_init =1;
+ initialize_sntp();//确保只初始化一次
// ==============================
//
// ==============================
const int timeout_ms = 15000;
int waited_ms = 0;
-
+ ESP_LOGI("TIME", "start sntp_get_sync_status: %d", sntp_get_sync_status());
while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET)
{
vTaskDelay(pdMS_TO_TICKS(200));
break;
}
}
-
+ ESP_LOGI("TIME", "end sntp_get_sync_status: %d", sntp_get_sync_status());
time_t now = 0;
time(&now);
-
+
// 时区
setenv("TZ", "CST-8", 1);
tzset();
char buf[64];
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &time_info);
ESP_LOGI("TIME", "time success: %s", buf);
+
+ if(sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET) //同步时间完成
+ {
+
+ int TimeZone = 8;//默认是东八区 8
+ ESP_LOGI("TIME", "ret : %d", ret);
+ common_setting.time_flash_cfg.time_flash=1;
+ sntp_sync_init=1;//同步成功
+ return;
+ }else{
+ sntp_sync_init=0;
+ return;
+ }
+
}
-#endif
\ No newline at end of file
+#endif
+
+
+time_t Get_Time_Stamp(void)
+{
+ time_t Time_Stamp = 0;
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+
+ Time_Stamp = tv.tv_sec;
+ return Time_Stamp;
+}
\ No newline at end of file
#define WIFI_SSID_MAX_LEN 32
#define WIFI_PWD_MAX_LEN 64
-#define NET_PAIRING_INFO_MAX_LEN 256
+#define NET_PAIRING_INFO_MAX_LEN 255
#define SERIAL_NUMBER_MAX_LEN 32
#define MQTT_SUB_URL_MAX_LEN 128
// WIFI
//是否需要同步sntp网络时间
-#define ENABLE_SNTP_TIME 0
+#define ENABLE_SYNC_SNTP_TIME 0
-#define MAIN_LOOP_INTERVAL 50
+#define MAIN_LOOP_INTERVAL 50
//蓝牙协议指令
typedef enum
{
uint8_t buffer[SSL_CERT_BUFFER_SIZE];
}__attribute__((packed)) SSL_CERT_T;
+#define HTTP_TOKEN_MAX 255
typedef union
{
struct
uint8_t device_id[32];
uint8_t mqtt_url_len;
char mqtt_sub_url[MQTT_SUB_URL_MAX_LEN+1];
+ uint8_t http_url_flag;
+ uint8_t http_token_flag;
+ uint8_t user_id_flag;
+ uint8_t http_token_str[HTTP_TOKEN_MAX-1];
+
+
};
}__attribute__((packed)) NET_INFO_T;
}__attribute__((packed)) MQTT_CONFIG_INFO_T;
+
+typedef struct
+{
+ uint8_t time_flash;//是否同步过时间 flash保存成功
+
+}__attribute__((packed)) TIME_FLASH_T;
typedef struct
{
uint8_t heart_beat_enable:1;
uint8_t mcu_info_got_flag:1;
+ uint8_t mcu_platform_mode;
uint8_t reserved:6;
// UNIVERSAL
//https ota
HTTPS_OTA_CONFIG_INFO_T https_ota_cfg;
+ TIME_FLASH_T time_flash_cfg;
}COMMON_SETTING_T;
-
+//获取时间戳单位是s
+time_t Get_Time_Stamp(void);
void network_request_replay(uint8_t status);
void get_chip_info(char *chip_id,uint8_t *chip_len);
void print_chip_info(void);
-#if ENABLE_SNTP_TIME
+#if ENABLE_SYNC_SNTP_TIME
void wait_for_sntp_sync(void);
#endif
#endif
{
common_setting.heart_beat_enable = 1;
common_setting.heart_beat_interval = data[3] * 1000;
+
+ }
+ if(data[2] >= 2)
+ {
+ common_setting.mcu_platform_mode = data[4];//mcu连接的pc的模式
+ ESP_LOGI(COMMON_TAG,"common_setting.mcu_platform_mode:%d\n",common_setting.mcu_platform_mode);
}
+
//0x01
}
break;
}
}
+
+
+// 保存当前时间到 Flash
+// 传入时区小时,例如:
+// 中国:8
+// 美国东部:-5
+// 美国太平洋:-8
+// 欧洲伦敦:0
+// 日本:9
+// struct timeval now;
+// gettimeofday(&now, NULL);
+
+// flash_time_t time_data;
+// time_data.utc_timestamp = now.tv_sec;
+// time_data.timezone_sec = timezone_hour * 3600; // 自动转秒
+
+
+// struct timeval tv = {
+// .tv_sec = time_data.utc_timestamp,
+// .tv_usec = 0
+// };
+// settimeofday(&tv, NULL);
+
+// // ==============================
+// // 关键:自动根据时区秒数设置时区
+// // ==============================
+// long tz_hour = (long)(time_data.timezone_sec/3600);
+// char tz_str[32];
+// sprintf(tz_str, "UTC%+ld", -tz_hour);
+// setenv("TZ", tz_str, 1);
+// tzset();
//清除配网信息
void User_Erase_Nimble_NetWork_Infor(void)
{
cJSON_AddStringToObject(root, "fw_version", fw_ver);
cJSON_AddStringToObject(root, "wifi_version", wifi_ver);
cJSON_AddStringToObject(root, "serial_id", (char *)common_storage.net_info.serial_number);
- cJSON_AddNumberToObject(root, "connected_platform", 2);
+ cJSON_AddNumberToObject(root, "connected_platform", common_setting.mcu_platform_mode);
cJSON_AddNumberToObject(root, "power_on", 0);
cJSON *pRoot = cJSON_CreateObject();
// cJSON_AddItemToObject(root,""thingsModelValue": "string",");
// 版本号格式化 0x0015 → V0021
char fw_ver[8] = {0}, wifi_ver[8] = {0};
- snprintf(fw_ver, sizeof(fw_ver), "%04u", common_setting.mcu_info.fw_version);
- snprintf(wifi_ver, sizeof(wifi_ver), "%04u", (unsigned int)FW_VERSION);
- if(FW_VERSION > 9999)
- {
-
- snprintf(wifi_ver, sizeof(wifi_ver), "%s","9999");
- }
+ snprintf(fw_ver, sizeof(fw_ver), "0x%04X", common_setting.mcu_info.fw_version);
+ snprintf(wifi_ver, sizeof(wifi_ver), "0x%04X", (unsigned int)FW_VERSION);
+
// ===================== 构建正确的 JSON =====================
cJSON *root = cJSON_CreateObject();
if (root == NULL) return;
cJSON_AddStringToObject(root, "fw_version", fw_ver);
cJSON_AddStringToObject(root, "wifi_version", wifi_ver);
cJSON_AddStringToObject(root, "serial_id", (char *)common_storage.net_info.serial_number);
- cJSON_AddNumberToObject(root, "connected_platform", 2);
- cJSON_AddNumberToObject(root, "power_on", 0);
+ cJSON_AddNumberToObject(root, "connected_platform", common_setting.mcu_platform_mode);
+ cJSON_AddNumberToObject(root, "power_on", 1);
// cJSON *pRoot = cJSON_CreateObject();
// // cJSON_AddItemToObject(root,""thingsModelValue": "string",");
// if(pRoot == NULL)
}
return true;
}
+char msgID[64]={0};
+// 云端 version 转 16 进制版本号(例如 1.03 → 0x0103)
+uint16_t version_str_to_hex(char *version)
+{
+ if(version == NULL)
+ {
+ return 0xffff;
+ }
+ if(strlen(version)==0 || version[0] == ' ')
+ {
+ ESP_LOGI(MQTT_TAG,"len err%s\n", version); // 1
+ return 0xffff;
+ }
+ //
+ // // "1.03" → 1
+ char *dot = strchr(version, '.');
+ if(dot == NULL) //没有找到.号 不合法
+ {
+ ESP_LOGI(MQTT_TAG,"不合法%s\n", version); // 1
+ return 0xffff;
+ }
+ char major_str[10] = {0};
+ strncpy(major_str, version, dot - version); // 复制 "1"
+ int major = atoi(major_str); // 转成数字 1
+
+
+ // --------------------
+ // 取小数点后面:03
+ // --------------------
+ int minor = atoi(dot + 1); // dot+1 指向 "03" → 转成 3
+ // 输出结果
+ ESP_LOGI(MQTT_TAG,"主版本:%d\n", major); // 1
+ ESP_LOGI(MQTT_TAG,"次版本:%d\n", minor); // 3
+ ESP_LOGI(MQTT_TAG,"总版本:%04x\n", (major << 8) | minor);
+ // 合成 0x0103
+ return (major << 8) | minor;
+}
static void mqtt_parse_recv_data(char *data, int data_len)
{
+ //"method": "thing.service.property.set.reply",
+
+
+
// 安全判断
if (data == NULL || data_len <= 0 || data_len > MQTT_DATA_BUF_SIZE) {
ESP_LOGW(MQTT_TAG, "parese too len:%d\n",data_len);
return;
}
- // otareset ====================
- //{"productId":"A00B","productName":"WGTL方向盘","otareset":1} otareset
- cJSON *productId = cJSON_GetObjectItem(root, "productId");//清除配网标识字符串 int
- if (productId != NULL && cJSON_IsString(productId)) {
-
- char cur_pid[7]={0};
- snprintf(cur_pid,sizeof(cur_pid)-1,"%04X",common_setting.mcu_info.pid);
- ESP_LOGI(MQTT_TAG, "productId: %s %s\n", productId->valuestring,cur_pid);
- if (strcasecmp(cur_pid, productId->valuestring) != 0) {//和当前PID不一致
- return;
+
+ //请求方式
+ cJSON *method = cJSON_GetObjectItem(root, "method");//
+ if (method != NULL && cJSON_IsString(method)) {
+ if(strcmp("thing.service.property.set",method->valuestring) == 0)
+ {
+ cJSON *msgId = cJSON_GetObjectItem(root, "msgId");//
+ if (msgId != NULL && cJSON_IsString(msgId)) {
+ snprintf(msgID,sizeof(msgID)-1,"%s",msgId->valuestring);
+ // ===================== 构建正确的 JSON =====================
+ cJSON *r_root = cJSON_CreateObject();
+ if (r_root != NULL) {
+
+ time_t now = Get_Time_Stamp(); // 64位时间戳
+
+ char stamp_str[32];
+ // 转成字符串
+ sprintf(stamp_str, "%lld", now);
+
+ // 以字符串加入
+ cJSON_AddStringToObject(r_root, "time", stamp_str);
+ cJSON_AddStringToObject(r_root, "method", "thing.service.property.set.reply"); //属性设置回复
+ cJSON_AddStringToObject(r_root, "msgId", msgId->valuestring);
+ cJSON_AddStringToObject(r_root, "serialNumber", (const char *)common_storage.net_info.serial_number);
+ char pid[10] = {0};
+ sprintf(pid,"%04x",common_setting.mcu_info.pid);
+ cJSON_AddStringToObject(r_root, "productId",pid );
+ cJSON_AddNumberToObject(r_root, "code", 0);
+ cJSON_AddStringToObject(r_root, "message", "ok");
+
+ //
+ char *json_r = cJSON_Print(r_root);
+ cJSON_Delete(r_root);
+ r_root=NULL;
+ if(strlen(json_r))
+ {
+
+ mqtt_send_msg_t send_msg={0};
+ memcpy(send_msg.data,json_r,strlen(json_r));
+ ESP_LOGI(MQTT_TAG, "CJSON:%s", json_r);
+ if(json_r)
+ {
+ free(json_r);
+ json_r = NULL;
+ }
+ memcpy(send_msg.topic,topic_str,strlen(topic_str));
+ // esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT,ESP_PWR_LVL_P9);
+ if(mqtt_send_queue_handle==NULL)
+ {
+ ESP_LOGI(MQTT_TAG, "replay error\n");
+ return;
+ }
+ //回复服务器
+ xQueueSend(mqtt_send_queue_handle, &send_msg, 0);
+ }
+ }
+ }
+ vTaskDelay(5);
}
-
}
// 示例 1:解析字符串类型
//2.重启设备
User_Erase_Nimble_NetWork_Infor();
vTaskDelay(pdMS_TO_TICKS(100));
+ if(root != NULL)
+ {
+ cJSON_Delete(root);
+ root=NULL;
+ }
esp_restart();//重启模组
+ return;
}
}
//"tenantId":1,"tenantName":"13714325636","isLatest":1,"version":1.0,
//"filePath":"https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/20/69e589eb7a67c1057c3d452e.bin"}
//========OTA 升级文件key=====================//
- cJSON *filePath = cJSON_GetObjectItem(root, "filePath");
- if (filePath != NULL && cJSON_IsString(filePath)) {
- //开启ota线程
- const char *ota_url = filePath->valuestring;
- // static const char *filePath="https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/27/69ef076479113dba3ec8e375.bin";//https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/20/69e589eb7a67c1057c3d452e.bin";
- uint8_t filePath_Len = strlen(ota_url);
- if(filePath_Len > sizeof(https_ota_url)-1)
- {
- filePath_Len = sizeof(https_ota_url)-1;
- }
- else{
- filePath_Len = strlen(ota_url);
- }
- memcpy(https_ota_url,ota_url,filePath_Len);
- https_ota_url[filePath_Len] = '\0';
- ESP_LOGI(MQTT_TAG, "ota_url:%s", https_ota_url);
- https_ota_start();
+ // {
+ // "msg": "操作成功",
+ // "code": 200,
+ // "data": {
+ // "topic": "topic/PXN1LJ1QUR078E/A00B/property/post",
+ // "payload": {
+ // "firmwareId": 25,
+ // "firmwareName": "wgtl方向盘",
+ // "productId": "A00B",
+ // "productName": "WGTL方向盘",
+ // "tenantId": 1,
+ // "tenantName": "13714325636",
+ // "isLatest": 1,
+ // "version": 1.04,
+ // "filePath": "https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/27/69ef076479113dba3ec8e375.bin"
+ // }
+ // }
+ // }
+ // cJSON *payload = cJSON_GetObjectItem(root, "payload");//
+ if (1) {
+ cJSON *filePath = cJSON_GetObjectItem(root, "filePath");
+ if (filePath != NULL && cJSON_IsString(filePath)) {
+ cJSON *version = cJSON_GetObjectItem(root, "version");
+ if ((version != NULL && cJSON_IsString(version)) )
+ {
+ // version->valuestring = "10.165";
+ // const char* version = "10.165";
+ uint16_t new_version = version_str_to_hex(version->valuestring);
+ // 核心:把 0x0A15 转成浮点数 10.21
+ ESP_LOGI(MQTT_TAG, "固件版本: %s %04x", version->valuestring,new_version);
+ if(new_version != FW_VERSION && new_version != 0xffff)
+ {
+ //开启ota线程
+ #if ENABLE_HTTPS_OTA_FUNC
+ const char *ota_url = filePath->valuestring;
+ // static const char *filePath="https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/27/69ef076479113dba3ec8e375.bin";//https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/20/69e589eb7a67c1057c3d452e.bin";
+ uint8_t filePath_Len = strlen(ota_url);
+ if(filePath_Len > sizeof(https_ota_url)-1)
+ {
+ filePath_Len = sizeof(https_ota_url)-1;
+ }
+
+ memcpy(https_ota_url,ota_url,filePath_Len);
+ https_ota_url[filePath_Len] = '\0';
+ ESP_LOGI(MQTT_TAG, "ota_url:%s", https_ota_url);
+ if(root != NULL)
+ {
+ cJSON_Delete(root);
+ root=NULL;
+ }
+ Https_Ota_Start();
+ return;
+ #endif
+ }
+
+ }else{
+ #if ENABLE_HTTPS_OTA_FUNC
+ const char *ota_url = filePath->valuestring;
+ // static const char *filePath="https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/27/69ef076479113dba3ec8e375.bin";//https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/20/69e589eb7a67c1057c3d452e.bin";
+ uint8_t filePath_Len = strlen(ota_url);
+ if(filePath_Len > sizeof(https_ota_url)-1)
+ {
+ filePath_Len = sizeof(https_ota_url)-1;
+ }
+
+ memcpy(https_ota_url,ota_url,filePath_Len);
+ https_ota_url[filePath_Len] = '\0';
+ ESP_LOGI(MQTT_TAG, "ota_url:%s", https_ota_url);
+ if(root != NULL)
+ {
+ cJSON_Delete(root);
+ root=NULL;
+ }
+ Https_Ota_Start();
+ return;
+ #endif
+ }
+
+
+ }
}
//
uint8_t type = 1;
uint16_t total_data_len = 0;
uint16_t dpid = 0;
- int value = 0;
+ uint32_t value = 0;
int type_len = 0;
uint8_t send_data[UART_REPLY_MAX_PAYLOAD_MQTT];
memset(send_data,0,UART_REPLY_MAX_PAYLOAD_MQTT);
}
// 1. KEY 必须纯数字
if (is_pure_number(key_str) ) {
- value = item->valueint;//atoi(item->valuestring); //item->valueint;
+ value = (uint32_t)cJSON_GetNumberValue(item); //item->valueint;//atoi(item->valuestring); //item->valueint;
dpid = atoi(key_str);
if(value <= 0xff)
{
{
type = 4;
type_len = 4;
+ }else{
+ ESP_LOGI(MQTT_TAG,"dayu 32byte\n");
+ continue;
+
}
// ESP_LOGI(MQTT_TAG,"dpid %u value:%u\n",dpid,value);
}else{
// { "344": "#00ff00"},
// { "345": "#00ff00"},
- // { "271": "#ffffff"},
- // { "272": "#00ff00"},
- // { "273": "#00ff00"},
- // { "274": "#00ff00"},
- // { "275": "#ffffff"},
- // { "276": "#00ff00"},
- // { "277": "#00ff00"},
- // { "278": "#00ff00"},
- // { "279": "#ffffff"},
- // { "280": "#00ff00"},
- // { "281": "#00ff00"},
- // { "282": "#00ff00"},
- // { "283": "#ffffff"},
- // { "284": "#00ff00"},
- // { "285": "#00ff00"},
+// { "271": "#ffffff"},
+// { "272": "#00ff00"},
+// { "273": "#00ff00"},
+// { "274": "#00ff00"},
+// { "275": "#ffffff"},
+// { "276": "#00ff00"},
+// { "277": "#00ff00"},
+// { "278": "#00ff00"},
+// { "279": "#ffffff"},
+// { "280": "#00ff00"},
+// { "281": "#00ff00"},
+// { "282": "#00ff00"},
+// { "283": "#ffffff"},
+// { "284": "#00ff00"},
+// { "285": "#00ff00"},
// {"735":80},
// {"736":70},
// {"737":60},
// {"400":"#00ff00"},
// {"401":"#0000ff"},
- // {"412":"00ff00"},
- // {"413":"ffffff"},
- // {"414":"ff0000"}
-
-
- // ]
- // }
- // 获取 UTC 时间戳(固定不变)
- // time_t now = 0;
- // time(&now);
+// {"412":"00ff00"},
+// {"413":"ffffff"},
+// {"414":"ff0000"}
- // // 转成 本地时间(自动时区计算)
- // struct tm *time_info = localtime(&now);
- // // 输出本地时间
- // char buf[64];
- // strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", time_info);
- // ESP_LOGI("TIME", "本地时间: %s", buf);
- // ESP_LOGI("TIME", "UTC 时间戳: %lld", now); // 这个才是正确 Unix 时间戳
- //property get
- // {
- // "serialNumber": "PXN1LJ1QUR078E",
- // "proper_get":["dpid1","dpid2","dpid3",................]
-
- // }
// 737 10 738 50 739 70
// total_data_len = 0 0 1 2 3 4 5
- // total_data_len = 0+5+1=6 6 7 8 9 10 11
- // total_data_len = 6+6=12 12 13 14 15 16 17
- // total_data_len =
- // F1 06 12 00 00 00 00 00 00 00 00 00 00 00 00 E1 02 01 01 00 28 D0
-
send_data[total_data_len+0] = dpid & 0xff;
send_data[total_data_len+1] = (dpid >> 8 )&0xff;
send_data[total_data_len+2] = type;//类型
}
}
+
+
+
static void Mqtt_Init_Task_Cb(void *p)
{
mqtt_recv_msg_t recv_msg;
void Wifi_Sta_Init(void);
void Wifi_Start(void);
+void Wifi_Stop(void);
void Wifi_Queue_Send(uint8_t host, uint8_t enable, uint8_t net_pair_encrypt_profile);
void Wifi_Enable_Status_Check(void);