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

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

alienwalker 9 месяцев назад
Родитель
Сommit
79f3d5be81

+ 2 - 1
components/bluetooth/luat_bluetooth.c

@@ -175,7 +175,8 @@ static void luat_ble_cb(luat_bluetooth_t* luat_bluetooth, luat_ble_event_t ble_e
 
 int luat_ble_wlan_config_bk(luat_ble_wlan_config_info_t* config_info, luat_ble_cb_t luat_ble_wlan_config_cb){
     int ret = 0;
-    luat_bluetooth_t* luat_bluetooth = luat_bluetooth_init();
+    luat_bluetooth_t* luat_bluetooth = luat_heap_malloc(sizeof(luat_bluetooth_t));
+    luat_bluetooth_init(luat_bluetooth);
     luat_ble_init(luat_bluetooth, luat_ble_cb);
     luat_bluetooth->luat_ble->userdata = config_info;
     luat_bluetooth->luat_ble->wlan_config_cb = luat_ble_wlan_config_cb;

+ 13 - 1
components/bluetooth/luat_bluetooth.h

@@ -193,8 +193,18 @@ typedef enum{
     LUAT_BLE_ADV_ADDR_MODE_NRPA,     // 不可解析的私有地址
 }luat_ble_adv_addr_mode_t;
 
+typedef enum{
+    LUAT_BLE_ADV_CHNL_37    = 0x01, /**< Byte value for advertising channel map for channel 37 enable */
+    LUAT_BLE_ADV_CHNL_38    = 0x02, /**< Byte value for advertising channel map for channel 38 enable */
+    LUAT_BLE_ADV_CHNL_39    = 0x04, /**< Byte value for advertising channel map for channel 39 enable */
+    LUAT_BLE_ADV_CHNLS_ALL  = 0x07, /**< Byte value for advertising channel map for channel 37, 38 and 39 enable */
+}luat_ble_adv_chnl_t;
+
 typedef struct {
     luat_ble_adv_addr_mode_t addr_mode;
+    luat_ble_adv_chnl_t channel_map;
+    uint32_t intv_min;
+    uint32_t intv_max;
     int len;
 }luat_ble_adv_cfg_t;
 
@@ -202,6 +212,7 @@ typedef struct {
     luat_ble_actv_state state;
     luat_ble_cb_t cb;
     luat_ble_wlan_config_cb_t wlan_config_cb;
+    int lua_cb;
     void* userdata;
 }luat_ble_t;
 
@@ -212,6 +223,7 @@ typedef struct {
 typedef struct luat_bluetooth{
     luat_ble_t* luat_ble;
     luat_bt_t* luat_bt;
+    int bluetooth_ref;
 }luat_bluetooth_t;
 
 
@@ -250,7 +262,7 @@ int luat_bt_set_mac(luat_bluetooth_t* luat_bluetooth, uint8_t *addr, uint8_t len
 
 // bluetooth
 
-luat_bluetooth_t* luat_bluetooth_init(void);
+int luat_bluetooth_init(luat_bluetooth_t* luat_bluetooth);
 int luat_bluetooth_deinit(luat_bluetooth_t* luat_bluetooth);
 
 #endif

+ 338 - 0
components/bluetooth/luat_lib_bluetooth.c

@@ -0,0 +1,338 @@
+#include "luat_base.h"
+#include "luat_mem.h"
+#include "luat_rtos.h"
+#include "luat_msgbus.h"
+#include "luat_bluetooth.h"
+
+#include "luat_log.h"
+#define LUAT_LOG_TAG "bluetooth"
+
+#define LUAT_BLUETOOTH_TYPE "BLUETOOTH*"
+#define LUAT_BLE_TYPE "BLE*"
+
+static int luatos_ble_callback(lua_State *L, void* ptr){
+	(void)ptr;
+    rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
+    luat_bluetooth_t* luat_bluetooth =(luat_bluetooth_t *)msg->ptr;
+    luat_ble_event_t ble_event = (luat_ble_event_t)msg->arg1;
+    luat_ble_param_t* luat_ble_param = (luat_ble_param_t*)msg->arg2;
+
+    if (luat_bluetooth->luat_ble->lua_cb) {
+        lua_geti(L, LUA_REGISTRYINDEX, luat_bluetooth->luat_ble->lua_cb);
+        if (lua_isfunction(L, -1)) {
+            lua_geti(L, LUA_REGISTRYINDEX, luat_bluetooth->bluetooth_ref);
+            lua_pushinteger(L, ble_event);
+            lua_call(L, 2, 0);
+        }
+    }
+
+    switch(ble_event){
+        default:
+            break;
+    }
+    return 0;
+}
+
+static void luat_ble_cb(luat_bluetooth_t* luat_bluetooth, luat_ble_event_t ble_event, luat_ble_param_t* ble_param){
+    luat_ble_wlan_config_info_t* config_info = (luat_ble_wlan_config_info_t*)luat_bluetooth->luat_ble->userdata;
+    luat_ble_wlan_config_cb_t luat_ble_wlan_config_cb = luat_bluetooth->luat_ble->wlan_config_cb;
+    // LLOGD("ble event: %d", ble_event);
+
+    rtos_msg_t msg = {
+        .handler = luatos_ble_callback,
+        .ptr = (void*)luat_bluetooth,
+        .arg1 = (int)ble_event,
+        .arg2 = (int)ble_param,
+    };
+    luat_msgbus_put(&msg, 0);
+}
+
+
+static int l_bluetooth_create(lua_State* L) {
+    if (!lua_isuserdata(L, 1)){
+        return 0;
+    }
+    size_t len = 0;
+    luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t *)luaL_checkudata(L, 1, LUAT_BLUETOOTH_TYPE);
+    const char* type = luaL_checklstring(L, 2, &len);
+    if(memcmp("ble", type, len) == 0 || memcmp("BLE", type, len) == 0){
+        luat_ble_init(luat_bluetooth, luat_ble_cb);
+        int ble_param = lua_gettable(L, 2);
+        if (lua_gettable(L, 2) == LUA_TTABLE){
+            /* code */
+        }
+        
+    }else{
+        LLOGE("error type: %s", type);
+        return 0;
+    }
+    return 0;
+}
+
+static int l_bluetooth_create_ble(lua_State* L) {
+    if (!lua_isuserdata(L, 1)){
+        return 0;
+    }
+    luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t *)luaL_checkudata(L, 1, LUAT_BLUETOOTH_TYPE);
+    luat_ble_init(luat_bluetooth, luat_ble_cb);
+
+    if (lua_isfunction(L, 2)) {
+		lua_pushvalue(L, 2);
+		luat_bluetooth->luat_ble->lua_cb = luaL_ref(L, LUA_REGISTRYINDEX);
+	}
+
+    lua_pushboolean(L, 1);
+    return 1;
+}
+
+static int l_ble_gatt_create(lua_State* L) {
+    if (!lua_isuserdata(L, 1)){
+        return 0;
+    }
+    if (lua_type(L, 2) != LUA_TTABLE){
+        LLOGE("error param");
+        return 0;
+    }
+    size_t len = 0;
+    luat_ble_gatt_cfg_t luat_ble_gatt_cfg = {0};
+
+    luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t *)luaL_checkudata(L, 1, LUAT_BLUETOOTH_TYPE);
+
+    lua_pushstring(L, "uuid");
+    if (LUA_TSTRING == lua_gettable(L, -2)){
+        const char* data = luaL_checklstring(L, -1, &len);
+        memcpy(luat_ble_gatt_cfg.uuid, data, len);
+    }
+    lua_pop(L, 1);
+
+    lua_pushstring(L, "att_db");
+    if (LUA_TTABLE == lua_gettable(L, -2)){
+        luat_ble_gatt_cfg.att_db_num = luaL_len(L, -1);
+        luat_ble_gatt_cfg.att_db = (luat_ble_att_db_t*)luat_heap_malloc(sizeof(luat_ble_att_db_t) * luat_ble_gatt_cfg.att_db_num);
+        for (int i = 1; i <= luat_ble_gatt_cfg.att_db_num; i++) {
+            lua_rawgeti(L, -1, i);
+            int table_len = luaL_len(L, -1);
+            for (int j = 1; j <= table_len; j++){
+                lua_rawgeti(L, -1, j);
+
+                if (j == 1 && lua_type(L, -1) == LUA_TSTRING){
+                    const char* data = luaL_checklstring(L, -1, &len);
+                    memcpy(luat_ble_gatt_cfg.att_db[i-1].uuid, data, len);
+                }else if(j == 2 && lua_type(L, -1) == LUA_TNUMBER){
+                    luat_ble_gatt_cfg.att_db[i-1].perm = (uint16_t)luaL_optnumber(L, -1, 0);
+                }else if(j == 3 && lua_type(L, -1) == LUA_TNUMBER){
+                    luat_ble_gatt_cfg.att_db[i-1].ext_perm = (uint16_t)luaL_optnumber(L, -1, 0);
+                }else if(j == 4 && lua_type(L, -1) == LUA_TNUMBER){
+                    luat_ble_gatt_cfg.att_db[i-1].max_size = (uint16_t)luaL_optnumber(L, -1, 0);
+                }else{
+                    LLOGE("error att_db type");
+                    goto end; 
+                }
+                lua_pop(L, 1);
+            }
+            lua_pop(L, 1);
+        }
+    }
+    lua_pop(L, 1);
+    luat_ble_create_gatt(luat_bluetooth, &luat_ble_gatt_cfg);
+    luat_heap_free(luat_ble_gatt_cfg.att_db);
+
+    // if (lua_isfunction(L, 3)) {
+	// 	lua_pushvalue(L, 3);
+	// 	luat_bluetooth->luat_ble->lua_cb = luaL_ref(L, LUA_REGISTRYINDEX);
+	// }
+
+    lua_pushboolean(L, 1);
+    return 1;
+end:
+    return 0;
+}
+
+static int l_ble_advertising_create(lua_State* L) {
+    if (!lua_isuserdata(L, 1)){
+        return 0;
+    }
+    if (lua_type(L, 2) != LUA_TTABLE){
+        LLOGE("error param");
+        return 0;
+    }
+    luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t *)luaL_checkudata(L, 1, LUAT_BLUETOOTH_TYPE);
+    size_t len = 0;
+    // const char* complete_local_name = NULL;
+    // lua_pushstring(L, "name");
+    // if (LUA_TSTRING == lua_gettable(L, 2)) {
+    //     complete_local_name = luaL_checklstring(L, -1, &len);
+    // }else{
+    //     complete_local_name = (char* )luat_heap_malloc(32);
+    //     memset(complete_local_name, 0, 32);
+    //     sprintf_(complete_local_name, "LuatOS_%s", luat_os_bsp());
+    // }
+    // lua_pop(L, 1);
+
+    luat_ble_adv_cfg_t luat_ble_adv_cfg = {
+        .addr_mode = LUAT_BLE_ADV_ADDR_MODE_PUBLIC,
+        .channel_map = LUAT_BLE_ADV_CHNLS_ALL,
+        .intv_min = 120,
+        .intv_max = 160,
+    };
+
+    lua_pushstring(L, "addr_mode");
+    if (LUA_TNUMBER == lua_gettable(L, -2)){
+        luat_ble_adv_cfg.addr_mode = luaL_checknumber(L, -1);
+    }
+    lua_pop(L, 1);
+
+    lua_pushstring(L, "channel_map");
+    if (LUA_TNUMBER == lua_gettable(L, 2)) {
+        luat_ble_adv_cfg.channel_map = luaL_checknumber(L, -1);
+    }
+    lua_pop(L, 1);
+
+    lua_pushstring(L, "intv_min");
+    if (LUA_TNUMBER == lua_gettable(L, 2)) {
+        luat_ble_adv_cfg.intv_min = luaL_checknumber(L, -1);
+    }
+    lua_pop(L, 1);
+
+    lua_pushstring(L, "intv_max");
+    if (LUA_TNUMBER == lua_gettable(L, 2)) {
+        luat_ble_adv_cfg.intv_max = luaL_checknumber(L, -1);
+    }
+    lua_pop(L, 1);
+
+    luat_ble_create_advertising(luat_bluetooth, &luat_ble_adv_cfg);
+
+    // 广播内容 (adv data)
+    uint8_t adv_data[255] = {0};
+    uint8_t adv_index = 0;
+
+    lua_pushstring(L, "adv_data");
+    if (LUA_TTABLE == lua_gettable(L, -2)){
+        int adv_data_count = luaL_len(L, -1);
+        for (int i = 1; i <= adv_data_count; i++) {
+            lua_rawgeti(L, -1, i);
+            if (LUA_TTABLE == lua_type(L, -1)){
+                lua_rawgeti(L, -1, 2);
+                if (lua_type(L, -1) == LUA_TSTRING){
+                    const char* data = luaL_checklstring(L, -1, &len);
+                    adv_data[adv_index++] = (uint8_t)(len+1);
+                    lua_rawgeti(L, -2, 1);
+                    if (lua_type(L, -1) == LUA_TNUMBER){
+                        adv_data[adv_index++] = (uint8_t)luaL_checknumber(L, -1);
+                    }else{
+                        LLOGE("error adv_data type");
+                        goto end;
+                    }
+                    memcpy(adv_data + adv_index, data, len);
+                    adv_index += len;
+                    lua_pop(L, 2);
+                }else{
+                    LLOGE("error adv_data type");
+                    goto end;
+                }
+            }else{
+                LLOGE("error adv_data type");
+                goto end;
+            }
+            lua_pop(L, 1);
+        }
+    }
+    lua_pop(L, 1);
+    /* set adv paramters */
+    luat_ble_set_adv_data(luat_bluetooth, adv_data, adv_index);
+    // luat_ble_set_name(luat_bluetooth, complete_local_name, strlen(complete_local_name));
+
+    lua_pushboolean(L, 1);
+    return 1;
+end:
+    return 0;
+}
+
+static int l_ble_advertising_start(lua_State* L) {
+    luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t*)lua_newuserdata(L, sizeof(luat_bluetooth_t));
+    lua_pushboolean(L, luat_ble_start_advertising(luat_bluetooth)?0:1);
+    return 1;
+}
+
+static int l_ble_advertising_stop(lua_State* L) {
+    luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t*)lua_newuserdata(L, sizeof(luat_bluetooth_t));
+    lua_pushboolean(L, luat_ble_stop_advertising(luat_bluetooth)?0:1);
+    return 1;
+}
+
+static int l_bluetooth_init(lua_State* L) {
+    luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t*)lua_newuserdata(L, sizeof(luat_bluetooth_t));
+    if (luat_bluetooth) {
+        luat_bluetooth_init(luat_bluetooth);
+        luaL_setmetatable(L, LUAT_BLUETOOTH_TYPE);
+        lua_pushvalue(L, -1);
+        luat_bluetooth->bluetooth_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+        return 1;
+    }
+    return 0;
+}
+
+static int _bluetooth_struct_newindex(lua_State *L);
+
+void luat_bluetooth_struct_init(lua_State *L) {
+    luaL_newmetatable(L, LUAT_BLUETOOTH_TYPE);
+    lua_pushcfunction(L, _bluetooth_struct_newindex);
+    lua_setfield( L, -2, "__index" );
+    lua_pop(L, 1);
+}
+
+#include "rotable2.h"
+static const rotable_Reg_t reg_bluetooth[] =
+{
+	{"init",               ROREG_FUNC(l_bluetooth_init)},
+    {"create",             ROREG_FUNC(l_bluetooth_create)},
+    {"ble",                ROREG_FUNC(l_bluetooth_create_ble)},
+    {"gatt_create",         ROREG_FUNC(l_ble_gatt_create)},
+    {"adv_create",         ROREG_FUNC(l_ble_advertising_create)},
+    {"adv_start",          ROREG_FUNC(l_ble_advertising_start)},
+    {"adv_stop",           ROREG_FUNC(l_ble_advertising_stop)},
+
+    // ADV_ADDR_MODE
+    {"PUBLIC",                ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_PUBLIC)},
+    {"RANDOM",                ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_RANDOM)},
+    {"RPA",                ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_RPA)},
+    {"NRPA",                ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_NRPA)},
+    // ADV_CHNL
+    {"CHNL_37",                ROREG_INT(LUAT_BLE_ADV_CHNL_37)},
+    {"CHNL_38",                ROREG_INT(LUAT_BLE_ADV_CHNL_38)},
+    {"CHNL_39",                ROREG_INT(LUAT_BLE_ADV_CHNL_39)},
+    {"CHNLS_ALL",                ROREG_INT(LUAT_BLE_ADV_CHNLS_ALL)},
+    // Permission
+    {"READ",                ROREG_INT(LUAT_BLE_GATT_PERM_READ)},
+    {"WRITE",                ROREG_INT(LUAT_BLE_GATT_PERM_WRITE)},
+    {"IND",                ROREG_INT(LUAT_BLE_GATT_PERM_IND)},
+    {"NOTIFY",                ROREG_INT(LUAT_BLE_GATT_PERM_NOTIFY)},
+    // FLAGS
+    {"FLAGS",                ROREG_INT(LUAT_ADV_TYPE_FLAGS)},
+    {"COMPLETE_LOCAL_NAME",  ROREG_INT(LUAT_ADV_TYPE_COMPLETE_LOCAL_NAME)},
+    {"SERVICE_DATA",  ROREG_INT(LUAT_ADV_TYPE_SERVICE_DATA_16BIT)},
+    {"MANUFACTURER_SPECIFIC_DATA",  ROREG_INT(LUAT_ADV_TYPE_MANUFACTURER_SPECIFIC_DATA)},
+	{ NULL,             ROREG_INT(0)}
+};
+
+static int _bluetooth_struct_newindex(lua_State *L) {
+	const rotable_Reg_t* reg = reg_bluetooth;
+    const char* key = luaL_checkstring(L, 2);
+	while (1) {
+		if (reg->name == NULL)
+			return 0;
+		if (!strcmp(reg->name, key)) {
+			lua_pushcfunction(L, reg->value.value.func);
+			return 1;
+		}
+		reg ++;
+	}
+}
+
+LUAMOD_API int luaopen_bluetooth( lua_State *L ) {
+    rotable2_newlib(L, reg_bluetooth);
+    luat_bluetooth_struct_init(L);
+    lua_pushvalue(L, -1);
+    lua_setglobal(L, "ble");
+    return 1;
+}

