Răsfoiți Sursa

Merge branch 'master' of https://gitee.com/openLuat/LuatOS

梁健 6 luni în urmă
părinte
comite
76157bb298
79 a modificat fișierele cu 1280 adăugiri și 4723 ștergeri
  1. 2 2
      components/airlink/src/luat_airlink.c
  2. 1 1
      components/ethernet/common/dhcp_client.c
  3. 5 5
      components/mobile/luat_lib_mobile.c
  4. 115 68
      components/mreport/src/luat_mreport.c
  5. 3 3
      components/network/netdrv/src/luat_netdrv_napt.c
  6. 5 2
      components/yhm27xx/binding/luat_lib_yhm27xx.c
  7. 20 1
      luat/include/luat_pm.h
  8. 17 9
      luat/modules/luat_lib_gpio.c
  9. 167 1
      luat/modules/luat_lib_pm.c
  10. 2 2
      module/Air780EHM_Air780EHV_Air780EGH/demo/socket/client/long_connection/netdrv_device.lua
  11. 0 142
      module/Air780EHM_Air780EHV_Air780EGH/demo/tcp/TCP-UART/main.lua
  12. 0 145
      module/Air780EHM_Air780EHV_Air780EGH/demo/tcp/TCP单向认证/main.lua
  13. 0 141
      module/Air780EHM_Air780EHV_Air780EGH/demo/tcp/TCP断链续连/main.lua
  14. 0 130
      module/Air780EHM_Air780EHV_Air780EGH/demo/udp/main.lua
  15. 4 3
      module/Air780EPM/demo/lowpower/lowpower_dissipation.lua
  16. 2 2
      module/Air780EPM/demo/lowpower/main.lua
  17. 15 11
      module/Air780EPM/demo/pwm/示例1 PWM输出/main.lua
  18. 2 2
      module/Air780EPM/demo/socket/client/long_connection/netdrv_device.lua
  19. 0 142
      module/Air780EPM/demo/tcp/TCP-UART/main.lua
  20. 0 145
      module/Air780EPM/demo/tcp/TCP单向认证/main.lua
  21. 0 141
      module/Air780EPM/demo/tcp/TCP断链续连/main.lua
  22. 0 130
      module/Air780EPM/demo/udp/main.lua
  23. 46 0
      module/Air8000/demo/luatos_framework/luatos_task/create.lua
  24. 18 0
      module/Air8000/demo/luatos_framework/luatos_task/global_msg_receiver1.lua
  25. 30 0
      module/Air8000/demo/luatos_framework/luatos_task/global_msg_receiver2.lua
  26. 43 0
      module/Air8000/demo/luatos_framework/luatos_task/global_msg_sender.lua
  27. 40 32
      module/Air8000/demo/luatos_framework/luatos_task/main.lua
  28. 52 0
      module/Air8000/demo/luatos_framework/luatos_task/memory_task.lua
  29. 42 0
      module/Air8000/demo/luatos_framework/luatos_task/memory_valid.lua
  30. 149 0
      module/Air8000/demo/luatos_framework/luatos_task/non_targeted_msg.lua
  31. 47 0
      module/Air8000/demo/luatos_framework/luatos_task/readme.md
  32. 49 0
      module/Air8000/demo/luatos_framework/luatos_task/scheduling.lua
  33. 63 0
      module/Air8000/demo/luatos_framework/luatos_task/shared_resource.lua
  34. 33 0
      module/Air8000/demo/luatos_framework/luatos_task/targeted_msg_sender.lua
  35. 33 0
      module/Air8000/demo/luatos_framework/luatos_task/task_count.lua
  36. 27 0
      module/Air8000/demo/luatos_framework/luatos_task/task_func.lua
  37. 37 0
      module/Air8000/demo/luatos_framework/luatos_task/task_inout_env_err.lua
  38. 131 0
      module/Air8000/demo/luatos_framework/luatos_task/tgted_msg_receiver.lua
  39. 39 0
      module/Air8000/demo/luatos_framework/luatos_task/timer.lua
  40. 24 0
      module/Air8000/demo/luatos_framework/luatos_task/variable_args.lua
  41. 5 0
      module/Air8000/demo/mqtt/readme.md
  42. 0 266
      module/Air8000/demo/mqttv2/mqtt/mqtt_main.lua
  43. 0 64
      module/Air8000/demo/mqttv2/mqtt/mqtt_receiver.lua
  44. 0 154
      module/Air8000/demo/mqttv2/mqtt/mqtt_sender.lua
  45. 0 266
      module/Air8000/demo/mqttv2/mqtts/mqtts_main.lua
  46. 0 64
      module/Air8000/demo/mqttv2/mqtts/mqtts_receiver.lua
  47. 0 154
      module/Air8000/demo/mqttv2/mqtts/mqtts_sender.lua
  48. 0 20
      module/Air8000/demo/mqttv2/mqtts_ca/airlbs_parent_ca.crt
  49. 0 293
      module/Air8000/demo/mqttv2/mqtts_ca/mqtts_ca_main.lua
  50. 0 64
      module/Air8000/demo/mqttv2/mqtts_ca/mqtts_ca_receiver.lua
  51. 0 154
      module/Air8000/demo/mqttv2/mqtts_ca/mqtts_ca_sender.lua
  52. 0 66
      module/Air8000/demo/mqttv2/mqtts_ca/sntp_app.lua
  53. 0 33
      module/Air8000/demo/mqttv2/netdrv/netdrv_4g.lua
  54. 0 85
      module/Air8000/demo/mqttv2/netdrv/netdrv_eth_spi.lua
  55. 0 95
      module/Air8000/demo/mqttv2/netdrv/netdrv_multiple.lua
  56. 0 50
      module/Air8000/demo/mqttv2/netdrv/netdrv_wifi.lua
  57. 0 33
      module/Air8000/demo/mqttv2/netdrv_device.lua
  58. 0 64
      module/Air8000/demo/mqttv2/network_watchdog.lua
  59. 0 144
      module/Air8000/demo/mqttv2/readme.md
  60. 0 44
      module/Air8000/demo/mqttv2/timer_app.lua
  61. 0 80
      module/Air8000/demo/mqttv2/uart_app.lua
  62. 1 1
      module/Air8000/demo/socket/client/long_connection/netdrv/netdrv_wifi.lua
  63. 2 2
      module/Air8000/demo/socket/client/long_connection/netdrv_device.lua
  64. 1 1
      module/Air8000/demo/socket/client/long_connection/tcp/tcp_client_main.lua
  65. 1 1
      module/Air8000/demo/socket/client/long_connection/tcp_ssl/tcp_ssl_main.lua
  66. 1 1
      module/Air8000/demo/socket/client/long_connection/udp/udp_client_main.lua
  67. 0 142
      module/Air8000/demo/tcp/TCP-UART/main.lua
  68. 0 145
      module/Air8000/demo/tcp/TCP单向认证/main.lua
  69. 0 141
      module/Air8000/demo/tcp/TCP断链续连/main.lua
  70. 0 130
      module/Air8000/demo/udp/main.lua
  71. 1 1
      module/Air8101/demo/mqtt/netdrv_device.lua
  72. 2 2
      module/Air8101/demo/socket/client/long_connection/netdrv_device.lua
  73. 1 1
      module/Air8101/demo/socket/client/long_connection/tcp/tcp_client_main.lua
  74. 1 1
      module/Air8101/demo/socket/client/long_connection/tcp_ssl/tcp_ssl_main.lua
  75. 1 1
      module/Air8101/demo/socket/client/long_connection/udp/udp_client_main.lua
  76. 0 161
      module/Air8101/demo/tcp/TCP_Uart/main.lua
  77. 0 164
      module/Air8101/demo/tcp/TCP单向认证/main.lua
  78. 0 164
      module/Air8101/demo/tcp/TCP断链续连/main.lua
  79. 0 211
      module/Air8101/demo/udp/main.lua

+ 2 - 2
components/airlink/src/luat_airlink.c

