bool repeaterClient::connect () { int status; if ( ! makeSocket ( PORT_ANY, false, & this->sock ) ) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf ( stderr, "%s: no client sock because \"%s\"\n", __FILE__, sockErrBuf ); return false; } status = ::connect ( this->sock, &this->from.sa, sizeof ( this->from.sa ) ); if ( status < 0 ) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf ( stderr, "%s: unable to connect client sock because \"%s\"\n", __FILE__, sockErrBuf ); return false; } return true; }
void serverServe(Server *server) { #ifdef _WIN32 WSADATA wsaData; WSAStartup(2 , &wsaData); #endif int sock = makeSocket(server->port); int newSock; socklen_t size; fd_set activeFDs; fd_set readFDs; struct sockaddr_in addr; FD_ZERO(&activeFDs); FD_SET(sock, &activeFDs); fprintf(stdout, "Listening on port %d.\n\n", server->port); for (;;) { readFDs = activeFDs; if (select(FD_SETSIZE, &readFDs, NULL, NULL, NULL) < 0) { fprintf(stderr, "error: failed to select\n"); exit(1); } for (int fd = 0; fd < FD_SETSIZE; ++fd) { if (FD_ISSET(fd, &readFDs)) { if (fd == sock) { size = sizeof(addr); newSock = accept(sock, (struct sockaddr *) &addr, &size); if (newSock < 0) { fprintf(stderr, "error: failed to accept connection\n"); exit(1); } FD_SET(newSock, &activeFDs); } else { handle(server, fd, &activeFDs, &addr); } } } } }
void DebuggerServer::accept() { TRACE(2, "DebuggerServer::accept\n"); // Setup server-side usage logging before accepting any connections. Debugger::InitUsageLogging(); // server loop unsigned int count = m_socks.size(); struct pollfd fds[count]; for (unsigned int i = 0; i < count; i++) { fds[i].fd = nthSocket(i)->fd(); fds[i].events = POLLIN|POLLERR|POLLHUP; } while (!m_stopped) { int ret = poll(fds, count, POLLING_SECONDS * 1000); for (unsigned int i = 0; ret > 0 && i < count; i++) { bool in = (fds[i].revents & POLLIN); if (in) { struct sockaddr sa; socklen_t salen = sizeof(sa); try { auto sock = nthSocket(i); auto new_sock = makeSocket( ::accept(sock->fd(), &sa, &salen), sock->getType()); if (new_sock->valid()) { Debugger::CreateProxy(new_sock, false); } else { Logger::Error("unable to accept incoming debugger request"); } } catch (Exception &e) { Logger::Error("%s", e.getMessage().c_str()); } catch (std::exception &e) { Logger::Error("%s", e.what()); } catch (...) { Logger::Error("(unknown exception was thrown)"); } } fds[i].revents = 0; // reset the POLLIN flag } // else timed out, then we have a chance to check m_stopped bit // A chance for some housekeeping... Debugger::CleanupRetiredProxies(); } for(auto &m_sock : m_socks) { m_sock.reset(); } }
PothosPacketSocketEndpointInterfaceUdt(const Poco::Net::SocketAddress &addr, const bool server): server(server), connected(false), sess(getUDTSession()) { if (server) { this->serverSock = makeSocket(); if (UDT::ERROR == UDT::bind(this->serverSock, addr.addr(), addr.length())) { throw Pothos::RuntimeException("UDT::bind("+addr.toString()+")", UDT::getlasterror().getErrorMessage()); } UDT::listen(this->serverSock, 1/*only one client expected*/); } else { this->clientSock = makeSocket(); if (UDT::ERROR == UDT::connect(this->clientSock, addr.addr(), addr.length())) { throw Pothos::RuntimeException("UDT::connect("+addr.toString()+")", UDT::getlasterror().getErrorMessage()); } this->connected = true; } }
bool repeaterClient::verify () // X aCC 361 { SOCKET tmpSock; bool success = makeSocket ( this->port (), false, & tmpSock ); if ( success ) { epicsSocketDestroy ( tmpSock ); } else { if ( SOCKERRNO != SOCK_EADDRINUSE ) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf ( stderr, "CA Repeater: bind test err was \"%s\"\n", sockErrBuf ); } } return ! success; }
bool Ts2Rtp::addChannels( QPtrList<ChannelDesc> *channels ) { int i, j, k, pmtpid=8191; ChannelDesc *desc, *d; QValueList<int> pids; if ( !rtpSocket && !makeSocket() ) return false; sendList = ""; for ( i=0; i<(int)channels->count(); i++ ) { desc = channels->at( i ); sendList = sendList+desc->name+"|"+QString().setNum(desc->vpid)+"|"+QString().setNum(desc->apid[0].pid)+"|"; if ( desc->apid[0].ac3 ) sendList+= "y|"; else sendList+= "n|"; sendList+= QString().setNum(desc->subpid[0].pid); sendList+= "|"; sendList+= QString().setNum(desc->subpid[0].page); sendList+= "|"; sendList+= QString().setNum(desc->subpid[0].id); sendList+= "|"; sendList+= QString().setNum(desc->subpid[0].type); sendList+= "|"; sendList+= desc->subpid[0].lang+"|"; for ( j=i; j<(int)channels->count(); j++ ) { pids.clear(); d = channels->at( j ); if ( d->vpid ) pids.append( d->vpid ); for ( k=0; k<d->napid && k<MAX_AUDIO; k++ ) pids.append( d->apid[k].pid ); for ( k=0; k<d->nsubpid && k<MAX_DVBSUB; k++ ) pids.append( d->subpid[k].pid ); while ( pmtpid==17 || pids.contains( pmtpid ) ) --pmtpid; } desc->pmtpid = pmtpid--; } sendList+="\n"; psiTables( channels ); writePsi = true; psiTimer.start( 500 ); return true; }
void Handler::listenner(void *) { SOCKET connection, sock = makeSocket(); if (INVALID_SOCKET == sock) return; const int buffLen = 512; char *buffer = new char[buffLen]; int datalen = 0; while ((connection = accept(sock, 0, 0)) != INVALID_SOCKET) { int len = 0; while ((len = recv(connection, &buffer[datalen], buffLen-datalen, 0)) > 0) { datalen += len; Sleep(1); } buffer[datalen] = 0; if (instance()->m_callback) instance()->m_callback(buffer); datalen = 0; } delete[] buffer; }
/* * register_new_client() */ static void register_new_client ( osiSockAddr & from, tsFreeList < repeaterClient, 0x20 > & freeList ) { bool newClient = false; int status; if ( from.sa.sa_family != AF_INET ) { return; } /* * the repeater and its clients must be on the same host */ if ( INADDR_LOOPBACK != ntohl ( from.ia.sin_addr.s_addr ) ) { static SOCKET testSock = INVALID_SOCKET; static bool init = false; if ( ! init ) { SOCKET sock; if ( ! makeSocket ( PORT_ANY, true, & sock ) ) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf ( stderr, "%s: Unable to create repeater bind test socket because \"%s\"\n", __FILE__, sockErrBuf ); } else { testSock = sock; } init = true; } /* * Unfortunately on 3.13 beta 11 and before the * repeater would not always allow the loopback address * as a local client address so current clients alternate * between the address of the first non-loopback interface * found and the loopback addresss when subscribing with * the CA repeater until all CA repeaters have been updated * to current code. */ if ( testSock != INVALID_SOCKET ) { osiSockAddr addr; addr = from; addr.ia.sin_port = PORT_ANY; /* we can only bind to a local address */ status = bind ( testSock, &addr.sa, sizeof ( addr ) ); if ( status ) { return; } } else { return; } } tsDLIter < repeaterClient > pclient = client_list.firstIter (); while ( pclient.valid () ) { if ( pclient->identicalPort ( from ) ) { break; } pclient++; } repeaterClient *pNewClient; if ( pclient.valid () ) { pNewClient = pclient.pointer (); } else { pNewClient = new ( freeList ) repeaterClient ( from ); if ( ! pNewClient ) { fprintf ( stderr, "%s: no memory for new client\n", __FILE__ ); return; } if ( ! pNewClient->connect () ) { pNewClient->~repeaterClient (); freeList.release ( pNewClient ); return; } client_list.add ( *pNewClient ); newClient = true; } if ( ! pNewClient->sendConfirm () ) { client_list.remove ( *pNewClient ); pNewClient->~repeaterClient (); freeList.release ( pNewClient ); # ifdef DEBUG epicsUInt16 port = ntohs ( from.ia.sin_port ); debugPrintf ( ( "Deleted repeater client=%u (error while sending ack)\n", port ) ); # endif } /* * send a noop message to all other clients so that we dont * accumulate sockets when there are no beacons */ caHdr noop; memset ( (char *) &noop, '\0', sizeof ( noop ) ); AlignedWireRef < epicsUInt16 > ( noop.m_cmmd ) = CA_PROTO_VERSION; fanOut ( from, &noop, sizeof ( noop ), freeList ); if ( newClient ) { /* * For HPUX and Solaris we need to verify that the clients * have not gone away - because an ICMP error return does not * get through to send(), which returns no error code. * * This is done each time that a new client is created. * See also the note in the file header. * * This is done here in order to avoid deleting a client * prior to sending its confirm message. */ verifyClients ( freeList ); } }
/* * ca_repeater () */ void ca_repeater () { tsFreeList < repeaterClient, 0x20 > freeList; int size; SOCKET sock; osiSockAddr from; unsigned short port; char * pBuf; pBuf = new char [MAX_UDP_RECV]; { bool success = osiSockAttach(); assert ( success ); } port = envGetInetPortConfigParam ( & EPICS_CA_REPEATER_PORT, static_cast <unsigned short> (CA_REPEATER_PORT) ); if ( ! makeSocket ( port, true, & sock ) ) { /* * test for server was already started */ if ( SOCKERRNO == SOCK_EADDRINUSE ) { osiSockRelease (); debugPrintf ( ( "CA Repeater: exiting because a repeater is already running\n" ) ); return; } char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf ( stderr, "%s: Unable to create repeater socket because \"%s\" - fatal\n", __FILE__, sockErrBuf ); osiSockRelease (); delete [] pBuf; return; } debugPrintf ( ( "CA Repeater: Attached and initialized\n" ) ); while ( true ) { osiSocklen_t from_size = sizeof ( from ); size = recvfrom ( sock, pBuf, MAX_UDP_RECV, 0, &from.sa, &from_size ); if ( size < 0 ) { int errnoCpy = SOCKERRNO; // Avoid spurious ECONNREFUSED bug in linux if ( errnoCpy == SOCK_ECONNREFUSED ) { continue; } // Avoid ECONNRESET from connected socket in windows if ( errnoCpy == SOCK_ECONNRESET ) { continue; } char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf ( stderr, "CA Repeater: unexpected UDP recv err: %s\n", sockErrBuf ); continue; } caHdr * pMsg = ( caHdr * ) pBuf; /* * both zero length message and a registration message * will register a new client */ if ( ( (size_t) size) >= sizeof (*pMsg) ) { if ( AlignedWireRef < epicsUInt16 > ( pMsg->m_cmmd ) == REPEATER_REGISTER ) { register_new_client ( from, freeList ); /* * strip register client message */ pMsg++; size -= sizeof ( *pMsg ); if ( size==0 ) { continue; } } else if ( AlignedWireRef < epicsUInt16 > ( pMsg->m_cmmd ) == CA_PROTO_RSRV_IS_UP ) { if ( pMsg->m_available == 0u ) { pMsg->m_available = from.ia.sin_addr.s_addr; } } } else if ( size == 0 ) { register_new_client ( from, freeList ); continue; } fanOut ( from, pMsg, size, freeList ); } }
extern "C" JNIEXPORT jint JNICALL Java_java_nio_channels_DatagramChannel_makeSocket(JNIEnv* e, jclass) { return makeSocket(e, SOCK_DGRAM, IPPROTO_UDP); }
extern "C" JNIEXPORT jint JNICALL Java_java_nio_channels_SocketChannel_makeSocket(JNIEnv* e, jclass) { return makeSocket(e); }
/* * Actually downloads the page, registering a hit (donation) * If the fileBuf passed in is NULL, the url is downloaded and then * freed; otherwise the necessary space is allocated for fileBuf. * Returns size of download on success, -1 on error is set, */ int http_fetch(const char *url_tmp, char **fileBuf) { fd_set rfds; struct timeval tv; char headerBuf[HEADER_BUF_SIZE]; char *tmp, *url, *pageBuf, *requestBuf = NULL, *host, *charIndex; int sock, bytesRead = 0, contentLength = -1, bufsize = REQUEST_BUF_SIZE; int i, ret = -1, tempSize, selectRet, found = 0, /* For redirects */ redirectsFollowed = 0; if(url_tmp == NULL) { errorSource = FETCHER_ERROR; http_errno = HF_NULLURL; return -1; } /* Copy the url passed in into a buffer we can work with, change, etc. */ url = malloc(strlen(url_tmp)+1); if(url == NULL) { errorSource = ERRNO; return -1; } strncpy(url, url_tmp, strlen(url_tmp) + 1); /* This loop allows us to follow redirects if need be. An afterthought, * added to provide this basic functionality. Will hopefully be designed * better in 2.x.x ;) */ /* while(!found && (followRedirects < 0 || redirectsFollowed < followRedirects) ) */ do { /* Seek to the file path portion of the url */ charIndex = strstr(url, "://"); if(charIndex != NULL) { /* url contains a protocol field */ charIndex += strlen("://"); host = charIndex; charIndex = strchr(charIndex, '/'); } else { host = (char *)url; charIndex = strchr(url, '/'); } /* Compose a request string */ requestBuf = malloc(bufsize); if(requestBuf == NULL) { free(url); errorSource = ERRNO; return -1; } requestBuf[0] = 0; if(charIndex == NULL) { /* The url has no '/' in it, assume the user is making a root-level * request */ tempSize = strlen("GET /") + strlen(HTTP_VERSION) + 2; if(_checkBufSize(&requestBuf, &bufsize, tempSize) || snprintf(requestBuf, bufsize, "GET / %s\r\n", HTTP_VERSION) < 0) { free(url); free(requestBuf); errorSource = ERRNO; return -1; } } else { tempSize = strlen("GET ") + strlen(charIndex) + strlen(HTTP_VERSION) + 4; /* + 4 is for ' ', '\r', '\n', and NULL */ if(_checkBufSize(&requestBuf, &bufsize, tempSize) || snprintf(requestBuf, bufsize, "GET %s %s\r\n", charIndex, HTTP_VERSION) < 0) { free(url); free(requestBuf); errorSource = ERRNO; return -1; } } /* Null out the end of the hostname if need be */ if(charIndex != NULL) *charIndex = 0; /* Use Host: even though 1.0 doesn't specify it. Some servers * won't play nice if we don't send Host, and it shouldn't * hurt anything */ ret = bufsize - strlen(requestBuf); /* Space left in buffer */ tempSize = (int)strlen("Host: ") + (int)strlen(host) + 3; /* +3 for "\r\n\0" */ if(_checkBufSize(&requestBuf, &bufsize, tempSize + 128)) { free(url); free(requestBuf); errorSource = ERRNO; return -1; } strcat(requestBuf, "Host: "); strcat(requestBuf, host); strcat(requestBuf, "\r\n"); if(!hideReferer && referer != NULL) /* NO default referer */ { tempSize = (int)strlen("Referer: ") + (int)strlen(referer) + 3; /* + 3 is for '\r', '\n', and NULL */ if(_checkBufSize(&requestBuf, &bufsize, tempSize)) { free(url); free(requestBuf); errorSource = ERRNO; return -1; } strcat(requestBuf, "Referer: "); strcat(requestBuf, referer); strcat(requestBuf, "\r\n"); } if(!hideUserAgent && userAgent == NULL) { tempSize = (int)strlen("User-Agent: ") + (int)strlen(DEFAULT_USER_AGENT) + (int)strlen(VERSION) + 4; /* + 4 is for '\', '\r', '\n', and NULL */ if(_checkBufSize(&requestBuf, &bufsize, tempSize)) { free(url); free(requestBuf); errorSource = ERRNO; return -1; } strcat(requestBuf, "User-Agent: "); strcat(requestBuf, DEFAULT_USER_AGENT); strcat(requestBuf, "/"); strcat(requestBuf, VERSION); strcat(requestBuf, "\r\n"); } else if(!hideUserAgent) { tempSize = (int)strlen("User-Agent: ") + (int)strlen(userAgent) + 3; /* + 3 is for '\r', '\n', and NULL */ if(_checkBufSize(&requestBuf, &bufsize, tempSize)) { free(url); free(requestBuf); errorSource = ERRNO; return -1; } strcat(requestBuf, "User-Agent: "); strcat(requestBuf, userAgent); strcat(requestBuf, "\r\n"); } tempSize = (int)strlen("Connection: Close\r\n\r\n"); if(_checkBufSize(&requestBuf, &bufsize, tempSize)) { free(url); free(requestBuf); errorSource = ERRNO; return -1; } strcat(requestBuf, "Connection: Close\r\n\r\n"); /* Now free any excess memory allocated to the buffer */ tmp = realloc(requestBuf, strlen(requestBuf) + 1); if(tmp == NULL) { free(url); free(requestBuf); errorSource = ERRNO; return -1; } requestBuf = tmp; sock = makeSocket(host); /* errorSource set within makeSocket */ if(sock == -1) { free(url); free(requestBuf); return -1;} free(url); url = NULL; if(write(sock, requestBuf, strlen(requestBuf)) == -1) { close(sock); free(requestBuf); errorSource = ERRNO; return -1; } free(requestBuf); requestBuf = NULL; /* Grab enough of the response to get the metadata */ ret = _http_read_header(sock, headerBuf); /* errorSource set within */ if(ret < 0) { close(sock); return -1; } /* Get the return code */ charIndex = strstr(headerBuf, "HTTP/"); if(charIndex == NULL) { close(sock); errorSource = FETCHER_ERROR; http_errno = HF_FRETURNCODE; return -1; } while(*charIndex != ' ') charIndex++; charIndex++; ret = sscanf(charIndex, "%d", &i); if(ret != 1) { close(sock); errorSource = FETCHER_ERROR; http_errno = HF_CRETURNCODE; return -1; } if(i<200 || i>307) { close(sock); errorInt = i; /* Status code, to be inserted in error string */ errorSource = FETCHER_ERROR; http_errno = HF_STATUSCODE; return -1; } /* If a redirect, repeat operation until final URL is found or we * redirect followRedirects times. Note the case sensitive "Location", * should probably be made more robust in the future (without relying * on the non-standard strcasecmp()). * This bit mostly by Dean Wilder, tweaked by me */ if(i >= 300) { redirectsFollowed++; /* Pick up redirect URL, allocate new url, and repeat process */ charIndex = strstr(headerBuf, "Location:"); if(!charIndex) { close(sock); errorInt = i; /* Status code, to be inserted in error string */ errorSource = FETCHER_ERROR; http_errno = HF_CANTREDIRECT; return -1; } charIndex += strlen("Location:"); /* Skip any whitespace... */ while(*charIndex != '\0' && isspace((int)*charIndex)) charIndex++; if(*charIndex == '\0') { close(sock); errorInt = i; /* Status code, to be inserted in error string */ errorSource = FETCHER_ERROR; http_errno = HF_CANTREDIRECT; return -1; } i = strcspn(charIndex, " \r\n"); if(i > 0) { url = (char *)malloc(i + 1); strncpy(url, charIndex, i); url[i] = '\0'; } else /* Found 'Location:' but contains no URL! We'll handle it as * 'found', hopefully the resulting document will give the user * a hint as to what happened. */ found = 1; } else found = 1; } while(!found && (followRedirects < 0 || redirectsFollowed <= followRedirects) ); if(url) /* Redirection code may malloc this, then exceed followRedirects */ { free(url); url = NULL; } if(redirectsFollowed >= followRedirects && !found) { close(sock); errorInt = followRedirects; /* To be inserted in error string */ errorSource = FETCHER_ERROR; http_errno = HF_MAXREDIRECTS; return -1; } /* * Parse out about how big the data segment is. * Note that under current HTTP standards (1.1 and prior), the * Content-Length field is not guaranteed to be accurate or even present. * I just use it here so I can allocate a ballpark amount of memory. * * Note that some servers use different capitalization */ charIndex = strstr(headerBuf, "Content-Length:"); if(charIndex == NULL) charIndex = strstr(headerBuf, "Content-length:"); if(charIndex != NULL) { ret = sscanf(charIndex + strlen("content-length: "), "%d", &contentLength); if(ret < 1) { close(sock); errorSource = FETCHER_ERROR; http_errno = HF_CONTENTLEN; return -1; } } /* Allocate enough memory to hold the page */ if(contentLength == -1) contentLength = DEFAULT_PAGE_BUF_SIZE; pageBuf = (char *)malloc(contentLength); if(pageBuf == NULL) { close(sock); errorSource = ERRNO; return -1; } /* Begin reading the body of the file */ while(ret > 0) { FD_ZERO(&rfds); FD_SET(sock, &rfds); tv.tv_sec = timeout; tv.tv_usec = 0; if(timeout >= 0) selectRet = select(sock+1, &rfds, NULL, NULL, &tv); else /* No timeout, can block indefinately */ selectRet = select(sock+1, &rfds, NULL, NULL, NULL); if(selectRet == 0) { errorSource = FETCHER_ERROR; http_errno = HF_DATATIMEOUT; errorInt = timeout; close(sock); free(pageBuf); return -1; } else if(selectRet == -1) { setoserror(neterror()); close(sock); free(pageBuf); errorSource = ERRNO; return -1; } ret = recv(sock, pageBuf + bytesRead, contentLength, 0); if(ret == -1) { setoserror(neterror()); close(sock); free(pageBuf); errorSource = ERRNO; return -1; } bytesRead += ret; if(ret > 0) { /* To be tolerant of inaccurate Content-Length fields, we'll * allocate another read-sized chunk to make sure we have * enough room. */ tmp = (char *)realloc(pageBuf, bytesRead + contentLength); if(tmp == NULL) { close(sock); free(pageBuf); errorSource = ERRNO; return -1; } pageBuf = tmp; } } /* * The download buffer is too large. Trim off the safety padding. * Note that we add one NULL byte to the end of the data, as it may not * already be NULL terminated and we can't be sure what type of data it * is or what the caller will do with it. */ tmp = (char *)realloc(pageBuf, bytesRead + 1); /* tmp shouldn't be null, since we're _shrinking_ the buffer, * and if it DID fail, we could go on with the too-large buffer, * but something would DEFINATELY be wrong, so we'll just give * an error message */ if(tmp == NULL) { close(sock); free(pageBuf); errorSource = ERRNO; return -1; } pageBuf = tmp; pageBuf[bytesRead] = '\0'; /* NULL terminate the data */ if(fileBuf == NULL) /* They just wanted us to "hit" the url */ free(pageBuf); else *fileBuf = pageBuf; close(sock); return bytesRead; }
int main(int argc, char *argv[]) { fd_set rset; struct timeval timeout; char * IP; //IP address of socket char * PTY; //Pseudo Terminal Name unsigned char cBuff[BUFFER]; //char c[BUFFER]; int csize; int pty = -1; //Pseudo Terminal File Descriptor int sockfd1, sockfd2 = -1; int x; int args = 0; int tmp; char argSerial[] = "-serial"; char argHelp[] = "-help"; char argPort[] = "-port"; char argPTY[] = "-pty"; char argStrip[] = "-strip"; char argBaud[] = "-baud"; char argDebug[] = "-debug"; int SOCKET_PORT, BAUD, STRIP, DEBUG = 0; char SERIAL[100]; for (x = 0; x < argc; x++){//Cycle through the command line arguments if (!strcmp(argSerial,argv[x])) {//Look for the -serial option strcpy(SERIAL,argv[x+1]); //Copies the port to SERIAL if(BAUD>0){ //If the baud option has been passed sockfd2 = connectSerial(SERIAL, BAUD); //Open the serial port and return the file descriptor if (sockfd2 < 0) { close(sockfd2); if(sockfd1>=0) close(sockfd1); if(pty>=0) close(pty); return -1; }else{ args+=3; } }else{ args+=3; } } else if (!strcmp(argPort,argv[x])) { //Look for -port option SOCKET_PORT = atoi(argv[x+1]); //Convert string address into int sockfd1 = makeSocket(SOCKET_PORT); //Make the socket and return the file descriptor if (sockfd1 < 0) { close(sockfd1); if(sockfd2>=0) close(sockfd2); if(pty>=0) close(pty); return -1; }else{ args+=5; } } else if (!strcmp(argPTY,argv[x])) { //Look for -pty option pty = pseudoTY(&PTY); if(pty<0){ close(pty); if(sockfd2>=0) close(sockfd2); if(sockfd1>=0) close(sockfd1); return -1; }else{ args+=7; } } else if (!strcmp(argBaud,argv[x])) { //Look for -baud option tmp = atoi(argv[x+1]); //Convert string baud rate to int switch (tmp) { //Make sure the value is supported case 115200: BAUD = B115200; break; case 38400: BAUD = B38400; break; case 19200: BAUD = B19200; break; case 9600: BAUD = B9600; break; default: printf("ERROR!: Unknown baud rate.\n"); return -1; break; } if(strlen(SERIAL) != 0) //If we got the tag for a serial port, create the serial port sockfd2 = connectSerial(SERIAL, BAUD); //Open the serial port and return the file descriptor args+=1; } else if ( (args != 9 && args != 11 && args !=16 && x == argc-1) || (!strcmp(argHelp,argv[x]))) { //If not enough arguments, output usage directions and exit // Serial <=> Socket w/ baud = 9 // Serial <=> PTY w/ baud = 11 // Serial <=> Socket, Serial <=> PTY w/ baud = 16 printf("--------------------------------------\n"); printf("------------ SerialDaemon ------------\n"); printf("--------------------------------------\n"); printf("Usage:"); printf("\t./serialdaemon [options] [arguments]\n"); printf("\t-serial [Use to indicate which serial port to connect to. E.G. /dev/ttyS1]\n"); printf("\t-port [Use to indicate which TCP/IP port of the local host to connect to. E.G. 5000]\n"); printf("\t-pty [Create a pseudo terminal for the serial port to connect to.]\n"); printf("\t-baud [Serial port baudrate.]\n"); printf("\t\t115200\n"); printf("\t\t38400\n"); printf("\t\t19200\n"); printf("\t\t9600\n"); printf("\t-strip [Strip the endline character and replace with a space.]\n"); printf("\t-debug [Set the verbose debug mode for help.]\n"); printf("\t-help [For this help screen.]\n\n"); printf("Example Usage:\t./serialdaemon -serial /dev/ttyS1 -baud 115200 -pty -port 5000\n"); printf("This will link ttyS1 to localhost:5000 and ttyS1 to a pseudo terminal. The connection to ttyS1 will have a baudrate of 115200.\n"); return -1; } else if (!strcmp(argStrip,argv[x])){STRIP = 1;} //Look for the -strip option else if (!strcmp(argDebug,argv[x])){DEBUG = 1; printf ("DEBUG: debug mode on!\n");} //Look for the -debug option } signal(SIGINT, controlC); // catch ^C so we can close sockets & exit cleanly IP = getIP(); //Get the local IP address if(args == 9)//Serial to Socket printf("Connections made: \n\t\t\t%s < = > http://%s:%d\n",SERIAL,IP,SOCKET_PORT); else if(args == 11)//Serial to PTY printf("Connections made: \n\t\t\t%s < = > %s\n",SERIAL,PTY); else if(args == 16)//Serial to PTY & Serial to Socket printf("Connections made: \n\t\t\t%s < = > http://%s:%d\n\t\t\t%s < = > %s\n",SERIAL,IP,SOCKET_PORT,SERIAL,PTY); sd1 = waitOnSocket(sockfd1); //Check for a connection to the socket while(1){ /* Select on sockets */ if(sd1 > 0){ //If There is a connection to the socket then potentially set up these connections: tty < = > socket and tty < = > pty if (DEBUG) printf("DEBUG: New client socket opened.\n"); if (sd1 < 0) { //Error in creating connection close(sd1); return -1; } sd2 = sockfd2; //File descriptor of the serial port if (sd2 < 0) { //If an error close(sd1); close(sd2); return -1; } FD_ZERO(&rset); //Clear file descriptors in the rset set while(1) { FD_SET(sd1,&rset);//Set sd1 in rset FD_SET(sd2,&rset);//Set sd2 in rset if(pty!=-1) {//If a virtual port is requested FD_SET(pty,&rset); select(max(max(sd1,sd2),pty)+1,&rset,NULL,NULL,NULL); //Select specifies which of the file descriptors is ready for reading or writing }else { select(max(sd1,sd2)+1,&rset,NULL,NULL,NULL); //Select tests file descriptors in the range of 0 to nfds-1 or in this case 0 to max(sd1,sd2). } //----------------Check The Socket For Data ------------------ if (FD_ISSET(sd1,&rset)) { //Is there stuff to read from the socket /* There's stuff to read */ if ((csize= read(sd1, &cBuff, BUFFER)) >= 1) { //If there's something worth reading if (STRIP==1) { //Remove endline characters and replace with space for(x = 0 ; x < csize; x++) { if (cBuff[x] == '\n' ) { cBuff[x] = ' '; if (DEBUG) printf ("DEBUG: **STRIPPED**\n"); } } } if (DEBUG) { //Replace &cBuff and cBuff with c //cBuff[csize] = '\0'; printf("\nDEBUG: %s <== ",SERIAL); for(x=0; x<csize;x++){ printf("%#.2x ",cBuff[x]); } printf("\n"); } write(sd2, &cBuff, csize);//Write data from sd1 to sd2 }else{break;}// Failed -- port closed } //----------------Check The Serial Port For Data ------------------ if (FD_ISSET(sd2,&rset)) {//Is there stuff to read from the serial port if ((csize = read(sd2, &cBuff, BUFFER)) >= 1) {//If there is something worth reading from the serial port write(sd1, &cBuff, csize); //Write this data to the socket if(pty != -1){write(pty,&cBuff,csize);} //Write this data to the virtual com port if (DEBUG) { //Replace &cBuff and cBuff with c //cBuff[csize] = '\0'; printf("DEBUG: http://%s:%d <== ",IP,SOCKET_PORT); for(x=0; x<csize;x++){ printf("%#.2x ",cBuff[x]); } printf("\n"); if(pty !=-1){ printf("DEBUG: %s <== ",PTY); for(x=0; x<csize;x++){ printf("%#.2x ",cBuff[x]); } printf("\n"); } } } //else break; /* Failed */ } //----------------Check The PTY Port For Data ------------------ if (pty != -1 && FD_ISSET(pty,&rset)) {//If there is a virtual port, and data is ready, write data from if ((csize = read(pty, &cBuff, BUFFER)) >= 1) {//If there is something worth reading from the serial port write(sd2, &cBuff, csize); //Write this data to the serial port if (DEBUG) { //Replace &cBuff and cBuff with c //cBuff[csize] = '\0'; printf("\nDEBUG: %s <== ",SERIAL); for(x=0; x<csize;x++){ printf("%#.2x ",cBuff[x]); } printf("\n"); } } //else break; /* Failed */ } } printf("Restarting\n"); close(sd1);/* clean up */ sd1 = waitOnSocket(sockfd1); //Check for a connection to the socket }else if(pty != -1) {//Else, if there is a virtual port then tty <=> pty sd2 = sockfd2; //File descriptor of the serial port if (sd2 < 0) { //If an error close(sd2); close(pty); return -1; } FD_ZERO(&rset); //Clear file descriptors in the rset set while(1) { FD_SET(sd2,&rset);//Set sd2 in rset FD_SET(pty,&rset);//Set pty in rset sd1 = waitOnSocket(sockfd1); if(sd1 >= 0){break;} //Check for socket connection, if there is, break out of this loop. select(max(sd2,pty)+1,&rset,NULL,NULL,NULL); // Specifies which of the file descriptors is ready for reading or writing if (FD_ISSET(pty,&rset)) { //If there is a virtual port, and data is ready, write data from if ((csize = read(pty, &cBuff, BUFFER)) >= 1) {//If there is something worth reading from the serial port write(sd2, &cBuff, csize); //Write this data to the serial port if (DEBUG) { //Replace &cBuff and cBuff with c //cBuff[csize] = '\0'; printf("\nDEBUG: %s <== ",SERIAL); for(x=0; x<csize;x++){ printf("%#.2x ",cBuff[x]); } printf("\n"); } } //else break; // Failed } if (FD_ISSET(sd2,&rset)) {//Is there stuff to read from the serial port if ((csize = read(sd2, &cBuff, BUFFER)) >= 1) { //If there is something worth reading from the serial port write(pty, &cBuff, csize); //Write this data to the virtual com port if (DEBUG) { //Replace &cBuff and cBuff with c //cBuff[csize] = '\0'; printf("DEBUG: %s <== ",PTY); for(x=0; x<csize;x++){ printf("%#.2x ",cBuff[x]); } printf("\n"); } } //else break; /* Failed */ } } }else {//If there isn't a pty, then check the socket for a connection once a second if(DEBUG) printf("\rWaiting on the socket connection...\n"); sd1 = waitOnSocket(sockfd1); //Check for a connection to the socket sleep(1); } } }
bool DebuggerServer::start() { TRACE(2, "DebuggerServer::start\n"); int port = RuntimeOption::DebuggerServerPort; int backlog = 128; struct addrinfo hint; struct addrinfo *ai; memset(&hint, 0, sizeof(hint)); hint.ai_family = AF_UNSPEC; hint.ai_socktype = SOCK_STREAM; hint.ai_flags = AI_PASSIVE; if (RuntimeOption::DebuggerDisableIPv6) { hint.ai_family = AF_INET; } if (getaddrinfo(nullptr, std::to_string(port).c_str(), &hint, &ai)) { Logger::Error("unable to get address information"); return false; } SCOPE_EXIT { freeaddrinfo(ai); }; /* use a cur pointer so we still have ai to be able to free the struct */ struct addrinfo *cur; for (cur = ai; cur; cur = cur->ai_next) { int s_fd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol); if (s_fd < 0 && errno == EAFNOSUPPORT) { continue; } auto m_sock = makeSocket(s_fd, cur->ai_family, cur->ai_addr->sa_data, port); int yes = 1; setsockopt(m_sock->fd(), SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); if (!m_sock->valid()) { Logger::Error("unable to create debugger server socket"); return false; } if (cur->ai_family == AF_INET6) { int on = 1; setsockopt(m_sock->fd(), IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); } if (bind(m_sock->fd(), cur->ai_addr, cur->ai_addrlen) < 0) { Logger::Error("unable to bind to port %d for debugger server", port); return false; } if (listen(m_sock->fd(), backlog) < 0) { Logger::Error("unable to listen on port %d for debugger server", port); return false; } m_socks.push_back(m_sock->getData()); } if (m_socks.size() == 0) { Logger::Error("Did not bind to any sockets on port %d", port); return false; } m_serverThread.start(); return true; }
void startServer(int port) { // Make sure types have the required size. assert(sizeof(bits8) == 1); assert(sizeof(bits16) == 2); assert(sizeof(bits32) == 4); int parsedValues; #ifdef _WIN32 WSADATA wsaData; WSAStartup(0x0202, &wsaData); #endif int sock = makeSocket(port); char req[REQ_SIZE + 1]; req[REQ_SIZE] = 0; while (1) { int conn = waitForConnection(sock); recv(conn, req, REQ_SIZE, 0); // Cut the string off to one line. char *endOfLine = strchr(req, '\n'); if (endOfLine != NULL) { *endOfLine = '\0'; } // Find the path. char path[PATH_SIZE + 1]; parsedValues = sscanf(req, "GET %s HTTP/1.1", path); if (parsedValues == 1) { if (strcmp(path, "/") == 0) { // Homepage char *msg = "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" "\r\n" "<!DOCTYPE html>\n" "<script src=\"http://almondbread.cse.unsw.edu.au/tiles.js\"></script>\n"; send(conn, msg, strlen(msg), 0); } else { double x, y; int zoom; parsedValues = sscanf( path, "/tile_x%lf_y%lf_z%d.bmp", &x, &y, &zoom); if (parsedValues == 3) { char *msg = "HTTP/1.0 200 OK\r\n" "Content-Type: image/bmp\r\n" "\r\n"; send(conn, msg, strlen(msg), 0); char image[FILE_SIZE]; mandelBitmap(image, x, y, zoom); send(conn, image, FILE_SIZE, 0); } else { // HTTP Error 404. } } } else { // HTTP Error 400. } closeSocket(conn); } // Closing the socket is unnecessary, because the OS will // immediately recover it thanks to SO_REUSEADDR. }
int KeyRemap4MacBook_client::sendmsg(KeyRemap4MacBook_bridge::RequestType type, void* request, uint32_t requestsize, void* reply, uint32_t replysize) { if (! lock_) { return EIO; } IOLockWrapper::ScopedLock lk(lock_); if (type == KeyRemap4MacBook_bridge::REQUEST_STATUS_MESSAGE) { if (config.general_hide_statusmessage) { if (! request) return 0; char* p = reinterpret_cast<KeyRemap4MacBook_bridge::StatusMessage::Request*>(request)->message; if (p[0] != '\0') { return 0; } } } // ------------------------------------------------------------ int result = 0; int error = 0; socket_t socket; bool isMakeSocket = false; if (! makeSocket(socket)) { result = EIO; goto finish; } isMakeSocket = true; if (! connectSocket(socket)) { result = EIO; goto finish; } // ---------------------------------------- struct msghdr msg; memset(&msg, 0, sizeof(msg)); struct iovec aiov[3]; size_t iolen; aiov[0].iov_base = reinterpret_cast<caddr_t>(&type); aiov[0].iov_len = sizeof(type); if (requestsize <= 0) { msg.msg_iovlen = 1; } else { aiov[1].iov_base = reinterpret_cast<caddr_t>(&requestsize); aiov[1].iov_len = sizeof(requestsize); aiov[2].iov_base = reinterpret_cast<caddr_t>(request); aiov[2].iov_len = requestsize; msg.msg_iovlen = 3; } msg.msg_iov = aiov; error = sock_send(socket, &msg, 0, &iolen); if (error) { printf("KeyRemap4MacBook_client::sendmsg sock_send failed(%d)\n", error); result = error; goto finish; } // ---------------------------------------- if (replysize > 0) { memset(&msg, 0, sizeof(msg)); uint32_t status = -1; aiov[0].iov_base = reinterpret_cast<caddr_t>(&status); aiov[0].iov_len = sizeof(status); aiov[1].iov_base = reinterpret_cast<caddr_t>(reply); aiov[1].iov_len = replysize; msg.msg_iov = aiov; msg.msg_iovlen = 2; error = sock_receive(socket, &msg, MSG_WAITALL, &iolen); if (error) { printf("KeyRemap4MacBook_client::sendmsg sock_receive failed(%d)\n", error); result = error; goto finish; } } finish: if (isMakeSocket) { releaseSocket(socket); } if (result) { printf("KeyRemap4MacBook_client::sendmsg error result (%d)\n", result); } return result; }
int startReceiver(int doWarn, struct disk_config *disk_config, struct net_config *net_config, struct stat_config *stat_config, const char *ifName) { char ipBuffer[16]; union serverControlMsg Msg; int connectReqSent=0; struct client_config client_config; int outFile=1; int pipedOutFile; struct sockaddr_in myIp; int pipePid = 0; int origOutFile; int haveServerAddress; client_config.sender_is_newgen = 0; net_config->net_if = getNetIf(ifName); zeroSockArray(client_config.socks, NR_CLIENT_SOCKS); client_config.S_UCAST = makeSocket(ADDR_TYPE_UCAST, net_config->net_if, 0, RECEIVER_PORT(net_config->portBase)); client_config.S_BCAST = makeSocket(ADDR_TYPE_BCAST, net_config->net_if, 0, RECEIVER_PORT(net_config->portBase)); if(net_config->ttl == 1 && net_config->mcastRdv == NULL) { getBroadCastAddress(net_config->net_if, &net_config->controlMcastAddr, SENDER_PORT(net_config->portBase)); setSocketToBroadcast(client_config.S_UCAST); } else { getMcastAllAddress(&net_config->controlMcastAddr, net_config->mcastRdv, SENDER_PORT(net_config->portBase)); if(isMcastAddress(&net_config->controlMcastAddr)) { setMcastDestination(client_config.S_UCAST, net_config->net_if, &net_config->controlMcastAddr); setTtl(client_config.S_UCAST, net_config->ttl); client_config.S_MCAST_CTRL = makeSocket(ADDR_TYPE_MCAST, net_config->net_if, &net_config->controlMcastAddr, RECEIVER_PORT(net_config->portBase)); // TODO: subscribe address as receiver to! } } clearIp(&net_config->dataMcastAddr); udpc_flprintf("%sUDP receiver for %s at ", disk_config->pipeName == NULL ? "" : "Compressed ", disk_config->fileName == NULL ? "(stdout)":disk_config->fileName); printMyIp(net_config->net_if); udpc_flprintf(" on %s\n", net_config->net_if->name); connectReqSent = 0; haveServerAddress = 0; client_config.clientNumber= 0; /*default number for asynchronous transfer*/ while(1) { // int len; int msglen; int sock; if (!connectReqSent) { if (sendConnectReq(&client_config, net_config, haveServerAddress) < 0) { perror("sendto to locate server"); } connectReqSent = 1; } haveServerAddress=0; sock = udpc_selectSock(client_config.socks, NR_CLIENT_SOCKS, net_config->startTimeout); if(sock < 0) { return -1; } // len = sizeof(server); msglen=RECV(sock, Msg, client_config.serverAddr, net_config->portBase); if (msglen < 0) { perror("recvfrom to locate server"); exit(1); } if(getPort(&client_config.serverAddr) != SENDER_PORT(net_config->portBase)) /* not from the right port */ continue; switch(ntohs(Msg.opCode)) { case CMD_CONNECT_REPLY: client_config.clientNumber = ntohl(Msg.connectReply.clNr); net_config->blockSize = ntohl(Msg.connectReply.blockSize); udpc_flprintf("received message, cap=%08lx\n", (long) ntohl(Msg.connectReply.capabilities)); if(ntohl(Msg.connectReply.capabilities) & CAP_NEW_GEN) { client_config.sender_is_newgen = 1; copyFromMessage(&net_config->dataMcastAddr, Msg.connectReply.mcastAddr); } if (client_config.clientNumber == -1) { udpc_fatal(1, "Too many clients already connected\n"); } goto break_loop; case CMD_HELLO_STREAMING: case CMD_HELLO_NEW: case CMD_HELLO: connectReqSent = 0; if(ntohs(Msg.opCode) == CMD_HELLO_STREAMING) net_config->flags |= FLAG_STREAMING; if(ntohl(Msg.hello.capabilities) & CAP_NEW_GEN) { client_config.sender_is_newgen = 1; copyFromMessage(&net_config->dataMcastAddr, Msg.hello.mcastAddr); net_config->blockSize = ntohs(Msg.hello.blockSize); if(ntohl(Msg.hello.capabilities) & CAP_ASYNC) net_config->flags |= FLAG_PASSIVE; if(net_config->flags & FLAG_PASSIVE) goto break_loop; } haveServerAddress=1; continue; case CMD_CONNECT_REQ: case CMD_DATA: case CMD_FEC: continue; default: break; } udpc_fatal(1, "Bad server reply %04x. Other transfer in progress?\n", (unsigned short) ntohs(Msg.opCode)); } break_loop: udpc_flprintf("Connected as #%d to %s\n", client_config.clientNumber, getIpString(&client_config.serverAddr, ipBuffer)); getMyAddress(net_config->net_if, &myIp); if(!ipIsZero(&net_config->dataMcastAddr) && !ipIsEqual(&net_config->dataMcastAddr, &myIp) && (ipIsZero(&net_config->controlMcastAddr) || !ipIsEqual(&net_config->dataMcastAddr, &net_config->controlMcastAddr) )) { udpc_flprintf("Listening to multicast on %s\n", getIpString(&net_config->dataMcastAddr, ipBuffer)); client_config.S_MCAST_DATA = makeSocket(ADDR_TYPE_MCAST, net_config->net_if, &net_config->dataMcastAddr, RECEIVER_PORT(net_config->portBase)); } if(net_config->requestedBufSize) { int i; for(i=0; i<NR_CLIENT_SOCKS; i++) if(client_config.socks[i] != -1) setRcvBuf(client_config.socks[i],net_config->requestedBufSize); } outFile=openOutFile(disk_config); origOutFile = outFile; pipedOutFile = openPipe(outFile, disk_config, &pipePid); global_client_config= &client_config; atexit(sendDisconnectWrapper); { struct fifo fifo; int printUncompressedPos = udpc_shouldPrintUncompressedPos(stat_config->printUncompressedPos, origOutFile, pipedOutFile); receiver_stats_t stats = allocReadStats(origOutFile, stat_config->statPeriod, printUncompressedPos); udpc_initFifo(&fifo, net_config->blockSize); fifo.data = pc_makeProduconsum(fifo.dataBufSize, "receive"); client_config.isStarted = 0; if((net_config->flags & (FLAG_PASSIVE|FLAG_NOKBD))) { /* No console used */ client_config.console = NULL; } else { if(doWarn) udpc_flprintf("WARNING: This will overwrite the hard disk of this machine\n"); client_config.console = prepareConsole(0); atexit(fixConsole); } spawnNetReceiver(&fifo,&client_config, net_config, stats); writer(&fifo, pipedOutFile); if(pipePid) { close(pipedOutFile); } pthread_join(client_config.thread, NULL); /* if we have a pipe, now wait for that too */ if(pipePid) { udpc_waitForProcess(pipePid, "Pipe"); } #ifndef __MINGW32__ fsync(origOutFile); #endif /* __MINGW32__ */ displayReceiverStats(stats, 1); } fixConsole(); sendDisconnectWrapper(); global_client_config= NULL; return 0; }
int main(int argc, char *argv[]) { fd_set rset; struct timeval timeout; char c[BUFFER_SIZE]; int csize; int mode; int x; int y; int args = 0; int tmp; int result; int blockerror = 0; char argSerial[] = "-serial"; char argPort[] = "-port"; char argStrip[] = "-strip"; char argBaud[] = "-baud"; char argDebug[] = "-debug"; char argInDebug[] = "-indebug"; char argOutDebug[] = "-outdebug"; char argNonblock[] = "-nonblock"; char argAux[] = "-aux"; int SOCKET_PORT = 0; int BAUD = 0; int STRIP = 0; int NONBLOCK = 0; int AUX_PORT = 0; char SERIAL[100]; for (x=1; x<argc; x++) { if (!strcmp(argSerial,argv[x])) { strcpy(SERIAL,argv[x+1]); x++; args++; } else if (!strcmp(argPort,argv[x])) { SOCKET_PORT = atoi(argv[x+1]); x++; args++; } else if (!strcmp(argBaud,argv[x])) { BAUD = parseBaudRates(argv[x+1]); if (!BAUD) return 1; x++; args++; } else if (!strcmp(argAux, argv[x])) { AUX_PORT = atoi(argv[x+1]); x++; } else if (!strcmp(argStrip,argv[x])) STRIP = 1; else if (!strcmp(argInDebug,argv[x])) INDEBUG = 1; else if (!strcmp(argOutDebug,argv[x])) OUTDEBUG = 1; else if (!strcmp(argDebug,argv[x])) INDEBUG = OUTDEBUG = 1; else if (!strcmp(argNonblock,argv[x])) NONBLOCK = 1; else { printf("ERROR!: Unknown argument %s\n", argv[x]); return 1; } } if (args < 3) { printf("--------------------------------------------------------------\n"); printf("------------------ GMU SerialDaemon ------------------------\n"); printf("--------------------------------------------------------------\n"); printf("Usage:\n"); printf("\tserialdaemon\n"); printf("\t\t-serial [serialPort]\n"); printf("\t\t-port [TCP/IP Port]\n"); printf("\t\t-aux [auxiliary TCP/IP Port]\n"); printf("\t\t-baud [baudRate]\n"); printf("\t\t\t500000 (available on Linux only)\n"); printf("\t\t\t460800 (available on Linux only)\n"); printf("\t\t\t230400\n"); printf("\t\t\t115200\n"); printf("\t\t\t57600\n"); printf("\t\t\t38400\n"); printf("\t\t\t19200\n"); printf("\t\t\t9600\n"); printf("\t\t-strip\n"); printf("\t\t-indebug\n"); printf("\t\t-outdebug\n"); printf("\t\t-debug\n"); printf("\t\t-nonblock\n"); printf("\n"); printf("Notes:\n"); printf("1) If you have declared an auxiliary port, your client program\n"); printf(" must connect to the primary TCP/IP port, THEN the auxiliary\n"); printf(" port, and both must be connected before any traffic is sent\n"); printf("2) Baud rates 460800 and 500000 are not available on OS/X\n"); return(1); } if (INDEBUG || OUTDEBUG) printf ("DEBUG: debug mode on!\n"); sockfd_pre = makeSocket(SOCKET_PORT); if (sockfd_pre <= 0) { printf("ERROR: couldn't make TCP/IP socket!\n"); closeAll(); return; } if (AUX_PORT != 0) { auxfd_pre = makeSocket(AUX_PORT); if (auxfd_pre <= 0) { printf("ERROR: couldn't make TCP/IP socket!\n"); closeAll(); return; } } serialfd = makeSerialPortFd(SERIAL, BAUD); if (serialfd <= 0) { printf("ERROR: couldn't open serial port!\n"); closeAll(); return; } if (argc <= 1) mode = 0; else mode = atoi(argv[1]); printf("Listening for data connections on port: %i\n",SOCKET_PORT); if (AUX_PORT != 0) { printf("Listening for aux connections on port: %i\n",AUX_PORT); } while(1) { /* Wait for connection on data socket */ sockfd = waitOnSocket(sockfd_pre); if (INDEBUG || OUTDEBUG) printf("DEBUG: New data socket opened.\n"); if (sockfd < 0) { closeAll(); return; } /* Set data socket to non-blocking */ if (NONBLOCK) { if (fcntl(sockfd, F_SETFL, O_NONBLOCK) != 0) { printf("ERROR: couldn't make TCP/IP socket non-blocking!\n"); closeAll(); return; } } /* Wait for connection on AUX socket (if specified) */ if (auxfd_pre != NOTHING) { auxfd = waitOnSocket(auxfd_pre); if (INDEBUG || OUTDEBUG) printf("DEBUG: New aux socket opened.\n"); if (auxfd < 0) { closeAll(); return; } } /* Must have a serial file descriptor (else, why are we running?) */ if (serialfd < 0) { closeAll(); return; } FD_ZERO(&rset); /* Main Loop */ while(1) { /* Add connections to set */ FD_SET(sockfd,&rset); if (auxfd!=NOTHING) FD_SET(auxfd,&rset); FD_SET(serialfd,&rset); /* Select on connection */ select(max(max(sockfd,auxfd),serialfd)+1,&rset,NULL,NULL,NULL); /* There's stuff to read on AUX */ if (FD_ISSET(auxfd,&rset)) { if ((csize = readline(auxfd, c, BUFFER_SIZE)) >= 1) { c[csize] = '\0'; // after length, so no problem char cmd = c[0]; if (c[1] != ' ') printf("ERROR!: Malformed AUX command; ignoring\n"); char* data = &c[2]; switch (cmd) { case 'B': if (INDEBUG) { printf("DEBUG: AUX baud change\n"); } auxShiftBaud(data); break; default: printf("ERROR!: Unknown AUX command; ignoring\n"); break; } } else break; /* Failed */ } /* There's stuff to read on SOCKET */ if (FD_ISSET(sockfd,&rset)) { if ((csize= read(sockfd, c, BUFFER_SIZE)) >= 1) { y = csize; if (STRIP==1) { for(x = 0, y = 0 ; x < csize; x++, y++) { if (c[x] == '\n') { // get rid of it y--; if (OUTDEBUG) printf ("DEBUG: **STRIPPED**\n"); } else c[y] = c[x]; } } if (OUTDEBUG) { c[y] = '\0'; // after length, so no problem printf("DEBUG: serial <=="); printDebugString(c, y); } result = write(serialfd, c, y); if (OUTDEBUG) { printf("DEBUG: wrote %d/%d\n", result, y); } } else break; /* Failed */ } /* There's stuff to read on SERIAL */ if (FD_ISSET(serialfd,&rset)) { if ((csize = read(serialfd, c, BUFFER_SIZE)) >= 1) { if (STRIP==1) { for(x = 0 ; x < csize; x++) { if (c[x] == '\r' ) { // get rid of it c[x] = '\n'; if (OUTDEBUG) printf ("DEBUG: **STRIPPED**\n"); } else c[y] = c[x]; } } if (INDEBUG) { c[csize] = '\0'; // after length, so no problem printf("DEBUG: serial ==>"); printDebugString(c, csize); } result = write(sockfd, c, csize); if (result == EWOULDBLOCK) { if (!blockerror) { blockerror = 1; printf("ERROR: dropping bytes writing to socket\n"); } } else if (INDEBUG) { printf("DEBUG: read %d/%d\n", result, csize); } } else break; /* Failed */ } } /* Restart connection-wait loop */ printf("Restarting\n"); close(sockfd); /* clean up */ } }