跳转至

exnetif - 网络优先级控制与多网融合模块

作者:魏健强

一、概述

exnetif 模块用于简化多网络环境下的优先级管理,例如(以太网 > WiFi > 4G)和多网融合操作;通过设置网络优先级,模块自动选择最优网卡上网,并支持配置网络代理实现多网融合功能(如 4G 作为数据出口供 WiFi/以太网设备上网);

网络拓扑图:

多网:

单以太网:

单wifi:

单4G:

4G_out-wifi_in-eth_in:

eth_out-wifi_in-eth_in:

wifi_out-eth_in-wifi_in:

二、核心示例

1、核心示例是指:使用本扩展库文件提供的 API,开发的基础业务逻辑的演示代码;

2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;

3、多网优先级和单网的更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 tcp,mqtt等网络demo的netdrv目录;

-- 设置网络优先级(以太网 > WiFi > 4G)
exnetif.set_priority_order({{ -- 最高优先级:以太网

    ETHERNET = {

        pwrpin = 13, -- 以太网供电引脚

        need_ping = true, -- 启用PING检测

        local_network_mode = true -- 自动设置网关为PING_IP

    }

}, { -- 次优先级:WiFi

    WIFI = {

        ssid = "your_ssid",

        password = "your_pwd",

    }

}, { -- 最低优先级:4G

    LWIP_GP = true

}})

-- 设置网络状态回调

exnetif.notify_status(function(net_type, adapter)

    log.info("网络切换至:", net_type)

end)

4、多网融合的更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的network_routing demo;

res = exnetif.setproxy(socket.LWIP_ETH, socket.LWIP_GP, {
    ethpower_en = 20,               -- 以太网模块的pwrpin引脚(gpio编号)
    tp = netdrv.CH390,              -- 网卡芯片型号(选填参数),仅spi方式外挂以太网时需要填写。
    opts = {spi = 0, cs = 8},       -- 外挂方式,需要额外的参数(选填参数),仅spi方式外挂以太网时需要填写。
})

三、常量详解

核心库常量,顾名思义是由合宙 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;

3.1 socket.LWIP_ETH

常量含义:以太网网卡;
数据类型:number
取值范围:4
示例代码: exnetif.setproxy(socket.LWIP_AP, socket.LWIP_ETH, {
            ssid = "test2",                    
            password = "HZ88888888",         
         })

3.2 socket.LWIP_AP

常量含义:wifi_ap网卡
数据类型:number
取值范围:3
示例代码: exnetif.setproxy(socket.LWIP_AP, socket.LWIP_STA, {
            ssid = "test2",                    
            password = "HZ88888888",         
         })

3.3 socket.LWIP_STA

常量含义:wifi_sta网卡
数据类型:number
取值范围:2
示例代码: exnetif.setproxy(socket.LWIP_AP, socket.LWIP_STA, {
            ssid = "test2",                    
            password = "HZ88888888",         
         })

3.4 socket.LWIP_GP

常量含义:4G网卡
数据类型:number
取值范围:1
示例代码: exnetif.setproxy(socket.LWIP_AP, socket.LWIP_GP, {
            ssid = "test2",                    
            password = "HZ88888888",         
         })

3.5 socket.LWIP_USER1

常量含义:自定义网卡;
数据类型:number
取值范围:8
示例代码:exnetif.setproxy(socket.LWIP_USER1, socket.LWIP_ETH, {
            ethpower_en = 13       
        })

3.6 netdrv.CH390

常量含义:网卡芯片,南京沁恒CH390系列,支持CH390D/CH390H, SPI通信
数据类型:number
取值范围:暂无;
示例代码:exnetif.set_priority_order({
            {
                ETHERNET = {
                    pwrpin = 140, 
                    tp = netdrv.CH390,
                    opts = {spi = 1, cs = 12}
                }
            }
        })

四、函数详解

4.1 exnetif.set_priority_order(networkConfigs)

功能

设置网络优先级并初始化网络;

注意事项

可以开启单网络或多网优先级,单网时不会判断网络连通性,多网络时根据table中的顺序确定联网优先级;

参数

networkConfigs

