diff -r 000000000000 -r f5a58ecadc66 servicediscoveryandcontrol/pnp/test/upnp/Server/ServicePoint/src/upnpservicescpractivities.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servicediscoveryandcontrol/pnp/test/upnp/Server/ServicePoint/src/upnpservicescpractivities.cpp Tue Feb 02 01:12:20 2010 +0200 @@ -0,0 +1,1090 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// @file +// @internalComponent +// +// + +//System Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include "upnpdescriptionschema.h" +#include +#include + +//Local Includes +#include "upnpservicescpractivities.h" +#include "upnpservicescprstates.h" +#include "upnpctrlscprstates.h" +#include "upnpstatemachine.h" +#include "upnpuuid.h" +#include "upnpserverconstants.h" +#include "upnplog.h" + +using namespace UPnPServiceSCprActivities; +using namespace ESock; +using namespace MeshMachine; +using namespace CoreNetStates; +using namespace CoreStates; +using namespace CorePanics; +using namespace PRActivities; +using namespace CoreActivities; +using namespace UPnPStateMachine; +using namespace UPnPServiceSCprStates; + +__FLOG_STMT(_LIT8(KComponent,"UPnPSPScpr");) +const TUint KHttpDefaultPort = 80; + +namespace UPnPServiceSCprParamRequestActivity +{ +#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW +DECLARE_DEFINE_NODEACTIVITY ( ECFActivityParamRequest, UPnPServiceSCprParamRequest, TCFScpr::TSetParamsRequest ) + FIRST_NODEACTIVITY_ENTRY ( TAwaitingSetParamRequest, TNoTag ) + LAST_NODEACTIVITY_ENTRY ( KNoTag, UPnPServiceSCprStates::TStoreParamsAndSendResponse ) +NODEACTIVITY_END ( ) +#else +DECLARE_DEFINE_NODEACTIVITY ( ECFActivityParamRequest, UPnPServiceSCprParamRequest, TCFScpr::TParamsRequest ) + FIRST_NODEACTIVITY_ENTRY ( TAwaitingSetParamRequest, TNoTag ) + LAST_NODEACTIVITY_ENTRY ( KNoTag, UPnPServiceSCprStates::TStoreParamsAndSendResponse ) +NODEACTIVITY_END ( ) +#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW +} + +namespace UPnPServiceSCprApplyRequestActivity +{ +#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW +DECLARE_DEFINE_NODEACTIVITY ( ECFActivityApplyChanges, UPnPServiceSCprApplyRequest, TCFScpr::TApplyRequest ) + FIRST_NODEACTIVITY_ENTRY ( PRStates::TAwaitingApplyRequest, TNoTag ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, UPnPServiceSCprStates::TInitiateActivities, TNoTag ) + LAST_NODEACTIVITY_ENTRY ( KNoTag, PRStates::TSendApplyResponse ) +NODEACTIVITY_END ( ) +#else +DECLARE_DEFINE_NODEACTIVITY ( ECFActivityApplyChanges, UPnPServiceSCprApplyRequest, TCFScpr::TApplyRequest ) + FIRST_NODEACTIVITY_ENTRY ( SCprStates::TAwaitingApplyRequest, TNoTag ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, UPnPServiceSCprStates::TInitiateActivities, TNoTag ) + LAST_NODEACTIVITY_ENTRY ( KNoTag, SCprStates::TSendApplyResponse ) +NODEACTIVITY_END ( ) +#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW +} + +//Activity to create UPnP Server Flow for RSocket used in UPnP Control Phase +namespace UPnPServiceSCprBinderRequestActivity +{ +DECLARE_DEFINE_CUSTOM_NODEACTIVITY ( ECFActivityBinderRequest, UPnPServiceSCprBinderRequest, TCFServiceProvider::TCommsBinderRequest, CCommsBinderActivity::NewL ) + FIRST_NODEACTIVITY_ENTRY ( CoreNetStates::TAwaitingBinderRequest, CCommsBinderActivity::TNoTagOrUseExistingBlockedByBinderRequest ) + + NODEACTIVITY_ENTRY ( KNoTag, TCreateServerFlow, CoreNetStates::TAwaitingDataClientJoin, TNoTag ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, CCommsBinderActivity::TProcessDataClientCreation, TNoTag ) + + NODEACTIVITY_ENTRY ( KNoTag, TSendDataClientStart, CoreNetStates::TAwaitingDataClientStarted, TTag ) + NODEACTIVITY_ENTRY ( CoreStates::KUseExisting, CCommsBinderActivity::TSendBinderResponse, CCommsBinderActivity::TAwaitingBindToComplete, TNoTagOrErrorTag ) + LAST_NODEACTIVITY_ENTRY ( KNoTag, TDoNothing ) + + LAST_NODEACTIVITY_ENTRY ( KErrorTag, TClearError ) +NODEACTIVITY_END ( ) +} + +// Note! Handle DataClientIdle from UPnP Flow created for RSocket used in UPnP CONTROL Phase +namespace UPnPServiceSCprDataClientIdleActivity +{ +DECLARE_DEFINE_NODEACTIVITY ( ECFActivityDataClientIdle, UPnPServiceSCprDataClientIdle, TCFControlProvider::TIdle ) + NODEACTIVITY_ENTRY ( KNoTag, UPnPStateMachine::THandleControlChannelDataClientIdle, CoreNetStates::TAwaitingDataClientIdle, TNoTag ) +NODEACTIVITY_END ( ) +} + + +namespace UPnPServiceSCprClientLeaveActivity +{ +DECLARE_DEFINE_NODEACTIVITY ( ECFActivityClientLeave, UPnPServiceSCprClientLeave, TNodeSignal::TNullMessageId ) //May be waiting for both messages + FIRST_NODEACTIVITY_ENTRY ( CoreStates::TAwaitingClientLeave, TNoTag ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, UPnPServiceSCprStates::TProcessClientLeave, TTag ) + LAST_NODEACTIVITY_ENTRY ( KDataClientIdle, TSendDataClientIdleOrUnregister ) +NODEACTIVITY_END ( ) +} + + +namespace UPnPServiceSCprDataClientStopActivity +{ +DECLARE_DEFINE_NODEACTIVITY ( ECFActivityStopDataClient, UPnPServiceSCprDataClientStop, TCFDataClient::TStop ) + FIRST_NODEACTIVITY_ENTRY ( CoreNetStates::TAwaitingDataClientStop, CoreNetStates::TNoTagOrDataClientsToStop ) + + NODEACTIVITY_ENTRY ( CoreNetStates::KDataClientsToStop, UPnPServiceSCprStates::TProcessDataClientStop, CoreNetStates::TAwaitingDataClientsStopped, TNoTag ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, TDoNothing, CoreNetStates::TNoTagOrUnbindOnStop ) + + NODEACTIVITY_ENTRY ( CoreNetStates::KUnbind, CoreNetStates::TSendClientLeavingRequestToServiceProvider, CoreStates::TAwaitingLeaveComplete, TNoTag ) + + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, UPnPStateMachine::TDestroyDataClients, TNoTag ) + LAST_NODEACTIVITY_ENTRY ( KNoTag, PRStates::TSendDataClientStopped ) +NODEACTIVITY_END ( ) +} + +namespace UPnPServiceSCprDestroyActivity +{ +DECLARE_DEFINE_CUSTOM_NODEACTIVITY ( ECFActivityDestroy, UPnPServiceSCprDestroy, TEChild::TDestroy, CoreActivities::CDestroyActivity::New ) + FIRST_NODEACTIVITY_ENTRY ( TAwaitingDestroy, UPnPStateMachine::TBlockedByAllActivitiesStopped ) + + //Stop self first + NODEACTIVITY_ENTRY ( KNoTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, TNoTag ) + + LAST_NODEACTIVITY_ENTRY ( KNoTag, CoreNetStates::TSendClientLeavingAndRemoveControlProvider ) +NODEACTIVITY_END() +} + + +namespace UPnPServiceScprServiceRegistrationActivity +{ +DECLARE_DEFINE_CUSTOM_NODEACTIVITY ( TUpnpMessage::EActivityServiceRegistration, UPnPServiceSCprServiceRegistration, TUpnpMessage::TServiceRegistration, CUpnpServiceRegistrationActivity::NewL ) + FIRST_NODEACTIVITY_ENTRY ( CUpnpServiceRegistrationActivity::TAwaitingServiceRegistration, TNoTag ) + + NODEACTIVITY_ENTRY ( KNoTag, CUpnpServiceRegistrationActivity::TRequestServiceJoin, TAwaitingServiceValidated, TErrorTagOr > ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, CUpnpServiceRegistrationActivity::TBuildPublishAndServiceInfo, TNoTag ) + NODEACTIVITY_ENTRY ( KNoTag, CUpnpServiceRegistrationActivity::TRegisterServiceInfoWithCPR, TAwaitingServiceRegisteredFromCpr, TErrorTagOr > ) + + NODEACTIVITY_ENTRY ( KNoTag, TFindOrCreateUdpClientFlow, CoreNetStates::TAwaitingDataClientJoin, TErrorTagOr > ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, PRStates::TProcessDataClientCreation, UPnPServiceSCprStates::TStoreUdpClientAndSendRequest ) + NODEACTIVITY_ENTRY ( KSendRequest, TSendDataClientStart, CoreNetStates::TAwaitingDataClientStarted, TNoTag ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, CUpnpServiceRegistrationActivity::TSendPublishRequest, TNoTag ) + // sendpublish request should be written as utility + + NODEACTIVITY_ENTRY ( KNoTag, TFindOrCreateUdpServerFlow, CoreNetStates::TAwaitingDataClientJoin, TErrorTagOr > ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, PRStates::TProcessDataClientCreation, UPnPServiceSCprStates::TStoreUdpServer ) + NODEACTIVITY_ENTRY ( KNoTag, TSendDataClientStart, CoreNetStates::TAwaitingDataClientStarted, TNoTag ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, CUpnpServiceRegistrationActivity::TRegisterSsdpInfoWithServer, TNoTag ) + + LAST_NODEACTIVITY_ENTRY ( KNoTag, CUpnpServiceRegistrationActivity::TInitiateTcpFlowCreation ) + // makes use of activity.Error ( ) && activity destruction clears error + LAST_NODEACTIVITY_ENTRY ( KErrorTag, TSendPublishResponseToClient ) +NODEACTIVITY_END ( ) +} + +namespace UPnPServiceScprDeviceRegistrationActivity +{ +DECLARE_DEFINE_CUSTOM_NODEACTIVITY ( TUpnpMessage::EActivityDeviceRegistration, UPnPServiceSCprDeviceRegistration, TUpnpMessage::TDeviceRegistration, CUpnpDeviceRegistrationActivity::NewL ) + FIRST_NODEACTIVITY_ENTRY ( CUpnpDeviceRegistrationActivity::TAwaitingDeviceRegistration, TNoTag ) + + NODEACTIVITY_ENTRY ( KNoTag, CUpnpDeviceRegistrationActivity::TRequestDeviceJoin, TAwaitingServiceValidated, TErrorTagOr > ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, CUpnpDeviceRegistrationActivity::TBuildPublishAndDeviceInfo, TNoTag ) + NODEACTIVITY_ENTRY ( KNoTag, CUpnpDeviceRegistrationActivity::TRegisterDeviceInfoWithCPR, TAwaitingServiceRegisteredFromCpr, TErrorTagOr > ) + + NODEACTIVITY_ENTRY ( KNoTag, TFindOrCreateUdpClientFlow, CoreNetStates::TAwaitingDataClientJoin, TErrorTagOr > ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, PRStates::TProcessDataClientCreation, UPnPServiceSCprStates::TStoreUdpClientAndSendRequest ) + NODEACTIVITY_ENTRY ( KSendRequest, TSendDataClientStart, CoreNetStates::TAwaitingDataClientStarted, TNoTag ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, CUpnpDeviceRegistrationActivity::TSendPublishRequest, TNoTag ) + // sendpublish request should be written as utility + + NODEACTIVITY_ENTRY ( KNoTag, TFindOrCreateUdpServerFlow, CoreNetStates::TAwaitingDataClientJoin, TErrorTagOr > ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, PRStates::TProcessDataClientCreation, UPnPServiceSCprStates::TStoreUdpServer ) + NODEACTIVITY_ENTRY ( KNoTag, TSendDataClientStart, CoreNetStates::TAwaitingDataClientStarted, TNoTag ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, CUpnpDeviceRegistrationActivity::TRegisterSsdpInfoWithServer, CUpnpDeviceRegistrationActivity::TIconCreateOrNoTag ) + + NODEACTIVITY_ENTRY ( KCreateIconTag, CUpnpDeviceRegistrationActivity::TCreateIconFlow, CoreNetStates::TAwaitingDataClientJoin, TErrorTagOr > ) + NODEACTIVITY_ENTRY ( KIconCreatedTag, TProcessServerFlowCreation, CoreNetStates::TAwaitingDataClientStarted, CUpnpDeviceRegistrationActivity::TIconOrNoTag ) + + LAST_NODEACTIVITY_ENTRY ( KNoTag, TSendPublishResponseToClient ) + // activity destruction clears error + LAST_NODEACTIVITY_ENTRY ( KErrorTag, TSendPublishResponseToClient ) + // no TCP flows for embedded device scpr +NODEACTIVITY_END ( ) +} + +namespace UPnPServiceSCprFlowCreationActivity +{ +DECLARE_DEFINE_NODEACTIVITY ( TUpnpMessage::EActivityCreateServerFlow, UPnPServiceSCprFlowCreation, TUpnpMessage::TCreateServerFlow ) + FIRST_NODEACTIVITY_ENTRY ( TAwaitingServerFlowRequest, TNoTag ) + NODEACTIVITY_ENTRY ( KNoTag, TCreateServerFlow, CoreNetStates::TAwaitingDataClientJoin, TErrorTagOr > ) + NODEACTIVITY_ENTRY ( KNoTag, TProcessServerFlowCreation, CoreNetStates::TAwaitingDataClientStarted, TNoTag ) + NODEACTIVITY_ENTRY ( KNoTag, TCreateServerFlow, CoreNetStates::TAwaitingDataClientJoin, TErrorTagOr > ) + NODEACTIVITY_ENTRY ( KNoTag, TProcessServerFlowCreation, CoreNetStates::TAwaitingDataClientStarted, TNoTag ) + + LAST_NODEACTIVITY_ENTRY ( KNoTag, TSendPublishResponseToClient ) + THROUGH_NODEACTIVITY_ENTRY ( KErrorTag, TSendPublishResponseToClient, TNoTag ) + LAST_NODEACTIVITY_ENTRY ( KNoTag, TClearError ) +NODEACTIVITY_END ( ) +} + +namespace UPnPSerivceSearchResponseActivity +{ +DECLARE_DEFINE_CUSTOM_NODEACTIVITY ( TUpnpMessage::EActivitySearchResponse, UPnPServiceSearchResponse, TUpnpMessage::TUPnPSearchRequest, CNodeParallelActivityBase::NewL ) + FIRST_NODEACTIVITY_ENTRY ( UPnPStateMachine::TAwaitingSearchRequest, UPnPServiceSCprStates::TNoTagOrIgnoreTag ) + LAST_NODEACTIVITY_ENTRY ( KNoTag, UPnPServiceSCprStates::TValidateAndSendResponse ) + LAST_NODEACTIVITY_ENTRY ( CoreStates::KIgnore, UPnPStateMachine::TDiscardSearchRequestData ) +NODEACTIVITY_END ( ) +} + +namespace UpnpServiceRequestInfoActivity +{ +DECLARE_DEFINE_CUSTOM_NODEACTIVITY ( TUpnpMessage::EActivityRequestInfo, UpnpServiceRequestInfo, TUpnpMessage::TUPnPRequestInfo, CUpnpSPRequestInfoActivity::NewL ) + FIRST_NODEACTIVITY_ENTRY ( TAwaitingUpnpRequestInfo, UPnPStateMachine::TRequestOrIgnoreTag ) + + LAST_NODEACTIVITY_ENTRY ( UPnPStateMachine::KDescribeRequest, CUpnpSPRequestInfoActivity::TSendDescribeResponse ) + LAST_NODEACTIVITY_ENTRY ( UPnPStateMachine::KSubscribeRequest, CUpnpSPRequestInfoActivity::TSendSubscribeResponse ) + LAST_NODEACTIVITY_ENTRY ( UPnPStateMachine::KUnsubscribeRequest, CUpnpSPRequestInfoActivity::TSendUnsubscribeResponse ) + + LAST_NODEACTIVITY_ENTRY ( CoreStates::KIgnore, UPnPStateMachine::TSendIgnoreResponse ) +NODEACTIVITY_END ( ) +} + + +namespace UpnpServiceClientFlowCreationActivity +{ +DECLARE_DEFINE_CUSTOM_NODEACTIVITY ( TUpnpMessage::EActivityFindOrCreateFlow, FindOrCreateFlow, TUpnpMessage::TCreateNotifyFlow, CNotifyFlowFinder::NewL ) + FIRST_NODEACTIVITY_ENTRY ( CNotifyFlowFinder::TAwaitingFlowCreationRequest, TNoTag ) + + NODEACTIVITY_ENTRY ( KNoTag, CNotifyFlowFinder::TFindOrCreateFlow, CoreNetStates::TAwaitingDataClientJoin, TNoTag ) + THROUGH_NODEACTIVITY_ENTRY ( KNoTag, PRStates::TProcessDataClientCreation, TNoTag ) + NODEACTIVITY_ENTRY ( KNoTag, TSendDataClientStart, CoreNetStates::TAwaitingDataClientStarted, TNoTag ) + + LAST_NODEACTIVITY_ENTRY ( KNoTag, CNotifyFlowFinder::TProcessDataClient ) +NODEACTIVITY_END ( ) +} + +namespace UpnpEventNotificationActivity +{ +DECLARE_DEFINE_CUSTOM_NODEACTIVITY ( TUpnpMessage::EActivityNotifyRequest, UpnpEventNotification, TUpnpMessage::TNotifyRequest, CUpnpEventNotificationActivity::NewL ) + FIRST_NODEACTIVITY_ENTRY ( CUpnpEventNotificationActivity::TAwaitingNotifyRequest, TNoTag ) + NODEACTIVITY_ENTRY ( KNoTag, CUpnpEventNotificationActivity::TSendRequest, CUpnpEventNotificationActivity::TAwaitingErrorOrResponse, TNoTag ) + LAST_NODEACTIVITY_ENTRY ( KNoTag, TClearError ) +NODEACTIVITY_END ( ) +} + + +namespace UPnPServiceSCprActivities +{ +DEFINE_ACTIVITY_MAP ( activityMap ) + ACTIVITY_MAP_ENTRY ( UPnPServiceSCprParamRequestActivity, UPnPServiceSCprParamRequest ) + ACTIVITY_MAP_ENTRY ( UPnPServiceSCprApplyRequestActivity, UPnPServiceSCprApplyRequest ) + ACTIVITY_MAP_ENTRY ( UPnPServiceSCprBinderRequestActivity, UPnPServiceSCprBinderRequest ) + ACTIVITY_MAP_ENTRY ( UPnPServiceSCprDataClientIdleActivity, UPnPServiceSCprDataClientIdle ) + ACTIVITY_MAP_ENTRY ( UPnPServiceSCprClientLeaveActivity, UPnPServiceSCprClientLeave ) + ACTIVITY_MAP_ENTRY ( UPnPServiceSCprDataClientStopActivity, UPnPServiceSCprDataClientStop ) + ACTIVITY_MAP_ENTRY ( UPnPServiceSCprDestroyActivity, UPnPServiceSCprDestroy ) + ACTIVITY_MAP_ENTRY ( UPnPServiceScprServiceRegistrationActivity, UPnPServiceSCprServiceRegistration ) + ACTIVITY_MAP_ENTRY ( UPnPServiceScprDeviceRegistrationActivity, UPnPServiceSCprDeviceRegistration ) + ACTIVITY_MAP_ENTRY ( UPnPServiceSCprFlowCreationActivity, UPnPServiceSCprFlowCreation ) + ACTIVITY_MAP_ENTRY ( UPnPSerivceSearchResponseActivity, UPnPServiceSearchResponse ) + ACTIVITY_MAP_ENTRY ( UpnpServiceRequestInfoActivity, UpnpServiceRequestInfo ) + ACTIVITY_MAP_ENTRY ( UpnpServiceClientFlowCreationActivity, FindOrCreateFlow ) + ACTIVITY_MAP_ENTRY ( UpnpEventNotificationActivity, UpnpEventNotification ) +ACTIVITY_MAP_END_BASE ( SCprActivities, coreSCprActivities ) +} + + +//-------------------------Service Registration Activity------------------------------------- +CNodeActivityBase* CUpnpServiceRegistrationActivity::NewL ( const TNodeActivity& aActivitySig, AMMNodeBase& aNode ) + { + return new ( ELeave ) CUpnpServiceRegistrationActivity ( aActivitySig, aNode ) ; + } + + +CUpnpServiceRegistrationActivity::CUpnpServiceRegistrationActivity ( const TNodeActivity& aActivitySig, AMMNodeBase& aNode ) + : CNodeActivityBase ( aActivitySig, aNode ) + { + } + +CUpnpServiceRegistrationActivity::~CUpnpServiceRegistrationActivity ( ) + { + SetError ( KErrNone ); + delete iParamSet; + } + +DEFINE_SMELEMENT ( CUpnpServiceRegistrationActivity::TRequestServiceJoin, NetStateMachine::MStateTransition, CUpnpServiceRegistrationActivity::TContext ) +void CUpnpServiceRegistrationActivity::TRequestServiceJoin::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPSrvcRegActivity, KComponent, _L8("CUpnpServiceRegistrationActivity::TRequestServiceJoin::DoL"))); + TUpnpMessage::TServiceRegistration& msg = message_cast( iContext.iMessage ); + + CUpnpServiceRegistrationActivity& activity = static_cast ( *iContext.iNodeActivity ); + activity.iParamSet = static_cast ( msg.iParamSet ); + + LOG(ESockLogExternal::Printf(KSubsysSPSrvcRegActivity, KComponent, _L8("CUpnpServiceRegistrationActivity::TRequestServiceJoin::DoL - Posting message TUpnpMessage::TServiceJoinRequest"))); + activity.PostRequestTo ( iContext.Node ().ControlProvider ()->RecipientId (), TUpnpMessage::TServiceJoinRequest ( activity.iParamSet ).CRef () ); + } + +DEFINE_SMELEMENT ( CUpnpServiceRegistrationActivity::TBuildPublishAndServiceInfo, NetStateMachine::MStateTransition, CUpnpServiceRegistrationActivity::TContext ) +void CUpnpServiceRegistrationActivity::TBuildPublishAndServiceInfo::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPSrvcRegActivity, KComponent, _L8("CUpnpServiceRegistrationActivity::TBuildPublishAndServiceInfo::DoL"))); + CUpnpServiceRegistrationActivity& activity = static_cast ( *iContext.iNodeActivity ); + + CStringPoolManager& stringPoolMgr = iContext.Node ().ConnectionProvider ().StringPoolManager (); + RStringPool& sp = stringPoolMgr.StringPool ( ); + + CUPnPPublishInfoElement* publishInfo = CUPnPPublishInfoElement::NewL ( ); + CleanupStack::PushL ( publishInfo ); + + publishInfo->SetUuidL( activity.iParamSet->DeviceUid( ) ); + publishInfo->SetSearchTargetL( activity.iParamSet->Uri( ) ) ; + publishInfo->SetServiceDescriptionL( activity.iParamSet->ServiceDescription( ) ); + publishInfo->SetCacheControlL( activity.iParamSet->CacheControlData( ) ) ; + publishInfo->SetTimeOut( activity.iParamSet->SubscriptionDuration() ); + + const CUPnPSubscribeInfoContainer* subContainer = iContext.Node ( ).GetSubscribeInfoContainer ( ); + subContainer->SetEventDataL( activity.iParamSet->InitialMessage( ) ); + + //Set USN + RBuf8 resultUrl; + TInt length = activity.iParamSet->DeviceUid( ).Length ( ) + + activity.iParamSet->Uri( ).Length ( ) + + KSeperator ( ).Length ( ); + resultUrl.CreateL ( length ); + CleanupClosePushL ( resultUrl ); + resultUrl.Copy ( activity.iParamSet->DeviceUid( ) ); + resultUrl.Append ( KSeperator ); + resultUrl.Append ( activity.iParamSet->Uri( ) ); + publishInfo->SetUsnL( resultUrl ); + CleanupStack::PopAndDestroy ( &resultUrl ); + + activity.iServiceInfo = CUPnPServiceInfo::NewL ( ); + activity.iServiceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EServiceType, stringPoolMgr.GetUPnPTable() ), activity.iParamSet->Uri( ) ); + + // construct serviceid + RBuf8 serviceId; + activity.GenerateServiceIdL ( stringPoolMgr, activity.iParamSet->Uri( ), serviceId ); + CleanupClosePushL ( serviceId ); + activity.iServiceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EServiceId, stringPoolMgr.GetUPnPTable() ), serviceId ); + + + // SCPD Url + activity.CreateRelativeUrlL ( serviceId, + sp.String ( UPNPDESCRIPTIONXMLTAGS::EScpdUrl, stringPoolMgr.GetUPnPTable()).DesC ( ), + resultUrl ); + CleanupClosePushL ( resultUrl ); + activity.iServiceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EScpdUrl, stringPoolMgr.GetUPnPTable ( ) ), resultUrl ); + //Note! result url is a relative url that starts with '/', avoid this in scpr properties, bare url will take care + TPtr8 urlPtr = resultUrl.MidTPtr ( 1 ); + publishInfo->SetKeyL( urlPtr ); + iContext.Node ( ).SetKeyL ( urlPtr ); + + CleanupStack::PopAndDestroy ( &resultUrl ); + + // ControlUrl + activity.CreateRelativeUrlL ( serviceId, + sp.String ( UPNPDESCRIPTIONXMLTAGS::EContorlUrl, stringPoolMgr.GetUPnPTable() ).DesC ( ), + resultUrl ); + CleanupClosePushL ( resultUrl ); + activity.iServiceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EContorlUrl, stringPoolMgr.GetUPnPTable() ), resultUrl ); + urlPtr.Set ( resultUrl.MidTPtr ( 1 ) ); + iContext.Node ( ).SetControlUrlL ( urlPtr ); + CleanupStack::PopAndDestroy ( &resultUrl ); + + // EventSubUrl + activity.CreateRelativeUrlL ( serviceId, + sp.String ( UPNPDESCRIPTIONXMLTAGS::EEventSubUrl, stringPoolMgr.GetUPnPTable() ).DesC ( ), + resultUrl ); + CleanupClosePushL ( resultUrl ); + activity.iServiceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EEventSubUrl, stringPoolMgr.GetUPnPTable() ), resultUrl ); + urlPtr.Set ( resultUrl.MidTPtr ( 1 ) ); + iContext.Node ( ).SetEventUrlL ( urlPtr ); + CleanupStack::PopAndDestroy ( &resultUrl ); + + + CleanupStack::PopAndDestroy ( &serviceId ); + CleanupStack::Pop ( publishInfo ); + + iContext.Node ( ).SetPublishInfo ( publishInfo ); + } + +void CUpnpServiceRegistrationActivity::GenerateServiceIdL ( CStringPoolManager& aStringPoolMgr, const TDesC8& aUri, RBuf8& aServiceId ) + { + TLex8 parser ( aUri ); + TChar ch = ':'; + parser.Mark ( ); + while ( !parser.Eos ( ) && parser.Peek ( ) != ch ) + parser.Inc ( ); + + parser.Inc ( ); + while ( !parser.Eos ( ) && parser.Peek ( ) != ch ) + parser.Inc ( ); + + TPtrC8 schemaType = parser.MarkedToken ( ); + + if ( schemaType.Compare ( KUrnSchema ( ) ) == 0 ) + { + // Standard Upnp devices + aServiceId.CreateL ( KUrnService ); + } + else + { + RStringPool& sp = aStringPoolMgr.StringPool ( ); + + // Vendor specific devices + aServiceId.CreateL ( schemaType ); + aServiceId.ReAllocL ( aServiceId.Length ( ) + + sp.String ( UPNPDESCRIPTIONXMLTAGS::EServiceId, aStringPoolMgr.GetUPnPTable() ).DesC ( ).Length ( ) + + KColon ( ).Length ( ) * 2 ); + + aServiceId.Append ( KColon ( ) ); + aServiceId.Append ( sp.String ( UPNPDESCRIPTIONXMLTAGS::EServiceId, aStringPoolMgr.GetUPnPTable() ).DesC ( ) ); + aServiceId.Append ( KColon ( ) ); + } + + parser.Inc ( ); + + while ( !parser.Eos ( ) && parser.Peek ( ) != ch ) + parser.Inc ( ); + + parser.Inc ( ); + parser.Mark ( ); + + while ( !parser.Eos ( ) && parser.Peek ( ) != ch ) + parser.Inc ( ); + + TPtrC8 serviceType = parser.MarkedToken ( ); + + RBuf8 uniqueId; + UpnpUuid::GenerateUuidL ( uniqueId ); + CleanupClosePushL ( uniqueId ); + + aServiceId.ReAllocL ( aServiceId.Length ( ) + serviceType.Length ( ) + uniqueId.Length ( ) ); + aServiceId.Append ( serviceType ); + aServiceId.Append ( uniqueId ); + + CleanupStack::PopAndDestroy ( &uniqueId ); + } + + + +void CUpnpServiceRegistrationActivity::CreateRelativeUrlL ( const TDesC8& aServiceId, const TDesC8& aUri, RBuf8& aResultUrl ) + { + _LIT8 ( KForwardSlash, "/" ); + RBuf8 tempUrl; + TInt length = KForwardSlash ().Length () + aServiceId.Length ( ) + + KUnderScore ( ).Length ( ) + + aUri.Length ( ); + + tempUrl.CreateL ( length ); + tempUrl.Copy ( KForwardSlash ); + tempUrl.Append ( aServiceId ); + tempUrl.Append ( KUnderScore ); + tempUrl.Append ( aUri ); + aResultUrl.Assign ( tempUrl ); + } + + +DEFINE_SMELEMENT ( CUpnpServiceRegistrationActivity::TRegisterServiceInfoWithCPR, NetStateMachine::MStateTransition, CUpnpServiceRegistrationActivity::TContext ) +void CUpnpServiceRegistrationActivity::TRegisterServiceInfoWithCPR::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPSrvcRegActivity, KComponent, _L8("CUpnpServiceRegistrationActivity::TRegisterServiceInfoWithCPR::DoL"))); + CUpnpServiceRegistrationActivity& activity = static_cast ( *iContext.iNodeActivity ); + activity.PostRequestTo ( iContext.Node ().ControlProvider ()->RecipientId (), TUpnpMessage::TRegisterService ( activity.iParamSet, activity.iServiceInfo ).CRef () ); + } + +DEFINE_SMELEMENT ( CUpnpServiceRegistrationActivity::TSendPublishRequest, NetStateMachine::MStateTransition, CUpnpServiceRegistrationActivity::TContext ) +void CUpnpServiceRegistrationActivity::TSendPublishRequest::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPSrvcRegActivity, KComponent, _L8("CUpnpServiceRegistrationActivity::TSendPublishRequest::DoL"))); + CUPnPPublishInfoElement* publishInfo = iContext.Node ( ).PublishInfo ( ); + + // Publish once for uuid:device-UUID::urn:domain-name-service:serviceType:v + iContext.Node ( ).DoPublishL ( publishInfo->SearchTarget ( ), publishInfo->Usn ( ), publishInfo->CacheControl ( ) ); + } + + +DEFINE_SMELEMENT ( CUpnpServiceRegistrationActivity::TRegisterSsdpInfoWithServer, NetStateMachine::MStateTransition, CUpnpServiceRegistrationActivity::TContext ) +void CUpnpServiceRegistrationActivity::TRegisterSsdpInfoWithServer::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPSrvcRegActivity, KComponent, _L8("CUpnpServiceRegistrationActivity::TRegisterSsdpInfoWithServer::DoL"))); + CUPnPPublishInfoElement* publishInfo = iContext.Node ( ).PublishInfo ( ); + + RMemChunk stBuf; + stBuf.CreateL ( publishInfo->SearchTarget ( ), iContext.Node ( ).ConnectionProvider().MemoryAllocator() ); + + LOG(ESockLogExternal::Printf(KSubsysSPSrvcRegActivity, KComponent, _L8("CUpnpServiceRegistrationActivity::TInitiateTcpFlowCreation::DoL - Posting message TUpnpMessage::TUPnPPublishRegistration"))); + TSsdpInfo ssdpInfo ( stBuf ); + RClientInterface::OpenPostMessageClose ( TNodeCtxId ( MeshMachine::KActivityNull, iContext.NodeId () ), iContext.Node ().UdpServerFlow (), TUpnpMessage::TUPnPPublishRegistration ( ssdpInfo ).CRef () ); + } + + +DEFINE_SMELEMENT ( CUpnpServiceRegistrationActivity::TInitiateTcpFlowCreation, NetStateMachine::MStateTransition, CUpnpServiceRegistrationActivity::TContext ) +void CUpnpServiceRegistrationActivity::TInitiateTcpFlowCreation::DoL ( ) + { + // kickoff self activity to create tcp server flows + LOG(ESockLogExternal::Printf(KSubsysSPSrvcRegActivity, KComponent, _L8("CUpnpServiceRegistrationActivity::TInitiateTcpFlowCreation::DoL - Posting message TUpnpMessage::TCreateServerFlow"))); + RClientInterface::OpenPostMessageClose ( iContext.NodeId (), iContext.NodeId (), TUpnpMessage::TCreateServerFlow ().CRef () ); + } + + +//-------------------------Embedded Device Session Registration Activity------------------------------------- +CNodeActivityBase* CUpnpDeviceRegistrationActivity::NewL ( const TNodeActivity& aActivitySig, AMMNodeBase& aNode ) + { + return new ( ELeave ) CUpnpDeviceRegistrationActivity ( aActivitySig, aNode ) ; + } + + +CUpnpDeviceRegistrationActivity::CUpnpDeviceRegistrationActivity ( const TNodeActivity& aActivitySig, AMMNodeBase& aNode ) + : CNodeActivityBase ( aActivitySig, aNode ), iIconUrlIdx ( 0 ) + { + } + +CUpnpDeviceRegistrationActivity::~CUpnpDeviceRegistrationActivity ( ) + { + SetError ( KErrNone ); + delete iParamSet; + iIconUrl.Close (); + } + +DEFINE_SMELEMENT ( CUpnpDeviceRegistrationActivity::TRequestDeviceJoin, NetStateMachine::MStateTransition, CUpnpDeviceRegistrationActivity::TContext ) +void CUpnpDeviceRegistrationActivity::TRequestDeviceJoin::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPDeviceRegActivity, KComponent, _L8("CUpnpDeviceRegistrationActivity::TRequestDeviceJoin::DoL"))); + TUpnpMessage::TDeviceRegistration& msg = message_cast( iContext.iMessage ); + + CUpnpDeviceRegistrationActivity& activity = static_cast ( *iContext.iNodeActivity ); + activity.iParamSet = static_cast ( msg.iParamSet ); + + LOG(ESockLogExternal::Printf(KSubsysSPDeviceRegActivity, KComponent, _L8("CUpnpDeviceRegistrationActivity::TRequestDeviceJoin::DoL - Posting message TUpnpMessage::TDeviceJoinRequest"))); + activity.PostRequestTo ( iContext.Node ().ControlProvider ()->RecipientId (), TUpnpMessage::TDeviceJoinRequest ( activity.iParamSet ).CRef () ); + } + +DEFINE_SMELEMENT ( CUpnpDeviceRegistrationActivity::TBuildPublishAndDeviceInfo, NetStateMachine::MStateTransition, CUpnpDeviceRegistrationActivity::TContext ) +void CUpnpDeviceRegistrationActivity::TBuildPublishAndDeviceInfo::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPDeviceRegActivity, KComponent, _L8("CUpnpDeviceRegistrationActivity::TBuildPublishAndDeviceInfo::DoL"))); + CUpnpDeviceRegistrationActivity& activity = static_cast ( *iContext.iNodeActivity ); + + CUPnPPublishInfoElement* publishInfo = CUPnPPublishInfoElement::NewL ( ); + CleanupStack::PushL ( publishInfo ); + + publishInfo->SetUuidL( activity.iParamSet->UDN( ) ); + publishInfo->SetSearchTargetL( activity.iParamSet->Uri( ) ) ; + publishInfo->SetCacheControlL( activity.iParamSet->CacheControlData( ) ) ; + // for an embedded device both key and UDN are same, so...it can key can be used + // for deregistering embedded device. + publishInfo->SetKeyL( activity.iParamSet->UDN( ) ); + + //Set USN + RBuf8 tempUrl; + TInt length = activity.iParamSet->UDN( ).Length ( ) + + activity.iParamSet->Uri( ).Length ( ) + + KSeperator ( ).Length ( ); + + tempUrl.CreateMaxL ( length ); + CleanupClosePushL ( tempUrl ); + + tempUrl.Copy ( activity.iParamSet->UDN( ) ); + tempUrl.Append ( KSeperator ); + tempUrl.Append ( activity.iParamSet->Uri( ) ); + publishInfo->SetUsnL( tempUrl ); + + activity.iDeviceInfo = CUPnPDevice::NewL ( ); + + CStringPoolManager& stringPoolMgr = iContext.Node ().ConnectionProvider ().StringPoolManager (); + RStringPool& sp = stringPoolMgr.StringPool ( ); + + // set device info + activity.iDeviceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EPresentationUrl, stringPoolMgr.GetUPnPTable() ), activity.iParamSet->PresentationUri( ) ); + // set the device attributes + activity.iDeviceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EDeviceType, stringPoolMgr.GetUPnPTable() ), activity.iParamSet->Uri( ) ); + activity.iDeviceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EFriendlyName, stringPoolMgr.GetUPnPTable() ),activity.iParamSet->FriendlyName( ) ); + activity.iDeviceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EUdn,stringPoolMgr.GetUPnPTable()), activity.iParamSet->UDN( ) ); + activity.iDeviceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EUpc, stringPoolMgr.GetUPnPTable()), activity.iParamSet->UPC( ) ); + + // set manufacturer attributes + activity.iDeviceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EManufacturer, stringPoolMgr.GetUPnPTable() ), activity.iParamSet->Manufacturer( ) ); + activity.iDeviceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EManufacturerUrl, stringPoolMgr.GetUPnPTable() ), activity.iParamSet->ManufacturerUrl( ) ); + activity.iDeviceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::ESerialNumber, stringPoolMgr.GetUPnPTable() ), activity.iParamSet->SerialNumber( ) ); + + // set device model attributes + activity.iDeviceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EModelName, stringPoolMgr.GetUPnPTable() ), activity.iParamSet->ModelName( ) ); + activity.iDeviceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EModelDescription,stringPoolMgr.GetUPnPTable() ), activity.iParamSet->ModelDesc( ) ); + activity.iDeviceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EModelNumber, stringPoolMgr.GetUPnPTable()), activity.iParamSet->ModelNumber( ) ); + activity.iDeviceInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EModel,stringPoolMgr.GetUPnPTable() ), activity.iParamSet->ModelUri( ) ); + + for (TInt i = 0; i < activity.iParamSet->IconList ().Count (); i++ ) + { + CUPnPIconParams* iconParams = activity.iParamSet->IconList ()[i]; + CUPnPIconInfo* iconInfo = CUPnPIconInfo::NewL (); + CleanupStack::PushL ( iconInfo ); + iconInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EMimeType, stringPoolMgr.GetUPnPTable() ), iconParams->MimeType () ); + iconInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EWidth,stringPoolMgr.GetUPnPTable() ), iconParams->Width () ); + iconInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EHeight, stringPoolMgr.GetUPnPTable()), iconParams->Height () ); + iconInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EDepth,stringPoolMgr.GetUPnPTable() ), iconParams->Depth () ); + iconInfo->SetPropertyL( sp.String ( UPNPDESCRIPTIONXMLTAGS::EUrl,stringPoolMgr.GetUPnPTable() ), iconParams->Url () ); + + activity.iDeviceInfo->AppendToIconInfoTableL ( iconInfo ); + CleanupStack::Pop ( iconInfo ); + } + + CleanupStack::PopAndDestroy ( &tempUrl ); + CleanupStack::Pop ( publishInfo ); + + iContext.Node ( ).SetPublishInfo ( publishInfo ); + iContext.Node ( ). SetDevice ( ETrue ); + } + +DEFINE_SMELEMENT ( CUpnpDeviceRegistrationActivity::TRegisterDeviceInfoWithCPR, NetStateMachine::MStateTransition, CUpnpDeviceRegistrationActivity::TContext ) +void CUpnpDeviceRegistrationActivity::TRegisterDeviceInfoWithCPR::DoL ( ) + { + CUpnpDeviceRegistrationActivity& activity = static_cast ( *iContext.iNodeActivity ); + LOG(ESockLogExternal::Printf(KSubsysSPDeviceRegActivity, KComponent, _L8("CUpnpDeviceRegistrationActivity::TRegisterDeviceInfoWithCPR::DoL - Posting message TUpnpMessage::TRegisterDevice"))); + activity.PostRequestTo ( iContext.Node ().ControlProvider ()->RecipientId (), TUpnpMessage::TRegisterDevice ( activity.iParamSet, activity.iDeviceInfo ).CRef () ); + } + +DEFINE_SMELEMENT ( CUpnpDeviceRegistrationActivity::TSendPublishRequest, NetStateMachine::MStateTransition, CUpnpDeviceRegistrationActivity::TContext ) +void CUpnpDeviceRegistrationActivity::TSendPublishRequest::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPDeviceRegActivity, KComponent, _L8("CUpnpDeviceRegistrationActivity::TSendPublishRequest::DoL"))); + CUPnPPublishInfoElement* publishInfo = iContext.Node ( ).PublishInfo ( ); + + // Publish once for uuid:device-UUID + iContext.Node ( ).DoPublishL ( publishInfo->Uuid ( ), publishInfo->Uuid ( ), publishInfo->CacheControl ( ) ); + + // Publish once for uuid:device-UUID::urn:domain-name-device:deviceType:v + iContext.Node ( ).DoPublishL ( publishInfo->SearchTarget ( ), publishInfo->Usn ( ), publishInfo->CacheControl ( ) ); + } + +DEFINE_SMELEMENT ( CUpnpDeviceRegistrationActivity::TRegisterSsdpInfoWithServer, NetStateMachine::MStateTransition, CUpnpDeviceRegistrationActivity::TContext ) +void CUpnpDeviceRegistrationActivity::TRegisterSsdpInfoWithServer::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPDeviceRegActivity, KComponent, _L8("CUpnpDeviceRegistrationActivity::TRegisterSsdpInfoWithServer::DoL"))); + CUPnPPublishInfoElement* publishInfo = iContext.Node ( ).PublishInfo ( ); + + // Register once for uuid:device-UUID + RegisterForMSearchL ( publishInfo->Uuid ( ) ); + + // Register once for uuid:device-UUID::urn:domain-name-device:deviceType:v + RegisterForMSearchL ( publishInfo->SearchTarget ( ) ); + } + +void CUpnpDeviceRegistrationActivity::TRegisterSsdpInfoWithServer::RegisterForMSearchL ( const TDesC8& aSearchTarget ) + { + LOG(ESockLogExternal::Printf(KSubsysSPDeviceRegActivity, KComponent, _L8("CUpnpDeviceRegistrationActivity::TRegisterSsdpInfoWithServer::DoL"))); + RMemChunk stBuf; + stBuf.CreateL ( aSearchTarget, iContext.Node ( ).ConnectionProvider().MemoryAllocator() ); + + LOG(ESockLogExternal::Printf(KSubsysSPDeviceRegActivity, KComponent, _L8("CUpnpDeviceRegistrationActivity::TRegisterSsdpInfoWithServer::DoL - Posting message TUpnpMessage::TUPnPPublishRegistration"))); + TSsdpInfo ssdpInfo ( stBuf ); + RClientInterface::OpenPostMessageClose ( TNodeCtxId ( MeshMachine::KActivityNull, iContext.NodeId () ), iContext.Node ().UdpServerFlow () , TUpnpMessage::TUPnPPublishRegistration ( ssdpInfo ).CRef () ); + } + +DEFINE_SMELEMENT ( CUpnpDeviceRegistrationActivity::TCreateIconFlow, NetStateMachine::MStateTransition, CUpnpDeviceRegistrationActivity::TContext ) +void CUpnpDeviceRegistrationActivity::TCreateIconFlow::DoL () + { + CUpnpDeviceRegistrationActivity& activity = static_cast ( *iContext.iNodeActivity ); + activity.iIconUrl.Close (); + + const TDesC8& rootLoc = iContext.Node ().ConnectionProvider ().RootDeviceLocation (); + const TDesC8& url = activity.iParamSet->IconList()[activity.iIconUrlIdx]->Url (); + if ( url[0] == TChar ('/') ) + { + activity.iIconUrl.CreateL ( rootLoc.Length () + ( url.Length () - 1 ) ); + activity.iIconUrl.Copy ( rootLoc ); + activity.iIconUrl.Append ( url.Mid (1) ); + } + else + { + activity.iIconUrl.CreateL ( rootLoc.Length () + url.Length () ); + activity.iIconUrl.Copy ( rootLoc ); + activity.iIconUrl.Append ( url ); + } + + const TUint8* uriPtr = activity.iIconUrl.Ptr (); + TUint size = activity.iIconUrl.Size (); + const TUid requestedUid = { CUPnPFlowFactory::iUid }; + THttpServerFlowQuery flowQuery ( uriPtr, + size, + iContext.NodeId (), + EHttpServerFlow ); + + ESock::TCFFactory::TFindOrCreatePeer msg ( TCFPlayerRole::EDataPlane, requestedUid, &flowQuery ); + + TCFPlayerRole playerRole ( TCFPlayerRole::EDataPlane ); + Messages::TNodeId factoryContainer = SockManGlobals::Get()->GetPlaneFC( playerRole ); + activity.PostRequestTo( factoryContainer, msg ); + } + +DEFINE_SMELEMENT ( CUpnpDeviceRegistrationActivity::TIconCreateOrNoTag, NetStateMachine::MStateFork, CUpnpDeviceRegistrationActivity::TContext ) +TInt CUpnpDeviceRegistrationActivity::TIconCreateOrNoTag::TransitionTag () + { + CUpnpDeviceRegistrationActivity& activity = static_cast ( *iContext.iNodeActivity ); + return activity.iParamSet->IconList ().Count () != 0 ? KCreateIconTag : KNoTag; + } + +DEFINE_SMELEMENT ( CUpnpDeviceRegistrationActivity::TIconOrNoTag, NetStateMachine::MStateFork, CUpnpDeviceRegistrationActivity::TContext ) +TInt CUpnpDeviceRegistrationActivity::TIconOrNoTag::TransitionTag () + { + CUpnpDeviceRegistrationActivity& activity = static_cast ( *iContext.iNodeActivity ); + + activity.iIconUrlIdx++; + if ( activity.iParamSet->IconList ().Count () != activity.iIconUrlIdx ) + { + return NetStateMachine::EBackward | KCreateIconTag; + } + + return NetStateMachine::EForward | KNoTag; + } + +// -------------- Request Info Activity-------------------------------------------------- + +CNodeActivityBase* CUpnpSPRequestInfoActivity::NewL ( const TNodeActivity& aActivitySig, AMMNodeBase& aNode ) + { + return ( new ( ELeave ) CUpnpSPRequestInfoActivity ( aActivitySig, aNode ) ); + } + +CUpnpSPRequestInfoActivity::~CUpnpSPRequestInfoActivity ( ) + { + SetError ( KErrNone ); + } + +// Transitions +DEFINE_SMELEMENT ( CUpnpSPRequestInfoActivity::TSendDescribeResponse, NetStateMachine::MStateTransition, CUpnpSPRequestInfoActivity::TContext ) +void CUpnpSPRequestInfoActivity::TSendDescribeResponse::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPServiceReqInfoActivity, KComponent, _L8("CUpnpSPRequestInfoActivity::TSendDescribeResponse::DoL"))); + + TUpnpMessage::TUPnPRequestInfo& requestMsg = message_cast< TUpnpMessage::TUPnPRequestInfo > ( iContext.iMessage ); + CTransaction* transaction = static_cast ( requestMsg.iPtr ); + TInt statusCode; + RMemoryAllocator allocator = iContext.Node ( ).ConnectionProvider().MemoryAllocator(); + + if ( transaction->Request()->URI()->Uri().UriDes().Compare ( iContext.Node ().Key () ) == 0 ) + { + RMemChunk dataChian; + dataChian.CreateL( iContext.Node ( ).SCPDData ( ), allocator ); + transaction->AddBodyPart( dataChian ); + statusCode = HTTPStatus::EOk; + } + else + { + CUPnPUtils::FindAndSendIconDataL ( transaction, statusCode, allocator ); + } + + RClientInterface::OpenPostMessageClose ( iContext.NodeId (), iContext.iSender, + TUpnpMessage::TUPnPResponseInfo ( transaction, statusCode, NULL ).CRef () ); + } + + +DEFINE_SMELEMENT ( CUpnpSPRequestInfoActivity::TSendSubscribeResponse, NetStateMachine::MStateTransition, CUpnpSPRequestInfoActivity::TContext ) +void CUpnpSPRequestInfoActivity::TSendSubscribeResponse::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPServiceReqInfoActivity, KComponent, _L8("CUpnpSPRequestInfoActivity::TSendSubscribeResponse::DoL"))); + CUpnpSPRequestInfoActivity& activity = static_cast< CUpnpSPRequestInfoActivity& > ( *iContext.iNodeActivity ); + + TUpnpMessage::TUPnPRequestInfo& requestMsg = message_cast< TUpnpMessage::TUPnPRequestInfo > ( iContext.iMessage ); + CTransaction* transaction = static_cast ( requestMsg.iPtr ); + + TInt statusCode; + TSubsribeResponseInfo subscribeResponse; + + THTTPHdrVal fieldVal; + CUPnPPublishInfoElement* publishInfo = iContext.Node().PublishInfo(); + if ( KErrNotFound == activity.GetHeaderValue ( *transaction->Request( ), UPnP::ESID, fieldVal, TUPnPTable::Table() ) ) + { + statusCode = activity.HandleSubscribeRequestL ( *transaction->Request( ), subscribeResponse, *publishInfo ); + + if ( statusCode == HTTPStatus::EOk && IsFirstSubscription ( ) ) + { + // trigger CPR to start subscription timer + RClientInterface::OpenPostMessageClose ( iContext.NodeId (), iContext.Node ().ControlProvider ()->RecipientId (), + TUpnpMessage::TStartTimer ().CRef () ); + } + } + else + { + statusCode = activity.HandleResubscribeRequestL ( *transaction->Request( ), subscribeResponse, *publishInfo ); + } + RClientInterface::OpenPostMessageClose ( iContext.NodeId (), iContext.iSender, + TUpnpMessage::TUPnPResponseInfo ( transaction, statusCode, &subscribeResponse ).CRef () ); + } + +TInt CUpnpSPRequestInfoActivity::HandleSubscribeRequestL ( CRequest& aRequest, TSubsribeResponseInfo& aSubscribeResponse, CUPnPPublishInfoElement& aPublishInfo ) + { + TInt statusCode = HTTPStatus::EOk; + // Note! as of now there is no limitation on subscribers or else send 5xx status code + // Note! duration is accepted what ever the client is requesting + + THTTPHdrVal timeOutField; + TInt err = GetHeaderValue ( aRequest, UPnP::ETimeout, timeOutField, TUPnPTable::Table() ); + TInt timeout = aPublishInfo.TimeOut(); + + // If the SUBSCRIBE request doesn't have the Timeout header, + // assume the standard DLNA specified value of 300 seconds. + if(err != KErrNotFound) + { + if(timeOutField.Int() < aPublishInfo.TimeOut()) + timeout = timeOutField.Int ( ); + } + + THTTPHdrVal callbackField; + err = GetHeaderValue ( aRequest, UPnP::ECallback, callbackField, TUPnPTable::Table() ); + __ASSERT_DEBUG ( err != KErrNotFound, User::Invariant ( ) ); + const TDesC8& callBackUrl = callbackField.StrF ( ).DesC ( ); + + // construct the subscribeinfoelement + CUPnPSubscribeInfoElement* newSubscription = CUPnPSubscribeInfoElement::NewL ( ); + newSubscription->SetEventKey ( 0 ); // initial value + + newSubscription->SetSubscriptionDuration ( timeout ); + + RBuf8 uuid; + CleanupClosePushL ( uuid ); + UpnpUuid::GenerateUuidL ( uuid ); + newSubscription->SetSubscriptionIdentifierL ( uuid ); + + // extract and cache callback urls + ProcessCallBackUrlL ( callBackUrl, newSubscription ); + + // append element in subscription container list + CUPnPServiceSubConnectionProvider& subConn = static_cast ( iNode ); + const CUPnPSubscribeInfoContainer* container = subConn.GetSubscribeInfoContainer ( ); + container->AppendSubscribeInfoElementL( newSubscription ); + + // construct the response; + aSubscribeResponse.iTimeout = timeout; + aSubscribeResponse.iSid.CreateL ( uuid, subConn.ConnectionProvider().MemoryAllocator() ); + CleanupStack::PopAndDestroy ( &uuid ); + + // send a message find or create a flow. + // NOTE: This will also send the intial notify message and add it into the container. + RClientInterface::OpenPostMessageClose ( iNode.Id(), iNode.Id (), + TUpnpMessage::TCreateNotifyFlow ( newSubscription ).CRef () ); + return statusCode; + } + + +void CUpnpSPRequestInfoActivity::ProcessCallBackUrlL ( const TDesC8& aUrl, CUPnPSubscribeInfoElement* aSubscribeElement ) + { + // extract the ip address and flow and add it to the info element + aSubscribeElement->SetCallBackUrlL( aUrl ); + + TUriParser8 parsedUri; + parsedUri.Parse ( aUrl ); + + TInt ip = 0; + InetProtTextUtils::ConvertDescriptorToInt ( parsedUri.Extract ( EUriHost ), ip ); + + TInt port = KHttpDefaultPort; + if ( parsedUri.IsPresent ( EUriPort ) ) + { + InetProtTextUtils::ConvertDescriptorToInt ( parsedUri.Extract ( EUriPort ), port ); + } + + TAppProtAddr addr ( ip, port ); + aSubscribeElement->SetRemoteAddr ( addr ); + } + + +TBool CUpnpSPRequestInfoActivity::TSendSubscribeResponse::IsFirstSubscription ( ) + { + const CUPnPSubscribeInfoContainer* container = iContext.Node ( ).GetSubscribeInfoContainer ( ); + return container->CountOfSubscribeInfoElementArray( ) == 1 ? ETrue : EFalse; + } + + +TInt CUpnpSPRequestInfoActivity::HandleResubscribeRequestL ( CRequest& aRequest, TSubsribeResponseInfo& aSubscribeResponse, CUPnPPublishInfoElement& aPublishInfo ) + { + CUPnPServiceSubConnectionProvider& provider = static_cast ( iNode ); + + // Note! as of now there is no limitation on subscribers or else send 5xx status code + // Note! duration is accepted what ever the client is requesting + TInt statusCode = HTTPStatus::EOk; + THTTPHdrVal timeOutField; + TInt err = GetHeaderValue ( aRequest, UPnP::ETimeout, timeOutField, TUPnPTable::Table() ); + TInt timeout = aPublishInfo.TimeOut(); + + // If the Re-SUBSCRIBE request doesn't have the Timeout header, + // assume the standard DLNA specified value of 300 seconds. + if(err != KErrNotFound) + { + if(timeOutField.Int() < aPublishInfo.TimeOut()) + timeout = timeOutField.Int ( ); + } + + THTTPHdrVal sidField; + err = GetHeaderValue ( aRequest, UPnP::ESID, sidField, TUPnPTable::Table() ); + __ASSERT_DEBUG ( err != KErrNotFound, User::Invariant ( ) ); + + const CUPnPSubscribeInfoContainer* container = provider.GetSubscribeInfoContainer ( ); + CUPnPSubscribeInfoElement* element = container->GetSubscribeInfoBySid ( sidField.StrF ( ).DesC ( ) ); + + if ( element == NULL ) + { + // susbscription is expired send 412 error condition + statusCode = HTTPStatus::EPreconditionFailed; + } + else + { + element->SetSubscriptionDuration ( timeout ); + + // construct the response; + aSubscribeResponse.iTimeout = timeout; + aSubscribeResponse.iSid.CreateL ( element->SubscriptionIdentifier( ), provider.ConnectionProvider().MemoryAllocator() ); + } + + return statusCode; + } + + +DEFINE_SMELEMENT ( CUpnpSPRequestInfoActivity::TSendUnsubscribeResponse, NetStateMachine::MStateTransition, CUpnpSPRequestInfoActivity::TContext ) +void CUpnpSPRequestInfoActivity::TSendUnsubscribeResponse::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPServiceReqInfoActivity, KComponent, _L8("CUpnpSPRequestInfoActivity::TSendUnsubscribeResponse::DoL"))); + + TUpnpMessage::TUPnPRequestInfo& requestMsg = message_cast< TUpnpMessage::TUPnPRequestInfo > ( iContext.iMessage ); + CTransaction* transaction = static_cast ( requestMsg.iPtr ); + + + CUpnpSPRequestInfoActivity& activity = static_cast< CUpnpSPRequestInfoActivity& > ( *iContext.iNodeActivity ); + THTTPHdrVal sidField; + TInt err = activity.GetHeaderValue ( *transaction->Request( ), UPnP::ESID, sidField, TUPnPTable::Table() ); + __ASSERT_DEBUG ( err != KErrNotFound, User::Invariant ( ) ); + + + CUPnPSubscribeInfoContainer* container = iContext.Node ( ).GetSubscribeInfoContainer ( ); + CUPnPSubscribeInfoElement* element = container->GetSubscribeInfoBySid( sidField.StrF ( ).DesC ( ) ); + + TInt statusCode = HTTPStatus::EOk; + if ( element == NULL ) + { + // susbscription is expired send 412 error condition + statusCode = HTTPStatus::EPreconditionFailed; + } + else + { + container->DeleteSubscribeInfoElement(element); + } + if ( IsLastSubscription ( ) ) + { + // trigger CPR to stop subscription timer + RClientInterface::OpenPostMessageClose ( iContext.NodeId (), iContext.Node ().ControlProvider ()->RecipientId (), + TUpnpMessage::TStopTimer ().CRef () ); + } + RClientInterface::OpenPostMessageClose ( iContext.NodeId (), iContext.iSender, + TUpnpMessage::TUPnPResponseInfo ( transaction, statusCode, NULL ).CRef () ); + } + + +TBool CUpnpSPRequestInfoActivity::TSendUnsubscribeResponse::IsLastSubscription ( ) + { + const CUPnPSubscribeInfoContainer* container = iContext.Node ( ).GetSubscribeInfoContainer ( ); + return container->CountOfSubscribeInfoElementArray( ) == 0 ? ETrue : EFalse; + } + + +TInt CUpnpSPRequestInfoActivity::GetHeaderValue ( CRequest& aRequest, TInt aFieldIndex, THTTPHdrVal& aFieldVal, const TStringTable& aTable ) + { + RRequest request = aRequest.Handle ( ); + RHTTPHeaders headers = request.GetHeaderCollection ( ); + RStringF fieldStr = aRequest.StringPool ( ).StringF ( aFieldIndex , aTable ); + return headers.GetField ( fieldStr, 0, aFieldVal ); + } + +// -----------------------Client Flow Creation--------------------------------------------- +CNodeActivityBase* CNotifyFlowFinder::NewL ( const TNodeActivity& aActivitySig, AMMNodeBase& aNode ) + { + TUint activityId = GetNextActivityCountL ( aActivitySig, aNode ); + return ( new ( ELeave ) CNotifyFlowFinder ( aActivitySig, aNode, activityId ) ); + } + + +CNotifyFlowFinder::~CNotifyFlowFinder ( ) + { + SetError( KErrNone ); + } + + +CNotifyFlowFinder::CNotifyFlowFinder ( const TNodeActivity& aActivitySig, AMMNodeBase& aNode, TUint aActivityCount ) +:CNodeParallelActivityBase ( aActivitySig, aNode, aActivityCount ) + { + } + +DEFINE_SMELEMENT ( CNotifyFlowFinder::TFindOrCreateFlow, NetStateMachine::MStateTransition, CNotifyFlowFinder::TContext ) +void CNotifyFlowFinder::TFindOrCreateFlow::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPClntFlowCreationActivity, KComponent, _L8("CNotifyFlowFinder::TFindOrCreateFlow::DoL"))); + CNotifyFlowFinder& activity = static_cast< CNotifyFlowFinder& > ( *iContext.iNodeActivity ); + + TUpnpMessage::TCreateNotifyFlow& createFlowMsg = message_cast< TUpnpMessage::TCreateNotifyFlow > ( iContext.iMessage ); + activity.iSubscribeInfo = static_cast< CUPnPSubscribeInfoElement* > ( createFlowMsg.iPtr ); + + TNodeId factoryContainer = SockManGlobals::Get( )->GetPlaneFC( TCFPlayerRole ( TCFPlayerRole::EDataPlane ) ); + + const TUid requestedUid = { CUPnPFlowFactory::iUid }; + THttpClientFlowQuery flowQuery ( activity.iSubscribeInfo->RemoteAddr( ), iContext.NodeId (), EHttpClientFlow, THttpClientFlowQuery::EUseExisting ); + + activity.PostRequestTo ( factoryContainer, TCFFactory::TFindOrCreatePeer ( TCFPlayerRole::EDataPlane, requestedUid, &flowQuery ).CRef () ); + } + + +DEFINE_SMELEMENT ( CNotifyFlowFinder::TProcessDataClient, NetStateMachine::MStateTransition, CNotifyFlowFinder::TContext ) +void CNotifyFlowFinder::TProcessDataClient::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPClntFlowCreationActivity, KComponent, _L8("CNotifyFlowFinder::TProcessDataClient::DoL"))); + CNotifyFlowFinder& activity = static_cast< CNotifyFlowFinder& > ( *iContext.iNodeActivity ); + + //TNodeId dataClient = ( message_cast ( iContext.iMessage ) ).iSender; + activity.iSubscribeInfo->SetFlowId ( address_cast ( iContext.iSender ) ); + + if ( !iContext.Node ( ).IsClosing ( ) ) + { + // send the intial notify message + RClientInterface::OpenPostMessageClose ( iContext.NodeId (), iContext.NodeId (), TUpnpMessage::TNotifyRequest ( activity.iSubscribeInfo ).CRef () ); + } + } + + +//---------------------Event Notification Activity------------------------------------- +CNodeActivityBase* CUpnpEventNotificationActivity::NewL ( const TNodeActivity& aActivitySig, AMMNodeBase& aNode ) + { + TUint activityId = GetNextActivityCountL ( aActivitySig, aNode ); + return ( new ( ELeave ) CUpnpEventNotificationActivity ( aActivitySig, aNode, activityId ) ); + } + + +CUpnpEventNotificationActivity::CUpnpEventNotificationActivity ( const TNodeActivity& aActivitySig, AMMNodeBase& aNode, TUint aActivitiesCount ) +:CNodeParallelActivityBase ( aActivitySig, aNode, aActivitiesCount ) + { + } + +// Transitions +DEFINE_SMELEMENT ( CUpnpEventNotificationActivity::TSendRequest, NetStateMachine::MStateTransition, CUpnpEventNotificationActivity::TContext ) +void CUpnpEventNotificationActivity::TSendRequest::DoL ( ) + { + LOG(ESockLogExternal::Printf(KSubsysSPEventNotifyActivity, KComponent, _L8("CUpnpEventNotificationActivity::TSendRequest::DoL"))); + CUpnpEventNotificationActivity& activity = static_cast< CUpnpEventNotificationActivity& > ( *iContext.iNodeActivity ); + + RMemoryAllocator allocator = iContext.Node ( ).ConnectionProvider().MemoryAllocator(); + + const CUPnPSubscribeInfoContainer* cont = iContext.Node ( ).GetSubscribeInfoContainer ( ); + + TUpnpMessage::TNotifyRequest& msg = message_cast< TUpnpMessage::TNotifyRequest > ( iContext.iMessage ); + CUPnPSubscribeInfoElement* subscribeInfo = static_cast< CUPnPSubscribeInfoElement* > ( msg.iPtr );; + + RMemChunk uriBuf; + uriBuf.CreateL( subscribeInfo->CallBackUrl( ), allocator ); + TCleanupItem item ( &UPnPStateMachine::CUPnPUtils::CleanupMBufChain, &uriBuf ); + CleanupStack::PushL ( item ); + + RMemChunk bodyBuf; + bodyBuf.CreateL( cont->EventData(), allocator ); + TCleanupItem item1 ( &UPnPStateMachine::CUPnPUtils::CleanupMBufChain, &bodyBuf ); + CleanupStack::PushL ( item1 ); + + TEventNotifyRequestInfo notifyRequest; + RMemChunk sid; + notifyRequest.iSid.CreateL( subscribeInfo->SubscriptionIdentifier(), allocator ); + notifyRequest.iSeqKey = subscribeInfo->EventKey(); + + activity.PostRequestTo( subscribeInfo->FlowId(), + TUpnpMessage::TUPnPClientRequestInfo ( UPnP::ENotify, uriBuf, bodyBuf, ¬ifyRequest ).CRef () ); + + CleanupStack::Pop ( ); // item + CleanupStack::Pop ( ); // item1 + }