shuichan_old/V1.5/STM32F103_App1/HardWare/NETWORK/network.c

429 lines
16 KiB
C
Raw Normal View History

/* network.c - <20><><EFBFBD><EFBFBD><EFBFBD>㣺4G/WiFi ˫ͨ<CBAB><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>
*
* ҵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>(app_loop/relay/feed_scale)ֻ<EFBFBD><EFBFBD> NET_* <EFBFBD>ӿڣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪<EFBFBD>ײ<EFBFBD>ģ<EFBFBD>
* ͨ<EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><EFBFBD><EFBFBD><EFBFBD> EEPROM <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<EFBFBD>ϴγɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD>ϴ<EFBFBD> 4G <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>4G<EFBFBD><EFBFBD><EFBFBD>޿<EFBFBD>/<EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD>ÿ 10s <EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD>3 <EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD> WiFi <EFBFBD><EFBFBD> <EFBFBD><EFBFBD> 4G<EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD>
* <EFBFBD>ϴ<EFBFBD> WiFi <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>WiFi <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD> <EFBFBD><EFBFBD> 4G<EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> WiFi<EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD>
* WiFi <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȳ<EFBFBD><EFBFBD>Ѵ<EFBFBD> AP <EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>CIPSTATUS, 10s<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD>̶<EFBFBD> SSID<EFBFBD><EFBFBD>60s<EFBFBD><EFBFBD><EFBFBD><EFBFBD> SmartConfig<EFBFBD><EFBFBD>60s<EFBFBD><EFBFBD>
* <EFBFBD>κη<EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> NET_SaveMode()<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD>ʱдһ<EFBFBD><EFBFBD> EEPROM<EFBFBD><EFBFBD>
*/
#include "network.h"
#include "net_wifi.h"
#include "net_wifi_ota.h"
#include "air780e.h"
#include "led.h"
#include "log.h"
#include "main.h"
#include "uart.h"
#include "relay.h"
#include "proto.h"
#include "24c02.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "stdio.h"
#include "string.h"
volatile uint8_t g_net_mqtt_ready = 0;
volatile uint8_t g_net_first_publish_ok = 0;
/* <20><><EFBFBD><EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE>OTA <20><><EFBFBD>ص<EFBFBD> AT <20><><EFBFBD><EFBFBD><EFBFBD>ڼ<EFBFBD><DABC><EFBFBD>λ */
volatile uint8_t g_net_tx_busy = 0;
/* 4G <20><> SIM <20><><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD> air780e.c <20>ڳ<EFBFBD>ʼ<EFBFBD><CABC>ʧ<EFBFBD><CAA7>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD> */
volatile uint8_t g_no_sim_detected = 0;
/* 4G <20><><EFBFBD>źű<C5BA>־<EFBFBD><D6BE><EFBFBD><EFBFBD> air780e.c <20><> AT+CSQ <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD> */
volatile uint8_t g_no_signal_detected = 0;
/* <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
volatile net_ui_phase_t g_net_ui_phase = NET_UI_NONE;
volatile int g_net_ui_countdown = 0;
static net_backend_t s_backend = NET_BACKEND_4G;
/* <20>ϴγɹ<CEB3><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD>EEPROM ƫ<><C6AB> 130<33><30><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>ռ<EFBFBD>õ<EFBFBD> 126<32><36><EFBFBD>ܿ<EFBFBD><DCBF><EFBFBD> */
#define EEPROM_NETMODE_ADDR 130
static uint8_t s_last_mode = NET_MODE_4G;
/* <20><> SIM <20><><EFBFBD>Զ<EFBFBD><D4B6>ٴκ<D9B4><CEBA><EFBFBD> WiFi */
#define NET_NO_SIM_SWITCH_COUNT 3
/* WiFi һ<><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>Ѵ<EFBFBD>AP<41><50><EFBFBD>̶<EFBFBD>SSID<49><44>SmartConfig)ʧ<>ܺ<EFBFBD><DCBA>л<EFBFBD> 4G */
#define NET_WIFI_FAIL_SWITCH_COUNT 1
/*==== <20><><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3> AT <20><EFBFBD><E1BBB0><EFBFBD>⣨RTOS <20>棩====
* net <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> AT <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<EFBFBD><EFBFBD><EFBFBD><EFBFBD>/OTA<EFBFBD><EFBFBD><EFBFBD>ڼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> NET_publish_* <EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>η<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD>񷢲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD> AT Ӧ<EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͻ<EFBFBD>֯<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>
* <EFBFBD>ݹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>net <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>õķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> net_wifi_init <EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
static SemaphoreHandle_t s_net_at_mutex = NULL;
void NET_LockInit(void)
{
s_net_at_mutex = xSemaphoreCreateRecursiveMutex();
}
static void net_at_lock(void)
{
if (s_net_at_mutex && xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
xSemaphoreTakeRecursive(s_net_at_mutex, portMAX_DELAY);
}
}
static void net_at_unlock(void)
{
if (s_net_at_mutex && xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
xSemaphoreGiveRecursive(s_net_at_mutex);
}
}
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0=<3D>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱͨ<D6B1><CDA8><EFBFBD><EFBFBD>-1=<3D><> AT <20>ռ<E1BBB0>á<EFBFBD>
* <EFBFBD><EFBFBD> 2s <EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>net <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD> process <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѽ<EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD>
* ҵ<EFBFBD>񷢲<EFBFBD><EFBFBD><EFBFBD>΢<EFBFBD><EFBFBD>һ<EFBFBD>¼<EFBFBD><EFBFBD>ɣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򻥳<EFBFBD>Ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
static int net_at_trylock(void)
{
if (s_net_at_mutex && xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
return xSemaphoreTakeRecursive(s_net_at_mutex, pdMS_TO_TICKS(2000)) == pdTRUE ? 0 : -1;
}
return 0;
}
net_backend_t NET_GetActiveBackend(void)
{
return s_backend;
}
uint8_t NET_GetLastMode(void)
{
return s_last_mode;
}
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><E4A3BA><EFBFBD><EFBFBD>ʽ<EFBFBD>仯ʱдһ<D0B4><D2BB> EEPROM<4F><4D><><D6BB>һ<EFBFBD><D2BB>"<22><> */
void NET_SaveMode(uint8_t mode)
{
if (mode == s_last_mode || mode > NET_MODE_WIFI_SMART) return;
s_last_mode = mode;
eepromWriteData(EEPROM_NETMODE_ADDR, &mode, 1);
log_info("> NET: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD>ѱ<EFBFBD><D1B1><EFBFBD> -> %s",
mode == NET_MODE_4G ? "4G" :
mode == NET_MODE_WIFI_FIXED ? "WiFi(<28>̶<EFBFBD><CCB6>ȵ<EFBFBD>)" : "WiFi(<28><><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD>)");
}
void NET_init(void)
{
g_net_mqtt_ready = 0;
g_net_first_publish_ok = 0;
g_no_sim_detected = 0;
g_no_signal_detected = 0;
/* <20><> EEPROM <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴγɹ<CEB3><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>Ƿ<EFBFBD>ֵ(<28><> EEPROM δ<><CEB4>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD> 0xFF)<29><> 4G */
uint8_t m = NET_MODE_4G;
eepromReadData(EEPROM_NETMODE_ADDR, &m, 1);
if (m > NET_MODE_WIFI_SMART) m = NET_MODE_4G;
s_last_mode = m;
if (m == NET_MODE_4G) {
s_backend = NET_BACKEND_4G;
net_at_lock();
air780e_init();
net_at_unlock();
if (g_no_sim_detected) {
log_warn("> 4G <20><> SIM <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SIM <20><>");
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> WiFi<46><69><EFBFBD><EFBFBD> NET_process <20><><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޿<EFBFBD><DEBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD> */
}
g_net_mqtt_ready = g_air780e_mqtt_ready;
} else {
/* <20>ϴ<EFBFBD> WiFi <20>ɹ<EFBFBD><C9B9><EFBFBD>WiFi <20><><EFBFBD>ȣ<EFBFBD>NET_process <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> net_wifi_init */
log_info("> NET: <20>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽΪ WiFi<46><69>WiFi <20><><EFBFBD><EFBFBD>");
s_backend = NET_BACKEND_WIFI;
}
}
/* <20>е<EFBFBD> WiFi ͨ<><CDA8><EFBFBD><EFBFBD>ͣ 4G <20><><EFBFBD>գ<EFBFBD><D5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E2A3A9>WiFi <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> NET_process <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
static void net_switch_to_wifi(void)
{
log_warn("> NET: <20>л<EFBFBD> 4G -> WiFi");
USART3_StopRx();
g_net_mqtt_ready = 0;
g_net_first_publish_ok = 0;
s_backend = NET_BACKEND_WIFI;
}
/* <20>л<EFBFBD> 4G ͨ<><CDA8><EFBFBD><EFBFBD>ͣ WiFi <20><><EFBFBD>գ<EFBFBD><D5A3>ָ<EFBFBD> 4G <20><><EFBFBD>ղ<EFBFBD><D5B2><EFBFBD><EFBFBD>³<EFBFBD>ʼ<EFBFBD><CABC> */
static void net_switch_to_4g(void)
{
log_warn("> NET: <20>л<EFBFBD> WiFi -> 4G");
UART4_StopRx();
g_net_mqtt_ready = 0;
g_net_first_publish_ok = 0;
g_no_sim_detected = 0;
g_no_signal_detected = 0;
g_air780e_mqtt_ready = 0;
g_air780e_first_publish_ok = 0;
s_backend = NET_BACKEND_4G;
USART3_StartRx();
net_at_lock();
air780e_init();
net_at_unlock();
}
void NET_process(void)
{
static uint32_t retry_tick = 0;
static uint16_t fail_count = 0;
if (s_backend == NET_BACKEND_4G) {
/* <20><><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>ʱ<EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD> */
if (!g_air780e_mqtt_ready) {
if (g_no_sim_detected || g_no_signal_detected) {
/* <20><> SIM <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>źţ<C5BA>ÿ 10s <20><><EFBFBD><EFBFBD>һ<EFBFBD>Σ<EFBFBD><CEA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD> WiFi ͨ<><CDA8> */
if (retry_tick == 0 ||
(HAL_GetTick() - retry_tick) >= 10000) {
retry_tick = HAL_GetTick();
fail_count++;
log_warn("> NET: 4G <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (no_sim=%d, no_signal=%d)<29><><EFBFBD><EFBFBD><EFBFBD>Գ<EFBFBD>ʼ<EFBFBD><CABC> %d/%d",
g_no_sim_detected, g_no_signal_detected,
fail_count, NET_NO_SIM_SWITCH_COUNT);
g_no_sim_detected = 0;
g_no_signal_detected = 0;
net_at_lock();
air780e_init();
net_at_unlock();
if (!g_no_sim_detected && !g_no_signal_detected) {
log_info("> NET: 4G SIM<49><4D>/<2F>ź<EFBFBD><C5BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѻָ<D1BB>");
fail_count = 0;
} else if (fail_count >= NET_NO_SIM_SWITCH_COUNT) {
log_warn("> NET: 4G <20><><EFBFBD><EFBFBD> %d <20><><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD>˵<EFBFBD> WiFi",
NET_NO_SIM_SWITCH_COUNT);
net_switch_to_wifi();
fail_count = 0;
retry_tick = 0;
}
}
} else {
retry_tick = 0;
fail_count = 0;
}
} else {
retry_tick = 0;
fail_count = 0;
NET_SaveMode(NET_MODE_4G); /* 4G <20><><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>䣨δ<E4A3A8><EFBFBD><E4BBAF><EFBFBD>ղ<EFBFBD><D5B2><EFBFBD><EFBFBD><EFBFBD> */
}
net_at_lock();
air780e_process();
net_at_unlock();
g_net_mqtt_ready = g_air780e_mqtt_ready;
g_net_first_publish_ok = g_air780e_first_publish_ok;
} else {
/* WiFi ͨ<><CDA8><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>½<EFBFBD><C2BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ʧ<EFBFBD>ܼ<EFBFBD><DCBC>л<EFBFBD> 4G */
if (!g_wifi_mqtt_ready) {
if (retry_tick == 0 ||
(HAL_GetTick() - retry_tick) >= 10000) {
retry_tick = HAL_GetTick();
fail_count++;
log_warn("> NET: WiFi <20><><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD> %d/%d",
fail_count, NET_WIFI_FAIL_SWITCH_COUNT);
net_at_lock();
int wifi_rc = net_wifi_init();
net_at_unlock();
if (wifi_rc == 0) {
fail_count = 0;
} else if (fail_count >= NET_WIFI_FAIL_SWITCH_COUNT) {
log_warn("> NET: WiFi <20><><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD>˵<EFBFBD> 4G");
net_switch_to_4g();
fail_count = 0;
retry_tick = 0;
}
}
} else {
retry_tick = 0;
fail_count = 0;
}
net_at_lock();
net_wifi_process();
net_at_unlock();
g_net_mqtt_ready = g_wifi_mqtt_ready;
g_net_first_publish_ok = g_wifi_first_publish_ok;
}
}
void NET_publish_status(int sw1, int feeding, int sw2, int sw3, int sw4,
float weight_kg, float once_wt_kg, float zero_kg)
{
if (g_net_tx_busy) { log_info("> NET: ״̬<D7B4>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>æ)"); return; }
if (net_at_trylock() != 0) { log_info("> NET: ״̬<D7B4>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (AT æ)"); return; }
/* ver <20>ֶΣ<D6B6><CEA3>̼<EFBFBD><CCBC><EFBFBD>ţ<EFBFBD>ƽ̨<C6BD>ݴ˿<DDB4>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> OTA <20><><EFBFBD><EFBFBD> */
/* sw1 <20><> feeding <20><>ӳ<EFBFBD><D3B3><EFBFBD>̵<EFBFBD><CCB5><EFBFBD> 1 ״̬<D7B4><CCAC><EFBFBD>޳<EFBFBD>ģʽ<C4A3><CABD><EFBFBD>ߵ<EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶζ<EFBFBD><EFBFBD>ϱ<EFBFBD><EFBFBD><EFBFBD>ƽ̨<EFBFBD><EFBFBD> sw1 <EFBFBD><EFBFBD><EFBFBD>غ<EFBFBD> feeding ״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD>ˢ<EFBFBD><EFBFBD> */
/* <20>޳<EFBFBD>ģʽ<C4A3><CABD>PRODUCT_WITH_FEED_SCALE=0<><30><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD> zero/onceWt <20>ֶ<EFBFBD> */
if (s_backend == NET_BACKEND_4G) {
#if PRODUCT_WITH_FEED_SCALE
CAT1_printf("AT+MPUB=\"/iot/data/up/%s\",0,0,\"{\\22header\\22:\\22iot.prop.post\\22,\\22body\\22:{\\22ver\\22:%u,\\22weight\\22:%.1f,\\22onceWt\\22:%.1f,\\22zero\\22:%.1f,\\22sw1\\22:%d,\\22feeding\\22:%d,\\22sw2\\22:%d,\\22sw3\\22:%d,\\22sw4\\22:%d}}\"",
MqttInfoStr.ClientID, (unsigned)MqttInfoStr.Ver, zero_kg, once_wt_kg, weight_kg, sw1, feeding, sw2, sw3, sw4);
#else
CAT1_printf("AT+MPUB=\"/iot/data/up/%s\",0,0,\"{\\22header\\22:\\22iot.prop.post\\22,\\22body\\22:{\\22ver\\22:%u,\\22weight\\22:%.1f,\\22sw1\\22:%d,\\22feeding\\22:%d,\\22sw2\\22:%d,\\22sw3\\22:%d,\\22sw4\\22:%d}}\"",
MqttInfoStr.ClientID, (unsigned)MqttInfoStr.Ver, zero_kg, sw1, feeding, sw2, sw3, sw4);
#endif
} else {
char json[256];
#if PRODUCT_WITH_FEED_SCALE
snprintf(json, sizeof(json),
"{\"header\":\"iot.prop.post\",\"body\":{\"ver\":%u,\"weight\":%.1f,\"onceWt\":%.1f,\"zero\":%.1f,\"sw1\":%d,\"feeding\":%d,\"sw2\":%d,\"sw3\":%d,\"sw4\":%d}}",
(unsigned)MqttInfoStr.Ver, zero_kg, once_wt_kg, weight_kg, sw1, feeding, sw2, sw3, sw4);
#else
snprintf(json, sizeof(json),
"{\"header\":\"iot.prop.post\",\"body\":{\"ver\":%u,\"weight\":%.1f,\"sw1\":%d,\"feeding\":%d,\"sw2\":%d,\"sw3\":%d,\"sw4\":%d}}",
(unsigned)MqttInfoStr.Ver, zero_kg, sw1, feeding, sw2, sw3, sw4);
#endif
net_wifi_publish_up(json);
}
net_at_unlock();
}
void NET_publish_response(const char *cmd_id, int ok, const char *msg)
{
if (g_net_tx_busy) { log_info("> NET: Ӧ<><D3A6><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>æ)"); return; }
if (net_at_trylock() != 0) { log_info("> NET: Ӧ<><D3A6><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (AT æ)"); return; }
const char *text = msg ? msg : (ok ? "OK" : "command failed");
if (s_backend == NET_BACKEND_4G) {
CAT1_printf("AT+MPUB=\"/iot/data/up/%s\",0,0,\"{\\22id\\22:\\22%s\\22,\\22code\\22:0,\\22message\\22:\\22%s\\22}\"",
MqttInfoStr.ClientID, cmd_id, text);
} else {
char json[200];
snprintf(json, sizeof(json),
"{\"id\":\"%s\",\"code\":0,\"message\":\"%s\"}", cmd_id, text);
net_wifi_publish_up(json);
}
net_at_unlock();
}
/* <20>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD>״̬: on=1 <20><><EFBFBD><EFBFBD>, on=0 <20>͵<EFBFBD><CDB5><EFBFBD> */
void NET_publish_power(int on)
{
if (g_net_tx_busy) { log_info("> NET: <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>æ)"); return; }
if (net_at_trylock() != 0) { log_info("> NET: <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (AT æ)"); return; }
if (s_backend == NET_BACKEND_4G) {
CAT1_printf("AT+MPUB=\"/iot/data/up/%s\",0,0,\"{\\22header\\22:\\22iot.prop.post\\22,\\22body\\22:{\\22pow\\22:%d}}\"",
MqttInfoStr.ClientID, on ? 1 : 0);
} else {
char json[96];
snprintf(json, sizeof(json),
"{\"header\":\"iot.prop.post\",\"body\":{\"pow\":%d}}", on ? 1 : 0);
net_wifi_publish_up(json);
}
net_at_unlock();
}
/* <20>ϱ<EFBFBD><CFB1>ۼƵ<DBBC><C6B5><EFBFBD>: energy <20>ֶΣ<D6B6><CEA3><EFBFBD>λ kWh<57><68><EFBFBD><EFBFBD>λС<CEBB><D0A1> */
void NET_publish_energy(float kwh)
{
if (g_net_tx_busy) { log_info("> NET: energy <20>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>æ)"); return; }
if (net_at_trylock() != 0) { log_info("> NET: energy <20>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (AT æ)"); return; }
if (s_backend == NET_BACKEND_4G) {
CAT1_printf("AT+MPUB=\"/iot/data/up/%s\",0,0,\"{\22header\22:\22iot.prop.post\22,\22body\22:{\22energy\22:%.2f}}\"",
MqttInfoStr.ClientID, kwh);
} else {
char json[96];
snprintf(json, sizeof(json),
"{\"header\":\"iot.prop.post\",\"body\":{\"energy\":%.2f}}", kwh);
net_wifi_publish_up(json);
}
net_at_unlock();
}
void NET_mqtt_report(const char *header, const char *ota_id, int val)
{
if (g_net_tx_busy) { log_info("> NET: <20><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>æ)"); return; }
if (net_at_trylock() != 0) { log_info("> NET: <20><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (AT æ)"); return; }
if (s_backend == NET_BACKEND_4G) {
air780e_mqtt_report(header, ota_id, val);
net_at_unlock();
return;
}
if (!header || !ota_id || !ota_id[0]) { net_at_unlock(); return; }
char json[200];
if (strstr(header, "progress")) {
snprintf(json, sizeof(json),
"{\"header\":\"%s\",\"body\":{\"id\":\"%.16s\",\"progress\":%d}}",
header, ota_id, val);
} else {
snprintf(json, sizeof(json),
"{\"header\":\"%s\",\"body\":{\"id\":\"%.16s\",\"success\":%s}}",
header, ota_id, val ? "true" : "false");
}
net_wifi_publish_up(json);
net_at_unlock();
}
void NET_ota_confirm(void)
{
/* <20><>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬһȷ<D2BB><C8B7><EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD><CCA3>޹<EFBFBD><DEB9><EFBFBD> OTA ʱ<>ڲ<EFBFBD>ֱ<EFBFBD>ӷ<EFBFBD><D3B7>أ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><EFBFBD>ϱ<EFBFBD><EFBFBD>Ѹ<EFBFBD>Ϊ NET_mqtt_report<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰͨ<EFBFBD><EFBFBD>·<EFBFBD><EFBFBD> */
air780e_ota_confirm();
}
/*==== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣͳһ<CDB3>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD> air780e.c <20><><EFBFBD><EFBFBD><E1A3AC>ģ<EFBFBD><C4A3><EFBFBD>޹أ<DEB9>====
* msg <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> +MSUB URC<EFBFBD><EFBFBD>4G<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> JSON<EFBFBD><EFBFBD>WiFi<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD>ƥ<EFBFBD><EFBFBD><EFBFBD> */
void net_dispatch_message(const char *msg)
{
/* dedup by message id */
static char last_id[20] = {0};
char cur_id[20] = {0};
proto_get_id((char*)msg, cur_id, sizeof(cur_id));
if (cur_id[0] && strcmp(cur_id, last_id) == 0) {
log_info("> MQTT: <20>ظ<EFBFBD><D8B8><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>id=%.16s", cur_id);
return;
}
strncpy(last_id, cur_id, sizeof(last_id)-1);
/* relay control */
if (strstr(msg, "iot.prop.set")) { relay_action((uint8_t *)msg); }
/* OTA upgrade */
if (strstr(msg, "iot.ota.upgrade.post")) {
log_info("> OTA <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
char host[30]={0}, path[80]={0}, ota_id[20]={0}; int port = 81;
uint16_t new_ver = 0;
uint16_t crc16 = 0;
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6B1BE><EFBFBD><EFBFBD> crc16 */
{ uint32_t v = 0; if (proto_get_u32((char*)msg, "ver", &v)) new_ver = (uint16_t)v; }
proto_get_hex16((char*)msg, "crc16", &crc16);
log_info("> OTA <20>汾: <20><>ǰ=%u, <20>°汾=%u, crc16=0x%04X", MqttInfoStr.Ver, new_ver, crc16);
/* <20><EFBFBD><E6B1BE> <20><> <20><>ǰ<EFBFBD><20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><>ֹ<EFBFBD>ظ<EFBFBD><D8B8>򽵼<EFBFBD>) */
if (new_ver > 0 && new_ver <= MqttInfoStr.Ver) {
proto_get_id((char*)msg, ota_id, sizeof(ota_id));
log_info("> OTA: <20><EFBFBD><E6B1BE>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD> (<28><>ǰ=%u, <20>°汾=%u)", MqttInfoStr.Ver, new_ver);
NET_mqtt_report("iot.ota.progress.post", ota_id, 10);
} else {
strncpy(host, MqttInfoStr.ServerIP, sizeof(host)-1); strcpy(path, "/firmware.bin");
proto_get_id((char*)msg, ota_id, sizeof(ota_id));
{ char fu[100]={0};
if (proto_get_str((char*)msg, "url", fu, sizeof(fu))) {
log_info("> OTA <20><><EFBFBD>ص<EFBFBD>ַ: %s", fu); char *p=fu;
if(strncmp(p,"http://",7)==0)p+=7;
char *sl=strchr(p,'/'),*co=strchr(p,':');
if(co&&(!sl||co<sl)){ int hl=co-p; memcpy(host,p,hl); host[hl]=0;
co++; port=0; while(*co>='0'&&*co<='9'){port=port*10+(*co-'0');co++;}
if(sl)strncpy(path,sl,sizeof(path)-1); }
else if(sl){ int hl=sl-p; memcpy(host,p,hl); host[hl]=0; strncpy(path,sl,sizeof(path)-1); }
else strncpy(host,p,sizeof(host)-1);
}}
log_info("> OTA: %s:%d%s", host, port, path);
/* <20><><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> W25Q64 ˫<><CBAB> + CRC + BootLoader <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD><D8B4>䲻ͬ */
if (s_backend == NET_BACKEND_WIFI) {
net_wifi_ota(host, port, path, ota_id, new_ver, crc16);
} else {
air780e_trigger_ota(host, port, path, ota_id, new_ver, crc16);
}
}
}
}