blob: 6b580069f2e5f89c78135b6c9531f17ed608d865 [file] [log] [blame]
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02001/*! \file lapd_core.c
2 * LAPD core implementation */
3/*
4 * (C) 2010-2011 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 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 *
23 */
24
25/*! \addtogroup lapd
26 * @{
Neels Hofmeyr17518fe2017-06-20 04:35:06 +020027 *
28 * Osmocom LAPD core, used for Q.921, LAPDm and others.
29 *
rootaf48bed2011-09-26 11:23:06 +020030 * Notes on Buffering: rcv_buffer, tx_queue, tx_hist, send_buffer, send_queue
31 *
32 * RX data is stored in the rcv_buffer (pointer). If the message is complete, it
33 * is removed from rcv_buffer pointer and forwarded to L3. If the RX data is
34 * received while there is an incomplete rcv_buffer, it is appended to it.
35 *
36 * TX data is stored in the send_queue first. When transmitting a frame,
37 * the first message in the send_queue is moved to the send_buffer. There it
38 * resides until all fragments are acknowledged. Fragments to be sent by I
39 * frames are stored in the tx_hist buffer for resend, if required. Also the
40 * current fragment is copied into the tx_queue. There it resides until it is
41 * forwarded to layer 1.
42 *
43 * In case we have SAPI 0, we only have a window size of 1, so the unack-
44 * nowledged message resides always in the send_buffer. In case of a suspend,
45 * it can be written back to the first position of the send_queue.
46 *
47 * The layer 1 normally sends a PH-READY-TO-SEND. But because we use
48 * asynchronous transfer between layer 1 and layer 2 (serial link), we must
49 * send a frame before layer 1 reaches the right timeslot to send it. So we
50 * move the tx_queue to layer 1 when there is not already a pending frame, and
51 * wait until acknowledge after the frame has been sent. If we receive an
52 * acknowledge, we can send the next frame from the buffer, if any.
53 *
54 * The moving of tx_queue to layer 1 may also trigger T200, if desired. Also it
55 * will trigger next I frame, if possible.
56 *
57 * T203 is optional. It will be stated when entering MF EST state. It will also
58 * be started when I or S frame is received in that state . It will be
59 * restarted in the lapd_acknowledge() function, in case outstanding frames
60 * will not trigger T200. It will be stoped, when T200 is started in MF EST
61 * state. It will also be stoped when leaving MF EST state.
62 *
Neels Hofmeyr17518fe2017-06-20 04:35:06 +020063 * \file lapd_core.c
rootaf48bed2011-09-26 11:23:06 +020064 */
65
66/* Enable this to test content resolution on network side:
67 * - The first SABM is received, UA is dropped.
68 * - The phone repeats SABM, but it's content is wrong, so it is ignored
69 * - The phone repeats SABM again, content is right, so UA is sent.
70 */
71//#define TEST_CONTENT_RESOLUTION_NETWORK
72
73#include <stdio.h>
74#include <stdint.h>
75#include <string.h>
76#include <errno.h>
rootaf48bed2011-09-26 11:23:06 +020077
78#include <osmocom/core/logging.h>
79#include <osmocom/core/timer.h>
80#include <osmocom/core/msgb.h>
81#include <osmocom/core/utils.h>
82#include <osmocom/core/talloc.h>
83#include <osmocom/gsm/lapd_core.h>
Max2f0b0c92017-01-12 16:47:13 +010084#include <osmocom/gsm/rsl.h>
rootaf48bed2011-09-26 11:23:06 +020085
86/* TS 04.06 Table 4 / Section 3.8.1 */
87#define LAPD_U_SABM 0x7
88#define LAPD_U_SABME 0xf
89#define LAPD_U_DM 0x3
90#define LAPD_U_UI 0x0
91#define LAPD_U_DISC 0x8
92#define LAPD_U_UA 0xC
93#define LAPD_U_FRMR 0x11
94
95#define LAPD_S_RR 0x0
96#define LAPD_S_RNR 0x1
97#define LAPD_S_REJ 0x2
98
99#define CR_USER2NET_CMD 0
100#define CR_USER2NET_RESP 1
101#define CR_NET2USER_CMD 1
102#define CR_NET2USER_RESP 0
103
104#define LAPD_HEADROOM 56
105
106#define SBIT(a) (1 << a)
107#define ALL_STATES 0xffffffff
108
Andreas Eversberg742fc792011-09-27 09:40:25 +0200109static void lapd_t200_cb(void *data);
110static void lapd_t203_cb(void *data);
111static int lapd_send_i(struct lapd_msg_ctx *lctx, int line);
112static int lapd_est_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx);
113
rootaf48bed2011-09-26 11:23:06 +0200114/* UTILITY FUNCTIONS */
115
116struct msgb *lapd_msgb_alloc(int length, const char *name)
117{
118 /* adding space for padding, FIXME: add as an option */
119 if (length < 21)
120 length = 21;
121 return msgb_alloc_headroom(length + LAPD_HEADROOM, LAPD_HEADROOM, name);
122}
123
124static inline uint8_t do_mod(uint8_t x, uint8_t m)
125{
126 return x & (m - 1);
127}
128
129static inline uint8_t inc_mod(uint8_t x, uint8_t m)
130{
131 return (x + 1) & (m - 1);
132}
133
134static inline uint8_t add_mod(uint8_t x, uint8_t y, uint8_t m)
135{
136 return (x + y) & (m - 1);
137}
138
139static inline uint8_t sub_mod(uint8_t x, uint8_t y, uint8_t m)
140{
141 return (x - y) & (m - 1); /* handle negative results correctly */
142}
143
144static void lapd_dl_flush_send(struct lapd_datalink *dl)
145{
146 struct msgb *msg;
147
148 /* Flush send-queue */
149 while ((msg = msgb_dequeue(&dl->send_queue)))
150 msgb_free(msg);
151
152 /* Clear send-buffer */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +0200153 msgb_free(dl->send_buffer);
154 dl->send_buffer = NULL;
rootaf48bed2011-09-26 11:23:06 +0200155}
156
157static void lapd_dl_flush_hist(struct lapd_datalink *dl)
158{
159 unsigned int i;
160
Harald Weltef92e44c2016-08-01 00:24:19 +0200161 if (!dl->range_hist || !dl->tx_hist)
Harald Welte0ee90f82016-07-03 20:45:21 +0200162 return;
163
rootaf48bed2011-09-26 11:23:06 +0200164 for (i = 0; i < dl->range_hist; i++) {
165 if (dl->tx_hist[i].msg) {
166 msgb_free(dl->tx_hist[i].msg);
167 dl->tx_hist[i].msg = NULL;
168 }
169 }
170}
171
172static void lapd_dl_flush_tx(struct lapd_datalink *dl)
173{
174 struct msgb *msg;
175
176 while ((msg = msgb_dequeue(&dl->tx_queue)))
177 msgb_free(msg);
178 lapd_dl_flush_hist(dl);
179}
180
181/* Figure B.2/Q.921 */
Harald Weltec733d142017-03-15 10:20:51 +0100182const struct value_string lapd_state_names[] = {
183 OSMO_VALUE_STRING(LAPD_STATE_NULL),
184 OSMO_VALUE_STRING(LAPD_STATE_TEI_UNASS),
185 OSMO_VALUE_STRING(LAPD_STATE_ASS_TEI_WAIT),
186 OSMO_VALUE_STRING(LAPD_STATE_EST_TEI_WAIT),
187 OSMO_VALUE_STRING(LAPD_STATE_IDLE),
188 OSMO_VALUE_STRING(LAPD_STATE_SABM_SENT),
189 OSMO_VALUE_STRING(LAPD_STATE_DISC_SENT),
190 OSMO_VALUE_STRING(LAPD_STATE_MF_EST),
191 OSMO_VALUE_STRING(LAPD_STATE_TIMER_RECOV),
192 { 0, NULL }
rootaf48bed2011-09-26 11:23:06 +0200193};
194
Harald Weltec733d142017-03-15 10:20:51 +0100195static inline const char *lapd_state_name(enum lapd_state state)
196{
197 return get_value_string(lapd_state_names, state);
198}
199
Andreas Eversberg742fc792011-09-27 09:40:25 +0200200static void lapd_start_t200(struct lapd_datalink *dl)
201{
202 if (osmo_timer_pending(&dl->t200))
203 return;
Philipp Maier08177d32016-12-08 17:23:26 +0100204 LOGP(DLLAPD, LOGL_INFO, "start T200 (dl=%p)\n", dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +0200205 osmo_timer_schedule(&dl->t200, dl->t200_sec, dl->t200_usec);
206}
207
208static void lapd_start_t203(struct lapd_datalink *dl)
209{
210 if (osmo_timer_pending(&dl->t203))
211 return;
Philipp Maier08177d32016-12-08 17:23:26 +0100212 LOGP(DLLAPD, LOGL_INFO, "start T203 (dl=%p)\n", dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +0200213 osmo_timer_schedule(&dl->t203, dl->t203_sec, dl->t203_usec);
214}
215
216static void lapd_stop_t200(struct lapd_datalink *dl)
217{
218 if (!osmo_timer_pending(&dl->t200))
219 return;
Philipp Maier08177d32016-12-08 17:23:26 +0100220 LOGP(DLLAPD, LOGL_INFO, "stop T200 (dl=%p)\n", dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +0200221 osmo_timer_del(&dl->t200);
222}
223
224static void lapd_stop_t203(struct lapd_datalink *dl)
225{
226 if (!osmo_timer_pending(&dl->t203))
227 return;
Philipp Maier08177d32016-12-08 17:23:26 +0100228 LOGP(DLLAPD, LOGL_INFO, "stop T203 (dl=%p)\n", dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +0200229 osmo_timer_del(&dl->t203);
230}
231
rootaf48bed2011-09-26 11:23:06 +0200232static void lapd_dl_newstate(struct lapd_datalink *dl, uint32_t state)
233{
Philipp Maier08177d32016-12-08 17:23:26 +0100234 LOGP(DLLAPD, LOGL_INFO, "new state %s -> %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100235 lapd_state_name(dl->state), lapd_state_name(state), dl);
rootaf48bed2011-09-26 11:23:06 +0200236
237 if (state != LAPD_STATE_MF_EST && dl->state == LAPD_STATE_MF_EST) {
238 /* stop T203 on leaving MF EST state, if running */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200239 lapd_stop_t203(dl);
rootaf48bed2011-09-26 11:23:06 +0200240 /* remove content res. (network side) on leaving MF EST state */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +0200241 msgb_free(dl->cont_res);
242 dl->cont_res = NULL;
rootaf48bed2011-09-26 11:23:06 +0200243 }
244
245 /* start T203 on entering MF EST state, if enabled */
246 if ((dl->t203_sec || dl->t203_usec)
Andreas Eversberg742fc792011-09-27 09:40:25 +0200247 && state == LAPD_STATE_MF_EST && dl->state != LAPD_STATE_MF_EST)
248 lapd_start_t203(dl);
rootaf48bed2011-09-26 11:23:06 +0200249
250 dl->state = state;
251}
252
rootaf48bed2011-09-26 11:23:06 +0200253static void *tall_lapd_ctx = NULL;
254
255/* init datalink instance and allocate history */
256void lapd_dl_init(struct lapd_datalink *dl, uint8_t k, uint8_t v_range,
257 int maxf)
258{
259 int m;
260
261 memset(dl, 0, sizeof(*dl));
262 INIT_LLIST_HEAD(&dl->send_queue);
263 INIT_LLIST_HEAD(&dl->tx_queue);
264 dl->reestablish = 1;
265 dl->n200_est_rel = 3;
266 dl->n200 = 3;
267 dl->t200_sec = 1;
268 dl->t200_usec = 0;
Pablo Neira Ayuso44f423f2017-05-08 18:00:28 +0200269 osmo_timer_setup(&dl->t200, lapd_t200_cb, dl);
rootaf48bed2011-09-26 11:23:06 +0200270 dl->t203_sec = 10;
271 dl->t203_usec = 0;
Pablo Neira Ayuso44f423f2017-05-08 18:00:28 +0200272 osmo_timer_setup(&dl->t203, lapd_t203_cb, dl);
rootaf48bed2011-09-26 11:23:06 +0200273 dl->maxf = maxf;
274 if (k > v_range - 1)
275 k = v_range - 1;
276 dl->k = k;
277 dl->v_range = v_range;
278
279 /* Calculate modulo for history array:
280 * - The history range must be at least k+1.
281 * - The history range must be 2^x, where x is as low as possible.
282 */
283 k++;
284 for (m = 0x80; m; m >>= 1) {
285 if ((m & k)) {
286 if (k > m)
287 m <<= 1;
288 dl->range_hist = m;
289 break;
290 }
291 }
292
293 LOGP(DLLAPD, LOGL_INFO, "Init DL layer: sequence range = %d, k = %d, "
Philipp Maier08177d32016-12-08 17:23:26 +0100294 "history range = %d (dl=%p)\n", dl->v_range, dl->k,
295 dl->range_hist, dl);
rootaf48bed2011-09-26 11:23:06 +0200296
297 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
298
299 if (!tall_lapd_ctx)
300 tall_lapd_ctx = talloc_named_const(NULL, 1, "lapd context");
Holger Hans Peter Freyther10f0bde2014-02-09 20:03:38 +0100301 dl->tx_hist = talloc_zero_array(tall_lapd_ctx,
302 struct lapd_history, dl->range_hist);
rootaf48bed2011-09-26 11:23:06 +0200303}
304
305/* reset to IDLE state */
306void lapd_dl_reset(struct lapd_datalink *dl)
307{
rootaf48bed2011-09-26 11:23:06 +0200308 /* flush buffer */
309 lapd_dl_flush_tx(dl);
310 lapd_dl_flush_send(dl);
311 /* Discard partly received L3 message */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +0200312 msgb_free(dl->rcv_buffer);
313 dl->rcv_buffer = NULL;
Andreas Eversberg742fc792011-09-27 09:40:25 +0200314 /* stop Timers */
315 lapd_stop_t200(dl);
316 lapd_stop_t203(dl);
Jean-Francois Dionned78c9732017-03-06 14:33:20 -0500317 if (dl->state == LAPD_STATE_IDLE)
318 return;
319 LOGP(DLLAPD, LOGL_INFO, "Resetting LAPDm instance (dl=%p)\n", dl);
320 /* enter idle state (and remove eventual cont_res) */
321 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
rootaf48bed2011-09-26 11:23:06 +0200322}
323
324/* reset and de-allocate history buffer */
325void lapd_dl_exit(struct lapd_datalink *dl)
326{
327 /* free all ressources except history buffer */
328 lapd_dl_reset(dl);
Ivan Kluchnikovb9759db2017-05-11 15:19:23 +0300329
330 /* enter null state */
331 lapd_dl_newstate(dl, LAPD_STATE_NULL);
332
rootaf48bed2011-09-26 11:23:06 +0200333 /* free history buffer list */
334 talloc_free(dl->tx_hist);
Holger Hans Peter Freytherf5a079f2013-05-08 18:42:39 +0200335 dl->tx_hist = NULL;
rootaf48bed2011-09-26 11:23:06 +0200336}
337
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200338/*! Set the \ref lapdm_mode of a LAPDm entity */
rootaf48bed2011-09-26 11:23:06 +0200339int lapd_set_mode(struct lapd_datalink *dl, enum lapd_mode mode)
340{
341 switch (mode) {
342 case LAPD_MODE_USER:
343 dl->cr.loc2rem.cmd = CR_USER2NET_CMD;
344 dl->cr.loc2rem.resp = CR_USER2NET_RESP;
345 dl->cr.rem2loc.cmd = CR_NET2USER_CMD;
346 dl->cr.rem2loc.resp = CR_NET2USER_RESP;
347 break;
348 case LAPD_MODE_NETWORK:
349 dl->cr.loc2rem.cmd = CR_NET2USER_CMD;
350 dl->cr.loc2rem.resp = CR_NET2USER_RESP;
351 dl->cr.rem2loc.cmd = CR_USER2NET_CMD;
352 dl->cr.rem2loc.resp = CR_USER2NET_RESP;
353 break;
354 default:
355 return -EINVAL;
356 }
357 dl->mode = mode;
358
359 return 0;
360}
361
362/* send DL message with optional msgb */
363static int send_dl_l3(uint8_t prim, uint8_t op, struct lapd_msg_ctx *lctx,
364 struct msgb *msg)
365{
366 struct lapd_datalink *dl = lctx->dl;
367 struct osmo_dlsap_prim dp;
368
369 osmo_prim_init(&dp.oph, 0, prim, op, msg);
370 return dl->send_dlsap(&dp, lctx);
371}
372
373/* send simple DL message */
374static inline int send_dl_simple(uint8_t prim, uint8_t op,
375 struct lapd_msg_ctx *lctx)
376{
377 struct msgb *msg = lapd_msgb_alloc(0, "DUMMY");
378
379 return send_dl_l3(prim, op, lctx, msg);
380}
381
382/* send MDL-ERROR INDICATION */
383static int mdl_error(uint8_t cause, struct lapd_msg_ctx *lctx)
384{
385 struct lapd_datalink *dl = lctx->dl;
386 struct osmo_dlsap_prim dp;
387
Philipp Maier08177d32016-12-08 17:23:26 +0100388 LOGP(DLLAPD, LOGL_NOTICE,
389 "sending MDL-ERROR-IND cause %d from state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100390 cause, lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +0200391 osmo_prim_init(&dp.oph, 0, PRIM_MDL_ERROR, PRIM_OP_INDICATION, NULL);
392 dp.u.error_ind.cause = cause;
393 return dl->send_dlsap(&dp, lctx);
394}
395
396/* send UA response */
397static int lapd_send_ua(struct lapd_msg_ctx *lctx, uint8_t len, uint8_t *data)
398{
399 struct msgb *msg = lapd_msgb_alloc(len, "LAPD UA");
400 struct lapd_msg_ctx nctx;
401 struct lapd_datalink *dl = lctx->dl;
402
403 memcpy(&nctx, lctx, sizeof(nctx));
404 msg->l3h = msgb_put(msg, len);
405 if (len)
406 memcpy(msg->l3h, data, len);
407 /* keep nctx.ldp */
408 /* keep nctx.sapi */
409 /* keep nctx.tei */
410 nctx.cr = dl->cr.loc2rem.resp;
411 nctx.format = LAPD_FORM_U;
412 nctx.s_u = LAPD_U_UA;
413 /* keep nctx.p_f */
414 nctx.length = len;
415 nctx.more = 0;
416
417 return dl->send_ph_data_req(&nctx, msg);
418}
419
420/* send DM response */
421static int lapd_send_dm(struct lapd_msg_ctx *lctx)
422{
423 struct msgb *msg = lapd_msgb_alloc(0, "LAPD DM");
424 struct lapd_msg_ctx nctx;
425 struct lapd_datalink *dl = lctx->dl;
426
427 memcpy(&nctx, lctx, sizeof(nctx));
428 /* keep nctx.ldp */
429 /* keep nctx.sapi */
430 /* keep nctx.tei */
431 nctx.cr = dl->cr.loc2rem.resp;
432 nctx.format = LAPD_FORM_U;
433 nctx.s_u = LAPD_U_DM;
434 /* keep nctx.p_f */
435 nctx.length = 0;
436 nctx.more = 0;
437
438 return dl->send_ph_data_req(&nctx, msg);
439}
440
441/* send RR response / command */
442static int lapd_send_rr(struct lapd_msg_ctx *lctx, uint8_t f_bit, uint8_t cmd)
443{
444 struct msgb *msg = lapd_msgb_alloc(0, "LAPD RR");
445 struct lapd_msg_ctx nctx;
446 struct lapd_datalink *dl = lctx->dl;
447
448 memcpy(&nctx, lctx, sizeof(nctx));
449 /* keep nctx.ldp */
450 /* keep nctx.sapi */
451 /* keep nctx.tei */
452 nctx.cr = (cmd) ? dl->cr.loc2rem.cmd : dl->cr.loc2rem.resp;
453 nctx.format = LAPD_FORM_S;
454 nctx.s_u = LAPD_S_RR;
455 nctx.p_f = f_bit;
456 nctx.n_recv = dl->v_recv;
457 nctx.length = 0;
458 nctx.more = 0;
459
460 return dl->send_ph_data_req(&nctx, msg);
461}
462
463/* send RNR response / command */
464static int lapd_send_rnr(struct lapd_msg_ctx *lctx, uint8_t f_bit, uint8_t cmd)
465{
466 struct msgb *msg = lapd_msgb_alloc(0, "LAPD RNR");
467 struct lapd_msg_ctx nctx;
468 struct lapd_datalink *dl = lctx->dl;
469
470 memcpy(&nctx, lctx, sizeof(nctx));
471 /* keep nctx.ldp */
472 /* keep nctx.sapi */
473 /* keep nctx.tei */
474 nctx.cr = (cmd) ? dl->cr.loc2rem.cmd : dl->cr.loc2rem.resp;
475 nctx.format = LAPD_FORM_S;
476 nctx.s_u = LAPD_S_RNR;
477 nctx.p_f = f_bit;
478 nctx.n_recv = dl->v_recv;
479 nctx.length = 0;
480 nctx.more = 0;
481
482 return dl->send_ph_data_req(&nctx, msg);
483}
484
485/* send REJ response */
486static int lapd_send_rej(struct lapd_msg_ctx *lctx, uint8_t f_bit)
487{
488 struct msgb *msg = lapd_msgb_alloc(0, "LAPD REJ");
489 struct lapd_msg_ctx nctx;
490 struct lapd_datalink *dl = lctx->dl;
491
492 memcpy(&nctx, lctx, sizeof(nctx));
493 /* keep nctx.ldp */
494 /* keep nctx.sapi */
495 /* keep nctx.tei */
496 nctx.cr = dl->cr.loc2rem.resp;
497 nctx.format = LAPD_FORM_S;
498 nctx.s_u = LAPD_S_REJ;
499 nctx.p_f = f_bit;
500 nctx.n_recv = dl->v_recv;
501 nctx.length = 0;
502 nctx.more = 0;
503
504 return dl->send_ph_data_req(&nctx, msg);
505}
506
507/* resend SABM or DISC message */
508static int lapd_send_resend(struct lapd_datalink *dl)
509{
510 struct msgb *msg;
511 uint8_t h = do_mod(dl->v_send, dl->range_hist);
512 int length = dl->tx_hist[h].msg->len;
513 struct lapd_msg_ctx nctx;
514
515 /* assemble message */
516 memcpy(&nctx, &dl->lctx, sizeof(nctx));
517 /* keep nctx.ldp */
518 /* keep nctx.sapi */
519 /* keep nctx.tei */
520 nctx.cr = dl->cr.loc2rem.cmd;
521 nctx.format = LAPD_FORM_U;
522 if (dl->state == LAPD_STATE_SABM_SENT)
523 nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
524 else
525 nctx.s_u = LAPD_U_DISC;
526 nctx.p_f = 1;
527 nctx.length = length;
528 nctx.more = 0;
529
530 /* Resend SABM/DISC from tx_hist */
531 msg = lapd_msgb_alloc(length, "LAPD resend");
532 msg->l3h = msgb_put(msg, length);
533 if (length)
534 memcpy(msg->l3h, dl->tx_hist[h].msg->data, length);
535
536 return dl->send_ph_data_req(&nctx, msg);
537}
538
539/* reestablish link */
540static int lapd_reestablish(struct lapd_datalink *dl)
541{
542 struct osmo_dlsap_prim dp;
543 struct msgb *msg;
544
Philipp Maier08177d32016-12-08 17:23:26 +0100545 LOGP(DLLAPD, LOGL_DEBUG, "lapd reestablish (dl=%p)\n", dl);
546
rootaf48bed2011-09-26 11:23:06 +0200547 msg = lapd_msgb_alloc(0, "DUMMY");
548 osmo_prim_init(&dp.oph, 0, PRIM_DL_EST, PRIM_OP_REQUEST, msg);
549
550 return lapd_est_req(&dp, &dl->lctx);
551}
552
553/* Timer callback on T200 expiry */
554static void lapd_t200_cb(void *data)
555{
556 struct lapd_datalink *dl = data;
557
Philipp Maier08177d32016-12-08 17:23:26 +0100558 LOGP(DLLAPD, LOGL_INFO, "Timeout T200 state=%s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100559 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +0200560
561 switch (dl->state) {
562 case LAPD_STATE_SABM_SENT:
563 /* 5.4.1.3 */
564 if (dl->retrans_ctr + 1 >= dl->n200_est_rel + 1) {
rootaf48bed2011-09-26 11:23:06 +0200565 /* flush tx and send buffers */
566 lapd_dl_flush_tx(dl);
567 lapd_dl_flush_send(dl);
568 /* go back to idle state */
569 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
570 /* NOTE: we must not change any other states or buffers
571 * and queues, since we may reconnect after handover
572 * failure. the buffered messages is replaced there */
Philipp Maier6b986c22017-02-01 12:00:45 +0100573 /* send MDL ERROR INIDCATION to L3 */
574 mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
Philipp Maierd9f61292016-12-08 10:45:06 +0100575 /* send RELEASE INDICATION to L3 */
576 send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION,
577 &dl->lctx);
rootaf48bed2011-09-26 11:23:06 +0200578 break;
579 }
580 /* retransmit SABM command */
581 lapd_send_resend(dl);
582 /* increment re-transmission counter */
583 dl->retrans_ctr++;
584 /* restart T200 (PH-READY-TO-SEND) */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200585 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200586 break;
587 case LAPD_STATE_DISC_SENT:
588 /* 5.4.4.3 */
589 if (dl->retrans_ctr + 1 >= dl->n200_est_rel + 1) {
rootaf48bed2011-09-26 11:23:06 +0200590 /* send MDL ERROR INIDCATION to L3 */
591 mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
Philipp Maier6b986c22017-02-01 12:00:45 +0100592 /* send RELEASE INDICATION to L3 */
593 send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
rootaf48bed2011-09-26 11:23:06 +0200594 /* flush tx and send buffers */
595 lapd_dl_flush_tx(dl);
596 lapd_dl_flush_send(dl);
597 /* go back to idle state */
598 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
599 /* NOTE: we must not change any other states or buffers
600 * and queues, since we may reconnect after handover
601 * failure. the buffered messages is replaced there */
602 break;
603 }
604 /* retransmit DISC command */
605 lapd_send_resend(dl);
606 /* increment re-transmission counter */
607 dl->retrans_ctr++;
608 /* restart T200 (PH-READY-TO-SEND) */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200609 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200610 break;
611 case LAPD_STATE_MF_EST:
612 /* 5.5.7 */
613 dl->retrans_ctr = 0;
614 lapd_dl_newstate(dl, LAPD_STATE_TIMER_RECOV);
615 /* fall through */
616 case LAPD_STATE_TIMER_RECOV:
617 dl->retrans_ctr++;
618 if (dl->retrans_ctr < dl->n200) {
619 uint8_t vs = sub_mod(dl->v_send, 1, dl->v_range);
620 uint8_t h = do_mod(vs, dl->range_hist);
621 /* retransmit I frame (V_s-1) with P=1, if any */
622 if (dl->tx_hist[h].msg) {
623 struct msgb *msg;
624 int length = dl->tx_hist[h].msg->len;
625 struct lapd_msg_ctx nctx;
626
627 LOGP(DLLAPD, LOGL_INFO, "retransmit last frame"
Philipp Maier08177d32016-12-08 17:23:26 +0100628 " V(S)=%d (dl=%p)\n", vs, dl);
rootaf48bed2011-09-26 11:23:06 +0200629 /* Create I frame (segment) from tx_hist */
630 memcpy(&nctx, &dl->lctx, sizeof(nctx));
631 /* keep nctx.ldp */
632 /* keep nctx.sapi */
633 /* keep nctx.tei */
634 nctx.cr = dl->cr.loc2rem.cmd;
635 nctx.format = LAPD_FORM_I;
636 nctx.p_f = 1;
637 nctx.n_send = vs;
638 nctx.n_recv = dl->v_recv;
639 nctx.length = length;
640 nctx.more = dl->tx_hist[h].more;
641 msg = lapd_msgb_alloc(length, "LAPD I resend");
642 msg->l3h = msgb_put(msg, length);
643 memcpy(msg->l3h, dl->tx_hist[h].msg->data,
644 length);
645 dl->send_ph_data_req(&nctx, msg);
646 } else {
647 /* OR send appropriate supervision frame with P=1 */
648 if (!dl->own_busy && !dl->seq_err_cond) {
649 lapd_send_rr(&dl->lctx, 1, 1);
650 /* NOTE: In case of sequence error
651 * condition, the REJ frame has been
652 * transmitted when entering the
653 * condition, so it has not be done
654 * here
655 */
656 } else if (dl->own_busy) {
657 lapd_send_rnr(&dl->lctx, 1, 1);
658 } else {
659 LOGP(DLLAPD, LOGL_INFO, "unhandled, "
Philipp Maier08177d32016-12-08 17:23:26 +0100660 "pls. fix (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200661 }
662 }
663 /* restart T200 (PH-READY-TO-SEND) */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200664 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200665 } else {
666 /* send MDL ERROR INIDCATION to L3 */
667 mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
668 /* reestablish */
669 if (!dl->reestablish)
670 break;
671 LOGP(DLLAPD, LOGL_NOTICE, "N200 reached, performing "
Philipp Maier08177d32016-12-08 17:23:26 +0100672 "reestablishment. (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200673 lapd_reestablish(dl);
674 }
675 break;
676 default:
677 LOGP(DLLAPD, LOGL_INFO, "T200 expired in unexpected "
Harald Weltec733d142017-03-15 10:20:51 +0100678 "dl->state %s (dl=%p)\n", lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +0200679 }
680}
681
682/* Timer callback on T203 expiry */
683static void lapd_t203_cb(void *data)
684{
685 struct lapd_datalink *dl = data;
686
Philipp Maier08177d32016-12-08 17:23:26 +0100687 LOGP(DLLAPD, LOGL_INFO, "Timeout T203 state=%s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100688 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +0200689
690 if (dl->state != LAPD_STATE_MF_EST) {
691 LOGP(DLLAPD, LOGL_ERROR, "T203 fired outside MF EST state, "
Philipp Maier08177d32016-12-08 17:23:26 +0100692 "please fix! (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200693 return;
694 }
695
696 /* set retransmission counter to 0 */
697 dl->retrans_ctr = 0;
698 /* enter timer recovery state */
699 lapd_dl_newstate(dl, LAPD_STATE_TIMER_RECOV);
700 /* transmit a supervisory command with P bit set to 1 as follows: */
701 if (!dl->own_busy) {
Philipp Maier08177d32016-12-08 17:23:26 +0100702 LOGP(DLLAPD, LOGL_INFO,
703 "transmit an RR poll command (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200704 /* Send RR with P=1 */
705 lapd_send_rr(&dl->lctx, 1, 1);
706 } else {
Philipp Maier08177d32016-12-08 17:23:26 +0100707 LOGP(DLLAPD, LOGL_INFO,
708 "transmit an RNR poll command (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200709 /* Send RNR with P=1 */
710 lapd_send_rnr(&dl->lctx, 1, 1);
711 }
712 /* start T200 */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200713 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200714}
715
716/* 5.5.3.1: Common function to acknowlege frames up to the given N(R) value */
717static void lapd_acknowledge(struct lapd_msg_ctx *lctx)
718{
719 struct lapd_datalink *dl = lctx->dl;
720 uint8_t nr = lctx->n_recv;
Holger Hans Peter Freytherfb6a2e22012-03-16 10:35:38 +0100721 int s = 0, rej = 0, t200_reset = 0;
rootaf48bed2011-09-26 11:23:06 +0200722 int i, h;
723
724 /* supervisory frame ? */
725 if (lctx->format == LAPD_FORM_S)
726 s = 1;
727 /* REJ frame ? */
728 if (s && lctx->s_u == LAPD_S_REJ)
729 rej = 1;
730
731 /* Flush all transmit buffers of acknowledged frames */
732 for (i = dl->v_ack; i != nr; i = inc_mod(i, dl->v_range)) {
733 h = do_mod(i, dl->range_hist);
734 if (dl->tx_hist[h].msg) {
735 msgb_free(dl->tx_hist[h].msg);
736 dl->tx_hist[h].msg = NULL;
737 LOGP(DLLAPD, LOGL_INFO, "ack frame %d\n", i);
738 }
739 }
740
741 if (dl->state != LAPD_STATE_TIMER_RECOV) {
742 /* When not in the timer recovery condition, the data
743 * link layer entity shall reset the timer T200 on
744 * receipt of a valid I frame with N(R) higher than V(A),
745 * or an REJ with an N(R) equal to V(A). */
746 if ((!rej && nr != dl->v_ack)
747 || (rej && nr == dl->v_ack)) {
rootaf48bed2011-09-26 11:23:06 +0200748 t200_reset = 1;
Andreas Eversberg742fc792011-09-27 09:40:25 +0200749 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200750 /* 5.5.3.1 Note 1 + 2 imply timer recovery cond. */
751 }
752 /* 5.7.4: N(R) sequence error
753 * N(R) is called valid, if and only if
754 * (N(R)-V(A)) mod 8 <= (V(S)-V(A)) mod 8.
755 */
756 if (sub_mod(nr, dl->v_ack, dl->v_range)
757 > sub_mod(dl->v_send, dl->v_ack, dl->v_range)) {
Philipp Maier08177d32016-12-08 17:23:26 +0100758 LOGP(DLLAPD, LOGL_NOTICE, "N(R) sequence error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200759 mdl_error(MDL_CAUSE_SEQ_ERR, lctx);
760 }
761 }
762
763 /* V(A) shall be set to the value of N(R) */
764 dl->v_ack = nr;
765
Andreas Eversberg742fc792011-09-27 09:40:25 +0200766 /* If T200 has been stopped by the receipt of an I, RR or RNR frame,
rootaf48bed2011-09-26 11:23:06 +0200767 * and if there are outstanding I frames, restart T200 */
768 if (t200_reset && !rej) {
769 if (dl->tx_hist[sub_mod(dl->v_send, 1, dl->range_hist)].msg) {
770 LOGP(DLLAPD, LOGL_INFO, "start T200, due to unacked I "
Philipp Maier08177d32016-12-08 17:23:26 +0100771 "frame(s) (dl=%p)\n", dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +0200772 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200773 }
774 }
775
776 /* This also does a restart, when I or S frame is received */
777
778 /* Stop T203, if running */
Andreas Eversberg742fc792011-09-27 09:40:25 +0200779 lapd_stop_t203(dl);
rootaf48bed2011-09-26 11:23:06 +0200780 /* Start T203, if T200 is not running in MF EST state, if enabled */
781 if (!osmo_timer_pending(&dl->t200)
782 && (dl->t203_sec || dl->t203_usec)
783 && (dl->state == LAPD_STATE_MF_EST)) {
Andreas Eversberg742fc792011-09-27 09:40:25 +0200784 lapd_start_t203(dl);
rootaf48bed2011-09-26 11:23:06 +0200785 }
786}
787
788/* L1 -> L2 */
789
790/* Receive a LAPD U (Unnumbered) message from L1 */
791static int lapd_rx_u(struct msgb *msg, struct lapd_msg_ctx *lctx)
792{
793 struct lapd_datalink *dl = lctx->dl;
794 int length = lctx->length;
Sylvain Munaut9a5f3b82011-11-20 09:01:59 +0100795 int rc = 0;
rootaf48bed2011-09-26 11:23:06 +0200796 uint8_t prim, op;
797
798 switch (lctx->s_u) {
799 case LAPD_U_SABM:
800 case LAPD_U_SABME:
801 prim = PRIM_DL_EST;
802 op = PRIM_OP_INDICATION;
803
Philipp Maier08177d32016-12-08 17:23:26 +0100804 LOGP(DLLAPD, LOGL_INFO, "SABM(E) received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100805 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +0200806 /* 5.7.1 */
807 dl->seq_err_cond = 0;
808 /* G.2.2 Wrong value of the C/R bit */
809 if (lctx->cr == dl->cr.rem2loc.resp) {
Philipp Maier08177d32016-12-08 17:23:26 +0100810 LOGP(DLLAPD, LOGL_ERROR,
811 "SABM response error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200812 msgb_free(msg);
813 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
814 return -EINVAL;
815 }
816
817 /* G.4.5 If SABM is received with L>N201 or with M bit
818 * set, AN MDL-ERROR-INDICATION is sent to MM.
819 */
820 if (lctx->more || length > lctx->n201) {
Philipp Maier08177d32016-12-08 17:23:26 +0100821 LOGP(DLLAPD, LOGL_ERROR,
822 "SABM too large error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200823 msgb_free(msg);
824 mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
825 return -EIO;
826 }
827
828 switch (dl->state) {
829 case LAPD_STATE_IDLE:
830 break;
831 case LAPD_STATE_MF_EST:
832 LOGP(DLLAPD, LOGL_INFO, "SABM command, multiple "
Philipp Maier08177d32016-12-08 17:23:26 +0100833 "frame established state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200834 /* If link is lost on the remote side, we start over
835 * and send DL-ESTABLISH indication again. */
Andreas Eversberg6e182082013-02-06 14:13:21 +0100836 /* Additionally, continue in case of content resoltion
837 * (GSM network). This happens, if the mobile has not
838 * yet received UA or another mobile (collision) tries
839 * to establish connection. The mobile must receive
840 * UA again. */
Andreas Eversbergccc46332013-06-12 09:25:27 +0200841 /* 5.4.2.1 */
842 if (!length) {
843 /* If no content resolution, this is a
844 * re-establishment. */
845 LOGP(DLLAPD, LOGL_INFO,
Philipp Maier08177d32016-12-08 17:23:26 +0100846 "Remote reestablish (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200847 break;
848 }
Andreas Eversbergccc46332013-06-12 09:25:27 +0200849 if (!dl->cont_res) {
850 LOGP(DLLAPD, LOGL_INFO, "SABM command not "
Philipp Maier08177d32016-12-08 17:23:26 +0100851 "allowed in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100852 lapd_state_name(dl->state), dl);
Andreas Eversbergccc46332013-06-12 09:25:27 +0200853 mdl_error(MDL_CAUSE_SABM_MF, lctx);
854 msgb_free(msg);
855 return 0;
856 }
rootaf48bed2011-09-26 11:23:06 +0200857 /* Ignore SABM if content differs from first SABM. */
Andreas Eversbergccc46332013-06-12 09:25:27 +0200858 if (dl->mode == LAPD_MODE_NETWORK && length) {
rootaf48bed2011-09-26 11:23:06 +0200859#ifdef TEST_CONTENT_RESOLUTION_NETWORK
860 dl->cont_res->data[0] ^= 0x01;
861#endif
Andreas Eversberg6e182082013-02-06 14:13:21 +0100862 if (memcmp(dl->cont_res->data, msg->data,
863 length)) {
rootaf48bed2011-09-26 11:23:06 +0200864 LOGP(DLLAPD, LOGL_INFO, "Another SABM "
Thorsten Alteholza81055d2017-03-02 22:13:48 +0100865 "with different content - "
Philipp Maier08177d32016-12-08 17:23:26 +0100866 "ignoring! (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200867 msgb_free(msg);
868 return 0;
869 }
870 }
871 /* send UA again */
872 lapd_send_ua(lctx, length, msg->l3h);
873 msgb_free(msg);
874 return 0;
875 case LAPD_STATE_DISC_SENT:
876 /* 5.4.6.2 send DM with F=P */
877 lapd_send_dm(lctx);
Andreas Eversberg742fc792011-09-27 09:40:25 +0200878 /* stop Timer T200 */
879 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200880 msgb_free(msg);
881 return send_dl_simple(prim, op, lctx);
882 default:
883 /* collision: Send UA, but still wait for rx UA, then
884 * change to MF_EST state.
885 */
886 /* check for contention resoultion */
887 if (dl->tx_hist[0].msg && dl->tx_hist[0].msg->len) {
888 LOGP(DLLAPD, LOGL_NOTICE, "SABM not allowed "
Philipp Maier08177d32016-12-08 17:23:26 +0100889 "during contention resolution (state=%s, dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100890 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +0200891 mdl_error(MDL_CAUSE_SABM_INFO_NOTALL, lctx);
892 }
893 lapd_send_ua(lctx, length, msg->l3h);
894 msgb_free(msg);
895 return 0;
896 }
897 /* save message context for further use */
898 memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
899#ifndef TEST_CONTENT_RESOLUTION_NETWORK
900 /* send UA response */
901 lapd_send_ua(lctx, length, msg->l3h);
902#endif
903 /* set Vs, Vr and Va to 0 */
904 dl->v_send = dl->v_recv = dl->v_ack = 0;
905 /* clear tx_hist */
906 lapd_dl_flush_hist(dl);
907 /* enter multiple-frame-established state */
908 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
909 /* store content resolution data on network side
910 * Note: cont_res will be removed when changing state again,
911 * so it must be allocated AFTER lapd_dl_newstate(). */
912 if (dl->mode == LAPD_MODE_NETWORK && length) {
913 dl->cont_res = lapd_msgb_alloc(length, "CONT RES");
914 memcpy(msgb_put(dl->cont_res, length), msg->l3h,
915 length);
Philipp Maier08177d32016-12-08 17:23:26 +0100916 LOGP(DLLAPD, LOGL_NOTICE,
917 "Store content res. (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200918 }
919 /* send notification to L3 */
920 if (length == 0) {
921 /* 5.4.1.2 Normal establishment procedures */
922 rc = send_dl_simple(prim, op, lctx);
923 msgb_free(msg);
924 } else {
925 /* 5.4.1.4 Contention resolution establishment */
Harald Welte087116a2013-06-18 21:41:34 +0200926 msgb_trim(msg, length);
rootaf48bed2011-09-26 11:23:06 +0200927 rc = send_dl_l3(prim, op, lctx, msg);
928 }
929 break;
930 case LAPD_U_DM:
Philipp Maier08177d32016-12-08 17:23:26 +0100931 LOGP(DLLAPD, LOGL_INFO, "DM received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +0100932 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +0200933 /* G.2.2 Wrong value of the C/R bit */
934 if (lctx->cr == dl->cr.rem2loc.cmd) {
Philipp Maier08177d32016-12-08 17:23:26 +0100935 LOGP(DLLAPD, LOGL_ERROR,
936 "DM command error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200937 msgb_free(msg);
938 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
939 return -EINVAL;
940 }
941 if (!lctx->p_f) {
942 /* 5.4.1.2 DM responses with the F bit set to "0"
943 * shall be ignored.
944 */
945 msgb_free(msg);
946 return 0;
947 }
948 switch (dl->state) {
949 case LAPD_STATE_SABM_SENT:
950 break;
951 case LAPD_STATE_MF_EST:
952 if (lctx->p_f) {
953 LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
Philipp Maier08177d32016-12-08 17:23:26 +0100954 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200955 mdl_error(MDL_CAUSE_UNSOL_DM_RESP, lctx);
956 } else {
957 LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
958 "response, multiple frame established "
Philipp Maier08177d32016-12-08 17:23:26 +0100959 "state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200960 mdl_error(MDL_CAUSE_UNSOL_DM_RESP_MF, lctx);
961 /* reestablish */
962 if (!dl->reestablish) {
963 msgb_free(msg);
964 return 0;
965 }
966 LOGP(DLLAPD, LOGL_NOTICE, "Performing "
Philipp Maier08177d32016-12-08 17:23:26 +0100967 "reestablishment. (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200968 lapd_reestablish(dl);
969 }
970 msgb_free(msg);
971 return 0;
972 case LAPD_STATE_TIMER_RECOV:
973 /* FP = 0 (DM is normal in case PF = 1) */
974 if (!lctx->p_f) {
975 LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
976 "response, multiple frame established "
Philipp Maier08177d32016-12-08 17:23:26 +0100977 "state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200978 mdl_error(MDL_CAUSE_UNSOL_DM_RESP_MF, lctx);
979 msgb_free(msg);
980 /* reestablish */
981 if (!dl->reestablish)
982 return 0;
983 LOGP(DLLAPD, LOGL_NOTICE, "Performing "
Philipp Maier08177d32016-12-08 17:23:26 +0100984 "reestablishment. (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +0200985 return lapd_reestablish(dl);
986 }
987 break;
988 case LAPD_STATE_DISC_SENT:
Andreas Eversberg742fc792011-09-27 09:40:25 +0200989 /* stop Timer T200 */
990 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +0200991 /* go to idle state */
992 lapd_dl_flush_tx(dl);
993 lapd_dl_flush_send(dl);
994 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
995 rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, lctx);
996 msgb_free(msg);
997 return 0;
998 case LAPD_STATE_IDLE:
999 /* 5.4.5 all other frame types shall be discarded */
1000 default:
1001 LOGP(DLLAPD, LOGL_INFO, "unsolicited DM response! "
Philipp Maier08177d32016-12-08 17:23:26 +01001002 "(discarding) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001003 msgb_free(msg);
1004 return 0;
1005 }
Andreas Eversberg742fc792011-09-27 09:40:25 +02001006 /* stop timer T200 */
1007 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001008 /* go to idle state */
1009 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1010 rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION, lctx);
1011 msgb_free(msg);
1012 break;
1013 case LAPD_U_UI:
Philipp Maier08177d32016-12-08 17:23:26 +01001014 LOGP(DLLAPD, LOGL_INFO, "UI received (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001015 /* G.2.2 Wrong value of the C/R bit */
1016 if (lctx->cr == dl->cr.rem2loc.resp) {
Holger Hans Peter Freyther8c012312012-11-26 16:52:23 +01001017 LOGP(DLLAPD, LOGL_ERROR, "UI indicates response "
Philipp Maier08177d32016-12-08 17:23:26 +01001018 "error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001019 msgb_free(msg);
1020 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1021 return -EINVAL;
1022 }
1023
1024 /* G.4.5 If UI is received with L>N201 or with M bit
1025 * set, AN MDL-ERROR-INDICATION is sent to MM.
1026 */
1027 if (length > lctx->n201 || lctx->more) {
Holger Hans Peter Freyther8c012312012-11-26 16:52:23 +01001028 LOGP(DLLAPD, LOGL_ERROR, "UI too large error "
Philipp Maier08177d32016-12-08 17:23:26 +01001029 "(%d > N201(%d) or M=%d) (dl=%p)\n", length,
1030 lctx->n201, lctx->more, dl);
rootaf48bed2011-09-26 11:23:06 +02001031 msgb_free(msg);
1032 mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
1033 return -EIO;
1034 }
1035
1036 /* do some length checks */
1037 if (length == 0) {
1038 /* 5.3.3 UI frames received with the length indicator
1039 * set to "0" shall be ignored
1040 */
Philipp Maier08177d32016-12-08 17:23:26 +01001041 LOGP(DLLAPD, LOGL_INFO,
1042 "length=0 (discarding) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001043 msgb_free(msg);
1044 return 0;
1045 }
Harald Welte087116a2013-06-18 21:41:34 +02001046 msgb_trim(msg, length);
rootaf48bed2011-09-26 11:23:06 +02001047 rc = send_dl_l3(PRIM_DL_UNIT_DATA, PRIM_OP_INDICATION, lctx,
1048 msg);
1049 break;
1050 case LAPD_U_DISC:
1051 prim = PRIM_DL_REL;
1052 op = PRIM_OP_INDICATION;
1053
Philipp Maier08177d32016-12-08 17:23:26 +01001054 LOGP(DLLAPD, LOGL_INFO, "DISC received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +01001055 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +02001056 /* flush tx and send buffers */
1057 lapd_dl_flush_tx(dl);
1058 lapd_dl_flush_send(dl);
1059 /* 5.7.1 */
1060 dl->seq_err_cond = 0;
1061 /* G.2.2 Wrong value of the C/R bit */
1062 if (lctx->cr == dl->cr.rem2loc.resp) {
Philipp Maier08177d32016-12-08 17:23:26 +01001063 LOGP(DLLAPD, LOGL_ERROR,
1064 "DISC response error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001065 msgb_free(msg);
1066 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1067 return -EINVAL;
1068 }
1069 if (length > 0 || lctx->more) {
1070 /* G.4.4 If a DISC or DM frame is received with L>0 or
1071 * with the M bit set to "1", an MDL-ERROR-INDICATION
1072 * primitive with cause "U frame with incorrect
1073 * parameters" is sent to the mobile management entity.
1074 */
Holger Hans Peter Freyther8c012312012-11-26 16:52:23 +01001075 LOGP(DLLAPD, LOGL_ERROR,
Philipp Maier08177d32016-12-08 17:23:26 +01001076 "U frame iwth incorrect parameters (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001077 msgb_free(msg);
1078 mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
1079 return -EIO;
1080 }
1081 switch (dl->state) {
1082 case LAPD_STATE_IDLE:
Philipp Maier08177d32016-12-08 17:23:26 +01001083 LOGP(DLLAPD, LOGL_INFO,
1084 "DISC in idle state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001085 /* send DM with F=P */
1086 msgb_free(msg);
1087 return lapd_send_dm(lctx);
1088 case LAPD_STATE_SABM_SENT:
Philipp Maier08177d32016-12-08 17:23:26 +01001089 LOGP(DLLAPD, LOGL_INFO,
1090 "DISC in SABM state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001091 /* 5.4.6.2 send DM with F=P */
1092 lapd_send_dm(lctx);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001093 /* stop Timer T200 */
1094 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001095 /* go to idle state */
1096 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1097 msgb_free(msg);
1098 return send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION,
1099 lctx);
1100 case LAPD_STATE_MF_EST:
1101 case LAPD_STATE_TIMER_RECOV:
Philipp Maier08177d32016-12-08 17:23:26 +01001102 LOGP(DLLAPD, LOGL_INFO,
1103 "DISC in est state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001104 break;
1105 case LAPD_STATE_DISC_SENT:
Philipp Maier08177d32016-12-08 17:23:26 +01001106 LOGP(DLLAPD, LOGL_INFO,
1107 "DISC in disc state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001108 prim = PRIM_DL_REL;
1109 op = PRIM_OP_CONFIRM;
1110 break;
1111 default:
1112 lapd_send_ua(lctx, length, msg->l3h);
1113 msgb_free(msg);
1114 return 0;
1115 }
1116 /* send UA response */
1117 lapd_send_ua(lctx, length, msg->l3h);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001118 /* stop Timer T200 */
1119 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001120 /* enter idle state, keep tx-buffer with UA response */
1121 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1122 /* send notification to L3 */
1123 rc = send_dl_simple(prim, op, lctx);
1124 msgb_free(msg);
1125 break;
1126 case LAPD_U_UA:
Philipp Maier08177d32016-12-08 17:23:26 +01001127 LOGP(DLLAPD, LOGL_INFO, "UA received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +01001128 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +02001129 /* G.2.2 Wrong value of the C/R bit */
1130 if (lctx->cr == dl->cr.rem2loc.cmd) {
Holger Hans Peter Freyther8c012312012-11-26 16:52:23 +01001131 LOGP(DLLAPD, LOGL_ERROR, "UA indicates command "
Philipp Maier08177d32016-12-08 17:23:26 +01001132 "error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001133 msgb_free(msg);
1134 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1135 return -EINVAL;
1136 }
1137
1138 /* G.4.5 If UA is received with L>N201 or with M bit
1139 * set, AN MDL-ERROR-INDICATION is sent to MM.
1140 */
1141 if (lctx->more || length > lctx->n201) {
Philipp Maier08177d32016-12-08 17:23:26 +01001142 LOGP(DLLAPD, LOGL_ERROR,
1143 "UA too large error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001144 msgb_free(msg);
1145 mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
1146 return -EIO;
1147 }
1148
1149 if (!lctx->p_f) {
1150 /* 5.4.1.2 A UA response with the F bit set to "0"
1151 * shall be ignored.
1152 */
Philipp Maier08177d32016-12-08 17:23:26 +01001153 LOGP(DLLAPD, LOGL_INFO,
1154 "F=0 (discarding) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001155 msgb_free(msg);
1156 return 0;
1157 }
1158 switch (dl->state) {
1159 case LAPD_STATE_SABM_SENT:
1160 break;
1161 case LAPD_STATE_MF_EST:
1162 case LAPD_STATE_TIMER_RECOV:
1163 LOGP(DLLAPD, LOGL_INFO, "unsolicited UA response! "
Philipp Maier08177d32016-12-08 17:23:26 +01001164 "(discarding) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001165 mdl_error(MDL_CAUSE_UNSOL_UA_RESP, lctx);
1166 msgb_free(msg);
1167 return 0;
1168 case LAPD_STATE_DISC_SENT:
Philipp Maier08177d32016-12-08 17:23:26 +01001169 LOGP(DLLAPD, LOGL_INFO,
1170 "UA in disconnect state (dl=%p)\n", dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001171 /* stop Timer T200 */
1172 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001173 /* go to idle state */
1174 lapd_dl_flush_tx(dl);
1175 lapd_dl_flush_send(dl);
1176 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1177 rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, lctx);
1178 msgb_free(msg);
1179 return 0;
1180 case LAPD_STATE_IDLE:
1181 /* 5.4.5 all other frame types shall be discarded */
1182 default:
1183 LOGP(DLLAPD, LOGL_INFO, "unsolicited UA response! "
Philipp Maier08177d32016-12-08 17:23:26 +01001184 "(discarding) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001185 msgb_free(msg);
1186 return 0;
1187 }
Philipp Maier08177d32016-12-08 17:23:26 +01001188 LOGP(DLLAPD, LOGL_INFO, "UA in SABM state (dl=%p)\n", dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001189 /* stop Timer T200 */
1190 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001191 /* compare UA with SABME if contention resolution is applied */
1192 if (dl->tx_hist[0].msg->len) {
1193 if (length != (dl->tx_hist[0].msg->len)
1194 || !!memcmp(dl->tx_hist[0].msg->data, msg->l3h,
1195 length)) {
1196 LOGP(DLLAPD, LOGL_INFO, "**** UA response "
Philipp Maier08177d32016-12-08 17:23:26 +01001197 "mismatches **** (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001198 rc = send_dl_simple(PRIM_DL_REL,
1199 PRIM_OP_INDICATION, lctx);
1200 msgb_free(msg);
1201 /* go to idle state */
1202 lapd_dl_flush_tx(dl);
1203 lapd_dl_flush_send(dl);
1204 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
1205 return 0;
1206 }
1207 }
1208 /* set Vs, Vr and Va to 0 */
1209 dl->v_send = dl->v_recv = dl->v_ack = 0;
1210 /* clear tx_hist */
1211 lapd_dl_flush_hist(dl);
1212 /* enter multiple-frame-established state */
1213 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1214 /* send outstanding frames, if any (resume / reconnect) */
1215 lapd_send_i(lctx, __LINE__);
1216 /* send notification to L3 */
1217 rc = send_dl_simple(PRIM_DL_EST, PRIM_OP_CONFIRM, lctx);
1218 msgb_free(msg);
1219 break;
1220 case LAPD_U_FRMR:
Philipp Maier08177d32016-12-08 17:23:26 +01001221 LOGP(DLLAPD, LOGL_NOTICE,
1222 "Frame reject received (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001223 /* send MDL ERROR INIDCATION to L3 */
1224 mdl_error(MDL_CAUSE_FRMR, lctx);
1225 msgb_free(msg);
1226 /* reestablish */
1227 if (!dl->reestablish)
1228 break;
Philipp Maier08177d32016-12-08 17:23:26 +01001229 LOGP(DLLAPD, LOGL_NOTICE,
1230 "Performing reestablishment. (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001231 rc = lapd_reestablish(dl);
1232 break;
1233 default:
1234 /* G.3.1 */
Philipp Maier08177d32016-12-08 17:23:26 +01001235 LOGP(DLLAPD, LOGL_NOTICE,
1236 "Unnumbered frame not allowed. (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001237 msgb_free(msg);
1238 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1239 return -EINVAL;
1240 }
1241 return rc;
1242}
1243
1244/* Receive a LAPD S (Supervisory) message from L1 */
1245static int lapd_rx_s(struct msgb *msg, struct lapd_msg_ctx *lctx)
1246{
1247 struct lapd_datalink *dl = lctx->dl;
1248 int length = lctx->length;
1249
1250 if (length > 0 || lctx->more) {
1251 /* G.4.3 If a supervisory frame is received with L>0 or
1252 * with the M bit set to "1", an MDL-ERROR-INDICATION
1253 * primitive with cause "S frame with incorrect
1254 * parameters" is sent to the mobile management entity. */
Holger Hans Peter Freyther8c012312012-11-26 16:52:23 +01001255 LOGP(DLLAPD, LOGL_ERROR,
Philipp Maier08177d32016-12-08 17:23:26 +01001256 "S frame with incorrect parameters (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001257 msgb_free(msg);
1258 mdl_error(MDL_CAUSE_SFRM_INC_PARAM, lctx);
1259 return -EIO;
1260 }
1261
1262 if (lctx->cr == dl->cr.rem2loc.resp
1263 && lctx->p_f
1264 && dl->state != LAPD_STATE_TIMER_RECOV) {
1265 /* 5.4.2.2: Inidcate error on supervisory reponse F=1 */
Philipp Maier08177d32016-12-08 17:23:26 +01001266 LOGP(DLLAPD, LOGL_NOTICE,
1267 "S frame response with F=1 error (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001268 mdl_error(MDL_CAUSE_UNSOL_SPRV_RESP, lctx);
1269 }
1270
1271 switch (dl->state) {
1272 case LAPD_STATE_IDLE:
1273 /* if P=1, respond DM with F=1 (5.2.2) */
1274 /* 5.4.5 all other frame types shall be discarded */
1275 if (lctx->p_f)
1276 lapd_send_dm(lctx); /* F=P */
1277 /* fall though */
1278 case LAPD_STATE_SABM_SENT:
1279 case LAPD_STATE_DISC_SENT:
Philipp Maier08177d32016-12-08 17:23:26 +01001280 LOGP(DLLAPD, LOGL_NOTICE,
1281 "S frame ignored in this state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001282 msgb_free(msg);
1283 return 0;
1284 }
1285 switch (lctx->s_u) {
1286 case LAPD_S_RR:
Philipp Maier08177d32016-12-08 17:23:26 +01001287 LOGP(DLLAPD, LOGL_INFO, "RR received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +01001288 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +02001289 /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
1290 lapd_acknowledge(lctx);
1291
1292 /* 5.5.3.2 */
1293 if (lctx->cr == dl->cr.rem2loc.cmd
1294 && lctx->p_f) {
1295 if (!dl->own_busy && !dl->seq_err_cond) {
1296 LOGP(DLLAPD, LOGL_INFO, "RR frame command "
Philipp Maier08177d32016-12-08 17:23:26 +01001297 "with polling bit set and we are not "
1298 "busy, so we reply with RR frame "
1299 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001300 lapd_send_rr(lctx, 1, 0);
1301 /* NOTE: In case of sequence error condition,
1302 * the REJ frame has been transmitted when
1303 * entering the condition, so it has not be
1304 * done here
1305 */
1306 } else if (dl->own_busy) {
1307 LOGP(DLLAPD, LOGL_INFO, "RR frame command "
Philipp Maier08177d32016-12-08 17:23:26 +01001308 "with polling bit set and we are busy, "
1309 "so we reply with RR frame response (dl=%p)\n",
1310 dl);
rootaf48bed2011-09-26 11:23:06 +02001311 lapd_send_rnr(lctx, 1, 0);
1312 }
1313 } else if (lctx->cr == dl->cr.rem2loc.resp
1314 && lctx->p_f
1315 && dl->state == LAPD_STATE_TIMER_RECOV) {
1316 LOGP(DLLAPD, LOGL_INFO, "RR response with F==1, "
1317 "and we are in timer recovery state, so "
Philipp Maier08177d32016-12-08 17:23:26 +01001318 "we leave that state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001319 /* V(S) to the N(R) in the RR frame */
1320 dl->v_send = lctx->n_recv;
Andreas Eversberg742fc792011-09-27 09:40:25 +02001321 /* stop Timer T200 */
1322 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001323 /* 5.5.7 Clear timer recovery condition */
1324 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1325 }
1326 /* Send message, if possible due to acknowledged data */
1327 lapd_send_i(lctx, __LINE__);
1328
1329 break;
1330 case LAPD_S_RNR:
Philipp Maier08177d32016-12-08 17:23:26 +01001331 LOGP(DLLAPD, LOGL_INFO, "RNR received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +01001332 lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +02001333 /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
1334 lapd_acknowledge(lctx);
1335
1336 /* 5.5.5 */
1337 /* Set peer receiver busy condition */
1338 dl->peer_busy = 1;
1339
1340 if (lctx->p_f) {
1341 if (lctx->cr == dl->cr.rem2loc.cmd) {
1342 if (!dl->own_busy) {
1343 LOGP(DLLAPD, LOGL_INFO, "RNR poll "
1344 "command and we are not busy, "
1345 "so we reply with RR final "
Philipp Maier08177d32016-12-08 17:23:26 +01001346 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001347 /* Send RR with F=1 */
1348 lapd_send_rr(lctx, 1, 0);
1349 } else {
1350 LOGP(DLLAPD, LOGL_INFO, "RNR poll "
1351 "command and we are busy, so "
1352 "we reply with RNR final "
Philipp Maier08177d32016-12-08 17:23:26 +01001353 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001354 /* Send RNR with F=1 */
1355 lapd_send_rnr(lctx, 1, 0);
1356 }
1357 } else if (dl->state == LAPD_STATE_TIMER_RECOV) {
1358 LOGP(DLLAPD, LOGL_INFO, "RNR poll response "
1359 "and we in timer recovery state, so "
Philipp Maier08177d32016-12-08 17:23:26 +01001360 "we leave that state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001361 /* 5.5.7 Clear timer recovery condition */
1362 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1363 /* V(S) to the N(R) in the RNR frame */
1364 dl->v_send = lctx->n_recv;
1365 }
1366 } else
1367 LOGP(DLLAPD, LOGL_INFO, "RNR not polling/final state "
Philipp Maier08177d32016-12-08 17:23:26 +01001368 "received (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001369
1370 /* Send message, if possible due to acknowledged data */
1371 lapd_send_i(lctx, __LINE__);
1372
1373 break;
1374 case LAPD_S_REJ:
Philipp Maier08177d32016-12-08 17:23:26 +01001375 LOGP(DLLAPD, LOGL_INFO, "REJ received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +01001376 lapd_state_name(dl->state), dl);
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.4.1 */
1381 if (dl->state != LAPD_STATE_TIMER_RECOV) {
1382 /* Clear an existing peer receiver busy condition */
1383 dl->peer_busy = 0;
1384 /* V(S) and V(A) to the N(R) in the REJ frame */
1385 dl->v_send = dl->v_ack = lctx->n_recv;
Andreas Eversberg742fc792011-09-27 09:40:25 +02001386 /* stop Timer T200 */
1387 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001388 /* 5.5.3.2 */
1389 if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
1390 if (!dl->own_busy && !dl->seq_err_cond) {
1391 LOGP(DLLAPD, LOGL_INFO, "REJ poll "
1392 "command not in timer recovery "
1393 "state and not in own busy "
1394 "condition received, so we "
1395 "respond with RR final "
Philipp Maier08177d32016-12-08 17:23:26 +01001396 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001397 lapd_send_rr(lctx, 1, 0);
1398 /* NOTE: In case of sequence error
1399 * condition, the REJ frame has been
1400 * transmitted when entering the
1401 * condition, so it has not be done
1402 * here
1403 */
1404 } else if (dl->own_busy) {
1405 LOGP(DLLAPD, LOGL_INFO, "REJ poll "
1406 "command not in timer recovery "
1407 "state and in own busy "
1408 "condition received, so we "
1409 "respond with RNR final "
Philipp Maier08177d32016-12-08 17:23:26 +01001410 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001411 lapd_send_rnr(lctx, 1, 0);
1412 }
1413 } else
1414 LOGP(DLLAPD, LOGL_INFO, "REJ response or not "
1415 "polling command not in timer recovery "
Philipp Maier08177d32016-12-08 17:23:26 +01001416 "state received (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001417 /* send MDL ERROR INIDCATION to L3 */
1418 if (lctx->cr == dl->cr.rem2loc.resp && lctx->p_f) {
Philipp Maier08177d32016-12-08 17:23:26 +01001419 LOGP(DLLAPD, LOGL_ERROR,
1420 "unsolicited supervisory response! (dl=%p)\n",
1421 dl);
rootaf48bed2011-09-26 11:23:06 +02001422 mdl_error(MDL_CAUSE_UNSOL_SPRV_RESP, lctx);
1423 }
1424
1425 } else if (lctx->cr == dl->cr.rem2loc.resp && lctx->p_f) {
1426 LOGP(DLLAPD, LOGL_INFO, "REJ poll response in timer "
Philipp Maier08177d32016-12-08 17:23:26 +01001427 "recovery state received (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001428 /* Clear an existing peer receiver busy condition */
1429 dl->peer_busy = 0;
1430 /* V(S) and V(A) to the N(R) in the REJ frame */
1431 dl->v_send = dl->v_ack = lctx->n_recv;
Andreas Eversberg742fc792011-09-27 09:40:25 +02001432 /* stop Timer T200 */
1433 lapd_stop_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001434 /* 5.5.7 Clear timer recovery condition */
1435 lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
1436 } else {
1437 /* Clear an existing peer receiver busy condition */
1438 dl->peer_busy = 0;
1439 /* V(S) and V(A) to the N(R) in the REJ frame */
1440 dl->v_send = dl->v_ack = lctx->n_recv;
1441 /* 5.5.3.2 */
1442 if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
1443 if (!dl->own_busy && !dl->seq_err_cond) {
1444 LOGP(DLLAPD, LOGL_INFO, "REJ poll "
1445 "command in timer recovery "
1446 "state and not in own busy "
1447 "condition received, so we "
1448 "respond with RR final "
Philipp Maier08177d32016-12-08 17:23:26 +01001449 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001450 lapd_send_rr(lctx, 1, 0);
1451 /* NOTE: In case of sequence error
1452 * condition, the REJ frame has been
1453 * transmitted when entering the
1454 * condition, so it has not be done
1455 * here
1456 */
1457 } else if (dl->own_busy) {
1458 LOGP(DLLAPD, LOGL_INFO, "REJ poll "
1459 "command in timer recovery "
1460 "state and in own busy "
1461 "condition received, so we "
1462 "respond with RNR final "
Philipp Maier08177d32016-12-08 17:23:26 +01001463 "response (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001464 lapd_send_rnr(lctx, 1, 0);
1465 }
1466 } else
1467 LOGP(DLLAPD, LOGL_INFO, "REJ response or not "
1468 "polling command in timer recovery "
Philipp Maier08177d32016-12-08 17:23:26 +01001469 "state received (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001470 }
1471
1472 /* FIXME: 5.5.4.2 2) */
1473
1474 /* Send message, if possible due to acknowledged data */
1475 lapd_send_i(lctx, __LINE__);
1476
1477 break;
1478 default:
1479 /* G.3.1 */
Philipp Maier08177d32016-12-08 17:23:26 +01001480 LOGP(DLLAPD, LOGL_ERROR,
1481 "Supervisory frame not allowed. (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001482 msgb_free(msg);
1483 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1484 return -EINVAL;
1485 }
1486 msgb_free(msg);
1487 return 0;
1488}
1489
1490/* Receive a LAPD I (Information) message from L1 */
1491static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx)
1492{
1493 struct lapd_datalink *dl = lctx->dl;
1494 //uint8_t nr = lctx->n_recv;
1495 uint8_t ns = lctx->n_send;
1496 int length = lctx->length;
1497 int rc;
1498
Philipp Maier08177d32016-12-08 17:23:26 +01001499 LOGP(DLLAPD, LOGL_INFO, "I received in state %s on SAPI(%u) (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +01001500 lapd_state_name(dl->state), lctx->sapi, dl);
rootaf48bed2011-09-26 11:23:06 +02001501
1502 /* G.2.2 Wrong value of the C/R bit */
1503 if (lctx->cr == dl->cr.rem2loc.resp) {
Philipp Maier08177d32016-12-08 17:23:26 +01001504 LOGP(DLLAPD, LOGL_ERROR,
1505 "I frame response not allowed (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001506 msgb_free(msg);
1507 mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
1508 return -EINVAL;
1509 }
1510
1511 if (length == 0 || length > lctx->n201) {
1512 /* G.4.2 If the length indicator of an I frame is set
1513 * to a numerical value L>N201 or L=0, an MDL-ERROR-INDICATION
1514 * primitive with cause "I frame with incorrect length"
1515 * is sent to the mobile management entity. */
Philipp Maier08177d32016-12-08 17:23:26 +01001516 LOGP(DLLAPD, LOGL_ERROR,
1517 "I frame length not allowed (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001518 msgb_free(msg);
1519 mdl_error(MDL_CAUSE_IFRM_INC_LEN, lctx);
1520 return -EIO;
1521 }
1522
1523 /* G.4.2 If the numerical value of L is L<N201 and the M
1524 * bit is set to "1", then an MDL-ERROR-INDICATION primitive with
1525 * cause "I frame with incorrect use of M bit" is sent to the
1526 * mobile management entity. */
1527 if (lctx->more && length < lctx->n201) {
Philipp Maier08177d32016-12-08 17:23:26 +01001528 LOGP(DLLAPD, LOGL_ERROR,
1529 "I frame with M bit too short (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001530 msgb_free(msg);
1531 mdl_error(MDL_CAUSE_IFRM_INC_MBITS, lctx);
1532 return -EIO;
1533 }
1534
1535 switch (dl->state) {
1536 case LAPD_STATE_IDLE:
1537 /* if P=1, respond DM with F=1 (5.2.2) */
1538 /* 5.4.5 all other frame types shall be discarded */
1539 if (lctx->p_f)
1540 lapd_send_dm(lctx); /* F=P */
1541 /* fall though */
1542 case LAPD_STATE_SABM_SENT:
1543 case LAPD_STATE_DISC_SENT:
Philipp Maier08177d32016-12-08 17:23:26 +01001544 LOGP(DLLAPD, LOGL_NOTICE,
1545 "I frame ignored in this state (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001546 msgb_free(msg);
1547 return 0;
1548 }
1549
1550 /* 5.7.1: N(s) sequence error */
1551 if (ns != dl->v_recv) {
1552 LOGP(DLLAPD, LOGL_NOTICE, "N(S) sequence error: N(S)=%u, "
Philipp Maier08177d32016-12-08 17:23:26 +01001553 "V(R)=%u (dl=%p)\n", ns, dl->v_recv, dl);
rootaf48bed2011-09-26 11:23:06 +02001554 /* discard data */
1555 msgb_free(msg);
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001556 if (dl->seq_err_cond != 1) {
rootaf48bed2011-09-26 11:23:06 +02001557 /* FIXME: help me understand what exactly todo here
rootaf48bed2011-09-26 11:23:06 +02001558 */
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001559 dl->seq_err_cond = 1;
rootaf48bed2011-09-26 11:23:06 +02001560 lapd_send_rej(lctx, lctx->p_f);
1561 } else {
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001562 /* If there are two subsequent sequence errors received,
1563 * ignore it. (Ignore every second subsequent error.)
1564 * This happens if our reply with the REJ is too slow,
1565 * so the remote gets a T200 timeout and sends another
1566 * frame with a sequence error.
1567 * Test showed that replying with two subsequent REJ
1568 * messages could the remote L2 process to abort.
1569 * Replying too slow shouldn't happen, but may happen
1570 * over serial link between BB and LAPD.
1571 */
1572 dl->seq_err_cond = 2;
rootaf48bed2011-09-26 11:23:06 +02001573 }
Andreas.Eversberg301f01e2012-01-10 13:02:01 +01001574 /* Even if N(s) sequence error, acknowledge to N(R)-1 */
1575 /* 5.5.3.1: Acknowlege all transmitted frames up the N(R)-1 */
1576 lapd_acknowledge(lctx); /* V(A) is also set here */
1577
1578 /* Send message, if possible due to acknowledged data */
1579 lapd_send_i(lctx, __LINE__);
1580
1581 return 0;
rootaf48bed2011-09-26 11:23:06 +02001582 }
1583 dl->seq_err_cond = 0;
1584
1585 /* Increment receiver state */
1586 dl->v_recv = inc_mod(dl->v_recv, dl->v_range);
Philipp Maier08177d32016-12-08 17:23:26 +01001587 LOGP(DLLAPD, LOGL_INFO, "incrementing V(R) to %u (dl=%p)\n",
1588 dl->v_recv, dl);
rootaf48bed2011-09-26 11:23:06 +02001589
1590 /* 5.5.3.1: Acknowlege all transmitted frames up the the N(R)-1 */
1591 lapd_acknowledge(lctx); /* V(A) is also set here */
1592
1593 /* Only if we are not in own receiver busy condition */
1594 if (!dl->own_busy) {
1595 /* if the frame carries a complete segment */
1596 if (!lctx->more && !dl->rcv_buffer) {
Philipp Maier08177d32016-12-08 17:23:26 +01001597 LOGP(DLLAPD, LOGL_INFO,
1598 "message in single I frame (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001599 /* send a DATA INDICATION to L3 */
Harald Welte087116a2013-06-18 21:41:34 +02001600 msgb_trim(msg, length);
rootaf48bed2011-09-26 11:23:06 +02001601 rc = send_dl_l3(PRIM_DL_DATA, PRIM_OP_INDICATION, lctx,
1602 msg);
1603 } else {
1604 /* create rcv_buffer */
1605 if (!dl->rcv_buffer) {
1606 LOGP(DLLAPD, LOGL_INFO, "message in multiple "
Philipp Maier08177d32016-12-08 17:23:26 +01001607 "I frames (first message) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001608 dl->rcv_buffer = lapd_msgb_alloc(dl->maxf,
1609 "LAPD RX");
1610 dl->rcv_buffer->l3h = dl->rcv_buffer->data;
1611 }
1612 /* concat. rcv_buffer */
1613 if (msgb_l3len(dl->rcv_buffer) + length > dl->maxf) {
1614 LOGP(DLLAPD, LOGL_NOTICE, "Received frame "
Philipp Maier08177d32016-12-08 17:23:26 +01001615 "overflow! (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001616 } else {
1617 memcpy(msgb_put(dl->rcv_buffer, length),
1618 msg->l3h, length);
1619 }
1620 /* if the last segment was received */
1621 if (!lctx->more) {
1622 LOGP(DLLAPD, LOGL_INFO, "message in multiple "
Philipp Maier08177d32016-12-08 17:23:26 +01001623 "I frames (last message) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001624 rc = send_dl_l3(PRIM_DL_DATA,
1625 PRIM_OP_INDICATION, lctx,
1626 dl->rcv_buffer);
1627 dl->rcv_buffer = NULL;
1628 } else
1629 LOGP(DLLAPD, LOGL_INFO, "message in multiple "
Philipp Maier08177d32016-12-08 17:23:26 +01001630 "I frames (next message) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001631 msgb_free(msg);
1632
1633 }
1634 } else
1635 LOGP(DLLAPD, LOGL_INFO, "I frame ignored during own receiver "
1636 "busy condition\n");
1637
1638 /* Check for P bit */
1639 if (lctx->p_f) {
1640 /* 5.5.2.1 */
1641 /* check if we are not in own receiver busy */
1642 if (!dl->own_busy) {
Philipp Maier08177d32016-12-08 17:23:26 +01001643 LOGP(DLLAPD, LOGL_INFO,
1644 "we are not busy, send RR (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001645 /* Send RR with F=1 */
1646 rc = lapd_send_rr(lctx, 1, 0);
1647 } else {
Philipp Maier08177d32016-12-08 17:23:26 +01001648 LOGP(DLLAPD, LOGL_INFO,
1649 "we are busy, send RNR (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001650 /* Send RNR with F=1 */
1651 rc = lapd_send_rnr(lctx, 1, 0);
1652 }
1653 } else {
1654 /* 5.5.2.2 */
1655 /* check if we are not in own receiver busy */
1656 if (!dl->own_busy) {
1657 /* NOTE: V(R) is already set above */
1658 rc = lapd_send_i(lctx, __LINE__);
Daniel Willmann3dc4e162014-03-20 19:24:48 +01001659
1660 /* if update_pending_iframe returns 0 it updated
1661 * the lapd header of an iframe in the tx queue */
1662 if (rc && dl->update_pending_frames)
1663 rc = dl->update_pending_frames(lctx);
1664
rootaf48bed2011-09-26 11:23:06 +02001665 if (rc) {
1666 LOGP(DLLAPD, LOGL_INFO, "we are not busy and "
Philipp Maier08177d32016-12-08 17:23:26 +01001667 "have no pending data, send RR (dl=%p)\n",
1668 dl);
rootaf48bed2011-09-26 11:23:06 +02001669 /* Send RR with F=0 */
1670 return lapd_send_rr(lctx, 0, 0);
1671 }
1672 /* all I or one RR is sent, we are done */
1673 return 0;
1674 } else {
Philipp Maier08177d32016-12-08 17:23:26 +01001675 LOGP(DLLAPD, LOGL_INFO,
1676 "we are busy, send RNR (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001677 /* Send RNR with F=0 */
1678 rc = lapd_send_rnr(lctx, 0, 0);
1679 }
1680 }
1681
1682 /* Send message, if possible due to acknowledged data */
1683 lapd_send_i(lctx, __LINE__);
1684
1685 return rc;
1686}
1687
1688/* Receive a LAPD message from L1 */
1689int lapd_ph_data_ind(struct msgb *msg, struct lapd_msg_ctx *lctx)
1690{
1691 int rc;
1692
1693 switch (lctx->format) {
1694 case LAPD_FORM_U:
1695 rc = lapd_rx_u(msg, lctx);
1696 break;
1697 case LAPD_FORM_S:
1698 rc = lapd_rx_s(msg, lctx);
1699 break;
1700 case LAPD_FORM_I:
1701 rc = lapd_rx_i(msg, lctx);
1702 break;
1703 default:
Philipp Maier08177d32016-12-08 17:23:26 +01001704 LOGP(DLLAPD, LOGL_NOTICE,
1705 "unknown LAPD format (dl=%p)\n", lctx->dl);
rootaf48bed2011-09-26 11:23:06 +02001706 msgb_free(msg);
1707 rc = -EINVAL;
1708 }
1709 return rc;
1710}
1711
1712/* L3 -> L2 */
1713
1714/* send unit data */
1715static int lapd_udata_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1716{
1717 struct lapd_datalink *dl = lctx->dl;
1718 struct msgb *msg = dp->oph.msg;
1719 struct lapd_msg_ctx nctx;
1720
1721 memcpy(&nctx, lctx, sizeof(nctx));
1722 /* keep nctx.ldp */
1723 /* keep nctx.sapi */
1724 /* keep nctx.tei */
1725 nctx.cr = dl->cr.loc2rem.cmd;
1726 nctx.format = LAPD_FORM_U;
1727 nctx.s_u = LAPD_U_UI;
1728 /* keep nctx.p_f */
1729 nctx.length = msg->len;
1730 nctx.more = 0;
1731
1732 return dl->send_ph_data_req(&nctx, msg);
1733}
1734
1735/* request link establishment */
1736static int lapd_est_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1737{
1738 struct lapd_datalink *dl = lctx->dl;
1739 struct msgb *msg = dp->oph.msg;
1740 struct lapd_msg_ctx nctx;
1741
1742 if (msg->len)
1743 LOGP(DLLAPD, LOGL_INFO, "perform establishment with content "
Philipp Maier08177d32016-12-08 17:23:26 +01001744 "(SABM) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001745 else
Philipp Maier08177d32016-12-08 17:23:26 +01001746 LOGP(DLLAPD, LOGL_INFO,
1747 "perform normal establishm. (SABM), (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001748
1749 /* Flush send-queue */
1750 /* Clear send-buffer */
1751 lapd_dl_flush_send(dl);
1752 /* be sure that history is empty */
1753 lapd_dl_flush_hist(dl);
1754
1755 /* save message context for further use */
1756 memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
1757
1758 /* Discard partly received L3 message */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +02001759 msgb_free(dl->rcv_buffer);
1760 dl->rcv_buffer = NULL;
rootaf48bed2011-09-26 11:23:06 +02001761
1762 /* assemble message */
1763 memcpy(&nctx, &dl->lctx, sizeof(nctx));
1764 /* keep nctx.ldp */
1765 /* keep nctx.sapi */
1766 /* keep nctx.tei */
1767 nctx.cr = dl->cr.loc2rem.cmd;
1768 nctx.format = LAPD_FORM_U;
1769 nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
1770 nctx.p_f = 1;
1771 nctx.length = msg->len;
1772 nctx.more = 0;
1773
1774 /* Transmit-buffer carries exactly one segment */
1775 dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
1776 msgb_put(dl->tx_hist[0].msg, msg->len);
1777 if (msg->len)
1778 memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
1779 dl->tx_hist[0].more = 0;
1780 /* set Vs to 0, because it is used as index when resending SABM */
1781 dl->v_send = 0;
1782
1783 /* Set states */
1784 dl->own_busy = dl->peer_busy = 0;
1785 dl->retrans_ctr = 0;
1786 lapd_dl_newstate(dl, LAPD_STATE_SABM_SENT);
1787
1788 /* Tramsmit and start T200 */
1789 dl->send_ph_data_req(&nctx, msg);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001790 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02001791
1792 return 0;
1793}
1794
1795/* send data */
1796static int lapd_data_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
1797{
1798 struct lapd_datalink *dl = lctx->dl;
1799 struct msgb *msg = dp->oph.msg;
1800
Holger Hans Peter Freyther90656db2012-01-13 05:49:29 +08001801 if (msgb_l3len(msg) == 0) {
1802 LOGP(DLLAPD, LOGL_ERROR,
Philipp Maier08177d32016-12-08 17:23:26 +01001803 "writing an empty message is not possible. (dl=%p)\n", dl);
Holger Hans Peter Freyther90656db2012-01-13 05:49:29 +08001804 msgb_free(msg);
1805 return -1;
1806 }
1807
Holger Hans Peter Freyther6ecafef2012-01-13 05:46:26 +08001808 LOGP(DLLAPD, LOGL_INFO,
Philipp Maier08177d32016-12-08 17:23:26 +01001809 "writing message to send-queue: l3len: %d (dl=%p)\n",
1810 msgb_l3len(msg), dl);
rootaf48bed2011-09-26 11:23:06 +02001811
1812 /* Write data into the send queue */
1813 msgb_enqueue(&dl->send_queue, msg);
1814
1815 /* Send message, if possible */
1816 lapd_send_i(&dl->lctx, __LINE__);
1817
1818 return 0;
1819}
1820
1821/* Send next I frame from queued/buffered data */
1822static int lapd_send_i(struct lapd_msg_ctx *lctx, int line)
1823{
1824 struct lapd_datalink *dl = lctx->dl;
1825 uint8_t k = dl->k;
1826 uint8_t h;
1827 struct msgb *msg;
1828 int length, left;
1829 int rc = - 1; /* we sent nothing */
1830 struct lapd_msg_ctx nctx;
1831
1832
Philipp Maier08177d32016-12-08 17:23:26 +01001833 LOGP(DLLAPD, LOGL_INFO,
1834 "%s() called from line %d (dl=%p)\n", __func__, line, dl);
rootaf48bed2011-09-26 11:23:06 +02001835
1836 next_frame:
1837
1838 if (dl->peer_busy) {
Philipp Maier08177d32016-12-08 17:23:26 +01001839 LOGP(DLLAPD, LOGL_INFO, "peer busy, not sending (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001840 return rc;
1841 }
1842
1843 if (dl->state == LAPD_STATE_TIMER_RECOV) {
Philipp Maier08177d32016-12-08 17:23:26 +01001844 LOGP(DLLAPD, LOGL_INFO,
1845 "timer recovery, not sending (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001846 return rc;
1847 }
1848
1849 /* If the send state variable V(S) is equal to V(A) plus k
1850 * (where k is the maximum number of outstanding I frames - see
1851 * subclause 5.8.4), the data link layer entity shall not transmit any
1852 * new I frames, but shall retransmit an I frame as a result
1853 * of the error recovery procedures as described in subclauses 5.5.4 and
1854 * 5.5.7. */
1855 if (dl->v_send == add_mod(dl->v_ack, k, dl->v_range)) {
1856 LOGP(DLLAPD, LOGL_INFO, "k frames outstanding, not sending "
Philipp Maier08177d32016-12-08 17:23:26 +01001857 "more (k=%u V(S)=%u V(A)=%u) (dl=%p)\n", k, dl->v_send,
1858 dl->v_ack, dl);
rootaf48bed2011-09-26 11:23:06 +02001859 return rc;
1860 }
1861
1862 h = do_mod(dl->v_send, dl->range_hist);
1863
1864 /* if we have no tx_hist yet, we create it */
1865 if (!dl->tx_hist[h].msg) {
1866 /* Get next message into send-buffer, if any */
1867 if (!dl->send_buffer) {
1868 next_message:
1869 dl->send_out = 0;
1870 dl->send_buffer = msgb_dequeue(&dl->send_queue);
1871 /* No more data to be sent */
1872 if (!dl->send_buffer)
1873 return rc;
1874 LOGP(DLLAPD, LOGL_INFO, "get message from "
Philipp Maier08177d32016-12-08 17:23:26 +01001875 "send-queue (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001876 }
1877
1878 /* How much is left in the send-buffer? */
1879 left = msgb_l3len(dl->send_buffer) - dl->send_out;
1880 /* Segment, if data exceeds N201 */
1881 length = left;
1882 if (length > lctx->n201)
1883 length = lctx->n201;
1884 LOGP(DLLAPD, LOGL_INFO, "msg-len %d sent %d left %d N201 %d "
Philipp Maier08177d32016-12-08 17:23:26 +01001885 "length %d first byte %02x (dl=%p)\n",
rootaf48bed2011-09-26 11:23:06 +02001886 msgb_l3len(dl->send_buffer), dl->send_out, left,
Philipp Maier08177d32016-12-08 17:23:26 +01001887 lctx->n201, length, dl->send_buffer->l3h[0], dl);
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
Philipp Maier08177d32016-12-08 17:23:26 +01001895 LOGP(DLLAPD, LOGL_INFO, "send I frame %sV(S)=%d (dl=%p)\n",
1896 (left > length) ? "segment " : "", dl->v_send, dl);
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 {
1928 LOGP(DLLAPD, LOGL_INFO, "resend I frame from tx buffer "
Philipp Maier08177d32016-12-08 17:23:26 +01001929 "V(S)=%d (dl=%p)\n", dl->v_send, dl);
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
Philipp Maier08177d32016-12-08 17:23:26 +01001977 LOGP(DLLAPD, LOGL_INFO, "perform suspension (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001978
1979 /* put back the send-buffer to the send-queue (first position) */
1980 if (dl->send_buffer) {
1981 LOGP(DLLAPD, LOGL_INFO, "put frame in sendbuffer back to "
Philipp Maier08177d32016-12-08 17:23:26 +01001982 "queue (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001983 llist_add(&dl->send_buffer->list, &dl->send_queue);
1984 dl->send_buffer = NULL;
1985 } else
Philipp Maier08177d32016-12-08 17:23:26 +01001986 LOGP(DLLAPD, LOGL_INFO, "no frame in sendbuffer (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02001987
1988 /* Clear transmit buffer, but keep send buffer */
1989 lapd_dl_flush_tx(dl);
Andreas Eversberg742fc792011-09-27 09:40:25 +02001990 /* Stop timers (there is no state change, so we must stop all timers */
1991 lapd_stop_t200(dl);
1992 lapd_stop_t203(dl);
rootaf48bed2011-09-26 11:23:06 +02001993
1994 msgb_free(msg);
1995
1996 return send_dl_simple(PRIM_DL_SUSP, PRIM_OP_CONFIRM, &dl->lctx);
1997}
1998
Neels Hofmeyr9e57a5a2015-12-21 11:20:14 +01001999/* request, resume or reconnect of link */
rootaf48bed2011-09-26 11:23:06 +02002000static int lapd_res_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
2001{
2002 struct lapd_datalink *dl = lctx->dl;
2003 struct msgb *msg = dp->oph.msg;
2004 struct lapd_msg_ctx nctx;
2005
Philipp Maier08177d32016-12-08 17:23:26 +01002006 LOGP(DLLAPD, LOGL_INFO,
2007 "perform re-establishment (SABM) length=%d (dl=%p)\n",
2008 msg->len, dl);
rootaf48bed2011-09-26 11:23:06 +02002009
2010 /* be sure that history is empty */
2011 lapd_dl_flush_hist(dl);
2012
2013 /* save message context for further use */
2014 memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
2015
2016 /* Replace message in the send-buffer (reconnect) */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +02002017 msgb_free(dl->send_buffer);
2018 dl->send_buffer = NULL;
2019
rootaf48bed2011-09-26 11:23:06 +02002020 dl->send_out = 0;
Andreas Eversbergcad54b82013-07-09 20:25:24 +02002021 if (msg->len) {
rootaf48bed2011-09-26 11:23:06 +02002022 /* Write data into the send buffer, to be sent first */
2023 dl->send_buffer = msg;
Andreas Eversbergcad54b82013-07-09 20:25:24 +02002024 } else {
2025 msgb_free(msg);
2026 msg = NULL;
Andreas Eversberg5ad4ac82011-11-01 09:40:21 +01002027 dl->send_buffer = NULL;
Andreas Eversbergcad54b82013-07-09 20:25:24 +02002028 }
rootaf48bed2011-09-26 11:23:06 +02002029
2030 /* Discard partly received L3 message */
Holger Hans Peter Freyther9b037a62013-07-11 08:17:02 +02002031 msgb_free(dl->rcv_buffer);
2032 dl->rcv_buffer = NULL;
rootaf48bed2011-09-26 11:23:06 +02002033
2034 /* Create new msgb (old one is now free) */
2035 msg = lapd_msgb_alloc(0, "LAPD SABM");
2036 msg->l3h = msg->data;
2037 /* assemble message */
2038 memcpy(&nctx, &dl->lctx, sizeof(nctx));
2039 /* keep nctx.ldp */
2040 /* keep nctx.sapi */
2041 /* keep nctx.tei */
2042 nctx.cr = dl->cr.loc2rem.cmd;
2043 nctx.format = LAPD_FORM_U;
2044 nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
2045 nctx.p_f = 1;
2046 nctx.length = 0;
2047 nctx.more = 0;
2048
2049 dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
2050 msgb_put(dl->tx_hist[0].msg, msg->len);
2051 if (msg->len)
2052 memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
2053 dl->tx_hist[0].more = 0;
2054 /* set Vs to 0, because it is used as index when resending SABM */
2055 dl->v_send = 0;
2056
2057 /* Set states */
2058 dl->own_busy = dl->peer_busy = 0;
2059 dl->retrans_ctr = 0;
2060 lapd_dl_newstate(dl, LAPD_STATE_SABM_SENT);
2061
2062 /* Tramsmit and start T200 */
2063 dl->send_ph_data_req(&nctx, msg);
Andreas Eversberg742fc792011-09-27 09:40:25 +02002064 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02002065
2066 return 0;
2067}
2068
2069/* requesst release of link */
2070static int lapd_rel_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
2071{
2072 struct lapd_datalink *dl = lctx->dl;
2073 struct msgb *msg = dp->oph.msg;
2074 struct lapd_msg_ctx nctx;
2075
2076 /* local release */
2077 if (dp->u.rel_req.mode) {
Philipp Maier08177d32016-12-08 17:23:26 +01002078 LOGP(DLLAPD, LOGL_INFO, "perform local release (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02002079 msgb_free(msg);
Andreas Eversberg742fc792011-09-27 09:40:25 +02002080 /* stop Timer T200 */
2081 lapd_stop_t200(dl);
2082 /* enter idle state, T203 is stopped here, if running */
rootaf48bed2011-09-26 11:23:06 +02002083 lapd_dl_newstate(dl, LAPD_STATE_IDLE);
2084 /* flush buffers */
2085 lapd_dl_flush_tx(dl);
2086 lapd_dl_flush_send(dl);
2087 /* send notification to L3 */
2088 return send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
2089 }
2090
2091 /* in case we are already disconnecting */
2092 if (dl->state == LAPD_STATE_DISC_SENT)
2093 return -EBUSY;
2094
2095 /* flush tx_hist */
2096 lapd_dl_flush_hist(dl);
2097
Philipp Maier08177d32016-12-08 17:23:26 +01002098 LOGP(DLLAPD, LOGL_INFO, "perform normal release (DISC) (dl=%p)\n", dl);
rootaf48bed2011-09-26 11:23:06 +02002099
2100 /* Push LAPD header on msgb */
2101 /* assemble message */
2102 memcpy(&nctx, &dl->lctx, sizeof(nctx));
2103 /* keep nctx.ldp */
2104 /* keep nctx.sapi */
2105 /* keep nctx.tei */
2106 nctx.cr = dl->cr.loc2rem.cmd;
2107 nctx.format = LAPD_FORM_U;
2108 nctx.s_u = LAPD_U_DISC;
2109 nctx.p_f = 1;
2110 nctx.length = 0;
2111 nctx.more = 0;
2112
2113 dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
2114 msgb_put(dl->tx_hist[0].msg, msg->len);
2115 if (msg->len)
2116 memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
2117 dl->tx_hist[0].more = 0;
2118 /* set Vs to 0, because it is used as index when resending DISC */
2119 dl->v_send = 0;
2120
2121 /* Set states */
2122 dl->own_busy = dl->peer_busy = 0;
2123 dl->retrans_ctr = 0;
2124 lapd_dl_newstate(dl, LAPD_STATE_DISC_SENT);
2125
2126 /* Tramsmit and start T200 */
2127 dl->send_ph_data_req(&nctx, msg);
Andreas Eversberg742fc792011-09-27 09:40:25 +02002128 lapd_start_t200(dl);
rootaf48bed2011-09-26 11:23:06 +02002129
2130 return 0;
2131}
2132
2133/* request release of link in idle state */
2134static int lapd_rel_req_idle(struct osmo_dlsap_prim *dp,
2135 struct lapd_msg_ctx *lctx)
2136{
2137 struct lapd_datalink *dl = lctx->dl;
2138 struct msgb *msg = dp->oph.msg;
2139
2140 msgb_free(msg);
2141
2142 /* send notification to L3 */
2143 return send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
2144}
2145
2146/* statefull handling for DL SAP messages from L3 */
Holger Hans Peter Freyther579fb092012-11-22 10:54:23 +01002147static const struct l2downstate {
rootaf48bed2011-09-26 11:23:06 +02002148 uint32_t states;
2149 int prim, op;
2150 const char *name;
2151 int (*rout) (struct osmo_dlsap_prim *dp,
2152 struct lapd_msg_ctx *lctx);
2153} l2downstatelist[] = {
2154 /* create and send UI command */
2155 {ALL_STATES,
2156 PRIM_DL_UNIT_DATA, PRIM_OP_REQUEST,
2157 "DL-UNIT-DATA-REQUEST", lapd_udata_req},
2158
2159 /* create and send SABM command */
2160 {SBIT(LAPD_STATE_IDLE),
2161 PRIM_DL_EST, PRIM_OP_REQUEST,
2162 "DL-ESTABLISH-REQUEST", lapd_est_req},
2163
2164 /* create and send I command */
2165 {SBIT(LAPD_STATE_MF_EST) |
2166 SBIT(LAPD_STATE_TIMER_RECOV),
2167 PRIM_DL_DATA, PRIM_OP_REQUEST,
2168 "DL-DATA-REQUEST", lapd_data_req},
2169
2170 /* suspend datalink */
2171 {SBIT(LAPD_STATE_MF_EST) |
2172 SBIT(LAPD_STATE_TIMER_RECOV),
2173 PRIM_DL_SUSP, PRIM_OP_REQUEST,
2174 "DL-SUSPEND-REQUEST", lapd_susp_req},
2175
2176 /* create and send SABM command (resume) */
2177 {SBIT(LAPD_STATE_MF_EST) |
2178 SBIT(LAPD_STATE_TIMER_RECOV),
2179 PRIM_DL_RES, PRIM_OP_REQUEST,
2180 "DL-RESUME-REQUEST", lapd_res_req},
2181
2182 /* create and send SABM command (reconnect) */
2183 {SBIT(LAPD_STATE_IDLE) |
2184 SBIT(LAPD_STATE_MF_EST) |
2185 SBIT(LAPD_STATE_TIMER_RECOV),
2186 PRIM_DL_RECON, PRIM_OP_REQUEST,
2187 "DL-RECONNECT-REQUEST", lapd_res_req},
2188
2189 /* create and send DISC command */
2190 {SBIT(LAPD_STATE_SABM_SENT) |
2191 SBIT(LAPD_STATE_MF_EST) |
2192 SBIT(LAPD_STATE_TIMER_RECOV) |
2193 SBIT(LAPD_STATE_DISC_SENT),
2194 PRIM_DL_REL, PRIM_OP_REQUEST,
2195 "DL-RELEASE-REQUEST", lapd_rel_req},
2196
2197 /* release in idle state */
2198 {SBIT(LAPD_STATE_IDLE),
2199 PRIM_DL_REL, PRIM_OP_REQUEST,
2200 "DL-RELEASE-REQUEST", lapd_rel_req_idle},
2201};
2202
2203#define L2DOWNSLLEN \
2204 (sizeof(l2downstatelist) / sizeof(struct l2downstate))
2205
2206int lapd_recv_dlsap(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
2207{
2208 struct lapd_datalink *dl = lctx->dl;
2209 int i, supported = 0;
2210 struct msgb *msg = dp->oph.msg;
2211 int rc;
2212
2213 /* find function for current state and message */
2214 for (i = 0; i < L2DOWNSLLEN; i++) {
2215 if (dp->oph.primitive == l2downstatelist[i].prim
2216 && dp->oph.operation == l2downstatelist[i].op) {
2217 supported = 1;
2218 if ((SBIT(dl->state) & l2downstatelist[i].states))
2219 break;
2220 }
2221 }
2222 if (!supported) {
Philipp Maier08177d32016-12-08 17:23:26 +01002223 LOGP(DLLAPD, LOGL_NOTICE,
2224 "Message %u/%u unsupported. (dl=%p)\n", dp->oph.primitive,
2225 dp->oph.operation, dl);
rootaf48bed2011-09-26 11:23:06 +02002226 msgb_free(msg);
2227 return 0;
2228 }
2229 if (i == L2DOWNSLLEN) {
2230 LOGP(DLLAPD, LOGL_NOTICE, "Message %u/%u unhandled at this "
Philipp Maier08177d32016-12-08 17:23:26 +01002231 "state %s. (dl=%p)\n", dp->oph.primitive,
Harald Weltec733d142017-03-15 10:20:51 +01002232 dp->oph.operation, lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +02002233 msgb_free(msg);
2234 return 0;
2235 }
2236
Philipp Maier08177d32016-12-08 17:23:26 +01002237 LOGP(DLLAPD, LOGL_INFO, "Message %s received in state %s (dl=%p)\n",
Harald Weltec733d142017-03-15 10:20:51 +01002238 l2downstatelist[i].name, lapd_state_name(dl->state), dl);
rootaf48bed2011-09-26 11:23:06 +02002239
2240 rc = l2downstatelist[i].rout(dp, lctx);
2241
2242 return rc;
2243}
2244
Katerina Barone-Adesic28c6a02013-02-15 13:27:59 +01002245/*! @} */