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;
+}
+