@@ -310,8 +310,8 @@ void luat_airlink_print_mac_pkg(uint8_t* buff, uint16_t len) {
 }
 
 void luat_airlink_hexdump(const char* tag, uint8_t* buff, uint16_t len) {
-    if (len > 256) {
-        len = 256;
+    if (len > 500) {
+        len = 500;
     }
     uint8_t* tmp = luat_heap_opt_zalloc(AIRLINK_MEM_TYPE, len * 2 + 1);
     if (tmp == NULL) {

+ 1 - 1
components/ethernet/common/dhcp_client.c

@@ -124,7 +124,7 @@ void make_ip4_dhcp_select_msg(dhcp_client_info_t *dhcp, uint16_t flag, Buffer_St
 	ip4_dhcp_msg_add_integer_option(DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN, DHCP_REQUEST, out);
 	ip4_dhcp_msg_add_client_id_option(DHCP_OPTION_CLIENT_ID, (uint8_t*)dhcp->mac, 6, out);
 	ip4_dhcp_msg_add_ip_option(DHCP_OPTION_REQUESTED_IP, dhcp->temp_ip, out);
-	if (!flag)
+	if (dhcp->server_ip)
 	{
 		ip4_dhcp_msg_add_ip_option(DHCP_OPTION_SERVER_ID, dhcp->server_ip, out);
 	}

+ 5 - 5
components/mobile/luat_lib_mobile.c

@@ -1256,10 +1256,10 @@ LUAMOD_API int luaopen_mobile( lua_State *L ) {
 }
 
 static int l_mobile_event_handle(lua_State* L, void* ptr) {
-    LUAT_MOBILE_EVENT_E event;
-    uint8_t index;
-    uint8_t status;
-    // int ret;
+    LUAT_MOBILE_EVENT_E event = {0};
+    uint8_t index = 0;
+    uint8_t status = 0;
+    int ret = 0;
 
 
     rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
@@ -1388,7 +1388,7 @@ end)
             luat_ip_addr_t local_ip, net_mask, gate_way, ipv6;
             #ifdef LUAT_USE_LWIP
 	        ipv6.type = 0xff;
-	        int ret = network_get_full_local_ip_info(NULL, NW_ADAPTER_INDEX_LWIP_GPRS, &local_ip, &net_mask, &gate_way, &ipv6);
+	        ret = network_get_full_local_ip_info(NULL, NW_ADAPTER_INDEX_LWIP_GPRS, &local_ip, &net_mask, &gate_way, &ipv6);
             #else
 	        void* userdata = NULL;
 	        network_adapter_info* info = network_adapter_fetch(NW_ADAPTER_INDEX_LWIP_GPRS, &userdata);

+ 115 - 68
components/mreport/src/luat_mreport.c

@@ -38,8 +38,40 @@ static inline uint16_t u162bcd(uint16_t src) {
     return dst;
 }
 
-// 模块的基础信息
-void luat_mreport_mobile(cJSON* mreport_data) {
+// 基础信息
+static void luat_mreport_sys_basic(cJSON* mreport_data) {
+    // 时间戳
+	time_t t;
+	time(&t);
+    cJSON_AddNumberToObject(mreport_data, "localtime", t);
+
+    // luatos项目信息
+    cJSON_AddStringToObject(mreport_data, "proj", project_name);
+    cJSON_AddStringToObject(mreport_data, "pver", project_version);
+    
+    // rndis
+    cJSON_AddNumberToObject(mreport_data, "rndis", 0);
+    // usb
+    cJSON_AddNumberToObject(mreport_data, "usb", 1);
+    // vbus
+    cJSON_AddNumberToObject(mreport_data, "vbus", 1);
+
+    // 开机原因
+    cJSON_AddNumberToObject(mreport_data, "powerreson", luat_pm_get_poweron_reason());
+
+    // 开机次数
+    cJSON_AddNumberToObject(mreport_data, "bootc", 1);
+
+    // 开机时长
+    uint64_t tick64 = luat_mcu_tick64();
+    uint64_t tmms = tick64 / 1000000;
+    uint64_t tms = tick64 % 1000000;
+    cJSON_AddNumberToObject(mreport_data, "tmms", tmms);
+    cJSON_AddNumberToObject(mreport_data, "tms", tms);
+}
+
+// 模块的信息
+static void luat_mreport_mobile(cJSON* mreport_data) {
     // IMEI
     char imei[16] = {0};
     luat_mobile_get_imei(0, imei, 16);                  
@@ -77,7 +109,7 @@ void luat_mreport_mobile(cJSON* mreport_data) {
 }
 
 // 网络信息
-void luat_mreport_sim_network(cJSON* mreport_data, struct netif* netif) {
+static void luat_mreport_sim_network(cJSON* mreport_data, struct netif* netif) {
     cJSON* cells = cJSON_CreateArray();
     // ICCID
     char iccid[24] = {0};
@@ -142,6 +174,9 @@ void luat_mreport_sim_network(cJSON* mreport_data, struct netif* netif) {
             }
         }
     }
+    if (cell_info != NULL) {
+        luat_heap_free(cell_info);
+    }
 
     // ip地址
     cJSON_AddStringToObject(mreport_data, "ipv4", ip4addr_ntoa(&netif->ip_addr));
@@ -161,7 +196,7 @@ void luat_mreport_sim_network(cJSON* mreport_data, struct netif* netif) {
 }
 
 // adc信息
-void luat_mreport_adc(cJSON* mreport_data) {
+static void luat_mreport_adc(cJSON* mreport_data) {
     // adc-vbat
     if (luat_adc_open(LUAT_ADC_CH_VBAT, NULL) == 0) {
         int val = 0xFF;
@@ -183,13 +218,63 @@ void luat_mreport_adc(cJSON* mreport_data) {
 }
 
 // wifi信息
-void luat_mreport_wifi(cJSON* mreport_data) {
+static void luat_mreport_wifi(cJSON* mreport_data) {
     // wifi版本
     uint32_t wifi_version = 0;
     if (g_airlink_ext_dev_info.tp == 0x01) {
         memcpy(&wifi_version, g_airlink_ext_dev_info.wifi.version, 4);
     }
-    cJSON_AddNumberToObject(mreport_data, "wifiver", wifi_version);
+    cJSON_AddNumberToObject(mreport_data, "wifi_ver", wifi_version);
+
+    // wifi mac
+    char mac[18] = {0};
+    sprintf_(mac, "%02x:%02x:%02x:%02x:%02x:%02x", g_airlink_ext_dev_info.wifi.sta_mac[0], g_airlink_ext_dev_info.wifi.sta_mac[1], g_airlink_ext_dev_info.wifi.sta_mac[2], g_airlink_ext_dev_info.wifi.sta_mac[3], g_airlink_ext_dev_info.wifi.sta_mac[4], g_airlink_ext_dev_info.wifi.sta_mac[5]);
+    cJSON_AddStringToObject(mreport_data, "wifi_sta_mac", mac);
+    sprintf_(mac, "%02x:%02x:%02x:%02x:%02x:%02x", g_airlink_ext_dev_info.wifi.ap_mac[0], g_airlink_ext_dev_info.wifi.ap_mac[1], g_airlink_ext_dev_info.wifi.ap_mac[2], g_airlink_ext_dev_info.wifi.ap_mac[3], g_airlink_ext_dev_info.wifi.ap_mac[4], g_airlink_ext_dev_info.wifi.ap_mac[5]);
+    cJSON_AddStringToObject(mreport_data, "wifi_ap_mac", mac);
+    sprintf_(mac, "%02x:%02x:%02x:%02x:%02x:%02x", g_airlink_ext_dev_info.wifi.bt_mac[0], g_airlink_ext_dev_info.wifi.bt_mac[1], g_airlink_ext_dev_info.wifi.bt_mac[2], g_airlink_ext_dev_info.wifi.bt_mac[3], g_airlink_ext_dev_info.wifi.bt_mac[4], g_airlink_ext_dev_info.wifi.bt_mac[5]);
+    cJSON_AddStringToObject(mreport_data, "wifi_bt_mac", mac);
+
+    // wifi状态
+    cJSON_AddNumberToObject(mreport_data, "wifi_sta_state", g_airlink_ext_dev_info.wifi.sta_state);
+    cJSON_AddNumberToObject(mreport_data, "wifi_ap_state", g_airlink_ext_dev_info.wifi.ap_state);
+
+    // wifi connect ap bssid/rssi/channel
+    if (g_airlink_ext_dev_info.wifi.sta_state == 1) {
+        sprintf_(mac, "%02x:%02x:%02x:%02x:%02x:%02x", g_airlink_ext_dev_info.wifi.sta_ap_bssid[0], g_airlink_ext_dev_info.wifi.sta_ap_bssid[1], g_airlink_ext_dev_info.wifi.sta_ap_bssid[2], g_airlink_ext_dev_info.wifi.sta_ap_bssid[3], g_airlink_ext_dev_info.wifi.sta_ap_bssid[4], g_airlink_ext_dev_info.wifi.sta_ap_bssid[5]);
+        cJSON_AddStringToObject(mreport_data, "wifi_bssid", mac);
+        cJSON_AddNumberToObject(mreport_data, "wifi_rssi", g_airlink_ext_dev_info.wifi.sta_ap_rssi);
+        cJSON_AddNumberToObject(mreport_data, "wifi_channel", g_airlink_ext_dev_info.wifi.sta_ap_channel);
+    }
+}
+
+// 内存信息
+static void luat_mreport_meminfo(cJSON* mreport_data) {
+    // 当前内存状态
+    size_t total = 0;
+    size_t used = 0;
+    size_t max_used = 0;
+    cJSON* meminfo_sram = cJSON_CreateArray();
+    luat_meminfo_opt_sys(LUAT_HEAP_SRAM, &total, &used, &max_used);
+    cJSON_AddItemToArray(meminfo_sram, cJSON_CreateNumber(total));
+    cJSON_AddItemToArray(meminfo_sram, cJSON_CreateNumber(used));
+    cJSON_AddItemToArray(meminfo_sram, cJSON_CreateNumber(max_used));
+    cJSON_AddItemToObject(mreport_data, "mem_sram", meminfo_sram);
+    
+    cJSON* meminfo_psram = cJSON_CreateArray();
+    luat_meminfo_opt_sys(LUAT_HEAP_PSRAM, &total, &used, &max_used);
+    cJSON_AddItemToArray(meminfo_psram, cJSON_CreateNumber(total));
+    cJSON_AddItemToArray(meminfo_psram, cJSON_CreateNumber(used));
+    cJSON_AddItemToArray(meminfo_psram, cJSON_CreateNumber(max_used));
+    cJSON_AddItemToObject(mreport_data, "mem_psram", meminfo_psram);
+
+    cJSON* meminfo_luavm = cJSON_CreateArray();
+    luat_meminfo_luavm(&total, &used, &max_used);
+    cJSON_AddItemToArray(meminfo_luavm, cJSON_CreateNumber(total));
+    cJSON_AddItemToArray(meminfo_luavm, cJSON_CreateNumber(used));
+    cJSON_AddItemToArray(meminfo_luavm, cJSON_CreateNumber(max_used));
+    cJSON_AddItemToObject(mreport_data, "mem_lua", meminfo_luavm);
+    cJSON_AddNumberToObject(mreport_data, "memfree", total - used);
 }
 
 void luat_mreport_send(void) {
@@ -198,21 +283,26 @@ void luat_mreport_send(void) {
     size_t olen = 0;
     cJSON* mreport_data = cJSON_CreateObject();
 
-    luat_netdrv_t* netdrv = luat_netdrv_get(NW_ADAPTER_INDEX_LWIP_GPRS);
+    int adapter_index = network_register_get_default();
+	if (adapter_index < 0 || adapter_index >= NW_ADAPTER_QTY){
+		LLOGE("尚无已注册的网络适配器");
+		return;
+	}
+    luat_netdrv_t* netdrv = luat_netdrv_get(adapter_index);
     if (netdrv == NULL || netdrv->netif == NULL) {
         return;
     }
 
     struct netif *netif = netdrv->netif;
-    if (netif == NULL || ip_addr_isany(&netif->ip_addr)) {
-        // LLOGD("还没联网");
+    if (ip_addr_isany(&netif->ip_addr)) {
+        LLOGD("还没联网");
         return;
     }
 
     if (mreport_pcb == NULL) {
         mreport_pcb = udp_new();
         if (mreport_pcb == NULL) {
-            LLOGE("创建udp pcb 失败, 内存不足?");
+            LLOGE("创建,mreport udp pcb 失败, 内存不足?");
             cJSON_Delete(mreport_data);
             return;
         }
@@ -226,83 +316,40 @@ void luat_mreport_send(void) {
         return;
     }
 
-    // 时间戳
-	time_t t;
-	time(&t);
-    cJSON_AddNumberToObject(mreport_data, "localtime", t);
-
-    // luatos项目信息
-    cJSON_AddStringToObject(mreport_data, "proj", project_name);
-    cJSON_AddStringToObject(mreport_data, "pver", project_version);
-
+    // 基础信息
+    luat_mreport_sys_basic(mreport_data);
     // 模组信息
     luat_mreport_mobile(mreport_data);
-
     // sim卡和网络相关
     luat_mreport_sim_network(mreport_data, netif);
-
     // adc信息
     luat_mreport_adc(mreport_data);
-
     // wifi信息
+#ifdef LUAT_USE_DRV_WLAN
     luat_mreport_wifi(mreport_data);
-
-    // rndis
-    cJSON_AddNumberToObject(mreport_data, "rndis", 0);
-    // usb
-    cJSON_AddNumberToObject(mreport_data, "usb", 1);
-    // vbus
-    cJSON_AddNumberToObject(mreport_data, "vbus", 1);
-
-    // 开机原因
-    cJSON_AddNumberToObject(mreport_data, "powerreson", luat_pm_get_poweron_reason());
-    // 当前内存状态
-    size_t total = 0;
-    size_t used = 0;
-    size_t max_used = 0;
-    cJSON* meminfo_sram = cJSON_CreateArray();
-    luat_meminfo_opt_sys(LUAT_HEAP_SRAM, &total, &used, &max_used);
-    cJSON_AddItemToArray(meminfo_sram, cJSON_CreateNumber(total));
-    cJSON_AddItemToArray(meminfo_sram, cJSON_CreateNumber(used));
-    cJSON_AddItemToArray(meminfo_sram, cJSON_CreateNumber(max_used));
-    cJSON_AddItemToObject(mreport_data, "mem_sram", meminfo_sram);
-    
-    cJSON* meminfo_psram = cJSON_CreateArray();
-    luat_meminfo_opt_sys(LUAT_HEAP_PSRAM, &total, &used, &max_used);
-    cJSON_AddItemToArray(meminfo_psram, cJSON_CreateNumber(total));
-    cJSON_AddItemToArray(meminfo_psram, cJSON_CreateNumber(used));
-    cJSON_AddItemToArray(meminfo_psram, cJSON_CreateNumber(max_used));
-    cJSON_AddItemToObject(mreport_data, "mem_sys", meminfo_psram);
-    cJSON_AddItemToObject(mreport_data, "mem_psram", meminfo_psram);
-
-    cJSON* meminfo_luavm = cJSON_CreateArray();
-    luat_meminfo_luavm(&total, &used, &max_used);
-    cJSON_AddItemToArray(meminfo_luavm, cJSON_CreateNumber(total));
-    cJSON_AddItemToArray(meminfo_luavm, cJSON_CreateNumber(used));
-    cJSON_AddItemToArray(meminfo_luavm, cJSON_CreateNumber(max_used));
-    cJSON_AddItemToObject(mreport_data, "mem_lua", meminfo_luavm);
-    cJSON_AddNumberToObject(mreport_data, "memfree", total - used);
-
-    // 开机次数
-    cJSON_AddNumberToObject(mreport_data, "bootc", 1);
-
-    // 开机时长
-    uint64_t tick64 = luat_mcu_tick64();
-    uint64_t tmms = tick64 / 1000000;
-    uint64_t tms = tick64 % 1000000;
-    cJSON_AddNumberToObject(mreport_data, "tmms", tmms);
-    cJSON_AddNumberToObject(mreport_data, "tms", tms);
+#endif
+    // 内存信息
+    luat_mreport_meminfo(mreport_data);
 
     // 结束 转换成json字符串
     char* json = cJSON_PrintUnformatted(mreport_data);
+    if (json == NULL) {
+        LLOGE("拼接转换为json数据格式, 失败");
+        cJSON_Delete(mreport_data);
+        return;
+    }
     LLOGE("mreport json --- len: %d\r\n%s", strlen(json), json);
 
     struct pbuf* p = pbuf_alloc(PBUF_TRANSPORT, strlen(json), PBUF_RAM);
     if (p == NULL) {
         LLOGE("获取pbuf失败 %d", strlen(json));
+        free(json);
+        cJSON_Delete(mreport_data);
         return;
     }
+
     pbuf_take(p, json, strlen(json));
+    memcpy(&mreport_pcb->local_ip, &netif->ip_addr, sizeof(ip_addr_t));
     ret = udp_sendto_if(mreport_pcb, p, &host, MREPORT_PORT, netif);
     pbuf_free(p);
     free(json);

+ 3 - 3
components/network/netdrv/src/luat_netdrv_napt.c

@@ -25,7 +25,7 @@
 
 #define ICMP_MAP_SIZE (32)
 #define UDP_MAP_TIMEOUT (60 * 1000)
-
+#define NAPT_MAX_PACKET_SIZE (1520)
 /* napt icmp id range: 3000-65535 */
 #define NAPT_ICMP_ID_RANGE_START     0xBB8
 #define NAPT_ICMP_ID_RANGE_END       0xFFFF
@@ -180,7 +180,7 @@ __NETDRV_CODE_IN_RAM__ int luat_netdrv_napt_pkg_input(int id, uint8_t* buff, siz
 static uint8_t* napt_buff;
 err_t netdrv_ip_input_cb(int id, struct pbuf *p, struct netif *inp) {
     size_t len = p->tot_len;
-    if (len > 1500 || len < 24) {
+    if (len > NAPT_MAX_PACKET_SIZE || len < 24) {
         return 1;
     }
     if (napt_buff == NULL) {
@@ -198,7 +198,7 @@ err_t netdrv_ip_input_cb(int id, struct pbuf *p, struct netif *inp) {
 
 // 辅助函数
 int luat_netdrv_napt_pkg_input_pbuf(int id, struct pbuf* p) {
-    if (p == NULL || p->tot_len > 1500) {
+    if (p == NULL || p->tot_len > NAPT_MAX_PACKET_SIZE) {
         return 0;
     }
     // LLOGD("pbuf情况 total %d len %d", p->tot_len, p->len);

+ 5 - 2
components/yhm27xx/binding/luat_lib_yhm27xx.c

@@ -10,6 +10,7 @@
 -- 请查阅demo/yhm27xx
 */
 
+#include "luat_pm.h"
 #include "luat_base.h"
 #include "luat_timer.h"
 #include "luat_mem.h"
@@ -124,10 +125,11 @@ static int l_yhm27xx_reqinfo(lua_State *L)
   return 0;
 }
 
+#ifdef LUAT_USE_YHM27XX
 #include "rotable2.h"
 static const rotable_Reg_t reg_yhm27xx[] = {
-        {"cmd",     ROREG_FUNC(l_yhm27xx_cmd)},
-        {"reqinfo", ROREG_FUNC(l_yhm27xx_reqinfo)},
+        {"cmd",     ROREG_FUNC(l_pm_chgcmd)},
+        {"reqinfo", ROREG_FUNC(l_pm_chginfo)},
         {NULL,          ROREG_INT(0)}
 };
 
@@ -136,3 +138,4 @@ LUAMOD_API int luaopen_yhm27xx(lua_State *L)
   luat_newlib2(L, reg_yhm27xx);
   return 1;
 }
+#endif

+ 20 - 1
luat/include/luat_pm.h

@@ -17,7 +17,6 @@
 #define LUAT_PM_POWER_MODE_BALANCED (2) ///< 性能和功耗平衡,使用LUAT_PM_SLEEP_MODE_LIGHT
 #define LUAT_PM_POWER_MODE_POWER_SAVER (3) ///< 超低功耗,使用LUAT_PM_SLEEP_MODE_STANDBY,进入PSM模式
 
-
 /**
  * @brief 开机原因
  */
@@ -201,5 +200,25 @@ int luat_pm_get_last_req_mode(void);
  * @return uint32_t 0xffffffff失败,其他是剩余时间
  */
 uint32_t luat_pm_dtimer_remain(int id);
+
+#ifdef LUAT_USE_YHM27XX
+/**
+ * @brief 单总线命令读写YHM27XX
+ * @param pin yhm27xx_CMD引脚(可选,若传入nil则根据模组型号自动选择)
+ * @param chip_id 芯片ID
+ * @param reg_addr 读写寄存器地址
+ * @param reg_data 要写入的数据,如果没填,则表示从寄存器读取数据
+ * @return boolean 成功返回true,失败返回false
+ * @return int 读取成功返回寄存器值,写入成功无返回
+ */
+int l_pm_chgcmd(lua_State *L);
+/**
+ * @brief 获取最新的寄存器信息(异步)
+ * @param pin yhm27xx_CMD引脚(可选,若传入nil则根据模组型号自动选择)
+ * @param chip_id 芯片ID
+ * @return nil 无返回值
+ */
+int l_pm_chginfo(lua_State *L);
+#endif
 /** @}*/
 #endif

+ 17 - 9
luat/modules/luat_lib_gpio.c

@@ -396,8 +396,8 @@ int luat_caplevel_irq_cb(int pin, void* args) {
 @function func 完成捕获后的回调函数,仅一个参数,参数为捕获到的时间长度number型数值,单位us
 @return any 返回获取电平的闭包
 @usage
--- 捕获pin.PA07为高电平的持续时间
-gpio.caplevel(pin.PA07,1,function(us_int) print(us_float) end)
+-- 捕获GPIO7为高电平的持续时间
+gpio.caplevel(7,1,function(us_int) print(us_float) end)
 */
 static int l_gpio_caplevel(lua_State *L){
     luat_gpio_t conf = {0};
@@ -439,6 +439,8 @@ static int l_gpio_caplevel(lua_State *L){
 @int value 电平, 可以是 高电平gpio.HIGH, 低电平gpio.LOW, 或者直接写数值1或0
 @return nil 无返回值
 @usage
+-- 注意!!! 仅输出状态下,这个函数才有效
+-- 一定要先gpio.setup, 起码执行过一次gpio.setup, 才能使用本函数. 但不需要每次都gpio.setup
 -- 设置gpio17为低电平
 gpio.set(17, 0)
 */
@@ -468,8 +470,11 @@ static int l_gpio_set(lua_State *L) {
 @int pin GPIO编号,必须是数值
 @return value 电平, 高电平gpio.HIGH, 低电平gpio.LOW, 对应数值1和0
 @usage
+-- 注意!!! 仅输入模式或者中断模式状态下,这个函数才有效
+-- 一定要先gpio.setup, 起码执行过一次gpio.setup, 才能使用本函数. 但不需要每次都gpio.setup
 -- 获取gpio17的当前电平
-gpio.get(17)
+local value = gpio.get(17)
+log.info("gpio", "GPIO17:", value)
 */
 static int l_gpio_get(lua_State *L) {
     int upindex = lua_upvalueindex(1);
@@ -496,7 +501,7 @@ static int l_gpio_get(lua_State *L) {
 }
 
 /*
-关闭管脚功能(高阻输入态),关掉中断
+关闭管脚功能(恢复高阻输入态),关掉中断
 @api gpio.close(pin)
 @int pin GPIO编号,必须是数值
 @return nil 无返回值,总是执行成功
@@ -553,6 +558,7 @@ static int l_gpio_set_default_pull(lua_State *L) {
 @usage
 -- 本API于 2022.05.17 添加
 -- 假设GPIO16上有LED, 每500ms切换一次开关
+-- 注意!!! 仅输出状态下,这个函数才有效
 gpio.setup(16, 0)
 sys.timerLoopStart(function()
     gpio.toggle(16)
@@ -579,7 +585,7 @@ static int l_gpio_toggle(lua_State *L) {
 }
 
 /*
-在同一个GPIO输出一组脉冲, 注意, len的单位是bit, 高位在前,高低电平时间均是由delay决定。本API是阻塞操作,不可以一次性输出太多的脉冲!!!
+在同一个GPIO输出一组脉冲
 @api gpio.pulse(pin,level,len,delay)
 @int gpio号
 @int/string 数值或者字符串.
@@ -587,8 +593,10 @@ static int l_gpio_toggle(lua_State *L) {
 @int delay 高低电平延迟时间, 用的软件while来delay, 这里的delay值是while循环次数, 具体delay时间必须实际调试才知道
 @return nil 无返回值
 @usage
--- 通过PB06脚输出输出8个电平变化,while循环次数是0
-gpio.pulse(pin.PB06,0xA9, 8, 0)
+-- 注意, len的单位是bit, 高位在前,高低电平时间均是由delay决定。
+-- 本API是阻塞操作,不可以一次性输出太多的脉冲!!! 否则会死机!!!
+-- 通过GPIO1脚输出输出8个电平变化,while循环次数是0
+gpio.pulse(1,0xA9, 8, 0)
 */
 static int l_gpio_pulse(lua_State *L) {
     int pin,delay = 0;
@@ -637,7 +645,7 @@ static int l_gpio_pulse(lua_State *L) {
 -- 1 触发中断后,延迟N个毫秒,期间没有新中断且电平没有变化,上报一次
 
 -- 开启防抖, 模式0-冷却, 中断后马上上报, 但100ms内只上报一次
-gpio.debounce(7, 100) -- 若芯片支持pin库, 可用pin.PA7代替数字7
+gpio.debounce(7, 100) -- 对应GPIO7
 -- 开启防抖, 模式1-延时, 中断后等待100ms,期间若保持该电平了,时间到之后上报一次
 -- 对应的,如果输入的是一个 50hz的方波,那么不会触发任何上报
 gpio.debounce(7, 100, 1)
@@ -677,7 +685,7 @@ static int l_gpio_debounce(lua_State *L) {
 }
 
 /*
-获取gpio中断数量,并清空累计值,类似air724的脉冲计数
+获取gpio中断数量,并清空累计值
 @api gpio.count(pin)
 @int gpio号, 0~127, 与硬件相关
 @return int 返回从上次获取中断数量后到当前的中断计数

+ 167 - 1
luat/modules/luat_lib_pm.c

@@ -53,6 +53,7 @@ pm.request(pm.IDLE) -- 通过切换不同的值请求进入不同的休眠模式
 #include "luat_base.h"
 #include "luat_pm.h"
 #include "luat_msgbus.h"
+#include "luat_hmeta.h"
 
 #define LUAT_LOG_TAG "pm"
 #include "luat_log.h"
@@ -64,6 +65,20 @@ pm.request(pm.IDLE) -- 通过切换不同的值请求进入不同的休眠模式
 extern uint32_t g_airlink_pause;
 #endif
 
+#ifdef LUAT_USE_YHM27XX
+#include "luat_gpio.h"
+#include "luat_zbuff.h"
+#include "luat_msgbus.h"
+#include "luat_gpio.h"
+#ifdef LUAT_USE_DRV_GPIO
+#include "luat/drv_gpio.h"
+#endif
+
+static uint8_t yhm27xx_reg_infos[9] = {0};
+#endif
+
+
+
 // static int lua_event_cb = 0;
 /*
 @sys_pub pm
@@ -444,6 +459,153 @@ static int l_pm_wakeup_pin(lua_State *L) {
     return 1;
 }
 
+// yhm27xx
+#ifdef LUAT_USE_YHM27XX
+/* 
+@sys_pub pm 
+YHM27XX芯片寄存器信息更新回调
+YHM27XX_REG
+@usage 
+sys.subscribe("YHM27XX_REG", function(data)
+    -- 注意, 会一次性读出0-9,总共8个寄存器值
+    log.info("yhm27xx", data and data:toHex())
+end)
+*/
+static int l_yhm_27xx_cb(lua_State *L, void *ptr)
+{
+    lua_getglobal(L, "sys_pub");
+    if (lua_isfunction(L, -1))
+    {
+        lua_pushstring(L, "YHM27XX_REG");
+        lua_pushlstring(L, (const char *)yhm27xx_reg_infos, 9);
+        lua_call(L, 2, 0);
+    }
+    return 0;
+}
+
+static void luat_gpio_driver_yhm27xx_reqinfo(uint8_t pin, uint8_t chip_id)
+{
+    for (uint8_t i = 0; i < 9; i++)
+    {
+        luat_gpio_driver_yhm27xx(pin, chip_id, i, 1, &(yhm27xx_reg_infos[i]));
+    }
+    rtos_msg_t msg = {0};
+    msg.handler = l_yhm_27xx_cb;
+    luat_msgbus_put(&msg, 0);
+}
+
+// 根据模组型号匹配YHM27XX引脚
+static uint8_t get_default_yhm27xx_pin(void)
+{
+    char model[32] = {0};
+    luat_hmeta_model_name(model);
+    if (memcmp("Air8000\0", model, 8) == 0 || memcmp("Air8000XB\0", model, 10) == 0 || memcmp("Air8000U\0", model, 9) == 0 || memcmp("Air8000N\0", model, 9) == 0) {
+        return 152;
+    }
+    if (memcmp("Air8000G\0", model, 9) == 0) {
+        return 22;
+    }
+    return 0;
+}
+
+/**
+单总线命令读写YHM27XX
+@api    pm.chgcmd(pin, chip_id, reg, data)
+@int    yhm27xx_CMD引脚(可选,若传入nil则根据模组型号自动选择)
+@int    芯片ID
+@int    读写寄存器地址
+@int    要写入的数据,如果没填,则表示从寄存器读取数据
+@return boolean 成功返回true,失败返回false
+@return int 读取成功返回寄存器值,写入成功无返回
+@usage
+-- 读取寄存器0x01的值
+local ret = pm.chgcmd(pin, chip_id, 0x01)
+-- 写入寄存器0x01的值为0x55
+local ret = pm.chgcmd(pin, chip_id, 0x01, 0x55)
+*/
+int l_pm_chgcmd(lua_State *L)
+{
+    uint8_t pin = 0;
+    // 第一个参数可选,若传入nil则根据模组型号自动选择
+    if (!lua_isnoneornil(L, 1))
+    {
+        pin = luaL_checkinteger(L, 1);
+    }
+    else
+    {
+        // 根据模组型号设置默认值
+        pin = get_default_yhm27xx_pin();
+    }
+
+    uint8_t chip_id = luaL_checkinteger(L, 2);
+    uint8_t reg = luaL_checkinteger(L, 3);
+    uint8_t data = 0;
+    uint8_t is_read = 1;
+    int ret = 0;
+    if (!lua_isnone(L, 4))
+    {
+        is_read = 0;
+        data = luaL_checkinteger(L, 4);
+    }
+    #ifdef LUAT_USE_DRV_GPIO
+    ret = luat_drv_gpio_driver_yhm27xx(pin, chip_id, reg, is_read, &data);
+    #else
+    ret = luat_gpio_driver_yhm27xx(pin, chip_id, reg, is_read, &data);
+    #endif
+    if (ret != 0)
+    {
+        lua_pushboolean(L, 0);
+        return 1;
+    }
+    lua_pushboolean(L, 1);
+    if (is_read)
+    {
+        lua_pushinteger(L, data);
+        return 2;
+    }
+    return 1;
+}
+
+/*
+获取最新的寄存器信息(异步)
+@api    pm.chginfo(pin, chip_id)
+@int    yhm27xx_CMD引脚(可选,若传入nil则根据模组型号自动选择)
+@int    芯片ID
+@return nil 无返回值
+@usage
+sys.subscribe("YHM27XX_REG", function(data)
+    -- 注意, 会一次性读出0-9,总共8个寄存器值
+    log.info("yhm27xx", data and data:toHex())
+end)
+yhm27xx.reqinfo(24, 0x04)
+*/
+int l_pm_chginfo(lua_State *L)
+{
+    uint8_t pin = 0;
+    // 第一个参数可选,若传入nil则根据模组型号自动选择
+    if (!lua_isnoneornil(L, 1))
+    {
+        pin = luaL_checkinteger(L, 1);
+    }
+    else
+    {
+        // 根据模组型号设置默认值
+        pin = get_default_yhm27xx_pin();
+    }
+
+    uint8_t chip_id = luaL_checkinteger(L, 2);
+    #ifdef LUAT_USE_DRV_GPIO
+    if (pin >= 128)
+    {
+        luat_drv_gpio_driver_yhm27xx_reqinfo(pin, chip_id);
+        return 0;
+    }
+    #endif
+    luat_gpio_driver_yhm27xx_reqinfo(pin, chip_id);
+    return 0;
+}
+#endif
+
 #include "rotable2.h"
 static const rotable_Reg_t reg_pm[] =
 {
@@ -463,7 +625,11 @@ static const rotable_Reg_t reg_pm[] =
 	{ "power",          ROREG_FUNC(l_pm_power_ctrl)},
     { "ioVol",          ROREG_FUNC(l_pm_iovolt_ctrl)},
     { "wakeupPin",      ROREG_FUNC(l_pm_wakeup_pin)},
-
+    // yhm27xx
+    #ifdef LUAT_USE_YHM27XX
+    { "chgcmd",         ROREG_FUNC(l_pm_chgcmd)},
+    { "chginfo",        ROREG_FUNC(l_pm_chginfo)},
+    #endif
 
     //@const NONE number 不休眠模式
     { "NONE",           ROREG_INT(LUAT_PM_SLEEP_MODE_NONE)},

+ 2 - 2
module/Air780EHM_Air780EHV_Air780EGH/demo/socket/client/long_connection/netdrv_device.lua

@@ -20,11 +20,11 @@
 -- 根据自己的项目需求,只需要require以下四种中的一种即可;
 
 -- 加载“4G网卡”驱动模块
-require "netdrv_4g"
+-- require "netdrv_4g"
 
 
 -- 加载“通过SPI外挂CH390H芯片的以太网卡”驱动模块
 -- require "netdrv_eth_spi"
 
 -- 加载“可以配置优先级的多种网卡”驱动模块
--- require "netdrv_multiple"
+require "netdrv_multiple"

+ 0 - 142
module/Air780EHM_Air780EHV_Air780EGH/demo/tcp/TCP-UART/main.lua

@@ -1,142 +0,0 @@
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "uart_tcp"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
--- 引入必要的库文件(lua编写), 内部库不需要require
-sys = require("sys")
-
-_G.sysplus = require("sysplus")
-local taskName = "TCP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-local uartid = 1 -- 根据实际设备选取不同的uartid
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接tcp服务器的ip地址
-local port = 43919                 -- 连接tcp服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = false                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = false                       -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)      -- 发送至tcp服务器的数据
-local rx_buff = zbuff.create(1024)      -- 从tcp服务器接收到的数据
-
---初始化
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
--- 处理未识别的消息
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-
-function TCP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                      -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl)       -- 此配置为TCP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        result = libnet.connect(taskName, 15000, socket_client, ip, port)
-
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-              local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-               if len <= 0 then    -- 接收到的字节长度为0 则退出
-                   break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                   sys_send(taskName, socket.EVENT, 0)
-                end
-                break
-            end
-        end)
-
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            connect_state = true
-            libnet.tx(taskName, 0, socket_client, "TCP  CONNECT")
-        end
-
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-
-                uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给tcp待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(d1Name, 5000, socket_client)
-        socket.release(socket_client)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-
-end
-
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(TCP_TASK, taskName, tcp_client_main_cbfunc)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 145
module/Air780EHM_Air780EHV_Air780EGH/demo/tcp/TCP单向认证/main.lua

@@ -1,145 +0,0 @@
--- main.lua文件
-
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "uart_tcp"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
--- 引入必要的库文件(lua编写), 内部库不需要require
-sys = require("sys")
-
-_G.sysplus = require("sysplus")
-local taskName = "TCP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-
-local uartid = 1 -- 根据实际设备选取不同的uartid
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接tcp服务器的ip地址
-local port = 46428            -- 连接tcp服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = false                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = true                     -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)      -- 发送至tcp服务器的数据
-local rx_buff = zbuff.create(1024)      -- 从tcp服务器接收到的数据
-
---初始化
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
--- 处理未识别的消息
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-
-function TCP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                      -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl)       -- 此配置为TCP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        result = libnet.connect(taskName, 15000, socket_client, ip, port)
-
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-                local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-                if len <= 0 then    -- 接收到的字节长度为0 则退出
-                    break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                    sys_send(taskName, socket.EVENT, 0)
-                end
-            end
-        end)
-
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            connect_state = true
-            libnet.tx(taskName, 0, socket_client, "TCP  CONNECT")
-        end
-
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-
-                uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给tcp待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(d1Name, 5000, socket_client)
-        socket.release(socket_client)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-
-end
-
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(TCP_TASK, taskName, tcp_client_main_cbfunc)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 141
module/Air780EHM_Air780EHV_Air780EGH/demo/tcp/TCP断链续连/main.lua

@@ -1,141 +0,0 @@
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "uart_tcp"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
--- 引入必要的库文件(lua编写), 内部库不需要require
-sys = require("sys")
-
-_G.sysplus = require("sysplus")
-local taskName = "TCP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-local uartid = 1 -- 根据实际设备选取不同的uartid
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接tcp服务器的ip地址
-local port = 46244                 -- 连接tcp服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = false                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = false                       -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)      -- 发送至tcp服务器的数据
-local rx_buff = zbuff.create(1024)      -- 从tcp服务器接收到的数据
-
---初始化
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
--- 处理未识别的消息
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-
-function TCP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                      -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl)       -- 此配置为TCP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        result = libnet.connect(taskName, 15000, socket_client, ip, port)
-
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-                local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-                if len <= 0 then    -- 接收到的字节长度为0 则退出
-                    break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                    sys_send(taskName, socket.EVENT, 0)
-                end
-            end
-        end)
-
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            connect_state = true
-            libnet.tx(taskName, 0, socket_client, "TCP  CONNECT")
-        end
-
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-
-                uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给tcp待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(d1Name, 5000, socket_client)
-        socket.release(socket_client)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-
-end
-
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(TCP_TASK, taskName, tcp_client_main_cbfunc)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 130
module/Air780EHM_Air780EHV_Air780EGH/demo/udp/main.lua

@@ -1,130 +0,0 @@
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "scdemo"
-VERSION = "1.0.0"
-log.info("main", PROJECT, VERSION)
--- 一定要添加sys.lua !!!!
-sys = require("sys")
-_G.sysplus = require("sysplus")
-local taskName = "UDP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-----------------------------网络配置---------------------------
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接UDP服务器的ip地址
-local port = 46139                      -- 连接UDP服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = true                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = false                       -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)     -- 发送至UDP服务器的数据
-local rx_buff = zbuff.create(1024)     -- 从UDP服务器接收到的数据
---==============================================================
---Uart初始化  
-local uartid = 1 -- 根据实际设备选取不同的uartid
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-function UDP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    -- 串口和UDP服务器的交互逻辑
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl) -- 此配置为UDP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        local result = libnet.connect(taskName, 15000, socket_client, ip, port)
-        -----查询网络状态
-        local status = mobile.status()    
-        log.info("status", status) 
-        
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        log.info("connect ip: 等待连接 ",result)
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-                local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-                if len <= 0 then    -- 接收到的字节长度为0 则退出
-                    break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                    sys_send(taskName, socket.EVENT, 0)
-                end
-            end
-        end)
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            log.info("connect ip: 连接成功")
-            connect_state = true
-           libnet.tx(taskName, 0, socket_client, "UDP CONNECT")
-        end
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-               uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给UDP待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(taskName, 5000, socket_client)
-        socket.release(netc)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-end
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(UDP_TASK, taskName, tcp_client_main_cbfunc)
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 4 - 3
module/Air780EPM/demo/lowpower/lowpower_dissipation.lua

@@ -1,14 +1,14 @@
 
 -- netlab.luatos.com上打开TCP 有测试服务器
 local server_ip = "112.125.89.8"
-local server_port = 47523
+local server_port = 43667
 local is_udp = false --用户根据自己实际情况选择
 
 --是UDP服务器就赋值为true,是TCP服务器就赋值为flase
 --UDP服务器比TCP服务器功耗低
 --如果用户对数据的丢包率有极为苛刻的要求,最好选择TCP
 
-local Heartbeat_interval = 5 -- 发送数据的间隔时间,单位分钟
+local Heartbeat_interval = 1 -- 发送数据的间隔时间,单位分钟
 
 -- 数据内容  
 local heart_data = string.rep("1234567890", 10)
@@ -79,8 +79,9 @@ function socketDemo()
      --进入低功耗长连接模式
     pm.power(pm.WORK_MODE, 1)
 
+    -- pm.dtimerStart(0, 120 * 1000)
     sys.taskInit(socketTask)
-
+    pm.dtimerStart(0, 120 * 1000)
 end
 
 sys.taskInit(socketDemo)

+ 2 - 2
module/Air780EPM/demo/lowpower/main.lua

@@ -8,8 +8,8 @@ _G.sysplus = require("sysplus")
 log.style(1)
 
 -- require "normal" --正常模式
--- require "lowpower_dissipation" --低功耗模式
-require "ultra_low_power" --超低功耗模式(PSM+模式)
+require "lowpower_dissipation" --低功耗模式
+-- require "ultra_low_power" --超低功耗模式(PSM+模式)
 
 -- 用户代码已结束---------------------------------------------
 -- 结尾总是这一句

+ 15 - 11
module/Air780EPM/demo/pwm/示例1 PWM输出/main.lua

@@ -15,19 +15,23 @@ if wdt then
 end
 
 sys.taskInit(function()
-    while true do
-        -- 开启pwm通道4,设置脉冲频率为1kHz,分频精度为1000,占空比为10/1000=1% 持续输出
-        pwm.open(4, 1000, 10, 0, 1000) -- 小灯微微发光
-        sys.wait(1000)
-        -- 开启pwm通道4,设置脉冲频率为1kHz,分频精度为1000,占空比为500/1000=50% 持续输出
-        pwm.open(4, 1000, 500, 0, 1000) -- 小灯中等亮度
-        sys.wait(1000)
-        -- 开启pwm通道4,设置脉冲频率为1kHz,分频精度为1000,占空比为1000/1000=100% 持续输出
-        pwm.open(4, 1000, 1000, 0, 1000) -- 小灯很高亮度
-        sys.wait(1000)
-    end
+    gpio.setup(27,1)
 end)
 
+-- sys.taskInit(function()
+--     while true do
+--         -- 开启pwm通道4,设置脉冲频率为1kHz,分频精度为1000,占空比为10/1000=1% 持续输出
+--         pwm.open(4, 1000, 10, 0, 1000) -- 小灯微微发光
+--         sys.wait(1000)
+--         -- 开启pwm通道4,设置脉冲频率为1kHz,分频精度为1000,占空比为500/1000=50% 持续输出
+--         pwm.open(4, 1000, 500, 0, 1000) -- 小灯中等亮度
+--         sys.wait(1000)
+--         -- 开启pwm通道4,设置脉冲频率为1kHz,分频精度为1000,占空比为1000/1000=100% 持续输出
+--         pwm.open(4, 1000, 1000, 0, 1000) -- 小灯很高亮度
+--         sys.wait(1000)
+--     end
+-- end)
+
 -- 用户代码已结束---------------------------------------------
 -- 结尾总是这一句
 sys.run()

+ 2 - 2
module/Air780EPM/demo/socket/client/long_connection/netdrv_device.lua

@@ -20,11 +20,11 @@
 -- 根据自己的项目需求,只需要require以下四种中的一种即可;
 
 -- 加载“4G网卡”驱动模块
-require "netdrv_4g"
+-- require "netdrv_4g"
 
 
 -- 加载“通过SPI外挂CH390H芯片的以太网卡”驱动模块
 -- require "netdrv_eth_spi"
 
 -- 加载“可以配置优先级的多种网卡”驱动模块
--- require "netdrv_multiple"
+require "netdrv_multiple"

+ 0 - 142
module/Air780EPM/demo/tcp/TCP-UART/main.lua

@@ -1,142 +0,0 @@
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "uart_tcp"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
--- 引入必要的库文件(lua编写), 内部库不需要require
-sys = require("sys")
-
-_G.sysplus = require("sysplus")
-local taskName = "TCP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-local uartid = 1 -- 根据实际设备选取不同的uartid
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接tcp服务器的ip地址
-local port = 44451                 -- 连接tcp服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = false                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = false                       -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)      -- 发送至tcp服务器的数据
-local rx_buff = zbuff.create(1024)      -- 从tcp服务器接收到的数据
-
---初始化
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
--- 处理未识别的消息
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-
-function TCP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                      -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl)       -- 此配置为TCP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        result = libnet.connect(taskName, 15000, socket_client, ip, port)
-
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-              local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-               if len <= 0 then    -- 接收到的字节长度为0 则退出
-                   break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                   sys_send(taskName, socket.EVENT, 0)
-                end
-                break
-            end
-        end)
-
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            connect_state = true
-            libnet.tx(taskName, 0, socket_client, "TCP  CONNECT")
-        end
-
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-
-                uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给tcp待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(d1Name, 5000, socket_client)
-        socket.release(socket_client)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-
-end
-
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(TCP_TASK, taskName, tcp_client_main_cbfunc)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 145
module/Air780EPM/demo/tcp/TCP单向认证/main.lua

@@ -1,145 +0,0 @@
--- main.lua文件
-
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "uart_tcp"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
--- 引入必要的库文件(lua编写), 内部库不需要require
-sys = require("sys")
-
-_G.sysplus = require("sysplus")
-local taskName = "TCP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-
-local uartid = 1 -- 根据实际设备选取不同的uartid
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接tcp服务器的ip地址
-local port = 46428            -- 连接tcp服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = false                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = true                     -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)      -- 发送至tcp服务器的数据
-local rx_buff = zbuff.create(1024)      -- 从tcp服务器接收到的数据
-
---初始化
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
--- 处理未识别的消息
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-
-function TCP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                      -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl)       -- 此配置为TCP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        result = libnet.connect(taskName, 15000, socket_client, ip, port)
-
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-                local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-                if len <= 0 then    -- 接收到的字节长度为0 则退出
-                    break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                    sys_send(taskName, socket.EVENT, 0)
-                end
-            end
-        end)
-
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            connect_state = true
-            libnet.tx(taskName, 0, socket_client, "TCP  CONNECT")
-        end
-
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-
-                uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给tcp待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(d1Name, 5000, socket_client)
-        socket.release(socket_client)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-
-end
-
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(TCP_TASK, taskName, tcp_client_main_cbfunc)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 141
module/Air780EPM/demo/tcp/TCP断链续连/main.lua

@@ -1,141 +0,0 @@
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "uart_tcp"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
--- 引入必要的库文件(lua编写), 内部库不需要require
-sys = require("sys")
-
-_G.sysplus = require("sysplus")
-local taskName = "TCP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-local uartid = 1 -- 根据实际设备选取不同的uartid
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接tcp服务器的ip地址
-local port = 46244                 -- 连接tcp服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = false                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = false                       -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)      -- 发送至tcp服务器的数据
-local rx_buff = zbuff.create(1024)      -- 从tcp服务器接收到的数据
-
---初始化
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
--- 处理未识别的消息
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-
-function TCP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                      -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl)       -- 此配置为TCP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        result = libnet.connect(taskName, 15000, socket_client, ip, port)
-
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-                local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-                if len <= 0 then    -- 接收到的字节长度为0 则退出
-                    break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                    sys_send(taskName, socket.EVENT, 0)
-                end
-            end
-        end)
-
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            connect_state = true
-            libnet.tx(taskName, 0, socket_client, "TCP  CONNECT")
-        end
-
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-
-                uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给tcp待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(d1Name, 5000, socket_client)
-        socket.release(socket_client)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-
-end
-
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(TCP_TASK, taskName, tcp_client_main_cbfunc)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 130
module/Air780EPM/demo/udp/main.lua

@@ -1,130 +0,0 @@
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "scdemo"
-VERSION = "1.0.0"
-log.info("main", PROJECT, VERSION)
--- 一定要添加sys.lua !!!!
-sys = require("sys")
-_G.sysplus = require("sysplus")
-local taskName = "UDP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-----------------------------网络配置---------------------------
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接UDP服务器的ip地址
-local port = 42335                      -- 连接UDP服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = true                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = false                       -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)     -- 发送至UDP服务器的数据
-local rx_buff = zbuff.create(1024)     -- 从UDP服务器接收到的数据
---==============================================================
---Uart初始化  
-local uartid = 1 -- 根据实际设备选取不同的uartid
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-function UDP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    -- 串口和UDP服务器的交互逻辑
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl) -- 此配置为UDP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        local result = libnet.connect(taskName, 15000, socket_client, ip, port)
-        -----查询网络状态
-        local status = mobile.status()    
-        log.info("status", status) 
-        
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        log.info("connect ip: 等待连接 ",result)
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-                local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-                if len <= 0 then    -- 接收到的字节长度为0 则退出
-                    break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                    sys_send(taskName, socket.EVENT, 0)
-                end
-            end
-        end)
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            log.info("connect ip: 连接成功")
-            connect_state = true
-           libnet.tx(taskName, 0, socket_client, "UDP CONNECT")
-        end
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-               uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给UDP待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(taskName, 5000, socket_client)
-        socket.release(netc)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-end
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(UDP_TASK, taskName, tcp_client_main_cbfunc)
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 46 - 0
module/Air8000/demo/luatos_framework/luatos_task/create.lua

@@ -0,0 +1,46 @@
+--[[
+@module  create
+@summary task调度演示 
+@version 1.0
+@date    2025.08.12
+@author  朱天华
+@usage
+本文件为task_scheduling应用功能模块,用来演示task调度,核心业务逻辑为:
+1、创建两个task,task1和task2;
+2、在task1的任务处理函数中,每隔500毫秒,task1的计数器加1,并且通过日志打印task1计数器的值;
+3、在task2的任务处理函数中,每隔300毫秒,task2的计数器加1,并且通过日志打印task2计数器的值;
+
+本文件没有对外接口,直接在main.lua中require "create"就可以加载运行;
+]]
+
+local count = 0
+
+-- led task的任务处理函数
+local function led_task_func()
+    while true do
+        log.info("led_task_func")
+
+        -- 等待500ms
+        -- sys.wait(500)
+
+        sys.waitUntil("INVALID_MESSAGE")
+
+        -- log.info("during led task, mem.lua", rtos.meminfo())
+        -- log.info("before led task, mem.sys", rtos.meminfo("sys"))
+    end
+end
+
+log.info("before led task, mem.lua", rtos.meminfo())
+log.info("before led task, mem.sys", rtos.meminfo("sys"))
+
+-- 创建并启动第一个led task
+-- 运行这个task的任务处理函数led_task_func
+while true do
+    sys.taskInit(led_task_func)
+    count = count+1
+    log.info("create task count", count)
+end
+
+log.info("after led task, mem.lua", rtos.meminfo())
+log.info("before led task, mem.sys", rtos.meminfo("sys"))
+

+ 18 - 0
module/Air8000/demo/luatos_framework/luatos_task/global_msg_receiver1.lua

@@ -0,0 +1,18 @@
+
+
+
+local function init_subscribe_cbfunc(tag, count)
+    log.info("init_subscribe_cbfunc", tag, count)
+end
+
+local function delay_subscribe_cbfunc(tag, count)
+    log.info("delay_subscribe_cbfunc", tag, count)
+end
+
+
+sys.subscribe("SEND_DATA_REQ", init_subscribe_cbfunc)
+sys.timerStart(sys.subscribe, 5000, "SEND_DATA_REQ", delay_subscribe_cbfunc)
+
+
+sys.timerStart(sys.unsubscribe, 10000, "SEND_DATA_REQ", init_subscribe_cbfunc)
+sys.timerStart(sys.unsubscribe, 10000, "SEND_DATA_REQ", delay_subscribe_cbfunc)

+ 30 - 0
module/Air8000/demo/luatos_framework/luatos_task/global_msg_receiver2.lua

@@ -0,0 +1,30 @@
+
+
+
+local function success_wait_until_base_task_func()
+    local result, tag, count
+    while true do
+        result, tag, count = sys.waitUntil("SEND_DATA_REQ")
+        if result then
+            log.info("success_wait_until_base_task_func", tag, count)
+        end
+    end
+end
+
+
+local function lost_wait_until_base_task_func()
+    local result, tag, count
+    while true do
+        sys.wait(3000)
+        
+        result, tag, count = sys.waitUntil("SEND_DATA_REQ")
+        if result then
+            log.info("lost_wait_until_base_task_func", tag, count)
+        end
+    end
+end
+
+
+sys.taskInit(success_wait_until_base_task_func)
+sys.taskInit(lost_wait_until_base_task_func)
+

+ 43 - 0
module/Air8000/demo/luatos_framework/luatos_task/global_msg_sender.lua

@@ -0,0 +1,43 @@
+
+
+
+local function global_sender_msg_task_func()
+    local count = 0
+
+    while true do
+        count = count+1
+
+        -- 发布一条全局消息
+        -- 消息名称为"SEND_DATA_REQ"
+        -- 消息携带两个参数:
+        -- 第一个参数是"from task"
+        -- 第二个参数是number类型的count
+        sys.publish("SEND_DATA_REQ", "from task", count)
+
+        -- 延时等待1秒
+        sys.wait(1000)
+    end
+end
+
+
+local timer_count = 0
+
+local function global_sender_msg_timer_cbfunc()
+    timer_count = timer_count+1
+
+    -- 发布一条全局消息
+    -- 消息名称为"SEND_DATA_REQ"
+    -- 消息携带两个参数:
+    -- 第一个参数是"from timer"
+    -- 第二个参数是number类型的timer_count
+    sys.publish("SEND_DATA_REQ", "from timer", timer_count)
+end
+
+
+-- 创建并且启动一个基础task
+-- 运行这个task的任务处理函数global_sender_msg_task_func
+sys.taskInit(global_sender_msg_task_func)
+
+global_sender_msg_timer_cbfunc()
+sys.timerLoopStart(global_sender_msg_timer_cbfunc, 1000)
+

+ 40 - 32
module/Air8000/demo/mqttv2/main.lua → module/Air8000/demo/luatos_framework/luatos_task/main.lua

@@ -2,26 +2,11 @@
 @module  main
 @summary LuatOS用户应用脚本文件入口,总体调度应用逻辑 
 @version 1.0
-@date    2025.07.28
+@date    2025.07.19
 @author  朱天华
 @usage
 本demo演示的核心功能为:
-1、创建三路mqtt连接,详情如下
-- 创建一个mqtt client,连接mqtt server;
-- 创建一个mqtt ssl client,连接mqtt ssl server,不做证书校验;
-- 创建一个mqtt ssl client,连接mqtt ssl server,client仅单向校验server的证书,server不校验client的证书和密钥文件;
-2、每一路mqtt连接出现异常后,自动重连;
-3、每一路mqtt连接,client按照以下几种逻辑发送数据给server
-- 串口应用功能模块uart_app.lua,通过uart1接收到串口数据,将串口数据增加send from uart: 前缀后,使用mobile.imei().."/uart/up"主题,发送给server;
-- 定时器应用功能模块timer_app.lua,定时产生数据,将数据增加send from timer:前缀后,使用mobile.imei().."/timer/up"主题,发送给server;
-4、每一路mqtt连接,client收到server数据后,将数据增加recv from mqtt/mqtt ssl/mqtt ssl ca(三选一)server: 前缀后,通过uart1发送出去;
-5、启动一个网络业务逻辑看门狗task,用来监控网络环境,如果连续长时间工作不正常,重启整个软件系统;
-6、netdrv_device:配置连接外网使用的网卡,目前支持以下四种选择(四选一)
-   (1) netdrv_4g:4G网卡
-   (2) netdrv_wifi:WIFI STA网卡
-   (3) netdrv_eth_spi:通过SPI外挂CH390H芯片的以太网卡
-   (4) netdrv_multiple:支持以上三种网卡,可以配置三种网卡的优先级
-
+每隔一秒钟通过日志输出一次Hello, LuatOS
 更多说明参考本目录下的readme.md文件
 ]]
 
@@ -36,7 +21,7 @@ VERSION:项目版本号,ascii string类型
             因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
         如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
 ]]
