blob: 2e78aeee9676dbdebdbf69c1140553ef6e7124fd [file] [log] [blame]
Harald Welte1f0b8c22011-06-27 10:51:37 +02001#ifndef _OSMOCOM_LAPDM_H
2#define _OSMOCOM_LAPDM_H
3
4#include <stdint.h>
5
6#include <osmocom/core/timer.h>
7#include <osmocom/core/msgb.h>
8#include <osmocom/gsm/prim.h>
9
10/* primitive related sutff */
11
12enum osmo_ph_prim {
13 PRIM_PH_DATA, /* PH-DATA */
14 PRIM_PH_RACH, /* PH-RANDOM_ACCESS */
15 PRIM_PH_CONN, /* PH-CONNECT */
16 PRIM_PH_EMPTY_FRAME, /* PH-EMPTY_FRAME */
17 PRIM_PH_RTS, /* PH-RTS */
18};
19
20/* for PH-RANDOM_ACCESS.req */
21struct ph_rach_req_param {
22 uint8_t ra;
23 uint8_t ta;
24 uint8_t tx_power;
25 uint8_t is_combined_ccch;
26 uint16_t offset;
27};
28
29/* for PH-RANDOM_ACCESS.ind */
30struct ph_rach_ind_param {
31 uint8_t ra;
32 uint8_t acc_delay;
33 uint32_t fn;
34};
35
36/* for PH-[UNIT]DATA.{req,ind} */
37struct ph_data_param {
38 uint8_t link_id;
39 uint8_t chan_nr;
40};
41
42struct ph_conn_ind_param {
43 uint32_t fn;
44};
45
46struct osmo_phsap_prim {
47 struct osmo_prim_hdr oph;
48 union {
49 struct ph_data_param data;
50 struct ph_rach_req_param rach_req;
51 struct ph_rach_ind_param rach_ind;
52 struct ph_conn_ind_param conn_ind;
53 } u;
54};
55
56enum lapdm_mode {
57 LAPDM_MODE_MS,
58 LAPDM_MODE_BTS,
59};
60
61enum lapdm_state {
62 LAPDm_STATE_NULL = 0,
63 LAPDm_STATE_IDLE,
64 LAPDm_STATE_SABM_SENT,
65 LAPDm_STATE_MF_EST,
66 LAPDm_STATE_TIMER_RECOV,
67 LAPDm_STATE_DISC_SENT,
68};
69
70struct lapdm_entity;
71
72struct lapdm_msg_ctx {
73 struct lapdm_datalink *dl;
74 int lapdm_fmt;
75 uint8_t n201;
76 uint8_t chan_nr;
77 uint8_t link_id;
78 uint8_t addr;
79 uint8_t ctrl;
80 uint8_t ta_ind;
81 uint8_t tx_power_ind;
82};
83
84/* TS 04.06 / Section 3.5.2 */
85struct lapdm_datalink {
86 uint8_t V_send; /* seq nr of next I frame to be transmitted */
87 uint8_t V_ack; /* last frame ACKed by peer */
88 uint8_t N_send; /* ? set to V_send at Tx time*/
89 uint8_t V_recv; /* seq nr of next I frame expected to be received */
90 uint8_t N_recv; /* expected send seq nr of the next received I frame */
91 uint32_t state;
92 int seq_err_cond; /* condition of sequence error */
93 uint8_t own_busy, peer_busy;
94 struct osmo_timer_list t200;
95 uint8_t retrans_ctr;
96 struct llist_head send_queue; /* frames from L3 */
97 struct msgb *send_buffer; /* current frame transmitting */
98 int send_out; /* how much was sent from send_buffer */
99 uint8_t tx_hist[8][200]; /* tx history buffer */
100 int tx_length[8]; /* length in history buffer */
101 struct llist_head tx_queue; /* frames to L1 */
102 struct lapdm_msg_ctx mctx; /* context of established connection */
103 struct msgb *rcv_buffer; /* buffer to assemble the received message */
104
105 struct lapdm_entity *entity;
106};
107
108enum lapdm_dl_sapi {
109 DL_SAPI0 = 0,
110 DL_SAPI3 = 1,
111 _NR_DL_SAPI
112};
113
114typedef int (*lapdm_cb_t)(struct msgb *msg, struct lapdm_entity *le, void *ctx);
115
116struct lapdm_cr_ent {
117 uint8_t cmd;
118 uint8_t resp;
119};
120
121#define LAPDM_ENT_F_EMPTY_FRAME 0x0001
122#define LAPDM_ENT_F_POLLING_ONLY 0x0002
123
124/* register message handler for messages that are sent from L2->L3 */
125struct lapdm_entity {
126 struct lapdm_datalink datalink[_NR_DL_SAPI];
127 int last_tx_dequeue; /* last entity that was dequeued */
128 int tx_pending; /* currently a pending frame not confirmed by L1 */
129 enum lapdm_mode mode; /* are we in BTS mode or MS mode */
130 unsigned int flags;
131
132 struct {
133 /* filled-in once we set the lapdm_mode above */
134 struct lapdm_cr_ent loc2rem;
135 struct lapdm_cr_ent rem2loc;
136 } cr;
137
138 void *l1_ctx; /* context for layer1 instance */
139 void *l3_ctx; /* context for layer3 instance */
140
141 osmo_prim_cb l1_prim_cb;
142 lapdm_cb_t l3_cb; /* callback for sending stuff to L3 */
143
144 struct lapdm_channel *lapdm_ch;
145};
146
147/* the two lapdm_entities that form a GSM logical channel (ACCH + DCCH) */
148struct lapdm_channel {
149 struct llist_head list;
150 char *name;
151 struct lapdm_entity lapdm_acch;
152 struct lapdm_entity lapdm_dcch;
153};
154
155const char *get_rsl_name(int value);
156extern const char *lapdm_state_names[];
157
158/* initialize a LAPDm entity */
159void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode);
160void lapdm_channel_init(struct lapdm_channel *lc, enum lapdm_mode mode);
161
162/* deinitialize a LAPDm entity */
163void lapdm_entity_exit(struct lapdm_entity *le);
164void lapdm_channel_exit(struct lapdm_channel *lc);
165
166/* input into layer2 (from layer 1) */
167int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le);
168
169/* input into layer2 (from layer 3) */
170int lapdm_rslms_recvmsg(struct msgb *msg, struct lapdm_channel *lc);
171
172void lapdm_channel_set_l3(struct lapdm_channel *lc, lapdm_cb_t cb, void *ctx);
173void lapdm_channel_set_l1(struct lapdm_channel *lc, osmo_prim_cb cb, void *ctx);
174
175int lapdm_entity_set_mode(struct lapdm_entity *le, enum lapdm_mode mode);
176int lapdm_channel_set_mode(struct lapdm_channel *lc, enum lapdm_mode mode);
177
178void lapdm_entity_reset(struct lapdm_entity *le);
179void lapdm_channel_reset(struct lapdm_channel *lc);
180
181void lapdm_entity_set_flags(struct lapdm_entity *le, unsigned int flags);
182void lapdm_channel_set_flags(struct lapdm_channel *lc, unsigned int flags);
183
184int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp);
185
186#endif /* _OSMOCOM_LAPDM_H */