blob: a77515d254a599c9abf1de95282343e742085a5a [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 Welte8645e102012-06-16 16:09:52 +080091#include <osmocom/gprs/gprs_msgb.h>
Harald Welte9f75c352010-04-30 20:26:32 +020092
Harald Welteea4647d2010-05-12 17:19:53 +000093#define NS_TIMERS_COUNT 7
94#define NS_TIMERS "(tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries)"
95#define NS_TIMERS_HELP \
96 "(un)blocking Timer (Tns-block) timeout\n" \
97 "(un)blocking Timer (Tns-block) number of retries\n" \
98 "Reset Timer (Tns-reset) timeout\n" \
99 "Reset Timer (Tns-reset) number of retries\n" \
100 "Test Timer (Tns-test) timeout\n" \
Holger Hans Peter Freyther2eb6e2c2011-11-05 15:14:59 +0100101 "Alive Timer (Tns-alive) timeout\n" \
102 "Alive Timer (Tns-alive) number of retries\n"
Harald Welteea4647d2010-05-12 17:19:53 +0000103
104enum ns_timeout {
105 NS_TOUT_TNS_BLOCK,
106 NS_TOUT_TNS_BLOCK_RETRIES,
107 NS_TOUT_TNS_RESET,
108 NS_TOUT_TNS_RESET_RETRIES,
109 NS_TOUT_TNS_TEST,
110 NS_TOUT_TNS_ALIVE,
111 NS_TOUT_TNS_ALIVE_RETRIES,
112};
113
Harald Welte9f75c352010-04-30 20:26:32 +0200114#define NSE_S_BLOCKED 0x0001
115#define NSE_S_ALIVE 0x0002
116
Harald Welte914660d2011-11-23 15:01:31 +0100117/*! \brief Osmocom NS link layer types */
Harald Welteb77c6972010-05-01 11:28:43 +0200118enum gprs_ns_ll {
Harald Welte914660d2011-11-23 15:01:31 +0100119 GPRS_NS_LL_UDP, /*!< NS/UDP/IP */
120 GPRS_NS_LL_E1, /*!< NS/E1 */
121 GPRS_NS_LL_FR_GRE, /*!< NS/FR/GRE/IP */
Harald Welteb77c6972010-05-01 11:28:43 +0200122};
123
Harald Welte914660d2011-11-23 15:01:31 +0100124/*! \brief Osmoco NS events */
Harald Welteb77c6972010-05-01 11:28:43 +0200125enum gprs_ns_evt {
126 GPRS_NS_EVT_UNIT_DATA,
127};
128
129struct gprs_nsvc;
Harald Welte914660d2011-11-23 15:01:31 +0100130/*! \brief Osmocom GPRS callback function type */
Harald Welteb77c6972010-05-01 11:28:43 +0200131typedef int gprs_ns_cb_t(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
Harald Welteeaa614c2010-05-02 11:26:34 +0200132 struct msgb *msg, uint16_t bvci);
Harald Welteb77c6972010-05-01 11:28:43 +0200133
Harald Welte914660d2011-11-23 15:01:31 +0100134/*! \brief An instance of the NS protocol stack */
Harald Welteb77c6972010-05-01 11:28:43 +0200135struct gprs_ns_inst {
Harald Welte914660d2011-11-23 15:01:31 +0100136 /*! \brief callback to the user for incoming UNIT DATA IND */
Harald Welteb77c6972010-05-01 11:28:43 +0200137 gprs_ns_cb_t *cb;
138
Harald Welte914660d2011-11-23 15:01:31 +0100139 /*! \brief linked lists of all NSVC in this instance */
Harald Welteb77c6972010-05-01 11:28:43 +0200140 struct llist_head gprs_nsvcs;
141
Harald Welte914660d2011-11-23 15:01:31 +0100142 /*! \brief a NSVC object that's needed to deal with packets for
143 * unknown NSVC */
Harald Welte9aa97fc2010-05-13 13:58:08 +0200144 struct gprs_nsvc *unknown_nsvc;
145
Harald Welteea4647d2010-05-12 17:19:53 +0000146 uint16_t timeout[NS_TIMERS_COUNT];
147
Harald Welte914660d2011-11-23 15:01:31 +0100148 /*! \brief NS-over-IP specific bits */
Harald Welte5540c4c2010-05-19 14:38:50 +0200149 struct {
Pablo Neira Ayuso4db92992011-05-06 12:11:23 +0200150 struct osmo_fd fd;
Harald Welteff3bde82010-05-19 15:09:09 +0200151 uint32_t local_ip;
152 uint16_t local_port;
Harald Welte5540c4c2010-05-19 14:38:50 +0200153 } nsip;
Harald Welte914660d2011-11-23 15:01:31 +0100154 /*! \brief NS-over-FR-over-GRE-over-IP specific bits */
Harald Welte5540c4c2010-05-19 14:38:50 +0200155 struct {
Pablo Neira Ayuso4db92992011-05-06 12:11:23 +0200156 struct osmo_fd fd;
Harald Welteff3bde82010-05-19 15:09:09 +0200157 uint32_t local_ip;
Holger Hans Peter Freyther3e603482012-03-02 14:14:33 +0100158 unsigned int enabled:1;
Harald Welte5540c4c2010-05-19 14:38:50 +0200159 } frgre;
Harald Welteb77c6972010-05-01 11:28:43 +0200160};
161
Harald Welte05b320a2010-05-03 20:16:13 +0200162enum nsvc_timer_mode {
163 /* standard timers */
164 NSVC_TIMER_TNS_TEST,
165 NSVC_TIMER_TNS_ALIVE,
Harald Welte199d9df2010-05-03 20:55:10 +0200166 NSVC_TIMER_TNS_RESET,
167 _NSVC_TIMER_NR,
Harald Welte05b320a2010-05-03 20:16:13 +0200168};
169
Harald Welte914660d2011-11-23 15:01:31 +0100170/*! \brief Structure representing a single NS-VC */
Harald Welte9f75c352010-04-30 20:26:32 +0200171struct gprs_nsvc {
Harald Welte914660d2011-11-23 15:01:31 +0100172 /*! \brief list of NS-VCs within NS Instance */
Harald Welte9f75c352010-04-30 20:26:32 +0200173 struct llist_head list;
Harald Welte914660d2011-11-23 15:01:31 +0100174 /*! \brief pointer to NS Instance */
Harald Welte9f75c352010-04-30 20:26:32 +0200175 struct gprs_ns_inst *nsi;
176
Harald Welte914660d2011-11-23 15:01:31 +0100177 uint16_t nsei; /*! \brief end-to-end significance */
178 uint16_t nsvci; /*! \brief uniquely identifies NS-VC at SGSN */
Harald Welte9f75c352010-04-30 20:26:32 +0200179
Harald Welteeaa614c2010-05-02 11:26:34 +0200180 uint32_t state;
181 uint32_t remote_state;
Harald Welte9f75c352010-04-30 20:26:32 +0200182
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200183 struct osmo_timer_list timer;
Harald Welte05b320a2010-05-03 20:16:13 +0200184 enum nsvc_timer_mode timer_mode;
Harald Welte9f75c352010-04-30 20:26:32 +0200185 int alive_retries;
186
Harald Welte1194b582010-05-12 15:55:23 +0000187 unsigned int remote_end_is_sgsn:1;
188 unsigned int persistent:1;
Harald Welte9f75c352010-04-30 20:26:32 +0200189
Harald Weltef2b4cd72010-05-13 11:45:07 +0200190 struct rate_ctr_group *ctrg;
191
Harald Welte914660d2011-11-23 15:01:31 +0100192 /*! \brief which link-layer are we based on? */
Harald Welte5540c4c2010-05-19 14:38:50 +0200193 enum gprs_ns_ll ll;
194
Harald Welte9f75c352010-04-30 20:26:32 +0200195 union {
196 struct {
197 struct sockaddr_in bts_addr;
198 } ip;
Harald Welte5540c4c2010-05-19 14:38:50 +0200199 struct {
200 struct sockaddr_in bts_addr;
201 } frgre;
Harald Welte9f75c352010-04-30 20:26:32 +0200202 };
203};
204
Harald Weltecb991632010-04-26 19:18:54 +0200205/* Create a new NS protocol instance */
Harald Weltea6a20b42012-06-16 16:40:42 +0800206struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb, void *ctx);
Harald Welte9b455bf2010-03-14 15:45:01 +0800207
Harald Weltecb991632010-04-26 19:18:54 +0200208/* Destroy a NS protocol instance */
209void gprs_ns_destroy(struct gprs_ns_inst *nsi);
210
Harald Welte5540c4c2010-05-19 14:38:50 +0200211/* Listen for incoming GPRS packets via NS/UDP */
Harald Welteff3bde82010-05-19 15:09:09 +0200212int gprs_ns_nsip_listen(struct gprs_ns_inst *nsi);
Harald Weltecb991632010-04-26 19:18:54 +0200213
214struct sockaddr_in;
215
Harald Weltecb991632010-04-26 19:18:54 +0200216/* main function for higher layers (BSSGP) to send NS messages */
Harald Welte44f1c272010-04-30 19:54:29 +0200217int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg);
Harald Weltecb991632010-04-26 19:18:54 +0200218
Harald Welte99e32482010-05-11 06:20:54 +0200219int gprs_ns_tx_reset(struct gprs_nsvc *nsvc, uint8_t cause);
220int gprs_ns_tx_block(struct gprs_nsvc *nsvc, uint8_t cause);
221int gprs_ns_tx_unblock(struct gprs_nsvc *nsvc);
Harald Welte9f75c352010-04-30 20:26:32 +0200222
Harald Welte5540c4c2010-05-19 14:38:50 +0200223/* Listen for incoming GPRS packets via NS/FR/GRE */
Harald Welteff3bde82010-05-19 15:09:09 +0200224int gprs_ns_frgre_listen(struct gprs_ns_inst *nsi);
Harald Welte9f75c352010-04-30 20:26:32 +0200225
226/* Establish a connection (from the BSS) to the SGSN */
227struct gprs_nsvc *nsip_connect(struct gprs_ns_inst *nsi,
Harald Welteb77c6972010-05-01 11:28:43 +0200228 struct sockaddr_in *dest, uint16_t nsei,
229 uint16_t nsvci);
Harald Welte1194b582010-05-12 15:55:23 +0000230
Harald Weltef2b4cd72010-05-13 11:45:07 +0200231struct gprs_nsvc *nsvc_create(struct gprs_ns_inst *nsi, uint16_t nsvci);
232void nsvc_delete(struct gprs_nsvc *nsvc);
233struct gprs_nsvc *nsvc_by_nsei(struct gprs_ns_inst *nsi, uint16_t nsei);
Harald Welteff56d612010-05-15 23:02:24 +0200234struct gprs_nsvc *nsvc_by_nsvci(struct gprs_ns_inst *nsi, uint16_t nsvci);
Harald Weltef2b4cd72010-05-13 11:45:07 +0200235
Harald Welte1ccbf442010-05-14 11:53:08 +0000236/* Initiate a RESET procedure (including timer start, ...)*/
Holger Hans Peter Freyther83e0b3f2010-05-23 21:18:01 +0800237void gprs_nsvc_reset(struct gprs_nsvc *nsvc, uint8_t cause);
Harald Welte1ccbf442010-05-14 11:53:08 +0000238
Harald Welte1194b582010-05-12 15:55:23 +0000239/* Add NS-specific VTY stuff */
240int gprs_ns_vty_init(struct gprs_ns_inst *nsi);
241
Holger Hans Peter Freyther28441442010-06-14 22:11:40 +0800242#define NS_ALLOC_SIZE 2048
Harald Weltee4860d72010-05-19 15:38:10 +0200243#define NS_ALLOC_HEADROOM 20
244static inline struct msgb *gprs_ns_msgb_alloc(void)
245{
246 return msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM, "GPRS/NS");
247}
Harald Welte5540c4c2010-05-19 14:38:50 +0200248
Harald Weltea6a20b42012-06-16 16:40:42 +0800249enum signal_ns {
250 S_NS_RESET,
251 S_NS_BLOCK,
252 S_NS_UNBLOCK,
253 S_NS_ALIVE_EXP, /* Tns-alive expired more than N times */
254};
255
256struct ns_signal_data {
257 struct gprs_nsvc *nsvc;
258 uint8_t cause;
259};
260
Harald Welte68d85d52012-06-16 17:45:59 +0800261void gprs_ns_set_log_ss(int ss);
262
Harald Welte914660d2011-11-23 15:01:31 +0100263/*! }@ */
264
Harald Welte9b455bf2010-03-14 15:45:01 +0800265#endif