UtlBoolean UserLocationDB::removeRow ( const Url& identityUri, const UtlString& location ) { UtlBoolean rc = FALSE; UtlString identityStr; identityUri.getIdentity(identityStr); if ( !identityStr.isNull() && (m_pFastDB != NULL) ) { // Thread Local Storage m_pFastDB->attach(); dbCursor< UserLocationRow > cursor(dbCursorForUpdate); dbQuery query; query="identity=",identityStr,"and location=",location; if ( cursor.select( query ) > 0 ) { cursor.removeAllSelected(); rc = TRUE; } // Commit rows to memory - multiprocess workaround m_pFastDB->detach(0); } return rc; }
/// Non-static callback to handle incoming NOTIFYs. void SipDialogMonitor::handleNotifyMessage(const SipMessage* notifyMessage, const char* earlyDialogHandle, const char* dialogHandle) { Url fromUrl; notifyMessage->getFromUrl(fromUrl); UtlString contact; fromUrl.getIdentity(contact); OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::handleNotifyMessage receiving a notify message from %s", contact.data()); const HttpBody* notifyBody = notifyMessage->getBody(); if (notifyBody) { UtlString messageContent; ssize_t bodyLength; notifyBody->getBytes(&messageContent, &bodyLength); // Parse the content and store it in a SipDialogEvent object SipDialogEvent* sipDialogEvent = new SipDialogEvent(messageContent); // Add the SipDialogEvent object to the hash table addDialogEvent(contact, sipDialogEvent, earlyDialogHandle, dialogHandle); } else { OsSysLog::add(FAC_SIP, PRI_WARNING, "SipDialogMonitor::handleNotifyMessage receiving an empty notify body from %s", contact.data()); } }
UtlBoolean RegistrationDB::isOutOfSequence( const Url& uri ,const UtlString& callid ,const int& cseq ) const { UtlBoolean isOlder; UtlString identity; uri.getIdentity( identity ); if ( !identity.isNull() && ( m_pFastDB != NULL) ) { SMART_DB_ACCESS; dbCursor< RegistrationRow > cursor; dbQuery query; query="np_identity=",identity, " and callid=",callid, " and cseq>=",cseq; isOlder = ( cursor.select(query) > 0 ); } else { OsSysLog::add( FAC_SIP, PRI_ERR, "RegistrationDB::isOutOfSequence bad state @ %d %p" ,__LINE__, m_pFastDB ); isOlder = TRUE; // will cause 500 Server Internal Error, which is true } return isOlder; }
UtlBoolean DialByNameDB::removeRow ( const Url& contact ) { UtlBoolean removed = FALSE; UtlString identity; contact.getIdentity(identity); if ( !identity.isNull() && (m_pFastDB != NULL) ) { // Thread Local Storage m_pFastDB->attach(); dbCursor< DialByNameRow > cursor(dbCursorForUpdate); dbQuery query; query="np_identity=",identity; if ( cursor.select( query ) > 0 ) { cursor.removeAllSelected(); removed = TRUE; } // Commit rows to memory - multiprocess workaround m_pFastDB->detach(0); } return removed; }
void CredentialDB::removeRows ( const Url& uri, const UtlString& realm ) { UtlString identity; uri.getIdentity(identity); if ( !identity.isNull() && (m_pFastDB != NULL)) { // Thread Local Storage m_pFastDB->attach(); dbCursor< CredentialRow > cursor(dbCursorForUpdate); dbQuery query; query="np_identity=",identity,"and realm=",realm; if (cursor.select(query) > 0) { cursor.removeAllSelected(); } // Commit rows to memory - multiprocess workaround m_pFastDB->detach(0); // Table Data changed SIPDBManager::getInstance()-> setDatabaseChangedFlag(mDatabaseName, TRUE); } }
UtlBoolean UserForwardDB::getCfwdTime ( const Url& identity, UtlString& cfwdtime ) const { UtlString identityStr; identity.getIdentity(identityStr); UtlBoolean found = FALSE; if ( !identityStr.isNull() && (m_pFastDB != NULL) ) { // Thread Local Storage m_pFastDB->attach(); // Match a all rows where the contact identity matches dbQuery query; query="identity=",identityStr; // Search to see if we have a User Forward Row dbCursor< UserForwardRow > cursor; if ( cursor.select(query) > 0 ) { cfwdtime = cursor->cfwdtime; found = TRUE; } m_pFastDB->detach(0); } return found; }
UtlBoolean ExtensionDB::removeRow ( const Url& uri ) { UtlBoolean removed = FALSE; UtlString identity; uri.getIdentity(identity); if ( !identity.isNull() && (m_pFastDB != NULL) ) { // Thread Local Storage m_pFastDB->attach(); dbCursor< ExtensionRow > cursor(dbCursorForUpdate); dbQuery query; query="np_identity=",identity; if ( cursor.select( query ) > 0 ) { cursor.removeAllSelected(); removed = TRUE; } // Commit rows to memory - multiprocess workaround m_pFastDB->detach(0); // Table Data changed SIPDBManager::getInstance()-> setDatabaseChangedFlag(mDatabaseName, TRUE); } return removed; }
bool SipPresenceMonitor::removeExtension(UtlString& groupName, Url& contactUrl) { bool result = false; mLock.acquire(); // Check whether the group has existed or not. If not, return false. SipResourceList* list = dynamic_cast <SipResourceList *> (mMonitoredLists.findValue(&groupName)); if (list == NULL) { OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipPresenceMonitor::removeExtension group %s does not exist", groupName.data()); } else { // Check whether the contact has existed or not UtlString resourceId; contactUrl.getIdentity(resourceId); Resource* resource = list->getResource(resourceId); if (resource) { resource = list->removeResource(resource); delete resource; result = true; } else { OsSysLog::add(FAC_LOG, PRI_WARNING, "SipPresenceMonitor::removeExtension subscription for contact %s does not exists.", resourceId.data()); } } mLock.release(); return result; }
UtlBoolean PermissionDB::hasPermission ( const Url& identity, const UtlString& permission ) const { UtlBoolean hasPermission = FALSE; UtlString identityStr; identity.getIdentity(identityStr); if ( !permission.isNull() && (m_pFastDB != NULL) ) { // Thread Local Storage m_pFastDB->attach(); dbQuery query; // Primary Key is the uriPermission's identity query="identity=",identityStr,"and permission=", permission; // Search to see if we have a Credential Row dbCursor< PermissionRow > cursor; if ( cursor.select(query) > 0 ) { hasPermission = TRUE; } // Commit the rows to memory - multiprocess workaround m_pFastDB->detach(0); } return hasPermission; }
UtlBoolean DialByNameDB::insertRow ( const Url& contact ) const { UtlBoolean result = FALSE; if ( m_pFastDB != NULL ) { // Fetch the display name UtlString identity, displayName, contactString; contact.getIdentity( identity ); contact.getDisplayName( displayName ); contact.toString( contactString ); // Make sure that the contact URL is valid and contains // a contactIdentity and a contactDisplayName if ( !identity.isNull() && !displayName.isNull() ) { UtlSList dtmfStrings; getDigitStrings ( displayName, dtmfStrings ); if ( !dtmfStrings.isEmpty() ) { // Thread Local Storage m_pFastDB->attach(); // Search for a matching row before deciding to update or insert dbCursor< DialByNameRow > cursor(dbCursorForUpdate); DialByNameRow row; dbQuery query; // Primary Key is identity query="np_identity=",identity; // Purge all existing entries associated with this identity if ( cursor.select( query ) > 0 ) { cursor.removeAllSelected(); } // insert all dtmf combinations for this user unsigned int i; for (i=0; i<dtmfStrings.entries(); i++) { UtlString* digits = (UtlString*)dtmfStrings.at(i); row.np_contact = contactString; row.np_identity = identity; row.np_digits = digits->data(); insert (row); } // Commit rows to memory - multiprocess workaround m_pFastDB->detach(0); } } } return result; }
RedirectPlugin::LookUpStatus SipRedirectorPresenceRouting::doLookUp( const Url& toUrl, ContactList& contactList) { // check if we have unified presence info for this user const UnifiedPresence* pUp; UtlString to; UtlString username; toUrl.getIdentity( to ); toUrl.getUserId( username ); OsSysLog::add(FAC_SIP, PRI_INFO, "%s::LookUpStatus is looking up '%s'", mLogName.data(),to.data() ); pUp = UnifiedPresenceContainer::getInstance()->lookup( &to ); if( pUp ) { // unified presence data is available for the called party. // Use it to make call routing decisions. OsSysLog::add(FAC_SIP, PRI_INFO, "%s::LookUpStatus " "Presence information for '%s':\r\n" " Telephony presence: '%s'" " XMPP presence: '%s'" " Custom presence message: '%s'", mLogName.data(), to.data(), pUp->getSipState().data(), pUp->getXmppPresence().data(), pUp->getXmppStatusMessage().data() ); // look for tel uri in the custom presence message RegEx telUri( TelUri ); telUri.Search( pUp->getXmppStatusMessage().data() ); UtlString targetUri; if( telUri.MatchString( &targetUri, 1 ) ) { // prepend 'sip:' and add target as contact targetUri.insert( 0, "sip:" ); contactList.add( targetUri, *this ); } else { // If user is busy then call goes directly to voicemail. if( ( pUp->getSipState().compareTo("BUSY", UtlString::ignoreCase ) == 0 && mbForwardToVmOnBusy ) || ( pUp->getXmppPresence().compareTo("BUSY", UtlString::ignoreCase ) == 0 && mUserPrefs.forwardToVoicemailOnDnd( username ) ) ) { // prune all non-voicemail contacts from the list removeNonVoicemailContacts( contactList ); } } } return RedirectPlugin::SUCCESS; }
UtlBoolean ExtensionDB::insertRow ( const Url& uri, const UtlString& extension ) { UtlBoolean result = FALSE; UtlString identity; uri.getIdentity(identity); if ( !identity.isNull() && (m_pFastDB != NULL) ) { // Thread Local Storage m_pFastDB->attach(); // Search for a matching row before deciding to update or insert dbCursor< ExtensionRow > cursor(dbCursorForUpdate); ExtensionRow row; // see if this in an insert or update dbQuery query; query="np_identity=",identity; if ( cursor.select( query ) > 0 ) { // already in DB so update the extension // the uri should remain the same as the identity // part has'nt changed do { cursor->extension = extension; cursor.update(); } while ( cursor.next() ); } else // Insert as the row does not exist { UtlString uriStr; uri.toString(uriStr); // Fill out the row columns row.np_identity = identity; row.uri = uriStr; row.extension = extension; insert (row); } // Commit rows to memory - multiprocess workaround m_pFastDB->detach(0); // Table Data changed SIPDBManager::getInstance()-> setDatabaseChangedFlag(mDatabaseName, TRUE); result = TRUE; } return result; }
void AliasDB::getAliases ( const Url& contactIdentity, ResultSet& rResultSet ) const { UtlString contactIdentityStr; contactIdentity.getIdentity(contactIdentityStr); // This should erase the contents of the existing resultset rResultSet.clear(); if ( !contactIdentityStr.isNull() && (m_pFastDB != NULL) ) { // Thread Local Storage m_pFastDB->attach(); // Match a all rows where the contact identity matches UtlString queryString = "contact like '%" + contactIdentityStr + "%'"; dbQuery query; query=queryString; // Search to see if we have a Credential Row dbCursor< AliasRow > cursor; if ( cursor.select(query) > 0 ) { do { UtlHashMap record; UtlString* identityValue = new UtlString ( cursor->identity ); UtlString* contactValue = new UtlString ( cursor->contact ); // Memory Leak fixes, make shallow copies of static keys UtlString* identityKey = new UtlString( gIdentityKey ); UtlString* contactKey = new UtlString( gContactKey ); record.insertKeyAndValue ( identityKey, identityValue ); record.insertKeyAndValue ( contactKey, contactValue ); rResultSet.addValue(record); } while ( cursor.next() ); } // Commit the rows to memory - multiprocess workaround m_pFastDB->detach(0); } }
bool SipPresenceMonitor::addExtension(UtlString& groupName, Url& contactUrl) { bool result = false; mLock.acquire(); // Check whether the group has already existed. If not, create one. SipResourceList* list = dynamic_cast <SipResourceList *> (mMonitoredLists.findValue(&groupName)); if (list == NULL) { UtlString* listName = new UtlString(groupName); list = new SipResourceList((UtlBoolean)TRUE, listName->data(), PRESENCE_EVENT_TYPE); mMonitoredLists.insertKeyAndValue(listName, list); OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipPresenceMonitor::addExtension insert listName %s and object %p to the resource list", groupName.data(), list); } // Check whether the contact has already been added to the group UtlString resourceId; contactUrl.getIdentity(resourceId); Resource* resource = list->getResource(resourceId); if (resource == NULL) { resource = new Resource(resourceId); UtlString userName; contactUrl.getDisplayName(userName); resource->setName(userName); UtlString id; makeId(id, resourceId); resource->setInstance(id, STATE_PENDING); list->insertResource(resource); result = true; } else { OsSysLog::add(FAC_LOG, PRI_WARNING, "SipPresenceMonitor::addExtension contact %s already exists.", resourceId.data()); } int dummy; list->buildBody(&dummy); mLock.release(); return result; }
void AliasDB::getContacts ( const Url& identity, ResultSet& rResultSet ) const { UtlString identityStr; identity.getIdentity(identityStr); // This should erase the contents from the resultset object rResultSet.clear(); if ( !identityStr.isNull() && (m_pFastDB != NULL) ) { // Thread Local Storage m_pFastDB->attach(); dbQuery query; // Primary Key is the urialias's identity query="identity=",identityStr; // Search to see if we have a Credential Row dbCursor< AliasRow > cursor; if ( cursor.select(query) > 0 ) { do { UtlHashMap record; UtlString* identityValue = new UtlString ( cursor->identity ); UtlString* contactValue = new UtlString ( cursor->contact ); // Memory Leak fixes, make shallow copies of static keys UtlString* identityKey = new UtlString( gIdentityKey ); UtlString* contactKey = new UtlString( gContactKey ); record.insertKeyAndValue ( identityKey, identityValue ); record.insertKeyAndValue ( contactKey, contactValue ); rResultSet.addValue(record); } while ( cursor.next() ); } // Commit the rows to memory - multiprocess workaround m_pFastDB->detach(0); } }
bool SipDialogMonitor::removeExtension(UtlString& groupName, Url& contactUrl) { bool result = false; mLock.acquire(); // Check whether the group has existed or not. If not, return false. SipResourceList* list = dynamic_cast <SipResourceList *> (mMonitoredLists.findValue(&groupName)); if (list == NULL) { OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::removeExtension group %s does not exist", groupName.data()); } else { // Check whether the contact has existed or not UtlString resourceId; contactUrl.getIdentity(resourceId); Resource* resource = list->getResource(resourceId); if (resource) { UtlString* dialogHandle = dynamic_cast <UtlString *> (mDialogHandleList.findValue(&resourceId)); OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::removeExtension Calling endSubscription(%s)", dialogHandle->data()); UtlBoolean status = mpSipSubscribeClient->endSubscription(dialogHandle->data()); if (!status) { OsSysLog::add(FAC_SIP, PRI_ERR, "SipDialogMonitor::removeExtension Unsubscription failed for %s.", resourceId.data()); } mDialogHandleList.destroy(&resourceId); resource = list->removeResource(resource); delete resource; result = true; } else { OsSysLog::add(FAC_LOG, PRI_WARNING, "SipDialogMonitor::removeExtension subscription for contact %s does not exists.", resourceId.data()); } } mLock.release(); return result; }
UtlBoolean UserLocationDB::insertRow ( const Url& identityUri, const UtlString& location ) { UtlBoolean result = FALSE; UtlString identityStr; identityUri.getIdentity( identityStr ); // both the pk and fk's are stored in the db as identities // making for consistency, this is how they are stored in // the credentials database and the uriIdentity is a FK to that db // so this step of extracting identies is crucial if ( !identityStr.isNull() && !location.isNull() && (m_pFastDB != NULL) ) { // Thread Local Storage m_pFastDB->attach(); // Search for a matching row before deciding to update or insert dbCursor< UserLocationRow > cursor(dbCursorForUpdate); dbQuery query; // If the row already exists do nothing query="identity=",identityStr,"and location=",location; if ( cursor.select( query ) == 0 ) { // Non existent row so insert UserLocationRow row; // Fill out the row columns row.identity = identityStr; row.location = location; insert( row ); } // Commit rows to memory - multiprocess workaround m_pFastDB->detach(0); // Successful return code result = TRUE; } // Most likely an arg problem return result; }
/// clean out any bindings for this callid and older cseq values. void RegistrationDB::expireOldBindings( const Url& uri ,const UtlString& callid ,const int& cseq ,const int& timeNow ,const UtlString& primary ,const Int64& update_number ) { UtlString identity; uri.getIdentity(identity); int expirationTime = timeNow-1; if ( !identity.isNull() && ( m_pFastDB != NULL ) ) { SMART_DB_ACCESS; dbCursor< RegistrationRow > cursor(dbCursorForUpdate); dbQuery query; query="np_identity=",identity, "and callid=",callid, "and cseq<",cseq, "and expires>=",expirationTime ; if (cursor.select(query) > 0) { do { cursor->expires = expirationTime; cursor->cseq = cseq; cursor->primary = primary; cursor->update_number = update_number; cursor.update(); } while ( cursor.next() ); } } else { OsSysLog::add(FAC_DB, PRI_CRIT, "RegistrationDB::expireOldBindings failed - no DB"); } }
UtlBoolean CredentialDB::isUriDefined ( const Url& uri, UtlString& realm, UtlString& authType ) const { UtlBoolean found = FALSE; UtlString identity; uri.getIdentity(identity); OsSysLog::add(FAC_DB, PRI_DEBUG, "CredentialDB::isUriDefined identity %s, m_pFastDB=%p ", identity.data(), m_pFastDB); if ( !identity.isNull() && (m_pFastDB != NULL) ) { // Thread Local Storage m_pFastDB->attach(); // Search to see if we have a Credential Row dbCursor< CredentialRow > cursor; dbQuery query; // This is equivalent to select * from credentials // where identity=uri.getIdentity() and realm=realm // and authType = authType query="np_identity=",identity; if ( cursor.select(query) > 0 ) { OsSysLog::add(FAC_DB, PRI_DEBUG, "CredentialDB::isUriDefined cursor selected "); do { realm = cursor->realm; authType = cursor->authtype; } while ( cursor.next() ); found = TRUE; } // Commit the rows to memory - multiprocess workaround m_pFastDB->detach(0); } OsSysLog::add(FAC_DB, PRI_DEBUG, "CredentialDB::isUriDefined found=%d ", (int)found); return found; }
/// Retrieve the User PIN check values for a given identity and realm UtlBoolean CredentialDB::getUserPin ( const Url& uri, const UtlString& realm, UtlString& userid, UtlString& pintoken, UtlString& authType ) const { UtlBoolean found = FALSE; UtlString identity; uri.getIdentity(identity); // Match the row and return the passtoken and authtype if ( !identity.isNull() && (m_pFastDB != NULL) ) { // Thread Local Storage m_pFastDB->attach(); dbCursor< CredentialRow > cursor; dbQuery query; query="np_identity=",identity, \ "and realm=",realm, \ "order by np_identity asc, realm asc"; if ( cursor.select( query ) > 0 ) { do { userid = cursor->userid; pintoken = cursor->pintoken; authType = cursor->authtype; found = TRUE; } while ( cursor.next() ); } // Commit rows to memory - multiprocess workaround m_pFastDB->detach(0); } return found; }
UtlBoolean UserForwardDB::insertRow ( const Url& identity, const UtlString& cfwdTime ) { UtlBoolean result = FALSE; UtlString identityStr; identity.getIdentity(identityStr); // both the pk and fk's are stored in the db as identities // making for consistency, this is how they are stored in // the user forward database and the uriIdentity is a FK to that db // so this step of extracting identies is crucial if ( !identityStr.isNull() && !cfwdTime.isNull() && (m_pFastDB != NULL) ) { // Thread Local Storage m_pFastDB->attach(); // Search for a matching row before deciding to update or insert dbCursor< UserForwardRow > cursor(dbCursorForUpdate); UserForwardRow row; { // Fill out the row columns row.identity = identityStr; row.cfwdtime = cfwdTime; insert (row); } result = TRUE; // Commit rows to memory - multiprocess workaround m_pFastDB->detach(0); // Table Data changed SIPDBManager::getInstance()-> setDatabaseChangedFlag(mDatabaseName, TRUE); } return result; }
UtlBoolean ExtensionDB::getExtension ( const Url& uri, UtlString& rExtesnion ) const { UtlBoolean found = FALSE; UtlString identity; uri.getIdentity(identity); if ( !identity.isNull() && (m_pFastDB != NULL) ) { // Thread Local Storage m_pFastDB->attach(); dbQuery query; // Primary Key is the uriExtension's identity query="np_identity=",identity; // Search to see if we have a Credential Row dbCursor< ExtensionRow > cursor; if ( cursor.select(query) > 0 ) { // should only be row do { rExtesnion = cursor->extension; } while ( cursor.next() ); found = TRUE; } // Commit the rows to memory - multiprocess workaround m_pFastDB->detach(0); } return found; }
void PermissionDB::removeRows ( const Url& identity ) { UtlString identityStr; identity.getIdentity(identityStr); if ( !identityStr.isNull() && ( m_pFastDB != NULL ) ) { // Thread Local Storage m_pFastDB->attach(); dbCursor< PermissionRow > cursor(dbCursorForUpdate); dbQuery query; query="identity=",identityStr; if ( cursor.select( query ) > 0 ) { cursor.removeAllSelected(); } // Commit rows to memory - multiprocess workaround m_pFastDB->detach(0); } return; }
bool SipPresenceMonitor::setStatus(const Url& aor, const Status value) { bool result = false; UtlString contact; aor.getIdentity(contact); // Create a presence event package and store it in the publisher SipPresenceEvent* sipPresenceEvent = new SipPresenceEvent(contact); UtlString id; NetMd5Codec::encode(contact, id); Tuple* tuple = new Tuple(id.data()); if (value == StateChangeNotifier::PRESENT) { tuple->setStatus(STATUS_OPEN); tuple->setContact(contact, 1.0); } else { if (value == StateChangeNotifier::AWAY) { tuple->setStatus(STATUS_CLOSE); tuple->setContact(contact, 1.0); } } sipPresenceEvent->insertTuple(tuple); // Add the SipPresenceEvent object to the subscribe list result = addPresenceEvent(contact, sipPresenceEvent); return result; }
SubscribeServerThread::SubscribeStatus SubscribeServerThread::addSubscription( const int timeNow, const SipMessage* subscribeMessage, const char* domain, const UtlString& eventType, const UtlString& eventId, const UtlHashMap& eventParams, UtlString& newToTag, int& grantedExpiration) { SubscribeStatus returnStatus = STATUS_INTERNAL_ERROR; int subscribeCseqInt = 0; UtlString callId; UtlString contactEntry; UtlString to; UtlString from; UtlString route; UtlString key; UtlString method; Url identity; // Construct the identity UtlString uriUser, requestUri; subscribeMessage->getUri( NULL, NULL, NULL, &uriUser ); subscribeMessage->getRequestUri( &requestUri ); identity.setUserId( uriUser ); identity.setUrlType( "sip" ); identity.setHostAddress( domain ); subscribeMessage->getToField(&to); subscribeMessage->getFromField(&from); subscribeMessage->getCallIdField(&callId); subscribeMessage->getCSeqField(&subscribeCseqInt, &method); subscribeMessage->getContactEntry(0, &contactEntry); subscribeMessage->buildRouteField(&route); Url toUrl; subscribeMessage->getToUrl(toUrl); int commonExpires = -1; if ( subscribeMessage->getExpiresField( &commonExpires ) ) { if( commonExpires > 0 ) // came from request { if (commonExpires < mMinExpiresTimeint) { returnStatus = STATUS_LESS_THAN_MINEXPIRES; OsSysLog::add( FAC_SIP, PRI_ERR, "addSubscription: " "Expires (%d) less than Minimum (%d)", commonExpires, mMinExpiresTimeint); return returnStatus; } else if (commonExpires > mDefaultSubscribePeriod) { commonExpires = mDefaultSubscribePeriod; } else { // commonExpires is in the allowed range - use the requested value } } else if( commonExpires == 0 ) { // remove subscription binding // remove all bindings because one contact value is * OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription -" " subscription for url %s and event %s to be removed after sending NOTIFY", toUrl.toString().data(), eventType.data()); returnStatus = STATUS_TO_BE_REMOVED; return returnStatus; } else if( commonExpires == -1) // no expires value in request { // Assume the default value commonExpires = mDefaultSubscribePeriod; OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription -" " No Expires Value, assigning default value (%d)", commonExpires); } } UtlString sipxImpliedParameter(SIPX_IMPLIED_SUB); UtlString* sipxImpliedDuration = NULL; int grantedExpirationTime; if (( sipxImpliedDuration = dynamic_cast<UtlString*>(eventParams.findValue(&sipxImpliedParameter)))) { /* * This request was generated by the registrar as an implied subscription; * its duration must therefore match that of the registration, which has * already been randomized. */ grantedExpirationTime = atoi(sipxImpliedDuration->data()); } else { /* * The request is for a new or refreshed subscription (other cases were handled above); * commonExpires is now the requested duration in the range: * mMinExpiresTimeint <= commonExpires <= mDefaultSubscribePeriod * In order to distribute expirations smoothly, we actually grant a randomized duration */ int spreadFloor = mMinExpiresTimeint*2; if ( commonExpires > spreadFloor ) { // a normal (long) registration // - spread it between twice the min and the longest they asked for grantedExpirationTime = ( (rand() % (commonExpires - spreadFloor)) + spreadFloor); } else if ( commonExpires > mMinExpiresTimeint ) { // a short but not minimum registration // - spread it between the min and the longest they asked for grantedExpirationTime = ( (rand() % (commonExpires - mMinExpiresTimeint) ) + mMinExpiresTimeint ); } else // longestExpiration == mMinExpiresTimeint { // minimum - can't randomize because we can't shorten or lengthen it grantedExpirationTime = mMinExpiresTimeint; } } // Handle the to-tag: // If no to-tag, this is a new subscription, for which we must create // a to-tag. // If there is a to-tag, this is a renewal of a subscription, and we // must first check that the subscription exists. (This is because if // the UA thinks there is a subscription, but we do not know of it, we // cannot reconstitute the subscription, as we do not know the NOTIFY CSeq // that the UA expects. See XECS-406 for the ill consequences of // this problem.) // Clear the returned new to-tag. newToTag.remove(0); { UtlString x; bool r = toUrl.getFieldParameter("tag", x); OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription getting to-tag, return %d, value '%s'", (int) r, x.data()); } UtlString toTag; if (toUrl.getFieldParameter("tag", toTag)) { // Check to see if this subscription exists. // Critical Section here OsLock mutex(mLock); bool exists = SubscriptionDB::getInstance()->subscriptionExists( SUBSCRIPTION_COMPONENT_STATUS, to, from, callId, OsDateTime::getSecsSinceEpoch()); OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription subscriptionExists(..., '%s', '%s', '%s', %d) = %d", to.data(), from.data(), callId.data(), (int) OsDateTime::getSecsSinceEpoch(), exists); if (!exists) { returnStatus = STATUS_BAD_SUBSCRIPTION; return returnStatus; } } else { // Generate a random to-tag. CallId::getNewTag(newToTag); // Add it to the remembered To header value. to.append(";tag="); to.append(newToTag); OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription generated to-tag '%s'", newToTag.data()); } OsSysLog::add(FAC_SIP, PRI_DEBUG, "SubscribeServerThread::addSubscription -" " Adding/updating subscription for URI '%s' event %s duration %d to '%s'", toUrl.toString().data(), eventType.data(), grantedExpirationTime, contactEntry.data()); // trim the contact to just the uri Url contactUrl(contactEntry); contactUrl.getUri(contactEntry); // add bindings identity.getIdentity( key ); // Insert or update the information for this subscription. // (Note that the "notify CSeq" parameter is ignored if there is // an existing SubscriptionDB row for this subscription.) if (insertRow(requestUri, // identity, callId, contactEntry, grantedExpirationTime + timeNow, subscribeCseqInt, eventType, eventId, to, from, key, // this will be searched for later route, 1)) // initial notify cseq (sent to phone) { grantedExpiration = grantedExpirationTime; returnStatus = STATUS_SUCCESS; } else { // log the error and send error indication to subscriber OsSysLog::add(FAC_SIP, PRI_ERR, "SubscribeServerThread::addSubscription -" " Could not insert record in Database"); returnStatus = STATUS_INTERNAL_ERROR; } return returnStatus; }
UtlBoolean AppAgentSubscribePolicy::isAuthenticated(const SipMessage & subscribeRequest, SipMessage & subscribeResponse) { UtlBoolean isAuthorized = FALSE; UtlString callId; subscribeRequest.getCallIdField(&callId); Url fromNameAddr; UtlString fromTag; subscribeRequest.getFromUrl(fromNameAddr); fromNameAddr.getFieldParameter("tag", fromTag); UtlString authNonce; UtlString authRealm; UtlString authUser; UtlString authUserBase; UtlString uriParam; UtlString authCnonce; UtlString authNonceCount; UtlString authQop; // Iterate through Authorization and Proxy-Authorization credentials, // looking for one that shows this request is authenticated. for (int authIndex = 0; ! isAuthorized && subscribeRequest.getDigestAuthorizationData(&authUser, &authRealm, &authNonce, NULL, NULL, &uriParam, &authCnonce, &authNonceCount, &authQop, HttpMessage::SERVER, authIndex, &authUserBase); authIndex++ ) { Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "AppAgentSubscribePolicy::isAuthenticated " "Message Authorization received: " "reqRealm='%s', reqUser='******', reqUserBase='%s'", authRealm.data(), authUser.data(), authUserBase.data()); UtlString qopType; if (mRealm.compareTo(authRealm) ) // case sensitive check that realm is correct { Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "AppAgentSubscribePolicy::isAuthenticated " "Realm does not match"); } // validate the nonce else if (!mNonceDb.isNonceValid(authNonce, callId, fromTag, mRealm, mNonceExpiration)) { Os::Logger::instance().log(FAC_AUTH, PRI_INFO, "AppAgentSubscribePolicy::isAuthenticated -" "Invalid nonce: nonce='%s', callId='%s'", authNonce.data(), callId.data()); } // verify that qop,cnonce, nonceCount are compatible else if (subscribeRequest.verifyQopConsistency(authCnonce.data(), authNonceCount.data(), &authQop, qopType) >= HttpMessage::AUTH_QOP_NOT_SUPPORTED) { Os::Logger::instance().log(FAC_AUTH, PRI_INFO, "AppAgentSubscribePolicy::isAuthenticated -" "Invalid combination of QOP('%s'), cnonce('%s') and nonceCount('%s')", authQop.data(), authCnonce.data(), authNonceCount.data()); } else // realm, nonce and qop are all ok { // build the "authorization identity" from the auth credentials Url authIdentity; UtlString authTypeDB; UtlString passTokenDB; // then get the credentials for this user & realm if (mEntityDb.getCredential(authUserBase, authRealm, authIdentity, passTokenDB, authTypeDB)) { // only DIGEST is used, so the authTypeDB above is ignored if ((isAuthorized = subscribeRequest.verifyMd5Authorization(authUser.data(), passTokenDB.data(), authNonce.data(), authRealm.data(), authCnonce.data(), authNonceCount.data(), authQop.data(), uriParam.data()) )) { Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "AppAgentSubscribePolicy::isAuthenticated " "response auth hash matches"); } else { UtlString identity; authIdentity.getIdentity(identity); Os::Logger::instance().log(FAC_AUTH, PRI_ERR, "AppAgentSubscribePolicy::isAuthenticated " "Response auth hash does not match (bad password?)" " authIdentity='%s' authUser='******' authUserBase='%s'", identity.data(), authUser.data(), authUserBase.data()); } } else // failed to get credentials { UtlString identity; authIdentity.getIdentity(identity); Os::Logger::instance().log(FAC_AUTH, PRI_ERR, "AppAgentSubscribePolicy::isAuthenticated " "Unable to get credentials for realm='%s', user='******', userBase = '%s'", mRealm.data(), authUser.data(), authUserBase.data()); } } // end DB check } //end for if ( !isAuthorized ) { // Generate a new challenge UtlString newNonce; UtlString opaque; mNonceDb.createNewNonce(callId, fromTag, mRealm, newNonce); subscribeResponse.setRequestUnauthorized(&subscribeRequest, HTTP_DIGEST_AUTHENTICATION, mRealm, newNonce, NULL // opaque ); } return isAuthorized; }
RedirectPlugin::LookUpStatus SipRedirectorRegDB::lookUp( const SipMessage& message, const UtlString& requestString, const Url& requestUri, const UtlString& method, ContactList& contactList, RequestSeqNo requestSeqNo, int redirectorNo, SipRedirectorPrivateStorage*& privateStorage, ErrorDescriptor& errorDescriptor) { unsigned long timeNow = OsDateTime::getSecsSinceEpoch(); // Local copy of requestUri Url requestUriCopy = requestUri; // Look for any grid parameter and remove it. UtlString gridParameter; UtlBoolean gridPresent = requestUriCopy.getUrlParameter("grid", gridParameter, 0); if (gridPresent) { requestUriCopy.removeUrlParameter("grid"); } if (Os::Logger::instance().willLog(FAC_SIP, PRI_DEBUG)) { UtlString temp; requestUriCopy.getUri(temp); Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp gridPresent = %d, gridParameter = '%s', " "requestUriCopy after removing grid = '%s'", mLogName.data(), gridPresent, gridParameter.data(), temp.data()); } RegDB::Bindings registrations; // Give the ~~in~ URIs separate processing. UtlString user; requestUriCopy.getUserId(user); if (user.index(URI_IN_PREFIX) == 0) { // This is a ~~in~ URI. // Check for an '&' separator. ssize_t s = user.last('&'); if (s != UTL_NOT_FOUND) { // This is a ~~in~[user]&[instrument] URI. const char* instrumentp = user.data() + s + 1; UtlString u; u.append(user, sizeof (URI_IN_PREFIX) - 1, s - (sizeof (URI_IN_PREFIX) - 1)); requestUriCopy.setUserId(u); //regDB-> // getUnexpiredContactsUserInstrument(requestUriCopy, instrumentp, timeNow, registrations); UtlString identity; requestUriCopy.getIdentity(identity); _dataStore.regDB().getUnexpiredContactsUserInstrument(identity.str(), instrumentp, timeNow, registrations); } else { // This is a ~~in~[instrument] URI. const char* instrumentp = user.data() + sizeof (URI_IN_PREFIX) - 1; _dataStore.regDB().getUnexpiredContactsInstrument(instrumentp, timeNow, registrations); } } else { // Note that getUnexpiredContactsUser will reduce the requestUri to its // identity (user/host/port) part before searching in the // database. The requestUri identity is matched against the // "identity" column of the database, which is the identity part of // the "uri" column which is stored in registration.xml. UtlString identity; requestUriCopy.getIdentity(identity); _dataStore.regDB().getUnexpiredContactsUser(identity.str(), timeNow, registrations); } int numUnexpiredContacts = registrations.size(); Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp got %d unexpired contacts", mLogName.data(), numUnexpiredContacts); // Check for a per-user call forward timer. // Don't set timer if we're not going to forward to voicemail. std::ostringstream userCfwdTimer; bool foundUserCfwdTimer = false; if (method.compareTo(SIP_INVITE_METHOD) == 0) { UtlString noRoute; requestUriCopy.getUrlParameter("sipx-noroute", noRoute); if ((!noRoute.isNull()) && (noRoute.compareTo("Voicemail") == 0)) { // This is not a call scenerio controlled by this users "forward to voicemail" timer } else { UtlString identity; requestUriCopy.getIdentity(identity); EntityRecord entity; foundUserCfwdTimer = _dataStore.entityDB().findByIdentity(identity.str(), entity); if (foundUserCfwdTimer) userCfwdTimer << entity.callForwardTime(); } } for (RegDB::Bindings::const_iterator iter = registrations.begin(); iter != registrations.end(); iter++) { // Query the Registration DB for the contact, expires and qvalue columns. Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp contact = '%s', qvalue = '%s', path = '%s'", mLogName.data(), iter->getContact().c_str(), iter->getQvalue().c_str(), iter->getPath().c_str() ); Url contactUri(iter->getContact().c_str()); // If available set the per-user call forward timer. if (foundUserCfwdTimer) { contactUri.setHeaderParameter("expires", userCfwdTimer.str().c_str()); } // If the contact URI is the same as the request URI, ignore it. if (!contactUri.isUserHostPortEqual(requestUriCopy)) { // Check if the q-value from the database is valid, and if so, // add it into contactUri. if (!iter->getQvalue().empty()) { // :TODO: (XPL-3) need a RegEx copy constructor here // Check if q value is numeric and between the range 0.0 and 1.0. static RegEx qValueValid("^(0(\\.\\d{0,3})?|1(\\.0{0,3})?)$"); if (qValueValid.Search(iter->getQvalue().c_str())) { contactUri.setFieldParameter(SIP_Q_FIELD, iter->getQvalue().c_str()); } } // Re-apply any grid parameter. if (gridPresent) { contactUri.setUrlParameter("grid", gridParameter); } contactUri.setUrlParameter(SIP_SIPX_CALL_DEST_FIELD, "INT"); // Check if database contained a Path value. If so, add a Route // header parameter to the contact with the Path vector taken from // the registration data. if (!iter->getPath().empty()) { UtlString existingRouteValue; std::string pathVector = iter->getPath(); if ( contactUri.getHeaderParameter(SIP_ROUTE_FIELD, existingRouteValue)) { // there is already a Route header parameter in the contact; append it to the // Route derived from the Path vector. pathVector += SIP_MULTIFIELD_SEPARATOR; pathVector += existingRouteValue.str(); } contactUri.setHeaderParameter(SIP_ROUTE_FIELD, pathVector.c_str()); } // Add the contact. contactList.add( contactUri, *this ); } } return RedirectPlugin::SUCCESS; }
UtlBoolean DialogEventPublisher::handleMessage(OsMsg& rMsg) { SipDialog sipDialog; UtlString sipDialogContent; Url requestUrl; UtlString entity; UtlString* pEntity; char dialogId[10]; SipDialogEvent* pThisCall; Dialog* pDialog; UtlString localTag, remoteTag; Url localIdentity, remoteIdentity; Url localTarget, remoteTarget; UtlString identity, displayName; OsTime receivedTime; int numOldContents; HttpBody* oldContent[1]; int length; UtlString dialogEvent; // React to telephony events if(rMsg.getMsgSubType()== TaoMessage::EVENT) { TaoMessage* taoMessage = (TaoMessage*)&rMsg; int taoEventId = taoMessage->getTaoObjHandle(); UtlString argList(taoMessage->getArgList()); TaoString arg(argList, TAOMESSAGE_DELIMITER); #ifdef DEBUGGING dumpTaoMessageArgs(taoEventId, arg) ; #endif UtlBoolean localConnection = atoi(arg[TAO_OFFER_PARAM_LOCAL_CONNECTION]); UtlString callId = arg[TAO_OFFER_PARAM_CALLID] ; UtlString address = arg[TAO_OFFER_PARAM_ADDRESS] ; switch (taoEventId) { case PtEvent::CONNECTION_OFFERED: mpCallManager->getSipDialog(callId, address, sipDialog); #ifdef DEBUGGING sipDialog.toString(sipDialogContent); OsSysLog::add(FAC_SIP, PRI_DEBUG, "DialogEventPublisher:: sipDialog = %s", sipDialogContent.data()); #endif sipDialog.getRemoteRequestUri(entity); OsSysLog::add(FAC_SIP, PRI_DEBUG, "DialogEventPublisher:: Call arrived: callId %s address %s requestUrl %s", callId.data(), address.data(), entity.data()); if (entity.isNull()) { OsSysLog::add(FAC_SIP, PRI_WARNING, "DialogEventPublisher:: Call arrived: callId %s address %s without requestUrl", callId.data(), address.data()); break; } else { requestUrl = Url(entity); requestUrl.getIdentity(entity); } // Create a dialog event if has not been created yet pThisCall = (SipDialogEvent *) mCalls.findValue(&entity); if (pThisCall == NULL) { pEntity = new UtlString(entity); pThisCall = new SipDialogEvent(STATE, entity); mCalls.insertKeyAndValue(pEntity, pThisCall); OsSysLog::add(FAC_SIP, PRI_DEBUG, "DialogEventPublisher:: insert DialogEvent object %p to the list", pThisCall); } // Create the dialog element sipDialog.getLocalField(localIdentity); localIdentity.getFieldParameter("tag", localTag); sipDialog.getRemoteField(remoteIdentity); remoteIdentity.getFieldParameter("tag", remoteTag); sprintf(dialogId, "%ld", mDialogId); mDialogId++; pDialog = new Dialog(dialogId, callId, localTag, remoteTag, "recipient"); pDialog->setState(STATE_EARLY, NULL, NULL); localIdentity.getIdentity(identity); localIdentity.getDisplayName(displayName); pDialog->setLocalIdentity(identity, displayName); remoteIdentity.getIdentity(identity); remoteIdentity.getDisplayName(displayName); pDialog->setRemoteIdentity(identity, displayName); sipDialog.getLocalContact(localTarget); pDialog->setLocalTarget(localTarget.toString()); sipDialog.getRemoteContact(remoteTarget); pDialog->setRemoteTarget(remoteTarget.toString()); pDialog->setDuration(OsDateTime::getSecsSinceEpoch()); pThisCall->insertDialog(pDialog); // Insert it into the active call list pThisCall->buildBody(); // Send the content to the subscribe server if (!mpSipPublishContentMgr->publish(entity.data(), DIALOG_EVENT_TYPE, DIALOG_EVENT_TYPE, 1, (HttpBody**)&pThisCall, 1, numOldContents, oldContent)) { pThisCall->getBytes(&dialogEvent, &length); OsSysLog::add(FAC_SIP, PRI_ERR, "DialogEventPublisher:: Call arrived - DialogEvent %s\n was not successfully published to the subscribe server", dialogEvent.data()); } break; case PtEvent::CONNECTION_ESTABLISHED: if (localConnection) { mpCallManager->getSipDialog(callId, address, sipDialog); #ifdef DEBUGGING sipDialog.toString(sipDialogContent); OsSysLog::add(FAC_SIP, PRI_DEBUG, "DialogEventPublisher:: sipDialog = %s", sipDialogContent.data()); #endif sipDialog.getRemoteRequestUri(entity); OsSysLog::add(FAC_SIP, PRI_DEBUG, "Call connected: callId %s address %s with request %s", callId.data(), address.data(), entity.data()); if (entity.isNull()) { OsSysLog::add(FAC_SIP, PRI_WARNING, "DialogEventPublisher:: Call connected: callId %s address %s without requestUrl", callId.data(), address.data()); break; } else { requestUrl = Url(entity); requestUrl.getIdentity(entity); } pThisCall = (SipDialogEvent *) mCalls.findValue(&entity); if (pThisCall == NULL) { pEntity = new UtlString(entity); pThisCall = new SipDialogEvent(STATE, entity); // Insert it into the active call list mCalls.insertKeyAndValue(pEntity, pThisCall); } // Get the new callId because it might be changed sipDialog.getCallId(callId); pDialog = pThisCall->getDialog(callId); // Update the dialog content if exist if (pDialog) { sipDialog.getLocalField(localIdentity); localIdentity.getFieldParameter("tag", localTag); sipDialog.getRemoteField(remoteIdentity); remoteIdentity.getFieldParameter("tag", remoteTag); pDialog->setTags(localTag, remoteTag); sipDialog.getLocalContact(localTarget); pDialog->setLocalTarget(localTarget.toString()); sipDialog.getRemoteContact(remoteTarget); pDialog->setRemoteTarget(remoteTarget.toString()); pDialog->setState(STATE_CONFIRMED, NULL, NULL); } else { // Create a new dialog element sipDialog.getLocalField(localIdentity); localIdentity.getFieldParameter("tag", localTag); sipDialog.getRemoteField(remoteIdentity); remoteIdentity.getFieldParameter("tag", remoteTag); sprintf(dialogId, "%ld", mDialogId); mDialogId++; pDialog = new Dialog(dialogId, callId, localTag, remoteTag, "recipient"); pDialog->setState(STATE_CONFIRMED, NULL, NULL); localIdentity.getIdentity(identity); localIdentity.getDisplayName(displayName); pDialog->setLocalIdentity(identity, displayName); remoteIdentity.getIdentity(identity); remoteIdentity.getDisplayName(displayName); pDialog->setRemoteIdentity(identity, displayName); sipDialog.getLocalContact(localTarget); pDialog->setLocalTarget(localTarget.toString()); sipDialog.getRemoteContact(remoteTarget); pDialog->setRemoteTarget(remoteTarget.toString()); pDialog->setDuration(OsDateTime::getSecsSinceEpoch()); pThisCall->insertDialog(pDialog); } pThisCall->buildBody(); // Publish the content to the subscribe server if (!mpSipPublishContentMgr->publish(entity.data(), DIALOG_EVENT_TYPE, DIALOG_EVENT_TYPE, 1, (HttpBody**)&pThisCall, 1, numOldContents, oldContent)) { pThisCall->getBytes(&dialogEvent, &length); OsSysLog::add(FAC_SIP, PRI_ERR, "DialogEventPublisher:: Call connected - DialogEvent %s\n was not successfully published to the subscribe server", dialogEvent.data()); } } break; case PtEvent::CONNECTION_DISCONNECTED: if (!localConnection) { mpCallManager->getSipDialog(callId, address, sipDialog); #ifdef DEBUGGING sipDialog.toString(sipDialogContent); OsSysLog::add(FAC_SIP, PRI_DEBUG, "DialogEventPublisher:: sipDialog = %s", sipDialogContent.data()); #endif sipDialog.getLocalContact(requestUrl); requestUrl.getIdentity(entity); OsSysLog::add(FAC_SIP, PRI_DEBUG, "Call dropped: %s address %s with entity %s", callId.data(), address.data(), entity.data()); if (entity.isNull()) { OsSysLog::add(FAC_SIP, PRI_WARNING, "DialogEventPublisher:: Call dropped: callId %s address %s without requestUrl", callId.data(), address.data()); break; } // Get the new callId because it might be changed sipDialog.getCallId(callId); // Remove the call from the pool and clean up the call pThisCall = (SipDialogEvent *) mCalls.findValue(&entity); if (pThisCall) { pDialog = pThisCall->getDialog(callId); if (pDialog) { pDialog->setState(STATE_TERMINATED, NULL, NULL); pThisCall->buildBody(); // Publish the content to the subscribe server if (!mpSipPublishContentMgr->publish(entity.data(), DIALOG_EVENT_TYPE, DIALOG_EVENT_TYPE, 1, (HttpBody**)&pThisCall, 1, numOldContents, oldContent)) { pThisCall->getBytes(&dialogEvent, &length); OsSysLog::add(FAC_SIP, PRI_ERR, "DialogEventPublisher:: Call dropped - DialogEvent %s\n was not successfully published to the subscribe server", dialogEvent.data()); } // Remove the dialog from the dialog event package pDialog = pThisCall->removeDialog(pDialog); delete pDialog; } if (pThisCall->isEmpty()) { // Unpublisher the content from the subscribe server if (!mpSipPublishContentMgr->unpublish(entity.data(), DIALOG_EVENT_TYPE, DIALOG_EVENT_TYPE, 1, numOldContents, oldContent)) { pThisCall->getBytes(&dialogEvent, &length); OsSysLog::add(FAC_SIP, PRI_ERR, "DialogEventPublisher:: Call dropped - DialogEvent %s\n was not successfully unpublished to the subscribe server", dialogEvent.data()); } UtlContainable *foundValue; mCalls.removeKeyAndValue(pEntity, foundValue); if (foundValue) { OsSysLog::add(FAC_SIP, PRI_DEBUG, "DialogEventPublisher:: remove DialogEvent object %p from the list", pThisCall); pThisCall = (SipDialogEvent *) foundValue; delete pThisCall; delete pEntity; } } } else { OsSysLog::add(FAC_SIP, PRI_ERR, "DialogEventPublisher:: Call dropped - no entity %s founded in the active call list", entity.data()); } } break; case PtEvent::CONNECTION_FAILED: OsSysLog::add(FAC_SIP, PRI_WARNING, "Connection failed on call: %s", callId.data()); break; } } return(TRUE); }
bool SipDialogMonitor::addExtension(UtlString& groupName, Url& contactUrl) { bool result = false; mLock.acquire(); // Check whether the group already exists. If not, create one. SipResourceList* list = dynamic_cast <SipResourceList *> (mMonitoredLists.findValue(&groupName)); if (list == NULL) { UtlString* listName = new UtlString(groupName); list = new SipResourceList((UtlBoolean)TRUE, listName->data(), DIALOG_EVENT_TYPE); mMonitoredLists.insertKeyAndValue(listName, list); OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::addExtension insert listName %s and object %p to the resource list", groupName.data(), list); } // Check whether the contact has already been added to the group. UtlString resourceId; contactUrl.getIdentity(resourceId); Resource* resource = list->getResource(resourceId); if (resource == NULL) { // If not, add it. resource = new Resource(resourceId); UtlString userName; contactUrl.getDisplayName(userName); resource->setName(userName); UtlString id; NetMd5Codec::encode(resourceId, id); resource->setInstance(id, STATE_PENDING); list->insertResource(resource); // Set up the subscription to the URI. OsSysLog::add(FAC_LOG, PRI_DEBUG, "SipDialogMonitor::addExtension Sending out the SUBSCRIBE to contact %s", resourceId.data()); UtlString toUrl; contactUrl.toString(toUrl); UtlString fromUri = "dialogMonitor@" + mDomainName; UtlString earlyDialogHandle; UtlBoolean status = mpSipSubscribeClient->addSubscription(resourceId.data(), DIALOG_EVENT_TYPE, DIALOG_EVENT_CONTENT_TYPE, fromUri.data(), toUrl.data(), mContact.data(), mRefreshTimeout, (void *) this, SipDialogMonitor::subscriptionStateCallback, SipDialogMonitor::notifyEventCallback, earlyDialogHandle); if (!status) { result = false; OsSysLog::add(FAC_LOG, PRI_ERR, "SipDialogMonitor::addExtension Subscription failed to contact %s.", resourceId.data()); } else { mDialogHandleList.insertKeyAndValue(new UtlString(resourceId), new UtlString(earlyDialogHandle)); createDialogState(&earlyDialogHandle); OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::addExtension Added earlyDialogHandle: %s", earlyDialogHandle.data()); result = true; } } else { OsSysLog::add(FAC_LOG, PRI_WARNING, "SipDialogMonitor::addExtension contact %s already exists.", resourceId.data()); } int dummy; list->buildBody(dummy); mLock.release(); return result; }
bool SipDialogMonitor::removeExtension(UtlString& groupName, Url& contactUrl) { bool result = false; mLock.acquire(); // Check whether the group exists or not. If not, return false. SipResourceList* list = dynamic_cast <SipResourceList *> (mMonitoredLists.findValue(&groupName)); if (list == NULL) { OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::removeExtension group %s does not exist", groupName.data()); } else { // Check whether the contact exists in the group or not. UtlString resourceId; contactUrl.getIdentity(resourceId); Resource* resource = list->getResource(resourceId); if (resource) { // If it exists, get the early dialog handle for the SUBSCRIBE, // which specifies all of its subscriptions. UtlString* earlyDialogHandle = dynamic_cast <UtlString *> (mDialogHandleList.findValue(&resourceId)); if (earlyDialogHandle) { OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::removeExtension Calling endSubscription(%s)", earlyDialogHandle->data()); // Terminate the subscription. UtlBoolean status = mpSipSubscribeClient->endSubscription(earlyDialogHandle->data()); if (!status) { OsSysLog::add(FAC_SIP, PRI_ERR, "SipDialogMonitor::removeExtension Unsubscription failed for %s.", resourceId.data()); } // Remove the remembered state for dialog event notices. destroyDialogState(earlyDialogHandle); } else { OsSysLog::add(FAC_SIP, PRI_ERR, "SipDialogMonitor::removeExtension no dialogHandle for %s.", resourceId.data()); } // Now delete all the references to this URI. mDialogHandleList.destroy(&resourceId); resource = list->removeResource(resource); delete resource; result = true; } else { OsSysLog::add(FAC_LOG, PRI_WARNING, "SipDialogMonitor::removeExtension subscription for contact %s does not exists.", resourceId.data()); } } mLock.release(); return result; }