Commit 7783fff1fce10bb14e2cc849a27ea5e550c14cfa

Authored by Adhidarma Hadiwinoto
1 parent 0fb8b9d58d
Exists in master

Fast IMEI, IMSI, and COPS

Showing 4 changed files with 89 additions and 29 deletions Side-by-side Diff

lib/smstools-modem-info.js
1   -/* eslint-disable no-console */
  1 +const fs = require('fs');
2 2  
3   -// const MAX_LINES_TO_READ = 100000;
  3 +const REGEX_IMSI = /AT\+CIMI: (\d+)/;
  4 +const REGEX_IMEI = /AT\+CGSN: (\d+)/;
  5 +const REGEX_COPS = /\+COPS: (.+) OK/;
4 6  
5   -const util = require('util');
  7 +function getMatchFromBuffer(buffer, pattern) {
  8 + if (!buffer) return null;
6 9  
7   -const exec = util.promisify(require('child_process').exec);
  10 + const content = typeof buffer === 'string' ? buffer : buffer.toString();
  11 + const matches = content.match(pattern);
  12 + return (matches && matches[1]) || null;
  13 +}
  14 +
  15 +exports.getIMSI = async (modemName, filenameTemplate) => {
  16 + const filename = (filenameTemplate || '').replace(/<MODEMNAME>/g, modemName);
  17 + if (!filename) return null;
8 18  
9   -async function getLastLineFromLog(keyword, modemName, logFileName) {
10   - let execResult;
11 19 try {
12   - // eslint-disable-next-line max-len
13   - // execResult = await exec(`tail -n${MAX_LINES_TO_READ} ${logFileName} |grep ${modemName}:|grep ${keyword}:|tail -n1`);
14   - execResult = await exec(`tac ${logFileName} |grep ${modemName}:|grep -m 1 ${keyword}:`);
  20 + const contentBuffer = await fs.promises.readFile(filename);
  21 + return getMatchFromBuffer(contentBuffer, REGEX_IMSI);
15 22 } catch (e) {
16   - console.error(`SMSTOOLS-MODEM-INFO: Got exception. ${e.toString()}`);
17 23 return null;
18 24 }
  25 +};
19 26  
20   - return (execResult && execResult.stdout) || null;
21   -}
  27 +exports.getIMEI = async (modemName, filenameTemplate) => {
  28 + const filename = (filenameTemplate || '').replace(/<MODEMNAME>/g, modemName);
  29 + if (!filename) return null;
  30 +
  31 + try {
  32 + const contentBuffer = await fs.promises.readFile(filename);
  33 + return getMatchFromBuffer(contentBuffer, REGEX_IMEI);
  34 + } catch (e) {
  35 + return null;
  36 + }
  37 +};
