Dependency updates and new API for logging
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Larv IT AB
|
||||
Copyright (c) 2018 Larv IT AB
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -19,7 +19,7 @@ npm install larvitsmpp
|
||||
This will setup a client that connects to localhost, port 2775 without username or password and send a message.
|
||||
|
||||
```javascript
|
||||
var larvitsmpp = require('larvitsmpp');
|
||||
const larvitsmpp = require('larvitsmpp');
|
||||
|
||||
larvitsmpp.client(function(err, clientSession) {
|
||||
clientSession.sendSms({
|
||||
@@ -35,14 +35,20 @@ larvitsmpp.client(function(err, clientSession) {
|
||||
|
||||
### Some connection parameters and DLR
|
||||
|
||||
This will setup a client that connects to given host, port with username and password, send a password and retrieve a DLR.
|
||||
This will setup a client that connects to given host, port with username and password, send a password and retrieve a DLR and with a custom log driver, compatible with winston.
|
||||
|
||||
```javascript
|
||||
const larvitsmpp = require('larvitsmpp');
|
||||
const LUtils = require('larvitutils');
|
||||
const lUtils = new LUtils();
|
||||
const log = new lUtils.Log('debug');
|
||||
|
||||
larvitsmpp.client({
|
||||
'host': 'smpp.somewhere.com',
|
||||
'port': 2775,
|
||||
'username': 'foo',
|
||||
'password': 'bar'
|
||||
'password': 'bar',
|
||||
'log': log
|
||||
}, function(err, clientSession) {
|
||||
if (err) {
|
||||
throw err;
|
||||
@@ -82,7 +88,7 @@ larvitsmpp.client({
|
||||
This will setup a password less server on localhost, port 2775 and console.log() incomming commands.
|
||||
|
||||
```javascript
|
||||
var larvitsmpp = require('larvitsmpp');
|
||||
const larvitsmpp = require('larvitsmpp');
|
||||
|
||||
larvitsmpp.server(function(err, serverSession) {
|
||||
if (err) {
|
||||
@@ -95,23 +101,29 @@ larvitsmpp.server(function(err, serverSession) {
|
||||
});
|
||||
```
|
||||
|
||||
### With auth, returning smsId and DLR
|
||||
### With auth and custom logging, returning smsId and DLR
|
||||
|
||||
Example code below:
|
||||
|
||||
```javascript
|
||||
const larvitsmpp = require('larvitsmpp');
|
||||
const LUtils = require('larvitutils');
|
||||
const lUtils = new LUtils();
|
||||
const log = new lUtils.Log('debug');
|
||||
|
||||
// This should of course be replaced with your preferred auth system
|
||||
function checkuserpass(username, password, callback) {
|
||||
function checkuserpass(username, password, cb) {
|
||||
if (username === 'foo' && password === 'bar') {
|
||||
// The last parameter is just user meta data that will be attached to the session as "userData" and is optional
|
||||
callback(null, true, {'username': 'foo', 'userId': 123});
|
||||
cb(null, true, {'username': 'foo', 'userId': 123});
|
||||
} else {
|
||||
callback(null, false);
|
||||
cb(null, false);
|
||||
}
|
||||
}
|
||||
|
||||
larvitsmpp.server({
|
||||
'checkuserpass': checkuserpass
|
||||
'checkuserpass': checkuserpass,
|
||||
'log': log
|
||||
}, function(err, serverSession) {
|
||||
if (err) {
|
||||
throw err;
|
||||
|
||||
+16
-15
@@ -2,12 +2,12 @@
|
||||
|
||||
const topLogPrefix = 'larvitsmpp: lib/client.js: ',
|
||||
session = require(__dirname + '/session'),
|
||||
LUtils = require('larvitutils'),
|
||||
merge = require('utils-merge'),
|
||||
log = require('winston'),
|
||||
net = require('net'),
|
||||
tls = require('tls');
|
||||
|
||||
function login() {
|
||||
function login(options) {
|
||||
const logPrefix = topLogPrefix + 'login() - ',
|
||||
that = this;
|
||||
|
||||
@@ -26,11 +26,11 @@ function login() {
|
||||
if (err) return that.emit('loginFailed');
|
||||
|
||||
if (retPduObj.cmdStatus === 'ESME_ROK') {
|
||||
log.info(logPrefix + 'Successful login system_id: "' + loginPdu.params.system_id + '"');
|
||||
options.log.info(logPrefix + 'Successful login system_id: "' + loginPdu.params.system_id + '"');
|
||||
that.loggedIn = true;
|
||||
that.emit('loggedIn');
|
||||
} else {
|
||||
log.info(logPrefix + 'Login failed system_id: "' + loginPdu.params.system_id + '". Status msg: ' + retPduObj.cmdStatus);
|
||||
options.log.info(logPrefix + 'Login failed system_id: "' + loginPdu.params.system_id + '". Status msg: ' + retPduObj.cmdStatus);
|
||||
that.emit('loginFailed');
|
||||
}
|
||||
});
|
||||
@@ -40,7 +40,7 @@ function resetEnqLinkTimer() {
|
||||
const logPrefix = topLogPrefix + 'resetEnqLinkTimer() - ',
|
||||
that = this;
|
||||
|
||||
log.silly(logPrefix + 'Resetting the kill timer');
|
||||
that.log.silly(logPrefix + 'Resetting the kill timer');
|
||||
if (that.enqLinkTimer) {
|
||||
clearTimeout(that.enqLinkTimer);
|
||||
}
|
||||
@@ -61,27 +61,27 @@ function resetEnqLinkTimer() {
|
||||
* @return {object} (returnObj)
|
||||
*/
|
||||
function clientSession(sock, options) {
|
||||
const returnObj = session(sock),
|
||||
const returnObj = session({'sock': sock, 'log': options.log}),
|
||||
logPrefix = topLogPrefix + 'clientSession() - ';
|
||||
|
||||
returnObj.options = options;
|
||||
returnObj.login = login;
|
||||
returnObj.resetEnqLinkTimer = resetEnqLinkTimer;
|
||||
|
||||
returnObj.login();
|
||||
returnObj.resetEnqLinkTimer();
|
||||
returnObj.login({'log': options.log});
|
||||
returnObj.resetEnqLinkTimer({'log': options.log});
|
||||
|
||||
// Handle incoming Pdu Objects
|
||||
returnObj.on('incomingPduObj', function (pduObj) {
|
||||
// Call the appropriate handleCmd function
|
||||
|
||||
if (typeof returnObj.handleCmd[pduObj.cmdName] === 'function') {
|
||||
log.debug(logPrefix + 'returnObj.on(incomingPduObj) - Running cmd handling function returnObj.handleCmd.' + pduObj.cmdName + '()');
|
||||
options.log.debug(logPrefix + 'returnObj.on(incomingPduObj) - Running cmd handling function returnObj.handleCmd.' + pduObj.cmdName + '()');
|
||||
|
||||
returnObj.handleCmd[pduObj.cmdName](pduObj);
|
||||
} else {
|
||||
// No command handling function is registered, return error "invalid command"
|
||||
log.info(logPrefix + 'returnObj.on(incomingPduObj) - No handling function found for command: "' + pduObj.cmdName + '"');
|
||||
options.log.info(logPrefix + 'returnObj.on(incomingPduObj) - No handling function found for command: "' + pduObj.cmdName + '"');
|
||||
|
||||
returnObj.sendReturn(pduObj, 'ESME_RINVCMDID');
|
||||
}
|
||||
@@ -93,7 +93,7 @@ function clientSession(sock, options) {
|
||||
/**
|
||||
* Setup a client.
|
||||
*
|
||||
* @param {object} options - host, port, username, password, tls, enqLinkTiming
|
||||
* @param {object} options - host, port, username, password, tls, enqLinkTiming, log
|
||||
* @param {function} cb(err, session)
|
||||
*/
|
||||
function client(options, cb) {
|
||||
@@ -113,7 +113,8 @@ function client(options, cb) {
|
||||
'username': 'user',
|
||||
'password': 'pass',
|
||||
'tls': false,
|
||||
'enqLinkTiming': 20000 // 20 sec
|
||||
'enqLinkTiming': 20000, // 20 sec
|
||||
'log': new (new LUtils()).Log()
|
||||
}, options || {});
|
||||
|
||||
if (options && options.tls && options.tls === true) {
|
||||
@@ -122,11 +123,11 @@ function client(options, cb) {
|
||||
sock = new net.Socket();
|
||||
}
|
||||
|
||||
log.debug(logPrefix + 'Connecting to ' + options.host + ':' + options.port);
|
||||
options.log.debug(logPrefix + 'Connecting to ' + options.host + ':' + options.port);
|
||||
sock.connect(options, function () {
|
||||
const session = clientSession(sock, options);
|
||||
|
||||
log.info(logPrefix + 'Connected to ' + sock.remoteAddress + ':' + sock.remotePort);
|
||||
options.log.info(logPrefix + 'Connected to ' + sock.remoteAddress + ':' + sock.remotePort);
|
||||
|
||||
session.on('loggedIn', function () {
|
||||
cb(null, session);
|
||||
@@ -134,7 +135,7 @@ function client(options, cb) {
|
||||
|
||||
session.on('loginFailed', function () {
|
||||
const err = new Error('Remote host refused login.');
|
||||
log.warn(logPrefix + err.message);
|
||||
options.log.warn(logPrefix + err.message);
|
||||
cb(err);
|
||||
});
|
||||
});
|
||||
|
||||
+3
-1
@@ -15,7 +15,9 @@ const topLogPrefix = 'larvitsmpp: lib/defs.js: ',
|
||||
tlvs = {},
|
||||
cmds = {},
|
||||
iconv = require('iconv-lite'),
|
||||
log = require('winston');
|
||||
LUtils = require('larvitutils'),
|
||||
lUtils = new LUtils(),
|
||||
log = new lUtils.Log('error');
|
||||
|
||||
consts.REGISTERED_DELIVERY = {
|
||||
'FINAL': 0x01,
|
||||
|
||||
+19
-16
@@ -3,8 +3,9 @@
|
||||
const topLogPrefix = 'larvitsmpp: lib/server.js: ',
|
||||
smppUtils = require(__dirname + '/utils'),
|
||||
session = require(__dirname + '/session'),
|
||||
LUtils = require('larvitutils'),
|
||||
lUtils = new LUtils(),
|
||||
merge = require('utils-merge'),
|
||||
log = require('winston'),
|
||||
net = require('net'),
|
||||
tls = require('tls');
|
||||
|
||||
@@ -17,14 +18,14 @@ function login(pduObj) {
|
||||
const logPrefix = topLogPrefix + 'login() - ',
|
||||
that = this;
|
||||
|
||||
log.debug(logPrefix + 'Data received and session is not loggedIn');
|
||||
that.log.debug(logPrefix + 'Data received and session is not loggedIn');
|
||||
|
||||
// Pause socket so we do not receive any other commands until we have processed the login
|
||||
that.sock.pause();
|
||||
|
||||
// Only bind_* is accepted when the client is not logged in
|
||||
if (pduObj.cmdName !== 'bind_transceiver' && pduObj.cmdName !== 'bind_receiver' && pduObj.cmdName !== 'bind_transmitter') {
|
||||
log.debug(logPrefix + 'Session is not loggedIn and no bind_* command is given. Return error "ESME_RINVBNDSTS');
|
||||
that.log.debug(logPrefix + 'Session is not loggedIn and no bind_* command is given. Return error "ESME_RINVBNDSTS');
|
||||
|
||||
smppUtils.pduReturn(pduObj, 'ESME_RINVBNDSTS', function (err, retPdu) {
|
||||
if (err) return that.closeSocket();
|
||||
@@ -42,13 +43,13 @@ function login(pduObj) {
|
||||
if (err) return that.closeSocket();
|
||||
|
||||
if ( ! res) {
|
||||
log.info(logPrefix + 'Login failed! Connected host: ' + that.sock.remoteAddress + ':' + that.sock.remotePort + ' system_id: "' + pduObj.params.system_id + '"');
|
||||
that.log.info(logPrefix + 'Login failed! Connected host: ' + that.sock.remoteAddress + ':' + that.sock.remotePort + ' system_id: "' + pduObj.params.system_id + '"');
|
||||
|
||||
that.sock.resume();
|
||||
return that.sendReturn(pduObj, 'ESME_RBINDFAIL');
|
||||
}
|
||||
|
||||
log.verbose(logPrefix + 'Login successful! Connected host: ' + that.sock.remoteAddress + ':' + that.sock.remotePort + ' system_id: "' + pduObj.params.system_id + '"');
|
||||
that.log.verbose(logPrefix + 'Login successful! Connected host: ' + that.sock.remoteAddress + ':' + that.sock.remotePort + ' system_id: "' + pduObj.params.system_id + '"');
|
||||
that.loggedIn = true;
|
||||
|
||||
// Set additional user data to the session
|
||||
@@ -77,13 +78,13 @@ function resetEnqLinkTimer() {
|
||||
const logPrefix = topLogPrefix + 'resetEnqLinkTimer() - ',
|
||||
that = this;
|
||||
|
||||
log.silly(logPrefix + 'Resetting the kill timer');
|
||||
that.log.silly(logPrefix + 'Resetting the kill timer');
|
||||
if (that.enqLinkTimer) {
|
||||
clearTimeout(that.enqLinkTimer);
|
||||
}
|
||||
|
||||
that.enqLinkTimer = setTimeout(function () {
|
||||
log.info(logPrefix + 'Closing session from ' + that.sock.remoteAddress + ':' + that.sock.remotePort + ' due to timeout');
|
||||
that.log.info(logPrefix + 'Closing session from ' + that.sock.remoteAddress + ':' + that.sock.remotePort + ' due to timeout');
|
||||
that.closeSocket();
|
||||
}, that.options.timeout);
|
||||
}
|
||||
@@ -96,11 +97,12 @@ function resetEnqLinkTimer() {
|
||||
* @return {object} (returnObj)
|
||||
*/
|
||||
function serverSession(sock, options) {
|
||||
const returnObj = session(sock);
|
||||
const returnObj = session({'sock': sock, 'log': options.log});
|
||||
|
||||
returnObj.options = options;
|
||||
returnObj.login = login;
|
||||
returnObj.resetEnqLinkTimer = resetEnqLinkTimer;
|
||||
returnObj.log = options.log;
|
||||
|
||||
returnObj.resetEnqLinkTimer();
|
||||
|
||||
@@ -115,18 +117,18 @@ function serverSession(sock, options) {
|
||||
|
||||
// If client is not logged in, always run the login function
|
||||
} else if (returnObj.loggedIn === false) {
|
||||
log.debug(logPrefix + ' Not logged in, running login function');
|
||||
options.log.debug(logPrefix + ' Not logged in, running login function');
|
||||
returnObj.login(pduObj);
|
||||
|
||||
// Client is logged in, try to match a handling function
|
||||
} else if (typeof returnObj.handleCmd[pduObj.cmdName] === 'function') {
|
||||
log.debug(logPrefix + 'Running cmd handling function returnObj.handleCmd.' + pduObj.cmdName + '()');
|
||||
options.log.debug(logPrefix + 'Running cmd handling function returnObj.handleCmd.' + pduObj.cmdName + '()');
|
||||
|
||||
returnObj.handleCmd[pduObj.cmdName](pduObj);
|
||||
|
||||
// No command handling function is registered, return error "invalid command"
|
||||
} else {
|
||||
log.info(logPrefix + 'No handling function found for command: "' + pduObj.cmdName + '"');
|
||||
options.log.info(logPrefix + 'No handling function found for command: "' + pduObj.cmdName + '"');
|
||||
|
||||
returnObj.sendReturn(pduObj, 'ESME_RINVCMDID');
|
||||
}
|
||||
@@ -138,7 +140,7 @@ function serverSession(sock, options) {
|
||||
/**
|
||||
* Setup a server
|
||||
*
|
||||
* @param {object} options - host, port, checkuserpass() etc (OPTIONAL)
|
||||
* @param {object} options - host, port, checkuserpass() etc (OPTIONAL), log
|
||||
* @param {function} cb(err, session)
|
||||
*/
|
||||
function server(options, cb) {
|
||||
@@ -155,7 +157,8 @@ function server(options, cb) {
|
||||
options = merge({
|
||||
'port': 2775,
|
||||
'tls': false,
|
||||
'timeout': 40000 // 40 sec
|
||||
'timeout': 40000, // 40 sec
|
||||
'log': new lUtils.Log()
|
||||
}, options || {});
|
||||
|
||||
if (options && options.tls && options.tls === true) {
|
||||
@@ -171,15 +174,15 @@ function server(options, cb) {
|
||||
const returnObj = serverSession(sock, options);
|
||||
|
||||
// We have a connection - a socket object is assigned to the connection automatically
|
||||
log.verbose(logPrefix + 'Incoming connection! From: ' + sock.remoteAddress + ':' + sock.remotePort);
|
||||
options.log.verbose(logPrefix + 'Incoming connection! From: ' + sock.remoteAddress + ':' + sock.remotePort);
|
||||
|
||||
cb(null, returnObj);
|
||||
}).listen(options.port, options.host);
|
||||
|
||||
if (options.host !== undefined) {
|
||||
log.info(logPrefix + 'Up and listening at ' + options.host + ':' + options.port);
|
||||
options.log.info(logPrefix + 'Up and listening at ' + options.host + ':' + options.port);
|
||||
} else {
|
||||
log.info(logPrefix + 'Up and listening at *:' + options.port);
|
||||
options.log.info(logPrefix + 'Up and listening at *:' + options.port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+76
-64
@@ -1,13 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
const topLogPrefix = 'larvitsmpp: lib/session.js: ',
|
||||
LUtils = require('larvitutils'),
|
||||
lUtils = new LUtils(),
|
||||
events = require('events'),
|
||||
moment = require('moment'),
|
||||
utils = require('./utils'),
|
||||
async = require('async'),
|
||||
defs = require('./defs'),
|
||||
uuid = require('uuid/v1'),
|
||||
log = require('winston');
|
||||
uuid = require('uuid/v1');
|
||||
|
||||
/**
|
||||
* Send a response to an sms
|
||||
@@ -48,7 +49,7 @@ function smsResp(status, cb) {
|
||||
|
||||
if (sms.pduObjs === undefined) {
|
||||
const err = new Error('No pdu objects found to base return PDU upon');
|
||||
log.warn(logPrefix + err.message);
|
||||
sms.log.warn(logPrefix + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
@@ -90,14 +91,15 @@ function incOurSeqNr() {
|
||||
* Always use this function to close the socket so we get it on log
|
||||
*/
|
||||
function closeSocket() {
|
||||
const logPrefix = topLogPrefix + 'closeSocket() - ';
|
||||
const logPrefix = topLogPrefix + 'closeSocket() - ',
|
||||
that = this;
|
||||
|
||||
log.verbose(logPrefix + 'Closing socket for ' + this.sock.remoteAddress + ':' + this.sock.remotePort);
|
||||
if (this.enqLinkTimer) {
|
||||
log.debug(logPrefix + 'enqLinkTimer found, clearing.');
|
||||
clearTimeout(this.enqLinkTimer);
|
||||
that.log.verbose(logPrefix + 'Closing socket for ' + this.sock.remoteAddress + ':' + this.sock.remotePort);
|
||||
if (that.enqLinkTimer) {
|
||||
that.log.debug(logPrefix + 'enqLinkTimer found, clearing.');
|
||||
clearTimeout(that.enqLinkTimer);
|
||||
}
|
||||
this.sock.destroy();
|
||||
that.sock.destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,7 +115,7 @@ function sockWrite(pdu, closeAfterSend) {
|
||||
if ( ! Buffer.isBuffer(pdu)) {
|
||||
utils.objToPdu(pdu, function (err, buffer) {
|
||||
if (err) {
|
||||
log.warn(logPrefix + 'Could not convert PDU to buffer');
|
||||
that.log.warn(logPrefix + 'Could not convert PDU to buffer');
|
||||
return that.closeSocket();
|
||||
}
|
||||
|
||||
@@ -123,9 +125,9 @@ function sockWrite(pdu, closeAfterSend) {
|
||||
}
|
||||
|
||||
try {
|
||||
log.verbose(logPrefix + 'sending PDU. SeqNr: ' + pdu.readUInt32BE(12) + ' cmd: ' + defs.cmdsById[pdu.readUInt32BE(4)].command + ' cmdStatus: ' + defs.errorsById[parseInt(pdu.readUInt32BE(8))] + ' hex: ' + pdu.toString('hex'));
|
||||
that.log.verbose(logPrefix + 'sending PDU. SeqNr: ' + pdu.readUInt32BE(12) + ' cmd: ' + defs.cmdsById[pdu.readUInt32BE(4)].command + ' cmdStatus: ' + defs.errorsById[parseInt(pdu.readUInt32BE(8))] + ' hex: ' + pdu.toString('hex'));
|
||||
} catch (err) {
|
||||
log.error(logPrefix + 'PDU buffer is invalid. Buffer hex: "' + pdu.toString('hex') + '"');
|
||||
that.log.error(logPrefix + 'PDU buffer is invalid. Buffer hex: "' + pdu.toString('hex') + '"');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -161,7 +163,7 @@ function send(pdu, closeAfterSend, cb) {
|
||||
// Make sure the sequence number is set and is correct
|
||||
pduObj.seqNr = this.ourSeqNr;
|
||||
|
||||
log.debug(logPrefix + 'Sending PDU to remote. pduObj: ' + JSON.stringify(pduObj));
|
||||
that.log.debug(logPrefix + 'Sending PDU to remote. pduObj: ' + JSON.stringify(pduObj));
|
||||
|
||||
// If closeAndSend is omitted, put cb in its place
|
||||
if (typeof closeAfterSend === 'function') {
|
||||
@@ -177,13 +179,13 @@ function send(pdu, closeAfterSend, cb) {
|
||||
// Response PDUs are not allowed with the send() command, they should use the sendReturn()
|
||||
if (pduObj.cmdName.substring(pduObj.cmdName - 5) === '_resp') {
|
||||
const err = new Error('Given pduObj is a response, use sendReturn() instead. cmdName: ' + pduObj.cmdName);
|
||||
log.verbose(logPrefix + err.message);
|
||||
that.log.verbose(logPrefix + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
// When the return is fetched, call the cb
|
||||
that.on('incomingPduObj' + pduObj.seqNr, function (incPduObj) {
|
||||
log.debug(logPrefix + 'this.on(incomingPduObj) - cmdName: ' + incPduObj.cmdName + ' seqNr: ' + incPduObj.seqNr + ' cmdStatus: ' + incPduObj.cmdStatus);
|
||||
that.log.debug(logPrefix + 'this.on(incomingPduObj) - cmdName: ' + incPduObj.cmdName + ' seqNr: ' + incPduObj.seqNr + ' cmdStatus: ' + incPduObj.cmdStatus);
|
||||
|
||||
// Make sure this is the actual response to the sent PDU
|
||||
if (incPduObj.isResp() && incPduObj.seqNr === pduObj.seqNr) {
|
||||
@@ -194,7 +196,7 @@ function send(pdu, closeAfterSend, cb) {
|
||||
}
|
||||
} else {
|
||||
const err = new Error('Event triggered but incoming PDU is not a response or seqNr does not match. isResp: ' + incPduObj.isResp().toString() + ' incSeqNr: ' + incPduObj.seqNr + ' expected seqNr: ' + pduObj.seqNr);
|
||||
log.warn(logPrefix + 'this.on(incomingPduObj) - ' + err.message);
|
||||
that.log.warn(logPrefix + 'this.on(incomingPduObj) - ' + err.message);
|
||||
cb(err);
|
||||
}
|
||||
});
|
||||
@@ -219,7 +221,7 @@ function sendReturn(pdu, status, params, closeAfterSend, cb) {
|
||||
const logPrefix = topLogPrefix + 'sendReturn() - ',
|
||||
that = this;
|
||||
|
||||
log.silly(logPrefix + 'ran');
|
||||
that.log.silly(logPrefix + 'ran');
|
||||
|
||||
if (typeof params === 'function') {
|
||||
cb = params;
|
||||
@@ -238,13 +240,13 @@ function sendReturn(pdu, status, params, closeAfterSend, cb) {
|
||||
|
||||
utils.pduReturn(pdu, status, params, function (err, retPdu) {
|
||||
if (err) {
|
||||
log.error(logPrefix + 'Could not create return PDU: ' + err.message);
|
||||
that.log.error(logPrefix + 'Could not create return PDU: ' + err.message);
|
||||
that.closeSocket();
|
||||
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
log.silly(logPrefix + 'Sending return PDU: ' + retPdu.toString('hex'));
|
||||
that.log.silly(logPrefix + 'Sending return PDU: ' + retPdu.toString('hex'));
|
||||
that.sockWrite(retPdu, closeAfterSend);
|
||||
cb(null, retPdu);
|
||||
});
|
||||
@@ -264,7 +266,8 @@ function sendReturn(pdu, status, params, closeAfterSend, cb) {
|
||||
*/
|
||||
function sendSms(smsOptions, cb) {
|
||||
const logPrefix = topLogPrefix + 'sendSms() - ',
|
||||
pduObj = {};
|
||||
pduObj = {},
|
||||
that = this;
|
||||
|
||||
pduObj.cmdName = 'submit_sm';
|
||||
pduObj.params = {
|
||||
@@ -276,7 +279,7 @@ function sendSms(smsOptions, cb) {
|
||||
|
||||
// Flash messages overrides default data_coding
|
||||
if (smsOptions.flash) {
|
||||
log.debug(logPrefix + 'Flash SMS detected, set data_coding to 0x10!');
|
||||
that.log.debug(logPrefix + 'Flash SMS detected, set data_coding to 0x10!');
|
||||
pduObj.params.data_coding = 0x10;
|
||||
}
|
||||
|
||||
@@ -287,16 +290,16 @@ function sendSms(smsOptions, cb) {
|
||||
|
||||
// Check if we must split this message into multiple
|
||||
if (utils.bitCount(smsOptions.message) > 1120) {
|
||||
log.debug(logPrefix + 'Message larger than 1120 bits, send it as long message!');
|
||||
that.log.debug(logPrefix + 'Message larger than 1120 bits, send it as long message!');
|
||||
|
||||
this.sendLongSms(smsOptions, cb);
|
||||
that.sendLongSms(smsOptions, cb);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug(logPrefix + 'pduObj: ' + JSON.stringify(pduObj));
|
||||
that.log.debug(logPrefix + 'pduObj: ' + JSON.stringify(pduObj));
|
||||
|
||||
this.send(pduObj, function (err, retPduObj) {
|
||||
that.send(pduObj, function (err, retPduObj) {
|
||||
if (typeof cb === 'function') {
|
||||
cb(err, [retPduObj.params.message_id], [retPduObj]);
|
||||
}
|
||||
@@ -341,16 +344,16 @@ function sendLongSms(smsOptions, cb) {
|
||||
pduObj.params.registered_delivery = 0x01;
|
||||
}
|
||||
|
||||
log.debug(logPrefix + 'pduObj: ' + JSON.stringify(pduObj));
|
||||
that.log.debug(logPrefix + 'pduObj: ' + JSON.stringify(pduObj));
|
||||
|
||||
that.send(pduObj, function (err, retPduObj) {
|
||||
smsIds.push(retPduObj.params.message_id);
|
||||
retPduObjs.push(retPduObj);
|
||||
|
||||
log.silly(logPrefix + 'Got cb from that.send()');
|
||||
that.log.silly(logPrefix + 'Got cb from that.send()');
|
||||
|
||||
if (typeof cb === 'function' && smsIds.length === msgs.length) {
|
||||
log.silly(logPrefix + 'All cbs returned, run the parent cb.');
|
||||
that.log.silly(logPrefix + 'All cbs returned, run the parent cb.');
|
||||
cb(err, smsIds, retPduObjs);
|
||||
}
|
||||
});
|
||||
@@ -420,7 +423,7 @@ function checkLongSmses() {
|
||||
smsObj = {},
|
||||
that = this;
|
||||
|
||||
log.silly(logPrefix + 'Running');
|
||||
that.log.silly(logPrefix + 'Running');
|
||||
|
||||
// Call when complete SMS is received
|
||||
function smsReceived() {
|
||||
@@ -436,7 +439,7 @@ function checkLongSmses() {
|
||||
|
||||
// All parts are accounted for! Emit sms event and clear from tmp storage
|
||||
if (smsGroup.partsCount === smsGroup.pduObjs.length) {
|
||||
log.debug(logPrefix + 'All parts accounted for in smsGroupId "' + smsGroupId + '", emitting sms event.');
|
||||
that.log.debug(logPrefix + 'All parts accounted for in smsGroupId "' + smsGroupId + '", emitting sms event.');
|
||||
|
||||
// These are needed for references here and there in functions
|
||||
smsObj.session = that;
|
||||
@@ -449,6 +452,7 @@ function checkLongSmses() {
|
||||
smsObj.dlr = Boolean(smsGroup.pduObjs[0].pduObj.params.registered_delivery);
|
||||
smsObj.sendResp = smsResp;
|
||||
smsObj.sendDlr = utils.smsDlr;
|
||||
smsObj.log = that.log;
|
||||
|
||||
// Concatenate all the parts messages to one and set references to the session
|
||||
|
||||
@@ -464,7 +468,7 @@ function checkLongSmses() {
|
||||
}
|
||||
smsReceived();
|
||||
} else if (moment(new Date()).diff(smsGroup.created, 'hours') > 24) {
|
||||
log.info(logPrefix + 'smsGroupId "' + smsGroupId + '" is removed from this.longSmses due to being older than 24 hours.');
|
||||
that.log.info(logPrefix + 'smsGroupId "' + smsGroupId + '" is removed from this.longSmses due to being older than 24 hours.');
|
||||
|
||||
delete this.longSmses[smsGroupId];
|
||||
}
|
||||
@@ -474,18 +478,25 @@ function checkLongSmses() {
|
||||
/**
|
||||
* Generic session function
|
||||
*
|
||||
* @param {object} sock - socket object
|
||||
* @param {object} options - {sock, log}
|
||||
* @return {object} (returnObj)
|
||||
*/
|
||||
function session(sock) {
|
||||
const logPrefix = topLogPrefix + 'session() - socket address: ' + sock.remoteAddress + ':' + sock.remotePort + ' - ',
|
||||
function session(options) {
|
||||
const logPrefix = topLogPrefix + 'session() - socket address: ' + options.sock.remoteAddress + ':' + options.sock.remotePort + ' - ',
|
||||
returnObj = new events.EventEmitter();
|
||||
|
||||
log.silly(logPrefix + 'New session started');
|
||||
if (! options.log) {
|
||||
options.log = new lUtils.Log();
|
||||
}
|
||||
utils.log = options.log;
|
||||
|
||||
returnObj.log = options.log;
|
||||
|
||||
returnObj.log.silly(logPrefix + 'New session started');
|
||||
|
||||
returnObj.loggedIn = false;
|
||||
returnObj.ourSeqNr = 1; // Sequence number used for commands initiated from us
|
||||
returnObj.sock = sock; // Make the socket transparent via the returned emitter
|
||||
returnObj.sock = options.sock; // Make the socket transparent via the returned emitter
|
||||
returnObj.incOurSeqNr = incOurSeqNr;
|
||||
returnObj.closeSocket = closeSocket;
|
||||
returnObj.sockWrite = sockWrite;
|
||||
@@ -517,7 +528,7 @@ function session(sock) {
|
||||
|
||||
// TLV message_state must exists
|
||||
if (pduObj.tlvs.message_state === undefined) {
|
||||
log.info(thisLogPrefix + 'TLV message_state is missing. SeqNr: ' + pduObj.seqNr);
|
||||
returnObj.log.info(thisLogPrefix + 'TLV message_state is missing. SeqNr: ' + pduObj.seqNr);
|
||||
returnObj.sendReturn(pduObj, 'ESME_RINVTLVSTREAM');
|
||||
|
||||
return;
|
||||
@@ -525,7 +536,7 @@ function session(sock) {
|
||||
|
||||
// TLV message_state needs to be valid
|
||||
if (defs.constsById.MESSAGE_STATE[pduObj.tlvs.message_state.tagValue] === undefined) {
|
||||
log.info(thisLogPrefix + 'Invalid TLV message_state: "' + pduObj.tlvs.message_state.tagValue + '". SeqNr: ' + pduObj.seqNr);
|
||||
returnObj.log.info(thisLogPrefix + 'Invalid TLV message_state: "' + pduObj.tlvs.message_state.tagValue + '". SeqNr: ' + pduObj.seqNr);
|
||||
returnObj.sendReturn(pduObj, 'ESME_RINVTLVSTREAM');
|
||||
|
||||
return;
|
||||
@@ -533,7 +544,7 @@ function session(sock) {
|
||||
|
||||
// TLV receipted_message_id must exist
|
||||
if (pduObj.tlvs.receipted_message_id === undefined) {
|
||||
log.info(thisLogPrefix + 'TLV receipted_message_id is missing. SeqNr: ' + pduObj.seqNr);
|
||||
returnObj.log.info(thisLogPrefix + 'TLV receipted_message_id is missing. SeqNr: ' + pduObj.seqNr);
|
||||
returnObj.sendReturn(pduObj, 'ESME_RINVTLVSTREAM');
|
||||
|
||||
return;
|
||||
@@ -551,7 +562,7 @@ function session(sock) {
|
||||
returnObj.handleCmd.enquire_link = function enquire_link(pduObj) {
|
||||
const thisLogPrefix = logPrefix + 'enquire_link() - ';
|
||||
|
||||
log.silly(thisLogPrefix + 'Enquiring link');
|
||||
returnObj.log.silly(thisLogPrefix + 'Enquiring link');
|
||||
returnObj.resetEnqLinkTimer();
|
||||
returnObj.sendReturn(pduObj);
|
||||
};
|
||||
@@ -561,13 +572,13 @@ function session(sock) {
|
||||
const thisLogPrefix = logPrefix + 'submit_sm() - ',
|
||||
smsObj = {};
|
||||
|
||||
log.silly(thisLogPrefix + 'ran');
|
||||
returnObj.log.silly(thisLogPrefix + 'ran');
|
||||
|
||||
// If esm_class is 0x40 it means this is just a part of a larger message
|
||||
//if (pduObj.params.esm_class === 0x40) {
|
||||
// Fix: esm_class can be combination of bits. We need to extract 0x40 and then compare
|
||||
if ((pduObj.params.esm_class & 0x40) === 0x40) {
|
||||
log.debug(thisLogPrefix + 'long sms detected, esm_class 0x40.');
|
||||
returnObj.log.debug(thisLogPrefix + 'long sms detected, esm_class 0x40.');
|
||||
returnObj.longSms(pduObj);
|
||||
return; // Long messages should not get handled here at all, so cancel execution here
|
||||
}
|
||||
@@ -582,12 +593,13 @@ function session(sock) {
|
||||
smsObj.dlr = Boolean(pduObj.params.registered_delivery);
|
||||
smsObj.sendResp = smsResp;
|
||||
smsObj.sendDlr = utils.smsDlr;
|
||||
smsObj.log = returnObj.log;
|
||||
|
||||
if (pduObj.params.data_coding === 0x10) {
|
||||
smsObj.flash = true;
|
||||
}
|
||||
|
||||
log.silly(thisLogPrefix + 'Emitting sms object');
|
||||
returnObj.log.silly(thisLogPrefix + 'Emitting sms object');
|
||||
|
||||
returnObj.emit('sms', smsObj);
|
||||
};
|
||||
@@ -601,18 +613,18 @@ function session(sock) {
|
||||
returnObj.login = function login() {
|
||||
const thisLogPrefix = logPrefix + 'login() - ';
|
||||
|
||||
log.info(thisLogPrefix + 'Dummy login function ran, this might be a mistake');
|
||||
returnObj.log.info(thisLogPrefix + 'Dummy login function ran, this might be a mistake');
|
||||
returnObj.loggedIn = true;
|
||||
};
|
||||
|
||||
// Dummy method - should be used by serverSession or clientSession
|
||||
returnObj.resetEnqLinkTimer = function resetEnqLinkTimer() {
|
||||
const thisLogPrefix = logPrefix + 'resetEnqLinkTimer() - ';
|
||||
log.silly(thisLogPrefix + 'Resetting the kill timer');
|
||||
returnObj.log.silly(thisLogPrefix + 'Resetting the kill timer');
|
||||
};
|
||||
|
||||
// Unbind this session
|
||||
returnObj.unbind = function () {
|
||||
returnObj.unbind = function unbind() {
|
||||
returnObj.send({
|
||||
'cmdName': 'unbind'
|
||||
}, true);
|
||||
@@ -623,7 +635,7 @@ function session(sock) {
|
||||
returnObj.dataQueue = new Buffer(0);
|
||||
|
||||
// Add a 'data' event handler to this instance of socket
|
||||
sock.on('data', function (data) {
|
||||
options.sock.on('data', function (data) {
|
||||
const thisLogPrefix = logPrefix + 'sock.on(data) - ';
|
||||
|
||||
// Pass the data along to the returnObj
|
||||
@@ -632,7 +644,7 @@ function session(sock) {
|
||||
// Reset the enquire link timer
|
||||
returnObj.resetEnqLinkTimer();
|
||||
|
||||
log.debug(thisLogPrefix + 'Incoming data: ' + data.toString('hex'));
|
||||
returnObj.log.debug(thisLogPrefix + 'Incoming data: ' + data.toString('hex'));
|
||||
|
||||
// Add this data to the dataQueue for processing
|
||||
returnObj.dataQueue = Buffer.concat([returnObj.dataQueue, data]);
|
||||
@@ -641,23 +653,23 @@ function session(sock) {
|
||||
while (returnObj.dataQueue.length > 4) {
|
||||
const cmdLength = parseInt(returnObj.dataQueue.readUInt32BE(0)); // Get this commands length
|
||||
|
||||
let pdu;
|
||||
|
||||
// Malformed PDU with command length 0
|
||||
if (cmdLength <= 0) {
|
||||
// Since PDU is Malformed we need to discard buffer.
|
||||
log.silly(thisLogPrefix + 'Malformed PDU with 0 Length. Discarding buffer.');
|
||||
returnObj.log.silly(thisLogPrefix + 'Malformed PDU with 0 Length. Discarding buffer.');
|
||||
returnObj.dataQueue = returnObj.dataQueue.slice(0, returnObj.dataQueue.length);
|
||||
|
||||
// Since PDU is malformed we need to close socket since we cannot trust data from now on.
|
||||
returnObj.closeSocket();
|
||||
}
|
||||
|
||||
let pdu;
|
||||
|
||||
log.silly(thisLogPrefix + 'Processing ' + cmdLength + ' bytes of data');
|
||||
returnObj.log.silly(thisLogPrefix + 'Processing ' + cmdLength + ' bytes of data');
|
||||
|
||||
// If there is at least enough bytes in the dataQueue to fill this PDU, do it!
|
||||
if (cmdLength <= returnObj.dataQueue.length) {
|
||||
log.silly(thisLogPrefix + 'Full PDU found in dataQueue, processing ' + cmdLength + ' bytes of queue total ' + returnObj.dataQueue.length + ' bytes');
|
||||
returnObj.log.silly(thisLogPrefix + 'Full PDU found in dataQueue, processing ' + cmdLength + ' bytes of queue total ' + returnObj.dataQueue.length + ' bytes');
|
||||
|
||||
// Slice up the dataQueue buffer to this commands length
|
||||
pdu = returnObj.dataQueue.slice(0, cmdLength);
|
||||
@@ -667,19 +679,19 @@ function session(sock) {
|
||||
|
||||
returnObj.emit('incomingPdu', pdu);
|
||||
} else {
|
||||
log.debug(thisLogPrefix + 'Tried to process ' + cmdLength + ' bytes, but only ' + returnObj.dataQueue.length + ' bytes found. Awaiting more data. Current data in queue: ' + returnObj.dataQueue.toString('hex'));
|
||||
returnObj.log.debug(thisLogPrefix + 'Tried to process ' + cmdLength + ' bytes, but only ' + returnObj.dataQueue.length + ' bytes found. Awaiting more data. Current data in queue: ' + returnObj.dataQueue.toString('hex'));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (returnObj.dataQueue.length === 0) {
|
||||
log.silly(thisLogPrefix + 'All queue handled, breaking while loop.');
|
||||
returnObj.log.silly(thisLogPrefix + 'All queue handled, breaking while loop.');
|
||||
break;
|
||||
}
|
||||
|
||||
// If the command length is larger than the queue, we need to wait for more data. Stop processing!
|
||||
if (cmdLength > returnObj.dataQueue) {
|
||||
log.debug(thisLogPrefix + 'Incomplete PDU found in dataQueue, waiting for more data to continue. Current cmdLength: ' + cmdLength + ' current queue: ' + returnObj.dataQueue.toString('hex'));
|
||||
returnObj.log.debug(thisLogPrefix + 'Incomplete PDU found in dataQueue, waiting for more data to continue. Current cmdLength: ' + cmdLength + ' current queue: ' + returnObj.dataQueue.toString('hex'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -691,11 +703,11 @@ function session(sock) {
|
||||
|
||||
utils.pduToObj(pdu, function (err, pduObj) {
|
||||
if (err) {
|
||||
log.warn(thisLogPrefix + 'Invalid PDU, closing socket.');
|
||||
returnObj.log.warn(thisLogPrefix + 'Invalid PDU, closing socket.');
|
||||
|
||||
returnObj.closeSocket();
|
||||
} else {
|
||||
log.verbose(thisLogPrefix + 'Incoming PDU parsed. Seqnr: ' + pduObj.seqNr + ' cmd: ' + pduObj.cmdName + ' cmdStatus: ' + pduObj.cmdStatus + ' hex: ' + pdu.toString('hex'));
|
||||
returnObj.log.verbose(thisLogPrefix + 'Incoming PDU parsed. Seqnr: ' + pduObj.seqNr + ' cmd: ' + pduObj.cmdName + ' cmdStatus: ' + pduObj.cmdStatus + ' hex: ' + pdu.toString('hex'));
|
||||
|
||||
if (pduObj.isResp()) {
|
||||
// We do this so we can remove the dynamic event listeners to not have a memory leak
|
||||
@@ -711,23 +723,23 @@ function session(sock) {
|
||||
});
|
||||
|
||||
// Add a 'close' event handler to this instance of socket
|
||||
sock.on('close', function () {
|
||||
options.sock.on('close', function () {
|
||||
const thisLogPrefix = logPrefix + 'sock.on(close) - ';
|
||||
|
||||
returnObj.emit('close');
|
||||
if (returnObj.enqLinkTimer) {
|
||||
log.debug(thisLogPrefix + 'enqLinkTimer found, clearing.');
|
||||
returnObj.log.debug(thisLogPrefix + 'enqLinkTimer found, clearing.');
|
||||
clearTimeout(returnObj.enqLinkTimer);
|
||||
}
|
||||
log.debug(thisLogPrefix + 'socket closed');
|
||||
returnObj.log.debug(thisLogPrefix + 'socket closed');
|
||||
});
|
||||
|
||||
sock.on('error', function () {
|
||||
options.sock.on('error', function () {
|
||||
const thisLogPrefix = logPrefix + 'sock.on(error) - ';
|
||||
|
||||
log.warn(thisLogPrefix + 'Socket error detected!');
|
||||
returnObj.log.warn(thisLogPrefix + 'Socket error detected!');
|
||||
if (returnObj.enqLinkTimer) {
|
||||
log.debug(thisLogPrefix + 'enqLinkTimer found, clearing.');
|
||||
returnObj.log.debug(thisLogPrefix + 'enqLinkTimer found, clearing.');
|
||||
clearTimeout(returnObj.enqLinkTimer);
|
||||
}
|
||||
});
|
||||
|
||||
+44
-42
@@ -1,8 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
const topLogPrefix = 'larvitsmpp: lib/utils.js: ',
|
||||
defs = require(__dirname + '/defs.js'),
|
||||
log = require('winston');
|
||||
LUtils = require('larvitutils'),
|
||||
lUtils = new LUtils(),
|
||||
defs = require(__dirname + '/defs.js');
|
||||
|
||||
let bundleMsgId = 0;
|
||||
|
||||
@@ -29,7 +30,7 @@ function calcCmdLength(obj, cb) {
|
||||
|
||||
if (isNaN(paramType.size(obj.params[param]))) {
|
||||
const err = new Error('Invalid param value "' + obj.params[param] + '" for param "' + param + '" and command "' + obj.cmdName + '". Is it of the right type?');
|
||||
log.error(logPrefix + err.message);
|
||||
exports.log.error(logPrefix + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
@@ -50,7 +51,7 @@ function calcCmdLength(obj, cb) {
|
||||
cmdLength += tlvDef.type.size(tlvValue) + 4;
|
||||
} catch (err) {
|
||||
const manErr = new Error('Could not get size of TLV parameter "' + tlvName + '" with value "' + tlvValue + '", err: ' + err.message);
|
||||
log.error(logPrefix + manErr.message);
|
||||
exports.log.error(logPrefix + manErr.message);
|
||||
return cb(manErr);
|
||||
}
|
||||
}
|
||||
@@ -73,13 +74,13 @@ function writeBuffer(obj, cmdLength, cb) {
|
||||
|
||||
if (isNaN(cmdLength)) {
|
||||
const err = new Error('cmdLength is NaN');
|
||||
log.error(logPrefix + err.message);
|
||||
exports.log.error(logPrefix + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
if (cmdLength < 16) {
|
||||
const err = new Error('cmdLength is less than 16 (' + cmdLength + ')');
|
||||
log.error(logPrefix + err.message);
|
||||
exports.log.error(logPrefix + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
@@ -93,7 +94,7 @@ function writeBuffer(obj, cmdLength, cb) {
|
||||
buff.writeUInt32BE(obj.seqNr, 12); // Sequence number as the fourth 4 octets
|
||||
} catch (err) {
|
||||
const manErr = new Error('Could not write PDU header, catched err: ' + err.message, obj);
|
||||
log.error(logPrefix + manErr.message);
|
||||
exports.log.error(logPrefix + manErr.message);
|
||||
return cb(manErr);
|
||||
}
|
||||
|
||||
@@ -103,13 +104,13 @@ function writeBuffer(obj, cmdLength, cb) {
|
||||
paramSize = paramType.size(obj.params[param]);
|
||||
|
||||
if (Buffer.isBuffer(obj.params[param])) {
|
||||
log.silly(logPrefix + 'Writing param "' + param + '" with content "' + obj.params[param].toString('hex') + '" and size "' + paramSize + '"');
|
||||
exports.log.silly(logPrefix + 'Writing param "' + param + '" with content "' + obj.params[param].toString('hex') + '" and size "' + paramSize + '"');
|
||||
} else {
|
||||
if (param === 'sm_length') {
|
||||
log.silly(logPrefix + 'sm_length is calculated by short_message: "' + obj.params.short_message.toString('hex') + '"');
|
||||
exports.log.silly(logPrefix + 'sm_length is calculated by short_message: "' + obj.params.short_message.toString('hex') + '"');
|
||||
}
|
||||
|
||||
log.silly(logPrefix + 'Writing param "' + param + '" with content "' + obj.params[param] + '"');
|
||||
exports.log.silly(logPrefix + 'Writing param "' + param + '" with content "' + obj.params[param] + '"');
|
||||
}
|
||||
|
||||
// Write parameter value to buffer using the types method write()
|
||||
@@ -133,7 +134,7 @@ function writeBuffer(obj, cmdLength, cb) {
|
||||
|
||||
tlvSize = tlvDef.type.size(tlvValue);
|
||||
|
||||
log.silly(logPrefix + 'Writing TLV "' + tlvName + '" offset: ' + offset + ' value: "' + tlvValue + '"');
|
||||
exports.log.silly(logPrefix + 'Writing TLV "' + tlvName + '" offset: ' + offset + ' value: "' + tlvValue + '"');
|
||||
|
||||
buff.writeUInt16BE(tlvId, offset);
|
||||
buff.writeUInt16BE(tlvSize, offset + 2);
|
||||
@@ -142,7 +143,7 @@ function writeBuffer(obj, cmdLength, cb) {
|
||||
offset += tlvDef.type.size(tlvValue) + 4;
|
||||
}
|
||||
|
||||
log.silly(logPrefix + 'Complete PDU: "' + buff.toString('hex') + '"');
|
||||
exports.log.silly(logPrefix + 'Complete PDU: "' + buff.toString('hex') + '"');
|
||||
|
||||
cb(null, buff);
|
||||
}
|
||||
@@ -169,11 +170,11 @@ function decodeMsg(buffer, encoding, offset) {
|
||||
}
|
||||
|
||||
if (defs.encodings[encoding] === undefined) {
|
||||
log.info(logPrefix + 'Invalid encoding "' + encoding + '" given. Falling back to ASCII (0x01).');
|
||||
exports.log.info(logPrefix + 'Invalid encoding "' + encoding + '" given. Falling back to ASCII (0x01).');
|
||||
encoding = 'ASCII';
|
||||
}
|
||||
|
||||
log.debug(logPrefix + 'Decoding msg. Encoding: "' + encoding + '" offset: "' + offset + '" buffer: "' + buffer.toString('hex') + '"');
|
||||
exports.log.debug(logPrefix + 'Decoding msg. Encoding: "' + encoding + '" offset: "' + offset + '" buffer: "' + buffer.toString('hex') + '"');
|
||||
|
||||
return defs.encodings[encoding].decode(buffer.slice(offset));
|
||||
}
|
||||
@@ -208,11 +209,11 @@ function pduToObj(pdu, stupidNullByte, cb) {
|
||||
return ! ! (this.cmdId & 0x80000000);
|
||||
};
|
||||
|
||||
log.silly(logPrefix + 'Decoding PDU to Obj. PDU buff in hex: ' + pdu.toString('hex'));
|
||||
exports.log.silly(logPrefix + 'Decoding PDU to Obj. PDU buff in hex: ' + pdu.toString('hex'));
|
||||
|
||||
if (pdu.length < 16) {
|
||||
const err = new Error('PDU is to small, minimum size is 16, given size is ' + pdu.length);
|
||||
log.warn(logPrefix + '' + err.message);
|
||||
exports.log.warn(logPrefix + '' + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
@@ -225,19 +226,19 @@ function pduToObj(pdu, stupidNullByte, cb) {
|
||||
// Lookup the command id in the definitions
|
||||
if (defs.cmdsById[retObj.cmdId] === undefined) {
|
||||
const err = new Error('Unknown PDU command id: ' + retObj.cmdId + ' PDU buff in hex: ' + pdu.toString('hex'));
|
||||
log.warn(logPrefix + '' + err.message);
|
||||
exports.log.warn(logPrefix + '' + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
if (isNaN(retObj.seqNr)) {
|
||||
const err = new Error('Invalid seqNr, is not an interger: "' + retObj.seqNr + '"');
|
||||
log.warn(logPrefix + '' + err.message);
|
||||
exports.log.warn(logPrefix + '' + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
if (retObj.seqNr > 2147483646) {
|
||||
const err = new Error('Invalid seqNr, maximum size of 2147483646 (0x7fffffff) exceeded.');
|
||||
log.warn(logPrefix + '' + err.message);
|
||||
exports.log.warn(logPrefix + '' + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
@@ -254,12 +255,12 @@ function pduToObj(pdu, stupidNullByte, cb) {
|
||||
retObj.params[param] = command.params[param].type.read(pdu, offset, retObj.params.sm_length);
|
||||
paramSize = command.params[param].type.size(retObj.params[param]);
|
||||
|
||||
log.silly(logPrefix + 'Reading param "' + param + '" at offset ' + offset + ' with calculated size: ' + paramSize + ' content in hex: ' + pdu.slice(offset, offset + paramSize).toString('hex'));
|
||||
exports.log.silly(logPrefix + 'Reading param "' + param + '" at offset ' + offset + ' with calculated size: ' + paramSize + ' content in hex: ' + pdu.slice(offset, offset + paramSize).toString('hex'));
|
||||
if (param === 'short_message') {
|
||||
// Check if we have a trailing NULL octet after the short_message. Some idiot thought that would be a good idea
|
||||
// in some implementations, so we need to account for that.
|
||||
if (stupidNullByte === true) {
|
||||
log.silly(logPrefix + 'stupidNullByte is set, so short_message is followed by a NULL octet, increase paramSize one extra to account for that');
|
||||
exports.log.silly(logPrefix + 'stupidNullByte is set, so short_message is followed by a NULL octet, increase paramSize one extra to account for that');
|
||||
paramSize ++;
|
||||
}
|
||||
}
|
||||
@@ -268,7 +269,7 @@ function pduToObj(pdu, stupidNullByte, cb) {
|
||||
offset += paramSize;
|
||||
} catch (err) {
|
||||
const manErr = new Error('Failed to read param "' + param + '", err: ' + err.message);
|
||||
log.error(logPrefix + '' + manErr.message);
|
||||
exports.log.error(logPrefix + '' + manErr.message);
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
@@ -285,7 +286,7 @@ function pduToObj(pdu, stupidNullByte, cb) {
|
||||
tlvLength = pdu.readInt16BE(offset + 2);
|
||||
} catch (err) {
|
||||
const manErr = new Error('Unable to read TLV at offset "' + offset + '", given cmdLength: "' + retObj.cmdLength + '" pdu: ' + pdu.toString('hex') + ', err: ' + err.message);
|
||||
log.error(logPrefix + '' + manErr.message);
|
||||
exports.log.error(logPrefix + '' + manErr.message);
|
||||
return cb(manErr);
|
||||
}
|
||||
|
||||
@@ -298,7 +299,7 @@ function pduToObj(pdu, stupidNullByte, cb) {
|
||||
'tagValue': tlvValue
|
||||
};
|
||||
|
||||
log.verbose(logPrefix + 'Unknown TLV found. Hex ID: ' + tlvCmdId.toString(16) + ' length: ' + tlvLength + ' hex value: ' + tlvValue);
|
||||
exports.log.verbose(logPrefix + 'Unknown TLV found. Hex ID: ' + tlvCmdId.toString(16) + ' length: ' + tlvLength + ' hex value: ' + tlvValue);
|
||||
} else {
|
||||
tlvValue = defs.tlvsById[tlvCmdId].type.read(pdu, offset + 4, tlvLength);
|
||||
|
||||
@@ -312,20 +313,20 @@ function pduToObj(pdu, stupidNullByte, cb) {
|
||||
'tagValue': tlvValue
|
||||
};
|
||||
|
||||
log.silly(logPrefix + 'TLV found: "' + defs.tlvsById[tlvCmdId].tag + '" ID: "' + tlvCmdId + '" value: "' + tlvValue + '"');
|
||||
exports.log.silly(logPrefix + 'TLV found: "' + defs.tlvsById[tlvCmdId].tag + '" ID: "' + tlvCmdId + '" value: "' + tlvValue + '"');
|
||||
}
|
||||
|
||||
offset = offset + 4 + tlvLength;
|
||||
}
|
||||
|
||||
if (offset !== retObj.cmdLength && stupidNullByte === undefined) {
|
||||
log.verbose(logPrefix + 'Offset (' + offset + ') !== cmdLength (' + retObj.cmdLength + ') for seqNr: ' + retObj.seqNr + ' - retry with the stupid NULL byte for short_message');
|
||||
exports.log.verbose(logPrefix + 'Offset (' + offset + ') !== cmdLength (' + retObj.cmdLength + ') for seqNr: ' + retObj.seqNr + ' - retry with the stupid NULL byte for short_message');
|
||||
|
||||
return pduToObj(pdu, true, cb);
|
||||
}
|
||||
|
||||
if (offset !== retObj.cmdLength) {
|
||||
log.warn(logPrefix + 'Offset (' + offset + ') !== cmdLength (' + retObj.cmdLength + ') for seqNr: ' + retObj.seqNr);
|
||||
exports.log.warn(logPrefix + 'Offset (' + offset + ') !== cmdLength (' + retObj.cmdLength + ') for seqNr: ' + retObj.seqNr);
|
||||
}
|
||||
|
||||
// Decode the short message if it is set and esm_class is 0
|
||||
@@ -335,7 +336,7 @@ function pduToObj(pdu, stupidNullByte, cb) {
|
||||
retObj.params.short_message = decodeMsg(retObj.params.short_message, retObj.params.data_coding);
|
||||
}
|
||||
|
||||
log.debug(logPrefix + 'Complete decoded PDU: ' + JSON.stringify(retObj));
|
||||
exports.log.debug(logPrefix + 'Complete decoded PDU: ' + JSON.stringify(retObj));
|
||||
|
||||
cb(null, retObj);
|
||||
}
|
||||
@@ -353,7 +354,7 @@ function objToPdu(obj, cb) {
|
||||
// Check so the command is ok
|
||||
if (defs.cmds[obj.cmdName] === undefined) {
|
||||
const err = new Error('Invalid cmdName: "' + obj.cmdName + '"');
|
||||
log.warn(logPrefix + err.message);
|
||||
exports.log.warn(logPrefix + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
@@ -364,20 +365,20 @@ function objToPdu(obj, cb) {
|
||||
|
||||
if (defs.errors[obj.cmdStatus] === undefined) {
|
||||
const err = new Error('Invalid cmdStatus: "' + obj.cmdStatus + '"');
|
||||
log.warn(logPrefix + err.message);
|
||||
exports.log.warn(logPrefix + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
// Check so seqNr is ok
|
||||
if (isNaN(seqNr)) {
|
||||
const err = new Error('Invalid seqNr, is not an interger: "' + obj.seqNr + '"');
|
||||
log.warn(logPrefix + err.message);
|
||||
exports.log.warn(logPrefix + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
if (seqNr > 2147483646) {
|
||||
const err = new Error('Invalid seqNr, maximum size of 2147483646 (0x7fffffff) exceeded.');
|
||||
log.warn(logPrefix + err.message);
|
||||
exports.log.warn(logPrefix + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
@@ -394,7 +395,7 @@ function objToPdu(obj, cb) {
|
||||
if (obj.params.data_coding === undefined) {
|
||||
obj.params.data_coding = defs.encodings.detect(obj.params.short_message);
|
||||
|
||||
log.silly(logPrefix + 'data_coding "' + obj.params.data_coding + '" detected');
|
||||
exports.log.silly(logPrefix + 'data_coding "' + obj.params.data_coding + '" detected');
|
||||
|
||||
// Now set the hex value
|
||||
obj.params.data_coding = defs.consts.ENCODING[obj.params.data_coding];
|
||||
@@ -404,10 +405,10 @@ function objToPdu(obj, cb) {
|
||||
shortMsg = obj.params.short_message;
|
||||
obj.params.short_message = encodeMsg(obj.params.short_message);
|
||||
obj.params.sm_length = obj.params.short_message.length;
|
||||
log.silly(logPrefix + 'Encoding message "' + shortMsg + '" to "' + obj.params.short_message.toString('hex') + '"');
|
||||
exports.log.silly(logPrefix + 'Encoding message "' + shortMsg + '" to "' + obj.params.short_message.toString('hex') + '"');
|
||||
}
|
||||
|
||||
log.debug(logPrefix + 'Complete object to encode: ' + JSON.stringify(obj));
|
||||
exports.log.debug(logPrefix + 'Complete object to encode: ' + JSON.stringify(obj));
|
||||
|
||||
calcCmdLength(obj, function (err, cmdLength) {
|
||||
if (err) return cb(err);
|
||||
@@ -432,7 +433,7 @@ function pduReturn(pdu, status, params, tlvs, cb) {
|
||||
let err = null;
|
||||
|
||||
if (Buffer.isBuffer(pdu)) {
|
||||
log.silly(logPrefix + 'Ran with pdu as buffer, run pduToObj() and retry');
|
||||
exports.log.silly(logPrefix + 'Ran with pdu as buffer, run pduToObj() and retry');
|
||||
|
||||
pduToObj(pdu, function (err, pduObj) {
|
||||
if (err) return cb(err);
|
||||
@@ -442,7 +443,7 @@ function pduReturn(pdu, status, params, tlvs, cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.silly(logPrefix + 'ran');
|
||||
exports.log.silly(logPrefix + 'ran');
|
||||
|
||||
if (typeof tlvs === 'function') {
|
||||
cb = tlvs;
|
||||
@@ -481,7 +482,7 @@ function pduReturn(pdu, status, params, tlvs, cb) {
|
||||
if (err === null && defs.cmds[pdu.cmdName + '_resp'] === undefined) err = new Error('This command does not have a response listed. Given command: "' + pdu.cmdName + '"');
|
||||
|
||||
if (err !== null) {
|
||||
log.warn(logPrefix + err.message);
|
||||
exports.log.warn(logPrefix + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
@@ -580,7 +581,7 @@ function splitMsg(msg, encoding) {
|
||||
// A single message could contain up to 1120 bits
|
||||
// Return directly if the message fits into that
|
||||
if (totBitCount < 1121) {
|
||||
log.silly(logPrefix + 'bitCount below 1121 (' + totBitCount + ') return only one part');
|
||||
exports.log.silly(logPrefix + 'bitCount below 1121 (' + totBitCount + ') return only one part');
|
||||
return [defs.encodings[resolvedEncoding].encode(msg)];
|
||||
}
|
||||
|
||||
@@ -590,7 +591,7 @@ function splitMsg(msg, encoding) {
|
||||
bundleMsgId = 1;
|
||||
}
|
||||
|
||||
log.silly(logPrefix + 'bundleMsgId set to ' + bundleMsgId);
|
||||
exports.log.silly(logPrefix + 'bundleMsgId set to ' + bundleMsgId);
|
||||
|
||||
if (resolvedEncoding === 'ASCII') {
|
||||
partCharLimit = 153;
|
||||
@@ -677,7 +678,7 @@ function smsDlr(status, cb) {
|
||||
|
||||
if (sms.smsId === undefined) {
|
||||
const err = new Error('Trying to send DLR with no smsId.');
|
||||
log.warn(logPrefix + err.message);
|
||||
exports.log.warn(logPrefix + err.message);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
@@ -696,7 +697,7 @@ function smsDlr(status, cb) {
|
||||
shortMessage += ' stat:UNDELIVERABLE err:1 text:xxx';
|
||||
}
|
||||
|
||||
log.verbose(logPrefix + 'Sending DLR message: "' + shortMessage + '"');
|
||||
exports.log.verbose(logPrefix + 'Sending DLR message: "' + shortMessage + '"');
|
||||
|
||||
dlrPduObj.cmdName = 'deliver_sm';
|
||||
dlrPduObj.params = {
|
||||
@@ -733,3 +734,4 @@ exports.smppDate = smppDate;
|
||||
exports.bitCount = bitCount;
|
||||
exports.splitMsg = splitMsg;
|
||||
exports.smsDlr = smsDlr;
|
||||
exports.log = new lUtils.Log();
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "larvitsmpp",
|
||||
"version": "0.3.4",
|
||||
"version": "0.4.0",
|
||||
"author": {
|
||||
"name": "Mikael 'Lilleman' Göransson",
|
||||
"email": "lilleman@larvit.se",
|
||||
@@ -11,10 +11,10 @@
|
||||
"dependencies": {
|
||||
"async": "^2.4.1",
|
||||
"iconv-lite": "^0.4.18",
|
||||
"larvitutils": "^2.1.0",
|
||||
"moment": "^2.18.1",
|
||||
"utils-merge": "^1.0.0",
|
||||
"uuid": "^3.2.1",
|
||||
"winston": "^3.0.0"
|
||||
"uuid": "^3.2.1"
|
||||
},
|
||||
"description": "Simplified SMPP implementation",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const log = require('winston');
|
||||
|
||||
// Remove log output to the console
|
||||
log.remove(log.transports.Console);
|
||||
Reference in New Issue
Block a user