PageRenderTime 58ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/platform/FNET/fnet_demos/common/fnet_application/fapp_bench.c

https://gitlab.com/fuggles/ucos
C | 921 lines | 609 code | 163 blank | 149 comment | 130 complexity | b657e662a449f8ad2d9560151c052021 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0
  1. /**************************************************************************
  2. *
  3. * Copyright 2011-2015 by Andrey Butok. FNET Community.
  4. * Copyright 2008-2010 by Andrey Butok. Freescale Semiconductor, Inc.
  5. *
  6. ***************************************************************************
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License Version 3
  9. * or later (the "LGPL").
  10. *
  11. * As a special exception, the copyright holders of the FNET project give you
  12. * permission to link the FNET sources with independent modules to produce an
  13. * executable, regardless of the license terms of these independent modules,
  14. * and to copy and distribute the resulting executable under terms of your
  15. * choice, provided that you also meet, for each linked independent module,
  16. * the terms and conditions of the license of that module.
  17. * An independent module is a module which is not derived from or based
  18. * on this library.
  19. * If you modify the FNET sources, you may extend this exception
  20. * to your version of the FNET sources, but you are not obligated
  21. * to do so. If you do not wish to do so, delete this
  22. * exception statement from your version.
  23. *
  24. * This program is distributed in the hope that it will be useful,
  25. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  27. *
  28. * You should have received a copy of the GNU General Public License
  29. * and the GNU Lesser General Public License along with this program.
  30. * If not, see <http://www.gnu.org/licenses/>.
  31. *
  32. **********************************************************************/ /*!
  33. *
  34. * @file fapp_bench.c
  35. *
  36. * @author Andrey Butok
  37. *
  38. * @brief FNET Shell Demo implementation.
  39. *
  40. ***************************************************************************/
  41. #include "fnet.h"
  42. #include "fapp_prv.h"
  43. #include "fapp_bench.h"
  44. #if FAPP_CFG_BENCH_CMD
  45. /************************************************************************
  46. * Benchmark definitions
  47. ************************************************************************/
  48. #define FAPP_BENCH_UDP_END_BUFFER_LENGTH (1)
  49. #define FAPP_UDP_TIMEOUT_MS (8000)
  50. /* Socket Tx&Rx buffer sizes. */
  51. #define FAPP_BENCH_SOCKET_BUF_SIZE (FAPP_BENCH_PACKET_SIZE_MAX)
  52. #define FAPP_BENCH_BUFFER_SIZE (FAPP_BENCH_PACKET_SIZE_MAX)
  53. #define FAPP_BENCH_TX_UDP_END_ITERATIONS (10)
  54. /* Keepalive probe retransmit limit.*/
  55. #define FAPP_BENCH_TCP_KEEPCNT (2)
  56. /* Keepalive retransmit interval.*/
  57. #define FAPP_BENCH_TCP_KEEPINTVL (5) /*sec*/
  58. /* Time between keepalive probes.*/
  59. #define FAPP_BENCH_TCP_KEEPIDLE (5) /*sec*/
  60. #define FAPP_BENCH_COMPLETED_STR "Test completed."
  61. /************************************************************************
  62. * Benchmark server control structure.
  63. *************************************************************************/
  64. struct fapp_bench_t
  65. {
  66. SOCKET socket_listen; /* Listening socket.*/
  67. SOCKET socket_foreign; /* Foreign socket.*/
  68. char buffer[FAPP_BENCH_BUFFER_SIZE]; /* Transmit circular buffer */
  69. unsigned long first_time;
  70. unsigned long last_time;
  71. unsigned long bytes;
  72. unsigned long remote_bytes;
  73. };
  74. static struct fapp_bench_t fapp_bench;
  75. /**************************************************************************/ /*!
  76. * TX benchmark parameters
  77. ******************************************************************************/
  78. struct fapp_bench_tx_params
  79. {
  80. fnet_shell_desc_t desc;
  81. struct sockaddr foreign_addr;
  82. int packet_size;
  83. int packet_number;
  84. int iteration_number;
  85. };
  86. /************************************************************************
  87. * Function Prototypes
  88. *************************************************************************/
  89. static void fapp_bench_print_results (fnet_shell_desc_t desc);
  90. static void fapp_bench_tcp_rx (fnet_shell_desc_t desc, fnet_address_family_t family);
  91. static void fapp_bench_udp_rx (fnet_shell_desc_t desc, fnet_address_family_t family, struct sockaddr *multicast_address /* optional, set to 0*/);
  92. static void fapp_bench_tcp_tx (struct fapp_bench_tx_params *params);
  93. static void fapp_bench_udp_tx (struct fapp_bench_tx_params *params);
  94. /************************************************************************
  95. * NAME: fapp_bench_print_results
  96. *
  97. * DESCRIPTION: Print Benchmark results.
  98. ************************************************************************/
  99. static void fapp_bench_print_results (fnet_shell_desc_t desc)
  100. {
  101. /* Print benchmark results.*/
  102. unsigned long interval = fnet_timer_get_interval(fapp_bench.first_time, fapp_bench.last_time);
  103. fnet_shell_println(desc, "Results:");
  104. if(fapp_bench.remote_bytes == 0)
  105. {
  106. fnet_shell_println(desc, "\t%d bytes in %d.%d seconds = %d Kbits/sec\n", fapp_bench.bytes,
  107. ((interval*FNET_TIMER_PERIOD_MS)/1000),
  108. ((interval*FNET_TIMER_PERIOD_MS)%1000)/100,
  109. (interval == 0) ? -1 : (int)((fapp_bench.bytes*8/**(1000*//FNET_TIMER_PERIOD_MS/*)*/)/interval)/*/1000*/);
  110. }
  111. else /* UDP TX only */
  112. {
  113. fnet_shell_println(desc, "\t%d [%d] bytes in %d.%d seconds = %d [%d] Kbits/sec\n", fapp_bench.bytes, fapp_bench.remote_bytes,
  114. ((interval*FNET_TIMER_PERIOD_MS)/1000),
  115. ((interval*FNET_TIMER_PERIOD_MS)%1000)/100,
  116. (interval == 0) ? -1 : (int)((fapp_bench.bytes*8/**(1000*//FNET_TIMER_PERIOD_MS/*)*/)/interval)/*/1000*/,
  117. (interval == 0) ? -1 : (int)((fapp_bench.remote_bytes*8/**(1000*//FNET_TIMER_PERIOD_MS/*)*/)/interval)/*/1000*/);
  118. }
  119. }
  120. /************************************************************************
  121. * NAME: fapp_bench_tcp_rx
  122. *
  123. * DESCRIPTION: Start Benchmark TCP server.
  124. ************************************************************************/
  125. static void fapp_bench_tcp_rx (fnet_shell_desc_t desc, fnet_address_family_t family)
  126. {
  127. struct sockaddr local_addr;
  128. int received;
  129. char ip_str[FNET_IP_ADDR_STR_SIZE];
  130. struct linger linger_option ={1, /*l_onoff*/
  131. 4 /*l_linger*/};
  132. unsigned long bufsize_option = FAPP_BENCH_SOCKET_BUF_SIZE;
  133. int keepalive_option = 1;
  134. int keepcnt_option = FAPP_BENCH_TCP_KEEPCNT;
  135. int keepintvl_option = FAPP_BENCH_TCP_KEEPINTVL;
  136. int keepidle_option = FAPP_BENCH_TCP_KEEPIDLE;
  137. struct sockaddr foreign_addr;
  138. unsigned int addr_len;
  139. int exit_flag = 0;
  140. fapp_bench.socket_foreign = SOCKET_INVALID;
  141. /* Create listen socket */
  142. if((fapp_bench.socket_listen = socket(family, SOCK_STREAM, 0)) == SOCKET_INVALID)
  143. {
  144. FNET_DEBUG("BENCH: Socket creation error.");
  145. goto ERROR_1;
  146. }
  147. /* Bind socket.*/
  148. fnet_memset_zero(&local_addr, sizeof(local_addr));
  149. local_addr.sa_port = FAPP_BENCH_PORT;
  150. local_addr.sa_family = family;
  151. if(bind(fapp_bench.socket_listen, &local_addr, sizeof(local_addr)) == SOCKET_ERROR)
  152. {
  153. FNET_DEBUG("BENCH: Socket bind error.");
  154. goto ERROR_2;
  155. }
  156. /* Set Socket options. */
  157. if( /* Setup linger option. */
  158. (setsockopt (fapp_bench.socket_listen, SOL_SOCKET, SO_LINGER, (char *)&linger_option, sizeof(linger_option)) == SOCKET_ERROR) ||
  159. /* Set socket buffer size. */
  160. (setsockopt(fapp_bench.socket_listen, SOL_SOCKET, SO_RCVBUF, (char *) &bufsize_option, sizeof(bufsize_option))== SOCKET_ERROR) ||
  161. (setsockopt(fapp_bench.socket_listen, SOL_SOCKET, SO_SNDBUF, (char *) &bufsize_option, sizeof(bufsize_option))== SOCKET_ERROR) ||
  162. /* Enable keepalive_option option. */
  163. (setsockopt (fapp_bench.socket_listen, SOL_SOCKET, SO_KEEPALIVE, (char *)&keepalive_option, sizeof(keepalive_option)) == SOCKET_ERROR) ||
  164. /* Keepalive probe retransmit limit. */
  165. (setsockopt (fapp_bench.socket_listen, IPPROTO_TCP, TCP_KEEPCNT, (char *)&keepcnt_option, sizeof(keepcnt_option)) == SOCKET_ERROR) ||
  166. /* Keepalive retransmit interval.*/
  167. (setsockopt (fapp_bench.socket_listen, IPPROTO_TCP, TCP_KEEPINTVL, (char *)&keepintvl_option, sizeof(keepintvl_option)) == SOCKET_ERROR) ||
  168. /* Time between keepalive probes.*/
  169. (setsockopt (fapp_bench.socket_listen, IPPROTO_TCP, TCP_KEEPIDLE, (char *)&keepidle_option, sizeof(keepidle_option)) == SOCKET_ERROR)
  170. )
  171. {
  172. FNET_DEBUG("BENCH: Socket setsockopt error.\n");
  173. goto ERROR_2;
  174. }
  175. /* Listen. */
  176. if(listen(fapp_bench.socket_listen, 1) == SOCKET_ERROR)
  177. {
  178. FNET_DEBUG("BENCH: Socket listen error.\n");
  179. goto ERROR_2;
  180. }
  181. /* ------ Start test.----------- */
  182. fnet_shell_println(desc, FAPP_DELIMITER_STR);
  183. fnet_shell_println(desc, " TCP RX Test");
  184. fnet_shell_println(desc, FAPP_DELIMITER_STR);
  185. fapp_netif_addr_print(desc, family, fapp_default_netif, FNET_FALSE);
  186. fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Local Port", FNET_NTOHS(FAPP_BENCH_PORT));
  187. fnet_shell_println(desc, FAPP_TOCANCEL_STR);
  188. fnet_shell_println(desc, FAPP_DELIMITER_STR);
  189. while(exit_flag == 0)
  190. {
  191. fnet_shell_println(desc, "Waiting.");
  192. fapp_bench.bytes = 0;
  193. fapp_bench.remote_bytes = 0;
  194. if(fapp_bench.socket_foreign != SOCKET_INVALID)
  195. {
  196. closesocket(fapp_bench.socket_foreign);
  197. fapp_bench.socket_foreign = SOCKET_INVALID;
  198. }
  199. while((fapp_bench.socket_foreign == SOCKET_INVALID) && (exit_flag == 0))
  200. {
  201. /*Accept*/
  202. addr_len = sizeof(foreign_addr);
  203. fapp_bench.socket_foreign = accept(fapp_bench.socket_listen, &foreign_addr, &addr_len);
  204. exit_flag = fnet_shell_ctrlc (desc);
  205. if(fapp_bench.socket_foreign != SOCKET_INVALID)
  206. {
  207. fnet_shell_println(desc,"Receiving from %s:%d", fnet_inet_ntop(foreign_addr.sa_family, (char*)(foreign_addr.sa_data), ip_str, sizeof(ip_str)), fnet_ntohs(foreign_addr.sa_port));
  208. fapp_bench.first_time = fnet_timer_ticks();
  209. while(1) /* Receiving data.*/
  210. {
  211. received = recv(fapp_bench.socket_foreign, (char*)(&fapp_bench.buffer[0]), FAPP_BENCH_BUFFER_SIZE, 0);
  212. if ((received == SOCKET_ERROR) || exit_flag)
  213. {
  214. fapp_bench.last_time = fnet_timer_ticks();
  215. /* Print benchmark results.*/
  216. fapp_bench_print_results (desc);
  217. break;
  218. }
  219. else
  220. {
  221. fapp_bench.bytes += received;
  222. }
  223. exit_flag = fnet_shell_ctrlc (desc); /* Check [Ctrl+c]*/
  224. }
  225. }
  226. }
  227. }
  228. closesocket(fapp_bench.socket_foreign);
  229. ERROR_2:
  230. closesocket(fapp_bench.socket_listen);
  231. ERROR_1:
  232. fnet_shell_println(desc, FAPP_BENCH_COMPLETED_STR);
  233. }
  234. /************************************************************************
  235. * NAME: fapp_bench_udp_rx
  236. *
  237. * DESCRIPTION: Start Benchmark UDP server.
  238. ************************************************************************/
  239. static void fapp_bench_udp_rx (fnet_shell_desc_t desc, fnet_address_family_t family, struct sockaddr *multicast_address /* optional, set to 0*/)
  240. {
  241. struct sockaddr local_addr;
  242. const unsigned long bufsize_option = FAPP_BENCH_SOCKET_BUF_SIZE;
  243. int received;
  244. char ip_str[FNET_IP_ADDR_STR_SIZE];
  245. struct sockaddr addr;
  246. unsigned int addr_len;
  247. int is_first = 1;
  248. int exit_flag = 0;
  249. /* Create listen socket */
  250. if((fapp_bench.socket_listen = socket(family, SOCK_DGRAM, 0)) == SOCKET_INVALID)
  251. {
  252. FNET_DEBUG("BENCH: Socket creation error.\n");
  253. goto ERROR_1;
  254. }
  255. /*Bind.*/
  256. fnet_memset_zero(&local_addr, sizeof(local_addr));
  257. local_addr.sa_port = FAPP_BENCH_PORT;
  258. local_addr.sa_family = family;
  259. if(bind(fapp_bench.socket_listen, &local_addr, sizeof(local_addr)) == SOCKET_ERROR)
  260. {
  261. FNET_DEBUG("BENCH: Socket bind error.\n");
  262. goto ERROR_2;
  263. }
  264. /* Set socket options. */
  265. if(
  266. /* Set socket buffer size. */
  267. (setsockopt(fapp_bench.socket_listen, SOL_SOCKET, SO_RCVBUF, (char *) &bufsize_option, sizeof(bufsize_option))== SOCKET_ERROR) ||
  268. (setsockopt(fapp_bench.socket_listen, SOL_SOCKET, SO_SNDBUF, (char *) &bufsize_option, sizeof(bufsize_option))== SOCKET_ERROR)
  269. )
  270. {
  271. FNET_DEBUG("BENCH: Socket setsockopt error.\n");
  272. goto ERROR_2;
  273. }
  274. /* Join multicast group, if set. */
  275. if(multicast_address)
  276. {
  277. #if FNET_CFG_IP4
  278. if(multicast_address->sa_family == AF_INET)
  279. {
  280. struct ip_mreq mreq; /* Multicast group information.*/
  281. mreq.imr_multiaddr.s_addr = ((struct sockaddr_in*)multicast_address)->sin_addr.s_addr;
  282. mreq.imr_interface.s_addr = FNET_HTONL(INADDR_ANY); /* Default Interface.*/
  283. /* Join multicast group. */
  284. if(setsockopt(fapp_bench.socket_listen, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) == SOCKET_ERROR)
  285. {
  286. FNET_DEBUG("BENCH: Joining to multicast group is failed.\n");
  287. goto ERROR_2;
  288. }
  289. }
  290. #endif
  291. #if FNET_CFG_IP6
  292. if(multicast_address->sa_family == AF_INET6)
  293. {
  294. struct ipv6_mreq mreq6; /* Multicast group information.*/
  295. FNET_IP6_ADDR_COPY(&((struct sockaddr_in6*)multicast_address)->sin6_addr.s6_addr, &mreq6.ipv6imr_multiaddr.s6_addr);
  296. mreq6.ipv6imr_interface = ((struct sockaddr_in6*)multicast_address)->sin6_scope_id;
  297. /* Join multicast group. */
  298. if(setsockopt(fapp_bench.socket_listen, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&mreq6, sizeof(mreq6)) == SOCKET_ERROR)
  299. {
  300. FNET_DEBUG("BENCH: Joining to multicast group is failed.\n");
  301. goto ERROR_2;
  302. }
  303. }
  304. #endif
  305. }
  306. /* ------ Start test.----------- */
  307. fnet_shell_println(desc, FAPP_DELIMITER_STR);
  308. fnet_shell_println(desc, " UDP RX Test" );
  309. fnet_shell_println(desc, FAPP_DELIMITER_STR);
  310. fapp_netif_addr_print(desc, family, fapp_default_netif, FNET_FALSE);
  311. if(multicast_address)
  312. {
  313. fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_S, "Multicast Group", fnet_inet_ntop(multicast_address->sa_family, (char*)(multicast_address->sa_data), ip_str, sizeof(ip_str)) );
  314. }
  315. fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Local Port", FNET_NTOHS(FAPP_BENCH_PORT));
  316. fnet_shell_println(desc, FAPP_TOCANCEL_STR);
  317. fnet_shell_println(desc, FAPP_DELIMITER_STR);
  318. while(exit_flag == 0) /* Main loop */
  319. {
  320. fnet_shell_println(desc, "Waiting.");
  321. fapp_bench.bytes = 0;
  322. fapp_bench.remote_bytes = 0;
  323. addr_len = sizeof(addr);
  324. is_first = 1;
  325. while(exit_flag == 0) /* Test loop. */
  326. {
  327. /* Receive data */
  328. received = recvfrom (fapp_bench.socket_listen, (char*)(&fapp_bench.buffer[0]), FAPP_BENCH_BUFFER_SIZE, 0,
  329. &addr, &addr_len );
  330. if(received >= FAPP_BENCH_UDP_END_BUFFER_LENGTH)
  331. {
  332. /* Reset timeout. */
  333. fapp_bench.last_time = fnet_timer_ticks();
  334. if(is_first)
  335. {
  336. if( received > FAPP_BENCH_UDP_END_BUFFER_LENGTH )
  337. {
  338. fnet_shell_println(desc,"Receiving from %s:%d", fnet_inet_ntop(addr.sa_family, (char*)(addr.sa_data), ip_str, sizeof(ip_str)), fnet_ntohs(addr.sa_port));
  339. fapp_bench.first_time = fnet_timer_ticks();
  340. is_first = 0;
  341. }
  342. }
  343. else
  344. {
  345. if(received == FAPP_BENCH_UDP_END_BUFFER_LENGTH ) /* End of transfer. */
  346. {
  347. /* Send ACK containing amount of received data.*/
  348. unsigned long ack_bytes = fnet_htonl(fapp_bench.bytes);
  349. /* Send several times, just to be sure that it is received/not lost.*/
  350. sendto(fapp_bench.socket_listen, (char*)(&ack_bytes), sizeof(ack_bytes), 0, (struct sockaddr*)&addr, sizeof(addr));
  351. sendto(fapp_bench.socket_listen, (char*)(&ack_bytes), sizeof(ack_bytes), 0, (struct sockaddr*)&addr, sizeof(addr));
  352. sendto(fapp_bench.socket_listen, (char*)(&ack_bytes), sizeof(ack_bytes), 0, (struct sockaddr*)&addr, sizeof(addr));
  353. /* Print benchmark results.*/
  354. fapp_bench_print_results (desc);
  355. break;
  356. }
  357. else
  358. fapp_bench.bytes += received;
  359. }
  360. }
  361. else
  362. {
  363. /* Check error. Check timeout */
  364. if(received == SOCKET_ERROR)
  365. {
  366. fnet_shell_println(desc, "BENCH: Error (%d).", fnet_error_get());
  367. break;
  368. }
  369. /* Check timeout. */
  370. if((is_first == 0) &&
  371. (fnet_timer_get_interval(fapp_bench.last_time, fnet_timer_ticks()) > (FAPP_UDP_TIMEOUT_MS/FNET_TIMER_PERIOD_MS)))
  372. {
  373. fnet_shell_println(desc, "BENCH: Exit on timeout.");
  374. fapp_bench_print_results (desc);
  375. break;
  376. }
  377. }
  378. exit_flag = fnet_shell_ctrlc (desc);
  379. }
  380. }
  381. ERROR_2:
  382. closesocket(fapp_bench.socket_listen);
  383. ERROR_1:
  384. fnet_shell_println(desc, FAPP_BENCH_COMPLETED_STR);
  385. }
  386. /************************************************************************
  387. * NAME: fapp_benchrx_cmd
  388. *
  389. * DESCRIPTION: Start RX Benchmark server.
  390. ************************************************************************/
  391. void fapp_benchrx_cmd( fnet_shell_desc_t desc, int argc, char ** argv )
  392. {
  393. fnet_address_family_t family;
  394. family = AF_SUPPORTED;
  395. /* TCP */
  396. if((argc == 1)||(argc == 2 && fnet_strcasecmp("tcp", argv[1]) == 0))
  397. {
  398. fapp_bench_tcp_rx(desc, family);
  399. }
  400. /* UDP */
  401. else if(((argc == 2) || (argc == 3)) && fnet_strcasecmp("udp", argv[1]) == 0)
  402. {
  403. struct sockaddr multicast_address;
  404. struct sockaddr *multicast_address_p = FNET_NULL;
  405. if(argc == 3) /* Multicast group address.*/
  406. {
  407. if((fnet_inet_ptos(argv[2], &multicast_address) == FNET_ERR) /* Convert from string to address.*/
  408. || !fnet_socket_addr_is_multicast(&multicast_address) /* Check if address is multicast.*/
  409. || !(family & multicast_address.sa_family) ) /* Check supported family.*/
  410. {
  411. fnet_shell_println(desc, FAPP_PARAM_ERR, argv[2]);
  412. return;
  413. }
  414. multicast_address_p = &multicast_address;
  415. }
  416. fapp_bench_udp_rx(desc, family, multicast_address_p);
  417. }
  418. else
  419. {
  420. fnet_shell_println(desc, FAPP_PARAM_ERR, argv[1]);
  421. }
  422. }
  423. ////////////////////////////////////////////// TX //////////////////////////////////////
  424. /************************************************************************
  425. * NAME: fapp_bench_tcp_tx
  426. *
  427. * DESCRIPTION: Start TX TCP Benchmark.
  428. ************************************************************************/
  429. static void fapp_bench_tcp_tx (struct fapp_bench_tx_params *params)
  430. {
  431. int send_result;
  432. char ip_str[FNET_IP_ADDR_STR_SIZE];
  433. const struct linger linger_option ={1, /*l_onoff*/
  434. 4 /*l_linger*/};
  435. const unsigned long bufsize_option = FAPP_BENCH_SOCKET_BUF_SIZE;
  436. const int keepalive_option = 1;
  437. const int keepcnt_option = FAPP_BENCH_TCP_KEEPCNT;
  438. const int keepintvl_option = FAPP_BENCH_TCP_KEEPINTVL;
  439. const int keepidle_option = FAPP_BENCH_TCP_KEEPIDLE;
  440. struct sockaddr foreign_addr;
  441. int exit_flag = 0;
  442. int sock_err ;
  443. unsigned int option_len;
  444. fnet_shell_desc_t desc = params->desc;
  445. fnet_socket_state_t connection_state;
  446. int packet_size = params->packet_size;
  447. int cur_packet_number;
  448. int buffer_offset;
  449. int iterations = params->iteration_number;
  450. fnet_address_family_t family = params->foreign_addr.sa_family;
  451. if(packet_size > FAPP_BENCH_BUFFER_SIZE) /* Check max size.*/
  452. packet_size = FAPP_BENCH_BUFFER_SIZE;
  453. fapp_bench.socket_listen = SOCKET_INVALID;
  454. /* ------ Start test.----------- */
  455. fnet_shell_println(desc, FAPP_DELIMITER_STR);
  456. fnet_shell_println(desc, " TCP TX Test" );
  457. fnet_shell_println(desc, FAPP_DELIMITER_STR);
  458. fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_S, "Remote IP Addr", fnet_inet_ntop(family, params->foreign_addr.sa_data, ip_str, sizeof(ip_str)));
  459. fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Remote Port", fnet_ntohs(params->foreign_addr.sa_port));
  460. fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Message Size", params->packet_size);
  461. fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Num. of messages", params->packet_number);
  462. fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Num. of iterations", params->iteration_number);
  463. fnet_shell_println(desc, FAPP_TOCANCEL_STR);
  464. fnet_shell_println(desc, FAPP_DELIMITER_STR);
  465. while(iterations--)
  466. {
  467. /* Create socket */
  468. if((fapp_bench.socket_foreign = socket(family, SOCK_STREAM, 0)) == SOCKET_INVALID)
  469. {
  470. FNET_DEBUG("BENCH: Socket creation error.\n");
  471. iterations = 0;
  472. goto ERROR_1;
  473. }
  474. /* Set Socket options. */
  475. if( /* Setup linger option. */
  476. (setsockopt (fapp_bench.socket_foreign, SOL_SOCKET, SO_LINGER, (char *)&linger_option, sizeof(linger_option)) == SOCKET_ERROR) ||
  477. /* Set socket buffer size. */
  478. (setsockopt(fapp_bench.socket_foreign, SOL_SOCKET, SO_RCVBUF, (char *) &bufsize_option, sizeof(bufsize_option))== SOCKET_ERROR) ||
  479. (setsockopt(fapp_bench.socket_foreign, SOL_SOCKET, SO_SNDBUF, (char *) &bufsize_option, sizeof(bufsize_option))== SOCKET_ERROR) ||
  480. /* Enable keepalive_option option. */
  481. (setsockopt (fapp_bench.socket_foreign, SOL_SOCKET, SO_KEEPALIVE, (char *)&keepalive_option, sizeof(keepalive_option)) == SOCKET_ERROR) ||
  482. /* Keepalive probe retransmit limit. */
  483. (setsockopt (fapp_bench.socket_foreign, IPPROTO_TCP, TCP_KEEPCNT, (char *)&keepcnt_option, sizeof(keepcnt_option)) == SOCKET_ERROR) ||
  484. /* Keepalive retransmit interval.*/
  485. (setsockopt (fapp_bench.socket_foreign, IPPROTO_TCP, TCP_KEEPINTVL, (char *)&keepintvl_option, sizeof(keepintvl_option)) == SOCKET_ERROR) ||
  486. /* Time between keepalive probes.*/
  487. (setsockopt (fapp_bench.socket_foreign, IPPROTO_TCP, TCP_KEEPIDLE, (char *)&keepidle_option, sizeof(keepidle_option)) == SOCKET_ERROR)
  488. )
  489. {
  490. FNET_DEBUG("BENCH: Socket setsockopt error.\n");
  491. iterations = 0;
  492. goto ERROR_2;
  493. }
  494. /* Connect to the server.*/
  495. fnet_shell_println(desc,"Connecting.");
  496. foreign_addr = params->foreign_addr;
  497. connect(fapp_bench.socket_foreign, (struct sockaddr *)(&foreign_addr), sizeof(foreign_addr));
  498. do
  499. {
  500. option_len = sizeof(connection_state);
  501. getsockopt(fapp_bench.socket_foreign, SOL_SOCKET, SO_STATE, (char*)&connection_state, &option_len);
  502. }
  503. while (connection_state == SS_CONNECTING);
  504. if(connection_state != SS_CONNECTED)
  505. {
  506. fnet_shell_println(desc, "Connection failed.");
  507. iterations = 0;
  508. goto ERROR_2;
  509. }
  510. /* Sending.*/
  511. fnet_shell_println(desc,"Sending.");
  512. fapp_bench.bytes = 0;
  513. fapp_bench.remote_bytes = 0;
  514. cur_packet_number = 0;
  515. buffer_offset = 0;
  516. fapp_bench.first_time = fnet_timer_ticks();
  517. while(1)
  518. {
  519. send_result = send( fapp_bench.socket_foreign, (char*)(&fapp_bench.buffer[buffer_offset]), (packet_size-buffer_offset), 0);
  520. fapp_bench.last_time = fnet_timer_ticks();
  521. if ( send_result == SOCKET_ERROR )
  522. {
  523. option_len = sizeof(sock_err);
  524. getsockopt(fapp_bench.socket_foreign, SOL_SOCKET, SO_ERROR, (char*)&sock_err, &option_len);
  525. fnet_shell_println(desc, "Socket error = %d", sock_err);
  526. iterations = 0;
  527. #if 0
  528. /* Print benchmark results.*/
  529. fapp_bench_print_results (desc);
  530. #endif
  531. break;
  532. }
  533. else if(send_result)
  534. {
  535. fapp_bench.bytes += send_result;
  536. buffer_offset += send_result;
  537. if(buffer_offset == packet_size)
  538. {
  539. cur_packet_number ++;
  540. buffer_offset = 0;
  541. }
  542. exit_flag = fnet_shell_ctrlc(desc); /* Check [Ctrl+c]*/
  543. if((cur_packet_number >= params->packet_number)|| exit_flag)
  544. {
  545. if(exit_flag)
  546. {
  547. fnet_shell_println(desc, FAPP_SHELL_CANCELED_CTRL_C);
  548. iterations = 0;
  549. }
  550. /* Print benchmark results.*/
  551. fapp_bench_print_results (desc);
  552. break;
  553. }
  554. }
  555. }
  556. ERROR_2:
  557. closesocket(fapp_bench.socket_foreign);
  558. }
  559. ERROR_1:
  560. fnet_shell_println(desc, FAPP_BENCH_COMPLETED_STR);
  561. }
  562. /************************************************************************
  563. * NAME: fapp_bench_udp_tx
  564. *
  565. * DESCRIPTION: Start TX TCP Benchmark.
  566. ************************************************************************/
  567. static void fapp_bench_udp_tx (struct fapp_bench_tx_params *params)
  568. {
  569. int send_result;
  570. char ip_str[FNET_IP_ADDR_STR_SIZE];
  571. int i;
  572. int received;
  573. const struct linger linger_option ={1, /*l_onoff*/
  574. 4 /*l_linger*/};
  575. const unsigned long bufsize_option = FAPP_BENCH_SOCKET_BUF_SIZE;
  576. struct sockaddr foreign_addr;
  577. int exit_flag = 0;
  578. int sock_err;
  579. unsigned int option_len;
  580. fnet_shell_desc_t desc = params->desc;
  581. int packet_size = params->packet_size;
  582. int cur_packet_number;
  583. int iterations = params->iteration_number;
  584. fnet_address_family_t family = params->foreign_addr.sa_family;
  585. if(packet_size > FAPP_BENCH_BUFFER_SIZE) /* Check max size.*/
  586. packet_size = FAPP_BENCH_BUFFER_SIZE;
  587. fapp_bench.socket_listen = SOCKET_INVALID;
  588. /* ------ Start test.----------- */
  589. fnet_shell_println(desc, FAPP_DELIMITER_STR);
  590. fnet_shell_println(desc, " UDP TX Test" );
  591. fnet_shell_println(desc, FAPP_DELIMITER_STR);
  592. fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_S, "Remote IP addr", fnet_inet_ntop(family, params->foreign_addr.sa_data, ip_str, sizeof(ip_str)));
  593. fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Remote Port", fnet_ntohs(params->foreign_addr.sa_port));
  594. fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Message Size", params->packet_size);
  595. fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Num. of messages", params->packet_number);
  596. fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Num. of iterations", params->iteration_number);
  597. fnet_shell_println(desc, FAPP_TOCANCEL_STR);
  598. fnet_shell_println(desc, FAPP_DELIMITER_STR);
  599. while(iterations--)
  600. {
  601. /* Create socket */
  602. if((fapp_bench.socket_foreign = socket(family, SOCK_DGRAM, 0)) == SOCKET_INVALID)
  603. {
  604. FNET_DEBUG("BENCH: Socket creation error.\n");
  605. iterations = 0;
  606. goto ERROR_1;
  607. }
  608. /* Set Socket options. */
  609. if( /* Setup linger option. */
  610. (setsockopt (fapp_bench.socket_foreign, SOL_SOCKET, SO_LINGER, (char *)&linger_option, sizeof(linger_option)) == SOCKET_ERROR) ||
  611. /* Set socket buffer size. */
  612. (setsockopt(fapp_bench.socket_foreign, SOL_SOCKET, SO_RCVBUF, (char *) &bufsize_option, sizeof(bufsize_option))== SOCKET_ERROR) ||
  613. (setsockopt(fapp_bench.socket_foreign, SOL_SOCKET, SO_SNDBUF, (char *) &bufsize_option, sizeof(bufsize_option))== SOCKET_ERROR)
  614. )
  615. {
  616. FNET_DEBUG("BENCH: Socket setsockopt error.\n");
  617. iterations = 0;
  618. goto ERROR_2;
  619. }
  620. /* Bind to the server.*/
  621. fnet_shell_println(desc,"Connecting.");
  622. foreign_addr = params->foreign_addr;
  623. if(connect(fapp_bench.socket_foreign, &foreign_addr, sizeof(foreign_addr))== FNET_ERR)
  624. {
  625. fnet_shell_println(desc, "Connection failed.");
  626. iterations = 0;
  627. goto ERROR_2;
  628. }
  629. /* Sending.*/
  630. fnet_shell_println(desc,"Sending.");
  631. fapp_bench.bytes = 0;
  632. fapp_bench.remote_bytes = 0;
  633. cur_packet_number = 0;
  634. fapp_bench.first_time = fnet_timer_ticks();
  635. while(1)
  636. {
  637. send_result = send( fapp_bench.socket_foreign, (char*)(&fapp_bench.buffer[0]), packet_size, 0);
  638. fapp_bench.last_time = fnet_timer_ticks();
  639. if ( send_result == SOCKET_ERROR )
  640. {
  641. option_len = sizeof(sock_err);
  642. getsockopt(fapp_bench.socket_foreign, SOL_SOCKET, SO_ERROR, (char*)&sock_err, &option_len);
  643. fnet_shell_println(desc, "socket_error = %d", sock_err);
  644. iterations = 0;
  645. goto ERROR_2;
  646. }
  647. else
  648. {
  649. fapp_bench.bytes += send_result;
  650. cur_packet_number ++;
  651. exit_flag = fnet_shell_ctrlc (desc); /* Check [Ctrl+c]*/
  652. if((cur_packet_number >= params->packet_number)|| exit_flag)
  653. {
  654. if(exit_flag)
  655. {
  656. fnet_shell_println(desc, FAPP_SHELL_CANCELED_CTRL_C);
  657. iterations = 0;
  658. }
  659. break;/* => TX END. */
  660. }
  661. }
  662. }
  663. /* Send End mark.*/
  664. for(i=0; i < FAPP_BENCH_TX_UDP_END_ITERATIONS; i++)
  665. {
  666. unsigned long ack_bytes;
  667. /* Send END mark.*/
  668. send( fapp_bench.socket_foreign, (char*)(&fapp_bench.buffer[0]), 1, 0);
  669. fnet_timer_delay(1);
  670. /* Check ACK. It should contain recieved amount of data.*/
  671. received = recv(fapp_bench.socket_foreign, (char*)(&ack_bytes), sizeof(ack_bytes), 0);
  672. if(received == sizeof(ack_bytes)) /* ACK received.*/
  673. {
  674. fapp_bench.remote_bytes = fnet_ntohl(ack_bytes);
  675. break;
  676. }
  677. else if(received == SOCKET_ERROR)
  678. {
  679. break;
  680. }
  681. }
  682. /* Print benchmark results.*/
  683. fapp_bench_print_results (desc);
  684. ERROR_2:
  685. closesocket(fapp_bench.socket_foreign);
  686. }
  687. ERROR_1:
  688. fnet_shell_println(desc, FAPP_BENCH_COMPLETED_STR);
  689. }
  690. /************************************************************************
  691. * NAME: fapp_benchtx_cmd
  692. *
  693. * DESCRIPTION: Start TX Benchmark.
  694. ************************************************************************/
  695. void fapp_benchtx_cmd( fnet_shell_desc_t desc, int argc, char ** argv )
  696. {
  697. struct fapp_bench_tx_params bench_params;
  698. fnet_memset_zero(&bench_params.foreign_addr, sizeof(bench_params.foreign_addr));
  699. if(fnet_inet_ptos(argv[1], &bench_params.foreign_addr) == FNET_OK)
  700. {
  701. bench_params.desc = desc;
  702. bench_params.foreign_addr.sa_port = FAPP_BENCH_PORT;
  703. bench_params.packet_size = FAPP_BENCH_TX_PACKET_SIZE_DEFAULT;
  704. bench_params.packet_number = FAPP_BENCH_TX_PACKET_NUMBER_DEFAULT;
  705. bench_params.iteration_number = FAPP_BENCH_TX_ITERATION_NUMBER_DEFAULT;
  706. if(argc > 3)
  707. {
  708. char *p = 0;
  709. /* Packet size.*/
  710. bench_params.packet_size = (int)fnet_strtoul(argv[3], &p, 0);
  711. if ((bench_params.packet_size == 0) || (bench_params.packet_size > FAPP_BENCH_PACKET_SIZE_MAX))
  712. {
  713. fnet_shell_println(desc, FAPP_PARAM_ERR, argv[3]); /* Print error mesage. */
  714. return;
  715. }
  716. /* Number of packets.*/
  717. if(argc > 4)
  718. {
  719. bench_params.packet_number = (int)fnet_strtoul(argv[4], &p, 0);
  720. if (bench_params.packet_number == 0)
  721. {
  722. fnet_shell_println(desc, FAPP_PARAM_ERR, argv[4]); /* Print error mesage. */
  723. return;
  724. }
  725. /* Number of iterations.*/
  726. if(argc > 5)
  727. {
  728. bench_params.iteration_number = (int)fnet_strtoul(argv[5], &p, 0);
  729. if ((bench_params.iteration_number < 1) || (bench_params.iteration_number > FAPP_BENCH_TX_ITERATION_NUMBER_MAX) )
  730. {
  731. fnet_shell_println(desc, FAPP_PARAM_ERR, argv[5]); /* Print error mesage. */
  732. return;
  733. }
  734. }
  735. }
  736. }
  737. /* TCP */
  738. if((argc == 2)||(argc >= 3 && fnet_strcasecmp("tcp", argv[2]) == 0))
  739. {
  740. fapp_bench_tcp_tx (&bench_params);
  741. }
  742. /* UDP */
  743. else if(argc >= 3 && fnet_strcasecmp("udp", argv[2]) == 0)
  744. {
  745. fapp_bench_udp_tx (&bench_params);
  746. }
  747. else
  748. {
  749. fnet_shell_println(desc, FAPP_PARAM_ERR, argv[2]);
  750. }
  751. }
  752. else
  753. {
  754. fnet_shell_println(desc, FAPP_PARAM_ERR, argv[1]); /* Wrong Benchmark Server IP address. */
  755. return;
  756. }
  757. }
  758. #endif /* FAPP_CFG_BENCH_CMD */