fixeria has uploaded this change for review.

View Change

trxcon: maintain full power scan state in the trxcon_fsm

Currently the trxcon_fsm is simply passing start and stop ARFCN values
(as received from the L1CTL peer) over the PHYIF, and expecting the
PHY to perform the measurements within the given range. This approach
requires the PHY implementation to maintain some state internally.

Let's simplify the job of the PHY implementation(s) by maintaining the
power scan state in the trxcon_fsm and sending a PHYIF_CMDT_MEASURE
command for each ARFCN in the given start/stop boundaries separately.

Change-Id: Ic5f724a11e225b439ec10aed7697e3e03b7929e5
Related: OS#5599
---
M src/host/trxcon/include/osmocom/bb/trxcon/phyif.h
M src/host/trxcon/include/osmocom/bb/trxcon/trx_if.h
M src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
M src/host/trxcon/include/osmocom/bb/trxcon/trxcon_fsm.h
M src/host/trxcon/src/trx_if.c
M src/host/trxcon/src/trxcon.c
M src/host/trxcon/src/trxcon_fsm.c
7 files changed, 71 insertions(+), 41 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/54/30054/1
diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/phyif.h b/src/host/trxcon/include/osmocom/bb/trxcon/phyif.h
index ae272dd..a92cb89 100644
--- a/src/host/trxcon/include/osmocom/bb/trxcon/phyif.h
+++ b/src/host/trxcon/include/osmocom/bb/trxcon/phyif.h
@@ -42,13 +42,11 @@

/* param of PHYIF_CMDT_MEASURE (command) */
struct phyif_cmdp_measure {
- uint16_t band_arfcn_start;
- uint16_t band_arfcn_stop;
+ uint16_t band_arfcn;
};

/* param of PHYIF_CMDT_MEASURE (response) */
struct phyif_rspp_measure {
- bool last;
uint16_t band_arfcn;
int dbm;
};
diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/trx_if.h b/src/host/trxcon/include/osmocom/bb/trxcon/trx_if.h
index bfab0ad..92de3b0 100644
--- a/src/host/trxcon/include/osmocom/bb/trxcon/trx_if.h
+++ b/src/host/trxcon/include/osmocom/bb/trxcon/trx_if.h
@@ -29,10 +29,6 @@
uint32_t prev_state;
bool powered_up;

- /* GSM L1 specific */
- uint16_t pm_band_arfcn_start;
- uint16_t pm_band_arfcn_stop;
-
/* Some private data */
void *priv;
};
diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h b/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
index ad00a05..fbbd9e6 100644
--- a/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
+++ b/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
@@ -19,6 +19,9 @@
/* L2 interface (e.g. L1CTL) */
void *l2if;

