luat_lib_iperf.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. @module iperf
  3. @summary 吞吐量测试
  4. @catalog 网络API
  5. @version 1.0
  6. @date 2025.02.14
  7. @tag LUAT_USE_IPERF
  8. @usage
  9. -- 本库仅部分模组固件已添加
  10. -- 当前仅支持server模式, client模式未添加
  11. */
  12. #include "luat_base.h"
  13. #include "luat_lwiperf.h"
  14. #include "luat_network_adapter.h"
  15. #include "luat_netdrv.h"
  16. #include "luat_msgbus.h"
  17. #include "lwip/ip.h"
  18. #define LUAT_LOG_TAG "iperf"
  19. #include "luat_log.h"
  20. static void* iperf_session;
  21. static int l_iperf_report_handle(lua_State*L, void* ptr) {
  22. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  23. uint32_t bytes_transferred, ms_duration, bandwidth;
  24. bytes_transferred = msg->arg1;
  25. ms_duration = msg->arg2;
  26. bandwidth = (int)ptr;
  27. lua_getglobal(L, "sys_pub");
  28. lua_pushstring(L, "IPERF_REPORT");
  29. lua_pushinteger(L, bytes_transferred);
  30. lua_pushinteger(L, ms_duration);
  31. lua_pushinteger(L, bandwidth);
  32. LLOGD("report bytes %ld ms_duration %ld bandwidth %ld kbps", bytes_transferred, ms_duration, bandwidth);
  33. lua_call(L, 4, 0);
  34. return 0;
  35. }
  36. static void iperf_report_cb(void *arg, enum lwiperf_report_type report_type,
  37. const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
  38. u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec) {
  39. rtos_msg_t msg = {0};
  40. msg.arg1 = bytes_transferred;
  41. msg.arg2 = ms_duration;
  42. msg.ptr = (void*)bandwidth_kbitpsec;
  43. msg.handler = l_iperf_report_handle;
  44. luat_msgbus_put(&msg, 0);
  45. }
  46. static int start_gogogo(int adpater_id, int is_server, const ip_addr_t* remote_ip) {
  47. char buff[64] = {0};
  48. char buff2[64] = {0};
  49. if (adpater_id < 0 || adpater_id >= NW_ADAPTER_INDEX_LWIP_NETIF_QTY) {
  50. // 必须明确指定合法的索引号
  51. LLOGE("非法的网络适配器索引号 %d", adpater_id);
  52. return 0;
  53. }
  54. // 首先, 通过netdrv获取对应的网络设备的netif
  55. luat_netdrv_t* drv = luat_netdrv_get(adpater_id);
  56. if (drv == NULL || drv->netif == NULL) {
  57. LLOGE("非法的网络适配器索引号 %d", adpater_id);
  58. return 0;
  59. }
  60. if (!netif_is_up(drv->netif) || !netif_is_link_up(drv->netif) || ip_addr_isany(&drv->netif->ip_addr)) {
  61. LLOGE("该网络还没就绪, 无法启动");
  62. return 0;
  63. }
  64. ipaddr_ntoa_r(&drv->netif->ip_addr, buff, sizeof(buff));
  65. if (is_server) {
  66. iperf_session = luat_lwiperf_start_tcp_server(&drv->netif->ip_addr, 5001, iperf_report_cb, NULL);
  67. LLOGD("iperf listen %s:5001", buff);
  68. }
  69. else {
  70. ipaddr_ntoa_r(remote_ip, buff2, sizeof(buff2));
  71. luat_lwiperf_start_tcp_client(remote_ip, 5001, LWIPERF_CLIENT, iperf_report_cb, NULL, &drv->netif->ip_addr);
  72. LLOGD("iperf connect %s --> %s:5001", buff, buff2);
  73. }
  74. return iperf_session != NULL;
  75. }
  76. /*
  77. 启动server模式
  78. @api iperf.server(id)
  79. @int 网络适配器的id, 必须填, 例如 socket.LWIP_ETH0
  80. @return boolean 成功返回true, 失败返回false
  81. @usage
  82. -- 启动server模式, 监听5001端口
  83. if iperf then
  84. log.info("启动iperf服务器端")
  85. iperf.server(socket.LWIP_ETH)
  86. end
  87. */
  88. static int l_iperf_server(lua_State *L) {
  89. if (iperf_session != NULL) {
  90. LLOGE("已经启动了server或者client,要先关掉才能启动新的");
  91. return 0;
  92. }
  93. int adpater_id = luaL_checkinteger(L, 1);
  94. if (start_gogogo(adpater_id, 1, NULL)) {
  95. lua_pushboolean(L, 1);
  96. return 1;
  97. }
  98. return 0;
  99. }
  100. static int l_iperf_client(lua_State *L) {
  101. ip_addr_t remote_ip = {0};
  102. if (iperf_session != NULL) {
  103. LLOGE("已经启动了server或者client,要先关掉才能启动新的");
  104. return 0;
  105. }
  106. int adpater_id = luaL_checkinteger(L, 1);
  107. const char* ip = luaL_checkstring(L, 2);
  108. if (ipaddr_aton(ip, &remote_ip) == 0) {
  109. LLOGE("非法的ip地址 %s", ip);
  110. return 0;
  111. }
  112. if (start_gogogo(adpater_id, 0, &remote_ip)) {
  113. lua_pushboolean(L, 1);
  114. return 1;
  115. }
  116. return 0;
  117. }
  118. /*
  119. 关闭iperf
  120. @api iperf.abort()
  121. @return boolean 成功返回true, 失败返回false
  122. @usage
  123. -- 关闭已经启动的server或者client
  124. */
  125. static int l_iperf_abort(lua_State *L) {
  126. if (iperf_session == NULL) {
  127. return 0;
  128. }
  129. luat_lwiperf_abort(iperf_session);
  130. iperf_session = NULL;
  131. lua_pushboolean(L, 1);
  132. return 1;
  133. }
  134. #include "rotable2.h"
  135. static const rotable_Reg_t reg_iperf[] =
  136. {
  137. { "server" , ROREG_FUNC(l_iperf_server)},
  138. { "client" , ROREG_FUNC(l_iperf_client)},
  139. { "abort" , ROREG_FUNC(l_iperf_abort)},
  140. { NULL, ROREG_INT(0)}
  141. };
  142. LUAMOD_API int luaopen_iperf( lua_State *L ) {
  143. luat_newlib2(L, reg_iperf);
  144. return 1;
  145. }