含义说明:网络配置表,按优先级从高到低排序;
        -- 多网络模式,填写多个网络:
        {
        -- 参数含义:配置WiFi参数;
        -- 数据类型:table;
        -- 取值范围:暂无;
        -- 是否必选:可选;
        -- 注意事项:根据位置决定优先级顺序,当前wifi优先级最高;
        -- 参数示例: 
                    { 
                        WIFI = {
                            -- 参数含义:WiFi名称;
                            -- 数据类型:string;
                            -- 取值范围:暂无;
                            -- 是否必选:必选;
                            -- 注意事项:暂无;
                            -- 参数示例:
                            ssid = "your_ssid",  
                            -- 参数含义:WiFi密码;
                            -- 数据类型:string;
                            -- 取值范围:暂无;
                            -- 是否必选:必选;
                            -- 注意事项:暂无;
                            -- 参数示例:
                            password = "your_pwd",  
                            -- 参数含义:是否需要通过ping来测试网络的连通性;
                            -- 数据类型:boolean/nil;
                            -- 取值范围:true/false;
                            -- 是否必选:可选;
                            -- 注意事项:-- 在没有ping测试环境的项目中,需要将这个参数为false,表示不需要ping测试网络连通,
                                        -- 仅根据IP READYip地址)来判断网络环网络连通性则无法保证
                                        -- 如果没有设置此参数,默认为true
                                        -- 在有ping测试环境要将这个参数设置为true
                            -- 参数示例:            
                            need_ping = true,         
                            -- 参数含义:局域网模式(选填参数),设置为true时,exnetif会自动将ping_ip设置为网卡的网ip;
                            -- 数据类型:boolean/nil;
                            -- 取值范围:true/false;
                            -- 是否必选:可选;
                            -- 注意事项:-- 用户不需要传入ping_ip参数,即使传入了,也无效;
                                        -- 这个模式的使用场景,仅适用于局域网环境;可以访问外网时,不要使用
                            -- 参数示例:            
                            local_network_mode = true,
                            -- 参数含义:连通性检测IP(选填参数),默认使用httpdns获取baidu.com的ip作为判断条件;
                            -- 数据类型:string/nil;
                            -- 取值范围:暂无;
                            -- 是否必选:可选;
                            -- 注意事项:-- 注:如果填写ip,则ping通作为判断网络是否可用的条件,
                                        -- 所以需要根据网络环境填写内网或者外网ip,
                                        -- 填写外网ip的话要保证外网ip始终可用,
                                        -- 填写局域网ip的话要确保相应ip固定且能够被ping通
                            -- 参数示例:           
                            ping_ip = "112.125.89.8", 
                            -- 参数含义:填写ping_ip且未ping通时的检测间隔(ms, 可选,默认为10秒);
                            -- 数据类型:number/nil;
                            -- 取值范围:暂无;
                            -- 是否必选:可选;
                            -- 注意事项:定时ping将会影响模块功耗,使用低功耗模式的话可以适当延迟间隔时间
                            -- 参数示例:
                            ping_time = 10000         
                        }
                    },
        -- 参数含义:配置以太网参数,Air8000系列SPI方式,780EXX系列SPI方式,8101RMII方式;
        -- 数据类型:table;
        -- 取值范围:暂无;
        -- 是否必选:可选;
        -- 注意事项:根据位置决定优先级顺序,当前以太网优先级排第二;
        -- 参数示例:
                    {
                        ETHERNET = {
                            -- 参数含义:供电使能引脚(GPIO号);
                            -- 数据类型:number;
                            -- 取值范围:暂无;
                            -- 是否必选:可选;
                            -- 注意事项:控制以太网模块供电使能;
                            -- 参数示例:
                            pwrpin = 140,
                            -- 参数含义:网卡芯片型号;
                            -- 数据类型:常量,可参考第三章节常量详解;
                            -- 取值范围:暂无;
                            -- 是否必选:可选;
                            -- 注意事项:仅spi方式外挂以太网时需要填写;
                            -- 参数示例:
                            tp = netdrv.CH390,
                            -- 参数含义:外挂方式,需要额外的参数;
                            -- 数据类型:table;
                            -- 取值范围:暂无;
                            -- 是否必选:可选;
                            -- 注意事项:仅spi方式外挂以太网时需要填写;
                            -- 参数示例:
                                        opts = {
                                            -- 参数含义:外挂的spi_id;
                                            -- 数据类型:number;
                                            -- 取值范围:暂无;
                                            -- 是否必选:必选;
                                            -- 注意事项:仅spi方式外挂以太网时需要填写;
                                            -- 参数示例:
                                            spi = 1,
                                            -- 参数含义:外挂的spi片选引脚(GPIO号);
                                            -- 数据类型:number;
                                            -- 取值范围:暂无;
                                            -- 是否必选:必选;
                                            -- 注意事项:仅spi方式外挂以太网时需要填写;
                                            -- 参数示例:
                                            cs = 12 
                                        },
                            -- 参数含义:手动设置静态IP;
                            -- 数据类型:table;
                            -- 取值范围:暂无;
                            -- 是否必选:可选;
                            -- 注意事项:选填参数,不填默认使用dhcp获取IP;
                            -- 参数示例:
                                        static_ip = {
                                            -- 参数含义:ip参数;
                                            -- 数据类型:string;
                                            -- 取值范围:暂无;
                                            -- 是否必选:必选;
                                            -- 注意事项:使用static_ip配置静态ip是必填参数;
                                            -- 参数示例:
                                            ipv4 = "192.168.5.100",
                                            -- 参数含义:子网掩码;
                                            -- 数据类型:string;
                                            -- 取值范围:暂无;
                                            -- 是否必选:必选;
                                            -- 注意事项:使用static_ip配置静态ip是必填参数;
                                            -- 参数示例:
                                            mark = "255.255.255.0",
                                            -- 参数含义:网关参数;
                                            -- 数据类型:string;
                                            -- 取值范围:暂无;
                                            -- 是否必选:必选;
                                            -- 注意事项:使用static_ip配置静态ip是必填参数;
                                            -- 参数示例:
                                            gw = "192.168.5.1"
                                        },
                            --同上
                            need_ping = true,      
                            --同上   
                            local_network_mode = true,
                            --同上
                            ping_ip = "112.125.89.8",
                        }
                    },
        -- 参数含义:配置以太网参数,8101SPI方式;
        -- 数据类型:table;
        -- 取值范围:暂无;
        -- 是否必选:可选;
        -- 注意事项:根据位置决定优先级顺序,当前外挂spi以太网优先级排第三;
        -- 参数示例:
                    {
                        ETHUSER1 = {
                            --同上
                            pwrpin = 13,
                            --同上
                            tp = netdrv.CH390,
                            --同上
                            opts = { spi = 0, cs = 15 }
                            --同上
                            need_ping = true,      
                            --同上   
                            local_network_mode = true,
                            --同上
                            ping_ip = "112.125.89.8",
                            --同上
                            static_ip = {
                                ipv4 = "192.168.5.100",
                                mark = "255.255.255.0",
                                gw = "192.168.5.1"
                            }
                        }
                    },
        -- 参数含义:是否开启4G;
        -- 数据类型:boolean/nil;
        -- 取值范围:暂无;
        -- 是否必选:可选;
        -- 注意事项:根据位置决定优先级顺序,当前4G优先级最低;
        -- 参数示例:
                    {   
                        LWIP_GP = true 
                    }
        }

        -- 单网络模式:
        -- 单网络模式下只使用WIFI网络
        {
            -- 参数含义:配置单wifi参数;
            -- 数据类型:table;
            -- 取值范围:暂无;
            -- 是否必选:必选;
            -- 注意事项:无优先级概念,不检测网络连通性;
            -- 参数示例:
                        { 
                            WIFI = {
                                ssid = "test", 
                                password = "HZ88888888",
                            }
                        }
        }
        -- 单网络模式下只使用SPI以太网网络
        {
            -- 参数含义:配置单以太网参数;
            -- 数据类型:table;
            -- 取值范围:暂无;
            -- 是否必选:必选;
            -- 注意事项:暂无;注意事项:无优先级概念,不检测网络连通性;
            -- 参数示例:
                        {
                            ETHUSER1 = {
                                pwrpin = 140, 
                                tp = netdrv.CH390,
                                opts = {spi = 1, cs = 12}
                            }
                        }
        }
        -- 单网络模式下只使用RMII以太网网络
        {
            -- 参数含义:配置单以太网参数;
            -- 数据类型:table;
            -- 取值范围:暂无;
            -- 是否必选:必选;
            -- 注意事项:暂无;注意事项:无优先级概念,不检测网络连通性;
            -- 参数示例:
                        {
                            ETHERNET = { -- 以太网配置
                                pwrpin = 13, -- 供电使能引脚(number)
                            }
                        }
        }
        -- 4G单网模式下,不需要require "exnetif",减少不必要的功能模块加载
        -- 数据类型:table;
        -- 取值范围:暂无;
        -- 是否必选:必选;
        -- 注意事项:按照表格中的顺序确定优先级;
        -- 参数示例:;
                    {
                        {
                            ETHUSER1 = {
                                pwrpin = 140, 
                                tp = netdrv.CH390,
                                opts = {spi = 1, cs = 12}
                            }
                        }
                    }
