Commit 7012ada0ede60dacfa498c68ca7cf6882c72494e

Authored by Adhidarma Hadiwinoto
1 parent f323e782da
Exists in master

CNMI

Showing 1 changed file with 3 additions and 0 deletions Inline Diff

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 const parser = new ParserReadline({ delimiter: '\r\n' }); 276 const parser = new ParserReadline({ delimiter: '\r\n' });
277 parser.on('data', () => { 277 parser.on('data', () => {
278 port.unpipe(parser); 278 port.unpipe(parser);
279 mutex.releaseLockWaitForSubCommand(); 279 mutex.releaseLockWaitForSubCommand();
280 }); 280 });
281 281
282 logger.verbose('Waiting for command lock to send message'); 282 logger.verbose('Waiting for command lock to send message');
283 await mutex.setLockWaitForCommand(); 283 await mutex.setLockWaitForCommand();
284 284
285 logger.info('Sending message', { destination, msg }); 285 logger.info('Sending message', { destination, msg });
286 // counters.increment('MESSAGE_SENT', modemInfo); 286 // counters.increment('MESSAGE_SENT', modemInfo);
287 287
288 const correctedDestination = `+${destination}`.replace(/^0/, '62').replace(/^\++/, '+'); 288 const correctedDestination = `+${destination}`.replace(/^0/, '62').replace(/^\++/, '+');
289 289
290 logger.verbose('Waiting for lock before set to text mode'); 290 logger.verbose('Waiting for lock before set to text mode');
291 await mutex.setLockWaitForSubCommand(); 291 await mutex.setLockWaitForSubCommand();
292 port.pipe(parser); 292 port.pipe(parser);
293 await writeToPort('AT+CMGF=1\r'); 293 await writeToPort('AT+CMGF=1\r');
294 294
295 logger.verbose('Waiting for lock before writing message'); 295 logger.verbose('Waiting for lock before writing message');
296 await mutex.setLockWaitForSubCommand(); 296 await mutex.setLockWaitForSubCommand();
297 port.pipe(parser); 297 port.pipe(parser);
298 await writeToPort(`AT+CMGS="${correctedDestination}"\r${msg}${Buffer.from([0x1A])}`); 298 await writeToPort(`AT+CMGS="${correctedDestination}"\r${msg}${Buffer.from([0x1A])}`);
299 299
300 await mutex.setLockWaitForSubCommand(); 300 await mutex.setLockWaitForSubCommand();
301 mutex.releaseLockWaitForSubCommand(); 301 mutex.releaseLockWaitForSubCommand();
302 302
303 logger.info('Message has been sent'); 303 logger.info('Message has been sent');
304 304
305 setTimeout(() => { 305 setTimeout(() => {
306 logger.verbose('Releasing command lock'); 306 logger.verbose('Releasing command lock');
307 mutex.releaseLockWaitForCommand(); 307 mutex.releaseLockWaitForCommand();
308 }, config.wait_for_release_lock_wait_for_command_ms || 2000); 308 }, config.wait_for_release_lock_wait_for_command_ms || 2000);
309 } 309 }
310 310
311 /** 311 /**
312 * Ekseksusi kode USSD. 312 * Ekseksusi kode USSD.
313 * 313 *
314 * Pilihan includeCUSD2: 314 * Pilihan includeCUSD2:
315 * -1: sebelum 315 * -1: sebelum
316 * 0: tidak (default) 316 * 0: tidak (default)
317 * 1: sesudah 317 * 1: sesudah
318 * 2: sebelum dan sesudah 318 * 2: sebelum dan sesudah
319 * 319 *
320 * @param {string} code - Kode USSD 320 * @param {string} code - Kode USSD
321 * @param {number} [includeCUSD2=0] - Apakah ingin otomatis memasukkan CUSD=2 321 * @param {number} [includeCUSD2=0] - Apakah ingin otomatis memasukkan CUSD=2
322 */ 322 */
323 function executeUSSD(code, includeCUSD2) { 323 function executeUSSD(code, includeCUSD2) {
324 return new Promise(async (resolve) => { 324 return new Promise(async (resolve) => {
325 const parserMain = new ParserReadline({ delimiter: '\r\n' }); 325 const parserMain = new ParserReadline({ delimiter: '\r\n' });
326 // const parserMain = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); 326 // const parserMain = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
327 parserMain.on('data', (data) => { 327 parserMain.on('data', (data) => {
328 if (!data || !data.toString().trim()) return; 328 if (!data || !data.toString().trim()) return;
329 329
330 if (data.toString().trim() === 'OK') return; 330 if (data.toString().trim() === 'OK') return;
331 331
332 port.unpipe(parserMain); 332 port.unpipe(parserMain);
333 mutex.releaseLockWaitForSubCommand(); 333 mutex.releaseLockWaitForSubCommand();
334 resolve(data); 334 resolve(data);
335 }); 335 });
336 336
337 const parserCUSD2 = new ParserReadline({ delimiter: '\r\n' }); 337 const parserCUSD2 = new ParserReadline({ delimiter: '\r\n' });
338 // const parserCUSD2 = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR }); 338 // const parserCUSD2 = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
339 parserCUSD2.on('data', () => { 339 parserCUSD2.on('data', () => {
340 port.unpipe(parserCUSD2); 340 port.unpipe(parserCUSD2);
341 mutex.releaseLockWaitForSubCommand(); 341 mutex.releaseLockWaitForSubCommand();
342 }); 342 });
343 343
344 logger.verbose('Waiting for command lock to execute USSD'); 344 logger.verbose('Waiting for command lock to execute USSD');
345 await mutex.setLockWaitForCommand(); 345 await mutex.setLockWaitForCommand();
346 346
347 if (includeCUSD2 === -1 || includeCUSD2 === 2) { 347 if (includeCUSD2 === -1 || includeCUSD2 === 2) {
348 await mutex.setLockWaitForSubCommand(); 348 await mutex.setLockWaitForSubCommand();
349 logger.info('Terminating existing USSD session'); 349 logger.info('Terminating existing USSD session');
350 port.pipe(parserCUSD2); 350 port.pipe(parserCUSD2);
351 await writeToPort('AT+CUSD=2\r'); 351 await writeToPort('AT+CUSD=2\r');
352 } 352 }
353 353
354 await mutex.setLockWaitForSubCommand(); 354 await mutex.setLockWaitForSubCommand();
355 logger.info(`Executing USSD code "${code}"`); 355 logger.info(`Executing USSD code "${code}"`);
356 port.pipe(parserMain); 356 port.pipe(parserMain);
357 await writeToPort(`AT+CUSD=1,"${code}",15\r`); 357 await writeToPort(`AT+CUSD=1,"${code}",15\r`);
358 358
359 if (includeCUSD2 === 1 || includeCUSD2 === 2) { 359 if (includeCUSD2 === 1 || includeCUSD2 === 2) {
360 await mutex.setLockWaitForSubCommand(); 360 await mutex.setLockWaitForSubCommand();
361 logger.info('Terminating existing USSD session'); 361 logger.info('Terminating existing USSD session');
362 port.pipe(parserCUSD2); 362 port.pipe(parserCUSD2);
363 await writeToPort('AT+CUSD=2\r'); 363 await writeToPort('AT+CUSD=2\r');
364 } 364 }
365 365
366 await mutex.setLockWaitForSubCommand(); 366 await mutex.setLockWaitForSubCommand();
367 mutex.releaseLockWaitForSubCommand(); 367 mutex.releaseLockWaitForSubCommand();
368 368
369 mutex.releaseLockWaitForCommand(); 369 mutex.releaseLockWaitForCommand();
370 }); 370 });
371 } 371 }
372 372
373 function init() { 373 function init() {
374 port = new SerialPort(config.modem.device, { baudRate: 115200 }, (err) => { 374 port = new SerialPort(config.modem.device, { baudRate: 115200 }, (err) => {
375 if (err) { 375 if (err) {
376 logger.warn(`Error opening modem. ${err}. Terminating modem ${config.modem.device}.`); 376 logger.warn(`Error opening modem. ${err}. Terminating modem ${config.modem.device}.`);
377 process.exit(1); 377 process.exit(1);
378 } 378 }
379 379
380 registerModem(modemInfo); 380 registerModem(modemInfo);
381 }); 381 });
382 port.pipe(parserReadLine); 382 port.pipe(parserReadLine);
383 383
384 setInterval(() => { 384 setInterval(() => {
385 if ((new Date() - lastTs) > MAX_LAST_DATA_AGE_MS) { 385 if ((new Date() - lastTs) > MAX_LAST_DATA_AGE_MS) {
386 logger.warn(`No data for more than ${MAX_LAST_DATA_AGE_MS} ms. Modem might be unresponsive. Terminating modem ${config.modem.device}.`); 386 logger.warn(`No data for more than ${MAX_LAST_DATA_AGE_MS} ms. Modem might be unresponsive. Terminating modem ${config.modem.device}.`);
387 process.exit(0); 387 process.exit(0);
388 } 388 }
389 }, 30 * 1000); 389 }, 30 * 1000);
390 390
391 port.on('open', async () => { 391 port.on('open', async () => {
392 await mutex.setLockWaitForCommand(); 392 await mutex.setLockWaitForCommand();
393 393
394 logger.info('Modem opened'); 394 logger.info('Modem opened');
395 await writeToPort('\r'); 395 await writeToPort('\r');
396 await simpleSubCommand('AT\r'); 396 await simpleSubCommand('AT\r');
397 397
398 logger.info('Initializing modem to factory set'); 398 logger.info('Initializing modem to factory set');
399 await simpleSubCommand('AT&F\r'); 399 await simpleSubCommand('AT&F\r');
400 400
401 logger.info('Disabling echo'); 401 logger.info('Disabling echo');
402 await simpleSubCommand('ATE0\r'); 402 await simpleSubCommand('ATE0\r');
403 403
404 logger.info('Set to text mode'); 404 logger.info('Set to text mode');
405 await simpleSubCommand('AT+CMGF=1\r'); 405 await simpleSubCommand('AT+CMGF=1\r');
406 406
407 logger.info('Set message indication');
408 await simpleSubCommand('AT+CNMI=1,1,2,1,1\r');
409
407 await readCOPS(); 410 await readCOPS();
408 411
409 await readManufacturer(); 412 await readManufacturer();
410 await readModel(); 413 await readModel();
411 await readIMEI(); 414 await readIMEI();
412 await readIMSI(); 415 await readIMSI();
413 416
414 if (!config.disable_delete_inbox_on_startup) { 417 if (!config.disable_delete_inbox_on_startup) {
415 logger.info('Deleting existing messages'); 418 logger.info('Deleting existing messages');
416 await deleteInbox(); 419 await deleteInbox();
417 } 420 }
418 421
419 mutex.releaseLockWaitForCommand(); 422 mutex.releaseLockWaitForCommand();
420 logger.verbose('Init completed'); 423 logger.verbose('Init completed');
421 424
422 registerModemToCenterPeriodically(); 425 registerModemToCenterPeriodically();
423 registerSignalStrengthBackgroundQuery(); 426 registerSignalStrengthBackgroundQuery();
424 }); 427 });
425 } 428 }
426 429
427 init(); 430 init();
428 431
429 exports.modemInfo = modemInfo; 432 exports.modemInfo = modemInfo;
430 exports.sendSMS = sendSMS; 433 exports.sendSMS = sendSMS;
431 exports.executeUSSD = executeUSSD; 434 exports.executeUSSD = executeUSSD;
432 435