From 13e10daa330ea2b699c9aa9d14b3adbd01111fd6 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Wed, 10 Jun 2009 05:40:52 +0800 Subject: move openbsc into its own subdirectory --- openbsc/include/openbsc/Makefile.am | 5 + openbsc/include/openbsc/abis_nm.h | 635 +++++++++++++++++++++++++++++ openbsc/include/openbsc/abis_rsl.h | 415 +++++++++++++++++++ openbsc/include/openbsc/call_handling.h | 64 +++ openbsc/include/openbsc/chan_alloc.h | 49 +++ openbsc/include/openbsc/db.h | 44 ++ openbsc/include/openbsc/debug.h | 39 ++ openbsc/include/openbsc/e1_input.h | 159 ++++++++ openbsc/include/openbsc/gsm_04_08.h | 568 ++++++++++++++++++++++++++ openbsc/include/openbsc/gsm_04_11.h | 172 ++++++++ openbsc/include/openbsc/gsm_data.h | 406 ++++++++++++++++++ openbsc/include/openbsc/gsm_subscriber.h | 58 +++ openbsc/include/openbsc/gsm_utils.h | 33 ++ openbsc/include/openbsc/ipaccess.h | 37 ++ openbsc/include/openbsc/linuxlist.h | 360 ++++++++++++++++ openbsc/include/openbsc/misdn.h | 28 ++ openbsc/include/openbsc/msgb.h | 111 +++++ openbsc/include/openbsc/openbscdefines.h | 35 ++ openbsc/include/openbsc/paging.h | 46 +++ openbsc/include/openbsc/rs232.h | 9 + openbsc/include/openbsc/select.h | 22 + openbsc/include/openbsc/signal.h | 88 ++++ openbsc/include/openbsc/subchan_demux.h | 102 +++++ openbsc/include/openbsc/telnet_interface.h | 52 +++ openbsc/include/openbsc/timer.h | 71 ++++ openbsc/include/openbsc/tlv.h | 171 ++++++++ openbsc/include/openbsc/trau_frame.h | 65 +++ openbsc/include/openbsc/trau_mux.h | 49 +++ 28 files changed, 3893 insertions(+) create mode 100644 openbsc/include/openbsc/Makefile.am create mode 100644 openbsc/include/openbsc/abis_nm.h create mode 100644 openbsc/include/openbsc/abis_rsl.h create mode 100644 openbsc/include/openbsc/call_handling.h create mode 100644 openbsc/include/openbsc/chan_alloc.h create mode 100644 openbsc/include/openbsc/db.h create mode 100644 openbsc/include/openbsc/debug.h create mode 100644 openbsc/include/openbsc/e1_input.h create mode 100644 openbsc/include/openbsc/gsm_04_08.h create mode 100644 openbsc/include/openbsc/gsm_04_11.h create mode 100644 openbsc/include/openbsc/gsm_data.h create mode 100644 openbsc/include/openbsc/gsm_subscriber.h create mode 100644 openbsc/include/openbsc/gsm_utils.h create mode 100644 openbsc/include/openbsc/ipaccess.h create mode 100644 openbsc/include/openbsc/linuxlist.h create mode 100644 openbsc/include/openbsc/misdn.h create mode 100644 openbsc/include/openbsc/msgb.h create mode 100644 openbsc/include/openbsc/openbscdefines.h create mode 100644 openbsc/include/openbsc/paging.h create mode 100644 openbsc/include/openbsc/rs232.h create mode 100644 openbsc/include/openbsc/select.h create mode 100644 openbsc/include/openbsc/signal.h create mode 100644 openbsc/include/openbsc/subchan_demux.h create mode 100644 openbsc/include/openbsc/telnet_interface.h create mode 100644 openbsc/include/openbsc/timer.h create mode 100644 openbsc/include/openbsc/tlv.h create mode 100644 openbsc/include/openbsc/trau_frame.h create mode 100644 openbsc/include/openbsc/trau_mux.h (limited to 'openbsc/include/openbsc') diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am new file mode 100644 index 000000000..86f056d26 --- /dev/null +++ b/openbsc/include/openbsc/Makefile.am @@ -0,0 +1,5 @@ +noinst_HEADERS = abis_nm.h abis_rsl.h debug.h db.h gsm_04_08.h gsm_data.h \ + gsm_subscriber.h linuxlist.h msgb.h select.h tlv.h gsm_04_11.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 diff --git a/openbsc/include/openbsc/abis_nm.h b/openbsc/include/openbsc/abis_nm.h new file mode 100644 index 000000000..3aac31f3a --- /dev/null +++ b/openbsc/include/openbsc/abis_nm.h @@ -0,0 +1,635 @@ +/* GSM Network Management messages on the A-bis interface + * 3GPP TS 12.21 version 8.0.0 Release 1999 / ETSI TS 100 623 V8.0.0 */ + +/* (C) 2008-2009 by Harald Welte + * 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 _NM_H +#define _NM_H + +#include + +#include + +/* PRIVATE */ + +/* generic header in front of every OML message according to TS 08.59 */ +struct abis_om_hdr { + u_int8_t mdisc; + u_int8_t placement; + u_int8_t sequence; + u_int8_t length; + u_int8_t data[0]; +} __attribute__ ((packed)); + +#define ABIS_OM_MDISC_FOM 0x80 +#define ABIS_OM_MDISC_MMI 0x40 +#define ABIS_OM_MDISC_TRAU 0x20 +#define ABIS_OM_MDISC_MANUF 0x10 +#define ABIS_OM_PLACEMENT_ONLY 0x80 +#define ABIS_OM_PLACEMENT_FIRST 0x40 +#define ABIS_OM_PLACEMENT_MIDDLE 0x20 +#define ABIS_OM_PLACEMENT_LAST 0x10 + +struct abis_om_obj_inst { + u_int8_t bts_nr; + u_int8_t trx_nr; + u_int8_t ts_nr; +} __attribute__ ((packed)); + +struct abis_om_fom_hdr { + u_int8_t msg_type; + u_int8_t obj_class; + struct abis_om_obj_inst obj_inst; + u_int8_t data[0]; +} __attribute__ ((packed)); + +#define ABIS_OM_FOM_HDR_SIZE (sizeof(struct abis_om_hdr) + sizeof(struct abis_om_fom_hdr)) + +/* Section 9.1: Message Types */ +enum abis_nm_msgtype { + /* SW Download Management Messages */ + NM_MT_LOAD_INIT = 0x01, + NM_MT_LOAD_INIT_ACK, + NM_MT_LOAD_INIT_NACK, + NM_MT_LOAD_SEG, + NM_MT_LOAD_SEG_ACK, + NM_MT_LOAD_ABORT, + NM_MT_LOAD_END, + NM_MT_LOAD_END_ACK, + NM_MT_LOAD_END_NACK, + NM_MT_SW_ACT_REQ, /* BTS->BSC */ + NM_MT_SW_ACT_REQ_ACK, + NM_MT_SW_ACT_REQ_NACK, + NM_MT_ACTIVATE_SW, /* BSC->BTS */ + NM_MT_ACTIVATE_SW_ACK, + NM_MT_ACTIVATE_SW_NACK, + NM_MT_SW_ACTIVATED_REP, /* 0x10 */ + /* A-bis Interface Management Messages */ + NM_MT_ESTABLISH_TEI = 0x21, + NM_MT_ESTABLISH_TEI_ACK, + NM_MT_ESTABLISH_TEI_NACK, + NM_MT_CONN_TERR_SIGN, + NM_MT_CONN_TERR_SIGN_ACK, + NM_MT_CONN_TERR_SIGN_NACK, + NM_MT_DISC_TERR_SIGN, + NM_MT_DISC_TERR_SIGN_ACK, + NM_MT_DISC_TERR_SIGN_NACK, + NM_MT_CONN_TERR_TRAF, + NM_MT_CONN_TERR_TRAF_ACK, + NM_MT_CONN_TERR_TRAF_NACK, + NM_MT_DISC_TERR_TRAF, + NM_MT_DISC_TERR_TRAF_ACK, + NM_MT_DISC_TERR_TRAF_NACK, + /* Transmission Management Messages */ + NM_MT_CONN_MDROP_LINK = 0x31, + NM_MT_CONN_MDROP_LINK_ACK, + NM_MT_CONN_MDROP_LINK_NACK, + NM_MT_DISC_MDROP_LINK, + NM_MT_DISC_MDROP_LINK_ACK, + NM_MT_DISC_MDROP_LINK_NACK, + /* Air Interface Management Messages */ + NM_MT_SET_BTS_ATTR = 0x41, + NM_MT_SET_BTS_ATTR_ACK, + NM_MT_SET_BTS_ATTR_NACK, + NM_MT_SET_RADIO_ATTR, + NM_MT_SET_RADIO_ATTR_ACK, + NM_MT_SET_RADIO_ATTR_NACK, + NM_MT_SET_CHAN_ATTR, + NM_MT_SET_CHAN_ATTR_ACK, + NM_MT_SET_CHAN_ATTR_NACK, + /* Test Management Messages */ + NM_MT_PERF_TEST = 0x51, + NM_MT_PERF_TESET_ACK, + NM_MT_PERF_TEST_NACK, + NM_MT_TEST_REP, + NM_MT_SEND_TEST_REP, + NM_MT_SEND_TEST_REP_ACK, + NM_MT_SEND_TEST_REP_NACK, + NM_MT_STOP_TEST, + NM_MT_STOP_TEST_ACK, + NM_MT_STOP_TEST_NACK, + /* State Management and Event Report Messages */ + NM_MT_STATECHG_EVENT_REP = 0x61, + NM_MT_FAILURE_EVENT_REP, + NM_MT_STOP_EVENT_REP, + NM_MT_STOP_EVENT_REP_ACK, + NM_MT_STOP_EVENT_REP_NACK, + NM_MT_REST_EVENT_REP, + NM_MT_REST_EVENT_REP_ACK, + NM_MT_REST_EVENT_REP_NACK, + NM_MT_CHG_ADM_STATE, + NM_MT_CHG_ADM_STATE_ACK, + NM_MT_CHG_ADM_STATE_NACK, + NM_MT_CHG_ADM_STATE_REQ, + NM_MT_CHG_ADM_STATE_REQ_ACK, + NM_MT_CHG_ADM_STATE_REQ_NACK, + NM_MT_REP_OUTST_ALARMS = 0x93, + NM_MT_REP_OUTST_ALARMS_ACK, + NM_MT_REP_OUTST_ALARMS_NACK, + /* Equipment Management Messages */ + NM_MT_CHANGEOVER = 0x71, + NM_MT_CHANGEOVER_ACK, + NM_MT_CHANGEOVER_NACK, + NM_MT_OPSTART, + NM_MT_OPSTART_ACK, + NM_MT_OPSTART_NACK, + NM_MT_REINIT, + NM_MT_REINIT_ACK, + NM_MT_REINIT_NACK, + NM_MT_SET_SITE_OUT, /* BS11: get alarm ?!? */ + NM_MT_SET_SITE_OUT_ACK, + NM_MT_SET_SITE_OUT_NACK, + NM_MT_CHG_HW_CONF = 0x90, + NM_MT_CHG_HW_CONF_ACK, + NM_MT_CHG_HW_CONF_NACK, + /* Measurement Management Messages */ + NM_MT_MEAS_RES_REQ = 0x8a, + NM_MT_MEAS_RES_RESP, + NM_MT_STOP_MEAS, + NM_MT_START_MEAS, + /* Other Messages */ + NM_MT_GET_ATTR = 0x81, + NM_MT_GET_ATTR_RESP, + NM_MT_GET_ATTR_NACK, + NM_MT_SET_ALARM_THRES, + NM_MT_SET_ALARM_THRES_ACK, + NM_MT_SET_ALARM_THRES_NACK, + + NM_MT_IPACC_RESTART = 0x87, + NM_MT_IPACC_RESTART_ACK, +}; + +enum abis_nm_msgtype_bs11 { + NM_MT_BS11_RESET_RESOURCE = 0x74, + + NM_MT_BS11_BEGIN_DB_TX = 0xa3, + NM_MT_BS11_BEGIN_DB_TX_ACK, + NM_MT_BS11_BEGIN_DB_TX_NACK, + NM_MT_BS11_END_DB_TX = 0xa6, + NM_MT_BS11_END_DB_TX_ACK, + NM_MT_BS11_END_DB_TX_NACK, + NM_MT_BS11_CREATE_OBJ = 0xa9, + NM_MT_BS11_CREATE_OBJ_ACK, + NM_MT_BS11_CREATE_OBJ_NACK, + NM_MT_BS11_DELETE_OBJ = 0xac, + NM_MT_BS11_DELETE_OBJ_ACK, + NM_MT_BS11_DELETE_OBJ_NACK, + + NM_MT_BS11_SET_ATTR = 0xd0, + NM_MT_BS11_SET_ATTR_ACK, + NM_MT_BS11_SET_ATTR_NACK, + NM_MT_BS11_LMT_SESSION = 0xdc, + + NM_MT_BS11_GET_STATE = 0xe3, + NM_MT_BS11_GET_STATE_ACK, + NM_MT_BS11_LMT_LOGON = 0xe5, + NM_MT_BS11_LMT_LOGON_ACK, + NM_MT_BS11_RESTART = 0xe7, + NM_MT_BS11_RESTART_ACK, + NM_MT_BS11_DISCONNECT = 0xe9, + NM_MT_BS11_DISCONNECT_ACK, + NM_MT_BS11_LMT_LOGOFF = 0xec, + NM_MT_BS11_LMT_LOGOFF_ACK, + NM_MT_BS11_RECONNECT = 0xf1, + NM_MT_BS11_RECONNECT_ACK, +}; + +enum abis_nm_msgtype_ipacc { + NM_MT_IPACC_RSL_CONNECT = 0xe0, + NM_MT_IPACC_RSL_CONNECT_ACK, + NM_MT_IPACC_RSL_CONNECT_NACK, + NM_MT_IPACC_SET_NVATTR = 0xef, + NM_MT_IPACC_SET_NVATTR_ACK, + NM_MT_IPACC_SET_NVATTR_NACK, + NM_MT_IPACC_GET_NVATTR = 0xf2, + NM_MT_IPACC_GET_NVATTR_ACK, + NM_MT_IPACC_GET_NVATTR_NACK, +}; + +enum abis_nm_bs11_cell_alloc { + NM_BS11_CANR_GSM = 0x00, + NM_BS11_CANR_DCS1800 = 0x01, +}; + +/* Section 9.2: Object Class */ +enum abis_nm_obj_class { + NM_OC_SITE_MANAGER = 0x00, + NM_OC_BTS, + NM_OC_RADIO_CARRIER, + NM_OC_CHANNEL, + NM_OC_BASEB_TRANSC, + /* RFU: 05-FE */ + NM_OC_BS11_ADJC = 0xa0, + NM_OC_BS11_HANDOVER = 0xa1, + NM_OC_BS11_PWR_CTRL = 0xa2, + NM_OC_BS11_BTSE = 0xa3, /* LMT? */ + NM_OC_BS11_RACK = 0xa4, + NM_OC_BS11 = 0xa5, /* 01: ALCO */ + NM_OC_BS11_TEST = 0xa6, + NM_OC_BS11_ENVABTSE = 0xa8, + NM_OC_BS11_BPORT = 0xa9, + + NM_OC_GPRS_NSE = 0xf0, + NM_OC_GPRS_CELL = 0xf1, + NM_OC_GPRS_NSVC0 = 0xf2, + NM_OC_GPRS_NSVC1 = 0xf3, + + NM_OC_NULL = 0xff, +}; + +/* Section 9.4: Attributes */ +enum abis_nm_attr { + NM_ATT_ABIS_CHANNEL = 0x01, + NM_ATT_ADD_INFO, + NM_ATT_ADD_TEXT, + NM_ATT_ADM_STATE, + NM_ATT_ARFCN_LIST, + NM_ATT_AUTON_REPORT, + NM_ATT_AVAIL_STATUS, + NM_ATT_BCCH_ARFCN, + NM_ATT_BSIC, + NM_ATT_BTS_AIR_TIMER, + NM_ATT_CCCH_L_I_P, + NM_ATT_CCCH_L_T, + NM_ATT_CHAN_COMB, + NM_ATT_CONN_FAIL_CRIT, + NM_ATT_DEST, + /* res */ + NM_ATT_EVENT_TYPE = 0x11, /* BS11: file data ?!? */ + NM_ATT_FILE_ID, + NM_ATT_FILE_VERSION, + NM_ATT_GSM_TIME, + NM_ATT_HSN, + NM_ATT_HW_CONFIG, + NM_ATT_HW_DESC, + NM_ATT_INTAVE_PARAM, + NM_ATT_INTERF_BOUND, + NM_ATT_LIST_REQ_ATTR, + NM_ATT_MAIO, + NM_ATT_MANUF_STATE, + NM_ATT_MANUF_THRESH, + NM_ATT_MANUF_ID, + NM_ATT_MAX_TA, + NM_ATT_MDROP_LINK, /* 0x20 */ + NM_ATT_MDROP_NEXT, + NM_ATT_NACK_CAUSES, + NM_ATT_NY1, + NM_ATT_OPER_STATE, + NM_ATT_OVERL_PERIOD, + NM_ATT_PHYS_CONF, + NM_ATT_POWER_CLASS, + NM_ATT_POWER_THRESH, + NM_ATT_PROB_CAUSE, + NM_ATT_RACH_B_THRESH, + NM_ATT_LDAVG_SLOTS, + NM_ATT_RAD_SUBC, + NM_ATT_RF_MAXPOWR_R, + NM_ATT_SITE_INPUTS, + NM_ATT_SITE_OUTPUTS, + NM_ATT_SOURCE, /* 0x30 */ + NM_ATT_SPEC_PROB, + NM_ATT_START_TIME, + NM_ATT_T200, + NM_ATT_TEI, + NM_ATT_TEST_DUR, + NM_ATT_TEST_NO, + NM_ATT_TEST_REPORT, + NM_ATT_VSWR_THRESH, + NM_ATT_WINDOW_SIZE, + /* Res */ + NM_ATT_BS11_RSSI_OFFS = 0x3d, + NM_ATT_BS11_TXPWR = 0x3e, + NM_ATT_BS11_DIVERSITY = 0x3f, + /* Res */ + NM_ATT_TSC = 0x40, + NM_ATT_SW_CONFIG, + NM_ATT_SW_DESCR, + NM_ATT_SEVERITY, + NM_ATT_GET_ARI, + NM_ATT_HW_CONF_CHG, + NM_ATT_OUTST_ALARM, + NM_ATT_FILE_DATA, + NM_ATT_MEAS_RES, + NM_ATT_MEAS_TYPE, + + NM_ATT_BS11_ESN_FW_CODE_NO = 0x4c, + NM_ATT_BS11_ESN_HW_CODE_NO = 0x4f, + + NM_ATT_BS11_ESN_PCB_SERIAL = 0x55, + NM_ATT_BS11_EXCESSIVE_DISTANCE = 0x58, + + NM_ATT_BS11_ALL_TEST_CATG = 0x60, + NM_ATT_BS11_BTSLS_HOPPING, + NM_ATT_BS11_CELL_ALLOC_NR, + NM_ATT_BS11_CALL_GLOBAL_ID, + NM_ATT_BS11_ENA_INTERF_CLASS = 0x66, + NM_ATT_BS11_ENA_INT_INTEC_HANDO = 0x67, + NM_ATT_BS11_ENA_INT_INTRC_HANDO = 0x68, + NM_ATT_BS11_ENA_MS_PWR_CTRL = 0x69, + NM_ATT_BS11_ENA_PWR_BDGT_HO = 0x6a, + NM_ATT_BS11_ENA_PWR_CTRL_RLFW = 0x6b, + NM_ATT_BS11_ENA_RXLEV_HO = 0x6c, + NM_ATT_BS11_ENA_RXQUAL_HO = 0x6d, + NM_ATT_BS11_FACCH_QUAL = 0x6e, + + NM_ATT_IPACC_RSL_BSC_IP = 0x80, + NM_ATT_IPACC_RSL_BSC_PORT = 0x81, + NM_ATT_IPACC_LOCATION = 0x8e, /* string describing location */ + NM_ATT_IPACC_UNIT_ID = 0x91, /* Site/BTS/TRX */ + NM_ATT_IPACC_UNIT_NAME = 0x93, /* default: nbts- */ + NM_ATT_IPACC_PRIM_OML_IP = 0x95, + NM_ATT_IPACC_SEC_OML_IP = 0x96, + + NM_ATT_BS11_RF_RES_IND_PER = 0x8f, + + NM_ATT_BS11_RX_LEV_MIN_CELL = 0x90, + NM_ATT_BS11_ABIS_EXT_TIME = 0x91, + NM_ATT_BS11_TIMER_HO_REQUEST = 0x92, + NM_ATT_BS11_TIMER_NCELL = 0x93, + NM_ATT_BS11_TSYNC = 0x94, + NM_ATT_BS11_TTRAU = 0x95, + NM_ATT_BS11_EMRG_CFG_MEMBER = 0x9b, + NM_ATT_BS11_TRX_AREA = 0x9f, + + NM_ATT_BS11_BCCH_RECONF = 0xd7, + NM_ATT_BS11_BIT_ERR_THESH = 0xa0, + NM_ATT_BS11_BOOT_SW_VERS = 0xa1, + NM_ATT_BS11_CCLK_ACCURACY = 0xa3, + NM_ATT_BS11_CCLK_TYPE = 0xa4, + NM_ATT_BS11_INP_IMPEDANCE = 0xaa, + NM_ATT_BS11_L1_PROT_TYPE = 0xab, + NM_ATT_BS11_LINE_CFG = 0xac, + NM_ATT_BS11_LI_PORT_1 = 0xad, + NM_ATT_BS11_LI_PORT_2 = 0xae, + + NM_ATT_BS11_L1_REM_ALM_TYPE = 0xb0, + NM_ATT_BS11_SW_LOAD_INTENDED = 0xbb, + NM_ATT_BS11_SW_LOAD_SAFETY = 0xbc, + NM_ATT_BS11_SW_LOAD_STORED = 0xbd, + + NM_ATT_BS11_VENDOR_NAME = 0xc1, + NM_ATT_BS11_HOPPING_MODE = 0xc5, + NM_ATT_BS11_LMT_LOGON_SESSION = 0xc6, + NM_ATT_BS11_LMT_LOGIN_TIME = 0xc7, + NM_ATT_BS11_LMT_USER_ACC_LEV = 0xc8, + NM_ATT_BS11_LMT_USER_NAME = 0xc9, + + NM_ATT_BS11_L1_CONTROL_TS = 0xd8, + NM_ATT_BS11_RADIO_MEAS_GRAN = 0xdc, /* in SACCH multiframes */ + NM_ATT_BS11_RADIO_MEAS_REP = 0xdd, + + NM_ATT_BS11_SH_LAPD_INT_TIMER = 0xe8, + + NM_ATT_BS11_BTS_STATE = 0xf0, + NM_ATT_BS11_E1_STATE = 0xf1, + NM_ATT_BS11_PLL = 0xf2, + NM_ATT_BS11_RX_OFFSET = 0xf3, + NM_ATT_BS11_ANT_TYPE = 0xf4, + NM_ATT_BS11_PLL_MODE = 0xfc, + NM_ATT_BS11_PASSWORD = 0xfd, +}; +#define NM_ATT_BS11_FILE_DATA NM_ATT_EVENT_TYPE + +/* Section 9.4.4: Administrative State */ +enum abis_nm_adm_state { + NM_STATE_LOCKED = 0x01, + NM_STATE_UNLOCKED = 0x02, + NM_STATE_SHUTDOWN = 0x03, + NM_STATE_NULL = 0xff, +}; + +/* Section 9.4.13: Channel Combination */ +enum abis_nm_chan_comb { + NM_CHANC_TCHFull = 0x00, + NM_CHANC_TCHHalf = 0x01, + NM_CHANC_TCHHalf2 = 0x02, + NM_CHANC_SDCCH = 0x03, + NM_CHANC_mainBCCH = 0x04, + NM_CHANC_BCCCHComb = 0x05, + NM_CHANC_BCCH = 0x06, + NM_CHANC_BCCH_CBCH = 0x07, + NM_CHANC_SDCCH_CBCH = 0x08, +}; + +/* Section 9.4.16: Event Type */ +enum abis_nm_event_type { + NM_EVT_COMM_FAIL = 0x00, + NM_EVT_QOS_FAIL = 0x01, + NM_EVT_PROC_FAIL = 0x02, + NM_EVT_EQUIP_FAIL = 0x03, + NM_EVT_ENV_FAIL = 0x04, +}; + +/* Section: 9.4.63: Perceived Severity */ +enum abis_nm_severity { + NM_SEVER_CEASED = 0x00, + NM_SEVER_CRITICAL = 0x01, + NM_SEVER_MAJOR = 0x02, + NM_SEVER_MINOR = 0x03, + NM_SEVER_WARNING = 0x04, + NM_SEVER_INDETERMINATE = 0x05, +}; + +/* Section 9.4.43: Probable Cause Type */ +enum abis_nm_pcause_type { + NM_PCAUSE_T_X721 = 0x01, + NM_PCAUSE_T_GSM = 0x02, + NM_PCAUSE_T_MANUF = 0x03, +}; + +/* Section 9.4.36: NACK Causes */ +enum abis_nm_nack_cause { + /* General Nack Causes */ + NM_NACK_INCORR_STRUCT = 0x01, + NM_NACK_MSGTYPE_INVAL = 0x02, + NM_NACK_OBJCLASS_INVAL = 0x05, + NM_NACK_OBJCLASS_NOTSUPP = 0x06, + NM_NACK_BTSNR_UNKN = 0x07, + NM_NACK_TRXNR_UNKN = 0x08, + NM_NACK_OBJINST_UNKN = 0x09, + NM_NACK_ATTRID_INVAL = 0x0c, + NM_NACK_ATTRID_NOTSUPP = 0x0d, + NM_NACK_PARAM_RANGE = 0x0e, + NM_NACK_ATTRLIST_INCONSISTENT = 0x0f, + NM_NACK_SPEC_IMPL_NOTSUPP = 0x10, + NM_NACK_CANT_PERFORM = 0x11, + /* Specific Nack Causes */ + NM_NACK_RES_NOTIMPL = 0x19, + NM_NACK_RES_NOTAVAIL = 0x1a, + NM_NACK_FREQ_NOTAVAIL = 0x1b, + NM_NACK_TEST_NOTSUPP = 0x1c, + NM_NACK_CAPACITY_RESTR = 0x1d, + NM_NACK_PHYSCFG_NOTPERFORM = 0x1e, + NM_NACK_TEST_NOTINIT = 0x1f, + NM_NACK_PHYSCFG_NOTRESTORE = 0x20, + NM_NACK_TEST_NOSUCH = 0x21, + NM_NACK_TEST_NOSTOP = 0x22, + NM_NACK_MSGINCONSIST_PHYSCFG = 0x23, + NM_NACK_FILE_INCOMPLETE = 0x25, + NM_NACK_FILE_NOTAVAIL = 0x26, + MN_NACK_FILE_NOTACTIVATE = 0x27, + NM_NACK_REQ_NOT_GRANT = 0x28, + NM_NACK_WAIT = 0x29, + NM_NACK_NOTH_REPORT_EXIST = 0x2a, + NM_NACK_MEAS_NOTSUPP = 0x2b, + NM_NACK_MEAS_NOTSTART = 0x2c, +}; + +/* Section 9.4.1 */ +struct abis_nm_channel { + u_int8_t attrib; + u_int8_t bts_port; + u_int8_t timeslot; + u_int8_t subslot; +} __attribute__ ((packed)); + +/* Siemens BS-11 specific objects in the SienemsHW (0xA5) object class */ +enum abis_bs11_objtype { + BS11_OBJ_ALCO = 0x01, + BS11_OBJ_BBSIG = 0x02, /* obj_class: 0,1 */ + BS11_OBJ_TRX1 = 0x03, /* only DEACTIVATE TRX1 */ + BS11_OBJ_CCLK = 0x04, + BS11_OBJ_GPSU = 0x06, + BS11_OBJ_LI = 0x07, + BS11_OBJ_PA = 0x09, /* obj_class: 0, 1*/ +}; + +enum abis_bs11_trx_power { + BS11_TRX_POWER_GSM_2W = 0x06, + BS11_TRX_POWER_GSM_250mW= 0x07, + BS11_TRX_POWER_GSM_80mW = 0x08, + BS11_TRX_POWER_GSM_30mW = 0x09, + BS11_TRX_POWER_DCS_3W = 0x0a, + BS11_TRX_POWER_DCS_1W6 = 0x0b, + BS11_TRX_POWER_DCS_500mW= 0x0c, + BS11_TRX_POWER_DCS_160mW= 0x0d, +}; + +enum abis_bs11_li_pll_mode { + BS11_LI_PLL_LOCKED = 2, + BS11_LI_PLL_STANDALONE = 3, +}; + +enum abis_bs11_phase { + BS11_STATE_SOFTWARE_RQD = 0x01, + BS11_STATE_LOAD_SMU_INTENDED = 0x11, + BS11_STATE_LOAD_SMU_SAFETY = 0x21, + BS11_STATE_LOAD_FAILED = 0x31, + BS11_STATE_LOAD_DIAGNOSTIC = 0x41, + BS11_STATE_WARM_UP = 0x51, + BS11_STATE_WARM_UP_2 = 0x52, + BS11_STATE_WAIT_MIN_CFG = 0x62, + BS11_STATE_MAINTENANCE = 0x72, + BS11_STATE_LOAD_MBCCU = 0x92, + BS11_STATE_WAIT_MIN_CFG_2 = 0xA2, + BS11_STATE_NORMAL = 0x03, + BS11_STATE_ABIS_LOAD = 0x13, +}; + + +/* PUBLIC */ + +struct msgb; + +struct abis_nm_cfg { + /* callback for unidirectional reports */ + int (*report_cb)(struct msgb *, + struct abis_om_fom_hdr *); + /* callback for software activate requests from BTS */ + int (*sw_act_req)(struct msgb *); +}; + +extern int abis_nm_rcvmsg(struct msgb *msg); + +int abis_nm_tlv_parse(struct tlv_parsed *tp, const u_int8_t *buf, int len); +int abis_nm_rx(struct msgb *msg); +int abis_nm_opstart(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0, u_int8_t i1, u_int8_t i2); +int abis_nm_chg_adm_state(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0, + u_int8_t i1, u_int8_t i2, u_int8_t adm_state); +int abis_nm_establish_tei(struct gsm_bts *bts, u_int8_t trx_nr, + u_int8_t e1_port, u_int8_t e1_timeslot, u_int8_t e1_subslot, + u_int8_t tei); +int abis_nm_conn_terr_sign(struct gsm_bts_trx *trx, + u_int8_t e1_port, u_int8_t e1_timeslot, u_int8_t e1_subslot); +int abis_nm_conn_terr_traf(struct gsm_bts_trx_ts *ts, + u_int8_t e1_port, u_int8_t e1_timeslot, + u_int8_t e1_subslot); +int abis_nm_set_bts_attr(struct gsm_bts *bts, u_int8_t *attr, int attr_len); +int abis_nm_set_radio_attr(struct gsm_bts_trx *trx, u_int8_t *attr, int attr_len); +int abis_nm_set_channel_attr(struct gsm_bts_trx_ts *ts, u_int8_t chan_comb); +int abis_nm_sw_act_req_ack(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i1, + u_int8_t i2, u_int8_t i3, int nack, u_int8_t *attr, int att_len); +int abis_nm_raw_msg(struct gsm_bts *bts, int len, u_int8_t *msg); +int abis_nm_event_reports(struct gsm_bts *bts, int on); +int abis_nm_reset_resource(struct gsm_bts *bts); +int abis_nm_software_load(struct gsm_bts *bts, const char *fname, + u_int8_t win_size, int forced, + gsm_cbfn *cbfn, void *cb_data); +int abis_nm_software_load_status(struct gsm_bts *bts); +int abis_nm_software_activate(struct gsm_bts *bts, const char *fname, + gsm_cbfn *cbfn, void *cb_data); + +/* Siemens / BS-11 specific */ +int abis_nm_bs11_reset_resource(struct gsm_bts *bts); +int abis_nm_bs11_db_transmission(struct gsm_bts *bts, int begin); +int abis_nm_bs11_create_object(struct gsm_bts *bts, enum abis_bs11_objtype type, + u_int8_t idx, u_int8_t attr_len, const u_int8_t *attr); +int abis_nm_bs11_create_envaBTSE(struct gsm_bts *bts, u_int8_t idx); +int abis_nm_bs11_create_bport(struct gsm_bts *bts, u_int8_t idx); +int abis_nm_bs11_delete_object(struct gsm_bts *bts, + enum abis_bs11_objtype type, u_int8_t idx); +int abis_nm_bs11_conn_oml_tei(struct gsm_bts *bts, u_int8_t e1_port, + u_int8_t e1_timeslot, u_int8_t e1_subslot, u_int8_t tei); +int abis_nm_bs11_get_oml_tei_ts(struct gsm_bts *bts); +int abis_nm_bs11_get_serno(struct gsm_bts *bts); +int abis_nm_bs11_set_trx_power(struct gsm_bts_trx *trx, u_int8_t level); +int abis_nm_bs11_get_trx_power(struct gsm_bts_trx *trx); +int abis_nm_bs11_factory_logon(struct gsm_bts *bts, int on); +int abis_nm_bs11_set_trx1_pw(struct gsm_bts *bts, const char *password); +int abis_nm_bs11_set_pll_locked(struct gsm_bts *bts, int locked); +int abis_nm_bs11_get_pll_mode(struct gsm_bts *bts); +int abis_nm_bs11_get_cclk(struct gsm_bts *bts); +int abis_nm_bs11_get_state(struct gsm_bts *bts); +int abis_nm_bs11_load_swl(struct gsm_bts *bts, const char *fname, + u_int8_t win_size, int forced, gsm_cbfn *cbfn); +int abis_nm_bs11_set_ext_time(struct gsm_bts *bts); +int abis_nm_bs11_bsc_disconnect(struct gsm_bts *bts, int reconnect); +int abis_nm_bs11_restart(struct gsm_bts *bts); + +/* ip.access nanoBTS specific commands */ +int abis_nm_ipaccess_msg(struct gsm_bts *bts, u_int8_t msg_type, + u_int8_t obj_class, u_int8_t bts_nr, + u_int8_t trx_nr, u_int8_t ts_nr, + u_int8_t *attr, int attr_len); +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); + +/* Functions calling into other code parts */ +enum nm_evt { + EVT_STATECHG_OPER, + EVT_STATECHG_ADM, +}; +int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj, + struct gsm_nm_state *old_state, struct gsm_nm_state *new_state); + +const char *nm_opstate_name(u_int8_t os); +const char *nm_avail_name(u_int8_t avail); +#endif /* _NM_H */ diff --git a/openbsc/include/openbsc/abis_rsl.h b/openbsc/include/openbsc/abis_rsl.h new file mode 100644 index 000000000..532595b90 --- /dev/null +++ b/openbsc/include/openbsc/abis_rsl.h @@ -0,0 +1,415 @@ +/* GSM Radio Signalling Link messages on the A-bis interface + * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */ + +/* (C) 2008 by Harald Welte + * 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 _RSL_H +#define _RSL_H + +struct abis_rsl_common_hdr { + u_int8_t msg_discr; + u_int8_t msg_type; + u_int8_t data[0]; +} __attribute__ ((packed)); + +/* Chapter 8.3 */ +struct abis_rsl_rll_hdr { + struct abis_rsl_common_hdr c; + u_int8_t ie_chan; + u_int8_t chan_nr; + u_int8_t ie_link_id; + u_int8_t link_id; + u_int8_t data[0]; +} __attribute__ ((packed)); + +/* Chapter 8.3 and 8.4 */ +struct abis_rsl_dchan_hdr { + struct abis_rsl_common_hdr c; + u_int8_t ie_chan; + u_int8_t chan_nr; + u_int8_t data[0]; +} __attribute__ ((packed)); + + +/* Chapter 9.1 */ +#define ABIS_RSL_MDISC_RLL 0x02 +#define ABIS_RSL_MDISC_DED_CHAN 0x08 +#define ABIS_RSL_MDISC_COM_CHAN 0x0c +#define ABIS_RSL_MDISC_TRX 0x10 +#define ABIS_RSL_MDISC_LOC 0x20 +#define ABIS_RSL_MDISC_IPACCESS 0x7e +#define ABIS_RSL_MDISC_TRANSP 0x01 + +#define ABIS_RSL_MDISC_IS_TRANSP(x) (x & 0x01) + +/* Chapter 9.1 */ +enum abis_rsl_msgtype { + /* Radio Link Layer Management */ + RSL_MT_DATA_REQ = 0x01, + RSL_MT_DATA_IND, + RSL_MT_ERROR_IND, + RSL_MT_EST_REQ, + RSL_MT_EST_CONF, + RSL_MT_EST_IND, + RSL_MT_REL_REQ, + RSL_MT_REL_CONF, + RSL_MT_REL_IND, + RSL_MT_UNIT_DATA_REQ, + RSL_MT_UNIT_DATA_IND, /* 0x0b */ + + /* Common Channel Management / TRX Management */ + RSL_MT_BCCH_INFO = 0x11, + RSL_MT_CCCH_LOAD_IND, + RSL_MT_CHAN_RQD, + RSL_MT_DELETE_IND, + RSL_MT_PAGING_CMD, + RSL_MT_IMMEDIATE_ASSIGN_CMD, + RSL_MT_SMS_BC_REQ, + /* empty */ + RSL_MT_RF_RES_IND = 0x19, + RSL_MT_SACCH_FILL, + RSL_MT_OVERLOAD, + RSL_MT_ERROR_REPORT, + RSL_MT_SMS_BC_CMD, + RSL_MT_CBCH_LOAD_IND, + RSL_MT_NOT_CMD, /* 0x1f */ + + /* Dedicate Channel Management */ + RSL_MT_CHAN_ACTIV = 0x21, + RSL_MT_CHAN_ACTIV_ACK, + RSL_MT_CHAN_ACTIV_NACK, + RSL_MT_CONN_FAIL, + RSL_MT_DEACTIVATE_SACCH, + RSL_MT_ENCR_CMD, + RSL_MT_HANDO_DET, + RSL_MT_MEAS_RES, + RSL_MT_MODE_MODIFY_REQ, + RSL_MT_MODE_MODIFY_ACK, + RSL_MT_MODE_MODIFY_NACK, + RSL_MT_PHY_CONTEXT_REQ, + RSL_MT_PHY_CONTEXT_CONF, + RSL_MT_RF_CHAN_REL, + RSL_MT_MS_POWER_CONTROL, + RSL_MT_BS_POWER_CONTROL, /* 0x30 */ + RSL_MT_PREPROC_CONFIG, + RSL_MT_PREPROC_MEAS_RES, + RSL_MT_RF_CHAN_REL_ACK, + RSL_MT_SACCH_INFO_MODIFY, + RSL_MT_TALKER_DET, + RSL_MT_LISTENER_DET, + RSL_MT_REMOTE_CODEC_CONF_REP, + RSL_MT_RTD_REP, + RSL_MT_PRE_HANDO_NOTIF, + RSL_MT_MR_CODEC_MOD_REQ, + RSL_MT_MR_CODEC_MOD_ACK, + RSL_MT_MR_CODEC_MOD_NACK, + RSL_MT_MR_CODEC_MOD_PER, + RSL_MT_TFO_REP, + RSL_MT_TFO_MOD_REQ, /* 0x3f */ + + /* ip.access specific RSL message types */ + 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, + +}; + +/* Chapter 9.3 */ +enum abis_rsl_ie { + RSL_IE_CHAN_NR = 0x01, + RSL_IE_LINK_IDENT, + RSL_IE_ACT_TYPE, + RSL_IE_BS_POWER, + RSL_IE_CHAN_IDENT, + RSL_IE_CHAN_MODE, + RSL_IE_ENCR_INFO, + RSL_IE_FRAME_NUMBER, + RSL_IE_HANDO_REF, + RSL_IE_L1_INFO, + RSL_IE_L3_INFO, + RSL_IE_MS_IDENTITY, + RSL_IE_MS_POWER, + RSL_IE_PAGING_GROUP, + RSL_IE_PAGING_LOAD, + RSL_IE_PYHS_CONTEXT = 0x10, + RSL_IE_ACCESS_DELAY, + RSL_IE_RACH_LOAD, + RSL_IE_REQ_REFERENCE, + RSL_IE_RELEASE_MODE, + RSL_IE_RESOURCE_INFO, + RSL_IE_RLM_CAUSE, + RSL_IE_STARTNG_TIME, + RSL_IE_TIMING_ADVANCE, + RSL_IE_UPLINK_MEAS, + RSL_IE_CAUSE, + RSL_IE_MEAS_RES_NR, + RSL_IE_MSG_ID, + /* reserved */ + RSL_IE_SYSINFO_TYPE = 0x1e, + RSL_IE_MS_POWER_PARAM, + RSL_IE_BS_POWER_PARAM, + RSL_IE_PREPROC_PARAM, + RSL_IE_PREPROC_MEAS, + RSL_IE_IMM_ASS_INFO, /* Phase 1 (3.6.0), later Full below */ + RSL_IE_SMSCB_INFO = 0x24, + RSL_IE_MS_TIMING_OFFSET, + RSL_IE_ERR_MSG, + RSL_IE_FULL_BCCH_INFO, + RSL_IE_CHAN_NEEDED, + RSL_IE_CB_CMD_TYPE, + RSL_IE_SMSCB_MSG, + RSL_IE_FULL_IMM_ASS_INFO, + RSL_IE_SACCH_INFO, + RSL_IE_CBCH_LOAD_INFO, + RSL_IE_SMSCB_CHAN_INDICATOR, + RSL_IE_GROUP_CALL_REF, + RSL_IE_CHAN_DESC, + RSL_IE_NCH_DRX_INFO, + RSL_IE_CMD_INDICATOR, + RSL_IE_EMLPP_PRIO, + RSL_IE_UIC, + RSL_IE_MAIN_CHAN_REF, + RSL_IE_MR_CONFIG, + RSL_IE_MR_CONTROL, + RSL_IE_SUP_CODEC_TYPES, + RSL_IE_CODEC_CONFIG, + RSL_IE_RTD, + RSL_IE_TFO_STATUS, + RSL_IE_LLP_APDU, + + RSL_IE_IPAC_REMOTE_IP = 0xf0, + RSL_IE_IPAC_REMOTE_PORT = 0xf1, + RSL_IE_IPAC_LOCAL_PORT = 0xf3, + RSL_IE_IPAC_LOCAL_IP = 0xf5, +}; + +/* Chapter 9.3.1 */ +#define RSL_CHAN_NR_MASK 0xf8 +#define RSL_CHAN_Bm_ACCHs 0x08 +#define RSL_CHAN_Lm_ACCHs 0x10 /* .. 0x18 */ +#define RSL_CHAN_SDCCH4_ACCH 0x20 /* .. 0x38 */ +#define RSL_CHAN_SDCCH8_ACCH 0x40 /* ...0x78 */ +#define RSL_CHAN_BCCH 0x80 +#define RSL_CHAN_RACH 0x88 +#define RSL_CHAN_PCH_AGCH 0x90 + +/* Chapter 9.3.3 */ +#define RSL_ACT_TYPE_INITIAL 0x00 +#define RSL_ACT_TYPE_REACT 0x80 +#define RSL_ACT_INTRA_IMM_ASS 0x00 +#define RSL_ACT_INTRA_NORM_ASS 0x01 +#define RSL_ACT_INTER_ASYNC 0x02 +#define RSL_ACT_INTER_SYNC 0x03 +#define RSL_ACT_SECOND_ADD 0x04 +#define RSL_ACT_SECOND_MULTI 0x05 + +/* Chapter 9.3.6 */ +struct rsl_ie_chan_mode { + u_int8_t dtx_dtu; + u_int8_t spd_ind; + u_int8_t chan_rt; + u_int8_t chan_rate; +} __attribute__ ((packed)); +#define RSL_CMOD_DTXu 0x01 /* uplink */ +#define RSL_CMOD_DTXd 0x02 /* downlink */ +#define RSL_CMOD_SPD_SPEECH 0x01 +#define RSL_CMOD_SPD_DATA 0x02 +#define RSL_CMOD_SPD_SIGN 0x03 +#define RSL_CMOD_CRT_SDCCH 0x01 +#define RSL_CMOD_CRT_TCH_Bm 0x08 /* full-rate */ +#define RSL_CMOD_CRT_TCH_Lm 0x09 /* half-rate */ +/* FIXME: More CRT types */ +#define RSL_CMOD_SP_GSM1 0x01 +#define RSL_CMOD_SP_GSM2 0x11 +#define RSL_CMOD_SP_GSM3 0x21 + +/* Chapter 9.3.5 */ +struct rsl_ie_chan_ident { + /* GSM 04.08 10.5.2.5 */ + struct { + u_int8_t iei; + u_int8_t chan_nr; /* enc_chan_nr */ + u_int8_t oct3; + u_int8_t oct4; + } chan_desc; +#if 0 /* spec says we need this but Abissim doesn't use it */ + struct { + u_int8_t tag; + u_int8_t len; + } mobile_alloc; +#endif +} __attribute__ ((packed)); + +/* Chapter 9.3.22 */ +#define RLL_CAUSE_T200_EXPIRED 0x01 +#define RLL_CAUSE_REEST_REQ 0x02 +#define RLL_CAUSE_UNSOL_UA_RESP 0x03 +#define RLL_CAUSE_UNSOL_DM_RESP 0x04 +#define RLL_CAUSE_UNSOL_DM_RESP_MF 0x05 +#define RLL_CAUSE_UNSOL_SPRV_RESP 0x06 +#define RLL_CAUSE_SEQ_ERR 0x07 +#define RLL_CAUSE_UFRM_INC_PARAM 0x08 +#define RLL_CAUSE_SFRM_INC_PARAM 0x09 +#define RLL_CAUSE_IFRM_INC_MBITS 0x0a +#define RLL_CAUSE_IFRM_INC_LEN 0x0b +#define RLL_CAUSE_FRM_UNIMPL 0x0c +#define RLL_CAUSE_SABM_MF 0x0d +#define RLL_CAUSE_SABM_INFO_NOTALL 0x0e + +/* Chapter 9.3.26 */ +#define RSL_ERRCLS_NORMAL 0x00 +#define RSL_ERRCLS_RESOURCE_UNAVAIL 0x20 +#define RSL_ERRCLS_SERVICE_UNAVAIL 0x30 +#define RSL_ERRCLS_SERVICE_UNIMPL 0x40 +#define RSL_ERRCLS_INVAL_MSG 0x50 +#define RSL_ERRCLS_PROTO_ERROR 0x60 +#define RSL_ERRCLS_INTERWORKING 0x70 + +#define RSL_ERR_RADIO_IF_FAIL 0x00 +#define RSL_ERR_RADIO_LINK_FAIL 0x01 +#define RSL_ERR_HANDOVER_ACC_FAIL 0x02 +#define RSL_ERR_TALKER_ACC_FAIL 0x03 +#define RSL_ERR_OM_INTERVENTION 0x07 +#define RSL_ERR_EQUIPMENT_FAIL 0x20 +#define RSL_ERR_RR_UNAVAIL 0x21 +#define RSL_ERR_TERR_CH_FAIL 0x22 +#define RSL_ERR_CCCH_OVERLOAD 0x23 +#define RSL_ERR_ACCH_OVERLOAD 0x24 +#define RSL_ERR_PROCESSOR_OVERLOAD 0x25 +#define RSL_ERR_RES_UNAVAIL 0x2f +#define RSL_ERR_TRANSC_UNAVAIL 0x30 +#define RSL_ERR_SERV_OPT_UNAVAIL 0x3f +#define RSL_ERR_ENCR_UNIMPL 0x40 +#define RSL_ERR_SEV_OPT_UNIMPL 0x4f +#define RSL_ERR_RCH_ALR_ACTV_ALLOC 0x50 +#define RSL_ERR_INVALID_MESSAGE 0x5f +#define RSL_ERR_MSG_DISCR 0x60 +#define RSL_ERR_MSG_TYPE 0x61 +#define RSL_ERR_MSG_SEQA 0x62 +#define RSL_ERR_IE_ERROR 0x63 +#define RSL_ERR_MAND_IE_ERROR 0x64 +#define RSL_ERR_OPT_IE_ERROR 0x65 +#define RSL_ERR_IE_NONEXIST 0x66 +#define RSL_ERR_IE_LENGTH 0x67 +#define RSL_ERR_IE_CONTENT 0x68 +#define RSL_ERR_PROTO 0x6f +#define RSL_ERR_INTERWORKING 0x7f + +/* Chapter 9.3.30 */ +#define RSL_SYSTEM_INFO_8 0x00 +#define RSL_SYSTEM_INFO_1 0x01 +#define RSL_SYSTEM_INFO_2 0x02 +#define RSL_SYSTEM_INFO_3 0x03 +#define RSL_SYSTEM_INFO_4 0x04 +#define RSL_SYSTEM_INFO_5 0x05 +#define RSL_SYSTEM_INFO_6 0x06 +#define RSL_SYSTEM_INFO_7 0x07 +#define RSL_SYSTEM_INFO_16 0x08 +#define RSL_SYSTEM_INFO_17 0x09 +#define RSL_SYSTEM_INFO_2bis 0x0a +#define RSL_SYSTEM_INFO_2ter 0x0b +#define RSL_SYSTEM_INFO_5bis 0x0d +#define RSL_SYSTEM_INFO_5ter 0x0e +#define RSL_SYSTEM_INFO_10 0x0f +#define REL_EXT_MEAS_ORDER 0x47 +#define RSL_MEAS_INFO 0x48 +#define RSL_SYSTEM_INFO_13 0x28 +#define RSL_SYSTEM_INFO_2quater 0x29 +#define RSL_SYSTEM_INFO_9 0x2a +#define RSL_SYSTEM_INFO_18 0x2b +#define RSL_SYSTEM_INFO_19 0x2c +#define RSL_SYSTEM_INFO_20 0x2d + +/* Chapter 9.3.40 */ +#define RSL_CHANNEED_ANY 0x00 +#define RSL_CHANNEED_SDCCH 0x01 +#define RSL_CHANNEED_TCH_F 0x02 +#define RSL_CHANNEED_TCH_ForH 0x03 + +/* Chapter 3.3.2.3 Brocast control channel */ +/* CCCH-CONF, NC is not combined */ +#define RSL_BCCH_CCCH_CONF_1_NC 0x00 +#define RSL_BCCH_CCCH_CONF_1_C 0x01 +#define RSL_BCCH_CCCH_CONF_2_NC 0x02 +#define RSL_BCCH_CCCH_CONF_3_NC 0x04 +#define RSL_BCCH_CCCH_CONF_4_NC 0x06 + +/* BS-PA-MFRMS */ +#define RSL_BS_PA_MFRMS_2 0x00 +#define RSL_BS_PA_MFRMS_3 0x01 +#define RSL_BS_PA_MFRMS_4 0x02 +#define RSL_BS_PA_MFRMS_5 0x03 +#define RSL_BS_PA_MFRMS_6 0x04 +#define RSL_BS_PA_MFRMS_7 0x05 +#define RSL_BS_PA_MFRMS_8 0x06 +#define RSL_BS_PA_MFRMS_9 0x07 + + +#include "msgb.h" + +int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type, + const u_int8_t *data, int len); +int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type, + const u_int8_t *data, int len); +int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr, + u_int8_t act_type, + struct rsl_ie_chan_mode *chan_mode, + struct rsl_ie_chan_ident *chan_ident, + u_int8_t bs_power, u_int8_t ms_power, + u_int8_t ta); +int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type, + u_int8_t ta, u_int8_t mode); +int rsl_chan_mode_modify_req(struct gsm_lchan *ts); +int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len, + u_int8_t *ms_ident, u_int8_t chan_needed); +int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_needed, + struct gsm_subscriber *subscr); +int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val); + +int rsl_data_request(struct msgb *msg, u_int8_t link_id); + +/* 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 f8, u_int8_t fc); + +int abis_rsl_rcvmsg(struct msgb *msg); + +unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans, + int n_pag_blocks); +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(struct gsm_lchan *lchan); + +/* to be provided by external code */ +int abis_rsl_sendmsg(struct msgb *msg); +int rsl_chan_release(struct gsm_lchan *lchan); + +/* BCCH related code */ +int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf); +int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf); +int rsl_number_of_paging_subchannels(struct gsm_bts *bts); + +#endif /* RSL_MT_H */ + diff --git a/openbsc/include/openbsc/call_handling.h b/openbsc/include/openbsc/call_handling.h new file mode 100644 index 000000000..02027889e --- /dev/null +++ b/openbsc/include/openbsc/call_handling.h @@ -0,0 +1,64 @@ +/* + * (C) 2008 by Holger Hans Peter Freyther + * (C) 2008 by Stefan Schmidt + * 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 _CALL_HANDLING_H +#define _CALL_HANDLING_H + +#include "linuxlist.h" +#include "gsm_subscriber.h" +#include "timer.h" + +/* + * State transitions to be seen from the outside + */ +#define CALL_STATE_NULL 0 +#define CALL_STATE_SETUP 1 +#define CALL_STATE_PROCEED 2 +#define CALL_STATE_ALERT 3 +#define CALL_STATE_CONNECT 4 +#define CALL_STATE_ACTIVE 5 +#define CALL_STATE_RELEASE 6 + +struct call_data { + struct llist_head entry; + void (*state_change_cb)(int oldstate, int newstate, int event, void *data); + void *data; + char *destination_number; + + /* Internal */ + int state; + char tmsi[GSM_TMSI_LENGTH]; + struct timer_list t30x; /* to be added for... */ +}; + + +int call_initiate(struct call_data *call, char *tmsi); +void call_abort(struct call_data *call); + +/** + * Get notified about new incoming calls. The call_data is owned + * and managed by the internal call handling. + */ +void call_set_callback(void (*cb)(struct call_data *call, void *data), void* data); +void call_proceed(struct call_data *call_data); +void call_connect(struct call_data *call_data); + +#endif /* _CALL_HANDLING_H */ diff --git a/openbsc/include/openbsc/chan_alloc.h b/openbsc/include/openbsc/chan_alloc.h new file mode 100644 index 000000000..d6d367c84 --- /dev/null +++ b/openbsc/include/openbsc/chan_alloc.h @@ -0,0 +1,49 @@ +/* Management functions to allocate/release struct gsm_lchan */ +/* (C) 2008 by Harald Welte + * (C) 2009 by Holger Hans Peter Freyther + * 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 _CHAN_ALLOC_H +#define _CHAN_ALLOC_H + +#include "gsm_subscriber.h" + +/* Special allocator for C0 of BTS */ +struct gsm_bts_trx_ts *ts_c0_alloc(struct gsm_bts *bts, + enum gsm_phys_chan_config pchan); + +/* Regular physical channel allocator */ +struct gsm_bts_trx_ts *ts_alloc(struct gsm_bts *bts, + enum gsm_phys_chan_config pchan); + +/* Regular physical channel (TS) */ +void ts_free(struct gsm_bts_trx_ts *ts); + +/* Find an allocated channel */ +struct gsm_lchan *lchan_find(struct gsm_bts *bts, struct gsm_subscriber *subscr); + +/* Allocate a logical channel (SDCCH, TCH, ...) */ +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); + +#endif /* _CHAN_ALLOC_H */ diff --git a/openbsc/include/openbsc/db.h b/openbsc/include/openbsc/db.h new file mode 100644 index 000000000..61a3ac47c --- /dev/null +++ b/openbsc/include/openbsc/db.h @@ -0,0 +1,44 @@ +/* (C) 2008 by Jan Luebbe + * (C) 2009 by Holger Hans Peter Freyther + * 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 _DB_H +#define _DB_H + +#include + +#include + +/* one time initialisation */ +int db_init(const char *name); +int db_prepare(); +int db_fini(); + +/* subscriber management */ +struct gsm_subscriber* db_create_subscriber(char *imsi); +struct gsm_subscriber* db_get_subscriber(enum gsm_subscriber_field field, const char *subscr); +int db_sync_subscriber(struct gsm_subscriber* subscriber); +int db_subscriber_alloc_tmsi(struct gsm_subscriber* subscriber); +int db_subscriber_assoc_imei(struct gsm_subscriber* subscriber, char *imei); + +/* SMS store-and-forward */ +int db_sms_store(struct gsm_sms *sms); +struct gsm_sms *db_sms_get_unsent(int min_id); +int db_sms_mark_sent(struct gsm_sms *sms); +#endif /* _DB_H */ diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h new file mode 100644 index 000000000..63f9e671c --- /dev/null +++ b/openbsc/include/openbsc/debug.h @@ -0,0 +1,39 @@ +#ifndef _DEBUG_H +#define _DEBUG_H + +#define DEBUG + +#define DRLL 0x0001 +#define DCC 0x0002 +#define DMM 0x0004 +#define DRR 0x0008 +#define DRSL 0x0010 +#define DNM 0x0020 + +#define DMNCC 0x0080 +#define DSMS 0x0100 +#define DPAG 0x0200 + +#define DMI 0x1000 +#define DMIB 0x2000 +#define DMUX 0x4000 +#define DINP 0x8000 + +#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) +#else +#define DEBUGP(xss, fmt, args...) +#define DEBUGPC(ss, fmt, args...) +#endif + +#define static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1]; + +char *hexdump(unsigned char *buf, int len); +void debugp(unsigned int subsys, char *file, int line, int cont, const char *format, ...); +void debug_parse_category_mask(const char* mask); +void debug_use_color(int use_color); +void debug_timestamp(int enable); +extern unsigned int debug_mask; + +#endif /* _DEBUG_H */ diff --git a/openbsc/include/openbsc/e1_input.h b/openbsc/include/openbsc/e1_input.h new file mode 100644 index 000000000..132672364 --- /dev/null +++ b/openbsc/include/openbsc/e1_input.h @@ -0,0 +1,159 @@ +#ifndef _E1_INPUT_H +#define _E1_INPUT_H + +#include +#include + +#include +#include +#include +#include +#include + +#define NUM_E1_TS 32 + +enum e1inp_sign_type { + E1INP_SIGN_NONE, + E1INP_SIGN_OML, + E1INP_SIGN_RSL, +}; +const char *e1inp_signtype_name(enum e1inp_sign_type tp); + +struct e1inp_ts; + +struct e1inp_sign_link { + /* list of signalling links */ + struct llist_head list; + + /* to which timeslot do we belong? */ + struct e1inp_ts *ts; + + enum e1inp_sign_type type; + + /* trx for msg->trx of received msgs */ + struct gsm_bts_trx *trx; + + /* msgb queue of to-be-transmitted msgs */ + struct llist_head tx_list; + + /* SAPI and TEI on the E1 TS */ + u_int8_t sapi; + u_int8_t tei; + + union { + struct { + u_int8_t channel; + } misdn; + } driver; +}; + +enum e1inp_ts_type { + E1INP_TS_TYPE_NONE, + E1INP_TS_TYPE_SIGN, + E1INP_TS_TYPE_TRAU, +}; +const char *e1inp_tstype_name(enum e1inp_ts_type tp); + +/* A timeslot in the E1 interface */ +struct e1inp_ts { + enum e1inp_ts_type type; + int num; + + /* to which line do we belong ? */ + struct e1inp_line *line; + + union { + struct { + /* list of all signalling links on this TS */ + struct llist_head sign_links; + /* timer when to dequeue next frame */ + struct timer_list tx_timer; + } sign; + struct { + /* subchannel demuxer for frames from E1 */ + struct subch_demux demux; + /* subchannel muxer for frames to E1 */ + struct subch_mux mux; + } trau; + }; + union { + struct { + /* mISDN driver has one fd for each ts */ + struct bsc_fd fd; + } misdn; + struct { + /* ip.access driver has one fd for each ts */ + struct bsc_fd fd; + } ipaccess; + + } driver; +}; + +struct e1inp_driver { + struct llist_head list; + const char *name; + int (*want_write)(struct e1inp_ts *ts); +}; + +struct e1inp_line { + struct llist_head list; + unsigned int num; + const char *name; + + /* array of timestlots */ + struct e1inp_ts ts[NUM_E1_TS]; + + struct e1inp_driver *driver; + void *driver_data; +}; + +/* register a driver with the E1 core */ +int e1inp_driver_register(struct e1inp_driver *drv); + +/* register a line with the E1 core */ +int e1inp_line_register(struct e1inp_line *line); + +/* find a sign_link for given TEI and SAPI in a TS */ +struct e1inp_sign_link * +e1inp_lookup_sign_link(struct e1inp_ts *ts, u_int8_t tei, + u_int8_t sapi); + +/* create a new signalling link in a E1 timeslot */ +struct e1inp_sign_link * +e1inp_sign_link_create(struct e1inp_ts *ts, enum e1inp_sign_type type, + struct gsm_bts_trx *trx, u_int8_t tei, + u_int8_t sapi); + +/* configure and initialize one e1inp_ts */ +int e1inp_ts_config(struct e1inp_ts *ts, struct e1inp_line *line, + enum e1inp_ts_type type); + +/* Call from the Stack: configuration of this TS has changed */ +int e1inp_update_ts(struct e1inp_ts *ts); + +/* Receive a packet from the E1 driver */ +int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg, + u_int8_t tei, u_int8_t sapi); + +/* called by driver if it wants to transmit on a given TS */ +struct msgb *e1inp_tx_ts(struct e1inp_ts *e1i_ts, + struct e1inp_sign_link **sign_link); + +/* called by driver in case some kind of link state event */ +int e1inp_event(struct e1inp_ts *ts, int evt, u_int8_t tei, u_int8_t sapi); + +/* Write LAPD frames to the fd. */ +void e1_set_pcap_fd(int fd); + +/* called by TRAU muxer to obtain the destination mux entity */ +struct subch_mux *e1inp_get_mux(u_int8_t e1_nr, u_int8_t ts_nr); + +/* e1_config.c */ +int e1_config(struct gsm_bts *bts, int cardnr, int release_l2); +int ia_config_connect(struct gsm_bts *bts, struct sockaddr_in *sin); +int ipaccess_setup(struct gsm_network *gsmnet); + +extern struct llist_head e1inp_driver_list; +extern struct llist_head e1inp_line_list; + +#endif /* _E1_INPUT_H */ diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h new file mode 100644 index 000000000..fe18f4ee5 --- /dev/null +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -0,0 +1,568 @@ +#ifndef _GSM_04_08_H +#define _GSM_04_08_H + +/* GSM TS 04.08 definitions */ +struct gsm_lchan; + +struct gsm48_classmark1 { + u_int8_t spare:1, + rev_level:2, + es_ind:1, + a5_1:1, + pwr_lev:3; +} __attribute__ ((packed)); + +/* Chapter 10.5.2.5 */ +struct gsm48_chan_desc { + u_int8_t chan_nr; + union { + struct { + u_int8_t maio_high:4, + h:1, + tsc:3; + u_int8_t hsn:6, + maio_low:2; + } h1; + struct { + u_int8_t arfcn_high:2, + spare:2, + h:1, + tsc:3; + u_int8_t arfcn_low; + } h0; + }; +} __attribute__ ((packed)); + +/* Chapter 10.5.2.30 */ +struct gsm48_req_ref { + u_int8_t ra; + u_int8_t t3_high:3, + t1_:5; + u_int8_t t2:5, + t3_low:3; +} __attribute__ ((packed)); + +/* Chapter 9.1.5 */ +struct gsm48_chan_mode_modify { + struct gsm48_chan_desc chan_desc; + u_int8_t mode; +} __attribute__ ((packed)); + +#define GSM48_CMODE_SIGN 0x00 +#define GSM48_CMODE_SPEECH_V1 0x01 +#define GSM48_CMODE_SPEECH_EFR 0x21 +#define GSM48_CMODE_SPEECH_AMR 0x41 +#define GSM48_CMODE_DATA_14k5 0x0f +#define GSM48_CMODE_DATA_12k0 0x03 +#define GSM48_CMODE_DATA_6k0 0x0b +#define GSM48_CMODE_DATA_3k6 0x23 + +/* Chapter 9.1.18 */ +struct gsm48_imm_ass { + u_int8_t l2_plen; + u_int8_t proto_discr; + u_int8_t msg_type; + u_int8_t page_mode; + struct gsm48_chan_desc chan_desc; + struct gsm48_req_ref req_ref; + u_int8_t timing_advance; + u_int8_t mob_alloc_len; + u_int8_t mob_alloc[0]; +} __attribute__ ((packed)); + +/* Chapter 10.5.1.3 */ +struct gsm48_loc_area_id { + u_int8_t digits[3]; /* BCD! */ + u_int16_t lac; +} __attribute__ ((packed)); + +/* Section 9.2.15 */ +struct gsm48_loc_upd_req { + u_int8_t type:4, + key_seq:4; + struct gsm48_loc_area_id lai; + struct gsm48_classmark1 classmark1; + u_int8_t mi_len; + u_int8_t mi[0]; +} __attribute__ ((packed)); + +/* Section 10.1 */ +struct gsm48_hdr { + u_int8_t proto_discr; + u_int8_t msg_type; + u_int8_t data[0]; +} __attribute__ ((packed)); + +/* Section 9.1.3x System information Type header */ +struct gsm48_system_information_type_header { + u_int8_t l2_plen; + u_int8_t rr_protocol_discriminator :4, + skip_indicator:4; + u_int8_t system_information; +} __attribute__ ((packed)); + +struct gsm48_rach_control { + u_int8_t re :1, + cell_bar :1, + tx_integer :4, + max_trans :2; + u_int8_t t2; + u_int8_t t3; +} __attribute__ ((packed)); + +/* Section 10.5.2.11 Control Channel Description , Figure 10.5.33 */ +struct gsm48_control_channel_descr { + u_int8_t ccch_conf :3, + bs_ag_blks_res :3, + att :1, + spare1 :1; + u_int8_t bs_pa_mfrms : 3, + spare2 :5; + u_int8_t t3212; +} __attribute__ ((packed)); + +/* Section 9.2.9 CM service request */ +struct gsm48_service_request { + u_int8_t cm_service_type : 4, + cipher_key_seq : 4; + /* length + 3 bytes */ + u_int32_t classmark; + u_int8_t mi_len; + u_int8_t mi[0]; + /* optional priority level */ +} __attribute__ ((packed)); + +/* Section 9.1.31 System information Type 1 */ +struct gsm48_system_information_type_1 { + struct gsm48_system_information_type_header header; + u_int8_t cell_channel_description[16]; + struct gsm48_rach_control rach_control; + u_int8_t s1_reset; +} __attribute__ ((packed)); + +/* Section 9.1.32 System information Type 2 */ +struct gsm48_system_information_type_2 { + struct gsm48_system_information_type_header header; + u_int8_t bcch_frequency_list[16]; + u_int8_t ncc_permitted; + struct gsm48_rach_control rach_control; +} __attribute__ ((packed)); + +/* Section 9.1.35 System information Type 3 */ +struct gsm48_system_information_type_3 { + struct gsm48_system_information_type_header header; + u_int16_t cell_identity; + struct gsm48_loc_area_id lai; + struct gsm48_control_channel_descr control_channel_desc; + u_int8_t cell_options; + u_int8_t cell_selection[2]; + struct gsm48_rach_control rach_control; + u_int8_t s3_reset_octets[4]; +} __attribute__ ((packed)); + +/* Section 9.1.36 System information Type 4 */ +struct gsm48_system_information_type_4 { + struct gsm48_system_information_type_header header; + struct gsm48_loc_area_id lai; + u_int8_t cell_selection[2]; + struct gsm48_rach_control rach_control; + /* optional CBCH conditional CBCH... followed by + mandantory SI 4 Reset Octets + */ + u_int8_t data[0]; +} __attribute__ ((packed)); + +/* Section 9.1.37 System information Type 5 */ +struct gsm48_system_information_type_5 { + u_int8_t rr_protocol_discriminator :4, + skip_indicator:4; + u_int8_t system_information; + u_int8_t bcch_frequency_list[16]; +} __attribute__ ((packed)); + +/* Section 9.1.40 System information Type 6 */ +struct gsm48_system_information_type_6 { + u_int8_t rr_protocol_discriminator :4, + skip_indicator:4; + u_int8_t system_information; + u_int8_t cell_identity[2]; + struct gsm48_loc_area_id lai; + u_int8_t cell_options; + u_int8_t ncc_permitted; + u_int8_t si_6_reset[0]; +} __attribute__ ((packed)); + +/* Section 9.2.12 IMSI Detach Indication */ +struct gsm48_imsi_detach_ind { + struct gsm48_classmark1 classmark1; + u_int8_t mi_len; + u_int8_t mi[0]; +} __attribute__ ((packed)); + +/* Section 10.2 + GSM 04.07 12.2.3.1.1 */ +#define GSM48_PDISC_GROUP_CC 0x00 +#define GSM48_PDISC_BCAST_CC 0x01 +#define GSM48_PDISC_PDSS1 0x02 +#define GSM48_PDISC_CC 0x03 +#define GSM48_PDISC_PDSS2 0x04 +#define GSM48_PDISC_MM 0x05 +#define GSM48_PDISC_RR 0x06 +#define GSM48_PDISC_MM_GPRS 0x08 +#define GSM48_PDISC_SMS 0x09 +#define GSM48_PDISC_SM_GPRS 0x0a +#define GSM48_PDISC_NC_SS 0x0b +#define GSM48_PDISC_LOC 0x0c +#define GSM48_PDISC_MASK 0x0f +#define GSM48_PDISC_USSD 0x11 + +/* Section 10.4 */ +#define GSM48_MT_RR_INIT_REQ 0x3c +#define GSM48_MT_RR_ADD_ASS 0x3b +#define GSM48_MT_RR_IMM_ASS 0x3f +#define GSM48_MT_RR_IMM_ASS_EXT 0x39 +#define GSM48_MT_RR_IMM_ASS_REJ 0x3a + +#define GSM48_MT_RR_CIPH_M_CMD 0x35 +#define GSM48_MT_RR_CIPH_M_COMPL 0x32 + +#define GSM48_MT_RR_CFG_CHG_CMD 0x30 +#define GSM48_MT_RR_CFG_CHG_ACK 0x31 +#define GSM48_MT_RR_CFG_CHG_REJ 0x33 + +#define GSM48_MT_RR_ASS_CMD 0x2e +#define GSM48_MT_RR_ASS_COMPL 0x29 +#define GSM48_MT_RR_ASS_FAIL 0x2f +#define GSM48_MT_RR_HANDO_CMD 0x2b +#define GSM48_MT_RR_HANDO_COMPL 0x2c +#define GSM48_MT_RR_HANDO_FAIL 0x28 +#define GSM48_MT_RR_HANDO_INFO 0x2d + +#define GSM48_MT_RR_CELL_CHG_ORDER 0x08 +#define GSM48_MT_RR_PDCH_ASS_CMD 0x23 + +#define GSM48_MT_RR_CHAN_REL 0x0d +#define GSM48_MT_RR_PART_REL 0x0a +#define GSM48_MT_RR_PART_REL_COMP 0x0f + +#define GSM48_MT_RR_PAG_REQ_1 0x21 +#define GSM48_MT_RR_PAG_REQ_2 0x22 +#define GSM48_MT_RR_PAG_REQ_3 0x24 +#define GSM48_MT_RR_PAG_RESP 0x27 +#define GSM48_MT_RR_NOTIF_NCH 0x20 +#define GSM48_MT_RR_NOTIF_FACCH 0x25 +#define GSM48_MT_RR_NOTIF_RESP 0x26 + +#define GSM48_MT_RR_SYSINFO_8 0x18 +#define GSM48_MT_RR_SYSINFO_1 0x19 +#define GSM48_MT_RR_SYSINFO_2 0x1a +#define GSM48_MT_RR_SYSINFO_3 0x1b +#define GSM48_MT_RR_SYSINFO_4 0x1c +#define GSM48_MT_RR_SYSINFO_5 0x1d +#define GSM48_MT_RR_SYSINFO_6 0x1e +#define GSM48_MT_RR_SYSINFO_7 0x1f + +#define GSM48_MT_RR_SYSINFO_2bis 0x02 +#define GSM48_MT_RR_SYSINFO_2ter 0x03 +#define GSM48_MT_RR_SYSINFO_5bis 0x05 +#define GSM48_MT_RR_SYSINFO_5ter 0x06 +#define GSM48_MT_RR_SYSINFO_9 0x04 +#define GSM48_MT_RR_SYSINFO_13 0x00 + +#define GSM48_MT_RR_SYSINFO_16 0x3d +#define GSM48_MT_RR_SYSINFO_17 0x3e + +#define GSM48_MT_RR_CHAN_MODE_MODIF 0x10 +#define GSM48_MT_RR_STATUS 0x12 +#define GSM48_MT_RR_CHAN_MODE_MODIF_ACK 0x17 +#define GSM48_MT_RR_FREQ_REDEF 0x14 +#define GSM48_MT_RR_MEAS_REP 0x15 +#define GSM48_MT_RR_CLSM_CHG 0x16 +#define GSM48_MT_RR_CLSM_ENQ 0x13 +#define GSM48_MT_RR_EXT_MEAS_REP 0x36 +#define GSM48_MT_RR_EXT_MEAS_REP_ORD 0x37 +#define GSM48_MT_RR_GPRS_SUSP_REQ 0x34 + +#define GSM48_MT_RR_VGCS_UPL_GRANT 0x08 +#define GSM48_MT_RR_UPLINK_RELEASE 0x0e +#define GSM48_MT_RR_UPLINK_FREE 0x0c +#define GSM48_MT_RR_UPLINK_BUSY 0x2a +#define GSM48_MT_RR_TALKER_IND 0x11 + +#define GSM48_MT_RR_APP_INFO 0x38 + +/* Table 10.2/3GPP TS 04.08 */ +#define GSM48_MT_MM_IMSI_DETACH_IND 0x01 +#define GSM48_MT_MM_LOC_UPD_ACCEPT 0x02 +#define GSM48_MT_MM_LOC_UPD_REJECT 0x04 +#define GSM48_MT_MM_LOC_UPD_REQUEST 0x08 + +#define GSM48_MT_MM_AUTH_REJ 0x11 +#define GSM48_MT_MM_AUTH_REQ 0x12 +#define GSM48_MT_MM_AUTH_RESP 0x14 +#define GSM48_MT_MM_ID_REQ 0x18 +#define GSM48_MT_MM_ID_RESP 0x19 +#define GSM48_MT_MM_TMSI_REALL_CMD 0x1a +#define GSM48_MT_MM_TMSI_REALL_COMPL 0x1b + +#define GSM48_MT_MM_CM_SERV_ACC 0x21 +#define GSM48_MT_MM_CM_SERV_REJ 0x22 +#define GSM48_MT_MM_CM_SERV_ABORT 0x23 +#define GSM48_MT_MM_CM_SERV_REQ 0x24 +#define GSM48_MT_MM_CM_SERV_PROMPT 0x25 +#define GSM48_MT_MM_CM_REEST_REQ 0x28 +#define GSM48_MT_MM_ABORT 0x29 + +#define GSM48_MT_MM_NULL 0x30 +#define GSM48_MT_MM_STATUS 0x31 +#define GSM48_MT_MM_INFO 0x32 + +/* Table 10.3/3GPP TS 04.08 */ +#define GSM48_MT_CC_ALERTING 0x01 +#define GSM48_MT_CC_CALL_CONF 0x08 +#define GSM48_MT_CC_CALL_PROC 0x02 +#define GSM48_MT_CC_CONNECT 0x07 +#define GSM48_MT_CC_CONNECT_ACK 0x0f +#define GSM48_MT_CC_EMERG_SETUP 0x0e +#define GSM48_MT_CC_PROGRESS 0x03 +#define GSM48_MT_CC_ESTAB 0x04 +#define GSM48_MT_CC_ESTAB_CONF 0x06 +#define GSM48_MT_CC_RECALL 0x0b +#define GSM48_MT_CC_START_CC 0x09 +#define GSM48_MT_CC_SETUP 0x05 + +#define GSM48_MT_CC_MODIFY 0x17 +#define GSM48_MT_CC_MODIFY_COMPL 0x1f +#define GSM48_MT_CC_MODIFY_REJECT 0x13 +#define GSM48_MT_CC_USER_INFO 0x10 +#define GSM48_MT_CC_HOLD 0x18 +#define GSM48_MT_CC_HOLD_ACK 0x19 +#define GSM48_MT_CC_HOLD_REJ 0x1a +#define GSM48_MT_CC_RETR 0x1c +#define GSM48_MT_CC_RETR_ACK 0x1d +#define GSM48_MT_CC_RETR_REJ 0x1e + +#define GSM48_MT_CC_DISCONNECT 0x25 +#define GSM48_MT_CC_RELEASE 0x2d +#define GSM48_MT_CC_RELEASE_COMPL 0x2a + +#define GSM48_MT_CC_CONG_CTRL 0x39 +#define GSM48_MT_CC_NOTIFY 0x3e +#define GSM48_MT_CC_STATUS 0x3d +#define GSM48_MT_CC_STATUS_ENQ 0x34 +#define GSM48_MT_CC_START_DTMF 0x35 +#define GSM48_MT_CC_STOP_DTMF 0x31 +#define GSM48_MT_CC_STOP_DTMF_ACK 0x32 +#define GSM48_MT_CC_START_DTMF_ACK 0x36 +#define GSM48_MT_CC_START_DTMF_REJ 0x37 +#define GSM48_MT_CC_FACILITY 0x3a + +/* FIXME: Table 10.4 / 10.4a (GPRS) */ + +/* Section 10.5.2.26, Table 10.5.64 */ +#define GSM48_PM_MASK 0x03 +#define GSM48_PM_NORMAL 0x00 +#define GSM48_PM_EXTENDED 0x01 +#define GSM48_PM_REORG 0x02 +#define GSM48_PM_SAME 0x03 + +/* Chapter 10.5.3.5 / Table 10.5.93 */ +#define GSM48_LUPD_NORMAL 0x0 +#define GSM48_LUPD_PERIODIC 0x1 +#define GSM48_LUPD_IMSI_ATT 0x2 +#define GSM48_LUPD_RESERVED 0x3 + +/* Table 10.5.4 */ +#define GSM_MI_TYPE_MASK 0x07 +#define GSM_MI_TYPE_NONE 0x00 +#define GSM_MI_TYPE_IMSI 0x01 +#define GSM_MI_TYPE_IMEI 0x02 +#define GSM_MI_TYPE_IMEISV 0x03 +#define GSM_MI_TYPE_TMSI 0x04 +#define GSM_MI_ODD 0x08 + +#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 */ +#define GSM48_IE_UTC 0x46 /* 10.5.3.8 */ +#define GSM48_IE_NET_TIME_TZ 0x47 /* 10.5.3.9 */ +#define GSM48_IE_LSA_IDENT 0x48 /* 10.5.3.11 */ + +#define GSM48_IE_BEARER_CAP 0x04 /* 10.5.4.5 */ +#define GSM48_IE_CAUSE 0x08 /* 10.5.4.11 */ +#define GSM48_IE_CC_CAP 0x15 /* 10.5.4.5a */ +#define GSM48_IE_ALERT 0x19 /* 10.5.4.26 */ +#define GSM48_IE_FACILITY 0x1c /* 10.5.4.15 */ +#define GSM48_IE_PROGR_IND 0x1e /* 10.5.4.21 */ +#define GSM48_IE_AUX_STATUS 0x24 /* 10.5.4.4 */ +#define GSM48_IE_KPD_FACILITY 0x2c /* 10.5.4.17 */ +#define GSM48_IE_SIGNAL 0x34 /* 10.5.4.23 */ +#define GSM48_IE_CONN_NUM 0x4c /* 10.5.4.13 */ +#define GSM48_IE_CONN_SUBADDR 0x4d /* 10.5.4.14 */ +#define GSM48_IE_CALLING_BCD 0x5c /* 10.5.4.9 */ +#define GSM48_IE_CALLING_SUB 0x5d /* 10.5.4.10 */ +#define GSM48_IE_CALLED_BCD 0x5e /* 10.5.4.7 */ +#define GSM48_IE_CALLED_SUB 0x6d /* 10.5.4.8 */ +#define GSM48_IE_REDIR_BCD 0x74 /* 10.5.4.21a */ +#define GSM48_IE_REDIR_SUB 0x75 /* 10.5.4.21b */ +#define GSM48_IE_LOWL_COMPAT 0x7c /* 10.5.4.18 */ +#define GSM48_IE_HIGHL_COMPAT 0x7d /* 10.5.4.16 */ +#define GSM48_IE_USER_USER 0x7e /* 10.5.4.25 */ +#define GSM48_IE_SS_VERS 0x7f /* 10.5.4.24 */ +#define GSM48_IE_MORE_DATA 0xa0 /* 10.5.4.19 */ +#define GSM48_IE_CLIR_SUPP 0xa1 /* 10.5.4.11a */ +#define GSM48_IE_CLIR_INVOC 0xa2 /* 10.5.4.11b */ +#define GSM48_IE_REV_C_SETUP 0xa3 /* 10.5.4.22a */ + +/* Section 10.5.4.11 / Table 10.5.122 */ +#define GSM48_CAUSE_CS_GSM 0x60 + +/* Section 9.1.2 / Table 9.3 */ +#define GSM48_IE_FRQLIST_AFTER 0x05 +#define GSM48_IE_CELL_CH_DESC 0x62 +#define GSM48_IE_MSLOT_DESC 0x10 +#define GSM48_IE_CHANMODE_1 0x63 +#define GSM48_IE_CHANMODE_2 0x11 +#define GSM48_IE_CHANMODE_3 0x13 +#define GSM48_IE_CHANMODE_4 0x14 +#define GSM48_IE_CHANMODE_5 0x15 +#define GSM48_IE_CHANMODE_6 0x16 +#define GSM48_IE_CHANMODE_7 0x17 +#define GSM48_IE_CHANMODE_8 0x18 +#define GSM48_IE_CHANDESC_2 0x64 +/* FIXME */ + +/* Section 10.5.4.23 / Table 10.5.130 */ +enum gsm48_signal_val { + GSM48_SIGNAL_DIALTONE = 0x00, + GSM48_SIGNAL_RINGBACK = 0x01, + GSM48_SIGNAL_INTERCEPT = 0x02, + GSM48_SIGNAL_NET_CONG = 0x03, + GSM48_SIGNAL_BUSY = 0x04, + GSM48_SIGNAL_CONFIRM = 0x05, + GSM48_SIGNAL_ANSWER = 0x06, + GSM48_SIGNAL_CALL_WAIT = 0x07, + GSM48_SIGNAL_OFF_HOOK = 0x08, + GSM48_SIGNAL_OFF = 0x3f, + GSM48_SIGNAL_ALERT_OFF = 0x4f, +}; + +enum gsm48_cause_loc { + GSM48_CAUSE_LOC_USER = 0x00, + GSM48_CAUSE_LOC_PRN_S_LU = 0x01, + GSM48_CAUSE_LOC_PUN_S_LU = 0x02, + GSM48_CAUSE_LOC_TRANS_NET = 0x03, + GSM48_CAUSE_LOC_PUN_S_RU = 0x04, + GSM48_CAUSE_LOC_PRN_S_RU = 0x05, + /* not defined */ + GSM48_CAUSE_LOC_INN_NET = 0x07, + GSM48_CAUSE_LOC_NET_BEYOND = 0x0a, +}; + +/* Section 10.5.2.31 RR Cause / Table 10.5.70 */ +enum gsm48_rr_cause { + GSM48_RR_CAUSE_NORMAL = 0x00, + GSM48_RR_CAUSE_ABNORMAL_UNSPEC = 0x01, + GSM48_RR_CAUSE_ABNORMAL_UNACCT = 0x02, + GSM48_RR_CAUSE_ABNORMAL_TIMER = 0x03, + GSM48_RR_CAUSE_ABNORMAL_NOACT = 0x04, + GSM48_RR_CAUSE_PREMPTIVE_REL = 0x05, + GSM48_RR_CAUSE_HNDOVER_IMP = 0x06, + GSM48_RR_CAUSE_CHAN_MODE_UNACCT = 0x07, + GSM48_RR_CAUSE_FREQ_NOT_IMPL = 0x08, + GSM48_RR_CAUSE_CALL_CLEARED = 0x41, + GSM48_RR_CAUSE_SEMANT_INCORR = 0x5f, + GSM48_RR_CAUSE_INVALID_MAND_INF = 0x60, + GSM48_RR_CAUSE_MSG_TYPE_N = 0x61, + GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT= 0x62, + GSM48_RR_CAUSE_COND_IE_ERROR = 0x64, + GSM48_RR_CAUSE_NO_CELL_ALLOC_A = 0x65, + GSM48_RR_CAUSE_PROT_ERROR_UNSPC = 0x6f, +}; + +/* Annex G, GSM specific cause values for mobility management */ +enum gsm48_reject_value { + GSM48_REJECT_IMSI_UNKNOWN_IN_HLR = 2, + GSM48_REJECT_ILLEGAL_MS = 3, + GSM48_REJECT_IMSI_UNKNOWN_IN_VLR = 4, + GSM48_REJECT_IMEI_NOT_ACCEPTED = 5, + GSM48_REJECT_ILLEGAL_ME = 6, + GSM48_REJECT_PLMN_NOT_ALLOWED = 11, + GSM48_REJECT_LOC_NOT_ALLOWED = 12, + GSM48_REJECT_ROAMING_NOT_ALLOWED = 13, + GSM48_REJECT_NETWORK_FAILURE = 17, + GSM48_REJECT_CONGESTION = 22, + GSM48_REJECT_SRV_OPT_NOT_SUPPORTED = 32, + GSM48_REJECT_RQD_SRV_OPT_NOT_SUPPORTED = 33, + GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER = 34, + GSM48_REJECT_CALL_CAN_NOT_BE_IDENTIFIED = 38, + GSM48_REJECT_INCORRECT_MESSAGE = 95, + GSM48_REJECT_INVALID_MANDANTORY_INF = 96, + GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED = 97, + GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE = 98, + GSM48_REJECT_INF_ELEME_NOT_IMPLEMENTED = 99, + GSM48_REJECT_CONDTIONAL_IE_ERROR = 100, + GSM48_REJECT_MSG_NOT_COMPATIBLE = 101, + GSM48_REJECT_PROTOCOL_ERROR = 111, + + /* according to G.6 Additional cause codes for GMM */ + GSM48_REJECT_GPRS_NOT_ALLOWED = 7, + GSM48_REJECT_SERVICES_NOT_ALLOWED = 8, + GSM48_REJECT_MS_IDENTITY_NOT_DERVIVABLE = 9, + GSM48_REJECT_IMPLICITLY_DETACHED = 10, + GSM48_REJECT_GPRS_NOT_ALLOWED_IN_PLMN = 14, + GSM48_REJECT_MSC_TMP_NOT_REACHABLE = 16, +}; + + +/* extracted from a L3 measurement report IE */ +struct gsm_meas_rep_cell { + u_int8_t rxlev; + u_int8_t bcch_freq; /* fixme: translate to ARFCN */ + u_int8_t bsic; +}; + +struct gsm_meas_rep { + unsigned int flags; + u_int8_t rxlev_full; + u_int8_t rxqual_full; + u_int8_t rxlev_sub; + u_int8_t rxqual_sub; + int num_cell; + struct gsm_meas_rep_cell cell[6]; +}; +#define MEAS_REP_F_DTX 0x01 +#define MEAS_REP_F_VALID 0x02 +#define MEAS_REP_F_BA1 0x04 + +void gsm48_parse_meas_rep(struct gsm_meas_rep *rep, const u_int8_t *data, + int len); + + +struct msgb; +struct gsm_bts; +struct gsm_subscriber; + +/* config options controlling the behaviour of the lower leves */ +void gsm0408_allow_everyone(int allow); +void gsm0408_set_reject_cause(int cause); + +int gsm0408_rcvmsg(struct msgb *msg); +void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc, + u_int16_t mnc, u_int16_t lac); +int gsm48_cc_tx_setup(struct gsm_lchan *lchan, struct gsm_subscriber *calling); +enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra); +enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra); + +int gsm48_tx_mm_info(struct gsm_lchan *lchan); +struct msgb *gsm48_msgb_alloc(void); +int gsm48_sendmsg(struct msgb *msg); +int generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi); + +int gsm48_send_rr_release(struct gsm_lchan *lchan); + +/* convert a ASCII phone number to call-control BCD */ +int encode_bcd_number(u_int8_t *bcd_lv, u_int8_t max_len, + u_int8_t type, const char *input); +u_int8_t decode_bcd_number(char *output, int output_len, const u_int8_t *bcd_lv); + +#endif diff --git a/openbsc/include/openbsc/gsm_04_11.h b/openbsc/include/openbsc/gsm_04_11.h new file mode 100644 index 000000000..12c607f54 --- /dev/null +++ b/openbsc/include/openbsc/gsm_04_11.h @@ -0,0 +1,172 @@ +#ifndef _GSM_04_11_H +#define _GSM_04_11_H + +/* GSM TS 04.11 definitions */ + +/* Chapter 8.1.2 (refers to GSM 04.07 Chapter 11.2.3.1.1 */ +#define GSM411_PDISC_SMS 0x09 + +/* Chapter 8.1.3 */ +#define GSM411_MT_CP_DATA 0x01 +#define GSM411_MT_CP_ACK 0x04 +#define GSM411_MT_CP_ERROR 0x10 + +enum gsm411_cp_ie { + GSM411_CP_IE_USER_DATA = 0x01, /* 8.1.4.1 */ + GSM411_CP_IE_CAUSE = 0x02, /* 8.1.4.2. */ +}; + +/* Chapter 8.2.2 */ +#define GSM411_MT_RP_DATA_MO 0x00 +#define GSM411_MT_RP_DATA_MT 0x01 +#define GSM411_MT_RP_ACK_MO 0x02 +#define GSM411_MT_RP_ACK_MT 0x03 +#define GSM411_MT_RP_ERROR_MO 0x04 +#define GSM411_MT_RP_ERROR_MT 0x04 +#define GSM411_MT_RP_SMMA_MO 0x05 + +enum gsm411_rp_ie { + GSM411_IE_RP_USER_DATA = 0x41, /* 8.2.5.3 */ + GSM411_IE_RP_CAUSE = 0x42, /* 8.2.5.4 */ +}; + +/* Chapter 8.2.1 */ +struct gsm411_rp_hdr { + u_int8_t len; + u_int8_t msg_type; + u_int8_t msg_ref; + u_int8_t data[0]; +} __attribute__ ((packed)); + +/* our own enum, not related to on-air protocol */ +enum sms_alphabet { + DCS_NONE, + DCS_7BIT_DEFAULT, + DCS_UCS2, + DCS_8BIT_DATA, +}; + +/* SMS submit PDU */ +struct sms_submit { + u_int8_t *smsc; + u_int8_t mti:2; + u_int8_t vpf:2; + u_int8_t msg_ref; + u_int8_t pid; + u_int8_t dcs; + u_int8_t *vp; + u_int8_t ud_len; + u_int8_t *user_data; + + /* interpreted */ + u_int8_t mms:1; + u_int8_t sri:1; + u_int8_t udhi:1; + u_int8_t rp:1; + enum sms_alphabet alphabet; + char dest_addr[20+1]; /* DA LV is 12 bytes max, i.e. 10 bytes BCD == 20 bytes string */ + unsigned long validity_mins; + char decoded[256]; +}; + +/* GSM 03.40 / Chapter 9.2.3.1: TP-Message-Type-Indicator */ +#define GSM340_SMS_DELIVER_SC2MS 0x00 +#define GSM340_SMS_DELIVER_REP_MS2SC 0x00 +#define GSM340_SMS_STATUS_REP_SC2MS 0x02 +#define GSM340_SMS_COMMAND_MS2SC 0x02 +#define GSM340_SMS_SUBMIT_MS2SC 0x01 +#define GSM340_SMS_SUBMIT_REP_SC2MS 0x01 +#define GSM340_SMS_RESSERVED 0x03 + +/* GSM 03.40 / Chapter 9.2.3.2: TP-More-Messages-to-Send */ +#define GSM340_TP_MMS_MORE 0 +#define GSM340_TP_MMS_NO_MORE 1 + +/* GSM 03.40 / Chapter 9.2.3.3: TP-Validity-Period-Format */ +#define GSM340_TP_VPF_NONE 0 +#define GSM340_TP_VPF_RELATIVE 2 +#define GSM340_TP_VPF_ENHANCED 1 +#define GSM340_TP_VPF_ABSOLUTE 3 + +/* GSM 03.40 / Chapter 9.2.3.4: TP-Status-Report-Indication */ +#define GSM340_TP_SRI_NONE 0 +#define GSM340_TP_SRI_PRESENT 1 + +/* GSM 03.40 / Chapter 9.2.3.5: TP-Status-Report-Request */ +#define GSM340_TP_SRR_NONE 0 +#define GSM340_TP_SRR_REQUESTED 1 + +/* GSM 03.40 / Chapter 9.2.3.9: TP-Protocol-Identifier */ +/* telematic interworking (001 or 111 in bits 7-5) */ +#define GSM340_TP_PID_IMPLICIT 0x00 +#define GSM340_TP_PID_TELEX 0x01 +#define GSM340_TP_PID_FAX_G3 0x02 +#define GSM340_TP_PID_FAX_G4 0x03 +#define GSM340_TP_PID_VOICE 0x04 +#define GSM430_TP_PID_ERMES 0x05 +#define GSM430_TP_PID_NATIONAL_PAGING 0x06 +#define GSM430_TP_PID_VIDEOTEX 0x07 +#define GSM430_TP_PID_TELETEX_UNSPEC 0x08 +#define GSM430_TP_PID_TELETEX_PSPDN 0x09 +#define GSM430_TP_PID_TELETEX_CSPDN 0x0a +#define GSM430_TP_PID_TELETEX_PSTN 0x0b +#define GSM430_TP_PID_TELETEX_ISDN 0x0c +#define GSM430_TP_PID_TELETEX_UCI 0x0d +#define GSM430_TP_PID_MSG_HANDLING 0x10 +#define GSM430_TP_PID_MSG_X400 0x11 +#define GSM430_TP_PID_EMAIL 0x12 +#define GSM430_TP_PID_GSM_MS 0x1f +/* if bit 7 = 0 and bit 6 = 1 */ +#define GSM430_TP_PID_SMS_TYPE_0 0 +#define GSM430_TP_PID_SMS_TYPE_1 1 +#define GSM430_TP_PID_SMS_TYPE_2 2 +#define GSM430_TP_PID_SMS_TYPE_3 3 +#define GSM430_TP_PID_SMS_TYPE_4 4 +#define GSM430_TP_PID_SMS_TYPE_5 5 +#define GSM430_TP_PID_SMS_TYPE_6 6 +#define GSM430_TP_PID_SMS_TYPE_7 7 +#define GSM430_TP_PID_RETURN_CALL_MSG 0x1f +#define GSM430_TP_PID_ME_DATA_DNLOAD 0x3d +#define GSM430_TP_PID_ME_DE_PERSONAL 0x3e +#define GSM430_TP_PID_ME_SIM_DNLOAD 0x3f + +/* GSM 03.38 Chapter 4: SMS Data Coding Scheme */ +#define GSM338_DCS_00_ + +#define GSM338_DCS_1110_7BIT (0 << 2) +#define GSM338_DCS_1111_7BIT (0 << 2) +#define GSM338_DCS_1111_8BIT_DATA (1 << 2) +#define GSM338_DCS_1111_CLASS0 0 +#define GSM338_DCS_1111_CLASS1_ME 1 +#define GSM338_DCS_1111_CLASS2_SIM 2 +#define GSM338_DCS_1111_CLASS3_TE 3 /* See TS 07.05 */ + + +/* SMS deliver PDU */ +struct sms_deliver { + u_int8_t *smsc; + u_int8_t mti:2; + u_int8_t rd:1; + u_int8_t vpf:2; + u_int8_t srr:1; + u_int8_t udhi:1; + u_int8_t rp:1; + u_int8_t msg_ref; + u_int8_t *orig_addr; + u_int8_t pid; + u_int8_t dcs; + u_int8_t vp; + u_int8_t ud_len; + u_int8_t *user_data; +}; + +struct msgb; + +int gsm0411_rcv_sms(struct msgb *msg); + +int gsm0411_send_sms(struct gsm_lchan *lchan, struct sms_deliver *sms); + +struct msgb *gsm411_msgb_alloc(void); +int gsm0411_sendmsg(struct msgb *msg); + +#endif diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h new file mode 100644 index 000000000..e85adf829 --- /dev/null +++ b/openbsc/include/openbsc/gsm_data.h @@ -0,0 +1,406 @@ +#ifndef _GSM_DATA_H +#define _GSM_DATA_H + +#include + +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#define GSM_MAX_BTS 8 +#define BTS_MAX_TRX 8 +#define TRX_NR_TS 8 +#define TS_MAX_LCHAN 8 + +#define HARDCODED_ARFCN 123 +#define HARDCODED_TSC 7 +#define HARDCODED_BSIC 0x3f /* NCC = 7 / BCC = 7 */ + +enum gsm_hooks { + GSM_HOOK_NM_SWLOAD, + GSM_HOOK_RR_PAGING, +}; + +enum gsm_paging_event { + GSM_PAGING_SUCCEEDED, + GSM_PAGING_EXPIRED, +}; + +struct msgb; +typedef int gsm_cbfn(unsigned int hooknum, + unsigned int event, + struct msgb *msg, + void *data, void *param); + +/* + * Use the channel. As side effect the lchannel recycle timer + * will be started. + */ +#define LCHAN_RELEASE_TIMEOUT 4, 0 +#define use_lchan(lchan) \ + do { lchan->use_count++; \ + DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) increases usage to: %d\n", \ + lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \ + lchan->nr, lchan->use_count); \ + bsc_schedule_timer(&lchan->release_timer, LCHAN_RELEASE_TIMEOUT); } while(0); + +#define put_lchan(lchan) \ + do { lchan->use_count--; \ + DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \ + lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \ + lchan->nr, lchan->use_count); \ + } while(0); + + +/* communications link with a BTS */ +struct gsm_bts_link { + struct gsm_bts *bts; +}; + +enum gsm_call_type { + GSM_CT_NONE, + GSM_CT_MO, + GSM_CT_MT, +}; + +enum gsm_call_state { + GSM_CSTATE_NULL, + GSM_CSTATE_INITIATED, + GSM_CSTATE_ACTIVE, + GSM_CSTATE_RELEASE_REQ, +}; + +struct gsm_lchan; +struct gsm_subscriber; + +/* One end of a call */ +struct gsm_call { + enum gsm_call_type type; + enum gsm_call_state state; + u_int8_t transaction_id; /* 10.3.2 */ + + /* the 'local' channel */ + struct gsm_lchan *local_lchan; + /* the 'remote' channel */ + struct gsm_lchan *remote_lchan; + + /* the 'remote' subscriber */ + struct gsm_subscriber *called_subscr; +}; + + +enum gsm_phys_chan_config { + GSM_PCHAN_NONE, + GSM_PCHAN_CCCH, + GSM_PCHAN_CCCH_SDCCH4, + GSM_PCHAN_TCH_F, + GSM_PCHAN_TCH_H, + GSM_PCHAN_SDCCH8_SACCH8C, + GSM_PCHAN_UNKNOWN, +}; + +enum gsm_chan_t { + GSM_LCHAN_NONE, + GSM_LCHAN_SDCCH, + GSM_LCHAN_TCH_F, + GSM_LCHAN_TCH_H, + GSM_LCHAN_UNKNOWN, +}; + + +/* Channel Request reason */ +enum gsm_chreq_reason_t { + GSM_CHREQ_REASON_EMERG, + GSM_CHREQ_REASON_PAG, + GSM_CHREQ_REASON_CALL, + GSM_CHREQ_REASON_LOCATION_UPD, + GSM_CHREQ_REASON_OTHER, +}; + +/* Network Management State */ +struct gsm_nm_state { + u_int8_t operational; + u_int8_t administrative; + u_int8_t availability; +}; +struct gsm_attr { + u_int8_t len; + u_int8_t data[0]; +}; + +/* + * LOCATION UPDATING REQUEST state + * + * Our current operation is: + * - Get imei/tmsi + * - Accept/Reject according to global policy + */ +struct gsm_loc_updating_operation { + struct timer_list updating_timer; + int waiting_for_imsi : 1; + int waiting_for_imei : 1; +}; + +struct gsm_lchan { + /* The TS that we're part of */ + struct gsm_bts_trx_ts *ts; + /* The logical subslot number in the TS */ + u_int8_t nr; + /* The logical channel type */ + enum gsm_chan_t type; + /* If TCH, traffic channel mode */ + enum gsm_chan_t tch_mode; + /* Power levels for MS and BTS */ + u_int8_t bs_power; + u_int8_t ms_power; + + /* To whom we are allocated at the moment */ + struct gsm_subscriber *subscr; + + /* Timer started to release the channel */ + struct timer_list release_timer; + + /* local end of a call, if any */ + struct gsm_call call; + + /* temporary user data, to be removed... and merged into gsm_call */ + void *user_data; + + /* + * Operations that have a state and might be pending + */ + struct gsm_loc_updating_operation *loc_operation; + + /* use count. how many users use this channel */ + unsigned int use_count; +}; + +struct gsm_e1_subslot { + /* Number of E1 link */ + u_int8_t e1_nr; + /* Number of E1 TS inside E1 link */ + u_int8_t e1_ts; + /* Sub-slot within the E1 TS, 0xff if full TS */ + u_int8_t e1_ts_ss; +}; + +#define BTS_TRX_F_ACTIVATED 0x0001 +/* One Timeslot in a TRX */ +struct gsm_bts_trx_ts { + struct gsm_bts_trx *trx; + /* number of this timeslot at the TRX */ + u_int8_t nr; + + enum gsm_phys_chan_config pchan; + + unsigned int flags; + struct gsm_nm_state nm_state; + struct gsm_attr *nm_attr; + + /* To which E1 subslot are we connected */ + struct gsm_e1_subslot e1_link; + struct { + u_int32_t bound_ip; + u_int16_t bound_port; + u_int8_t attr_fc; + u_int16_t attr_f8; + } abis_ip; + + struct gsm_lchan lchan[TS_MAX_LCHAN]; +}; + +/* One TRX in a BTS */ +struct gsm_bts_trx { + struct gsm_bts *bts; + /* number of this TRX in the BTS */ + u_int8_t nr; + /* how do we talk RSL with this TRX? */ + struct e1inp_sign_link *rsl_link; + struct gsm_nm_state nm_state; + struct gsm_attr *nm_attr; + struct { + struct gsm_nm_state nm_state; + } bb_transc; + + u_int16_t arfcn; + + union { + struct { + struct { + struct gsm_nm_state nm_state; + } bbsig; + struct { + struct gsm_nm_state nm_state; + } pa; + } bs11; + }; + struct gsm_bts_trx_ts ts[TRX_NR_TS]; +}; + +enum gsm_bts_type { + GSM_BTS_TYPE_UNKNOWN, + GSM_BTS_TYPE_BS11, + GSM_BTS_TYPE_NANOBTS_900, + GSM_BTS_TYPE_NANOBTS_1800, +}; + +/** + * A pending paging request + */ +struct gsm_paging_request { + /* list_head for list of all paging requests */ + struct llist_head entry; + /* the subscriber which we're paging. Later gsm_paging_request + * should probably become a part of the gsm_subscriber struct? */ + struct gsm_subscriber *subscr; + /* back-pointer to the BTS on which we are paging */ + struct gsm_bts *bts; + /* what kind of channel type do we ask the MS to establish */ + int chan_type; + + /* Timer 3113: how long do we try to page? */ + struct timer_list T3113; + + /* callback to be called in case paging completes */ + gsm_cbfn *cbfn; + void *cbfn_param; +}; +#define T3113_VALUE 60, 0 + +/* + * This keeps track of the paging status of one BTS. It + * includes a number of pending requests, a back pointer + * to the gsm_bts, a timer and some more state. + */ +struct gsm_bts_paging_state { + /* pending requests */ + struct llist_head pending_requests; + struct gsm_paging_request *last_request; + struct gsm_bts *bts; + + struct timer_list work_timer; + + /* load */ + u_int16_t available_slots; +}; + +struct gsm_envabtse { + struct gsm_nm_state nm_state; +}; + +/* One BTS */ +struct gsm_bts { + struct gsm_network *network; + /* number of ths BTS in network */ + u_int8_t nr; + /* location area code of this BTS */ + u_int8_t location_area_code; + /* Training Sequence Code */ + u_int8_t tsc; + /* Base Station Identification Code (BSIC) */ + u_int8_t bsic; + /* type of BTS */ + enum gsm_bts_type type; + /* how do we talk OML with this TRX? */ + struct e1inp_sign_link *oml_link; + + /* Abis network management O&M handle */ + struct abis_nm_h *nmh; + struct gsm_nm_state nm_state; + struct gsm_attr *nm_attr; + + /* number of this BTS on given E1 link */ + u_int8_t bts_nr; + + struct gsm48_control_channel_descr chan_desc; + + /* paging state and control */ + struct gsm_bts_paging_state paging; + + /* CCCH is on C0 */ + struct gsm_bts_trx *c0; + + struct { + struct gsm_nm_state nm_state; + } site_mgr; + + /* ip.accesss Unit ID's have Site/BTS/TRX layout */ + union { + struct { + u_int16_t site_id; + u_int16_t bts_id; + } ip_access; + struct { + struct { + struct gsm_nm_state nm_state; + } cclk; + struct { + struct gsm_nm_state nm_state; + } rack; + struct gsm_envabtse envabtse[4]; + } bs11; + }; + + /* transceivers */ + int num_trx; + struct gsm_bts_trx trx[BTS_MAX_TRX+1]; +}; + +struct gsm_network { + /* global parameters */ + u_int16_t country_code; + u_int16_t network_code; + char *name_long; + char *name_short; + + unsigned int num_bts; + /* private lists */ + struct gsm_bts bts[GSM_MAX_BTS+1]; +}; + +#define SMS_HDR_SIZE 128 +#define SMS_TEXT_SIZE 256 +struct gsm_sms { + u_int64_t id; + struct gsm_subscriber *sender; + struct gsm_subscriber *receiver; + + unsigned char header[SMS_HDR_SIZE]; + char text[SMS_TEXT_SIZE]; +}; + +struct gsm_network *gsm_network_init(unsigned int num_bts, enum gsm_bts_type bts_type, + u_int16_t country_code, u_int16_t network_code); + +const char *gsm_pchan_name(enum gsm_phys_chan_config c); +const char *gsm_lchan_name(enum gsm_chan_t c); +const char *gsm_chreq_name(enum gsm_chreq_reason_t c); +char *gsm_ts_name(struct gsm_bts_trx_ts *ts); + +enum gsm_e1_event { + EVT_E1_NONE, + EVT_E1_TEI_UP, + EVT_E1_TEI_DN, +}; + +void set_ts_e1link(struct gsm_bts_trx_ts *ts, u_int8_t e1_nr, + u_int8_t e1_ts, u_int8_t e1_ts_ss); +enum gsm_bts_type parse_btstype(char *arg); +char *btstype2str(enum gsm_bts_type type); +struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac, + struct gsm_bts *start_bts); + +static inline int is_ipaccess_bts(struct gsm_bts *bts) +{ + switch (bts->type) { + case GSM_BTS_TYPE_NANOBTS_900: + case GSM_BTS_TYPE_NANOBTS_1800: + return 1; + default: + break; + } + return 0; +} + +#endif diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h new file mode 100644 index 000000000..1ca79e2ae --- /dev/null +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -0,0 +1,58 @@ +#ifndef _GSM_SUBSCR_H +#define _GSM_SUBSCR_H + +#include +#include "gsm_data.h" +#include "linuxlist.h" + +#define GSM_IMEI_LENGTH 17 +#define GSM_IMSI_LENGTH 17 +#define GSM_TMSI_LENGTH 17 +#define GSM_NAME_LENGTH 128 +#define GSM_EXTENSION_LENGTH 128 + +struct gsm_subscriber { + long long unsigned int id; + char imsi[GSM_IMSI_LENGTH]; + char tmsi[GSM_TMSI_LENGTH]; + u_int16_t lac; + char name[GSM_NAME_LENGTH]; + char extension[GSM_EXTENSION_LENGTH]; + int authorized; + + /* for internal management */ + int use_count; + struct llist_head entry; + + /* those are properties of the equipment, but they + * are applicable to the subscriber at the moment */ + struct gsm48_classmark1 classmark1; + u_int8_t classmark2_len; + u_int8_t classmark2[3]; + u_int8_t classmark3_len; + u_int8_t classmark3[14]; +}; + +enum gsm_subscriber_field { + GSM_SUBSCRIBER_IMSI, + GSM_SUBSCRIBER_TMSI, + GSM_SUBSCRIBER_EXTENSION, +}; + +enum gsm_subscriber_update_reason { + GSM_SUBSCRIBER_UPDATE_ATTACHED, + GSM_SUBSCRIBER_UPDATE_DETACHED, +}; + +struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr); +struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr); +struct gsm_subscriber *subscr_get_by_tmsi(const char *tmsi); +struct gsm_subscriber *subscr_get_by_imsi(const char *imsi); +struct gsm_subscriber *subscr_get_by_extension(const char *ext); +int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason); +void subscr_put_channel(struct gsm_lchan *lchan); + +/* internal */ +struct gsm_subscriber *subscr_alloc(void); + +#endif /* _GSM_SUBSCR_H */ diff --git a/openbsc/include/openbsc/gsm_utils.h b/openbsc/include/openbsc/gsm_utils.h new file mode 100644 index 000000000..c46837185 --- /dev/null +++ b/openbsc/include/openbsc/gsm_utils.h @@ -0,0 +1,33 @@ +/* GSM utility functions, e.g. coding and decoding */ +/* + * (C) 2008 by Daniel Willmann + * (C) 2009 by Holger Hans Peter Freyther + * (C) 2009 by Harald Welte + * + * 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 GSM_UTILS_H +#define GSM_UTILS_H + +#include + +int gsm_7bit_decode(char *decoded, const u_int8_t *user_data, u_int8_t length); +int gsm_7bit_encode(u_int8_t *result, const char *data); + +#endif diff --git a/openbsc/include/openbsc/ipaccess.h b/openbsc/include/openbsc/ipaccess.h new file mode 100644 index 000000000..d6ded3551 --- /dev/null +++ b/openbsc/include/openbsc/ipaccess.h @@ -0,0 +1,37 @@ +#ifndef _IPACCESS_H +#define _IPACCESS_H + +struct ipaccess_head { + u_int8_t zero; + u_int8_t len; + u_int8_t proto; + u_int8_t data[0]; +} __attribute__ ((packed)); + +enum ipaccess_proto { + IPAC_PROTO_RSL = 0x00, + IPAC_PROTO_IPACCESS = 0xfe, + IPAC_PROTO_OML = 0xff, +}; + +enum ipaccess_msgtype { + IPAC_MSGT_PING = 0x00, + IPAC_MSGT_PONG = 0x01, + IPAC_MSGT_ID_GET = 0x04, + IPAC_MSGT_ID_RESP = 0x05, + IPAC_MSGT_ID_ACK = 0x06, +}; + +enum ipaccess_id_tags { + IPAC_IDTAG_SERNR = 0x00, + IPAC_IDTAG_UNITNAME = 0x01, + IPAC_IDTAG_LOCATION1 = 0x02, + IPAC_IDTAG_LOCATION2 = 0x03, + IPAC_IDTAG_EQUIPVERS = 0x04, + IPAC_IDTAG_SWVERSION = 0x05, + IPAC_IDTAG_IPADDR = 0x06, + IPAC_IDTAG_MACADDR = 0x07, + IPAC_IDTAG_UNIT = 0x08, +}; + +#endif /* _IPACCESS_H */ diff --git a/openbsc/include/openbsc/linuxlist.h b/openbsc/include/openbsc/linuxlist.h new file mode 100644 index 000000000..fb99c5ec8 --- /dev/null +++ b/openbsc/include/openbsc/linuxlist.h @@ -0,0 +1,360 @@ +#ifndef _LINUX_LLIST_H +#define _LINUX_LLIST_H + +#include + +#ifndef inline +#define inline __inline__ +#endif + +static inline void prefetch(const void *x) {;} + +/** + * container_of - cast a member of a structure out to the containing structure + * + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (typeof( ((type *)0)->member ) *)(ptr); \ + (type *)( (char *)__mptr - offsetof(type, member) );}) + + +/* + * These are non-NULL pointers that will result in page faults + * under normal circumstances, used to verify that nobody uses + * non-initialized llist entries. + */ +#define LLIST_POISON1 ((void *) 0x00100100) +#define LLIST_POISON2 ((void *) 0x00200200) + +/* + * Simple doubly linked llist implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole llists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +struct llist_head { + struct llist_head *next, *prev; +}; + +#define LLIST_HEAD_INIT(name) { &(name), &(name) } + +#define LLIST_HEAD(name) \ + struct llist_head name = LLIST_HEAD_INIT(name) + +#define INIT_LLIST_HEAD(ptr) do { \ + (ptr)->next = (ptr); (ptr)->prev = (ptr); \ +} while (0) + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal llist manipulation where we know + * the prev/next entries already! + */ +static inline void __llist_add(struct llist_head *_new, + struct llist_head *prev, + struct llist_head *next) +{ + next->prev = _new; + _new->next = next; + _new->prev = prev; + prev->next = _new; +} + +/** + * llist_add - add a new entry + * @new: new entry to be added + * @head: llist head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static inline void llist_add(struct llist_head *_new, struct llist_head *head) +{ + __llist_add(_new, head, head->next); +} + +/** + * llist_add_tail - add a new entry + * @new: new entry to be added + * @head: llist head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void llist_add_tail(struct llist_head *_new, struct llist_head *head) +{ + __llist_add(_new, head->prev, head); +} + +/* + * Delete a llist entry by making the prev/next entries + * point to each other. + * + * This is only for internal llist manipulation where we know + * the prev/next entries already! + */ +static inline void __llist_del(struct llist_head * prev, struct llist_head * next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * llist_del - deletes entry from llist. + * @entry: the element to delete from the llist. + * Note: llist_empty on entry does not return true after this, the entry is + * in an undefined state. + */ +static inline void llist_del(struct llist_head *entry) +{ + __llist_del(entry->prev, entry->next); + entry->next = (struct llist_head *)LLIST_POISON1; + entry->prev = (struct llist_head *)LLIST_POISON2; +} + +/** + * llist_del_init - deletes entry from llist and reinitialize it. + * @entry: the element to delete from the llist. + */ +static inline void llist_del_init(struct llist_head *entry) +{ + __llist_del(entry->prev, entry->next); + INIT_LLIST_HEAD(entry); +} + +/** + * llist_move - delete from one llist and add as another's head + * @llist: the entry to move + * @head: the head that will precede our entry + */ +static inline void llist_move(struct llist_head *llist, struct llist_head *head) +{ + __llist_del(llist->prev, llist->next); + llist_add(llist, head); +} + +/** + * llist_move_tail - delete from one llist and add as another's tail + * @llist: the entry to move + * @head: the head that will follow our entry + */ +static inline void llist_move_tail(struct llist_head *llist, + struct llist_head *head) +{ + __llist_del(llist->prev, llist->next); + llist_add_tail(llist, head); +} + +/** + * llist_empty - tests whether a llist is empty + * @head: the llist to test. + */ +static inline int llist_empty(const struct llist_head *head) +{ + return head->next == head; +} + +static inline void __llist_splice(struct llist_head *llist, + struct llist_head *head) +{ + struct llist_head *first = llist->next; + struct llist_head *last = llist->prev; + struct llist_head *at = head->next; + + first->prev = head; + head->next = first; + + last->next = at; + at->prev = last; +} + +/** + * llist_splice - join two llists + * @llist: the new llist to add. + * @head: the place to add it in the first llist. + */ +static inline void llist_splice(struct llist_head *llist, struct llist_head *head) +{ + if (!llist_empty(llist)) + __llist_splice(llist, head); +} + +/** + * llist_splice_init - join two llists and reinitialise the emptied llist. + * @llist: the new llist to add. + * @head: the place to add it in the first llist. + * + * The llist at @llist is reinitialised + */ +static inline void llist_splice_init(struct llist_head *llist, + struct llist_head *head) +{ + if (!llist_empty(llist)) { + __llist_splice(llist, head); + INIT_LLIST_HEAD(llist); + } +} + +/** + * llist_entry - get the struct for this entry + * @ptr: the &struct llist_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the llist_struct within the struct. + */ +#define llist_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/** + * llist_for_each - iterate over a llist + * @pos: the &struct llist_head to use as a loop counter. + * @head: the head for your llist. + */ +#define llist_for_each(pos, head) \ + for (pos = (head)->next, prefetch(pos->next); pos != (head); \ + pos = pos->next, prefetch(pos->next)) + +/** + * __llist_for_each - iterate over a llist + * @pos: the &struct llist_head to use as a loop counter. + * @head: the head for your llist. + * + * This variant differs from llist_for_each() in that it's the + * simplest possible llist iteration code, no prefetching is done. + * Use this for code that knows the llist to be very short (empty + * or 1 entry) most of the time. + */ +#define __llist_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +/** + * llist_for_each_prev - iterate over a llist backwards + * @pos: the &struct llist_head to use as a loop counter. + * @head: the head for your llist. + */ +#define llist_for_each_prev(pos, head) \ + for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \ + pos = pos->prev, prefetch(pos->prev)) + +/** + * llist_for_each_safe - iterate over a llist safe against removal of llist entry + * @pos: the &struct llist_head to use as a loop counter. + * @n: another &struct llist_head to use as temporary storage + * @head: the head for your llist. + */ +#define llist_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/** + * llist_for_each_entry - iterate over llist of given type + * @pos: the type * to use as a loop counter. + * @head: the head for your llist. + * @member: the name of the llist_struct within the struct. + */ +#define llist_for_each_entry(pos, head, member) \ + for (pos = llist_entry((head)->next, typeof(*pos), member), \ + prefetch(pos->member.next); \ + &pos->member != (head); \ + pos = llist_entry(pos->member.next, typeof(*pos), member), \ + prefetch(pos->member.next)) + +/** + * llist_for_each_entry_reverse - iterate backwards over llist of given type. + * @pos: the type * to use as a loop counter. + * @head: the head for your llist. + * @member: the name of the llist_struct within the struct. + */ +#define llist_for_each_entry_reverse(pos, head, member) \ + for (pos = llist_entry((head)->prev, typeof(*pos), member), \ + prefetch(pos->member.prev); \ + &pos->member != (head); \ + pos = llist_entry(pos->member.prev, typeof(*pos), member), \ + prefetch(pos->member.prev)) + +/** + * llist_for_each_entry_continue - iterate over llist of given type + * continuing after existing point + * @pos: the type * to use as a loop counter. + * @head: the head for your llist. + * @member: the name of the llist_struct within the struct. + */ +#define llist_for_each_entry_continue(pos, head, member) \ + for (pos = llist_entry(pos->member.next, typeof(*pos), member), \ + prefetch(pos->member.next); \ + &pos->member != (head); \ + pos = llist_entry(pos->member.next, typeof(*pos), member), \ + prefetch(pos->member.next)) + +/** + * llist_for_each_entry_safe - iterate over llist of given type safe against removal of llist entry + * @pos: the type * to use as a loop counter. + * @n: another type * to use as temporary storage + * @head: the head for your llist. + * @member: the name of the llist_struct within the struct. + */ +#define llist_for_each_entry_safe(pos, n, head, member) \ + for (pos = llist_entry((head)->next, typeof(*pos), member), \ + n = llist_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = llist_entry(n->member.next, typeof(*n), member)) + +/** + * llist_for_each_rcu - iterate over an rcu-protected llist + * @pos: the &struct llist_head to use as a loop counter. + * @head: the head for your llist. + */ +#define llist_for_each_rcu(pos, head) \ + for (pos = (head)->next, prefetch(pos->next); pos != (head); \ + pos = pos->next, ({ smp_read_barrier_depends(); 0;}), prefetch(pos->next)) + +#define __llist_for_each_rcu(pos, head) \ + for (pos = (head)->next; pos != (head); \ + pos = pos->next, ({ smp_read_barrier_depends(); 0;})) + +/** + * llist_for_each_safe_rcu - iterate over an rcu-protected llist safe + * against removal of llist entry + * @pos: the &struct llist_head to use as a loop counter. + * @n: another &struct llist_head to use as temporary storage + * @head: the head for your llist. + */ +#define llist_for_each_safe_rcu(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, ({ smp_read_barrier_depends(); 0;}), n = pos->next) + +/** + * llist_for_each_entry_rcu - iterate over rcu llist of given type + * @pos: the type * to use as a loop counter. + * @head: the head for your llist. + * @member: the name of the llist_struct within the struct. + */ +#define llist_for_each_entry_rcu(pos, head, member) \ + for (pos = llist_entry((head)->next, typeof(*pos), member), \ + prefetch(pos->member.next); \ + &pos->member != (head); \ + pos = llist_entry(pos->member.next, typeof(*pos), member), \ + ({ smp_read_barrier_depends(); 0;}), \ + prefetch(pos->member.next)) + + +/** + * llist_for_each_continue_rcu - iterate over an rcu-protected llist + * continuing after existing point. + * @pos: the &struct llist_head to use as a loop counter. + * @head: the head for your llist. + */ +#define llist_for_each_continue_rcu(pos, head) \ + for ((pos) = (pos)->next, prefetch((pos)->next); (pos) != (head); \ + (pos) = (pos)->next, ({ smp_read_barrier_depends(); 0;}), prefetch((pos)->next)) + + +#endif diff --git a/openbsc/include/openbsc/misdn.h b/openbsc/include/openbsc/misdn.h new file mode 100644 index 000000000..d3631e794 --- /dev/null +++ b/openbsc/include/openbsc/misdn.h @@ -0,0 +1,28 @@ +/* (C) 2008 by Harald Welte + * 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 MISDN_H +#define MISDN_H + +#include "e1_input.h" + +int mi_setup(int cardnr, struct e1inp_line *line, int release_l2); +int _abis_nm_sendmsg(struct msgb *msg); + +#endif diff --git a/openbsc/include/openbsc/msgb.h b/openbsc/include/openbsc/msgb.h new file mode 100644 index 000000000..2c31d1587 --- /dev/null +++ b/openbsc/include/openbsc/msgb.h @@ -0,0 +1,111 @@ +#ifndef _MSGB_H +#define _MSGB_H + +/* (C) 2008 by Harald Welte + * 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. + * + */ + +#include + +struct bts_link; + +struct msgb { + struct llist_head list; + + /* ptr to the physical E1 link to the BTS(s) */ + struct gsm_bts_link *bts_link; + + /* Part of which TRX logical channel we were received / transmitted */ + struct gsm_bts_trx *trx; + struct gsm_lchan *lchan; + + unsigned char *l2h; + unsigned char *l3h; + unsigned char *smsh; + + u_int16_t data_len; + u_int16_t len; + + unsigned char *head; + unsigned char *tail; + unsigned char *data; + unsigned char _data[0]; +}; + +extern struct msgb *msgb_alloc(u_int16_t size); +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); + +#define msgb_l2(m) ((void *)(m->l2h)) +#define msgb_l3(m) ((void *)(m->l3h)) +#define msgb_sms(m) ((void *)(m->smsh)) + +static inline unsigned int msgb_l2len(const struct msgb *msgb) +{ + return msgb->tail - (u_int8_t *)msgb_l2(msgb); +} + +static inline unsigned int msgb_l3len(const struct msgb *msgb) +{ + return msgb->tail - (u_int8_t *)msgb_l3(msgb); +} + +static inline unsigned int msgb_headlen(const struct msgb *msgb) +{ + return msgb->len - msgb->data_len; +} +static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len) +{ + unsigned char *tmp = msgb->tail; + msgb->tail += len; + msgb->len += len; + return tmp; +} +static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len) +{ + msgb->data -= len; + msgb->len += len; + return msgb->data; +} +static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len) +{ + msgb->len -= len; + return msgb->data += len; +} +static inline int msgb_tailroom(const struct msgb *msgb) +{ + return (msgb->data + msgb->data_len) - msgb->tail; +} + +/* increase the headroom of an empty msgb, reducing the tailroom */ +static inline void msgb_reserve(struct msgb *msg, int len) +{ + msg->data += len; + msg->tail += len; +} + +static inline struct msgb *msgb_alloc_headroom(int size, int headroom) +{ + struct msgb *msg = msgb_alloc(size); + if (msg) + msgb_reserve(msg, headroom); + return msg; +} + +#endif /* _MSGB_H */ diff --git a/openbsc/include/openbsc/openbscdefines.h b/openbsc/include/openbsc/openbscdefines.h new file mode 100644 index 000000000..082e5922e --- /dev/null +++ b/openbsc/include/openbsc/openbscdefines.h @@ -0,0 +1,35 @@ +/* + * (C) 2009 by Holger Hans Peter Freyther + * + * 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 OPENBSCDEFINES_H +#define OPENBSCDEFINES_H + +#ifdef BUILDING_ON_WINDOWS + #ifdef BUILDING_OPENBSC + #define BSC_API __declspec(dllexport) + #else + #define BSC_API __declspec(dllimport) + #endif +#else + #define BSC_API __attribute__((visibility("default"))) +#endif + +#endif diff --git a/openbsc/include/openbsc/paging.h b/openbsc/include/openbsc/paging.h new file mode 100644 index 000000000..de512d1ae --- /dev/null +++ b/openbsc/include/openbsc/paging.h @@ -0,0 +1,46 @@ +/* Paging helper and manager.... */ +/* (C) 2009 by Holger Hans Peter Freyther + * 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 PAGING_H +#define PAGING_H + +#include +#include + +#include "linuxlist.h" +#include "gsm_data.h" +#include "gsm_subscriber.h" +#include "timer.h" + +/* call once for every gsm_bts... */ +void paging_init(struct gsm_bts *bts); + +/* schedule paging request */ +void paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscr, + int type, gsm_cbfn *cbfn, void *data); + +/* stop paging requests */ +void paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *subscr, + struct gsm_lchan *lchan); + +/* update paging load */ +void paging_update_buffer_space(struct gsm_bts *bts, u_int16_t); + +#endif diff --git a/openbsc/include/openbsc/rs232.h b/openbsc/include/openbsc/rs232.h new file mode 100644 index 000000000..61187ca62 --- /dev/null +++ b/openbsc/include/openbsc/rs232.h @@ -0,0 +1,9 @@ +#ifndef _RS232_H +#define _RS232_H + +int rs232_setup(const char *serial_port, unsigned int delay_ms, + struct gsm_bts *bts); + +int handle_serial_msg(struct msgb *msg); + +#endif /* _RS232_H */ diff --git a/openbsc/include/openbsc/select.h b/openbsc/include/openbsc/select.h new file mode 100644 index 000000000..c2af1d787 --- /dev/null +++ b/openbsc/include/openbsc/select.h @@ -0,0 +1,22 @@ +#ifndef _BSC_SELECT_H +#define _BSC_SELECT_H + +#include + +#define BSC_FD_READ 0x0001 +#define BSC_FD_WRITE 0x0002 +#define BSC_FD_EXCEPT 0x0004 + +struct bsc_fd { + struct llist_head list; + int fd; + unsigned int when; + int (*cb)(struct bsc_fd *fd, unsigned int what); + void *data; + unsigned int priv_nr; +}; + +int bsc_register_fd(struct bsc_fd *fd); +void bsc_unregister_fd(struct bsc_fd *fd); +int bsc_select_main(int polling); +#endif /* _BSC_SELECT_H */ diff --git a/openbsc/include/openbsc/signal.h b/openbsc/include/openbsc/signal.h new file mode 100644 index 000000000..4a583f689 --- /dev/null +++ b/openbsc/include/openbsc/signal.h @@ -0,0 +1,88 @@ +/* Generic signalling/notification infrastructure */ +/* (C) 2009 by Holger Hans Peter Freyther + * (C) 2009 by Harald Welte + * 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 OPENBSC_SIGNAL_H +#define OPENBSC_SIGNAL_H + +#include +#include + +#include +#include + + +/* + * Signalling subsystems + */ +enum signal_subsystems { + SS_PAGING, + SS_SMS, + SS_ABISIP, + SS_NM, + SS_LCHAN, +}; + +/* SS_PAGING signals */ +enum signal_paging { + S_PAGING_COMPLETED, +}; + +/* SS_ABISIP signals */ +enum signal_abisip { + S_ABISIP_BIND_ACK, +}; + +/* SS_NM signals */ +enum signal_nm { + S_NM_SW_ACTIV_REP, /* GSM 12.21 software activated report */ + S_NM_FAIL_REP, /* GSM 12.21 failure event report */ +}; + +/* SS_LCHAN signals */ +enum signal_lchan { + /* + * The lchan got freed with an use_count != 0 and error + * recovery needs to be carried out from within the + * signal handler. + */ + S_LCHAN_UNEXPECTED_RELEASE, +}; + +typedef int signal_cbfn(unsigned int subsys, unsigned int signal, + void *handler_data, void *signal_data); + +struct paging_signal_data { + struct gsm_subscriber *subscr; + struct gsm_bts *bts; + + /* NULL in case the paging didn't work */ + struct gsm_lchan *lchan; +}; + +/* 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); + +/* Dispatch */ +void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data); + + +#endif diff --git a/openbsc/include/openbsc/subchan_demux.h b/openbsc/include/openbsc/subchan_demux.h new file mode 100644 index 000000000..9661b0481 --- /dev/null +++ b/openbsc/include/openbsc/subchan_demux.h @@ -0,0 +1,102 @@ +#ifndef _SUBCH_DEMUX_H +#define _SUBCH_DEMUX_H +/* A E1 sub-channel (de)multiplexer with TRAU frame sync */ + +/* (C) 2009 by Harald Welte + * 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. + * + */ + +#include +#include + +#define NR_SUBCH 4 +#define TRAU_FRAME_SIZE 40 +#define TRAU_FRAME_BITS (TRAU_FRAME_SIZE*8) + +/***********************************************************************/ +/* DEMULTIPLEXER */ +/***********************************************************************/ + +struct demux_subch { + u_int8_t out_bitbuf[TRAU_FRAME_BITS]; + u_int16_t out_idx; /* next bit to be written in out_bitbuf */ + /* number of consecutive zeros that we have received (for sync) */ + unsigned int consecutive_zeros; + /* are we in TRAU frame sync or not? */ + unsigned int in_sync; +}; + +struct subch_demux { + /* bitmask of currently active subchannels */ + u_int8_t chan_activ; + /* one demux_subch struct for every subchannel */ + struct demux_subch subch[NR_SUBCH]; + /* callback to be called once we have received a complete + * frame on a given subchannel */ + int (*out_cb)(struct subch_demux *dmx, int ch, u_int8_t *data, int len, + void *); + /* user-provided data, transparently passed to out_cb() */ + void *data; +}; + +/* initialize one demultiplexer instance */ +int subch_demux_init(struct subch_demux *dmx); + +/* feed 'len' number of muxed bytes into the demultiplexer */ +int subch_demux_in(struct subch_demux *dmx, u_int8_t *data, int len); + +/* activate decoding/processing for one subchannel */ +int subch_demux_activate(struct subch_demux *dmx, int subch); + +/* deactivate decoding/processing for one subchannel */ +int subch_demux_deactivate(struct subch_demux *dmx, int subch); + +/***********************************************************************/ +/* MULTIPLEXER */ +/***********************************************************************/ + +/* one element in the tx_queue of a muxer sub-channel */ +struct subch_txq_entry { + struct llist_head list; + + unsigned int bit_len; /* total number of bits in 'bits' */ + unsigned int next_bit; /* next bit to be transmitted */ + + u_int8_t bits[0]; /* one bit per byte */ +}; + +struct mux_subch { + struct llist_head tx_queue; +}; + +/* structure representing one instance of the subchannel muxer */ +struct subch_mux { + struct mux_subch subch[NR_SUBCH]; +}; + +/* initialize a subchannel muxer instance */ +int subchan_mux_init(struct subch_mux *mx); + +/* request the output of 'len' multiplexed bytes */ +int subchan_mux_out(struct subch_mux *mx, u_int8_t *data, int len); + +/* enqueue some data into one sub-channel of the muxer */ +int subchan_mux_enqueue(struct subch_mux *mx, int s_nr, const u_int8_t *data, + int len); + +#endif /* _SUBCH_DEMUX_H */ diff --git a/openbsc/include/openbsc/telnet_interface.h b/openbsc/include/openbsc/telnet_interface.h new file mode 100644 index 000000000..97357d794 --- /dev/null +++ b/openbsc/include/openbsc/telnet_interface.h @@ -0,0 +1,52 @@ +/* minimalistic telnet/network interface it might turn into a wire interface */ +/* (C) 2009 by Holger Hans Peter Freyther + * 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 TELNET_INTERFACE_H +#define TELNET_INTERFACE_H + +#include "gsm_data.h" +#include "linuxlist.h" +#include "select.h" + +#include + +#define TELNET_COMMAND_48 1 +#define TELNET_COMMAND_11 2 + +struct telnet_connection { + struct llist_head entry; + struct gsm_network *network; + struct bsc_fd fd; + struct vty *vty; + + int bts; + + int command; + char *imsi; + char commands[1024]; + int read; +}; + + +void telnet_init(struct gsm_network *network, int port); + +int bsc_vty_init(struct gsm_network *net); + +#endif diff --git a/openbsc/include/openbsc/timer.h b/openbsc/include/openbsc/timer.h new file mode 100644 index 000000000..ae67a5a1a --- /dev/null +++ b/openbsc/include/openbsc/timer.h @@ -0,0 +1,71 @@ +/* + * (C) 2008, 2009 by Holger Hans Peter Freyther + * 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 TIMER_H +#define TIMER_H + +#include + +#include "linuxlist.h" + +/** + * Timer management: + * - Create a struct timer_list + * - Fill out timeout and use add_timer or + * use schedule_timer to schedule a timer in + * x seconds and microseconds from now... + * - Use del_timer to remove the timer + * + * Internally: + * - We hook into select.c to give a timeval of the + * nearest timer. On already passed timers we give + * it a 0 to immediately fire after the select + * - update_timers will call the callbacks and remove + * the timers. + * + */ +struct timer_list { + struct llist_head entry; + struct timeval timeout; + int active : 1; + int handled : 1; + int in_list : 1; + + void (*cb)(void*); + void *data; +}; + +/** + * timer management + */ +void bsc_add_timer(struct timer_list *timer); +void bsc_schedule_timer(struct timer_list *timer, int seconds, int microseconds); +void bsc_del_timer(struct timer_list *timer); +int bsc_timer_pending(struct timer_list *timer); + + +/** + * internal timer list management + */ +struct timeval *bsc_nearest_timer(); +void bsc_prepare_timers(); +int bsc_update_timers(); + +#endif diff --git a/openbsc/include/openbsc/tlv.h b/openbsc/include/openbsc/tlv.h new file mode 100644 index 000000000..ae88e6ed3 --- /dev/null +++ b/openbsc/include/openbsc/tlv.h @@ -0,0 +1,171 @@ +#ifndef _TLV_H +#define _TLV_H + +#include +#include + +#include + +#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) + +/* TLV generation */ + +static inline u_int8_t *lv_put(u_int8_t *buf, u_int8_t len, + const u_int8_t *val) +{ + *buf++ = len; + memcpy(buf, val, len); + return buf + len; +} + +static inline u_int8_t *tlv_put(u_int8_t *buf, u_int8_t tag, u_int8_t len, + const u_int8_t *val) +{ + *buf++ = tag; + *buf++ = len; + memcpy(buf, val, len); + return buf + len; +} + +static inline u_int8_t *tlv16_put(u_int8_t *buf, u_int8_t tag, u_int8_t len, + const u_int16_t *val) +{ + *buf++ = tag; + *buf++ = len; + memcpy(buf, val, len*2); + return buf + len*2; +} + +static inline u_int8_t *tl16v_put(u_int8_t *buf, u_int8_t tag, u_int16_t len, + const u_int8_t *val) +{ + *buf++ = tag; + *buf++ = len >> 8; + *buf++ = len & 0xff; + memcpy(buf, val, len); + return buf + len*2; +} + +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)); + return tlv16_put(buf, tag, len, val); +} + +static inline u_int8_t *msgb_tl16v_put(struct msgb *msg, u_int8_t tag, u_int16_t len, + const u_int8_t *val) +{ + u_int8_t *buf = msgb_put(msg, TL16V_GROSS_LEN(len)); + return tl16v_put(buf, tag, len, val); +} + +static inline u_int8_t *v_put(u_int8_t *buf, u_int8_t val) +{ + *buf++ = val; + return buf; +} + +static inline u_int8_t *tv_put(u_int8_t *buf, u_int8_t tag, + u_int8_t val) +{ + *buf++ = tag; + *buf++ = val; + return buf; +} + +static inline u_int8_t *tv16_put(u_int8_t *buf, u_int8_t tag, + u_int16_t val) +{ + *buf++ = tag; + *buf++ = val >> 8; + *buf++ = val & 0xff; + return buf; +} + +static inline u_int8_t *msgb_lv_put(struct msgb *msg, u_int8_t len, const u_int8_t *val) +{ + u_int8_t *buf = msgb_put(msg, LV_GROSS_LEN(len)); + return lv_put(buf, len, val); +} + +static inline u_int8_t *msgb_tlv_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val) +{ + u_int8_t *buf = msgb_put(msg, TLV_GROSS_LEN(len)); + return tlv_put(buf, tag, len, val); +} + +static inline u_int8_t *msgb_tv_put(struct msgb *msg, u_int8_t tag, u_int8_t val) +{ + u_int8_t *buf = msgb_put(msg, 2); + return tv_put(buf, tag, val); +} + +static inline u_int8_t *msgb_v_put(struct msgb *msg, u_int8_t val) +{ + u_int8_t *buf = msgb_put(msg, 1); + return v_put(buf, val); +} + +static inline u_int8_t *msgb_tv16_put(struct msgb *msg, u_int8_t tag, u_int16_t val) +{ + u_int8_t *buf = msgb_put(msg, 3); + return tv16_put(buf, tag, val); +} + +static inline u_int8_t *msgb_tlv_push(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val) +{ + u_int8_t *buf = msgb_push(msg, TLV_GROSS_LEN(len)); + return tlv_put(buf, tag, len, val); +} + +static inline u_int8_t *msgb_tv_push(struct msgb *msg, u_int8_t tag, u_int8_t val) +{ + u_int8_t *buf = msgb_push(msg, 2); + return tv_put(buf, tag, val); +} + +static inline u_int8_t *msgb_tv16_push(struct msgb *msg, u_int8_t tag, u_int16_t val) +{ + u_int8_t *buf = msgb_push(msg, 3); + return tv16_put(buf, tag, val); +} + +/* TLV parsing */ + +struct tlv_p_entry { + u_int16_t len; + const u_int8_t *val; +}; + +enum tlv_type { + TLV_TYPE_FIXED, + TLV_TYPE_T, + TLV_TYPE_TV, + TLV_TYPE_TLV, + TLV_TYPE_TL16V, +}; + +struct tlv_def { + enum tlv_type type; + u_int8_t fixed_len; +}; + +struct tlv_definition { + struct tlv_def def[0xff]; +}; + +struct tlv_parsed { + struct tlv_p_entry lv[0xff]; +}; + +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); + +#define TLVP_PRESENT(x, y) ((x)->lv[y].val) +#define TLVP_LEN(x, y) (x)->lv[y].len +#define TLVP_VAL(x, y) (x)->lv[y].val + +#endif /* _TLV_H */ diff --git a/openbsc/include/openbsc/trau_frame.h b/openbsc/include/openbsc/trau_frame.h new file mode 100644 index 000000000..5923d4ac1 --- /dev/null +++ b/openbsc/include/openbsc/trau_frame.h @@ -0,0 +1,65 @@ +#ifndef _TRAU_FRAME_H +#define _TRAU_FRAME_H +/* TRAU frame handling according to GSM TS 08.60 */ + +/* (C) 2009 by Harald Welte + * 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. + * + */ + +#include + +/* 21 for FR/EFR, 25 for AMR, 15 for OM, 15 for data, 13 for E-data, 21 idle */ +#define MAX_C_BITS 25 +/* 260 for FR/EFR, 256 for AMR, 264 for OM, 288 for E-data */ +#define MAX_D_BITS 288 +/* for all speech frames */ +#define MAX_T_BITS 4 +/* for OM */ +#define MAX_S_BITS 6 +/* for E-data */ +#define MAX_M_BITS 2 + +struct decoded_trau_frame { + u_int8_t c_bits[MAX_C_BITS]; + u_int8_t d_bits[MAX_D_BITS]; + u_int8_t t_bits[MAX_T_BITS]; + u_int8_t s_bits[MAX_S_BITS]; + u_int8_t m_bits[MAX_M_BITS]; +}; + +#define TRAU_FT_FR_UP 0x02 /* 0 0 0 1 0 - 3.5.1.1.1 */ +#define TRAU_FT_FR_DOWN 0x1c /* 1 1 1 0 0 - 3.5.1.1.1 */ +#define TRAU_FT_EFR 0x1a /* 1 1 0 1 0 - 3.5.1.1.1 */ +#define TRAU_FT_AMR 0x06 /* 0 0 1 1 0 - 3.5.1.2 */ +#define TRAU_FT_OM_UP 0x07 /* 0 0 1 0 1 - 3.5.2 */ +#define TRAU_FT_OM_DOWN 0x1b /* 1 1 0 1 1 - 3.5.2 */ +#define TRAU_FT_DATA_UP 0x08 /* 0 1 0 0 0 - 3.5.3 */ +#define TRAU_FT_DATA_DOWN 0x16 /* 1 0 1 1 0 - 3.5.3 */ +#define TRAU_FT_D145_SYNC 0x14 /* 1 0 1 0 0 - 3.5.3 */ +#define TRAU_FT_EDATA 0x1f /* 1 1 1 1 1 - 3.5.4 */ +#define TRAU_FT_IDLE_UP 0x10 /* 1 0 0 0 0 - 3.5.5 */ +#define TRAU_FT_IDLE_DOWN 0x0e /* 0 1 1 1 0 - 3.5.5 */ + + +int decode_trau_frame(struct decoded_trau_frame *fr, const u_int8_t *trau_bits); +int encode_trau_frame(u_int8_t *trau_bits, const struct decoded_trau_frame *fr); +int trau_frame_up2down(struct decoded_trau_frame *fr); +u_int8_t *trau_idle_frame(void); + + +#endif /* _TRAU_FRAME_H */ diff --git a/openbsc/include/openbsc/trau_mux.h b/openbsc/include/openbsc/trau_mux.h new file mode 100644 index 000000000..90535add4 --- /dev/null +++ b/openbsc/include/openbsc/trau_mux.h @@ -0,0 +1,49 @@ +/* Simple TRAU frame reflector to route voice calls */ + +/* (C) 2009 by Harald Welte + * 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. + * + */ + +/* The "TRAU mux map" defines which particular 16kbit sub-slot (in which E1 + * timeslot on which E1 interface) should be directly muxed to which other + * sub-slot. Entries in the mux map are always bi-directional. + * + * The idea of all this is to directly switch voice channels in the BSC + * from one phone to another. We do this right now since we don't support + * any external interface for voice channels, and in the future as an + * optimization to routing them externally. + */ + +/* map a TRAU mux map entry */ +int trau_mux_map(const struct gsm_e1_subslot *src, + const struct gsm_e1_subslot *dst); +int trau_mux_map_lchan(const struct gsm_lchan *src, + const struct gsm_lchan *dst); + +/* unmap a TRAU mux map entry */ +int trau_mux_unmap(const struct gsm_e1_subslot *ss, u_int32_t callref); + +/* we get called by subchan_demux */ +int trau_mux_input(struct gsm_e1_subslot *src_e1_ss, + const u_int8_t *trau_bits, int num_bits); + +/* add a trau receiver */ +int trau_recv_lchan(struct gsm_lchan *lchan, u_int32_t callref); + +/* send trau from application */ +int trau_send_lchan(struct gsm_lchan *lchan, struct decoded_trau_frame *tf); -- cgit v1.2.3