blob: 6812102e12fc08c0c821cffba8a7618fb5fc1810 [file] [log] [blame]
Sylvain Munaut12ba7782014-06-16 10:13:40 +02001#pragma once
Harald Welte1f0b8c22011-06-27 10:51:37 +02002
Andreas Eversbergaa85a2d2013-02-07 12:18:37 +01003#include <osmocom/gsm/l1sap.h>
Harald Welte20de6202019-06-02 21:33:38 +02004#include <osmocom/gsm/gsm_utils.h>
rootaf48bed2011-09-26 11:23:06 +02005#include <osmocom/gsm/lapd_core.h>
Harald Welte1f0b8c22011-06-27 10:51:37 +02006
Harald Welte6bdf0b12011-08-17 18:22:08 +02007/*! \defgroup lapdm LAPDm implementation according to GSM TS 04.06
8 * @{
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02009 * \file lapdm.h */
Harald Welte6bdf0b12011-08-17 18:22:08 +020010
Neels Hofmeyr87e45502017-06-20 00:17:59 +020011/*! LAPDm mode/role */
Harald Welte1f0b8c22011-06-27 10:51:37 +020012enum lapdm_mode {
Neels Hofmeyr87e45502017-06-20 00:17:59 +020013 LAPDM_MODE_MS, /*!< behave like a MS (mobile phone) */
14 LAPDM_MODE_BTS, /*!< behave like a BTS (network) */
Harald Welte1f0b8c22011-06-27 10:51:37 +020015};
16
Harald Welte1f0b8c22011-06-27 10:51:37 +020017struct lapdm_entity;
18
Neels Hofmeyr87e45502017-06-20 00:17:59 +020019/*! LAPDm message context */
Harald Welte1f0b8c22011-06-27 10:51:37 +020020struct lapdm_msg_ctx {
21 struct lapdm_datalink *dl;
22 int lapdm_fmt;
Harald Welte1f0b8c22011-06-27 10:51:37 +020023 uint8_t chan_nr;
24 uint8_t link_id;
Andreas.Eversbergf1f80de2011-11-06 20:45:29 +010025 uint8_t ta_ind; /* TA indicated by network */
26 uint8_t tx_power_ind; /* MS power indicated by network */
Pau Espin Pedrol1247aa12023-08-09 17:41:25 +020027 uint32_t fn;
Harald Welte1f0b8c22011-06-27 10:51:37 +020028};
29
Neels Hofmeyr87e45502017-06-20 00:17:59 +020030/*! LAPDm datalink like TS 04.06 / Section 3.5.2 */
Harald Welte1f0b8c22011-06-27 10:51:37 +020031struct lapdm_datalink {
Neels Hofmeyr87e45502017-06-20 00:17:59 +020032 struct lapd_datalink dl; /* common LAPD */
33 struct lapdm_msg_ctx mctx; /*!< context of established connection */
Harald Welte1f0b8c22011-06-27 10:51:37 +020034
Neels Hofmeyr87e45502017-06-20 00:17:59 +020035 struct lapdm_entity *entity; /*!< LAPDm entity we are part of */
Andreas Eversberg2d7119d2023-11-09 13:06:19 +010036
Andreas Eversbergf51f9162023-11-09 13:19:34 +010037 struct llist_head tx_ui_queue; /*!< UI frames to L1 */
Andreas Eversberg2d7119d2023-11-09 13:06:19 +010038 uint32_t t200_fn; /*!< T200 timer in frames */
39 uint32_t t200_timeout; /*!< T200 timeout frame number */
Harald Welte1f0b8c22011-06-27 10:51:37 +020040};
41
Neels Hofmeyr87e45502017-06-20 00:17:59 +020042/*! LAPDm datalink SAPIs */
Harald Welte1f0b8c22011-06-27 10:51:37 +020043enum lapdm_dl_sapi {
Neels Hofmeyr87e45502017-06-20 00:17:59 +020044 DL_SAPI0 = 0, /*!< SAPI 0 */
45 DL_SAPI3 = 1, /*!< SAPI 1 */
Harald Welte1f0b8c22011-06-27 10:51:37 +020046 _NR_DL_SAPI
47};
48
49typedef int (*lapdm_cb_t)(struct msgb *msg, struct lapdm_entity *le, void *ctx);
50
Harald Welte1f0b8c22011-06-27 10:51:37 +020051#define LAPDM_ENT_F_EMPTY_FRAME 0x0001
52#define LAPDM_ENT_F_POLLING_ONLY 0x0002
Andreas Eversbergbd2b8972023-11-15 14:33:53 +010053#define LAPDM_ENT_F_DROP_2ND_REJ 0x0004
Andreas Eversberg285f3692023-11-29 12:03:00 +010054#define LAPDM_ENT_F_RTS 0x0008
Harald Welte1f0b8c22011-06-27 10:51:37 +020055
Neels Hofmeyr87e45502017-06-20 00:17:59 +020056/*! a LAPDm Entity */
Harald Welte1f0b8c22011-06-27 10:51:37 +020057struct lapdm_entity {
Neels Hofmeyr87e45502017-06-20 00:17:59 +020058 /*! the SAPIs of the LAPDm entity */
Harald Welte1f0b8c22011-06-27 10:51:37 +020059 struct lapdm_datalink datalink[_NR_DL_SAPI];
Neels Hofmeyr87e45502017-06-20 00:17:59 +020060 int last_tx_dequeue; /*!< last entity that was dequeued */
61 int tx_pending; /*!< currently a pending frame not confirmed by L1 */
62 enum lapdm_mode mode; /*!< are we in BTS mode or MS mode */
Harald Welte1f0b8c22011-06-27 10:51:37 +020063 unsigned int flags;
64
Neels Hofmeyr87e45502017-06-20 00:17:59 +020065 void *l1_ctx; /*!< context for layer1 instance */
66 void *l3_ctx; /*!< context for layer3 instance */
Harald Welte1f0b8c22011-06-27 10:51:37 +020067
Neels Hofmeyr87e45502017-06-20 00:17:59 +020068 osmo_prim_cb l1_prim_cb;/*!< callback for sending prims to L1 */
69 lapdm_cb_t l3_cb; /*!< callback for sending stuff to L3 */
Harald Welte1f0b8c22011-06-27 10:51:37 +020070
Neels Hofmeyr87e45502017-06-20 00:17:59 +020071 /*! pointer to \ref lapdm_channel of which we're part */
Harald Welte1f0b8c22011-06-27 10:51:37 +020072 struct lapdm_channel *lapdm_ch;
Andreas.Eversbergf1f80de2011-11-06 20:45:29 +010073
74 uint8_t ta; /* TA used and indicated to network */
75 uint8_t tx_power; /* MS power used and indicated to network */
Harald Welte1f0b8c22011-06-27 10:51:37 +020076};
77
Neels Hofmeyr87e45502017-06-20 00:17:59 +020078/*! the two lapdm_entities that form a GSM logical channel (ACCH + DCCH) */
Harald Welte1f0b8c22011-06-27 10:51:37 +020079struct lapdm_channel {
Neels Hofmeyr87e45502017-06-20 00:17:59 +020080 struct llist_head list; /*!< internal linked list */
81 char *name; /*!< human-readable name */
82 struct lapdm_entity lapdm_acch; /*!< Associated Control Channel */
83 struct lapdm_entity lapdm_dcch; /*!< Dedicated Control Channel */
Harald Welte1f0b8c22011-06-27 10:51:37 +020084};
85
86const char *get_rsl_name(int value);
87extern const char *lapdm_state_names[];
88
Daniel Willmann55405fb2014-03-26 13:45:17 +010089struct lapdm_datalink *lapdm_datalink_for_sapi(struct lapdm_entity *le, uint8_t sapi);
90
Harald Welte1f0b8c22011-06-27 10:51:37 +020091/* initialize a LAPDm entity */
Harald Welte20de6202019-06-02 21:33:38 +020092void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode, int t200)
Harald Welte00b2faf2020-05-02 19:56:36 +020093 OSMO_DEPRECATED("Use lapdm_entity_init3() instead");
Harald Welte20de6202019-06-02 21:33:38 +020094void lapdm_entity_init2(struct lapdm_entity *le, enum lapdm_mode mode,
Harald Welte00b2faf2020-05-02 19:56:36 +020095 const int *t200_ms, int n200)
96 OSMO_DEPRECATED("Use lapdm_entity_init3() instead");
97void lapdm_entity_init3(struct lapdm_entity *le, enum lapdm_mode mode,
98 const int *t200_ms, int n200, const char *name_pfx);
Harald Welte20de6202019-06-02 21:33:38 +020099void lapdm_channel_init(struct lapdm_channel *lc, enum lapdm_mode mode)
Neels Hofmeyr137efc92021-09-29 15:22:28 +0200100 OSMO_DEPRECATED_OUTSIDE("Use lapdm_channel_init3() instead");
Harald Welte20de6202019-06-02 21:33:38 +0200101int lapdm_channel_init2(struct lapdm_channel *lc, enum lapdm_mode mode,
102 const int *t200_ms_dcch, const int *t200_ms_acch, enum gsm_chan_t chan_t);
Harald Welte00b2faf2020-05-02 19:56:36 +0200103int lapdm_channel_init3(struct lapdm_channel *lc, enum lapdm_mode mode,
104 const int *t200_ms_dcch, const int *t200_ms_acch, enum gsm_chan_t chan_t,
105 const char *name_pfx);
Harald Welte1f0b8c22011-06-27 10:51:37 +0200106/* deinitialize a LAPDm entity */
107void lapdm_entity_exit(struct lapdm_entity *le);
108void lapdm_channel_exit(struct lapdm_channel *lc);
109
110/* input into layer2 (from layer 1) */
111int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le);
112
113/* input into layer2 (from layer 3) */
114int lapdm_rslms_recvmsg(struct msgb *msg, struct lapdm_channel *lc);
115
116void lapdm_channel_set_l3(struct lapdm_channel *lc, lapdm_cb_t cb, void *ctx);
117void lapdm_channel_set_l1(struct lapdm_channel *lc, osmo_prim_cb cb, void *ctx);
118
119int lapdm_entity_set_mode(struct lapdm_entity *le, enum lapdm_mode mode);
120int lapdm_channel_set_mode(struct lapdm_channel *lc, enum lapdm_mode mode);
121
122void lapdm_entity_reset(struct lapdm_entity *le);
123void lapdm_channel_reset(struct lapdm_channel *lc);
124
125void lapdm_entity_set_flags(struct lapdm_entity *le, unsigned int flags);
126void lapdm_channel_set_flags(struct lapdm_channel *lc, unsigned int flags);
127
Andreas Eversberg2d7119d2023-11-09 13:06:19 +0100128void lapdm_entity_set_t200_fn(struct lapdm_entity *le, const uint32_t *t200_fn);
129void lapdm_channel_set_t200_fn(struct lapdm_channel *lc, const uint32_t *t200_fn_dcch, const uint32_t *t200_fn_acch);
130
Harald Welte1f0b8c22011-06-27 10:51:37 +0200131int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp);
Andreas Eversberg2d7119d2023-11-09 13:06:19 +0100132int lapdm_phsap_dequeue_prim_fn(struct lapdm_entity *le, struct osmo_phsap_prim *pp, uint32_t fn);
133void lapdm_t200_fn(struct lapdm_entity *le, uint32_t fn);
Harald Welte1f0b8c22011-06-27 10:51:37 +0200134
Sylvain Munautdca7d2c2012-04-18 21:53:23 +0200135/*! @} */