farhadi / node-smpp

SMPP client and server implementation in node.js
MIT License
419 stars 180 forks source link

I have Configured SMPP Server, Received PUD in several parts. #171

Closed niteshtripathi1234 closed 3 years ago

niteshtripathi1234 commented 3 years ago

How I compile all parts to make one message in the Right order, also how I get notified the message got Completed. Sample of data which I received

[PDU] PDU { command_length: 211, command_id: 4, command_status: 0, sequence_number: 7476, command: 'submit_sm', service_type: '', source_addr_ton: 1, source_addr_npi: 1, source_addr: '14702506533', dest_addr_ton: 1, dest_addr_npi: 1, destination_addr: '14702029143', esm_class: 64, protocol_id: 0, priority_flag: 0, schedule_delivery_time: '', validity_period: '', registered_delivery: 0, replace_if_present_flag: 0, data_coding: 0, sm_default_msg_id: 0, short_message: { udh: <Buffer 05 00 03 38 05 02>, message: 'forward to seeing you May, 18 2021\n\nSo long!\nNitesh BrightlinkNitesh,\nThank you for your message.\nWe look forward to seeing you May, 18 2021\n\nSo long!' } } [PDU] PDU { command_length: 211, command_id: 4, command_status: 0, sequence_number: 7477, command: 'submit_sm', service_type: '', source_addr_ton: 1, source_addr_npi: 1, source_addr: '14702506533', dest_addr_ton: 1, dest_addr_npi: 1, destination_addr: '14702029143', esm_class: 64, protocol_id: 0, priority_flag: 0, schedule_delivery_time: '', validity_period: '', registered_delivery: 0, replace_if_present_flag: 0, data_coding: 0, sm_default_msg_id: 0, short_message: { udh: <Buffer 05 00 03 38 05 01>, message: 'Nitesh,\nThank you for your message.\nWe look forward to seeing you May, 18 2021\n\nSo long!\nNitesh BrightlinkNitesh,\nThank you for your message.\nWe look ' } } [RabbitMQ] drain event undefined [PDU] PDU { command_length: 211, command_id: 4, command_status: 0, sequence_number: 7578, command: 'submit_sm', service_type: '', source_addr_ton: 1, source_addr_npi: 1, source_addr: '14702506533', dest_addr_ton: 1, dest_addr_npi: 1, destination_addr: '14702029143', esm_class: 64, protocol_id: 0, priority_flag: 0, schedule_delivery_time: '', validity_period: '', registered_delivery: 0, replace_if_present_flag: 0, data_coding: 0, sm_default_msg_id: 0, short_message: { udh: <Buffer 05 00 03 38 05 04>, message: 'message.\nWe look forward to seeing you May, 18 2021\n\nSo long!Nitesh,\nThank you for your message.\nWe look forward to seeing you May, 18 2021\n\nSo long!\n' } } [PDU] PDU { command_length: 212, command_id: 4, command_status: 0, sequence_number: 7478, command: 'submit_sm', service_type: '', source_addr_ton: 1, source_addr_npi: 1, source_addr: '14702506533', dest_addr_ton: 1, dest_addr_npi: 1, destination_addr: '14702029143', esm_class: 64, protocol_id: 0, priority_flag: 0, schedule_delivery_time: '', validity_period: '', registered_delivery: 0, replace_if_present_flag: 0, data_coding: 0, sm_default_msg_id: 0, short_message: { udh: <Buffer 05 00 03 38 05 03>, message: 'Nitesh,\nThank you for your message.\nWe look forward to seeing you May, 18 2021\n\nSo long!\nNitesh Brightlink\nNitesh BrightlinkNitesh,\nThank you for your ' } } [RabbitMQ] drain event undefined [PDU] PDU { command_length: 96, command_id: 4, command_status: 0, sequence_number: 7479, command: 'submit_sm', service_type: '', source_addr_ton: 1, source_addr_npi: 1, source_addr: '14702506533', dest_addr_ton: 1, dest_addr_npi: 1, destination_addr: '14702029143', esm_class: 64, protocol_id: 0, priority_flag: 0, schedule_delivery_time: '', validity_period: '', registered_delivery: 0, replace_if_present_flag: 0, data_coding: 0, sm_default_msg_id: 0, short_message: { udh: <Buffer 05 00 03 38 05 05>, message: 'Nitesh Brightlink\nNitesh Brightlink' } } [RabbitMQ] drain event undefined [RabbitMQ] drain event undefined [RabbitMQ] drain event undefined