-PROJECT = "MQTT"
+PROJECT = "luatos_framework_luatos_task"
 VERSION = "001.000.000"
 
 
@@ -77,25 +62,48 @@ end
 --     log.info("mem.sys", rtos.meminfo("sys"))
 -- end, 3000)
 
--- 加载网络环境检测看门狗功能模块
-require "network_watchdog"
+-- 加载“task调度”演示功能模块
+-- require "scheduling"
+
+-- 加载“task访问共享资源”演示功能模块
+-- require "shared_resource"
+
+-- 加载“task创建”演示功能模块
+-- require "create"
+
+-- 加载“用户可用ram信息”演示功能模块
+-- require "memory_valid"
+
+-- 加载“单个task占用的ram资源”演示功能模块
+-- require "memory_task"
+
+-- 加载“创建task的数量”演示功能模块
+-- require "task_count"
+
+-- 加载“task_func参数”演示功能模块
+-- require "task_func"
+
+-- 加载“task创建时的可变参数”演示功能模块
+-- require "variable_args"
+
+-- 加载“非目标消息回调函数”演示功能模块
+-- require "non_targeted_msg"
 
--- 加载网络驱动设备功能模块
-require "netdrv_device"
+-- 加载“用户全局消息处理”演示功能模块
+-- require "global_msg_receiver1"
+-- require "global_msg_receiver2"
+-- require "global_msg_sender"
 
--- 加载串口应用功能模块
-require "uart_app"
--- 加载定时器应用功能模块
-require "timer_app"
+-- 加载“用户定向消息处理”演示功能模块
+-- require "tgted_msg_receiver"
+-- require "targeted_msg_sender"
 
--- 加载mqtt client 主应用功能模块
-require "mqtt_main"
+-- 加载“定时器”演示功能模块
+-- require "timer"
 
--- 加载mqtt ssl client 主应用功能模块(目前还没有合适的服务器,等服务器搭建好之后再调试)
--- require "mqtts_main"
+-- 加载“task内外部运行环境典型错误”演示功能模块
+require "task_inout_env_err"
 
--- 加载mqtt ssl ca client 主应用功能模块(目前还没有合适的服务器,等服务器搭建好之后再调试)
--- require "mqtts_ca_main"
 
 -- 用户代码已结束---------------------------------------------
 -- 结尾总是这一句

+ 52 - 0
module/Air8000/demo/luatos_framework/luatos_task/memory_task.lua

@@ -0,0 +1,52 @@
+--[[
+@module  create
+@summary task调度演示 
+@version 1.0
+@date    2025.08.12
+@author  朱天华
+@usage
+本文件为task_scheduling应用功能模块,用来演示task调度,核心业务逻辑为:
+1、创建两个task,task1和task2;
+2、在task1的任务处理函数中,每隔500毫秒,task1的计数器加1,并且通过日志打印task1计数器的值;
+3、在task2的任务处理函数中,每隔300毫秒,task2的计数器加1,并且通过日志打印task2计数器的值;
+
+本文件没有对外接口,直接在main.lua中require "create"就可以加载运行;
+]]
+
+local function print_mem_info()
+    -- 这个接口可以强制执行一次垃圾内存回收,方便我们分析内存信息
+    -- 在实际项目开发中中,用户不需要主动使用这个接口,LuatOS内部的Lua虚拟机会自动进行垃圾回收
+    collectgarbage()
+
+    -- rtos.meminfo()有三个返回值:
+    -- 1、总ram大小(单位字节)
+    -- 2、运行过程中实时使用的ram大小(单位字节)
+    -- 3、运行过程中历史使用的最高ram大小(单位字节)
+
+    -- rtos.meminfo()是Lua虚拟机中的用户可用ram信息,用户开发的大部分LuatOS脚本程序都是自动从这里分配ram
+    log.info("mem.lua", rtos.meminfo())
+    -- rtos.meminfo("sys")是内核系统中的用户可用ram信息,用户使用zbuff核心库时,会用到这部分ram
+    -- 在这里我们就不展开讲这一部分了,等讲到zbuff的时候再做讨论
+    log.info("mem.sys", rtos.meminfo("sys"))
+end
+
+-- led task的任务处理函数
+local function led_task_func()
+    while true do
+        log.info("led_task_func")
+
+        -- 永远等待一个不存在的消息
+        sys.waitUntil("INVALID_MESSAGE")
+    end
+end
+
+log.info("before led task")
+print_mem_info()
+
+-- 创建并启动一个led task
+-- 运行这个task的任务处理函数led_task_func
+sys.taskInit(led_task_func)
+
+log.info("after led task")
+print_mem_info()
+

+ 42 - 0
module/Air8000/demo/luatos_framework/luatos_task/memory_valid.lua

@@ -0,0 +1,42 @@
+--[[
+@module  create
+@summary task调度演示 
+@version 1.0
+@date    2025.08.12
+@author  朱天华
+@usage
+本文件为task_scheduling应用功能模块,用来演示task调度,核心业务逻辑为:
+1、创建两个task,task1和task2;
+2、在task1的任务处理函数中,每隔500毫秒,task1的计数器加1,并且通过日志打印task1计数器的值;
+3、在task2的任务处理函数中,每隔300毫秒,task2的计数器加1,并且通过日志打印task2计数器的值;
+
+本文件没有对外接口,直接在main.lua中require "create"就可以加载运行;
+]]
+
+
+local function print_mem_info()
+    -- 这个接口可以强制执行一次垃圾内存回收,方便我们分析内存信息
+    -- 在实际项目开发中中,用户不需要主动使用这个接口,LuatOS内部的Lua虚拟机会自动进行垃圾回收
+    collectgarbage()
+
+    -- rtos.meminfo()有三个返回值:
+    -- 1、总ram大小(单位字节)
+    -- 2、运行过程中实时使用的ram大小(单位字节)
+    -- 3、运行过程中历史使用的最高ram大小(单位字节)
+
+    -- rtos.meminfo()是Lua虚拟机中的用户可用ram信息,用户开发的大部分LuatOS脚本程序都是自动从这里分配ram
+    log.info("mem.lua", rtos.meminfo())
+    -- rtos.meminfo("sys")是内核系统中的用户可用ram信息,用户使用zbuff核心库时,会用到这部分ram
+    -- 在这里我们就不展开讲这一部分了,等讲到zbuff的时候再做讨论
+    log.info("mem.sys", rtos.meminfo("sys"))
+end
+
+local function mem_task_func()
+    while true do
+        print_mem_info()
+        sys.wait(1000)
+    end
+end
+
+sys.taskInit(mem_task_func)
+

+ 149 - 0
module/Air8000/demo/luatos_framework/luatos_task/non_targeted_msg.lua

@@ -0,0 +1,149 @@
+--[[
+@module  create
+@summary task调度演示 
+@version 1.0
+@date    2025.08.12
+@author  朱天华
+@usage
+本文件为task_scheduling应用功能模块,用来演示task调度,核心业务逻辑为:
+1、创建两个task,task1和task2;
+2、在task1的任务处理函数中,每隔500毫秒,task1的计数器加1,并且通过日志打印task1计数器的值;
+3、在task2的任务处理函数中,每隔300毫秒,task2的计数器加1,并且通过日志打印task2计数器的值;
+
+本文件没有对外接口,直接在main.lua中require "create"就可以加载运行;
+]]
+
+
+-- tcp_client_main的任务名
+local TASK_NAME = "TCP_CLINET_MAIN"
+
+
+-- 非目标消息回调函数
+local function mqtt_client_main_cbfunc(msg)
+	log.info("mqtt_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
+end
+
+-- mqtt main task 的任务处理函数
+local function mqtt_client_main_task_func()
+    -- 连接、断开连接、订阅、取消订阅、异常等各种事件的处理调度逻辑
+    while true do
+        -- 等待"MQTT_EVENT"消息
+        msg = sysplus.waitMsg(TASK_NAME, "MQTT_EVENT")
+        log.info("mqtt_client_main_task_func waitMsg", msg[2], msg[3], msg[4])
+
+        -- connect连接结果
+        -- msg[3]表示连接结果,true为连接成功,false为连接失败
+        if msg[2] == "CONNECT" then
+            -- mqtt连接成功
+            if msg[3] then
+                log.info("mqtt_client_main_task_func", "connect success")
+            -- mqtt连接失败
+            else
+                log.info("mqtt_client_main_task_func", "connect error")
+            end
+
+        -- subscribe订阅结果
+        -- msg[3]表示订阅结果,true为订阅成功,false为订阅失败
+        elseif msg[2] == "SUBSCRIBE" then
+            -- 订阅成功
+            if msg[3] then
+                log.info("mqtt_client_main_task_func", "subscribe success", "qos: "..(msg[4] or "nil"))
+            -- 订阅失败
+            else
+                log.error("mqtt_client_main_task_func", "subscribe error", "code", msg[4])
+            end
+
+        -- 被动关闭了mqtt连接
+        -- 被网络或者服务器断开了连接
+        elseif msg[2] == "DISCONNECTED" then
+            log.info("mqtt_client_main_task_func", "disconnected")
+        end
+    end
+end
+
+local function send_non_targeted_msg_task_func()
+    local count = 0
+
+    while true do
+        count = count+1
+
+        -- 向TASK_NAME这个任务发送一条消息
+        -- 消息名称为"UNKNOWN_EVENT"
+        -- 消息携带一个number类型的参数count
+        sys.sendMsg(TASK_NAME, "UNKNOWN_EVENT", count)
+
+        -- 延时等待1秒
+        sys.wait(1000)
+    end
+end
+
+local function send_non_targeted_msg_task_func()
+    local count = 0
+
+    while true do
+        count = count+1
+
+        -- 向TASK_NAME这个任务发送一条消息
+        -- 消息名称为"UNKNOWN_EVENT"
+        -- 消息携带一个number类型的参数count
+        sysplus.sendMsg(TASK_NAME, "UNKNOWN_EVENT", count)
+
+        -- 延时等待1秒
+        sys.wait(1000)
+    end
+end
+
+
+local function send_targeted_msg_task_func()
+    while true do
+        -- 向TASK_NAME这个任务发送一条消息
+        -- 消息名称为"MQTT_EVENT"
+        -- 消息携带两个参数
+        -- 第一个参数为"CONNECT"
+        -- 第二个参数为true
+        -- 这条消息的意思是MQTT连接成功
+        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "CONNECT", true)
+
+        -- 延时等待1秒
+        sys.wait(1000)
+
+        -- 向TASK_NAME这个任务发送一条消息
+        -- 消息名称为"MQTT_EVENT"
+        -- 消息携带三个参数
+        -- 第一个参数为"SUBSCRIBE"
+        -- 第二个参数为true
+        -- 第三个参数为0
+        -- 这条消息的意思是MQTT订阅成功,qos为0
+        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "SUBSCRIBE", true, 0)
+
+        -- 延时等待1秒
+        sys.wait(1000)
+
+        -- 向TASK_NAME这个任务发送一条消息
+        -- 消息名称为"MQTT_EVENT"
+        -- 消息携带一个参数"DISCONNECTED"
+        -- 这条消息的意思是MQTT连接被动断开
+        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "DISCONNECTED")
+
+        -- 延时等待1秒
+        sys.wait(1000)
+    end
+end
+
+-- 创建并且启动一个高级task
+-- task的任务处理函数为mqtt_client_main_task_func
+-- task的名称为TASK_NAME变量的值"MQTT_CLINET_MAIN"
+-- task的非目标消息回调函数为mqtt_client_main_cbfunc
+-- 运行这个task的任务处理函数mqtt_client_main_task_func
+sysplus.taskInitEx(mqtt_client_main_task_func, TASK_NAME, mqtt_client_main_cbfunc)
+
+
+-- 创建并且启动一个基础task
+-- 运行这个task的任务处理函数send_targeted_msg_task_func
+sys.taskInit(send_non_targeted_msg_task_func)
+
+-- 创建并且启动一个高级task
+-- task的任务处理函数为send_targeted_msg_task_func
+-- task的名称为SEND_TASK_NAME
+-- 运行这个task的任务处理函数send_targeted_msg_task_func
+sysplus.taskInitEx(send_targeted_msg_task_func, "SEND_MSG_TASK")

+ 47 - 0
module/Air8000/demo/luatos_framework/luatos_task/readme.md

