-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
174 lines (167 loc) · 6.46 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
const EventEmitter = require('events')
const assert = require('assert')
const split = require('split')
const execa = require('execa')
const fs = require('fs')
const interfaceName = process.env.npm_package_config_interface_name
const sourceId = process.env.npm_package_config_source_id
const destinationId = process.env.npm_package_config_destination_id
const address = process.env.npm_package_config_address
const size = process.env.npm_package_config_size
const tune = fs.readFileSync('tune.bin')
const emitter = new EventEmitter()
const state = {}
const send = async (serviceIdentifier, response) => {
await new Promise(resolve => setTimeout(resolve, 10))
console.log(`Sending request... interfaceName=${interfaceName} sourceId=${sourceId} destinationId=${destinationId}`)
console.log(`${serviceIdentifier.toString(16).padStart(2, '0')}${response.toString('hex')}`)
const formattedResponse = response.length ? response.toString('hex').match(/.{1,2}/g).join(' ').trim() : ''
const formattedBody = `${serviceIdentifier.toString(16).padStart(2, '0')} ${formattedResponse}`
const subprocess = execa('isotpsend', [interfaceName, '-s', sourceId, '-d', destinationId, '-p', 'AA:AA'])
subprocess.stdin.end(formattedBody.trim())
await subprocess
}
const recv = () => new Promise(resolve => emitter.once('message', resolve))
const run = async () => {
const steps = [
async () => {
console.log('step 01 - startDiagnosticSession extended')
await send(0x10, Buffer.from('03', 'hex'))
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x50)
},
async () => {
console.log('step 02 - readDataByIdentifier softwareNumber')
await send(0x22, Buffer.from('F121', 'hex'))
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x62)
state.softwareNumber = response.slice(1)
},
async () => {
console.log('step 03 - readDataByIdentifier vin')
await send(0x22, Buffer.from('F190', 'hex'))
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x62)
state.vin = response.slice(1)
},
async () => {
console.log('step 04 - readDataByIdentifier partNumber')
await send(0x22, Buffer.from('F111', 'hex'))
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x62)
state.partNumber = response.slice(1)
},
async () => {
console.log('step 05 - startDiagnosticSession ecuProgramming')
await send(0x10, Buffer.from('03', 'hex'))
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x50)
},
async () => {
console.log('step 06 - securityAccess securityAccess')
await send(0x27, Buffer.from('05', 'hex'))
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x67)
state.seed = response.slice(2)
state.key = Buffer.from('57E951FD', 'hex') // TODO: implement calculateKeyFromSeed
},
async () => {
console.log('step 07 - securityAccess sendKey')
await send(0x27, Buffer.from(`06${state.key.toString('hex')}`, 'hex'))
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x67 && response[1] === 0x02)
},
async () => {
console.log('step 08 - readDataByIdentifier F15A')
await send(0x22, Buffer.from('F15A', 'hex'))
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x62)
state.f15a = response.slice(1)
},
async () => {
console.log('step 09 - activateRoutine 0x01FF')
await send(0x31, Buffer.from('01FF00', 'hex'))
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x71)
},
async () => {
console.log('step 10 - readDataByIdentifier F15B')
await send(0x22, Buffer.from('F15B', 'hex'))
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x62)
state.f15b = response.slice(1)
},
async () => {
console.log('step 11 - requestDownload')
await send(0x34, Buffer.from(`0044${address}${size}`, 'hex'))
const response = await recv()
console.log(response.toString('hex'))
state.transferDataChunkIndex = 0x01
assert(response[0] === 0x74)
console.log(state)
},
async () => {
console.log('step 12 - writeDataByIdentifier F15A')
await send(0x2E, Buffer.from('F15A0000030D090600000000', 'hex'))
// might be f15a020004110a0b00191471 (comes from read 0xF15B?)
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x6E)
},
async () => {
console.log('step 13 - transferData')
const chunkSize = 240
for (let i = 0; i < tune.length; i += chunkSize) {
console.log(`${i.toString(16)} / ${tune.length.toString(16)}`)
const chunk = tune.slice(i, i + chunkSize)
await send(0x36, Buffer.from(`${state.transferDataChunkIndex.toString(16).padStart(2, '0')}${chunk.toString('hex')}`, 'hex'))
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x76 && response[1] === state.transferDataChunkIndex)
state.transferDataChunkIndex += 1
if (state.transferDataChunkIndex === 0x100) {
state.transferDataChunkIndex = 0x00
}
}
},
async () => {
console.log('step 14 - requestTransferExit')
await send(0x37, Buffer.from([]))
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x77)
},
async () => {
console.log('step 15 - ecuReset')
await send(0x11, Buffer.from('01', 'hex'))
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x51)
},
async () => {
console.log('step 16 - clearDtc')
await send(0x14, Buffer.from('FFFFFF', 'hex'))
const response = await recv()
console.log(response.toString('hex'))
assert(response[0] === 0x54)
}
]
for (let stepIndex = 0; stepIndex < steps.length; ++stepIndex) {
await steps[stepIndex]()
}
process.exit(0)
}
process.stdin
.pipe(split())
.on('data', (data) => emitter.emit('message', Buffer.from(data.replace(/ /g, ''), 'hex')))
run()