juliangut commented 3 years ago

Hi @niteshtripathi1234

Have a look over here: https://en.wikipedia.org/wiki/User_Data_Header#UDH_Information_Elements

UDH headers provide the information to concatenate parted messages (IEI 00 and 08). This library returns corresponding UDH headers already parsed for you

niteshtripathi1234 commented 3 years ago

Hi, I need to know how can we achieve this by using your smpp Liberary.

juliangut commented 3 years ago

Hi @niteshtripathi1234

Once you receive a PDU with esm_class 0x40 you have UDH headers as an array at short_message.udh and the actual message at short_message.message

Each UDH will be separated in the array. You have to detect the one with IEI 0x00 or 0x08 and concatenate the parts, how to keep track of the parts and concatenate the message is up to you

juliangut commented 3 years ago

As per my previous comment this should be answered, feel free to reopen if you don't agree

tapan-thapa commented 2 years ago

I don't know if this is the best approach to concatenate messages in memory but this is how I did it.

//Global Vars
var userinfo = {};
userinfo.concatinate = {};

//Code inside submit_sm
let msgid = uuidv4();
if (
        pdu.esm_class === smpp.consts.ESM_CLASS.UDH_INDICATOR ||
        pdu.esm_class === smpp.consts.ESM_CLASS.KANNEL_UDH_INDICATOR
      ) {
        // Mind that multiple UDH headers can arrive, here we read the first one
        const udh = pdu.short_message.udh[0];

        if (udh[0] === 0x00 || udh[0] === 0x08) {
          let messageId = parseInt(udh[2]);
          let messageTotalParts = parseInt(udh[3]);
          let messagePart = parseInt(udh[4]);
          if (userinfo.concatinate.hasOwnProperty(messageId)) {
            userinfo.concatinate[messageId][messagePart - 1] = pdu;
            if (userinfo.concatinate[messageId].length == messageTotalParts) {
              let concatinatedMessage = '';
              userinfo.concatinate[messageId].forEach((concatPdu) => {
                concatinatedMessage += concatPdu.short_message.message;
              });
              delete userinfo.concatinate[messageId];
              pdu.short_message.message = concatinatedMessage;
            } else {
              //Sending message_id back to smpp client
              session.send(
                pdu.response({
                  message_id: msgid,
                })
              );
              return;
            }
          } else {
            userinfo.concatinate[messageId] = [];
            userinfo.concatinate[messageId][messagePart - 1] = pdu;
            //Sending message_id back to smpp client
            session.send(
              pdu.response({
                message_id: msgid,
              })
            );
            return;
          }
        }
      }
tapan-thapa commented 2 years ago

Small improvement with javascript maps

if (udh[0] === 0x00 || udh[0] === 0x08) {
          let messageId = parseInt(udh[2]);
          let messageTotalParts = parseInt(udh[3]);
          let messagePart = parseInt(udh[4]);
          if (userinfo.concatinate.hasOwnProperty(messageId)) {
            userinfo.concatinate[messageId].set(messagePart - 1, pdu);
            if (userinfo.concatinate[messageId].size == messageTotalParts) {
              let concatinatedMessage = '';
              let concatinatedArray = [];
              for (const [key, value] of userinfo.concatinate[messageId]) {
                concatinatedArray[key] = value;
              }
              concatinatedArray.forEach((concatPdu) => {
                concatinatedMessage += concatPdu.short_message.message;
              });
              delete userinfo.concatinate[messageId];
              pdu.short_message.message = concatinatedMessage;
            } else {
              //Sending message_id back to smpp client
              session.send(
                pdu.response({
                  message_id: msgid,
                })
              );
              return;
            }
          } else {
            userinfo.concatinate[messageId] = new Map();
            userinfo.concatinate[messageId].set(messagePart - 1, pdu);
            //Sending message_id back to smpp client
            session.send(
              pdu.response({
                message_id: msgid,
              })
            );
            return;
          }
        }