跳到主要内容

多网融合

概述

YFAir8000 支持 4G、以太网、WiFi 三种网络协同工作。通过 LuatOS 的 exnetif.setproxy() API,可将主网络的上网能力桥接到其他接口,实现局域网设备共享上网。

架构设计

┌──────────────────────────────┐
│ main.lua │ ← 入口,选择模式
│ MODE_MOBILE / ETH / WIFI │
└──────────────┬───────────────┘

┌──────────┼──────────┐
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌──────────┐
│mobile │ │eth │ │wifi │
│_net.lua│ │_net.lua│ │_net.lua │
│(4G主网)│ │(以太主)│ │(WiFi主网) │
└───┬────┘ └───┬────┘ └────┬─────┘
│exnetif. │exnetif. │exnetif.
│setproxy │setproxy │setproxy
▼ ▼ ▼
┌──────────────────────────────┐
│ WiFi AP + 以太网 LAN 共享 │ ← 其他设备通过 WiFi/网线接入上网
└──────────────────────────────┘

三种网络模式

模式主网络桥接共享适用场景
MODE_MOBILE4G→ WiFi AP + 以太网 LAN移动场景、无固定宽带
MODE_ETH以太网→ WiFi AP有网线接入
MODE_WIFIWiFi STA→ WiFi AP + 以太网 LAN有 WiFi 覆盖

项目结构

04 - 多网融合/
├── main.lua # 主入口,按模式启动对应适配器
├── config.lua # 配置管理(模式定义、网络参数)
├── mobile_net.lua # 4G 主网络适配器
├── wifi_net.lua # WiFi 主网络适配器
├── eth_net.lua # 以太网主网络适配器
└── readme.md

核心代码详解

1. 配置管理 (config.lua)

定义三种模式常量及网络参数:

config.MODE_MOBILE = 1  -- 4G
config.MODE_ETH = 2 -- 以太网
config.MODE_WIFI = 3 -- WiFi

config.DEFAULT_CONFIG = {
default_mode = config.MODE_MOBILE, -- 默认4G
wifi = {
ssid = "YOUR_WIFI_SSID", password = "YOUR_WIFI_PASSWORD",
ap_ssid = "YFAir8000W_AP", ap_password = "yf123456",
},
eth = {
tp = "ch390", spi = 1, cs = 12, irq = 21,
},
priority = { [MODE_MOBILE] = 1, [MODE_ETH] = 2, [MODE_WIFI] = 3 },
}

2. 主入口 (main.lua)

根据 mode 变量启动对应适配器:

local mode = config.MODE_WIFI  -- 当前模式,可改为 MODE_MOBILE / MODE_ETH

if mode == config.MODE_MOBILE then
sys.taskInit(function() require("mobile_net").start() end)
elseif mode == config.MODE_WIFI then
sys.taskInit(function() require("wifi_net").start() end)
elseif mode == config.MODE_ETH then
sys.taskInit(function() require("eth_net").start() end)
end

3. exnetif.setproxy() 核心 API

三种模式都使用同一个 API 实现桥接:

exnetif.setproxy(local_if, upstream_if, config)
参数说明可选值
local_if局域网接口socket.LWIP_AP / socket.LWIP_ETH
upstream_if上行网络接口socket.LWIP_GP(4G) / socket.LWIP_STA(WiFi) / socket.LWIP_ETH
config接口配置SSID、密码、CH390参数等

4. 4G 主网络模式 (mobile_net.lua)

4G 连外网 → WiFi AP + 以太网 LAN 共享:

function mobile_net.start()
-- 等待 4G 就绪
while not socket.adapter() do
sys.waitUntil("IP_READY", 1000)
end

-- 4G → WiFi 热点
exnetif.setproxy(socket.LWIP_AP, socket.LWIP_GP, {
ssid = "YFAir8000W_AP", password = "yf123456",
})

-- 4G → 以太网 LAN
exnetif.setproxy(socket.LWIP_ETH, socket.LWIP_GP, {
tp = netdrv.CH390,
opts = { spi = 1, cs = 12, irq = 21 },
})
end

5. WiFi 主网络模式 (wifi_net.lua)

WiFi STA 连外网 → 以太网 LAN + WiFi AP 共享:

function wifi_net.start()
-- WiFi STA → 以太网 LAN
exnetif.setproxy(socket.LWIP_ETH, socket.LWIP_STA, {
tp = netdrv.CH390, opts = { spi = 1, cs = 12, irq = 21 },
main_adapter = { ssid = "YFSoft_IoT", password = "YFSoft1018" },
})

-- WiFi STA → WiFi AP
exnetif.setproxy(socket.LWIP_AP, socket.LWIP_STA, {
ssid = "YFAir8000W_AP", password = "yf123456",
main_adapter = { ssid = "YFSoft_IoT", password = "YFSoft1018" },
})
end

6. 以太网主网络模式 (eth_net.lua)

以太网连外网 → WiFi AP 共享:

function eth_net.start()
-- 以太网 → WiFi AP
exnetif.setproxy(socket.LWIP_AP, socket.LWIP_ETH, {
ssid = "YFAir8000W_AP", password = "yf123456",
main_adapter = {
tp = netdrv.CH390,
opts = { spi = 1, cs = 12, irq = 21 },
},
})
end

全部代码

main.lua

main.lua
PROJECT = "MultiNetTest"
VERSION = "1.0.0"

log.info("main", PROJECT, VERSION)

local config = require "config"
local mode = config.MODE_WIFI

if mode == config.MODE_MOBILE then
log.info("main", "启动4G网络作为主网络,WiFi AP + 以太网LAN共享")
local mobile_net = require "mobile_net"
sys.taskInit(function()
mobile_net.start()
end)
elseif mode == config.MODE_WIFI then
log.info("main", "启动WiFi网络作为主网络,WiFi AP + 以太网LAN共享")
local wifi_net = require "wifi_net"
sys.taskInit(function()
wifi_net.start()
end)
elseif mode == config.MODE_ETH then
log.info("main", "启动以太网作为主网络,WiFi AP共享")
local eth_net = require "eth_net"
sys.taskInit(function()
eth_net.start()
end)
end

sys.run()

config.lua

config.lua
local config = {}

config.MODE_MOBILE = 1
config.MODE_ETH = 2
config.MODE_WIFI = 3

config.MODE_NAMES = {
[config.MODE_MOBILE] = "MOBILE",
[config.MODE_ETH] = "ETH",
[config.MODE_WIFI] = "WIFI",
}

config.DEFAULT_CONFIG = {
default_mode = config.MODE_MOBILE,
wifi = {
ssid = "YOUR_WIFI_SSID",
password = "YOUR_WIFI_PASSWORD",
ap_ssid = "YFAir8000W_AP",
ap_password = "yf123456",
},
eth = {
tp = "ch390", spi = 1, cs = 12, irq = 21,
},
monitor = {
interval = 5000, timeout = 10000, max_retries = 3,
},
priority = {
[config.MODE_MOBILE] = 1,
[config.MODE_ETH] = 2,
[config.MODE_WIFI] = 3,
}
}

function config.get_wifi_config() return config.DEFAULT_CONFIG.wifi end
function config.get_eth_config() return config.DEFAULT_CONFIG.eth end
function config.get_monitor_config() return config.DEFAULT_CONFIG.monitor end
function config.get_priority_config() return config.DEFAULT_CONFIG.priority end

return config

mobile_net.lua

mobile_net.lua
local mobile_net = {}

mobile_net.STATE_DISCONNECTED = 0
mobile_net.STATE_CONNECTING = 1
mobile_net.STATE_CONNECTED = 2

local state = mobile_net.STATE_DISCONNECTED

function mobile_net.start()
if state == mobile_net.STATE_CONNECTED then
log.warn("mobile_net", "4G已连接,跳过")
return
end
state = mobile_net.STATE_CONNECTING
log.info("mobile_net", "等待4G网络就绪...")

while not socket.adapter() do
sys.waitUntil("IP_READY", 1000)
end

log.info("mobile_net", "4G网络已就绪,开始配置多网融合...")

local config = require "config"
local exnetif = require "exnetif"
local wifi_cfg = config.get_wifi_config()
local eth_cfg = config.get_eth_config()

-- 4G → WiFi 热点
local res = exnetif.setproxy(socket.LWIP_AP, socket.LWIP_GP, {
ssid = wifi_cfg.ap_ssid, password = wifi_cfg.ap_password,
})
if res then
log.info("mobile_net", "WiFi热点已开启:", wifi_cfg.ap_ssid)
else
log.warn("mobile_net", "WiFi热点开启失败")
end

