blob: 52e8fc52aa1d8f55a5948da2b11b5ca3aede894d [file] [log] [blame]
Harald Welte1f0b8c22011-06-27 10:51:37 +02001#ifndef _OSMOCOM_LAPDM_H
2#define _OSMOCOM_LAPDM_H
3
rootaf48bed2011-09-26 11:23:06 +02004#include <osmocom/gsm/lapd_core.h>
Harald Welte1f0b8c22011-06-27 10:51:37 +02005
Harald Welte6bdf0b12011-08-17 18:22:08 +02006/*! \defgroup lapdm LAPDm implementation according to GSM TS 04.06
7 * @{
8 */
9
10/*! \file lapdm.h */
11
Harald Welte1f0b8c22011-06-27 10:51:37 +020012/* primitive related sutff */
13
rootaf48bed2011-09-26 11:23:06 +020014/*! \brief LAPDm related primitives (L1<->L2 SAP) */
Harald Welte1f0b8c22011-06-27 10:51:37 +020015enum osmo_ph_prim {
Harald Welte6bdf0b12011-08-17 18:22:08 +020016 PRIM_PH_DATA, /*!< \brief PH-DATA */
17 PRIM_PH_RACH, /*!< \brief PH-RANDOM_ACCESS */
18 PRIM_PH_CONN, /*!< \brief PH-CONNECT */
19 PRIM_PH_EMPTY_FRAME, /*!< \brief PH-EMPTY_FRAME */
20 PRIM_PH_RTS, /*!< \brief PH-RTS */
Harald Welte1f0b8c22011-06-27 10:51:37 +020021};
22
Harald Welte6bdf0b12011-08-17 18:22:08 +020023/*! \brief for PH-RANDOM_ACCESS.req */
Harald Welte1f0b8c22011-06-27 10:51:37 +020024struct ph_rach_req_param {
Harald Welte6bdf0b12011-08-17 18:22:08 +020025 uint8_t ra; /*!< \brief Random Access */
26 uint8_t ta; /*!< \brief Timing Advance */
27 uint8_t tx_power; /*!< \brief Transmit Power */
28 uint8_t is_combined_ccch;/*!< \brief Are we using a combined CCCH? */
29 uint16_t offset; /*!< \brief Timing Offset */
Harald Welte1f0b8c22011-06-27 10:51:37 +020030};
31
Harald Welte6bdf0b12011-08-17 18:22:08 +020032/*! \brief for PH-RANDOM_ACCESS.ind */
Harald Welte1f0b8c22011-06-27 10:51:37 +020033struct ph_rach_ind_param {
Harald Welte6bdf0b12011-08-17 18:22:08 +020034 uint8_t ra; /*!< \brief Random Access */
35 uint8_t acc_delay; /*!< \brief Delay in bit periods */
36 uint32_t fn; /*!< \brief GSM Frame Number at time of RA */
Harald Welte1f0b8c22011-06-27 10:51:37 +020037};
38
Harald Welte6bdf0b12011-08-17 18:22:08 +020039/*! \brief for PH-[UNIT]DATA.{req,ind} */
Harald Welte1f0b8c22011-06-27 10:51:37 +020040struct ph_data_param {
Harald Welte6bdf0b12011-08-17 18:22:08 +020041 uint8_t link_id; /*!< \brief Link Identifier (Like RSL) */
42 uint8_t chan_nr; /*!< \brief Channel Number (Like RSL) */
Harald Welte1f0b8c22011-06-27 10:51:37 +020043};
44
Harald Welte6bdf0b12011-08-17 18:22:08 +020045/*! \brief for PH-CONN.ind */
Harald Welte1f0b8c22011-06-27 10:51:37 +020046struct ph_conn_ind_param {
Harald Welte6bdf0b12011-08-17 18:22:08 +020047 uint32_t fn; /*!< \brief GSM Frame Number */
Harald Welte1f0b8c22011-06-27 10:51:37 +020048};
49
Harald Welte6bdf0b12011-08-17 18:22:08 +020050/*! \brief primitive header for LAPDm PH-SAP primitives */
Harald Welte1f0b8c22011-06-27 10:51:37 +020051struct osmo_phsap_prim {
Harald Welte6bdf0b12011-08-17 18:22:08 +020052 struct osmo_prim_hdr oph; /*!< \brief generic primitive header */
Harald Welte1f0b8c22011-06-27 10:51:37 +020053 union {
54 struct ph_data_param data;
55 struct ph_rach_req_param rach_req;
56 struct ph_rach_ind_param rach_ind;
57 struct ph_conn_ind_param conn_ind;
Harald Welte6bdf0b12011-08-17 18:22:08 +020058 } u; /*!< \brief request-specific data */
Harald Welte1f0b8c22011-06-27 10:51:37 +020059};
60
Harald Welte6bdf0b12011-08-17 18:22:08 +020061/*! \brief LAPDm mode/role */
Harald Welte1f0b8c22011-06-27 10:51:37 +020062enum lapdm_mode {
Harald Welte6bdf0b12011-08-17 18:22:08 +020063 LAPDM_MODE_MS, /*!< \brief behave like a MS (mobile phone) */
64 LAPDM_MODE_BTS, /*!< \brief behave like a BTS (network) */
Harald Welte1f0b8c22011-06-27 10:51:37 +020065};
66
Harald Welte1f0b8c22011-06-27 10:51:37 +020067struct lapdm_entity;
68
Harald Welte6bdf0b12011-08-17 18:22:08 +020069/*! \brief LAPDm message context */
Harald Welte1f0b8c22011-06-27 10:51:37 +020070struct lapdm_msg_ctx {
71 struct lapdm_datalink *dl;
72 int lapdm_fmt;
Harald Welte1f0b8c22011-06-27 10:51:37 +020073 uint8_t chan_nr;
74 uint8_t link_id;
Andreas.Eversbergf1f80de2011-11-06 20:45:29 +010075 uint8_t ta_ind; /* TA indicated by network */
76 uint8_t tx_power_ind; /* MS power indicated by network */
Harald Welte1f0b8c22011-06-27 10:51:37 +020077};
78
Harald Welte6bdf0b12011-08-17 18:22:08 +020079/*! \brief LAPDm datalink like TS 04.06 / Section 3.5.2 */
Harald Welte1f0b8c22011-06-27 10:51:37 +020080struct lapdm_datalink {
rootaf48bed2011-09-26 11:23:06 +020081 struct lapd_datalink dl; /* \brief common LAPD */
Harald Welte6bdf0b12011-08-17 18:22:08 +020082 struct lapdm_msg_ctx mctx; /*!< \brief context of established connection */
Harald Welte1f0b8c22011-06-27 10:51:37 +020083
Harald Welte6bdf0b12011-08-17 18:22:08 +020084 struct lapdm_entity *entity; /*!< \brief LAPDm entity we are part of */
Harald Welte1f0b8c22011-06-27 10:51:37 +020085};
86
Harald Welte6bdf0b12011-08-17 18:22:08 +020087/*! \brief LAPDm datalink SAPIs */
Harald Welte1f0b8c22011-06-27 10:51:37 +020088enum lapdm_dl_sapi {
Harald Welte6bdf0b12011-08-17 18:22:08 +020089 DL_SAPI0 = 0, /*!< \brief SAPI 0 */
90 DL_SAPI3 = 1, /*!< \brief SAPI 1 */
Harald Welte1f0b8c22011-06-27 10:51:37 +020091 _NR_DL_SAPI
92};
93
94typedef int (*lapdm_cb_t)(struct msgb *msg, struct lapdm_entity *le, void *ctx);
95
Harald Welte1f0b8c22011-06-27 10:51:37 +020096#define LAPDM_ENT_F_EMPTY_FRAME 0x0001
97#define LAPDM_ENT_F_POLLING_ONLY 0x0002
98
Harald Welte6bdf0b12011-08-17 18:22:08 +020099/*! \brief a LAPDm Entity */
Harald Welte1f0b8c22011-06-27 10:51:37 +0200100struct lapdm_entity {
Harald Welte6bdf0b12011-08-17 18:22:08 +0200101 /*! \brief the SAPIs of the LAPDm entity */
Harald Welte1f0b8c22011-06-27 10:51:37 +0200102 struct lapdm_datalink datalink[_NR_DL_SAPI];
Harald Welte6bdf0b12011-08-17 18:22:08 +0200103 int last_tx_dequeue; /*!< \brief last entity that was dequeued */
104 int tx_pending; /*!< \brief currently a pending frame not confirmed by L1 */
105 enum lapdm_mode mode; /*!< \brief are we in BTS mode or MS mode */
Harald Welte1f0b8c22011-06-27 10:51:37 +0200106 unsigned int flags;
107
Harald Welte6bdf0b12011-08-17 18:22:08 +0200108 void *l1_ctx; /*!< \brief context for layer1 instance */
109 void *l3_ctx; /*!< \brief context for layer3 instance */
Harald Welte1f0b8c22011-06-27 10:51:37 +0200110
Harald Welte6bdf0b12011-08-17 18:22:08 +0200111 osmo_prim_cb l1_prim_cb;/*!< \brief callback for sending prims to L1 */
112 lapdm_cb_t l3_cb; /*!< \brief callback for sending stuff to L3 */
Harald Welte1f0b8c22011-06-27 10:51:37 +0200113
Harald Welte6bdf0b12011-08-17 18:22:08 +0200114 /*! \brief pointer to \ref lapdm_channel of which we're part */
Harald Welte1f0b8c22011-06-27 10:51:37 +0200115 struct lapdm_channel *lapdm_ch;
Andreas.Eversbergf1f80de2011-11-06 20:45:29 +0100116
117 uint8_t ta; /* TA used and indicated to network */
118 uint8_t tx_power; /* MS power used and indicated to network */
Harald Welte1f0b8c22011-06-27 10:51:37 +0200119};
120
Harald Welte6bdf0b12011-08-17 18:22:08 +0200121/*! \brief the two lapdm_entities that form a GSM logical channel (ACCH + DCCH) */
Harald Welte1f0b8c22011-06-27 10:51:37 +0200122struct lapdm_channel {
Harald Welte6bdf0b12011-08-17 18:22:08 +0200123 struct llist_head list; /*!< \brief internal linked list */
124 char *name; /*!< \brief human-readable name */
125 struct lapdm_entity lapdm_acch; /*!< \brief Associated Control Channel */
126 struct lapdm_entity lapdm_dcch; /*!< \brief Dedicated Control Channel */
Harald Welte1f0b8c22011-06-27 10:51:37 +0200127};
128
129const char *get_rsl_name(int value);
130extern const char *lapdm_state_names[];
131
132/* initialize a LAPDm entity */
Andreas.Eversberg5ac44782011-11-06 20:35:48 +0100133void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode, int t200);
Harald Welte1f0b8c22011-06-27 10:51:37 +0200134void lapdm_channel_init(struct lapdm_channel *lc, enum lapdm_mode mode);
135
136/* deinitialize a LAPDm entity */
137void lapdm_entity_exit(struct lapdm_entity *le);
138void lapdm_channel_exit(struct lapdm_channel *lc);
139
140/* input into layer2 (from layer 1) */
141int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le);
142
143/* input into layer2 (from layer 3) */
144int lapdm_rslms_recvmsg(struct msgb *msg, struct lapdm_channel *lc);
145
146void lapdm_channel_set_l3(struct lapdm_channel *lc, lapdm_cb_t cb, void *ctx);
147void lapdm_channel_set_l1(struct lapdm_channel *lc, osmo_prim_cb cb, void *ctx);
148
149int lapdm_entity_set_mode(struct lapdm_entity *le, enum lapdm_mode mode);
150int lapdm_channel_set_mode(struct lapdm_channel *lc, enum lapdm_mode mode);
151
152void lapdm_entity_reset(struct lapdm_entity *le);
153void lapdm_channel_reset(struct lapdm_channel *lc);
154
155void lapdm_entity_set_flags(struct lapdm_entity *le, unsigned int flags);
156void lapdm_channel_set_flags(struct lapdm_channel *lc, unsigned int flags);
157
158int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp);
159
Harald Welte6bdf0b12011-08-17 18:22:08 +0200160/*! }@ */
161
Harald Welte1f0b8c22011-06-27 10:51:37 +0200162#endif /* _OSMOCOM_LAPDM_H */