Browse Source

update:w5500直接对接lwip做准备,也为后续其他芯片SDK对接统一的lwip做准备

alienwalker 3 years ago
parent
commit
37a27a8fea

+ 6 - 2
components/ethernet/w5500/luat_lib_w5500.c

@@ -1,6 +1,6 @@
 /*
 @module  w5500
-@summary w5500
+@summary w5500的硬件初始化,和注册进network适配器
 @version 1.0
 @date    2022.04.11
 */
@@ -44,6 +44,7 @@ static int l_w5500_init(lua_State *L){
 	return 0;
 }
 
+#ifndef LUAT_USE_LWIP
 /*
 w5500配置网络信息
 @api w5500.config(ip, submask, gateway, mac, RTR, RCR, speed)
@@ -94,7 +95,7 @@ static int l_w5500_config(lua_State *L){
 	lua_pushboolean(L, 1);
 	return 1;
 }
-
+#endif
 /*
 将w5500注册进通用网络接口
 @api w5500.bind(network.xxx)
@@ -109,11 +110,14 @@ static int l_w5500_network_register(lua_State *L){
 	return 0;
 }
 
+
 #include "rotable2.h"
 static const rotable_Reg_t reg_w5500[] =
 {
     { "init",           ROREG_FUNC(l_w5500_init)},
+#ifndef LUAT_USE_LWIP
 	{ "config",           ROREG_FUNC(l_w5500_config)},
+#endif
 	{ "bind",           ROREG_FUNC(l_w5500_network_register)},
 	{ NULL,            ROREG_INT(0)}
 };

+ 443 - 15
components/ethernet/w5500/w5500.c

@@ -9,8 +9,6 @@
 
 
 #include "luat_network_adapter.h"
-#include "dhcp_def.h"
-#include "dns_def.h"
 
 extern void DBG_Printf(const char* format, ...);
 extern void DBG_HexPrintf(void *Data, unsigned int len);
@@ -22,9 +20,6 @@ extern void DBG_HexPrintf(void *Data, unsigned int len);
 #define DBG_ERR(x,y...)		DBG_Printf("%s %d:"x"\r\n", __FUNCTION__,__LINE__,##y)
 #endif
 
-#define W5500_LOCK	OS_LOCK
-#define W5500_UNLOCK OS_UNLOCK
-
 #define socket_index(n)	(n << 5)
 #define common_reg	(0)
 #define socket_reg	(1 << 3)
@@ -103,6 +98,448 @@ extern void DBG_HexPrintf(void *Data, unsigned int len);
 
 #define SOCK_BUF_LEN				(20 * 1024)
 
+#ifdef LUAT_USE_LWIP
+
+enum
+{
+	W5500_COMMON_MR,
+	W5500_COMMON_GAR0,
+	W5500_COMMON_SUBR0 = 5,
+	W5500_COMMON_MAC0 = 9,
+	W5500_COMMON_IP0 = 0x0f,
+	W5500_COMMON_INTLEVEL0 = 0x13,
+	W5500_COMMON_IR = 0x15,
+	W5500_COMMON_IMR,
+	W5500_COMMON_SOCKET_IR,
+	W5500_COMMON_SOCKET_IMR,
+	W5500_COMMON_SOCKET_RTR0,
+	W5500_COMMON_SOCKET_RCR = 0x1b,
+	W5500_COMMON_PPP,
+	W5500_COMMON_UIPR0 = 0x28,
+	W5500_COMMON_UPORT0 = 0x2c,
+	W5500_COMMON_PHY = 0x2e,
+	W5500_COMMON_VERSIONR = 0x39,
+	W5500_COMMON_QTY,
+
+	W5500_SOCKET_MR = 0,
+	W5500_SOCKET_CR,
+	W5500_SOCKET_IR,
+	W5500_SOCKET_SR,
+	W5500_SOCKET_SOURCE_PORT0,
+	W5500_SOCKET_DEST_MAC0 = 0x06,
+	W5500_SOCKET_DEST_IP0 = 0x0C,
+	W5500_SOCKET_DEST_PORT0 = 0x10,
+	W5500_SOCKET_SEGMENT0 = 0x12,
+	W5500_SOCKET_TOS = 0x15,
+	W5500_SOCKET_TTL,
+	W5500_SOCKET_RX_MEM_SIZE = 0x1e,
+	W5500_SOCKET_TX_MEM_SIZE,
+	W5500_SOCKET_TX_FREE_SIZE0 = 0x20,
+	W5500_SOCKET_TX_READ_POINT0 = 0x22,
+	W5500_SOCKET_TX_WRITE_POINT0 = 0x24,
+	W5500_SOCKET_RX_SIZE0 = 0x26,
+	W5500_SOCKET_RX_READ_POINT0 = 0x28,
+	W5500_SOCKET_RX_WRITE_POINT0 = 0x2A,
+	W5500_SOCKET_IMR = 0x2C,
+	W5500_SOCKET_IP_HEAD_FRAG_VALUE0,
+	W5500_SOCKET_KEEP_TIME = 0x2f,
+	W5500_SOCKET_QTY,
+
+	EV_W5500_IRQ = USER_EVENT_ID_START + 1,
+	EV_W5500_LINK,
+	EV_W5500_RE_INIT,
+	EV_W5500_READ,
+	EV_W5500_WRITE,
+};
+
+typedef struct
+{
+	llist_head node;
+	uint64_t tag;	//考虑到socket复用的问题,必须有tag来做比对
+	luat_ip_addr_t ip;
+	uint8_t *data;
+	uint32_t read_pos;
+	uint32_t len;
+	uint16_t port;
+	uint8_t is_sending;
+}socket_data_t;
+
+typedef struct
+{
+	uint64_t last_tx_time;
+	struct netif netif;
+	void *user_data;
+	void *task_handle;
+	void *cb_handle;
+	uint8_t auto_speed;
+	uint8_t spi_id;
+	uint8_t cs_pin;
+	uint8_t rst_pin;
+	uint8_t irq_pin;
+	uint8_t link_pin;
+	uint8_t speed_status;
+	uint8_t link_ready;
+	uint8_t inter_error;
+	uint8_t device_on;
+}w5500_ctrl_t;
+
+static w5500_ctrl_t *prv_w5500_ctrl;
+
+
+static void w5500_init_reg(w5500_ctrl_t *w5500);
+
+
+static void w5500_callback_to_nw_task(w5500_ctrl_t *w5500, uint32_t event_id, uint32_t param1, uint32_t param2, uint32_t param3)
+{
+	platform_send_event(w5500->cb_handle, event_id, param1, param2, param3);
+}
+
+
+static int32_t w5500_irq(int pin, void *args)
+{
+	w5500_ctrl_t *w5500 = (w5500_ctrl_t *)args;
+	if ((pin & 0x00ff) == w5500->irq_pin)
+	{
+		platform_send_event(w5500->task_handle, EV_W5500_IRQ, 0, 0, 0);
+	}
+	if ((pin & 0x00ff) == w5500->link_pin)
+	{
+		platform_send_event(w5500->task_handle, EV_W5500_LINK, 0, 0, 0);
+	}
+}
+
+static void w5500_xfer(w5500_ctrl_t *w5500, uint16_t address, uint8_t ctrl, uint8_t write_flag, uint8_t *data, uint32_t len)
+{
+	uint8_t temp[3];
+	BytesPutBe16(temp, address);
+	temp[2] = ctrl|write_flag;
+	luat_gpio_set(w5500->cs_pin, 0);
+	luat_spi_send(w5500->spi_id, temp, 3);
+	if (write_flag)
+	{
+		luat_spi_send(w5500->spi_id, data, len);
+	}
+	else
+	{
+		luat_spi_recv(w5500->spi_id, data, len);
+	}
+	luat_gpio_set(w5500->cs_pin, 1);
+}
+
+
+static int w5500_tx(w5500_ctrl_t *w5500, uint8_t *data, uint16_t len)
+{
+	uint8_t delay_cnt;
+	uint8_t temp;
+	uint8_t point[6];
+	uint16_t tx_free, tx_point;
+	if (!w5500->device_on) return -1;
+
+	w5500_xfer(w5500, W5500_SOCKET_TX_FREE_SIZE0, socket_reg, 0, point, 6);
+	tx_free = BytesGetBe16(point);
+	tx_point = BytesGetBe16(point + 4);
+//	if (tx_free != 2048)
+//	{
+//		DBG("%d,0x%04x,%u,%u", socket_id, tx_point, len,tx_free);
+//	}
+//	DBG_HexPrintf(data, len);
+	if (len > tx_free)
+	{
+		len = tx_free;
+	}
+
+	w5500->last_tx_time = GetSysTickMS();
+	w5500_xfer(w5500, tx_point, socket_tx, is_write, data, len);
+	tx_point += len;
+	BytesPutBe16(point, tx_point);
+	w5500_xfer(w5500, W5500_SOCKET_TX_WRITE_POINT0, socket_reg, is_write, point, 2);
+	point[0] = Sn_CR_SEND;
+	w5500_xfer(w5500, W5500_SOCKET_CR, socket_reg, is_write, point, 1);
+	return len;
+}
+
+static int w5500_rx(w5500_ctrl_t *w5500, uint8_t *data, uint16_t len)
+{
+	uint8_t delay_cnt;
+	uint8_t temp;
+	uint8_t point[4];
+	uint16_t rx_size, rx_point;
+	w5500_xfer(w5500, W5500_SOCKET_RX_SIZE0, socket_reg, 0, point, 4);
+
+	rx_size = BytesGetBe16(point);
+	rx_point = BytesGetBe16(point + 2);
+//	DBG("%d,0x%04x,%u", socket_id, rx_point, rx_size);
+	if (!rx_size) return 0;
+	if (rx_size < len)
+	{
+		len = rx_size;
+	}
+	w5500_xfer(w5500, rx_point, socket_rx, 0, data, len);
+	rx_point += len;
+	BytesPutBe16(point, rx_point);
+	w5500_xfer(w5500, W5500_SOCKET_RX_READ_POINT0, socket_reg, is_write, point, 2);
+	point[0] = Sn_CR_RECV;
+	w5500_xfer(w5500, W5500_SOCKET_CR, socket_reg, is_write, point, 1);
+	return len;
+}
+
+static void w5500_link_state(w5500_ctrl_t *w5500, uint8_t check_state)
+{
+	Buffer_Struct tx_msg_buf = {0,0,0};
+	uint32_t remote_ip;
+	int result;
+	if (w5500->link_ready != check_state)
+	{
+		DBG("link %d -> %d", w5500->link_ready, check_state);
+		w5500->link_ready = check_state;
+
+		if (w5500->link_ready)
+		{
+			w5500_callback_to_nw_task(w5500, EV_NW_STATE, 0, 1, 0);
+		}
+		else
+		{
+			w5500_callback_to_nw_task(w5500, EV_NW_STATE, 0, 0, 0);
+			if (GetSysTickMS() < (w5500->last_tx_time + 1500))
+			{
+				w5500->inter_error++;
+				DBG_ERR("link down too fast, error %u", w5500->inter_error);
+			}
+		}
+	}
+}
+
+
+
+static void w5500_init_reg(w5500_ctrl_t *w5500)
+{
+	uint8_t temp[64];
+	luat_gpio_set(w5500->rst_pin, 0);
+	msleep(5);
+	luat_gpio_set(w5500->rst_pin, 1);
+	msleep(10);
+
+	luat_gpio_close(w5500->link_pin);
+	luat_gpio_close(w5500->irq_pin);
+
+	w5500_xfer(w5500, W5500_COMMON_MR, 0, 0, temp, W5500_COMMON_QTY);
+	w5500->device_on = (0x04 == temp[W5500_COMMON_VERSIONR])?1:0;
+	w5500_link_state(w5500, w5500->device_on?(temp[W5500_COMMON_PHY] & 0x01):0);
+
+	memcpy(&temp[W5500_COMMON_MAC0], w5500->netif.hwaddr, 6);
+
+
+//	BytesPutBe16(&temp[W5500_COMMON_SOCKET_RTR0], w5500->RTR);
+	temp[W5500_COMMON_IMR] = 0;
+	temp[W5500_COMMON_SOCKET_IMR] = 0x01;
+//	temp[W5500_COMMON_SOCKET_RCR] = w5500->RCR;
+//	DBG_HexPrintf(temp + W5500_COMMON_SOCKET_RTR0, 3);
+	w5500_xfer(w5500, W5500_COMMON_MR, 0, is_write, temp, W5500_COMMON_QTY);
+	memset(temp, 0, sizeof(temp));
+	w5500_xfer(w5500, W5500_COMMON_MR, 0, 0,  temp, W5500_COMMON_QTY);
+
+	temp[0] = 16;
+	temp[1] = 16;
+	w5500_xfer(w5500, W5500_SOCKET_RX_MEM_SIZE, socket_reg, is_write, temp, 2);
+	temp[0] = Sn_IR_SEND_OK|Sn_IR_TIMEOUT|Sn_IR_RECV;
+	w5500_xfer(w5500, W5500_SOCKET_IMR, socket_reg, is_write, temp, 1);
+	temp[0] = Sn_MR_MACRAW|Sn_MR_MFEN;
+	temp[1] = Sn_CR_OPEN;
+	w5500_xfer(w5500, W5500_SOCKET_MR, socket_reg, is_write, temp, 2);
+
+	luat_gpio_t gpio = {0};
+	gpio.pin = w5500->irq_pin;
+	gpio.mode = Luat_GPIO_IRQ;
+	gpio.pull = Luat_GPIO_PULLUP;
+	gpio.irq = Luat_GPIO_FALLING;
+	gpio.irq_cb = w5500_irq;
+	gpio.irq_args = w5500;
+	luat_gpio_setup(&gpio);
+
+	gpio.pin = w5500->link_pin;
+	gpio.pull = Luat_GPIO_DEFAULT;
+	gpio.irq = Luat_GPIO_BOTH;
+	gpio.irq_cb = w5500_irq;
+	gpio.irq_args = w5500;
+	luat_gpio_setup(&gpio);
+
+	if (w5500->auto_speed)
+	{
+		temp[0] = 0x78;
+		w5500_xfer(w5500, W5500_COMMON_PHY, 0, is_write, temp, 1);
+		temp[0] = 0x78+ 0x80;
+		w5500_xfer(w5500, W5500_COMMON_PHY, 0, is_write, temp, 1);
+	}
+	w5500->inter_error = 0;
+
+}
+
+static int32_t w5500_dummy_callback(void *pData, void *pParam)
+{
+	return 0;
+}
+
+static void w5500_read_irq(w5500_ctrl_t *w5500)
+{
+	OS_EVENT socket_event;
+	uint8_t temp[1];
+	w5500_xfer(w5500, W5500_SOCKET_IR, socket_reg, 0, temp, 1);
+	w5500_xfer(w5500, W5500_SOCKET_IR, socket_reg, is_write, temp, 1);
+	if (temp[0] & Sn_IR_SEND_OK)
+	{
+	}
+	else if (temp[0] & Sn_IR_RECV)
+	{
+	}
+	else if (temp[0] & Sn_IR_TIMEOUT)
+	{
+	}
+}
+
+
+
+static void w5500_task(void *param)
+{
+	w5500_ctrl_t *w5500 = (w5500_ctrl_t *)param;
+	OS_EVENT event;
+	int result;
+	uint32_t sleep_time;
+	uint8_t temp[64];
+	PV_Union uPV;
+	w5500_init_reg(w5500);
+	while(1)
+	{
+		if (w5500->inter_error >= 2)
+		{
+			DBG("w5500 error too much, reboot");
+			w5500_init_reg(w5500);
+		}
+		sleep_time = 500;
+		if (w5500->link_ready)
+		{
+			sleep_time = 1000;
+		}
+		else if (w5500->link_pin != 0xff)
+		{
+			sleep_time = 0;
+		}
+		result = platform_wait_event(w5500->task_handle, 0, &event, NULL, sleep_time);
+		w5500_xfer(w5500, W5500_COMMON_MR, 0, 0, temp, W5500_COMMON_QTY);
+		w5500->device_on = (0x04 == temp[W5500_COMMON_VERSIONR])?1:0;
+		if (w5500->device_on && (temp[W5500_COMMON_SOCKET_IMR] != 0x01))
+		{
+			w5500_init_reg(w5500);
+		}
+		if (!w5500->device_on)
+		{
+			w5500_link_state(w5500, 0);
+			luat_gpio_close(w5500->link_pin);
+			luat_gpio_close(w5500->irq_pin);
+		}
+		else
+		{
+			w5500_link_state(w5500, temp[W5500_COMMON_PHY] & 0x01);
+			w5500->speed_status = temp[W5500_COMMON_PHY] & (3 << 1);
+		}
+		if (result)
+		{
+			continue;
+		}
+
+
+
+		switch(event.ID)
+		{
+		case EV_W5500_IRQ:
+			if (w5500->device_on)
+			{
+				w5500_read_irq(w5500);
+			}
+			break;
+		case EV_W5500_READ:
+			break;
+		case EV_W5500_WRITE:
+			break;
+		case EV_W5500_RE_INIT:
+			w5500_init_reg(w5500);
+			break;
+		case EV_W5500_LINK:
+			w5500_link_state(w5500, !luat_gpio_get(w5500->link_pin));
+			break;
+		}
+	}
+}
+
+
+
+void w5500_init(luat_spi_t* spi, uint8_t irq_pin, uint8_t rst_pin, uint8_t link_pin)
+{
+	uint8_t *uid;
+	size_t t, i;
+	if (!prv_w5500_ctrl)
+	{
+		w5500_ctrl_t *w5500 = malloc(sizeof(w5500_ctrl_t));
+		memset(w5500, 0, sizeof(w5500_ctrl_t));
+		w5500->spi_id = spi->id;
+		w5500->cs_pin = spi->cs;
+		w5500->irq_pin = irq_pin;
+		w5500->rst_pin = rst_pin;
+		w5500->link_pin = link_pin;
+		w5500->auto_speed = 1;
+		spi->cs = 0xff;
+		luat_spi_setup(spi);
+		luat_gpio_t gpio = {0};
+		gpio.pin = w5500->cs_pin;
+		gpio.mode = Luat_GPIO_OUTPUT;
+		gpio.pull = Luat_GPIO_DEFAULT;
+		luat_gpio_setup(&gpio);
+		luat_gpio_set(w5500->cs_pin, 1);
+
+		gpio.pin = w5500->rst_pin;
+		luat_gpio_setup(&gpio);
+		luat_gpio_set(w5500->rst_pin, 0);
+
+		luat_thread_t thread;
+		thread.task_fun = w5500_task;
+		thread.name = "w5500";
+		thread.stack_size = 4 * 1024;
+		thread.priority = 3;
+		thread.userdata = w5500;
+		platform_create_task(&thread);
+		prv_w5500_ctrl = w5500;
+		w5500->task_handle = thread.handle;
+		prv_w5500_ctrl->device_on = 1;
+
+	}
+}
+
+uint8_t w5500_device_ready(void)
+{
+	if (prv_w5500_ctrl)
+	{
+		return prv_w5500_ctrl->device_on;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+
+void w5500_register_adapter(int index)
+{
+	if (prv_w5500_ctrl)
+	{
+		//network_register_adapter(index, &prv_w5500_adapter, prv_w5500_ctrl);
+	}
+}
+
+#else
+#include "dhcp_def.h"
+#include "dns_def.h"
+#define W5500_LOCK	OS_LOCK
+#define W5500_UNLOCK OS_UNLOCK
+
 enum
 {
 	W5500_COMMON_MR,
@@ -1814,14 +2251,5 @@ void w5500_register_adapter(int index)
 		network_register_adapter(index, &prv_w5500_adapter, prv_w5500_ctrl);
 	}
 }
-#else
-void w5500_init(luat_spi_t* spi, uint8_t irq_pin, uint8_t rst_pin) {;}
-void w5500_set_static_ip(uint32_t ipv4, uint32_t submask, uint32_t gateway) {;}
-void w5500_set_mac(uint8_t mac[6])  {;}
-void w5500_set_param(uint16_t timeout, uint8_t retry, uint8_t auto_speed, uint8_t force_arp) {;}
-int w5500_reset(void) {return -1;}
-uint32_t w5500_string_to_ip(const char *string, uint32_t len) {return 0;}
-void w5500_array_to_mac(uint8_t *array, uint32_t *mac1, uint16_t *mac2) {return;}
-uint8_t w5500_device_ready(void) {return 0;}
-void w5500_register_adapter(int index) {;}
+#endif
 #endif

+ 684 - 0
components/network/adapter/luat_lib_network.c

@@ -22,6 +22,7 @@ typedef struct
 	uint8_t adapter_index;
 }luat_network_ctrl_t;
 
+#ifdef LUAT_USE_LWIP
 
 static int32_t l_network_callback(lua_State *L, void* ptr)
 {
@@ -302,6 +303,688 @@ static int l_network_linkup(lua_State *L)
 	return 2;
 
 
+}
+
+/*
+作为客户端连接服务器
+@api network.connect(ctrl, ip, remote_port)
+@user_data network.create得到的ctrl
+@string or int ip或者域名,如果是IPV4,可以是大端格式的int值
+@int 服务器端口号,小端格式
+@return boolean true有异常发生,false没有异常,如果有error则不需要看下一个返回值了,如果有异常,后续要close
+@return boolean true已经connect,false没有connect,之后需要接收network.ON_LINE消息
+@usage local error, result = network.connect(ctrl, "xxx.xxx.xxx.xxx", xxxx)
+*/
+static int l_network_connect(lua_State *L)
+{
+	luat_network_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
+	luat_ip_addr_t ip_addr;
+	const char *ip;
+	size_t ip_len;
+	ip_addr.type = 0xff;
+	if (lua_isinteger(L, 2))
+	{
+		ip_addr.type = IPADDR_TYPE_V4;
+		ip_addr.u_addr.ip4.addr = lua_tointeger(L, 2);
+		ip = NULL;
+		ip_len = 0;
+	}
+	else
+	{
+		ip_len = 0;
+	    ip = luaL_checklstring(L, 2, &ip_len);
+	}
+	uint16_t remote_port = luaL_checkinteger(L, 3);
+	int result = network_connect(l_ctrl->netc, ip, ip_len, ip_addr.type?NULL:&ip_addr, remote_port, 0);
+	lua_pushboolean(L, result < 0);
+	lua_pushboolean(L, result == 0);
+	return 2;
+}
+
+/*
+作为客户端断开连接
+@api network.discon(ctrl)
+@user_data network.create得到的ctrl
+@return
+boolean true有异常发生,false没有异常,如果有error则不需要看下一个返回值了
+boolean true已经断开,false没有断开,之后需要接收network.CLOSED消息
+@usage local error, result = network.discon(ctrl)
+*/
+static int l_network_disconnect(lua_State *L)
+{
+	luat_network_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
+	int result = network_close(l_ctrl->netc, 0);
+	lua_pushboolean(L, result < 0);
+	lua_pushboolean(L, result == 0);
+	return 2;
+}
+
+/*
+强制关闭socket
+@api network.close(ctrl)
+@user_data network.create得到的ctrl
+*/
+static int l_network_close(lua_State *L)
+{
+	luat_network_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
+	network_force_close_socket(l_ctrl->netc);
+	return 0;
+}
+
+/*
+发送数据给对端
+@api network.tx(ctrl, data, ip, port, flag)
+@user_data network.create得到的ctrl
+@string or user_data zbuff  要发送的数据
+@string or int 对端IP,如果是TCP应用则忽略,如果是UDP,如果留空则用connect时候的参数,如果是IPV4,可以是大端格式的int值
+@int 对端端口号,小端格式,如果是TCP应用则忽略,如果是UDP,如果留空则用connect时候的参数
+@int 发送参数,目前预留,不起作用
+@return boolean true有异常发生,false没有异常,如果有error则不需要看下一个返回值了,如果有异常,后续要close
+@return boolean true缓冲区满了,false没有异常,如果true,则需要等待一段时间或者等到network.TX_OK消息后再尝试发送,同时忽略下一个返回值
+@return boolean true已经收到应答,false没有收到应答,之后需要接收network.TX_OK消息, 也可以忽略继续发送,直到full==true
+@usage local error, full, result = network.tx(ctrl, "123456", "xxx.xxx.xxx.xxx", xxxx)
+*/
+static int l_network_tx(lua_State *L)
+{
+	char ip_buf[68];
+	luat_network_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
+	luat_ip_addr_t ip_addr;
+	luat_zbuff_t *buff = NULL;
+	const char *ip;
+	const char *data;
+	size_t ip_len, data_len;
+	ip_addr.type = 0xff;
+	if (lua_isstring(L, 2))
+	{
+		data_len = 0;
+		data = luaL_checklstring(L, 2, &data_len);
+	}
+	else
+	{
+		buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
+		data = buff->addr;
+		data_len = buff->used;
+	}
+
+	if (lua_isstring(L, 3))
+	{
+		ip_len = 0;
+	    ip = luaL_checklstring(L, 3, &ip_len);
+	    memcpy(ip_buf, ip, ip_len);
+	    ip_buf[ip_len] = 0;
+	    ipaddr_aton(ip_buf, &ip_addr);
+
+	}
+	else if (lua_isinteger(L, 3))
+	{
+		ip_addr.type = 0;
+		ip_addr.u_addr.ip4.addr = lua_tointeger(L, 3);
+	}
+	uint32_t tx_len;
+	int result = network_tx(l_ctrl->netc, data, data_len, luaL_optinteger(L, 5, 0), (ip_addr.type != 0xff)?&ip_addr:NULL, luaL_optinteger(L, 4, 0), &tx_len, 0);
+	lua_pushboolean(L, result < 0);
+	lua_pushboolean(L, tx_len != data_len);
+	lua_pushboolean(L, result == 0);
+	return 3;
+}
+
+/*
+接收对端发出的数据,注意数据已经缓存在底层,使用本函数只是提取出来,UDP模式下一次只会取出一个数据包
+@api network.rx(ctrl, buff, flag)
+@user_data network.create得到的ctrl
+@user_data zbuff 存放接收的数据,如果缓冲区不够大会自动扩容
+@int 接收参数,目前预留,不起作用
+@return boolean true有异常发生,false没有异常,如果有异常,后续要close
+@return int 本次接收到数据长度
+@return string 对端IP,只有UDP模式下才有意义,TCP模式返回nil,注意返回的格式,如果是IPV4,1byte 0x00 + 4byte地址 如果是IPV6,1byte 0x01 + 16byte地址
+@return int 对端port,只有UDP模式下才有意义,TCP模式返回0
+@usage local error, data_len, ip, port = network.rx(ctrl, buff)
+*/
+static int l_network_rx(lua_State *L)
+{
+	luat_network_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
+	luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
+
+	luat_ip_addr_t ip_addr;
+	uint8_t ip[17];
+	uint16_t port;
+	uint8_t new_flag = 0;
+	int rx_len;
+	int total_len;
+	int result = network_rx(l_ctrl->netc, NULL, 0, 0, NULL, NULL, &total_len);
+	if (result < 0)
+	{
+		lua_pushboolean(L, 1);
+		lua_pushinteger(L, 0);
+		lua_pushnil(L);
+		lua_pushnil(L);
+	}
+	else if (!total_len)
+	{
+		lua_pushboolean(L, 0);
+		lua_pushinteger(L, 0);
+		lua_pushnil(L);
+		lua_pushnil(L);
+	}
+	else
+	{
+		if ((buff->len - buff->used) < total_len)
+		{
+			__zbuff_resize(buff, total_len + buff->used);
+		}
+		result = network_rx(l_ctrl->netc, buff->addr + buff->used, total_len, 0, &ip_addr, &port, &rx_len);
+		if (result < 0)
+		{
+			lua_pushboolean(L, 1);
+			lua_pushinteger(L, 0);
+			lua_pushnil(L);
+			lua_pushnil(L);
+		}
+		else if (!rx_len)
+		{
+			lua_pushboolean(L, 0);
+			lua_pushinteger(L, 0);
+			lua_pushnil(L);
+			lua_pushnil(L);
+		}
+		else
+		{
+			buff->used += rx_len;
+			lua_pushboolean(L, 0);
+			lua_pushinteger(L, rx_len);
+			if (l_ctrl->netc->is_tcp)
+			{
+				lua_pushnil(L);
+				lua_pushnil(L);
+			}
+			else
+			{
+				if (IPADDR_TYPE_V6 == ip_addr.type)
+				{
+					ip[0] = 0;
+					memcpy(ip + 1, &ip_addr.u_addr.ip4.addr, 4);
+					lua_pushlstring(L, ip, 5);
+				}
+				else
+				{
+					ip[0] = 1;
+					memcpy(ip + 1, ip_addr.u_addr.ip6.addr, 16);
+					lua_pushlstring(L, ip, 17);
+				}
+				lua_pushinteger(L, port);
+			}
+		}
+	}
+	return 4;
+}
+
+/*
+等待新的socket消息,在连接成功和发送数据成功后,使用一次将network状态转换到接收新数据
+@api network.wait(ctrl)
+@user_data network.create得到的ctrl
+@return boolean true有异常发生,false没有异常,如果有异常,后续要close
+@return boolean true有新的数据需要接收,false没有数据,之后需要接收network.EVENT消息
+@usage local error, result = network.wait(ctrl)
+*/
+static int l_network_wait(lua_State *L)
+{
+	luat_network_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
+	int result = network_wait_event(l_ctrl->netc, NULL, 0, NULL);
+	lua_pushboolean(L, result < 0);
+	lua_pushboolean(L, result == 0);
+	return 2;
+}
+
+/*
+作为服务端开始监听
+@api network.listen(ctrl)
+@user_data network.create得到的ctrl
+@return boolean true有异常发生,false没有异常,如果有error则不需要看下一个返回值了,如果有异常,后续要close
+@return boolean true已经connect,false没有connect,之后需要接收network.ON_LINE消息
+@usage local error, result = network.listen(ctrl)
+*/
+static int l_network_listen(lua_State *L)
+{
+	luat_network_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
+	int result = network_listen(l_ctrl->netc, 0);
+	lua_pushboolean(L, result < 0);
+	lua_pushboolean(L, result == 0);
+	return 2;
+}
+
+/*
+作为服务端接收到一个新的客户端,注意,如果是类似W5500的硬件协议栈不支持1对多,则不需要第二个参数
+@api network.accept(ctrl)
+@user_data network.create得到的ctrl,这里是服务器端
+@string or function or nil string为消息通知的taskName,function则为回调函数,和network.create参数一致
+@return boolean true有异常发生,false没有异常,如果有error则不需要看下一个返回值了,如果有异常,后续要close
+@return user_data or nil 如果支持1对多,则会返回新的ctrl,自动create,如果不支持则返回nil
+@usage local error, new_netc = network.listen(ctrl, cb)
+*/
+static int l_network_accept(lua_State *L)
+{
+	luat_network_ctrl_t *old_ctrl = l_get_ctrl(L, 1);
+	if (network_accept_enable(old_ctrl->netc))
+	{
+		luat_network_ctrl_t *new_ctrl = (luat_network_ctrl_t *)lua_newuserdata(L, sizeof(luat_network_ctrl_t));
+		if (!new_ctrl)
+		{
+			lua_pushboolean(L, 0);
+			lua_pushnil(L);
+			return 2;
+		}
+		new_ctrl->adapter_index = old_ctrl->adapter_index;
+		new_ctrl->netc = network_alloc_ctrl(old_ctrl->adapter_index);
+		if (!new_ctrl->netc)
+		{
+			LLOGD("create fail");
+			lua_pushboolean(L, 0);
+			lua_pushnil(L);
+			return 2;
+		}
+		network_init_ctrl(new_ctrl->netc, NULL, luat_lib_network_callback, new_ctrl);
+		if (lua_isfunction(L, 2))
+		{
+			lua_pushvalue(L, 2);
+			new_ctrl->cb_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+			new_ctrl->task_name = NULL;
+		}
+		else if (lua_isstring(L, 2))
+		{
+			new_ctrl->cb_ref = 0;
+			size_t len;
+			const char *buf;
+			buf = lua_tolstring(L, 2, &len);//取出字符串数据
+			new_ctrl->task_name = luat_heap_malloc(len + 1);
+			memset(new_ctrl->task_name, 0, len + 1);
+			memcpy(new_ctrl->task_name, buf, len);
+		}
+		if (network_socket_accept(old_ctrl, new_ctrl))
+		{
+			lua_pushboolean(L, 0);
+			lua_pushnil(L);
+			return 2;
+		}
+		else
+		{
+			lua_pushboolean(L, 1);
+			luaL_setmetatable(L, LUAT_NW_CTRL_TYPE);
+			return 2;
+		}
+
+	}
+	else
+	{
+		lua_pushboolean(L, !network_socket_accept(old_ctrl->netc, NULL));
+		lua_pushnil(L);
+		return 2;
+	}
+}
+
+/*
+主动释放掉network_ctrl
+@api    network.release(ctrl)
+@user_data	network.create得到的ctrl
+@usage network.release(ctrl)
+*/
+static int l_network_release(lua_State *L)
+{
+	return l_network_gc(L);
+}
+
+/*
+设置DNS服务器
+@api    network.setDNS(adapter_index, dns_index, ip)
+@int 适配器序号, 只能是network.ETH0,network.STA,network.AP,如果不填,会选择最后一个注册的适配器
+@int dns服务器序号,从1开始
+@string or int dns,如果是IPV4,可以是大端格式的int值
+@return boolean 成功返回true,失败返回false
+@usage network.setDNS(network.ETH0, 1, "114.114.114.114")
+*/
+static int l_network_set_dns(lua_State *L)
+{
+	char ip_buf[68];
+	int adapter_index = luaL_optinteger(L, 1, network_get_last_register_adapter());
+	if (adapter_index < 0 || adapter_index >= NW_ADAPTER_QTY)
+	{
+		lua_pushboolean(L, 0);
+		return 1;
+	}
+	int dns_index = luaL_optinteger(L, 2, 1);
+	luat_ip_addr_t ip_addr;
+	const char *ip;
+	size_t ip_len;
+	ip_addr.type = 0xff;
+	if (lua_isinteger(L, 3))
+	{
+		ip_addr.type = 0;
+		ip_addr.u_addr.ip4.addr = lua_tointeger(L, 3);
+		ip = NULL;
+		ip_len = 0;
+	}
+	else
+	{
+		ip_len = 0;
+	    ip = luaL_checklstring(L, 3, &ip_len);
+	    memcpy(ip_buf, ip, ip_len);
+	    ip_buf[ip_len] = 0;
+	    ipaddr_aton(ip_buf, &ip_addr);
+	}
+	network_set_dns_server(adapter_index, dns_index - 1, &ip_addr);
+	lua_pushboolean(L, 1);
+	return 1;
+}
+
+#include "rotable2.h"
+static const rotable_Reg_t reg_network_adapter[] =
+{
+	{"create",			ROREG_FUNC(l_network_create)},
+	{"debug",		ROREG_FUNC(l_network_set_debug)},
+	{"config",		ROREG_FUNC(l_network_config)},
+	{"linkup",			ROREG_FUNC(l_network_linkup)},
+	{"connect",			ROREG_FUNC(l_network_connect)},
+	{"listen",			ROREG_FUNC(l_network_listen)},
+	{"accept",			ROREG_FUNC(l_network_accept)},
+	{"discon",			ROREG_FUNC(l_network_disconnect)},
+	{"close",			ROREG_FUNC(l_network_close)},
+	{"tx",			ROREG_FUNC(l_network_tx)},
+	{"rx",			ROREG_FUNC(l_network_rx)},
+	{"wait",			ROREG_FUNC(l_network_wait)},
+	//{"listen",			ROREG_FUNC(l_network_listen)},
+	//{"accept",			ROREG_FUNC(l_network_accept)},
+	{"release",			ROREG_FUNC(l_network_release)},
+	{ "setDNS",           ROREG_FUNC(l_network_set_dns)},
+    { "ETH0",           ROREG_INT(NW_ADAPTER_INDEX_ETH0)},
+	{ "STA",          	ROREG_INT(NW_ADAPTER_INDEX_STA)},
+	{ "AP",     		ROREG_INT(NW_ADAPTER_INDEX_AP)},
+    { "LINK",           ROREG_INT(EV_NW_RESULT_LINK & 0x0fffffff)},
+	{ "ON_LINE",          	ROREG_INT(EV_NW_RESULT_CONNECT & 0x0fffffff)},
+	{ "EVENT",          	ROREG_INT(EV_NW_RESULT_EVENT & 0x0fffffff)},
+	{ "TX_OK",     		ROREG_INT(EV_NW_RESULT_TX & 0x0fffffff)},
+	{ "CLOSED",     		ROREG_INT(EV_NW_RESULT_CLOSE & 0x0fffffff)},
+	{ NULL,            ROREG_INT(0)}
+};
+
+#else
+static int32_t l_network_callback(lua_State *L, void* ptr)
+{
+    rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
+    luat_network_ctrl_t *l_ctrl =(luat_network_ctrl_t *)msg->ptr;
+    if (l_ctrl->netc)
+    {
+    	if (l_ctrl->cb_ref)
+    	{
+            lua_geti(L, LUA_REGISTRYINDEX, l_ctrl->cb_ref);
+            if (lua_isfunction(L, -1)) {
+            	lua_pushlightuserdata(L, l_ctrl);
+            	lua_pushinteger(L, msg->arg1);
+            	lua_pushinteger(L, msg->arg2);
+                lua_call(L, 3, 0);
+            }
+    	}
+    	else if (l_ctrl->task_name)
+    	{
+    	    lua_getglobal(L, "sys_send");
+    	    if (lua_isfunction(L, -1)) {
+    	        lua_pushstring(L, l_ctrl->task_name);
+    	        lua_pushinteger(L, msg->arg1);
+    	        lua_pushinteger(L, msg->arg2);
+    	        lua_call(L, 3, 0);
+    	    }
+    	}
+    	else
+    	{
+    	    lua_getglobal(L, "sys_pub");
+    	    if (lua_isfunction(L, -1)) {
+    	        lua_pushstring(L, LUAT_NW_CTRL_TYPE);
+    	        lua_pushinteger(L, l_ctrl->netc->adapter_index);
+    	        lua_pushinteger(L, l_ctrl->netc->socket_id);
+    	        lua_pushinteger(L, msg->arg1);
+    	        lua_pushinteger(L, msg->arg2);
+    	        lua_call(L, 5, 0);
+    	    }
+    	}
+    }
+    lua_pushinteger(L, 0);
+    return 1;
+}
+
+static int32_t luat_lib_network_callback(void *data, void *param)
+{
+	OS_EVENT *event = (OS_EVENT *)data;
+	rtos_msg_t msg;
+    msg.handler = l_network_callback;
+    msg.ptr = param;
+    msg.arg1 = event->ID & 0x0fffffff;
+    msg.arg2 = event->Param1;
+    luat_msgbus_put(&msg, 0);
+    return 0;
+}
+
+static luat_network_ctrl_t * l_get_ctrl(lua_State *L, int index)
+{
+	if (luaL_testudata(L, 1, LUAT_NW_CTRL_TYPE))
+	{
+		return ((luat_network_ctrl_t *)luaL_checkudata(L, 1, LUAT_NW_CTRL_TYPE));
+	}
+	else
+	{
+		return ((luat_network_ctrl_t *)lua_touserdata(L, 1));
+	}
+}
+
+// __gc
+static int l_network_gc(lua_State *L)
+{
+	luat_network_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
+    if (l_ctrl->netc)
+    {
+    	network_force_close_socket(l_ctrl->netc);
+    	network_release_ctrl(l_ctrl->netc);
+    	l_ctrl->netc = NULL;
+    }
+    if (l_ctrl->cb_ref)
+    {
+        luaL_unref(L, LUA_REGISTRYINDEX, l_ctrl->cb_ref);
+        l_ctrl->cb_ref = 0;
+    }
+    if (l_ctrl->task_name)
+    {
+    	luat_heap_free(l_ctrl->task_name);
+    	l_ctrl->task_name = 0;
+    }
+    return 0;
+}
+
+/*
+在某个适配的网卡上申请一个network_ctrl
+@api    network.create(adapter, cb)
+@int 适配器序号, 只能是network.ETH0,network.STA,network.AP,如果不填,会选择最后一个注册的适配器
+@string or function string为消息通知的taskName,function则为回调函数,如果固件没有内置sys_wait,则必须是function
+当通过回调函数回调消息时,输入给function一共3个参数:
+param1为申请的network_ctrl
+param2为具体的消息,只能是network.RESET, network.LINK, network.ON_LINE, network.TX_OK, network.RX_NEW, network.CLOSE等等
+param3为消息对应的参数
+@return some 成功返回network_ctrl,失败返回nil
+@usage
+local netc = network.create(network.ETH0, socket_cb_fun)	--以太网网卡上申请一个network_ctrl,通过socket_cb_fun回调相关消息
+local netc = network.create(network.ETH0, "IOT_TASK")	--以太网网卡上申请一个network_ctrl,通过sendMsg方式通知taskName为"IOT_TASK"回调相关消息
+
+*/
+static int l_network_create(lua_State *L)
+{
+	int adapter_index = luaL_optinteger(L, 1, network_get_last_register_adapter());
+	if (adapter_index < 0 || adapter_index >= NW_ADAPTER_QTY)
+	{
+		lua_pushnil(L);
+		return 1;
+	}
+
+	luat_network_ctrl_t *l_ctrl = (luat_network_ctrl_t *)lua_newuserdata(L, sizeof(luat_network_ctrl_t));
+	if (!l_ctrl)
+	{
+		lua_pushnil(L);
+		return 1;
+	}
+	l_ctrl->adapter_index = adapter_index;
+	l_ctrl->netc = network_alloc_ctrl(adapter_index);
+	if (!l_ctrl->netc)
+	{
+		LLOGD("create fail");
+		lua_pushnil(L);
+		return 1;
+	}
+	network_init_ctrl(l_ctrl->netc, NULL, luat_lib_network_callback, l_ctrl);
+	if (lua_isfunction(L, 2))
+	{
+        lua_pushvalue(L, 2);
+        l_ctrl->cb_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+        l_ctrl->task_name = NULL;
+	}
+	else if (lua_isstring(L, 2))
+	{
+		l_ctrl->cb_ref = 0;
+	    size_t len;
+	    const char *buf;
+        buf = lua_tolstring(L, 2, &len);//取出字符串数据
+		l_ctrl->task_name = luat_heap_malloc(len + 1);
+		memset(l_ctrl->task_name, 0, len + 1);
+		memcpy(l_ctrl->task_name, buf, len);
+	}
+	luaL_setmetatable(L, LUAT_NW_CTRL_TYPE);
+	return 1;
+}
+
+/*
+配置是否打开debug信息
+@api network.debug(ctrl, onoff)
+@user_data network.create得到的ctrl
+@boolean true 打开debug开关
+@return nil 无返回值
+@usage network.debug(ctrl, true)
+*/
+static int l_network_set_debug(lua_State *L)
+{
+	luat_network_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
+	if (lua_isboolean(L, 2))
+	{
+		l_ctrl->netc->is_debug = lua_toboolean(L, 2);
+	}
+	return 0;
+}
+
+/*
+配置network一些信息,
+@api network.config(ctrl, local_port, is_udp, is_tls, keep_idle, keep_interval, keep_cnt, server_cert, client_cert, client_key, client_password)
+@user_data network.create得到的ctrl
+@int 本地端口号,小端格式,如果不写,则自动分配一个,如果用户填了端口号则需要小于60000, 默认不写
+@boolean 是否是UDP,默认false
+@boolean 是否是加密传输,默认false
+@int tcp keep live模式下的idle时间,如果留空则表示不启用,如果是不支持标准posix接口的网卡(比如W5500),则为心跳间隔
+@int tcp keep live模式下的探测间隔时间
+@int tcp keep live模式下的探测次数
+@string TCP模式下的服务器ca证书数据,UDP模式下的PSK,不需要加密传输写nil,后续参数也全部nil
+@string TCP模式下的客户端ca证书数据,UDP模式下的PSK-ID,TCP模式下如果不需要验证客户端证书时,忽略,一般不需要验证客户端证书
+@string TCP模式下的客户端私钥加密数据
+@string TCP模式下的客户端私钥口令数据
+@return nil 无返回值
+@usage network.config(ctrl)	--最普通的TCP传输
+network.config(ctrl, nil, nil ,true)	--最普通的加密TCP传输,证书都不用验证的那种
+*/
+static int l_network_config(lua_State *L)
+{
+	luat_network_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
+	uint8_t is_udp = 0;
+	uint8_t is_tls = 0;
+	int param_pos = 1;
+	uint32_t keep_idle, keep_interval, keep_cnt;
+
+	const char *server_cert = NULL;
+	const char *client_cert = NULL;
+	const char *client_key = NULL;
+	const char *client_password = NULL;
+	size_t server_cert_len, client_cert_len, client_key_len, client_password_len;
+
+	uint16_t local_port = luaL_optinteger(L, ++param_pos, 0);
+	if (lua_isboolean(L, ++param_pos))
+	{
+		is_udp = lua_toboolean(L, param_pos);
+	}
+	if (lua_isboolean(L, ++param_pos))
+	{
+		is_tls = lua_toboolean(L, param_pos);
+	}
+	keep_idle = luaL_optinteger(L, ++param_pos, 0);
+	keep_interval = luaL_optinteger(L, ++param_pos, 0);
+	keep_cnt = luaL_optinteger(L, ++param_pos, 0);
+	if (lua_isstring(L, ++param_pos))
+	{
+		server_cert_len = 0;
+		server_cert = luaL_checklstring(L, param_pos, &server_cert_len);
+	}
+	if (lua_isstring(L, ++param_pos))
+	{
+		client_cert_len = 0;
+		client_cert = luaL_checklstring(L, param_pos, &client_cert_len);
+	}
+
+	if (lua_isstring(L, ++param_pos))
+	{
+		client_key_len = 0;
+		client_key = luaL_checklstring(L, param_pos, &client_key_len);
+	}
+	if (lua_isstring(L, ++param_pos))
+	{
+		client_password_len = 0;
+		client_password = luaL_checklstring(L, param_pos, &client_password_len);
+	}
+	network_set_base_mode(l_ctrl->netc, !is_udp, 10000, keep_idle, keep_idle, keep_interval, keep_cnt);
+	network_set_local_port(l_ctrl->netc, local_port);
+	if (is_tls)
+	{
+		network_init_tls(l_ctrl->netc, (server_cert || client_cert)?2:0);
+		if (is_udp)
+		{
+			network_set_psk_info(l_ctrl->netc, server_cert, server_cert_len, client_key, client_key_len);
+		}
+		else
+		{
+			if (server_cert)
+			{
+				network_set_server_cert(l_ctrl->netc, server_cert, server_cert_len);
+			}
+			if (client_cert)
+			{
+				network_set_client_cert(l_ctrl->netc, client_cert, client_cert_len,
+						client_key, client_key_len,
+						client_password, client_password_len);
+			}
+		}
+	}
+	else
+	{
+		network_deinit_tls(l_ctrl->netc);
+	}
+	return 0;
+}
+
+/*
+等待网卡linkup
+@api network.linkup(ctrl)
+@user_data network.create得到的ctrl
+@return boolean true有异常发生,false没有异常,如果有error则不需要看下一个返回值了
+@return boolean true已经linkup,false没有linkup,之后需要接收network.LINK消息
+@usage local error, result = network.linkup(ctrl)
+*/
+static int l_network_linkup(lua_State *L)
+{
+	luat_network_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
+	int result = network_wait_link_up(l_ctrl->netc, 0);
+	lua_pushboolean(L, result < 0);
+	lua_pushboolean(L, result == 0);
+	return 2;
+
+
 }
 
 /*
@@ -721,6 +1404,7 @@ static const rotable_Reg_t reg_network_adapter[] =
 	{ "CLOSED",     		ROREG_INT(EV_NW_RESULT_CLOSE & 0x0fffffff)},
 	{ NULL,            ROREG_INT(0)}
 };
+#endif
 
 LUAMOD_API int luaopen_network_adapter( lua_State *L ) {
     luat_newlib2(L, reg_network_adapter);

File diff suppressed because it is too large
+ 1888 - 0
components/network/adapter/luat_network_adapter.c


+ 16 - 4
components/network/adapter/luat_network_adapter.h

@@ -3,7 +3,6 @@
 #include "luat_base.h"
 #ifdef LUAT_USE_NETWORK
 #include "luat_rtos.h"
-
 #ifdef LUAT_USE_TLS
 #include "mbedtls/ssl.h"
 #include "mbedtls/platform.h"
@@ -14,6 +13,10 @@
 #include "mbedtls/entropy.h"
 #include "mbedtls/sha1.h"
 #endif
+#ifdef LUAT_USE_LWIP
+#include "lwip/netif.h"
+#include "lwip/ip.h"
+#endif
 #ifndef __BSP_COMMON_H__
 #include "c_common.h"
 #endif
@@ -73,6 +76,9 @@ enum
 
 };
 
+#ifdef LUAT_USE_LWIP
+#define luat_ip_addr_t ip_addr_t
+#else
 typedef struct
 {
 	union
@@ -83,6 +89,10 @@ typedef struct
 	};
 	uint8_t is_ipv6;
 }luat_ip_addr_t;
+uint8_t network_string_is_ipv4(const char *string, uint32_t len);
+uint32_t network_string_to_ipv4(const char *string, uint32_t len);
+int network_string_to_ipv6(const char *string, luat_ip_addr_t *ip_addr);
+#endif
 
 typedef struct
 {
@@ -126,7 +136,7 @@ typedef struct
 	HANDLE tls_long_timer;
 	uint32_t tcp_keep_idle;
 	int socket_id;
-	const char *domain_name;
+	char *domain_name;
 	uint32_t domain_name_len;
 	luat_ip_addr_t remote_ip;
 	luat_dns_ip_result *dns_ip;
@@ -218,6 +228,10 @@ typedef struct
 
 	int (*dns)(const char *domain_name, uint32_t len, void *param,  void *user_data);
 	int (*set_dns_server)(uint8_t server_index, luat_ip_addr_t *ip, void *user_data);
+#ifdef LUAT_USE_LWIP
+	int (*set_mac)(uint8_t *mac, void *user_data);
+	int (*set_static_ip)(luat_ip_addr_t *ip, luat_ip_addr_t *submask, luat_ip_addr_t *gateway, void *user_data);
+#endif
 	int (*get_local_ip_info)(luat_ip_addr_t *ip, luat_ip_addr_t *submask, luat_ip_addr_t *gateway, void *user_data);
 	//所有网络消息都是通过cb_fun回调
 	//cb_fun回调时第一个参数为OS_EVENT,包含了socket的必要信息,第二个是luat_network_cb_param_t,其中的param是这里传入的param(就是适配器序号)
@@ -236,8 +250,6 @@ typedef struct
 
 //获取最后一个注册的适配器序号
 int network_get_last_register_adapter(void);
-uint32_t network_string_to_ipv4(const char *string, uint32_t len);
-uint8_t network_string_is_ipv4(const char *string, uint32_t len);
 /****************************以下是通用基础api********************************************************/
 /*
  * 在使用之后任意API前,必须先注册相关的协议栈接口

Some files were not shown because too many files changed in this diff