diff --git a/cliOptions.js b/cliOptions.js index 7487887..a396346 100644 --- a/cliOptions.js +++ b/cliOptions.js @@ -68,6 +68,11 @@ const clientOptions = [ defaultOption: 1000, description: "Default max rate for metrics/bars." }, + { + name: "longsms", + type: Boolean, + description: "Split messages into multiple parts. Applies only if message is too big for one packet." + }, ]; const centerOptions = [ @@ -151,6 +156,11 @@ const centerOptions = [ defaultOption: 1000, description: "Default max rate for metrics/bars." }, + { + name: "longsms", + type: Boolean, + description: "Split messages into multiple parts. Applies only if message is too big for one packet." + }, ]; module.exports = { clientOptions, centerOptions }; diff --git a/client.js b/client.js index 4291e7a..f03204d 100644 --- a/client.js +++ b/client.js @@ -64,7 +64,7 @@ function startInterval(session, sessionLogger, metrics) { short_message: options.message, }); - sendPdu(session, pdu) + sendPdu(session, pdu, sessionLogger, options.longsms) .then((resp) => { inFlight--; sessionLogger.info(`Received response with id ${resp.message_id}`); diff --git a/utils.js b/utils.js index ee75520..be14f3c 100644 --- a/utils.js +++ b/utils.js @@ -1,3 +1,5 @@ +const smpp = require("smpp"); + function verifyExists(value, err, logger) { if (!value) { logger.error(err); @@ -14,15 +16,87 @@ function verifyDefaults(options, definitions) { } } -async function sendPdu(session, pdu) { +function getCharacterSizeForEncoding(pdu) { + let encoding = pdu.data_coding; + if (!encoding) { + encoding = 0; + } + let characterSizeBits = 0; + switch (encoding) { + case 0: + characterSizeBits = 7; + break; + case 1: + characterSizeBits = 8; + break; + case 8: + characterSizeBits = 16; + break; + } + return characterSizeBits; +} + +const maxMessageSizeBits = 1072; +function splitToParts(pdu) { + const charSize = getCharacterSizeForEncoding(pdu); + const maxMessageLength = maxMessageSizeBits / charSize; + + const splitMessage = []; + const message = pdu.short_message; + const messageLength = message.length; + const messageCount = Math.ceil(messageLength / maxMessageLength); + for (let i = 0; i < messageCount; i++) { + splitMessage.push(message.substr(i * maxMessageLength, maxMessageLength)); + } + + const pdus = []; + splitMessage.forEach((messagePart, index) => { + let udh = Buffer.from([0x05, 0x00, 0x03, this.iterator++, messageCount, index + 1]); + + let partPdu = new smpp.PDU(pdu.command, { ...pdu }); + partPdu.short_message = { + udh: udh, + message: messagePart, + }; + pdus.push(partPdu); + }); + return pdus; +} + +// TODO: Add "uselongsms" switch to options; +async function sendPdu(session, pdu, logger, uselongsms) { return new Promise((resolve, reject) => { - session.send(pdu, (respPdu) => { - if (respPdu.command_status === 0) { - resolve(respPdu); - } else { - reject(respPdu); + if (uselongsms) { + const pdus = splitToParts(pdu); + logger.info(`Sending long sms of ${pdus.length} parts`); + const total = pdus.length; + let success = 0; + let failed = 0; + for (const pdu of pdus) { + session.send(pdu, (respPdu) => { + if (respPdu.command_status === 0) { + success++; + if (success + failed === total) { + resolve(respPdu); + } + } else { + failed++; + if (success + failed === total) { + reject(respPdu); + } + } + }); } - }); + } else { + session.send(pdu, (respPdu) => { + console.log(respPdu); + if (respPdu.command_status === 0) { + resolve(respPdu); + } else { + reject(respPdu); + } + }); + } }); }