aboutsummaryrefslogtreecommitdiffstats
path: root/include/mtp_level3.h
blob: f311ad503339bb1de00f8c1e9af88d3a53c9c67b (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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* Q.701-Q.704, Q.706, Q.707 handling code */
/*
 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2010 by On-Waves
 * 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/>.
 *
 */

#ifndef mtp_level3_h
#define mtp_level3_h

#include <stdint.h>
#include <endian.h>
#include <sys/types.h>


/*
 * pssible service information octets..
 */
#define MTP_NI_NATION_NET	0x02

#define MTP_SI_MNT_SNM_MSG	0x00
#define MTP_SI_MNT_REG_MSG	0x01
#define MTP_SI_MNT_SCCP		0x03
#define MTP_SI_MNT_ISUP		0x05

/*
 * h0 contains the group, h1 the semantic of it
 */

#define MTP_TST_MSG_GRP		0x01
#define MTP_PROHIBIT_MSG_GRP	0x04
#define MTP_SROUTE_MSG_GRP	0x05
#define MTP_TRF_RESTR_MSG_GRP	0x07

/* h1 values for different groups */
#define MTP_TST_MSG_SLTM	0x01
#define MTP_TST_MSG_SLTA	0x02

#define MTP_RESTR_MSG_ALLWED	0x01

/* For the prohibit group */
#define MTP_PROHIBIT_MSG_SIG	0x01
#define MTP_PROHIBIT_MSG_TFA	0x05

/* For the Signalling-route-set-test */
#define MTP_SROUTE_MSG_TEST	0x01


#define SCCP_SST	0x03
#define SCCP_SSP	0x02
#define SCCP_SSA	0x01

#define MTP_LINK_MASK	    0x0F
#define MTP_ADDR_MASK	    0x3FFF
#define MTP_APOC_MASK 0x3f


#if __BYTE_ORDER == __LITTLE_ENDIAN
#define MTP_LINK_SLS(addr) ((addr >>28) & MTP_LINK_MASK)
#define MTP_ADDR(link, dpc, opc) \
	(((dpc)  & MTP_ADDR_MASK) << 0 |  \
	 ((opc)  & MTP_ADDR_MASK) << 14|  \
	 ((link) & MTP_LINK_MASK) << 28)
#define MTP_MAKE_APOC(apoc) \
	(apoc & 0x3fff)
#define MTP_ADDR_DPC(addr) \
	(addr & MTP_ADDR_MASK)
#define MTP_ADDR_OPC(addr) \
	((addr >> 14) & MTP_ADDR_MASK)
#elif __BYTE_ORDER == __BIG_ENDIAN
static inline uint32_t c_swap_32(uint32_t in)
{
	return 	(((in & 0x000000ff) << 24) |
		((in & 0x0000ff00) <<  8) |
		((in & 0x00ff0000) >>  8) |
	        ((in & 0xff000000) >> 24));
}
static inline uint16_t c_swap_16(uint16_t in)
{
	return (((in & 0x00ff) << 8) |
		 (in & 0xff00) >> 8);
}
#define MTP_LINK_SLS(addr) ((c_swap_32(addr)>>28) & MTP_LINK_MASK)
#define MTP_ADDR(link, dpc, opc) \
        c_swap_32(((dpc)  & MTP_ADDR_MASK) << 0 |  \
         ((opc)  & MTP_ADDR_MASK) << 14|  \
         ((link) & MTP_LINK_MASK) << 28)
#define MTP_MAKE_APOC(apoc) \
	c_swap_16((apoc & 0x3fff))
#define MTP_ADDR_DPC(addr) \
	(c_swap_32(addr) & MTP_ADDR_MASK)
#define MTP_ADDR_OPC(addr) \
	((c_swap_32(addr) >> 14) & MTP_ADDR_MASK)
#endif



/*
 * not the on wire address...
 */
struct mtp_addr {
	uint16_t dpc;
	uint16_t opc;
	uint8_t link;
} __attribute__((packed));

/*
 * the struct is defined in Q.704 and can be seen in the
 * wireshark dissectors too
 */
struct mtp_level_3_hdr {
#if __BYTE_ORDER == __LITTLE_ENDIAN
	uint8_t ser_ind : 4,
		 spare : 2,
		 ni : 2;
#elif __BYTE_ORDER == __BIG_ENDIAN
	uint8_t ni : 2,
		 spare : 2,
		 ser_ind : 4;
#endif
	uint32_t addr;
	uint8_t data[0];
} __attribute__((packed));

struct mtp_level_3_cmn {
#if __BYTE_ORDER == __LITTLE_ENDIAN
	uint8_t h0 : 4,
		 h1 : 4;
#elif __BYTE_ORDER == __BIG_ENDIAN
	uint8_t h1 : 4,
		 h0 : 4;
#endif
} __attribute__((packed));

struct mtp_level_3_mng {
	struct mtp_level_3_cmn  cmn;
#if __BYTE_ORDER == __LITTLE_ENDIAN
	uint8_t spare : 4,
		 length : 4;
#elif __BYTE_ORDER == __BIG_ENDIAN
	uint8_t length : 4,
		 spare : 4;
#endif
	uint8_t data[0];
} __attribute__((packed));

struct mtp_level_3_prohib {
	struct mtp_level_3_cmn  cmn;

	uint16_t apoc;
} __attribute__((packed));

struct sccp_con_ctrl_prt_mgt {
	uint8_t sst;
	uint8_t assn; /* affected sub system number */
	uint16_t apoc;
#if __BYTE_ORDER == __LITTLE_ENDIAN
	uint8_t mul_ind : 2,
		 spare : 6;
#elif __BYTE_ORDER == __BIG_ENDIAN
	uint8_t spare : 6,
		 mul_ind : 2;
#endif
} __attribute__((packed));

#endif