aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/include
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/include')
-rw-r--r--openbsc/include/openbsc/Makefile.am4
-rw-r--r--openbsc/include/openbsc/abis_nm.h7
-rw-r--r--openbsc/include/openbsc/abis_rsl.h3
-rw-r--r--openbsc/include/openbsc/chan_alloc.h1
-rw-r--r--openbsc/include/openbsc/crc24.h8
-rw-r--r--openbsc/include/openbsc/db.h3
-rw-r--r--openbsc/include/openbsc/debug.h3
-rw-r--r--openbsc/include/openbsc/gb_proxy.h42
-rw-r--r--openbsc/include/openbsc/gprs_bssgp.h163
-rw-r--r--openbsc/include/openbsc/gprs_llc.h32
-rw-r--r--openbsc/include/openbsc/gprs_ns.h215
-rw-r--r--openbsc/include/openbsc/gprs_sgsn.h114
-rw-r--r--openbsc/include/openbsc/gsm_04_08.h10
-rw-r--r--openbsc/include/openbsc/gsm_04_08_gprs.h350
-rw-r--r--openbsc/include/openbsc/gsm_data.h74
-rw-r--r--openbsc/include/openbsc/ipaccess.h2
-rw-r--r--openbsc/include/openbsc/rest_octets.h11
-rw-r--r--openbsc/include/openbsc/rtp_proxy.h6
-rw-r--r--openbsc/include/openbsc/sgsn.h30
-rw-r--r--openbsc/include/openbsc/signal.h18
-rw-r--r--openbsc/include/openbsc/vty.h4
-rw-r--r--openbsc/include/sccp/sccp_types.h6
-rw-r--r--openbsc/include/vty/buffer.h2
-rw-r--r--openbsc/include/vty/command.h25
24 files changed, 1106 insertions, 27 deletions
diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am
index 259e6d6f5..afb62dec2 100644
--- a/openbsc/include/openbsc/Makefile.am
+++ b/openbsc/include/openbsc/Makefile.am
@@ -6,7 +6,9 @@ noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \
bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \
silent_call.h mgcp.h meas_rep.h rest_octets.h \
system_information.h handover.h mgcp_internal.h \
- vty.h
+ vty.h \
+ crc24.h gprs_bssgp.h gprs_llc.h gprs_ns.h \
+ gb_proxy.h gprs_sgsn.h gsm_04_08_gprs.h sgsn.h
openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h
openbscdir = $(includedir)/openbsc
diff --git a/openbsc/include/openbsc/abis_nm.h b/openbsc/include/openbsc/abis_nm.h
index 45307e3c8..c20e4e172 100644
--- a/openbsc/include/openbsc/abis_nm.h
+++ b/openbsc/include/openbsc/abis_nm.h
@@ -92,7 +92,7 @@ int abis_nm_sw_act_req_ack(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i1,
int abis_nm_raw_msg(struct gsm_bts *bts, int len, u_int8_t *msg);
int abis_nm_event_reports(struct gsm_bts *bts, int on);
int abis_nm_reset_resource(struct gsm_bts *bts);
-int abis_nm_software_load(struct gsm_bts *bts, const char *fname,
+int abis_nm_software_load(struct gsm_bts *bts, int trx_nr, const char *fname,
u_int8_t win_size, int forced,
gsm_cbfn *cbfn, void *cb_data);
int abis_nm_software_load_status(struct gsm_bts *bts);
@@ -148,7 +148,7 @@ int abis_nm_ipaccess_msg(struct gsm_bts *bts, u_int8_t msg_type,
u_int8_t *attr, int attr_len);
int abis_nm_ipaccess_set_nvattr(struct gsm_bts_trx *trx, u_int8_t *attr,
int attr_len);
-int abis_nm_ipaccess_restart(struct gsm_bts *bts);
+int abis_nm_ipaccess_restart(struct gsm_bts_trx *trx);
int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, u_int8_t obj_class,
u_int8_t bts_nr, u_int8_t trx_nr, u_int8_t ts_nr,
u_int8_t *attr, u_int8_t attr_len);
@@ -164,7 +164,8 @@ enum nm_evt {
EVT_STATECHG_ADM,
};
int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
- struct gsm_nm_state *old_state, struct gsm_nm_state *new_state);
+ struct gsm_nm_state *old_state, struct gsm_nm_state *new_state,
+ struct abis_om_obj_inst *obj_inst);
const char *nm_opstate_name(u_int8_t os);
const char *nm_avail_name(u_int8_t avail);
diff --git a/openbsc/include/openbsc/abis_rsl.h b/openbsc/include/openbsc/abis_rsl.h
index e6973eef0..8e6774d15 100644
--- a/openbsc/include/openbsc/abis_rsl.h
+++ b/openbsc/include/openbsc/abis_rsl.h
@@ -70,10 +70,11 @@ u_int64_t str_to_imsi(const char *imsi_str);
u_int8_t lchan2chan_nr(const struct gsm_lchan *lchan);
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id);
+int rsl_lchan_set_state(struct gsm_lchan *lchan, int);
+
/* to be provided by external code */
int abis_rsl_sendmsg(struct msgb *msg);
int rsl_deact_sacch(struct gsm_lchan *lchan);
-int rsl_chan_release(struct gsm_lchan *lchan);
/* BCCH related code */
int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf);
diff --git a/openbsc/include/openbsc/chan_alloc.h b/openbsc/include/openbsc/chan_alloc.h
index f564e9e4d..d4f5858b7 100644
--- a/openbsc/include/openbsc/chan_alloc.h
+++ b/openbsc/include/openbsc/chan_alloc.h
@@ -45,6 +45,7 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type);
/* Free a logical channel (SDCCH, TCH, ...) */
void lchan_free(struct gsm_lchan *lchan);
+void lchan_reset(struct gsm_lchan *lchan);
/* Consider releasing the channel */
int lchan_auto_release(struct gsm_lchan *lchan);
diff --git a/openbsc/include/openbsc/crc24.h b/openbsc/include/openbsc/crc24.h
new file mode 100644
index 000000000..358fcb58f
--- /dev/null
+++ b/openbsc/include/openbsc/crc24.h
@@ -0,0 +1,8 @@
+#ifndef _CRC24_H
+#define _CRC24_H
+
+#define INIT_CRC24 0xffffff
+
+u_int32_t crc24_calc(u_int32_t fcs, u_int8_t *cp, unsigned int len);
+
+#endif
diff --git a/openbsc/include/openbsc/db.h b/openbsc/include/openbsc/db.h
index d0a1278ef..1782efb50 100644
--- a/openbsc/include/openbsc/db.h
+++ b/openbsc/include/openbsc/db.h
@@ -66,6 +66,9 @@ int db_apdu_blob_store(struct gsm_subscriber *subscr,
u_int8_t *apdu);
/* Statistics counter storage */
+struct counter;
int db_store_counter(struct counter *ctr);
+struct rate_ctr_group;
+int db_store_rate_ctr_group(struct rate_ctr_group *ctrg);
#endif /* _DB_H */
diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h
index f1c5a699a..65fd0bb53 100644
--- a/openbsc/include/openbsc/debug.h
+++ b/openbsc/include/openbsc/debug.h
@@ -29,6 +29,9 @@ enum {
DHO,
DDB,
DREF,
+ DGPRS,
+ DNS,
+ DBSSGP,
Debug_LastEntry,
};
diff --git a/openbsc/include/openbsc/gb_proxy.h b/openbsc/include/openbsc/gb_proxy.h
new file mode 100644
index 000000000..db236b5d0
--- /dev/null
+++ b/openbsc/include/openbsc/gb_proxy.h
@@ -0,0 +1,42 @@
+#ifndef _GB_PROXY_H
+#define _GB_PROXY_H
+
+#include <sys/types.h>
+
+#include <osmocore/msgb.h>
+
+#include <openbsc/gprs_ns.h>
+#include <vty/command.h>
+
+struct gbproxy_config {
+ /* parsed from config file */
+ u_int32_t nsip_listen_ip;
+ u_int16_t nsip_listen_port;
+
+ u_int32_t nsip_sgsn_ip;
+ u_int16_t nsip_sgsn_port;
+
+ u_int16_t nsip_sgsn_nsei;
+ u_int16_t nsip_sgsn_nsvci;
+
+ /* misc */
+ struct gprs_ns_inst *nsi;
+};
+
+extern struct gbproxy_config gbcfg;
+extern struct cmd_element show_gbproxy_cmd;
+
+/* gb_proxy_vty .c */
+
+int gbproxy_vty_init(void);
+int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg);
+
+
+/* gb_proxy.c */
+
+/* Main input function for Gb proxy */
+int gbprox_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci);
+
+int gbprox_signal(unsigned int subsys, unsigned int signal,
+ void *handler_data, void *signal_data);
+#endif
diff --git a/openbsc/include/openbsc/gprs_bssgp.h b/openbsc/include/openbsc/gprs_bssgp.h
new file mode 100644
index 000000000..d3ccb12ee
--- /dev/null
+++ b/openbsc/include/openbsc/gprs_bssgp.h
@@ -0,0 +1,163 @@
+#ifndef _GPRS_BSSGP_H
+#define _GPRS_BSSGP_H
+
+#include <stdint.h>
+
+/* Section 11.3.26 / Table 11.27 */
+enum bssgp_pdu_type {
+ /* PDUs between RL and BSSGP SAPs */
+ BSSGP_PDUT_DL_UNITDATA = 0x00,
+ BSSGP_PDUT_UL_UNITDATA = 0x01,
+ BSSGP_PDUT_RA_CAPABILITY = 0x02,
+ BSSGP_PDUT_PTM_UNITDATA = 0x03,
+ /* PDUs between GMM SAPs */
+ BSSGP_PDUT_PAGING_PS = 0x06,
+ BSSGP_PDUT_PAGING_CS = 0x07,
+ BSSGP_PDUT_RA_CAPA_UDPATE = 0x08,
+ BSSGP_PDUT_RA_CAPA_UPDATE_ACK = 0x09,
+ BSSGP_PDUT_RADIO_STATUS = 0x0a,
+ BSSGP_PDUT_SUSPEND = 0x0b,
+ BSSGP_PDUT_SUSPEND_ACK = 0x0c,
+ BSSGP_PDUT_SUSPEND_NACK = 0x0d,
+ BSSGP_PDUT_RESUME = 0x0e,
+ BSSGP_PDUT_RESUME_ACK = 0x0f,
+ BSSGP_PDUT_RESUME_NACK = 0x10,
+ /* PDus between NM SAPs */
+ BSSGP_PDUT_BVC_BLOCK = 0x20,
+ BSSGP_PDUT_BVC_BLOCK_ACK = 0x21,
+ BSSGP_PDUT_BVC_RESET = 0x22,
+ BSSGP_PDUT_BVC_RESET_ACK = 0x23,
+ BSSGP_PDUT_BVC_UNBLOCK = 0x24,
+ BSSGP_PDUT_BVC_UNBLOCK_ACK = 0x25,
+ BSSGP_PDUT_FLOW_CONTROL_BVC = 0x26,
+ BSSGP_PDUT_FLOW_CONTROL_BVC_ACK = 0x27,
+ BSSGP_PDUT_FLOW_CONTROL_MS = 0x28,
+ BSSGP_PDUT_FLOW_CONTROL_MS_ACK = 0x29,
+ BSSGP_PDUT_FLUSH_LL = 0x2a,
+ BSSGP_PDUT_FLUSH_LL_ACK = 0x2b,
+ BSSGP_PDUT_LLC_DISCARD = 0x2c,
+ BSSGP_PDUT_SGSN_INVOKE_TRACE = 0x40,
+ BSSGP_PDUT_STATUS = 0x41,
+ /* PDUs between PFM SAP's */
+ BSSGP_PDUT_DOWNLOAD_BSS_PFC = 0x50,
+ BSSGP_PDUT_CREATE_BSS_PFC = 0x51,
+ BSSGP_PDUT_CREATE_BSS_PFC_ACK = 0x52,
+ BSSGP_PDUT_CREATE_BSS_PFC_NACK = 0x53,
+ BSSGP_PDUT_MODIFY_BSS_PFC = 0x54,
+ BSSGP_PDUT_MODIFY_BSS_PFC_ACK = 0x55,
+ BSSGP_PDUT_DELETE_BSS_PFC = 0x56,
+ BSSGP_PDUT_DELETE_BSS_PFC_ACK = 0x57,
+};
+
+/* Section 10.2.1 and 10.2.2 */
+struct bssgp_ud_hdr {
+ uint8_t pdu_type;
+ uint32_t tlli;
+ uint8_t qos_profile[3];
+ uint8_t data[0]; /* TLV's */
+} __attribute__((packed));
+
+struct bssgp_normal_hdr {
+ uint8_t pdu_type;
+ uint8_t data[0]; /* TLV's */
+};
+
+enum bssgp_iei_type {
+ BSSGP_IE_ALIGNMENT = 0x00,
+ BSSGP_IE_BMAX_DEFAULT_MS = 0x01,
+ BSSGP_IE_BSS_AREA_ID = 0x02,
+ BSSGP_IE_BUCKET_LEAK_RATE = 0x03,
+ BSSGP_IE_BVCI = 0x04,
+ BSSGP_IE_BVC_BUCKET_SIZE = 0x05,
+ BSSGP_IE_BVC_MEASUREMENT = 0x06,
+ BSSGP_IE_CAUSE = 0x07,
+ BSSGP_IE_CELL_ID = 0x08,
+ BSSGP_IE_CHAN_NEEDED = 0x09,
+ BSSGP_IE_DRX_PARAMS = 0x0a,
+ BSSGP_IE_EMLPP_PRIO = 0x0b,
+ BSSGP_IE_FLUSH_ACTION = 0x0c,
+ BSSGP_IE_IMSI = 0x0d,
+ BSSGP_IE_LLC_PDU = 0x0e,
+ BSSGP_IE_LLC_FRAMES_DISCARDED = 0x0f,
+ BSSGP_IE_LOCATION_AREA = 0x10,
+ BSSGP_IE_MOBILE_ID = 0x11,
+ BSSGP_IE_MS_BUCKET_SIZE = 0x12,
+ BSSGP_IE_MS_RADIO_ACCESS_CAP = 0x13,
+ BSSGP_IE_OMC_ID = 0x14,
+ BSSGP_IE_PDU_IN_ERROR = 0x15,
+ BSSGP_IE_PDU_LIFETIME = 0x16,
+ BSSGP_IE_PRIORITY = 0x17,
+ BSSGP_IE_QOS_PROFILE = 0x18,
+ BSSGP_IE_RADIO_CAUSE = 0x19,
+ BSSGP_IE_RA_CAP_UPD_CAUSE = 0x1a,
+ BSSGP_IE_ROUTEING_AREA = 0x1b,
+ BSSGP_IE_R_DEFAULT_MS = 0x1c,
+ BSSGP_IE_SUSPEND_REF_NR = 0x1d,
+ BSSGP_IE_TAG = 0x1e,
+ BSSGP_IE_TLLI = 0x1f,
+ BSSGP_IE_TMSI = 0x20,
+ BSSGP_IE_TRACE_REFERENC = 0x21,
+ BSSGP_IE_TRACE_TYPE = 0x22,
+ BSSGP_IE_TRANSACTION_ID = 0x23,
+ BSSGP_IE_TRIGGER_ID = 0x24,
+ BSSGP_IE_NUM_OCT_AFF = 0x25,
+ BSSGP_IE_LSA_ID_LIST = 0x26,
+ BSSGP_IE_LSA_INFORMATION = 0x27,
+ BSSGP_IE_PACKET_FLOW_ID = 0x28,
+ BSSGP_IE_PACKET_FLOW_TIMER = 0x29,
+ BSSGP_IE_AGG_BSS_QOS_PROFILE = 0x3a,
+ BSSGP_IE_FEATURE_BITMAP = 0x3b,
+ BSSGP_IE_BUCKET_FULL_RATIO = 0x3c,
+ BSSGP_IE_SERVICE_UTRAN_CCO = 0x3d,
+};
+
+/* Section 11.3.8 / Table 11.10: Cause coding */
+enum gprs_bssgp_cause {
+ BSSGP_CAUSE_PROC_OVERLOAD = 0x00,
+ BSSGP_CAUSE_EQUIP_FAIL = 0x01,
+ BSSGP_CAUSE_TRASIT_NET_FAIL = 0x02,
+ BSSGP_CAUSE_CAPA_GREATER_0KPBS = 0x03,
+ BSSGP_CAUSE_UNKNOWN_MS = 0x04,
+ BSSGP_CAUSE_UNKNOWN_BVCI = 0x05,
+ BSSGP_CAUSE_CELL_TRAF_CONG = 0x06,
+ BSSGP_CAUSE_SGSN_CONG = 0x07,
+ BSSGP_CAUSE_OML_INTERV = 0x08,
+ BSSGP_CAUSE_BVCI_BLOCKED = 0x09,
+ BSSGP_CAUSE_PFC_CREATE_FAIL = 0x0a,
+ BSSGP_CAUSE_SEM_INCORR_PDU = 0x20,
+ BSSGP_CAUSE_INV_MAND_INF = 0x21,
+ BSSGP_CAUSE_MISSING_MAND_IE = 0x22,
+ BSSGP_CAUSE_MISSING_COND_IE = 0x23,
+ BSSGP_CAUSE_UNEXP_COND_IE = 0x24,
+ BSSGP_CAUSE_COND_IE_ERR = 0x25,
+ BSSGP_CAUSE_PDU_INCOMP_STATE = 0x26,
+ BSSGP_CAUSE_PROTO_ERR_UNSPEC = 0x27,
+ BSSGP_CAUSE_PDU_INCOMP_FEAT = 0x28,
+};
+
+/* Our implementation */
+
+/* gprs_bssgp_util.c */
+extern struct gprs_ns_inst *bssgp_nsi;
+struct msgb *bssgp_msgb_alloc(void);
+const char *bssgp_cause_str(enum gprs_bssgp_cause cause);
+/* Transmit a simple response such as BLOCK/UNBLOCK/RESET ACK/NACK */
+int bssgp_tx_simple_bvci(uint8_t pdu_type, uint16_t nsei,
+ uint16_t bvci, uint16_t ns_bvci);
+/* Chapter 10.4.14: Status */
+int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg);
+
+/* gprs_bssgp.c */
+
+#include <osmocore/tlv.h>
+
+extern int gprs_bssgp_rcvmsg(struct msgb *msg);
+uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf);
+
+/* Wrapper around TLV parser to parse BSSGP IEs */
+static inline int bssgp_tlv_parse(struct tlv_parsed *tp, uint8_t *buf, int len)
+{
+ return tlv_parse(tp, &tvlv_att_def, buf, len, 0, 0);
+}
+
+#endif /* _GPRS_BSSGP_H */
diff --git a/openbsc/include/openbsc/gprs_llc.h b/openbsc/include/openbsc/gprs_llc.h
new file mode 100644
index 000000000..5a6682d80
--- /dev/null
+++ b/openbsc/include/openbsc/gprs_llc.h
@@ -0,0 +1,32 @@
+#ifndef _GPRS_LLC_H
+#define _GPRS_LLC_H
+
+#include <stdint.h>
+
+/* Section 4.7 LLC Layer Structure */
+enum gprs_llc_sapi {
+ GPRS_SAPI_GMM = 1,
+ GPRS_SAPI_TOM2 = 2,
+ GPRS_SAPI_SNDCP3 = 3,
+ GPRS_SAPI_SNDCP5 = 5,
+ GPRS_SAPI_SMS = 7,
+ GPRS_SAPI_TOM8 = 8,
+ GPRS_SAPI_SNDCP9 = 9,
+ GPRS_SAPI_SNDCP11 = 11,
+};
+
+/* Section 6.4 Commands and Responses */
+enum gprs_llc_u_cmd {
+ GPRS_LLC_U_DM_RESP = 0x01,
+ GPRS_LLC_U_DISC_CMD = 0x04,
+ GPRS_LLC_U_UA_RESP = 0x06,
+ GPRS_LLC_U_SABM_CMD = 0x07,
+ GPRS_LLC_U_FRMR_RESP = 0x08,
+ GPRS_LLC_U_XID = 0x0b,
+ GPRS_LLC_U_NULL_CMD = 0x00,
+};
+
+int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv);
+int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command);
+
+#endif
diff --git a/openbsc/include/openbsc/gprs_ns.h b/openbsc/include/openbsc/gprs_ns.h
new file mode 100644
index 000000000..4ccf4c7b9
--- /dev/null
+++ b/openbsc/include/openbsc/gprs_ns.h
@@ -0,0 +1,215 @@
+#ifndef _GPRS_NS_H
+#define _GPRS_NS_H
+
+#include <stdint.h>
+
+/* GPRS Networks Service (NS) messages on the Gb interface
+ * 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05)
+ * 3GPP TS 48.016 version 6.5.0 Release 6 / ETSI TS 148 016 V6.5.0 (2005-11) */
+
+struct gprs_ns_hdr {
+ uint8_t pdu_type;
+ uint8_t data[0];
+} __attribute__((packed));
+
+/* TS 08.16, Section 10.3.7, Table 14 */
+enum ns_pdu_type {
+ NS_PDUT_UNITDATA = 0x00,
+ NS_PDUT_RESET = 0x02,
+ NS_PDUT_RESET_ACK = 0x03,
+ NS_PDUT_BLOCK = 0x04,
+ NS_PDUT_BLOCK_ACK = 0x05,
+ NS_PDUT_UNBLOCK = 0x06,
+ NS_PDUT_UNBLOCK_ACK = 0x07,
+ NS_PDUT_STATUS = 0x08,
+ NS_PDUT_ALIVE = 0x0a,
+ NS_PDUT_ALIVE_ACK = 0x0b,
+ /* TS 48.016 Section 10.3.7, Table 10.3.7.1 */
+ SNS_PDUT_ACK = 0x0c,
+ SNS_PDUT_ADD = 0x0d,
+ SNS_PDUT_CHANGE_WEIGHT = 0x0e,
+ SNS_PDUT_CONFIG = 0x0f,
+ SNS_PDUT_CONFIG_ACK = 0x10,
+ SNS_PDUT_DELETE = 0x11,
+ SNS_PDUT_SIZE = 0x12,
+ SNS_PDUT_SIZE_ACK = 0x13,
+};
+
+/* TS 08.16, Section 10.3, Table 12 */
+enum ns_ctrl_ie {
+ NS_IE_CAUSE = 0x00,
+ NS_IE_VCI = 0x01,
+ NS_IE_PDU = 0x02,
+ NS_IE_BVCI = 0x03,
+ NS_IE_NSEI = 0x04,
+ /* TS 48.016 Section 10.3, Table 10.3.1 */
+ NS_IE_IPv4_LIST = 0x05,
+ NS_IE_IPv6_LIST = 0x06,
+ NS_IE_MAX_NR_NSVC = 0x07,
+ NS_IE_IPv4_EP_NR = 0x08,
+ NS_IE_IPv6_EP_NR = 0x09,
+ NS_IE_RESET_FLAG = 0x0a,
+ NS_IE_IP_ADDR = 0x0b,
+};
+
+/* TS 08.16, Section 10.3.2, Table 13 */
+enum ns_cause {
+ NS_CAUSE_TRANSIT_FAIL = 0x00,
+ NS_CAUSE_OM_INTERVENTION = 0x01,
+ NS_CAUSE_EQUIP_FAIL = 0x02,
+ NS_CAUSE_NSVC_BLOCKED = 0x03,
+ NS_CAUSE_NSVC_UNKNOWN = 0x04,
+ NS_CAUSE_BVCI_UNKNOWN = 0x05,
+ NS_CAUSE_SEM_INCORR_PDU = 0x08,
+ NS_CAUSE_PDU_INCOMP_PSTATE = 0x0a,
+ NS_CAUSE_PROTO_ERR_UNSPEC = 0x0b,
+ NS_CAUSE_INVAL_ESSENT_IE = 0x0c,
+ NS_CAUSE_MISSING_ESSENT_IE = 0x0d,
+ /* TS 48.016 Section 10.3.2, Table 10.3.2.1 */
+ NS_CAUSE_INVAL_NR_IPv4_EP = 0x0e,
+ NS_CAUSE_INVAL_NR_IPv6_EP = 0x0f,
+ NS_CAUSE_INVAL_NR_NS_VC = 0x10,
+ NS_CAUSE_INVAL_WEIGH = 0x11,
+ NS_CAUSE_UNKN_IP_EP = 0x12,
+ NS_CAUSE_UNKN_IP_ADDR = 0x13,
+ NS_CAUSE_UNKN_IP_TEST_FAILED = 0x14,
+};
+
+/* Our Implementation */
+#include <netinet/in.h>
+#include <osmocore/linuxlist.h>
+#include <osmocore/msgb.h>
+#include <osmocore/timer.h>
+#include <osmocore/select.h>
+
+#define NS_TIMERS_COUNT 7
+#define NS_TIMERS "(tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries)"
+#define NS_TIMERS_HELP \
+ "(un)blocking Timer (Tns-block) timeout\n" \
+ "(un)blocking Timer (Tns-block) number of retries\n" \
+ "Reset Timer (Tns-reset) timeout\n" \
+ "Reset Timer (Tns-reset) number of retries\n" \
+ "Test Timer (Tns-test) timeout\n" \
+
+enum ns_timeout {
+ NS_TOUT_TNS_BLOCK,
+ NS_TOUT_TNS_BLOCK_RETRIES,
+ NS_TOUT_TNS_RESET,
+ NS_TOUT_TNS_RESET_RETRIES,
+ NS_TOUT_TNS_TEST,
+ NS_TOUT_TNS_ALIVE,
+ NS_TOUT_TNS_ALIVE_RETRIES,
+};
+
+#define NSE_S_BLOCKED 0x0001
+#define NSE_S_ALIVE 0x0002
+
+enum gprs_ns_ll {
+ GPRS_NS_LL_UDP,
+ GPRS_NS_LL_E1,
+};
+
+enum gprs_ns_evt {
+ GPRS_NS_EVT_UNIT_DATA,
+};
+
+struct gprs_nsvc;
+typedef int gprs_ns_cb_t(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
+ struct msgb *msg, uint16_t bvci);
+
+/* An instance of the NS protocol stack */
+struct gprs_ns_inst {
+ /* callback to the user for incoming UNIT DATA IND */
+ gprs_ns_cb_t *cb;
+
+ /* linked lists of all NSVC in this instance */
+ struct llist_head gprs_nsvcs;
+
+ /* a NSVC object that's needed to deal with packets for unknown NSVC */
+ struct gprs_nsvc *unknown_nsvc;
+
+ uint16_t timeout[NS_TIMERS_COUNT];
+
+ /* which link-layer are we based on? */
+ enum gprs_ns_ll ll;
+
+ union {
+ /* NS-over-IP specific bits */
+ struct {
+ struct bsc_fd fd;
+ } nsip;
+ };
+};
+
+enum nsvc_timer_mode {
+ /* standard timers */
+ NSVC_TIMER_TNS_TEST,
+ NSVC_TIMER_TNS_ALIVE,
+ NSVC_TIMER_TNS_RESET,
+ _NSVC_TIMER_NR,
+};
+
+struct gprs_nsvc {
+ struct llist_head list;
+ struct gprs_ns_inst *nsi;
+
+ uint16_t nsei; /* end-to-end significance */
+ uint16_t nsvci; /* uniquely identifies NS-VC at SGSN */
+
+ uint32_t state;
+ uint32_t remote_state;
+
+ struct timer_list timer;
+ enum nsvc_timer_mode timer_mode;
+ int alive_retries;
+
+ unsigned int remote_end_is_sgsn:1;
+ unsigned int persistent:1;
+
+ struct rate_ctr_group *ctrg;
+
+ union {
+ struct {
+ struct sockaddr_in bts_addr;
+ } ip;
+ };
+};
+
+/* Create a new NS protocol instance */
+struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb);
+
+/* Destroy a NS protocol instance */
+void gprs_ns_destroy(struct gprs_ns_inst *nsi);
+
+/* Listen for incoming GPRS packets */
+int nsip_listen(struct gprs_ns_inst *nsi, uint16_t udp_port);
+
+struct sockaddr_in;
+
+/* main entry point, here incoming NS frames enter */
+int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
+ struct sockaddr_in *saddr);
+
+/* main function for higher layers (BSSGP) to send NS messages */
+int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg);
+
+int gprs_ns_tx_reset(struct gprs_nsvc *nsvc, uint8_t cause);
+int gprs_ns_tx_block(struct gprs_nsvc *nsvc, uint8_t cause);
+int gprs_ns_tx_unblock(struct gprs_nsvc *nsvc);
+
+/* Listen for incoming GPRS packets */
+int nsip_listen(struct gprs_ns_inst *nsi, uint16_t udp_port);
+
+/* Establish a connection (from the BSS) to the SGSN */
+struct gprs_nsvc *nsip_connect(struct gprs_ns_inst *nsi,
+ struct sockaddr_in *dest, uint16_t nsei,
+ uint16_t nsvci);
+
+struct gprs_nsvc *nsvc_create(struct gprs_ns_inst *nsi, uint16_t nsvci);
+void nsvc_delete(struct gprs_nsvc *nsvc);
+struct gprs_nsvc *nsvc_by_nsei(struct gprs_ns_inst *nsi, uint16_t nsei);
+
+/* Add NS-specific VTY stuff */
+int gprs_ns_vty_init(struct gprs_ns_inst *nsi);
+
+#endif
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h
new file mode 100644
index 000000000..bdc0b1c8f
--- /dev/null
+++ b/openbsc/include/openbsc/gprs_sgsn.h
@@ -0,0 +1,114 @@
+#ifndef _GPRS_SGSN_H
+#define _GPRS_SGSN_H
+
+#include <stdint.h>
+
+/* TS 04.08 4.1.3.3 GMM mobility management states on the network side */
+enum gprs_mm_state {
+ GMM_DEREGISTERED, /* 4.1.3.3.1.1 */
+ GMM_COMMON_PROC_INIT, /* 4.1.3.3.1.2 */
+ GMM_REGISTERED_NORMAL, /* 4.1.3.3.2.1 */
+ GMM_REGISTERED_SUSPENDED, /* 4.1.3.3.2.2 */
+ GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */
+};
+
+enum gprs_ciph_algo {
+ GPRS_ALGO_GEA0,
+ GPRS_ALGO_GEA1,
+ GPRS_ALGO_GEA2,
+};
+
+#define MS_RADIO_ACCESS_CAPA
+
+/* According to TS 03.60, Table 5: SGSN MM and PDP Contexts */
+/* Extended by 3GPP TS 23.060, Table 6: SGSN MM and PDP Contexts */
+struct sgsn_mm_ctx {
+ struct llist_head list;
+
+ char imsi[GSM_IMSI_LENGTH];
+ enum gprs_mm_state mm_state;
+ uint32_t p_tmsi;
+ uint32_t p_tmsi_sig;
+ char imei[GSM_IMEI_LENGTH];
+ /* Opt: Software Version Numbber / TS 23.195 */
+ char msisdn[GSM_EXTENSION_LENGTH];
+ struct gprs_ra_id ra;
+ uint16_t cell_id;
+ uint32_t cell_id_age;
+ uint16_t sac; /* Iu: Service Area Code */
+ uint32_t sac_age;/* Iu: Service Area Code age */
+ /* VLR number */
+ uint32_t new_sgsn_addr;
+ /* Authentication Triplets */
+ /* Kc */
+ /* Iu: CK, IK, KSI */
+ /* CKSN */
+ enum gprs_ciph_algo ciph_algo;
+ struct {
+ uint8_t buf[14]; /* 10.5.5.12a */
+ uint8_t len;
+ } ms_radio_access_capa;
+ struct {
+ uint8_t buf[4]; /* 10.5.5.12 */
+ uint8_t len;
+ } ms_network_capa;
+ uint16_t drx_parms;
+ int mnrg; /* MS reported to HLR? */
+ int ngaf; /* MS reported to MSC/VLR? */
+ int ppf; /* paging for GPRS + non-GPRS? */
+ /* SMS Parameters */
+ int recovery;
+ uint8_t radio_prio_sms;
+
+ struct llist_head pdp_list;
+
+ /* Additional bits not present in the GSM TS */
+ uint32_t tlli;
+ struct timer_list timer;
+ unsigned int T;
+};
+
+enum pdp_ctx_state {
+ PDP_STAE_NONE,
+};
+
+enum pdp_type {
+ PDP_TYPE_NONE,
+};
+
+struct sgsn_pdp_ctx {
+ struct llist_head list;
+
+ unsigned int id;
+ enum pdp_ctx_state state;
+ enum pdp_type type;
+ uint32_t addresss;
+ char *apn_subscribed;
+ char *apn_used;
+ uint16_t nsapi;
+ uint8_t ti; /* transaction identifier */
+ uint32_t ggsn_in_use;
+ int vplmn_allowed;
+ uint32_t qos_profile_subscr;
+ uint32_t qos_profile_req;
+ uint32_t qos_profile_neg;
+ uint8_t radio_prio;
+ uint32_t tx_npdu_nr;
+ uint32_t rx_npdu_nr;
+ uint32_t tx_gtp_snd;
+ uint32_t rx_gtp_snu;
+ uint32_t charging_id;
+ int reordering_reqd;
+};
+
+/* look-up a SGSN MM context based on TLLI + RAI */
+struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
+ const struct gprs_ra_id *raid);
+struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi);
+struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi);
+
+/* Allocate a new SGSN MM context */
+struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
+ const struct gprs_ra_id *raid);
+
+#endif /* _GPRS_SGSN_H */
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h
index daf3bd780..74dcbe52a 100644
--- a/openbsc/include/openbsc/gsm_04_08.h
+++ b/openbsc/include/openbsc/gsm_04_08.h
@@ -12,6 +12,15 @@ struct gsm_subscriber;
struct gsm_network;
struct gsm_trans;
+#define GSM48_ALLOC_SIZE 1024
+#define GSM48_ALLOC_HEADROOM 128
+
+static inline struct msgb *gsm48_msgb_alloc(void)
+{
+ return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM,
+ "GSM 04.08");
+}
+
/* config options controlling the behaviour of the lower leves */
void gsm0408_allow_everyone(int allow);
@@ -22,7 +31,6 @@ enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra, in
int gsm48_tx_mm_info(struct gsm_lchan *lchan);
int gsm48_tx_mm_auth_req(struct gsm_lchan *lchan, u_int8_t *rand, int key_seq);
int gsm48_tx_mm_auth_rej(struct gsm_lchan *lchan);
-struct msgb *gsm48_msgb_alloc(void);
int gsm48_sendmsg(struct msgb *msg, struct gsm_trans *trans);
int gsm48_send_rr_release(struct gsm_lchan *lchan);
diff --git a/openbsc/include/openbsc/gsm_04_08_gprs.h b/openbsc/include/openbsc/gsm_04_08_gprs.h
new file mode 100644
index 000000000..344b2774b
--- /dev/null
+++ b/openbsc/include/openbsc/gsm_04_08_gprs.h
@@ -0,0 +1,350 @@
+#ifndef _GSM48_GPRS_H
+#define _GSM48_GPRS_H
+
+#include <stdint.h>
+
+/* Table 10.4 / 10.4a, GPRS Mobility Management (GMM) */
+#define GSM48_MT_GMM_ATTACH_REQ 0x01
+#define GSM48_MT_GMM_ATTACH_ACK 0x02
+#define GSM48_MT_GMM_ATTACH_COMPL 0x03
+#define GSM48_MT_GMM_ATTACH_REJ 0x04
+#define GSM48_MT_GMM_DETACH_REQ 0x05
+#define GSM48_MT_GMM_DETACH_ACK 0x06
+
+#define GSM48_MT_GMM_RA_UPD_REQ 0x08
+#define GSM48_MT_GMM_RA_UPD_ACK 0x09
+#define GSM48_MT_GMM_RA_UPD_COMPL 0x0a
+#define GSM48_MT_GMM_RA_UPD_REJ 0x0b
+
+#define GSM48_MT_GMM_PTMSI_REALL_CMD 0x10
+#define GSM48_MT_GMM_PTMSI_REALL_COMPL 0x11
+#define GSM48_MT_GMM_AUTH_CIPH_REQ 0x12
+#define GSM48_MT_GMM_AUTH_CIPH_RESP 0x13
+#define GSM48_MT_GMM_AUTH_CIPH_REJ 0x14
+#define GSM48_MT_GMM_ID_REQ 0x15
+#define GSM48_MT_GMM_ID_RESP 0x16
+#define GSM48_MT_GMM_STATUS 0x20
+#define GSM48_MT_GMM_INFO 0x21
+
+/* Table 10.4a, GPRS Session Management (GSM) */
+#define GSM48_MT_GSM_ACT_PDP_REQ 0x41
+#define GSM48_MT_GSM_ACT_PDP_ACK 0x42
+#define GSM48_MT_GSM_ACT_PDP_REJ 0x43
+#define GSM48_MT_GSM_REQ_PDP_ACT 0x44
+#define GSM48_MT_GSM_REQ_PDP_ACT_REJ 0x45
+#define GSM48_MT_GSM_DEACT_PDP_REQ 0x46
+#define GSM48_MT_GSM_DEACT_PDP_ACK 0x47
+#define GSM48_MT_GSM_ACT_AA_PDP_REQ 0x50
+#define GSM48_MT_GSM_ACT_AA_PDP_ACK 0x51
+#define GSM48_MT_GSM_ACT_AA_PDP_REJ 0x52
+#define GSM48_MT_GSM_DEACT_AA_PDP_REQ 0x53
+#define GSM48_MT_GSM_DEACT_AA_PDP_ACK 0x54
+#define GSM48_MT_GSM_STATUS 0x55
+
+/* Chapter 10.5.5.2 / Table 10.5.135 */
+#define GPRS_ATT_T_ATTACH 1
+#define GPRS_ATT_T_ATT_WHILE_IMSI 2
+#define GPRS_ATT_T_COMBINED 3
+
+/* Chapter 10.5.5.18 / Table 105.150 */
+#define GPRS_UPD_T_RA 0
+#define GPRS_UPD_T_RA_LA 1
+#define GPRS_UPD_T_RA_LA_IMSI_ATT 2
+#define GPRS_UPD_T_PERIODIC 3
+
+enum gsm48_gprs_ie_mm {
+ GSM48_IE_GMM_TIMER_READY = 0x17, /* 10.5.7.3 */
+ GSM48_IE_GMM_PTMSI_SIG = 0x19, /* 10.5.5.8 */
+ GSM48_IE_GMM_AUTH_RAND = 0x21, /* 10.5.3.1 */
+ GSM48_IE_GMM_AUTH_SRES = 0x22, /* 10.5.3.2 */
+ GSM48_IE_GMM_IMEISV = 0x23, /* 10.5.1.4 */
+ GSM48_IE_GMM_DRX_PARAM = 0x27, /* 10.5.5.6 */
+ GSM48_IE_GMM_MS_NET_CAPA = 0x31, /* 10.5.5.12 */
+};
+
+enum gsm48_gprs_ie_sm {
+ GSM48_IE_GSM_APN = 0x28, /* 10.5.6.1 */
+ GSM48_IE_GSM_PROTO_CONF_OPT = 0x27, /* 10.5.6.3 */
+ GSM48_IE_GSM_PDP_ADDR = 0x2b, /* 10.5.6.4 */
+ GSM48_IE_GSM_AA_TMR = 0x29, /* 10.5.7.3 */
+ GSM48_IE_GSM_NAME_FULL = 0x43, /* 10.5.3.5a */
+ GSM48_IE_GSM_NAME_SHORT = 0x45, /* 10.5.3.5a */
+ GSM48_IE_GSM_TIMEZONE = 0x46, /* 10.5.3.8 */
+ GSM48_IE_GSM_UTC_AND_TZ = 0x47, /* 10.5.3.9 */
+ GSM48_IE_GSM_LSA_ID = 0x48, /* 10.5.3.11 */
+};
+
+/* Chapter 9.4.15 / Table 9.4.15 */
+struct gsm48_ra_upd_ack {
+ uint8_t force_stby:4, /* 10.5.5.7 */
+ upd_result:4; /* 10.5.5.17 */
+ uint8_t ra_upd_timer; /* 10.5.7.3 */
+ struct gsm48_ra_id ra_id; /* 10.5.5.15 */
+ uint8_t data[0];
+} __attribute__((packed));
+
+/* Chapter 10.5.7.3 */
+enum gsm48_gprs_tmr_unit {
+ GPRS_TMR_2SECONDS = 0 << 5,
+ GPRS_TMR_MINUTE = 1 << 5,
+ GPRS_TMR_6MINUTE = 2 << 5,
+ GPRS_TMR_DEACTIVATED = 3 << 5,
+};
+
+/* Chapter 9.4.2 / Table 9.4.2 */
+struct gsm48_attach_ack {
+ uint8_t att_result:4, /* 10.5.5.7 */
+ force_stby:4; /* 10.5.5.1 */
+ uint8_t ra_upd_timer; /* 10.5.7.3 */
+ uint8_t radio_prio; /* 10.5.7.2 */
+ struct gsm48_ra_id ra_id; /* 10.5.5.15 */
+ uint8_t data[0];
+} __attribute__((packed));
+
+/* Chapter 9.5.1 / Table 9.5.1 */
+struct gsm48_act_pdp_ctx_req {
+ uint8_t req_nsapi;
+ uint8_t req_llc_sapi;
+ uint8_t data[0];
+} __attribute__((packed));
+
+/* Chapter 10.5.5.14 / Table 10.5.147 */
+enum gsm48_gmm_cause {
+ GMM_CAUSE_IMSI_UNKNOWN = 0x02,
+ GMM_CAUSE_ILLEGAL_MS = 0x03,
+ GMM_CAUSE_ILLEGAL_ME = 0x06,
+ GMM_CAUSE_GPRS_NOTALLOWED = 0x07,
+ GMM_CAUSE_GPRS_OTHER_NOTALLOWED = 0x08,
+ GMM_CAUSE_MS_ID_NOT_DERIVED = 0x09,
+ GMM_CAUSE_IMPL_DETACHED = 0x0a,
+ GMM_CAUSE_PLMN_NOTALLOWED = 0x0b,
+ GMM_CAUSE_LA_NOTALLOWED = 0x0c,
+ GMM_CAUSE_ROAMING_NOTALLOWED = 0x0d,
+ GMM_CAUSE_NO_GPRS_PLMN = 0x0e,
+ GMM_CAUSE_MSC_TEMP_NOTREACH = 0x10,
+ GMM_CAUSE_NET_FAIL = 0x11,
+ GMM_CAUSE_CONGESTION = 0x16,
+ GMM_CAUSE_SEM_INCORR_MSG = 0x5f,
+ GMM_CAUSE_INV_MAND_INFO = 0x60,
+ GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL = 0x61,
+ GMM_CAUSE_MSGT_INCOMP_P_STATE = 0x62,
+ GMM_CAUSE_IE_NOTEXIST_NOTIMPL = 0x63,
+ GMM_CAUSE_COND_IE_ERR = 0x64,
+ GMM_CAUSE_MSG_INCOMP_P_STATE = 0x65,
+ GMM_CAUSE_PROTO_ERR_UNSPEC = 0x6f,
+};
+
+/* Chapter 10.4.6.6 / Table 10.5.157 */
+enum gsm48_gsm_cause {
+ GSM_CAUSE_INSUFF_RSRC = 0x1a,
+ GSM_CAUSE_MISSING_APN = 0x1b,
+ GSM_CAUSE_UNKNOWN_PDP = 0x1c,
+ GSM_CAUSE_AUTH_FAILED = 0x1d,
+ GSM_CAUSE_ACT_REJ_GGSN = 0x1e,
+ GSM_CAUSE_ACT_REJ_UNSPEC = 0x1f,
+ GSM_CAUSE_SERV_OPT_NOTSUPP = 0x20,
+ GSM_CAUSE_REQ_SERV_OPT_NOTSUB = 0x21,
+ GSM_CAUSE_SERV_OPT_TEMP_OOO = 0x22,
+ GSM_CAUSE_NSAPI_IN_USE = 0x23,
+ GSM_CAUSE_DEACT_REGULAR = 0x24,
+ GSM_CAUSE_QOS_NOT_ACCEPTED = 0x25,
+ GSM_CAUSE_NET_FAIL = 0x26,
+ GSM_CAUSE_REACT_RQD = 0x27,
+ GSM_CAUSE_FEATURE_NOTSUPP = 0x28,
+ GSM_CAUSE_INVALID_TRANS_ID = 0x51,
+ GSM_CAUSE_SEM_INCORR_MSG = 0x5f,
+ GSM_CAUSE_INV_MAND_INFO = 0x60,
+ GSM_CAUSE_MSGT_NOTEXIST_NOTIMPL = 0x61,
+ GSM_CAUSE_MSGT_INCOMP_P_STATE = 0x62,
+ GSM_CAUSE_IE_NOTEXIST_NOTIMPL = 0x63,
+ GSM_CAUSE_COND_IE_ERR = 0x64,
+ GSM_CAUSE_MSG_INCOMP_P_STATE = 0x65,
+ GSM_CAUSE_PROTO_ERR_UNSPEC = 0x6f,
+};
+
+/* Section 6.1.2.2: Session management states on the network side */
+enum gsm48_pdp_state {
+ PDP_S_INACTIVE,
+ PDP_S_ACTIVE_PENDING,
+ PDP_S_ACTIVE,
+ PDP_S_INACTIVE_PENDING,
+ PDP_S_MODIFY_PENDING,
+};
+
+/* Table 10.5.155/3GPP TS 24.008 */
+enum gsm48_pdp_type_org {
+ PDP_TYPE_ORG_ETSI = 0x00,
+ PDP_TYPE_ORG_IETF = 0x01,
+};
+enum gsm48_pdp_type_nr {
+ PDP_TYPE_N_ETSI_RESERVED = 0x00,
+ PDP_TYPE_N_ETSI_PPP = 0x01,
+ PDP_TYPE_N_IETF_IPv4 = 0x21,
+ PDP_TYPE_N_IETF_IPv6 = 0x57,
+};
+
+/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
+enum gsm48_qos_reliab_class {
+ GSM48_QOS_RC_LLC_ACK_RLC_ACK_DATA_PROT = 2,
+ GSM48_QOS_RC_LLC_UN_RLC_ACK_DATA_PROT = 3,
+ GSM48_QOS_RC_LLC_UN_RLC_UN_PROT_DATA = 4,
+ GSM48_QOS_RC_LLC_UN_RLC_UN_DATA_UN = 5,
+};
+
+/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
+enum gsm48_qos_preced_class {
+ GSM48_QOS_PC_HIGH = 1,
+ GSM48_QOS_PC_NORMAL = 2,
+ GSM48_QOS_PC_LOW = 3,
+};
+
+/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
+enum gsm48_qos_peak_tput {
+ GSM48_QOS_PEAK_TPUT_1000bps = 1,
+ GSM48_QOS_PEAK_TPUT_2000bps = 2,
+ GSM48_QOS_PEAK_TPUT_4000bps = 3,
+ GSM48_QOS_PEAK_TPUT_8000bps = 4,
+ GSM48_QOS_PEAK_TPUT_16000bps = 5,
+ GSM48_QOS_PEAK_TPUT_32000bps = 6,
+ GSM48_QOS_PEAK_TPUT_64000bps = 7,
+ GSM48_QOS_PEAK_TPUT_128000bps = 8,
+ GSM48_QOS_PEAK_TPUT_256000bps = 9,
+};
+
+/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
+enum gsm48_qos_mean_tput {
+ GSM48_QOS_MEAN_TPUT_100bph = 1,
+ GSM48_QOS_MEAN_TPUT_200bph = 2,
+ GSM48_QOS_MEAN_TPUT_500bph = 3,
+ GSM48_QOS_MEAN_TPUT_1000bph = 4,
+ GSM48_QOS_MEAN_TPUT_2000bph = 5,
+ GSM48_QOS_MEAN_TPUT_5000bph = 6,
+ GSM48_QOS_MEAN_TPUT_10000bph = 7,
+ GSM48_QOS_MEAN_TPUT_20000bph = 8,
+ GSM48_QOS_MEAN_TPUT_50000bph = 9,
+ GSM48_QOS_MEAN_TPUT_100kbph = 10,
+ GSM48_QOS_MEAN_TPUT_200kbph = 11,
+ GSM48_QOS_MEAN_TPUT_500kbph = 0xc,
+ GSM48_QOS_MEAN_TPUT_1Mbph = 0xd,
+ GSM48_QOS_MEAN_TPUT_2Mbph = 0xe,
+ GSM48_QOS_MEAN_TPUT_5Mbph = 0xf,
+ GSM48_QOS_MEAN_TPUT_10Mbph = 0x10,
+ GSM48_QOS_MEAN_TPUT_20Mbph = 0x11,
+ GSM48_QOS_MEAN_TPUT_50Mbph = 0x12,
+ GSM48_QOS_MEAN_TPUT_BEST_EFFORT = 0x1f,
+};
+
+/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
+enum gsm48_qos_err_sdu {
+ GSM48_QOS_ERRSDU_NODETECT = 1,
+ GSM48_QOS_ERRSDU_YES = 2,
+ GSM48_QOS_ERRSDU_NO = 3,
+};
+
+/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
+enum gsm48_qos_deliv_order {
+ GSM48_QOS_DO_ORDERED = 1,
+ GSM48_QOS_DO_UNORDERED = 2,
+};
+
+/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
+enum gsm48_qos_traf_class {
+ GSM48_QOS_TC_CONVERSATIONAL = 1,
+ GSM48_QOS_TC_STREAMING = 2,
+ GSM48_QOS_TC_INTERACTIVE = 3,
+ GSM48_QOS_TC_BACKGROUND = 4,
+};
+
+/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
+enum gsm48_qos_max_sdu_size {
+ /* values below in 10 octet granularity */
+ GSM48_QOS_MAXSDU_1502 = 0x97,
+ GSM48_QOS_MAXSDU_1510 = 0x98,
+ GSM48_QOS_MAXSDU_1520 = 0x99,
+};
+
+/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
+enum gsm48_qos_max_bitrate {
+ GSM48_QOS_MBRATE_1k = 0x01,
+ GSM48_QOS_MBRATE_63k = 0x3f,
+ GSM48_QOS_MBRATE_64k = 0x40,
+ GSM48_QOS_MBRATE_568k = 0x7f,
+ GSM48_QOS_MBRATE_576k = 0x80,
+ GSM48_QOS_MBRATE_8640k = 0xfe,
+ GSM48_QOS_MBRATE_0k = 0xff,
+};
+
+/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
+enum gsm48_qos_resid_ber {
+ GSM48_QOS_RBER_5e_2 = 0x01,
+ GSM48_QOS_RBER_1e_2 = 0x02,
+ GSM48_QOS_RBER_5e_3 = 0x03,
+ GSM48_QOS_RBER_4e_3 = 0x04,
+ GSM48_QOS_RBER_1e_3 = 0x05,
+ GSM48_QOS_RBER_1e_4 = 0x06,
+ GSM48_QOS_RBER_1e_5 = 0x07,
+ GSM48_QOS_RBER_1e_6 = 0x08,
+ GSM48_QOS_RBER_6e_8 = 0x09,
+};
+
+/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
+enum gsm48_qos_sdu_err {
+ GSM48_QOS_SERR_1e_2 = 0x01,
+ GSM48_QOS_SERR_7e_2 = 0x02,
+ GSM48_QOS_SERR_1e_3 = 0x03,
+ GSM48_QOS_SERR_1e_4 = 0x04,
+ GSM48_QOS_SERR_1e_5 = 0x05,
+ GSM48_QOS_SERR_1e_6 = 0x06,
+ GSM48_QOS_SERR_1e_1 = 0x07,
+};
+
+/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
+struct gsm48_qos {
+ /* octet 3 */
+ uint8_t reliab_class:3;
+ uint8_t delay_class:3;
+ uint8_t spare:2;
+ /* octet 4 */
+ uint8_t preced_class:3;
+ uint8_t spare2:1;
+ uint8_t peak_tput:4;
+ /* octet 5 */
+ uint8_t mean_tput:5;
+ uint8_t spare3:3;
+ /* octet 6 */
+ uint8_t deliv_err_sdu:3;
+ uint8_t deliv_order:2;
+ uint8_t traf_class:3;
+ /* octet 7 */
+ uint8_t max_sdu_size;
+ /* octet 8 */
+ uint8_t max_bitrate_up;
+ /* octet 9 */
+ uint8_t max_bitrate_down;
+ /* octet 10 */
+ uint8_t sdu_err_ratio:4;
+ uint8_t resid_ber:4;
+ /* octet 11 */
+ uint8_t handling_prio:2;
+ uint8_t xfer_delay:6;
+ /* octet 12 */
+ uint8_t guar_bitrate_up;
+ /* octet 13 */
+ uint8_t guar_bitrate_down;
+ /* octet 14 */
+ uint8_t src_stats_desc:4;
+ uint8_t sig_ind:1;
+ uint8_t spare5:3;
+ /* octet 15 */
+ uint8_t max_bitrate_down_ext;
+ /* octet 16 */
+ uint8_t guar_bitrate_down_ext;
+};
+
+
+int gprs_tlli_type(uint32_t tlli);
+
+struct gsm_bts *gsm48_bts_by_ra_id(struct gsm_network *net,
+ const uint8_t *buf, unsigned int len);
+
+#endif /* _GSM48_GPRS_H */
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 8dfa5886b..91527c933 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -73,6 +73,37 @@ enum gsm_paging_event {
GSM_PAGING_OOM,
};
+enum bts_gprs_mode {
+ BTS_GPRS_NONE = 0,
+ BTS_GPRS_GPRS = 1,
+ BTS_GPRS_EGPRS = 2,
+};
+
+/* the data structure stored in msgb->cb for openbsc apps */
+struct openbsc_msgb_cb {
+ unsigned char *bssgph;
+ unsigned char *llch;
+
+ /* Cell Identifier */
+ unsigned char *bssgp_cell_id;
+
+ /* Identifiers of a BTS, equal to 'struct bssgp_bts_ctx' */
+ u_int16_t nsei;
+ u_int16_t bvci;
+
+ /* Identifier of a MS (inside BTS), equal to 'struct sgsn_mm_ctx' */
+ u_int32_t tlli;
+} __attribute__((packed));
+#define OBSC_MSGB_CB(__msgb) ((struct openbsc_msgb_cb *)&((__msgb)->cb[0]))
+#define msgb_tlli(__x) OBSC_MSGB_CB(__x)->tlli
+#define msgb_nsei(__x) OBSC_MSGB_CB(__x)->nsei
+#define msgb_bvci(__x) OBSC_MSGB_CB(__x)->bvci
+#define msgb_gmmh(__x) (__x)->l3h
+#define msgb_bssgph(__x) OBSC_MSGB_CB(__x)->bssgph
+#define msgb_bssgp_len(__x) ((__x)->tail - (uint8_t *)msgb_bssgph(__x))
+#define msgb_bcid(__x) OBSC_MSGB_CB(__x)->bssgp_cell_id
+#define msgb_llch(__x) OBSC_MSGB_CB(__x)->llch
+
struct msgb;
typedef int gsm_cbfn(unsigned int hooknum,
unsigned int event,
@@ -99,11 +130,6 @@ typedef int gsm_cbfn(unsigned int hooknum,
} while(0);
-/* communications link with a BTS */
-struct gsm_bts_link {
- struct gsm_bts *bts;
-};
-
/* Real authentication information containing Ki */
enum gsm_auth_algo {
AUTH_ALGO_NONE,
@@ -250,6 +276,7 @@ struct gsm_lchan {
u_int16_t bound_port;
u_int16_t connect_port;
u_int16_t conn_id;
+ u_int8_t rtp_payload;
u_int8_t rtp_payload2;
u_int8_t speech_mode;
struct rtp_socket *rtp_socket;
@@ -368,7 +395,6 @@ struct gsm_paging_request {
struct gsm_bts_paging_state {
/* pending requests */
struct llist_head pending_requests;
- struct gsm_paging_request *last_request;
struct gsm_bts *bts;
struct timer_list work_timer;
@@ -383,11 +409,14 @@ struct gsm_envabtse {
struct gsm_bts_gprs_nsvc {
struct gsm_bts *bts;
+ /* data read via VTY config file, to configure the BTS
+ * via OML from BSC */
int id;
u_int16_t nsvci;
- u_int16_t local_port;
- u_int16_t remote_port;
- u_int32_t remote_ip;
+ u_int16_t local_port; /* on the BTS */
+ u_int16_t remote_port; /* on the SGSN */
+ u_int32_t remote_ip; /* on the SGSN */
+
struct gsm_nm_state nm_state;
};
@@ -476,18 +505,24 @@ struct gsm_bts {
/* Not entirely sure how ip.access specific this is */
struct {
- int enabled;
+ enum bts_gprs_mode mode;
struct {
struct gsm_nm_state nm_state;
u_int16_t nsei;
+ uint8_t timer[7];
} nse;
struct {
struct gsm_nm_state nm_state;
u_int16_t bvci;
+ uint8_t timer[11];
} cell;
struct gsm_bts_gprs_nsvc nsvc[2];
u_int8_t rac;
} gprs;
+
+ /* RACH NM values */
+ int rach_b_thresh;
+ int rach_ldavg_slots;
/* transceivers */
int num_trx;
@@ -535,6 +570,14 @@ struct gsmnet_stats {
struct counter *alerted; /* we alerted the other end */
struct counter *connected;/* how many calls were accepted */
} call;
+ struct {
+ struct counter *rf_fail;
+ struct counter *rll_err;
+ } chan;
+ struct {
+ struct counter *oml_fail;
+ struct counter *rsl_fail;
+ } bts;
};
enum gsm_auth_policy {
@@ -697,15 +740,10 @@ const char *gsm_auth_policy_name(enum gsm_auth_policy policy);
enum rrlp_mode rrlp_mode_parse(const char *arg);
const char *rrlp_mode_name(enum rrlp_mode mode);
-void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
+enum bts_gprs_mode bts_gprs_mode_parse(const char *arg);
+const char *bts_gprs_mode_name(enum bts_gprs_mode mode);
-/* A parsed GPRS routing area */
-struct gprs_ra_id {
- u_int16_t mnc;
- u_int16_t mcc;
- u_int16_t lac;
- u_int8_t rac;
-};
+void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
int gsm48_ra_id_by_bts(u_int8_t *buf, struct gsm_bts *bts);
void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts);
diff --git a/openbsc/include/openbsc/ipaccess.h b/openbsc/include/openbsc/ipaccess.h
index 86248aae5..f8ddfd467 100644
--- a/openbsc/include/openbsc/ipaccess.h
+++ b/openbsc/include/openbsc/ipaccess.h
@@ -53,6 +53,8 @@ int ipaccess_send_id_req(int fd);
int ipaccess_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len);
+int ipaccess_drop_oml(struct gsm_bts *bts);
+int ipaccess_drop_rsl(struct gsm_bts_trx *trx);
/*
* Firmware specific header
diff --git a/openbsc/include/openbsc/rest_octets.h b/openbsc/include/openbsc/rest_octets.h
index 4e72c0f87..6d9011963 100644
--- a/openbsc/include/openbsc/rest_octets.h
+++ b/openbsc/include/openbsc/rest_octets.h
@@ -71,6 +71,7 @@ enum gprs_nmo {
GPRS_NMO_III = 2, /* no paging coordination */
};
+/* TS 04.60 12.24 */
struct gprs_cell_options {
enum gprs_nmo nmo;
/* T3168: wait for packet uplink assignment message */
@@ -79,6 +80,16 @@ struct gprs_cell_options {
u_int32_t t3192; /* in milliseconds */
u_int32_t drx_timer_max;/* in seconds */
u_int32_t bs_cv_max;
+
+ u_int8_t ext_info_present;
+ struct {
+ u_int8_t egprs_supported;
+ u_int8_t use_egprs_p_ch_req;
+ u_int8_t bep_period;
+ u_int8_t pfc_supported;
+ u_int8_t dtm_supported;
+ u_int8_t bss_paging_coordination;
+ } ext_info;
};
/* TS 04.60 Table 12.9.2 */
diff --git a/openbsc/include/openbsc/rtp_proxy.h b/openbsc/include/openbsc/rtp_proxy.h
index f82711a8e..65b1a5fac 100644
--- a/openbsc/include/openbsc/rtp_proxy.h
+++ b/openbsc/include/openbsc/rtp_proxy.h
@@ -28,6 +28,12 @@
#include <osmocore/linuxlist.h>
#include <osmocore/select.h>
+#define RTP_PT_GSM_FULL 3
+#define RTP_PT_GSM_HALF 96
+#define RTP_PT_GSM_EFR 97
+#define RTP_PT_AMR_FULL 98
+#define RTP_PT_AMR_HALF 99
+
enum rtp_rx_action {
RTP_NONE,
RTP_PROXY,
diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h
new file mode 100644
index 000000000..2dc53c13d
--- /dev/null
+++ b/openbsc/include/openbsc/sgsn.h
@@ -0,0 +1,30 @@
+#ifndef _SGSN_H
+#define _SGSN_H
+
+#include <sys/types.h>
+
+#include <osmocore/msgb.h>
+
+#include <openbsc/gprs_ns.h>
+
+struct sgsn_config {
+ /* parsed from config file */
+ u_int32_t nsip_listen_ip;
+ u_int16_t nsip_listen_port;
+
+ /* misc */
+ struct gprs_ns_inst *nsi;
+};
+
+
+/* sgsn_vty.c */
+
+int sgsn_vty_init(void);
+int sgsn_parse_config(const char *config_file, struct sgsn_config *cfg);
+
+/* sgsn.c */
+
+/* Main input function for Gb proxy */
+int sgsn_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci);
+
+#endif
diff --git a/openbsc/include/openbsc/signal.h b/openbsc/include/openbsc/signal.h
index 1b974e288..48f7946b3 100644
--- a/openbsc/include/openbsc/signal.h
+++ b/openbsc/include/openbsc/signal.h
@@ -26,7 +26,6 @@
#include <errno.h>
#include <openbsc/gsm_data.h>
-#include <openbsc/gsm_subscriber.h>
#include <osmocore/signal.h>
@@ -43,6 +42,7 @@ enum signal_subsystems {
SS_SCALL,
SS_GLOBAL,
SS_CHALLOC,
+ SS_NS,
};
/* SS_PAGING signals */
@@ -118,6 +118,8 @@ enum signal_global {
S_GLOBAL_SHUTDOWN,
};
+struct gsm_subscriber;
+
struct paging_signal_data {
struct gsm_subscriber *subscr;
struct gsm_bts *bts;
@@ -133,7 +135,7 @@ struct scall_signal_data {
};
struct ipacc_ack_signal_data {
- struct gsm_bts *bts;
+ struct gsm_bts_trx *trx;
u_int8_t msg_type;
};
@@ -143,4 +145,16 @@ struct challoc_signal_data {
enum gsm_chan_t type;
};
+enum signal_ns {
+ S_NS_RESET,
+ S_NS_BLOCK,
+ S_NS_UNBLOCK,
+ S_NS_ALIVE_EXP, /* Tns-alive expired more than N times */
+};
+
+struct ns_signal_data {
+ struct gprs_nsvc *nsvc;
+ uint8_t cause;
+};
+
#endif
diff --git a/openbsc/include/openbsc/vty.h b/openbsc/include/openbsc/vty.h
index 40e219162..f1b1148ad 100644
--- a/openbsc/include/openbsc/vty.h
+++ b/openbsc/include/openbsc/vty.h
@@ -1,6 +1,10 @@
#ifndef OPENBSC_VTY_H
#define OPENBSC_VTY_H
+struct gsm_network;
+struct vty;
+
void openbsc_vty_add_cmds(void);
+void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *);
#endif
diff --git a/openbsc/include/sccp/sccp_types.h b/openbsc/include/sccp/sccp_types.h
index 42fda96ae..22bd70f21 100644
--- a/openbsc/include/sccp/sccp_types.h
+++ b/openbsc/include/sccp/sccp_types.h
@@ -411,4 +411,10 @@ struct sccp_data_it {
u_int8_t credit;
} __attribute__((packed));
+struct sccp_proto_err {
+ u_int8_t type;
+ struct sccp_source_reference destination_local_reference;
+ u_int8_t error_cause;
+};
+
#endif
diff --git a/openbsc/include/vty/buffer.h b/openbsc/include/vty/buffer.h
index 31519400f..c9467a91d 100644
--- a/openbsc/include/vty/buffer.h
+++ b/openbsc/include/vty/buffer.h
@@ -28,7 +28,7 @@
/* Create a new buffer. Memory will be allocated in chunks of the given
size. If the argument is 0, the library will supply a reasonable
default size suitable for buffering socket I/O. */
-struct buffer *buffer_new(size_t);
+struct buffer *buffer_new(void *ctx, size_t);
/* Free all data in the buffer. */
void buffer_reset(struct buffer *);
diff --git a/openbsc/include/vty/command.h b/openbsc/include/vty/command.h
index 03b071f70..1b6e0a7b7 100644
--- a/openbsc/include/vty/command.h
+++ b/openbsc/include/vty/command.h
@@ -107,6 +107,9 @@ enum node_type {
TS_NODE,
SUBSCR_NODE,
MGCP_NODE,
+ GBPROXY_NODE,
+ SGSN_NODE,
+ NS_NODE,
};
/* Node which has some commands and prompt string and configuration
@@ -173,6 +176,17 @@ struct desc {
/* helper defines for end-user DEFUN* macros */
#define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
+ static struct cmd_element cmdname = \
+ { \
+ .string = cmdstr, \
+ .func = funcname, \
+ .doc = helpstr, \
+ .attr = attrs, \
+ .daemon = dnum, \
+ };
+
+/* global (non static) cmd_element */
+#define gDEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
struct cmd_element cmdname = \
{ \
.string = cmdstr, \
@@ -195,6 +209,12 @@ struct desc {
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
DEFUN_CMD_FUNC_TEXT(funcname)
+/* global (non static) cmd_element */
+#define gDEFUN(funcname, cmdname, cmdstr, helpstr) \
+ DEFUN_CMD_FUNC_DECL(funcname) \
+ gDEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
+ DEFUN_CMD_FUNC_TEXT(funcname)
+
#define DEFUN_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \
DEFUN_CMD_FUNC_DECL(funcname) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0) \
@@ -236,6 +256,10 @@ struct desc {
#define ALIAS(funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0)
+/* global (non static) cmd_element */
+#define gALIAS(funcname, cmdname, cmdstr, helpstr) \
+ gDEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0)
+
#define ALIAS_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0)
@@ -326,6 +350,7 @@ struct desc {
void install_node(struct cmd_node *, int (*)(struct vty *));
void install_default(enum node_type);
void install_element(enum node_type, struct cmd_element *);
+void install_element_ve(struct cmd_element *cmd);
void sort_node();
/* Concatenates argv[shift] through argv[argc-1] into a single NUL-terminated