summaryrefslogtreecommitdiffstats
path: root/connection/SMPPConnection.st
blob: c244f0f7ab7ac32d391b46f67a3b9fd297788b67 (plain)
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
124
125
"
 (C) 2014 by Holger Hans Peter Freyther
 All Rights Reserved

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as
 published by the Free Software Foundation, either version 3 of the
 License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
"

Osmo.OsmoStreamSocketBase subclass: SMPPConnection [
    | writeQueue nextSeq systemId password systemType pendingCommands |
    <category: 'SMPP-Connection'>

    createConnection: aHostname port: aPort [
        <category: 'socket'>
        ^ Sockets.StreamSocket remote: aHostname port: aPort.
    ]

    systemId: anId [
        systemId := anId
    ]

    password: aPassword [
        password := aPassword
    ]

    systemType: aType [
        systemType := aType
    ]

    scheduleBindTrx [
        | header body |

        header := SMPPPDUHeader new
                    commandId: SMPPBindTransceiver messageType;
                    commandStatus: 0;
                    yourself.
        body := SMPPBindTransceiver new
                    systemId: systemId;
                    password: password;
                    systemType: systemType;
                    version: 16r34;
                    numberingPlanIndicator: 0;
                    typeOfNumber: 0;
                    addressRange: #[];
                    yourself.

        self send: (SMPPMessage new
                    header: header;
                    body: body) onResponse: [:resp | ].
    ]

    send: aMessage onResponse: aBlock [
        | seq key |
        seq := nextSeq.
        nextSeq := nextSeq + 1.

        aMessage header sequenceNumber: seq.

        "Remember that we want a response. TODO add timeout handling"
        pendingCommands at: seq put: aBlock.

        writeQueue nextPut: aMessage toMessage asByteArray
    ]

    connect [
        super connect.
        nextSeq := 1.
        writeQueue := SharedQueue new.
        pendingCommands := Dictionary new.
        self scheduleBindTrx.
    ]

    sendOne [
        | msg |
        "TODO: Pill of death!"
        msg := writeQueue next.
        socket nextPutAllFlush: msg.
    ]

    dispatchOne [
        | msg |

        [
            msg := SMPPMessage readFrom: socket.
            msg body connectionDispatchOn: self with: msg
        ] on: Error do: [:e |
            e
                inspect;
                pass
        ]
    ]

    respondToEnquire: aMessage [
        | msg |
        msg := SMPPMessage new
                    header: (SMPPPDUHeader new
                                commandId: SMPPBodyBase enquireLinkResp;
                                commandStatus: 0;
                                sequenceNumber: aMessage header sequenceNumber;
                                yourself);
                    body: #[].
        writeQueue nextPut: msg toMessage asByteArray
    ]

    receviedResponse: aMessage [
        | seq block |
	"Search for a response"
        seq := aMessage header sequenceNumber.
        block := pendingCommands removeKey: seq ifAbsent: [
            "TODO: log it"
            ^false].

        block value: aMessage
    ]
]