smpp

package
v0.0.0-...-02bf1cd Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 8, 2023 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package smpp is an implementation of the SMPP 3.4 protocol.

Index

Examples

Constants

View Source
const MaxDestinationAddress = 254

MaxDestinationAddress is the maximum number of destination addresses allowed in the submit_multi operation.

Variables

View Source
var (
	// ErrNotConnected is returned on attempts to use a dead connection.
	ErrNotConnected = errors.New("not connected")

	// ErrNotBound is returned on attempts to use a Transmitter,
	// Receiver or Transceiver before calling Bind.
	ErrNotBound = errors.New("not bound")

	// ErrTimeout is returned when we've reached timeout while waiting for response.
	ErrTimeout = errors.New("timeout waiting for response")
)
View Source
var ErrMaxWindowSize = errors.New("reached max window size")

ErrMaxWindowSize is returned when an operation (such as Submit) violates the maximum window size configured for the Transmitter or Transceiver.

Functions

This section is empty.

Types

type ClientConn

type ClientConn interface {
	// Bind starts the client connection and returns a
	// channel that is triggered every time the connection
	// status changes.
	Bind() <-chan ConnStatus

	// Closer embeds the Closer interface. When Close is
	// called, client sends the Unbind command first and
	// terminates the connection upon response, or 1s timeout.
	Closer
}

ClientConn provides a persistent client connection that handles reconnection with a back-off algorithm.

type Closer

type Closer interface {
	// Close terminates the connection.
	Close() error
}

Closer is the interface that wraps the basic Close method.

type Conn

type Conn interface {
	Reader
	Writer
	Closer
}

Conn is an SMPP connection.

func Dial

func Dial(addr string, TLS *tls.Config) (Conn, error)

Dial dials to the SMPP server and returns a Conn, or error. TLS is only used if provided.

type ConnStatus

type ConnStatus interface {
	Status() ConnStatusID
	Error() error
}

ConnStatus is an abstract interface for a connection status change.

type ConnStatusID

type ConnStatusID uint8

ConnStatusID represents a connection status change.

const (
	Connected ConnStatusID = iota + 1
	Disconnected
	ConnectionFailed
	BindFailed
)

Supported connection statuses.

func (ConnStatusID) String

func (cs ConnStatusID) String() string

String implements the Stringer interface.

type HandlerFunc

type HandlerFunc func(p pdu.Body)

HandlerFunc is the handler function that a Receiver calls when a new PDU arrives.

type MergeHolder

type MergeHolder struct {
	MessageID     int
	MessageParts  []*MessagePart // Slice with the parts of the message
	PartsCount    int
	LastWriteTime time.Time
}

MergeHolder is a struct which holds the slice of MessageParts for the merging of a long incoming message.

type MessagePart

type MessagePart struct {
	PartID int
	Data   *bytes.Buffer
}

MessagePart is a struct which holds the data of the part of a long incoming message.

type QueryResp

type QueryResp struct {
	MsgID     string
	MsgState  string
	FinalDate string
	ErrCode   uint8
}

QueryResp contains the parsed the response of a QuerySM request.

type RateLimiter

type RateLimiter interface {
	// Wait blocks until the limiter permits an event to happen.
	Wait(ctx context.Context) error
}

RateLimiter defines an interface for pacing the sending of short messages to a client connection.

The Transmitter or Transceiver using the RateLimiter holds a single context.Context per client connection, passed to Wait prior to sending short messages.

Suitable for use with package golang.org/x/time/rate.

type Reader

type Reader interface {
	// Read reads PDU binary data off the wire and returns it.
	Read() (pdu.Body, error)
}

Reader is the interface that wraps the basic Read method.

type Receiver

type Receiver struct {
	Addr                 string
	User                 string
	Passwd               string
	SystemType           string
	EnquireLink          time.Duration
	EnquireLinkTimeout   time.Duration // Time after last EnquireLink response when connection considered down
	BindInterval         time.Duration // Binding retry interval
	MergeInterval        time.Duration // Time in which Receiver waits for the parts of the long messages
	MergeCleanupInterval time.Duration // How often to cleanup expired message parts
	TLS                  *tls.Config
	Handler              HandlerFunc
	SkipAutoRespondIDs   []pdu.ID
	// contains filtered or unexported fields
}

Receiver implements an SMPP client receiver.

Example
package main