数据类型:table
取值范围:暂无;
是否必选:必选;
注意事项:根据位置决定优先级顺序,当前wifi优先级最高
参数示例: exnetif.set_priority_order(
        {{
            ETHERNET = {
                pwrpin = 13,
                need_ping = true,
                local_network_mode = true
            }
        }, {
            WIFI = {
                ssid = "your_ssid",
                password = "your_pwd"
            }
        }, {
            LWIP_GP = true
        }})

返回值
- true:成功,false:失败

示例

exnetif.set_priority_order({
    {
        ETHUSER1 = {
            pwrpin = 140, 
            tp = netdrv.CH390,
            opts = {spi = 1, cs = 12}
        }
    }
})

4.2 exnetif.notify_status(cb_fnc)

功能

设置网络状态变化回调函数;

注意事项

可选配置,设置回调函数后可以通过回调函数获取网络状态的变化;

参数

cb_fnc

参数含义:设置网络状态变化回调函数;
        回调函数接收以下两个参数,
        -- 参数含义: 网络类型字符串(如"Ethernet");
        -- 数据类型:string;
        -- 取值范围:无限制;
        -- 是否必选:必选;
        -- 注意事项:暂无;
        net_type
        -- 参数含义: 网络适配器ID(如socket.LWIP_ETH);
        -- 数据类型:string;
        -- 取值范围:无限制;
        -- 是否必选:必选;
        -- 注意事项:暂无;
        adapter
