diff --git a/lib/modem.js b/lib/modem.js index adfd75b..df65fa2 100644 --- a/lib/modem.js +++ b/lib/modem.js @@ -1,12 +1,17 @@ 'use strict'; const INTERVAL_BEETWEN_SIGNAL_STRENGTH_MS = 60000; -const DELIMITER_WAIT_FOR_OK = '\nOK\r\n'; +// const DELIMITER_WAIT_FOR_OK = '\nOK\r\n'; + +const REGEX_WAIT_FOR_OK_OR_ERROR = /\n(?:OK|ERROR)\r\n/; +// const REGEX_WAIT_FOR_OK_OR_ERROR = /\nOK\r\n/; const moment = require('moment'); const SerialPort = require('serialport'); const ParserReadline = require('@serialport/parser-readline'); -const ParserDelimiter = require('@serialport/parser-delimiter'); +// const ParserDelimiter = require('@serialport/parser-delimiter'); + +const ParserRegex = require('@serialport/parser-regex'); const config = require('komodo-sdk/config'); const logger = require('komodo-sdk/logger'); @@ -37,7 +42,7 @@ const port = new SerialPort(config.modem.device, { baudRate: 115200 }); const parserReadLine = new ParserReadline(); -const parserWaitForOK = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); +const parserWaitForOK = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); parserWaitForOK.on('data', () => { mutex.releaseLockWaitForCommand(); }); @@ -55,6 +60,7 @@ function writeToPort(data) { }); } +// eslint-disable-next-line no-unused-vars async function writeToPortAndWaitForOK(data) { await mutex.setLockWaitForCommand(); const result = await writeToPort(data); @@ -66,16 +72,23 @@ async function writeToPortAndWaitForOK(data) { } async function readSMS(slot) { - const parserCMGR = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); + const parserCMGR = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); parserCMGR.on('data', (data) => { if (data) { - reportSender.incomingSMS(sms.extract(data.toString().trim())); + try { + reportSender.incomingSMS(sms.extract(data.toString().trim())); + } catch (e) { + logger.warn(`Exception on reporting new message. ${e.toString()}`, { smsObj: e.smsObj, dataFromModem: data }); + + process.exit(0); + } } port.unpipe(parserCMGR); mutex.releaseLockWaitForCommand(); }); - const parserCMGD = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); + // const parserCMGD = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); + const parserCMGD = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); parserCMGD.on('data', () => { port.unpipe(parserCMGD); mutex.releaseLockWaitForCommand(); @@ -139,24 +152,32 @@ parserReadLine.on('data', (data) => { } }); -function simpleCommand(cmd, callback) { - const parser = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); +async function simpleSubCommand(cmd, callback) { + const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); parser.on('data', (data) => { port.unpipe(parser); - mutex.releaseLockWaitForCommand(); + mutex.releaseLockWaitForSubCommand(); if (data) { - callback(null, data.toString().trim()); + if (callback) callback(null, data.toString().trim()); } }); - port.pipe(parser); - writeToPortAndWaitForOK(cmd); + return new Promise(async (resolve) => { + await mutex.setLockWaitForSubCommand(); + port.pipe(parser); + writeToPort(cmd); + + await mutex.setLockWaitForSubCommand(); + mutex.releaseLockWaitForSubCommand(); + + resolve(); + }); } function readManufacturer() { return new Promise((resolve) => { - simpleCommand('AT+CGMI\r', (err, result) => { + simpleSubCommand('AT+CGMI\r', (err, result) => { modemInfo.manufacturer = result; logger.info(`Manufacturer: ${result}`); resolve(result); @@ -166,7 +187,7 @@ function readManufacturer() { function readModel() { return new Promise((resolve) => { - simpleCommand('AT+CGMM\r', (err, result) => { + simpleSubCommand('AT+CGMM\r', (err, result) => { modemInfo.model = result; logger.info(`Model: ${result}`); resolve(result); @@ -176,7 +197,7 @@ function readModel() { function readIMEI() { return new Promise((resolve) => { - simpleCommand('AT+CGSN\r', (err, result) => { + simpleSubCommand('AT+CGSN\r', (err, result) => { modemInfo.imei = result; logger.info(`IMEI: ${result}`); resolve(result); @@ -186,7 +207,7 @@ function readIMEI() { function readIMSI() { return new Promise((resolve) => { - simpleCommand('AT+CIMI\r', (err, result) => { + simpleSubCommand('AT+CIMI\r', (err, result) => { modemInfo.imsi = result; logger.info(`IMSI: ${result}`); @@ -201,8 +222,24 @@ function readIMSI() { }); } +function readCOPS() { + return new Promise((resolve) => { + simpleSubCommand('AT+COPS?\r', (err, result) => { + resolve(result); + }); + }); +} + +function deleteInbox() { + return new Promise((resolve) => { + simpleSubCommand('AT+CMGD=0,4\r', (err, result) => { + resolve(result); + }); + }); +} + async function querySignalStrength() { - const parser = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); + const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); parser.on('data', () => { port.unpipe(parser); mutex.releaseLockWaitForCommand(); @@ -227,7 +264,7 @@ async function registerSignalStrengthBackgroundQuery() { async function sendSMS(destination, msg) { if (typeof destination !== 'string' || typeof msg !== 'string' || !destination.trim() || !msg.trim()) return; - const parser = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); + const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); parser.on('data', () => { port.unpipe(parser); mutex.releaseLockWaitForSubCommand(); @@ -263,19 +300,19 @@ async function sendSMS(destination, msg) { function init() { port.on('open', async () => { - // await mutex.setLockWaitForCommand(); - port.pipe(parserWaitForOK); + await mutex.setLockWaitForCommand(); logger.info('Modem opened'); - await writeToPortAndWaitForOK('AT\r'); + await writeToPort('\r'); + await simpleSubCommand('AT\r'); logger.info('Initializing modem to factory set'); - await writeToPortAndWaitForOK('AT&F\r'); + await simpleSubCommand('AT&F\r'); logger.info('Disabling echo'); - await writeToPortAndWaitForOK('ATE0\r'); + await simpleSubCommand('ATE0\r'); - await writeToPortAndWaitForOK('AT+COPS?\r'); + await readCOPS(); await readManufacturer(); await readModel(); @@ -284,16 +321,13 @@ function init() { if (!config.disable_delete_inbox_on_startup) { logger.info('Deleting existing messages'); - await writeToPortAndWaitForOK('AT+CMGD=0,4\r'); + await deleteInbox(); } - port.unpipe(parserWaitForOK); - - await mutex.setLockWaitForCommand(); mutex.releaseLockWaitForCommand(); + logger.verbose('Init completed'); registerSignalStrengthBackgroundQuery(); - logger.verbose('Init completed'); }); } diff --git a/lib/mutex.js b/lib/mutex.js index c2ddbee..d3e734f 100644 --- a/lib/mutex.js +++ b/lib/mutex.js @@ -53,15 +53,13 @@ function setLockWaitForSubCommand() { } function releaseLockWaitForSubCommand() { - mutexSubCommand.unlock(); + // mutexSubCommand.unlock(); - /* try { mutexSubCommand.unlock(); } catch (e) { // } - */ } exports.setLockWaitForOK = setLockWaitForOK; diff --git a/lib/report-sender.js b/lib/report-sender.js index c56c057..1f604a7 100644 --- a/lib/report-sender.js +++ b/lib/report-sender.js @@ -6,7 +6,19 @@ const config = require('komodo-sdk/config'); const logger = require('komodo-sdk/logger'); function incomingSMS(message) { - if (!config || !config.report_url || !config.report_url.incoming_sms) return; + if (!message || !config || !config.report_url || !config.report_url.incoming_sms) return; + + if (!message.metadata) { + const e = new Error('Missing metadata on incoming sms'); + e.smsObj = message; + throw e; + } + + if (!message.message) { + const e = new Error('Missing message on incoming sms'); + e.smsObj = message; + throw e; + } const requestOptions = { url: config.report_url.incoming_sms, diff --git a/package.json b/package.json index 7de3222..08ec1d6 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "dependencies": { "@serialport/parser-delimiter": "^2.0.2", "@serialport/parser-readline": "^2.0.2", + "@serialport/parser-regex": "^2.0.2", "express": "^4.17.1", "komodo-sdk": "git+http://gitlab.kodesumber.com/komodo/komodo-sdk.git", "locks": "^0.2.2",