@@ -0,0 +1,47 @@
+
+## 演示功能概述
+
+1、创建一个task;
+
+2、在task中的任务处理函数中,每隔一秒钟通过日志输出一次Hello, LuatOS;
+
+
+## 演示硬件环境
+
+1、Air8000核心板一块
+
+2、TYPE-C USB数据线一根
+
+4、Air8101核心板和数据线的硬件接线方式为
+
+- Air8101核心板通过TYPE-C USB口连接TYPE-C USB 数据线,数据线的另外一端连接电脑的USB口;
+- 核心板正面的 供电/充电 拨动开关 拨到供电一端;
+- 核心板背面的 USB ON/USB OFF 拨动开关 拨到USB ON一端;
+
+
+## 演示软件环境
+
+1、[Luatools下载调试工具](https://docs.openluat.com/air8000/luatos/common/download/)
+
+2、[Air8000 最新版本的内核固件](https://docs.openluat.com/air8000/luatos/firmware/)
+
+
+## 演示核心步骤
+
+1、搭建好硬件环境
+
+2、Luatools烧录内核固件和demo脚本代码
+
+3、烧录成功后,自动开机运行
+
+4、出现类似于下面的日志,每隔1秒输出1次Hello, LuatOS,就表示运行成功:
+
+``` lua
+[2025-07-19 23:19:04.944][000000015.256] I/user.Hello, LuatOS
+[2025-07-19 23:19:05.954][000000016.256] I/user.Hello, LuatOS
+[2025-07-19 23:19:06.956][000000017.256] I/user.Hello, LuatOS
+[2025-07-19 23:19:07.947][000000018.256] I/user.Hello, LuatOS
+[2025-07-19 23:19:08.955][000000019.256] I/user.Hello, LuatOS
+[2025-07-19 23:19:09.944][000000020.256] I/user.Hello, LuatOS
+
+```

+ 49 - 0
module/Air8000/demo/luatos_framework/luatos_task/scheduling.lua

@@ -0,0 +1,49 @@
+--[[
+@module  scheduling
+@summary task调度演示 
+@version 1.0
+@date    2025.08.12
+@author  朱天华
+@usage
+本文件为task_scheduling应用功能模块,用来演示task调度,核心业务逻辑为:
+1、创建两个task,task1和task2;
+2、在task1的任务处理函数中,每隔500毫秒,task1的计数器加1,并且通过日志打印task1计数器的值;
+3、在task2的任务处理函数中,每隔300毫秒,task2的计数器加1,并且通过日志打印task2计数器的值;
+
+本文件没有对外接口,直接在main.lua中require "task_scheduling"就可以加载运行;
+]]
+
+
+-- 第一个task的任务处理函数
+local function task1_func()
+    local count = 0
+    while true do
+        count = count + 1
+        log.info("task1_func", "运行中,计数:", count)
+        -- 等待500ms
+        sys.wait(500)  
+    end
+end
+
+
+-- 第二个task的任务处理函数
+local function task2_func()
+    local count = 0
+    while true do
+        count = count + 1
+        log.info("task2_func", "运行中,计数:", count)
+        -- 等待300ms
+        sys.wait(300)  
+    end
+end
+
+-- 创建并启动第一个task
+-- 运行这个task的任务处理函数task1_func
+sys.taskInit(task1_func)
+
+log.info("task_scheduling", "after task1 and before task2")
+
+-- 创建并启动第二个task
+-- 运行这个task的任务处理函数task2_func
+sys.taskInit(task2_func)
+

+ 63 - 0
module/Air8000/demo/luatos_framework/luatos_task/shared_resource.lua

@@ -0,0 +1,63 @@
+--[[
+@module  shared_resource
+@summary 共享资源访问演示 
+@version 1.0
+@date    2025.08.15
+@author  朱天华
+@usage
+本文件为shared_resource应用功能模块,用来演示多个task访问共享资源,核心业务逻辑为:
+1、创建一个全局共享变量global_shared_variable,变量值初始化为0;
+2、创建两个task,task1和task2;
+2、在task1的任务处理函数中:
+   (1) 每隔1秒,执行一次for循环
+   (2) 循环体内循环100次,每次将全局共享变量global_shared_variable的值加1
+3、在task2的任务处理函数中,每隔300毫秒,task2的计数器加1,并且通过日志打印task2计数器的值;
+
+本文件没有对外接口,直接在main.lua中require "task_scheduling"就可以加载运行;
+]]
+
+-- 全局共享变量,初始值为0
+local global_shared_variable = 0
+
+-- 第一个task的任务处理函数
+local function task1_func()
+    while true do
+        log.info("task1_func", "for循环前,全局共享变量的值:", global_shared_variable)
+
+        for i=1,100 do
+            global_shared_variable = global_shared_variable + 1
+            -- sys.wait(5)
+        end
+
+        log.info("task1_func", "for循环后,全局共享变量的值:", global_shared_variable)
+
+        sys.wait(1000)
+    end
+end
+
+
+-- 第二个task的任务处理函数
+local function task2_func()
+    while true do
+        log.info("task2_func", "for循环前,全局共享变量的值:", global_shared_variable)
+
+        for i=1,100 do
+            global_shared_variable = global_shared_variable + 1
+            -- sys.wait(5)
+        end
+
+        log.info("task2_func", "for循环后,全局共享变量的值:", global_shared_variable)
+
+        sys.wait(1000)
+    end
+end
+
+
+-- 创建并启动第一个task
+-- 运行这个task的任务处理函数为task1_func
+sys.taskInit(task1_func)
+
+-- 创建并启动第二个task
+-- 运行这个task的任务处理函数为task2_func
+sys.taskInit(task2_func)
+

+ 33 - 0
module/Air8000/demo/luatos_framework/luatos_task/targeted_msg_sender.lua

@@ -0,0 +1,33 @@
+
+
+
+local function targeted_msg_sender_task_func()
+    local count = 0
+
+    while true do
+        count = count+1
+
+        -- 发布一条定向消息到名称为"nromal_wait_msg_task"的高级task
+        -- 消息名称为"SEND_DATA_REQ"
+        -- 消息携带两个参数:
+        -- 第一个参数是"from task"
+        -- 第二个参数是number类型的count
+        sysplus.sendMsg("nromal_wait_msg_task", "SEND_DATA_REQ", "from task", count)
+
+        -- 发布一条定向消息到名称为"delay_wait_msg_task"的高级task
+        -- 消息名称为"SEND_DATA_REQ"
+        -- 消息携带两个参数:
+        -- 第一个参数是"from task"
+        -- 第二个参数是number类型的count
+        sysplus.sendMsg("delay_wait_msg_task", "SEND_DATA_REQ", "from task", count)
+
+        -- 延时等待1秒
+        sys.wait(1000)
+    end
+end
+
+
+-- 创建并且启动一个基础task
+-- 运行这个task的任务处理函数targeted_msg_sender_task_func
+sys.taskInit(targeted_msg_sender_task_func)
+

+ 33 - 0
module/Air8000/demo/luatos_framework/luatos_task/task_count.lua

@@ -0,0 +1,33 @@
+--[[
+@module  create
+@summary task调度演示 
+@version 1.0
+@date    2025.08.12
+@author  朱天华
+@usage
+本文件为task_scheduling应用功能模块,用来演示task调度,核心业务逻辑为:
+1、创建两个task,task1和task2;
+2、在task1的任务处理函数中,每隔500毫秒,task1的计数器加1,并且通过日志打印task1计数器的值;
+3、在task2的任务处理函数中,每隔300毫秒,task2的计数器加1,并且通过日志打印task2计数器的值;
+
+本文件没有对外接口,直接在main.lua中require "create"就可以加载运行;
+]]
+
+local count = 0
+
+-- led task的任务处理函数
+local function led_task_func()
+    while true do
+        log.info("led_task_func")
+        sys.waitUntil("INVALID_MESSAGE")
+    end
+end
+
+-- 创建并启动第一个led task
+-- 运行这个task的任务处理函数led_task_func
+while true do
+    sys.taskInit(led_task_func)
+    count = count+1
+    log.info("create task count", count)
+end
+

+ 27 - 0
module/Air8000/demo/luatos_framework/luatos_task/task_func.lua

@@ -0,0 +1,27 @@
+--[[
+@module  create
+@summary task调度演示 
+@version 1.0
+@date    2025.08.12
+@author  朱天华
+@usage
+本文件为task_scheduling应用功能模块,用来演示task调度,核心业务逻辑为:
+1、创建两个task,task1和task2;
+2、在task1的任务处理函数中,每隔500毫秒,task1的计数器加1,并且通过日志打印task1计数器的值;
+3、在task2的任务处理函数中,每隔300毫秒,task2的计数器加1,并且通过日志打印task2计数器的值;
+
+本文件没有对外接口,直接在main.lua中require "create"就可以加载运行;
+]]
+
+sys.taskInit(led_task_func)
+
+
+local function led_task_func()
+    while true do
+        log.info("led_task_func")
+        sys.wait(1000)
+    end
+end
+
+
+

+ 37 - 0
module/Air8000/demo/luatos_framework/luatos_task/task_inout_env_err.lua

@@ -0,0 +1,37 @@
+
+
+local function mqtt_event_cbfunc()
+    log.info("mqtt_event_cbfunc")
+    sys.wait(1000)
+end
+
+-- sys.subscribe("MQTT_EVENT", mqtt_event_cbfunc)
+-- sys.timerStart(sys.publish, 1000, "MQTT_EVENT")
+
+
+local function timer_cbfunc()
+    log.info("timer_cbfunc")
+    sys.waitUntil("UNKNOWN_MSG", 1000)
+end
+
+-- sys.timerStart(timer_cbfunc, 1000)
+
+
+local function loop_timer_cbfunc()
+    log.info("loop_timer_cbfunc")
+    sysplus.waitMsg("SEND_MSG_TASK", "UNKNOWN_MSG", 1000)
+end
+
+local function send_targeted_msg_task_func()
+    while true do
+        -- 延时等待1秒
+        sys.wait(1000)
+    end
+end
+
+-- 创建并且启动一个高级task
+-- task的任务处理函数为send_targeted_msg_task_func
+-- task的名称为SEND_TASK_NAME
+-- 运行这个task的任务处理函数send_targeted_msg_task_func
+sysplus.taskInitEx(send_targeted_msg_task_func, "SEND_MSG_TASK")
+sys.timerLoopStart(loop_timer_cbfunc, 1000)

+ 131 - 0
module/Air8000/demo/luatos_framework/luatos_task/tgted_msg_receiver.lua

@@ -0,0 +1,131 @@
+local TASK_NAME = "MQTT_CLINET_MAIN"
+
+-- 非目标消息回调函数
+local function mqtt_client_main_cbfunc(msg)
+	log.info("mqtt_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
+end
+
+-- mqtt main task 的任务处理函数
+local function mqtt_client_main_task_func()
+    -- 连接、断开连接、订阅、取消订阅、异常等各种事件的处理调度逻辑
+    while true do
+        -- 等待"MQTT_EVENT"消息
+        msg = sysplus.waitMsg(TASK_NAME, "MQTT_EVENT")
+        log.info("mqtt_client_main_task_func waitMsg", msg[2], msg[3], msg[4])
+
+        -- connect连接结果
+        -- msg[3]表示连接结果,true为连接成功,false为连接失败
+        if msg[2] == "CONNECT" then
+            -- mqtt连接成功
+            if msg[3] then
+                log.info("mqtt_client_main_task_func", "connect success")
+            -- mqtt连接失败
+            else
+                log.info("mqtt_client_main_task_func", "connect error")
+            end
+
+        -- subscribe订阅结果
+        -- msg[3]表示订阅结果,true为订阅成功,false为订阅失败
+        elseif msg[2] == "SUBSCRIBE" then
+            -- 订阅成功
+            if msg[3] then
+                log.info("mqtt_client_main_task_func", "subscribe success", "qos: "..(msg[4] or "nil"))
+            -- 订阅失败
+            else
+                log.error("mqtt_client_main_task_func", "subscribe error", "code", msg[4])
+            end
+
+        -- 被动关闭了mqtt连接
+        -- 被网络或者服务器断开了连接
+        elseif msg[2] == "DISCONNECTED" then
+            log.info("mqtt_client_main_task_func", "disconnected")
+        end
+    end
+end
+
+local function send_non_targeted_msg_task_func()
+    local count = 0
+
+    while true do
+        count = count+1
+
+        -- 向TASK_NAME这个任务发送一条消息
+        -- 消息名称为"UNKNOWN_EVENT"
+        -- 消息携带一个number类型的参数count
+        sys.sendMsg(TASK_NAME, "UNKNOWN_EVENT", count)
+
+        -- 延时等待1秒
+        sys.wait(1000)
+    end
+end
+
+local function send_non_targeted_msg_task_func()
+    local count = 0
+
+    while true do
+        count = count+1
+
+        -- 向TASK_NAME这个任务发送一条消息
+        -- 消息名称为"UNKNOWN_EVENT"
+        -- 消息携带一个number类型的参数count
+        sysplus.sendMsg(TASK_NAME, "UNKNOWN_EVENT", count)
+
+        -- 延时等待1秒
+        sys.wait(1000)
+    end
+end
+
+
+local function send_targeted_msg_task_func()
+    while true do
+        -- 向TASK_NAME这个任务发送一条消息
+        -- 消息名称为"MQTT_EVENT"
+        -- 消息携带两个参数
+        -- 第一个参数为"CONNECT"
+        -- 第二个参数为true
+        -- 这条消息的意思是MQTT连接成功
+        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "CONNECT", true)
+
+        -- 延时等待1秒
+        sys.wait(1000)
+
+        -- 向TASK_NAME这个任务发送一条消息
+        -- 消息名称为"MQTT_EVENT"
+        -- 消息携带三个参数
+        -- 第一个参数为"SUBSCRIBE"
+        -- 第二个参数为true
+        -- 第三个参数为0
+        -- 这条消息的意思是MQTT订阅成功,qos为0
+        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "SUBSCRIBE", true, 0)
+
+        -- 延时等待1秒
+        sys.wait(1000)
+
+        -- 向TASK_NAME这个任务发送一条消息
+        -- 消息名称为"MQTT_EVENT"
+        -- 消息携带一个参数"DISCONNECTED"
+        -- 这条消息的意思是MQTT连接被动断开
+        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "DISCONNECTED")
+
+        -- 延时等待1秒
+        sys.wait(1000)
+    end
+end
+
+-- 创建并且启动一个高级task
+-- task的任务处理函数为mqtt_client_main_task_func
+-- task的名称为TASK_NAME变量的值"MQTT_CLINET_MAIN"
+-- task的非目标消息回调函数为mqtt_client_main_cbfunc
+-- 运行这个task的任务处理函数mqtt_client_main_task_func
+sysplus.taskInitEx(mqtt_client_main_task_func, TASK_NAME, mqtt_client_main_cbfunc)
+
+
+-- 创建并且启动一个基础task
+-- 运行这个task的任务处理函数send_targeted_msg_task_func
+sys.taskInit(send_non_targeted_msg_task_func)
+
+-- 创建并且启动一个高级task
+-- task的任务处理函数为send_targeted_msg_task_func
+-- task的名称为SEND_TASK_NAME
+-- 运行这个task的任务处理函数send_targeted_msg_task_func
+sysplus.taskInitEx(send_targeted_msg_task_func, "SEND_MSG_TASK")

+ 39 - 0
module/Air8000/demo/luatos_framework/luatos_task/timer.lua

@@ -0,0 +1,39 @@
+
+
+
+local function timer_test_task_func()
+    sys.timerStart(log.info, 1000, "red")
+    sys.timerStart(log.info, 2000, "red")
+    sys.timerStart(log.info, 3000, "red")
+
+    sys.wait(3000)
+
+    sys.timerLoopStart(sys.publish, 1000, "loop_timer_cbfunc_msg")
+    sys.timerStart(sys.timerStop, 5500, sys.publish, "loop_timer_cbfunc_msg")
+
+    while true do
+        local result = sys.waitUntil("loop_timer_cbfunc_msg", 2000)
+        if result then
+            log.info("receive loop_timer_cbfunc_msg")
+        else
+            log.info("no loop_timer_cbfunc_msg, 2000ms timeout")
+            break
+        end
+    end
+
+    local timer_id = sys.timerStart(log.info, 1000, "1")
+    sys.timerStart(log.info, 2000, "2")
+    sys.timerStart(log.info, 3000, "3")
+    sys.timerStart(log.info, 4000, "4")
+    sys.timerStart(log.info, 5000, "5")
+
+    sys.timerStop(timer_id)
+    
+    sys.wait(2000)
+
+    sys.timerStopAll(log.info)
+end
+
+
+sys.timerStart(sys.taskInit, 3000, timer_test_task_func)
+

+ 24 - 0
module/Air8000/demo/luatos_framework/luatos_task/variable_args.lua

@@ -0,0 +1,24 @@
+--[[
+@module  create
+@summary task调度演示 
+@version 1.0
+@date    2025.08.12
+@author  朱天华
+@usage
+本文件为task_scheduling应用功能模块,用来演示task调度,核心业务逻辑为:
+1、创建两个task,task1和task2;
+2、在task1的任务处理函数中,每隔500毫秒,task1的计数器加1,并且通过日志打印task1计数器的值;
+3、在task2的任务处理函数中,每隔300毫秒,task2的计数器加1,并且通过日志打印task2计数器的值;
+
+本文件没有对外接口,直接在main.lua中require "create"就可以加载运行;
+]]
+
+
+local function led_task_func(arg1, arg2, arg3, arg4, arg5)
+    while true do
+        log.info("led_task_func", arg1, arg2, arg3, arg4, arg5)
+        sys.wait(1000)
+    end
+end
+
+sys.taskInit(led_task_func, "arg1", 3, nil, true, led_task_func)

+ 5 - 0
module/Air8000/demo/mqtt/readme.md

@@ -1,3 +1,8 @@
+## 总体设计框图
+![](https://docs.openluat.com/air8000/luatos/app/socket/mqtt/image/block_diagram.png)
+
+
+
 ## 功能模块介绍
 
 1、main.lua:主程序入口;

+ 0 - 266
module/Air8000/demo/mqttv2/mqtt/mqtt_main.lua

@@ -1,266 +0,0 @@
---[[
-@module  mqtt_main
-@summary mqtt client 主应用功能模块 
-@version 1.0
-@date    2025.07.28
-@author  朱天华
-@usage
-本文件为mqtt client 主应用功能模块,核心业务逻辑为:
-1、创建一个mqtt client,连接server;
-2、处理连接/订阅/取消订阅/异常逻辑,出现异常后执行重连动作;
-3、调用mqtt_receiver的外部接口mqtt_receiver.proc,对接收到的publish数据进行处理;
-4、调用sysplus.sendMsg接口,发送"CONNECT OK"、"PUBLISH OK"和"DISCONNECTED"三种类型的"MQTT_EVENT"消息到mqtt_sender的task,控制publish数据发送逻辑;
-5、收到MQTT心跳应答后,执行sys.publish("FEED_NETWORK_WATCHDOG") 对网络环境检测看门狗功能模块进行喂狗;
-
-本文件没有对外接口,直接在main.lua中require "mqtt_main"就可以加载运行;
-]]
-
-
--- 加载mqtt client数据接收功能模块
-local mqtt_receiver = require "mqtt_receiver"
--- 加载mqtt client数据发送功能模块
-local mqtt_sender = require "mqtt_sender"
-
--- mqtt服务器地址和端口
--- 这里使用的地址和端口,仅能用作测试用途,不可商用,说不定哪一天就关闭了
--- 用户开发项目时,替换为自己的商用服务器地址和端口
-local SERVER_ADDR = "lbsmqtt.airm2m.com"
-local SERVER_PORT = 1884
-
--- mqtt_main的任务名
-local TASK_NAME = mqtt_sender.TASK_NAME_PREFIX.."main"
-
--- mqtt主题的前缀:IMEI号
-local TOPIC_PREFIX = mobile.imei()
-
--- mqtt client的事件回调函数
-local function mqtt_client_event_cbfunc(mqtt_client, event, data, payload, metas)
-    log.info("mqtt_client_event_cbfunc", mqtt_client, event, data, payload, json.encode(metas))
-
-    -- mqtt连接成功
-    if event == "conack" then
-        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "CONNECT", true)
-        -- 订阅单主题
-        -- 第二个参数表示qos,取值范围为0,1,2,如果不设置,默认为0
-        if not mqtt_client:subscribe(TOPIC_PREFIX .. "/down") then
-            sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "SUBSCRIBE", false, -1)
-        end
-        -- 订阅多主题,如果有需要,打开注释
-        -- 表中的每一个订阅主题的格式为[topic]=qos
-        -- if not mqtt_client:subscribe(
-        --         {
-        --             [(TOPIC_PREFIX .. "/data"]=0,
-        --             [(TOPIC_PREFIX .. "/cmd"]=1
-        --         }
-        -- ) then
-        --     sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "SUBSCRIBE", false, -1)
-        -- end
-
-    -- 订阅结果
-    -- data:订阅应答结果,true为成功,false为失败
-    -- payload:number类型;成功时表示qos,取值范围为0,1,2;失败时表示失败码,一般是0x80
-    elseif event == "suback" then
-        -- 发送消息通知 mqtt main task
-        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "SUBSCRIBE", data, payload)
-        
-    -- 取消订阅成功
-    elseif event == "unsuback" then
-        -- 发送消息通知 mqtt main task
-        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "UNSUBSCRIBE", true)
-
-    -- 接收到服务器下发的publish数据
-    -- data:string类型,表示topic
-    -- payload:string类型,表示payload
-    -- metas:table类型,数据内容如下
-    -- {
-    --     qos: number类型,取值范围0,1,2
-    --     retain:number类型,取值范围0,1
-    --     dup:number类型,取值范围0,1
-    --     message_id: number类型
-    -- }
-    elseif event == "recv" then
-        -- 对接收到的publish数据处理
-        mqtt_receiver.proc(data, payload, metas)
-
-    -- 发送成功publish数据
-    -- data:number类型,表示message id
-    elseif event == "sent" then
-        -- 发送消息通知 mqtt sender task
-        sysplus.sendMsg(mqtt_sender.TASK_NAME, "MQTT_EVENT", "PUBLISH_OK", data)
-
-    -- 服务器断开mqtt连接
-    elseif event == "disconnect" then
-        -- 发送消息通知 mqtt main task
-        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "DISCONNECTED", false)
-
-    -- 收到服务器的心跳应答
-    elseif event == "pong" then
-        -- 接收到数据,通知网络环境检测看门狗功能模块进行喂狗
-        sys.publish("FEED_NETWORK_WATCHDOG") 
-	
-    -- 严重异常,本地会主动断开连接
-    -- data:string类型,表示具体的异常,有以下几种:
-    --       "connect":tcp连接失败
-    --       "tx":数据发送失败
-    --       "conack":mqtt connect后,服务器应答CONNACK鉴权失败,失败码为payload(number类型)
-    --       "other":其他异常
-    elseif event == "error" then
-        if data == "connect" or data == "conack" then
-            -- 发送消息通知 mqtt main task,连接失败
-            sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "CONNECT", false)
-        elseif data == "other" or data == "tx" then
-            -- 发送消息通知 mqtt main task,出现异常
-            sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "ERROR")
-        end
-    end
-end
-
--- mqtt main task 的任务处理函数
-local function mqtt_client_main_task_func() 
-
-    local mqtt_client
-    local result, msg, para
-
-    while true do
-        -- 如果当前时间点设置的默认网卡还没有连接成功,一直在这里循环等待
-        while not socket.adapter(socket.dft()) do
-            log.warn("mqtt_client_main_task_func", "wait IP_READY", socket.dft())
-            -- 在此处阻塞等待默认网卡连接成功的消息"IP_READY"
-            -- 或者等待1秒超时退出阻塞等待状态;
-            -- 注意:此处的1000毫秒超时不要修改的更长;
-            -- 因为当使用exnetif.set_priority_order配置多个网卡连接外网的优先级时,会隐式的修改默认使用的网卡
-            -- 当exnetif.set_priority_order的调用时序和此处的socket.adapter(socket.dft())判断时序有可能不匹配
-            -- 此处的1秒,能够保证,即使时序不匹配,也能1秒钟退出阻塞状态,再去判断socket.adapter(socket.dft())
-            sys.waitUntil("IP_READY", 1000)
-        end
-
-        -- 检测到了IP_READY消息
-        log.info("mqtt_client_main_task_func", "recv IP_READY", socket.dft())
-
-        -- 清空此task绑定的消息队列中的未处理的消息
-        sysplus.cleanMsg(TASK_NAME)
-
-        -- 创建mqtt client对象
-        mqtt_client = mqtt.create(nil, SERVER_ADDR, SERVER_PORT)
-        -- 如果创建mqtt client对象失败
-        if not mqtt_client then
-            log.error("mqtt_client_main_task_func", "mqtt.create error")
-            goto EXCEPTION_PROC
-        end
-
-        -- 配置mqtt client对象的client id,username,password和clean session标志
-        result = mqtt_client:auth(mobile.imei(), "", "", true)
-        -- 如果配置失败
-        if not result then
-            log.error("mqtt_client_main_task_func", "mqtt_client:auth error")
-            goto EXCEPTION_PROC
-        end
-
-        -- 注册mqtt client对象的事件回调函数
-        mqtt_client:on(mqtt_client_event_cbfunc)
-
-        -- 设置mqtt keepalive时间为120秒
-        -- 如果没有设置,内核固件中默认为180秒
-        -- 有需要的话,可以打开注释
-        -- mqtt_client:keepalive(120)
-
-        -- 设置遗嘱消息,有需要的话,可以打开注释
-        -- mqtt_client:will(TOPIC_PREFIX .. "/status", "offline")
-
-        -- 连接server
-        result = mqtt_client:connect()
-        -- 如果连接server失败
-        if not result then
-            log.error("mqtt_client_main_task_func", "mqtt_client:connect error")
-            goto EXCEPTION_PROC
-        end
-
-
-        -- 连接、断开连接、订阅、取消订阅、异常等各种事件的处理调度逻辑
-        while true do
-            -- 等待"MQTT_EVENT"消息
-            msg = sysplus.waitMsg(TASK_NAME, "MQTT_EVENT")
-            log.info("mqtt_client_main_task_func waitMsg", msg[2], msg[3], msg[4])
-
-            -- connect连接结果
-            -- msg[3]表示连接结果,true为连接成功,false为连接失败
-            if msg[2] == "CONNECT" then                
-                -- mqtt连接成功
-                if msg[3] then
-                    log.info("mqtt_client_main_task_func", "connect success")
-                    -- 通知mqtt sender数据发送应用模块的task,MQTT连接成功
-                    sysplus.sendMsg(mqtt_sender.TASK_NAME, "MQTT_EVENT", "CONNECT_OK", mqtt_client)
-                -- mqtt连接失败
-                else
-                    log.info("mqtt_client_main_task_func", "connect error")
-                    -- 退出循环,发起重连
-                    break
-                end
-
-            -- subscribe订阅结果
-            -- msg[3]表示订阅结果,true为订阅成功,false为订阅失败
-            elseif msg[2] == "SUBSCRIBE" then
-                -- 订阅成功
-                if msg[3] then
-                    log.info("mqtt_client_main_task_func", "subscribe success", "qos: "..(msg[4] or "nil"))
-                -- 订阅失败
-                else
-                    log.error("mqtt_client_main_task_func", "subscribe error", "code", msg[4])
-                    -- 主动断开mqtt client连接
-                    mqtt_client:disconnect()
-                    -- 发送disconnect之后,此处延时1秒,给数据发送预留一点儿时间,发送到服务器;
-                    -- 即使1秒的时间不足以发送给服务器也没关系;对服务器来说,mqtt客户端只是没有优雅的断开,不影响什么实质功能;
-                    sys.wait(1000)
-                    break
-                end
-
-            -- unsubscribe取消订阅成功
-            elseif msg[2] == "UNSUBSCRIBE" then
-                log.info("mqtt_client_main_task_func", "unsubscribe success")
-            
-            -- 需要主动关闭mqtt连接
-            -- 用户需要主动关闭mqtt连接时,可以调用sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "CLOSE")
-            elseif msg[2] == "CLOSE" then
-                -- 主动断开mqtt client连接
-                mqtt_client:disconnect()
-                -- 发送disconnect之后,此处延时1秒,给数据发送预留一点儿时间,发送到服务器;
-                -- 即使1秒的时间不足以发送给服务器也没关系;对服务器来说,mqtt客户端只是没有优雅的断开,不影响什么实质功能;
-                sys.wait(1000)
-                break
-            
-            -- 被动关闭了mqtt连接
-            -- 被网络或者服务器断开了连接
-            elseif msg[2] == "DISCONNECTED" then
-                break
-            
-            -- 出现了其他异常
-            elseif msg[2] == "ERROR" then
-                break
-            end     
-        end
-
-        -- 出现异常    
-        ::EXCEPTION_PROC::
-
-        -- 清空此task绑定的消息队列中的未处理的消息
-        sysplus.cleanMsg(TASK_NAME)
-
-        -- 通知mqtt sender数据发送应用模块的task,MQTT连接已经断开
-        sysplus.sendMsg(mqtt_sender.TASK_NAME, "MQTT_EVENT", "DISCONNECTED")
-
-        -- 如果存在mqtt client对象
-        if mqtt_client then
-            -- 关闭mqtt client,并且释放mqtt client对象
-            mqtt_client:close()
-            mqtt_client = nil
-        end
-        
-        -- 5秒后跳转到循环体开始位置,自动发起重连
-        sys.wait(5000)
-    end
-end
-
---创建并且启动一个task
---运行这个task的处理函数mqtt_client_main_task_func
-sysplus.taskInitEx(mqtt_client_main_task_func, TASK_NAME)
-

+ 0 - 64
module/Air8000/demo/mqttv2/mqtt/mqtt_receiver.lua

@@ -1,64 +0,0 @@
---[[
-@module  mqtt_receiver
-@summary mqtt client数据接收处理应用功能模块 
-@version 1.0
-@date    2025.07.29
-@author  朱天华
-@usage
-本文件为mqtt client 数据接收应用功能模块,核心业务逻辑为:
-处理接收到的publish数据,同时将数据发送给其他应用功能模块做进一步处理;
-
-本文件的对外接口有2个:
-1、mqtt_receiver.proc(topic, payload, metas):publish数据处理入口,在mqtt_main.lua中调用;
-2、sys.publish("RECV_DATA_FROM_SERVER", "recv from mqtt server: ", topic, payload):
-   将接收到的publish中的topic和payload数据通过消息"RECV_DATA_FROM_SERVER"发布出去;
-   需要处理数据的应用功能模块订阅处理此消息即可,本demo项目中uart_app.lua中订阅处理了本消息;
-]]
-
-local mqtt_receiver = {}
-
-
-
---[[
-处理接收到的publish数据
-
-@api mqtt_receiver.proc(topic, payload, metas)
-
-@param1 topic string
-表示publish主题
-
-@param2 payload string
-表示publish数据负载
-
-@param2 payload string
-表示publish数据负载
-
-@param3 metas table
-表示publish报文的一些参数;格式如下:
-{
-    qos: number类型,取值范围0,1,2
-    retain:number类型,取值范围0,1
-    dup:number类型,取值范围0,1
-    message_id: number类型
-}
-
-@return1 result nil
-
-@usage
-
-mqtt_receiver.proc(topic, payload, metas)
-]]
-function mqtt_receiver.proc(topic, payload, metas)
-
-    log.info("mqtt_receiver.proc", topic, payload:len(), json.encode(metas))
-
-    -- 接收到数据,通知网络环境检测看门狗功能模块进行喂狗
-    sys.publish("FEED_NETWORK_WATCHDOG") 
-
-    -- 将topic和payload通过"RECV_DATA_FROM_SERVER"消息publish出去,给其他应用模块处理
-    sys.publish("RECV_DATA_FROM_SERVER", "recv from mqtt server: ", topic, payload)
-
-    -- 也可以直接在此处编写代码,处理topic和payload   
-end
-
-return mqtt_receiver

+ 0 - 154
module/Air8000/demo/mqttv2/mqtt/mqtt_sender.lua

