Coder Social home page Coder Social logo

go-smpp's People

Contributors

0x19 avatar aleksi avatar amus-sal avatar cesarrodrig avatar codemonkeykevin avatar fiorix avatar haisum avatar hungdinhts avatar levashovms avatar lucianjon avatar mcswitch avatar michalm86 avatar nezorflame avatar pydima avatar temoto avatar vagruchi avatar vdvsx avatar wovan avatar yektaleblebici avatar zaikin 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

go-smpp's Issues

Marshaling/Unmarshaling PDU to/from JSON

I am looking to represent PDUs as JSON, and the most simple implementation doesn't work since codec's fields are private:

p := pdu.NewDeliverSM()
fields := p.Fields()
fields.Set(pdufield.ShortMessage, "ShortMessage")
bytes, err := json.Marshal(p)
log.Println(string(bytes))

Outputs: {}. I implemented my own func (pdu *codec) MarshalJSON() ([]byte, error) and it works only if I don't encode TLVMap, since it returns unsupported type. I don't mind this error since I can implement its own MarshalJSON() as well.

The problem I am facing is with UnmarshalJSON(). Since I am trying to get back a pdu.Body and it is an interface, I need to unmarshal first to the underlying type (codec) but it is a private struct. What do you think about exposing Codec and its fields? Out of curiosity, what was the purpose of having pdu.Body as an interface?

How do you set address range

Hi

How do you set the address range, an upstream smpp server requires us to set the address range as 100 on the bind.

How is this achieved in the code.

These are the parameters I have to connect with:

  • Host
  • Port
  • Addressrange
  • SystemID
  • NPI : ISDN
  • TON : internation
  • SystemType: SMS

*Apologies, I am still finding my way around Go, (the obvious might not be that obvious to me right now)

Map.Set() doesn't cover for RegisteredDelivery field

The method Map.Set() has a switch statement on the type of the value passed, but in the case of RegisteredDelivery the type is DeliverySetting which will not be covered by this switch causing it to not be set in the map. We can either change the DeliverySettings to uint8 or add the extra type case in the switch statement.

Windowed mode & automatic reconnection

  1. Does this library allows to send submit_sm messages with a window size greater than 1? For example, if the output window size is set to 10, I am allowed to send up to 10 submit_sm pdus before having the submit_sm_resp received. This mode can increase throughput to smsc substantially.
  2. What about automatic reconnection of dropped smpp connections to smsc?

Many thanks!

alphabetical Sender

Dears Am not able to send a msg to anyone if the Src was letters instead of numbers
Can you guide me through the solution pleaaase 🥺

Gracefully stop

Hello,

Here is my code that initiate the connection to the SMPP server :

var trx *smpp.Transceiver

func Bind() error {
	trx = &smpp.Transceiver{
		Addr:    "localhost:2375",
	}
	conn := trx.Bind()
	if connStatus := <-conn ; connStatus.Status() != smpp.Connected {
		return connStatus.Error()
	}
	return nil
}

func Stop() error {
	return trx.Close()
}

I call the Stop() function when I catch the Interrupt signal.
I'd like to send an Ubind command to the SMPP server before closing the connection.
Is there a way to do that ?
It would be great to have something like that :

func Stop() error {
	return trx.Unbind()
}

Thanks

ошибка подключения SMPP

Можете подсказать делаю пакет для API своего https://play.golang.org/p/ES7Fv1tuzJz . Но ошибка идетъ
err con
2018/02/06 17:49:59 SMPP connection status: Connected
err con
2018/02/06 17:50:33 SMPP connection status: Connected
err con
2018/02/06 17:51:22 SMPP connection status: Connected

в связи с чем такая ошибка может возникать

Standart Conn interface.

Why we have 2 different Conn interfaces(smpptest.Conn and smpp.Conn). And why we can't use simple net.Conn?

SUBMIT_SMRESP not received in the callback.

          In transmitter.go file  rc != nil,which eventually not calling the f(p). After changing to else if to if ,submit_smresp event is being received in the transceiver callback. Could you please help me why its being written like this? 
          seq := p.Header().Seq
	t.tx.Lock()
	rc := t.tx.inflight[seq]
	t.tx.Unlock()
	if rc != nil {
		rc <- &tx{PDU: p}
	} else if f != nil {
		f(p)
	}

