diff options
author | Harald Welte <laforge@gnumonks.org> | 2009-06-10 23:11:52 +0800 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2009-06-10 23:25:50 +0800 |
commit | 4bfdfe7f70376612ad2343dd71e8b6ad52124ee6 (patch) | |
tree | cfe0b6321dc1346d72471f1805d5bdf02384498b /openbsc/include/openbsc | |
parent | ec44e1ff4139f60483dfcaa8329e39b41bfb8c4a (diff) |
reworked MNCC codebase
This is Harald's reworked MNCC base, slowly heading towards integration
into master. The key changes are:
* provide much more structure to the data in gsm_mncc
* encode_* and decode_* functions now take a structure rather than tons
of individual arguments (whose order nobody can remember)
* make sure we don't have copies of the same code everywhere by introducing
mncc_set_cause() and mncc_release_ind()
* save horizontal screen space if possible
* make sure we break lines > 80 characters
Diffstat (limited to 'openbsc/include/openbsc')
-rw-r--r-- | openbsc/include/openbsc/gsm_04_08.h | 54 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_data.h | 116 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_subscriber.h | 1 | ||||
-rw-r--r-- | openbsc/include/openbsc/mncc.h | 210 |
4 files changed, 324 insertions, 57 deletions
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index 03922acc7..d83d67bd5 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -540,10 +540,59 @@ struct gsm_meas_rep { void gsm48_parse_meas_rep(struct gsm_meas_rep *rep, const u_int8_t *data, int len); +enum chreq_type { + CHREQ_T_EMERG_CALL, + CHREQ_T_CALL_REEST_TCH_F, + CHREQ_T_CALL_REEST_TCH_H, + CHREQ_T_CALL_REEST_TCH_H_DBL, + CHREQ_T_SDCCH, + CHREQ_T_TCH_F, + CHREQ_T_VOICE_CALL_TCH_H, + CHREQ_T_DATA_CALL_TCH_H, + CHREQ_T_LOCATION_UPD, + CHREQ_T_PAG_R_ANY, + CHREQ_T_PAG_R_TCH_F, + CHREQ_T_PAG_R_TCH_FH, +}; + +/* Chapter 11.3 */ +#define GSM48_T301 180, 0 +#define GSM48_T303 30, 0 +#define GSM48_T305 30, 0 +#define GSM48_T306 30, 0 +#define GSM48_T308 10, 0 +#define GSM48_T310 180, 0 +#define GSM48_T313 30, 0 +#define GSM48_T323 30, 0 +#define GSM48_T331 30, 0 +#define GSM48_T333 30, 0 +#define GSM48_T334 25, 0 /* min 15 */ +#define GSM48_T338 30, 0 + +/* Chapter 5.1.2.2 */ +#define GSM_CSTATE_NULL 0 +#define GSM_CSTATE_INITIATED 1 +#define GSM_CSTATE_MO_CALL_PROC 3 +#define GSM_CSTATE_CALL_DELIVERED 4 +#define GSM_CSTATE_CALL_PRESENT 6 +#define GSM_CSTATE_CALL_RECEIVED 7 +#define GSM_CSTATE_CONNECT_REQUEST 8 +#define GSM_CSTATE_MO_TERM_CALL_CONF 9 +#define GSM_CSTATE_ACTIVE 10 +#define GSM_CSTATE_DISCONNECT_REQ 12 +#define GSM_CSTATE_DISCONNECT_IND 12 +#define GSM_CSTATE_RELEASE_REQ 19 +#define GSM_CSTATE_MO_ORIG_MODIFY 26 +#define GSM_CSTATE_MO_TERM_MODIFY 27 +#define GSM_CSTATE_CONNECT_IND 28 + +#define SBIT(a) (1 << a) +#define ALL_STATES 0xffffffff struct msgb; struct gsm_bts; struct gsm_subscriber; +struct gsm_network; /* config options controlling the behaviour of the lower leves */ void gsm0408_allow_everyone(int allow); @@ -552,7 +601,6 @@ void gsm0408_set_reject_cause(int cause); int gsm0408_rcvmsg(struct msgb *msg); void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc, u_int16_t mnc, u_int16_t lac); -int gsm48_cc_tx_setup(struct gsm_lchan *lchan, struct gsm_subscriber *calling); enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra); enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra); @@ -563,6 +611,10 @@ int generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi); int gsm48_send_rr_release(struct gsm_lchan *lchan); +int bsc_upqueue(struct gsm_network *net); + +int mncc_send(struct gsm_network *net, int msg_type, void *arg); + /* convert a ASCII phone number to call-control BCD */ int encode_bcd_number(u_int8_t *bcd_lv, u_int8_t max_len, int h_len, const char *input); diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 1fb80a2f3..cc92a9e35 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -3,8 +3,37 @@ #include <sys/types.h> +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, +}; + + +/* 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, +}; + #include <openbsc/timer.h> #include <openbsc/gsm_04_08.h> +#include <openbsc/mncc.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -59,66 +88,41 @@ struct gsm_bts_link { struct gsm_bts *bts; }; -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, -}; - struct gsm_lchan; struct gsm_subscriber; +struct gsm_mncc; -/* 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 */ - - /* the 'local' channel */ - struct gsm_lchan *local_lchan; - /* the 'remote' channel */ - struct gsm_lchan *remote_lchan; +/* One transaction */ +struct gsm_trans { + /* Entry in list of all transactions */ + struct llist_head entry; - /* the 'remote' subscriber */ - struct gsm_subscriber *called_subscr; -}; + /* Network */ + struct gsm_network *network; + /* The current transaction ID */ + u_int8_t transaction_id; + + /* The LCHAN that we're part of */ + struct gsm_lchan *lchan; -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, -}; + /* To whom we are allocated at the moment */ + struct gsm_subscriber *subscr; -enum gsm_chan_t { - GSM_LCHAN_NONE, - GSM_LCHAN_SDCCH, - GSM_LCHAN_TCH_F, - GSM_LCHAN_TCH_H, - GSM_LCHAN_UNKNOWN, -}; + /* reference */ + u_int32_t callref; + /* current call state */ + int state; -/* 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, + /* current timer and message queue */ + int Tcurrent; /* current CC timer */ + int T308_second; /* used to send release again */ + struct timer_list cc_timer; + struct gsm_mncc cc_msg; /* stores setup/disconnect/release message */ }; + /* Network Management State */ struct gsm_nm_state { u_int8_t operational; @@ -162,12 +166,6 @@ struct gsm_lchan { /* Timer started to release the channel */ struct timer_list release_timer; - /* local end of a call, if any */ - struct gsm_call call; - - /* temporary user data, to be removed... and merged into gsm_call */ - void *user_data; - /* * Operations that have a state and might be pending */ @@ -355,6 +353,11 @@ struct gsm_network { char *name_long; char *name_short; + /* layer 4 */ + int (*mncc_recv) (struct gsm_network *net, int msg_type, void *arg); + struct llist_head upqueue; + struct llist_head trans_list; + unsigned int num_bts; /* private lists */ struct gsm_bts bts[GSM_MAX_BTS+1]; @@ -372,7 +375,8 @@ struct gsm_sms { }; 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); + u_int16_t country_code, u_int16_t network_code, + int (*mncc_recv)(struct gsm_network *, int, void *)); const char *gsm_pchan_name(enum gsm_phys_chan_config c); const char *gsm_lchan_name(enum gsm_chan_t c); diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index 780d8ede0..dc4f6d7a6 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -12,6 +12,7 @@ #define GSM_EXTENSION_LENGTH 128 struct gsm_subscriber { + struct gsm_network *net; long long unsigned int id; char imsi[GSM_IMSI_LENGTH]; char tmsi[GSM_TMSI_LENGTH]; diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h new file mode 100644 index 000000000..c04a81f6d --- /dev/null +++ b/openbsc/include/openbsc/mncc.h @@ -0,0 +1,210 @@ +/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface + * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */ + +/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org> + * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef _MNCC_H +#define _MNCC_H + +#include <openbsc/linuxlist.h> + +/* One end of a call */ +struct gsm_call { + struct llist_head entry; + + /* network handle */ + void *net; + + /* the 'local' transaction */ + u_int32_t callref; + /* the 'remote' transaction */ + u_int32_t remote_ref; +}; + +#define MNCC_SETUP_REQ 0x0101 +#define MNCC_SETUP_IND 0x0102 +#define MNCC_SETUP_RSP 0x0103 +#define MNCC_SETUP_CNF 0x0104 +#define MNCC_SETUP_COMPL_REQ 0x0105 +#define MNCC_SETUP_COMPL_IND 0x0106 +/* MNCC_REJ_* is perfomed via MNCC_REL_* */ +#define MNCC_CALL_CONF_IND 0x0107 +#define MNCC_CALL_PROC_REQ 0x0108 +#define MNCC_PROGRESS_REQ 0x0109 +#define MNCC_ALERT_REQ 0x010a +#define MNCC_ALERT_IND 0x010b +#define MNCC_NOTIFY_REQ 0x010c +#define MNCC_NOTIFY_IND 0x010d +#define MNCC_DISC_REQ 0x010e +#define MNCC_DISC_IND 0x010f +#define MNCC_REL_REQ 0x0110 +#define MNCC_REL_IND 0x0111 +#define MNCC_REL_CNF 0x0112 +#define MNCC_FACILITY_REQ 0x0113 +#define MNCC_FACILITY_IND 0x0114 +#define MNCC_START_DTMF_IND 0x0115 +#define MNCC_START_DTMF_RSP 0x0116 +#define MNCC_START_DTMF_REJ 0x0117 +#define MNCC_STOP_DTMF_IND 0x0118 +#define MNCC_STOP_DTMF_RSP 0x0119 +#define MNCC_MODIFY_REQ 0x011a +#define MNCC_MODIFY_IND 0x011b +#define MNCC_MODIFY_RSP 0x011c +#define MNCC_MODIFY_CNF 0x011d +#define MNCC_MODIFY_REJ 0x011e +#define MNCC_HOLD_IND 0x011f +#define MNCC_HOLD_CNF 0x0120 +#define MNCC_HOLD_REJ 0x0121 +#define MNCC_RETRIEVE_IND 0x0122 +#define MNCC_RETRIEVE_CNF 0x0123 +#define MNCC_RETRIEVE_REJ 0x0124 +#define MNCC_USERINFO_REQ 0x0125 +#define MNCC_USERINFO_IND 0x0126 +#define MNCC_REJ_REQ 0x0127 +#define MNCC_REJ_IND 0x0128 + +#define MNCC_BRIDGE 0x0200 +#define MNCC_FRAME_RECV 0x0201 +#define MNCC_FRAME_DROP 0x0202 +#define MNCC_LCHAN_MODIFY 0x0203 + +#define GSM_TRAU_FRAME 0x0300 + +#define GSM_MAX_FACILITY 128 +#define GSM_MAX_SSVERSION 128 +#define GSM_MAX_USERUSER 128 + +#define MNCC_F_BEARER_CAP 0x0001 +#define MNCC_F_CALLED 0x0002 +#define MNCC_F_CALLING 0x0004 +#define MNCC_F_REDIRECTING 0x0008 +#define MNCC_F_CONNECTED 0x0010 +#define MNCC_F_CAUSE 0x0020 +#define MNCC_F_USERUSER 0x0040 +#define MNCC_F_PROGRESS 0x0080 +#define MNCC_F_EMERGENCY 0x0100 +#define MNCC_F_FACILITY 0x0200 +#define MNCC_F_SSVERSION 0x0400 +#define MNCC_F_CCCAP 0x0800 +#define MNCC_F_KEYPAD 0x1000 +#define MNCC_F_SIGNAL 0x2000 + +struct gsm_mncc_bearer_cap { + int transfer; + int mode; + int coding; + int radio; + int speech_ctm; + int speech_ver[8]; +}; + +struct gsm_mncc_number { + int type; + int plan; + int present; + int screen; + char number[33]; +}; + +struct gsm_mncc_cause { + int location; + int coding; + int rec; + int rec_val; + int value; + int diag_len; + char diag[32]; +}; + +struct gsm_mncc_useruser { + int proto; + char info[GSM_MAX_USERUSER + 1]; /* + termination char */ +}; + +struct gsm_mncc_progress { + int coding; + int location; + int descr; +}; + +struct gsm_mncc_facility { + int len; + char info[GSM_MAX_FACILITY]; +}; + +struct gsm_mncc_ssversion { + int len; + char info[GSM_MAX_SSVERSION]; +}; + +struct gsm_mncc_cccap { + int dtmf; + int pcp; +}; + + +struct gsm_mncc { + /* context based information */ + u_int32_t msg_type; + u_int32_t callref; + + /* which fields are present */ + u_int32_t fields; + + /* data derived informations (MNCC_F_ based) */ + struct gsm_mncc_bearer_cap bearer_cap; + struct gsm_mncc_number called; + struct gsm_mncc_number calling; + struct gsm_mncc_number redirecting; + struct gsm_mncc_number connected; + struct gsm_mncc_cause cause; + struct gsm_mncc_progress progress; + struct gsm_mncc_useruser useruser; + struct gsm_mncc_facility facility; + struct gsm_mncc_cccap cccap; + struct gsm_mncc_ssversion ssversion; + struct { + int sup; + int inv; + } clir; + int signal; + + /* data derived information, not MNCC_F based */ + int keypad; + int more; + int notify; /* 0..127 */ + int emergency; + + unsigned char lchan_mode; +}; + +struct gsm_trau_frame { + u_int32_t msg_type; + u_int32_t callref; + unsigned char data[0]; +}; + +char *get_mncc_name(int value); +int mncc_recv(struct gsm_network *net, int msg_type, void *arg); +void mncc_set_cause(struct gsm_mncc *data, int loc, int val); + +#endif |