Index: asp3_tinet_ecnl_arm/trunk/ntshell/src/socket_stub.c
===================================================================
--- asp3_tinet_ecnl_arm/trunk/ntshell/src/socket_stub.c	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/ntshell/src/socket_stub.c	(revision 364)
@@ -42,5 +42,8 @@
 #include <sil.h>
 #include "syssvc/syslog.h"
+#include <tinet_defs.h>
 #include <tinet_config.h>
+#include <net/net.h>
+#include <net/net_endian.h>
 #include <netinet/in.h>
 #include <netinet/in_itron.h>
@@ -53,4 +56,5 @@
 #include <net/if_var.h>
 #include <netinet/udp_var.h>
+#include <net/net_buf.h>
 //#include <netinet/tcp_var.h>
 #include <netapp/resolver.h>
@@ -58,4 +62,5 @@
 #include "ff.h"
 #include "socket_stub.h"
+#include "kernel_cfg.h"
 
 #define SOCKET_TIMEOUT 2000000
@@ -181,4 +186,7 @@
 			fp->psock->buf_size = 512 + 512;
 			fp->psock->buf = malloc(fp->psock->buf_size);
+#ifdef _DEBUG
+			memset(fp->psock->buf, 0, fp->psock->buf_size);
+#endif
 			T_TCP_CCEP ccep = { 0, fp->psock->buf, 512, &fp->psock->buf[512], 512, (FP)socket_tcp_callback };
 			ret = tcp_cre_cep(cepid, &ccep);
@@ -279,4 +287,7 @@
 			fp->psock->buf_size = 512 + 512;
 			fp->psock->buf = malloc(fp->psock->buf_size);
+#ifdef _DEBUG
+			memset(fp->psock->buf, 0, fp->psock->buf_size);
+#endif
 			T_TCP_CCEP ccep = { 0, fp->psock->buf, 512, &fp->psock->buf[512], 512, (FP)socket_tcp_callback };
 			ret = tcp_cre_cep(cepid, &ccep);
@@ -298,5 +309,4 @@
 			return -EHOSTUNREACH;
 		}
-		fp->writable = 1;
 		break;
 	}
@@ -322,5 +332,5 @@
 	}
 
-	memcpy(&fp->psock, &lfp->psock, sizeof(fp->psock));
+	memcpy(fp->psock, lfp->psock, offsetof(socket_t, buf_size));
 
 	ER ret;
@@ -335,4 +345,7 @@
 			fp->psock->buf_size = 512 + 512;
 			fp->psock->buf = malloc(fp->psock->buf_size);
+#ifdef _DEBUG
+			memset(fp->psock->buf, 0, fp->psock->buf_size);
+#endif
 			T_TCP_CCEP ccep = { 0, fp->psock->buf, 512, &fp->psock->buf[512], 512, (FP)socket_tcp_callback };
 			ret = tcp_cre_cep(cepid, &ccep);
@@ -346,4 +359,5 @@
 		else {
 			cepid = lfp->psock->cepid;
+			fp->handle = cepid;
 			lfp->handle = tmax_tcp_cepid + lfp->psock->repid;
 			lfp->psock->cepid = 0;
@@ -356,5 +370,4 @@
 			return -ENOMEM;
 		}
-		fp->writable = 1;
 		struct sockaddr_in *raddr = &fp->psock->raddr4;
 		memset(raddr, 0, sizeof(*raddr));
@@ -384,5 +397,5 @@
 }
 
