javaextensions/satsa/apdu/src.s60/cstsuri.cpp
branchRCL_3
changeset 14 04becd199f91
equal deleted inserted replaced
13:f5050f1da672 14:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "cstsuri.h"
       
    21 #include "stsapduconstants.h"
       
    22 #include "logger.h"
       
    23 
       
    24 namespace java
       
    25 {
       
    26 namespace satsa
       
    27 {
       
    28 
       
    29 // CONSTANTS
       
    30 const TInt KSTSAIDMaxLength = 16;
       
    31 const TInt KSTSAIDMinLength = 5;
       
    32 
       
    33 const TInt KSTSMinURILength = 15;//(SAT uri without slot number)
       
    34 const TInt KSTSMaxURILength = 61;//(AID uri with slot and maximum AID)
       
    35 
       
    36 const TUint8 KSTSErrNotAHexNumber = 255;
       
    37 
       
    38 const TInt KSTSApduUriPrefixLength = 5; // "apdu:" takes 5 characters
       
    39 
       
    40 const TUint8 KSTSApduUriSlotTargetSeparator = ';';
       
    41 const TUint8 KSTSApduUriAIDSeparator = '.';
       
    42 const TUint8 KSTSSmallA = 'a';
       
    43 const TUint8 KSTSBigA = 'A';
       
    44 const TInt KSTSValueOfHexA = 0x0A;
       
    45 const TInt KSTSMaxHexValue = 0x0F;
       
    46 const TInt KSTSLengthOfSingleHexDigitInBits = 4;
       
    47 
       
    48 _LIT(KSTSUriTargetPrefix, "target=");
       
    49 _LIT(KSTSUriTargetSAT, "SAT");
       
    50 
       
    51 // ============================ MEMBER FUNCTIONS ===============================
       
    52 
       
    53 
       
    54 CSTSURI::CSTSURI()
       
    55 {
       
    56 }
       
    57 
       
    58 void CSTSURI::ConstructL(const TDesC& aURIString)
       
    59 {
       
    60     LOG(ESATSA, EInfo, "CSTSURI::ConstructL++");
       
    61     // does URI conform to the BNF syntax
       
    62     if (!CheckURIL(aURIString))
       
    63     {
       
    64         ELOG(ESATSA, "CSTSURI::ConstructL: URI does not conform to BNF sntax");
       
    65         // IllegalArgumentException
       
    66         User::Leave(KSTSErrIllegalArgument + KSTSErrIAInvalidParam);
       
    67     }
       
    68 }
       
    69 
       
    70 CSTSURI* CSTSURI::NewLC(const TDesC& aURIString)
       
    71 {
       
    72     LOG(ESATSA, EInfo, "CSTSURI::NewLC++");
       
    73     CSTSURI* self = new(ELeave) CSTSURI();
       
    74     CleanupStack::PushL(self);
       
    75     self->ConstructL(aURIString);
       
    76     LOG(ESATSA, EInfo, "CSTSURI::NewLC---");
       
    77     return self;
       
    78 }
       
    79 
       
    80 CSTSURI::~CSTSURI()
       
    81 {
       
    82     delete iAID;
       
    83 }
       
    84 
       
    85 // -----------------------------------------------------------------------------
       
    86 // CSTSURI::AID
       
    87 // Getter for AID value
       
    88 // -----------------------------------------------------------------------------
       
    89 const TDesC8& CSTSURI::AID() const
       
    90 {
       
    91     return *iAID;
       
    92 }
       
    93 
       
    94 // -----------------------------------------------------------------------------
       
    95 // CSTSURI::Slot
       
    96 // Getter for Slot
       
    97 // -----------------------------------------------------------------------------
       
    98 TUint8 CSTSURI::Slot() const
       
    99 {
       
   100     return iSlot;
       
   101 }
       
   102 
       
   103 // -----------------------------------------------------------------------------
       
   104 // CSTSURI::Type
       
   105 // Getter for URI type
       
   106 // -----------------------------------------------------------------------------
       
   107 CSTSURI::TURIType CSTSURI::Type() const
       
   108 {
       
   109     return iURIType;
       
   110 }
       
   111 
       
   112 // -----------------------------------------------------------------------------
       
   113 // CSTSURI::CheckURIL
       
   114 // Checks uri and saves needed information to member variables
       
   115 //
       
   116 /*
       
   117  URI can be for example: "apdu:0;target=A0.0.0.67.4.7.1F.3.2C.3"
       
   118  or                     "apdu:0;target=SAT"
       
   119 
       
   120  <APDU_connection_string>::= "apdu:"<targetAddress>
       
   121  <targetAddress>            ::= [slot];target
       
   122  <slot>                 ::= smart card slot number. (optional. Hexadecimal
       
   123  number identifying the smart card slot. Default
       
   124  slot assumed if left empty)
       
   125  <target>               ::= "target="<AID>|"SAT"
       
   126  <AID>                  ::= < 5 - 16 bytes >
       
   127  An AID (Application Identifier) uniquely
       
   128  identifies a smart card application. It is
       
   129  represented by 5 to 16 hexadecimal bytes where
       
   130  each byte value is seperated by a ".".
       
   131  */
       
   132 // (other items were commented in a header).
       
   133 // -----------------------------------------------------------------------------
       
   134 //
       
   135 TBool CSTSURI::CheckURIL(const TDesC& aURI)
       
   136 {
       
   137     LOG(ESATSA, EInfo, "CSTSURI::CheckURIL");
       
   138     const TInt uriLength = aURI.Length();
       
   139     LOG1(ESATSA, EInfo, "CSTSURI::CheckURIL:The lenghth of URI is %d", uriLength);
       
   140     // check length
       
   141     if ((uriLength > KSTSMaxURILength) || (uriLength < KSTSMinURILength))
       
   142     {
       
   143         ELOG(ESATSA, "CSTSURI::CheckURIL:wrong length of the URI");
       
   144         return EFalse;
       
   145     }
       
   146     // uri is now between 15 and 61 characters
       
   147     // Connector has already parsed the scheme part of the uri,
       
   148     // so we don't need to
       
   149 
       
   150     // "apdu:" takes 5 first characters
       
   151     TInt pos = KSTSApduUriPrefixLength;
       
   152 
       
   153     // parse slot number
       
   154     TChar slotChar = aURI[pos++];
       
   155     TUint8 slotInt = 0;
       
   156     //if slot number is gived
       
   157     if (slotChar != KSTSApduUriSlotTargetSeparator)
       
   158     {
       
   159         //create ptr which starts from slot number position
       
   160         TPtrC16 slotAndRest(aURI.Ptr() + KSTSApduUriPrefixLength, uriLength
       
   161                             - KSTSApduUriPrefixLength);
       
   162         TLex slotLex(slotAndRest);
       
   163         TInt slotNumber;
       
   164         //parse slot number
       
   165         TInt err = slotLex.Val(slotNumber);
       
   166         if (err != KErrNone)
       
   167         {
       
   168             return EFalse;
       
   169         }
       
   170 
       
   171         slotInt = static_cast<TUint8>(slotNumber);
       
   172 
       
   173         //calculate amount of slot number digits
       
   174         HBufC8* slotBuf = HBufC8::NewL(KSTSMaxURILength);
       
   175         slotBuf->Des().AppendNum(slotNumber);
       
   176         TInt slotNumberLength = slotBuf->Des().Length();
       
   177         delete slotBuf;
       
   178 
       
   179         //if digits of slotnumber are more that one
       
   180         slotChar = aURI[pos + (slotNumberLength - 1)];
       
   181         pos += slotNumberLength;
       
   182     }
       
   183 
       
   184     if (slotChar != KSTSApduUriSlotTargetSeparator)
       
   185     {
       
   186         return EFalse;
       
   187     }
       
   188 
       
   189     // next should be "target="
       
   190     if (aURI.Find(KSTSUriTargetPrefix()) != pos)
       
   191     {
       
   192         return EFalse;
       
   193     }
       
   194     pos += KSTSUriTargetPrefix().Length();
       
   195 
       
   196     TURIType uriType = EAID;
       
   197     TBufC8<KSTSAIDMaxLength> aid;
       
   198 
       
   199     if (aURI.Find(KSTSUriTargetSAT()) == pos)
       
   200     {
       
   201         if (uriLength != (pos + KSTSUriTargetSAT().Length()))
       
   202         {
       
   203             return EFalse;
       
   204         }
       
   205         uriType = ESAT;
       
   206     }
       
   207     else
       
   208     {
       
   209         TPtr8 aidDes = aid.Des();
       
   210         if (!ParseAID(aURI, pos, aidDes))
       
   211         {
       
   212             return EFalse;
       
   213         }
       
   214     }
       
   215 
       
   216     iSlot = slotInt;
       
   217     iURIType = uriType;
       
   218 
       
   219     //copies data to the member buffer
       
   220     iAID = aid.AllocL();
       
   221     LOG(ESATSA, EInfo, "CSTSURI::CheckURIL---");
       
   222     return ETrue;
       
   223 }
       
   224 
       
   225 // -----------------------------------------------------------------------------
       
   226 // CSTSURI::GetHexValue
       
   227 // returns an integer value of given hex character
       
   228 // -----------------------------------------------------------------------------
       
   229 //
       
   230 TUint8 CSTSURI::GetHexValue(const TChar& aDigit)
       
   231 {
       
   232     // if aDigit is 0-9, we can use TChar::GetNumericValue directly
       
   233     if (aDigit.IsDigit())
       
   234     {
       
   235         return static_cast<TUint8>(aDigit.GetNumericValue());
       
   236     }
       
   237 
       
   238     // if aDigit is not a hexadecimal digit, it is an error
       
   239     if (!(aDigit.IsHexDigit()))
       
   240     {
       
   241         return KSTSErrNotAHexNumber;
       
   242     }
       
   243 
       
   244     // otherwise, aDigit is a-f or A-F
       
   245     TChar charA = KSTSSmallA;
       
   246     if (aDigit.IsUpper())
       
   247     {
       
   248         charA = KSTSBigA;
       
   249     }
       
   250 
       
   251     // we can get the value by calculating the difference of the character
       
   252     // and character 'a', and adding the value of hex digit 'a'.
       
   253     TUint8 retVal = static_cast<TUint8>((aDigit - charA) + KSTSValueOfHexA);
       
   254     return retVal;
       
   255 }
       
   256 
       
   257 // -----------------------------------------------------------------------------
       
   258 // CSTSURI::ParseAID
       
   259 // parses AID from URI
       
   260 // -----------------------------------------------------------------------------
       
   261 //
       
   262 TBool CSTSURI::ParseAID(const TDesC& aURI, TInt aPos, TDes8& aAID)
       
   263 {
       
   264     TInt aidLength = aAID.Length();
       
   265     TInt aidMaxLength = aAID.MaxLength();
       
   266     TInt uriLength = aURI.Length();
       
   267     TInt pos = aPos;
       
   268     TAidParserState aidState = EFirstDigit;
       
   269     TUint8 aidDigit = 0;
       
   270     while (pos < uriLength)
       
   271     {
       
   272         TChar digit = aURI[pos++];
       
   273         ParseAIDCharacter(digit, aidState, aidDigit);
       
   274         switch (aidState)
       
   275         {
       
   276         case EFirstDigit:
       
   277         {
       
   278             if (++aidLength > aidMaxLength)
       
   279             {
       
   280                 return EFalse;
       
   281             }
       
   282             aAID.Append(aidDigit);
       
   283             break;
       
   284         }
       
   285         case EERROR:
       
   286         {
       
   287             return EFalse;
       
   288         }
       
   289         default:
       
   290         {
       
   291             // other states don't require action
       
   292         }
       
   293         }
       
   294     }
       
   295     if (aidState == ESecondDigit)
       
   296     {
       
   297         // the uri ended after first digit, which is not yet added
       
   298         if (++aidLength > aidMaxLength)
       
   299         {
       
   300             return EFalse;
       
   301         }
       
   302         aAID.Append(aidDigit);
       
   303     }
       
   304     if (aidState == EFirstDigit)
       
   305     {
       
   306         // AID ended with a dot
       
   307         return EFalse;
       
   308     }
       
   309 
       
   310     if (aidState == EDot)
       
   311     {
       
   312         // Append also last digit
       
   313         aAID.Append(aidDigit);
       
   314     }
       
   315 
       
   316     if (aidLength < KSTSAIDMinLength)
       
   317     {
       
   318         return EFalse;
       
   319     }
       
   320     return ETrue;
       
   321 }
       
   322 
       
   323 // -----------------------------------------------------------------------------
       
   324 // CSTSURI::ParseAIDCharacter
       
   325 // Implements AID parsing state machine
       
   326 // -----------------------------------------------------------------------------
       
   327 void CSTSURI::ParseAIDCharacter(const TChar& aDigit, TAidParserState& aState,
       
   328                                 TUint8& aAIDDigit)
       
   329 {
       
   330     switch (aState)
       
   331     {
       
   332     case EFirstDigit:
       
   333     {
       
   334         aAIDDigit = GetHexValue(aDigit);
       
   335         if (aAIDDigit > KSTSMaxHexValue)
       
   336         {
       
   337             aState = EERROR;
       
   338         }
       
   339         else
       
   340         {
       
   341             aState = ESecondDigit;
       
   342         }
       
   343         break;
       
   344     }
       
   345     case ESecondDigit:
       
   346     {
       
   347         if (aDigit != KSTSApduUriAIDSeparator)
       
   348         {
       
   349             TUint8 secondDigit = GetHexValue(aDigit);
       
   350             if (secondDigit > KSTSMaxHexValue)
       
   351             {
       
   352                 aState = EERROR;
       
   353             }
       
   354             else
       
   355             {
       
   356                 aAIDDigit <<= KSTSLengthOfSingleHexDigitInBits;
       
   357                 aAIDDigit |= secondDigit;
       
   358                 aState = EDot;
       
   359             }
       
   360         }
       
   361         else
       
   362         {
       
   363             aState = EFirstDigit;
       
   364         }
       
   365         break;
       
   366     }
       
   367     case EDot:
       
   368     {
       
   369         if (aDigit != KSTSApduUriAIDSeparator)
       
   370         {
       
   371             aState = EERROR;
       
   372         }
       
   373         else
       
   374         {
       
   375             aState = EFirstDigit;
       
   376         }
       
   377         break;
       
   378     }
       
   379     default:
       
   380     {
       
   381 
       
   382     }
       
   383     }
       
   384 }
       
   385 
       
   386 } // namespace satsa
       
   387 } // namespace java
       
   388 //  End of File