osmith has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-bsc-nat/+/27469 )
Change subject: bsc_nat_fsm: split up sccp_sap_up in _cn, _ran
......................................................................
bsc_nat_fsm: split up sccp_sap_up in _cn, _ran
Prepare for future patches where more will happen in the callback
function. Split it up into two functions, one for CN and one for RAN, so
we don't need to constantly think through both cases while
changing/trying to understand the function.
Related: SYS#5560
Change-Id: I8eb8f24ad33a59de8fbaf512547d389ee86c13dc
---
M src/osmo-bsc-nat/bsc_nat_fsm.c
1 file changed, 159 insertions(+), 30 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc-nat refs/changes/69/27469/1
diff --git a/src/osmo-bsc-nat/bsc_nat_fsm.c b/src/osmo-bsc-nat/bsc_nat_fsm.c
index a0ff4d2..94b6658 100644
--- a/src/osmo-bsc-nat/bsc_nat_fsm.c
+++ b/src/osmo-bsc-nat/bsc_nat_fsm.c
@@ -99,91 +99,220 @@
return 0;
}
-/* Handle incoming messages. For now this is simplified by assuming there is
- * only one MSC, one BSC (not yet translating connection ids etc.). */
-static int sccp_sap_up(struct osmo_prim_hdr *oph, void *scu)
+/* Handle incoming messages from CN (MSC). For now this is simplified by
+ * assuming there is only one MSC, one BSC (not yet translating connection ids
+ * etc.). */
+static int sccp_sap_up_cn(struct osmo_prim_hdr *oph, void *scu)
{
- struct bsc_nat_sccp_inst *src = osmo_sccp_user_get_priv(scu);
- struct bsc_nat_sccp_inst *dest = sccp_inst_dest(src);
+ struct bsc_nat_sccp_inst *sccp_inst = osmo_sccp_user_get_priv(scu);
struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph;
- struct osmo_sccp_addr *peer_addr_in;
+ struct osmo_sccp_addr *addr; /* MSC's address */
struct osmo_sccp_addr peer_addr_out;
int rc = -1;
- LOGP(DMAIN, LOGL_DEBUG, "Rx %s from %s\n", osmo_scu_prim_name(oph), src ==
g_bsc_nat->cn ? "CN" : "RAN");
+ LOGP(DMAIN, LOGL_DEBUG, "Rx %s from CN\n", osmo_scu_prim_name(oph));
switch (OSMO_PRIM_HDR(oph)) {
case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION):
/* indication of new inbound connection request */
- if (sccp_sap_get_peer_addr_in(src, &peer_addr_in,
&prim->u.connect.called_addr,
+ if (sccp_sap_get_peer_addr_in(sccp_inst, &addr,
&prim->u.connect.called_addr,
&prim->u.connect.calling_addr) < 0)
goto error;
- if (sccp_sap_get_peer_addr_out(src, peer_addr_in, &peer_addr_out) < 0)
+ if (sccp_sap_get_peer_addr_out(sccp_inst, addr, &peer_addr_out) < 0)
goto error;
- LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(dest,
&peer_addr_out));
+ LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(g_bsc_nat->ran,
&peer_addr_out));
msgb_pull_to_l2(oph->msg);
- osmo_sccp_tx_conn_req(dest->scu, prim->u.connect.conn_id,
&dest->local_sccp_addr, &peer_addr_out,
- oph->msg->data, msgb_length(oph->msg));
+ osmo_sccp_tx_conn_req(g_bsc_nat->ran->scu,
+ prim->u.connect.conn_id,
+ &g_bsc_nat->ran->local_sccp_addr,
+ &peer_addr_out,
+ oph->msg->data,
+ msgb_length(oph->msg));
rc = 0;
break;
case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM):
/* indication of connection confirm */
- if (sccp_sap_get_peer_addr_in(src, &peer_addr_in,
&prim->u.connect.called_addr,
+ if (sccp_sap_get_peer_addr_in(sccp_inst, &addr,
&prim->u.connect.called_addr,
&prim->u.connect.calling_addr) < 0)
goto error;
- if (sccp_sap_get_peer_addr_out(src, peer_addr_in, &peer_addr_out) < 0)
+ if (sccp_sap_get_peer_addr_out(sccp_inst, addr, &peer_addr_out) < 0)
goto error;
- LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(dest,
&peer_addr_out));
+ LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(g_bsc_nat->ran,
&peer_addr_out));
msgb_pull_to_l2(oph->msg);
- osmo_sccp_tx_conn_resp(dest->scu, prim->u.connect.conn_id, &peer_addr_out,
oph->msg->data,
+ osmo_sccp_tx_conn_resp(g_bsc_nat->ran->scu,
+ prim->u.connect.conn_id,
+ &peer_addr_out,
+ oph->msg->data,
msgb_length(oph->msg));
rc = 0;
break;
case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION):
/* connection-oriented data received */
- if (sccp_sap_get_peer_addr_out(src, NULL, &peer_addr_out) < 0)
+ if (sccp_sap_get_peer_addr_out(sccp_inst, NULL, &peer_addr_out) < 0)
goto error;
- LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(dest,
&peer_addr_out));
+ LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(g_bsc_nat->ran,
&peer_addr_out));
msgb_pull_to_l2(oph->msg);
- osmo_sccp_tx_data(dest->scu, prim->u.data.conn_id, oph->msg->data,
msgb_length(oph->msg));
+ osmo_sccp_tx_data(g_bsc_nat->ran->scu,
+ prim->u.data.conn_id,
+ oph->msg->data,
+ msgb_length(oph->msg));
rc = 0;
break;
case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION):
/* indication of disconnect */
- if (sccp_sap_get_peer_addr_out(src, NULL, &peer_addr_out) < 0)
+ if (sccp_sap_get_peer_addr_out(sccp_inst, NULL, &peer_addr_out) < 0)
goto error;
- LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(dest,
&peer_addr_out));
+ LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(g_bsc_nat->ran,
&peer_addr_out));
- osmo_sccp_tx_disconn(dest->scu, prim->u.disconnect.conn_id,
&prim->u.disconnect.responding_addr,
+ osmo_sccp_tx_disconn(g_bsc_nat->ran->scu,
+ prim->u.disconnect.conn_id,
+ &prim->u.disconnect.responding_addr,
prim->u.disconnect.cause);
rc = 0;
break;
case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION):
/* connection-less data received */
- peer_addr_in = &prim->u.unitdata.calling_addr;
+ addr = &prim->u.unitdata.calling_addr;
- if (sccp_sap_get_peer_addr_out(src, peer_addr_in, &peer_addr_out) < 0)
+ if (sccp_sap_get_peer_addr_out(sccp_inst, addr, &peer_addr_out) < 0)
goto error;
- LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(dest,
&peer_addr_out));
+ LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(g_bsc_nat->ran,
&peer_addr_out));
/* oph->msg stores oph and unitdata msg. Move oph->msg->data to
* unitdata msg and send it again. */
msgb_pull_to_l2(oph->msg);
- osmo_sccp_tx_unitdata(dest->scu, &dest->local_sccp_addr, &peer_addr_out,
oph->msg->data,
+ osmo_sccp_tx_unitdata(g_bsc_nat->ran->scu,
+ &g_bsc_nat->ran->local_sccp_addr,
+ &peer_addr_out,
+ oph->msg->data,
+ msgb_length(oph->msg));
+ rc = 0;
+ break;
+
+ default:
+ LOGP(DMAIN, LOGL_ERROR, "%s(%s) is not implemented!\n", __func__,
osmo_scu_prim_name(oph));
+ break;
+ }
+
+error:
+ msgb_free(oph->msg);
+ return rc;
+}
+
+/* Handle incoming messages from RAN (BSC). For now this is simplified by
+ * assuming there is only one MSC, one BSC (not yet translating connection ids
+ * etc.). */
+static int sccp_sap_up_ran(struct osmo_prim_hdr *oph, void *scu)
+{
+ struct bsc_nat_sccp_inst *sccp_inst = osmo_sccp_user_get_priv(scu);
+ struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph;
+ struct osmo_sccp_addr *addr; /* BSC's address */
+ struct osmo_sccp_addr peer_addr_out;
+ int rc = -1;
+
+ LOGP(DMAIN, LOGL_DEBUG, "Rx %s from RAN\n", osmo_scu_prim_name(oph));
+
+ switch (OSMO_PRIM_HDR(oph)) {
+ case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION):
+ /* indication of new inbound connection request */
+ if (sccp_sap_get_peer_addr_in(sccp_inst, &addr,
&prim->u.connect.called_addr,
+ &prim->u.connect.calling_addr) < 0)
+ goto error;
+
+ if (sccp_sap_get_peer_addr_out(sccp_inst, addr, &peer_addr_out) < 0)
+ goto error;
+
+ LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(g_bsc_nat->cn,
&peer_addr_out));
+
+ msgb_pull_to_l2(oph->msg);
+ osmo_sccp_tx_conn_req(g_bsc_nat->cn->scu,
+ prim->u.connect.conn_id,
+ &g_bsc_nat->cn->local_sccp_addr,
+ &peer_addr_out,
+ oph->msg->data,
+ msgb_length(oph->msg));
+ rc = 0;
+ break;
+
+ case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM):
+ /* indication of connection confirm */
+ if (sccp_sap_get_peer_addr_in(sccp_inst, &addr,
&prim->u.connect.called_addr,
+ &prim->u.connect.calling_addr) < 0)
+ goto error;
+
+ if (sccp_sap_get_peer_addr_out(sccp_inst, addr, &peer_addr_out) < 0)
+ goto error;
+
+ LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(g_bsc_nat->cn,
&peer_addr_out));
+
+ msgb_pull_to_l2(oph->msg);
+ osmo_sccp_tx_conn_resp(g_bsc_nat->cn->scu,
+ prim->u.connect.conn_id,
+ &peer_addr_out,
+ oph->msg->data,
+ msgb_length(oph->msg));
+ rc = 0;
+ break;
+
+ case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION):
+ /* connection-oriented data received */
+ if (sccp_sap_get_peer_addr_out(sccp_inst, NULL, &peer_addr_out) < 0)
+ goto error;
+
+ LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(g_bsc_nat->cn,
&peer_addr_out));
+
+ msgb_pull_to_l2(oph->msg);
+ osmo_sccp_tx_data(g_bsc_nat->cn->scu,
+ prim->u.data.conn_id,
+ oph->msg->data,
+ msgb_length(oph->msg));
+ rc = 0;
+ break;
+
+ case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION):
+ /* indication of disconnect */
+ if (sccp_sap_get_peer_addr_out(sccp_inst, NULL, &peer_addr_out) < 0)
+ goto error;
+
+ LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(g_bsc_nat->cn,
&peer_addr_out));
+
+ osmo_sccp_tx_disconn(g_bsc_nat->cn->scu,
+ prim->u.disconnect.conn_id,
+ &prim->u.disconnect.responding_addr,
+ prim->u.disconnect.cause);
+ rc = 0;
+ break;
+
+ case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION):
+ /* connection-less data received */
+ addr = &prim->u.unitdata.calling_addr;
+
+ if (sccp_sap_get_peer_addr_out(sccp_inst, addr, &peer_addr_out) < 0)
+ goto error;
+
+ LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(g_bsc_nat->cn,
&peer_addr_out));
+
+ /* oph->msg stores oph and unitdata msg. Move oph->msg->data to
+ * unitdata msg and send it again. */
+ msgb_pull_to_l2(oph->msg);
+ osmo_sccp_tx_unitdata(g_bsc_nat->cn->scu,
+ &g_bsc_nat->cn->local_sccp_addr,
+ &peer_addr_out,
+ oph->msg->data,
msgb_length(oph->msg));
rc = 0;
break;
@@ -199,7 +328,7 @@
}
static int sccp_inst_init(struct bsc_nat_sccp_inst *sccp_inst, const char *name, const
char *default_pc_str,
- enum osmo_sccp_ssn ssn)
+ osmo_prim_cb prim_cb, enum osmo_sccp_ssn ssn)
{
int default_pc;
struct osmo_sccp_instance *sccp;
@@ -218,7 +347,7 @@
osmo_sccp_local_addr_by_instance(&sccp_inst->local_sccp_addr, sccp, ssn);
- sccp_inst->scu = osmo_sccp_user_bind(sccp, name, sccp_sap_up, ssn);
+ sccp_inst->scu = osmo_sccp_user_bind(sccp, name, prim_cb, ssn);
if (!sccp_inst->scu) {
LOGP(DMAIN, LOGL_ERROR, "%s: failed to bind sccp user\n", name);
return -2;
@@ -245,12 +374,12 @@
{
struct bsc_nat *bsc_nat = (struct bsc_nat *)fi->priv;
- if (sccp_inst_init(bsc_nat->cn, "OsmoBSCNAT-CN", DEFAULT_PC_CN,
OSMO_SCCP_SSN_BSSAP) < 0) {
+ if (sccp_inst_init(bsc_nat->cn, "OsmoBSCNAT-CN", DEFAULT_PC_CN,
sccp_sap_up_cn, OSMO_SCCP_SSN_BSSAP) < 0) {
osmo_fsm_inst_state_chg(fi, BSC_NAT_FSM_ST_STOPPED, 0, 0);
return;
}
- if (sccp_inst_init(bsc_nat->ran, "OsmoBSCNAT-RAN", DEFAULT_PC_RAN,
OSMO_SCCP_SSN_BSSAP) < 0) {
+ if (sccp_inst_init(bsc_nat->ran, "OsmoBSCNAT-RAN", DEFAULT_PC_RAN,
sccp_sap_up_ran, OSMO_SCCP_SSN_BSSAP) < 0) {
osmo_fsm_inst_state_chg(fi, BSC_NAT_FSM_ST_STOPPED, 0, 0);
return;
}
--
To view, visit
https://gerrit.osmocom.org/c/osmo-bsc-nat/+/27469
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc-nat
Gerrit-Branch: master
Gerrit-Change-Id: I8eb8f24ad33a59de8fbaf512547d389ee86c13dc
Gerrit-Change-Number: 27469
Gerrit-PatchSet: 1
Gerrit-Owner: osmith <osmith(a)sysmocom.de>
Gerrit-MessageType: newchange