Example #1
0
void OSSSIP::sendRequestDirect(const SIPMessage::Ptr& pRequest,
  const OSS::IPAddress& localAddress,
  const OSS::IPAddress& remoteAddress)
{

  std::string transport;
  if (SIPVia::msgGetTopViaTransport(pRequest.get(), transport))
  {
    std::string transportId;
    pRequest->getProperty("transport-id", transportId);
    if (transportId.empty())
      transportId="0";
    OSS_LOG_DEBUG("Sending request directly protocol=" << transport << " id=" << transportId);
    SIPTransportSession::Ptr client = _fsmDispatch.transport().createClientTransport(localAddress, remoteAddress, transport, transportId);
    if (client)
      client->writeMessage(pRequest, remoteAddress.toString(), OSS::string_from_number(remoteAddress.getPort()));
    else
      OSS_LOG_ERROR("OSSSIP::sendRequestDirect failed - Unable to create client transport");
  }
  else
  {
    OSS_LOG_ERROR("OSSSIP::sendRequestDirect failed - Unable to determine transport protocol.")
  }
}
void SIPTransaction::sendResponse(
  const SIPMessage::Ptr& pResponse,
  const OSS::IPAddress& sendAddress)
{
  if (!pResponse->isResponse())
    throw OSS::SIP::SIPException("Sending a REQUEST using sendResponse() is illegal!");

  SIPTransaction::Ptr pParent = getParent();

  if (!_transport && isParent())
    throw OSS::SIP::SIPException("Transport Not Ready!");
  else if (!isParent() && pParent)
    _transport = pParent->_transport;

  if (_sendAddress.getPort() == 0)
    _sendAddress = sendAddress;

  SIPTransaction::Ptr pBranch = findBranch(pResponse);

  if (pBranch)
  {
    pBranch->sendResponse(pResponse, sendAddress);
    return;
  }
  else
  {
    //
    // No branch is found.  This instance will handle the response
    //
    if (_transport && _transport->isReliableTransport())
    {
      if (_transport->writeKeepAlive())
      {
        writeMessage(pResponse);
      }
      else
      {
        //
        // Keep-alive failed so create a new transport
        //
        if (_localAddress.isValid() && _sendAddress.isValid())
        {
          //
          // According to RFC 3261, if there is any transport failure, we must try to
          // re-estabish a connectoin to the via sentby parameter instead
          //
          std::string transport;
          if (SIPVia::msgGetTopViaTransport(pResponse.get(), transport))
          {
            _transport = _transportService->createClientTransport(_localAddress, _sendAddress, transport);
            writeMessage(pResponse);
          }
        }
        else
        {
          OSS_LOG_ERROR("SIPTransaction::sendResponse - Unable to re-establish transport to send response.");
        }

      }
    }
    else if (_transport)
    {
      //
      // This is UDP so a keep-alive check won't do us any good
      //
      writeMessage(pResponse, _sendAddress);
    }
    else
    {
      OSS_LOG_ERROR("SIPTransaction::sendResponse - Transport is NULL.");
    }
  }
}
void SIPTransaction::sendRequest(
    const SIPMessage::Ptr& pRequest,
    const OSS::IPAddress& localAddress,
    const OSS::IPAddress& remoteAddress,
    SIPTransaction::Callback callback)
{
  OSS::mutex_lock lock(_mutex);

  if (!pRequest->isRequest())
  {
    throw OSS::SIP::SIPException("Sending a REQUEST using sendRequest() is illegal!");
  }

  if (!_pInitialRequest)
  {
    _pInitialRequest = pRequest;
    if (_logId.empty())
      _logId = pRequest->createContextId(true);
    
    if (SIPXOR::isEnabled() && !_isXOREncrypted)
    {
      std::string isXOR;
      _isXOREncrypted = pRequest->getProperty("xor", isXOR) && isXOR == "1";
    }
  }

  if (!_responseTU)
    _responseTU = callback;

  if (_localAddress.getPort() == 0)
    _localAddress = localAddress;

  if (_remoteAddress.getPort() == 0)
    _remoteAddress = remoteAddress;

  if (!_transport)
  {
    if (!_transportService)
      throw OSS::SIP::SIPException("Transport Not Ready!");


    std::string transport;
    if (pRequest->getProperty("target-transport", transport))
    {
      std::string transportId;
      pRequest->getProperty("transport-id", transportId);
      _transport = _transportService->createClientTransport(localAddress, remoteAddress, transport, transportId);
    }else if (SIPVia::msgGetTopViaTransport(pRequest.get(), transport))
    {
      _transport = _transportService->createClientTransport(localAddress, remoteAddress, transport);
    }
    if (!_transport)
      throw OSS::SIP::SIPException("Unable to create transport!");
  }

  if (_transport->isReliableTransport())
  {
    writeMessage(pRequest);
  }
  else
  {
    writeMessage(pRequest, remoteAddress);
  }
}