多网融合
概述
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_MOBILE | 4G | → WiFi AP + 以太网 LAN | 移动场景、无固定宽带 |
| MODE_ETH | 以太网 | → WiFi AP | 有网线接入 |
| MODE_WIFI | WiFi 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