Просмотр исходного кода

add: airlink初版,起码能访问内网IP了

Wendal Chen 1 год назад
Родитель
Сommit
b871d89f2c

+ 8 - 1
components/airlink/binding/luat_lib_airlink.c

@@ -13,6 +13,12 @@
 #define LUAT_LOG_TAG "airlink"
 #include "luat_log.h"
 
+static int l_airlink_init(lua_State *L) {
+    LLOGD("初始化AirLink");
+    luat_airlink_init();
+    return 0;
+}
+
 static int l_airlink_start(lua_State *L) {
     int id = luaL_checkinteger(L, 1);
     if (id == 0) {
@@ -44,9 +50,10 @@ static int l_airlink_stop(lua_State *L) {
 #include "rotable2.h"
 static const rotable_Reg_t reg_airlink[] =
 {
+    { "init" ,         ROREG_FUNC(l_airlink_init )},
     { "start" ,        ROREG_FUNC(l_airlink_start )},
     { "stop" ,         ROREG_FUNC(l_airlink_stop )},
-	{ NULL,             ROREG_INT(0) }
+	{ NULL,            ROREG_INT(0) }
 };
 
 LUAMOD_API int luaopen_airlink( lua_State *L ) {

+ 34 - 1
components/airlink/include/luat_airlink.h

@@ -8,8 +8,8 @@ typedef struct luat_airlink_cmd
     uint8_t data[0];
 }luat_airlink_cmd_t;
 
+int luat_airlink_init(void);
 int luat_airlink_start(int id);
-
 int luat_airlink_stop(int id);
 
 void luat_airlink_data_pack(uint8_t* buff, size_t len, uint8_t* dst);
@@ -47,4 +47,37 @@ int luat_airlink_cmd_recv_simple(airlink_queue_item_t* cmd);
 
 int luat_airlink_queue_send_ippkg(uint8_t adapter_id, uint8_t* data, size_t len);
 
+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);
+
+typedef struct luat_airlink_dev_wifi_info {
+    uint8_t sta_mac[6];
+    uint8_t ap_mac[6];
+    uint8_t bt_mac[6];
+    uint8_t sta_state;
+    uint8_t ap_state;
+}luat_airlink_dev_wifi_info_t;
+
+typedef struct luat_airlink_dev_cat_info {
+    uint8_t ipv4[4];
+    uint8_t ipv6[16];
+    uint8_t cat_state;
+    uint8_t sim_state;
+    uint8_t imei[16];
+    uint8_t iccid[20];
+    uint8_t imsi[16];
+}luat_airlink_dev_wifi_cat_t;
+
+typedef struct luat_airlink_dev_info
+{
+    uint8_t tp;
+    union
+    {
+        luat_airlink_dev_wifi_info_t wifi;
+        luat_airlink_dev_wifi_cat_t cat1;
+    };
+    uint8_t unique_id_len;
+    uint8_t unique_id[24];
+}luat_airlink_dev_info_t;
+
 #endif

+ 170 - 50
components/airlink/src/luat_airlink.c

@@ -5,6 +5,9 @@
 #include "luat_mem.h"
 #include "luat_rtos.h"
 #include "luat_crypto.h"
+#include "luat_netdrv.h"
+#include "luat_netdrv_whale.h"
+#include "lwip/prot/ethernet.h"
 
 #define LUAT_LOG_TAG "airlink"
 #include "luat_log.h"
@@ -12,33 +15,68 @@
 luat_rtos_queue_t airlink_cmd_queue;
 luat_rtos_queue_t airlink_ippkg_queue;
 
-int luat_airlink_start(int id) {
-    if (airlink_cmd_queue == NULL) {
+extern int luat_airlink_start_slave(void);
+extern int luat_airlink_start_master(void);
+
+int luat_airlink_init(void)
+{
+    luat_netdrv_whale_t cfg = {0};
+    luat_netdrv_t *drv = NULL;
+    // 注册2个网络设备, STA和AP
+    cfg.id = NW_ADAPTER_INDEX_LWIP_WIFI_STA;
+    cfg.flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6;
+    cfg.mtu = 1460;
+    drv = luat_netdrv_whale_create(&cfg);
+    if (drv != NULL)
+    {
+        // LLOGD("注册STA网络设备");
+        luat_netdrv_register(cfg.id, drv);
+    }
+
+    // AP设备
+    cfg.id = NW_ADAPTER_INDEX_LWIP_WIFI_AP;
+    drv = luat_netdrv_whale_create(&cfg);
+    if (drv != NULL)
+    {
+        // LLOGD("注册AP网络设备");
+        luat_netdrv_register(cfg.id, drv);
+    }
+    return 0;
+}
+
+int luat_airlink_start(int id)
+{
+    if (airlink_cmd_queue == NULL)
+    {
         luat_rtos_queue_create(&airlink_cmd_queue, 2048, sizeof(airlink_queue_item_t));
     }
-    if (airlink_ippkg_queue == NULL) {
+    if (airlink_ippkg_queue == NULL)
+    {
         luat_rtos_queue_create(&airlink_ippkg_queue, 2048, sizeof(airlink_queue_item_t));
     }
-    if (id == 0) {
-        extern int luat_airlink_start_slave(void);
+    if (id == 0)
+    {
         luat_airlink_start_slave();
     }
-    else {
-        extern int luat_airlink_start_master(void);
+    else
+    {
         luat_airlink_start_master();
     }
     return 0;
 }
 
-int luat_airlink_stop(int id) {
+int luat_airlink_stop(int id)
+{
     return 0;
 }
 
-void luat_airlink_data_unpack(uint8_t* buff, size_t len, size_t* pkg_offset, size_t* pkg_size) {
+void luat_airlink_data_unpack(uint8_t *buff, size_t len, size_t *pkg_offset, size_t *pkg_size)
+{
     size_t tlen = 0;
     uint16_t crc16 = 0;
     uint16_t crc16_data = 0;
-    if (len < 12) {
+    if (len < 12)
+    {
         *pkg_offset = 0;
         *pkg_size = 0;
         return;
@@ -49,31 +87,35 @@ void luat_airlink_data_unpack(uint8_t* buff, size_t len, size_t* pkg_offset, siz
         if (buff[i] == 0xA1 && buff[i + 1] == 0xB1 && buff[i + 2] == 0xCA && buff[i + 3] == 0x66)
         {
             // 找到了magic
-            tlen = buff[i + 4] + buff[i+5] * 256;
-            crc16 = buff[i + 6] + buff[i+7] * 256;
-            LLOGD("找到magic, 且数据长度为 %d", tlen);
-            if (tlen > 0 && tlen + 4 + i + 4 <= len) {
+            tlen = buff[i + 4] + buff[i + 5] * 256;
+            crc16 = buff[i + 6] + buff[i + 7] * 256;
+            // LLOGD("找到magic, 且数据长度为 %d", tlen);
+            if (tlen > 0 && tlen + 4 + i + 4 <= len)
+            {
                 // 计算crc16
                 crc16_data = luat_crc16(buff + i + 4 + 4, tlen, 0xFFFF, 0x1021, 0);
-                if (crc16_data == crc16) {
-                    LLOGD("crc16校验成功");
+                if (crc16_data == crc16)
+                {
+                    // LLOGD("crc16校验成功");
                     *pkg_offset = i + 4 + 4;
                     *pkg_size = tlen;
                     return;
                 }
-                else {
+                else
+                {
                     LLOGD("crc16校验失败 %d %d", crc16_data, crc16);
                 }
             }
-            else {
+            else
+            {
                 LLOGD("数据长度错误");
             }
         }
     }
-    
 }
 
-void luat_airlink_data_pack(uint8_t* buff, size_t len, uint8_t* dst) {
+void luat_airlink_data_pack(uint8_t *buff, size_t len, uint8_t *dst)
+{
     // 先写入magic
     dst[0] = 0xA1;
     dst[1] = 0xB1;
@@ -92,28 +134,34 @@ void luat_airlink_data_pack(uint8_t* buff, size_t len, uint8_t* dst) {
     memcpy(dst + 8, buff, len);
 }
 
-void luat_airlink_print_buff(const char* tag, uint8_t* buff, size_t len) {
+void luat_airlink_print_buff(const char *tag, uint8_t *buff, size_t len)
+{
     static char tmpbuff[1024] = {0};
-    for (size_t i = 0; i < len; i+=8)
+    for (size_t i = 0; i < len; i += 8)
     {
         // sprintf(tmpbuff + i * 2, "%02X", buff[i]);
         // LLOGD("SPI TX[%d] 0x%02X", i, buff[i]);
-        LLOGD("%s [%04X-%04X] %02X%02X%02X%02X%02X%02X%02X%02X", tag, i, i + 8, 
-            buff[i+0], buff[i+1], buff[i+2], buff[i+3], 
-            buff[i+4], buff[i+5], buff[i+6], buff[i+7]);
+        LLOGD("%s [%04X-%04X] %02X%02X%02X%02X%02X%02X%02X%02X", tag, i, i + 8,
+              buff[i + 0], buff[i + 1], buff[i + 2], buff[i + 3],
+              buff[i + 4], buff[i + 5], buff[i + 6], buff[i + 7]);
     }
     // LLOGD("SPI0 %s", tmpbuff);
 }
 
-int luat_airlink_queue_send(int tp, airlink_queue_item_t* item) {
-    if (tp == LUAT_AIRLINK_QUEUE_CMD) {
-        if (airlink_cmd_queue == NULL) {
+int luat_airlink_queue_send(int tp, airlink_queue_item_t *item)
+{
+    if (tp == LUAT_AIRLINK_QUEUE_CMD)
+    {
+        if (airlink_cmd_queue == NULL)
+        {
             return -1;
         }
         return luat_rtos_queue_send(airlink_cmd_queue, item, 0, 0);
     }
-    if (tp == LUAT_AIRLINK_QUEUE_IPPKG) {
-        if (airlink_ippkg_queue == NULL) {
+    if (tp == LUAT_AIRLINK_QUEUE_IPPKG)
+    {
+        if (airlink_ippkg_queue == NULL)
+        {
             return -1;
         }
         return luat_rtos_queue_send(airlink_ippkg_queue, item, 0, 0);
@@ -121,37 +169,48 @@ int luat_airlink_queue_send(int tp, airlink_queue_item_t* item) {
     return -2;
 }
 
-int luat_airlink_queue_get_cnt(int tp) {
+int luat_airlink_queue_get_cnt(int tp)
+{
     size_t len = 0;
     int ret = -2;
-    if (tp == LUAT_AIRLINK_QUEUE_CMD) {
-        if (airlink_cmd_queue == NULL) {
+    if (tp == LUAT_AIRLINK_QUEUE_CMD)
+    {
+        if (airlink_cmd_queue == NULL)
+        {
             return -1;
         }
         ret = luat_rtos_queue_get_cnt(airlink_cmd_queue, &len);
     }
-    if (tp == LUAT_AIRLINK_QUEUE_IPPKG) {
-        if (airlink_ippkg_queue == NULL) {
+    if (tp == LUAT_AIRLINK_QUEUE_IPPKG)
+    {
+        if (airlink_ippkg_queue == NULL)
+        {
             return -1;
         }
         ret = luat_rtos_queue_get_cnt(airlink_ippkg_queue, &len);
     }
-    if (ret) {
+    if (ret)
+    {
         return ret;
     }
     return len;
 }
 
-int luat_airlink_cmd_recv(int tp, airlink_queue_item_t* item, size_t timeout) {
+int luat_airlink_cmd_recv(int tp, airlink_queue_item_t *item, size_t timeout)
+{
     int ret = -2;
-    if (tp == LUAT_AIRLINK_QUEUE_CMD) {
-        if (airlink_cmd_queue == NULL) {
+    if (tp == LUAT_AIRLINK_QUEUE_CMD)
+    {
+        if (airlink_cmd_queue == NULL)
+        {
             return -1;
         }
         ret = luat_rtos_queue_recv(airlink_cmd_queue, item, 0, timeout);
     }
-    if (tp == LUAT_AIRLINK_QUEUE_IPPKG) {
-        if (airlink_ippkg_queue == NULL) {
+    if (tp == LUAT_AIRLINK_QUEUE_IPPKG)
+    {
+        if (airlink_ippkg_queue == NULL)
+        {
             return -1;
         }
         ret = luat_rtos_queue_recv(airlink_ippkg_queue, item, 0, timeout);
@@ -159,16 +218,35 @@ int luat_airlink_cmd_recv(int tp, airlink_queue_item_t* item, size_t timeout) {
     return ret;
 }
 
-int luat_airlink_queue_send_ippkg(uint8_t adapter_id, uint8_t* data, size_t len) {
-    if (len < 8) {
-        // LLOGE("数据包太小了, 抛弃掉");
+int luat_airlink_queue_send_ippkg(uint8_t adapter_id, uint8_t *data, size_t len)
+{
+    if (len < 8)
+    {
+        LLOGE("数据包太小了, 抛弃掉");
         return -1;
     }
+    luat_netdrv_t* netdrv = luat_netdrv_get(adapter_id);
+    if (netdrv == NULL || netdrv->netif == NULL) {
+        LLOGW("应该是BUG了, netdrv为空或者没有netif %d", adapter_id);
+        return -2;
+    }
+    struct eth_hdr* eth = (struct eth_hdr*)data;
+    if (netdrv->netif->flags & NETIF_FLAG_ETHARP) {
+        if (eth->type == PP_HTONS(ETHTYPE_IP) || eth->type == PP_HTONS(ETHTYPE_ARP)) {
+            // LLOGD("是ARP/IP包,继续转发");
+        }
+        else {
+            // LLOGD("不是ARP/IP包,丢弃掉");
+            return -3;
+        }
+    }
+
     airlink_queue_item_t item = {
         .len = len + 5,
         .cmd = luat_heap_malloc(len + 8),
     };
-    if (item.cmd == NULL) {
+    if (item.cmd == NULL)
+    {
         return -2;
     }
     memcpy(item.cmd->data + 1, data, len);
@@ -179,22 +257,64 @@ int luat_airlink_queue_send_ippkg(uint8_t adapter_id, uint8_t* data, size_t len)
     return 0;
 }
 
-int luat_airlink_cmd_recv_simple(airlink_queue_item_t* cmd) {
+int luat_airlink_cmd_recv_simple(airlink_queue_item_t *cmd)
+{
     // 看待发送队列里有没有数据, 有就发送
     int ret = luat_airlink_queue_get_cnt(LUAT_AIRLINK_QUEUE_CMD);
     // LLOGD("待发送CMD队列长度 %d", ret);
     airlink_queue_item_t item = {0};
-    if (ret > 0) {
+    if (ret > 0)
+    {
         ret = luat_airlink_cmd_recv(LUAT_AIRLINK_QUEUE_CMD, &item, 0);
     }
-    else {
+    else
+    {
         ret = luat_airlink_queue_get_cnt(LUAT_AIRLINK_QUEUE_IPPKG);
         // LLOGD("待发送IPPKG队列长度 %d", ret);
-        if (ret > 0) {
+        if (ret > 0)
+        {
             ret = luat_airlink_cmd_recv(LUAT_AIRLINK_QUEUE_IPPKG, &item, 0);
-            LLOGD("获取到IP数据包 %d %p", ret, item.cmd);
+            // LLOGD("从队列获取到IP数据包 %d %p", item.len, item.cmd);
+            // luat_airlink_hexdump("从队列获取到IP数据包", item.cmd->data + 1, item.len - 1);
         }
     }
     memcpy(cmd, &item, sizeof(airlink_queue_item_t));
     return 0;
 }
+
+void luat_airlink_print_mac_pkg(uint8_t* buff, uint16_t len) {
+    if (len < 24 || len > 1600) {
+        LLOGW("非法的pkg长度 %d", len);
+        return;
+    }
+    LLOGD("pkg len %d 前24个字节 " MACFMT MACFMT MACFMT MACFMT, len, MAC_ARG(buff), MAC_ARG(buff + 6), MAC_ARG(buff+12), MAC_ARG(buff + 18));
+    
+    struct eth_hdr* eth = (struct eth_hdr*)buff;
+    struct ip_hdr* iphdr = (struct ip_hdr*)(buff + SIZEOF_ETH_HDR);
+    struct etharp_hdr* arp = (struct etharp_hdr*)(buff + SIZEOF_ETH_HDR);
+    // LLOGD("eth " MACFMT " -> " MACFMT " tp %02X", MAC_ARG(eth->src.addr), MAC_ARG(eth->dest.addr), (u16_t)lwip_htons(eth->type));
+    switch (eth->type) {
+        case PP_HTONS(ETHTYPE_IP):
+            // LLOGD("  ipv%d %d len %d", (u16_t)IPH_V(iphdr), (u16_t)IPH_PROTO(iphdr),(u16_t)IPH_LEN(iphdr));
+            break;
+        case PP_HTONS(ETHTYPE_ARP):
+            // LLOGD("  arp proto %d", arp->proto);
+            break;
+    }
+}
+
+void luat_airlink_hexdump(const char* tag, uint8_t* buff, uint16_t len) {
+    if (len > 500) {
+        len = 500;
+    }
+    uint8_t* tmp = luat_heap_opt_zalloc(LUAT_HEAP_PSRAM, len * 2 + 1);
+    if (tmp == NULL) {
+        return;
+    }
+    for (size_t i = 0; i < len; i++)
+    {
+        sprintf((char*)(tmp + i * 2), "%02X", buff[i]);
+    }
+    LLOGD("%s %s", tag, tmp);
+    luat_heap_opt_free(LUAT_HEAP_PSRAM, tmp);
+}

+ 3 - 0
components/airlink/src/luat_airlink_cmds.c

@@ -24,6 +24,7 @@ CMD_DEFINE(reset);
 CMD_DEFINE(fota_init);
 CMD_DEFINE(fota_write);
 CMD_DEFINE(fota_done);
+CMD_DEFINE(dev_info);
 
 // MAC和IP包指令, 0x100开始
 CMD_DEFINE(ip_pkg);
@@ -48,6 +49,8 @@ luat_airlink_cmd_reg_t airlink_cmds[] = {
     // CMD_REG(0x05, fota_write),
     // CMD_REG(0x06, fota_done),
 
+    CMD_REG(0x10, dev_info),
+
     CMD_REG(0x100, ip_pkg),
     // CMD_REG(0x101, set_mac),
     // CMD_REG(0x102, link_up),

+ 73 - 0
components/airlink/src/luat_airlink_cmds_info.c

@@ -0,0 +1,73 @@
+#include "luat_base.h"
+#include "luat_spi.h"
+#include "luat_airlink.h"
+
+
+#include "luat_rtos.h"
+#include "luat_debug.h"
+#include "luat_spi.h"
+#include "luat_pm.h"
+#include "luat_gpio.h"
+#include "luat_airlink.h"
+#include "luat_fota.h"
+#include "luat_netdrv.h"
+#include "luat_network_adapter.h"
+#include "lwip/netif.h"
+#include "lwip/pbuf.h"
+#include "luat_netdrv_whale.h"
+
+#define LUAT_LOG_TAG "airlink"
+#include "luat_log.h"
+
+luat_airlink_dev_info_t airlink_ext_dev_info;
+
+int luat_airlink_cmd_exec_dev_info(luat_airlink_cmd_t* cmd, void* userdata) {
+    luat_airlink_dev_info_t* dev = cmd->data;
+    luat_netdrv_t* drv = NULL;
+    // LLOGD("收到设备信息通知 类型 %d", dev->tp);
+    if (dev->tp == 0) {
+        return 0;
+    }
+    memcpy(&airlink_ext_dev_info, dev, sizeof(luat_airlink_dev_info_t));
+    if (dev->tp == 1) {
+        // WIFI设备
+        // 首先, 把MAC地址打印出来
+        // LLOGD("wifi sta MAC %02X:%02X:%02X:%02X:%02X:%02X", dev->wifi.sta_mac[0], dev->wifi.sta_mac[1], dev->wifi.sta_mac[2], dev->wifi.sta_mac[3], dev->wifi.sta_mac[4], dev->wifi.sta_mac[5]);
+        if (dev->wifi.sta_mac[0]) {
+            // 是合法的MAC地址, 那就搞一下
+            drv = luat_netdrv_get(NW_ADAPTER_INDEX_LWIP_WIFI_STA);
+            while (1) {
+                if (drv == NULL) {
+                    LLOGD("没有找到lwip wifi sta驱动, 无法设置MAC地址");
+                    break;
+                }
+                if (drv->netif == NULL) {
+                    LLOGD("没有找到lwip wifi sta接口, 无法设置MAC地址");
+                    break;
+                }
+                memcpy(drv->netif->hwaddr, dev->wifi.sta_mac, 6);
+                drv->netif->hwaddr_len = 6;
+
+                // 网络状态对吗?
+                if (dev->wifi.sta_state == 0) {
+                    if (netif_is_up(drv->netif)) {
+                        // 网卡掉线了哦
+                        LLOGD("wifi sta掉线了, 重新连接");
+                        netif_set_down(drv->netif);
+                        luat_netdrv_whale_ipevent(drv->id);
+                    }
+                }
+                else {
+                    if (netif_is_up(drv->netif) == 0) {
+                        // 网卡上线了哦
+                        LLOGD("wifi sta上线了");
+                        netif_set_up(drv->netif);
+                        luat_netdrv_whale_ipevent(drv->id);
+                    }
+                }
+                break;
+            }
+        }
+    }
+    return 0;
+}

+ 7 - 4
components/airlink/src/luat_airlink_cmds_ippkg.c

@@ -12,13 +12,16 @@
 #include "luat_fota.h"
 #include "luat_netdrv.h"
 #include "luat_netdrv_napt.h"
+#include "luat_network_adapter.h"
 
 #define LUAT_LOG_TAG "airlink"
 #include "luat_log.h"
 
 int luat_airlink_cmd_exec_ip_pkg(luat_airlink_cmd_t* cmd, void* userdata) {
     uint8_t adapter_id = cmd->data[0];
-    LLOGD("收到IP包 长度 %d 适配器 %d", cmd->len - 1, adapter_id);
+    // LLOGD("收到IP包 长度 %d 适配器 %d", cmd->len - 1, adapter_id);
+    // luat_airlink_print_mac_pkg(cmd->data + 1, cmd->len - 1);
+    // luat_airlink_hexdump("收到IP包", cmd->data + 1, cmd->len - 1);
     // 首先, NAPT处理一下
     int ret = 0;
     luat_netdrv_t* drv = NULL;
@@ -35,14 +38,14 @@ int luat_airlink_cmd_exec_ip_pkg(luat_airlink_cmd_t* cmd, void* userdata) {
     }
     
     // 这里开始就复杂了
-    // 首先, 这是不是平台的包, 如果是, 那就直接交给平台处理
+    // 首先, 如果是平台的包, 那就直接交给平台处理
     //      例如wifi的包, 在wifi平台, 那就应该输出到硬件去
     // 否则, 那就应该转给lwip处理
     #ifdef __BK72XX__
     if (drv->id == NW_ADAPTER_INDEX_LWIP_WIFI_STA || drv->id == NW_ADAPTER_INDEX_LWIP_WIFI_AP) {
         // 这里是wifi的包, 直接输出到硬件去
-        LLOGD("收到wifi的IP包, 直接输出到硬件去 %p %d", buff, len);
-        drv->dataout(drv, buff, len);
+        // LLOGD("收到wifi的IP包, 直接输出到硬件去 %p %d", cmd->data + 1, cmd->len - 1);
+        drv->dataout(drv, drv->userdata, cmd->data + 1, cmd->len - 1);
         return 0;
     }
     #endif

+ 16 - 10
components/airlink/src/luat_airlink_spi_master_task.c

@@ -10,6 +10,7 @@
 #include "luat_gpio.h"
 #include "luat_airlink.h"
 #include "luat_mem.h"
+#include "luat_mcu.h"
 
 #define LUAT_LOG_TAG "airlink"
 #include "luat_log.h"
@@ -91,7 +92,7 @@ static void spi_gpio_setup(void) {
     gpio_cfg.pin = TEST_RDY_PIN;
     gpio_cfg.mode = LUAT_GPIO_IRQ;
     gpio_cfg.irq_type = LUAT_GPIO_FALLING_IRQ;
-    gpio_cfg.pull = LUAT_GPIO_PULLUP;
+    gpio_cfg.pull = 0;
     gpio_cfg.irq_cb = slave_rdy_irq;
     luat_gpio_open(&gpio_cfg);
     LLOGD(" gpio rdy setup done %d", TEST_RDY_PIN);
@@ -121,28 +122,33 @@ static void spi_master_task(void *param)
     spi_gpio_setup();
     thread_rdy = 1;
 
-    const char* test_data = "123456789";
-    luat_airlink_data_pack((uint8_t*)test_data, strlen(test_data), basic_info);
+    // const char* test_data = "123456789";
+    // luat_airlink_data_pack((uint8_t*)test_data, strlen(test_data), basic_info);
     // luat_airlink_print_buff("TX", txbuff, 16);
-
+    // uint64_t tprev = 0;
+    // uint64_t tnow = 0;
     while (1)
     {
         // 等到消息
         event.id = 0;
         item.len = 0;
-        luat_rtos_event_recv(spi_task_handle, 0, &event, NULL, 5000);
+        luat_rtos_event_recv(spi_task_handle, 0, &event, NULL, 10);
         luat_airlink_cmd_recv_simple(&item);
         if (item.len == 0 && event.id == 0) {
-            // LLOGD("啥都没等到, 继续等");
-            continue; // 无事发生,继续等下一个事件.
+            // // LLOGD("啥都没等到, 继续等");
+            // tnow = luat_mcu_tick64_ms();
+            // if (tnow - tprev < 1000) {
+            //     continue; // 无事发生,继续等下一个事件.
+            // }
+            // tprev = tnow;
         }
         if (item.len > 0 && item.cmd != NULL) {
-            LLOGD("发送待传输的数据, 塞入SPI的FIFO %d", item.len);
+            // LLOGD("发送待传输的数据, 塞入SPI的FIFO %d", item.len);
             luat_airlink_data_pack(item.cmd, item.len, txbuff);
             luat_heap_free(item.cmd);
         }
         else {
-            LLOGD("填充PING数据");
+            // LLOGD("填充PING数据");
             luat_airlink_data_pack(basic_info, sizeof(basic_info), txbuff);
         }
         slave_rdy = 0;
@@ -155,7 +161,7 @@ static void spi_master_task(void *param)
                 luat_rtos_task_sleep(1);
                 continue;
             }
-            LLOGD("从机已就绪!! %s %s", __DATE__, __TIME__);
+            // LLOGD("从机已就绪!! %s %s", __DATE__, __TIME__);
             break;
         }
         

+ 5 - 6
components/airlink/src/luat_airlink_task.c

@@ -26,33 +26,32 @@ static int luat_airlink_task(void *param) {
     LLOGD("处理线程启动");
     luat_event_t event;
     luat_airlink_cmd_t* ptr = NULL;
-    size_t len = 0;
+    // size_t len = 0;
     luat_airlink_cmd_reg_t* cmd_reg = NULL;
     while (1) {
         luat_rtos_event_recv(airlink_task_handle, 0, &event, NULL, LUAT_WAIT_FOREVER);
         if (event.id == 1) { // 收到数据了, 马上处理
             // 处理数据
             ptr = (void*)event.param1;
-            len = event.param2;
+            // len = event.param2;
             if (ptr == NULL) {
                 LLOGW("空指令!");
                 continue;
             }
             // TODO 真正的处理逻辑
-            LLOGD("收到指令/回复 cmd %d len %d", ptr->cmd, len);
+            // LLOGD("收到指令/回复 cmd %d len %d", ptr->cmd, len);
             cmd_reg = airlink_cmds;
             while (1) {
                 if (cmd_reg->id == 0) {
                     break;
                 }
                 if (cmd_reg->id == ptr->cmd) {
-                    LLOGI("找到CMD执行程序 %p", cmd_reg->exec);
+                    // LLOGI("找到CMD执行程序 %p", cmd_reg->exec);
                     cmd_reg->exec(ptr, NULL);
                     break;
                 }
                 cmd_reg ++;
             }
-            
 
             // 处理完成, 释放内存
             luat_heap_opt_free(LUAT_HEAP_PSRAM, ptr);
@@ -63,7 +62,7 @@ static int luat_airlink_task(void *param) {
 
 void luat_airlink_task_start(void) {
     if (airlink_task_handle == NULL) {
-        luat_rtos_task_create(&airlink_task_handle, 8 * 1024, 20, "airlink", luat_airlink_task, NULL, 1024);
+        luat_rtos_task_create(&airlink_task_handle, 8 * 1024, 50, "airlink", luat_airlink_task, NULL, 1024);
     }
     else {
         LLOGD("airlink task 已经启动过了");

+ 1 - 1
components/network/netdrv/binding/luat_lib_netdrv.c

@@ -99,7 +99,7 @@ static int l_netdrv_mac(lua_State *L) {
     char buff[6] = {0};
     char tmpbuff[13] = {0};
     size_t len = 0;
-    if (lua_isstring(L, 2)) {
+    if (lua_type(L, 2) == LUA_TSTRING) {
         const char* tmp = luaL_checklstring(L, 2, &len);
         if (len != 6) {
             return 0;

+ 12 - 0
components/network/netdrv/include/luat_netdrv_whale.h

@@ -6,8 +6,20 @@
 #include "lwip/pbuf.h"
 #include "luat_ulwip.h"
 
+typedef struct luat_netdrv_whale {
+    uint8_t id;
+    void* userdata;
+    uint8_t flags;
+    uint16_t mtu;
+    uint8_t mac[6];
+}luat_netdrv_whale_t;
+
 
 void luat_netdrv_whale_dataout(luat_netdrv_t* drv, void* userdata, uint8_t* buff, uint16_t len);
 void luat_netdrv_whale_boot(luat_netdrv_t* drv, void* userdata);
 
+luat_netdrv_t* luat_netdrv_whale_create(luat_netdrv_whale_t* cfg);
+
+void luat_netdrv_whale_ipevent(int id);
+
 #endif

+ 5 - 1
components/network/netdrv/src/luat_netdrv.c

@@ -6,6 +6,7 @@
 #include "luat_netdrv_uart.h"
 #endif
 #include "luat_mem.h"
+#include "luat_airlink.h"
 
 #define LUAT_LOG_TAG "netdrv"
 #include "luat_log.h"
@@ -31,9 +32,12 @@ luat_netdrv_t* luat_netdrv_setup(luat_netdrv_conf_t *conf) {
     }
     else {
         if (drvs[conf->id]->boot) {
+            LLOGD("启动网络设备 %p", drvs[conf->id]);
             drvs[conf->id]->boot(drvs[conf->id], NULL);
+            return drvs[conf->id];
         }
     }
+    LLOGW("无效的注册id或类型 id=%d, type=%d", conf->id, conf->impl);
     return NULL;
 }
 
@@ -167,7 +171,7 @@ void luat_netdrv_netif_input(void* args) {
         return;
     }
     pbuf_take(p, ptr->buff, ptr->len);
-    // LLOGD("数据注入到netif " MACFMT, MAC_ARG(p->payload));
+    // luat_airlink_hexdump("收到IP数据,注入到netif", ptr->buff, ptr->len);
     int ret = ptr->netif->input(p, ptr->netif);
     if (ret) {
         pbuf_free(p);

+ 70 - 18
components/network/netdrv/src/luat_netdrv_whale.c

@@ -12,6 +12,8 @@
 #include "net_lwip2.h"
 #include "luat_airlink.h"
 #include "luat_mem.h"
+#include "luat_netdrv_whale.h"
+#include "luat_ulwip.h"
 
 #define LUAT_LOG_TAG "netdrv.whale"
 #include "luat_log.h"
@@ -22,23 +24,30 @@ static int netif_ip_event_cb(lua_State *L, void* ptr);
 
 void luat_netdrv_whale_dataout(luat_netdrv_t* drv, void* userdata, uint8_t* buff, uint16_t len) {
     // TODO 发送到spi slave task
-    LLOGD("上行给主机的IP数据 %p %d", buff, len);
+    // LLOGD("上行给主机的IP数据 %p %d", buff, len);
     if (len < 0) {
         return;
     }
-    luat_netdrv_t* netdrv = (luat_netdrv_t*)userdata;
-    luat_airlink_queue_send_ippkg(netdrv->id, buff, len);
+    // TODO 这里应该根据userdata, 也就是whale上下文, 转发可配置的出口
+    luat_airlink_queue_send_ippkg(drv->id, buff, len);
 }
 
 static err_t netif_output(struct netif *netif, struct pbuf *p) {
     // TODO 发送到spi slave task
-    LLOGD("上行给主机的IP数据 %p %d", p, p->tot_len);
+    // LLOGD("上行给主机的IP数据2 %p %d", p, p->tot_len);
+    // LLOGD("上行给主机的IP数据 前24个字节 " MACFMT "" MACFMT "" MACFMT "" MACFMT, 
+    //         MAC_ARG(p->payload), 
+    //         MAC_ARG(p->payload + 6), 
+    //         MAC_ARG(p->payload + 12), 
+    //         MAC_ARG(p->payload + 18));
     luat_netdrv_t* netdrv = (luat_netdrv_t*)(netif->state);
     void* buff = luat_heap_opt_zalloc(LUAT_HEAP_PSRAM, p->tot_len);
     if (buff == NULL) {
         return ERR_MEM;
     }
     pbuf_copy_partial(p, buff, p->tot_len, 0);
+    // luat_airlink_hexdump("准备上行给硬件协议栈的IP数据", buff, p->tot_len);
+    // TODO 这里应该根据userdata, 也就是whale上下文, 转发可配置的出口
     luat_airlink_queue_send_ippkg(netdrv->id, buff, p->tot_len);
     luat_heap_opt_free(LUAT_HEAP_PSRAM, buff);
     return 0;
@@ -57,9 +66,6 @@ static err_t netif_output_ip6(struct netif *netif, struct pbuf *p, const ip6_add
 #endif
 
 void luat_netdrv_whale_boot(luat_netdrv_t* drv, void* userdata) {
-    if (userdata == NULL) {
-        return;
-    }
     luat_netdrv_t* netdrv = drv;
     // 首先, 初始化netif
     if (netdrv->netif == NULL) {
@@ -69,17 +75,48 @@ void luat_netdrv_whale_boot(luat_netdrv_t* drv, void* userdata) {
 
     netif_add(netdrv->netif, IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY, netdrv, luat_netif_init, netif_input);
 
-    // 网卡设置成可用状态
-    netif_set_up(netdrv->netif);
+    // 网卡设置成可用状态
+    // netif_set_up(netdrv->netif);
     netif_set_link_up(netdrv->netif);
     net_lwip2_set_netif(netdrv->id, netdrv->netif);
     net_lwip2_register_adapter(netdrv->id);
-    LLOGD("luat_netif_init 执行完成");
+    // LLOGD("luat_netif_init 执行完成");
 }
 
 static err_t luat_netif_init(struct netif *netif) {
+    luat_netdrv_t* drv = (luat_netdrv_t*)netif->state;
+    // LLOGD("luat_netif_init 执行drv %p", drv);
+    luat_netdrv_whale_t* cfg = (luat_netdrv_whale_t*)drv->userdata;
+    // LLOGD("luat_netif_init 执行cfg %p", cfg);
+    // 先配置MTU和flags
+    // 暂时写死MTU
+    // 暂时写死flags
+    netif->mtu        = 1420;
+    netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
+    // if (0 == cfg->mtu) {
+    //     netif->mtu        = 1420;
+    // }
+    // else{
+    //     netif->mtu = cfg->mtu;
+    // }
+    // if (0 == cfg->flags) {
+    //     netif->flags      = NETIF_FLAG_BROADCAST;
+    // }
+    // else {
+    //     netif->flags = cfg->flags;
+    // }
+    if (netif->flags & NETIF_FLAG_ETHARP) {
+        netif->hwaddr_len = 6;
+        memcpy(netif->hwaddr, cfg->mac, 6);
+    }
+
     netif->linkoutput = netif_output;
-    netif->output     = netif_ip4_output;
+    if (netif->flags & NETIF_FLAG_ETHARP) {
+        netif->output = ulwip_etharp_output;
+    }
+    else {
+        netif->output = netif_ip4_output;
+    }
     #if ENABLE_PSIF
     netif->primary_ipv4_cid = LWIP_PS_INVALID_CID;
     #endif
@@ -89,12 +126,6 @@ static err_t luat_netif_init(struct netif *netif) {
     netif->primary_ipv6_cid = LWIP_PS_INVALID_CID;
     #endif
     #endif
-    if (netif->mtu == 0) {
-        netif->mtu        = 1420;
-    }
-    if (netif->flags == 0) {
-        netif->flags      = NETIF_FLAG_BROADCAST;
-    }
     return 0;
 }
 
@@ -126,4 +157,25 @@ void luat_netdrv_whale_ipevent(int id) {
     msg.ptr = NULL;
     msg.handler = netif_ip_event_cb;
     luat_msgbus_put(&msg, 0);
-}
+}
+
+
+luat_netdrv_t* luat_netdrv_whale_create(luat_netdrv_whale_t* tmp) {
+    // LLOGD("创建Whale设备");
+    luat_netdrv_t* netdrv = luat_heap_malloc(sizeof(luat_netdrv_t));
+    if (netdrv == NULL) {
+        return NULL;
+    }
+    // 把配置信息拷贝一份
+    luat_netdrv_whale_t* cfg = luat_heap_malloc(sizeof(luat_netdrv_whale_t));
+    memcpy(cfg, tmp, sizeof(luat_netdrv_whale_t));
+
+    // 初始化netdrv
+    memset(netdrv, 0, sizeof(luat_netdrv_t));
+    netdrv->id = cfg->id;
+    netdrv->netif = NULL;
+    netdrv->dataout = luat_netdrv_whale_dataout;
+    netdrv->boot = luat_netdrv_whale_boot;
+    netdrv->userdata = cfg;
+    return netdrv;
+}

+ 32 - 1
demo/airlink/air780epm/main.lua

@@ -10,8 +10,39 @@ _G.sys = require("sys")
 _G.sysplus = require("sysplus")
 
 sys.taskInit(function()
-    sys.wait(500)
+    -- 设置电平, 关闭小核的供电
+    pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
+    gpio.setup(23, 0) -- 关闭Air8000S的LDO供电
+    sys.wait(100)
+    -- 初始化airlink
+    airlink.init()
+    log.info("注册STA和AP设备")
+    netdrv.setup(socket.LWIP_STA)
+    netdrv.setup(socket.LWIP_AP)
+    -- 启动底层线程, 从机模式
     airlink.start(1)
+    sys.wait(100)
+    log.info("打开Air8000S的LDO供电")
+    gpio.setup(23, 1) -- 打开Air8000S的LDO供电
+    log.info("一切就绪了")
+    sys.wait(5000)
+
+    netdrv.ipv4(socket.LWIP_STA, "192.168.1.35", "255.255.255.0", "192.168.1.1")
+
+    while 1 do
+        -- log.info("MAC地址", netdrv.mac(socket.LWIP_STA))
+        -- log.info("IP地址", netdrv.ipv4(socket.LWIP_STA))
+        -- log.info("ready?", netdrv.ready(socket.LWIP_STA))
+        sys.wait(5000)
+        log.info("执行http请求")
+        local code = http.request("GET", "http://192.168.1.15:8000/README.md", nil, nil, {adapter=socket.LWIP_STA,timeout=3000}).wait()
+        -- local code = http.request("GET", "http://112.125.89.8:42376/get", nil, nil, {adapter=socket.LWIP_STA,timeout=3000}).wait()
+        log.info("http执行结果", code, "=============================================")
+    end
+end)
+
+sys.subscribe("IP_READY", function(id, ip)
+    log.info("收到IP_READY!!", id, ip)
 end)
 
 -- 用户代码已结束---------------------------------------------

+ 10 - 8
demo/airlink/air8101/main.lua

@@ -10,8 +10,10 @@ _G.sys = require("sys")
 _G.sysplus = require("sysplus")
 
 sys.taskInit(function()
-    sys.wait(500)
+    -- sys.wait(500)
     airlink.start(0)
+    wlan.init()
+    wlan.connect("uiot", "12345678")
     -- log.info("设置静态IPV4")
     -- netdrv.ipv4(socket.LWIP_ETH, "192.168.1.129", "255.255.255.0", "192.168.1.1")
     -- log.info("ip", socket.localIP(socket.LWIP_ETH))
@@ -19,13 +21,13 @@ end)
 
 sys.taskInit(function()
     -- sys.waitUntil("IP_READY")
-    -- while 1 do
-    --     sys.wait(6000)
-    --     log.info("http", http.request("GET", "http://httpbin.air32.cn/bytes/2048", nil, nil, {adapter=socket.LWIP_ETH,timeout=3000}).wait())
-    --     log.info("lua", rtos.meminfo())
-    --     log.info("sys", rtos.meminfo("sys"))
-    --     log.info("ip", socket.localIP(socket.LWIP_ETH))
-    -- end
+    while 1 do
+        sys.wait(6000)
+        -- log.info("http", http.request("GET", "http://httpbin.air32.cn/bytes/2048", nil, nil, {adapter=socket.LWIP_ETH,timeout=3000}).wait())
+        log.info("lua", rtos.meminfo())
+        log.info("sys", rtos.meminfo("sys"))
+        -- log.info("ip", socket.localIP(socket.LWIP_ETH))
+    end
 end)
 
 -- 用户代码已结束---------------------------------------------