Просмотр исходного кода

add: netdrv,支持监听socket的事件

https://gitee.com/openLuat/LuatOS/issues/ICN3ZD
Wendal Chen 6 месяцев назад
Родитель
Сommit
d3a458596a

+ 26 - 0
components/network/adapter/luat_network_adapter.c

@@ -13,6 +13,11 @@
 #define LWIP_NUM_SOCKETS 8
 #endif
 
+#ifdef LUAT_USE_NETDRV
+#include "luat_netdrv.h"
+#include "luat_netdrv_event.h"
+#endif
+
 typedef struct
 {
 #ifdef LUAT_USE_LWIP
@@ -1089,6 +1094,13 @@ static int32_t network_default_socket_callback(void *data, void *param)
 	int i;
 	network_ctrl_t *ctrl = (network_ctrl_t *)event->Param3;
 
+	// 插入几个事件回调
+	if (event->ID != 0 && ctrl) {
+		#ifdef LUAT_USE_NETDRV
+		luat_netdrv_fire_socket_event_netctrl(event->ID, ctrl);
+		#endif
+	}
+
 	if (event->ID > EV_NW_TIMEOUT)
 	{
 		if (ctrl && ((event->ID == EV_NW_DNS_RESULT) || (ctrl->tag == cb_param->tag)))
@@ -1384,6 +1396,12 @@ network_ctrl_t *network_alloc_ctrl(uint8_t adapter_index)
 	}
 	OS_UNLOCK;
 	if (i >= adapter->opt->max_socket_num) {DBG_ERR("adapter no more ctrl!");}
+	#ifdef LUAT_USE_NETDRV
+	if (ctrl) {
+		extern void luat_netdrv_fire_socket_event_netctrl(uint32_t event_id, network_ctrl_t* ctrl);
+		luat_netdrv_fire_socket_event_netctrl(0x81 + EV_NW_RESET, ctrl);
+	}
+	#endif // LUAT_USE_NETDRV
 	return ctrl;
 }
 
@@ -1400,6 +1418,10 @@ void network_release_ctrl(network_ctrl_t *ctrl)
 	{
 		if (&adapter->ctrl_table[i] == ctrl)
 		{
+			#ifdef LUAT_USE_NETDRV
+			extern void luat_netdrv_fire_socket_event_netctrl(uint32_t event_id, network_ctrl_t* ctrl);
+			luat_netdrv_fire_socket_event_netctrl(0x82 + EV_NW_RESET, ctrl);
+			#endif
 			network_deinit_tls(ctrl);
 			if (ctrl->timer)
 			{
@@ -1577,6 +1599,10 @@ int network_socket_connect(network_ctrl_t *ctrl, luat_ip_addr_t *remote_ip)
 		local_port += 50000 + adapter->port + offset * 10;
 		DBG("network %d local port auto select %u",offset, local_port);
 	}
+	#ifdef LUAT_USE_NETDRV
+	extern void luat_netdrv_fire_socket_event_netctrl(uint32_t event_id, network_ctrl_t* ctrl);
+	luat_netdrv_fire_socket_event_netctrl(0x83 + EV_NW_RESET, ctrl);
+	#endif
 	return adapter->opt->socket_connect(ctrl->socket_id, ctrl->tag, local_port, remote_ip, ctrl->remote_port, adapter->user_data);
 }
 

+ 168 - 9
components/network/netdrv/binding/luat_lib_netdrv.c

@@ -368,6 +368,171 @@ end)
 */
 extern int l_icmp_ping(lua_State *L);
 
