Ver Fonte

update:更新Air8000/demo/http:新增https单项认证演示,网卡驱动全部修改为exnetif扩展库接口

zhutianhua há 4 meses atrás
pai
commit
7fc1499a86

+ 26 - 0
module/Air8000/demo/http/baidu_parent_ca.crt

@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIETjCCAzagAwIBAgINAe5fIh38YjvUMzqFVzANBgkqhkiG9w0BAQsFADBMMSAw
+HgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFs
+U2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xODExMjEwMDAwMDBaFw0yODEx
+MjEwMDAwMDBaMFAxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52
+LXNhMSYwJAYDVQQDEx1HbG9iYWxTaWduIFJTQSBPViBTU0wgQ0EgMjAxODCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdaydUMGCEAI9WXD+uu3Vxoa2uP
+UGATeoHLl+6OimGUSyZ59gSnKvuk2la77qCk8HuKf1UfR5NhDW5xUTolJAgvjOH3
+idaSz6+zpz8w7bXfIa7+9UQX/dhj2S/TgVprX9NHsKzyqzskeU8fxy7quRU6fBhM
+abO1IFkJXinDY+YuRluqlJBJDrnw9UqhCS98NE3QvADFBlV5Bs6i0BDxSEPouVq1
+lVW9MdIbPYa+oewNEtssmSStR8JvA+Z6cLVwzM0nLKWMjsIYPJLJLnNvBhBWk0Cq
+o8VS++XFBdZpaFwGue5RieGKDkFNm5KQConpFmvv73W+eka440eKHRwup08CAwEA
+AaOCASkwggElMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMB0G
+A1UdDgQWBBT473/yzXhnqN5vjySNiPGHAwKz6zAfBgNVHSMEGDAWgBSP8Et/qC5F
+JK5NUPpjmove4t0bvDA+BggrBgEFBQcBAQQyMDAwLgYIKwYBBQUHMAGGImh0dHA6
+Ly9vY3NwMi5nbG9iYWxzaWduLmNvbS9yb290cjMwNgYDVR0fBC8wLTAroCmgJ4Yl
+aHR0cDovL2NybC5nbG9iYWxzaWduLmNvbS9yb290LXIzLmNybDBHBgNVHSAEQDA+
+MDwGBFUdIAAwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFsc2lnbi5j
+b20vcmVwb3NpdG9yeS8wDQYJKoZIhvcNAQELBQADggEBAJmQyC1fQorUC2bbmANz
+EdSIhlIoU4r7rd/9c446ZwTbw1MUcBQJfMPg+NccmBqixD7b6QDjynCy8SIwIVbb
+0615XoFYC20UgDX1b10d65pHBf9ZjQCxQNqQmJYaumxtf4z1s4DfjGRzNpZ5eWl0
+6r/4ngGPoJVpjemEuunl1Ig423g7mNA2eymw0lIYkN5SQwCuaifIFJ6GlazhgDEw
+fpolu4usBCOmmQDo8dIm7A9+O4orkjgTHY+GzYZSR+Y0fFukAj6KYXwidlNalFMz
+hriSqHKvoflShx8xpfywgVcvzfTO3PYkz6fiNJBonf6q8amaEsybwMbDqKWwIX7e
+SPY=
+-----END CERTIFICATE-----

+ 31 - 63
module/Air8000/demo/http/http_app.lua

@@ -22,68 +22,6 @@ http核心库和httpplus扩展库的区别如下:
 ]]
 
 
