blob: 45753292d06fb70162611879206bc68606f0cd01 [file] [log] [blame]
Alexander Couzens6a161492020-07-12 13:45:50 +02001/*! \file gprs_ns2.h */
2
3
4#pragma once
5
6#include <stdint.h>
7#include <netinet/in.h>
8
9#include <osmocom/core/prim.h>
Alexander Couzensb3b837c2020-10-27 15:12:25 +010010#include <osmocom/gprs/protocol/gsm_08_16.h>
Alexander Couzens841817e2020-11-19 00:41:29 +010011#include <osmocom/gprs/frame_relay.h>
Alexander Couzens6a161492020-07-12 13:45:50 +020012
13struct osmo_sockaddr;
Alexander Couzens1fac6f72020-10-01 19:08:38 +020014struct osmo_sockaddr_str;
Alexander Couzens841817e2020-11-19 00:41:29 +010015struct osmo_fr_network;
Alexander Couzens6a161492020-07-12 13:45:50 +020016
17struct gprs_ns2_inst;
18struct gprs_ns2_nse;
19struct gprs_ns2_vc;
20struct gprs_ns2_vc_bind;
21struct gprs_ns2_vc_driver;
22struct gprs_ns_ie_ip4_elem;
23struct gprs_ns_ie_ip6_elem;
24
25enum gprs_ns2_vc_mode {
Harald Weltefa2d66c2020-10-17 13:09:34 +020026 /*! The VC will use RESET/BLOCK/UNBLOCK to start the connection and do ALIVE/ACK.
27 * This is what is needed for Frame Relay transport, and if you use a R97/R99 Gb
28 * interface over an IP transport (never standardized by 3GPP) */
29 NS2_VC_MODE_BLOCKRESET,
30 /*! The VC will only use ALIVE/ACK (no RESET/BLOCK/UNBLOCK), which is for Gb-IP
31 * interface compliant to 3GPP Rel=4 or later. */
32 NS2_VC_MODE_ALIVE,
Alexander Couzens6a161492020-07-12 13:45:50 +020033};
34
Alexander Couzens24a14ac2020-11-19 02:34:49 +010035/*! Osmocom NS link layer types */
36enum gprs_ns2_ll {
37 GPRS_NS2_LL_UDP, /*!< NS/UDP/IP */
Alexander Couzens24a14ac2020-11-19 02:34:49 +010038 GPRS_NS2_LL_FR, /*!< NS/FR */
39 GPRS_NS2_LL_FR_GRE, /*!< NS/FR/GRE/IP */
40};
41
Alexander Couzens6a161492020-07-12 13:45:50 +020042/*! Osmocom NS primitives according to 48.016 5.2 Service primitves */
43enum gprs_ns2_prim {
44 PRIM_NS_UNIT_DATA,
45 PRIM_NS_CONGESTION,
46 PRIM_NS_STATUS,
47};
48
Alexander Couzens0ab028c2020-11-04 02:41:44 +010049extern const struct value_string gprs_ns2_prim_strs[];
Harald Weltea24e7ee2020-11-29 17:38:48 +010050extern const struct value_string gprs_ns2_lltype_strs[];
Alexander Couzens2498f1d2020-10-27 01:09:01 +010051
52/*! Obtain a human-readable string for NS primitives */
53static inline const char *gprs_ns2_prim_str(enum gprs_ns2_prim val)
Alexander Couzens0ab028c2020-11-04 02:41:44 +010054{ return get_value_string(gprs_ns2_prim_strs, val); }
Alexander Couzens2498f1d2020-10-27 01:09:01 +010055
Harald Weltea24e7ee2020-11-29 17:38:48 +010056/*! Obtain a human-readable string for NS link-layer type */
57static inline const char *gprs_ns2_lltype_str(enum gprs_ns2_ll val)
58{ return get_value_string(gprs_ns2_lltype_strs, val); }
59
Alexander Couzens6a161492020-07-12 13:45:50 +020060/*! Osmocom NS primitives according to 48.016 5.2.2.4 Service primitves */
61enum gprs_ns2_congestion_cause {
62 NS_CONG_CAUSE_BACKWARD_BEGIN,
63 NS_CONG_CAUSE_BACKWARD_END,
64 NS_CONG_CAUSE_FORWARD_BEGIN,
65 NS_CONG_CAUSE_FORWARD_END,
66};
67
68/*! Osmocom NS primitives according to 48.016 5.2.2.6 Service primitves */
69enum gprs_ns2_affecting_cause {
70 NS_AFF_CAUSE_VC_FAILURE,
71 NS_AFF_CAUSE_VC_RECOVERY,
72 NS_AFF_CAUSE_FAILURE,
73 NS_AFF_CAUSE_RECOVERY,
74 /* osmocom own causes */
75 NS_AFF_CAUSE_SNS_CONFIGURED,
76 NS_AFF_CAUSE_SNS_FAILURE,
77};
78
Alexander Couzens2498f1d2020-10-27 01:09:01 +010079extern const struct value_string gprs_ns2_aff_cause_prim_strs[];
80
81/*! Obtain a human-readable string for NS affective cause in primitives */
82static inline const char *gprs_ns2_aff_cause_prim_str(enum gprs_ns2_affecting_cause val)
83{ return get_value_string(gprs_ns2_aff_cause_prim_strs, val); }
84
Alexander Couzens6a161492020-07-12 13:45:50 +020085/*! Osmocom NS primitives according to 48.016 5.2.2.7 Service primitves */
86enum gprs_ns2_change_ip_endpoint {
87 NS_ENDPOINT_NO_CHANGE,
88 NS_ENDPOINT_REQUEST_CHANGE,
89 NS_ENDPOINT_CONFIRM_CHANGE,
90};
91
Alexander Couzensb3b837c2020-10-27 15:12:25 +010092extern const struct value_string gprs_ns2_cause_strs[];
93
94/*! Obtain a human-readable string for NS primitives */
95static inline const char *gprs_ns2_cause_str(enum ns_cause val)
96{ return get_value_string(gprs_ns2_cause_strs, val); }
97
Alexander Couzens6a161492020-07-12 13:45:50 +020098struct osmo_gprs_ns2_prim {
99 struct osmo_prim_hdr oph;
100
101 uint16_t nsei;
102 uint16_t bvci;
103
104 union {
105 struct {
106 enum gprs_ns2_change_ip_endpoint change;
Alexander Couzensfc3dd1f2020-11-19 00:41:47 +0100107 uint32_t link_selector;
Alexander Couzens6a161492020-07-12 13:45:50 +0200108 /* TODO: implement resource distribution
109 * add place holder for the link selector */
110 long long _resource_distribution_placeholder1;
111 long long _resource_distribution_placeholder2;
112 long long _resource_distribution_placeholder3;
113 } unitdata;
114 struct {
115 enum gprs_ns2_congestion_cause cause;
116 } congestion;
117 struct {
118 enum gprs_ns2_affecting_cause cause;
Daniel Willmann15c09a82020-11-03 23:05:43 +0100119 char *nsvc;
Alexander Couzens6a161492020-07-12 13:45:50 +0200120 /* 48.016 5.2.2.6 transfer capability */
121 int transfer;
Alexander Couzensda0a2852020-10-01 23:24:07 +0200122 /* osmocom specific */
123 /* Persistent NSE/NSVC are configured by vty */
124 bool persistent;
125 /* Only true on the first time it's available.
126 * Allow the BSSGP layer to reset persistent NSE */
127 bool first;
Alexander Couzens6a161492020-07-12 13:45:50 +0200128 } status;
129 } u;
130};
131
132/* instance */
133struct gprs_ns2_inst *gprs_ns2_instantiate(void *ctx, osmo_prim_cb cb, void *cb_data);
134void gprs_ns2_free(struct gprs_ns2_inst *inst);
135int gprs_ns2_dynamic_create_nse(struct gprs_ns2_inst *nsi, bool create_nse);
136
137/* Entrypoint for primitives from the NS USER */
138int gprs_ns2_recv_prim(struct gprs_ns2_inst *nsi, struct osmo_prim_hdr *oph);
139
Alexander Couzens6cb5d5f2020-10-11 23:23:31 +0200140/*! a callback to iterate over all NSVC */
141typedef int (*gprs_ns2_foreach_nsvc_cb)(struct gprs_ns2_vc *nsvc, void *ctx);
142
143int gprs_ns2_nse_foreach_nsvc(struct gprs_ns2_nse *nse,
144 gprs_ns2_foreach_nsvc_cb cb, void *cb_data);
Alexander Couzens6a161492020-07-12 13:45:50 +0200145struct gprs_ns2_nse *gprs_ns2_nse_by_nsei(struct gprs_ns2_inst *nsi, uint16_t nsei);
Alexander Couzensaac90162020-11-19 02:44:04 +0100146struct gprs_ns2_nse *gprs_ns2_create_nse(struct gprs_ns2_inst *nsi, uint16_t nsei,
147 enum gprs_ns2_ll linklayer);
Alexander Couzens05e7f7d2020-10-11 19:51:46 +0200148uint16_t gprs_ns2_nse_nsei(struct gprs_ns2_nse *nse);
Alexander Couzens6a161492020-07-12 13:45:50 +0200149void gprs_ns2_free_nse(struct gprs_ns2_nse *nse);
Alexander Couzens4b6c8af2020-10-11 20:15:25 +0200150void gprs_ns2_free_nses(struct gprs_ns2_inst *nsi);
Alexander Couzens6a161492020-07-12 13:45:50 +0200151
152/* create vc */
153void gprs_ns2_free_nsvc(struct gprs_ns2_vc *nsvc);
154struct gprs_ns2_vc *gprs_ns2_nsvc_by_nsvci(struct gprs_ns2_inst *nsi, uint16_t nsvci);
155
156/* IP VL driver */
157int gprs_ns2_ip_bind(struct gprs_ns2_inst *nsi,
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700158 const struct osmo_sockaddr *local,
Alexander Couzens6a161492020-07-12 13:45:50 +0200159 int dscp,
160 struct gprs_ns2_vc_bind **result);
Alexander Couzens4f608452020-10-11 18:41:24 +0200161struct gprs_ns2_vc_bind *gprs_ns2_ip_bind_by_sockaddr(struct gprs_ns2_inst *nsi,
162 const struct osmo_sockaddr *sockaddr);
Alexander Couzens6a161492020-07-12 13:45:50 +0200163void gprs_ns2_bind_set_mode(struct gprs_ns2_vc_bind *bind, enum gprs_ns2_vc_mode mode);
164
Alexander Couzens841817e2020-11-19 00:41:29 +0100165/* FR VL driver */
166struct gprs_ns2_vc_bind *gprs_ns2_fr_bind_by_netif(
167 struct gprs_ns2_inst *nsi,
168 const char *netif);
169const char *gprs_ns2_fr_bind_netif(struct gprs_ns2_vc_bind *bind);
170int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi,
171 const char *netif,
172 struct osmo_fr_network *fr_network,
173 enum osmo_fr_role fr_role,
174 struct gprs_ns2_vc_bind **result);
175int gprs_ns2_is_fr_bind(struct gprs_ns2_vc_bind *bind);
176struct gprs_ns2_vc *gprs_ns2_fr_nsvc_by_dlci(struct gprs_ns2_vc_bind *bind, uint16_t dlci);
177struct gprs_ns2_vc *gprs_ns2_fr_connect(struct gprs_ns2_vc_bind *bind,
178 uint16_t nsei,
179 uint16_t nsvci,
180 uint16_t dlci);
181
Alexander Couzens6a161492020-07-12 13:45:50 +0200182/* create a VC connection */
183struct gprs_ns2_vc *gprs_ns2_ip_connect(struct gprs_ns2_vc_bind *bind,
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700184 const struct osmo_sockaddr *remote,
Alexander Couzens6a161492020-07-12 13:45:50 +0200185 struct gprs_ns2_nse *nse,
186 uint16_t nsvci);
187
188struct gprs_ns2_vc *gprs_ns2_ip_connect2(struct gprs_ns2_vc_bind *bind,
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700189 const struct osmo_sockaddr *remote,
Alexander Couzens6a161492020-07-12 13:45:50 +0200190 uint16_t nsei,
191 uint16_t nsvci);
192struct gprs_ns2_vc *gprs_ns2_ip_connect_inactive(struct gprs_ns2_vc_bind *bind,
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700193 const struct osmo_sockaddr *remote,
Alexander Couzens6a161492020-07-12 13:45:50 +0200194 struct gprs_ns2_nse *nse,
195 uint16_t nsvci);
196
197void gprs_ns2_free_bind(struct gprs_ns2_vc_bind *bind);
Alexander Couzens896fcd52020-10-11 19:52:36 +0200198void gprs_ns2_free_binds(struct gprs_ns2_inst *nsi);
Alexander Couzens6a161492020-07-12 13:45:50 +0200199
200/* create a VC SNS connection */
201int gprs_ns2_ip_connect_sns(struct gprs_ns2_vc_bind *bind,
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700202 const struct osmo_sockaddr *remote,
Alexander Couzens6a161492020-07-12 13:45:50 +0200203 uint16_t nsei);
Alexander Couzens125298f2020-10-11 21:22:42 +0200204const struct osmo_sockaddr *gprs_ns2_nse_sns_remote(struct gprs_ns2_nse *nse);
Alexander Couzens6a161492020-07-12 13:45:50 +0200205
Alexander Couzensd33512b2020-10-11 21:42:11 +0200206const struct osmo_sockaddr *gprs_ns2_ip_vc_remote(const struct gprs_ns2_vc *nsvc);
Alexander Couzens979f5f52020-10-11 21:01:48 +0200207const struct osmo_sockaddr *gprs_ns2_ip_vc_local(const struct gprs_ns2_vc *nsvc);
Alexander Couzensd420ea92020-10-12 01:11:05 +0200208bool gprs_ns2_ip_vc_equal(const struct gprs_ns2_vc *nsvc,
209 const struct osmo_sockaddr *local,
210 const struct osmo_sockaddr *remote,
211 uint16_t nsvci);
Alexander Couzens9a4cf272020-10-11 20:48:04 +0200212const struct osmo_sockaddr *gprs_ns2_ip_bind_sockaddr(struct gprs_ns2_vc_bind *bind);
Alexander Couzens6a161492020-07-12 13:45:50 +0200213int gprs_ns2_is_ip_bind(struct gprs_ns2_vc_bind *bind);
214int gprs_ns2_ip_bind_set_dscp(struct gprs_ns2_vc_bind *bind, int dscp);
Alexander Couzens38b19e82020-09-23 23:56:37 +0200215struct gprs_ns2_vc *gprs_ns2_nsvc_by_sockaddr_bind(
Alexander Couzens6a161492020-07-12 13:45:50 +0200216 struct gprs_ns2_vc_bind *bind,
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700217 const struct osmo_sockaddr *saddr);
Alexander Couzens6a161492020-07-12 13:45:50 +0200218
219int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi,
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700220 const struct osmo_sockaddr *local,
Alexander Couzens6a161492020-07-12 13:45:50 +0200221 int dscp,
222 struct gprs_ns2_vc_bind **result);
223int gprs_ns2_is_frgre_bind(struct gprs_ns2_vc_bind *bind);
Alexander Couzens841817e2020-11-19 00:41:29 +0100224uint16_t gprs_ns2_fr_nsvc_dlci(struct gprs_ns2_vc *nsvc);
Alexander Couzens6a161492020-07-12 13:45:50 +0200225
Alexander Couzens38b19e82020-09-23 23:56:37 +0200226struct gprs_ns2_vc *gprs_ns2_nsvc_by_sockaddr_nse(
227 struct gprs_ns2_nse *nse,
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700228 const struct osmo_sockaddr *sockaddr);
Alexander Couzens6a161492020-07-12 13:45:50 +0200229void gprs_ns2_start_alive_all_nsvcs(struct gprs_ns2_nse *nse);
Daniel Willmannf1286542020-11-03 23:03:33 +0100230
231/* VC information */
Alexander Couzens6a161492020-07-12 13:45:50 +0200232const char *gprs_ns2_ll_str(struct gprs_ns2_vc *nsvc);
233char *gprs_ns2_ll_str_buf(char *buf, size_t buf_len, struct gprs_ns2_vc *nsvc);
234char *gprs_ns2_ll_str_c(const void *ctx, struct gprs_ns2_vc *nsvc);
Daniel Willmannf1286542020-11-03 23:03:33 +0100235const char *gprs_ns2_nsvc_state_name(struct gprs_ns2_vc *nsvc);
Alexander Couzens6a161492020-07-12 13:45:50 +0200236
237/* vty */
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700238int gprs_ns2_vty_init(struct gprs_ns2_inst *nsi,
239 const struct osmo_sockaddr_str *default_bind);
Alexander Couzens6a161492020-07-12 13:45:50 +0200240int gprs_ns2_vty_create();
Daniel Willmann4fb27a82020-09-25 15:39:46 +0200241void gprs_ns2_vty_force_vc_mode(bool force, enum gprs_ns2_vc_mode mode, const char *reason);
Alexander Couzens6a161492020-07-12 13:45:50 +0200242
243
244/*! @} */