//functions UtlBoolean SubscribeServerThread::handleMessage(OsMsg& eventMessage) { // Only handle SIP messages if (eventMessage.getMsgType() != OsMsg::PHONE_APP || eventMessage.getMsgSubType() != SipMessage::NET_SIP_MESSAGE) { return FALSE ; } const SipMessage* message = ((SipMessageEvent&)eventMessage).getMessage(); UtlString userKey; UtlString uri; SipMessage finalResponse; // Test for request/response processing code path if (!message->isResponse()) { // this is a request, so authenticate and authorize the request if ( isValidDomain( message, &finalResponse ) ) { UtlString eventPackage; UtlString id; UtlHashMap otherParams; message->getEventField(&eventPackage, &id, &otherParams); StatusPluginReference* pluginContainer = mPluginTable->getPlugin( eventPackage ); if( pluginContainer ) { //check in credential database if authentication needed UtlString authenticatedUser, authenticatedRealm; if( isAuthenticated ( message, &finalResponse, authenticatedUser, authenticatedRealm ) ) { if ( isAuthorized ( message, &finalResponse, pluginContainer ) ) { // fetch the plugin SubscribeServerPluginBase* plugin = pluginContainer->getPlugin(); if (plugin) { int timeNow = (int)OsDateTime::getSecsSinceEpoch(); int grantedExpiration; UtlString newToTag; // add the subscription to the IMDB SubscribeStatus isSubscriptionAdded = addSubscription(timeNow, message, mDefaultDomain, eventPackage, id, otherParams, newToTag, grantedExpiration); otherParams.destroyAll(); switch ( isSubscriptionAdded ) { case STATUS_SUCCESS: // create response - 202 Accepted Response finalResponse.setResponseData( message, SIP_ACCEPTED_CODE, SIP_ACCEPTED_TEXT); // Set the granted subscription time. finalResponse.setExpiresField(grantedExpiration); plugin->handleSubscribeRequest( *message, finalResponse, authenticatedUser.data(), authenticatedRealm.data(), mDefaultDomain.data()); // ensure that the contact returned will route back to here // (the default supplied by SipUserAgent will not). { UtlString requestUri; message->getRequestUri(&requestUri); finalResponse.setContactField(requestUri); } break; case STATUS_TO_BE_REMOVED: // create response - 202 Accepted Response finalResponse.setResponseData( message, SIP_ACCEPTED_CODE, SIP_ACCEPTED_TEXT); // Set the granted subscription time. finalResponse.setExpiresField(grantedExpiration); plugin->handleSubscribeRequest( *message, finalResponse, authenticatedUser.data(), authenticatedRealm.data(), mDefaultDomain.data()); // ensure that the contact returned will route back to here // (the default supplied by SipUserAgent will not). { UtlString requestUri; message->getRequestUri(&requestUri); finalResponse.setContactField(requestUri); } // Now that final NOTIFY has been sent, remove row removeSubscription(message); break; case STATUS_LESS_THAN_MINEXPIRES: // (already logged in addSubscription) // send 423 Subscription Too Brief response finalResponse.setResponseData( message, SIP_TOO_BRIEF_CODE, SIP_TOO_BRIEF_TEXT ); finalResponse.setHeaderValue( SIP_MIN_EXPIRES_FIELD, mMinExpiresTimeStr, 0 ); break; case STATUS_INVALID_REQUEST: OsSysLog::add(FAC_SIP, PRI_ERR, "SubscribeServerThread::handleMessage()" "Subscription Could Not Be Added " SIP_BAD_REQUEST_TEXT ); finalResponse.setResponseData( message, SIP_BAD_REQUEST_CODE, SIP_BAD_REQUEST_TEXT ); break; case STATUS_FORBIDDEN: OsSysLog::add(FAC_SIP, PRI_ERR, "SubscribeServerThread::handleMessage()" "Subscription Could Not Be Added " SIP_FORBIDDEN_TEXT ); finalResponse.setResponseData( message, SIP_FORBIDDEN_CODE, SIP_FORBIDDEN_TEXT); break; case STATUS_NOT_FOUND: OsSysLog::add(FAC_SIP, PRI_ERR, "SubscribeServerThread::handleMessage()" "Subscription Could Not Be Added " SIP_NOT_FOUND_TEXT ); finalResponse.setResponseData( message, SIP_NOT_FOUND_CODE, SIP_NOT_FOUND_TEXT ); break; case STATUS_BAD_SUBSCRIPTION: // send 481 Subscription Does Not Exist response OsSysLog::add(FAC_SIP, PRI_DEBUG, "SubscribeServerThread::handleMessage()" "Subscription to be renewed does not exist " SIP_BAD_SUBSCRIPTION_TEXT ); finalResponse.setResponseData( message, SIP_BAD_SUBSCRIPTION_CODE, SIP_BAD_SUBSCRIPTION_TEXT ); break; case STATUS_INTERNAL_ERROR: default: OsSysLog::add(FAC_SIP, PRI_ERR, "SubscribeServerThread::handleMessage()" "Subscription Could Not Be Added " "Status %d from addSubscription", isSubscriptionAdded ); finalResponse.setResponseData( message, SIP_SERVER_INTERNAL_ERROR_CODE, "Subscription database error" ); } // Apply the new to-tag, if any, to the response. if (!newToTag.isNull()) { finalResponse.setToFieldTag(newToTag); } } else { OsSysLog::add(FAC_SIP, PRI_CRIT, "SubscribeServerThread::handleMessage()" " container->getPlugin failed for '%s'", eventPackage.data() ); finalResponse.setResponseData( message, SIP_SERVER_INTERNAL_ERROR_CODE, SIP_SERVER_INTERNAL_ERROR_TEXT ); } } else { // not authorized - the response was created in isAuthorized } } else { // not authenticated - the response was created in isAuthenticated } } else // no plugin found for this event type { OsSysLog::add(FAC_SIP, PRI_WARNING, "SubscribeServerThread::handleMessage()" " Request denied - " SIP_BAD_EVENT_TEXT ); finalResponse.setResponseData( message, SIP_BAD_EVENT_CODE, "Event type not supported" ); } // send final response UtlString finalMessageStr; ssize_t finalMessageLen; finalResponse.getBytes(&finalMessageStr, &finalMessageLen); OsSysLog::add(FAC_SIP, PRI_DEBUG, "\n----------------------------------\n" "Sending final response\n%s",finalMessageStr.data()); mpSipUserAgent->setUserAgentHeader( finalResponse ); mpSipUserAgent->send( finalResponse ); } else // Invalid domain { const char* notFoundMsg = SIP_NOT_FOUND_TEXT " Invalid Domain"; finalResponse.setResponseData(message, SIP_NOT_FOUND_CODE, notFoundMsg ); mpSipUserAgent->setUserAgentHeader( finalResponse ); mpSipUserAgent->send( finalResponse ); } } else // response { // The server may send us back a "481" response, if it does we need // to remove the subscription from the SubscriptionDB as the callid // that it corresponds to is stale (probably the phone was rebooted) // In the above case, RFC 3265 says we MUST remove the subscription. // It also says (essentially) that any error that does not imply a retry // SHOULD remove the subscription. We will interpret this to be any // 4xx code _except_ 408 timeout (because that may be a transient error). int responseCode = message->getResponseStatusCode(); if ( responseCode >= SIP_4XX_CLASS_CODE && responseCode != SIP_REQUEST_TIMEOUT_CODE ) { // remove the subscription removeErrorSubscription ( *message ); } } return TRUE; }
/* ============================ ACCESSORS ================================= */ void WebServer::ProcessEvent( const HttpRequestContext& requestContext, const HttpMessage& request, HttpMessage*& response ) { // get the action type (used to be the event) UtlString event; response = new HttpMessage(); ssize_t len; UtlString httpString; SubscribeServerPluginBase* plugin = NULL; request.getBytes(&httpString , &len); Os::Logger::instance().log(FAC_SIP, PRI_INFO, "WebServer::ProcessEvent HttpEvent \n%s", httpString.data()); // get the ACTION CGI variable requestContext.getCgiVariable( EVENTTYPE, event ); if( !event.isNull()) { //according to event type , get the correct plugin from spPluginTable StatusPluginReference* pluginContainer = spPluginTable->getPlugin(event); if(pluginContainer) { plugin = pluginContainer->getPlugin(); if(plugin) { // send 200 ok reply. response->setResponseFirstHeaderLine ( HTTP_PROTOCOL_VERSION, HTTP_OK_CODE, HTTP_OK_TEXT ); //call the event handler for the plugin plugin->handleEvent(requestContext, request, *response); } else { Os::Logger::instance().log(FAC_SIP, PRI_ERR, "WebServer::ProcessEvent no plugin in container for event type '%s'", event.data() ); } } else { Os::Logger::instance().log(FAC_SIP, PRI_WARNING, "WebServer::ProcessEvent no plugin found for event type '%s'", event.data() ); } } else { Os::Logger::instance().log(FAC_SIP, PRI_WARNING, "WebServer::ProcessEvent no '" EVENTTYPE "' variable found" ); } // We did not find a plugin so nobody handled this request. if(plugin == NULL) { response->setResponseFirstHeaderLine ( HTTP_PROTOCOL_VERSION, HTTP_FILE_NOT_FOUND_CODE, HTTP_FILE_NOT_FOUND_TEXT ); } Os::Logger::instance().flush(); }