modem.js 6.62 KB
'use strict';

const SerialPort = require("serialport");
const Readline = require('@serialport/parser-readline');
const Delimiter = require('@serialport/parser-delimiter');
const config = require('./config.json');
const request = require('request');
const common = require('./common');
const qs = require('querystring');
const locks = require('locks');

var mutex = locks.createMutex();

//let portUse = process.argv[2];
//let modemName = process.argv[4];

//common.log("port use man !! "+portUse+" "+modemName);
let modemName = config.core.modem_name;

const serialPort = new SerialPort(config.core.usb_port, {
    baudRate: 115200
});
const parser = serialPort.pipe(new Readline());

function serialPortWrite(data) {
    return new Promise(function(resolve, reject) {
        serialPort.write(data, function() {
            resolve();
        })
    })
}

function setLock() {
    return new Promise(function(resolve) {
        mutex.lock(function() {
            resolve(true);
        })
    })    
}

function releaseLock() {
    mutex.unlock();
}

exports.startModem = async function(){
    let count = 1;
    let statusModem = "0K";
    let errorMessageModem= "";


    serialPort.on("open", async function () {
        //const serialPortWrite = util.promisify(serialPort.write);

        common.log('Serial communication open');
        //
        await serialPortWrite("ATE0\r");
        await serialPortWrite("AT+CNMI?\r");
        //await serialPortWrite("AT+CNMI=1,1,2,1,1");
        //await serialPortWrite("\r");
        await serialPortWrite('AT+CUSD=2\r');
        await serialPortWrite('AT+CUSD=1,"*888*4#",15\r');
        common.log('receive sms ON');
    });

    serialPort.on('error', function(err) {
        statusModem = "NOT OK";
        errorMessageModem = err.message;
        common.log('Error!: ', err.message);
        process.exit(1);
    });

    parser.on('data', function(data) {
        common.log("incoming data: " + data);
        let lastData = data.toString();
        if (lastData.match(/\+CMTI:/)){
            let numberPattern = /(\d+)/g;
            let slot = lastData.match(numberPattern);
            common.log("slot "+slot);
            common.log("ada message baru");
            readSmsAuto(serialPort, slot);
        } 
    });
}

async function readSmsAuto(serialPort, slot){

    await serialPortWrite("AT+CMGR="+slot);// read only slot 1
    await serialPortWrite('\r');

    const parserD = serialPort.pipe(new Delimiter({ delimiter: '\r\nOK\r\n' }));
    parserD.on('data',function(dataD){
        //common.log("incoming datad "+dataD);
        let lastData = dataD.toString();
        common.log("incoming datad "+lastData);
        if (lastData.match(/\+CMGR:/)){
            common.log("incoming SMS "+lastData);
            // try to parse dataD
            const lines = lastData.split(/\n/);
            common.log("lines1 "+lines[1]);
            common.log("lines2 "+lines[2]);
            const content = lines[1].split(',');
            common.log("content0 "+content[0]);
            common.log("content1 "+content[1]);
            common.log("content2 "+content[2]);
            common.log("content3 "+content[3]);
            common.log("content4 "+content[4]);
            let nomor = content[1].toString();
            nomor = nomor.replace(/"/g,'');
            nomor = nomor.replace(/\+/g,'');
            let pesan = lines[2].toString();
            common.log("nomor nya "+nomor);
            serialPort.unpipe(parserD);
            postIncomingMessage(nomor, pesan);
        }	
    });

    common.log("pesan slot "+slot+" sudah di baca");

    setTimeout(async function(){
        await serialPortWrite("AT+CMGD="+slot);
        await serialPortWrite("\r");
        common.log("delete pesan slot "+slot+" done!");
    }, 2000);
}

function postIncomingMessage(nomor, pesan){
    common.log("----------------------------post incoming message-------------------------");
    pesan = pesan.replace(/\s+$/, '');
    //let encodePesan = encodeURIComponent(pesan);
    let inboxUrl = config.core.url_post;//+"/inbox?";msg="+encodePesan+"&number="+nomor;
    common.log("url 2211; "+inboxUrl);
    let tryOptions = {
        url: inboxUrl,
        qs: {
            msg: pesan,
            number: nomor,
            modem: modemName
        }
    }

    //post to URL end Point
    request(tryOptions, function (error, response, body) {
        if (error) {
           common.log("error post! "+nomor+" msg; \""+pesan+"\" errornya; "+error.message);
        } else if (!error && response.statusCode == 200) {
           common.log("success post "+nomor+" msg; \""+pesan+"\" resp; "+body);
        }
    });
}

exports.sendingSMS = async function (message, phone_no) {
    await setLock();

    await serialPortWrite("AT+CMGF=1\r");
    
    const parserD = serialPort.pipe(new Delimiter({ delimiter: '\r\nOK\r\n' }));
    parserD.on('data',function(dataD) {
        common.log('MESSAGE SENT');
        serialPort.unpipe(parserD);
        setTimeout(() => {
            releaseLock();
        }, 2000)
    })
    
    common.log('number '+phone_no);
    await serialPortWrite(`AT+CMGS="${ phone_no }"\r${ message }`);
    common.log(message);
    await serialPortWrite(Buffer([0x1A]));
}

exports.sendingUSSD = function (msg, count){

    return new Promise(async resolve => {
        let respUssd = null;
        let new_respUssd;
        await serialPortWrite("AT+CUSD=1,\""+msg+"\"");
        await serialPortWrite('\r');

        const parserUSSD = serialPort.pipe(new Delimiter({ delimiter: '\",0'}));
        parserUSSD.on('data',function(dataUSSD){
            let lastData = dataUSSD.toString();
            common.log("incoming dataUSSD "+lastData);
            respUssd = lastData;
            serialPort.unpipe(parserUSSD);
        });

        let countDown = 10;
        let waiting = setInterval(async () => {
            countDown--;
            console.log("wait respUssd "+countDown);
            //if (respUssd || countDown < 2 ){
            if (respUssd){
                new_respUssd = respUssd.replace(/^[^ ]+\+CUSD:/, '\+CUSD:');
                //to close command if resp CUSD: 1
                if (new_respUssd.match(/^\+CUSD: 1,/)){
                    await serialPortWrite("AT+CUSD=2\r");
                }
                resolve(new_respUssd);
                clearInterval(waiting);
            } else if (!respUssd && countDown < 2){
                new_respUssd = "+CUSD: 4";
                resolve(new_respUssd);
                clearInterval(waiting);
            }
        },1000);
    });
}

async function deleteMessage(serialPort, slot){
    await serialPortWrite("AT+CMGD=" + slot);
    await serialPortWrite("\r");
    common.log("delete pesan slot "+slot+" done!");
}