blob: 12697285ff40b4f4ac162dea29e7ce5d0398966f [file] [log] [blame]
Harald Weltef5e72642022-10-30 22:20:55 +01001#pragma once
2
3/* Osmocom Software Defined E1
4 * Implements ITU-T Rec. G.704 Section 2.3
5 *
6 * (C) 2018 by Harald Welte <laforge@gnumonks.org>
7 * All Rights Reserved
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published
13 * by the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 */
21
22#include <stdint.h>
23#include <stdbool.h>
24#include <osmocom/core/msgb.h>
25#include <osmocom/core/linuxlist.h>
26#include <osmocom/core/fsm.h>
27#include <osmocom/core/isdnhdlc.h>
28
29struct osmo_e1f_tx_state {
30 bool remote_alarm;
31 bool crc4_error;
32 /* lower 5 bits: Sa4..Sa8 */
33 uint8_t sa4_sa8;
34 /* frame number 0..15 */
35 uint8_t frame_nr;
36 uint8_t crc4_last_smf;
37 uint8_t crc4;
38};
39
40struct osmo_e1f_rx_state {
41 uint8_t frame_nr;
42 /* history of rceived TS0 octets */
43 uint8_t ts0_history[16];
44 uint8_t ts0_hist_len;
45 /* was a remote alarm received? */
46 bool remote_alarm;
47 bool remote_crc4_error;
48 /* number of TS0 bytes received since entering CRC mframe search */
49 uint8_t num_ts0_in_mframe_search;
50 struct osmo_fsm_inst *fi;
51 /* computed CRC4 */
52 uint8_t crc4_last_smf;
53 uint8_t crc4;
54};
55
56enum osmo_e1f_notify_event {
57 E1_NTFY_EVT_ALIGN_FRAME,
58 E1_NTFY_EVT_ALIGN_CRC_MFRAME,
59 E1_NTFY_EVT_CRC_ERROR,
60 E1_NTFY_EVT_REMOTE_CRC_ERROR,
61 E1_NTFY_EVT_REMOTE_ALARM,
62};
63
64enum osmo_e1f_ts_mode {
65 OSMO_E1F_TS_RAW,
66 OSMO_E1F_TS_HDLC_CRC,
67};
68
69struct osmo_e1f_instance_ts;
70struct osmo_e1f_instance;
71typedef void (*e1_data_cb)(struct osmo_e1f_instance_ts *ts, struct msgb *msg);
72typedef void (*e1_notify_cb)(struct osmo_e1f_instance *e1i, enum osmo_e1f_notify_event evt,
73 bool present, void *data);
74
75struct osmo_e1f_instance_ts {
76 /* timeslot number */
77 uint8_t ts_nr;
78 /* mode in which we operate (RAW/HDLC) */
79 enum osmo_e1f_ts_mode mode;
80 /* back-pointer to e1 instance */
81 struct osmo_e1f_instance *inst;
82 struct {
83 /* optional HDLC encoder state */
84 struct osmo_isdnhdlc_vars hdlc;
85 /* queue of pending to-be-transmitted messages */
86 struct llist_head queue;
87 unsigned long underruns;
88 } tx;
89 struct {
90 /* optional HDLC decoder state */
91 struct osmo_isdnhdlc_vars hdlc;
92 bool enabled;
93 /* how many bytes to buffer before calling call-back */
94 unsigned int granularity;
95 /* current receive buffer */
96 struct msgb *msg;
97 e1_data_cb data_cb;
98 /* private data, relevant to user */
99 void *priv;
100 } rx;
101};
102
103struct osmo_e1f_instance {
104 /* list; currently not used yet */
105 struct llist_head list;
106
107 /* is CRC4 generation + parsing enabled? */
108 bool crc4_enabled;
109 /* notification call-back function */
110 e1_notify_cb notify_cb;
111
112 /* Rx + Tx related state */
113 struct osmo_e1f_tx_state tx;
114 struct osmo_e1f_rx_state rx;
115
116 /* our 32 timeslots (only 1..32 are used) */
117 struct osmo_e1f_instance_ts ts[32];
118
119 /* private data, relevant to user */
120 void *priv;
121};
122
123extern const struct value_string osmo_e1f_notifv_evt_names[];
124
125static inline const char *osmo_e1f_notify_event_name(enum osmo_e1f_notify_event evt) {
126 return get_value_string(osmo_e1f_notifv_evt_names, evt);
127}
128
129int osmo_e1f_init(void);
130struct osmo_e1f_instance_ts *osmo_e1f_instance_ts(struct osmo_e1f_instance *e1i, uint8_t ts_nr);
131int osmo_e1f_instance_init(struct osmo_e1f_instance *e1i, const char *name, e1_notify_cb cb,
132 bool crc4_enabled, void *priv);
133void osmo_e1f_instance_reset(struct osmo_e1f_instance *e1i);
134int osmo_e1f_ts_config(struct osmo_e1f_instance_ts *e1t, e1_data_cb cb, unsigned int granularity,
135 bool enable, enum osmo_e1f_ts_mode mode);
136void osmo_e1f_ts_reset(struct osmo_e1f_instance_ts *e1t);
137
138
139void osmo_e1f_ts_enqueue(struct osmo_e1f_instance_ts *e1t, struct msgb *msg);
140int osmo_e1f_pull_tx_frame(struct osmo_e1f_instance *e1i, uint8_t *out_frame);
141int osmo_e1f_rx_frame(struct osmo_e1f_instance *e1i, const uint8_t *in_frame);