net_debug.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176
  1. /******************************************************************************
  2. 版权所有:
  3. 文件名称: net_debug.c
  4. 文件版本: 01.01
  5. 创建作者: sunxi
  6. 创建日期: 2012-11-07
  7. 功能说明: 网络调试接口
  8. 其它说明:
  9. 修改记录:
  10. */
  11. /*------------------------------- 头文件 --------------------------------------
  12. */
  13. #include "head.h"
  14. #ifdef LINUX_KERNEL_APP
  15. #include <linux/delay.h>
  16. #include <linux/syscalls.h>
  17. #include <linux/signal.h>
  18. #else
  19. #include <pthread.h>
  20. #include <sys/prctl.h>
  21. #endif
  22. /*------------------------------- 宏定义 --------------------------------------
  23. */
  24. /*------------------------------ 类型结构 -------------------------------------
  25. */
  26. /*------------------------------ 全局变量 -------------------------------------
  27. */
  28. #ifdef LINUX_KERNEL_APP
  29. static struct task_struct * g_ts_debug_send;
  30. static struct task_struct * g_ts_debug_recv;
  31. #else
  32. static pthread_t g_ts_debug_recv = 0;
  33. #endif
  34. SOCKET g_debug_client = RT_SOCKET_ERR;
  35. unsigned char g_net_debug_buf[NET_RECV_MAX]; // 以太网接收缓冲区
  36. int g_print_to_net;
  37. int g_print_time;
  38. int g_print_comm_raw;
  39. int g_print_101;
  40. int g_print_104;
  41. int g_print_lnk;
  42. int g_print_hmi;
  43. int g_print_can;
  44. int g_print_can_monitor;
  45. int g_print_sys;
  46. int g_print_dd;
  47. int g_print_goose;
  48. u32 g_print_port= -1; // 允许打印的串口通道,用位表示
  49. int g_test_on;
  50. extern struct semaphore g_print_sem;
  51. #ifdef LINUX_KERNEL_APP
  52. extern struct semaphore g_print_sem;
  53. static pid_t g_net_debug_thread_send_pid ;
  54. static pid_t g_net_debug_thread_recv_pid ;
  55. static int g_net_debug_send_exit_flag = 0;
  56. #endif
  57. static volatile int g_net_debug_sock_flag = NET_SOCKET_INIT;//关闭SOCKET标志
  58. static int g_net_debug_recv_exit_flag = 0;
  59. DEBUG_COMM g_tDebug; //定义下载串口结构
  60. /*------------------------------ 函数声明 -------------------------------------
  61. */
  62. void _net_debug_recv_reset(void);
  63. void _net_debug_print_reset(void);
  64. #ifdef LINUX_KERNEL_APP
  65. int _net_debug_thread_send(void * unused);
  66. #endif
  67. int _net_debug_thread_recv(void * unused);
  68. /*------------------------------ 外部函数 -------------------------------------
  69. 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
  70. */
  71. //设置socket关闭标志并等待socket关闭完成
  72. void net_debug_set_sock_closing(int no)
  73. {
  74. struct sockaddr_in local_addr;
  75. unsigned int len = sizeof(local_addr);
  76. RUN_PARA *pRunPara=&tRunPara;
  77. unsigned int ip=0;
  78. int bflag = 0;
  79. //如果有客户端连接
  80. if(g_debug_client != RT_SOCKET_ERR)
  81. {
  82. //获取客户端连接的IP
  83. rt_getsockname(g_debug_client, (struct sockaddr *)&local_addr, &len);
  84. #if 1
  85. if(pRunPara->tNetPara[no].old_index==0)
  86. {
  87. //获取网卡IP
  88. rt_if_ip_get(pRunPara->tNetPara[no].old_ethid, (unsigned char *)&ip);//sunxi: 20220825 335x
  89. }
  90. else
  91. {
  92. //获取虚拟网卡上的IP地址
  93. rt_if_ip_get2(pRunPara->tNetPara[no].old_ethid, pRunPara->tNetPara[no].old_index, (unsigned char *)&ip);//sunxi: 20220825 335x
  94. }
  95. //如果是该网卡的IP并且该网卡要修改IP或MASK,则需要通知关闭socket
  96. if((htonl (ip)==local_addr.sin_addr.s_addr) && pRunPara->tNetPara[no].bInit)//sunxi: 20220825 335x
  97. {
  98. bflag = 1;
  99. }
  100. #endif
  101. //该网卡的IP和MASK没有修改,则不需要通知关闭socket
  102. if(!bflag)
  103. {
  104. return;
  105. }
  106. g_net_debug_sock_flag = NET_SOCKET_CLOSING; //置关闭标志
  107. //等待关闭完成
  108. while(g_net_debug_sock_flag != NET_SOCKET_CLOSED)
  109. {
  110. msleep(20);
  111. }
  112. }
  113. }
  114. //设置socket重新创建标志
  115. void net_debug_set_sock_initflag(void)
  116. {
  117. if(g_net_debug_sock_flag == NET_SOCKET_CLOSED)
  118. {
  119. g_net_debug_sock_flag = NET_SOCKET_REINIT;
  120. }
  121. }
  122. //
  123. #ifdef LINUX_KERNEL_APP
  124. int net_debug_s_init(void)
  125. {
  126. struct sched_param sp;
  127. pid_t pid;
  128. #if 1
  129. // 如果已经初始化,退出
  130. if(g_ts_debug_send)
  131. {
  132. return 0;
  133. }
  134. // 运行应用调试线程
  135. //g_ts_debug_send = kthread_run(_net_debug_thread_send,NULL,"net_debug_send");
  136. pid = kernel_thread(_net_debug_thread_send, NULL,CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
  137. g_ts_debug_send = find_task_by_vpid(pid);
  138. if(IS_ERR(g_ts_debug_send))
  139. {
  140. printk("ts=%p\r\n",g_ts_debug_send);
  141. g_ts_debug_send = NULL;
  142. return -1;
  143. }
  144. g_net_debug_thread_send_pid = pid;
  145. memset(&sp,0,sizeof(sp));
  146. sp.sched_priority = 8;
  147. sched_setscheduler(g_ts_debug_send,SCHED_FIFO,&sp);
  148. // 设置进程名字
  149. set_task_comm(g_ts_debug_send, "net_debug_send");
  150. #endif
  151. return 0;
  152. }
  153. #else
  154. int net_debug_s_init(void)
  155. {
  156. return 0;
  157. }
  158. #endif
  159. #ifdef LINUX_KERNEL_APP
  160. int net_debug_s_exit(void)
  161. {
  162. int status;
  163. if(g_ts_debug_send != NULL)
  164. {
  165. up(&g_print_sem);
  166. g_net_debug_send_exit_flag = 1;
  167. sys_wait4(g_net_debug_thread_send_pid, (int __user *)&status, 0, NULL);
  168. g_ts_debug_send = NULL;
  169. }
  170. return 0;
  171. }
  172. #else
  173. int net_debug_s_exit(void)
  174. {
  175. return 0;
  176. }
  177. #endif
  178. // TODO: 需要确认是否需要重新初始化
  179. int net_debug_init(void)
  180. {
  181. int ret;
  182. pthread_attr_t attr;
  183. //attr.__schedpolicy = SCHED_FIFO;
  184. //attr.__schedparam.sched_priority =8;
  185. // 设置调度策略和优先级
  186. pthread_attr_init(&attr);
  187. pthread_attr_setschedpolicy(&attr, SCHED_FIFO); //调度
  188. struct sched_param s_parm;
  189. //s_parm.sched_priority = sched_get_priority_max(SCHED_FIFO);
  190. s_parm.sched_priority = 8;
  191. pthread_attr_setschedparam(&attr, &s_parm); //优先级
  192. ret = pthread_create(&g_ts_debug_recv, &attr, (void *)_net_debug_thread_recv, NULL);
  193. if(!ret)
  194. {
  195. rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret));
  196. //g_ts_rcd = 0;
  197. return ret;
  198. }
  199. return 0;
  200. }
  201. #ifdef LINUX_KERNEL_APP
  202. int net_debug_exit(void)
  203. {
  204. int status;
  205. #if 0
  206. if(g_ts_debug_send != NULL)
  207. {
  208. up(&g_print_sem);
  209. g_net_debug_send_exit_flag = 1;
  210. sys_wait4(g_net_debug_thread_send_pid, (int __user *)&status, 0, NULL);
  211. g_ts_debug_send = NULL;
  212. }
  213. #endif
  214. if(g_ts_debug_recv != NULL)
  215. {
  216. g_net_debug_recv_exit_flag = 1;
  217. sys_wait4(g_net_debug_thread_recv_pid, (int __user *)&status, 0, NULL);
  218. g_ts_debug_recv = NULL;
  219. }
  220. return 0;
  221. }
  222. #else
  223. int net_debug_exit(void)
  224. {
  225. if(g_ts_debug_recv)
  226. {
  227. g_net_debug_recv_exit_flag = 1;
  228. // sys_wait4(g_net_debug_thread_recv_pid, (int __user *)&status, 0, NULL);
  229. pthread_join(g_ts_debug_recv, NULL);
  230. g_ts_debug_recv = 0;
  231. }
  232. return 0;
  233. }
  234. #endif
  235. // 此函数必须在线程中调用,不能在中断中调用。
  236. int net_debug_send(unsigned char *buf,int len)
  237. {
  238. if(g_debug_client == RT_SOCKET_ERR)
  239. {
  240. return 0;
  241. }
  242. return rt_send(g_debug_client,buf,len,0);
  243. }
  244. #ifdef METERING_ENERGY
  245. const char main_Debug[]=
  246. "\r\n*********装置调试菜单*******\r\n \
  247. 0:通讯原始数据监视[通道可选]\r\n \
  248. 1:101报文监视[通道可选]\r\n \
  249. 2:104报文监视[通道可选]\r\n \
  250. 3:CAN报文监视\r\n \
  251. 4:系统信息监视\r\n \
  252. 5:报文时标开启\r\n \
  253. 6:关闭所有监视\r\n \
  254. 7:面板报文监视\r\n \
  255. 8:CAN总线监视\r\n \
  256. A:载入默认公钥\r\n \
  257. B:加密测试\r\n \
  258. C:SOE测试\r\n \
  259. D:重启系统\r\n \
  260. E:打印点表\r\n \
  261. F: 级联报文监视[通道可选]\r\n \
  262. G:goose报文监视\r\n \
  263. H:文件召唤测试\r\n \
  264. I:程序升级测试\r\n \
  265. J:打印终端固有参数\r\n \
  266. K:新生成soe.xml文件\r\n \
  267. L:新生成co.xml文件\r\n \
  268. M:清零电压合格率\r\n \
  269. N:清零脉冲计数值\r\n \
  270. P:61850信息打印\r\n \
  271. Q:生成菜单显示文件\r\n \
  272. R:生成icd文件\r\n \
  273. S:计量板校准\r\n \
  274. T:计量电能清零\r\n \
  275. U:CAN子板ID打印\r\n \
  276. 其它:关闭所有监视信息\r\n \
  277. \r\n>:";
  278. #else
  279. const char main_Debug[]=
  280. "\r\n*********装置调试菜单*******\r\n \
  281. 0:通讯原始数据监视[通道可选]\r\n \
  282. 1:101报文监视[通道可选]\r\n \
  283. 2:104报文监视[通道可选]\r\n \
  284. 3:CAN报文监视\r\n \
  285. 4:系统信息监视\r\n \
  286. 5:报文时标开启\r\n \
  287. 6:关闭所有监视\r\n \
  288. 7:面板报文监视\r\n \
  289. 8:CAN总线监视\r\n \
  290. A:载入默认公钥\r\n \
  291. B:加密测试\r\n \
  292. C:SOE测试\r\n \
  293. D:重启系统\r\n \
  294. E:打印点表\r\n \
  295. F: 级联报文监视[通道可选]\r\n \
  296. G:goose报文监视\r\n \
  297. H:文件召唤测试\r\n \
  298. I:程序升级测试\r\n \
  299. J:打印终端固有参数\r\n \
  300. K:新生成soe.xml文件\r\n \
  301. L:新生成co.xml文件\r\n \
  302. M:清零电压合格率\r\n \
  303. N:清零脉冲计数值\r\n \
  304. P:61850信息打印\r\n \
  305. Q:生成菜单显示文件\r\n \
  306. R:生成icd文件\r\n \
  307. r:查看实时线程状态\r\n \
  308. s:复位实时线程状态\r\n \
  309. S:ADC采样状态\r\n \
  310. 其它:关闭所有监视信息\r\n \
  311. \r\n>:";
  312. #endif
  313. BYTE arrApn[48];
  314. extern int g_soe_test;
  315. int _net_debug_get_chn(void)
  316. {
  317. int chn;
  318. if(g_tDebug.cRecvCnt >= 3)
  319. {
  320. chn = g_tDebug.arrRecvBuf[2] - '0';
  321. if(chn >=0 && chn < COMM_CHANNEL_NUM)
  322. {
  323. g_print_port = 1<<chn;
  324. return chn;
  325. }
  326. }
  327. return -1;
  328. }
  329. extern int dt_cmd_rt(void);
  330. extern int dt_cmd_adc(void);
  331. extern int dt_cmd_rt_reset(void);
  332. void net_debug_app(void)
  333. {
  334. u8 ch;
  335. int chn;
  336. int ret=-1;
  337. #ifdef CAN_SLAVE_BOARD
  338. static bool sb_metering=false;
  339. #endif
  340. if(!g_tDebug.bData)
  341. return;
  342. g_tDebug.bData=false;
  343. //超级终端处理
  344. ch=g_tDebug.arrRecvBuf[g_tDebug.cRecvCnt-1];
  345. if(ch!=0x0d) // 回车键
  346. {
  347. _net_debug_recv_reset();
  348. return;
  349. }
  350. // 前7个和维护工具配合使用,不可改变
  351. switch(g_tDebug.arrRecvBuf[0])
  352. {
  353. case '0':
  354. g_print_comm_raw = 1;
  355. g_print_to_net = 1;
  356. chn = _net_debug_get_chn();
  357. rt_printf("\r\n打开串口原始数据监视[chn=%d]:\r\n",chn);
  358. break;
  359. case '1':
  360. g_print_101 = 1;
  361. g_print_to_net = 1;
  362. chn = _net_debug_get_chn();
  363. rt_printf("\r\n打开101报文监视[chn=%d]:\r\n",chn);
  364. break;
  365. case '2':
  366. g_print_104 = 1;
  367. g_print_to_net = 1;
  368. chn = _net_debug_get_chn();
  369. rt_printf("\r\n打开104报文监视[chn=%d]:\r\n",chn);
  370. break;
  371. case '3':
  372. g_print_can = 1;
  373. g_print_to_net = 1;
  374. rt_printf("\r\n打开CAN报文监视:\r\n");
  375. break;
  376. case '4':
  377. g_print_sys = 1;
  378. g_print_to_net = 1;
  379. rt_printf("\r\n打开系统监视:\r\n");
  380. break;
  381. case '5':
  382. g_print_time = 1;
  383. rt_printf("\r\n报文时标开启:\r\n");
  384. break;
  385. case '6':
  386. g_print_to_net = 1;
  387. g_print_port = -1;
  388. rt_printf("\r\n所有报文监视关闭:\r\n");
  389. _net_debug_print_reset();
  390. break;
  391. case '7':
  392. g_print_hmi = 1;
  393. g_print_to_net = 1;
  394. rt_printf("\r\n打开面板报文监视:\r\n");
  395. break;
  396. case '8':
  397. g_print_can_monitor= 1;
  398. g_print_to_net = 1;
  399. break;
  400. case 'A':
  401. case 'a':
  402. g_print_to_net = 1;
  403. #ifdef ENCRYPT_SM2
  404. InitSM2Key();
  405. rt_printf("\r\n公钥保存成功\r\n");
  406. #else
  407. rt_printf("\r\n不支持SM2加密\r\n");
  408. #endif
  409. break;
  410. case 'B':
  411. case 'b':
  412. g_print_sys = 1;
  413. g_print_to_net = 1;
  414. #ifdef ENCRYPT_SM2
  415. encrypt_test();
  416. #else
  417. rt_printf("\r\n不支持SM2加密\r\n");
  418. #endif
  419. break;
  420. case 'C':
  421. case 'c':
  422. g_print_to_net = 1;
  423. g_soe_test = 1;
  424. break;
  425. case 'D':
  426. case 'd':
  427. g_print_to_net = 1;
  428. rt_printf("\r\n系统重新启动\r\n");
  429. Delayms(dTCounter,T_1s);
  430. watchdog_reset_cpu(4);
  431. break;
  432. case 'E':
  433. case 'e':
  434. g_print_to_net = 1;
  435. tbl_printf_cvs();
  436. break;
  437. case 'f':
  438. case 'F':
  439. g_print_lnk = 1;
  440. g_print_to_net = 1;
  441. chn = _net_debug_get_chn();
  442. rt_printf("\r\n打开级联报文监视[chn=%d]:\r\n",chn);
  443. break;
  444. case 'J':
  445. case 'j':
  446. {
  447. extern void iec_printfihertset(void);
  448. g_print_to_net = 1;
  449. rt_printf("\r\n-----配电终端固有参数-----------\r\n");
  450. iec_printfixedset();
  451. g_print_dd = 1;
  452. }
  453. break;
  454. case 'h':
  455. case 'H':
  456. {
  457. g_print_to_net = 1;
  458. g_print_lnk = 1;
  459. lnk_read_test_file();
  460. }
  461. break;
  462. case 'i':
  463. case 'I':
  464. {
  465. g_print_to_net = 1;
  466. g_print_lnk = 1;
  467. lnk_write_test_file();
  468. }
  469. case 'G':
  470. case 'g':
  471. g_print_goose= 1;
  472. g_print_to_net = 1;
  473. g_print_port = -1;
  474. //_net_debug_get_chn();
  475. rt_printf("\r\n打开goose报文监视:\r\n");
  476. break;
  477. case 'k':
  478. case 'K':
  479. g_print_to_net = 1;
  480. ret = del_history_file(HS_FILE_SOE);
  481. if(!ret)
  482. {
  483. ret = create_event_rcd_file(HS_FILE_SOE);
  484. }
  485. if(!ret)
  486. {
  487. rt_printf("新生成soe.msg文件成功\r\n");
  488. }
  489. else
  490. {
  491. rt_printf("新生成soe.msg文件失败\r\n");
  492. }
  493. break;
  494. case 'l':
  495. case 'L':
  496. g_print_to_net = 1;
  497. ret = del_history_file(HS_FILE_CO);
  498. if(!ret)
  499. {
  500. ret = create_event_rcd_file(HS_FILE_CO);
  501. }
  502. if(!ret)
  503. {
  504. rt_printf("新生成co.msg文件成功\r\n");
  505. }
  506. else
  507. {
  508. rt_printf("新生成co.msg文件失败\r\n");
  509. }
  510. break;
  511. case 'M':
  512. case 'm':
  513. g_print_to_net = 1;
  514. SaveUqua(true);
  515. rt_printf("\r\n电压合格率清零\r\n");
  516. break;
  517. case 'N':
  518. case 'n':
  519. g_print_to_net = 1;
  520. {
  521. int sw;
  522. for(sw=0;sw<SWITCH_NUM_MAX;sw++)
  523. {
  524. g_sw[sw].ac_in[SW_AC_IN_IMP1]=0;
  525. g_sw[sw].ac_in[SW_AC_IN_IMP2]=0;
  526. }
  527. }
  528. rt_printf("\r\n脉冲计数率清零\r\n");
  529. break;
  530. case 'P':
  531. case 'p':
  532. {
  533. void app_goose_inf_print(void);
  534. g_print_to_net = 1;
  535. #ifdef __IEC61850_GOOSE_FUNC__
  536. app_goose_inf_print();
  537. #endif
  538. }
  539. break;
  540. case 'Q':
  541. case 'q':
  542. {
  543. // void mmd_create_menufile(void);
  544. g_print_to_net = 1;
  545. // mmd_create_menufile();
  546. // rt_printf("\r\n/app/data/lcd_menu.csv 菜单定义文件已生成\r\n");
  547. }
  548. break;
  549. case 'r':
  550. {
  551. g_print_to_net = 1;
  552. dt_cmd_rt();
  553. }
  554. break;
  555. case 'S':
  556. {
  557. g_print_to_net = 1;
  558. dt_cmd_adc();
  559. }
  560. break;
  561. case 's':
  562. {
  563. g_print_to_net = 1;
  564. dt_cmd_rt_reset();
  565. }
  566. break;
  567. #ifdef CAN_SLAVE_BOARD
  568. case 'R':
  569. case 'r':
  570. {
  571. g_print_to_net = 1;
  572. can_id_printf();
  573. }
  574. break;
  575. case 'S':
  576. case 's':
  577. {
  578. sb_metering = true;
  579. g_print_to_net = 1;
  580. can_metering_calib(g_tDebug.arrRecvBuf);
  581. }
  582. break;
  583. case 'T':
  584. case 't':
  585. {
  586. g_print_to_net = 1;
  587. can_app_energy_clear(0, get_can_slot(0));
  588. }
  589. break;
  590. case 'U':
  591. case 'u':
  592. {
  593. g_print_to_net = 1;
  594. can_id_printf();
  595. }
  596. break;
  597. #endif
  598. default:
  599. #ifdef CAN_SLAVE_BOARD
  600. ret = 0;
  601. g_print_to_net = 1;
  602. if(sb_metering)
  603. {
  604. ret = can_metering_calib(g_tDebug.arrRecvBuf);
  605. }
  606. if(!ret)
  607. #endif
  608. {
  609. _net_debug_print_reset();
  610. net_debug_send((unsigned char *)main_Debug,sizeof(main_Debug));
  611. g_print_sys=false;
  612. }
  613. break;
  614. }
  615. _net_debug_recv_reset();
  616. }
  617. void print_mem_net(char *addr,unsigned char *pd,int lenth)
  618. {
  619. BYTE i,j;
  620. char buf[128],tempstr[8];
  621. if(addr!=NULL)
  622. {
  623. sprintf(buf,"%s",addr);
  624. rt_printf(buf);
  625. }
  626. strcpy(buf,"");
  627. for(i=0,j=0;i<lenth;i++)
  628. {
  629. sprintf(tempstr,"%02X ",*pd++);
  630. strcat(buf,tempstr);
  631. j++;
  632. if(j>18)
  633. {
  634. rt_printf(buf);
  635. strcpy(buf,"\r\n ");
  636. j=0;
  637. }
  638. }
  639. if(j>0)
  640. {
  641. rt_printf(buf);
  642. }
  643. rt_printf("\r\n");
  644. }
  645. /*------------------------------ 内部函数 -------------------------------------
  646. 内部函数以下划线‘_’开头,不需要检查参数的合法性.
  647. */
  648. void _net_debug_recv_reset(void)
  649. {
  650. g_tDebug.cTypeCounter=0;
  651. g_tDebug.cRecvCnt=0;
  652. }
  653. void _net_debug_print_reset(void)
  654. {
  655. g_print_to_net = 0;
  656. g_print_time = 0;
  657. g_print_101 = 0;
  658. g_print_104 = 0;
  659. g_print_lnk = 0;
  660. g_print_hmi = 0;
  661. g_print_can = 0;
  662. g_print_can_monitor= 0;
  663. g_print_sys = 0;
  664. g_print_dd = 0;
  665. g_print_comm_raw = 0;
  666. g_print_port = -1;
  667. g_test_on = 0;
  668. g_print_goose=0;
  669. }
  670. void _net_debug_recv(BYTE cRcvData)
  671. {
  672. if(g_tDebug.bData)
  673. {
  674. return;
  675. }
  676. //xshell 发送的保活状态消息
  677. if(cRcvData == 0xff || cRcvData == 0xf1)
  678. {
  679. return;
  680. }
  681. //rt_printf("cRcvData=%02x\r\n",cRcvData);
  682. g_tDebug.arrRecvBuf[g_tDebug.cRecvCnt++]=cRcvData;
  683. if(cRcvData == 0x0d)
  684. {
  685. g_tDebug.bData=true;
  686. }
  687. if(g_tDebug.cRecvCnt >= UART_FRAME_LEN)
  688. {
  689. _net_debug_recv_reset();
  690. return;
  691. }
  692. return;
  693. }
  694. #ifdef LINUX_KERNEL_APP
  695. int _net_debug_thread_send(void * unused)
  696. {
  697. while(1)
  698. {
  699. msleep(100);
  700. // 检查是否退出
  701. if(g_net_debug_send_exit_flag)
  702. {
  703. g_net_debug_send_exit_flag = 0;
  704. return 0;
  705. }
  706. //noted by sunxi: 20220701 统一冷火和335x,有信号量,才往下执行
  707. if(down_interruptible(&g_print_sem)<0)
  708. {
  709. continue;
  710. }
  711. rt_printf_fifo_get(1);
  712. }
  713. return 0;
  714. }
  715. #endif
  716. /*
  717. noted by sunxi:20220825 335x 修复 6000端口超时或断开后,不能重连的问题
  718. */
  719. int _net_debug_thread_recv(void * unused)
  720. {
  721. struct sockaddr_in server_addr;
  722. struct sockaddr_in client_addr;
  723. struct linger ling;
  724. #ifndef LINUX_KERNEL_APP
  725. struct timeval timeout;
  726. #endif
  727. SOCKET sk_server,tmp_sock;
  728. int sin_size;
  729. int i,len,ret;
  730. unsigned char *ip;
  731. #ifdef LINUX_KERNEL_APP
  732. unsigned int recv_timeout;
  733. unsigned int link_timeout = dTCounter;
  734. #else
  735. int recv_timeout;
  736. int link_timeout = 0;
  737. #endif
  738. unsigned int ip_server;
  739. // while(1) //noted by sunxi:20220825 335x 修复 6000端口超时或断开后,不能重连的问题
  740. // {
  741. NET_BEGIN:
  742. // 1、建立socket并侦听
  743. // 服务器端开始建立socket描述符
  744. #ifdef LINUX_KERNEL_APP
  745. sk_server = rt_socket(AF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0);
  746. #else
  747. sk_server = rt_socket(AF_INET, SOCK_STREAM, 0);
  748. #endif
  749. if (sk_server == RT_SOCKET_ERR)
  750. {
  751. RT_PRINTF_POSITION();
  752. g_ts_debug_recv = NULL;
  753. return -1;
  754. }
  755. // 服务器端填充sockaddr结构
  756. memset (&server_addr, 0, sizeof (struct sockaddr_in));
  757. server_addr.sin_family = AF_INET;
  758. if(get_mt_port_proc()==NET_MT_PORT_PROC_2)
  759. {
  760. if(rt_if_ip_get2(0, 3, (unsigned char *)&ip_server)==0)
  761. {
  762. server_addr.sin_addr.s_addr = htonl (ip_server);
  763. }
  764. else
  765. {
  766. server_addr.sin_addr.s_addr = htonl (INADDR_ANY);
  767. }
  768. }
  769. else
  770. {
  771. server_addr.sin_addr.s_addr = htonl (INADDR_ANY);
  772. }
  773. server_addr.sin_port = htons (NET_DEBUG_PORT);
  774. // 捆绑sockfd描述符
  775. ret = rt_bind (sk_server, (struct sockaddr *)(&server_addr), sizeof (struct sockaddr));
  776. if (ret < 0)
  777. {
  778. RT_PRINTF_POSITION();
  779. rt_socket_close (sk_server);
  780. g_ts_debug_recv = NULL;
  781. return -2;
  782. }
  783. // 监听sockfd描述符
  784. ret = rt_listen (sk_server, 1);
  785. if (ret < 0)
  786. {
  787. RT_PRINTF_POSITION();
  788. rt_socket_close (sk_server);
  789. g_ts_debug_recv = NULL;
  790. return -3;
  791. }
  792. #ifndef LINUX_KERNEL_APP
  793. // 设置接收超时
  794. timeout.tv_sec = 0;
  795. timeout.tv_usec = 500000;
  796. rt_setsockopt(sk_server,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout ,sizeof(struct timeval));
  797. #endif
  798. // 设置关闭延时
  799. ling.l_onoff = 1;
  800. ling.l_linger = 0;
  801. rt_setsockopt(sk_server,SOL_SOCKET,SO_LINGER,(char *)&ling ,sizeof(struct linger));
  802. prctl(PR_SET_NAME, "_net_debug_recv");
  803. while(1) //noted by sunxi:20220825 335x 修复 6000端口超时或断开后,不能重连的问题
  804. {
  805. g_debug_client = RT_SOCKET_ACCEPT_RST;
  806. // 2、接受外部链接
  807. #ifdef RT_SOCKET_FD
  808. while(g_debug_client < 0)
  809. #else
  810. while(g_debug_client == RT_SOCKET_ACCEPT_RST)
  811. #endif
  812. {
  813. msleep(100);
  814. // 服务器阻塞,直到客户程序建立连接
  815. sin_size = sizeof (struct sockaddr_in);
  816. g_debug_client = rt_accept (sk_server, (struct sockaddr*)(&client_addr), &sin_size);
  817. // 检查是否退出
  818. //if(kthread_should_stop())
  819. if(g_net_debug_recv_exit_flag)
  820. {
  821. // 关闭客户端
  822. if(g_debug_client != RT_SOCKET_ERR)
  823. {
  824. tmp_sock = g_debug_client;
  825. g_debug_client = RT_SOCKET_ERR;
  826. rt_socket_close (tmp_sock);
  827. }
  828. // 关闭服务器
  829. rt_socket_close (sk_server);
  830. g_net_debug_recv_exit_flag= 0;
  831. return 0;
  832. }
  833. //IP已经修改要关闭SOCKET
  834. if(g_net_debug_sock_flag == NET_SOCKET_CLOSING)
  835. {
  836. // 关闭客户端
  837. if(g_debug_client != RT_SOCKET_ERR)
  838. {
  839. tmp_sock = g_debug_client;
  840. g_debug_client = RT_SOCKET_ERR;
  841. rt_socket_close (tmp_sock);
  842. }
  843. // 关闭服务器
  844. rt_socket_close (sk_server);
  845. //置已经关闭标志
  846. g_net_debug_sock_flag = NET_SOCKET_CLOSED;
  847. //等待IP修改完成
  848. while(g_net_debug_sock_flag != NET_SOCKET_REINIT)
  849. {
  850. msleep(100);
  851. }
  852. //置为初始化
  853. g_net_debug_sock_flag = NET_SOCKET_INIT;
  854. goto NET_BEGIN;
  855. }
  856. }
  857. // 3、关闭侦听socket,避免多个外部连接
  858. //rt_shutdown(sk_server, SHUT_RDWR);
  859. //rt_socket_close(sk_server); //noted by sunxi:20220825 335x 修复 6000端口超时或断开后,不能重连的问题
  860. ip = (unsigned char *)&client_addr.sin_addr.s_addr;
  861. rt_printf("debug client connect(ip=%d.%d.%d.%d)!\r\n",ip[0],ip[1],ip[2],ip[3]);
  862. {
  863. char buf[64];
  864. char log_info[128];
  865. sprintf(buf,"6000端口连接(%d#网络:IP=%d.%d.%d.%d)!\r\n", set_get_network_id_from_socket(g_debug_client)+1, ip[0],ip[1],ip[2],ip[3]);
  866. log_str_time(LOG_OPERATE,buf,0,1);
  867. sprintf(log_info,"6000 port connection(%d#net:IP=%d.%d.%d.%d)",set_get_network_id_from_socket(g_debug_client)+1, ip[0],ip[1],ip[2],ip[3]);
  868. load_hs_log_rcd(TYPE_CHNL_LINK,true,NULL,log_info,1);
  869. }
  870. // 4、客户端已连接,处理客户端命令
  871. #ifdef LINUX_KERNEL_APP
  872. recv_timeout=dTCounter;
  873. #else
  874. recv_timeout=0;
  875. #endif
  876. while(1)
  877. {
  878. #ifdef LINUX_KERNEL_APP
  879. msleep(2);//noted by sunxi: 20221212 设为非阻塞型
  880. len = rt_recv (g_debug_client, g_net_debug_buf, NET_RECV_MAX, MSG_DONTWAIT);
  881. #else
  882. len = rt_recv (g_debug_client, g_net_debug_buf, NET_RECV_MAX, 0);
  883. #endif
  884. // 检查是否退出
  885. if(g_net_debug_recv_exit_flag)
  886. {
  887. // 关闭客户端
  888. tmp_sock = g_debug_client;
  889. g_debug_client = RT_SOCKET_ERR;
  890. rt_socket_close (tmp_sock);
  891. // 关闭服务器
  892. rt_socket_close (sk_server); //noted by sunxi:20220825 335x 修复 6000端口超时或断开后,不能重连的问题
  893. g_net_debug_recv_exit_flag = 0;
  894. return 0;
  895. }
  896. //IP已经修改要关闭SOCKET
  897. if(g_net_debug_sock_flag == NET_SOCKET_CLOSING)
  898. {
  899. // 关闭客户端
  900. tmp_sock = g_debug_client;
  901. g_debug_client = RT_SOCKET_ERR;
  902. rt_socket_close (tmp_sock);
  903. // 关闭服务器
  904. rt_socket_close (sk_server); //noted by sunxi:20220825 335x 修复 6000端口超时或断开后,不能重连的问题
  905. //置已经关闭标志
  906. g_net_debug_sock_flag = NET_SOCKET_CLOSED;
  907. //等待IP修改完成
  908. while(g_net_debug_sock_flag != NET_SOCKET_REINIT)
  909. {
  910. msleep(100);
  911. }
  912. //置为初始化
  913. g_net_debug_sock_flag = NET_SOCKET_INIT;
  914. goto NET_BEGIN;
  915. }
  916. #ifdef LINUX_KERNEL_APP
  917. if(len == -EAGAIN)
  918. #else
  919. if((len == -EAGAIN)||(len==-1))//使用linux的recvfrom没有接收到数据时返回-1 jack.liu 20200916
  920. #endif
  921. {
  922. if(rt_get_net_linkstatus(rt_get_netcard_id_from_socket(g_debug_client))==1)
  923. {
  924. #ifdef LINUX_KERNEL_APP
  925. if((dTCounter - link_timeout)>RT_LINK_TIMEOUT*T_1s) //500ms超时
  926. #else
  927. link_timeout++;
  928. if(link_timeout>RT_LINK_TIMEOUT*2) //500ms超时
  929. #endif
  930. {
  931. rt_printf("%s: link down\n",__FUNCTION__);
  932. #ifdef LINUX_KERNEL_APP
  933. link_timeout = dTCounter;
  934. #else
  935. link_timeout = 0;
  936. #endif
  937. break;
  938. }
  939. }
  940. else
  941. {
  942. #ifdef LINUX_KERNEL_APP
  943. link_timeout = dTCounter;
  944. #else
  945. link_timeout = 0;
  946. #endif
  947. }
  948. // 超时
  949. #ifdef LINUX_KERNEL_APP
  950. if((dTCounter - recv_timeout)>120*T_1s) // 超时2分钟,端口未收到数据,关闭端口
  951. #else
  952. recv_timeout++;
  953. if(recv_timeout>240) // 超时2分钟,端口未收到数据,关闭端口
  954. #endif
  955. {
  956. rt_printf ("net_debug_thread:timeout\r\n");
  957. break;
  958. }
  959. continue;
  960. }
  961. #ifdef LINUX_KERNEL_APP
  962. else if (len <= 0)
  963. #else
  964. else if ((len == 0)||(len<-1)) //使用linux的recvfrom没有接收到数据时返回-1 jack.liu 20200916
  965. #endif
  966. {
  967. //调用recv时,如果返回0,则表示对端关闭;返回负数,表示出错
  968. rt_printf ("net_debug_thread:peer close(ret=%d).\r\n",len);
  969. msleep(100);
  970. break;
  971. }
  972. // 接收数据
  973. #ifdef LINUX_KERNEL_APP
  974. recv_timeout = dTCounter;
  975. link_timeout = dTCounter;
  976. #else
  977. recv_timeout = 0;
  978. link_timeout = 0;
  979. #endif
  980. for(i=0;i<len;i++)
  981. {
  982. _net_debug_recv(g_net_debug_buf[i]);
  983. }
  984. g_tDebug.bNet=true;
  985. }
  986. // 复位调试打印信息
  987. _net_debug_print_reset();
  988. // 关闭客户端socket
  989. tmp_sock = g_debug_client;
  990. g_debug_client = RT_SOCKET_ERR;
  991. {
  992. char buf[64];
  993. sprintf(buf,"6000端口关闭(%d#网络:IP=%d.%d.%d.%d)!\r\n", set_get_network_id_from_socket(tmp_sock)+1,ip[0],ip[1],ip[2],ip[3]);
  994. log_str_time(LOG_OPERATE,buf,0,0);
  995. load_hs_log_rcd(TYPE_CHNL_LINK,true,NULL,"6000 port disconnection",0);
  996. }
  997. rt_socket_close (tmp_sock);
  998. }
  999. // 理论上,程序不会运行到这儿
  1000. return 0;
  1001. }
  1002. /*------------------------------ 测试函数 -------------------------------------
  1003. 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
  1004. 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
  1005. */
  1006. /*------------------------------ 文件结束 -------------------------------------
  1007. */