Advertisement
Guest User

Untitled

a guest
Oct 12th, 2020
342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // envisalink.js
  2. const nwTcp = require('net');
  3.  
  4. const Invisalink = ({
  5.   network,
  6.   authentication,
  7.   defaultCallbackHandlers = {},
  8.   callbacks,
  9.   runningOptions
  10. } = {}) => {
  11.   const retr = {};
  12.  
  13.   const connectionOptions = {
  14.     ...network
  15.   };
  16.  
  17.   const auth = {
  18.     ...authentication
  19.   };
  20.  
  21.   const parsedCallbacks = {
  22.     ...callbacks
  23.   };
  24.  
  25.   const options = {
  26.     ...runningOptions
  27.   };
  28.  
  29.   let shouldReconnect = true;
  30.   let activeConnection = null;
  31.   let pollTimer = null;
  32.   let cbs = {};
  33.  
  34.   const printDebug = (message) => {
  35.     if (options.printDebug) {
  36.       console.log(message);
  37.     }
  38.   };
  39.  
  40.   const printReceivePacket = (packetData) => {
  41.     if (options.printReceivePacket) {
  42.       console.log(packetData);
  43.     }
  44.   };
  45.  
  46.   const printSendPacket = (packetData) => {
  47.     if (options.printSendPacket) {
  48.       console.log(packetData);
  49.     }
  50.   };
  51.  
  52.   const printCommandData = (packetData) => {
  53.     if (options.printCommandData) {
  54.       console.log(packetData);
  55.     }
  56.   };
  57.  
  58.   const connOnError = (err) => {
  59.     console.log(err);
  60.   };
  61.  
  62.   const connOnEnd = (param) => {
  63.     console.log('End', param);
  64.   };
  65.  
  66.   const connOnClose = (hadErr) => {
  67.     clearInterval(pollTimer);
  68.     console.log('Closed', hadErr);
  69.     setTimeout(() => {
  70.       if (shouldReconnect && (!activeConnection || activeConnection.destroyed)) {
  71.         retr.connect()
  72.       }
  73.     }, 5000);
  74.   };
  75.  
  76.   const loginResponse = (data) => {
  77.     printDebug(`[Debug] [loginResponse()]: Processing Login...`);
  78.     const loginStatus = data;
  79.     if (loginStatus === 'FAILED') {
  80.       printDebug(`[Debug] [loginResponse()]: Login Failed: 'Bad Password'`);
  81.       throw new Error(JSON.stringify({
  82.         error: 'login failed',
  83.         reason: 'bad credentials'
  84.       }));
  85.     } else if (loginStatus === 'OK') {
  86.       printDebug(`[Debug] [loginResponse()]: Login Success`);
  87.       sendCommand({ data: '001' })
  88.       clearInterval(pollTimer);
  89.       pollTimer = setInterval(function () {
  90.         sendCommand({ data: '000' });
  91.       }, 60000);
  92.     } else if (loginStatus === 'Timed Out!') {
  93.       printDebug(`[Debug] [loginResponse()]: Login Failed: 'Password timeout'`);
  94.       throw new Error(JSON.stringify({
  95.         error: 'login failed',
  96.         reason: 'password not entered in time'
  97.       }));
  98.     } else if (loginStatus === 'Login:') {
  99.       printDebug(`[Debug] [loginResponse()]: Sending authentication credentials`);
  100.       sendCommand({ data: auth.user })
  101.     }
  102.   };
  103.  
  104.   const connOnData = (data) => {
  105.     const dataBuffer = data.toString().replace(/[\n\r]/g, '|').split('|');
  106.     // printDebug(`[Debug] [connOnData()]: Commands received: '${dataBuffer.length}'`);
  107.     printReceivePacket(`Data received: '${dataBuffer}'`);
  108.  
  109.     for (let i = 0; i < dataBuffer.length; i++) {
  110.       const commandData = dataBuffer[i];
  111.       if (commandData !== '') { // TODO: Add error checking
  112.         printCommandData(`Data received: '${commandData}'`);
  113.         if (commandData) { // TODO: Add protocol checking
  114.           if (commandData === '' || commandData === 0) {
  115.           } else {
  116.             if (commandData.trim() === 'Login:') {
  117.               loginResponse(commandData);
  118.             } else {
  119.               console.log('datarec:', commandData);
  120.             }
  121.           }
  122.         }
  123.       }
  124.     }
  125.   };
  126.  
  127.   const sendCommand = ({ data, includeChecksum = false, includeSentinels = false }) => {
  128.     let checksum = 0
  129.     for (let i = 0; i < data.length; i++) {
  130.       checksum += data.charCodeAt(i);
  131.     }
  132.  
  133.     checksum = checksum.toString(16).slice(-2).toUpperCase();
  134.     let sendData = data;
  135.  
  136.     if (includeSentinels) {
  137.       sendData = '^' + sendData + '$';
  138.     }
  139.  
  140.     if (includeChecksum) {
  141.       sendData += checksum;
  142.     }
  143.  
  144.     printSendPacket(`Data sent: '${sendData}'<crlf>`);
  145.     sendData += '\r\n';
  146.     activeConnection.write(sendData);
  147.   };
  148.  
  149.   const connectToInvisalink = (netCon, cbs) => {
  150.     const port = netCon.port || '4025';
  151.     if (Number.isNaN(Number.parseInt(port))
  152.       || port < 1
  153.       || port > 65535) {
  154.       throw new Error(JSON.stringify({
  155.         error: 'Bad port',
  156.         reason: 'Port number is not valid',
  157.         data: port
  158.       }));
  159.     }
  160.  
  161.     activeConnection = nwTcp.createConnection({ port: port || '4025', host: netCon.host });
  162.  
  163.     printDebug(`[Debug] [connectToInvisalink()]: TCP link established to port '${netCon.port}'`);
  164.  
  165.     activeConnection.on('error', cbs.onErrCb);
  166.     activeConnection.on('close', cbs.onCloseCb);
  167.     activeConnection.on('end', cbs.onEndCb);
  168.     activeConnection.on('data', cbs.onDataCb);
  169.     printDebug(`[Debug] [connectToInvisalink()]: Callbacks registered`);
  170.   };
  171.  
  172.   retr.connect = () => {
  173.     connectToInvisalink(connectionOptions, cbs);
  174.   };
  175.  
  176.   const init = () => {
  177.     cbs = {
  178.       onErrCb: connOnError,
  179.       onCloseCb: connOnClose,
  180.       onEndCb: connOnEnd,
  181.       onDataCb: connOnData,
  182.       ...defaultCallbackHandlers
  183.     };
  184.  
  185.     shouldReconnect = connectionOptions.shouldReconnect === null || connectionOptions.shouldReconnect === undefined ? true : shouldReconnect;
  186.  
  187.     if (!connectionOptions.host) {
  188.       throw new Error(JSON.stringify({
  189.         error: 'Bad host',
  190.         reason: 'Host is not valid',
  191.         data: connectionOptions.host
  192.       }));
  193.     }
  194.  
  195.     if (!authentication.user) {
  196.       throw new Error(JSON.stringify({
  197.         error: 'Bad user',
  198.         reason: 'user is not valid'
  199.       }));
  200.     }
  201.  
  202.     if (typeof(cbs.onErrCb) !== 'function') {
  203.       throw new Error(JSON.stringify({
  204.         error: 'Bad parameter',
  205.         reason: 'Default callback: onErrCb is not a function',
  206.         data: typeof(cbs.onErrCb)
  207.       }));
  208.     }
  209.  
  210.     if (typeof(cbs.onCloseCb) !== 'function') {
  211.       throw new Error(JSON.stringify({
  212.         error: 'Bad parameter',
  213.         reason: 'Default callback: onCloseCb is not a function',
  214.         data: typeof(cbs.onCloseCb)
  215.       }));
  216.     }
  217.  
  218.     if (typeof(cbs.onEndCb) !== 'function') {
  219.       throw new Error(JSON.stringify({
  220.         error: 'Bad parameter',
  221.         reason: 'Default callback: onEndCb is not a function',
  222.         data: typeof(cbs.onEndCb)
  223.       }));
  224.     }
  225.  
  226.     if (typeof(cbs.onDataCb) !== 'function') {
  227.       throw new Error(JSON.stringify({
  228.         error: 'Bad parameter',
  229.         reason: 'Default callback: onDataCb is not a function',
  230.         data: typeof(cbs.onDataCb)
  231.       }));
  232.     }
  233.  
  234.     if (typeof(parsedCallbacks.onData) !== 'function') {
  235.       throw new Error(JSON.stringify({
  236.         error: 'Bad callback',
  237.         reason: 'Callback: onData is not a function',
  238.         data: typeof(parsedCallbacks.onData)
  239.       }));
  240.     }
  241.  
  242.     if (typeof(parsedCallbacks.onError) !== 'function') {
  243.       throw new Error(JSON.stringify({
  244.         error: 'Bad callback',
  245.         reason: 'Callback: onError is not a function',
  246.         data: typeof(parsedCallbacks.onError)
  247.       }));
  248.     }
  249.  
  250.     if (process.stdin.isTTY) {
  251.       process.stdin.setRawMode(true);
  252.     }
  253.     process.stdin.setEncoding('utf8');
  254.     process.stdin.on('data', function (chunk) {
  255.       chunk = chunk.trim();
  256.       console.log(`data: '${chunk}'`);
  257.       if (chunk === 'c' || chunk.name === 'c') {
  258.         process.exit();
  259.       }
  260.  
  261.       if ( chunk === '\u0003' ) {
  262.         process.exit();
  263.       }
  264.  
  265.       if (chunk === 'q') {
  266.         const includeSentinels = true;
  267.         sendCommand({ data: '*99', includeSentinels: false });
  268.         sendCommand({ data: '*99', includeSentinels });
  269.       }
  270.       if (chunk === 'p') {
  271.         sendCommand({ data: '01', includeSentinels: true });
  272.       }
  273.  
  274.       if (chunk === 'r') {
  275.         sendCommand({ data: '02', includeSentinels: true });
  276.       }
  277.  
  278.       if (chunk === 'o') {
  279.         sendCommand({ data: '08', includeSentinels: true });
  280.       }
  281.  
  282.       if (chunk === 's') {
  283.         const includeSentinels = true;
  284.         sendCommand({ data: '0000#', includeSentinels });
  285.         sendCommand({ data: '63', includeSentinels });
  286.       }
  287.  
  288.  
  289.     });
  290.     process.stdin.resume();
  291.  
  292.   };
  293.  
  294.   init();
  295.  
  296.   return retr;
  297. };
  298.  
  299. module.exports = Invisalink;
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310. // index.js
  311. const Invisalink = require('./envisalink');
  312.  
  313. const onData = (data) => {
  314.   console.log('got data', data);
  315. }
  316.  
  317. const onError = (err) => {
  318.   console.log('got err', err);
  319. }
  320.  
  321. const invisalink = Invisalink({
  322.   network: {
  323.     host: '192.168.1.6',
  324.     port: 4025
  325.   },
  326.   authentication: {
  327.     user: 'user'
  328.   },
  329.   callbacks: {
  330.     onData,
  331.     onError
  332.   },
  333.   runningOptions: {
  334.     printDebug: true,
  335.     printCommandData: true,
  336.     printSendPacket: true
  337.   }
  338. });
  339.  
  340. setTimeout(() => {
  341.   invisalink.connect();
  342. }, 500)
  343.  
  344.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement