aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/include
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/include')
-rw-r--r--openbsc/include/openbsc/Makefile.am2
-rw-r--r--openbsc/include/openbsc/abis_rsl.h2
-rw-r--r--openbsc/include/openbsc/bsc_msc.h46
-rw-r--r--openbsc/include/openbsc/bsc_nat.h212
-rw-r--r--openbsc/include/openbsc/bssap.h336
-rw-r--r--openbsc/include/openbsc/chan_alloc.h26
-rw-r--r--openbsc/include/openbsc/debug.h1
-rw-r--r--openbsc/include/openbsc/gsm_04_08.h5
-rw-r--r--openbsc/include/openbsc/gsm_data.h93
-rw-r--r--openbsc/include/openbsc/gsm_subscriber.h2
-rw-r--r--openbsc/include/openbsc/mgcp.h27
-rw-r--r--openbsc/include/openbsc/mgcp_internal.h9
-rw-r--r--openbsc/include/sccp/sccp.h7
-rw-r--r--openbsc/include/vty/command.h2
14 files changed, 734 insertions, 36 deletions
diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am
index 259e6d6f5..25e3f4dd9 100644
--- a/openbsc/include/openbsc/Makefile.am
+++ b/openbsc/include/openbsc/Makefile.am
@@ -6,7 +6,7 @@ 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 bssap.h bsc_msc.h bsc_nat.h
openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h
openbscdir = $(includedir)/openbsc
diff --git a/openbsc/include/openbsc/abis_rsl.h b/openbsc/include/openbsc/abis_rsl.h
index e6973eef0..c8ac1dead 100644
--- a/openbsc/include/openbsc/abis_rsl.h
+++ b/openbsc/include/openbsc/abis_rsl.h
@@ -68,7 +68,7 @@ unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res);
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_release_request(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t release_reason);
/* to be provided by external code */
int abis_rsl_sendmsg(struct msgb *msg);
diff --git a/openbsc/include/openbsc/bsc_msc.h b/openbsc/include/openbsc/bsc_msc.h
new file mode 100644
index 000000000..29ce065d1
--- /dev/null
+++ b/openbsc/include/openbsc/bsc_msc.h
@@ -0,0 +1,46 @@
+/* Routines to talk to the MSC using the IPA Protocol */
+/*
+ * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010 by On-Waves
+ * 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 BSC_MSC_H
+#define BSC_MSC_H
+
+#include <osmocore/write_queue.h>
+#include <osmocore/timer.h>
+
+struct bsc_msc_connection {
+ struct write_queue write_queue;
+ int is_connected;
+ const char *ip;
+ int port;
+
+ void (*connection_loss) (struct bsc_msc_connection *);
+ void (*connected) (struct bsc_msc_connection *);
+ struct timer_list reconnect_timer;
+};
+
+struct bsc_msc_connection *bsc_msc_create(const char *ip, int port);
+int bsc_msc_connect(struct bsc_msc_connection *);
+void bsc_msc_schedule_connect(struct bsc_msc_connection *);
+
+void bsc_msc_lost(struct bsc_msc_connection *);
+
+#endif
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
new file mode 100644
index 000000000..ff0f907c5
--- /dev/null
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -0,0 +1,212 @@
+/*
+ * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010 by On-Waves
+ * 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 BSC_NAT_H
+#define BSC_NAT_H
+
+#include "mgcp.h"
+
+#include <sys/types.h>
+#include <sccp/sccp_types.h>
+
+#include <osmocore/select.h>
+#include <osmocore/msgb.h>
+#include <osmocore/timer.h>
+#include <osmocore/write_queue.h>
+
+#define DIR_BSC 1
+#define DIR_MSC 2
+
+#define NAT_IPAC_PROTO_MGCP 0xfc
+
+struct bsc_nat;
+
+/*
+ * For the NAT we will need to analyze and later patch
+ * the received message. This would require us to parse
+ * the IPA and SCCP header twice. Instead of doing this
+ * we will have one analyze structure and have the patching
+ * and filter operate on the same structure.
+ */
+struct bsc_nat_parsed {
+ /* ip access prototype */
+ int ipa_proto;
+
+ /* source local reference */
+ struct sccp_source_reference *src_local_ref;
+
+ /* destination local reference */
+ struct sccp_source_reference *dest_local_ref;
+
+ /* called ssn number */
+ int called_ssn;
+
+ /* calling ssn number */
+ int calling_ssn;
+
+ /* sccp message type */
+ int sccp_type;
+
+ /* bssap type, e.g. 0 for BSS Management */
+ int bssap;
+
+ /* the gsm0808 message type */
+ int gsm_type;
+};
+
+/*
+ * Per BSC data structure
+ */
+struct bsc_connection {
+ struct llist_head list_entry;
+
+ /* do we know anything about this BSC? */
+ int authenticated;
+
+ /* the fd we use to communicate */
+ struct write_queue write_queue;
+
+ /* the BSS associated */
+ struct bsc_config *cfg;
+
+ /* a timeout node */
+ struct timer_list id_timeout;
+
+ /* a back pointer */
+ struct bsc_nat *nat;
+};
+
+/*
+ * Per SCCP source local reference patch table. It needs to
+ * be updated on new SCCP connections, connection confirm and reject,
+ * and on the loss of the BSC connection.
+ */
+struct sccp_connections {
+ struct llist_head list_entry;
+
+ struct bsc_connection *bsc;
+
+ struct sccp_source_reference real_ref;
+ struct sccp_source_reference patched_ref;
+ struct sccp_source_reference remote_ref;
+
+ /* GSM audio handling. That is 32 * multiplex + ts */
+ int msc_timeslot;
+ int bsc_timeslot;
+};
+
+/**
+ * One BSC entry in the config
+ */
+struct bsc_config {
+ struct llist_head entry;
+
+ char *token;
+ unsigned int lac;
+ int nr;
+
+ struct bsc_nat *nat;
+};
+
+/**
+ * BSCs point of view of endpoints
+ */
+struct bsc_endpoint {
+ /* the pending transaction id */
+ char *transaction_id;
+ /* the bsc we are talking to */
+ struct bsc_connection *bsc;
+ /* pending delete */
+ int pending_delete;
+};
+
+/**
+ * the structure of the "nat" network
+ */
+struct bsc_nat {
+ /* active SCCP connections that need patching */
+ struct llist_head sccp_connections;
+
+ /* active BSC connections that need patching */
+ struct llist_head bsc_connections;
+
+ /* known BSC's */
+ struct llist_head bsc_configs;
+ int num_bsc;
+
+ /* MGCP config */
+ struct mgcp_config *mgcp_cfg;
+ struct write_queue mgcp_queue;
+ u_int8_t mgcp_msg[4096];
+ int mgcp_length;
+
+ struct bsc_endpoint *bsc_endpoints;
+};
+
+/* create and init the structures */
+struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token, unsigned int lac);
+struct bsc_config *bsc_config_num(struct bsc_nat *nat, int num);
+struct bsc_nat *bsc_nat_alloc(void);
+struct bsc_connection *bsc_connection_alloc(struct bsc_nat *nat);
+
+void sccp_connection_destroy(struct sccp_connections *);
+
+/**
+ * parse the given message into the above structure
+ */
+struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg);
+
+/**
+ * filter based on IP Access header in both directions
+ */
+int bsc_nat_filter_ipa(int direction, struct msgb *msg, struct bsc_nat_parsed *parsed);
+int bsc_nat_vty_init(struct bsc_nat *nat);
+struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg);
+
+/**
+ * SCCP patching and handling
+ */
+int create_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed);
+int update_sccp_src_ref(struct sccp_connections *sccp, struct bsc_nat_parsed *parsed);
+void remove_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed);
+struct sccp_connections *patch_sccp_src_ref_to_bsc(struct msgb *, struct bsc_nat_parsed *, struct bsc_nat *);
+struct sccp_connections *patch_sccp_src_ref_to_msc(struct msgb *, struct bsc_nat_parsed *, struct bsc_nat *);
+
+/**
+ * MGCP/Audio handling
+ */
+int bsc_write_mgcp_msg(struct bsc_connection *bsc, struct msgb *msg);
+int bsc_write_mgcp(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length);
+int bsc_mgcp_assign(struct sccp_connections *, struct msgb *msg);
+void bsc_mgcp_clear(struct sccp_connections *);
+void bsc_mgcp_free_endpoint(struct bsc_nat *nat, int);
+void bsc_mgcp_free_endpoints(struct bsc_nat *nat);
+int bsc_mgcp_init(struct bsc_nat *nat);
+
+struct bsc_connection *bsc_mgcp_find_con(struct bsc_nat *, int endpoint_number);
+struct msgb *bsc_mgcp_rewrite(char *input, int length, const char *ip, int port);
+void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg);
+
+void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc);
+int bsc_mgcp_parse_response(const char *str, int *code, char transaction[60]);
+int bsc_mgcp_extract_ci(const char *resp);
+
+#endif
diff --git a/openbsc/include/openbsc/bssap.h b/openbsc/include/openbsc/bssap.h
new file mode 100644
index 000000000..3b06fb5c3
--- /dev/null
+++ b/openbsc/include/openbsc/bssap.h
@@ -0,0 +1,336 @@
+/* From GSM08.08 */
+
+#ifndef BSSAP_H
+#define BSSAP_H
+
+#include <stdlib.h>
+
+#include <osmocore/msgb.h>
+#include <openbsc/gsm_data.h>
+
+/*
+ * this is from GSM 03.03 CGI but is copied in GSM 08.08
+ * in § 3.2.2.27 for Cell Identifier List
+ */
+enum CELL_IDENT {
+ CELL_IDENT_WHOLE_GLOBAL = 0,
+ CELL_IDENT_LAC_AND_CI = 1,
+ CELL_IDENT_CI = 2,
+ CELL_IDENT_NO_CELL = 3,
+ CELL_IDENT_LAI_AND_LAC = 4,
+ CELL_IDENT_LAC = 5,
+ CELL_IDENT_BSS = 6,
+ CELL_IDENT_UTRAN_PLMN_LAC_RNC = 8,
+ CELL_IDENT_UTRAN_RNC = 9,
+ CELL_IDENT_UTRAN_LAC_RNC = 10,
+};
+
+
+/* GSM 08.06 § 6.3 */
+enum BSSAP_MSG_TYPE {
+ BSSAP_MSG_BSS_MANAGEMENT = 0x0,
+ BSSAP_MSG_DTAP = 0x1,
+};
+
+struct bssmap_header {
+ u_int8_t type;
+ u_int8_t length;
+} __attribute__((packed));
+
+struct dtap_header {
+ u_int8_t type;
+ u_int8_t link_id;
+ u_int8_t length;
+} __attribute__((packed));
+
+
+enum BSS_MAP_MSG_TYPE {
+ BSS_MAP_MSG_RESERVED_0 = 0,
+
+ /* ASSIGNMENT MESSAGES */
+ BSS_MAP_MSG_ASSIGMENT_RQST = 1,
+ BSS_MAP_MSG_ASSIGMENT_COMPLETE = 2,
+ BSS_MAP_MSG_ASSIGMENT_FAILURE = 3,
+
+ /* HANDOVER MESSAGES */
+ BSS_MAP_MSG_HANDOVER_RQST = 16,
+ BSS_MAP_MSG_HANDOVER_REQUIRED = 17,
+ BSS_MAP_MSG_HANDOVER_RQST_ACKNOWLEDGE= 18,
+ BSS_MAP_MSG_HANDOVER_CMD = 19,
+ BSS_MAP_MSG_HANDOVER_COMPLETE = 20,
+ BSS_MAP_MSG_HANDOVER_SUCCEEDED = 21,
+ BSS_MAP_MSG_HANDOVER_FAILURE = 22,
+ BSS_MAP_MSG_HANDOVER_PERFORMED = 23,
+ BSS_MAP_MSG_HANDOVER_CANDIDATE_ENQUIRE = 24,
+ BSS_MAP_MSG_HANDOVER_CANDIDATE_RESPONSE = 25,
+ BSS_MAP_MSG_HANDOVER_REQUIRED_REJECT = 26,
+ BSS_MAP_MSG_HANDOVER_DETECT = 27,
+
+ /* RELEASE MESSAGES */
+ BSS_MAP_MSG_CLEAR_CMD = 32,
+ BSS_MAP_MSG_CLEAR_COMPLETE = 33,
+ BSS_MAP_MSG_CLEAR_RQST = 34,
+ BSS_MAP_MSG_RESERVED_1 = 35,
+ BSS_MAP_MSG_RESERVED_2 = 36,
+ BSS_MAP_MSG_SAPI_N_REJECT = 37,
+ BSS_MAP_MSG_CONFUSION = 38,
+
+ /* OTHER CONNECTION RELATED MESSAGES */
+ BSS_MAP_MSG_SUSPEND = 40,
+ BSS_MAP_MSG_RESUME = 41,
+ BSS_MAP_MSG_CONNECTION_ORIENTED_INFORMATION = 42,
+ BSS_MAP_MSG_PERFORM_LOCATION_RQST = 43,
+ BSS_MAP_MSG_LSA_INFORMATION = 44,
+ BSS_MAP_MSG_PERFORM_LOCATION_RESPONSE = 45,
+ BSS_MAP_MSG_PERFORM_LOCATION_ABORT = 46,
+ BSS_MAP_MSG_COMMON_ID = 47,
+
+ /* GENERAL MESSAGES */
+ BSS_MAP_MSG_RESET = 48,
+ BSS_MAP_MSG_RESET_ACKNOWLEDGE = 49,
+ BSS_MAP_MSG_OVERLOAD = 50,
+ BSS_MAP_MSG_RESERVED_3 = 51,
+ BSS_MAP_MSG_RESET_CIRCUIT = 52,
+ BSS_MAP_MSG_RESET_CIRCUIT_ACKNOWLEDGE = 53,
+ BSS_MAP_MSG_MSC_INVOKE_TRACE = 54,
+ BSS_MAP_MSG_BSS_INVOKE_TRACE = 55,
+ BSS_MAP_MSG_CONNECTIONLESS_INFORMATION = 58,
+
+ /* TERRESTRIAL RESOURCE MESSAGES */
+ BSS_MAP_MSG_BLOCK = 64,
+ BSS_MAP_MSG_BLOCKING_ACKNOWLEDGE = 65,
+ BSS_MAP_MSG_UNBLOCK = 66,
+ BSS_MAP_MSG_UNBLOCKING_ACKNOWLEDGE = 67,
+ BSS_MAP_MSG_CIRCUIT_GROUP_BLOCK = 68,
+ BSS_MAP_MSG_CIRCUIT_GROUP_BLOCKING_ACKNOWLEDGE = 69,
+ BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCK = 70,
+ BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCKING_ACKNOWLEDGE = 71,
+ BSS_MAP_MSG_UNEQUIPPED_CIRCUIT = 72,
+ BSS_MAP_MSG_CHANGE_CIRCUIT = 78,
+ BSS_MAP_MSG_CHANGE_CIRCUIT_ACKNOWLEDGE = 79,
+
+ /* RADIO RESOURCE MESSAGES */
+ BSS_MAP_MSG_RESOURCE_RQST = 80,
+ BSS_MAP_MSG_RESOURCE_INDICATION = 81,
+ BSS_MAP_MSG_PAGING = 82,
+ BSS_MAP_MSG_CIPHER_MODE_CMD = 83,
+ BSS_MAP_MSG_CLASSMARK_UPDATE = 84,
+ BSS_MAP_MSG_CIPHER_MODE_COMPLETE = 85,
+ BSS_MAP_MSG_QUEUING_INDICATION = 86,
+ BSS_MAP_MSG_COMPLETE_LAYER_3 = 87,
+ BSS_MAP_MSG_CLASSMARK_RQST = 88,
+ BSS_MAP_MSG_CIPHER_MODE_REJECT = 89,
+ BSS_MAP_MSG_LOAD_INDICATION = 90,
+
+ /* VGCS/VBS */
+ BSS_MAP_MSG_VGCS_VBS_SETUP = 4,
+ BSS_MAP_MSG_VGCS_VBS_SETUP_ACK = 5,
+ BSS_MAP_MSG_VGCS_VBS_SETUP_REFUSE = 6,
+ BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RQST = 7,
+ BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RESULT = 28,
+ BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_FAILURE = 29,
+ BSS_MAP_MSG_VGCS_VBS_QUEUING_INDICATION = 30,
+ BSS_MAP_MSG_UPLINK_RQST = 31,
+ BSS_MAP_MSG_UPLINK_RQST_ACKNOWLEDGE = 39,
+ BSS_MAP_MSG_UPLINK_RQST_CONFIRMATION = 73,
+ BSS_MAP_MSG_UPLINK_RELEASE_INDICATION = 74,
+ BSS_MAP_MSG_UPLINK_REJECT_CMD = 75,
+ BSS_MAP_MSG_UPLINK_RELEASE_CMD = 76,
+ BSS_MAP_MSG_UPLINK_SEIZED_CMD = 77,
+};
+
+enum GSM0808_IE_CODING {
+ GSM0808_IE_CIRCUIT_IDENTITY_CODE = 1,
+ GSM0808_IE_RESERVED_0 = 2,
+ GSM0808_IE_RESOURCE_AVAILABLE = 3,
+ GSM0808_IE_CAUSE = 4,
+ GSM0808_IE_CELL_IDENTIFIER = 5,
+ GSM0808_IE_PRIORITY = 6,
+ GSM0808_IE_LAYER_3_HEADER_INFORMATION = 7,
+ GSM0808_IE_IMSI = 8,
+ GSM0808_IE_TMSI = 9,
+ GSM0808_IE_ENCRYPTION_INFORMATION = 10,
+ GSM0808_IE_CHANNEL_TYPE = 11,
+ GSM0808_IE_PERIODICITY = 12,
+ GSM0808_IE_EXTENDED_RESOURCE_INDICATOR = 13,
+ GSM0808_IE_NUMBER_OF_MSS = 14,
+ GSM0808_IE_RESERVED_1 = 15,
+ GSM0808_IE_RESERVED_2 = 16,
+ GSM0808_IE_RESERVED_3 = 17,
+ GSM0808_IE_CLASSMARK_INFORMATION_T2 = 18,
+ GSM0808_IE_CLASSMARK_INFORMATION_T3 = 19,
+ GSM0808_IE_INTERFERENCE_BAND_TO_USE = 20,
+ GSM0808_IE_RR_CAUSE = 21,
+ GSM0808_IE_RESERVED_4 = 22,
+ GSM0808_IE_LAYER_3_INFORMATION = 23,
+ GSM0808_IE_DLCI = 24,
+ GSM0808_IE_DOWNLINK_DTX_FLAG = 25,
+ GSM0808_IE_CELL_IDENTIFIER_LIST = 26,
+ GSM0808_IE_RESPONSE_RQST = 27,
+ GSM0808_IE_RESOURCE_INDICATION_METHOD = 28,
+ GSM0808_IE_CLASSMARK_INFORMATION_TYPE_1 = 29,
+ GSM0808_IE_CIRCUIT_IDENTITY_CODE_LIST = 30,
+ GSM0808_IE_DIAGNOSTIC = 31,
+ GSM0808_IE_LAYER_3_MESSAGE_CONTENTS = 32,
+ GSM0808_IE_CHOSEN_CHANNEL = 33,
+ GSM0808_IE_TOTAL_RESOURCE_ACCESSIBLE = 34,
+ GSM0808_IE_CIPHER_RESPONSE_MODE = 35,
+ GSM0808_IE_CHANNEL_NEEDED = 36,
+ GSM0808_IE_TRACE_TYPE = 37,
+ GSM0808_IE_TRIGGERID = 38,
+ GSM0808_IE_TRACE_REFERENCE = 39,
+ GSM0808_IE_TRANSACTIONID = 40,
+ GSM0808_IE_MOBILE_IDENTITY = 41,
+ GSM0808_IE_OMCID = 42,
+ GSM0808_IE_FORWARD_INDICATOR = 43,
+ GSM0808_IE_CHOSEN_ENCR_ALG = 44,
+ GSM0808_IE_CIRCUIT_POOL = 45,
+ GSM0808_IE_CIRCUIT_POOL_LIST = 46,
+ GSM0808_IE_TIME_INDICATION = 47,
+ GSM0808_IE_RESOURCE_SITUATION = 48,
+ GSM0808_IE_CURRENT_CHANNEL_TYPE_1 = 49,
+ GSM0808_IE_QUEUEING_INDICATOR = 50,
+ GSM0808_IE_SPEECH_VERSION = 64,
+ GSM0808_IE_ASSIGNMENT_REQUIREMENT = 51,
+ GSM0808_IE_TALKER_FLAG = 53,
+ GSM0808_IE_CONNECTION_RELEASE_RQSTED = 54,
+ GSM0808_IE_GROUP_CALL_REFERENCE = 55,
+ GSM0808_IE_EMLPP_PRIORITY = 56,
+ GSM0808_IE_CONFIG_EVO_INDI = 57,
+ GSM0808_IE_OLD_BSS_TO_NEW_BSS_INFORMATION = 58,
+ GSM0808_IE_LSA_IDENTIFIER = 59,
+ GSM0808_IE_LSA_IDENTIFIER_LIST = 60,
+ GSM0808_IE_LSA_INFORMATION = 61,
+ GSM0808_IE_LCS_QOS = 62,
+ GSM0808_IE_LSA_ACCESS_CTRL_SUPPR = 63,
+ GSM0808_IE_LCS_PRIORITY = 67,
+ GSM0808_IE_LOCATION_TYPE = 68,
+ GSM0808_IE_LOCATION_ESTIMATE = 69,
+ GSM0808_IE_POSITIONING_DATA = 70,
+ GSM0808_IE_LCS_CAUSE = 71,
+ GSM0808_IE_LCS_CLIENT_TYPE = 72,
+ GSM0808_IE_APDU = 73,
+ GSM0808_IE_NETWORK_ELEMENT_IDENTITY = 74,
+ GSM0808_IE_GPS_ASSISTANCE_DATA = 75,
+ GSM0808_IE_DECIPHERING_KEYS = 76,
+ GSM0808_IE_RETURN_ERROR_RQST = 77,
+ GSM0808_IE_RETURN_ERROR_CAUSE = 78,
+ GSM0808_IE_SEGMENTATION = 79,
+ GSM0808_IE_SERVICE_HANDOVER = 80,
+ GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_UMTS = 81,
+ GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_CDMA2000= 82,
+ GSM0808_IE_RESERVED_5 = 65,
+ GSM0808_IE_RESERVED_6 = 66,
+};
+
+enum gsm0808_cause {
+ GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE = 0,
+ GSM0808_CAUSE_RADIO_INTERFACE_FAILURE = 1,
+ GSM0808_CAUSE_UPLINK_QUALITY = 2,
+ GSM0808_CAUSE_UPLINK_STRENGTH = 3,
+ GSM0808_CAUSE_DOWNLINK_QUALITY = 4,
+ GSM0808_CAUSE_DOWNLINK_STRENGTH = 5,
+ GSM0808_CAUSE_DISTANCE = 6,
+ GSM0808_CAUSE_O_AND_M_INTERVENTION = 7,
+ GSM0808_CAUSE_RESPONSE_TO_MSC_INVOCATION = 8,
+ GSM0808_CAUSE_CALL_CONTROL = 9,
+ GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION = 10,
+ GSM0808_CAUSE_HANDOVER_SUCCESSFUL = 11,
+ GSM0808_CAUSE_BETTER_CELL = 12,
+ GSM0808_CAUSE_DIRECTED_RETRY = 13,
+ GSM0808_CAUSE_JOINED_GROUP_CALL_CHANNEL = 14,
+ GSM0808_CAUSE_TRAFFIC = 15,
+ GSM0808_CAUSE_EQUIPMENT_FAILURE = 32,
+ GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE = 33,
+ GSM0808_CAUSE_RQSTED_TERRESTRIAL_RESOURCE_UNAVAILABLE = 34,
+ GSM0808_CAUSE_CCCH_OVERLOAD = 35,
+ GSM0808_CAUSE_PROCESSOR_OVERLOAD = 36,
+ GSM0808_CAUSE_BSS_NOT_EQUIPPED = 37,
+ GSM0808_CAUSE_MS_NOT_EQUIPPED = 38,
+ GSM0808_CAUSE_INVALID_CELL = 39,
+ GSM0808_CAUSE_TRAFFIC_LOAD = 40,
+ GSM0808_CAUSE_PREEMPTION = 41,
+ GSM0808_CAUSE_RQSTED_TRANSCODING_RATE_ADAPTION_UNAVAILABLE = 48,
+ GSM0808_CAUSE_CIRCUIT_POOL_MISMATCH = 49,
+ GSM0808_CAUSE_SWITCH_CIRCUIT_POOL = 50,
+ GSM0808_CAUSE_RQSTED_SPEECH_VERSION_UNAVAILABLE = 51,
+ GSM0808_CAUSE_LSA_NOT_ALLOWED = 52,
+ GSM0808_CAUSE_CIPHERING_ALGORITHM_NOT_SUPPORTED = 64,
+ GSM0808_CAUSE_TERRESTRIAL_CIRCUIT_ALREADY_ALLOCATED = 80,
+ GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS = 81,
+ GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING = 82,
+ GSM0808_CAUSE_INCORRECT_VALUE = 83,
+ GSM0808_CAUSE_UNKNOWN_MESSAGE_TYPE = 84,
+ GSM0808_CAUSE_UNKNOWN_INFORMATION_ELEMENT = 85,
+ GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC = 96,
+};
+
+/* GSM 08.08 3.2.2.11 Channel Type */
+enum gsm0808_chan_indicator {
+ GSM0808_CHAN_SPEECH = 1,
+ GSM0808_CHAN_DATA = 2,
+ GSM0808_CHAN_SIGN = 3,
+};
+
+enum gsm0808_chan_rate_type_data {
+ GSM0808_DATA_FULL_BM = 0x8,
+ GSM0808_DATA_HALF_LM = 0x9,
+ GSM0808_DATA_FULL_RPREF = 0xa,
+ GSM0808_DATA_HALF_PREF = 0xb,
+ GSM0808_DATA_FULL_PREF_NO_CHANGE = 0x1a,
+ GSM0808_DATA_HALF_PREF_NO_CHANGE = 0x1b,
+ GSM0808_DATA_MULTI_MASK = 0x20,
+ GSM0808_DATA_MULTI_MASK_NO_CHANGE = 0x30,
+};
+
+enum gsm0808_chan_rate_type_speech {
+ GSM0808_SPEECH_FULL_BM = 0x8,
+ GSM0808_SPEECH_HALF_LM = 0x9,
+ GSM0808_SPEECH_FULL_PREF= 0xa,
+ GSM0808_SPEECH_HALF_PREF= 0xb,
+ GSM0808_SPEECH_FULL_PREF_NO_CHANGE = 0x1a,
+ GSM0808_SPEECH_HALF_PREF_NO_CHANGE = 0x1b,
+ GSM0808_SPEECH_PERM = 0xf,
+ GSM0808_SPEECH_PERM_NO_CHANGE = 0x1f,
+};
+
+enum gsm0808_permitted_speech {
+ GSM0808_PERM_FR1 = 0x01,
+ GSM0808_PERM_FR2 = 0x11,
+ GSM0808_PERM_FR3 = 0x21,
+ GSM0808_PERM_HR1 = GSM0808_PERM_FR1 | 0x4,
+ GSM0808_PERM_HR2 = GSM0808_PERM_FR2 | 0x4,
+ GSM0808_PERM_HR3 = GSM0808_PERM_FR3 | 0x4,
+};
+
+int bssmap_rcvmsg_dt1(struct sccp_connection *conn, struct msgb *msg, unsigned int length);
+int bssmap_rcvmsg_udt(struct gsm_network *net, struct msgb *msg, unsigned int length);
+
+struct msgb *bssmap_create_layer3(struct msgb *msg);
+struct msgb *bssmap_create_reset(void);
+struct msgb *bssmap_create_clear_complete(void);
+struct msgb *bssmap_create_cipher_complete(struct msgb *layer3);
+struct msgb *bssmap_create_cipher_reject(u_int8_t cause);
+struct msgb *bssmap_create_sapi_reject(u_int8_t link_id);
+struct msgb *bssmap_create_assignment_completed(struct gsm_lchan *lchan, u_int8_t rr_cause);
+struct msgb *bssmap_create_assignment_failure(u_int8_t cause, u_int8_t *rr_cause);
+struct msgb *bssmap_create_classmark_update(const u_int8_t *classmark, u_int8_t length);
+
+void gsm0808_send_assignment_failure(struct gsm_lchan *l, u_int8_t cause, u_int8_t *rr_value);
+void gsm0808_send_assignment_compl(struct gsm_lchan *l, u_int8_t rr_value);
+
+int dtap_rcvmsg(struct gsm_lchan *lchan, struct msgb *msg, unsigned int length);
+struct msgb *dtap_create_msg(struct msgb *msg_l3, u_int8_t link_id);
+
+void bsc_queue_connection_write(struct sccp_connection *conn, struct msgb *msg);
+void bsc_free_queued(struct sccp_connection *conn);
+void bsc_send_queued(struct sccp_connection *conn);
+
+void bts_queue_send(struct msgb *msg, int link_id);
+void bts_send_queued(struct bss_sccp_connection_data*);
+void bts_free_queued(struct bss_sccp_connection_data*);
+void bts_unblock_queue(struct bss_sccp_connection_data*);
+
+const struct tlv_definition *gsm0808_att_tlvdef();
+
+#endif
diff --git a/openbsc/include/openbsc/chan_alloc.h b/openbsc/include/openbsc/chan_alloc.h
index f564e9e4d..2cf447c7f 100644
--- a/openbsc/include/openbsc/chan_alloc.h
+++ b/openbsc/include/openbsc/chan_alloc.h
@@ -23,6 +23,28 @@
#include "gsm_subscriber.h"
+/*
+ * Refcounting for the lchan. If the refcount drops to zero
+ * the channel will send a RSL release request.
+ */
+#define use_subscr_con(con) \
+ do { (con)->use_count++; \
+ DEBUGP(DREF, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) increases usage to: %d\n", \
+ (con)->lchan->ts->trx->bts->nr, (con)->lchan->ts->trx->nr, (con)->lchan->ts->nr, \
+ (con)->lchan->nr, (con)->use_count); \
+ } while(0);
+
+#define put_subscr_con(con, reason) \
+ do { (con)->use_count--; \
+ DEBUGP(DREF, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \
+ (con)->lchan->ts->trx->bts->nr, (con)->lchan->ts->trx->nr, (con)->lchan->ts->nr, \
+ (con)->lchan->nr, (con)->use_count); \
+ if ((con)->use_count <= 0) \
+ _lchan_release((con)->lchan, reason); \
+ } while(0);
+
+
+
/* Special allocator for C0 of BTS */
struct gsm_bts_trx_ts *ts_c0_alloc(struct gsm_bts *bts,
enum gsm_phys_chan_config pchan);
@@ -46,8 +68,8 @@ 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);
-/* Consider releasing the channel */
-int lchan_auto_release(struct gsm_lchan *lchan);
+/* internal.. do not use */
+int _lchan_release(struct gsm_lchan *lchan, u_int8_t release_reason);
struct load_counter {
unsigned int total;
diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h
index f1c5a699a..c96d58922 100644
--- a/openbsc/include/openbsc/debug.h
+++ b/openbsc/include/openbsc/debug.h
@@ -29,6 +29,7 @@ enum {
DHO,
DDB,
DREF,
+ DNAT,
Debug_LastEntry,
};
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h
index daf3bd780..eb445d11a 100644
--- a/openbsc/include/openbsc/gsm_04_08.h
+++ b/openbsc/include/openbsc/gsm_04_08.h
@@ -16,8 +16,9 @@ struct gsm_trans;
void gsm0408_allow_everyone(int allow);
int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id);
-enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
-enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
+enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *bts, u_int8_t ra);
+enum gsm_chreq_reason_t get_reason_by_chreq(u_int8_t ra, int neci);
+void gsm_net_update_ctype(struct gsm_network *net);
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);
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 8dfa5886b..303663f41 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -79,31 +79,13 @@ typedef int gsm_cbfn(unsigned int hooknum,
struct msgb *msg,
void *data, void *param);
-/*
- * Use the channel. As side effect the lchannel recycle timer
- * will be started.
- */
-#define LCHAN_RELEASE_TIMEOUT 20, 0
-#define use_subscr_con(con) \
- do { (con)->use_count++; \
- DEBUGP(DREF, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) increases usage to: %d\n", \
- (con)->lchan->ts->trx->bts->nr, (con)->lchan->ts->trx->nr, (con)->lchan->ts->nr, \
- (con)->lchan->nr, (con)->use_count); \
- bsc_schedule_timer(&(con)->release_timer, LCHAN_RELEASE_TIMEOUT); } while(0);
-
-#define put_subscr_con(con) \
- do { (con)->use_count--; \
- DEBUGP(DREF, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \
- (con)->lchan->ts->trx->bts->nr, (con)->lchan->ts->trx->nr, (con)->lchan->ts->nr, \
- (con)->lchan->nr, (con)->use_count); \
- } while(0);
-
-
/* communications link with a BTS */
struct gsm_bts_link {
struct gsm_bts *bts;
};
+struct sccp_connection;
+
/* Real authentication information containing Ki */
enum gsm_auth_algo {
AUTH_ALGO_NONE,
@@ -131,6 +113,43 @@ struct gsm_subscriber;
struct gsm_mncc;
struct rtp_socket;
+/* BSC/MSC data holding them together */
+struct bss_sccp_connection_data {
+ struct gsm_lchan *lchan;
+ struct gsm_lchan *secondary_lchan;
+ struct sccp_connection *sccp;
+ int ciphering_handled : 1;
+
+ /* Timers... */
+
+ /* for assginment command */
+ struct timer_list T10;
+
+ /* for SCCP ... */
+ struct timer_list sccp_it;
+
+ /* audio handling */
+ int rtp_port;
+
+ /* Queue SCCP and GSM0408 messages */
+ int block_gsm;
+ struct llist_head gsm_queue;
+ unsigned int gsm_queue_size;
+
+ struct llist_head sccp_queue;
+ unsigned int sccp_queue_size;
+
+ /* Active connections */
+ struct llist_head active_connections;
+};
+
+#define GSM0808_T10_VALUE 6, 0
+#define sccp_get_lchan(data_ctx) ((struct bss_sccp_connection_data *)data_ctx)->lchan
+#define lchan_get_sccp(lchan) lchan->msc_data->sccp
+struct bss_sccp_connection_data *bss_sccp_create_data();
+void bss_sccp_free_data(struct bss_sccp_connection_data *);
+
+
/* Network Management State */
struct gsm_nm_state {
u_int8_t operational;
@@ -187,9 +206,6 @@ struct gsm_subscriber_connection {
/* To whom we are allocated at the moment */
struct gsm_subscriber *subscr;
- /* Timer started to release the channel */
- struct timer_list release_timer;
-
/*
* Operations that have a state and might be pending
*/
@@ -237,6 +253,12 @@ struct gsm_lchan {
/* Established data link layer services */
u_int8_t sapis[8];
+ /*
+ * MSC handling...
+ */
+ struct bss_sccp_connection_data *msc_data;
+
+
/* cache of last measurement reports on this lchan */
struct gsm_meas_rep meas_rep[6];
int meas_rep_idx;
@@ -546,6 +568,14 @@ enum gsm_auth_policy {
#define GSM_T3101_DEFAULT 10
#define GSM_T3113_DEFAULT 60
+/*
+ * internal data for audio management
+ */
+struct gsm_audio_support {
+ u_int8_t hr : 1,
+ ver : 7;
+};
+
struct gsm_network {
/* global parameters */
u_int16_t country_code;
@@ -576,6 +606,11 @@ struct gsm_network {
struct gsmnet_stats stats;
+ struct gsm_audio_support **audio_support;
+ int audio_length;
+ int rtp_payload;
+ int rtp_base_port;
+
/* layer 4 */
int (*mncc_recv) (struct gsm_network *net, int msg_type, void *arg);
struct llist_head upqueue;
@@ -601,6 +636,18 @@ struct gsm_network {
struct {
enum rrlp_mode mode;
} rrlp;
+
+ enum gsm_chan_t ctype_by_chreq[16];
+
+ /* Use a TCH for handling requests of type paging any */
+ int pag_any_tch;
+
+ /* a hack for On Waves. It must be signed */
+ int32_t core_country_code;
+ int32_t core_network_code;
+
+ /* a simple token for this network... */
+ char *bsc_token;
};
#define SMS_HDR_SIZE 128
diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h
index 06539960e..a7dac8df8 100644
--- a/openbsc/include/openbsc/gsm_subscriber.h
+++ b/openbsc/include/openbsc/gsm_subscriber.h
@@ -81,6 +81,8 @@ struct gsm_subscriber *subscr_get_by_extension(struct gsm_network *net,
const char *ext);
struct gsm_subscriber *subscr_get_by_id(struct gsm_network *net,
unsigned long long id);
+struct gsm_subscriber *subscr_get_or_create(struct gsm_network *net,
+ const char *imsi);
int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason);
void subscr_put_channel(struct gsm_lchan *lchan);
void subscr_get_channel(struct gsm_subscriber *subscr,
diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h
index f7e800bd8..778a1f116 100644
--- a/openbsc/include/openbsc/mgcp.h
+++ b/openbsc/include/openbsc/mgcp.h
@@ -29,7 +29,6 @@
#include <arpa/inet.h>
#define RTP_PORT_DEFAULT 4000
-
/**
* Calculate the RTP audio port for the given multiplex
* and the direction. This allows a semi static endpoint
@@ -77,14 +76,17 @@ struct mgcp_config;
typedef int (*mgcp_change)(struct mgcp_config *cfg, int endpoint, int state, int local_rtp);
typedef int (*mgcp_policy)(struct mgcp_config *cfg, int endpoint, int state, const char *transactio_id);
+typedef int (*mgcp_reset)(struct mgcp_config *cfg);
struct mgcp_config {
+ /* common configuration */
int source_port;
char *local_ip;
char *source_addr;
- unsigned int number_endpoints;
char *bts_ip;
+ char *call_agent_addr;
+ /* default endpoint data */
struct in_addr bts_in;
char *audio_name;
int audio_payload;
@@ -92,15 +94,21 @@ struct mgcp_config {
int early_bind;
int rtp_base_port;
+ /* only used in forward mode */
char *forward_ip;
int forward_port;
+ unsigned int last_call_id;
+
+ /* endpoint configuration */
+ unsigned int number_endpoints;
+ struct mgcp_endpoint *endpoints;
+
+ /* callback functionality */
mgcp_change change_cb;
mgcp_policy policy_cb;
+ mgcp_reset reset_cb;
void *data;
-
- struct mgcp_endpoint *endpoints;
- unsigned int last_call_id;
};
/* config management */
@@ -115,8 +123,15 @@ void mgcp_free_endp(struct mgcp_endpoint *endp);
* format helper functions
*/
struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg);
-struct msgb *mgcp_create_rsip(void);
struct msgb *mgcp_create_response_with_data(int code, const char *msg, const char *trans, const char *data);
+/* adc helper */
+static inline int mgcp_timeslot_to_endpoint(int multiplex, int timeslot)
+{
+ if (timeslot == 0)
+ timeslot = 1;
+ return timeslot + (31 * multiplex);
+}
+
#endif
diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h
index 10d0ca6ae..7ce1732f9 100644
--- a/openbsc/include/openbsc/mgcp_internal.h
+++ b/openbsc/include/openbsc/mgcp_internal.h
@@ -61,4 +61,13 @@ struct mgcp_endpoint {
#define ENDPOINT_NUMBER(endp) abs(endp - endp->cfg->endpoints)
+struct mgcp_msg_ptr {
+ unsigned int start;
+ unsigned int length;
+};
+
+int mgcp_analyze_header(struct mgcp_config *cfg, struct msgb *msg,
+ struct mgcp_msg_ptr *ptr, int size,
+ const char **transaction_id, struct mgcp_endpoint **endp);
+
#endif
diff --git a/openbsc/include/sccp/sccp.h b/openbsc/include/sccp/sccp.h
index 643479adc..604a2ac72 100644
--- a/openbsc/include/sccp/sccp.h
+++ b/openbsc/include/sccp/sccp.h
@@ -94,7 +94,7 @@ struct sccp_connection {
* call sccp_system_incoming for incoming data (from the network)
* sccp will call outgoing whenever outgoing data exists
*/
-int sccp_system_init(int (*outgoing)(struct msgb *data, void *ctx), void *context);
+int sccp_system_init(void (*outgoing)(struct msgb *data, void *ctx), void *context);
int sccp_system_incoming(struct msgb *data);
/**
@@ -106,6 +106,11 @@ int sccp_connection_close(struct sccp_connection *connection, int cause);
int sccp_connection_free(struct sccp_connection *connection);
/**
+ * internal..
+ */
+int sccp_connection_force_free(struct sccp_connection *conn);
+
+/**
* Create a new socket. Set your callbacks and then call bind to open
* the connection.
*/
diff --git a/openbsc/include/vty/command.h b/openbsc/include/vty/command.h
index 03b071f70..31dd7f3b2 100644
--- a/openbsc/include/vty/command.h
+++ b/openbsc/include/vty/command.h
@@ -107,6 +107,8 @@ enum node_type {
TS_NODE,
SUBSCR_NODE,
MGCP_NODE,
+ NAT_NODE,
+ BSC_NODE,
};
/* Node which has some commands and prompt string and configuration