// Queue a message to be sent to the specified address and port. UtlBoolean SipClient::sendTo(SipMessage& message, const char* address, int port) { UtlBoolean sendOk; if (mClientSocket) { // If port == PORT_NONE, get the correct default port for this // transport method. int portToSendTo = ( port == PORT_NONE ? defaultPort() : port ); // 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(), address, portToSendTo, msgText.data(), msgLength); mpSipUserAgent->executeAllSipOutputProcessors( message, address, portToSendTo ); } // Create message to queue. SipClientSendMsg sendMsg(OsMsg::OS_EVENT, SipClientSendMsg::SIP_CLIENT_SEND, message, address, portToSendTo ); // Post the message to the task's queue. OsStatus status = postMessage(sendMsg, OsTime::NO_WAIT); sendOk = status == OS_SUCCESS; if (!sendOk) { Os::Logger::instance().log(FAC_SIP, PRI_ERR, "SipClient[%s]::sendTo attempt to post message failed", mName.data()); } } else { Os::Logger::instance().log(FAC_SIP, PRI_CRIT, "SipClient[%s]::sendTo called for client without socket", mName.data() ); sendOk = FALSE; } return sendOk; }
/// 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(); } }