121 lines
3.4 KiB
C
121 lines
3.4 KiB
C
#pragma once
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
|
|
#include <osmocom/core/linuxlist.h>
|
|
|
|
struct l1gprs_state;
|
|
struct msgb;
|
|
|
|
struct l1gprs_tbf_pending_req {
|
|
/*! Item in l1gprs_state->tbf_list_pending */
|
|
struct llist_head list;
|
|
/*! Uplink or Downlink */
|
|
bool uplink;
|
|
/*! TBF reference number (not index) */
|
|
uint8_t tbf_ref;
|
|
/*! PDCH timeslots used by this TBF */
|
|
uint8_t slotmask;
|
|
/*! (Downlink only) DL TFI (Temporary Flow Indentity): 0..31 */
|
|
uint8_t dl_tfi;
|
|
/*! TBF starting time (absolute TDMA Fn) */
|
|
uint32_t start_fn;
|
|
};
|
|
|
|
struct l1gprs_tbf {
|
|
/*! Item in l1gprs_state->tbf_list */
|
|
struct llist_head list;
|
|
/*! Uplink or Downlink */
|
|
bool uplink;
|
|
/*! TBF reference number (not index) */
|
|
uint8_t tbf_ref;
|
|
/*! PDCH timeslots used by this TBF */
|
|
uint8_t slotmask;
|
|
/*! (Downlink only) DL TFI (Temporary Flow Indentity): 0..31 */
|
|
uint8_t dl_tfi;
|
|
};
|
|
|
|
struct l1gprs_pdch {
|
|
/*! Timeslot number */
|
|
uint8_t tn;
|
|
/*! Backpointer to l1gprs_state we belong to */
|
|
struct l1gprs_state *gprs;
|
|
/*! UL TBF count */
|
|
uint8_t ul_tbf_count;
|
|
/*! DL TBF count */
|
|
uint8_t dl_tbf_count;
|
|
/*! DL TFI mask */
|
|
uint32_t dl_tfi_mask;
|
|
/*! Pending UL TBF count */
|
|
uint8_t pending_ul_tbf_count;
|
|
/*! Pending DL TBF count */
|
|
uint8_t pending_dl_tbf_count;
|
|
};
|
|
|
|
static inline size_t l1gprs_pdch_use_count(const struct l1gprs_pdch *pdch)
|
|
{
|
|
return pdch->ul_tbf_count + pdch->dl_tbf_count +
|
|
pdch->pending_ul_tbf_count + pdch->pending_dl_tbf_count;
|
|
}
|
|
|
|
|
|
typedef void (*l1gprs_pdch_changed_t)(struct l1gprs_pdch *pdch, bool active);
|
|
|
|
struct l1gprs_state {
|
|
/*! PDCH state for each timeslot */
|
|
struct l1gprs_pdch pdch[8];
|
|
/*! Uplink and Downlink TBFs (active), struct l1gprs_pending_tbf */
|
|
struct llist_head tbf_list;
|
|
/*! Uplink and Downlink TBFs (pending), struct l1gprs_tbf_pending_req */
|
|
struct llist_head tbf_list_pending;
|
|
/*! Logging context (used as prefix for messages) */
|
|
char *log_prefix;
|
|
/*! Some private data for API user */
|
|
void *priv;
|
|
/*! Callback triggered to signal lower layers when a PDCH TS has to be activated/deactivated */
|
|
l1gprs_pdch_changed_t pdch_changed_cb;
|
|
};
|
|
|
|
void l1gprs_logging_init(int logc);
|
|
struct l1gprs_state *l1gprs_state_alloc(void *ctx, const char *log_prefix, void *priv);
|
|
void l1gprs_state_free(struct l1gprs_state *gprs);
|
|
void l1gprs_state_set_pdch_changed_cb(struct l1gprs_state *gprs, l1gprs_pdch_changed_t pdch_changed_cb);
|
|
|
|
int l1gprs_handle_ul_tbf_cfg_req(struct l1gprs_state *gprs, const struct msgb *msg);
|
|
int l1gprs_handle_dl_tbf_cfg_req(struct l1gprs_state *gprs, const struct msgb *msg);
|
|
|
|
struct l1gprs_prim_block_hdr {
|
|
uint32_t fn;
|
|
uint8_t tn;
|
|
};
|
|
|
|
struct l1gprs_prim_ul_block_req {
|
|
struct l1gprs_prim_block_hdr hdr;
|
|
size_t data_len;
|
|
const uint8_t *data;
|
|
};
|
|
|
|
struct l1gprs_prim_dl_block_ind {
|
|
struct l1gprs_prim_block_hdr hdr;
|
|
struct {
|
|
uint16_t ber10k;
|
|
int16_t ci_cb;
|
|
uint8_t rx_lev;
|
|
} meas;
|
|
size_t data_len;
|
|
const uint8_t *data;
|
|
};
|
|
|
|
int l1gprs_handle_ul_block_req(struct l1gprs_state *gprs,
|
|
struct l1gprs_prim_ul_block_req *req,
|
|
const struct msgb *msg);
|
|
struct msgb *l1gprs_handle_ul_block_cnf(struct l1gprs_state *gprs,
|
|
uint32_t fn, uint8_t tn,
|
|
const uint8_t *data,
|
|
size_t data_len);
|
|
struct msgb *l1gprs_handle_dl_block_ind(struct l1gprs_state *gprs,
|
|
const struct l1gprs_prim_dl_block_ind *ind, uint8_t *usf);
|
|
struct msgb *l1gprs_handle_rts_ind(struct l1gprs_state *gprs, uint32_t fn, uint8_t tn, uint8_t usf);
|