+ /* State specific data of trxcon_fsm */
+ void *fi_data;
+
/* L1 parameters */
struct {
uint16_t band_arfcn;
diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/trxcon_fsm.h b/src/host/trxcon/include/osmocom/bb/trxcon/trxcon_fsm.h
index e1ab84d..bb57d25 100644
--- a/src/host/trxcon/include/osmocom/bb/trxcon/trxcon_fsm.h
+++ b/src/host/trxcon/include/osmocom/bb/trxcon/trxcon_fsm.h
@@ -47,7 +47,6 @@

/* param of TRXCON_EV_FULL_POWER_SCAN_RES */
struct trxcon_param_full_power_scan_res {
- bool last_result;
uint16_t band_arfcn;
int dbm;
};
diff --git a/src/host/trxcon/src/trx_if.c b/src/host/trxcon/src/trx_if.c
index 928ad5d..77001ac 100644
--- a/src/host/trxcon/src/trx_if.c
+++ b/src/host/trxcon/src/trx_if.c
@@ -354,15 +354,11 @@
{
uint16_t freq10;

- /* Update ARFCN range for measurement */
- trx->pm_band_arfcn_start = cmdp->band_arfcn_start;
- trx->pm_band_arfcn_stop = cmdp->band_arfcn_stop;
-
/* Calculate a frequency for current ARFCN (DL) */
- freq10 = gsm_arfcn2freq10(cmdp->band_arfcn_start, 0);
+ freq10 = gsm_arfcn2freq10(cmdp->band_arfcn, 0);
if (freq10 == 0xffff) {
LOGPFSML(trx->fi, LOGL_ERROR,
- "ARFCN %d not defined\n", cmdp->band_arfcn_start);
+ "ARFCN %d not defined\n", cmdp->band_arfcn);
return -ENOTSUP;
}

@@ -379,36 +375,22 @@
sscanf(resp, "%u %d", &freq10, &dbm);
freq10 /= 100;

- /* Check received ARFCN against expected */
band_arfcn = gsm_freq102arfcn((uint16_t) freq10, 0);
- if (band_arfcn != trx->pm_band_arfcn_start) {
- LOGPFSML(trx->fi, LOGL_ERROR, "Power measurement error: "
- "response ARFCN=%u doesn't match expected ARFCN=%u\n",
- band_arfcn & ~ARFCN_FLAG_MASK,
- trx->pm_band_arfcn_start & ~ARFCN_FLAG_MASK);
+ if (band_arfcn == 0xffff) {
+ LOGPFSML(trx->fi, LOGL_ERROR,
+ "Failed to parse ARFCN from RSP MEASURE: %s\n", resp);
return;
}

const struct phyif_rsp rsp = {
.type = PHYIF_CMDT_MEASURE,
.param.measure = {
- .last = band_arfcn == trx->pm_band_arfcn_stop,
.band_arfcn = band_arfcn,
.dbm = dbm,
},
};

phyif_handle_rsp(trx, &rsp);
-
- /* Schedule a next measurement */
- if (band_arfcn != trx->pm_band_arfcn_stop) {
- const struct phyif_cmdp_measure cmdp = {
- .band_arfcn_start = ++band_arfcn,
- .band_arfcn_stop = trx->pm_band_arfcn_stop,
- };
-
- trx_if_cmd_measure(trx, &cmdp);
- }
}

/*
diff --git a/src/host/trxcon/src/trxcon.c b/src/host/trxcon/src/trxcon.c
index 4eea55a..838bb6a 100644
--- a/src/host/trxcon/src/trxcon.c
+++ b/src/host/trxcon/src/trxcon.c
@@ -188,7 +188,6 @@
{
const struct phyif_rspp_measure *meas = &rsp->param.measure;
struct trxcon_param_full_power_scan_res res = {
- .last_result = meas->last,
.band_arfcn = meas->band_arfcn,
.dbm = meas->dbm,
};
diff --git a/src/host/trxcon/src/trxcon_fsm.c b/src/host/trxcon/src/trxcon_fsm.c
index 38b95ec..bbbf51a 100644
--- a/src/host/trxcon/src/trxcon_fsm.c
+++ b/src/host/trxcon/src/trxcon_fsm.c
@@ -53,6 +53,7 @@
osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL);
break;
case TRXCON_EV_RESET_FULL_REQ:
+ TALLOC_FREE(trxcon->fi_data);
if (fi->state != TRXCON_ST_RESET)
osmo_fsm_inst_state_chg(fi, TRXCON_ST_RESET, 0, 0);
l1sched_reset(trxcon->sched, true);
@@ -125,16 +126,26 @@
const struct trxcon_param_full_power_scan_req *req)
{
struct trxcon_inst *trxcon = fi->priv;
- const struct phyif_cmd phycmd = {
- .type = PHYIF_CMDT_MEASURE,
- .param.measure = {
- .band_arfcn_start = req->band_arfcn_start,
- .band_arfcn_stop = req->band_arfcn_stop,
- },
- };
+ enum gsm_band band_start, band_stop;

+ if (trxcon->fi_data != NULL) {
+ LOGPFSML(fi, LOGL_ERROR, "Full power scan is already in progress\n");
+ return;
+ }
+
+ /* The start and stop ARFCNs must be in the same band */
+ if (gsm_arfcn2band_rc(req->band_arfcn_start, &band_start) != 0 ||
+ gsm_arfcn2band_rc(req->band_arfcn_stop, &band_stop) != 0 ||
+ band_start != band_stop) {
+ LOGPFSML(fi, LOGL_ERROR, "Full power scan request has invalid params\n");
+ return;
+ }
+
+ trxcon->fi_data = talloc_memdup(fi, req, sizeof(*req));
+ OSMO_ASSERT(trxcon->fi_data != NULL);
+
+ /* trxcon_st_full_power_scan_onenter() sends the initial PHYIF_CMDT_MEASURE */
osmo_fsm_inst_state_chg(fi, TRXCON_ST_FULL_POWER_SCAN, 0, 0); /* TODO: timeout */
- phyif_handle_cmd(trxcon->phyif, &phycmd);
}

