6 #include <osmocom/core/bits.h>
7 #include <osmocom/core/utils.h>
8 #include <osmocom/gsm/gsm_utils.h>
9 #include <osmocom/core/linuxlist.h>
12 #include "scheduler.h"
14 #define GSM_BURST_LEN 148
15 #define GSM_BURST_PL_LEN 116
17 #define GPRS_BURST_LEN GSM_BURST_LEN
18 #define EDGE_BURST_LEN 444
20 #define TRX_CH_LID_DEDIC 0x00
21 #define TRX_CH_LID_SACCH 0x40
23 /* Is a channel related to PDCH (GPRS) */
24 #define TRX_CH_FLAG_PDCH (1 << 0)
25 /* Should a channel be activated automatically */
26 #define TRX_CH_FLAG_AUTO (1 << 1)
27 /* Is continuous burst transmission assumed */
28 #define TRX_CH_FLAG_CBTX (1 << 2)
30 #define MAX_A5_KEY_LEN (128 / 8)
31 #define TRX_TS_COUNT 8
33 /* Forward declaration to avoid mutual include */
34 struct trx_lchan_state
;
44 * These types define the different channels on a multiframe.
45 * Each channel has queues and can be activated individually.
89 typedef int trx_lchan_rx_func(struct trx_instance
*trx
,
90 struct trx_ts
*ts
, struct trx_lchan_state
*lchan
,
91 uint32_t fn
, uint8_t bid
, sbit_t
*bits
,
92 int8_t rssi
, int16_t toa256
);
94 typedef int trx_lchan_tx_func(struct trx_instance
*trx
,
95 struct trx_ts
*ts
, struct trx_lchan_state
*lchan
,
96 uint32_t fn
, uint8_t bid
);
98 struct trx_lchan_desc
{
99 /*! \brief TRX Channel Type */
100 enum trx_lchan_type chan
;
101 /*! \brief Human-readable name */
103 /*! \brief Channel Number (like in RSL) */
105 /*! \brief Link ID (like in RSL) */
108 /*! \brief How much memory do we need to store bursts */
109 size_t burst_buf_size
;
110 /*! \brief Channel specific flags */
113 /*! \brief Function to call when burst received from PHY */
114 trx_lchan_rx_func
*rx_fn
;
115 /*! \brief Function to call when data received from L2 */
116 trx_lchan_tx_func
*tx_fn
;
120 /*! \brief Downlink TRX channel type */
121 enum trx_lchan_type dl_chan
;
122 /*! \brief Downlink block ID */
124 /*! \brief Uplink TRX channel type */
125 enum trx_lchan_type ul_chan
;
126 /*! \brief Uplink block ID */
130 struct trx_multiframe
{
131 /*! \brief Channel combination */
132 enum gsm_phys_chan_config chan_config
;
133 /*! \brief Human-readable name */
135 /*! \brief Repeats how many frames */
137 /*! \brief Applies to which timeslots */
139 /*! \brief Contains which lchans */
141 /*! \brief Pointer to scheduling structure */
142 const struct trx_frame
*frames
;
145 /* States each channel on a multiframe */
146 struct trx_lchan_state
{
147 /*! \brief Channel type */
148 enum trx_lchan_type type
;
149 /*! \brief Channel status */
151 /*! \brief Link to a list of channels */
152 struct llist_head list
;
154 /*! \brief Burst type: GMSK or 8PSK */
155 enum trx_burst_type burst_type
;
156 /*! \brief Frame number of first burst */
157 uint32_t rx_first_fn
;
158 /*! \brief Mask of received bursts */
159 uint8_t rx_burst_mask
;
160 /*! \brief Mask of transmitted bursts */
161 uint8_t tx_burst_mask
;
162 /*! \brief Burst buffer for RX */
164 /*! \brief Burst buffer for TX */
167 /*! \brief A primitive being sent */
168 struct trx_ts_prim
*prim
;
170 /*! \brief Mode for TCH channels */
171 uint8_t rsl_cmode
, tch_mode
;
173 /*! \brief FACCH/H on downlink */
174 uint8_t dl_ongoing_facch
;
175 /*! \brief FACCH/H on uplink */
176 uint8_t ul_ongoing_facch
;
179 /*! \brief Number of RSSI values */
181 /*! \brief Sum of RSSI values */
183 /*! \brief Number of TOA values */
185 /*! \brief Sum of TOA values */
191 /*! \brief 4 possible codecs for AMR */
193 /*! \brief Number of possible codecs */
195 /*! \brief Current uplink FT index */
197 /*! \brief Current downlink FT index */
199 /*! \brief Current uplink CMR index */
201 /*! \brief Current downlink CMR index */
203 /*! \brief If AMR loop is enabled */
205 /*! \brief Number of bit error rates */
207 /*! \brief Sum of bit error rates */
211 /*! \brief A5/X encryption state */
213 uint8_t key
[MAX_A5_KEY_LEN
];
220 /*! \brief Timeslot index within a frame (0..7) */
222 /*! \brief Last received frame number */
225 /*! \brief Pointer to multiframe layout */
226 const struct trx_multiframe
*mf_layout
;
227 /*! \brief Channel states for logical channels */
228 struct llist_head lchans
;
229 /*! \brief Queue primitives for TX */
230 struct llist_head tx_prims
;
233 /* Represents one TX primitive in the queue of trx_ts */
235 /*! \brief Link to queue of TS */
236 struct llist_head list
;
237 /*! \brief Logical channel type */
238 enum trx_lchan_type chan
;
239 /*! \brief Payload length */
241 /*! \brief Payload */
245 extern const struct trx_lchan_desc trx_lchan_desc
[_TRX_CHAN_MAX
];
246 const struct trx_multiframe
*sched_mframe_layout(
247 enum gsm_phys_chan_config config
, int tn
);
249 /* Scheduler management functions */
250 int sched_trx_init(struct trx_instance
*trx
, uint32_t fn_advance
);
251 int sched_trx_reset(struct trx_instance
*trx
, int reset_clock
);
252 int sched_trx_shutdown(struct trx_instance
*trx
);
254 /* Timeslot management functions */
255 struct trx_ts
*sched_trx_add_ts(struct trx_instance
*trx
, int tn
);
256 void sched_trx_del_ts(struct trx_instance
*trx
, int tn
);
257 int sched_trx_reset_ts(struct trx_instance
*trx
, int tn
);
258 int sched_trx_configure_ts(struct trx_instance
*trx
, int tn
,
259 enum gsm_phys_chan_config config
);
260 int sched_trx_start_ciphering(struct trx_ts
*ts
, uint8_t algo
,
261 uint8_t *key
, uint8_t key_len
);
263 /* Logical channel management functions */
264 enum gsm_phys_chan_config
sched_trx_chan_nr2pchan_config(uint8_t chan_nr
);
265 enum trx_lchan_type
sched_trx_chan_nr2lchan_type(uint8_t chan_nr
,
268 void sched_trx_deactivate_all_lchans(struct trx_ts
*ts
);
269 int sched_trx_set_lchans(struct trx_ts
*ts
, uint8_t chan_nr
, int active
, uint8_t tch_mode
);
270 int sched_trx_activate_lchan(struct trx_ts
*ts
, enum trx_lchan_type chan
);
271 int sched_trx_deactivate_lchan(struct trx_ts
*ts
, enum trx_lchan_type chan
);
272 struct trx_lchan_state
*sched_trx_find_lchan(struct trx_ts
*ts
,
273 enum trx_lchan_type chan
);
275 /* Primitive management functions */
276 int sched_prim_init(struct trx_instance
*trx
, struct trx_ts_prim
**prim
,
277 size_t pl_len
, uint8_t chan_nr
, uint8_t link_id
);
278 int sched_prim_push(struct trx_instance
*trx
,
279 struct trx_ts_prim
*prim
, uint8_t chan_nr
);
281 #define TCH_MODE_IS_SPEECH(mode) \
282 (mode == GSM48_CMODE_SPEECH_V1 \
283 || mode == GSM48_CMODE_SPEECH_EFR \
284 || mode == GSM48_CMODE_SPEECH_AMR)
286 #define TCH_MODE_IS_DATA(mode) \
287 (mode == GSM48_CMODE_DATA_14k5 \
288 || mode == GSM48_CMODE_DATA_12k0 \
289 || mode == GSM48_CMODE_DATA_6k0 \
290 || mode == GSM48_CMODE_DATA_3k6)
292 #define CHAN_IS_TCH(chan) \
293 (chan == TRXC_TCHF || chan == TRXC_TCHH_0 || chan == TRXC_TCHH_1)
295 #define CHAN_IS_SACCH(chan) \
296 (trx_lchan_desc[chan].link_id & TRX_CH_LID_SACCH)
298 #define PRIM_IS_TCH(prim) \
299 CHAN_IS_TCH(prim->chan) && prim->payload_len != GSM_MACBLOCK_LEN
301 #define PRIM_IS_FACCH(prim) \
302 CHAN_IS_TCH(prim->chan) && prim->payload_len == GSM_MACBLOCK_LEN
304 struct trx_ts_prim
*sched_prim_dequeue(struct llist_head
*queue
,
305 enum trx_lchan_type lchan_type
);
306 int sched_prim_dummy(struct trx_lchan_state
*lchan
);
307 void sched_prim_drop(struct trx_lchan_state
*lchan
);
308 void sched_prim_flush_queue(struct llist_head
*list
);
310 int sched_trx_handle_rx_burst(struct trx_instance
*trx
, uint8_t tn
,
311 uint32_t burst_fn
, sbit_t
*bits
, uint16_t nbits
,
312 int8_t rssi
, int16_t toa256
);
313 int sched_trx_handle_tx_burst(struct trx_instance
*trx
,
314 struct trx_ts
*ts
, struct trx_lchan_state
*lchan
,
315 uint32_t fn
, ubit_t
*bits
);
317 /* Shared declarations for lchan handlers */
318 extern const uint8_t sched_nb_training_bits
[8][26];
320 size_t sched_bad_frame_ind(uint8_t *l2
, uint8_t rsl_cmode
, uint8_t tch_mode
);
321 int sched_send_dt_ind(struct trx_instance
*trx
, struct trx_ts
*ts
,
322 struct trx_lchan_state
*lchan
, uint8_t *l2
, size_t l2_len
,
323 int bit_error_count
, bool dec_failed
, bool traffic
);
324 int sched_send_dt_conf(struct trx_instance
*trx
, struct trx_ts
*ts
,
325 struct trx_lchan_state
*lchan
, uint32_t fn
, bool traffic
);