diff -r 6295dc2169f3 -r 8486d82aef45 connectivitylayer/isce/isirouter_dll/src/isicltransceiver.cpp --- a/connectivitylayer/isce/isirouter_dll/src/isicltransceiver.cpp Wed Apr 21 14:29:55 2010 +0300 +++ b/connectivitylayer/isce/isirouter_dll/src/isicltransceiver.cpp Tue Oct 19 13:16:20 2010 +0300 @@ -17,151 +17,449 @@ -#include // For Kern -#include "isirouter.h" // For DISIRouter -#include "isiroutertrace.h" // For C_TRACE, ASSERT_RESET.. and fault codes -#include "misirouterlinkif.h" // For MISIRouterLinkIf -#include "isihelpers.h" // For GET_SENDER_DEV... -#include "memapi.h" // For MemApi -#include // For ETrxTest... -#include "isicltransceiver.h" // For DISICLTransceiver -#include // For PN_NAMESERVICE... TODO:Remove this +#include // For Kern +#include // For PN_OBJ_ROUTING_REQ +#include // For ISI_HEADER_OFFSET_... +#include // For COMMON_ISA_... -#define PN_MEDIA_TEST 0xBB //not real -//#define PN_DEV_MODEM 0x12 -#define PN_DEV_DUMMYIST 0x13 -#define PN_DEV_OWN 0x6C - -// CONSTS -DISICLTransceiver* DISICLTransceiver::iThisPtr = NULL; - +#include "isirouter.h" // For DISIRouter +#include "isiroutertrace.h" // For C_TRACE, ASSERT_RESET.. and fault codes +#include "misirouterlinkif.h" // For MISIRouterLinkIf +#include "isihelpers.h" // For GET_SENDER_DEV... +#include "memapi.h" // For MemApi +#include // For ETrxTest... +#include "isicltransceiver.h" // For DISICLTransceiver +#include // For PN_NAMESERVICE... +#include "isirouterservice.h" // For DIsiRouterService +#include "isimsgqueue.h" // For DISIMsgQueue +#include "iscnokiadefinitions.h" // For EIscNokiaUsbPhonetLink +#ifdef USE_MEDIAAPI +#include // For PN_DEV_PC +#endif /* USE_MEDIAAPI */ // Faults enum TISICLTransceiverFaults { EISICLTransceiverMemAllocFailure = 0x01, EISICLTransceiverMemAllocFailure1, + EISICLTransceiverMemAllocFailure2, + EISICLTransceiverMemAllocFailure3, + EISICLTransceiverMemAllocFailure4, + EISICLTransceiverMemAllocFailure5, + EISICLTransceiverMemAllocFailure6, + EISICLTransceiverMemAllocFailure7, + EISICLTransceiverMemAllocFailure8, +#ifdef USE_MEDIAAPI + EISICLTransceiverMemAllocFailure9, + EISICLTransceiverMemAllocFailure10, +#endif /* USE_MEDIAAPI */ EISICLTransceiverNotSupportedMedia, EISICLTransceiverOverTheLimits, EISICLTransceiverNULLPtr, + EISICLTransceiverNULLPtr2, + EISICLTransceiverNULLPtr3, + EISICLTransceiverNULLPtr4, + EISICLTransceiverNULLPtr5, + EISICLTransceiverNULLPtr6, + EISICLTransceiverNULLPtr7, EISICLTransceiverNotSupportedDevice, + EISICLTransceiverDeviceConnection, + EISICLTransceiverCommIsaEntityNotReachableResp, + EISICLTransceiverNotThreadContext, + EISICLTransceiverMutexCreateFailed, + EISICLTransceiverMutexWaitFailed, + EISICLTransceiverMutexWaitFailed2, }; -DISICLTransceiver::DISICLTransceiver( DISIRouter* aPtr ) - : iRouter( aPtr ) +// Constants +const TInt KDfcPriority( 5 ); + +DMutex* DISICLTransceiver::iDynamicDeviceTableMutex = NULL; +_LIT8( KISICLTransceiverMutex, "ISICLTransceiverMutex" ); + +DISICLTransceiver::DISICLTransceiver( + DISIRouter& aRouter, + TDfcQue* aThreadPtr + ) + : iShRouter( aRouter ) { C_TRACE( ( _T( "DISICLTransceiver::DISICLTransceiver>" ) ) ); - iLinksArray = new MISIRouterLinkIf*[ EISIAmountOfMedias ]; - ASSERT_RESET_ALWAYS( iLinksArray, ( EISICLTransceiverMemAllocFailure | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); - // Initialize links - for( TInt i( 0 ); i < EISIAmountOfMedias; i++ ) - { - iLinksArray[ i ] = NULL; - } - //TODO add real media and trx when known - iLinksArray[ EISIMediaTest ] = MISIRouterLinkIf::CreateLinkF( this, PN_MEDIA_TEST, ETrxTest ); + ASSERT_RESET_ALWAYS( aThreadPtr, ( EISICLTransceiverNULLPtr7 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + iShStateChangedDfc = new TDfc( StateChangedDfc, this, aThreadPtr, KDfcPriority ); + ASSERT_RESET_ALWAYS( iShStateChangedDfc, ( EISICLTransceiverMemAllocFailure6 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + + iRxQueueDfc = new TDfc( RxQueueDfc, this, aThreadPtr, KDfcPriority ); + ASSERT_RESET_ALWAYS( iShStateChangedDfc, ( EISICLTransceiverMemAllocFailure8 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + + DISIDevice* dev = new DISIDevice( PN_DEV_MODEM, + MISIRouterLinkIf::CreateLinkF( this, PN_MEDIA_MODEM_HOST_IF, ETrxSharedMemory) + ); + ASSERT_RESET_ALWAYS( dev, ( EISICLTransceiverMemAllocFailure3 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + iShDevices.Append( dev ); +#ifdef USE_MEDIAAPI + DISIDevice* dev2 = new DISIDevice( PN_DEV_PC, // append to dynamic table if needed + MISIRouterLinkIf::CreateLinkF( this, PN_MEDIA_USB, ETrxUSB ) + ); + ASSERT_RESET_ALWAYS( dev2, ( EISICLTransceiverMemAllocFailure9 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + iShDevices.Append( dev2 ); + + DISIDevice* dev4 = new DISIDevice( PN_DEV_PC, // append to dynamic table if needed + MISIRouterLinkIf::CreateLinkF( this, PN_MEDIA_BT, ETrxBT ) + ); + ASSERT_RESET_ALWAYS( dev4, ( EISICLTransceiverMemAllocFailure10 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + iShDevices.Append( dev4 ); + #endif /* USE_MEDIAAPI */ + DISIDevice* dev3 = new DISIDevice( PN_DEV_DUMMYIST, + MISIRouterLinkIf::CreateLinkF( this, PN_MEDIA_TEST, ETrxTest ) + ); + ASSERT_RESET_ALWAYS( dev3, ( EISICLTransceiverMemAllocFailure5 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + iShDevices.Append( dev3 ); + + iRouterService = new DIsiRouterService( *this ); + ASSERT_RESET_ALWAYS( iRouterService, ( EISICLTransceiverMemAllocFailure2 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + + iRxQueue = new DISIMsgQueue( KISIMainRxQueueSize ); + ASSERT_RESET_ALWAYS( iRxQueue, ( EISICLTransceiverMemAllocFailure7 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + + TInt err( Kern::MutexCreate( iDynamicDeviceTableMutex, KISICLTransceiverMutex, KMutexOrdGeneral0 ) ); + ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EISICLTransceiverMutexCreateFailed | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); +#ifdef USE_MEDIAAPI + iDevPcLastSendTrxId = EAmountOfTrxs; //put a maxvalue + iDevPcLastActiveTrxId = EAmountOfTrxs; //put a maxvalue +#endif /* USE_MEDIAAPI */ C_TRACE( ( _T( "DISICLTransceiver::DISICLTransceiver<" ) ) ); } DISICLTransceiver::~DISICLTransceiver() { C_TRACE( ( _T( "DISICLTransceiver::~DISICLTransceiver>" ) ) ); - for( TUint8 i( 0 ); i < EISIAmountOfMedias; i++ ) + + iShDevices.ResetAndDestroy(); + + if ( iRouterService ) + { + delete iRouterService; + iRouterService = NULL; + } + + if ( iShStateChangedDfc ) + { + iShStateChangedDfc->Cancel(); + delete iShStateChangedDfc; + iShStateChangedDfc = NULL; + } + + if( iRxQueue ) { - MISIRouterLinkIf* tmp = iLinksArray[ i ]; - if( tmp ) + C_TRACE( ( _T( "DISICLTransceiver::ResetQueues 0x%x iRxQueue 0x%x" ), this, iRxQueue ) ); + while( iRxQueue->Count() ) { - tmp->Release(); - tmp = NULL; - iLinksArray[ i ] = NULL; + MemApi::DeallocBlock( iRxQueue->Get() ); } } - delete []iLinksArray; + + if( iRxQueueDfc ) + { + C_TRACE( ( _T( "DISIUserChannel::~DISIUserChannel 0x%x iRxQueueDfc 0x%x" ), this, iRxQueueDfc ) ); + iRxQueueDfc->Cancel(); + delete iRxQueueDfc; + iRxQueueDfc = NULL; + } + C_TRACE( ( _T( "DISICLTransceiver::~DISICLTransceiver<" ) ) ); + + } + +TInt DISICLTransceiver::SendCommIsaEntityNotReachableResp( + TDes8& aNotDeliveredMessage + ) + { + C_TRACE( ( _T( "DISICLTransceiver::SendCommIsaEntityNotReachableResp 0x%x>" ), &aNotDeliveredMessage ) ); + const TUint8* notDeliveredMsgPtr( aNotDeliveredMessage.Ptr() ); + TInt error = KErrAlreadyExists; + // Avoid COMM_ISA_ENTITY_NOT_REACHABLE_RESP loop. + if( ( notDeliveredMsgPtr[ ISI_HEADER_OFFSET_MESSAGEID ] == COMMON_MESSAGE ) && + ( ( notDeliveredMsgPtr[ ISI_HEADER_OFFSET_SUBMESSAGEID ] == COMM_ISA_ENTITY_NOT_REACHABLE_RESP ) || + ( notDeliveredMsgPtr[ ISI_HEADER_OFFSET_SUBMESSAGEID ] == COMM_SERVICE_NOT_IDENTIFIED_RESP ) ) ) + { + C_TRACE( ( _T( "DISICLTransceiver Not sending another CommIsaEntityNotReachableResp 0x%x 0x%x" ), &aNotDeliveredMessage, notDeliveredMsgPtr[ ISI_HEADER_OFFSET_SUBMESSAGEID ] ) ); + } + else + { + // Follows COMM specification: 000.031 + TUint8 length( ISI_HEADER_SIZE + SIZE_COMMON_MESSAGE_COMM_ISA_ENTITY_NOT_REACHABLE_RESP ); + TDes8& respMsg = MemApi::AllocBlock( length ); + ASSERT_RESET_ALWAYS( length > ISI_HEADER_OFFSET_MESSAGEID, ( EISICLTransceiverOverTheLimits | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + TUint8* respMsgPtr = const_cast( respMsg.Ptr() ); + // We start to append from transaction id. + respMsg.SetLength( ISI_HEADER_OFFSET_TRANSID ); + // Get the header until messageid from prev. message. + // Just turn receiver and sender device and object vice versa. + respMsgPtr[ ISI_HEADER_OFFSET_MEDIA ] = notDeliveredMsgPtr[ ISI_HEADER_OFFSET_MEDIA ]; + SET_RECEIVER_DEV( respMsgPtr, GET_SENDER_DEV( aNotDeliveredMessage ) ); + SET_SENDER_DEV ( respMsgPtr, GET_RECEIVER_DEV( aNotDeliveredMessage ) ); + respMsgPtr[ ISI_HEADER_OFFSET_RESOURCEID ] = notDeliveredMsgPtr[ ISI_HEADER_OFFSET_RESOURCEID ]; + SET_LENGTH( respMsgPtr, ( length - PN_HEADER_SIZE ) ); + SET_RECEIVER_OBJ( respMsgPtr, GET_SENDER_OBJ( aNotDeliveredMessage ) ); + SET_SENDER_OBJ( respMsgPtr, GET_RECEIVER_OBJ( aNotDeliveredMessage ) ); + // Set from undelivered message + respMsg.Append( notDeliveredMsgPtr[ ISI_HEADER_OFFSET_TRANSID ] ); + // Message Identifier + respMsg.Append( COMMON_MESSAGE ); + // Sub message Identifier. + respMsg.Append( COMM_ISA_ENTITY_NOT_REACHABLE_RESP ); + // Not Delivered Message from original message. + respMsg.Append( notDeliveredMsgPtr[ ISI_HEADER_OFFSET_MESSAGEID ] ); + // Status + respMsg.Append( COMM_ISA_ENTITY_NOT_AVAILABLE );// different status in a case of device not existing + // Filler + const TUint8 KFiller( 0x00 ); + respMsg.Append( KFiller ); + // Filler + respMsg.Append( KFiller ); + // Filler + respMsg.Append( KFiller ); + error = RouteISIMessage( respMsg, EFalse ); + // Programming error in this function if below assert is raised + ASSERT_RESET_ALWAYS( KErrNone == error, ( EISICLTransceiverCommIsaEntityNotReachableResp | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + } + MemApi::DeallocBlock( aNotDeliveredMessage ); + C_TRACE( ( _T( "DISICLTransceiver::SendCommIsaEntityNotReachableResp 0x%x<" ), &aNotDeliveredMessage ) ); + return error; + } -TInt DISICLTransceiver::SendCommIsaEntityNotReachableResp( TDes8& aMessage ) +// This is called in 1...N thread contextes +void DISICLTransceiver::ReceiveISIMessage( + const TDesC8& aMessage, + const TUint8 aTrxId + ) { - C_TRACE( ( _T( "DISICLTransceiver::SendCommIsaEntityNotReachableResp 0x%x>" ), &aMessage ) ); - const TUint8* msgTmpPtr( aMessage.Ptr() ); - TInt error = KErrAlreadyExists; + C_TRACE( ( _T( "DISICLTransceiver::ReceiveMsg 0x%x 0x%x 0x%x>" ), this, &aMessage, aTrxId ) ); + // Can only be called from thread context. + ASSERT_THREAD_CONTEXT_ALWAYS( ( EISICLTransceiverNotThreadContext | EDISIUserChannelTraceId << KClassIdentifierShift ) ); + + TUint8 txDevId = GET_SENDER_DEV( aMessage.Ptr() ); + if ( DynamicDevice( txDevId ) ) + { + TUint8 staticDevId(0); + const TInt count( iShDevices.Count() ); + TInt index(0); + TBool staticDeviceFound(EFalse); + MISIRouterLinkIf* Link = NULL; + while( !staticDeviceFound && ( index < count ) ) + { + C_TRACE( ( _T( "DISICLTransceiver::ReceiveMsg find static device for trx 0x%x index %d" ), aTrxId, index ) ); + DISIDevice* tmpDevice = iShDevices[ index ]; + ASSERT_RESET_ALWAYS( tmpDevice, ( EISICLTransceiverNULLPtr4 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + tmpDevice->LockDeviceFM(); + Link = tmpDevice->GetLink(); + if( Link->GetTrxId() == aTrxId ) + { + staticDevId = tmpDevice->GetDeviceIdentifier(); + tmpDevice->FreeDeviceFM(); + C_TRACE( ( _T( "DISICLTransceiver::ReceiveMsg static device 0x%x trx 0x%x" ), this, &aMessage, aTrxId ) ); + staticDeviceFound = ETrue; + } + else + { + tmpDevice->FreeDeviceFM(); + } + index++; + } +#ifdef USE_MEDIAAPI + if ( PN_DEV_PC == GET_SENDER_DEV( aMessage.Ptr() )) + { + C_TRACE( ( _T( "DISICLTransceiver::ReceiveMsg 0x%x 0x%x trx id = %d<" ), this, &aMessage, (Link->GetTrxId()) ) ); + iDevPcLastActiveTrxId = iDevPcLastSendTrxId; + iDevPcLastSendTrxId = Link->GetTrxId(); + } +#endif /* USE_MEDIAAPI */ + UpdateDynamicDeviceTable( txDevId, staticDevId ); + } + // else static device. No need to save trxId - // To avoid COMM_ISA_ENTITY_NOT_REACHABLE_RESP loop - if( msgTmpPtr[ ISI_HEADER_OFFSET_MESSAGEID ] != COMMON_MESSAGE && - msgTmpPtr[ ISI_HEADER_OFFSET_SUBMESSAGEID ] != COMM_ISA_ENTITY_NOT_REACHABLE_RESP ) + iRxQueue->Add( aMessage ); + iRxQueueDfc->Enque(); + C_TRACE( ( _T( "DISICLTransceiver::ReceiveMsg 0x%x 0x%x 0x%x<" ), this, &aMessage, aTrxId ) ); + } + +void DISICLTransceiver::RxQueueDfc( + TAny* aPtr // Pointer to this object. + ) + { + C_TRACE( ( _T( "DISICLTransceiver::RxQueueDfc ->" ) ) ); + + DISICLTransceiver& tmp = *reinterpret_cast( aPtr ); + if( tmp.iRxQueue->Count() > 0 ) + { + TDes8& msg( tmp.iRxQueue->Get() ); + + tmp.RouteISIMessage( msg, EFalse ); + // Check here too to avoid unnecessary dfc queuing. + if( tmp.iRxQueue->Count() > 0 ) + { + C_TRACE( ( _T( "DISICLTransceiver::RxQueueDfc enque RxQueueDfc" ) ) ); + tmp.iRxQueueDfc->Enque(); + } + } + C_TRACE( ( _T( "DISICLTransceiver::RxQueueDfc <-" ) ) ); + } + + +TInt DISICLTransceiver::RouteISIMessage( + TDes8& aMessage, + TBool aDynamicSenderCheckNeeded + ) + { + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage 0x%x 0x%x> len %d" ), &aMessage, aDynamicSenderCheckNeeded, aMessage.Length() ) ); + const TUint8* msgPtr = aMessage.Ptr(); + ISIMESSAGE_TRACE( aMessage ); + TInt error( ValidateISIMessage( aMessage ) ); + if( KErrNone != error ) + { + TRACE_ASSERT_ALWAYS; + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage invalid message 0x%x" ), &aMessage ) ); + MemApi::DeallocBlock( aMessage ); + } + else { - // Make channel opening request followinfg COMM specification: 000.026 - // Length is sixteen bytes. - TUint8 length( 16 ); - TDes8& tempPtr = MemApi::AllocBlock( ISI_HEADER_SIZE + SIZE_COMMON_MESSAGE_COMM_ISA_ENTITY_NOT_REACHABLE_RESP ); - ASSERT_RESET_ALWAYS( &tempPtr, ( EISICLTransceiverMemAllocFailure1 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); - ASSERT_RESET_ALWAYS( ISI_HEADER_SIZE + SIZE_COMMON_MESSAGE_COMM_ISA_ENTITY_NOT_REACHABLE_RESP > ISI_HEADER_OFFSET_MESSAGEID, ( EISICLTransceiverOverTheLimits | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); - TUint8* ptr = const_cast( tempPtr.Ptr() ); - // We start to append from transaction id. - tempPtr.SetLength( ISI_HEADER_OFFSET_TRANSID ); - // Get the header until messageid from prev. message. - // Just turn receiver and sender device and object vice versa. - ptr[ ISI_HEADER_OFFSET_MEDIA ] = msgTmpPtr[ ISI_HEADER_OFFSET_MEDIA ]; - SET_RECEIVER_DEV( ptr, GET_SENDER_DEV( aMessage ) ); - SET_SENDER_DEV ( ptr, GET_RECEIVER_DEV( aMessage ) ); - ptr[ ISI_HEADER_OFFSET_RESOURCEID ] = msgTmpPtr[ ISI_HEADER_OFFSET_RESOURCEID ]; - SET_LENGTH( ptr, length - PN_HEADER_SIZE ); - SET_RECEIVER_OBJ( ptr, GET_SENDER_OBJ( aMessage ) ); - SET_SENDER_OBJ( ptr, GET_RECEIVER_OBJ( aMessage ) ); - // Transactionid. Set to 0x01 since this is the first. - tempPtr.Append( msgTmpPtr[ ISI_HEADER_OFFSET_TRANSID ] ); - // Message ID - tempPtr.Append( ISI_HEADER_OFFSET_MESSAGEID ); - // Sub message ID. - tempPtr.Append( COMM_ISA_ENTITY_NOT_REACHABLE_RESP ); - // Not Delivered Message from original req. - tempPtr.Append( msgTmpPtr[ ISI_HEADER_OFFSET_MESSAGEID ] ); - // Status - COMM_ISA_ENTITY_NOT_AVAILABLE - tempPtr.Append( 0x00 ); - // Filler - tempPtr.Append( 0x00 ); - // Filler - tempPtr.Append( 0x00 ); - // Filler - tempPtr.Append( 0x00 ); - error = RouteISIMessage( tempPtr ); - } - else - { - C_TRACE( ( _T( "DISICLTransceiver Not sending another CommIsaEntityNotReachableResp" ) ) ); - } - C_TRACE( ( _T( "DISICLTransceiver::SendCommIsaEntityNotReachableResp 0x%x<" ), &aMessage ) ); + TBool sendOk( EFalse ); + if ( aDynamicSenderCheckNeeded )// Save dynamic device ids from PN_DEV_OWN + { + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage from ISI Router" ) ) ); + TUint8 txDeviceIdentifier = GET_SENDER_DEV( aMessage ); + if ( DynamicDevice( txDeviceIdentifier ) ) + { + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage from ISI Router Dynamic Dev" ) ) ); + UpdateDynamicDeviceTable( txDeviceIdentifier, PN_DEV_OWN ); +#ifndef USE_MEDIAAPI + ASSERT_RESET_ALWAYS( txDeviceIdentifier == PN_DEV_PC, 0xdeaddead );// only supported PN_DEV_PC with EIscNokiaUsbPhonetLink +#endif /* USE_MEDIAAPI */ + } + } + + TUint8 rxDeviceIdentifier = GET_RECEIVER_DEV( aMessage ); + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage rxDeviceIdentifier 0x%x" ), rxDeviceIdentifier ) ); + + if ( DynamicDevice( rxDeviceIdentifier ) ) + { + DynamicToStaticDevice( rxDeviceIdentifier ); + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage rxDeviceIdentifier after 0x%x" ), rxDeviceIdentifier ) ); + } + + + if( rxDeviceIdentifier == PN_DEV_OWN ) + { + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage PN_DEV_OWN 0x%x" ), &aMessage ) ); + TUint16 objId(0xffff); +#ifndef USE_MEDIAAPI + if ( GET_RECEIVER_DEV( aMessage ) == PN_DEV_PC ) + { + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage to PN_DEV_PC in PN_DEV_OWN" )) ); + objId = EIscNokiaUsbPhonetLink; + } + else + { + objId = GET_RECEIVER_OBJ( aMessage ); + } +#endif /* USE_MEDIAAPI */ +#ifdef USE_MEDIAAPI + objId = GET_RECEIVER_OBJ( aMessage ); +#endif /* USE_MEDIAAPI */ + sendOk = iShRouter.Receive( aMessage, objId ); + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage PN_DEV_OWN 0x%x ok %d" ), &aMessage, sendOk ) ); + } + else + { + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage Not PN_DEV_OWN 0x%x" ), &aMessage ) ); + MISIRouterLinkIf* link = NULL; + + + const TInt count( iShDevices.Count() ); + for( TInt index( 0 ); index < count; index++ ) + { + DISIDevice* tmpDevice = iShDevices[ index ]; + ASSERT_RESET_ALWAYS( tmpDevice, ( EISICLTransceiverNULLPtr4 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + tmpDevice->LockDeviceFM(); + if( tmpDevice->GetDeviceIdentifier() == rxDeviceIdentifier ) + { + link = tmpDevice->GetLink(); + tmpDevice->FreeDeviceFM(); +#ifndef USE_MEDIAAPI + sendOk = link->Send( aMessage ); + break; +#endif /* USE_MEDIAAPI */ +#ifdef USE_MEDIAAPI + if ( GET_RECEIVER_DEV( aMessage ) == PN_DEV_PC ) + { + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage PN_DEV_PC %d, %d" ), link->GetTrxId(), iDevPcLastSendTrxId ) ); + if(iDevPcLastSendTrxId < EAmountOfTrxs) + { + if ( link->GetTrxId() == iDevPcLastSendTrxId ) + { + if (link->StateConnected()) + { + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage PN_DEV_PC %d, Msg mediaid 0x%x" ), link->GetTrxId(), msgPtr[ ISI_HEADER_OFFSET_MEDIA ] ) ); + sendOk = link->Send( aMessage ); + break; + } + } + } + else + { + break; + } + } + else + { + sendOk = link->Send( aMessage ); + break; + } +#endif /* USE_MEDIAAPI */ + } + else + { + tmpDevice->FreeDeviceFM(); + } + } + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage Not PN_DEV_OWN ok %d" ), &aMessage, sendOk ) ); + } + if( !sendOk ) + { + TRACE_ASSERT_ALWAYS; + error = SendCommIsaEntityNotReachableResp( aMessage ); + } + } + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage 0x%x<" ), &aMessage ) ); return error; } -TInt DISICLTransceiver::RouteISIMessage( TDes8& aMessage ) +void DISICLTransceiver::GetDeviceConnectionStates( + RArray& aDeviceIdentifierList, + const TBool aConnectedDevice + ) { - C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage 0x%x>" ), &aMessage ) ); - TInt error( ValidateISIMessage( aMessage ) ); - TBool sendOk( EFalse ); - if(GET_RECEIVER_DEV( aMessage ) == PN_DEV_OWN ) - { - C_TRACE( ( _T( "DISIRouter msg to PN_DEV_APE" ) ) ); - sendOk = iRouter->Receive( aMessage, GET_RECEIVER_OBJ( aMessage ) ); - C_TRACE( ( _T( "DISIRouter router sendOk %d" ), sendOk ) ); - } - else + C_TRACE( ( _T( "DISICLTransceiver::GetDeviceConnectionStates 0x%x 0x%x>" ), &aDeviceIdentifierList, aConnectedDevice ) ); + + const TInt count( iShDevices.Count() ); + for( TInt index( 0 ); index < count; index++ ) { - C_TRACE( ( _T( "DISIRouter msg to other device" ) ) ); - TUint8 linkId = MapDeviceToMedia( GET_RECEIVER_DEV( aMessage ) ); - ASSERT_RESET_ALWAYS( linkId < EISIAmountOfMedias, ( EISICLTransceiverNotSupportedMedia | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); - MISIRouterLinkIf* link = iLinksArray[ linkId ]; - ASSERT_RESET_ALWAYS( link, ( EISICLTransceiverNULLPtr | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); - sendOk = link->Send( aMessage ); - C_TRACE( ( _T( "DISIRouter link sendOk %d" ), sendOk ) ); - } - if( !sendOk ) - { - SendCommIsaEntityNotReachableResp( aMessage ); - MemApi::DeallocBlock( aMessage ); + DISIDevice* tmpDevice = iShDevices[ index ]; + ASSERT_RESET_ALWAYS( tmpDevice, ( EISICLTransceiverNULLPtr3 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + tmpDevice->LockDeviceFM(); + if( tmpDevice->GetDeviceState() == aConnectedDevice ) + { + const TUint8 deviceIdentifier( tmpDevice->GetDeviceIdentifier() ); + tmpDevice->FreeDeviceFM(); + aDeviceIdentifierList.Append( deviceIdentifier ); + } + else + { + tmpDevice->FreeDeviceFM(); + } } - C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage 0x%x<" ), &aMessage ) ); - return error; + C_TRACE( ( _T( "DISICLTransceiver::GetDeviceConnectionStates 0x%x 0x%x<" ), &aDeviceIdentifierList, aConnectedDevice ) ); } // KErrBadDescriptor, if message length too small @@ -171,6 +469,7 @@ TDes8& aMessage ) { + C_TRACE( ( _T( "DISICLTransceiver::ValidateISIMessage 0x%x>" ), &aMessage ) ); const TUint16 descLength( aMessage.Length() ); TInt msgOk( KErrNone ); @@ -188,40 +487,217 @@ // If the ISI message length with PN_HEADER_SIZE is less or equal than ISI_HEADER_OFFSET_MESSAGEID. msgOk = ( ( msgOk == KErrNone && isiMsgLength <= ISI_HEADER_OFFSET_MESSAGEID ) ? KErrUnderflow : msgOk ); TRACE_ASSERT_INFO( msgOk == KErrNone, msgOk ); - TRACE_ASSERT_INFO( msgOk == KErrNone, msgOk ); TRACE_ASSERT_INFO( msgOk == KErrNone, isiMsgLength ); TRACE_ASSERT_INFO( msgOk == KErrNone, descLength ); - TRACE_ASSERT_INFO( msgOk == KErrNone, msgOk ); C_TRACE( ( _T( "DISICLTransceiver::ValidateISIMessage %d<" ), msgOk ) ); return msgOk; } -TUint8 DISICLTransceiver::MapDeviceToMedia( - const TUint8 aDevice +// NOTE!! Called with FM held. Not allowed to block or nothing. Not even print traces! +// Called in N Thread context +void DISICLTransceiver::StateChanged( + // None + ) + { + + iShStateChangedDfc->Enque(); + + } + +void DISICLTransceiver::StateChangedDfc( + TAny* aPtr + ) + { + C_TRACE( ( _T( "DISICLTransceiver::StateChangedDfc>" ) ) ); + DISICLTransceiver* self = reinterpret_cast( aPtr ); + ASSERT_RESET_ALWAYS( self, ( EISICLTransceiverNULLPtr5 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + self->ReadStateChanges(); + C_TRACE( ( _T( "DISICLTransceiver::StateChangedDfc<" ) ) ); + } + +void DISICLTransceiver::ReadStateChanges( + // None ) { - C_TRACE( ( _T( "DISICLTransceiver::MapDeviceToMedia aDevice %d>" ), aDevice ) ); - TUint8 media( KErrNone ); - switch( aDevice ) + + C_TRACE( ( _T( "DISICLTransceiver::ReadStateChanges>" ) ) ); + + const TInt count( iShDevices.Count() ); + for( TInt index( 0 ); index < count; index++ ) { - case PN_DEV_MODEM: + DISIDevice* tmpDevice = iShDevices[ index ]; + ASSERT_RESET_ALWAYS( tmpDevice, ( EISICLTransceiverNULLPtr6 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + tmpDevice->LockDeviceFM(); + const TBool connected = tmpDevice->GetDeviceState();// tee paremmaksi + +#ifdef USE_MEDIAAPI + MISIRouterLinkIf* link = NULL; + link = tmpDevice->GetLink(); +#endif /* USE_MEDIAAPI */ + if( connected != tmpDevice->GetDeviceOldState() ) { - media = EISIMediaSharedMemory; + tmpDevice->SetDeviceOldState( connected ); + const TUint8 deviceIdentifier = tmpDevice->GetDeviceIdentifier(); + tmpDevice->FreeDeviceFM(); +#ifdef USE_MEDIAAPI + C_TRACE( ( _T( "DISICLTransceiver::ReadStateChanges trxid 0x%x state changed>" ),link->GetTrxId() ) ); + if( (link->GetTrxId() == iDevPcLastSendTrxId) && (!connected) ) + { + C_TRACE( ( _T( "DISICLTransceiver::ReadStateChanges trxid 0x%x disconneted>" ),link->GetTrxId() ) ); + iDevPcLastSendTrxId = iDevPcLastActiveTrxId; + iDevPcLastActiveTrxId = EAmountOfTrxs; //put a maxvalue + } +#endif /* USE_MEDIAAPI */ + iRouterService->SendDeviceConnectionStateChangedInd( connected, deviceIdentifier ); + } + else + { + tmpDevice->FreeDeviceFM(); + } + } + C_TRACE( ( _T( "DISICLTransceiver::ReadStateChanges<" ) ) ); + } + +TBool DISICLTransceiver::DynamicDevice( const TUint8 aDevId ) + { + C_TRACE( ( _T( "DISICLTransceiver::DynamicDevice 0x%x>" ), aDevId ) ); + TBool dynamicDevice(EFalse); + switch( aDevId ) + { + case PN_DEV_MODEM: + case PN_DEV_DUMMYIST: + case PN_DEV_OWN: + { + //already set as EFalse break; } - case PN_DEV_DUMMYIST: - { - media = EISIMediaTest; - break; - } - // Not supported device default: { - ASSERT_RESET_ALWAYS( 0, ( EISICLTransceiverNotSupportedDevice | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + dynamicDevice = ETrue; break; } } - C_TRACE( ( _T( "DISICLTransceiver::MapDeviceToMedia media %d<" ), media ) ); - return media; + C_TRACE( ( _T( "DISICLTransceiver::DynamicDevice 0x%x<" ), dynamicDevice ) ); + return dynamicDevice; + } + +void DISICLTransceiver::UpdateDynamicDeviceTable( const TUint8 aDynamicDevId, const TUint8 aStaticDevId ) + { + C_TRACE( ( _T( "DISICLTransceiver::UpdateDynamicDeviceTable 0x%x 0x%x>" ), aDynamicDevId, aStaticDevId) ); + TBool deviceExist(EFalse); + TInt count(iDynamicDeviceTable.Count()); + TInt err( Kern::MutexWait( *iDynamicDeviceTableMutex ) ); + ASSERT_RESET_ALWAYS( ( err == KErrNone ), ( EISICLTransceiverMutexWaitFailed2 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + for( TUint8 i = 0; i < count; i++ ) + { + C_TRACE( ( _T( "DISICLTransceiver::UpdateDynamicDeviceTable find dynamic device %d" ), i) ); + if( iDynamicDeviceTable[ i ]->iDynamicDevId == aDynamicDevId ) + { + C_TRACE( ( _T( "DISICLTransceiver::UpdateDynamicDeviceTable dyn dev exist i = %d aDynamicDevId 0x%x staticDevId 0x%x previous 0x%x" ), i, iDynamicDeviceTable[ i ]->iDynamicDevId, aStaticDevId, iDynamicDeviceTable[ i ]->iStaticDevId ) ); + iDynamicDeviceTable[ i ]->iStaticDevId = aStaticDevId; + deviceExist = ETrue; + break; + } + } + + if ( !deviceExist ) + { + C_TRACE( ( _T( "DISICLTransceiver::UpdateDynamicDeviceTable new dynamic device added 0x%x 0x%x" ), aDynamicDevId, aStaticDevId ) ); + iDynamicDeviceTable.Append( new TDynamicDevice( aDynamicDevId, aStaticDevId ) ); + } + Kern::MutexSignal( *iDynamicDeviceTableMutex ); + C_TRACE( ( _T( "DISICLTransceiver::UpdateDynamicDeviceTable 0x%x 0x%x<" ), aDynamicDevId, aStaticDevId) ); } +void DISICLTransceiver::DynamicToStaticDevice( TUint8& aRxDev ) + { + C_TRACE( ( _T( "DISICLTransceiver::DynamicToStaticDevice aRxDev>" ), &aRxDev ) ); + TInt err( Kern::MutexWait( *iDynamicDeviceTableMutex ) ); + ASSERT_RESET_ALWAYS( ( err == KErrNone ), ( EISICLTransceiverMutexWaitFailed | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + for( TUint8 i = 0; i < iDynamicDeviceTable.Count(); i++ ) + { + if( iDynamicDeviceTable[ i ]->iDynamicDevId == aRxDev ) + { + C_TRACE( ( _T( "DISICLTransceiver::DynamicToStaticDevice dyn dev exist i = %d iDynamicDevId 0x%x iStaticDevId 0x%x" ), i, iDynamicDeviceTable[ i ]->iDynamicDevId, iDynamicDeviceTable[ i ]->iStaticDevId) ); + aRxDev = iDynamicDeviceTable[ i ]->iStaticDevId; + break; + } + } + Kern::MutexSignal( *iDynamicDeviceTableMutex ); + C_TRACE( ( _T( "DISICLTransceiver::DynamicToStaticDevice aRxDev<" ), &aRxDev ) ); + } + + +DISICLTransceiver::DISIDevice::DISIDevice( + const TUint8 aDeviceIdentifier, + MISIRouterLinkIf* aLink + ) + { + C_TRACE( ( _T( "DISICLTransceiver::DISIDevice::DISIDevice 0x%x 0x%x 0x%x>" ), aDeviceIdentifier, aLink ) ); + iShDeviceIdentifier = aDeviceIdentifier; + iShOldDeviceConnectedState = EFalse; + ASSERT_RESET_ALWAYS( aLink, ( EISICLTransceiverNULLPtr2 | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + iShLink = aLink; + iShDeviceMutex = new NFastMutex(); + ASSERT_RESET_ALWAYS( iShDeviceMutex, EISICLTransceiverNULLPtr6 | EDISICLTransceiverTraceId << KClassIdentifierShift ); + C_TRACE( ( _T( "DISICLTransceiver::DISIDevice::DISIDevice<" ) ) ); + } + +DISICLTransceiver::DISIDevice::~DISIDevice() + { + C_TRACE( ( _T( "DISICLTransceiver::DISIDevice::~DISIDevice>" ) ) ); + iShLink->Release(); + iShLink = NULL; + // If not exists faulted already. + delete iShDeviceMutex; + iShDeviceMutex = NULL; + C_TRACE( ( _T( "DISICLTransceiver::DISIDevice::~DISIDevice<" ) ) ); + } + +MISIRouterLinkIf* DISICLTransceiver::DISIDevice::GetLink() + { +// C_TRACE( ( _T( "DISICLTransceiver::DISIDevice::GetLink<> 0x%x" ), iShLink ) ); + return iShLink; + } + +TUint8 DISICLTransceiver::DISIDevice::GetDeviceIdentifier() + { +// C_TRACE( ( _T( "DISICLTransceiver::DISIDevice::GetDeviceIdentifier<> 0x%x" ), iShDeviceIdentifier ) ); + return iShDeviceIdentifier; + } + +TBool DISICLTransceiver::DISIDevice::GetDeviceState() + { +// C_TRACE( ( _T( "DISICLTransceiver::DISIDevice::GetDeviceState<>" ) ) ); + return iShLink->StateConnected(); + } + +TBool DISICLTransceiver::DISIDevice::GetDeviceOldState() + { +// C_TRACE( ( _T( "DISICLTransceiver::DISIDevice::GetDeviceOldState<> 0x%x" ), iShOldDeviceConnectedState ) ); + return iShOldDeviceConnectedState; + } + +void DISICLTransceiver::DISIDevice::SetDeviceOldState( + TBool aConnected + ) + { +// C_TRACE( ( _T( "DISICLTransceiver::DISIDevice::SetDeviceOldState<> 0x%x 0x%x" ), iShOldDeviceConnectedState, aConnected ) ); + iShOldDeviceConnectedState = aConnected; + } + +void DISICLTransceiver::DISIDevice::LockDeviceFM( + // None + ) + { + C_TRACE( ( _T( "DISICLTransceiver::DISIDevice::LockDeviceFM<>" ) ) ); + NKern::FMWait( iShDeviceMutex ); + } + +void DISICLTransceiver::DISIDevice::FreeDeviceFM( + // None + ) + { + NKern::FMSignal( iShDeviceMutex ); + C_TRACE( ( _T( "DISICLTransceiver::DISIDevice::FreeDeviceFM<>" ) ) ); + }