-ssize_t shell_send(int fd, const void *buf, size_t len, int flags)
+ssize_t shell_sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
 {
 	SOCKET *fp = fd_to_fp(fd);
@@ -396,5 +409,8 @@
 		switch (fp->psock->type) {
 		case SOCK_STREAM: {
-			fp->writable = 0;
+			if ((addr != NULL) || (alen != 0)) {
+				return -EISCONN;
+			}
+
 			if (flags & MSG_OOB) {
 				ret = tcp_snd_oob(fp->psock->cepid, (void *)buf, len, SOCKET_TIMEOUT);
@@ -404,53 +420,16 @@
 			}
 			else {
-				ret = tcp_snd_dat(fp->psock->cepid, (void *)buf, len, SOCKET_TIMEOUT);
-				if (ret < 0) {
-					return -ECOMM;
-				}
-			}
-			break;
-		}
-		case SOCK_DGRAM: {
-			return -EINVAL;
-		}
-		}
-		break;
-	}
-	case AF_INET6: {
-		return -EAFNOSUPPORT;
-	}
-	}
-
-	return ret;
-}
-
-ssize_t shell_sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
-{
-	SOCKET *fp = fd_to_fp(fd);
-	if (fp == NULL) {
-		return -EBADF;
-	}
-
-	int ret = 0;
-	switch (fp->psock->family) {
-	case AF_INET: {
-		switch (fp->psock->type) {
-		case SOCK_STREAM: {
-			if ((addr != NULL) && (alen != 0)) {
-				return -EINVAL;
-			}
-
-			fp->writable = 0;
-			if (flags & MSG_OOB) {
-				ret = tcp_snd_oob(fp->psock->cepid, (void *)buf, len, SOCKET_TIMEOUT);
-				if (ret < 0) {
-					return -ECOMM;
-				}
-			}
-			else {
-				ret = tcp_snd_dat(fp->psock->cepid, (void *)buf, len, SOCKET_TIMEOUT);
-				if (ret < 0) {
-					return -ECOMM;
-				}
+				for (;;) {
+					ret = tcp_snd_dat(fp->psock->cepid, (void *)buf, len, SOCKET_TIMEOUT);
+					if (ret < 0) {
+						if (ret == E_TMOUT)
+							return -ETIME;
+						return -ECOMM;
+					}
+					len -= ret;
+					if (len <= 0)
+						break;
+					buf = (const void *)&((uint8_t *)buf)[ret];
+				} 
 			}
 			break;
@@ -458,5 +437,5 @@
 		case SOCK_DGRAM: {
 			int sz = alen;
-			if (sz < 8) {
+			if ((addr == NULL) || (sz < 8)) {
 				return -EINVAL;
 			}
@@ -465,9 +444,8 @@
 			memcpy(raddr, addr, sz);
 			T_IPV4EP rep = { ntohl(raddr->sin_addr.s_addr), ntohs(raddr->sin_port) };
-			fp->writable = 0;
 			ret = udp_snd_dat(fp->psock->cepid, &rep, (void *)buf, len,
-				(fp->psock->flags & O_NONBLOCK) ? 0 : SOCKET_TIMEOUT);
+				(fp->psock->flags & O_NONBLOCK) ? TMO_POL : SOCKET_TIMEOUT);
 			if (ret < 0) {
-				return -ECOMM;
+				return (ret == E_TMOUT) ? -ETIME : -ECOMM;
 			}
 			break;
@@ -490,5 +468,5 @@
 }
 
-ssize_t shell_recv(int fd, void *buf, size_t len, int flags)
+ssize_t shell_recvfrom(int fd, void *__restrict buf, size_t len, int flags, struct sockaddr *__restrict addr, socklen_t *__restrict alen)
 {
 	SOCKET *fp = fd_to_fp(fd);
@@ -505,74 +483,127 @@
 				ret = tcp_rcv_oob(fp->psock->cepid, buf, len);
 				if (ret < 0) {
+					syslog(LOG_ERROR, "tcp_rcv_oob => %d", ret);
 					return -ECOMM;
 				}
 			}
 			else {
-				ret = tcp_rcv_dat(fp->psock->cepid, buf, len, TMO_FEVR);
+				int rsz, tmp;
+				if (fp->psock->input == NULL) {
+					ret = wai_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "wai_sem => %d", ret);
+					}
+					fp->psock->len = 0;
+					ret = sig_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "sig_sem => %d", ret);
+					}
+					ret = tcp_rcv_buf(fp->psock->cepid, &fp->psock->input, TMO_FEVR);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "tcp_rcv_buf => %d", ret);
+						return -ECOMM;
+					}
+					rsz = ret;
+				}
+				else
+					rsz = fp->psock->len;
+				tmp = rsz;
+				if (rsz > len)
+					rsz = len;
+				if (rsz >= 0) {
+					memcpy(buf, fp->psock->input, rsz);
+					ret = wai_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "wai_sem => %d", ret);
+					}
+					fp->psock->len = tmp - rsz;
+					ret = sig_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "sig_sem => %d", ret);
+					}
+					if (tmp - rsz == 0) {
+						fp->psock->input = NULL;
+					}
+					else
+						fp->psock->input = (void *)&((uint8_t *)fp->psock->input)[rsz];
+					ret = tcp_rel_buf(fp->psock->cepid, rsz);
+					if ((ret != E_OBJ) && (ret < 0)) {
+						syslog(LOG_ERROR, "tcp_rel_buf => %d", ret);
+						//return -ECOMM;
+					}
+				}
+				ret = rsz;
+			}
+			break;
+		}
+		case SOCK_DGRAM: {
+			struct sockaddr_in *raddr = &fp->psock->raddr4;
+			int rsz;
+			ret = wai_sem(SEM_FILEDESC);
+			if (ret < 0) {
+				syslog(LOG_ERROR, "wai_sem => %d", ret);
+			}
+			T_NET_BUF *input = fp->psock->input;
+			if (input == NULL) {
+				ret = sig_sem(SEM_FILEDESC);
 				if (ret < 0) {
-					return -ECOMM;
-				}
-			}
-			break;
-		}
-		case SOCK_DGRAM: {
-			T_IPV4EP rep = { 0, 0 };
-			ret = udp_rcv_dat(fp->psock->cepid, &rep, buf, len, (fp->psock->flags & O_NONBLOCK) ? 0 : TMO_FEVR);
-			if (ret < 0) {
-				return -ECOMM;
-			}
-		}
-		}
-		break;
-	}
-	case AF_INET6: {
-		return -EAFNOSUPPORT;
-	}
-	}
-
-	return ret;
-}
-
-ssize_t shell_recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr *__restrict addr, socklen_t *__restrict alen)
-{
-	SOCKET *fp = fd_to_fp(fd);
-	if (fp == NULL) {
-		return -EBADF;
-	}
-
-	int ret = 0;
-	switch (fp->psock->family) {
-	case AF_INET: {
-		switch (fp->psock->type) {
-		case SOCK_STREAM: {
-			if (flags & MSG_OOB) {
-				ret = tcp_rcv_oob(fp->psock->cepid, buf, len);
+					syslog(LOG_ERROR, "sig_sem => %d", ret);
+				}
+
+				T_IPV4EP rep = { 0, 0 };
+				ret = udp_rcv_dat(fp->psock->cepid, &rep, buf, len,
+					(fp->psock->flags & O_NONBLOCK) ? TMO_POL : SOCKET_TIMEOUT);
 				if (ret < 0) {
-					return -ECOMM;
+					syslog(LOG_ERROR, "udp_rcv_buf => %d", ret);
+					return (ret == E_TMOUT) ? -ETIME : -ECOMM;
+				}
+				rsz = ret;
+				if ((addr != NULL) && (alen != NULL)) {
+					ret = wai_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "wai_sem => %d", ret);
+					}
+					int sz = *alen;
+					memset(raddr, 0, sizeof(fp->psock->raddr4));
+					raddr->sin_family = AF_INET;
+					raddr->sin_port = htons(rep.portno);
+					raddr->sin_addr.s_addr = htonl(rep.ipaddr);
+					if (sz > sizeof(fp->psock->raddr4))
+						sz = sizeof(fp->psock->raddr4);
+					memcpy(addr, raddr, sz);
+					*alen = sz;
+					ret = sig_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "sig_sem => %d", ret);
+					}
 				}
 			}
 			else {
-				ret = tcp_rcv_dat(fp->psock->cepid, buf, len, TMO_FEVR);
+				rsz = fp->psock->len;
+				void *pbuf = fp->psock->buf;
+				fp->psock->input = NULL;
+				fp->psock->len = 0;
+				fp->psock->buf = NULL;
+				if ((addr != NULL) && (alen != NULL)) {
+					int sz = *alen;
+					if (sz > sizeof(fp->psock->raddr4))
+						sz = sizeof(fp->psock->raddr4);
+					memcpy(addr, raddr, sz);
+					*alen = sz;
+				}
+				ret = sig_sem(SEM_FILEDESC);
 				if (ret < 0) {
-					return -ECOMM;
-				}
-			}
-			break;
-		}
-		case SOCK_DGRAM: {
-			T_IPV4EP rep = { 0, 0 };
-			ret = udp_rcv_dat(fp->psock->cepid, &rep, buf, len, TMO_FEVR);
-			if (ret < 0) {
-				return -ECOMM;
-			}
-			int sz = *alen;
-			struct sockaddr_in raddr;
-			memset(&raddr, 0, sizeof(raddr));
-			raddr.sin_family = AF_INET;
-			raddr.sin_port = htons(rep.portno);
-			raddr.sin_addr.s_addr = htonl(rep.ipaddr);
-			if (sz > sizeof(raddr))
-				sz = sizeof(raddr);
-			memcpy(addr, &raddr, sz);
+					syslog(LOG_ERROR, "sig_sem => %d", ret);
+				}
+				if (rsz > len)
+					rsz = len;
+				memcpy(buf, pbuf, rsz);
+				ret = rel_net_buf(input);
+				if (ret < 0) {
+					syslog(LOG_ERROR, "rel_net_buf => %d", ret);
+					//return -ECOMM;
+				}
+			}
+			ret = rsz;
 		}
 		}
