예제 #1
0
void Negotiating::FailureResponse( DialogTracker& impl, SipMessage& response, const char* address, int port ) const
{
   int seqNum;
   UtlString seqMethod;
   
   if( response.getCSeqField( &seqNum, &seqMethod ) )
   {
      if( seqMethod.compareTo( SIP_INVITE_METHOD ) == 0 )
      {
         // session negotiation failed.  Deallocate all the tentative
         // media relays tentatively allocated to handle the media
         // sessions that just failed.
         impl.deallocateAndClearAllMediaRelaySessions( true, true, false );         

         if( !impl.getDialogEstablishedFlag() )
         {
            // this is a final failure response to a dialog-forming INVITE.  That 
            // event marks the end of the dialog hence, we do not need to continue
            // to track it.
            ChangeState( impl, impl.pMoribund );
         }
         else
         {
            // the renegotiation failed but the dialog is still active. Go back to state where
            // we wait for an incoming INVITE.
            ChangeState( impl, impl.pWaitingForInvite );
         }
      }
      else
      {
         OsSysLog::add(FAC_NAT,PRI_DEBUG,"'%s:%s' - Received unexpected successful response for %s request",
               impl.name(), impl.GetCurrentState()->name(), seqMethod.data() );    
      }
   }   
}
예제 #2
0
void HomerProxyPlugin::handleOutgoing(SipMessage& message, const char* address, int port)
{
  struct timeval now;
  gettimeofday(&now, NULL);

  std::string data = message.getString();

  //OS_LOG_ERROR(FAC_SIP, "LENGTH: " << data.size() << " - " << data);

  StateQueueMessage msg;
  msg.setType(StateQueueMessage::Data);
  msg.set("Outgoing", 1);
  msg.set("IpProtoId", (int)HEPMessage::TCP);
  msg.set("Ip4SrcAddress", _localHost.c_str());
  msg.set("Ip4DestAddress", address);
  msg.set("SrcPort", _localPort);
  msg.set("DestPort", port);
  msg.set("TimeStamp", (double)now.tv_sec);
  msg.set("TimeStampMicroOffset", (double)now.tv_usec);
  msg.set("Data", data.c_str());

  std::string msgData = msg.data();
  bool noresponse = true;
  _sqa.publish("CAP", msgData.c_str(), noresponse);
}
void MyInviteSessionHandler::onConnected(ClientInviteSessionHandle cis, const SipMessage& msg) 
{
   mDialInstance.onConnected(cis);

   SdpContents *sdp = (SdpContents*)msg.getContents();
   cis->provideAnswer(*sdp);
}
예제 #4
0
/// Add identity info to a message.
bool SipXauthIdentity::insert(SipMessage & message,
                              HeaderName headerName,
                              const OsDateTime * timestamp)
{
   // Don't proceed if the encapsulated identity is invalid
   if (!mIsValidIdentity)
   {
      Os::Logger::instance().log(FAC_SIP, PRI_CRIT,
                    "SipXauthIdentity::insert: "
                    "encapsulated SipXauthIdentity is invalid");
   }
   else
   {
      // make sure no existing identity in the message
      remove(message, headerName);

      // set Call-Id and from-tag for the signature calculation
      UtlString callId;
      UtlString fromTag;
      Url fromUrl;
      message.getCallIdField(&callId);
      message.getFromUrl(fromUrl);
      fromUrl.getFieldParameter("tag", fromTag);

      OsDateTime now;
      OsDateTime::getCurTime(now);
      if (NULL==timestamp)
      {
         timestamp = &now;
      }

      UtlString value;
      encode(value, callId, fromTag, *timestamp);

      // Insert displayName if it is an P-Asserted-Identity header.
      if (headerName == SipXauthIdentity::PAssertedIdentityHeaderName)
      {
          UtlString displayName;
          fromUrl.getDisplayName(displayName);
          value.prepend(displayName.data());
      }

      message.addHeaderField(headerName, value.data());
   }

   return mIsValidIdentity;
}
예제 #5
0
/// Remove identity info from a message.
void SipXauthIdentity::remove(SipMessage & message, HeaderName headerName)
{
   int idHeaderCount = message.getCountHeaderFields(headerName);
   if (idHeaderCount>0)
   {
      UtlString rUri;
      message.getRequestUri(&rUri);
      Os::Logger::instance().log(FAC_SIP, PRI_WARNING,
                    "SipXauthIdentity::remove"
                    ": '%d' occurrances of %s in request to '%s'",
                    idHeaderCount, headerName, rUri.data());
      for (int i = idHeaderCount - 1;i>=0;i--)
      {
         message.removeHeader(headerName, i);
      }
   }
}
예제 #6
0
UtlBoolean SipUserAgentStateless::send(SipMessage& message,
                                       OsMsgQ* responseListener,
                                       void* responseListenerData)
{
    UtlString sendAddress;
    UtlString sendProtocol;
    int sendPort;

    if(message.isResponse())
    {
        int receivedPort;
        UtlBoolean receivedSet;
        UtlBoolean maddrSet;
        UtlBoolean receivedPortSet;
        message.getLastVia(&sendAddress, &sendPort, &sendProtocol, &receivedPort,
                           &receivedSet, &maddrSet, &receivedPortSet);
        if(receivedPortSet && portIsValid(receivedPort))
        {
            sendPort = receivedPort;
        }
    }
    else
    {
        UtlString uriString;
        message.getRequestUri(&uriString);
        Url uri(uriString);
        uri.getHostAddress(sendAddress);

        // Check for maddr
        UtlString maddr;
        uri.getUrlParameter("maddr", maddr);
        if(!maddr.isNull())
        {
            // Use maddr if present
            sendAddress = maddr;
        }

        uri.getUrlParameter("transport", sendProtocol);
        sendPort = uri.getHostPort();
    }

    UtlBoolean sendOk =
        sendTo(message, sendAddress.data(), sendProtocol.data(), sendPort);

    return(sendOk);
}
예제 #7
0
int SubscribeServerThread::removeErrorSubscription (const SipMessage& sipMessage )
{
    int returnStatus = STATUS_SUCCESS;
    UtlString callId;
    UtlString to;
    UtlString from;
    sipMessage.getToField(&to);
    sipMessage.getFromField(&from);
    sipMessage.getCallIdField(&callId);

    OsSysLog::add(FAC_SIP, PRI_WARNING,
                  "SubscribeServerThread::removeErrorSubscription %s",
                  callId.data());

    removeErrorRow(from, to, callId);
    return returnStatus;
}
예제 #8
0
// Process a MESSAGE request, which is used to trigger debugging actions.
void AppearanceAgentTask::handleMessageRequest(const SipMessage& msg)
{
   // Extract the user-part of the request-URI, which should tell us what
   // to do.
   UtlString user;
   msg.getUri(NULL, NULL, NULL, &user);

   // Construct the response.
   SipMessage response;

   if (user.compareTo(dumpStateUri) == 0)
   {
      // dumpStateUri is used to request to dump the Appearance Agent state into the log.
      debugDumpState(msg);
      response.setOkResponseData(&msg, NULL);
   }
   else
   {
      response.setInterfaceIpPort(msg.getInterfaceIp(), msg.getInterfacePort());
      response.setResponseData(&msg, SIP_NOT_FOUND_CODE, SIP_NOT_FOUND_TEXT);
   }

   // Send the response.
   getAppearanceAgent()->getServerUserAgent().send(response);
}
예제 #9
0
// 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;
}
예제 #10
0
UtlString SessionContext::getDiscriminatingTagValue( const SipMessage& message, bool bFromCallerToCallee ) const
{
   UtlString discriminatingTag;
   Url tempUrl;

   if( bFromCallerToCallee )
   {
      // caller-to-callee uses To-tag to distinguish between dialogs
      message.getToUrl( tempUrl );
   }
   else
   {
      // callee-to-caller uses From-tag to distinguish between dialogs
      message.getFromUrl( tempUrl );
   }
   tempUrl.getFieldParameter( "tag", discriminatingTag );
   return discriminatingTag;
}
예제 #11
0
AuthPlugin::AuthResult
SubscriptionAuth::authorizeAndModify(const UtlString& id,    /**< The authenticated identity of the
                                                              *   request originator, if any (the null
                                                              *   string if not).
                                                              *   This is in the form of a SIP uri
                                                              *   identity value as used in the
                                                              *   credentials database (user@domain)
                                                              *   without the scheme or any parameters.
                                                              */
                                    const Url&  requestUri, ///< parsed target Uri
                                    RouteState& routeState, ///< the state for this request.
                                    const UtlString& method,///< the request method
                                    AuthResult  priorResult,///< results from earlier plugins.
                                    SipMessage& request,    ///< see AuthPlugin wrt modifying
                                    bool bSpiralingRequest, ///< request spiraling indication
                                    UtlString&  reason      ///< rejection reason
                                    )
{
   AuthResult result = CONTINUE;
   UtlString eventField;
   UtlString targetUser;
   requestUri.getUserId(targetUser);

   if (CONTINUE == priorResult &&
       id.isNull() &&
       method.compareTo(SIP_SUBSCRIBE_METHOD) == 0 &&
       request.getEventField(eventField) &&
       mEventPackagesRequiringAuthentication.contains( &eventField ) &&
       !isTargetExemptedFromAuthentication(targetUser))
   {
      // we do not have an authenticated ID for the request - challenge it.
      // get the call-id to use in logging
      UtlString callId;
      request.getCallIdField(&callId);

      OsSysLog::add(FAC_AUTH, PRI_INFO, "SubscriptionAuth[%s]::authorizeAndModify "
                    "challenging subscription for dialog event package '%s' (call id = '%s')",
                    mInstanceName.data(), eventField.data(), callId.data()
                    );
      result = DENY;
      reason = "Authentication Required to Subscribe to " + eventField;
   }
   return result;
}
예제 #12
0
UtlBoolean SipDialogMgr::setNextLocalTransactionInfo(SipMessage& request,
                                                     const char* method,
                                                     const char* dialogHandle)
{
    UtlBoolean requestSet = FALSE;
    UtlString dialogHandleString(dialogHandle ? dialogHandle : "");
    if(dialogHandleString.isNull())
    {
        request.getDialogHandle(dialogHandleString);
    }

    lock();
    SipDialog* dialog = findDialog(dialogHandleString,
                                   FALSE, // If established only want exact match dialogs
                                   TRUE); // If message is from a prior transaction
                                          // when the dialog was in an early state
                                          // allow it to match an established
                                          // dialog
    if(dialog)
    {
        dialog->setRequestData(request, method);
        requestSet = TRUE;

#ifdef TEST_PRINT
        UtlString dialogDump;
        dialog->toString(dialogDump);
        OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMgr::setNextLocalTransactionInfo dialog: '%s'",
                      dialogDump.data());
#endif
    }
    else
    {
       OsSysLog::add(FAC_SIP, PRI_ERR, "SipDialogMgr::setNextLocalTransactionInfo dialog not found for handle '%s'",
                     dialogHandle);

       if (OsSysLog::willLog(FAC_SIP, PRI_DEBUG))
       {
          SipDialog* dialog;
          UtlHashBagIterator iterator(mDialogs);
          
          while ((dialog = (SipDialog*) iterator()))
          {
             UtlString callId, localTag, remoteTag;
             dialog->getCallId(callId);
             dialog->getLocalTag(localTag);
             dialog->getRemoteTag(remoteTag);
             OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMgr::setNextLocalTransactionInfo dialog call-id = '%s', local tag = '%s', remote tag = '%s'",
                           callId.data(), localTag.data(), remoteTag.data());
          }
       }
    }

    unlock();

    return(requestSet);
}
예제 #13
0
UtlBoolean RlsSubscribePolicy::isAuthorized(const SipMessage& subscribeRequest,
                                            SipMessage& subscribeResponse)
{
   // SUBSCRIBE is authorized if "eventlist" is supported.
   UtlBoolean ret = subscribeRequest.isInSupportedField(SIP_EVENTLIST_EXTENSION);

   // If we return false, we must construct a failure response.
   if (!ret)
   {
      // 421 Extension Required
      // Require: eventlist"
      subscribeResponse.setResponseData(&subscribeRequest,
                                        SIP_EXTENSION_REQUIRED_CODE,
                                        SIP_EXTENSION_REQUIRED_TEXT);
      subscribeResponse.addRequireExtension(SIP_EVENTLIST_EXTENSION);
   }

   return ret;
}
예제 #14
0
/// Normalize identity info in a message.
void SipXauthIdentity::normalize(SipMessage & message,  HeaderName headerName)
{
   int idHeaderCount = message.getCountHeaderFields(headerName);
   if (idHeaderCount>1)
   {
      UtlString rUri;
      message.getRequestUri(&rUri);
      Os::Logger::instance().log(FAC_SIP, PRI_WARNING,
                    "SipXauthIdentity::remove"
                    ": '%d' occurrances of SipXauthIdentity in request to '%s'",
                    idHeaderCount, rUri.data());
      // Remove all BUT the last header
      for (int i = idHeaderCount - 2;i>=0;i--)
      {
         //message.removeHeader(SipXauthIdentity::AuthIdentityHeaderName, i);
         message.removeHeader(headerName, i);
      }
   }
}
예제 #15
0
enum SipDialogMgr::transactionSequence
    SipDialogMgr::isNewRemoteTransaction(const SipMessage& message)
{
    enum transactionSequence ordering;
    UtlString handle;
    message.getDialogHandle(handle);

    UtlString callId;
    UtlString fromTag;
    UtlString toTag;
    SipDialog::parseHandle(handle, callId, fromTag, toTag);

    lock();
    // Looking for any dialog that matches this handle
    SipDialog* dialog = findDialog(handle,
                                   TRUE, // if established, match early dialog
                                   TRUE); // if early, match established dialog

    if (dialog && 
        dialog->isTransactionRemotelyInitiated(callId, fromTag, toTag))
    {
       int messageCSeq;
       message.getCSeqField(&messageCSeq, NULL);
       int lastRemoteCSeq = dialog->getLastRemoteCseq();
       ordering =
          messageCSeq < lastRemoteCSeq ? OUT_OF_ORDER :
          /** If this message was an exact duplicate of a previous message
           *  (with the same CSeq and branch parameter), it would have been
           *  absorbed earlier in processing.  So we know the branch parameter
           *  is different without having to remember the previous value.
           */
          messageCSeq == lastRemoteCSeq ? LOOPED :
          IN_ORDER;
    }
    else
    {
       ordering = NO_DIALOG;
    }

    unlock();
    
    return ordering;
}
예제 #16
0
UtlBoolean SipSubscriptionMgr::getNotifyDialogInfo(const UtlString& subscribeDialogHandle,
                                                   SipMessage& notifyRequest)
{
    UtlBoolean notifyInfoSet = FALSE;
    lock();
    SubscriptionServerState* state = (SubscriptionServerState*)
        mSubscriptionStatesByDialogHandle.find(&subscribeDialogHandle);

    if (state)
    {
        notifyInfoSet = mDialogMgr.setNextLocalTransactionInfo(notifyRequest, 
                                                               SIP_NOTIFY_METHOD,
                                                               subscribeDialogHandle);

        // Set the event header, if we know what it is.
        if (state->mpLastSubscribeRequest)
        {
            UtlString eventHeader;
            state->mpLastSubscribeRequest->getEventField(eventHeader);
            notifyRequest.setEventField(eventHeader);
        }

        // Set the subscription-state header.
        long expires =
           state->mExpirationDate - OsDateTime::getSecsSinceEpoch();
        char buffer[30];
        sprintf(buffer,
                (expires > 0 ? "active;expires=%ld" : "terminated;reason=timeout"),
                expires);
        notifyRequest.setHeaderValue(SIP_SUBSCRIPTION_STATE_FIELD, buffer, 0);
    }
    else
    {
       OsSysLog::add(FAC_SIP, PRI_ERR,
                     "SipSubscriptionMgr::getNotifyDialogInfo No subscription state found for handle '%s'",
                     subscribeDialogHandle.data());
    }

    unlock();

    return(notifyInfoSet);
}
UtlBoolean SipSubscribeServerEventHandler::getKeys(const SipMessage& subscribeRequest,
                                                   UtlString& resourceId,
                                                   UtlString& eventTypeKey,
                                                   UtlString& eventType)
{
    // default resourceId is the identity
    UtlString uriString;
    subscribeRequest.getRequestUri(&uriString);
    Url uri(uriString);
    uri.getIdentity(resourceId);
    // Make the resourceId be a proper URI by prepending "sip:".
    resourceId.prepend("sip:");

    // Default event key is the event type with no parameters
    subscribeRequest.getEventField(&eventTypeKey, NULL);
    // Event type is the same.
    eventType = eventTypeKey;

    return(TRUE);
}
예제 #18
0
UtlString SessionContext::getDiscriminatingTagValue( const SipMessage& message ) const
{
   UtlString discriminatingTag;
   Url tempUrl;

   // We do not know the directionality of the message.  In this case
   // we cannot tell if the discriminating tag will come from the From:
   // or To: header.  Return the one that does not match the dialog's
   // original From-tag.

   // Look at the To-Tag first
   message.getToUrl( tempUrl );
   tempUrl.getFieldParameter( "tag", discriminatingTag );
   if( discriminatingTag == mDialogOriginalFromTag )
   {
      message.getFromUrl( tempUrl );
      tempUrl.getFieldParameter( "tag", discriminatingTag );
   }
   return discriminatingTag;
}
예제 #19
0
void WaitingFor200OkWithMediaOffer::SuccessfulResponse( DialogTracker& impl, SipMessage& response, const char* address, int port ) const
{
   // RFC requires that all SDP previews be identical.  In ensure that this
   // requirement is met, we apply the saved copy of the patched SDP preview
   // to the response.
   if( response.hasSdpBody() )
   {
      impl.applyPatchedSdpPreview( response );
   }
   ChangeState( impl, impl.pWaitingForAckWithAnswerForInvite );
}
UtlBoolean AppAgentSubscribePolicy::getKeys(const SipMessage& subscribeRequest,
                                                   UtlString& resourceId,
                                                   UtlString& eventTypeKey,
                                                   UtlString& eventType)
{
    // default resourceId is the identity, but we want it from the From URI
    UtlString uriString;
    subscribeRequest.getFromUri(&uriString);
    Url uri(uriString);
    uri.getIdentity(resourceId);
    // Make the resourceId be a proper URI by prepending "sip:".
    resourceId.prepend("sip:");

    // Default event key is the event type with no parameters, but we want the full thing (dialog;sla)
    subscribeRequest.getEventField(eventTypeKey);
    // Event type is the event type with no parameters.
    subscribeRequest.getEventFieldParts(&eventType);

    return(TRUE);
}
예제 #21
0
void SipDialog::setRequestData(SipMessage& request, const char* method)
{
    UtlString methodString(method ? method : "");
    if(methodString.isNull())
    {
        request.getRequestMethod(&methodString);
    }

    // The request URI should be the remote contact
    UtlString remoteContact;
    // Use getUri() to get the contact in addr-spec format.
    // (mRemoteContact should have no field parameters, but if it has
    // URI parameters, toString would add <...>, which are not allowed
    // in URIs.)
    mRemoteContact.getUri(remoteContact);

    // If the remote contact is empty, use the remote request uri
    if (remoteContact.compareTo("sip:") == 0)
    {
         Os::Logger::instance().log(FAC_ACD, PRI_DEBUG, "SipDialog::setRequestData - using remote request uri %s",
                       msRemoteRequestUri.data());
         request.setSipRequestFirstHeaderLine(methodString, msRemoteRequestUri);
    }
    else
    {
         request.setSipRequestFirstHeaderLine(methodString, remoteContact);
    }

    // The local field is the From field
    UtlString fromField;
    mLocalField.toString(fromField);
    request.setRawFromField(fromField);

    // The remote field is the To field
    UtlString toField;
    mRemoteField.toString(toField);
    request.setRawToField(toField);

    // Get the next local Cseq, the method should already be set
    getNextLocalCseq();
    request.setCSeqField(mLastLocalCseq, methodString);

    // Set the route header according to the route set
    if(!mRouteSet.isNull())
    {
        request.setRouteField(mRouteSet);
    }

    // Set the call-id
    request.setCallIdField(*this);
}
예제 #22
0
/// Encode identity info into a URL
bool SipXauthIdentity::encodeUri(Url              & uri,
                                 const SipMessage & request,
                                 const OsDateTime * timestamp)
{
   // Don't proceed if the encapsulated identity is invalid
   if (!mIsValidIdentity)
   {
      Os::Logger::instance().log(FAC_SIP, PRI_CRIT,
                    "SipXauthIdentity::encodeUri[bound]: encapsulated SipXauthIdentity is invalid");
   }
   else
   {
      // make sure no existing identity in the URI
      uri.removeHeaderParameter(SipXauthIdentity::AuthIdentityHeaderName);
      // set Call-Id and from-tag for the signature calculation
      UtlString callId;
      UtlString fromTag;
      Url fromUrl;
      request.getCallIdField(&callId);
      request.getFromUrl(fromUrl);
      fromUrl.getFieldParameter("tag", fromTag);

      OsDateTime now;
      OsDateTime::getCurTime(now);
      if (NULL==timestamp)
      {
         timestamp = &now;
      }

      UtlString value;
      encode(value, callId, fromTag, *timestamp);
      uri.setHeaderParameter(SipXauthIdentity::AuthIdentityHeaderName, value.data());

      Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                    "SipXauthIdentity::encodeUri[bound] encoded URI '%s'",
                    uri.toString().data()
                    );
   }

   return mIsValidIdentity;
}
예제 #23
0
// Callback routine for NOTIFY events.
// Called by AppearanceGroupTask.
// This callback MUST send a response, as we told the SipSubscribeClient not to.
void AppearanceGroupSet::notifyEventCallbackSync(const UtlString* dialogHandle,
        const SipMessage* msg)
{
    OsSysLog::add(FAC_SAA, PRI_DEBUG,
                  "AppearanceGroupSet::notifyEventCallbackSync dialogHandle = '%s'",
                  dialogHandle->data());

    // Serialize access to the appearance group set.
    OsLock lock(mSemaphore);

    // Look up the ResourceNotifyReceiver to notify based on the dialogHandle.
    /* To call the handler, we dynamic_cast the object to
     * (ResourceNotifyReceiver*).  Whether this is strictly
     * conformant C++ I'm not sure, since UtlContainanble and
     * ResourceNotifyReceiver are not base/derived classes of
     * each other.  But it seems to work in GCC as long as the dynamic
     * type of the object is a subclass of both UtlContainable and
     * ResourceNotifyReceiver.
     */
    ResourceNotifyReceiver* receiver =
        dynamic_cast <ResourceNotifyReceiver*>
        (mNotifyMap.findValue(dialogHandle));

    if (receiver)
    {
        // the callback MUST respond to the NOTIFY
        receiver->notifyEventCallback(dialogHandle, msg);
    }
    else
    {
        OsSysLog::add(FAC_SAA, PRI_DEBUG,
                      "AppearanceGroupSet::notifyEventCallbackSync this = %p, no ResourceNotifyReceiver found for dialogHandle '%s'",
                      this, dialogHandle->data());
        // Acknowledge the NOTIFY, even though we won't process it.
        SipMessage response;
        response.setOkResponseData(msg, NULL);
        getAppearanceAgent()->getServerUserAgent().send(response);
    }
    delete msg;
}
예제 #24
0
UtlBoolean SipDialog::isEarlyDialogFor(const SipMessage& message) const
{
    UtlString handle;

    message.getDialogHandle(handle);

    UtlString callId;
    UtlString localTag;
    UtlString remoteTag;
    parseHandle(handle, callId, localTag, remoteTag);

    return(isEarlyDialogFor(callId, localTag, remoteTag));
}
예제 #25
0
UtlBoolean SipDialogMgr::isLastLocalTransaction(const SipMessage& message, 
                                                const char* dialogHandle)
{
    UtlBoolean matchesTransaction = FALSE;
    UtlString handle(dialogHandle ? dialogHandle : "");
    // If the dialog handle was not set, get it from the message
    if(handle.isNull())
    {
       SipDialog::getDialogHandle(message, handle);
    }

    UtlString callId;
    UtlString fromTag;
    UtlString toTag;
    Url fromField;
    Url toField;
    message.getFromUrl(fromField);
    message.getToUrl(toField);
    message.getCallIdField(callId);
    fromField.getFieldParameter("tag", fromTag);
    toField.getFieldParameter("tag", toTag);

    lock();
    // Looking for any dialog that matches this handle
    SipDialog* dialog = findDialog(handle,
                                   TRUE, // if established, match early dialog
                                   TRUE); // if early, match established dialog

    if(dialog && 
       dialog->isTransactionLocallyInitiated(callId, fromTag, toTag) &&
       dialog->isSameLocalCseq(message))
    {
        matchesTransaction = TRUE;
    }

    unlock();
    
    return(matchesTransaction);
}
예제 #26
0
bool CallTracker::removeSessionHandleFromVias( SipMessage& message, const UtlString& sessionHandleToRemove ) const
{
   bool bSessionHandleRemoved = false;
   UtlString viaValue;
   UtlString tempSessionHandle;
   int viaIndex = 0;

   while( message.getViaFieldSubField( &viaValue, viaIndex ) )
   {
      if( message.getViaTag( viaValue, VIA_SESSION_HANDLE_TAG, tempSessionHandle ) &&
          tempSessionHandle.compareTo( sessionHandleToRemove ) == 0 )
      {
         bSessionHandleRemoved = message.setViaTag( "nil", VIA_SESSION_HANDLE_TAG, viaIndex );
         break;
      }
      else
      {
         viaIndex++;
      }
   }
   return bSessionHandleRemoved;
}
예제 #27
0
bool WaitingForPrack::PrackRequest( DialogTracker& impl, SipMessage& request, TransactionDirectionality direction, const char* address, int port ) const
{
   if( request.hasSdpBody() )
   {
      impl.ProcessMediaOffer( request, NON_INITIAL_OFFER_ANSWER );
      ChangeState( impl, impl.pWaitingFor200OkWithAnswerForPrack );
   }
   else
   {
      ChangeState( impl, impl.pWaitingFor200OkForPrack );
   }
   return true;
}
예제 #28
0
UtlBoolean SipDialog::isSameDialog(const SipMessage& message) const
{
    UtlString messageCallId;
    message.getCallIdField(&messageCallId);
    UtlBoolean isSameDialog = FALSE;
    if(messageCallId.compareTo(*this, UtlString::ignoreCase) == 0)
    {
        Url messageFromUrl;
        message.getFromUrl(messageFromUrl);
        UtlString messageFromTag;
        messageFromUrl.getFieldParameter("tag", messageFromTag);
        if(messageFromTag.compareTo(mLocalTag, UtlString::ignoreCase) == 0)
        {
            Url messageToUrl;
            message.getToUrl(messageToUrl);
            UtlString messageToTag;
            messageToUrl.getFieldParameter("tag", messageToTag);
            if(messageToTag.compareTo(mRemoteTag, UtlString::ignoreCase) == 0)
            {
                isSameDialog = TRUE;
            }
        }
        else if(messageFromTag.compareTo(mRemoteTag, UtlString::ignoreCase) == 0)
        {
            Url messageToUrl;
            message.getToUrl(messageToUrl);
            UtlString messageToTag;
            messageToUrl.getFieldParameter("tag", messageToTag);
            if(messageToTag.compareTo(mLocalTag, UtlString::ignoreCase) == 0)
            {
                isSameDialog = TRUE;
            }
        }

    }
    return(isSameDialog);

}
// Update the IMDB with the NOTIFY CSeq now in notifyRequest and the
// specified 'version' for the given eventTypeKey.
void SipPersistentSubscriptionMgr::updateVersion(SipMessage& notifyRequest,
                                                 int version,
                                                 const UtlString& eventTypeKey)
{
   // Call the superclass's updateVersion.
   SipSubscriptionMgr::updateVersion(notifyRequest, version, eventTypeKey);

   // Extract from the NOTIFY the information we need to find the right
   // IMDB row.
   int cseq;
   UtlString method;
   notifyRequest.getCSeqField(&cseq, &method);

   UtlString to;
   UtlString from;
   UtlString callId;
   UtlString eventType, eventId;
   int now;

   // Note that the "to" and "from" fields of the subscription table
   // are as those URIs appear in the SUBSCRIBE message, which is
   // reversed in the NOTIFY message.
   notifyRequest.getToField(&from);
   notifyRequest.getFromField(&to);
   notifyRequest.getCallIdField(&callId);
   notifyRequest.getEventField(&eventType, &eventId);
   now = (int) OsDateTime::getSecsSinceEpoch();

   OsSysLog::add(FAC_SIP, PRI_DEBUG,
                 "SipPersistentSubscriptionMgr::updateVersion "
                 "callId = '%s', to = '%s', from = '%s', eventType = '%s', eventTypeKey = '%s', eventId = '%s', cseq = %d, version = %d",
                 callId.data(), to.data(), from.data(), eventType.data(), eventTypeKey.data(), eventId.data(), cseq, version);
   mSubscriptionDBInstance->updateNotifyUnexpiredSubscription(
      mComponent, to, from, callId, eventTypeKey, eventId, now, cseq, version);

   // Start the save timer.
   mPersistenceTimer.oneshotAfter(sPersistInterval);
}
예제 #30
0
bool
TuPresSvr::process()
{

    bool done = 0;
    FdSet fdset;
    mStack->buildFdSet(fdset);
//    int err = fdset.selectMilliSeconds(0);
    int err = fdset.selectMilliSeconds(100);
    assert( err != -1 );

    mStack->process(fdset);

    SipMessage* msg = (mStack->receive());
    if (msg)
    {
      if (msg->isRequest())
      {
	if (msg->header(h_RequestLine).getMethod() == SUBSCRIBE )
	{
          processSubscribe(msg);
	}
	else if (msg->header(h_RequestLine).getMethod() == REGISTER )
	{
	  processPublish(msg);
	}
	else if (msg->header(h_RequestLine).getMethod() == OPTIONS )
	{
          auto_ptr<SipMessage> resp(
               Helper::makeResponse(*msg,500,"You Shot Me!")); 
          mStack->send(*resp);
	  done = 1;
	}
	else if (msg->header(h_RequestLine).getMethod() == PUBLISH)
	{
           processPublish(msg);
	}
	else
	{
          auto_ptr<SipMessage> resp(Helper::makeResponse(*msg,501,"")); 
          mStack->send(*resp);
	}
      }
      else
      {
	/*
	 Nope - dialog key is currently overscoped to requests - bad.
	assert(msg->isResponse());
	if (msg->header(h_CSeq).method()==NOTIFY)
	  mDialogMgr.dispatchNotifyResponse(msg);
         */
      }
      delete msg;
    } else {
      mDialogMgr.processExpirations();
    }
    return done;
}