static void trxcon_st_reset_action(struct osmo_fsm_inst *fi,
@@ -179,6 +190,23 @@
}
}

+static void trxcon_st_full_power_scan_onenter(struct osmo_fsm_inst *fi,
+ uint32_t prev_state)
+{
+ const struct trxcon_inst *trxcon = fi->priv;
+ const struct trxcon_param_full_power_scan_req *req = trxcon->fi_data;
+
+ /* req->band_arfcn_start holds the current ARFCN */
+ const struct phyif_cmd phycmd = {
+ .type = PHYIF_CMDT_MEASURE,
+ .param.measure = {
+ .band_arfcn = req->band_arfcn_start,
+ },
+ };
+
+ phyif_handle_cmd(trxcon->phyif, &phycmd);
+}
+
static void trxcon_st_full_power_scan_action(struct osmo_fsm_inst *fi,
uint32_t event, void *data)
{
@@ -187,9 +215,33 @@
switch (event) {
case TRXCON_EV_FULL_POWER_SCAN_RES:
{
+ struct trxcon_param_full_power_scan_req *req = trxcon->fi_data;
const struct trxcon_param_full_power_scan_res *res = data;

- l1ctl_tx_pm_conf(trxcon->l2if, res->band_arfcn, res->dbm, res->last_result);
+ if (req == NULL) {
+ LOGPFSML(fi, LOGL_ERROR, "Rx unexpected power scan result\n");
+ break;
+ }
+
+ /* req->band_arfcn_start holds the expected ARFCN */
+ if (res->band_arfcn != req->band_arfcn_start) {
+ LOGPFSML(fi, LOGL_ERROR, "Rx power scan result "
+ "with unexpected ARFCN %s (expected %s)\n",
+ res->band_arfcn & ~ARFCN_FLAG_MASK,
+ req->band_arfcn_start & ~ARFCN_FLAG_MASK);
+ break;
+ }
+
+ if (res->band_arfcn < req->band_arfcn_stop) {
+ l1ctl_tx_pm_conf(trxcon->l2if, res->band_arfcn, res->dbm, false);
+ /* trxcon_st_full_power_scan_onenter() sends the next PHYIF_CMDT_MEASURE */
+ req->band_arfcn_start = res->band_arfcn + 1;
+ osmo_fsm_inst_state_chg(fi, TRXCON_ST_FULL_POWER_SCAN, 0, 0); /* TODO: timeout */
+ } else {
+ l1ctl_tx_pm_conf(trxcon->l2if, res->band_arfcn, res->dbm, true);
+ LOGPFSML(fi, LOGL_INFO, "Full power scan completed\n");
+ TALLOC_FREE(trxcon->fi_data);
+ }
break;
}
case TRXCON_EV_FULL_POWER_SCAN_REQ:
@@ -525,6 +577,7 @@
| S(TRXCON_ST_FULL_POWER_SCAN),
.in_event_mask = S(TRXCON_EV_FULL_POWER_SCAN_RES)
| S(TRXCON_EV_FULL_POWER_SCAN_REQ),
+ .onenter = &trxcon_st_full_power_scan_onenter,
.action = &trxcon_st_full_power_scan_action,
},
[TRXCON_ST_FBSB_SEARCH] = {

To view, visit change 30054. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: Ic5f724a11e225b439ec10aed7697e3e03b7929e5
Gerrit-Change-Number: 30054
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de>
Gerrit-MessageType: newchange