diff options
author | Harald Welte <laforge@gnumonks.org> | 2009-11-27 09:19:21 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2009-11-27 09:19:21 +0100 |
commit | 39a4f047c89ceb111c1756596c712a57048154e3 (patch) | |
tree | 9c237408c22b7635903884af2456f9eec5cdcc4a /openbsc/include | |
parent | 260b7ddb239d0d497ee7bb7c8c93d52a1c0fe88c (diff) | |
parent | 1a79d364401dfad2a71f1e61ff13a3861e3da46e (diff) |
Merge remote branch 'origin/master' into the lcr_rtp brancheversberg/lcr_rtp
Conflicts:
openbsc/src/Makefile.am
Diffstat (limited to 'openbsc/include')
24 files changed, 1019 insertions, 43 deletions
diff --git a/openbsc/include/Makefile.am b/openbsc/include/Makefile.am index a95129fa9..56b2a338a 100644 --- a/openbsc/include/Makefile.am +++ b/openbsc/include/Makefile.am @@ -1,3 +1,3 @@ -SUBDIRS = openbsc vty +SUBDIRS = openbsc vty sccp noinst_HEADERS = mISDNif.h compat_af_isdn.h diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 8d454bb00..8bb64eb91 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -3,4 +3,5 @@ noinst_HEADERS = abis_nm.h abis_rsl.h debug.h db.h gsm_04_08.h gsm_data.h \ timer.h misdn.h chan_alloc.h telnet_interface.h paging.h \ subchan_demux.h trau_frame.h e1_input.h trau_mux.h signal.h \ gsm_utils.h ipaccess.h rs232.h openbscdefines.h rtp_proxy.h \ - bsc_rll.h mncc.h talloc.h transaction.h + bsc_rll.h mncc.h talloc.h transaction.h ussd.h gsm_04_80.h \ + silent_call.h mgcp.h diff --git a/openbsc/include/openbsc/abis_nm.h b/openbsc/include/openbsc/abis_nm.h index 3e72321c5..00697a384 100644 --- a/openbsc/include/openbsc/abis_nm.h +++ b/openbsc/include/openbsc/abis_nm.h @@ -482,6 +482,7 @@ enum abis_nm_avail_state { NM_AVSTATE_DEPENDENCY = 5, NM_AVSTATE_DEGRADED = 6, NM_AVSTATE_NOT_INSTALLED= 7, + NM_AVSTATE_OK = 0xff, }; /* Section 9.4.13: Channel Combination */ @@ -659,6 +660,58 @@ enum abis_nm_ipacc_testres_ie { NM_IPACC_TR_IE_FREQ_ERR = 18, }; +enum ipac_eie { + NM_IPAC_EIE_ARFCN_WHITE = 0x01, + NM_IPAC_EIE_ARFCH_BLACK = 0x02, + NM_IPAC_EIE_FREQ_ERR_LIST = 0x03, + NM_IPAC_EIE_CHAN_USE_LIST = 0x04, + NM_IPAC_EIE_BCCH_INFO_TYPE = 0x05, + NM_IPAC_EIE_BCCH_INFO = 0x06, + /* FIXME */ +}; + +enum ipac_bcch_info_type { + IPAC_BINF_RXLEV = (1 << 8), + IPAC_BINF_RXQUAL = (1 << 9), + IPAC_BINF_FREQ_ERR_QUAL = (1 << 10), + IPAC_BINF_FRAME_OFFSET = (1 << 11), + IPAC_BINF_FRAME_NR_OFFSET = (1 << 12), + IPAC_BINF_BSIC = (1 << 13), + IPAC_BINF_CGI = (1 << 14), + IPAC_BINF_NEIGH_BA_SI2 = (1 << 15), + IPAC_BINF_NEIGH_BA_SI2bis = (1 << 0), + IPAC_BINF_NEIGH_BA_SI2ter = (1 << 1), + IPAC_BINF_CELL_ALLOC = (1 << 2), +}; + +struct cell_global_id { + u_int16_t mcc; + u_int16_t mnc; + u_int16_t lac; + u_int16_t ci; +}; + +/* The BCCH info from an ip.access test, in host byte order + * and already parsed... */ +struct ipac_bcch_info { + struct llist_head list; + + u_int16_t info_type; + u_int8_t freq_qual; + u_int16_t arfcn; + u_int8_t rx_lev; + u_int8_t rx_qual; + int16_t freq_err; + u_int16_t frame_offset; + u_int32_t frame_nr_offset; + u_int8_t bsic; + struct cell_global_id cgi; + u_int8_t ba_list_si2[16]; + u_int8_t ba_list_si2bis[16]; + u_int8_t ba_list_si2ter[16]; + u_int8_t ca_list_si1[16]; +}; + /* PUBLIC */ struct msgb; @@ -748,6 +801,13 @@ int abis_nm_ipaccess_msg(struct gsm_bts *bts, u_int8_t msg_type, int abis_nm_ipaccess_set_nvattr(struct gsm_bts *bts, u_int8_t *attr, int attr_len); int abis_nm_ipaccess_restart(struct gsm_bts *bts); +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); +int abis_nm_ipaccess_rsl_connect(struct gsm_bts_trx *trx, + u_int32_t ip, u_int16_t port, u_int8_t stream); +int ipac_parse_bcch_info(struct ipac_bcch_info *binf, u_int8_t *buf); +const char *ipacc_testres_name(u_int8_t res); /* Functions calling into other code parts */ enum nm_evt { diff --git a/openbsc/include/openbsc/abis_rsl.h b/openbsc/include/openbsc/abis_rsl.h index 8c5547d1d..a911be355 100644 --- a/openbsc/include/openbsc/abis_rsl.h +++ b/openbsc/include/openbsc/abis_rsl.h @@ -142,16 +142,16 @@ enum abis_rsl_msgtype { RSL_MT_IPAC_DISC_MUX = 0x56, RSL_MT_IPAC_DISC_MUX_ACK, RSL_MT_IPAC_DISC_MUX_NACK, - RSL_MT_IPAC_BIND = 0x70, /* Bind to local BTS RTP port */ - RSL_MT_IPAC_BIND_ACK, - RSL_MT_IPAC_BIND_NACK, - RSL_MT_IPAC_CONNECT = 0x73, - RSL_MT_IPAC_CONNECT_ACK, - RSL_MT_IPAC_CONNECT_NACK, - RSL_MT_IPAC_DISCONNECT_IND = 0x76, - RSL_MT_IPAC_DISCONNECT = 0x77, - RSL_MT_IPAC_DISCONNECT_ACK, - RSL_MT_IPAC_DISCONNECT_NACK, + RSL_MT_IPAC_CRCX = 0x70, /* Bind to local BTS RTP port */ + RSL_MT_IPAC_CRCX_ACK, + RSL_MT_IPAC_CRCX_NACK, + RSL_MT_IPAC_MDCX = 0x73, + RSL_MT_IPAC_MDCX_ACK, + RSL_MT_IPAC_MDCX_NACK, + RSL_MT_IPAC_DLCX_IND = 0x76, + RSL_MT_IPAC_DLCX = 0x77, + RSL_MT_IPAC_DLCX_ACK, + RSL_MT_IPAC_DLCX_NACK, }; /* Siemens vendor-specific */ @@ -535,10 +535,11 @@ enum rsl_mrpci_phase { int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci); /* ip.access specfic RSL extensions */ -int rsl_ipacc_bind(struct gsm_lchan *lchan); -int rsl_ipacc_connect(struct gsm_lchan *lchan, u_int32_t ip, - u_int16_t port, u_int16_t conn_id, - u_int8_t rtp_payload2); +int rsl_ipacc_crcx(struct gsm_lchan *lchan); +int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip, + u_int16_t port, u_int16_t conn_id, + u_int8_t rtp_payload2); +int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan); int abis_rsl_rcvmsg(struct msgb *msg); diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h index 089132ea9..447c3584f 100644 --- a/openbsc/include/openbsc/debug.h +++ b/openbsc/include/openbsc/debug.h @@ -20,6 +20,11 @@ #define DMUX 0x4000 #define DINP 0x8000 +#define DSCCP 0x10000 +#define DMSC 0x20000 + +#define DMGCP 0x40000 + #ifdef DEBUG #define DEBUGP(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 0, fmt, ## args) #define DEBUGPC(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 1, fmt, ## args) @@ -31,7 +36,7 @@ #define static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1]; char *hexdump(const unsigned char *buf, int len); -void debugp(unsigned int subsys, char *file, int line, int cont, const char *format, ...); +void debugp(unsigned int subsys, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6))); void debug_parse_category_mask(const char* mask); void debug_use_color(int use_color); void debug_timestamp(int enable); diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index 485e240cd..b7c8a2662 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -33,6 +33,23 @@ struct gsm48_chan_desc { }; } __attribute__ ((packed)); +/* Chapter 10.5.2.21aa */ +struct gsm48_multi_rate_conf { + u_int8_t smod : 2, + spare: 1, + icmi : 1, + nscb : 1, + ver : 3; + u_int8_t m4_75 : 1, + m5_15 : 1, + m5_90 : 1, + m6_70 : 1, + m7_40 : 1, + m7_95 : 1, + m10_2 : 1, + m12_2 : 1; +} __attribute__((packed)); + /* Chapter 10.5.2.30 */ struct gsm48_req_ref { u_int8_t ra; @@ -42,7 +59,11 @@ struct gsm48_req_ref { t3_low:3; } __attribute__ ((packed)); -/* Chapter 9.1.5 */ +/* + * Chapter 9.1.5/9.1.6 + * + * For 9.1.6 the chan_desc has the meaning of 10.5.2.5a + */ struct gsm48_chan_mode_modify { struct gsm48_chan_desc chan_desc; u_int8_t mode; @@ -59,6 +80,15 @@ enum gsm48_chan_mode { GSM48_CMODE_DATA_3k6 = 0x23, }; +/* Chapter 9.1.2 */ +struct gsm48_ass_cmd { + /* Semantic is from 10.5.2.5a */ + struct gsm48_chan_desc chan_desc; + u_int8_t power_command; + u_int8_t data[0]; +} __attribute__((packed)); + + /* Chapter 9.1.18 */ struct gsm48_imm_ass { u_int8_t l2_plen; @@ -398,6 +428,7 @@ struct gsm48_imsi_detach_ind { #define GSM_MI_TYPE_TMSI 0x04 #define GSM_MI_ODD 0x08 +#define GSM48_IE_MUL_RATE_CFG 0x03 /* 10.5.2.21aa */ #define GSM48_IE_MOBILE_ID 0x17 #define GSM48_IE_NAME_LONG 0x43 /* 10.5.3.5a */ #define GSM48_IE_NAME_SHORT 0x45 /* 10.5.3.5a */ @@ -621,9 +652,13 @@ enum chreq_type { CHREQ_T_VOICE_CALL_TCH_H, CHREQ_T_DATA_CALL_TCH_H, CHREQ_T_LOCATION_UPD, - CHREQ_T_PAG_R_ANY, + CHREQ_T_PAG_R_ANY_NECI0, + CHREQ_T_PAG_R_ANY_NECI1, CHREQ_T_PAG_R_TCH_F, CHREQ_T_PAG_R_TCH_FH, + CHREQ_T_LMU, + CHREQ_T_RESERVED_SDCCH, + CHREQ_T_RESERVED_IGNORE, }; /* Chapter 11.3 */ @@ -711,8 +746,8 @@ void gsm0408_set_reject_cause(int cause); int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id); void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc, u_int16_t mnc, u_int16_t lac); -enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra); -enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra); +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); int gsm48_tx_mm_info(struct gsm_lchan *lchan); int gsm48_tx_mm_auth_req(struct gsm_lchan *lchan, u_int8_t *rand); @@ -726,7 +761,8 @@ int gsm48_mi_to_string(char *string, const int str_len, const u_int8_t *mi, cons int gsm48_send_rr_release(struct gsm_lchan *lchan); int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv); int gsm48_send_rr_app_info(struct gsm_lchan *lchan, u_int8_t apdu_id, - u_int8_t apdu_len, u_int8_t *apdu); + u_int8_t apdu_len, const u_int8_t *apdu); +int gsm48_send_rr_ass_cmd(struct gsm_lchan *lchan, u_int8_t power_class); int bsc_upqueue(struct gsm_network *net); @@ -744,4 +780,7 @@ int send_siemens_mrpci(struct gsm_lchan *lchan, u_int8_t *classmark2_lv); int gsm48_paging_extract_mi(struct msgb *msg, char *mi_string, u_int8_t *mi_type); int gsm48_handle_paging_resp(struct msgb *msg, struct gsm_subscriber *subscr); +int gsm48_lchan_modify(struct gsm_lchan *lchan, u_int8_t lchan_mode); +int gsm48_rx_rr_modif_ack(struct msgb *msg); + #endif diff --git a/openbsc/include/openbsc/gsm_04_11.h b/openbsc/include/openbsc/gsm_04_11.h index bfa90b522..1851bba53 100644 --- a/openbsc/include/openbsc/gsm_04_11.h +++ b/openbsc/include/openbsc/gsm_04_11.h @@ -210,4 +210,7 @@ int gsm411_send_sms_lchan(struct gsm_lchan *lchan, struct gsm_sms *sms); struct gsm_sms *sms_alloc(void); void sms_free(struct gsm_sms *sms); +void _gsm411_sms_trans_free(struct gsm_trans *trans); +int gsm411_send_sms_subscr(struct gsm_subscriber *subscr, + struct gsm_sms *sms); #endif diff --git a/openbsc/include/openbsc/gsm_04_80.h b/openbsc/include/openbsc/gsm_04_80.h new file mode 100644 index 000000000..c240bbe94 --- /dev/null +++ b/openbsc/include/openbsc/gsm_04_80.h @@ -0,0 +1,143 @@ +#ifndef _GSM_04_80_H +#define _GSM_04_80_H + +/* GSM TS 04.80 definitions (Supplementary Services Specification, Formats and Coding) */ + +/* Section 3.4 */ +#define GSM0480_MTYPE_RELEASE_COMPLETE 0x2A +#define GSM0480_MTYPE_FACILITY 0x3A +#define GSM0480_MTYPE_REGISTER 0x3B + +/* Section 3.5 */ +#define GSM0480_IE_FACILITY 0x1C +#define GSM0480_IE_SS_VERSION 0x7F + +/* Section 3.6.2 */ +#define GSM0480_CTYPE_INVOKE 0xA1 +#define GSM0480_CTYPE_RETURN_RESULT 0xA2 +#define GSM0480_CTYPE_RETURN_ERROR 0xA3 +#define GSM0480_CTYPE_REJECT 0xA4 + +/* Section 3.6.3 */ +#define GSM0480_COMPIDTAG_INVOKE_ID 0x02 +#define GSM0480_COMPIDTAG_LINKED_ID 0x80 + +/* Section 3.6.4 */ +#define GSM0480_OPERATION_CODE 0x02 + +/* Section 3.6.5 */ +#define GSM_0480_SEQUENCE_TAG 0x30 +#define GSM_0480_SET_TAG 0x31 + +/* Section 3.6.6 */ +#define GSM_0480_ERROR_CODE_TAG 0x02 + +/* Section 3.6.7 */ +/* Table 3.13 */ +#define GSM_0480_PROBLEM_CODE_TAG_GENERAL 0x80 +#define GSM_0480_PROBLEM_CODE_TAG_INVOKE 0x81 +#define GSM_0480_PROBLEM_CODE_TAG_RETURN_RESULT 0x82 +#define GSM_0480_PROBLEM_CODE_TAG_RETURN_ERROR 0x83 + +/* Table 3.14 */ +#define GSM_0480_GEN_PROB_CODE_UNRECOGNISED 0x00 +#define GSM_0480_GEN_PROB_CODE_MISTYPED 0x01 +#define GSM_0480_GEN_PROB_CODE_BAD_STRUCTURE 0x02 + +/* Table 3.15 */ +#define GSM_0480_INVOKE_PROB_CODE_DUPLICATE_INVOKE_ID 0x00 +#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_OPERATION 0x01 +#define GSM_0480_INVOKE_PROB_CODE_MISTYPED_PARAMETER 0x02 +#define GSM_0480_INVOKE_PROB_CODE_RESOURCE_LIMITATION 0x03 +#define GSM_0480_INVOKE_PROB_CODE_INITIATING_RELEASE 0x04 +#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_LINKED_ID 0x05 +#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_RESPONSE 0x06 +#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_OPERATION 0x07 + +/* Table 3.16 */ +#define GSM_0480_RESULT_PROB_CODE_UNRECOGNISED_INVOKE_ID 0x00 +#define GSM_0480_RESULT_PROB_CODE_RETURN_RESULT_UNEXPECTED 0x01 +#define GSM_0480_RESULT_PROB_CODE_MISTYPED_PARAMETER 0x02 + +/* Table 3.17 */ +#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_INVOKE_ID 0x00 +#define GSM_0480_ERROR_PROB_CODE_RETURN_ERROR_UNEXPECTED 0x01 +#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_ERROR 0x02 +#define GSM_0480_ERROR_PROB_CODE_UNEXPECTED_ERROR 0x03 +#define GSM_0480_ERROR_PROB_CODE_MISTYPED_PARAMETER 0x04 + +/* Section 4.5 */ +#define GSM0480_OP_CODE_REGISTER_SS 0x0A +#define GSM0480_OP_CODE_ERASE_SS 0x0B +#define GSM0480_OP_CODE_ACTIVATE_SS 0x0C +#define GSM0480_OP_CODE_DEACTIVATE_SS 0x0D +#define GSM0480_OP_CODE_INTERROGATE_SS 0x0E +#define GSM0480_OP_CODE_NOTIFY_SS 0x10 +#define GSM0480_OP_CODE_REGISTER_PASSWORD 0x11 +#define GSM0480_OP_CODE_GET_PASSWORD 0x12 +#define GSM0480_OP_CODE_PROCESS_USS_DATA 0x13 +#define GSM0480_OP_CODE_FORWARD_CHECK_SS_IND 0x26 +#define GSM0480_OP_CODE_PROCESS_USS_REQ 0x3B +#define GSM0480_OP_CODE_USS_REQUEST 0x3C +#define GSM0480_OP_CODE_USS_NOTIFY 0x3D +#define GSM0480_OP_CODE_FORWARD_CUG_INFO 0x78 +#define GSM0480_OP_CODE_SPLIT_MPTY 0x79 +#define GSM0480_OP_CODE_RETRIEVE_MPTY 0x7A +#define GSM0480_OP_CODE_HOLD_MPTY 0x7B +#define GSM0480_OP_CODE_BUILD_MPTY 0x7C +#define GSM0480_OP_CODE_FORWARD_CHARGE_ADVICE 0x7D + +#define GSM0480_ERR_CODE_UNKNOWN_SUBSCRIBER 0x01 +#define GSM0480_ERR_CODE_ILLEGAL_SUBSCRIBER 0x09 +#define GSM0480_ERR_CODE_BEARER_SERVICE_NOT_PROVISIONED 0x0A +#define GSM0480_ERR_CODE_TELESERVICE_NOT_PROVISIONED 0x0B +#define GSM0480_ERR_CODE_ILLEGAL_EQUIPMENT 0x0C +#define GSM0480_ERR_CODE_CALL_BARRED 0x0D +#define GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION 0x10 +#define GSM0480_ERR_CODE_SS_ERROR_STATUS 0x11 +#define GSM0480_ERR_CODE_SS_NOT_AVAILABLE 0x12 +#define GSM0480_ERR_CODE_SS_SUBSCRIPTION_VIOLATION 0x13 +#define GSM0480_ERR_CODE_SS_INCOMPATIBILITY 0x14 +#define GSM0480_ERR_CODE_FACILITY_NOT_SUPPORTED 0x15 +#define GSM0480_ERR_CODE_ABSENT_SUBSCRIBER 0x1B +#define GSM0480_ERR_CODE_SYSTEM_FAILURE 0x22 +#define GSM0480_ERR_CODE_DATA_MISSING 0x23 +#define GSM0480_ERR_CODE_UNEXPECTED_DATA_VALUE 0x24 +#define GSM0480_ERR_CODE_PW_REGISTRATION_FAILURE 0x25 +#define GSM0480_ERR_CODE_NEGATIVE_PW_CHECK 0x26 +#define GSM0480_ERR_CODE_NUM_PW_ATTEMPTS_VIOLATION 0x2B +#define GSM0480_ERR_CODE_UNKNOWN_ALPHABET 0x47 +#define GSM0480_ERR_CODE_USSD_BUSY 0x48 +#define GSM0480_ERR_CODE_MAX_MPTY_PARTICIPANTS 0x7E +#define GSM0480_ERR_CODE_RESOURCES_NOT_AVAILABLE 0x7F + +/* ASN.1 type-tags */ +#define ASN1_BOOLEAN_TAG 0x01 +#define ASN1_INTEGER_TAG 0x02 +#define ASN1_BIT_STRING_TAG 0x03 +#define ASN1_OCTET_STRING_TAG 0x04 +#define ASN1_NULL_TYPE_TAG 0x05 +#define ASN1_OBJECT_ID_TAG 0x06 +#define ASN1_UTF8_STRING_TAG 0x0C +#define ASN1_PRINTABLE_STRING_TAG 0x13 +#define ASN1_IA5_STRING_TAG 0x16 +#define ASN1_UNICODE_STRING_TAG 0x1E + +#include <openbsc/msgb.h> + +#define MAX_LEN_USSD_STRING 31 + +struct ussd_request { + char text[MAX_LEN_USSD_STRING + 1]; + u_int8_t transaction_id; + u_int8_t invoke_id; +}; + +int gsm0480_decode_ussd_request(const struct msgb *msg, + struct ussd_request *request); +int gsm0480_send_ussd_response(const struct msgb *in_msg, const char* response_text, + const struct ussd_request *req); +int gsm0480_send_ussd_reject(const struct msgb *msg, + const struct ussd_request *request); + +#endif diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index a493a69d9..638b03506 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -3,6 +3,13 @@ #include <sys/types.h> +struct value_string { + unsigned int value; + const char *str; +}; + +const char *get_value_string(const struct value_string *vs, u_int32_t val); + enum gsm_band { GSM_BAND_400, GSM_BAND_850, @@ -18,6 +25,8 @@ enum gsm_phys_chan_config { GSM_PCHAN_TCH_F, GSM_PCHAN_TCH_H, GSM_PCHAN_SDCCH8_SACCH8C, + GSM_PCHAN_PDCH, /* GPRS PDCH */ + GSM_PCHAN_TCH_F_PDCH, /* TCH/F if used, PDCH otherwise */ GSM_PCHAN_UNKNOWN, }; @@ -122,13 +131,18 @@ struct gsm_nm_state { */ struct gsm_loc_updating_operation { struct timer_list updating_timer; - int waiting_for_imsi : 1; - int waiting_for_imei : 1; + unsigned int waiting_for_imsi : 1; + unsigned int waiting_for_imei : 1; }; #define MAX_A5_KEY_LEN (128/8) #define RSL_ENC_ALG_A5(x) (x+1) +/* is the data link established? who established it? */ +#define LCHAN_SAPI_UNUSED 0 +#define LCHAN_SAPI_MS 1 +#define LCHAN_SAPI_NET 2 + struct gsm_lchan { /* The TS that we're part of */ struct gsm_bts_trx_ts *ts; @@ -149,6 +163,9 @@ struct gsm_lchan { u_int8_t key_len; u_int8_t key[MAX_A5_KEY_LEN]; } encr; + + /* AMR bits */ + struct gsm48_multi_rate_conf mr_conf; /* To whom we are allocated at the moment */ struct gsm_subscriber *subscr; @@ -158,6 +175,9 @@ struct gsm_lchan { struct timer_list T3101; + /* Established data link layer services */ + u_int8_t sapis[8]; + /* * Operations that have a state and might be pending */ @@ -237,6 +257,9 @@ struct gsm_bts_trx { } bs11; }; struct gsm_bts_trx_ts ts[TRX_NR_TS]; + + /* NM state */ + int rf_locked; }; enum gsm_bts_type { @@ -266,7 +289,6 @@ struct gsm_paging_request { gsm_cbfn *cbfn; void *cbfn_param; }; -#define T3113_VALUE 60, 0 /* * This keeps track of the paging status of one BTS. It @@ -289,6 +311,12 @@ struct gsm_envabtse { struct gsm_nm_state nm_state; }; +struct gsm_bts_gprs_nsvc { + struct gsm_bts *bts; + int id; + struct gsm_nm_state nm_state; +}; + /* One BTS */ struct gsm_bts { /* list header in net->bts_list */ @@ -356,6 +384,17 @@ struct gsm_bts { struct gsm_envabtse envabtse[4]; } bs11; }; + + /* Not entirely sure how ip.access specific this is */ + struct { + struct { + struct gsm_nm_state nm_state; + } nse; + struct { + struct gsm_nm_state nm_state; + } cell; + struct gsm_bts_gprs_nsvc nsvc[2]; + } gprs; /* transceivers */ int num_trx; @@ -376,6 +415,7 @@ struct gsm_network { char *name_short; enum gsm_auth_policy auth_policy; int a5_encryption; + int neci; /* layer 4 */ int (*mncc_recv) (struct gsm_network *net, int msg_type, void *arg); @@ -384,12 +424,25 @@ struct gsm_network { unsigned int num_bts; struct llist_head bts_list; + + /* timer values */ + int T3101; + int T3103; + int T3105; + int T3107; + int T3109; + int T3111; + int T3113; + int T3115; + int T3117; + int T3119; + int T3141; }; #define SMS_HDR_SIZE 128 #define SMS_TEXT_SIZE 256 struct gsm_sms { - u_int64_t id; + unsigned long long id; struct gsm_subscriber *sender; struct gsm_subscriber *receiver; @@ -468,4 +521,6 @@ static inline int is_siemens_bts(struct gsm_bts *bts) enum gsm_auth_policy gsm_auth_policy_parse(const char *arg); const char *gsm_auth_policy_name(enum gsm_auth_policy policy); +void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked); + #endif diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index ea70c3aa2..d612ed566 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -8,13 +8,14 @@ #define GSM_IMEI_LENGTH 17 #define GSM_IMSI_LENGTH 17 #define GSM_NAME_LENGTH 128 -#define GSM_EXTENSION_LENGTH 128 + +#define GSM_EXTENSION_LENGTH 15 /* MSISDN can only be 15 digits length */ +#define GSM_MIN_EXTEN 20000 +#define GSM_MAX_EXTEN 49999 /* reserved according to GSM 03.03 ยง 2.4 */ #define GSM_RESERVED_TMSI 0xFFFFFFFF -#define GSM_MIN_EXTEN 20000 -#define GSM_MAX_EXTEN 49999 #define GSM_SUBSCRIBER_FIRST_CONTACT 0x00000001 #define tmsi_from_string(str) strtoul(str, NULL, 10) diff --git a/openbsc/include/openbsc/gsm_utils.h b/openbsc/include/openbsc/gsm_utils.h index 7cd0578ad..1bd1bc55a 100644 --- a/openbsc/include/openbsc/gsm_utils.h +++ b/openbsc/include/openbsc/gsm_utils.h @@ -32,4 +32,6 @@ int gsm_7bit_encode(u_int8_t *result, const char *data); int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm); int ms_pwr_dbm(enum gsm_band band, u_int8_t lvl); + +void generate_backtrace(); #endif diff --git a/openbsc/include/openbsc/ipaccess.h b/openbsc/include/openbsc/ipaccess.h index 87942f270..395687764 100644 --- a/openbsc/include/openbsc/ipaccess.h +++ b/openbsc/include/openbsc/ipaccess.h @@ -1,9 +1,10 @@ #ifndef _IPACCESS_H #define _IPACCESS_H +#include "e1_input.h" + struct ipaccess_head { - u_int8_t zero; - u_int8_t len; + u_int16_t len; /* network byte order */ u_int8_t proto; u_int8_t data[0]; } __attribute__ ((packed)); diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h new file mode 100644 index 000000000..fa6224c12 --- /dev/null +++ b/openbsc/include/openbsc/mgcp.h @@ -0,0 +1,48 @@ +/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */ + +/* + * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2009 by on-waves.com + * 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. + * + */ + +unsigned int rtp_base_port = 4000; + +/** + * Calculate the RTP audio port for the given multiplex + * and the direction. This allows a semi static endpoint + * to port calculation removing the need for the BSC + * and the MediaGateway to communicate. + * + * Port usage explained: + * base + (multiplex * 2) + 0 == local port to wait for network packets + * base + (multiplex * 2) + 1 == local port for rtcp + * + * The above port will receive packets from the BTS that need + * to be patched and forwarded to the network. + * The above port will receive packets from the network that + * need to be patched and forwarded to the BTS. + * + * We assume to have a static BTS IP address so we can differentiate + * network and BTS. + * + */ +int rtp_calculate_port(int multiplex, int base) +{ + return base + (multiplex * 2); +} diff --git a/openbsc/include/openbsc/msgb.h b/openbsc/include/openbsc/msgb.h index 5ecac459b..ab3c03396 100644 --- a/openbsc/include/openbsc/msgb.h +++ b/openbsc/include/openbsc/msgb.h @@ -51,6 +51,7 @@ extern struct msgb *msgb_alloc(u_int16_t size, const char *name); extern void msgb_free(struct msgb *m); extern void msgb_enqueue(struct llist_head *queue, struct msgb *msg); extern struct msgb *msgb_dequeue(struct llist_head *queue); +extern void msgb_reset(struct msgb *m); #define msgb_l2(m) ((void *)(m->l2h)) #define msgb_l3(m) ((void *)(m->l3h)) diff --git a/openbsc/include/openbsc/signal.h b/openbsc/include/openbsc/signal.h index 1af849684..fee9d5bfd 100644 --- a/openbsc/include/openbsc/signal.h +++ b/openbsc/include/openbsc/signal.h @@ -39,6 +39,7 @@ enum signal_subsystems { SS_NM, SS_LCHAN, SS_SUBSCR, + SS_SCALL, }; /* SS_PAGING signals */ @@ -56,8 +57,8 @@ enum signal_sms { /* SS_ABISIP signals */ enum signal_abisip { - S_ABISIP_BIND_ACK, - S_ABISIP_DISC_IND, + S_ABISIP_CRCX_ACK, + S_ABISIP_DLCX_IND, }; /* SS_NM signals */ @@ -85,6 +86,13 @@ enum signal_subscr { S_SUBSCR_DETACHED, }; +/* SS_SCALL signals */ +enum signal_scall { + S_SCALL_SUCCESS, + S_SCALL_EXPIRED, + S_SCALL_DETACHED, +}; + typedef int signal_cbfn(unsigned int subsys, unsigned int signal, void *handler_data, void *signal_data); @@ -96,6 +104,12 @@ struct paging_signal_data { struct gsm_lchan *lchan; }; +struct scall_signal_data { + struct gsm_subscriber *subscr; + struct gsm_lchan *lchan; + void *data; +}; + /* Management */ int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data); void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data); diff --git a/openbsc/include/openbsc/silent_call.h b/openbsc/include/openbsc/silent_call.h new file mode 100644 index 000000000..53ed4e248 --- /dev/null +++ b/openbsc/include/openbsc/silent_call.h @@ -0,0 +1,7 @@ +#ifndef _SILENT_CALL_H +#define _SILENT_CALL_H + +extern int gsm_silent_call_start(struct gsm_subscriber *subscr, void *data); +extern int gsm_silent_call_stop(struct gsm_subscriber *subscr); + +#endif /* _SILENT_CALL_H */ diff --git a/openbsc/include/openbsc/telnet_interface.h b/openbsc/include/openbsc/telnet_interface.h index 97357d794..d3381e0a4 100644 --- a/openbsc/include/openbsc/telnet_interface.h +++ b/openbsc/include/openbsc/telnet_interface.h @@ -35,13 +35,6 @@ struct telnet_connection { struct gsm_network *network; struct bsc_fd fd; struct vty *vty; - - int bts; - - int command; - char *imsi; - char commands[1024]; - int read; }; diff --git a/openbsc/include/openbsc/timer.h b/openbsc/include/openbsc/timer.h index ae67a5a1a..fee888bfd 100644 --- a/openbsc/include/openbsc/timer.h +++ b/openbsc/include/openbsc/timer.h @@ -44,9 +44,9 @@ struct timer_list { struct llist_head entry; struct timeval timeout; - int active : 1; - int handled : 1; - int in_list : 1; + unsigned int active : 1; + unsigned int handled : 1; + unsigned int in_list : 1; void (*cb)(void*); void *data; @@ -67,5 +67,6 @@ int bsc_timer_pending(struct timer_list *timer); struct timeval *bsc_nearest_timer(); void bsc_prepare_timers(); int bsc_update_timers(); +int bsc_timer_check(void); #endif diff --git a/openbsc/include/openbsc/tlv.h b/openbsc/include/openbsc/tlv.h index ae88e6ed3..0cf4388d8 100644 --- a/openbsc/include/openbsc/tlv.h +++ b/openbsc/include/openbsc/tlv.h @@ -6,11 +6,33 @@ #include <openbsc/msgb.h> +/* Terminology / wording + tag length value (in bits) + + V - - 8 + LV - 8 N * 8 + TLV 8 8 N * 8 + TL16V 8 16 N * 8 + TLV16 8 8 N * 16 + TvLV 8 8/16 N * 8 + +*/ + #define LV_GROSS_LEN(x) (x+1) #define TLV_GROSS_LEN(x) (x+2) #define TLV16_GROSS_LEN(x) ((2*x)+2) #define TL16V_GROSS_LEN(x) (x+3) +#define TVLV_MAX_ONEBYTE 0x7f + +static inline u_int16_t TVLV_GROSS_LEN(u_int16_t len) +{ + if (len <= TVLV_MAX_ONEBYTE) + return TLV_GROSS_LEN(len); + else + return TL16V_GROSS_LEN(len); +} + /* TLV generation */ static inline u_int8_t *lv_put(u_int8_t *buf, u_int8_t len, @@ -49,6 +71,20 @@ static inline u_int8_t *tl16v_put(u_int8_t *buf, u_int8_t tag, u_int16_t len, return buf + len*2; } +static inline u_int8_t *tvlv_put(u_int8_t *buf, u_int8_t tag, u_int16_t len, + const u_int8_t *val) +{ + u_int8_t *ret; + + if (len <= TVLV_MAX_ONEBYTE) { + ret = tlv_put(buf, tag, len, val); + buf[1] |= 0x80; + } else + ret = tl16v_put(buf, tag, len, val); + + return ret; +} + static inline u_int8_t *msgb_tlv16_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int16_t *val) { u_int8_t *buf = msgb_put(msg, TLV16_GROSS_LEN(len)); @@ -62,6 +98,13 @@ static inline u_int8_t *msgb_tl16v_put(struct msgb *msg, u_int8_t tag, u_int16_t return tl16v_put(buf, tag, len, val); } +static inline u_int8_t *msgb_tvlv_put(struct msgb *msg, u_int8_t tag, u_int16_t len, + const u_int8_t *val) +{ + u_int8_t *buf = msgb_put(msg, TVLV_GROSS_LEN(len)); + return tvlv_put(buf, tag, len, val); +} + static inline u_int8_t *v_put(u_int8_t *buf, u_int8_t val) { *buf++ = val; @@ -146,6 +189,7 @@ enum tlv_type { TLV_TYPE_TV, TLV_TYPE_TLV, TLV_TYPE_TL16V, + TLV_TYPE_TvLV, }; struct tlv_def { @@ -161,6 +205,11 @@ struct tlv_parsed { struct tlv_p_entry lv[0xff]; }; +extern struct tlv_definition tvlv_att_def; + +int tlv_parse_one(u_int8_t *o_tag, u_int16_t *o_len, const u_int8_t **o_val, + const struct tlv_definition *def, + const u_int8_t *buf, int buf_len); int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def, const u_int8_t *buf, int buf_len, u_int8_t lv_tag, u_int8_t lv_tag2); diff --git a/openbsc/include/openbsc/ussd.h b/openbsc/include/openbsc/ussd.h new file mode 100644 index 000000000..e7bd6d69d --- /dev/null +++ b/openbsc/include/openbsc/ussd.h @@ -0,0 +1,10 @@ +#ifndef _USSD_H +#define _USSD_H + +/* Handler function for mobile-originated USSD messages */ + +#include <openbsc/msgb.h> + +int handle_rcv_ussd(struct msgb *msg); + +#endif diff --git a/openbsc/include/sccp/Makefile.am b/openbsc/include/sccp/Makefile.am new file mode 100644 index 000000000..42fd31047 --- /dev/null +++ b/openbsc/include/sccp/Makefile.am @@ -0,0 +1 @@ +noinst_HEADERS = sccp_types.h sccp.h diff --git a/openbsc/include/sccp/sccp.h b/openbsc/include/sccp/sccp.h new file mode 100644 index 000000000..3ad568c0b --- /dev/null +++ b/openbsc/include/sccp/sccp.h @@ -0,0 +1,146 @@ +/* + * SCCP management code + * + * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef SCCP_H +#define SCCP_H + +#include <stdlib.h> + +#include <sys/socket.h> + +#include <openbsc/msgb.h> + +#include "sccp_types.h" + +struct sccp_system; + +enum { + SCCP_CONNECTION_STATE_NONE, + SCCP_CONNECTION_STATE_REQUEST, + SCCP_CONNECTION_STATE_CONFIRM, + SCCP_CONNECTION_STATE_ESTABLISHED, + SCCP_CONNECTION_STATE_RELEASE, + SCCP_CONNECTION_STATE_RELEASE_COMPLETE, + SCCP_CONNECTION_STATE_REFUSED, + SCCP_CONNECTION_STATE_SETUP_ERROR, +}; + +struct sockaddr_sccp { + sa_family_t sccp_family; /* AF_SCCP in the future??? */ + u_int8_t sccp_ssn; /* subssystem number for routing */ + + /* TODO fill in address indicator... if that is ever needed */ + + /* not sure about these */ + /* u_int8_t sccp_class; */ +}; + +/* + * parsed structure of an address + */ +struct sccp_address { + struct sccp_called_party_address address; + u_int8_t ssn; + u_int8_t poi[2]; +}; + +struct sccp_optional_data { + u_int8_t data_len; + u_int8_t data_start; +}; + +struct sccp_connection { + /* public */ + void *data_ctx; + void (*data_cb)(struct sccp_connection *conn, struct msgb *msg, unsigned int len); + + void *state_ctx; + void (*state_cb)(struct sccp_connection *, int old_state); + + struct sccp_source_reference source_local_reference; + struct sccp_source_reference destination_local_reference; + + int connection_state; + + /* private */ + /* list of active connections */ + struct llist_head list; + struct sccp_system *system; + int incoming; +}; + +/** + * system functionality to implement on top of any other transport layer: + * 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_incoming(struct msgb *data); + +/** + * Send data on an existing connection + */ +int sccp_connection_write(struct sccp_connection *connection, struct msgb *data); +int sccp_connection_send_it(struct sccp_connection *connection); +int sccp_connection_close(struct sccp_connection *connection, int cause); +int sccp_connection_free(struct sccp_connection *connection); + +/** + * Create a new socket. Set your callbacks and then call bind to open + * the connection. + */ +struct sccp_connection *sccp_connection_socket(void); + +/** + * Open the connection and send additional data + */ +int sccp_connection_connect(struct sccp_connection *conn, + const struct sockaddr_sccp *sccp_called, + struct msgb *data); + +/** + * mostly for testing purposes only. Set the accept callback. + * TODO: add true routing information... in analogy to socket, bind, accept + */ +int sccp_connection_set_incoming(const struct sockaddr_sccp *sock, + int (*accept_cb)(struct sccp_connection *connection, void *data), + void *user_data); + +/** + * Send data in terms of unit data. A fixed address indicator will be used. + */ +int sccp_write(struct msgb *data, + const struct sockaddr_sccp *sock_sender, + const struct sockaddr_sccp *sock_target, int class); +int sccp_set_read(const struct sockaddr_sccp *sock, + int (*read_cb)(struct msgb *msgb, unsigned int, void *user_data), + void *user_data); + +/* generic sock addresses */ +extern const struct sockaddr_sccp sccp_ssn_bssap; + +/* helpers */ +u_int32_t sccp_src_ref_to_int(struct sccp_source_reference *ref); +struct sccp_source_reference sccp_src_ref_from_int(u_int32_t); + +#endif diff --git a/openbsc/include/sccp/sccp_types.h b/openbsc/include/sccp/sccp_types.h new file mode 100644 index 000000000..9310a6bf0 --- /dev/null +++ b/openbsc/include/sccp/sccp_types.h @@ -0,0 +1,394 @@ +/* + * ITU Q.713 defined types for SCCP + * + * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef SCCP_TYPES_H +#define SCCP_TYPES_H + +/* Table 1/Q.713 - SCCP message types */ +enum sccp_message_types { + SCCP_MSG_TYPE_CR = 1, + SCCP_MSG_TYPE_CC = 2, + SCCP_MSG_TYPE_CREF = 3, + SCCP_MSG_TYPE_RLSD = 4, + SCCP_MSG_TYPE_RLC = 5, + SCCP_MSG_TYPE_DT1 = 6, + SCCP_MSG_TYPE_DT2 = 7, + SCCP_MSG_TYPE_AK = 8, + SCCP_MSG_TYPE_UDT = 9, + SCCP_MSG_TYPE_UDTS = 10, + SCCP_MSG_TYPE_ED = 11, + SCCP_MSG_TYPE_EA = 12, + SCCP_MSG_TYPE_RSR = 13, + SCCP_MSG_TYPE_RSC = 14, + SCCP_MSG_TYPE_ERR = 15, + SCCP_MSG_TYPE_IT = 16, + SCCP_MSG_TYPE_XUDT = 17, + SCCP_MSG_TYPE_XUDTS = 18, + SCCP_MSG_TYPE_LUDT = 19, + SCCP_MSG_TYPE_LUDTS = 20 +}; + +/* Table 2/Q.713 - SCCP parameter name codes */ +enum sccp_parameter_name_codes { + SCCP_PNC_END_OF_OPTIONAL = 0, + SCCP_PNC_DESTINATION_LOCAL_REFERENCE = 1, + SCCP_PNC_SOURCE_LOCAL_REFERENCE = 2, + SCCP_PNC_CALLED_PARTY_ADDRESS = 3, + SCCP_PNC_CALLING_PARTY_ADDRESS = 4, + SCCP_PNC_PROTOCOL_CLASS = 5, + SCCP_PNC_SEGMENTING = 6, + SCCP_PNC_RECEIVE_SEQ_NUMBER = 7, + SCCP_PNC_SEQUENCING = 8, + SCCP_PNC_CREDIT = 9, + SCCP_PNC_RELEASE_CAUSE = 10, + SCCP_PNC_RETURN_CAUSE = 11, + SCCP_PNC_RESET_CAUSE = 12, + SCCP_PNC_ERROR_CAUSE = 13, + SCCP_PNC_REFUSAL_CAUSE = 14, + SCCP_PNC_DATA = 15, + SCCP_PNC_SEGMENTATION = 16, + SCCP_PNC_HOP_COUNTER = 17, + SCCP_PNC_IMPORTANCE = 18, + SCCP_PNC_LONG_DATA = 19, +}; + +/* Figure 3/Q.713 Called/calling party address */ +enum { + SCCP_TITLE_IND_NONE = 0, + SCCP_TITLE_IND_NATURE_ONLY = 1, + SCCP_TITLE_IND_TRANSLATION_ONLY = 2, + SCCP_TITLE_IND_TRANS_NUM_ENC = 3, + SCCP_TITLE_IND_TRANS_NUM_ENC_NATURE = 4, +}; + +enum { + SCCP_CALL_ROUTE_ON_SSN = 1, + SCCP_CALL_ROUTE_ON_GT = 0, +}; + +struct sccp_called_party_address { + u_int8_t point_code_indicator : 1, + ssn_indicator : 1, + global_title_indicator : 4, + routing_indicator : 1, + reserved : 1; + u_int8_t data[0]; +} __attribute__((packed)); + +/* indicator indicates presence in the above order */ + +/* Figure 6/Q.713 */ +struct sccp_signalling_point_code { + u_int8_t lsb; + u_int8_t msb : 6, + reserved : 2; +} __attribute__((packed)); + +/* SSN == subsystem number */ +enum sccp_subsystem_number { + SCCP_SSN_NOT_KNOWN_OR_USED = 0, + SCCP_SSN_MANAGEMENT = 1, + SCCP_SSN_RESERVED_ITU = 2, + SCCP_SSN_ISDN_USER_PART = 3, + SCCP_SSN_OMAP = 4, /* operation, maint and administration part */ + SCCP_SSN_MAP = 5, /* mobile application part */ + SCCP_SSN_HLR = 6, + SCCP_SSN_VLR = 7, + SCCP_SSN_MSC = 8, + SCCP_SSN_EIC = 9, /* equipent identifier centre */ + SCCP_SSN_AUC = 10, /* authentication centre */ + SCCP_SSN_ISDN_SUPPL_SERVICES = 11, + SCCP_SSN_RESERVED_INTL = 12, + SCCP_SSN_ISDN_EDGE_TO_EDGE = 13, + SCCP_SSN_TC_TEST_RESPONDER = 14, + + /* From GSM 03.03 8.2 */ + SCCP_SSN_BSSAP = 254, + SCCP_SSN_BSSOM = 253, +}; + +/* Q.713, 3.4.2.3 */ +enum { + SCCP_NAI_UNKNOWN = 0, + SCCP_NAI_SUBSCRIBER_NUMBER = 1, + SCCP_NAI_RESERVED_NATIONAL = 2, + SCCP_NAI_NATIONAL_SIGNIFICANT = 3, + SCCP_NAI_INTERNATIONAL = 4, +}; + +struct sccp_global_title { + u_int8_t nature_of_addr_ind : 7, + odd_even : 1; + u_int8_t data[0]; +} __attribute__((packed)); + +/* Q.713, 3.3 */ +struct sccp_source_reference { + u_int8_t octet1; + u_int8_t octet2; + u_int8_t octet3; +} __attribute__((packed)); + +/* Q.714, 3.6 */ +enum sccp_protocol_class { + SCCP_PROTOCOL_CLASS_0 = 0, + SCCP_PROTOCOL_CLASS_1 = 1, + SCCP_PROTOCOL_CLASS_2 = 2, + SCCP_PROTOCOL_CLASS_3 = 3, +}; + +/* bits 5-8 when class0, class1 is used */ +enum sccp_protocol_options { + SCCP_PROTOCOL_NO_SPECIAL = 0, + SCCP_PROTOCOL_RETURN_MESSAGE = 8, +}; + +enum sccp_release_cause { + SCCP_RELEASE_CAUSE_END_USER_ORIGINATED = 0, + SCCP_RELEASE_CAUSE_END_USER_CONGESTION = 1, + SCCP_RELEASE_CAUSE_END_USER_FAILURE = 2, + SCCP_RELEASE_CAUSE_SCCP_USER_ORIGINATED = 3, + SCCP_RELEASE_CAUSE_REMOTE_PROCEDURE_ERROR = 4, + SCCP_RELEASE_CAUSE_INCONSISTENT_CONN_DATA = 5, + SCCP_RELEASE_CAUSE_ACCESS_FAILURE = 6, + SCCP_RELEASE_CAUSE_ACCESS_CONGESTION = 7, + SCCP_RELEASE_CAUSE_SUBSYSTEM_FAILURE = 8, + SCCP_RELEASE_CAUSE_SUBSYSTEM_CONGESTION = 9, + SCCP_RELEASE_CAUSE_MTP_FAILURE = 10, + SCCP_RELEASE_CAUSE_NETWORK_CONGESTION = 11, + SCCP_RELEASE_CAUSE_EXPIRATION_RESET = 12, + SCCP_RELEASE_CAUSE_EXPIRATION_INACTIVE = 13, + SCCP_RELEASE_CAUSE_RESERVED = 14, + SCCP_RELEASE_CAUSE_UNQUALIFIED = 15, + SCCP_RELEASE_CAUSE_SCCP_FAILURE = 16, +}; + +enum sccp_return_cause { + SCCP_RETURN_CAUSE_NO_TRANSLATION_NATURE = 0, + SCCP_RETURN_CAUSE_NO_TRANSLATION = 1, + SCCP_RETURN_CAUSE_SUBSYSTEM_CONGESTION = 2, + SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE = 3, + SCCP_RETURN_CAUSE_UNEQUIPPED_USER = 4, + SCCP_RETURN_CAUSE_MTP_FAILURE = 5, + SCCP_RETURN_CAUSE_NETWORK_CONGESTION = 6, + SCCP_RETURN_CAUSE_UNQUALIFIED = 7, + SCCP_RETURN_CAUSE_ERROR_IN_MSG_TRANSPORT = 8, + SCCP_RETURN_CAUSE_ERROR_IN_LOCAL_PROCESSING = 9, + SCCP_RETURN_CAUSE_DEST_CANNOT_PERFORM_REASSEMBLY = 10, + SCCP_RETURN_CAUSE_SCCP_FAILURE = 11, + SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION = 12, + SCCP_RETURN_CAUSE_SEGMENTATION_NOT_SUPPORTED= 13, + SCCP_RETURN_CAUSE_SEGMENTATION_FAOLURE = 14 +}; + +enum sccp_reset_cause { + SCCP_RESET_CAUSE_END_USER_ORIGINATED = 0, + SCCP_RESET_CAUSE_SCCP_USER_ORIGINATED = 1, + SCCP_RESET_CAUSE_MSG_OUT_OF_ORDER_PS = 2, + SCCP_RESET_CAUSE_MSG_OUT_OF_ORDER_PR = 3, + SCCP_RESET_CAUSE_RPC_OUT_OF_WINDOW = 4, + SCCP_RESET_CAUSE_RPC_INCORRECT_PS = 5, + SCCP_RESET_CAUSE_RPC_GENERAL = 6, + SCCP_RESET_CAUSE_REMOTE_END_USER_OPERATIONAL= 7, + SCCP_RESET_CAUSE_NETWORK_OPERATIONAL = 8, + SCCP_RESET_CAUSE_ACCESS_OPERATIONAL = 9, + SCCP_RESET_CAUSE_NETWORK_CONGESTION = 10, + SCCP_RESET_CAUSE_RESERVED = 11, +}; + +enum sccp_error_cause { + SCCP_ERROR_LRN_MISMATCH_UNASSIGNED = 0, /* local reference number */ + SCCP_ERROR_LRN_MISMATCH_INCONSISTENT = 1, + SCCP_ERROR_POINT_CODE_MISMATCH = 2, + SCCP_ERROR_SERVICE_CLASS_MISMATCH = 3, + SCCP_ERROR_UNQUALIFIED = 4, +}; + +enum sccp_refusal_cause { + SCCP_REFUSAL_END_USER_ORIGINATED = 0, + SCCP_REFUSAL_END_USER_CONGESTION = 1, + SCCP_REFUSAL_END_USER_FAILURE = 2, + SCCP_REFUSAL_SCCP_USER_ORIGINATED = 3, + SCCP_REFUSAL_DESTINATION_ADDRESS_UKNOWN = 4, + SCCP_REFUSAL_DESTINATION_INACCESSIBLE = 5, + SCCP_REFUSAL_NET_QOS_NON_TRANSIENT = 6, + SCCP_REFUSAL_NET_QOS_TRANSIENT = 7, + SCCP_REFUSAL_ACCESS_FAILURE = 8, + SCCP_REFUSAL_ACCESS_CONGESTION = 9, + SCCP_REFUSAL_SUBSYSTEM_FAILURE = 10, + SCCP_REFUSAL_SUBSYTEM_CONGESTION = 11, + SCCP_REFUSAL_EXPIRATION = 12, + SCCP_REFUSAL_INCOMPATIBLE_USER_DATA = 13, + SCCP_REFUSAL_RESERVED = 14, + SCCP_REFUSAL_UNQUALIFIED = 15, + SCCP_REFUSAL_HOP_COUNTER_VIOLATION = 16, + SCCP_REFUSAL_SCCP_FAILURE = 17, + SCCP_REFUSAL_UNEQUIPPED_USER = 18, +}; + +/* + * messages... as of Q.713 Chapter 4 + */ +struct sccp_connection_request { + /* mandantory */ + u_int8_t type; + struct sccp_source_reference source_local_reference; + u_int8_t proto_class; + + + /* variable */ + u_int8_t variable_called; +#if VARIABLE + called_party_address +#endif + + /* optional */ + u_int8_t optional_start; + +#if OPTIONAL + credit 3 + callingparty var 4-n + data 3-130 + hop_counter 3 + importance 3 + end_of_optional 1 +#endif + + u_int8_t data[0]; +} __attribute__((packed)); + +struct sccp_connection_confirm { + /* mandantory */ + u_int8_t type; + struct sccp_source_reference destination_local_reference; + struct sccp_source_reference source_local_reference; + u_int8_t proto_class; + + /* optional */ + u_int8_t optional_start; + + /* optional */ +#if OPTIONAL + credit 3 + called party 4 + data 3-130 + importance 3 + end_of_optional 1 +#endif + + u_int8_t data[0]; +} __attribute__((packed)); + +struct sccp_connection_refused { + /* mandantory */ + u_int8_t type; + struct sccp_source_reference destination_local_reference; + u_int8_t cause; + + /* optional */ + u_int8_t optional_start; + + /* optional */ +#if OPTIONAL + called party 4 + data 3-130 + importance 3 + end_of_optional 1 +#endif + + u_int8_t data[0]; +} __attribute__((packed)); + +struct sccp_connection_released { + /* mandantory */ + u_int8_t type; + struct sccp_source_reference destination_local_reference; + struct sccp_source_reference source_local_reference; + u_int8_t release_cause; + + + /* optional */ + u_int8_t optional_start; + +#if OPTIONAL + data 3-130 + importance 3 + end_of_optional 1 +#endif + u_int8_t data[0]; +} __attribute__((packed)); + +struct sccp_connection_release_complete { + u_int8_t type; + struct sccp_source_reference destination_local_reference; + struct sccp_source_reference source_local_reference; +} __attribute__((packed)); + +struct sccp_data_form1 { + /* mandantory */ + u_int8_t type; + struct sccp_source_reference destination_local_reference; + u_int8_t segmenting; + + /* variable */ + u_int8_t variable_start; + +#if VARIABLE + data 2-256; +#endif + + u_int8_t data[0]; +} __attribute__((packed)); + + +struct sccp_data_unitdata { + /* mandantory */ + u_int8_t type; + u_int8_t proto_class; + + + /* variable */ + u_int8_t variable_called; + u_int8_t variable_calling; + u_int8_t variable_data; + +#if VARIABLE + called party address + calling party address +#endif + + u_int8_t data[0]; +} __attribute__((packed)); + +struct sccp_data_it { + /* mandantory */ + u_int8_t type; + struct sccp_source_reference destination_local_reference; + struct sccp_source_reference source_local_reference; + u_int8_t proto_class; + + u_int8_t sequencing[2]; + u_int8_t credit; +} __attribute__((packed)); + +#endif diff --git a/openbsc/include/vty/command.h b/openbsc/include/vty/command.h index 9daa2d62d..10a60add5 100644 --- a/openbsc/include/vty/command.h +++ b/openbsc/include/vty/command.h @@ -106,6 +106,7 @@ enum node_type { TRX_NODE, TS_NODE, SUBSCR_NODE, + MGCP_NODE, }; /* Node which has some commands and prompt string and configuration |