diff options
Diffstat (limited to 'src/ipaccess/ipaccess-config.c')
-rw-r--r-- | src/ipaccess/ipaccess-config.c | 162 |
1 files changed, 121 insertions, 41 deletions
diff --git a/src/ipaccess/ipaccess-config.c b/src/ipaccess/ipaccess-config.c index c9264d723..3df9f61cb 100644 --- a/src/ipaccess/ipaccess-config.c +++ b/src/ipaccess/ipaccess-config.c @@ -58,8 +58,6 @@ #include <osmocom/bsc/bss.h> #include <osmocom/bsc/bts.h> -struct gsm_network *bsc_gsmnet; - static int net_listen_testnr; static int restart; static bool get_attr; @@ -131,7 +129,7 @@ static int ia_config_connect(struct gsm_bts *bts, struct sockaddr_in *sin) { struct e1inp_line *line; struct e1inp_ts *sign_ts, *rsl_ts; - struct e1inp_sign_link *oml_link, *rsl_link; + struct e1inp_sign_link *oml_link, *osmo_link, *rsl_link; line = talloc_zero(tall_bsc_ctx, struct e1inp_line); if (!line) @@ -142,23 +140,29 @@ static int ia_config_connect(struct gsm_bts *bts, struct sockaddr_in *sin) fprintf(stderr, "cannot `ipa' driver, giving up.\n"); return -EINVAL; } - line->ops = &ipaccess_e1inp_line_ops; + e1inp_line_bind_ops(line, &ipaccess_e1inp_line_ops); + e1_set_pcap_fd2(line, -1); /* Disable writing to pcap */ + + sign_ts = e1inp_line_ipa_oml_ts(line); + rsl_ts = e1inp_line_ipa_rsl_ts(line, 0); /* create E1 timeslots for signalling and TRAU frames */ - e1inp_ts_config_sign(&line->ts[1-1], line); - e1inp_ts_config_sign(&line->ts[2-1], line); + e1inp_ts_config_sign(sign_ts, line); + e1inp_ts_config_sign(rsl_ts, line); + rsl_ts->driver.ipaccess.fd.fd = -1; - /* create signalling links for TS1 */ - sign_ts = &line->ts[1-1]; - rsl_ts = &line->ts[2-1]; + /* create signalling links for TRX0 */ oml_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OML, - bts->c0, 0xff, 0); + bts->c0, IPAC_PROTO_OML, 0); + osmo_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OSMO, + bts->c0, IPAC_PROTO_OSMO, 0); rsl_link = e1inp_sign_link_create(rsl_ts, E1INP_SIGN_RSL, - bts->c0, 0, 0); + bts->c0, IPAC_PROTO_RSL, 0); /* create back-links from bts/trx */ bts->oml_link = oml_link; - bts->c0->rsl_link = rsl_link; + bts->osmo_link = osmo_link; + bts->c0->rsl_link_primary = rsl_link; /* default port at BTS for incoming connections is 3006 */ if (sin->sin_port == 0) @@ -192,6 +196,9 @@ static void check_restart_or_exit(struct gsm_bts_trx *trx) static int ipacc_msg_ack(uint8_t mt, struct gsm_bts_trx *trx) { + if (mt != NM_MT_IPACC_SET_NVATTR_ACK && mt != NM_MT_IPACC_SET_ATTR_ACK) + return 0; + if (sw_load_state == 1) { fprintf(stderr, "The new software is activated.\n"); check_restart_or_exit(trx); @@ -269,6 +276,8 @@ static int nwl_sig_cb(unsigned int subsys, unsigned int signal, return 0; } +static const struct value_string ipa_nvflag_strs[]; + static int print_attr_rep(struct msgb *mb) { /* Parse using nanoBTS own formatting for Get Attribute Response */ @@ -282,22 +291,67 @@ static int print_attr_rep(struct msgb *mb) char oml_ip[20] = {0}; uint16_t oml_port = 0; char unit_id[40] = {0}; + unsigned int indent = 0; - abis_nm_tlv_parse(&tp, bts, foh->data, oh->length-sizeof(*foh)); + if (abis_nm_tlv_parse(&tp, bts, foh->data, oh->length-sizeof(*foh)) < 0) { + LOGPFOH(DNM, LOGL_ERROR, foh, "%s(): tlv_parse failed\n", __func__); + return -EINVAL; + } abis_nm_tlv_attr_primary_oml(&tp, &ia, &oml_port); osmo_strlcpy(oml_ip, inet_ntoa(ia), sizeof(oml_ip)); abis_nm_tlv_attr_unit_id(&tp, unit_id, sizeof(unit_id)); - fprintf(stdout, "{ \"primary_oml_ip\": \"%s\", \"primary_oml_port\": %" PRIu16 ", \"unit_id\": \"%s\" }\n", - oml_ip, oml_port, unit_id); +#define ENDL(last) \ + fprintf(stdout, "%s\n", last ? "" : ",") +#define print_offset(fmt, args...) \ + fprintf(stdout, "%*s" fmt, indent * 4, "", ## args) +#define print_field(field, fmt, args...) \ + print_offset("\"%s\": \"" fmt "\"", field, ## args) + + print_offset("{\n"); + indent++; + + print_field("primary_oml_ip", "%s", oml_ip); ENDL(false); + print_field("primary_oml_port", "%u", oml_port); ENDL(false); + print_field("unit_id", "%s", unit_id); ENDL(false); + + uint16_t Fx = (TLVP_VAL(&tp, NM_ATT_IPACC_NV_FLAGS)[2] << 8) + | (TLVP_VAL(&tp, NM_ATT_IPACC_NV_FLAGS)[0] << 0); + uint16_t Mx = (TLVP_VAL(&tp, NM_ATT_IPACC_NV_FLAGS)[3] << 8) + | (TLVP_VAL(&tp, NM_ATT_IPACC_NV_FLAGS)[1] << 0); + const struct value_string *nvflag = ipa_nvflag_strs; + + print_offset("\"nv_flags\": {\n"); + indent++; + + while (nvflag->value && nvflag->str) { + const char *val = (Fx & nvflag->value) ? "yes" : "no"; + if (~Mx & nvflag->value) + val = "unknown"; + print_field(nvflag->str, "%s", val); + + nvflag++; + + if (nvflag->value && nvflag->str) + ENDL(false); /* more fields to print */ + else + ENDL(true); /* this was the last field */ + } + + indent--; + print_offset("}\n"); + + indent--; + print_offset("}\n"); + return 0; } static int nm_state_event(int evt, uint8_t obj_class, void *obj, - struct gsm_nm_state *old_state, struct gsm_nm_state *new_state, + const struct gsm_nm_state *old_state, const struct gsm_nm_state *new_state, struct abis_om_obj_inst *obj_inst); static int nm_sig_cb(unsigned int subsys, unsigned int signal, @@ -306,14 +360,23 @@ static int nm_sig_cb(unsigned int subsys, unsigned int signal, struct ipacc_ack_signal_data *ipacc_data; struct nm_statechg_signal_data *nsd; struct msgb *oml_msg; + struct gsm_bts_trx *trx; switch (signal) { case S_NM_IPACC_NACK: ipacc_data = signal_data; - return ipacc_msg_nack(ipacc_data->msg_type); + return ipacc_msg_nack(ipacc_data->foh->msg_type); case S_NM_IPACC_ACK: ipacc_data = signal_data; - return ipacc_msg_ack(ipacc_data->msg_type, ipacc_data->trx); + switch (ipacc_data->foh->obj_class) { + case NM_OC_BASEB_TRANSC: + case NM_OC_RADIO_CARRIER: + trx = gsm_bts_trx_num(ipacc_data->bts, + ipacc_data->foh->obj_inst.trx_nr); + return ipacc_msg_ack(ipacc_data->foh->msg_type, trx); + default: + return 0; + } case S_NM_IPACC_RESTART_ACK: if (!quiet) printf("The BTS has acked the restart. Exiting.\n"); @@ -324,11 +387,10 @@ static int nm_sig_cb(unsigned int subsys, unsigned int signal, printf("The BTS has nacked the restart. Exiting.\n"); exit(0); break; - case S_NM_STATECHG_OPER: - case S_NM_STATECHG_ADM: + case S_NM_STATECHG: nsd = signal_data; - nm_state_event(signal, nsd->obj_class, nsd->obj, nsd->old_state, - nsd->new_state, nsd->obj_inst); + nm_state_event(signal, nsd->obj_class, nsd->obj, &nsd->old_state, + &nsd->new_state, nsd->obj_inst); break; case S_NM_GET_ATTR_REP: fprintf(stderr, "Received SIGNAL S_NM_GET_ATTR_REP\n"); @@ -342,6 +404,32 @@ static int nm_sig_cb(unsigned int subsys, unsigned int signal, return 0; } +/* Callback function to be called every time we receive a signal from INPUT */ +static int inp_sig_cb(unsigned int subsys, unsigned int signal, + void *handler_data, void *signal_data) +{ + struct input_signal_data *isd = signal_data; + + if (subsys != SS_L_INPUT) + return -EINVAL; + + fprintf(stderr, "%s(): Input signal '%s' received\n", __func__, + get_value_string(e1inp_signal_names, signal)); + + switch (signal) { + case S_L_INP_TEI_UP: + break; + case S_L_INP_TEI_DN: + fprintf(stderr, "Lost E1 %s link\n", e1inp_signtype_name(isd->link_type)); + exit(1); + break; + default: + break; + } + + return 0; +} + /* callback function passed to the ABIS OML code */ static int percent; static int percent_old; @@ -502,7 +590,7 @@ static const struct value_string ipa_nvflag_strs[] = { { 0x0002, "static-gw" }, { 0x0004, "no-dhcp-vsi" }, { 0x0008, "dhcp-enabled" }, - { 0x0040, "led-disabled" }, + { 0x0040, "led-enabled" }, { 0x0100, "secondary-oml-enabled" }, { 0x0200, "diag-enabled" }, { 0x0400, "cli-enabled" }, @@ -517,8 +605,10 @@ static int ipa_nvflag_set(uint16_t *flags, uint16_t *mask, const char *name, int { int rc; rc = get_string_value(ipa_nvflag_strs, name); - if (rc < 0) + if (rc < 0) { + fprintf(stderr, "Unknown attribute '%s'\n", name); return rc; + } *mask |= rc; if (en) @@ -542,6 +632,7 @@ static void bootstrap_om(struct gsm_bts_trx *trx) if (get_attr) { msgb_put_u8(nmsg_get, NM_ATT_IPACC_PRIM_OML_CFG); msgb_put_u8(nmsg_get, NM_ATT_IPACC_UNIT_ID); + msgb_put_u8(nmsg_get, NM_ATT_IPACC_NV_FLAGS); } if (unit_id) { len = strlen(unit_id); @@ -632,7 +723,7 @@ out_err: } static int nm_state_event(int evt, uint8_t obj_class, void *obj, - struct gsm_nm_state *old_state, struct gsm_nm_state *new_state, + const struct gsm_nm_state *old_state, const struct gsm_nm_state *new_state, struct abis_om_obj_inst *obj_inst) { if (obj_class == NM_OC_BASEB_TRANSC) { @@ -641,9 +732,9 @@ static int nm_state_event(int evt, uint8_t obj_class, void *obj, bootstrap_om(trx); found_trx = 1; } - } else if (evt == S_NM_STATECHG_OPER && + } else if (evt == S_NM_STATECHG && obj_class == NM_OC_RADIO_CARRIER && - new_state->availability == 3) { + new_state->availability == NM_AVSTATE_OFF_LINE) { struct gsm_bts_trx *trx = obj; if (net_listen_testnr) @@ -926,7 +1017,7 @@ static const struct log_info_cat log_categories[] = { .name = "DNM", .description = "A-bis Network Management / O&M (NM/OML)", .color = "\033[1;36m", - .loglevel = LOGL_DEBUG, + .loglevel = LOGL_NOTICE, .enabled = 1, }, }; @@ -1104,6 +1195,7 @@ int main(int argc, char **argv) bts->oml_tei = stream_id; osmo_signal_register_handler(SS_NM, nm_sig_cb, NULL); + osmo_signal_register_handler(SS_L_INPUT, inp_sig_cb, NULL); osmo_signal_register_handler(SS_IPAC_NWL, nwl_sig_cb, NULL); ipac_nwl_init(); @@ -1121,7 +1213,7 @@ int main(int argc, char **argv) } bts->oml_link->ts->sign.delay = 10; - bts->c0->rsl_link->ts->sign.delay = 10; + bts->c0->rsl_link_primary->ts->sign.delay = 10; while (1) { rc = osmo_select_main(0); if (rc < 0) @@ -1130,15 +1222,3 @@ int main(int argc, char **argv) exit(0); } - -/* Stub */ -int osmo_bsc_sigtran_send(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ return 0; } -int osmo_bsc_sigtran_open_conn(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ return 0; } -int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan) { return 0; } -void pcu_info_update(struct gsm_bts *bts) {}; -int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type, const uint8_t *data, int len) { return 0; } -int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len) -{ return 0; } -int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type si_type) { return 0; } |