From fc629ddfdb04f3185acd0e724365067b095424ab Mon Sep 17 00:00:00 2001 From: Lilleman Date: Tue, 7 Jun 2016 12:48:50 +0200 Subject: [PATCH] Modifications to Qasims pull request to fix support for UDH header sizes above 1 --- lib/session.js | 21 +++++++-------------- lib/utils.js | 34 +++++++++++++++------------------- 2 files changed, 22 insertions(+), 33 deletions(-) diff --git a/lib/session.js b/lib/session.js index 1ae34b8..50e5341 100644 --- a/lib/session.js +++ b/lib/session.js @@ -366,28 +366,23 @@ function longSms(pduObj) { // Fix: UDH values are stored in HEX and decoding them make it garbage. First OCTET contains // the size of UDH data header. If UDH data header size is 0x05 then field 4 i.e. CSMS // reference number is of one octet otherwise it consists of 2 octets. Other fields can - // be found from below reference. + // be found from below reference. // reference: https://en.wikipedia.org/wiki/Concatenated_SMS - var udhSize = pduObj.params['udhHeader'].size, - smsGroupId = pduObj.params['udhHeader'].reference, - smsParts = pduObj.params['udhHeader'].totalParts, - partNr = pduObj.params['udhHeader'].partNr; - - var longSmsId = pduObj.params.source_addr + '_' + pduObj.params.destination_addr + '_' + smsGroupId; + var longSmsId = pduObj.params.source_addr + '_' + pduObj.params.destination_addr + '_' + pduObj.params.udhHeader.reference; if (this.longSmses[longSmsId] === undefined) { this.longSmses[longSmsId] = { 'created': new Date(), - 'partsCount': parseInt(smsParts), - 'udhSize': udhSize, // Saving udh size to remove garbage from message + 'partsCount': pduObj.params.udhHeader.totalParts, + 'udhSize': pduObj.params.udhHeader.size, // Saving udh size to remove garbage from message 'pduObjs': [{ - 'partNr': partNr, // We save this here to easier sort the array later on + 'partNr': pduObj.params.udhHeader.partNr, // We save this here to easier sort the array later on 'pduObj': pduObj }] }; } else { this.longSmses[longSmsId].pduObjs.push({ - 'partNr': partNr, // We save this here to easier sort the array later on + 'partNr': pduObj.params.udhHeader.partNr, // We save this here to easier sort the array later on 'pduObj': pduObj }); } @@ -461,9 +456,7 @@ function checkLongSmses() { curPduObj = smsObj.pduObjs[i].pduObj; curPduObj.session = this; - // Fix: message in pduObj is already decoded we dont need to do it again. Also removing garbade from original message. - //smsObj.message += utils.decodeMsg(curPduObj.params.short_message, curPduObj.params.data_coding, curPduObj.params.short_message[0] + 1); - smsObj.message += curPduObj.params.short_message.substring(udhSize + 1); + smsObj.message += utils.decodeMsg(curPduObj.params.short_message, curPduObj.params.data_coding, udhSize + 1); i ++; } diff --git a/lib/utils.js b/lib/utils.js index 3beadb7..48e24e8 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -272,27 +272,23 @@ function pduToObj(pdu, stupidNullByte, callback) { log.silly('larvitsmpp: lib/utils.js: 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') { - if((retObj.params['esm_class'] & 0x40) === 0x40) { - //This is a part of long sms. We should save UDH header information in params. - var hsize = parseInt("0x" + pdu.slice(offset, offset + paramSize).toString('hex').slice(0, 2)); - //If hsize is >5 then CSMS Reference consist of two parts - if(hsize == 5) { - var reference = parseInt("0x" + pdu.slice(offset, offset + paramSize).toString('hex').slice(6, 8)), - totalParts = parseInt("0x" + pdu.slice(offset, offset + paramSize).toString('hex').slice(8, 10)), - partNr = parseInt("0x" + pdu.slice(offset, offset + paramSize).toString('hex').slice(10, 12)); + if ((retObj.params.esm_class & 0x40) === 0x40) { + // This is a part of long sms. We should save UDH header information in params. + retObj.params.udhHeader = {}; + retObj.params.udhHeader.size = parseInt('0x' + pdu.slice(offset, offset + paramSize).toString('hex').slice(0, 2)); + + // If hsize is >5 then CSMS Reference consist of two parts + if (retObj.params.udhHeader.size === 5) { + retObj.params.udhHeader.reference = parseInt('0x' + pdu.slice(offset, offset + paramSize).toString('hex').slice(6, 8)); + retObj.params.udhHeader.totalParts = parseInt('0x' + pdu.slice(offset, offset + paramSize).toString('hex').slice(8, 10)); + retObj.params.udhHeader.partNr = parseInt('0x' + pdu.slice(offset, offset + paramSize).toString('hex').slice(10, 12)); } else { - var reference = (parseInt("0x" + pdu.slice(offset, offset + paramSize).toString('hex').slice(6, 8)) * 256) + parseInt("0x" + pdu.slice(offset, offset + paramSize).toString('hex').slice(8, 10)), - totalParts = parseInt("0x" + pdu.slice(offset, offset + paramSize).toString('hex').slice(10, 12)), - partNr = parseInt("0x" + pdu.slice(offset, offset + paramSize).toString('hex').slice(12, 14)); + retObj.params.udhHeader.reference = (parseInt('0x' + pdu.slice(offset, offset + paramSize).toString('hex').slice(6, 8)) * 256) + parseInt('0x' + pdu.slice(offset, offset + paramSize).toString('hex').slice(8, 10)), + retObj.params.udhHeader.totalParts = parseInt('0x' + pdu.slice(offset, offset + paramSize).toString('hex').slice(10, 12)), + retObj.params.udhHeader.partNr = parseInt('0x' + pdu.slice(offset, offset + paramSize).toString('hex').slice(12, 14)); } - var udhHeader = { - 'size': hsize, - 'reference': reference, - 'totalParts': totalParts, - 'partNr': partNr - } - retObj.params['udhHeader'] = udhHeader; } + // Check if we have a trailing NULL octet after the short_message. Some idiot thought that would be a good idea // in some implementations, so we need to account for that. if (stupidNullByte === true) { @@ -368,7 +364,7 @@ function pduToObj(pdu, stupidNullByte, callback) { // Decode the short message if it is set and esm_class is 0 // The esm_class 0x40 (64 int) means the short_message have a UDH // Thats why we return the short_message as a buffer - if (retObj.params.short_message !== undefined && retObj.params.esm_class !== 0x40) { + if (retObj.params.short_message !== undefined && (retObj.params.esm_class & 0x40) !== 0x40) { retObj.params.short_message = decodeMsg(retObj.params.short_message, retObj.params.data_coding); }