blob: 4ad7556848e8d348692f4f3989d897ee08cc36a9 [file] [log] [blame]
rootaf48bed2011-09-26 11:23:06 +02001/* LAPD core implementation */
2
3/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org>
4 * (C) 2010-2011 by Andreas Eversberg <jolly@eversberg.eu>
5 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
24/*! \addtogroup lapd
25 * @{
Neels Hofmeyr87e45502017-06-20 00:17:59 +020026 * Osmocom LAPD core, used for Q.921, LAPDm and others
rootaf48bed2011-09-26 11:23:06 +020027 */
28
Katerina Barone-Adesic28c6a02013-02-15 13:27:59 +010029/*! \file lapd_core.c */
rootaf48bed2011-09-26 11:23:06 +020030
31/*!
32 * Notes on Buffering: rcv_buffer, tx_queue, tx_hist, send_buffer, send_queue
33 *
34 * RX data is stored in the rcv_buffer (pointer). If the message is complete, it
35 * is removed from rcv_buffer pointer and forwarded to L3. If the RX data is
36 * received while there is an incomplete rcv_buffer, it is appended to it.
37 *
38 * TX data is stored in the send_queue first. When transmitting a frame,
39 * the first message in the send_queue is moved to the send_buffer. There it
40 * resides until all fragments are acknowledged. Fragments to be sent by I
41 * frames are stored in the tx_hist buffer for resend, if required. Also the
42 * current fragment is copied into the tx_queue. There it resides until it is
43 * forwarded to layer 1.
44 *
45 * In case we have SAPI 0, we only have a window size of 1, so the unack-
46 * nowledged message resides always in the send_buffer. In case of a suspend,
47 * it can be written back to the first position of the send_queue.
48 *
49 * The layer 1 normally sends a PH-READY-TO-SEND. But because we use
50 * asynchronous transfer between layer 1 and layer 2 (serial link), we must
51 * send a frame before layer 1 reaches the right timeslot to send it. So we
52 * move the tx_queue to layer 1 when there is not already a pending frame, and
53 * wait until acknowledge after the frame has been sent. If we receive an
54 * acknowledge, we can send the next frame from the buffer, if any.
55 *
56 * The moving of tx_queue to layer 1 may also trigger T200, if desired. Also it
57 * will trigger next I frame, if possible.
58 *
59 * T203 is optional. It will be stated when entering MF EST state. It will also
60 * be started when I or S frame is received in that state . It will be
61 * restarted in the lapd_acknowledge() function, in case outstanding frames
62 * will not trigger T200. It will be stoped, when T200 is started in MF EST
63 * state. It will also be stoped when leaving MF EST state.
64 *
65 */
66
67/* Enable this to test content resolution on network side:
68 * - The first SABM is received, UA is dropped.
69 * - The phone repeats SABM, but it's content is wrong, so it is ignored
70 * - The phone repeats SABM again, content is right, so UA is sent.
71 */
72//#define TEST_CONTENT_RESOLUTION_NETWORK
73
74#include <stdio.h>
75#include <stdint.h>
76#include <string.h>
77#include <errno.h>
rootaf48bed2011-09-26 11:23:06 +020078
79#include <osmocom/core/logging.h>
80#include <osmocom/core/timer.h>
81#include <osmocom/core/msgb.h>
82#include <osmocom/core/utils.h>
83#include <osmocom/core/talloc.h>
84#include <osmocom/gsm/lapd_core.h>
Max2f0b0c92017-01-12 16:47:13 +010085#include <osmocom/gsm/rsl.h>
rootaf48bed2011-09-26 11:23:06 +020086
87/* TS 04.06 Table 4 / Section 3.8.1 */
88#define LAPD_U_SABM 0x7
89#define LAPD_U_SABME 0xf
90#define LAPD_U_DM 0x3
91#define LAPD_U_UI 0x0
92#define LAPD_U_DISC 0x8
93#define LAPD_U_UA 0xC
94#define LAPD_U_FRMR 0x11
95
96#define LAPD_S_RR 0x0
97#define LAPD_S_RNR 0x1
98#define LAPD_S_REJ 0x2
99
100#define CR_USER2NET_CMD 0
101#define CR_USER2NET_RESP 1
102#define CR_NET2USER_CMD 1
103#define CR_NET2USER_RESP 0
104
105#define LAPD_HEADROOM 56
106
107#define SBIT(a) (1 << a)
108#define ALL_STATES 0xffffffff
109
Andreas Eversberg742fc792011-09-27 09:40:25 +0200110static void lapd_t200_cb(void *data);
111static void lapd_t203_cb(void *data);
112static int lapd_send_i(struct lapd_msg_ctx *lctx, int line);
113static int lapd_est_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx);
114
rootaf48bed2011-09-26 11:23:06 +0200115/* UTILITY FUNCTIONS */
116
117struct msgb *lapd_msgb_alloc(int length, const char *name)
118{
119 /* adding space for padding, FIXME: add as an option */
120 if (length < 21)
121 length = 21;
122 return msgb_alloc_headroom(length + LAPD_HEADROOM, LAPD_HEADROOM, name);
123}
124
125static inline uint8_t do_mod(uint8_t x, uint8_t m)
126{
127 return x & (m - 1);
128}
129
130static inline uint8_t inc_mod(uint8_t x, uint8_t m)
131{
132 return (x + 1) & (m - 1);
133}
134
135static inline uint8_t add_mod(uint8_t x, uint8_t y, uint8_t m)
136{
137 return (x + y) & (m - 1);
138}
139
140static inline uint8_t sub_mod(uint8_t x, uint8_t y, uint8_t m)
141{
142 return (x - y) & (m - 1); /* handle negative results correctly */
143}
144
145static void lapd_dl_flush_send(struct lapd_datalink *dl)
146{
147 struct msgb *msg;
148
149 /* Flush send-queue */
150 while ((msg = msgb_dequeue(&dl->send_queue)))
151 msgb_free(msg);
152
153 /* Clear send-buffer */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +0200154 msgb_free(dl->send_buffer);
155 dl->send_buffer = NULL;
rootaf48bed2011-09-26 11:23:06 +0200156}
157
158static void lapd_dl_flush_hist(struct lapd_datalink *dl)
159{
160 unsigned int i;
161
Harald Weltef92e44c2016-08-01 00:24:19 +0200162 if (!dl->range_hist || !dl->tx_hist)
Harald Welte0ee90f82016-07-03 20:45:21 +0200163 return;
164
rootaf48bed2011-09-26 11:23:06 +0200165 for (i = 0; i < dl->range_hist; i++) {
166 if (dl->tx_hist[i].msg) {
167 msgb_free(dl->tx_hist[i].msg);
168 dl->tx_hist[i].msg = NULL;
169 }
170 }
171}
172
173static void lapd_dl_flush_tx(struct lapd_datalink *dl)
174{
175 struct msgb *msg;
176
177 while ((msg = msgb_dequeue(&dl->tx_queue)))
178 msgb_free(msg);
179 lapd_dl_flush_hist(dl);
180}
181
182/* Figure B.2/Q.921 */
Harald Weltec733d142017-03-15 10:20:51 +0100183const struct value_string lapd_state_names[] = {
184 OSMO_VALUE_STRING(LAPD_STATE_NULL),
185 OSMO_VALUE_STRING(LAPD_STATE_TEI_UNASS),
186 OSMO_VALUE_STRING(LAPD_STATE_ASS_TEI_WAIT),
187 OSMO_VALUE_STRING(LAPD_STATE_EST_TEI_WAIT),
188 OSMO_VALUE_STRING(LAPD_STATE_IDLE),
189 OSMO_VALUE_STRING(LAPD_STATE_SABM_SENT),
190 OSMO_VALUE_STRING(LAPD_STATE_DISC_SENT),
191 OSMO_VALUE_STRING(LAPD_STATE_MF_EST),
192 OSMO_VALUE_STRING(LAPD_STATE_TIMER_RECOV),
193 { 0, NULL }
rootaf48bed2011-09-26 11:23:06 +0200194};
195
Harald Weltec733d142017-03-15 10:20:51 +0100196static inline const char *lapd_state_name(enum lapd_state state)
197{
198 return get_value_string(lapd_state_names, state);
199}
200
Andreas Eversberg742fc792011-09-27 09:40:25 +0200201static void lapd_start_t200(struct lapd_datalink *dl)
202{
203 if (osmo_timer_pending(&dl->t200))
204 return;
Philipp Maier08177d32016-12-08 17:23:26 +0100205 LOGP(DLLAPD, LOGL_INFO, "start T200 (dl=%p)\n", dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +0200206 osmo_timer_schedule(&dl->t200, dl->t200_sec, dl->t200_usec);
207}
208
209static void lapd_start_t203(struct lapd_datalink *dl)
210{
211 if (osmo_timer_pending(&dl->t203))
212 return;
Philipp Maier08177d32016-12-08 17:23:26 +0100213 LOGP(DLLAPD, LOGL_INFO, "start T203 (dl=%p)\n", dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +0200214 osmo_timer_schedule(&dl->t203, dl->t203_sec, dl->t203_usec);
215}
216
217static void lapd_stop_t200(struct lapd_datalink *dl)
218{
219 if (!osmo_timer_pending(&dl->t200))
220 return;
Philipp Maier08177d32016-12-08 17:23:26 +0100221 LOGP(DLLAPD, LOGL_INFO, "stop T200 (dl=%p)\n", dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +0200222 osmo_timer_del(&dl->t200);
223}
224
225static void lapd_stop_t203(struct lapd_datalink *dl)
226{
227 if (!osmo_timer_pending(&dl->t203))
228 return;
Philipp Maier08177d32016-12-08 17:23:26 +0100229 LOGP(DLLAPD, LOGL_INFO, "stop T203 (dl=%p)\n", dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +0200230 osmo_timer_del(&dl->t203);
231}
232
rootaf48bed2011-09-26 11:23:06 +0200233static void lapd_dl_newstate(struct lapd_datalink *dl, uint32_t state)
234{
Philipp Maier08177d32016-12-08 17:23:26 +0100235 LOGP(DLLAPD, LOGL_INFO, "new state %s -> %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100236 lapd_state_name(dl->state), lapd_state_name(state), dl);
rootaf48bed2011-09-26 11:23:06 +0200237
238 if (state != LAPD_STATE_MF_EST && dl->state == LAPD_STATE_MF_EST) {
239 /* stop T203 on leaving MF EST state, if running */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200240 lapd_stop_t203(dl);
rootaf48bed2011-09-26 11:23:06 +0200241 /* remove content res. (network side) on leaving MF EST state */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +0200242 msgb_free(dl->cont_res);
243 dl->cont_res = NULL;
rootaf48bed2011-09-26 11:23:06 +0200244 }
245
246 /* start T203 on entering MF EST state, if enabled */
247 if ((dl->t203_sec || dl->t203_usec)
Andreas Eversberg742fc792011-09-27 09:40:25 +0200248 && state == LAPD_STATE_MF_EST && dl->state != LAPD_STATE_MF_EST)
249 lapd_start_t203(dl);
rootaf48bed2011-09-26 11:23:06 +0200250
251 dl->state = state;
252}
253
rootaf48bed2011-09-26 11:23:06 +0200254static void *tall_lapd_ctx = NULL;
255
256/* init datalink instance and allocate history */
257void lapd_dl_init(struct lapd_datalink *dl, uint8_t k, uint8_t v_range,
258 int maxf)
259{
260 int m;
261
262 memset(dl, 0, sizeof(*dl));
263 INIT_LLIST_HEAD(&dl->send_queue);
264 INIT_LLIST_HEAD(&dl->tx_queue);
265 dl->reestablish = 1;
266 dl->n200_est_rel = 3;
267 dl->n200 = 3;
268 dl->t200_sec = 1;
269 dl->t200_usec = 0;
Pablo Neira Ayuso44f423f2017-05-08 18:00:28 +0200270 osmo_timer_setup(&dl->t200, lapd_t200_cb, dl);
rootaf48bed2011-09-26 11:23:06 +0200271 dl->t203_sec = 10;
272 dl->t203_usec = 0;
Pablo Neira Ayuso44f423f2017-05-08 18:00:28 +0200273 osmo_timer_setup(&dl->t203, lapd_t203_cb, dl);
rootaf48bed2011-09-26 11:23:06 +0200274 dl->maxf = maxf;
275 if (k > v_range - 1)
276 k = v_range - 1;
277 dl->k = k;
278 dl->v_range = v_range;
279
280 /* Calculate modulo for history array:
281 * - The history range must be at least k+1.
282 * - The history range must be 2^x, where x is as low as possible.
283 */
284 k++;
285 for (m = 0x80; m; m >>= 1) {
286 if ((m & k)) {
287 if (k > m)
288 m <<= 1;
289 dl->range_hist = m;
290 break;
291 }
292 }
293
294 LOGP(DLLAPD, LOGL_INFO, "Init DL layer: sequence range = %d, k = %d, "
Philipp Maier08177d32016-12-08 17:23:26 +0100295 "history range = %d (dl=%p)\n", dl->v_range, dl->k,
296 dl->range_hist, dl);
rootaf48bed2011-09-26 11:23:06 +0200297
298 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
299
300 if (!tall_lapd_ctx)
301 tall_lapd_ctx = talloc_named_const(NULL, 1, "lapd context");
Holger Hans Peter Freyther10f0bde2014-02-09 20:03:38 +0100302 dl->tx_hist = talloc_zero_array(tall_lapd_ctx,
303 struct lapd_history, dl->range_hist);
rootaf48bed2011-09-26 11:23:06 +0200304}
305
306/* reset to IDLE state */
307void lapd_dl_reset(struct lapd_datalink *dl)
308{
rootaf48bed2011-09-26 11:23:06 +0200309 /* flush buffer */
310 lapd_dl_flush_tx(dl);
311 lapd_dl_flush_send(dl);
312 /* Discard partly received L3 message */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +0200313 msgb_free(dl->rcv_buffer);
314 dl->rcv_buffer = NULL;
Andreas Eversberg742fc792011-09-27 09:40:25 +0200315 /* stop Timers */
316 lapd_stop_t200(dl);
317 lapd_stop_t203(dl);
Jean-Francois Dionned78c9732017-03-06 14:33:20 -0500318 if (dl->state == LAPD_STATE_IDLE)
319 return;
320 LOGP(DLLAPD, LOGL_INFO, "Resetting LAPDm instance (dl=%p)\n", dl);
321 /* enter idle state (and remove eventual cont_res) */
322 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
rootaf48bed2011-09-26 11:23:06 +0200323}
324
325/* reset and de-allocate history buffer */
326void lapd_dl_exit(struct lapd_datalink *dl)
327{
328 /* free all ressources except history buffer */
329 lapd_dl_reset(dl);
330 /* free history buffer list */
331 talloc_free(dl->tx_hist);
Holger Hans Peter Freytherf5a079f2013-05-08 18:42:39 +0200332 dl->tx_hist = NULL;
rootaf48bed2011-09-26 11:23:06 +0200333}
334
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200335/*! Set the \ref lapdm_mode of a LAPDm entity */
rootaf48bed2011-09-26 11:23:06 +0200336int lapd_set_mode(struct lapd_datalink *dl, enum lapd_mode mode)
337{
338 switch (mode) {
339 case LAPD_MODE_USER:
340 dl->cr.loc2rem.cmd = CR_USER2NET_CMD;
341 dl->cr.loc2rem.resp = CR_USER2NET_RESP;
342 dl->cr.rem2loc.cmd = CR_NET2USER_CMD;
343 dl->cr.rem2loc.resp = CR_NET2USER_RESP;
344 break;
345 case LAPD_MODE_NETWORK:
346 dl->cr.loc2rem.cmd = CR_NET2USER_CMD;
347 dl->cr.loc2rem.resp = CR_NET2USER_RESP;
348 dl->cr.rem2loc.cmd = CR_USER2NET_CMD;
349 dl->cr.rem2loc.resp = CR_USER2NET_RESP;
350 break;
351 default:
352 return -EINVAL;
353 }
354 dl->mode = mode;
355
356 return 0;
357}
358
359/* send DL message with optional msgb */
360static int send_dl_l3(uint8_t prim, uint8_t op, struct lapd_msg_ctx *lctx,
361 struct msgb *msg)
362{
363 struct lapd_datalink *dl = lctx->dl;
364 struct osmo_dlsap_prim dp;
365
366 osmo_prim_init(&dp.oph, 0, prim, op, msg);
367 return dl->send_dlsap(&dp, lctx);
368}
369
370/* send simple DL message */
371static inline int send_dl_simple(uint8_t prim, uint8_t op,
372 struct lapd_msg_ctx *lctx)
373{
374 struct msgb *msg = lapd_msgb_alloc(0, "DUMMY");
375
376 return send_dl_l3(prim, op, lctx, msg);
377}
378
379/* send MDL-ERROR INDICATION */
380static int mdl_error(uint8_t cause, struct lapd_msg_ctx *lctx)
381{
382 struct lapd_datalink *dl = lctx->dl;
383 struct osmo_dlsap_prim dp;
384
Philipp Maier08177d32016-12-08 17:23:26 +0100385 LOGP(DLLAPD, LOGL_NOTICE,
386 "sending MDL-ERROR-IND cause %d from state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100387 cause, lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +0200388 osmo_prim_init(&dp.oph, 0, PRIM_MDL_ERROR, PRIM_OP_INDICATION, NULL);
389 dp.u.error_ind.cause = cause;
390 return dl->send_dlsap(&dp, lctx);
391}
392
393/* send UA response */
394static int lapd_send_ua(struct lapd_msg_ctx *lctx, uint8_t len, uint8_t *data)
395{
396 struct msgb *msg = lapd_msgb_alloc(len, "LAPD UA");
397 struct lapd_msg_ctx nctx;
398 struct lapd_datalink *dl = lctx->dl;
399
400 memcpy(&nctx, lctx, sizeof(nctx));
401 msg->l3h = msgb_put(msg, len);
402 if (len)
403 memcpy(msg->l3h, data, len);
404 /* keep nctx.ldp */
405 /* keep nctx.sapi */
406 /* keep nctx.tei */
407 nctx.cr = dl->cr.loc2rem.resp;
408 nctx.format = LAPD_FORM_U;
409 nctx.s_u = LAPD_U_UA;
410 /* keep nctx.p_f */
411 nctx.length = len;
412 nctx.more = 0;
413
414 return dl->send_ph_data_req(&nctx, msg);
415}
416
417/* send DM response */
418static int lapd_send_dm(struct lapd_msg_ctx *lctx)
419{
420 struct msgb *msg = lapd_msgb_alloc(0, "LAPD DM");
421 struct lapd_msg_ctx nctx;
422 struct lapd_datalink *dl = lctx->dl;
423
424 memcpy(&nctx, lctx, sizeof(nctx));
425 /* keep nctx.ldp */
426 /* keep nctx.sapi */
427 /* keep nctx.tei */
428 nctx.cr = dl->cr.loc2rem.resp;
429 nctx.format = LAPD_FORM_U;
430 nctx.s_u = LAPD_U_DM;
431 /* keep nctx.p_f */
432 nctx.length = 0;
433 nctx.more = 0;
434
435 return dl->send_ph_data_req(&nctx, msg);
436}
437
438/* send RR response / command */
439static int lapd_send_rr(struct lapd_msg_ctx *lctx, uint8_t f_bit, uint8_t cmd)
440{
441 struct msgb *msg = lapd_msgb_alloc(0, "LAPD RR");
442 struct lapd_msg_ctx nctx;
443 struct lapd_datalink *dl = lctx->dl;
444
445 memcpy(&nctx, lctx, sizeof(nctx));
446 /* keep nctx.ldp */
447 /* keep nctx.sapi */
448 /* keep nctx.tei */
449 nctx.cr = (cmd) ? dl->cr.loc2rem.cmd : dl->cr.loc2rem.resp;
450 nctx.format = LAPD_FORM_S;
451 nctx.s_u = LAPD_S_RR;
452 nctx.p_f = f_bit;
453 nctx.n_recv = dl->v_recv;
454 nctx.length = 0;
455 nctx.more = 0;
456
457 return dl->send_ph_data_req(&nctx, msg);
458}
459
460/* send RNR response / command */
461static int lapd_send_rnr(struct lapd_msg_ctx *lctx, uint8_t f_bit, uint8_t cmd)
462{
463 struct msgb *msg = lapd_msgb_alloc(0, "LAPD RNR");
464 struct lapd_msg_ctx nctx;
465 struct lapd_datalink *dl = lctx->dl;
466
467 memcpy(&nctx, lctx, sizeof(nctx));
468 /* keep nctx.ldp */
469 /* keep nctx.sapi */
470 /* keep nctx.tei */
471 nctx.cr = (cmd) ? dl->cr.loc2rem.cmd : dl->cr.loc2rem.resp;
472 nctx.format = LAPD_FORM_S;
473 nctx.s_u = LAPD_S_RNR;
474 nctx.p_f = f_bit;
475 nctx.n_recv = dl->v_recv;
476 nctx.length = 0;
477 nctx.more = 0;
478
479 return dl->send_ph_data_req(&nctx, msg);
480}
481
482/* send REJ response */
483static int lapd_send_rej(struct lapd_msg_ctx *lctx, uint8_t f_bit)
484{
485 struct msgb *msg = lapd_msgb_alloc(0, "LAPD REJ");
486 struct lapd_msg_ctx nctx;
487 struct lapd_datalink *dl = lctx->dl;
488
489 memcpy(&nctx, lctx, sizeof(nctx));
490 /* keep nctx.ldp */
491 /* keep nctx.sapi */
492 /* keep nctx.tei */
493 nctx.cr = dl->cr.loc2rem.resp;
494 nctx.format = LAPD_FORM_S;
495 nctx.s_u = LAPD_S_REJ;
496 nctx.p_f = f_bit;
497 nctx.n_recv = dl->v_recv;
498 nctx.length = 0;
499 nctx.more = 0;
500
501 return dl->send_ph_data_req(&nctx, msg);
502}
503
504/* resend SABM or DISC message */
505static int lapd_send_resend(struct lapd_datalink *dl)
506{
507 struct msgb *msg;
508 uint8_t h = do_mod(dl->v_send, dl->range_hist);
509 int length = dl->tx_hist[h].msg->len;
510 struct lapd_msg_ctx nctx;
511
512 /* assemble message */
513 memcpy(&nctx, &dl->lctx, sizeof(nctx));
514 /* keep nctx.ldp */
515 /* keep nctx.sapi */
516 /* keep nctx.tei */
517 nctx.cr = dl->cr.loc2rem.cmd;
518 nctx.format = LAPD_FORM_U;
519 if (dl->state == LAPD_STATE_SABM_SENT)
520 nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
521 else
522 nctx.s_u = LAPD_U_DISC;
523 nctx.p_f = 1;
524 nctx.length = length;
525 nctx.more = 0;
526
527 /* Resend SABM/DISC from tx_hist */
528 msg = lapd_msgb_alloc(length, "LAPD resend");
529 msg->l3h = msgb_put(msg, length);
530 if (length)
531 memcpy(msg->l3h, dl->tx_hist[h].msg->data, length);
532
533 return dl->send_ph_data_req(&nctx, msg);
534}
535
536/* reestablish link */
537static int lapd_reestablish(struct lapd_datalink *dl)
538{
539 struct osmo_dlsap_prim dp;
540 struct msgb *msg;
541
Philipp Maier08177d32016-12-08 17:23:26 +0100542 LOGP(DLLAPD, LOGL_DEBUG, "lapd reestablish (dl=%p)\n", dl);
543
rootaf48bed2011-09-26 11:23:06 +0200544 msg = lapd_msgb_alloc(0, "DUMMY");
545 osmo_prim_init(&dp.oph, 0, PRIM_DL_EST, PRIM_OP_REQUEST, msg);
546
547 return lapd_est_req(&dp, &dl->lctx);
548}
549
550/* Timer callback on T200 expiry */
551static void lapd_t200_cb(void *data)
552{
553 struct lapd_datalink *dl = data;
554
Philipp Maier08177d32016-12-08 17:23:26 +0100555 LOGP(DLLAPD, LOGL_INFO, "Timeout T200 state=%s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100556 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +0200557
558 switch (dl->state) {
559 case LAPD_STATE_SABM_SENT:
560 /* 5.4.1.3 */
561 if (dl->retrans_ctr + 1 >= dl->n200_est_rel + 1) {
rootaf48bed2011-09-26 11:23:06 +0200562 /* flush tx and send buffers */
563 lapd_dl_flush_tx(dl);
564 lapd_dl_flush_send(dl);
565 /* go back to idle state */
566 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
567 /* NOTE: we must not change any other states or buffers
568 * and queues, since we may reconnect after handover
569 * failure. the buffered messages is replaced there */
Philipp Maier6b986c22017-02-01 12:00:45 +0100570 /* send MDL ERROR INIDCATION to L3 */
571 mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
Philipp Maierd9f61292016-12-08 10:45:06 +0100572 /* send RELEASE INDICATION to L3 */
573 send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION,
574 &dl->lctx);
rootaf48bed2011-09-26 11:23:06 +0200575 break;
576 }
577 /* retransmit SABM command */
578 lapd_send_resend(dl);
579 /* increment re-transmission counter */
580 dl->retrans_ctr++;
581 /* restart T200 (PH-READY-TO-SEND) */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200582 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200583 break;
584 case LAPD_STATE_DISC_SENT:
585 /* 5.4.4.3 */
586 if (dl->retrans_ctr + 1 >= dl->n200_est_rel + 1) {
rootaf48bed2011-09-26 11:23:06 +0200587 /* send MDL ERROR INIDCATION to L3 */
588 mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
Philipp Maier6b986c22017-02-01 12:00:45 +0100589 /* send RELEASE INDICATION to L3 */
590 send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
rootaf48bed2011-09-26 11:23:06 +0200591 /* flush tx and send buffers */
592 lapd_dl_flush_tx(dl);
593 lapd_dl_flush_send(dl);
594 /* go back to idle state */
595 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
596 /* NOTE: we must not change any other states or buffers
597 * and queues, since we may reconnect after handover
598 * failure. the buffered messages is replaced there */
599 break;
600 }
601 /* retransmit DISC command */
602 lapd_send_resend(dl);
603 /* increment re-transmission counter */
604 dl->retrans_ctr++;
605 /* restart T200 (PH-READY-TO-SEND) */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200606 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200607 break;
608 case LAPD_STATE_MF_EST:
609 /* 5.5.7 */
610 dl->retrans_ctr = 0;
611 lapd_dl_newstate(dl, LAPD_STATE_TIMER_RECOV);
612 /* fall through */
613 case LAPD_STATE_TIMER_RECOV:
614 dl->retrans_ctr++;
615 if (dl->retrans_ctr < dl->n200) {
616 uint8_t vs = sub_mod(dl->v_send, 1, dl->v_range);
617 uint8_t h = do_mod(vs, dl->range_hist);
618 /* retransmit I frame (V_s-1) with P=1, if any */
619 if (dl->tx_hist[h].msg) {
620 struct msgb *msg;
621 int length = dl->tx_hist[h].msg->len;
622 struct lapd_msg_ctx nctx;
623
624 LOGP(DLLAPD, LOGL_INFO, "retransmit last frame"
Philipp Maier08177d32016-12-08 17:23:26 +0100625 " V(S)=%d (dl=%p)\n", vs, dl);
rootaf48bed2011-09-26 11:23:06 +0200626 /* Create I frame (segment) from tx_hist */
627 memcpy(&nctx, &dl->lctx, sizeof(nctx));
628 /* keep nctx.ldp */
629 /* keep nctx.sapi */
630 /* keep nctx.tei */
631 nctx.cr = dl->cr.loc2rem.cmd;
632 nctx.format = LAPD_FORM_I;
633 nctx.p_f = 1;
634 nctx.n_send = vs;
635 nctx.n_recv = dl->v_recv;
636 nctx.length = length;
637 nctx.more = dl->tx_hist[h].more;
638 msg = lapd_msgb_alloc(length, "LAPD I resend");
639 msg->l3h = msgb_put(msg, length);
640 memcpy(msg->l3h, dl->tx_hist[h].msg->data,
641 length);
642 dl->send_ph_data_req(&nctx, msg);
643 } else {
644 /* OR send appropriate supervision frame with P=1 */
645 if (!dl->own_busy && !dl->seq_err_cond) {
646 lapd_send_rr(&dl->lctx, 1, 1);
647 /* NOTE: In case of sequence error
648 * condition, the REJ frame has been
649 * transmitted when entering the
650 * condition, so it has not be done
651 * here
652 */
653 } else if (dl->own_busy) {
654 lapd_send_rnr(&dl->lctx, 1, 1);
655 } else {
656 LOGP(DLLAPD, LOGL_INFO, "unhandled, "
Philipp Maier08177d32016-12-08 17:23:26 +0100657 "pls. fix (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200658 }
659 }
660 /* restart T200 (PH-READY-TO-SEND) */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200661 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200662 } else {
663 /* send MDL ERROR INIDCATION to L3 */
664 mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
665 /* reestablish */
666 if (!dl->reestablish)
667 break;
668 LOGP(DLLAPD, LOGL_NOTICE, "N200 reached, performing "
Philipp Maier08177d32016-12-08 17:23:26 +0100669 "reestablishment. (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200670 lapd_reestablish(dl);
671 }
672 break;
673 default:
674 LOGP(DLLAPD, LOGL_INFO, "T200 expired in unexpected "
Harald Weltec733d142017-03-15 10:20:51 +0100675 "dl->state %s (dl=%p)\n", lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +0200676 }
677}
678
679/* Timer callback on T203 expiry */
680static void lapd_t203_cb(void *data)
681{
682 struct lapd_datalink *dl = data;
683
Philipp Maier08177d32016-12-08 17:23:26 +0100684 LOGP(DLLAPD, LOGL_INFO, "Timeout T203 state=%s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100685 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +0200686
687 if (dl->state != LAPD_STATE_MF_EST) {
688 LOGP(DLLAPD, LOGL_ERROR, "T203 fired outside MF EST state, "
Philipp Maier08177d32016-12-08 17:23:26 +0100689 "please fix! (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200690 return;
691 }
692
693 /* set retransmission counter to 0 */
694 dl->retrans_ctr = 0;
695 /* enter timer recovery state */
696 lapd_dl_newstate(dl, LAPD_STATE_TIMER_RECOV);
697 /* transmit a supervisory command with P bit set to 1 as follows: */
698 if (!dl->own_busy) {
Philipp Maier08177d32016-12-08 17:23:26 +0100699 LOGP(DLLAPD, LOGL_INFO,
700 "transmit an RR poll command (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200701 /* Send RR with P=1 */
702 lapd_send_rr(&dl->lctx, 1, 1);
703 } else {
Philipp Maier08177d32016-12-08 17:23:26 +0100704 LOGP(DLLAPD, LOGL_INFO,
705 "transmit an RNR poll command (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200706 /* Send RNR with P=1 */
707 lapd_send_rnr(&dl->lctx, 1, 1);
708 }
709 /* start T200 */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200710 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200711}
712
713/* 5.5.3.1: Common function to acknowlege frames up to the given N(R) value */
714static void lapd_acknowledge(struct lapd_msg_ctx *lctx)
715{
716 struct lapd_datalink *dl = lctx->dl;
717 uint8_t nr = lctx->n_recv;
Holger Hans Peter Freytherfb6a2e22012-03-16 10:35:38 +0100718 int s = 0, rej = 0, t200_reset = 0;
rootaf48bed2011-09-26 11:23:06 +0200719 int i, h;
720
721 /* supervisory frame ? */
722 if (lctx->format == LAPD_FORM_S)
723 s = 1;
724 /* REJ frame ? */
725 if (s && lctx->s_u == LAPD_S_REJ)
726 rej = 1;
727
728 /* Flush all transmit buffers of acknowledged frames */
729 for (i = dl->v_ack; i != nr; i = inc_mod(i, dl->v_range)) {
730 h = do_mod(i, dl->range_hist);
731 if (dl->tx_hist[h].msg) {
732 msgb_free(dl->tx_hist[h].msg);
733 dl->tx_hist[h].msg = NULL;
734 LOGP(DLLAPD, LOGL_INFO, "ack frame %d\n", i);
735 }
736 }
737
738 if (dl->state != LAPD_STATE_TIMER_RECOV) {
739 /* When not in the timer recovery condition, the data
740 * link layer entity shall reset the timer T200 on
741 * receipt of a valid I frame with N(R) higher than V(A),
742 * or an REJ with an N(R) equal to V(A). */
743 if ((!rej && nr != dl->v_ack)
744 || (rej && nr == dl->v_ack)) {
rootaf48bed2011-09-26 11:23:06 +0200745 t200_reset = 1;
Andreas Eversberg742fc792011-09-27 09:40:25 +0200746 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200747 /* 5.5.3.1 Note 1 + 2 imply timer recovery cond. */
748 }
749 /* 5.7.4: N(R) sequence error
750 * N(R) is called valid, if and only if
751 * (N(R)-V(A)) mod 8 <= (V(S)-V(A)) mod 8.
752 */
753 if (sub_mod(nr, dl->v_ack, dl->v_range)
754 > sub_mod(dl->v_send, dl->v_ack, dl->v_range)) {
Philipp Maier08177d32016-12-08 17:23:26 +0100755 LOGP(DLLAPD, LOGL_NOTICE, "N(R) sequence error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200756 mdl_error(MDL_CAUSE_SEQ_ERR, lctx);
757 }
758 }
759
760 /* V(A) shall be set to the value of N(R) */
761 dl->v_ack = nr;
762
Andreas Eversberg742fc792011-09-27 09:40:25 +0200763 /* If T200 has been stopped by the receipt of an I, RR or RNR frame,
rootaf48bed2011-09-26 11:23:06 +0200764 * and if there are outstanding I frames, restart T200 */
765 if (t200_reset && !rej) {
766 if (dl->tx_hist[sub_mod(dl->v_send, 1, dl->range_hist)].msg) {
767 LOGP(DLLAPD, LOGL_INFO, "start T200, due to unacked I "
Philipp Maier08177d32016-12-08 17:23:26 +0100768 "frame(s) (dl=%p)\n", dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +0200769 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200770 }
771 }
772
773 /* This also does a restart, when I or S frame is received */
774
775 /* Stop T203, if running */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200776 lapd_stop_t203(dl);
rootaf48bed2011-09-26 11:23:06 +0200777 /* Start T203, if T200 is not running in MF EST state, if enabled */
778 if (!osmo_timer_pending(&dl->t200)
779 && (dl->t203_sec || dl->t203_usec)
780 && (dl->state == LAPD_STATE_MF_EST)) {
Andreas Eversberg742fc792011-09-27 09:40:25 +0200781 lapd_start_t203(dl);
rootaf48bed2011-09-26 11:23:06 +0200782 }
783}
784
785/* L1 -> L2 */
786
787/* Receive a LAPD U (Unnumbered) message from L1 */
788static int lapd_rx_u(struct msgb *msg, struct lapd_msg_ctx *lctx)
789{
790 struct lapd_datalink *dl = lctx->dl;
791 int length = lctx->length;
Sylvain Munaut9a5f3b82011-11-20 09:01:59 +0100792 int rc = 0;
rootaf48bed2011-09-26 11:23:06 +0200793 uint8_t prim, op;
794
795 switch (lctx->s_u) {
796 case LAPD_U_SABM:
797 case LAPD_U_SABME:
798 prim = PRIM_DL_EST;
799 op = PRIM_OP_INDICATION;
800
Philipp Maier08177d32016-12-08 17:23:26 +0100801 LOGP(DLLAPD, LOGL_INFO, "SABM(E) received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100802 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +0200803 /* 5.7.1 */
804 dl->seq_err_cond = 0;
805 /* G.2.2 Wrong value of the C/R bit */
806 if (lctx->cr == dl->cr.rem2loc.resp) {
Philipp Maier08177d32016-12-08 17:23:26 +0100807 LOGP(DLLAPD, LOGL_ERROR,
808 "SABM response error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200809 msgb_free(msg);
810 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
811 return -EINVAL;
812 }
813
814 /* G.4.5 If SABM is received with L>N201 or with M bit
815 * set, AN MDL-ERROR-INDICATION is sent to MM.
816 */
817 if (lctx->more || length > lctx->n201) {
Philipp Maier08177d32016-12-08 17:23:26 +0100818 LOGP(DLLAPD, LOGL_ERROR,
819 "SABM too large error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200820 msgb_free(msg);
821 mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
822 return -EIO;
823 }
824
825 switch (dl->state) {
826 case LAPD_STATE_IDLE:
827 break;
828 case LAPD_STATE_MF_EST:
829 LOGP(DLLAPD, LOGL_INFO, "SABM command, multiple "
Philipp Maier08177d32016-12-08 17:23:26 +0100830 "frame established state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200831 /* If link is lost on the remote side, we start over
832 * and send DL-ESTABLISH indication again. */
Andreas Eversberg6e182082013-02-06 14:13:21 +0100833 /* Additionally, continue in case of content resoltion
834 * (GSM network). This happens, if the mobile has not
835 * yet received UA or another mobile (collision) tries
836 * to establish connection. The mobile must receive
837 * UA again. */
Andreas Eversbergccc46332013-06-12 09:25:27 +0200838 /* 5.4.2.1 */
839 if (!length) {
840 /* If no content resolution, this is a
841 * re-establishment. */
842 LOGP(DLLAPD, LOGL_INFO,
Philipp Maier08177d32016-12-08 17:23:26 +0100843 "Remote reestablish (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200844 break;
845 }
Andreas Eversbergccc46332013-06-12 09:25:27 +0200846 if (!dl->cont_res) {
847 LOGP(DLLAPD, LOGL_INFO, "SABM command not "
Philipp Maier08177d32016-12-08 17:23:26 +0100848 "allowed in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100849 lapd_state_name(dl->state), dl);
Andreas Eversbergccc46332013-06-12 09:25:27 +0200850 mdl_error(MDL_CAUSE_SABM_MF, lctx);
851 msgb_free(msg);
852 return 0;
853 }
rootaf48bed2011-09-26 11:23:06 +0200854 /* Ignore SABM if content differs from first SABM. */
Andreas Eversbergccc46332013-06-12 09:25:27 +0200855 if (dl->mode == LAPD_MODE_NETWORK && length) {
rootaf48bed2011-09-26 11:23:06 +0200856#ifdef TEST_CONTENT_RESOLUTION_NETWORK
857 dl->cont_res->data[0] ^= 0x01;
858#endif
Andreas Eversberg6e182082013-02-06 14:13:21 +0100859 if (memcmp(dl->cont_res->data, msg->data,
860 length)) {
rootaf48bed2011-09-26 11:23:06 +0200861 LOGP(DLLAPD, LOGL_INFO, "Another SABM "
Thorsten Alteholza81055d2017-03-02 22:13:48 +0100862 "with different content - "
Philipp Maier08177d32016-12-08 17:23:26 +0100863 "ignoring! (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200864 msgb_free(msg);
865 return 0;
866 }
867 }
868 /* send UA again */
869 lapd_send_ua(lctx, length, msg->l3h);
870 msgb_free(msg);
871 return 0;
872 case LAPD_STATE_DISC_SENT:
873 /* 5.4.6.2 send DM with F=P */
874 lapd_send_dm(lctx);
Andreas Eversberg742fc792011-09-27 09:40:25 +0200875 /* stop Timer T200 */
876 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200877 msgb_free(msg);
878 return send_dl_simple(prim, op, lctx);
879 default:
880 /* collision: Send UA, but still wait for rx UA, then
881 * change to MF_EST state.
882 */
883 /* check for contention resoultion */
884 if (dl->tx_hist[0].msg && dl->tx_hist[0].msg->len) {
885 LOGP(DLLAPD, LOGL_NOTICE, "SABM not allowed "
Philipp Maier08177d32016-12-08 17:23:26 +0100886 "during contention resolution (state=%s, dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100887 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +0200888 mdl_error(MDL_CAUSE_SABM_INFO_NOTALL, lctx);
889 }
890 lapd_send_ua(lctx, length, msg->l3h);
891 msgb_free(msg);
892 return 0;
893 }
894 /* save message context for further use */
895 memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
896#ifndef TEST_CONTENT_RESOLUTION_NETWORK
897 /* send UA response */
898 lapd_send_ua(lctx, length, msg->l3h);
899#endif
900 /* set Vs, Vr and Va to 0 */
901 dl->v_send = dl->v_recv = dl->v_ack = 0;
902 /* clear tx_hist */
903 lapd_dl_flush_hist(dl);
904 /* enter multiple-frame-established state */
905 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
906 /* store content resolution data on network side
907 * Note: cont_res will be removed when changing state again,
908 * so it must be allocated AFTER lapd_dl_newstate(). */
909 if (dl->mode == LAPD_MODE_NETWORK && length) {
910 dl->cont_res = lapd_msgb_alloc(length, "CONT RES");
911 memcpy(msgb_put(dl->cont_res, length), msg->l3h,
912 length);
Philipp Maier08177d32016-12-08 17:23:26 +0100913 LOGP(DLLAPD, LOGL_NOTICE,
914 "Store content res. (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200915 }
916 /* send notification to L3 */
917 if (length == 0) {
918 /* 5.4.1.2 Normal establishment procedures */
919 rc = send_dl_simple(prim, op, lctx);
920 msgb_free(msg);
921 } else {
922 /* 5.4.1.4 Contention resolution establishment */
Harald Welte087116a2013-06-18 21:41:34 +0200923 msgb_trim(msg, length);
rootaf48bed2011-09-26 11:23:06 +0200924 rc = send_dl_l3(prim, op, lctx, msg);
925 }
926 break;
927 case LAPD_U_DM:
Philipp Maier08177d32016-12-08 17:23:26 +0100928 LOGP(DLLAPD, LOGL_INFO, "DM received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100929 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +0200930 /* G.2.2 Wrong value of the C/R bit */
931 if (lctx->cr == dl->cr.rem2loc.cmd) {
Philipp Maier08177d32016-12-08 17:23:26 +0100932 LOGP(DLLAPD, LOGL_ERROR,
933 "DM command error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200934 msgb_free(msg);
935 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
936 return -EINVAL;
937 }
938 if (!lctx->p_f) {
939 /* 5.4.1.2 DM responses with the F bit set to "0"
940 * shall be ignored.
941 */
942 msgb_free(msg);
943 return 0;
944 }
945 switch (dl->state) {
946 case LAPD_STATE_SABM_SENT:
947 break;
948 case LAPD_STATE_MF_EST:
949 if (lctx->p_f) {
950 LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
Philipp Maier08177d32016-12-08 17:23:26 +0100951 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200952 mdl_error(MDL_CAUSE_UNSOL_DM_RESP, lctx);
953 } else {
954 LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
955 "response, multiple frame established "
Philipp Maier08177d32016-12-08 17:23:26 +0100956 "state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200957 mdl_error(MDL_CAUSE_UNSOL_DM_RESP_MF, lctx);
958 /* reestablish */
959 if (!dl->reestablish) {
960 msgb_free(msg);
961 return 0;
962 }
963 LOGP(DLLAPD, LOGL_NOTICE, "Performing "
Philipp Maier08177d32016-12-08 17:23:26 +0100964 "reestablishment. (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200965 lapd_reestablish(dl);
966 }
967 msgb_free(msg);
968 return 0;
969 case LAPD_STATE_TIMER_RECOV:
970 /* FP = 0 (DM is normal in case PF = 1) */
971 if (!lctx->p_f) {
972 LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
973 "response, multiple frame established "
Philipp Maier08177d32016-12-08 17:23:26 +0100974 "state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200975 mdl_error(MDL_CAUSE_UNSOL_DM_RESP_MF, lctx);
976 msgb_free(msg);
977 /* reestablish */
978 if (!dl->reestablish)
979 return 0;
980 LOGP(DLLAPD, LOGL_NOTICE, "Performing "
Philipp Maier08177d32016-12-08 17:23:26 +0100981 "reestablishment. (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200982 return lapd_reestablish(dl);
983 }
984 break;
985 case LAPD_STATE_DISC_SENT:
Andreas Eversberg742fc792011-09-27 09:40:25 +0200986 /* stop Timer T200 */
987 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200988 /* go to idle state */
989 lapd_dl_flush_tx(dl);
990 lapd_dl_flush_send(dl);
991 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
992 rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, lctx);
993 msgb_free(msg);
994 return 0;
995 case LAPD_STATE_IDLE:
996 /* 5.4.5 all other frame types shall be discarded */
997 default:
998 LOGP(DLLAPD, LOGL_INFO, "unsolicited DM response! "
Philipp Maier08177d32016-12-08 17:23:26 +0100999 "(discarding) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001000 msgb_free(msg);
1001 return 0;
1002 }
Andreas Eversberg742fc792011-09-27 09:40:25 +02001003 /* stop timer T200 */
1004 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001005 /* go to idle state */
1006 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1007 rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION, lctx);
1008 msgb_free(msg);
1009 break;
1010 case LAPD_U_UI:
Philipp Maier08177d32016-12-08 17:23:26 +01001011 LOGP(DLLAPD, LOGL_INFO, "UI received (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001012 /* G.2.2 Wrong value of the C/R bit */
1013 if (lctx->cr == dl->cr.rem2loc.resp) {
Holger Hans Peter Freyther8c012312012-11-26 16:52:23 +01001014 LOGP(DLLAPD, LOGL_ERROR, "UI indicates response "
Philipp Maier08177d32016-12-08 17:23:26 +01001015 "error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001016 msgb_free(msg);
1017 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1018 return -EINVAL;
1019 }
1020
1021 /* G.4.5 If UI is received with L>N201 or with M bit
1022 * set, AN MDL-ERROR-INDICATION is sent to MM.
1023 */
1024 if (length > lctx->n201 || lctx->more) {
Holger Hans Peter Freyther8c012312012-11-26 16:52:23 +01001025 LOGP(DLLAPD, LOGL_ERROR, "UI too large error "
Philipp Maier08177d32016-12-08 17:23:26 +01001026 "(%d > N201(%d) or M=%d) (dl=%p)\n", length,
1027 lctx->n201, lctx->more, dl);
rootaf48bed2011-09-26 11:23:06 +02001028 msgb_free(msg);
1029 mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
1030 return -EIO;
1031 }
1032
1033 /* do some length checks */
1034 if (length == 0) {
1035 /* 5.3.3 UI frames received with the length indicator
1036 * set to "0" shall be ignored
1037 */
Philipp Maier08177d32016-12-08 17:23:26 +01001038 LOGP(DLLAPD, LOGL_INFO,
1039 "length=0 (discarding) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001040 msgb_free(msg);
1041 return 0;
1042 }
Harald Welte087116a2013-06-18 21:41:34 +02001043 msgb_trim(msg, length);
rootaf48bed2011-09-26 11:23:06 +02001044 rc = send_dl_l3(PRIM_DL_UNIT_DATA, PRIM_OP_INDICATION, lctx,
1045 msg);
1046 break;
1047 case LAPD_U_DISC:
1048 prim = PRIM_DL_REL;
1049 op = PRIM_OP_INDICATION;
1050
Philipp Maier08177d32016-12-08 17:23:26 +01001051 LOGP(DLLAPD, LOGL_INFO, "DISC received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +01001052 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +02001053 /* flush tx and send buffers */
1054 lapd_dl_flush_tx(dl);
1055 lapd_dl_flush_send(dl);
1056 /* 5.7.1 */
1057 dl->seq_err_cond = 0;
1058 /* G.2.2 Wrong value of the C/R bit */
1059 if (lctx->cr == dl->cr.rem2loc.resp) {
Philipp Maier08177d32016-12-08 17:23:26 +01001060 LOGP(DLLAPD, LOGL_ERROR,
1061 "DISC response error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001062 msgb_free(msg);
1063 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1064 return -EINVAL;
1065 }
1066 if (length > 0 || lctx->more) {
1067 /* G.4.4 If a DISC or DM frame is received with L>0 or
1068 * with the M bit set to "1", an MDL-ERROR-INDICATION
1069 * primitive with cause "U frame with incorrect
1070 * parameters" is sent to the mobile management entity.
1071 */
Holger Hans Peter Freyther8c012312012-11-26 16:52:23 +01001072 LOGP(DLLAPD, LOGL_ERROR,
Philipp Maier08177d32016-12-08 17:23:26 +01001073 "U frame iwth incorrect parameters (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001074 msgb_free(msg);
1075 mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
1076 return -EIO;
1077 }
1078 switch (dl->state) {
1079 case LAPD_STATE_IDLE:
Philipp Maier08177d32016-12-08 17:23:26 +01001080 LOGP(DLLAPD, LOGL_INFO,
1081 "DISC in idle state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001082 /* send DM with F=P */
1083 msgb_free(msg);
1084 return lapd_send_dm(lctx);
1085 case LAPD_STATE_SABM_SENT:
Philipp Maier08177d32016-12-08 17:23:26 +01001086 LOGP(DLLAPD, LOGL_INFO,
1087 "DISC in SABM state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001088 /* 5.4.6.2 send DM with F=P */
1089 lapd_send_dm(lctx);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001090 /* stop Timer T200 */
1091 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001092 /* go to idle state */
1093 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1094 msgb_free(msg);
1095 return send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION,
1096 lctx);
1097 case LAPD_STATE_MF_EST:
1098 case LAPD_STATE_TIMER_RECOV:
Philipp Maier08177d32016-12-08 17:23:26 +01001099 LOGP(DLLAPD, LOGL_INFO,
1100 "DISC in est state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001101 break;
1102 case LAPD_STATE_DISC_SENT:
Philipp Maier08177d32016-12-08 17:23:26 +01001103 LOGP(DLLAPD, LOGL_INFO,
1104 "DISC in disc state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001105 prim = PRIM_DL_REL;
1106 op = PRIM_OP_CONFIRM;
1107 break;
1108 default:
1109 lapd_send_ua(lctx, length, msg->l3h);
1110 msgb_free(msg);
1111 return 0;
1112 }
1113 /* send UA response */
1114 lapd_send_ua(lctx, length, msg->l3h);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001115 /* stop Timer T200 */
1116 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001117 /* enter idle state, keep tx-buffer with UA response */
1118 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1119 /* send notification to L3 */
1120 rc = send_dl_simple(prim, op, lctx);
1121 msgb_free(msg);
1122 break;
1123 case LAPD_U_UA:
Philipp Maier08177d32016-12-08 17:23:26 +01001124 LOGP(DLLAPD, LOGL_INFO, "UA received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +01001125 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +02001126 /* G.2.2 Wrong value of the C/R bit */
1127 if (lctx->cr == dl->cr.rem2loc.cmd) {
Holger Hans Peter Freyther8c012312012-11-26 16:52:23 +01001128 LOGP(DLLAPD, LOGL_ERROR, "UA indicates command "
Philipp Maier08177d32016-12-08 17:23:26 +01001129 "error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001130 msgb_free(msg);
1131 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1132 return -EINVAL;
1133 }
1134
1135 /* G.4.5 If UA is received with L>N201 or with M bit
1136 * set, AN MDL-ERROR-INDICATION is sent to MM.
1137 */
1138 if (lctx->more || length > lctx->n201) {
Philipp Maier08177d32016-12-08 17:23:26 +01001139 LOGP(DLLAPD, LOGL_ERROR,
1140 "UA too large error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001141 msgb_free(msg);
1142 mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
1143 return -EIO;
1144 }
1145
1146 if (!lctx->p_f) {
1147 /* 5.4.1.2 A UA response with the F bit set to "0"
1148 * shall be ignored.
1149 */
Philipp Maier08177d32016-12-08 17:23:26 +01001150 LOGP(DLLAPD, LOGL_INFO,
1151 "F=0 (discarding) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001152 msgb_free(msg);
1153 return 0;
1154 }
1155 switch (dl->state) {
1156 case LAPD_STATE_SABM_SENT:
1157 break;
1158 case LAPD_STATE_MF_EST:
1159 case LAPD_STATE_TIMER_RECOV:
1160 LOGP(DLLAPD, LOGL_INFO, "unsolicited UA response! "
Philipp Maier08177d32016-12-08 17:23:26 +01001161 "(discarding) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001162 mdl_error(MDL_CAUSE_UNSOL_UA_RESP, lctx);
1163 msgb_free(msg);
1164 return 0;
1165 case LAPD_STATE_DISC_SENT:
Philipp Maier08177d32016-12-08 17:23:26 +01001166 LOGP(DLLAPD, LOGL_INFO,
1167 "UA in disconnect state (dl=%p)\n", dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001168 /* stop Timer T200 */
1169 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001170 /* go to idle state */
1171 lapd_dl_flush_tx(dl);
1172 lapd_dl_flush_send(dl);
1173 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1174 rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, lctx);
1175 msgb_free(msg);
1176 return 0;
1177 case LAPD_STATE_IDLE:
1178 /* 5.4.5 all other frame types shall be discarded */
1179 default:
1180 LOGP(DLLAPD, LOGL_INFO, "unsolicited UA response! "
Philipp Maier08177d32016-12-08 17:23:26 +01001181 "(discarding) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001182 msgb_free(msg);
1183 return 0;
1184 }
Philipp Maier08177d32016-12-08 17:23:26 +01001185 LOGP(DLLAPD, LOGL_INFO, "UA in SABM state (dl=%p)\n", dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001186 /* stop Timer T200 */
1187 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001188 /* compare UA with SABME if contention resolution is applied */
1189 if (dl->tx_hist[0].msg->len) {
1190 if (length != (dl->tx_hist[0].msg->len)
1191 || !!memcmp(dl->tx_hist[0].msg->data, msg->l3h,
1192 length)) {
1193 LOGP(DLLAPD, LOGL_INFO, "**** UA response "
Philipp Maier08177d32016-12-08 17:23:26 +01001194 "mismatches **** (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001195 rc = send_dl_simple(PRIM_DL_REL,
1196 PRIM_OP_INDICATION, lctx);
1197 msgb_free(msg);
1198 /* go to idle state */
1199 lapd_dl_flush_tx(dl);
1200 lapd_dl_flush_send(dl);
1201 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1202 return 0;
1203 }
1204 }
1205 /* set Vs, Vr and Va to 0 */
1206 dl->v_send = dl->v_recv = dl->v_ack = 0;
1207 /* clear tx_hist */
1208 lapd_dl_flush_hist(dl);
1209 /* enter multiple-frame-established state */
1210 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1211 /* send outstanding frames, if any (resume / reconnect) */
1212 lapd_send_i(lctx, __LINE__);
1213 /* send notification to L3 */
1214 rc = send_dl_simple(PRIM_DL_EST, PRIM_OP_CONFIRM, lctx);
1215 msgb_free(msg);
1216 break;
1217 case LAPD_U_FRMR:
Philipp Maier08177d32016-12-08 17:23:26 +01001218 LOGP(DLLAPD, LOGL_NOTICE,
1219 "Frame reject received (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001220 /* send MDL ERROR INIDCATION to L3 */
1221 mdl_error(MDL_CAUSE_FRMR, lctx);
1222 msgb_free(msg);
1223 /* reestablish */
1224 if (!dl->reestablish)
1225 break;
Philipp Maier08177d32016-12-08 17:23:26 +01001226 LOGP(DLLAPD, LOGL_NOTICE,
1227 "Performing reestablishment. (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001228 rc = lapd_reestablish(dl);
1229 break;
1230 default:
1231 /* G.3.1 */
Philipp Maier08177d32016-12-08 17:23:26 +01001232 LOGP(DLLAPD, LOGL_NOTICE,
1233 "Unnumbered frame not allowed. (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001234 msgb_free(msg);
1235 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1236 return -EINVAL;
1237 }
1238 return rc;
1239}
1240
1241/* Receive a LAPD S (Supervisory) message from L1 */
1242static int lapd_rx_s(struct msgb *msg, struct lapd_msg_ctx *lctx)
1243{
1244 struct lapd_datalink *dl = lctx->dl;
1245 int length = lctx->length;
1246
1247 if (length > 0 || lctx->more) {
1248 /* G.4.3 If a supervisory frame is received with L>0 or
1249 * with the M bit set to "1", an MDL-ERROR-INDICATION
1250 * primitive with cause "S frame with incorrect
1251 * parameters" is sent to the mobile management entity. */
Holger Hans Peter Freyther8c012312012-11-26 16:52:23 +01001252 LOGP(DLLAPD, LOGL_ERROR,
Philipp Maier08177d32016-12-08 17:23:26 +01001253 "S frame with incorrect parameters (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001254 msgb_free(msg);
1255 mdl_error(MDL_CAUSE_SFRM_INC_PARAM, lctx);
1256 return -EIO;
1257 }
1258
1259 if (lctx->cr == dl->cr.rem2loc.resp
1260 && lctx->p_f
1261 && dl->state != LAPD_STATE_TIMER_RECOV) {
1262 /* 5.4.2.2: Inidcate error on supervisory reponse F=1 */
Philipp Maier08177d32016-12-08 17:23:26 +01001263 LOGP(DLLAPD, LOGL_NOTICE,
1264 "S frame response with F=1 error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001265 mdl_error(MDL_CAUSE_UNSOL_SPRV_RESP, lctx);
1266 }
1267
1268 switch (dl->state) {
1269 case LAPD_STATE_IDLE:
1270 /* if P=1, respond DM with F=1 (5.2.2) */
1271 /* 5.4.5 all other frame types shall be discarded */
1272 if (lctx->p_f)
1273 lapd_send_dm(lctx); /* F=P */
1274 /* fall though */
1275 case LAPD_STATE_SABM_SENT:
1276 case LAPD_STATE_DISC_SENT:
Philipp Maier08177d32016-12-08 17:23:26 +01001277 LOGP(DLLAPD, LOGL_NOTICE,
1278 "S frame ignored in this state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001279 msgb_free(msg);
1280 return 0;
1281 }
1282 switch (lctx->s_u) {
1283 case LAPD_S_RR:
Philipp Maier08177d32016-12-08 17:23:26 +01001284 LOGP(DLLAPD, LOGL_INFO, "RR received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +01001285 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +02001286 /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
1287 lapd_acknowledge(lctx);
1288
1289 /* 5.5.3.2 */
1290 if (lctx->cr == dl->cr.rem2loc.cmd
1291 && lctx->p_f) {
1292 if (!dl->own_busy && !dl->seq_err_cond) {
1293 LOGP(DLLAPD, LOGL_INFO, "RR frame command "
Philipp Maier08177d32016-12-08 17:23:26 +01001294 "with polling bit set and we are not "
1295 "busy, so we reply with RR frame "
1296 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001297 lapd_send_rr(lctx, 1, 0);
1298 /* NOTE: In case of sequence error condition,
1299 * the REJ frame has been transmitted when
1300 * entering the condition, so it has not be
1301 * done here
1302 */
1303 } else if (dl->own_busy) {
1304 LOGP(DLLAPD, LOGL_INFO, "RR frame command "
Philipp Maier08177d32016-12-08 17:23:26 +01001305 "with polling bit set and we are busy, "
1306 "so we reply with RR frame response (dl=%p)\n",
1307 dl);
rootaf48bed2011-09-26 11:23:06 +02001308 lapd_send_rnr(lctx, 1, 0);
1309 }
1310 } else if (lctx->cr == dl->cr.rem2loc.resp
1311 && lctx->p_f
1312 && dl->state == LAPD_STATE_TIMER_RECOV) {
1313 LOGP(DLLAPD, LOGL_INFO, "RR response with F==1, "
1314 "and we are in timer recovery state, so "
Philipp Maier08177d32016-12-08 17:23:26 +01001315 "we leave that state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001316 /* V(S) to the N(R) in the RR frame */
1317 dl->v_send = lctx->n_recv;
Andreas Eversberg742fc792011-09-27 09:40:25 +02001318 /* stop Timer T200 */
1319 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001320 /* 5.5.7 Clear timer recovery condition */
1321 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1322 }
1323 /* Send message, if possible due to acknowledged data */
1324 lapd_send_i(lctx, __LINE__);
1325
1326 break;
1327 case LAPD_S_RNR:
Philipp Maier08177d32016-12-08 17:23:26 +01001328 LOGP(DLLAPD, LOGL_INFO, "RNR received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +01001329 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +02001330 /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
1331 lapd_acknowledge(lctx);
1332
1333 /* 5.5.5 */
1334 /* Set peer receiver busy condition */
1335 dl->peer_busy = 1;
1336
1337 if (lctx->p_f) {
1338 if (lctx->cr == dl->cr.rem2loc.cmd) {
1339 if (!dl->own_busy) {
1340 LOGP(DLLAPD, LOGL_INFO, "RNR poll "
1341 "command and we are not busy, "
1342 "so we reply with RR final "
Philipp Maier08177d32016-12-08 17:23:26 +01001343 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001344 /* Send RR with F=1 */
1345 lapd_send_rr(lctx, 1, 0);
1346 } else {
1347 LOGP(DLLAPD, LOGL_INFO, "RNR poll "
1348 "command and we are busy, so "
1349 "we reply with RNR final "
Philipp Maier08177d32016-12-08 17:23:26 +01001350 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001351 /* Send RNR with F=1 */
1352 lapd_send_rnr(lctx, 1, 0);
1353 }
1354 } else if (dl->state == LAPD_STATE_TIMER_RECOV) {
1355 LOGP(DLLAPD, LOGL_INFO, "RNR poll response "
1356 "and we in timer recovery state, so "
Philipp Maier08177d32016-12-08 17:23:26 +01001357 "we leave that state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001358 /* 5.5.7 Clear timer recovery condition */
1359 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1360 /* V(S) to the N(R) in the RNR frame */
1361 dl->v_send = lctx->n_recv;
1362 }
1363 } else
1364 LOGP(DLLAPD, LOGL_INFO, "RNR not polling/final state "
Philipp Maier08177d32016-12-08 17:23:26 +01001365 "received (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001366
1367 /* Send message, if possible due to acknowledged data */
1368 lapd_send_i(lctx, __LINE__);
1369
1370 break;
1371 case LAPD_S_REJ:
Philipp Maier08177d32016-12-08 17:23:26 +01001372 LOGP(DLLAPD, LOGL_INFO, "REJ received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +01001373 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +02001374 /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
1375 lapd_acknowledge(lctx);
1376
1377 /* 5.5.4.1 */
1378 if (dl->state != LAPD_STATE_TIMER_RECOV) {
1379 /* Clear an existing peer receiver busy condition */
1380 dl->peer_busy = 0;
1381 /* V(S) and V(A) to the N(R) in the REJ frame */
1382 dl->v_send = dl->v_ack = lctx->n_recv;
Andreas Eversberg742fc792011-09-27 09:40:25 +02001383 /* stop Timer T200 */
1384 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001385 /* 5.5.3.2 */
1386 if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
1387 if (!dl->own_busy && !dl->seq_err_cond) {
1388 LOGP(DLLAPD, LOGL_INFO, "REJ poll "
1389 "command not in timer recovery "
1390 "state and not in own busy "
1391 "condition received, so we "
1392 "respond with RR final "
Philipp Maier08177d32016-12-08 17:23:26 +01001393 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001394 lapd_send_rr(lctx, 1, 0);
1395 /* NOTE: In case of sequence error
1396 * condition, the REJ frame has been
1397 * transmitted when entering the
1398 * condition, so it has not be done
1399 * here
1400 */
1401 } else if (dl->own_busy) {
1402 LOGP(DLLAPD, LOGL_INFO, "REJ poll "
1403 "command not in timer recovery "
1404 "state and in own busy "
1405 "condition received, so we "
1406 "respond with RNR final "
Philipp Maier08177d32016-12-08 17:23:26 +01001407 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001408 lapd_send_rnr(lctx, 1, 0);
1409 }
1410 } else
1411 LOGP(DLLAPD, LOGL_INFO, "REJ response or not "
1412 "polling command not in timer recovery "
Philipp Maier08177d32016-12-08 17:23:26 +01001413 "state received (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001414 /* send MDL ERROR INIDCATION to L3 */
1415 if (lctx->cr == dl->cr.rem2loc.resp && lctx->p_f) {
Philipp Maier08177d32016-12-08 17:23:26 +01001416 LOGP(DLLAPD, LOGL_ERROR,
1417 "unsolicited supervisory response! (dl=%p)\n",
1418 dl);
rootaf48bed2011-09-26 11:23:06 +02001419 mdl_error(MDL_CAUSE_UNSOL_SPRV_RESP, lctx);
1420 }
1421
1422 } else if (lctx->cr == dl->cr.rem2loc.resp && lctx->p_f) {
1423 LOGP(DLLAPD, LOGL_INFO, "REJ poll response in timer "
Philipp Maier08177d32016-12-08 17:23:26 +01001424 "recovery state received (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001425 /* Clear an existing peer receiver busy condition */
1426 dl->peer_busy = 0;
1427 /* V(S) and V(A) to the N(R) in the REJ frame */
1428 dl->v_send = dl->v_ack = lctx->n_recv;
Andreas Eversberg742fc792011-09-27 09:40:25 +02001429 /* stop Timer T200 */
1430 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001431 /* 5.5.7 Clear timer recovery condition */
1432 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1433 } else {
1434 /* Clear an existing peer receiver busy condition */
1435 dl->peer_busy = 0;
1436 /* V(S) and V(A) to the N(R) in the REJ frame */
1437 dl->v_send = dl->v_ack = lctx->n_recv;
1438 /* 5.5.3.2 */
1439 if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
1440 if (!dl->own_busy && !dl->seq_err_cond) {
1441 LOGP(DLLAPD, LOGL_INFO, "REJ poll "
1442 "command in timer recovery "
1443 "state and not in own busy "
1444 "condition received, so we "
1445 "respond with RR final "
Philipp Maier08177d32016-12-08 17:23:26 +01001446 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001447 lapd_send_rr(lctx, 1, 0);
1448 /* NOTE: In case of sequence error
1449 * condition, the REJ frame has been
1450 * transmitted when entering the
1451 * condition, so it has not be done
1452 * here
1453 */
1454 } else if (dl->own_busy) {
1455 LOGP(DLLAPD, LOGL_INFO, "REJ poll "
1456 "command in timer recovery "
1457 "state and in own busy "
1458 "condition received, so we "
1459 "respond with RNR final "
Philipp Maier08177d32016-12-08 17:23:26 +01001460 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001461 lapd_send_rnr(lctx, 1, 0);
1462 }
1463 } else
1464 LOGP(DLLAPD, LOGL_INFO, "REJ response or not "
1465 "polling command in timer recovery "
Philipp Maier08177d32016-12-08 17:23:26 +01001466 "state received (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001467 }
1468
1469 /* FIXME: 5.5.4.2 2) */
1470
1471 /* Send message, if possible due to acknowledged data */
1472 lapd_send_i(lctx, __LINE__);
1473
1474 break;
1475 default:
1476 /* G.3.1 */
Philipp Maier08177d32016-12-08 17:23:26 +01001477 LOGP(DLLAPD, LOGL_ERROR,
1478 "Supervisory frame not allowed. (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001479 msgb_free(msg);
1480 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1481 return -EINVAL;
1482 }
1483 msgb_free(msg);
1484 return 0;
1485}
1486
1487/* Receive a LAPD I (Information) message from L1 */
1488static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx)
1489{
1490 struct lapd_datalink *dl = lctx->dl;
1491 //uint8_t nr = lctx->n_recv;
1492 uint8_t ns = lctx->n_send;
1493 int length = lctx->length;
1494 int rc;
1495
Philipp Maier08177d32016-12-08 17:23:26 +01001496 LOGP(DLLAPD, LOGL_INFO, "I received in state %s on SAPI(%u) (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +01001497 lapd_state_name(dl->state), lctx->sapi, dl);
rootaf48bed2011-09-26 11:23:06 +02001498
1499 /* G.2.2 Wrong value of the C/R bit */
1500 if (lctx->cr == dl->cr.rem2loc.resp) {
Philipp Maier08177d32016-12-08 17:23:26 +01001501 LOGP(DLLAPD, LOGL_ERROR,
1502 "I frame response not allowed (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001503 msgb_free(msg);
1504 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1505 return -EINVAL;
1506 }
1507
1508 if (length == 0 || length > lctx->n201) {
1509 /* G.4.2 If the length indicator of an I frame is set
1510 * to a numerical value L>N201 or L=0, an MDL-ERROR-INDICATION
1511 * primitive with cause "I frame with incorrect length"
1512 * is sent to the mobile management entity. */
Philipp Maier08177d32016-12-08 17:23:26 +01001513 LOGP(DLLAPD, LOGL_ERROR,
1514 "I frame length not allowed (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001515 msgb_free(msg);
1516 mdl_error(MDL_CAUSE_IFRM_INC_LEN, lctx);
1517 return -EIO;
1518 }
1519
1520 /* G.4.2 If the numerical value of L is L<N201 and the M
1521 * bit is set to "1", then an MDL-ERROR-INDICATION primitive with
1522 * cause "I frame with incorrect use of M bit" is sent to the
1523 * mobile management entity. */
1524 if (lctx->more && length < lctx->n201) {
Philipp Maier08177d32016-12-08 17:23:26 +01001525 LOGP(DLLAPD, LOGL_ERROR,
1526 "I frame with M bit too short (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001527 msgb_free(msg);
1528 mdl_error(MDL_CAUSE_IFRM_INC_MBITS, lctx);
1529 return -EIO;
1530 }
1531
1532 switch (dl->state) {
1533 case LAPD_STATE_IDLE:
1534 /* if P=1, respond DM with F=1 (5.2.2) */
1535 /* 5.4.5 all other frame types shall be discarded */
1536 if (lctx->p_f)
1537 lapd_send_dm(lctx); /* F=P */
1538 /* fall though */
1539 case LAPD_STATE_SABM_SENT:
1540 case LAPD_STATE_DISC_SENT:
Philipp Maier08177d32016-12-08 17:23:26 +01001541 LOGP(DLLAPD, LOGL_NOTICE,
1542 "I frame ignored in this state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001543 msgb_free(msg);
1544 return 0;
1545 }
1546
1547 /* 5.7.1: N(s) sequence error */
1548 if (ns != dl->v_recv) {
1549 LOGP(DLLAPD, LOGL_NOTICE, "N(S) sequence error: N(S)=%u, "
Philipp Maier08177d32016-12-08 17:23:26 +01001550 "V(R)=%u (dl=%p)\n", ns, dl->v_recv, dl);
rootaf48bed2011-09-26 11:23:06 +02001551 /* discard data */
1552 msgb_free(msg);
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001553 if (dl->seq_err_cond != 1) {
rootaf48bed2011-09-26 11:23:06 +02001554 /* FIXME: help me understand what exactly todo here
rootaf48bed2011-09-26 11:23:06 +02001555 */
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001556 dl->seq_err_cond = 1;
rootaf48bed2011-09-26 11:23:06 +02001557 lapd_send_rej(lctx, lctx->p_f);
1558 } else {
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001559 /* If there are two subsequent sequence errors received,
1560 * ignore it. (Ignore every second subsequent error.)
1561 * This happens if our reply with the REJ is too slow,
1562 * so the remote gets a T200 timeout and sends another
1563 * frame with a sequence error.
1564 * Test showed that replying with two subsequent REJ
1565 * messages could the remote L2 process to abort.
1566 * Replying too slow shouldn't happen, but may happen
1567 * over serial link between BB and LAPD.
1568 */
1569 dl->seq_err_cond = 2;
rootaf48bed2011-09-26 11:23:06 +02001570 }
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001571 /* Even if N(s) sequence error, acknowledge to N(R)-1 */
1572 /* 5.5.3.1: Acknowlege all transmitted frames up the N(R)-1 */
1573 lapd_acknowledge(lctx); /* V(A) is also set here */
1574
1575 /* Send message, if possible due to acknowledged data */
1576 lapd_send_i(lctx, __LINE__);
1577
1578 return 0;
rootaf48bed2011-09-26 11:23:06 +02001579 }
1580 dl->seq_err_cond = 0;
1581
1582 /* Increment receiver state */
1583 dl->v_recv = inc_mod(dl->v_recv, dl->v_range);
Philipp Maier08177d32016-12-08 17:23:26 +01001584 LOGP(DLLAPD, LOGL_INFO, "incrementing V(R) to %u (dl=%p)\n",
1585 dl->v_recv, dl);
rootaf48bed2011-09-26 11:23:06 +02001586
1587 /* 5.5.3.1: Acknowlege all transmitted frames up the the N(R)-1 */
1588 lapd_acknowledge(lctx); /* V(A) is also set here */
1589
1590 /* Only if we are not in own receiver busy condition */
1591 if (!dl->own_busy) {
1592 /* if the frame carries a complete segment */
1593 if (!lctx->more && !dl->rcv_buffer) {
Philipp Maier08177d32016-12-08 17:23:26 +01001594 LOGP(DLLAPD, LOGL_INFO,
1595 "message in single I frame (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001596 /* send a DATA INDICATION to L3 */
Harald Welte087116a2013-06-18 21:41:34 +02001597 msgb_trim(msg, length);
rootaf48bed2011-09-26 11:23:06 +02001598 rc = send_dl_l3(PRIM_DL_DATA, PRIM_OP_INDICATION, lctx,
1599 msg);
1600 } else {
1601 /* create rcv_buffer */
1602 if (!dl->rcv_buffer) {
1603 LOGP(DLLAPD, LOGL_INFO, "message in multiple "
Philipp Maier08177d32016-12-08 17:23:26 +01001604 "I frames (first message) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001605 dl->rcv_buffer = lapd_msgb_alloc(dl->maxf,
1606 "LAPD RX");
1607 dl->rcv_buffer->l3h = dl->rcv_buffer->data;
1608 }
1609 /* concat. rcv_buffer */
1610 if (msgb_l3len(dl->rcv_buffer) + length > dl->maxf) {
1611 LOGP(DLLAPD, LOGL_NOTICE, "Received frame "
Philipp Maier08177d32016-12-08 17:23:26 +01001612 "overflow! (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001613 } else {
1614 memcpy(msgb_put(dl->rcv_buffer, length),
1615 msg->l3h, length);
1616 }
1617 /* if the last segment was received */
1618 if (!lctx->more) {
1619 LOGP(DLLAPD, LOGL_INFO, "message in multiple "
Philipp Maier08177d32016-12-08 17:23:26 +01001620 "I frames (last message) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001621 rc = send_dl_l3(PRIM_DL_DATA,
1622 PRIM_OP_INDICATION, lctx,
1623 dl->rcv_buffer);
1624 dl->rcv_buffer = NULL;
1625 } else
1626 LOGP(DLLAPD, LOGL_INFO, "message in multiple "
Philipp Maier08177d32016-12-08 17:23:26 +01001627 "I frames (next message) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001628 msgb_free(msg);
1629
1630 }
1631 } else
1632 LOGP(DLLAPD, LOGL_INFO, "I frame ignored during own receiver "
1633 "busy condition\n");
1634
1635 /* Check for P bit */
1636 if (lctx->p_f) {
1637 /* 5.5.2.1 */
1638 /* check if we are not in own receiver busy */
1639 if (!dl->own_busy) {
Philipp Maier08177d32016-12-08 17:23:26 +01001640 LOGP(DLLAPD, LOGL_INFO,
1641 "we are not busy, send RR (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001642 /* Send RR with F=1 */
1643 rc = lapd_send_rr(lctx, 1, 0);
1644 } else {
Philipp Maier08177d32016-12-08 17:23:26 +01001645 LOGP(DLLAPD, LOGL_INFO,
1646 "we are busy, send RNR (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001647 /* Send RNR with F=1 */
1648 rc = lapd_send_rnr(lctx, 1, 0);
1649 }
1650 } else {
1651 /* 5.5.2.2 */
1652 /* check if we are not in own receiver busy */
1653 if (!dl->own_busy) {
1654 /* NOTE: V(R) is already set above */
1655 rc = lapd_send_i(lctx, __LINE__);
Daniel Willmann3dc4e162014-03-20 19:24:48 +01001656
1657 /* if update_pending_iframe returns 0 it updated
1658 * the lapd header of an iframe in the tx queue */
1659 if (rc && dl->update_pending_frames)
1660 rc = dl->update_pending_frames(lctx);
1661
rootaf48bed2011-09-26 11:23:06 +02001662 if (rc) {
1663 LOGP(DLLAPD, LOGL_INFO, "we are not busy and "
Philipp Maier08177d32016-12-08 17:23:26 +01001664 "have no pending data, send RR (dl=%p)\n",
1665 dl);
rootaf48bed2011-09-26 11:23:06 +02001666 /* Send RR with F=0 */
1667 return lapd_send_rr(lctx, 0, 0);
1668 }
1669 /* all I or one RR is sent, we are done */
1670 return 0;
1671 } else {
Philipp Maier08177d32016-12-08 17:23:26 +01001672 LOGP(DLLAPD, LOGL_INFO,
1673 "we are busy, send RNR (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001674 /* Send RNR with F=0 */
1675 rc = lapd_send_rnr(lctx, 0, 0);
1676 }
1677 }
1678
1679 /* Send message, if possible due to acknowledged data */
1680 lapd_send_i(lctx, __LINE__);
1681
1682 return rc;
1683}
1684
1685/* Receive a LAPD message from L1 */
1686int lapd_ph_data_ind(struct msgb *msg, struct lapd_msg_ctx *lctx)
1687{
1688 int rc;
1689
1690 switch (lctx->format) {
1691 case LAPD_FORM_U:
1692 rc = lapd_rx_u(msg, lctx);
1693 break;
1694 case LAPD_FORM_S:
1695 rc = lapd_rx_s(msg, lctx);
1696 break;
1697 case LAPD_FORM_I:
1698 rc = lapd_rx_i(msg, lctx);
1699 break;
1700 default:
Philipp Maier08177d32016-12-08 17:23:26 +01001701 LOGP(DLLAPD, LOGL_NOTICE,
1702 "unknown LAPD format (dl=%p)\n", lctx->dl);
rootaf48bed2011-09-26 11:23:06 +02001703 msgb_free(msg);
1704 rc = -EINVAL;
1705 }
1706 return rc;
1707}
1708
1709/* L3 -> L2 */
1710
1711/* send unit data */
1712static int lapd_udata_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1713{
1714 struct lapd_datalink *dl = lctx->dl;
1715 struct msgb *msg = dp->oph.msg;
1716 struct lapd_msg_ctx nctx;
1717
1718 memcpy(&nctx, lctx, sizeof(nctx));
1719 /* keep nctx.ldp */
1720 /* keep nctx.sapi */
1721 /* keep nctx.tei */
1722 nctx.cr = dl->cr.loc2rem.cmd;
1723 nctx.format = LAPD_FORM_U;
1724 nctx.s_u = LAPD_U_UI;
1725 /* keep nctx.p_f */
1726 nctx.length = msg->len;
1727 nctx.more = 0;
1728
1729 return dl->send_ph_data_req(&nctx, msg);
1730}
1731
1732/* request link establishment */
1733static int lapd_est_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1734{
1735 struct lapd_datalink *dl = lctx->dl;
1736 struct msgb *msg = dp->oph.msg;
1737 struct lapd_msg_ctx nctx;
1738
1739 if (msg->len)
1740 LOGP(DLLAPD, LOGL_INFO, "perform establishment with content "
Philipp Maier08177d32016-12-08 17:23:26 +01001741 "(SABM) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001742 else
Philipp Maier08177d32016-12-08 17:23:26 +01001743 LOGP(DLLAPD, LOGL_INFO,
1744 "perform normal establishm. (SABM), (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001745
1746 /* Flush send-queue */
1747 /* Clear send-buffer */
1748 lapd_dl_flush_send(dl);
1749 /* be sure that history is empty */
1750 lapd_dl_flush_hist(dl);
1751
1752 /* save message context for further use */
1753 memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
1754
1755 /* Discard partly received L3 message */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +02001756 msgb_free(dl->rcv_buffer);
1757 dl->rcv_buffer = NULL;
rootaf48bed2011-09-26 11:23:06 +02001758
1759 /* assemble message */
1760 memcpy(&nctx, &dl->lctx, sizeof(nctx));
1761 /* keep nctx.ldp */
1762 /* keep nctx.sapi */
1763 /* keep nctx.tei */
1764 nctx.cr = dl->cr.loc2rem.cmd;
1765 nctx.format = LAPD_FORM_U;
1766 nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
1767 nctx.p_f = 1;
1768 nctx.length = msg->len;
1769 nctx.more = 0;
1770
1771 /* Transmit-buffer carries exactly one segment */
1772 dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
1773 msgb_put(dl->tx_hist[0].msg, msg->len);
1774 if (msg->len)
1775 memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
1776 dl->tx_hist[0].more = 0;
1777 /* set Vs to 0, because it is used as index when resending SABM */
1778 dl->v_send = 0;
1779
1780 /* Set states */
1781 dl->own_busy = dl->peer_busy = 0;
1782 dl->retrans_ctr = 0;
1783 lapd_dl_newstate(dl, LAPD_STATE_SABM_SENT);
1784
1785 /* Tramsmit and start T200 */
1786 dl->send_ph_data_req(&nctx, msg);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001787 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001788
1789 return 0;
1790}
1791
1792/* send data */
1793static int lapd_data_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1794{
1795 struct lapd_datalink *dl = lctx->dl;
1796 struct msgb *msg = dp->oph.msg;
1797
Holger Hans Peter Freyther90656db2012-01-13 05:49:29 +08001798 if (msgb_l3len(msg) == 0) {
1799 LOGP(DLLAPD, LOGL_ERROR,
Philipp Maier08177d32016-12-08 17:23:26 +01001800 "writing an empty message is not possible. (dl=%p)\n", dl);
Holger Hans Peter Freyther90656db2012-01-13 05:49:29 +08001801 msgb_free(msg);
1802 return -1;
1803 }
1804
Holger Hans Peter Freyther6ecafef2012-01-13 05:46:26 +08001805 LOGP(DLLAPD, LOGL_INFO,
Philipp Maier08177d32016-12-08 17:23:26 +01001806 "writing message to send-queue: l3len: %d (dl=%p)\n",
1807 msgb_l3len(msg), dl);
rootaf48bed2011-09-26 11:23:06 +02001808
1809 /* Write data into the send queue */
1810 msgb_enqueue(&dl->send_queue, msg);
1811
1812 /* Send message, if possible */
1813 lapd_send_i(&dl->lctx, __LINE__);
1814
1815 return 0;
1816}
1817
1818/* Send next I frame from queued/buffered data */
1819static int lapd_send_i(struct lapd_msg_ctx *lctx, int line)
1820{
1821 struct lapd_datalink *dl = lctx->dl;
1822 uint8_t k = dl->k;
1823 uint8_t h;
1824 struct msgb *msg;
1825 int length, left;
1826 int rc = - 1; /* we sent nothing */
1827 struct lapd_msg_ctx nctx;
1828
1829
Philipp Maier08177d32016-12-08 17:23:26 +01001830 LOGP(DLLAPD, LOGL_INFO,
1831 "%s() called from line %d (dl=%p)\n", __func__, line, dl);
rootaf48bed2011-09-26 11:23:06 +02001832
1833 next_frame:
1834
1835 if (dl->peer_busy) {
Philipp Maier08177d32016-12-08 17:23:26 +01001836 LOGP(DLLAPD, LOGL_INFO, "peer busy, not sending (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001837 return rc;
1838 }
1839
1840 if (dl->state == LAPD_STATE_TIMER_RECOV) {
Philipp Maier08177d32016-12-08 17:23:26 +01001841 LOGP(DLLAPD, LOGL_INFO,
1842 "timer recovery, not sending (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001843 return rc;
1844 }
1845
1846 /* If the send state variable V(S) is equal to V(A) plus k
1847 * (where k is the maximum number of outstanding I frames - see
1848 * subclause 5.8.4), the data link layer entity shall not transmit any
1849 * new I frames, but shall retransmit an I frame as a result
1850 * of the error recovery procedures as described in subclauses 5.5.4 and
1851 * 5.5.7. */
1852 if (dl->v_send == add_mod(dl->v_ack, k, dl->v_range)) {
1853 LOGP(DLLAPD, LOGL_INFO, "k frames outstanding, not sending "
Philipp Maier08177d32016-12-08 17:23:26 +01001854 "more (k=%u V(S)=%u V(A)=%u) (dl=%p)\n", k, dl->v_send,
1855 dl->v_ack, dl);
rootaf48bed2011-09-26 11:23:06 +02001856 return rc;
1857 }
1858
1859 h = do_mod(dl->v_send, dl->range_hist);
1860
1861 /* if we have no tx_hist yet, we create it */
1862 if (!dl->tx_hist[h].msg) {
1863 /* Get next message into send-buffer, if any */
1864 if (!dl->send_buffer) {
1865 next_message:
1866 dl->send_out = 0;
1867 dl->send_buffer = msgb_dequeue(&dl->send_queue);
1868 /* No more data to be sent */
1869 if (!dl->send_buffer)
1870 return rc;
1871 LOGP(DLLAPD, LOGL_INFO, "get message from "
Philipp Maier08177d32016-12-08 17:23:26 +01001872 "send-queue (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001873 }
1874
1875 /* How much is left in the send-buffer? */
1876 left = msgb_l3len(dl->send_buffer) - dl->send_out;
1877 /* Segment, if data exceeds N201 */
1878 length = left;
1879 if (length > lctx->n201)
1880 length = lctx->n201;
1881 LOGP(DLLAPD, LOGL_INFO, "msg-len %d sent %d left %d N201 %d "
Philipp Maier08177d32016-12-08 17:23:26 +01001882 "length %d first byte %02x (dl=%p)\n",
rootaf48bed2011-09-26 11:23:06 +02001883 msgb_l3len(dl->send_buffer), dl->send_out, left,
Philipp Maier08177d32016-12-08 17:23:26 +01001884 lctx->n201, length, dl->send_buffer->l3h[0], dl);
rootaf48bed2011-09-26 11:23:06 +02001885 /* If message in send-buffer is completely sent */
1886 if (left == 0) {
1887 msgb_free(dl->send_buffer);
1888 dl->send_buffer = NULL;
1889 goto next_message;
1890 }
1891
Philipp Maier08177d32016-12-08 17:23:26 +01001892 LOGP(DLLAPD, LOGL_INFO, "send I frame %sV(S)=%d (dl=%p)\n",
1893 (left > length) ? "segment " : "", dl->v_send, dl);
rootaf48bed2011-09-26 11:23:06 +02001894
1895 /* Create I frame (segment) and transmit-buffer content */
1896 msg = lapd_msgb_alloc(length, "LAPD I");
1897 msg->l3h = msgb_put(msg, length);
1898 /* assemble message */
1899 memcpy(&nctx, &dl->lctx, sizeof(nctx));
1900 /* keep nctx.ldp */
1901 /* keep nctx.sapi */
1902 /* keep nctx.tei */
1903 nctx.cr = dl->cr.loc2rem.cmd;
1904 nctx.format = LAPD_FORM_I;
1905 nctx.p_f = 0;
1906 nctx.n_send = dl->v_send;
1907 nctx.n_recv = dl->v_recv;
1908 nctx.length = length;
1909 if (left > length)
1910 nctx.more = 1;
1911 else
1912 nctx.more = 0;
1913 if (length)
1914 memcpy(msg->l3h, dl->send_buffer->l3h + dl->send_out,
1915 length);
1916 /* store in tx_hist */
1917 dl->tx_hist[h].msg = lapd_msgb_alloc(msg->len, "HIST");
1918 msgb_put(dl->tx_hist[h].msg, msg->len);
1919 if (length)
1920 memcpy(dl->tx_hist[h].msg->data, msg->l3h, msg->len);
1921 dl->tx_hist[h].more = nctx.more;
1922 /* Add length to track how much is already in the tx buffer */
1923 dl->send_out += length;
1924 } else {
1925 LOGP(DLLAPD, LOGL_INFO, "resend I frame from tx buffer "
Philipp Maier08177d32016-12-08 17:23:26 +01001926 "V(S)=%d (dl=%p)\n", dl->v_send, dl);
rootaf48bed2011-09-26 11:23:06 +02001927
1928 /* Create I frame (segment) from tx_hist */
1929 length = dl->tx_hist[h].msg->len;
1930 msg = lapd_msgb_alloc(length, "LAPD I resend");
1931 msg->l3h = msgb_put(msg, length);
1932 /* assemble message */
1933 memcpy(&nctx, &dl->lctx, sizeof(nctx));
1934 /* keep nctx.ldp */
1935 /* keep nctx.sapi */
1936 /* keep nctx.tei */
1937 nctx.cr = dl->cr.loc2rem.cmd;
1938 nctx.format = LAPD_FORM_I;
1939 nctx.p_f = 0;
1940 nctx.n_send = dl->v_send;
1941 nctx.n_recv = dl->v_recv;
1942 nctx.length = length;
1943 nctx.more = dl->tx_hist[h].more;
1944 if (length)
1945 memcpy(msg->l3h, dl->tx_hist[h].msg->data, length);
1946 }
1947
1948 /* The value of the send state variable V(S) shall be incremented by 1
1949 * at the end of the transmission of the I frame */
1950 dl->v_send = inc_mod(dl->v_send, dl->v_range);
1951
1952 /* If timer T200 is not running at the time right before transmitting a
1953 * frame, when the PH-READY-TO-SEND primitive is received from the
1954 * physical layer., it shall be set. */
1955 if (!osmo_timer_pending(&dl->t200)) {
Andreas Eversberg742fc792011-09-27 09:40:25 +02001956 /* stop Timer T203, if running */
1957 lapd_stop_t203(dl);
1958 /* start Timer T200 */
1959 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001960 }
1961
1962 dl->send_ph_data_req(&nctx, msg);
1963
1964 rc = 0; /* we sent something */
1965 goto next_frame;
1966}
1967
1968/* request link suspension */
1969static int lapd_susp_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1970{
1971 struct lapd_datalink *dl = lctx->dl;
1972 struct msgb *msg = dp->oph.msg;
1973
Philipp Maier08177d32016-12-08 17:23:26 +01001974 LOGP(DLLAPD, LOGL_INFO, "perform suspension (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001975
1976 /* put back the send-buffer to the send-queue (first position) */
1977 if (dl->send_buffer) {
1978 LOGP(DLLAPD, LOGL_INFO, "put frame in sendbuffer back to "
Philipp Maier08177d32016-12-08 17:23:26 +01001979 "queue (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001980 llist_add(&dl->send_buffer->list, &dl->send_queue);
1981 dl->send_buffer = NULL;
1982 } else
Philipp Maier08177d32016-12-08 17:23:26 +01001983 LOGP(DLLAPD, LOGL_INFO, "no frame in sendbuffer (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001984
1985 /* Clear transmit buffer, but keep send buffer */
1986 lapd_dl_flush_tx(dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001987 /* Stop timers (there is no state change, so we must stop all timers */
1988 lapd_stop_t200(dl);
1989 lapd_stop_t203(dl);
rootaf48bed2011-09-26 11:23:06 +02001990
1991 msgb_free(msg);
1992
1993 return send_dl_simple(PRIM_DL_SUSP, PRIM_OP_CONFIRM, &dl->lctx);
1994}
1995
Neels Hofmeyr9e57a5a2015-12-21 11:20:14 +01001996/* request, resume or reconnect of link */
rootaf48bed2011-09-26 11:23:06 +02001997static int lapd_res_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1998{
1999 struct lapd_datalink *dl = lctx->dl;
2000 struct msgb *msg = dp->oph.msg;
2001 struct lapd_msg_ctx nctx;
2002
Philipp Maier08177d32016-12-08 17:23:26 +01002003 LOGP(DLLAPD, LOGL_INFO,
2004 "perform re-establishment (SABM) length=%d (dl=%p)\n",
2005 msg->len, dl);
rootaf48bed2011-09-26 11:23:06 +02002006
2007 /* be sure that history is empty */
2008 lapd_dl_flush_hist(dl);
2009
2010 /* save message context for further use */
2011 memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
2012
2013 /* Replace message in the send-buffer (reconnect) */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +02002014 msgb_free(dl->send_buffer);
2015 dl->send_buffer = NULL;
2016
rootaf48bed2011-09-26 11:23:06 +02002017 dl->send_out = 0;
Andreas Eversbergcad54b82013-07-09 20:25:24 +02002018 if (msg->len) {
rootaf48bed2011-09-26 11:23:06 +02002019 /* Write data into the send buffer, to be sent first */
2020 dl->send_buffer = msg;
Andreas Eversbergcad54b82013-07-09 20:25:24 +02002021 } else {
2022 msgb_free(msg);
2023 msg = NULL;
Andreas Eversberg5ad4ac82011-11-01 09:40:21 +01002024 dl->send_buffer = NULL;
Andreas Eversbergcad54b82013-07-09 20:25:24 +02002025 }
rootaf48bed2011-09-26 11:23:06 +02002026
2027 /* Discard partly received L3 message */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +02002028 msgb_free(dl->rcv_buffer);
2029 dl->rcv_buffer = NULL;
rootaf48bed2011-09-26 11:23:06 +02002030
2031 /* Create new msgb (old one is now free) */
2032 msg = lapd_msgb_alloc(0, "LAPD SABM");
2033 msg->l3h = msg->data;
2034 /* assemble message */
2035 memcpy(&nctx, &dl->lctx, sizeof(nctx));
2036 /* keep nctx.ldp */
2037 /* keep nctx.sapi */
2038 /* keep nctx.tei */
2039 nctx.cr = dl->cr.loc2rem.cmd;
2040 nctx.format = LAPD_FORM_U;
2041 nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
2042 nctx.p_f = 1;
2043 nctx.length = 0;
2044 nctx.more = 0;
2045
2046 dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
2047 msgb_put(dl->tx_hist[0].msg, msg->len);
2048 if (msg->len)
2049 memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
2050 dl->tx_hist[0].more = 0;
2051 /* set Vs to 0, because it is used as index when resending SABM */
2052 dl->v_send = 0;
2053
2054 /* Set states */
2055 dl->own_busy = dl->peer_busy = 0;
2056 dl->retrans_ctr = 0;
2057 lapd_dl_newstate(dl, LAPD_STATE_SABM_SENT);
2058
2059 /* Tramsmit and start T200 */
2060 dl->send_ph_data_req(&nctx, msg);
Andreas Eversberg742fc792011-09-27 09:40:25 +02002061 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02002062
2063 return 0;
2064}
2065
2066/* requesst release of link */
2067static int lapd_rel_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
2068{
2069 struct lapd_datalink *dl = lctx->dl;
2070 struct msgb *msg = dp->oph.msg;
2071 struct lapd_msg_ctx nctx;
2072
2073 /* local release */
2074 if (dp->u.rel_req.mode) {
Philipp Maier08177d32016-12-08 17:23:26 +01002075 LOGP(DLLAPD, LOGL_INFO, "perform local release (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02002076 msgb_free(msg);
Andreas Eversberg742fc792011-09-27 09:40:25 +02002077 /* stop Timer T200 */
2078 lapd_stop_t200(dl);
2079 /* enter idle state, T203 is stopped here, if running */
rootaf48bed2011-09-26 11:23:06 +02002080 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
2081 /* flush buffers */
2082 lapd_dl_flush_tx(dl);
2083 lapd_dl_flush_send(dl);
2084 /* send notification to L3 */
2085 return send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
2086 }
2087
2088 /* in case we are already disconnecting */
2089 if (dl->state == LAPD_STATE_DISC_SENT)
2090 return -EBUSY;
2091
2092 /* flush tx_hist */
2093 lapd_dl_flush_hist(dl);
2094
Philipp Maier08177d32016-12-08 17:23:26 +01002095 LOGP(DLLAPD, LOGL_INFO, "perform normal release (DISC) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02002096
2097 /* Push LAPD header on msgb */
2098 /* assemble message */
2099 memcpy(&nctx, &dl->lctx, sizeof(nctx));
2100 /* keep nctx.ldp */
2101 /* keep nctx.sapi */
2102 /* keep nctx.tei */
2103 nctx.cr = dl->cr.loc2rem.cmd;
2104 nctx.format = LAPD_FORM_U;
2105 nctx.s_u = LAPD_U_DISC;
2106 nctx.p_f = 1;
2107 nctx.length = 0;
2108 nctx.more = 0;
2109
2110 dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
2111 msgb_put(dl->tx_hist[0].msg, msg->len);
2112 if (msg->len)
2113 memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
2114 dl->tx_hist[0].more = 0;
2115 /* set Vs to 0, because it is used as index when resending DISC */
2116 dl->v_send = 0;
2117
2118 /* Set states */
2119 dl->own_busy = dl->peer_busy = 0;
2120 dl->retrans_ctr = 0;
2121 lapd_dl_newstate(dl, LAPD_STATE_DISC_SENT);
2122
2123 /* Tramsmit and start T200 */
2124 dl->send_ph_data_req(&nctx, msg);
Andreas Eversberg742fc792011-09-27 09:40:25 +02002125 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02002126
2127 return 0;
2128}
2129
2130/* request release of link in idle state */
2131static int lapd_rel_req_idle(struct osmo_dlsap_prim *dp,
2132 struct lapd_msg_ctx *lctx)
2133{
2134 struct lapd_datalink *dl = lctx->dl;
2135 struct msgb *msg = dp->oph.msg;
2136
2137 msgb_free(msg);
2138
2139 /* send notification to L3 */
2140 return send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
2141}
2142
2143/* statefull handling for DL SAP messages from L3 */
Holger Hans Peter Freyther579fb092012-11-22 10:54:23 +01002144static const struct l2downstate {
rootaf48bed2011-09-26 11:23:06 +02002145 uint32_t states;
2146 int prim, op;
2147 const char *name;
2148 int (*rout) (struct osmo_dlsap_prim *dp,
2149 struct lapd_msg_ctx *lctx);
2150} l2downstatelist[] = {
2151 /* create and send UI command */
2152 {ALL_STATES,
2153 PRIM_DL_UNIT_DATA, PRIM_OP_REQUEST,
2154 "DL-UNIT-DATA-REQUEST", lapd_udata_req},
2155
2156 /* create and send SABM command */
2157 {SBIT(LAPD_STATE_IDLE),
2158 PRIM_DL_EST, PRIM_OP_REQUEST,
2159 "DL-ESTABLISH-REQUEST", lapd_est_req},
2160
2161 /* create and send I command */
2162 {SBIT(LAPD_STATE_MF_EST) |
2163 SBIT(LAPD_STATE_TIMER_RECOV),
2164 PRIM_DL_DATA, PRIM_OP_REQUEST,
2165 "DL-DATA-REQUEST", lapd_data_req},
2166
2167 /* suspend datalink */
2168 {SBIT(LAPD_STATE_MF_EST) |
2169 SBIT(LAPD_STATE_TIMER_RECOV),
2170 PRIM_DL_SUSP, PRIM_OP_REQUEST,
2171 "DL-SUSPEND-REQUEST", lapd_susp_req},
2172
2173 /* create and send SABM command (resume) */
2174 {SBIT(LAPD_STATE_MF_EST) |
2175 SBIT(LAPD_STATE_TIMER_RECOV),
2176 PRIM_DL_RES, PRIM_OP_REQUEST,
2177 "DL-RESUME-REQUEST", lapd_res_req},
2178
2179 /* create and send SABM command (reconnect) */
2180 {SBIT(LAPD_STATE_IDLE) |
2181 SBIT(LAPD_STATE_MF_EST) |
2182 SBIT(LAPD_STATE_TIMER_RECOV),
2183 PRIM_DL_RECON, PRIM_OP_REQUEST,
2184 "DL-RECONNECT-REQUEST", lapd_res_req},
2185
2186 /* create and send DISC command */
2187 {SBIT(LAPD_STATE_SABM_SENT) |
2188 SBIT(LAPD_STATE_MF_EST) |
2189 SBIT(LAPD_STATE_TIMER_RECOV) |
2190 SBIT(LAPD_STATE_DISC_SENT),
2191 PRIM_DL_REL, PRIM_OP_REQUEST,
2192 "DL-RELEASE-REQUEST", lapd_rel_req},
2193
2194 /* release in idle state */
2195 {SBIT(LAPD_STATE_IDLE),
2196 PRIM_DL_REL, PRIM_OP_REQUEST,
2197 "DL-RELEASE-REQUEST", lapd_rel_req_idle},
2198};
2199
2200#define L2DOWNSLLEN \
2201 (sizeof(l2downstatelist) / sizeof(struct l2downstate))
2202
2203int lapd_recv_dlsap(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
2204{
2205 struct lapd_datalink *dl = lctx->dl;
2206 int i, supported = 0;
2207 struct msgb *msg = dp->oph.msg;
2208 int rc;
2209
2210 /* find function for current state and message */
2211 for (i = 0; i < L2DOWNSLLEN; i++) {
2212 if (dp->oph.primitive == l2downstatelist[i].prim
2213 && dp->oph.operation == l2downstatelist[i].op) {
2214 supported = 1;
2215 if ((SBIT(dl->state) & l2downstatelist[i].states))
2216 break;
2217 }
2218 }
2219 if (!supported) {
Philipp Maier08177d32016-12-08 17:23:26 +01002220 LOGP(DLLAPD, LOGL_NOTICE,
2221 "Message %u/%u unsupported. (dl=%p)\n", dp->oph.primitive,
2222 dp->oph.operation, dl);
rootaf48bed2011-09-26 11:23:06 +02002223 msgb_free(msg);
2224 return 0;
2225 }
2226 if (i == L2DOWNSLLEN) {
2227 LOGP(DLLAPD, LOGL_NOTICE, "Message %u/%u unhandled at this "
Philipp Maier08177d32016-12-08 17:23:26 +01002228 "state %s. (dl=%p)\n", dp->oph.primitive,
Harald Weltec733d142017-03-15 10:20:51 +01002229 dp->oph.operation, lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +02002230 msgb_free(msg);
2231 return 0;
2232 }
2233
Philipp Maier08177d32016-12-08 17:23:26 +01002234 LOGP(DLLAPD, LOGL_INFO, "Message %s received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +01002235 l2downstatelist[i].name, lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +02002236
2237 rc = l2downstatelist[i].rout(dp, lctx);
2238
2239 return rc;
2240}
2241
Katerina Barone-Adesic28c6a02013-02-15 13:27:59 +01002242/*! @} */