diff -r 510c70acdbf6 -r 8ccc39f9d787 connectivitylayer/isce/isicommunicationmanager_dll/src/isiindicationhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/connectivitylayer/isce/isicommunicationmanager_dll/src/isiindicationhandler.cpp Thu Jan 14 10:44:58 2010 +0200 @@ -0,0 +1,672 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +#include +#include // PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_... +#include // For ISI_HEADER_SIZE +#include // For PN_HEADER_SIZE +#include "isiindicationhandler.h" // For DISIIndicationHandler +#include "isicommunicationmanagertrace.h" // For C_TRACE.. +#include "misiobjectrouterif.h" // For DISICommunicationManager +#include "memapi.h" // For MemApi +#include "iadhelpers.h" // For SET_RECEIVER_OBJ... +#include "nsisi.h" // For PN_MEDIA_ROUTING_REQ +#include "ape_commgrisi.h" // For APE_COMMGR.. + + +/* PUTB8 macro writes byte value to given address. + * This macro is used mainly by other PUTBXX macros. + */ +#define PUTB8(p,v) \ + {(*(TUint8 *)(p)) = ((TUint8)(v));} + + +/* PUTB16 macro writes 16-bit value in Big Endian format + * to given address. 16-bit value is written as two separate + * bytes, and so this macro can write 16-bit value to whatever + * address, regardless of the processor alignment restrictions + */ +#define PUTB16(p,v) \ + {PUTB8((p),(TUint16)(v)>>8); PUTB8((TUint8*)(p)+1,v);} + + +/* PUTB32 macro writes 32-bit value in Big Endian format + * to given address. 32-bit value is written as four separate + * bytes, and so this macro can write 32-bit value to whatever + * address, regardless of the processor alignment restrictions + */ +#define PUTB32(p,v) \ + {PUTB16((p),(TUint32)(v)>>16); PUTB16((TUint8*)(p)+2,(TUint32)(v));} + +/** + * Big Endian to local endian type + */ + /* GETB8 macro returns byte value from given address. + * This macro is used mainly by other GETBXX macros. + */ +#define GETB8(p) \ + (*(TUint8 *)(p)) + + +/* GETB16 macro reads 16-bit value in Big Endian format + * from given address. 16-bit value is read as two separate + * bytes, and so this macro can read 16-bit value from whatever + * address, regardless of the processor alignment restrictions + */ +#define GETB16(p) \ + (((TUint16) GETB8(p)<<8) | (TUint16) GETB8((TUint8 *)(p)+1)) + +#define GETB32(p) \ + (((TUint32) GETB16(p)<<16) | (TUint32) GETB16((TUint8 *)(p)+2)) + +// Faults +enum TISIIndincationHandlerFaults + { + EISIIndicationHandlerWrongParameter = 0x01, + EISIIndicationHandlerMemAllocFailure, + EISIIndicationHandlerMemAllocFailure1, + EISIIndicationHandlerMemAllocFailure2, + EISIIndicationHandlerMemAllocFailure3, + }; + + +// ----------------------------------------------------------------------------- +// DISIIndicationHandler:: +// +// ----------------------------------------------------------------------------- +// +DISIIndicationHandler::DISIIndicationHandler( + MISIObjectRouterIf* aRouter + ) : iRouter( aRouter ) + { + C_TRACE( ( _T( "DISIIndicationHandler::DISIIndicationHandler 0x%x>" ), &iRouter ) ); + C_TRACE( ( _T( "DISIIndicationHandler::DISIIndicationHandler 0x%x<" ), &iRouter ) ); + } + +// ----------------------------------------------------------------------------- +// DISIIndicationHandler::~DISIIndicationHandler +// +// ----------------------------------------------------------------------------- +// +DISIIndicationHandler::~DISIIndicationHandler( + // None + ) + { + C_TRACE( ( _T( "DISIIndicationHandler::~DISIIndicationHandler>" ) ) ); + + SDblQueLink* deviceAnchor = &iDeviceQ.iA; + SDblQueLink* next = deviceAnchor->iNext; + TDeviceIdLink* deviceLink = NULL; + + SDblQueLink* serverAnchor = NULL; + SDblQueLink* serverNext = NULL; + TServerIdLink* serverLink = NULL; + + SDblQueLink* indicationAnchor = NULL; + SDblQueLink* indicationNext = NULL; + TIndicationLink* indicationLink = NULL; + + SDblQueLink* subscriberAnchor = NULL; + SDblQueLink* subscriberNext = NULL; + TSubscriberLink* subscriberLink = NULL; + + while( deviceAnchor != next ) + { + deviceLink = _LOFF( next, TDeviceIdLink, iDeviceLink ); + C_TRACE( ( _T("DISIIndicationHandler::~DISIIndicationHandler device: 0x%x"), deviceLink->iDeviceId ) ); + serverAnchor = &deviceLink->iServerQ.iA; + serverNext = serverAnchor->iNext; + while( serverAnchor != serverNext ) + { + serverLink = _LOFF( serverNext, TServerIdLink, iServerLink ); + indicationAnchor = &serverLink->iIndicationQ.iA; + indicationNext = indicationAnchor->iNext; + while( indicationAnchor != indicationNext ) + { + indicationLink = _LOFF( indicationNext, TIndicationLink, iIndicationLink ); + C_TRACE( ( _T("DISIIndicationHandler::~DISIIndicationHandler indication: 0x%x"), indicationLink->iIndication )); + // get next link already in case if particular link is to be deleted + indicationNext = indicationNext->iNext; + subscriberAnchor = &indicationLink->iSubscriberQ.iA; + subscriberNext = subscriberAnchor->iNext; + while( subscriberAnchor != subscriberNext ) + { + subscriberLink = _LOFF( subscriberNext, TSubscriberLink, iSubscriberLink ); + C_TRACE( ( _T("DISIIndicationHandler::~DISIIndicationHandler subscriber: 0x%x"), subscriberLink->iObjId )); + TBool onlySubscriber( subscriberLink->iSubscriberLink.Alone() ); + subscriberLink->iSubscriberLink.Deque(); + delete subscriberLink; + subscriberLink = NULL; + if( onlySubscriber ) + { + C_TRACE( ( _T("DISIIndicationHandler::~DISIIndicationHandler remove indication: 0x%x"), indicationLink->iIndication )); + indicationLink->iIndicationLink.Deque(); + delete indicationLink; + indicationLink = NULL; + } + // No need to go through rest of subscriberlinks since this one already found and deleted + subscriberNext = subscriberAnchor; + } + } + indicationAnchor = &serverLink->iIndicationQ.iA; + indicationNext = indicationAnchor->iNext; + serverNext = serverNext->iNext; + if( indicationAnchor == indicationNext ) + { + // No more indications on the server -> server link can be deleted + C_TRACE( ( _T("DISIIndicationHandler::~DISIIndicationHandler remove server: 0x%x"), serverLink->iResourceId )); + serverLink->iServerLink.Deque(); + delete serverLink; + serverLink = NULL; + } + } + serverAnchor = &deviceLink->iServerQ.iA; + serverNext = serverAnchor->iNext; + next = next->iNext; + if( serverAnchor == serverNext ) + { + // No more servers on the device -> device link can be deleted + C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription remove device: 0x%x"), deviceLink->iDeviceId )); + deviceLink->iDeviceLink.Deque(); + delete deviceLink; + deviceLink = NULL; + } + } + C_TRACE( ( _T( "DISIIndicationHandler::~DISIIndicationHandler<" ) ) ); + } + + +// ----------------------------------------------------------------------------- +// DISIIndicationHandler::Subscribe +// +// ----------------------------------------------------------------------------- +// +TInt DISIIndicationHandler::Subscribe( + TDes8& aSubscriptionReq + ) + { + C_TRACE( ( _T( "DISIIndicationHandler::Subscribe 0x%x>" ), &aSubscriptionReq ) ); + + TUint8* msgPtr( const_cast( aSubscriptionReq.Ptr() ) ); + + TInt msgLength( aSubscriptionReq.Length() ); + TUint32 resourceId( 0 ); + TUint8 deviceId( 0 ); + TUint8 indication( 0 ); + TUint16 objId( 0 ); + + objId = msgPtr[ ISI_HEADER_OFFSET_SENDEROBJECT ]; + RemoveSubscription( objId ); + for( TInt subBlockOffset( ISI_HEADER_SIZE + SIZE_APE_COMMGR_SUBSCRIBE_REQ ); subBlockOffset < msgLength; subBlockOffset += ( SIZE_APE_COMMGR_SUBSCRIBE_SB ) ) + { + deviceId = msgPtr[ subBlockOffset + APE_COMMGR_SUBSCRIBE_SB_OFFSET_DEVICEID ]; + resourceId = GETB32( &msgPtr[ subBlockOffset + APE_COMMGR_SUBSCRIBE_SB_OFFSET_FILLERBYTE1 ] ); //resource offset + indication = msgPtr[ subBlockOffset + APE_COMMGR_SUBSCRIBE_SB_OFFSET_RESOURCEID ]; + C_TRACE( ( _T("DISIIndicationHandler indication 0x%x objId 0x%x resource 0x%x device 0x%x"), indication, objId, resourceId, deviceId ) ); + TDeviceIdLink* deviceLink = GetDeviceLink( deviceId ); + if( !deviceLink ) + { + C_TRACE( ( _T("DISIIndicationHandler::Subscribe device not found yet -> create: 0x%x"), deviceId ) ); + deviceLink = new TDeviceIdLink(); + ASSERT_RESET_ALWAYS( deviceLink, ( EISIIndicationHandlerMemAllocFailure | EDISIIndicationHandlerTraceId << KClassIdentifierShift ) ); + deviceLink->iDeviceId = deviceId; + iDeviceQ.Add( &( deviceLink->iDeviceLink ) ); + } + AddServer( *deviceLink, resourceId, indication, objId ); + } + +#ifdef _DEBUG +#ifdef COMPONENT_TRACE_FLAG + PrintSubscriptions(); +#endif // COMPONENT_TRACE_FLAG +#endif // _DEBUG + + TDeviceIdLink* deviceLink = NULL; + SDblQueLink* anchor = &iDeviceQ.iA; + SDblQueLink* next = anchor->iNext; + while( anchor != next ) + { + deviceLink = _LOFF( next, TDeviceIdLink, iDeviceLink ); + C_TRACE( ( _T("DISIIndicationHandler::Subscribe device: 0x%x"), deviceLink->iDeviceId ) ); + if( deviceLink->iDeviceId != PN_DEV_OWN ) + { + C_TRACE( ( _T("DISIIndicationHandler::Subscribe send subscription to device: 0x%x"), deviceLink->iDeviceId ) ); + SendSubscription( *deviceLink ); + } + next = next->iNext; + } + C_TRACE( ( _T( "DISIIndicationHandler::Subscribe<" ) ) ); + return KErrNone; + } + + +// ----------------------------------------------------------------------------- +// DISIIndicationHandler::AddServer +// +// ----------------------------------------------------------------------------- +// +void DISIIndicationHandler::AddServer( + TDeviceIdLink& aDeviceLink, + const TUint32 aResourceId, + const TUint8 aIndication, + const TUint16 aObjId + ) + { + C_TRACE( ( _T( "DISIIndicationHandler::AddServer 0x%x 0x%x 0x%x 0x%x>" ), &aDeviceLink, aResourceId, aIndication, aObjId ) ); + + TServerIdLink* serverLink = GetServerLink( aDeviceLink, aResourceId ); + if( !serverLink ) + { + C_TRACE( ( _T("DISIIndicationHandler::AddServer resource: 0x%x not found, create"), aResourceId )); + serverLink = new TServerIdLink(); + ASSERT_RESET_ALWAYS( serverLink, ( EISIIndicationHandlerMemAllocFailure1 | EDISIIndicationHandlerTraceId << KClassIdentifierShift ) ); + serverLink->iResourceId = aResourceId; + aDeviceLink.iServerQ.Add( &( serverLink->iServerLink ) ); + } + AddIndication( *serverLink, aIndication, aObjId ); + C_TRACE( ( _T( "DISIIndicationHandler::AddServer 0x%x 0x%x 0x%x 0x%x<" ), &aDeviceLink, aResourceId, aIndication, aObjId ) ); + } + +// ----------------------------------------------------------------------------- +// DISIIndicationHandler::AddIndication +// +// ----------------------------------------------------------------------------- +// +void DISIIndicationHandler::AddIndication( + TServerIdLink& aServerLink, + const TUint8 aIndication, + const TUint16 aObjId + ) + { + C_TRACE( ( _T( "DISIIndicationHandler::AddIndication 0x%x 0x%x 0x%x>" ), &aServerLink, aIndication, aObjId ) ); + TIndicationLink* indicationLink = GetIndicationLink( aServerLink, aIndication ); + if( !indicationLink ) + { + C_TRACE( ( _T("DISIIndicationHandler::AddIndication Indication: 0x%x not found, create"), aIndication )); + indicationLink = new TIndicationLink(); + ASSERT_RESET_ALWAYS( indicationLink, ( EISIIndicationHandlerMemAllocFailure3 | EDISIIndicationHandlerTraceId << KClassIdentifierShift ) ); + indicationLink->iIndication = aIndication; + aServerLink.iIndicationQ.Add( &( indicationLink->iIndicationLink ) ); + } + AddSubscriber( *indicationLink, aObjId ); + C_TRACE( ( _T( "DISIIndicationHandler::AddIndication 0x%x 0x%x 0x%x<" ), &aServerLink, aIndication, aObjId ) ); + } + +// ----------------------------------------------------------------------------- +// DISIIndicationHandler::AddSubscriber +// +// ----------------------------------------------------------------------------- +// +void DISIIndicationHandler::AddSubscriber( + TIndicationLink& aIndicationLink, + const TUint16 aObjId + ) + { + C_TRACE( ( _T( "DISIIndicationHandler::AddSubscriber 0x%x, 0x%x>" ), &aIndicationLink, aObjId ) ); + TSubscriberLink* subscriberLink = GetSubscriberLink( aIndicationLink, aObjId ); + if( !subscriberLink ) + { + C_TRACE( ( _T("DISIIndicationHandler::AddSubscriber Subscriber not found: 0x%x 0x%x"), aIndicationLink.iIndication, aObjId ) ); + subscriberLink = new TSubscriberLink(); + ASSERT_RESET_ALWAYS( subscriberLink, ( EISIIndicationHandlerMemAllocFailure2 | EDISIIndicationHandlerTraceId << KClassIdentifierShift ) ); + subscriberLink->iObjId = aObjId; + aIndicationLink.iSubscriberQ.Add( &( subscriberLink->iSubscriberLink ) ); + } + else + { + TRACE_ASSERT_INFO(0, (TUint8)aObjId<" ), aDeviceId ) ); + TDeviceIdLink* deviceLink = NULL; + TDeviceIdLink* tmpDeviceLink = NULL; + SDblQueLink* anchor = &iDeviceQ.iA; + SDblQueLink* next = anchor->iNext; + while( anchor != next ) + { + tmpDeviceLink = _LOFF( next, TDeviceIdLink, iDeviceLink ); + C_TRACE( ( _T( "DISIIndicationHandler::GetDeviceLink device: 0x%x"), tmpDeviceLink->iDeviceId ) ); + if( tmpDeviceLink->iDeviceId == aDeviceId ) + { + deviceLink = tmpDeviceLink; + break; + } + next = next->iNext; + } + C_TRACE( ( _T( "DISIIndicationHandler::GetDeviceLink 0x%x <-" ), deviceLink ) ); + return deviceLink; + } + + +// ----------------------------------------------------------------------------- +// DISIIndicationHandler::GetServerLink +// +// ----------------------------------------------------------------------------- +// + +DISIIndicationHandler::TServerIdLink* DISIIndicationHandler::GetServerLink( + TDeviceIdLink& aDeviceLink, + const TUint32 aResourceId + ) + { + C_TRACE( ( _T( "DISIIndicationHandler::GetServerLink 0x%x 0x%x ->" ), &aDeviceLink, aResourceId ) ); + TServerIdLink* serverLink = NULL; + TServerIdLink* tmpServerLink = NULL; + SDblQueLink* anchor = &aDeviceLink.iServerQ.iA; + SDblQueLink* next = anchor->iNext; + while( anchor != next ) // servers + { + tmpServerLink = _LOFF( next, TServerIdLink, iServerLink ); + C_TRACE( ( _T( "DISIIndicationHandler::GetServerLink server: 0x%x"), tmpServerLink->iResourceId ) ); + if( tmpServerLink->iResourceId == aResourceId ) + { + serverLink = tmpServerLink; + break; + } + next = next->iNext; + } + C_TRACE( ( _T( "DISIIndicationHandler::GetServerLink 0x%x <-" ), serverLink ) ); + return serverLink; + } + + +// ----------------------------------------------------------------------------- +// DISIIndicationHandler::GetIndicationLink +// +// ----------------------------------------------------------------------------- +// +DISIIndicationHandler::TIndicationLink* DISIIndicationHandler::GetIndicationLink( + TServerIdLink& aServerLink, + const TUint8 aIndication + ) + { + C_TRACE( ( _T( "DISIIndicationHandler::GetIndicationLink 0x%x 0x%x ->" ), &aServerLink, aIndication ) ); + TIndicationLink* indicationLink = NULL; + TIndicationLink* tmpIndicationLink = NULL; + SDblQueLink* anchor = &aServerLink.iIndicationQ.iA; + SDblQueLink* next = anchor->iNext; + while( anchor != next ) + { + tmpIndicationLink = _LOFF( next, TIndicationLink, iIndicationLink ); + if( tmpIndicationLink->iIndication == aIndication ) + { + indicationLink = tmpIndicationLink; + break; + } + next = next->iNext; + } + C_TRACE( ( _T( "DISIIndicationHandler::GetIndicationLink 0x%x <-" ), indicationLink ) ); + return indicationLink; + } + +// ----------------------------------------------------------------------------- +// DISIIndicationHandler::GetSubscriberLink +// +// ----------------------------------------------------------------------------- +// +DISIIndicationHandler::TSubscriberLink* DISIIndicationHandler::GetSubscriberLink( + TIndicationLink& aIndicationLink, + const TUint16 aObjId + ) + { + C_TRACE( ( _T( "DISIIndicationHandler::GetSubscriberLink 0x%x, 0x%x ->" ), &aIndicationLink, aObjId ) ); + TSubscriberLink* tmpSubscriberLink = NULL; + TSubscriberLink* subscriberLink = NULL; + SDblQueLink* anchor = &aIndicationLink.iSubscriberQ.iA; + SDblQueLink* next = anchor->iNext; + while( anchor != next ) + { + tmpSubscriberLink= _LOFF( next, TSubscriberLink, iSubscriberLink ); + if ( tmpSubscriberLink->iObjId == aObjId ) + { + subscriberLink = tmpSubscriberLink; + break; + } + next = next->iNext; + } + C_TRACE( ( _T( "DISIIndicationHandler::GetSubscriberLink 0x%x <-" ), subscriberLink ) ); + return subscriberLink; + } + +// ----------------------------------------------------------------------------- +// DISIIndicationHandler::PrintSubscriptions +// +// ----------------------------------------------------------------------------- +// +void DISIIndicationHandler::PrintSubscriptions( + // None + ) + { + C_TRACE( ( _T( "DISIIndicationHandler::PrintSubscriptions>" ) ) ); + TDeviceIdLink* deviceLink = NULL; + SDblQueLink* anchor = &iDeviceQ.iA; + SDblQueLink* next = anchor->iNext; + SDblQueLink* serverAnchor = NULL; + SDblQueLink* serverNext = NULL; + TServerIdLink* serverLink = NULL; + SDblQueLink* indicationAnchor = NULL; + SDblQueLink* indicationNext = NULL; + TIndicationLink* indicationLink = NULL; + SDblQueLink* subscriberAnchor = NULL; + SDblQueLink* subscriberNext = NULL; + TSubscriberLink* subscriberLink = NULL; + while( anchor != next ) + { + deviceLink = _LOFF( next, TDeviceIdLink, iDeviceLink ); + C_TRACE( ( _T("DISIIndicationHandler::PrintSubscriptions device: 0x%x"), deviceLink->iDeviceId ) ); + serverAnchor = &deviceLink->iServerQ.iA; + serverNext = serverAnchor->iNext; + while( serverAnchor != serverNext ) + { + serverLink = _LOFF( serverNext, TServerIdLink, iServerLink ); + C_TRACE( ( _T("DISIIndicationHandler::PrintSubscriptions server: 0x%x"), serverLink->iResourceId ) ); + indicationAnchor = &serverLink->iIndicationQ.iA; + indicationNext = indicationAnchor->iNext; + while( indicationAnchor != indicationNext ) + { + indicationLink = _LOFF( indicationNext, TIndicationLink, iIndicationLink ); + C_TRACE( ( _T("DISIIndicationHandler::PrintSubscriptions indication: 0x%x"), indicationLink->iIndication ) ); + subscriberAnchor = &indicationLink->iSubscriberQ.iA; + subscriberNext = subscriberAnchor->iNext; + while( subscriberAnchor != subscriberNext) + { + subscriberLink = _LOFF( subscriberNext, TSubscriberLink, iSubscriberLink ); + subscriberLink = subscriberLink; + C_TRACE( ( _T("DISIIndicationHandler::PrintSubscriptions objid: 0x%x"), subscriberLink->iObjId ) ); + subscriberNext = subscriberNext->iNext; + } + indicationNext = indicationNext->iNext; + } + serverNext = serverNext->iNext; + } + next = next->iNext; + } + C_TRACE( ( _T( "DISIIndicationHandler::PrintSubscriptions<" ) ) ); + } + +// ----------------------------------------------------------------------------- +// DISIIndicationHandler::RemoveSubscription +// Removes all subscriptions from objectid +// ----------------------------------------------------------------------------- +// +void DISIIndicationHandler::RemoveSubscription( + const TUint16 aObjId + ) + { + C_TRACE( ( _T( "DISIIndicationHandler::RemoveSubscription 0x%x>" ), aObjId ) ); + + SDblQueLink* deviceAnchor = &iDeviceQ.iA; + SDblQueLink* next = deviceAnchor->iNext; + TDeviceIdLink* deviceLink = NULL; + + SDblQueLink* serverAnchor = NULL; + SDblQueLink* serverNext = NULL; + TServerIdLink* serverLink = NULL; + + SDblQueLink* indicationAnchor = NULL; + SDblQueLink* indicationNext = NULL; + TIndicationLink* indicationLink = NULL; + + SDblQueLink* subscriberAnchor = NULL; + SDblQueLink* subscriberNext = NULL; + TSubscriberLink* subscriberLink = NULL; + + while( deviceAnchor != next ) + { + deviceLink = _LOFF( next, TDeviceIdLink, iDeviceLink ); + C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription device: 0x%x"), deviceLink->iDeviceId ) ); + serverAnchor = &deviceLink->iServerQ.iA; + serverNext = serverAnchor->iNext; + while( serverAnchor != serverNext ) + { + serverLink = _LOFF( serverNext, TServerIdLink, iServerLink ); + indicationAnchor = &serverLink->iIndicationQ.iA; + indicationNext = indicationAnchor->iNext; + while( indicationAnchor != indicationNext ) + { + indicationLink = _LOFF( indicationNext, TIndicationLink, iIndicationLink ); + C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription indication: 0x%x"), indicationLink->iIndication )); + // get next link already in case if particular link is to be deleted + indicationNext = indicationNext->iNext; + subscriberAnchor = &indicationLink->iSubscriberQ.iA; + subscriberNext = subscriberAnchor->iNext; + while( subscriberAnchor != subscriberNext ) + { + subscriberLink = _LOFF( subscriberNext, TSubscriberLink, iSubscriberLink ); + C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription objid: 0x%x"), subscriberLink->iObjId )); + if( subscriberLink->iObjId == aObjId ) + { + C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription remove objid: 0x%x"), subscriberLink->iObjId )); + TBool onlySubscriber( subscriberLink->iSubscriberLink.Alone() ); + subscriberLink->iSubscriberLink.Deque(); + delete subscriberLink; + subscriberLink = NULL; + if( onlySubscriber ) + { + C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription remove indication: 0x%x"), indicationLink->iIndication )); + indicationLink->iIndicationLink.Deque(); + delete indicationLink; + indicationLink = NULL; + } + // No need to go through rest of subscriberlinks since this one already found and deleted + subscriberNext = subscriberAnchor; + } + else + { + subscriberNext = subscriberNext->iNext; + } + } + } + indicationAnchor = &serverLink->iIndicationQ.iA; + indicationNext = indicationAnchor->iNext; + serverNext = serverNext->iNext; + if( indicationAnchor == indicationNext ) + { + // No more indications for the server -> server link can be deleted + C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription remove server: 0x%x"), serverLink->iResourceId )); + serverLink->iServerLink.Deque(); + delete serverLink; + serverLink = NULL; + } + } + serverAnchor = &deviceLink->iServerQ.iA; + serverNext = serverAnchor->iNext; + next = next->iNext; + if( serverAnchor == serverNext ) + { + // No more servers for the device -> device link can be deleted + C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription remove device: 0x%x"), deviceLink->iDeviceId )); + deviceLink->iDeviceLink.Deque(); + delete deviceLink; + deviceLink = NULL; + } + } + C_TRACE( ( _T( "DISIIndicationHandler::RemoveSubscription 0x%x<" ), aObjId ) ); + } + +// ----------------------------------------------------------------------------- +// DISIIndicationHandler::SendSubscription +// +// ----------------------------------------------------------------------------- +// +TInt DISIIndicationHandler::SendSubscription( TDeviceIdLink& aDevice ) + { + C_TRACE( ( _T( "DISIIndicationHandler::SendSubscription>" ) ) ); + const TUint8 KMaxAmountOfResources( 255 ); + const TUint8 KPnsSubscribedResourcesExtendLength( 12 ); + const TUint8 KResourceArraySize( 4 ); + + TDes8& desPtr = MemApi::AllocBlock( ISI_HEADER_SIZE + SIZE_PNS_SUBSCRIBED_RESOURCES_EXTEND_IND + ( KMaxAmountOfResources * KResourceArraySize ) ); + + TUint8* ptr( const_cast( desPtr.Ptr() ) ); + ptr[ ISI_HEADER_OFFSET_MEDIA ] = PN_MEDIA_ROUTING_REQ; + SET_RECEIVER_DEV( ptr, aDevice.iDeviceId ); + SET_SENDER_DEV( ptr, PN_DEV_OWN ); + ptr[ ISI_HEADER_OFFSET_RESOURCEID ] = PN_COMMGR; + SET_RECEIVER_OBJ( ptr, PN_OBJ_ROUTER ); + SET_SENDER_OBJ( ptr, PN_OBJ_EVENT_MULTICAST ); + ptr[ ISI_HEADER_SIZE + PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_OFFSET_TRANSACTIONID ] = 0x00; + ptr[ ISI_HEADER_SIZE + PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_OFFSET_MESSAGEID ] = PNS_SUBSCRIBED_RESOURCES_EXTEND_IND; + ptr[ ISI_HEADER_SIZE + PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_OFFSET_FILLER ] = 0x00; + + TServerIdLink* serverLink = NULL; + SDblQueLink* anchor = &(aDevice.iServerQ.iA); + SDblQueLink* next = anchor->iNext; + + TUint8 resourceCount( 0x00 ); + while( anchor != next ) + { + serverLink = _LOFF( next, TServerIdLink, iServerLink ); + TUint32 resourceId = serverLink->iResourceId; + C_TRACE( ( _T("DISIIndicationHandler::SendSubscription Server: 0x%08x"), resourceId ) ); + PUTB32( &ptr[ ISI_HEADER_SIZE + PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_OFFSET_RESOURCELIST ], resourceId ); + resourceCount++; + next = next->iNext; + } + ptr[ ISI_HEADER_SIZE + PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_OFFSET_RESOURCECOUNT ] = resourceCount; + TInt messageLength( ( resourceCount * KResourceArraySize ) + KPnsSubscribedResourcesExtendLength ); + while( messageLength % 4 != 0 ) + { + TRACE_ASSERT_INFO(0, messageLength); + messageLength++; + } + desPtr.SetLength( messageLength ); + SET_LENGTH( ptr, messageLength - PN_HEADER_SIZE ); + + for( TInt i( 0 ); i < desPtr.Length(); i++ ) + { + C_TRACE( ( _T( "index[ %d ] data 0x%x"), i, desPtr.Ptr()[i] ) ); + } + TInt error = iRouter->Send( desPtr, PN_OBJ_EVENT_MULTICAST ); + C_TRACE( ( _T( "DISIIndicationHandler::SendSubscription<" ) ) ); + return error; + } + +// End of file. +