aboutsummaryrefslogtreecommitdiffstats
path: root/include/osmocom/gprs/frame_relay.h
blob: 81b42a6991894ecb2dc5cb251e86bc243ae6fa73 (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
/*! \file frame_relay.h */

/* (C) 2020 Harald Welte <laforge@gnumonks.org>
 * (C) 2020 sysmocom - s.f.m.c. GmbH
 * Author: Alexander Couzens <lynxis@fe80.eu>
 *
 * All Rights Reserved
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#pragma once

#include <osmocom/core/linuxlist.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/utils.h>

#include <stdint.h>

struct osmo_tdef;
struct msgb;
struct vty;

enum osmo_fr_role {
	FR_ROLE_USER_EQUIPMENT,
	FR_ROLE_NETWORK_EQUIPMENT,
};

/* 48.016 § 6.1.4.2 default maximum information field size of 1600 octets */
#define FRAME_RELAY_MTU 1600
/* FR DLC header is 2 byte */
#define FRAME_RELAY_SDU (FRAME_RELAY_MTU - 2)

extern const struct value_string osmo_fr_role_names[];

static inline const char *osmo_fr_role_str(enum osmo_fr_role role) {
	return get_value_string(osmo_fr_role_names, role);
}

struct osmo_fr_network {
	struct llist_head links;

	unsigned int n391; 		/* full status polling counter */
	unsigned int n392;		/* error threshold */
	unsigned int n393;		/* monitored events count */

	struct osmo_tdef *T_defs;	/* T391, T392 */
};

struct osmo_fr_dlc;

/* Frame Relay Link */
struct osmo_fr_link {
	/* list in osmo_fr_network.links */
	struct llist_head list;
	struct osmo_fr_network *net;
	enum osmo_fr_role role;
	/* human-readable name */
	const char *name;

	/* value of the last received send sequence number field in the
	 * link integrity verification information element */
	uint8_t last_rx_seq;

	/* value of the send sequence number field of the last link
	 * integrity verification information element sent */
	uint8_t last_tx_seq;

	struct osmo_timer_list t391;
	struct osmo_timer_list t392;

	unsigned int polling_count;
	unsigned int err_count;
	unsigned int succeed;
	/* the type of the last status enquiry */
	uint8_t expected_rep;
	bool state;

	/* list of data link connections at this link */
	struct llist_head dlc_list;

	/* optional call-back to be called for each PDU received on an unknown DLC */
	int (*unknown_dlc_rx_cb)(void *cb_data, struct msgb *msg);
	void *unknown_dlc_rx_cb_data;

	/* call-back to be called for transmitting on the underlying hardware */
	int (*tx_cb)(void *data, struct msgb *msg);
	/* optional call-back to be called each time the status changes active/inactive */
	void (*status_cb)(struct osmo_fr_link *link, void *cb_data, bool active);
	void *cb_data;
};

/* Frame Relay Data Link Connection */
struct osmo_fr_dlc {
	/* entry in fr_link.dlc_list */
	struct llist_head list;
	struct osmo_fr_link *link;

	uint16_t dlci;

	/* is this DLC marked active for traffic? */
	bool active;
	/* was this DLC newly added? */
	bool add;
	/* is this DLC about to be destroyed */
	bool del;

	/* The local state needs to be transferred to the USER;
	 * NET must wait until USER confirms it implicitly by a seq number check */
	bool state_send;

	/* call-back to be called for each PDU received on this DLC */
	int (*rx_cb)(void *cb_data, struct msgb *msg);
	/* optional call-back to be called each time the status changes active/inactive */
	void (*status_cb)(struct osmo_fr_dlc *dlc, void *cb_data, bool active);
	void *cb_data;
};

/* allocate a frame relay network */
struct osmo_fr_network *osmo_fr_network_alloc(void *ctx);
void osmo_fr_network_free(struct osmo_fr_network *net);
void osmo_fr_network_dump_vty(struct vty *vty, const struct osmo_fr_network *net);

/* allocate a frame relay link in a given network */
struct osmo_fr_link *osmo_fr_link_alloc(struct osmo_fr_network *net, enum osmo_fr_role role, const char *name);

/* free a frame link in a given network */
void osmo_fr_link_free(struct osmo_fr_link *link);

/* allocate a data link connectoin on a given framerelay link */
struct osmo_fr_dlc *osmo_fr_dlc_alloc(struct osmo_fr_link *link, uint16_t dlci);
void osmo_fr_dlc_free(struct osmo_fr_dlc *dlc);

struct osmo_fr_dlc *osmo_fr_dlc_by_dlci(struct osmo_fr_link *link, uint16_t dlci);

int osmo_fr_rx(struct msgb *msg);
int osmo_fr_tx_dlc(struct msgb *msg);