Commit fe3033bbf9c22322931e8437da588b0dcbc6be1b
1 parent
9fd37cd21f
Exists in
master
MODEM-TESTER: report type detection
Showing 2 changed files with 74 additions and 25 deletions Inline Diff
modem-tester.js
1 | const REGEX_WAIT_FOR_OK_OR_ERROR = /\r\n(?:OK|ERROR)\r/; | 1 | const REGEX_WAIT_FOR_OK_OR_ERROR = /\r\n(?:OK|ERROR)\r/; |
2 | // const REGEX_WAIT_FOR_OK_OR_ERROR = /\nOK\r/; | 2 | // const REGEX_WAIT_FOR_OK_OR_ERROR = /\nOK\r/; |
3 | 3 | ||
4 | const SerialPort = require('serialport'); | 4 | const SerialPort = require('serialport'); |
5 | 5 | ||
6 | const config = require('komodo-sdk/config'); | 6 | const config = require('komodo-sdk/config'); |
7 | const logger = require('komodo-sdk/logger'); | 7 | const logger = require('komodo-sdk/logger'); |
8 | 8 | ||
9 | const ParserReadline = require('@serialport/parser-readline'); | ||
10 | |||
11 | const parserReadline = new ParserReadline({ delimiter: '\r\n' }); | ||
12 | parserReadline.on('data', (data) => { | ||
13 | logger.verbose('INCOMING', { parser: 'parserReadLine', data: data.toString() }); | ||
14 | }); | ||
15 | 9 | ||
16 | const ParserRegex = require('@serialport/parser-regex'); | 10 | const ParserRegex = require('@serialport/parser-regex'); |
17 | 11 | ||
18 | const parserWaitForOkOrError = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); | 12 | const parserWaitForOkOrError = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); |
19 | parserWaitForOkOrError.on('data', (data) => { | 13 | parserWaitForOkOrError.on('data', (data) => { |
20 | logger.verbose('INCOMING', { parser: 'parserWaitForOkOrError', data: data.toString() }); | 14 | logger.verbose('INCOMING', { parser: 'parserWaitForOkOrError', data: data.toString() }); |
21 | }); | 15 | }); |
22 | 16 | ||
23 | |||
24 | const ParserInterByteTimeout = require('@serialport/parser-inter-byte-timeout'); | 17 | const ParserInterByteTimeout = require('@serialport/parser-inter-byte-timeout'); |
25 | 18 | ||
19 | const parsers = require('./serialport-parsers'); | ||
20 | |||
26 | const parserInterByteTimeout = new ParserInterByteTimeout({ interval: 1000 }); | 21 | const parserInterByteTimeout = new ParserInterByteTimeout({ interval: 1000 }); |
27 | parserInterByteTimeout.on('data', (data) => { | 22 | parserInterByteTimeout.on('data', (data) => { |
28 | logger.verbose('INCOMING', { parser: 'parserInterByteTimeout', data: data.toString() }); | 23 | logger.verbose('INCOMING', { parser: 'parserInterByteTimeout', data: data.toString() }); |
29 | }); | 24 | }); |
30 | 25 | ||
31 | let port; | 26 | let port; |
32 | 27 | ||
33 | function sleep(ms) { | 28 | function sleep(ms) { |
34 | return new Promise((resolve) => { | 29 | return new Promise((resolve) => { |
35 | setTimeout(() => { | 30 | setTimeout(() => { |
36 | resolve(); | 31 | resolve(); |
37 | }, ms || 0); | 32 | }, ms || 0); |
38 | }); | 33 | }); |
39 | } | 34 | } |
40 | 35 | ||
41 | function writeToPort(data) { | 36 | function writeToPort(data) { |
42 | return new Promise((resolve) => { | 37 | return new Promise((resolve) => { |
43 | port.write(data, (err, bytesWritten) => { | 38 | port.write(data, (err, bytesWritten) => { |
44 | if (err) logger.warn(`ERROR: ${err.toString()}`); | 39 | if (err) logger.warn(`ERROR: ${err.toString()}`); |
45 | 40 | ||
46 | logger.verbose('OUTGOING', { bytesWritten, data: data.toString() }); | 41 | logger.verbose('OUTGOING', { bytesWritten, data: data.toString() }); |
47 | resolve(bytesWritten); | 42 | resolve(bytesWritten); |
48 | }); | 43 | }); |
49 | }); | 44 | }); |
50 | } | 45 | } |
51 | 46 | ||
52 | async function writeToPortDelayed(data, ms) { | 47 | async function writeToPortDelayed(data, ms) { |
53 | await sleep(ms || 500); | 48 | await sleep(ms || 500); |
54 | const result = writeToPort(data); | 49 | const result = writeToPort(data); |
55 | return result; | 50 | return result; |
56 | } | 51 | } |
57 | 52 | ||
58 | /* | 53 | /* |
59 | function isNotBlacklistedCommand(command) { | 54 | function isNotBlacklistedCommand(command) { |
60 | let [, cmd] = (command || '').trim().split('+'); | 55 | let [, cmd] = (command || '').trim().split('+'); |
61 | cmd = (cmd || '').replace(/=.*$/, ''); | 56 | cmd = (cmd || '').replace(/=.*$/, ''); |
62 | return !config | 57 | return !config |
63 | || !config.modem_tester | 58 | || !config.modem_tester |
64 | || !config.modem_tester.skip_commands | 59 | || !config.modem_tester.skip_commands |
65 | || (config.modem_tester.skip_commands.indexOf(cmd) < 0); | 60 | || (config.modem_tester.skip_commands.indexOf(cmd) < 0); |
66 | } | 61 | } |
67 | */ | 62 | */ |
68 | 63 | ||
69 | port = new SerialPort(config.modem.device, { baudRate: 115200 }, async (err) => { | 64 | port = new SerialPort(config.modem.device, { baudRate: 115200 }, async (err) => { |
70 | if (err) { | 65 | if (err) { |
71 | logger.warn(`Error opening modem. ${err}. Terminating modem ${config.modem.device}.`); | 66 | logger.warn(`Error opening modem. ${err}. Terminating modem ${config.modem.device}.`); |
72 | process.exit(1); | 67 | process.exit(1); |
73 | } | 68 | } |
74 | 69 | ||
75 | await writeToPortDelayed('AT\r'); | 70 | await writeToPortDelayed('AT\r'); |
76 | 71 | ||
77 | /* | 72 | /* |
78 | if (isNotBlacklistedCommand('CGSN')) await writeToPortDelayed('AT&F\r', 2000); | 73 | if (isNotBlacklistedCommand('CGSN')) await writeToPortDelayed('AT&F\r', 2000); |
79 | if (isNotBlacklistedCommand('CGSN')) await writeToPortDelayed('AT+CGSN\r', 2000); | 74 | if (isNotBlacklistedCommand('CGSN')) await writeToPortDelayed('AT+CGSN\r', 2000); |
80 | if (isNotBlacklistedCommand('CIMI')) await writeToPortDelayed('AT+CIMI\r', 2000); | 75 | if (isNotBlacklistedCommand('CIMI')) await writeToPortDelayed('AT+CIMI\r', 2000); |
81 | if (isNotBlacklistedCommand('CSQ')) await writeToPortDelayed('AT+CSQ\r', 2000); | 76 | if (isNotBlacklistedCommand('CSQ')) await writeToPortDelayed('AT+CSQ\r', 2000); |
82 | if (isNotBlacklistedCommand('COPS?')) await writeToPortDelayed('AT+COPS?\r', 2000); | 77 | if (isNotBlacklistedCommand('COPS?')) await writeToPortDelayed('AT+COPS?\r', 2000); |
83 | // if (isNotBlacklistedCommand('CMGD')) await writeToPortDelayed('AT+CMGD=0,4\r', 2000); | 78 | // if (isNotBlacklistedCommand('CMGD')) await writeToPortDelayed('AT+CMGD=0,4\r', 2000); |
84 | */ | 79 | */ |
85 | 80 | ||
86 | let commands; | 81 | const commands = [ |
87 | if (config && config.modem_tester && config.modem_tester.commands) { | 82 | 'AT&F\r', |
88 | ({ commands } = config.modem_tester); | 83 | 'ATE0\r', |
89 | } else { | 84 | 'AT+CGSN\r', |
90 | commands = [ | 85 | 'AT+CIMI\r', |
91 | 'AT&F\r', | 86 | 'AT+COPS?\r', |
92 | 'ATE0\r', | 87 | 'AT+CSQ\r', |
93 | 'AT+CGSN\r', | 88 | ]; |
94 | 'AT+CIMI\r', | 89 | |
95 | 'AT+COPS?\r', | ||
96 | 'AT+CNMI=1,1,2,1,1\r', | ||
97 | 'AT+CSQ\r', | ||
98 | ]; | ||
99 | } | ||
100 | 90 | ||
101 | const commandsCount = commands.length; | 91 | const commandsCount = commands.length; |
102 | // eslint-disable-next-line no-plusplus | 92 | // eslint-disable-next-line no-plusplus |
103 | for (let i = 0; i < commandsCount; i++) { | 93 | for (let i = 0; i < commandsCount; i++) { |
104 | // eslint-disable-next-line no-await-in-loop | 94 | // eslint-disable-next-line no-await-in-loop |
105 | await writeToPortDelayed(commands[i], 2000); | 95 | await writeToPortDelayed(commands[i], 2000); |
106 | } | 96 | } |
107 | 97 | ||
108 | setInterval(() => { | 98 | if (config && config.modem_tester && config.modem_tester.commands |
109 | writeToPort('AT+CSQ\r', 2000); | 99 | && config.modem_tester.commands.length) { |
110 | }, 30000); | 100 | const additionalCommandsLength = config.modem_tester.commands.length; |
101 | // eslint-disable-next-line no-plusplus | ||
102 | for (let i = 0; i < additionalCommandsLength; i++) { | ||
103 | // eslint-disable-next-line no-await-in-loop | ||
104 | await writeToPortDelayed(config.modem_tester.commands[i], 2000); | ||
105 | } | ||
106 | } | ||
111 | }); | 107 | }); |
112 | 108 | ||
109 | parsers.setPort(port); | ||
110 | |||
113 | if (config && config.modem_tester && config.modem_tester.parser === 'regex') { | 111 | if (config && config.modem_tester && config.modem_tester.parser === 'regex') { |
serialport-parsers.js
File was created | 1 | const PARSER_READLINE_DELIMITER = '\r\n'; | |
2 | |||
3 | const ParserReadline = require('@serialport/parser-readline'); | ||
4 | const logger = require('komodo-sdk/logger'); | ||
5 | |||
6 | let port; | ||
7 | |||
8 | exports.setPort = function setPort(val) { | ||
9 | logger.info('SERIALPORT-PARSERS: setting port'); | ||
10 | port = val; | ||
11 | }; | ||
12 | |||
13 | exports.getPort = function getPort() { | ||
14 | return port; | ||
15 | }; | ||
16 | |||
17 | function isResultCodeIs(data, resultCode) { | ||
18 | if (!data) return false; | ||
19 | const cleanedData = (data.toString() || '').trim(); | ||
20 | if (!cleanedData) return false; | ||
21 | |||
22 | if (resultCode.indexOf('+') !== 0) { | ||
23 | // eslint-disable-next-line no-param-reassign | ||
24 | resultCode = `+${resultCode}`; | ||
25 | } | ||
26 | |||
27 | if (resultCode.search(/:$/) < 0) { | ||
28 | // eslint-disable-next-line no-param-reassign | ||
29 | resultCode += ':'; | ||
30 | } | ||
31 | |||
32 | return cleanedData.indexOf(resultCode) === 0; | ||
33 | } | ||
34 | |||
35 | const parserReadline = new ParserReadline({ delimiter: PARSER_READLINE_DELIMITER }); | ||
36 | parserReadline.on('data', (data) => { | ||
37 | logger.verbose('INCOMING', { parser: 'parserReadLine', data: `${data.toString()}${PARSER_READLINE_DELIMITER}` }); | ||
38 | |||
39 | if (!data) return; | ||
40 | if (isResultCodeIs(data, 'CSQ')) { | ||
41 | logger.verbose('Got a signal quality report', { data: data.toString() }); | ||
42 | } else if (isResultCodeIs(data, 'COPS:')) { | ||
43 | logger.verbose('Got a COPS report', { data: data.toString() }); | ||
44 | } else if (isResultCodeIs(data, 'CMT')) { | ||
45 | logger.verbose('Got a new message report', { data: data.toString() }); | ||
46 | } else if (isResultCodeIs(data, 'CMTI')) { | ||
47 | logger.verbose('Got a new message notification report', { data: data.toString() }); | ||
48 | } | ||
49 | }); | ||
50 | |||
51 | exports.parserReadline = parserReadline; | ||
52 |