+static int s_socket_evt_ref[NW_ADAPTER_QTY] = {0};
+
+static int l_socket_evt_cb(lua_State *L, void* ptr) {
+    rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
+    netdrv_tcp_evt_t* evt = (netdrv_tcp_evt_t*)ptr;
+    int ref = s_socket_evt_ref[evt->id];
+    if (ref == 0) {
+        LLOGW("socket evt cb no lua ref");
+        luat_heap_free(ptr);
+        return 0;
+    }
+    // LLOGD("socket evt cb %d %d lua function %d", evt->id, evt->flags, ref);
+    // 取出函数
+    lua_geti(L, LUA_REGISTRYINDEX, ref);
+    if (!lua_isfunction(L, -1)) {
+        LLOGW("socket evt cb ref not function");
+        lua_pop(L, 1);
+        luat_heap_free(ptr);
+        return 0;
+    }
+    lua_pushinteger(L, evt->id);
+    switch (evt->flags)
+    {
+    case 0x81:
+        lua_pushstring(L, "create");
+        break;
+    case 0x82:
+        lua_pushstring(L, "release");
+        break;
+    case 0x83:
+        lua_pushstring(L, "connecting");
+        break;
+    case EV_NW_TIMEOUT - EV_NW_RESET:
+        lua_pushstring(L, "timeout");
+        break;
+    case EV_NW_SOCKET_CLOSE_OK - EV_NW_RESET:
+        lua_pushstring(L, "closed");
+        break;
+    case EV_NW_SOCKET_CONNECT_OK - EV_NW_RESET:
+        lua_pushstring(L, "connected");
+        break;
+    case EV_NW_SOCKET_REMOTE_CLOSE - EV_NW_RESET:
+        lua_pushstring(L, "remote_close");
+        break;
+    case EV_NW_SOCKET_ERROR - EV_NW_RESET:
+        lua_pushstring(L, "error");
+        break;
+    case EV_NW_DNS_RESULT - EV_NW_RESET:
+        lua_pushstring(L, "dns_result");
+        break;
+    
+    default:
+        lua_pushstring(L, "unknown");
+        break;
+    }
+    lua_newtable(L);
+    // 填充参数表, 远端ip, 远端端口, 本地ip, 本地端口
+    char buff[32] = {0};
+    char* p = ipaddr_ntoa_r(&evt->remote_ip, buff, 32);
+    lua_pushstring(L, p);
+    lua_setfield(L, -2, "remote_ip");
+
+    lua_pushinteger(L, evt->remote_port);
+    lua_setfield(L, -2, "remote_port");
+
+    // p = ipaddr_ntoa_r(&evt->local_ip, buff, 32);
+    // lua_pushstring(L, p);
+    // lua_setfield(L, -2, "local_ip");
+
+    // lua_pushinteger(L, evt->local_port);
+    // lua_setfield(L, -2, "local_port");
+
+    if (evt->domain_name[0]) {
+        lua_pushstring(L, evt->domain_name);
+        lua_setfield(L, -2, "domain_name");
+    }
+
+    lua_call(L, 3, 0);
+    // 释放内存
+    luat_heap_free(ptr);
+
+    return 0;
+}
+
+static void luat_socket_evt_cb(netdrv_tcp_evt_t* evt, void* userdata) {
+    rtos_msg_t msg = {0};
+    msg.handler = l_socket_evt_cb;
+    msg.ptr = luat_heap_malloc(sizeof(netdrv_tcp_evt_t));
+    if (msg.ptr == NULL) {
+        LLOGE("socket evt cb no mem");
+        return;
+    }
+    memcpy(msg.ptr, evt, sizeof(netdrv_tcp_evt_t));
+    luat_msgbus_put(&msg, 0);
+}
+
+// 监听socket事件
+/*
+订阅网络事件
+@api netdrv.event_subscribe(adapter_id, event_type, callback)
+@int 网络适配器的id
+@int 事件总类型, 当前支持 netdrv.EVT_SOCKET
+@function 回调函数 function(id, event, params)
+@return bool 成功与否,成功返回true,否则返回nil
+@usage
+-- 订阅socket连接状态变化事件
+netdrv.event_subscribe(socket.LWIP_ETH, netdrv.EVT_SOCKET, function(id, event, params)
+    -- id 是网络适配器id
+    -- event是事件id, 字符串类型, 
+        - create 创建socket对象
+        - release 释放socket对象
+        - connecting 正在连接
+        - connected 连接成功
+        - closed 连接关闭
+        - remote_close 远程关闭
+        - error 错误,包括一切异常错误
+        - dns_result dns解析结果, 如果remote_ip为0.0.0.0,表示解析失败
+    -- params是参数表
+        - remote_ip 远端ip地址
+        - remote_port 远端端口
+        - domain_name 远端域名,如果是通过域名连接的话, release时没有这个值, create时也没有
+    log.info("netdrv", "socket event", id, event, json.encode(params or {}))
+    if params then
+        -- params里会有remote_ip, remote_port等信息, 可按需获取
+        local remote_ip = params.remote_ip
+        local remote_port = params.remote_port
+        local domain_name = params.domain_name
+        log.info("netdrv", "socket event", "remote_ip", remote_ip, "remote_port", remote_port, "domain_name", domain_name)
+    end
+end)
+*/
+static int l_netdrv_event_subscribe(lua_State *L) {
+    int id = luaL_checkinteger(L, 1);
+    if (id < 0) {
+        return 0; // 非法id
+    }
+    luat_netdrv_t* netdrv = luat_netdrv_get(id);
+    if (netdrv == NULL || netdrv->netif == NULL) {
+        return 0;
+    }
+    int event_id = luaL_checkinteger(L, 2);
+    if (event_id == 0) {
+        if (s_socket_evt_ref[id]) {
+            luaL_unref(L, LUA_REGISTRYINDEX, s_socket_evt_ref[id]);
+            s_socket_evt_ref[id] = 0;
+        }
+        luat_netdrv_register_socket_event_cb(id, 0, NULL, NULL);
+        lua_pushboolean(L, 1);
+        return 1;
+    }
+    else if (event_id == 1) {
+        if (!lua_isfunction(L, 3)) {
+            return 0;
+        }
+        lua_pushvalue(L, 3);
+        s_socket_evt_ref[id] = luaL_ref(L, LUA_REGISTRYINDEX);
+        // LLOGD("register socket event cb %d", s_socket_evt_ref[id]);
+        luat_netdrv_register_socket_event_cb(id, 0xFF, luat_socket_evt_cb, NULL);
+        lua_pushboolean(L, 1);
+        return 1;
+    }
+    LLOGW("not support event type %d", event_id);
+    return 0;
+}
+
 #include "rotable2.h"
 static const rotable_Reg_t reg_netdrv[] =
 {
@@ -381,6 +546,7 @@ static const rotable_Reg_t reg_netdrv[] =
 
     { "ctrl",           ROREG_FUNC(l_netdrv_ctrl)},
     { "debug",          ROREG_FUNC(l_netdrv_debug)},
+    { "event_subscribe",ROREG_FUNC(l_netdrv_event_subscribe)},
 #ifdef LUAT_USE_MREPORT
     { "mreport",        ROREG_FUNC(l_mreport_config)},
 #endif
@@ -401,15 +567,8 @@ static const rotable_Reg_t reg_netdrv[] =
     //@const RESET_SOFT number 请求对网卡软复位,当前仅支持CH390H
     { "RESET_SOFT",     ROREG_INT(0x102)},
 
-    { "EVENT_TCP",      ROREG_INT(LUAT_NETDRV_EVENT_TCP)},
-    { "EVENT_UDP",      ROREG_INT(LUAT_NETDRV_EVENT_UDP)},
-    { "EVENT_DNS",      ROREG_INT(LUAT_NETDRV_EVENT_DNS)},
-
-    { "EVT_TCP_FLAG_CREATE", ROREG_INT(NETDRV_EVENT_TCP_FLAG_CREATE)},
-    { "EVT_TCP_FLAG_CONNECT", ROREG_INT(NETDRV_EVENT_TCP_FLAG_CREATE)},
-    { "EVT_TCP_FLAG_DISCONNECT", ROREG_INT(NETDRV_EVENT_TCP_FLAG_DISCONNECT)},
-    { "EVT_UDP_FLAG_CLOSE", ROREG_INT(NETDRV_EVENT_TCP_FLAG_CLOSE)},
-    { "EVT_TCP_FLAG_ERROR", ROREG_INT(NETDRV_EVENT_TCP_FLAG_ERROR)},
+    //@const EVT_SOCKET number 事件类型-socket事件
+    { "EVT_SOCKET",     ROREG_INT(1)}, // socket事件
 
 	{ NULL,             ROREG_INT(0) }
 };

