net_debug.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167
  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. 其它:关闭所有监视信息\r\n \
  310. \r\n>:";
  311. #endif
  312. BYTE arrApn[48];
  313. extern int g_soe_test;
  314. int _net_debug_get_chn(void)
  315. {
  316. int chn;
  317. if(g_tDebug.cRecvCnt >= 3)
  318. {
  319. chn = g_tDebug.arrRecvBuf[2] - '0';
  320. if(chn >=0 && chn < COMM_CHANNEL_NUM)
  321. {
  322. g_print_port = 1<<chn;
  323. return chn;
  324. }
  325. }
  326. return -1;
  327. }
  328. extern int dt_cmd_rt(void);
  329. extern int dt_cmd_rt_reset(void);
  330. void net_debug_app(void)
  331. {
  332. u8 ch;
  333. int chn;
  334. int ret=-1;
  335. #ifdef CAN_SLAVE_BOARD
  336. static bool sb_metering=false;
  337. #endif
  338. if(!g_tDebug.bData)
  339. return;
  340. g_tDebug.bData=false;
  341. //超级终端处理
  342. ch=g_tDebug.arrRecvBuf[g_tDebug.cRecvCnt-1];
  343. if(ch!=0x0d) // 回车键
  344. {
  345. _net_debug_recv_reset();
  346. return;
  347. }
  348. // 前7个和维护工具配合使用,不可改变
  349. switch(g_tDebug.arrRecvBuf[0])
  350. {
  351. case '0':
  352. g_print_comm_raw = 1;
  353. g_print_to_net = 1;
  354. chn = _net_debug_get_chn();
  355. rt_printf("\r\n打开串口原始数据监视[chn=%d]:\r\n",chn);
  356. break;
  357. case '1':
  358. g_print_101 = 1;
  359. g_print_to_net = 1;
  360. chn = _net_debug_get_chn();
  361. rt_printf("\r\n打开101报文监视[chn=%d]:\r\n",chn);
  362. break;
  363. case '2':
  364. g_print_104 = 1;
  365. g_print_to_net = 1;
  366. chn = _net_debug_get_chn();
  367. rt_printf("\r\n打开104报文监视[chn=%d]:\r\n",chn);
  368. break;
  369. case '3':
  370. g_print_can = 1;
  371. g_print_to_net = 1;
  372. rt_printf("\r\n打开CAN报文监视:\r\n");
  373. break;
  374. case '4':
  375. g_print_sys = 1;
  376. g_print_to_net = 1;
  377. rt_printf("\r\n打开系统监视:\r\n");
  378. break;
  379. case '5':
  380. g_print_time = 1;
  381. rt_printf("\r\n报文时标开启:\r\n");
  382. break;
  383. case '6':
  384. g_print_to_net = 1;
  385. g_print_port = -1;
  386. rt_printf("\r\n所有报文监视关闭:\r\n");
  387. _net_debug_print_reset();
  388. break;
  389. case '7':
  390. g_print_hmi = 1;
  391. g_print_to_net = 1;
  392. rt_printf("\r\n打开面板报文监视:\r\n");
  393. break;
  394. case '8':
  395. g_print_can_monitor= 1;
  396. g_print_to_net = 1;
  397. break;
  398. case 'A':
  399. case 'a':
  400. g_print_to_net = 1;
  401. #ifdef ENCRYPT_SM2
  402. InitSM2Key();
  403. rt_printf("\r\n公钥保存成功\r\n");
  404. #else
  405. rt_printf("\r\n不支持SM2加密\r\n");
  406. #endif
  407. break;
  408. case 'B':
  409. case 'b':
  410. g_print_sys = 1;
  411. g_print_to_net = 1;
  412. #ifdef ENCRYPT_SM2
  413. encrypt_test();
  414. #else
  415. rt_printf("\r\n不支持SM2加密\r\n");
  416. #endif
  417. break;
  418. case 'C':
  419. case 'c':
  420. g_print_to_net = 1;
  421. g_soe_test = 1;
  422. break;
  423. case 'D':
  424. case 'd':
  425. g_print_to_net = 1;
  426. rt_printf("\r\n系统重新启动\r\n");
  427. Delayms(dTCounter,T_1s);
  428. watchdog_reset_cpu(4);
  429. break;
  430. case 'E':
  431. case 'e':
  432. g_print_to_net = 1;
  433. tbl_printf_cvs();
  434. break;
  435. case 'f':
  436. case 'F':
  437. g_print_lnk = 1;
  438. g_print_to_net = 1;
  439. chn = _net_debug_get_chn();
  440. rt_printf("\r\n打开级联报文监视[chn=%d]:\r\n",chn);
  441. break;
  442. case 'J':
  443. case 'j':
  444. {
  445. extern void iec_printfihertset(void);
  446. g_print_to_net = 1;
  447. rt_printf("\r\n-----配电终端固有参数-----------\r\n");
  448. iec_printfixedset();
  449. g_print_dd = 1;
  450. }
  451. break;
  452. case 'h':
  453. case 'H':
  454. {
  455. g_print_to_net = 1;
  456. g_print_lnk = 1;
  457. lnk_read_test_file();
  458. }
  459. break;
  460. case 'i':
  461. case 'I':
  462. {
  463. g_print_to_net = 1;
  464. g_print_lnk = 1;
  465. lnk_write_test_file();
  466. }
  467. case 'G':
  468. case 'g':
  469. g_print_goose= 1;
  470. g_print_to_net = 1;
  471. g_print_port = -1;
  472. //_net_debug_get_chn();
  473. rt_printf("\r\n打开goose报文监视:\r\n");
  474. break;
  475. case 'k':
  476. case 'K':
  477. g_print_to_net = 1;
  478. ret = del_history_file(HS_FILE_SOE);
  479. if(!ret)
  480. {
  481. ret = create_event_rcd_file(HS_FILE_SOE);
  482. }
  483. if(!ret)
  484. {
  485. rt_printf("新生成soe.msg文件成功\r\n");
  486. }
  487. else
  488. {
  489. rt_printf("新生成soe.msg文件失败\r\n");
  490. }
  491. break;
  492. case 'l':
  493. case 'L':
  494. g_print_to_net = 1;
  495. ret = del_history_file(HS_FILE_CO);
  496. if(!ret)
  497. {
  498. ret = create_event_rcd_file(HS_FILE_CO);
  499. }
  500. if(!ret)
  501. {
  502. rt_printf("新生成co.msg文件成功\r\n");
  503. }
  504. else
  505. {
  506. rt_printf("新生成co.msg文件失败\r\n");
  507. }
  508. break;
  509. case 'M':
  510. case 'm':
  511. g_print_to_net = 1;
  512. SaveUqua(true);
  513. rt_printf("\r\n电压合格率清零\r\n");
  514. break;
  515. case 'N':
  516. case 'n':
  517. g_print_to_net = 1;
  518. {
  519. int sw;
  520. for(sw=0;sw<SWITCH_NUM_MAX;sw++)
  521. {
  522. g_sw[sw].ac_in[SW_AC_IN_IMP1]=0;
  523. g_sw[sw].ac_in[SW_AC_IN_IMP2]=0;
  524. }
  525. }
  526. rt_printf("\r\n脉冲计数率清零\r\n");
  527. break;
  528. case 'P':
  529. case 'p':
  530. {
  531. void app_goose_inf_print(void);
  532. g_print_to_net = 1;
  533. #ifdef __IEC61850_GOOSE_FUNC__
  534. app_goose_inf_print();
  535. #endif
  536. }
  537. break;
  538. case 'Q':
  539. case 'q':
  540. {
  541. void mmd_create_menufile(void);
  542. g_print_to_net = 1;
  543. mmd_create_menufile();
  544. rt_printf("\r\n/app/data/lcd_menu.csv 菜单定义文件已生成\r\n");
  545. }
  546. break;
  547. case 'r':
  548. {
  549. g_print_to_net = 1;
  550. dt_cmd_rt();
  551. }
  552. break;
  553. case 's':
  554. {
  555. g_print_to_net = 1;
  556. dt_cmd_rt_reset();
  557. }
  558. break;
  559. #ifdef CAN_SLAVE_BOARD
  560. case 'R':
  561. case 'r':
  562. {
  563. g_print_to_net = 1;
  564. can_id_printf();
  565. }
  566. break;
  567. case 'S':
  568. case 's':
  569. {
  570. sb_metering = true;
  571. g_print_to_net = 1;
  572. can_metering_calib(g_tDebug.arrRecvBuf);
  573. }
  574. break;
  575. case 'T':
  576. case 't':
  577. {
  578. g_print_to_net = 1;
  579. can_app_energy_clear(0, get_can_slot(0));
  580. }
  581. break;
  582. case 'U':
  583. case 'u':
  584. {
  585. g_print_to_net = 1;
  586. can_id_printf();
  587. }
  588. break;
  589. #endif
  590. default:
  591. #ifdef CAN_SLAVE_BOARD
  592. ret = 0;
  593. g_print_to_net = 1;
  594. if(sb_metering)
  595. {
  596. ret = can_metering_calib(g_tDebug.arrRecvBuf);
  597. }
  598. if(!ret)
  599. #endif
  600. {
  601. _net_debug_print_reset();
  602. net_debug_send((unsigned char *)main_Debug,sizeof(main_Debug));
  603. g_print_sys=false;
  604. }
  605. break;
  606. }
  607. _net_debug_recv_reset();
  608. }
  609. void print_mem_net(char *addr,unsigned char *pd,int lenth)
  610. {
  611. BYTE i,j;
  612. char buf[128],tempstr[8];
  613. if(addr!=NULL)
  614. {
  615. sprintf(buf,"%s",addr);
  616. rt_printf(buf);
  617. }
  618. strcpy(buf,"");
  619. for(i=0,j=0;i<lenth;i++)
  620. {
  621. sprintf(tempstr,"%02X ",*pd++);
  622. strcat(buf,tempstr);
  623. j++;
  624. if(j>18)
  625. {
  626. rt_printf(buf);
  627. strcpy(buf,"\r\n ");
  628. j=0;
  629. }
  630. }
  631. if(j>0)
  632. {
  633. rt_printf(buf);
  634. }
  635. rt_printf("\r\n");
  636. }
  637. /*------------------------------ 内部函数 -------------------------------------
  638. 内部函数以下划线‘_’开头,不需要检查参数的合法性.
  639. */
  640. void _net_debug_recv_reset(void)
  641. {
  642. g_tDebug.cTypeCounter=0;
  643. g_tDebug.cRecvCnt=0;
  644. }
  645. void _net_debug_print_reset(void)
  646. {
  647. g_print_to_net = 0;
  648. g_print_time = 0;
  649. g_print_101 = 0;
  650. g_print_104 = 0;
  651. g_print_lnk = 0;
  652. g_print_hmi = 0;
  653. g_print_can = 0;
  654. g_print_can_monitor= 0;
  655. g_print_sys = 0;
  656. g_print_dd = 0;
  657. g_print_comm_raw = 0;
  658. g_print_port = -1;
  659. g_test_on = 0;
  660. g_print_goose=0;
  661. }
  662. void _net_debug_recv(BYTE cRcvData)
  663. {
  664. if(g_tDebug.bData)
  665. {
  666. return;
  667. }
  668. //xshell 发送的保活状态消息
  669. if(cRcvData == 0xff || cRcvData == 0xf1)
  670. {
  671. return;
  672. }
  673. //rt_printf("cRcvData=%02x\r\n",cRcvData);
  674. g_tDebug.arrRecvBuf[g_tDebug.cRecvCnt++]=cRcvData;
  675. if(cRcvData == 0x0d)
  676. {
  677. g_tDebug.bData=true;
  678. }
  679. if(g_tDebug.cRecvCnt >= UART_FRAME_LEN)
  680. {
  681. _net_debug_recv_reset();
  682. return;
  683. }
  684. return;
  685. }
  686. #ifdef LINUX_KERNEL_APP
  687. int _net_debug_thread_send(void * unused)
  688. {
  689. while(1)
  690. {
  691. msleep(100);
  692. // 检查是否退出
  693. if(g_net_debug_send_exit_flag)
  694. {
  695. g_net_debug_send_exit_flag = 0;
  696. return 0;
  697. }
  698. //noted by sunxi: 20220701 统一冷火和335x,有信号量,才往下执行
  699. if(down_interruptible(&g_print_sem)<0)
  700. {
  701. continue;
  702. }
  703. rt_printf_fifo_get(1);
  704. }
  705. return 0;
  706. }
  707. #endif
  708. /*
  709. noted by sunxi:20220825 335x 修复 6000端口超时或断开后,不能重连的问题
  710. */
  711. int _net_debug_thread_recv(void * unused)
  712. {
  713. struct sockaddr_in server_addr;
  714. struct sockaddr_in client_addr;
  715. struct linger ling;
  716. #ifndef LINUX_KERNEL_APP
  717. struct timeval timeout;
  718. #endif
  719. SOCKET sk_server,tmp_sock;
  720. int sin_size;
  721. int i,len,ret;
  722. unsigned char *ip;
  723. #ifdef LINUX_KERNEL_APP
  724. unsigned int recv_timeout;
  725. unsigned int link_timeout = dTCounter;
  726. #else
  727. int recv_timeout;
  728. int link_timeout = 0;
  729. #endif
  730. unsigned int ip_server;
  731. // while(1) //noted by sunxi:20220825 335x 修复 6000端口超时或断开后,不能重连的问题
  732. // {
  733. NET_BEGIN:
  734. // 1、建立socket并侦听
  735. // 服务器端开始建立socket描述符
  736. #ifdef LINUX_KERNEL_APP
  737. sk_server = rt_socket(AF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0);
  738. #else
  739. sk_server = rt_socket(AF_INET, SOCK_STREAM, 0);
  740. #endif
  741. if (sk_server == RT_SOCKET_ERR)
  742. {
  743. RT_PRINTF_POSITION();
  744. g_ts_debug_recv = NULL;
  745. return -1;
  746. }
  747. // 服务器端填充sockaddr结构
  748. memset (&server_addr, 0, sizeof (struct sockaddr_in));
  749. server_addr.sin_family = AF_INET;
  750. if(get_mt_port_proc()==NET_MT_PORT_PROC_2)
  751. {
  752. if(rt_if_ip_get2(0, 3, (unsigned char *)&ip_server)==0)
  753. {
  754. server_addr.sin_addr.s_addr = htonl (ip_server);
  755. }
  756. else
  757. {
  758. server_addr.sin_addr.s_addr = htonl (INADDR_ANY);
  759. }
  760. }
  761. else
  762. {
  763. server_addr.sin_addr.s_addr = htonl (INADDR_ANY);
  764. }
  765. server_addr.sin_port = htons (NET_DEBUG_PORT);
  766. // 捆绑sockfd描述符
  767. ret = rt_bind (sk_server, (struct sockaddr *)(&server_addr), sizeof (struct sockaddr));
  768. if (ret < 0)
  769. {
  770. RT_PRINTF_POSITION();
  771. rt_socket_close (sk_server);
  772. g_ts_debug_recv = NULL;
  773. return -2;
  774. }
  775. // 监听sockfd描述符
  776. ret = rt_listen (sk_server, 1);
  777. if (ret < 0)
  778. {
  779. RT_PRINTF_POSITION();
  780. rt_socket_close (sk_server);
  781. g_ts_debug_recv = NULL;
  782. return -3;
  783. }
  784. #ifndef LINUX_KERNEL_APP
  785. // 设置接收超时
  786. timeout.tv_sec = 0;
  787. timeout.tv_usec = 500000;
  788. rt_setsockopt(sk_server,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout ,sizeof(struct timeval));
  789. #endif
  790. // 设置关闭延时
  791. ling.l_onoff = 1;
  792. ling.l_linger = 0;
  793. rt_setsockopt(sk_server,SOL_SOCKET,SO_LINGER,(char *)&ling ,sizeof(struct linger));
  794. prctl(PR_SET_NAME, "_net_debug_recv");
  795. while(1) //noted by sunxi:20220825 335x 修复 6000端口超时或断开后,不能重连的问题
  796. {
  797. g_debug_client = RT_SOCKET_ACCEPT_RST;
  798. // 2、接受外部链接
  799. #ifdef RT_SOCKET_FD
  800. while(g_debug_client < 0)
  801. #else
  802. while(g_debug_client == RT_SOCKET_ACCEPT_RST)
  803. #endif
  804. {
  805. msleep(100);
  806. // 服务器阻塞,直到客户程序建立连接
  807. sin_size = sizeof (struct sockaddr_in);
  808. g_debug_client = rt_accept (sk_server, (struct sockaddr*)(&client_addr), &sin_size);
  809. // 检查是否退出
  810. //if(kthread_should_stop())
  811. if(g_net_debug_recv_exit_flag)
  812. {
  813. // 关闭客户端
  814. if(g_debug_client != RT_SOCKET_ERR)
  815. {
  816. tmp_sock = g_debug_client;
  817. g_debug_client = RT_SOCKET_ERR;
  818. rt_socket_close (tmp_sock);
  819. }
  820. // 关闭服务器
  821. rt_socket_close (sk_server);
  822. g_net_debug_recv_exit_flag= 0;
  823. return 0;
  824. }
  825. //IP已经修改要关闭SOCKET
  826. if(g_net_debug_sock_flag == NET_SOCKET_CLOSING)
  827. {
  828. // 关闭客户端
  829. if(g_debug_client != RT_SOCKET_ERR)
  830. {
  831. tmp_sock = g_debug_client;
  832. g_debug_client = RT_SOCKET_ERR;
  833. rt_socket_close (tmp_sock);
  834. }
  835. // 关闭服务器
  836. rt_socket_close (sk_server);
  837. //置已经关闭标志
  838. g_net_debug_sock_flag = NET_SOCKET_CLOSED;
  839. //等待IP修改完成
  840. while(g_net_debug_sock_flag != NET_SOCKET_REINIT)
  841. {
  842. msleep(100);
  843. }
  844. //置为初始化
  845. g_net_debug_sock_flag = NET_SOCKET_INIT;
  846. goto NET_BEGIN;
  847. }
  848. }
  849. // 3、关闭侦听socket,避免多个外部连接
  850. //rt_shutdown(sk_server, SHUT_RDWR);
  851. //rt_socket_close(sk_server); //noted by sunxi:20220825 335x 修复 6000端口超时或断开后,不能重连的问题
  852. ip = (unsigned char *)&client_addr.sin_addr.s_addr;
  853. rt_printf("debug client connect(ip=%d.%d.%d.%d)!\r\n",ip[0],ip[1],ip[2],ip[3]);
  854. {
  855. char buf[64];
  856. char log_info[128];
  857. 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]);
  858. log_str_time(LOG_OPERATE,buf,0,1);
  859. 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]);
  860. load_hs_log_rcd(TYPE_CHNL_LINK,true,NULL,log_info,1);
  861. }
  862. // 4、客户端已连接,处理客户端命令
  863. #ifdef LINUX_KERNEL_APP
  864. recv_timeout=dTCounter;
  865. #else
  866. recv_timeout=0;
  867. #endif
  868. while(1)
  869. {
  870. #ifdef LINUX_KERNEL_APP
  871. msleep(2);//noted by sunxi: 20221212 设为非阻塞型
  872. len = rt_recv (g_debug_client, g_net_debug_buf, NET_RECV_MAX, MSG_DONTWAIT);
  873. #else
  874. len = rt_recv (g_debug_client, g_net_debug_buf, NET_RECV_MAX, 0);
  875. #endif
  876. // 检查是否退出
  877. if(g_net_debug_recv_exit_flag)
  878. {
  879. // 关闭客户端
  880. tmp_sock = g_debug_client;
  881. g_debug_client = RT_SOCKET_ERR;
  882. rt_socket_close (tmp_sock);
  883. // 关闭服务器
  884. rt_socket_close (sk_server); //noted by sunxi:20220825 335x 修复 6000端口超时或断开后,不能重连的问题
  885. g_net_debug_recv_exit_flag = 0;
  886. return 0;
  887. }
  888. //IP已经修改要关闭SOCKET
  889. if(g_net_debug_sock_flag == NET_SOCKET_CLOSING)
  890. {
  891. // 关闭客户端
  892. tmp_sock = g_debug_client;
  893. g_debug_client = RT_SOCKET_ERR;
  894. rt_socket_close (tmp_sock);
  895. // 关闭服务器
  896. rt_socket_close (sk_server); //noted by sunxi:20220825 335x 修复 6000端口超时或断开后,不能重连的问题
  897. //置已经关闭标志
  898. g_net_debug_sock_flag = NET_SOCKET_CLOSED;
  899. //等待IP修改完成
  900. while(g_net_debug_sock_flag != NET_SOCKET_REINIT)
  901. {
  902. msleep(100);
  903. }
  904. //置为初始化
  905. g_net_debug_sock_flag = NET_SOCKET_INIT;
  906. goto NET_BEGIN;
  907. }
  908. #ifdef LINUX_KERNEL_APP
  909. if(len == -EAGAIN)
  910. #else
  911. if((len == -EAGAIN)||(len==-1))//使用linux的recvfrom没有接收到数据时返回-1 jack.liu 20200916
  912. #endif
  913. {
  914. if(rt_get_net_linkstatus(rt_get_netcard_id_from_socket(g_debug_client))==1)
  915. {
  916. #ifdef LINUX_KERNEL_APP
  917. if((dTCounter - link_timeout)>RT_LINK_TIMEOUT*T_1s) //500ms超时
  918. #else
  919. link_timeout++;
  920. if(link_timeout>RT_LINK_TIMEOUT*2) //500ms超时
  921. #endif
  922. {
  923. rt_printf("%s: link down\n",__FUNCTION__);
  924. #ifdef LINUX_KERNEL_APP
  925. link_timeout = dTCounter;
  926. #else
  927. link_timeout = 0;
  928. #endif
  929. break;
  930. }
  931. }
  932. else
  933. {
  934. #ifdef LINUX_KERNEL_APP
  935. link_timeout = dTCounter;
  936. #else
  937. link_timeout = 0;
  938. #endif
  939. }
  940. // 超时
  941. #ifdef LINUX_KERNEL_APP
  942. if((dTCounter - recv_timeout)>120*T_1s) // 超时2分钟,端口未收到数据,关闭端口
  943. #else
  944. recv_timeout++;
  945. if(recv_timeout>240) // 超时2分钟,端口未收到数据,关闭端口
  946. #endif
  947. {
  948. rt_printf ("net_debug_thread:timeout\r\n");
  949. break;
  950. }
  951. continue;
  952. }
  953. #ifdef LINUX_KERNEL_APP
  954. else if (len <= 0)
  955. #else
  956. else if ((len == 0)||(len<-1)) //使用linux的recvfrom没有接收到数据时返回-1 jack.liu 20200916
  957. #endif
  958. {
  959. //调用recv时,如果返回0,则表示对端关闭;返回负数,表示出错
  960. rt_printf ("net_debug_thread:peer close(ret=%d).\r\n",len);
  961. msleep(100);
  962. break;
  963. }
  964. // 接收数据
  965. #ifdef LINUX_KERNEL_APP
  966. recv_timeout = dTCounter;
  967. link_timeout = dTCounter;
  968. #else
  969. recv_timeout = 0;
  970. link_timeout = 0;
  971. #endif
  972. for(i=0;i<len;i++)
  973. {
  974. _net_debug_recv(g_net_debug_buf[i]);
  975. }
  976. g_tDebug.bNet=true;
  977. }
  978. // 复位调试打印信息
  979. _net_debug_print_reset();
  980. // 关闭客户端socket
  981. tmp_sock = g_debug_client;
  982. g_debug_client = RT_SOCKET_ERR;
  983. {
  984. char buf[64];
  985. 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]);
  986. log_str_time(LOG_OPERATE,buf,0,0);
  987. load_hs_log_rcd(TYPE_CHNL_LINK,true,NULL,"6000 port disconnection",0);
  988. }
  989. rt_socket_close (tmp_sock);
  990. }
  991. // 理论上,程序不会运行到这儿
  992. return 0;
  993. }
  994. /*------------------------------ 测试函数 -------------------------------------
  995. 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
  996. 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
  997. */
  998. /*------------------------------ 文件结束 -------------------------------------
  999. */