@@ -830,8 +861,5 @@
 int tcp_fd_close(struct _IO_FILE *fp)
 {
-	ER ret;
-
-	free(fp->psock->buf);
-	fp->psock->buf = NULL;
+	ER ret, ret2;
 
 	switch (fp->psock->family) {
@@ -844,12 +872,11 @@
 			}
 			ret = tcp_cls_cep(cepid, (fp->psock->repid != 0) ? 0 : SOCKET_TIMEOUT);
-			if (ret < 0) {
-				//return -1;
-			}
-			ret = tcp_del_cep(cepid);
+			ret2 = tcp_del_cep(cepid);
+			free(fp->psock->buf);
+			fp->psock->buf = NULL;
 			delete_tcp_fd(cepid);
 			delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
-			if (ret < 0) {
-				return -EINVAL;
+			if ((ret < 0) || (ret2 < 0)) {
+				return (ret == E_TMOUT) ? -ETIME : -EINVAL;
 			}
 		}
@@ -857,4 +884,6 @@
 			ID repid = fp->psock->repid;
 			ret = tcp_del_rep(repid);
+			free(fp->psock->buf);
+			fp->psock->buf = NULL;
 			delete_tcp_fd(tmax_tcp_cepid + repid);
 			delete_id(tcp_repid_table, tcp_repid_table_count, repid);
@@ -864,4 +893,6 @@
 		}
 		else {
+			free(fp->psock->buf);
+			fp->psock->buf = NULL;
 			return -EINVAL;
 		}
