Il formato OpenPass
Da Libro Bianco OpenPass.
Versione del 22 ago 2016 alle 20:23 di Marco (Discussione | contributi) (→Formato 3: : resto "collassabile" il testo del codice XML)
Struttura del formato
Di seguito si riportano tutti i formati OpenPass utilizzati negli anni.
Formato 1
Il Formato 1 è stato il primo formato redatto ed è stato usato solo come versione di prova, quindi non è mai stato utilizzato sul mercato. Per questo motivo il formato 1 non viene riportato.
Formato 2
Anche il Formato 2 di OpenPass è stato utilizzato solo in fase di test e non è attualmente usato, quindi non viene riportato.
Formato 3
Il Formato 3 è il formato attualmente attivo, strutturato come segue. Clicca su Espandi a lato per visualizzare la struttura del formato
<?xml version="1.0"?>
<FormatDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Identifier>3</Identifier>
<Description>Common compatible format for season passes, day/time pass and point passes - V0.25 (DRAFT)</Description>
<Creator>Axess Alfi SkiData</Creator>
<LastTouch>2010-09-15T13:23:00</LastTouch>
<!-- Change history -->
<!-- V0.10 Apr 15th, 2010: initial version (Axess AG) -->
<!-- V0.11 Apr 26th, 2010: changes from first review (Skidata, Axess AG) -->
<!-- V0.12 May 10th, 2010: remove reloading of point tickets (Skidata, Axess AG) -->
<!-- V0.13 May 11th, 2010: Group renamed to Region (Skidata AG) -->
<!-- V0.14 May 26th, 2010: changes from review with Alfi: constant value for Root.Group, changed Root.TicketType, renamed Root.SerialNumberEx, minor changes (Axess AG, Alfi) -->
<!-- V0.15 June 11th, 2010: decrease size of Root.Region, change syntax of variable area (add new tokens Root.BlockCRC, ...), use Root.Season+Root.SerialNumberEx in Lombardia (Axess AG, Alfi)-->
<!-- V0.16 June 15th, 2010: removed Root.PriceType, correct bitaddress in variable area, added comments (Axess AG, Skidata AG)-->
<!-- V0.17 June 16th, 2010: added Root.TargetRegion, modified Root.UserID, defined enumerations for Root.Region (Axess AG)-->
<!-- V0.18 June 18th, 2010: renamed Root.Region to Root.IssuerRegion (Axess AG)-->
<!-- V0.19 July 13th, 2010: introduced format 4 (point pass) - identical to format 3 but increased width for Root.RemainingDuration to 20 bits + skipped Root.CurrentDay (SkiData, Axess AG)-->
<!-- V0.20 July 19th, 2010: splitted Root.UserID in Root.UserIDRegion, Root.UserIDWorkstation, Root.UserID, splitted VariableArea parts to support automatic checksum calculations, removed format 4 (SkiData)-->
<!-- V0.21 July 19th, 2010: changed Root.RemainingDuration to 14, Root.CurrentDay to 12 and Root.CRC to 6 bits (Axess AG, SkiData)-->
<!-- V0.22 July 21th, 2010: changed Root.Duration to 14 bits, reverted some changes (Root.UserID + VariableArea definition) from V0.20 and V0.21 to stay compatible with OpenPass (Axess AG)-->
<!-- V0.23 August 17th, 2010: added Root.DateIssued, Root.TimeIssued (Axess AG, SkiData)-->
<!-- V0.24 August 23rd, 2010: renamed Root.BlockCRC tokens to have unique names (Axess AG, SkiData)-->
<!-- V0.25 September 15th, 2010: added currency code (Axess AG)-->
<FixedArea>
<TokenAllocation>
<Name>Root.CRC</Name>
<BitAddress>0</BitAddress>
<BitWidth>16</BitWidth>
</TokenAllocation>
<TokenAllocation>
<Name>Root.IssuerRegion</Name>
<BitAddress>16</BitAddress>
<BitWidth>13</BitWidth>
<!-- Note: in SkiData/Axess compatibilty replaces 'Root.Region' the earlier field 'Root.Group': worldwide unique number for region, also stored in header -->
<!-- (0=Test, 1=Lombardia, ...) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.Group</Name>
<ConstantValue>1</ConstantValue>
<!-- Note: no usage for coding Root.Group, therefor define constant value for it -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.UsageDomain</Name>
<BitAddress>29</BitAddress>
<BitWidth>9</BitWidth>
<!-- pool (group of companies having gates) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.SubDomain</Name>
<BitAddress>38</BitAddress>
<BitWidth>7</BitWidth>
<!-- 0 = NotUsed (All gates within usage domain) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.Workstation</Name>
<BitAddress>45</BitAddress>
<BitWidth>11</BitWidth>
<!-- unique ID of the workstation (0-2047) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.StartDate</Name>
<BitAddress>56</BitAddress>
<BitWidth>14</BitWidth>
<!-- ticket is valid starting from this date (days since 1/1/2008) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.ExpiryDate</Name>
<BitAddress>70</BitAddress>
<BitWidth>14</BitWidth>
<!-- ticket is valid until this date (days since 1/1/2008), also stored in header (SkiData/Axess compatibilty only) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.StartTime</Name>
<BitAddress>84</BitAddress>
<BitWidth>11</BitWidth>
<!-- ticket is valid from this time (minutes since midnight), only applicable if Root.Unit = Hours/Minutes -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.StartMode</Name>
<BitAddress>95</BitAddress>
<BitWidth>4</BitWidth>
<!-- 1 = ValidFromIssue (directly use Root.StartDate, Root.StartTime, Root.ExpiryDate) -->
<!-- 2 = ValidFromFirstUsage (day pass depot ticket, use Root.DateOfFirstEntry + Root.StartTime/Root.TimeOfFirstEntry [dependent on Root.Unit]; Root.StartDate and Root.ExpiryDate specify absolute limits only) -->
<!-- only applicable if Root.Unit = Days -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.Duration</Name>
<BitAddress>99</BitAddress>
<BitWidth>14</BitWidth>
<!-- duration (in days/hours/points) - only used if countable (Days, Hours, Minutes, Years, Month, Points, SingleRides), otherwise set to 1 (Seasons, ...) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.TicketType</Name>
<BitAddress>113</BitAddress>
<BitWidth>4</BitWidth>
<!-- 0 = time pass, 1 = consumable (point pass, non-consecutive time pass) -->
<!-- Note: if multiple formats are used, this token can be ommited -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.Unit</Name>
<BitAddress>117</BitAddress>
<BitWidth>4</BitWidth>
<!-- unit for Root.Duration (0 = Days, 1 = Reserved, 2 = Reserved, 3 = Points, 4 = SingleRides, 5 = Seasons, 6 = Reserved, 7 = Hours, 8 = Minutes, 9 = Year, 10 = Month) -->
<!-- currently only supported: 0 = Days, 3 = Points, 5 = Seasons, 7 = Hours, 8 = Minutes -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.SerialNumberEx2</Name>
<BitAddress>121</BitAddress>
<BitWidth>32</BitWidth>
<!-- unique serial number of ticket (based on used workstation ID) -->
<!-- Note: no longer dependent on season! (SkiData/Axess compatibilty only) -->
<!-- TODO: in Lombardia replaced by Root.Season (4 bit) + Root.SerialNumberEx (28 bit); needs final confirmation from Alfi -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.Restrictions</Name>
<BitAddress>153</BitAddress>
<BitWidth>16</BitWidth>
<!-- 0 = No Restrictions; restriction ID defined on central server (valid season, days, time, ...) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.TicketID</Name>
<BitAddress>169</BitAddress>
<BitWidth>32</BitWidth>
<!-- unique ticket/product identifier -->
<!-- has to match with Region, UsageDomain, Duration, Unit, Restriction and UserType -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.Price</Name>
<BitAddress>201</BitAddress>
<BitWidth>23</BitWidth>
<!-- tariff in 1/100 Root.Currency units -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.UserID</Name>
<BitAddress>224</BitAddress>
<BitWidth>56</BitWidth>
<!-- unique user ID (this is a bitfield, upper 13 bits contain the region, middle 11 bits contain workstation ID, lower 32 bit contain a local ID) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.UserType</Name>
<BitAddress>280</BitAddress>
<BitWidth>8</BitWidth>
<!-- only used for visualization on gate, e.g. Adult, child, senior, ... -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.TargetRegion</Name>
<BitAddress>288</BitAddress>
<BitWidth>13</BitWidth>
<!-- region for interpretation of UsageDomain, TicketID, Restrictions (typically same as Root.Region) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.DateIssued</Name>
<BitAddress>301</BitAddress>
<BitWidth>14</BitWidth>
<!-- date when the ticket has been sold; used for identification of e.g. pre-selling of season passes ... -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.TimeIssued</Name>
<BitAddress>315</BitAddress>
<BitWidth>11</BitWidth>
<!-- time when the ticket has been sold; used for identification of e.g. 'gestaffelten Tageskarten' -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.CurrencyCode</Name>
<BitAddress>326</BitAddress>
<BitWidth>15</BitWidth>
<!-- ISO 4217 alphanumeric currency code converted to 3*5 bit numeric value ('A'=0x00, 'B'=0x01, ...) -->
<!-- e.g. 'EUR': 'E' (0x04) + 'U' (0x14) + 'R' (0x11) -> Root.CurrencyCode = 001001010010001b = 0x1291) -->
</TokenAllocation>
</FixedArea>
<VariableArea>
<!-- ********* START of VARIABLE AREA ********** -->
<TokenAllocation>
<Name>Root.BlockCRC</Name>
<BitAddress>0</BitAddress>
<BitWidth>16</BitWidth>
<!-- CRC calculated from this token until the next Root.BlockCRC -->
<!-- (CRC calculated from BitAddress 0-63) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.Initialized</Name>
<BitAddress>16</BitAddress>
<BitWidth>1</BitWidth>
</TokenAllocation>
<TokenAllocation>
<Name>Root.TicketState</Name>
<BitAddress>17</BitAddress>
<BitWidth>2</BitWidth>
<!-- 0 = Valid, 1 = Cancelled, 2 = Refunded -->
<!-- Note: this value needs to be evaluated by each vendor, even if it is not set by all vendors; gate must only be opened if ticket state is 0! -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.DateOfFirstEntry</Name>
<BitAddress>19</BitAddress>
<BitWidth>14</BitWidth>
<!-- date of first usage (days since 1/1/2008) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.TimeOfFirstEntry</Name>
<BitAddress>33</BitAddress>
<BitWidth>11</BitWidth>
<!-- time of first usage (minutes since midnight) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.Reserved</Name>
<BitAddress>44</BitAddress>
<BitWidth>20</BitWidth>
<!-- padding to match chip block boundary -->
</TokenAllocation>
<!-- ********* START of SHADOW A ********** -->
<TokenAllocation>
<Name>Root.BlockCRCA</Name>
<BitAddress>64</BitAddress>
<BitWidth>6</BitWidth>
<!-- (CRC calculated from BitAddress 64-95) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.CurrentDayA</Name>
<BitAddress>70</BitAddress>
<BitWidth>12</BitWidth>
<!-- last usage of the ticket (days since Root.DateOfFirstEntry) -->
<!-- required field -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.RemainingDurationA</Name>
<BitAddress>82</BitAddress>
<BitWidth>14</BitWidth>
<!-- remaing duration -->
</TokenAllocation>
<!-- ********* PADDING ********** -->
<TokenAllocation>
<Name>Root.BlockCRCP</Name>
<BitAddress>96</BitAddress>
<BitWidth>32</BitWidth>
<!-- dummy entry: used for padding to match chip block boundary (on 64bit chips) -->
<!-- (CRC calculated from BitAddress 96-127) -->
</TokenAllocation>
<!-- ********* START of SHADOW B ********** -->
<TokenAllocation>
<Name>Root.BlockCRCB</Name>
<BitAddress>128</BitAddress>
<BitWidth>6</BitWidth>
<!-- (CRC calculated from BitAddress 128-159) -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.CurrentDayB</Name>
<BitAddress>134</BitAddress>
<BitWidth>12</BitWidth>
<!-- last usage of the ticket (days since Root.DateOfFirstEntry) -->
<!-- required field -->
</TokenAllocation>
<TokenAllocation>
<Name>Root.RemainingDurationB</Name>
<BitAddress>146</BitAddress>
<BitWidth>14</BitWidth>
<!-- remaing duration -->
</TokenAllocation>
</VariableArea>
</FormatDefinition>