---[[
-此处先详细解释下http.request接口的使用方法
-
-接口定义:
-    http.request(method, url, headers, body, opts, server_ca_cert, client_cert, client_key, client_password)
-
-使用方法:
-    local code, headers, body = http.request(method, url, headers, body, opts, server_ca_cert, client_cert, client_key, client_password).wait()
-    只能在task中使用
-    发送http请求到服务器,等待服务器的http应答,此处会阻塞当前task,等待整个过程成功结束或者出现错误异常结束或者超时结束
-
-参数定义:
-    method,stirng类型,必须包含此参数,表示HTTP请求方法,支持"GET"、"POST"、"HEAD"等所有HTTP请求方法
-    url,string类型,必须包含此参数,表示HTTP请求URL地址,支持HTTP、HTTPS,支持域名、IP地址,支持自定义端口,标准的HTTP URL格式都支持
-    headers,table或者nil类型,可选包含此参数,表示HTTP请求头,例如 {["Content-Type"] = "application/x-www-form-urlencoded", ["self_defined_key"] = "self_defined_value"} 
-    body,string或者zbuff或者nil类型,可选包含此参数,表示HTTP请求体,如果请求体是一个文件中的内容,要把文件内容读出来,赋值给body使用
-    opts,table或者nil类型,可选包含此参数,表示HTTP请求的一些额外配置,包含以下内容
-    {
-        timeout    -- -- number或者nil类型,单位毫秒,可选包含此参数,表示从发送请求到读取到服务器响应整个过程的超时时间,如果传入0,表示永久等待;如果没有传入此参数或者传入nil,则使用默认值10分钟
-        dst        -- 下载路径,string类型,当HTTP请求的数据需要保存到文件中时,此处填写完整的文件路径
-        adapter    -- 使用的网卡ID,number类型,例如4G网卡,SPI外挂以太网卡,WIFI网卡等;如果没有传入此参数,内核固件会自动选择当前时间点其他功能模块设置的默认网卡
-                    -- 除非你HTTP请求时,一定要使用某一种网卡,才设置此参数;如果没什么特别要求,不要使用此参数,使用系统中设置的默认网卡即可
-                    -- 这个参数和本demo中的netdrv_device.lua关系比较大,netdrv_device会设置默认网卡,此处http不要设置adapter参数,直接使用netdrv_device设置的默认网卡就行
-        debug      -- 调试开关,bool类型,true表示打开debug调试信息日志,false表示关闭debug调试信息日志,默认为关闭状态
-        ipv6       -- 是否为ipv6,bool类型,true表示使用ipv6,false表示不使用ipv6,默认为false
-        userdata   -- 下载回调函数使用的用户自定义回调参数,做为callback回调函数的第三个参数使用
-        callback   -- 下载回调函数,function类型,当下载数据时,无论是保存到内存中,还是保存到文件系统中,如果设置了callback,内核固件中每收到一包body数据,都会自动执行一次callback回调函数
-                    -- 回调函数的调用形式为callback(content_len, body_len, userdata)
-                    --     content_len:number类型,数据总长度
-                    --     body_len:number类型,已经下载的数据长度
-                    --     userdata:下载回调函数使用的用户自定义回调参数
-    }
-    server_ca_cert,string类型,服务器ca证书数据,可选包含此参数,当客户端需要验证服务器证书时,需要此参数,如果证书数据在一个文件中,要把文件内容读出来,赋值给server_ca_cert
-    client_cert,string类型,客户端证书数据,可选包含此参数,当服务器需要验证客户端证书时,需要此参数,如果证书数据在一个文件中,要把文件内容读出来,赋值给client_cert
-    client_key, string类型,客户端加密后的私钥数据,可选包含此参数,当服务器需要验证客户端证书时,需要此参数,如果加密后的私钥数据在一个文件中,要把文件内容读出来,赋值给client_key
-    client_password,string类型,客户端私钥口令数据,可选包含此参数,当服务器需要验证客户端证书时,需要此参数,如果私钥口令数据在一个文件中,要把文件内容读出来,赋值给client_password
-
-返回值定义:
-
-    http.request().wait()有三个返回值code,headers,body
-    code表示执行结果,number类型,有以下两种含义:
-        1、code大于等于100时,表示服务器返回的HTTP状态码,例如200表示成功,详细说明可以通过搜索引擎搜索“HTTP状态码”自行了解
-        2、code小于0时,表示内核固件中检测到通信异常,有如下几种:
-            -1 HTTP_ERROR_STATE 错误的状态, 一般是底层异常,请报issue
-            -2 HTTP_ERROR_HEADER 错误的响应头部, 通常是服务器问题
-            -3 HTTP_ERROR_BODY 错误的响应体,通常是服务器问题
-            -4 HTTP_ERROR_CONNECT 连接服务器失败, 未联网,地址错误,域名错误
-            -5 HTTP_ERROR_CLOSE 提前断开了连接, 网络或服务器问题
-            -6 HTTP_ERROR_RX 接收数据报错, 网络问题
-            -7 HTTP_ERROR_DOWNLOAD 下载文件过程报错, 网络问题或下载路径问题
-            -8 HTTP_ERROR_TIMEOUT 超时, 包括连接超时,读取数据超时
-            -9 HTTP_ERROR_FOTA fota功能报错,通常是更新包不合法  
-    headers有以下两种含义:
-        1、当code的返回值大于等于100时,headers表示服务器返回的应答头,table类型
-        2、当code的返回值小于0时,headers为nil        
-    body有以下三种含义
-        1、当code的返回值大于等于100时,如果请求的body数据不需要保存到文件中,而是直接保存到内存中,则body表示请求到的数据内容,string类型
-        2、当code的返回值大于等于100时,如果请求的body数据需要保存到文件中,则body表示保存请求数据后的文件的大小,number类型
-        3、当code的返回值小于0时,body为nil
-]]
-
-
 -- http下载数据回调函数
 -- content_len:number类型,数据总长度
 -- body_len:number类型,已经下载的数据长度
