aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2023-02-24 14:50:11 +0100
committerlaforge <laforge@osmocom.org>2023-03-07 12:54:58 +0000
commitecf825dc0856411df3b83737d9439de044823d1b (patch)
treeb4f9b6fa12cc177a2345702484459713d8977fc2 /src
parenta8f5dbce77ce95a601987db00f0ad9a1d4b47458 (diff)
pcu_sock: activate/deactivate PDCH on pcu reconnect
When the PCU is disconnected while the BSC keeps running the PDCH should be closed. Also the PDCH should be reopened when the PCU is reconnected. Change-Id: I9ea0c53a5e68a51c781ef43bae71f947cdb95678 Related: OS#5198
Diffstat (limited to 'src')
-rw-r--r--src/osmo-bsc/pcu_sock.c44
-rw-r--r--src/osmo-bsc/timeslot_fsm.c37
2 files changed, 69 insertions, 12 deletions
diff --git a/src/osmo-bsc/pcu_sock.c b/src/osmo-bsc/pcu_sock.c
index 1d5e56c3f..51b59c6ef 100644
--- a/src/osmo-bsc/pcu_sock.c
+++ b/src/osmo-bsc/pcu_sock.c
@@ -44,6 +44,7 @@
#include <osmocom/bsc/gsm_04_08_rr.h>
#include <osmocom/bsc/bts.h>
#include <osmocom/bsc/bts_sm.h>
+#include <osmocom/bsc/timeslot_fsm.h>
static int pcu_sock_send(struct gsm_bts *bts, struct msgb *msg);
@@ -58,11 +59,14 @@ static const char *sapi_string[] = {
[PCU_IF_SAPI_PCH_DT] = "PCH_DT",
};
-/* Check if BTS has a PCU connection */
-static bool pcu_connected(struct gsm_bts *bts)
+bool pcu_connected(struct gsm_bts *bts)
{
struct pcu_sock_state *state = bts->pcu_state;
+ /* BSC co-located PCU is only supported for Ericsson RBS */
+ if (!is_ericsson_bts(bts))
+ return false;
+
if (!state)
return false;
if (state->conn_bfd.fd <= 0)
@@ -751,8 +755,7 @@ static void pcu_sock_close(struct pcu_sock_state *state)
struct osmo_fd *bfd = &state->conn_bfd;
struct gsm_bts *bts;
struct gsm_bts_trx *trx;
- struct gsm_bts_trx_ts *ts;
- int i, j;
+ int j;
/* FIXME: allow multiple BTS */
bts = llist_entry(state->net->bts_list.next, struct gsm_bts, list);
@@ -773,15 +776,14 @@ static void pcu_sock_close(struct pcu_sock_state *state)
#endif
/* release PDCH */
- for (i = 0; i < 8; i++) {
- trx = gsm_bts_trx_num(bts, i);
- if (!trx)
- break;
- for (j = 0; j < 8; j++) {
- ts = &trx->ts[j];
+ llist_for_each_entry(trx, &bts->trx_list, list) {
+ for (j = 0; j < ARRAY_SIZE(trx->ts); j++) {
+ struct gsm_bts_trx_ts *ts = &trx->ts[j];
+ /* BSC co-located PCU applies only to Ericsson RBS, which supports only GSM_PCHAN_OSMO_DYN.
+ * So we need to deact only on this pchan kind. */
if (ts->mo.nm_state.operational == NM_OPSTATE_ENABLED
- && ts->pchan_is == GSM_PCHAN_PDCH) {
- printf("l1sap_chan_rel(trx,gsm_lchan2chan_nr(ts->lchan));\n");
+ && ts->pchan_on_init == GSM_PCHAN_OSMO_DYN) {
+ ts_pdch_deact(ts);
}
}
}
@@ -908,9 +910,15 @@ static int pcu_sock_accept(struct osmo_fd *bfd, unsigned int flags)
struct pcu_sock_state *state = (struct pcu_sock_state *)bfd->data;
struct osmo_fd *conn_bfd = &state->conn_bfd;
struct sockaddr_un un_addr;
+ struct gsm_bts *bts;
+ struct gsm_bts_trx *trx;
+ int j;
socklen_t len;
int rc;
+ /* FIXME: allow multiple BTS */
+ bts = llist_entry(state->net->bts_list.next, struct gsm_bts, list);
+
len = sizeof(un_addr);
rc = accept(bfd->fd, (struct sockaddr *) &un_addr, &len);
if (rc < 0) {
@@ -939,6 +947,18 @@ static int pcu_sock_accept(struct osmo_fd *bfd, unsigned int flags)
LOGP(DPCU, LOGL_NOTICE, "PCU socket connected to external PCU\n");
+ /* activate PDCH */
+ llist_for_each_entry(trx, &bts->trx_list, list) {
+ for (j = 0; j < ARRAY_SIZE(trx->ts); j++) {
+ struct gsm_bts_trx_ts *ts = &trx->ts[j];
+ /* (See comment in pcu_sock_close above) */
+ if (ts->mo.nm_state.operational == NM_OPSTATE_ENABLED
+ && ts->pchan_on_init == GSM_PCHAN_OSMO_DYN) {
+ ts_pdch_act(ts);
+ }
+ }
+ }
+
return 0;
}
diff --git a/src/osmo-bsc/timeslot_fsm.c b/src/osmo-bsc/timeslot_fsm.c
index 28e2aaa70..16d736033 100644
--- a/src/osmo-bsc/timeslot_fsm.c
+++ b/src/osmo-bsc/timeslot_fsm.c
@@ -341,6 +341,11 @@ static void ts_fsm_unused_pdch_act(struct osmo_fsm_inst *fi)
return;
}
+ if (!pcu_connected(bts)) {
+ LOG_TS(ts, LOGL_DEBUG, "PCU not connected: not activating PDCH.\n");
+ return;
+ }
+
osmo_fsm_inst_state_chg(fi, TS_ST_WAIT_PDCH_ACT, CHAN_ACT_DEACT_TIMEOUT,
T_CHAN_ACT_DEACT);
}
@@ -408,6 +413,10 @@ static void ts_fsm_unused(struct osmo_fsm_inst *fi, uint32_t event, void *data)
/* ignored. */
return;
+ case TS_EV_PDCH_ACT:
+ ts_fsm_unused_pdch_act(fi);
+ return;
+
default:
OSMO_ASSERT(false);
}
@@ -531,6 +540,10 @@ static void ts_fsm_pdch(struct osmo_fsm_inst *fi, uint32_t event, void *data)
}
}
+ case TS_EV_PDCH_DEACT:
+ ts_fsm_pdch_deact(fi);
+ return;
+
case TS_EV_LCHAN_UNUSED:
/* ignored */
return;
@@ -889,6 +902,7 @@ static const struct osmo_fsm_state ts_fsm_states[] = {
.in_event_mask = 0
| S(TS_EV_LCHAN_REQUESTED)
| S(TS_EV_LCHAN_UNUSED)
+ | S(TS_EV_PDCH_ACT)
,
.out_state_mask = 0
| S(TS_ST_WAIT_PDCH_ACT)
@@ -921,6 +935,7 @@ static const struct osmo_fsm_state ts_fsm_states[] = {
.in_event_mask = 0
| S(TS_EV_LCHAN_REQUESTED)
| S(TS_EV_LCHAN_UNUSED)
+ | S(TS_EV_PDCH_DEACT)
,
.out_state_mask = 0
| S(TS_ST_WAIT_PDCH_DEACT)
@@ -992,6 +1007,8 @@ static const struct value_string ts_fsm_event_names[] = {
OSMO_VALUE_STRING(TS_EV_PDCH_ACT_NACK),
OSMO_VALUE_STRING(TS_EV_PDCH_DEACT_ACK),
OSMO_VALUE_STRING(TS_EV_PDCH_DEACT_NACK),
+ OSMO_VALUE_STRING(TS_EV_PDCH_DEACT),
+ OSMO_VALUE_STRING(TS_EV_PDCH_ACT),
{}
};
@@ -1105,3 +1122,23 @@ bool ts_usable_as_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config as_
return true;
}
+
+void ts_pdch_act(struct gsm_bts_trx_ts *ts)
+{
+ /* We send the activation event only when the timeslot is UNUSED. In all other cases the timeslot FSM
+ * will automatically handle the activation at some later point. */
+ if (ts->fi->state != TS_ST_UNUSED)
+ return;
+
+ osmo_fsm_inst_dispatch(ts->fi, TS_EV_PDCH_ACT, NULL);
+}
+
+void ts_pdch_deact(struct gsm_bts_trx_ts *ts)
+{
+ /* We send the deactivation event only when the timeslot is active as PDCH. The timeslot FSM will check
+ * if the PCU is available before activating the PDCH again. */
+ if (ts->fi->state != TS_ST_PDCH)
+ return;
+
+ osmo_fsm_inst_dispatch(ts->fi, TS_EV_PDCH_DEACT, NULL);
+}