forked from linxGnu/gosmpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
connect.go
123 lines (103 loc) · 2.52 KB
/
connect.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package gosmpp
import (
"fmt"
"net"
"github.com/linxGnu/gosmpp/data"
"github.com/linxGnu/gosmpp/pdu"
)
var (
// NonTLSDialer is non-tls connection dialer.
NonTLSDialer = func(addr string) (net.Conn, error) {
return net.Dial("tcp", addr)
}
)
// Dialer is connection dialer.
type Dialer func(addr string) (net.Conn, error)
// Auth represents basic authentication to SMSC.
type Auth struct {
// SMSC is SMSC address.
SMSC string
SystemID string
Password string
SystemType string
}
func newBindRequest(s Auth, bindingType pdu.BindingType) (bindReq *pdu.BindRequest) {
bindReq = pdu.NewBindRequest(bindingType)
bindReq.SystemID = s.SystemID
bindReq.Password = s.Password
bindReq.SystemType = s.SystemType
return
}
// Connector is connection factory interface.
type Connector interface {
Connect() (conn *Connection, err error)
}
type connector struct {
dialer Dialer
auth Auth
bindingType pdu.BindingType
}
func (c *connector) Connect() (conn *Connection, err error) {
conn, err = connect(c.dialer, c.auth.SMSC, newBindRequest(c.auth, c.bindingType))
return
}
func connect(dialer Dialer, addr string, bindReq *pdu.BindRequest) (c *Connection, err error) {
conn, err := dialer(addr)
if err != nil {
return
}
// create wrapped connection
c = NewConnection(conn)
// send binding request
_, err = c.WritePDU(bindReq)
if err != nil {
_ = conn.Close()
return
}
// catching response
var (
p pdu.PDU
resp *pdu.BindResp
)
for {
if p, err = pdu.Parse(c); err != nil {
_ = conn.Close()
return
}
if pd, ok := p.(*pdu.BindResp); ok {
resp = pd
break
}
}
if resp.CommandStatus != data.ESME_ROK {
err = fmt.Errorf("binding error. Command status: [%d]. Please refer to: https://github.com/linxGnu/gosmpp/blob/master/data/pkg.go for more detail about this status code", resp.CommandStatus)
_ = conn.Close()
} else {
c.systemID = resp.SystemID
}
return
}
// TXConnector returns a Transmitter (TX) connector.
func TXConnector(dialer Dialer, auth Auth) Connector {
return &connector{
dialer: dialer,
auth: auth,
bindingType: pdu.Transmitter,
}
}
// RXConnector returns a Receiver (RX) connector.
func RXConnector(dialer Dialer, auth Auth) Connector {
return &connector{
dialer: dialer,
auth: auth,
bindingType: pdu.Receiver,
}
}
// TRXConnector returns a Transceiver (TRX) connector.
func TRXConnector(dialer Dialer, auth Auth) Connector {
return &connector{
dialer: dialer,
auth: auth,
bindingType: pdu.Transceiver,
}
}