diff -r f5050f1da672 -r 04becd199f91 javaextensions/satsa/apdu/src.s60/cstsuri.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaextensions/satsa/apdu/src.s60/cstsuri.cpp Tue Apr 27 16:30:29 2010 +0300 @@ -0,0 +1,388 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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 FILES +#include "cstsuri.h" +#include "stsapduconstants.h" +#include "logger.h" + +namespace java +{ +namespace satsa +{ + +// CONSTANTS +const TInt KSTSAIDMaxLength = 16; +const TInt KSTSAIDMinLength = 5; + +const TInt KSTSMinURILength = 15;//(SAT uri without slot number) +const TInt KSTSMaxURILength = 61;//(AID uri with slot and maximum AID) + +const TUint8 KSTSErrNotAHexNumber = 255; + +const TInt KSTSApduUriPrefixLength = 5; // "apdu:" takes 5 characters + +const TUint8 KSTSApduUriSlotTargetSeparator = ';'; +const TUint8 KSTSApduUriAIDSeparator = '.'; +const TUint8 KSTSSmallA = 'a'; +const TUint8 KSTSBigA = 'A'; +const TInt KSTSValueOfHexA = 0x0A; +const TInt KSTSMaxHexValue = 0x0F; +const TInt KSTSLengthOfSingleHexDigitInBits = 4; + +_LIT(KSTSUriTargetPrefix, "target="); +_LIT(KSTSUriTargetSAT, "SAT"); + +// ============================ MEMBER FUNCTIONS =============================== + + +CSTSURI::CSTSURI() +{ +} + +void CSTSURI::ConstructL(const TDesC& aURIString) +{ + LOG(ESATSA, EInfo, "CSTSURI::ConstructL++"); + // does URI conform to the BNF syntax + if (!CheckURIL(aURIString)) + { + ELOG(ESATSA, "CSTSURI::ConstructL: URI does not conform to BNF sntax"); + // IllegalArgumentException + User::Leave(KSTSErrIllegalArgument + KSTSErrIAInvalidParam); + } +} + +CSTSURI* CSTSURI::NewLC(const TDesC& aURIString) +{ + LOG(ESATSA, EInfo, "CSTSURI::NewLC++"); + CSTSURI* self = new(ELeave) CSTSURI(); + CleanupStack::PushL(self); + self->ConstructL(aURIString); + LOG(ESATSA, EInfo, "CSTSURI::NewLC---"); + return self; +} + +CSTSURI::~CSTSURI() +{ + delete iAID; +} + +// ----------------------------------------------------------------------------- +// CSTSURI::AID +// Getter for AID value +// ----------------------------------------------------------------------------- +const TDesC8& CSTSURI::AID() const +{ + return *iAID; +} + +// ----------------------------------------------------------------------------- +// CSTSURI::Slot +// Getter for Slot +// ----------------------------------------------------------------------------- +TUint8 CSTSURI::Slot() const +{ + return iSlot; +} + +// ----------------------------------------------------------------------------- +// CSTSURI::Type +// Getter for URI type +// ----------------------------------------------------------------------------- +CSTSURI::TURIType CSTSURI::Type() const +{ + return iURIType; +} + +// ----------------------------------------------------------------------------- +// CSTSURI::CheckURIL +// Checks uri and saves needed information to member variables +// +/* + URI can be for example: "apdu:0;target=A0.0.0.67.4.7.1F.3.2C.3" + or "apdu:0;target=SAT" + + ::= "apdu:" + ::= [slot];target + ::= smart card slot number. (optional. Hexadecimal + number identifying the smart card slot. Default + slot assumed if left empty) + ::= "target="|"SAT" + ::= < 5 - 16 bytes > + An AID (Application Identifier) uniquely + identifies a smart card application. It is + represented by 5 to 16 hexadecimal bytes where + each byte value is seperated by a ".". + */ +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CSTSURI::CheckURIL(const TDesC& aURI) +{ + LOG(ESATSA, EInfo, "CSTSURI::CheckURIL"); + const TInt uriLength = aURI.Length(); + LOG1(ESATSA, EInfo, "CSTSURI::CheckURIL:The lenghth of URI is %d", uriLength); + // check length + if ((uriLength > KSTSMaxURILength) || (uriLength < KSTSMinURILength)) + { + ELOG(ESATSA, "CSTSURI::CheckURIL:wrong length of the URI"); + return EFalse; + } + // uri is now between 15 and 61 characters + // Connector has already parsed the scheme part of the uri, + // so we don't need to + + // "apdu:" takes 5 first characters + TInt pos = KSTSApduUriPrefixLength; + + // parse slot number + TChar slotChar = aURI[pos++]; + TUint8 slotInt = 0; + //if slot number is gived + if (slotChar != KSTSApduUriSlotTargetSeparator) + { + //create ptr which starts from slot number position + TPtrC16 slotAndRest(aURI.Ptr() + KSTSApduUriPrefixLength, uriLength + - KSTSApduUriPrefixLength); + TLex slotLex(slotAndRest); + TInt slotNumber; + //parse slot number + TInt err = slotLex.Val(slotNumber); + if (err != KErrNone) + { + return EFalse; + } + + slotInt = static_cast(slotNumber); + + //calculate amount of slot number digits + HBufC8* slotBuf = HBufC8::NewL(KSTSMaxURILength); + slotBuf->Des().AppendNum(slotNumber); + TInt slotNumberLength = slotBuf->Des().Length(); + delete slotBuf; + + //if digits of slotnumber are more that one + slotChar = aURI[pos + (slotNumberLength - 1)]; + pos += slotNumberLength; + } + + if (slotChar != KSTSApduUriSlotTargetSeparator) + { + return EFalse; + } + + // next should be "target=" + if (aURI.Find(KSTSUriTargetPrefix()) != pos) + { + return EFalse; + } + pos += KSTSUriTargetPrefix().Length(); + + TURIType uriType = EAID; + TBufC8 aid; + + if (aURI.Find(KSTSUriTargetSAT()) == pos) + { + if (uriLength != (pos + KSTSUriTargetSAT().Length())) + { + return EFalse; + } + uriType = ESAT; + } + else + { + TPtr8 aidDes = aid.Des(); + if (!ParseAID(aURI, pos, aidDes)) + { + return EFalse; + } + } + + iSlot = slotInt; + iURIType = uriType; + + //copies data to the member buffer + iAID = aid.AllocL(); + LOG(ESATSA, EInfo, "CSTSURI::CheckURIL---"); + return ETrue; +} + +// ----------------------------------------------------------------------------- +// CSTSURI::GetHexValue +// returns an integer value of given hex character +// ----------------------------------------------------------------------------- +// +TUint8 CSTSURI::GetHexValue(const TChar& aDigit) +{ + // if aDigit is 0-9, we can use TChar::GetNumericValue directly + if (aDigit.IsDigit()) + { + return static_cast(aDigit.GetNumericValue()); + } + + // if aDigit is not a hexadecimal digit, it is an error + if (!(aDigit.IsHexDigit())) + { + return KSTSErrNotAHexNumber; + } + + // otherwise, aDigit is a-f or A-F + TChar charA = KSTSSmallA; + if (aDigit.IsUpper()) + { + charA = KSTSBigA; + } + + // we can get the value by calculating the difference of the character + // and character 'a', and adding the value of hex digit 'a'. + TUint8 retVal = static_cast((aDigit - charA) + KSTSValueOfHexA); + return retVal; +} + +// ----------------------------------------------------------------------------- +// CSTSURI::ParseAID +// parses AID from URI +// ----------------------------------------------------------------------------- +// +TBool CSTSURI::ParseAID(const TDesC& aURI, TInt aPos, TDes8& aAID) +{ + TInt aidLength = aAID.Length(); + TInt aidMaxLength = aAID.MaxLength(); + TInt uriLength = aURI.Length(); + TInt pos = aPos; + TAidParserState aidState = EFirstDigit; + TUint8 aidDigit = 0; + while (pos < uriLength) + { + TChar digit = aURI[pos++]; + ParseAIDCharacter(digit, aidState, aidDigit); + switch (aidState) + { + case EFirstDigit: + { + if (++aidLength > aidMaxLength) + { + return EFalse; + } + aAID.Append(aidDigit); + break; + } + case EERROR: + { + return EFalse; + } + default: + { + // other states don't require action + } + } + } + if (aidState == ESecondDigit) + { + // the uri ended after first digit, which is not yet added + if (++aidLength > aidMaxLength) + { + return EFalse; + } + aAID.Append(aidDigit); + } + if (aidState == EFirstDigit) + { + // AID ended with a dot + return EFalse; + } + + if (aidState == EDot) + { + // Append also last digit + aAID.Append(aidDigit); + } + + if (aidLength < KSTSAIDMinLength) + { + return EFalse; + } + return ETrue; +} + +// ----------------------------------------------------------------------------- +// CSTSURI::ParseAIDCharacter +// Implements AID parsing state machine +// ----------------------------------------------------------------------------- +void CSTSURI::ParseAIDCharacter(const TChar& aDigit, TAidParserState& aState, + TUint8& aAIDDigit) +{ + switch (aState) + { + case EFirstDigit: + { + aAIDDigit = GetHexValue(aDigit); + if (aAIDDigit > KSTSMaxHexValue) + { + aState = EERROR; + } + else + { + aState = ESecondDigit; + } + break; + } + case ESecondDigit: + { + if (aDigit != KSTSApduUriAIDSeparator) + { + TUint8 secondDigit = GetHexValue(aDigit); + if (secondDigit > KSTSMaxHexValue) + { + aState = EERROR; + } + else + { + aAIDDigit <<= KSTSLengthOfSingleHexDigitInBits; + aAIDDigit |= secondDigit; + aState = EDot; + } + } + else + { + aState = EFirstDigit; + } + break; + } + case EDot: + { + if (aDigit != KSTSApduUriAIDSeparator) + { + aState = EERROR; + } + else + { + aState = EFirstDigit; + } + break; + } + default: + { + + } + } +} + +} // namespace satsa +} // namespace java +// End of File