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