void SipDialog::updateDialogData(const SipMessage& message) { UtlString messageCallId; message.getCallIdField(&messageCallId); Url messageFromUrl; message.getFromUrl(messageFromUrl); UtlString messageFromTag; messageFromUrl.getFieldParameter("tag", messageFromTag); Url messageToUrl; message.getToUrl(messageToUrl); UtlString messageToTag; messageToUrl.getFieldParameter("tag", messageToTag); int cSeq; UtlString method; message.getCSeqField(&cSeq, &method); int responseCode = message.getResponseStatusCode(); // Figure out if the request is from the local or // the remote side if(isTransactionLocallyInitiated(messageCallId, messageFromTag, messageToTag)) { // This message is part of a transaction initiated by // the local side of the dialog if(cSeq > mLastLocalCseq) { mLastLocalCseq = cSeq; } if(cSeq >= mLastLocalCseq) { // Always update the contact if it is set UtlString messageContact; // Get the Contact value, but as an addr-spec. if(message.getContactUri(0, &messageContact) && !messageContact.isNull()) { if(message.isResponse()) { mRemoteContact.fromString(messageContact, TRUE); } else { mLocalContact.fromString(messageContact, TRUE); } } } // Cannot assume that we only establish a dialog with the // initial cseq. For example if there is an authentication // challenge, the dialog will not be established until the // second transaction. if(cSeq == mLastLocalCseq) { // A successful response to an INVITE or SUBSCRIBE // make this early dialog a set up dialog if(mLocalInitiatedDialog && message.isResponse() && responseCode >= SIP_2XX_CLASS_CODE && // successful dialog setup responseCode < SIP_3XX_CLASS_CODE && mRemoteTag.isNull() && // tag not set mRouteSet.isNull()) // have not yet set the route set { // Change this early dialog to a set up dialog. // The tag gets set in the 2xx response // so we need to update the URL message.getToUrl(mRemoteField); mRemoteField.getFieldParameter("tag", mRemoteTag); // Need to get the route set as well // Make sure the Request Method is allowed to set Record-Routes if(message.isRecordRouteAccepted()) { message.buildRouteField(&mRouteSet); } } } } else if(isTransactionRemotelyInitiated(messageCallId, messageFromTag, messageToTag)) { int prevRemoteCseq = mLastRemoteCseq; // This message is part of a transaction initiated by // the callee/destination of the session if(cSeq > mLastRemoteCseq) { mLastRemoteCseq = cSeq; } if(cSeq >= mLastRemoteCseq) { // Always update the contact if it is set UtlString messageContact; // Get the Contact value, but as an addr-spec. if(message.getContactUri(0, &messageContact) && !messageContact.isNull()) { if(message.isResponse()) { mLocalContact.fromString(messageContact, TRUE); } else { mRemoteContact.fromString(messageContact, TRUE); } } } // First transaction from the otherside if(cSeq == mLastRemoteCseq && prevRemoteCseq == -1) { // A response (e.g. NOTIFY) can come before we get the // successful response to the initial transaction if(!mLocalInitiatedDialog && !message.isResponse() && mRemoteTag.isNull()) // tag not set { // Change this early dialog to a set up dialog. // The tag gets set in the 2xx response // so we need to update the URL message.getFromUrl(mRemoteField); mRemoteField.getFieldParameter("tag", mRemoteTag); } } // First successful response from the local side if(cSeq == mLastRemoteCseq) { if(!mLocalInitiatedDialog && message.isResponse() && responseCode >= SIP_2XX_CLASS_CODE && // successful dialog setup responseCode < SIP_3XX_CLASS_CODE && mLocalTag.isNull()) { // Update the local tag message.getToUrl(mLocalField); mLocalField.getFieldParameter("tag", mLocalTag); } } } }
UtlBoolean SipPersistentSubscriptionMgr::updateDialogInfo( const SipMessage& subscribeRequest, UtlString& resourceId, UtlString& eventTypeKey, UtlString& eventType, UtlString& subscribeDialogHandle, UtlBoolean& isNew, UtlBoolean& isSubscriptionExpired, SipMessage& subscribeResponse, SipSubscribeServerEventHandler& handler) { OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipPersistentSubscriptionMgr::updateDialogInfo " "resourceId = '%s', eventTypeKey = '%s'", resourceId.data(), eventTypeKey.data()); UtlBoolean ret; // Call SipSubscriptionMgr to update the in-memory data. ret = SipSubscriptionMgr::updateDialogInfo(subscribeRequest, resourceId, eventTypeKey, eventType, subscribeDialogHandle, isNew, isSubscriptionExpired, subscribeResponse, handler); // If that succeeded, update the IMDB. if (ret) { UtlString requestUri; UtlString callId; UtlString contactEntry; UtlString to; UtlString from; UtlString route; UtlString accept; subscribeRequest.getRequestUri(&requestUri); subscribeRequest.getCallIdField(&callId); subscribeRequest.getContactEntry(0, &contactEntry); subscribeRequest.getToField(&to); subscribeRequest.getFromField(&from); subscribeRequest.buildRouteField(&route); accept.append(subscribeRequest.getHeaderValue(0, SIP_ACCEPT_FIELD)); int expires = 0; subscribeResponse.getExpiresField(&expires); expires += OsDateTime::getSecsSinceEpoch(); int subscribeCseq; UtlString subscribeCseqMethod; subscribeRequest.getCSeqField(&subscribeCseq, &subscribeCseqMethod); OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipPersistentSubscriptionMgr::updateDialogInfo " "mComponent = '%s', requestUri = '%s', callId = '%s', contactEntry = '%s', expires = %d, to = '%s', from = '%s', key = '%s', route = '%s', accept = '%s'", mComponent.data(), requestUri.data(), callId.data(), contactEntry.data(), expires, to.data(), from.data(), resourceId.data(), route.data(), accept.data()); // Attempt to update an existing row. int now = (int)OsDateTime::getSecsSinceEpoch(); ret = mSubscriptionDBInstance->updateSubscribeUnexpiredSubscription( mComponent, to, from, callId, eventTypeKey, "", now, expires, subscribeCseq); if (!ret) { // Add a new row. // This call assumes that eventTypeKey is OK for use as the <eventtype>, // and that the NOTIFY CSeq's will start at 1. 0 is used as // the initial XML version. ret = mSubscriptionDBInstance->insertRow( mComponent, requestUri, callId, contactEntry, expires, subscribeCseq, eventTypeKey, "", to, from, resourceId, route, 1, accept, 0); if (!ret) { OsSysLog::add(FAC_SIP, PRI_ERR, "SipPersistantSubscriptionMgr::addSubscription " "Could not update or insert record in database"); } } // Start the save timer. mPersistenceTimer.oneshotAfter(sPersistInterval); } return ret; }