aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/include/openbsc
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2009-06-10 23:11:52 +0800
committerHarald Welte <laforge@gnumonks.org>2009-06-10 23:25:50 +0800
commit4bfdfe7f70376612ad2343dd71e8b6ad52124ee6 (patch)
treecfe0b6321dc1346d72471f1805d5bdf02384498b /openbsc/include/openbsc
parentec44e1ff4139f60483dfcaa8329e39b41bfb8c4a (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.h54
-rw-r--r--openbsc/include/openbsc/gsm_data.h116
-rw-r--r--openbsc/include/openbsc/gsm_subscriber.h1
-rw-r--r--openbsc/include/openbsc/mncc.h210
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