#include "main.h" #include "os-app.h" #include #include #include #include #include #include "usart-board.h" #include "mqtt-board.h" #include "network.h" #include "netdrv.h" #include "proto.h" #include "util.h" #include "data.h" #include "disdefine.h" #include "jsonpacket.h" #include "jsonunpack.h" #include #include "user_config.h" #if !defined(LOG_TAG) #define LOG_TAG "network" #endif #include ALIGN (RT_ALIGN_SIZE) static char thread_stack[4096]; static struct rt_thread netapp_thread; extern MqttDrv_t gMqttDrv; static rt_timer_t timer; static uint32_t g_net_5min_timer[SUBTOPIC_COUNT] = {0}; static uint32_t g_net_1min_timer[SUBTOPIC_COUNT] = {0}; static void timerouter (void * parameter) { TypeIndexMail_t mail; for (int i = 0; i < SUBTOPIC_COUNT; i++) { if (g_net_1min_timer[i] == 1) { g_net_1min_timer[i] = 60; mail.Type = MAIL_COMM_HEART; mail.index = i + 1; rt_mb_send (gTCommMail, * ( (uint32_t *) &mail)); } if (g_net_5min_timer[i] == 1) { g_net_5min_timer[i] = 60 * 5; mail.Type = MAIL_COMM_STAND; mail.index = i + 1; rt_mb_send (gTCommMail, * ( (uint32_t *) &mail)); } if (g_net_1min_timer[i] > 1) g_net_1min_timer[i]--; if (g_net_5min_timer[i] > 1) g_net_5min_timer[i]--; } } const static char upinfo[][10] = {"heart", "regist", "stand", "sluice", "upack", "slack","readcfg"} ; static void thread_entry (void * argument) { log_i ("network was start!"); TypeIndexMail_t mail; timer = rt_timer_create ("timer", timerouter, RT_NULL, 1000, RT_TIMER_FLAG_PERIODIC); // 读取网络驱动类型 netdrv_init(); MQTTThreadStart(); char data[100] = {0}; int tx_size = 0; #ifndef USER_JSON_PACKET char rxdata_decode[256]; int rxdata_decode_size = 0; uint32_t datak; #endif // 判断站点类型 //site_type char * p = ef_get_env ("site_type") ; int site_type = cSiteType2Index(p); log_i ("site_type:%d", site_type); //CommTMail_t mail; // 注册网络驱动 // 注册网络驱动 while (1) { INIT: if (RT_EOK == rt_event_recv (gTrigEvents, EVENT_TRIG_COMM_RST, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_NO, RT_NULL)) { log_i ("net work lost"); mail.Type = MAIL_VIEW_NET_STE; mail.index = DIS_STE_ERROR; rt_mb_send (gViewMail, * ( (uint32_t*) &mail)); rt_timer_stop (timer); // 发送消息给 } if (MQTT_Subscribed() != 1) // 网络链接不成功 { rt_thread_mdelay (1000); goto INIT; } // 订阅成功 if (RT_EOK == rt_event_recv (gTrigEvents, EVENT_TRIG_MQTT_SUB, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_NO, RT_NULL)) { log_i ("sub Success"); // // 发送注册报 // mail.Type = MAIL_COMM_REGIST; // mail.index = 1; // rt_mb_send (gTCommMail, * ( (uint32_t *) &mail)); for (int i = 0; i < SUBTOPIC_COUNT; i++) { rt_timer_start (timer); g_net_1min_timer[i] = i * 10 + 5; g_net_5min_timer[i] = i * 10 + 10; mail.Type = MAIL_VIEW_NET_STE; mail.index = DIS_STE_SUCCSEE; rt_mb_send (gViewMail, * ( (uint32_t*) &mail)); } } if (rt_mb_recv (gTCommMail, (rt_ubase_t *) &mail, RT_WAITING_NO) == RT_EOK) { log_i ("send packet: type:%s,index:%d", upinfo[mail.Type], mail.index); if (g_ifupdate != 1) { switch (mail.Type) { case MAIL_COMM_HEART: #ifdef USER_JSON_PACKET gMqttDrv.tx_size = JsonHeartDatapacket ( (uint8_t *) gMqttDrv.txbuff); gMqttDrv.tx_index = mail.index; #else // 心跳数据 gMqttDrv.tx_size = PacketHeader (0x2F, data, 4, gMqttDrv.txbuff); gMqttDrv.tx_index = mail.index; #endif MQTT_SendData () ; break; case MAIL_COMM_REGIST: // 注册报 #ifdef USER_JSON_PACKET // 使用Json格式数据包 // gMqttDrv.tx_size = JsonRegistDataPacket ((uint8_t *) gMqttDrv.txbuff); // gMqttDrv.tx_index = mail.index; // 通道号 #else // 心跳数据 tx_size = PacketUpRegist (data); gMqttDrv.tx_size = PacketHeader (0xE4, data, tx_size, gMqttDrv.txbuff); gMqttDrv.tx_index = mail.index; #endif MQTT_SendData () ; break; case MAIL_COMM_SLUICE: // 闸门状态自报 #ifndef USER_JSON_PACKET // 使用Json格式数据包 tx_size = PacketSluiceUp (mail.index - 1, data); gMqttDrv.tx_size = PacketHeader (0x4E, data, tx_size, gMqttDrv.txbuff); gMqttDrv.tx_index = mail.index; MQTT_SendData () ; break; #endif case MAIL_COMM_STAND: // 5分钟标准包上报 #ifdef USER_JSON_PACKET // 使用Json格式数据包 // 判断站点类型 switch (site_type) { case SiteSluice: // 闸门站 gMqttDrv.tx_size = Json5MinSluiceDataPacket ( (uint8_t *) gMqttDrv.txbuff); break; case SiteFlow: case SiteSee: case SiteLevel: case SiteSkew: gMqttDrv.tx_size = Json5MinFlowDataPacket ( (uint8_t *) gMqttDrv.txbuff); break; case SiteColl: case SiteServer: break; } gMqttDrv.tx_index = mail.index; #else // 心跳数据 tx_size = PakcetTimerUp (mail.index - 1, data); gMqttDrv.tx_size = PacketHeader (0x31, data, tx_size, gMqttDrv.txbuff); gMqttDrv.tx_index = mail.index; #endif MQTT_SendData () ; break; // case MAIL_COMM_SLACK: // 提闸的应答 // tx_size = PacketSluiceAck (data); // gMqttDrv.tx_size = PacketHeader (0x4E, data, tx_size, gMqttDrv.txbuff); // gMqttDrv.tx_index = mail.index; // MQTT_SendData(); // break; // MQTT_SendData(); // break; case MAIL_COMM_READPARA: #ifdef USER_JSON_PACKET // 使用Json格式数据包 gMqttDrv.tx_size = JsonConfigReadDataPacket ((uint8_t *) gMqttDrv.txbuff); gMqttDrv.tx_index = mail.index; #else // 心跳数据 tx_size = PacketUpRegist (data); gMqttDrv.tx_size = PacketHeader (0xE4, data, tx_size, gMqttDrv.txbuff); gMqttDrv.tx_index = mail.index; #endif MQTT_SendData(); break; case MAIL_COMM_UPACK: // 升级的应答 #ifdef USER_JSON_PACKET // 使用Json格式数据包 gMqttDrv.tx_size = JsonAckDownload ((uint8_t *) gMqttDrv.txbuff,DownUpdate); gMqttDrv.tx_index = mail.index; #else // 心跳数据 tx_size = PacketAnsAck (data); gMqttDrv.tx_size = PacketHeader (0xE0, data, tx_size, gMqttDrv.txbuff); gMqttDrv.tx_index = mail.index; #endif break; case MAIL_COMM_SLACK: // 升级的应答 #ifdef USER_JSON_PACKET // 使用Json格式数据包 gMqttDrv.tx_size = JsonAckDownload ((uint8_t *) gMqttDrv.txbuff,DownRun); gMqttDrv.tx_index = mail.index; #else // 心跳数据 tx_size = PacketAnsAck (data); gMqttDrv.tx_size = PacketHeader (0xE0, data, tx_size, gMqttDrv.txbuff); gMqttDrv.tx_index = mail.index; #endif break; case MAIL_COMM_WRACK: // 升级的应答 #ifdef USER_JSON_PACKET // 使用Json格式数据包 gMqttDrv.tx_size = JsonAckDownload ((uint8_t *) gMqttDrv.txbuff,DownConfig); gMqttDrv.tx_index = mail.index; #else // 心跳数据 tx_size = PacketAnsAck (data); gMqttDrv.tx_size = PacketHeader (0xE0, data, tx_size, gMqttDrv.txbuff); gMqttDrv.tx_index = mail.index; #endif break; case MAIL_COMM_FACACK: // 升级的应答 #ifdef USER_JSON_PACKET // 使用Json格式数据包 gMqttDrv.tx_size = JsonAckDownload ((uint8_t *) gMqttDrv.txbuff,DownFact); gMqttDrv.tx_index = mail.index; #else // 心跳数据 tx_size = PacketAnsAck (data); gMqttDrv.tx_size = PacketHeader (0xE0, data, tx_size, gMqttDrv.txbuff); gMqttDrv.tx_index = mail.index; #endif break; default: break; } } } // 接受数据 if (RT_EOK == rt_event_recv (gTrigEvents, EVENT_TRIG_COMM_RX, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_NO, RT_NULL)) { #ifdef USER_JSON_PACKET // 使用Json格式数据包 // 这里-1的作用是将通道0 作为升级通道 JsonUnPacket(gMqttDrv.rx_index - 1,gMqttDrv.rxbuff); // 第n个通道过来的数据 // 解析数据 #else rxdata_decode_size = hexstr_to_hexbyte (gMqttDrv.rxbuff, rxdata_decode, gMqttDrv.rx_size); elog_hexdump("recv",16,rxdata_decode,rxdata_decode_size); switch ( (int) rxdata_decode[10]) { case 0x4E: // 控制闸门操作 { // 远程提闸 datak = rxdata_decode[18]; datak = (datak << 8) + rxdata_decode[19]; log_i ("chann: %d,open:%u mm\r\n",gMqttDrv.rx_index, datak/10); //SluiceData[gMqttDrv.rx_index].opt = 1; // 执行操作闸门 SluiceData[0].sopen = datak / 10; mail.Type = MAIL_SLUICE_OPT; mail.index = gMqttDrv.rx_index-1; // 获取是从哪个通道来的数据 rt_mb_send (gSluiceMail, * ( (uint32_t*) &mail)); log_i ("index:%u\r\n", mail.index); // 回复应答 mail.Type = MAIL_COMM_SLACK; mail.index = gMqttDrv.rx_index; rt_mb_send (gTCommMail, * ( (uint32_t*) &mail)); break; } case 0xE0:// 远程升级 { int filenamesize = 0; rt_memset (SysData.fileName, 0, 32); filenamesize = rxdata_decode[12] - 2; rt_memcpy (SysData.fileName, &rxdata_decode[16], filenamesize); // 启动升级线程 rt_kprintf ("filename:[%s]\r\n", SysData.fileName); // 回复应答 mail.Type = MAIL_COMM_UPACK; mail.index = gMqttDrv.rx_index; rt_mb_send (gTCommMail, * ( (uint32_t*) &mail)); rt_thread_mdelay (2000); UpgradeThreadStart(); // // 应答ACK break; } case 0xE1: // 远程停止闸门 { mail.Type = MAIL_SLUICE_STP; // 停止提 mail.index = gMqttDrv.rx_index - 1; rt_mb_send (gSluiceMail, * ( (uint32_t*) &mail)); break; } case 0xE2: // 读取远程参数 { break; } default: break; } #endif } // 网络连接丢失 rt_thread_mdelay (10); } //NETWORKEXIT: } void NET_APPThreadStart (void) { /* 创建线程1,名称是thread1,入口是thread1_entry*/ rt_thread_init (&netapp_thread, "netapp_thread", thread_entry, RT_NULL, &thread_stack[0], sizeof (thread_stack), NET_APP_THREAD_PRIORITY, NET_APP_THREAD_TIMESLICE); rt_thread_startup (&netapp_thread); return ; }