1136 lines
49 KiB
Lua
1136 lines
49 KiB
Lua
|
|
--[[
|
|||
|
|
@module exnetif
|
|||
|
|
@summary exnetif 控制网络优先级(以太网->WIFI->4G)根据优先级选择上网的网卡。简化开启多网融合的操作,4G作为数据出口给WIFI,以太网设备上网,以太网作为数据出口给WIFI,Air8000上网,WIFI作为数据出口给Air8000,以太网上网。
|
|||
|
|
@version 1.0
|
|||
|
|
@date 2025.06.26
|
|||
|
|
@author wjq
|
|||
|
|
@usage
|
|||
|
|
本文件的对外接口有5个:
|
|||
|
|
1、exnetif.set_priority_order(networkConfigs):设置网络优先级顺序并初始化对应网络(需要在task中调用)
|
|||
|
|
2、exnetif.notify_status(cb_fnc):设置网络状态变化回调函数
|
|||
|
|
3、exnetif.setproxy(adapter, main_adapter,other_configs):配置网络代理实现多网融合(需要在task中调用)
|
|||
|
|
4、exnetif.check_network_status(interval),检测间隔时间ms(选填),不填时只检测一次,填写后将根据间隔时间循环检测,会提高模块功耗
|
|||
|
|
5、exnetif.close(type, adapter):关闭指定网卡,内核固件版本号需>=2020
|
|||
|
|
]]
|
|||
|
|
local exnetif = {}
|
|||
|
|
|
|||
|
|
dnsproxy = require("dnsproxy")
|
|||
|
|
dhcpsrv = require("dhcpsrv")
|
|||
|
|
httpdns = require("httpdns")
|
|||
|
|
-- 设置pingip
|
|||
|
|
local wifi_ping_ip
|
|||
|
|
local eth_ping_ip
|
|||
|
|
-- 局域网模式
|
|||
|
|
local local_network_mode
|
|||
|
|
-- 是否需要通过ping来测试网络的连通性
|
|||
|
|
local need_ping = true
|
|||
|
|
-- 使用单网卡模式
|
|||
|
|
local single_network_mode = false
|
|||
|
|
-- 是否自动关闭非当前网卡socket连接
|
|||
|
|
local auto_socket_switch = true
|
|||
|
|
-- ping检测间隔时间
|
|||
|
|
local ping_time = 10000
|
|||
|
|
-- 连接状态
|
|||
|
|
local connection_states = {
|
|||
|
|
DISCONNECTED = 0,
|
|||
|
|
CONNECTING = 1,
|
|||
|
|
CONNECTED = 2,
|
|||
|
|
OPENED = 3,
|
|||
|
|
SINGLE_NETWORK = 4,
|
|||
|
|
STOPED = 5
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
-- 状态回调函数
|
|||
|
|
local states_cbfnc = function(net_type)
|
|||
|
|
end
|
|||
|
|
-- 当前优先级
|
|||
|
|
local current_priority = {socket.LWIP_ETH, socket.LWIP_STA, socket.LWIP_GP}
|
|||
|
|
-- 连接状态
|
|||
|
|
local available = {
|
|||
|
|
[socket.LWIP_STA] = connection_states.DISCONNECTED,
|
|||
|
|
[socket.LWIP_ETH] = connection_states.DISCONNECTED,
|
|||
|
|
[socket.LWIP_GP] = connection_states.DISCONNECTED,
|
|||
|
|
[socket.LWIP_USER1] = connection_states.DISCONNECTED
|
|||
|
|
}
|
|||
|
|
-- 当前使用的网卡
|
|||
|
|
local current_active = nil
|
|||
|
|
|
|||
|
|
-- 网络类型转字符串
|
|||
|
|
local function type_to_string(net_type)
|
|||
|
|
local type_map = {
|
|||
|
|
[socket.LWIP_STA] = "WiFi",
|
|||
|
|
[socket.LWIP_ETH] = "Ethernet",
|
|||
|
|
[socket.LWIP_GP] = "4G",
|
|||
|
|
[socket.LWIP_USER1] = "8101SPIETH"
|
|||
|
|
}
|
|||
|
|
return type_map[net_type] or "Unknown"
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- 保存以太网网卡参数,用于关闭spi和供电使能
|
|||
|
|
local eth_cfg = {
|
|||
|
|
[socket.LWIP_ETH] = {},
|
|||
|
|
[socket.LWIP_USER1] = {}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
-- 订阅socket连接状态变化事件,socket出现异常时修改网卡状态
|
|||
|
|
local function socket_state_detection(adapter)
|
|||
|
|
if netdrv.on then
|
|||
|
|
log.info("netdrv", "订阅socket连接状态变化事件", type_to_string(adapter))
|
|||
|
|
-- 订阅socket连接状态变化事件
|
|||
|
|
netdrv.on(adapter, netdrv.EVT_SOCKET, function(id, event, params)
|
|||
|
|
if event == "timeout" or event == "error" then
|
|||
|
|
if available[adapter] == connection_states.CONNECTED then
|
|||
|
|
available[adapter] = connection_states.CONNECTING
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
-- 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)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- 状态更改后重新设置默认网卡
|
|||
|
|
local function apply_priority()
|
|||
|
|
local usable = false
|
|||
|
|
-- 查找优先级最高的可用网络
|
|||
|
|
for _, net_type in ipairs(current_priority) do
|
|||
|
|
-- log.info("网卡顺序",type_to_string(net_type),available[net_type])
|
|||
|
|
if available[net_type] == connection_states.CONNECTED then
|
|||
|
|
usable = true
|
|||
|
|
-- 设置优先级高的网卡
|
|||
|
|
if current_active ~= net_type then
|
|||
|
|
log.info("设置网卡", type_to_string(net_type))
|
|||
|
|
states_cbfnc(type_to_string(net_type), net_type) -- 默认网卡改变的回调函数
|
|||
|
|
socket.dft(net_type)
|
|||
|
|
if auto_socket_switch and socket.close_all then
|
|||
|
|
socket.close_all(current_active)
|
|||
|
|
end
|
|||
|
|
current_active = net_type
|
|||
|
|
end
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- 从存在可用网卡到没有可用网卡,才通知回调
|
|||
|
|
if usable == false and current_active ~= nil then
|
|||
|
|
-- 避免重复通知
|
|||
|
|
current_active = nil
|
|||
|
|
states_cbfnc(nil, -1)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- httpdns域名解析测试
|
|||
|
|
local function http_dnstest(adaptertest)
|
|||
|
|
local ip = httpdns.ali("baidu.com", {
|
|||
|
|
adapter = adaptertest,
|
|||
|
|
timeout = 3000
|
|||
|
|
})
|
|||
|
|
if ip ~= nil then
|
|||
|
|
available[adaptertest] = connection_states.CONNECTED
|
|||
|
|
log.info(type_to_string(adaptertest) .. "网卡httpdns域名解析成功")
|
|||
|
|
else
|
|||
|
|
log.info(type_to_string(adaptertest) .. "网卡httpdns域名解析失败")
|
|||
|
|
end
|
|||
|
|
log.info("httpdns", "baidu.com", ip)
|
|||
|
|
end
|
|||
|
|
-- ping操作
|
|||
|
|
local function ping_request(adaptertest)
|
|||
|
|
log.info("dns_request", type_to_string(adaptertest), need_ping)
|
|||
|
|
if need_ping then
|
|||
|
|
if adaptertest == socket.LWIP_ETH or adaptertest == socket.LWIP_USER1 then
|
|||
|
|
if eth_ping_ip == nil then
|
|||
|
|
http_dnstest(adaptertest)
|
|||
|
|
else
|
|||
|
|
icmp.setup(adaptertest)
|
|||
|
|
icmp.ping(adaptertest, eth_ping_ip)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
if adaptertest == socket.LWIP_STA then
|
|||
|
|
if wifi_ping_ip == nil then
|
|||
|
|
http_dnstest(adaptertest)
|
|||
|
|
else
|
|||
|
|
icmp.setup(adaptertest)
|
|||
|
|
icmp.ping(adaptertest, wifi_ping_ip)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
if adaptertest == socket.LWIP_GP then
|
|||
|
|
if eth_ping_ip ~= nil then
|
|||
|
|
icmp.setup(adaptertest)
|
|||
|
|
icmp.ping(adaptertest, eth_ping_ip)
|
|||
|
|
elseif wifi_ping_ip ~= nil then
|
|||
|
|
icmp.setup(adaptertest)
|
|||
|
|
icmp.ping(adaptertest, wifi_ping_ip)
|
|||
|
|
else
|
|||
|
|
http_dnstest(adaptertest)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
else
|
|||
|
|
log.info(type_to_string(adaptertest) .. "配置了不需要ping,直接切换为CONNECTED状态")
|
|||
|
|
available[adaptertest] = connection_states.CONNECTED
|
|||
|
|
end
|
|||
|
|
apply_priority()
|
|||
|
|
end
|
|||
|
|
-- 网卡上线回调函数
|
|||
|
|
local function ip_ready_handle(ip, adapter)
|
|||
|
|
local _, _, gw = socket.localIP(adapter)
|
|||
|
|
log.info("ip_ready_handle", ip, type_to_string(adapter), "state", available[adapter], "gw", gw)
|
|||
|
|
if local_network_mode then
|
|||
|
|
if adapter == socket.LWIP_ETH or adapter == socket.LWIP_USER1 then
|
|||
|
|
eth_ping_ip = gw
|
|||
|
|
elseif adapter == socket.LWIP_STA then
|
|||
|
|
wifi_ping_ip = gw
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
log.info("eth_ping_ip", eth_ping_ip, "wifi_ping_ip", wifi_ping_ip)
|
|||
|
|
-- 需要ping操作,ping通后认为网络可用
|
|||
|
|
if available[adapter] == connection_states.OPENED then
|
|||
|
|
available[adapter] = connection_states.CONNECTING
|
|||
|
|
end
|
|||
|
|
-- ping_request(adapter)
|
|||
|
|
end
|
|||
|
|
-- 网卡下线回调函数
|
|||
|
|
local function ip_lose_handle(adapter)
|
|||
|
|
log.info("ip_lose_handle", type_to_string(adapter))
|
|||
|
|
if available[adapter] == connection_states.CONNECTING or available[adapter] == connection_states.CONNECTED then
|
|||
|
|
available[adapter] = connection_states.OPENED
|
|||
|
|
end
|
|||
|
|
if current_active == adapter then
|
|||
|
|
log.info(type_to_string(adapter) .. " 失效,切换到其他网络")
|
|||
|
|
apply_priority()
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
local interval_time = nil
|
|||
|
|
|
|||
|
|
--[[
|
|||
|
|
对正常状态的网卡进行ping测试
|
|||
|
|
@api exnetif.check_network_status(interval),
|
|||
|
|
@int 检测间隔时间ms(选填),不填时只检测一次,填写后将根据间隔时间循环检测,会提高模块功耗
|
|||
|
|
]]
|
|||
|
|
function exnetif.check_network_status(interval)
|
|||
|
|
if interval ~= nil then
|
|||
|
|
interval_time = interval
|
|||
|
|
end
|
|||
|
|
for _, net_type in ipairs(current_priority) do
|
|||
|
|
if available[net_type] == connection_states.CONNECTED then
|
|||
|
|
available[net_type] = connection_states.CONNECTING
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- 打开以太网Wan功能
|
|||
|
|
local function setup_eth(config)
|
|||
|
|
if config.local_network_mode then
|
|||
|
|
local_network_mode = true
|
|||
|
|
end
|
|||
|
|
if config.need_ping ~= nil then
|
|||
|
|
need_ping = config.need_ping
|
|||
|
|
end
|
|||
|
|
if config.auto_socket_switch ~= nil then
|
|||
|
|
auto_socket_switch = config.auto_socket_switch
|
|||
|
|
-- log.info("设置自动关闭非当前网卡socket连接", auto_socket_switch)
|
|||
|
|
end
|
|||
|
|
eth_ping_ip = config.ping_ip
|
|||
|
|
if type(config.ping_time) == "number" then
|
|||
|
|
ping_time = config.ping_time
|
|||
|
|
end
|
|||
|
|
log.info("初始化以太网")
|
|||
|
|
if not single_network_mode then
|
|||
|
|
available[socket.LWIP_ETH] = connection_states.OPENED
|
|||
|
|
else
|
|||
|
|
available[socket.LWIP_ETH] = connection_states.SINGLE_NETWORK
|
|||
|
|
end
|
|||
|
|
-- 打开CH390供电
|
|||
|
|
if config.pwrpin then
|
|||
|
|
gpio.setup(config.pwrpin, 1, gpio.PULLUP)
|
|||
|
|
end
|
|||
|
|
-- sys.wait(100) -- 等待以太网模块上电稳定
|
|||
|
|
if config.tp == nil then
|
|||
|
|
log.info("8101以太网")
|
|||
|
|
if netdrv.setup(socket.LWIP_ETH) == false then
|
|||
|
|
log.error("以太网初始化失败")
|
|||
|
|
if config.pwrpin then
|
|||
|
|
gpio.close(config.pwrpin)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
else
|
|||
|
|
log.info("config.opts.spi", config.opts.spi, ",config.type", config.tp)
|
|||
|
|
-- 配置SPI和初始化网络驱动
|
|||
|
|
local result = spi.setup(config.opts.spi, -- spi id
|
|||
|
|
nil, 0, -- CPHA
|
|||
|
|
0, -- CPOL
|
|||
|
|
8, -- 数据宽度
|
|||
|
|
25600000 -- ,--波特率
|
|||
|
|
)
|
|||
|
|
log.info("main", "open spi", result)
|
|||
|
|
if result ~= 0 then -- 返回值为0,表示打开成功
|
|||
|
|
log.info("main", "spi open error", result)
|
|||
|
|
if config.pwrpin then
|
|||
|
|
gpio.close(config.pwrpin)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
-- 初始化指定netdrv设备,
|
|||
|
|
-- socket.LWIP_ETH 网络适配器编号
|
|||
|
|
-- netdrv.CH390外挂CH390
|
|||
|
|
-- SPI ID 1, 片选 GPIO12
|
|||
|
|
if netdrv.setup(socket.LWIP_ETH, config.tp, config.opts) == false then
|
|||
|
|
log.error("以太网初始化失败")
|
|||
|
|
if config.pwrpin then
|
|||
|
|
gpio.close(config.pwrpin)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
if config.static_ip then
|
|||
|
|
sys.wait(1000) -- 等待以太网模块初始化完成,去掉会导致以太网初始化失败
|
|||
|
|
log.info("netdrv", "自定义以太网IP地址", config.static_ip.ipv4)
|
|||
|
|
log.info("静态ip",
|
|||
|
|
netdrv.ipv4(socket.LWIP_ETH, config.static_ip.ipv4, config.static_ip.mark, config.static_ip.gw))
|
|||
|
|
else
|
|||
|
|
netdrv.dhcp(socket.LWIP_ETH, true)
|
|||
|
|
end
|
|||
|
|
log.info("以太网初始化完成")
|
|||
|
|
socket_state_detection(socket.LWIP_ETH)
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- 打开8101spi以太网Wan功能
|
|||
|
|
local function setup_eth_user1(config)
|
|||
|
|
if config.local_network_mode then
|
|||
|
|
local_network_mode = true
|
|||
|
|
end
|
|||
|
|
if config.need_ping ~= nil then
|
|||
|
|
need_ping = config.need_ping
|
|||
|
|
end
|
|||
|
|
if config.auto_socket_switch ~= nil then
|
|||
|
|
auto_socket_switch = config.auto_socket_switch
|
|||
|
|
-- log.info("设置自动关闭非当前网卡socket连接", auto_socket_switch)
|
|||
|
|
end
|
|||
|
|
eth_ping_ip = config.ping_ip
|
|||
|
|
if type(config.ping_time) == "number" then
|
|||
|
|
ping_time = config.ping_time
|
|||
|
|
end
|
|||
|
|
log.info("初始化以太网")
|
|||
|
|
if not single_network_mode then
|
|||
|
|
available[socket.LWIP_USER1] = connection_states.OPENED
|
|||
|
|
else
|
|||
|
|
available[socket.LWIP_USER1] = connection_states.SINGLE_NETWORK
|
|||
|
|
end
|
|||
|
|
-- 打开CH390供电
|
|||
|
|
if config.pwrpin then
|
|||
|
|
gpio.setup(config.pwrpin, 1, gpio.PULLUP)
|
|||
|
|
end
|
|||
|
|
-- sys.wait(100)-- 等待以太网模块上电稳定
|
|||
|
|
log.info("config.opts.spi", config.opts.spi, ",config.type", config.tp)
|
|||
|
|
-- 配置SPI和初始化网络驱动
|
|||
|
|
local result = spi.setup(config.opts.spi, -- spi id
|
|||
|
|
nil, 0, -- CPHA
|
|||
|
|
0, -- CPOL
|
|||
|
|
8, -- 数据宽度
|
|||
|
|
25600000 -- ,--波特率
|
|||
|
|
)
|
|||
|
|
log.info("main", "open spi", result)
|
|||
|
|
if result ~= 0 then -- 返回值为0,表示打开成功
|
|||
|
|
log.info("main", "spi open error", result)
|
|||
|
|
if config.pwrpin then
|
|||
|
|
gpio.close(config.pwrpin)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
-- 初始化指定netdrv设备,
|
|||
|
|
-- socket.LWIP_ETH 网络适配器编号
|
|||
|
|
-- netdrv.CH390外挂CH390
|
|||
|
|
-- SPI ID 1, 片选 GPIO12
|
|||
|
|
if netdrv.setup(socket.LWIP_USER1, config.tp, config.opts) == false then
|
|||
|
|
log.error("以太网初始化失败")
|
|||
|
|
if config.pwrpin then
|
|||
|
|
gpio.close(config.pwrpin)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
if config.static_ip then
|
|||
|
|
sys.wait(1000) -- 等待以太网模块初始化完成,去掉会导致以太网初始化失败
|
|||
|
|
log.info("netdrv", "自定义以太网IP地址", config.static_ip.ipv4)
|
|||
|
|
log.info("静态ip",
|
|||
|
|
netdrv.ipv4(socket.LWIP_USER1, config.static_ip.ipv4, config.static_ip.mark, config.static_ip.gw))
|
|||
|
|
else
|
|||
|
|
netdrv.dhcp(socket.LWIP_USER1, true)
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
log.info("以太网初始化完成")
|
|||
|
|
socket_state_detection(socket.LWIP_USER1)
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- 连接wifi(STA模式)
|
|||
|
|
local function set_wifi_info(config)
|
|||
|
|
if config.local_network_mode then
|
|||
|
|
local_network_mode = true
|
|||
|
|
end
|
|||
|
|
if config.need_ping ~= nil then
|
|||
|
|
need_ping = config.need_ping
|
|||
|
|
end
|
|||
|
|
if config.auto_socket_switch ~= nil then
|
|||
|
|
auto_socket_switch = config.auto_socket_switch
|
|||
|
|
-- log.info("设置自动关闭非当前网卡socket连接", auto_socket_switch)
|
|||
|
|
end
|
|||
|
|
wifi_ping_ip = config.ping_ip
|
|||
|
|
if type(config.ping_time) == "number" then
|
|||
|
|
ping_time = config.ping_time
|
|||
|
|
end
|
|||
|
|
log.info("WiFi名称:", config.ssid)
|
|||
|
|
log.info("密码 :", config.password)
|
|||
|
|
log.info("ping_ip :", config.ping_ip)
|
|||
|
|
wlan.init()
|
|||
|
|
if not single_network_mode then
|
|||
|
|
available[socket.LWIP_STA] = connection_states.OPENED
|
|||
|
|
else
|
|||
|
|
available[socket.LWIP_STA] = connection_states.SINGLE_NETWORK
|
|||
|
|
end
|
|||
|
|
-- 尝试连接Wi-Fi,并处理可能出现的错误
|
|||
|
|
local success = wlan.connect(config.ssid, config.password)
|
|||
|
|
if not success then
|
|||
|
|
log.error("WiFi连接失败")
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
log.info("WiFi STA初始化完成")
|
|||
|
|
socket_state_detection(socket.LWIP_STA)
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- 以太网处于stop状态,重启以太网
|
|||
|
|
local function eth_net_restart(adapter)
|
|||
|
|
log.info("以太网处于stop状态,重启下")
|
|||
|
|
if not single_network_mode then
|
|||
|
|
available[adapter] = connection_states.OPENED
|
|||
|
|
else
|
|||
|
|
available[adapter] = connection_states.SINGLE_NETWORK
|
|||
|
|
end
|
|||
|
|
-- 打开CH390供电
|
|||
|
|
if eth_cfg[adapter].pwrpin then
|
|||
|
|
log.info("打开以太网供电引脚:", eth_cfg[adapter].pwrpin)
|
|||
|
|
gpio.setup(eth_cfg[adapter].pwrpin, 1, gpio.PULLUP)
|
|||
|
|
end
|
|||
|
|
-- sys.wait(100) -- 等待以太网模块上电稳定
|
|||
|
|
if eth_cfg[adapter].tp == nil then
|
|||
|
|
log.info("8101以太网")
|
|||
|
|
else
|
|||
|
|
log.info("config.opts.spi", eth_cfg[adapter].opts.spi, ",config.type", eth_cfg[adapter].tp)
|
|||
|
|
-- 配置SPI和初始化网络驱动
|
|||
|
|
local result = spi.setup(eth_cfg[adapter].opts.spi, -- spi id
|
|||
|
|
nil, 0, -- CPHA
|
|||
|
|
0, -- CPOL
|
|||
|
|
8, -- 数据宽度
|
|||
|
|
25600000 -- ,--波特率
|
|||
|
|
)
|
|||
|
|
log.info("main", "open spi", result)
|
|||
|
|
if result ~= 0 then -- 返回值为0,表示打开成功
|
|||
|
|
log.info("main", "spi open error", result)
|
|||
|
|
if eth_cfg[adapter].pwrpin then
|
|||
|
|
gpio.close(eth_cfg[adapter].pwrpin)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
netdrv.ctrl(adapter, netdrv.CTRL_UPDOWN, 1)
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- ping测试循环
|
|||
|
|
local function ping_test_loop()
|
|||
|
|
while true do
|
|||
|
|
for _, net_type in ipairs(current_priority) do
|
|||
|
|
-- log.info("网卡顺序",type_to_string(net_type),available[net_type])
|
|||
|
|
if available[net_type] == connection_states.CONNECTING then
|
|||
|
|
log.info(type_to_string(net_type) .. "网卡开始PING")
|
|||
|
|
ping_request(net_type)
|
|||
|
|
sys.wait(ping_time)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
sys.wait(1000) -- 避免死循环
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- 正常状态网卡的检测任务
|
|||
|
|
local function normal_network_test()
|
|||
|
|
while true do
|
|||
|
|
if interval_time ~= nil then
|
|||
|
|
sys.wait(interval_time)
|
|||
|
|
exnetif.check_network_status()
|
|||
|
|
end
|
|||
|
|
sys.wait(1000) -- 避免死循环
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- PING结果处理函数
|
|||
|
|
local function ping_res(id, time, dst)
|
|||
|
|
log.info("ping", id, time, dst)
|
|||
|
|
log.info(type_to_string(id) .. "网卡PING测试成功")
|
|||
|
|
available[id] = connection_states.CONNECTED
|
|||
|
|
apply_priority()
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--[[
|
|||
|
|
设置网络优先级,相应网卡获取到ip且网络正常视为网卡可用,丢失ip视为网卡不可用.(需要在task中调用)
|
|||
|
|
@api exnetif.set_priority_order(new_priority)
|
|||
|
|
@table 网络优先级列表,优先级从高到低对应table中的第一个参数到最后一个参数
|
|||
|
|
@return boolean 成功返回true,失败返回false
|
|||
|
|
@usage
|
|||
|
|
多网优先级模式:
|
|||
|
|
exnetif.set_priority_order({
|
|||
|
|
{ -- 最高优先级网络
|
|||
|
|
WIFI = { -- WiFi配置
|
|||
|
|
ssid = "your_ssid", -- WiFi名称(string)
|
|||
|
|
password = "your_pwd", -- WiFi密码(string)
|
|||
|
|
need_ping = true, -- 是否需要通过ping来测试网络的连通性
|
|||
|
|
-- 在没有ping测试环境的项目中,需要将这个参数设置为false,表示不需要ping测试网络连通,
|
|||
|
|
-- 仅根据IP READY消息(即获取到了ip地址)来判断网络环境准备就绪,是否网络连通性则无法保证
|
|||
|
|
-- 如果没有设置此参数,默认为true
|
|||
|
|
-- 在有ping测试环境的项目中,建议不要将这个参数设置为true
|
|||
|
|
local_network_mode = true,-- 局域网模式(选填参数),设置为true时,exnetif会自动将ping_ip设置为网卡的网关ip。
|
|||
|
|
-- 用户不需要传入ping_ip参数,即使传入了,也无效。
|
|||
|
|
-- 这个模式的使用场景,仅适用于局域网环境;可以访问外网时,不要使用
|
|||
|
|
ping_ip = "112.125.89.8", -- 连通性检测IP(选填参数),默认使用httpdns获取baidu.com的ip作为判断条件,
|
|||
|
|
-- 注:如果填写ip,则ping通作为判断网络是否可用的条件,
|
|||
|
|
-- 所以需要根据网络环境填写内网或者外网ip,
|
|||
|
|
-- 填写外网ip的话要保证外网ip始终可用,
|
|||
|
|
-- 填写局域网ip的话要确保相应ip固定且能够被ping通
|
|||
|
|
ping_time = 10000 -- 填写ping_ip且未ping通时的检测间隔(ms, 可选,默认为10秒)
|
|||
|
|
-- 定时ping将会影响模块功耗,使用低功耗模式的话可以适当延迟间隔时间
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
{ -- 次优先级网络
|
|||
|
|
ETHERNET = { -- 以太网配置
|
|||
|
|
pwrpin = 140, -- 供电使能引脚(number)
|
|||
|
|
need_ping = true, -- 是否需要通过ping来测试网络的连通性
|
|||
|
|
-- 在没有ping测试环境的项目中,需要将这个参数设置为false,表示不需要ping测试网络连通,
|
|||
|
|
-- 仅根据IP READY消息(即获取到了ip地址)来判断网络环境准备就绪,是否网络连通性则无法保证
|
|||
|
|
-- 如果没有设置此参数,默认为true
|
|||
|
|
-- 在有ping测试环境的项目中,建议不要将这个参数设置为true
|
|||
|
|
local_network_mode = true, -- 局域网模式(选填参数),设置为true时,exnetif会自动将ping_ip设置为网卡的网关ip。
|
|||
|
|
-- 用户不需要传入ping_ip参数,即使传入了,也无效。
|
|||
|
|
-- 这个模式的使用场景,仅适用于局域网环境;可以访问外网时,不要使用
|
|||
|
|
ping_ip = "112.125.89.8", -- 连通性检测IP(选填参数),默认使用httpdns获取baidu.com的ip作为判断条件,
|
|||
|
|
-- 注:如果填写ip,则ping通作为判断网络是否可用的条件,
|
|||
|
|
-- 所以需要根据网络环境填写内网或者外网ip,
|
|||
|
|
-- 填写外网ip的话要保证外网ip始终可用,
|
|||
|
|
-- 填写局域网ip的话要确保相应ip固定且能够被ping通
|
|||
|
|
ping_time = 10000, -- 填写ping_ip且未ping通时的检测间隔(ms, 可选,默认为10秒)
|
|||
|
|
-- 定时ping将会影响模块功耗,使用低功耗模式的话可以适当延迟间隔时间
|
|||
|
|
tp = netdrv.CH390, -- 网卡芯片型号(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
opts = { spi = 1, cs = 12 }, -- 外挂方式,需要额外的参数(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
static_ip = { -- 静态ip配置(选填参数),不填写则使用dhcp获取ip
|
|||
|
|
ipv4 = "192.168.5.100", -- ip地址(string)
|
|||
|
|
mark = "255.255.255.0", -- 子网掩码(string)
|
|||
|
|
gw = "192.168.5.1" -- 网关地址(string)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
{ -- 最低优先级网络
|
|||
|
|
LWIP_GP = true -- 启用4G网络
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
单网络模式:
|
|||
|
|
-- 单网络模式下只使用WIFI网络
|
|||
|
|
exnetif.set_priority_order({
|
|||
|
|
{ -- 单网络,打开wifi
|
|||
|
|
WIFI = { -- WiFi配置
|
|||
|
|
ssid = "test", -- WiFi名称(string)
|
|||
|
|
password = "HZ88888888", -- WiFi密码(string)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
-- Air8000系列和780EXX系列单网络模式下只使用SPI以太网网络
|
|||
|
|
exnetif.set_priority_order({
|
|||
|
|
{
|
|||
|
|
ETHERNET = { -- 以太网配置
|
|||
|
|
pwrpin = 140, -- 供电使能引脚(number)
|
|||
|
|
tp = netdrv.CH390, -- 网卡芯片型号(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
opts = {spi = 1, cs = 12}, -- 外挂方式,需要额外的参数(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
-- Air8101单网络模式下只使用SPI以太网网络
|
|||
|
|
exnetif.set_priority_order({
|
|||
|
|
{
|
|||
|
|
ETHUSER1 = { -- 以太网配置
|
|||
|
|
pwrpin = 13, -- 供电使能引脚(number)
|
|||
|
|
tp = netdrv.CH390, -- 网卡芯片型号(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
opts = {spi = 0, cs = 15}, -- 外挂方式,需要额外的参数(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
static_ip = { -- 静态ip配置(选填参数),不填写则使用dhcp获取ip
|
|||
|
|
ipv4 = "192.168.5.100", -- ip地址(string)
|
|||
|
|
mark = "255.255.255.0", -- 子网掩码(string)
|
|||
|
|
gw = "192.168.5.1" -- 网关地址(string)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
-- 单网络模式下只使用RMII以太网网络
|
|||
|
|
exnetif.set_priority_order({
|
|||
|
|
{
|
|||
|
|
ETHERNET = { -- 以太网配置
|
|||
|
|
pwrpin = 13, -- 供电使能引脚(number)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
-- 4G单网模式下,不需要require "exnetif",减少不必要的功能模块加载
|
|||
|
|
]]
|
|||
|
|
function exnetif.set_priority_order(networkConfigs)
|
|||
|
|
-- 判断表中数据个数
|
|||
|
|
if #networkConfigs < 1 then
|
|||
|
|
log.error("网络配置为空")
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
if #networkConfigs == 1 then
|
|||
|
|
single_network_mode = true
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
if not single_network_mode then
|
|||
|
|
-- CONNECTING的网卡需要定时ping
|
|||
|
|
sys.taskInit(ping_test_loop)
|
|||
|
|
|
|||
|
|
-- 循环ping检测正常网卡的任务,默认不启用
|
|||
|
|
sys.taskInit(normal_network_test)
|
|||
|
|
|
|||
|
|
sys.subscribe("PING_RESULT", ping_res)
|
|||
|
|
-- 订阅网络状态变化的消息
|
|||
|
|
sys.subscribe("IP_READY", ip_ready_handle)
|
|||
|
|
sys.subscribe("IP_LOSE", ip_lose_handle)
|
|||
|
|
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
local new_priority = {}
|
|||
|
|
-- 只有关闭状态的网卡需要初始化
|
|||
|
|
for _, config in ipairs(networkConfigs) do
|
|||
|
|
if type(config.WIFI) == "table" then
|
|||
|
|
if available[socket.LWIP_STA] == connection_states.DISCONNECTED then
|
|||
|
|
-- 开启wifi
|
|||
|
|
local res = set_wifi_info(config.WIFI)
|
|||
|
|
if res == false then
|
|||
|
|
log.error("wifi连接失败")
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
else
|
|||
|
|
log.info("wifi不是关闭状态,跳过初始化")
|
|||
|
|
end
|
|||
|
|
table.insert(new_priority, socket.LWIP_STA)
|
|||
|
|
end
|
|||
|
|
if type(config.ETHUSER1) == "table" then
|
|||
|
|
eth_cfg[socket.LWIP_USER1] = config.ETHUSER1
|
|||
|
|
if available[socket.LWIP_USER1] == connection_states.DISCONNECTED then
|
|||
|
|
-- 开启以太网
|
|||
|
|
local res = setup_eth_user1(config.ETHUSER1)
|
|||
|
|
if res == false then
|
|||
|
|
log.error("以太网打开失败")
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
elseif available[socket.LWIP_USER1] == connection_states.STOPED then
|
|||
|
|
eth_net_restart(socket.LWIP_USER1)
|
|||
|
|
else
|
|||
|
|
log.info("8101spi以太网不是关闭状态,跳过初始化")
|
|||
|
|
end
|
|||
|
|
table.insert(new_priority, socket.LWIP_USER1)
|
|||
|
|
end
|
|||
|
|
if type(config.ETHERNET) == "table" then
|
|||
|
|
eth_cfg[socket.LWIP_ETH] = config.ETHERNET
|
|||
|
|
if available[socket.LWIP_ETH] == connection_states.DISCONNECTED then
|
|||
|
|
-- 开启以太网
|
|||
|
|
local res = setup_eth(config.ETHERNET)
|
|||
|
|
if res == false then
|
|||
|
|
log.error("以太网打开失败")
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
elseif available[socket.LWIP_ETH] == connection_states.STOPED then
|
|||
|
|
eth_net_restart(socket.LWIP_ETH)
|
|||
|
|
else
|
|||
|
|
log.info("以太网不是关闭状态,跳过初始化")
|
|||
|
|
end
|
|||
|
|
table.insert(new_priority, socket.LWIP_ETH)
|
|||
|
|
end
|
|||
|
|
if config.LWIP_GP then
|
|||
|
|
-- 退出飞行模式
|
|||
|
|
mobile.flymode(nil, false)
|
|||
|
|
-- 开启4G
|
|||
|
|
table.insert(new_priority, socket.LWIP_GP)
|
|||
|
|
available[socket.LWIP_GP] = connection_states.CONNECTING
|
|||
|
|
if config.auto_socket_switch ~= nil then
|
|||
|
|
auto_socket_switch = config.auto_socket_switch
|
|||
|
|
-- log.info("设置自动关闭非当前网卡socket连接", auto_socket_switch)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- 设置新优先级
|
|||
|
|
current_priority = new_priority
|
|||
|
|
-- 此处按照用户期望的配置,先设置优先级最高的默认网卡
|
|||
|
|
-- 防止出现以下问题:
|
|||
|
|
-- 例如Air8000内核固件运行起来之后,默认网卡是socket.LWIP_GP,如果用户调用exnetif.set_priority_order接口配置最高优先级网卡为socket.LWIP_ETH
|
|||
|
|
-- 在socket.LWIP_ETH网卡准备就绪之前,socket.LWIP_GP可能已经准备就绪,此时默认网卡仍然是socket.LWIP_GP;
|
|||
|
|
-- 而网络应用层(例如socket,mqtt等)有关的demo,我们编写时,不关心具体网卡,直接使用默认网卡(这样符合正常逻辑);
|
|||
|
|
-- 就可能会出现“网络应用在这段时间内直接使用socket.LWIP_GP,而不是用户期望的网卡socket.LWIP_ETH来上网”的问题;
|
|||
|
|
socket.dft(new_priority[1])
|
|||
|
|
apply_priority()
|
|||
|
|
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--[[
|
|||
|
|
设置网络状态变化回调函数。触发条件:网卡切换或者所有网卡都断网。回调函数的输入参数: 1. 当有可用网络的时候,返回当前使用网卡、网卡id;2. 当没有可用网络的时候,返回 nil、-1 。
|
|||
|
|
@api exnetif.notify_status(cb_fnc)
|
|||
|
|
@function 回调函数
|
|||
|
|
@usage
|
|||
|
|
exnetif.notify_status(function(net_type,adapter)
|
|||
|
|
log.info("可以使用优先级更高的网络:", net_type,adapter)
|
|||
|
|
end)
|
|||
|
|
]]
|
|||
|
|
function exnetif.notify_status(cb_fnc)
|
|||
|
|
log.info("notify_status", type(cb_fnc))
|
|||
|
|
if type(cb_fnc) ~= "function" then
|
|||
|
|
log.error("notify_status设置错误,请传入一个函数")
|
|||
|
|
return
|
|||
|
|
end
|
|||
|
|
states_cbfnc = cb_fnc
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--[[
|
|||
|
|
设置多网融合模式,例如4G作为数据出口给WIFI或以太网设备上网(需要在task中调用)
|
|||
|
|
@api exnetif.setproxy(adapter, main_adapter,other_configs)
|
|||
|
|
@adapter 需要使用网络的网卡,例如socket.LWIP_ETH
|
|||
|
|
@adapter 提供网络的网卡,例如socket.LWIP_GP
|
|||
|
|
@table 其他设置参数(选填参数),
|
|||
|
|
@usage
|
|||
|
|
典型应用:
|
|||
|
|
-- 以太网WAN提供网络其他设备连接以太网LAN口上网
|
|||
|
|
exnetif.setproxy(socket.LWIP_ETH, socket.LWIP_USER1, {
|
|||
|
|
ethpower_en = 20,-- 以太网模块的pwrpin引脚(gpio编号)
|
|||
|
|
tp = netdrv.CH390, -- 网卡芯片型号(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
opts = {spi = 0, cs = 8}, -- 外挂方式,需要额外的参数(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
main_adapter = {
|
|||
|
|
ethpower_en = 21,-- 以太网模块的pwrpin引脚(gpio编号)
|
|||
|
|
tp = netdrv.CH390, -- 网卡芯片型号(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
opts = {spi = 1, cs = 12}
|
|||
|
|
}
|
|||
|
|
}) then
|
|||
|
|
-- wifi_sta提供网络开启wifi_ap热点供设备上网
|
|||
|
|
exnetif.setproxy(socket.LWIP_AP, socket.LWIP_STA, {
|
|||
|
|
ssid = "test2", -- AP热点名称(string),网卡包含wifi时填写
|
|||
|
|
password = "HZ88888888", -- AP热点密码(string),网卡包含wifi时填写
|
|||
|
|
ap_opts = { -- AP模式下配置项(选填参数)
|
|||
|
|
hidden = false, -- 是否隐藏SSID, 默认false,不隐藏
|
|||
|
|
max_conn = 4 }, -- 最大客户端数量, 默认4
|
|||
|
|
channel = 6, -- AP建立的通道, 默认6
|
|||
|
|
main_adapter = {
|
|||
|
|
ssid = "test", -- 提供网络的网卡开启参数
|
|||
|
|
password = "HZ88888888"
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
-- 4G提供网络开启wifi_ap热点供设备上网,其他设备连接以太网LAN口上网
|
|||
|
|
exnetif.setproxy(socket.LWIP_AP, socket.LWIP_GP, {
|
|||
|
|
ssid = "Hotspot", -- WiFi名称(string),网卡包含wifi时填写
|
|||
|
|
password = "password123", -- WiFi密码(string),网卡包含wifi时填写
|
|||
|
|
adapter_addr = "192.168.5.1", -- adapter网卡的ip地址(选填),需要自定义ip和网关ip时填写
|
|||
|
|
adapter_gw= { 192, 168, 5, 1 }, -- adapter网卡的网关地址(选填),需要自定义ip和网关ip时填写
|
|||
|
|
ap_opts={ -- AP模式下配置项(选填参数)
|
|||
|
|
hidden = false, -- 是否隐藏SSID, 默认false,不隐藏
|
|||
|
|
max_conn = 4 }, -- 最大客户端数量, 默认4
|
|||
|
|
channel=6 -- AP建立的通道, 默认6
|
|||
|
|
})
|
|||
|
|
exnetif.setproxy(socket.LWIP_ETH, socket.LWIP_GP, {
|
|||
|
|
tp = netdrv.CH390, -- 网卡芯片型号(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
opts = { spi = 1, cs = 12}, -- 外挂方式,需要额外的参数(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
ethpower_en = 140, -- 以太网模块的pwrpin引脚(gpio编号)
|
|||
|
|
adapter_addr = "192.168.5.1", -- adapter网卡的ip地址(选填),需要自定义ip和网关ip时填写
|
|||
|
|
adapter_gw= { 192, 168, 5, 1 }, -- adapter网卡的网关地址(选填),需要自定义ip和网关ip时填写
|
|||
|
|
})
|
|||
|
|
-- 以太网提供网络供WiFi设备上网
|
|||
|
|
exnetif.setproxy(socket.LWIP_AP, socket.LWIP_ETH, {
|
|||
|
|
ssid = "Hotspot", -- WiFi名称(string),网卡包含wifi时填写
|
|||
|
|
password = "password123", -- WiFi密码(string),网卡包含wifi时填写
|
|||
|
|
main_adapter={
|
|||
|
|
tp = netdrv.CH390, -- 网卡芯片型号(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
opts = { spi = 1, cs = 12}, -- 外挂方式,需要额外的参数(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
ethpower_en = 140, -- 以太网模块的pwrpin引脚(gpio编号)
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
-- WIFI提供网络供以太网设备上网
|
|||
|
|
exnetif.setproxy(socket.LWIP_ETH, socket.LWIP_STA, {
|
|||
|
|
tp = netdrv.CH390, -- 网卡芯片型号(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
opts = { spi = 1, cs = 12}, -- 外挂方式,需要额外的参数(选填参数),仅spi方式外挂以太网时需要填写。
|
|||
|
|
ethpower_en = 140, -- 以太网模块的pwrpin引脚(gpio编号)
|
|||
|
|
main_adapter = {
|
|||
|
|
ssid = "test", -- 提供网络的网卡开启参数
|
|||
|
|
password = "HZ88888888"
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
]]
|
|||
|
|
function exnetif.setproxy(adapter, main_adapter, other_configs)
|
|||
|
|
if main_adapter == socket.LWIP_ETH and available[socket.LWIP_ETH] == connection_states.DISCONNECTED then
|
|||
|
|
-- 打开WAN功能
|
|||
|
|
log.info("ch390", "打开LDO供电", other_configs.main_adapter.ethpower_en)
|
|||
|
|
available[socket.LWIP_ETH] = connection_states.OPENED
|
|||
|
|
-- 打开CH390供电
|
|||
|
|
if other_configs.main_adapter.ethpower_en then
|
|||
|
|
gpio.setup(other_configs.main_adapter.ethpower_en, 1, gpio.PULLUP)
|
|||
|
|
end
|
|||
|
|
-- sys.wait(100) -- 等待以太网模块上电稳定
|
|||
|
|
if other_configs.main_adapter.tp == nil then
|
|||
|
|
log.info("8101以太网")
|
|||
|
|
if netdrv.setup(socket.LWIP_ETH) == false then
|
|||
|
|
log.error("以太网初始化失败")
|
|||
|
|
if other_configs.main_adapter.ethpower_en then
|
|||
|
|
gpio.close(other_configs.main_adapter.ethpower_en)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
else
|
|||
|
|
log.info("config.opts.spi", other_configs.main_adapter.opts.spi, ",config.type",
|
|||
|
|
other_configs.main_adapter.tp)
|
|||
|
|
-- 配置SPI和初始化网络驱动
|
|||
|
|
local result = spi.setup(other_configs.main_adapter.opts.spi, -- spi id
|
|||
|
|
nil, 0, -- CPHA
|
|||
|
|
0, -- CPOL
|
|||
|
|
8, -- 数据宽度
|
|||
|
|
25600000 -- ,--波特率
|
|||
|
|
)
|
|||
|
|
log.info("main", "open spi", result)
|
|||
|
|
if result ~= 0 then -- 返回值为0,表示打开成功
|
|||
|
|
log.info("main", "spi open error", result)
|
|||
|
|
if other_configs.main_adapter.ethpower_en then
|
|||
|
|
gpio.close(other_configs.main_adapter.ethpower_en)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
-- 初始化指定netdrv设备,
|
|||
|
|
local success =
|
|||
|
|
netdrv.setup(socket.LWIP_ETH, other_configs.main_adapter.tp, other_configs.main_adapter.opts)
|
|||
|
|
if not success then
|
|||
|
|
log.error("以太网初始化失败")
|
|||
|
|
if other_configs.main_adapter.ethpower_en then
|
|||
|
|
gpio.close(other_configs.main_adapter.ethpower_en)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
netdrv.dhcp(socket.LWIP_ETH, true)
|
|||
|
|
local count = 1
|
|||
|
|
while 1 do
|
|||
|
|
local ip = netdrv.ipv4(socket.LWIP_ETH)
|
|||
|
|
if ip and ip ~= "0.0.0.0" then
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
if count > 600 then
|
|||
|
|
log.error("以太网连接超时,请检查配置")
|
|||
|
|
if other_configs.main_adapter.ethpower_en then
|
|||
|
|
gpio.close(other_configs.main_adapter.ethpower_en)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
sys.wait(100)
|
|||
|
|
count = count + 1
|
|||
|
|
end
|
|||
|
|
elseif main_adapter == socket.LWIP_USER1 and available[socket.LWIP_USER1] == connection_states.DISCONNECTED then
|
|||
|
|
log.info("初始化以太网")
|
|||
|
|
-- 打开CH390供电
|
|||
|
|
if other_configs.main_adapter.ethpower_en then
|
|||
|
|
gpio.setup(other_configs.main_adapter.ethpower_en, 1, gpio.PULLUP)
|
|||
|
|
end
|
|||
|
|
-- sys.wait(100) -- 等待以太网模块上电稳定
|
|||
|
|
log.info("config.opts.spi", other_configs.main_adapter.opts.spi, ",config.type", other_configs.main_adapter.tp)
|
|||
|
|
available[socket.LWIP_USER1] = connection_states.OPENED
|
|||
|
|
-- 配置SPI和初始化网络驱动
|
|||
|
|
local result = spi.setup(other_configs.main_adapter.opts.spi, -- spi id
|
|||
|
|
nil, 0, -- CPHA
|
|||
|
|
0, -- CPOL
|
|||
|
|
8, -- 数据宽度
|
|||
|
|
25600000 -- ,--波特率
|
|||
|
|
)
|
|||
|
|
log.info("main", "open spi", result)
|
|||
|
|
if result ~= 0 then -- 返回值为0,表示打开成功
|
|||
|
|
log.info("main", "spi open error", result)
|
|||
|
|
if other_configs.main_adapter.ethpower_en then
|
|||
|
|
gpio.close(other_configs.main_adapter.ethpower_en)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
-- 初始化指定netdrv设备,
|
|||
|
|
-- socket.LWIP_ETH 网络适配器编号
|
|||
|
|
-- netdrv.CH390外挂CH390
|
|||
|
|
-- SPI ID 1, 片选 GPIO12
|
|||
|
|
if netdrv.setup(socket.LWIP_USER1, other_configs.main_adapter.tp, other_configs.main_adapter.opts) == false then
|
|||
|
|
log.error("以太网初始化失败")
|
|||
|
|
if other_configs.main_adapter.ethpower_en then
|
|||
|
|
gpio.close(other_configs.main_adapter.ethpower_en)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
netdrv.dhcp(socket.LWIP_USER1, true)
|
|||
|
|
log.info("以太网初始化完成")
|
|||
|
|
local count = 1
|
|||
|
|
while 1 do
|
|||
|
|
local ip = netdrv.ipv4(socket.LWIP_USER1)
|
|||
|
|
if ip and ip ~= "0.0.0.0" then
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
if count > 600 then
|
|||
|
|
log.error("以太网连接超时,请检查配置")
|
|||
|
|
if other_configs.main_adapter.ethpower_en then
|
|||
|
|
gpio.close(other_configs.main_adapter.ethpower_en)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
sys.wait(100)
|
|||
|
|
count = count + 1
|
|||
|
|
end
|
|||
|
|
elseif main_adapter == socket.LWIP_STA and available[socket.LWIP_STA] == connection_states.DISCONNECTED then
|
|||
|
|
-- 打开STA功能,设置混合模式
|
|||
|
|
wlan.init()
|
|||
|
|
wlan.setMode(wlan.APSTA)
|
|||
|
|
available[socket.LWIP_STA] = connection_states.OPENED
|
|||
|
|
-- 尝试连接Wi-Fi,并处理可能出现的错误
|
|||
|
|
wlan.connect(other_configs.main_adapter.ssid, other_configs.main_adapter.password)
|
|||
|
|
-- 等待获取IP地址
|
|||
|
|
local count = 1
|
|||
|
|
while 1 do
|
|||
|
|
local ip = netdrv.ipv4(socket.LWIP_STA)
|
|||
|
|
if ip and ip ~= "0.0.0.0" then
|
|||
|
|
log.info("WiFi STA已连接,IP:", ip)
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
if count > 600 then
|
|||
|
|
log.error("WiFi STA连接超时,请检查配置")
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
sys.wait(100)
|
|||
|
|
count = count + 1
|
|||
|
|
end
|
|||
|
|
log.info("WiFi STA初始化完成")
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
if adapter == socket.LWIP_ETH then
|
|||
|
|
log.info("ch390", "打开LDO供电", other_configs.ethpower_en)
|
|||
|
|
if other_configs.ethpower_en then
|
|||
|
|
gpio.setup(other_configs.ethpower_en, 1, gpio.PULLUP)
|
|||
|
|
end
|
|||
|
|
-- 打开LAN功能
|
|||
|
|
-- 配置 SPI 参数,Air8000 使用 SPI 接口与以太网模块进行通信。
|
|||
|
|
if other_configs.tp then
|
|||
|
|
log.info("netdrv spi挂载以太网", "初始化LAN功能")
|
|||
|
|
local result = spi.setup(other_configs.opts.spi, -- spi id
|
|||
|
|
nil, 0, -- CPHA
|
|||
|
|
0, -- CPOL
|
|||
|
|
8, -- 数据宽度
|
|||
|
|
25600000 -- ,--波特率
|
|||
|
|
)
|
|||
|
|
log.info("main", "open spi", result)
|
|||
|
|
if result ~= 0 then -- 返回值为 0,表示打开成功
|
|||
|
|
log.error("main", "spi open error", result)
|
|||
|
|
if other_configs.ethpower_en then
|
|||
|
|
gpio.close(other_configs.ethpower_en)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
-- 初始化以太网,Air8000 指定使用 CH390 芯片。
|
|||
|
|
log.info("netdrv", "初始化以太网", other_configs.tp, other_configs.opts)
|
|||
|
|
if netdrv.setup(socket.LWIP_ETH, other_configs.tp, other_configs.opts) == false then
|
|||
|
|
log.error("初始化以太网失败")
|
|||
|
|
if other_configs.ethpower_en then
|
|||
|
|
gpio.close(other_configs.ethpower_en)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
sys.wait(1000) -- 等待以太网模块初始化完成,去掉会导致以太网初始化失败
|
|||
|
|
-- 设置以太网的 IP 地址、子网掩码、网关地址
|
|||
|
|
log.info("netdrv", "自定义以太网IP地址", other_configs.adapter_addr, "网关地址",
|
|||
|
|
other_configs.adapter_gw)
|
|||
|
|
netdrv.ipv4(socket.LWIP_ETH, other_configs.adapter_addr or "192.168.5.1", "255.255.255.0", "0.0.0.0")
|
|||
|
|
-- 获取以太网网络状态,连接后返回 true,否则返回 false,如果不存在就返回 nil。
|
|||
|
|
local count = 1
|
|||
|
|
while netdrv.ready(socket.LWIP_ETH) ~= true do
|
|||
|
|
if count > 600 then
|
|||
|
|
log.error("以太网连接超时,请检查配置")
|
|||
|
|
if other_configs.ethpower_en then
|
|||
|
|
gpio.close(other_configs.ethpower_en)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
count = count + 1
|
|||
|
|
-- log.info("netdrv", "等待以太网就绪") -- 若以太网设备没有连上,可打开此处注释排查。
|
|||
|
|
sys.wait(100)
|
|||
|
|
end
|
|||
|
|
log.info("netdrv", "以太网就绪")
|
|||
|
|
-- 创建 DHCP 服务器,为连接到以太网的设备分配 IP 地址。
|
|||
|
|
log.info("netdrv", "创建dhcp服务器, 供以太网使用")
|
|||
|
|
if other_configs.adapter_gw then
|
|||
|
|
dhcpsrv.create({
|
|||
|
|
adapter = socket.LWIP_ETH,
|
|||
|
|
gw = other_configs.adapter_gw
|
|||
|
|
})
|
|||
|
|
else
|
|||
|
|
dhcpsrv.create({
|
|||
|
|
adapter = socket.LWIP_ETH,
|
|||
|
|
gw = {192, 168, 5, 1}
|
|||
|
|
})
|
|||
|
|
end
|
|||
|
|
-- 创建 DNS 代理服务,使得以太网接口上的设备可以通过 4G 网络访问互联网。
|
|||
|
|
log.info("netdrv", "创建dns代理服务, 供以太网使用")
|
|||
|
|
elseif adapter == socket.LWIP_AP then
|
|||
|
|
wlan.setMode(wlan.APSTA)
|
|||
|
|
-- 打开AP功能,设置混合模式
|
|||
|
|
log.info("执行AP创建操作", airlink.ready(), "正常吗?")
|
|||
|
|
wlan.createAP(other_configs.ssid, other_configs.password, other_configs.adapter_addr or "192.168.4.1",
|
|||
|
|
"255.255.255.0", other_configs.channel, other_configs.ap_opts)
|
|||
|
|
-- 设置 AP 的 IP 地址、子网掩码、网关地址
|
|||
|
|
netdrv.ipv4(socket.LWIP_AP, other_configs.adapter_addr or "192.168.4.1", "255.255.255.0", "0.0.0.0")
|
|||
|
|
-- 获取 WiFi AP 网络状态,连接后返回 true,否则返回 false,如果不存在就返回 nil。
|
|||
|
|
log.info("netdrv", "等待AP就绪")
|
|||
|
|
local count = 1
|
|||
|
|
while netdrv.ready(socket.LWIP_AP) ~= true do
|
|||
|
|
-- log.info("netdrv", "等待AP就绪")
|
|||
|
|
if count > 600 then
|
|||
|
|
log.error("AP创建超时,请检查配置")
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
sys.wait(100)
|
|||
|
|
count = count + 1
|
|||
|
|
end
|
|||
|
|
-- 创建 DHCP 服务器,为连接到 WiFi AP 的设备分配 IP 地址。
|
|||
|
|
log.info("netdrv", "创建dhcp服务器, 供AP使用")
|
|||
|
|
if other_configs.adapter_gw then
|
|||
|
|
dhcpsrv.create({
|
|||
|
|
adapter = socket.LWIP_AP,
|
|||
|
|
gw = other_configs.adapter_gw
|
|||
|
|
})
|
|||
|
|
else
|
|||
|
|
dhcpsrv.create({
|
|||
|
|
adapter = socket.LWIP_AP
|
|||
|
|
})
|
|||
|
|
end
|
|||
|
|
elseif adapter == socket.LWIP_USER1 then
|
|||
|
|
log.info("ch390", "打开LDO供电", other_configs.ethpower_en)
|
|||
|
|
if other_configs.ethpower_en then
|
|||
|
|
gpio.setup(other_configs.ethpower_en, 1, gpio.PULLUP)
|
|||
|
|
end
|
|||
|
|
-- 打开LAN功能
|
|||
|
|
-- 配置 SPI 参数,Air8101 使用 SPI 接口与以太网模块进行通信。
|
|||
|
|
log.info("netdrv spi挂载以太网", "初始化LAN功能")
|
|||
|
|
local result = spi.setup(other_configs.opts.spi, -- spi id
|
|||
|
|
nil, 0, -- CPHA
|
|||
|
|
0, -- CPOL
|
|||
|
|
8, -- 数据宽度
|
|||
|
|
25600000 -- ,--波特率
|
|||
|
|
)
|
|||
|
|
log.info("main", "open spi", result)
|
|||
|
|
if result ~= 0 then -- 返回值为 0,表示打开成功
|
|||
|
|
log.error("main", "spi open error", result)
|
|||
|
|
if other_configs.ethpower_en then
|
|||
|
|
gpio.close(other_configs.ethpower_en)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
-- 初始化以太网,Air8000 指定使用 CH390 芯片。
|
|||
|
|
log.info("netdrv", "初始化以太网", other_configs.tp, other_configs.opts)
|
|||
|
|
if netdrv.setup(socket.LWIP_USER1, other_configs.tp, other_configs.opts) == false then
|
|||
|
|
log.error("初始化以太网失败")
|
|||
|
|
if other_configs.ethpower_en then
|
|||
|
|
gpio.close(other_configs.ethpower_en)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
sys.wait(1000) -- 等待以太网模块初始化完成,去掉会导致以太网初始化失败
|
|||
|
|
-- 设置以太网的 IP 地址、子网掩码、网关地址
|
|||
|
|
log.info("netdrv", "自定义以太网IP地址", other_configs.adapter_addr, "网关地址",
|
|||
|
|
other_configs.adapter_gw)
|
|||
|
|
netdrv.ipv4(socket.LWIP_USER1, other_configs.adapter_addr or "192.168.5.1", "255.255.255.0", "0.0.0.0")
|
|||
|
|
-- 获取以太网网络状态,连接后返回 true,否则返回 false,如果不存在就返回 nil。
|
|||
|
|
local count = 1
|
|||
|
|
while netdrv.ready(socket.LWIP_USER1) ~= true do
|
|||
|
|
if count > 600 then
|
|||
|
|
log.error("以太网连接超时,请检查配置")
|
|||
|
|
if other_configs.ethpower_en then
|
|||
|
|
gpio.close(other_configs.ethpower_en)
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
count = count + 1
|
|||
|
|
-- log.info("netdrv", "等待以太网就绪") -- 若以太网设备没有连上,可打开此处注释排查。
|
|||
|
|
sys.wait(100)
|
|||
|
|
end
|
|||
|
|
log.info("netdrv", "以太网就绪")
|
|||
|
|
-- 创建 DHCP 服务器,为连接到以太网的设备分配 IP 地址。
|
|||
|
|
log.info("netdrv", "创建dhcp服务器, 供以太网使用")
|
|||
|
|
if other_configs.adapter_gw then
|
|||
|
|
dhcpsrv.create({
|
|||
|
|
adapter = socket.LWIP_USER1,
|
|||
|
|
gw = other_configs.adapter_gw
|
|||
|
|
})
|
|||
|
|
else
|
|||
|
|
dhcpsrv.create({
|
|||
|
|
adapter = socket.LWIP_USER1,
|
|||
|
|
gw = {192, 168, 5, 1}
|
|||
|
|
})
|
|||
|
|
end
|
|||
|
|
-- 创建 DNS 代理服务,使得以太网接口上的设备可以通过 4G 网络访问互联网。
|
|||
|
|
log.info("netdrv", "创建dns代理服务, 供以太网使用")
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
dnsproxy.setup(adapter, main_adapter)
|
|||
|
|
netdrv.napt(main_adapter)
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--[[
|
|||
|
|
关闭网卡功能。(内核固件版本号需>=2020)
|
|||
|
|
@api exnetif.close(type,adapter)
|
|||
|
|
@param type boolean 是否为多网融合
|
|||
|
|
@param adapter number 需要关闭的网卡
|
|||
|
|
@return boolean 操作结果
|
|||
|
|
@usage
|
|||
|
|
exnetif.close(true) --关闭多网融合功能
|
|||
|
|
exnetif.close(false,socket.LWIP_ETH) --关闭优先级中的以太网网卡
|
|||
|
|
]]
|
|||
|
|
function exnetif.close(type, adapter)
|
|||
|
|
if type == true then
|
|||
|
|
-- TODO: 目前dhcpsrv扩展库,dnsproxy扩展库和napt没有关闭接口
|
|||
|
|
else
|
|||
|
|
if adapter == nil then
|
|||
|
|
log.error("请指定需要关闭的网卡")
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
-- 处理关闭操作,以太网关闭spi和供电使能。WLAN部分AP可以关闭,STA可以断开连接。4G的话就是进出飞行模式。并设置网卡为关闭状态。
|
|||
|
|
available[adapter] = connection_states.DISCONNECTED
|
|||
|
|
if adapter == socket.LWIP_AP then
|
|||
|
|
wlan.stopAP()
|
|||
|
|
elseif adapter == socket.LWIP_ETH or adapter == socket.LWIP_USER1 then
|
|||
|
|
if netdrv.CTRL_UPDOWN == nil then
|
|||
|
|
log.error("当前固件不支持关闭接口,请使用最新固件测试")
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
if eth_cfg[adapter] and eth_cfg[adapter].pwrpin then
|
|||
|
|
gpio.set(eth_cfg[adapter].pwrpin, 0)
|
|||
|
|
gpio.close(eth_cfg[adapter].pwrpin)
|
|||
|
|
end
|
|||
|
|
-- 关闭spi
|
|||
|
|
spi.close(eth_cfg[adapter].opts.spi)
|
|||
|
|
netdrv.ctrl(adapter, netdrv.CTRL_UPDOWN, 0)
|
|||
|
|
available[adapter] = connection_states.STOPED
|
|||
|
|
elseif adapter == socket.LWIP_STA then
|
|||
|
|
wlan.disconnect()
|
|||
|
|
elseif adapter == socket.LWIP_GP then
|
|||
|
|
mobile.flymode(nil, true)
|
|||
|
|
end
|
|||
|
|
log.info("exnetif", "关闭网卡功能", type_to_string(adapter))
|
|||
|
|
apply_priority()
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
return exnetif
|