Blame view

lib/modem.js 11.4 KB
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
1
2
3
  'use strict';
  
  const INTERVAL_BEETWEN_SIGNAL_STRENGTH_MS = 60000;
fb3911e43   Adhidarma Hadiwinoto   Typo max age
4
  const MAX_LAST_DATA_AGE_MS = 3 * 60 * 1000;
8ebd9e257   Adhidarma Hadiwinoto   Coba delimiter \n
5
6
  const REGEX_WAIT_FOR_OK_OR_ERROR = /
  (?:OK|ERROR)\r/;
c5ce14d55   Adhidarma Hadiwinoto   Uji coba ussd
7
8
  // const REGEX_WAIT_FOR_OK_OR_ERROR_USSD = /
  (?:OK|ERROR)\r/;
35ba3f574   Adhidarma Hadiwinoto   Proteksi kalo mod...
9

5a00ec06f   Adhidarma Hadiwinoto   DEBUG signalStrength
10
  const moment = require('moment');
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
11
12
  const SerialPort = require('serialport');
  const ParserReadline = require('@serialport/parser-readline');
2db546a87   Adhidarma Hadiwinoto   Regex parser
13
14
15
  // const ParserDelimiter = require('@serialport/parser-delimiter');
  
  const ParserRegex = require('@serialport/parser-regex');
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
16
17
18
  
  const config = require('komodo-sdk/config');
  const logger = require('komodo-sdk/logger');
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
19

cba7eef40   Adhidarma Hadiwinoto   Separate locks fu...
20
  const mutex = require('./mutex');
67af4245e   Adhidarma Hadiwinoto   Refactor util men...
21
  const common = require('./common');
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
22
  const sms = require('./sms');
7355ad895   Adhidarma Hadiwinoto   Network information
23
  const dbCops = require('./db-cops');
5ae543453   Adhidarma Hadiwinoto   Report via HTTP
24
  const reportSender = require('./report-sender');
e88bc6967   Adhidarma Hadiwinoto   Disable msisdn lo...
25
  // const msisdn = require('./msisdn');
a846e83f2   Adhidarma Hadiwinoto   register modem on...
26
  const registerModem = require('./register-modem');
737247043   Adhidarma Hadiwinoto   Disable message c...
27
  // const counters = require('./counters');
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
28

bc541e414   Adhidarma Hadiwinoto   modemInfo
29
  const modemInfo = {
209ea177a   Adhidarma Hadiwinoto   modemInfo.device
30
      device: config.modem.device,
c428dcf05   Adhidarma Hadiwinoto   More information ...
31
32
      manufacturer: null,
      model: null,
3ec3e9eb3   Adhidarma Hadiwinoto   HTTP command serv...
33
      imei: null,
bc541e414   Adhidarma Hadiwinoto   modemInfo
34
      imsi: null,
9ad3c8d30   Adhidarma Hadiwinoto   MSISDN db
35
      msisdn: null,
7355ad895   Adhidarma Hadiwinoto   Network information
36
37
38
      cops: null,
      networkId: null,
      networkName: null,
bc541e414   Adhidarma Hadiwinoto   modemInfo
39
      signalStrength: null,
5a00ec06f   Adhidarma Hadiwinoto   DEBUG signalStrength
40
41
      signalStrengthTs: null,
      signalStrengthTsReadable: null,
737247043   Adhidarma Hadiwinoto   Disable message c...
42
43
      // messageSentCounter: null,
      // messageReceivedCounter: null,
bc541e414   Adhidarma Hadiwinoto   modemInfo
44
  };
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
45

35ba3f574   Adhidarma Hadiwinoto   Proteksi kalo mod...
46
  let lastTs = new Date();
04b85c093   Adhidarma Hadiwinoto   Register modem be...
47
  let port;
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
48
49
  
  const parserReadLine = new ParserReadline();
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
50

2db546a87   Adhidarma Hadiwinoto   Regex parser
51
  const parserWaitForOK = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
52
53
54
  parserWaitForOK.on('data', () => {
      mutex.releaseLockWaitForCommand();
  });
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
55
56
57
58
59
60
61
62
63
  function writeToPort(data) {
      return new Promise((resolve) => {
          port.write(data, (err, bytesWritten) => {
              if (err) logger.warn(`ERROR: ${err.toString()}`);
              logger.verbose(`* OUT: ${data}`);
              resolve(bytesWritten);
          });
      });
  }
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
64
  async function readSMS(slot) {
2db546a87   Adhidarma Hadiwinoto   Regex parser
65
      const parserCMGR = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
66
      parserCMGR.on('data', (data) => {
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
67
          if (data) {
2db546a87   Adhidarma Hadiwinoto   Regex parser
68
              try {
343164ad5   Adhidarma Hadiwinoto   Repot modem info ...
69
                  reportSender.incomingSMS(sms.extract(data.toString().trim()), modemInfo);
2db546a87   Adhidarma Hadiwinoto   Regex parser
70
71
72
73
74
              } catch (e) {
                  logger.warn(`Exception on reporting new message. ${e.toString()}`, { smsObj: e.smsObj, dataFromModem: data });
  
                  process.exit(0);
              }
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
75
          }
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
76
77
78
          port.unpipe(parserCMGR);
          mutex.releaseLockWaitForCommand();
      });
2db546a87   Adhidarma Hadiwinoto   Regex parser
79
80
      // const parserCMGD = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK });
      const parserCMGD = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
81
82
83
      parserCMGD.on('data', () => {
          port.unpipe(parserCMGD);
          mutex.releaseLockWaitForCommand();
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
84
85
86
      });
  
      logger.info(`Reading SMS on slot ${slot}`);
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
87
88
89
90
      await mutex.setLockWaitForCommand();
      port.pipe(parserCMGR);
      await writeToPort(`AT+CMGR=${slot}\r`);
      logger.info(`Finished reading SMS on slot ${slot}`);
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
91
92
  
      logger.info(`Deleting message on slot ${slot}`);
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
93
94
95
      await mutex.setLockWaitForCommand();
      port.pipe(parserCMGD);
      await writeToPort(`AT+CMGD=${slot}\r`);
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
      logger.info('Message processing has completed');
  }
  
  function onIncomingSMS(data) {
      const value = common.extractValueFromReadLineData(data);
      if (!value) return;
  
      const chunks = value.split(',');
      if (!chunks && !chunks[1]) return;
  
      const slot = chunks[1];
  
      logger.info(`Incoming SMS on slot ${slot}`);
      readSMS(slot);
  }
7355ad895   Adhidarma Hadiwinoto   Network information
111
112
113
114
115
116
117
118
119
  function onCOPS(data) {
      modemInfo.cops = common.extractValueFromReadLineData(data).trim();
      logger.info(`Connected Network: ${modemInfo.cops}`);
  
      if (!modemInfo.cops) return;
  
      [, , modemInfo.networkId] = modemInfo.cops.split(',');
  
      if (modemInfo.networkId) {
e811898ae   Adhidarma Hadiwinoto   Bug-fix networkNa...
120
          modemInfo.networkName = dbCops[modemInfo.networkId] || modemInfo.networkId;
7355ad895   Adhidarma Hadiwinoto   Network information
121
122
      }
  }
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
123
124
125
  parserReadLine.on('data', (data) => {
      logger.verbose(`* IN: ${data}`);
      if (data) {
35ba3f574   Adhidarma Hadiwinoto   Proteksi kalo mod...
126
          lastTs = new Date();
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
127
          if (data.indexOf('+CSQ: ') === 0) {
5a00ec06f   Adhidarma Hadiwinoto   DEBUG signalStrength
128
129
130
131
132
133
              const signalStrength = common.extractValueFromReadLineData(data).trim();
              if (signalStrength) {
                  modemInfo.signalStrength = signalStrength;
                  modemInfo.signalStrengthTs = new Date();
                  modemInfo.signalStrengthTsReadable = moment(modemInfo.signalStrengthTs).format('YYYY-MM-DD HH:mm:ss');
                  logger.info(`Signal strength: ${modemInfo.signalStrength}`);
d416919cb   Adhidarma Hadiwinoto   re-register modem...
134
                  registerModem(modemInfo);
5a00ec06f   Adhidarma Hadiwinoto   DEBUG signalStrength
135
              }
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
136
          } else if (data.indexOf('+CMTI: ') === 0) {
737247043   Adhidarma Hadiwinoto   Disable message c...
137
              // counters.increment('MESSAGE_RECEIVED', modemInfo);
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
138
              onIncomingSMS(data);
7355ad895   Adhidarma Hadiwinoto   Network information
139
140
          } else if (data.indexOf('+COPS: ') === 0) {
              onCOPS(data);
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
141
142
143
          }
      }
  });
2db546a87   Adhidarma Hadiwinoto   Regex parser
144
145
  async function simpleSubCommand(cmd, callback) {
      const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
c428dcf05   Adhidarma Hadiwinoto   More information ...
146
147
      parser.on('data', (data) => {
          port.unpipe(parser);
2db546a87   Adhidarma Hadiwinoto   Regex parser
148
          mutex.releaseLockWaitForSubCommand();
c428dcf05   Adhidarma Hadiwinoto   More information ...
149
150
  
          if (data) {
2db546a87   Adhidarma Hadiwinoto   Regex parser
151
              if (callback) callback(null, data.toString().trim());
c428dcf05   Adhidarma Hadiwinoto   More information ...
152
153
          }
      });
2db546a87   Adhidarma Hadiwinoto   Regex parser
154
155
156
157
158
159
160
161
162
163
      return new Promise(async (resolve) => {
          await mutex.setLockWaitForSubCommand();
          port.pipe(parser);
          writeToPort(cmd);
  
          await mutex.setLockWaitForSubCommand();
          mutex.releaseLockWaitForSubCommand();
  
          resolve();
      });
c428dcf05   Adhidarma Hadiwinoto   More information ...
164
  }
c428dcf05   Adhidarma Hadiwinoto   More information ...
165
166
  function readManufacturer() {
      return new Promise((resolve) => {
2db546a87   Adhidarma Hadiwinoto   Regex parser
167
          simpleSubCommand('AT+CGMI\r', (err, result) => {
c428dcf05   Adhidarma Hadiwinoto   More information ...
168
169
170
171
172
173
174
175
176
              modemInfo.manufacturer = result;
              logger.info(`Manufacturer: ${result}`);
              resolve(result);
          });
      });
  }
  
  function readModel() {
      return new Promise((resolve) => {
2db546a87   Adhidarma Hadiwinoto   Regex parser
177
          simpleSubCommand('AT+CGMM\r', (err, result) => {
c428dcf05   Adhidarma Hadiwinoto   More information ...
178
179
180
181
182
183
184
185
186
              modemInfo.model = result;
              logger.info(`Model: ${result}`);
              resolve(result);
          });
      });
  }
  
  function readIMEI() {
      return new Promise((resolve) => {
2db546a87   Adhidarma Hadiwinoto   Regex parser
187
          simpleSubCommand('AT+CGSN\r', (err, result) => {
c428dcf05   Adhidarma Hadiwinoto   More information ...
188
189
190
191
192
193
194
195
196
              modemInfo.imei = result;
              logger.info(`IMEI: ${result}`);
              resolve(result);
          });
      });
  }
  
  function readIMSI() {
      return new Promise((resolve) => {
2db546a87   Adhidarma Hadiwinoto   Regex parser
197
          simpleSubCommand('AT+CIMI\r', (err, result) => {
c428dcf05   Adhidarma Hadiwinoto   More information ...
198
199
              modemInfo.imsi = result;
              logger.info(`IMSI: ${result}`);
9ad3c8d30   Adhidarma Hadiwinoto   MSISDN db
200
201
  
              if (result) {
e88bc6967   Adhidarma Hadiwinoto   Disable msisdn lo...
202
                  /*
9ad3c8d30   Adhidarma Hadiwinoto   MSISDN db
203
204
205
                  modemInfo.msisdn = msisdn[result];
                  if (modemInfo.msisdn) {
                      logger.info(`MSISDN: ${modemInfo.msisdn}`);
0c5ab3931   Adhidarma Hadiwinoto   Register modem ju...
206
                      registerModem(modemInfo);
9ad3c8d30   Adhidarma Hadiwinoto   MSISDN db
207
                  }
e88bc6967   Adhidarma Hadiwinoto   Disable msisdn lo...
208
                  */
5087dec58   Adhidarma Hadiwinoto   ESLINT
209
              } else {
18586efc2   Adhidarma Hadiwinoto   More detail on te...
210
                  logger.warn(`IMSI not detected. Please insert a sim card to your modem. Terminating  ${config.modem.device}.`);
24c0e1ac1   Adhidarma Hadiwinoto   Perbaikan deteksi...
211
212
                  process.exit(2);
              }
c428dcf05   Adhidarma Hadiwinoto   More information ...
213
214
215
216
              resolve(result);
          });
      });
  }
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
217

