aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/include/openbsc/gprs_ns.h
blob: dd10d33392b63471fac2a73466de8c12d65c75d3 (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
#ifndef _GPRS_NS_H
#define _GPRS_NS_H

/* GPRS Networks Service (NS) messages on the Gb interface
 * 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05)
 * 3GPP TS 48.016 version 6.5.0 Release 6 / ETSI TS 148 016 V6.5.0 (2005-11) */

struct gprs_ns_hdr {
	u_int8_t pdu_type;
	u_int8_t data[0];
} __attribute__((packed));

/* TS 08.16, Section 10.3.7, Table 14 */
enum ns_pdu_type {
	NS_PDUT_UNITDATA	= 0x00,
	NS_PDUT_RESET		= 0x02,
	NS_PDUT_RESET_ACK	= 0x03,
	NS_PDUT_BLOCK		= 0x04,
	NS_PDUT_BLOCK_ACK	= 0x05,
	NS_PDUT_UNBLOCK		= 0x06,
	NS_PDUT_UNBLOCK_ACK	= 0x07,
	NS_PDUT_STATUS		= 0x08,
	NS_PDUT_ALIVE		= 0x0a,
	NS_PDUT_ALIVE_ACK	= 0x0b,
	/* TS 48.016 Section 10.3.7, Table 10.3.7.1 */
	SNS_PDUT_ACK		= 0x0c,
	SNS_PDUT_ADD		= 0x0d,
	SNS_PDUT_CHANGE_WEIGHT	= 0x0e,
	SNS_PDUT_CONFIG		= 0x0f,
	SNS_PDUT_CONFIG_ACK	= 0x10,
	SNS_PDUT_DELETE		= 0x11,
	SNS_PDUT_SIZE		= 0x12,
	SNS_PDUT_SIZE_ACK	= 0x13,
};

/* TS 08.16, Section 10.3, Table 12 */
enum ns_ctrl_ie {
	NS_IE_CAUSE		= 0x00,
	NS_IE_VCI		= 0x01,
	NS_IE_PDU		= 0x02,
	NS_IE_BVCI		= 0x03,
	NS_IE_NSEI		= 0x04,
	/* TS 48.016 Section 10.3, Table 10.3.1 */
	NS_IE_IPv4_LIST		= 0x05,
	NS_IE_IPv6_LIST		= 0x06,
	NS_IE_MAX_NR_NSVC	= 0x07,
	NS_IE_IPv4_EP_NR	= 0x08,
	NS_IE_IPv6_EP_NR	= 0x09,
	NS_IE_RESET_FLAG	= 0x0a,
	NS_IE_IP_ADDR		= 0x0b,
};

/* TS 08.16, Section 10.3.2, Table 13 */
enum ns_cause {
	NS_CAUSE_TRANSIT_FAIL		= 0x00,
	NS_CAUSE_OM_INTERVENTION	= 0x01,
	NS_CAUSE_EQUIP_FAIL		= 0x02,
	NS_CAUSE_NSVC_BLOCKED		= 0x03,
	NS_CAUSE_NSVC_UNKNOWN		= 0x04,
	NS_CAUSE_BVCI_UNKNOWN		= 0x05,
	NS_CAUSE_SEM_INCORR_PDU		= 0x08,
	NS_CAUSE_PDU_INCOMP_PSTATE	= 0x0a,
	NS_CAUSE_PROTO_ERR_UNSPEC	= 0x0b,
	NS_CAUSE_INVAL_ESSENT_IE	= 0x0c,
	NS_CAUSE_MISSING_ESSENT_IE	= 0x0d,
	/* TS 48.016 Section 10.3.2, Table 10.3.2.1 */
	NS_CAUSE_INVAL_NR_IPv4_EP	= 0x0e,
	NS_CAUSE_INVAL_NR_IPv6_EP	= 0x0f,
	NS_CAUSE_INVAL_NR_NS_VC		= 0x10,
	NS_CAUSE_INVAL_WEIGH		= 0x11,
	NS_CAUSE_UNKN_IP_EP		= 0x12,
	NS_CAUSE_UNKN_IP_ADDR		= 0x13,
	NS_CAUSE_UNKN_IP_TEST_FAILED	= 0x14,
};


/* Our Implementation */
#include <netinet/in.h>

#define NSE_S_BLOCKED	0x0001
#define NSE_S_ALIVE	0x0002

struct gprs_nsvc {
	struct llist_head list;
	struct gprs_ns_inst *nsi;

	u_int16_t nsei;		/* end-to-end significance */
	u_int16_t nsvci;	/* uniquely identifies NS-VC at SGSN */

	u_int32_t state;
	u_int32_t remote_state;

	struct timer_list alive_timer;
	int timer_is_tns_alive;
	int alive_retries;

	int remote_end_is_sgsn;

	union {
		struct {
			struct sockaddr_in bts_addr;
		} ip;
	};
};


struct gprs_ns_inst;

enum gprs_ns_evt {
	GPRS_NS_EVT_UNIT_DATA,
};

typedef int gprs_ns_cb_t(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
			 struct msgb *msg, u_int16_t bvci);

/* Create a new NS protocol instance */
struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb);

/* Destroy a NS protocol instance */
void gprs_ns_destroy(struct gprs_ns_inst *nsi);

/* Listen for incoming GPRS packets */
int nsip_listen(struct gprs_ns_inst *nsi, uint16_t udp_port);

struct sockaddr_in;

/* main entry point, here incoming NS frames enter */
int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
		   struct sockaddr_in *saddr);

/* main function for higher layers (BSSGP) to send NS messages */
int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg);


/* Listen for incoming GPRS packets */
int nsip_listen(struct gprs_ns_inst *nsi, uint16_t udp_port);

/* Establish a connection (from the BSS) to the SGSN */
struct gprs_nsvc *nsip_connect(struct gprs_ns_inst *nsi,
				struct sockaddr_in *dest, uint16_t nsvci);
#endif