diff options
Diffstat (limited to 'openbsc/include')
-rw-r--r-- | openbsc/include/openbsc/Makefile.am | 2 | ||||
-rw-r--r-- | openbsc/include/openbsc/abis_rsl.h | 2 | ||||
-rw-r--r-- | openbsc/include/openbsc/bsc_msc.h | 46 | ||||
-rw-r--r-- | openbsc/include/openbsc/bsc_nat.h | 212 | ||||
-rw-r--r-- | openbsc/include/openbsc/bssap.h | 336 | ||||
-rw-r--r-- | openbsc/include/openbsc/chan_alloc.h | 26 | ||||
-rw-r--r-- | openbsc/include/openbsc/debug.h | 1 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_04_08.h | 5 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_data.h | 93 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_subscriber.h | 2 | ||||
-rw-r--r-- | openbsc/include/openbsc/mgcp.h | 27 | ||||
-rw-r--r-- | openbsc/include/openbsc/mgcp_internal.h | 9 | ||||
-rw-r--r-- | openbsc/include/sccp/sccp.h | 7 | ||||
-rw-r--r-- | openbsc/include/vty/command.h | 2 |
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 |