📄 sipimpliedsubscriptions.cpp
字号:
,"%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, ®istrationValue); 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 + -