Skip to content

Instantly share code, notes, and snippets.

@brandonros
Last active June 3, 2019 18:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brandonros/239592a42ef0513c859869140df1b51d to your computer and use it in GitHub Desktop.
Save brandonros/239592a42ef0513c859869140df1b51d to your computer and use it in GitHub Desktop.
node.js implementation of chunking a CAN response into ISO-TP frames
const FIRST_FRAME_PCI_BYTE = 0x01
const CONSECUTIVE_FRAME_PCI_BYTE = 0x02
const FIRST_FRAME_DATA_LENGTH = 5
const CONSECUTIVE_FRAME_DATA_LENGTH = 7
const PADDING_BYTE = 0xAA
const buildFirstFrame = (responseSid, data) => {
const responseLength = data.length + 1 // add a byte for response SID
const firstFrameData = data.slice(0, FIRST_FRAME_DATA_LENGTH)
const firstFrameHeader = Buffer.from([
(FIRST_FRAME_PCI_BYTE << 4) ^ (responseLength >> 8),
responseLength & 0xFF,
responseSid
])
return Buffer.concat([
firstFrameHeader,
firstFrameData
])
}
const buildConsecutiveFrame = (consecutiveFrameCounter, remainingData) => {
let frameData = remainingData.slice(0, CONSECUTIVE_FRAME_DATA_LENGTH)
// Pad last frame
if (frameData.length < CONSECUTIVE_FRAME_DATA_LENGTH) {
const paddingLength = 7 - frameData.length
let padding = Buffer.from(new Array(paddingLength).fill(PADDING_BYTE))
frameData = Buffer.concat([frameData, padding])
}
const consecutiveFrameHeader = Buffer.from([
(CONSECUTIVE_FRAME_PCI_BYTE << 4) ^ consecutiveFrameCounter
])
return Buffer.concat([
consecutiveFrameHeader,
frameData
])
}
const buildIsoTpFrames = (responseSid, data) => {
const frames = []
frames.push(buildFirstFrame(responseSid, data))
let remainingData = data.slice(FIRST_FRAME_DATA_LENGTH)
const numConsecutiveFrames = Math.ceil(remainingData.length / CONSECUTIVE_FRAME_DATA_LENGTH)
let consecutiveFrameCounter = 1
for (let i = 0; i < numConsecutiveFrames; ++i) {
frames.push(buildConsecutiveFrame(consecutiveFrameCounter, remainingData))
consecutiveFrameCounter += 1
// Wrap consecutive frame counter
if (consecutiveFrameCounter === 10) {
consecutiveFrameCounter = 0
}
remainingData = remainingData.slice(CONSECUTIVE_FRAME_DATA_LENGTH)
}
return frames
}
const vin = 'WDDZF8KB1KA539167'
const vinDataIdentifier = 0xF190
const readDataResponse = Buffer.concat([
Buffer.from([vinDataIdentifier >> 8, vinDataIdentifier & 0xFF]),
Buffer.from(vin)
])
buildIsoTpFrames(0x62, readDataResponse)
@brandonros
Copy link
Author

brandonros commented Jun 3, 2019

> buildIsoTpFrames(0x62, readDataResponse)
[ <Buffer 10 14 62 f1 90 57 44 44>,
  <Buffer 21 5a 46 38 4b 42 31 4b>,
  <Buffer 22 41 35 33 39 31 36 37> ]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment