Git Product home page Git Product logo

node-smpp's Introduction

node-smpp

SMPP client and server implementation in node.js.

Build Status Dependency Status devDependency Status Coverage Status

Introduction

This is a complete implementation of SMPP v5.0 in node.js, with support for custom commands and TLVs.

SMPP v5.0, by design, is backward compatible with v3.4, so you would be able to use this module with 3.4 implementations. Even you can use this module with 3.3 implementations as far as you don't use TLV parameters and don't bind in transceiver mode.

The name of the methods and parameters in this implementation are equivalent to the names defined in SMPP specification. So get a copy of SMPP v5.0 Specification for a list of available operations and their parameters.

Installation

npm install smpp

Usage

Creating a SMPP session

var smpp = require('smpp');
var session = smpp.connect({
	url: 'smpp://example.com:2775',
	auto_enquire_link_period: 10000,
	debug: true
}, function() {
	session.bind_transceiver({
		system_id: 'YOUR_SYSTEM_ID',
		password: 'YOUR_PASSWORD'
	}, function(pdu) {
		if (pdu.command_status === 0) {
			// Successfully bound
			session.submit_sm({
				destination_addr: 'DESTINATION NUMBER',
				short_message: 'Hello!'
			}, function(pdu) {
				if (pdu.command_status === 0) {
					// Message successfully sent
					console.log(pdu.message_id);
				}
			});
		}
	});
});

Creating a SMPP server

var smpp = require('smpp');
var server = smpp.createServer({
	debug: true
}, function(session) {
	session.on('error', function (err) {
		// Something ocurred, not listening for this event will terminate the program
  	});
	session.on('bind_transceiver', function(pdu) {
		// we pause the session to prevent further incoming pdu events,
		// untill we authorize the session with some async operation.
		session.pause();
		checkAsyncUserPass(pdu.system_id, pdu.password, function(err) {
			if (err) {
				session.send(pdu.response({
					command_status: smpp.ESME_RBINDFAIL
				}));
				session.close();
				return;
			}
			session.send(pdu.response());
			session.resume();
		});
	});
});

server.listen(2775);

It's very important to listen for session errors, not listening for error events will terminate the program.

Debug

To enable a simple debug of ingoing/outgoing messages pass debug: true as server/client option. Debug is disabled by default.

Alternatively, you can listen for the debug event and write your own implementation:

session.on('debug', function(type, msg, payload) {
	console.log({type: type, msg: msg, payload: payload});
});

A debugListener option is also supported:

var options = {
	debug: false,
	debugListener: function(type, msg, payload) {
		console.log({type: type, msg: msg, payload: payload});
	}
}

Handling client connection errors

In case of errors while trying to connect, an error event will be emitted by the session and the program will be terminated if it's not listened. This is how you should check for errors.

session.on('error', function(e) {
	// empty callback to catch emitted errors to prevent exit due unhandled errors
	if (e.code === "ETIMEOUT") {
		// TIMEOUT
	} else if (e.code === "ECONNREFUSED" {
		// CONNECTION REFUSED
	} else {
		// OTHER ERROR
	}
});

Connection timeout

By default the socket will be dropped after 30000 ms if it doesn't connect. A connectTimeout option can be sent when making connections with the server in order to change this setting.

Proxy protocol

Proxy Protocol v1 is now supported as an experimental feature, both for TCP4 and TCP6.

Pass enable_proxy_protocol_detection: true as server option to enable proxy protocol detection, if the option is not provided the feature is completely ignored.

  • session.remoteAddress will contain the proxied source IP.
  • session.proxyProtocolProxy will contain the proxy IP.
  • Even with proxy protocol detection enabled the server will understand non-proxied requests.
  • Security: Proxy CIDRs validation is yet to be implemented.
  • Uses findhit-proxywrap, a third party library to wrap the net/tls implementations and decode the proxy-protocol
  • header before forwarding it to the standard implementations.

Compatibility issues

  • On proxied, non-tls connections (with Nodejs < v8): Proxywrap shows some misbehaviour with the way this library inherits from the net server, the socket looses the ability to emit events. As a minor-fix, the socket.emit method is backed up and restored after the proxying to the net server, making everything work as expected.

Encodings

This smpp implementation supports 3 encodings: ASCII (GSM 03.38), LATIN1, and UCS2. data_coding for these encodings are 0x01, 0x03, and 0x08 respectively.

Default encoding for data_coding:0 is ASCII. You can change it as follows:

smpp.encodings.default = 'LATIN1';

String messages will be automatically encoded using one of these three encodings. If the SMSC you are communicating with doesn't support one of these encodings, you can simply remove it as follows:

delete smpp.encodings.ASCII;

You can also manually convert a message to a buffer and pass it as short_message or message_payload parameter to bypass automatic message encoding.

API

smpp.connect(url, [callback])

Creates a new smpp session using the specified connection url. url must be a string in this format: smpp://host:port. To establish a secure smpp connection use ssmpp as scheme like in ssmpp://host:port. If port is omitted in the url, the default port (2775 for smpp and 3550 for secure smpp) will be used. If called without arguments, smpp://localhost:2775 will be assumed.

The callback, if specified, will be added as a listener for the connect event in plain connections and secureConnect event in secure connections.

smpp.Session

This is the base object for a SMPP session. sessions can be created by calling smpp.connect() or can be created by a smpp server when a client establishes a connection to the server. In this case the server passes the session object to the 'session' event listener.

session.send(pdu, [responseCallback], [sendCallback], [failureCallback])

Sends a pdu request/response to the MC/ESME over the session. The pdu is an instance of smpp.PDU which might be either a response or a request pdu.

When sending a request pdu, pdu.sequence_number will be automatically set to the proper value.

If the pdu is a request pdu, when the relevant response is received, the optional responseCallback parameter will be invoked with the response pdu passed to it.

Optional sendCallback will be called when the pdu is successfully flushed.

Optional failureCallback will be called whenever it is not possible to write to the socket.

session.close([callback])

Closes the current session connection. If supplied, the callback is called once the session is fully closed.

session.destroy([callback])

Forcibly closes the current session connection. This aids some broken servers, that don't honor gracefull tear-down. ( Looking at you SMPPSim ) If supplied, the callback is called once the session is fully closed.

session.connect()

Can be used to reconnect a closed connection.

session.pause()

Can be used to postpone incoming pdu events untill calling session.resume().

session.resume()

Resumes the session after a call to pause().

Shortcut methods

For all smpp operations you can call methods with the same name as the operation name, which is equivalent to createing a pdu instance and then sending it over the session.

For example calling session.submit_sm(options, [responseCallback], [sendCallback], [failureCallback]) is equivalent to:

var pdu = new smpp.PDU('submit_sm', options);
session.send(pdu, responseCallback);

Event: 'connect'

Emitted when the session connection successfully is established.

Event: 'secureConnect'

The secureConnect event is emitted after the handshaking process for a secure connection has successfully completed.

Event: 'close'

Emitted when the connection is fully closed.

Event: 'error' (error)

Emitted when an error occurs. The 'close' event will be called directly following this event.

Event: 'send' (pdu)

Emitted when a pdu is being sent over the session with the pdu as the argument.

Event: 'pdu' (pdu)

Emitted upon receiving a pdu.

Event: 'unknown' (pdu)

Emitted upon receiving an unknown pdu.

Shortcut events

When a pdu is received, after emitting the 'pdu' event, an event with the same name as the operation of that pdu will also be emitted.

smpp.createServer([options], [sessionListener])

Creates a new SMPP server. The sessionListener argument is automatically set as a listener for the 'session' event. If options include key and cert, a TLS secured server will be created. Include rejectUnauthorized: false to disable the certificate validation.

smpp.Server

The base object for a SMPP server created with smpp.createServer(). It is a child class of node's net.Server.

server.listen([port], [host], [callback])

Begin accepting connections on the specified port and host. If port is omitted 2775 will be used. If the host is omitted, the server will accept connections directed to any IPv4 address.

This function is asynchronous. The last parameter callback will be called when the server has been bound.

Event: 'session' (session)

Emitted when a new session connection is established. session is an instance of smpp.Session.

for other server methods/events documentations see node's net.Server docs.

smpp.PDU

This is the base object for a PDU request or response.

new smpp.PDU(command, [options])

Creates a new PDU object with the specified command and options.

options is a list of parameters acceptable by the specified command. The name of the parameters are equivalent to the names specified in SMPP specification v5.0. The order of the parameters doesn't matter. If you don't specify a required parameter in options a default value (usually null or 0 for integers) will be used.

For the type of the parameters note the following rules:

  • For Integer parameters (no matter what the length is) you must specify a value of type number in JavaScript.
  • For Octet-String and COctet-String parameters you can specify either a Buffer or a String.
  • For the fields that accept SMPP Time Format (broadcast_end_time, schedule_delivery_time, validity_period, final_date) you can specify a Javascript Date instance which will be automatically converted to a SMPP absolute time string. For relative times you don't need to specify the whole string, specifying a portion of it is enough. for example '0430' will be converted to '000000000430000R'.
  • For short_message and message_payload fields you can specify a buffer or a string or an object containing udh and message properties, while udh is a buffer and message is either a string or a buffer. strings will be automatically encoded using ASCII, LATIN1, or UCS2 depending on their characters. data_coding (if not specified) will be automatically set to 0x01, 0x03, or 0x08 for ASCII, LATIN1, and UCS2 encodings respectively. Also UDH indicator bit in esm_class is automatically set if udh exists.
  • sm_length parameter is not needed. It will be automatically set depending on the length of the short_message.
  • dest_address parameter in submit_multi operation must be an array of objects containing either dest_addr_ton, dest_addr_npi and, destination_addr properties or dl_name property for SME addresses or Distribution Lists respectively.
  • unsuccess_sme parameter in submit_multi_resp operation must be an array of objects containing dest_addr_ton, dest_addr_npi, destination_addr and, error_status_code properties.
  • number_of_dests and no_unsuccess parameters are not needed. They will be automatically set depending on the dest_address and unsuccess_sme parameters respectively.
  • TLV parameters which can be specified multiple times (e.g. broadcast_area_identifier), must be specified as an array, even if you want to specifiy just one item.

pdu.isResponse()

Returns true if the pdu is a response pdu, otherwise returns false;

pdu.response([options])

For a request pdu, calling response() creates and returns a response pdu for that request.

For an unknown pdu, response() creates and returns a generic_nack pdu.

session.on('submit_sm', function(pdu) {
	var msgid = .... ; // generate a message_id for this message.
	session.send(pdu.response({
		message_id: msgid
	}));
});

session.on('unbind', function(pdu) {
	session.send(pdu.response());
	session.close();
});

session.on('enquire_link', function(pdu) {
	session.send(pdu.response());
});

Upgrade notes

upgrade to version 0.6.0

  • Support for Nodejs < v4 (2015) has been dropped due compatibility issues with findhit-proxywrap library
  • Proxy protocol v1 support has been added as an experimental feature. Disabled by default, will be completely ignored if not enabled.

Roadmap

  • Add some usage examples (e.g client, server, and cluster examples)

License

node-smpp is released under the MIT license.

node-smpp's People

Contributors

0leg0 avatar buraktamturk avatar daper avatar dragomir-ivanov avatar elenduuche avatar farhadi avatar humaidk2 avatar juliangut avatar peter-vasarhelyi avatar rimantaseskimi avatar rmruano avatar tsypa avatar velichkov avatar xaka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-smpp's Issues

Using TLV params in long sms

Can you show me a simple example where you are using TLV params: sar_total_segments, sar_segment_seqnum, sar_msg_ref_num. When i try to use this options i have not some informations and errors.
P.S. How i can send a long sms without UDH?

SMPP-Not able to send unicode message.

Hi @farhadi ,
Need your help.
I am trying to send uni code message from node.js using your library.
I have set payload as :
var payload = {
destination_addr: '919999999999',
short_message: 'ರನ್!',
source_addr: 'IM-DEMO',
registered_delivery: '0',
data_coding: 8,
};
and submitting this payload.But unicode message is not properly sent to SMP3 server.It is receiving as some weird text.Please help.

Need to send Bulk SMS

Is it possible to send Bulk SMSs using submit_multi method? I tried using your API but no luck :( . If possible to could you please share a code snippet to send Bulk SMS?

TLV Data

I have your sample code which works fine with one SMPP server but in another case I am have having a problem. This is what I have:

var smpp = require('smpp');
var session = smpp.connect('smpp_server', 2775);
session.bind_transceiver({
    system_id: 'smppclient1',
    password: 'password'
}, function(pdu) {
    if (pdu.command_status == 0) {
        // Successfully bound
        session.submit_sm({
            destination_addr: '8475551212',
            short_message: 'Hello!'
        }, function(pdu) {
            if (pdu.command_status == 0) {
                // Message successfully sent
                console.log(pdu.message_id);
            }
        });
    }
});

Turns out I need to send TLV like this one:

abc42xyz_operator,   0x1520,1,5, 5,0x03,CUSTMR_13914533_TESTIPC_111_D

I looked at the GitHub page and I see you mention TLV as an Array but I don't see how it would be put into the javascript.

I see this in smpp.js but I am not sure how to apply that to the TLV:

exports.addTLV = function(tag, options) {
    options.tag = tag;
    defs.tlvs[tag] = options;
    defs.tlvsById[options.id] = options;
};

Connection always on

Hi, there is any way to keep a connection opened? I have tried using setKeepAlive on the session socket returned by smpp.connect() without luck.

Thanks in advance!

Wrong mapping of ASCII coding

i try decode char: 0x40 with data_coding: 0 which is the '@' in ASCII table, but decode to '¡' when using encodings['ASCII'].decode()

i found ASCII decode using this table

encodings.ASCII = { // GSM 03.38
    chars: '@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞ\x1BÆæßÉ !"#¤%&\'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà',

is it decoded ASCII data using GSM 03.38 table?

CheckAsysncUserPass Is Not Defined

var smpp = require('smpp');
var server = smpp.createServer(function(session) {
session.on('bind_transceiver', function(pdu) {
// we pause the session to prevent further incoming pdu events,
// untill we authorize the session with some async operation.
session.pause();
checkAsyncUserPass(pdu.system_id, pdu.password, function(err) {
if (err) {
session.send(pdu.response({
command_status: smpp.ESME_RBINDFAIL
}));
session.close();
return;
}
session.send(pdu.response());
session.resume();
});
});
});
server.listen(2775);

// Using This to create server please Hellp

Mismatch between data_coding and short_message.message after decode

Receiving an message submit_sm of this type:

new smpp.PDU('submit_sm', {
     'data_coding': 8,
     'short_message': new Buffer("0043006f0043006f0043006f0043006f0043006f", "hex")
 });

the server decodes it with filters.message.decode (in defs.js) and decodes the message from UCS2 without changing data_coding field.
So we have 'data_coding': 8 and short_message coded as Buffer("436f436f436f436f436f", "hex"), that is not UCS2 coding, is it ok?
If we have to store the decoded PDU without re-encoding, the data_coding is wrong...

Cluster mode?

I need to run several instances of the application.
How can i use node-smpp in the cluster mode (manually or for example through pm2)? Or maybe use any loadbalancer (haproxy)?

Add auto close with enquire link support for server

enquire link event is used to keep the server alive. In most servers this is defined with a timer. Eg: 60s where users must send a enquire_link to avoid the close of the session.

This could be integrated in this module with a config option. Since this feature will be the same for all the user.

[Question] Anyone using this plugin with mBlox API ?

Does any of you tried this plugin with the mBlox SMPP interface ?

I know mBlox SMPP gateway supports v3.4 specification and should be backward compatible with SMPP v3.3, but I haven't try yet. Will this plugin work?

Why message states are incomplete

According to the SMPP 3.4 docs, there are 10 message states:

0 SCHEDULED The message is scheduled for later sending.
1 ENROUTE The message is enroute.
2 DELIVERED The message was successfully delivered.
3 EXPIRED The SMSC was unable to deliver the message in a specified amount of time.For instance when the phone was turned off.
4 DELETED The message was deleted.
5 UNDELIVERABLE The SMS was unable to deliver the message.For instance, when the number does not exist.
6 ACCEPTED The SMS was accepted and will be send.
7 UNKNOWN Unknown error occured.
8 REJECTED The message was rejected.The provider could have blocked phonenumbers in this range.
9 SKIPPED The message was skipped.

But, only 6 of them are provided in defs.js file.

Cannot set bytes in UDH header larger than 127

I am bulding message_payload by concatenating bytes in the following way:

// UDH header
var session_id = new Buffer(4);
session_id.writeUInt8(5, 0);
session_id.writeUInt8(0, 1);
session_id.writeUInt8(3, 2);
session_id.writeUInt8(227, 3);

var message_part1 = new Buffer([2, 1]);
var message_part2 = new Buffer([2, 2]);

// message parts
var message1 = Array(153).join("A")
var message2 = Array(153).join("B")

var part1 = new Buffer(message1);
var part2 = new Buffer(message2);

// Setting message payload field inside the deliver_sm function
message_payload: session_id + message_part2 + part2

Setting byte to be larger than 127 causes trouble and the whole message gets messed up by encoding message body to UCS2 encoding

According to specs (3GPP TS 23.040) sequence number of a message can have range from 0 to 255, however I am not able to set it in node-smpp.

Am I misusing the library or is it a bug?

EDIT: I have tried to concatenate buffer (Buffer.concat) before assigning to message_payload and verifying it with Buffer.isBuffer function and the value I am providing to message_payload is a buffer. It looks that message_payload has a filter which checks whether field value is a buffer and should use unmodified value if true. But it seems it converts it anyway.

var bufferArr = [session_id, message_part2, part2];
var concatenatedBuf = Buffer.concat(bufferArr);

message_payload: concatenatedBuf

EDIT: I have removed filters.message for message_payload in defs.js and it worked, so the problem is somewhere in filters.message function.

toBuffer throws an exception for PDUs that cannot have bodies

Hi there,

As per SMPP specification the submit_sm_resp command cannot have body if the status is not a zero. It's not respected by library and so you end up with:

../node_modules/smpp/lib/defs.js:70
                        value.copy(buffer, offset);
                              ^
TypeError: Cannot call method 'copy' of undefined
    at Object.types.cstring.write (../node_modules/smpp/lib/defs.js:70:10)
    at PDU.toBuffer (../node_modules/smpp/lib/pdu.js:136:20)
    at Session.send (../node_modules/smpp/lib/smpp.js:73:24)
    at Session.onPdu (../main.js:152:23)
    at Session.emit (events.js:95:17)
    at Session._extractPDUs (../node_modules/smpp/lib/smpp.js:52:8)
    at Socket.<anonymous> (../node_modules/smpp/lib/smpp.js:29:8)
    at Socket.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:748:14)
    at Socket.emit (events.js:92:17)

I'm not sure yet what would be the best solution, but as a workaround i had to add a check to toBuffer method and skip encoding.

We probably should add some kind of flag to commands that not allow the body when status is not a zero and add support for it to toBuffer method.

query_sm

Hi!!

When I use query_sm always return generic_nack.

pdu { command: 'query_sm',
command_length: 41,
command_id: 3,
command_status: 0,
sequence_number: 2,
message_id: '9066579236',
source_addr_ton: 1,
source_addr_npi: 1,
source_addr: '506848xxxxx' }

pdu { command_length: 16,
command_id: 2147483648,
command_status: 3,
sequence_number: 2,
command: 'generic_nack' }

Memory leak

So it appears that when returning a submit_sm_resp PDU internally these messages are held in memory and then delivered to the client when available, if a client disconnects then some of these messages remain in memory. If a client is sending more messages in than it can receive, these messages build up on the server and it crashes

Trouble with sending long message in non-ASCII

I'm trying to send a long message but something going wrong and I see a stack trace:

TypeError: value is out of bounds
    at TypeError (<anonymous>)
    at checkInt (buffer.js:784:11)
    at Buffer.writeUInt8 (buffer.js:794:5)
    at Object.types.buffer.write (/home/qfox/repos/selfcare-tools/node_modules/smpp/lib/defs.js:84:11)
    at PDU.toBuffer (/home/qfox/repos/selfcare-tools/node_modules/smpp/lib/pdu.js:137:20)
    at Session.send (/home/qfox/repos/selfcare-tools/node_modules/smpp/lib/smpp.js:71:24)
    at Session.createShortcut [as submit_sm] (/home/qfox/repos/selfcare-tools/node_modules/smpp/lib/smpp.js:94:15)
    at Object.send (/home/qfox/repos/selfcare-tools/lib/smpp.js:133:24)
    at module.exports.actions.check4g (/home/qfox/repos/selfcare-buddy/routes/api/usim.js:24:14)
    at callbacks (/home/qfox/repos/selfcare-buddy/node_modules/express/lib/router/index.js:164:37)

'Абвгдеёжзий, кл мнопрс туфхцчшщъы ab ьэ юяабв гдеёжзий к лмноп рстуфхцчшщ. ъыьэюяабвгде ёж зийклмнопрст уфхцчшщ ъыьэю: abc.defghi' is throwing that error while
'Абвгдеёжзий, кл мнопрс туфхцчшщъы ab ьэ юяабв гдеёжзий к лмноп рстуфхцчшщ. ъыьэюяабвгде ёж зийклмнопрст уфхцчшщ ъыьэю: abc.defg' is works fine.

Is it a bug or i've just missed something? Thanks.

Session close event is emitted after a successful bind_transceiver method

session.bind_transceiver({
    system_id: 'system_id',
    password: 'password'
}, function (pdu) {
    if (pdu.command_status != smpp.errors.ESME_ROK) {
        console.error('SMPP bind transceiver error: ' + pdu.command_status);
        process.exit(1);
    } else {
        console.log('Connected');
    }
});

session.on('close', function () {
    console.log('SMPP connection is closed');
});

Output: Connected, SMPP connection is closed

Why is the session close event emitted after a successful bind_transceiver method?

Error in incoming message decoding

Hello,
When Node-smpp receives sms, it replaces @ character with 0. I suppose it's because filters.message.decode() function but i'm not sure.

Do you have the same problem ?

Regards,
Hasan.

Session doesn't emit error event (or any events) when connection breaks

Session doesn't emit error event (or any events) when connection breaks.

I run my app which basically does this:

  • Starts session (successfully)
  • Binds transciever (sccessfully)
  • Sets timeout for enquire_link

After that I disconnect network, I continue enquiring link and submitting SMSes, it sends PDUs, doesn't receive any response, doesn't emit any error.

How can I detect network absence?

Update release

Hello.
The last commit with bug-fix (268b055) is not included in the last release 0.1.0 and doesn't install from npm repository. Please update release.

Cannot send SMS with over 255 chars.

Hi,
I got an issue sending SMS when I send an SMS with 280 chars. Is it possible to send message over 255 chars, If yes, Please help me how to fix it or show me what did I do wrong. Thank sa lot.

Here is my code to submit_sm:
session.submit_sm({
source_addr: 'TEST',
destination_addr: number,
short_message: message
}, function(pdu) {
if (pdu.command_status == 0) {
console.log("- submit_sm success",pdu.message_id);
session.close();
}
else{
console.log("- submit_sm fail:", pdu);
session.close();
}
});

Here is error log:
0|DMV-VNP: | TypeError: "value" argument is out of bounds
0|DMV-VNP: | at checkInt (buffer.js:1026:11)
0|DMV-VNP: | at Buffer.writeUInt8 (buffer.js:1074:5)
0|DMV-VNP: | at Object.write (/home/dmvit/testSMS/SMS/node_modules/smpp/lib/defs.js:86:11)
0|DMV-VNP: | at PDU.toBuffer (/home/dmvit/testSMS/SMS/node_modules/smpp/lib/pdu.js:175:20)
0|DMV-VNP: | at Session.send (/home/dmvit/testSMS/SMS/node_modules/smpp/lib/smpp.js:97:24)
0|DMV-VNP: | at Array.<anonymous> (/home/dmvit/testSMS/SMS/routes/index.js:42:18)
0|DMV-VNP: | at Session._extractPDUs (/home/dmvit/testSMS/SMS/node_modules/smpp/lib/smpp.js:69:40)
0|DMV-VNP: | at emitNone (events.js:86:13)
0|DMV-VNP: | at Socket.emit (events.js:185:7)
0|DMV-VNP: | at emitReadable_ (_stream_readable.js:432:10)
0|DMV-VNP: | at emitReadable (_stream_readable.js:426:7)
0|DMV-VNP: | at readableAddChunk (_stream_readable.js:187:13)
0|DMV-VNP: | at Socket.Readable.push (_stream_readable.js:134:10)
0|DMV-VNP: | at TCP.onread (net.js:548:20)

Delivery reports

Is it possible to receive delivery reports in an asynchronous manner? I have tried the on pdu event but got nothing

TypeError: value is out of bounds

buffer.js:705
    throw TypeError('value is out of bounds');
          ^
TypeError: value is out of bounds
    at TypeError (<anonymous>)
    at checkInt (buffer.js:705:11)
    at Buffer.writeUInt32BE (buffer.js:748:5)
    at PDU.<anonymous> (/var/node-demo/node_modules/smpp/lib/pdu.js:122:10)
    at Array.forEach (native)
    at PDU._initBuffer (/var/node-demo/node_modules/smpp/lib/pdu.js:121:16)
    at PDU.toBuffer (/var/node-demo/node_modules/smpp/lib/pdu.js:144:20)
    at Session.send (/var/node-demo/node_modules/smpp/lib/smpp.js:74:24)
    at Session.<anonymous> (/var/node-demo/server-smpp.js:25:11)
    at Session.emit (events.js:95:17)

Node: v0.10.31
"smpp": "^0.1.0"

ECONNREFUSED

Hi,

Thanks for the module. I am getting the below error. Please guide me on this.

events.js:72
throw er; // Unhandled 'error' event
^
Error: connect ECONNREFUSED
at errnoException (net.js:901:11)
at Object.afterConnect as oncomplete

Thanks,
Sabari.

Sending binary messages

To send binary messages is sufficient to establish the value data_coding - 4? I get an error:

[TypeError: Can not read property 'length' of indefinedsch

subtit_sm:
session.submit_sm({
destination_addr : message.phone,
message_payload : message.data,
registered_delivery : 1,
data_coding : 4
}, function(pdu) {
if (pdu.command_status == 0) {
...
} else {
...
}
});

https://gist.github.com/xorumtes/19f1c3aeb2a7708037ca

Data Coding Scheme (DCS)

Is it possible to use DCS=0x00?

SMPP server administrator asks to use explicitly DCS=0 for regular SMS instead of DCS=1 (SMPP Data Coding Scheme: IA5 (CCITT T.50/ASCII (ANSI X3.4) (0x01)), which is default for latin-based SMS in my case.

Multipart SMS works fine (UDH packets), meaning it's related to characters limits on SMSC according to encoding, but I cannot use this flow as every MT SMS is chargeable.

TLVs in _resp with non-zero command_status

According to SMPP documentation, tlvs may be returned in case of command failures, for example:
4.2.1.2 submit_sm_resp Syntax
4.2.5 Message Submission Response TLVs
The following table contains TLVs that can be returned in a submit_sm_resp or data_sm_resp PDU. All TLVs are relevant to transaction message mode only (ref. 4.2.10.4)
...
delivery_failure_reason Include to indicate reason for delivery failure

current code prevents this
sadly, wireshark also doesn't dissect these parameters in _resps

session.submit_multi

session.submit_multi({
dest_address: [
{destination_addr: 'DESTINATION NUMBER 1'},
{destination_addr: 'DESTINATION NUMBER 2'},
// ...
],
short_message: 'Hello!'
});

I did,

PDU {
command_length: 32,
command_id: 2147483681,
command_status: 13,
sequence_number: 2,
command: 'submit_multi_resp',
message_id:* 'Unknown command.' }* --> I get the error

I would be glad if a large sample of code or a large document, Greetings

message.decode() incorrect detects encoding

defs.filters.message.decode() function detects encoding simply encoding = this.data_coding & 0x0F;
But according documentation this is incorrect when data_coding carriers more information than only encoding ftp://www.3gpp.org/tsg_t/TSG_T/TSGT_04/Docs/PDFs/TP-99127.pdf

What about to change line encoding = this.data_coding & 0x0F; to

var encoding = 0;

if (this.data_coding <= 0x0E) {    
	encoding = this.data_coding & 0x0F;
}
// Non-MWI Mode 1
else if ((this.data_coding & 0xF0) == 0xF0) {
	encoding = (this.data_coding & 0x04) ? consts.ENCODING.BINARY : consts.ENCODING.ASCII; // grab bit 2
}
// Non-MWI Mode 0
else if ((this.data_coding & 0xC0) == 0x00) {
	encoding = (this.data_coding & 0x0C) >> 2; // grab bit 3,2
	if (encoding == 0) {
		encoding = consts.ENCODING.ASCII;
	} else if (encoding == 1) {
		encoding = consts.ENCODING.BINARY;
	} else if (encoding == 2) {
		encoding = consts.ENCODING.UCS2;
	} else {   // 3 is reserved
		//encoding = consts.ENCODING.ASCII;
	}
}
// MWI Mode
else if ((this.data_coding & 0xC0) == 0xC0) {
	encoding = ((this.data_coding & 0xE0) == 0xE0) ? consts.ENCODING.UCS2 : consts.ENCODING.ASCII;
}

Binary Message

How to send a specific UDH?

As a practical example, say I want to create a UDH to send a WAP Push, where the standard destination port for WAP pushes is 2948, the UDH will be:

06 05 04 0B 84 23 F0 

where:

  • 06 means “read the following 6 bytes”
  • 05 is the format for numbers, in this case hexadecimal numbers
  • 04 will tell the UDH that each port is represented using 4 character
  • 0B84 is the destination port, 2948 (decimal representation) or 0B84 (hexadecimal representation)
  • 23F0 is the source port, 9200 (decimal representation) or 23F0 (hexadecimal representation).

I've tried playing around with this example but can't quite figure out how to get what I need:

I will be sending a string in the payload.

This is an example of message:

xample message: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY00
Binary SMS with user data unencoded. Src port 8880 and Dest port is 8888.

PID - 0x00
DCS- 0x00
UDH- 0x0605040B8423F0
UD - 0x6162636465666768696A6B6C6D6E6F707172737475767778797A4142434445464748494A4B4C4D4E4F505152535455565758593030

Message submit failed with status ESME_RSUBMITFAIL

Hello, Team I tried to send an SMS through the SMPP and I am getting this error,

ESME_RSUBMITFAIL with the status code, command_status: 69

Here is the code snippet,

var smpp = require('smpp');
var session = new smpp.Session({host: '150.120.36.58', port: 2775});
var didConnect = false;

session.on('connect', function(){
  didConnect = true;

  session.bind_transceiver({
      system_id: 'my-system-id',
      password: 'my-password',
  }, function(pdu) {
    console.log('pdu status', lookupPDUStatusKey(pdu.command_status));
    // the above method is for handling errors
    if (pdu.command_status == 0) {
        console.log('Successfully bound')
    }
  });
})

function lookupPDUStatusKey(pduCommandStatus) {
  for (var k in smpp.errors) {
    if (smpp.errors[k] == pduCommandStatus) {
      return k
    }
  }
}

function connectSMPP() {
  console.log('smpp reconnecting');
  session.connect();
}

session.on('close', function(){
  console.log('smpp disconnected')
  if (didConnect) {
    connectSMPP();
  }
})

session.on('error', function(error){
  console.log('smpp error', error)
  didConnect = false;
})


function sendSMS(from, to, text) {

  
  from = '+' + from.toString();
  to   = '+' + to.toString();
  
  session.submit_sm({
      source_addr:      from,
      destination_addr: to,
      short_message:    text
  }, function(pdu) {
    console.log('sms pdu status', lookupPDUStatusKey(pdu.command_status));
      if (pdu.command_status == 0) {
          // Message successfully sent
          console.log(pdu.message_id);
      }
  });
}

sendSMS(fromNumber, toNumber, 'text')

Now, when I send the message I am getting this error, ESME_RSUBMITFAIL with the status code 69

There is no particular documentation on what to do on this, nor a particular response.

Sorry, if this should not be asked here. But, I am struck. :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.