@@ -1,154 +0,0 @@
---[[
-@module  mqtt_sender
-@summary mqtt client数据发送应用功能模块 
-@version 1.0
-@date    2025.07.29
-@author  朱天华
-@usage
-本文件为mqtt client 数据发送应用功能模块,核心业务逻辑为:
-1、sys.subscribe("SEND_DATA_REQ", send_data_req_proc_func)订阅"SEND_DATA_REQ"消息,将其他应用模块需要发送的数据存储到队列send_queue中;
-2、mqtt sender task接收"CONNECT OK"、"PUBLISH_REQ"、"PUBLISH OK"三种类型的"MQTT_EVENT"消息,遍历队列send_queue,逐条发送数据到server;
-3、mqtt sender task接收"DISCONNECTED"类型的"MQTT_EVENT"消息,丢弃掉队列send_queue中未发送的数据;
-4、任何一条数据无论发送成功还是失败,只要这条数据有回调函数,都会通过回调函数通知数据发送方;
-
-本文件的对外接口有1个:
-1、sys.subscribe("SEND_DATA_REQ", send_data_req_proc_func):订阅"SEND_DATA_REQ"消息;
-   其他应用模块如果需要发送数据,直接sys.publish这个消息即可,将需要发送的topic,payload和qos以及回调函数和回调参数一起publish出去;
-   本demo项目中uart_app.lua和timer_app.lua中publish了这个消息;
-]]
-
-local mqtt_sender = {}
-
---[[
-数据发送队列,数据结构为:
-{
-    [1] = {topic="topic1", payload="payload1", qos=0, cb={func=callback_function1, para=callback_para1}},
-    [2] = {topic="topic2", payload="payload2", qos=1, cb={func=callback_function2, para=callback_para2}},
-    [3] = {topic="topic3", payload="payload3", qos=2, cb={func=callback_function3, para=callback_para3}},
-}
-topic的内容为publish的主题,string类型,必须存在;
-payload的内容为publish的负载数据,string类型,必须存在;
-qos的内容为publish的质量等级,number类型,取值范围0,1,2,可选,如果用户没有指定,默认为0;
-cb.func的内容为数据发送结果的用户回调函数,可以不存在;
-cb.para的内容为数据发送结果的用户回调函数的回调参数,可以不存在;
-]]
-local send_queue = {}
-
--- mqtt client的任务名前缀
-mqtt_sender.TASK_NAME_PREFIX = "mqtt_"
-
--- mqtt_client_sender的任务名
-mqtt_sender.TASK_NAME = mqtt_sender.TASK_NAME_PREFIX.."sender"
-
--- "SEND_DATA_REQ"消息的处理函数
-local function send_data_req_proc_func(tag, topic, payload, qos, cb)
-    -- 将原始数据增加前缀,然后插入到发送队列send_queue中
-    table.insert(send_queue, {topic=topic, payload="send from "..tag..": "..payload, qos=qos or 0, cb=cb})
-    -- 发送消息通知 mqtt sender task,有新数据等待发送
-    sysplus.sendMsg(mqtt_sender.TASK_NAME, "MQTT_EVENT", "PUBLISH_REQ")
-end
-
--- 按照顺序发送send_queue中的数据
--- 如果调用publish接口成功,则返回当前正在发送的数据项
--- 如果调用publish接口失败,通知回调函数发送失败后,继续发送下一条数据
-local function publish_item(mqtt_client)
-    local item
-    -- 如果发送队列中有数据等待发送
-    while #send_queue>0 do
-        -- 取出来第一条数据赋值给item
-        -- 同时从队列send_queue中删除这一条数据
-        item = table.remove(send_queue, 1)
-
-        -- publish数据
-        -- result表示调用publish接口的同步结果,返回值有以下几种:
-        -- 如果失败,返回nil
-        -- 如果成功,number类型,qos为0时直接返回0;qos为1或者2时返回publish报文的message id
-        result = mqtt_client:publish(item.topic, item.payload, item.qos)
-
-        -- publish接口调用成功
-        if result then
-            return item
-        -- publish接口调用失败
-        else
-            -- 如果当前发送的数据有用户回调函数,则执行用户回调函数
-            if item.cb and item.cb.func then
-                item.cb.func(false, item.cb.para)
-            end
-        end
-    end
-end
-
-
-local function publish_item_cbfunc(item, result)
-    if item then
-        -- 如果当前发送的数据有用户回调函数,则执行用户回调函数
-        if item.cb and item.cb.func then
-            item.cb.func(result, item.cb.para)
-        end
-    end
-end
-
--- mqtt client sender的任务处理函数
-local function mqtt_client_sender_task_func() 
-
-    local mqtt_client
-    local send_item
-    local result, msg
-
-    while true do
-        -- 等待"MQTT_EVENT"消息
-        msg = sysplus.waitMsg(mqtt_sender.TASK_NAME, "MQTT_EVENT")
-
-        -- mqtt连接成功
-        -- msg[3]表示mqtt client对象
-        if msg[2] == "CONNECT_OK" then
-            mqtt_client = msg[3]
-            -- 发送send_queue中的数据
-            send_item = publish_item(mqtt_client)
-        -- mqtt publish数据请求
-        elseif msg[2] == "PUBLISH_REQ" then
-            -- 如果mqtt client对象存在,并且没有正在等待发送结果的发送数据项
-            if mqtt_client and not send_item then
-                -- 发送send_queue中的数据
-                send_item = publish_item(mqtt_client)
-            end
-        -- mqtt publish数据成功
-        elseif msg[2] == "PUBLISH_OK" then
-            -- publish成功,执行回调函数通知发送方
-            publish_item_cbfunc(send_item, true)
-            -- publish成功,通知网络环境检测看门狗功能模块进行喂狗
-            sys.publish("FEED_NETWORK_WATCHDOG")
-            -- 发送send_queue中的数据
-            send_item = publish_item(mqtt_client)
-        -- mqtt断开连接
-        elseif msg[2] == "DISCONNECTED" then
-            -- 清空mqtt client对象
-            mqtt_client = nil
-            -- 如果存在正在等待发送结果的发送项,执行回调函数通知发送方失败
-            publish_item_cbfunc(send_item, false)
-            -- 如果发送队列中有数据等待发送
-            while #send_queue>0 do
-                -- 取出来第一条数据赋值给send_item
-                -- 同时从队列send_queue中删除这一条数据
-                send_item = table.remove(send_queue,1)
-                -- 执行回调函数通知发送方失败
-                publish_item_cbfunc(send_item, false)
-            end
-            -- 当前没有正在等待发送结果的发送项
-            send_item = nil
-        end
-    end
-end
-
-
--- 订阅"SEND_DATA_REQ"消息;
--- 其他应用模块如果需要发送数据,直接sys.publish这个消息即可,将需要发送的数据以及回调函数和回调参数一起publish出去;
--- 本demo项目中uart_app.lua和timer_app.lua中publish了这个消息;
-sys.subscribe("SEND_DATA_REQ", send_data_req_proc_func)
-
-
---创建并且启动一个task
---运行这个task的处理函数mqtt_client_sender_task_func
-sysplus.taskInitEx(mqtt_client_sender_task_func, mqtt_sender.TASK_NAME)
-
-return mqtt_sender

+ 0 - 266
module/Air8000/demo/mqttv2/mqtts/mqtts_main.lua

@@ -1,266 +0,0 @@
---[[
-@module  mqtts_main
-@summary mqtts client 主应用功能模块 
-@version 1.0
-@date    2025.07.28
-@author  朱天华
-@usage
-本文件为mqtts client 主应用功能模块,核心业务逻辑为:
-1、创建一个mqtts client,连接server;
-2、处理连接/订阅/取消订阅/异常逻辑,出现异常后执行重连动作;
-3、调用mqtts_receiver的外部接口mqtts_receiver.proc,对接收到的publish数据进行处理;
-4、调用sysplus.sendMsg接口,发送"CONNECT OK"、"PUBLISH OK"和"DISCONNECTED"三种类型的"MQTT_EVENT"消息到mqtts_sender的task,控制publish数据发送逻辑;
-5、收到MQTT心跳应答后,执行sys.publish("FEED_NETWORK_WATCHDOG") 对网络环境检测看门狗功能模块进行喂狗;
-
-本文件没有对外接口,直接在main.lua中require "mqtts_main"就可以加载运行;
-]]
-
-
--- 加载mqtts client数据接收功能模块
-local mqtts_receiver = require "mqtts_receiver"
--- 加载mqtts client数据发送功能模块
-local mqtts_sender = require "mqtts_sender"
-
--- mqtts服务器地址和端口
--- 这里使用的地址和端口,仅能用作测试用途,不可商用,说不定哪一天就关闭了
--- 用户开发项目时,替换为自己的商用服务器地址和端口
-local SERVER_ADDR = "airlbs.openluat.com"
-local SERVER_PORT = 8883
-
--- mqtts_main的任务名
-local TASK_NAME = mqtts_sender.TASK_NAME_PREFIX.."main"
-
--- mqtt主题的前缀:IMEI号
-local TOPIC_PREFIX = mobile.imei()
-
--- mqtts client的事件回调函数
-local function mqtts_client_event_cbfunc(mqtt_client, event, data, payload, metas)
-    log.info("mqtts_client_event_cbfunc", mqtt_client, event, data, payload, json.encode(metas))
-
-    -- mqtt连接成功
-    if event == "conack" then
-        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "CONNECT", true)
-        -- 订阅单主题
-        -- 第二个参数表示qos,取值范围为0,1,2,如果不设置,默认为0
-        if not mqtt_client:subscribe(TOPIC_PREFIX .. "/down") then
-            sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "SUBSCRIBE", false, -1)
-        end
-        -- 订阅多主题,如果有需要,打开注释
-        -- 表中的每一个订阅主题的格式为[topic]=qos
-        -- if not mqtt_client:subscribe(
-        --         {
-        --             [(TOPIC_PREFIX .. "/data"]=0,
-        --             [(TOPIC_PREFIX .. "/cmd"]=1
-        --         }
-        -- ) then
-        --     sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "SUBSCRIBE", false, -1)
-        -- end
-
-    -- 订阅结果
-    -- data:订阅应答结果,true为成功,false为失败
-    -- payload:number类型;成功时表示qos,取值范围为0,1,2;失败时表示失败码,一般是0x80
-    elseif event == "suback" then
-        -- 发送消息通知 mqtts main task
-        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "SUBSCRIBE", data, payload)
-        
-    -- 取消订阅成功
-    elseif event == "unsuback" then
-        -- 发送消息通知 mqtts main task
-        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "UNSUBSCRIBE", true)
-
-    -- 接收到服务器下发的publish数据
-    -- data:string类型,表示topic
-    -- payload:string类型,表示payload
-    -- metas:table类型,数据内容如下
-    -- {
-    --     qos: number类型,取值范围0,1,2
-    --     retain:number类型,取值范围0,1
-    --     dup:number类型,取值范围0,1
-    --     message_id: number类型
-    -- }
-    elseif event == "recv" then
-        -- 对接收到的publish数据处理
-        mqtts_receiver.proc(data, payload, metas)
-
-    -- 发送成功publish数据
-    -- data:number类型,表示message id
-    elseif event == "sent" then
-        -- 发送消息通知 mqtts sender task
-        sysplus.sendMsg(mqtts_sender.TASK_NAME, "MQTT_EVENT", "PUBLISH_OK", data)
-
-    -- 服务器断开mqtt连接
-    elseif event == "disconnect" then
-        -- 发送消息通知 mqtts main task
-        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "DISCONNECTED", false)
-
-    -- 收到服务器的心跳应答
-    elseif event == "pong" then
-        -- 接收到数据,通知网络环境检测看门狗功能模块进行喂狗
-        sys.publish("FEED_NETWORK_WATCHDOG") 
-	
-    -- 严重异常,本地会主动断开连接
-    -- data:string类型,表示具体的异常,有以下几种:
-    --       "connect":tcp连接失败
-    --       "tx":数据发送失败
-    --       "conack":mqtt connect后,服务器应答CONNACK鉴权失败,失败码为payload(number类型)
-    --       "other":其他异常
-    elseif event == "error" then
-        if data == "connect" or data == "conack" then
-            -- 发送消息通知 mqtts main task,连接失败
-            sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "CONNECT", false)
-        elseif data == "other" or data == "tx" then
-            -- 发送消息通知 mqtts main task,出现异常
-            sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "ERROR")
-        end
-    end
-end
-
--- mqtts main task 的任务处理函数
-local function mqtts_client_main_task_func() 
-
-    local mqtt_client
-    local result, msg, para
-
-    while true do
-        -- 如果当前时间点设置的默认网卡还没有连接成功,一直在这里循环等待
-        while not socket.adapter(socket.dft()) do
-            log.warn("mqtts_client_main_task_func", "wait IP_READY", socket.dft())
-            -- 在此处阻塞等待默认网卡连接成功的消息"IP_READY"
-            -- 或者等待1秒超时退出阻塞等待状态;
-            -- 注意:此处的1000毫秒超时不要修改的更长;
-            -- 因为当使用exnetif.set_priority_order配置多个网卡连接外网的优先级时,会隐式的修改默认使用的网卡
-            -- 当exnetif.set_priority_order的调用时序和此处的socket.adapter(socket.dft())判断时序有可能不匹配
-            -- 此处的1秒,能够保证,即使时序不匹配,也能1秒钟退出阻塞状态,再去判断socket.adapter(socket.dft())
-            sys.waitUntil("IP_READY", 1000)
-        end
-
-        -- 检测到了IP_READY消息
-        log.info("mqtts_client_main_task_func", "recv IP_READY", socket.dft())
-
-        -- 清空此task绑定的消息队列中的未处理的消息
-        sysplus.cleanMsg(TASK_NAME)
-
-        -- 创建mqtt client对象,ssl连接,不需要证书校验
-        mqtt_client = mqtt.create(nil, SERVER_ADDR, SERVER_PORT, true)
-        -- 如果创建mqtt client对象失败
-        if not mqtt_client then
-            log.error("mqtts_client_main_task_func", "mqtt.create error")
-            goto EXCEPTION_PROC
-        end
-
-        -- 配置mqtt client对象的client id,username,password和clean session标志
-        result = mqtt_client:auth(mobile.imei(), "", "", true)
-        -- 如果配置失败
-        if not result then
-            log.error("mqtts_client_main_task_func", "mqtt_client:auth error")
-            goto EXCEPTION_PROC
-        end
-
-        -- 注册mqtt client对象的事件回调函数
-        mqtt_client:on(mqtts_client_event_cbfunc)
-
-        -- 设置mqtt keepalive时间为120秒
-        -- 如果没有设置,内核固件中默认为180秒
-        -- 有需要的话,可以打开注释
-        -- mqtt_client:keepalive(120)
-
-        -- 设置遗嘱消息,有需要的话,可以打开注释
-        -- mqtt_client:will(TOPIC_PREFIX .. "/status", "offline")
-
-        -- 连接server
-        result = mqtt_client:connect()
-        -- 如果连接server失败
-        if not result then
-            log.error("mqtts_client_main_task_func", "mqtt_client:connect error")
-            goto EXCEPTION_PROC
-        end
-
-
-        -- 连接、断开连接、订阅、取消订阅、异常等各种事件的处理调度逻辑
-        while true do
-            -- 等待"MQTT_EVENT"消息
-            msg = sysplus.waitMsg(TASK_NAME, "MQTT_EVENT")
-            log.info("mqtts_client_main_task_func waitMsg", msg[2], msg[3], msg[4])
-
-            -- connect连接结果
-            -- msg[3]表示连接结果,true为连接成功,false为连接失败
-            if msg[2] == "CONNECT" then                
-                -- mqtt连接成功
-                if msg[3] then
-                    log.info("mqtts_client_main_task_func", "connect success")
-                    -- 通知数据发送应用模块,MQTT连接成功
-                    sysplus.sendMsg(mqtts_sender.TASK_NAME, "MQTT_EVENT", "CONNECT_OK", mqtt_client)
-                -- mqtt连接失败
-                else
-                    log.info("mqtts_client_main_task_func", "connect error")
-                    -- 退出循环,发起重连
-                    break
-                end
-
-            -- subscribe订阅结果
-            -- msg[3]表示订阅结果,true为订阅成功,false为订阅失败
-            elseif msg[2] == "SUBSCRIBE" then
-                -- 订阅成功
-                if msg[3] then
-                    log.info("mqtts_client_main_task_func", "subscribe success", "qos: "..(msg[4] or "nil"))
-                -- 订阅失败
-                else
-                    log.error("mqtts_client_main_task_func", "subscribe error", "code", msg[4])
-                    -- 主动断开mqtt client连接
-                    mqtt_client:disconnect()
-                    -- 发送disconnect之后,此处延时1秒,给数据发送预留一点儿时间,发送到服务器;
-                    -- 即使1秒的时间不足以发送给服务器也没关系;对服务器来说,mqtt客户端只是没有优雅的断开,不影响什么实质功能;
-                    sys.wait(1000)
-                    break
-                end
-
-            -- unsubscribe取消订阅成功
-            elseif msg[2] == "UNSUBSCRIBE" then
-                log.info("mqtts_client_main_task_func", "unsubscribe success")
-            
-            -- 需要主动关闭mqtt连接
-            -- 用户需要主动关闭mqtt连接时,可以调用sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "CLOSE")
-            elseif msg[2] == "CLOSE" then
-                -- 主动断开mqtt client连接
-                mqtt_client:disconnect()
-                -- 发送disconnect之后,此处延时1秒,给数据发送预留一点儿时间,发送到服务器;
-                -- 即使1秒的时间不足以发送给服务器也没关系;对服务器来说,mqtt客户端只是没有优雅的断开,不影响什么实质功能;
-                sys.wait(1000)
-                break
-            
-            -- 被动关闭了mqtt连接
-            -- 被网络或者服务器断开了连接
-            elseif msg[2] == "DISCONNECTED" then
-                break
-            
-            -- 出现了其他异常
-            elseif msg[2] == "ERROR" then
-                break
-            end     
-        end
-
-        -- 出现异常    
-        ::EXCEPTION_PROC::
-
-        -- 清空此task绑定的消息队列中的未处理的消息
-        sysplus.cleanMsg(TASK_NAME)
-
-        -- 通知mqtts sender数据发送应用模块的task,MQTT连接已经断开
-        sysplus.sendMsg(mqtts_sender.TASK_NAME, "MQTT_EVENT", "DISCONNECTED")
-
-        -- 如果存在mqtt client对象
-        if mqtt_client then
-            -- 关闭mqtt client,并且释放mqtt client对象
-            mqtt_client:close()
-            mqtt_client = nil
-        end
-        
-        -- 5秒后跳转到循环体开始位置,自动发起重连
-        sys.wait(5000)
-    end
-end
-
---创建并且启动一个task
---运行这个task的处理函数mqtts_client_main_task_func
-sysplus.taskInitEx(mqtts_client_main_task_func, TASK_NAME)
-

+ 0 - 64
module/Air8000/demo/mqttv2/mqtts/mqtts_receiver.lua

@@ -1,64 +0,0 @@
---[[
-@module  mqtts_receiver
-@summary mqtts cient数据接收处理应用功能模块 
-@version 1.0
-@date    2025.07.29
-@author  朱天华
-@usage
-本文件为mqtts client 数据接收应用功能模块,核心业务逻辑为:
-处理接收到的publish数据,同时将数据发送给其他应用功能模块做进一步处理;
-
-本文件的对外接口有2个:
-1、mqtts_receiver.proc(topic, payload, metas):publish数据处理入口,在mqtts_main.lua中调用;
-2、sys.publish("RECV_DATA_FROM_SERVER", "recv from mqtt ssl server: ", topic, payload):
-   将接收到的publish中的topic和payload数据通过消息"RECV_DATA_FROM_SERVER"发布出去;
-   需要处理数据的应用功能模块订阅处理此消息即可,本demo项目中uart_app.lua中订阅处理了本消息;
-]]
-
-local mqtts_receiver = {}
-
-
-
---[[
-处理接收到的publish数据
-
-@api mqtts_receiver.proc(topic, payload, metas)
-
-@param1 topic string
-表示publish主题
-
-@param2 payload string
-表示publish数据负载
-
-@param2 payload string
-表示publish数据负载
-
-@param3 metas table
-表示publish报文的一些参数;格式如下:
-{
-    qos: number类型,取值范围0,1,2
-    retain:number类型,取值范围0,1
-    dup:number类型,取值范围0,1
-    message_id: number类型
-}
-
-@return1 result nil
-
-@usage
-
-mqtts_receiver.proc(topic, payload, metas)
-]]
-function mqtts_receiver.proc(topic, payload, metas)
-
-    log.info("mqtts_receiver.proc", topic, payload:len(), json.encode(metas))
-
-    -- 接收到数据,通知网络环境检测看门狗功能模块进行喂狗
-    sys.publish("FEED_NETWORK_WATCHDOG") 
-
-    -- 将topic和payload通过"RECV_DATA_FROM_SERVER"消息publish出去,给其他应用模块处理
-    sys.publish("RECV_DATA_FROM_SERVER", "recv from mqtt ssl server: ", topic, payload)
-
-    -- 也可以直接在此处编写代码,处理topic和payload   
-end
-
-return mqtts_receiver

+ 0 - 154
module/Air8000/demo/mqttv2/mqtts/mqtts_sender.lua

@@ -1,154 +0,0 @@
---[[
-@module  mqtts_sender
-@summary mqtts client数据发送应用功能模块 
-@version 1.0
-@date    2025.07.29
-@author  朱天华
-@usage
-本文件为mqtts client 数据发送应用功能模块,核心业务逻辑为:
-1、sys.subscribe("SEND_DATA_REQ", send_data_req_proc_func)订阅"SEND_DATA_REQ"消息,将其他应用模块需要发送的数据存储到队列send_queue中;
-2、mqtts sender task接收"CONNECT OK"、"PUBLISH_REQ"、"PUBLISH OK"三种类型的"MQTT_EVENT"消息,遍历队列send_queue,逐条发送数据到server;
-3、mqtts sender task接收"DISCONNECTED"类型的"MQTT_EVENT"消息,丢弃掉队列send_queue中未发送的数据;
-4、任何一条数据无论发送成功还是失败,只要这条数据有回调函数,都会通过回调函数通知数据发送方;
-
-本文件的对外接口有1个:
-1、sys.subscribe("SEND_DATA_REQ", send_data_req_proc_func):订阅"SEND_DATA_REQ"消息;
-   其他应用模块如果需要发送数据,直接sys.publish这个消息即可,将需要发送的topic,payload和qos以及回调函数和回调参数一起publish出去;
-   本demo项目中uart_app.lua和timer_app.lua中publish了这个消息;
-]]
-
-local mqtts_sender = {}
-
---[[
-数据发送队列,数据结构为:
-{
-    [1] = {topic="topic1", payload="payload1", qos=0, cb={func=callback_function1, para=callback_para1}},
-    [2] = {topic="topic2", payload="payload2", qos=1, cb={func=callback_function2, para=callback_para2}},
-    [3] = {topic="topic3", payload="payload3", qos=2, cb={func=callback_function3, para=callback_para3}},
-}
-topic的内容为publish的主题,string类型,必须存在;
-payload的内容为publish的负载数据,string类型,必须存在;
-qos的内容为publish的质量等级,number类型,取值范围0,1,2,可选,如果用户没有指定,默认为0;
-cb.func的内容为数据发送结果的用户回调函数,可以不存在;
-cb.para的内容为数据发送结果的用户回调函数的回调参数,可以不存在;
-]]
-local send_queue = {}
-
--- mqtts client的任务名前缀
-mqtts_sender.TASK_NAME_PREFIX = "mqtts_"
-
--- mqtts_client_sender的任务名
-mqtts_sender.TASK_NAME = mqtts_sender.TASK_NAME_PREFIX.."sender"
-
--- "SEND_DATA_REQ"消息的处理函数
-local function send_data_req_proc_func(tag, topic, payload, qos, cb)
-    -- 将原始数据增加前缀,然后插入到发送队列send_queue中
-    table.insert(send_queue, {topic=topic, payload="send from "..tag..": "..payload, qos=qos or 0, cb=cb})
-    -- 发送消息通知 mqtts sender task,有新数据等待发送
-    sysplus.sendMsg(mqtts_sender.TASK_NAME, "MQTT_EVENT", "PUBLISH_REQ")
-end
-
--- 按照顺序发送send_queue中的数据
--- 如果调用publish接口成功,则返回当前正在发送的数据项
--- 如果调用publish接口失败,通知回调函数发送失败后,继续发送下一条数据
-local function publish_item(mqtt_client)
-    local item
-    -- 如果发送队列中有数据等待发送
-    while #send_queue>0 do
-        -- 取出来第一条数据赋值给item
-        -- 同时从队列send_queue中删除这一条数据
-        item = table.remove(send_queue, 1)
-
-        -- publish数据
-        -- result表示调用publish接口的同步结果,返回值有以下几种:
-        -- 如果失败,返回nil
-        -- 如果成功,number类型,qos为0时直接返回0;qos为1或者2时返回publish报文的message id
-        result = mqtt_client:publish(item.topic, item.payload, item.qos)
-
-        -- publish接口调用成功
-        if result then
-            return item
-        -- publish接口调用失败
-        else
-            -- 如果当前发送的数据有用户回调函数,则执行用户回调函数
-            if item.cb and item.cb.func then
-                item.cb.func(false, item.cb.para)
-            end
-        end
-    end
-end
-
-
-local function publish_item_cbfunc(item, result)
-    if item then
-        -- 如果当前发送的数据有用户回调函数,则执行用户回调函数
-        if item.cb and item.cb.func then
-            item.cb.func(result, item.cb.para)
-        end
-    end
-end
-
--- mqtts client sender的任务处理函数
-local function mqtts_client_sender_task_func() 
-
-    local mqtt_client
-    local send_item
-    local result, msg
-
-    while true do
-        -- 等待"MQTT_EVENT"消息
-        msg = sysplus.waitMsg(mqtts_sender.TASK_NAME, "MQTT_EVENT")
-
-        -- mqtt连接成功
-        -- msg[3]表示mqtt client对象
-        if msg[2] == "CONNECT_OK" then
-            mqtt_client = msg[3]
-            -- 发送send_queue中的数据
-            send_item = publish_item(mqtt_client)
-        -- mqtt publish数据请求
-        elseif msg[2] == "PUBLISH_REQ" then
-            -- 如果mqtt client对象存在,并且没有正在等待发送结果的发送数据项
-            if mqtt_client and not send_item then
-                -- 发送send_queue中的数据
-                send_item = publish_item(mqtt_client)
-            end
-        -- mqtt publish数据成功
-        elseif msg[2] == "PUBLISH_OK" then
-            -- publish成功,执行回调函数通知发送方
-            publish_item_cbfunc(send_item, true)
-            -- publish成功,通知网络环境检测看门狗功能模块进行喂狗
-            sys.publish("FEED_NETWORK_WATCHDOG")
-            -- 发送send_queue中的数据
-            send_item = publish_item(mqtt_client)
-        -- mqtt断开连接
-        elseif msg[2] == "DISCONNECTED" then
-            -- 清空mqtt client对象
-            mqtt_client = nil
-            -- 如果存在正在等待发送结果的发送项,执行回调函数通知发送方失败
-            publish_item_cbfunc(send_item, false)
-            -- 如果发送队列中有数据等待发送
-            while #send_queue>0 do
-                -- 取出来第一条数据赋值给send_item
-                -- 同时从队列send_queue中删除这一条数据
-                send_item = table.remove(send_queue,1)
-                -- 执行回调函数通知发送方失败
-                publish_item_cbfunc(send_item, false)
-            end
-            -- 当前没有正在等待发送结果的发送项
-            send_item = nil
-        end
-    end
-end
-
-
--- 订阅"SEND_DATA_REQ"消息;
--- 其他应用模块如果需要发送数据,直接sys.publish这个消息即可,将需要发送的数据以及回调函数和回调参数一起publish出去;
--- 本demo项目中uart_app.lua和timer_app.lua中publish了这个消息;
-sys.subscribe("SEND_DATA_REQ", send_data_req_proc_func)
-
-
---创建并且启动一个task
---运行这个task的处理函数mqtts_client_sender_task_func
-sysplus.taskInitEx(mqtts_client_sender_task_func, mqtts_sender.TASK_NAME)
-
-return mqtts_sender

+ 0 - 20
module/Air8000/demo/mqttv2/mqtts_ca/airlbs_parent_ca.crt

@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDUTCCAjmgAwIBAgIJAPPYCjTmxdt/MA0GCSqGSIb3DQEBCwUAMD8xCzAJBgNV
-BAYTAkNOMREwDwYDVQQIDAhoYW5nemhvdTEMMAoGA1UECgwDRU1RMQ8wDQYDVQQD
-DAZSb290Q0EwHhcNMjAwNTA4MDgwNjUyWhcNMzAwNTA2MDgwNjUyWjA/MQswCQYD
-VQQGEwJDTjERMA8GA1UECAwIaGFuZ3pob3UxDDAKBgNVBAoMA0VNUTEPMA0GA1UE
-AwwGUm9vdENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzcgVLex1
-EZ9ON64EX8v+wcSjzOZpiEOsAOuSXOEN3wb8FKUxCdsGrsJYB7a5VM/Jot25Mod2
-juS3OBMg6r85k2TWjdxUoUs+HiUB/pP/ARaaW6VntpAEokpij/przWMPgJnBF3Ur
-MjtbLayH9hGmpQrI5c2vmHQ2reRZnSFbY+2b8SXZ+3lZZgz9+BaQYWdQWfaUWEHZ
-uDaNiViVO0OT8DRjCuiDp3yYDj3iLWbTA/gDL6Tf5XuHuEwcOQUrd+h0hyIphO8D
-tsrsHZ14j4AWYLk1CPA6pq1HIUvEl2rANx2lVUNv+nt64K/Mr3RnVQd9s8bK+TXQ
-KGHd2Lv/PALYuwIDAQABo1AwTjAdBgNVHQ4EFgQUGBmW+iDzxctWAWxmhgdlE8Pj
-EbQwHwYDVR0jBBgwFoAUGBmW+iDzxctWAWxmhgdlE8PjEbQwDAYDVR0TBAUwAwEB
-/zANBgkqhkiG9w0BAQsFAAOCAQEAGbhRUjpIred4cFAFJ7bbYD9hKu/yzWPWkMRa
-ErlCKHmuYsYk+5d16JQhJaFy6MGXfLgo3KV2itl0d+OWNH0U9ULXcglTxy6+njo5
-CFqdUBPwN1jxhzo9yteDMKF4+AHIxbvCAJa17qcwUKR5MKNvv09C6pvQDJLzid7y
-E2dkgSuggik3oa0427KvctFf8uhOV94RvEDyqvT5+pgNYZ2Yfga9pD/jjpoHEUlo
-88IGU8/wJCx3Ds2yc8+oBg/ynxG8f/HmCC1ET6EHHoe2jlo8FpU/SgGtghS1YL30
-IWxNsPrUP+XsZpBJy/mvOhE5QXo6Y35zDqqj8tI7AGmAWu22jg==
------END CERTIFICATE-----