Submitting custom PDU from Transmitter

I'm wondering is there a way to submit a custom PDU from Transmitter, not using predefined Submit and SubmitLongMsg methods?

E.g getting DELIVER_SM pdu, changing header ID to SUBMIT_SM and pushing it back to SMSC.

Submitting to multiple recipients and returned message ID

From the SMSC I'm connecting to (not sure which SMSC) when submitting to multiple recipients Response Message contains a single ID, but when delivery report is received it has different message IDs for each recipient.

Is there a way to retrieve message ID for each recipient?

Implements generic_nack on ESME side

Hello,

How could I send a generic_nack PDU to SMS-C when my ESME receive an unsupported PDU ?
Here is the handler that I provide to my Transceiver :

func handle(p pdu.Body) {
		switch p.Header().ID {
		case pdu.DeliverSMID:
			logger.Infof("Received DeliverSM PDU")
		case pdu.UnbindID:
			logger.Infof("Received Unbind PDU from SMS-C... shutting down !")
			stopGracefully()
		default:
			nack := pdu.NewGenericNACK()
			// TODO: send nack ... but how ?
			logger.Errorf("Received unknown pdu: %+v", p)
		}
	}

Any idea ?

Thanks !
Emmanuel

Long message multi-part tracking

Hi all,

Noticed that the library, when sending long messages, only returns the data for the last part of the multi-part message. This is due to the function only returning a single ShortMessage in the response:

func (t *Transmitter) SubmitLongMsg(sm *ShortMessage) (*ShortMessage, error) {

I would like to extend this function to return all parts of the multi-part message:

func (t *Transmitter) SubmitLongMsg(sm *ShortMessage) ([]ShortMessage, error) {

We could then keep track of the delivery status (via Delivery-Receipts) of each part of the multi-part message.

ShortMessage as request and response

Hi,

I am going over SubmitLongMsg and needed access to all response PDUs, but only the last is returned. What was the reasoning behind having ShortMessage working both as a request and response struct? Why only return the last response PDU?

Thanks!

[ENHANCEMENT] SemVer tags

I think we need to mark some milestone changes with SemVer tags like v1.2.3.
This would help people with dependency managers like golang/dep easily control which version of the library they prefer to take.

short_message in DeliverSM scrambles when data_coding is 0x08

When receiving DeliverSM of a UCS encoded message, short_message gets decoded using UCS2 and gets corrupt. A solution is, not to decode short_message when decoding PDU and let user decide what to do.

Current output of short_message pdu field:
selection_078

After I removed automatic decoding:
selection_079

Datacoding type for Wappush

First of all, Thank you for this awesome plugin.
Is it possible to send WapPush message if this plugin?
I read that you need to set the datacoding to 245 but from the 3 available datacoding types on this plugin i am not sure which one it is if it is any of these at all or is there a way i can set up the Text parameter of the message to switch my need?

Thank you

Set UDH in the sender SMS

how to set UDH (user data header) to Transmitter ??
because there is no param in the &smpp.ShortMessage{} ??

how to solve this ??

Sending pdu.Body

From my understanding it's not yet possible to write anything over the wire if you use a receiver och transceiver which makes things difficult. Having the possibility to a HandlerFunction is great, but it's not that helpful if you have no way of replying back to the incoming PDU's.

One example being a transceiver where you use tx.Submit(...) which is great how it's blocking and taking care of responses and response matching for you, but when the DeliverSM finally arrives in the handler there is no way to reply to this with an DeliverSMResp (non that I've found, please correct me if I'm wrong).

My suggestion is to make all connections (Transmitter, Receiver and Transceiver) implement the Writer interface, that way the clients can respond to DeliverSM, send their own DeliverSM (acting as a server) and have their own EnquireLink handling in the future (right now EnquireLink only seems to work if the client initiates it; but the client will never reply to an enquire link from the server).

Problems using test server

Hi,

I am trying to use (and expand) the server in smpptest. I ran a server and took the sample code for running a client. When I try to submit a ShortMessage with transmitter.Submit(), I get the error unexpected PDU ID: SubmitSM which makes sense since the server is only responding back with the same PDU in the EchoHandler.

In the EchoHandler, I modified the ID of the PDU to be SubmitSMRespID by accessing the headers of the request PDU and when I send it back, the client times out. I pinpointed the problem to be in list.go:112 where it complains: not enough data for tag 0x0: want 29554, have 22.

I would imagine that messing directly with the headers could be a bad idea, so I went ahead and used the function NewSubmitSMResp() from types.go to build a the appropriate response in the EchoHandler. When I sent it back, the client just times out again with no response and I can't pinpoint the cause.

EchoHandler looks like this:

func EchoHandler(conn Conn, m pdu.Body) {
    // Approach #1: Send it back as-is

    // Approach #2: Modify the ID directly
    // m.Header().ID = pdu.SubmitSMRespID

    // Approach #3: Send a new response
    // m = pdu.NewSubmitSMResp()

    err := conn.Write(m)
    if err != nil {
        fmt.Println(err)
    }
}

What am I doing wrong? Or am I missing to implement something? I am quite knew to SMPP so bare with me if there are obvious mistakes I didn't spot.

Thanks!

smpp server not accepting multiple clients

Hi,
I want to connect multiple clients to server but if one client is connected, unable to connect another client (unable to bind ). Any suggestions please.
Error if more than one client connects :

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x7a18af]

goroutine 1 [running]:
main.smpp_connection(0xc0000143c0, 0xc, 0xbb8, 0xc000014420, 0x6, 0xc000014470, 0x6, 0x8)

Thanks in advance

is it possible receive USSD and response?

Example
I am calling *933*Hello#, mobile operator sends to endpoint.
Endpoint responses "Hi there" to mobile operator and I receive "Hi There"
is possible to do USSD with go-smpp?

unexpected PDU ID: Deliver SM

Hello, thx for you job.

i have this problem.

i receiving response error - unexpected PDU ID: Deliver SM

there is source

func (t *Transmitter) submitMsg(sm *ShortMessage, p pdu.Body, dataCoding uint8) (*ShortMessage, error) {
	f := p.Fields()
	f.Set(pdufield.SourceAddr, sm.Src)
	f.Set(pdufield.DestinationAddr, sm.Dst)
	f.Set(pdufield.ShortMessage, sm.Text)
	f.Set(pdufield.RegisteredDelivery, uint8(sm.Register))
	// Check if the message has validity set.
	if sm.Validity != time.Duration(0) {
		f.Set(pdufield.ValidityPeriod, convertValidity(sm.Validity))
	}
	f.Set(pdufield.ServiceType, sm.ServiceType)
	f.Set(pdufield.SourceAddrTON, sm.SourceAddrTON)
	f.Set(pdufield.SourceAddrNPI, sm.SourceAddrNPI)
	f.Set(pdufield.DestAddrTON, sm.DestAddrTON)
	f.Set(pdufield.DestAddrNPI, sm.DestAddrNPI)
	f.Set(pdufield.ESMClass, sm.ESMClass)
	f.Set(pdufield.ProtocolID, sm.ProtocolID)
	f.Set(pdufield.PriorityFlag, sm.PriorityFlag)
	f.Set(pdufield.ScheduleDeliveryTime, sm.ScheduleDeliveryTime)
	f.Set(pdufield.ReplaceIfPresentFlag, sm.ReplaceIfPresentFlag)
	f.Set(pdufield.SMDefaultMsgID, sm.SMDefaultMsgID)
	f.Set(pdufield.DataCoding, dataCoding)
	resp, err := t.do(p)
	if err != nil {
		return nil, err
	}
	sm.resp.Lock()
	sm.resp.p = resp.PDU
	sm.resp.Unlock()
	if resp.PDU == nil {
		return nil, fmt.Errorf("unexpected empty PDU")
	}
	if id := resp.PDU.Header().ID; id != pdu.SubmitSMRespID {
		return sm, fmt.Errorf("unexpected PDU ID: %s", id)
	}
	if s := resp.PDU.Header().Status; s != 0 {
		return sm, s
	}
	return sm, resp.Err
}

may be problem, that outgoing sequence id has same sequence id that and incoming Deliver SM

func (t *Transmitter) do(p pdu.Body) (*tx, error) {
	t.cl.Lock()
	notbound := t.cl.client == nil
	t.cl.Unlock()
	if notbound {
		return nil, ErrNotBound
	}
	if t.cl.WindowSize > 0 {
		inflight := uint(atomic.AddInt32(&t.tx.count, 1))
		defer func(t *Transmitter) { atomic.AddInt32(&t.tx.count, -1) }(t)
		if inflight > t.cl.WindowSize {
			return nil, ErrMaxWindowSize
		}
	}
	rc := make(chan *tx, 1)
	seq := p.Header().Seq
	t.tx.Lock()
	t.tx.inflight[seq] = rc
	t.tx.Unlock()
	defer func() {
		t.tx.Lock()
		delete(t.tx.inflight, seq)
		t.tx.Unlock()
	}()
	err := t.cl.Write(p)
	if err != nil {
		return nil, err
	}
	select {
	case resp := <-rc:
		if resp.Err != nil {
			return nil, resp.Err
		}
		return resp, nil
	case <-t.cl.respTimeout():
		return nil, ErrTimeout
	}
}

may be here deleting happen later

defer func() {
		t.tx.Lock()
		delete(t.tx.inflight, seq)
		t.tx.Unlock()
	}()

sorry for my bad english, can you help ?
thank you

client.BindFunc blocks on client.Read (resource leak)

Using:

tx := &smpp.Transceiver{
  ...
}
tx.Bind()

on unstable connection leads to memory leak (sorry for line numbers - issue encountered on old github.com/zpas-lab/go-smpp fork):

github.com/zpas-lab/go-smpp/smpp.(*client).Read(0xc4201264d0, 0xc420e62f58, 0xc40000ac38, 0xc420bdbde8, 0x0)
        github.com/zpas-lab/go-smpp/smpp/client.go:170 +0xf8
github.com/zpas-lab/go-smpp/smpp.(*Transmitter).handlePDU(0xc4202d3b68, 0xc4205248a0)
        github.com/zpas-lab/go-smpp/smpp/transmitter.go:103 +0x44
created by github.com/zpas-lab/go-smpp/smpp.(*Transceiver).bindFunc
        github.com/zpas-lab/go-smpp/smpp/transceiver.go:74 +0x43a

For current code would be:

client.go:225
transmitter.go:118
transceiver.go:80

This happens because transceiver calls go client.Bind(), in which:

  1. l.130-138: connection is set up
  2. l.139: client.BindFunc is called, which is transceiver.bindFunc injected, which calls go transmitter.handlePDU, which calls client.Read, which waits on client.inbox channel)
  3. l.147: if for whatever reason err is returned, break in l.153 is called, which means there is no send to client.inbox. close(client.inbox) is called nowhere, so transceiver.bindFunc waits forever

