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