summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--misc/dynamicContentFDCv1.0.asn115
-rw-r--r--misc/headerSpec.asn5
-rw-r--r--misc/uicBarcodeFCBv2.0.1.asn4
-rw-r--r--misc/uicBarcodeFCBv2.0.2.asn6
-rw-r--r--misc/uicBarcodeFCBv2.0.asn774
-rw-r--r--misc/uicBarcodeV1finalDelayConfirmation1.3.1.asn2
-rw-r--r--misc/uicBarcodeV1finalDelayConfirmation1.3.asn2
-rw-r--r--pom.xml132
-rw-r--r--src/main/java/org/uic/barcode/Encoder.java18
-rw-r--r--src/main/java/org/uic/barcode/dynamicContent/fdc1/ExtensionData.java59
-rw-r--r--src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoCoordinateSystemType.java57
-rw-r--r--src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoCoordinateType.java144
-rw-r--r--src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoUnitType.java65
-rw-r--r--src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLatitudeType.java56
-rw-r--r--src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLongitudeType.java55
-rw-r--r--src/main/java/org/uic/barcode/dynamicContent/fdc1/SequenceOfExtension.java11
-rw-r--r--src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java144
-rw-r--r--src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java205
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/Constants.java2
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java19
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java4
-rw-r--r--src/main/java/org/uic/barcode/staticFrame/StaticFrame.java9
-rw-r--r--src/main/java/org/uic/barcode/staticFrame/UHEADDataRecord.java2
-rw-r--r--src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java2
-rw-r--r--src/test/java/org/uic/barcode/test/utils/TestUtils.java35
-rw-r--r--src/test/java/org/uic/barcode/ticketTestDB/DecodeSparpreisTicketDBTest.java2
-rw-r--r--src/test/java/org/uic/barcode/ticketTestDB/EncodeSparpreisTicketDBTest.java121
-rw-r--r--src/test/java/org/uic/barcode/ticketTestDB/SignatureValidationDBTicketTest.java2
28 files changed, 1957 insertions, 95 deletions
diff --git a/misc/dynamicContentFDCv1.0.asn b/misc/dynamicContentFDCv1.0.asn
new file mode 100644
index 0000000..693980f
--- /dev/null
+++ b/misc/dynamicContentFDCv1.0.asn
@@ -0,0 +1,115 @@
+-- ##########################################################################################
+-- #
+-- # FCB Dynamic Content - Version 1.0 - Draft #3 (2021-05-12)
+-- #
+-- # This file is available on the UIC FCB User Group GitHub:
+-- # <GitHub-link-to-be-added-here>
+-- # Please check this link to see if a more recent version of this file is available.
+-- #
+-- # The type UicDynamicContentData defined below is at least intended to generate a data
+-- # that, once valued and encoded as PER unaligned [UPER],
+-- # is to be stored in UicBarcodeHeader.level2SignedData.level2Data.data,
+-- # and identified as "FDC1" in UicBarcodeHeader.level2SignedData.level2Data.dataFormat.
+-- #
+-- ##########################################################################################
+ UicDynamicContentData ::= SEQUENCE {
+
+ -- Identification of the mobile application that generated the barcode
+ -- and filled in the data of its dynamic part.
+ --
+ -- The possible values are defined by the security provider
+ -- (the security provider being UicBarcodeHeader.level2SignedData.level1Data.securityProviderNum/IA5)
+ dynamicContentMobileAppId IA5String OPTIONAL,
+
+ -- Moment of generation of the dynamic content, expressed in UTC
+ dynamicContentTimeStamp TimeStampData OPTIONAL,
+
+ -- Coordinates of the place where the dynamic content has been generated
+ -- (same GeoCoordinateType type as in UicRailTicketData)
+ dynamicContentGeoCoordinate GeoCoordinateType OPTIONAL,
+
+ -- Response from the mobile to any data received from the terminal.
+ -- The data received from the terminal may be a random number, or any other information.
+ -- The response may be the received data itself, possibly completed with other information
+ -- (e.g. IMEI, mobile phone number, user identifier assigned by the phone-app...),
+ -- the whole being returned as is, or hashed, or modified in some way.
+ --
+ -- The type used is a SEQUENCE OF ExtensionData
+ -- (the same ExtensionData type as in UicRailTicketData, as it is fully adapted),
+ -- in which extensionId identifies the content of extensionData.
+ --
+ -- Two types of value are possible for extensionId:
+ -- * predefined standardized values
+ -- (e.g. "=" if extensionData is exactly the data received from the terminal)
+ -- The list of predefined values is available on the UIC FCB User Group GitHub.
+ -- * "_" followed by any other value, defined by the security provider, in other cases.
+ -- (the security provider being UicBarcodeHeader.level2SignedData.level1Data.securityProviderNum/IA5)
+ dynamicContentResponseToChallenge SEQUENCE OF ExtensionData OPTIONAL,
+
+ -- Proprietary data defined bilaterally
+ -- (same ExtensionData type as in UicRailTicketData).
+ -- extensionId identifies the content of extensionData,
+ -- it shall be set to "_" + RICS + addon chosen by the issuer identified by its RICS code
+ dynamicContentExtension ExtensionData OPTIONAL,
+
+ ...
+ }
+
+ -- ##########################################################################################
+ -- # Generic type for timestamp, with a precision to the second.
+ -- #
+ -- # Day is the number of the day in the year (1 = January 1st, 2 = January 2nd...)
+ -- #
+ -- # Time is the number of seconds of the day (from 0 = 0:00:00 to 86399 = 23:59:59)
+ -- ##########################################################################################
+ TimeStampData ::= SEQUENCE {
+ day INTEGER (1..366),
+ time INTEGER (0..86399)
+ }
+
+ -- ##########################################################################################
+ -- # Generic type for geo coordinates.
+ -- ##########################################################################################
+ GeoCoordinateType ::= SEQUENCE {
+ geoUnit GeoUnitType DEFAULT milliDegree,
+ coordinateSystem GeoCoordinateSystemType DEFAULT wgs84,
+ hemisphereLongitude HemisphereLongitudeType DEFAULT north, -- separate hemisphere flag reduces the data size
+ hemisphereLatitude HemisphereLatitudeType DEFAULT east, -- separate hemisphere flag reduces the data size
+ longitude INTEGER,
+ latitude INTEGER,
+ accuracy GeoUnitType OPTIONAL
+ }
+
+ GeoCoordinateSystemType ::= ENUMERATED {
+ wgs84 (0), -- WGS 84 standard system
+ grs80 (1) -- (outdated) GRS 80 coordinate system
+ }
+
+ GeoUnitType ::= ENUMERATED {
+ microDegree (0), -- approx. 11 cm on earth surface
+ tenthmilliDegree (1), -- 1 / 10000 degree is approx. 11 meter on earth surface
+ milliDegree (2), -- approx 110 meter on earth surface
+ centiDegree (3),
+ deciDegree (4)
+ }
+
+ HemisphereLongitudeType ::= ENUMERATED {
+ north (0),
+ south (1)
+ }
+
+ HemisphereLatitudeType ::= ENUMERATED {
+ east (0),
+ west (1)
+ }
+
+ -- ###########################################################################################
+ -- # Generic extension element.
+ -- #
+ -- # extensionId identifies the content of extensionData.
+ -- ###########################################################################################
+ ExtensionData ::= SEQUENCE {
+ extensionId IA5String,
+ extensionData OCTET STRING
+ }
+ \ No newline at end of file
diff --git a/misc/headerSpec.asn b/misc/headerSpec.asn
index 3fe6b15..77aef50 100644
--- a/misc/headerSpec.asn
+++ b/misc/headerSpec.asn
@@ -29,7 +29,7 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN
-- # the format is kept more flexible to cover upcoming extensions of the RICS code by ERA
-- #
-- #
--- # - A bar code which is only static (printed on a paper), and for which the security is in the system, doesn’t need any of these elements.
+-- # - A bar code which is only static (printed on a paper), and for which the security is in the system, doesn’t need any of these elements.
-- # - A bar code which is only static, and includes its own security, needs:
-- # level1Signature
-- # level1KeyAlg if the associated key does not include the complete certificate in keys.xml but only the public key
@@ -114,6 +114,3 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN
dataFormat IA5String,
data OCTET STRING
}
-
-
-END \ No newline at end of file
diff --git a/misc/uicBarcodeFCBv2.0.1.asn b/misc/uicBarcodeFCBv2.0.1.asn
index 33ff0d7..8589f5a 100644
--- a/misc/uicBarcodeFCBv2.0.1.asn
+++ b/misc/uicBarcodeFCBv2.0.1.asn
@@ -1998,7 +1998,7 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN
GeoUnitType ::= ENUMERATED {
microDegree (0), -- approx. 11 cm on earth surface
- tenthmilliDegree (1), -- 1 / 100000 degree is approx. 1.1 meter on earth surface
+ tenthmilliDegree (1), -- 1 / 10000 degree is approx. 11 meter on earth surface
milliDegree (2), -- approx 110 meter on earth surface
centiDegree (3),
deciDegree (4)
@@ -2038,5 +2038,3 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN
otherRack (8)
,...
}
-
-END \ No newline at end of file
diff --git a/misc/uicBarcodeFCBv2.0.2.asn b/misc/uicBarcodeFCBv2.0.2.asn
index 048f600..5d590df 100644
--- a/misc/uicBarcodeFCBv2.0.2.asn
+++ b/misc/uicBarcodeFCBv2.0.2.asn
@@ -868,7 +868,7 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN
-- in case no UTC offset is provided (RECOMMENDED) the local date time in the time zone of the current location of the traveler
-- offset in units of 15 minutes from local time to UTC
-- (UTC = local + offset * 15 Minutes)
- validFromUTCOffset INTEGER (-60..60) OPTIONAL,
+ validFromUTCOffset INTEGER (-60..60) OPTIONAL,
-- end of validity (local time)
-- number of days from valid from day, 0 = valid on valid-from-date
@@ -2069,7 +2069,7 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN
GeoUnitType ::= ENUMERATED {
microDegree (0), -- approx. 11 cm on earth surface
- tenthmilliDegree (1), -- 1 / 100000 degree is approx. 1.1 meter on earth surface
+ tenthmilliDegree (1), -- 1 / 10000 degree is approx. 11 meter on earth surface
milliDegree (2), -- approx 110 meter on earth surface
centiDegree (3),
deciDegree (4)
@@ -2109,5 +2109,3 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN
otherRack (8)
,...
}
-
-END \ No newline at end of file
diff --git a/misc/uicBarcodeFCBv2.0.asn b/misc/uicBarcodeFCBv2.0.asn
index ec4ec2c..bfb0969 100644
--- a/misc/uicBarcodeFCBv2.0.asn
+++ b/misc/uicBarcodeFCBv2.0.asn
@@ -1996,7 +1996,7 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN
GeoUnitType ::= ENUMERATED {
microDegree (0), -- approx. 11 cm on earth surface
- tenthmilliDegree (1), -- 1 / 100000 degree is approx. 1.1 meter on earth surface
+ tenthmilliDegree (1), -- 1 / 10000 degree is approx. 11 meter on earth surface
milliDegree (2), -- approx 110 meter on earth surface
centiDegree (3),
deciDegree (4)
@@ -2037,4 +2037,774 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN
,...
}
-END \ No newline at end of file
+=======
+-- Creator: ASN.1 Editor (http://asneditor.sourceforge.net)
+-- Author: ClemensGantert
+-- Created: Tue Aug 11 11:40:28 CEST 2015
+ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN
+
+-- imports and exports
+-- EXPORTS ALL;
+
+
+-- changes:
+-- product id 1 bit more 65535
+-- open ticket transport mode EN 1545-1
+-- allowing -1 in differences of days between dates (validity of tickets crossing time zones)
+
+-- ##############################################################################################
+-- #
+-- # Draft version 2.0 - value 2 in the UIC bar code version element
+-- # (see element 2 in U_FLEX record definition in leaflet 918.9)
+-- #
+-- ##############################################################################################
+
+
+-- ##############################################################################################
+-- #
+-- # Naming and encoding conventions
+-- #
+-- # Elements included as String and as Numeric values:
+-- # Some elements are included in different formats to reduce the data size.
+-- # These elements must be included only once.
+-- # These elements are named with the same name and appendix
+-- # Num (numeric values)
+-- # IA5 (String values according to ASN IA5String (7Bit))
+-- # Example:
+-- # trainNum - in case of a numeric train number
+-- # trainIA5 - in case of a alphanumeric train Id
+-- #
+-- #
+-- # RICS codes must be used to encode companies (issuer, product owner, ...) where available
+-- # other codes are possible based on bilateral agreements
+-- # the format is kept more flexible to cover upcoming extensions of the RICS code by ERA
+-- #
+-- # Stations can be coded using the UIC and upcoming ERA code lists. Proprietary codes are
+-- # possible based on bilateral agreements. Format: 1..9999999 or alphanumeric without
+-- # special character (IA5String)
+-- #
+-- #
+-- # ! INTEGERS must not exceed the value of 9,223,372,036,854,775,807 (64 bit) even in case
+-- # ! they are unrestricted!!!
+-- # !
+-- # ! Some elements like ReferenceNum or cardIdNum are defined as an unrestricted integer.
+-- # ! Unlike other numerical values the cardIdNum and referenceNum can be larger than a usual 32 bit Integer
+-- # ! Some ASN.1 implementation tools are limited to 32 bit integers which is too small.
+-- # ! Please ensure to use a tool capable of dealing with larger numbers.
+-- #
+-- # Optional BOOLEANs have three values: "true", "false", "unknown" = the Boolean is absent from the data.
+-- #
+-- #
+-- # Encoding of time:
+-- # time is encoded as the number of minutes of the day 0 = 00:00, 1439 = 23:59,
+-- # time data elements end with "time" in their name
+-- #
+-- # Encoding of date:
+-- # .........................................................................................................
+-- # The issuing date is given in UTC, but some other date values are given in local time where the exact time zone is not known.
+-- #
+-- # For local dates the date is associated with the corresponding location:
+-- # e.g.:
+-- # valid from date -> location where the journey starts
+-- # valid until date -> location where the journey covered by the ticket ends
+-- #
+-- # there could be rare cases where this does not provide a unique interpretation:
+-- # e.g. open ticket or pass without start and end location for a collection of zones or countries with different time zones.
+-- # in these cases the fare conditions must clarify the rules for these cases (e.g. by allowing to use the
+-- # ticket a few hours after the end of validity).
+-- #
+-- # The difference in days is calculated from dates only, ignoring the time and time zone information.
+-- #
+-- # example 1: (31.12.2017 23:05 UTC == 01.01.2018 00:05 CET) :
+-- # issuing date (UTC): 31.12.2017 23:05 == 01.01.2018 00:05 CET
+-- # issuingYear = 2017
+-- # issuingDay = 365
+-- # issuingTime = 1385
+-- # local departure date (CET): 01.01.2018 00:15 == 31.12.2017 23:15 UTC
+-- # departureDate = 1 (= 01.01.2018 - 31.12.2017)
+-- # departureTime = 15
+-- # departureUTCOffset = -4 (UTC = local + offset * 15 Minutes)
+-- #
+-- #
+-- # example 2: (01.01.2018 00:05 UTC == 31.12.2017 20:05 AST)
+-- # issuing date (UTC): 01.01.2018 00:05 UTC == 31.12.2017 20:05 AST
+-- # issuingYear = 2018
+-- # issuingDay = 1
+-- # issuingTime = 5
+-- # local departure date (AST): 31.12.2017 22:05 AST == 1.1.2018 02:05 UTC
+-- # departureDate = -1 (= 31.12.2017 - 01.01.2018)
+-- # departureTime = 1325
+-- # departureUTCOffset = 16 (UTC = local + offset * 15 Minutes)
+-- #
+-- # departureDate can become -1 with a departure west of the GMT zone only
+-- #
+-- #
+-- #
+-- #
+-- #
+-- #
+-- # ASN.1 Extensions:
+-- #
+-- # The specification makes use of extension (",...").
+-- # These extensions might be defined in future versions of the UIC specification
+-- # Implementations must support the extension feature of ASN.1, at least they must be able to ignore extensions while decoding the data
+-- # ASN.1 extensions will be defined by UIC. It is not allowed to define bilateral extensions.
+-- #
+-- # Bilateral Extensions:
+-- # Bilateral extensions can be included in the data element "ExtensionData".
+-- #
+-- #
+-- #
+-- #########################################################################################
+
+
+-- ############################################################################################
+
+
+-- type assignments
+
+ -- #########################################################################################
+ -- the basic entry point of the data structure
+ -- the data include:
+ -- -issuer informations
+ -- -the details of the transport document
+ -- -informations required for the control process
+ -- -informations on the travelers independent from the transport document
+ -- -proprietary extensions
+ --
+ -- ##########################################################################################
+ UicRailTicketData ::= SEQUENCE {
+ -- data specific to the issuer
+ issuingDetail IssuingData,
+
+ -- data on the travelers
+ travelerDetail TravelerData OPTIONAL,
+
+ -- data of the transport document
+ --!!! proposal: replace this by a comment in the lealet on the total size of the barcode: more than one document to be used on bilateral agreement only
+ transportDocument SEQUENCE OF DocumentData OPTIONAL,
+
+ -- data specific to support the ticket control process
+ controlDetail ControlData OPTIONAL,
+
+ -- proprietary data defined bilaterally
+ extension SEQUENCE OF ExtensionData OPTIONAL
+ ,...
+ }
+
+
+
+ -- ###########################################################################################
+ -- the choice on the different transport documents that can be included in the bar code data:
+ -- - reservation of seat / couchette or berths (IRT, RES, BOA)
+ -- - reservation of car carriage (VET)
+ -- - open ticket (NRT including NRT group ticket) (NRT, GRT, SUP, UPD, COI)
+ -- - Rail passes (including Eurail, Interail and local passes) (RPT)
+ -- - Voucher (TRV)
+ -- - Customer Cards (including bonus cards and reduction cards)
+ -- - counter marks issued for group tickets
+ -- - parking ground tickets
+ -- - FIP tickets
+ -- - station access / station passage tickets
+ -- - proprietary documents as an extension
+ -- ############################################################################################
+ DocumentData ::= SEQUENCE {
+
+ -- token
+ -- specific id to be exchanged with the ticket (e.g. id of the phone in case of tickets linked to a phone)
+ token TokenType OPTIONAL,
+
+ -- choice of the ticket
+ ticket CHOICE
+ {
+
+ -- Reservation (without car carriage) (IRT and RES)
+ reservation ReservationData,
+
+
+ -- Reservation of car carriage
+ carCarriageReservation CarCarriageReservationData,
+
+ -- open ticket specification (NRT)
+ openTicket OpenTicketData,
+
+ -- pass specification (RPT) including Eurail and Interrail
+ pass PassData,
+
+ -- voucher
+ voucher VoucherData,
+
+ -- customer card either to identify a customer and / or to provide reductions
+ customerCard CustomerCardData,
+
+ -- countermark to accompagny a group ticket
+ counterMark CountermarkData,
+
+ -- car parking slot
+ parkingGround ParkingGroundData,
+
+ -- FIP duty ticket
+ fipTicket FIPTicketData,
+
+ -- ticket to pass the gates at a station
+ stationPassage StationPassageData,
+
+ -- proprietary data defined bilaterally
+ extension ExtensionData,
+
+ -- delay confirmation
+ delayConfirmation DelayConfirmation
+
+ ,...
+ }
+ ,...
+ }
+
+ -- ########################################################################################
+ -- confirmation of the delay of a train
+ --
+ -- ########################################################################################
+ DelayConfirmation ::= SEQUENCE {
+
+ -- reference of the delay confirmation
+ referenceIA5 IA5String OPTIONAL,
+ referenceNum INTEGER OPTIONAL,
+
+ -- train number of the delayed train - numeric or alphanumeric
+ trainNum INTEGER OPTIONAL,
+ trainIA5 IA5String OPTIONAL,
+
+ -- departure date of the delayed train in local time
+ -- number of year
+ departureYear INTEGER (2016..2269) OPTIONAL,
+ -- number of the day in the year (1.1. = 1)
+ departureDay INTEGER (1..366) OPTIONAL,
+ departureTime INTEGER (0..1439) OPTIONAL,
+ departureUTCOffset INTEGER (-60..60) OPTIONAL, -- offset in units of 15 minutes from local time to UTC
+ -- (UTC = local + offset * 15 Minutes)
+
+
+ -- station where the delay became relevant
+ stationCodeTable CodeTableType DEFAULT stationUIC,
+ stationNum INTEGER (1..9999999) OPTIONAL,
+ stationIA5 IA5String OPTIONAL,
+
+ -- delay in minutes at the mentioned station
+ delay INTEGER (1..999),
+
+ -- indication that the train was cancelled
+ trainCancelled BOOLEAN,
+
+ -- type of confirmation provided
+ confirmationType ConfirmationType DEFAULT travelerDelayConfirmation,
+
+ -- affected original ticket(s)
+ affectedTickets SEQUENCE OF TicketLinkType OPTIONAL,
+
+ -- info text
+ infoText UTF8String OPTIONAL,
+
+ -- proprietary data defined bilaterally
+ extension ExtensionData OPTIONAL
+ ,...
+ }
+
+ ConfirmationType ::= ENUMERATED {
+ trainDelayConfirmation (0), -- confirmation of train delay, whether the traveler was on board in unconfirmed
+ travelerDelayConfirmation (1), -- confirmation that the traveler was on board of the delayed train
+ trainLinkedTicketDelay (2) -- confirmation that a ticket linked to the delayed train was issued
+ ,...
+ }
+
+
+ -- ########################################################################################
+ -- Details of the issuer and the issue of the ticket
+ -- - details on the issuer
+ -- - indication of test tickets (specimen)
+ -- - payment details: method of payment, currency
+ -- - proprietary PNR of the issuer to be used to identify the sale within
+ -- the issuers ecosystem
+ -- - web link to display more information for the customer
+ -- - proprietary extension data
+ -- ########################################################################################
+ IssuingData ::= SEQUENCE {
+
+ -- provider of the signature (RICS code)
+ securityProviderNum INTEGER (1..32000) OPTIONAL,
+ securityProviderIA5 IA5String OPTIONAL,
+
+ -- issuer of the transport document if the issuer is different from the security provider
+ -- (RICS code)
+ issuerNum INTEGER (1..32000) OPTIONAL,
+ issuerIA5 IA5String OPTIONAL,
+
+ -- issuing time stamp in UTC
+ -- number of year
+ issuingYear INTEGER (2016..2269),
+ -- number of the day in the year (1.1. = 1)
+ issuingDay INTEGER (1..366),
+ -- The number of the minutes of issue might be used in case of account
+ -- based ticketing with a delay of n minutes for the replication of central
+ -- booking data to the control devices (e.g. at SBB)
+ -- The time can be compared with the last synchronization time of
+ -- the control device
+ issuingTime INTEGER (0..1439) OPTIONAL,
+
+ -- name of the issuer (E.g. short name mentioned in RICS code table)
+ issuerName UTF8String OPTIONAL,
+
+ -- specimen indicates a test specimen not valid for travelling
+ specimen BOOLEAN,
+
+ -- secure paper indicates that this barcode is issued with a secure paper ticket
+ -- to ensure the uniqueness of the ticket. This allows to use the same control
+ -- procedure as for e-tickets also for anonymous tickets
+ -- the double use of the ticket is in this case excluded by the secure paper
+ securePaperTicket BOOLEAN,
+
+ -- indicates that the ticket is valid for traveling or still needs activation
+ activated BOOLEAN,
+
+ -- currency of the price: ISO4217 currency codes
+ currency IA5String (SIZE(3)) DEFAULT "EUR",
+
+ -- fraction of the prices included
+ currencyFract INTEGER (1..3) DEFAULT 2,
+
+ -- PNR used by the issuer to identify the document
+ issuerPNR IA5String OPTIONAL,
+
+ -- proprietary data defined bilaterally
+ extension ExtensionData OPTIONAL,
+
+ -- location of sale in case of a sale on board of a train
+ -- numeric train number or alphanumeric id of the train where the ticket was sold
+ issuedOnTrainNum INTEGER OPTIONAL,
+ issuedOnTrainIA5 IA5String OPTIONAL,
+ -- line number
+ issuedOnLine INTEGER OPTIONAL,
+
+ -- point of sale
+ pointOfSale GeoCoordinateType OPTIONAL
+ ,...
+ }
+
+ -- ###################################################################################
+ -- data supporting the control process
+ -- - list of items which the traveler can use to identify himself or the unique
+ -- usage of the ticket
+ -- (card ids, parts or identity card numbers, credit card numbers,..)
+ -- - hints on the validation to be made on board
+ --
+ -- ###################################################################################
+ ControlData ::= SEQUENCE {
+
+ -- cards that can be used to identify the ticket holder
+ identificationByCardReference SEQUENCE OF CardReferenceType OPTIONAL,
+
+ -- id-card id must be checked to identify the traveler
+ identificationByIdCard BOOLEAN,
+
+ -- passport id must be checked to identify the traveler
+ identificationByPassportId BOOLEAN,
+
+ -- other items which could be used to identify the ticket holder
+ -- (for future use, code list to be defined)
+ identificationItem INTEGER OPTIONAL,
+
+ -- validation of the passport is required (e.g. in case of Eurail)
+ passportValidationRequired BOOLEAN,
+
+ -- online validation of the ticket required
+ onlineValidationRequired BOOLEAN,
+
+ -- percentage of the tickets to be validated in more detail
+ -- (i.e. via online check or detailed checks later-on)
+ randomDetailedValidationRequired INTEGER (0..99) OPTIONAL,
+
+ -- manual validation of the traveler age required (in case of reductions)
+ ageCheckRequired BOOLEAN,
+
+ -- manual validation of the travelers reduction card required (in case of reductions)
+ reductionCardCheckRequired BOOLEAN,
+
+ -- controler info text
+ infoText UTF8String OPTIONAL,
+
+ -- additional tickets that should be controlled
+ includedTickets SEQUENCE OF TicketLinkType OPTIONAL,
+
+ -- proprietary data defined bilaterally
+ extension ExtensionData OPTIONAL
+ ,...
+ }
+
+ -- ################################################################################
+ -- Traveler data
+ -- these data do not include tariff details of the booked tariffs,
+ -- tariff data are included in the transport document details and might
+ -- have a reference to the traveler defined here.
+ -- - personal data of the travellers
+ -- - the index of the list can be used to identify the
+ -- traveler within other contexts (e.g. in assigned tariffs)
+ -- ################################################################################
+ TravelerData ::= SEQUENCE {
+ -- traveler list
+ traveler SEQUENCE OF TravelerType OPTIONAL,
+
+ -- ISO 639-1 coding of the language preferred for the traveler / ticket holder
+ preferredLanguage IA5String (SIZE(2)) OPTIONAL,
+
+ -- name of the group in case of a group ticket
+ groupName UTF8String OPTIONAL
+ ,...
+ }
+
+ -- ####################################################################################
+ -- the following part contains the different transport document specifications
+ -- ####################################################################################
+
+
+ -- ####################################################################################
+ -- reservations of seats , couchettes and berths
+ -- included are the data defined in:
+ -- - leaflet 918.1 for reservation data exchange
+ -- - a few additional data currently used by some railways via different interfaces
+ -- - information on trach an dplafoorm where the coach stops
+ -- - additional second coach for large groups
+ -- ####################################################################################
+ ReservationData ::= SEQUENCE {
+
+ -- train number - numeric or alphanumeric
+ trainNum INTEGER OPTIONAL,
+ trainIA5 IA5String OPTIONAL,
+
+ -- departure date in local time
+ -- number of the days calculated from the issuing date
+ departureDate INTEGER (-1..370) DEFAULT 0,
+
+
+ -- reservation reference according ton 918.1 in case ade via Hermes
+ referenceIA5 IA5String OPTIONAL,
+ referenceNum INTEGER OPTIONAL,
+
+ -- organization responsible for the product definition
+ -- (RICS Code to be used as standard)
+ productOwnerNum INTEGER (1..32000) OPTIONAL,
+ productOwnerIA5 IA5String OPTIONAL,
+
+ -- product id to identify the issued product codelist defined by the product owner
+ -- !!! productIdNum extended
+ productIdNum INTEGER (0..65535) OPTIONAL,
+ productIdIA5 IA5String OPTIONAL,
+
+ -- service brand: code list https://uic.org/service-brand-code-list
+ serviceBrand INTEGER (0..32000) OPTIONAL,
+ serviceBrandAbrUTF8 UTF8String OPTIONAL,
+ serviceBrandNameUTF8 UTF8String OPTIONAL,
+
+ -- service code list from 918.1 (seat couchette,..)
+ service ServiceType DEFAULT seat,
+
+ -- code table used to encode stations
+ stationCodeTable CodeTableType DEFAULT stationUICReservation,
+
+ -- origin station code
+ fromStationNum INTEGER (1..9999999) OPTIONAL,
+ fromStationIA5 IA5String OPTIONAL,
+
+ -- destination station code
+ toStationNum INTEGER (1..9999999) OPTIONAL,
+ toStationIA5 IA5String OPTIONAL,
+
+ -- origin station name
+ fromStationNameUTF8 UTF8String OPTIONAL,
+
+ -- destination station name
+ toStationNameUTF8 UTF8String OPTIONAL,
+
+ -- departure time
+ departureTime INTEGER (0..1439),
+ departureUTCOffset INTEGER (-60..60) OPTIONAL, -- offset in units of 15 minutes from local time to UTC
+ -- (UTC = local + offset * 15 Minutes)
+
+ -- arrival date and time in local time
+ -- number of days counted from the departure date
+ -- !!! proposal for change: arrivalDate INTEGER (-1..20) DEFAULT 0,
+ arrivalDate INTEGER (-1..20) DEFAULT 0,
+ arrivalTime INTEGER (0..1439) OPTIONAL,
+ arrivalUTCOffset INTEGER (-60..60) OPTIONAL, -- offset in units of 15 minutes from local time to UTC
+ -- (UTC = local + offset * 15 Minutes)
+ -- should be omitted in case it is the same as for departure
+
+ -- responsible carriers on the route
+ carrierNum SEQUENCE OF INTEGER (1..32000) OPTIONAL,
+ carrierIA5 SEQUENCE OF IA5String OPTIONAL,
+
+ -- travel class
+ classCode TravelClassType DEFAULT second,
+
+ -- service level code list from 918.1
+ serviceLevel IA5String (SIZE(1..2)) OPTIONAL,
+
+ -- places
+ places PlacesType OPTIONAL,
+
+ -- additional places in a second coach
+ additionalPlaces PlacesType OPTIONAL,
+
+ --bicycle places
+ bicyclePlaces PlacesType OPTIONAL,
+
+ -- compartment details (open space, wheelchair,..)
+ compartmentDetails CompartmentDetailsType OPTIONAL,
+
+ -- number of persons on the ticket without place numbers (on IRT)
+ numberOfOverbooked INTEGER (0..200) DEFAULT 0,
+
+ -- description of berths
+ berth SEQUENCE OF BerthDetailData OPTIONAL,
+
+ -- tariffs included (Adult, Children,... )
+ tariff SEQUENCE OF TariffType OPTIONAL,
+
+ -- type of the price (supplement,... )
+ priceType PriceTypeType DEFAULT travelPrice,
+
+ price INTEGER OPTIONAL,
+
+ vatDetail SEQUENCE OF VatDetailType OPTIONAL,
+
+ -- type of supplement - code list from 918.1
+ typeOfSupplement INTEGER (0..9) DEFAULT 0,
+
+ numberOfSupplements INTEGER (0..200) DEFAULT 0,
+
+ -- luggage restrictions and registered luggage
+ -- in case the luggage restrictions are general and do not depend on the
+ -- ticket type they should not be included
+ luggage LuggageRestrictionType OPTIONAL,
+
+ infoText UTF8String OPTIONAL,
+
+
+ -- bilaterally agreed proprietary extension
+ extension ExtensionData OPTIONAL
+ ,...
+ }
+
+ -- #################################################################################
+ -- details on the VAT included to be used in after sale processes
+ -- #################################################################################
+ VatDetailType ::= SEQUENCE {
+
+ -- ISO 3166 numeric country code
+ country INTEGER (1..999),
+
+ -- 1/10th of a percent
+ percentage INTEGER (0..999),
+
+ -- amount of VAT, the currency and the currency fraction is included in the issuing data
+ amount INTEGER OPTIONAL,
+
+ -- european tax id of the company paying VAT
+ vatId IA5String OPTIONAL
+
+ }
+
+
+ -- #################################################################################
+ -- reservations of car carriage
+ -- included are the data defined in:
+ -- - leaflet 918.1 for reservation data exchange
+ -- - a few additional data currently used by some railways via different interfaces
+ -- #################################################################################
+ CarCarriageReservationData ::= SEQUENCE {
+
+ trainNum INTEGER OPTIONAL,
+ trainIA5 IA5String OPTIONAL,
+
+
+ -- loading / unloading of the car in local date and time
+ -- number of the days calculated from the issuing date
+ beginLoadingDate INTEGER (-1..370) DEFAULT 0,
+ beginLoadingTime INTEGER (0..1439) OPTIONAL,
+ endLoadingTime INTEGER (0..1439) OPTIONAL,
+ loadingUTCOffset INTEGER (-60..60) OPTIONAL, -- offset in units of 15 minutes from local time to UTC
+ -- (UTC = local + offset * 15 Minutes)
+
+
+ -- reservation reference according on 918.1 in case ade via Hermes
+ referenceIA5 IA5String OPTIONAL,
+ referenceNum INTEGER OPTIONAL,
+
+ -- organization responsible for the product definition
+ -- (RICS Code / proprietary code in case no RICS code is defined, proprietary codes must ensure to be unique)
+ productOwnerNum INTEGER (1..32000) OPTIONAL,
+ productOwnerIA5 IA5String OPTIONAL,
+
+ -- product id to identify the issued product codelist defined by the product owner
+ -- !!! productIdNum extended
+ productIdNum INTEGER (0..65535) OPTIONAL,
+ productIdIA5 IA5String OPTIONAL,
+
+ -- service brand: code list https://uic.org/service-brand-code-list
+ serviceBrand INTEGER (1..32000) OPTIONAL,
+ serviceBrandAbrUTF8 UTF8String OPTIONAL,
+ serviceBrandNameUTF8 UTF8String OPTIONAL,
+
+ stationCodeTable CodeTableType DEFAULT stationUICReservation,
+
+ fromStationNum INTEGER (1..9999999) OPTIONAL,
+ fromStationIA5 IA5String OPTIONAL,
+
+ toStationNum INTEGER (1..9999999) OPTIONAL,
+ toStationIA5 IA5String OPTIONAL,
+
+ fromStationNameUTF8 UTF8String OPTIONAL,
+ toStationNameUTF8 UTF8String OPTIONAL,
+
+ coach IA5String OPTIONAL,
+ place IA5String OPTIONAL,
+
+ compartmentDetails CompartmentDetailsType OPTIONAL,
+
+ -- description of the car
+ numberPlate IA5String,
+ trailerPlate IA5String OPTIONAL,
+ carCategory INTEGER (0..9),
+ boatCategory INTEGER (0..6) OPTIONAL,
+ textileRoof BOOLEAN,
+ roofRackType RoofRackType DEFAULT norack,
+
+ -- height of a roof rack in cm
+ roofRackHeight INTEGER (0..99) OPTIONAL,
+
+ -- number of boats on a rack
+ attachedBoats INTEGER (0..2) OPTIONAL,
+
+ -- number of biycles on a rack
+ attachedBicycles INTEGER (0..4) OPTIONAL,
+
+ -- number of surf boards on a rack
+ attachedSurfboards INTEGER (0..5) OPTIONAL,
+
+ -- reference to an entry on the loading list
+ loadingListEntry INTEGER (0..999) OPTIONAL,
+ loadingDeck LoadingDeckType DEFAULT upper,
+
+ -- responsible carriers on the route (RICS codes)
+ carrierNum SEQUENCE OF INTEGER (1..32000) OPTIONAL,
+ carrierIA5 SEQUENCE OF IA5String OPTIONAL,
+
+ tariff TariffType,
+ priceType PriceTypeType DEFAULT travelPrice,
+
+ price INTEGER OPTIONAL,
+
+ vatDetail SEQUENCE OF VatDetailType OPTIONAL,
+
+ infoText UTF8String OPTIONAL,
+ extension ExtensionData OPTIONAL
+ ,...
+ }
+
+
+ -- #####################################################################################
+ -- data for open tickets (NRT and group tickets)
+ -- included are the data defined in:
+ -- - the ticket layout (leaflet 918.8)
+ -- - the ticket bar code version 3 (leaflet 918.9)
+ -- - additional data based on 108.1 with some extensions as 108.1
+ -- does not provide well structured data,
+ -- especially concerning regional validity
+ --
+ -- #####################################################################################
+
+ OpenTicketData ::= SEQUENCE {
+
+ -- reference must be given either in numeric or alphanumeric format
+ referenceNum INTEGER OPTIONAL,
+ referenceIA5 IA5String OPTIONAL,
+
+ -- organization responsible for the product definition
+ -- (RICS Code / proprietary code in case no RICS code is defined, proprietary codes must ensure to be unique)
+ productOwnerNum INTEGER (1..32000) OPTIONAL,
+ productOwnerIA5 IA5String OPTIONAL,
+
+ -- product id to identify the issued product codelist defined by the product owner
+ -- !!! productIdNum extended
+ productIdNum INTEGER (0..65535) OPTIONAL,
+ productIdIA5 IA5String OPTIONAL,
+
+ -- to support other ticket content (e.g. VDV, UTPF, V�V, CALYPSO)
+ -- issuer code using the default code table of the product owner
+ extIssuerId INTEGER OPTIONAL,
+ -- authorization id provided to the issuer by the product owner
+ issuerAutorizationId INTEGER OPTIONAL,
+
+ -- ticket includes the return trip - should be set to false if it is not relevant (e.g. zones)
+ returnIncluded BOOLEAN,
+
+ -- for tickets valid in regions without from or to stations no station is provided
+ stationCodeTable CodeTableType DEFAULT stationUIC,
+ fromStationNum INTEGER (1..9999999) OPTIONAL,
+ fromStationIA5 IA5String OPTIONAL,
+
+ -- for tickets valid in regions without from or to stations no station is provided
+ toStationNum INTEGER (1..9999999) OPTIONAL,
+ toStationIA5 IA5String OPTIONAL,
+
+ fromStationNameUTF8 UTF8String OPTIONAL,
+ toStationNameUTF8 UTF8String OPTIONAL,
+
+ -- description for manual evaluation in case structured data are not available
+ validRegionDesc UTF8String OPTIONAL,
+ -- specification of the ordered sequence of valid regions
+ validRegion SEQUENCE OF RegionalValidityType OPTIONAL,
+
+ -- return route description
+ -- the return route description can be omitted if it is identical to the
+ -- inversed outbound validRegion sequence
+ returnDescription ReturnRouteDescriptionType OPTIONAL,
+
+ -- temporal validity data in local time of the location where the journey starts
+ -- number of days from issuing date
+ validFromDay INTEGER (-1..700) DEFAULT 0,
+ validFromTime INTEGER (0..1439) OPTIONAL,
+ validFromUTCOffset INTEGER (-60..60) OPTIONAL, -- offset in units of 15 minutes from local time to UTC
+ -- (UTC = local + offset * 15 Minutes)
+
+ -- number of days from valid-from date, 0 = first day of validity
+ validUntilDay INTEGER (-1..370) DEFAULT 0,
+ validUntilTime INTEGER (0..1439) OPTIONAL,
+ validUntilUTCOffset INTEGER (-60..60) OPTIONAL, -- offset in units of 15 minutes from local time to UTC
+ -- (UTC = local + offset * 15 Minutes)
+ -- should be omitted in case it is the same as for departure
+
+ -- travel days of a ticket might be subject to a separate activation to be valid for traveling
+ -- here it is possible to list the activated days of the ticket:
+ -- list of activated days in case the entire ticket is not activated
+ -- the day is given by the number of days from the first day of validity
+ -- change in V2 1 -> 0..370
+ -- 0 = first day of validity
+ activatedDay SEQUENCE OF INTEGER (0..370) OPTIONAL,
+
+ classCode TravelClassType DEFAULT second,
+
+ -- servicelevel code according to leaflet 918.1 to encode other products
+ -- (e.g. PREMIUM, ...)
+ serviceLevel IA5String (SIZE(1..2)) OPTIONAL,
+
+ -- carriers involved in the transport (RICS codes)
+ -- the indication of carriers is mandatory on international routes, they can be
+ -- listed here but can also be included in viaDetails
+ carrierNum SEQUENCE OF INTEGER (1..32000) OPTIONAL,
+ carrierIA5 SEQUENCE OF IA5String OPTIONAL,
+
+
+ -- list of service brands for which the ticket is valid
+ -- in case the included service brands are listed all other brands are excluded
+ -- service brand: code list https://uic.org/service-brand-code-list
+ includedServiceBrands SEQUENCE OF INTEGER (1..32000) OPTIONAL,
+
diff --git a/misc/uicBarcodeV1finalDelayConfirmation1.3.1.asn b/misc/uicBarcodeV1finalDelayConfirmation1.3.1.asn
index 3c589eb..0181738 100644
--- a/misc/uicBarcodeV1finalDelayConfirmation1.3.1.asn
+++ b/misc/uicBarcodeV1finalDelayConfirmation1.3.1.asn
@@ -1977,7 +1977,7 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN
GeoUnitType ::= ENUMERATED {
microDegree (0), -- approx. 11 cm on earth surface
- tenthmilliDegree (1), -- 1 / 100000 degree is approx. 1.1 meter on earth surface
+ tenthmilliDegree (1), -- 1 / 10000 degree is approx. 11 meter on earth surface
milliDegree (2), -- approx 110 meter on earth surface
centiDegree (3),
deciDegree (4)
diff --git a/misc/uicBarcodeV1finalDelayConfirmation1.3.asn b/misc/uicBarcodeV1finalDelayConfirmation1.3.asn
index fb19462..6b79451 100644
--- a/misc/uicBarcodeV1finalDelayConfirmation1.3.asn
+++ b/misc/uicBarcodeV1finalDelayConfirmation1.3.asn
@@ -2003,7 +2003,7 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN
GeoUnitType ::= ENUMERATED {
microDegree (0), -- approx. 11 cm on earth surface
- tenthmilliDegree (1), -- 1 / 100000 degree is approx. 1.1 meter on earth surface
+ tenthmilliDegree (1), -- 1 / 10000 degree is approx. 11 meter on earth surface
milliDegree (2), -- approx 110 meter on earth surface
centiDegree (3),
deciDegree (4)
diff --git a/pom.xml b/pom.xml
index aed14c9..51de693 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,80 +1,66 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.uic.barcode</groupId>
+ <artifactId>org.uic.barcode</artifactId>
+ <version>1.2.5-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>UIC barcode</name>
+ <description>encoding and decoding of bar code content according to UIC IRS 90918-9</description>
+ <build>
+ <sourceDirectory>src/main/java</sourceDirectory>
+ <resources>
+ <resource>
+ <directory>src/main/java</directory>
+ <excludes>
+ <exclude>**/*.java</exclude>
+ </excludes>
+ </resource>
+ </resources>
- <modelVersion>4.0.0</modelVersion>
-
- <groupId>org.uic.barcode</groupId>
- <artifactId>org.uic.barcode</artifactId>
- <version>1.2.4-SNAPSHOT</version>
- <packaging>jar</packaging>
-
- <name>UIC barcode</name>
- <description>encoding and decoding of bar code content according to UIC IRS 90918-9</description>
-
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-
- <maven.compiler.source>1.8</maven.compiler.source>
- <maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
- </properties>
- <build>
- <sourceDirectory>src/main/java</sourceDirectory>
- <testSourceDirectory>src/test/java</testSourceDirectory>
-
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.8.1</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- <version>3.2.1</version>
- <executions>
- <execution>
- <id>attach-javadocs</id>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.22.2</version>
- <configuration>
- <includes>
- <!-- needed for test files not ending with 'Test' -->
- <include>**/test/**/*.java</include>
- </includes>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.13.2</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcprov-jdk15on</artifactId>
- <version>1.68</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <licenses>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>${jdk.version}</source>
+ <target>${jdk.version}</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+
+ </build>
+
+
+ <licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
- </licenses>
+ </licenses>
</project> \ No newline at end of file
diff --git a/src/main/java/org/uic/barcode/Encoder.java b/src/main/java/org/uic/barcode/Encoder.java
index aafe5cc..d971214 100644
--- a/src/main/java/org/uic/barcode/Encoder.java
+++ b/src/main/java/org/uic/barcode/Encoder.java
@@ -5,6 +5,7 @@ import java.security.PrivateKey;
import java.security.PublicKey;
import org.uic.barcode.asn1.datatypesimpl.OctetString;
+import org.uic.barcode.dynamicContent.fdc1.UicDynamicContentDataFDC1;
import org.uic.barcode.dynamicFrame.Constants;
import org.uic.barcode.dynamicFrame.DataType;
import org.uic.barcode.dynamicFrame.DynamicFrame;
@@ -165,6 +166,15 @@ public class Encoder {
}
}
+ public void setDynamicContentDataUIC1(UicDynamicContentDataFDC1 dcd) {
+ if (dynamicFrame != null) {
+ if (dynamicFrame.getLevel2SignedData() == null) {
+ dynamicFrame.setLevel2SignedData(new Level2DataType());
+ }
+ dynamicFrame.getLevel2SignedData().setLevel2Data(dcd.getDataType());
+ }
+ }
+
public DataType getLevel2Data() {
if (dynamicFrame != null && dynamicFrame.getLevel2SignedData() != null) {
return dynamicFrame.getLevel2SignedData().getLevel2Data();
@@ -172,6 +182,14 @@ public class Encoder {
return null;
}
+ public UicDynamicContentDataFDC1 getDynamicContentDataUIC1() {
+ if (dynamicFrame != null && dynamicFrame.getLevel2SignedData() != null) {
+ return dynamicFrame.getDynamicDataFDC1();
+ }
+ return null;
+ }
+
+
/**
* Sign level 1 of a dynamic bar code or a static bar code.
*
diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/ExtensionData.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/ExtensionData.java
new file mode 100644
index 0000000..52b76d1
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/ExtensionData.java
@@ -0,0 +1,59 @@
+/*
+ * This file was generated by openASN.1 - an open source ASN.1 toolkit for java
+ *
+ * openASN.1 is Copyright (C) 2007 Clayton Hoss, Marc Weyland
+ *
+ * openASN.1 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * openASN.1 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with openASN.1. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.uic.barcode.dynamicContent.fdc1;
+
+import org.uic.barcode.asn1.datatypes.CharacterRestriction;
+import org.uic.barcode.asn1.datatypes.FieldOrder;
+import org.uic.barcode.asn1.datatypes.RestrictedString;
+import org.uic.barcode.asn1.datatypes.Sequence;
+import org.uic.barcode.asn1.datatypesimpl.OctetString;
+
+
+@Sequence
+public class ExtensionData extends Object {
+ public ExtensionData() {
+ }
+
+ @FieldOrder(order = 0)
+ @RestrictedString(CharacterRestriction.IA5String)
+ public String extensionId;
+
+ @FieldOrder(order = 1)
+ public OctetString extensionData;
+
+ public String getExtensionId() {
+ return this.extensionId;
+ }
+
+ public byte[] getExtensionData() {
+ return extensionData.toByteArray();
+ }
+
+ public void setExtensionId(String extensionId) {
+ this.extensionId = extensionId;
+ }
+
+ public void setExtensionData(byte[] extensionData) {
+ this.extensionData = new OctetString(extensionData);
+ }
+
+
+
+}
diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoCoordinateSystemType.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoCoordinateSystemType.java
new file mode 100644
index 0000000..b25ad1a
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoCoordinateSystemType.java
@@ -0,0 +1,57 @@
+/*
+ * This file was generated by openASN.1 - an open source ASN.1 toolkit for java
+ *
+ * openASN.1 is Copyright (C) 2007 Clayton Hoss, Marc Weyland
+ *
+ * openASN.1 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * openASN.1 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with openASN.1. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.uic.barcode.dynamicContent.fdc1;
+
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Enum GeoCoordinateSystemType.
+ */
+public enum GeoCoordinateSystemType {
+
+ /** The wgs 84. */
+ wgs84("wgs84"),
+
+ /** The grs 80. */
+ grs80("grs80");
+
+
+ /** The text. */
+ public String text;
+
+ /**
+ * Instantiates a new geo coordinate system type.
+ *
+ * @param text the text
+ */
+ GeoCoordinateSystemType(String text) {
+ this.text = text;
+ }
+
+ /**
+ * To string.
+ *
+ * @return the string
+ */
+ public String toString(){
+ return text;
+ }
+}
+
diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoCoordinateType.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoCoordinateType.java
new file mode 100644
index 0000000..1f1cfc5
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoCoordinateType.java
@@ -0,0 +1,144 @@
+/*
+ * This file was generated by openASN.1 - an open source ASN.1 toolkit for java
+ *
+ * openASN.1 is Copyright (C) 2007 Clayton Hoss, Marc Weyland
+ *
+ * openASN.1 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * openASN.1 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with openASN.1. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.uic.barcode.dynamicContent.fdc1;
+
+import org.uic.barcode.asn1.datatypes.Asn1BigInteger;
+import org.uic.barcode.asn1.datatypes.Asn1Default;
+import org.uic.barcode.asn1.datatypes.Asn1Optional;
+import org.uic.barcode.asn1.datatypes.FieldOrder;
+import org.uic.barcode.asn1.datatypes.Sequence;
+
+@Sequence
+public class GeoCoordinateType extends Object {
+ public GeoCoordinateType() {
+ }
+
+ @FieldOrder(order = 0)
+ @Asn1Default(value="milliDegree")
+ @Asn1Optional public GeoUnitType geoUnit;
+
+ @FieldOrder(order = 1)
+ @Asn1Default(value="wgs84")
+ @Asn1Optional public GeoCoordinateSystemType coordinateSystem;
+
+ @FieldOrder(order = 2)
+ @Asn1Default(value="north")
+ @Asn1Optional public HemisphereLongitudeType hemisphereLongitude;
+
+ @FieldOrder(order = 3)
+ @Asn1Default(value="east")
+ @Asn1Optional public HemisphereLatitudeType hemisphereLatitude;
+
+ @FieldOrder(order = 4)
+ public Asn1BigInteger longitude;
+
+ @FieldOrder(order = 5)
+ public Asn1BigInteger latitude;
+
+ @FieldOrder(order = 6)
+ @Asn1Optional public GeoUnitType accuracy;
+
+ public GeoUnitType getGeoUnit() {
+
+ if (geoUnit == null){
+ return GeoUnitType.milliDegree;
+ }
+ return this.geoUnit;
+ }
+
+ public GeoCoordinateSystemType getCoordinateSystem() {
+
+ if (coordinateSystem == null) {
+ return GeoCoordinateSystemType.wgs84;
+ }
+
+ return this.coordinateSystem;
+ }
+
+ public HemisphereLongitudeType getHemisphereLongitude() {
+
+ if (hemisphereLongitude == null){
+ return HemisphereLongitudeType.north;
+ }
+
+ return this.hemisphereLongitude;
+ }
+
+ public HemisphereLatitudeType getHemisphereLatitude() {
+
+ if (hemisphereLatitude == null) {
+ return HemisphereLatitudeType.east;
+ }
+
+ return this.hemisphereLatitude;
+ }
+
+ public Long getLongitude() {
+
+ return Asn1BigInteger.toLong(this.longitude);
+ }
+
+ public Long getLatitude() {
+
+ return Asn1BigInteger.toLong(this.latitude);
+ }
+
+ public GeoUnitType getAccuracy() {
+
+ return this.accuracy;
+ }
+
+ public void setGeoUnit(GeoUnitType geoUnit) {
+
+ this.geoUnit = geoUnit;
+ }
+
+ public void setCoordinateSystem(GeoCoordinateSystemType coordinateSystem) {
+
+ this.coordinateSystem = coordinateSystem;
+ }
+
+ public void setHemisphereLongitude(HemisphereLongitudeType hemisphereLongitude) {
+
+ this.hemisphereLongitude = hemisphereLongitude;
+ }
+
+ public void setHemisphereLatitude(HemisphereLatitudeType hemisphereLatitude) {
+
+ this.hemisphereLatitude = hemisphereLatitude;
+ }
+
+ public void setLongitude(Long longitude) {
+
+ this.longitude = Asn1BigInteger.toAsn1(longitude);
+ }
+
+ public void setLatitude(Long latitude) {
+
+ this.latitude = Asn1BigInteger.toAsn1(latitude);
+ }
+
+ public void setAccuracy(GeoUnitType accuracy) {
+
+ this.accuracy = accuracy;
+ }
+
+
+}
diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoUnitType.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoUnitType.java
new file mode 100644
index 0000000..4eaa8c9
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoUnitType.java
@@ -0,0 +1,65 @@
+/*
+ * This file was generated by openASN.1 - an open source ASN.1 toolkit for java
+ *
+ * openASN.1 is Copyright (C) 2007 Clayton Hoss, Marc Weyland
+ *
+ * openASN.1 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * openASN.1 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with openASN.1. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.uic.barcode.dynamicContent.fdc1;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Enum GeoUnitType.
+ */
+public enum GeoUnitType {
+
+ /** The micro degree. */
+ microDegree("microDegree"),
+
+ /** The tenthmilli degree. */
+ tenthmilliDegree("tenthmilliDegree"),
+
+ /** The milli degree. */
+ milliDegree("milliDegree"),
+
+ /** The centi degree. */
+ centiDegree("centiDegree"),
+
+ /** The deci degree. */
+ deciDegree("deciDegree");
+
+
+ /** The text. */
+ public String text;
+
+ /**
+ * Instantiates a new geo unit type.
+ *
+ * @param text the text
+ */
+ GeoUnitType(String text) {
+ this.text = text;
+ }
+
+ /**
+ * To string.
+ *
+ * @return the string
+ */
+ public String toString(){
+ return text;
+ }
+}
+
diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLatitudeType.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLatitudeType.java
new file mode 100644
index 0000000..5157b0e
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLatitudeType.java
@@ -0,0 +1,56 @@
+/*
+ * This file was generated by openASN.1 - an open source ASN.1 toolkit for java
+ *
+ * openASN.1 is Copyright (C) 2007 Clayton Hoss, Marc Weyland
+ *
+ * openASN.1 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * openASN.1 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with openASN.1. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.uic.barcode.dynamicContent.fdc1;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Enum HemisphereLatitudeType.
+ */
+public enum HemisphereLatitudeType {
+
+ /** The east. */
+ east("east"),
+
+ /** The west. */
+ west("west");
+
+
+ /** The text. */
+ public String text;
+
+ /**
+ * Instantiates a new hemisphere latitude type.
+ *
+ * @param text the text
+ */
+ HemisphereLatitudeType(String text) {
+ this.text = text;
+ }
+
+ /**
+ * To string.
+ *
+ * @return the string
+ */
+ public String toString(){
+ return text;
+ }
+}
+
diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLongitudeType.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLongitudeType.java
new file mode 100644
index 0000000..c0e33e6
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLongitudeType.java
@@ -0,0 +1,55 @@
+/*
+ * This file was generated by openASN.1 - an open source ASN.1 toolkit for java
+ *
+ * openASN.1 is Copyright (C) 2007 Clayton Hoss, Marc Weyland
+ *
+ * openASN.1 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * openASN.1 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with openASN.1. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.uic.barcode.dynamicContent.fdc1;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Enum HemisphereLongitudeType.
+ */
+public enum HemisphereLongitudeType {
+
+ /** The north. */
+ north("north"),
+
+ /** The south. */
+ south("south");
+
+ /** The text. */
+ public String text;
+
+ /**
+ * Instantiates a new hemisphere longitude type.
+ *
+ * @param text the text
+ */
+ HemisphereLongitudeType(String text) {
+ this.text = text;
+ }
+
+ /**
+ * To string.
+ *
+ * @return the string
+ */
+ public String toString(){
+ return text;
+ }
+}
+
diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/SequenceOfExtension.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/SequenceOfExtension.java
new file mode 100644
index 0000000..38833df
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/SequenceOfExtension.java
@@ -0,0 +1,11 @@
+package org.uic.barcode.dynamicContent.fdc1;
+
+import java.util.Collection;
+
+import org.uic.barcode.asn1.datatypes.Asn1SequenceOf;
+import org.uic.barcode.ticket.api.asn.omv2.TravelerType;
+
+public class SequenceOfExtension extends Asn1SequenceOf<ExtensionData> {
+ public SequenceOfExtension() { super(); }
+ public SequenceOfExtension(Collection<ExtensionData> coll) { super(coll); }
+}
diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java
new file mode 100644
index 0000000..32cce65
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java
@@ -0,0 +1,144 @@
+package org.uic.barcode.dynamicContent.fdc1;
+
+import java.time.Instant;
+import java.time.temporal.ChronoField;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+import org.uic.barcode.asn1.datatypes.FieldOrder;
+import org.uic.barcode.asn1.datatypes.IntRange;
+import org.uic.barcode.asn1.datatypes.Sequence;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class TimeStamp.
+ */
+@Sequence
+public class TimeStamp {
+
+
+ /*
+ -- Moment of generation of the dynamic content, expressed in UTC :
+ -- * dynamicContentDay is the number of days from issuing date
+ -- (UicRailTicketData.issuingDetail.issuingYear and issuingDay)
+ -- The range 0..1070 allows a validity equal to that of the validFrom (700) plus
+ -- validUntil (370) elements of the different transport documents of UicRailTicketData.
+ -- * dynamicContentTime is the number of seconds of the day
+ -- (from 0 = 0:00:00 to 86399 = 23:59:59)
+ -- These two elements shall be either both present, either both absent
+ dynamicContentDay INTEGER (0..366),
+ *
+ */
+ @FieldOrder(order = 0)
+ @IntRange(minValue=1, maxValue=366)
+ public Long day;
+
+ /** The second of day. */
+ // dynamicContentTime INTEGER (0..86399) OPTIONAL,
+ @FieldOrder(order = 1)
+ @IntRange(minValue=0, maxValue=86399)
+ public Long secondOfDay;
+
+
+
+ /**
+ * Instantiates a new time stamp and sets the time-stamp to now.
+ */
+ public TimeStamp() {
+ Instant now = Instant.now();
+ day = new Long(now.get(ChronoField.DAY_OF_YEAR));
+ secondOfDay = new Long(now.get(ChronoField.SECOND_OF_DAY));
+ }
+
+ /**
+ * Sets the the time-stamp to now.
+ */
+ public void setNow() {
+ Instant now = Instant.now();
+ day = new Long(now.get(ChronoField.DAY_OF_YEAR));
+ secondOfDay = new Long(now.get(ChronoField.SECOND_OF_DAY));
+ }
+
+ /**
+ * Gets the day.
+ *
+ * @return the day
+ */
+ public Long getDay() {
+ return day;
+ }
+
+ /**
+ * Sets the day.
+ *
+ * @param day the new day
+ */
+ public void setDay(Long day) {
+ this.day = day;
+ }
+
+ /**
+ * Gets the time.
+ *
+ * @return the time
+ */
+ public Long getTime() {
+ return secondOfDay;
+ }
+
+ /**
+ * Sets the time.
+ *
+ * @param time the new time
+ */
+ public void setTime(Long time) {
+ this.secondOfDay = time;
+ }
+
+ /**
+ * Gets the time.
+ *
+ * @return the date and time of content creation in UTC
+ */
+ public Date getTimeAsDate() {
+
+ Calendar cal = Calendar.getInstance();
+ int dayOfYear = cal.get(Calendar.DAY_OF_YEAR);
+
+ if (dayOfYear - day.intValue() > 250) {
+ cal.add(Calendar.YEAR, 1);
+ }
+ if (day.intValue() - dayOfYear > 250) {
+ cal.add(Calendar.YEAR, -1);
+ }
+
+ cal.setTimeZone(TimeZone.getTimeZone("UTC"));
+ cal.set(Calendar.SECOND,0);
+ cal.set(Calendar.HOUR,0);
+ cal.set(Calendar.MINUTE,0);
+ cal.set(Calendar.DAY_OF_YEAR, day.intValue());
+ cal.add(Calendar.SECOND, secondOfDay.intValue());
+
+ return cal.getTime();
+ }
+
+ /**
+ * Sets the date time.
+ *
+ * @param dateUTC the current date and time in UTC
+ */
+ public void setDateTime(Date dateUTC) {
+
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(dateUTC);
+
+ day = Long.valueOf(cal.get(Calendar.DAY_OF_YEAR));
+
+ secondOfDay = (long) cal.get(Calendar.SECOND);
+ secondOfDay = secondOfDay + 60 * (long) cal.get(Calendar.MINUTE);
+ secondOfDay = secondOfDay + 60 * 60 * (long) cal.get(Calendar.HOUR_OF_DAY);
+
+ }
+
+}
diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java
new file mode 100644
index 0000000..ce6d1b3
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java
@@ -0,0 +1,205 @@
+/*
+ *
+ */
+package org.uic.barcode.dynamicContent.fdc1;
+
+import java.io.UnsupportedEncodingException;
+import org.uic.barcode.asn1.datatypes.Asn1Optional;
+import org.uic.barcode.asn1.datatypes.CharacterRestriction;
+import org.uic.barcode.asn1.datatypes.FieldOrder;
+import org.uic.barcode.asn1.datatypes.HasExtensionMarker;
+import org.uic.barcode.asn1.datatypes.RestrictedString;
+import org.uic.barcode.asn1.datatypes.Sequence;
+import org.uic.barcode.asn1.uper.UperEncoder;
+import org.uic.barcode.dynamicContent.DynamicContent;
+import org.uic.barcode.dynamicFrame.DataType;
+
+
+/**
+ * The Class UicDynamicContentData.
+ *
+ * The dynamic content for FDC1
+ *
+ */
+
+
+
+
+@Sequence
+@HasExtensionMarker
+public class UicDynamicContentDataFDC1 {
+
+
+
+ /*
+ -- The possible values are defined by the security provider
+ -- (the security provider being UicBarcodeHeader.level2SignedData.level1Data.securityProviderNum/IA5)
+ dynamicContentMobileAppId IA5String OPTIONAL,
+ */
+ //timestamp when the bar code was created
+ @FieldOrder(order = 0)
+ @RestrictedString(CharacterRestriction.IA5String)
+ @Asn1Optional public String appId;
+
+ //timestamp when the bar code was created
+ @FieldOrder(order = 1)
+ @Asn1Optional public TimeStamp timeStamp;
+
+
+ //-- Coordinates of the place where the dynamic content has been generated
+ // -- (same GeoCoordinateType type as in UicRailTicketData)
+ /** The geo coordinate. */
+ //dynamicContentGeoCoordinate GeoCoordinateType OPTIONAL,
+ @FieldOrder(order = 2)
+ @Asn1Optional public GeoCoordinateType geoCoordinate;
+ //-- Response from the mobile to any data received from the terminal.
+ //-- The data received from the terminal may be a random number, or any other information.
+ //-- The response may be the data itself, a hashing of this data, or any other response.
+ // -- This response may be completed with other information: IMEI, mobile phone number...
+ //-- The type used is ExtensionData, as it is fully adapted.
+ // -- extensionId shall be set to:
+ // -- * "=" if the data included in extensionData is exactly the one that was transmitted by the terminal,
+ // -- * any other value (chosen by the issuer) in other cases.
+ /** The challenge response. */
+
+ @FieldOrder(order = 3)
+ @Asn1Optional public SequenceOfExtension extensions;
+
+
+
+ //...
+
+
+
+ /**
+ * Gets the geo coordinate.
+ *
+ * @return the geo coordinate
+ */
+ public GeoCoordinateType getGeoCoordinate() {
+ return geoCoordinate;
+ }
+
+ /**
+ * Sets the geo coordinate.
+ *
+ * @param geoCoordinate the new geo coordinate
+ */
+ public void setGeoCoordinate(GeoCoordinateType geoCoordinate) {
+ this.geoCoordinate = geoCoordinate;
+ }
+
+ public static String getFormat() {
+ return "FDC1";
+ }
+
+ public DataType getDataType() {
+ DataType data = new DataType();
+ data.setFormat(getFormat());
+ data.setByteData(UperEncoder.encode(this));
+ return data;
+ }
+
+ public String getChallengeString() {
+ if (this.extensions != null) {
+ for (ExtensionData ed : extensions) {
+ if (ed.getExtensionId().equals("=")) {
+ byte[] c = ed.getExtensionData();
+ try {
+ return new String(c,"UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ return null;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public void setChallengeString(String challengeString) {
+ if (extensions == null) {
+ extensions = new SequenceOfExtension();
+ };
+ ExtensionData ed = new ExtensionData();
+ ed.setExtensionId("=");
+ try {
+ ed.setExtensionData(challengeString.getBytes("UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ return;
+ }
+ extensions.add(ed);
+ }
+
+ public byte[] getPhoneIdHash() {
+ if (this.extensions != null) {
+ for (ExtensionData ed : extensions) {
+ if (ed.getExtensionId().equals("phone")) {
+ return ed.getExtensionData();
+ }
+ }
+ }
+ return null;
+ }
+
+ public void setPhoneIdHash(byte[] phoneIdHash) {
+ if (extensions == null) {
+ extensions = new SequenceOfExtension();
+ };
+ ExtensionData ed = new ExtensionData();
+ ed.setExtensionId("phone");
+ ed.setExtensionData(phoneIdHash);
+ extensions.add(ed);
+ }
+
+ public byte[] getPassIdHash() {
+ if (this.extensions != null) {
+ for (ExtensionData ed : extensions) {
+ if (ed.getExtensionId().equals("pass")) {
+ return ed.getExtensionData();
+ }
+ }
+ }
+ return null;
+ }
+
+ public void setPassIdHash(byte[] phoneIdHash) {
+ if (extensions == null) {
+ extensions = new SequenceOfExtension();
+ };
+ ExtensionData ed = new ExtensionData();
+ ed.setExtensionId("pass");
+ ed.setExtensionData(phoneIdHash);
+ extensions.add(ed);
+ }
+
+ public TimeStamp getTimeStamp() {
+ return timeStamp;
+ }
+
+ public void setTimeStamp(TimeStamp timeStamp) {
+ this.timeStamp = timeStamp;
+ }
+
+ public SequenceOfExtension getExtensions() {
+ return extensions;
+ }
+
+ public void setExtensions(SequenceOfExtension extensions) {
+ this.extensions = extensions;
+ }
+
+ public byte[] encode() {
+ return UperEncoder.encode(this);
+ }
+
+ public String getAppId() {
+ return appId;
+ }
+
+ public void setAppId(String appId) {
+ this.appId = appId;
+ }
+
+
+
+}
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/Constants.java b/src/main/java/org/uic/barcode/dynamicFrame/Constants.java
index 98b62aa..774475a 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/Constants.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/Constants.java
@@ -12,7 +12,7 @@ public class Constants {
public static String DSA_SHA1 = "1.2.840.10040.4.3";
public static String DSA_SHA224 = "2.16.840.1.101.3.4.3.1";
- public static String DSA_SHA248 = "2.16.840.1.101.3.4.3.2";
+ public static String DSA_SHA256 = "2.16.840.1.101.3.4.3.2";
public static String DATA_TYPE_FCB_VERSION_1 = "FCB1";
public static String DATA_TYPE_FCB_VERSION_2 = "FCB2";
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java
index 9605a0d..375e2c6 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java
@@ -18,6 +18,7 @@ import org.uic.barcode.asn1.datatypes.RestrictedString;
import org.uic.barcode.asn1.datatypes.Sequence;
import org.uic.barcode.asn1.datatypesimpl.OctetString;
import org.uic.barcode.asn1.uper.UperEncoder;
+import org.uic.barcode.dynamicContent.fdc1.UicDynamicContentDataFDC1;
import org.uic.barcode.utils.AlgorithmNameResolver;
@@ -262,5 +263,23 @@ public class DynamicFrame extends Object{
}
+ public void addLevel2DynamicData(UicDynamicContentDataFDC1 dynamicData) {
+ this.getLevel2SignedData().setLevel2Data( dynamicData.getDataType());
+ }
+
+ public UicDynamicContentDataFDC1 getDynamicDataFDC1() {
+
+ if (this.getLevel2SignedData() == null ||
+ this.getLevel2SignedData().getLevel2Data() == null){
+ return null;
+ }
+
+ if ( UicDynamicContentDataFDC1.getFormat().equals(this.getLevel2SignedData().getLevel2Data().getFormat())) {
+ return UperEncoder.decode(this.getLevel2SignedData().getLevel2Data().getByteData(), UicDynamicContentDataFDC1.class);
+ }
+ return null;
+
+ }
+
}
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java
index 1f4d476..aac0188 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java
@@ -49,7 +49,7 @@ public class Level1DataType {
*
* e.g.:
* -- DSA SHA224 2.16.840.1.101.3.4.3.1
- * -- DSA SHA248 2.16.840.1.101.3.4.3.2
+ * -- DSA SHA256 2.16.840.1.101.3.4.3.2
* -- ECC 256 1.2.840.10045.3.1.7
*
*
@@ -69,7 +69,7 @@ public class Level1DataType {
*
* e.g.:
* -- DSA SHA224 2.16.840.1.101.3.4.3.1
- * -- DSA SHA248 2.16.840.1.101.3.4.3.2
+ * -- DSA SHA256 2.16.840.1.101.3.4.3.2
* -- ECC 256 1.2.840.10045.3.1.7
*
*
diff --git a/src/main/java/org/uic/barcode/staticFrame/StaticFrame.java b/src/main/java/org/uic/barcode/staticFrame/StaticFrame.java
index 639af69..2759bf0 100644
--- a/src/main/java/org/uic/barcode/staticFrame/StaticFrame.java
+++ b/src/main/java/org/uic/barcode/staticFrame/StaticFrame.java
@@ -655,7 +655,7 @@ public class StaticFrame {
* @throws NoSuchAlgorithmException the no such algorithm exception
* @throws SignatureException the signature exception
* @throws IllegalArgumentException the illegal argument exception
- * @throws UnsupportedOperationException the unsupported operatign exception
+ * @throws UnsupportedOperationException the unsupported operating exception
* @throws EncodingFormatException
* @throws IOException
*/
@@ -669,6 +669,9 @@ public class StaticFrame {
algo = service.getAlgorithm();
}
}
+ if (algo == null) {
+ throw new NoSuchAlgorithmException("No service for algorithm found: " + signingAlg);
+ }
Signature sig = Signature.getInstance(algo);
sig.initVerify(key);
sig.update(getDataForSignature());
@@ -697,8 +700,12 @@ public class StaticFrame {
Service service = prov.getService("Signature",signingAlg);
if (service != null) {
algo = service.getAlgorithm();
+ break;
}
}
+ if (algo == null) {
+ throw new NoSuchAlgorithmException("No service for algorthm found: " + signingAlg);
+ }
Signature sig = Signature.getInstance(algo);
sig.initSign(key);
signedData = getDataForSignature();
diff --git a/src/main/java/org/uic/barcode/staticFrame/UHEADDataRecord.java b/src/main/java/org/uic/barcode/staticFrame/UHEADDataRecord.java
index 855c9d5..492656a 100644
--- a/src/main/java/org/uic/barcode/staticFrame/UHEADDataRecord.java
+++ b/src/main/java/org/uic/barcode/staticFrame/UHEADDataRecord.java
@@ -180,7 +180,7 @@ public class UHEADDataRecord extends DataRecord{
}
// date format "DDMMYYYYHHMM"
- SimpleDateFormat formatter = new SimpleDateFormat("ddMMyyyyhhmm");
+ SimpleDateFormat formatter = new SimpleDateFormat("ddMMyyyyHHmm");
try {
issuingDate = formatter.parse(issuingDateString);
} catch (ParseException e) {
diff --git a/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java b/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java
index 300bf7d..e3918b0 100644
--- a/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java
+++ b/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java
@@ -50,7 +50,7 @@ public class AlgorithmNameResolver {
Service pservice = prov.getService(ptype, poid);
String palgo = pservice.getAlgorithm();
- if (ptype.equalsIgnoreCase(type) && poid.equals(oid)) {
+ if (poid != null && ptype.equalsIgnoreCase(type) && poid.equals(oid)) {
return palgo;
}
}
diff --git a/src/test/java/org/uic/barcode/test/utils/TestUtils.java b/src/test/java/org/uic/barcode/test/utils/TestUtils.java
index 7311ae4..20a21c4 100644
--- a/src/test/java/org/uic/barcode/test/utils/TestUtils.java
+++ b/src/test/java/org/uic/barcode/test/utils/TestUtils.java
@@ -1,9 +1,19 @@
package org.uic.barcode.test.utils;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
+import org.bouncycastle.jce.ECNamedCurveTable;
+import org.bouncycastle.jce.spec.ECParameterSpec;
+import org.uic.barcode.utils.AlgorithmNameResolver;
+
public class TestUtils {
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
@@ -35,4 +45,29 @@ public class TestUtils {
}
+ /**
+ * Generate DSA keys.
+ *
+ * @return the key pair
+ * @throws NoSuchAlgorithmException the no such algorithm exception
+ * @throws NoSuchProviderException the no such provider exception
+ * @throws InvalidAlgorithmParameterException the invalid algorithm parameter exception
+ */
+ public static KeyPair generateDSAKeys(int keySize) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException{
+ KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "BC");
+ g.initialize(keySize, new SecureRandom());
+ return g.generateKeyPair();
+ }
+
+ public static KeyPair generateECKeys(String keyAlgorithmOid, String curve) throws Exception{
+
+ String keyAlgorithmName = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, keyAlgorithmOid, "BC");
+
+ keyAlgorithmName = "ECDSA";
+ ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(curve);
+ KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC");
+ g.initialize(ecSpec, new SecureRandom());
+ return g.generateKeyPair();
+ }
+
}
diff --git a/src/test/java/org/uic/barcode/ticketTestDB/DecodeSparpreisTicketDBTest.java b/src/test/java/org/uic/barcode/ticketTestDB/DecodeSparpreisTicketDBTest.java
index 979b3ca..1f1be30 100644
--- a/src/test/java/org/uic/barcode/ticketTestDB/DecodeSparpreisTicketDBTest.java
+++ b/src/test/java/org/uic/barcode/ticketTestDB/DecodeSparpreisTicketDBTest.java
@@ -1,5 +1,6 @@
package org.uic.barcode.ticketTestDB;
+
import java.util.TimeZone;
import org.junit.After;
@@ -118,4 +119,5 @@ public class DecodeSparpreisTicketDBTest {
"14b00240400f53757065722053706172" +
"7072656973c41e4a03";
}
+
} \ No newline at end of file
diff --git a/src/test/java/org/uic/barcode/ticketTestDB/EncodeSparpreisTicketDBTest.java b/src/test/java/org/uic/barcode/ticketTestDB/EncodeSparpreisTicketDBTest.java
new file mode 100644
index 0000000..787abf5
--- /dev/null
+++ b/src/test/java/org/uic/barcode/ticketTestDB/EncodeSparpreisTicketDBTest.java
@@ -0,0 +1,121 @@
+package org.uic.barcode.ticketTestDB;
+
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Security;
+import java.util.TimeZone;
+import java.util.zip.DataFormatException;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.uic.barcode.Decoder;
+import org.uic.barcode.Encoder;
+import org.uic.barcode.asn1.uper.UperEncoder;
+import org.uic.barcode.dynamicFrame.Constants;
+import org.uic.barcode.staticFrame.StaticFrame;
+import org.uic.barcode.test.utils.TestUtils;
+import org.uic.barcode.ticket.EncodingFormatException;
+import org.uic.barcode.ticket.api.spec.IUicRailTicket;
+
+public class EncodeSparpreisTicketDBTest {
+
+ /** The algorithm OID. */
+ public String algorithmOID = Constants.DSA_SHA1;
+
+ public int keySize = 1024;
+
+ /** The key pair. */
+ public KeyPair keyPair = null;
+
+ public String securityProvider = null;
+
+ /** the test ticket **/
+ public IUicRailTicket ticket = null;
+
+ TimeZone defaulttimeZone = null;
+
+ /**
+ * Prepare tickets.
+ * @throws DataFormatException
+ * @throws EncodingFormatException
+ * @throws IOException
+ */
+ @Before public void prepare() throws IOException, EncodingFormatException, DataFormatException {
+ defaulttimeZone = TimeZone.getDefault();
+ //decode in local CET time zone
+ TimeZone.setDefault(TimeZone.getTimeZone("CET"));
+
+ algorithmOID = Constants.DSA_SHA1;
+ keySize = 1024;
+
+ Security.addProvider(new BouncyCastleProvider());
+
+ try {
+ keyPair = TestUtils.generateDSAKeys(keySize);
+ } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
+ e.printStackTrace();
+ }
+
+ assert(keyPair != null);
+
+ //get original ticket
+ byte[] content = UperEncoder.bytesFromHexString(getEncodingV2Hex());
+ // decode to get the ticket
+ Decoder decoder = new Decoder(content);
+ ticket = decoder.getUicTicket();
+ StaticFrame frame = decoder.getStaticFrame();
+ securityProvider = frame.getSecurityProvider();
+ }
+
+
+ /**
+ * clean up
+ */
+ @After public void resetTimeZone() {
+ TimeZone.setDefault(defaulttimeZone);
+ }
+
+ @Test
+ public void testDecoder() throws Exception {
+
+ Encoder encoder = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_CLASSIC, 1, 2);
+ encoder.signLevel1(securityProvider, keyPair.getPrivate(), algorithmOID, "1");
+
+ byte[] encoded = encoder.encode();
+
+ assert(encoded != null);
+
+ //TODO check ticket in detail
+
+ }
+
+ private static String getEncodingV2Hex() {
+
+ return "2355543032313038303030303032782e" +
+ "2fe184a1d85e89e9338b298ec61aeba2" +
+ "48ce722056ca940a967c8a1d39126e2c" +
+ "628c4fcea91ba35216a0a350f894de5e" +
+ "bd7b8909920fde947feede0e20c43031" +
+ "3939789c01bc0043ff555f464c455831" +
+ "333031383862b20086e10dc125ea2815" +
+ "110881051c844464d985668e23a00a80" +
+ "000e96c2e4e6e8cadc08aed2d8d90104" +
+ "44d7be0100221ce610ea559b64364c38" +
+ "a82361d1cb5e1e5d32a3d0979bd099c8" +
+ "426b0b7373432b4b6852932baba3634b" +
+ "733b2b715ab34b09d101e18981c181f1" +
+ "424221521291521292a17a3a920a1152" +
+ "5a095282314952b20a49529952826278" +
+ "083001a4c38ae5bb303ace7003800700" +
+ "14b00240400f53757065722053706172" +
+ "7072656973c41e4a03";
+ }
+
+
+
+} \ No newline at end of file
diff --git a/src/test/java/org/uic/barcode/ticketTestDB/SignatureValidationDBTicketTest.java b/src/test/java/org/uic/barcode/ticketTestDB/SignatureValidationDBTicketTest.java
index 44f9c4a..9249f4f 100644
--- a/src/test/java/org/uic/barcode/ticketTestDB/SignatureValidationDBTicketTest.java
+++ b/src/test/java/org/uic/barcode/ticketTestDB/SignatureValidationDBTicketTest.java
@@ -58,7 +58,7 @@ public class SignatureValidationDBTicketTest {
assert("00002".equals(keyVersion));
- String algorithmOID = Constants.DSA_SHA248;
+ String algorithmOID = Constants.DSA_SHA256;
int result = decoder.validateLevel1(getPublicKey2(), algorithmOID);