aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/abis_nm.h4
-rw-r--r--openbsc/include/openbsc/gsm_data.h12
-rw-r--r--openbsc/src/Makefile.am5
-rw-r--r--openbsc/src/abis_nm.c93
-rw-r--r--openbsc/src/bs11_config.c5
-rw-r--r--openbsc/src/bsc_hack.c6
-rw-r--r--openbsc/src/bts_ipaccess_nanobts.c84
-rw-r--r--openbsc/src/bts_siemens_bs11.c66
-rw-r--r--openbsc/src/gsm_data.c43
-rw-r--r--openbsc/src/vty_interface.c5
10 files changed, 234 insertions, 89 deletions
diff --git a/openbsc/include/openbsc/abis_nm.h b/openbsc/include/openbsc/abis_nm.h
index d6469c466..81b4eda61 100644
--- a/openbsc/include/openbsc/abis_nm.h
+++ b/openbsc/include/openbsc/abis_nm.h
@@ -719,6 +719,8 @@ struct ipac_bcch_info {
u_int8_t ca_list_si1[16];
};
+extern const struct tlv_definition nm_att_tlvdef;
+
/* PUBLIC */
struct msgb;
@@ -733,7 +735,7 @@ struct abis_nm_cfg {
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_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, 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,
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 573ce5fb7..5567d89bd 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -335,6 +335,15 @@ enum gsm_bts_type {
GSM_BTS_TYPE_NANOBTS,
};
+struct gsm_bts_model {
+ struct llist_head list;
+
+ enum gsm_bts_type type;
+ const char *name;
+
+ struct tlv_definition nm_att_tlvdef;
+};
+
/**
* A pending paging request
*/
@@ -402,6 +411,7 @@ struct gsm_bts {
u_int8_t bsic;
/* type of BTS */
enum gsm_bts_type type;
+ struct gsm_bts_model *model;
enum gsm_band band;
/* should the channel allocator allocate channels from high TRX to TRX0,
* rather than starting from TRX0 and go upwards? */
@@ -619,7 +629,7 @@ struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_c
struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
u_int8_t tsc, u_int8_t bsic);
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
-void gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
+int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);
diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am
index 7d7fee79e..aa50b8cbc 100644
--- a/openbsc/src/Makefile.am
+++ b/openbsc/src/Makefile.am
@@ -12,7 +12,7 @@ libbsc_a_SOURCES = abis_rsl.c abis_nm.c gsm_data.c gsm_04_08_utils.c \
trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c tlv_parser.c \
input/misdn.c input/ipaccess.c signal.c gsm_utils.c talloc.c \
talloc_ctx.c system_information.c bitvec.c rest_octets.c \
- rtp_proxy.c statistics.c
+ rtp_proxy.c statistics.c bts_siemens_bs11.c bts_ipaccess_nanobts.c
libmsc_a_SOURCES = gsm_subscriber.c db.c telnet_interface.c \
mncc.c gsm_04_08.c gsm_04_11.c transaction.c \
@@ -27,7 +27,8 @@ bsc_hack_SOURCES = bsc_hack.c bsc_init.c vty_interface.c vty_interface_layer3.c
bsc_hack_LDADD = libmsc.a libbsc.a libmsc.a libvty.a -ldl -ldbi $(LIBCRYPT)
bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c msgb.c debug.c \
- select.c timer.c rs232.c tlv_parser.c signal.c talloc.c
+ select.c timer.c rs232.c tlv_parser.c signal.c talloc.c \
+ bts_siemens_bs11.c
ipaccess_find_SOURCES = ipaccess/ipaccess-find.c select.c timer.c
diff --git a/openbsc/src/abis_nm.c b/openbsc/src/abis_nm.c
index aaa7dd5fb..82d7b0254 100644
--- a/openbsc/src/abis_nm.c
+++ b/openbsc/src/abis_nm.c
@@ -264,7 +264,7 @@ static const enum abis_nm_attr nm_att_settable[] = {
NM_ATT_MEAS_TYPE,
};
-static const struct tlv_definition nm_att_tlvdef = {
+const struct tlv_definition nm_att_tlvdef = {
.def = {
[NM_ATT_ABIS_CHANNEL] = { TLV_TYPE_FIXED, 3 },
[NM_ATT_ADD_INFO] = { TLV_TYPE_TL16V },
@@ -330,77 +330,6 @@ static const struct tlv_definition nm_att_tlvdef = {
[NM_ATT_HW_CONF_CHG] = { TLV_TYPE_TL16V },
[NM_ATT_OUTST_ALARM] = { TLV_TYPE_TV },
[NM_ATT_MEAS_RES] = { TLV_TYPE_TL16V },
- /* BS11 specifics */
- [NM_ATT_BS11_ESN_FW_CODE_NO] = { TLV_TYPE_TLV },
- [NM_ATT_BS11_ESN_HW_CODE_NO] = { TLV_TYPE_TLV },
- [NM_ATT_BS11_ESN_PCB_SERIAL] = { TLV_TYPE_TLV },
- [NM_ATT_BS11_BOOT_SW_VERS] = { TLV_TYPE_TLV },
- [0xd5] = { TLV_TYPE_TLV },
- [0xa8] = { TLV_TYPE_TLV },
- [NM_ATT_BS11_PASSWORD] = { TLV_TYPE_TLV },
- [NM_ATT_BS11_TXPWR] = { TLV_TYPE_TLV },
- [NM_ATT_BS11_RSSI_OFFS] = { TLV_TYPE_TLV },
- [NM_ATT_BS11_LINE_CFG] = { TLV_TYPE_TV },
- [NM_ATT_BS11_L1_PROT_TYPE] = { TLV_TYPE_TV },
- [NM_ATT_BS11_BIT_ERR_THESH] = { TLV_TYPE_FIXED, 2 },
- [NM_ATT_BS11_DIVERSITY] = { TLV_TYPE_TLV },
- [NM_ATT_BS11_LMT_LOGON_SESSION]={ TLV_TYPE_TLV },
- [NM_ATT_BS11_LMT_LOGIN_TIME] = { TLV_TYPE_TLV },
- [NM_ATT_BS11_LMT_USER_ACC_LEV] ={ TLV_TYPE_TLV },
- [NM_ATT_BS11_LMT_USER_NAME] = { TLV_TYPE_TLV },
- [NM_ATT_BS11_BTS_STATE] = { TLV_TYPE_TLV },
- [NM_ATT_BS11_E1_STATE] = { TLV_TYPE_TLV },
- [NM_ATT_BS11_PLL_MODE] = { TLV_TYPE_TLV },
- [NM_ATT_BS11_PLL] = { TLV_TYPE_TLV },
- [NM_ATT_BS11_CCLK_ACCURACY] = { TLV_TYPE_TV },
- [NM_ATT_BS11_CCLK_TYPE] = { TLV_TYPE_TV },
- /* ip.access specifics */
- [NM_ATT_IPACC_DST_IP] = { TLV_TYPE_FIXED, 4 },
- [NM_ATT_IPACC_DST_IP_PORT] = { TLV_TYPE_FIXED, 2 },
- [NM_ATT_IPACC_STREAM_ID] = { TLV_TYPE_TV, },
- [NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_TV, },
- [NM_ATT_IPACC_SEC_OML_CFG] = { TLV_TYPE_FIXED, 6 },
- [NM_ATT_IPACC_IP_IF_CFG] = { TLV_TYPE_FIXED, 8 },
- [NM_ATT_IPACC_IP_GW_CFG] = { TLV_TYPE_FIXED, 12 },
- [NM_ATT_IPACC_IN_SERV_TIME] = { TLV_TYPE_FIXED, 4 },
- [NM_ATT_IPACC_LOCATION] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_PAGING_CFG] = { TLV_TYPE_FIXED, 2 },
- [NM_ATT_IPACC_UNIT_ID] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_UNIT_NAME] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_SNMP_CFG] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_PRIM_OML_CFG_LIST] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_NV_FLAGS] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_FIXED, 2 },
- [NM_ATT_IPACC_PRIM_OML_FB_TOUT] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_CUR_SW_CFG] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_TIMING_BUS] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_CGI] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_RAC] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_OBJ_VERSION] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_GPRS_PAGING_CFG]= { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_NSEI] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_BVCI] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_NSVCI] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_NS_CFG] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_BSSGP_CFG] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_NS_LINK_CFG] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_RLC_CFG] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_ALM_THRESH_LIST]= { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_MONIT_VAL_LIST] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_TIB_CONTROL] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_SUPP_FEATURES] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_CODING_SCHEMES] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_RLC_CFG_2] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_HEARTB_TOUT] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_UPTIME] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_RLC_CFG_3] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_SSL_CFG] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_SEC_POSSIBLE] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_IML_SSL_STATE] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_REVOC_DATE] = { TLV_TYPE_TL16V },
- //[0x95] = { TLV_TYPE_FIXED, 2 },
- [0x85] = { TLV_TYPE_TV },
-
},
};
@@ -423,9 +352,11 @@ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan)
return -EINVAL;
}
-int abis_nm_tlv_parse(struct tlv_parsed *tp, const u_int8_t *buf, int len)
+int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const u_int8_t *buf, int len)
{
- return tlv_parse(tp, &nm_att_tlvdef, buf, len, 0, 0);
+ if (!bts->model)
+ return -EIO;
+ return tlv_parse(tp, &bts->model->nm_att_tlvdef, buf, len, 0, 0);
}
static int is_in_arr(enum abis_nm_msgtype mt, const enum abis_nm_msgtype *arr, int size)
@@ -801,7 +732,7 @@ static int abis_nm_rx_statechg_rep(struct msgb *mb)
new_state = *nm_state;
- abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
+ abis_nm_tlv_parse(&tp, bts, foh->data, oh->length-sizeof(*foh));
if (TLVP_PRESENT(&tp, NM_ATT_OPER_STATE)) {
new_state.operational = *TLVP_VAL(&tp, NM_ATT_OPER_STATE);
DEBUGPC(DNM, "OP_STATE=%s ", nm_opstate_name(new_state.operational));
@@ -853,7 +784,7 @@ static int rx_fail_evt_rep(struct msgb *mb)
DEBUGPC(DNM, "Failure Event Report ");
- abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
+ abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
if (TLVP_PRESENT(&tp, NM_ATT_EVENT_TYPE))
DEBUGPC(DNM, "Type=%s ", event_type_name(*TLVP_VAL(&tp, NM_ATT_EVENT_TYPE)));
@@ -947,7 +878,7 @@ static int abis_nm_rx_sw_act_req(struct msgb *mb)
if (nack)
return ret;
- abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
+ abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
sw_config = TLVP_VAL(&tp, NM_ATT_SW_CONFIG);
sw_config_len = TLVP_LEN(&tp, NM_ATT_SW_CONFIG);
if (!TLVP_PRESENT(&tp, NM_ATT_SW_CONFIG)) {
@@ -981,7 +912,7 @@ static int abis_nm_rx_chg_adm_state_ack(struct msgb *mb)
struct tlv_parsed tp;
u_int8_t adm_state;
- abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
+ abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
if (!TLVP_PRESENT(&tp, NM_ATT_ADM_STATE))
return -EINVAL;
@@ -997,7 +928,7 @@ static int abis_nm_rx_lmt_event(struct msgb *mb)
struct tlv_parsed tp;
DEBUGP(DNM, "LMT Event ");
- abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
+ abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
if (TLVP_PRESENT(&tp, NM_ATT_BS11_LMT_LOGON_SESSION) &&
TLVP_LEN(&tp, NM_ATT_BS11_LMT_LOGON_SESSION) >= 1) {
u_int8_t onoff = *TLVP_VAL(&tp, NM_ATT_BS11_LMT_LOGON_SESSION);
@@ -1043,7 +974,7 @@ static int abis_nm_rcvmsg_fom(struct msgb *mb)
else
DEBUGPC(DNM, "NACK 0x%02x ", mt);
- abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
+ abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
if (TLVP_PRESENT(&tp, NM_ATT_NACK_CAUSES))
DEBUGPC(DNM, "CAUSE=%s\n",
nack_cause_name(*TLVP_VAL(&tp, NM_ATT_NACK_CAUSES)));
@@ -2770,7 +2701,7 @@ static int abis_nm_rx_ipacc(struct msgb *msg)
}
foh = (struct abis_om_fom_hdr *) (oh->data + 1 + idstrlen);
- abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
+ abis_nm_tlv_parse(&tp, msg->trx->bts, foh->data, oh->length-sizeof(*foh));
debugp_foh(foh);
diff --git a/openbsc/src/bs11_config.c b/openbsc/src/bs11_config.c
index 6a76b962d..703591eed 100644
--- a/openbsc/src/bs11_config.c
+++ b/openbsc/src/bs11_config.c
@@ -649,7 +649,7 @@ int handle_serial_msg(struct msgb *rx_msg)
exit(0);
break;
case NM_MT_BS11_GET_STATE_ACK:
- rc = abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
+ rc = abis_nm_tlv_parse(&tp, g_bts, foh->data, oh->length-sizeof(*foh));
print_state(&tp);
if (TLVP_PRESENT(&tp, NM_ATT_BS11_BTS_STATE) &&
TLVP_LEN(&tp, NM_ATT_BS11_BTS_STATE) >= 1)
@@ -657,7 +657,7 @@ int handle_serial_msg(struct msgb *rx_msg)
break;
case NM_MT_GET_ATTR_RESP:
printf("\n%sATTRIBUTES:\n", obj_name(foh));
- abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
+ abis_nm_tlv_parse(&tp, g_bts, foh->data, oh->length-sizeof(*foh));
rc = print_attr(&tp);
//hexdump(foh->data, oh->length-sizeof(*foh));
break;
@@ -839,6 +839,7 @@ int main(int argc, char **argv)
debug_add_target(stderr_target);
debug_set_all_filter(stderr_target, 1);
handle_options(argc, argv);
+ bts_model_bs11_init();
gsmnet = gsm_network_init(1, 1, NULL);
if (!gsmnet) {
diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c
index 3122fae9c..581e9be4d 100644
--- a/openbsc/src/bsc_hack.c
+++ b/openbsc/src/bsc_hack.c
@@ -178,6 +178,9 @@ static void db_sync_timer_cb(void *data)
bsc_schedule_timer(&db_sync_timer, DB_SYNC_INTERVAL);
}
+extern int bts_model_bs11_init(void);
+extern int bts_model_nanobts_init(void);
+
int main(int argc, char **argv)
{
int rc;
@@ -191,6 +194,9 @@ int main(int argc, char **argv)
stderr_target = debug_target_create_stderr();
debug_add_target(stderr_target);
+ bts_model_bs11_init();
+ bts_model_nanobts_init();
+
/* enable filters */
debug_set_all_filter(stderr_target, 1);
diff --git a/openbsc/src/bts_ipaccess_nanobts.c b/openbsc/src/bts_ipaccess_nanobts.c
new file mode 100644
index 000000000..6765517b3
--- /dev/null
+++ b/openbsc/src/bts_ipaccess_nanobts.c
@@ -0,0 +1,84 @@
+/* ip.access nanoBTS specific code */
+
+/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <sys/types.h>
+
+#include <openbsc/gsm_data.h>
+#include <openbsc/tlv.h>
+#include <openbsc/abis_nm.h>
+
+static struct gsm_bts_model model_nanobts = {
+ .type = GSM_BTS_TYPE_NANOBTS,
+ .nm_att_tlvdef = {
+ .def = {
+ /* ip.access specifics */
+ [NM_ATT_IPACC_DST_IP] = { TLV_TYPE_FIXED, 4 },
+ [NM_ATT_IPACC_DST_IP_PORT] = { TLV_TYPE_FIXED, 2 },
+ [NM_ATT_IPACC_STREAM_ID] = { TLV_TYPE_TV, },
+ [NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_TV, },
+ [NM_ATT_IPACC_SEC_OML_CFG] = { TLV_TYPE_FIXED, 6 },
+ [NM_ATT_IPACC_IP_IF_CFG] = { TLV_TYPE_FIXED, 8 },
+ [NM_ATT_IPACC_IP_GW_CFG] = { TLV_TYPE_FIXED, 12 },
+ [NM_ATT_IPACC_IN_SERV_TIME] = { TLV_TYPE_FIXED, 4 },
+ [NM_ATT_IPACC_LOCATION] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_PAGING_CFG] = { TLV_TYPE_FIXED, 2 },
+ [NM_ATT_IPACC_UNIT_ID] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_UNIT_NAME] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_SNMP_CFG] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_PRIM_OML_CFG_LIST] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_NV_FLAGS] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_FIXED, 2 },
+ [NM_ATT_IPACC_PRIM_OML_FB_TOUT] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_CUR_SW_CFG] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_TIMING_BUS] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_CGI] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_RAC] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_OBJ_VERSION] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_GPRS_PAGING_CFG]= { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_NSEI] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_BVCI] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_NSVCI] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_NS_CFG] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_BSSGP_CFG] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_NS_LINK_CFG] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_RLC_CFG] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_ALM_THRESH_LIST]= { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_MONIT_VAL_LIST] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_TIB_CONTROL] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_SUPP_FEATURES] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_CODING_SCHEMES] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_RLC_CFG_2] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_HEARTB_TOUT] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_UPTIME] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_RLC_CFG_3] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_SSL_CFG] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_SEC_POSSIBLE] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_IML_SSL_STATE] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_REVOC_DATE] = { TLV_TYPE_TL16V },
+ },
+ },
+};
+
+int bts_model_nanobts_init(void)
+{
+ return gsm_bts_model_register(&model_nanobts);
+}
diff --git a/openbsc/src/bts_siemens_bs11.c b/openbsc/src/bts_siemens_bs11.c
new file mode 100644
index 000000000..1c8f889e1
--- /dev/null
+++ b/openbsc/src/bts_siemens_bs11.c
@@ -0,0 +1,66 @@
+/* Siemens BS-11 specific code */
+
+/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <sys/types.h>
+
+#include <openbsc/gsm_data.h>
+#include <openbsc/tlv.h>
+#include <openbsc/abis_nm.h>
+
+static struct gsm_bts_model model_bs11 = {
+ .type = GSM_BTS_TYPE_BS11,
+ .nm_att_tlvdef = {
+ .def = {
+ [NM_ATT_AVAIL_STATUS] = { TLV_TYPE_TLV },
+ /* BS11 specifics */
+ [NM_ATT_BS11_ESN_FW_CODE_NO] = { TLV_TYPE_TLV },
+ [NM_ATT_BS11_ESN_HW_CODE_NO] = { TLV_TYPE_TLV },
+ [NM_ATT_BS11_ESN_PCB_SERIAL] = { TLV_TYPE_TLV },
+ [NM_ATT_BS11_BOOT_SW_VERS] = { TLV_TYPE_TLV },
+ [0xd5] = { TLV_TYPE_TLV },
+ [0xa8] = { TLV_TYPE_TLV },
+ [NM_ATT_BS11_PASSWORD] = { TLV_TYPE_TLV },
+ [NM_ATT_BS11_TXPWR] = { TLV_TYPE_TLV },
+ [NM_ATT_BS11_RSSI_OFFS] = { TLV_TYPE_TLV },
+ [NM_ATT_BS11_LINE_CFG] = { TLV_TYPE_TV },
+ [NM_ATT_BS11_L1_PROT_TYPE] = { TLV_TYPE_TV },
+ [NM_ATT_BS11_BIT_ERR_THESH] = { TLV_TYPE_FIXED, 2 },
+ [NM_ATT_BS11_DIVERSITY] = { TLV_TYPE_TLV },
+ [NM_ATT_BS11_LMT_LOGON_SESSION]={ TLV_TYPE_TLV },
+ [NM_ATT_BS11_LMT_LOGIN_TIME] = { TLV_TYPE_TLV },
+ [NM_ATT_BS11_LMT_USER_ACC_LEV] ={ TLV_TYPE_TLV },
+ [NM_ATT_BS11_LMT_USER_NAME] = { TLV_TYPE_TLV },
+ [NM_ATT_BS11_BTS_STATE] = { TLV_TYPE_TLV },
+ [NM_ATT_BS11_E1_STATE] = { TLV_TYPE_TLV },
+ [NM_ATT_BS11_PLL_MODE] = { TLV_TYPE_TLV },
+ [NM_ATT_BS11_PLL] = { TLV_TYPE_TLV },
+ [NM_ATT_BS11_CCLK_ACCURACY] = { TLV_TYPE_TV },
+ [NM_ATT_BS11_CCLK_TYPE] = { TLV_TYPE_TV },
+ [0x95] = { TLV_TYPE_FIXED, 2 },
+ },
+ },
+};
+
+int bts_model_bs11_init(void)
+{
+ return gsm_bts_model_register(&model_bs11);
+}
diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c
index d2676db1b..694ae06c6 100644
--- a/openbsc/src/gsm_data.c
+++ b/openbsc/src/gsm_data.c
@@ -32,6 +32,8 @@
void *tall_bsc_ctx;
+static LLIST_HEAD(bts_models);
+
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)
{
@@ -118,6 +120,29 @@ const char *gsm_chreq_name(enum gsm_chreq_reason_t c)
return chreq_names[c];
}
+static struct gsm_bts_model *bts_model_find(enum gsm_bts_type type)
+{
+ struct gsm_bts_model *model;
+
+ llist_for_each_entry(model, &bts_models, list) {
+ if (model->type == type)
+ return model;
+ }
+
+ return NULL;
+}
+
+int gsm_bts_model_register(struct gsm_bts_model *model)
+{
+ if (bts_model_find(model->type))
+ return -EEXIST;
+
+ tlv_def_patch(&model->nm_att_tlvdef, &nm_att_tlvdef);
+ llist_add_tail(&model->list, &bts_models);
+ return 0;
+}
+
+
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
{
struct gsm_bts_trx *trx = talloc_zero(bts, struct gsm_bts_trx);
@@ -160,14 +185,21 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
u_int8_t tsc, u_int8_t bsic)
{
struct gsm_bts *bts = talloc_zero(net, struct gsm_bts);
+ struct gsm_bts_model *model = bts_model_find(type);
int i;
if (!bts)
return NULL;
+ if (!model) {
+ talloc_free(bts);
+ return NULL;
+ }
+
bts->network = net;
bts->nr = net->num_bts++;
bts->type = type;
+ bts->model = model;
bts->tsc = tsc;
bts->bsic = bsic;
bts->num_trx = 0;
@@ -504,9 +536,16 @@ struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan)
return meas_rep;
}
-void gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type)
+int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type)
{
+ struct gsm_bts_model *model;
+
+ model = bts_model_find(type);
+ if (!model)
+ return -EINVAL;
+
bts->type = type;
+ bts->model = model;
switch (bts->type) {
case GSM_BTS_TYPE_NANOBTS:
@@ -517,4 +556,6 @@ void gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type)
case GSM_BTS_TYPE_BS11:
break;
}
+
+ return 0;
}
diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c
index 8d6e202c1..265444779 100644
--- a/openbsc/src/vty_interface.c
+++ b/openbsc/src/vty_interface.c
@@ -1339,8 +1339,11 @@ DEFUN(cfg_bts_type,
"Set the BTS type\n")
{
struct gsm_bts *bts = vty->index;
+ int rc;
- gsm_set_bts_type(bts, parse_btstype(argv[0]));
+ rc = gsm_set_bts_type(bts, parse_btstype(argv[0]));
+ if (rc < 0)
+ return CMD_WARNING;
return CMD_SUCCESS;
}