[OML] parse attributes depending on BTS type

Some NM attributes are defined differently depending on
the BTS type.  Having one big nm_att_tlvdef[] table for
all BTS types is no longer sufficient.  This patch

* introduces 'struct gsm_bts_model' to describe a BTS model
* adds definitions of gsm_bts_model for BS-11 and nanoBTS
* changes the abis_nm_tlv_parse() function: include a bts pointer
This commit is contained in:
Harald Welte 2010-01-10 18:01:52 +01:00
parent 5078148829
commit 39315c4798
10 changed files with 234 additions and 89 deletions

View File

@ -719,6 +719,8 @@ struct ipac_bcch_info {
u_int8_t ca_list_si1[16]; u_int8_t ca_list_si1[16];
}; };
extern const struct tlv_definition nm_att_tlvdef;
/* PUBLIC */ /* PUBLIC */
struct msgb; struct msgb;
@ -733,7 +735,7 @@ struct abis_nm_cfg {
extern int abis_nm_rcvmsg(struct msgb *msg); 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_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_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, int abis_nm_chg_adm_state(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0,

View File

@ -335,6 +335,15 @@ enum gsm_bts_type {
GSM_BTS_TYPE_NANOBTS, 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 * A pending paging request
*/ */
@ -402,6 +411,7 @@ struct gsm_bts {
u_int8_t bsic; u_int8_t bsic;
/* type of BTS */ /* type of BTS */
enum gsm_bts_type type; enum gsm_bts_type type;
struct gsm_bts_model *model;
enum gsm_band band; enum gsm_band band;
/* should the channel allocator allocate channels from high TRX to TRX0, /* should the channel allocator allocate channels from high TRX to TRX0,
* rather than starting from TRX0 and go upwards? */ * 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, struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
u_int8_t tsc, u_int8_t bsic); u_int8_t tsc, u_int8_t bsic);
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts); 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); struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);

View File

@ -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 \ 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 \ input/misdn.c input/ipaccess.c signal.c gsm_utils.c talloc.c \
talloc_ctx.c system_information.c bitvec.c rest_octets.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 \ libmsc_a_SOURCES = gsm_subscriber.c db.c telnet_interface.c \
mncc.c gsm_04_08.c gsm_04_11.c transaction.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) 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 \ 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 ipaccess_find_SOURCES = ipaccess/ipaccess-find.c select.c timer.c

View File

@ -264,7 +264,7 @@ static const enum abis_nm_attr nm_att_settable[] = {
NM_ATT_MEAS_TYPE, NM_ATT_MEAS_TYPE,
}; };
static const struct tlv_definition nm_att_tlvdef = { const struct tlv_definition nm_att_tlvdef = {
.def = { .def = {
[NM_ATT_ABIS_CHANNEL] = { TLV_TYPE_FIXED, 3 }, [NM_ATT_ABIS_CHANNEL] = { TLV_TYPE_FIXED, 3 },
[NM_ATT_ADD_INFO] = { TLV_TYPE_TL16V }, [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_HW_CONF_CHG] = { TLV_TYPE_TL16V },
[NM_ATT_OUTST_ALARM] = { TLV_TYPE_TV }, [NM_ATT_OUTST_ALARM] = { TLV_TYPE_TV },
[NM_ATT_MEAS_RES] = { TLV_TYPE_TL16V }, [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; 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) 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; 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)) { if (TLVP_PRESENT(&tp, NM_ATT_OPER_STATE)) {
new_state.operational = *TLVP_VAL(&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)); 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 "); 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)) if (TLVP_PRESENT(&tp, NM_ATT_EVENT_TYPE))
DEBUGPC(DNM, "Type=%s ", event_type_name(*TLVP_VAL(&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) if (nack)
return ret; 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 = TLVP_VAL(&tp, NM_ATT_SW_CONFIG);
sw_config_len = TLVP_LEN(&tp, NM_ATT_SW_CONFIG); sw_config_len = TLVP_LEN(&tp, NM_ATT_SW_CONFIG);
if (!TLVP_PRESENT(&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; struct tlv_parsed tp;
u_int8_t adm_state; 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)) if (!TLVP_PRESENT(&tp, NM_ATT_ADM_STATE))
return -EINVAL; return -EINVAL;
@ -997,7 +928,7 @@ static int abis_nm_rx_lmt_event(struct msgb *mb)
struct tlv_parsed tp; struct tlv_parsed tp;
DEBUGP(DNM, "LMT Event "); 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) && if (TLVP_PRESENT(&tp, NM_ATT_BS11_LMT_LOGON_SESSION) &&
TLVP_LEN(&tp, NM_ATT_BS11_LMT_LOGON_SESSION) >= 1) { TLVP_LEN(&tp, NM_ATT_BS11_LMT_LOGON_SESSION) >= 1) {
u_int8_t onoff = *TLVP_VAL(&tp, NM_ATT_BS11_LMT_LOGON_SESSION); 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 else
DEBUGPC(DNM, "NACK 0x%02x ", mt); 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)) if (TLVP_PRESENT(&tp, NM_ATT_NACK_CAUSES))
DEBUGPC(DNM, "CAUSE=%s\n", DEBUGPC(DNM, "CAUSE=%s\n",
nack_cause_name(*TLVP_VAL(&tp, NM_ATT_NACK_CAUSES))); 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); 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); debugp_foh(foh);

View File

@ -649,7 +649,7 @@ int handle_serial_msg(struct msgb *rx_msg)
exit(0); exit(0);
break; break;
case NM_MT_BS11_GET_STATE_ACK: 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); print_state(&tp);
if (TLVP_PRESENT(&tp, NM_ATT_BS11_BTS_STATE) && if (TLVP_PRESENT(&tp, NM_ATT_BS11_BTS_STATE) &&
TLVP_LEN(&tp, NM_ATT_BS11_BTS_STATE) >= 1) TLVP_LEN(&tp, NM_ATT_BS11_BTS_STATE) >= 1)
@ -657,7 +657,7 @@ int handle_serial_msg(struct msgb *rx_msg)
break; break;
case NM_MT_GET_ATTR_RESP: case NM_MT_GET_ATTR_RESP:
printf("\n%sATTRIBUTES:\n", obj_name(foh)); 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); rc = print_attr(&tp);
//hexdump(foh->data, oh->length-sizeof(*foh)); //hexdump(foh->data, oh->length-sizeof(*foh));
break; break;
@ -839,6 +839,7 @@ int main(int argc, char **argv)
debug_add_target(stderr_target); debug_add_target(stderr_target);
debug_set_all_filter(stderr_target, 1); debug_set_all_filter(stderr_target, 1);
handle_options(argc, argv); handle_options(argc, argv);
bts_model_bs11_init();
gsmnet = gsm_network_init(1, 1, NULL); gsmnet = gsm_network_init(1, 1, NULL);
if (!gsmnet) { if (!gsmnet) {

View File

@ -178,6 +178,9 @@ static void db_sync_timer_cb(void *data)
bsc_schedule_timer(&db_sync_timer, DB_SYNC_INTERVAL); 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 main(int argc, char **argv)
{ {
int rc; int rc;
@ -191,6 +194,9 @@ int main(int argc, char **argv)
stderr_target = debug_target_create_stderr(); stderr_target = debug_target_create_stderr();
debug_add_target(stderr_target); debug_add_target(stderr_target);
bts_model_bs11_init();
bts_model_nanobts_init();
/* enable filters */ /* enable filters */
debug_set_all_filter(stderr_target, 1); debug_set_all_filter(stderr_target, 1);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -32,6 +32,8 @@
void *tall_bsc_ctx; void *tall_bsc_ctx;
static LLIST_HEAD(bts_models);
void set_ts_e1link(struct gsm_bts_trx_ts *ts, u_int8_t e1_nr, 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) 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]; 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 *gsm_bts_trx_alloc(struct gsm_bts *bts)
{ {
struct gsm_bts_trx *trx = talloc_zero(bts, struct gsm_bts_trx); 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) u_int8_t tsc, u_int8_t bsic)
{ {
struct gsm_bts *bts = talloc_zero(net, struct gsm_bts); struct gsm_bts *bts = talloc_zero(net, struct gsm_bts);
struct gsm_bts_model *model = bts_model_find(type);
int i; int i;
if (!bts) if (!bts)
return NULL; return NULL;
if (!model) {
talloc_free(bts);
return NULL;
}
bts->network = net; bts->network = net;
bts->nr = net->num_bts++; bts->nr = net->num_bts++;
bts->type = type; bts->type = type;
bts->model = model;
bts->tsc = tsc; bts->tsc = tsc;
bts->bsic = bsic; bts->bsic = bsic;
bts->num_trx = 0; bts->num_trx = 0;
@ -504,9 +536,16 @@ struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan)
return meas_rep; 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->type = type;
bts->model = model;
switch (bts->type) { switch (bts->type) {
case GSM_BTS_TYPE_NANOBTS: 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: case GSM_BTS_TYPE_BS11:
break; break;
} }
return 0;
} }

View File

@ -1339,8 +1339,11 @@ DEFUN(cfg_bts_type,
"Set the BTS type\n") "Set the BTS type\n")
{ {
struct gsm_bts *bts = vty->index; 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; return CMD_SUCCESS;
} }