Parsing CAN frames from a ByteArray
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
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
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
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
edited Jun 30 at 2:44
200_success
123k14143399
123k14143399
asked Jun 21 at 7:40
Ernest Zamelczyk
112
112
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
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
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
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
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
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