+ 0 - 293
module/Air8000/demo/mqttv2/mqtts_ca/mqtts_ca_main.lua

@@ -1,293 +0,0 @@
---[[
-@module  mqtts_ca_main
-@summary mqtts ca client 主应用功能模块 
-@version 1.0
-@date    2025.07.28
-@author  朱天华
-@usage
-本文件为mqtts ca client 主应用功能模块,核心业务逻辑为:
-1、创建一个mqtts ca client,连接server;
-2、处理连接/订阅/取消订阅/异常逻辑,出现异常后执行重连动作;
-3、调用mqtts_ca_receiver的外部接口mqtts_ca_receiver.proc,对接收到的publish数据进行处理;
-4、调用sysplus.sendMsg接口,发送"CONNECT OK"、"PUBLISH OK"和"DISCONNECTED"三种类型的"MQTT_EVENT"消息到mqtts_ca_sender的task,控制publish数据发送逻辑;
-5、收到MQTT心跳应答后,执行sys.publish("FEED_NETWORK_WATCHDOG") 对网络环境检测看门狗功能模块进行喂狗;
-
-本文件没有对外接口,直接在main.lua中require "mqtts_ca_main"就可以加载运行;
-]]
-
--- 加载sntp时间同步应用功能模块(ca证书校验的mqtt ssl需要时间同步功能)
-require "sntp_app"
-
--- 加载mqtts ca client数据接收功能模块
-local mqtts_ca_receiver = require "mqtts_ca_receiver"
--- 加载mqtts ca client数据发送功能模块
-local mqtts_ca_sender = require "mqtts_ca_sender"
-
--- mqtts ca服务器地址和端口
--- 这里使用的地址和端口,仅能用作测试用途,不可商用,说不定哪一天就关闭了
--- 用户开发项目时,替换为自己的商用服务器地址和端口
-local SERVER_ADDR = "airlbs.openluat.com"
-local SERVER_PORT = 8883
-
--- mqtts_ca_main的任务名
-local TASK_NAME = mqtts_ca_sender.TASK_NAME_PREFIX.."main"
-
--- mqtt主题的前缀:IMEI号
-local TOPIC_PREFIX = mobile.imei()
-
--- mqtts ca client的事件回调函数
-local function mqtts_ca_client_event_cbfunc(mqtt_client, event, data, payload, metas)
-    log.info("mqtts_ca_client_event_cbfunc", mqtt_client, event, data, payload, json.encode(metas))
-
-    -- mqtt连接成功
-    if event == "conack" then
-        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "CONNECT", true)
-        -- 订阅单主题
-        -- 第二个参数表示qos,取值范围为0,1,2,如果不设置,默认为0
-        if not mqtt_client:subscribe(TOPIC_PREFIX .. "/down") then
-            sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "SUBSCRIBE", false, -1)
-        end
-        -- 订阅多主题,如果有需要,打开注释
-        -- 表中的每一个订阅主题的格式为[topic]=qos
-        -- if not mqtt_client:subscribe(
-        --         {
-        --             [(TOPIC_PREFIX .. "/data"]=0,
-        --             [(TOPIC_PREFIX .. "/cmd"]=1
-        --         }
-        -- ) then
-        --     sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "SUBSCRIBE", false, -1)
-        -- end
-
-    -- 订阅结果
-    -- data:订阅应答结果,true为成功,false为失败
-    -- payload:number类型;成功时表示qos,取值范围为0,1,2;失败时表示失败码,一般是0x80
-    elseif event == "suback" then
-        -- 发送消息通知 mqtts ca main task
-        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "SUBSCRIBE", data, payload)
-        
-    -- 取消订阅成功
-    elseif event == "unsuback" then
-        -- 发送消息通知 mqtts ca main task
-        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "UNSUBSCRIBE", true)
-
-    -- 接收到服务器下发的publish数据
-    -- data:string类型,表示topic
-    -- payload:string类型,表示payload
-    -- metas:table类型,数据内容如下
-    -- {
-    --     qos: number类型,取值范围0,1,2
-    --     retain:number类型,取值范围0,1
-    --     dup:number类型,取值范围0,1
-    --     message_id: number类型
-    -- }
-    elseif event == "recv" then
-        -- 对接收到的publish数据处理
-        mqtts_ca_receiver.proc(data, payload, metas)
-
-    -- 发送成功publish数据
-    -- data:number类型,表示message id
-    elseif event == "sent" then
-        -- 发送消息通知 mqtts ca sender task
-        sysplus.sendMsg(mqtts_ca_sender.TASK_NAME, "MQTT_EVENT", "PUBLISH_OK", data)
-
-    -- 服务器断开mqtt连接
-    elseif event == "disconnect" then
-        -- 发送消息通知 mqtts ca main task
-        sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "DISCONNECTED", false)
-
-    -- 收到服务器的心跳应答
-    elseif event == "pong" then
-        -- 接收到数据,通知网络环境检测看门狗功能模块进行喂狗
-        sys.publish("FEED_NETWORK_WATCHDOG") 
-	
-    -- 严重异常,本地会主动断开连接
-    -- data:string类型,表示具体的异常,有以下几种:
-    --       "connect":tcp连接失败
-    --       "tx":数据发送失败
-    --       "conack":mqtt connect后,服务器应答CONNACK鉴权失败,失败码为payload(number类型)
-    --       "other":其他异常
-    elseif event == "error" then
-        if data == "connect" or data == "conack" then
-            -- 发送消息通知 mqtts ca main task,连接失败
-            sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "CONNECT", false)
-        elseif data == "other" or data == "tx" then
-            -- 发送消息通知 mqtts ca main task,出现异常
-            sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "ERROR")
-        end
-    end
-end
-
--- mqtts ca main task 的任务处理函数
-local function mqtts_ca_client_main_task_func() 
-
-    local mqtt_client
-    local result, msg, para
-
-    -- 用来验证server证书是否合法的ca证书文件为airlbs_parent_ca.crt
-    -- 此ca证书的有效期截止到2030年5月6日
-    -- 将这个ca证书文件的内容读取出来,赋值给server_ca_cert
-    -- 注意:此处的ca证书文件仅用来验证airlbs.openluat.com:8883端口的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/airlbs_parent_ca.crt")
-
-    while true do
-        -- 如果当前时间点设置的默认网卡还没有连接成功,一直在这里循环等待
-        while not socket.adapter(socket.dft()) do
-            log.warn("mqtts_ca_client_main_task_func", "wait IP_READY", socket.dft())
-            -- 在此处阻塞等待默认网卡连接成功的消息"IP_READY"
-            -- 或者等待1秒超时退出阻塞等待状态;
-            -- 注意:此处的1000毫秒超时不要修改的更长;
-            -- 因为当使用exnetif.set_priority_order配置多个网卡连接外网的优先级时,会隐式的修改默认使用的网卡
-            -- 当exnetif.set_priority_order的调用时序和此处的socket.adapter(socket.dft())判断时序有可能不匹配
-            -- 此处的1秒,能够保证,即使时序不匹配,也能1秒钟退出阻塞状态,再去判断socket.adapter(socket.dft())
-            sys.waitUntil("IP_READY", 1000)
-        end
-
-        -- 检测到了IP_READY消息
-        log.info("mqtts_ca_client_main_task_func", "recv IP_READY", socket.dft())
-
-        -- 清空此task绑定的消息队列中的未处理的消息
-        sysplus.cleanMsg(TASK_NAME)
-
-        -- 创建mqtt client对象,ssl连接,单向证书校验
-        -- client仅单向校验server的证书,server不校验client的证书和密钥文件
-        -- 如果做证书校验,需要特别注意以下几点:
-        -- 1、证书校验前,设备端必须同步为正确的时间,因为校验过程中会检查ca证书以及server证书中的有效期是否合法;本demo中的sntp_app.lua会同步时间;
-        -- 2、任何证书都有有效期,无论是ca证书还是server证书,必须在有效期截止之前,及时更换证书,延长有效期,否则证书校验会失败;
-        -- 3、如果要更换ca证书,需要在设备端远程升级,必须保证ca证书失效之前升级成功,否则校验失败,就无法连接server;
-        -- 综上所述,证书校验虽然安全,可以验证身份,但是后续维护成本比较高;除非有需要,否则可以不配置证书校验功能;
-        -- 另外,如果使用https://netlab.luatos.com/创建的TCP SSL Server,使用的server证书有可能过了有效期;
-        -- 如果过了有效期,使用本文件无法连接成功tcp ssl ca server,遇到这种问题,可以在main.lua中打开socket.sslLog(3),观察Luatools的日志,如果出现类似于下面的日志
-        -- expires on        : 2020-12-27 15:46:55
-        -- 表示证书有效期截止到2020-12-27 15:46:55,明显就是证书已经过了有效期
-        -- 遇到这种情况,可以反馈给合宙的技术人员;或者不再使用netlab server测试,使用你自己的tcp ssl server来测试,只要保证你的server证书合法就行
-        mqtt_client = mqtt.create(nil, SERVER_ADDR, SERVER_PORT, {server_cert = server_ca_cert})
-        -- 如果创建mqtt client对象失败
-        if not mqtt_client then
-            log.error("mqtts_ca_client_main_task_func", "mqtt.create error")
-            goto EXCEPTION_PROC
-        end
-
-        -- 配置mqtt client对象的client id,username,password和clean session标志
-        result = mqtt_client:auth(mobile.imei(), "", "", true)
-        -- 如果配置失败
-        if not result then
-            log.error("mqtts_ca_client_main_task_func", "mqtt_client:auth error")
-            goto EXCEPTION_PROC
-        end
-
-        -- 注册mqtt client对象的事件回调函数
-        mqtt_client:on(mqtts_ca_client_event_cbfunc)
-
-        -- 设置mqtt keepalive时间为120秒
-        -- 如果没有设置,内核固件中默认为180秒
-        -- 有需要的话,可以打开注释
-        -- mqtt_client:keepalive(120)
-
-        -- 设置遗嘱消息,有需要的话,可以打开注释
-        -- mqtt_client:will(TOPIC_PREFIX .. "/status", "offline")
-
-        -- 配置开启debug信息,有需要的话,可以打开注释
-        -- mqtt_client:debug(true)
-        -- socket.sslLog(3)
-
-        -- 连接server
-        result = mqtt_client:connect()
-        -- 如果连接server失败
-        if not result then
-            log.error("mqtts_ca_client_main_task_func", "mqtt_client:connect error")
-            goto EXCEPTION_PROC
-        end
-
-
-        -- 连接、断开连接、订阅、取消订阅、异常等各种事件的处理调度逻辑
-        while true do
-            -- 等待"MQTT_EVENT"消息
-            msg = sysplus.waitMsg(TASK_NAME, "MQTT_EVENT")
-            log.info("mqtts_ca_client_main_task_func waitMsg", msg[2], msg[3], msg[4])
-
-            -- connect连接结果
-            -- msg[3]表示连接结果,true为连接成功,false为连接失败
-            if msg[2] == "CONNECT" then                
-                -- mqtt连接成功
-                if msg[3] then
-                    log.info("mqtts_ca_client_main_task_func", "connect success")
-                    -- 通知数据发送应用模块,MQTT连接成功
-                    sysplus.sendMsg(mqtts_ca_sender.TASK_NAME, "MQTT_EVENT", "CONNECT_OK", mqtt_client)
-                -- mqtt连接失败
-                else
-                    log.info("mqtts_ca_client_main_task_func", "connect error")
-                    -- 退出循环,发起重连
-                    break
-                end
-
-            -- subscribe订阅结果
-            -- msg[3]表示订阅结果,true为订阅成功,false为订阅失败
-            elseif msg[2] == "SUBSCRIBE" then
-                -- 订阅成功
-                if msg[3] then
-                    log.info("mqtts_ca_client_main_task_func", "subscribe success", "qos: "..(msg[4] or "nil"))
-                -- 订阅失败
-                else
-                    log.error("mqtts_ca_client_main_task_func", "subscribe error", "code", msg[4])
-                    -- 主动断开mqtt client连接
-                    mqtt_client:disconnect()
-                    -- 发送disconnect之后,此处延时1秒,给数据发送预留一点儿时间,发送到服务器;
-                    -- 即使1秒的时间不足以发送给服务器也没关系;对服务器来说,mqtt客户端只是没有优雅的断开,不影响什么实质功能;
-                    sys.wait(1000)
-                    break
-                end
-
-            -- unsubscribe取消订阅成功
-            elseif msg[2] == "UNSUBSCRIBE" then
-                log.info("mqtts_ca_client_main_task_func", "unsubscribe success")
-            
-            -- 需要主动关闭mqtt连接
-            -- 用户需要主动关闭mqtt连接时,可以调用sysplus.sendMsg(TASK_NAME, "MQTT_EVENT", "CLOSE")
-            elseif msg[2] == "CLOSE" then
-                -- 主动断开mqtt client连接
-                mqtt_client:disconnect()
-                -- 发送disconnect之后,此处延时1秒,给数据发送预留一点儿时间,发送到服务器;
-                -- 即使1秒的时间不足以发送给服务器也没关系;对服务器来说,mqtt客户端只是没有优雅的断开,不影响什么实质功能;
-                sys.wait(1000)
-                break
-            
-            -- 被动关闭了mqtt连接
-            -- 被网络或者服务器断开了连接
-            elseif msg[2] == "DISCONNECTED" then
-                break
-            
-            -- 出现了其他异常
-            elseif msg[2] == "ERROR" then
-                break
-            end     
-        end
-
-        -- 出现异常    
-        ::EXCEPTION_PROC::
-
-        -- 清空此task绑定的消息队列中的未处理的消息
-        sysplus.cleanMsg(TASK_NAME)
-
-        -- 通知mqtts ca sender数据发送应用模块的task,MQTT连接已经断开
-        sysplus.sendMsg(mqtts_ca_sender.TASK_NAME, "MQTT_EVENT", "DISCONNECTED")
-
-        -- 如果存在mqtt client对象
-        if mqtt_client then
-            -- 关闭mqtt client,并且释放mqtt client对象
-            mqtt_client:close()
-            mqtt_client = nil
-        end
-        
-        -- 5秒后跳转到循环体开始位置,自动发起重连
-        sys.wait(5000)
-    end
-end
-
---创建并且启动一个task
---运行这个task的处理函数mqtts_ca_client_main_task_func
-sysplus.taskInitEx(mqtts_ca_client_main_task_func, TASK_NAME)
-

+ 0 - 64
module/Air8000/demo/mqttv2/mqtts_ca/mqtts_ca_receiver.lua

@@ -1,64 +0,0 @@
---[[
-@module  mqtts_ca_receiver
-@summary mqtts ca cient数据接收处理应用功能模块 
-@version 1.0
-@date    2025.07.29
-@author  朱天华
-@usage
-本文件为mqtts ca client 数据接收应用功能模块,核心业务逻辑为:
-处理接收到的publish数据,同时将数据发送给其他应用功能模块做进一步处理;
-
-本文件的对外接口有2个:
-1、mqtts_ca_receiver.proc(topic, payload, metas):publish数据处理入口,在mqtts_ca_main.lua中调用;
-2、sys.publish("RECV_DATA_FROM_SERVER", "recv from mqtt ssl ca server: ", topic, payload):
-   将接收到的publish中的topic和payload数据通过消息"RECV_DATA_FROM_SERVER"发布出去;
-   需要处理数据的应用功能模块订阅处理此消息即可,本demo项目中uart_app.lua中订阅处理了本消息;
-]]
-
-local mqtts_ca_receiver = {}
-
-
-
---[[
-处理接收到的publish数据
-
-@api mqtts_ca_receiver.proc(topic, payload, metas)
-
-@param1 topic string
-表示publish主题
-
-@param2 payload string
-表示publish数据负载
-
-@param2 payload string
-表示publish数据负载
-
-@param3 metas table
-表示publish报文的一些参数;格式如下:
-{
-    qos: number类型,取值范围0,1,2
-    retain:number类型,取值范围0,1
-    dup:number类型,取值范围0,1
-    message_id: number类型
-}
-
-@return1 result nil
-
-@usage
-
-mqtts_ca_receiver.proc(topic, payload, metas)
-]]
-function mqtts_ca_receiver.proc(topic, payload, metas)
-
-    log.info("mqtts_ca_receiver.proc", topic, payload:len(), json.encode(metas))
-
-    -- 接收到数据,通知网络环境检测看门狗功能模块进行喂狗
-    sys.publish("FEED_NETWORK_WATCHDOG") 
-
-    -- 将topic和payload通过"RECV_DATA_FROM_SERVER"消息publish出去,给其他应用模块处理
-    sys.publish("RECV_DATA_FROM_SERVER", "recv from mqtt ssl ca server: ", topic, payload)
-
-    -- 也可以直接在此处编写代码,处理topic和payload   
-end
-
-return mqtts_ca_receiver

+ 0 - 154
module/Air8000/demo/mqttv2/mqtts_ca/mqtts_ca_sender.lua

@@ -1,154 +0,0 @@
---[[
-@module  mqttt_ca_sender
-@summary mqtts ca client数据发送应用功能模块 
-@version 1.0
-@date    2025.07.29
-@author  朱天华
-@usage
-本文件为mqtts ca client 数据发送应用功能模块,核心业务逻辑为:
-1、sys.subscribe("SEND_DATA_REQ", send_data_req_proc_func)订阅"SEND_DATA_REQ"消息,将其他应用模块需要发送的数据存储到队列send_queue中;
-2、mqtts ca sender task接收"CONNECT OK"、"PUBLISH_REQ"、"PUBLISH OK"三种类型的"MQTT_EVENT"消息,遍历队列send_queue,逐条发送数据到server;
-3、mqtts ca sender task接收"DISCONNECTED"类型的"MQTT_EVENT"消息,丢弃掉队列send_queue中未发送的数据;
-4、任何一条数据无论发送成功还是失败,只要这条数据有回调函数,都会通过回调函数通知数据发送方;
-
-本文件的对外接口有1个:
-1、sys.subscribe("SEND_DATA_REQ", send_data_req_proc_func):订阅"SEND_DATA_REQ"消息;
-   其他应用模块如果需要发送数据,直接sys.publish这个消息即可,将需要发送的topic,payload和qos以及回调函数和回调参数一起publish出去;
-   本demo项目中uart_app.lua和timer_app.lua中publish了这个消息;
-]]
-
-local mqtts_ca_sender = {}
-
---[[
-数据发送队列,数据结构为:
-{
-    [1] = {topic="topic1", payload="payload1", qos=0, cb={func=callback_function1, para=callback_para1}},
-    [2] = {topic="topic2", payload="payload2", qos=1, cb={func=callback_function2, para=callback_para2}},
-    [3] = {topic="topic3", payload="payload3", qos=2, cb={func=callback_function3, para=callback_para3}},
-}
-topic的内容为publish的主题,string类型,必须存在;
-payload的内容为publish的负载数据,string类型,必须存在;
-qos的内容为publish的质量等级,number类型,取值范围0,1,2,可选,如果用户没有指定,默认为0;
-cb.func的内容为数据发送结果的用户回调函数,可以不存在;
-cb.para的内容为数据发送结果的用户回调函数的回调参数,可以不存在;
-]]
-local send_queue = {}
-
--- mqtts ca client的任务名前缀
-mqtts_ca_sender.TASK_NAME_PREFIX = "mqtts_ca_"
-
--- mqtts_ca_client_sender的任务名
-mqtts_ca_sender.TASK_NAME = mqtts_ca_sender.TASK_NAME_PREFIX.."sender"
-
--- "SEND_DATA_REQ"消息的处理函数
-local function send_data_req_proc_func(tag, topic, payload, qos, cb)
-    -- 将原始数据增加前缀,然后插入到发送队列send_queue中
-    table.insert(send_queue, {topic=topic, payload="send from "..tag..": "..payload, qos=qos or 0, cb=cb})
-    -- 发送消息通知 mqtts ca sender task,有新数据等待发送
-    sysplus.sendMsg(mqtts_ca_sender.TASK_NAME, "MQTT_EVENT", "PUBLISH_REQ")
-end
-
--- 按照顺序发送send_queue中的数据
--- 如果调用publish接口成功,则返回当前正在发送的数据项
--- 如果调用publish接口失败,通知回调函数发送失败后,继续发送下一条数据
-local function publish_item(mqtt_client)
-    local item
-    -- 如果发送队列中有数据等待发送
-    while #send_queue>0 do
-        -- 取出来第一条数据赋值给item
-        -- 同时从队列send_queue中删除这一条数据
-        item = table.remove(send_queue, 1)
-
-        -- publish数据
-        -- result表示调用publish接口的同步结果,返回值有以下几种:
-        -- 如果失败,返回nil
-        -- 如果成功,number类型,qos为0时直接返回0;qos为1或者2时返回publish报文的message id
-        result = mqtt_client:publish(item.topic, item.payload, item.qos)
-
-        -- publish接口调用成功
-        if result then
-            return item
-        -- publish接口调用失败
-        else
-            -- 如果当前发送的数据有用户回调函数,则执行用户回调函数
-            if item.cb and item.cb.func then
-                item.cb.func(false, item.cb.para)
-            end
-        end
-    end
-end
-
-
-local function publish_item_cbfunc(item, result)
-    if item then
-        -- 如果当前发送的数据有用户回调函数,则执行用户回调函数
-        if item.cb and item.cb.func then
-            item.cb.func(result, item.cb.para)
-        end
-    end
-end
-
--- mqtts_ca client sender的任务处理函数
-local function mqtts_ca_client_sender_task_func() 
-
-    local mqtt_client
-    local send_item
-    local result, msg
-
-    while true do
-        -- 等待"MQTT_EVENT"消息
-        msg = sysplus.waitMsg(mqtts_ca_sender.TASK_NAME, "MQTT_EVENT")
-
-        -- mqtt连接成功
-        -- msg[3]表示mqtt client对象
-        if msg[2] == "CONNECT_OK" then
-            mqtt_client = msg[3]
-            -- 发送send_queue中的数据
-            send_item = publish_item(mqtt_client)
-        -- mqtt publish数据请求
-        elseif msg[2] == "PUBLISH_REQ" then
-            -- 如果mqtt client对象存在,并且没有正在等待发送结果的发送数据项
-            if mqtt_client and not send_item then
-                -- 发送send_queue中的数据
-                send_item = publish_item(mqtt_client)
-            end
-        -- mqtt publish数据成功
-        elseif msg[2] == "PUBLISH_OK" then
-            -- publish成功,执行回调函数通知发送方
-            publish_item_cbfunc(send_item, true)
-            -- publish成功,通知网络环境检测看门狗功能模块进行喂狗
-            sys.publish("FEED_NETWORK_WATCHDOG")
-            -- 发送send_queue中的数据
-            send_item = publish_item(mqtt_client)
-        -- mqtt断开连接
-        elseif msg[2] == "DISCONNECTED" then
-            -- 清空mqtt client对象
-            mqtt_client = nil
-            -- 如果存在正在等待发送结果的发送项,执行回调函数通知发送方失败
-            publish_item_cbfunc(send_item, false)
-            -- 如果发送队列中有数据等待发送
-            while #send_queue>0 do
-                -- 取出来第一条数据赋值给send_item
-                -- 同时从队列send_queue中删除这一条数据
-                send_item = table.remove(send_queue,1)
-                -- 执行回调函数通知发送方失败
-                publish_item_cbfunc(send_item, false)
-            end
-            -- 当前没有正在等待发送结果的发送项
-            send_item = nil
-        end
-    end
-end
-
-
--- 订阅"SEND_DATA_REQ"消息;
--- 其他应用模块如果需要发送数据,直接sys.publish这个消息即可,将需要发送的数据以及回调函数和回调参数一起publish出去;
--- 本demo项目中uart_app.lua和timer_app.lua中publish了这个消息;
-sys.subscribe("SEND_DATA_REQ", send_data_req_proc_func)
-
-
---创建并且启动一个task
---运行这个task的处理函数mqtts_ca_client_sender_task_func
-sysplus.taskInitEx(mqtts_ca_client_sender_task_func, mqtts_ca_sender.TASK_NAME)
-
-return mqtts_ca_sender

+ 0 - 66
module/Air8000/demo/mqttv2/mqtts_ca/sntp_app.lua

@@ -1,66 +0,0 @@
---[[
-@module  sntp_app
-@summary sntp时间同步应用功能模块 
-@version 1.0
-@date    2025.07.01
-@author  朱天华
-@usage
-本文件为sntp时间同步应用功能模块,核心业务逻辑为:
-1、连接ntp服务器进行时间同步;
-2、如果同步成功,1小时之后重新发起同步动作;
-3、如果同步失败,10秒钟之后重新发起同步动作;
-
-本文件没有对外接口,直接在其他应用功能模块中require "sntp_app"就可以加载运行;
-]]
-
--- sntp时间同步的任务处理函数
-local function sntp_task_func() 
-
-    while true do
-        -- 如果当前时间点设置的默认网卡还没有连接成功,一直在这里循环等待
-        while not socket.adapter(socket.dft()) do
-            log.warn("sntp_task_func", "wait IP_READY", socket.dft())
-            -- 在此处阻塞等待默认网卡连接成功的消息"IP_READY"
-            -- 或者等待1秒超时退出阻塞等待状态;
-            -- 注意:此处的1000毫秒超时不要修改的更长;
-            -- 因为当使用exnetif.set_priority_order配置多个网卡连接外网的优先级时,会隐式的修改默认使用的网卡
-            -- 当exnetif.set_priority_order的调用时序和此处的socket.adapter(socket.dft())判断时序有可能不匹配
-            -- 此处的1秒,能够保证,即使时序不匹配,也能1秒钟退出阻塞状态,再去判断socket.adapter(socket.dft())
-            sys.waitUntil("IP_READY", 1000)
-        end
-
-        -- 检测到了IP_READY消息
-        log.warn("sntp_task_func", "recv IP_READY")
-
-        -- 发起ntp时间同步动作
-        socket.sntp()
-
-        -- 等待ntp时间同步结果,30秒超时失败,通常只需要几百毫秒就能成功
-        local ret = sys.waitUntil("NTP_UPDATE", 30000)
-
-        --同步成功
-        if ret then
-            -- 以下是获取/打印时间的演示,注意时区问题
-            log.info("sntp_task_func", "时间同步成功", "本地时间", os.date())
-            log.info("sntp_task_func", "时间同步成功", "UTC时间", os.date("!%c"))
-            log.info("sntp_task_func", "时间同步成功", "RTC时钟(UTC时间)", json.encode(rtc.get()))
-            log.info("sntp_task_func", "时间同步成功", "本地时间戳", os.time())
-            local t = os.date("*t")
-            log.info("sntp_task_func", "时间同步成功", "本地时间os.date() json格式", json.encode(t))
-            log.info("sntp_task_func", "时间同步成功", "本地时间os.date(os.time())", os.time(t))
-
-            -- 正常使用, 一小时一次, 已经足够了, 甚至1天一次也可以
-            sys.wait(3600000) 
-        --同步失败
-        else
-            log.info("sntp_task_func", "时间同步失败")
-            -- 10秒后重新发起同步动作
-            sys.wait(10000) 
-        end
-    end
-end
-
---创建并且启动一个task
---运行这个task的主函数sntp_task_func
-sys.taskInit(sntp_task_func)
-

+ 0 - 33
module/Air8000/demo/mqttv2/netdrv/netdrv_4g.lua

