int ThreadedAudioDevice::waitForDevice(unsigned int wTime) { int ret; unsigned waitSecs = int(wTime / 1000.0); unsigned waitUsecs = 1000 * (wTime - unsigned(waitSecs * 1000)); // Wait wTime msecs for select to return, then bail. if (!stopping()) { int nfds = _device + 1; struct timeval tv; tv.tv_sec = waitSecs; tv.tv_usec = waitUsecs; // If wTime == 0, wait forever by passing NULL as the final arg. // if (!isPlaying()) // printf("select(%d, 0x%x, 0x%x, NULL, 0x%x)...\n", // nfds, &_rfdset, &_wfdset, wTime == 0 ? NULL : &tv); int selret = ::select(nfds, &_rfdset, &_wfdset, NULL, wTime == 0 ? NULL : &tv); if (selret <= 0) { if (errno != EINTR) fprintf(stderr, "ThreadedAudioDevice::waitForDevice: select %s\n", (selret == 0) ? "timed out" : "returned error"); ret = -1; } else { setFDSet(); ret = 0; } } else { PRINT1("ThreadedAudioDevice::waitForDevice: stopping == true\n"); ret = 1; } return ret; }
void ThreadedAudioDevice::setDevice(int dev) { _device = dev; if (_device > 0) { FD_ZERO(&_rfdset); FD_ZERO(&_wfdset); setFDSet(); } }
static UA_StatusCode ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl) { ServerNetworkLayerTCP *layer = nl->handle; #ifdef _WIN32 if((layer->serversockfd = socket(PF_INET, SOCK_STREAM,0)) == (UA_Int32)INVALID_SOCKET) { UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, "Error opening socket, code: %d", WSAGetLastError()); return UA_STATUSCODE_BADINTERNALERROR; } #else if((layer->serversockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, "Error opening socket"); return UA_STATUSCODE_BADINTERNALERROR; } #endif const struct sockaddr_in serv_addr = {.sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY, .sin_port = htons(layer->port), .sin_zero = {0}}; int optval = 1; if(setsockopt(layer->serversockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof(optval)) == -1) { UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, "Error during setting of socket options"); CLOSESOCKET(layer->serversockfd); return UA_STATUSCODE_BADINTERNALERROR; } if(bind(layer->serversockfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, "Error during socket binding"); CLOSESOCKET(layer->serversockfd); return UA_STATUSCODE_BADINTERNALERROR; } socket_set_nonblocking(layer->serversockfd); listen(layer->serversockfd, MAXBACKLOG); UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK, "TCP network layer listening on %.*s", nl->discoveryUrl.length, nl->discoveryUrl.data); return UA_STATUSCODE_GOOD; } static size_t ServerNetworkLayerTCP_getJobs(UA_ServerNetworkLayer *nl, UA_Job **jobs, UA_UInt16 timeout) { ServerNetworkLayerTCP *layer = nl->handle; fd_set fdset; UA_Int32 highestfd = setFDSet(layer, &fdset); struct timeval tmptv = {0, timeout}; UA_Int32 resultsize; resultsize = select(highestfd+1, &fdset, NULL, NULL, &tmptv); if(resultsize < 0) { *jobs = NULL; return 0; } /* accept new connections (can only be a single one) */ if(FD_ISSET(layer->serversockfd, &fdset)) { resultsize--; struct sockaddr_in cli_addr; socklen_t cli_len = sizeof(cli_addr); int newsockfd = accept(layer->serversockfd, (struct sockaddr *) &cli_addr, &cli_len); int i = 1; setsockopt(newsockfd, IPPROTO_TCP, TCP_NODELAY, (void *)&i, sizeof(i)); if(newsockfd >= 0) { socket_set_nonblocking(newsockfd); ServerNetworkLayerTCP_add(layer, newsockfd); } } /* alloc enough space for a cleanup-connection and free-connection job per resulted socket */ if(resultsize == 0) return 0; UA_Job *js = malloc(sizeof(UA_Job) * resultsize * 2); if(!js) return 0; /* read from established sockets */ size_t j = 0; UA_ByteString buf = UA_BYTESTRING_NULL; for(size_t i = 0; i < layer->mappingsSize && j < (size_t)resultsize; i++) { if(!(FD_ISSET(layer->mappings[i].sockfd, &fdset))) continue; UA_StatusCode retval = socket_recv(layer->mappings[i].connection, &buf, 0); if(retval == UA_STATUSCODE_GOOD) { UA_Boolean realloced = UA_FALSE; retval = UA_Connection_completeMessages(layer->mappings[i].connection, &buf, &realloced); if(retval != UA_STATUSCODE_GOOD || buf.length == 0) continue; js[j].job.binaryMessage.connection = layer->mappings[i].connection; js[j].job.binaryMessage.message = buf; if(!realloced) js[j].type = UA_JOBTYPE_BINARYMESSAGE_NETWORKLAYER; else js[j].type = UA_JOBTYPE_BINARYMESSAGE_ALLOCATED; j++; } else if (retval == UA_STATUSCODE_BADCONNECTIONCLOSED) { UA_Connection *c = layer->mappings[i].connection; /* the socket was closed from remote */ js[j].type = UA_JOBTYPE_DETACHCONNECTION; js[j].job.closeConnection = layer->mappings[i].connection; layer->mappings[i] = layer->mappings[layer->mappingsSize-1]; layer->mappingsSize--; j++; js[j].type = UA_JOBTYPE_METHODCALL_DELAYED; js[j].job.methodCall.method = FreeConnectionCallback; js[j].job.methodCall.data = c; j++; } } if(j == 0) { free(js); js = NULL; } *jobs = js; return j; }
static UA_StatusCode ServerNetworkLayerUDP_start(ServerNetworkLayerUDP *layer, UA_Logger logger) { layer->layer.logger = logger; layer->serversockfd = socket(PF_INET, SOCK_DGRAM, 0); if(layer->serversockfd < 0) { UA_LOG_WARNING(layer->layer.logger, UA_LOGCATEGORY_COMMUNICATION, "Error opening socket"); return UA_STATUSCODE_BADINTERNALERROR; } const struct sockaddr_in serv_addr = {.sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY, .sin_port = htons(layer->port), .sin_zero = {0}}; int optval = 1; if(setsockopt(layer->serversockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof(optval)) == -1) { UA_LOG_WARNING(layer->layer.logger, UA_LOGCATEGORY_COMMUNICATION, "Could not setsockopt"); CLOSESOCKET(layer->serversockfd); return UA_STATUSCODE_BADINTERNALERROR; } if(bind(layer->serversockfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { UA_LOG_WARNING(layer->layer.logger, UA_LOGCATEGORY_COMMUNICATION, "Could not bind the socket"); CLOSESOCKET(layer->serversockfd); return UA_STATUSCODE_BADINTERNALERROR; } socket_set_nonblocking(layer->serversockfd); UA_LOG_WARNING(layer->layer.logger, UA_LOGCATEGORY_COMMUNICATION, "Listening for UDP connections on %s:%d", inet_ntoa(serv_addr.sin_addr), ntohs(serv_addr.sin_port)); return UA_STATUSCODE_GOOD; } static size_t ServerNetworkLayerUDP_getJobs(ServerNetworkLayerUDP *layer, UA_Job **jobs, UA_UInt16 timeout) { UA_Job *items = NULL; setFDSet(layer); struct timeval tmptv = {0, timeout}; UA_Int32 resultsize = select(layer->serversockfd+1, &layer->fdset, NULL, NULL, &tmptv); if(resultsize <= 0 || !FD_ISSET(layer->serversockfd, &layer->fdset)) { *jobs = items; return 0; } items = malloc(sizeof(UA_Job)*resultsize); // read from established sockets UA_Int32 j = 0; UA_ByteString buf = {-1, NULL}; if(!buf.data) { buf.data = malloc(sizeof(UA_Byte) * layer->conf.recvBufferSize); if(!buf.data) UA_LOG_WARNING(layer->layer.logger, UA_LOGCATEGORY_COMMUNICATION, "malloc failed"); } struct sockaddr sender; socklen_t sendsize = sizeof(sender); bzero(&sender, sizeof(sender)); buf.length = recvfrom(layer->serversockfd, buf.data, layer->conf.recvBufferSize, 0, &sender, &sendsize); if (buf.length <= 0) { } else { UDPConnection *c = malloc(sizeof(UDPConnection)); if(!c) return UA_STATUSCODE_BADINTERNALERROR; UA_Connection_init(&c->connection); c->from = sender; c->fromlen = sendsize; // c->sockfd = newsockfd; c->connection.getSendBuffer = GetMallocedBuffer; c->connection.releaseSendBuffer = ReleaseMallocedBuffer; c->connection.releaseRecvBuffer = ReleaseMallocedBuffer; c->connection.handle = layer; c->connection.send = sendUDP; c->connection.close = closeConnectionUDP; c->connection.localConf = layer->conf; c->connection.state = UA_CONNECTION_OPENING; items[j].type = UA_JOBTYPE_BINARYMESSAGE_NETWORKLAYER; items[j].job.binaryMessage.message = buf; items[j].job.binaryMessage.connection = (UA_Connection*)c; buf.data = NULL; j++; } if(buf.data) free(buf.data); if(j == 0) { free(items); *jobs = NULL; } else *jobs = items; return j; }