Пример #1
0
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;
}
Пример #2
0
/// 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()); 
   }
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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);
    }
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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;   
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #12
0
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;
}
Пример #13
0
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);
    }
}
Пример #14
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;
}
Пример #15
0
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);
    }
}
Пример #16
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;   
}
Пример #17
0
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;
}
Пример #18
0
/// 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");
    }
}
Пример #19
0
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;
}
Пример #20
0
/// 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;
}
Пример #21
0
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;
}
Пример #22
0
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;
}
Пример #23
0
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;
}
Пример #24
0
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;
} 
Пример #25
0
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;
}
Пример #27
0
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;
}
Пример #28
0
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);
}
Пример #29
0
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;
}
Пример #30
0
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;   
}