@@ -1,33 +0,0 @@
---[[
-@module  netdrv_4g
-@summary “4G网卡”驱动模块 
-@version 1.0
-@date    2025.07.01
-@author  朱天华
-@usage
-本文件为4G网卡驱动模块,核心业务逻辑为:
-1、监听"IP_READY"和"IP_LOSE",在日志中进行打印;
-
-本文件没有对外接口,直接在其他功能模块中require "netdrv_4g"就可以加载运行;
-]]
-
-local function ip_ready_func()
-    log.info("netdrv_4g.ip_ready_func", "IP_READY", socket.localIP(socket.LWIP_GP))
-end
-
-local function ip_lose_func()
-    log.warn("netdrv_4g.ip_lose_func", "IP_LOSE")
-end
-
-
-
---此处订阅"IP_READY"和"IP_LOSE"两种消息
---在消息的处理函数中,仅仅打印了一些信息,便于实时观察4G网络的连接状态
---也可以根据自己的项目需求,在消息处理函数中增加自己的业务逻辑控制,例如可以在连网状态发生改变时更新网络图标
-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)

+ 0 - 85
module/Air8000/demo/mqttv2/netdrv/netdrv_eth_spi.lua

@@ -1,85 +0,0 @@
---[[
-@module  netdrv_eth_spi
-@summary “通过SPI外挂CH390H芯片的以太网卡”驱动模块 
-@version 1.0
-@date    2025.07.24
-@author  朱天华
-@usage
-本文件为“通过SPI外挂CH390H芯片的以太网卡”驱动模块 ,核心业务逻辑为:
-1、打开CH390H芯片供电开关;
-2、初始化spi1,初始化以太网卡,并且在以太网卡上开启DHCP(动态主机配置协议);
-3、以太网卡的连接状态发生变化时,在日志中进行打印;
-
-直接使用Air8000开发板硬件测试即可;
-
-本文件没有对外接口,直接在其他功能模块中require "netdrv_eth_spi"就可以加载运行;
-]]
-
-local function ip_ready_func()
-    log.info("netdrv_eth_spi.ip_ready_func", "IP_READY", socket.localIP(socket.LWIP_ETH))
-end
-
-local function ip_lose_func()
-    log.warn("netdrv_eth_spi.ip_lose_func", "IP_LOSE")
-end
-
-
-
---此处订阅"IP_READY"和"IP_LOSE"两种消息
---在消息的处理函数中,仅仅打印了一些信息,便于实时观察“通过SPI外挂CH390H芯片的以太网卡”的连接状态
---也可以根据自己的项目需求,在消息处理函数中增加自己的业务逻辑控制,例如可以在连网状态发生改变时更新网络图标
-sys.subscribe("IP_READY", ip_ready_func)
-sys.subscribe("IP_LOSE", ip_lose_func)
-
-
--- 设置默认网卡为socket.LWIP_ETH
-socket.dft(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)

+ 0 - 95
module/Air8000/demo/mqttv2/netdrv/netdrv_multiple.lua

@@ -1,95 +0,0 @@
---[[
-@module  netdrv_multiple
-@summary 多网卡(4G网卡、WIFI STA网卡、通过SPI外挂CH390H芯片的以太网卡)驱动模块 
-@version 1.0
-@date    2025.07.24
-@author  朱天华
-@usage
-本文件为多网卡驱动模块 ,核心业务逻辑为:
-1、调用exnetif.set_priority_order配置多网卡的控制参数以及优先级;
-
-直接使用Air8000开发板硬件测试即可;
-
-本文件没有对外接口,直接在其他功能模块中require "netdrv_multiple"就可以加载运行;
-]]
-
-
-local exnetif = require "exnetif"
-
--- 网卡状态变化通知回调函数
--- 当exnetif中检测到网卡切换或者所有网卡都断网时,会触发调用此回调函数
--- 当网卡切换切换时:
---     net_type:string类型,表示当前使用的网卡字符串
---     adapter:number类型,表示当前使用的网卡id
--- 当所有网卡断网时:
---     net_type:为nil
---     adapter:number类型,为-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
-
-local function netdrv_multiple_task_func()
-    --设置网卡优先级
-    exnetif.set_priority_order(
-        {
-            -- “通过SPI外挂CH390H芯片”的以太网卡,使用Air8000开发板验证
-            {
-                ETHERNET = {
-                    -- 供电使能GPIO
-                    pwrpin = 140,
-                    -- 设置的多个“已经IP READY,但是还没有ping通”网卡,循环执行ping动作的间隔(单位毫秒,可选)
-                    -- 如果没有传入此参数,exnetif会使用默认值10秒
-                    ping_time = 3000,
-
-                    -- 连通性检测ip(选填参数);
-                    -- 如果没有传入ip地址,exnetif中会默认使用httpdns能否成功获取baidu.com的ip作为是否连通的判断条件;
-                    -- 如果传入,一定要传入可靠的并且可以ping通的ip地址;
-                    -- ping_ip = "填入可靠的并且可以ping通的ip地址",     
-                    
-                    -- 网卡芯片型号(选填参数),仅spi方式外挂以太网时需要填写。
-                    tp = netdrv.CH390, 
-                    opts = {spi=1, cs=12}
-                }
-            },
-
-            -- WIFI STA网卡
-            {
-                WIFI = {
-                    -- 要连接的WIFI路由器名称
-                    ssid = "茶室-降功耗,找合宙!",
-                    -- 要连接的WIFI路由器密码
-                    password = "Air123456", 
-
-                    -- 连通性检测ip(选填参数);
-                    -- 如果没有传入ip地址,exnetif中会默认使用httpdns能否成功获取baidu.com的ip作为是否连通的判断条件;
-                    -- 如果传入,一定要传入可靠的并且可以ping通的ip地址;
-                    -- ping_ip = "填入可靠的并且可以ping通的ip地址",
-                }
-            },
-
-            -- 4G网卡
-            {
-                LWIP_GP = true
-            }
-        }
-    )    
-end
-
--- 设置网卡状态变化通知回调函数netdrv_multiple_notify_cbfunc
-exnetif.notify_status(netdrv_multiple_notify_cbfunc)
-
--- 如果存在udp网络应用,并且udp网络应用中,根据应用层的心跳能够判断出来udp数据通信出现了异常;
--- 可以在判断出现异常的位置,调用一次exnetif.check_network_status()接口,强制对当前正式使用的网卡进行一次连通性检测;
--- 如果存在tcp网络应用,不需要用户调用exnetif.check_network_status()接口去控制,exnetif会在tcp网络应用通信异常时自动对当前使用的网卡进行连通性检测。
-
-
--- 启动一个task,task的处理函数为netdrv_multiple_task_func
--- 在处理函数中调用exnetif.set_priority_order设置网卡优先级
--- 因为exnetif.set_priority_order要求必须在task中被调用,所以此处启动一个task
-sys.taskInit(netdrv_multiple_task_func)

+ 0 - 50
module/Air8000/demo/mqttv2/netdrv/netdrv_wifi.lua

@@ -1,50 +0,0 @@
---[[
-@module  netdrv_wifi
-@summary “WIFI STA网卡”驱动模块 
-@version 1.0
-@date    2025.07.01
-@author  朱天华
-@usage
-本文件为WIFI STA网卡驱动模块,核心业务逻辑为:
-1、初始化WIFI网络;
-2、连接WIFI路由器;
-3、和WIFI路由器之间的连接状态发生变化时,在日志中进行打印;
-
-本文件没有对外接口,直接在其他功能模块中require "netdrv_wifi"就可以加载运行;
-]]
-
-local function ip_ready_func()
-    log.info("netdrv_wifi.ip_ready_func", "IP_READY", json.encode(wlan.getInfo()))
-end
-
-local function ip_lose_func()
-    log.warn("netdrv_wifi.ip_lose_func", "IP_LOSE")
-end
-
-
-
---此处订阅"IP_READY"和"IP_LOSE"两种消息
---在消息的处理函数中,仅仅打印了一些信息,便于实时观察WIFI的连接状态
---也可以根据自己的项目需求,在消息处理函数中增加自己的业务逻辑控制,例如可以在连网状态发生改变时更新网络图标
-sys.subscribe("IP_READY", ip_ready_func)
-sys.subscribe("IP_LOSE", ip_lose_func)
-
-
--- 设置默认网卡为socket.LWIP_STA
-socket.dft(socket.LWIP_STA)
-
-
-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断网后,内核固件会产生一个"IP_LOSE"消息
---各个功能模块可以订阅"IP_LOSE"消息实时处理WIFI断网的事件
---也可以在任何时刻调用socket.adapter(socket.LWIP_STA)来获取WIFI网络是否连接成功

+ 0 - 33
module/Air8000/demo/mqttv2/netdrv_device.lua

@@ -1,33 +0,0 @@
---[[
-@module  netdrv_device
-@summary 网络驱动设备功能模块 
-@version 1.0
-@date    2025.07.24
-@author  朱天华
-@usage
-本文件为网络驱动设备功能模块,核心业务逻辑为:根据项目需求,选择并且配置合适的网卡(网络适配器)
-1、netdrv_4g:socket.LWIP_GP,4G网卡;
-2、netdrv_wifi:socket.LWIP_STA,WIFI STA网卡;
-3、netdrv_ethernet_spi:socket.LWIP_USER1,通过SPI外挂CH390H芯片的以太网卡;
-4、netdrv_multiple:可以配置多种网卡的优先级,按照优先级配置,使用其中一种网卡连接外网;
-
-根据自己的项目需求,只需要require以上四种中的一种即可;
-
-
-本文件没有对外接口,直接在main.lua中require "netdrv_device"就可以加载运行;
-]]
-
-
--- 根据自己的项目需求,只需要require以下四种中的一种即可;
-
--- 加载“4G网卡”驱动模块
-require "netdrv_4g"
-
--- 加载“WIFI STA网卡”驱动模块
--- require "netdrv_wifi"
-
--- 加载“通过SPI外挂CH390H芯片的以太网卡”驱动模块
--- require "netdrv_eth_spi"
-
--- 加载“可以配置优先级的多种网卡”驱动模块
--- require "netdrv_multiple"

+ 0 - 64
module/Air8000/demo/mqttv2/network_watchdog.lua

@@ -1,64 +0,0 @@
---[[
-@module  network_watchdog
-@summary 网络环境检测看门狗功能模块 
-@version 1.0
-@date    2025.07.23
-@author  朱天华
-@usage
-本文件为网络环境检测看门狗功能模块,监控网络环境是否工作正常(设备和服务器双向通信正常,或者至少单向通信正常),核心业务逻辑为:
-1、启动一个网络环境检测看门狗task,等待其他mqtt网络应用功能模块来喂狗,如果喂狗超时,则控制软件重启;
-2、如何确定“喂狗超时时间”,一般来说,有以下几个原则;
-   (1) 先确定一个最小基准值T1,2分钟或者5分钟或者10分钟,这个取值取决于具体项目需求,但是不能太短,因为开机后,在网络环境不太好的地方,网络初始化可能需要比较长的时间,一般推荐这个值不能小于2分钟;
-   (2) 再确定一个和产品业务逻辑有关的一个值T2,这个值和产品的应用业务逻辑息息相关,假设你的产品业务中:
-       <1> 服务器会定时下发数据给设备,例如设备连接上业务服务器之后,每隔3分钟,设备都会给服务器发送一次心跳,然后服务器都会立即回复一个心跳应答包;
-           这种情况下,可以取3分钟的大于等于1的倍数(例如1倍,1.5倍,2倍等等)+一段时间(例如10秒钟,如果前面是1倍,则此处必须加一段时间,给网络数据传输过程留够充足的时间);
-       <2> mqtt本身有keep alive的心跳机制,例如设备连接上业务服务器之后,默认每隔2分钟,设备都会给服务器发送一次心跳,服务器也会回复一个心跳应答数据;
-           这种情况下,可以取2分钟的大于等于1的倍数(例如1倍,1.5倍,2倍等等)+一段时间(例如10秒钟,如果前面是1倍,则此处必须加一段时间,给网络数据传输过程留够充足的时间);
-    (3) 取T1和T2的最大值,就是“喂狗超时时间”
-3、其他mqtt网络业务功能模块的喂狗时机,和上面2.2的描述相对应,一般来说,可以在以下几种时间点执行喂狗动作:
-   (1) 设备收到服务器下发的数据时
-   (2) 设备收到服务器回复的mqtt心跳应答数据时
-4、最重要的一点是:以上所说的原则,仅仅是建议,要根据自己的实际项目业务逻辑以及自己的需求最终确定看门狗方案
-
-5、具体到本demo
-   (1) 产品业务逻辑为:
-       <1> 创建了一个mqtt连接,设备每隔5秒钟发送一次数据到服务器,服务器何时下发应用数据给设备不确定;
-       <2> 创建了一个mqtt ssl、不需要证书校验的连接,设备每隔5秒钟发送一次数据到服务器,服务器何时下发应用数据给设备不确定;
-       <3> 创建了一个mqtt ssl、client单向校验server证书的连接,设备每隔5秒钟发送一次数据到服务器,服务器何时下发应用数据给设备不确定;
-       <4> 每隔3分钟,这三路mqtt连接都会发送一次mqtt心跳给server,server收到心跳后回复心跳应答给client;
-   (2) 确定喂狗超时时间:
-       <1> 本demo支持单WIFI、单以太网、单4G网络连接外网,网络环境准备就绪预留2分钟的时间已经足够,所以最小基准值T1取值2分钟;
-       <2> 本demo中存在3路mqtt连接,但是这3路mqtt连接都没有定时或者至少一段时间,服务器下发应用数据给设备,所以无法基于服务器下发应用数据的业务逻辑来确定T2的值;
-       <3> 本demo中存在3路mqtt连接,每1路mqtt连接,设备都是3分钟发送一次mqtt心跳数据给服务器,服务器收到后会立即回复一个mqtt心跳应答数据给设备;
-           所以可以通过3分钟的大于等于1的倍数(例如1倍,1.5倍,2倍等等)+一段时间(例如10秒钟,如果前面是1倍,则此处必须加一段时间,给网络数据传输过程留够充足的时间)来确定T2的值;
-           在这个demo中,我能接受的网络连续异常时长是5分钟,所以,T2取值5分钟;
-       <4> 取T1 2分钟和T2 5分钟的最大值,最终的喂狗超时时间就是5分钟;
-   (3) 确定喂狗时机:
-       <1> 3路mqtt连接中,任何1路收到服务器的下发的应用数据时;       
-       <2> 3路mqtt连接中,任何1路收到服务器的回复的心跳应答数据时;
-6、本demo设计的网络环境检测看门狗功能模块,可以检测以下两种种的任意一种网络环境异常:
-   (1) 网络环境连续超过5分钟没有准备就绪   
-   (2) mqtt、mqtt ssl、mqtt ssl单向校验证书3路连接中,连续5分钟没有收到服务器下发的应用数据或者服务器回复的心跳应答数据; 
-      
-
-本文件没有对外接口,直接在main.lua中require "network_watchdog"就可以加载运行;
-外部功能模块喂狗时,直接调用sys.publish("FEED_NETWORK_WATCHDOG")
-]]
-
--- 网络环境检测看门狗task处理函数
-local function network_watchdog_task_func()
-    while true do
-        --如果等待180秒没有等到"FEED_NETWORK_WATCHDOG"消息,则看门狗超时
-        if not sys.waitUntil("FEED_NETWORK_WATCHDOG", 300000) then            
-            log.error("network_watchdog_task_func timeout")
-            -- 等待3秒钟,然后软件重启
-            sys.wait(3000)
-            rtos.reboot()
-        end
-    end
-end
-
---创建并且启动一个task
---运行这个task的处理函数network_watchdog_task_func
-sys.taskInit(network_watchdog_task_func)
-

+ 0 - 144
module/Air8000/demo/mqttv2/readme.md

@@ -1,144 +0,0 @@
-## 功能模块介绍
-
-1、main.lua:主程序入口;
-
-2、netdrv_device.lua:网卡驱动设备,可以配置使用netdrv文件夹内的四种网卡(单4g网卡,单wifi网卡,单spi以太网卡,多网卡)中的任何一种网卡;
-
-3、mqtt文件夹:mqtt client连接以及数据收发处理逻辑;
-
-4、mqtts文件夹:mqtt ss client(不支持证书校验)连接以及数据收发处理逻辑;
-
-5、mqtts_ca文件夹:mqtt ss client(仅单向校验server端证书)连接以及数据收发处理逻辑;
-
-6、network_watchdog.lua:网络环境检测看门狗;
-
-7、timer_app.lua:通知三个mqtt client定时发送数据到服务器;
-
-8、uart_app.lua:在三个mqtt client和uart外设之间透传数据;
-
-
-
-## 系统消息介绍
-
-1、"IP_READY":某种网卡已经获取到ip信息,仅仅获取到了ip信息,能否和外网连通还不确认;
-
-2、"IP_LOSE":某种网卡已经掉网;
-
-
-
-## 用户消息介绍
-
-1、"RECV_DATA_FROM_SERVER":mqtt client收到服务器下发的publish数据后,通过此消息发布出去,给其他应用模块(uart_app)处理;
-
-2、"SEND_DATA_REQ":其他应用模块(uart_app,timer_app)发布此消息,通知mqtt client发送publish数据给服务器;
-
-3、"FEED_NETWORK_WATCHDOG":网络环境检测看门狗的喂狗消息,在需要喂狗的地方发布此消息;
-
-
-
-## 演示功能概述
-
-1、创建三路mqtt连接,详情如下
-
-- 创建一个mqtt client,连接mqtt server;
-
-- 创建一个mqtt ssl client,连接mqtt ssl server,不做证书校验;
-
-- 创建一个mqtt ssl client,连接mqtt ssl server,client仅单向校验server的证书,server不校验client的证书和密钥文件;
-
-2、每一路mqtt连接出现异常后,自动重连;
-
-3、每一路mqtt连接,client按照以下几种逻辑发送数据给server
-
-- 串口应用功能模块uart_app.lua,通过uart1接收到串口数据,将串口数据增加send from uart: 前缀后,使用mobile.imei().."/uart/up"主题,发送给server;
-
-- 定时器应用功能模块timer_app.lua,定时产生数据,将数据增加send from timer:前缀后,使用mobile.imei().."/timer/up"主题,发送给server;
-
-4、每一路mqtt连接,client收到server数据后,将数据增加recv from mqtt/mqtt ssl/mqtt ssl ca(三选一)server: 前缀后,通过uart1发送出去;
-
-5、启动一个网络业务逻辑看门狗task,用来监控网络环境,如果连续长时间工作不正常,重启整个软件系统;
-
-6、netdrv_device:配置连接外网使用的网卡,目前支持以下四种选择(四选一)
-
-   (1) netdrv_4g:4G网卡
-
-   (2) netdrv_wifi:WIFI STA网卡
-
-   (3) netdrv_eth_spi:通过SPI外挂CH390H芯片的以太网卡
-
-   (4) netdrv_multiple:支持以上三种网卡,可以配置三种网卡的优先级
-
-
-
-## 演示硬件环境
-
-![](https://docs.openluat.com/air8000/luatos/app/image/netdrv_multi.jpg)
-
-1、Air8000开发板一块+可上网的sim卡一张+4g天线一根+wifi天线一根+网线一根:
-
-- sim卡插入开发板的sim卡槽
-
-- 天线装到开发板上
-
-- 网线一端插入开发板网口,另外一端连接可以上外网的路由器网口
-
-2、TYPE-C USB数据线一根 + USB转串口数据线一根,Air8000开发板和数据线的硬件接线方式为:
-
-- Air8000开发板通过TYPE-C USB口供电;(外部供电/USB供电 拨动开关 拨到 USB供电一端)
-
-- TYPE-C USB数据线直接插到核心板的TYPE-C USB座子,另外一端连接电脑USB口;
-
-- USB转串口数据线,一般来说,白线连接开发板的UART1_TX,绿线连接开发板的UART1_RX,黑线连接核心板的GND,另外一端连接电脑USB口;
-
-
-## 演示软件环境
-
-1、Luatools下载调试工具
-
-2、[Air8000 V2011版本固件)](https://docs.openluat.com/air8000/luatos/firmware/)(理论上,2025年7月26日之后发布的固件都可以)
-
-3、PC端的串口工具,例如SSCOM、LLCOM等都可以
-
-4、[MQTT客户端软件MQTTX](https://docs.openluat.com/air8000/luatos/common/swenv/#27-mqttmqttx)
-
-
-## 演示核心步骤
-
-1、搭建好硬件环境
-
-2、demo脚本代码netdrv_device.lua中,按照自己的网卡需求启用对应的Lua文件
-
-- 如果需要单4G网卡,打开require "netdrv_4g",其余注释掉
-
-- 如果需要单WIFI STA网卡,打开require "netdrv_wifi",其余注释掉;同时netdrv_wifi.lua中的wlan.connect("茶室-降功耗,找合宙!", "Air123456", 1),前两个参数,修改为自己测试时wifi热点的名称和密码;注意:仅支持2.4G的wifi,不支持5G的wifi
-
-- 如果需要以太网卡,打开require "netdrv_eth_spi",其余注释掉
-
-- 如果需要多网卡,打开require "netdrv_multiple",其余注释掉;同时netdrv_multiple.lua中的ssid = "茶室-降功耗,找合宙!", password = "Air123456", 修改为自己测试时wifi热点的名称和密码;注意:仅支持2.4G的wifi,不支持5G的wifi
-
-3、Luatools烧录内核固件和修改后的demo脚本代码
-
-4、烧录成功后,自动开机运行,如果出现以下日志,表示三路mqtt连接成功
-
-``` lua
-I/user.mqtt_client_main_task_func connect success
-
-I/user.mqtts_client_main_task_func connect success
-
-I/user.mqtts_ca__client_main_task_func connect success
-```
-
-5、启动两个MQTTX工具,分别连接上mqtt client和mqtts client对应的server,订阅$imei/up主题,$imei表示设备的imei号;
-   可以看到,每隔5秒钟,会接收到一段类似于 send from timer: 1 的数据,最后面的数字每次加1;
-
-6、打开PC端的串口工具,选择对应的端口,配置波特率115200,数据位8,停止位1,无奇偶校验位;
-
-7、PC端的串口工具输入一段数据,点击发送,在MQTTX工具订阅的$imei/up主题下可以接收到数据;
-
-8、在MQTTX工具上,在主题$imei/down下publish一段数据,点击发送,在PC端的串口工具上可以接收到主题和数据,并且也能看到是哪一个server发送的,类似于以下效果:
-
-``` lua
-recv from mqtt server: 864793080144269/down,123456798012345678901234567830
-recv from mqtt ssl server: 864793080144269/down,123456798012345678901234567830
-recv from mqtt ca ssl server: 864793080144269/down,123456798012345678901234567830
-```

+ 0 - 44
module/Air8000/demo/mqttv2/timer_app.lua

@@ -1,44 +0,0 @@
---[[
-@module  timer_app
-@summary 定时器应用功能模块 
-@version 1.0
-@date    2025.07.01
-@author  朱天华
-@usage
-本文件为定时器应用功能模块,核心业务逻辑为:
-创建一个5秒的循环定时器,每次产生一段数据,通知三个mqtt client进行处理;
-
-本文件的对外接口有一个:
-1、sys.publish("SEND_DATA_REQ", "timer", mobile.imei().."/timer/up", payload, 0, {func=send_data_cbfunc, para="timer"..payload})
-   通过publish通知三路mqtt client数据发送功能模块publish数据;
-   数据发送结果通过执行回调函数send_data_cbfunc通知本功能模块;
-]]
-
-local payload = 1
-
--- 数据发送结果回调函数
--- result:发送结果,true为发送成功,false为发送失败
--- para:回调参数,sys.publish("SEND_DATA_REQ", "timer", mobile.imei().."/timer/up", payload, 0, {func=send_data_cbfunc, para="timer"..payload})中携带的para
-local function send_data_cbfunc(result, para)
-    log.info("send_data_cbfunc", result, para)
-    -- 无论上一次发送成功还是失败,启动一个5秒的定时器,5秒后发送下次数据
-    sys.timerStart(send_data_req_timer_cbfunc, 5000)
-end
-
--- 定时器回调函数
-function send_data_req_timer_cbfunc()
-    -- 发布消息"SEND_DATA_REQ"
-    -- 携带的第一个参数"timer"表示是定时器应用模块发布的消息
-    -- 携带的第二个参数mobile.imei().."/timer/up"为要publish的topic
-    -- 携带的第三个参数payload为要publish的payload
-    -- 携带的第四个参数0为publish的qos
-    -- 携带的第五个参数cb为发送结果回调(可以为空,如果为空,表示不关心mqtt client发送数据成功还是失败),其中:
-    --       cb.func为回调函数(可以为空,如果为空,表示不关心mqtt client发送数据成功还是失败)
-    --       cb.para为回调函数的第二个参数(可以为空),回调函数的第一个参数为发送结果(true表示成功,false表示失败)
-    sys.publish("SEND_DATA_REQ", "timer", mobile.imei().."/timer/up", payload, 0, {func=send_data_cbfunc, para="timer"..payload})
-    payload = payload+1
-end
-
--- 启动一个5秒的单次定时器
--- 时间到达后,执行一次send_data_req_timer_cbfunc函数
-sys.timerStart(send_data_req_timer_cbfunc, 5000)

+ 0 - 80
module/Air8000/demo/mqttv2/uart_app.lua

@@ -1,80 +0,0 @@
---[[
-@module  uart_app
-@summary 串口应用功能模块 
-@version 1.0
-@date    2025.07.28
-@author  朱天华
-@usage
-本文件为串口应用功能模块,核心业务逻辑为:
-1、打开uart1,波特率115200,数据位8,停止位1,无奇偶校验位;
-2、uart1和pc端的串口工具相连;
-3、从uart1接收到pc端串口工具发送的数据后,通知三个mqtt client进行处理;
-4、收到三个mqtt client从socket server接收到的数据后,将数据通过uart1发送到pc端串口工具;
-
-本文件的对外接口有两个:
-1、sys.publish("SEND_DATA_REQ", "uart", mobile.imei().."/uart/up", read_buf, 1)
-   通知mqtt client数据发送模块,在mobile.imei().."/uart/up"的topic上publish数据read_buf,不关心数据发送成功还是失败;
-2、sys.subscribe("RECV_DATA_FROM_SERVER", recv_data_from_server_proc),订阅RECV_DATA_FROM_SERVER消息,处理消息携带的数据;
-]]
-
-
--- 使用UART1
-local UART_ID = 1
--- 串口接收数据缓冲区
-local read_buf = ""
-
--- 将前缀prefix和topic,payload数据拼接
--- 然后末尾增加回车换行两个字符,通过uart发送出去,方便在PC端换行显示查看
-local function recv_data_from_server_proc(prefix, topic, payload)
-    uart.write(UART_ID, prefix..topic..","..payload.."\r\n")
-end
-
-
-local function concat_timeout_func()
-    -- 如果存在尚未处理的串口缓冲区数据;
-    -- 将数据通过publish通知其他应用功能模块处理;
-    -- 然后清空本文件的串口缓冲区数据
-    if read_buf:len() > 0 then
-        sys.publish("SEND_DATA_REQ", "uart", mobile.imei().."/uart/up", read_buf, 1)
-        read_buf = ""
-    end
-end
-
-
--- UART1的数据接收中断处理函数,UART1接收到数据时,会执行此函数
-local function read()
-    local s
-    while true do
-        -- 非阻塞读取UART1接收到的数据,最长读取1024字节
-        s = uart.read(UART_ID, 1024)
-        
-        -- 如果从串口没有读到数据
-        if not s or s:len() == 0 then
-            -- 启动50毫秒的定时器,如果50毫秒内没收到新的数据,则处理当前收到的所有数据
-            -- 这样处理是为了防止将一大包数据拆分成多个小包来处理
-            -- 例如pc端串口工具下发1100字节的数据,可能会产生将近20次的中断进入到read函数,才能读取完整
-            -- 此处的50毫秒可以根据自己项目的需求做适当修改,在满足整包拼接完整的前提下,时间越短,处理越及时
-            sys.timerStart(concat_timeout_func, 50)
-            -- 跳出循环,退出本函数
-            break
-        end
-
-        log.info("uart_app.read len", s:len())
-        -- log.info("uart_app.read", s)
-
-        -- 将本次从串口读到的数据拼接到串口缓冲区read_buf中
-        read_buf = read_buf..s
-    end
-end
-
-
-
--- 初始化UART1,波特率115200,数据位8,停止位1
-uart.setup(UART_ID, 115200, 8, 1)
-
--- 注册UART1的数据接收中断处理函数,UART1接收到数据时,会执行read函数
-uart.on(UART_ID, "receive", read)
-
--- 订阅"RECV_DATA_FROM_SERVER"消息的处理函数recv_data_from_server_proc
--- 收到"RECV_DATA_FROM_SERVER"消息后,会执行函数recv_data_from_server_proc
-sys.subscribe("RECV_DATA_FROM_SERVER", recv_data_from_server_proc)

+ 1 - 1
module/Air8000/demo/socket/client/long_connection/netdrv/netdrv_wifi.lua

@@ -39,7 +39,7 @@ wlan.init()
 --Air8000仅支持2.4G的WIFI,不支持5G的WIFI
 --此处前两个参数表示WIFI热点名称以及密码,更换为自己测试时的真实参数即可
 --第三个参数1表示WIFI连接异常时,内核固件会自动重连
-wlan.connect("茶室-降功耗,找合宙!", "Air123456", 1)
+wlan.connect("iPhone", "xiaoshuai", 1)
 
 --WIFI联网成功(做为STATION成功连接AP,并且获取到了IP地址)后,内核固件会产生一个"IP_READY"消息
 --各个功能模块可以订阅"IP_READY"消息实时处理WIFI联网成功的事件

+ 2 - 2
module/Air8000/demo/socket/client/long_connection/netdrv_device.lua

@@ -21,7 +21,7 @@
 -- 根据自己的项目需求,只需要require以下四种中的一种即可;
 
 -- 加载“4G网卡”驱动模块
-require "netdrv_4g"
+-- require "netdrv_4g"
 
 -- 加载“WIFI STA网卡”驱动模块
 -- require "netdrv_wifi"
@@ -30,4 +30,4 @@ require "netdrv_4g"
 -- require "netdrv_eth_spi"
 
 -- 加载“可以配置优先级的多种网卡”驱动模块
--- require "netdrv_multiple"
+require "netdrv_multiple"

+ 1 - 1
module/Air8000/demo/socket/client/long_connection/tcp/tcp_client_main.lua

@@ -24,7 +24,7 @@ local tcp_client_sender = require "tcp_client_sender"
 -- 点击 打开TCP 按钮,会创建一个TCP server
 -- 将server的地址和端口赋值给下面这两个变量
 local SERVER_ADDR = "112.125.89.8"
-local SERVER_PORT = 42610
+local SERVER_PORT = 42145
 
 -- tcp_client_main的任务名
 local TASK_NAME = tcp_client_sender.TASK_NAME

+ 1 - 1
module/Air8000/demo/socket/client/long_connection/tcp_ssl/tcp_ssl_main.lua

@@ -24,7 +24,7 @@ local tcp_ssl_sender = require "tcp_ssl_sender"
 -- 点击 打开TCP SSL 按钮,会创建一个TCP SSL server
 -- 将server的地址和端口赋值给下面这两个变量
 local SERVER_ADDR = "112.125.89.8"
-local SERVER_PORT = 42429
+local SERVER_PORT = 43428 
 
 -- tcp_ssl_main的任务名
 local TASK_NAME = tcp_ssl_sender.TASK_NAME

+ 1 - 1
module/Air8000/demo/socket/client/long_connection/udp/udp_client_main.lua

@@ -24,7 +24,7 @@ local udp_client_sender = require "udp_client_sender"
 -- 点击 打开UDP 按钮,会创建一个UDP server
 -- 将server的地址和端口赋值给下面这两个变量
 local SERVER_ADDR = "112.125.89.8"
-local SERVER_PORT = 46819
+local SERVER_PORT = 47708 
 
 -- udp_client_main的任务名
 local TASK_NAME = udp_client_sender.TASK_NAME

+ 0 - 142
module/Air8000/demo/tcp/TCP-UART/main.lua

@@ -1,142 +0,0 @@
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "uart_tcp"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
--- 引入必要的库文件(lua编写), 内部库不需要require
-sys = require("sys")
-
-_G.sysplus = require("sysplus")
-local taskName = "TCP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-local uartid = 1 -- 根据实际设备选取不同的uartid
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接tcp服务器的ip地址
-local port = 43919                 -- 连接tcp服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = false                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = false                       -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)      -- 发送至tcp服务器的数据
-local rx_buff = zbuff.create(1024)      -- 从tcp服务器接收到的数据
-
---初始化
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
--- 处理未识别的消息
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-
-function TCP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                      -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl)       -- 此配置为TCP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        result = libnet.connect(taskName, 15000, socket_client, ip, port)
-
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-              local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-               if len <= 0 then    -- 接收到的字节长度为0 则退出
-                   break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                   sys_send(taskName, socket.EVENT, 0)
-                end
-                break
-            end
-        end)
-
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            connect_state = true
-            libnet.tx(taskName, 0, socket_client, "TCP  CONNECT")
-        end
-
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-
-                uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给tcp待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(d1Name, 5000, socket_client)
-        socket.release(socket_client)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-
-end
-
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(TCP_TASK, taskName, tcp_client_main_cbfunc)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 145
module/Air8000/demo/tcp/TCP单向认证/main.lua

