Skip to content

Commit b59324d

Browse files
committed
coder
1 parent 0966fa8 commit b59324d

File tree

2 files changed

+154
-0
lines changed

2 files changed

+154
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package net.heberling.ismart.asn1.v2_0;
2+
3+
import net.heberling.ismart.asn1.AbstractMessage;
4+
import org.bn.coders.IASN1PreparedElement;
5+
6+
public class Message<E extends IASN1PreparedElement>
7+
extends AbstractMessage<MP_DispatcherHeader, MP_DispatcherBody, E> {
8+
9+
private final byte[] reserved;
10+
11+
Message(MP_DispatcherHeader header, byte[] reserved, MP_DispatcherBody body, E applicationData) {
12+
super(header, body, applicationData);
13+
this.reserved = reserved;
14+
}
15+
16+
public byte[] getReserved() {
17+
return reserved;
18+
}
19+
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package net.heberling.ismart.asn1.v2_0;
2+
3+
import java.io.ByteArrayInputStream;
4+
import java.io.ByteArrayOutputStream;
5+
import java.io.InputStream;
6+
import java.time.Instant;
7+
import net.heberling.ismart.asn1.AbstractMessageCoder;
8+
import net.heberling.ismart.asn1.Util;
9+
import org.bn.coders.IASN1PreparedElement;
10+
import org.bn.coders.per.PERUnalignedDecoder;
11+
12+
public class MessageCoder<E extends IASN1PreparedElement>
13+
extends AbstractMessageCoder<MP_DispatcherHeader, MP_DispatcherBody, E, Message<E>> {
14+
15+
public MessageCoder(Class<E> applicationDataClass) {
16+
super(applicationDataClass);
17+
}
18+
19+
@Override
20+
public String encodeRequest(Message<E> message) {
21+
22+
E request = message.getApplicationData();
23+
24+
try {
25+
26+
ByteArrayOutputStream bos;
27+
byte[] applicationData;
28+
MyPERUnalignedEncoder encoder = new MyPERUnalignedEncoder();
29+
if (request != null) {
30+
bos = new ByteArrayOutputStream();
31+
encoder.encode(request, bos);
32+
applicationData = bos.toByteArray();
33+
} else {
34+
applicationData = new byte[0];
35+
}
36+
37+
MP_DispatcherBody body = message.getBody();
38+
final DataEncodingType dataEncoding = new DataEncodingType();
39+
dataEncoding.setValue(DataEncodingType.EnumType.perUnaligned);
40+
body.setApplicationDataEncoding(dataEncoding);
41+
body.setApplicationDataLength(applicationData.length);
42+
43+
bos = new ByteArrayOutputStream();
44+
encoder.encode(body, bos);
45+
final byte[] bodyData = bos.toByteArray();
46+
47+
MP_DispatcherHeader header = message.getHeader();
48+
if (header.getProtocolVersion() == null) {
49+
header.setProtocolVersion(33);
50+
}
51+
header.setDispatcherMessageLength(bodyData.length + 3 /*header length*/);
52+
header.setDispatcherBodyEncoding(0); // PER
53+
54+
bos = new ByteArrayOutputStream();
55+
bos.write(header.getProtocolVersion());
56+
bos.write(header.getDispatcherMessageLength());
57+
bos.write(header.getDispatcherBodyEncoding());
58+
59+
bos.write(message.getReserved());
60+
61+
bos.write(bodyData);
62+
63+
bos.write(applicationData);
64+
65+
byte[] bytes = bos.toByteArray();
66+
return "1" + String.format("%04X", bytes.length + 3) + bytesToHex(bytes);
67+
} catch (Exception e) {
68+
throw new RuntimeException(e);
69+
}
70+
}
71+
72+
@Override
73+
public Message<E> decodeResponse(String message) {
74+
try {
75+
// TODO: check for message encoding and length
76+
byte[] bytes = hexStringToByteArray(message.substring(5));
77+
InputStream inputStream = new ByteArrayInputStream(bytes);
78+
// not asn.1 encoded
79+
MP_DispatcherHeader header = new MP_DispatcherHeader();
80+
header.setProtocolVersion(inputStream.read());
81+
// messages can be longer than 256 bytes, so this value can be wrong!
82+
header.setDispatcherMessageLength(inputStream.read());
83+
header.setDispatcherBodyEncoding(inputStream.read());
84+
85+
// TODO: whats this?
86+
byte[] reserved = new byte[16];
87+
inputStream.read(reserved);
88+
89+
final PERUnalignedDecoder decoder = new MyPERUnalignedDecoder();
90+
MP_DispatcherBody body = decoder.decode(inputStream, MP_DispatcherBody.class);
91+
92+
E e = null;
93+
if (getApplicationDataClass() != null && body.getApplicationDataLength() > 0) {
94+
e = decoder.decode(inputStream, getApplicationDataClass());
95+
}
96+
return new Message<>(header, reserved, body, e);
97+
} catch (Exception e) {
98+
throw new RuntimeException("Could not decode: " + message, e);
99+
}
100+
}
101+
102+
@Override
103+
public Message<E> initializeMessage(
104+
String uid,
105+
String token,
106+
String vin,
107+
String applicationID,
108+
int applicationDataProtocolVersion,
109+
int messageID,
110+
E applicationData) {
111+
Message<E> message =
112+
new Message<>(
113+
new MP_DispatcherHeader(),
114+
Util.generateReservedBytes(),
115+
new MP_DispatcherBody(),
116+
applicationData);
117+
118+
message.getBody().setMessageID(messageID);
119+
message.getBody().setEventCreationTime((int) Instant.now().getEpochSecond());
120+
message.getBody().setApplicationID(applicationID);
121+
message.getBody().setApplicationDataProtocolVersion(applicationDataProtocolVersion);
122+
message.getBody().setTestFlag(2);
123+
message.getBody().setUid(uid);
124+
message.getBody().setToken(token);
125+
message.getBody().setVin(vin);
126+
message.getBody().setEventID(0);
127+
128+
return message;
129+
}
130+
131+
@Override
132+
public String getVersion() {
133+
return "2.1";
134+
}
135+
}

0 commit comments

Comments
 (0)