+ 1 - 1
components/network/adapter_lwip2/net_lwip2.c

@@ -765,7 +765,7 @@ static void net_lwip2_task(void *param)
 		}
 		else
 		{
-			NET_DBG("udp bind %d", prvlwip.socket[socket_id].local_port);
+			// NET_DBG("udp bind %d", prvlwip.socket[socket_id].local_port);
 			error = udp_bind(prvlwip.socket[socket_id].pcb.udp, local_ip, prvlwip.socket[socket_id].local_port);
 			if (error) {
 				NET_DBG("udp bind ret %d port %d", error, prvlwip.socket[socket_id].local_port);

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

@@ -253,7 +253,7 @@ static int l_netdrv_link(lua_State *L) {
 @int netdrv的id, 例如 socket.LWIP_ETH
 @return bool 已连接返回true, 否则返回false. 如果id对应的netdrv不存在,返回nil
 @usage
--- 注意, 本函数仅支持读取, 即判断是否能联网
+-- 注意, 本函数仅支持读取, 即判断是否能通信, 不代表IP状态
 */
 static int l_netdrv_ready(lua_State *L) {
     int id = luaL_checkinteger(L, 1);

+ 2 - 0
components/network/netdrv/include/luat_netdrv.h

@@ -104,4 +104,6 @@ void luat_netdrv_netif_input(void* args);
 
 int luat_netdrv_netif_input_proxy(struct netif * netif, uint8_t* buff, uint16_t len);
 
+void luat_netdrv_print_tm(const char * tag);
+
 #endif

+ 15 - 2
components/network/netdrv/include/luat_netdrv_napt.h

@@ -22,11 +22,11 @@ typedef struct luat_netdrv_napt_tcpudp
 {
     uint8_t  is_vaild;
     uint8_t adapter_id;
+    uint32_t inet_ip;
     uint16_t inet_port;
+    uint32_t wnet_ip;
     uint16_t wnet_port;
     uint16_t wnet_local_port;
-    uint32_t inet_ip;
-    uint32_t wnet_ip;
     uint8_t  inet_mac[6];
     uint64_t tm_ms; // 最后通信时间
 
@@ -49,6 +49,15 @@ typedef struct napt_ctx
     int is_wnet;
 }napt_ctx_t;
 
+struct luat_netdrv_napt_llist;
+typedef struct luat_netdrv_napt_llist
+{
+    struct luat_netdrv_napt_llist* next;
+    luat_netdrv_napt_tcpudp_t item;
+}luat_netdrv_napt_llist_t;
+
+
+
 int luat_napt_icmp_handle(napt_ctx_t* ctx);
 int luat_napt_tcp_handle(napt_ctx_t* ctx);
 int luat_napt_udp_handle(napt_ctx_t* ctx);
@@ -57,4 +66,8 @@ int luat_netdrv_napt_pkg_input(int id, uint8_t* buff, size_t len);
 
 int luat_netdrv_napt_pkg_input_pbuf(int id, struct pbuf* p);
 
+// 维护影响关系
+int luat_netdrv_napt_tcp_wan2lan(napt_ctx_t* ctx, luat_netdrv_napt_tcpudp_t* mapping);
+int luat_netdrv_napt_tcp_lan2wan(napt_ctx_t* ctx, luat_netdrv_napt_tcpudp_t* mapping);
+
 #endif

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

@@ -409,7 +409,11 @@ static int task_loop(ch390h_t *ch, luat_ch390h_cstring_t* cs) {
     }
     if (ret) {
         pkg_evt_t evt = {0};
-        luat_rtos_queue_send(qt, &evt, sizeof(pkg_evt_t), 0);
+        size_t t = 0;
+        luat_rtos_queue_get_cnt(qt, &t);
+        if (t < 4) {
+            luat_rtos_queue_send(qt, &evt, sizeof(pkg_evt_t), 0);
+        }
     }
     return ret;
 }

+ 23 - 4
components/network/netdrv/src/luat_netdrv.c

@@ -6,6 +6,7 @@
 // #include "luat_netdrv_uart.h"
 #endif
 #include "luat_mem.h"
+#include "luat_mcu.h"
 
 #ifdef LUAT_USE_AIRLINK
 #include "luat_airlink.h"
@@ -14,6 +15,10 @@
 #define LUAT_LOG_TAG "netdrv"
 #include "luat_log.h"
 
+#ifndef __USER_FUNC_IN_RAM__
+#define __USER_FUNC_IN_RAM__ 
+#endif
+
 static luat_netdrv_t* drvs[NW_ADAPTER_QTY];
 
 luat_netdrv_t* luat_netdrv_ch390h_setup(luat_netdrv_conf_t *conf);
@@ -126,7 +131,7 @@ void luat_netdrv_print_pkg(const char* tag, uint8_t* buff, size_t len) {
 
 #define NAPT_CHKSUM_16BIT_LEN        sizeof(uint16_t)
 
-uint32_t alg_hdr_16bitsum(const uint16_t *buff, uint16_t len)
+__USER_FUNC_IN_RAM__ uint32_t alg_hdr_16bitsum(const uint16_t *buff, uint16_t len)
 {
     uint32_t sum = 0;
 
@@ -147,7 +152,7 @@ uint32_t alg_hdr_16bitsum(const uint16_t *buff, uint16_t len)
     return sum;
 }
 
-uint16_t alg_iphdr_chksum(const uint16_t *buff, uint16_t len)
+__USER_FUNC_IN_RAM__ uint16_t alg_iphdr_chksum(const uint16_t *buff, uint16_t len)
 {
     uint32_t sum = alg_hdr_16bitsum(buff, len);
 
@@ -157,7 +162,7 @@ uint16_t alg_iphdr_chksum(const uint16_t *buff, uint16_t len)
     return (uint16_t)(~sum);
 }
 
-uint16_t alg_tcpudphdr_chksum(uint32_t src_addr, uint32_t dst_addr, uint8_t proto, const uint16_t *buff, uint16_t len)
+__USER_FUNC_IN_RAM__ uint16_t alg_tcpudphdr_chksum(uint32_t src_addr, uint32_t dst_addr, uint8_t proto, const uint16_t *buff, uint16_t len)
 {
     uint32_t sum = 0;
 
@@ -215,7 +220,13 @@ int luat_netdrv_netif_input_proxy(struct netif * netif, uint8_t* buff, uint16_t
     memcpy(ptr->buff, buff, len);
     ptr->netif = netif;
     ptr->len = len;
-    int ret = tcpip_callback(luat_netdrv_netif_input, ptr);
+    // uint64_t tbegin = luat_mcu_tick64();
+    int ret = tcpip_callback_with_block(luat_netdrv_netif_input, ptr, 0);
+    // uint64_t tend = luat_mcu_tick64();
+    // uint64_t tused = (tend - tbegin) / luat_mcu_us_period();
+    // if (tused > 50) {
+    //     LLOGD("tcpip_callback!! use %lld us", tused);
+    // }
     if (ret) {
         luat_heap_free(ptr);
         LLOGE("tcpip_callback 返回错误!!! ret %d", ret);
@@ -223,3 +234,11 @@ int luat_netdrv_netif_input_proxy(struct netif * netif, uint8_t* buff, uint16_t
     }
     return 0;
 }
+
+
+
+void luat_netdrv_print_tm(const char * tag) {
+    uint64_t tnow = luat_mcu_tick64();
+    uint64_t t_us = tnow / luat_mcu_us_period();
+    LLOGI("tag %s time %lld", tag, t_us);
+}

+ 257 - 7
components/network/netdrv/src/luat_netdrv_napt.c

@@ -4,14 +4,21 @@
 #ifdef __LUATOS__
 #include "luat_netdrv_ch390h.h"
 #endif
-#include "luat_malloc.h"
 #include "luat_netdrv_napt.h"
+#include "luat_mcu.h"
+#include "luat_mem.h"
+
 #include "lwip/pbuf.h"
 #include "lwip/ip.h"
 #include "lwip/etharp.h"
 #include "lwip/icmp.h"
 #include "lwip/prot/etharp.h"
-#include "luat_mcu.h"
+#include "lwip/tcpip.h"
+#include "lwip/tcp.h"
+#include "lwip/udp.h"
+#include "lwip/prot/tcp.h"
+#include "lwip/prot/udp.h"
+#include "lwip/ip_addr.h"
 
 #define LUAT_LOG_TAG "netdrv.napt"
 #include "luat_log.h"
@@ -130,20 +137,29 @@ __USER_FUNC_IN_RAM__ int luat_netdrv_napt_pkg_input(int id, uint8_t* buff, size_
         return 0;
     }
     // LLOGD("按协议类型, 使用对应的NAPT修改器进行处理 id %d proto %d", id, IPH_PROTO(ctx.iphdr));
+    // uint64_t tbegin = luat_mcu_tick64();
+    int ret = 0;
     switch (IPH_PROTO(ctx.iphdr))
     {
     case IP_PROTO_ICMP:
-        return luat_napt_icmp_handle(&ctx);
+        ret = luat_napt_icmp_handle(&ctx);
+        break;
     case IP_PROTO_TCP:
-        return luat_napt_tcp_handle(&ctx);
+        ret = luat_napt_tcp_handle(&ctx);
+        break;
     case IP_PROTO_UDP:
-        return luat_napt_udp_handle(&ctx);
+        ret = luat_napt_udp_handle(&ctx);
+        break;
     default:
         LLOGD("不是tcp/udp/icmp包, 不需要执行napt");
         return 0;
     }
-
-    return 0;
+    // uint64_t tend = luat_mcu_tick64();
+    // uint64_t tused_us = (tend - tbegin) / luat_mcu_us_period();
+    // if (tused_us > 100) {
+    //     LLOGI("time used %4lld us tp %2d way %d", tused_us, IPH_PROTO(ctx.iphdr), luat_netdrv_gw_adapter_id == id);
+    // }
+    return ret;
 }
 #endif
 
@@ -174,3 +190,237 @@ int luat_netdrv_napt_pkg_input_pbuf(int id, struct pbuf* p) {
     }
     return 0; // lwip继续处理 
 }
+
+
+// --- TCP/UDP的映射关系维护
+
+static luat_rtos_mutex_t tcp_mutex;
+static luat_netdrv_napt_llist_t node_head;
+static size_t clean_tm = 1;
+
+// 端口分配
+#define NAPT_TCP_RANGE_START     0x1BBC
+#define NAPT_TCP_RANGE_END       0x5AAA
+static uint32_t port_used[1024];
+__USER_FUNC_IN_RAM__ static size_t luat_napt_tcp_port_alloc(void) {
+    #if 0
+    luat_netdrv_napt_llist_t* head = node_head.next;
+    size_t used = 0;
+    for (size_t i = NAPT_TCP_RANGE_START; i <= NAPT_TCP_RANGE_END; i++)
+    {
+        head = node_head.next;
+        used = 0;
+        while (head != NULL) {
+            if (head->item.wnet_local_port == i) {
+                used = 1;
+                break;
+            }
+            head = head->next;
+        }
+        if (used == 0) {
+            LLOGD("分配新的TCP本地端口 %d", i);
+            return i;
+        }
+    }
+    #else
+    size_t offset;
+    size_t soffset;
+    for (size_t i = 0; i <= NAPT_TCP_RANGE_END - NAPT_TCP_RANGE_START; i++) {
+        offset = i / ( 4 * 8);
+        soffset = i % ( 4 * 8);
+        if ((port_used[offset] & (1 << soffset)) == 0) {
+            port_used[offset] |= (1 << soffset);
+            return i + NAPT_TCP_RANGE_START;
+        }
+    }
+    #endif
+    return 0;
+}
+
+__USER_FUNC_IN_RAM__ static void mapping_cleanup(void) {
+    luat_netdrv_napt_llist_t* head = node_head.next;
+    luat_netdrv_napt_llist_t* prev = &node_head;
+    luat_netdrv_napt_llist_t* tmp = NULL;
+    uint64_t tnow = luat_mcu_tick64_ms();
+    uint64_t tdiff = 0;
+    size_t offset;
+    size_t soffset;
+    size_t port;
+    int flag = 0;
+    luat_netdrv_napt_tcpudp_t* it = NULL;
+    while (head != NULL) {
+        it = &head->item;
+        // 远程ip(4 byte), 远程端口(2 byte), 本地映射端口(2 byte)
+        tdiff = tnow - it->tm_ms;
+        if (tdiff > 20*60*1000) {
+            flag = 1;
+            // LLOGD("映射关系超时 %lldms port %ld", tdiff, it->wnet_local_port);
+        }
+        else if ((((it->finack1 && it->finack2) || !it->synack) &&
+                  tnow - it->tm_ms > IP_NAPT_TIMEOUT_MS_TCP_DISCON)) {
+            // LLOGD("映射的TCP链路已经断开%lldms, 超过 %ld ms, 设置为无效", tnow - it->tm_ms, IP_NAPT_TIMEOUT_MS_TCP_DISCON);
+            flag = 1;
+        }
+        if (flag) {
+            tmp = head;
+            port = it->wnet_local_port - NAPT_TCP_RANGE_START;
+            // LLOGD("释放端口号 %d", it->wnet_local_port);
+            offset = port / ( 4 * 8);
+            soffset = port % ( 4 * 8);
+            port_used[offset] &= (~(1 << soffset));
+            prev->next = head->next;
+            head = head->next;
+            // 注意, prev不变
+            luat_heap_opt_free(LUAT_HEAP_PSRAM, tmp);
+        }
+        else {
+            prev = head;
+            head = head->next;
+        }
+    }
+}
+
+
+__USER_FUNC_IN_RAM__ static void update_tcp_stat_wnet(struct tcp_hdr *tcphdr, luat_netdrv_napt_tcpudp_t* t) {
+    if ((TCPH_FLAGS(tcphdr) & (TCP_SYN|TCP_ACK)) == (TCP_SYN|TCP_ACK))
+      t->synack = 1;
+    if ((TCPH_FLAGS(tcphdr) & TCP_FIN))
+      t->fin1 = 1;
+    if (t->fin2 && (TCPH_FLAGS(tcphdr) & TCP_ACK))
+      t->finack2 = 1; /* FIXME: Currently ignoring ACK seq... */
+    if (TCPH_FLAGS(tcphdr) & TCP_RST)
+      t->rst = 1;
+  // LLOGD("TCP链路状态 synack %d fin1 %d finack2 %d rst %d", t->synack, t->fin1, t->finack2, t->rst);
+}
+
+__USER_FUNC_IN_RAM__ static void update_tcp_stat_inet(struct tcp_hdr *tcphdr, luat_netdrv_napt_tcpudp_t* t) {
+    if ((TCPH_FLAGS(tcphdr) & TCP_FIN))
+        t->fin2 = 1;
+    if (t->fin1 && (TCPH_FLAGS(tcphdr) & TCP_ACK))
+        t->finack1 = 1; /* FIXME: Currently ignoring ACK seq... */
+    if (TCPH_FLAGS(tcphdr) & TCP_RST)
+        t->rst = 1;
+    // LLOGD("TCP链路状态 synack %d fin1 %d finack2 %d rst %d", t->synack, t->fin1, t->finack2, t->rst);
+}
+
+// 外网到内网
+__USER_FUNC_IN_RAM__ int luat_netdrv_napt_tcp_wan2lan(napt_ctx_t* ctx, luat_netdrv_napt_tcpudp_t* mapping) {
+    int ret = -1;
+    luat_netdrv_napt_llist_t* head = node_head.next;
+    uint16_t iphdr_len = (ctx->iphdr->_v_hl & 0x0F) * 4;
+    struct ip_hdr* ip_hdr = ctx->iphdr;
+    uint64_t tnow = luat_mcu_tick64_ms();
+    uint32_t tsec = (uint32_t)(tnow / 1000);
+    luat_netdrv_napt_tcpudp_t tmp = {0};
+    struct tcp_hdr *tcp_hdr = (struct tcp_hdr*)(((uint8_t*)ctx->iphdr) + iphdr_len);
+
+    tmp.wnet_ip = ctx->iphdr->src.addr;
+    tmp.wnet_port = tcp_hdr->src;
+    tmp.wnet_local_port = tcp_hdr->dest;
+
+    // TODO Lock
+    if (tcp_mutex == NULL) {
+        luat_rtos_mutex_create(&tcp_mutex);
+    }
+    luat_rtos_mutex_lock(tcp_mutex, 5000);
+    // 清理映射关系
+    if (tsec - clean_tm > 5) {
+        mapping_cleanup();
+        clean_tm = tsec;
+    }
+    while (head != NULL) {
+        // 远程ip(4 byte), 远程端口(2 byte), 本地映射端口(2 byte)
+        if (memcmp(&tmp.wnet_ip, &head->item.wnet_ip, 8) == 0) {
+            memcpy(mapping, &head->item, sizeof(luat_netdrv_napt_tcpudp_t));
+            head->item.tm_ms = tnow;
+            ret = 0;
+            update_tcp_stat_wnet(tcp_hdr, &head->item);
+            break;
+        }
+        head = head->next;
+    }
+    // TODO UnLock
+    luat_rtos_mutex_unlock(tcp_mutex);
+    return ret;
+}
+
+// 内网到外网
+__USER_FUNC_IN_RAM__ int luat_netdrv_napt_tcp_lan2wan(napt_ctx_t* ctx, luat_netdrv_napt_tcpudp_t* mapping) {
+    int ret = -1;
+    luat_netdrv_napt_llist_t* head = node_head.next;
+    uint16_t iphdr_len = (ctx->iphdr->_v_hl & 0x0F) * 4;
+    struct ip_hdr* ip_hdr = ctx->iphdr;
+    uint64_t tnow = luat_mcu_tick64_ms();
+    uint32_t tsec = (uint32_t)(tnow / 1000);
+    luat_netdrv_napt_tcpudp_t tmp = {0};
+    struct tcp_hdr *tcp_hdr = (struct tcp_hdr*)(((uint8_t*)ctx->iphdr) + iphdr_len);
+
+    tmp.inet_ip = ctx->iphdr->src.addr;
+    tmp.inet_port = tcp_hdr->src;
+    tmp.wnet_ip = ctx->iphdr->dest.addr;
+    tmp.wnet_port = tcp_hdr->dest;
+
+    if (tcp_mutex == NULL) {
+        luat_rtos_mutex_create(&tcp_mutex);
+    }
+    
+    luat_rtos_mutex_lock(tcp_mutex, 5000);
+
+    // 清理映射关系
+    if (tsec - clean_tm > 5) {
+        mapping_cleanup();
+        clean_tm = tsec;
+    }
+
+    while (head != NULL) {
+        // 本地ip(4 byte), 本地端口(2 byte), 远程ip(4 byte), 远程端口(2 byte)
+        if (memcmp(&tmp.inet_ip, &head->item.inet_ip, 6 + 6) == 0) {
+            head->item.tm_ms = tnow;
+            ret = 0;
+            // 映射关系找到了,那就关联一下情况
+            update_tcp_stat_inet(tcp_hdr, &head->item);
+            memcpy(mapping, &head->item, sizeof(luat_netdrv_napt_tcpudp_t));
+            break;
+        }
+        head = head->next;
+    }
+    while (ret != 0) {
+        tmp.wnet_local_port = luat_napt_tcp_port_alloc();
+        if (tmp.wnet_local_port == 0) {
+            LLOGE("TCP映射关系已经用完");
+            ret = - 2;
+            break;
+        }
+        // 没找到, 那就新增一个
+        luat_netdrv_napt_llist_t* node = luat_heap_opt_malloc(LUAT_HEAP_PSRAM, sizeof(luat_netdrv_napt_llist_t));
+        if (node == NULL) {
+            // 内存不够了
+            ret = -3;
+            break;
+        }
+        else {
+            memcpy(&node->item, &tmp, sizeof(luat_netdrv_napt_tcpudp_t));
+            node->item.tm_ms = tnow;
+            if (ctx->eth) {
+                memcpy(node->item.inet_mac, ctx->eth->src.addr, 6);
+            }
+            
+            node->item.adapter_id = ctx->net->id;
+            node->next = node_head.next;
+            node_head.next = node;
+            memcpy(mapping, &node->item, sizeof(luat_netdrv_napt_tcpudp_t));
+            LLOGD("分配出去的端口号 %d", node->item.wnet_local_port);
+            ret = 0;
+        }
+        break;
+    }
+
+    // unlock
+    luat_rtos_mutex_unlock(tcp_mutex);
+
+    return ret;
+}
+
+int luat_netdrv_napt_watch_task_main(void) {
+    return 0;
+}

+ 15 - 189
components/network/netdrv/src/luat_netdrv_napt_tcp.c

@@ -14,88 +14,16 @@
 #define LUAT_LOG_TAG "netdrv.napt.tcp"
 #include "luat_log.h"
 
-#define TCP_MAP_SIZE (2048)
-#define TCP_MAP_TIMEOUT (15*60*1000)
-
-/* napt tcp port range: 7100-23210 */
-#define NAPT_TCP_RANGE_START     0x1BBC
-#define NAPT_TCP_RANGE_END       0x5AAA
-
 extern int luat_netdrv_gw_adapter_id;
-static uint16_t napt_curr_id = NAPT_TCP_RANGE_START;
 static luat_netdrv_napt_tcpudp_t* tcps;
+static uint8_t *tcp_buff;
 
 #define u32 uint32_t
 #define u16 uint16_t
 #define u8 uint8_t
 #define NAPT_ETH_HDR_LEN             sizeof(struct ethhdr)
 
-static u16 luat_napt_tcp_port_alloc(void)
-{
-    u16 cnt = 0;
-
-again:
-    if (napt_curr_id++ == NAPT_TCP_RANGE_END)
-    {
-        napt_curr_id = NAPT_TCP_RANGE_START;
-    }
-
-    for (size_t i = 0; i < TCP_MAP_SIZE; i++)
-    {
-        if (napt_curr_id == tcps[i].wnet_local_port)
-        {
-            if (++cnt > (NAPT_TCP_RANGE_END - NAPT_TCP_RANGE_START))
-            {
-                return 0;
-            }
-
-	       goto again;
-        }
-    }
-
-    return napt_curr_id;
-}
 
-static void print_item(const char* tag, luat_netdrv_napt_tcpudp_t* it) {
-    char buff[16] = {0};
-    char buff2[16] = {0};
-    ip_addr_t ip;
-    
-    ip_addr_set_ip4_u32(&ip, it->inet_ip);
-    ipaddr_ntoa_r(&ip, buff, 16);
-
-    ip_addr_set_ip4_u32(&ip, it->wnet_ip);
-    ipaddr_ntoa_r(&ip, buff2, 16);
-
-    LLOGD("%s (%5d) 内网 %s:%d <-> 外网 %s:%d", tag, it->wnet_local_port,
-        buff, ntohs(it->inet_port),
-        buff2, ntohs(it->wnet_port)
-    );
-}
-
-static void update_tcp_stat_wnet(struct tcp_hdr *tcphdr, luat_netdrv_napt_tcpudp_t* t) {
-      if ((TCPH_FLAGS(tcphdr) & (TCP_SYN|TCP_ACK)) == (TCP_SYN|TCP_ACK))
-        t->synack = 1;
-      if ((TCPH_FLAGS(tcphdr) & TCP_FIN))
-        t->fin1 = 1;
-      if (t->fin2 && (TCPH_FLAGS(tcphdr) & TCP_ACK))
-        t->finack2 = 1; /* FIXME: Currently ignoring ACK seq... */
-      if (TCPH_FLAGS(tcphdr) & TCP_RST)
-        t->rst = 1;
-    // LLOGD("TCP链路状态 synack %d fin1 %d finack2 %d rst %d", t->synack, t->fin1, t->finack2, t->rst);
-}
-
-static void update_tcp_stat_inet(struct tcp_hdr *tcphdr, luat_netdrv_napt_tcpudp_t* t) {
-    if ((TCPH_FLAGS(tcphdr) & TCP_FIN))
-        t->fin2 = 1;
-    if (t->fin1 && (TCPH_FLAGS(tcphdr) & TCP_ACK))
-        t->finack1 = 1; /* FIXME: Currently ignoring ACK seq... */
-    if (TCPH_FLAGS(tcphdr) & TCP_RST)
-        t->rst = 1;
-    // LLOGD("TCP链路状态 synack %d fin1 %d finack2 %d rst %d", t->synack, t->fin1, t->finack2, t->rst);
-}
-
-static uint8_t *tcp_buff;
 int luat_napt_tcp_handle(napt_ctx_t* ctx) {
     uint16_t iphdr_len = (ctx->iphdr->_v_hl & 0x0F) * 4;
     struct ip_hdr* ip_hdr = ctx->iphdr;
@@ -103,50 +31,25 @@ int luat_napt_tcp_handle(napt_ctx_t* ctx) {
     luat_netdrv_t* gw = luat_netdrv_get(luat_netdrv_gw_adapter_id);
     luat_netdrv_napt_tcpudp_t* it = NULL;
     luat_netdrv_napt_tcpudp_t* it_map = NULL;
+    int ret = 0;
     if (gw == NULL || gw->netif == NULL) {
         return 0;
     }
-    if (tcps == NULL) {
-        tcps = luat_heap_opt_zalloc(LUAT_HEAP_PSRAM, sizeof(luat_netdrv_napt_tcpudp_t) * TCP_MAP_SIZE);
-    }
     if (tcp_buff == NULL) {
         tcp_buff = luat_heap_opt_zalloc(LUAT_HEAP_SRAM, 1600);
     }
     uint64_t tnow = luat_mcu_tick64_ms();
+    luat_netdrv_napt_tcpudp_t mapping = {0};
     if (ctx->is_wnet) {
         // 这是从外网到内网的TCP包
         // LLOGD("wnet.search dst port %d", ntohs(tcp_hdr->dest));
-        for (size_t i = 0; i < TCP_MAP_SIZE; i++)
-        {
-            it = &tcps[i];
-            if (it->is_vaild == 0) {
-                continue;
-            }
-            tnow = luat_mcu_tick64_ms();
-            if (it->is_vaild && tnow > it->tm_ms &&  (tnow - it->tm_ms) > TCP_MAP_TIMEOUT) {
-                // LLOGD("映射关系超时了!!设置为无效 %lld %lld %lld", tnow, it->tm_ms, tnow - it->tm_ms);
-                it->is_vaild = 0;
-                continue;
-            }
-            // print_item("wnet.search item", it);
-            // 校验远程IP与预期IP是否相同
-            if (ip_hdr->src.addr != it->wnet_ip) {
-                // LLOGD("IP地址不匹配,下一条");
-                continue;
-            }
-            // 下行的目标端口, 与本地端口, 是否一直
-            if (tcp_hdr->dest != tcps[i].wnet_local_port) {
-                // LLOGD("port不匹配,下一条");
-                continue;
-            }
-            // 找到映射关系了!!!
-            // LLOGD("TCP port %u -> %d", ntohs(tcp_hdr->dest), ntohs(tcps[i].inet_port));
-            tcps[i].tm_ms = tnow;
+        ret = luat_netdrv_napt_tcp_wan2lan(ctx, &mapping);
+        if (ret == 0) {
             // 修改目标端口
-            tcp_hdr->dest = tcps[i].inet_port;
+            tcp_hdr->dest = mapping.inet_port;
 
             // 修改目标地址到内网地址,并重新计算ip的checksu
-            ip_hdr->dest.addr = tcps[i].inet_ip;
+            ip_hdr->dest.addr = mapping.inet_ip;
             ip_hdr->_chksum = 0;
             ip_hdr->_chksum = alg_iphdr_chksum((u16 *)ip_hdr, iphdr_len);
 
@@ -163,10 +66,9 @@ int luat_napt_tcp_handle(napt_ctx_t* ctx) {
             // 如果是ETH包, 那还需要修改源MAC和目标MAC
             if (ctx->eth) {
                 memcpy(ctx->eth->src.addr, ctx->net->netif->hwaddr, 6);
-                memcpy(ctx->eth->dest.addr, tcps[i].inet_mac, 6);
+                memcpy(ctx->eth->dest.addr, mapping.inet_mac, 6);
             }
-            update_tcp_stat_wnet(tcp_hdr, &tcps[i]);
-            luat_netdrv_t* dst = luat_netdrv_get(tcps[i].adapter_id);
+            luat_netdrv_t* dst = luat_netdrv_get(mapping.adapter_id);
             if (dst == NULL) {
                 LLOGE("能找到TCP映射关系, 但目标netdrv不存在, 这肯定是BUG啊!!");
                 return 1;
@@ -178,7 +80,7 @@ int luat_napt_tcp_handle(napt_ctx_t* ctx) {
                 }
                 else if (!ctx->eth && dst->netif->flags & NETIF_FLAG_ETHARP) {
                     // 需要补全一个ETH头部
-                    memcpy(tcp_buff, tcps[i].inet_mac, 6);
+                    memcpy(tcp_buff, mapping.inet_mac, 6);
                     memcpy(tcp_buff + 6, dst->netif->hwaddr, 6);
                     memcpy(tcp_buff + 12, "\x08\x00", 2);
                     memcpy(tcp_buff + 14, ip_hdr, ctx->len);
@@ -206,88 +108,12 @@ int luat_napt_tcp_handle(napt_ctx_t* ctx) {
         }
         // 第一轮循环, 是否有已知映射
         // LLOGD("inet.search src port %d -> %d", ntohs(tcp_hdr->src), ntohs(tcp_hdr->dest));
-        for (size_t i = 0; i < TCP_MAP_SIZE; i++)
-        {
-            it = &tcps[i];
-            if (it->is_vaild == 0) {
-                continue;
-            }
-            tnow = luat_mcu_tick64_ms();
-            if (tnow > it->tm_ms && (tnow - it->tm_ms) > TCP_MAP_TIMEOUT) {
-                // LLOGD("映射关系超时了!!设置为无效 %lld %lld %lld", tnow, it->tm_ms, tnow - it->tm_ms);
-                it->is_vaild = 0;
-                it->tm_ms = 0;
-                continue;
-            }
-
-            // 判断TCP链路状态
-            if ((((it->finack1 && it->finack2) || !it->synack) &&
-                  tnow - it->tm_ms > IP_NAPT_TIMEOUT_MS_TCP_DISCON)) {
-                //LLOGD("映射的TCP链路已经断开%lldms, 超过 %ld ms, 设置为无效", tnow - it->tm_ms, IP_NAPT_TIMEOUT_MS_TCP_DISCON);
-                it->is_vaild = 0;
-                it->tm_ms = 0;
-                continue;
-            }
-            
-            // print_item("inet.search", it);
-            // 几个要素都要相同 源IP/源端口/目标IP/目标端口, 如果是MAC包, 源MAC也要相同
-            if (it->inet_ip != ip_hdr->src.addr || it->inet_port != tcp_hdr->src) {
-                // LLOGD("源ip/port不匹配, 继续下一条");
-                continue;
-            }
-            if (it->wnet_ip != ip_hdr->dest.addr || it->wnet_port != tcp_hdr->dest) {
-                // LLOGD("目标ip/port不匹配, 继续下一条");
-                continue;
-            }
-            if (ctx->eth && memcmp(ctx->eth->src.addr, it->inet_mac, 6)) {
-                // LLOGD("源MAC不匹配, 继续下一条");
-                continue;
-            }
-            // 都相同, 那就是同一个映射了, 可以复用
-            it->tm_ms = tnow;
-            it_map = it;
-            break;
-        }
-        // 寻找一个空位
-        if (it_map == NULL) {
-            if ((TCPH_FLAGS(tcp_hdr) & (TCP_SYN|TCP_ACK)) == TCP_SYN && PP_NTOHS(tcp_hdr->src) >= 1024) {
-                // 允许新增映射
-            }
-            else {
-                // LLOGI("非SYN包/源端口小于1024,且没有已知映射,不允许新增映射 %02X %d", TCPH_FLAGS(tcp_hdr), PP_NTOHS(tcp_hdr->src));
-                // TODO 应该返回RST?
-                return 0;
-            }
-            for (size_t i = 0; i < TCP_MAP_SIZE; i++) {
-                it = &tcps[i];
-                if (it->is_vaild) {
-                    continue;
-                }
-                // 有空位了, 马上分配
-                it_map = it;
-                break;
-            }
-            if (it_map == NULL) {
-                LLOGE("没有空闲的TCP映射了!!!!");
-                return 0;
-            }
-            memset(it_map, 0, sizeof(luat_netdrv_napt_tcpudp_t));
-            it->adapter_id = ctx->net->id;
-            it->inet_port = tcp_hdr->src;
-            it->wnet_port = tcp_hdr->dest;
-            it->inet_ip = ip_hdr->src.addr;
-            it->wnet_ip = ip_hdr->dest.addr;
-            it->wnet_local_port = luat_napt_tcp_port_alloc();
-            it->tm_ms = tnow;
-            if (ctx->eth) {
-                memcpy(it->inet_mac, ctx->eth->src.addr, 6);
-            }
-            it->is_vaild = 1;
-            //LLOGD("分配新的TCP映射 inet %d wnet %d", it->inet_port, it->wnet_local_port);
-        }
-        else {
-            update_tcp_stat_inet(tcp_hdr, it_map);
+        ret = luat_netdrv_napt_tcp_lan2wan(ctx, &mapping);
+        if (ret != 0) {
+            return 0;
         }
+        it_map = &mapping;
+
         // 2. 修改信息
         ip_hdr->src.addr = ip_addr_get_ip4_u32(&gw->netif->ip_addr);
         tcp_hdr->src = it_map->wnet_local_port;

+ 1 - 1
components/network/netdrv/src/luat_netdrv_napt_udp.c

@@ -13,7 +13,7 @@
 #include "luat_log.h"
 
 #ifdef LUAT_USE_PSRAM
-#define UDP_MAP_SIZE (8*1024)
+#define UDP_MAP_SIZE (256)
 #else
 #define UDP_MAP_SIZE (1024)
 #endif

+ 1 - 1
components/network/ulwip/src/ulwip_dhcp_client.c

@@ -183,7 +183,7 @@ void ulwip_dhcp_client_start(ulwip_ctx_t *ctx) {
 }
 
 void ulwip_dhcp_client_stop(ulwip_ctx_t *ctx) {
-    LLOGD("dhcp stop netif %p", ctx->netif);
+    // LLOGD("dhcp stop netif %p", ctx->netif);
     if (ctx->dhcp_timer != NULL && luat_rtos_timer_is_active(ctx->dhcp_timer)) {
         luat_rtos_timer_stop(ctx->dhcp_timer);
         reset_dhcp_client(ctx);

+ 2 - 2
components/network/websocket/luat_websocket.c

@@ -545,7 +545,7 @@ int luat_websocket_read_packet(luat_websocket_ctrl_t *websocket_ctrl)
 	}
 	int recv_want = 0;
 
-	while (WEBSOCKET_RECV_BUF_LEN_MAX + 8 - websocket_ctrl->buffer_offset > 0)
+	while (((WEBSOCKET_RECV_BUF_LEN_MAX + 8) - websocket_ctrl->buffer_offset) > 0)
 	{
 		if (WEBSOCKET_MAX_READ > (WEBSOCKET_RECV_BUF_LEN_MAX - websocket_ctrl->buffer_offset))
 		{
@@ -588,7 +588,7 @@ int luat_websocket_read_packet(luat_websocket_ctrl_t *websocket_ctrl)
 			return -1;
 		}
 	}
-	if (WEBSOCKET_RECV_BUF_LEN_MAX + 8 < websocket_ctrl->buffer_offset > 0) {
+	if (WEBSOCKET_RECV_BUF_LEN_MAX + 8 < websocket_ctrl->buffer_offset) {
 		LLOGD("pkg maybe too large");
 		return -1;
 	}

+ 112 - 0
components/pins/meta/Air8000.define.json

@@ -0,0 +1,112 @@
+{
+    "model":"air8000",
+    "pin_count":104,
+    "pins":[
+        [83,11,"GPIO16",["","","","","GPIO16","","",""]],
+        [82,12,"GPIO17",["","","","","GPIO17","","",""]],
+        [80,13,"I2C0_SCL",["","","I2C0_SCL","I2C1_SCL","GPIO18","PWM0","",""]],
+        [81,14,"I2C0_SDA",["","","I2C0_SDA","I2C1_SDA","GPIO19","PWM1","",""]],
+        [1,15,"USB_BOOT",["","","","","","","",""]],
+        [31,16,"GPIO1",["GPIO1","","","","","PWM0","",""]],
+        [30,17,"GPIO2",["GPIO2","","","","ONEWIRE","PWM1","",""]],
+        [98,18,"GPIO3",["GPIO3","CAM_MCLK","","","ONEWIRE","PWM2","",""]],
+        [67,19,"I2C1_SDA",["GPIO4","CAM_BCLK","I2C1_SDA","","USIM2_RST","","",""]],
+        [66,20,"I2C1_SCL",["GPIO5","CAM_CS","I2C1_SCL","","USIM2_CLK","","",""]],       
+        [41,27,"SPI1_CS",["GPIO12","SPI1_CS","","UART2_RXD","USIM2_DAT","","","CAN_RXD"]],
+        [40,28,"SPI1_MOSI",["GPIO13","SPI1_MOSI","","UART2_TXD","USIM2_RST","","","CAN_TXD"]],
+        [39,29,"SPI1_MISO",["GPIO14","SPI1_MISO","I2C0_SDA","UART3_RXD","USIM2_CLK","PWM0","","CAN_STB"]],
+        [38,30,"SPI1_SCLK",["GPIO15","SPI1_SCLK","I2C0_SCL","UART3_TXD","","PWM1","",""]],
+        [47,31,"DBG_RXD",["","","","","","","",""]],
+        [46,32,"DBG_TXD",["","","","","","","",""]],
+        [17,33,"UART1_RXD",["GPIO18","UART1_RXD","","","","","",""]],
+        [16,34,"UART1_TXD",["GPIO19","UART1_TXD","","","","","",""]],
+        [18,35,"I2S_BCLK",["GPIO29","","","","I2S_BCLK","PWM0","",""]],
+        [19,36,"I2S_LRCK",["GPIO30","","","","I2S_LRCK","PWM1","",""]],
+        [20,37,"I2S_DIN",["GPIO31","","","","I2S_DIN","PWM2","",""]],
+        [21,38,"I2S_DOUT",["GPIO32","","","","I2S_DOUT","","",""]],
+        [22,39,"I2S_MCLK",["GPIO33","","","","I2S_MCLK","PWM4","",""]],
+        [25,40,"LCD_CLK",["GPIO34","LCD_CLK","I2C0_SDA","UART3_RXD","","","",""]],
+        [26,41,"LCD_CS",["GPIO35","LCD_CS","I2C0_SCL","UART3_TXD","","","",""]],
+        [27,42,"LCD_RST",["GPIO36","LCD_RST","I2C1_SCL","","","","",""]],
+        [28,43,"LCD_SDA",["GPIO37","LCD_SDA","I2C1_SDA","","","","",""]],
+        [29,44,"LCD_RS",["GPIO38","","LCD_RS","","","","",""]],
+        [23,45,"GPIO20",["GPIO20","","","","","","",""]],
+        [24,46,"GPIO21",["GPIO21","","","","","PWM4","",""]],
+        [36,51,"CAN_TXD",["GPIO26","","","","","","","CAN_TXD"]],
+        [35,52,"CAN_STB",["GPIO27","","","","","PWM4","","CAN_STB"]],
+        [37,53,"CAN_RXD",["GPIO28","","","","ONEWIRE","","CAN_STB","CAN_RXD"]],
+        [44,0,"WAKEUP0",["WAKEUP0","","","","","","",""]],
+        [2,0,"VBUS",["VBUS","","","","","","",""]],
+        [14,0,"PWR_KEY",["PWR_KEY","","","","","","",""]],
+        [43,0,"WAKEUP6",["WAKEUP6","","","","","","",""]],
+        [52,0,"GPIO153",["GPIO153","","","","","","",""]],
+        [96,0,"GPIO160",["GPIO160","","","","","","",""]],
+        [73,0,"GPIO162",["GPIO162","","","","","","",""]],
+        [74,0,"GPIO164",["GPIO164","","","","","","",""]],
+        [48,0,"UART11_RX",["UART11_RX","GPIO129","","","","","",""]],
+        [49,0,"UART11_TX",["UART11_TX","GPIO128","","","","","",""]],
+        [56,0,"GPIO140",["GPIO140","","","","","","",""]],
+        [55,0,"GPIO141",["GPIO141","","","","","","",""]],
+        [54,0,"GPIO146",["GPIO146","","","","","","",""]],
+        [53,0,"GPIO147",["GPIO147","","","","","","",""]],
+        [60,0,"UART12_TX",["UART12_TX","GPIO169","","","","","",""]],
+        [59,0,"UART12_RX",["UART12_RX","GPIO168","","","","","",""]]
+    ],
+    "pin_others":[
+        [65,"1PPS"],
+        [6,"V_CHG"],
+        [7,"VBAT"],
+        [8,"VBAT"],
+        [10,"SIM_VDD"],
+        [11,"SIM_RST"],
+        [12,"SIM_DAT"],
+        [13,"SIM_CLK"],
+        [3,"USB_P"],
+        [4,"USB_N"],
+        [75,"ADC0"],
+        [68,"ADC1"],
+        [42,"ADC2"],
+        [87,"ADC3"],
+        [5,"GND"],
+        [9,"GND"],
+        [32,"GND"],
+        [34,"GND"],
+        [50,"GND"],
+        [61,"GND"],
+        [63,"GND"],
+        [70,"GND"],
+        [76,"GND"],
+        [77,"GND"],
+        [86,"GND"],
+        [93,"GND"],
+        [99,"GND"],
+        [101,"GND"],
+        [102,"GND"],
+        [103,"GND"],
+        [104,"GND"],
+        [15,"RSTN"],
+        [33,"LTE_ANT"],
+        [45,"VDD_EXT"],
+        [51,"WIFI_ANT"],
+        [62,"GNSS_ANT"],
+        [64,"GNSS_VCC"],
+        [79,"NC"],
+        [97,"NC"],
+        [100,"NC"],
+        [95,"NC"],
+        [94,"NC"],
+        [90,"NC"],
+        [91,"NC"],
+        [92,"NC"],
+        [89,"NC"],
+        [88,"NC"],
+        [84,"NC"],
+        [85,"NC"],
+        [69,"NC"],
+        [78,"NC"],
+        [71,"NC"],
+        [72,"NC"],
+        [57,"NC"],
+        [58,"NC"]
+        ]
+}

+ 1 - 1
components/pins/meta/define_check.py

@@ -101,7 +101,7 @@ def main():
         f.write(autotest_script)
 
     # 检查管脚是不是全部声明了, 包括不需要复用的
-    for item in data["pins_others"] :
+    for item in data["pin_others"] :
         pin = item[0]
         pin_list.add(pin)
     for id in range(1, data["pin_count"] + 1) :

+ 3 - 0
luat/include/luat_libs.h

@@ -215,4 +215,7 @@ LUAMOD_API int luaopen_vtool( lua_State *L );
 // icmp
 LUAMOD_API int luaopen_icmp( lua_State *L );
 
+// bluetooth
+LUAMOD_API int luaopen_bluetooth( lua_State *L );
+
 #endif