数据类型:function
取值范围:回调函数本身无取值范围这一说法;
是否必选:必选;
注意事项:每次调用会覆盖之前注册的回调函数;
参数示例:
        local function netdrv_multiple_notify_cbfunc(net_type,adapter)
            if type(net_type)=="string" then
                log.info("netdrv_multiple_notify_cbfunc", "use new adapter", net_type, adapter)
            elseif type(net_type)=="nil" then
                log.warn("netdrv_multiple_notify_cbfunc", "no available adapter", net_type, adapter)
            else
                log.warn("netdrv_multiple_notify_cbfunc", "unknown status", net_type, adapter)
            end
        end

触发条件
- 网卡切换时返回当前网卡类型和ID
- 所有网卡断网时返回 nil, -1

示例

local function netdrv_multiple_notify_cbfunc(net_type,adapter)
    if type(net_type)=="string" then
        log.info("netdrv_multiple_notify_cbfunc", "use new adapter", net_type, adapter)
    elseif type(net_type)=="nil" then
        log.warn("netdrv_multiple_notify_cbfunc", "no available adapter", net_type, adapter)
    else
        log.warn("netdrv_multiple_notify_cbfunc", "unknown status", net_type, adapter)
    end
end

exnetif.notify_status(netdrv_multiple_notify_cbfunc)

4.3 exnetif.setproxy(adapter, main_adapter, other_configs)

功能

配置网络代理实现多网融合;

注意事项

填写other_configs参数时需要注意区分adapter和main_adapter的参数,参考下文参数中的说明;

参数

adapter