@@ -100,8 +38,9 @@ end
 -- callback可以设置回调函数,可用于实时检测body数据的下载进度
 local function http_app_get()
     -- https get请求https://www.air32.cn/网页内容
+    -- 应答体为chunk编码
     -- 如果请求成功,请求的数据保存到body中
-    local code, headers, body = http.request("GET", "https://www.air32.cn/").wait()
+    local code, headers, body = http.request("GET", "http://www.air32.cn/").wait()
     log.info("http_app_get1", 
         code==200 and "success" or "error", 
         code, 
@@ -463,6 +402,33 @@ local function http_app_post_file()
 end
 
 
+-- https+证书校验 get请求功能演示
+-- 请求的body数据保存到内存变量中,在内存够用的情况下,最大支持32KB的数据存储到内存中
+local function http_app_ca_get()
+
+    -- 用来验证server证书是否合法的ca证书文件为baidu_parent_ca.crt
+    -- 此ca证书的有效期截止到2028年11月21日
+    -- 将这个ca证书文件的内容读取出来,赋值给server_ca_cert
+    -- 注意:此处的ca证书文件仅用来验证baidu网站的server证书
+    -- baidu网站的server证书有效期截止到2026年8月10日
+    -- 在有效期之前,baidu会更换server证书,如果server证书更换后,此处验证使用的baidu_parent_ca.crt也可能需要更换
+    -- 使用电脑上的网页浏览器访问https://www.baidu.com,可以实时看到baidu的server证书以及baidu_parent_ca.crt
+    -- 如果你使用的是自己的server,要替换为自己server证书对应的ca证书文件
+    -- local server_ca_cert = io.readFile("/luadb/baidu_parent_ca.crt")
+    local server_ca_cert = io.readFile("/luadb/openluat_root_ca.crt")
+
+
+    -- https get请求https://www.bidu.cn/网页内容
+    -- 如果请求成功,请求的数据保存到body中
+    local code, headers, body = http.request("GET", "https://www.baidu.com/", nil, nil, nil, server_ca_cert).wait()
+    log.info("http_app_ca_get", 
+        code==200 and "success" or "error", 
+        code, 
+        json.encode(headers or {}), 
+        body and (body:len()>512 and body:len() or body) or "nil")
+end
+
+
 
 -- http app task 的任务处理函数
 local function http_app_task_func()
@@ -500,6 +466,8 @@ local function http_app_task_func()
         http_app_post_binary()
         -- http post文件上传功能演示
         http_app_post_file()
+        -- https+证书校验 get请求功能演示
+        http_app_ca_get()
 
         -- 60秒之后,循环测试
         sys.wait(60000)

+ 0 - 69
module/Air8000/demo/http/httpplus_app.lua

@@ -22,74 +22,6 @@ http核心库和httpplus扩展库的区别如下:
 ]]
 
 
