/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
#include <kernel.h> // For Kern
#include <pn_const.h> // For PN_OBJ_ROUTING_REQ
#include <phonetisi.h> // For ISI_HEADER_OFFSET_...
#include <commisi.h> // For COMMON_ISA_...
#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 <trxdefs.h> // For ETrxTest...
#include "isicltransceiver.h" // For DISICLTransceiver
#include <nsisi.h> // For PN_NAMESERVICE...
#include "isirouterservice.h" // For DIsiRouterService
#include "isimsgqueue.h" // For DISIMsgQueue
#include "iscnokiadefinitions.h" // For EIscNokiaUsbPhonetLink
#ifdef USE_MEDIAAPI
#include <pn_isimedia_const.h> // 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,
};
// 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>" ) ) );
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>" ) ) );
iShDevices.ResetAndDestroy();
if ( iRouterService )
{
delete iRouterService;
iRouterService = NULL;
}
if ( iShStateChangedDfc )
{
iShStateChangedDfc->Cancel();
delete iShStateChangedDfc;
iShStateChangedDfc = NULL;
}
if( iRxQueue )
{
C_TRACE( ( _T( "DISICLTransceiver::ResetQueues 0x%x iRxQueue 0x%x" ), this, iRxQueue ) );
while( iRxQueue->Count() )
{
MemApi::DeallocBlock( iRxQueue->Get() );
}
}
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<TUint8*>( 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;
}
// This is called in 1...N thread contextes
void DISICLTransceiver::ReceiveISIMessage(
const TDesC8& aMessage,
const TUint8 aTrxId
)
{
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
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<DISICLTransceiver*>( 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
{
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;
}
void DISICLTransceiver::GetDeviceConnectionStates(
RArray<TUint8>& aDeviceIdentifierList,
const TBool aConnectedDevice
)
{
C_TRACE( ( _T( "DISICLTransceiver::GetDeviceConnectionStates 0x%x 0x%x>" ), &aDeviceIdentifierList, aConnectedDevice ) );
const TInt count( iShDevices.Count() );
for( TInt index( 0 ); index < count; index++ )
{
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::GetDeviceConnectionStates 0x%x 0x%x<" ), &aDeviceIdentifierList, aConnectedDevice ) );
}
// KErrBadDescriptor, if message length too small
// KErrUnderFlow, if message length too big.
// KErrCouldNotConnect, if receiver object is out of scope.
TInt DISICLTransceiver::ValidateISIMessage(
TDes8& aMessage
)
{
C_TRACE( ( _T( "DISICLTransceiver::ValidateISIMessage 0x%x>" ), &aMessage ) );
const TUint16 descLength( aMessage.Length() );
TInt msgOk( KErrNone );
msgOk = ( ISI_HEADER_OFFSET_MESSAGEID >= descLength ) ? KErrBadDescriptor : msgOk;
TRACE_ASSERT_INFO( msgOk == KErrNone, msgOk );
// Get ISI message length after known that the descriptor is big enough.
const TUint8* msgPtr( aMessage.Ptr() );
const TUint16 isiMsgLength( GET_LENGTH( msgPtr ) + PN_HEADER_SIZE );
// If the descriptor length is less than ISI message length.
msgOk = ( ( msgOk == KErrNone && isiMsgLength > descLength ) ? KErrUnderflow : msgOk );
TRACE_ASSERT_INFO( msgOk == KErrNone, msgOk );
// If the ISI message length is bigger that the largest supported.
msgOk = ( ( msgOk == KErrNone && isiMsgLength > KMaxISIMsgSize ) ? KErrUnderflow : msgOk );
TRACE_ASSERT_INFO( msgOk == KErrNone, msgOk );
// 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, isiMsgLength );
TRACE_ASSERT_INFO( msgOk == KErrNone, descLength );
C_TRACE( ( _T( "DISICLTransceiver::ValidateISIMessage %d<" ), msgOk ) );
return msgOk;
}
// 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<DISICLTransceiver*>( aPtr );
ASSERT_RESET_ALWAYS( self, ( EISICLTransceiverNULLPtr5 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
self->ReadStateChanges();
C_TRACE( ( _T( "DISICLTransceiver::StateChangedDfc<" ) ) );
}
void DISICLTransceiver::ReadStateChanges(
// None
)
{
C_TRACE( ( _T( "DISICLTransceiver::ReadStateChanges>" ) ) );
const TInt count( iShDevices.Count() );
for( TInt index( 0 ); index < count; index++ )
{
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() )
{
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;
}
default:
{
dynamicDevice = ETrue;
break;
}
}
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<>" ) ) );
}