2008-12-23 20:25:15 +00:00
|
|
|
#ifndef _GSM_DATA_H
|
|
|
|
#define _GSM_DATA_H
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
2008-12-28 02:26:27 +00:00
|
|
|
#include <openbsc/timer.h>
|
2009-02-04 00:04:52 +00:00
|
|
|
#include <openbsc/gsm_04_08.h>
|
2008-12-28 02:26:27 +00:00
|
|
|
|
2008-12-25 23:28:35 +00:00
|
|
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
|
|
|
|
2008-12-23 20:25:15 +00:00
|
|
|
#define GSM_MAX_BTS 8
|
|
|
|
#define BTS_MAX_TRX 8
|
2009-01-18 17:47:32 +00:00
|
|
|
#define TRX_NR_TS 8
|
2008-12-25 23:28:35 +00:00
|
|
|
#define TS_MAX_LCHAN 8
|
2008-12-23 20:25:15 +00:00
|
|
|
|
|
|
|
#define HARDCODED_ARFCN 123
|
2009-02-28 13:11:07 +00:00
|
|
|
#define HARDCODED_TSC 7
|
2009-05-23 16:56:52 +00:00
|
|
|
#define HARDCODED_BSIC 0x3f /* NCC = 7 / BCC = 7 */
|
2008-12-23 20:25:15 +00:00
|
|
|
|
2009-02-01 13:32:45 +00:00
|
|
|
enum gsm_hooks {
|
|
|
|
GSM_HOOK_NM_SWLOAD,
|
2009-02-16 22:53:52 +00:00
|
|
|
GSM_HOOK_RR_PAGING,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum gsm_paging_event {
|
|
|
|
GSM_PAGING_SUCCEEDED,
|
|
|
|
GSM_PAGING_EXPIRED,
|
2009-04-18 11:48:55 +00:00
|
|
|
GSM_PAGING_OOM,
|
2009-02-01 13:32:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct msgb;
|
|
|
|
typedef int gsm_cbfn(unsigned int hooknum,
|
|
|
|
unsigned int event,
|
|
|
|
struct msgb *msg,
|
|
|
|
void *data, void *param);
|
|
|
|
|
2008-12-30 19:18:21 +00:00
|
|
|
/*
|
|
|
|
* Use the channel. As side effect the lchannel recycle timer
|
|
|
|
* will be started.
|
|
|
|
*/
|
|
|
|
#define LCHAN_RELEASE_TIMEOUT 4, 0
|
|
|
|
#define use_lchan(lchan) \
|
|
|
|
do { lchan->use_count++; \
|
2009-06-02 02:55:07 +00:00
|
|
|
DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) increases usage to: %d\n", \
|
|
|
|
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
|
|
|
|
lchan->nr, lchan->use_count); \
|
2009-05-23 05:22:08 +00:00
|
|
|
bsc_schedule_timer(&lchan->release_timer, LCHAN_RELEASE_TIMEOUT); } while(0);
|
2008-12-30 19:18:21 +00:00
|
|
|
|
|
|
|
#define put_lchan(lchan) \
|
2009-06-02 02:55:07 +00:00
|
|
|
do { lchan->use_count--; \
|
|
|
|
DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \
|
|
|
|
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
|
|
|
|
lchan->nr, lchan->use_count); \
|
|
|
|
} while(0);
|
|
|
|
|
2008-12-30 19:18:21 +00:00
|
|
|
|
2008-12-23 20:25:15 +00:00
|
|
|
/* communications link with a BTS */
|
|
|
|
struct gsm_bts_link {
|
|
|
|
struct gsm_bts *bts;
|
|
|
|
};
|
|
|
|
|
2008-12-27 17:02:56 +00:00
|
|
|
enum gsm_call_type {
|
|
|
|
GSM_CT_NONE,
|
|
|
|
GSM_CT_MO,
|
|
|
|
GSM_CT_MT,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum gsm_call_state {
|
|
|
|
GSM_CSTATE_NULL,
|
|
|
|
GSM_CSTATE_INITIATED,
|
|
|
|
GSM_CSTATE_ACTIVE,
|
|
|
|
GSM_CSTATE_RELEASE_REQ,
|
|
|
|
};
|
|
|
|
|
2009-02-17 15:29:33 +00:00
|
|
|
struct gsm_lchan;
|
|
|
|
struct gsm_subscriber;
|
|
|
|
|
2008-12-27 17:02:56 +00:00
|
|
|
/* One end of a call */
|
|
|
|
struct gsm_call {
|
|
|
|
enum gsm_call_type type;
|
|
|
|
enum gsm_call_state state;
|
|
|
|
u_int8_t transaction_id; /* 10.3.2 */
|
|
|
|
|
2009-02-17 15:29:33 +00:00
|
|
|
/* the 'local' channel */
|
|
|
|
struct gsm_lchan *local_lchan;
|
|
|
|
/* the 'remote' channel */
|
|
|
|
struct gsm_lchan *remote_lchan;
|
|
|
|
|
2009-02-16 22:53:52 +00:00
|
|
|
/* the 'remote' subscriber */
|
|
|
|
struct gsm_subscriber *called_subscr;
|
2008-12-27 17:02:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-12-25 23:28:35 +00:00
|
|
|
enum gsm_phys_chan_config {
|
|
|
|
GSM_PCHAN_NONE,
|
|
|
|
GSM_PCHAN_CCCH,
|
|
|
|
GSM_PCHAN_CCCH_SDCCH4,
|
|
|
|
GSM_PCHAN_TCH_F,
|
|
|
|
GSM_PCHAN_TCH_H,
|
|
|
|
GSM_PCHAN_SDCCH8_SACCH8C,
|
|
|
|
GSM_PCHAN_UNKNOWN,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum gsm_chan_t {
|
|
|
|
GSM_LCHAN_NONE,
|
|
|
|
GSM_LCHAN_SDCCH,
|
|
|
|
GSM_LCHAN_TCH_F,
|
|
|
|
GSM_LCHAN_TCH_H,
|
|
|
|
GSM_LCHAN_UNKNOWN,
|
|
|
|
};
|
|
|
|
|
2008-12-29 04:08:28 +00:00
|
|
|
|
|
|
|
/* Channel Request reason */
|
|
|
|
enum gsm_chreq_reason_t {
|
|
|
|
GSM_CHREQ_REASON_EMERG,
|
|
|
|
GSM_CHREQ_REASON_PAG,
|
|
|
|
GSM_CHREQ_REASON_CALL,
|
|
|
|
GSM_CHREQ_REASON_LOCATION_UPD,
|
|
|
|
GSM_CHREQ_REASON_OTHER,
|
|
|
|
};
|
|
|
|
|
2009-02-14 19:45:44 +00:00
|
|
|
/* Network Management State */
|
|
|
|
struct gsm_nm_state {
|
|
|
|
u_int8_t operational;
|
|
|
|
u_int8_t administrative;
|
2009-02-15 03:38:12 +00:00
|
|
|
u_int8_t availability;
|
|
|
|
};
|
|
|
|
struct gsm_attr {
|
|
|
|
u_int8_t len;
|
|
|
|
u_int8_t data[0];
|
2009-02-14 19:45:44 +00:00
|
|
|
};
|
|
|
|
|
2008-12-31 18:53:57 +00:00
|
|
|
/*
|
|
|
|
* LOCATION UPDATING REQUEST state
|
|
|
|
*
|
|
|
|
* Our current operation is:
|
|
|
|
* - Get imei/tmsi
|
|
|
|
* - Accept/Reject according to global policy
|
|
|
|
*/
|
|
|
|
struct gsm_loc_updating_operation {
|
|
|
|
struct timer_list updating_timer;
|
|
|
|
int waiting_for_imsi : 1;
|
|
|
|
int waiting_for_imei : 1;
|
|
|
|
};
|
|
|
|
|
2008-12-25 23:28:35 +00:00
|
|
|
struct gsm_lchan {
|
|
|
|
/* The TS that we're part of */
|
|
|
|
struct gsm_bts_trx_ts *ts;
|
|
|
|
/* The logical subslot number in the TS */
|
|
|
|
u_int8_t nr;
|
2009-05-23 15:51:12 +00:00
|
|
|
/* The logical channel type */
|
2008-12-25 23:28:35 +00:00
|
|
|
enum gsm_chan_t type;
|
2009-05-23 15:51:12 +00:00
|
|
|
/* If TCH, traffic channel mode */
|
|
|
|
enum gsm_chan_t tch_mode;
|
2009-02-15 16:56:18 +00:00
|
|
|
/* Power levels for MS and BTS */
|
|
|
|
u_int8_t bs_power;
|
|
|
|
u_int8_t ms_power;
|
|
|
|
|
2008-12-25 23:28:35 +00:00
|
|
|
/* To whom we are allocated at the moment */
|
|
|
|
struct gsm_subscriber *subscr;
|
2008-12-30 19:18:21 +00:00
|
|
|
|
|
|
|
/* Timer started to release the channel */
|
|
|
|
struct timer_list release_timer;
|
2008-12-27 17:02:56 +00:00
|
|
|
|
|
|
|
/* local end of a call, if any */
|
|
|
|
struct gsm_call call;
|
2008-12-29 06:23:49 +00:00
|
|
|
|
|
|
|
/* temporary user data, to be removed... and merged into gsm_call */
|
|
|
|
void *user_data;
|
2008-12-29 17:44:08 +00:00
|
|
|
|
2008-12-31 18:53:57 +00:00
|
|
|
/*
|
|
|
|
* Operations that have a state and might be pending
|
|
|
|
*/
|
|
|
|
struct gsm_loc_updating_operation *loc_operation;
|
|
|
|
|
2008-12-29 17:44:08 +00:00
|
|
|
/* use count. how many users use this channel */
|
|
|
|
unsigned int use_count;
|
2008-12-25 23:28:35 +00:00
|
|
|
};
|
|
|
|
|
2009-01-18 17:47:32 +00:00
|
|
|
struct gsm_e1_subslot {
|
|
|
|
/* Number of E1 link */
|
|
|
|
u_int8_t e1_nr;
|
|
|
|
/* Number of E1 TS inside E1 link */
|
|
|
|
u_int8_t e1_ts;
|
|
|
|
/* Sub-slot within the E1 TS, 0xff if full TS */
|
|
|
|
u_int8_t e1_ts_ss;
|
|
|
|
};
|
|
|
|
|
2008-12-23 20:25:15 +00:00
|
|
|
#define BTS_TRX_F_ACTIVATED 0x0001
|
|
|
|
/* One Timeslot in a TRX */
|
|
|
|
struct gsm_bts_trx_ts {
|
|
|
|
struct gsm_bts_trx *trx;
|
|
|
|
/* number of this timeslot at the TRX */
|
|
|
|
u_int8_t nr;
|
|
|
|
|
2008-12-25 23:28:35 +00:00
|
|
|
enum gsm_phys_chan_config pchan;
|
|
|
|
|
2008-12-23 20:25:15 +00:00
|
|
|
unsigned int flags;
|
2009-02-14 19:45:44 +00:00
|
|
|
struct gsm_nm_state nm_state;
|
2009-02-15 03:38:12 +00:00
|
|
|
struct gsm_attr *nm_attr;
|
2008-12-25 23:28:35 +00:00
|
|
|
|
2009-01-18 17:47:32 +00:00
|
|
|
/* To which E1 subslot are we connected */
|
|
|
|
struct gsm_e1_subslot e1_link;
|
2009-02-16 21:12:08 +00:00
|
|
|
struct {
|
|
|
|
u_int32_t bound_ip;
|
|
|
|
u_int16_t bound_port;
|
|
|
|
u_int8_t attr_fc;
|
|
|
|
u_int16_t attr_f8;
|
|
|
|
} abis_ip;
|
2009-01-18 17:47:32 +00:00
|
|
|
|
2008-12-25 23:28:35 +00:00
|
|
|
struct gsm_lchan lchan[TS_MAX_LCHAN];
|
2008-12-23 20:25:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* One TRX in a BTS */
|
|
|
|
struct gsm_bts_trx {
|
|
|
|
struct gsm_bts *bts;
|
|
|
|
/* number of this TRX in the BTS */
|
|
|
|
u_int8_t nr;
|
2009-02-09 18:13:26 +00:00
|
|
|
/* how do we talk RSL with this TRX? */
|
|
|
|
struct e1inp_sign_link *rsl_link;
|
2009-02-14 19:45:44 +00:00
|
|
|
struct gsm_nm_state nm_state;
|
2009-02-15 03:38:12 +00:00
|
|
|
struct gsm_attr *nm_attr;
|
|
|
|
struct {
|
|
|
|
struct gsm_nm_state nm_state;
|
|
|
|
} bb_transc;
|
2008-12-23 20:25:15 +00:00
|
|
|
|
|
|
|
u_int16_t arfcn;
|
2009-06-05 19:18:45 +00:00
|
|
|
|
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
struct {
|
|
|
|
struct gsm_nm_state nm_state;
|
|
|
|
} bbsig;
|
|
|
|
struct {
|
|
|
|
struct gsm_nm_state nm_state;
|
|
|
|
} pa;
|
|
|
|
} bs11;
|
|
|
|
};
|
2009-01-18 17:47:32 +00:00
|
|
|
struct gsm_bts_trx_ts ts[TRX_NR_TS];
|
2008-12-23 20:25:15 +00:00
|
|
|
};
|
|
|
|
|
2009-01-18 17:57:27 +00:00
|
|
|
enum gsm_bts_type {
|
|
|
|
GSM_BTS_TYPE_UNKNOWN,
|
|
|
|
GSM_BTS_TYPE_BS11,
|
2009-02-14 19:45:44 +00:00
|
|
|
GSM_BTS_TYPE_NANOBTS_900,
|
|
|
|
GSM_BTS_TYPE_NANOBTS_1800,
|
2009-01-18 17:57:27 +00:00
|
|
|
};
|
|
|
|
|
2009-02-06 18:54:00 +00:00
|
|
|
/**
|
|
|
|
* A pending paging request
|
|
|
|
*/
|
|
|
|
struct gsm_paging_request {
|
2009-02-16 22:53:52 +00:00
|
|
|
/* list_head for list of all paging requests */
|
2009-02-06 18:54:00 +00:00
|
|
|
struct llist_head entry;
|
2009-02-16 22:53:52 +00:00
|
|
|
/* the subscriber which we're paging. Later gsm_paging_request
|
|
|
|
* should probably become a part of the gsm_subscriber struct? */
|
2009-02-06 18:54:00 +00:00
|
|
|
struct gsm_subscriber *subscr;
|
2009-02-16 22:53:52 +00:00
|
|
|
/* back-pointer to the BTS on which we are paging */
|
2009-02-06 18:54:00 +00:00
|
|
|
struct gsm_bts *bts;
|
2009-02-16 22:53:52 +00:00
|
|
|
/* what kind of channel type do we ask the MS to establish */
|
2009-02-06 18:54:00 +00:00
|
|
|
int chan_type;
|
2009-02-10 17:33:56 +00:00
|
|
|
|
|
|
|
/* Timer 3113: how long do we try to page? */
|
|
|
|
struct timer_list T3113;
|
2009-02-16 22:53:52 +00:00
|
|
|
|
|
|
|
/* callback to be called in case paging completes */
|
|
|
|
gsm_cbfn *cbfn;
|
|
|
|
void *cbfn_param;
|
2009-02-06 18:54:00 +00:00
|
|
|
};
|
2009-02-10 17:33:56 +00:00
|
|
|
#define T3113_VALUE 60, 0
|
2009-02-06 18:54:00 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This keeps track of the paging status of one BTS. It
|
|
|
|
* includes a number of pending requests, a back pointer
|
|
|
|
* to the gsm_bts, a timer and some more state.
|
|
|
|
*/
|
|
|
|
struct gsm_bts_paging_state {
|
|
|
|
/* pending requests */
|
|
|
|
struct llist_head pending_requests;
|
|
|
|
struct gsm_paging_request *last_request;
|
|
|
|
struct gsm_bts *bts;
|
|
|
|
|
2009-02-17 01:39:41 +00:00
|
|
|
struct timer_list work_timer;
|
|
|
|
|
2009-02-10 00:06:19 +00:00
|
|
|
/* load */
|
|
|
|
u_int16_t available_slots;
|
2009-02-06 18:54:00 +00:00
|
|
|
};
|
|
|
|
|
2009-06-05 19:18:45 +00:00
|
|
|
struct gsm_envabtse {
|
|
|
|
struct gsm_nm_state nm_state;
|
|
|
|
};
|
|
|
|
|
2008-12-23 20:25:15 +00:00
|
|
|
/* One BTS */
|
|
|
|
struct gsm_bts {
|
|
|
|
struct gsm_network *network;
|
|
|
|
/* number of ths BTS in network */
|
|
|
|
u_int8_t nr;
|
|
|
|
/* location area code of this BTS */
|
|
|
|
u_int8_t location_area_code;
|
2009-02-28 13:11:07 +00:00
|
|
|
/* Training Sequence Code */
|
|
|
|
u_int8_t tsc;
|
2009-05-23 16:56:52 +00:00
|
|
|
/* Base Station Identification Code (BSIC) */
|
|
|
|
u_int8_t bsic;
|
2009-01-18 17:57:27 +00:00
|
|
|
/* type of BTS */
|
|
|
|
enum gsm_bts_type type;
|
2009-02-09 18:13:26 +00:00
|
|
|
/* how do we talk OML with this TRX? */
|
|
|
|
struct e1inp_sign_link *oml_link;
|
2008-12-23 20:25:15 +00:00
|
|
|
|
|
|
|
/* Abis network management O&M handle */
|
|
|
|
struct abis_nm_h *nmh;
|
2009-02-14 19:45:44 +00:00
|
|
|
struct gsm_nm_state nm_state;
|
2009-02-15 03:38:12 +00:00
|
|
|
struct gsm_attr *nm_attr;
|
2009-01-18 17:57:27 +00:00
|
|
|
|
2008-12-23 20:25:15 +00:00
|
|
|
/* number of this BTS on given E1 link */
|
|
|
|
u_int8_t bts_nr;
|
|
|
|
|
2009-02-04 00:04:52 +00:00
|
|
|
struct gsm48_control_channel_descr chan_desc;
|
|
|
|
|
2009-02-06 18:54:00 +00:00
|
|
|
/* paging state and control */
|
|
|
|
struct gsm_bts_paging_state paging;
|
|
|
|
|
2008-12-23 20:25:15 +00:00
|
|
|
/* CCCH is on C0 */
|
|
|
|
struct gsm_bts_trx *c0;
|
2009-02-14 19:45:44 +00:00
|
|
|
|
|
|
|
struct {
|
|
|
|
struct gsm_nm_state nm_state;
|
|
|
|
} site_mgr;
|
2009-05-01 14:59:07 +00:00
|
|
|
|
|
|
|
/* ip.accesss Unit ID's have Site/BTS/TRX layout */
|
2009-05-28 11:39:21 +00:00
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
u_int16_t site_id;
|
|
|
|
u_int16_t bts_id;
|
|
|
|
} ip_access;
|
|
|
|
struct {
|
|
|
|
struct {
|
|
|
|
struct gsm_nm_state nm_state;
|
|
|
|
} cclk;
|
|
|
|
struct {
|
|
|
|
struct gsm_nm_state nm_state;
|
|
|
|
} rack;
|
2009-06-05 19:18:45 +00:00
|
|
|
struct gsm_envabtse envabtse[4];
|
2009-05-28 11:39:21 +00:00
|
|
|
} bs11;
|
|
|
|
};
|
2009-02-14 19:45:44 +00:00
|
|
|
|
2008-12-23 20:25:15 +00:00
|
|
|
/* transceivers */
|
|
|
|
int num_trx;
|
|
|
|
struct gsm_bts_trx trx[BTS_MAX_TRX+1];
|
|
|
|
};
|
|
|
|
|
|
|
|
struct gsm_network {
|
|
|
|
/* global parameters */
|
2008-12-28 23:42:04 +00:00
|
|
|
u_int16_t country_code;
|
|
|
|
u_int16_t network_code;
|
2008-12-30 18:01:02 +00:00
|
|
|
char *name_long;
|
|
|
|
char *name_short;
|
2008-12-23 20:25:15 +00:00
|
|
|
|
|
|
|
unsigned int num_bts;
|
|
|
|
/* private lists */
|
|
|
|
struct gsm_bts bts[GSM_MAX_BTS+1];
|
|
|
|
};
|
|
|
|
|
2009-03-30 20:56:32 +00:00
|
|
|
#define SMS_HDR_SIZE 128
|
|
|
|
#define SMS_TEXT_SIZE 256
|
|
|
|
struct gsm_sms {
|
|
|
|
u_int64_t id;
|
|
|
|
struct gsm_subscriber *sender;
|
|
|
|
struct gsm_subscriber *receiver;
|
|
|
|
|
|
|
|
unsigned char header[SMS_HDR_SIZE];
|
|
|
|
char text[SMS_TEXT_SIZE];
|
|
|
|
};
|
|
|
|
|
2009-02-15 03:38:12 +00:00
|
|
|
struct gsm_network *gsm_network_init(unsigned int num_bts, enum gsm_bts_type bts_type,
|
|
|
|
u_int16_t country_code, u_int16_t network_code);
|
2008-12-25 23:28:35 +00:00
|
|
|
|
2009-01-04 16:10:38 +00:00
|
|
|
const char *gsm_pchan_name(enum gsm_phys_chan_config c);
|
|
|
|
const char *gsm_lchan_name(enum gsm_chan_t c);
|
|
|
|
const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
|
2009-02-19 17:06:42 +00:00
|
|
|
char *gsm_ts_name(struct gsm_bts_trx_ts *ts);
|
2009-01-04 16:10:38 +00:00
|
|
|
|
2008-12-26 10:20:07 +00:00
|
|
|
enum gsm_e1_event {
|
|
|
|
EVT_E1_NONE,
|
2009-02-09 18:13:26 +00:00
|
|
|
EVT_E1_TEI_UP,
|
|
|
|
EVT_E1_TEI_DN,
|
2008-12-26 10:20:07 +00:00
|
|
|
};
|
|
|
|
|
2009-02-10 17:33:56 +00:00
|
|
|
void set_ts_e1link(struct gsm_bts_trx_ts *ts, u_int8_t e1_nr,
|
|
|
|
u_int8_t e1_ts, u_int8_t e1_ts_ss);
|
2009-03-10 12:15:10 +00:00
|
|
|
enum gsm_bts_type parse_btstype(char *arg);
|
|
|
|
char *btstype2str(enum gsm_bts_type type);
|
2009-05-23 13:56:40 +00:00
|
|
|
struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
|
|
|
|
struct gsm_bts *start_bts);
|
2009-03-10 12:15:10 +00:00
|
|
|
|
|
|
|
static inline int is_ipaccess_bts(struct gsm_bts *bts)
|
|
|
|
{
|
|
|
|
switch (bts->type) {
|
|
|
|
case GSM_BTS_TYPE_NANOBTS_900:
|
|
|
|
case GSM_BTS_TYPE_NANOBTS_1800:
|
|
|
|
return 1;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-12-23 20:25:15 +00:00
|
|
|
#endif
|