blob: 7045d84d1f6a56623a84c7e0dfc5e8500a0f8506 [file] [log] [blame]
Harald Welte9b455bf2010-03-14 15:45:01 +08001#ifndef _GPRS_NS_H
2#define _GPRS_NS_H
3
Harald Welteeaa614c2010-05-02 11:26:34 +02004#include <stdint.h>
5
Harald Weltecb991632010-04-26 19:18:54 +02006/* GPRS Networks Service (NS) messages on the Gb interface
7 * 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05)
8 * 3GPP TS 48.016 version 6.5.0 Release 6 / ETSI TS 148 016 V6.5.0 (2005-11) */
9
Harald Welte914660d2011-11-23 15:01:31 +010010/*! \addtogroup libgb
11 * @{
12 */
13
14/*! \file gprs_ns.h */
15
16/*! \brief Common header of GPRS NS */
Harald Welte9b455bf2010-03-14 15:45:01 +080017struct gprs_ns_hdr {
Harald Welte914660d2011-11-23 15:01:31 +010018 uint8_t pdu_type; /*!< NS PDU type */
19 uint8_t data[0]; /*!< variable-length payload */
Harald Welte9b455bf2010-03-14 15:45:01 +080020} __attribute__((packed));
21
Harald Welte914660d2011-11-23 15:01:31 +010022/*! \brief NS PDU Type (TS 08.16, Section 10.3.7, Table 14) */
Harald Welte9b455bf2010-03-14 15:45:01 +080023enum ns_pdu_type {
24 NS_PDUT_UNITDATA = 0x00,
25 NS_PDUT_RESET = 0x02,
26 NS_PDUT_RESET_ACK = 0x03,
27 NS_PDUT_BLOCK = 0x04,
28 NS_PDUT_BLOCK_ACK = 0x05,
29 NS_PDUT_UNBLOCK = 0x06,
30 NS_PDUT_UNBLOCK_ACK = 0x07,
31 NS_PDUT_STATUS = 0x08,
32 NS_PDUT_ALIVE = 0x0a,
33 NS_PDUT_ALIVE_ACK = 0x0b,
Harald Weltecb991632010-04-26 19:18:54 +020034 /* TS 48.016 Section 10.3.7, Table 10.3.7.1 */
35 SNS_PDUT_ACK = 0x0c,
36 SNS_PDUT_ADD = 0x0d,
37 SNS_PDUT_CHANGE_WEIGHT = 0x0e,
38 SNS_PDUT_CONFIG = 0x0f,
39 SNS_PDUT_CONFIG_ACK = 0x10,
40 SNS_PDUT_DELETE = 0x11,
41 SNS_PDUT_SIZE = 0x12,
42 SNS_PDUT_SIZE_ACK = 0x13,
Harald Welte9b455bf2010-03-14 15:45:01 +080043};
44
Harald Welte914660d2011-11-23 15:01:31 +010045/*! \brief NS Control IE (TS 08.16, Section 10.3, Table 12) */
Harald Welte9b455bf2010-03-14 15:45:01 +080046enum ns_ctrl_ie {
47 NS_IE_CAUSE = 0x00,
48 NS_IE_VCI = 0x01,
49 NS_IE_PDU = 0x02,
50 NS_IE_BVCI = 0x03,
51 NS_IE_NSEI = 0x04,
Harald Weltecb991632010-04-26 19:18:54 +020052 /* TS 48.016 Section 10.3, Table 10.3.1 */
53 NS_IE_IPv4_LIST = 0x05,
54 NS_IE_IPv6_LIST = 0x06,
55 NS_IE_MAX_NR_NSVC = 0x07,
56 NS_IE_IPv4_EP_NR = 0x08,
57 NS_IE_IPv6_EP_NR = 0x09,
58 NS_IE_RESET_FLAG = 0x0a,
59 NS_IE_IP_ADDR = 0x0b,
Harald Welte9b455bf2010-03-14 15:45:01 +080060};
61
Harald Welte914660d2011-11-23 15:01:31 +010062/*! \brief NS Cause (TS 08.16, Section 10.3.2, Table 13) */
Harald Welte9b455bf2010-03-14 15:45:01 +080063enum ns_cause {
64 NS_CAUSE_TRANSIT_FAIL = 0x00,
65 NS_CAUSE_OM_INTERVENTION = 0x01,
66 NS_CAUSE_EQUIP_FAIL = 0x02,
67 NS_CAUSE_NSVC_BLOCKED = 0x03,
68 NS_CAUSE_NSVC_UNKNOWN = 0x04,
69 NS_CAUSE_BVCI_UNKNOWN = 0x05,
70 NS_CAUSE_SEM_INCORR_PDU = 0x08,
71 NS_CAUSE_PDU_INCOMP_PSTATE = 0x0a,
72 NS_CAUSE_PROTO_ERR_UNSPEC = 0x0b,
73 NS_CAUSE_INVAL_ESSENT_IE = 0x0c,
74 NS_CAUSE_MISSING_ESSENT_IE = 0x0d,
Harald Weltecb991632010-04-26 19:18:54 +020075 /* TS 48.016 Section 10.3.2, Table 10.3.2.1 */
76 NS_CAUSE_INVAL_NR_IPv4_EP = 0x0e,
77 NS_CAUSE_INVAL_NR_IPv6_EP = 0x0f,
78 NS_CAUSE_INVAL_NR_NS_VC = 0x10,
79 NS_CAUSE_INVAL_WEIGH = 0x11,
80 NS_CAUSE_UNKN_IP_EP = 0x12,
81 NS_CAUSE_UNKN_IP_ADDR = 0x13,
82 NS_CAUSE_UNKN_IP_TEST_FAILED = 0x14,
Harald Welte9b455bf2010-03-14 15:45:01 +080083};
84
Harald Welte9f75c352010-04-30 20:26:32 +020085/* Our Implementation */
86#include <netinet/in.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010087#include <osmocom/core/linuxlist.h>
88#include <osmocom/core/msgb.h>
89#include <osmocom/core/timer.h>
90#include <osmocom/core/select.h>
Harald Welte9f75c352010-04-30 20:26:32 +020091
Harald Welteea4647d2010-05-12 17:19:53 +000092#define NS_TIMERS_COUNT 7
93#define NS_TIMERS "(tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries)"
94#define NS_TIMERS_HELP \
95 "(un)blocking Timer (Tns-block) timeout\n" \
96 "(un)blocking Timer (Tns-block) number of retries\n" \
97 "Reset Timer (Tns-reset) timeout\n" \
98 "Reset Timer (Tns-reset) number of retries\n" \
99 "Test Timer (Tns-test) timeout\n" \
Holger Hans Peter Freyther2eb6e2c2011-11-05 15:14:59 +0100100 "Alive Timer (Tns-alive) timeout\n" \
101 "Alive Timer (Tns-alive) number of retries\n"
Harald Welteea4647d2010-05-12 17:19:53 +0000102
103enum ns_timeout {
104 NS_TOUT_TNS_BLOCK,
105 NS_TOUT_TNS_BLOCK_RETRIES,
106 NS_TOUT_TNS_RESET,
107 NS_TOUT_TNS_RESET_RETRIES,
108 NS_TOUT_TNS_TEST,
109 NS_TOUT_TNS_ALIVE,
110 NS_TOUT_TNS_ALIVE_RETRIES,
111};
112
Harald Welte9f75c352010-04-30 20:26:32 +0200113#define NSE_S_BLOCKED 0x0001
114#define NSE_S_ALIVE 0x0002
115
Harald Welte914660d2011-11-23 15:01:31 +0100116/*! \brief Osmocom NS link layer types */
Harald Welteb77c6972010-05-01 11:28:43 +0200117enum gprs_ns_ll {
Harald Welte914660d2011-11-23 15:01:31 +0100118 GPRS_NS_LL_UDP, /*!< NS/UDP/IP */
119 GPRS_NS_LL_E1, /*!< NS/E1 */
120 GPRS_NS_LL_FR_GRE, /*!< NS/FR/GRE/IP */
Harald Welteb77c6972010-05-01 11:28:43 +0200121};
122
Harald Welte914660d2011-11-23 15:01:31 +0100123/*! \brief Osmoco NS events */
Harald Welteb77c6972010-05-01 11:28:43 +0200124enum gprs_ns_evt {
125 GPRS_NS_EVT_UNIT_DATA,
126};
127
128struct gprs_nsvc;
Harald Welte914660d2011-11-23 15:01:31 +0100129/*! \brief Osmocom GPRS callback function type */
Harald Welteb77c6972010-05-01 11:28:43 +0200130typedef int gprs_ns_cb_t(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
Harald Welteeaa614c2010-05-02 11:26:34 +0200131 struct msgb *msg, uint16_t bvci);
Harald Welteb77c6972010-05-01 11:28:43 +0200132
Harald Welte914660d2011-11-23 15:01:31 +0100133/*! \brief An instance of the NS protocol stack */
Harald Welteb77c6972010-05-01 11:28:43 +0200134struct gprs_ns_inst {
Harald Welte914660d2011-11-23 15:01:31 +0100135 /*! \brief callback to the user for incoming UNIT DATA IND */
Harald Welteb77c6972010-05-01 11:28:43 +0200136 gprs_ns_cb_t *cb;
137
Harald Welte914660d2011-11-23 15:01:31 +0100138 /*! \brief linked lists of all NSVC in this instance */
Harald Welteb77c6972010-05-01 11:28:43 +0200139 struct llist_head gprs_nsvcs;
140
Harald Welte914660d2011-11-23 15:01:31 +0100141 /*! \brief a NSVC object that's needed to deal with packets for
142 * unknown NSVC */
Harald Welte9aa97fc2010-05-13 13:58:08 +0200143 struct gprs_nsvc *unknown_nsvc;
144
Harald Welteea4647d2010-05-12 17:19:53 +0000145 uint16_t timeout[NS_TIMERS_COUNT];
146
Harald Welte914660d2011-11-23 15:01:31 +0100147 /*! \brief NS-over-IP specific bits */
Harald Welte5540c4c2010-05-19 14:38:50 +0200148 struct {
Pablo Neira Ayuso4db92992011-05-06 12:11:23 +0200149 struct osmo_fd fd;
Harald Welteff3bde82010-05-19 15:09:09 +0200150 uint32_t local_ip;
151 uint16_t local_port;
Harald Welte5540c4c2010-05-19 14:38:50 +0200152 } nsip;
Harald Welte914660d2011-11-23 15:01:31 +0100153 /*! \brief NS-over-FR-over-GRE-over-IP specific bits */
Harald Welte5540c4c2010-05-19 14:38:50 +0200154 struct {
Pablo Neira Ayuso4db92992011-05-06 12:11:23 +0200155 struct osmo_fd fd;
Harald Welteff3bde82010-05-19 15:09:09 +0200156 uint32_t local_ip;
Holger Hans Peter Freyther3e603482012-03-02 14:14:33 +0100157 unsigned int enabled:1;
Harald Welte5540c4c2010-05-19 14:38:50 +0200158 } frgre;
Harald Welteb77c6972010-05-01 11:28:43 +0200159};
160
Harald Welte05b320a2010-05-03 20:16:13 +0200161enum nsvc_timer_mode {
162 /* standard timers */
163 NSVC_TIMER_TNS_TEST,
164 NSVC_TIMER_TNS_ALIVE,
Harald Welte199d9df2010-05-03 20:55:10 +0200165 NSVC_TIMER_TNS_RESET,
166 _NSVC_TIMER_NR,
Harald Welte05b320a2010-05-03 20:16:13 +0200167};
168
Harald Welte914660d2011-11-23 15:01:31 +0100169/*! \brief Structure representing a single NS-VC */
Harald Welte9f75c352010-04-30 20:26:32 +0200170struct gprs_nsvc {
Harald Welte914660d2011-11-23 15:01:31 +0100171 /*! \brief list of NS-VCs within NS Instance */
Harald Welte9f75c352010-04-30 20:26:32 +0200172 struct llist_head list;
Harald Welte914660d2011-11-23 15:01:31 +0100173 /*! \brief pointer to NS Instance */
Harald Welte9f75c352010-04-30 20:26:32 +0200174 struct gprs_ns_inst *nsi;
175
Harald Welte914660d2011-11-23 15:01:31 +0100176 uint16_t nsei; /*! \brief end-to-end significance */
177 uint16_t nsvci; /*! \brief uniquely identifies NS-VC at SGSN */
Harald Welte9f75c352010-04-30 20:26:32 +0200178
Harald Welteeaa614c2010-05-02 11:26:34 +0200179 uint32_t state;
180 uint32_t remote_state;
Harald Welte9f75c352010-04-30 20:26:32 +0200181
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200182 struct osmo_timer_list timer;
Harald Welte05b320a2010-05-03 20:16:13 +0200183 enum nsvc_timer_mode timer_mode;
Harald Welte9f75c352010-04-30 20:26:32 +0200184 int alive_retries;
185
Harald Welte1194b582010-05-12 15:55:23 +0000186 unsigned int remote_end_is_sgsn:1;
187 unsigned int persistent:1;
Harald Welte9f75c352010-04-30 20:26:32 +0200188
Harald Weltef2b4cd72010-05-13 11:45:07 +0200189 struct rate_ctr_group *ctrg;
190
Harald Welte914660d2011-11-23 15:01:31 +0100191 /*! \brief which link-layer are we based on? */
Harald Welte5540c4c2010-05-19 14:38:50 +0200192 enum gprs_ns_ll ll;
193
Harald Welte9f75c352010-04-30 20:26:32 +0200194 union {
195 struct {
196 struct sockaddr_in bts_addr;
197 } ip;
Harald Welte5540c4c2010-05-19 14:38:50 +0200198 struct {
199 struct sockaddr_in bts_addr;
200 } frgre;
Harald Welte9f75c352010-04-30 20:26:32 +0200201 };
202};
203
Harald Weltecb991632010-04-26 19:18:54 +0200204/* Create a new NS protocol instance */
205struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb);
Harald Welte9b455bf2010-03-14 15:45:01 +0800206
Harald Weltecb991632010-04-26 19:18:54 +0200207/* Destroy a NS protocol instance */
208void gprs_ns_destroy(struct gprs_ns_inst *nsi);
209
Harald Welte5540c4c2010-05-19 14:38:50 +0200210/* Listen for incoming GPRS packets via NS/UDP */
Harald Welteff3bde82010-05-19 15:09:09 +0200211int gprs_ns_nsip_listen(struct gprs_ns_inst *nsi);
Harald Weltecb991632010-04-26 19:18:54 +0200212
213struct sockaddr_in;
214
Harald Weltecb991632010-04-26 19:18:54 +0200215/* main function for higher layers (BSSGP) to send NS messages */
Harald Welte44f1c272010-04-30 19:54:29 +0200216int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg);
Harald Weltecb991632010-04-26 19:18:54 +0200217
Harald Welte99e32482010-05-11 06:20:54 +0200218int gprs_ns_tx_reset(struct gprs_nsvc *nsvc, uint8_t cause);
219int gprs_ns_tx_block(struct gprs_nsvc *nsvc, uint8_t cause);
220int gprs_ns_tx_unblock(struct gprs_nsvc *nsvc);
Harald Welte9f75c352010-04-30 20:26:32 +0200221
Harald Welte5540c4c2010-05-19 14:38:50 +0200222/* Listen for incoming GPRS packets via NS/FR/GRE */
Harald Welteff3bde82010-05-19 15:09:09 +0200223int gprs_ns_frgre_listen(struct gprs_ns_inst *nsi);
Harald Welte9f75c352010-04-30 20:26:32 +0200224
225/* Establish a connection (from the BSS) to the SGSN */
226struct gprs_nsvc *nsip_connect(struct gprs_ns_inst *nsi,
Harald Welteb77c6972010-05-01 11:28:43 +0200227 struct sockaddr_in *dest, uint16_t nsei,
228 uint16_t nsvci);
Harald Welte1194b582010-05-12 15:55:23 +0000229
Harald Weltef2b4cd72010-05-13 11:45:07 +0200230struct gprs_nsvc *nsvc_create(struct gprs_ns_inst *nsi, uint16_t nsvci);
231void nsvc_delete(struct gprs_nsvc *nsvc);
232struct gprs_nsvc *nsvc_by_nsei(struct gprs_ns_inst *nsi, uint16_t nsei);
Harald Welteff56d612010-05-15 23:02:24 +0200233struct gprs_nsvc *nsvc_by_nsvci(struct gprs_ns_inst *nsi, uint16_t nsvci);
Harald Weltef2b4cd72010-05-13 11:45:07 +0200234
Harald Welte1ccbf442010-05-14 11:53:08 +0000235/* Initiate a RESET procedure (including timer start, ...)*/
Holger Hans Peter Freyther83e0b3f2010-05-23 21:18:01 +0800236void gprs_nsvc_reset(struct gprs_nsvc *nsvc, uint8_t cause);
Harald Welte1ccbf442010-05-14 11:53:08 +0000237
Harald Welte1194b582010-05-12 15:55:23 +0000238/* Add NS-specific VTY stuff */
239int gprs_ns_vty_init(struct gprs_ns_inst *nsi);
240
Holger Hans Peter Freyther28441442010-06-14 22:11:40 +0800241#define NS_ALLOC_SIZE 2048
Harald Weltee4860d72010-05-19 15:38:10 +0200242#define NS_ALLOC_HEADROOM 20
243static inline struct msgb *gprs_ns_msgb_alloc(void)
244{
245 return msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM, "GPRS/NS");
246}
Harald Welte5540c4c2010-05-19 14:38:50 +0200247
Harald Welte914660d2011-11-23 15:01:31 +0100248/*! }@ */
249
Harald Welte9b455bf2010-03-14 15:45:01 +0800250#endif