Commit b53db5e8b65ce8c11129b086cc6c818f3a21c1f4

Authored by Adhidarma Hadiwinoto
1 parent 6f494f86f0
Exists in master

Migrated to modem-commands. I hope so

Showing 11 changed files with 123 additions and 36 deletions Side-by-side Diff

... ... @@ -25,4 +25,6 @@ global.KOMODO_LOG_LABEL = (typeof config.name === 'string' && config.name.trim()
25 25 : `KOMODO-MODEM@${path.basename(config.modem.device).replace('tty', '').toUpperCase()}`;
26 26  
27 27 require('./lib/http-command-server');
28   -require('./lib/modem');
  28 +
  29 +// require('./lib/modem');
  30 +require('./lib/bootstrap');
1 1 /**
2 2 * Modul modem bootstrap
3   - * @module bootstrap
  3 + * @module
4 4 * @since 2019-09-25
5 5 */
6 6  
  7 +const DEFAULT_BAUDRATE = 115200;
  8 +
  9 +const fs = require('fs');
7 10 const SerialPort = require('serialport');
8 11  
9 12 const config = require('komodo-sdk/config');
... ... @@ -11,14 +14,32 @@ const logger = require('komodo-sdk/logger');
11 14  
12 15 const parsers = require('./serialport-parsers');
13 16 const modemCommands = require('./modem-commands');
  17 +const ussdCodes = require('./modem-commands/ussd-codes');
  18 +
14 19 const modemInfo = require('./modem-info');
  20 +const registerModem = require('./register-modem');
  21 +
  22 +logger.info('Bootstraping modem');
15 23  
16   -const port = new SerialPort(config.modem.device, { baudRate: 115200 }, async (err) => {
  24 +if (!fs.existsSync(config.modem.device)) {
  25 + logger.error(`Modem not found on ${config.modem.device}. Terminating.`);
  26 + process.exit(1);
  27 +}
  28 +
  29 +const port = new SerialPort(config.modem.device, {
  30 + baudRate: (config.modem && config.modem.options && config.modem.options.baudRate)
  31 + || DEFAULT_BAUDRATE,
  32 +}, async (err) => {
17 33 if (err) {
18 34 logger.warn(`Error opening modem. ${err}. Terminating modem ${config.modem.device}.`);
19 35 process.exit(1);
20 36 }
21 37  
  38 + global.MODEM_PORT = port;
  39 + parsers.setPort(port);
  40 + // modemCommands.setPort(port);
  41 + port.pipe(parsers.parserReadline);
  42 +
22 43 await modemCommands.writeToPortAndWaitForOkOrError(`${modemCommands.CTRLZ}AT&FE0\r`);
23 44 await modemCommands.initATCommands();
24 45 await modemCommands.queryManufacturer();
... ... @@ -27,6 +48,22 @@ const port = new SerialPort(config.modem.device, { baudRate: 115200 }, async (er
27 48 await modemCommands.queryCOPSAndSignalQuality();
28 49  
29 50 logger.info('Modem state', modemInfo);
  51 + registerModem();
  52 +
  53 + if (config.debug_sms_destination_on_start) {
  54 + await modemCommands.sendSMS(config.debug_sms_destination_on_start,
  55 + `${config.name} (${modemInfo.imsi || 'UNKNOWN'}) started on ${new Date()}`);
  56 + }
  57 +
  58 + if (config.debug_ussd_code_on_start) {
  59 + const ussdResponse = await modemCommands.executeUSSD(config.debug_ussd_code_on_start, 2);
  60 + logger.info('USSD RESPONSE', { command: config.debug_ussd_code_on_start, ussdResponse });
  61 + }
  62 +
  63 + if ((modemInfo.networkName && modemInfo.networkName === 'TELKOMSEL') || config.bootstrap_tsel_sms_quota_check) {
  64 + const ussdResponse = await modemCommands.executeUSSD(ussdCodes.TSEL_SMS_QUOTA_CHECK, 1);
  65 + logger.info('USSD RESPONSE', { command: config.debug_ussd_code_on_start, ussdResponse });
  66 + }
30 67  
31 68 setInterval(async () => {
32 69 await modemCommands.initATCommands();
... ... @@ -35,10 +72,6 @@ const port = new SerialPort(config.modem.device, { baudRate: 115200 }, async (er
35 72 await modemCommands.queryIMEIAndIMSI();
36 73 await modemCommands.queryCOPSAndSignalQuality();
37 74 logger.info('Modem state', modemInfo);
  75 + registerModem();
38 76 }, config.interval_beetwen_signal_strength_ms || 30000);
39 77 });
40   -
41   -global.MODEM_PORT = port;
42   -parsers.setPort(port);
43   -modemCommands.setPort(port);
44   -port.pipe(parsers.parserReadline);
lib/http-command-server/router-sms.js
... ... @@ -2,7 +2,8 @@
2 2  
3 3 const express = require('express');
4 4  
5   -const modem = require('../modem');
  5 +// const modem = require('../modem');
  6 +const modem = require('../modem-commands');
6 7  
7 8 const router = express.Router();
8 9 module.exports = router;
lib/modem-commands/index.js
... ... @@ -301,7 +301,7 @@ function sendSMS(destination, msg) {
301 301 logger.verbose('SMS sent callback called', { data });
302 302  
303 303 if (data.indexOf('ERROR') >= 0 || data.indexOf('+CMS ERROR') >= 0 || data.indexOf('+CMGS') >= 0) {
304   - logger.verbose('SMS sent');
  304 + logger.info('SMS sent', { data });
305 305 parsers.setSmsSentCallback(null);
306 306 mutex.unlock(MUTEX_COMMAND, 'sendSMS');
307 307 resolve(data.indexOf('ERROR') >= 0 ? null : data.toString().trim());
... ... @@ -321,7 +321,7 @@ function sendSMS(destination, msg) {
321 321 }
322 322  
323 323 const correctedDestination = `+${destination.replace(/^0/, '62')}`.replace(/^\++/, '+');
324   - logger.verbose(`Sending sms to ${correctedDestination}`, { msg });
  324 + logger.info(`Sending sms to ${correctedDestination}`, { msg, length: msg.length });
325 325  
326 326 await this.writeToPortAndWaitForOkOrError('AT+CMGF=0\r', MUTEX_SUBCOMMAND);
327 327  
lib/modem-commands/ussd-codes.js
... ... @@ -0,0 +1 @@
  1 +exports.TSEL_SMS_QUOTA_CHECK = '*888*2*2*4#';
... ... @@ -5,6 +5,7 @@
5 5 *
6 6 * @module
7 7 * @deprecated going to move to module:bootstrap
  8 + * @see module:bootstrap
8 9 */
9 10  
10 11 const DEFAULT_SLEEP_AFTER_SEND_SMS_MS = 2000;
... ... @@ -13,6 +14,7 @@ const MAX_LAST_DATA_AGE_MS = 3 * 60 * 1000;
13 14 const REGEX_WAIT_FOR_OK_OR_ERROR = /\n(?:OK|ERROR)\r/;
14 15 // const REGEX_WAIT_FOR_OK_OR_ERROR_USSD = /\n(?:OK|ERROR)\r/;
15 16  
  17 +const path = require('path');
16 18 const moment = require('moment');
17 19 const SerialPort = require('serialport');
18 20 const ParserReadline = require('@serialport/parser-readline');
... ... @@ -23,6 +25,11 @@ const ParserRegex = require('@serialport/parser-regex');
23 25 const config = require('komodo-sdk/config');
24 26 const logger = require('komodo-sdk/logger');
25 27  
  28 +// const stack = new Error().stack;
  29 +logger.warn(`'${path.basename(__filename, '.js')}' is DEPRECATED, please use 'modem-commands'!`);
  30 +// eslint-disable-next-line no-console
  31 +console.trace(`'${path.basename(__filename, '.js')}' is DEPRECATED, please use 'modem-commands'!`);
  32 +
26 33 const mutex = require('./mutex');
27 34 const common = require('./common');
28 35 const sms = require('./sms');
... ... @@ -30,20 +37,7 @@ const dbCops = require('./db-cops');
30 37 const reportSender = require('./report-sender');
31 38 const registerModem = require('./register-modem');
32 39  
33   -const modemInfo = {
34   - device: config.modem.device,
35   - manufacturer: null,
36   - model: null,
37   - imei: null,
38   - imsi: null,
39   - msisdn: null,
40   - cops: null,
41   - networkId: null,
42   - networkName: null,
43   - signalStrength: null,
44   - signalStrengthTs: null,
45   - signalStrengthTsReadable: null,
46   -};
  40 +const modemInfo = require('./modem-info');
47 41  
48 42 let lastTs = new Date();
49 43  
lib/register-modem.js
... ... @@ -8,6 +8,8 @@ const locks = require('locks');
8 8 const config = require('komodo-sdk/config');
9 9 const logger = require('komodo-sdk/logger');
10 10  
  11 +const modemInfo = require('./modem-info');
  12 +
11 13 const mutex = locks.createMutex();
12 14  
13 15 function reportUrl() {
... ... @@ -19,7 +21,7 @@ function reportUrl() {
19 21 return `${baseUrl}/modems/set`;
20 22 }
21 23  
22   -function sender(modemInfo) {
  24 +function sender() {
23 25 if (mutex.tryLock()) {
24 26 const requestOptions = {
25 27 url: reportUrl(),
lib/report-sender2.js
... ... @@ -0,0 +1,45 @@
  1 +const request = require('request');
  2 +
  3 +const config = require('komodo-sdk/config');
  4 +const logger = require('komodo-sdk/logger');
  5 +const modemInfo = require('./modem-info');
  6 +
  7 +function incomingSMS(ts, from, msg) {
  8 + if (!ts || !from || !msg
  9 + || !config || !config.report_url || !config.report_url.incoming_sms) return;
  10 +
  11 + const requestOptions = {
  12 + url: config.report_url.incoming_sms,
  13 + qs: {
  14 + ts,
  15 + // status: message.metadata.status,
  16 + number: from,
  17 + msg,
  18 + modem: config.name,
  19 + modem_imsi: modemInfo.imsi,
  20 + modem_msisdn: modemInfo.msisdn,
  21 + modem_device: config.modem.device,
  22 + modem_network_id: modemInfo.networkId,
  23 + modem_network_name: modemInfo.networkName,
  24 + modem_signal_strength: modemInfo.signalStrength,
  25 + uptime: Math.floor(process.uptime()),
  26 + report_port: config.http_command_server.listen_port,
  27 + report_apikey: config.http_command_server.apikey,
  28 + report_path_sms: '/sms',
  29 + },
  30 + };
  31 +
  32 + logger.info('Sending report via HTTP', requestOptions);
  33 + request(requestOptions, (err, res, body) => {
  34 + if (err) {
  35 + logger.warn(`Error sending report via HTTP. ${err.toString()}`);
  36 + return;
  37 + }
  38 +
  39 + if (res.statusCode !== 200) {
  40 + logger.warn(`Error sending report via HTTP. Server respond with HTTP status code ${res.statusCode}`, { http_status_code: res.statusCode, body });
  41 + }
  42 + });
  43 +}
  44 +
  45 +exports.incomingSMS = incomingSMS;
lib/serialport-parsers.js
... ... @@ -11,6 +11,7 @@ const logger = require('komodo-sdk/logger');
11 11  
12 12 const dbCops = require('./db-cops');
13 13 const modemInfo = require('./modem-info');
  14 +const reportSender = require('./report-sender2');
14 15  
15 16 let port;
16 17  
... ... @@ -88,7 +89,7 @@ function onPduDeliver(data, parsedData) {
88 89 const ts = new Date(parsedData.getScts().getIsoString());
89 90  
90 91 logger.verbose('PDU processed', { ts, from, msg });
91   - return { from, msg };
  92 + return { ts, from, msg };
92 93 }
93 94  
94 95 function onCOPS(data) {
... ... @@ -149,7 +150,13 @@ parserReadline.on('data', (data) => {
149 150 if (pduParsed && pduParsed.constructor.name === 'Deliver' && pduParsed.getData().getSize()) {
150 151 const pduType = pduParsed.getType();
151 152 logger.verbose('Got a PDU SMS-DELIVER', { pduType });
152   - onPduDeliver(data, pduParsed);
  153 + const parsedData = onPduDeliver(data, pduParsed);
  154 +
  155 + if (parsedData.ts && parsedData.from && parsedData.msg) {
  156 + reportSender.incomingSMS(parsedData.ts, parsedData.from, parsedData.msg);
  157 + } else {
  158 + logger.warn('Got a PDU SMS-DELIVER but failed on parsing PDU message');
  159 + }
153 160 } else if (data.toString().trim() === 'ERROR') {
154 161 if (typeof smsSentCallback === 'function') smsSentCallback(data.toString());
155 162 } else if (isResultCodeIs(data, 'CSQ')) {
... ... @@ -33,13 +33,14 @@ const port = new SerialPort(config.modem.device, { baudRate: 115200 }, async (er
33 33 await modemCommands.queryCOPSAndSignalQuality();
34 34 logger.info('Modem state', modemInfo);
35 35  
36   - // await modemCommands.sendSMS('628128364883', `coba pakai pdu ${new Date()}`);
37   - // await modemCommands.sendSMS('+6282210008543', `coba pakai pdu ${new Date()}`);
38   - // await modemCommands.sendSMS('6281809903333', `coba pakai pdu ${new Date()}`);
39   - await modemCommands.sendSMS('999', `coba pakai pdu ${new Date()}`);
  36 + if (config.debug_sms_destination_on_start) {
  37 + await modemCommands.sendSMS(config.debug_sms_destination_on_start, `${modemInfo.imsi || 'UNKNOWN'}: coba pakai pdu ${new Date()}`);
  38 + }
40 39  
41   - // const ussdResponse = await modemCommands.executeUSSD('*888#', 2);
42   - // logger.info('USSD RESPONSE', { ussdResponse });
  40 + if (config.debug_ussd_code_on_start) {
  41 + const ussdResponse = await modemCommands.executeUSSD(config.debug_ussd_code_on_start, 2);
  42 + logger.info('USSD RESPONSE', { command: config.debug_ussd_code_on_start, ussdResponse });
  43 + }
43 44  
44 45 setInterval(async () => {
45 46 await modemCommands.initATCommands();
... ... @@ -53,7 +54,7 @@ const port = new SerialPort(config.modem.device, { baudRate: 115200 }, async (er
53 54  
54 55 global.MODEM_PORT = port;
55 56 parsers.setPort(port);
56   -modemCommands.setPort(port);
  57 +// modemCommands.setPort(port);
57 58  
58 59 if (config && config.modem_tester && config.modem_tester.parser === 'regex') {
59 60 logger.info('Using parserWaitForOkOrError');
... ... @@ -5,7 +5,8 @@
5 5 "main": "index.js",
6 6 "scripts": {
7 7 "test": "mocha",
8   - "postversion": "git push && git push --tags"
  8 + "postversion": "git push && git push --tags",
  9 + "jsdoc": "./generate-jsdoc.sh"
9 10 },
10 11 "repository": {
11 12 "type": "git",