参数含义:使用网络的网卡;
数据类型:常量;
取值范围:取值范围参考第三部分常量详解;
是否必选:必选;
注意事项:暂无;
参数示例:socket.LWIP_AP
main_adapter
参数含义:提供网络的网卡;
数据类型:常量;
取值范围:取值范围参考第三部分常量详解;
是否必选:必选;
注意事项:暂无;
参数示例:socket.LWIP_ETH
other_configs
参数含义:开启网卡所需的配置参数;
        {
            -- 参数含义:AP热点名称,网卡包含wifi时填写;
            -- 数据类型:string;
            -- 取值范围:暂无;
            -- 是否必选:可选;
            -- 注意事项:暂无;
            -- 参数示例:
            ssid = "test2",    
            -- 参数含义:AP热点密码,网卡包含wifi时填写;
            -- 数据类型:string;
            -- 取值范围:暂无;
            -- 是否必选:可选;
            -- 注意事项:暂无;
            -- 参数示例:                 
            password = "HZ88888888", 
            -- 参数含义:AP模式下配置项;
            -- 数据类型:table;
            -- 取值范围:暂无;
            -- 是否必选:可选;
            -- 注意事项:暂无;
            -- 参数示例:
                    ap_opts = {
                        -- 参数含义:AP是否隐藏SSID, 默认false,不隐藏;
                        -- 数据类型:boolean;
                        -- 取值范围:true/false;
                        -- 是否必选:可选;
                        -- 注意事项:暂无;
                        -- 参数示例:
                        hidden = false,      
                        -- 参数含义:AP最大客户端数量;
                        -- 数据类型:number;
                        -- 取值范围:1-4;
                        -- 是否必选:可选;
                        -- 注意事项:暂无;
                        -- 参数示例:
                        max_conn = 4 },
            -- 参数含义:AP建立的通道;
            -- 数据类型:number;
            -- 取值范围:1-13;
            -- 是否必选:可选;
            -- 注意事项:暂无;
            -- 参数示例:
            channel = 6,
            -- 参数含义:自定义LWIP_AP网卡的ip地址;
            -- 数据类型:string;
            -- 取值范围:暂无;
            -- 是否必选:可选;
            -- 注意事项:需要自定义ip和网关ip时填写
            -- 参数示例:
            adapter_addr = "192.168.5.1", 
            -- 参数含义:自定义LWIP_AP网卡的网关地址;
            -- 数据类型:table;
            -- 取值范围:暂无;
            -- 是否必选:可选;
            -- 注意事项:需要自定义ip和网关ip时填写
            -- 参数示例:
            adapter_gw = { 192, 168, 5, 1 }, 
            -- 参数含义:提供网络的网卡开启参数;
            -- 数据类型:table;
            -- 取值范围:暂无;
            -- 是否必选:必选;
            -- 注意事项:暂无;
            -- 参数示例:  
                        main_adapter = {    
                            -- 参数含义:供电使能引脚(GPIO号);
                            -- 数据类型:number;
                            -- 取值范围:暂无;
                            -- 是否必选:可选;
                            -- 注意事项:控制以太网模块供电使能
                            -- 参数示例:
                            pwrpin = 140,
                            -- 参数含义:网卡芯片型号;
                            -- 数据类型:常量,可参考第三部分常量详解;
                            -- 取值范围:暂无;
                            -- 是否必选:可选;
                            -- 注意事项:暂无;仅spi方式外挂以太网时需要填写;
                            -- 参数示例:
                            tp = netdrv.CH390,
                            -- 参数含义:外挂方式,需要额外的参数;
                            -- 数据类型:table;
                            -- 取值范围:暂无;
                            -- 是否必选:可选;
                            -- 注意事项:暂无;仅spi方式外挂以太网时需要填写;
                            -- 参数示例:
                            opts = {
                                -- 参数含义:外挂的spi_id;
                                -- 数据类型:number;
                                -- 取值范围:0/1;
                                -- 是否必选:必选;
                                -- 注意事项:仅spi方式外挂以太网时需要填写;
                                -- 参数示例:
                                spi = 1,
                                -- 参数含义:外挂的spi片选引脚(GPIO号);
                                -- 数据类型:number;
                                -- 取值范围:暂无;
                                -- 是否必选:必选;
                                -- 注意事项:仅spi方式外挂以太网时需要填写;
                                -- 参数示例:
                                cs = 12 
                            }
                    }
        }
数据类型:table
取值范围:暂无;
是否必选:必选;
注意事项:暂无;
参数示例:
        {
            ssid = "test2",                   
            password = "HZ88888888",          
            main_adapter = {                
                ethpower_en = 13
            }
        }

返回值
- true:成功,false:失败

示例

exnetif.setproxy(socket.LWIP_AP, socket.LWIP_ETH, {
    ssid = "test2",                   
    password = "HZ88888888",          
    main_adapter = {                
        ethpower_en = 140,       
        tp = netdrv.CH390,
        opts = {spi = 1, cs = 12}
    }
})

4.4 exnetif.check_network_status(interval)

功能

主动触发网络状态检测;

注意事项

可选配置,检测一次或者定时检测所有可用网络的网络连通性,当网络显示可用但是业务代码数据收发异常时可以重新检测网络连通性,如果配置定时检测会增加模块功耗;

参数

interval

参数含义:检测间隔时间ms(选填),不填时只检测一次,填写后将根据间隔时间循环检测;
数据类型:number
取值范围:暂无;
是否必选:可选;
注意事项:填写后将根据间隔时间循环检测,会提高模块功耗;
参数示例:exnetif.check_network_status()  exnetif.check_network_status(60000)
返回值
- 无

示例

exnetif.check_network_status()

五、产品支持说明

支持 LuatOS 开发的所有产品都支持 exnetif 扩展库;

注意:多网融合功能需硬件支持(如双网卡设备);