zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/ap/app/goahead/server/sockGen.c b/ap/app/goahead/server/sockGen.c
new file mode 100755
index 0000000..8e3292c
--- /dev/null
+++ b/ap/app/goahead/server/sockGen.c
@@ -0,0 +1,522 @@
+#include	<errno.h>
+#include	<fcntl.h>
+#include	<string.h>
+#include	<stdlib.h>
+#include	"uemf.h"
+#include "softap_log.h"
+
+extern socket_t		**socketList;			
+extern int			socketMax;				
+extern int			socketHighestFd;		
+static int			socketOpenCount = 0;	
+
+static void socketAccept(socket_t *sp);
+static int 	socketDoEvent(socket_t *sp);
+static int	tryAlternateConnect(int sock, struct sockaddr *sockaddr);
+
+int socketOpen()
+{
+	if (++socketOpenCount > 1) {
+		return 0;
+	}
+	socketList = NULL;
+	socketMax = 0;
+	socketHighestFd = -1;
+
+	return 0;
+}
+
+int socketWaitForEvent(socket_t *sp, int handlerMask, int *errCode)
+{
+	int	mask;
+
+	a_assert(sp);
+
+	mask = sp->handlerMask;
+	sp->handlerMask |= handlerMask;
+	while (socketSelect(sp->sid, 1000)) {
+		if (sp->currentEvents & (handlerMask | SOCKET_EXCEPTION)) {
+			break;
+		}
+	}
+	sp->handlerMask = mask;
+	if (sp->currentEvents & SOCKET_EXCEPTION) {
+		return -1;
+	} else if (sp->currentEvents & handlerMask) {
+		return 1;
+	}
+	if (errCode) {
+		*errCode = errno = EWOULDBLOCK;
+	}
+	return 0;
+}
+
+void socketClose()
+{
+	int		i;
+
+	if (--socketOpenCount <= 0) {
+		for (i = socketMax; i >= 0; i--) {
+			if (socketList && socketList[i]) {
+				socketCloseConnection(i);
+			}
+		}
+		socketOpenCount = 0;
+	}
+}
+
+int socketOpenConnection6(char *host, int port, socketAccept_t accept, int flags)
+{
+	socket_t			*sp;
+	struct sockaddr_in6	sockaddr;
+	int					sid, dgram, rc;
+	if (port > SOCKET_PORT_MAX) {
+		return -1;
+	}
+	if ((sid = socketAlloc(NULL, port, accept, flags)) < 0) {
+		return -1;
+	}
+	sp = socketList[sid];
+	a_assert(sp);
+	memset((char *) &sockaddr, '\0', sizeof(struct sockaddr_in6));
+	sockaddr.sin6_family = AF_INET6;
+	sockaddr.sin6_port = htons((short) (port & 0xFFFF));
+	dgram = sp->flags & SOCKET_DATAGRAM;
+	sp->sock = socket(AF_INET6, dgram ? SOCK_DGRAM: SOCK_STREAM, 0);
+	if (sp->sock < 0) {
+		socketFree(sid);
+		return -1;
+	}
+	if(fcntl(sp->sock, F_SETFD, FD_CLOEXEC) < 0)
+	{
+		slog(MISC_PRINT,SLOG_ERR, "fcntl return -1.\n");
+	}
+
+	socketHighestFd = max(socketHighestFd, sp->sock);
+	rc = 1;
+	// cov 3 CHECKED_RETURN
+	if(setsockopt(sp->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc)) < 0){
+        ;
+	}
+	if (bind(sp->sock, (struct sockaddr *) &sockaddr, 
+			sizeof(sockaddr)) < 0) {
+		socketFree(sid);
+		return -1;
+	}
+
+	if (! dgram) {
+		if (listen(sp->sock, SOMAXCONN) < 0) {
+			socketFree(sid);
+			return -1;
+		}
+
+		sp->flags |= SOCKET_LISTENING;
+	}
+	sp->handlerMask |= SOCKET_READABLE;
+
+	if (flags & SOCKET_BLOCK) {
+		socketSetBlock(sid, 1);
+	} else {
+		socketSetBlock(sid, 0);
+	}
+	return sid;
+}
+
+void socketCloseConnection(int sid)
+{
+	socket_t	*sp;
+
+	if ((sp = socketPtr(sid)) == NULL) {
+		return;
+	}
+	socketFree(sid);
+}
+
+static void socketAccept(socket_t *sp)
+{
+	struct sockaddr_in6	addr;
+	//socket_t 			*nsp;
+	size_t				len;
+	char				pString[40]={0};
+	int 				newSock, nid;
+
+	a_assert(sp);
+	len = sizeof(struct sockaddr_in6);
+	if ((newSock = accept(sp->sock, (struct sockaddr *) &addr, (int *) &len)) < 0) {
+		return;
+	}
+	if(fcntl(newSock, F_SETFD, FD_CLOEXEC) < 0)
+	{
+		slog(MISC_PRINT,SLOG_ERR, "fcntl return -1.\n");
+	}
+	socketHighestFd = max(socketHighestFd, newSock);
+
+	nid = socketAlloc(sp->host, sp->port, sp->accept, sp->flags);
+	//nsp = socketList[nid];
+	a_assert(socketList[nid]);
+	if (socketList[nid] == NULL) {
+		close(newSock);
+		return;
+	}
+	socketList[nid]->sock = newSock;
+	socketList[nid]->flags &= ~SOCKET_LISTENING;
+
+	socketSetBlock(nid, (socketList[nid]->flags & SOCKET_BLOCK) ? 1: 0);
+
+	if (sp->accept != NULL) {
+		//pString = inet_ntoa(addr);
+		if(addr.sin6_addr.s6_addr32[0] == 0
+			&& addr.sin6_addr.s6_addr32[1] == 0
+			&& addr.sin6_addr.s6_addr32[2] == 0xffff0000)
+			inet_ntop(AF_INET,(void*)&addr.sin6_addr.s6_addr32[3],pString,sizeof(pString));
+		else
+			inet_ntop(AF_INET6,(void*)&addr.sin6_addr,pString,sizeof(pString));
+		if ((sp->accept)(nid, pString, ntohs(addr.sin6_port), sp->sid) < 0) {
+			socketFree(nid);
+		}
+	}
+	else
+		socketFree(nid);
+}
+
+int socketGetInput(int sid, char *buf, int toRead, int *errCode)
+{
+	struct sockaddr_in 	server;
+	socket_t			*sp;
+	int 				len, bytesRead;
+    static int          s_ErrorCnt = 0;
+	a_assert(buf);
+	a_assert(errCode);
+
+	*errCode = 0;
+
+	if ((sp = socketPtr(sid)) == NULL) {
+		return -1;
+	}
+
+	if (sp->flags & SOCKET_EOF) {
+		return 0;
+	}
+	if (sp->flags & SOCKET_DATAGRAM) {
+		len = sizeof(server);
+		bytesRead = recvfrom(sp->sock, buf, toRead, 0,
+			(struct sockaddr *) &server, &len);
+	} else {
+		bytesRead = recv(sp->sock, buf, toRead, 0);
+	}
+   
+    if (bytesRead < 0) 
+    {
+        *errCode = socketGetError();
+        //printf("\n socketGetInput ERROR: bytesRead = %d, *errCode = %d! ", bytesRead, *errCode);
+        if (*errCode == ECONNRESET || s_ErrorCnt++ > 500) 
+        {
+            sp->flags |= SOCKET_CONNRESET;
+            return 0;
+        }
+        return -1;
+    }
+    else
+    {
+        s_ErrorCnt = 0;
+    }
+	return bytesRead;
+}
+
+void socketRegisterInterest(socket_t *sp, int handlerMask)
+{
+	a_assert(sp);
+
+	sp->handlerMask = handlerMask;
+}
+
+int socketReady(int sid)
+{
+	socket_t 	*sp;
+	int			all;
+
+	all = 0;
+	if (sid < 0) {
+		sid = 0;
+		all = 1;
+	}
+
+	for (; sid < socketMax; sid++) {
+		if ((sp = socketList[sid]) == NULL) {
+			if (! all) {
+				break;
+			} else {
+				continue;
+			}
+		} 
+		if (sp->flags & SOCKET_CONNRESET) {
+			socketCloseConnection(sid);
+			return 0;
+		}
+		if (sp->currentEvents & sp->handlerMask) {
+			return 1;
+		}
+
+		if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid) > 0) {
+			socketSelect(sid, 0);
+			return 1;
+		}
+		if (! all) {
+			break;
+		}
+	}
+	return 0;
+}
+
+int socketSelect(int sid, int timeout)
+{
+	socket_t		*sp;
+	struct timeval	tv;
+	fd_mask 		*readFds, *writeFds, *exceptFds;
+	int 			all, len, nwords, index, bit, nEvents;
+
+	nwords = (socketHighestFd + NFDBITS) / NFDBITS;
+	len = nwords * sizeof(int);
+
+	readFds = balloc(B_L, len);
+	if(readFds == NULL)
+		return 0;
+	memset(readFds, 0, len);
+	writeFds = balloc(B_L, len);
+	if(writeFds == NULL){
+		bfree(B_L, readFds);
+		return 0;
+	}
+	memset(writeFds, 0, len);
+	exceptFds = balloc(B_L, len);
+	if(exceptFds == NULL){
+		bfree(B_L, readFds);
+		bfree(B_L, writeFds);
+		return 0;
+	}
+	memset(exceptFds, 0, len);
+
+	tv.tv_sec = timeout / 1000;
+	tv.tv_usec = (timeout % 1000) * 1000;
+
+	all = nEvents = 0;
+
+	if (sid < 0) {
+		all++;
+		sid = 0;
+	}
+
+	for (; sid < socketMax; sid++) {
+		if ((sp = socketList[sid]) == NULL) {
+			if (all == 0) {
+				break;
+			} else {
+				continue;
+			}
+		}
+		a_assert(sp);
+
+		index = sp->sock / (NBBY * sizeof(fd_mask));
+		bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask)));
+		
+		if (sp->handlerMask & SOCKET_READABLE) {
+			readFds[index] |= bit;
+			nEvents++;
+			if (socketInputBuffered(sid) > 0) {
+				tv.tv_sec = 0;
+				tv.tv_usec = 0;
+			}
+		}
+		if (sp->handlerMask & SOCKET_WRITABLE) {
+			writeFds[index] |= bit;
+			nEvents++;
+		}
+		if (sp->handlerMask & SOCKET_EXCEPTION) {
+			exceptFds[index] |= bit;
+			nEvents++;
+		}
+		if (! all) {
+			break;
+		}
+	}
+
+	nEvents = select(socketHighestFd + 1, (fd_set *) readFds,
+		(fd_set *) writeFds, (fd_set *) exceptFds, &tv);
+
+	if (nEvents > 0) {
+		if (all) {
+			sid = 0;
+		}
+		for (; sid < socketMax; sid++) {
+			if ((sp = socketList[sid]) == NULL) {
+				if (all == 0) {
+					break;
+				} else {
+					continue;
+				}
+			}
+
+			index = sp->sock / (NBBY * sizeof(fd_mask));
+			bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask)));
+
+			if (readFds[index] & bit || socketInputBuffered(sid) > 0) {
+				sp->currentEvents |= SOCKET_READABLE;
+			}
+			if (writeFds[index] & bit) {
+				sp->currentEvents |= SOCKET_WRITABLE;
+			}
+			if (exceptFds[index] & bit) {
+				sp->currentEvents |= SOCKET_EXCEPTION;
+			}
+			if (! all) {
+				break;
+			}
+		}
+	}
+
+	bfree(B_L, readFds);
+	bfree(B_L, writeFds);
+	bfree(B_L, exceptFds);
+
+	return nEvents;
+}
+
+void socketProcess(int sid)
+{
+	socket_t	*sp;
+	int			all;
+
+	all = 0;
+	if (sid < 0) {
+		all = 1;
+		sid = 0;
+	}
+	for (; sid < socketMax; sid++) {
+		if ((sp = socketList[sid]) == NULL) {
+			if (! all) {
+				break;
+			} else {
+				continue;
+			}
+		}
+		if (socketReady(sid)) {
+			socketDoEvent(sp);
+		}
+		if (! all) {
+			break;
+		}
+	}
+}
+
+static int socketDoEvent(socket_t *sp)
+{
+	ringq_t		*rq;
+	int 		sid;
+
+	a_assert(sp);
+
+	sid = sp->sid;
+	if (sp->currentEvents & SOCKET_READABLE) {
+		if (sp->flags & SOCKET_LISTENING) { 
+			socketAccept(sp);
+			sp->currentEvents = 0;
+			return 1;
+		} 
+
+	} else {
+
+		if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid) > 0) {
+			sp->currentEvents |= SOCKET_READABLE;
+		}
+	}
+
+	if (sp->currentEvents & SOCKET_WRITABLE) {
+		if (sp->flags & SOCKET_FLUSHING) {
+			rq = &sp->outBuf;
+			if (ringqLen(rq) > 0) {
+				socketFlush(sp->sid);
+			} else {
+				sp->flags &= ~SOCKET_FLUSHING;
+			}
+		}
+	}
+
+	if (sp->handler && (sp->handlerMask & sp->currentEvents)) {
+		(sp->handler)(sid, sp->handlerMask & sp->currentEvents, 
+			sp->handler_data);
+
+		if (socketList && sid < socketMax && socketList[sid] == sp) {
+			sp->currentEvents = 0;
+		}
+	}
+	return 1;
+}
+
+int socketSetBlock(int sid, int on)
+{
+	socket_t		*sp;
+	unsigned long	flag;
+	int				iflag;
+	int				oldBlock;
+	struct timeval rcv_timeo;
+
+	flag = iflag = !on;
+
+	if ((sp = socketPtr(sid)) == NULL) {
+		a_assert(0);
+		return 0;
+	}
+	oldBlock = (sp->flags & SOCKET_BLOCK);
+	sp->flags &= ~(SOCKET_BLOCK);
+	if (on) {
+		sp->flags |= SOCKET_BLOCK;
+	}
+
+
+	if (sp->flags & SOCKET_BLOCK) {
+
+		if(fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) & ~O_NONBLOCK) < 0)
+    	{
+    		slog(MISC_PRINT,SLOG_ERR, "fcntl return -1.\n");
+    	}			
+
+	rcv_timeo.tv_sec = 60;
+	rcv_timeo.tv_usec = 0;
+	//printf("[zyl]set 60s send timeout\n");
+	//ÉèÖÃ60Ãë·¢Ëͳ¬Ê±
+	// cov 3 CHECKED_RETURN
+	if(setsockopt(sp->sock, SOL_SOCKET,SO_SNDTIMEO, (void*)&rcv_timeo, sizeof(rcv_timeo)) < 0){
+        ;
+	}
+	rcv_timeo.tv_sec = 1;
+	rcv_timeo.tv_usec = 0;
+	
+	//ÉèÖÃ1Ãë½ÓÊÕ³¬Ê±
+	// cov 3 CHECKED_RETURN
+	if(setsockopt(sp->sock, SOL_SOCKET,SO_RCVTIMEO, (void*)&rcv_timeo, sizeof(rcv_timeo)) < 0){
+        ;
+	}
+
+	} else {
+		if(fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) | O_NONBLOCK) < 0)
+    	{
+    		slog(MISC_PRINT,SLOG_ERR, "fcntl return -1.\n");
+    	}			
+	}
+	return oldBlock;
+}
+
+int socketSockBuffered(int sock)
+{
+	socket_t	*sp;
+	int			i;
+
+	for (i = 0; i < socketMax; i++) {
+		if ((sp = socketList[i]) == NULL || sp->sock != sock) {
+			continue;
+		}
+		return socketInputBuffered(i);
+	}
+	return 0;
+}
+