fba-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # fba-cli: A CLI (command line interface) to execute FBA (fishbone analysis <img src="https://github.com/mbehr1/fishbone/blob/main/fishbone-icon2.png?raw=true" alt="icon" width="24">) files with DLT-logs/adlt
2
+
3
+ ## Summary
4
+
5
+ Executes fishbone-analysis files (fba) from the Visual Studio Code(tm) extension 'fishbone' [![Visual Studio Marketplace Version](https://img.shields.io/visual-studio-marketplace/v/mbehr1.fishbone.svg)](https://marketplace.visualstudio.com/items?itemName=mbehr1.fishbone) standalone - without vscode - on the console.
6
+
7
+ Execution performs:
8
+ - run all badges queries on a list of provided DLT logs
9
+ - generate a markdown report with any output from either the upper or the lower badge of all root causes.
10
+
11
+ ### How to use
12
+
13
+ Preconditions:
14
+ - Installed `adlt` and available in path. Check in terminal/console e.g. via `adlt --version`
15
+ - `node.js` v18 or higher installed. Check via `node --version`
16
+ - Install fba-cli via `npm install fba-cli -g`
17
+ - If adlt plugins shall be used a config file in json/jsonc/json5 format with
18
+ <details>
19
+ <summary>example json config file...</summary>
20
+
21
+ ```jsonc
22
+ {
23
+ "dlt-logs.plugins":[
24
+ // all plugins from dlt-logs/adlt are supported
25
+ { // e.g. NonVerbose plugin
26
+ "name": "NonVerbose",
27
+ "enabled": true,
28
+ "fibexDir": "<...path to non-verbose fibex files...>",
29
+ },
30
+ {
31
+ "name": "SomeIp",
32
+ "enabled": true,
33
+ "fibexDir": "<...path to someip fibex files...>"
34
+ },
35
+ {
36
+ "name": "Rewrite",
37
+ "enabled": true,
38
+ "rewrites": [
39
+ {
40
+ "name": "SYS/JOUR timestamp",
41
+ "filter": {
42
+ "apid": "SYS",
43
+ "ctid": "JOUR"
44
+ },
45
+ "payloadRegex": "^.*? .*? (?<timeStamp>\\d+\\.\\d+) (?<text>.*)$"
46
+ }
47
+ ]
48
+ },
49
+ {
50
+ "name": "CAN",
51
+ "enabled": true,
52
+ "fibexDir": "<...path to can fibex files...",
53
+ }
54
+ ]
55
+ }
56
+ ```
57
+ </details>
58
+
59
+
60
+ Call from terminal/console
61
+
62
+ ```bash
63
+ # fba-cli -c <config_file> <list of fba files> <list of DLT files>
64
+ # e.g.
65
+ fba-cli -c config.json analysis.fba recorded.dlt recorded_p2.dlt > analysis_report.md
66
+ ```
67
+ if you dont have adlt in path you can start it manually with the options
68
+ ```sh
69
+ cd 'path where adlt binary is installed'
70
+ adlt remote -p 7777
71
+ ```
72
+
73
+ and then use `fba-cli`:
74
+ ```bash
75
+ # fba-cli -p host:port -c <config_file> <list of fba files> <list of DLT files>
76
+ # e.g.
77
+ fba-cli -p 127.0.0.1:7777 -c config.json analysis.fba recorded.dlt recorded_p2.dlt > analysis_report.md
78
+ ```
79
+
80
+
81
+ ## Planned Features
82
+
83
+ * included messages from all badge queries that provided an output
84
+ - support graphical reports as well
85
+
86
+ ## Known Issues
87
+
88
+ - embedded markdown background descriptions will not be properly formatted
89
+
90
+ ## Contributions
91
+
92
+ Any and all test, code or feedback contributions are welcome.
93
+ Open an [issue](https://github.com/mbehr1/fba-cli/issues) or create a pull request to make this tool/lib work better for all.
94
+
95
+ [![Donations](https://www.paypalobjects.com/en_US/DK/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=2ZNMJP5P43QQN&source=url) Donations are welcome!
96
+
97
+ ## Third-party Content
98
+
99
+ This project leverages third party content. For details see the `dependencies` and `devDependencies` section in `package.json`.
100
+
101
+ Thanks to all contributors!
@@ -0,0 +1,430 @@
1
+ import { WebSocket } from 'ws';
2
+ import { spawn } from 'child_process';
3
+ import * as remote_types from './remote_types.js';
4
+ import { retryOperation } from './util.js';
5
+ const mapEAC = new Map();
6
+ const maprEAC = new Map();
7
+ let maxEAC = 0;
8
+ export function getIdxFromEAC(eac) {
9
+ let eMap = maprEAC.get(eac.e);
10
+ if (eMap === undefined) {
11
+ eMap = new Map();
12
+ maprEAC.set(eac.e, eMap);
13
+ }
14
+ let aMap = eMap.get(eac.a);
15
+ if (aMap === undefined) {
16
+ aMap = new Map();
17
+ eMap.set(eac.a, aMap);
18
+ }
19
+ let idx = aMap.get(eac.c);
20
+ if (idx !== undefined) {
21
+ return idx;
22
+ }
23
+ else {
24
+ idx = ++maxEAC;
25
+ aMap.set(eac.c, idx);
26
+ mapEAC.set(idx, eac);
27
+ return idx;
28
+ }
29
+ }
30
+ export function getEACFromIdx(idx) {
31
+ const eac = mapEAC.get(idx);
32
+ return eac;
33
+ }
34
+ export function char4U32LeToString(char4le) {
35
+ let codes = [char4le & 0xff, 0xff & (char4le >> 8), 0xff & (char4le >> 16), 0xff & (char4le >> 24)];
36
+ while (codes.length > 0 && codes[codes.length - 1] === 0) {
37
+ codes.splice(-1);
38
+ }
39
+ return String.fromCharCode(...codes);
40
+ }
41
+ export const MTIN_LOG_strs = ['', 'fatal', 'error', 'warn', 'info', 'debug', 'verbose', '', '', '', '', '', '', '', '', ''];
42
+ class AdltMsg {
43
+ _eac;
44
+ index;
45
+ htyp;
46
+ receptionTimeInMs;
47
+ timeStamp;
48
+ // lifecycle?: DltLifecycleInfoMinIF | undefined
49
+ lifecycle_id;
50
+ mcnt;
51
+ mstp;
52
+ mtin;
53
+ verbose;
54
+ payloadString;
55
+ constructor(binMsg /*, lifecycle?: DltLifecycleInfoMinIF*/) {
56
+ // cached ECU, APID, CTID:
57
+ this._eac = getEACFromIdx(getIdxFromEAC({ e: char4U32LeToString(binMsg.ecu), a: char4U32LeToString(binMsg.apid), c: char4U32LeToString(binMsg.ctid) }));
58
+ this.index = binMsg.index;
59
+ this.receptionTimeInMs = Number(binMsg.reception_time / 1000n);
60
+ this.timeStamp = binMsg.timestamp_dms;
61
+ //this.lifecycle = lifecycle
62
+ this.lifecycle_id = binMsg.lifecycle_id;
63
+ this.htyp = binMsg.htyp;
64
+ this.mcnt = binMsg.mcnt;
65
+ this.mstp = (binMsg.verb_mstp_mtin >> 1) & 0x7;
66
+ this.mtin = (binMsg.verb_mstp_mtin >> 4) & 0xf;
67
+ this.verbose = (binMsg.verb_mstp_mtin & 0x01) === 0x01;
68
+ this.payloadString = binMsg.payload_as_text;
69
+ }
70
+ get ecu() {
71
+ return this._eac.e;
72
+ }
73
+ get apid() {
74
+ return this._eac.a;
75
+ }
76
+ get ctid() {
77
+ return this._eac.c;
78
+ }
79
+ asRestObject(idHint) {
80
+ return {
81
+ id: this.index,
82
+ type: 'msg',
83
+ attributes: {
84
+ timeStamp: this.timeStamp,
85
+ ecu: this.ecu,
86
+ mcnt: this.mcnt,
87
+ apid: this.apid,
88
+ ctid: this.ctid,
89
+ mtin: MTIN_LOG_strs[this.mtin],
90
+ payloadString: this.payloadString,
91
+ lifecycle: this.lifecycle_id, // this.lifecycle ? this.lifecycle.persistentId : undefined,
92
+ },
93
+ };
94
+ }
95
+ }
96
+ export class AdltRemoteClient {
97
+ fileBasedMsgsHandler;
98
+ webSocket;
99
+ adltVersion;
100
+ webSocketIsConnected = false;
101
+ webSocketErrors = [];
102
+ _reqCallbacks = [];
103
+ streamMsgs = new Map();
104
+ constructor(fileBasedMsgsHandler) {
105
+ this.fileBasedMsgsHandler = fileBasedMsgsHandler;
106
+ }
107
+ close() {
108
+ if (this.webSocket) {
109
+ // todo if connected???
110
+ this.webSocket.close();
111
+ }
112
+ }
113
+ /**
114
+ * connect to (an existing) adlt process via websocket
115
+ *
116
+ * Does not start the adlt process!
117
+ *
118
+ * @param wssUrl url of the adlt remote websocket. e.g. ws://localhost:7777
119
+ * @returns the adlt version connected to
120
+ */
121
+ connectToWebSocket(wssUrl) {
122
+ const webSocket = new WebSocket(wssUrl, [], { perMessageDeflate: false, origin: 'adlt-logs', maxPayload: 1000000000 });
123
+ this.webSocket = webSocket;
124
+ webSocket.binaryType = 'arraybuffer'; // todo ArrayBuffer needed for sink?
125
+ return new Promise((resolve, reject) => {
126
+ let promiseWaits = true;
127
+ webSocket.on('message', (data, isBinary) => {
128
+ try {
129
+ if (isBinary) {
130
+ this.onBinaryMessage(data);
131
+ }
132
+ else {
133
+ const text = data.toString();
134
+ if (text.startsWith('info:')) {
135
+ // todo still used?
136
+ console.info(`AdltRemoteClient.on(message) info:`, text);
137
+ }
138
+ else if (this._reqCallbacks.length > 0) {
139
+ // response to a request:
140
+ // console.info(`AdltRemoteClient.on(message) response for request:`, text)
141
+ let cb = this._reqCallbacks.shift();
142
+ if (cb) {
143
+ cb(text);
144
+ }
145
+ }
146
+ else {
147
+ console.warn(`AdltRemoteClient.on(message) unexpected text=`, text);
148
+ }
149
+ }
150
+ }
151
+ catch (e) {
152
+ console.error(`ws on message got error:${e}\n`);
153
+ }
154
+ });
155
+ webSocket.on('upgrade', (response) => {
156
+ // console.log(`AdltRemoteClient.on(upgrade) got response:`) //, response)
157
+ let ah = response.headers['adlt-version'];
158
+ this.adltVersion = ah && !Array.isArray(ah) ? ah : ah && Array.isArray(ah) ? ah.join(',') : undefined;
159
+ if (this.adltVersion) {
160
+ /*
161
+ if (!semver.satisfies(this.adltVersion, MIN_ADLT_VERSION_SEMVER_RANGE)) {
162
+ vscode.window.showErrorMessage(
163
+ `Your adlt version is not matching the required version!\nPlease correct!\nDetected version is '${this.adltVersion}' vs required '${MIN_ADLT_VERSION_SEMVER_RANGE}.'`,
164
+ { modal: true },
165
+ )
166
+ } else {
167
+ console.log(`adlt.AdltDocumentProvider got matching adlt version ${this.adltVersion} vs ${MIN_ADLT_VERSION_SEMVER_RANGE}.`)
168
+ }*/
169
+ //console.log(`AdltRemoteClient.on(upgrade) got adlt version:${this.adltVersion}`)
170
+ }
171
+ });
172
+ webSocket.on('open', () => {
173
+ this.webSocketIsConnected = true;
174
+ this.webSocketErrors = [];
175
+ if (promiseWaits) {
176
+ promiseWaits = false;
177
+ resolve(this.adltVersion || 'no version');
178
+ }
179
+ });
180
+ webSocket.on('close', () => {
181
+ this.webSocketIsConnected = false;
182
+ this.webSocketErrors.push('wss closed');
183
+ // console.warn(`AdltRemoteClient.on(close) wss got close`)
184
+ // this.emitStatusChanges.fire(this.uri)
185
+ });
186
+ webSocket.on('error', (err) => {
187
+ console.warn(`AdltRemoteClient.on(error) wss got error:`, err);
188
+ this.webSocketErrors.push(`error: ${err}`);
189
+ if (promiseWaits) {
190
+ promiseWaits = false;
191
+ reject(err);
192
+ }
193
+ // this.emitStatusChanges.fire(this.uri)
194
+ });
195
+ });
196
+ }
197
+ sendAndRecvAdltMsg(req) {
198
+ return new Promise((resolve, reject) => {
199
+ if (this.webSocket) {
200
+ this._reqCallbacks.push((response) => {
201
+ // if we get an error/n ok we do reject as well:
202
+ if (response.startsWith('ok:')) {
203
+ resolve(response);
204
+ }
205
+ else {
206
+ console.warn(`AdltRemoteClient.sendAndRecvAdltMsg got nok ('${response}') for request '${req}'`);
207
+ reject(response);
208
+ }
209
+ });
210
+ this.webSocket.send(req, (err) => {
211
+ if (err) {
212
+ console.warn(`AdltRemoteClient.sendAndRecvAdltMsg wss got error:`, err);
213
+ this.webSocketErrors.push(`wss send failed with:${err}`);
214
+ // todo! this.emitStatusChanges.fire(this.uri);
215
+ }
216
+ });
217
+ }
218
+ else {
219
+ console.error(`AdltRemoteClient.sendAndRecvAdltMsg got no webSocket yet!`);
220
+ reject(`AdltRemoteClient.sendAndRecvAdltMsg got no webSocket yet!`);
221
+ }
222
+ });
223
+ }
224
+ onBinaryMessage(data) {
225
+ try {
226
+ const bin_type = remote_types.readBinType(data);
227
+ switch (bin_type.tag) {
228
+ case 'DltMsgs':
229
+ case 'StreamInfo':
230
+ {
231
+ let streamId = bin_type.tag === 'DltMsgs' ? bin_type.value[0] : bin_type.value.stream_id;
232
+ let streamData = this.streamMsgs.get(streamId);
233
+ if (streamData && !Array.isArray(streamData)) {
234
+ this.processBinStreamMsgs(bin_type, streamData);
235
+ }
236
+ else {
237
+ // we store the pure data for later processing:
238
+ if (!streamData) {
239
+ streamData = [bin_type];
240
+ this.streamMsgs.set(streamId, streamData);
241
+ }
242
+ else {
243
+ streamData.push(bin_type);
244
+ if (streamData.length > 3) {
245
+ console.warn(`adlt.on(binary): appended ${bin_type.tag} for yet unknown stream=${streamId}, streamData.length=${streamData.length}`);
246
+ }
247
+ }
248
+ }
249
+ }
250
+ break;
251
+ case 'FileInfo':
252
+ case 'Lifecycles':
253
+ case 'EacInfo':
254
+ case 'PluginState':
255
+ {
256
+ this.fileBasedMsgsHandler(bin_type);
257
+ }
258
+ break;
259
+ default:
260
+ console.warn(`ws on binary message ignored:${bin_type.tag}`);
261
+ break;
262
+ }
263
+ }
264
+ catch (e) {
265
+ console.error(`ws on binary message got error:${e}\n`);
266
+ }
267
+ }
268
+ processBinStreamMsgs(bin_type, streamData) {
269
+ try {
270
+ switch (bin_type.tag) {
271
+ case 'DltMsgs':
272
+ const [streamId, msgs] = bin_type.value;
273
+ if (msgs.length === 0) {
274
+ // indicates end of query:
275
+ if (streamData.sink.onDone) {
276
+ streamData.sink.onDone();
277
+ }
278
+ this.streamMsgs.delete(streamId);
279
+ //console.error(`adlt.processBinDltMsgs deleted stream #${streamId}\n\n`)
280
+ }
281
+ else {
282
+ for (let i = 0; i < msgs.length; ++i) {
283
+ let binMsg = msgs[i];
284
+ let msg = new AdltMsg(binMsg /*, this.lifecycleInfoForPersistentId(binMsg.lifecycle_id)*/);
285
+ streamData.msgs.push(msg);
286
+ }
287
+ if (streamData.sink.onNewMessages) {
288
+ streamData.sink.onNewMessages(msgs.length);
289
+ }
290
+ }
291
+ break;
292
+ case 'StreamInfo':
293
+ const si = bin_type.value;
294
+ // console.log(`adlt.processBinStreamMsgs: StreamInfo stream=${si.stream_id}, stream msgs=${si.nr_stream_msgs} processed=${si.nr_file_msgs_processed} total=${si.nr_file_msgs_total}`);
295
+ if (streamData.sink.onStreamInfo) {
296
+ streamData.sink.onStreamInfo(si.nr_stream_msgs, si.nr_file_msgs_processed, si.nr_file_msgs_total);
297
+ }
298
+ break;
299
+ }
300
+ }
301
+ catch (e) {
302
+ console.error(`adlt.processBinStreamMsgs got error:${e}\n`);
303
+ }
304
+ }
305
+ /**
306
+ * calculate and return the matching messages. Does not modify the current content/view.
307
+ * @param filters list of filters to use. Should only be pos and neg filters. Others will be ignored.
308
+ * @param maxMsgsToReturn maximum number of messages to return. As this is no async function the caller
309
+ * needs to be careful!
310
+ * @returns list of matching messages (as Promise)
311
+ */
312
+ getMatchingMessages(filters, maxMsgsToReturn) {
313
+ let p = new Promise((resolve, reject) => {
314
+ const matchingMsgs = [];
315
+ // sort the filters here into the enabled pos and neg:
316
+ try {
317
+ let filterStr = filters
318
+ .filter((f) => ('enabled' in f ? f.enabled : true))
319
+ .map((f) => JSON.stringify({ ...f, enabled: true }))
320
+ .join(',');
321
+ this.sendAndRecvAdltMsg(`query {"window":[0,${maxMsgsToReturn}], "filters":[${filterStr}]}`)
322
+ .then((response) => {
323
+ const streamObj = JSON.parse(response.substring(10));
324
+ let sink = {
325
+ onDone() {
326
+ // console.log(`adlt.getMatchingMessages done matchingMsgs.length=${matchingMsgs.length}`)
327
+ resolve(matchingMsgs);
328
+ },
329
+ };
330
+ // here some data might be already there for that stream.
331
+ // this can happen even though the wss data arrives sequentially but the processing
332
+ // here for wss data is a direct call vs. an asyn .then()...
333
+ let curStreamMsgData = this.streamMsgs.get(streamObj.id);
334
+ let streamData = { msgs: matchingMsgs, sink: sink };
335
+ this.streamMsgs.set(streamObj.id, streamData);
336
+ if (curStreamMsgData && Array.isArray(curStreamMsgData)) {
337
+ // process the data now:
338
+ curStreamMsgData.forEach((msgs) => this.processBinStreamMsgs(msgs, streamData));
339
+ }
340
+ })
341
+ .catch((reason) => {
342
+ reject(reason);
343
+ });
344
+ }
345
+ catch (e) {
346
+ throw new Error(`getMatchingMessages failed due to error '${e}'`);
347
+ reject(e);
348
+ }
349
+ });
350
+ return p;
351
+ }
352
+ }
353
+ /**
354
+ * get the host&port (e.g. 127.0.0.1:7777) & spawned process of adlt process.
355
+ * Starts adlt and tries to find an open port in range
356
+ * 6700-6789.
357
+ *
358
+ * Sets internal variables _adltProcess and _adltPort as well.
359
+ * @returns a promise for the host&port and the spawned process
360
+ */
361
+ export function getAdltProcessAndPort(adltCommand, outStream) {
362
+ return new Promise((resolve, reject) => {
363
+ // start it
364
+ // currently it retries 89 times even if spawnAdltProcess rejects with ENOENT! todo
365
+ retryOperation((retries_left) => spawnAdltProcess(adltCommand, 6789 - retries_left, outStream), 10, 89)
366
+ .then(([childProc, port]) => {
367
+ resolve({ hostAndPort: `127.0.0.1:${port}`, process: childProc });
368
+ })
369
+ .catch((reason) => {
370
+ reject(reason);
371
+ });
372
+ });
373
+ }
374
+ /**
375
+ * spawn an adlt process at specified port.
376
+ *
377
+ * Checks whether the process could be started sucessfully and
378
+ * whether its listening on the port.
379
+ *
380
+ * Uses adltCommand to start the process and the params 'remote -p<port>'.
381
+ *
382
+ * It listens on stdout and stderr (and on 'close' and 'error' events) and forwards output to the outStream.
383
+ * This could be improved/changed to listen only until a successful start is detected.
384
+ *
385
+ * Rejects with 'ENOENT' or 'AddrInUse' or 'did close unexpectedly' in case of errors.
386
+ *
387
+ * @param port number of port to use for remote websocket
388
+ * @returns pair of ChildProcess started and the port number
389
+ */
390
+ function spawnAdltProcess(adltCommand, port, outStream) {
391
+ return new Promise((resolve, reject) => {
392
+ let finishedListening = [false]; // todo could be a regular boolean
393
+ let childProc = spawn(adltCommand, ['remote', `-p=${port}`], { detached: false, windowsHide: true });
394
+ childProc.on('error', (err) => {
395
+ outStream.write(`spawnAdltProcess process got err='${err}'\n`);
396
+ if (!finishedListening[0] && err.message.includes('ENOENT')) {
397
+ finishedListening[0] = true;
398
+ reject(`ENOENT - ${adltCommand} not found in path?. Detail error: ${err.message}`);
399
+ }
400
+ });
401
+ childProc.on('close', (code, signal) => {
402
+ outStream.write(`spawnAdltProcess(port=${port}) process got close code='${code}' signal='${signal}'\n`);
403
+ if (!finishedListening[0]) {
404
+ finishedListening[0] = true;
405
+ reject('did close unexpectedly');
406
+ }
407
+ });
408
+ childProc?.stdout?.on('data', (data) => {
409
+ // todo or use 'spawn' event?
410
+ try {
411
+ if (!finishedListening[0] && `${data}`.includes('remote server listening on')) {
412
+ finishedListening[0] = true; // todo stop searching for ... (might as well stop listening completely for stdout)
413
+ resolve([childProc, port]);
414
+ }
415
+ outStream.write(data);
416
+ }
417
+ catch (err) {
418
+ outStream.write(`spawnAdltProcess(port=${port}) process stdout got err='${err}, typeof data=${typeof data}'\n`);
419
+ }
420
+ });
421
+ childProc?.stderr?.on('data', (data) => {
422
+ outStream.write(`spawnAdltProcess(port=${port}) process got stderr='${data}'\n`);
423
+ if (!finishedListening[0] && `${data}`.includes('AddrInUse')) {
424
+ finishedListening[0] = true;
425
+ reject('AddrInUse');
426
+ }
427
+ });
428
+ });
429
+ }
430
+ //# sourceMappingURL=adltRemoteClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adltRemoteClient.js","sourceRoot":"","sources":["../src/adltRemoteClient.ts"],"names":[],"mappings":"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"}