If this scenario repeats, we end up with more and more goroutines (transceiver.bindFunc -> transmitter.handlePDU -> client.Read) waiting on the client.inbox channel.

SAR support.

There is another methods to send long messages, like SAR. It would be awesome to support it.

Method for sending additional fields with SMS

Firstly, thanks for really awesome work. I have used and tested this package for simple sms and it works on smppsim simulator. My real smpp provided wants addrton,dest_addr_ton, source_addr_npi and addr_npi to be provided. If I send sms without these fields using Submit method it says invalid source address.

Method func (t *Transmitter) Submit(sm *ShortMessage) (*ShortMessage, error) doesn't support a parmeter to send additional fields along with simple ones. May I suggest a new method with signature:

func (t *Transmitter) SubmitWithFields(sm *ShortMessage, fields map[string]interface{}) (*ShortMessage, error)

I tried implementing above using following code:

// SubmitWithFields sends a short message along with extra pdu fields and returns and updates the given
// sm with the response status. It returns the same sm object.
func (t *Transmitter) SubmitWithFields(sm *ShortMessage, fields map[string]int) (*ShortMessage, error) {
    p := pdu.NewSubmitSM()
    f := p.Fields()
    f.Set(pdufield.SourceAddr, sm.Src)
    f.Set(pdufield.DestinationAddr, sm.Dst)
    f.Set(pdufield.ShortMessage, sm.Text)
    f.Set(pdufield.RegisteredDelivery, uint8(sm.Register))
    for k, v := range fields {
        err := f.Set(pdufield.Name(k), v)
        if err != nil {
            return sm, fmt.Errorf("Couldn't set field %s with value %s. Error: %s", k, v, err)
        }
    }
    // Check if the message has validity set.
    if sm.Validity != time.Duration(0) {
        f.Set(pdufield.ValidityPeriod, convertValidity(sm.Validity))
    }
    resp, err := t.do(p)
    if err != nil {
        return nil, err
    }
    sm.resp.Lock()
    sm.resp.p = resp.PDU
    sm.resp.Unlock()
    if id := resp.PDU.Header().ID; id != pdu.SubmitSMRespID {
        return sm, fmt.Errorf("unexpected PDU ID: %s", id)
    }
    if s := resp.PDU.Header().Status; s != 0 {
        return sm, s
    }
    return sm, resp.Err
}

