luat_lib_icmp.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. @module icmp
  3. @summary ICMP协议(PING)
  4. @version 1.0
  5. @date 2024.010.15
  6. @demo icmp
  7. @tag LUAT_USE_NETWORK
  8. @usage
  9. -- 等网络就绪后, 初始化icmp库
  10. icmp.setup(socket.LWIP_GP)
  11. -- 执行ping,等待回应
  12. icmp.ping(socket.LWIP_GP, "183.2.172.177")
  13. -- 等待结果
  14. sys.waitUnitl("PING_RESULT", 3000)
  15. -- 详细用法请看demo
  16. */
  17. #include "luat_base.h"
  18. #include "luat_icmp.h"
  19. #include "luat_network_adapter.h"
  20. #include "luat_msgbus.h"
  21. #include "lwip/ip_addr.h"
  22. #include "lwip/tcpip.h"
  23. #include "rotable2.h"
  24. #define LUAT_LOG_TAG "icmp"
  25. #include "luat_log.h"
  26. typedef struct ping_result
  27. {
  28. uint8_t adapter_id;
  29. uint32_t addr;
  30. uint32_t t_used;
  31. }ping_result_t;
  32. static int l_icmp_handler(lua_State *L, void* ptr) {
  33. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  34. luat_icmp_ctx_t* ctx = (luat_icmp_ctx_t*)msg->ptr;
  35. lua_getglobal(L, "sys_pub");
  36. char buff[64] = {0};
  37. if (ctx) {
  38. ipaddr_ntoa_r(&ctx->dst, buff, sizeof(buff));
  39. }
  40. if (lua_isfunction(L, -1)) {
  41. lua_pushstring(L, "PING_RESULT");
  42. lua_pushinteger(L, (msg->arg1 >> 16) & 0xFFFF);
  43. lua_pushinteger(L, (msg->arg1 >> 0) & 0xFFFF);
  44. lua_pushstring(L, buff);
  45. lua_call(L, 4, 0);
  46. }
  47. return 0;
  48. }
  49. static void l_icmp_cb(void* _ctx, uint32_t tused) {
  50. if (_ctx == NULL) {
  51. return;
  52. }
  53. luat_icmp_ctx_t* ctx = (luat_icmp_ctx_t*)_ctx;
  54. rtos_msg_t msg = {
  55. .handler = l_icmp_handler,
  56. .ptr = ctx,
  57. .arg1 = ctx->adapter_id << 16 | (tused & 0xFFFF),
  58. .arg2 = 0
  59. };
  60. luat_msgbus_put(&msg, 0);
  61. }
  62. /*
  63. 初始化指定网络设备的icmp
  64. @api icmp.setup(id)
  65. @int 网络适配器的id
  66. @return bool 成功与否
  67. @usage
  68. -- 初始化4G网络的icmp, 要等4G联网后才能调用
  69. icmp.setup(socket.LWIP_GP)
  70. */
  71. int l_icmp_setup(lua_State *L) {
  72. int id = luaL_checkinteger(L, 1);
  73. luat_icmp_ctx_t* ctx = luat_icmp_init(id);
  74. if (ctx != NULL) {
  75. ctx->cb = l_icmp_cb;
  76. }
  77. lua_pushboolean(L, ctx != NULL);
  78. return 1;
  79. }
  80. /*
  81. 发起ping(异步的)
  82. @api icmp.ping(id, ip, len)
  83. @int 网络适配器的id
  84. @string 目标ip地址,不支持域名!!
  85. @int ping包大小,默认128字节,可以不传
  86. @return bool 成功与否, 仅代表发送与否,不代表服务器已经响应
  87. @usage
  88. sys.taskInit(function()
  89. sys.waitUntil("IP_READY")
  90. sys.wait(1000)
  91. icmp.setup(socket.LWIP_GP)
  92. while 1 do
  93. icmp.ping(socket.LWIP_GP, "121.14.77.221")
  94. sys.waitUntil("PING_RESULT", 3000)
  95. sys.wait(3000)
  96. end
  97. end)
  98. sys.subscribe("PING_RESULT", function(id, time, dst)
  99. log.info("ping", id, time, dst);
  100. end)
  101. */
  102. int l_icmp_ping(lua_State *L) {
  103. int id = luaL_checkinteger(L, 1);
  104. luat_icmp_ctx_t* ctx = luat_icmp_get(id);
  105. if (ctx == NULL) {
  106. ctx = luat_icmp_init(id);
  107. if (ctx == NULL) {
  108. LLOGW("icmp初始化失败");
  109. return 0;
  110. }
  111. ctx->cb = l_icmp_cb;
  112. }
  113. const char* ip = luaL_checkstring(L, 2);
  114. ctx->len = luaL_optinteger(L, 3, 128);
  115. if (0 == ipaddr_aton(ip, &ctx->tmpdst)) {
  116. LLOGW("目标地址非法 %s", ip);
  117. return 0;
  118. };
  119. int result = tcpip_callback_with_block(luat_icmp_ping, ctx, 1);
  120. if (result) {
  121. LLOGW("luat_icmp_ping/tcpip_callback_with_block result %d", result);
  122. }
  123. lua_pushinteger(L, result == 0);
  124. return 1;
  125. }
  126. static int l_icmp_debug(lua_State *L) {
  127. extern uint8_t g_icmp_debug;
  128. g_icmp_debug = lua_toboolean(L, 1);
  129. lua_pushboolean(L, g_icmp_debug);
  130. return 1;
  131. }
  132. static const rotable_Reg_t reg_icmp[] =
  133. {
  134. { "setup" , ROREG_FUNC(l_icmp_setup)},
  135. { "ping" , ROREG_FUNC(l_icmp_ping)},
  136. { "debug" , ROREG_FUNC(l_icmp_debug)},
  137. // { "close" , ROREG_FUNC(l_icmp_close)},
  138. { NULL, ROREG_INT(0)}
  139. };
  140. LUAMOD_API int luaopen_icmp( lua_State *L ) {
  141. luat_newlib2(L, reg_icmp);
  142. return 1;
  143. }