Example #1
0
UtlBoolean SipSubscribeServer::handleSubscribe(const SipMessage& subscribeRequest)
{
    UtlBoolean handledSubscribe = FALSE;
    UtlString eventName;
    subscribeRequest.getEventField(&eventName, NULL);

    // Not modifying the SubscribeServerEventData, just reading it
    lockForRead();

    // Get the event specific handler and information
    SubscribeServerEventData* eventPackageInfo =
       dynamic_cast <SubscribeServerEventData*> (mEventDefinitions.find(&eventName));

    // We handle this event type
    if (eventPackageInfo)
    {
        handledSubscribe = TRUE;
        SipSubscribeServerEventHandler* handler =
            eventPackageInfo->mpEventSpecificHandler;

        SipMessage subscribeResponse;

        // Check if authenticated (or if it needs to be authenticated)
        if (handler->isAuthenticated(subscribeRequest,
                                     subscribeResponse))
        {
            // Check if authorized (or if authorization is required)
            if (handler->isAuthorized(subscribeRequest,
                                     subscribeResponse))
            {
                // The subscription is allowed, so update the
                // subscription state.  Set the To field tag if
                // this request initiated the dialog
                UtlString subscribeDialogHandle;
                UtlBoolean isNewDialog;
                UtlBoolean isExpiredSubscription;
                UtlString resourceId, eventTypeKey, eventType;
                eventPackageInfo->mpEventSpecificSubscriptionMgr->
                   updateDialogInfo(
                      subscribeRequest,
                      resourceId,
                      eventTypeKey,
                      eventType,
                      subscribeDialogHandle,
                      isNewDialog,
                      isExpiredSubscription,
                      subscribeResponse,
                      // The event-specific handler provides a getKeys method
                      // which is used to determine the resource ID
                      // and event type if this is a new subscription.
                      *handler);

                 // Build a NOTIFY
                 SipMessage notifyRequest;

                 // Set the dialog information into the NOTIFY.
                 // Note that the dialog can have ended by now, because of
                 // a race condition with the processing of dialog-ending
                 // messages from the outside world.
                 if (eventPackageInfo->mpEventSpecificSubscriptionMgr->
                     getNotifyDialogInfo(subscribeDialogHandle,
                                         notifyRequest,
                                         "active;expires=%ld"))
                 {
                    // We still have record of the dialog, so the
                    // NOTIFY headers were set.

                    // Set the NOTIFY content
                    UtlString acceptHeaderValue;
                    if (!subscribeRequest.getAcceptField(acceptHeaderValue))
                    {
                       // No Accept header seen, set special value allowing any
                       // content type.
                       acceptHeaderValue = SipPublishContentMgr::acceptAllTypes;
                    }
                    // Note that since this NOTIFY is due to a SUBSCRIBE,
                    // it should contain 'full' content.  Hence,
                    // the fullState parameter of getNotifyContent is TRUE,
                    // and is not taken from
                    // eventPackageInfo->mEventSpecificFullState.
                    UtlString availableMediaTypes;
                    if (handler->getNotifyContent(resourceId,
                                                  eventTypeKey,
                                                  eventType,
                                                  *(eventPackageInfo->mpEventSpecificContentMgr),
                                                  acceptHeaderValue,
                                                  notifyRequest,
                                                  TRUE,
                                                  &availableMediaTypes))
                    {
                       // Update the NOTIFY content if required for this event type.
                       // Sets 'version' and 'eventTypeKey'.
                       int version;
                       eventPackageInfo->mpEventSpecificSubscriptionMgr->
                          updateNotifyVersion(eventPackageInfo->mpEventSpecificContentVersionCallback,
                                              notifyRequest,
                                              version,
                                              eventTypeKey);

                       // Update the saved record of the NOTIFY CSeq and the
                       // XML version number for the specified eventTypeKey,
                       // as needed by the subscription manager.
                       // In practice, this is only used by SipPersistentSubscriptionMgr
                       // to write the NOTIFY Cseq and XML version into the IMDB.
                       eventPackageInfo->mpEventSpecificSubscriptionMgr->
                          updateVersion(notifyRequest, version, eventTypeKey);

                       // Send the NOTIFY request
                       setContact(&notifyRequest);
                       eventPackageInfo->mpEventSpecificUserAgent->send(notifyRequest);

                       if (OsSysLog::willLog(FAC_SIP, PRI_INFO))
                       {
                          UtlString requestContact;
                          subscribeRequest.getContactField(0, requestContact);
                          OsSysLog::add(FAC_SIP, PRI_INFO,
                              "SipSubscribeServer::handleSubscribe: %s has setup subscription to %s, eventTypeKey %s",
                              requestContact.data(), resourceId.data(), eventTypeKey.data());
                       }
                    }
                    else
                    {
                       // No content was available, so the subscription fails.

                       // Determine the reason and set the response code.
                       if (availableMediaTypes.isNull())
                       {
                          // No MIME types are available, so the resource does not exist.
                          subscribeResponse.setResponseFirstHeaderLine(SIP_PROTOCOL_VERSION,
                                                                       SIP_NOT_FOUND_CODE,
                                                                       SIP_NOT_FOUND_TEXT);
                       }
                       else
                       {
                          // MIME types are available, so the resource exists.
                          subscribeResponse.setResponseFirstHeaderLine(SIP_PROTOCOL_VERSION,
                                                                       SIP_BAD_MEDIA_CODE,
                                                                       SIP_BAD_MEDIA_TEXT);
                          subscribeResponse.setAcceptField(availableMediaTypes);
                       }

                       // Destroy the subscription.
                       eventPackageInfo->mpEventSpecificSubscriptionMgr->
                          endSubscription(subscribeDialogHandle,
                                          SipSubscriptionMgr::subscriptionTerminated);

                       // Do not send the NOTIFY.
                    }
                 }
                 else
                 {
                    // Oops, the subscription was destroyed while we looked.
                    OsSysLog::add(FAC_SIP, PRI_WARNING,
                                  "SipSubscribeServer::handleSubscribe "
                                  "subscription '%s' vanished while being processed",
                                  subscribeDialogHandle.data());
                 }

                 // Send the response ASAP to minimize resending.
                 setContact(&subscribeResponse);
                 eventPackageInfo->mpEventSpecificUserAgent->send(subscribeResponse);
            }
            // Not authorized
            else
            {
                // Send the response that was prepared by ::isAuthorized().
                setContact(&subscribeResponse);
                eventPackageInfo->mpEventSpecificUserAgent->send(subscribeResponse);
            }
        }

        // Not authenticated
        else
        {
            // Send the response that was prepared by ::isAuthenticated().
            setContact(&subscribeResponse);
            eventPackageInfo->mpEventSpecificUserAgent->send(subscribeResponse);
        }
    }

    // We should not have received SUBSCRIBE requests for this event type.
    // This event type has not been enabled in this SubscribeServer.
    else
    {
        OsSysLog::add(FAC_SIP, PRI_ERR,
            "SipSubscribeServer::handleSubscribe event type: %s not enabled",
            eventName.data());

        SipMessage eventTypeNotHandled;
        eventTypeNotHandled.setResponseData(&subscribeRequest,
                                            SIP_BAD_EVENT_CODE,
                                            SIP_BAD_EVENT_TEXT);

        setContact(&eventTypeNotHandled);
        mpDefaultUserAgent->send(eventTypeNotHandled);
    }
    unlockForRead();

    return(handledSubscribe);
}
UtlBoolean SipSubscribeServer::handleSubscribe(const SipMessage& subscribeRequest)
{
    UtlBoolean handledSubscribe = FALSE;
    UtlString eventName;
    subscribeRequest.getEventField(&eventName, NULL);

    // Not modifying the SubscribeServerEventData, just reading it
    lockForRead();

    // Get the event specific handler and information
    SubscribeServerEventData* eventPackageInfo = (SubscribeServerEventData*)
        mEventDefinitions.find(&eventName);

    // We handle this event type
    if(eventPackageInfo)
    {
        handledSubscribe = TRUE;
        UtlString resourceId;
        UtlString eventTypeKey, eventType;
        SipSubscribeServerEventHandler* handler =
            eventPackageInfo->mpEventSpecificHandler;

        // Get the keys used to identify the event state content
        handler->getKeys(subscribeRequest,
                         resourceId,
                         eventTypeKey,
                         eventType);

        SipMessage subscribeResponse;

        // Check if authenticated (or if it needs to be authenticated)
        if(handler->isAuthenticated(subscribeRequest,
                                     resourceId,
                                     eventTypeKey,
                                     subscribeResponse))
        {
            // Check if authorized (or if authorization is required)
            if(handler->isAuthorized(subscribeRequest,
                                     resourceId,
                                     eventTypeKey,
                                     subscribeResponse))
            {
                // The subscription is allowed, so update the
                // subscription state.  Set the To field tag if
                // this request initiated the dialog
                UtlString subscribeDialogHandle;
                UtlBoolean isNewDialog;
                UtlBoolean isExpiredSubscription;
                eventPackageInfo->mpEventSpecificSubscriptionMgr->updateDialogInfo(
                                                            subscribeRequest,
                                                            resourceId, 
                                                            eventTypeKey, 
                                                            getMessageQueue(),
                                                            subscribeDialogHandle, 
                                                            isNewDialog, 
                                                            isExpiredSubscription,
                                                            subscribeResponse);

                // Send the response ASAP to minimize resend handling of request
                 eventPackageInfo->mpEventSpecificUserAgent->send(subscribeResponse);

                 // Build a NOTIFY
                 SipMessage notifyRequest;

                 // Set the dialog information
                 eventPackageInfo->mpEventSpecificSubscriptionMgr->getNotifyDialogInfo(subscribeDialogHandle,
                                                                    notifyRequest);

                 // Set the NOTIFY content
                 UtlString acceptHeaderValue;
                 subscribeRequest.getAcceptField(acceptHeaderValue);
                 handler->getNotifyContent(resourceId, 
                                           eventTypeKey, 
                                           eventType, 
                                           *(eventPackageInfo->mpEventSpecificContentMgr),
                                           acceptHeaderValue,
                                           notifyRequest);

                 // Send the notify request
                 eventPackageInfo->mpEventSpecificUserAgent->send(notifyRequest);
            }
            // Not authorized
            else
            {
                // Send the response
                eventPackageInfo->mpEventSpecificUserAgent->send(subscribeResponse);
            }
        }

        // Not authenticated
        else
        {
            // Send the response
            eventPackageInfo->mpEventSpecificUserAgent->send(subscribeResponse);
        }
    }


    // We should not have received SUBSCRIBE requests for this event type
    // This event type has not been enabled in this SubscribeServer
    else
    {
        OsSysLog::add(FAC_SIP, PRI_ERR, 
            "SipSubscribeServer::handleSubscribe event type: %s not enabled",
            eventName.data());

        SipMessage eventTypeNotHandled;
        eventTypeNotHandled.setResponseData(&subscribeRequest,
            SIP_BAD_EVENT_CODE, SIP_BAD_EVENT_TEXT);

        mpDefaultUserAgent->send(eventTypeNotHandled);
    }
    unlockForRead();

    return(handledSubscribe);
}