Commit 49ca8506b009c10233eb375255109aa9c50ceee8

Authored by Adhidarma Hadiwinoto
1 parent b21c4fec10
Exists in master

CUSD2

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