voipplugins/dhcppositionprovider/src/dhcpocationinformationparser.cpp
branchRCL_3
changeset 22 d38647835c2e
parent 0 a4daefaec16c
equal deleted inserted replaced
21:f742655b05bf 22:d38647835c2e
       
     1 /*
       
     2 * Copyright (c) 2007 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:  Parses location information from DHCP message to LCI
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32math.h>
       
    20 #include "dhcplocationinformationparser.h"
       
    21 #include "dhcppsylogging.h"
       
    22 
       
    23 // Dynamic Host Configuration Protocol (DHCPv4 and DHCPv6) Option for Civic
       
    24 // Addresses Configuration Information
       
    25 // draft-ietf-geopriv-dhcp-civil-09
       
    26 
       
    27 // Civic Address CAtypes
       
    28 const TUint8 KDhcpState = 1;
       
    29 const TUint8 KDhcpCounty = 2;
       
    30 const TUint8 KDhcpCity = 3;
       
    31 const TUint8 KDhcpBorough = 4;
       
    32 const TUint8 KDhcpBlock = 5;
       
    33 const TUint8 KDhcpGroupOfStreets = 6;
       
    34 
       
    35 // Civic Address Additional CAtypes
       
    36 // const TUint8 KLanguage = 0;
       
    37 const TUint8 KDhcpLeadingStreetDirection = 16;
       
    38 const TUint8 KDhcpTrailingStreetDirection = 17;
       
    39 const TUint8 KDhcpStreetSuffix = 18;
       
    40 const TUint8 KDhcpHouseNumber = 19;
       
    41 const TUint8 KDhcpHouseNumberSuffix = 20;
       
    42 const TUint8 KDhcpVanityAddress = 21;
       
    43 const TUint8 KDhcpAdditionalLocationInformation = 22;
       
    44 const TUint8 KDhcpName = 23;
       
    45 const TUint8 KDhcpPostalCode = 24;
       
    46 const TUint8 KDhcpFloor = 27;
       
    47 const TUint8 KDchpCASeat = 33;
       
    48 
       
    49 // XML civilLoc elements
       
    50 _LIT8( KDhcpCountry, "country" );
       
    51 _LIT8( KDhcpA1, "A1" );     // state
       
    52 _LIT8( KDhcpA2, "A2" );     // county
       
    53 _LIT8( KDhcpA3, "A3" );     // city
       
    54 _LIT8( KDhcpA4, "A4" );     // borough
       
    55 _LIT8( KDhcpA5, "A5" );     // block
       
    56 _LIT8( KDhcpA6, "A6" );     // street
       
    57 _LIT8( KDhcpPRD, "PRD" );   // leading street direction
       
    58 _LIT8( KDhcpPOD, "POD" );   // trailing street direction
       
    59 _LIT8( KDhcpSTS, "STS" );   // street suffix
       
    60 _LIT8( KDhcpHNO, "HNO" );   // house number
       
    61 _LIT8( KDhcpHNS, "HNS" );   // house number suffix
       
    62 _LIT8( KDhcpLMK, "LMK" );   // landmark or vanity address
       
    63 _LIT8( KDhcpLOC, "LOC" );   // additional location information
       
    64 _LIT8( KDhcpNAM, "NAM" );   // name
       
    65 _LIT8( KDhcpPC, "PC" );     // postal code
       
    66 _LIT8( KDhcpFLR, "FLR" );   // floor
       
    67 _LIT8( KDhcpSEAT, "SEAT" ); // seat
       
    68 
       
    69 
       
    70 // XML message parsing
       
    71 
       
    72 // General
       
    73 _LIT8( KOpenBracket, "<" );
       
    74 _LIT8( KCloseBracket, ">" );
       
    75 _LIT8( KForwardSlash, "/" );
       
    76 _LIT8( KQuotationMark, "\"" );
       
    77 _LIT8( KColon, ":" );
       
    78 _LIT8( KSpaceChar, " " );
       
    79 _LIT8( KHyphen, "-" );
       
    80 
       
    81 // XML (RFC 4119)
       
    82 _LIT8( KXMLBegin, "?xml version=\"1.0\" encoding=\"UTF-8\"?" );
       
    83 _LIT8( KPresence, "presence" );
       
    84 _LIT8( KTuple, "tuple" );
       
    85 _LIT8( KStatus, "status" );
       
    86 _LIT8( KTimeStamp, "<timestamp>" );
       
    87 _LIT8( KTimeStampEnd, "</timestamp>" );
       
    88 _LIT8( KXmlnsNamespace, " xmlns=\"urn:ietf:params:xml:ns:pidf\"" );
       
    89 _LIT8( KId, " id=\"" );
       
    90 _LIT8( KTupleId1, "tuple1" );
       
    91 _LIT8( KT, "T" );
       
    92 _LIT8( KZ, "Z" );
       
    93 
       
    94 // gp namespace (RFC 4119)
       
    95 _LIT8( KGpNamespace, " xmlns:gp=\"urn:ietf:params:xml:ns:pidf:geopriv10\"" );
       
    96 _LIT8( KGp, "<gp:" );
       
    97 _LIT8( KGpEnd, "</gp:" );
       
    98 _LIT8( KGeopriv, "geopriv" );
       
    99 _LIT8( KLocationInfo, "location-info" );
       
   100 _LIT8( KUsageRules, "usage-rules" );
       
   101 _LIT8( KRetransmissionAllowed, "retransmission-allowed" );
       
   102 _LIT8( KRetentionExpiry, "retention-expiry" );
       
   103 _LIT8( KMethod, "method" );
       
   104 _LIT8( KNo, "no" );
       
   105 _LIT8( KDhcp, "DHCP" );
       
   106 
       
   107 // gml namespace (RFC 4119)
       
   108 _LIT8( KGmlNamespace,
       
   109     " xmlns:gml=\"urn:opengis:specification:gml:schema-xsd:feature:v3.0\"" );
       
   110 _LIT8( KGml, "<gml:" );
       
   111 _LIT8( KGmlEnd, "</gml:" );
       
   112 _LIT8( KGmlId, " gml:id=\"" );
       
   113 _LIT8( KLocation, "location" );
       
   114 _LIT8( KPoint, "Point" );
       
   115 _LIT8( KCoordinates, "coordinates" );
       
   116 _LIT8( KPointId1, "point1" );
       
   117 _LIT8( KSrsName, " srsName=\"" );
       
   118 _LIT8( KNorth, "N" );
       
   119 _LIT8( KEast, "E" );
       
   120 _LIT8( KSouth, "S" );
       
   121 _LIT8( KWest, "W" );
       
   122 
       
   123 // Datum related (RFC 3825)
       
   124 _LIT8( KEpsg4269, "epsg:4269" ); // NAD83 (North American Datum 1983)
       
   125 _LIT8( KEpsg4326, "epsg:4326" ); // EPSG:4326 - WGS84 (World Geodesic Datum)
       
   126 
       
   127 // cl namespace (RFC 4119)
       
   128 _LIT8( KClNamespace,
       
   129     " xmlns:cl=\" urn:ietf:params:xml:ns:pidf:geopriv10:civicLoc\"" );
       
   130 _LIT8( KCl, "<cl:" );
       
   131 _LIT8( KClEnd, "</cl:" );
       
   132 _LIT8( KCivicAddress, "civicAddress" );
       
   133 
       
   134 // Other constants
       
   135 const TUint8 KDhcpMinAsciiValue = 0x1f;
       
   136 const TUint8 KDhcpMaxAsciiValue = 0x7f;
       
   137 const TReal KDhcp25BitDivisor = 0x2000000;          // 33554432dec;
       
   138 
       
   139 // ---------------------------------------------------------------------------
       
   140 // Default constructor
       
   141 // ---------------------------------------------------------------------------
       
   142 //
       
   143 TDhcpLocationInformationParser::TDhcpLocationInformationParser()
       
   144     {
       
   145     iTimeStamp.HomeTime();
       
   146     }
       
   147 
       
   148 // ---------------------------------------------------------------------------
       
   149 // Parse XML description, geoConf or civic address, of the location
       
   150 // information. RFC 4119
       
   151 // ---------------------------------------------------------------------------
       
   152 //
       
   153 void TDhcpLocationInformationParser::ParseLocationInformation(
       
   154     const TDesC8& aInput, const TParsingType aParsingType, TDes8& aOutput )
       
   155     {
       
   156     TRACESTRING( "TLocationInformationParser::ParseLocationInformation" );
       
   157 
       
   158     // XML
       
   159     aOutput.Append( KOpenBracket );
       
   160     aOutput.Append( KXMLBegin );
       
   161     aOutput.Append( KCloseBracket );
       
   162 
       
   163     // presence
       
   164     aOutput.Append( KOpenBracket );
       
   165     aOutput.Append( KPresence );
       
   166     aOutput.Append( KXmlnsNamespace );
       
   167     aOutput.Append( KGpNamespace );
       
   168     if ( EDHCPCoordinates == aParsingType )
       
   169         {
       
   170         aOutput.Append( KGmlNamespace );
       
   171         }
       
   172     else // EDHCPCivicAddress
       
   173         {
       
   174         aOutput.Append( KClNamespace );
       
   175         }
       
   176 
       
   177     aOutput.Append( KCloseBracket );
       
   178 
       
   179     // tuple
       
   180     aOutput.Append( KOpenBracket );
       
   181     aOutput.Append( KTuple );
       
   182     aOutput.Append( KId );
       
   183     aOutput.Append( KTupleId1 );
       
   184     aOutput.Append( KQuotationMark );
       
   185     aOutput.Append( KCloseBracket );
       
   186 
       
   187     // timestamp
       
   188     aOutput.Append( KTimeStamp );
       
   189     ParseTimeStamp( aOutput );
       
   190     aOutput.Append( KTimeStampEnd );
       
   191 
       
   192     // status
       
   193     aOutput.Append( KOpenBracket );
       
   194     aOutput.Append( KStatus );
       
   195     aOutput.Append( KCloseBracket );
       
   196 
       
   197     // geopriv
       
   198     aOutput.Append( KGp );
       
   199     aOutput.Append( KGeopriv );
       
   200     aOutput.Append( KCloseBracket );
       
   201 
       
   202     // location-info
       
   203     aOutput.Append( KGp );
       
   204     aOutput.Append( KLocationInfo );
       
   205     aOutput.Append( KCloseBracket );
       
   206 
       
   207     if (aParsingType == EDHCPCoordinates)
       
   208         {
       
   209         // GML
       
   210         aOutput.Append( KGml );
       
   211         aOutput.Append( KLocation );
       
   212         aOutput.Append( KCloseBracket );
       
   213 
       
   214         // Point
       
   215         aOutput.Append( KGml );
       
   216         aOutput.Append( KPoint );
       
   217         aOutput.Append( KGmlId );
       
   218         aOutput.Append( KPointId1 );
       
   219         aOutput.Append( KQuotationMark );
       
   220         // srsName, i.e. datum
       
   221         ParseDatum( aInput, aOutput ); // Ignore error
       
   222         aOutput.Append( KCloseBracket );
       
   223 
       
   224         // coordinates
       
   225         aOutput.Append( KGml );
       
   226         aOutput.Append( KCoordinates );
       
   227         aOutput.Append( KCloseBracket );
       
   228 
       
   229         // Parse coordinates
       
   230         ParseLCI( aInput, aOutput );
       
   231 
       
   232         // coordinates end
       
   233         aOutput.Append( KGmlEnd );
       
   234         aOutput.Append( KCoordinates );
       
   235         aOutput.Append( KCloseBracket );
       
   236 
       
   237         // Point end
       
   238         aOutput.Append( KGmlEnd );
       
   239         aOutput.Append( KPoint );
       
   240         aOutput.Append( KCloseBracket );
       
   241 
       
   242         // GML end
       
   243         aOutput.Append( KGmlEnd );
       
   244         aOutput.Append( KLocation );
       
   245         aOutput.Append( KCloseBracket );
       
   246         }
       
   247     else // EDHCPCivicAddress
       
   248         {
       
   249         // civicAddress
       
   250         aOutput.Append( KCl );
       
   251         aOutput.Append( KCivicAddress );
       
   252         aOutput.Append( KCloseBracket );
       
   253 
       
   254         // Parse civic address elements
       
   255         ParseCivicAddressElements( aInput, aOutput );
       
   256 
       
   257         // civicAddress end
       
   258         aOutput.Append( KClEnd );
       
   259         aOutput.Append( KCivicAddress );
       
   260         aOutput.Append( KCloseBracket );
       
   261         }
       
   262 
       
   263     // location-info end
       
   264     aOutput.Append( KGpEnd );
       
   265     aOutput.Append( KLocationInfo );
       
   266     aOutput.Append( KCloseBracket );
       
   267 
       
   268     // usage-rules
       
   269     aOutput.Append( KGp );
       
   270     aOutput.Append( KUsageRules );
       
   271     aOutput.Append( KCloseBracket );
       
   272     // retransmission-allowed
       
   273     aOutput.Append( KGp );
       
   274     aOutput.Append( KRetransmissionAllowed );
       
   275     aOutput.Append( KCloseBracket );
       
   276     aOutput.Append( KNo );
       
   277     aOutput.Append( KGpEnd );
       
   278     aOutput.Append( KRetransmissionAllowed );
       
   279     aOutput.Append( KCloseBracket );
       
   280     // retention-expiry
       
   281     aOutput.Append( KGp );
       
   282     aOutput.Append( KRetentionExpiry );
       
   283     aOutput.Append( KCloseBracket );
       
   284     ParseRetentionExpiry( aOutput );
       
   285     aOutput.Append( KGpEnd );
       
   286     aOutput.Append( KRetentionExpiry );
       
   287     aOutput.Append( KCloseBracket );
       
   288     // method
       
   289     aOutput.Append( KGp );
       
   290     aOutput.Append( KMethod );
       
   291     aOutput.Append( KCloseBracket );
       
   292     aOutput.Append( KDhcp );
       
   293     aOutput.Append( KGpEnd );
       
   294     aOutput.Append( KMethod );
       
   295     aOutput.Append( KCloseBracket );
       
   296 
       
   297     // : provided-by
       
   298 
       
   299     // usage-rules end
       
   300     aOutput.Append( KGpEnd );
       
   301     aOutput.Append( KUsageRules );
       
   302     aOutput.Append( KCloseBracket );
       
   303 
       
   304     // geopriv end
       
   305     aOutput.Append( KGpEnd );
       
   306     aOutput.Append( KGeopriv );
       
   307     aOutput.Append( KCloseBracket );
       
   308 
       
   309     // status end
       
   310     aOutput.Append( KOpenBracket );
       
   311     aOutput.Append( KForwardSlash );
       
   312     aOutput.Append( KStatus );
       
   313     aOutput.Append( KCloseBracket );
       
   314 
       
   315     // tuple end
       
   316     aOutput.Append( KOpenBracket );
       
   317     aOutput.Append( KForwardSlash );
       
   318     aOutput.Append( KTuple );
       
   319     aOutput.Append( KCloseBracket );
       
   320 
       
   321     // presence end
       
   322     aOutput.Append( KOpenBracket );
       
   323     aOutput.Append( KForwardSlash );
       
   324     aOutput.Append( KPresence );
       
   325     aOutput.Append( KCloseBracket );
       
   326     }
       
   327 
       
   328 
       
   329 // ---------------------------------------------------------------------------
       
   330 // Parses datum from the input
       
   331 // Datum usage: RFC 3825.
       
   332 // ---------------------------------------------------------------------------
       
   333 //
       
   334 TInt TDhcpLocationInformationParser::ParseDatum (const TDesC8& aInput, TDes8& aOutput )
       
   335     {
       
   336     TRACESTRING( "TLocationInformationParser::ParseDatum" );
       
   337 
       
   338     if ( 16 > aInput.Length() )
       
   339         {
       
   340         return KErrNotFound;
       
   341         }
       
   342 
       
   343     // The LCI form is of fixed length (16 bytes). The last byte of the input
       
   344     // contains the datum value.
       
   345     switch ( ( TUint8 )aInput[ 15 ] )
       
   346         {
       
   347         case 1:
       
   348             {
       
   349             // WGS 84, 2D only (For 3D: WGS84 (Geographical 3D))
       
   350             aOutput.Append( KSrsName );
       
   351             aOutput.Append( KEpsg4326 );
       
   352             aOutput.Append( KQuotationMark );
       
   353             return KErrNone;
       
   354             }
       
   355         case 2:
       
   356             {
       
   357             // NAD83, 2D only (For 3D: NAD83 & NAVD88)
       
   358             aOutput.Append( KSrsName );
       
   359             aOutput.Append( KEpsg4269 );
       
   360             aOutput.Append( KQuotationMark );
       
   361             return KErrNone;
       
   362             }
       
   363         case 3:
       
   364             {
       
   365             // NAD83, 2D only (For 3D: NAD83 & MLLW)
       
   366             aOutput.Append( KSrsName );
       
   367             aOutput.Append( KEpsg4269 );
       
   368             aOutput.Append( KQuotationMark );
       
   369             return KErrNone;
       
   370             }
       
   371         default:
       
   372             {
       
   373             return KErrNotSupported;
       
   374             }
       
   375         }
       
   376     }
       
   377 
       
   378 
       
   379 // ---------------------------------------------------------------------------
       
   380 // Parses the input to the LCI form
       
   381 // ---------------------------------------------------------------------------
       
   382 //
       
   383 void TDhcpLocationInformationParser::ParseLCI(
       
   384     const TDesC8& aInput, TDes8& aOutput )
       
   385     {
       
   386     TRACESTRING( "TLocationInformationParser::ParseLCI" );
       
   387 
       
   388     TLex8 input( aInput );
       
   389 
       
   390     // Latitude
       
   391 
       
   392     // Latitude resolution (6 bits)
       
   393     TUint8 laRes = ( TUint8 )input.Peek();
       
   394     laRes >>= 2;
       
   395 
       
   396     // Latitude (9 bits integer, 25 bits fraction)
       
   397     TUint16 laInt = ( TUint16 )input.Get();
       
   398     laInt <<= 14;
       
   399     laInt >>= 6;
       
   400     laInt += ( TUint8 )input.Peek();
       
   401     laInt >>= 1;
       
   402 
       
   403     TUint32 laFra = ( TUint32 )input.Get();
       
   404     laFra <<= 8;
       
   405     laFra += ( TUint8 )input.Get();
       
   406     laFra <<= 8;
       
   407     laFra += ( TUint8 )input.Get();
       
   408     laFra <<= 8;
       
   409     laFra += ( TUint8 )input.Get();
       
   410     laFra <<= 7;
       
   411     laFra >>= 7;
       
   412 
       
   413     ParseDMS( ETrue, laRes, laInt, laFra, aOutput );
       
   414 
       
   415     aOutput.Append( KSpaceChar );
       
   416 
       
   417     // Longitude
       
   418 
       
   419     // Longitude resolution (6 bits)
       
   420     TUint8 loRes = ( TUint8 )input.Peek();
       
   421     loRes >>= 2;
       
   422 
       
   423     // Longitude (9 bits integer, 25 bits fraction)
       
   424     TUint16 loInt = ( TUint16 )input.Get();
       
   425     loInt <<= 14;
       
   426     loInt >>= 6;
       
   427     loInt += ( TUint8 )input.Peek();
       
   428     loInt >>= 1;
       
   429 
       
   430     TUint32 loFra = ( TUint32 )input.Get();
       
   431     loFra <<= 8;
       
   432     loFra += ( TUint8 )input.Get();
       
   433     loFra <<= 8;
       
   434     loFra += ( TUint8 )input.Get();
       
   435     loFra <<= 8;
       
   436     loFra += ( TUint8 )input.Get();
       
   437     loFra <<= 7;
       
   438     loFra >>= 7;
       
   439 
       
   440     ParseDMS( EFalse, loRes, loInt, loFra, aOutput );
       
   441 
       
   442     // Altitude
       
   443     if ( 15 <= aInput.Length() )
       
   444         {
       
   445         // AT (4 bits)
       
   446         // 1 for meters, 2 for floors
       
   447         TUint8 AT = ( TUint8 )input.Peek();
       
   448         AT >>= 4;
       
   449 
       
   450         // Altitude resolution (6 bits)
       
   451         TUint16 altRes = ( TUint16 )input.Get();
       
   452         altRes <<= 8;
       
   453         altRes += ( TUint8 )input.Peek();
       
   454         altRes >>= 6;
       
   455 
       
   456         // Altitude (30 bits)
       
   457         TUint32 alt = ( TUint32 )input.Get();
       
   458         alt <<= 26;
       
   459         alt >>= 18;
       
   460         alt += ( TUint8 )input.Get();
       
   461         alt <<= 8;
       
   462         alt += ( TUint8 )input.Get();
       
   463         alt <<= 8;
       
   464         alt += ( TUint8 )input.Get();
       
   465         alt <<= 8;
       
   466 
       
   467         TRACESTRING2( "AT: %d", AT );
       
   468         TRACESTRING2( "altRes: %d", altRes );
       
   469         TRACESTRING2( "alt: %d", alt );
       
   470         }
       
   471 
       
   472     // No support for parsing altitude to XML yet
       
   473     }
       
   474 
       
   475 
       
   476 // ---------------------------------------------------------------------------
       
   477 // Parses the input to the DMS coordinate form
       
   478 // ---------------------------------------------------------------------------
       
   479 //
       
   480 void TDhcpLocationInformationParser::ParseDMS(
       
   481     TBool aIsLatitude,
       
   482     TUint8 aResolution,
       
   483     TUint16 aInteger,
       
   484     TUint32 aFraction,
       
   485     TDes8& aOutput )
       
   486     {
       
   487     TRACESTRING( "TLocationInformationParser::ParseDMS" );
       
   488 
       
   489     TRACESTRING2( "aResolution: %d", aResolution );
       
   490     TRACESTRING2( "aInteger: %d", aInteger );
       
   491     TRACESTRING2( "aFraction: %d", aFraction );
       
   492 
       
   493     // Check the first bit for sign
       
   494     TUint16 sign = aInteger; // 9 bits
       
   495     sign >>= 8;
       
   496 
       
   497     // 2s complement
       
   498     if ( sign )
       
   499         {
       
   500         aInteger = ~aInteger;
       
   501         aInteger <<= 7;
       
   502         aInteger >>= 7;
       
   503         aFraction = ~aFraction;
       
   504         aFraction <<= 7;
       
   505         aFraction >>= 7;
       
   506         }
       
   507 
       
   508     // Apply resolution
       
   509     if ( 9 < aResolution )
       
   510         {
       
   511         // Fractional part
       
   512         aFraction >>= ( 34 - aResolution );
       
   513         aFraction <<= ( 34 - aResolution );
       
   514         }
       
   515     else
       
   516         {
       
   517         // No fractional part
       
   518         aFraction = 0;
       
   519         // Integer part
       
   520         aInteger >>= ( 9 - aResolution );
       
   521         aInteger <<= ( 9 - aResolution );
       
   522         }
       
   523 
       
   524     // Fractional part
       
   525     TReal minutes( 0.0 );
       
   526     TReal seconds( 0.0 );
       
   527     if ( aFraction )
       
   528         {
       
   529         TReal frac = ( TReal )aFraction / KDhcp25BitDivisor;
       
   530         Math::Int( minutes, 60.0 * frac );
       
   531         frac = 60.0 * frac - minutes;
       
   532         Math::Int( seconds, 60.0 * frac );
       
   533         }
       
   534 
       
   535     // Parse the result
       
   536     aOutput.AppendNum( aInteger );
       
   537     aOutput.Append( KColon );
       
   538     aOutput.AppendNum( ( TUint8 )minutes );
       
   539     aOutput.Append( KColon );
       
   540     aOutput.AppendNum( ( TUint8 )seconds );
       
   541     if ( aIsLatitude )
       
   542         {
       
   543         if ( sign )
       
   544             {
       
   545             aOutput.Append( KSouth );
       
   546             }
       
   547         else
       
   548             {
       
   549             aOutput.Append( KNorth );
       
   550             }
       
   551         }
       
   552     else
       
   553         {
       
   554         if ( sign )
       
   555             {
       
   556             aOutput.Append( KWest );
       
   557             }
       
   558         else
       
   559             {
       
   560             aOutput.Append( KEast );
       
   561             }
       
   562         }
       
   563     }
       
   564 
       
   565 
       
   566 // ---------------------------------------------------------------------------
       
   567 // Parse XML description of civic address elements
       
   568 // Correspondence of tags can be found in Ch.3.4 Civic Address Components in
       
   569 // http://www.ietf.org/internet-drafts/draft-ietf-geopriv-dhcp-civil-09.txt
       
   570 // ---------------------------------------------------------------------------
       
   571 //
       
   572 void TDhcpLocationInformationParser::ParseCivicAddressElements(
       
   573     const TDesC8& aInput, TDes8& aOutput )
       
   574     {
       
   575     TRACESTRING( "TLocationInformationParser::ParseCivicAddressElements" );
       
   576 
       
   577     TLex8 input( aInput );
       
   578 
       
   579     // Skip what
       
   580     input.Inc();
       
   581 
       
   582     // country code, two letters long
       
   583     aOutput.Append( KCl );
       
   584     aOutput.Append( KDhcpCountry );
       
   585     aOutput.Append( KCloseBracket );
       
   586     aOutput.Append( input.Get() );
       
   587     aOutput.Append( input.Get() );
       
   588     aOutput.Append( KClEnd );
       
   589     aOutput.Append( KDhcpCountry );
       
   590     aOutput.Append( KCloseBracket );
       
   591 
       
   592     // civicAddress elements
       
   593     while ( !input.Eos() )
       
   594         {
       
   595         TInt type = ( TUint8 )input.Get();
       
   596         switch ( type )
       
   597             {
       
   598             case KDhcpState:
       
   599                 {
       
   600                 TRACESTRING( "KDhcpState" );
       
   601                 aOutput.Append( KCl );
       
   602                 aOutput.Append( KDhcpA1 );
       
   603                 aOutput.Append( KCloseBracket );
       
   604                 ExtractCivicAddressElement( input, aOutput );
       
   605                 aOutput.Append( KClEnd );
       
   606                 aOutput.Append( KDhcpA1 );
       
   607                 aOutput.Append( KCloseBracket );
       
   608                 break;
       
   609                 }
       
   610             case KDhcpCounty:
       
   611                 {
       
   612                 TRACESTRING( "KDhcpCounty" );
       
   613                 aOutput.Append( KCl );
       
   614                 aOutput.Append( KDhcpA2 );
       
   615                 aOutput.Append( KCloseBracket );
       
   616                 ExtractCivicAddressElement( input, aOutput );
       
   617                 aOutput.Append( KClEnd );
       
   618                 aOutput.Append( KDhcpA2 );
       
   619                 aOutput.Append( KCloseBracket );
       
   620                 break;
       
   621                 }
       
   622             case KDhcpCity:
       
   623                 {
       
   624                 TRACESTRING( "KDhcpCity" );
       
   625                 aOutput.Append( KCl );
       
   626                 aOutput.Append( KDhcpA3 );
       
   627                 aOutput.Append( KCloseBracket );
       
   628                 ExtractCivicAddressElement( input, aOutput );
       
   629                 aOutput.Append( KClEnd );
       
   630                 aOutput.Append( KDhcpA3 );
       
   631                 aOutput.Append( KCloseBracket );
       
   632                 break;
       
   633                 }
       
   634             case KDhcpBorough:
       
   635                 {
       
   636                 TRACESTRING( "KDhcpBorough" );
       
   637                 aOutput.Append( KCl );
       
   638                 aOutput.Append( KDhcpA4 );
       
   639                 aOutput.Append( KCloseBracket );
       
   640                 ExtractCivicAddressElement( input, aOutput );
       
   641                 aOutput.Append( KClEnd );
       
   642                 aOutput.Append( KDhcpA4 );
       
   643                 aOutput.Append( KCloseBracket );
       
   644                 break;
       
   645                 }
       
   646             case KDhcpBlock:
       
   647                 {
       
   648                 TRACESTRING( "KBlock" );
       
   649                 aOutput.Append( KCl );
       
   650                 aOutput.Append( KDhcpA5 );
       
   651                 aOutput.Append( KCloseBracket );
       
   652                 ExtractCivicAddressElement( input, aOutput );
       
   653                 aOutput.Append( KClEnd );
       
   654                 aOutput.Append( KDhcpA5 );
       
   655                 aOutput.Append( KCloseBracket );
       
   656                 break;
       
   657                 }
       
   658             case KDhcpGroupOfStreets:
       
   659                 {
       
   660                 TRACESTRING( "KGroupOfStreets" );
       
   661                 aOutput.Append( KCl );
       
   662                 aOutput.Append( KDhcpA6 );
       
   663                 aOutput.Append( KCloseBracket );
       
   664                 ExtractCivicAddressElement( input, aOutput );
       
   665                 aOutput.Append( KClEnd );
       
   666                 aOutput.Append( KDhcpA6 );
       
   667                 aOutput.Append( KCloseBracket );
       
   668                 break;
       
   669                 }
       
   670             case KDhcpLeadingStreetDirection:
       
   671                 {
       
   672                 TRACESTRING( "KLeadingStreetDirection" );
       
   673                 aOutput.Append( KCl );
       
   674                 aOutput.Append( KDhcpPRD );
       
   675                 aOutput.Append( KCloseBracket );
       
   676                 ExtractCivicAddressElement( input, aOutput );
       
   677                 aOutput.Append( KClEnd );
       
   678                 aOutput.Append( KDhcpPRD );
       
   679                 aOutput.Append( KCloseBracket );
       
   680                 break;
       
   681                 }
       
   682             case KDhcpTrailingStreetDirection:
       
   683                 {
       
   684                 TRACESTRING( "KTrailingStreetDirection" );
       
   685                 aOutput.Append( KCl );
       
   686                 aOutput.Append( KDhcpPOD );
       
   687                 aOutput.Append( KCloseBracket );
       
   688                 ExtractCivicAddressElement( input, aOutput );
       
   689                 aOutput.Append( KClEnd );
       
   690                 aOutput.Append( KDhcpPOD );
       
   691                 aOutput.Append( KCloseBracket );
       
   692                 break;
       
   693                 }
       
   694             case KDhcpStreetSuffix:
       
   695                 {
       
   696                 TRACESTRING( "KStreetSuffix" );
       
   697                 aOutput.Append( KCl );
       
   698                 aOutput.Append( KDhcpSTS );
       
   699                 aOutput.Append( KCloseBracket );
       
   700                 ExtractCivicAddressElement( input, aOutput );
       
   701                 aOutput.Append( KClEnd );
       
   702                 aOutput.Append( KDhcpSTS );
       
   703                 aOutput.Append( KCloseBracket );
       
   704                 break;
       
   705                 }
       
   706             case KDhcpHouseNumber:
       
   707                 {
       
   708                 TRACESTRING( "KHouseNumber" );
       
   709                 aOutput.Append( KCl );
       
   710                 aOutput.Append( KDhcpHNO );
       
   711                 aOutput.Append( KCloseBracket );
       
   712                 ExtractCivicAddressElement( input, aOutput );
       
   713                 aOutput.Append( KClEnd );
       
   714                 aOutput.Append( KDhcpHNO );
       
   715                 aOutput.Append( KCloseBracket );
       
   716                 break;
       
   717                 }
       
   718             case KDhcpHouseNumberSuffix:
       
   719                 {
       
   720                 TRACESTRING( "KHouseNumberSuffix" );
       
   721                 aOutput.Append( KCl );
       
   722                 aOutput.Append( KDhcpHNS );
       
   723                 aOutput.Append( KCloseBracket );
       
   724                 ExtractCivicAddressElement( input, aOutput );
       
   725                 aOutput.Append( KClEnd );
       
   726                 aOutput.Append( KDhcpHNS );
       
   727                 aOutput.Append( KCloseBracket );
       
   728                 break;
       
   729                 }
       
   730             case KDhcpVanityAddress:
       
   731                 {
       
   732                 TRACESTRING( "KVanityAddress" );
       
   733                 aOutput.Append( KCl );
       
   734                 aOutput.Append( KDhcpLMK );
       
   735                 aOutput.Append( KCloseBracket );
       
   736                 ExtractCivicAddressElement( input, aOutput );
       
   737                 aOutput.Append( KClEnd );
       
   738                 aOutput.Append( KDhcpLMK );
       
   739                 aOutput.Append( KCloseBracket );
       
   740                 break;
       
   741                 }
       
   742             case KDhcpAdditionalLocationInformation:
       
   743                 {
       
   744                 TRACESTRING( "KAdditionalLocationInformation" );
       
   745                 aOutput.Append( KCl );
       
   746                 aOutput.Append( KDhcpLOC );
       
   747                 aOutput.Append( KCloseBracket );
       
   748                 ExtractCivicAddressElement( input, aOutput );
       
   749                 aOutput.Append( KClEnd );
       
   750                 aOutput.Append( KDhcpLOC );
       
   751                 aOutput.Append( KCloseBracket );
       
   752                 break;
       
   753                 }
       
   754             case KDhcpName:
       
   755                 {
       
   756                 TRACESTRING( "KName" );
       
   757                 aOutput.Append( KCl );
       
   758                 aOutput.Append( KDhcpNAM );
       
   759                 aOutput.Append( KCloseBracket );
       
   760                 ExtractCivicAddressElement( input, aOutput );
       
   761                 aOutput.Append( KClEnd );
       
   762                 aOutput.Append( KDhcpNAM );
       
   763                 aOutput.Append( KCloseBracket );
       
   764                 break;
       
   765                 }
       
   766             case KDhcpPostalCode:
       
   767                 {
       
   768                 TRACESTRING( "KPostalCode" );
       
   769                 aOutput.Append( KCl );
       
   770                 aOutput.Append( KDhcpPC );
       
   771                 aOutput.Append( KCloseBracket );
       
   772                 ExtractCivicAddressElement( input, aOutput );
       
   773                 aOutput.Append( KClEnd );
       
   774                 aOutput.Append( KDhcpPC );
       
   775                 aOutput.Append( KCloseBracket );
       
   776                 break;
       
   777                 }
       
   778             case KDchpCASeat:
       
   779                 {
       
   780                 TRACESTRING( "KCASeat" );
       
   781                 aOutput.Append( KCl );
       
   782                 aOutput.Append( KDhcpSEAT );
       
   783                 aOutput.Append( KCloseBracket );
       
   784                 ExtractCivicAddressElement( input, aOutput );
       
   785                 aOutput.Append( KClEnd );
       
   786                 aOutput.Append( KDhcpSEAT );
       
   787                 aOutput.Append( KCloseBracket );
       
   788                 break;
       
   789                 }
       
   790             case KDhcpFloor:
       
   791                 {
       
   792                 TRACESTRING( "KFloor" );
       
   793                 aOutput.Append( KCl );
       
   794                 aOutput.Append( KDhcpFLR );
       
   795                 aOutput.Append( KCloseBracket );
       
   796                 ExtractCivicAddressElement( input, aOutput );
       
   797                 aOutput.Append( KClEnd );
       
   798                 aOutput.Append( KDhcpFLR );
       
   799                 aOutput.Append( KCloseBracket );
       
   800                 break;
       
   801                 }
       
   802             default:
       
   803                 {
       
   804                 TRACESTRING2( "Not a supported CAtype: %d", type );
       
   805                 input.Inc( ( TInt )input.Get() ); // Skip value
       
   806                 break;
       
   807                 }
       
   808             }
       
   809         }
       
   810     }
       
   811 
       
   812 // ---------------------------------------------------------------------------
       
   813 // Extract a single civic address element from the input
       
   814 // ---------------------------------------------------------------------------
       
   815 //
       
   816 void TDhcpLocationInformationParser::ExtractCivicAddressElement(
       
   817     TLex8& aInput, TDes8& aOutput )
       
   818     {
       
   819     TRACESTRING( "TLocationInformationParser::ExtractCivicAddressElement" );
       
   820 
       
   821     // Extract data length
       
   822     TInt length = ( TInt )aInput.Get();
       
   823     // Extract data
       
   824     while ( length )
       
   825         {
       
   826         if ( KDhcpMinAsciiValue < ( TUint8 )aInput.Peek() &&
       
   827              KDhcpMaxAsciiValue > ( TUint8 )aInput.Peek() )
       
   828             {
       
   829             aOutput.Append( aInput.Get() );
       
   830             }
       
   831         length--;
       
   832         }
       
   833     }
       
   834 
       
   835 
       
   836 // ---------------------------------------------------------------------------
       
   837 // Parses the timestamp
       
   838 // ---------------------------------------------------------------------------
       
   839 //
       
   840 void TDhcpLocationInformationParser::ParseTimeStamp( TDes8& aTimeStamp )
       
   841     {
       
   842     TRACESTRING( "TLocationInformationParser::ParseTimeStamp" );
       
   843 
       
   844     TDateTime timeStamp = iTimeStamp.DateTime();
       
   845     aTimeStamp.AppendNum( timeStamp.Year() );
       
   846     aTimeStamp.Append( KHyphen );
       
   847     aTimeStamp.AppendNum( timeStamp.Month() + 1 );
       
   848     aTimeStamp.Append( KHyphen );
       
   849     aTimeStamp.AppendNum( timeStamp.Day() + 1 );
       
   850     aTimeStamp.Append( KT );
       
   851     aTimeStamp.AppendNum( timeStamp.Hour() );
       
   852     aTimeStamp.Append( KColon );
       
   853     aTimeStamp.AppendNum( timeStamp.Minute() );
       
   854     aTimeStamp.Append( KColon );
       
   855     aTimeStamp.AppendNum( timeStamp.Second() );
       
   856     aTimeStamp.Append( KZ );
       
   857     }
       
   858 
       
   859 // ---------------------------------------------------------------------------
       
   860 // Parses the retention expiry. It is the timestamp value plus one day
       
   861 // ---------------------------------------------------------------------------
       
   862 //
       
   863 void TDhcpLocationInformationParser::ParseRetentionExpiry( TDes8& aTargetBfr )
       
   864     {
       
   865     TRACESTRING( "TLocationInformationParser::ParseRetentionExpiry" );
       
   866     // Define the retention-expiry
       
   867     TTime expiryTime( iTimeStamp );
       
   868     TTimeIntervalDays day( 1 );
       
   869     expiryTime += day;
       
   870     TDateTime retentionExpiry = expiryTime.DateTime();
       
   871 
       
   872     // Parse the retention-expiry
       
   873     aTargetBfr.AppendNum( retentionExpiry.Year() );
       
   874     aTargetBfr.Append( KHyphen );
       
   875     aTargetBfr.AppendNum( retentionExpiry.Month() + 1 );
       
   876     aTargetBfr.Append( KHyphen );
       
   877     aTargetBfr.AppendNum( retentionExpiry.Day() + 1 );
       
   878     aTargetBfr.Append( KT );
       
   879     aTargetBfr.AppendNum( retentionExpiry.Hour() );
       
   880     aTargetBfr.Append( KColon );
       
   881     aTargetBfr.AppendNum( retentionExpiry.Minute() );
       
   882     aTargetBfr.Append( KColon );
       
   883     aTargetBfr.AppendNum( retentionExpiry.Second() );
       
   884     aTargetBfr.Append( KZ );
       
   885     }