vd960DBN:
- heartbeat/sensor/initialize 发布统一走 dld960/{sn}/dev
- dev_initialize_pub 补 model/hard_ver/soft_ver,删 extra_info.version
DBNMQTTool:
- 协议版本号更新至 V1.03
- 协议 Topic 树和模拟页增加 initialize 支持
1626 lines
52 KiB
C
1626 lines
52 KiB
C
/**
|
||
******************************************************************************
|
||
* @file net_srv.c
|
||
* @author wangfq
|
||
* @version V1.0
|
||
* @date 2026-03-02
|
||
* @brief net message handle: unpack, exeute, response
|
||
*
|
||
******************************************************************************
|
||
*/
|
||
#include "CONFIG.h"
|
||
#include "net_srv.h"
|
||
#include "eth_driver.h"
|
||
#include "wchnet.h"
|
||
#include "MQTTPacket.h"
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include "cmcng.h"
|
||
#include "simple_json.h"
|
||
#include "tcp_json_srv.h"
|
||
#include "iot_mqtt_srv.h"
|
||
|
||
|
||
uint32_t slen;
|
||
char g_dev_number_str[13] = "";
|
||
uint8_t g_flag_timestamp = 0;
|
||
|
||
#define KEEPALIVE_ENABLE 1 //Enable keep alive function
|
||
|
||
|
||
#define maxLenTemp 430
|
||
static char temp_guide[maxLenTemp] = "";
|
||
|
||
static void reset_temp_guide()
|
||
{
|
||
memset(temp_guide, 0, maxLenTemp);
|
||
}
|
||
|
||
|
||
//************************************************************************10
|
||
#define KEEPLIVE_ENABLE 1 //Enable keeplive function
|
||
|
||
|
||
Local_Net_Cfg local_net_cfg = {{0x00, 0x08, 0xdc, 0x33, 0x44, 0x55}, {192,168,1,188}, {255,255,255,0}, {192, 168,1,1}, "", 5550,NET_REPORT_INTERVAL, 5505, PORT_TCP_DEFAULT, MAX_CLEAR_COUNTER_INTERVAL};
|
||
|
||
NET_CENTER_INFO net_center_info = {{192,168,1,222}, 5505, PORT_TCP_DEFAULT, 5505, ""};
|
||
IOT_NET_INFO iot_net_info = {"", 1883, "", "", ""};
|
||
IOT_Topic g_iot_topic = {0, "", ""};
|
||
uint8_t RemoteIP[4] = {0,0,0,0};
|
||
|
||
Net_State g_net_state = {0,0, 0};
|
||
|
||
|
||
uint16_t srcport = 6000;
|
||
//UINT8 UDPDESIP[4] = {255,255,255,255}; /* ????????????????????,?????????��???????????????????? */
|
||
//UINT16 aport=1000; /* CH579?????????? */
|
||
uint32_t g_wdg_counter = 0;
|
||
|
||
uint8_t SocketId_TCP;
|
||
uint8_t SocketId_UDP ;
|
||
uint8_t socket[WCHNET_MAX_SOCKET_NUM]; //Save the currently connected socket
|
||
uint8_t SocketRecvBuf[WCHNET_MAX_SOCKET_NUM][RECE_BUF_LEN]; //socket receive buffer
|
||
uint8_t MyBuf[RECE_BUF_LEN];
|
||
|
||
|
||
#define MAX_TMP_BUF_LEN 64
|
||
#define MAX_MQTTBUF_LEN 512 //384 //512
|
||
char mqtt_username[64] = {0};
|
||
char mqtt_password[32] = {0};
|
||
char mqtt_clientid[64] = {0};
|
||
uint8_t mqttBuf[MAX_MQTTBUF_LEN];
|
||
uint8_t TmpBuf[MAX_TMP_BUF_LEN] = "";
|
||
|
||
MQTTPacket_connectData mqttData = MQTTPacket_connectData_initializer;
|
||
|
||
uint8_t flag_mqtt_ping_send = 0;
|
||
uint8_t flag_mqtt_ping_err = 0; //++, 0 normal, >0 send and no response
|
||
uint8_t g_mqtt_ping_counter = 0; //
|
||
|
||
void clear_mqtt_buf(void)
|
||
{
|
||
memset(mqttBuf, 0, MAX_MQTTBUF_LEN);
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @fn mStopIfError
|
||
*
|
||
* @brief check if error.
|
||
*
|
||
* @param iError - error constants.
|
||
*
|
||
* @return none
|
||
*/
|
||
void mStopIfError(u8 iError)
|
||
{
|
||
if (iError == WCHNET_ERR_SUCCESS) return;
|
||
printf("Error: 0x%02X\r\n", (u16)iError);
|
||
}
|
||
|
||
void mqtt_connect(void)
|
||
{
|
||
int len = 0;
|
||
mqttData.username.cstring = iot_net_info.username;
|
||
mqttData.password.cstring = iot_net_info.password;
|
||
mqttData.clientID.cstring = g_dev_number_str; //TODO: ?��????????????????????
|
||
mqttData.keepAliveInterval = MQTT_KEEPALIVE_INTERVAL;
|
||
|
||
PRINT("username:%s\r\n", mqttData.username.cstring);
|
||
PRINT("password:%s\r\n", mqttData.password.cstring);
|
||
PRINT("clientID:%s\r\n", mqttData.clientID.cstring);
|
||
|
||
clear_mqtt_buf();
|
||
len = MQTTSerialize_connect(mqttBuf, sizeof(mqttBuf), &mqttData);
|
||
// Transport_SendPacket(mqttBuf, len);
|
||
WCHNET_SocketSend(SocketId_TCP, (uint8_t *)mqttBuf, &len);
|
||
|
||
}
|
||
|
||
void MQTT_Subscribe(char *topic, unsigned char msgid)
|
||
{
|
||
int len = 0, req_qos = 0;
|
||
MQTTString topicString = MQTTString_initializer;
|
||
topicString.cstring = topic;
|
||
clear_mqtt_buf();
|
||
len = MQTTSerialize_subscribe(mqttBuf, sizeof(mqttBuf), 0, msgid, 1, &topicString, &req_qos);
|
||
// Transport_SendPacket(mqttBuf, len);
|
||
WCHNET_SocketSend(SocketId_TCP, (uint8_t *)mqttBuf, &len);
|
||
}
|
||
|
||
|
||
void dg_subscribe_display_topic(void)
|
||
{
|
||
char *mBuff = (char *)malloc(256);
|
||
if(mBuff == NULL)
|
||
{
|
||
return;
|
||
}
|
||
memset(mBuff, 0, 256);
|
||
|
||
// V1.01: 双主题协议 — topic_sub 即为完整订阅主题,不再追加后缀
|
||
strcpy(mBuff, (char *)g_iot_topic.topic_sub);
|
||
|
||
{
|
||
PRINT("\nWill subscribe display_topic:\n%s\n", mBuff);
|
||
}
|
||
MQTT_Subscribe(mBuff, 1);
|
||
|
||
free(mBuff);
|
||
}
|
||
|
||
|
||
void MQTT_Pingreq()
|
||
{
|
||
uint8_t ping_buf[2];
|
||
int buf_len = sizeof(ping_buf);
|
||
int ping_len = MQTTSerialize_pingreq(ping_buf, buf_len);
|
||
// Transport_SendPacket(ping_buf, ping_len);
|
||
WCHNET_SocketSend(SocketId_TCP, (uint8_t *)ping_buf, &buf_len);
|
||
}
|
||
|
||
void mqtt_publish(char *topic, char *message, int req_qos)
|
||
{
|
||
uint32_t len = 0;
|
||
clear_mqtt_buf();
|
||
|
||
{
|
||
PRINT("\nWill_publish_topid:%s, message:%s\n", topic, message);
|
||
}
|
||
|
||
MQTTString topicString = MQTTString_initializer;
|
||
int msglen = strlen(message);
|
||
topicString.cstring = topic;
|
||
len = MQTTSerialize_publish(mqttBuf, sizeof(mqttBuf), 0, req_qos, 0, 0, topicString, (unsigned char *)message, msglen);
|
||
// Transport_SendPacket(mqttBuf, len);
|
||
WCHNET_SocketSend(SocketId_TCP, (uint8_t *)mqttBuf, &len);
|
||
}
|
||
|
||
void dev_initialize_pub(void)
|
||
{
|
||
char *mBuff = (char *)malloc(512);
|
||
if(mBuff == NULL)
|
||
{
|
||
return;
|
||
}
|
||
memset(mBuff, 0, 512);
|
||
|
||
// V1.03: 上线后发布 initialize,告知服务器设备信息
|
||
// 格式: {msg_id, cmd:"initialize", ts, data:{dev_serial, model, hard_ver, soft_ver, extra_info:{code,csq,location}}}
|
||
uint32_t now = (mstick() > 0) ? (uint32_t)(mstick() / 1000) : 0;
|
||
char topic[64];
|
||
snprintf(topic, sizeof(topic), "dld960/%s/dev", g_dev_number_str);
|
||
sprintf((char *)mBuff,
|
||
"{\"msg_id\":%lu,\"cmd\":\"initialize\",\"ts\":%lu,"
|
||
"\"data\":{\"dev_serial\":\"%s\",\"model\":\"%s\","
|
||
"\"hard_ver\":\"%s\",\"soft_ver\":\"%s\","
|
||
"\"extra_info\":{\"code\":\"%s\",\"csq\":\"%d\","
|
||
"\"location\":\"%s\"}}}",
|
||
(unsigned long)++g_iot_msg_id, (unsigned long)now,
|
||
g_dev_number_str, PRODUCT_MODEL,
|
||
HARDWARE_VER, FIRMWARE_VER,
|
||
"0", 0, "");
|
||
|
||
PRINT("\nWill publish initialize topic=%s:\n%s\n", topic, mBuff);
|
||
|
||
mqtt_publish(topic, (char *)mBuff, 0);
|
||
|
||
free(mBuff);
|
||
}
|
||
|
||
void dev_response_heartbeat(char *dat)
|
||
{
|
||
char *mBuff = (char *)malloc(256);
|
||
if(mBuff == NULL)
|
||
{
|
||
return;
|
||
}
|
||
memset(mBuff, 0, 256);
|
||
if(dat == NULL)
|
||
{
|
||
sprintf((char *)mBuff, "{\"Method\":\"Heartbeat\", \"Data\":{\"Device_id\": \"%s\"}}", g_dev_number_str);
|
||
} else {
|
||
sprintf((char *)mBuff, "{\"Method\":\"Heartbeat\", \"Data\":{\"Device_id\": \"%s\",\"Remark\":\"%s\"}}", g_dev_number_str, dat);
|
||
}
|
||
// mqtt_publish("gtpc/display/Initialize", gbufSend, 0);
|
||
mqtt_publish((char *)(g_iot_topic.topic_pub), (char *)mBuff, 0);
|
||
|
||
free(mBuff);
|
||
}
|
||
|
||
void mqtt_deserialize_publish(char* topic, char* msg, int length)
|
||
{
|
||
// V1.01: 使用配置的 topic_sub 匹配,而非硬编码默认值
|
||
if(strstr(topic, (char *)g_iot_topic.topic_sub) != NULL)
|
||
{
|
||
manage_mqtt_recv_message(msg, length);
|
||
}
|
||
else
|
||
{
|
||
{
|
||
PRINT("\n%s, line:%d, other topic:%s, msg:%s.\n", __FUNCTION__, __LINE__, topic, msg);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
void tcp_send_test()
|
||
{
|
||
uint8_t ping_buf[5] = {0x33, 0x32, 0x33,0x30,0x39};
|
||
int buf_len = 5;
|
||
// Transport_SendPacket(ping_buf, ping_len);
|
||
WCHNET_SocketSend(SocketId_TCP, (uint8_t *)ping_buf, &buf_len);
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @fn WCHNET_CreateTcpSocket
|
||
*
|
||
* @brief Create TCP Socket
|
||
*
|
||
* @return none
|
||
*/
|
||
void WCHNET_CreateTcpSocket(void)
|
||
{
|
||
uint8_t i = 0;
|
||
uint8_t ret;
|
||
uint32_t len;
|
||
SOCK_INF TmpSocketInf;
|
||
|
||
memset((void *) &TmpSocketInf, 0, sizeof(SOCK_INF));
|
||
memcpy((void *) TmpSocketInf.IPAddr, net_center_info.lssc_ip, 4);
|
||
TmpSocketInf.DesPort = net_center_info.tcp_port;
|
||
TmpSocketInf.SourPort = srcport++; // local_net_cfg.port_dev_udp;
|
||
TmpSocketInf.ProtoType = PROTO_TYPE_TCP;
|
||
TmpSocketInf.RecvBufLen = RECE_BUF_LEN;
|
||
i = WCHNET_SocketCreat(&SocketId_TCP, &TmpSocketInf);
|
||
|
||
{
|
||
PRINT("WCHNET_SocketCreate %d,desIP:%d.%d.%d.%d, des_port:%d, srcport:%d\r\n", SocketId_TCP, net_center_info.lssc_ip[0],net_center_info.lssc_ip[1],net_center_info.lssc_ip[2],net_center_info.lssc_ip[3], TmpSocketInf.DesPort, TmpSocketInf.SourPort);
|
||
}
|
||
mStopIfError(i);
|
||
i = WCHNET_SocketConnect(SocketId_TCP); //make a TCP connection
|
||
if(i == WCHNET_ERR_SUCCESS)
|
||
{
|
||
PRINT("Tcp_Connect_Success!:%d\n", SocketId_TCP);
|
||
g_net_state.flag = 3;
|
||
|
||
// tcp_send_test();
|
||
}
|
||
mStopIfError(i);
|
||
}
|
||
|
||
|
||
void WCHNET_CreateTcpMqttSocket(void)
|
||
{
|
||
uint8_t i;
|
||
uint8_t ret;
|
||
uint32_t len;
|
||
SOCK_INF TmpSocketInf;
|
||
|
||
memset((void *) &TmpSocketInf, 0, sizeof(SOCK_INF));
|
||
memcpy((void *) TmpSocketInf.IPAddr, RemoteIP, 4);
|
||
TmpSocketInf.DesPort = iot_net_info.mqtt_port; // net_center_info.tcp_port;
|
||
TmpSocketInf.SourPort = local_net_cfg.port_dev_udp + 1;
|
||
TmpSocketInf.ProtoType = PROTO_TYPE_TCP;
|
||
TmpSocketInf.RecvBufLen = RECE_BUF_LEN;
|
||
i = WCHNET_SocketCreat(&SocketId_TCP, &TmpSocketInf);
|
||
|
||
{
|
||
PRINT("WCHNET_MQTT_SocketCreate %d,desIP:%d.%d.%d.%d, des_port:%d, srcport:%d\r\n", SocketId_TCP, RemoteIP[0],RemoteIP[1],RemoteIP[2],RemoteIP[3], iot_net_info.mqtt_port, TmpSocketInf.SourPort);
|
||
}
|
||
mStopIfError(i);
|
||
i = WCHNET_SocketConnect(SocketId_TCP); //make a TCP connection
|
||
if(i == WCHNET_ERR_SUCCESS)
|
||
{
|
||
g_net_state.flag = 3;
|
||
}
|
||
mStopIfError(i);
|
||
}
|
||
|
||
|
||
/*********************************************************************
|
||
* @fn WCHNET_UdpServerRecv
|
||
*
|
||
* @brief UDP Receive data function
|
||
*
|
||
*@param socinf - socket information.
|
||
* ipaddr - The IP address from which the data was sent
|
||
* port - source port
|
||
* buf - pointer to the data buffer
|
||
* len - received data length
|
||
* @return none
|
||
*/
|
||
void WCHNET_UdpServerRecv(struct _SOCK_INF *socinf, uint32_t ipaddr, uint16_t port, uint8_t *buf, uint32_t len)
|
||
{
|
||
uint8_t ip_addr[4], i;
|
||
|
||
// PRINT("Remote IP:");
|
||
for (i = 0; i < 4; i++) {
|
||
ip_addr[i] = ipaddr & 0xff;
|
||
// PRINT("%d ", ip_addr[i]);
|
||
ipaddr = ipaddr >> 8;
|
||
}
|
||
|
||
PRINT("srcport = %d len = %d socketid = %d,buf:\r\n%s\r\n", port, len,
|
||
socinf->SockIndex, buf);
|
||
|
||
manage_udp_message(socinf->SockIndex, ip_addr, port, buf, len);
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @fn WCHNET_CreateUdpSocket
|
||
*
|
||
* @brief Create UDP Socket
|
||
*
|
||
* @return none
|
||
*/
|
||
void WCHNET_CreateUdpSocket(void)
|
||
{
|
||
uint8_t i;
|
||
SOCK_INF TmpSocketInf;
|
||
|
||
memset((void *) &TmpSocketInf, 0, sizeof(SOCK_INF));
|
||
// memcpy((void *) TmpSocketInf.IPAddr, UDPDESIP, 4);
|
||
// TmpSocketInf.DesPort = local_net_cfg.port_ssc_udp; //5500
|
||
TmpSocketInf.SourPort = local_net_cfg.port_dev_udp; //srcport;// local_net_cfg.port_dev_udp; // 4900
|
||
TmpSocketInf.ProtoType = PROTO_TYPE_UDP;
|
||
TmpSocketInf.RecvStartPoint = (uint32_t)SocketRecvBuf; //
|
||
TmpSocketInf.RecvBufLen = RECE_BUF_LEN;
|
||
TmpSocketInf.AppCallBack = WCHNET_UdpServerRecv;
|
||
i = WCHNET_SocketCreat(&SocketId_UDP, &TmpSocketInf);
|
||
PRINT("i:%d,WCHNET_SocketCreatUdp %d srcport %d\r\n", i, SocketId_UDP, TmpSocketInf.SourPort);
|
||
mStopIfError(i);
|
||
g_net_state.flag = 2;
|
||
}
|
||
|
||
|
||
void reset_net_active_timeup(void)
|
||
{
|
||
if(g_activ_counter){
|
||
g_activ_counter = 0;
|
||
}
|
||
}
|
||
|
||
/* MQTT 数据接收处理 — IoT 模式 (ref: DBN101GA) */
|
||
void mqtt_data_manage(uint8_t id)
|
||
{
|
||
uint32_t len;
|
||
static uint8_t MyBuf[RECE_BUF_LEN]; // static: 避免栈溢出
|
||
unsigned char dup;
|
||
unsigned short packetid;
|
||
int qos;
|
||
unsigned char retained;
|
||
MQTTString topicName;
|
||
unsigned char *payload;
|
||
int payloadlen;
|
||
|
||
memset(MyBuf, 0, RECE_BUF_LEN);
|
||
len = WCHNET_SocketRecvLen(id, NULL);
|
||
WCHNET_SocketRecv(id, MyBuf, &len);
|
||
PRINT("MQTT recv sock=%d len=%d type=0x%02X\n", id, (int)len, MyBuf[0]);
|
||
|
||
switch (MyBuf[0] >> 4) {
|
||
case CONNACK:
|
||
PRINT("MQTT CONNACK\n");
|
||
dg_subscribe_display_topic();
|
||
dev_initialize_pub();
|
||
reset_net_active_timeup();
|
||
g_iot_state = IOT_STATE_READY; // Sync iot_mqtt_srv state
|
||
break;
|
||
case PUBLISH:
|
||
MQTTDeserialize_publish(&dup, &qos, &retained, &packetid,
|
||
&topicName, &payload, &payloadlen, MyBuf, len);
|
||
/* V1.01: 通过 mqtt_deserialize_publish 做 topic 过滤 */
|
||
{
|
||
char TmpBuf[128] = {0};
|
||
memcpy(TmpBuf, topicName.lenstring.data, topicName.lenstring.len);
|
||
mqtt_deserialize_publish(TmpBuf, (char *)payload, payloadlen);
|
||
}
|
||
reset_net_active_timeup();
|
||
break;
|
||
case SUBACK:
|
||
PRINT("MQTT SUBACK\n");
|
||
break;
|
||
case PINGRESP:
|
||
PRINT("MQTT PINGRESP\n");
|
||
if(flag_mqtt_ping_err)
|
||
flag_mqtt_ping_err = 0;
|
||
reset_net_active_timeup();
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
g_net_state.flag = 4;
|
||
}
|
||
|
||
|
||
|
||
/*********************************************************************
|
||
* @fn WCHNET_DataManage
|
||
*
|
||
* @brief Data loopback function.
|
||
*
|
||
* @param id - socket id.
|
||
*
|
||
* @return none
|
||
*/
|
||
void WCHNET_DataManage(uint8_t id)
|
||
{
|
||
uint32_t len;
|
||
memset(MyBuf, 0, RECE_BUF_LEN);
|
||
|
||
unsigned char dup;
|
||
unsigned short packetid;
|
||
|
||
int qos;
|
||
unsigned char retained;
|
||
MQTTString topicName;
|
||
unsigned char* payload;
|
||
int payloadlen;
|
||
unsigned char *p=payload;
|
||
|
||
|
||
|
||
len = WCHNET_SocketRecvLen(id, NULL); //query length
|
||
WCHNET_SocketRecv(id, MyBuf, &len); //Read the data of the receive buffer into MyBuf
|
||
// totallen = len;
|
||
PRINT("Receive socketid:%d, Len = %d, MyBuf__:%s\r\n", id, len, MyBuf);
|
||
|
||
if(g_sub_code_enable.iot_enable){
|
||
switch(MyBuf[0] >> 4)
|
||
{
|
||
case CONNACK:
|
||
PRINT("connack\r\n");
|
||
// g_mqtt_con_flag=1;
|
||
dg_subscribe_display_topic();
|
||
dev_initialize_pub();
|
||
reset_net_active_timeup();
|
||
break;
|
||
|
||
case PUBLISH:
|
||
// use *dup, *qos, *retained, *packetid, *topicName, *payload, * payloadlen Will not work, miss some char from raw data.
|
||
MQTTDeserialize_publish(&dup,&qos,&retained,&packetid,&topicName,&payload,&payloadlen,MyBuf,len);
|
||
memset(TmpBuf, 0, MAX_TMP_BUF_LEN);
|
||
memcpy(TmpBuf, topicName.lenstring.data, topicName.lenstring.len);
|
||
// TmpBuf[topicName.lenstring.len] = 0x0;
|
||
mqtt_deserialize_publish(TmpBuf, payload, payloadlen);
|
||
// memset(payload, 0, payloadlen);
|
||
if(g_mqtt_ping_counter< 8){
|
||
g_mqtt_ping_counter = 8;
|
||
}
|
||
reset_net_active_timeup();
|
||
//TODO: need to check if len-received is out, prevent overflow.
|
||
break;
|
||
|
||
case SUBACK:
|
||
// sub_flag=1;
|
||
|
||
break;
|
||
case PINGRESP:
|
||
// printf("RecvPing\n");
|
||
//TODO: if need this?
|
||
if(flag_mqtt_ping_err)
|
||
{
|
||
flag_mqtt_ping_err = 0;
|
||
}
|
||
reset_net_active_timeup();
|
||
break;
|
||
default:
|
||
|
||
break;
|
||
}
|
||
}
|
||
else{
|
||
manage_tcp_message(id, MyBuf, len);
|
||
reset_net_active_timeup();
|
||
}
|
||
g_net_state.flag = 4;
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
/*********************************************************************
|
||
* @fn WCHNET_HandleSockInt
|
||
*
|
||
* @brief Socket Interrupt Handle
|
||
*
|
||
* @param socketid - socket id.
|
||
* intstat - interrupt status
|
||
*
|
||
* @return none
|
||
*/
|
||
void WCHNET_HandleSockInt(uint8_t socketid, uint8_t intstat)
|
||
{
|
||
uint8_t i;
|
||
|
||
// Route JSON protocol socket events -- always active regardless of mode
|
||
if (socketid == g_json_socket_listen || socketid == (g_json_socket_listen + 1)) {
|
||
tcp_json_handle_sock_int(socketid, intstat);
|
||
return;
|
||
}
|
||
|
||
// IoT MQTT mode — inline MQTT handling (ref: DBN101GA)
|
||
if (g_sub_code_enable.iot_enable) {
|
||
if (intstat & SINT_STAT_RECV) {
|
||
mqtt_data_manage(socketid);
|
||
}
|
||
if (intstat & SINT_STAT_CONNECT) {
|
||
#if KEEPLIVE_ENABLE
|
||
WCHNET_SocketSetKeepLive(socketid, ENABLE);
|
||
#endif
|
||
WCHNET_ModifyRecvBuf(socketid, (uint32_t)SocketRecvBuf[socketid], RECE_BUF_LEN);
|
||
PRINT("TCP Connect Success (MQTT)\n");
|
||
mqtt_connect();
|
||
}
|
||
if (intstat & SINT_STAT_DISCONNECT) {
|
||
PRINT("TCP Disconnect (MQTT)\n");
|
||
g_iot_state = IOT_STATE_DISCONNECTED;
|
||
g_net_state.flag = 1;
|
||
}
|
||
if (intstat & SINT_STAT_TIM_OUT) {
|
||
PRINT("TCP Timeout (MQTT)\n");
|
||
g_net_state.flag = 1;
|
||
}
|
||
return;
|
||
}
|
||
|
||
// === SSC mode below ===
|
||
g_net_state.intstat = intstat;
|
||
|
||
if (intstat & SINT_STAT_RECV) //receive data
|
||
{
|
||
WCHNET_DataManage(socketid); //Data loopback
|
||
}
|
||
if (intstat & SINT_STAT_CONNECT) //connect successfully
|
||
{
|
||
#if KEEPLIVE_ENABLE
|
||
WCHNET_SocketSetKeepLive(socketid, ENABLE);
|
||
#endif
|
||
WCHNET_ModifyRecvBuf(socketid, (uint32_t) SocketRecvBuf[socketid], RECE_BUF_LEN);
|
||
|
||
{
|
||
PRINT("TCP Connect Success\r\n");
|
||
PRINT("socket id: %d\r\n", socketid);
|
||
}
|
||
}
|
||
if (intstat & SINT_STAT_DISCONNECT) //disconnect
|
||
{
|
||
{
|
||
PRINT("TCP Disconnect\r\n");
|
||
}
|
||
g_net_state.flag = 1;
|
||
}
|
||
if (intstat & SINT_STAT_TIM_OUT) //timeout disconnect
|
||
{
|
||
{
|
||
PRINT("TCP Timeout\r\n");
|
||
}
|
||
g_net_state.flag = 1;
|
||
}
|
||
}
|
||
|
||
|
||
void dbn_net_ssc_srv(void)
|
||
{
|
||
uint8_t _flag_timestamp = 0;
|
||
static uint32_t _report_counter = 0; //�ϱ�ʱ�������
|
||
|
||
//Check net if connect
|
||
if(g_net_state.flag < 3)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if((g_net_state.intstat & SINT_STAT_RECV) || (g_net_state.intstat & SINT_STAT_CONNECT))
|
||
{
|
||
|
||
//check if update timestamp
|
||
if(!g_flag_timestamp)
|
||
{
|
||
if(mstick() - _report_counter > 2000)
|
||
{
|
||
//printf("_will_require_timestamp, _report_counter:%d, mstick:%d\n", _report_counter, mstick());
|
||
dev_get_timestamp_send();
|
||
_report_counter = mstick();
|
||
}
|
||
return;
|
||
}
|
||
|
||
//send heartbeat
|
||
if(mstick() - _report_counter > 9000)
|
||
{
|
||
_report_counter = mstick();
|
||
dev_send_heartbeat();
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
void poll_mqtt(void)
|
||
{
|
||
if(g_net_state.flag < 2)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// if(g_mqtt_con_flag == 0)
|
||
// {
|
||
// return;
|
||
// }
|
||
//
|
||
/* Auto-trigger PINGREQ every MQTT_KEEPALIVE_INTERVAL seconds of inactivity */
|
||
if (g_activ_counter > (MQTT_KEEPALIVE_INTERVAL * 1000)) {
|
||
g_activ_counter = 0;
|
||
flag_mqtt_ping_send = 1;
|
||
}
|
||
|
||
if(flag_mqtt_ping_send)
|
||
{
|
||
flag_mqtt_ping_send = 0;
|
||
flag_mqtt_ping_err++;
|
||
{
|
||
PRINT("send_mqtt_ping:%d\n", flag_mqtt_ping_err);
|
||
}
|
||
MQTT_Pingreq();
|
||
}
|
||
}
|
||
|
||
|
||
/*******************************************************************************
|
||
* Function Name : GetMacAddr
|
||
* Description : ϵͳ��ȡMAC��ַ
|
||
* Input : pMAC:ָ�������洢Mac��ַ�Ļ���
|
||
* Output : None
|
||
* Return : None
|
||
*******************************************************************************/
|
||
void GetMacAddr(unsigned char *pMAC)
|
||
{
|
||
uint8_t transbuf[6],i;
|
||
|
||
FLASH_GetMACAddress(transbuf);
|
||
for(i=0;i<6;i++)
|
||
{
|
||
pMAC[5-i]=transbuf[i];
|
||
|
||
}
|
||
}
|
||
|
||
|
||
// ��IPv4��ַ�ַ���ת��Ϊ4�ֽڵ�uint8_t���飬�������ϸ�Ĵ�����
|
||
int get_ipstr_to_array(char *src, uint8_t *dst) {
|
||
if (src == NULL || dst == NULL) {
|
||
return -1;
|
||
}
|
||
|
||
int part_count = 0;
|
||
char *token = NULL;
|
||
char *saveptr = NULL;
|
||
const char *delim = ".";
|
||
char src_copy[16];
|
||
strncpy(src_copy, src, sizeof(src_copy));
|
||
src_copy[15] = '\0';
|
||
|
||
token = strtok_r(src_copy, delim, &saveptr);
|
||
while (token != NULL && part_count < 4) {
|
||
char *endptr = NULL;
|
||
long val = strtol(token, &endptr, 10);
|
||
if (*endptr != '\0' || val < 0 || val > 255) {
|
||
return -2;
|
||
}
|
||
dst[part_count++] = (uint8_t)val;
|
||
token = strtok_r(NULL, delim, &saveptr);
|
||
}
|
||
if (part_count != 4) {
|
||
return -3;
|
||
}
|
||
if (token != NULL || (saveptr != NULL && *saveptr != '\0')) {
|
||
return -4;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
void unpack_ssc_count_off(uint8_t socket,uint8_t count_mode, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len)
|
||
{
|
||
uint16_t i,j;
|
||
uint16_t tmplen = 0;
|
||
int serPort = 0;
|
||
|
||
char *p = (char *)buf;
|
||
char *mBuff = (char *)malloc(400);
|
||
|
||
if(mBuff == NULL)
|
||
{
|
||
// PRINT("__unpack_net_udp_err, malloc_failed.\n");
|
||
return;
|
||
}
|
||
if(count_mode == 0)
|
||
{
|
||
memset(mBuff, 0, 400);
|
||
simple_parse_json(p, DPG_API_KEY_PARAMS, mBuff);
|
||
tmplen = strlen(mBuff);
|
||
|
||
if(tmplen == 0)
|
||
{
|
||
free(mBuff);
|
||
return;
|
||
}
|
||
p = mBuff;
|
||
|
||
reset_temp_guide();
|
||
simple_parse_json(p, DPG_API_KEY_PORT, temp_guide);
|
||
for(i = 0; i < strlen(temp_guide); i++)
|
||
{
|
||
if((serPort > 0x39) || (serPort < 0x30))
|
||
{
|
||
break;
|
||
}
|
||
serPort *= 10;
|
||
serPort += temp_guide[i] - 0x30;
|
||
}
|
||
}
|
||
|
||
uint8_t qw = 1;
|
||
uint8_t ds = 1;
|
||
uint8_t mode = 0;
|
||
mode |= 1;
|
||
memset(mBuff, 0, 400);
|
||
|
||
sprintf(mBuff,"{"
|
||
"\"Method\": \"%s\","
|
||
"\"Code\":0,"
|
||
"\"Message\":\"\","
|
||
"\"Data\":{"
|
||
"\"Ip\": \"%d.%d.%d.%d\","
|
||
"\"Port\": %d,"
|
||
"\"Mac\": \"%02X-%02X-%02X-%02X-%02X-%02X\","
|
||
"\"SubnetMask\": \"%d.%d.%d.%d\","
|
||
"\"Server_Ip\": \"%d.%d.%d.%d\","
|
||
"\"Gateway\": \"%d.%d.%d.%d\","
|
||
"\"Iot_Host\":\"%s\","
|
||
"\"Iot_Port\":%d,"
|
||
"\"UserName\":\"%s\","
|
||
"\"Device_id\":\"%s\","
|
||
"\"Device_type\":\"%d\","
|
||
"\"Area_amount\": %d,"
|
||
"\"Dev_amount\": %d,"
|
||
"\"Dev_mode\":%d,"
|
||
"\"Version\":\"%s,H%s,S%s\""
|
||
"}}",
|
||
SSC_Code_Count_Off,
|
||
local_net_cfg.lip[0],local_net_cfg.lip[1],local_net_cfg.lip[2],local_net_cfg.lip[3],
|
||
serPort,
|
||
local_net_cfg.mac[0], local_net_cfg.mac[1], local_net_cfg.mac[2], local_net_cfg.mac[3], local_net_cfg.mac[4], local_net_cfg.mac[5],
|
||
local_net_cfg.sub[0], local_net_cfg.sub[1], local_net_cfg.sub[2], local_net_cfg.sub[3],
|
||
//net_center_info.lssc_ip[0], net_center_info.lssc_ip[1], net_center_info.lssc_ip[2], net_center_info.lssc_ip[3],
|
||
net_center_info.lssc_ip[0], net_center_info.lssc_ip[1], net_center_info.lssc_ip[2], net_center_info.lssc_ip[3],
|
||
local_net_cfg.gw[0], local_net_cfg.gw[1], local_net_cfg.gw[2], local_net_cfg.gw[3],
|
||
iot_net_info.remote_addr, iot_net_info.mqtt_port, iot_net_info.username,
|
||
g_dev_number_str,
|
||
g_dg_sub_dev_type, //g_dg_device_type,
|
||
qw, ds, mode,
|
||
PRODUCT_MODEL, HARDWARE_VER,FIRMWARE_VER);
|
||
slen = strlen(mBuff);
|
||
|
||
if(count_mode == 0)
|
||
{
|
||
WCHNET_SocketUdpSendTo(socket, (uint8_t *)mBuff, &slen, ip, COM_LSSC_MESSAGE_UDP_PORT);
|
||
}
|
||
else
|
||
{
|
||
WCHNET_SocketUdpSendTo(SocketId_UDP, (uint8_t *)mBuff, &slen, net_center_info.lssc_ip, COM_LSSC_MESSAGE_UDP_PORT);
|
||
|
||
}
|
||
|
||
free(mBuff);
|
||
}
|
||
|
||
|
||
void unpack_ssc_device_reset(uint8_t socket, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len)
|
||
{
|
||
// ��λ�豸
|
||
uint16_t tmplen = 0;
|
||
char *p = (char *)buf;
|
||
char *mBuff = (char *)malloc(512);
|
||
if(mBuff == NULL)
|
||
{
|
||
PRINT("__unpack_ssc_device_net_set_err, malloc_failed.\n");
|
||
return;
|
||
}
|
||
//printf("Recv_net_set:%s\n", buf);
|
||
memset(mBuff, 0, 512);
|
||
simple_parse_json(p, DPG_API_KEY_PARAMS, mBuff);
|
||
tmplen = strlen(mBuff);
|
||
if(tmplen == 0)
|
||
{
|
||
free(mBuff);
|
||
return;
|
||
}
|
||
p = mBuff;
|
||
|
||
reset_temp_guide();
|
||
simple_parse_json(p, DPG_API_KEY_DEVICE_ID, temp_guide);
|
||
if(strcmp(temp_guide, g_dev_number_str) != 0)
|
||
{
|
||
free(mBuff);
|
||
return;
|
||
}
|
||
|
||
memset(mBuff, 0, 512);
|
||
sprintf(mBuff,"{"
|
||
"\"Method\": \"%s\","
|
||
"\"Code\":0,"
|
||
"\"Message\":\"Success\","
|
||
"\"Data\":{"
|
||
"\"Device_id\":\"%s\""
|
||
"}}", SSC_Code_Dev_Reset, g_dev_number_str);
|
||
slen = strlen(mBuff);
|
||
WCHNET_SocketSend(socket, (uint8_t *)mBuff, &slen);
|
||
|
||
free(mBuff);
|
||
Delay_Ms(100);
|
||
NVIC_SystemReset();
|
||
|
||
}
|
||
|
||
|
||
|
||
void unpack_ssc_tran_sub(uint8_t socket, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len)
|
||
{
|
||
uint16_t i, j;
|
||
uint16_t tmplen = 0;
|
||
char *p = (char *)buf;
|
||
|
||
char *mBuff = (char *)malloc(512);
|
||
|
||
if(mBuff == NULL)
|
||
{
|
||
return;
|
||
}
|
||
memset(mBuff, 0, 512);
|
||
|
||
simple_parse_json(p, DPG_API_KEY_PARAMS, mBuff);
|
||
tmplen = strlen(mBuff);
|
||
if(tmplen == 0)
|
||
{
|
||
free(mBuff);
|
||
return;
|
||
}
|
||
p = mBuff;
|
||
reset_temp_guide();
|
||
simple_parse_json(p, DPG_API_KEY_DEVICE_ID, temp_guide);
|
||
|
||
if(strcmp(temp_guide, g_dev_number_str) != 0)
|
||
{
|
||
free(mBuff);
|
||
return;
|
||
}
|
||
|
||
reset_temp_guide();
|
||
uint8_t _dev_type = 0;
|
||
simple_parse_json(p, SSC_Code_Dev_Type, temp_guide);
|
||
// printf("get_dev_type_str:%s\n", temp_guide);
|
||
for(i = 0; i < strlen(temp_guide); i++)
|
||
{
|
||
if((temp_guide[i] >= 0x30) && (temp_guide[i] <= 0x39))
|
||
{
|
||
_dev_type *= 10;
|
||
_dev_type += temp_guide[i] - 0x30;
|
||
}
|
||
}
|
||
|
||
|
||
free(mBuff);
|
||
}
|
||
|
||
|
||
void unpack_ssc_timestamp(uint8_t *buf, uint32_t len)
|
||
{
|
||
uint16_t tmplen = 0;
|
||
static uint8_t _first = 0;
|
||
char *p = (char *)buf;
|
||
char *mBuff = (char *)malloc(150);
|
||
if(mBuff == NULL)
|
||
{
|
||
// PRINT("__unpack_ssc_collect_cjq_acs_response_err, malloc_failed.\n");
|
||
return;
|
||
}
|
||
//printf("Recv_net_timestamp_response:%s\n", buf);
|
||
memset(mBuff, 0, 150);
|
||
simple_parse_json(p, DPG_API_KEY_DATA, mBuff);
|
||
if(strlen(mBuff) == 0)
|
||
{
|
||
free(mBuff);
|
||
return;
|
||
}
|
||
p = mBuff;
|
||
|
||
reset_temp_guide();
|
||
simple_parse_json(p, DPG_API_KEY_DEVICE_ID, temp_guide);
|
||
tmplen = strlen(temp_guide);
|
||
if(tmplen == 0)
|
||
{
|
||
free(mBuff);
|
||
return;
|
||
}
|
||
|
||
// PRINT("\n%s, line:%d, temp:%s, device_id:%s\n", __FUNCTION__, __LINE__, mBuff, g_dev_number_str);
|
||
if(strstr(temp_guide, g_dev_number_str) == NULL)
|
||
{
|
||
free(mBuff);
|
||
return;
|
||
}
|
||
g_activ_counter = 0; // mstick(); // reset active_counter
|
||
|
||
uint32_t _counter = 0;
|
||
uint16_t i = 0;
|
||
reset_temp_guide();
|
||
simple_parse_json(p, KEY_CODE_Time_Counter, temp_guide);
|
||
//printf("timestampStr:%s, p:%s\n", temp_guide, p);
|
||
for(i = 0; i < strlen(temp_guide); i++)
|
||
{
|
||
if((temp_guide[i] > 0x39) || (temp_guide[i] < 0x30))
|
||
{
|
||
break;
|
||
}
|
||
_counter *= 10;
|
||
_counter += temp_guide[i] - 0x30;
|
||
}
|
||
|
||
free(mBuff);
|
||
|
||
// uint32_t _c_counter = get_rtc_counter();
|
||
|
||
if(_first == 0)
|
||
{
|
||
//printf("before_settime,rtc_counter:%d\n", get_rtc_counter());
|
||
_first = 1;
|
||
|
||
uint16_t py,pmon,pday, phour, pmin, psec ;
|
||
// RTC_GetTime(&py,&pmon, &pday, &phour, &pmin, &psec);
|
||
// printf("\nGet_time %d-%d-%d %d:%d:%d\n", py, pmon, pday, phour, pmin, psec);
|
||
// set_rtc_from_timecount(_counter);
|
||
// RTC_GetTime(&py,&pmon, &pday, &phour, &pmin, &psec);
|
||
// printf("\nafter_settime_Get_time %d-%d-%d %d:%d:%d\n", py, pmon, pday, phour, pmin, psec);
|
||
// printf("after_settime, rtc_counter:%d\n", get_rtc_counter());
|
||
}
|
||
|
||
if(g_flag_timestamp == 0)
|
||
{
|
||
g_flag_timestamp = 1;
|
||
unpack_ssc_count_off(SocketId_UDP, 1, NULL, 0, NULL, 0);
|
||
}
|
||
else
|
||
{
|
||
// rcv_acs_dus_report_reponse();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void manage_tcp_message(uint8_t socket, uint8_t *buf, uint32_t len)
|
||
{
|
||
uint16_t tmplen = 0;
|
||
char *p = (char *)buf;
|
||
|
||
char *mMethod = (char *)malloc(20);
|
||
if(mMethod == NULL)
|
||
{
|
||
// PRINT("__unpack_net_udp0_err, malloc_failed.\n");
|
||
return;
|
||
}
|
||
|
||
memset(mMethod, 0, 20);
|
||
simple_parse_json(p, DPG_API_KEY_METHOD, mMethod);
|
||
|
||
if(strstr(mMethod, SSC_Code_TimeStamp) != NULL)
|
||
{
|
||
unpack_ssc_timestamp(buf, len);
|
||
}
|
||
|
||
free(mMethod);
|
||
}
|
||
|
||
void manage_udp_message(uint8_t socket, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len)
|
||
{
|
||
uint16_t tmplen = 0;
|
||
char *p = (char *)buf;
|
||
|
||
char *mMethod = (char *)malloc(20);
|
||
if(mMethod == NULL)
|
||
{
|
||
// PRINT("__unpack_net_udp0_err, malloc_failed.\n");
|
||
return;
|
||
}
|
||
|
||
memset(mMethod, 0, 20);
|
||
simple_parse_json(p, DPG_API_KEY_METHOD, mMethod);
|
||
|
||
|
||
if(strstr(mMethod, SSC_Code_Count_Off) != NULL)
|
||
{
|
||
unpack_ssc_count_off(socket, 0, ip, port, buf, len);
|
||
}
|
||
else if(strstr(mMethod, SSC_Code_Dev_Reset) != NULL)
|
||
{
|
||
unpack_ssc_device_reset(socket, ip, port, buf, len);
|
||
}
|
||
// else if(strstr(mMethod, SSC_Code_Device_Net_Set) != NULL)
|
||
// {
|
||
// unpack_ssc_device_net_set(socket, ip, port, buf, len);
|
||
// }
|
||
else if(strstr(mMethod, SSC_Code_Tran_Sub) != NULL)
|
||
{
|
||
unpack_ssc_tran_sub(socket, ip, port, buf, len);
|
||
}
|
||
// else if(strstr(mMethod, SSC_Code_Radar_Reset) != NULL)
|
||
// {
|
||
// unpack_ssc_radar_reset(socket, ip, port, buf, len);
|
||
// }
|
||
|
||
|
||
free(mMethod);
|
||
|
||
}
|
||
|
||
|
||
|
||
void manage_mqtt_recv_message(char * msg, int length)
|
||
{
|
||
uint8_t i = 0;
|
||
uint16_t tmplen = 0;
|
||
// Validate input parameters
|
||
if(msg == NULL || length <= 0) {
|
||
PRINT("Invalid MQTT message parameters\n");
|
||
return;
|
||
}
|
||
|
||
reset_temp_guide();
|
||
|
||
// V1.01: 优先解析新协议 cmd 字段,兼容旧 Method 字段
|
||
simple_parse_json(msg, "\"cmd\"", temp_guide);
|
||
if(strlen(temp_guide) == 0) {
|
||
simple_parse_json(msg, DPG_API_KEY_METHOD, temp_guide);
|
||
}
|
||
|
||
if(strlen(temp_guide) == 0)
|
||
{
|
||
PRINT("\nmethod is none..\n");
|
||
return;
|
||
}
|
||
PRINT("Rcv_Dis_LED_m:%s\n", temp_guide);
|
||
|
||
// 旧协议: Method = Heartbeat → 回复心跳
|
||
if(strstr(temp_guide, "Heartbeat") != NULL)
|
||
{
|
||
dev_response_heartbeat(NULL);
|
||
return;
|
||
}
|
||
|
||
// === V1.01 新协议: cmd 命令分发 ===
|
||
// 解析 msg_id
|
||
char tmp[32] = {0};
|
||
uint32_t msg_id = 0;
|
||
simple_parse_json(msg, "\"msg_id\"", tmp);
|
||
if(strlen(tmp) > 0) msg_id = (uint32_t)strtoul(tmp, NULL, 10);
|
||
|
||
// 去掉 temp_guide 里的引号
|
||
char *cmd_str = temp_guide;
|
||
if(cmd_str[0] == '"') cmd_str++;
|
||
int cmd_len = strlen(cmd_str);
|
||
if(cmd_len > 0 && cmd_str[cmd_len - 1] == '"') cmd_str[cmd_len - 1] = '\0';
|
||
|
||
// 响应 topic: g_iot_topic.topic_pub (= dld960/{sn}/dev)
|
||
char *resp_topic = (char *)g_iot_topic.topic_pub;
|
||
|
||
// --- dev_info_query ---
|
||
if(strcmp(cmd_str, "dev_info_query") == 0) {
|
||
char resp[600];
|
||
snprintf(resp, sizeof(resp),
|
||
"{\"msg_id\":%lu,\"cmd\":\"dev_info_query\","
|
||
"\"ts\":%lu,\"code\":0,\"msg\":\"success\","
|
||
"\"data\":{"
|
||
"\"dev_serial\":\"%s\",\"hard_ver\":\"%s\",\"soft_ver\":\"%s\","
|
||
"\"model\":\"%s\",\"product_code\":\"960001\","
|
||
"\"sub_code\":{\"net\":%s,\"iot\":%s},"
|
||
"\"bus\":{\"bus1\":0,\"bus2\":0,\"bus3\":0,\"bus4\":0}}}",
|
||
msg_id, mstick() / 1000,
|
||
g_dev_number_str, HARDWARE_VER, FIRMWARE_VER, PRODUCT_MODEL,
|
||
g_sub_code_enable.net_enable ? "true" : "false",
|
||
g_sub_code_enable.iot_enable ? "true" : "false");
|
||
mqtt_publish(resp_topic, resp, 1);
|
||
PRINT("IOT: dev_info_query → response\n");
|
||
return;
|
||
}
|
||
|
||
// --- pwd_verify ---
|
||
if(strcmp(cmd_str, "pwd_verify") == 0) {
|
||
char *data_buf = (char *)malloc(256);
|
||
char password[16] = {0};
|
||
if(data_buf) {
|
||
memset(data_buf, 0, 256);
|
||
simple_parse_json(msg, "\"data\"", data_buf);
|
||
if(strlen(data_buf) > 0) {
|
||
memset(tmp, 0, sizeof(tmp));
|
||
simple_parse_json(data_buf, "\"password\"", tmp);
|
||
char *pwd = tmp;
|
||
if(pwd[0] == '"') pwd++;
|
||
int plen = strlen(pwd);
|
||
if(plen > 0 && pwd[plen - 1] == '"') pwd[plen - 1] = '\0';
|
||
strncpy(password, pwd, 15);
|
||
}
|
||
free(data_buf);
|
||
}
|
||
|
||
if(strlen(password) == 6 && memcmp(password, g_dev_password, 6) == 0) {
|
||
char resp[256];
|
||
snprintf(resp, sizeof(resp),
|
||
"{\"msg_id\":%lu,\"cmd\":\"pwd_verify\","
|
||
"\"ts\":%lu,\"code\":0,\"msg\":\"success\"}",
|
||
msg_id, mstick() / 1000);
|
||
mqtt_publish(resp_topic, resp, 1);
|
||
PRINT("IOT: pwd_verify OK\n");
|
||
} else {
|
||
char resp[256];
|
||
snprintf(resp, sizeof(resp),
|
||
"{\"msg_id\":%lu,\"cmd\":\"pwd_verify\","
|
||
"\"ts\":%lu,\"code\":2,\"msg\":\"password incorrect\"}",
|
||
msg_id, mstick() / 1000);
|
||
mqtt_publish(resp_topic, resp, 1);
|
||
}
|
||
return;
|
||
}
|
||
|
||
// --- dev_serial_set ---
|
||
if(strcmp(cmd_str, "dev_serial_set") == 0) {
|
||
// TODO: 实现序列号修改
|
||
char resp[256];
|
||
snprintf(resp, sizeof(resp),
|
||
"{\"msg_id\":%lu,\"cmd\":\"dev_serial_set\","
|
||
"\"ts\":%lu,\"code\":4,\"msg\":\"not implemented yet\"}",
|
||
msg_id, mstick() / 1000);
|
||
mqtt_publish(resp_topic, resp, 1);
|
||
return;
|
||
}
|
||
|
||
// --- ssc_net_query ---
|
||
if(strcmp(cmd_str, "ssc_net_query") == 0) {
|
||
char resp[512];
|
||
snprintf(resp, sizeof(resp),
|
||
"{\"msg_id\":%lu,\"cmd\":\"ssc_net_query\","
|
||
"\"ts\":%lu,\"code\":0,\"msg\":\"success\","
|
||
"\"data\":{"
|
||
"\"dev_ip\":\"%d.%d.%d.%d\","
|
||
"\"subnet_mask\":\"%d.%d.%d.%d\","
|
||
"\"route_ip\":\"%d.%d.%d.%d\","
|
||
"\"lssc_ip\":\"%d.%d.%d.%d\","
|
||
"\"dns\":\"%d.%d.%d.%d\","
|
||
"\"port\":%d}}",
|
||
msg_id, mstick() / 1000,
|
||
local_net_cfg.lip[0], local_net_cfg.lip[1], local_net_cfg.lip[2], local_net_cfg.lip[3],
|
||
local_net_cfg.sub[0], local_net_cfg.sub[1], local_net_cfg.sub[2], local_net_cfg.sub[3],
|
||
local_net_cfg.gw[0], local_net_cfg.gw[1], local_net_cfg.gw[2], local_net_cfg.gw[3],
|
||
net_center_info.lssc_ip[0], net_center_info.lssc_ip[1], net_center_info.lssc_ip[2], net_center_info.lssc_ip[3],
|
||
local_net_cfg.dns[0], local_net_cfg.dns[1], local_net_cfg.dns[2], local_net_cfg.dns[3],
|
||
local_net_cfg.port_ssc_tcp);
|
||
mqtt_publish(resp_topic, resp, 1);
|
||
return;
|
||
}
|
||
|
||
// --- ssc_net_set ---
|
||
if(strcmp(cmd_str, "ssc_net_set") == 0) {
|
||
Local_Net_Cfg lcfg = local_net_cfg;
|
||
NET_CENTER_INFO ccfg = net_center_info;
|
||
char *data_buf = (char *)malloc(256);
|
||
if(data_buf) {
|
||
memset(data_buf, 0, 256);
|
||
simple_parse_json(msg, "\"data\"", data_buf);
|
||
if(strlen(data_buf) > 0) {
|
||
char ip_str[32];
|
||
int plen;
|
||
|
||
// dev_ip
|
||
memset(ip_str, 0, sizeof(ip_str));
|
||
simple_parse_json(data_buf, "\"dev_ip\"", ip_str);
|
||
if(strlen(ip_str) > 0) {
|
||
char *s = ip_str; if(s[0]=='"') s++; plen=strlen(s); if(plen>0&&s[plen-1]=='"') s[plen-1]=0;
|
||
get_ipstr_to_array(s, lcfg.lip);
|
||
}
|
||
// subnet_mask
|
||
memset(ip_str, 0, sizeof(ip_str));
|
||
simple_parse_json(data_buf, "\"subnet_mask\"", ip_str);
|
||
if(strlen(ip_str) > 0) {
|
||
char *s = ip_str; if(s[0]=='"') s++; plen=strlen(s); if(plen>0&&s[plen-1]=='"') s[plen-1]=0;
|
||
get_ipstr_to_array(s, lcfg.sub);
|
||
}
|
||
// route_ip
|
||
memset(ip_str, 0, sizeof(ip_str));
|
||
simple_parse_json(data_buf, "\"route_ip\"", ip_str);
|
||
if(strlen(ip_str) > 0) {
|
||
char *s = ip_str; if(s[0]=='"') s++; plen=strlen(s); if(plen>0&&s[plen-1]=='"') s[plen-1]=0;
|
||
get_ipstr_to_array(s, lcfg.gw);
|
||
}
|
||
// lssc_ip
|
||
memset(ip_str, 0, sizeof(ip_str));
|
||
simple_parse_json(data_buf, "\"lssc_ip\"", ip_str);
|
||
if(strlen(ip_str) > 0) {
|
||
char *s = ip_str; if(s[0]=='"') s++; plen=strlen(s); if(plen>0&&s[plen-1]=='"') s[plen-1]=0;
|
||
get_ipstr_to_array(s, ccfg.lssc_ip);
|
||
}
|
||
// dns
|
||
memset(ip_str, 0, sizeof(ip_str));
|
||
simple_parse_json(data_buf, "\"dns\"", ip_str);
|
||
if(strlen(ip_str) > 0) {
|
||
char *s = ip_str; if(s[0]=='"') s++; plen=strlen(s); if(plen>0&&s[plen-1]=='"') s[plen-1]=0;
|
||
get_ipstr_to_array(s, lcfg.dns);
|
||
}
|
||
// port
|
||
memset(tmp, 0, sizeof(tmp));
|
||
simple_parse_json(data_buf, "\"port\"", tmp);
|
||
if(strlen(tmp) > 0) {
|
||
uint32_t p = strtoul(tmp, NULL, 10);
|
||
if(p > 0 && p <= 65535) ccfg.tcp_port = (uint16_t)p;
|
||
}
|
||
}
|
||
free(data_buf);
|
||
}
|
||
write_net_config(&lcfg, &ccfg, &iot_net_info, &g_iot_topic);
|
||
local_net_cfg = lcfg;
|
||
net_center_info = ccfg;
|
||
|
||
char resp[256];
|
||
snprintf(resp, sizeof(resp),
|
||
"{\"msg_id\":%lu,\"cmd\":\"ssc_net_set\","
|
||
"\"ts\":%lu,\"code\":0,\"msg\":\"success\"}",
|
||
msg_id, mstick() / 1000);
|
||
mqtt_publish(resp_topic, resp, 1);
|
||
PRINT("IOT: ssc_net_set done\n");
|
||
return;
|
||
}
|
||
|
||
// --- iot_net_query ---
|
||
if(strcmp(cmd_str, "iot_net_query") == 0) {
|
||
char resp[512];
|
||
snprintf(resp, sizeof(resp),
|
||
"{\"msg_id\":%lu,\"cmd\":\"iot_net_query\","
|
||
"\"ts\":%lu,\"code\":0,\"msg\":\"success\","
|
||
"\"data\":{"
|
||
"\"host\":\"%s\",\"port\":%d,"
|
||
"\"client_id\":\"%s\",\"username\":\"%s\",\"password\":\"%s\"}}",
|
||
msg_id, mstick() / 1000,
|
||
iot_net_info.remote_addr, iot_net_info.mqtt_port,
|
||
iot_net_info.client_id, iot_net_info.username, iot_net_info.password);
|
||
mqtt_publish(resp_topic, resp, 1);
|
||
return;
|
||
}
|
||
|
||
// --- iot_net_set ---
|
||
if(strcmp(cmd_str, "iot_net_set") == 0) {
|
||
IOT_NET_INFO icfg = iot_net_info;
|
||
char *data_buf = (char *)malloc(256);
|
||
if(data_buf) {
|
||
memset(data_buf, 0, 256);
|
||
simple_parse_json(msg, "\"data\"", data_buf);
|
||
if(strlen(data_buf) > 0) {
|
||
char fld[64];
|
||
int plen;
|
||
|
||
// host
|
||
memset(fld, 0, sizeof(fld));
|
||
simple_parse_json(data_buf, "\"host\"", fld);
|
||
if(strlen(fld) > 0) {
|
||
char *s = fld; if(s[0]=='"') s++; plen=strlen(s); if(plen>0&&s[plen-1]=='"') s[plen-1]=0;
|
||
strncpy((char *)icfg.remote_addr, s, 63);
|
||
}
|
||
// port
|
||
memset(tmp, 0, sizeof(tmp));
|
||
simple_parse_json(data_buf, "\"port\"", tmp);
|
||
if(strlen(tmp) > 0) {
|
||
uint32_t p = strtoul(tmp, NULL, 10);
|
||
if(p > 0 && p <= 65535) icfg.mqtt_port = (uint16_t)p;
|
||
}
|
||
// client_id
|
||
memset(fld, 0, sizeof(fld));
|
||
simple_parse_json(data_buf, "\"client_id\"", fld);
|
||
if(strlen(fld) > 0) {
|
||
char *s = fld; if(s[0]=='"') s++; plen=strlen(s); if(plen>0&&s[plen-1]=='"') s[plen-1]=0;
|
||
strncpy((char *)icfg.client_id, s, 63);
|
||
}
|
||
// username
|
||
memset(fld, 0, sizeof(fld));
|
||
simple_parse_json(data_buf, "\"username\"", fld);
|
||
if(strlen(fld) > 0) {
|
||
char *s = fld; if(s[0]=='"') s++; plen=strlen(s); if(plen>0&&s[plen-1]=='"') s[plen-1]=0;
|
||
strncpy((char *)icfg.username, s, 63);
|
||
}
|
||
// password
|
||
memset(fld, 0, sizeof(fld));
|
||
simple_parse_json(data_buf, "\"password\"", fld);
|
||
if(strlen(fld) > 0) {
|
||
char *s = fld; if(s[0]=='"') s++; plen=strlen(s); if(plen>0&&s[plen-1]=='"') s[plen-1]=0;
|
||
strncpy((char *)icfg.password, s, 31);
|
||
}
|
||
}
|
||
free(data_buf);
|
||
}
|
||
write_net_config(&local_net_cfg, &net_center_info, &icfg, &g_iot_topic);
|
||
iot_net_info = icfg;
|
||
|
||
char resp[256];
|
||
snprintf(resp, sizeof(resp),
|
||
"{\"msg_id\":%lu,\"cmd\":\"iot_net_set\","
|
||
"\"ts\":%lu,\"code\":0,\"msg\":\"success\"}",
|
||
msg_id, mstick() / 1000);
|
||
mqtt_publish(resp_topic, resp, 1);
|
||
PRINT("IOT: iot_net_set done\n");
|
||
return;
|
||
}
|
||
|
||
// --- iot_topic_query ---
|
||
if(strcmp(cmd_str, "iot_topic_query") == 0) {
|
||
char resp[512];
|
||
snprintf(resp, sizeof(resp),
|
||
"{\"msg_id\":%lu,\"cmd\":\"iot_topic_query\","
|
||
"\"ts\":%lu,\"code\":0,\"msg\":\"success\","
|
||
"\"data\":{"
|
||
"\"client_id_enable\":%s,"
|
||
"\"topic_pub\":\"%s\",\"topic_sub\":\"%s\"}}",
|
||
msg_id, mstick() / 1000,
|
||
g_iot_topic.clientid_enable ? "true" : "false",
|
||
g_iot_topic.topic_pub, g_iot_topic.topic_sub);
|
||
mqtt_publish(resp_topic, resp, 1);
|
||
return;
|
||
}
|
||
|
||
// --- iot_topic_set ---
|
||
if(strcmp(cmd_str, "iot_topic_set") == 0) {
|
||
IOT_Topic topic = g_iot_topic;
|
||
char *data_buf = (char *)malloc(256);
|
||
if(data_buf) {
|
||
memset(data_buf, 0, 256);
|
||
simple_parse_json(msg, "\"data\"", data_buf);
|
||
if(strlen(data_buf) > 0) {
|
||
char fld[64];
|
||
int plen;
|
||
|
||
// client_id_enable (bool)
|
||
memset(tmp, 0, sizeof(tmp));
|
||
simple_parse_json(data_buf, "\"client_id_enable\"", tmp);
|
||
if(strlen(tmp) > 0) topic.clientid_enable = (uint8_t)(strstr(tmp, "true") ? 1 : 0);
|
||
|
||
// topic_pub
|
||
memset(fld, 0, sizeof(fld));
|
||
simple_parse_json(data_buf, "\"topic_pub\"", fld);
|
||
if(strlen(fld) > 0) {
|
||
char *s = fld; if(s[0]=='"') s++; plen=strlen(s); if(plen>0&&s[plen-1]=='"') s[plen-1]=0;
|
||
strncpy((char *)topic.topic_pub, s, 63);
|
||
}
|
||
// topic_sub
|
||
memset(fld, 0, sizeof(fld));
|
||
simple_parse_json(data_buf, "\"topic_sub\"", fld);
|
||
if(strlen(fld) > 0) {
|
||
char *s = fld; if(s[0]=='"') s++; plen=strlen(s); if(plen>0&&s[plen-1]=='"') s[plen-1]=0;
|
||
strncpy((char *)topic.topic_sub, s, 63);
|
||
}
|
||
}
|
||
free(data_buf);
|
||
}
|
||
write_net_config(&local_net_cfg, &net_center_info, &iot_net_info, &topic);
|
||
g_iot_topic = topic;
|
||
|
||
char resp[256];
|
||
snprintf(resp, sizeof(resp),
|
||
"{\"msg_id\":%lu,\"cmd\":\"iot_topic_set\","
|
||
"\"ts\":%lu,\"code\":0,\"msg\":\"success\"}",
|
||
msg_id, mstick() / 1000);
|
||
mqtt_publish(resp_topic, resp, 1);
|
||
PRINT("IOT: iot_topic_set done\n");
|
||
return;
|
||
}
|
||
|
||
// --- pwd_set ---
|
||
if(strcmp(cmd_str, "pwd_set") == 0) {
|
||
char resp[256];
|
||
snprintf(resp, sizeof(resp),
|
||
"{\"msg_id\":%lu,\"cmd\":\"pwd_set\","
|
||
"\"ts\":%lu,\"code\":4,\"msg\":\"not implemented yet\"}",
|
||
msg_id, mstick() / 1000);
|
||
mqtt_publish(resp_topic, resp, 1);
|
||
return;
|
||
}
|
||
|
||
// --- factory_reset ---
|
||
if(strcmp(cmd_str, "factory_reset") == 0) {
|
||
char resp[256];
|
||
snprintf(resp, sizeof(resp),
|
||
"{\"msg_id\":%lu,\"cmd\":\"factory_reset\","
|
||
"\"ts\":%lu,\"code\":0,\"msg\":\"success\"}",
|
||
msg_id, mstick() / 1000);
|
||
mqtt_publish(resp_topic, resp, 1);
|
||
PRINT("IOT: factory_reset — resetting...\n");
|
||
Delay_Ms(200);
|
||
factory_dev_info();
|
||
return;
|
||
}
|
||
|
||
// --- device_reset (无响应,复位后断开) ---
|
||
if(strcmp(cmd_str, "device_reset") == 0) {
|
||
PRINT("IOT: device_reset — rebooting...\n");
|
||
NVIC_SystemReset();
|
||
return;
|
||
}
|
||
|
||
// --- report_config ---
|
||
if(strcmp(cmd_str, "report_config") == 0) {
|
||
char *data_buf = (char *)malloc(512);
|
||
if(data_buf) {
|
||
memset(data_buf, 0, 512);
|
||
simple_parse_json(msg, "\"data\"", data_buf);
|
||
|
||
if(strlen(data_buf) > 0) {
|
||
// sensor_type (int)
|
||
memset(tmp, 0, sizeof(tmp));
|
||
simple_parse_json(data_buf, "\"sensor_type\"", tmp);
|
||
if(strlen(tmp) > 0) g_report_cfg.sensor_type = (uint8_t)strtoul(tmp, NULL, 10);
|
||
|
||
// enable (bool)
|
||
memset(tmp, 0, sizeof(tmp));
|
||
simple_parse_json(data_buf, "\"enable\"", tmp);
|
||
if(strlen(tmp) > 0) g_report_cfg.enable = (uint8_t)(strstr(tmp, "true") ? 1 : 0);
|
||
|
||
// once (bool)
|
||
memset(tmp, 0, sizeof(tmp));
|
||
simple_parse_json(data_buf, "\"once\"", tmp);
|
||
if(strlen(tmp) > 0) g_report_cfg.once = (uint8_t)(strstr(tmp, "true") ? 1 : 0);
|
||
|
||
// env_eval (bool)
|
||
memset(tmp, 0, sizeof(tmp));
|
||
simple_parse_json(data_buf, "\"env_eval\"", tmp);
|
||
if(strlen(tmp) > 0) g_report_cfg.env_eval = (uint8_t)(strstr(tmp, "true") ? 1 : 0);
|
||
|
||
// interval (int)
|
||
memset(tmp, 0, sizeof(tmp));
|
||
simple_parse_json(data_buf, "\"interval\"", tmp);
|
||
if(strlen(tmp) > 0) g_report_cfg.interval = (uint16_t)strtoul(tmp, NULL, 10);
|
||
|
||
// ack_required (bool)
|
||
memset(tmp, 0, sizeof(tmp));
|
||
simple_parse_json(data_buf, "\"ack_required\"", tmp);
|
||
if(strlen(tmp) > 0) g_report_cfg.ack_required = (uint8_t)(strstr(tmp, "true") ? 1 : 0);
|
||
|
||
// timeout (int)
|
||
memset(tmp, 0, sizeof(tmp));
|
||
simple_parse_json(data_buf, "\"timeout\"", tmp);
|
||
if(strlen(tmp) > 0) g_report_cfg.timeout = (uint16_t)strtoul(tmp, NULL, 10);
|
||
}
|
||
free(data_buf);
|
||
}
|
||
|
||
char resp[400];
|
||
snprintf(resp, sizeof(resp),
|
||
"{\"msg_id\":%lu,\"cmd\":\"report_config\","
|
||
"\"ts\":%lu,\"code\":0,\"msg\":\"success\","
|
||
"\"data\":{"
|
||
"\"sensor_type\":%d,\"enable\":%s,\"once\":%s,\"env_eval\":%s,"
|
||
"\"interval\":%u,\"ack_required\":%s,\"timeout\":%u}}",
|
||
msg_id, mstick() / 1000,
|
||
g_report_cfg.sensor_type,
|
||
g_report_cfg.enable ? "true" : "false",
|
||
g_report_cfg.once ? "true" : "false",
|
||
g_report_cfg.env_eval ? "true" : "false",
|
||
g_report_cfg.interval,
|
||
g_report_cfg.ack_required ? "true" : "false",
|
||
g_report_cfg.timeout);
|
||
mqtt_publish(resp_topic, resp, 1);
|
||
PRINT("IOT: report_config enable=%d interval=%u sensor=%d\n",
|
||
g_report_cfg.enable, g_report_cfg.interval, g_report_cfg.sensor_type);
|
||
return;
|
||
}
|
||
|
||
// --- 未支持的命令 ---
|
||
{
|
||
char resp[256];
|
||
snprintf(resp, sizeof(resp),
|
||
"{\"msg_id\":%lu,\"cmd\":\"%s\","
|
||
"\"ts\":%lu,\"code\":4,\"msg\":\"unsupported command\"}",
|
||
msg_id, cmd_str, mstick() / 1000);
|
||
mqtt_publish(resp_topic, resp, 1);
|
||
PRINT("IOT: unsupported cmd=%s\n", cmd_str);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*********************************************************************
|
||
* @fn WCHNET_HandleGlobalInt
|
||
*
|
||
* @brief Global Interrupt Handle
|
||
*
|
||
* @return none
|
||
*/
|
||
void WCHNET_HandleGlobalInt(void)
|
||
{
|
||
uint8_t intstat;
|
||
uint16_t i;
|
||
uint8_t socketint;
|
||
|
||
intstat = WCHNET_GetGlobalInt(); //get global interrupt flag
|
||
if (intstat & GINT_STAT_UNREACH ) //Unreachable interrupt
|
||
{
|
||
PRINT("GINT_STAT_UNREACH\r\n");
|
||
}
|
||
if (intstat & GINT_STAT_IP_CONFLI) //IP conflict
|
||
{
|
||
PRINT("GINT_STAT_IP_CONFLI\r\n");
|
||
}
|
||
if (intstat & GINT_STAT_PHY_CHANGE) //PHY status change
|
||
{
|
||
i = WCHNET_GetPHYStatus();
|
||
if (i & PHY_Linked_Status)
|
||
PRINT("PHY Link Success\r\n");
|
||
}
|
||
if (intstat & GINT_STAT_SOCKET) //socket related interrupt
|
||
{
|
||
for (i = 0; i < WCHNET_MAX_SOCKET_NUM; i++) {
|
||
socketint = WCHNET_GetSocketInt(i);
|
||
if (socketint) {
|
||
PRINT("SockInt: sock=%d stat=0x%02X\n", i, socketint);
|
||
WCHNET_HandleSockInt(i, socketint);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void net_srv_init(void)
|
||
{
|
||
uint8_t i;
|
||
|
||
if(g_net_state.flag == 0)
|
||
{
|
||
i = ETH_LibInit(local_net_cfg.lip, local_net_cfg.gw, local_net_cfg.sub, local_net_cfg.mac); //Ethernet library initialize
|
||
mStopIfError(i);
|
||
if (i == WCHNET_ERR_SUCCESS)
|
||
{
|
||
PRINT("WCHNET_LibInit Success\r\n");
|
||
g_net_state.flag = 1;
|
||
|
||
#if KEEPLIVE_ENABLE //Configure keeplive parameters
|
||
{
|
||
struct _KEEP_CFG cfg;
|
||
|
||
cfg.KLIdle = 20000;
|
||
cfg.KLIntvl = 15000;
|
||
cfg.KLCount = 9;
|
||
WCHNET_ConfigKeepLive(&cfg);
|
||
}
|
||
#endif
|
||
memset(socket, 0xff, WCHNET_MAX_SOCKET_NUM);
|
||
|
||
}
|
||
|
||
}
|
||
|
||
if(g_net_state.flag == 1)
|
||
{
|
||
if (g_sub_code_enable.iot_enable) {
|
||
/* IoT MQTT mode -- init MQTT client, skip UDP */
|
||
iot_mqtt_init(); // Init IoT MQTT client (connect to broker)
|
||
g_net_state.flag = 2; // Skip SSC init, advance state directly
|
||
} else {
|
||
/* SSC mode -- create UDP socket + JSON server */
|
||
WCHNET_CreateUdpSocket();
|
||
tcp_json_srv_init(); // Start JSON protocol TCP listener on port 5960
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|