⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sipimpliedsubscriptions.cpp

📁 sip协议站
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                    ,"%s::readConfig name=\"%s\" recognizer=\"%s\""                    ,mLogName.data(), name.data(), recognizer.data()                    );      configuredUserAgents.add( name, recognizer, mLogName );    }}/** * doImpliedSubscriptions checks for characteristics in the REGISTER message *    that imply that a subscription needs to be requested on behalf of the *    party doing the registration, and then invokes the appropriate subscription *    request method. */void SipImpliedSubscriptions::takeAction(    const SipMessage&   registerMessage  ///< the successful registration   ,const unsigned int  registrationDuration /**< the actual allowed                                              * registration time (note                                              * that this may be < the                                              * requested time). */   ,SipUserAgent*       sipUserAgent     /**< to be used if the plugin                                          *   wants to send any SIP msg */                                         ){   if ( needsImpliedSubscription( registerMessage ) )   {      OsSysLog::add( FAC_SIP, PRI_DEBUG                    ,"%s requesting mwi subscription duration=%d"                    ,mLogName.data(), registrationDuration                    );      // This phone - accepts message waiting notifies,      // but don't subscribe to them, so we'll do it for them.      SipMessage subscribeRequest;      UtlString  callId;      UtlString  fromTag;      UtlString  fromUri;      buildSubscribeRequest( registerMessage, registrationDuration                            ,subscribeRequest, callId, fromTag, fromUri                            );      authenticate( registerMessage, subscribeRequest, callId, fromTag, fromUri );      sipUserAgent->send( subscribeRequest, NULL, NULL );   }}bool SipImpliedSubscriptions::needsImpliedSubscription( const SipMessage& registerMessage ){   bool configuredForSubscription = false;            UtlString userAgent;   ImpliedSubscriptionUserAgent* configured;   registerMessage.getUserAgentField( &userAgent );   OsSysLog::add( FAC_SIP, PRI_DEBUG                 ,"%s checking User-Agent \"%s\""                 ,mLogName.data(), userAgent.data()                 );            configured = configuredUserAgents.configurationName( userAgent, mLogName );   if ( configured ) // ? did we find a configuration name whose recognizer matched ?   {      configuredForSubscription = true;      OsSysLog::add( FAC_SIP, PRI_INFO                    ,"%s User-Agent \"%s\" matched rule \"%s%s\""                    ,mLogName.data()                    ,userAgent.data()                    ,ConfigPrefix                    ,configured->data()                    );   }   return configuredForSubscription;}   void SipImpliedSubscriptions::buildSubscribeRequest( const SipMessage& registerMessage                           ,int duration                           ,SipMessage& subscribeRequest                           ,UtlString&  callId                           ,UtlString&  fromTag                           ,UtlString&  fromUri                           ){   UtlString registrationValue;   UtlString tagNameValuePair;   UtlString contactUri;   int      sequenceNumber = 0;   // Get the From URL, and change the tag   Url fromUrl;   registerMessage.getFromUrl( fromUrl );   fromUrl.removeFieldParameter("tag"); // discard from tag from REGISTER   registerMessage.getFromUri( &fromUri );   (void) registerMessage.getContactUri(0, &contactUri);   (void) registerMessage.getCSeqField(&sequenceNumber, &registrationValue);   Url toUrl;   registerMessage.getToUrl( toUrl );   toUrl.removeFieldParameter("tag");      UtlString toUri;   registerMessage.getToUri( &toUri );   registerMessage.getCallIdField( &callId );   callId.prepend("implied-mwi-");   // Build a from tag for the SUBSCRIBE   //   - hash the call id so that it will be the same on each refresh   UtlString callIdHash;   NetMd5Codec::encode( callId.data(), callIdHash );   fromUrl.setFieldParameter("tag", callIdHash.data() );   fromTag = callIdHash; // for constructing the nonce   subscribeRequest.setVoicemailData( fromUrl.toString() // From:                                     ,toUrl.toString()   // To:                                     ,toUri.data()       // request URI                                     ,contactUri.data()  // taken from registration                                     ,callId.data()                                     ,++sequenceNumber                                     ,duration                                     );   /*    * Rewrite the event field to add our extension parameter to    * ensure that the registration and subscription are synchronized.    */   const char* standardEventHeader = subscribeRequest.getHeaderValue(0, SIP_EVENT_FIELD);   UtlString extendedEventHeader(standardEventHeader);   extendedEventHeader.append(";" SIPX_IMPLIED_SUB "=");   char durationString[12];   sprintf(durationString, "%d", duration);   extendedEventHeader.append(durationString);   subscribeRequest.setHeaderValue(SIP_EVENT_FIELD, extendedEventHeader.data(), 0);}void SipImpliedSubscriptions::authenticate( const SipMessage& registerMessage                                           ,SipMessage& subscribeRequest                                           ,UtlString&  callId                                           ,UtlString&  fromTag                                           ,UtlString&  fromUri                                           ){   // Construct authentication that the status server will accept   // We need the user credentials, and a signed nonce like the one   //    the status server would have generated to challenge this phone.   UtlString user;   UtlString realm;   UtlString registrationNonce;   UtlString opaque;   UtlString response;   UtlString authUri;   // extract the identity from the authorization of the registration   if ( registerMessage.getDigestAuthorizationData( &user, &realm       // the identity                                                   ,NULL // request nonce not used                                                   ,&opaque // passed through to aid debugging                                                   ,NULL, NULL // response & authUri not used                                                   ,HttpMessage::SERVER, 0                                                   )       )   {      Url subscribeUser;      UtlString passToken;      UtlString authType;      if (CredentialDB::getInstance()->getCredential( user, realm, subscribeUser                                                     ,passToken, authType                                                     )          )      {         // Construct a nonce         UtlString serverNonce;         UtlString clientNonce;         SipNonceDb* nonceDb = SharedNonceDb::get();         nonceDb->createNewNonce( callId, fromTag, fromUri, realm ,serverNonce );         // generate a client nonce - doesn't matter what it is, really         //   because the server doesn't validate this one;         //   but change an input so that the two won't be the same         //              UtlString dummyFromTag("different value");         //              mRegistrarNonceDb.createNewNonce( callId, dummyFromTag, fromUri         //                                               ,clientNonce         //                               );         // Sign the message         UtlString responseHash;         HttpMessage::buildMd5Digest(passToken.data(),                                     HTTP_MD5_ALGORITHM,                                     serverNonce.data(),                                     NULL, // client nonce                                     1, // nonce count                                     "",                                     SIP_SUBSCRIBE_METHOD,                                     fromUri.data(),                                     NULL,                                     &responseHash                                     );         subscribeRequest.removeHeader( HTTP_AUTHORIZATION_FIELD, 0);         subscribeRequest.setDigestAuthorizationData(user.data(),                                                     realm.data(),                                                     serverNonce.data(),                                                     fromUri.data(),                                                     responseHash.data(),                                                     HTTP_MD5_ALGORITHM,                                                     NULL,//clientNonce.data(),                                                     opaque.data(),                                                     HTTP_QOP_AUTH,                                                     1, // nonce count                                                     HttpMessage::SERVER                                                     );      }      else      {         OsSysLog::add( FAC_SIP, PRI_WARNING,                       "%s implied subscription request not authenticated:\n"                       "   no credentials found for \"%s\"",                       mLogName.data(), user.data());      }   }   else   {      OsSysLog::add( FAC_SIP, PRI_WARNING,                    "%s implied subscription request not authenticated:\n"                    "   no credentials in registration",                    mLogName.data()                    );   }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -