Пример #1
0
//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;
}
Пример #2
0
/* ============================ 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();

}