import (
	"log"
	"time"

	"bitbucket.org/smsgrupp/go-smpp/smpp"
	"bitbucket.org/smsgrupp/go-smpp/smpp/pdu"
	"bitbucket.org/smsgrupp/go-smpp/smpp/pdu/pdufield"
)

func main() {
	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)
		}
	}
	r := &smpp.Receiver{
		Addr:    "localhost:2775",
		User:    "foobar",
		Passwd:  "secret",
		Handler: f,
	}
	// Create persistent connection.
	conn := r.Bind()
	time.AfterFunc(10*time.Second, func() { r.Close() })
	// Print connection status (Connected, Disconnected, etc).
	for c := range conn {
		log.Println("SMPP connection status:", c.Status())
	}
}
Output:

func (*Receiver) Bind

func (r *Receiver) Bind() <-chan ConnStatus

Bind starts the Receiver. It creates a persistent connection to the server, update its status via the returned channel, and calls the registered Handler when new PDU arrives.

Bind implements the ClientConn interface.

func (*Receiver) Close

func (r *Receiver) Close() error

Close implements the ClientConn interface.

type ShortMessage

type ShortMessage struct {
	Src      string
	Dst      string
	DstList  []string // List of destination addreses for submit multi
	DLs      []string //List if destribution list for submit multi
	Text     pdutext.Codec
	Validity time.Duration
	Register pdufield.DeliverySetting

	// Other fields, normally optional.
	TLVFields            pdutlv.Fields
	ServiceType          string
	SourceAddrTON        uint8
	SourceAddrNPI        uint8
	DestAddrTON          uint8
	DestAddrNPI          uint8
	ESMClass             uint8
	ProtocolID           uint8
	PriorityFlag         uint8
	ScheduleDeliveryTime string
	ReplaceIfPresentFlag uint8
	SMDefaultMsgID       uint8
	NumberDests          uint8
	// contains filtered or unexported fields
}

ShortMessage configures a short message that can be submitted via the Transmitter. When returned from Submit, the ShortMessage provides Resp and RespID.

func (*ShortMessage) NumbUnsuccess

func (sm *ShortMessage) NumbUnsuccess() (int, error)

NumbUnsuccess is a shortcut to Resp().Fields()pdufield.NoUnsuccess. Returns zero and an error if the response PDU is not available, or does not contain the NoUnsuccess field.

func (*ShortMessage) Resp

func (sm *ShortMessage) Resp() pdu.Body

Resp returns the response PDU, or nil if not set.

func (*ShortMessage) RespID

func (sm *ShortMessage) RespID() string

RespID is a shortcut to Resp().Fields()pdufield.MessageID. Returns empty if the response PDU is not available, or does not contain the MessageID field.

func (*ShortMessage) UnsuccessSmes

func (sm *ShortMessage) UnsuccessSmes() ([]UnsucessDest, error)

UnsuccessSmes returns a list with the SME address(es) or/and Distribution List names to which submission was unsuccessful and the respective errors, when submit multi is used. Returns nil and an error if the response PDU is not available, or does not contain the unsuccess_sme field.

type Transceiver

type Transceiver struct {
	Addr               string        // Server address in form of host:port.
	User               string        // Username.
	Passwd             string        // Password.
	SystemType         string        // System type, default empty.
	EnquireLink        time.Duration // Enquire link interval, default 10s.
	EnquireLinkTimeout time.Duration // Time after last EnquireLink response when connection considered down
	RespTimeout        time.Duration // Response timeout, default 1s.
	BindInterval       time.Duration // Binding retry interval
	TLS                *tls.Config   // TLS client settings, optional.
	Handler            HandlerFunc   // Receiver handler, optional.
	RateLimiter        RateLimiter   // Rate limiter, optional.
	WindowSize         uint

	Transmitter
}

Transceiver implements an SMPP transceiver.

The API is a combination of the Transmitter and Receiver.

Example
package main

import (
	"io"
	"log"
	"net/http"

	"golang.org/x/time/rate"

	"bitbucket.org/smsgrupp/go-smpp/smpp"
	"bitbucket.org/smsgrupp/go-smpp/smpp/pdu"
	"bitbucket.org/smsgrupp/go-smpp/smpp/pdu/pdufield"
	"bitbucket.org/smsgrupp/go-smpp/smpp/pdu/pdutext"
)

