Merge from master
This commit is contained in:
@@ -117,7 +117,7 @@ Example code below:
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Oh, the sms sender wants a dlr (delivery report), send it!
|
// Oh, the sms sender wants a dlr (delivery report), send it!
|
||||||
if (sms.dlrRequested === true) {
|
if (sms.dlr === true) {
|
||||||
serverSession.sendDlr(sms);
|
serverSession.sendDlr(sms);
|
||||||
|
|
||||||
// To send a negative delivery report do:
|
// To send a negative delivery report do:
|
||||||
|
|||||||
+29
-5
@@ -175,12 +175,18 @@ types = {
|
|||||||
},
|
},
|
||||||
write: function(value, buffer, offset) {
|
write: function(value, buffer, offset) {
|
||||||
buffer.writeUInt8(value.length, offset ++);
|
buffer.writeUInt8(value.length, offset ++);
|
||||||
if (typeof value === 'string' || typeof value === 'number') {
|
if (typeof value === 'number') {
|
||||||
|
value = value.toString();
|
||||||
|
}
|
||||||
|
if (typeof value === 'string') {
|
||||||
value = new Buffer(value, 'ascii');
|
value = new Buffer(value, 'ascii');
|
||||||
}
|
}
|
||||||
value.copy(buffer, offset);
|
value.copy(buffer, offset);
|
||||||
},
|
},
|
||||||
size: function(value) {
|
size: function(value) {
|
||||||
|
if (typeof value === 'number') {
|
||||||
|
value = value.toString();
|
||||||
|
}
|
||||||
return value.length + 1;
|
return value.length + 1;
|
||||||
},
|
},
|
||||||
default: ''
|
default: ''
|
||||||
@@ -197,7 +203,10 @@ types = {
|
|||||||
return buffer.toString('ascii', offset, offset + length);
|
return buffer.toString('ascii', offset, offset + length);
|
||||||
},
|
},
|
||||||
write: function(value, buffer, offset) {
|
write: function(value, buffer, offset) {
|
||||||
if (typeof value === 'string' || typeof value === 'number') {
|
if (typeof value === 'number') {
|
||||||
|
value = value.toString();
|
||||||
|
}
|
||||||
|
if (typeof value === 'string') {
|
||||||
value = new Buffer(value, 'ascii');
|
value = new Buffer(value, 'ascii');
|
||||||
}
|
}
|
||||||
value.copy(buffer, offset);
|
value.copy(buffer, offset);
|
||||||
@@ -217,7 +226,10 @@ types = {
|
|||||||
return buffer.slice(offset, offset + length);
|
return buffer.slice(offset, offset + length);
|
||||||
},
|
},
|
||||||
write: function(value, buffer, offset) {
|
write: function(value, buffer, offset) {
|
||||||
if (typeof value === 'string' || typeof value === 'number') {
|
if (typeof value === 'number') {
|
||||||
|
value = value.toString();
|
||||||
|
}
|
||||||
|
if (typeof value === 'string') {
|
||||||
value = new Buffer(value, 'ascii');
|
value = new Buffer(value, 'ascii');
|
||||||
}
|
}
|
||||||
value.copy(buffer, offset);
|
value.copy(buffer, offset);
|
||||||
@@ -337,12 +349,18 @@ types.tlv = {
|
|||||||
return buffer.toString('ascii', offset, offset + length);
|
return buffer.toString('ascii', offset, offset + length);
|
||||||
},
|
},
|
||||||
write: function(value, buffer, offset) {
|
write: function(value, buffer, offset) {
|
||||||
if (typeof value === 'string' || typeof value === 'number') {
|
if (typeof value === 'number') {
|
||||||
|
value = value.toString();
|
||||||
|
}
|
||||||
|
if (typeof value === 'string') {
|
||||||
value = new Buffer(value, 'ascii');
|
value = new Buffer(value, 'ascii');
|
||||||
}
|
}
|
||||||
value.copy(buffer, offset);
|
value.copy(buffer, offset);
|
||||||
},
|
},
|
||||||
size: function(value) {
|
size: function(value) {
|
||||||
|
if (typeof value === 'number') {
|
||||||
|
value = value.toString();
|
||||||
|
}
|
||||||
return value.length;
|
return value.length;
|
||||||
},
|
},
|
||||||
default: ''
|
default: ''
|
||||||
@@ -352,12 +370,18 @@ types.tlv = {
|
|||||||
return buffer.slice(offset, offset + length);
|
return buffer.slice(offset, offset + length);
|
||||||
},
|
},
|
||||||
write: function(value, buffer, offset) {
|
write: function(value, buffer, offset) {
|
||||||
if (typeof value === 'string' || typeof value === 'number') {
|
if (typeof value === 'number') {
|
||||||
|
value = value.toString();
|
||||||
|
}
|
||||||
|
if (typeof value === 'string') {
|
||||||
value = new Buffer(value, 'ascii');
|
value = new Buffer(value, 'ascii');
|
||||||
}
|
}
|
||||||
value.copy(buffer, offset);
|
value.copy(buffer, offset);
|
||||||
},
|
},
|
||||||
size: function(value) {
|
size: function(value) {
|
||||||
|
if (typeof value === 'number') {
|
||||||
|
value = value.toString();
|
||||||
|
}
|
||||||
return value.length;
|
return value.length;
|
||||||
},
|
},
|
||||||
default: null
|
default: null
|
||||||
|
|||||||
+6
-4
@@ -110,7 +110,7 @@ function session(sock) {
|
|||||||
// Make sure the sequence number is set and is correct
|
// Make sure the sequence number is set and is correct
|
||||||
pduObj.seqNr = returnObj.ourSeqNr;
|
pduObj.seqNr = returnObj.ourSeqNr;
|
||||||
|
|
||||||
log.debug('larvitsmpp: lib/session.js: session() - returnObj.send() - Sending PDU to remote. cmdName: ' + pduObj.cmdName + ' seqNr: ' + pduObj.seqNr);
|
log.debug('larvitsmpp: lib/session.js: session() - returnObj.send() - Sending PDU to remote. pduObj: ' + JSON.stringify(pduObj));
|
||||||
|
|
||||||
// If closeAndSend is omitted, put callback in its place
|
// If closeAndSend is omitted, put callback in its place
|
||||||
if (typeof closeAfterSend === 'function') {
|
if (typeof closeAfterSend === 'function') {
|
||||||
@@ -207,7 +207,7 @@ function session(sock) {
|
|||||||
* from - alphanum or international format
|
* from - alphanum or international format
|
||||||
* to - international format
|
* to - international format
|
||||||
* message - string
|
* message - string
|
||||||
* dlrRequested - boolean defaults to false
|
* dlr - boolean defaults to false
|
||||||
* @param func callback(err, smsId, retPduObj)
|
* @param func callback(err, smsId, retPduObj)
|
||||||
*/
|
*/
|
||||||
returnObj.sendSms = function(smsOptions, callback) {
|
returnObj.sendSms = function(smsOptions, callback) {
|
||||||
@@ -221,10 +221,12 @@ function session(sock) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Request DLRs!
|
// Request DLRs!
|
||||||
if (smsOptions.dlrRequested) {
|
if (smsOptions.dlr) {
|
||||||
pduObj.params.registered_delivery = 0x01;
|
pduObj.params.registered_delivery = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.debug('larvitsmpp: lib/session.js: returnObj.sendSms() - pduObj: ' + JSON.stringify(pduObj));
|
||||||
|
|
||||||
returnObj.send(pduObj, function(err, retPduObj) {
|
returnObj.send(pduObj, function(err, retPduObj) {
|
||||||
if (typeof callback === 'function') {
|
if (typeof callback === 'function') {
|
||||||
callback(err, retPduObj.params.message_id, retPduObj);
|
callback(err, retPduObj.params.message_id, retPduObj);
|
||||||
@@ -372,7 +374,7 @@ function session(sock) {
|
|||||||
'to': pduObj.params.destination_addr,
|
'to': pduObj.params.destination_addr,
|
||||||
'submitTime': new Date(),
|
'submitTime': new Date(),
|
||||||
'message': pduObj.params.short_message,
|
'message': pduObj.params.short_message,
|
||||||
'dlrRequested': Boolean(pduObj.params.registered_delivery)
|
'dlr': Boolean(pduObj.params.registered_delivery)
|
||||||
};
|
};
|
||||||
|
|
||||||
function smsReceived(smsData) {
|
function smsReceived(smsData) {
|
||||||
|
|||||||
+36
-14
@@ -116,6 +116,8 @@ function writeBuffer(obj, cmdLength, callback) {
|
|||||||
// Write parameter value to buffer using the types method write()
|
// Write parameter value to buffer using the types method write()
|
||||||
paramType.write(obj.params[param], buff, offset);
|
paramType.write(obj.params[param], buff, offset);
|
||||||
|
|
||||||
|
log.silly('larvitsmpp: lib/utils.js: writeBuffer() - Writing param "' + param + '" with content "' + obj.params[param] + '"');
|
||||||
|
|
||||||
// Increase the offset for the next param
|
// Increase the offset for the next param
|
||||||
offset += paramType.size(obj.params[param]);
|
offset += paramType.size(obj.params[param]);
|
||||||
}
|
}
|
||||||
@@ -132,7 +134,7 @@ function writeBuffer(obj, cmdLength, callback) {
|
|||||||
|
|
||||||
tlvSize = tlvDef.type.size(tlvValue);
|
tlvSize = tlvDef.type.size(tlvValue);
|
||||||
|
|
||||||
log.silly('larvitsmpp: lib/utils.js: objToPdu() - writeBuffer() - Writing TLV "' + tlvName + '" offset: ' + offset + ' value: "' + tlvValue + '"');
|
log.silly('larvitsmpp: lib/utils.js: writeBuffer() - 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);
|
||||||
@@ -178,9 +180,10 @@ function encodeMsg(str) {
|
|||||||
* Transforms a PDU to an object
|
* Transforms a PDU to an object
|
||||||
*
|
*
|
||||||
* @param buf pdu
|
* @param buf pdu
|
||||||
|
* @param bol stupidNullByte - Define if the short_message should be followed by a stupid NULL byte - will be auto resolved if left undefined
|
||||||
* @param func callback(err, obj)
|
* @param func callback(err, obj)
|
||||||
*/
|
*/
|
||||||
function pduToObj(pdu, callback) {
|
function pduToObj(pdu, stupidNullByte, callback) {
|
||||||
var retObj = {'params': {}, 'tlvs': {}},
|
var retObj = {'params': {}, 'tlvs': {}},
|
||||||
err = null,
|
err = null,
|
||||||
offset,
|
offset,
|
||||||
@@ -191,6 +194,11 @@ function pduToObj(pdu, callback) {
|
|||||||
tlvValue,
|
tlvValue,
|
||||||
paramSize;
|
paramSize;
|
||||||
|
|
||||||
|
if (typeof stupidNullByte === 'function') {
|
||||||
|
callback = stupidNullByte;
|
||||||
|
stupidNullByte = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns true if this PDU is a response to another PDU
|
// Returns true if this PDU is a response to another PDU
|
||||||
retObj.isResponse = function() {
|
retObj.isResponse = function() {
|
||||||
return ! ! (this.cmdId & 0x80000000);
|
return ! ! (this.cmdId & 0x80000000);
|
||||||
@@ -248,9 +256,8 @@ function pduToObj(pdu, callback) {
|
|||||||
// 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 (pdu.slice(offset + retObj.params.sm_length, offset + retObj.params.sm_length + 1).toString('hex') === '00') {
|
if (stupidNullByte === true) {
|
||||||
log.silly('larvitsmpp: lib/utils.js: pduToObj() - short_message is followed by a NULL octet, increase paramSize one extra to account for that');
|
log.silly('larvitsmpp: lib/utils.js: pduToObj() - stupidNullByte is set, so short_message is followed by a NULL octet, increase paramSize one extra to account for that');
|
||||||
|
|
||||||
paramSize ++;
|
paramSize ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,7 +274,8 @@ function pduToObj(pdu, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the length is greater than the current offset, there must be TLVs - resolve them!
|
// If the length is greater than the current offset, there must be TLVs - resolve them!
|
||||||
while (offset < retObj.cmdLength) {
|
// The minimal size for a TLV is its head, 4 octets
|
||||||
|
while ((offset + 4) < retObj.cmdLength) {
|
||||||
try {
|
try {
|
||||||
tlvCmdId = pdu.readInt16BE(offset);
|
tlvCmdId = pdu.readInt16BE(offset);
|
||||||
tlvLength = pdu.readInt16BE(offset + 2);
|
tlvLength = pdu.readInt16BE(offset + 2);
|
||||||
@@ -275,6 +283,7 @@ function pduToObj(pdu, callback) {
|
|||||||
err = new Error('Unable to read TLV at offset "' + offset + '", given cmdLength: "' + retObj.cmdLength + '" pdu: ' + pdu.toString('hex'));
|
err = new Error('Unable to read TLV at offset "' + offset + '", given cmdLength: "' + retObj.cmdLength + '" pdu: ' + pdu.toString('hex'));
|
||||||
log.error('larvitsmpp: lib/utils.js: pduToObj() - ' + err.message);
|
log.error('larvitsmpp: lib/utils.js: pduToObj() - ' + err.message);
|
||||||
callback(err);
|
callback(err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defs.tlvsById[tlvCmdId] === undefined) {
|
if (defs.tlvsById[tlvCmdId] === undefined) {
|
||||||
@@ -299,21 +308,32 @@ function pduToObj(pdu, callback) {
|
|||||||
'tagName': defs.tlvsById[tlvCmdId].tag,
|
'tagName': defs.tlvsById[tlvCmdId].tag,
|
||||||
'tagValue': tlvValue
|
'tagValue': tlvValue
|
||||||
};
|
};
|
||||||
|
|
||||||
|
log.silly('larvitsmpp: lib/utils.js: pduToObj() - TLV found: "' + defs.tlvsById[tlvCmdId].tag + '" ID: "' + tlvCmdId + '" value: "' + tlvValue + '"');
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = offset + 4 + tlvLength;
|
offset = offset + 4 + tlvLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (offset !== retObj.cmdLength && stupidNullByte === undefined) {
|
||||||
|
log.verbose('larvitsmpp: lib/utils.js: pduToObj() - Offset (' + offset + ') !== cmdLength (' + retObj.cmdLength + ') for seqNr: ' + retObj.seqNr + ' - retry with the stupid NULL byte for short_message');
|
||||||
|
|
||||||
|
pduToObj(pdu, true, callback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset !== retObj.cmdLength) {
|
||||||
|
log.warn('larvitsmpp: lib/utils.js: pduToObj() - Offset (' + offset + ') !== cmdLength (' + retObj.cmdLength + ') for seqNr: ' + retObj.seqNr);
|
||||||
|
}
|
||||||
|
|
||||||
// Decode the short message if it is set
|
// Decode the short message if it is set
|
||||||
if (retObj.params.short_message !== undefined) {
|
if (retObj.params.short_message !== undefined) {
|
||||||
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);
|
||||||
|
|
||||||
callback(null, retObj);
|
|
||||||
} else {
|
|
||||||
// We need to do the standard callback in an else statement since
|
|
||||||
// this always would be called before the above callback if we didn't
|
|
||||||
callback(null, retObj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.debug('larvitsmpp: lib/utils.js: pduToObj() - Complete decoded PDU: ' + JSON.stringify(retObj));
|
||||||
|
|
||||||
|
callback(null, retObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -357,7 +377,7 @@ function objToPdu(obj, callback) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All params are mandatory. Set them if they are not set
|
// Params must be an object
|
||||||
if (obj.params === undefined) {
|
if (obj.params === undefined) {
|
||||||
obj.params = {};
|
obj.params = {};
|
||||||
}
|
}
|
||||||
@@ -379,6 +399,8 @@ function objToPdu(obj, callback) {
|
|||||||
log.silly('larvitsmpp: lib/utils.js: objToPdu() - encoding message "' + shortMsg + '" to "' + obj.params.short_message.toString('hex') + '"');
|
log.silly('larvitsmpp: lib/utils.js: objToPdu() - encoding message "' + shortMsg + '" to "' + obj.params.short_message.toString('hex') + '"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.debug('larvitsmpp: lib/utils.js: objToPdu() - Complete object to encode: ' + JSON.stringify(obj));
|
||||||
|
|
||||||
calcCmdLength(obj, function(err, cmdLength) {
|
calcCmdLength(obj, function(err, cmdLength) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
@@ -622,4 +644,4 @@ exports.objToPdu = objToPdu;
|
|||||||
exports.pduReturn = pduReturn;
|
exports.pduReturn = pduReturn;
|
||||||
exports.smppDate = smppDate;
|
exports.smppDate = smppDate;
|
||||||
exports.bitCount = bitCount;
|
exports.bitCount = bitCount;
|
||||||
exports.splitMsg = splitMsg;
|
exports.splitMsg = splitMsg;
|
||||||
|
|||||||
@@ -141,6 +141,29 @@ describe('PDU convertion', function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should encode and decode integer cstring params correctly', function(done) {
|
||||||
|
var pduObj = {
|
||||||
|
'cmdName': 'submit_sm_resp',
|
||||||
|
'cmdStatus': 'ESME_ROK',
|
||||||
|
'seqNr': 2,
|
||||||
|
'params': {
|
||||||
|
'message_id': 450
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
larvitsmpp.utils.objToPdu(pduObj, function(err, pduBuf) {
|
||||||
|
assert( ! err, 'Error should be negative');
|
||||||
|
|
||||||
|
larvitsmpp.utils.pduToObj(pduBuf, function(err, retPduObj) {
|
||||||
|
assert( ! err, 'Error should be negative');
|
||||||
|
|
||||||
|
assert(retPduObj.params.message_id === '450', 'message_id param should be 450, but as string');
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('TLVs', function() {
|
describe('TLVs', function() {
|
||||||
@@ -201,6 +224,49 @@ describe('PDU convertion', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should add some other TLVs to a PDU', function(done) {
|
||||||
|
var pduObj = {
|
||||||
|
'cmdName': 'deliver_sm',
|
||||||
|
'params': {
|
||||||
|
'source_addr': '46701113311',
|
||||||
|
'destination_addr': '46709771337',
|
||||||
|
'esm_class': 4,
|
||||||
|
'short_message': 'id:450 sub:001 dlvrd:1 submit date:1504031342 done date:1504031342 stat:DELIVRD err:0 text:xxx'
|
||||||
|
},
|
||||||
|
'tlvs': {
|
||||||
|
'receipted_message_id': {
|
||||||
|
'tagId': 30,
|
||||||
|
'tagName': 'receipted_message_id',
|
||||||
|
'tagValue': 450
|
||||||
|
},
|
||||||
|
'message_state': {
|
||||||
|
'tagId': 1063,
|
||||||
|
'tagName': 'message_state',
|
||||||
|
'tagValue': 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'seqNr': 323
|
||||||
|
};
|
||||||
|
|
||||||
|
larvitsmpp.utils.objToPdu(pduObj, function(err, pduBuf) {
|
||||||
|
assert( ! err, 'Error should be negative');
|
||||||
|
|
||||||
|
larvitsmpp.utils.pduToObj(pduBuf, function(err, retPduObj) {
|
||||||
|
assert( ! err, 'Error should be negative');
|
||||||
|
|
||||||
|
assert(retPduObj.params.short_message === 'id:450 sub:001 dlvrd:1 submit date:1504031342 done date:1504031342 stat:DELIVRD err:0 text:xxx', 'short_message should be preserved');
|
||||||
|
assert(retPduObj.cmdName === 'deliver_sm', 'Command name should be "deliver_sm"');
|
||||||
|
assert(retPduObj.tlvs.message_state !== undefined, 'TLV message_state should be set');
|
||||||
|
assert(retPduObj.tlvs.message_state.tagValue === 2, 'TLV message_state tagValue should be 2');
|
||||||
|
assert(retPduObj.tlvs.receipted_message_id !== undefined, 'TLV receipted_message_id should be set');
|
||||||
|
assert(retPduObj.tlvs.receipted_message_id.tagValue === '450', 'TLV receipted_message_id tagValue should be "450"');
|
||||||
|
assert(retPduObj.seqNr === 323, 'Sequence number should be 323');
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Return PDUs', function() {
|
describe('Return PDUs', function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user