@@ -878,10 +909,10 @@
 size_t tcp_fd_read(struct _IO_FILE *fp, unsigned char *dst, size_t dstsz)
 {
-	return shell_recv(fp->fd, dst, dstsz, 0);
+	return shell_recvfrom(fp->fd, dst, dstsz, 0, NULL, NULL);
 }
 
 size_t tcp_fd_write(struct _IO_FILE *fp, const unsigned char *src, size_t srcsz)
 {
-	return shell_send(fp->fd, src, srcsz, 0);
+	return shell_sendto(fp->fd, src, srcsz, 0, NULL, 0);
 }
 
@@ -901,11 +932,10 @@
 	ID cepid;
 
-	free(fp->psock->buf);
-	fp->psock->buf = NULL;
-
 	switch (fp->psock->family) {
 	case AF_INET: {
 		cepid = fp->psock->cepid;
 		ret = udp_del_cep(cepid);
+		//free(fp->psock->buf);
+		//fp->psock->buf = NULL;
 		delete_udp_fd(cepid);
 		delete_id(udp_cepid_table, udp_cepid_table_count, cepid);
@@ -925,10 +955,10 @@
 size_t udp_fd_read(struct _IO_FILE *fp, unsigned char *dst, size_t dstsz)
 {
-	return shell_recv(fp->fd, dst, dstsz, 0);
+	return shell_recvfrom(fp->fd, dst, dstsz, 0, NULL, NULL);
 }
 
 size_t udp_fd_write(struct _IO_FILE *fp, const unsigned char *src, size_t srcsz)
 {
-	return shell_send(fp->fd, src, srcsz, 0);
+	return shell_sendto(fp->fd, src, srcsz, 0, NULL, 0);
 }
 
