Parsing CAN frames from a ByteArray
up vote
2
down vote
favorite
Here's my method used for parsing a ByteArray
into multiple frames of CAN interface. It works now correctly but it's somewhat ugly in my opinion.
It's written in Kotlin with use of RxJava2
private fun parseCanFrameBytes(frame: ByteArray): Observable<CanFrame> {
return Observable.create { emitter ->
var index = 0
while (index < frame.size) {
val byte = frame[index]
if(byte xor IFM_FRAME_HEADER == BYTE_ZERO) {
try {
val ifmIndex = index
val length = frame[ifmIndex + 1].toInt()
val dlc1 = length - 3
val dlc2 = length - 5
val command = frame[ifmIndex + 2].toInt()
val data = frame.copyOfRange(ifmIndex + 3, ifmIndex + 2 + length)
val isChecksumValid = frame[ifmIndex + 2 + length].toInt() == frame.copyOfRange(ifmIndex, ifmIndex + 2 + length).calculate8XorChecksum()
if (!isChecksumValid) {
index++
continue
}
val canFrame = when (command) {
0 -> {
val pgn = data.copyOfRange(0, 2).toHexString()
CanFrame(
type = "DLC1",
pgn = pgn,
id = pgn,
value = data.copyOfRange(2, 2 + dlc1).toHexString(),
ts = timestamp(),
data = frame.copyOfRange(ifmIndex, ifmIndex + 4 + length).toHexString()
)
}
2 -> {
val pgn = data.copyOfRange(0, 4).toHexString()
CanFrame(
type = "DLC2",
pgn = pgn,
id = pgn,
value = data.copyOfRange(4, 4 + dlc2).toHexString(),
ts = timestamp(),
data = frame.copyOfRange(ifmIndex, ifmIndex + 4 + length).toHexString()
)
}
else -> null
} ?: continue
emitter.onNext(canFrame)
index = ifmIndex + length + 4
} catch (ex: IllegalArgumentException) {
index++
}
} else {
index++
}
}
}
}
serialization kotlin rx-java
bumped to the homepage by Community♦ 9 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
up vote
2
down vote
favorite
Here's my method used for parsing a ByteArray
into multiple frames of CAN interface. It works now correctly but it's somewhat ugly in my opinion.
It's written in Kotlin with use of RxJava2
private fun parseCanFrameBytes(frame: ByteArray): Observable<CanFrame> {
return Observable.create { emitter ->
var index = 0
while (index < frame.size) {
val byte = frame[index]
if(byte xor IFM_FRAME_HEADER == BYTE_ZERO) {
try {
val ifmIndex = index
val length = frame[ifmIndex + 1].toInt()
val dlc1 = length - 3
val dlc2 = length - 5
val command = frame[ifmIndex + 2].toInt()
val data = frame.copyOfRange(ifmIndex + 3, ifmIndex + 2 + length)
val isChecksumValid = frame[ifmIndex + 2 + length].toInt() == frame.copyOfRange(ifmIndex, ifmIndex + 2 + length).calculate8XorChecksum()
if (!isChecksumValid) {
index++
continue
}
val canFrame = when (command) {
0 -> {
val pgn = data.copyOfRange(0, 2).toHexString()
CanFrame(
type = "DLC1",
pgn = pgn,
id = pgn,
value = data.copyOfRange(2, 2 + dlc1).toHexString(),
ts = timestamp(),
data = frame.copyOfRange(ifmIndex, ifmIndex + 4 + length).toHexString()
)
}
2 -> {
val pgn = data.copyOfRange(0, 4).toHexString()
CanFrame(
type = "DLC2",
pgn = pgn,
id = pgn,
value = data.copyOfRange(4, 4 + dlc2).toHexString(),
ts = timestamp(),
data = frame.copyOfRange(ifmIndex, ifmIndex + 4 + length).toHexString()
)
}
else -> null
} ?: continue
emitter.onNext(canFrame)
index = ifmIndex + length + 4
} catch (ex: IllegalArgumentException) {
index++
}
} else {
index++
}
}
}
}
serialization kotlin rx-java
bumped to the homepage by Community♦ 9 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
Can you add some more context, what exactly isCanFrame
?
– Simon Forsberg♦
Jun 21 at 14:08
I don't think that's important at all. What I want to achieve is more concise and better looking code. It's pretty niche thing but if you want you can read about it here en.wikipedia.org/wiki/CAN_bus
– Ernest Zamelczyk
Jun 21 at 14:13
I'd recommend you to read Simon's guide to a good question
– Simon Forsberg♦
Jun 21 at 16:20
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
Here's my method used for parsing a ByteArray
into multiple frames of CAN interface. It works now correctly but it's somewhat ugly in my opinion.
It's written in Kotlin with use of RxJava2
private fun parseCanFrameBytes(frame: ByteArray): Observable<CanFrame> {
return Observable.create { emitter ->
var index = 0
while (index < frame.size) {
val byte = frame[index]
if(byte xor IFM_FRAME_HEADER == BYTE_ZERO) {
try {
val ifmIndex = index
val length = frame[ifmIndex + 1].toInt()
val dlc1 = length - 3
val dlc2 = length - 5
val command = frame[ifmIndex + 2].toInt()
val data = frame.copyOfRange(ifmIndex + 3, ifmIndex + 2 + length)
val isChecksumValid = frame[ifmIndex + 2 + length].toInt() == frame.copyOfRange(ifmIndex, ifmIndex + 2 + length).calculate8XorChecksum()
if (!isChecksumValid) {
index++
continue
}
val canFrame = when (command) {
0 -> {
val pgn = data.copyOfRange(0, 2).toHexString()
CanFrame(
type = "DLC1",
pgn = pgn,
id = pgn,
value = data.copyOfRange(2, 2 + dlc1).toHexString(),
ts = timestamp(),
data = frame.copyOfRange(ifmIndex, ifmIndex + 4 + length).toHexString()
)
}
2 -> {
val pgn = data.copyOfRange(0, 4).toHexString()
CanFrame(
type = "DLC2",
pgn = pgn,
id = pgn,
value = data.copyOfRange(4, 4 + dlc2).toHexString(),
ts = timestamp(),
data = frame.copyOfRange(ifmIndex, ifmIndex + 4 + length).toHexString()
)
}
else -> null
} ?: continue
emitter.onNext(canFrame)
index = ifmIndex + length + 4
} catch (ex: IllegalArgumentException) {
index++
}
} else {
index++
}
}
}
}
serialization kotlin rx-java
Here's my method used for parsing a ByteArray
into multiple frames of CAN interface. It works now correctly but it's somewhat ugly in my opinion.
It's written in Kotlin with use of RxJava2
private fun parseCanFrameBytes(frame: ByteArray): Observable<CanFrame> {
return Observable.create { emitter ->
var index = 0
while (index < frame.size) {
val byte = frame[index]
if(byte xor IFM_FRAME_HEADER == BYTE_ZERO) {
try {
val ifmIndex = index
val length = frame[ifmIndex + 1].toInt()
val dlc1 = length - 3
val dlc2 = length - 5
val command = frame[ifmIndex + 2].toInt()
val data = frame.copyOfRange(ifmIndex + 3, ifmIndex + 2 + length)
val isChecksumValid = frame[ifmIndex + 2 + length].toInt() == frame.copyOfRange(ifmIndex, ifmIndex + 2 + length).calculate8XorChecksum()
if (!isChecksumValid) {
index++
continue
}
val canFrame = when (command) {
0 -> {
val pgn = data.copyOfRange(0, 2).toHexString()
CanFrame(
type = "DLC1",
pgn = pgn,
id = pgn,
value = data.copyOfRange(2, 2 + dlc1).toHexString(),
ts = timestamp(),
data = frame.copyOfRange(ifmIndex, ifmIndex + 4 + length).toHexString()
)
}
2 -> {
val pgn = data.copyOfRange(0, 4).toHexString()
CanFrame(
type = "DLC2",
pgn = pgn,
id = pgn,
value = data.copyOfRange(4, 4 + dlc2).toHexString(),
ts = timestamp(),
data = frame.copyOfRange(ifmIndex, ifmIndex + 4 + length).toHexString()
)
}
else -> null
} ?: continue
emitter.onNext(canFrame)
index = ifmIndex + length + 4
} catch (ex: IllegalArgumentException) {
index++
}
} else {
index++
}
}
}
}
serialization kotlin rx-java
serialization kotlin rx-java
edited Jun 30 at 2:44
200_success
127k15148411
127k15148411
asked Jun 21 at 7:40
Ernest Zamelczyk
1112
1112
bumped to the homepage by Community♦ 9 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
bumped to the homepage by Community♦ 9 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
Can you add some more context, what exactly isCanFrame
?
– Simon Forsberg♦
Jun 21 at 14:08
I don't think that's important at all. What I want to achieve is more concise and better looking code. It's pretty niche thing but if you want you can read about it here en.wikipedia.org/wiki/CAN_bus
– Ernest Zamelczyk
Jun 21 at 14:13
I'd recommend you to read Simon's guide to a good question
– Simon Forsberg♦
Jun 21 at 16:20
add a comment |
Can you add some more context, what exactly isCanFrame
?
– Simon Forsberg♦
Jun 21 at 14:08
I don't think that's important at all. What I want to achieve is more concise and better looking code. It's pretty niche thing but if you want you can read about it here en.wikipedia.org/wiki/CAN_bus
– Ernest Zamelczyk
Jun 21 at 14:13
I'd recommend you to read Simon's guide to a good question
– Simon Forsberg♦
Jun 21 at 16:20
Can you add some more context, what exactly is
CanFrame
?– Simon Forsberg♦
Jun 21 at 14:08
Can you add some more context, what exactly is
CanFrame
?– Simon Forsberg♦
Jun 21 at 14:08
I don't think that's important at all. What I want to achieve is more concise and better looking code. It's pretty niche thing but if you want you can read about it here en.wikipedia.org/wiki/CAN_bus
– Ernest Zamelczyk
Jun 21 at 14:13
I don't think that's important at all. What I want to achieve is more concise and better looking code. It's pretty niche thing but if you want you can read about it here en.wikipedia.org/wiki/CAN_bus
– Ernest Zamelczyk
Jun 21 at 14:13
I'd recommend you to read Simon's guide to a good question
– Simon Forsberg♦
Jun 21 at 16:20
I'd recommend you to read Simon's guide to a good question
– Simon Forsberg♦
Jun 21 at 16:20
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
Probably very little beautification. I would be curious to see someone beautify it and prove me wrong. Initially I thought you could use Kotlin streams on the frame ByteArray. This way you could have done something equivalent to frame.filterIndexed(..).map(it->CanFrame(..))
etc. However then I noticed you were doing random access on the ByteArray: ex: ifmIndex + length + 4
, frame.copyOfRange(ifmIndex + 3, ifmIndex + 2 + length)
which would negate the purpose of streams which go one by one.
Also try using Arrow FP library (arrow-kt.io)
– Ananth Raghuraman
Jul 1 at 18:16
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Probably very little beautification. I would be curious to see someone beautify it and prove me wrong. Initially I thought you could use Kotlin streams on the frame ByteArray. This way you could have done something equivalent to frame.filterIndexed(..).map(it->CanFrame(..))
etc. However then I noticed you were doing random access on the ByteArray: ex: ifmIndex + length + 4
, frame.copyOfRange(ifmIndex + 3, ifmIndex + 2 + length)
which would negate the purpose of streams which go one by one.
Also try using Arrow FP library (arrow-kt.io)
– Ananth Raghuraman
Jul 1 at 18:16
add a comment |
up vote
0
down vote
Probably very little beautification. I would be curious to see someone beautify it and prove me wrong. Initially I thought you could use Kotlin streams on the frame ByteArray. This way you could have done something equivalent to frame.filterIndexed(..).map(it->CanFrame(..))
etc. However then I noticed you were doing random access on the ByteArray: ex: ifmIndex + length + 4
, frame.copyOfRange(ifmIndex + 3, ifmIndex + 2 + length)
which would negate the purpose of streams which go one by one.
Also try using Arrow FP library (arrow-kt.io)
– Ananth Raghuraman
Jul 1 at 18:16
add a comment |
up vote
0
down vote
up vote
0
down vote
Probably very little beautification. I would be curious to see someone beautify it and prove me wrong. Initially I thought you could use Kotlin streams on the frame ByteArray. This way you could have done something equivalent to frame.filterIndexed(..).map(it->CanFrame(..))
etc. However then I noticed you were doing random access on the ByteArray: ex: ifmIndex + length + 4
, frame.copyOfRange(ifmIndex + 3, ifmIndex + 2 + length)
which would negate the purpose of streams which go one by one.
Probably very little beautification. I would be curious to see someone beautify it and prove me wrong. Initially I thought you could use Kotlin streams on the frame ByteArray. This way you could have done something equivalent to frame.filterIndexed(..).map(it->CanFrame(..))
etc. However then I noticed you were doing random access on the ByteArray: ex: ifmIndex + length + 4
, frame.copyOfRange(ifmIndex + 3, ifmIndex + 2 + length)
which would negate the purpose of streams which go one by one.
answered Jun 29 at 23:11
Ananth Raghuraman
1
1
Also try using Arrow FP library (arrow-kt.io)
– Ananth Raghuraman
Jul 1 at 18:16
add a comment |
Also try using Arrow FP library (arrow-kt.io)
– Ananth Raghuraman
Jul 1 at 18:16
Also try using Arrow FP library (arrow-kt.io)
– Ananth Raghuraman
Jul 1 at 18:16
Also try using Arrow FP library (arrow-kt.io)
– Ananth Raghuraman
Jul 1 at 18:16
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f196952%2fparsing-can-frames-from-a-bytearray%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Can you add some more context, what exactly is
CanFrame
?– Simon Forsberg♦
Jun 21 at 14:08
I don't think that's important at all. What I want to achieve is more concise and better looking code. It's pretty niche thing but if you want you can read about it here en.wikipedia.org/wiki/CAN_bus
– Ernest Zamelczyk
Jun 21 at 14:13
I'd recommend you to read Simon's guide to a good question
– Simon Forsberg♦
Jun 21 at 16:20