Commit cba7eef40e86fe792e58fd54ad7a7412a7823c4a

Authored by Adhidarma Hadiwinoto
1 parent 67af4245ef
Exists in master

Separate locks functions to mutex module

Showing 2 changed files with 57 additions and 48 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 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 const locks = require('locks');
13 12
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 16
17 let imsi; 17 let imsi;
18 let signalStrength; 18 let signalStrength;
19 19
20 const mutexWaitForOK = locks.createMutex();
21 const mutexCommand = locks.createMutex();
22
23 function setLockWaitForOK() {
24 return new Promise((resolve) => {
25 mutexWaitForOK.lock(() => {
26 resolve(true);
27 });
28 });
29 }
30
31 function releaseLockWaitForOK() {
32 try {
33 mutexWaitForOK.unlock();
34 } catch (e) {
35 //
36 }
37 }
38
39 function setLockWaitForCommand() {
40 return new Promise((resolve) => {
41 mutexCommand.lock(() => {
42 resolve(true);
43 });
44 });
45 }
46
47 function releaseLockWaitForCommand() {
48 setTimeout(() => {
49 try {
50 mutexCommand.unlock();
51 } catch (e) {
52 //
53 }
54 }, 1500);
55 }
56
57 const port = new SerialPort(config.modem.device, { baudRate: 115200 }); 20 const port = new SerialPort(config.modem.device, { baudRate: 115200 });
58 21
59 const parserReadLine = new ParserReadline(); 22 const parserReadLine = new ParserReadline();
60 const parserWaitForOK = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); 23 const parserWaitForOK = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK });
61 port.pipe(parserReadLine); 24 port.pipe(parserReadLine);
62 25
63 function writeToPort(data) { 26 function writeToPort(data) {
64 return new Promise((resolve) => { 27 return new Promise((resolve) => {
65 port.write(data, (err, bytesWritten) => { 28 port.write(data, (err, bytesWritten) => {
66 if (err) logger.warn(`ERROR: ${err.toString()}`); 29 if (err) logger.warn(`ERROR: ${err.toString()}`);
67 logger.verbose(`* OUT: ${data}`); 30 logger.verbose(`* OUT: ${data}`);
68 resolve(bytesWritten); 31 resolve(bytesWritten);
69 }); 32 });
70 }); 33 });
71 } 34 }
72 35
73 async function writeToPortAndWaitForOK(data) { 36 async function writeToPortAndWaitForOK(data) {
74 await setLockWaitForOK(); 37 await mutex.setLockWaitForOK();
75 const result = await writeToPort(data); 38 const result = await writeToPort(data);
76 await setLockWaitForOK(); 39 await mutex.setLockWaitForOK();
77 releaseLockWaitForOK(); 40 mutex.releaseLockWaitForOK();
78 return result; 41 return result;
79 } 42 }
80 43
81 async function readSMS(slot) { 44 async function readSMS(slot) {
82 const parser = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); 45 const parser = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK });
83 parser.on('data', async (data) => { 46 parser.on('data', async (data) => {
84 if (data) { 47 if (data) {
85 const smsObject = sms.extract(data.toString().trim()); 48 const smsObject = sms.extract(data.toString().trim());
86 console.log('SMS', smsObject); // eslint-disable-line no-console 49 console.log('SMS', smsObject); // eslint-disable-line no-console
87 } 50 }
88 releaseLockWaitForOK(); 51 mutex.releaseLockWaitForOK();
89 }); 52 });
90 53
91 logger.info(`Reading SMS on slot ${slot}`); 54 logger.info(`Reading SMS on slot ${slot}`);
92 port.pipe(parser); 55 port.pipe(parser);
93 await writeToPortAndWaitForOK(`AT+CMGR=${slot}\r`); 56 await writeToPortAndWaitForOK(`AT+CMGR=${slot}\r`);
94 port.unpipe(parser); 57 port.unpipe(parser);
95 logger.verbose(`Finished reading SMS on slot ${slot}`); 58 logger.verbose(`Finished reading SMS on slot ${slot}`);
96 59
97 logger.info(`Deleting message on slot ${slot}`); 60 logger.info(`Deleting message on slot ${slot}`);
98 port.pipe(parserWaitForOK); 61 port.pipe(parserWaitForOK);
99 await writeToPortAndWaitForOK(`AT+CMGD=${slot}\r`); 62 await writeToPortAndWaitForOK(`AT+CMGD=${slot}\r`);
100 port.unpipe(parserWaitForOK); 63 port.unpipe(parserWaitForOK);
101 64
102 logger.info('Message processing has completed'); 65 logger.info('Message processing has completed');
103 } 66 }
104 67
105 function onIncomingSMS(data) { 68 function onIncomingSMS(data) {
106 const value = common.extractValueFromReadLineData(data); 69 const value = common.extractValueFromReadLineData(data);
107 if (!value) return; 70 if (!value) return;
108 71
109 const chunks = value.split(','); 72 const chunks = value.split(',');
110 if (!chunks && !chunks[1]) return; 73 if (!chunks && !chunks[1]) return;
111 74
112 const slot = chunks[1]; 75 const slot = chunks[1];
113 76
114 logger.info(`Incoming SMS on slot ${slot}`); 77 logger.info(`Incoming SMS on slot ${slot}`);
115 readSMS(slot); 78 readSMS(slot);
116 } 79 }
117 80
118 parserReadLine.on('data', (data) => { 81 parserReadLine.on('data', (data) => {
119 logger.verbose(`* IN: ${data}`); 82 logger.verbose(`* IN: ${data}`);
120 if (data) { 83 if (data) {
121 if (data.indexOf('+CSQ: ') === 0) { 84 if (data.indexOf('+CSQ: ') === 0) {
122 signalStrength = common.extractValueFromReadLineData(data); 85 signalStrength = common.extractValueFromReadLineData(data);
123 logger.info(`Signal strength: ${signalStrength}`); 86 logger.info(`Signal strength: ${signalStrength}`);
124 } else if (data.indexOf('+CMTI: ') === 0) { 87 } else if (data.indexOf('+CMTI: ') === 0) {
125 onIncomingSMS(data); 88 onIncomingSMS(data);
126 } 89 }
127 } 90 }
128 }); 91 });
129 92
130 parserWaitForOK.on('data', () => { 93 parserWaitForOK.on('data', () => {
131 releaseLockWaitForOK(); 94 mutex.releaseLockWaitForOK();
132 }); 95 });
133 96
134 async function readIMSI() { 97 async function readIMSI() {
135 logger.info('Querying IMSI'); 98 logger.info('Querying IMSI');
136 const parserReadIMSI = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK }); 99 const parserReadIMSI = new ParserDelimiter({ delimiter: DELIMITER_WAIT_FOR_OK });
137 parserReadIMSI.on('data', (data) => { 100 parserReadIMSI.on('data', (data) => {
138 if (data) { 101 if (data) {
139 imsi = data.toString().trim(); 102 imsi = data.toString().trim();
140 logger.info(`IMSI: ${imsi}`); 103 logger.info(`IMSI: ${imsi}`);
141 } 104 }
142 releaseLockWaitForOK(); 105 mutex.releaseLockWaitForOK();
143 }); 106 });
144 107
145 port.pipe(parserReadIMSI); 108 port.pipe(parserReadIMSI);
146 await writeToPortAndWaitForOK('AT+CIMI\r'); 109 await writeToPortAndWaitForOK('AT+CIMI\r');
147 await setLockWaitForOK(); 110 await mutex.setLockWaitForOK();
148 releaseLockWaitForOK(); 111 mutex.releaseLockWaitForOK();
149 port.unpipe(parserReadIMSI); 112 port.unpipe(parserReadIMSI);
150 } 113 }
151 114
152 async function querySignalStrength() { 115 async function querySignalStrength() {
153 port.pipe(parserWaitForOK); 116 port.pipe(parserWaitForOK);
154 await writeToPortAndWaitForOK('AT+CSQ\r'); 117 await writeToPortAndWaitForOK('AT+CSQ\r');
155 port.unpipe(parserWaitForOK); 118 port.unpipe(parserWaitForOK);
156 } 119 }
157 120
158 async function registerSignalStrengthBackgroundQuery() { 121 async function registerSignalStrengthBackgroundQuery() {
159 logger.info('Registering background signal strength query'); 122 logger.info('Registering background signal strength query');
160 123
161 setInterval(() => { 124 setInterval(() => {
162 querySignalStrength(); 125 querySignalStrength();
163 }, INTERVAL_BEETWEN_SIGNAL_STRENGTH_MS); 126 }, INTERVAL_BEETWEN_SIGNAL_STRENGTH_MS);
164 } 127 }
165 128
166 async function sendSMS(destination, msg) { 129 async function sendSMS(destination, msg) {
167 await setLockWaitForCommand(); 130 await mutex.setLockWaitForCommand();
168 logger.info('Sending message', { destination, msg }); 131 logger.info('Sending message', { destination, msg });
169 132
170 const correctedDestination = `+${destination}`.replace(/^0/, '62').replace(/^\++/, '+'); 133 const correctedDestination = `+${destination}`.replace(/^0/, '62').replace(/^\++/, '+');
171 134
172 port.pipe(parserWaitForOK); 135 port.pipe(parserWaitForOK);
173 await writeToPortAndWaitForOK('AT+CMGF=1\r'); 136 await writeToPortAndWaitForOK('AT+CMGF=1\r');
174 await writeToPortAndWaitForOK(`AT+CMGS="${correctedDestination}"\n${msg}${Buffer.from([0x1A])}`); 137 await writeToPortAndWaitForOK(`AT+CMGS="${correctedDestination}"\n${msg}${Buffer.from([0x1A])}`);
175 port.unpipe(parserWaitForOK); 138 port.unpipe(parserWaitForOK);
176 139
177 logger.info('Message has been sent'); 140 logger.info('Message has been sent');
178 141
179 releaseLockWaitForCommand(); 142 mutex.releaseLockWaitForCommand();
180 } 143 }
181 144
182 function init() { 145 function init() {
183 port.on('open', async () => { 146 port.on('open', async () => {
184 port.pipe(parserWaitForOK); 147 port.pipe(parserWaitForOK);
185 148
186 logger.info('Modem opened'); 149 logger.info('Modem opened');
187 await writeToPortAndWaitForOK('AT\r'); 150 await writeToPortAndWaitForOK('AT\r');
188 151
189 logger.info('Initializing modem to factory set'); 152 logger.info('Initializing modem to factory set');
190 await writeToPortAndWaitForOK('AT&F\r'); 153 await writeToPortAndWaitForOK('AT&F\r');
191 154
192 logger.info('Disabling echo'); 155 logger.info('Disabling echo');
193 await writeToPortAndWaitForOK('ATE0\r'); 156 await writeToPortAndWaitForOK('ATE0\r');
194 157
195 logger.info('Querying signal strength'); 158 logger.info('Querying signal strength');
196 await writeToPortAndWaitForOK('AT+CSQ\r'); 159 await writeToPortAndWaitForOK('AT+CSQ\r');
197 160
198 logger.info('Deleting existing messages'); 161 logger.info('Deleting existing messages');
199 // await writeToPortAndWaitForOK('AT+CMGD=0,4\r'); 162 // await writeToPortAndWaitForOK('AT+CMGD=0,4\r');
200 163
201 await readIMSI(); 164 await readIMSI();
202 165
203 port.unpipe(parserWaitForOK); 166 port.unpipe(parserWaitForOK);
204 167
205 registerSignalStrengthBackgroundQuery(); 168 registerSignalStrengthBackgroundQuery();
206 logger.verbose('Init completed'); 169 logger.verbose('Init completed');
207 }); 170 });
208 } 171 }
209 172
210 init(); 173 init();
211 174
212 exports.sendSMS = sendSMS; 175 exports.sendSMS = sendSMS;
File was created 1 'use strict';
2
3 const locks = require('locks');
4
5 const mutexWaitForOK = locks.createMutex();
6 const mutexCommand = locks.createMutex();
7
8 function setLockWaitForOK() {
9 return new Promise((resolve) => {
10 mutexWaitForOK.lock(() => {
11 resolve(true);
12 });
13 });
14 }
15
16 function releaseLockWaitForOK() {
17 try {
18 mutexWaitForOK.unlock();
19 } catch (e) {
20 //
21 }
22 }
23
24 function setLockWaitForCommand() {
25 return new Promise((resolve) => {
26 mutexCommand.lock(() => {
27 resolve(true);
28 });
29 });
30 }
31
32 function releaseLockWaitForCommand() {
33 setTimeout(() => {
34 try {
35 mutexCommand.unlock();
36 } catch (e) {
37 //
38 }
39 }, 1500);
40 }
41
42 exports.setLockWaitForOK = setLockWaitForOK;
43 exports.releaseLockWaitForOK = releaseLockWaitForOK;
44
45 exports.setLockWaitForCommand = setLockWaitForCommand;
46 exports.releaseLockWaitForCommand = releaseLockWaitForCommand;
47