void CMuxCodec::fiboCode(unsigned int nb) { if ( nbBits >= 8 ) emptyBuffer(); int i = 1, t; for( ; nbFibo[i] <= nb; i++){ } int l = i + 1; i--; nb -= nbFibo[i]; register unsigned int r = 0xC0000000; t = i; i--; while( nb > 0 ){ i--; if (nbFibo[i] <= nb){ nb -= nbFibo[i]; r >>= t-i; r |= 0x80000000; t = i; i--; } }
// Handles an incoming message (from the message queue). UtlBoolean SipClientWriteBuffer::handleMessage(OsMsg& eventMessage) { UtlBoolean messageProcessed = FALSE; int msgType = eventMessage.getMsgType(); int msgSubType = eventMessage.getMsgSubType(); if (msgType == OsMsg::OS_SHUTDOWN) { // When shutting down, have to return all queued outgoing messages // with transport errors. emptyBuffer(TRUE); // Continue with shutdown processing. messageProcessed = FALSE; } else if (msgType == OsMsg::OS_EVENT && (msgSubType == SipClientSendMsg::SIP_CLIENT_SEND || msgSubType == SipClientSendMsg::SIP_CLIENT_SEND_KEEP_ALIVE)) { // Queued SIP message to send - normal path. if (msgSubType == SipClientSendMsg::SIP_CLIENT_SEND) { // Insert the SIP message into the queue, detaching it from // the incoming eventMessage. SipClientSendMsg* sendMsg = dynamic_cast <SipClientSendMsg*> (&eventMessage); if (sendMsg) { insertMessage(sendMsg->detachMessage()); messageProcessed = TRUE; } else { Os::Logger::instance().log(FAC_SIP, PRI_CRIT, "SipClientWriteBuffer[%s]::handleMessage " "message is not a SipClientSendMsg", mName.data()); } } else // send Keep Alive { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipClientWriteBuffer[%s]::handleMessage send TCP keep-alive CR-LF response", mName.data()); UtlString* pKeepAlive; pKeepAlive = new UtlString("\r\n"); insertMessage(pKeepAlive); messageProcessed = TRUE; } // Write what we can. writeMore(); // sendMsg will be deleted by ::run(), as usual. // Its destructor will free any storage owned by it. } return (messageProcessed); }
int getUserOkay() { int ok = 0; char c = 0; do { ok = scanf("%c", &c); emptyBuffer(); } while (!ok); if (c == 'y') { return 1; } return 0; }
/** * Get the number from the user. * Ensures it will return a positive integer. * Will loop until it gets a correct number from the user. * * 123foo is considered as 123. * foo123 is refused. * <space>123 is considered as 123. */ long getNumber(const char* nom, long min, long max) { int ok = 0; long n = 0; int checkMax = 1; if (max <= min) { checkMax = 0; } do { if (checkMax) { printf("Input %ld < %s < %ld : ", min - 1, nom, max + 1); } else { printf("Input %s > %ld : ", nom, min - 1); } ok = scanf("%ld", &n); emptyBuffer(); } while (!ok || n < min || (checkMax && n > max)); return n; }
void AudioInputConfig::on_Tick_timeout() { if (!inputProcessor) { inputProcessor = new QtSpeex::SpeexInputProcessor(); inputProcessor->open(QIODevice::WriteOnly | QIODevice::Unbuffered); if (!inputDevice) { inputDevice = AudioDeviceHelper::getPreferedInputDevice(); } inputDevice->start(inputProcessor); connect(inputProcessor, SIGNAL(networkPacketReady()), this, SLOT(emptyBuffer())); } abSpeech->iBelow = ui.qsTransmitMin->value(); abSpeech->iAbove = ui.qsTransmitMax->value(); if (loaded) { rsVoip->setVoipfVADmin(ui.qsTransmitMin->value()); rsVoip->setVoipfVADmax(ui.qsTransmitMax->value()); } abSpeech->iValue = iroundf(inputProcessor->dVoiceAcivityLevel * 32767.0f + 0.5f); abSpeech->update(); }
void *oompaChild(void *boxSize) { int size = ((candy_struct *)boxSize)->num; candy_struct* box = malloc(size * sizeof(candy_struct)); while (1){ //grab the stuff off the assembly line for (int i = 0; i < size; ++i) { pthread_mutex_lock(&mutex); if (!emptyBuffer()) { box[i] = removeCandy(); } else { --i; } // pthread_mutex_unlock(&mutex); // print the contents of the box if (i == size - 1) { // pthread_mutex_lock(&mu`tex); printBox(box, size); } pthread_mutex_unlock(&mutex); } } pthread_exit(NULL); }
int main(void) { #if defined (WIN32) WSADATA WSAData; int erreur = WSAStartup(MAKEWORD(2,2), &WSAData); #else int erreur = 0; #endif SOCKET sock; SOCKADDR_IN sin; int loop=1,i=0; unsigned short buffer[LG_BUF],repServ=0; unsigned long nb=0; client infoClient; //initialisation du buffer for(i=0;i<LG_BUF;i++) buffer[i]=0; /* Si les sockets Windows fonctionnent */ if(!erreur) { printf("Entrer l'adresse IP du serveur de communication :"); scanf("%s",buffer); emptyBuffer(); /* Création de la socket */ sock = socket(AF_INET, SOCK_STREAM, 0); /* Configuration de la connexion */ sin.sin_addr.s_addr = inet_addr(buffer); sin.sin_family = AF_INET; sin.sin_port = htons(PORT); /* Si l'on a réussi à se connecter */ if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR) { printf("Connection a %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port)); infoClient=autoten(sock); do{ printf("%s :",infoClient.login); message(buffer); nb=strlen(buffer)*2+2; nb=htonl(nb); if(send(sock, &nb, 4, 0)==SOCKET_ERROR) printf("Envoie de la chaine echouer.\n"); for(i=0;i<LG_BUF;i++) buffer[i]=htons(buffer[i]); nb=ntohl(nb); if(send(sock, buffer, nb, 0) == SOCKET_ERROR) printf("Erreur de transmission\n"); for(i=0;i<LG_BUF;i++) buffer[i]=ntohs(buffer[i]); if(!(strcmp(buffer,"exit")) || !(strcmp(buffer,"shutdown")) ) loop=0; recv(sock,&repServ,2,0); repServ=ntohs(repServ); if(repServ==1) { if(recv(sock, &nb, 4, 0) == SOCKET_ERROR) printf("Erreur de la reception de la taille\n"); nb=ntohl(nb); if(recv(sock, buffer, nb, 0) != SOCKET_ERROR){ for(i=0;i<LG_BUF;i++) buffer[i]=ntohs(buffer[i]); printf("Reponse serveur: %s\n", buffer); } else printf("Erreur de la reception de la chaine de caractere.\n"); } else if(repServ==2) { if(recv(sock, &nb, 4, 0) == SOCKET_ERROR) printf("Erreur de la reception du numero de la commande ADMIN\n"); else { nb=ntohl(nb); if(nb==COMMANDE_SEND_ADMIN){ repServ=htons(1); if(send(sock, &repServ, 2, 0)==SOCKET_ERROR) printf("Envoie du signal echouer.\n"); envoitFichier(sock,buffer); } else if(nb==COMMANDE_LS_ADMIN){ repServ=htons(1); if(send(sock, &repServ, 2, 0)==SOCKET_ERROR) printf("Envoie du signal echouer.\n"); cmdLS(sock); } else { printf("Le client ne connait pas cette commande ADMIN. Mettez a jour votre logiciel.\n"); repServ=htons(0); if(send(sock, &repServ, 2, 0)==SOCKET_ERROR) printf("Envoie du signal echouer.\n"); } if(recv(sock, &nb, 4, 0) == SOCKET_ERROR) printf("Erreur de la reception de la taille\n"); nb=ntohl(nb); if(recv(sock, buffer, nb, 0) != SOCKET_ERROR){ for(i=0;i<LG_BUF;i++) buffer[i]=ntohs(buffer[i]); printf("Reponse serveur: %s\n", buffer); } else printf("Erreur de la reception de la chaine de caractere.\n"); } } repServ=0; }while(loop); } /* sinon, on affiche "Impossible de se connecter" */ else { printf("Impossible de se connecter\n"); } /* On ferme la socket */ closesocket(sock); #if defined (WIN32) WSACleanup(); #endif } /* On attend que l'utilisateur tape sur une touche, puis on ferme */ getchar(); return EXIT_SUCCESS; }
status_t BnOMX::onTransact( uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { switch (code) { case LIVES_LOCALLY: { CHECK_INTERFACE(IOMX, data, reply); reply->writeInt32(livesLocally((pid_t)data.readInt32())); return OK; } case LIST_NODES: { CHECK_INTERFACE(IOMX, data, reply); List<ComponentInfo> list; listNodes(&list); reply->writeInt32(list.size()); for (List<ComponentInfo>::iterator it = list.begin(); it != list.end(); ++it) { ComponentInfo &cur = *it; reply->writeString8(cur.mName); reply->writeInt32(cur.mRoles.size()); for (List<String8>::iterator role_it = cur.mRoles.begin(); role_it != cur.mRoles.end(); ++role_it) { reply->writeString8(*role_it); } } return NO_ERROR; } case ALLOCATE_NODE: { CHECK_INTERFACE(IOMX, data, reply); const char *name = data.readCString(); sp<IOMXObserver> observer = interface_cast<IOMXObserver>(data.readStrongBinder()); node_id node; status_t err = allocateNode(name, observer, &node); reply->writeInt32(err); if (err == OK) { reply->writeIntPtr((intptr_t)node); } return NO_ERROR; } case FREE_NODE: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); reply->writeInt32(freeNode(node)); return NO_ERROR; } case SEND_COMMAND: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_COMMANDTYPE cmd = static_cast<OMX_COMMANDTYPE>(data.readInt32()); OMX_S32 param = data.readInt32(); reply->writeInt32(sendCommand(node, cmd, param)); return NO_ERROR; } case GET_PARAMETER: case SET_PARAMETER: case GET_CONFIG: case SET_CONFIG: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); size_t size = data.readInt32(); void *params = malloc(size); data.read(params, size); status_t err; switch (code) { case GET_PARAMETER: err = getParameter(node, index, params, size); break; case SET_PARAMETER: err = setParameter(node, index, params, size); break; case GET_CONFIG: err = getConfig(node, index, params, size); break; case SET_CONFIG: err = setConfig(node, index, params, size); break; default: TRESPASS(); } reply->writeInt32(err); if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) { reply->write(params, size); } free(params); params = NULL; return NO_ERROR; } case GET_STATE: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_STATETYPE state = OMX_StateInvalid; status_t err = getState(node, &state); reply->writeInt32(state); reply->writeInt32(err); return NO_ERROR; } case ENABLE_GRAPHIC_BUFFERS: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_U32 port_index = data.readInt32(); OMX_BOOL enable = (OMX_BOOL)data.readInt32(); status_t err = enableGraphicBuffers(node, port_index, enable); reply->writeInt32(err); return NO_ERROR; } case GET_GRAPHIC_BUFFER_USAGE: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_U32 port_index = data.readInt32(); OMX_U32 usage = 0; status_t err = getGraphicBufferUsage(node, port_index, &usage); reply->writeInt32(err); reply->writeInt32(usage); return NO_ERROR; } case USE_BUFFER: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_U32 port_index = data.readInt32(); sp<IMemory> params = interface_cast<IMemory>(data.readStrongBinder()); buffer_id buffer; status_t err = useBuffer(node, port_index, params, &buffer); reply->writeInt32(err); if (err == OK) { reply->writeIntPtr((intptr_t)buffer); } return NO_ERROR; } case USE_GRAPHIC_BUFFER: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_U32 port_index = data.readInt32(); sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); data.read(*graphicBuffer); buffer_id buffer; status_t err = useGraphicBuffer( node, port_index, graphicBuffer, &buffer); reply->writeInt32(err); if (err == OK) { reply->writeIntPtr((intptr_t)buffer); } return NO_ERROR; } case STORE_META_DATA_IN_BUFFERS: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_U32 port_index = data.readInt32(); OMX_BOOL enable = (OMX_BOOL)data.readInt32(); status_t err = storeMetaDataInBuffers(node, port_index, enable); reply->writeInt32(err); return NO_ERROR; } case ALLOC_BUFFER: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_U32 port_index = data.readInt32(); size_t size = data.readInt32(); buffer_id buffer; void *buffer_data; status_t err = allocateBuffer( node, port_index, size, &buffer, &buffer_data); reply->writeInt32(err); if (err == OK) { reply->writeIntPtr((intptr_t)buffer); reply->writeIntPtr((intptr_t)buffer_data); } return NO_ERROR; } case ALLOC_BUFFER_WITH_BACKUP: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_U32 port_index = data.readInt32(); sp<IMemory> params = interface_cast<IMemory>(data.readStrongBinder()); buffer_id buffer; status_t err = allocateBufferWithBackup( node, port_index, params, &buffer); reply->writeInt32(err); if (err == OK) { reply->writeIntPtr((intptr_t)buffer); } return NO_ERROR; } case FREE_BUFFER: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_U32 port_index = data.readInt32(); buffer_id buffer = (void*)data.readIntPtr(); reply->writeInt32(freeBuffer(node, port_index, buffer)); return NO_ERROR; } case FILL_BUFFER: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); buffer_id buffer = (void*)data.readIntPtr(); reply->writeInt32(fillBuffer(node, buffer)); return NO_ERROR; } case EMPTY_BUFFER: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); buffer_id buffer = (void*)data.readIntPtr(); OMX_U32 range_offset = data.readInt32(); OMX_U32 range_length = data.readInt32(); OMX_U32 flags = data.readInt32(); OMX_TICKS timestamp = data.readInt64(); reply->writeInt32( emptyBuffer( node, buffer, range_offset, range_length, flags, timestamp)); return NO_ERROR; } case GET_EXTENSION_INDEX: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); const char *parameter_name = data.readCString(); OMX_INDEXTYPE index; status_t err = getExtensionIndex(node, parameter_name, &index); reply->writeInt32(err); if (err == OK) { reply->writeInt32(index); } return OK; } default: return BBinder::onTransact(code, data, reply, flags); } }
/*! * \brief Get the next token in the stream */ HllTokenizer::Token HllTokenizer::getNext() { Token next; // Start out by moving past any whitespace skipCharacters(whitespace); // Check if we've reached the end of the file if(!fillBuffer(1)) { next = createToken(Token::TypeEnd, ""); return next; } // Scan through the list of literals and see if any match if(scanLiteral(literals, next)) { return next; } // If no literals matched, see if an identifier can be constructed if(std::isalpha(buffer()[0]) || buffer()[0] == '_') { size_t len = 0; while(std::isalpha(buffer()[len]) || buffer()[len] == '_') { len++; if(!fillBuffer(len + 1)) { break; } } TokenType type = TypeIdentifier; std::string string = buffer().substr(0, len); // Check if the string is a keyword for(std::string &keyword : keywords) { if(string == keyword) { type = TypeLiteral; break; } } // Construct a token out of the characters found next = createToken(type, string); emptyBuffer(len); return next; } // If an identifier couldn't be found, check for a number if(std::isdigit(buffer()[0])) { size_t len = 0; while(std::isdigit(buffer()[len])) { len++; if(!fillBuffer(len + 1)) { break; } } // Construct a token out of the characters found next = createToken(TypeNumber, buffer().substr(0, len)); emptyBuffer(len); return next; } if(buffer()[0] == '\"') { size_t len = 1; while(true) { if(!fillBuffer(len + 1)) { setError("Unterminated string literal"); return next; } if(buffer()[len] == '\"') { break; } len++; } // Construct a token out of the characters found std::string text = buffer().substr(1, len - 1); emptyBuffer(len + 1); if(evaluateEscapes(text)) { next = createToken(TypeString, text); } return next; } if(buffer()[0] == '\'') { size_t len = 1; while(true) { if(!fillBuffer(len + 1)) { setError("Unterminated character literal"); return next; } if(buffer()[len] == '\'') { break; } len++; } // Construct a token out of the characters found std::string text = buffer().substr(1, len - 1); emptyBuffer(len + 1); if(evaluateEscapes(text)) { if(text.size() == 1) { next = createToken(TypeChar, text); } else { setError("Invalid character literal"); } } return next; } // Nothing matched, log an error std::stringstream ss; ss << "Illegal symbol '" << buffer()[0] << "'"; setError(ss.str()); return next; }
// Thread execution code. int SipClient::run(void* runArg) { OsMsg* pMsg = NULL; OsStatus res; // Buffer to hold data read from the socket but not yet parsed // into incoming SIP messages. UtlString readBuffer; bool waitingToReportErr = FALSE; // controls whether to read-select on socket bool tcpOnErrWaitForSend = TRUE; int repeatedEOFs = 0; Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipClient[%s]::run start " "tcpOnErrWaitForSend-%d waitingToReportErr-%d mbTcpOnErrWaitForSend-%d repeatedEOFs-%d", mName.data(), tcpOnErrWaitForSend, waitingToReportErr, mbTcpOnErrWaitForSend, repeatedEOFs); // Wait structure: struct pollfd fds[2]; // Incoming message on the message queue (to be sent on the socket). fds[0].fd = mPipeReadingFd; // Socket ready to write (to continue sending message). // Socket ready to read (message to be received). do { assert(repeatedEOFs < 20); // The file descriptor for the socket may changemsg->getSendAddress(&fromIpAddress, &fromPort);, as OsSocket's // can be re-opened. fds[1].fd = mClientSocket->getSocketDescriptor(); // Initialize the revents members. // This may not be necessary (the man page is not clear), but // Valgrind flags 'fds[*].revents' as undefined if they aren't // initialized. fds[0].revents = 0; fds[1].revents = 0; fds[0].events = POLLIN; // only read-select on pipe // For non-blocking connect failures, don't read-select on socket if // the initial read showed an error but we have to wait to report it. if (!waitingToReportErr) { // This is the normal path. // Read the socket only if the socket is not shared. // If it is shared, the ancestral SipClient will read it. // If multiple threads attempt to read the socket, poll() may // succeed but another may read the data, leaving us to block on // read. fds[1].events = mbSharedSocket ? 0 : POLLIN; // Set wait for writing the socket if there is queued messages to // send. if (mWriteQueued) { // Wait for output on the socket to not block. fds[1].events |= POLLOUT; } } else { // just waiting to report error, ignore the socket fds[1].fd =-1; fds[1].events = 0; } // If there is residual data in the read buffer, // pretend the socket is ready to read. if (!readBuffer.isNull()) { fds[1].revents = POLLIN; } else { // Otherwise, call poll() to wait. int resPoll = poll(&fds[0], sizeof (fds) / sizeof (fds[0]), POLL_TIMEOUT); assert(resPoll >= 0 || (resPoll == -1 && errno == EINTR)); if (resPoll != 0) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipClient[%s]::run " "resPoll= %d revents: fd[0]= %x fd[1]= %x", mName.data(), resPoll, fds[0].revents, fds[1].revents ); } } if ((fds[1].revents & (POLLERR | POLLHUP)) != 0) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipClient[%s]::run " "SipMessage::poll error(%d) ", mName.data(), errno); if (OsSocket::isFramed(mClientSocket->getIpProtocol())) { Os::Logger::instance().log(FAC_SIP, PRI_ERR, "SipClient[%s]::run " "SipMessage::poll error(%d) got POLLERR | POLLHUP on UDP socket", mName.data(), errno); } else // eg. tcp socket // This client's socket is a connection-oriented protocol and the // connection has been terminated (probably by the remote end). // We must terminate the SipClient. // We drop the queued messages, but we do not report them to // SipUserAgent as failed sends. This will cause SipUserAgent to // retry the send using the same transport (rather than continuing // to the next transport), which should cause a new connection to // be made to the remote end. { // On non-blocking connect failures, we need to get the first send message // in order to successfully trigger the protocol fallback mechanism if (!tcpOnErrWaitForSend) { // Return all buffered messages with a transport error indication. emptyBuffer(TRUE); clientStopSelf(); } else { fds[1].revents &= ~(POLLERR | POLLHUP); // clear error bit if waiting waitingToReportErr = TRUE; } } } // Check for message queue messages (fds[0]) before checking the socket(fds[1]), // to make sure that we process shutdown messages promptly, even // if we would be spinning trying to service the socket. else if ((fds[0].revents & POLLIN) != 0) { // Poll finished because the pipe is ready to read. // (One byte in pipe means message available in queue.) // Only a SipClient with a derived SipClientWriteBuffer // uses the pipe in the Sip message send process // Check to see how many messages are in the queue. int numberMsgs = (getMessageQueue())->numMsgs(); Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipClient[%s]::run got pipe-select " "Number of Messages waiting: %d", mName.data(), numberMsgs); int i; char buffer[1]; for (i = 0; i < numberMsgs; i++) { // Receive the messages. res = receiveMessage((OsMsg*&) pMsg, OsTime::NO_WAIT); assert(res == OS_SUCCESS); // Normally, this is a SIP message for the write buffer. Once we have gotten // here, we are able to report any initial non-blocking connect error. mbTcpOnErrWaitForSend = FALSE; tcpOnErrWaitForSend = FALSE; Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipClient[%s]::run got pipe-select " "mbTcpOnErrWaitForSend-%d waitingToReportErr-%d mbTcpOnErrWaitForSend-%d repeatedEOFs-%d", mName.data(), mbTcpOnErrWaitForSend, waitingToReportErr, mbTcpOnErrWaitForSend, repeatedEOFs); // Read 1 byte from the pipe to clear it for this message. One byte is // inserted into the pipe for each message. assert(read(mPipeReadingFd, &buffer, 1) == 1); if (!handleMessage(*pMsg)) // process the message (from queue) { OsServerTask::handleMessage(*pMsg); } if (!pMsg->getSentFromISR()) { pMsg->releaseMsg(); // free the message } // In order to report an unframed(eg TCP) socket error to SipUserAgent dispatcher, // the error must be carried in a sip message from the client's message queue. // The message holds all the identifying information. if (waitingToReportErr) { // Return all buffered messages with a transport error indication. emptyBuffer(TRUE); clientStopSelf(); } } } // end reading msg-available-for-output-queue pipe else if ((fds[1].revents & POLLOUT) != 0) { // Poll finished because socket is ready to write. // Call method to continue writing data. writeMore(); } else if ((fds[1].revents & POLLIN) != 0) { // Poll finished because socket is ready to read. // Read message. // Must allocate a new message because SipUserAgent::dispatch will // take ownership of it. SipMessage* msg = new SipMessage; int res = msg->read(mClientSocket, HTTP_DEFAULT_SOCKET_BUFFER_SIZE, &readBuffer); if (res >= 65536) { // // This is more than the allowable size of a SIP message. Discard! // UtlString remoteHostAddress; int remoteHostPort; msg->getSendAddress(&remoteHostAddress, &remoteHostPort); OS_LOG_WARNING(FAC_SIP, "Received a SIP Message (" << res << " bytes) beyond the maximum allowable size from host " << remoteHostAddress.data() << ":" << remoteHostPort); delete msg; readBuffer.remove(0); continue; } // Use readBuffer to hold any unparsed data after the message // we read. // Note that if a message was successfully parsed, readBuffer // still contains as its prefix the characters of that message. // We save them for logging purposes below and will delete them later. UtlString remoteHostAddress; int remoteHostPort; msg->getSendAddress(&remoteHostAddress, &remoteHostPort); if (!mClientSocket->isSameHost(remoteHostAddress.data(), mLocalHostAddress.data())) { try { if (!remoteHostAddress.isNull()) { boost::asio::ip::address remoteIp = boost::asio::ip::address::from_string(remoteHostAddress.data()); if (rateLimit().isBannedAddress(remoteIp)) { delete msg; readBuffer.remove(0); continue; } rateLimit().logPacket(remoteIp, 0); } } catch(const std::exception& e) { Os::Logger::instance().log(FAC_SIP_INCOMING, PRI_CRIT, "SipClient[%s]::run rate limit exception: %s", mName.data(), e.what()); } } // Note that input was processed at this time. touch(); // // Count the CR/LF to see if this is a keep-alive // int crlfCount = 0; for (int i = 0; i < res; i++) { if (readBuffer(i) == '\r' || readBuffer(i) == '\n') { crlfCount++; } else { break; } } if (res == crlfCount) { repeatedEOFs = 0; // The 'message' was a keepalive (CR-LF or CR-LF-CR-LF). UtlString fromIpAddress; int fromPort; UtlString buffer; int bufferLen; // send one CRLF set in the reply buffer.append("\r\n"); bufferLen = buffer.length(); // Get the send address for response. msg->getSendAddress(&fromIpAddress, &fromPort); if ( !portIsValid(fromPort)) { fromPort = defaultPort(); } // Log the message at DEBUG level. // Only bother processing if the logs are enabled if ( mpSipUserAgent->isMessageLoggingEnabled() || Os::Logger::instance().willLog(FAC_SIP_INCOMING, PRI_DEBUG) ) { UtlString logMessage; logMessage.append("Read keepalive message:\n"); logMessage.append("----Local Host:"); logMessage.append(mLocalHostAddress); logMessage.append("---- Port: "); logMessage.appendNumber( portIsValid(mLocalHostPort) ? mLocalHostPort : defaultPort()); logMessage.append("----\n"); logMessage.append("----Remote Host:"); logMessage.append(fromIpAddress); logMessage.append("---- Port: "); logMessage.appendNumber( portIsValid(fromPort) ? fromPort : defaultPort()); logMessage.append("----\n"); logMessage.append(readBuffer.data(), res); UtlString messageString; logMessage.append(messageString); logMessage.append("====================END====================\n"); // Don't bother to send the message to the SipUserAgent for its internal log. // Write the message to the syslog. Os::Logger::instance().log(FAC_SIP_INCOMING, PRI_DEBUG, "%s", logMessage.data()); } // send the CR-LF response message switch (mSocketType) { case OsSocket::TCP: { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipClient[%s]::run send TCP keep-alive CR-LF response, ", mName.data()); SipClientSendMsg sendMsg(OsMsg::OS_EVENT, SipClientSendMsg::SIP_CLIENT_SEND_KEEP_ALIVE, fromIpAddress, fromPort); handleMessage(sendMsg); // add newly created keep-alive to write buffer } break; case OsSocket::UDP: { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipClient[%s]::run send UDP keep-alive CR-LF response, ", mName.data()); (dynamic_cast <OsDatagramSocket*> (mClientSocket))->write(buffer.data(), bufferLen, fromIpAddress, fromPort); } break; default: break; } // Delete the SipMessage allocated above, which is no longer needed. delete msg; // Now that logging is done, remove the parsed bytes and // remember any unparsed input for later use. readBuffer.remove(0, res); } // end keep-alive msg else if (res > 0) // got message, but not keep-alive { // Message successfully read. repeatedEOFs = 0; // Do preliminary processing of message to log it, // clean up its data, and extract any needed source address. preprocessMessage(*msg, readBuffer, res); // Dispatch the message. // dispatch() takes ownership of *msg. mpSipUserAgent->dispatch(msg); // Now that logging is done, remove the parsed bytes and // remember any unparsed input for later use. readBuffer.remove(0, res); } // end process read of >0 bytes else { // Something went wrong while reading the message. // (Possibly EOF on a connection-oriented socket.) repeatedEOFs++; // Delete the SipMessage allocated above, which is no longer needed. delete msg; Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipClient[%s]::run SipMessage::read returns %d (error(%d) or EOF), " "readBuffer = '%.1000s'", mName.data(), res, errno, readBuffer.data()); Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipClient[%s]::run error wait status " "tcpOnErrWaitForSend-%d waitingToReportErr-%d " "mbTcpOnErrWaitForSend-%d repeatedEOFs-%d " "protocol %d framed %d", mName.data(), tcpOnErrWaitForSend, waitingToReportErr, mbTcpOnErrWaitForSend, repeatedEOFs, mClientSocket->getIpProtocol(), OsSocket::isFramed(mClientSocket->getIpProtocol())); // If the socket is not framed (is connection-oriented), // we need to abort the connection and post a message // :TODO: This doesn't work right for framed connection-oriented // protocols (like SCTP), but OsSocket doesn't have an EOF-query // method -- we need to close all connection-oriented // sockets as well in case it was an EOF. // Define a virtual function that returns the correct bit. if (!OsSocket::isFramed(mClientSocket->getIpProtocol())) { // On non-blocking connect failures, we need to get the first send message // in order to successfully trigger the protocol fallback mechanism if (!tcpOnErrWaitForSend) { // Return all buffered messages with a transport error indication. emptyBuffer(TRUE); clientStopSelf(); } else { fds[1].revents &= ~(POLLERR | POLLHUP); // clear error bit if waiting waitingToReportErr = TRUE; } } // Delete the data read so far, which will not have been // deleted by HttpMessage::read. readBuffer.remove(0); } } // end POLLIN reading socket } while (isStarted()); return 0; // and then exit }
status_t BnOMX::onTransact( uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { switch (code) { case LIST_NODES: { CHECK_INTERFACE(IOMX, data, reply); List<String8> list; listNodes(&list); reply->writeInt32(list.size()); for (List<String8>::iterator it = list.begin(); it != list.end(); ++it) { reply->writeString8(*it); } return NO_ERROR; } case ALLOCATE_NODE: { CHECK_INTERFACE(IOMX, data, reply); const char *name = data.readCString(); sp<IOMXObserver> observer = interface_cast<IOMXObserver>(data.readStrongBinder()); node_id node; status_t err = allocateNode(name, observer, &node); reply->writeInt32(err); if (err == OK) { reply->writeIntPtr((intptr_t)node); } return NO_ERROR; } case FREE_NODE: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); reply->writeInt32(freeNode(node)); return NO_ERROR; } case SEND_COMMAND: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_COMMANDTYPE cmd = static_cast<OMX_COMMANDTYPE>(data.readInt32()); OMX_S32 param = data.readInt32(); reply->writeInt32(sendCommand(node, cmd, param)); return NO_ERROR; } case GET_PARAMETER: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); size_t size = data.readInt32(); // XXX I am not happy with this but Parcel::readInplace didn't work. void *params = malloc(size); data.read(params, size); status_t err = getParameter(node, index, params, size); reply->writeInt32(err); if (err == OK) { reply->write(params, size); } free(params); params = NULL; return NO_ERROR; } case SET_PARAMETER: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); size_t size = data.readInt32(); void *params = const_cast<void *>(data.readInplace(size)); reply->writeInt32(setParameter(node, index, params, size)); return NO_ERROR; } case GET_CONFIG: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); size_t size = data.readInt32(); // XXX I am not happy with this but Parcel::readInplace didn't work. void *params = malloc(size); data.read(params, size); status_t err = getConfig(node, index, params, size); reply->writeInt32(err); if (err == OK) { reply->write(params, size); } free(params); params = NULL; return NO_ERROR; } case SET_CONFIG: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); size_t size = data.readInt32(); void *params = const_cast<void *>(data.readInplace(size)); reply->writeInt32(setConfig(node, index, params, size)); return NO_ERROR; } case USE_BUFFER: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_U32 port_index = data.readInt32(); sp<IMemory> params = interface_cast<IMemory>(data.readStrongBinder()); buffer_id buffer; status_t err = useBuffer(node, port_index, params, &buffer); reply->writeInt32(err); if (err == OK) { reply->writeIntPtr((intptr_t)buffer); } return NO_ERROR; } case ALLOC_BUFFER: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_U32 port_index = data.readInt32(); size_t size = data.readInt32(); buffer_id buffer; status_t err = allocateBuffer(node, port_index, size, &buffer); reply->writeInt32(err); if (err == OK) { reply->writeIntPtr((intptr_t)buffer); } return NO_ERROR; } case ALLOC_BUFFER_WITH_BACKUP: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_U32 port_index = data.readInt32(); sp<IMemory> params = interface_cast<IMemory>(data.readStrongBinder()); buffer_id buffer; status_t err = allocateBufferWithBackup( node, port_index, params, &buffer); reply->writeInt32(err); if (err == OK) { reply->writeIntPtr((intptr_t)buffer); } return NO_ERROR; } case FREE_BUFFER: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); OMX_U32 port_index = data.readInt32(); buffer_id buffer = (void*)data.readIntPtr(); reply->writeInt32(freeBuffer(node, port_index, buffer)); return NO_ERROR; } case FILL_BUFFER: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); buffer_id buffer = (void*)data.readIntPtr(); reply->writeInt32(fillBuffer(node, buffer)); return NO_ERROR; } case EMPTY_BUFFER: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); buffer_id buffer = (void*)data.readIntPtr(); OMX_U32 range_offset = data.readInt32(); OMX_U32 range_length = data.readInt32(); OMX_U32 flags = data.readInt32(); OMX_TICKS timestamp = data.readInt64(); reply->writeInt32( emptyBuffer( node, buffer, range_offset, range_length, flags, timestamp)); return NO_ERROR; } case GET_EXTENSION_INDEX: { CHECK_INTERFACE(IOMX, data, reply); node_id node = (void*)data.readIntPtr(); const char *parameter_name = data.readCString(); OMX_INDEXTYPE index; status_t err = getExtensionIndex(node, parameter_name, &index); reply->writeInt32(err); if (err == OK) { reply->writeInt32(index); } return OK; } case CREATE_RENDERER: { CHECK_INTERFACE(IOMX, data, reply); sp<ISurface> isurface = interface_cast<ISurface>(data.readStrongBinder()); const char *componentName = data.readCString(); OMX_COLOR_FORMATTYPE colorFormat = static_cast<OMX_COLOR_FORMATTYPE>(data.readInt32()); size_t encodedWidth = (size_t)data.readInt32(); size_t encodedHeight = (size_t)data.readInt32(); size_t displayWidth = (size_t)data.readInt32(); size_t displayHeight = (size_t)data.readInt32(); sp<IOMXRenderer> renderer = createRenderer(isurface, componentName, colorFormat, encodedWidth, encodedHeight, displayWidth, displayHeight); reply->writeStrongBinder(renderer->asBinder()); return OK; } default: return BBinder::onTransact(code, data, reply, flags); } }
void EliminateDuplicates(char *infile, unsigned char field, block_t *buffer, unsigned int nmem_blocks, char *outfile, unsigned int *nunique, unsigned int *nios) { if (nmem_blocks < 3) { printf("At least 3 blocks are required."); return; } // empties the buffer emptyBuffer(buffer, nmem_blocks); uint memSize = nmem_blocks - 1; *nunique = 0; *nios = 0; uint fileSize = getSize(infile); // if the relation fits on the buffer and leaves one block free for output, // loads it to the buffer and eliminates duplicates using hashing if (fileSize <= memSize) { hashElimination(infile, fileSize, outfile, field, buffer, memSize, nunique, nios); } else if (fileSize == nmem_blocks) { // if the relation completely fits the buffer, calls useFirstBlock useFirstBlock(infile, outfile, field, buffer, nmem_blocks, nunique, nios); } else { // if the relation is larger than the buffer, then sort it using mergesort, // BUT during the final merging (during last pass) write to the output // only one time each value // the following code is similar to that of MergeSort: int input, output; char tmpFile1[] = ".ed1"; char tmpFile2[] = ".ed2"; uint fullSegments = fileSize / nmem_blocks; uint remainingSegment = fileSize % nmem_blocks; input = open(infile, O_RDONLY, S_IRWXU); output = open(tmpFile1, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); uint nSortedSegs = 0; uint segmentSize = nmem_blocks; for (uint i = 0; i <= fullSegments; i++) { if (fullSegments == i) { if (remainingSegment != 0) { segmentSize = remainingSegment; } else { break; } } (*nios) += readBlocks(input, buffer, segmentSize); if (sortBuffer(buffer, segmentSize, field)) { (*nios) += writeBlocks(output, buffer, segmentSize); nSortedSegs += 1; } } close(input); close(output); segmentSize = nmem_blocks; uint lastSegmentSize; if (remainingSegment == 0) { lastSegmentSize = nmem_blocks; } else { lastSegmentSize = remainingSegment; } buffer[memSize].valid = true; while (nSortedSegs != 1) { input = open(tmpFile1, O_RDONLY, S_IRWXU); output = open(tmpFile2, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); uint newSortedSegs = 0; uint fullMerges = nSortedSegs / memSize; uint lastMergeSegs = nSortedSegs % memSize; uint *blocksLeft = (uint*) malloc(memSize * sizeof (uint)); uint segsToMerge = memSize; bool lastMerge = false; for (uint mergeCounter = 0; mergeCounter <= fullMerges; mergeCounter++) { uint firstSegOffset = mergeCounter * memSize * segmentSize; if (mergeCounter == fullMerges - 1 && lastMergeSegs == 0) { lastMerge = true; } else if (mergeCounter == fullMerges) { if (lastMergeSegs != 0) { segsToMerge = lastMergeSegs; lastMerge = true; } else { break; } } for (uint i = 0; i < segsToMerge; i++) { (*nios) += preadBlocks(input, buffer + i, (firstSegOffset + i * segmentSize), 1); blocksLeft[i] = segmentSize - 1; } if (lastMerge) { blocksLeft[segsToMerge - 1] = lastSegmentSize - 1; } (*nios) += mergeElimination(input, output, buffer, memSize, segsToMerge, blocksLeft, segmentSize, firstSegOffset, field, nSortedSegs <= memSize, lastMerge, nunique); newSortedSegs += 1; } free(blocksLeft); if (lastMergeSegs == 0) { lastSegmentSize = (memSize - 1) * segmentSize + lastSegmentSize; } else { lastSegmentSize = (lastMergeSegs - 1) * segmentSize + lastSegmentSize; } segmentSize *= memSize; nSortedSegs = newSortedSegs; close(input); close(output); char tmp = tmpFile1[3]; tmpFile1[3] = tmpFile2[3]; tmpFile2[3] = tmp; } rename(tmpFile1, outfile); remove(tmpFile2); } }
/// Write as much of the buffered messages as can be written. // Executed by the thread. void SipClientWriteBuffer::writeMore() { // 'exit_loop' will be set to TRUE if an attempt to write does // not write any bytes, and we will then return. UtlBoolean exit_loop = FALSE; while (mWriteQueued && !exit_loop) { if (mWritePointer >= mWriteString.length()) { // We have written all of the first message. // Pop it and set up to write the next message. delete mWriteBuffer.get(); mWriteString.remove(0); mWritePointer = 0; mWriteQueued = ! mWriteBuffer.isEmpty(); if (mWriteQueued) { // get the message on the head of the queue, and figure out which kind it is UtlContainable* nextMsg = mWriteBuffer.first(); SipMessage* sipMsg; UtlString* keepAliveMsg; if ((sipMsg = dynamic_cast<SipMessage*>(nextMsg))) // a SIP message { ssize_t length; sipMsg->getBytes(&mWriteString, &length); } else if ((keepAliveMsg = dynamic_cast<UtlString*>(nextMsg))) // a keepalive CRLF { mWriteString.append(*keepAliveMsg); } else { Os::Logger::instance().log(FAC_SIP, PRI_CRIT, "SipClientWriteBuffer[%s]::writeMore " "unrecognized message type in queue", mName.data()); assert(false); delete mWriteBuffer.get(); mWriteQueued = mWriteBuffer.isEmpty(); } } } else { // Some portion of the first message remains to be written. // If the socket has failed, attempt to reconnect it. // :NOTE: OsConnectionSocket::reconnect isn't implemented. if (!mClientSocket->isOk()) { mClientSocket->reconnect(); } // Calculate the length to write. int length = mWriteString.length() - mWritePointer; // ret is the value returned from write attempt. // -1 means an error was seen. int ret; if (mClientSocket->isOk()) { // Write what we can. ret = mClientSocket->write(mWriteString.data() + mWritePointer, length); // Theoretically, ret > 0, since the socket is ready for writing, // but it appears that that ret can be 0. } else { // Record the error. ret = -1; // Set a special errno value, which hopefully is not a real value. errno = 1000; } if (ret > 0) { // We successfully sent some data, perhaps all of the // remainder of the first message. // Update the last-activity time. touch(); // Update the state variables. mWritePointer += ret; } else if (ret == 0) { // No data sent, even though (in our caller) poll() // reported the socket was ready to write. exit_loop = TRUE; } else { // Error while writing. Os::Logger::instance().log(FAC_SIP, PRI_ERR, "SipClientWriteBuffer[%s]::writeMore " "OsSocket::write() returned %d, errno = %d", getName().data(), ret, errno); // Return all buffered messages with a transport error indication. emptyBuffer(TRUE); // Because TCP is a connection protocol, we know that we cannot // send successfully any more and so should shut down this client. clientStopSelf(); // Exit the loop so handleMessage() can process the stop request. exit_loop = TRUE; } } } }
/// Insert a message into the buffer. void SipClientWriteBuffer::insertMessage(SipMessage* message) { UtlBoolean wasEmpty = mWriteBuffer.isEmpty(); // // Let all outbound processors know about this message // if (message && mpSipUserAgent && mClientSocket && mClientSocket->isOk()) { UtlString remoteHostAddress; int remotePort; mClientSocket->getRemoteHostIp(&remoteHostAddress, &remotePort); // We are about to post a message that will cause the // SIP message to be sent. Notify the user agent so // that it can offer the message to all its registered // output processors. ssize_t msgLength = 0; UtlString msgText; message->getBytes(&msgText, &msgLength, true); if (msgLength) { system_tap_sip_tx( mLocalHostAddress.data(), portIsValid(mLocalHostPort) ? mLocalHostPort : defaultPort(), remoteHostAddress.data(), remotePort == PORT_NONE ? defaultPort() : remotePort, msgText.data(), msgLength); mpSipUserAgent->executeAllBufferedSipOutputProcessors(*message, remoteHostAddress.data(), remotePort == PORT_NONE ? defaultPort() : remotePort); } } // Add the message to the queue. mWriteBuffer.insert(message); // If the buffer was empty, we need to set mWriteString and // mWritePointer. if (wasEmpty) { ssize_t length; message->getBytes(&mWriteString, &length); mWritePointer = 0; } mWriteQueued = TRUE; // Check to see if our internal queue is getting too big, which means // that the socket has been blocked for writing for a long time. // We use the message queue length of this task as the limit, since // both queues are affected by the same traffic load factors. if (mWriteBuffer.entries() > (size_t) (getMessageQueue()->maxMsgs())) { // If so, abort all unsent messages and terminate this client (so // as to clear any state of the socket). Os::Logger::instance().log(FAC_SIP, PRI_ERR, "SipClientWriteBuffer[%s]::insertMessage " "mWriteBuffer has '%d' entries, exceeding the limit of maxMsgs '%d'", getName().data(), (int) mWriteBuffer.entries(), getMessageQueue()->maxMsgs()); emptyBuffer(TRUE); clientStopSelf(); } }