UNPKG

keyupdateddtscript

Version:

Generate DDT2k scripts for provisionning many keys

304 lines (273 loc) 10.7 kB
#!/usr/bin/env node /** @fileOverview * Script for generating scripts to make key prov * * */ (function(root) { "use strict"; // script generator var DDTscriptGenerator = require('../index.js'); // getopt const getopt_module = require('posix-getopt'); const path = require('path'); const fs = require('fs'); var print_usage = () => { /** Implem of print_usage */ console.info("%s: Usage: %s [<OPTIONS>] <COMMAND> [<ARGUMENTS>]", flags.cmdname, flags.cmdname); console.info(" This command aims at generating script allowing to test ECU key "); console.info(" update. "); console.info(" OPTIONS: "); console.info(" -v|--verbose be more verbose when running. Use sev- "); console.info(" eral times in order to raise verbosity."); console.info(" -q|--quiet be quiet for list (no headers). "); console.info(" COMMANDS: "); console.info(" -h|--help display this help message. "); console.info(" -s|--script generate key update script. "); console.info(" -l|--list list known MAC ecu. "); console.info(" "); console.info(" ARGUMENTS: "); console.info(" -o|--output[=]<file>|- name of the output script file. If '-' "); console.info(" is provided, stdout is used. Default "); console.info(" is stdout. "); console.info(" -w|--wait[=][<WAIT-TIME>] time to wait between each command in "); console.info(" ms. Default is 500. "); console.info(" -C|--cid[=]<CID> Provides the CID to use. Default is "); console.info(" 4096 (0x1000). "); console.info(" -e|--ecu[=]<ECU-NAME> the name of the ECU for which the "); console.info(" script is generated. "); console.info(" -n|--num[=]<NB_TESTS> the number of key update tests. "); console.info(" -O|--overwrite overwrite output file if file already "); console.info(" exists. "); console.info(" "); console.info("Copyright © 2023 RENAULT GROUP / Rémi COHEN SCALI <remi.cohen-scali@renault.com> "); }; var flags = { cmdname: (path.basename(process.argv[0]) === "node" || path.basename(process.argv[0]) === "node.exe" ? path.basename(process.argv[1]) : path.basename(process.argv[0])), outputFileFlag: false, outputFile: undefined, cidFlag: false, cid: 4096, ecuFlag: false, ecu: undefined, waitFlag: false, wait: undefined, numFlag: false, num: undefined, helpFlag: false, verboseFlag: 0, quietFlag: false, listFlag: false, scriptFlag: false, overwriteFlag: false }; /*jslint indent: 2, bitwise: false, nomen: false, plusplus: false, white: false, regexp: false */ /*global document, window, escape, unescape, module, require, Uint32Array */ var option; /* Instanciate option parser for processing all command line arguments for getting options */ var parser = new getopt_module.BasicParser( 'v(verbose)h(help)q(quiet)l(list)s(script)o:(output)e:(ecu)w:(wait)C:(cid)n:(num)O(overwrite)', process.argv ); /* Processing all command line arguments */ while ((option = parser.getopt()) !== undefined && !option.error) { switch (option.option) { // --help/-h: display help case 'h': flags.helpFlag = true; if (flags.verboseFlag) console.info("%s: info: Help requested.", flags.cmdname); break; // --verbose/-v: Increase verbosity case 'v': flags.verboseFlag++; if (flags.verboseFlag) console.info("%s: info: verbosity (-v) increased to %s", flags.cmdname, flags.verboseFlag); break; // --quiet/-q: Be quiet for listing ECU (no headers and associated data, just names) case 'q': flags.quietFlag = true; if (flags.verboseFlag) console.info("%s: info: quiet (-q) option selected", flags.cmdname); break; // --list/-l: Increase verbosity case 'l': flags.listFlag = true; if (flags.verboseFlag) console.info("%s: info: list (-l) ECU requested", flags.cmdname); break; // --script/-s: generate script command case 's': flags.scriptFlag = true; if (flags.verboseFlag) console.info("%s: info: script (-s) requested", flags.cmdname); break; // --wait/-w: Increase verbosity case 'w': flags.waitFlag = true; flags.wait = option.optarg; if (flags.verboseFlag) console.info("%s: info: wait (-w) time set to %s", flags.cmdname, flags.wait); break; // --output/-o: Output file case 'o': flags.outputFileFlag = true; flags.outputFile = option.optarg; if (flags.verboseFlag) console.info("%s: info: Output file (-o) set to '%s'.", flags.cmdname, flags.outputFile); break; // --ecu/-e: ECU for which to gen script case 'e': flags.ecuFlag = true; flags.ecu = option.optarg; if (flags.verboseFlag) console.info("%s: info: ECU (-e) set to '%s'.", flags.cmdname, flags.ecu); break; // --cid/-c: CID for which to gen script case 'C': flags.cidFlag = true; flags.cid = (option.optarg[1] === 'x' ? Number.parseInt(option.optarg, 16) : Number.parseInt(option.optarg, 10)); if (flags.verboseFlag) console.info("%s: info: CID (-c) set to '%s'.", flags.cmdname, flags.cid); break; // --num/-n: number of tests case 'n': flags.numFlag = true; flags.num = (option.optarg[1] === 'x' ? Number.parseInt(option.optarg, 16) : Number.parseInt(option.optarg)); if (flags.verboseFlag) console.info("%s: info: Number (-n) set to '%s'.", flags.cmdname, flags.num); break; // --overwrite/-O: overwrite flag case 'O': flags.overwriteFlag = true; if (flags.verboseFlag) console.info("%s: info: Overwrite (-O) flag requested.", flags.cmdname); break; // Unknown option arg case '?': print_usage(); process.exit(GENSCRIPT_ERROR_BASE); default: break; } } /* * Print help & exit */ if (flags.helpFlag) { print_usage(); process.exit(0); } /* * List MAC ECU */ else if (flags.listFlag) { if (!flags.quietFlag) { console.info(`ECU | Addr | Resp. Req | Descr`); console.info(`--------+-------+---------------+-------------------------------------------`); } var scgen = new DDTscriptGenerator(flags.ecu, flags.cid); Object .keys(scgen.ECUS) .filter((ecu) => { return(scgen.ECUS[ecu].ismac) }) .forEach((ecu) => { if (flags.quietFlag) console.info(`${ecu}`); else console.info(`${ecu} | ${scgen.ECUS[ecu].addr} | ${scgen.ECUS[ecu].respreq?'true':'false'} | ${scgen.ECUS[ecu].descr}`); }); } /* * Generate script for ECU * */ else if (flags.scriptFlag) { if (!flags.outputFileFlag && flags.verboseFlag) console.warn("%s: warning: output file was not provided ! Printing script on stdout !", flags.cmdname); if (!flags.cidFlag && flags.verboseFlag) console.warn("%s: warning: CID was not provided ! Implicit CID used at value 1 !", flags.cmdname); if (!flags.ecuFlag) { console.error("%s: error: script generation requested but no ECU provided !", flags.cmdname); print_usage(); process.exit(1); } else { try { var scgen = new DDTscriptGenerator(flags.ecu, flags.cid, flags.wait); var scrBuf = scgen.get_script(flags.num); if (!flags.outputFileFlag) console.log(scrBuf.toString()); else { let statobj = undefined; try { statobj = fs.statSync(flags.outputFile); } catch(err) { } if (statobj !== undefined && statobj.isFile() && !flags.overwriteFlag) { console.error("%s: error: file '%s' already exists! Use argument (-O) to overwrite!", flags.cmdname, flags.outputFile); process.exit(2); } else if (statobj !== undefined && statobj.isDirectory()) { console.error("%s: error: a directory '%s' already exists!", flags.cmdname, flags.outputFile); process.exit(3); } if (statobj === undefined || (statobj !== undefined && statobj.isFile() && flags.overwriteFlag)) { fs.writeFileSync(flags.outputFile, scrBuf.toString(), (err) => { console.error("%s: error: %s", flags.cmdname, err); } ); if (flags.verboseFlag) console.info("%s: info: script file '%s' written.", flags.cmdname, flags.outputFile); } } } catch(err) { console.info("%s: error: %s! Use -l for listing ECUs!", flags.cmdname, err); process.exit(4); } } } else if (!flags.scriptFlag && !flags.listFlag) { console.error("%s: error: missing command arg (-s or -l)", flags.cmdname); print_usage(); process.exit(5); } else { console.error("%s: error: missing command arg (-s or -l)", flags.cmdname); print_usage(); process.exit(6); } })(this); /* * vim: et:ts=4:sw=4:sts=4 * -*- mode: JavaScript; coding: utf-8-unix; tab-width: 4 -*- */