aboutsummaryrefslogtreecommitdiffstats
path: root/include/osmocom/gprs/gprs_ns2.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/osmocom/gprs/gprs_ns2.h')
-rw-r--r--include/osmocom/gprs/gprs_ns2.h276
1 files changed, 276 insertions, 0 deletions
diff --git a/include/osmocom/gprs/gprs_ns2.h b/include/osmocom/gprs/gprs_ns2.h
new file mode 100644
index 00000000..7c7e2211
--- /dev/null
+++ b/include/osmocom/gprs/gprs_ns2.h
@@ -0,0 +1,276 @@
+/*! \file gprs_ns2.h */
+
+
+#pragma once
+
+#include <stdint.h>
+#include <netinet/in.h>
+
+#include <osmocom/core/prim.h>
+#include <osmocom/gprs/protocol/gsm_08_16.h>
+#include <osmocom/gprs/frame_relay.h>
+
+struct osmo_sockaddr;
+struct osmo_sockaddr_str;
+struct osmo_fr_network;
+
+struct gprs_ns2_inst;
+struct gprs_ns2_nse;
+struct gprs_ns2_vc;
+struct gprs_ns2_vc_bind;
+struct gprs_ns2_vc_driver;
+struct gprs_ns_ie_ip4_elem;
+struct gprs_ns_ie_ip6_elem;
+
+enum gprs_ns2_vc_mode {
+ /*! The VC will use RESET/BLOCK/UNBLOCK to start the connection and do ALIVE/ACK.
+ * This is what is needed for Frame Relay transport, and if you use a R97/R99 Gb
+ * interface over an IP transport (never standardized by 3GPP) */
+ GPRS_NS2_VC_MODE_BLOCKRESET,
+ /*! The VC will only use ALIVE/ACK (no RESET/BLOCK/UNBLOCK), which is for Gb-IP
+ * interface compliant to 3GPP Rel=4 or later. */
+ GPRS_NS2_VC_MODE_ALIVE,
+};
+
+enum gprs_ns2_dialect {
+ GPRS_NS2_DIALECT_UNDEF,
+ GPRS_NS2_DIALECT_STATIC_ALIVE,
+ GPRS_NS2_DIALECT_STATIC_RESETBLOCK,
+ GPRS_NS2_DIALECT_IPACCESS,
+ GPRS_NS2_DIALECT_SNS,
+};
+
+/*! Osmocom NS link layer types */
+enum gprs_ns2_ll {
+ GPRS_NS2_LL_UNDEF, /*!< undefined, used by vty */
+ GPRS_NS2_LL_UDP, /*!< NS/UDP/IP */
+ GPRS_NS2_LL_FR, /*!< NS/FR */
+ GPRS_NS2_LL_FR_GRE, /*!< NS/FR/GRE/IP */
+};
+
+/*! Osmocom NS primitives according to 48.016 5.2 Service primitives */
+enum gprs_ns2_prim {
+ GPRS_NS2_PRIM_UNIT_DATA,
+ GPRS_NS2_PRIM_CONGESTION,
+ GPRS_NS2_PRIM_STATUS,
+};
+
+extern const struct value_string gprs_ns2_prim_strs[];
+extern const struct value_string gprs_ns2_lltype_strs[];
+
+/*! Obtain a human-readable string for NS primitives */
+static inline const char *gprs_ns2_prim_str(enum gprs_ns2_prim val)
+{ return get_value_string(gprs_ns2_prim_strs, val); }
+
+/*! Obtain a human-readable string for NS link-layer type */
+static inline const char *gprs_ns2_lltype_str(enum gprs_ns2_ll val)
+{ return get_value_string(gprs_ns2_lltype_strs, val); }
+
+/*! Osmocom NS primitives according to 48.016 5.2.2.4 Service primitives */
+enum gprs_ns2_congestion_cause {
+ GPRS_NS2_CONG_CAUSE_BACKWARD_BEGIN,
+ GPRS_NS2_CONG_CAUSE_BACKWARD_END,
+ GPRS_NS2_CONG_CAUSE_FORWARD_BEGIN,
+ GPRS_NS2_CONG_CAUSE_FORWARD_END,
+};
+
+/*! Osmocom NS primitives according to 48.016 5.2.2.6 Service primitives */
+enum gprs_ns2_affecting_cause {
+ GPRS_NS2_AFF_CAUSE_VC_FAILURE,
+ GPRS_NS2_AFF_CAUSE_VC_RECOVERY,
+ GPRS_NS2_AFF_CAUSE_FAILURE,
+ GPRS_NS2_AFF_CAUSE_RECOVERY,
+ /* osmocom own causes */
+ GPRS_NS2_AFF_CAUSE_SNS_CONFIGURED,
+ GPRS_NS2_AFF_CAUSE_SNS_FAILURE,
+ GPRS_NS2_AFF_CAUSE_SNS_NO_ENDPOINTS,
+ GPRS_NS2_AFF_CAUSE_MTU_CHANGE,
+};
+
+extern const struct value_string gprs_ns2_aff_cause_prim_strs[];
+
+/*! Obtain a human-readable string for NS affecting cause in primitives */
+static inline const char *gprs_ns2_aff_cause_prim_str(enum gprs_ns2_affecting_cause val)
+{ return get_value_string(gprs_ns2_aff_cause_prim_strs, val); }
+
+/*! Osmocom NS primitives according to 48.016 5.2.2.7 Service primitives */
+enum gprs_ns2_change_ip_endpoint {
+ GRPS_NS2_ENDPOINT_NO_CHANGE,
+ GPRS_NS2_ENDPOINT_REQUEST_CHANGE,
+ GPRS_NS2_ENDPOINT_CONFIRM_CHANGE,
+};
+
+extern const struct value_string gprs_ns2_cause_strs[];
+
+/*! Obtain a human-readable string for NS primitives */
+static inline const char *gprs_ns2_cause_str(enum ns_cause val)
+{ return get_value_string(gprs_ns2_cause_strs, val); }
+
+struct osmo_gprs_ns2_prim {
+ struct osmo_prim_hdr oph;
+
+ uint16_t nsei;
+ uint16_t bvci;
+
+ union {
+ struct {
+ enum gprs_ns2_change_ip_endpoint change;
+ uint32_t link_selector;
+ /* TODO: implement resource distribution
+ * add place holder for the link selector */
+ long long _resource_distribution_placeholder1;
+ long long _resource_distribution_placeholder2;
+ long long _resource_distribution_placeholder3;
+ } unitdata;
+ struct {
+ enum gprs_ns2_congestion_cause cause;
+ } congestion;
+ struct {
+ enum gprs_ns2_affecting_cause cause;
+ char *nsvc;
+ /* 48.016 5.2.2.6 transfer capability */
+ int transfer;
+ /* osmocom specific */
+ /* Persistent NSE/NSVC are configured by vty */
+ bool persistent;
+ /* Only true on the first time it's available.
+ * Allow the BSSGP layer to reset persistent NSE */
+ bool first;
+ /* MTU of a NS SDU. It's the lowest MTU of all (alive & dead) NSVCs */
+ uint16_t mtu;
+ } status;
+ } u;
+};
+
+/* instance */
+struct gprs_ns2_inst *gprs_ns2_instantiate(void *ctx, osmo_prim_cb cb, void *cb_data);
+void gprs_ns2_free(struct gprs_ns2_inst *inst);
+
+/* Entrypoint for primitives from the NS USER */
+int gprs_ns2_recv_prim(struct gprs_ns2_inst *nsi, struct osmo_prim_hdr *oph);
+
+/*! a callback to iterate over all NSVC */
+typedef int (*gprs_ns2_foreach_nsvc_cb)(struct gprs_ns2_vc *nsvc, void *ctx);
+
+int gprs_ns2_nse_foreach_nsvc(struct gprs_ns2_nse *nse,
+ gprs_ns2_foreach_nsvc_cb cb, void *cb_data);
+struct gprs_ns2_nse *gprs_ns2_nse_by_nsei(struct gprs_ns2_inst *nsi, uint16_t nsei);
+struct gprs_ns2_nse *gprs_ns2_create_nse(struct gprs_ns2_inst *nsi, uint16_t nsei,
+ enum gprs_ns2_ll linklayer,
+ enum gprs_ns2_dialect dialect);
+struct gprs_ns2_nse *gprs_ns2_create_nse2(struct gprs_ns2_inst *nsi, uint16_t nsei,
+ enum gprs_ns2_ll linklayer,
+ enum gprs_ns2_dialect dialect, bool local_sgsn_role);
+uint16_t gprs_ns2_nse_nsei(struct gprs_ns2_nse *nse);
+void gprs_ns2_free_nse(struct gprs_ns2_nse *nse);
+void gprs_ns2_free_nses(struct gprs_ns2_inst *nsi);
+
+/* create vc */
+void gprs_ns2_free_nsvc(struct gprs_ns2_vc *nsvc);
+void gprs_ns2_free_nsvcs(struct gprs_ns2_nse *nse);
+struct gprs_ns2_vc *gprs_ns2_nsvc_by_nsvci(struct gprs_ns2_inst *nsi, uint16_t nsvci);
+
+/* generic VL driver */
+struct gprs_ns2_vc_bind *gprs_ns2_bind_by_name(struct gprs_ns2_inst *nsi,
+ const char *name);
+
+/* IP VL driver */
+int gprs_ns2_ip_bind(struct gprs_ns2_inst *nsi,
+ const char *name,
+ const struct osmo_sockaddr *local,
+ int dscp,
+ struct gprs_ns2_vc_bind **result);
+struct gprs_ns2_vc_bind *gprs_ns2_ip_bind_by_sockaddr(struct gprs_ns2_inst *nsi,
+ const struct osmo_sockaddr *sockaddr);
+
+/* FR VL driver */
+struct gprs_ns2_vc_bind *gprs_ns2_fr_bind_by_netif(
+ struct gprs_ns2_inst *nsi,
+ const char *netif);
+const char *gprs_ns2_fr_bind_netif(struct gprs_ns2_vc_bind *bind);
+enum osmo_fr_role gprs_ns2_fr_bind_role(struct gprs_ns2_vc_bind *bind);
+int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi,
+ const char *name,
+ const char *netif,
+ struct osmo_fr_network *fr_network,
+ enum osmo_fr_role fr_role,
+ struct gprs_ns2_vc_bind **result);
+int gprs_ns2_is_fr_bind(struct gprs_ns2_vc_bind *bind);
+struct gprs_ns2_vc *gprs_ns2_fr_nsvc_by_dlci(struct gprs_ns2_vc_bind *bind, uint16_t dlci);
+struct gprs_ns2_vc *gprs_ns2_fr_connect(struct gprs_ns2_vc_bind *bind,
+ struct gprs_ns2_nse *nse,
+ uint16_t nsvci,
+ uint16_t dlci);
+struct gprs_ns2_vc *gprs_ns2_fr_connect2(struct gprs_ns2_vc_bind *bind,
+ uint16_t nsei,
+ uint16_t nsvci,
+ uint16_t dlci);
+
+/* create a VC connection */
+struct gprs_ns2_vc *gprs_ns2_ip_connect(struct gprs_ns2_vc_bind *bind,
+ const struct osmo_sockaddr *remote,
+ struct gprs_ns2_nse *nse,
+ uint16_t nsvci);
+
+struct gprs_ns2_vc *gprs_ns2_ip_connect2(struct gprs_ns2_vc_bind *bind,
+ const struct osmo_sockaddr *remote,
+ uint16_t nsei,
+ uint16_t nsvci,
+ enum gprs_ns2_dialect dialect);
+struct gprs_ns2_vc *gprs_ns2_ip_connect_inactive(struct gprs_ns2_vc_bind *bind,
+ const struct osmo_sockaddr *remote,
+ struct gprs_ns2_nse *nse,
+ uint16_t nsvci);
+void gprs_ns2_ip_bind_set_sns_weight(struct gprs_ns2_vc_bind *bind,
+ uint8_t signalling, uint8_t data);
+
+void gprs_ns2_free_bind(struct gprs_ns2_vc_bind *bind);
+void gprs_ns2_free_binds(struct gprs_ns2_inst *nsi);
+
+/* create a VC SNS connection */
+int gprs_ns2_sns_count(struct gprs_ns2_nse *nse);
+int gprs_ns2_sns_add_endpoint(struct gprs_ns2_nse *nse,
+ const struct osmo_sockaddr *saddr);
+int gprs_ns2_sns_del_endpoint(struct gprs_ns2_nse *nse,
+ const struct osmo_sockaddr *saddr);
+int gprs_ns2_sns_add_bind(struct gprs_ns2_nse *nse, struct gprs_ns2_vc_bind *bind);
+int gprs_ns2_sns_del_bind(struct gprs_ns2_nse *nse, struct gprs_ns2_vc_bind *bind);
+const struct osmo_sockaddr *gprs_ns2_nse_sns_remote(struct gprs_ns2_nse *nse);
+
+const struct osmo_sockaddr *gprs_ns2_ip_vc_remote(const struct gprs_ns2_vc *nsvc);
+const struct osmo_sockaddr *gprs_ns2_ip_vc_local(const struct gprs_ns2_vc *nsvc);
+bool gprs_ns2_ip_vc_equal(const struct gprs_ns2_vc *nsvc,
+ const struct osmo_sockaddr *local,
+ const struct osmo_sockaddr *remote,
+ uint16_t nsvci);
+const struct osmo_sockaddr *gprs_ns2_ip_bind_sockaddr(struct gprs_ns2_vc_bind *bind);
+int gprs_ns2_is_ip_bind(struct gprs_ns2_vc_bind *bind);
+int gprs_ns2_ip_bind_set_dscp(struct gprs_ns2_vc_bind *bind, int dscp);
+int gprs_ns2_ip_bind_set_priority(struct gprs_ns2_vc_bind *bind, uint8_t priority);
+struct gprs_ns2_vc *gprs_ns2_nsvc_by_sockaddr_bind(
+ struct gprs_ns2_vc_bind *bind,
+ const struct osmo_sockaddr *rem_addr);
+
+int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi,
+ const char *name,
+ const struct osmo_sockaddr *local,
+ int dscp,
+ struct gprs_ns2_vc_bind **result);
+int gprs_ns2_is_frgre_bind(struct gprs_ns2_vc_bind *bind);
+uint16_t gprs_ns2_fr_nsvc_dlci(const struct gprs_ns2_vc *nsvc);
+
+struct gprs_ns2_vc *gprs_ns2_nsvc_by_sockaddr_nse(
+ struct gprs_ns2_nse *nse,
+ const struct osmo_sockaddr *sockaddr);
+void gprs_ns2_start_alive_all_nsvcs(struct gprs_ns2_nse *nse);
+
+/* VC information */
+const char *gprs_ns2_ll_str(struct gprs_ns2_vc *nsvc);
+char *gprs_ns2_ll_str_buf(char *buf, size_t buf_len, struct gprs_ns2_vc *nsvc);
+char *gprs_ns2_ll_str_c(const void *ctx, struct gprs_ns2_vc *nsvc);
+const char *gprs_ns2_nsvc_state_name(struct gprs_ns2_vc *nsvc);
+
+/* vty */
+int gprs_ns2_vty_init(struct gprs_ns2_inst *nsi);
+
+/*! @} */