tcp_server.c 14 KB

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