2db546a87   Adhidarma Hadiwinoto   Regex parser
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
  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);
          });
      });
  }
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
233
  async function querySignalStrength() {
2db546a87   Adhidarma Hadiwinoto   Regex parser
234
      const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
235
236
237
238
239
240
241
242
243
      parser.on('data', () => {
          port.unpipe(parser);
          mutex.releaseLockWaitForCommand();
      });
  
      if (mutex.tryLockWaitForCommand()) {
          port.pipe(parser);
          await writeToPort('AT+CSQ\r');
      }
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
244
  }
a8340480b   Adhidarma Hadiwinoto   registerModemToCe...
245
246
247
248
249
250
251
  function registerModemToCenterPeriodically() {
      registerModem(modemInfo);
  
      setInterval(() => {
          registerModem(modemInfo);
      }, 60 * 1000);
  }
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
252
253
  async function registerSignalStrengthBackgroundQuery() {
      logger.info('Registering background signal strength query');
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
254
      querySignalStrength();
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
255
256
      setInterval(() => {
          querySignalStrength();
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
257
      }, config.interval_beetwen_signal_strength_ms || INTERVAL_BEETWEN_SIGNAL_STRENGTH_MS);
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
258
259
260
  }
  
  async function sendSMS(destination, msg) {
3023245c4   Adhidarma Hadiwinoto   Pengamanan tambahan
261
      if (typeof destination !== 'string' || typeof msg !== 'string' || !destination.trim() || !msg.trim()) return;
2db546a87   Adhidarma Hadiwinoto   Regex parser
262
      const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
263
264
265
266
267
268
      parser.on('data', () => {
          port.unpipe(parser);
          mutex.releaseLockWaitForSubCommand();
      });
  
      logger.verbose('Waiting for command lock to send message');
cba7eef40   Adhidarma Hadiwinoto   Separate locks fu...
269
      await mutex.setLockWaitForCommand();
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
270

49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
271
      logger.info('Sending message', { destination, msg });
737247043   Adhidarma Hadiwinoto   Disable message c...
272
      // counters.increment('MESSAGE_SENT', modemInfo);
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
273
274
  
      const correctedDestination = `+${destination}`.replace(/^0/, '62').replace(/^\++/, '+');
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
275
276
277
278
279
280
281
282
      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);
e7c905091   Adhidarma Hadiwinoto   Perbaikan delimit...
283
      await writeToPort(`AT+CMGS="${correctedDestination}"\r${msg}${Buffer.from([0x1A])}`);
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
284
285
286
  
      await mutex.setLockWaitForSubCommand();
      mutex.releaseLockWaitForSubCommand();
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
287
288
  
      logger.info('Message has been sent');
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
289
290
291
      setTimeout(() => {
          logger.verbose('Releasing command lock');
          mutex.releaseLockWaitForCommand();
fceefa702   Adhidarma Hadiwinoto   config.wait_for_r...
292
      }, config.wait_for_release_lock_wait_for_command_ms || 2000);
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
293
  }
