diff --git a/lib/session.js b/lib/session.js index be75734..cb79b27 100644 --- a/lib/session.js +++ b/lib/session.js @@ -51,28 +51,26 @@ function smsResp(status, callback) { } if (sms.pduObjs === undefined) { - sms.pduObjs = [sms.pduObjs]; + sms.pduObjs = [sms.pduObj]; } // Build async tasks to run the responses in parallel i = 0; + while (sms.pduObjs[i] !== undefined) { - - - tasks.push(function(callback) { - sms.session.sendReturn( - sms.pduObj, - status, - {'message_id': sms.smsId}, - false, - callback - ); - }); + tasks.push(async.apply( + sms.session.sendReturn, + sms.pduObjs[i], + status, + {'message_id': sms.smsId}, + false + )); i ++; } - + async.parallel(tasks, callback); +/* sms.session.sendReturn( sms.pduObj, status, @@ -80,7 +78,7 @@ function smsResp(status, callback) { false, callback ); - +*/ } /** @@ -284,7 +282,7 @@ function session(sock) { // Response PDUs are not allowed with the send() command, they should use the sendReturn() if (pduObj.cmdName.substring(pduObj.cmdName - 5) === '_resp') { - err = new Error('larvitsmpp: lib/session.js: session() - returnObj.send() - Given pduObj is a response, use sendReturn() instead. cmdName: ' + pduObj.cmdName); + err = new Error('Given pduObj is a response, use sendReturn() instead. cmdName: ' + pduObj.cmdName); callback(err); return; } @@ -302,7 +300,7 @@ function session(sock) { returnObj.closeSocket(); } } else { - err = new Error('larvitsmpp: lib/session.js: session() - returnObj.send() - returnObj.on(incomingPduObj) - 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); + 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(err.message); callback(err); } @@ -358,56 +356,6 @@ function session(sock) { }); }; - /** - * Send a longer SMS than 1120 bits - * - * @param obj smsOptions - * from - alphanum or international format - * to - international format - * message - string - * dlr - boolean defaults to false - * @param func callback(err, smsId, retPduObj) - */ - returnObj.sendLongSms = function(smsOptions, callback) { - var smsIds = [], - msgs = utils.splitMsg(smsOptions.message), - encoding = defs.encodings.detect(smsOptions.message); // Set encoding once for all message parts - - function sendPart(i) { - var pduObj = { - 'cmdName': 'submit_sm', - 'params': { - 'source_addr_ton': 1, // Default to international format - 'esm_class': 0x40, // This indicates that there is a UDH in the short_message - 'source_addr': smsOptions.from, - 'destination_addr': smsOptions.to, - 'data_coding': defs.consts.ENCODING[encoding], - 'short_message': msgs[i], - 'sm_length': msgs[i].length - } - }; - - // Request DLRs! - if (smsOptions.dlr) { - pduObj.params.registered_delivery = 0x01; - } - - log.debug('larvitsmpp: lib/session.js: returnObj.sendLongSms() - pduObj: ' + JSON.stringify(pduObj)); - - returnObj.send(pduObj, function(err, retPduObj) { - smsIds.push(retPduObj.params.message_id); - - if (typeof callback === 'function' && msgs[i + 1] === undefined) { - callback(err, smsIds, retPduObj); - } else if (msgs[i + 1] !== undefined) { - sendPart(i + 1); - } - }); - } - - sendPart(0); - }; - /** * Send an SMS * @@ -454,6 +402,67 @@ function session(sock) { // These should be cleared if they lingre to long to avoid memory leaks returnObj.longSmses = {}; + // Temporary storage for DLRs to long smses + // We keep them like this to be able to simulate a single DLR when all parts have gotten DLRs + returnObj.longSmsDlrs = {}; + + /** + * Send a longer SMS than 1120 bits + * + * @param obj smsOptions + * from - alphanum or international format + * to - international format + * message - string + * dlr - boolean defaults to false + * @param func callback(err, smsId, retPduObj) + */ + returnObj.sendLongSms = function(smsOptions, callback) { + var smsIds = [], + retPduObjs = [], + msgs = utils.splitMsg(smsOptions.message), + encoding = defs.encodings.detect(smsOptions.message); // Set encoding once for all message parts + + function sendPart(i) { + var pduObj = { + 'cmdName': 'submit_sm', + 'params': { + 'source_addr_ton': 1, // Default to international format + 'esm_class': 0x40, // This indicates that there is a UDH in the short_message + 'source_addr': smsOptions.from, + 'destination_addr': smsOptions.to, + 'data_coding': defs.consts.ENCODING[encoding], + 'short_message': msgs[i], + 'sm_length': msgs[i].length + } + }; + + // Request DLRs! + if (smsOptions.dlr) { + pduObj.params.registered_delivery = 0x01; + } + + log.debug('larvitsmpp: lib/session.js: returnObj.sendLongSms() - pduObj: ' + JSON.stringify(pduObj)); + + returnObj.send(pduObj, function(err, retPduObj) { + smsIds.push(retPduObj.params.message_id); + retPduObjs.push(retPduObj); + + log.silly('larvitsmpp: lib/session.js: returnObj.sendLongSms() - Callback from returnObj.send() gotten'); + + if (typeof callback === 'function' && smsIds.length === msgs.length) { + log.silly('larvitsmpp: lib/session.js: returnObj.sendLongSms() - All callbacks returned, run the parent callback.'); + callback(err, smsIds, retPduObjs); + } + }); + + if (msgs[i + 1] !== undefined) { + sendPart(i + 1); + } + } + + sendPart(0); + }; + // Store long smses in the temporary storage returnObj.longSms = function(pduObj) { var smsGroupId = pduObj.params.short_message[3], @@ -472,6 +481,9 @@ function session(sock) { } else { returnObj.longSmses[longSmsId].pduObjs.push(pduObj); } + + // Check the long messages tmp storage to see if we should handle them + returnObj.checkLongSmses(); }; // Walk through the long sms storage to investigate if we can send complete messages along @@ -483,6 +495,8 @@ function session(sock) { i, curPduObj; + log.silly('larvitsmpp: lib/session.js: session() - returnObj.checkLongSmses() - Running'); + // Sort function to sort group parts function sortLongSmsPdus(a, b) { if (a.partNr < b.partNr) { @@ -497,7 +511,8 @@ function session(sock) { } // Callback function for emitted sms event - function smsReceived(smsData) { + function smsReceived() { + // This needs to be ran if DLRs are sent for these messages delete returnObj.longSmses[smsGroupId]; } @@ -602,6 +617,7 @@ function session(sock) { // If esm_class is 0x40 it means this is just a part of a larger message if (pduObj.params.esm_class === 0x40) { + log.debug('larvitsmpp: lib/session.js: session() - returnObj.handleCmd.submit_sm() - long sms detected, esm_class 0x40.'); returnObj.longSms(pduObj); return; // Long messages should not get handled here at all, so cancel execution here } @@ -662,7 +678,7 @@ function session(sock) { // Reset the enquire link timer returnObj.resetEnqLinkTimer(); - log.silly('larvitsmpp: lib/session.js: session() - sock.on(data) - Incoming data: ' + data.toString('hex')); + log.debug('larvitsmpp: lib/session.js: session() - sock.on(data) - Incoming data: ' + data.toString('hex')); // Add this data to the dataQueue for processing returnObj.dataQueue = Buffer.concat([returnObj.dataQueue, data]); @@ -670,7 +686,7 @@ function session(sock) { // Process queue while (returnObj.dataQueue.length !== 0) { // Get this commands length - cmdLength = parseInt(data.readUInt32BE(0)); + cmdLength = parseInt(returnObj.dataQueue.readUInt32BE(0)); log.silly('larvitsmpp: lib/session.js: session() - sock.on(data) - Processing ' + cmdLength + ' bytes of data'); // If there is at least enough bytes in the dataQueue to fill this PDU, do it! @@ -684,6 +700,10 @@ function session(sock) { returnObj.dataQueue = returnObj.dataQueue.slice(cmdLength, returnObj.dataQueue.length); returnObj.emit('incomingPdu', pdu); + } else { + log.debug('larvitsmpp: lib/session.js: session() - sock.on(data) - Tried to process ' + cmdLength + ' bytes, but only ' + returnObj.dataQueue.length + ' bytes found. Awaiting more data. Current data in queue: ' + returnObj.dataQueue.toString('hex')); + + break; } if (returnObj.dataQueue.length === 0) {