Skip to content

Commit a7e6e42

Browse files
committed
PartyAddress refactoring and some cleanup
1 parent 86d1cb4 commit a7e6e42

File tree

7 files changed

+403
-235
lines changed

7 files changed

+403
-235
lines changed

examples/client/simple-client.go

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,29 +72,43 @@ func main() {
7272
log.Fatal(err)
7373
}
7474

75-
cdPA, err := utils.StrToSwappedBytes("1234567890123456", "0")
75+
cd, err := utils.EncodeBCD("1234567890123456")
7676
if err != nil {
7777
log.Fatal(err)
7878
}
79-
cgPA, err := utils.StrToSwappedBytes("9876543210", "0")
79+
cg, err := utils.EncodeBCD("9876543210")
8080
if err != nil {
8181
log.Fatal(err)
8282
}
8383

84+
gti := params.GTITTNPESNAI
85+
ai := params.NewAddressIndicator(false, true, false, gti)
86+
cdPA := params.NewPartyAddressTyped(
87+
ai, 0, 6, params.NewGlobalTitle(
88+
gti,
89+
params.TranslationType(0),
90+
params.NPISDNTelephony,
91+
params.ESBCDOdd,
92+
params.NAIInternationalNumber,
93+
cd,
94+
),
95+
)
96+
cgPA := params.NewPartyAddressTyped(
97+
ai, 0, 7, params.NewGlobalTitle(
98+
gti,
99+
params.TranslationType(1),
100+
params.NPISDNMobile,
101+
params.ESBCDOdd,
102+
params.NAIInternationalNumber,
103+
cg,
104+
),
105+
)
84106
// create UDT message with CdPA, CgPA and payload
85107
udt, err := sccp.NewUDT(
86108
1, // Protocol Class
87109
true, // Message handling
88-
params.NewPartyAddress( // CalledPartyAddress: 1234567890123456
89-
0x12, 0, 6, 0x00, // Indicator, SPC, SSN, TT
90-
0x01, 0x01, 0x04, // NP, ES, NAI
91-
cdPA, // GlobalTitleInformation
92-
),
93-
params.NewPartyAddress( // CallingPartyAddress: 9876543210
94-
0x12, 0, 7, 0x01, // Indicator, SPC, SSN, TT
95-
0x01, 0x02, 0x04, // NP, ES, NAI
96-
cgPA, // GlobalTitleInformation
97-
),
110+
cdPA,
111+
cgPA,
98112
payload, // payload
99113
).MarshalBinary()
100114
if err != nil {

header.go

Lines changed: 0 additions & 72 deletions
This file was deleted.

params/global-title.go

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
package params
2+
3+
import (
4+
"fmt"
5+
"io"
6+
)
7+
8+
// GlobalTitle is a GlobalTitle inside the Called/Calling Party Address.
9+
type GlobalTitle struct {
10+
// GTI is included in the Address Indicator which is not a part of
11+
// Global Title itself, but necessary to encode/decode it properly.
12+
GTI GlobalTitleIndicator
13+
TranslationType
14+
NumberingPlan
15+
EncodingScheme
16+
NatureOfAddressIndicator
17+
AddressInformation []byte
18+
}
19+
20+
// GlobalTitleIndicator is a type of Global Title Indicator.
21+
// See Q.713 3.4.1 for more details.
22+
type GlobalTitleIndicator uint8
23+
24+
const (
25+
GTINAIOnly GlobalTitleIndicator = 0b0001
26+
GTITTOnly GlobalTitleIndicator = 0b0010
27+
GTITTNPES GlobalTitleIndicator = 0b0011
28+
GTITTNPESNAI GlobalTitleIndicator = 0b0100
29+
)
30+
31+
// NatureOfAddressIndicator is a type of Nature of Address Indicator.
32+
type NatureOfAddressIndicator uint8
33+
34+
// NatureOfAddressIndicator values.
35+
const (
36+
NAIUnknown NatureOfAddressIndicator = 0b00000000
37+
NAISubscriberNumber NatureOfAddressIndicator = 0b00000001
38+
_ NatureOfAddressIndicator = 0b00000010 // Reserved for national use
39+
NAINationalSignificantNumber NatureOfAddressIndicator = 0b00000011
40+
NAIInternationalNumber NatureOfAddressIndicator = 0b00000100
41+
)
42+
43+
// Even returns the NatureOfAddressIndicator with the last bit set to 0.
44+
func (nai NatureOfAddressIndicator) Even() NatureOfAddressIndicator {
45+
return nai & 0b01111111
46+
}
47+
48+
// Odd returns the NatureOfAddressIndicator with the last bit set to 1.
49+
func (nai NatureOfAddressIndicator) Odd() NatureOfAddressIndicator {
50+
return nai | 0b10000000
51+
}
52+
53+
// TranslationType is a type of Translation Type.
54+
type TranslationType uint8
55+
56+
// NumberingPlan is a type of Numbering Plan.
57+
type NumberingPlan uint8
58+
59+
// NumberingPlan values.
60+
const (
61+
NPUnknown NumberingPlan = 0b0000
62+
NPISDNTelephony NumberingPlan = 0b0001
63+
NPGeneric NumberingPlan = 0b0010
64+
NPData NumberingPlan = 0b0011
65+
NPTelex NumberingPlan = 0b0100
66+
NPMaritimeMobile NumberingPlan = 0b0101
67+
NPLandMobile NumberingPlan = 0b0110
68+
NPISDNMobile NumberingPlan = 0b0111
69+
NPPrivate NumberingPlan = 0b1110
70+
)
71+
72+
// EncodingScheme is a type of Encoding Scheme.
73+
type EncodingScheme uint8
74+
75+
// EncodingScheme values.
76+
const (
77+
ESUnknown EncodingScheme = 0b0000
78+
ESBCDOdd EncodingScheme = 0b0001
79+
ESBCDEven EncodingScheme = 0b0010
80+
ESNationalSpecific EncodingScheme = 0b0011
81+
)
82+
83+
// NewGlobalTitle creates a new GlobalTitle.
84+
//
85+
// The first argument is a Global Title Indicator, which is included in the Address Indicator
86+
// in the parent PartyAddress.
87+
func NewGlobalTitle(
88+
gti GlobalTitleIndicator,
89+
tt TranslationType,
90+
np NumberingPlan,
91+
es EncodingScheme,
92+
nai NatureOfAddressIndicator,
93+
addr []byte,
94+
) *GlobalTitle {
95+
gt := &GlobalTitle{GTI: gti}
96+
97+
switch gti {
98+
case GTINAIOnly:
99+
gt.NatureOfAddressIndicator = nai
100+
case GTITTOnly:
101+
gt.TranslationType = tt
102+
case GTITTNPES:
103+
gt.TranslationType = tt
104+
gt.NumberingPlan = np
105+
gt.EncodingScheme = es
106+
case GTITTNPESNAI:
107+
gt.TranslationType = tt
108+
gt.NumberingPlan = np
109+
gt.EncodingScheme = es
110+
gt.NatureOfAddressIndicator = nai
111+
}
112+
113+
gt.AddressInformation = addr
114+
return gt
115+
}
116+
117+
// MarshalBinary returns the byte sequence generated from a GlobalTitle.
118+
func (g *GlobalTitle) MarshalBinary() []byte {
119+
b := make([]byte, g.MarshalLen())
120+
if err := g.MarshalTo(b); err != nil {
121+
panic(err)
122+
}
123+
124+
return b
125+
}
126+
127+
// MarshalTo puts the byte sequence in the byte array given as b.
128+
func (g *GlobalTitle) MarshalTo(b []byte) error {
129+
if len(b) < g.MarshalLen() {
130+
return io.ErrUnexpectedEOF
131+
}
132+
offset := 0
133+
switch g.GTI {
134+
case GTINAIOnly:
135+
b[offset] = uint8(g.NatureOfAddressIndicator)
136+
offset++
137+
case GTITTOnly:
138+
b[offset] = uint8(g.TranslationType)
139+
offset++
140+
case GTITTNPES:
141+
b[offset] = uint8(g.TranslationType)
142+
b[offset+1] = uint8(g.NumberingPlan)<<4 | uint8(g.EncodingScheme)
143+
offset += 2
144+
case GTITTNPESNAI:
145+
b[offset] = uint8(g.TranslationType)
146+
b[offset+1] = uint8(g.NumberingPlan)<<4 | uint8(g.EncodingScheme)
147+
b[offset+2] = uint8(g.NatureOfAddressIndicator)
148+
offset += 3
149+
}
150+
151+
copy(b[offset:g.MarshalLen()], g.AddressInformation)
152+
return nil
153+
}
154+
155+
// ParseGlobalTitle decodes given byte sequence as a GlobalTitle.
156+
// The given byte sequence should not include the excess bytes for the parent PartyAddress.
157+
// otherwise, AddressInformation will include them.
158+
func ParseGlobalTitle(gti GlobalTitleIndicator, b []byte) (*GlobalTitle, error) {
159+
g := &GlobalTitle{GTI: gti}
160+
if err := g.UnmarshalBinary(b); err != nil {
161+
return nil, err
162+
}
163+
164+
return g, nil
165+
}
166+
167+
// UnmarshalBinary sets the values retrieved from byte sequence in a GlobalTitle.
168+
// The given byte sequence should not include the excess bytes for the parent PartyAddress.
169+
// otherwise, AddressInformation will include them.
170+
func (g *GlobalTitle) UnmarshalBinary(b []byte) error {
171+
if len(b) < g.lenByGTI() {
172+
return io.ErrUnexpectedEOF
173+
}
174+
175+
offset := 0
176+
switch g.GTI {
177+
case GTINAIOnly:
178+
g.NatureOfAddressIndicator = NatureOfAddressIndicator(b[offset])
179+
offset++
180+
case GTITTOnly:
181+
g.TranslationType = TranslationType(b[offset])
182+
offset++
183+
case GTITTNPES:
184+
g.TranslationType = TranslationType(b[offset])
185+
g.NumberingPlan = NumberingPlan(b[offset+1] >> 4)
186+
g.EncodingScheme = EncodingScheme(b[offset+1] & 0x0F)
187+
offset += 2
188+
case GTITTNPESNAI:
189+
g.TranslationType = TranslationType(b[offset])
190+
g.NumberingPlan = NumberingPlan(b[offset+1] >> 4)
191+
g.EncodingScheme = EncodingScheme(b[offset+1] & 0x0F)
192+
g.NatureOfAddressIndicator = NatureOfAddressIndicator(b[offset+2])
193+
offset += 3
194+
}
195+
196+
g.AddressInformation = b[offset:]
197+
return nil
198+
}
199+
200+
// MarshalLen returns the serial length of a GlobalTitle.
201+
func (g *GlobalTitle) MarshalLen() int {
202+
return g.lenByGTI()
203+
}
204+
205+
func (g *GlobalTitle) lenByGTI() int {
206+
var l int
207+
switch g.GTI {
208+
case GTINAIOnly:
209+
l += 1
210+
case GTITTOnly:
211+
l += 1
212+
case GTITTNPES:
213+
l += 2
214+
case GTITTNPESNAI:
215+
l += 3
216+
}
217+
218+
if g.AddressInformation != nil {
219+
l += len(g.AddressInformation)
220+
}
221+
222+
return l
223+
}
224+
225+
// String returns the GlobalTitle in a human-readable format.
226+
func (g *GlobalTitle) String() string {
227+
return fmt.Sprintf("{GTI: %d, TransationType: %d, NumberingPlan: %d, EncodingScheme: %d, NatureOfAddressIndicator: %d, AddressInformation: %#x}",
228+
g.GTI, g.TranslationType, g.NumberingPlan, g.EncodingScheme, g.NatureOfAddressIndicator, g.AddressInformation,
229+
)
230+
}

params/params_test.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,19 @@ var testcases = []struct {
2828
}{
2929
{
3030
description: "PartyAddress",
31-
structured: params.NewPartyAddress(
32-
0x12, 0, 6, 0, // GTI, SPC, SSN, TT
33-
1, 1, 4, // NP, ES, NAI
34-
[]byte{
35-
0x21, 0x43, 0x65, 0x87, 0x09,
36-
},
31+
structured: params.NewPartyAddressTyped(
32+
params.NewAddressIndicator(false, true, false, params.GTITTNPESNAI),
33+
0, 6, // SPC, SSN
34+
params.NewGlobalTitle(
35+
params.GTITTNPESNAI,
36+
params.TranslationType(0),
37+
params.NPISDNTelephony,
38+
params.ESBCDOdd,
39+
params.NAIInternationalNumber,
40+
[]byte{
41+
0x21, 0x43, 0x65, 0x87, 0x09,
42+
},
43+
),
3744
),
3845
serialized: []byte{
3946
0x0a, 0x12, 0x06, 0x00, 0x11, 0x04, 0x21, 0x43, 0x65, 0x87, 0x09,
@@ -48,10 +55,9 @@ var testcases = []struct {
4855
},
4956
}, {
5057
description: "PartyAddress/2-bytes",
51-
structured: params.NewPartyAddress(
52-
0x42, 0, 6, 0x00, // Indicator, SPC, SSN, TT
53-
0x00, 0x00, 0x00, // NP, ES, NAI
54-
nil, // GlobalTitleInformation
58+
structured: params.NewPartyAddressTyped(
59+
params.NewAddressIndicator(false, true, true, params.GlobalTitleIndicator(0)),
60+
0, 6, nil, // SPC, SSN, GT
5561
),
5662
serialized: []byte{
5763
0x02, 0x42, 0x06,

0 commit comments

Comments
 (0)