ipaccess-config / network listen: ordered list of RxLevels

Use libosmocore 'rxlev_stat' module to generate an ordered list
of ARFCN's, sorted by RxLev while performing test nr. 64
This commit is contained in:
Harald Welte 2010-03-06 11:38:05 +01:00
parent 549faada21
commit 887deabe38
6 changed files with 73 additions and 28 deletions

View File

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

View File

@ -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];

View File

@ -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 */

View File

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

View File

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

View File

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