sl@0: // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of the License "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: //
sl@0: 
sl@0: 
sl@0: #include <e32def.h>
sl@0: #include <e32cmn.h>
sl@0: #include <e32des8.h>
sl@0: #include <e32std.h>
sl@0: 
sl@0: #include "mstypes.h"
sl@0: #include "msctypes.h"
sl@0: #include "mscutils.h"
sl@0: #include "scsimsctypes.h"
sl@0: 
sl@0: #include "tscsiserverreq.h"
sl@0: #include "tscsiservercmds.h"
sl@0: #include "debug.h"
sl@0: #include "msdebug.h"
sl@0: 
sl@0: /**
sl@0: Default constructor for TSenseInfo
sl@0: */
sl@0: TSrvSenseInfo::TSrvSenseInfo()
sl@0:     {
sl@0:     __MSFNLOG
sl@0:     iSenseCode = ENoSense;
sl@0:     iAdditional = 0;
sl@0: 	iQualifier = 0;
sl@0:     }
sl@0: 
sl@0: /**
sl@0: Set sense with no additional info.
sl@0: 
sl@0: @param aSenseCode sense key
sl@0: */
sl@0: void TSrvSenseInfo::SetSense(TSenseCode aSenseCode)
sl@0: 	{
sl@0:     __MSFNLOG
sl@0: 	iSenseCode	= static_cast<TUint8>(aSenseCode);
sl@0: 	iAdditional = 0;
sl@0: 	iQualifier  = 0;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /**
sl@0: Set sense with additional info.
sl@0: 
sl@0: @param aSenseCode sense key
sl@0: @param aAdditional additional sense code (ASC)
sl@0: */
sl@0: void TSrvSenseInfo::SetSense(TSenseCode aSenseCode,
sl@0:                           TAdditionalCode aAdditional)
sl@0: 
sl@0: 	{
sl@0:     __MSFNLOG
sl@0: 	iSenseCode = static_cast<TUint8>(aSenseCode);
sl@0: 	iAdditional = static_cast<TUint8>(aAdditional);
sl@0: 	iQualifier = 0;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /**
sl@0: Set sense with additional info and qualifier.
sl@0: 
sl@0: @param aSenseCode sense key
sl@0: @param aAdditional additional sense code (ASC)
sl@0: @param aQualifier additional sense code qualifier (ASCQ)
sl@0: */
sl@0: void TSrvSenseInfo::SetSense(TSenseCode aSenseCode,
sl@0:                           TAdditionalCode aAdditional,
sl@0:                           TUint8 aQualifier)
sl@0: 	{
sl@0:     __MSFNLOG
sl@0: 	iSenseCode = static_cast<TUint8>(aSenseCode);
sl@0: 	iAdditional = static_cast<TUint8>(aAdditional);
sl@0: 	iQualifier = aQualifier;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: // **** TEST UNIT READY ****
sl@0: // **** REQUEST SENSE ****
sl@0: void TScsiServerRequestSenseResp::Encode(TDes8& aBuffer) const
sl@0:     {
sl@0:     __MSFNSLOG
sl@0:     aBuffer.FillZ(KCommandLength);
sl@0:     __PRINT(_L("->PROTOCOL(SCSI) REQUEST SENSE\n"));
sl@0:     //additional sense length
sl@0: 	aBuffer[07] = static_cast<TUint8>(KCommandLength - 8);
sl@0: 
sl@0:     aBuffer[0] = iResponseCode;
sl@0: 	aBuffer[02] = static_cast<TUint8>(iSensePtr->iSenseCode);
sl@0: 	aBuffer[12] = iSensePtr->iAdditional;
sl@0: 	aBuffer[13] = iSensePtr->iQualifier;
sl@0: 
sl@0:     //truncate to Allocation Length of the Request
sl@0:     TUint length = iAllocationLength < KCommandLength ?
sl@0:                     iAllocationLength : KCommandLength;
sl@0:     aBuffer.SetLength(length);
sl@0:     }
sl@0: 
sl@0: // **** INQUIRY ****
sl@0: void TScsiServerInquiryReq::DecodeL(const TDesC8& aPtr)
sl@0:     {
sl@0:     __MSFNLOG
sl@0: 	TScsiServerReq::DecodeL(aPtr);
sl@0:     iCmdDt = aPtr[1] & 0x2;
sl@0:     iEvpd = aPtr[1] & 0x1;
sl@0:     iPage = aPtr[2];
sl@0:     iAllocationLength = aPtr[4];
sl@0:     __PRINT(_L("<-PROTOCOL(SCSI) INQUIRY\n"));
sl@0:     }
sl@0: 
sl@0: 
sl@0: void TScsiServerInquiryResp::Encode(TDes8& aBuffer) const
sl@0:     {
sl@0:     __MSFNSLOG
sl@0:     __PRINT(_L("->PROTOCOL(SCSI) INQUIRY\n"));
sl@0: 
sl@0: 	aBuffer.FillZ(KResponseLength);
sl@0: 
sl@0:     // MSB: RMB : Removable
sl@0:     if (iRemovable)
sl@0:         {
sl@0:         aBuffer[1] |= 0x80;
sl@0:         }
sl@0: 
sl@0:     // AERC, TrmTsk, NormACA, Response Data Format
sl@0:     aBuffer[3] |= (iResponseDataFormat & 0x0F);
sl@0: 
sl@0:     // Additional Length
sl@0: 	aBuffer[4] = 0x1F;
sl@0: 
sl@0:     // Vendor ID (Vendor Specific/Logged by T10)
sl@0: 	TPtr8 vendorId(&aBuffer[8], 8, 8);
sl@0: 	vendorId.Fill(' ', 8);
sl@0: 	vendorId.Copy(iConfig.iVendorId);
sl@0: 
sl@0:     // Product ID (Vendor Specific)
sl@0:     TPtr8 productId(&aBuffer[16], 16, 16);
sl@0:     productId.Fill(' ', 16);
sl@0:     productId.Copy(iConfig.iProductId);
sl@0: 
sl@0:     // Product Revision Level (Vendor Specific)
sl@0:     TPtr8 productRev(&aBuffer[32], 4, 4);
sl@0:     productRev.Fill(' ', 4);
sl@0:     productRev.Copy(iConfig.iProductRev);
sl@0: 
sl@0:     // Truncate to Allocation Length of the Request
sl@0:     TUint length = iAllocationLength < KResponseLength ?
sl@0:                     iAllocationLength : KResponseLength;
sl@0:     aBuffer.SetLength(length);
sl@0:     }
sl@0: 
sl@0: 
sl@0: // ****	MODE SENSE (6) ****
sl@0: void TScsiServerModeSense6Req::DecodeL(const TDesC8& aPtr)
sl@0:     {
sl@0:     __MSFNLOG
sl@0: 	TScsiServerReq::DecodeL(aPtr);
sl@0:     iPageCode = aPtr[2] & 0x3F;
sl@0:     iPageControl = static_cast<TPageControl>(aPtr[2] >> 6);
sl@0:     iAllocationLength = aPtr[4];
sl@0:     __PRINT(_L("<-PROTOCOL(SCSI) MODE SENSE (6)\n"));
sl@0:     }
sl@0: 
sl@0: 
sl@0: void TScsiServerModeSense6Resp::Encode(TDes8& aBuffer) const
sl@0:     {
sl@0:     __MSFNSLOG
sl@0:     __PRINT(_L("->PROTOCOL(SCSI) MODE SENSE (6)\n"));
sl@0:     // reserve 4 bytes for Length, Media type, Device-specific parameter and
sl@0:     // Block descriptor length
sl@0:     aBuffer.FillZ(KCommandLength);
sl@0: 
sl@0:     // Mode Parameter List
sl@0:     // SPC-3 7.4.2
sl@0:     // - Mode Parameter Header
sl@0:     // - Block Descriptor(s)
sl@0:     // - Mode Page(s)
sl@0: 
sl@0:     // Mode Parameter Header
sl@0:     // SPC-3 7.4.3
sl@0:     // [0] Mode Data Length
sl@0:     // [1] Medium Type
sl@0:     // [2] Device-Specific Paramater
sl@0:     // [3] Block Descriptor Length
sl@0: 
sl@0:     // [0] Mode Date Length
sl@0:     // Sending only Mode parameter header
sl@0:     aBuffer[0] = 3;
sl@0: 
sl@0:     // [1] Medium Type
sl@0:     // 0x00 for SBC
sl@0: 
sl@0:     // [2] Device specific parameter
sl@0:     // SBC-3 6.3.1
sl@0:     // set SWP bit at the Device Specific parameters
sl@0:     if (iWp)
sl@0:         {
sl@0:         aBuffer[2] |= 0x80;
sl@0:         }
sl@0: 
sl@0:     // [3] Block Descriptor Length
sl@0:     // 0x00 for no descriptors
sl@0: 
sl@0:     // No Block Descriptors
sl@0: 
sl@0:     // No Mode Pages
sl@0: 
sl@0:     // Truncate to Allocation Length of the Request
sl@0:     TUint length = iAllocationLength < KCommandLength ?
sl@0:                     iAllocationLength : KCommandLength;
sl@0:     aBuffer.SetLength(length);
sl@0:     }
sl@0: 
sl@0: // ****	START STOP UNIT ****
sl@0: void TScsiServerStartStopUnitReq::DecodeL(const TDesC8& aPtr)
sl@0:     {
sl@0:     __MSFNLOG
sl@0: 	TScsiServerReq::DecodeL(aPtr);
sl@0: 
sl@0:     const TUint8 KStartMask = 0x01;
sl@0:     const TUint8 KImmedMask = 0x01;
sl@0:     const TUint8 KLoejMask = 0x02;
sl@0: 
sl@0:     iImmed = aPtr[1] & KImmedMask ? ETrue : EFalse;
sl@0:     iStart = aPtr[4] & KStartMask ? ETrue : EFalse;
sl@0:     iLoej = aPtr[4] & KLoejMask ? ETrue : EFalse;
sl@0: 
sl@0:     __PRINT2(_L("<-PROTOCOL(SCSI) START STOP UNIT Data %X %X\n"), aPtr[1], aPtr[4]);
sl@0:     __PRINT1(_L("IMMED = %d\n"), iImmed);
sl@0:     __PRINT1(_L("START = %d\n"), iStart);
sl@0:     __PRINT1(_L("LOEJ = %d\n"), iLoej);
sl@0:     }
sl@0: 
sl@0: 
sl@0: // ****	PREVENT MEDIA REMOVAL ****
sl@0: void TScsiServerPreventMediaRemovalReq::DecodeL(const TDesC8& aPtr)
sl@0:     {
sl@0:     __MSFNLOG
sl@0: 	TScsiServerReq::DecodeL(aPtr);
sl@0: 	iPrevent = aPtr[4] & 0x01;
sl@0: 	__PRINT1(_L("<-PROTOCOL(SCSI) PREVENT MEDIA REMOVAL prevent = %d\n"), iPrevent);
sl@0:     }
sl@0: 
sl@0: 
sl@0: // ****	READ FORMAT CAPACITIES ****
sl@0: void TScsiServerReadFormatCapacitiesReq::DecodeL(const TDesC8& aPtr)
sl@0:     {
sl@0:     __MSFNLOG
sl@0: 	TScsiServerReq::DecodeL(aPtr);
sl@0:     const TUint8* ptr = aPtr.Ptr();
sl@0:     iAllocationLength = BigEndian::Get32(ptr+7);
sl@0: 	__PRINT(_L("<-PROTOCOL(SCSI) READ FORMAT CAPACITIES\n"));
sl@0:     }
sl@0: 
sl@0: 
sl@0: void TScsiServerReadFormatCapacitiesResp::Encode(TDes8& aBuffer) const
sl@0:     {
sl@0:     __MSFNSLOG
sl@0: 	__PRINT(_L("->PROTOCOL(SCSI) READ FORMAT CAPACITIES\n"));
sl@0: 	aBuffer.FillZ(KResponseLength);
sl@0: 	aBuffer[3] = 0x08;	// Capacity List Length
sl@0: 
sl@0: 	aBuffer[4] = static_cast<TUint8>(iNumberBlocks >> 24);	// Number of blocks
sl@0: 	aBuffer[5] = static_cast<TUint8>(iNumberBlocks >> 16);	//
sl@0: 	aBuffer[6] = static_cast<TUint8>(iNumberBlocks >> 8);	//
sl@0: 	aBuffer[7] = static_cast<TUint8>(iNumberBlocks);		//
sl@0: 
sl@0: 	aBuffer[8] = 0x02;	// Formatted size
sl@0: 
sl@0: 	aBuffer[9]  = 0x00;	// 512 Byte Blocks
sl@0: 	aBuffer[10] = 0x02;	//
sl@0: 	aBuffer[11] = 0x00;	//
sl@0: 
sl@0:     // Truncate to Allocation Length of the Request
sl@0:     // Truncate to Allocation Length of the Request
sl@0:     TUint length = iAllocationLength < KResponseLength ?
sl@0:                     iAllocationLength : KResponseLength;
sl@0:     aBuffer.SetLength(length);
sl@0:     }
sl@0: 
sl@0: 
sl@0: // ****	READ CAPACITY (10) ****
sl@0: void TScsiServerReadCapacity10Req::DecodeL(const TDesC8& aPtr)
sl@0:     {
sl@0:     __MSFNLOG
sl@0: 	TScsiServerReq::DecodeL(aPtr);
sl@0:     iPmi = aPtr[8] & 0x01;
sl@0:     const TUint8* ptr = aPtr.Ptr();
sl@0: 	iLogicalBlockAddress = BigEndian::Get32(ptr+2);
sl@0:     __PRINT(_L("<-PROTOCOL(SCSI) READ CAPACITY (10)\n"));
sl@0:     }
sl@0: 
sl@0: 
sl@0: void TScsiServerReadCapacity10Resp::Encode(TDes8& aBuffer) const
sl@0:     {
sl@0:     __MSFNSLOG
sl@0:     aBuffer.FillZ(KCommandLength);
sl@0: 
sl@0:     __PRINT3(_L("->PROTOCOL(SCSI) READ CAPACITY (10) Block size=0x%X, NumBlocks=0x%08X%08X\n"),
sl@0:              iBlockSize,
sl@0:              I64HIGH(iNumberBlocks),
sl@0:              I64LOW(iNumberBlocks));
sl@0: 
sl@0:     if (I64HIGH(iNumberBlocks) == 0)
sl@0:         {
sl@0:         TUint32 numBlocks = I64LOW(iNumberBlocks);
sl@0: 
sl@0:         // Number of blocks
sl@0:         aBuffer[0] = static_cast<TUint8>(numBlocks >> 24);
sl@0:         aBuffer[1] = static_cast<TUint8>(numBlocks >> 16);
sl@0:         aBuffer[2] = static_cast<TUint8>(numBlocks >> 8);
sl@0:         aBuffer[3] = static_cast<TUint8>(numBlocks);
sl@0:         }
sl@0:     else
sl@0:         {
sl@0:         // indicate that size more then )0xFFFFFFFF
sl@0:         aBuffer[0] = aBuffer[1] = aBuffer[2] = aBuffer[3] = 0xFF;
sl@0:         }
sl@0: 
sl@0: 	// Block Size
sl@0:     aBuffer[4] = static_cast<TUint8>(iBlockSize >> 24);
sl@0:     aBuffer[5] = static_cast<TUint8>(iBlockSize >> 16);
sl@0:     aBuffer[6] = static_cast<TUint8>(iBlockSize >> 8);
sl@0:     aBuffer[7] = static_cast<TUint8>(iBlockSize);
sl@0:     }
sl@0: 
sl@0: 
sl@0: // ****	RdWr10 ****
sl@0: void TScsiServerRdWr10Req::DecodeL(const TDesC8& aDes)
sl@0: {
sl@0:     __MSFNLOG
sl@0: 	TScsiServerReq::DecodeL(aDes);
sl@0: 
sl@0:     // PROTECT
sl@0: 	iProtect = aDes[1] >> 5;
sl@0: 
sl@0:     const TUint8* ptr = aDes.Ptr();
sl@0:     // LOGICAL BLOCK ADDRESS
sl@0: 	iLogicalBlockAddress = BigEndian::Get32(ptr+2);
sl@0:     // TRANSFER LENGTH
sl@0: 	iTransferLength = BigEndian::Get16(ptr+7);
sl@0: 
sl@0: 	__PRINT2(_L("<-PROTOCOL(SCSI) RD/WR (10) : LBA = %x, Length = %x  (blocks)\n"),
sl@0:              iLogicalBlockAddress, iTransferLength);
sl@0: }
sl@0: 
sl@0: 
sl@0: // ****	READ (10) ****
sl@0: // ****	WRITE (10) ****
sl@0: // ****	VERIFY (10) ****
sl@0: void TScsiServerVerify10Req::DecodeL(const TDesC8& aPtr)
sl@0:     {
sl@0:     __MSFNLOG
sl@0: 	TScsiServerRdWr10Req::DecodeL(aPtr);
sl@0: 	iBytchk = aPtr[1] & 0x02 ? ETrue : EFalse;
sl@0:     }