+ 11 - 0
components/network/netdrv/include/luat_netdrv.h

@@ -39,6 +39,17 @@ typedef struct luat_netdrv_conf
     uint8_t irqpin;
     uint16_t mtu;
     uint8_t flags;
+    // Wireguard相关参数
+    #ifdef LUAT_USE_NETDRV_WG
+    const char* wg_private_key;
+    uint16_t wg_listen_port;
+    uint16_t wg_keepalive;
+    const char* wg_preshared_key;
+    
+    const char* wg_endpoint_key;
+    const char* wg_endpoint_ip;
+    uint16_t wg_endpoint_port;
+    #endif
 }luat_netdrv_conf_t;
 
 typedef struct luat_netdrv_statics_item

+ 3 - 8
components/network/netdrv/include/luat_netdrv_event.h

@@ -12,12 +12,6 @@ enum {
     LUAT_NETDRV_EVENT_LINK = 0x40, // 网卡连接状态变化事件
 };
 
-// TCP连接事件标志
-#define NETDRV_EVENT_TCP_FLAG_CREATE (1 << 0) // TCP连接创建
-#define NETDRV_EVENT_TCP_FLAG_CLOSE (1 << 1) // TCP连接关闭
-#define NETDRV_EVENT_TCP_FLAG_CONNECT (1 << 2) // TCP连接成功
-#define NETDRV_EVENT_TCP_FLAG_DISCONNECT (1 << 3) // TCP连接断开
-#define NETDRV_EVENT_TCP_FLAG_ERROR (1 << 4) // TCP的其他错误
 
 typedef struct netdrv_tcp_evt {
     uint8_t id; // 网络适配器ID
@@ -27,6 +21,7 @@ typedef struct netdrv_tcp_evt {
     ip_addr_t remote_ip; // 远程IP地址
     uint16_t local_port; // 本地端口
     uint16_t remote_port; // 远程端口
+    char domain_name[256]; // 解析的域名, DNS事件有效
     void* userdata; // 用户数据, 可用于回调时传递额外信息
 }netdrv_tcp_evt_t;
 
@@ -40,8 +35,8 @@ typedef struct netdrv_tcpevt_reg {
     void* userdata; // 用户数据, 可用于回调时传递额外信息
 }netdrv_tcpevt_reg_t;
 
-void luat_netdrv_fire_tcp_event(netdrv_tcp_evt_t* evt);
+void luat_netdrv_register_socket_event_cb(uint8_t id, uint32_t flags, luat_netdrv_tcp_evt_cb cb, void* userdata);
 
-void luat_netdrv_register_tcp_event_cb(uint8_t id, uint8_t flags, luat_netdrv_tcp_evt_cb cb, void* userdata);
+void luat_netdrv_fire_socket_event_netctrl(uint32_t event_id, network_ctrl_t* ctrl);
 
 #endif

+ 41 - 11
components/network/netdrv/src/luat_netdrv_event.c

@@ -4,6 +4,9 @@
 #include "luat_mem.h"
 #include "luat_mcu.h"
 
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+
 #include "luat_netdrv_event.h"
 
 #define LUAT_LOG_TAG "netdrv"
@@ -11,29 +14,56 @@
 
 netdrv_tcpevt_reg_t g_netdrv_tcpevt_regs[NW_ADAPTER_QTY] = {0};
 
-void luat_netdrv_register_tcp_event_cb(uint8_t id, uint8_t flags, luat_netdrv_tcp_evt_cb cb, void* userdata) {
+void luat_netdrv_register_socket_event_cb(uint8_t id, uint32_t evt_flags, luat_netdrv_tcp_evt_cb cb, void* userdata) {
     if (id >= NW_ADAPTER_QTY) {
         LLOGE("无效的TCP事件注册ID %d", id);
         return;
     }
-    if (flags == 0) {
+    if (evt_flags == 0) {
         g_netdrv_tcpevt_regs[id].cb = NULL;
         g_netdrv_tcpevt_regs[id].userdata = NULL;
         return;
     }
-    g_netdrv_tcpevt_regs[id].flags = flags;
+    g_netdrv_tcpevt_regs[id].flags = evt_flags;
     g_netdrv_tcpevt_regs[id].cb = cb;
     g_netdrv_tcpevt_regs[id].userdata = userdata;
-    LLOGD("注册TCP事件回调 %d, flags=0x%02X", id, flags);
+    // LLOGD("socket event cb adapter %d, flags=0x%02X userdata=%p", id, evt_flags, userdata);
 }
 
-
-__NETDRV_CODE_IN_RAM__ void luat_netdrv_fire_tcp_event(netdrv_tcp_evt_t* evt) {
-    if (evt == NULL || evt->id >= NW_ADAPTER_QTY) {
-        LLOGE("TCP事件网络适配器ID无效 %d", evt ? evt->id : -1);
+__NETDRV_CODE_IN_RAM__ void luat_netdrv_fire_socket_event_netctrl(uint32_t event_id, network_ctrl_t* ctrl) {
+    uint8_t adapter_id = ctrl->adapter_index;
+    //LLOGD("fire tcp event %08X for adapter %d", event_id, adapter_id);
+    if (event_id < EV_NW_RESET || event_id == EV_NW_SOCKET_TX_OK || event_id == EV_NW_SOCKET_RX_NEW) {
+        return; // 其他事件无视
+    }
+    if (g_netdrv_tcpevt_regs[adapter_id].cb == NULL) {
+        //LLOGD("TCP事件网络适配器ID无效 %d", adapter_id);
         return;
     }
-    if ((g_netdrv_tcpevt_regs[evt->id].flags & evt->flags) && g_netdrv_tcpevt_regs[evt->id].cb) {
-        g_netdrv_tcpevt_regs[evt->id].cb(evt, g_netdrv_tcpevt_regs[evt->id].userdata);
+    if (ctrl == NULL || adapter_id >= NW_ADAPTER_QTY || adapter_id <= 0) {
+        LLOGW("TCP事件网络适配器ID无效 %d", adapter_id);
+        return;
     }
-}
+    event_id -= EV_NW_RESET;
+    if ((g_netdrv_tcpevt_regs[adapter_id].flags & event_id) == 0) {
+        //LLOGD("TCP事件网络适配器ID无效 %d", adapter_id);
+        return;
+    }
+    netdrv_tcp_evt_t evt = {0};
+    evt.id = adapter_id;
+    evt.flags = event_id;
+    if (ctrl->domain_name && ctrl->domain_name_len > 0) {
+        strncpy(evt.domain_name, ctrl->domain_name, sizeof(evt.domain_name) - 1);
+        evt.domain_name[sizeof(evt.domain_name) - 1] = 0;
+    }
+    if (ctrl->online_ip) {
+        evt.remote_ip = *ctrl->online_ip;
+    }
+    else {
+        evt.remote_ip = ctrl->remote_ip;
+    }
+    evt.local_port = ctrl->local_port;
+    evt.remote_port = ctrl->remote_port;
+    evt.userdata = ctrl->user_data;
+    g_netdrv_tcpevt_regs[adapter_id].cb(&evt, g_netdrv_tcpevt_regs[adapter_id].userdata);
+}

+ 7 - 0
luat/demo/netdrv/ch390h/wan.lua

@@ -52,6 +52,13 @@ sys.taskInit(function()
         return 404, {}, "Not Found" .. uri
     end, socket.LWIP_ETH)
     iperf.server(socket.LWIP_ETH)
+    if netdrv.event_subscribe then
+        netdrv.event_subscribe(socket.LWIP_ETH, netdrv.EVT_SOCKET, function(id, event, params)
+            log.info("netdrv", "socket event", id, event, json.encode(params or {}))
+        end)
+    else
+        log.warn("netdrv", "not support event_subscribe")
+    end
     while 1 do
         sys.wait(6000)
         local code, headers, body = http.request("GET", "http://httpbin.air32.cn/bytes/4096", nil, nil, {adapter=socket.LWIP_ETH}).wait()