Review at  https://gerrit.osmocom.org/2282

WIP: Add IPA/SCCPlite stacking

Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56
---
M include/osmocom/sigtran/osmo_ss7.h
M src/osmo_ss7.c
M src/sccp_scrc.c
3 files changed, 134 insertions(+), 9 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/82/2282/1

diff --git a/include/osmocom/sigtran/osmo_ss7.h 
b/include/osmocom/sigtran/osmo_ss7.h
index 2d5eba9..e33a9ad 100644
--- a/include/osmocom/sigtran/osmo_ss7.h
+++ b/include/osmocom/sigtran/osmo_ss7.h
@@ -254,6 +254,7 @@
        OSMO_SS7_ASP_PROT_NONE,
        OSMO_SS7_ASP_PROT_SUA,
        OSMO_SS7_ASP_PROT_M3UA,
+       OSMO_SS7_ASP_PROT_IPA,
        _NUM_OSMO_SS7_ASP_PROT
 };
 
diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c
index e55d55c..f9770c7 100644
--- a/src/osmo_ss7.c
+++ b/src/osmo_ss7.c
@@ -41,6 +41,7 @@
 #include <osmocom/core/socket.h>
 
 #include <osmocom/netif/stream.h>
+#include <osmocom/netif/ipa.h>
 
 #include "sccp_internal.h"
 #include "xua_internal.h"
@@ -68,11 +69,24 @@
        { OSMO_SS7_ASP_PROT_NONE,       "none" },
        { OSMO_SS7_ASP_PROT_SUA,        "sua" },
        { OSMO_SS7_ASP_PROT_M3UA,       "m3ua" },
+       { OSMO_SS7_ASP_PROT_IPA,        "ipa" },
        { 0, NULL }
 };
 
 #define LOGSS7(inst, level, fmt, args ...)     \
        LOGP(DLSS7, level, "%u: " fmt, inst ? (inst)->cfg.id : 0, ## args)
+
+static int asp_proto_to_ip_proto(enum osmo_ss7_asp_protocol proto)
+{
+       switch (proto) {
+       case OSMO_SS7_ASP_PROT_IPA:
+               return IPPROTO_TCP;
+       case OSMO_SS7_ASP_PROT_SUA:
+       case OSMO_SS7_ASP_PROT_M3UA:
+       default:
+               return IPPROTO_SCTP;
+       }
+}
 
 int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst)
 {
@@ -786,7 +800,8 @@
                as->cfg.proto = proto;
                as->cfg.mode = OSMO_SS7_AS_TMOD_LOADSHARE;
                as->cfg.recovery_timeout_msec = 2000;
-               as->fi = xua_as_fsm_start(as, LOGL_DEBUG);
+               if (proto != OSMO_SS7_ASP_PROT_IPA)
+                       as->fi = xua_as_fsm_start(as, LOGL_DEBUG);
                llist_add_tail(&as->list, &inst->as_list);
        }
 
@@ -1020,6 +1035,7 @@
 }
 
 static int xua_cli_read_cb(struct osmo_stream_cli *conn);
+static int ipa_cli_read_cb(struct osmo_stream_cli *conn);
 static int xua_cli_connect_cb(struct osmo_stream_cli *cli);
 
 int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp)
@@ -1049,10 +1065,13 @@
                osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port);
                osmo_stream_cli_set_local_addr(asp->client, 
asp->cfg.local.host);
                osmo_stream_cli_set_local_port(asp->client, 
asp->cfg.local.port);
-               osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP);
+               osmo_stream_cli_set_proto(asp->client, 
asp_proto_to_ip_proto(asp->cfg.proto));
                osmo_stream_cli_set_reconnect_timeout(asp->client, 5);
                osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb);
-               osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb);
+               if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA)
+                       osmo_stream_cli_set_read_cb(asp->client, 
ipa_cli_read_cb);
+               else
+                       osmo_stream_cli_set_read_cb(asp->client, 
xua_cli_read_cb);
                osmo_stream_cli_set_data(asp->client, asp);
                rc = osmo_stream_cli_open2(asp->client, 1);
                if (rc < 0) {
@@ -1079,7 +1098,8 @@
        /* (re)start the ASP FSM */
        if (asp->fi)
                osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL);
-       asp->fi = xua_asp_fsm_start(asp, role, LOGL_DEBUG);
+       if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA)
+               asp->fi = xua_asp_fsm_start(asp, role, LOGL_DEBUG);
 
        return 0;
 }
@@ -1162,6 +1182,64 @@
                                notif->sn_header.sn_type));
                break;
        }
