tcp_server.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. #include "lwip/opt.h"
  2. #include "lwip/sys.h"
  3. #include "tcp_server.h"
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include "stm32f2xx.h"
  7. #include "main.h"
  8. #include "lwip/tcp.h"
  9. #include "lwip/memp.h"
  10. #include "lwip/api.h"
  11. #include "lwip/sockets.h"
  12. #include "log.h"
  13. #include "app_ethernet.h"
  14. #include "gateway_message.h"
  15. #include "stdlib.h"
  16. #include "timer.h"
  17. #include "sys_mqtt.h"
  18. #include "updata.h"
  19. #include "app_ethernet.h"
  20. #include "stm32f2xx_hal.h"
  21. #include "myFile.h"
  22. #include "app_ethernet.h"
  23. uint8_t closeFlag = 0; // DHCP关闭标志位
  24. uint8_t ProtocolsModeFlag = 1;// 默认 :开启内置协议模式
  25. uint8_t TransparentModeFlag = 0; // 表示用串口透传 将数据原封不动的发给客户端
  26. ip_config load_ip_config = {0};
  27. ip_config *get_ip_config()
  28. {
  29. return &load_ip_config;
  30. }
  31. #if 1
  32. // 解析设备当前的硬件信息(结构体内的数据)
  33. void get_device_params(char* device_params)
  34. {
  35. GATEWAY_PARAMS *get;
  36. get= get_gateway_config_params();
  37. DEVICE_PARAMS *current_device=get->device_params;
  38. sprintf(device_params, "{\"read_config\":\"success\",\"baudrate\":%d,\"checkBit\":%d,\"commandTopic\":\"%s\",\"dataBit\":%d,\
  39. \"deviceId\":\"%s\",\"host\":\"%s\",\"inboundTime\":%d,\"messageTopic\":\"%s\",\"port\":%d,\"stopBit\":%d,\"deviceList\":[",get->baudrate,
  40. get->checkBit,get->commandTopic,get->dataBits,get->deviceId,get->host,get->inboundTime,get->messageTopic,get->port,get->stopBit);
  41. while(current_device != NULL)
  42. {
  43. sprintf(device_params + strlen(device_params),"{\"protocol\":%d,\"bigLittleFormat\":%d,\"deviceId\":\"%s\",\"sensorData\":[",
  44. current_device->protocol,current_device->MDBbigLittleFormat,current_device->deviceID);
  45. GATEWAY_READ_DLT645_COMMAND *read_dlt645_command = current_device->params->gateway_read_dlt645_command;
  46. GATEWAY_READ_MODBUS_COMMAND *read_modbus_command = current_device->params->gateway_read_modbus_command;
  47. GATEWAY_WRITE_MODBUS_COMMAND *write_modbus_command = current_device->params->gateway_write_modbus_command;
  48. // dlt645 read
  49. while(read_dlt645_command != NULL)
  50. {
  51. sprintf(device_params + strlen(device_params),"{\"identifier645\":%d,\"identifier\":\"%s\",\"deviceID645\":\"%s\"},",
  52. read_dlt645_command->Identification,read_dlt645_command->keyword,read_dlt645_command->deviceID645);
  53. read_dlt645_command = read_dlt645_command->nextParams;
  54. }
  55. // modbus read
  56. while(read_modbus_command != NULL)
  57. {
  58. sprintf(device_params + strlen(device_params),"{\"rFunctionCode\":%d,\"registerAddress\":%d,\"slaveAddress\":%d,\"registerByteNum\":%d,\"identifier\":\"%s\",\"precise\":%d},",
  59. read_modbus_command->functionCode, read_modbus_command->registerAddress,read_modbus_command->slaveAddress,
  60. read_modbus_command->registerByteNum,read_modbus_command->keyword,read_modbus_command->decimalPoint);
  61. read_modbus_command = read_modbus_command->nextParams;
  62. }
  63. // modbus write
  64. sprintf(device_params + strlen(device_params)-1,"], \"commandData\":[");//sensorData:[
  65. while(write_modbus_command != NULL)
  66. {
  67. sprintf(device_params + strlen(device_params),"{\"registerAddress\":%d,\"slaveAddress\":%d,\"wFunctionCode\":%d,\"registerByteNum\":%d},",
  68. write_modbus_command->registerAddress,write_modbus_command->slaveAddress,write_modbus_command->functionCode,write_modbus_command->registerByteNum);
  69. write_modbus_command = write_modbus_command->nextParams;
  70. }
  71. sprintf(device_params + strlen(device_params)-1,"]},");// commandData:[
  72. current_device = current_device->nextDevice;
  73. }
  74. sprintf(device_params + strlen(device_params) -1 ,"]}");
  75. }
  76. // 储存上位机发送的config数据,并返回上位机操作结果
  77. void save_config(int client_socket,char* buf)
  78. {
  79. GATEWAY_PARAMS *get;
  80. get= get_gateway_config_params();
  81. char* saveData = mymalloc(SRAMEX,20 * 1024);//(RECV_BUF_SIZE);// 存储config数据 最大20K
  82. if(saveData == NULL)
  83. LogPrint(LOG_ERROR,__FILE__,__FUNCTION__,__LINE__,"recv buf malloc fail");
  84. memset(saveData,0,strlen(saveData));
  85. // 插入tcp_config标志位,后续不通过http获取默认配置数据
  86. sprintf(saveData, "tcp_config");
  87. sprintf(saveData + strlen(saveData),"%s",buf);
  88. // 获取上位机发送的数据
  89. do{
  90. memset(buf, 0, strlen(buf));
  91. recv(client_socket,buf,1460,0);
  92. memcpy(saveData + strlen(saveData), buf, strlen(buf));
  93. }while(buf[1] != 0 && buf[1459] != 0);
  94. // 删除当前文件,写入新文件
  95. DeleteDirFile("device.txt");
  96. write_file("device.txt",saveData,strlen(saveData));// 储存到flash 不用判断失败
  97. // 释放结构体
  98. myfree(SRAMEX, get->device_params->params->gateway_read_dlt645_command);
  99. get->device_params->params->gateway_read_dlt645_command = NULL;
  100. myfree(SRAMEX, get->device_params->params->gateway_read_modbus_command);
  101. get->device_params->params->gateway_read_modbus_command = NULL;
  102. myfree(SRAMEX, get->device_params->params->gateway_write_modbus_command);
  103. get->device_params->params->gateway_write_modbus_command = NULL;
  104. myfree(SRAMEX, get->device_params->params);
  105. get->device_params->params = NULL;
  106. myfree(SRAMEX, get->device_params);
  107. get->device_params = NULL;
  108. get = NULL;
  109. // 重新解析config数据
  110. addGatewayParams(saveData);
  111. myfree(SRAMEX, saveData);
  112. char* retMsg = mymalloc(SRAMEX,32);
  113. memset(retMsg, 0, strlen(retMsg));
  114. retMsg = "{\"write_config\":\"success\"}";
  115. send(client_socket, retMsg, strlen(retMsg), 0);
  116. myfree(SRAMEX ,retMsg);
  117. }
  118. // 储存上位机发送的config_add数据,并返回上位机操作结果
  119. void add_config(int client_socket, char* dataBuf)
  120. {
  121. GATEWAY_PARAMS *get;
  122. get= get_gateway_config_params();
  123. DEVICE_PARAMS *device=get->device_params;
  124. char* retMsg = mymalloc(SRAMEX,32);
  125. memset(retMsg, 0, strlen(retMsg));
  126. while(device != NULL)// 一直轮询到当前为NULL
  127. {
  128. device = device->nextDevice;
  129. }
  130. addDevice(dataBuf);
  131. // 再检查更新后的deviceId是否为NULL
  132. if(device == NULL)// error
  133. {
  134. retMsg = "{\"write_config\":\"error\"}";
  135. send(client_socket, retMsg, strlen(retMsg), 0);
  136. }
  137. else// success
  138. {
  139. retMsg = "{\"write_config\":\"success\"}";
  140. send(client_socket, retMsg, strlen(retMsg), 0);
  141. }
  142. myfree(SRAMEX, retMsg);
  143. }
  144. // 设备嗅探
  145. void find_device(int client_socket)
  146. {
  147. char deviceId[50];// 发送设备名
  148. GATEWAY_PARAMS *get;
  149. get= get_gateway_config_params();
  150. if(get->device_params == NULL)
  151. {
  152. sprintf(deviceId, "{\"find_device\":\"%s\"}", gatewayId);
  153. send(client_socket, deviceId, strlen(deviceId), 0);
  154. }
  155. else
  156. {
  157. sprintf(deviceId, "{\"find_device\":\"%s\"}", get->deviceId);
  158. send(client_socket, deviceId, strlen(deviceId), 0);
  159. }
  160. memset(deviceId, 0, 50);
  161. }
  162. // 发送设备当前的config数据
  163. void send_config(int client_socket)
  164. {
  165. GATEWAY_PARAMS *get;
  166. get= get_gateway_config_params();
  167. char* device_params = mymalloc(SRAMEX, 3 * 1024);
  168. memset(device_params,0,3 * 1024);
  169. if(get->device_params == NULL)
  170. {
  171. sprintf(device_params, "{\"read_config\":\"error\"}");
  172. send(client_socket, device_params, strlen(device_params), 0);
  173. }
  174. else
  175. {
  176. get_device_params(device_params);
  177. send(client_socket, device_params, strlen(device_params), 0);
  178. }
  179. myfree(SRAMEX, device_params);
  180. }
  181. // 解析上位机发送的ip_config数据
  182. void analysis_ip_config(int client_socket, int sockfd,struct sockaddr_in tcpServerSock, char* buf)
  183. {
  184. // 打开DHCP
  185. if (strstr(buf, "\"dhcpMode\":\"open\"") != NULL)
  186. {
  187. //#ifdef USE_DHCP
  188. DHCP_open();
  189. //#endif
  190. char* retMsg = mymalloc(SRAMEX,32);
  191. retMsg = "{\"ip_config\":\"success\"}";
  192. send(client_socket,retMsg,strlen(retMsg),0);
  193. myfree(SRAMEX, retMsg);
  194. }
  195. // 关闭DHCP
  196. else if (strstr(buf, "\"dhcpMode\":\"close\"") != NULL)
  197. {
  198. uint8_t prot[6];
  199. // 设置静态IP地址,并关闭DHCP
  200. set_ipaddr(buf);
  201. // 解析buf内的数据,保存到load_ip_config结构体
  202. parseStringField(buf, "\"ipv4\":\"", (char *)&load_ip_config.host);// eg:192.168.1.100
  203. parseStringField(buf, "\"subnetMask\":\"", (char *)&load_ip_config.subnetMask);// eg:255.255.255.0
  204. parseStringField(buf, "\"defaultGateway\":\"", (char *)&load_ip_config.defaultGateway);// eg:192.168.1.1
  205. parseStringField(buf, "\"udpLogPort\":\"", (char *)&prot);
  206. load_ip_config.udpLogPort = atoi((char *)&prot);
  207. // 关闭服务端和客户端
  208. lwip_close(sockfd);
  209. lwip_close(client_socket);
  210. // DHCP关闭标志位置 1
  211. closeFlag = 1;
  212. }
  213. }
  214. // 切换工作模式
  215. void work_mode(char* buf)
  216. {
  217. /* 用标志位开关data_task任务中,发送数据的方式 */
  218. // 内置协议模式
  219. if(strstr(buf,"protocolsMode") != NULL)
  220. {
  221. ProtocolsModeFlag = 1;// 开启内置协议模式
  222. TransparentModeFlag = 0; // 关闭透明传输模式
  223. LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"ProtocolsMode");
  224. }
  225. // 透明传输模式
  226. if(strstr(buf,"TransparentMode") != NULL)
  227. {
  228. ProtocolsModeFlag = 0;// 关闭内置协议模式
  229. TransparentModeFlag = 1; // 开启透明传输模式
  230. LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"TransparentModeFlag");
  231. }
  232. }
  233. #endif
  234. void tcp_server_task(void const * argument)
  235. {
  236. int ret,sockfd;
  237. int recv_size;
  238. struct sockaddr_in tcpServerSock;
  239. struct sockaddr_in client_sock;
  240. // 命令集
  241. char* recv_cmd[] = {"\"cmd\":\"write_config\"","\"cmd\":\"write_config_add\"",
  242. "\"cmd\":\"read_config\"","\"cmd\":\"find_device\"",
  243. "\"cmd\":\"ip_config\"","\"cmd\":\"toggle_work_mode\"",
  244. "\"cmd\":\"software_update\"","\"cmd\":\"reboot\""};
  245. #ifdef USE_DHCP
  246. while(dhcp_done!=1) {vTaskDelay(100);}
  247. #endif
  248. tcpServerSock.sin_family = AF_INET;
  249. inet_aton("192.168.0.3",&(tcpServerSock.sin_addr));
  250. // tcpServerSock.sin_addr.s_addr = htonl(IPADDR_ANY);
  251. tcpServerSock.sin_port = htons(8080);
  252. tcp_server_begin:
  253. sockfd = socket(AF_INET, SOCK_STREAM, 0);
  254. if (sockfd < 0)
  255. {
  256. goto tcp_server_begin;
  257. }
  258. ret = bind(sockfd, (struct sockaddr *)&tcpServerSock, sizeof(tcpServerSock));
  259. if (ret < 0)
  260. {
  261. lwip_close(sockfd);
  262. sockfd = -1;
  263. goto tcp_server_begin;
  264. }
  265. ret = listen(sockfd, 10);
  266. if (ret < 0)
  267. {
  268. lwip_close(sockfd);
  269. sockfd = -1;
  270. goto tcp_server_begin;
  271. }
  272. socklen_t len = sizeof(client_sock);
  273. int client_socket = accept(sockfd, (struct sockaddr*)&client_sock,&len);
  274. if (client_socket<0)
  275. {
  276. printf("error");
  277. }
  278. LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"PC connect success");
  279. while (1)
  280. {
  281. vTaskDelay(100);
  282. char *dataBuf= mymalloc(SRAMEX,RECV_BUF_SIZE);// 存储上位机下发数据
  283. memset(dataBuf,0,RECV_BUF_SIZE);
  284. // 获取上位机发送的数据
  285. recv_size=recv(client_socket,dataBuf,RECV_BUF_SIZE,0);
  286. // 接收到消息
  287. // 解析上位机发送的CMD命令
  288. if(recv_size>0)
  289. {
  290. int j = 0;
  291. for(int i = 0; i < sizeof(recv_cmd)/sizeof(recv_cmd[0]); i++)
  292. {
  293. if(strstr(dataBuf,recv_cmd[i]) != NULL)
  294. {
  295. i = sizeof(recv_cmd)/sizeof(recv_cmd[0]);
  296. }
  297. j++;
  298. }
  299. if (ProtocolsModeFlag) {
  300. switch (j) {
  301. case WRITE_CONFIG:
  302. LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "write config");
  303. save_config(client_socket, dataBuf);
  304. break;
  305. case WRITE_CONFIG_ADD:
  306. add_config(client_socket, dataBuf);
  307. LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "write config add");
  308. break;
  309. case READ_CONFIG:
  310. send_config(client_socket);
  311. LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "read config");
  312. break;
  313. case FIND_DEVICE:
  314. find_device(client_socket);
  315. LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "find device");
  316. break;
  317. case IP_CONFIG:
  318. LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "ipconfig");
  319. analysis_ip_config(client_socket, sockfd, tcpServerSock, dataBuf);
  320. if (closeFlag == 1) {
  321. // 更新新的地址
  322. inet_aton((char*)&load_ip_config.host, &(tcpServerSock.sin_addr));
  323. closeFlag = 0;
  324. goto tcp_server_begin;
  325. }
  326. break;
  327. case TOGGLE_MODE:
  328. work_mode(dataBuf);
  329. LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "toggle work mode");
  330. break;
  331. case UPDATE:
  332. LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "update");
  333. updata_task_creat(client_socket);
  334. break;
  335. case REBOOT:
  336. send(client_socket,"{\"reboot\":\"success\"}", 20, 0);
  337. LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "reboot");
  338. __set_PRIMASK(1);
  339. NVIC_SystemReset();
  340. break;
  341. }
  342. } else {
  343. switch (j) {
  344. case FIND_DEVICE:
  345. find_device(client_socket);
  346. LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "find device");
  347. break;
  348. case IP_CONFIG:
  349. LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "ip config");
  350. analysis_ip_config(client_socket, sockfd, tcpServerSock, dataBuf);
  351. if (closeFlag == 1) {
  352. // 更新新的地址
  353. inet_aton((char*)&load_ip_config.host, &(tcpServerSock.sin_addr));
  354. closeFlag = 0;
  355. goto tcp_server_begin;
  356. }
  357. break;
  358. case TOGGLE_MODE:
  359. work_mode(dataBuf);
  360. LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "toggle work mode");
  361. break;
  362. case UPDATE:
  363. LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "update");
  364. updata_task_creat(client_socket);
  365. break;
  366. case REBOOT:
  367. send(client_socket,"{\"reboot\":\"success\"}", 20, 0);
  368. LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "reboot");
  369. __set_PRIMASK(1);
  370. NVIC_SystemReset();
  371. break;
  372. }
  373. }
  374. }
  375. // 没接收到消息
  376. else if(recv_size==0)
  377. {
  378. lwip_close(client_socket);
  379. LOG_PRINT(LOG_ERROR,"PC disconnect,wait reconnect");
  380. client_socket= accept(sockfd, (struct sockaddr*)&client_sock,&len);
  381. }
  382. myfree(SRAMEX, dataBuf);
  383. }
  384. }
  385. /*!
  386. \brief initialize the tcp_client application
  387. \param[in] none
  388. \param[out] none
  389. \retval none
  390. */
  391. void tcp_server_init(void)
  392. {
  393. osThreadDef(SERVER, tcp_server_task, osPriorityNormal, 0, configMINIMAL_STACK_SIZE*8);
  394. osThreadCreate(osThread(SERVER), NULL);
  395. }