connectivitylayer/isce/isicommunicationmanager_dll/src/isiindicationhandler.cpp
changeset 5 8ccc39f9d787
child 7 fa67e03b87df
equal deleted inserted replaced
4:510c70acdbf6 5:8ccc39f9d787
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include <iscnokiadefinitions.h>
       
    19 #include <pn_eventmodem_extisi.h>         // PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_...
       
    20 #include <phonetisi.h>                    // For ISI_HEADER_SIZE
       
    21 #include <pn_const.h>                     // For PN_HEADER_SIZE
       
    22 #include "isiindicationhandler.h"         // For DISIIndicationHandler
       
    23 #include "isicommunicationmanagertrace.h" // For C_TRACE..
       
    24 #include "misiobjectrouterif.h"           // For DISICommunicationManager
       
    25 #include "memapi.h"                       // For MemApi
       
    26 #include "iadhelpers.h"                   // For SET_RECEIVER_OBJ...
       
    27 #include "nsisi.h"                        // For PN_MEDIA_ROUTING_REQ
       
    28 #include "ape_commgrisi.h"                // For APE_COMMGR..
       
    29 
       
    30 
       
    31 /* PUTB8 macro writes byte value to given address.
       
    32  * This macro is used mainly by other PUTBXX macros.
       
    33  */
       
    34 #define PUTB8(p,v) \
       
    35     {(*(TUint8 *)(p)) = ((TUint8)(v));}
       
    36 
       
    37 
       
    38 /* PUTB16 macro writes 16-bit value in Big Endian format
       
    39  * to given address. 16-bit value is written as two separate
       
    40  * bytes, and so this macro can write 16-bit value to whatever
       
    41  * address, regardless of the processor alignment restrictions
       
    42  */
       
    43 #define PUTB16(p,v) \
       
    44     {PUTB8((p),(TUint16)(v)>>8); PUTB8((TUint8*)(p)+1,v);}
       
    45 
       
    46 
       
    47 /* PUTB32 macro writes 32-bit value in Big Endian format
       
    48  * to given address. 32-bit value is written as four separate
       
    49  * bytes, and so this macro can write 32-bit value to whatever
       
    50  * address, regardless of the processor alignment restrictions
       
    51  */
       
    52 #define PUTB32(p,v) \
       
    53     {PUTB16((p),(TUint32)(v)>>16); PUTB16((TUint8*)(p)+2,(TUint32)(v));}
       
    54 
       
    55 /**
       
    56  *    Big Endian to local endian type
       
    57  */
       
    58  /* GETB8 macro returns byte value from given address.
       
    59  * This macro is used mainly by other GETBXX macros.
       
    60  */
       
    61 #define GETB8(p) \
       
    62     (*(TUint8 *)(p))
       
    63 
       
    64 
       
    65 /* GETB16 macro reads 16-bit value in Big Endian format
       
    66  * from given address. 16-bit value is read as two separate
       
    67  * bytes, and so this macro can read 16-bit value from whatever
       
    68  * address, regardless of the processor alignment restrictions
       
    69  */
       
    70 #define GETB16(p) \
       
    71     (((TUint16) GETB8(p)<<8) | (TUint16) GETB8((TUint8 *)(p)+1))
       
    72 
       
    73 #define GETB32(p) \
       
    74     (((TUint32) GETB16(p)<<16) | (TUint32) GETB16((TUint8 *)(p)+2))
       
    75 
       
    76 // Faults
       
    77 enum TISIIndincationHandlerFaults
       
    78     {
       
    79     EISIIndicationHandlerWrongParameter = 0x01,
       
    80     EISIIndicationHandlerMemAllocFailure,
       
    81     EISIIndicationHandlerMemAllocFailure1,
       
    82     EISIIndicationHandlerMemAllocFailure2,
       
    83     EISIIndicationHandlerMemAllocFailure3,
       
    84     };
       
    85 
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // DISIIndicationHandler::
       
    89 //
       
    90 // -----------------------------------------------------------------------------
       
    91 //
       
    92 DISIIndicationHandler::DISIIndicationHandler(
       
    93         MISIObjectRouterIf* aRouter
       
    94         ) : iRouter( aRouter )
       
    95     {
       
    96     C_TRACE( ( _T( "DISIIndicationHandler::DISIIndicationHandler 0x%x>" ), &iRouter ) );
       
    97     C_TRACE( ( _T( "DISIIndicationHandler::DISIIndicationHandler 0x%x<" ), &iRouter ) );
       
    98     }
       
    99 
       
   100 // -----------------------------------------------------------------------------
       
   101 // DISIIndicationHandler::~DISIIndicationHandler
       
   102 //
       
   103 // -----------------------------------------------------------------------------
       
   104 //
       
   105 DISIIndicationHandler::~DISIIndicationHandler(
       
   106         // None
       
   107         )
       
   108     {
       
   109     C_TRACE( ( _T( "DISIIndicationHandler::~DISIIndicationHandler>" ) ) );
       
   110     
       
   111     SDblQueLink*    deviceAnchor = &iDeviceQ.iA;
       
   112     SDblQueLink*    next = deviceAnchor->iNext;
       
   113     TDeviceIdLink*  deviceLink = NULL;
       
   114     
       
   115     SDblQueLink*        serverAnchor = NULL;
       
   116     SDblQueLink*        serverNext = NULL;
       
   117     TServerIdLink*      serverLink = NULL;
       
   118 
       
   119     SDblQueLink*        indicationAnchor = NULL;
       
   120     SDblQueLink*        indicationNext = NULL;
       
   121     TIndicationLink*    indicationLink = NULL;
       
   122 
       
   123     SDblQueLink*        subscriberAnchor = NULL;
       
   124     SDblQueLink*        subscriberNext = NULL;
       
   125     TSubscriberLink*    subscriberLink = NULL;
       
   126     
       
   127     while( deviceAnchor != next )
       
   128         {
       
   129         deviceLink = _LOFF( next, TDeviceIdLink, iDeviceLink );
       
   130         C_TRACE( ( _T("DISIIndicationHandler::~DISIIndicationHandler device: 0x%x"), deviceLink->iDeviceId ) );
       
   131         serverAnchor = &deviceLink->iServerQ.iA;
       
   132         serverNext = serverAnchor->iNext;
       
   133         while( serverAnchor != serverNext )
       
   134             {
       
   135             serverLink = _LOFF( serverNext, TServerIdLink, iServerLink );
       
   136             indicationAnchor = &serverLink->iIndicationQ.iA;
       
   137             indicationNext = indicationAnchor->iNext;
       
   138             while( indicationAnchor != indicationNext )
       
   139                 {
       
   140                 indicationLink = _LOFF( indicationNext, TIndicationLink, iIndicationLink );
       
   141                 C_TRACE( ( _T("DISIIndicationHandler::~DISIIndicationHandler indication: 0x%x"), indicationLink->iIndication ));
       
   142                 // get next link already in case if particular link is to be deleted
       
   143                 indicationNext = indicationNext->iNext;
       
   144                 subscriberAnchor = &indicationLink->iSubscriberQ.iA;
       
   145                 subscriberNext = subscriberAnchor->iNext;
       
   146                 while( subscriberAnchor != subscriberNext )
       
   147                     {
       
   148                     subscriberLink = _LOFF( subscriberNext, TSubscriberLink, iSubscriberLink );
       
   149                     C_TRACE( ( _T("DISIIndicationHandler::~DISIIndicationHandler subscriber: 0x%x"), subscriberLink->iObjId ));
       
   150                     TBool onlySubscriber( subscriberLink->iSubscriberLink.Alone() );
       
   151                     subscriberLink->iSubscriberLink.Deque();
       
   152                     delete subscriberLink;
       
   153                     subscriberLink = NULL;
       
   154                     if( onlySubscriber )
       
   155                         {
       
   156                         C_TRACE( ( _T("DISIIndicationHandler::~DISIIndicationHandler remove indication: 0x%x"), indicationLink->iIndication ));
       
   157                         indicationLink->iIndicationLink.Deque();
       
   158                         delete indicationLink;
       
   159                         indicationLink = NULL;
       
   160                         }
       
   161                     // No need to go through rest of subscriberlinks since this one already found and deleted
       
   162                     subscriberNext = subscriberAnchor;      
       
   163                     }
       
   164                 }
       
   165             indicationAnchor = &serverLink->iIndicationQ.iA;
       
   166             indicationNext = indicationAnchor->iNext;
       
   167             serverNext = serverNext->iNext;
       
   168             if( indicationAnchor == indicationNext )
       
   169                 {
       
   170                 // No more indications on the server -> server link can be deleted
       
   171                 C_TRACE( ( _T("DISIIndicationHandler::~DISIIndicationHandler remove server: 0x%x"), serverLink->iResourceId ));
       
   172                 serverLink->iServerLink.Deque();
       
   173                 delete serverLink;
       
   174                 serverLink = NULL;
       
   175                 }
       
   176             }
       
   177         serverAnchor = &deviceLink->iServerQ.iA;
       
   178         serverNext = serverAnchor->iNext;
       
   179         next = next->iNext;
       
   180         if( serverAnchor == serverNext )
       
   181             {
       
   182             // No more servers on the device -> device link can be deleted
       
   183             C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription remove device: 0x%x"), deviceLink->iDeviceId ));
       
   184             deviceLink->iDeviceLink.Deque();
       
   185             delete deviceLink;
       
   186             deviceLink = NULL;
       
   187             }
       
   188         }
       
   189     C_TRACE( ( _T( "DISIIndicationHandler::~DISIIndicationHandler<" ) ) );
       
   190     }
       
   191 
       
   192 
       
   193 // -----------------------------------------------------------------------------
       
   194 // DISIIndicationHandler::Subscribe
       
   195 //
       
   196 // -----------------------------------------------------------------------------
       
   197 //
       
   198 TInt DISIIndicationHandler::Subscribe(
       
   199         TDes8& aSubscriptionReq
       
   200         )
       
   201     {
       
   202     C_TRACE( ( _T( "DISIIndicationHandler::Subscribe 0x%x>" ), &aSubscriptionReq ) );
       
   203     
       
   204     TUint8* msgPtr( const_cast<TUint8*>( aSubscriptionReq.Ptr() ) );
       
   205     
       
   206     TInt msgLength( aSubscriptionReq.Length() ); 
       
   207     TUint32 resourceId( 0 );
       
   208     TUint8 deviceId( 0 );
       
   209     TUint8 indication( 0 );
       
   210     TUint16 objId( 0 );
       
   211       
       
   212     objId = msgPtr[ ISI_HEADER_OFFSET_SENDEROBJECT ];
       
   213     RemoveSubscription( objId );
       
   214     for( TInt subBlockOffset( ISI_HEADER_SIZE + SIZE_APE_COMMGR_SUBSCRIBE_REQ ); subBlockOffset < msgLength; subBlockOffset += ( SIZE_APE_COMMGR_SUBSCRIBE_SB ) )
       
   215         {
       
   216         deviceId = msgPtr[ subBlockOffset + APE_COMMGR_SUBSCRIBE_SB_OFFSET_DEVICEID ];
       
   217         resourceId = GETB32( &msgPtr[ subBlockOffset + APE_COMMGR_SUBSCRIBE_SB_OFFSET_FILLERBYTE1 ] ); //resource offset
       
   218         indication = msgPtr[ subBlockOffset + APE_COMMGR_SUBSCRIBE_SB_OFFSET_RESOURCEID ];
       
   219         C_TRACE( ( _T("DISIIndicationHandler indication 0x%x objId 0x%x resource 0x%x device 0x%x"), indication, objId, resourceId, deviceId ) );
       
   220         TDeviceIdLink* deviceLink = GetDeviceLink( deviceId );
       
   221         if( !deviceLink )
       
   222             {
       
   223             C_TRACE( ( _T("DISIIndicationHandler::Subscribe device not found yet -> create: 0x%x"), deviceId ) );
       
   224             deviceLink = new TDeviceIdLink();
       
   225             ASSERT_RESET_ALWAYS( deviceLink, ( EISIIndicationHandlerMemAllocFailure | EDISIIndicationHandlerTraceId << KClassIdentifierShift ) );
       
   226             deviceLink->iDeviceId = deviceId;
       
   227             iDeviceQ.Add( &( deviceLink->iDeviceLink ) );
       
   228             }
       
   229         AddServer( *deviceLink, resourceId, indication, objId );
       
   230         }
       
   231         
       
   232 #ifdef _DEBUG
       
   233 #ifdef COMPONENT_TRACE_FLAG
       
   234     PrintSubscriptions();
       
   235 #endif // COMPONENT_TRACE_FLAG
       
   236 #endif // _DEBUG
       
   237     
       
   238     TDeviceIdLink* deviceLink = NULL;
       
   239     SDblQueLink* anchor = &iDeviceQ.iA;
       
   240     SDblQueLink* next = anchor->iNext;
       
   241     while( anchor != next )
       
   242         {
       
   243         deviceLink = _LOFF( next, TDeviceIdLink, iDeviceLink );
       
   244         C_TRACE( ( _T("DISIIndicationHandler::Subscribe device: 0x%x"), deviceLink->iDeviceId ) );
       
   245         if( deviceLink->iDeviceId != PN_DEV_OWN )
       
   246             {
       
   247             C_TRACE( ( _T("DISIIndicationHandler::Subscribe send subscription to device: 0x%x"), deviceLink->iDeviceId ) );
       
   248             SendSubscription( *deviceLink );
       
   249             }
       
   250         next = next->iNext;
       
   251         }
       
   252     C_TRACE( ( _T( "DISIIndicationHandler::Subscribe<" ) ) );
       
   253     return KErrNone;
       
   254     }
       
   255 
       
   256 
       
   257 // -----------------------------------------------------------------------------
       
   258 // DISIIndicationHandler::AddServer
       
   259 //
       
   260 // -----------------------------------------------------------------------------
       
   261 //
       
   262 void DISIIndicationHandler::AddServer(
       
   263         TDeviceIdLink& aDeviceLink,
       
   264         const TUint32 aResourceId,
       
   265         const TUint8 aIndication,
       
   266         const TUint16 aObjId
       
   267         )
       
   268     {
       
   269     C_TRACE( ( _T( "DISIIndicationHandler::AddServer 0x%x 0x%x 0x%x 0x%x>" ), &aDeviceLink, aResourceId, aIndication, aObjId ) );
       
   270     
       
   271     TServerIdLink* serverLink = GetServerLink( aDeviceLink, aResourceId );
       
   272     if( !serverLink )
       
   273         {
       
   274         C_TRACE( ( _T("DISIIndicationHandler::AddServer resource: 0x%x not found, create"), aResourceId ));
       
   275         serverLink = new TServerIdLink();
       
   276         ASSERT_RESET_ALWAYS( serverLink, ( EISIIndicationHandlerMemAllocFailure1 | EDISIIndicationHandlerTraceId << KClassIdentifierShift ) );
       
   277         serverLink->iResourceId = aResourceId;
       
   278         aDeviceLink.iServerQ.Add( &( serverLink->iServerLink ) );
       
   279         }
       
   280     AddIndication( *serverLink, aIndication, aObjId );
       
   281     C_TRACE( ( _T( "DISIIndicationHandler::AddServer 0x%x 0x%x 0x%x 0x%x<" ), &aDeviceLink, aResourceId, aIndication, aObjId ) );
       
   282     }
       
   283 
       
   284 // -----------------------------------------------------------------------------
       
   285 // DISIIndicationHandler::AddIndication
       
   286 //
       
   287 // -----------------------------------------------------------------------------
       
   288 //
       
   289 void DISIIndicationHandler::AddIndication(
       
   290         TServerIdLink& aServerLink,
       
   291         const TUint8 aIndication,
       
   292         const TUint16 aObjId
       
   293         )
       
   294     {
       
   295     C_TRACE( ( _T( "DISIIndicationHandler::AddIndication 0x%x 0x%x 0x%x>" ), &aServerLink, aIndication, aObjId ) );
       
   296     TIndicationLink* indicationLink = GetIndicationLink( aServerLink, aIndication );
       
   297     if( !indicationLink )
       
   298         {
       
   299         C_TRACE( ( _T("DISIIndicationHandler::AddIndication Indication: 0x%x not found, create"), aIndication ));
       
   300         indicationLink = new TIndicationLink();
       
   301         ASSERT_RESET_ALWAYS( indicationLink, ( EISIIndicationHandlerMemAllocFailure3 | EDISIIndicationHandlerTraceId << KClassIdentifierShift ) );
       
   302         indicationLink->iIndication = aIndication;
       
   303         aServerLink.iIndicationQ.Add( &( indicationLink->iIndicationLink ) );
       
   304         }
       
   305     AddSubscriber( *indicationLink, aObjId );
       
   306     C_TRACE( ( _T( "DISIIndicationHandler::AddIndication 0x%x 0x%x 0x%x<" ), &aServerLink, aIndication, aObjId ) );
       
   307     }
       
   308 
       
   309 // -----------------------------------------------------------------------------
       
   310 // DISIIndicationHandler::AddSubscriber
       
   311 //
       
   312 // -----------------------------------------------------------------------------
       
   313 //
       
   314 void DISIIndicationHandler::AddSubscriber(
       
   315         TIndicationLink& aIndicationLink,
       
   316         const TUint16 aObjId
       
   317         )
       
   318     {
       
   319     C_TRACE( ( _T( "DISIIndicationHandler::AddSubscriber 0x%x, 0x%x>" ), &aIndicationLink, aObjId ) );
       
   320     TSubscriberLink* subscriberLink = GetSubscriberLink( aIndicationLink, aObjId );
       
   321     if( !subscriberLink )
       
   322         {
       
   323         C_TRACE( ( _T("DISIIndicationHandler::AddSubscriber Subscriber not found: 0x%x 0x%x"), aIndicationLink.iIndication, aObjId ) );
       
   324         subscriberLink = new TSubscriberLink();
       
   325         ASSERT_RESET_ALWAYS( subscriberLink, ( EISIIndicationHandlerMemAllocFailure2 | EDISIIndicationHandlerTraceId << KClassIdentifierShift ) );
       
   326         subscriberLink->iObjId = aObjId;
       
   327         aIndicationLink.iSubscriberQ.Add( &( subscriberLink->iSubscriberLink ) );
       
   328         }
       
   329     else
       
   330         {
       
   331         TRACE_ASSERT_INFO(0, (TUint8)aObjId<<KObjIdShift);
       
   332         C_TRACE( ( _T( "DISIIndicationHandler::AddSubscriber double subscription 0x%x" ), aObjId ) );
       
   333         }
       
   334     C_TRACE( ( _T( "DISIIndicationHandler::AddSubscriber 0x%x 0x%x<" ), &aIndicationLink, aObjId ) );
       
   335     }
       
   336 
       
   337 // -----------------------------------------------------------------------------
       
   338 // DISIIndicationHandler::GetDeviceLink
       
   339 //
       
   340 // -----------------------------------------------------------------------------
       
   341 //
       
   342 DISIIndicationHandler::TDeviceIdLink* DISIIndicationHandler::GetDeviceLink(
       
   343         const TUint8 aDeviceId
       
   344         )
       
   345     {
       
   346     C_TRACE( ( _T( "DISIIndicationHandler::GetDeviceLink 0x%x ->" ), aDeviceId ) );
       
   347     TDeviceIdLink* deviceLink = NULL;
       
   348     TDeviceIdLink* tmpDeviceLink = NULL;
       
   349     SDblQueLink* anchor = &iDeviceQ.iA;
       
   350     SDblQueLink* next = anchor->iNext;
       
   351     while( anchor != next )
       
   352         {
       
   353         tmpDeviceLink = _LOFF( next, TDeviceIdLink, iDeviceLink );
       
   354         C_TRACE( ( _T( "DISIIndicationHandler::GetDeviceLink device: 0x%x"), tmpDeviceLink->iDeviceId ) );
       
   355         if( tmpDeviceLink->iDeviceId == aDeviceId )
       
   356             {
       
   357             deviceLink = tmpDeviceLink;
       
   358             break;
       
   359             }
       
   360         next = next->iNext;
       
   361         }
       
   362     C_TRACE( ( _T( "DISIIndicationHandler::GetDeviceLink 0x%x <-" ), deviceLink ) );
       
   363     return deviceLink;
       
   364     }
       
   365 
       
   366 
       
   367 // -----------------------------------------------------------------------------
       
   368 // DISIIndicationHandler::GetServerLink
       
   369 //
       
   370 // -----------------------------------------------------------------------------
       
   371 //
       
   372 
       
   373 DISIIndicationHandler::TServerIdLink* DISIIndicationHandler::GetServerLink(
       
   374         TDeviceIdLink& aDeviceLink,
       
   375         const TUint32 aResourceId
       
   376         )
       
   377     {
       
   378     C_TRACE( ( _T( "DISIIndicationHandler::GetServerLink 0x%x 0x%x ->" ), &aDeviceLink, aResourceId ) );
       
   379     TServerIdLink* serverLink = NULL;
       
   380     TServerIdLink* tmpServerLink = NULL;
       
   381     SDblQueLink* anchor = &aDeviceLink.iServerQ.iA;
       
   382     SDblQueLink* next = anchor->iNext;
       
   383     while( anchor != next ) // servers
       
   384         {
       
   385         tmpServerLink = _LOFF( next, TServerIdLink, iServerLink );
       
   386         C_TRACE( ( _T( "DISIIndicationHandler::GetServerLink server: 0x%x"), tmpServerLink->iResourceId ) );
       
   387         if( tmpServerLink->iResourceId == aResourceId )
       
   388             {
       
   389             serverLink = tmpServerLink;
       
   390             break;
       
   391             }
       
   392         next = next->iNext;
       
   393         }
       
   394     C_TRACE( ( _T( "DISIIndicationHandler::GetServerLink 0x%x <-" ), serverLink ) );
       
   395     return serverLink;
       
   396     }
       
   397     
       
   398 
       
   399 // -----------------------------------------------------------------------------
       
   400 // DISIIndicationHandler::GetIndicationLink
       
   401 //
       
   402 // -----------------------------------------------------------------------------
       
   403 //
       
   404 DISIIndicationHandler::TIndicationLink* DISIIndicationHandler::GetIndicationLink(
       
   405         TServerIdLink& aServerLink,
       
   406         const TUint8 aIndication
       
   407         )
       
   408     {
       
   409     C_TRACE( ( _T( "DISIIndicationHandler::GetIndicationLink 0x%x 0x%x ->" ), &aServerLink, aIndication ) );
       
   410     TIndicationLink* indicationLink = NULL;
       
   411     TIndicationLink* tmpIndicationLink = NULL;
       
   412     SDblQueLink* anchor = &aServerLink.iIndicationQ.iA;
       
   413     SDblQueLink* next = anchor->iNext;
       
   414     while( anchor != next )
       
   415         {
       
   416         tmpIndicationLink = _LOFF( next, TIndicationLink, iIndicationLink );
       
   417         if( tmpIndicationLink->iIndication == aIndication )
       
   418             {
       
   419             indicationLink = tmpIndicationLink;
       
   420             break;
       
   421             }
       
   422         next = next->iNext;
       
   423         }
       
   424     C_TRACE( ( _T( "DISIIndicationHandler::GetIndicationLink 0x%x <-" ), indicationLink ) );
       
   425     return indicationLink;
       
   426     }
       
   427 
       
   428 // -----------------------------------------------------------------------------
       
   429 // DISIIndicationHandler::GetSubscriberLink
       
   430 //
       
   431 // -----------------------------------------------------------------------------
       
   432 //
       
   433 DISIIndicationHandler::TSubscriberLink* DISIIndicationHandler::GetSubscriberLink(
       
   434         TIndicationLink& aIndicationLink,
       
   435         const TUint16 aObjId
       
   436         )
       
   437     {
       
   438     C_TRACE( ( _T( "DISIIndicationHandler::GetSubscriberLink 0x%x, 0x%x ->" ), &aIndicationLink, aObjId ) );
       
   439     TSubscriberLink* tmpSubscriberLink = NULL;
       
   440     TSubscriberLink* subscriberLink = NULL;
       
   441     SDblQueLink* anchor = &aIndicationLink.iSubscriberQ.iA;
       
   442     SDblQueLink* next = anchor->iNext;
       
   443     while( anchor != next )
       
   444         {
       
   445         tmpSubscriberLink= _LOFF( next, TSubscriberLink, iSubscriberLink );
       
   446         if ( tmpSubscriberLink->iObjId == aObjId )
       
   447             {
       
   448             subscriberLink = tmpSubscriberLink;
       
   449             break;
       
   450             }
       
   451         next = next->iNext;
       
   452         }
       
   453     C_TRACE( ( _T( "DISIIndicationHandler::GetSubscriberLink 0x%x <-" ), subscriberLink ) );
       
   454     return subscriberLink;
       
   455     }
       
   456 
       
   457 // -----------------------------------------------------------------------------
       
   458 // DISIIndicationHandler::PrintSubscriptions
       
   459 //
       
   460 // -----------------------------------------------------------------------------
       
   461 //
       
   462 void DISIIndicationHandler::PrintSubscriptions(
       
   463         // None
       
   464         )
       
   465     {
       
   466     C_TRACE( ( _T( "DISIIndicationHandler::PrintSubscriptions>" ) ) );
       
   467     TDeviceIdLink* deviceLink = NULL;
       
   468     SDblQueLink* anchor = &iDeviceQ.iA;
       
   469     SDblQueLink* next = anchor->iNext;
       
   470     SDblQueLink* serverAnchor = NULL;
       
   471     SDblQueLink* serverNext = NULL;
       
   472     TServerIdLink* serverLink = NULL;
       
   473     SDblQueLink* indicationAnchor = NULL;
       
   474     SDblQueLink* indicationNext = NULL;
       
   475     TIndicationLink* indicationLink = NULL;
       
   476     SDblQueLink* subscriberAnchor = NULL;
       
   477     SDblQueLink* subscriberNext = NULL;
       
   478     TSubscriberLink* subscriberLink = NULL;
       
   479     while( anchor != next )
       
   480         {
       
   481         deviceLink = _LOFF( next, TDeviceIdLink, iDeviceLink );
       
   482         C_TRACE( ( _T("DISIIndicationHandler::PrintSubscriptions device: 0x%x"), deviceLink->iDeviceId ) );
       
   483         serverAnchor = &deviceLink->iServerQ.iA;
       
   484         serverNext = serverAnchor->iNext;
       
   485         while( serverAnchor != serverNext )
       
   486             {
       
   487             serverLink = _LOFF( serverNext, TServerIdLink, iServerLink );
       
   488             C_TRACE( ( _T("DISIIndicationHandler::PrintSubscriptions server: 0x%x"), serverLink->iResourceId ) );
       
   489             indicationAnchor = &serverLink->iIndicationQ.iA;
       
   490             indicationNext = indicationAnchor->iNext;
       
   491             while( indicationAnchor != indicationNext )
       
   492                 {
       
   493                 indicationLink = _LOFF( indicationNext, TIndicationLink, iIndicationLink );
       
   494                 C_TRACE( ( _T("DISIIndicationHandler::PrintSubscriptions indication: 0x%x"), indicationLink->iIndication ) );
       
   495                 subscriberAnchor = &indicationLink->iSubscriberQ.iA;
       
   496                 subscriberNext = subscriberAnchor->iNext;
       
   497                 while( subscriberAnchor != subscriberNext)
       
   498                     {
       
   499                     subscriberLink = _LOFF( subscriberNext, TSubscriberLink, iSubscriberLink );
       
   500                     subscriberLink = subscriberLink;
       
   501                     C_TRACE( ( _T("DISIIndicationHandler::PrintSubscriptions objid: 0x%x"), subscriberLink->iObjId ) );
       
   502                     subscriberNext = subscriberNext->iNext;
       
   503                     }
       
   504                 indicationNext = indicationNext->iNext;
       
   505                 }
       
   506             serverNext = serverNext->iNext;
       
   507             }
       
   508         next = next->iNext;
       
   509         }
       
   510     C_TRACE( ( _T( "DISIIndicationHandler::PrintSubscriptions<" ) ) );
       
   511     }
       
   512 
       
   513 // -----------------------------------------------------------------------------
       
   514 // DISIIndicationHandler::RemoveSubscription
       
   515 // Removes all subscriptions from objectid
       
   516 // -----------------------------------------------------------------------------
       
   517 //
       
   518 void DISIIndicationHandler::RemoveSubscription(
       
   519         const TUint16 aObjId
       
   520         )
       
   521     {
       
   522     C_TRACE( ( _T( "DISIIndicationHandler::RemoveSubscription 0x%x>" ), aObjId ) );
       
   523 
       
   524     SDblQueLink*    deviceAnchor = &iDeviceQ.iA;
       
   525     SDblQueLink*    next = deviceAnchor->iNext;
       
   526     TDeviceIdLink*  deviceLink = NULL;
       
   527 
       
   528     SDblQueLink*        serverAnchor = NULL;
       
   529     SDblQueLink*        serverNext = NULL;
       
   530     TServerIdLink*      serverLink = NULL;
       
   531 
       
   532     SDblQueLink*        indicationAnchor = NULL;
       
   533     SDblQueLink*        indicationNext = NULL;
       
   534     TIndicationLink*    indicationLink = NULL;
       
   535 
       
   536     SDblQueLink*        subscriberAnchor = NULL;
       
   537     SDblQueLink*        subscriberNext = NULL;
       
   538     TSubscriberLink*    subscriberLink = NULL;
       
   539 
       
   540     while( deviceAnchor != next )
       
   541         {
       
   542         deviceLink = _LOFF( next, TDeviceIdLink, iDeviceLink );
       
   543         C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription device: 0x%x"), deviceLink->iDeviceId ) );
       
   544         serverAnchor = &deviceLink->iServerQ.iA;
       
   545         serverNext = serverAnchor->iNext;
       
   546         while( serverAnchor != serverNext )
       
   547             {
       
   548             serverLink = _LOFF( serverNext, TServerIdLink, iServerLink );
       
   549             indicationAnchor = &serverLink->iIndicationQ.iA;
       
   550             indicationNext = indicationAnchor->iNext;
       
   551             while( indicationAnchor != indicationNext )
       
   552                 {
       
   553                 indicationLink = _LOFF( indicationNext, TIndicationLink, iIndicationLink );
       
   554                 C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription indication: 0x%x"), indicationLink->iIndication ));
       
   555                 // get next link already in case if particular link is to be deleted
       
   556                 indicationNext = indicationNext->iNext;
       
   557                 subscriberAnchor = &indicationLink->iSubscriberQ.iA;
       
   558                 subscriberNext = subscriberAnchor->iNext;
       
   559                 while( subscriberAnchor != subscriberNext )
       
   560                     {
       
   561                     subscriberLink = _LOFF( subscriberNext, TSubscriberLink, iSubscriberLink );
       
   562                     C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription objid: 0x%x"), subscriberLink->iObjId ));
       
   563                     if( subscriberLink->iObjId == aObjId )
       
   564                         {
       
   565                         C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription remove objid: 0x%x"), subscriberLink->iObjId ));
       
   566                         TBool onlySubscriber( subscriberLink->iSubscriberLink.Alone() );
       
   567                         subscriberLink->iSubscriberLink.Deque();
       
   568                         delete subscriberLink;
       
   569                         subscriberLink = NULL;
       
   570                         if( onlySubscriber )
       
   571                             {
       
   572                             C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription remove indication: 0x%x"), indicationLink->iIndication ));
       
   573                             indicationLink->iIndicationLink.Deque();
       
   574                             delete indicationLink;
       
   575                             indicationLink = NULL;
       
   576                             }
       
   577                         // No need to go through rest of subscriberlinks since this one already found and deleted
       
   578                         subscriberNext = subscriberAnchor;
       
   579                         }
       
   580                     else
       
   581                         {
       
   582                         subscriberNext = subscriberNext->iNext;
       
   583                         }
       
   584                     }
       
   585                 }
       
   586             indicationAnchor = &serverLink->iIndicationQ.iA;
       
   587             indicationNext = indicationAnchor->iNext;
       
   588             serverNext = serverNext->iNext;
       
   589             if( indicationAnchor == indicationNext )
       
   590                 {
       
   591                 // No more indications for the server -> server link can be deleted
       
   592                 C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription remove server: 0x%x"), serverLink->iResourceId ));
       
   593                 serverLink->iServerLink.Deque();
       
   594                 delete serverLink;
       
   595                 serverLink = NULL;
       
   596                 }
       
   597             }
       
   598         serverAnchor = &deviceLink->iServerQ.iA;
       
   599         serverNext = serverAnchor->iNext;
       
   600         next = next->iNext;
       
   601         if( serverAnchor == serverNext )
       
   602             {
       
   603             // No more servers for the device -> device link can be deleted
       
   604             C_TRACE( ( _T("DISIIndicationHandler::RemoveSubscription remove device: 0x%x"), deviceLink->iDeviceId ));
       
   605             deviceLink->iDeviceLink.Deque();
       
   606             delete deviceLink;
       
   607             deviceLink = NULL;
       
   608             }
       
   609         }
       
   610     C_TRACE( ( _T( "DISIIndicationHandler::RemoveSubscription 0x%x<" ), aObjId ) );
       
   611     }
       
   612 
       
   613 // -----------------------------------------------------------------------------
       
   614 // DISIIndicationHandler::SendSubscription
       
   615 //
       
   616 // -----------------------------------------------------------------------------
       
   617 //
       
   618 TInt DISIIndicationHandler::SendSubscription( TDeviceIdLink& aDevice )
       
   619     {
       
   620     C_TRACE( ( _T( "DISIIndicationHandler::SendSubscription>" ) ) );
       
   621     const TUint8 KMaxAmountOfResources( 255 );
       
   622     const TUint8 KPnsSubscribedResourcesExtendLength( 12 );
       
   623     const TUint8 KResourceArraySize( 4 );
       
   624     
       
   625     TDes8& desPtr = MemApi::AllocBlock( ISI_HEADER_SIZE + SIZE_PNS_SUBSCRIBED_RESOURCES_EXTEND_IND + ( KMaxAmountOfResources * KResourceArraySize ) );
       
   626 
       
   627     TUint8* ptr( const_cast<TUint8*>( desPtr.Ptr() ) );
       
   628     ptr[ ISI_HEADER_OFFSET_MEDIA ] = PN_MEDIA_ROUTING_REQ;
       
   629     SET_RECEIVER_DEV( ptr, aDevice.iDeviceId );
       
   630     SET_SENDER_DEV( ptr, PN_DEV_OWN );
       
   631     ptr[ ISI_HEADER_OFFSET_RESOURCEID ] = PN_COMMGR;
       
   632     SET_RECEIVER_OBJ( ptr, PN_OBJ_ROUTER );
       
   633     SET_SENDER_OBJ( ptr, PN_OBJ_EVENT_MULTICAST );
       
   634     ptr[ ISI_HEADER_SIZE + PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_OFFSET_TRANSACTIONID ] = 0x00;
       
   635     ptr[ ISI_HEADER_SIZE + PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_OFFSET_MESSAGEID ] = PNS_SUBSCRIBED_RESOURCES_EXTEND_IND;
       
   636     ptr[ ISI_HEADER_SIZE + PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_OFFSET_FILLER ] = 0x00;
       
   637     
       
   638     TServerIdLink* serverLink = NULL;
       
   639     SDblQueLink* anchor = &(aDevice.iServerQ.iA);
       
   640     SDblQueLink* next = anchor->iNext;
       
   641 
       
   642     TUint8 resourceCount( 0x00 );
       
   643     while( anchor != next )
       
   644         {
       
   645         serverLink = _LOFF( next, TServerIdLink, iServerLink );
       
   646         TUint32 resourceId = serverLink->iResourceId;
       
   647         C_TRACE( ( _T("DISIIndicationHandler::SendSubscription Server: 0x%08x"), resourceId ) );
       
   648         PUTB32( &ptr[ ISI_HEADER_SIZE + PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_OFFSET_RESOURCELIST ], resourceId );
       
   649         resourceCount++;
       
   650         next = next->iNext;
       
   651         }
       
   652     ptr[ ISI_HEADER_SIZE + PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_OFFSET_RESOURCECOUNT ] = resourceCount;
       
   653     TInt messageLength( ( resourceCount * KResourceArraySize ) + KPnsSubscribedResourcesExtendLength );
       
   654     while( messageLength % 4 != 0 )
       
   655         {
       
   656         TRACE_ASSERT_INFO(0, messageLength);
       
   657         messageLength++;
       
   658         }
       
   659     desPtr.SetLength( messageLength );
       
   660     SET_LENGTH( ptr, messageLength - PN_HEADER_SIZE );
       
   661       
       
   662     for( TInt i( 0 ); i < desPtr.Length(); i++ )
       
   663         {
       
   664         C_TRACE( ( _T( "index[ %d ] data 0x%x"), i, desPtr.Ptr()[i] ) );
       
   665         }
       
   666     TInt error = iRouter->Send( desPtr, PN_OBJ_EVENT_MULTICAST );
       
   667     C_TRACE( ( _T( "DISIIndicationHandler::SendSubscription<" ) ) );  
       
   668     return error;
       
   669     }
       
   670 
       
   671 // End of file.
       
   672