Commit 8a8888ce32cee6f1e79fbf5262da4f2d35b771fc

Authored by Adhidarma Hadiwinoto
1 parent c5ce14d558
Exists in master

USSD code tanpa trim

Showing 2 changed files with 7 additions and 6 deletions Inline Diff

lib/http-command-server/router-ussd.js
1 'use strict'; 1 'use strict';
2 2
3 const express = require('express'); 3 const express = require('express');
4 4
5 const modem = require('../modem'); 5 const modem = require('../modem');
6 6
7 const router = express.Router(); 7 const router = express.Router();
8 module.exports = router; 8 module.exports = router;
9 9
10 10
11 async function handlerIndex(req, res) { 11 async function handlerIndex(req, res) {
12 if (!req.query || !req.query.code || typeof req.query.code !== 'string' || !req.query.code.trim()) { 12 if (!req.query || !req.query.code || typeof req.query.code !== 'string') {
13 res.json({ 13 res.json({
14 status: 'NOT-OK', 14 status: 'NOT-OK',
15 error: 'INVALID-PARAMETER', 15 error: 'INVALID-PARAMETER',
16 message: 'Undefined parameter: code', 16 message: 'Undefined parameter: code',
17 }); 17 });
18 } 18 }
19 19
20 const reply = await modem.executeUSSD(req.query.code.trim()); 20 const reply = await modem.executeUSSD(req.query.code);
21 res.json({ 21 res.json({
22 status: 'OK', 22 status: 'OK',
23 error: false, 23 error: false,
24 message: 'USSD executed', 24 code: req.query.code,
25 result: reply, 25 result: reply,
26 message: 'USSD executed',
26 }); 27 });
27 } 28 }
28 29
29 router.get('/', handlerIndex); 30 router.get('/', handlerIndex);
30 31
1 'use strict'; 1 'use strict';
2 2
3 const INTERVAL_BEETWEN_SIGNAL_STRENGTH_MS = 60000; 3 const INTERVAL_BEETWEN_SIGNAL_STRENGTH_MS = 60000;
4 const MAX_LAST_DATA_AGE_MS = 3 * 60 * 1000; 4 const MAX_LAST_DATA_AGE_MS = 3 * 60 * 1000;
5 const REGEX_WAIT_FOR_OK_OR_ERROR = /\n(?:OK|ERROR)\r/; 5 const REGEX_WAIT_FOR_OK_OR_ERROR = /\n(?:OK|ERROR)\r/;
6 // const REGEX_WAIT_FOR_OK_OR_ERROR_USSD = /\n(?:OK|ERROR)\r/; 6 // const REGEX_WAIT_FOR_OK_OR_ERROR_USSD = /\n(?:OK|ERROR)\r/;
7 7
8 const moment = require('moment'); 8 const moment = require('moment');
9 const SerialPort = require('serialport'); 9 const SerialPort = require('serialport');
10 const ParserReadline = require('@serialport/parser-readline'); 10 const ParserReadline = require('@serialport/parser-readline');
11 // const ParserDelimiter = require('@serialport/parser-delimiter'); 11 // const ParserDelimiter = require('@serialport/parser-delimiter');
12 12
13 const ParserRegex = require('@serialport/parser-regex'); 13 const ParserRegex = require('@serialport/parser-regex');
14 14
15 const config = require('komodo-sdk/config'); 15 const config = require('komodo-sdk/config');
16 const logger = require('komodo-sdk/logger'); 16 const logger = require('komodo-sdk/logger');
17 17
18 const mutex = require('./mutex'); 18 const mutex = require('./mutex');
19 const common = require('./common'); 19 const common = require('./common');
20 const sms = require('./sms'); 20 const sms = require('./sms');
21 const dbCops = require('./db-cops'); 21 const dbCops = require('./db-cops');
22 const reportSender = require('./report-sender'); 22 const reportSender = require('./report-sender');
23 // const msisdn = require('./msisdn'); 23 // const msisdn = require('./msisdn');
24 const registerModem = require('./register-modem'); 24 const registerModem = require('./register-modem');
25 // const counters = require('./counters'); 25 // const counters = require('./counters');
26 26
27 const modemInfo = { 27 const modemInfo = {
28 device: config.modem.device, 28 device: config.modem.device,
29 manufacturer: null, 29 manufacturer: null,
30 model: null, 30 model: null,
31 imei: null, 31 imei: null,
32 imsi: null, 32 imsi: null,
33 msisdn: null, 33 msisdn: null,
34 cops: null, 34 cops: null,
35 networkId: null, 35 networkId: null,
36 networkName: null, 36 networkName: null,
37 signalStrength: null, 37 signalStrength: null,
38 signalStrengthTs: null, 38 signalStrengthTs: null,
39 signalStrengthTsReadable: null, 39 signalStrengthTsReadable: null,
40 // messageSentCounter: null, 40 // messageSentCounter: null,
41 // messageReceivedCounter: null, 41 // messageReceivedCounter: null,
42 }; 42 };
43 43
44 let lastTs = new Date(); 44 let lastTs = new Date();
45 45
46 let port; 46 let port;
47 47
48 const parserReadLine = new ParserReadline(); 48 const parserReadLine = new ParserReadline();
49 49
50 const parserWaitForOK = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); 50 const parserWaitForOK = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
51 parserWaitForOK.on('data', () => { 51 parserWaitForOK.on('data', () => {
52 mutex.releaseLockWaitForCommand(); 52 mutex.releaseLockWaitForCommand();
53 }); 53 });
54 54
55 function writeToPort(data) { 55 function writeToPort(data) {
56 return new Promise((resolve) => { 56 return new Promise((resolve) => {
57 port.write(data, (err, bytesWritten) => { 57 port.write(data, (err, bytesWritten) => {
58 if (err) logger.warn(`ERROR: ${err.toString()}`); 58 if (err) logger.warn(`ERROR: ${err.toString()}`);
59 logger.verbose(`* OUT: ${data}`); 59 logger.verbose(`* OUT: ${data}`);
60 resolve(bytesWritten); 60 resolve(bytesWritten);
61 }); 61 });
62 }); 62 });
63 } 63 }
64 64
65 async function readSMS(slot) { 65 async function readSMS(slot) {
66 const parserCMGR = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); 66 const parserCMGR = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
67 parserCMGR.on('data', (data) => { 67 parserCMGR.on('data', (data) => {
68 if (data) { 68 if (data) {
69 try { 69 try {
70 reportSender.incomingSMS(sms.extract(data.toString().trim()), modemInfo); 70 reportSender.incomingSMS(sms.extract(data.toString().trim()), modemInfo);
71 } catch (e) { 71 } catch (e) {
72 logger.warn(`Exception on reporting new message. ${e.toString()}`, { smsObj: e.smsObj, dataFromModem: data }); 72 logger.warn(`Exception on reporting new message. ${e.toString()}`, { smsObj: e.smsObj, dataFromModem: data });
73 73
74 process.exit(0); 74 process.exit(0);
75 } 75 }
76 } 76 }
77 port.unpipe(parserCMGR); 77 port.unpipe(parserCMGR);
78 mutex.releaseLockWaitForCommand(); 78 mutex.releaseLockWaitForCommand();
79 }); 79 });
80 80
81 // const parserCMGD = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); 81 // const parserCMGD = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK });
82 const parserCMGD = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); 82 const parserCMGD = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
83 parserCMGD.on('data', () => { 83 parserCMGD.on('data', () => {
84 port.unpipe(parserCMGD); 84 port.unpipe(parserCMGD);
85 mutex.releaseLockWaitForCommand(); 85 mutex.releaseLockWaitForCommand();
86 }); 86 });
87 87
88 logger.info(`Reading SMS on slot ${slot}`); 88 logger.info(`Reading SMS on slot ${slot}`);
89 await mutex.setLockWaitForCommand(); 89 await mutex.setLockWaitForCommand();
90 port.pipe(parserCMGR); 90 port.pipe(parserCMGR);
91 await writeToPort(`AT+CMGR=${slot}\r`); 91 await writeToPort(`AT+CMGR=${slot}\r`);
92 logger.info(`Finished reading SMS on slot ${slot}`); 92 logger.info(`Finished reading SMS on slot ${slot}`);
93 93
94 logger.info(`Deleting message on slot ${slot}`); 94 logger.info(`Deleting message on slot ${slot}`);
95 await mutex.setLockWaitForCommand(); 95 await mutex.setLockWaitForCommand();
96 port.pipe(parserCMGD); 96 port.pipe(parserCMGD);
97 await writeToPort(`AT+CMGD=${slot}\r`); 97 await writeToPort(`AT+CMGD=${slot}\r`);
98 logger.info('Message processing has completed'); 98 logger.info('Message processing has completed');
99 } 99 }
100 100
101 function onIncomingSMS(data) { 101 function onIncomingSMS(data) {
102 const value = common.extractValueFromReadLineData(data); 102 const value = common.extractValueFromReadLineData(data);
103 if (!value) return; 103 if (!value) return;
104 104
105 const chunks = value.split(','); 105 const chunks = value.split(',');
106 if (!chunks && !chunks[1]) return; 106 if (!chunks && !chunks[1]) return;
107 107
108 const slot = chunks[1]; 108 const slot = chunks[1];
109 109
110 logger.info(`Incoming SMS on slot ${slot}`); 110 logger.info(`Incoming SMS on slot ${slot}`);
111 readSMS(slot); 111 readSMS(slot);
112 } 112 }
113 113
114 function onCOPS(data) { 114 function onCOPS(data) {
115 modemInfo.cops = common.extractValueFromReadLineData(data).trim(); 115 modemInfo.cops = common.extractValueFromReadLineData(data).trim();
116 logger.info(`Connected Network: ${modemInfo.cops}`); 116 logger.info(`Connected Network: ${modemInfo.cops}`);
117 117
118 if (!modemInfo.cops) return; 118 if (!modemInfo.cops) return;
119 119
120 [, , modemInfo.networkId] = modemInfo.cops.split(','); 120 [, , modemInfo.networkId] = modemInfo.cops.split(',');
121 121
122 if (modemInfo.networkId) { 122 if (modemInfo.networkId) {
123 modemInfo.networkName = dbCops[modemInfo.networkId] || modemInfo.networkId; 123 modemInfo.networkName = dbCops[modemInfo.networkId] || modemInfo.networkId;
124 } 124 }
125 } 125 }
126 126
127 parserReadLine.on('data', (data) => { 127 parserReadLine.on('data', (data) => {
128 logger.verbose(`* IN: ${data}`); 128 logger.verbose(`* IN: ${data}`);
129 if (data) { 129 if (data) {
130 lastTs = new Date(); 130 lastTs = new Date();
131 if (data.indexOf('+CSQ: ') === 0) { 131 if (data.indexOf('+CSQ: ') === 0) {
132 const signalStrength = common.extractValueFromReadLineData(data).trim(); 132 const signalStrength = common.extractValueFromReadLineData(data).trim();
133 if (signalStrength) { 133 if (signalStrength) {
134 modemInfo.signalStrength = signalStrength; 134 modemInfo.signalStrength = signalStrength;
135 modemInfo.signalStrengthTs = new Date(); 135 modemInfo.signalStrengthTs = new Date();
136 modemInfo.signalStrengthTsReadable = moment(modemInfo.signalStrengthTs).format('YYYY-MM-DD HH:mm:ss'); 136 modemInfo.signalStrengthTsReadable = moment(modemInfo.signalStrengthTs).format('YYYY-MM-DD HH:mm:ss');
137 logger.info(`Signal strength: ${modemInfo.signalStrength}`); 137 logger.info(`Signal strength: ${modemInfo.signalStrength}`);
138 registerModem(modemInfo); 138 registerModem(modemInfo);
139 } 139 }
140 } else if (data.indexOf('+CMTI: ') === 0) { 140 } else if (data.indexOf('+CMTI: ') === 0) {
141 // counters.increment('MESSAGE_RECEIVED', modemInfo); 141 // counters.increment('MESSAGE_RECEIVED', modemInfo);
142 onIncomingSMS(data); 142 onIncomingSMS(data);
143 } else if (data.indexOf('+COPS: ') === 0) { 143 } else if (data.indexOf('+COPS: ') === 0) {
144 onCOPS(data); 144 onCOPS(data);
145 } 145 }
146 } 146 }
147 }); 147 });
148 148
149 async function simpleSubCommand(cmd, callback) { 149 async function simpleSubCommand(cmd, callback) {
150 const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); 150 const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
151 parser.on('data', (data) => { 151 parser.on('data', (data) => {
152 port.unpipe(parser); 152 port.unpipe(parser);
153 mutex.releaseLockWaitForSubCommand(); 153 mutex.releaseLockWaitForSubCommand();
154 154
155 if (data) { 155 if (data) {
156 if (callback) callback(null, data.toString().trim()); 156 if (callback) callback(null, data.toString().trim());
157 } 157 }
158 }); 158 });
159 159
160 return new Promise(async (resolve) => { 160 return new Promise(async (resolve) => {
161 await mutex.setLockWaitForSubCommand(); 161 await mutex.setLockWaitForSubCommand();
162 port.pipe(parser); 162 port.pipe(parser);
163 writeToPort(cmd); 163 writeToPort(cmd);
164 164
165 await mutex.setLockWaitForSubCommand(); 165 await mutex.setLockWaitForSubCommand();
166 mutex.releaseLockWaitForSubCommand(); 166 mutex.releaseLockWaitForSubCommand();
167 167
168 resolve(); 168 resolve();
169 }); 169 });
170 } 170 }
171 171
172 function readManufacturer() { 172 function readManufacturer() {
173 return new Promise((resolve) => { 173 return new Promise((resolve) => {
174 simpleSubCommand('AT+CGMI\r', (err, result) => { 174 simpleSubCommand('AT+CGMI\r', (err, result) => {
175 modemInfo.manufacturer = result; 175 modemInfo.manufacturer = result;
176 logger.info(`Manufacturer: ${result}`); 176 logger.info(`Manufacturer: ${result}`);
177 resolve(result); 177 resolve(result);
178 }); 178 });
179 }); 179 });
180 } 180 }
181 181
182 function readModel() { 182 function readModel() {
183 return new Promise((resolve) => { 183 return new Promise((resolve) => {
184 simpleSubCommand('AT+CGMM\r', (err, result) => { 184 simpleSubCommand('AT+CGMM\r', (err, result) => {
185 modemInfo.model = result; 185 modemInfo.model = result;
186 logger.info(`Model: ${result}`); 186 logger.info(`Model: ${result}`);
187 resolve(result); 187 resolve(result);
188 }); 188 });
189 }); 189 });
190 } 190 }
191 191
192 function readIMEI() { 192 function readIMEI() {
193 return new Promise((resolve) => { 193 return new Promise((resolve) => {
194 simpleSubCommand('AT+CGSN\r', (err, result) => { 194 simpleSubCommand('AT+CGSN\r', (err, result) => {
195 modemInfo.imei = result; 195 modemInfo.imei = result;
196 logger.info(`IMEI: ${result}`); 196 logger.info(`IMEI: ${result}`);
197 resolve(result); 197 resolve(result);
198 }); 198 });
199 }); 199 });
200 } 200 }
201 201
202 function readIMSI() { 202 function readIMSI() {
203 return new Promise((resolve) => { 203 return new Promise((resolve) => {
204 simpleSubCommand('AT+CIMI\r', (err, result) => { 204 simpleSubCommand('AT+CIMI\r', (err, result) => {
205 modemInfo.imsi = result; 205 modemInfo.imsi = result;
206 logger.info(`IMSI: ${result}`); 206 logger.info(`IMSI: ${result}`);
207 207
208 if (result) { 208 if (result) {
209 /* 209 /*
210 modemInfo.msisdn = msisdn[result]; 210 modemInfo.msisdn = msisdn[result];
211 if (modemInfo.msisdn) { 211 if (modemInfo.msisdn) {
212 logger.info(`MSISDN: ${modemInfo.msisdn}`); 212 logger.info(`MSISDN: ${modemInfo.msisdn}`);
213 registerModem(modemInfo); 213 registerModem(modemInfo);
214 } 214 }
215 */ 215 */
216 } else { 216 } else {
217 logger.warn(`IMSI not detected. Please insert a sim card to your modem. Terminating ${config.modem.device}.`); 217 logger.warn(`IMSI not detected. Please insert a sim card to your modem. Terminating ${config.modem.device}.`);
218 process.exit(2); 218 process.exit(2);
219 } 219 }
220 resolve(result); 220 resolve(result);
221 }); 221 });
222 }); 222 });
223 } 223 }
224 224
225 function readCOPS() { 225 function readCOPS() {
226 return new Promise((resolve) => { 226 return new Promise((resolve) => {
227 simpleSubCommand('AT+COPS?\r', (err, result) => { 227 simpleSubCommand('AT+COPS?\r', (err, result) => {
228 resolve(result); 228 resolve(result);
229 }); 229 });
230 }); 230 });
231 } 231 }
232 232
233 function deleteInbox() { 233 function deleteInbox() {
234 return new Promise((resolve) => { 234 return new Promise((resolve) => {
235 simpleSubCommand('AT+CMGD=0,4\r', (err, result) => { 235 simpleSubCommand('AT+CMGD=0,4\r', (err, result) => {
236 resolve(result); 236 resolve(result);
237 }); 237 });
238 }); 238 });
239 } 239 }
240 240
241 async function querySignalStrength() { 241 async function querySignalStrength() {
242 const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); 242 const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
243 parser.on('data', () => { 243 parser.on('data', () => {
244 port.unpipe(parser); 244 port.unpipe(parser);
245 mutex.releaseLockWaitForCommand(); 245 mutex.releaseLockWaitForCommand();
246 }); 246 });
247 247
248 if (mutex.tryLockWaitForCommand()) { 248 if (mutex.tryLockWaitForCommand()) {
249 port.pipe(parser); 249 port.pipe(parser);
250 await writeToPort('AT+CSQ\r'); 250 await writeToPort('AT+CSQ\r');
251 } 251 }
252 } 252 }
253 253
254 function registerModemToCenterPeriodically() { 254 function registerModemToCenterPeriodically() {
255 registerModem(modemInfo); 255 registerModem(modemInfo);
256 256
257 setInterval(() => { 257 setInterval(() => {
258 registerModem(modemInfo); 258 registerModem(modemInfo);
259 }, 60 * 1000); 259 }, 60 * 1000);
260 } 260 }
261 261
262 async function registerSignalStrengthBackgroundQuery() { 262 async function registerSignalStrengthBackgroundQuery() {
263 logger.info('Registering background signal strength query'); 263 logger.info('Registering background signal strength query');
264 264
265 querySignalStrength(); 265 querySignalStrength();
266 266
267 setInterval(() => { 267 setInterval(() => {
268 querySignalStrength(); 268 querySignalStrength();
269 }, config.interval_beetwen_signal_strength_ms || INTERVAL_BEETWEN_SIGNAL_STRENGTH_MS); 269 }, config.interval_beetwen_signal_strength_ms || INTERVAL_BEETWEN_SIGNAL_STRENGTH_MS);
270 } 270 }
271 271
272 async function sendSMS(destination, msg) { 272 async function sendSMS(destination, msg) {
273 if (typeof destination !== 'string' || typeof msg !== 'string' || !destination.trim() || !msg.trim()) return; 273 if (typeof destination !== 'string' || typeof msg !== 'string' || !destination.trim() || !msg.trim()) return;
274 274
275 const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); 275 const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
276 parser.on('data', () => { 276 parser.on('data', () => {
277 port.unpipe(parser); 277 port.unpipe(parser);
278 mutex.releaseLockWaitForSubCommand(); 278 mutex.releaseLockWaitForSubCommand();
279 }); 279 });
280 280
281 logger.verbose('Waiting for command lock to send message'); 281 logger.verbose('Waiting for command lock to send message');
282 await mutex.setLockWaitForCommand(); 282 await mutex.setLockWaitForCommand();
283 283
284 logger.info('Sending message', { destination, msg }); 284 logger.info('Sending message', { destination, msg });
285 // counters.increment('MESSAGE_SENT', modemInfo); 285 // counters.increment('MESSAGE_SENT', modemInfo);
286 286
287 const correctedDestination = `+${destination}`.replace(/^0/, '62').replace(/^\++/, '+'); 287 const correctedDestination = `+${destination}`.replace(/^0/, '62').replace(/^\++/, '+');
288 288
289 logger.verbose('Waiting for lock before set to text mode'); 289 logger.verbose('Waiting for lock before set to text mode');
290 await mutex.setLockWaitForSubCommand(); 290 await mutex.setLockWaitForSubCommand();
291 port.pipe(parser); 291 port.pipe(parser);
292 await writeToPort('AT+CMGF=1\r'); 292 await writeToPort('AT+CMGF=1\r');
293 293
294 logger.verbose('Waiting for lock before writing message'); 294 logger.verbose('Waiting for lock before writing message');
295 await mutex.setLockWaitForSubCommand(); 295 await mutex.setLockWaitForSubCommand();
296 port.pipe(parser); 296 port.pipe(parser);
297 await writeToPort(`AT+CMGS="${correctedDestination}"\r${msg}${Buffer.from([0x1A])}`); 297 await writeToPort(`AT+CMGS="${correctedDestination}"\r${msg}${Buffer.from([0x1A])}`);
298 298
299 await mutex.setLockWaitForSubCommand(); 299 await mutex.setLockWaitForSubCommand();
300 mutex.releaseLockWaitForSubCommand(); 300 mutex.releaseLockWaitForSubCommand();
301 301
302 logger.info('Message has been sent'); 302 logger.info('Message has been sent');
303 303
304 setTimeout(() => { 304 setTimeout(() => {
305 logger.verbose('Releasing command lock'); 305 logger.verbose('Releasing command lock');
306 mutex.releaseLockWaitForCommand(); 306 mutex.releaseLockWaitForCommand();
307 }, config.wait_for_release_lock_wait_for_command_ms || 2000); 307 }, config.wait_for_release_lock_wait_for_command_ms || 2000);
308 } 308 }
309 /** 309 /**
310 * Ekseksusi kode USSD. 310 * Ekseksusi kode USSD.
311 * 311 *
312 * @param {string} cmd - Kode USSD 312 * @param {string} code - Kode USSD
313 */ 313 */
314 function executeUSSD(cmd) { 314 function executeUSSD(code) {
315 return new Promise(async (resolve) => { 315 return new Promise(async (resolve) => {
316 const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); 316 const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
317 parser.on('data', (data) => { 317 parser.on('data', (data) => {
318 port.unpipe(parser); 318 port.unpipe(parser);
319 mutex.releaseLockWaitForSubCommand(); 319 mutex.releaseLockWaitForSubCommand();
320 resolve(data); 320 resolve(data);
321 }); 321 });
322 322
323 logger.verbose('Waiting for command lock to execute USSD'); 323 logger.verbose('Waiting for command lock to execute USSD');
324 await mutex.setLockWaitForCommand(); 324 await mutex.setLockWaitForCommand();
325 325
326 await mutex.setLockWaitForSubCommand(); 326 await mutex.setLockWaitForSubCommand();
327 await writeToPort(`AT+CUSD=1,"${cmd.trim()}",15\r`); 327 await writeToPort(`AT+CUSD=1,"${code.trim()}",15\r`);
328 328
329 await mutex.setLockWaitForSubCommand(); 329 await mutex.setLockWaitForSubCommand();
330 mutex.releaseLockWaitForSubCommand(); 330 mutex.releaseLockWaitForSubCommand();
331 331
332 mutex.releaseLockWaitForCommand(); 332 mutex.releaseLockWaitForCommand();
333 }); 333 });
334 } 334 }
335 335
336 function init() { 336 function init() {
337 port = new SerialPort(config.modem.device, { baudRate: 115200 }, (err) => { 337 port = new SerialPort(config.modem.device, { baudRate: 115200 }, (err) => {
338 if (err) { 338 if (err) {
339 logger.warn(`Error opening modem. ${err}. Terminating modem ${config.modem.device}.`); 339 logger.warn(`Error opening modem. ${err}. Terminating modem ${config.modem.device}.`);
340 process.exit(1); 340 process.exit(1);
341 } 341 }
342 342
343 registerModem(modemInfo); 343 registerModem(modemInfo);
344 }); 344 });
345 port.pipe(parserReadLine); 345 port.pipe(parserReadLine);
346 346
347 setInterval(() => { 347 setInterval(() => {
348 if ((new Date() - lastTs) > MAX_LAST_DATA_AGE_MS) { 348 if ((new Date() - lastTs) > MAX_LAST_DATA_AGE_MS) {
349 logger.warn(`No data for more than ${MAX_LAST_DATA_AGE_MS} ms. Modem might be unresponsive. Terminating modem ${config.modem.device}.`); 349 logger.warn(`No data for more than ${MAX_LAST_DATA_AGE_MS} ms. Modem might be unresponsive. Terminating modem ${config.modem.device}.`);
350 process.exit(0); 350 process.exit(0);
351 } 351 }
352 }, 30 * 1000); 352 }, 30 * 1000);
353 353
354 port.on('open', async () => { 354 port.on('open', async () => {
355 await mutex.setLockWaitForCommand(); 355 await mutex.setLockWaitForCommand();
356 356
357 logger.info('Modem opened'); 357 logger.info('Modem opened');
358 await writeToPort('\r'); 358 await writeToPort('\r');
359 await simpleSubCommand('AT\r'); 359 await simpleSubCommand('AT\r');
360 360
361 logger.info('Initializing modem to factory set'); 361 logger.info('Initializing modem to factory set');
362 await simpleSubCommand('AT&F\r'); 362 await simpleSubCommand('AT&F\r');
363 363
364 logger.info('Disabling echo'); 364 logger.info('Disabling echo');
365 await simpleSubCommand('ATE0\r'); 365 await simpleSubCommand('ATE0\r');
366 366
367 logger.info('Set to text mode'); 367 logger.info('Set to text mode');
368 await simpleSubCommand('AT+CMGF=1\r'); 368 await simpleSubCommand('AT+CMGF=1\r');
369 369
370 await readCOPS(); 370 await readCOPS();
371 371
372 await readManufacturer(); 372 await readManufacturer();
373 await readModel(); 373 await readModel();
374 await readIMEI(); 374 await readIMEI();
375 await readIMSI(); 375 await readIMSI();
376 376
377 if (!config.disable_delete_inbox_on_startup) { 377 if (!config.disable_delete_inbox_on_startup) {
378 logger.info('Deleting existing messages'); 378 logger.info('Deleting existing messages');
379 await deleteInbox(); 379 await deleteInbox();
380 } 380 }
381 381
382 mutex.releaseLockWaitForCommand(); 382 mutex.releaseLockWaitForCommand();
383 logger.verbose('Init completed'); 383 logger.verbose('Init completed');
384 384
385 registerModemToCenterPeriodically(); 385 registerModemToCenterPeriodically();
386 registerSignalStrengthBackgroundQuery(); 386 registerSignalStrengthBackgroundQuery();
387 }); 387 });
388 } 388 }
389 389
390 init(); 390 init();
391 391
392 exports.modemInfo = modemInfo; 392 exports.modemInfo = modemInfo;
393 exports.sendSMS = sendSMS; 393 exports.sendSMS = sendSMS;
394 exports.executeUSSD = executeUSSD; 394 exports.executeUSSD = executeUSSD;
395 395