func main() {
	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)
		}
	}
	lm := rate.NewLimiter(rate.Limit(10), 1) // Max rate of 10/s.
	tx := &smpp.Transceiver{
		Addr:        "localhost:2775",
		User:        "foobar",
		Passwd:      "secret",
		Handler:     f,  // Handle incoming SM or delivery receipts.
		RateLimiter: lm, // Optional rate limiter.
	}
	// Create persistent connection.
	conn := tx.Bind()
	go func() {
		for c := range conn {
			log.Println("SMPP connection status:", c.Status())
		}
	}()
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		sm, err := tx.Submit(&smpp.ShortMessage{
			Src:      r.FormValue("src"),
			Dst:      r.FormValue("dst"),
			Text:     pdutext.Raw(r.FormValue("text")),
			Register: pdufield.FinalDeliveryReceipt,
		})
		if err == smpp.ErrNotConnected {
			http.Error(w, "Oops.", http.StatusServiceUnavailable)
			return
		}
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		io.WriteString(w, sm.RespID())
	})
	log.Fatal(http.ListenAndServe(":8080", nil))
}
Output:

func (*Transceiver) Bind

func (t *Transceiver) Bind() <-chan ConnStatus

Bind implements the ClientConn interface.

type Transmitter

type Transmitter struct {
	Addr               string        // Server address in form of host:port.
	User               string        // Username.
	Passwd             string        // Password.
	SystemType         string        // System type, default empty.
	EnquireLink        time.Duration // Enquire link interval, default 10s.
	EnquireLinkTimeout time.Duration // Time after last EnquireLink response when connection considered down
	RespTimeout        time.Duration // Response timeout, default 1s.
	BindInterval       time.Duration // Binding retry interval
	TLS                *tls.Config   // TLS client settings, optional.
	RateLimiter        RateLimiter   // Rate limiter, optional.
	WindowSize         uint
	// contains filtered or unexported fields
}

Transmitter implements an SMPP client transmitter.

Example
package main

import (
	"log"

	"bitbucket.org/smsgrupp/go-smpp/smpp"
	"bitbucket.org/smsgrupp/go-smpp/smpp/pdu/pdufield"
	"bitbucket.org/smsgrupp/go-smpp/smpp/pdu/pdutext"
)

func main() {
	tx := &smpp.Transmitter{
		Addr:   "localhost:2775",
		User:   "foobar",
		Passwd: "secret",
	}
	// 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:      "sender",
		Dst:      "recipient",
		Text:     pdutext.Latin1("Olá mundo"),
		Register: pdufield.NoDeliveryReceipt,
	})
	if err != nil {
		log.Fatal(err)
	}
	log.Println("Message ID:", sm.RespID())
}
Output:

func (*Transmitter) Bind

func (t *Transmitter) Bind() <-chan ConnStatus

Bind implements the ClientConn interface.

Any commands (e.g. Submit) attempted on a dead connection will return ErrNotConnected.

func (*Transmitter) Close

func (t *Transmitter) Close() error

Close implements the ClientConn interface.

func (*Transmitter) QuerySM

func (t *Transmitter) QuerySM(src, msgid string, srcTON, srcNPI uint8) (*QueryResp, error)

QuerySM queries the delivery status of a message. It requires the source address (sender) with TON and NPI and message ID.

func (*Transmitter) Submit

func (t *Transmitter) Submit(sm *ShortMessage) (*ShortMessage, error)

Submit sends a short message and returns and updates the given sm with the response status. It returns the same sm object.

func (*Transmitter) SubmitLongMsg

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

SubmitLongMsg sends a long message (more than 140 bytes) and returns and updates the given sm with the response status. It returns the same sm object.

type UnsucessDest

type UnsucessDest struct {
	AddrTON uint8
	AddrNPI uint8
	Address string
	Error   pdu.Status
}

UnsucessDest contains information about unsuccessful delivery to an address when submit multi is used

type Writer

type Writer interface {
	// Write serializes the given PDU and writes to the connection.
	Write(w pdu.Body) error
}

Writer is the interface that wraps the basic Write method.

Directories

Path Synopsis
pdu
Package pdu provide codecs for binary PDU data.
Package pdu provide codecs for binary PDU data.
pdufield
Package pdufield provides PDU field codecs and utilities.
Package pdufield provides PDU field codecs and utilities.
pdutext
Package pdutext provides text conversion for PDU fields.
Package pdutext provides text conversion for PDU fields.
Package smpptest provides an SMPP test server.
Package smpptest provides an SMPP test server.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL