Quellcode durchsuchen

add: netdrv,napt,支持ap到eth的转换,添加air8000_airlink_wifi_eth

Wendal Chen vor 11 Monaten
Ursprung
Commit
6144e42511

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

@@ -63,6 +63,7 @@ typedef struct luat_netdrv {
     luat_netdrv_statics_t statics;
     void* userdata;
     luat_netdrv_ctrl_cb ctrl;
+    uint8_t gw_mac[6];
 }luat_netdrv_t;
 
 luat_netdrv_t* luat_netdrv_setup(luat_netdrv_conf_t *conf);

+ 30 - 0
components/network/netdrv/src/luat_netdrv_napt.c

@@ -10,6 +10,7 @@
 #include "lwip/ip.h"
 #include "lwip/etharp.h"
 #include "lwip/icmp.h"
+#include "lwip/prot/etharp.h"
 #include "luat_mcu.h"
 
 #define LUAT_LOG_TAG "netdrv.napt"
@@ -73,6 +74,35 @@ __USER_FUNC_IN_RAM__ int luat_netdrv_napt_pkg_input(int id, uint8_t* buff, size_
             return 0;
         }
         // LLOGD("ETH包 " MACFMT " -> " MACFMT " %04X", MAC_ARG(ctx.eth->src.addr), MAC_ARG(ctx.eth->dest.addr), ctx.eth->type);
+        if (ctx.eth->type == PP_HTONS(ETHTYPE_ARP)) {
+            // LLOGD("ETH包 " MACFMT " -> " MACFMT " %04X", MAC_ARG(ctx.eth->src.addr), MAC_ARG(ctx.eth->dest.addr), ctx.eth->type);
+            if (luat_netdrv_gw_adapter_id == id) {
+                // LLOGD("ETH包 " MACFMT " -> " MACFMT " %04X", MAC_ARG(ctx.eth->src.addr), MAC_ARG(ctx.eth->dest.addr), ctx.eth->type);
+                // 这是网关侧的ARP包, 需要分析是否网关的ARP包, 然后更新到本地ARP表
+                struct etharp_hdr* hdr = (struct etharp_hdr*)(buff + SIZEOF_ETH_HDR);
+                ip4_addr_t sipaddr, dipaddr;
+                // 是不是ARP回应
+                // LLOGD("ARP数据 %04X %04X", hdr->opcode, PP_HTONS(ARP_REPLY));
+                memcpy(&sipaddr, &hdr->sipaddr, 4);
+                memcpy(&dipaddr, &hdr->dipaddr, 4);
+                char tmp[16];
+                ip4addr_ntoa_r(&sipaddr, tmp, 16);
+                // LLOGD("ARP数据 %04X %04X from %s", hdr->opcode, PP_HTONS(ARP_REPLY), tmp);
+                // if (hdr->opcode == PP_HTONS(ARP_REPLY)) {
+                    // memcpy(&dipaddr, &hdr->dipaddr, 4);
+                    luat_netdrv_t* gw = luat_netdrv_get(luat_netdrv_gw_adapter_id);
+                    if (gw && gw->netif) {
+                        // LLOGD("sipaddr.addr %08X", sipaddr.addr);
+                        memcpy(gw->gw_mac, hdr->shwaddr.addr, 6);
+                        // LLOGD("网关MAC更新成功 %02X%02X%02X%02X%02X%02X", gw->gw_mac[0], gw->gw_mac[1], gw->gw_mac[2], gw->gw_mac[3], gw->gw_mac[4], gw->gw_mac[5]);
+                        // return 0;
+                    }
+                    else {
+                        // LLOGD("不是网关的ARP包? gw %p", gw);
+                    }
+                // }
+            }
+        }
         if (ctx.eth->type != PP_HTONS(ETHTYPE_IP)) {
             // LLOGD("不是IP包, 不需要执行napt");
             return 0;

+ 10 - 5
components/network/netdrv/src/luat_netdrv_napt_icmp.c

@@ -109,8 +109,8 @@ int luat_napt_icmp_handle(napt_ctx_t* ctx) {
             }
             if (dst->dataout) {
                 if (ctx->eth && dst->netif->flags & NETIF_FLAG_ETHARP) {
-                    LLOGD("输出到内网netdrv,无需额外添加eth头");
-                    dst->dataout(dst, dst->userdata, icmp_buff, ctx->len);
+                    // LLOGD("输出到内网netdrv,无需额外添加eth头");
+                    dst->dataout(dst, dst->userdata, ctx->eth, ctx->len);
                 }
                 else if (!ctx->eth && dst->netif->flags & NETIF_FLAG_ETHARP) {
                     // 需要补全一个ETH头部
@@ -202,9 +202,14 @@ int luat_napt_icmp_handle(napt_ctx_t* ctx) {
             memcpy(it->inet_mac, ctx->eth->src.addr, 6);
         }
         if (gw->netif->flags & NETIF_FLAG_ETHARP) {
-            // TODO 网关设备也是ETHARP? 还不支持
-            LLOGD("网关netdrv也是ETH, 当前不支持");
-            return 0;
+            if (ctx->eth) {
+                memcpy(ctx->eth->dest.addr, gw->gw_mac, 6);
+                gw->dataout(gw, gw->userdata, ctx->eth, ctx->len);
+            }
+            else {
+                LLOGD("网关netdrv是ETH,源网卡不是ETH, 当前不支持");
+                return 0;
+            }
         }
         else {
             if (ctx->eth) {

+ 10 - 4
components/network/netdrv/src/luat_netdrv_napt_tcp.c

@@ -173,8 +173,8 @@ int luat_napt_tcp_handle(napt_ctx_t* ctx) {
             }
             if (dst->dataout) {
                 if (ctx->eth && dst->netif->flags & NETIF_FLAG_ETHARP) {
-                    LLOGD("输出到内网netdrv,无需额外添加eth头");
-                    dst->dataout(dst, dst->userdata, tcp_buff, ctx->len);
+                    // LLOGD("输出到内网netdrv,无需额外添加eth头");
+                    dst->dataout(dst, dst->userdata, ctx->eth, ctx->len);
                 }
                 else if (!ctx->eth && dst->netif->flags & NETIF_FLAG_ETHARP) {
                     // 需要补全一个ETH头部
@@ -308,8 +308,14 @@ int luat_napt_tcp_handle(napt_ctx_t* ctx) {
         if (gw && gw->dataout && gw->netif) {
             // LLOGD("ICMP改写完成, 发送到GW");
             if (gw->netif->flags & NETIF_FLAG_ETHARP) {
-                // TODO 网关设备也是ETHARP? 还不支持
-                LLOGD("网关netdrv也是ETH, 当前不支持");
+                if (ctx->eth) {
+                    memcpy(ctx->eth->dest.addr, gw->gw_mac, 6);
+                    gw->dataout(gw, gw->userdata, ctx->eth, ctx->len);
+                }
+                else {
+                    LLOGD("网关netdrv是ETH,源网卡不是ETH, 当前不支持");
+                    return 0;
+                }
             }
             else {
                 if (ctx->eth) {

+ 10 - 4
components/network/netdrv/src/luat_netdrv_napt_udp.c

@@ -123,8 +123,8 @@ int luat_napt_udp_handle(napt_ctx_t* ctx) {
                 }
                 if (dst->dataout) {
                     if (ctx->eth && dst->netif->flags & NETIF_FLAG_ETHARP) {
-                        LLOGD("输出到内网netdrv,无需额外添加eth头");
-                        dst->dataout(dst, dst->userdata, udp_buff, ctx->len);
+                        // LLOGD("输出到内网netdrv,无需额外添加eth头");
+                        dst->dataout(dst, dst->userdata, ctx->eth, ctx->len);
                     }
                     else if (!ctx->eth && dst->netif->flags & NETIF_FLAG_ETHARP) {
                         // 需要补全一个ETH头部
@@ -244,8 +244,14 @@ int luat_napt_udp_handle(napt_ctx_t* ctx) {
         if (gw && gw->dataout && gw->netif) {
             // LLOGD("ICMP改写完成, 发送到GW");
             if (gw->netif->flags & NETIF_FLAG_ETHARP) {
-                // TODO 网关设备也是ETHARP? 还不支持
-                LLOGD("网关netdrv也是ETH, 当前不支持");
+                if (ctx->eth) {
+                    memcpy(ctx->eth->dest.addr, gw->gw_mac, 6);
+                    gw->dataout(gw, gw->userdata, ctx->eth, ctx->len);
+                }
+                else {
+                    LLOGD("网关netdrv是ETH,源网卡不是ETH, 当前不支持");
+                    return 0;
+                }
             }
             else {
                 if (ctx->eth) {

+ 2 - 6
demo/airlink/air8000_wifi/main.lua

@@ -26,10 +26,6 @@ function test_ap()
     log.info("执行AP创建操作")
     wlan.createAP("uiot5678", "12345678")
     netdrv.ipv4(socket.LWIP_AP, "192.168.4.1", "255.255.255.0", "0.0.0.0")
-    for i=1, 10 do
-        log.info("当前ip信息", netdrv.ipv4(socket.LWIP_AP))
-        sys.wait(100)
-    end
     sys.wait(5000)
     -- netdrv.ipv4(socket.LWIP_AP, "192.168.4.1", "255.255.255.0", "0.0.0.0")
     -- log.info("创建dns代理", netdrv.ipv4(socket.LWIP_AP))
@@ -50,7 +46,7 @@ sys.subscribe("WLAN_STA_INC", function(evt, data)
     -- evt 可能的值有: "CONNECTED", "DISCONNECTED"
     -- 当evt=CONNECTED, data是连接的AP的ssid, 字符串类型
     -- 当evt=DISCONNECTED, data断开的原因, 整数类型
-    log.info("收到STA事件", evt)
+    log.info("收到STA事件", evt, data)
 end)
 
 -- wifi的AP相关事件
@@ -58,7 +54,7 @@ sys.subscribe("WLAN_AP_INC", function(evt, data)
     -- evt 可能的值有: "CONNECTED", "DISCONNECTED"
     -- 当evt=CONNECTED, data是连接的AP的新STA的MAC地址
     -- 当evt=DISCONNECTED, data是断开与AP连接的STA的MAC地址
-    log.info("收到STA事件", evt)
+    log.info("收到AP事件", evt, data and data:toHex())
 end)
 
 function test_sta()

+ 143 - 0
demo/airlink/air8000_wifi_eth/main.lua

@@ -0,0 +1,143 @@
+
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "air8000_wifi"
+VERSION = "1.0.5"
+
+dnsproxy = require("dnsproxy")
+dhcpsrv = require("dhcpsrv")
+httpplus = require("httpplus")
+
+gpio.setup(140, 1, gpio.PULLUP)
+
+-- 通过boot按键方便刷Air8000S
+function PWR8000S(val)
+    gpio.set(23, val)
+end
+
+gpio.debounce(0, 1000)
+gpio.setup(0, function()
+    sys.taskInit(function()
+        log.info("复位Air8000S")
+        PWR8000S(0)
+        sys.wait(20)
+        PWR8000S(1)
+    end)
+end, gpio.PULLDOWN)
+
+function test_ap()
+    log.info("执行AP创建操作")
+    wlan.createAP("uiot5678", "12345678")
+    netdrv.ipv4(socket.LWIP_AP, "192.168.4.1", "255.255.255.0", "0.0.0.0")
+    -- for i=1, 10 do
+    --     log.info("当前ip信息", netdrv.ipv4(socket.LWIP_AP))
+    --     sys.wait(100)
+    -- end
+    sys.wait(5000)
+    -- netdrv.ipv4(socket.LWIP_AP, "192.168.4.1", "255.255.255.0", "0.0.0.0")
+    -- log.info("创建dns代理", netdrv.ipv4(socket.LWIP_AP))
+    dnsproxy.setup(socket.LWIP_AP, socket.LWIP_GP)
+    -- log.info('创建DHCP服务器', netdrv.ipv4(socket.LWIP_AP))
+    dhcpsrv.create({adapter=socket.LWIP_AP})
+    while 1 do
+        if netdrv.ready(socket.LWIP_ETH) then
+            log.info("以太网作为网关")
+            netdrv.napt(socket.LWIP_ETH)
+            break
+        end
+        sys.wait(1000)
+    end
+    icmp.setup(socket.LWIP_ETH)
+    while 1 do
+        -- 持续ping网关
+        local ip,mark,gw = netdrv.ipv4(socket.LWIP_ETH)
+        if gw then
+            log.info("ping", gw)
+            icmp.ping(socket.LWIP_ETH, gw)
+        end
+        sys.wait(3000)
+    end
+end
+
+sys.subscribe("PING_RESULT", function(id, time, dst)
+    log.info("ping.result", id, time, dst);
+end)
+
+-- wifi的AP相关事件
+sys.subscribe("WLAN_AP_INC", function(evt, data)
+    -- evt 可能的值有: "CONNECTED", "DISCONNECTED"
+    -- 当evt=CONNECTED, data是连接的AP的新STA的MAC地址
+    -- 当evt=DISCONNECTED, data是断开与AP连接的STA的MAC地址
+    log.info("收到AP事件", evt, data and data:toHex())
+end)
+
+sys.subscribe("PING_RESULT", function(id, time, dst)
+    log.info("ping", id, time, dst);
+end)
+
+--  每隔6秒打印一次airlink统计数据, 调试用
+-- sys.taskInit(function()
+--     while 1 do
+--         sys.wait(6000)
+--         airlink.statistics()
+--     end
+-- end)
+
+
+function eth_wan()
+    -- sys.wait(3000)
+    local result = spi.setup(
+        1,--串口id
+        nil,
+        0,--CPHA
+        0,--CPOL
+        8,--数据宽度
+        25600000--,--频率
+        -- spi.MSB,--高低位顺序    可选,默认高位在前
+        -- spi.master,--主模式     可选,默认主
+        -- spi.full--全双工       可选,默认全双工
+    )
+    log.info("main", "open",result)
+    if result ~= 0 then--返回值为0,表示打开成功
+        log.info("main", "spi open error",result)
+        return
+    end
+
+    netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {spi=1,cs=12})
+    netdrv.dhcp(socket.LWIP_ETH, true)
+end
+
+sys.taskInit(function()
+    eth_wan()
+    wlan.init()
+    sys.wait(300)
+    test_ap()
+end)
+
+sys.taskInit(function ()
+    -- sys.wait(3000)
+    local result = spi.setup(
+        1,--串口id
+        nil,
+        0,--CPHA
+        0,--CPOL
+        8,--数据宽度
+        25600000--,--频率
+        -- spi.MSB,--高低位顺序    可选,默认高位在前
+        -- spi.master,--主模式     可选,默认主
+        -- spi.full--全双工       可选,默认全双工
+    )
+    log.info("main", "open",result)
+    if result ~= 0 then--返回值为0,表示打开成功
+        log.info("main", "spi open error",result)
+        return
+    end
+
+    netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {spi=1,cs=12})
+    netdrv.dhcp(socket.LWIP_ETH, true)
+end)
+
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!