aboutsummaryrefslogtreecommitdiffstats
path: root/include/osmocom/gprs/gprs_ns2.h
blob: cd2de96f4e79f264805016b922624901f4bbb499 (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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*! \file gprs_ns2.h */


#pragma once

#include <stdint.h>
#include <netinet/in.h>

#include <osmocom/core/prim.h>

struct osmo_sockaddr;

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 {
	NS2_VC_MODE_BLOCKRESET, /* The VC will use RESET/BLOCK/UNBLOCK to start the connection and do ALIVE/ACK */
	NS2_VC_MODE_ALIVE, /* The will only use ALIVE/ACK */
};

/*! Osmocom NS primitives according to 48.016 5.2 Service primitves */
enum gprs_ns2_prim {
	PRIM_NS_UNIT_DATA,
	PRIM_NS_CONGESTION,
	PRIM_NS_STATUS,
};

/*! Osmocom NS primitives according to 48.016 5.2.2.4 Service primitves */
enum gprs_ns2_congestion_cause {
	NS_CONG_CAUSE_BACKWARD_BEGIN,
	NS_CONG_CAUSE_BACKWARD_END,
	NS_CONG_CAUSE_FORWARD_BEGIN,
	NS_CONG_CAUSE_FORWARD_END,
};

/*! Osmocom NS primitives according to 48.016 5.2.2.6 Service primitves */
enum gprs_ns2_affecting_cause {
	NS_AFF_CAUSE_VC_FAILURE,
	NS_AFF_CAUSE_VC_RECOVERY,
	NS_AFF_CAUSE_FAILURE,
	NS_AFF_CAUSE_RECOVERY,
	/* osmocom own causes */
	NS_AFF_CAUSE_SNS_CONFIGURED,
	NS_AFF_CAUSE_SNS_FAILURE,
};

/*! Osmocom NS primitives according to 48.016 5.2.2.7 Service primitves */
enum gprs_ns2_change_ip_endpoint {
	NS_ENDPOINT_NO_CHANGE,
	NS_ENDPOINT_REQUEST_CHANGE,
	NS_ENDPOINT_CONFIRM_CHANGE,
};

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;
			/* 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;
			/* 48.016 5.2.2.6 transfer capability */
			int transfer;
		} 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);
int gprs_ns2_dynamic_create_nse(struct gprs_ns2_inst *nsi, bool create_nse);

/* Entrypoint for primitives from the NS USER */
int gprs_ns2_recv_prim(struct gprs_ns2_inst *nsi, struct osmo_prim_hdr *oph);

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);
void gprs_ns2_free_nse(struct gprs_ns2_nse *nse);

/* create vc */
void gprs_ns2_free_nsvc(struct gprs_ns2_vc *nsvc);
struct gprs_ns2_vc *gprs_ns2_nsvc_by_nsvci(struct gprs_ns2_inst *nsi, uint16_t nsvci);

/* IP VL driver */
int gprs_ns2_ip_bind(struct gprs_ns2_inst *nsi,
		     struct osmo_sockaddr *local,
		     int dscp,
		     struct gprs_ns2_vc_bind **result);
void gprs_ns2_bind_set_mode(struct gprs_ns2_vc_bind *bind, enum gprs_ns2_vc_mode mode);

/* create a VC connection */
struct gprs_ns2_vc *gprs_ns2_ip_connect(struct gprs_ns2_vc_bind *bind,
					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,
					 struct osmo_sockaddr *remote,
					 uint16_t nsei,
					 uint16_t nsvci);
struct gprs_ns2_vc *gprs_ns2_ip_connect_inactive(struct gprs_ns2_vc_bind *bind,
					struct osmo_sockaddr *remote,
					struct gprs_ns2_nse *nse,
					uint16_t nsvci);

void gprs_ns2_free_bind(struct gprs_ns2_vc_bind *bind);

/* create a VC SNS connection */
int gprs_ns2_ip_connect_sns(struct gprs_ns2_vc_bind *bind,
			    struct osmo_sockaddr *remote,
			    uint16_t nsei);

struct osmo_sockaddr *gprs_ns2_ip_vc_sockaddr(struct gprs_ns2_vc *nsvc);
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);
struct gprs_ns2_vc *gprs_ns2_nsvc_by_sockaddr_bind(
		struct gprs_ns2_vc_bind *bind,
		struct osmo_sockaddr *saddr);

int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi,
			struct osmo_sockaddr *local,
			int dscp,
			struct gprs_ns2_vc_bind **result);
int gprs_ns2_is_frgre_bind(struct gprs_ns2_vc_bind *bind);

struct gprs_ns2_vc *gprs_ns2_nsvc_by_sockaddr_nse(
		struct gprs_ns2_nse *nse,
		struct osmo_sockaddr *sockaddr);
void gprs_ns2_start_alive_all_nsvcs(struct gprs_ns2_nse *nse);
const char *gprs_ns2_cause_str(int cause);
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);

/* vty */
int gprs_ns2_vty_init(struct gprs_ns2_inst *nsi);
int gprs_ns2_vty_create();
void gprs_ns2_vty_force_vc_mode(bool force, enum gprs_ns2_vc_mode mode, char *reason);


/*! @} */