summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/abis_nm.h3
-rw-r--r--openbsc/include/openbsc/gsm_data.h3
-rw-r--r--openbsc/include/openbsc/network_listen.h3
-rw-r--r--openbsc/src/abis_nm.c24
-rw-r--r--openbsc/src/ipaccess/ipaccess-config.c11
-rw-r--r--openbsc/src/ipaccess/network_listen.c57
6 files changed, 73 insertions, 28 deletions
diff --git a/openbsc/include/openbsc/abis_nm.h b/openbsc/include/openbsc/abis_nm.h
index 13c074686..7672bb17c 100644
--- a/openbsc/include/openbsc/abis_nm.h
+++ b/openbsc/include/openbsc/abis_nm.h
@@ -106,8 +106,7 @@ int abis_nm_conn_mdrop_link(struct gsm_bts *bts, u_int8_t e1_port0, u_int8_t ts0
int abis_nm_perform_test(struct gsm_bts *bts, u_int8_t obj_class,
u_int8_t bts_nr, u_int8_t trx_nr, u_int8_t ts_nr,
- u_int8_t test_nr, u_int8_t auton_report,
- const u_int8_t *phys_config, u_int16_t phys_config_len);
+ u_int8_t test_nr, u_int8_t auton_report, struct msgb *msg);
int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan);
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 5ec4441be..09e0a2105 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -45,11 +45,13 @@ enum gsm_chreq_reason_t {
#include <openbsc/abis_rsl.h>
#include <openbsc/system_information.h>
#include <openbsc/mncc.h>
+
#include <osmocore/tlv.h>
#include <osmocore/bitvec.h>
#include <osmocore/statistics.h>
#include <osmocore/gsm_utils.h>
#include <osmocore/utils.h>
+#include <osmocore/rxlev_stat.h>
#define TRX_NR_TS 8
#define TS_MAX_LCHAN 8
@@ -381,6 +383,7 @@ struct gsm_bts_trx {
} bs11;
struct {
unsigned int test_state;
+ struct rxlev_stats rxlev_stat;
} ipaccess;
};
struct gsm_bts_trx_ts ts[TRX_NR_TS];
diff --git a/openbsc/include/openbsc/network_listen.h b/openbsc/include/openbsc/network_listen.h
index afd0049b7..8ca5cd8d4 100644
--- a/openbsc/include/openbsc/network_listen.h
+++ b/openbsc/include/openbsc/network_listen.h
@@ -7,6 +7,7 @@
void ipac_nwl_init(void);
/* Start a NWL test. It will raise the S_IPAC_TEST_COMPLETE signal. */
-int ipac_nwl_test_start(struct gsm_bts_trx *trx, uint8_t testnr);
+int ipac_nwl_test_start(struct gsm_bts_trx *trx, uint8_t testnr,
+ const uint8_t *phys_conf, unsigned int phys_conf_len);
#endif /* _OPENBSC_NWL_H */
diff --git a/openbsc/src/abis_nm.c b/openbsc/src/abis_nm.c
index f7fac6325..58f47d2d5 100644
--- a/openbsc/src/abis_nm.c
+++ b/openbsc/src/abis_nm.c
@@ -2120,26 +2120,20 @@ int abis_nm_conn_mdrop_link(struct gsm_bts *bts, u_int8_t e1_port0, u_int8_t ts0
/* Chapter 8.7.1 */
int abis_nm_perform_test(struct gsm_bts *bts, u_int8_t obj_class,
u_int8_t bts_nr, u_int8_t trx_nr, u_int8_t ts_nr,
- u_int8_t test_nr, u_int8_t auton_report,
- const u_int8_t *phys_config, u_int16_t phys_config_len)
+ u_int8_t test_nr, u_int8_t auton_report, struct msgb *msg)
{
struct abis_om_hdr *oh;
- struct msgb *msg = nm_msgb_alloc();
- int len = 4; /* 2 TV attributes */
DEBUGP(DNM, "PEFORM TEST\n");
-
- if (phys_config_len)
- len += 3 + phys_config_len;
-
- oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
- fill_om_fom_hdr(oh, len, NM_MT_PERF_TEST,
+
+ if (!msg)
+ msg = nm_msgb_alloc();
+
+ msgb_tv_push(msg, NM_ATT_AUTON_REPORT, auton_report);
+ msgb_tv_push(msg, NM_ATT_TEST_NO, test_nr);
+ oh = (struct abis_om_hdr *) msgb_push(msg, ABIS_OM_FOM_HDR_SIZE);
+ fill_om_fom_hdr(oh, msgb_l3len(msg), NM_MT_PERF_TEST,
obj_class, bts_nr, trx_nr, ts_nr);
- msgb_tv_put(msg, NM_ATT_TEST_NO, test_nr);
- msgb_tv_put(msg, NM_ATT_AUTON_REPORT, auton_report);
- if (phys_config_len)
- msgb_tl16v_put(msg, NM_ATT_PHYS_CONF, phys_config_len,
- phys_config);
return abis_nm_sendmsg(bts, msg);
}
diff --git a/openbsc/src/ipaccess/ipaccess-config.c b/openbsc/src/ipaccess/ipaccess-config.c
index 72bccf918..9b3cb8d6f 100644
--- a/openbsc/src/ipaccess/ipaccess-config.c
+++ b/openbsc/src/ipaccess/ipaccess-config.c
@@ -116,6 +116,8 @@ static int ipacc_msg_ack(u_int8_t mt, struct gsm_bts_trx *trx)
return 0;
}
+const uint8_t phys_conf[] = { 0x02, 0x0a, 0x00, 0x01, 0x02 };
+
static int nwl_sig_cb(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
@@ -124,7 +126,11 @@ static int nwl_sig_cb(unsigned int subsys, unsigned int signal,
switch (signal) {
case S_IPAC_NWL_COMPLETE:
trx = signal_data;
- ipac_nwl_test_start(trx, net_listen_testnr);
+ DEBUGP(DNM, "received S_IPAC_NWL_COMPLETE signal\n");
+ rxlev_stat_dump(&trx->ipaccess.rxlev_stat);
+ DEBUGP(DNM, "starting next test\n");
+ ipac_nwl_test_start(trx, net_listen_testnr, phys_conf,
+ sizeof(phys_conf));
break;
}
return 0;
@@ -441,7 +447,8 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
struct gsm_bts_trx *trx = obj;
if (net_listen_testnr)
- ipac_nwl_test_start(trx, net_listen_testnr);
+ ipac_nwl_test_start(trx, net_listen_testnr, phys_conf,
+ sizeof(phys_conf));
else if (software) {
int rc;
printf("Attempting software upload with '%s'\n", software);
diff --git a/openbsc/src/ipaccess/network_listen.c b/openbsc/src/ipaccess/network_listen.c
index f64f44ec1..87bf588f8 100644
--- a/openbsc/src/ipaccess/network_listen.c
+++ b/openbsc/src/ipaccess/network_listen.c
@@ -27,14 +27,36 @@
#include <errno.h>
#include <stdint.h>
+#include <arpa/inet.h>
+
#include <osmocore/talloc.h>
#include <osmocore/timer.h>
+#include <osmocore/rxlev_stat.h>
#include <openbsc/gsm_data.h>
#include <openbsc/abis_nm.h>
#include <openbsc/signal.h>
#include <openbsc/debug.h>
+#define WHITELIST_MAX_SIZE ((NUM_ARFCNS*2)+2+1)
+
+int ipac_rxlevstat2whitelist(uint16_t *buf, const struct rxlev_stats *st)
+{
+ int i;
+ unsigned int num_arfcn = 0;
+
+ for (i = NUM_RXLEVS-1; i >= 0; i--) {
+ int16_t arfcn = -1;
+
+ while ((arfcn = rxlev_stat_get_next(st, i, arfcn)) >= 0) {
+ *buf++ = htons(arfcn);
+ num_arfcn++;
+ }
+ }
+
+ return num_arfcn;
+}
+
enum ipac_test_state {
IPAC_TEST_S_IDLE,
IPAC_TEST_S_RQD,
@@ -42,17 +64,34 @@ enum ipac_test_state {
IPAC_TEST_S_PARTIAL,
};
-int ipac_nwl_test_start(struct gsm_bts_trx *trx, uint8_t testnr)
+int ipac_nwl_test_start(struct gsm_bts_trx *trx, uint8_t testnr,
+ const uint8_t *phys_conf, unsigned int phys_conf_len)
{
- const uint8_t phys_config[] = { 0x02, 0x0a, 0x00, 0x01, 0x02 };
+ struct msgb *msg;
if (trx->ipaccess.test_state != IPAC_TEST_S_IDLE) {
fprintf(stderr, "Cannot start test in state %u\n", trx->ipaccess.test_state);
return -EINVAL;
}
- abis_nm_perform_test(trx->bts, 2, 0, trx->nr, 0xff, testnr, 1,
- phys_config, sizeof(phys_config));
+ switch (testnr) {
+ case NM_IPACC_TESTNO_CHAN_USAGE:
+ rxlev_stat_reset(&trx->ipaccess.rxlev_stat);
+ break;
+ }
+
+ msg = msgb_alloc_headroom(phys_conf_len+256, 128, "OML");
+
+ if (phys_conf && phys_conf_len) {
+ uint8_t *payload;
+ /* first put the phys conf header */
+ msgb_tv16_put(msg, NM_ATT_PHYS_CONF, phys_conf_len);
+ payload = msgb_put(msg, phys_conf_len);
+ memcpy(payload, phys_conf, phys_conf_len);
+ }
+
+ abis_nm_perform_test(trx->bts, NM_OC_RADIO_CARRIER, 0, trx->nr, 0xff,
+ testnr, 1, msg);
/* FIXME: start safety timer until when test is supposed to complete */
@@ -113,8 +152,11 @@ static int test_rep(void *_msg)
for (i = 0; i < ferr_list_len; i+= 2) {
uint16_t *cu_ptr = (uint16_t *)(foh->data + 9 + i);
uint16_t cu = ntohs(*cu_ptr);
- DEBUGP(DNM, "==> ARFCN %4u, RxLev %2u\n",
- cu & 0x3ff, cu >> 10);
+ uint16_t arfcn = cu & 0x3ff;
+ uint8_t rxlev = cu >> 10;
+ DEBUGP(DNM, "==> ARFCN %4u, RxLev %2u\n", arfcn, rxlev);
+ rxlev_stat_input(&msg->trx->ipaccess.rxlev_stat,
+ arfcn, rxlev);
}
break;
case NM_IPAC_EIE_BCCH_INFO_TYPE:
@@ -141,6 +183,7 @@ static int test_rep(void *_msg)
case NM_IPACC_TESTRES_NO_CHANS:
msg->trx->ipaccess.test_state = IPAC_TEST_S_IDLE;
/* Send signal to notify higher layers of test completion */
+ DEBUGP(DNM, "dispatching S_IPAC_NWL_COMPLETE signal\n");
dispatch_signal(SS_IPAC_NWL, S_IPAC_NWL_COMPLETE, msg->trx);
break;
case NM_IPACC_TESTRES_PARTIAL:
@@ -154,8 +197,6 @@ static int test_rep(void *_msg)
static int nwl_sig_cb(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
- struct ipacc_ack_signal_data *ipacc_data;
-
switch (signal) {
case S_NM_TEST_REP:
return test_rep(signal_data);