blob: ed0b32098124476efdd1cfb95b21a1cce0b780b7 [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);
Philipp Maier6b986c22017-02-01 12:00:45 +0100627 /* send RELEASE INDICATION to L3 */
628 send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
rootaf48bed2011-09-26 11:23:06 +0200629 /* flush tx and send buffers */
630 lapd_dl_flush_tx(dl);
631 lapd_dl_flush_send(dl);
632 /* go back to idle state */
633 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
634 /* NOTE: we must not change any other states or buffers
635 * and queues, since we may reconnect after handover
636 * failure. the buffered messages is replaced there */
637 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");
1233 rc = send_dl_simple(PRIM_DL_REL,
1234 PRIM_OP_INDICATION, lctx);
1235 msgb_free(msg);
1236 /* go to idle state */
1237 lapd_dl_flush_tx(dl);
1238 lapd_dl_flush_send(dl);
1239 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1240 return 0;
1241 }
1242 }
1243 /* set Vs, Vr and Va to 0 */
1244 dl->v_send = dl->v_recv = dl->v_ack = 0;
1245 /* clear tx_hist */
1246 lapd_dl_flush_hist(dl);
1247 /* enter multiple-frame-established state */
1248 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1249 /* send outstanding frames, if any (resume / reconnect) */
1250 lapd_send_i(lctx, __LINE__);
1251 /* send notification to L3 */
1252 rc = send_dl_simple(PRIM_DL_EST, PRIM_OP_CONFIRM, lctx);
1253 msgb_free(msg);
1254 return rc;
1255}
1256
1257/* Receive a LAPD U FRMR message from L1 */
1258static int lapd_rx_u_frmr(struct msgb *msg, struct lapd_msg_ctx *lctx)
1259{
1260 struct lapd_datalink *dl = lctx->dl;
1261
1262 LOGDL(dl, LOGL_NOTICE, "Frame reject received\n");
1263 /* send MDL ERROR INIDCATION to L3 */
1264 mdl_error(MDL_CAUSE_FRMR, lctx);
1265 msgb_free(msg);
1266 /* reestablish */
1267 if (!dl->reestablish)
1268 return 0;
1269 LOGDL(dl, LOGL_NOTICE, "Performing reestablishment\n");
1270 return lapd_reestablish(dl);
1271}
1272
1273/* Receive a LAPD U (Unnumbered) message from L1 */
1274static int lapd_rx_u(struct msgb *msg, struct lapd_msg_ctx *lctx)
1275{
1276 switch (lctx->s_u) {
1277 case LAPD_U_SABM:
1278 case LAPD_U_SABME:
1279 return lapd_rx_u_sabm(msg, lctx);
1280 case LAPD_U_DM:
1281 return lapd_rx_u_dm(msg, lctx);
1282 case LAPD_U_UI:
1283 return lapd_rx_u_ui(msg, lctx);
1284 case LAPD_U_DISC:
1285 return lapd_rx_u_disc(msg, lctx);
1286 case LAPD_U_UA:
1287 return lapd_rx_u_ua(msg, lctx);
1288 case LAPD_U_FRMR:
1289 return lapd_rx_u_frmr(msg, lctx);
1290 default:
1291 /* G.3.1 */
1292 LOGDL(lctx->dl, LOGL_NOTICE, "Unnumbered frame not allowed\n");
1293 msgb_free(msg);
1294 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1295 return -EINVAL;
1296 }
1297}
1298
rootaf48bed2011-09-26 11:23:06 +02001299/* Receive a LAPD S (Supervisory) message from L1 */
1300static int lapd_rx_s(struct msgb *msg, struct lapd_msg_ctx *lctx)
1301{
1302 struct lapd_datalink *dl = lctx->dl;
1303 int length = lctx->length;
1304
1305 if (length > 0 || lctx->more) {
1306 /* G.4.3 If a supervisory frame is received with L>0 or
1307 * with the M bit set to "1", an MDL-ERROR-INDICATION
1308 * primitive with cause "S frame with incorrect
1309 * parameters" is sent to the mobile management entity. */
Harald Welte00b2faf2020-05-02 19:56:36 +02001310 LOGDL(dl, LOGL_ERROR, "S frame with incorrect parameters\n");
rootaf48bed2011-09-26 11:23:06 +02001311 msgb_free(msg);
1312 mdl_error(MDL_CAUSE_SFRM_INC_PARAM, lctx);
1313 return -EIO;
1314 }
1315
1316 if (lctx->cr == dl->cr.rem2loc.resp
1317 && lctx->p_f
1318 && dl->state != LAPD_STATE_TIMER_RECOV) {
1319 /* 5.4.2.2: Inidcate error on supervisory reponse F=1 */
Harald Welte00b2faf2020-05-02 19:56:36 +02001320 LOGDL(dl, LOGL_NOTICE, "S frame response with F=1 error\n");
rootaf48bed2011-09-26 11:23:06 +02001321 mdl_error(MDL_CAUSE_UNSOL_SPRV_RESP, lctx);
1322 }
1323
1324 switch (dl->state) {
1325 case LAPD_STATE_IDLE:
1326 /* if P=1, respond DM with F=1 (5.2.2) */
1327 /* 5.4.5 all other frame types shall be discarded */
1328 if (lctx->p_f)
1329 lapd_send_dm(lctx); /* F=P */
1330 /* fall though */
1331 case LAPD_STATE_SABM_SENT:
1332 case LAPD_STATE_DISC_SENT:
Harald Welte00b2faf2020-05-02 19:56:36 +02001333 LOGDL(dl, LOGL_NOTICE, "S frame ignored in this state\n");
rootaf48bed2011-09-26 11:23:06 +02001334 msgb_free(msg);
1335 return 0;
1336 }
1337 switch (lctx->s_u) {
1338 case LAPD_S_RR:
Harald Welte00b2faf2020-05-02 19:56:36 +02001339 LOGDL(dl, LOGL_INFO, "RR received in state %s\n", lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001340 /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
1341 lapd_acknowledge(lctx);
1342
1343 /* 5.5.3.2 */
1344 if (lctx->cr == dl->cr.rem2loc.cmd
1345 && lctx->p_f) {
1346 if (!dl->own_busy && !dl->seq_err_cond) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001347 LOGDL(dl, LOGL_INFO, "RR frame command with polling bit set and "
1348 "we are not busy, so we reply with RR frame response\n");
rootaf48bed2011-09-26 11:23:06 +02001349 lapd_send_rr(lctx, 1, 0);
1350 /* NOTE: In case of sequence error condition,
1351 * the REJ frame has been transmitted when
1352 * entering the condition, so it has not be
1353 * done here
1354 */
1355 } else if (dl->own_busy) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001356 LOGDL(dl, LOGL_INFO, "RR frame command with polling bit set and "
1357 "we are busy, so we reply with RR frame response\n");
rootaf48bed2011-09-26 11:23:06 +02001358 lapd_send_rnr(lctx, 1, 0);
1359 }
1360 } else if (lctx->cr == dl->cr.rem2loc.resp
1361 && lctx->p_f
1362 && dl->state == LAPD_STATE_TIMER_RECOV) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001363 LOGDL(dl, LOGL_INFO, "RR response with F==1, and we are in timer recovery "
1364 "state, so we leave that state\n");
rootaf48bed2011-09-26 11:23:06 +02001365 /* V(S) to the N(R) in the RR frame */
1366 dl->v_send = lctx->n_recv;
Andreas Eversberg742fc792011-09-27 09:40:25 +02001367 /* stop Timer T200 */
1368 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001369 /* 5.5.7 Clear timer recovery condition */
1370 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1371 }
1372 /* Send message, if possible due to acknowledged data */
1373 lapd_send_i(lctx, __LINE__);
1374
1375 break;
1376 case LAPD_S_RNR:
Harald Welte00b2faf2020-05-02 19:56:36 +02001377 LOGDL(dl, LOGL_INFO, "RNR received in state %s\n", lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001378 /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
1379 lapd_acknowledge(lctx);
1380
1381 /* 5.5.5 */
1382 /* Set peer receiver busy condition */
1383 dl->peer_busy = 1;
1384
1385 if (lctx->p_f) {
1386 if (lctx->cr == dl->cr.rem2loc.cmd) {
1387 if (!dl->own_busy) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001388 LOGDL(dl, LOGL_INFO, "RNR poll command and we are not busy, "
1389 "so we reply with RR final response\n");
rootaf48bed2011-09-26 11:23:06 +02001390 /* Send RR with F=1 */
1391 lapd_send_rr(lctx, 1, 0);
1392 } else {
Harald Welte00b2faf2020-05-02 19:56:36 +02001393 LOGDL(dl, LOGL_INFO, "RNR poll command and we are busy, so "
1394 "we reply with RNR final response\n");
rootaf48bed2011-09-26 11:23:06 +02001395 /* Send RNR with F=1 */
1396 lapd_send_rnr(lctx, 1, 0);
1397 }
1398 } else if (dl->state == LAPD_STATE_TIMER_RECOV) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001399 LOGDL(dl, LOGL_INFO, "RNR poll response and we in timer recovery "
1400 "state, so we leave that state\n");
rootaf48bed2011-09-26 11:23:06 +02001401 /* 5.5.7 Clear timer recovery condition */
1402 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1403 /* V(S) to the N(R) in the RNR frame */
1404 dl->v_send = lctx->n_recv;
1405 }
1406 } else
Harald Welte00b2faf2020-05-02 19:56:36 +02001407 LOGDL(dl, LOGL_INFO, "RNR not polling/final state received\n");
rootaf48bed2011-09-26 11:23:06 +02001408
1409 /* Send message, if possible due to acknowledged data */
1410 lapd_send_i(lctx, __LINE__);
1411
1412 break;
1413 case LAPD_S_REJ:
Harald Welte00b2faf2020-05-02 19:56:36 +02001414 LOGDL(dl, LOGL_INFO, "REJ received in state %s\n", lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001415 /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
1416 lapd_acknowledge(lctx);
1417
1418 /* 5.5.4.1 */
1419 if (dl->state != LAPD_STATE_TIMER_RECOV) {
1420 /* Clear an existing peer receiver busy condition */
1421 dl->peer_busy = 0;
1422 /* V(S) and V(A) to the N(R) in the REJ frame */
1423 dl->v_send = dl->v_ack = lctx->n_recv;
Andreas Eversberg742fc792011-09-27 09:40:25 +02001424 /* stop Timer T200 */
1425 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001426 /* 5.5.3.2 */
1427 if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
1428 if (!dl->own_busy && !dl->seq_err_cond) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001429 LOGDL(dl, LOGL_INFO, "REJ poll command not in timer recovery "
1430 "state and not in own busy condition received, so we "
1431 "respond with RR final response\n");
rootaf48bed2011-09-26 11:23:06 +02001432 lapd_send_rr(lctx, 1, 0);
1433 /* NOTE: In case of sequence error
1434 * condition, the REJ frame has been
1435 * transmitted when entering the
1436 * condition, so it has not be done
1437 * here
1438 */
1439 } else if (dl->own_busy) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001440 LOGDL(dl, LOGL_INFO, "REJ poll command not in timer recovery "
1441 "state and in own busy condition received, so we "
1442 "respond with RNR final response\n");
rootaf48bed2011-09-26 11:23:06 +02001443 lapd_send_rnr(lctx, 1, 0);
1444 }
1445 } else
Harald Welte00b2faf2020-05-02 19:56:36 +02001446 LOGDL(dl, LOGL_INFO, "REJ response or not polling command not "
1447 "in timer recovery state received\n");
rootaf48bed2011-09-26 11:23:06 +02001448 /* send MDL ERROR INIDCATION to L3 */
1449 if (lctx->cr == dl->cr.rem2loc.resp && lctx->p_f) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001450 LOGDL(dl, LOGL_ERROR, "unsolicited supervisory response!\n");
rootaf48bed2011-09-26 11:23:06 +02001451 mdl_error(MDL_CAUSE_UNSOL_SPRV_RESP, lctx);
1452 }
1453
1454 } else if (lctx->cr == dl->cr.rem2loc.resp && lctx->p_f) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001455 LOGDL(dl, LOGL_INFO, "REJ poll response in timer recovery state received\n");
rootaf48bed2011-09-26 11:23:06 +02001456 /* Clear an existing peer receiver busy condition */
1457 dl->peer_busy = 0;
1458 /* V(S) and V(A) to the N(R) in the REJ frame */
1459 dl->v_send = dl->v_ack = lctx->n_recv;
Andreas Eversberg742fc792011-09-27 09:40:25 +02001460 /* stop Timer T200 */
1461 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001462 /* 5.5.7 Clear timer recovery condition */
1463 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1464 } else {
1465 /* Clear an existing peer receiver busy condition */
1466 dl->peer_busy = 0;
1467 /* V(S) and V(A) to the N(R) in the REJ frame */
1468 dl->v_send = dl->v_ack = lctx->n_recv;
1469 /* 5.5.3.2 */
1470 if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
1471 if (!dl->own_busy && !dl->seq_err_cond) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001472 LOGDL(dl, LOGL_INFO, "REJ poll command in timer recovery "
1473 "state and not in own busy condition received, so we "
1474 "respond with RR final response\n");
rootaf48bed2011-09-26 11:23:06 +02001475 lapd_send_rr(lctx, 1, 0);
1476 /* NOTE: In case of sequence error
1477 * condition, the REJ frame has been
1478 * transmitted when entering the
1479 * condition, so it has not be done
1480 * here
1481 */
1482 } else if (dl->own_busy) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001483 LOGDL(dl, LOGL_INFO, "REJ poll command in timer recovery "
1484 "state and in own busy condition received, so we "
1485 "respond with RNR final response\n");
rootaf48bed2011-09-26 11:23:06 +02001486 lapd_send_rnr(lctx, 1, 0);
1487 }
1488 } else
Harald Welte00b2faf2020-05-02 19:56:36 +02001489 LOGDL(dl, LOGL_INFO, "REJ response or not polling command in "
1490 "timer recovery state received\n");
rootaf48bed2011-09-26 11:23:06 +02001491 }
1492
1493 /* FIXME: 5.5.4.2 2) */
1494
1495 /* Send message, if possible due to acknowledged data */
1496 lapd_send_i(lctx, __LINE__);
1497
1498 break;
1499 default:
1500 /* G.3.1 */
Harald Welte00b2faf2020-05-02 19:56:36 +02001501 LOGDL(dl, LOGL_ERROR, "Supervisory frame not allowed\n");
rootaf48bed2011-09-26 11:23:06 +02001502 msgb_free(msg);
1503 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1504 return -EINVAL;
1505 }
1506 msgb_free(msg);
1507 return 0;
1508}
1509
1510/* Receive a LAPD I (Information) message from L1 */
1511static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx)
1512{
1513 struct lapd_datalink *dl = lctx->dl;
1514 //uint8_t nr = lctx->n_recv;
1515 uint8_t ns = lctx->n_send;
1516 int length = lctx->length;
1517 int rc;
1518
Harald Welte00b2faf2020-05-02 19:56:36 +02001519 LOGDL(dl, LOGL_INFO, "I received in state %s on SAPI(%u)\n",
1520 lapd_state_name(dl->state), lctx->sapi);
Pau Espin Pedrola99e1102017-12-08 14:30:47 +01001521
rootaf48bed2011-09-26 11:23:06 +02001522 /* G.2.2 Wrong value of the C/R bit */
1523 if (lctx->cr == dl->cr.rem2loc.resp) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001524 LOGDL(dl, LOGL_ERROR, "I frame response not allowed (state %s)\n",
1525 lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001526 msgb_free(msg);
1527 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1528 return -EINVAL;
1529 }
1530
1531 if (length == 0 || length > lctx->n201) {
1532 /* G.4.2 If the length indicator of an I frame is set
1533 * to a numerical value L>N201 or L=0, an MDL-ERROR-INDICATION
1534 * primitive with cause "I frame with incorrect length"
1535 * is sent to the mobile management entity. */
Harald Welte00b2faf2020-05-02 19:56:36 +02001536 LOGDL(dl, LOGL_ERROR, "I frame length not allowed (state %s)\n",
1537 lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001538 msgb_free(msg);
1539 mdl_error(MDL_CAUSE_IFRM_INC_LEN, lctx);
1540 return -EIO;
1541 }
1542
1543 /* G.4.2 If the numerical value of L is L<N201 and the M
1544 * bit is set to "1", then an MDL-ERROR-INDICATION primitive with
1545 * cause "I frame with incorrect use of M bit" is sent to the
1546 * mobile management entity. */
1547 if (lctx->more && length < lctx->n201) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001548 LOGDL(dl, LOGL_ERROR, "I frame with M bit too short (state %s)\n",
1549 lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001550 msgb_free(msg);
1551 mdl_error(MDL_CAUSE_IFRM_INC_MBITS, lctx);
1552 return -EIO;
1553 }
1554
1555 switch (dl->state) {
1556 case LAPD_STATE_IDLE:
1557 /* if P=1, respond DM with F=1 (5.2.2) */
1558 /* 5.4.5 all other frame types shall be discarded */
1559 if (lctx->p_f)
1560 lapd_send_dm(lctx); /* F=P */
1561 /* fall though */
1562 case LAPD_STATE_SABM_SENT:
1563 case LAPD_STATE_DISC_SENT:
Harald Welte00b2faf2020-05-02 19:56:36 +02001564 LOGDL(dl, LOGL_NOTICE, "I frame ignored in state %s\n", lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001565 msgb_free(msg);
1566 return 0;
1567 }
1568
1569 /* 5.7.1: N(s) sequence error */
1570 if (ns != dl->v_recv) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001571 LOGDL(dl, LOGL_NOTICE, "N(S) sequence error: N(S)=%u, V(R)=%u (state %s)\n",
1572 ns, dl->v_recv, lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02001573 /* discard data */
1574 msgb_free(msg);
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001575 if (dl->seq_err_cond != 1) {
rootaf48bed2011-09-26 11:23:06 +02001576 /* FIXME: help me understand what exactly todo here
rootaf48bed2011-09-26 11:23:06 +02001577 */
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001578 dl->seq_err_cond = 1;
rootaf48bed2011-09-26 11:23:06 +02001579 lapd_send_rej(lctx, lctx->p_f);
1580 } else {
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001581 /* If there are two subsequent sequence errors received,
1582 * ignore it. (Ignore every second subsequent error.)
1583 * This happens if our reply with the REJ is too slow,
1584 * so the remote gets a T200 timeout and sends another
1585 * frame with a sequence error.
1586 * Test showed that replying with two subsequent REJ
1587 * messages could the remote L2 process to abort.
1588 * Replying too slow shouldn't happen, but may happen
1589 * over serial link between BB and LAPD.
1590 */
1591 dl->seq_err_cond = 2;
rootaf48bed2011-09-26 11:23:06 +02001592 }
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001593 /* Even if N(s) sequence error, acknowledge to N(R)-1 */
1594 /* 5.5.3.1: Acknowlege all transmitted frames up the N(R)-1 */
1595 lapd_acknowledge(lctx); /* V(A) is also set here */
1596
1597 /* Send message, if possible due to acknowledged data */
1598 lapd_send_i(lctx, __LINE__);
1599
1600 return 0;
rootaf48bed2011-09-26 11:23:06 +02001601 }
1602 dl->seq_err_cond = 0;
1603
1604 /* Increment receiver state */
1605 dl->v_recv = inc_mod(dl->v_recv, dl->v_range);
Harald Welte00b2faf2020-05-02 19:56:36 +02001606 LOGDL(dl, LOGL_INFO, "incrementing V(R) to %u\n", dl->v_recv);
rootaf48bed2011-09-26 11:23:06 +02001607
1608 /* 5.5.3.1: Acknowlege all transmitted frames up the the N(R)-1 */
1609 lapd_acknowledge(lctx); /* V(A) is also set here */
1610
1611 /* Only if we are not in own receiver busy condition */
1612 if (!dl->own_busy) {
1613 /* if the frame carries a complete segment */
1614 if (!lctx->more && !dl->rcv_buffer) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001615 LOGDL(dl, LOGL_INFO, "message in single I frame\n");
rootaf48bed2011-09-26 11:23:06 +02001616 /* send a DATA INDICATION to L3 */
Harald Welte087116a2013-06-18 21:41:34 +02001617 msgb_trim(msg, length);
rootaf48bed2011-09-26 11:23:06 +02001618 rc = send_dl_l3(PRIM_DL_DATA, PRIM_OP_INDICATION, lctx,
1619 msg);
1620 } else {
1621 /* create rcv_buffer */
1622 if (!dl->rcv_buffer) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001623 LOGDL(dl, LOGL_INFO, "message in multiple I frames (first message)\n");
rootaf48bed2011-09-26 11:23:06 +02001624 dl->rcv_buffer = lapd_msgb_alloc(dl->maxf,
1625 "LAPD RX");
1626 dl->rcv_buffer->l3h = dl->rcv_buffer->data;
1627 }
1628 /* concat. rcv_buffer */
1629 if (msgb_l3len(dl->rcv_buffer) + length > dl->maxf) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001630 LOGDL(dl, LOGL_NOTICE, "Received frame overflow!\n");
rootaf48bed2011-09-26 11:23:06 +02001631 } else {
1632 memcpy(msgb_put(dl->rcv_buffer, length),
1633 msg->l3h, length);
1634 }
1635 /* if the last segment was received */
1636 if (!lctx->more) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001637 LOGDL(dl, LOGL_INFO, "message in multiple I frames (last message)\n");
rootaf48bed2011-09-26 11:23:06 +02001638 rc = send_dl_l3(PRIM_DL_DATA,
1639 PRIM_OP_INDICATION, lctx,
1640 dl->rcv_buffer);
1641 dl->rcv_buffer = NULL;
1642 } else
Harald Welte00b2faf2020-05-02 19:56:36 +02001643 LOGDL(dl, LOGL_INFO, "message in multiple I frames (next message)\n");
rootaf48bed2011-09-26 11:23:06 +02001644 msgb_free(msg);
1645
1646 }
Harald Weltebc1d7152020-07-04 10:52:13 +02001647 /* the L3 or higher (called in-line above via send_dl_l3) might have destroyed the
1648 * data link meanwhile. See OS#1761 */
1649 if (dl->state == LAPD_STATE_NULL)
1650 return 0;
rootaf48bed2011-09-26 11:23:06 +02001651 } else
Harald Welte00b2faf2020-05-02 19:56:36 +02001652 LOGDL(dl, LOGL_INFO, "I frame ignored during own receiver busy condition\n");
rootaf48bed2011-09-26 11:23:06 +02001653
1654 /* Check for P bit */
1655 if (lctx->p_f) {
1656 /* 5.5.2.1 */
1657 /* check if we are not in own receiver busy */
1658 if (!dl->own_busy) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001659 LOGDL(dl, LOGL_INFO, "we are not busy, send RR\n");
rootaf48bed2011-09-26 11:23:06 +02001660 /* Send RR with F=1 */
1661 rc = lapd_send_rr(lctx, 1, 0);
1662 } else {
Harald Welte00b2faf2020-05-02 19:56:36 +02001663 LOGDL(dl, LOGL_INFO, "we are busy, send RNR\n");
rootaf48bed2011-09-26 11:23:06 +02001664 /* Send RNR with F=1 */
1665 rc = lapd_send_rnr(lctx, 1, 0);
1666 }
1667 } else {
1668 /* 5.5.2.2 */
1669 /* check if we are not in own receiver busy */
1670 if (!dl->own_busy) {
1671 /* NOTE: V(R) is already set above */
1672 rc = lapd_send_i(lctx, __LINE__);
Daniel Willmann3dc4e162014-03-20 19:24:48 +01001673
1674 /* if update_pending_iframe returns 0 it updated
1675 * the lapd header of an iframe in the tx queue */
1676 if (rc && dl->update_pending_frames)
1677 rc = dl->update_pending_frames(lctx);
1678
rootaf48bed2011-09-26 11:23:06 +02001679 if (rc) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001680 LOGDL(dl, LOGL_INFO, "we are not busy and have no pending data, "
1681 "send RR\n");
rootaf48bed2011-09-26 11:23:06 +02001682 /* Send RR with F=0 */
1683 return lapd_send_rr(lctx, 0, 0);
1684 }
1685 /* all I or one RR is sent, we are done */
1686 return 0;
1687 } else {
Harald Welte00b2faf2020-05-02 19:56:36 +02001688 LOGDL(dl, LOGL_INFO, "we are busy, send RNR\n");
rootaf48bed2011-09-26 11:23:06 +02001689 /* Send RNR with F=0 */
1690 rc = lapd_send_rnr(lctx, 0, 0);
1691 }
1692 }
1693
1694 /* Send message, if possible due to acknowledged data */
1695 lapd_send_i(lctx, __LINE__);
1696
1697 return rc;
1698}
1699
1700/* Receive a LAPD message from L1 */
1701int lapd_ph_data_ind(struct msgb *msg, struct lapd_msg_ctx *lctx)
1702{
1703 int rc;
1704
1705 switch (lctx->format) {
1706 case LAPD_FORM_U:
1707 rc = lapd_rx_u(msg, lctx);
1708 break;
1709 case LAPD_FORM_S:
1710 rc = lapd_rx_s(msg, lctx);
1711 break;
1712 case LAPD_FORM_I:
1713 rc = lapd_rx_i(msg, lctx);
1714 break;
1715 default:
Harald Welte00b2faf2020-05-02 19:56:36 +02001716 LOGDL(lctx->dl, LOGL_NOTICE, "unknown LAPD format\n");
rootaf48bed2011-09-26 11:23:06 +02001717 msgb_free(msg);
1718 rc = -EINVAL;
1719 }
1720 return rc;
1721}
1722
1723/* L3 -> L2 */
1724
1725/* send unit data */
1726static int lapd_udata_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1727{
1728 struct lapd_datalink *dl = lctx->dl;
1729 struct msgb *msg = dp->oph.msg;
1730 struct lapd_msg_ctx nctx;
1731
1732 memcpy(&nctx, lctx, sizeof(nctx));
1733 /* keep nctx.ldp */
1734 /* keep nctx.sapi */
1735 /* keep nctx.tei */
1736 nctx.cr = dl->cr.loc2rem.cmd;
1737 nctx.format = LAPD_FORM_U;
1738 nctx.s_u = LAPD_U_UI;
1739 /* keep nctx.p_f */
1740 nctx.length = msg->len;
1741 nctx.more = 0;
1742
1743 return dl->send_ph_data_req(&nctx, msg);
1744}
1745
1746/* request link establishment */
1747static int lapd_est_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1748{
1749 struct lapd_datalink *dl = lctx->dl;
1750 struct msgb *msg = dp->oph.msg;
1751 struct lapd_msg_ctx nctx;
1752
1753 if (msg->len)
Harald Welte00b2faf2020-05-02 19:56:36 +02001754 LOGDL(dl, LOGL_INFO, "perform establishment with content (SABM)\n");
rootaf48bed2011-09-26 11:23:06 +02001755 else
Harald Welte00b2faf2020-05-02 19:56:36 +02001756 LOGDL(dl, LOGL_INFO, "perform normal establishm. (SABM)\n");
rootaf48bed2011-09-26 11:23:06 +02001757
1758 /* Flush send-queue */
1759 /* Clear send-buffer */
1760 lapd_dl_flush_send(dl);
1761 /* be sure that history is empty */
1762 lapd_dl_flush_hist(dl);
1763
1764 /* save message context for further use */
1765 memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
1766
1767 /* Discard partly received L3 message */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +02001768 msgb_free(dl->rcv_buffer);
1769 dl->rcv_buffer = NULL;
rootaf48bed2011-09-26 11:23:06 +02001770
1771 /* assemble message */
1772 memcpy(&nctx, &dl->lctx, sizeof(nctx));
1773 /* keep nctx.ldp */
1774 /* keep nctx.sapi */
1775 /* keep nctx.tei */
1776 nctx.cr = dl->cr.loc2rem.cmd;
1777 nctx.format = LAPD_FORM_U;
1778 nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
1779 nctx.p_f = 1;
1780 nctx.length = msg->len;
1781 nctx.more = 0;
1782
1783 /* Transmit-buffer carries exactly one segment */
1784 dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
1785 msgb_put(dl->tx_hist[0].msg, msg->len);
1786 if (msg->len)
1787 memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
1788 dl->tx_hist[0].more = 0;
1789 /* set Vs to 0, because it is used as index when resending SABM */
1790 dl->v_send = 0;
Pau Espin Pedrola99e1102017-12-08 14:30:47 +01001791
rootaf48bed2011-09-26 11:23:06 +02001792 /* Set states */
1793 dl->own_busy = dl->peer_busy = 0;
1794 dl->retrans_ctr = 0;
1795 lapd_dl_newstate(dl, LAPD_STATE_SABM_SENT);
1796
1797 /* Tramsmit and start T200 */
1798 dl->send_ph_data_req(&nctx, msg);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001799 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001800
1801 return 0;
1802}
1803
1804/* send data */
1805static int lapd_data_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1806{
1807 struct lapd_datalink *dl = lctx->dl;
1808 struct msgb *msg = dp->oph.msg;
1809
Holger Hans Peter Freyther90656db2012-01-13 05:49:29 +08001810 if (msgb_l3len(msg) == 0) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001811 LOGDL(dl, LOGL_ERROR, "writing an empty message is not possible\n");
Holger Hans Peter Freyther90656db2012-01-13 05:49:29 +08001812 msgb_free(msg);
1813 return -1;
1814 }
1815
Harald Welte00b2faf2020-05-02 19:56:36 +02001816 LOGDL(dl, LOGL_INFO, "writing message to send-queue: l3len: %d\n", msgb_l3len(msg));
rootaf48bed2011-09-26 11:23:06 +02001817
1818 /* Write data into the send queue */
1819 msgb_enqueue(&dl->send_queue, msg);
1820
1821 /* Send message, if possible */
1822 lapd_send_i(&dl->lctx, __LINE__);
1823
1824 return 0;
1825}
1826
1827/* Send next I frame from queued/buffered data */
1828static int lapd_send_i(struct lapd_msg_ctx *lctx, int line)
1829{
1830 struct lapd_datalink *dl = lctx->dl;
1831 uint8_t k = dl->k;
1832 uint8_t h;
1833 struct msgb *msg;
1834 int length, left;
1835 int rc = - 1; /* we sent nothing */
1836 struct lapd_msg_ctx nctx;
1837
1838
Harald Welte00b2faf2020-05-02 19:56:36 +02001839 LOGDL(dl, LOGL_INFO, "%s() called from line %d\n", __func__, line);
rootaf48bed2011-09-26 11:23:06 +02001840
1841 next_frame:
1842
1843 if (dl->peer_busy) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001844 LOGDL(dl, LOGL_INFO, "peer busy, not sending\n");
rootaf48bed2011-09-26 11:23:06 +02001845 return rc;
1846 }
1847
1848 if (dl->state == LAPD_STATE_TIMER_RECOV) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001849 LOGDL(dl, LOGL_INFO, "timer recovery, not sending\n");
rootaf48bed2011-09-26 11:23:06 +02001850 return rc;
1851 }
1852
1853 /* If the send state variable V(S) is equal to V(A) plus k
1854 * (where k is the maximum number of outstanding I frames - see
1855 * subclause 5.8.4), the data link layer entity shall not transmit any
1856 * new I frames, but shall retransmit an I frame as a result
1857 * of the error recovery procedures as described in subclauses 5.5.4 and
1858 * 5.5.7. */
1859 if (dl->v_send == add_mod(dl->v_ack, k, dl->v_range)) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001860 LOGDL(dl, LOGL_INFO, "k frames outstanding, not sending more "
1861 "(k=%u V(S)=%u V(A)=%u)\n", k, dl->v_send, dl->v_ack);
rootaf48bed2011-09-26 11:23:06 +02001862 return rc;
1863 }
1864
1865 h = do_mod(dl->v_send, dl->range_hist);
1866
1867 /* if we have no tx_hist yet, we create it */
1868 if (!dl->tx_hist[h].msg) {
1869 /* Get next message into send-buffer, if any */
1870 if (!dl->send_buffer) {
1871 next_message:
1872 dl->send_out = 0;
1873 dl->send_buffer = msgb_dequeue(&dl->send_queue);
1874 /* No more data to be sent */
1875 if (!dl->send_buffer)
1876 return rc;
Harald Welte00b2faf2020-05-02 19:56:36 +02001877 LOGDL(dl, LOGL_INFO, "get message from send-queue\n");
rootaf48bed2011-09-26 11:23:06 +02001878 }
1879
1880 /* How much is left in the send-buffer? */
1881 left = msgb_l3len(dl->send_buffer) - dl->send_out;
1882 /* Segment, if data exceeds N201 */
1883 length = left;
1884 if (length > lctx->n201)
1885 length = lctx->n201;
Harald Welte00b2faf2020-05-02 19:56:36 +02001886 LOGDL(dl, LOGL_INFO, "msg-len %d sent %d left %d N201 %d length %d "
1887 "first byte %02x\n", msgb_l3len(dl->send_buffer), dl->send_out, left,
1888 lctx->n201, length, dl->send_buffer->l3h[0]);
rootaf48bed2011-09-26 11:23:06 +02001889 /* If message in send-buffer is completely sent */
1890 if (left == 0) {
1891 msgb_free(dl->send_buffer);
1892 dl->send_buffer = NULL;
1893 goto next_message;
1894 }
1895
Harald Welte00b2faf2020-05-02 19:56:36 +02001896 LOGDL(dl, LOGL_INFO, "send I frame %sV(S)=%d\n",
1897 (left > length) ? "segment " : "", dl->v_send);
rootaf48bed2011-09-26 11:23:06 +02001898
1899 /* Create I frame (segment) and transmit-buffer content */
1900 msg = lapd_msgb_alloc(length, "LAPD I");
1901 msg->l3h = msgb_put(msg, length);
1902 /* assemble message */
1903 memcpy(&nctx, &dl->lctx, sizeof(nctx));
1904 /* keep nctx.ldp */
1905 /* keep nctx.sapi */
1906 /* keep nctx.tei */
1907 nctx.cr = dl->cr.loc2rem.cmd;
1908 nctx.format = LAPD_FORM_I;
1909 nctx.p_f = 0;
1910 nctx.n_send = dl->v_send;
1911 nctx.n_recv = dl->v_recv;
1912 nctx.length = length;
1913 if (left > length)
1914 nctx.more = 1;
1915 else
1916 nctx.more = 0;
1917 if (length)
1918 memcpy(msg->l3h, dl->send_buffer->l3h + dl->send_out,
1919 length);
1920 /* store in tx_hist */
1921 dl->tx_hist[h].msg = lapd_msgb_alloc(msg->len, "HIST");
1922 msgb_put(dl->tx_hist[h].msg, msg->len);
1923 if (length)
1924 memcpy(dl->tx_hist[h].msg->data, msg->l3h, msg->len);
1925 dl->tx_hist[h].more = nctx.more;
1926 /* Add length to track how much is already in the tx buffer */
1927 dl->send_out += length;
1928 } else {
Harald Welte00b2faf2020-05-02 19:56:36 +02001929 LOGDL(dl, LOGL_INFO, "resend I frame from tx buffer V(S)=%d\n", dl->v_send);
rootaf48bed2011-09-26 11:23:06 +02001930
1931 /* Create I frame (segment) from tx_hist */
1932 length = dl->tx_hist[h].msg->len;
1933 msg = lapd_msgb_alloc(length, "LAPD I resend");
1934 msg->l3h = msgb_put(msg, length);
1935 /* assemble message */
1936 memcpy(&nctx, &dl->lctx, sizeof(nctx));
1937 /* keep nctx.ldp */
1938 /* keep nctx.sapi */
1939 /* keep nctx.tei */
1940 nctx.cr = dl->cr.loc2rem.cmd;
1941 nctx.format = LAPD_FORM_I;
1942 nctx.p_f = 0;
1943 nctx.n_send = dl->v_send;
1944 nctx.n_recv = dl->v_recv;
1945 nctx.length = length;
1946 nctx.more = dl->tx_hist[h].more;
1947 if (length)
1948 memcpy(msg->l3h, dl->tx_hist[h].msg->data, length);
1949 }
1950
1951 /* The value of the send state variable V(S) shall be incremented by 1
1952 * at the end of the transmission of the I frame */
1953 dl->v_send = inc_mod(dl->v_send, dl->v_range);
1954
1955 /* If timer T200 is not running at the time right before transmitting a
1956 * frame, when the PH-READY-TO-SEND primitive is received from the
1957 * physical layer., it shall be set. */
1958 if (!osmo_timer_pending(&dl->t200)) {
Andreas Eversberg742fc792011-09-27 09:40:25 +02001959 /* stop Timer T203, if running */
1960 lapd_stop_t203(dl);
1961 /* start Timer T200 */
1962 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001963 }
1964
1965 dl->send_ph_data_req(&nctx, msg);
1966
1967 rc = 0; /* we sent something */
1968 goto next_frame;
1969}
1970
1971/* request link suspension */
1972static int lapd_susp_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1973{
1974 struct lapd_datalink *dl = lctx->dl;
1975 struct msgb *msg = dp->oph.msg;
1976
Harald Welte00b2faf2020-05-02 19:56:36 +02001977 LOGDL(dl, LOGL_INFO, "perform suspension\n");
rootaf48bed2011-09-26 11:23:06 +02001978
1979 /* put back the send-buffer to the send-queue (first position) */
1980 if (dl->send_buffer) {
Harald Welte00b2faf2020-05-02 19:56:36 +02001981 LOGDL(dl, LOGL_INFO, "put frame in sendbuffer back to queue\n");
rootaf48bed2011-09-26 11:23:06 +02001982 llist_add(&dl->send_buffer->list, &dl->send_queue);
1983 dl->send_buffer = NULL;
1984 } else
Harald Welte00b2faf2020-05-02 19:56:36 +02001985 LOGDL(dl, LOGL_INFO, "no frame in sendbuffer\n");
rootaf48bed2011-09-26 11:23:06 +02001986
1987 /* Clear transmit buffer, but keep send buffer */
1988 lapd_dl_flush_tx(dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001989 /* Stop timers (there is no state change, so we must stop all timers */
1990 lapd_stop_t200(dl);
1991 lapd_stop_t203(dl);
rootaf48bed2011-09-26 11:23:06 +02001992
1993 msgb_free(msg);
1994
1995 return send_dl_simple(PRIM_DL_SUSP, PRIM_OP_CONFIRM, &dl->lctx);
1996}
1997
Neels Hofmeyr9e57a5a2015-12-21 11:20:14 +01001998/* request, resume or reconnect of link */
rootaf48bed2011-09-26 11:23:06 +02001999static int lapd_res_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
2000{
2001 struct lapd_datalink *dl = lctx->dl;
2002 struct msgb *msg = dp->oph.msg;
2003 struct lapd_msg_ctx nctx;
2004
Harald Welte00b2faf2020-05-02 19:56:36 +02002005 LOGDL(dl, LOGL_INFO, "perform re-establishment (SABM) length=%d\n", msg->len);
Pau Espin Pedrola99e1102017-12-08 14:30:47 +01002006
rootaf48bed2011-09-26 11:23:06 +02002007 /* 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) {
Harald Welte00b2faf2020-05-02 19:56:36 +02002075 LOGDL(dl, LOGL_INFO, "perform local release\n");
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
Harald Welte00b2faf2020-05-02 19:56:36 +02002095 LOGDL(dl, LOGL_INFO, "perform normal release (DISC)\n");
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;
Pau Espin Pedrola99e1102017-12-08 14:30:47 +01002117
rootaf48bed2011-09-26 11:23:06 +02002118 /* 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,
Pau Espin Pedrola99e1102017-12-08 14:30:47 +01002153 PRIM_DL_UNIT_DATA, PRIM_OP_REQUEST,
rootaf48bed2011-09-26 11:23:06 +02002154 "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) {
Harald Welte00b2faf2020-05-02 19:56:36 +02002220 LOGDL(dl, LOGL_NOTICE, "Message %u/%u unsupported\n",
2221 dp->oph.primitive, dp->oph.operation);
rootaf48bed2011-09-26 11:23:06 +02002222 msgb_free(msg);
2223 return 0;
2224 }
2225 if (i == L2DOWNSLLEN) {
Harald Welte00b2faf2020-05-02 19:56:36 +02002226 LOGDL(dl, LOGL_NOTICE, "Message %u/%u unhandled at this state %s\n",
2227 dp->oph.primitive, dp->oph.operation, lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02002228 msgb_free(msg);
2229 return 0;
2230 }
2231
Harald Welte00b2faf2020-05-02 19:56:36 +02002232 LOGDL(dl, LOGL_INFO, "Message %s received in state %s\n",
2233 l2downstatelist[i].name, lapd_state_name(dl->state));
rootaf48bed2011-09-26 11:23:06 +02002234
2235 rc = l2downstatelist[i].rout(dp, lctx);
2236
2237 return rc;
2238}
2239
Katerina Barone-Adesic28c6a02013-02-15 13:27:59 +01002240/*! @} */