+}
+
+static int ipa_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg)
+{
+       struct osmo_mtp_prim *omp;
+
+       /* FIXME: pull the IPA header */
+
+       /* Generate an MTP-TRANSFER.ind and hand it into the MTP core
+        * so it can dispatch it to SCCP */
+       omp = (struct osmo_mtp_prim *) msgb_push(msg, sizeof(*omp));
+       osmo_prim_init(&omp->oph, MTP_SAP_USER,
+                       OSMO_MTP_PRIM_TRANSFER, PRIM_OP_INDICATION, msg);
+       omp->u.transfer.opc = 0;
+       omp->u.transfer.dpc = 0;
+       omp->u.transfer.sio = MTP_SI_SCCP;
+       omp->u.transfer.sls = 0;
+
+       return osmo_ss7_mtp_to_user(asp->inst, omp);
+}
+
+/* netif code tells us we can read something from the socket */
+static int ipa_srv_conn_cb(struct osmo_stream_srv *conn)
+{
+       struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn);
+       struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn);
+       struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Server Rx");
+       int rc;
+
+       if (!msg)
+               return -ENOMEM;
+
+       /* read xUA message from socket and process it */
+       rc = osmo_stream_srv_recv(conn, msg);
+       LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): recvmsg() returned %d\n",
+               __func__, rc);
+       if (rc < 0) {
+               osmo_stream_srv_destroy(conn);
+               goto out;
+       } else if (rc == 0) {
+               osmo_stream_srv_destroy(conn);
+               goto out;
+       }
+       if (osmo_ipa_process_msg(msg) < 0) {
+               LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n");
+               osmo_stream_srv_destroy(conn);
+               goto out;
+       }
+       msg->dst = asp;
+
+       /* Handle IPA PING, PONG and ID_ACK messages */
+       if (osmo_ipa_rcvmsg_base(msg, ofd, 1))
+               return 0;
+
+       rc = ipa_rx_msg(asp, msg);
+out:
+       msgb_free(msg);
+       return rc;
 }
 
 /* netif code tells us we can read something from the socket */
@@ -1251,6 +1329,40 @@
        }
 
        return 0;
+}
+
+/* read call-back for IPA/SCCPlite socket */
+static int ipa_cli_read_cb(struct osmo_stream_cli *conn)
+{
+       struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn);
+       struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn);
+       struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "IPA Client Rx");
+       int rc;
+
+       if (!msg)
+               return -ENOMEM;
+
+       rc = osmo_stream_cli_recv(conn, msg);
+       if (rc <= 0) {
+               LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot receive message\n");
+               osmo_stream_cli_reconnect(conn);
+               goto out;
+       }
+       if (osmo_ipa_process_msg(msg) < 0) {
+               LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n");
+               osmo_stream_cli_reconnect(conn);
+               goto out;
+       }
+
+       /* Handle IPA PING, PONG and ID_ACK messages */
+       if (osmo_ipa_rcvmsg_base(msg, ofd, 0))
+               return 0;
+
+       msg->dst = asp;
+       rc = ipa_rx_msg(asp, msg);
+out:
+       msgb_free(msg);
+       return rc;
 }
 
 static int xua_cli_read_cb(struct osmo_stream_cli *conn)
@@ -1345,9 +1457,15 @@
        LOGP(DLSS7, LOGL_INFO, "%s: New SCTP connection accepted\n",
                sock_name);
 
-       srv = osmo_stream_srv_create(oxs, link, fd,
-                                    xua_srv_conn_cb,
-                                    xua_srv_conn_closed_cb, NULL);
+       if (oxs->cfg.proto == OSMO_SS7_ASP_PROT_IPA) {
+               srv = osmo_stream_srv_create(oxs, link, fd,
+                                            ipa_srv_conn_cb,
+                                            xua_srv_conn_closed_cb, NULL);
+       } else {
+               srv = osmo_stream_srv_create(oxs, link, fd,
+                                            xua_srv_conn_cb,
+                                            xua_srv_conn_closed_cb, NULL);
+       }
        if (!srv) {
                LOGP(DLSS7, LOGL_ERROR, "%s: Unable to create stream server "
                     "for SCTP connection\n", sock_name);
@@ -1413,6 +1531,10 @@
                break;
        case OSMO_SS7_ASP_PROT_M3UA:
                msgb_sctp_ppid(msg) = M3UA_PPID;
+               break;
+       case OSMO_SS7_ASP_PROT_IPA:
+               /* do we really want to do this here? */
+               osmo_ipa_msg_push_header(msg, FIXME);
                break;
        default:
                OSMO_ASSERT(0);
@@ -1489,7 +1611,7 @@
 
        osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host);
        osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port);
-       osmo_stream_srv_link_set_proto(oxs->server, IPPROTO_SCTP);
+       osmo_stream_srv_link_set_proto(oxs->server, 
asp_proto_to_ip_proto(proto));
 
        rc = osmo_stream_srv_link_open(oxs->server);
        if (rc < 0) {
diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c
index f9df075..80c8126 100644
--- a/src/sccp_scrc.c
+++ b/src/sccp_scrc.c
@@ -142,6 +142,7 @@
                case OSMO_SS7_ASP_PROT_SUA:
                        return sua_tx_xua_as(as, xua);
                case OSMO_SS7_ASP_PROT_M3UA:
+               case OSMO_SS7_ASP_PROT_IPA:
                        return sua2sccp_tx_m3ua(inst, xua);
                default:
                        LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req for "
@@ -295,7 +296,8 @@
                       const struct osmo_sccp_addr *called)
 {
        struct osmo_sccp_user *scu;
-
+       /* it is not really clear that called->pc will be set to
+        * anything here, in the case of a SSN-only CalledAddr */
        scu = sccp_user_find(inst, called->ssn, called->pc);
 
        /* Is subsystem equipped? */

-- 
To view, visit https://gerrit.osmocom.org/2282
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56
Gerrit-PatchSet: 1
Gerrit-Project: libosmo-sccp
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <[email protected]>

Reply via email to