text: #!/usr/bin/env node
  
  "use strict";
  
  /**
   * Command-line interface to packet decoding
   *
   * Usage:
   *   lora-packet-decode --hex <packet>
   *   lora-packet-decode --base64 <packet>
   */
  
  var lora_packet = require('../lib/index.js');
  
  var cmdlineArgs = process.argv;
  
  var hexOption = cmdlineArgs.indexOf("--hex");
  var b64Option = cmdlineArgs.indexOf("--base64");
  
  var nwkOption = cmdlineArgs.indexOf("--nwkkey");
  var appOption = cmdlineArgs.indexOf("--appkey");
  
  var fCntMSBOption = cmdlineArgs.indexOf("--cntmsb");
  
  function printUsageAndExit() {
      console.log ("Usage:");
      console.log ("\tlora-packet-decode [--nwkkey <NwkSKey> --appkey <AppSKey> --cntmsb <fCntMSB>] --{hex|base64} <data>");
      process.exit(1);
  }
  
  // need both keys (or neither)
  if (nwkOption >= 0 && ! (appOption >= 0) || !(nwkOption >= 0) && appOption >= 0) {
      printUsageAndExit()
  }
  
  var inputData;
  if (hexOption != -1 && hexOption+1 <  cmdlineArgs.length) {
      var arg = cmdlineArgs[hexOption+1];
      console.log("decoding from Hex: ", arg);
      inputData = Buffer.from(arg, 'hex');
  } else if (b64Option != -1 && b64Option+1 <  cmdlineArgs.length) {
          var arg = cmdlineArgs[b64Option+1];
          console.log("decoding from Base64: ", arg);
          inputData = Buffer.from(arg, 'base64');
  } else {
  	printUsageAndExit();
  }
  
  var packet = lora_packet.fromWire(inputData);
  console.log ("Decoded packet")
  console.log ("--------------")
  var res = packet.toString();
  if (nwkOption >= 0 && appOption >= 0) {
    var fCntMSBBytes = (fCntMSBOption >= 0) ? [ cmdlineArgs[fCntMSBOption + 1] & 0xff,  cmdlineArgs[fCntMSBOption + 1] & 0xff00] : null; //[0x00, 0x00];
    if (fCntMSBBytes) var fCntMSB =  new Buffer.from(fCntMSBBytes);
  
    var nwkKey = Buffer.from(cmdlineArgs[nwkOption+1], 'hex')
    var appKey = Buffer.from(cmdlineArgs[appOption+1], 'hex')
    var micOk = lora_packet.verifyMIC(packet, nwkKey, appKey, fCntMSB) ? " (OK)"
                : (" (BAD != "+asHexString(lora_packet.calculateMIC(packet, nwkKey, appKey, fCntMSB))+")");
    var plaintext = asHexString(lora_packet.decrypt(packet, appKey, nwkKey, fCntMSB));
    res = res.replace(/  MIC = [0-9a-fA-F]+/, '$&'+micOk);
    res = res.replace(/  FRMPayload = [0-9a-fA-F]+/, '$&\n'+
                      "             Plaintext = "+plaintext+" ('"+asAscii(plaintext)+"')");
  }
  console.log (res);
  
  function asHexString(buf) {
      return buf.toString('hex').toUpperCase();
  }
  
  function asAscii(hex) {
      return hex.replace(/../g, function(x) {
        var code = parseInt(x, 16);
        return code >= 32 && code < 127 ? String.fromCharCode(code) : ".";
      });
  }
  