---[[
-此处先详细解释下httpplus.request接口的使用方法
-
-接口定义:
-    httpplus.request(opts)
-
-使用方法:
-    local code, response = httpplus.request(opts)
-    只能在task中使用
-    发送http请求到服务器,等待服务器的http应答,此处会阻塞当前task,等待整个过程成功结束或者出现错误异常结束或者超时结束
-
-参数定义:
-    opts,table类型,表示HTTP请求参数,包含以下内容
-    {
-        url        -- string类型,必须包含此参数,表示HTTP请求URL地址,支持HTTP、HTTPS,支持域名、IP地址,支持自定义端口,标准的HTTP URL格式都支持
-        method     -- stirng或者nil类型,可选包含此参数,表示HTTP请求方法,支持"GET"、"POST"、"HEAD"等所有HTTP请求方法,如果没有传入此参数或者传入了nil类型,则使用默认值,默认值分为以下两种情况:
-                   -- 如果没有设置files,forms,body,bodyfile参数,则默认为"GET"
-                   -- 如果至少设置了files,forms,body,bodyfile中的一种参数,则默认为"POST"
-        headers    -- table或者nil类型,可选包含此参数,表示自定义的一个或者多个HTTP请求头,例如 {["self_defined_key1"] = "self_defined_value1", ["self_defined_key2"] = "self_defined_value2"}
-        timeout    -- number或者nil类型,单位秒,可选包含此参数,表示从发送请求到读取到服务器响应整个过程的超时时间,如果传入0,表示永久等待;如果没有传入此参数或者传入nil,则使用默认值30秒
-        files      -- table或者nil类型,可选包含此参数,表示POST上传的一个或者多个文件列表,键值对的形式,若存在本参数,会自动强制以multipart/form-data形式上传;例如
-                   -- {
-                   --     ["uploadFile"] = "/luadb/logo.jpg",
-                   --     ["logo1.jpg"] = "/luadb/logo.jpg",
-                   -- }
-
-        forms      -- table或者nil类型,可选包含此参数,表示POST上传的一个或者多个表单参数列表,键值对的形式
-                   -- 若存在本参数并且不存在files参数,会自动强制以application/x-www-form-urlencoded形式上传
-                   -- 若存在本参数并且存在files参数,会自动强制以multipart/form-data形式上传,也就是说支持同时上传文件和表单参数
-                   -- 例如:
-                   -- {
-                   --     ["username"] = "LuatOS",
-                   --     ["password"] = "123456",
-                   -- } 
-        body       -- string,zbuff,table或者nil类型,可选包含此参数,表示自定义的body内容, 不能与files或者forms同时存在
-        bodyfile   -- string或者nil类型,可选包含此参数,表示要上传的一个文件的路径,会自动读取文件中的内容进行上传
-                   -- 不能与files或者forms同时存在
-                   -- 可以与body同时存在,与body同时存在时, 优先级高于body参数,也就是说,bodyfile对应的文件路径中的内容在body参数对应的内容之前
-        debug      -- bool或者nil类型,可选包含此参数,表示调试开关,true表示打开debug调试信息日志,false表示关闭debug调试信息日志,如果没有传入此参数或者传入了nil类型,则使用默认值false
-        try_ipv6   -- bool或者nil类型,可选包含此参数,表示是否优先尝试ipv6地址,true表示优先尝试使用ipv6,false表示不尝试使用ipv6,如果没有传入此参数或者传入了nil类型,则使用默认值false
-        adapter    -- number或者nil类型,可选包含此参数,表示使用的网卡ID,例如4G网卡,SPI外挂以太网卡,WIFI网卡等;如果没有传入此参数,内核固件会自动选择当前时间点其他功能模块设置的默认网卡
-                   -- 除非你HTTP请求时,一定要使用某一种网卡,才设置此参数;如果没什么特别要求,不要使用此参数,使用系统中设置的默认网卡即可
-                   -- 这个参数和本demo中的netdrv_device.lua关系比较大,netdrv_device会设置默认网卡,此处http不要设置adapter参数,直接使用netdrv_device设置的默认网卡就行
-    }
-
-返回值定义:
-    httpplus.request(opts)有两个返回值code,response
-    code表示执行结果,number类型,有以下两种含义:
-        1、code大于等于100时,表示服务器返回的HTTP状态码,例如200表示成功,详细说明可以通过搜索引擎搜索“HTTP状态码”自行了解
-        2、code小于0时,表示内核固件中检测到通信异常,有如下几种:
-            -1 HTTP_ERROR_STATE 错误的状态, 一般是底层异常,请报issue
-            -2 HTTP_ERROR_HEADER 错误的响应头部, 通常是服务器问题
-            -3 HTTP_ERROR_BODY 错误的响应体,通常是服务器问题
-            -4 HTTP_ERROR_CONNECT 连接服务器失败, 未联网,地址错误,域名错误
-            -5 HTTP_ERROR_CLOSE 提前断开了连接, 网络或服务器问题
-            -6 HTTP_ERROR_RX 接收数据报错, 网络问题
-            -7 HTTP_ERROR_DOWNLOAD 下载文件过程报错, 网络问题或下载路径问题
-            -8 HTTP_ERROR_TIMEOUT 超时, 包括连接超时,读取数据超时
-            -9 HTTP_ERROR_FOTA fota功能报错,通常是更新包不合法     
-    response有以下两种含义
-        1、当code的返回值大于等于100时,response为table类型,包含以下两项内容
-           {
-               headers = {},    -- table类型,一个或者多个应答头,键值对的形式,可以使用json.encode(response.headers)在日志中打印
-               body = ,         -- zbuff类型,应答体数据;通过zbuff的query函数,可以转化为string类型:response.body:query();也可以通过uart.tx等支持zbuff的函数直接使用,例如uart.tx(1, response.body)
-           }
-        2、当code的返回值小于0时,response为nil
-]]
-
 local httpplus = require "httpplus"
 
 
@@ -314,7 +246,6 @@ local function httpplus_app_post_file()
 end
 
 
-
 -- http app task 的任务处理函数
 local function httpplus_app_task_func() 
     while true do

+ 10 - 4
module/Air8000/demo/http/netdrv/netdrv_4g.lua

@@ -13,6 +13,15 @@
 
 local function ip_ready_func(ip, adapter)
     if adapter == socket.LWIP_GP then
+        -- 在位置1和2设置自定义的DNS服务器ip地址:
+        -- "223.5.5.5",这个DNS服务器IP地址是阿里云提供的DNS服务器IP地址;
+        -- "114.114.114.114",这个DNS服务器IP地址是国内通用的DNS服务器IP地址;
+        -- 可以加上以下两行代码,在自动获取的DNS服务器工作不稳定的情况下,这两个新增的DNS服务器会使DNS服务更加稳定可靠;
+        -- 如果使用专网卡,不要使用这两行代码;
+        -- 如果使用国外的网络,不要使用这两行代码;
+        socket.setDNS(adapter, 1, "223.5.5.5")
+        socket.setDNS(adapter, 2, "114.114.114.114")
+        
         log.info("netdrv_4g.ip_ready_func", "IP_READY", socket.localIP(socket.LWIP_GP))
     end
 end
@@ -30,8 +39,5 @@ end
 sys.subscribe("IP_READY", ip_ready_func)
 sys.subscribe("IP_LOSE", ip_lose_func)
 
-
--- 设置默认网卡为socket.LWIP_GP
 -- 在Air8000上,内核固件运行起来之后,默认网卡就是socket.LWIP_GP
--- 在单4G网卡使用场景下,下面这一行代码加不加都没有影响,为了和其他网卡驱动模块的代码风格保持一致,所以加上了
-socket.dft(socket.LWIP_GP)
+

+ 36 - 54
module/Air8000/demo/http/netdrv/netdrv_eth_spi.lua

@@ -15,8 +15,19 @@
 本文件没有对外接口,直接在其他功能模块中require "netdrv_eth_spi"就可以加载运行;
 ]]
 
-local function ip_ready_func(ip, adapter)
+local exnetif = require "exnetif"
+
+local function ip_ready_func(ip, adapter)    
     if adapter == socket.LWIP_ETH then
+        -- 在位置1和2设置自定义的DNS服务器ip地址:
+        -- "223.5.5.5",这个DNS服务器IP地址是阿里云提供的DNS服务器IP地址;
+        -- "114.114.114.114",这个DNS服务器IP地址是国内通用的DNS服务器IP地址;
+        -- 可以加上以下两行代码,在自动获取的DNS服务器工作不稳定的情况下,这两个新增的DNS服务器会使DNS服务更加稳定可靠;
+        -- 如果使用专网卡,不要使用这两行代码;
+        -- 如果使用国外的网络,不要使用这两行代码;
+        socket.setDNS(adapter, 1, "223.5.5.5")
+        socket.setDNS(adapter, 2, "114.114.114.114")
+
         log.info("netdrv_eth_spi.ip_ready_func", "IP_READY", socket.localIP(socket.LWIP_ETH))
     end
 end
@@ -28,61 +39,32 @@ local function ip_lose_func(adapter)
 end
 
 
--- 此处订阅"IP_READY"和"IP_LOSE"两种消息
--- 在消息的处理函数中,仅仅打印了一些信息,便于实时观察“通过SPI外挂CH390H芯片的以太网卡”的连接状态
--- 也可以根据自己的项目需求,在消息处理函数中增加自己的业务逻辑控制,例如可以在连网状态发生改变时更新网络图标
-sys.subscribe("IP_READY", ip_ready_func)
-sys.subscribe("IP_LOSE", ip_lose_func)
+-- 以太网联网成功(成功连接路由器,并且获取到了IP地址)后,内核固件会产生一个"IP_READY"消息
+-- 各个功能模块可以订阅"IP_READY"消息实时处理以太网联网成功的事件
+-- 也可以在任何时刻调用socket.adapter(socket.LWIP_ETH)来获取以太网是否连接成功
 
+-- 以太网断网后,内核固件会产生一个"IP_LOSE"消息
+-- 各个功能模块可以订阅"IP_LOSE"消息实时处理以太网断网的事件
+-- 也可以在任何时刻调用socket.adapter(socket.LWIP_ETH)来获取以太网是否连接成功
 
--- 设置默认网卡为socket.LWIP_ETH
-socket.dft(socket.LWIP_ETH)
+--此处订阅"IP_READY"和"IP_LOSE"两种消息
+--在消息的处理函数中,仅仅打印了一些信息,便于实时观察“通过SPI外挂CH390H芯片的以太网卡”的连接状态
+--也可以根据自己的项目需求,在消息处理函数中增加自己的业务逻辑控制,例如可以在连网状态发生改变时更新网络图标
+sys.subscribe("IP_READY", ip_ready_func)
+sys.subscribe("IP_LOSE", ip_lose_func)
 
 
--- 本demo测试使用的是Air8000开发板
+-- 配置SPI外接以太网芯片CH390H的单网卡,exnetif.set_priority_order使用的网卡编号为socket.LWIP_ETH
+-- 本demo使用Air8000开发板测试,开发板上的硬件配置为:
 -- GPIO140为CH390H以太网芯片的供电使能控制引脚
-gpio.setup(140, 1, gpio.PULLUP)
-
--- 这个task的核心业务逻辑是:初始化SPI,初始化以太网卡,并在以太网卡上开启动态主机配置协议
-local function netdrv_eth_spi_task_func()
-    -- 初始化SPI1
-    local result = spi.setup(
-        1,--spi_id
-        nil,
-        0,--CPHA
-        0,--CPOL
-        8,--数据宽度
-        25600000--,--频率
-        -- spi.MSB,--高低位顺序    可选,默认高位在前
-        -- spi.master,--主模式     可选,默认主
-        -- spi.full--全双工       可选,默认全双工
-    )
-    log.info("netdrv_eth_spi", "spi open result", result)
-    --返回值为0,表示打开成功
-    if result ~= 0 then
-        log.error("netdrv_eth_spi", "spi open error",result)
-        return
-    end
-
-    -- 初始化以太网卡
-
-    -- 以太网联网成功(成功连接路由器,并且获取到了IP地址)后,内核固件会产生一个"IP_READY"消息
-    -- 各个功能模块可以订阅"IP_READY"消息实时处理以太网联网成功的事件
-    -- 也可以在任何时刻调用socket.adapter(socket.LWIP_ETH)来获取以太网是否连接成功
-
-    -- 以太网断网后,内核固件会产生一个"IP_LOSE"消息
-    -- 各个功能模块可以订阅"IP_LOSE"消息实时处理以太网断网的事件
-    -- 也可以在任何时刻调用socket.adapter(socket.LWIP_ETH)来获取以太网是否连接成功
-
-    -- socket.LWIP_ETH 指定网络适配器编号
-    -- netdrv.CH390外挂CH390
-    -- SPI ID 1, 片选 GPIO12
-    netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {spi=1, cs=12})
-
-    -- 在以太网上开启动态主机配置协议
-    netdrv.dhcp(socket.LWIP_ETH, true)
-end
-
--- 创建并且启动一个task
--- task的处理函数为netdrv_eth_spi_task_func
-sys.taskInit(netdrv_eth_spi_task_func)
+-- 使用spi1,片选引脚使用GPIO12
+-- 如果使用的硬件不是Air8000开发板,根据自己的硬件配置修改以下参数
+exnetif.set_priority_order({
+    {
+        ETHERNET = {
+            pwrpin = 140, 
+            tp = netdrv.CH390,
+            opts = {spi = 1, cs = 12}
+        }
+    }
+})

+ 9 - 0
module/Air8000/demo/http/netdrv/netdrv_multiple.lua

@@ -24,6 +24,15 @@ local exnetif = require "exnetif"
 --     net_type:为nil
 --     adapter:number类型,为-1
 local function netdrv_multiple_notify_cbfunc(net_type,adapter)