but when I submit with this method, smppsim disconnects and times out. Is there any better way via which I can send additional fields?

Support 2 byte reference number in UDH header

Hey there,

We're going to be running some services with this library that are going to be using a fairly large number of binds. With the current 1 byte reference number the chance of a collision would be relatively high and we'd like to use the alternative header with the 2 byte number. For now we've patched the library to add it in but was wanting to ask if you would accept a PR for it?

Cheers,
Lucian

Decoded DeliverSM PDU differs from serialised one

Looks like decoding process adds one null byte at the start of ShortMessage field.

Example code:

package main

import (
	"bytes"
	"fmt"

	"github.com/fiorix/go-smpp/smpp"
	"github.com/fiorix/go-smpp/smpp/pdu"
	"github.com/fiorix/go-smpp/smpp/pdu/pdufield"
	"github.com/fiorix/go-smpp/smpp/pdu/pdutext"
)

func main(){
	sm := &smpp.ShortMessage{
			Src:      "TEST",
			Dst:      "+79000005555",
			Text:     pdutext.UCS2("Hello"),
			Register: pdufield.NoDeliveryReceipt,
	}
	p := pdu.NewDeliverSM()
	f := p.Fields()
	f.Set(pdufield.SourceAddr, sm.Src)
	f.Set(pdufield.DestinationAddr, sm.Dst)
	f.Set(pdufield.ShortMessage, sm.Text)
	f.Set(pdufield.RegisteredDelivery, uint8(sm.Register))
	f.Set(pdufield.ServiceType, sm.ServiceType)
	f.Set(pdufield.SourceAddrTON, sm.SourceAddrTON)
	f.Set(pdufield.SourceAddrNPI, sm.SourceAddrNPI)
	f.Set(pdufield.DestAddrTON, sm.DestAddrTON)
	f.Set(pdufield.DestAddrNPI, sm.DestAddrNPI)
	f.Set(pdufield.ESMClass, sm.ESMClass)
	f.Set(pdufield.ProtocolID, sm.ProtocolID)
	f.Set(pdufield.PriorityFlag, sm.PriorityFlag)
	f.Set(pdufield.ScheduleDeliveryTime, sm.ScheduleDeliveryTime)
	f.Set(pdufield.ReplaceIfPresentFlag, sm.ReplaceIfPresentFlag)
	f.Set(pdufield.SMDefaultMsgID, sm.SMDefaultMsgID)
	f.Set(pdufield.DataCoding, uint8(sm.Text.Type()))

	var b bytes.Buffer
	p.SerializeTo(&b)
	fmt.Printf("INITIAL PDU: %x\n", b.Bytes())

	np, _ := pdu.Decode(bytes.NewBuffer(b.Bytes()))
	var nb bytes.Buffer
	np.SerializeTo(&nb)
	fmt.Printf("DECODED PDU: %x\n", nb.Bytes())

	fmt.Printf("INITIAL SM: %x\n", p.Fields()[pdufield.ShortMessage])
	fmt.Printf("DECODED SM: %x\n", np.Fields()[pdufield.ShortMessage])
}

Output:

$ go run smpp_sample.go
INITIAL PDU: 0000003c000000050000000000000001000000544553540000002b3739303030303035353535000000000000000008000a0000480065006c006c006f
DECODED PDU: 0000003c000000050000000000000001000000544553540000002b3739303030303035353535000000000000000008000a000000480065006c006c00
INITIAL SM: 00480065006c006c006f
DECODED SM: 0000480065006c006c00

Need help with other smpp library (encoding problem while receiving messages)

I use node-smpp library and I have problems with it.

When I receive a message that has more than 160 latin characters, then the message is divided into parts and instead of letters I accept some characters. For example:
short_message: { udh: <Buffer 05 00 03 4c 02 01>, message: ' nPXNO ePzÅ\n o9ΘDG ÆT ä ù A w \r Asxy 6 Agy Å 0\u001bD. 4 . ΘDG A w $ dP \r eΔ L& s=ö. Ae< & gΔ \r vΘ vY ß ' } }

GSM7 encoding

Hi all,

Currently there is no support for GSM7 encoding or packing.
Since most SMPP providers do not support receiving GSM7 packed (septet to octet conversion) requests, I suggest that we add two new codecs:

GSM7 Packed

Encode and pack messages. That means messages should be split after 140-7 bytes (UDH header), since there is the potential for splitting an escaped character (which consists of two bytes) like { across two parts, we should limit each part to 140-7-1 bytes.

GSM7 Unpacked

Only encode message, since many SMPP providers will not accept GSM7 packed. That means message should be split after 160-7 bytes (UDH header), since there is the potential for splitting an escaped character (which consists of two bytes) like { across two parts, we should limit each part to 160-7-1 bytes.

tranceiver got disconnect after few seconds

It looks that on each 10 seconds smpp session is re-connected.

2016/07/07 17:58:26 SMPP connection status: Connected
2016/07/07 17:58:26 Received message.
2016/07/07 17:58:31 Received message.
2016/07/07 17:58:36 SMPP connection status: Disconnected

Is this a normal behaviour or it's something unexpected ?

I've tried to compare it with a java library and it looks that is able to accept much more messages then the go library which is suspicious and I'm thinking that some messages are dismissed from go-smpp.

Here is the output from the same host/user/pass from jsmpp (the java library):

Jul 07, 2016 6:05:25 PM TestApp$1 onAcceptDeliverSm Received message.
Jul 07, 2016 6:05:26 PM TestApp$1 onAcceptDeliverSm Received message.
Jul 07, 2016 6:05:26 PM TestApp$1 onAcceptDeliverSm Received message.
Jul 07, 2016 6:05:26 PM TestApp$1 onAcceptDeliverSm Received message.
Jul 07, 2016 6:05:26 PM TestApp$1 onAcceptDeliverSm Received message.
Jul 07, 2016 6:05:26 PM TestApp$1 onAcceptDeliverSm Received message.
Jul 07, 2016 6:05:26 PM TestApp$1 onAcceptDeliverSm Received message.
Jul 07, 2016 6:05:27 PM TestApp$1 onAcceptDeliverSm Received message.

This is how Transceiver is created:

 tx := &smpp.Transceiver{
                Addr:        "20.20.20.20:2775",
                User:        "mytestuser",
                Passwd:      "mytestpass",
                SystemType:  "cp",
                EnquireLink: 30 * time.Minute,
                Handler:     f,
        }

How to make valid NewDeliverSM? Any example?

I'm trying to send DLR using NewDeliverSM, but with no success. Message is sent, but not recognized as DLR

I tried with:
p := pdu.NewDeliverSM()
p.TLVFields().Set(pdutlv.TagReceiptedMessageID, pdutlv.CString("1234"))
p.TLVFields().Set(pdutlv.TagMessageStateOption, 2)
f := p.Fields()
f.Set(pdufield.SourceAddr, m.Fields()[pdufield.SourceAddr])
f.Set(pdufield.DestinationAddr, m.Fields()[pdufield.DestinationAddr])
f.Set(pdufield.ESMClass, 4)
f.Set(pdufield.ServiceType, m.Fields()[pdufield.ServiceType])
f.Set(pdufield.ProtocolID, 0)
p.Header().Status = 0
p.Header().Seq = m.Header().Seq + 1
f.Set(pdufield.ShortMessage, pdutext.Latin1("id:1234 sub:001 dlvrd:001 submit date:180625012100 done date:180625012101 stat:DELIVRD err:000 text:"))

where f are fields from original SubmitSM, "1234" message @#id

What I'm doing wrong here? Do I need to encode values like pdufield.ESMClass = 4 to other formats?

Any working example will be appreciated

How to check if transmitter is bound ?

I want to restrict Send() of message during reconnects.
If Bind_tranciever coincide with Submit_sm it causes Bind to fail -- SMSC does not answer on Bind.

A small bug in SubmitLongMsg function

Hello everyone.
I've found a "bug" when I use SubmitLongMsg function.
If t.do(p) function returns ErrMaxWindowSize, then SubmitLongMsg terminates and it becomes impossible to send the rest parts of message.
But ErrMaxWindowSize is a minor error and it would be great if SubmitLongMsg entered to sleep mode when this error occured.
I've found the way how to do that:

again:
resp, err := t.do(p)
if err == ErrMaxWindowSize {
	time.Sleep(100 * time.Millisecond)
	goto again
}
if err != nil {
	return nil, err
}

But I don't know how can I calculate ideal sleep mode duration.

Oh! God damn. Maybe need I making semaphore struct and rework t.do function to limit sending messages by my goroutines?

Support messages larger than characters allowed per sms

I tried sending larger than one sms content UCS (60+) and Latin(160+) encoded data using ShortMessage struct but it failed on smpp service provided by cellular network. Sending large latin encoded messages work on smppsim. Smppsim fails to process any ucs encoded messages. I read up on it and came across these at http://www.activexperts.com/sms-component/smpp-specifications/smpp-parameter-definition/ :

short_message

The short_message parameter contains the user data. A maximum of 254 octets can be sent. ESME's should use the optional message_payload parameter in submit_sm, submit_multi, and deliver_sm to send larger user data sizes.

sm_length

The sm_length parameter specifies the length of the short_message parameter in octets. The sm_length should be set to 0 in the submit_sm, submit_multi, and deliver_sm PDUs if the message_payload parameter is being used to send user data larger than 254 octets.

If above is right, can this library support sending larger than 160 chars messages? I couldn't find any logic to handle this in code.

Using tx.Submit in thread

Can I use tx.Submit in thread ? I can see in the example_test it is used inside http Handler function

Also if I use tx.Submit in 10 threads, the delivery receipts traffic would increase. Will the Handler function of Transceiver perform fast enough ?

Check connected client(s)

Hi,

Please, if you could give a simple sample - to check to connect a client(s))? (need to check every 30 sec, if a client doesn't send any data - his need disconnect)

Thanks!

Receive message handler is not working

Hi,

With the latest version sms receive event is not firing and status is changing continuously connected and disconnects. Message send successfully but received message event is not firing. When using Transmitter in place of Transceiver without handler then status connected for all time.
Using below code .

   f := func(p pdu.Body) {
	switch p.Header().ID {
	case pdu.DeliverSMID:
		f := p.Fields()
		src := f[pdufield.SourceAddr]
		dst := f[pdufield.DestinationAddr]
		txt := f[pdufield.ShortMessage]
		log.Printf("Short message from=%q to=%q: %q",
			src, dst, txt)
	}
}

tx := &smpp.Transceiver{
	Addr:   "192.168.0.103:8802",
	User:   "userid",
	Passwd: "password",
	Handler:     f,  // Handle incoming SM or delivery receipts.
}
// Create persistent connection, wait for the first status.
conn := <-tx.Bind()
if conn.Status() != smpp.Connected {
	log.Fatal(conn.Error())
}
sm, err := tx.Submit(&smpp.ShortMessage{
	Src:      "src",
	Dst:      "des",
	Text:     pdutext.Raw("sandeep"),
	Register: pdufield.NoDeliveryReceipt,
})
if err != nil {
	log.Fatal(err)
}
log.Println("Message ID:", sm.RespID())


for{
	
	time.Sleep(time.Millisecond * 1600)
}

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.