diff --git a/config.sample.json b/config.sample.json index 6448561..156a455 100644 --- a/config.sample.json +++ b/config.sample.json @@ -14,6 +14,7 @@ "listen_port": "2110" }, + "interval_beetwen_signal_strength_ms": 60000, "disable_delete_inbox_on_startup": false } \ No newline at end of file diff --git a/lib/modem.js b/lib/modem.js index 9e3c264..adfd75b 100644 --- a/lib/modem.js +++ b/lib/modem.js @@ -36,7 +36,13 @@ const modemInfo = { const port = new SerialPort(config.modem.device, { baudRate: 115200 }); const parserReadLine = new ParserReadline(); + const parserWaitForOK = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); +parserWaitForOK.on('data', () => { + mutex.releaseLockWaitForCommand(); +}); + + port.pipe(parserReadLine); function writeToPort(data) { @@ -50,33 +56,41 @@ function writeToPort(data) { } async function writeToPortAndWaitForOK(data) { - await mutex.setLockWaitForOK(); + await mutex.setLockWaitForCommand(); const result = await writeToPort(data); - await mutex.setLockWaitForOK(); - mutex.releaseLockWaitForOK(); + + await mutex.setLockWaitForCommand(); + mutex.releaseLockWaitForCommand(); + return result; } async function readSMS(slot) { - const parser = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); - parser.on('data', async (data) => { + const parserCMGR = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); + parserCMGR.on('data', (data) => { if (data) { reportSender.incomingSMS(sms.extract(data.toString().trim())); } - mutex.releaseLockWaitForOK(); + port.unpipe(parserCMGR); + mutex.releaseLockWaitForCommand(); + }); + + const parserCMGD = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); + parserCMGD.on('data', () => { + port.unpipe(parserCMGD); + mutex.releaseLockWaitForCommand(); }); logger.info(`Reading SMS on slot ${slot}`); - port.pipe(parser); - await writeToPortAndWaitForOK(`AT+CMGR=${slot}\r`); - port.unpipe(parser); - logger.verbose(`Finished reading SMS on slot ${slot}`); + await mutex.setLockWaitForCommand(); + port.pipe(parserCMGR); + await writeToPort(`AT+CMGR=${slot}\r`); + logger.info(`Finished reading SMS on slot ${slot}`); logger.info(`Deleting message on slot ${slot}`); - port.pipe(parserWaitForOK); - await writeToPortAndWaitForOK(`AT+CMGD=${slot}\r`); - port.unpipe(parserWaitForOK); - + await mutex.setLockWaitForCommand(); + port.pipe(parserCMGD); + await writeToPort(`AT+CMGD=${slot}\r`); logger.info('Message processing has completed'); } @@ -125,15 +139,11 @@ parserReadLine.on('data', (data) => { } }); -parserWaitForOK.on('data', () => { - mutex.releaseLockWaitForOK(); -}); - function simpleCommand(cmd, callback) { const parser = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); parser.on('data', (data) => { port.unpipe(parser); - mutex.releaseLockWaitForOK(); + mutex.releaseLockWaitForCommand(); if (data) { callback(null, data.toString().trim()); @@ -192,39 +202,68 @@ function readIMSI() { } async function querySignalStrength() { - port.pipe(parserWaitForOK); - await writeToPortAndWaitForOK('AT+CSQ\r'); - port.unpipe(parserWaitForOK); + const parser = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); + parser.on('data', () => { + port.unpipe(parser); + mutex.releaseLockWaitForCommand(); + }); + + if (mutex.tryLockWaitForCommand()) { + port.pipe(parser); + await writeToPort('AT+CSQ\r'); + } } async function registerSignalStrengthBackgroundQuery() { logger.info('Registering background signal strength query'); + querySignalStrength(); + setInterval(() => { querySignalStrength(); - }, INTERVAL_BEETWEN_SIGNAL_STRENGTH_MS); + }, config.interval_beetwen_signal_strength_ms || INTERVAL_BEETWEN_SIGNAL_STRENGTH_MS); } 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 }); + parser.on('data', () => { + port.unpipe(parser); + mutex.releaseLockWaitForSubCommand(); + }); + + logger.verbose('Waiting for command lock to send message'); await mutex.setLockWaitForCommand(); + logger.info('Sending message', { destination, msg }); const correctedDestination = `+${destination}`.replace(/^0/, '62').replace(/^\++/, '+'); - port.pipe(parserWaitForOK); - await writeToPortAndWaitForOK('AT+CMGF=1\r'); - await writeToPortAndWaitForOK(`AT+CMGS="${correctedDestination}"\n${msg}${Buffer.from([0x1A])}`); - port.unpipe(parserWaitForOK); + logger.verbose('Waiting for lock before set to text mode'); + await mutex.setLockWaitForSubCommand(); + port.pipe(parser); + await writeToPort('AT+CMGF=1\r'); + + logger.verbose('Waiting for lock before writing message'); + await mutex.setLockWaitForSubCommand(); + port.pipe(parser); + await writeToPort(`AT+CMGS="${correctedDestination}"\n${msg}${Buffer.from([0x1A])}`); + + await mutex.setLockWaitForSubCommand(); + mutex.releaseLockWaitForSubCommand(); logger.info('Message has been sent'); - mutex.releaseLockWaitForCommand(); + setTimeout(() => { + logger.verbose('Releasing command lock'); + mutex.releaseLockWaitForCommand(); + }, 2000); } function init() { port.on('open', async () => { + // await mutex.setLockWaitForCommand(); port.pipe(parserWaitForOK); logger.info('Modem opened'); @@ -238,9 +277,6 @@ function init() { await writeToPortAndWaitForOK('AT+COPS?\r'); - logger.info('Querying signal strength'); - await writeToPortAndWaitForOK('AT+CSQ\r'); - await readManufacturer(); await readModel(); await readIMEI(); @@ -253,6 +289,9 @@ function init() { port.unpipe(parserWaitForOK); + await mutex.setLockWaitForCommand(); + mutex.releaseLockWaitForCommand(); + registerSignalStrengthBackgroundQuery(); logger.verbose('Init completed'); }); diff --git a/lib/mutex.js b/lib/mutex.js index 677b525..c2ddbee 100644 --- a/lib/mutex.js +++ b/lib/mutex.js @@ -5,6 +5,8 @@ const locks = require('locks'); const mutexWaitForOK = locks.createMutex(); const mutexCommand = locks.createMutex(); +const mutexSubCommand = locks.createMutex(); + function setLockWaitForOK() { return new Promise((resolve) => { mutexWaitForOK.lock(() => { @@ -29,14 +31,37 @@ function setLockWaitForCommand() { }); } +function tryLockWaitForCommand() { + return mutexCommand.tryLock(); +} + + function releaseLockWaitForCommand() { - setTimeout(() => { - try { - mutexCommand.unlock(); - } catch (e) { - // - } - }, 2000); + try { + mutexCommand.unlock(); + } catch (e) { + // + } +} + +function setLockWaitForSubCommand() { + return new Promise((resolve) => { + mutexSubCommand.lock(() => { + resolve(true); + }); + }); +} + +function releaseLockWaitForSubCommand() { + mutexSubCommand.unlock(); + + /* + try { + mutexSubCommand.unlock(); + } catch (e) { + // + } + */ } exports.setLockWaitForOK = setLockWaitForOK; @@ -44,3 +69,7 @@ exports.releaseLockWaitForOK = releaseLockWaitForOK; exports.setLockWaitForCommand = setLockWaitForCommand; exports.releaseLockWaitForCommand = releaseLockWaitForCommand; +exports.tryLockWaitForCommand = tryLockWaitForCommand; + +exports.setLockWaitForSubCommand = setLockWaitForSubCommand; +exports.releaseLockWaitForSubCommand = releaseLockWaitForSubCommand;