@@ -1,145 +0,0 @@
--- main.lua文件
-
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "uart_tcp"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
--- 引入必要的库文件(lua编写), 内部库不需要require
-sys = require("sys")
-
-_G.sysplus = require("sysplus")
-local taskName = "TCP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-
-local uartid = 1 -- 根据实际设备选取不同的uartid
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接tcp服务器的ip地址
-local port = 46428            -- 连接tcp服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = false                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = true                     -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)      -- 发送至tcp服务器的数据
-local rx_buff = zbuff.create(1024)      -- 从tcp服务器接收到的数据
-
---初始化
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
--- 处理未识别的消息
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-
-function TCP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                      -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl)       -- 此配置为TCP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        result = libnet.connect(taskName, 15000, socket_client, ip, port)
-
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-                local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-                if len <= 0 then    -- 接收到的字节长度为0 则退出
-                    break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                    sys_send(taskName, socket.EVENT, 0)
-                end
-            end
-        end)
-
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            connect_state = true
-            libnet.tx(taskName, 0, socket_client, "TCP  CONNECT")
-        end
-
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-
-                uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给tcp待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(d1Name, 5000, socket_client)
-        socket.release(socket_client)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-
-end
-
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(TCP_TASK, taskName, tcp_client_main_cbfunc)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 141
module/Air8000/demo/tcp/TCP断链续连/main.lua

@@ -1,141 +0,0 @@
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "uart_tcp"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
--- 引入必要的库文件(lua编写), 内部库不需要require
-sys = require("sys")
-
-_G.sysplus = require("sysplus")
-local taskName = "TCP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-local uartid = 1 -- 根据实际设备选取不同的uartid
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接tcp服务器的ip地址
-local port = 46244                 -- 连接tcp服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = false                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = false                       -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)      -- 发送至tcp服务器的数据
-local rx_buff = zbuff.create(1024)      -- 从tcp服务器接收到的数据
-
---初始化
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
--- 处理未识别的消息
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-
-function TCP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                      -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl)       -- 此配置为TCP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        result = libnet.connect(taskName, 15000, socket_client, ip, port)
-
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-                local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-                if len <= 0 then    -- 接收到的字节长度为0 则退出
-                    break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                    sys_send(taskName, socket.EVENT, 0)
-                end
-            end
-        end)
-
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            connect_state = true
-            libnet.tx(taskName, 0, socket_client, "TCP  CONNECT")
-        end
-
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-
-                uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给tcp待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(d1Name, 5000, socket_client)
-        socket.release(socket_client)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-
-end
-
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(TCP_TASK, taskName, tcp_client_main_cbfunc)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 130
module/Air8000/demo/udp/main.lua

@@ -1,130 +0,0 @@
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "scdemo"
-VERSION = "1.0.0"
-log.info("main", PROJECT, VERSION)
--- 一定要添加sys.lua !!!!
-sys = require("sys")
-_G.sysplus = require("sysplus")
-local taskName = "UDP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-----------------------------网络配置---------------------------
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接UDP服务器的ip地址
-local port = 46139                      -- 连接UDP服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = true                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = false                       -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)     -- 发送至UDP服务器的数据
-local rx_buff = zbuff.create(1024)     -- 从UDP服务器接收到的数据
---==============================================================
---Uart初始化  
-local uartid = 1 -- 根据实际设备选取不同的uartid
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-function UDP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    -- 串口和UDP服务器的交互逻辑
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl) -- 此配置为UDP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        local result = libnet.connect(taskName, 15000, socket_client, ip, port)
-        -----查询网络状态
-        local status = mobile.status()    
-        log.info("status", status) 
-        
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        log.info("connect ip: 等待连接 ",result)
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-                local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-                if len <= 0 then    -- 接收到的字节长度为0 则退出
-                    break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                    sys_send(taskName, socket.EVENT, 0)
-                end
-            end
-        end)
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            log.info("connect ip: 连接成功")
-            connect_state = true
-           libnet.tx(taskName, 0, socket_client, "UDP CONNECT")
-        end
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-               uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给UDP待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(taskName, 5000, socket_client)
-        socket.release(netc)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-end
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(UDP_TASK, taskName, tcp_client_main_cbfunc)
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 1 - 1
module/Air8101/demo/mqtt/netdrv_device.lua

@@ -31,7 +31,7 @@ require "netdrv_wifi"
 -- require "netdrv_eth_spi"
 
 -- 加载“通过SPI外挂4G模组的4G网卡”驱动模块
--- require "netdrv_4G"
+-- require "netdrv_4g"
 
 -- 加载“可以配置优先级的多种网卡”驱动模块
 -- require "netdrv_multiple"

+ 2 - 2
module/Air8101/demo/socket/client/long_connection/netdrv_device.lua

@@ -22,7 +22,7 @@
 -- 根据自己的项目需求,只需要require以下五种中的一种即可;
 
 -- 加载“WIFI STA网卡”驱动模块
-require "netdrv_wifi"
+-- require "netdrv_wifi"
 
 -- 加载“通过MAC层的rmii接口外挂PHY芯片(LAN8720Ai)的以太网卡”驱动模块
 -- require "netdrv_eth_rmii"
@@ -31,7 +31,7 @@ require "netdrv_wifi"
 -- require "netdrv_eth_spi"
 
 -- 加载“通过SPI外挂4G模组的4G网卡”驱动模块
--- require "netdrv_4G"
+require "netdrv_4g"
 
 -- 加载“可以配置优先级的多种网卡”驱动模块
 -- require "netdrv_multiple"

+ 1 - 1
module/Air8101/demo/socket/client/long_connection/tcp/tcp_client_main.lua

@@ -24,7 +24,7 @@ local tcp_client_sender = require "tcp_client_sender"
 -- 点击 打开TCP 按钮,会创建一个TCP server
 -- 将server的地址和端口赋值给下面这两个变量
 local SERVER_ADDR = "112.125.89.8"
-local SERVER_PORT = 43582
+local SERVER_PORT = 43187
 
 -- tcp_client_main的任务名
 local TASK_NAME = tcp_client_sender.TASK_NAME

+ 1 - 1
module/Air8101/demo/socket/client/long_connection/tcp_ssl/tcp_ssl_main.lua

@@ -24,7 +24,7 @@ local tcp_ssl_sender = require "tcp_ssl_sender"
 -- 点击 打开TCP SSL 按钮,会创建一个TCP SSL server
 -- 将server的地址和端口赋值给下面这两个变量
 local SERVER_ADDR = "112.125.89.8"
-local SERVER_PORT = 43312
+local SERVER_PORT = 46909  
 
 -- tcp_ssl_main的任务名
 local TASK_NAME = tcp_ssl_sender.TASK_NAME

+ 1 - 1
module/Air8101/demo/socket/client/long_connection/udp/udp_client_main.lua

@@ -24,7 +24,7 @@ local udp_client_sender = require "udp_client_sender"
 -- 点击 打开UDP 按钮,会创建一个UDP server
 -- 将server的地址和端口赋值给下面这两个变量
 local SERVER_ADDR = "112.125.89.8"
-local SERVER_PORT = 46392
+local SERVER_PORT = 45468  
 
 -- udp_client_main的任务名
 local TASK_NAME = udp_client_sender.TASK_NAME

+ 0 - 161
module/Air8101/demo/tcp/TCP_Uart/main.lua

@@ -1,161 +0,0 @@
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "Wifi_TCP_Uart"
-VERSION = "1.0.0"
-
-local taskName = "TCP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-local uartid = 1 -- 根据实际设备选取不同的uartid    
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接tcp服务器的ip地址
-local port = 46646             -- 连接tcp服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = false                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = false                       -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)      -- 发送至tcp服务器的数据
-local rx_buff = zbuff.create(1024)      -- 从tcp服务器接收到的数据
-local data_buf
---初始化
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
-sys.taskInit(function()
-    sys.wait(1000)
-    -----------------------------
-    ---------wifi 联网-----------
-    -----------------------------
-    if wlan and wlan.connect then
-        -- wifi 联网, ESP32系列均支持
-        local ssid = "test"
-        local password = "waljy2333"
-        log.info("wifi", ssid, password)
-        -- TODO 改成esptouch配网
-        -- LED = gpio.setup(12, 0, gpio.PULLUP)
-        wlan.init()
-        wlan.setMode(wlan.STATION)
-        wlan.connect(ssid, password, 1)
-        local result, data = sys.waitUntil("IP_READY")
-        log.info("wlan", "IP_READY", result, data)
-        device_id = wlan.getMac()
-    end
-    log.info("已联网")
-    sys.publish("net_ready")
-end)
-
--- 处理未识别的消息
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-
-function TCP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                      -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl)       -- 此配置为TCP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        result = libnet.connect(taskName, 15000, socket_client, ip, port)
-
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-              local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-               if len <= 0 then    -- 接收到的字节长度为0 则退出
-                   break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                   sys_send(taskName, socket.EVENT, 0)
-                end
-                break
-            end
-        end)
-
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            connect_state = true
-            libnet.tx(taskName, 0, socket_client, "TCP  CONNECT")
-        end
-
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-
-                uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给tcp待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(d1Name, 5000, socket_client)
-        socket.release(socket_client)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-
-end
-
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(TCP_TASK, taskName, tcp_client_main_cbfunc)
-
-
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 164
module/Air8101/demo/tcp/TCP单向认证/main.lua

@@ -1,164 +0,0 @@
--- main.lua文件
-
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "Wifi_TCP_Uart"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
-local taskName = "TCP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-
-local uartid = 1 -- 根据实际设备选取不同的uartid
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接tcp服务器的ip地址
-local port = 46428            -- 连接tcp服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = false                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = true                     -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)      -- 发送至tcp服务器的数据
-local rx_buff = zbuff.create(1024)      -- 从tcp服务器接收到的数据
-
---初始化
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
-sys.taskInit(function()
-    sys.wait(1000)
-    -----------------------------
-    ---------wifi 联网-----------
-    -----------------------------
-if wlan and wlan.connect then
-        -- wifi 联网, ESP32系列均支持
-        local ssid = "test"
-        local password = "waljy2333"
-        log.info("wifi", ssid, password)
-        -- TODO 改成esptouch配网
-        -- LED = gpio.setup(12, 0, gpio.PULLUP)
-        wlan.init()
-        wlan.setMode(wlan.STATION)
-        wlan.connect(ssid, password, 1)
-        local result, data = sys.waitUntil("IP_READY")
-        log.info("wlan", "IP_READY", result, data)
-        device_id = wlan.getMac()
-    end
-    log.info("已联网")
-    sys.publish("net_ready")
-end)
-
--- 处理未识别的消息
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-
-function TCP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                      -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl)       -- 此配置为TCP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        result = libnet.connect(taskName, 15000, socket_client, ip, port)
-
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-                local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-                if len <= 0 then    -- 接收到的字节长度为0 则退出
-                    break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                    sys_send(taskName, socket.EVENT, 0)
-                end
-            end
-        end)
-
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            connect_state = true
-            libnet.tx(taskName, 0, socket_client, "TCP  CONNECT")
-        end
-
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-
-                uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给tcp待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(d1Name, 5000, socket_client)
-        socket.release(socket_client)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-
-end
-
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(TCP_TASK, taskName, tcp_client_main_cbfunc)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 164
module/Air8101/demo/tcp/TCP断链续连/main.lua

@@ -1,164 +0,0 @@
--- main.lua文件
-
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "Wifi_TCP_Uart"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
-local taskName = "TCP_TASK"             -- sysplus库用到的任务名称,也作为任务id
-
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-
-local uartid = 1 -- 根据实际设备选取不同的uartid
-local uart_rx_buff = zbuff.create(1024)     -- 串口接收到的数据
-
-local libnet = require "libnet"         -- libnet库,支持tcp、udp协议所用的同步阻塞接口
-local ip = "112.125.89.8"               -- 连接tcp服务器的ip地址
-local port = 43115                -- 连接tcp服务器的端口
-local connect_state = false             -- 连接状态 true:已连接   false:未连接
-local protocol = false                  -- 通讯协议 true:UDP协议  false:TCP协议
-local ssl = false                       -- 加密传输 true:加密     false:不加密
-local tx_buff = zbuff.create(1024)      -- 发送至tcp服务器的数据
-local rx_buff = zbuff.create(1024)      -- 从tcp服务器接收到的数据
-
---初始化
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
-sys.taskInit(function()
-    sys.wait(1000)
-    -----------------------------
-    ---------wifi 联网-----------
-    -----------------------------
-    if wlan and wlan.connect then
-        -- wifi 联网, ESP32系列均支持
-        local ssid = "test"                 --wifi 名
-        local password = "waljy2333"        --wifi 密码
-        log.info("wifi", ssid, password)
-        -- TODO 改成esptouch配网
-        -- LED = gpio.setup(12, 0, gpio.PULLUP)
-        wlan.init()
-        wlan.setMode(wlan.STATION)
-        wlan.connect(ssid, password, 1)
-        local result, data = sys.waitUntil("IP_READY")
-        log.info("wlan", "IP_READY", result, data)
-        device_id = wlan.getMac()
-    end
-    log.info("已联网")
-    sys.publish("net_ready")
-end)
-
--- 处理未识别的消息
-local function tcp_client_main_cbfunc(msg)
-	log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
-end
-
-
-function TCP_TASK()
-    -- 打印一下连接的目标ip和端口号
-    log.info("connect ip: ", ip, "port:", port)
-
-    sys.waitUntil("IP_READY")                -- 等待联网成功
-    local socket_client
-    while true do
-        socket_client = socket.create(nil, taskName)     -- 创建socket对象
-        socket.debug(socket_client, true)                      -- 打开调试日志
-        socket.config(socket_client, nil, protocol, ssl)       -- 此配置为TCP连接,无SSL加密
-        -- 连接服务器,返回是否连接成功
-        result = libnet.connect(taskName, 15000, socket_client, ip, port)
-
-        -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
-        uart.on(uartid, "receive", function(id, len)
-            while true do
-                local len = uart.rx(id, uart_rx_buff)   -- 接收串口收到的数据,并赋值到uart_rx_buff
-                if len <= 0 then    -- 接收到的字节长度为0 则退出
-                    break
-                end
-                -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-                if connect_state then
-                    sys_send(taskName, socket.EVENT, 0)
-                end
-            end
-        end)
-
-        -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
-        if result then
-            connect_state = true
-            libnet.tx(taskName, 0, socket_client, "TCP  CONNECT")
-        end
-
-        -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
-        while result do
-            succ, param, _, _ = socket.rx(socket_client, rx_buff)   -- 接收数据
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-
-                uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-
-            tx_buff:copy(nil, uart_rx_buff)         -- 将串口数据赋值给tcp待发送数据的buff中
-            uart_rx_buff:del()                      -- 清除串口buff的数据长度
-            if tx_buff:used() > 0 then
-                log.info("发送到服务器数据,长度", tx_buff:used())
-                local result = libnet.tx(taskName, 0, socket_client, tx_buff)   -- 发送数据
-                if not result then
-                    log.info("发送失败了", result, param)
-                    break
-                end
-            end
-            tx_buff:del()
-
-            -- 如果zbuff对象长度超出,需要重新分配下空间
-            if uart_rx_buff:len() > 1024 then
-                uart_rx_buff:resize(1024)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))   -- 打印系统内存
-
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(taskName, 15000, socket_client)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-
-        -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
-        connect_state = false
-        libnet.close(d1Name, 5000, socket_client)
-        socket.release(socket_client)
-        tx_buff:clear(0)
-        rx_buff:clear(0)
-        socket_client=nil
-        sys.wait(1000)
-    end
-
-end
-
--- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
-sysplus.taskInitEx(TCP_TASK, taskName, tcp_client_main_cbfunc)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 211
module/Air8101/demo/udp/main.lua

@@ -1,211 +0,0 @@
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "scdemo"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
-libnet = require "libnet"
-
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-
---Uart初始化  
-local uartid = 1 -- 根据实际设备选取不同的uartid
-uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
-
---=============================================================
--- 测试网站 https://netlab.luatos.com/ 点击 打开TCP 获取测试端口号
--- 要按实际情况修改
-local host = "112.125.89.8" -- 服务器ip或者域名, 都可以的
-local port = 43743          -- 服务器端口号
-local is_udp = true         -- 如果是UDP, 要改成true, false就是TCP
-local is_tls = false        -- 加密与否, 要看服务器的实际情况
---=============================================================
-
--- 处理未识别的网络消息
-local function netCB(msg)
-    log.info("未处理消息", msg[1], msg[2], msg[3], msg[4])
-end
-
--- 统一联网函数
-sys.taskInit(function()
-    local res,data
-    -----------------------------
-    -- 统一联网函数, 可自行删减
-    ----------------------------
-    ----- time 为修复网络时间过长而修订为 while主体,增加网络状态判断
-    while true do
-        if wlan and wlan.connect then
-            -- wifi 联网,要根据实际情况修改ssid和password!!
-            local ssid = "kfyy_7890"
-            local password = "kfyy123456"
-            log.info("wifi", ssid, password)
-            -- TODO 改成自动配网
-            wlan.init()
-            wlan.setMode(wlan.STATION) -- 默认也是这个模式,不调用也可以
-            wlan.connect(ssid, password, 1)
-            -- 在网络连接成功时,会发布一个系统消息 IP_READY,而
-            -- sys.waitUntil 订阅此消息,能在设置的时间内收到此消息
-            -- 即表示网络连接成功。
-            res, data = sys.waitUntil("IP_READY", 30000)
-            log.info("wlan", "IP_READY", result, data)
-         else
-            -- 其他不认识的bsp, 循环提示一下吧
-            while 1 do
-                sys.wait(1000)
-                log.info("bsp", "本bsp可能未适配网络层, 请查证")
-            end
-        end
-
-        if res == true then
-            log.info("已联网")
-            sys.publish("net_ready")
-        end
-        ----- time 为修复网络时间过长而修订为 while主体,增加网络状态判断
-        while wlan and wlan.ready() do
-            sys.wait(4000)
-        end
-    end
-end)
-
--- 演示task
-local function sockettest()
-    -- 等待联网
-    sys.waitUntil("net_ready")
-    -- sntp时间同步
-    socket.sntp()
-
-    -- 开始正在的逻辑, 发起socket链接,等待数据/上报心跳
-    local taskName = "sc"
-    local topic = taskName .. "_txrx"
-    log.info("topic", topic)
-    local txqueue = {}
-    sysplus.taskInitEx(sockettask, taskName, netCB, taskName, txqueue, topic)
-    while 1 do
-        local result, tp, data = sys.waitUntil(topic, 30000)
-        log.info("event", result, tp, data)
-        if not result then
-            -- 等待30秒,没数据上传/下发, 发个日期心跳包吧
-            table.insert(txqueue, os.date())
-            sys_send(taskName, socket.EVENT, 0)
-        elseif tp == "uplink" then
-            -- 上行数据, 主动上报的数据,那就发送呀
-            table.insert(txqueue, data)
-            sys_send(taskName, socket.EVENT, 0)
-        elseif tp == "downlink" then
-            -- 下行数据,接收的数据
-            -- 其他代码可以通过 sys.publish()
-            log.info("socket", "收到下发的数据了", #data)
-        end
-    end
-end
-
-function sockettask(d1Name, txqueue, rxtopic)
-    -- 打印准备连接的服务器信息
-    log.info("socket", host, port, is_udp and "UDP" or "TCP", is_tls and "TLS" or "RAW")
-
-    -- 准备好所需要的接收缓冲区
-    local rx_buff = zbuff.create(1024)
-    local netc
-
-    while true do
-        netc = socket.create(nil, d1Name)
-        socket.config(netc, nil, is_udp, is_tls)
-        log.info("任务id", d1Name)
-
-        -- 连接服务器, 15秒超时
-        log.info("socket", "开始连接服务器")
-        sysplus.cleanMsg(d1Name)
-        local result = libnet.connect(d1Name, 15000, netc, host, port)
-        if result then
-            log.info("socket", "服务器连上了")
-            libnet.tx(d1Name, 0, netc, "helloworld")
-        else
-            log.info("socket", "服务器没连上了!!!")
-        end
-        while result do
-            -- 连接成功之后, 先尝试接收
-            -- log.info("socket", "调用rx接收数据")
-            local succ, param = socket.rx(netc, rx_buff)
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-            -- 如果服务器有下发数据, used()就必然大于0, 进行处理
-            if rx_buff:used() > 0 then
-                log.info("socket", "收到服务器数据,长度", rx_buff:used())
-                local data = rx_buff:query() -- 获取数据
-                sys.publish(rxtopic, "downlink", data)
-                uart.tx(uartid, rx_buff)    -- 从服务器收到的数据转发 从串口输出
-                rx_buff:del()
-            end
-            -- log.info("libnet", "调用wait开始等待消息")
-            -- 等待事件, 例如: 服务器下发数据, 有数据准备上报, 服务器断开连接
-            result, param, param2 = libnet.wait(d1Name, 15000, netc)
-            log.info("libnet", "wait", result, param, param2)
-            if not result then
-                -- 网络异常了, 那就断开了, 执行清理工作
-                log.info("socket", "服务器断开了", result, param)
-                break
-            elseif #txqueue > 0 then
-                -- 有待上报的数据,处理之
-                while #txqueue > 0 do
-                    local data = table.remove(txqueue, 1)
-                    if not data then
-                        break
-                    end
-                    result,param = libnet.tx(d1Name, 15000, netc,data)
-                    -- log.info("libnet", "发送数据的结果", result, param)
-                    if not result then
-                        log.info("socket", "数据发送异常", result, param)
-                        break
-                    end
-                end
-            end
-            -- 循环尾部, 继续下一轮循环
-        end
-        libnet.close(d1Name, 5000, netc)
-        socket.release(netc)
-        rx_buff:clear(0)
-        netc=nil
-        sys.wait(1000)
-    end
-end
-
-sys.taskInit(sockettest)
-
--- -- 演示定时上报数据, 不需要就注释掉
--- sys.taskInit(function()
---     sys.wait(5000)
---     while 1 do
---         sys.publish("sc_txrx", "uplink", os.date())
---         sys.wait(3000)
---     end
--- end)
-
--- 演示uart数据上报, 不需要就注释掉
-    uart.on(uartid, "receive", function(id, len)
-        while 1 do
-            local s = uart.read(1, 1024)
-            if #s == 0 then
-                break
-            end
-            sys.publish("sc_txrx", "uplink", s)
-            if #s == len then
-                break
-            end
-        end
-    end)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!