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

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

13917187172 4 месяцев назад
Родитель
Сommit
d26cb55710

+ 1 - 1
components/lcd/luat_lib_lcd.c

@@ -2076,7 +2076,7 @@ static const int l_lcd_draw_utf8(lua_State *L) {
 
 /*
 硬件lcd qspi接口配置,需要在lcd.init前配置好
-@api lcd.qspi(1_wire_command, 1_wire_command, 1_wire_command_4_wire_data, 4_wire_command_4_wire_data, vsync_reg, hsync_cmd, hsync_reg)
+@api lcd.qspi(1_wire_command, 1_wire_command_4_wire_data, 4_wire_command_4_wire_data, vsync_reg, hsync_cmd, hsync_reg)
 @int lcd命令模式下的qspi指令
 @int lcd数据模式下,1线地址,4线数据的qspi指令,
 @int lcd数据模式下,4线地址,4线数据的qspi指令,可以留空,如果存在,发送数据时优先使用这个模式

+ 1 - 1
components/multimedia/luat_lib_multimedia_codec.c

@@ -292,7 +292,7 @@ static int l_codec_get_audio_info(lua_State *L) {
 
 /**
 decoder从文件中解析出原始音频数据,比如从MP3文件里解析出PCM数据,这里的文件路径已经在codec.info传入,不需要再次传入
-@api codec.data(decoder, out_buff)
+@api codec.data(decoder, out_buff, size)
 @userdata 解码用的decoder
 @zbuff 存放输出数据的zbuff,空间必须不少于16KB
 @int   最少解码出多少字节的音频数据,默认16384

+ 61 - 12
components/network/adapter/luat_lib_socket.c

@@ -931,38 +931,67 @@ static int l_socket_wait(lua_State *L)
 
 /*
 作为服务端开始监听
-@api socket.listen(ctrl)
+@api socket.listen(ctrl, multi_client)
 @user_data socket.create得到的ctrl
+@int 等待accept的客户端数量, 默认0不支持, 取值范围0~8
 @return boolean true没有异常发生,false失败了,如果false则不需要看下一个返回值了,如果false,后续要close
 @return boolean true已经connect,false没有connect,之后需要接收socket.ON_LINE消息
 @usage 
 local succ, result = socket.listen(ctrl)
+-- 注意, 当目标适配器不支持1对多时,multi_client参数无效,并返回错误
+-- 注意, multi_client参数是可选的, 不传或者传0则表示单客户端模式
+-- multi_client 参数是 2025.11.10新增的, 之前的版本不支持
+local succ, result = socket.listen(ctrl, 8)
 */
 static int l_socket_listen(lua_State *L)
 {
 	luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
 	L_CTRL_CHECK;
+	if (lua_isinteger(L, 2))
+	{
+		l_ctrl->netc->max_wait_accept = lua_tointeger(L, 2);
+		if (!network_accept_enable(l_ctrl->netc) && l_ctrl->netc->max_wait_accept > 0)
+		{
+			l_ctrl->netc->max_wait_accept = 0;
+			LLOGE("目标适配器不支持1对多客户端连接模式");
+			lua_pushboolean(L, 0);
+			lua_pushboolean(L, 0);
+			return 2;
+		}
+	}
 	int result = network_listen(l_ctrl->netc, 0);
 	lua_pushboolean(L, (result < 0)?0:1);
 	lua_pushboolean(L, result == 0);
+	if (result < 0) {
+		LLOGE("listen fail %d adapter %d port %d", result, l_ctrl->netc->adapter_index, l_ctrl->netc->local_port);
+	}
 	return 2;
 }
 
 /*
-作为服务端接收到一个新的客户端,注意,如果是类似W5500的硬件协议栈不支持1对多,则不需要第二个参数
-@api socket.accept(ctrl)
+作为服务端接收到一个新的客户端
+@api socket.accept(ctrl, args)
 @user_data socket.create得到的ctrl,这里是服务器端
 @string or function or nil string为消息通知的taskName,function则为回调函数,和socket.create参数一致
 @return boolean true没有异常发生,false失败了,如果false则不需要看下一个返回值了,如果false,后续要close
 @return user_data or nil 如果支持1对多,则会返回新的ctrl,自动create,如果不支持则返回nil
+@return string 客户端ip, 2025.11.10新增
+@return int 客户端port, 2025.11.10新增
 @usage 
 local succ, new_netc = socket.accept(ctrl, cb)
+-- 注意, 当目标适配器不支持1对多时,new_netc会是nil, 第二个参数无效
+-- 当第二个参数为nil时, 固定为一对一模式, new_netc也会是nil
+
+-- 新增客户端ip和port返回值
+local succ, new_netc, client_ip, client_port = socket.accept(ctrl, "taskName")
+log.info("accept", succ, new_netc, client_ip, client_port)
 */
 static int l_socket_accept(lua_State *L)
 {
 	luat_socket_ctrl_t *old_ctrl = l_get_ctrl(L, 1);
 	if (!old_ctrl) return 0;
-	if (network_accept_enable(old_ctrl->netc))
+	int result = 0;
+	if ((lua_isfunction(L, 2) || lua_isstring(L, 2)) && network_accept_enable(old_ctrl->netc))
 	{
 		luat_socket_ctrl_t *new_ctrl = (luat_socket_ctrl_t *)lua_newuserdata(L, sizeof(luat_socket_ctrl_t));
 		if (!new_ctrl)
@@ -997,25 +1026,45 @@ static int l_socket_accept(lua_State *L)
 			memset(new_ctrl->task_name, 0, len + 1);
 			memcpy(new_ctrl->task_name, buf, len);
 		}
-		if (network_socket_accept(old_ctrl, new_ctrl))
-		{
+		else {
+			LLOGE("accept模式必须传入回调函数或taskName");
+			network_release_ctrl(new_ctrl->netc);
+			new_ctrl->netc = NULL;
 			lua_pushboolean(L, 0);
-			lua_pushnil(L);
-			return 2;
+			return 1;
 		}
-		else
+		if (network_socket_accept(old_ctrl->netc, new_ctrl->netc))
 		{
-			lua_pushboolean(L, 1);
-			luaL_setmetatable(L, LUAT_NW_CTRL_TYPE);
+			network_release_ctrl(new_ctrl->netc);
+			new_ctrl->netc = NULL;
+			lua_pushboolean(L, 0);
+			lua_pushnil(L);
 			return 2;
 		}
-
+		// 恢复到可监听状态
+		LLOGD("accept success %p", new_ctrl->netc);
+		luaL_setmetatable(L, LUAT_NW_CTRL_TYPE);
+		lua_pushboolean(L, 1);
+		lua_pushvalue(L, -2);
+		#ifdef LUAT_USE_LWIP
+		lua_pushstring(L, ipaddr_ntoa(&new_ctrl->netc->remote_ip));
+		lua_pushinteger(L, new_ctrl->netc->remote_port);
+		return 4;
+		#else
+		return 2;
+		#endif
 	}
 	else
 	{
 		lua_pushboolean(L, !network_socket_accept(old_ctrl->netc, NULL));
 		lua_pushnil(L);
+		#ifdef LUAT_USE_LWIP
+		lua_pushstring(L, ipaddr_ntoa(&old_ctrl->netc->remote_ip));
+		lua_pushinteger(L, old_ctrl->netc->remote_port);
+		return 4;
+		#else
 		return 2;
+		#endif
 	}
 }
 

+ 20 - 2
components/network/adapter/luat_network_adapter.c

@@ -977,6 +977,9 @@ static int network_state_listen(network_ctrl_t *ctrl, OS_EVENT *event, network_a
 		break;
 	case EV_NW_SOCKET_NEW_CONNECT:
 	case EV_NW_SOCKET_CONNECT_OK:
+		if (ctrl->is_server_mode && ctrl->max_wait_accept > 0) {
+			return 0; // 对于多客户的tcpserver模式, 保持listen状态
+		}
 		ctrl->state = NW_STATE_ONLINE;
 		return 0;
 	default:
@@ -1627,13 +1630,23 @@ uint8_t network_accept_enable(network_ctrl_t *ctrl)
 int network_socket_accept(network_ctrl_t *ctrl, network_ctrl_t *accept_ctrl)
 {
 	network_adapter_t *adapter = &prv_adapter_table[ctrl->adapter_index];
-	if (adapter->opt->no_accept)
+	if (adapter->opt == NULL) {
+		DBG_ERR("adapter %d not register!", ctrl->adapter_index);
+		return -1;
+	}
+	if (adapter->opt->no_accept || accept_ctrl == NULL)
 	{
 //		DBG("%x,%d,%llu,%x,%x,%x",adapter->opt->socket_accept, ctrl->socket_id, ctrl->tag, &ctrl->remote_ip, &ctrl->remote_port, adapter->user_data);
 		adapter->opt->socket_accept(ctrl->socket_id, ctrl->tag, &ctrl->remote_ip, &ctrl->remote_port, adapter->user_data);
 		return 0;
 	}
-	accept_ctrl->socket_id = adapter->opt->socket_accept(ctrl->socket_id, ctrl->tag, &accept_ctrl->remote_ip, &accept_ctrl->remote_port, adapter->user_data);
+	if (adapter->opt->socket_accept == NULL)
+	{
+		DBG_ERR("adapter %d not support accept multiple", ctrl->adapter_index);
+		return -1;
+	}
+	DBG_ERR("执行accept操作 %p %p", adapter, accept_ctrl, adapter->opt->socket_accept);
+	accept_ctrl->socket_id = adapter->opt->socket_accept(ctrl->socket_id, 0, &accept_ctrl->remote_ip, &accept_ctrl->remote_port, accept_ctrl);
 	if (accept_ctrl->socket_id < 0)
 	{
 		return -1;
@@ -1648,6 +1661,7 @@ int network_socket_accept(network_ctrl_t *ctrl, network_ctrl_t *accept_ctrl)
 		accept_ctrl->tcp_timeout_ms = ctrl->tcp_timeout_ms;
 		accept_ctrl->local_port = ctrl->local_port;
 		accept_ctrl->state = NW_STATE_ONLINE;
+		DBG_ERR("accept_ctrl %p tag: %llu", accept_ctrl, accept_ctrl->tag);
 		return 0;
 	}
 }
@@ -2188,10 +2202,14 @@ int network_listen(network_ctrl_t *ctrl, uint32_t timeout_ms)
 	if (NW_STATE_LISTEN == ctrl->state)
 	{
 		DBG("socket %d is listen", ctrl->socket_id);
+		if (network_accept_enable(ctrl)) {
+			return 1;
+		}
 		return 0;
 	}
 	if (ctrl->socket_id >= 0)
 	{
+		DBG("socket %d busy, state %d", ctrl->socket_id, ctrl->state);
 		return -1;
 	}
 	NW_LOCK;

+ 1 - 0
components/network/adapter/luat_network_adapter.h

@@ -210,6 +210,7 @@ typedef struct
     uint8_t state;
     uint8_t is_debug;
     uint8_t domain_ipv6;
+	uint8_t max_wait_accept; // 作为server时,最多支持多少个等待accept的客户端
 }network_ctrl_t;
 
 typedef struct

+ 101 - 19
components/network/adapter_lwip2/net_lwip2.c

@@ -203,6 +203,7 @@ static void net_lwip2_callback_to_nw_task(uint8_t adapter_index, uint32_t event_
 		prvlwip.socket_busy &= ~(1 << param1);
 		break;
 	}
+	LLOGD("socket_cb event_id %08X param.tag %d param3 %ld", event_id, param.tag, param3);
 	prvlwip.socket_cb(&event, &param);
 }
 