+    -- 在位置1和2设置自定义的DNS服务器ip地址:
+    -- "223.5.5.5",这个DNS服务器IP地址是阿里云提供的DNS服务器IP地址;
+    -- "114.114.114.114",这个DNS服务器IP地址是国内通用的DNS服务器IP地址;
+    -- 可以加上以下两行代码,在自动获取的DNS服务器工作不稳定的情况下,这两个新增的DNS服务器会使DNS服务更加稳定可靠;
+    -- 如果使用专网卡,不要使用这两行代码;
+    -- 如果使用国外的网络,不要使用这两行代码;
+    socket.setDNS(adapter, 1, "223.5.5.5")
+    socket.setDNS(adapter, 2, "114.114.114.114")
+    
     if type(net_type)=="string" then
         log.info("netdrv_multiple_notify_cbfunc", "use new adapter", net_type, adapter)
     elseif type(net_type)=="nil" then

+ 46 - 0
module/Air8000/demo/http/netdrv/netdrv_pc.lua

@@ -0,0 +1,46 @@
+--[[
+@module  netdrv_pc
+@summary “pc模拟器网卡”驱动模块 
+@version 1.0
+@date    2025.07.01
+@author  朱天华
+@usage
+本文件为pc模拟器网卡驱动模块,核心业务逻辑为:
+1、监听"IP_READY"和"IP_LOSE",在日志中进行打印;
+
+本文件没有对外接口,直接在其他功能模块中require "netdrv_pc"就可以加载运行;
+]]
+
+local function ip_ready_func(ip, adapter)    
+    if adapter == socket.ETH0 then
+        -- 在位置1和2设置自定义的DNS服务器ip地址:
+        -- "223.5.5.5",这个DNS服务器IP地址是阿里云提供的DNS服务器IP地址;
+        -- "114.114.114.114",这个DNS服务器IP地址是国内通用的DNS服务器IP地址;
+        -- 可以加上以下两行代码,在自动获取的DNS服务器工作不稳定的情况下,这两个新增的DNS服务器会使DNS服务更加稳定可靠;
+        -- 如果使用专网卡,不要使用这两行代码;
+        -- 如果使用国外的网络,不要使用这两行代码;
+        socket.setDNS(adapter, 1, "223.5.5.5")
+        socket.setDNS(adapter, 2, "114.114.114.114")
+
+        log.info("netdrv_pc.ip_ready_func", "IP_READY", socket.localIP(socket.ETH0))
+    end
+end
+
+local function ip_lose_func(adapter)    
+    if adapter == socket.ETH0 then
+        log.warn("netdrv_pc.ip_lose_func", "IP_LOSE")
+    end
+end
+
+
+
+--此处订阅"IP_READY"和"IP_LOSE"两种消息
+--在消息的处理函数中,仅仅打印了一些信息,便于实时观察pc模拟器网络的连接状态
+--也可以根据自己的项目需求,在消息处理函数中增加自己的业务逻辑控制,例如可以在连网状态发生改变时更新网络图标
+sys.subscribe("IP_READY", ip_ready_func)
+sys.subscribe("IP_LOSE", ip_lose_func)
+
+-- 设置默认网卡为socket.ETH0
+-- pc模拟器上的默认网卡仍然需要使用接口(socket.ETH0)来设置,因为exnetif扩展库当前还不支持模拟器
+socket.dft(socket.ETH0)
+

+ 36 - 21
module/Air8000/demo/http/netdrv/netdrv_wifi.lua

@@ -13,9 +13,20 @@
 本文件没有对外接口,直接在其他功能模块中require "netdrv_wifi"就可以加载运行;
 ]]
 
+local exnetif = require "exnetif"
+
 local function ip_ready_func(ip, adapter)
     if adapter == socket.LWIP_STA then
-        log.info("netdrv_wifi.ip_ready_func", "IP_READY", json.encode(wlan.getInfo()))
+        -- 在位置1和2设置自定义的DNS服务器ip地址:
+        -- "223.5.5.5",这个DNS服务器IP地址是阿里云提供的DNS服务器IP地址;
+        -- "114.114.114.114",这个DNS服务器IP地址是国内通用的DNS服务器IP地址;
+        -- 可以加上以下两行代码,在自动获取的DNS服务器工作不稳定的情况下,这两个新增的DNS服务器会使DNS服务更加稳定可靠;
+        -- 如果使用专网卡,不要使用这两行代码;
+        -- 如果使用国外的网络,不要使用这两行代码;
+        socket.setDNS(adapter, 1, "223.5.5.5")
+        socket.setDNS(adapter, 2, "114.114.114.114")
+
+        log.info("netdrv_wifi.ip_ready_func", "IP_READY", socket.localIP(socket.LWIP_STA))
     end
 end
 
@@ -26,28 +37,32 @@ local function ip_lose_func(adapter)
 end
 
 
--- 此处订阅"IP_READY"和"IP_LOSE"两种消息
--- 在消息的处理函数中,仅仅打印了一些信息,便于实时观察WIFI的连接状态
--- 也可以根据自己的项目需求,在消息处理函数中增加自己的业务逻辑控制,例如可以在连网状态发生改变时更新网络图标
-sys.subscribe("IP_READY", ip_ready_func)
-sys.subscribe("IP_LOSE", ip_lose_func)
+--WIFI联网成功(做为STATION成功连接AP,并且获取到了IP地址)后,内核固件会产生一个"IP_READY"消息
+--各个功能模块可以订阅"IP_READY"消息实时处理WIFI联网成功的事件
+--也可以在任何时刻调用socket.adapter(socket.LWIP_STA)来获取WIFI网络是否连接成功
 
+--WIFI断网后,内核固件会产生一个"IP_LOSE"消息
+--各个功能模块可以订阅"IP_LOSE"消息实时处理WIFI断网的事件
+--也可以在任何时刻调用socket.adapter(socket.LWIP_STA)来获取WIFI网络是否连接成功
 
--- 设置默认网卡为socket.LWIP_STA
-socket.dft(socket.LWIP_STA)
-
+--此处订阅"IP_READY"和"IP_LOSE"两种消息
+--在消息的处理函数中,仅仅打印了一些信息,便于实时观察WIFI的连接状态
+--也可以根据自己的项目需求,在消息处理函数中增加自己的业务逻辑控制,例如可以在连网状态发生改变时更新网络图标
+sys.subscribe("IP_READY", ip_ready_func)
+sys.subscribe("IP_LOSE", ip_lose_func)
 
-wlan.init()
--- 连接WIFI热点,连接结果会通过"IP_READY"或者"IP_LOSE"消息通知
--- Air8000仅支持2.4G的WIFI,不支持5G的WIFI
--- 此处前两个参数表示WIFI热点名称以及密码,更换为自己测试时的真实参数即可
--- 第三个参数1表示WIFI连接异常时,内核固件会自动重连
-wlan.connect("茶室-降功耗,找合宙!", "Air123456", 1)
 
--- WIFI联网成功(做为STATION成功连接AP,并且获取到了IP地址)后,内核固件会产生一个"IP_READY"消息
--- 各个功能模块可以订阅"IP_READY"消息实时处理WIFI联网成功的事件
--- 也可以在任何时刻调用socket.adapter(socket.LWIP_STA)来获取WIFI网络是否连接成功
+-- 配置WiFi设备模式的单网卡,exnetif.set_priority_order使用的网卡编号为socket.LWIP_STA
+-- ssid为要连接的WiFi路由器名称;
+-- password为要连接的WiFi路由器密码;
+-- 注意:仅支持2.4G的WiFi,不支持5G的WiFi;
+-- 实际测试时,根据自己要连接的WiFi热点信息修改以下参数
+exnetif.set_priority_order({
+    {
+        WIFI = {
+            ssid = "茶室-降功耗,找合宙!", 
+            password = "Air123456"
+        }
+    }
+})
 
--- WIFI断网后,内核固件会产生一个"IP_LOSE"消息
--- 各个功能模块可以订阅"IP_LOSE"消息实时处理WIFI断网的事件
--- 也可以在任何时刻调用socket.adapter(socket.LWIP_STA)来获取WIFI网络是否连接成功

+ 4 - 0
module/Air8000/demo/http/netdrv_device.lua

@@ -10,6 +10,7 @@
 2、netdrv_wifi:socket.LWIP_STA,WIFI STA网卡;
 3、netdrv_ethernet_spi:socket.LWIP_ETH,通过SPI外挂CH390H芯片的以太网卡;
 4、netdrv_multiple:可以配置多种网卡的优先级,按照优先级配置,使用其中一种网卡连接外网;
+5、netdrv_pc:pc模拟器上的网卡
 
 根据自己的项目需求,只需要require以上四种中的一种即可;
 
@@ -31,3 +32,6 @@ require "netdrv_4g"
 
 -- 加载“可以配置优先级的多种网卡”驱动模块
 -- require "netdrv_multiple"
+
+-- 加载“pc模拟器网卡”驱动模块
+-- require "netdrv_pc"