blob: e0c232feee9e3b6bb37d1781ecab5da0192be549 [file] [log] [blame]
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02001/*! \file lapd_core.c
2 * LAPD core implementation */
3/*
Harald Welte00b2faf2020-05-02 19:56:36 +02004 * (C) 2010-2020 by Harald Welte <laforge@gnumonks.org>
rootaf48bed2011-09-26 11:23:06 +02005 * (C) 2010-2011 by Andreas Eversberg <jolly@eversberg.eu>
6 *
7 * All Rights Reserved
8 *
Harald Weltee08da972017-11-13 01:00:26 +09009 * SPDX-License-Identifier: GPL-2.0+
10 *
rootaf48bed2011-09-26 11:23:06 +020011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 *
25 */
26
27/*! \addtogroup lapd
28 * @{
Neels Hofmeyr17518fe2017-06-20 04:35:06 +020029 *
30 * Osmocom LAPD core, used for Q.921, LAPDm and others.
31 *
rootaf48bed2011-09-26 11:23:06 +020032 * 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 *
Neels Hofmeyr17518fe2017-06-20 04:35:06 +020065 * \file lapd_core.c
rootaf48bed2011-09-26 11:23:06 +020066 */
67
68/* Enable this to test content resolution on network side:
69 * - The first SABM is received, UA is dropped.
70 * - The phone repeats SABM, but it's content is wrong, so it is ignored
71 * - The phone repeats SABM again, content is right, so UA is sent.
72 */
73//#define TEST_CONTENT_RESOLUTION_NETWORK
74
75#include <stdio.h>
76#include <stdint.h>
77#include <string.h>
78#include <errno.h>
rootaf48bed2011-09-26 11:23:06 +020079
80#include <osmocom/core/logging.h>
81#include <osmocom/core/timer.h>
82#include <osmocom/core/msgb.h>
83#include <osmocom/core/utils.h>
84#include <osmocom/core/talloc.h>
85#include <osmocom/gsm/lapd_core.h>
Max2f0b0c92017-01-12 16:47:13 +010086#include <osmocom/gsm/rsl.h>
rootaf48bed2011-09-26 11:23:06 +020087
88/* TS 04.06 Table 4 / Section 3.8.1 */
89#define LAPD_U_SABM 0x7
90#define LAPD_U_SABME 0xf
91#define LAPD_U_DM 0x3
92#define LAPD_U_UI 0x0
93#define LAPD_U_DISC 0x8
94#define LAPD_U_UA 0xC
95#define LAPD_U_FRMR 0x11
96
97#define LAPD_S_RR 0x0
98#define LAPD_S_RNR 0x1
99#define LAPD_S_REJ 0x2
100
101#define CR_USER2NET_CMD 0
102#define CR_USER2NET_RESP 1
103#define CR_NET2USER_CMD 1
104#define CR_NET2USER_RESP 0
105
106#define LAPD_HEADROOM 56
Harald Welte8617d092020-07-03 19:28:53 +0200107#define LAPD_TAILROOM 16
rootaf48bed2011-09-26 11:23:06 +0200108
109#define SBIT(a) (1 << a)
110#define ALL_STATES 0xffffffff
111
Andreas Eversberg742fc792011-09-27 09:40:25 +0200112static void lapd_t200_cb(void *data);
113static void lapd_t203_cb(void *data);
114static int lapd_send_i(struct lapd_msg_ctx *lctx, int line);
115static int lapd_est_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx);
116
rootaf48bed2011-09-26 11:23:06 +0200117/* UTILITY FUNCTIONS */
118
119struct msgb *lapd_msgb_alloc(int length, const char *name)
120{
121 /* adding space for padding, FIXME: add as an option */
122 if (length < 21)
123 length = 21;
Harald Welte8617d092020-07-03 19:28:53 +0200124 return msgb_alloc_headroom(length + LAPD_HEADROOM + LAPD_TAILROOM, LAPD_HEADROOM, name);
rootaf48bed2011-09-26 11:23:06 +0200125}
126
127static inline uint8_t do_mod(uint8_t x, uint8_t m)
128{
129 return x & (m - 1);
130}
131
132static inline uint8_t inc_mod(uint8_t x, uint8_t m)
133{
134 return (x + 1) & (m - 1);
135}
136
137static inline uint8_t add_mod(uint8_t x, uint8_t y, uint8_t m)
138{
139 return (x + y) & (m - 1);
140}
141
142static inline uint8_t sub_mod(uint8_t x, uint8_t y, uint8_t m)
143{
144 return (x - y) & (m - 1); /* handle negative results correctly */
145}
146
147static void lapd_dl_flush_send(struct lapd_datalink *dl)
148{
149 struct msgb *msg;
150
151 /* Flush send-queue */
152 while ((msg = msgb_dequeue(&dl->send_queue)))
153 msgb_free(msg);
154
155 /* Clear send-buffer */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +0200156 msgb_free(dl->send_buffer);
157 dl->send_buffer = NULL;
rootaf48bed2011-09-26 11:23:06 +0200158}
159
160static void lapd_dl_flush_hist(struct lapd_datalink *dl)
161{
162 unsigned int i;
163
Harald Weltef92e44c2016-08-01 00:24:19 +0200164 if (!dl->range_hist || !dl->tx_hist)
Harald Welte0ee90f82016-07-03 20:45:21 +0200165 return;
166
rootaf48bed2011-09-26 11:23:06 +0200167 for (i = 0; i < dl->range_hist; i++) {
168 if (dl->tx_hist[i].msg) {
169 msgb_free(dl->tx_hist[i].msg);
170 dl->tx_hist[i].msg = NULL;
171 }
172 }
173}
174
175static void lapd_dl_flush_tx(struct lapd_datalink *dl)
176{
177 struct msgb *msg;
178
179 while ((msg = msgb_dequeue(&dl->tx_queue)))
180 msgb_free(msg);
181 lapd_dl_flush_hist(dl);
182}
183
184/* Figure B.2/Q.921 */
Harald Weltec733d142017-03-15 10:20:51 +0100185const struct value_string lapd_state_names[] = {
186 OSMO_VALUE_STRING(LAPD_STATE_NULL),
187 OSMO_VALUE_STRING(LAPD_STATE_TEI_UNASS),
188 OSMO_VALUE_STRING(LAPD_STATE_ASS_TEI_WAIT),
189 OSMO_VALUE_STRING(LAPD_STATE_EST_TEI_WAIT),
190 OSMO_VALUE_STRING(LAPD_STATE_IDLE),
191 OSMO_VALUE_STRING(LAPD_STATE_SABM_SENT),
192 OSMO_VALUE_STRING(LAPD_STATE_DISC_SENT),
193 OSMO_VALUE_STRING(LAPD_STATE_MF_EST),
194 OSMO_VALUE_STRING(LAPD_STATE_TIMER_RECOV),
195 { 0, NULL }
rootaf48bed2011-09-26 11:23:06 +0200196};
197
Harald Weltec733d142017-03-15 10:20:51 +0100198static inline const char *lapd_state_name(enum lapd_state state)
199{
200 return get_value_string(lapd_state_names, state);
201}
202
Andreas Eversberg742fc792011-09-27 09:40:25 +0200203static void lapd_start_t200(struct lapd_datalink *dl)
204{
205 if (osmo_timer_pending(&dl->t200))
206 return;
Harald Welte00b2faf2020-05-02 19:56:36 +0200207 LOGDL(dl, LOGL_INFO, "start T200 (timeout=%d.%06ds)\n",
208 dl->t200_sec, dl->t200_usec);
Andreas Eversberg742fc792011-09-27 09:40:25 +0200209 osmo_timer_schedule(&dl->t200, dl->t200_sec, dl->t200_usec);
210}
211
212static void lapd_start_t203(struct lapd_datalink *dl)
213{
214 if (osmo_timer_pending(&dl->t203))
215 return;
Harald Welte00b2faf2020-05-02 19:56:36 +0200216 LOGDL(dl, LOGL_INFO, "start T203\n");
Andreas Eversberg742fc792011-09-27 09:40:25 +0200217 osmo_timer_schedule(&dl->t203, dl->t203_sec, dl->t203_usec);
218}
219
220static void lapd_stop_t200(struct lapd_datalink *dl)
221{
222 if (!osmo_timer_pending(&dl->t200))
223 return;
Harald Welte00b2faf2020-05-02 19:56:36 +0200224 LOGDL(dl, LOGL_INFO, "stop T200\n");
Andreas Eversberg742fc792011-09-27 09:40:25 +0200225 osmo_timer_del(&dl->t200);
226}
227
228static void lapd_stop_t203(struct lapd_datalink *dl)
229{
230 if (!osmo_timer_pending(&dl->t203))
231 return;
Harald Welte00b2faf2020-05-02 19:56:36 +0200232 LOGDL(dl, LOGL_INFO, "stop T203\n");
Andreas Eversberg742fc792011-09-27 09:40:25 +0200233 osmo_timer_del(&dl->t203);
234}
235
rootaf48bed2011-09-26 11:23:06 +0200236static void lapd_dl_newstate(struct lapd_datalink *dl, uint32_t state)
237{
Harald Welte00b2faf2020-05-02 19:56:36 +0200238 LOGDL(dl, LOGL_INFO, "new state %s -> %s\n",
239 lapd_state_name(dl->state), lapd_state_name(state));
rootaf48bed2011-09-26 11:23:06 +0200240
241 if (state != LAPD_STATE_MF_EST && dl->state == LAPD_STATE_MF_EST) {
242 /* stop T203 on leaving MF EST state, if running */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200243 lapd_stop_t203(dl);
rootaf48bed2011-09-26 11:23:06 +0200244 /* remove content res. (network side) on leaving MF EST state */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +0200245 msgb_free(dl->cont_res);
246 dl->cont_res = NULL;
rootaf48bed2011-09-26 11:23:06 +0200247 }
248
249 /* start T203 on entering MF EST state, if enabled */
250 if ((dl->t203_sec || dl->t203_usec)
Andreas Eversberg742fc792011-09-27 09:40:25 +0200251 && state == LAPD_STATE_MF_EST && dl->state != LAPD_STATE_MF_EST)
252 lapd_start_t203(dl);
rootaf48bed2011-09-26 11:23:06 +0200253
254 dl->state = state;
255}
256
Harald Welte00b2faf2020-05-02 19:56:36 +0200257void *tall_lapd_ctx = NULL;
rootaf48bed2011-09-26 11:23:06 +0200258
Harald Welte00b2faf2020-05-02 19:56:36 +0200259/*! Initialize LAPD datalink instance and allocate history
260 * \param[in] dl caller-allocated datalink structure
261 * \param[in] k maximum number of unacknowledged frames
262 * \param[in] v_range range of sequence numbers
263 * \param[in] maxf maximum frame size (after defragmentation)
264 * \param[in] name human-readable name for this LAPD datalink */
265void lapd_dl_init2(struct lapd_datalink *dl, uint8_t k, uint8_t v_range, int maxf,
266 const char *name)
rootaf48bed2011-09-26 11:23:06 +0200267{
268 int m;
269
270 memset(dl, 0, sizeof(*dl));
271 INIT_LLIST_HEAD(&dl->send_queue);
272 INIT_LLIST_HEAD(&dl->tx_queue);
273 dl->reestablish = 1;
274 dl->n200_est_rel = 3;
275 dl->n200 = 3;
276 dl->t200_sec = 1;
277 dl->t200_usec = 0;
Pablo Neira Ayuso44f423f2017-05-08 18:00:28 +0200278 osmo_timer_setup(&dl->t200, lapd_t200_cb, dl);
rootaf48bed2011-09-26 11:23:06 +0200279 dl->t203_sec = 10;
280 dl->t203_usec = 0;
Pablo Neira Ayuso44f423f2017-05-08 18:00:28 +0200281 osmo_timer_setup(&dl->t203, lapd_t203_cb, dl);
rootaf48bed2011-09-26 11:23:06 +0200282 dl->maxf = maxf;
283 if (k > v_range - 1)
284 k = v_range - 1;
285 dl->k = k;
286 dl->v_range = v_range;
287
288 /* Calculate modulo for history array:
289 * - The history range must be at least k+1.
290 * - The history range must be 2^x, where x is as low as possible.
291 */
292 k++;
293 for (m = 0x80; m; m >>= 1) {
294 if ((m & k)) {
295 if (k > m)
296 m <<= 1;
297 dl->range_hist = m;
298 break;
299 }
300 }
301
Harald Welte00b2faf2020-05-02 19:56:36 +0200302 if (!tall_lapd_ctx) {
303 tall_lapd_ctx = talloc_named_const(NULL, 1, "lapd context");
304 OSMO_ASSERT(tall_lapd_ctx);
305 }
306
307 talloc_free(dl->name);
308 if (name)
309 dl->name = talloc_strdup(tall_lapd_ctx, name);
310 else
311 dl->name = talloc_asprintf(tall_lapd_ctx, "dl=%p", dl);
312
313 LOGDL(dl, LOGL_INFO, "Init DL layer: sequence range = %d, k = %d, "
314 "history range = %d\n", dl->v_range, dl->k, dl->range_hist);
rootaf48bed2011-09-26 11:23:06 +0200315
316 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
317
Holger Hans Peter Freyther10f0bde2014-02-09 20:03:38 +0100318 dl->tx_hist = talloc_zero_array(tall_lapd_ctx,
319 struct lapd_history, dl->range_hist);
rootaf48bed2011-09-26 11:23:06 +0200320}
321
Harald Welte00b2faf2020-05-02 19:56:36 +0200322/*! Initialize LAPD datalink instance and allocate history
323 * \param[in] dl caller-allocated datalink structure
324 * \param[in] k maximum number of unacknowledged frames
325 * \param[in] v_range range of sequence numbers
326 * \param[in] maxf maximum frame size (after defragmentation) */
327void lapd_dl_init(struct lapd_datalink *dl, uint8_t k, uint8_t v_range, int maxf)
328{
329 lapd_dl_init2(dl, k, v_range, maxf, NULL);
330}
331
332void lapd_dl_set_name(struct lapd_datalink *dl, const char *name)
333{
334 if (!name)
335 return;
336 osmo_talloc_replace_string(tall_lapd_ctx, &dl->name, name);
337}
338
rootaf48bed2011-09-26 11:23:06 +0200339/* reset to IDLE state */
340void lapd_dl_reset(struct lapd_datalink *dl)
341{
Harald Welteef5b9b62020-06-07 22:29:53 +0200342 LOGDL(dl, LOGL_INFO, "Resetting LAPD instance\n");
Jean-Francois Dionne893979c2017-03-02 10:45:53 -0500343 /* enter idle state (and remove eventual cont_res) */
344 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
rootaf48bed2011-09-26 11:23:06 +0200345 /* flush buffer */
346 lapd_dl_flush_tx(dl);
347 lapd_dl_flush_send(dl);
348 /* Discard partly received L3 message */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +0200349 msgb_free(dl->rcv_buffer);
350 dl->rcv_buffer = NULL;
Andreas Eversberg742fc792011-09-27 09:40:25 +0200351 /* stop Timers */
352 lapd_stop_t200(dl);
353 lapd_stop_t203(dl);
Jean-Francois Dionned78c9732017-03-06 14:33:20 -0500354 if (dl->state == LAPD_STATE_IDLE)
355 return;
Jean-Francois Dionned78c9732017-03-06 14:33:20 -0500356 /* enter idle state (and remove eventual cont_res) */
357 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
rootaf48bed2011-09-26 11:23:06 +0200358}
359
360/* reset and de-allocate history buffer */
361void lapd_dl_exit(struct lapd_datalink *dl)
362{
363 /* free all ressources except history buffer */
364 lapd_dl_reset(dl);
Ivan Kluchnikovb9759db2017-05-11 15:19:23 +0300365
366 /* enter null state */
367 lapd_dl_newstate(dl, LAPD_STATE_NULL);
368
rootaf48bed2011-09-26 11:23:06 +0200369 /* free history buffer list */
370 talloc_free(dl->tx_hist);
Holger Hans Peter Freytherf5a079f2013-05-08 18:42:39 +0200371 dl->tx_hist = NULL;
Harald Welte00b2faf2020-05-02 19:56:36 +0200372 talloc_free(dl->name);
373 dl->name = NULL;
rootaf48bed2011-09-26 11:23:06 +0200374}
375
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200376/*! Set the \ref lapdm_mode of a LAPDm entity */
rootaf48bed2011-09-26 11:23:06 +0200377int lapd_set_mode(struct lapd_datalink *dl, enum lapd_mode mode)
378{
379 switch (mode) {
380 case LAPD_MODE_USER:
381 dl->cr.loc2rem.cmd = CR_USER2NET_CMD;
382 dl->cr.loc2rem.resp = CR_USER2NET_RESP;
383 dl->cr.rem2loc.cmd = CR_NET2USER_CMD;
384 dl->cr.rem2loc.resp = CR_NET2USER_RESP;
385 break;
386 case LAPD_MODE_NETWORK:
387 dl->cr.loc2rem.cmd = CR_NET2USER_CMD;
388 dl->cr.loc2rem.resp = CR_NET2USER_RESP;
389 dl->cr.rem2loc.cmd = CR_USER2NET_CMD;
390 dl->cr.rem2loc.resp = CR_USER2NET_RESP;
391 break;
392 default:
393 return -EINVAL;
394 }
395 dl->mode = mode;
396
397 return 0;
398}
399
400/* send DL message with optional msgb */
401static int send_dl_l3(uint8_t prim, uint8_t op, struct lapd_msg_ctx *lctx,
402 struct msgb *msg)
403{
404 struct lapd_datalink *dl = lctx->dl;
405 struct osmo_dlsap_prim dp;
406
407 osmo_prim_init(&dp.oph, 0, prim, op, msg);
408 return dl->send_dlsap(&dp, lctx);
409}
410
411/* send simple DL message */
412static inline int send_dl_simple(uint8_t prim, uint8_t op,
413 struct lapd_msg_ctx *lctx)
414{
Pau Espin Pedrol9dd3bf02016-02-29 08:49:22 -0500415 return send_dl_l3(prim, op, lctx, NULL);
rootaf48bed2011-09-26 11:23:06 +0200416}
417
418/* send MDL-ERROR INDICATION */
419static int mdl_error(uint8_t cause, struct lapd_msg_ctx *lctx)
420{
421 struct lapd_datalink *dl = lctx->dl;
422 struct osmo_dlsap_prim dp;
423
Harald Welte00b2faf2020-05-02 19:56:36 +0200424 LOGDL(dl, LOGL_NOTICE,
425 "sending MDL-ERROR-IND cause %d from state %s\n",
426 cause, lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +0200427 osmo_prim_init(&dp.oph, 0, PRIM_MDL_ERROR, PRIM_OP_INDICATION, NULL);
428 dp.u.error_ind.cause = cause;
429 return dl->send_dlsap(&dp, lctx);
430}
431
432/* send UA response */
433static int lapd_send_ua(struct lapd_msg_ctx *lctx, uint8_t len, uint8_t *data)
434{
435 struct msgb *msg = lapd_msgb_alloc(len, "LAPD UA");
436 struct lapd_msg_ctx nctx;
437 struct lapd_datalink *dl = lctx->dl;
438
439 memcpy(&nctx, lctx, sizeof(nctx));
440 msg->l3h = msgb_put(msg, len);
441 if (len)
442 memcpy(msg->l3h, data, len);
443 /* keep nctx.ldp */
444 /* keep nctx.sapi */
445 /* keep nctx.tei */
446 nctx.cr = dl->cr.loc2rem.resp;
447 nctx.format = LAPD_FORM_U;
448 nctx.s_u = LAPD_U_UA;
449 /* keep nctx.p_f */
450 nctx.length = len;
451 nctx.more = 0;
452
453 return dl->send_ph_data_req(&nctx, msg);
454}
455
456/* send DM response */
457static int lapd_send_dm(struct lapd_msg_ctx *lctx)
458{
459 struct msgb *msg = lapd_msgb_alloc(0, "LAPD DM");
460 struct lapd_msg_ctx nctx;
461 struct lapd_datalink *dl = lctx->dl;
462
463 memcpy(&nctx, lctx, sizeof(nctx));
464 /* keep nctx.ldp */
465 /* keep nctx.sapi */
466 /* keep nctx.tei */
467 nctx.cr = dl->cr.loc2rem.resp;
468 nctx.format = LAPD_FORM_U;
469 nctx.s_u = LAPD_U_DM;
470 /* keep nctx.p_f */
471 nctx.length = 0;
472 nctx.more = 0;
473
474 return dl->send_ph_data_req(&nctx, msg);
475}
476
477/* send RR response / command */
478static int lapd_send_rr(struct lapd_msg_ctx *lctx, uint8_t f_bit, uint8_t cmd)
479{
480 struct msgb *msg = lapd_msgb_alloc(0, "LAPD RR");
481 struct lapd_msg_ctx nctx;
482 struct lapd_datalink *dl = lctx->dl;
483
484 memcpy(&nctx, lctx, sizeof(nctx));
485 /* keep nctx.ldp */
486 /* keep nctx.sapi */
487 /* keep nctx.tei */
488 nctx.cr = (cmd) ? dl->cr.loc2rem.cmd : dl->cr.loc2rem.resp;
489 nctx.format = LAPD_FORM_S;
490 nctx.s_u = LAPD_S_RR;
491 nctx.p_f = f_bit;
492 nctx.n_recv = dl->v_recv;
493 nctx.length = 0;
494 nctx.more = 0;
495
496 return dl->send_ph_data_req(&nctx, msg);
497}
498
499/* send RNR response / command */
500static int lapd_send_rnr(struct lapd_msg_ctx *lctx, uint8_t f_bit, uint8_t cmd)
501{
502 struct msgb *msg = lapd_msgb_alloc(0, "LAPD RNR");
503 struct lapd_msg_ctx nctx;
504 struct lapd_datalink *dl = lctx->dl;
505
506 memcpy(&nctx, lctx, sizeof(nctx));
507 /* keep nctx.ldp */
508 /* keep nctx.sapi */
509 /* keep nctx.tei */
510 nctx.cr = (cmd) ? dl->cr.loc2rem.cmd : dl->cr.loc2rem.resp;
511 nctx.format = LAPD_FORM_S;
512 nctx.s_u = LAPD_S_RNR;
513 nctx.p_f = f_bit;
514 nctx.n_recv = dl->v_recv;
515 nctx.length = 0;
516 nctx.more = 0;
517
518 return dl->send_ph_data_req(&nctx, msg);
519}
520
521/* send REJ response */
522static int lapd_send_rej(struct lapd_msg_ctx *lctx, uint8_t f_bit)
523{
524 struct msgb *msg = lapd_msgb_alloc(0, "LAPD REJ");
525 struct lapd_msg_ctx nctx;
526 struct lapd_datalink *dl = lctx->dl;
527
528 memcpy(&nctx, lctx, sizeof(nctx));
529 /* keep nctx.ldp */
530 /* keep nctx.sapi */
531 /* keep nctx.tei */
532 nctx.cr = dl->cr.loc2rem.resp;
533 nctx.format = LAPD_FORM_S;
534 nctx.s_u = LAPD_S_REJ;
535 nctx.p_f = f_bit;
536 nctx.n_recv = dl->v_recv;
537 nctx.length = 0;
538 nctx.more = 0;
539
540 return dl->send_ph_data_req(&nctx, msg);
541}
542
543/* resend SABM or DISC message */
544static int lapd_send_resend(struct lapd_datalink *dl)
545{
546 struct msgb *msg;
547 uint8_t h = do_mod(dl->v_send, dl->range_hist);
548 int length = dl->tx_hist[h].msg->len;
549 struct lapd_msg_ctx nctx;
550
551 /* assemble message */
552 memcpy(&nctx, &dl->lctx, sizeof(nctx));
553 /* keep nctx.ldp */
554 /* keep nctx.sapi */
555 /* keep nctx.tei */
556 nctx.cr = dl->cr.loc2rem.cmd;
557 nctx.format = LAPD_FORM_U;
558 if (dl->state == LAPD_STATE_SABM_SENT)
559 nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
560 else
561 nctx.s_u = LAPD_U_DISC;
562 nctx.p_f = 1;
563 nctx.length = length;
564 nctx.more = 0;
565
566 /* Resend SABM/DISC from tx_hist */
567 msg = lapd_msgb_alloc(length, "LAPD resend");
568 msg->l3h = msgb_put(msg, length);
569 if (length)
570 memcpy(msg->l3h, dl->tx_hist[h].msg->data, length);
571
572 return dl->send_ph_data_req(&nctx, msg);
573}
574
575/* reestablish link */
576static int lapd_reestablish(struct lapd_datalink *dl)
577{
578 struct osmo_dlsap_prim dp;
579 struct msgb *msg;
580
Harald Welte00b2faf2020-05-02 19:56:36 +0200581 LOGDL(dl, LOGL_DEBUG, "LAPD reestablish\n");
Philipp Maier08177d32016-12-08 17:23:26 +0100582
rootaf48bed2011-09-26 11:23:06 +0200583 msg = lapd_msgb_alloc(0, "DUMMY");
584 osmo_prim_init(&dp.oph, 0, PRIM_DL_EST, PRIM_OP_REQUEST, msg);
Pau Espin Pedrola99e1102017-12-08 14:30:47 +0100585
rootaf48bed2011-09-26 11:23:06 +0200586 return lapd_est_req(&dp, &dl->lctx);
587}
588
589/* Timer callback on T200 expiry */
590static void lapd_t200_cb(void *data)
591{
592 struct lapd_datalink *dl = data;
593
Harald Welte00b2faf2020-05-02 19:56:36 +0200594 LOGDL(dl, LOGL_INFO, "Timeout T200 state=%s\n", lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +0200595
596 switch (dl->state) {
597 case LAPD_STATE_SABM_SENT:
598 /* 5.4.1.3 */
Harald Welte7a569522019-06-02 22:37:21 +0200599 if (dl->retrans_ctr >= dl->n200_est_rel + 1) {
rootaf48bed2011-09-26 11:23:06 +0200600 /* flush tx and send buffers */
601 lapd_dl_flush_tx(dl);
602 lapd_dl_flush_send(dl);
603 /* go back to idle state */
604 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
605 /* NOTE: we must not change any other states or buffers
606 * and queues, since we may reconnect after handover
607 * failure. the buffered messages is replaced there */
Philipp Maier6b986c22017-02-01 12:00:45 +0100608 /* send MDL ERROR INIDCATION to L3 */
609 mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
Philipp Maierd9f61292016-12-08 10:45:06 +0100610 /* send RELEASE INDICATION to L3 */
611 send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION,
612 &dl->lctx);
rootaf48bed2011-09-26 11:23:06 +0200613 break;
614 }
615 /* retransmit SABM command */
616 lapd_send_resend(dl);
617 /* increment re-transmission counter */
618 dl->retrans_ctr++;
619 /* restart T200 (PH-READY-TO-SEND) */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200620 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200621 break;
622 case LAPD_STATE_DISC_SENT:
623 /* 5.4.4.3 */
Harald Welte7a569522019-06-02 22:37:21 +0200624 if (dl->retrans_ctr >= dl->n200_est_rel + 1) {
rootaf48bed2011-09-26 11:23:06 +0200625 /* send MDL ERROR INIDCATION to L3 */
626 mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
627 /* flush tx and send buffers */
628 lapd_dl_flush_tx(dl);
629 lapd_dl_flush_send(dl);
630 /* go back to idle state */
631 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
632 /* NOTE: we must not change any other states or buffers
633 * and queues, since we may reconnect after handover
634 * failure. the buffered messages is replaced there */
Harald Welted2a61172020-12-21 17:43:54 +0100635 /* send RELEASE INDICATION to L3 */
636 send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
rootaf48bed2011-09-26 11:23:06 +0200637 break;
638 }
639 /* retransmit DISC command */
640 lapd_send_resend(dl);
641 /* increment re-transmission counter */
642 dl->retrans_ctr++;
643 /* restart T200 (PH-READY-TO-SEND) */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200644 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200645 break;
646 case LAPD_STATE_MF_EST:
647 /* 5.5.7 */
648 dl->retrans_ctr = 0;
649 lapd_dl_newstate(dl, LAPD_STATE_TIMER_RECOV);
650 /* fall through */
651 case LAPD_STATE_TIMER_RECOV:
652 dl->retrans_ctr++;
Harald Welte7a569522019-06-02 22:37:21 +0200653 if (dl->retrans_ctr <= dl->n200) {
rootaf48bed2011-09-26 11:23:06 +0200654 uint8_t vs = sub_mod(dl->v_send, 1, dl->v_range);
655 uint8_t h = do_mod(vs, dl->range_hist);
656 /* retransmit I frame (V_s-1) with P=1, if any */
657 if (dl->tx_hist[h].msg) {
658 struct msgb *msg;
659 int length = dl->tx_hist[h].msg->len;
660 struct lapd_msg_ctx nctx;
661
Harald Welte00b2faf2020-05-02 19:56:36 +0200662 LOGDL(dl, LOGL_INFO, "retransmit last frame V(S)=%d\n", vs);
rootaf48bed2011-09-26 11:23:06 +0200663 /* Create I frame (segment) from tx_hist */
664 memcpy(&nctx, &dl->lctx, sizeof(nctx));
665 /* keep nctx.ldp */
666 /* keep nctx.sapi */
667 /* keep nctx.tei */
668 nctx.cr = dl->cr.loc2rem.cmd;
669 nctx.format = LAPD_FORM_I;
670 nctx.p_f = 1;
671 nctx.n_send = vs;
672 nctx.n_recv = dl->v_recv;
673 nctx.length = length;
674 nctx.more = dl->tx_hist[h].more;
675 msg = lapd_msgb_alloc(length, "LAPD I resend");
676 msg->l3h = msgb_put(msg, length);
677 memcpy(msg->l3h, dl->tx_hist[h].msg->data,
678 length);
679 dl->send_ph_data_req(&nctx, msg);
680 } else {
681 /* OR send appropriate supervision frame with P=1 */
682 if (!dl->own_busy && !dl->seq_err_cond) {
683 lapd_send_rr(&dl->lctx, 1, 1);
684 /* NOTE: In case of sequence error
685 * condition, the REJ frame has been
686 * transmitted when entering the
687 * condition, so it has not be done
688 * here
689 */
690 } else if (dl->own_busy) {
691 lapd_send_rnr(&dl->lctx, 1, 1);
692 } else {
Harald Welte00b2faf2020-05-02 19:56:36 +0200693 LOGDL(dl, LOGL_INFO, "unhandled, pls. fix\n");
rootaf48bed2011-09-26 11:23:06 +0200694 }
695 }
696 /* restart T200 (PH-READY-TO-SEND) */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200697 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200698 } else {
699 /* send MDL ERROR INIDCATION to L3 */
700 mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
701 /* reestablish */
702 if (!dl->reestablish)
703 break;
Harald Welte00b2faf2020-05-02 19:56:36 +0200704 LOGDL(dl, LOGL_NOTICE, "N200+1 reached, performingreestablishment\n");
rootaf48bed2011-09-26 11:23:06 +0200705 lapd_reestablish(dl);
706 }
707 break;
708 default:
Harald Welte00b2faf2020-05-02 19:56:36 +0200709 LOGDL(dl, LOGL_INFO, "T200 expired in unexpected dl->state %s)\n",
710 lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +0200711 }
712}
713
714/* Timer callback on T203 expiry */
715static void lapd_t203_cb(void *data)
716{
717 struct lapd_datalink *dl = data;
718
Harald Welte00b2faf2020-05-02 19:56:36 +0200719 LOGDL(dl, LOGL_INFO, "Timeout T203 state=%s\n", lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +0200720
721 if (dl->state != LAPD_STATE_MF_EST) {
Harald Welte00b2faf2020-05-02 19:56:36 +0200722 LOGDL(dl, LOGL_ERROR, "T203 fired outside MF EST state, please fix!\n");
rootaf48bed2011-09-26 11:23:06 +0200723 return;
724 }
725
726 /* set retransmission counter to 0 */
727 dl->retrans_ctr = 0;
728 /* enter timer recovery state */
729 lapd_dl_newstate(dl, LAPD_STATE_TIMER_RECOV);
730 /* transmit a supervisory command with P bit set to 1 as follows: */
731 if (!dl->own_busy) {
Harald Welte00b2faf2020-05-02 19:56:36 +0200732 LOGDL(dl, LOGL_INFO, "transmit an RR poll command\n");
rootaf48bed2011-09-26 11:23:06 +0200733 /* Send RR with P=1 */
734 lapd_send_rr(&dl->lctx, 1, 1);
735 } else {
Harald Welte00b2faf2020-05-02 19:56:36 +0200736 LOGDL(dl, LOGL_INFO, "transmit an RNR poll command\n");
rootaf48bed2011-09-26 11:23:06 +0200737 /* Send RNR with P=1 */
738 lapd_send_rnr(&dl->lctx, 1, 1);
739 }
740 /* start T200 */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200741 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200742}
743
744/* 5.5.3.1: Common function to acknowlege frames up to the given N(R) value */
745static void lapd_acknowledge(struct lapd_msg_ctx *lctx)
746{
747 struct lapd_datalink *dl = lctx->dl;
748 uint8_t nr = lctx->n_recv;
Holger Hans Peter Freytherfb6a2e22012-03-16 10:35:38 +0100749 int s = 0, rej = 0, t200_reset = 0;
rootaf48bed2011-09-26 11:23:06 +0200750 int i, h;
751
752 /* supervisory frame ? */
753 if (lctx->format == LAPD_FORM_S)
754 s = 1;
755 /* REJ frame ? */
756 if (s && lctx->s_u == LAPD_S_REJ)
757 rej = 1;
758
759 /* Flush all transmit buffers of acknowledged frames */
760 for (i = dl->v_ack; i != nr; i = inc_mod(i, dl->v_range)) {
761 h = do_mod(i, dl->range_hist);
762 if (dl->tx_hist[h].msg) {
763 msgb_free(dl->tx_hist[h].msg);
764 dl->tx_hist[h].msg = NULL;
Harald Welte00b2faf2020-05-02 19:56:36 +0200765 LOGDL(dl, LOGL_INFO, "ack frame %d\n", i);
rootaf48bed2011-09-26 11:23:06 +0200766 }
767 }
768
769 if (dl->state != LAPD_STATE_TIMER_RECOV) {
770 /* When not in the timer recovery condition, the data
771 * link layer entity shall reset the timer T200 on
772 * receipt of a valid I frame with N(R) higher than V(A),
773 * or an REJ with an N(R) equal to V(A). */
774 if ((!rej && nr != dl->v_ack)
775 || (rej && nr == dl->v_ack)) {
rootaf48bed2011-09-26 11:23:06 +0200776 t200_reset = 1;
Andreas Eversberg742fc792011-09-27 09:40:25 +0200777 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200778 /* 5.5.3.1 Note 1 + 2 imply timer recovery cond. */
779 }
780 /* 5.7.4: N(R) sequence error
781 * N(R) is called valid, if and only if
782 * (N(R)-V(A)) mod 8 <= (V(S)-V(A)) mod 8.
783 */
784 if (sub_mod(nr, dl->v_ack, dl->v_range)
785 > sub_mod(dl->v_send, dl->v_ack, dl->v_range)) {
Harald Welte00b2faf2020-05-02 19:56:36 +0200786 LOGDL(dl, LOGL_NOTICE, "N(R) sequence error\n");
rootaf48bed2011-09-26 11:23:06 +0200787 mdl_error(MDL_CAUSE_SEQ_ERR, lctx);
788 }
789 }
790
791 /* V(A) shall be set to the value of N(R) */
792 dl->v_ack = nr;
793
Andreas Eversberg742fc792011-09-27 09:40:25 +0200794 /* If T200 has been stopped by the receipt of an I, RR or RNR frame,
rootaf48bed2011-09-26 11:23:06 +0200795 * and if there are outstanding I frames, restart T200 */
796 if (t200_reset && !rej) {
797 if (dl->tx_hist[sub_mod(dl->v_send, 1, dl->range_hist)].msg) {
Harald Welte00b2faf2020-05-02 19:56:36 +0200798 LOGDL(dl, LOGL_INFO, "start T200, due to unacked I frame(s)\n");
Andreas Eversberg742fc792011-09-27 09:40:25 +0200799 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200800 }
801 }
802
803 /* This also does a restart, when I or S frame is received */
804
805 /* Stop T203, if running */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200806 lapd_stop_t203(dl);
rootaf48bed2011-09-26 11:23:06 +0200807 /* Start T203, if T200 is not running in MF EST state, if enabled */
808 if (!osmo_timer_pending(&dl->t200)
809 && (dl->t203_sec || dl->t203_usec)
810 && (dl->state == LAPD_STATE_MF_EST)) {
Andreas Eversberg742fc792011-09-27 09:40:25 +0200811 lapd_start_t203(dl);
rootaf48bed2011-09-26 11:23:06 +0200812 }
813}
814
815/* L1 -> L2 */
816
Pau Espin Pedrold5f71472020-10-21 13:02:43 +0200817/* Receive a LAPD U SABM(E) message from L1 */
818static int lapd_rx_u_sabm(struct msgb *msg, struct lapd_msg_ctx *lctx)
rootaf48bed2011-09-26 11:23:06 +0200819{
820 struct lapd_datalink *dl = lctx->dl;
821 int length = lctx->length;
Sylvain Munaut9a5f3b82011-11-20 09:01:59 +0100822 int rc = 0;
rootaf48bed2011-09-26 11:23:06 +0200823 uint8_t prim, op;
824
Pau Espin Pedrold5f71472020-10-21 13:02:43 +0200825 prim = PRIM_DL_EST;
826 op = PRIM_OP_INDICATION;
rootaf48bed2011-09-26 11:23:06 +0200827
Pau Espin Pedrold5f71472020-10-21 13:02:43 +0200828 LOGDL(dl, LOGL_INFO, "SABM(E) received in state %s\n", lapd_state_name(dl->state));
829 /* 5.7.1 */
830 dl->seq_err_cond = 0;
831 /* G.2.2 Wrong value of the C/R bit */
832 if (lctx->cr == dl->cr.rem2loc.resp) {
833 LOGDL(dl, LOGL_ERROR, "SABM response error\n");
rootaf48bed2011-09-26 11:23:06 +0200834 msgb_free(msg);
835 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
836 return -EINVAL;
837 }
Pau Espin Pedrold5f71472020-10-21 13:02:43 +0200838
839 /* G.4.5 If SABM is received with L>N201 or with M bit
840 * set, AN MDL-ERROR-INDICATION is sent to MM.
841 */
842 if (lctx->more || length > lctx->n201) {
843 LOGDL(dl, LOGL_ERROR, "SABM too large error\n");
844 msgb_free(msg);
845 mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
846 return -EIO;
847 }
848
849 switch (dl->state) {
850 case LAPD_STATE_IDLE:
851 break;
Pau Espin Pedrol76190d32020-10-21 13:05:44 +0200852 case LAPD_STATE_TIMER_RECOV:
853 LOGDL(dl, LOGL_INFO, "SABM command, timer recovery state\n");
854 /* If link is lost on the remote side, we start over
855 * and send DL-ESTABLISH indication again. */
856 /* 3GPP TS 44.006 8.6.3 "Procedures for re-establishment" */
857 if (length) {
858 /* check for contention resoultion */
859 LOGDL(dl, LOGL_ERROR, "SABM L>0 not expected in timer "
860 "recovery state\n");
861 mdl_error(MDL_CAUSE_SABM_INFO_NOTALL, lctx);
862 lapd_send_dm(lctx);
863 msgb_free(msg);
864 return 0;
865 }
866 /* re-establishment, continue below */
867 lapd_stop_t200(dl);
868 break;
Pau Espin Pedrold5f71472020-10-21 13:02:43 +0200869 case LAPD_STATE_MF_EST:
870 LOGDL(dl, LOGL_INFO, "SABM command, multiple frame established state\n");
871 /* If link is lost on the remote side, we start over
872 * and send DL-ESTABLISH indication again. */
873 /* Additionally, continue in case of content resoltion
874 * (GSM network). This happens, if the mobile has not
875 * yet received UA or another mobile (collision) tries
876 * to establish connection. The mobile must receive
877 * UA again. */
878 /* 5.4.2.1 */
879 if (!length) {
880 /* If no content resolution, this is a
881 * re-establishment. */
882 LOGDL(dl, LOGL_INFO, "Remote reestablish\n");
883 break;
884 }
885 if (!dl->cont_res) {
886 LOGDL(dl, LOGL_INFO, "SABM command not allowed in state %s\n",
887 lapd_state_name(dl->state));
888 mdl_error(MDL_CAUSE_SABM_MF, lctx);
889 msgb_free(msg);
890 return 0;
891 }
892 /* Ignore SABM if content differs from first SABM. */
893 if (dl->mode == LAPD_MODE_NETWORK && length) {
894#ifdef TEST_CONTENT_RESOLUTION_NETWORK
895 dl->cont_res->data[0] ^= 0x01;
896#endif
897 if (memcmp(dl->cont_res->data, msg->data,
898 length)) {
899 LOGDL(dl, LOGL_INFO, "Another SABM with different content - "
900 "ignoring!\n");
901 msgb_free(msg);
902 return 0;
903 }
904 }
905 /* send UA again */
906 lapd_send_ua(lctx, length, msg->l3h);
907 msgb_free(msg);
908 return 0;
909 case LAPD_STATE_DISC_SENT:
910 /* 5.4.6.2 send DM with F=P */
911 lapd_send_dm(lctx);
912 /* stop Timer T200 */
913 lapd_stop_t200(dl);
914 msgb_free(msg);
915 return send_dl_simple(prim, op, lctx);
916 default:
917 /* collision: Send UA, but still wait for rx UA, then
918 * change to MF_EST state.
919 */
920 /* check for contention resoultion */
921 if (dl->tx_hist[0].msg && dl->tx_hist[0].msg->len) {
922 LOGDL(dl, LOGL_NOTICE, "SABM not allowed during contention "
923 "resolution (state=%s)\n", lapd_state_name(dl->state));
924 mdl_error(MDL_CAUSE_SABM_INFO_NOTALL, lctx);
925 }
926 lapd_send_ua(lctx, length, msg->l3h);
927 msgb_free(msg);
928 return 0;
929 }
930 /* save message context for further use */
931 memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
932#ifndef TEST_CONTENT_RESOLUTION_NETWORK
933 /* send UA response */
934 lapd_send_ua(lctx, length, msg->l3h);
935#endif
936 /* set Vs, Vr and Va to 0 */
937 dl->v_send = dl->v_recv = dl->v_ack = 0;
938 /* clear tx_hist */
939 lapd_dl_flush_hist(dl);
940 /* enter multiple-frame-established state */
941 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
942 /* store content resolution data on network side
943 * Note: cont_res will be removed when changing state again,
944 * so it must be allocated AFTER lapd_dl_newstate(). */
945 if (dl->mode == LAPD_MODE_NETWORK && length) {
946 dl->cont_res = lapd_msgb_alloc(length, "CONT RES");
947 memcpy(msgb_put(dl->cont_res, length), msg->l3h,
948 length);
949 LOGDL(dl, LOGL_NOTICE, "Store content res.\n");
950 }
951 /* send notification to L3 */
952 if (length == 0) {
953 /* 5.4.1.2 Normal establishment procedures */
954 rc = send_dl_simple(prim, op, lctx);
955 msgb_free(msg);
956 } else {
957 /* 5.4.1.4 Contention resolution establishment */
958 msgb_trim(msg, length);
959 rc = send_dl_l3(prim, op, lctx, msg);
960 }
rootaf48bed2011-09-26 11:23:06 +0200961 return rc;
962}
963
Pau Espin Pedrold5f71472020-10-21 13:02:43 +0200964/* Receive a LAPD U DM message from L1 */
965static int lapd_rx_u_dm(struct msgb *msg, struct lapd_msg_ctx *lctx)
966{
967 struct lapd_datalink *dl = lctx->dl;
968 int rc = 0;
969
970 LOGDL(dl, LOGL_INFO, "DM received in state %s\n", lapd_state_name(dl->state));
971 /* G.2.2 Wrong value of the C/R bit */
972 if (lctx->cr == dl->cr.rem2loc.cmd) {
973 LOGDL(dl, LOGL_ERROR, "DM command error\n");
974 msgb_free(msg);
975 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
976 return -EINVAL;
977 }
978 if (!lctx->p_f) {
979 /* 5.4.1.2 DM responses with the F bit set to "0"
980 * shall be ignored.
981 */
982 msgb_free(msg);
983 return 0;
984 }
985 switch (dl->state) {
986 case LAPD_STATE_SABM_SENT:
987 break;
988 case LAPD_STATE_MF_EST:
989 if (lctx->p_f) {
990 LOGDL(dl, LOGL_INFO, "unsolicited DM response\n");
991 mdl_error(MDL_CAUSE_UNSOL_DM_RESP, lctx);
992 } else {
993 LOGDL(dl, LOGL_INFO, "unsolicited DM response, "
994 "multiple frame established state\n");
995 mdl_error(MDL_CAUSE_UNSOL_DM_RESP_MF, lctx);
996 /* reestablish */
997 if (!dl->reestablish) {
998 msgb_free(msg);
999 return 0;
1000 }
1001 LOGDL(dl, LOGL_NOTICE, "Performing reestablishment\n");
1002 lapd_reestablish(dl);
1003 }
1004 msgb_free(msg);
1005 return 0;
1006 case LAPD_STATE_TIMER_RECOV:
1007 /* FP = 0 (DM is normal in case PF = 1) */
1008 if (!lctx->p_f) {
1009 LOGDL(dl, LOGL_INFO, "unsolicited DM response, multiple frame "
1010 "established state\n");
1011 mdl_error(MDL_CAUSE_UNSOL_DM_RESP_MF, lctx);
1012 msgb_free(msg);
1013 /* reestablish */
1014 if (!dl->reestablish)
1015 return 0;
1016 LOGDL(dl, LOGL_NOTICE, "Performing reestablishment\n");
1017 return lapd_reestablish(dl);
1018 }
1019 break;
1020 case LAPD_STATE_DISC_SENT:
1021 /* stop Timer T200 */
1022 lapd_stop_t200(dl);
1023 /* go to idle state */
1024 lapd_dl_flush_tx(dl);
1025 lapd_dl_flush_send(dl);
1026 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1027 rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, lctx);
1028 msgb_free(msg);
1029 return 0;
1030 case LAPD_STATE_IDLE:
1031 /* 5.4.5 all other frame types shall be discarded */
1032 default:
1033 LOGDL(dl, LOGL_INFO, "unsolicited DM response! (discarding)\n");
1034 msgb_free(msg);
1035 return 0;
1036 }
1037 /* stop timer T200 */
1038 lapd_stop_t200(dl);
1039 /* go to idle state */
1040 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1041 rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION, lctx);
1042 msgb_free(msg);
1043 return rc;
1044}
1045
1046/* Receive a LAPD U UI message from L1 */
1047static int lapd_rx_u_ui(struct msgb *msg, struct lapd_msg_ctx *lctx)
1048{
1049 struct lapd_datalink *dl = lctx->dl;
1050 int length = lctx->length;
1051
1052 LOGDL(dl, LOGL_INFO, "UI received\n");
1053 /* G.2.2 Wrong value of the C/R bit */
1054 if (lctx->cr == dl->cr.rem2loc.resp) {
1055 LOGDL(dl, LOGL_ERROR, "UI indicates response error\n");
1056 msgb_free(msg);
1057 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1058 return -EINVAL;
1059 }
1060
1061 /* G.4.5 If UI is received with L>N201 or with M bit
1062 * set, AN MDL-ERROR-INDICATION is sent to MM.
1063 */
1064 if (length > lctx->n201 || lctx->more) {
1065 LOGDL(dl, LOGL_ERROR, "UI too large error (%d > N201(%d) or M=%d)\n",
1066 length, lctx->n201, lctx->more);
1067 msgb_free(msg);
1068 mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
1069 return -EIO;
1070 }
1071
1072 /* do some length checks */
1073 if (length == 0) {
1074 /* 5.3.3 UI frames received with the length indicator
1075 * set to "0" shall be ignored
1076 */
1077 LOGDL(dl, LOGL_INFO, "length=0 (discarding)\n");
1078 msgb_free(msg);
1079 return 0;
1080 }
1081 msgb_trim(msg, length);
1082 return send_dl_l3(PRIM_DL_UNIT_DATA, PRIM_OP_INDICATION, lctx, msg);
1083}
1084
1085/* Receive a LAPD U DISC message from L1 */
1086static int lapd_rx_u_disc(struct msgb *msg, struct lapd_msg_ctx *lctx)
1087{
1088 struct lapd_datalink *dl = lctx->dl;
1089 int length = lctx->length;
1090 int rc = 0;
1091 uint8_t prim, op;
1092
1093 prim = PRIM_DL_REL;
1094 op = PRIM_OP_INDICATION;
1095
1096 LOGDL(dl, LOGL_INFO, "DISC received in state %s\n", lapd_state_name(dl->state));
1097 /* flush tx and send buffers */
1098 lapd_dl_flush_tx(dl);
1099 lapd_dl_flush_send(dl);
1100 /* 5.7.1 */
1101 dl->seq_err_cond = 0;
1102 /* G.2.2 Wrong value of the C/R bit */
1103 if (lctx->cr == dl->cr.rem2loc.resp) {
1104 LOGDL(dl, LOGL_ERROR, "DISC response error\n");
1105 msgb_free(msg);
1106 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1107 return -EINVAL;
1108 }
1109 if (length > 0 || lctx->more) {
1110 /* G.4.4 If a DISC or DM frame is received with L>0 or
1111 * with the M bit set to "1", an MDL-ERROR-INDICATION
1112 * primitive with cause "U frame with incorrect
1113 * parameters" is sent to the mobile management entity.
1114 */
1115 LOGDL(dl, LOGL_ERROR, "U frame iwth incorrect parameters\n");
1116 msgb_free(msg);
1117 mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
1118 return -EIO;
1119 }
1120 switch (dl->state) {
1121 case LAPD_STATE_IDLE:
1122 LOGDL(dl, LOGL_INFO, "DISC in idle state\n");
1123 /* send DM with F=P */
1124 msgb_free(msg);
1125 return lapd_send_dm(lctx);
1126 case LAPD_STATE_SABM_SENT:
1127 LOGDL(dl, LOGL_INFO, "DISC in SABM state\n");
1128 /* 5.4.6.2 send DM with F=P */
1129 lapd_send_dm(lctx);
1130 /* stop Timer T200 */
1131 lapd_stop_t200(dl);
1132 /* go to idle state */
1133 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1134 msgb_free(msg);
1135 return send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION,
1136 lctx);
1137 case LAPD_STATE_MF_EST:
1138 case LAPD_STATE_TIMER_RECOV:
1139 LOGDL(dl, LOGL_INFO, "DISC in est state\n");
1140 break;
1141 case LAPD_STATE_DISC_SENT:
1142 LOGDL(dl, LOGL_INFO, "DISC in disc state\n");
1143 prim = PRIM_DL_REL;
1144 op = PRIM_OP_CONFIRM;
1145 break;
1146 default:
1147 lapd_send_ua(lctx, length, msg->l3h);
1148 msgb_free(msg);
1149 return 0;
1150 }
1151 /* send UA response */
1152 lapd_send_ua(lctx, length, msg->l3h);
1153 /* stop Timer T200 */
1154 lapd_stop_t200(dl);
1155 /* enter idle state, keep tx-buffer with UA response */
1156 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1157 /* send notification to L3 */
1158 rc = send_dl_simple(prim, op, lctx);
1159 msgb_free(msg);
1160 return rc;
1161}
1162
1163/* Receive a LAPD U UA message from L1 */
1164static int lapd_rx_u_ua(struct msgb *msg, struct lapd_msg_ctx *lctx)
1165{
1166 struct lapd_datalink *dl = lctx->dl;
1167 int length = lctx->length;
1168 int rc = 0;
1169
1170 LOGDL(dl, LOGL_INFO, "UA received in state %s\n", lapd_state_name(dl->state));
1171 /* G.2.2 Wrong value of the C/R bit */
1172 if (lctx->cr == dl->cr.rem2loc.cmd) {
1173 LOGDL(dl, LOGL_ERROR, "UA indicates command error\n");
1174 msgb_free(msg);
1175 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1176 return -EINVAL;
1177 }
1178
1179 /* G.4.5 If UA is received with L>N201 or with M bit
1180 * set, AN MDL-ERROR-INDICATION is sent to MM.
1181 */
1182 if (lctx->more || length > lctx->n201) {
1183 LOGDL(dl, LOGL_ERROR, "UA too large error\n");
1184 msgb_free(msg);
1185 mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
1186 return -EIO;
1187 }
1188
1189 if (!lctx->p_f) {
1190 /* 5.4.1.2 A UA response with the F bit set to "0"
1191 * shall be ignored.
1192 */
1193 LOGDL(dl, LOGL_INFO, "F=0 (discarding)\n");
1194 msgb_free(msg);
1195 return 0;
1196 }
1197 switch (dl->state) {
1198 case LAPD_STATE_SABM_SENT:
1199 break;
1200 case LAPD_STATE_MF_EST:
1201 case LAPD_STATE_TIMER_RECOV:
1202 LOGDL(dl, LOGL_INFO, "unsolicited UA response! (discarding)\n");
1203 mdl_error(MDL_CAUSE_UNSOL_UA_RESP, lctx);
1204 msgb_free(msg);
1205 return 0;
1206 case LAPD_STATE_DISC_SENT:
1207 LOGDL(dl, LOGL_INFO, "UA in disconnect state\n");
1208 /* stop Timer T200 */
1209 lapd_stop_t200(dl);
1210 /* go to idle state */
1211 lapd_dl_flush_tx(dl);
1212 lapd_dl_flush_send(dl);
1213 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1214 rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, lctx);
1215 msgb_free(msg);
1216 return 0;
1217 case LAPD_STATE_IDLE:
1218 /* 5.4.5 all other frame types shall be discarded */
1219 default:
1220 LOGDL(dl, LOGL_INFO, "unsolicited UA response! (discarding)\n");
1221 msgb_free(msg);
1222 return 0;
1223 }
1224 LOGDL(dl, LOGL_INFO, "UA in SABM state\n");
1225 /* stop Timer T200 */
1226 lapd_stop_t200(dl);
1227 /* compare UA with SABME if contention resolution is applied */
1228 if (dl->tx_hist[0].msg->len) {
1229 if (length != (dl->tx_hist[0].msg->len)
1230 || !!memcmp(dl->tx_hist[0].msg->data, msg->l3h,
1231 length)) {
1232 LOGDL(dl, LOGL_INFO, "**** UA response mismatches ****\n");
Pau Espin Pedrold5f71472020-10-21 13:02:43 +02001233 /* go to idle state */
1234 lapd_dl_flush_tx(dl);
1235 lapd_dl_flush_send(dl);
1236 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
Harald Welted2a61172020-12-21 17:43:54 +01001237 rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION, lctx);
1238 msgb_free(msg);
Pau Espin Pedrold5f71472020-10-21 13:02:43 +02001239 return 0;
1240 }
1241 }
1242 /* set Vs, Vr and Va to 0 */
1243 dl->v_send = dl->v_recv = dl->v_ack = 0;
1244 /* clear tx_hist */
1245 lapd_dl_flush_hist(dl);
1246 /* enter multiple-frame-established state */
1247 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1248 /* send outstanding frames, if any (resume / reconnect) */
1249 lapd_send_i(lctx, __LINE__);
1250 /* send notification to L3 */
1251 rc = send_dl_simple(PRIM_DL_EST, PRIM_OP_CONFIRM, lctx);
1252 msgb_free(msg);
1253 return rc;
1254}
1255
1256/* Receive a LAPD U FRMR message from L1 */
1257static int lapd_rx_u_frmr(struct msgb *msg, struct lapd_msg_ctx *lctx)
1258{
1259 struct lapd_datalink *dl = lctx->dl;
1260
1261 LOGDL(dl, LOGL_NOTICE, "Frame reject received\n");
1262 /* send MDL ERROR INIDCATION to L3 */
1263 mdl_error(MDL_CAUSE_FRMR, lctx);
1264 msgb_free(msg);
1265 /* reestablish */
1266 if (!dl->reestablish)
1267 return 0;
1268 LOGDL(dl, LOGL_NOTICE, "Performing reestablishment\n");
1269 return lapd_reestablish(dl);
1270}
1271
1272/* Receive a LAPD U (Unnumbered) message from L1 */
1273static int lapd_rx_u(struct msgb *msg, struct lapd_msg_ctx *lctx)
1274{
1275 switch (lctx->s_u) {
1276 case LAPD_U_SABM:
1277 case LAPD_U_SABME:
1278 return lapd_rx_u_sabm(msg, lctx);
1279 case LAPD_U_DM:
1280 return lapd_rx_u_dm(msg, lctx);
1281 case LAPD_U_UI:
1282 return lapd_rx_u_ui(msg, lctx);
1283 case LAPD_U_DISC:
1284 return lapd_rx_u_disc(msg, lctx);
1285 case LAPD_U_UA:
1286 return lapd_rx_u_ua(msg, lctx);
1287 case LAPD_U_FRMR:
1288 return lapd_rx_u_frmr(msg, lctx);
1289 default:
1290 /* G.3.1 */
1291 LOGDL(lctx->dl, LOGL_NOTICE, "Unnumbered frame not allowed\n");
1292 msgb_free(msg);
1293 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1294 return -EINVAL;
1295 }
1296}
1297
rootaf48bed2011-09-26 11:23:06 +02001298/* Receive a LAPD S (Supervisory) message from L1 */
1299static int lapd_rx_s(struct msgb *msg, struct lapd_msg_ctx *lctx)
1300{
1301 struct lapd_datalink *dl = lctx->dl;
1302 int length = lctx->length;
1303
1304 if (length > 0 || lctx->more) {
1305 /* G.4.3 If a supervisory frame is received with L>0 or
1306 * with the M bit set to "1", an MDL-ERROR-INDICATION
1307 * primitive with cause "S frame with incorrect
1308 * parameters" is sent to the mobile management entity. */
Harald Welte00b2faf2020-05-02 19:56:36 +02001309 LOGDL(dl, LOGL_ERROR, "S frame with incorrect parameters\n");
rootaf48bed2011-09-26 11:23:06 +02001310 msgb_free(msg);
1311 mdl_error(MDL_CAUSE_SFRM_INC_PARAM, lctx);
1312 return -EIO;
1313 }
1314
1315 if (lctx->cr == dl->cr.rem2loc.resp
1316 && lctx->p_f
1317 && dl->state != LAPD_STATE_TIMER_RECOV) {
1318 /* 5.4.2.2: Inidcate error on supervisory reponse F=1 */
Harald Welte00b2faf2020-05-02 19:56:36 +02001319 LOGDL(dl, LOGL_NOTICE, "S frame response with F=1 error\n");
rootaf48bed2011-09-26 11:23:06 +02001320 mdl_error(MDL_CAUSE_UNSOL_SPRV_RESP, lctx);
1321 }
1322
1323 switch (dl->state) {
1324 case LAPD_STATE_IDLE:
1325 /* if P=1, respond DM with F=1 (5.2.2) */
1326 /* 5.4.5 all other frame types shall be discarded */
1327 if (lctx->p_f)
1328 lapd_send_dm(lctx); /* F=P */
1329 /* fall though */
1330 case LAPD_STATE_SABM_SENT:
1331 case LAPD_STATE_DISC_SENT:
Harald Welte00b2faf2020-05-02 19:56:36 +02001332 LOGDL(dl, LOGL_NOTICE, "S frame ignored in this state\n");
rootaf48bed2011-09-26 11:23:06 +02001333 msgb_free(msg);
1334 return 0;
1335 }
1336 switch (lctx->s_u) {
1337 case LAPD_S_RR:
Harald Welte00b2faf2020-05-02 19:56:36 +02001338 LOGDL(dl, LOGL_INFO, "RR received in state %s\n", lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001339 /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
1340 lapd_acknowledge(lctx);
1341
1342 /* 5.5.3.2 */
1343 if (lctx->cr == dl->cr.rem2loc.cmd
1344 && lctx->p_f) {
1345 if (!dl->own_busy && !dl->seq_err_cond) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001346 LOGDL(dl, LOGL_INFO, "RR frame command with polling bit set and "
1347 "we are not busy, so we reply with RR frame response\n");
rootaf48bed2011-09-26 11:23:06 +02001348 lapd_send_rr(lctx, 1, 0);
1349 /* NOTE: In case of sequence error condition,
1350 * the REJ frame has been transmitted when
1351 * entering the condition, so it has not be
1352 * done here
1353 */
1354 } else if (dl->own_busy) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001355 LOGDL(dl, LOGL_INFO, "RR frame command with polling bit set and "
1356 "we are busy, so we reply with RR frame response\n");
rootaf48bed2011-09-26 11:23:06 +02001357 lapd_send_rnr(lctx, 1, 0);
1358 }
1359 } else if (lctx->cr == dl->cr.rem2loc.resp
1360 && lctx->p_f
1361 && dl->state == LAPD_STATE_TIMER_RECOV) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001362 LOGDL(dl, LOGL_INFO, "RR response with F==1, and we are in timer recovery "
1363 "state, so we leave that state\n");
rootaf48bed2011-09-26 11:23:06 +02001364 /* V(S) to the N(R) in the RR frame */
1365 dl->v_send = lctx->n_recv;
Andreas Eversberg742fc792011-09-27 09:40:25 +02001366 /* stop Timer T200 */
1367 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001368 /* 5.5.7 Clear timer recovery condition */
1369 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1370 }
1371 /* Send message, if possible due to acknowledged data */
1372 lapd_send_i(lctx, __LINE__);
1373
1374 break;
1375 case LAPD_S_RNR:
Harald Welte00b2faf2020-05-02 19:56:36 +02001376 LOGDL(dl, LOGL_INFO, "RNR received in state %s\n", lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001377 /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
1378 lapd_acknowledge(lctx);
1379
1380 /* 5.5.5 */
1381 /* Set peer receiver busy condition */
1382 dl->peer_busy = 1;
1383
1384 if (lctx->p_f) {
1385 if (lctx->cr == dl->cr.rem2loc.cmd) {
1386 if (!dl->own_busy) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001387 LOGDL(dl, LOGL_INFO, "RNR poll command and we are not busy, "
1388 "so we reply with RR final response\n");
rootaf48bed2011-09-26 11:23:06 +02001389 /* Send RR with F=1 */
1390 lapd_send_rr(lctx, 1, 0);
1391 } else {
Harald Welte00b2faf2020-05-02 19:56:36 +02001392 LOGDL(dl, LOGL_INFO, "RNR poll command and we are busy, so "
1393 "we reply with RNR final response\n");
rootaf48bed2011-09-26 11:23:06 +02001394 /* Send RNR with F=1 */
1395 lapd_send_rnr(lctx, 1, 0);
1396 }
1397 } else if (dl->state == LAPD_STATE_TIMER_RECOV) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001398 LOGDL(dl, LOGL_INFO, "RNR poll response and we in timer recovery "
1399 "state, so we leave that state\n");
rootaf48bed2011-09-26 11:23:06 +02001400 /* 5.5.7 Clear timer recovery condition */
1401 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1402 /* V(S) to the N(R) in the RNR frame */
1403 dl->v_send = lctx->n_recv;
1404 }
1405 } else
Harald Welte00b2faf2020-05-02 19:56:36 +02001406 LOGDL(dl, LOGL_INFO, "RNR not polling/final state received\n");
rootaf48bed2011-09-26 11:23:06 +02001407
1408 /* Send message, if possible due to acknowledged data */
1409 lapd_send_i(lctx, __LINE__);
1410
1411 break;
1412 case LAPD_S_REJ:
Harald Welte00b2faf2020-05-02 19:56:36 +02001413 LOGDL(dl, LOGL_INFO, "REJ received in state %s\n", lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001414 /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
1415 lapd_acknowledge(lctx);
1416
1417 /* 5.5.4.1 */
1418 if (dl->state != LAPD_STATE_TIMER_RECOV) {
1419 /* Clear an existing peer receiver busy condition */
1420 dl->peer_busy = 0;
1421 /* V(S) and V(A) to the N(R) in the REJ frame */
1422 dl->v_send = dl->v_ack = lctx->n_recv;
Andreas Eversberg742fc792011-09-27 09:40:25 +02001423 /* stop Timer T200 */
1424 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001425 /* 5.5.3.2 */
1426 if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
1427 if (!dl->own_busy && !dl->seq_err_cond) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001428 LOGDL(dl, LOGL_INFO, "REJ poll command not in timer recovery "
1429 "state and not in own busy condition received, so we "
1430 "respond with RR final response\n");
rootaf48bed2011-09-26 11:23:06 +02001431 lapd_send_rr(lctx, 1, 0);
1432 /* NOTE: In case of sequence error
1433 * condition, the REJ frame has been
1434 * transmitted when entering the
1435 * condition, so it has not be done
1436 * here
1437 */
1438 } else if (dl->own_busy) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001439 LOGDL(dl, LOGL_INFO, "REJ poll command not in timer recovery "
1440 "state and in own busy condition received, so we "
1441 "respond with RNR final response\n");
rootaf48bed2011-09-26 11:23:06 +02001442 lapd_send_rnr(lctx, 1, 0);
1443 }
1444 } else
Harald Welte00b2faf2020-05-02 19:56:36 +02001445 LOGDL(dl, LOGL_INFO, "REJ response or not polling command not "
1446 "in timer recovery state received\n");
rootaf48bed2011-09-26 11:23:06 +02001447 /* send MDL ERROR INIDCATION to L3 */
1448 if (lctx->cr == dl->cr.rem2loc.resp && lctx->p_f) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001449 LOGDL(dl, LOGL_ERROR, "unsolicited supervisory response!\n");
rootaf48bed2011-09-26 11:23:06 +02001450 mdl_error(MDL_CAUSE_UNSOL_SPRV_RESP, lctx);
1451 }
1452
1453 } else if (lctx->cr == dl->cr.rem2loc.resp && lctx->p_f) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001454 LOGDL(dl, LOGL_INFO, "REJ poll response in timer recovery state received\n");
rootaf48bed2011-09-26 11:23:06 +02001455 /* Clear an existing peer receiver busy condition */
1456 dl->peer_busy = 0;
1457 /* V(S) and V(A) to the N(R) in the REJ frame */
1458 dl->v_send = dl->v_ack = lctx->n_recv;
Andreas Eversberg742fc792011-09-27 09:40:25 +02001459 /* stop Timer T200 */
1460 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001461 /* 5.5.7 Clear timer recovery condition */
1462 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1463 } else {
1464 /* Clear an existing peer receiver busy condition */
1465 dl->peer_busy = 0;
1466 /* V(S) and V(A) to the N(R) in the REJ frame */
1467 dl->v_send = dl->v_ack = lctx->n_recv;
1468 /* 5.5.3.2 */
1469 if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
1470 if (!dl->own_busy && !dl->seq_err_cond) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001471 LOGDL(dl, LOGL_INFO, "REJ poll command in timer recovery "
1472 "state and not in own busy condition received, so we "
1473 "respond with RR final response\n");
rootaf48bed2011-09-26 11:23:06 +02001474 lapd_send_rr(lctx, 1, 0);
1475 /* NOTE: In case of sequence error
1476 * condition, the REJ frame has been
1477 * transmitted when entering the
1478 * condition, so it has not be done
1479 * here
1480 */
1481 } else if (dl->own_busy) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001482 LOGDL(dl, LOGL_INFO, "REJ poll command in timer recovery "
1483 "state and in own busy condition received, so we "
1484 "respond with RNR final response\n");
rootaf48bed2011-09-26 11:23:06 +02001485 lapd_send_rnr(lctx, 1, 0);
1486 }
1487 } else
Harald Welte00b2faf2020-05-02 19:56:36 +02001488 LOGDL(dl, LOGL_INFO, "REJ response or not polling command in "
1489 "timer recovery state received\n");
rootaf48bed2011-09-26 11:23:06 +02001490 }
1491
1492 /* FIXME: 5.5.4.2 2) */
1493
1494 /* Send message, if possible due to acknowledged data */
1495 lapd_send_i(lctx, __LINE__);
1496
1497 break;
1498 default:
1499 /* G.3.1 */
Harald Welte00b2faf2020-05-02 19:56:36 +02001500 LOGDL(dl, LOGL_ERROR, "Supervisory frame not allowed\n");
rootaf48bed2011-09-26 11:23:06 +02001501 msgb_free(msg);
1502 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1503 return -EINVAL;
1504 }
1505 msgb_free(msg);
1506 return 0;
1507}
1508
1509/* Receive a LAPD I (Information) message from L1 */
1510static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx)
1511{
1512 struct lapd_datalink *dl = lctx->dl;
1513 //uint8_t nr = lctx->n_recv;
1514 uint8_t ns = lctx->n_send;
1515 int length = lctx->length;
1516 int rc;
1517
Harald Welte00b2faf2020-05-02 19:56:36 +02001518 LOGDL(dl, LOGL_INFO, "I received in state %s on SAPI(%u)\n",
1519 lapd_state_name(dl->state), lctx->sapi);
Pau Espin Pedrola99e1102017-12-08 14:30:47 +01001520
rootaf48bed2011-09-26 11:23:06 +02001521 /* G.2.2 Wrong value of the C/R bit */
1522 if (lctx->cr == dl->cr.rem2loc.resp) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001523 LOGDL(dl, LOGL_ERROR, "I frame response not allowed (state %s)\n",
1524 lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001525 msgb_free(msg);
1526 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1527 return -EINVAL;
1528 }
1529
1530 if (length == 0 || length > lctx->n201) {
1531 /* G.4.2 If the length indicator of an I frame is set
1532 * to a numerical value L>N201 or L=0, an MDL-ERROR-INDICATION
1533 * primitive with cause "I frame with incorrect length"
1534 * is sent to the mobile management entity. */
Harald Welte00b2faf2020-05-02 19:56:36 +02001535 LOGDL(dl, LOGL_ERROR, "I frame length not allowed (state %s)\n",
1536 lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001537 msgb_free(msg);
1538 mdl_error(MDL_CAUSE_IFRM_INC_LEN, lctx);
1539 return -EIO;
1540 }
1541
1542 /* G.4.2 If the numerical value of L is L<N201 and the M
1543 * bit is set to "1", then an MDL-ERROR-INDICATION primitive with
1544 * cause "I frame with incorrect use of M bit" is sent to the
1545 * mobile management entity. */
1546 if (lctx->more && length < lctx->n201) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001547 LOGDL(dl, LOGL_ERROR, "I frame with M bit too short (state %s)\n",
1548 lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001549 msgb_free(msg);
1550 mdl_error(MDL_CAUSE_IFRM_INC_MBITS, lctx);
1551 return -EIO;
1552 }
1553
1554 switch (dl->state) {
1555 case LAPD_STATE_IDLE:
1556 /* if P=1, respond DM with F=1 (5.2.2) */
1557 /* 5.4.5 all other frame types shall be discarded */
1558 if (lctx->p_f)
1559 lapd_send_dm(lctx); /* F=P */
1560 /* fall though */
1561 case LAPD_STATE_SABM_SENT:
1562 case LAPD_STATE_DISC_SENT:
Harald Welte00b2faf2020-05-02 19:56:36 +02001563 LOGDL(dl, LOGL_NOTICE, "I frame ignored in state %s\n", lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001564 msgb_free(msg);
1565 return 0;
1566 }
1567
1568 /* 5.7.1: N(s) sequence error */
1569 if (ns != dl->v_recv) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001570 LOGDL(dl, LOGL_NOTICE, "N(S) sequence error: N(S)=%u, V(R)=%u (state %s)\n",
1571 ns, dl->v_recv, lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001572 /* discard data */
1573 msgb_free(msg);
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001574 if (dl->seq_err_cond != 1) {
rootaf48bed2011-09-26 11:23:06 +02001575 /* FIXME: help me understand what exactly todo here
rootaf48bed2011-09-26 11:23:06 +02001576 */
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001577 dl->seq_err_cond = 1;
rootaf48bed2011-09-26 11:23:06 +02001578 lapd_send_rej(lctx, lctx->p_f);
1579 } else {
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001580 /* If there are two subsequent sequence errors received,
1581 * ignore it. (Ignore every second subsequent error.)
1582 * This happens if our reply with the REJ is too slow,
1583 * so the remote gets a T200 timeout and sends another
1584 * frame with a sequence error.
1585 * Test showed that replying with two subsequent REJ
1586 * messages could the remote L2 process to abort.
1587 * Replying too slow shouldn't happen, but may happen
1588 * over serial link between BB and LAPD.
1589 */
1590 dl->seq_err_cond = 2;
rootaf48bed2011-09-26 11:23:06 +02001591 }
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001592 /* Even if N(s) sequence error, acknowledge to N(R)-1 */
1593 /* 5.5.3.1: Acknowlege all transmitted frames up the N(R)-1 */
1594 lapd_acknowledge(lctx); /* V(A) is also set here */
1595
1596 /* Send message, if possible due to acknowledged data */
1597 lapd_send_i(lctx, __LINE__);
1598
1599 return 0;
rootaf48bed2011-09-26 11:23:06 +02001600 }
1601 dl->seq_err_cond = 0;
1602
1603 /* Increment receiver state */
1604 dl->v_recv = inc_mod(dl->v_recv, dl->v_range);
Harald Welte00b2faf2020-05-02 19:56:36 +02001605 LOGDL(dl, LOGL_INFO, "incrementing V(R) to %u\n", dl->v_recv);
rootaf48bed2011-09-26 11:23:06 +02001606
1607 /* 5.5.3.1: Acknowlege all transmitted frames up the the N(R)-1 */
1608 lapd_acknowledge(lctx); /* V(A) is also set here */
1609
1610 /* Only if we are not in own receiver busy condition */
1611 if (!dl->own_busy) {
1612 /* if the frame carries a complete segment */
1613 if (!lctx->more && !dl->rcv_buffer) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001614 LOGDL(dl, LOGL_INFO, "message in single I frame\n");
rootaf48bed2011-09-26 11:23:06 +02001615 /* send a DATA INDICATION to L3 */
Harald Welte087116a2013-06-18 21:41:34 +02001616 msgb_trim(msg, length);
rootaf48bed2011-09-26 11:23:06 +02001617 rc = send_dl_l3(PRIM_DL_DATA, PRIM_OP_INDICATION, lctx,
1618 msg);
1619 } else {
1620 /* create rcv_buffer */
1621 if (!dl->rcv_buffer) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001622 LOGDL(dl, LOGL_INFO, "message in multiple I frames (first message)\n");
rootaf48bed2011-09-26 11:23:06 +02001623 dl->rcv_buffer = lapd_msgb_alloc(dl->maxf,
1624 "LAPD RX");
1625 dl->rcv_buffer->l3h = dl->rcv_buffer->data;
1626 }
1627 /* concat. rcv_buffer */
1628 if (msgb_l3len(dl->rcv_buffer) + length > dl->maxf) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001629 LOGDL(dl, LOGL_NOTICE, "Received frame overflow!\n");
rootaf48bed2011-09-26 11:23:06 +02001630 } else {
1631 memcpy(msgb_put(dl->rcv_buffer, length),
1632 msg->l3h, length);
1633 }
1634 /* if the last segment was received */
1635 if (!lctx->more) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001636 LOGDL(dl, LOGL_INFO, "message in multiple I frames (last message)\n");
rootaf48bed2011-09-26 11:23:06 +02001637 rc = send_dl_l3(PRIM_DL_DATA,
1638 PRIM_OP_INDICATION, lctx,
1639 dl->rcv_buffer);
1640 dl->rcv_buffer = NULL;
1641 } else
Harald Welte00b2faf2020-05-02 19:56:36 +02001642 LOGDL(dl, LOGL_INFO, "message in multiple I frames (next message)\n");
rootaf48bed2011-09-26 11:23:06 +02001643 msgb_free(msg);
1644
1645 }
Harald Weltebc1d7152020-07-04 10:52:13 +02001646 /* the L3 or higher (called in-line above via send_dl_l3) might have destroyed the
1647 * data link meanwhile. See OS#1761 */
1648 if (dl->state == LAPD_STATE_NULL)
1649 return 0;
rootaf48bed2011-09-26 11:23:06 +02001650 } else
Harald Welte00b2faf2020-05-02 19:56:36 +02001651 LOGDL(dl, LOGL_INFO, "I frame ignored during own receiver busy condition\n");
rootaf48bed2011-09-26 11:23:06 +02001652
1653 /* Check for P bit */
1654 if (lctx->p_f) {
1655 /* 5.5.2.1 */
1656 /* check if we are not in own receiver busy */
1657 if (!dl->own_busy) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001658 LOGDL(dl, LOGL_INFO, "we are not busy, send RR\n");
rootaf48bed2011-09-26 11:23:06 +02001659 /* Send RR with F=1 */
1660 rc = lapd_send_rr(lctx, 1, 0);
1661 } else {
Harald Welte00b2faf2020-05-02 19:56:36 +02001662 LOGDL(dl, LOGL_INFO, "we are busy, send RNR\n");
rootaf48bed2011-09-26 11:23:06 +02001663 /* Send RNR with F=1 */
1664 rc = lapd_send_rnr(lctx, 1, 0);
1665 }
1666 } else {
1667 /* 5.5.2.2 */
1668 /* check if we are not in own receiver busy */
1669 if (!dl->own_busy) {
1670 /* NOTE: V(R) is already set above */
1671 rc = lapd_send_i(lctx, __LINE__);
Daniel Willmann3dc4e162014-03-20 19:24:48 +01001672
1673 /* if update_pending_iframe returns 0 it updated
1674 * the lapd header of an iframe in the tx queue */
1675 if (rc && dl->update_pending_frames)
1676 rc = dl->update_pending_frames(lctx);
1677
rootaf48bed2011-09-26 11:23:06 +02001678 if (rc) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001679 LOGDL(dl, LOGL_INFO, "we are not busy and have no pending data, "
1680 "send RR\n");
rootaf48bed2011-09-26 11:23:06 +02001681 /* Send RR with F=0 */
1682 return lapd_send_rr(lctx, 0, 0);
1683 }
1684 /* all I or one RR is sent, we are done */
1685 return 0;
1686 } else {
Harald Welte00b2faf2020-05-02 19:56:36 +02001687 LOGDL(dl, LOGL_INFO, "we are busy, send RNR\n");
rootaf48bed2011-09-26 11:23:06 +02001688 /* Send RNR with F=0 */
1689 rc = lapd_send_rnr(lctx, 0, 0);
1690 }
1691 }
1692
1693 /* Send message, if possible due to acknowledged data */
1694 lapd_send_i(lctx, __LINE__);
1695
1696 return rc;
1697}
1698
1699/* Receive a LAPD message from L1 */
1700int lapd_ph_data_ind(struct msgb *msg, struct lapd_msg_ctx *lctx)
1701{
1702 int rc;
1703
1704 switch (lctx->format) {
1705 case LAPD_FORM_U:
1706 rc = lapd_rx_u(msg, lctx);
1707 break;
1708 case LAPD_FORM_S:
1709 rc = lapd_rx_s(msg, lctx);
1710 break;
1711 case LAPD_FORM_I:
1712 rc = lapd_rx_i(msg, lctx);
1713 break;
1714 default:
Harald Welte00b2faf2020-05-02 19:56:36 +02001715 LOGDL(lctx->dl, LOGL_NOTICE, "unknown LAPD format\n");
rootaf48bed2011-09-26 11:23:06 +02001716 msgb_free(msg);
1717 rc = -EINVAL;
1718 }
1719 return rc;
1720}
1721
1722/* L3 -> L2 */
1723
1724/* send unit data */
1725static int lapd_udata_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1726{
1727 struct lapd_datalink *dl = lctx->dl;
1728 struct msgb *msg = dp->oph.msg;
1729 struct lapd_msg_ctx nctx;
1730
1731 memcpy(&nctx, lctx, sizeof(nctx));
1732 /* keep nctx.ldp */
1733 /* keep nctx.sapi */
1734 /* keep nctx.tei */
1735 nctx.cr = dl->cr.loc2rem.cmd;
1736 nctx.format = LAPD_FORM_U;
1737 nctx.s_u = LAPD_U_UI;
1738 /* keep nctx.p_f */
1739 nctx.length = msg->len;
1740 nctx.more = 0;
1741
1742 return dl->send_ph_data_req(&nctx, msg);
1743}
1744
1745/* request link establishment */
1746static int lapd_est_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1747{
1748 struct lapd_datalink *dl = lctx->dl;
1749 struct msgb *msg = dp->oph.msg;
1750 struct lapd_msg_ctx nctx;
1751
1752 if (msg->len)
Harald Welte00b2faf2020-05-02 19:56:36 +02001753 LOGDL(dl, LOGL_INFO, "perform establishment with content (SABM)\n");
rootaf48bed2011-09-26 11:23:06 +02001754 else
Harald Welte00b2faf2020-05-02 19:56:36 +02001755 LOGDL(dl, LOGL_INFO, "perform normal establishm. (SABM)\n");
rootaf48bed2011-09-26 11:23:06 +02001756
1757 /* Flush send-queue */
1758 /* Clear send-buffer */
1759 lapd_dl_flush_send(dl);
1760 /* be sure that history is empty */
1761 lapd_dl_flush_hist(dl);
1762
1763 /* save message context for further use */
1764 memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
1765
1766 /* Discard partly received L3 message */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +02001767 msgb_free(dl->rcv_buffer);
1768 dl->rcv_buffer = NULL;
rootaf48bed2011-09-26 11:23:06 +02001769
1770 /* assemble message */
1771 memcpy(&nctx, &dl->lctx, sizeof(nctx));
1772 /* keep nctx.ldp */
1773 /* keep nctx.sapi */
1774 /* keep nctx.tei */
1775 nctx.cr = dl->cr.loc2rem.cmd;
1776 nctx.format = LAPD_FORM_U;
1777 nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
1778 nctx.p_f = 1;
1779 nctx.length = msg->len;
1780 nctx.more = 0;
1781
1782 /* Transmit-buffer carries exactly one segment */
1783 dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
1784 msgb_put(dl->tx_hist[0].msg, msg->len);
1785 if (msg->len)
1786 memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
1787 dl->tx_hist[0].more = 0;
1788 /* set Vs to 0, because it is used as index when resending SABM */
1789 dl->v_send = 0;
Pau Espin Pedrola99e1102017-12-08 14:30:47 +01001790
rootaf48bed2011-09-26 11:23:06 +02001791 /* Set states */
1792 dl->own_busy = dl->peer_busy = 0;
1793 dl->retrans_ctr = 0;
1794 lapd_dl_newstate(dl, LAPD_STATE_SABM_SENT);
1795
1796 /* Tramsmit and start T200 */
1797 dl->send_ph_data_req(&nctx, msg);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001798 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001799
1800 return 0;
1801}
1802
1803/* send data */
1804static int lapd_data_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1805{
1806 struct lapd_datalink *dl = lctx->dl;
1807 struct msgb *msg = dp->oph.msg;
1808
Holger Hans Peter Freyther90656db2012-01-13 05:49:29 +08001809 if (msgb_l3len(msg) == 0) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001810 LOGDL(dl, LOGL_ERROR, "writing an empty message is not possible\n");
Holger Hans Peter Freyther90656db2012-01-13 05:49:29 +08001811 msgb_free(msg);
1812 return -1;
1813 }
1814
Harald Welte00b2faf2020-05-02 19:56:36 +02001815 LOGDL(dl, LOGL_INFO, "writing message to send-queue: l3len: %d\n", msgb_l3len(msg));
rootaf48bed2011-09-26 11:23:06 +02001816
1817 /* Write data into the send queue */
1818 msgb_enqueue(&dl->send_queue, msg);
1819
1820 /* Send message, if possible */
1821 lapd_send_i(&dl->lctx, __LINE__);
1822
1823 return 0;
1824}
1825
1826/* Send next I frame from queued/buffered data */
1827static int lapd_send_i(struct lapd_msg_ctx *lctx, int line)
1828{
1829 struct lapd_datalink *dl = lctx->dl;
1830 uint8_t k = dl->k;
1831 uint8_t h;
1832 struct msgb *msg;
1833 int length, left;
1834 int rc = - 1; /* we sent nothing */
1835 struct lapd_msg_ctx nctx;
1836
1837
Harald Welte00b2faf2020-05-02 19:56:36 +02001838 LOGDL(dl, LOGL_INFO, "%s() called from line %d\n", __func__, line);
rootaf48bed2011-09-26 11:23:06 +02001839
1840 next_frame:
1841
1842 if (dl->peer_busy) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001843 LOGDL(dl, LOGL_INFO, "peer busy, not sending\n");
rootaf48bed2011-09-26 11:23:06 +02001844 return rc;
1845 }
1846
1847 if (dl->state == LAPD_STATE_TIMER_RECOV) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001848 LOGDL(dl, LOGL_INFO, "timer recovery, not sending\n");
rootaf48bed2011-09-26 11:23:06 +02001849 return rc;
1850 }
1851
1852 /* If the send state variable V(S) is equal to V(A) plus k
1853 * (where k is the maximum number of outstanding I frames - see
1854 * subclause 5.8.4), the data link layer entity shall not transmit any
1855 * new I frames, but shall retransmit an I frame as a result
1856 * of the error recovery procedures as described in subclauses 5.5.4 and
1857 * 5.5.7. */
1858 if (dl->v_send == add_mod(dl->v_ack, k, dl->v_range)) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001859 LOGDL(dl, LOGL_INFO, "k frames outstanding, not sending more "
1860 "(k=%u V(S)=%u V(A)=%u)\n", k, dl->v_send, dl->v_ack);
rootaf48bed2011-09-26 11:23:06 +02001861 return rc;
1862 }
1863
1864 h = do_mod(dl->v_send, dl->range_hist);
1865
1866 /* if we have no tx_hist yet, we create it */
1867 if (!dl->tx_hist[h].msg) {
1868 /* Get next message into send-buffer, if any */
1869 if (!dl->send_buffer) {
1870 next_message:
1871 dl->send_out = 0;
1872 dl->send_buffer = msgb_dequeue(&dl->send_queue);
1873 /* No more data to be sent */
1874 if (!dl->send_buffer)
1875 return rc;
Harald Welte00b2faf2020-05-02 19:56:36 +02001876 LOGDL(dl, LOGL_INFO, "get message from send-queue\n");
rootaf48bed2011-09-26 11:23:06 +02001877 }
1878
1879 /* How much is left in the send-buffer? */
1880 left = msgb_l3len(dl->send_buffer) - dl->send_out;
1881 /* Segment, if data exceeds N201 */
1882 length = left;
1883 if (length > lctx->n201)
1884 length = lctx->n201;
Harald Welte00b2faf2020-05-02 19:56:36 +02001885 LOGDL(dl, LOGL_INFO, "msg-len %d sent %d left %d N201 %d length %d "
1886 "first byte %02x\n", msgb_l3len(dl->send_buffer), dl->send_out, left,
1887 lctx->n201, length, dl->send_buffer->l3h[0]);
rootaf48bed2011-09-26 11:23:06 +02001888 /* If message in send-buffer is completely sent */
1889 if (left == 0) {
1890 msgb_free(dl->send_buffer);
1891 dl->send_buffer = NULL;
1892 goto next_message;
1893 }
1894
Harald Welte00b2faf2020-05-02 19:56:36 +02001895 LOGDL(dl, LOGL_INFO, "send I frame %sV(S)=%d\n",
1896 (left > length) ? "segment " : "", dl->v_send);
rootaf48bed2011-09-26 11:23:06 +02001897
1898 /* Create I frame (segment) and transmit-buffer content */
1899 msg = lapd_msgb_alloc(length, "LAPD I");
1900 msg->l3h = msgb_put(msg, length);
1901 /* assemble message */
1902 memcpy(&nctx, &dl->lctx, sizeof(nctx));
1903 /* keep nctx.ldp */
1904 /* keep nctx.sapi */
1905 /* keep nctx.tei */
1906 nctx.cr = dl->cr.loc2rem.cmd;
1907 nctx.format = LAPD_FORM_I;
1908 nctx.p_f = 0;
1909 nctx.n_send = dl->v_send;
1910 nctx.n_recv = dl->v_recv;
1911 nctx.length = length;
1912 if (left > length)
1913 nctx.more = 1;
1914 else
1915 nctx.more = 0;
1916 if (length)
1917 memcpy(msg->l3h, dl->send_buffer->l3h + dl->send_out,
1918 length);
1919 /* store in tx_hist */
1920 dl->tx_hist[h].msg = lapd_msgb_alloc(msg->len, "HIST");
1921 msgb_put(dl->tx_hist[h].msg, msg->len);
1922 if (length)
1923 memcpy(dl->tx_hist[h].msg->data, msg->l3h, msg->len);
1924 dl->tx_hist[h].more = nctx.more;
1925 /* Add length to track how much is already in the tx buffer */
1926 dl->send_out += length;
1927 } else {
Harald Welte00b2faf2020-05-02 19:56:36 +02001928 LOGDL(dl, LOGL_INFO, "resend I frame from tx buffer V(S)=%d\n", dl->v_send);
rootaf48bed2011-09-26 11:23:06 +02001929
1930 /* Create I frame (segment) from tx_hist */
1931 length = dl->tx_hist[h].msg->len;
1932 msg = lapd_msgb_alloc(length, "LAPD I resend");
1933 msg->l3h = msgb_put(msg, length);
1934 /* assemble message */
1935 memcpy(&nctx, &dl->lctx, sizeof(nctx));
1936 /* keep nctx.ldp */
1937 /* keep nctx.sapi */
1938 /* keep nctx.tei */
1939 nctx.cr = dl->cr.loc2rem.cmd;
1940 nctx.format = LAPD_FORM_I;
1941 nctx.p_f = 0;
1942 nctx.n_send = dl->v_send;
1943 nctx.n_recv = dl->v_recv;
1944 nctx.length = length;
1945 nctx.more = dl->tx_hist[h].more;
1946 if (length)
1947 memcpy(msg->l3h, dl->tx_hist[h].msg->data, length);
1948 }
1949
1950 /* The value of the send state variable V(S) shall be incremented by 1
1951 * at the end of the transmission of the I frame */
1952 dl->v_send = inc_mod(dl->v_send, dl->v_range);
1953
1954 /* If timer T200 is not running at the time right before transmitting a
1955 * frame, when the PH-READY-TO-SEND primitive is received from the
1956 * physical layer., it shall be set. */
1957 if (!osmo_timer_pending(&dl->t200)) {
Andreas Eversberg742fc792011-09-27 09:40:25 +02001958 /* stop Timer T203, if running */
1959 lapd_stop_t203(dl);
1960 /* start Timer T200 */
1961 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001962 }
1963
1964 dl->send_ph_data_req(&nctx, msg);
1965
1966 rc = 0; /* we sent something */
1967 goto next_frame;
1968}
1969
1970/* request link suspension */
1971static int lapd_susp_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1972{
1973 struct lapd_datalink *dl = lctx->dl;
1974 struct msgb *msg = dp->oph.msg;
1975
Harald Welte00b2faf2020-05-02 19:56:36 +02001976 LOGDL(dl, LOGL_INFO, "perform suspension\n");
rootaf48bed2011-09-26 11:23:06 +02001977
1978 /* put back the send-buffer to the send-queue (first position) */
1979 if (dl->send_buffer) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001980 LOGDL(dl, LOGL_INFO, "put frame in sendbuffer back to queue\n");
rootaf48bed2011-09-26 11:23:06 +02001981 llist_add(&dl->send_buffer->list, &dl->send_queue);
1982 dl->send_buffer = NULL;
1983 } else
Harald Welte00b2faf2020-05-02 19:56:36 +02001984 LOGDL(dl, LOGL_INFO, "no frame in sendbuffer\n");
rootaf48bed2011-09-26 11:23:06 +02001985
1986 /* Clear transmit buffer, but keep send buffer */
1987 lapd_dl_flush_tx(dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001988 /* Stop timers (there is no state change, so we must stop all timers */
1989 lapd_stop_t200(dl);
1990 lapd_stop_t203(dl);
rootaf48bed2011-09-26 11:23:06 +02001991
1992 msgb_free(msg);
1993
1994 return send_dl_simple(PRIM_DL_SUSP, PRIM_OP_CONFIRM, &dl->lctx);
1995}
1996
Neels Hofmeyr9e57a5a2015-12-21 11:20:14 +01001997/* request, resume or reconnect of link */
rootaf48bed2011-09-26 11:23:06 +02001998static int lapd_res_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1999{
2000 struct lapd_datalink *dl = lctx->dl;
2001 struct msgb *msg = dp->oph.msg;
2002 struct lapd_msg_ctx nctx;
2003
Harald Welte00b2faf2020-05-02 19:56:36 +02002004 LOGDL(dl, LOGL_INFO, "perform re-establishment (SABM) length=%d\n", msg->len);
Pau Espin Pedrola99e1102017-12-08 14:30:47 +01002005
rootaf48bed2011-09-26 11:23:06 +02002006 /* be sure that history is empty */
2007 lapd_dl_flush_hist(dl);
2008
2009 /* save message context for further use */
2010 memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
2011
2012 /* Replace message in the send-buffer (reconnect) */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +02002013 msgb_free(dl->send_buffer);
2014 dl->send_buffer = NULL;
2015
rootaf48bed2011-09-26 11:23:06 +02002016 dl->send_out = 0;
Andreas Eversbergcad54b82013-07-09 20:25:24 +02002017 if (msg->len) {
rootaf48bed2011-09-26 11:23:06 +02002018 /* Write data into the send buffer, to be sent first */
2019 dl->send_buffer = msg;
Andreas Eversbergcad54b82013-07-09 20:25:24 +02002020 } else {
2021 msgb_free(msg);
2022 msg = NULL;
Andreas Eversberg5ad4ac82011-11-01 09:40:21 +01002023 dl->send_buffer = NULL;
Andreas Eversbergcad54b82013-07-09 20:25:24 +02002024 }
rootaf48bed2011-09-26 11:23:06 +02002025
2026 /* Discard partly received L3 message */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +02002027 msgb_free(dl->rcv_buffer);
2028 dl->rcv_buffer = NULL;
rootaf48bed2011-09-26 11:23:06 +02002029
2030 /* Create new msgb (old one is now free) */
2031 msg = lapd_msgb_alloc(0, "LAPD SABM");
2032 msg->l3h = msg->data;
2033 /* assemble message */
2034 memcpy(&nctx, &dl->lctx, sizeof(nctx));
2035 /* keep nctx.ldp */
2036 /* keep nctx.sapi */
2037 /* keep nctx.tei */
2038 nctx.cr = dl->cr.loc2rem.cmd;
2039 nctx.format = LAPD_FORM_U;
2040 nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
2041 nctx.p_f = 1;
2042 nctx.length = 0;
2043 nctx.more = 0;
2044
2045 dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
2046 msgb_put(dl->tx_hist[0].msg, msg->len);
2047 if (msg->len)
2048 memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
2049 dl->tx_hist[0].more = 0;
2050 /* set Vs to 0, because it is used as index when resending SABM */
2051 dl->v_send = 0;
2052
2053 /* Set states */
2054 dl->own_busy = dl->peer_busy = 0;
2055 dl->retrans_ctr = 0;
2056 lapd_dl_newstate(dl, LAPD_STATE_SABM_SENT);
2057
2058 /* Tramsmit and start T200 */
2059 dl->send_ph_data_req(&nctx, msg);
Andreas Eversberg742fc792011-09-27 09:40:25 +02002060 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02002061
2062 return 0;
2063}
2064
2065/* requesst release of link */
2066static int lapd_rel_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
2067{
2068 struct lapd_datalink *dl = lctx->dl;
2069 struct msgb *msg = dp->oph.msg;
2070 struct lapd_msg_ctx nctx;
2071
2072 /* local release */
2073 if (dp->u.rel_req.mode) {
Harald Welte00b2faf2020-05-02 19:56:36 +02002074 LOGDL(dl, LOGL_INFO, "perform local release\n");
rootaf48bed2011-09-26 11:23:06 +02002075 msgb_free(msg);
Andreas Eversberg742fc792011-09-27 09:40:25 +02002076 /* stop Timer T200 */
2077 lapd_stop_t200(dl);
2078 /* enter idle state, T203 is stopped here, if running */
rootaf48bed2011-09-26 11:23:06 +02002079 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
2080 /* flush buffers */
2081 lapd_dl_flush_tx(dl);
2082 lapd_dl_flush_send(dl);
2083 /* send notification to L3 */
2084 return send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
2085 }
2086
2087 /* in case we are already disconnecting */
2088 if (dl->state == LAPD_STATE_DISC_SENT)
2089 return -EBUSY;
2090
2091 /* flush tx_hist */
2092 lapd_dl_flush_hist(dl);
2093
Harald Welte00b2faf2020-05-02 19:56:36 +02002094 LOGDL(dl, LOGL_INFO, "perform normal release (DISC)\n");
rootaf48bed2011-09-26 11:23:06 +02002095
2096 /* Push LAPD header on msgb */
2097 /* assemble message */
2098 memcpy(&nctx, &dl->lctx, sizeof(nctx));
2099 /* keep nctx.ldp */
2100 /* keep nctx.sapi */
2101 /* keep nctx.tei */
2102 nctx.cr = dl->cr.loc2rem.cmd;
2103 nctx.format = LAPD_FORM_U;
2104 nctx.s_u = LAPD_U_DISC;
2105 nctx.p_f = 1;
2106 nctx.length = 0;
2107 nctx.more = 0;
2108
2109 dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
2110 msgb_put(dl->tx_hist[0].msg, msg->len);
2111 if (msg->len)
2112 memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
2113 dl->tx_hist[0].more = 0;
2114 /* set Vs to 0, because it is used as index when resending DISC */
2115 dl->v_send = 0;
Pau Espin Pedrola99e1102017-12-08 14:30:47 +01002116
rootaf48bed2011-09-26 11:23:06 +02002117 /* Set states */
2118 dl->own_busy = dl->peer_busy = 0;
2119 dl->retrans_ctr = 0;
2120 lapd_dl_newstate(dl, LAPD_STATE_DISC_SENT);
2121
2122 /* Tramsmit and start T200 */
2123 dl->send_ph_data_req(&nctx, msg);
Andreas Eversberg742fc792011-09-27 09:40:25 +02002124 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02002125
2126 return 0;
2127}
2128
2129/* request release of link in idle state */
2130static int lapd_rel_req_idle(struct osmo_dlsap_prim *dp,
2131 struct lapd_msg_ctx *lctx)
2132{
2133 struct lapd_datalink *dl = lctx->dl;
2134 struct msgb *msg = dp->oph.msg;
2135
2136 msgb_free(msg);
2137
2138 /* send notification to L3 */
2139 return send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
2140}
2141
2142/* statefull handling for DL SAP messages from L3 */
Holger Hans Peter Freyther579fb092012-11-22 10:54:23 +01002143static const struct l2downstate {
rootaf48bed2011-09-26 11:23:06 +02002144 uint32_t states;
2145 int prim, op;
2146 const char *name;
2147 int (*rout) (struct osmo_dlsap_prim *dp,
2148 struct lapd_msg_ctx *lctx);
2149} l2downstatelist[] = {
2150 /* create and send UI command */
2151 {ALL_STATES,
Pau Espin Pedrola99e1102017-12-08 14:30:47 +01002152 PRIM_DL_UNIT_DATA, PRIM_OP_REQUEST,
rootaf48bed2011-09-26 11:23:06 +02002153 "DL-UNIT-DATA-REQUEST", lapd_udata_req},
2154
2155 /* create and send SABM command */
2156 {SBIT(LAPD_STATE_IDLE),
2157 PRIM_DL_EST, PRIM_OP_REQUEST,
2158 "DL-ESTABLISH-REQUEST", lapd_est_req},
2159
2160 /* create and send I command */
2161 {SBIT(LAPD_STATE_MF_EST) |
2162 SBIT(LAPD_STATE_TIMER_RECOV),
2163 PRIM_DL_DATA, PRIM_OP_REQUEST,
2164 "DL-DATA-REQUEST", lapd_data_req},
2165
2166 /* suspend datalink */
2167 {SBIT(LAPD_STATE_MF_EST) |
2168 SBIT(LAPD_STATE_TIMER_RECOV),
2169 PRIM_DL_SUSP, PRIM_OP_REQUEST,
2170 "DL-SUSPEND-REQUEST", lapd_susp_req},
2171
2172 /* create and send SABM command (resume) */
2173 {SBIT(LAPD_STATE_MF_EST) |
2174 SBIT(LAPD_STATE_TIMER_RECOV),
2175 PRIM_DL_RES, PRIM_OP_REQUEST,
2176 "DL-RESUME-REQUEST", lapd_res_req},
2177
2178 /* create and send SABM command (reconnect) */
2179 {SBIT(LAPD_STATE_IDLE) |
2180 SBIT(LAPD_STATE_MF_EST) |
2181 SBIT(LAPD_STATE_TIMER_RECOV),
2182 PRIM_DL_RECON, PRIM_OP_REQUEST,
2183 "DL-RECONNECT-REQUEST", lapd_res_req},
2184
2185 /* create and send DISC command */
2186 {SBIT(LAPD_STATE_SABM_SENT) |
2187 SBIT(LAPD_STATE_MF_EST) |
2188 SBIT(LAPD_STATE_TIMER_RECOV) |
2189 SBIT(LAPD_STATE_DISC_SENT),
2190 PRIM_DL_REL, PRIM_OP_REQUEST,
2191 "DL-RELEASE-REQUEST", lapd_rel_req},
2192
2193 /* release in idle state */
2194 {SBIT(LAPD_STATE_IDLE),
2195 PRIM_DL_REL, PRIM_OP_REQUEST,
2196 "DL-RELEASE-REQUEST", lapd_rel_req_idle},
2197};
2198
2199#define L2DOWNSLLEN \
2200 (sizeof(l2downstatelist) / sizeof(struct l2downstate))
2201
2202int lapd_recv_dlsap(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
2203{
2204 struct lapd_datalink *dl = lctx->dl;
2205 int i, supported = 0;
2206 struct msgb *msg = dp->oph.msg;
2207 int rc;
2208
2209 /* find function for current state and message */
2210 for (i = 0; i < L2DOWNSLLEN; i++) {
2211 if (dp->oph.primitive == l2downstatelist[i].prim
2212 && dp->oph.operation == l2downstatelist[i].op) {
2213 supported = 1;
2214 if ((SBIT(dl->state) & l2downstatelist[i].states))
2215 break;
2216 }
2217 }
2218 if (!supported) {
Harald Welte00b2faf2020-05-02 19:56:36 +02002219 LOGDL(dl, LOGL_NOTICE, "Message %u/%u unsupported\n",
2220 dp->oph.primitive, dp->oph.operation);
rootaf48bed2011-09-26 11:23:06 +02002221 msgb_free(msg);
2222 return 0;
2223 }
2224 if (i == L2DOWNSLLEN) {
Harald Welte00b2faf2020-05-02 19:56:36 +02002225 LOGDL(dl, LOGL_NOTICE, "Message %u/%u unhandled at this state %s\n",
2226 dp->oph.primitive, dp->oph.operation, lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02002227 msgb_free(msg);
2228 return 0;
2229 }
2230
Harald Welte00b2faf2020-05-02 19:56:36 +02002231 LOGDL(dl, LOGL_INFO, "Message %s received in state %s\n",
2232 l2downstatelist[i].name, lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02002233
2234 rc = l2downstatelist[i].rout(dp, lctx);
2235
2236 return rc;
2237}
2238
Katerina Barone-Adesic28c6a02013-02-15 13:27:59 +01002239/*! @} */