Commit 37d0dbf8ab6b30b8e375ef7a1c6bab0888638536

Authored by Adhidarma Hadiwinoto
1 parent 1d6334a9bf
Exists in master

Tangkap CMS ERROR

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

lib/serialport-parsers.js
1 const PARSER_READLINE_DELIMITER = '\r\n'; 1 const PARSER_READLINE_DELIMITER = '\r\n';
2 const PARSER_WAIT_FOR_OK_OR_ERROR_REGEX = /\n(?:OK|ERROR)\r\n/; 2 const PARSER_WAIT_FOR_OK_OR_ERROR_REGEX = /\n(?:OK|ERROR)\r\n/;
3 3
4 const moment = require('moment'); 4 const moment = require('moment');
5 const nodePdu = require('node-pdu'); 5 const nodePdu = require('node-pdu');
6 // const pdu = require('pdu'); 6 // const pdu = require('pdu');
7 const ParserReadline = require('@serialport/parser-readline'); 7 const ParserReadline = require('@serialport/parser-readline');
8 const ParserRegex = require('@serialport/parser-regex'); 8 const ParserRegex = require('@serialport/parser-regex');
9 9
10 const logger = require('komodo-sdk/logger'); 10 const logger = require('komodo-sdk/logger');
11 11
12 const dbCops = require('./db-cops'); 12 const dbCops = require('./db-cops');
13 const modemInfo = require('./modem-info'); 13 const modemInfo = require('./modem-info');
14 14
15 let port; 15 let port;
16 16
17 exports.setPort = function setPort(val) { 17 exports.setPort = function setPort(val) {
18 logger.info('SERIALPORT-PARSERS: setting port'); 18 logger.info('SERIALPORT-PARSERS: setting port');
19 port = val; 19 port = val;
20 }; 20 };
21 21
22 exports.getPort = function getPort() { 22 exports.getPort = function getPort() {
23 return port; 23 return port;
24 }; 24 };
25 25
26 let ussdCallback = null; 26 let ussdCallback = null;
27 function setUssdCallback(cb) { 27 function setUssdCallback(cb) {
28 ussdCallback = cb; 28 ussdCallback = cb;
29 } 29 }
30 exports.setUssdCallback = setUssdCallback; 30 exports.setUssdCallback = setUssdCallback;
31 31
32 let smsSentCallback = null; 32 let smsSentCallback = null;
33 function setSmsSentCallback(cb) { 33 function setSmsSentCallback(cb) {
34 smsSentCallback = cb; 34 smsSentCallback = cb;
35 } 35 }
36 exports.setSmsSentCallback = setSmsSentCallback; 36 exports.setSmsSentCallback = setSmsSentCallback;
37 37
38 function isAlphaNumeric(str) { 38 function isAlphaNumeric(str) {
39 const len = str.length; 39 const len = str.length;
40 // eslint-disable-next-line no-plusplus 40 // eslint-disable-next-line no-plusplus
41 for (let i = 0; i < len; i++) { 41 for (let i = 0; i < len; i++) {
42 const code = str.charCodeAt(i); 42 const code = str.charCodeAt(i);
43 if (!(code > 47 && code < 58) // numeric (0-9) 43 if (!(code > 47 && code < 58) // numeric (0-9)
44 && !(code > 64 && code < 91) // upper alpha (A-Z) 44 && !(code > 64 && code < 91) // upper alpha (A-Z)
45 && !(code > 96 && code < 123)) { // lower alpha (a-z) 45 && !(code > 96 && code < 123)) { // lower alpha (a-z)
46 return false; 46 return false;
47 } 47 }
48 } 48 }
49 return true; 49 return true;
50 } 50 }
51 51
52 function parsePdu(_data) { 52 function parsePdu(_data) {
53 const data = _data && _data.toString().trim().toUpperCase(); 53 const data = _data && _data.toString().trim().toUpperCase();
54 54
55 if (!data) return null; 55 if (!data) return null;
56 if (!isAlphaNumeric(data)) return null; 56 if (!isAlphaNumeric(data)) return null;
57 57
58 try { 58 try {
59 const result = nodePdu.parse(data); 59 const result = nodePdu.parse(data);
60 return result; 60 return result;
61 } catch (e) { 61 } catch (e) {
62 return null; 62 return null;
63 } 63 }
64 } 64 }
65 65
66 function onCSQ(data) { 66 function onCSQ(data) {
67 const val = data.toString().trim().match(/\+CSQ:\s*(.*)/); 67 const val = data.toString().trim().match(/\+CSQ:\s*(.*)/);
68 if (!val || !val[1]) return null; 68 if (!val || !val[1]) return null;
69 69
70 const [, signalStrength] = val; 70 const [, signalStrength] = val;
71 71
72 logger.info('Signal quality extracted', { signalQuality: val[1] }); 72 logger.info('Signal quality extracted', { signalQuality: val[1] });
73 73
74 modemInfo.signalStrength = signalStrength; 74 modemInfo.signalStrength = signalStrength;
75 modemInfo.signalStrengthTs = new Date(); 75 modemInfo.signalStrengthTs = new Date();
76 modemInfo.signalStrengthTsReadable = moment(modemInfo.signalStrengthTs).format('YYYY-MM-DD HH:mm:ss'); 76 modemInfo.signalStrengthTsReadable = moment(modemInfo.signalStrengthTs).format('YYYY-MM-DD HH:mm:ss');
77 77
78 return signalStrength; 78 return signalStrength;
79 } 79 }
80 80
81 function onPduDeliver(data, parsedData) { 81 function onPduDeliver(data, parsedData) {
82 const from = parsedData.getAddress && parsedData.getAddress().getPhone 82 const from = parsedData.getAddress && parsedData.getAddress().getPhone
83 ? parsedData.getAddress().getPhone() : null; 83 ? parsedData.getAddress().getPhone() : null;
84 84
85 const msg = parsedData.getData && parsedData.getData().getData 85 const msg = parsedData.getData && parsedData.getData().getData
86 ? parsedData.getData().getData() : null; 86 ? parsedData.getData().getData() : null;
87 87
88 const ts = new Date(parsedData.getScts().getIsoString()); 88 const ts = new Date(parsedData.getScts().getIsoString());
89 89
90 logger.verbose('PDU processed', { ts, from, msg }); 90 logger.verbose('PDU processed', { ts, from, msg });
91 return { from, msg }; 91 return { from, msg };
92 } 92 }
93 93
94 function onCOPS(data) { 94 function onCOPS(data) {
95 const val = data.toString().trim().match(/\+COPS:\s*(.*)/); 95 const val = data.toString().trim().match(/\+COPS:\s*(.*)/);
96 if (!val || !val[1]) return null; 96 if (!val || !val[1]) return null;
97 97
98 const cops = val[1]; 98 const cops = val[1];
99 99
100 if (!cops) return null; 100 if (!cops) return null;
101 const [mode, format, networkId] = cops.split(','); 101 const [mode, format, networkId] = cops.split(',');
102 const networkName = networkId ? dbCops[networkId] || networkId : null; 102 const networkName = networkId ? dbCops[networkId] || networkId : null;
103 103
104 logger.info('COPS extracted', { 104 logger.info('COPS extracted', {
105 cops, mode, format, networkId, networkName, 105 cops, mode, format, networkId, networkName,
106 }); 106 });
107 107
108 modemInfo.cops = cops; 108 modemInfo.cops = cops;
109 modemInfo.networkId = networkId || null; 109 modemInfo.networkId = networkId || null;
110 modemInfo.networkName = networkName || null; 110 modemInfo.networkName = networkName || null;
111 111
112 return { 112 return {
113 cops, mode, format, networkId, networkName, 113 cops, mode, format, networkId, networkName,
114 }; 114 };
115 } 115 }
116 116
117 117
118 function isResultCodeIs(data, resultCode) { 118 function isResultCodeIs(data, resultCode) {
119 if (!data) return false; 119 if (!data) return false;
120 const cleanedData = (data.toString() || '').trim(); 120 const cleanedData = (data.toString() || '').trim();
121 if (!cleanedData) return false; 121 if (!cleanedData) return false;
122 122
123 if (resultCode.indexOf('+') !== 0) { 123 if (resultCode.indexOf('+') !== 0) {
124 // eslint-disable-next-line no-param-reassign 124 // eslint-disable-next-line no-param-reassign
125 resultCode = `+${resultCode}`; 125 resultCode = `+${resultCode}`;
126 } 126 }
127 127
128 if (resultCode.search(/:$/) < 0) { 128 if (resultCode.search(/:$/) < 0) {
129 // eslint-disable-next-line no-param-reassign 129 // eslint-disable-next-line no-param-reassign
130 resultCode += ':'; 130 resultCode += ':';
131 } 131 }
132 132
133 return cleanedData.indexOf(resultCode) === 0; 133 return cleanedData.indexOf(resultCode) === 0;
134 } 134 }
135 135
136 const parserReadline = new ParserReadline({ delimiter: PARSER_READLINE_DELIMITER }); 136 const parserReadline = new ParserReadline({ delimiter: PARSER_READLINE_DELIMITER });
137 parserReadline.on('data', (data) => { 137 parserReadline.on('data', (data) => {
138 modemInfo.lastReadTs = new Date(); 138 modemInfo.lastReadTs = new Date();
139 logger.verbose('INCOMING', { data: `${data.toString()}${PARSER_READLINE_DELIMITER}`, parser: 'parserReadLine' }); 139 logger.verbose('INCOMING', { data: `${data.toString()}${PARSER_READLINE_DELIMITER}`, parser: 'parserReadLine' });
140 140
141 if (!data) return; 141 if (!data) return;
142 142
143 const pduParsed = parsePdu(data); 143 const pduParsed = parsePdu(data);
144 if (pduParsed && pduParsed.constructor.name !== 'Deliver') { 144 if (pduParsed && pduParsed.constructor.name !== 'Deliver') {
145 const pduType = pduParsed.getType(); 145 const pduType = pduParsed.getType();
146 logger.warn('WARN-9DA32C41: Unknown PDU message type name. PLEASE REPORT IT TO DEVELOPER AT TEKTRANS', { typeName: pduParsed.constructor.name, pduType, data: data.toString().trim() }); 146 logger.warn('WARN-9DA32C41: Unknown PDU message type name. PLEASE REPORT IT TO DEVELOPER AT TEKTRANS', { typeName: pduParsed.constructor.name, pduType, data: data.toString().trim() });
147 } 147 }
148 148
149 if (pduParsed && pduParsed.constructor.name === 'Deliver' && pduParsed.getData().getSize()) { 149 if (pduParsed && pduParsed.constructor.name === 'Deliver' && pduParsed.getData().getSize()) {
150 const pduType = pduParsed.getType(); 150 const pduType = pduParsed.getType();
151 logger.verbose('Got a PDU SMS-DELIVER', { pduType }); 151 logger.verbose('Got a PDU SMS-DELIVER', { pduType });
152 onPduDeliver(data, pduParsed); 152 onPduDeliver(data, pduParsed);
153 } else if (isResultCodeIs(data, 'CSQ')) { 153 } else if (isResultCodeIs(data, 'CSQ')) {
154 logger.verbose('Got a signal quality report', { data: data.toString() }); 154 logger.verbose('Got a signal quality report', { data: data.toString() });
155 onCSQ(data); 155 onCSQ(data);
156 } else if (isResultCodeIs(data, 'COPS:')) { 156 } else if (isResultCodeIs(data, 'COPS:')) {
157 logger.verbose('Got a COPS report', { data: data.toString() }); 157 logger.verbose('Got a COPS report', { data: data.toString() });
158 onCOPS(data); 158 onCOPS(data);
159 } else if (isResultCodeIs(data, 'CMT')) { 159 } else if (isResultCodeIs(data, 'CMT')) {
160 logger.verbose('Got a new message report', { data: data.toString() }); 160 logger.verbose('Got a new message report', { data: data.toString() });
161 } else if (isResultCodeIs(data, 'CMTI')) { 161 } else if (isResultCodeIs(data, 'CMTI')) {
162 logger.verbose('Got a new message notification report', { data: data.toString() }); 162 logger.verbose('Got a new message notification report', { data: data.toString() });
163 } else if (isResultCodeIs(data, 'CUSD')) { 163 } else if (isResultCodeIs(data, 'CUSD')) {
164 logger.verbose('Got a USSD command response', { data: data.toString() }); 164 logger.verbose('Got a USSD command response', { data: data.toString() });
165 if (typeof ussdCallback === 'function') { 165 if (typeof ussdCallback === 'function') {
166 logger.verbose('Calling USSD callback'); 166 logger.verbose('Calling USSD callback');
167 ussdCallback(data.toString()); 167 ussdCallback(data.toString());
168 } else { 168 } else {
169 logger.verbose('Skip unwanted USSD response'); 169 logger.verbose('Skip unwanted USSD response');
170 } 170 }
171 } else if (isResultCodeIs(data, 'CMGS')) { 171 } else if (isResultCodeIs(data, 'CMGS')) {
172 logger.verbose('Got CMGS report', { data: data.toString() }); 172 logger.verbose('Got CMGS report', { data: data.toString() });
173 if (typeof smsSentCallback === 'function') smsSentCallback(data.toString()); 173 if (typeof smsSentCallback === 'function') smsSentCallback(data.toString());
174 } else if (isResultCodeIs(data, 'CMS ERROR')) {
175 logger.verbose('Got CMS ERROR report', { data: data.toString() });
176 if (typeof smsSentCallback === 'function') smsSentCallback(data.toString());
174 } 177 }
175 }); 178 });
176 179
177 const parserWaitForOkOrError = new ParserRegex({ regex: PARSER_WAIT_FOR_OK_OR_ERROR_REGEX }); 180 const parserWaitForOkOrError = new ParserRegex({ regex: PARSER_WAIT_FOR_OK_OR_ERROR_REGEX });
178 parserWaitForOkOrError.on('data', (data) => { 181 parserWaitForOkOrError.on('data', (data) => {
179 logger.verbose('INCOMING', { data: data.toString(), parser: 'parserWaitForOkOrError' }); 182 logger.verbose('INCOMING', { data: data.toString(), parser: 'parserWaitForOkOrError' });
180 }); 183 });
181 184
182 185
183 exports.PARSER_READLINE_DELIMITER = PARSER_READLINE_DELIMITER; 186 exports.PARSER_READLINE_DELIMITER = PARSER_READLINE_DELIMITER;
184 exports.PARSER_WAIT_FOR_OK_OR_ERROR_REGEX = PARSER_WAIT_FOR_OK_OR_ERROR_REGEX; 187 exports.PARSER_WAIT_FOR_OK_OR_ERROR_REGEX = PARSER_WAIT_FOR_OK_OR_ERROR_REGEX;
185 188
186 exports.parserReadline = parserReadline; 189 exports.parserReadline = parserReadline;
187 exports.parserWaitForOkOrError = parserWaitForOkOrError; 190 exports.parserWaitForOkOrError = parserWaitForOkOrError;
188 191