-- 4G → 以太网 LAN
res = exnetif.setproxy(socket.LWIP_ETH, socket.LWIP_GP, {
tp = netdrv.CH390,
opts = { spi = eth_cfg.spi, cs = eth_cfg.cs, irq = eth_cfg.irq },
})
if res then
log.info("mobile_net", "以太网LAN已开启")
else
log.warn("mobile_net", "以太网LAN开启失败")
end

state = mobile_net.STATE_CONNECTED
log.info("mobile_net", "MODE_MOBILE 多网融合配置完成")

while true do
sys.wait(30000)
log.info("mobile_net", "4G状态:", mobile.status(), "信号:", mobile.rssi())
end
end

function mobile_net.get_state() return state end
function mobile_net.is_connected() return state == mobile_net.STATE_CONNECTED end

return mobile_net

wifi_net.lua

wifi_net.lua
local wifi_net = {}
local exnetif = require "exnetif"

wifi_net.STATE_DISCONNECTED = 0
wifi_net.STATE_CONNECTING = 1
wifi_net.STATE_CONNECTED = 2

local state = wifi_net.STATE_DISCONNECTED

function wifi_net.start()
if state == wifi_net.STATE_CONNECTED then
log.warn("wifi_net", "WiFi已连接,跳过")
return
end
state = wifi_net.STATE_CONNECTING
log.info("wifi_net", "正在启动 WiFi 主网络...")

local config = require "config"
local wifi_cfg = config.get_wifi_config()
local eth_cfg = config.get_eth_config()

-- WiFi STA → 以太网 LAN
local res = exnetif.setproxy(socket.LWIP_ETH, socket.LWIP_STA, {
tp = netdrv[eth_cfg.tp:upper()],
opts = { spi = eth_cfg.spi, cs = eth_cfg.cs, irq = eth_cfg.irq },
main_adapter = { ssid = wifi_cfg.ssid, password = wifi_cfg.password }
})
if res then
log.info("wifi_net", "以太网 LAN 已开启(桥接 WiFi)")
else
log.warn("wifi_net", "以太网 LAN 开启失败")
end

-- WiFi STA → WiFi AP
res = exnetif.setproxy(socket.LWIP_AP, socket.LWIP_STA, {
ssid = wifi_cfg.ap_ssid, password = wifi_cfg.ap_password,
main_adapter = { ssid = wifi_cfg.ssid, password = wifi_cfg.password }
})
if res then
log.info("wifi_net", "WiFi 热点已开启:", wifi_cfg.ap_ssid)
else
log.warn("wifi_net", "WiFi 热点开启失败")
end

state = wifi_net.STATE_CONNECTED
log.info("wifi_net", "MODE_WIFI 多网融合配置完成")
end

function wifi_net.get_state() return state end
function wifi_net.is_connected() return state == wifi_net.STATE_CONNECTED end

return wifi_net

eth_net.lua

eth_net.lua
local eth_net = {}

eth_net.STATE_DISCONNECTED = 0
eth_net.STATE_CONNECTING = 1
eth_net.STATE_CONNECTED = 2

local state = eth_net.STATE_DISCONNECTED

function eth_net.start()
if state == eth_net.STATE_CONNECTED then
log.warn("eth_net", "以太网已连接,跳过")
return
end
state = eth_net.STATE_CONNECTING
log.info("eth_net", "正在启动以太网...")

local config = require "config"
local exnetif = require "exnetif"
local wifi_cfg = config.get_wifi_config()

-- 以太网 → WiFi AP
local res = exnetif.setproxy(socket.LWIP_AP, socket.LWIP_ETH, {
ssid = wifi_cfg.ap_ssid,
password = wifi_cfg.ap_password,
main_adapter = {
tp = netdrv.CH390,
opts = { spi = config.get_eth_config().spi,
cs = config.get_eth_config().cs,
irq = config.get_eth_config().irq },
}
})

if res then
log.info("eth_net", "WIFI AP 设置成功(桥接以太网)", wifi_cfg.ap_ssid)
else
log.error("eth_net", "WIFI 热点开启失败")
end

state = eth_net.STATE_CONNECTED
log.info("eth_net", "MODE_ETH 多网融合配置完成")
end

function eth_net.get_state() return state end
function eth_net.is_connected() return state == eth_net.STATE_CONNECTED end

return eth_net