Important fixes to short_message

This commit is contained in:
2015-04-06 22:47:45 +02:00
parent 022a12e181
commit bca6b67342
3 changed files with 94 additions and 52 deletions
+6 -16
View File
@@ -192,30 +192,20 @@ types = {
default: ''
},
buffer: {
read: function(buffer, offset) {
var length = buffer.readUInt8(offset ++);
read: function(buffer, offset, length) {
return buffer.slice(offset, offset + length);
},
write: function(value, buffer, offset) {
buffer.writeUInt8(value.length, offset ++);
if (typeof value === 'string') {
value = new Buffer(value, 'ascii');
}
value.copy(buffer, offset);
},
size: function(buffer, offset) {
var length;
if (isNaN(offset)) {
offset = 0;
}
length = buffer.readUInt8(offset ++);
if (buffer[offset + length + 1] !== undefined && buffer.slice(offset + length + 1).toString('hex') === '00') {
return offset + length + 1;
size: function(buffer) {
if (buffer[buffer.length - 1] === 0x00) {
return buffer.length - 1;
} else {
return offset + length;
return buffer.length;
}
},
default: new Buffer(0)
@@ -1325,7 +1315,7 @@ cmds = {
replace_if_present_flag: {type: types.int8},
data_coding: {type: types.int8},
sm_default_msg_id: {type: types.int8},
//sm_length: {type: types.int8},
sm_length: {type: types.int8},
short_message: {type: types.buffer, filter: filters.message}
}
},
+69 -36
View File
@@ -11,11 +11,10 @@ var log = require('winston'),
*
* @param buf buffer
* @param str encoding 'ASCII', 'LATIN1' or 'UCS2' or hex values
* @param func callback(err, str) - str will be in utf8 format
* @return str in utf8 format
*/
function decodeMsg(buffer, encoding, callback) {
var err = null,
checkEnc;
function decodeMsg(buffer, encoding) {
var checkEnc;
for (checkEnc in defs.consts.ENCODING) {
if (parseInt(encoding) === defs.consts.ENCODING[checkEnc] || encoding === checkEnc) {
@@ -28,18 +27,14 @@ function decodeMsg(buffer, encoding, callback) {
encoding = 'ASCII';
}
callback(err, defs.encodings[encoding].decode(buffer));
return defs.encodings[encoding].decode(buffer);
}
/*
function encodeMsg(str, callback) {
var encoding = defs.encodings.detect(str),
err = null,
buff;
buff = defs.encodings[encoding].encode(str);
function encodeMsg(str) {
var encoding = defs.encodings.detect(str);
callback(err, buff);
}*/
return defs.encodings[encoding].encode(str);
}
/**
* Transforms a PDU to an object
@@ -104,17 +99,22 @@ function pduToObj(pdu, callback) {
// Get the parameter value by using the definition type read() function
try {
retObj.params[param] = command.params[param].type.read(pdu, offset);
// Short message seems to sometimes be terminated with a NULL and sometimes not. Very ugly and needs special care.
if (param === 'short_message') {
paramSize = command.params[param].type.size(pdu, offset);
} else {
paramSize = command.params[param].type.size(retObj.params[param]);
}
retObj.params[param] = command.params[param].type.read(pdu, offset, retObj.params.sm_length);
paramSize = command.params[param].type.size(retObj.params[param]);
log.silly('larvitsmpp: pduToObj() - Reading param "' + param + '" at offset ' + offset + ' with calculated size: ' + paramSize + ' content in hex: ' + pdu.slice(offset, offset + paramSize).toString('hex'));
if (param === 'short_message') {
// Check if we have a trailing NULL octet after the short_message. Some idiot thought that would be a good idea
// in some implementations, so we need to account for that.
if (pdu.slice(offset + retObj.params.sm_length, offset + retObj.params.sm_length + 1).toString('hex') === '00') {
log.silly('larvitsmpp: pduToObj() - short_message is followed by a NULL octet, increase paramSize one extra to account for that');
paramSize ++;
}
}
// Increase the offset by the current params length
offset += paramSize;
} catch (e) {
@@ -145,17 +145,9 @@ function pduToObj(pdu, callback) {
// Decode the short message if it is set
if (retObj.params.short_message !== undefined) {
retObj.params.short_message = decodeMsg(retObj.params.short_message, retObj.params.data_coding);
decodeMsg(retObj.params.short_message, retObj.params.data_coding, function(err, decodedMsg) {
if (err) {
callback(err);
return;
}
retObj.params.short_message = decodedMsg;
callback(null, retObj);
});
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
@@ -172,6 +164,7 @@ function pduToObj(pdu, callback) {
function objToPdu(obj, callback) {
var cmdLength = 16, // All commands are at least 16 octets long
err = null,
shortMsg,
param,
paramType,
buff,
@@ -232,6 +225,28 @@ function objToPdu(obj, callback) {
return;
}
// All params are mandatory. Set them if they are not set
if (obj.params === undefined) {
obj.params = {};
}
// If param "short_message" exists, encode it and set parameter "data_coding" accordingly
if (obj.params.short_message !== undefined && ! Buffer.isBuffer(obj.params.short_message)) {
// Detect encoding
obj.params.data_coding = defs.encodings.detect(obj.params.short_message);
log.silly('larvitsmpp: objToPdu() - data_coding "' + obj.params.data_coding + '" detected');
// Now set the hex value
obj.params.data_coding = defs.consts.ENCODING[obj.params.data_coding];
// Acutally encode the string
shortMsg = obj.params.short_message;
obj.params.short_message = encodeMsg(obj.params.short_message);
obj.params.sm_length = obj.params.short_message.length;
log.silly('larvitsmpp: objToPdu() - encoding message "' + shortMsg + '" to "' + obj.params.short_message.toString('hex') + '"');
}
// Handle params - All command params should always exists, even if they do not contain data.
for (param in defs.cmds[obj.cmdName].params) {
@@ -239,11 +254,6 @@ function objToPdu(obj, callback) {
// This is needed so we can calculate length etc
paramType = defs.cmds[obj.cmdName].params[param].type;
// All params are mandatory. Set them if they are not set
if (obj.params === undefined) {
obj.params = {};
}
if (obj.params[param] === undefined) {
obj.params[param] = paramType.default;
}
@@ -521,6 +531,29 @@ function session(sock) {
});
};
/**
* Send an SMS
*
* @param obj smsOptions
* from - alphanum or international format
* to - international format
* message - string
* dlr - boolean defaults to false
* @param func callback(err, retPduObj)
*/
sessionEmitter.sendSms = function(smsOptions, callback) {
var pduObj = {};
pduObj.cmdName = 'submti_sm';
pduObj.params = {
'source_addr': smsOptions.from,
'destination_addr': smsOptions.to,
'short_message': smsOptions.message
};
sessionEmitter.send(pduObj, callback);
};
sessionEmitter.deliverSm = function(pduObj) {
console.log(pduObj);
sessionEmitter.sendReturn(pduObj);
+19
View File
@@ -117,6 +117,25 @@ describe('PDU convertion', function() {
done();
});
});
it('should create a very simple submit_sm PDU', function(done) {
larvitsmpp.objToPdu({
'cmdName': 'submit_sm',
'cmdStatus': 'ESME_ROK',
'seqNr': 12,
'params': {
'source_addr': '46701113311',
'destination_addr': '46709771337',
'short_message': 'Hello world'
}
}, function(err, pdu) {
assert( ! err, 'Error should be negative');
assert(pdu.toString('hex') === '0000004200000004000000000000000c00000034363730313131333331310000003436373039373731333337000000000000000001000b48656c6c6f20776f726c64');
done();
});
});
});
});