22 38  
23   -exports.getIMSI = async (modemName, logFileName) => {
24   - const lastLine = await getLastLineFromLog('IMSI', modemName, logFileName);
25   - if (!lastLine) return null;
  39 +exports.getCOPS = async (modemName, filenameTemplate) => {
  40 + const filename = (filenameTemplate || '').replace(/<MODEMNAME>/g, modemName);
  41 + if (!filename) return null;
26 42  
27   - const matches = lastLine.trim().match(/IMSI: (\d+)$/);
28   - return matches && matches[1];
  43 + try {
  44 + const contentBuffer = await fs.promises.readFile(filename);
  45 + return getMatchFromBuffer(contentBuffer, REGEX_COPS);
  46 + } catch (e) {
  47 + return null;
  48 + }
29 49 };
30 50  
31   -exports.getIMEI = async (modemName, logFileName) => {
32   - const lastLine = await getLastLineFromLog('IMEI', modemName, logFileName);
33   - if (!lastLine) return null;
  51 +exports.get = async (modemName, filenameTemplate) => {
  52 + const filename = (filenameTemplate || '').replace(/<MODEMNAME>/g, modemName);
  53 + if (!filename) return null;
  54 +
  55 + let buffer;
  56 + try {
  57 + buffer = await fs.promises.readFile(filename);
  58 + } catch (e) {
  59 + return null;
  60 + }
  61 +
  62 + if (!buffer) return null;
34 63  
35   - const matches = lastLine.trim().match(/IMEI: (\d+)$/);
36   - return matches && matches[1];
  64 + return {
  65 + imsi: getMatchFromBuffer(buffer, REGEX_IMSI),
  66 + imei: getMatchFromBuffer(buffer, REGEX_IMEI),
  67 + cops: getMatchFromBuffer(buffer, REGEX_COPS),
  68 + };
37 69 };
lib/smstools-status-parsed.js
... ... @@ -27,6 +27,11 @@ module.exports = async (statsFilename) =&gt; {
27 27 line,
28 28 });
29 29 } else {
  30 + const regularRunResultFile = config.smstools_regular_run_result_file || '/var/spool/sms/regular_run/<MODEMNAME>';
  31 +
  32 + // eslint-disable-next-line no-await-in-loop
  33 + const { imsi, imei, cops } = (await modemInfo.get(keyword, regularRunResultFile)) || {};
  34 +
30 35 lines.push({
31 36 keyword,
32 37 line,
... ... @@ -38,10 +43,9 @@ module.exports = async (statsFilename) =&gt; {
38 43 failed,
39 44 received,
40 45 signal,
41   - // eslint-disable-next-line no-await-in-loop
42   - imsi: await modemInfo.getIMSI(keyword, smstoolsLogfile),
43   - // eslint-disable-next-line no-await-in-loop
44   - imei: await modemInfo.getIMEI(keyword, smstoolsLogfile),
  46 + imsi,
  47 + imei,
  48 + cops,
45 49 });
46 50 }
47 51 }
test/data/regular_run_result_file/GSM1
... ... @@ -0,0 +1,4 @@
  1 +2019-12-02 12:27:50,5, GSM1: CMD: AT+CGSN: 351047887082374 OK
  2 +2019-12-02 12:27:51,5, GSM1: CMD: AT+CIMI: 510108325339393 OK
  3 +2019-12-02 12:27:51,5, GSM1: CMD: AT+COPS?: +COPS: 0,2,51010 OK
  4 +2019-12-02 12:27:51,5, GSM1: CMD: AT+CSQ: +CSQ: 30,0 OK
test/smstools-modem-info.js
1 1 /* global describe it */
2 2  
3   -require('should');
  3 +const should = require('should');
4 4 const modemInfo = require('../lib/smstools-modem-info');
5 5  
6 6 describe('#smstool-modem-info', () => {
7 7 describe('#getIMSI', () => {
8 8 it('should return correct result', async () => {
9   - (await modemInfo.getIMSI('GSM1', 'test/data/smsd.log')).should.equal('510107942023333');
  9 + (await modemInfo.getIMSI('GSM1', 'test/data/regular_run_result_file/<MODEMNAME>')).should.equal('510108325339393');
  10 + });
  11 +
  12 + it('should handle missing file', async () => {
  13 + should.not.exist(await modemInfo.getIMSI('GSM1', 'test/data/regular_run_result_file/<MODEMNAME>2', 'wrong file'));
  14 + should.not.exist(await modemInfo.getIMSI('GSM1', '/dev/null', '/dev/null'));
10 15 });
11 16 });
12 17  
13 18 describe('#getIMEI', () => {
14 19 it('should return correct result', async () => {
15   - (await modemInfo.getIMEI('GSM1', 'test/data/smsd.log')).should.equal('865794033258171');
  20 + (await modemInfo.getIMEI('GSM1', 'test/data/regular_run_result_file/<MODEMNAME>')).should.equal('351047887082374');
  21 + });
  22 + });
  23 +
  24 + describe('#getCOPS', () => {
  25 + it('should return correct result', async () => {
  26 + (await modemInfo.getCOPS('GSM1', 'test/data/regular_run_result_file/<MODEMNAME>')).should.equal('0,2,51010');
  27 + });
  28 + });
  29 +
  30 + describe('#get', () => {
  31 + it('should return correct result', async () => {
  32 + const { imsi, imei, cops } = await modemInfo.get('GSM1', 'test/data/regular_run_result_file/<MODEMNAME>');
  33 + imsi.should.equal('510108325339393');
  34 + imei.should.equal('351047887082374');
  35 + cops.should.equal('0,2,51010');
16 36 });
17 37 });
18 38 });