c5ce14d55   Adhidarma Hadiwinoto   Uji coba ussd
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
  /**
   * Ekseksusi kode USSD.
   *
   * @param  {string} cmd - Kode USSD
   */
  function executeUSSD(cmd) {
      return new Promise(async (resolve) => {
          const parser = new ParserRegex({ regex: REGEX_WAIT_FOR_OK_OR_ERROR });
          parser.on('data', (data) => {
              port.unpipe(parser);
              mutex.releaseLockWaitForSubCommand();
              resolve(data);
          });
  
          logger.verbose('Waiting for command lock to execute USSD');
          await mutex.setLockWaitForCommand();
  
          await mutex.setLockWaitForSubCommand();
          await writeToPort(`AT+CUSD=1,"${cmd.trim()}",15\r`);
  
          await mutex.setLockWaitForSubCommand();
          mutex.releaseLockWaitForSubCommand();
  
          mutex.releaseLockWaitForCommand();
      });
  }
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
320
321
  
  function init() {
04b85c093   Adhidarma Hadiwinoto   Register modem be...
322
323
324
325
326
      port = new SerialPort(config.modem.device, { baudRate: 115200 }, (err) => {
          if (err) {
              logger.warn(`Error opening modem. ${err}. Terminating modem ${config.modem.device}.`);
              process.exit(1);
          }
38b05d214   Adhidarma Hadiwinoto   Registrasi pertam...
327
328
  
          registerModem(modemInfo);
04b85c093   Adhidarma Hadiwinoto   Register modem be...
329
330
      });
      port.pipe(parserReadLine);
18586efc2   Adhidarma Hadiwinoto   More detail on te...
331
      setInterval(() => {
35ba3f574   Adhidarma Hadiwinoto   Proteksi kalo mod...
332
          if ((new Date() - lastTs) > MAX_LAST_DATA_AGE_MS) {
18586efc2   Adhidarma Hadiwinoto   More detail on te...
333
              logger.warn(`No data for more than ${MAX_LAST_DATA_AGE_MS} ms. Modem might be unresponsive. Terminating modem ${config.modem.device}.`);
35ba3f574   Adhidarma Hadiwinoto   Proteksi kalo mod...
334
335
336
              process.exit(0);
          }
      }, 30 * 1000);
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
337
      port.on('open', async () => {
2db546a87   Adhidarma Hadiwinoto   Regex parser
338
          await mutex.setLockWaitForCommand();
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
339
340
  
          logger.info('Modem opened');
2db546a87   Adhidarma Hadiwinoto   Regex parser
341
342
          await writeToPort('\r');
          await simpleSubCommand('AT\r');
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
343
344
  
          logger.info('Initializing modem to factory set');
2db546a87   Adhidarma Hadiwinoto   Regex parser
345
          await simpleSubCommand('AT&F\r');
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
346
347
  
          logger.info('Disabling echo');
2db546a87   Adhidarma Hadiwinoto   Regex parser
348
          await simpleSubCommand('ATE0\r');
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
349

c3fd6c7ff   Adhidarma Hadiwinoto   CMGF=1 saat init
350
351
          logger.info('Set to text mode');
          await simpleSubCommand('AT+CMGF=1\r');
2db546a87   Adhidarma Hadiwinoto   Regex parser
352
          await readCOPS();
7355ad895   Adhidarma Hadiwinoto   Network information
353

c428dcf05   Adhidarma Hadiwinoto   More information ...
354
355
356
          await readManufacturer();
          await readModel();
          await readIMEI();
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
357
          await readIMSI();
2253f95a7   Adhidarma Hadiwinoto   config.disable_de...
358
359
          if (!config.disable_delete_inbox_on_startup) {
              logger.info('Deleting existing messages');
2db546a87   Adhidarma Hadiwinoto   Regex parser
360
              await deleteInbox();
2253f95a7   Adhidarma Hadiwinoto   config.disable_de...
361
          }
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
362
          mutex.releaseLockWaitForCommand();
2db546a87   Adhidarma Hadiwinoto   Regex parser
363
          logger.verbose('Init completed');
0bdac2f9c   Adhidarma Hadiwinoto   Bersih kirim sms ...
364

a8340480b   Adhidarma Hadiwinoto   registerModemToCe...
365
          registerModemToCenterPeriodically();
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
366
          registerSignalStrengthBackgroundQuery();
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
367
368
369
370
      });
  }
  
  init();
bc541e414   Adhidarma Hadiwinoto   modemInfo
371
  exports.modemInfo = modemInfo;
49eaf19a3   Adhidarma Hadiwinoto   SMS is ok
372
  exports.sendSMS = sendSMS;
c5ce14d55   Adhidarma Hadiwinoto   Uji coba ussd
373
  exports.executeUSSD = executeUSSD;