Parsing CAN frames from a ByteArray

The name of the pictureThe name of the pictureThe name of the pictureClash 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++










share|improve this question





















  • 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
















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++










share|improve this question





















  • 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












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++










share|improve this question













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++












share|improve this question












share|improve this question




share|improve this question








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 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
















  • 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















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










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.






share|improve this answer





















  • Also try using Arrow FP library (arrow-kt.io)
    – Ananth Raghuraman
    Jul 1 at 18:16










Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















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






























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.






share|improve this answer





















  • Also try using Arrow FP library (arrow-kt.io)
    – Ananth Raghuraman
    Jul 1 at 18:16














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.






share|improve this answer





















  • Also try using Arrow FP library (arrow-kt.io)
    – Ananth Raghuraman
    Jul 1 at 18:16












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.






share|improve this answer













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.







share|improve this answer













share|improve this answer



share|improve this answer











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
















  • 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












 

draft saved


draft discarded


























 


draft saved


draft discarded














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













































































Popular posts from this blog

Greedy Best First Search implementation in Rust

Function to Return a JSON Like Objects Using VBA Collections and Arrays

C++11 CLH Lock Implementation