connectivitylayer/isce/isaaccessextension_dll/src/indicationhandler.cpp
changeset 0 63b37f68c1ce
child 5 8ccc39f9d787
equal deleted inserted replaced
-1:000000000000 0:63b37f68c1ce
       
     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 
       
    19 
       
    20 #ifndef NCP_COMMON_BRIDGE_FAMILY
       
    21 #include <cmisi.h>                      // PN_COMMMG, PNS_SUBSCRIBED_RESOURCES_...
       
    22 #else
       
    23 #include <pn_eventmodem_extisi.h>       // PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_...
       
    24 #endif
       
    25 #include <phonetisi.h>                  // For ISI_HEADER_SIZE
       
    26 #include <pn_const.h>                   // For PN_HEADER_SIZE
       
    27 #ifndef NCP_COMMON_BRIDGE_FAMILY
       
    28 #include <mediaisi.h>                   // For PNS_MEDIA_SOS
       
    29 #endif
       
    30 #include "indicationhandler.h"
       
    31 #include "iadtrace.h"                   // For C_TRACE..
       
    32 #include "router.h"                     // For DRouter
       
    33 #include "iadhelpers.h"
       
    34 #include "OstTraceDefinitions.h"
       
    35 #ifdef OST_TRACE_COMPILER_IN_USE
       
    36 #include "indicationhandlerTraces.h"
       
    37 #endif
       
    38                  // For GET_RECEIVER
       
    39 
       
    40 DIndicationHandler::DIndicationHandler(
       
    41         DRouter& aRouter
       
    42         )
       
    43         : iRouter( aRouter )
       
    44     {
       
    45     OstTrace1( TRACE_NORMAL, DINDICATIONHANDLER_DINDICATIONHANDLER_ENTRY, ">DIndicationHandler::DIndicationHandler;aRouter=%x", ( TUint )&( aRouter ) );
       
    46 
       
    47     C_TRACE( ( _T( "DIndicationHandler::DIndicationHandler 0x%x ->" ), &iRouter ) );
       
    48     C_TRACE( ( _T( "DIndicationHandler::DIndicationHandler 0x%x <-" ), &iRouter ) );
       
    49 
       
    50     OstTrace0( TRACE_NORMAL, DINDICATIONHANDLER_DINDICATIONHANDLER_EXIT, "<DIndicationHandler::DIndicationHandler" );
       
    51     }
       
    52 
       
    53 DIndicationHandler::~DIndicationHandler(
       
    54         // None
       
    55         )
       
    56     {
       
    57     OstTrace0( TRACE_NORMAL, DINDICATIONHANDLER_DINDICATIONHANDLER_DES_ENTRY, ">DIndicationHandler::~DIndicationHandler" );
       
    58 
       
    59     C_TRACE( ( _T( "DIndicationHandler::~DIndicationHandler ->" ) ) );
       
    60     C_TRACE( ( _T( "DIndicationHandler::~DIndicationHandler <-" ) ) );
       
    61 
       
    62     OstTrace0( TRACE_NORMAL, DINDICATIONHANDLER_DINDICATIONHANDLER_DES_EXIT, "<DIndicationHandler::~DIndicationHandler" );
       
    63     }
       
    64 
       
    65 
       
    66 void DIndicationHandler::Multicast(
       
    67         TDes8& aIndication
       
    68         )
       
    69     {
       
    70 
       
    71     OstTrace1( TRACE_NORMAL, DINDICATIONHANDLER_MULTICAST_ENTRY, ">DIndicationHandler::Multicast;aIndication=%x", ( TUint )&( aIndication ) );
       
    72     // TODO: ! NOTE ! This is run in commonrx dfc dfc queu, how long will this take? latency to dfc thread and commondfc switch to own dfc instead?
       
    73     C_TRACE( ( _T( "DIndicationHandler::Multicast 0x%x ->" ), &aIndication ) );
       
    74 //TODO: change there const to offsets?
       
    75     const TUint8 KPnMsgExtendedType( 9 );
       
    76     const TUint8 KPnMsgExtendedSubType( 10 );
       
    77     TUint8* ptr = const_cast<TUint8*>( aIndication.Ptr() );
       
    78     TUint32 resourceId( 0x00000000 );
       
    79     if( ptr[ ISI_HEADER_OFFSET_RESOURCEID ] == PN_PREFIX )
       
    80         {
       
    81 #ifdef NCP_COMMON_BRIDGE_FAMILY
       
    82         TRACE_ASSERT_ALWAYS;// So called "perävalotakuu" for indications PN_PREFIX defined to PN_COMMGR see iscnokiadefinitions.h
       
    83 #endif
       
    84         C_TRACE( ( _T( "DIndicationHandler::Multicast PN_PREFIX 0x%x" ), &aIndication ) );
       
    85         OstTrace1( TRACE_NORMAL, DINDICATIONHANDLER_MULTICAST_PN_PREFIX, "DIndicationHandler::Multicast extended resource;aIndication=%x", (TUint)&(aIndication) );
       
    86         
       
    87         ASSERT_RESET_ALWAYS( aIndication.Length() > KPnMsgExtendedType , EIADOverTheLimits | EIADFaultIdentifier40 << KFaultIdentifierShift );                                                
       
    88         resourceId = ( ptr [ KPnMsgExtendedSubType ] << 16 ) + ( ptr [ KPnMsgExtendedType ] << 8 ) +  ( PN_PREFIX );
       
    89         }
       
    90     else 
       
    91         {
       
    92         ASSERT_RESET_ALWAYS( aIndication.Length() > ISI_HEADER_OFFSET_RESOURCEID , EIADOverTheLimits | EIADFaultIdentifier41 << KFaultIdentifierShift );                                                            
       
    93         resourceId = ptr[ ISI_HEADER_OFFSET_RESOURCEID ];
       
    94         }
       
    95     TServerIdLink* serverLink = GetServerLink( resourceId );
       
    96     TIndicationLink* indicationLink = NULL;
       
    97     TSubscriberLink* subscriberLink = NULL;
       
    98 
       
    99     if( serverLink )
       
   100         {
       
   101         indicationLink = GetIndicationLink( *serverLink, ptr[ ISI_HEADER_OFFSET_MESSAGEID ] );
       
   102         }
       
   103     if( indicationLink )
       
   104         {
       
   105         SDblQueLink* subscriberAnchor = NULL;
       
   106         SDblQueLink* subscriberNext = NULL;
       
   107         subscriberAnchor = &indicationLink->iSubscriberQ.iA;
       
   108         subscriberNext = subscriberAnchor->iNext;
       
   109         while( subscriberAnchor != subscriberNext)
       
   110             {
       
   111             subscriberLink = _LOFF( subscriberNext, TSubscriberLink, iSubscriberLink );
       
   112             C_TRACE( ( _T("DIndicationHandler::Multicast Subscriber channel: 0x%x"), subscriberLink->iChannelId ));
       
   113             // Make a copy to another subscriber
       
   114             TDes8& tempPtr = iRouter.AllocateBlock( aIndication.Length() );
       
   115             tempPtr.Copy( ptr, aIndication.Length() );
       
   116             TUint8* ptr = const_cast<TUint8*>( tempPtr.Ptr() );
       
   117             SET_RECEIVER_OBJ( ptr, subscriberLink->iChannelId );
       
   118             ASSERT_RESET_ALWAYS( subscriberLink->iChannelId != KIADEventSubscriptionObjId, 0 );
       
   119             iRouter.CheckRouting( iRouter, tempPtr );
       
   120             subscriberNext = subscriberNext->iNext;
       
   121             }
       
   122         }
       
   123     C_TRACE( ( _T( "DIndicationHandler::Multicast 0x%x <-" ), &aIndication ) );
       
   124     OstTrace0( TRACE_NORMAL, DINDICATIONHANDLER_MULTICAST_EXIT, "<DIndicationHandler::Multicast" );
       
   125     }
       
   126 
       
   127 TInt DIndicationHandler::Subscribe(
       
   128         TDes8& anOrder,
       
   129         const TUint16 aCh,
       
   130         const TBool a32BitResource
       
   131         )
       
   132     {
       
   133     OstTraceExt3( TRACE_NORMAL, DINDICATIONHANDLER_SUBSCRIBE_ENTRY, ">DIndicationHandler::Subscribe;anOrder=%x;aCh=%hx;a32BitResource=%d", ( TUint )&( anOrder ), aCh, a32BitResource );
       
   134 
       
   135     C_TRACE( ( _T( "DIndicationHandler::Subscribe 0x%x ->" ), aCh ) );
       
   136     RemoveSubscription( aCh );
       
   137     TInt eventTableLength( anOrder.Length() );
       
   138     TUint32 resourceId( 0x00000000 );
       
   139     TUint8 extendedLength( a32BitResource ? 0x03 : 0x00 );
       
   140     TUint8* orderPtr( const_cast<TUint8*>( anOrder.Ptr() ) );
       
   141 
       
   142     TInt remove( 0 );
       
   143     // Deorder of indication 8-bit { 0x00, 0x00 } and 32-bit { 0x00, 0x00, 0x00, 0x00, 0x00 }
       
   144     for( TInt i( 0 ); i < eventTableLength; ++i )
       
   145         {
       
   146         remove += ( orderPtr[ i ] == 0x00 ? 1 : 0 );           
       
   147         }
       
   148     eventTableLength = ( eventTableLength == remove ? 0 : eventTableLength );
       
   149     C_TRACE( ( _T( "DIndicationHandler::Subscribe 0x%x length %d 32-bit %d" ), aCh, eventTableLength, a32BitResource ) );
       
   150 
       
   151     OstTraceExt4( TRACE_NORMAL, DINDICATIONHANDLER_SUBSCRIBE, "DIndicationHandler::Subscribe;anOrder=%x;aCh=%hx;a32BitResource=%d;eventTableLength=%hhu", ( TUint )&( anOrder ), aCh, a32BitResource, eventTableLength );
       
   152     
       
   153 
       
   154     /*
       
   155     for( TInt i( 0 ); i < anOrder.Length(); i++ )
       
   156         {
       
   157         Kern::Printf( "subscribe order[%d]0x%x", i, anOrder.Ptr()[ i ] );
       
   158         }
       
   159     */
       
   160 
       
   161     for( TInt i( 0 ); i < eventTableLength; i += ( 2 + extendedLength ) )
       
   162         {
       
   163         if( a32BitResource )
       
   164             {
       
   165             ASSERT_RESET_ALWAYS( ( KErrNone == eventTableLength % 5 ), EIADWrongParameter | ( (TUint8)aCh << KChannelNumberShift ) | EIADFaultIdentifier1 << KFaultIdentifierShift );
       
   166             resourceId = orderPtr[ i ] << 24 | orderPtr[ i + 1 ] << 16 | orderPtr[ i + 2 ] << 8 | orderPtr[ i + 3 ];
       
   167             C_TRACE( ( _T("DIndicationHandler::Subscribe 32-bit Channel: 0x%x Server: 0x%x Indication 0x%x"), aCh, resourceId, orderPtr[ i + 4 ] ) );
       
   168             OstTraceExt3( TRACE_DETAILED, DUP1_DINDICATIONHANDLER_SUBSCRIBE_32BIT, "DIndicationHandler::Subscribe 32bit;aCh=%hx;resourceId=%x;indication=%hhx", aCh, resourceId, orderPtr[ i + 4 ] );
       
   169             }
       
   170         else 
       
   171             {
       
   172             ASSERT_RESET_ALWAYS( ( KErrNone == eventTableLength % 2 ), EIADWrongParameter | ( (TUint8)aCh << KChannelNumberShift ) | EIADFaultIdentifier2 << KFaultIdentifierShift );
       
   173             resourceId = orderPtr[ i ];
       
   174             C_TRACE( ( _T("DIndicationHandler::Subscribe Channel: 0x%x Server: 0x%x Indication 0x%x"), aCh, resourceId, orderPtr[ i + 1 ] ) );
       
   175             OstTraceExt3( TRACE_DETAILED, DUP1_DINDICATIONHANDLER_SUBSCRIBE_8BIT, "DIndicationHandler::Subscribe 8bit;aCh=%hx;resourceId=%x;indication=%hhx", aCh, resourceId, orderPtr[ i + 1 ] );
       
   176             }
       
   177         // TODO: Ensure that ownership is not given! If given leaks memory below in allocation..!
       
   178         TServerIdLink* serverLink = GetServerLink( resourceId );
       
   179         if( !serverLink )
       
   180             {
       
   181             C_TRACE( ( _T("DIndicationHandler::Subscribe ServerIdLink not found yet -> create: 0x%x"), resourceId ) );
       
   182             OstTrace1( TRACE_DETAILED, DINDICATIONHANDLER_SUBSCRIBE_SERVERLINK, "DIndicationHandler::Subscribe serverlink not yet created;resourceId=%x", resourceId );
       
   183             
       
   184             serverLink = new TServerIdLink();
       
   185             ASSERT_RESET_ALWAYS( serverLink, EIADMemoryAllocationFailure | EIADFaultIdentifier1 << KFaultIdentifierShift );
       
   186             serverLink->iResourceId = resourceId;
       
   187             iServerQ.Add( &( serverLink->iServerLink ) );
       
   188             }
       
   189         AddIndication( *serverLink, orderPtr[ i + ( 1 + extendedLength ) ], aCh );
       
   190         }
       
   191 
       
   192 #ifdef _DEBUG
       
   193 #ifdef COMPONENT_TRACE
       
   194     PrintSubscriptions();
       
   195 #endif // COMPONENT_TRACE
       
   196 #endif // _DEBUG
       
   197     C_TRACE( ( _T( "DIndicationHandler::Subscribe 0x%x <-" ), aCh ) );
       
   198     TInt error = SendSubscription();
       
   199 
       
   200 
       
   201     OstTrace1( TRACE_NORMAL, DUP1_DINDICATIONHANDLER_SUBSCRIBE, "DIndicationHandler::Subscribe<;error=%d", error );
       
   202     return error;
       
   203     }
       
   204 
       
   205 void DIndicationHandler::AddIndication(
       
   206         TServerIdLink& aServerLink,
       
   207         const TUint8 aIndication,
       
   208         const TUint16 aCh
       
   209         )
       
   210     {
       
   211     OstTraceExt3( TRACE_NORMAL, DINDICATIONHANDLER_ADDINDICATION_ENTRY, ">DIndicationHandler::AddIndication;aServerLink=%x;aIndication=%hhu;aCh=%hx", ( TUint )&( aServerLink ), aIndication, aCh );
       
   212 
       
   213     C_TRACE( ( _T( "DIndicationHandler::AddIndication 0x%x 0x%x ->" ), aIndication, aCh ) );
       
   214 
       
   215     // TODO: ownership given or not?
       
   216     TIndicationLink* indicationLink = GetIndicationLink( aServerLink, aIndication );
       
   217     if( !indicationLink )
       
   218         {
       
   219         C_TRACE( ( _T("DIndicationHandler::AddIndication Indication: 0x%x not found, create"), aIndication ));
       
   220         OstTraceExt1( TRACE_NORMAL, DINDICATIONHANDLER_ADDINDICATION, "DIndicationHandler::AddIndication indicationLink not found -> create;aIndication=%hhx", aIndication );
       
   221         
       
   222         indicationLink = new TIndicationLink();
       
   223         ASSERT_RESET_ALWAYS( indicationLink, EIADMemoryAllocationFailure | EIADFaultIdentifier2 << KFaultIdentifierShift );
       
   224         indicationLink->iIndication = aIndication;
       
   225         aServerLink.iIndicationQ.Add( &( indicationLink->iIndicationLink ) );
       
   226         }
       
   227     AddSubscriber( *indicationLink, aCh );
       
   228     C_TRACE( ( _T( "DIndicationHandler::AddIndication 0x%x 0x%x <-" ), aIndication, aCh ) );
       
   229 
       
   230     OstTrace0( TRACE_NORMAL, DINDICATIONHANDLER_ADDINDICATION_EXIT, "<DIndicationHandler::AddIndication" );
       
   231     }
       
   232 
       
   233 void DIndicationHandler::AddSubscriber(
       
   234         TIndicationLink& aIndicationLink,
       
   235         const TUint16 aCh
       
   236         )
       
   237     {
       
   238     OstTraceExt2( TRACE_NORMAL, DINDICATIONHANDLER_ADDSUBSCRIBER_ENTRY, ">DIndicationHandler::AddSubscriber;aIndicationLink=%x;aCh=%hx", ( TUint )&( aIndicationLink ), aCh );
       
   239 
       
   240     C_TRACE( ( _T( "DIndicationHandler::AddSubscriber 0x%x, 0x%x ->" ), &aIndicationLink, aCh ) );
       
   241     TSubscriberLink* subscriberLink = GetSubscriberLink( aIndicationLink, aCh );
       
   242     if( !subscriberLink )
       
   243         {
       
   244         C_TRACE( ( _T("DIndicationHandler::AddSubscriber Subscriber not found: 0x%x 0x%x"), aIndicationLink.iIndication, aCh ) );
       
   245         OstTraceExt2( TRACE_NORMAL, DINDICATIONHANDLER_ADDSUBSCRIBER, "DIndicationHandler::AddSubscriber subscriber not found -> create;aIndicationLink.iIndication=%hhu;aCh=%hx", aIndicationLink.iIndication, aCh );
       
   246         
       
   247         subscriberLink = new TSubscriberLink();
       
   248         ASSERT_RESET_ALWAYS( subscriberLink, EIADMemoryAllocationFailure | EIADFaultIdentifier3 << KFaultIdentifierShift );
       
   249         subscriberLink->iChannelId = aCh;
       
   250         aIndicationLink.iSubscriberQ.Add( &( subscriberLink->iSubscriberLink ) );
       
   251         }
       
   252     else
       
   253         {
       
   254         TRACE_ASSERT_INFO(0, (TUint8)aCh<<KChannelNumberShift);
       
   255         C_TRACE( ( _T( "DIndicationHandler::AddSubscriber double subscription 0x%x" ), aCh ) );
       
   256         OstTraceExt1( TRACE_NORMAL, DINDICATIONHANDLER_ADDSUBSCRIBER_DOUBLE_SUB, "DIndicationHandler::AddSubscriber double subscription;aCh=%hx", aCh );        
       
   257         }
       
   258     C_TRACE( ( _T( "DIscIsiEventHandler::AddSubscriber <-" ) ) );
       
   259 
       
   260     OstTrace0( TRACE_NORMAL, DINDICATIONHANDLER_ADDSUBSCRIBER_EXIT, "<DIndicationHandler::AddSubscriber" );
       
   261     }
       
   262 
       
   263 DIndicationHandler::TServerIdLink* DIndicationHandler::GetServerLink(
       
   264         const TUint32 aResourceId
       
   265         )
       
   266     {
       
   267     OstTrace1( TRACE_NORMAL, DINDICATIONHANDLER_GETSERVERLINK_ENTRY, ">DIndicationHandler::GetServerLink;aResourceId=%u", ( TUint )( aResourceId ) );
       
   268 
       
   269     C_TRACE( ( _T( "DIndicationHandler::GetServerLink 0x%x ->" ), aResourceId ) );
       
   270 
       
   271     TServerIdLink* serverLink = NULL;
       
   272     TServerIdLink* tmpServerLink = NULL;
       
   273     SDblQueLink* anchor = &iServerQ.iA;
       
   274     SDblQueLink* next = anchor->iNext;
       
   275 
       
   276     while( anchor != next ) // servers
       
   277         {
       
   278         tmpServerLink = _LOFF( next, TServerIdLink, iServerLink );
       
   279         C_TRACE( ( _T( "DIndicationHandler::GetServerLink Server: 0x%x"), tmpServerLink->iResourceId ) );
       
   280         OstTrace1( TRACE_DETAILED, DINDICATIONHANDLER_GETSERVERLINK, "DIndicationHandler::GetServerLink;tmpServerLink->iResourceId=%u", ( TUint )( tmpServerLink->iResourceId ) );
       
   281         if( tmpServerLink->iResourceId == aResourceId )
       
   282             {
       
   283             serverLink = tmpServerLink;
       
   284             break;
       
   285             }
       
   286         next = next->iNext;
       
   287         }
       
   288     C_TRACE( ( _T( "DIndicationHandler::GetServerLink 0x%x <-" ), serverLink ) );
       
   289 
       
   290     OstTrace1( TRACE_NORMAL, DINDICATIONHANDLER_GETSERVERLINK_EXIT, "DIndicationHandler::GetServerLink<;serverLink=%x", serverLink );
       
   291     return serverLink;
       
   292     }
       
   293 
       
   294 DIndicationHandler::TIndicationLink* DIndicationHandler::GetIndicationLink(
       
   295         TServerIdLink& aServerLink,
       
   296         const TUint8 aIndication
       
   297         )
       
   298     {
       
   299     OstTraceExt2( TRACE_NORMAL, DINDICATIONHANDLER_GETINDICATIONLINK_ENTRY, ">DIndicationHandler::GetIndicationLink;aServerLink=%x;aIndication=%hhu", ( TUint )&( aServerLink ), aIndication );
       
   300 
       
   301     C_TRACE( ( _T( "DIndicationHandler::GetIndicationLink 0x%x ->" ), aIndication ) );
       
   302     TIndicationLink* indicationLink = NULL;
       
   303     TIndicationLink* tmpIndicationLink = NULL;
       
   304 
       
   305     SDblQueLink* anchor = &aServerLink.iIndicationQ.iA;
       
   306     SDblQueLink* next = anchor->iNext;
       
   307 
       
   308     while( anchor != next )
       
   309         {
       
   310         tmpIndicationLink = _LOFF( next, TIndicationLink, iIndicationLink );
       
   311         if( tmpIndicationLink->iIndication == aIndication )
       
   312             {
       
   313             indicationLink = tmpIndicationLink;
       
   314             break;
       
   315             }
       
   316         next = next->iNext;
       
   317         }
       
   318     C_TRACE( ( _T( "DIndicationHandler::GetIndicationLink 0x%x <-" ), indicationLink ) );
       
   319 
       
   320 
       
   321     OstTrace1( TRACE_NORMAL, DINDICATIONHANDLER_GETINDICATIONLINK_EXIT, "<DIndicationHandler::GetIndicationLink;indicationLink=%x", indicationLink );
       
   322     return indicationLink;
       
   323     }
       
   324 
       
   325 DIndicationHandler::TSubscriberLink* DIndicationHandler::GetSubscriberLink(
       
   326         TIndicationLink& aIndicationLink,
       
   327         const TUint16 aCh
       
   328         )
       
   329     {
       
   330     OstTraceExt2( TRACE_NORMAL, DINDICATIONHANDLER_GETSUBSCRIBERLINK_ENTRY, ">DIndicationHandler::GetSubscriberLink;aIndicationLink=%x;aCh=%hx", ( TUint )&( aIndicationLink ), aCh );
       
   331 
       
   332     C_TRACE( ( _T( "DIndicationHandler::GetSubscriberLink 0x%x, 0x%x ->" ), &aIndicationLink, aCh ) );
       
   333     TSubscriberLink* tmpSubscriberLink = NULL;
       
   334     TSubscriberLink* subscriberLink = NULL;
       
   335 
       
   336     SDblQueLink* anchor = &aIndicationLink.iSubscriberQ.iA;
       
   337     SDblQueLink* next = anchor->iNext;
       
   338 
       
   339     while( anchor != next )
       
   340         {
       
   341         tmpSubscriberLink= _LOFF( next, TSubscriberLink, iSubscriberLink );
       
   342         if ( tmpSubscriberLink->iChannelId == aCh )
       
   343             {
       
   344             subscriberLink = tmpSubscriberLink;
       
   345             break;
       
   346             }
       
   347         next = next->iNext;
       
   348         }
       
   349 
       
   350     C_TRACE( ( _T( "DIndicationHandler::GetSubscriberLink 0x%x <-" ), subscriberLink ) );
       
   351     
       
   352     OstTrace1( TRACE_NORMAL, DINDICATIONHANDLER_GETSUBSCRIBERLINK_EXIT, "<DIndicationHandler::GetSubscriberLink;subscriberLink=%x", subscriberLink );
       
   353     return subscriberLink;
       
   354     }
       
   355 
       
   356 void DIndicationHandler::PrintSubscriptions(
       
   357         // None
       
   358         )
       
   359     {
       
   360     OstTrace0( TRACE_NORMAL, DINDICATIONHANDLER_PRINTSUBSCRIPTIONS_ENTRY, ">DIndicationHandler::PrintSubscriptions" );
       
   361 
       
   362     C_TRACE( ( _T( "DIndicationHandler::PrintSubscriptions ->" ) ) );
       
   363     TServerIdLink* serverLink = NULL;//_LOFF(listElement, TServerIdLink, iServerLink);
       
   364     SDblQueLink* anchor = &iServerQ.iA;
       
   365     SDblQueLink* next = anchor->iNext;
       
   366     SDblQueLink* indicationAnchor = NULL;
       
   367     SDblQueLink* indicationNext = NULL;
       
   368     TIndicationLink* indicationLink = NULL;
       
   369     SDblQueLink* subscriberAnchor = NULL;
       
   370     SDblQueLink* subscriberNext = NULL;
       
   371     TSubscriberLink* subscriberLink = NULL;
       
   372     while( anchor != next ) // servers
       
   373         {
       
   374         serverLink = _LOFF( next, TServerIdLink, iServerLink );
       
   375         C_TRACE( ( _T("DIndicationHandler::PrintSubscriptions Server: 0x%x"), serverLink->iResourceId));
       
   376         OstTrace1( TRACE_DETAILED, DINDICATIONHANDLER_PRINTSUBSCRIPTIONS, "DIndicationHandler::PrintSubscriptions;resource=%x", (TUint)(serverLink->iResourceId) );// todo check these prints
       
   377         
       
   378         indicationAnchor = &serverLink->iIndicationQ.iA;
       
   379         indicationNext = indicationAnchor->iNext;
       
   380         while( indicationAnchor != indicationNext )
       
   381             {
       
   382             indicationLink = _LOFF( indicationNext, TIndicationLink, iIndicationLink );
       
   383             C_TRACE( ( _T("DIndicationHandler::PrintSubscriptions Indication: 0x%x"), indicationLink->iIndication ) );
       
   384             OstTraceExt1( TRACE_DETAILED, DINDICATIONHANDLER_PRINTSUBSCRIPTIONS_INDICATION, "DIndicationHandler::PrintSubscriptions;indication=%hhx", indicationLink->iIndication );
       
   385             
       
   386             subscriberAnchor = &indicationLink->iSubscriberQ.iA;
       
   387             subscriberNext = subscriberAnchor->iNext;
       
   388             while( subscriberAnchor != subscriberNext)
       
   389                 {
       
   390                 subscriberLink = _LOFF( subscriberNext, TSubscriberLink, iSubscriberLink );
       
   391                 subscriberLink = subscriberLink;
       
   392                 C_TRACE( ( _T("DIndicationHandler::PrintSubscriptions Channel: 0x%x"), subscriberLink->iChannelId ) );
       
   393                 OstTraceExt1( TRACE_DETAILED, DUP1_DINDICATIONHANDLER_PRINTSUBSCRIPTIONS_CHANNEL, "DIndicationHandler::PrintSubscriptions;subscriberLink->iChannelId=%hx", subscriberLink->iChannelId );
       
   394                 
       
   395                 subscriberNext = subscriberNext->iNext;
       
   396                 }
       
   397             indicationNext = indicationNext->iNext;
       
   398             }
       
   399         next = next->iNext;
       
   400         }
       
   401     C_TRACE( ( _T( "DIndicationHandler::PrintSubscriptions <-" ) ) );
       
   402 
       
   403     OstTrace0( TRACE_DETAILED, DUP1_DINDICATIONHANDLER_PRINTSUBSCRIPTIONS_EXIT, "<DIndicationHandler::PrintSubscriptions" );
       
   404     }
       
   405 
       
   406 
       
   407 void DIndicationHandler::RemoveSubscription(
       
   408         const TUint16 aCh
       
   409         )
       
   410     {
       
   411     OstTraceExt1( TRACE_NORMAL, DINDICATIONHANDLER_REMOVESUBSCRIPTION_ENTRY, ">DIndicationHandler::RemoveSubscription;aCh=%hx", aCh );
       
   412 
       
   413     C_TRACE( ( _T( "DIndicationHandler::RemoveSubscription 0x%x ->" ), aCh ) );
       
   414     // enter semaphore
       
   415 
       
   416     SDblQueLink*    serverAnchor = &iServerQ.iA;
       
   417     SDblQueLink*    next = serverAnchor->iNext;
       
   418     TServerIdLink*  serverLink = NULL;
       
   419 
       
   420     SDblQueLink*        indicationAnchor = NULL;
       
   421     SDblQueLink*        indicationNext = NULL;
       
   422     TIndicationLink*    indicationLink = NULL;
       
   423 
       
   424     SDblQueLink*        subscriberAnchor = NULL;
       
   425     SDblQueLink*        subscriberNext = NULL;
       
   426     TSubscriberLink*    subscriberLink = NULL;
       
   427 
       
   428     while( serverAnchor != next ) // servers
       
   429         {
       
   430         serverLink = _LOFF( next, TServerIdLink, iServerLink );
       
   431         C_TRACE( ( _T("DIndicationHandler::RemoveSubscription Server: 0x%x"), serverLink->iResourceId ) );
       
   432         OstTrace1( TRACE_NORMAL, DINDICATIONHANDLER_REMOVESUBSCRIPTION, "DIndicationHandler::RemoveSubscription;resource=%x", serverLink->iResourceId );
       
   433         
       
   434         indicationAnchor = &serverLink->iIndicationQ.iA;
       
   435         indicationNext = indicationAnchor->iNext;
       
   436         while( indicationAnchor != indicationNext )
       
   437             {
       
   438             indicationLink = _LOFF( indicationNext, TIndicationLink, iIndicationLink );
       
   439             // get next link already in case if particular link is to be deleted
       
   440             indicationNext = indicationNext->iNext;
       
   441             subscriberAnchor = &indicationLink->iSubscriberQ.iA;
       
   442             subscriberNext = subscriberAnchor->iNext;
       
   443             while( subscriberAnchor != subscriberNext )
       
   444                 {
       
   445                 subscriberLink = _LOFF( subscriberNext, TSubscriberLink, iSubscriberLink );
       
   446                 C_TRACE( ( _T("DIndicationHandler::RemoveSubscription Subscriber channel: 0x%x"), subscriberLink->iChannelId ));
       
   447                 OstTraceExt1( TRACE_NORMAL, DUP1_DINDICATIONHANDLER_REMOVESUBSCRIPTION_CHANNEL, "DIndicationHandler::RemoveSubscription;channelId=%hx", subscriberLink->iChannelId );
       
   448                 
       
   449                 if( subscriberLink->iChannelId == aCh )
       
   450                     {
       
   451                     TBool onlySubscriber( subscriberLink->iSubscriberLink.Alone() );
       
   452                     subscriberLink->iSubscriberLink.Deque();
       
   453                     delete subscriberLink;
       
   454                     subscriberLink = NULL;
       
   455                     if( onlySubscriber )
       
   456                         {
       
   457                         indicationLink->iIndicationLink.Deque();
       
   458                         delete indicationLink;
       
   459                         indicationLink = NULL;
       
   460                         }
       
   461                     // No need to go through rest of subscriberlinks since this one already found and deleted
       
   462                     subscriberNext = subscriberAnchor;
       
   463                     }
       
   464                 else
       
   465                     {
       
   466                     subscriberNext = subscriberNext->iNext;
       
   467                     }
       
   468                 }
       
   469             }
       
   470         indicationAnchor = &serverLink->iIndicationQ.iA;
       
   471         indicationNext = indicationAnchor->iNext;
       
   472         next = next->iNext;
       
   473         if( indicationAnchor == indicationNext )
       
   474             {
       
   475             // No more indications for the server -> server link can be deleted
       
   476             serverLink->iServerLink.Deque();
       
   477             delete serverLink;
       
   478             serverLink = NULL;
       
   479             }
       
   480         }
       
   481     // exit semaphore
       
   482     C_TRACE( ( _T( "DIndicationHandler::RemoveSubscription 0x%x <-" ), aCh ) );
       
   483 
       
   484     OstTraceExt1( TRACE_NORMAL, DINDICATIONHANDLER_REMOVESUBSCRIPTION_EXIT, "<DIndicationHandler::RemoveSubscription;aCh=%hx", aCh );
       
   485     }
       
   486 
       
   487 
       
   488 TInt DIndicationHandler::SendSubscription(
       
   489         // None
       
   490         )
       
   491     {
       
   492     OstTrace0( TRACE_NORMAL, DINDICATIONHANDLER_SENDSUBSCRIPTION_ENTRY, ">DIndicationHandler::SendSubscription" );
       
   493 
       
   494     C_TRACE( ( _T( "DIndicationHandler::SendSubscription ->" ) ) );
       
   495     const TInt KSubsriptionLength( 512 );
       
   496     const TUint8 KPnsSubscribedResourcesExtendLength( 12 );
       
   497     const TUint8 KIADEventSubscriptionObjId( 0xfc );
       
   498     // TODO: Assertion to somewhere else?
       
   499     TDes8& desPtr =  iRouter.AllocateBlock( KSubsriptionLength );
       
   500     ASSERT_RESET_ALWAYS( KSubsriptionLength > ( ISI_HEADER_SIZE + PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_OFFSET_RESOURCECOUNT ) , EIADOverTheLimits | EIADFaultIdentifier42 << KFaultIdentifierShift );                                                        	
       
   501 
       
   502     TUint8* ptr( const_cast<TUint8*>( desPtr.Ptr() ) );
       
   503 #ifndef NCP_COMMON_BRIDGE_FAMILY
       
   504     ptr[ ISI_HEADER_OFFSET_MEDIA ] = PN_MEDIA_SOS;
       
   505 #else
       
   506     ptr[ ISI_HEADER_OFFSET_MEDIA ] = PN_MEDIA_MODEM_HOST_IF;
       
   507 #endif
       
   508     SET_RECEIVER_DEV( ptr, OTHER_DEVICE_1 );
       
   509     SET_SENDER_DEV( ptr, THIS_DEVICE );
       
   510     ptr[ ISI_HEADER_OFFSET_RESOURCEID ] = PN_COMMGR;
       
   511     SET_RECEIVER_OBJ( ptr, PN_OBJ_ROUTER );
       
   512 
       
   513     SET_SENDER_OBJ( ptr, KIADEventSubscriptionObjId );
       
   514     ptr[ ISI_HEADER_SIZE + PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_OFFSET_TRANSACTIONID ] = 0x00;
       
   515     ptr[ ISI_HEADER_SIZE + PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_OFFSET_MESSAGEID ] = PNS_SUBSCRIBED_RESOURCES_EXTEND_IND;
       
   516     desPtr.SetLength( KPnsSubscribedResourcesExtendLength );
       
   517 
       
   518     TServerIdLink* serverLink = NULL;
       
   519     SDblQueLink* anchor = &iServerQ.iA;
       
   520     SDblQueLink* next = anchor->iNext;
       
   521 
       
   522     TUint8 serverIndex( 0x00 );
       
   523     TUint8 resourceCount( 0x00 );
       
   524     while( anchor != next ) // servers
       
   525         {
       
   526         serverLink = _LOFF( next, TServerIdLink, iServerLink );
       
   527         TUint32 resourceId = serverLink->iResourceId;
       
   528         C_TRACE( ( _T("DIndicationHandler::SendSubscription Server: 0x%08x"), resourceId ) );
       
   529         OstTrace1( TRACE_DETAILED, DINDICATIONHANDLER_SENDSUBSCRIPTION, "DIndicationHandler::SendSubscription;resourceId=%x", resourceId );
       
   530         
       
   531         desPtr.Append( static_cast<TUint8>( resourceId >> 24 ) );
       
   532         desPtr.Append( static_cast<TUint8>( resourceId >> 16 ) );
       
   533         desPtr.Append( static_cast<TUint8>( resourceId >> 8 ) );
       
   534         desPtr.Append( static_cast<TUint8>( resourceId ) );
       
   535         resourceCount++;
       
   536         next = next->iNext;
       
   537         serverIndex++;
       
   538         }
       
   539     ptr[ ISI_HEADER_SIZE + PNS_SUBSCRIBED_RESOURCES_EXTEND_IND_OFFSET_RESOURCECOUNT ] = resourceCount;
       
   540 
       
   541     TInt messageLength( ( resourceCount * 4 ) + KPnsSubscribedResourcesExtendLength );
       
   542     while( messageLength % 4 != 0 )
       
   543         {
       
   544         TRACE_ASSERT_ALWAYS;
       
   545         messageLength++;
       
   546         }
       
   547     // TODO : does this work? setting of length after append?
       
   548     desPtr.SetLength( messageLength );
       
   549     SET_LENGTH( ptr, messageLength - PN_HEADER_SIZE );
       
   550     C_TRACE( ( _T( "DIndicationHandler::SendSubscription <-" ) ) );    
       
   551     TInt error = iRouter.SendMessage( desPtr, KIADEventSubscriptionObjId );
       
   552 
       
   553     OstTrace1( TRACE_DETAILED, DINDICATIONHANDLER_SENDSUBSCRIPTION_EXIT, "<DIndicationHandler::SendSubscription<;error=%d", error );
       
   554     return error;
       
   555     }
       
   556 
       
   557 
       
   558 // End of file.
       
   559 
       
   560