diff -r 000000000000 -r 63b37f68c1ce connectivitylayer/isce/isirouter_dll/src/isicltransceiver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/connectivitylayer/isce/isirouter_dll/src/isicltransceiver.cpp Fri Nov 06 17:28:23 2009 +0000 @@ -0,0 +1,231 @@ +/* +* 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 // 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 + + +#define PN_MEDIA_TEST 0xBB //not real +#define PN_DEV_MODEM 0x12 +#define PN_DEV_DUMMYIST 0x13 +#define PN_DEV_APE 0x14 + +// Faults +enum TISICLTransceiverFaults + { + EISICLTransceiverMemAllocFailure = 0x01, + EISICLTransceiverMemAllocFailure1, + EISICLTransceiverNotSupportedMedia, + EISICLTransceiverOverTheLimits, + EISICLTransceiverNULLPtr, + EISICLTransceiverNotSupportedDevice, + }; + +DISICLTransceiver::DISICLTransceiver( DISIRouter* aPtr ) + : iRouter( aPtr ) + { + 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 ); + C_TRACE( ( _T( "DISICLTransceiver::DISICLTransceiver<" ) ) ); + } + +DISICLTransceiver::~DISICLTransceiver() + { + C_TRACE( ( _T( "DISICLTransceiver::~DISICLTransceiver>" ) ) ); + for( TUint8 i( 0 ); i < EISIAmountOfMedias; i++ ) + { + MISIRouterLinkIf* tmp = iLinksArray[ i ]; + if( tmp ) + { + tmp->Release(); + tmp = NULL; + iLinksArray[ i ] = NULL; + } + } + delete []iLinksArray; + C_TRACE( ( _T( "DISICLTransceiver::~DISICLTransceiver<" ) ) ); + } + +void DISICLTransceiver::SendCommIsaEntityNotReachableResp( TDes8& aMessage ) + { + C_TRACE( ( _T( "DISICLTransceiver::SendCommIsaEntityNotReachableResp 0x%x>" ), &aMessage ) ); + const TUint8* msgTmpPtr( aMessage.Ptr() ); + // 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 ) + { + // 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 ); + RouteISIMessage( tempPtr ); + } + else + { + C_TRACE( ( _T( "DISICLTransceiver Not sending another CommIsaEntityNotReachableResp" ) ) ); + } + C_TRACE( ( _T( "DISICLTransceiver::SendCommIsaEntityNotReachableResp 0x%x<" ), &aMessage ) ); + } + +void DISICLTransceiver::RouteISIMessage( TDes8& aMessage ) + { + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage 0x%x>" ), &aMessage ) ); + TInt error( ValidateISIMessage( aMessage ) ); //TODO what to do with error? + TBool sendOk( EFalse ); + TUint8* messageBlockPtr( const_cast( aMessage.Ptr() ) ); + switch( messageBlockPtr[ ISI_HEADER_OFFSET_RECEIVERDEVICE ] ) + { + case PN_DEV_APE: + { + C_TRACE( ( _T( "DISIRouter msg to PN_DEV_APE" ) ) ); + if( messageBlockPtr[ ISI_HEADER_OFFSET_RECEIVEROBJECT ] == PN_OBJ_ROUTING_REQ ) + { + //route with resource and nameservice + } + else{ + sendOk = iRouter->Receive( aMessage, messageBlockPtr[ ISI_HEADER_OFFSET_RECEIVEROBJECT ] ); + C_TRACE( ( _T( "DISIRouter router sendOk %d" ), sendOk ) ); + } + break; + } + default: + { + C_TRACE( ( _T( "DISIRouter msg to other device" ) ) ); + TUint8 linkId = MapDeviceToMedia( messageBlockPtr[ ISI_HEADER_OFFSET_RECEIVERDEVICE ] ); + 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 ) ); + break; + } + } + if( !sendOk ) + { + SendCommIsaEntityNotReachableResp( aMessage ); + MemApi::DeallocBlock( aMessage ); + } + C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage 0x%x<" ), &aMessage ) ); + } + +// 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, 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 + ) + { + C_TRACE( ( _T( "DISICLTransceiver::MapDeviceToMedia aDevice %d>" ), aDevice ) ); + TUint8 media( KErrNone ); + switch( aDevice ) + { + case PN_DEV_MODEM: + { + media = EISIMediaSharedMemory; + break; + } + case PN_DEV_DUMMYIST: + { + media = EISIMediaTest; + break; + } + // Not supported device + default: + { + ASSERT_RESET_ALWAYS( 0, ( EISICLTransceiverNotSupportedDevice | EDISICLTransceiverTraceId << KClassIdentifierShift ) ); + break; + } + } + C_TRACE( ( _T( "DISICLTransceiver::MapDeviceToMedia media %d<" ), media ) ); + return media; + } +