-
Notifications
You must be signed in to change notification settings - Fork 2
/
RawETicket.cs
96 lines (83 loc) · 4.76 KB
/
RawETicket.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using HslTravelSharp.Core.Helpers;
using System;
namespace HslTravelSharp.Core.Models
{
/// <summary>
/// Represents a single ticket data that is used both in HSL single tickets and in HSL travel card's value tickets.
/// </summary>
public class RawETicket
{
public ushort ProductCode { get; set; }
public byte Child { get; set; }
public byte LanguageCode { get; set; }
public byte ValidityLengthType { get; set; }
public byte ValidityLength { get; set; }
public byte ValidityAreaType { get; set; }
public byte ValidityArea { get; set; }
public DateTimeOffset SaleDate { get; set; }
public byte SaleTime { get; set; }
public byte GroupSize { get; set; }
public byte SaleStatus { get; set; }
public DateTimeOffset ValidityStartDate { get; set; }
public DateTimeOffset ValidityEndDate { get; set; }
public byte ValidityStatus { get; set; }
//Last boarding info
public DateTimeOffset BoardingDate { get; set; }
public ushort BoardingVehicle { get; set; }
public byte BoardingLocationNumType { get; set; }
public ushort BoardingLocationNum { get; set; }
public byte BoardingDirection { get; set; }
public byte BoardingArea { get; set; }
/// <summary>
/// This constructor mostly exists as a convenience method for
/// serializers like Json.NET. Using it directly
/// is not recommended.
/// </summary>
public RawETicket()
{
}
public RawETicket(byte[] eTicketData, Boolean isSingleTicket)
{
ProductCode = (ushort)((ushort)((eTicketData[0] & 0xFF) << 6) | ((eTicketData[1] & 0xFC) >> 2));
Child = (byte)((eTicketData[1] & 0x02) >> 1);
LanguageCode = (byte)(((eTicketData[1] & 0x01) << 1) | ((eTicketData[2] & 0x80) >> 7));
ValidityLengthType = (byte)((eTicketData[2] & 0x60) >> 5);
ValidityLength = (byte)(((eTicketData[2] & 0x1F) << 3) | ((eTicketData[3] & 0xE0) >> 5));
ValidityAreaType = (byte)((eTicketData[3] & 0x10) >> 4);
ValidityArea = (byte)(eTicketData[3] & 0x0F);
ushort date1 = (ushort)(((eTicketData[4] & 0xFF) << 6) | ((eTicketData[5] & 0xFC) >> 2));
SaleDate = ConversionUtil.FromEn1545Date(date1).UtcDateTime;
SaleTime = (byte)(((eTicketData[5] & 0x03) << 3) | ((eTicketData[6] & 0xE0) >> 5));
GroupSize = (byte)((eTicketData[10] & 0x3E) >> 1);
//sale status is relevant only in value tickets on desfire cards
SaleStatus = (byte)(eTicketData[10] & 0x01);
int count = 0;
//if we're reading separate eTicket (single ticket) skip over some data
if (isSingleTicket)
{
count = 6;
}
//read validity start datestamp
date1 = (ushort)(((eTicketData[11 + count] & 0xFF) << 6) | ((eTicketData[12 + count] & 0xFC) >> 2));
//read validity start timestamp
ushort time1 = (ushort)(((eTicketData[12 + count] & 0x03) << 9) | ((eTicketData[13 + count] & 0xFF) << 1) | ((eTicketData[14 + count] & 0x80) >> 7));
ValidityStartDate = ConversionUtil.FromEn1545DateAndTime(date1, time1);
//read validity end datestamp
date1 = (ushort)(((eTicketData[14 + count] & 0x7F) << 7) | ((eTicketData[15 + count] & 0xFF) >> 1));
//read validity end timestamp
time1 = (ushort)(((eTicketData[15 + count] & 0x01) << 10) | ((eTicketData[16 + count] & 0xFF) << 2) | ((eTicketData[17 + count] & 0xC0) >> 6));
ValidityEndDate = ConversionUtil.FromEn1545DateAndTime(date1, time1);
//validity status is relevant only in value tickets on desfire cards
ValidityStatus = (byte)(eTicketData[17 + count] & 0x01);
//LAST USE (BOARDING)
date1 = (ushort)(((eTicketData[18 + count] & 0xFF) << 6) | ((eTicketData[19 + count] & 0xFC) >> 2));
time1 = (ushort)(((eTicketData[19 + count] & 0x03) << 9) | ((eTicketData[20 + count] & 0xFF) << 1) | ((eTicketData[21 + count] & 0x80) >> 7));
BoardingDate = ConversionUtil.FromEn1545DateAndTime(date1, time1);
BoardingVehicle = (ushort)(((eTicketData[21 + count] & 0x7F) << 7) | (eTicketData[22 + count] & 0xFE) >> 1);
BoardingLocationNumType = (byte)(((eTicketData[22 + count] & 0x01) << 1) | ((eTicketData[23 + count] & 0x80) >> 7));
BoardingLocationNum = (ushort)(((eTicketData[23 + count] & 0x7F) << 7) | ((eTicketData[24 + count] & 0xFE) >> 1));
BoardingDirection = (byte)(eTicketData[24 + count] & 0x01);
BoardingArea = (byte)((eTicketData[25 + count] & 0xF0) >> 4);
}
}
}