@@ -411,11 +412,17 @@ static err_t net_lwip2_tcp_fast_accept_cb(void *arg, struct tcp_pcb *newpcb, err
 {
 	int socket_id = ((uint32_t)arg) & 0x0000ffff;
 	uint8_t adapter_index = ((uint32_t)arg) >> 16;
+	LLOGD("adapter %d socket %d new client", adapter_index, socket_id);
 	if (err || !newpcb)
 	{
 		net_lwip2_tcp_error(adapter_index, socket_id);
 		return 0;
 	}
+	if (prvlwip.socket[socket_id].pcb.tcp != NULL) {
+		LLOGE("accept fail, srv socket busy. from %s:%d", ipaddr_ntoa(&newpcb->remote_ip), newpcb->remote_port);
+		tcp_close(newpcb);
+		return ERR_OK;
+	}
 	prvlwip.socket[socket_id].pcb.tcp = newpcb;
 	// prvlwip.socket[socket_id].pcb.tcp->sockid = socket_id;
 	prvlwip.socket[socket_id].rx_wait_size = 0;
@@ -840,6 +847,11 @@ static void net_lwip2_task(void *param)
 		// LLOGD("event dns query 3");
 		break;
 	case EV_LWIP_SOCKET_LISTEN:
+		if (prvlwip.socket[socket_id].listen_tcp) {
+			// 已经在监听了, 不需要重复操作, 发送事件就行
+			net_lwip2_callback_to_nw_task(adapter_index, EV_NW_SOCKET_LISTEN, socket_id, 0, 0);
+			break;
+		}
 		if (!prvlwip.socket[socket_id].in_use || !prvlwip.socket[socket_id].pcb.ip)
 		{
 			NET_DBG("adapter %d socket %d cannot use! %d,%x", adapter_index, socket_id, prvlwip.socket[socket_id].in_use, prvlwip.socket[socket_id].pcb.ip);
@@ -1038,9 +1050,18 @@ static void net_lwip2_check_network_ready(uint8_t adapter_index)
 static int net_lwip2_check_socket(void *user_data, int socket_id, uint64_t tag)
 {
 	if ((uint32_t)user_data >= NW_ADAPTER_INDEX_LWIP_NETIF_QTY) return -1;
-	if (socket_id >= MAX_SOCK_NUM) return -1;
-	if (prvlwip.socket[socket_id].tag != tag) return -1;
-	if (!prvlwip.socket[socket_id].in_use || prvlwip.socket[socket_id].state) return -1;
+	if (socket_id >= MAX_SOCK_NUM) {
+		LLOGD("socket id 超出范围 %d", socket_id);
+		return -1;
+	}
+	if (prvlwip.socket[socket_id].tag != tag) {
+		LLOGD("socket tag 不匹配 %llx != %llx", prvlwip.socket[socket_id].tag, tag);
+		return -1;
+	}
+	if (!prvlwip.socket[socket_id].in_use || prvlwip.socket[socket_id].state) {
+		LLOGD("socket 状态不正确 %d,%d,%d", socket_id, prvlwip.socket[socket_id].in_use, prvlwip.socket[socket_id].state);
+		return -1;
+	}
 	return 0;
 }
 
@@ -1156,14 +1177,9 @@ static void net_lwip2_create_socket_now(uint8_t adapter_index, uint8_t socket_id
 	}
 }
 
-static int net_lwip2_create_socket(uint8_t is_tcp, uint64_t *tag, void *param, uint8_t is_ipv6, void *user_data)
-{
-	// uint8_t index = (uint32_t)user_data;
-	uint8_t adapter_index = (uint32_t)user_data;
-	if ((uint32_t)adapter_index >= NW_ADAPTER_INDEX_LWIP_NETIF_QTY) return 0;
-	int i, socket_id;
-	socket_id = -1;
-	// OS_LOCK;
+static int gen_next_socket_id() {
+	int socket_id = -1;
+	int i;
 	if (!prvlwip.socket[prvlwip.next_socket_index].in_use)
 	{
 		socket_id = prvlwip.next_socket_index;
@@ -1185,6 +1201,16 @@ static int net_lwip2_create_socket(uint8_t is_tcp, uint64_t *tag, void *param, u
 	{
 		prvlwip.next_socket_index = 0;
 	}
+	return socket_id;
+}
+
+static int net_lwip2_create_socket(uint8_t is_tcp, uint64_t *tag, void *param, uint8_t is_ipv6, void *user_data)
+{
+	// uint8_t index = (uint32_t)user_data;
+	uint8_t adapter_index = (uint32_t)user_data;
+	if ((uint32_t)adapter_index >= NW_ADAPTER_INDEX_LWIP_NETIF_QTY) return 0;
+	int socket_id = gen_next_socket_id();
+	// OS_LOCK;
 	if (socket_id >= 0)
 	{
 		LWIP_ASSERT("socket must free before create", !prvlwip.socket[socket_id].pcb.ip);
@@ -1239,14 +1265,68 @@ static int net_lwip2_socket_listen(int socket_id, uint64_t tag,  uint16_t local_
 	return 0;
 }
 //作为server接受一个client
-static int net_lwip2_socket_accept(int socket_id, uint64_t tag,  luat_ip_addr_t *remote_ip, uint16_t *remote_port, void *user_data)
+static int net_lwip2_socket_accept(int srv_socket_id, uint64_t srv_tag,  luat_ip_addr_t *remote_ip, uint16_t *remote_port, void *user_data)
 {
-	int result = net_lwip2_check_socket(user_data, socket_id, tag);
-	if (result) return result;
-	uint8_t adapter_index = (uint32_t)user_data;
-	if (adapter_index >= NW_ADAPTER_INDEX_LWIP_NETIF_QTY) return -1;
-	*remote_ip = prvlwip.socket[socket_id].pcb.tcp->remote_ip;
-	*remote_port = prvlwip.socket[socket_id].pcb.tcp->remote_port;
+	if (srv_tag == 0) {
+		uint64_t tag = 0;
+		LLOGD("accept tag 0, one to many");
+		if (prvlwip.socket[srv_socket_id].pcb.tcp == NULL) {
+			LLOGE("accept fail, srv socket not in wait-accept state");
+			return -1;
+		}
+		// 首先,分配新的socket id
+		int socket_id = gen_next_socket_id();
+		if (socket_id < 0) {
+			LLOGE("accept fail, too many socket");
+			return -1;
+		}
+		network_ctrl_t* accept_ctrl = (network_ctrl_t*)user_data;
+		// 然后, 把新的socket和老的socket绑定在一起
+		prvlwip.socket_busy &= (1 << socket_id);
+		prvlwip.socket_connect &= (1 << socket_id);
+		prvlwip.socket_tag++;
+		tag = prvlwip.socket_tag;
+		accept_ctrl->tag = tag;
+		prvlwip.socket[socket_id].in_use = 1;
+		prvlwip.socket[socket_id].tag = tag;
+		prvlwip.socket[socket_id].param = accept_ctrl;
+		prvlwip.socket[socket_id].is_tcp = 1;
+
+		LLOGI("accept new socket %d from srv socket %d", socket_id, srv_socket_id);
+		LLOGD("accept srv tag %llx, new tag %llx accept_ctrl->tag %llx", srv_tag, tag, accept_ctrl->tag);
+
+		//--------------------
+		// 把srv暂存的pcb给新的socket
+		prvlwip.socket[socket_id].pcb.tcp = prvlwip.socket[srv_socket_id].pcb.tcp;
+		prvlwip.socket[srv_socket_id].pcb.tcp = NULL; // 恢复成老的监听状态
+		prvlwip.socket[srv_socket_id].rx_wait_size = 0;
+		prvlwip.socket[srv_socket_id].tx_wait_size = 0;
+		//--------------------
+
+		PV_Union uPV;
+        uPV.u16[0] = socket_id;
+        uPV.u16[1] = accept_ctrl->adapter_index;
+		prvlwip.socket[socket_id].pcb.tcp->callback_arg = uPV.p;
+		llist_traversal(&prvlwip.socket[socket_id].wait_ack_head, net_lwip2_del_data_cache, NULL);
+		llist_traversal(&prvlwip.socket[socket_id].tx_head, net_lwip2_del_data_cache, NULL);
+		llist_traversal(&prvlwip.socket[socket_id].rx_head, net_lwip2_del_data_cache, NULL);
+		*remote_ip = prvlwip.socket[socket_id].pcb.tcp->remote_ip;
+		*remote_port = prvlwip.socket[socket_id].pcb.tcp->remote_port;
+
+		// 把srv_socket_id的对应的状态恢复好
+
+		return socket_id;
+	}
+	else {
+		// 一对一的情况, 兼容老的
+		int socket_id = srv_socket_id;
+		int result = net_lwip2_check_socket(user_data, socket_id, srv_tag);
+		if (result) return result;
+		uint8_t adapter_index = (uint32_t)user_data;
+		if (adapter_index >= NW_ADAPTER_INDEX_LWIP_NETIF_QTY) return -1;
+		*remote_ip = prvlwip.socket[socket_id].pcb.tcp->remote_ip;
+		*remote_port = prvlwip.socket[socket_id].pcb.tcp->remote_port;
+	}
 	return 0;
 }
 //主动断开一个tcp连接,需要走完整个tcp流程,用户需要接收到close ok回调才能确认彻底断开
@@ -1364,6 +1444,7 @@ static int net_lwip2_socket_receive(int socket_id, uint64_t tag,  uint8_t *buf,
 static int net_lwip2_socket_send(int socket_id, uint64_t tag, const uint8_t *buf, uint32_t len, int flags, luat_ip_addr_t *remote_ip, uint16_t remote_port, void *user_data)
 {
 	int result = net_lwip2_check_socket(user_data, socket_id, tag);
+	// LLOGD("net_lwip2_socket_send check result %d socket %d", result, socket_id);
 	if (result) return result;
 	
 	uint8_t adapter_index = (uint32_t)user_data;
@@ -1372,6 +1453,7 @@ static int net_lwip2_socket_send(int socket_id, uint64_t tag, const uint8_t *buf
 	uint32_t save_len = 0;
 	uint32_t dummy_len = 0;
 	socket_data_t *p;
+	// LLOGD("socket %d send len %d", socket_id, len);
 	if (prvlwip.socket[socket_id].is_tcp)
 	{
 		while(save_len < len)
@@ -1614,7 +1696,7 @@ static const network_adapter_info prv_net_lwip2_adapter =
 		.socket_set_callback = net_lwip2_socket_set_callback,
 		.name = "lwip",
 		.max_socket_num = MAX_SOCK_NUM,
-		.no_accept = 1,
+		.no_accept = 0,
 		.is_posix = 1,
 		.check_ack = net_lwip2_check_ack
 };

+ 1 - 1
components/statem/luat_lib_statem.c

@@ -14,7 +14,7 @@
 
 /*
 创建一个新的状态机.
-@api statem.create(count, repeat)
+@api statem.create(count, repeats)
 @int 指令条数,默认32条
 @int 重复执行的次数, 0 代表不重复, 正整数代表具体重复执行的次数. 暂不支持永续执行
 @return some 若成功,返回状态机指针,否则返回nil

+ 2 - 2
luat/modules/luat_lib_crypto.c

@@ -307,7 +307,7 @@ static const crc16method crc16method_table[] =
 };
 /**
 计算CRC16
-@api crypto.crc16(method, data, poly, initial, finally, inReversem outReverse)
+@api crypto.crc16(method, data, poly, initial, finally, inReversem, outReverse)
 @string CRC16模式("IBM","MAXIM","USB","MODBUS","CCITT","CCITT-FALSE","X25","XMODEM","DNP","USER-DEFINED")
 @string 字符串或者zbuff对象
 @int poly值,默认0x0000,范围0-0xFFFF
@@ -709,7 +709,7 @@ static int l_crypto_md(lua_State *L) {
 
 /*
 创建流式hash用的stream
-@api crypto.hash_init(tp)
+@api crypto.hash_init(tp, hmac)
 @string hash类型, 大写字母, 例如 "MD5" "SHA1" "SHA256"
 @string hmac值,可选
 @return userdata 成功返回一个数据结构,否则返回nil

+ 1 - 1
luat/modules/luat_lib_ir.c

@@ -86,7 +86,7 @@ static void ir_nec_send(int pin, uint8_t code)
 
 /**
 发送NEC数据
-@api ir.sendNEC(pin, addr, cmd, repeat, disablePWM)
+@api ir.sendNEC(pin, addr, cmd, repeats, disablePWM)
 @int 使用的GPIO引脚编号
 @int 用户码(大于0xff则采用Extended NEC模式)
 @int 数据码

+ 1 - 1
module/Air780EHM_Air780EHV_Air780EGH/demo/fs_io/http_download_flash.lua

@@ -33,7 +33,7 @@ local function http_download_flash_task()
 
     -- 核心下载操作开始
     local code, headers, body_size = http.request("GET",
-                                    "https://gitee.com/openLuat/LuatOS/raw/master/module/Air780EHM_Air780EHV_Air780EGH/demo/audio/sample-6s.mp3",
+                                    "https://www.air32.cn/demo/sample-6s.mp3",
                                     nil, nil, {dst = download_dir .. "/sample-6s.mp3"}).wait()
 
     -- 阶段3: 记录下载结果

+ 1 - 1
module/Air780EHM_Air780EHV_Air780EGH/demo/fs_io/readme.md

@@ -51,7 +51,7 @@
 
 - 下载状态码解析
 - 自动文件大小验证
-- 获取文件系统信息(fs.fsstat)
+- 获取文件系统信息( io.fsstat)
 
 ## **演示硬件环境**
 

+ 1 - 1
module/Air780EPM/demo/fs_io/http_download_flash.lua

@@ -33,7 +33,7 @@ local function http_download_flash_task()
 
     -- 核心下载操作开始
     local code, headers, body_size = http.request("GET",
-                                    "https://gitee.com/openLuat/LuatOS/raw/master/module/Air780EHM_Air780EHV_Air780EGH/demo/audio/sample-6s.mp3",
+                                    "https://www.air32.cn/demo/sample-6s.mp3",
                                     nil, nil, {dst = download_dir .. "/sample-6s.mp3"}).wait()
 
     -- 阶段3: 记录下载结果

+ 1 - 1
module/Air8000/demo/fs_io/http_download_flash.lua

@@ -33,7 +33,7 @@ local function http_download_flash_task()
 
     -- 核心下载操作开始
     local code, headers, body_size = http.request("GET",
-                                    "https://gitee.com/openLuat/LuatOS/raw/master/module/Air780EHM_Air780EHV_Air780EGH/demo/audio/sample-6s.mp3",
+                                    "https://www.air32.cn/demo/sample-6s.mp3",
                                     nil, nil, {dst = download_dir .. "/sample-6s.mp3"}).wait()
 
     -- 阶段3: 记录下载结果

+ 2 - 2
module/Air8000/demo/tf_card/http_download_file.lua

@@ -47,8 +47,8 @@ local function http_download_file_task()
     log.info("HTTP下载", "开始下载任务")
 
     -- 核心下载操作开始 (支持http和https)
-    local code, headers, body = http.request("GET", "...", nil, nil, {dst = "/sd/1.mp3"}).wait()
-    其中 "..."为url地址, 支持 http和https, 支持域名, 支持自定义端口。
+    -- local code, headers, body = http.request("GET", "...", nil, nil, {dst = "/sd/1.mp3"}).wait()
+    -- 其中 "..."为url地址, 支持 http和https, 支持域名, 支持自定义端口。
     local code, headers, body_size = http.request("GET",
                                     "https://cdn.openluat-erp.openluat.com/erp_site_file/product_file/AirM2M_780EHT_V2017_LTE_AT.dfota.bin",
                                     nil, nil, {dst = "/sd/3_23MB.bin"}).wait()

+ 52 - 0
olddemo/socket/tcp_server_mulit/main.lua

@@ -0,0 +1,52 @@
+
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "tcpserver"
+VERSION = "1.0.0"
+
+
+srv = require("tcpsrv")
+
+-- 统一联网函数
+sys.taskInit(function()
+    -----------------------------
+    -- 统一联网函数, 可自行删减
+    ----------------------------
+    if wlan and wlan.connect then
+        -- wifi 联网, ESP32系列均支持, 要根据实际情况修改ssid和password!!
+        local ssid = "uiot"
+        local password = "czcjhp1985cbm"
+        log.info("wifi", ssid, password)
+        -- TODO 改成自动配网
+        wlan.init()
+        -- wlan.setMode(wlan.STATION) -- 默认也是这个模式,不调用也可以
+        wlan.connect(ssid, password, 1)
+    elseif mobile then
+        -- EC618系列, 如Air780E/Air600E/Air700E
+        -- mobile.simid(2) -- 自动切换SIM卡, 按需启用
+        -- 模块默认会自动联网, 无需额外的操作
+    elseif socket then
+        -- 适配了socket库也OK, 就当1秒联网吧
+        sys.timerStart(sys.publish, 1000, "IP_READY")
+    else
+        -- 其他不认识的bsp, 循环提示一下吧
+        while 1 do
+            sys.wait(1000)
+            log.info("bsp", "本bsp可能未适配网络层, 请查证")
+        end
+    end
+    -- 默认都等到联网成功
+    sys.waitUntil("IP_READY")
+    sys.publish("net_ready")
+end)
+
+sys.taskInit(function()
+    sys.waitUntil("net_ready")
+    log.info("联网完成", "准备启动tcp server")
+    sys.wait(1000)
+    SerDemo(1080)
+end)
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 64 - 0
olddemo/socket/tcp_server_mulit/tcpsrv.lua

@@ -0,0 +1,64 @@
+local libnet = require "libnet"
+
+--下面演示用阻塞方式做自动应答服务器,只适合W5500
+local dName = "D2_TASK"
+local function netCB(msg)
+	log.info("未处理消息", msg[1], msg[2], msg[3], msg[4])
+end
+
+local function serTask(port, adapter)
+	log.info("tcpsrv", "准备监听端口", socket.localIP(adapter), port)
+	local tx_buff = zbuff.create(1024)
+	local rx_buff = zbuff.create(1024)
+	local netc 
+	local result, param, succ, rIP, rPort
+	netc = socket.create(adapter, dName)
+	socket.debug(netc, true)
+	socket.config(netc, port)
+	log.info("netc", netc)
+	-- result = libnet.waitLink(dName, 0, netc)
+	clients = {}
+	local buff = zbuff.create(1024)
+	while true do
+		log.info("开始监听客户端连接, 无限时长")
+		-- sys.wait(1000)
+		result, code = libnet.listen(dName, 0, netc, 8)  -- 支持最多8个等待accept的客户端
+		log.info("监听结果", result, code)
+		if result then
+			log.info("有客户端连接请求到来, 接受连接")
+            result, client, ip, port = socket.accept(netc, function(client, event, param)
+				log.info("客户端事件", client, event, params)
+				if event == socket.EVENT then
+					local result = socket.rx(client, buff)
+					log.info("客户端数据到来", result, buff:used())
+					buff:seek(0)
+				end
+			end)
+			log.info("accept结果", result, client, ip, port)
+			socket.debug(client, true)
+            if result then
+				table.insert(clients, client)
+			    log.info("客户端连上了", client, "发送个问候")
+			    log.info("发送数据", socket.tx(client, "helloworld"))
+            end
+		else
+			log.info("监听失败或超时", result, code)
+			break
+		end
+		--sys.wait(1000)
+	end
+	libnet.close(dName, 5000, netc)
+	log.info("服务器关闭了")
+end
+
+
+function SerDemo(port, adapter)
+	sysplus.taskInitEx(serTask, dName, netCB, port, adapter)
+end
+
+-- sys.taskInit(function()
+-- 	while 1 do
+-- 		sys.wait(1000)
+-- 		log.info("meminfo", rtos.meminfo("sys"))
+-- 	end
+-- end)