Commit 9ad3c8d304bdba60eebc63809836e5629af59966

Authored by Adhidarma Hadiwinoto
1 parent 7e9e3a6b3b
Exists in master

MSISDN db

Showing 3 changed files with 18 additions and 0 deletions Inline Diff

1 /node_modules/ 1 /node_modules/
2 /config.json 2 /config.json
3 /tmp/ 3 /tmp/
4 /logs/ 4 /logs/
5 pid.txt 5 pid.txt
6 /db-msisdn.json
7 /db-msisdn.js
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 DELIMITER_WAIT_FOR_OK = '\nOK\r\n'; 4 const DELIMITER_WAIT_FOR_OK = '\nOK\r\n';
5 5
6 const SerialPort = require('serialport'); 6 const SerialPort = require('serialport');
7 const ParserReadline = require('@serialport/parser-readline'); 7 const ParserReadline = require('@serialport/parser-readline');
8 const ParserDelimiter = require('@serialport/parser-delimiter'); 8 const ParserDelimiter = require('@serialport/parser-delimiter');
9 9
10 const config = require('komodo-sdk/config'); 10 const config = require('komodo-sdk/config');
11 const logger = require('komodo-sdk/logger'); 11 const logger = require('komodo-sdk/logger');
12 12
13 const mutex = require('./mutex'); 13 const mutex = require('./mutex');
14 const common = require('./common'); 14 const common = require('./common');
15 const sms = require('./sms'); 15 const sms = require('./sms');
16 const dbCops = require('./db-cops'); 16 const dbCops = require('./db-cops');
17 const reportSender = require('./report-sender'); 17 const reportSender = require('./report-sender');
18 const msisdn = require('./msisdn');
18 19
19 const modemInfo = { 20 const modemInfo = {
20 manufacturer: null, 21 manufacturer: null,
21 model: null, 22 model: null,
22 imei: null, 23 imei: null,
23 imsi: null, 24 imsi: null,
25 msisdn: null,
24 cops: null, 26 cops: null,
25 networkId: null, 27 networkId: null,
26 networkName: null, 28 networkName: null,
27 signalStrength: null, 29 signalStrength: null,
28 config: config.modem, 30 config: config.modem,
29 }; 31 };
30 32
31 const port = new SerialPort(config.modem.device, { baudRate: 115200 }); 33 const port = new SerialPort(config.modem.device, { baudRate: 115200 });
32 34
33 const parserReadLine = new ParserReadline(); 35 const parserReadLine = new ParserReadline();
34 const parserWaitForOK = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); 36 const parserWaitForOK = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK });
35 port.pipe(parserReadLine); 37 port.pipe(parserReadLine);
36 38
37 function writeToPort(data) { 39 function writeToPort(data) {
38 return new Promise((resolve) => { 40 return new Promise((resolve) => {
39 port.write(data, (err, bytesWritten) => { 41 port.write(data, (err, bytesWritten) => {
40 if (err) logger.warn(`ERROR: ${err.toString()}`); 42 if (err) logger.warn(`ERROR: ${err.toString()}`);
41 logger.verbose(`* OUT: ${data}`); 43 logger.verbose(`* OUT: ${data}`);
42 resolve(bytesWritten); 44 resolve(bytesWritten);
43 }); 45 });
44 }); 46 });
45 } 47 }
46 48
47 async function writeToPortAndWaitForOK(data) { 49 async function writeToPortAndWaitForOK(data) {
48 await mutex.setLockWaitForOK(); 50 await mutex.setLockWaitForOK();
49 const result = await writeToPort(data); 51 const result = await writeToPort(data);
50 await mutex.setLockWaitForOK(); 52 await mutex.setLockWaitForOK();
51 mutex.releaseLockWaitForOK(); 53 mutex.releaseLockWaitForOK();
52 return result; 54 return result;
53 } 55 }
54 56
55 async function readSMS(slot) { 57 async function readSMS(slot) {
56 const parser = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); 58 const parser = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK });
57 parser.on('data', async (data) => { 59 parser.on('data', async (data) => {
58 if (data) { 60 if (data) {
59 reportSender.incomingSMS(sms.extract(data.toString().trim())); 61 reportSender.incomingSMS(sms.extract(data.toString().trim()));
60 } 62 }
61 mutex.releaseLockWaitForOK(); 63 mutex.releaseLockWaitForOK();
62 }); 64 });
63 65
64 logger.info(`Reading SMS on slot ${slot}`); 66 logger.info(`Reading SMS on slot ${slot}`);
65 port.pipe(parser); 67 port.pipe(parser);
66 await writeToPortAndWaitForOK(`AT+CMGR=${slot}\r`); 68 await writeToPortAndWaitForOK(`AT+CMGR=${slot}\r`);
67 port.unpipe(parser); 69 port.unpipe(parser);
68 logger.verbose(`Finished reading SMS on slot ${slot}`); 70 logger.verbose(`Finished reading SMS on slot ${slot}`);
69 71
70 logger.info(`Deleting message on slot ${slot}`); 72 logger.info(`Deleting message on slot ${slot}`);
71 port.pipe(parserWaitForOK); 73 port.pipe(parserWaitForOK);
72 await writeToPortAndWaitForOK(`AT+CMGD=${slot}\r`); 74 await writeToPortAndWaitForOK(`AT+CMGD=${slot}\r`);
73 port.unpipe(parserWaitForOK); 75 port.unpipe(parserWaitForOK);
74 76
75 logger.info('Message processing has completed'); 77 logger.info('Message processing has completed');
76 } 78 }
77 79
78 function onIncomingSMS(data) { 80 function onIncomingSMS(data) {
79 const value = common.extractValueFromReadLineData(data); 81 const value = common.extractValueFromReadLineData(data);
80 if (!value) return; 82 if (!value) return;
81 83
82 const chunks = value.split(','); 84 const chunks = value.split(',');
83 if (!chunks && !chunks[1]) return; 85 if (!chunks && !chunks[1]) return;
84 86
85 const slot = chunks[1]; 87 const slot = chunks[1];
86 88
87 logger.info(`Incoming SMS on slot ${slot}`); 89 logger.info(`Incoming SMS on slot ${slot}`);
88 readSMS(slot); 90 readSMS(slot);
89 } 91 }
90 92
91 function onCOPS(data) { 93 function onCOPS(data) {
92 modemInfo.cops = common.extractValueFromReadLineData(data).trim(); 94 modemInfo.cops = common.extractValueFromReadLineData(data).trim();
93 logger.info(`Connected Network: ${modemInfo.cops}`); 95 logger.info(`Connected Network: ${modemInfo.cops}`);
94 96
95 if (!modemInfo.cops) return; 97 if (!modemInfo.cops) return;
96 98
97 [, , modemInfo.networkId] = modemInfo.cops.split(','); 99 [, , modemInfo.networkId] = modemInfo.cops.split(',');
98 100
99 if (modemInfo.networkId) { 101 if (modemInfo.networkId) {
100 modemInfo.networkName = dbCops[modemInfo.networkId]; 102 modemInfo.networkName = dbCops[modemInfo.networkId];
101 } 103 }
102 } 104 }
103 105
104 parserReadLine.on('data', (data) => { 106 parserReadLine.on('data', (data) => {
105 logger.verbose(`* IN: ${data}`); 107 logger.verbose(`* IN: ${data}`);
106 if (data) { 108 if (data) {
107 if (data.indexOf('+CSQ: ') === 0) { 109 if (data.indexOf('+CSQ: ') === 0) {
108 modemInfo.signalStrength = common.extractValueFromReadLineData(data).trim(); 110 modemInfo.signalStrength = common.extractValueFromReadLineData(data).trim();
109 logger.info(`Signal strength: ${modemInfo.signalStrength}`); 111 logger.info(`Signal strength: ${modemInfo.signalStrength}`);
110 } else if (data.indexOf('+CMTI: ') === 0) { 112 } else if (data.indexOf('+CMTI: ') === 0) {
111 onIncomingSMS(data); 113 onIncomingSMS(data);
112 } else if (data.indexOf('+COPS: ') === 0) { 114 } else if (data.indexOf('+COPS: ') === 0) {
113 onCOPS(data); 115 onCOPS(data);
114 } 116 }
115 } 117 }
116 }); 118 });
117 119
118 parserWaitForOK.on('data', () => { 120 parserWaitForOK.on('data', () => {
119 mutex.releaseLockWaitForOK(); 121 mutex.releaseLockWaitForOK();
120 }); 122 });
121 123
122 function simpleCommand(cmd, callback) { 124 function simpleCommand(cmd, callback) {
123 const parser = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); 125 const parser = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK });
124 parser.on('data', (data) => { 126 parser.on('data', (data) => {
125 port.unpipe(parser); 127 port.unpipe(parser);
126 mutex.releaseLockWaitForOK(); 128 mutex.releaseLockWaitForOK();
127 129
128 if (data) { 130 if (data) {
129 callback(null, data.toString().trim()); 131 callback(null, data.toString().trim());
130 } 132 }
131 }); 133 });
132 134
133 port.pipe(parser); 135 port.pipe(parser);
134 writeToPortAndWaitForOK(cmd); 136 writeToPortAndWaitForOK(cmd);
135 } 137 }
136 138
137 function readManufacturer() { 139 function readManufacturer() {
138 return new Promise((resolve) => { 140 return new Promise((resolve) => {
139 simpleCommand('AT+CGMI\r', (err, result) => { 141 simpleCommand('AT+CGMI\r', (err, result) => {
140 modemInfo.manufacturer = result; 142 modemInfo.manufacturer = result;
141 logger.info(`Manufacturer: ${result}`); 143 logger.info(`Manufacturer: ${result}`);
142 resolve(result); 144 resolve(result);
143 }); 145 });
144 }); 146 });
145 } 147 }
146 148
147 function readModel() { 149 function readModel() {
148 return new Promise((resolve) => { 150 return new Promise((resolve) => {
149 simpleCommand('AT+CGMM\r', (err, result) => { 151 simpleCommand('AT+CGMM\r', (err, result) => {
150 modemInfo.model = result; 152 modemInfo.model = result;
151 logger.info(`Model: ${result}`); 153 logger.info(`Model: ${result}`);
152 resolve(result); 154 resolve(result);
153 }); 155 });
154 }); 156 });
155 } 157 }
156 158
157 function readIMEI() { 159 function readIMEI() {
158 return new Promise((resolve) => { 160 return new Promise((resolve) => {
159 simpleCommand('AT+CGSN\r', (err, result) => { 161 simpleCommand('AT+CGSN\r', (err, result) => {
160 modemInfo.imei = result; 162 modemInfo.imei = result;
161 logger.info(`IMEI: ${result}`); 163 logger.info(`IMEI: ${result}`);
162 resolve(result); 164 resolve(result);
163 }); 165 });
164 }); 166 });
165 } 167 }
166 168
167 function readIMSI() { 169 function readIMSI() {
168 return new Promise((resolve) => { 170 return new Promise((resolve) => {
169 simpleCommand('AT+CIMI\r', (err, result) => { 171 simpleCommand('AT+CIMI\r', (err, result) => {
170 modemInfo.imsi = result; 172 modemInfo.imsi = result;
171 logger.info(`IMSI: ${result}`); 173 logger.info(`IMSI: ${result}`);
174
175 if (result) {
176 modemInfo.msisdn = msisdn[result];
177 if (modemInfo.msisdn) {
178 logger.info(`MSISDN: ${modemInfo.msisdn}`);
179 }
180 }
172 resolve(result); 181 resolve(result);
173 }); 182 });
174 }); 183 });
175 } 184 }
176 185
177 async function querySignalStrength() { 186 async function querySignalStrength() {
178 port.pipe(parserWaitForOK); 187 port.pipe(parserWaitForOK);
179 await writeToPortAndWaitForOK('AT+CSQ\r'); 188 await writeToPortAndWaitForOK('AT+CSQ\r');
180 port.unpipe(parserWaitForOK); 189 port.unpipe(parserWaitForOK);
181 } 190 }
182 191
183 async function registerSignalStrengthBackgroundQuery() { 192 async function registerSignalStrengthBackgroundQuery() {
184 logger.info('Registering background signal strength query'); 193 logger.info('Registering background signal strength query');
185 194
186 setInterval(() => { 195 setInterval(() => {
187 querySignalStrength(); 196 querySignalStrength();
188 }, INTERVAL_BEETWEN_SIGNAL_STRENGTH_MS); 197 }, INTERVAL_BEETWEN_SIGNAL_STRENGTH_MS);
189 } 198 }
190 199
191 async function sendSMS(destination, msg) { 200 async function sendSMS(destination, msg) {
192 if (typeof destination !== 'string' || typeof msg !== 'string' || !destination.trim() || !msg.trim()) return; 201 if (typeof destination !== 'string' || typeof msg !== 'string' || !destination.trim() || !msg.trim()) return;
193 202
194 await mutex.setLockWaitForCommand(); 203 await mutex.setLockWaitForCommand();
195 logger.info('Sending message', { destination, msg }); 204 logger.info('Sending message', { destination, msg });
196 205
197 const correctedDestination = `+${destination}`.replace(/^0/, '62').replace(/^\++/, '+'); 206 const correctedDestination = `+${destination}`.replace(/^0/, '62').replace(/^\++/, '+');
198 207
199 port.pipe(parserWaitForOK); 208 port.pipe(parserWaitForOK);
200 await writeToPortAndWaitForOK('AT+CMGF=1\r'); 209 await writeToPortAndWaitForOK('AT+CMGF=1\r');
201 await writeToPortAndWaitForOK(`AT+CMGS="${correctedDestination}"\n${msg}${Buffer.from([0x1A])}`); 210 await writeToPortAndWaitForOK(`AT+CMGS="${correctedDestination}"\n${msg}${Buffer.from([0x1A])}`);
202 port.unpipe(parserWaitForOK); 211 port.unpipe(parserWaitForOK);
203 212
204 logger.info('Message has been sent'); 213 logger.info('Message has been sent');
205 214
206 mutex.releaseLockWaitForCommand(); 215 mutex.releaseLockWaitForCommand();
207 } 216 }
208 217
209 function init() { 218 function init() {
210 port.on('open', async () => { 219 port.on('open', async () => {
211 port.pipe(parserWaitForOK); 220 port.pipe(parserWaitForOK);
212 221
213 logger.info('Modem opened'); 222 logger.info('Modem opened');
214 await writeToPortAndWaitForOK('AT\r'); 223 await writeToPortAndWaitForOK('AT\r');
215 224
216 logger.info('Initializing modem to factory set'); 225 logger.info('Initializing modem to factory set');
217 await writeToPortAndWaitForOK('AT&F\r'); 226 await writeToPortAndWaitForOK('AT&F\r');
218 227
219 logger.info('Disabling echo'); 228 logger.info('Disabling echo');
220 await writeToPortAndWaitForOK('ATE0\r'); 229 await writeToPortAndWaitForOK('ATE0\r');
221 230
222 await writeToPortAndWaitForOK('AT+COPS?\r'); 231 await writeToPortAndWaitForOK('AT+COPS?\r');
223 232
224 logger.info('Querying signal strength'); 233 logger.info('Querying signal strength');
225 await writeToPortAndWaitForOK('AT+CSQ\r'); 234 await writeToPortAndWaitForOK('AT+CSQ\r');
226 235
227 await readManufacturer(); 236 await readManufacturer();
228 await readModel(); 237 await readModel();
229 await readIMEI(); 238 await readIMEI();
230 await readIMSI(); 239 await readIMSI();
231 240
232 if (!config.disable_delete_inbox_on_startup) { 241 if (!config.disable_delete_inbox_on_startup) {
233 logger.info('Deleting existing messages'); 242 logger.info('Deleting existing messages');
234 await writeToPortAndWaitForOK('AT+CMGD=0,4\r'); 243 await writeToPortAndWaitForOK('AT+CMGD=0,4\r');
235 } 244 }
236 245
237 port.unpipe(parserWaitForOK); 246 port.unpipe(parserWaitForOK);
238 247
239 registerSignalStrengthBackgroundQuery(); 248 registerSignalStrengthBackgroundQuery();
240 logger.verbose('Init completed'); 249 logger.verbose('Init completed');
241 }); 250 });
242 } 251 }
243 252
244 init(); 253 init();
245 254
246 exports.modemInfo = modemInfo; 255 exports.modemInfo = modemInfo;
247 exports.sendSMS = sendSMS; 256 exports.sendSMS = sendSMS;
248 257
File was created 1 'use strict';
2
3 const fs = require('fs');
4
5 const db = fs.existsSync('db-msisdn.json') || fs.existsSync('db-msisdn.js') ? require('../db-msisdn') : {};
6
7 module.exports = db;
8