neels has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-hnbgw/+/33127 )

Change subject: cnpool: split up context_map_find_or_create_by_rua_ctx_id()
......................................................................

cnpool: split up context_map_find_or_create_by_rua_ctx_id()

Have separate find, alloc, set_cnlink functions instead of all in one.

For CN pooling, I need these operations to be separate:
- we need to decode the RANAP and L3 PDU only if no existing context_map
  was found (see I373d665c9684b607207f68094188eab63209db51 ).
- while decoding RANAP and L3 PDU, and while deciding which cnlink to
  use, I already want to use the logging context of LOG_MAP(). So I want
  to allocate a map first, and connect it to the selected cnlink later.

Related: SYS#6412
Change-Id: Ifc5242547260154eb5aecd3a9d9c2aac8419e8db
---
M include/osmocom/hnbgw/context_map.h
M src/osmo-hnbgw/context_map.c
M src/osmo-hnbgw/hnbgw_rua.c
3 files changed, 100 insertions(+), 39 deletions(-)

Approvals:
  pespin: Looks good to me, but someone else must approve
  Jenkins Builder: Verified
  laforge: Looks good to me, approved




diff --git a/include/osmocom/hnbgw/context_map.h 
b/include/osmocom/hnbgw/context_map.h
index fe9d3e0..55d96ea 100644
--- a/include/osmocom/hnbgw/context_map.h
+++ b/include/osmocom/hnbgw/context_map.h
@@ -136,8 +136,9 @@
 enum hnbgw_context_map_state map_rua_get_state(struct hnbgw_context_map *map);
 enum hnbgw_context_map_state map_sccp_get_state(struct hnbgw_context_map *map);

-struct hnbgw_context_map *context_map_find_or_create_by_rua_ctx_id(struct 
hnb_context *hnb, uint32_t rua_ctx_id,
-                                                                  bool is_ps);
+struct hnbgw_context_map *context_map_find_by_rua_ctx_id(struct hnb_context 
*hnb, uint32_t rua_ctx_id, bool is_ps);
+struct hnbgw_context_map *context_map_alloc(struct hnb_context *hnb, uint32_t 
rua_ctx_id, bool is_ps);
+int context_map_set_cnlink(struct hnbgw_context_map *map, struct hnbgw_cnlink 
*cnlink_selected);

 void map_rua_fsm_alloc(struct hnbgw_context_map *map);
 void map_sccp_fsm_alloc(struct hnbgw_context_map *map);
diff --git a/src/osmo-hnbgw/context_map.c b/src/osmo-hnbgw/context_map.c
index 2af685e..13aae0e 100644
--- a/src/osmo-hnbgw/context_map.c
+++ b/src/osmo-hnbgw/context_map.c
@@ -53,13 +53,9 @@
 }

 /* Map from a HNB + ContextID to the SCCP-side Connection ID */
-struct hnbgw_context_map *context_map_find_or_create_by_rua_ctx_id(struct 
hnb_context *hnb, uint32_t rua_ctx_id,
-                                                                  bool is_ps)
+struct hnbgw_context_map *context_map_find_by_rua_ctx_id(struct hnb_context 
*hnb, uint32_t rua_ctx_id, bool is_ps)
 {
        struct hnbgw_context_map *map;
-       int new_scu_conn_id;
-       struct hnbgw_cnlink *cnlink;
-       struct hnbgw_sccp_user *hsu;

        llist_for_each_entry(map, &hnb->map_list, hnb_list) {
                if (map->is_ps != is_ps)
@@ -77,51 +73,58 @@
                /* Already exists */
                return map;
        }
+       return NULL;
+}

-       /* Does not exist yet, create a new hnbgw_context_map. */
+struct hnbgw_context_map *context_map_alloc(struct hnb_context *hnb, uint32_t 
rua_ctx_id, bool is_ps)
+{
+       struct hnbgw_context_map *map;

-       /* From the RANAP/RUA input, determine which cnlink to use */
-       cnlink = hnbgw_cnlink_select(is_ps);
-       if (!cnlink) {
-               LOGHNB(hnb, DMAIN, LOGL_ERROR, "Failed to select CN link\n");
-               return NULL;
-       }
-
-       /* Allocate new SCCP conn id on the SCCP instance the cnlink is on. */
-       hsu = cnlink->hnbgw_sccp_user;
-       if (!hsu) {
-               LOGHNB(hnb, DMAIN, LOGL_ERROR, "Cannot allocate context map: No 
SCCP instance for CN link %s\n",
-                      cnlink->name);
-               return NULL;
-       }
-
-       new_scu_conn_id = osmo_sccp_instance_next_conn_id(hsu->ss7->sccp);
-       if (new_scu_conn_id < 0) {
-               LOGHNB(hnb, DMAIN, LOGL_ERROR, "Unable to allocate SCCP conn ID 
on %s\n", hsu->name);
-               return NULL;
-       }
-
-       /* allocate a new map entry. */
+       /* allocate a new map entry now, so we have logging context */
        map = talloc_zero(hnb, struct hnbgw_context_map);
-       map->cnlink = cnlink;
        map->hnb_ctx = hnb;
        map->rua_ctx_id = rua_ctx_id;
        map->is_ps = is_ps;
-       map->scu_conn_id = new_scu_conn_id;
        INIT_LLIST_HEAD(&map->ps_rab_ass);
        INIT_LLIST_HEAD(&map->ps_rabs);

        map_rua_fsm_alloc(map);
-       map_sccp_fsm_alloc(map);

        llist_add_tail(&map->hnb_list, &hnb->map_list);
-       llist_add_tail(&map->hnbgw_cnlink_entry, &cnlink->map_list);
+
+       LOG_MAP(map, DRUA, LOGL_INFO, "New RUA CTX\n");
+       return map;
+}
+
+int context_map_set_cnlink(struct hnbgw_context_map *map, struct hnbgw_cnlink 
*cnlink_selected)
+{
+       int new_scu_conn_id;
+       struct hnbgw_sccp_user *hsu;
+
+       /* Allocate new SCCP conn id on the SCCP instance the cnlink is on. */
+       hsu = cnlink_selected->hnbgw_sccp_user;
+       if (!hsu) {
+               LOG_MAP(map, DCN, LOGL_ERROR, "Cannot map RUA context to SCCP: 
No SCCP instance for CN link %s\n",
+                        cnlink_selected->name);
+               return -EIO;
+       }
+
+       new_scu_conn_id = osmo_sccp_instance_next_conn_id(hsu->ss7->sccp);
+       if (new_scu_conn_id < 0) {
+               LOG_MAP(map, DCN, LOGL_ERROR, "Unable to allocate SCCP conn ID 
on %s\n", hsu->name);
+               return new_scu_conn_id;
+       }
+
+       map->cnlink = cnlink_selected;
+       map->scu_conn_id = new_scu_conn_id;
+       llist_add_tail(&map->hnbgw_cnlink_entry, &cnlink_selected->map_list);
+
        hash_add(hsu->hnbgw_context_map_by_conn_id, 
&map->hnbgw_sccp_user_entry, new_scu_conn_id);

-       LOG_MAP(map, DMAIN, LOGL_INFO, "Creating new Mapping RUA CTX %u <-> SCU 
Conn ID %s/%u\n",
-               rua_ctx_id, hsu->name, new_scu_conn_id);
+       LOG_MAP(map, DMAIN, LOGL_INFO, "Creating new Mapping RUA CTX %u <-> SCU 
Conn ID %u to %s on %s\n",
+               map->rua_ctx_id, new_scu_conn_id, cnlink_selected->name, 
hsu->name);

-       return map;
+       return 0;
 }

 int _map_rua_dispatch(struct hnbgw_context_map *map, uint32_t event, struct 
msgb *ranap_msg,
diff --git a/src/osmo-hnbgw/hnbgw_rua.c b/src/osmo-hnbgw/hnbgw_rua.c
index 8157cfc..abda5ea 100644
--- a/src/osmo-hnbgw/hnbgw_rua.c
+++ b/src/osmo-hnbgw/hnbgw_rua.c
@@ -33,7 +33,7 @@

 #include "asn1helpers.h"

-#include <osmocom/hnbgw/hnbgw.h>
+#include <osmocom/hnbgw/hnbgw_cn.h>
 #include <osmocom/hnbgw/hnbgw_ranap.h>
 #include <osmocom/rua/rua_common.h>
 #include <osmocom/rua/rua_ies_defs.h>
@@ -189,6 +189,44 @@
        return get_value_string(rua_procedure_code_names, val);
 }

+static struct hnbgw_context_map *find_or_create_context_map(struct hnb_context 
*hnb, uint32_t rua_ctx_id, bool is_ps,
+                                                           struct msgb 
*ranap_msg)
+{
+       struct hnbgw_context_map *map;
+       struct hnbgw_cnlink *cnlink;
+
+       map = context_map_find_by_rua_ctx_id(hnb, rua_ctx_id, is_ps);
+       if (map) {
+               /* Already established SCCP link. Continue to use that. */
+               return map;
+       }
+
+       /* Establish a new context map. From the RUA Connect, extract a mobile 
identity, if any, and select a CN link
+        * based on an NRI found in the mobile identity, if any. */
+
+       /* Allocate a map for logging context */
+       map = context_map_alloc(hnb, rua_ctx_id, is_ps);
+       OSMO_ASSERT(map);
+
+       /* FUTURE: extract mobile identity and store in map-> */
+
+       cnlink = hnbgw_cnlink_select(map);
+       if (!cnlink) {
+               LOG_MAP(map, DCN, LOGL_ERROR, "Failed to select %s link\n", 
is_ps ? "IuPS" : "IuCS");
+               context_map_free(map);
+               return NULL;
+       }
+
+       if (context_map_set_cnlink(map, cnlink)) {
+               LOG_MAP(map, DCN, LOGL_ERROR, "Failed to establish link to 
%s\n", cnlink->name);
+               context_map_free(map);
+               return NULL;
+       }
+
+       LOG_MAP(map, DCN, LOGL_INFO, "establishing SCCP link: selected %s\n", 
cnlink->name);
+       return map;
+}
+
 /* dispatch a RUA connection-oriented message received from a HNB to a context 
mapping's RUA FSM, so that it is
  * forwarded to the CN via SCCP connection-oriented messages.
  * Connectionless messages are handled in hnbgw_ranap_rx() instead, not here. 
*/
@@ -224,7 +262,7 @@
                memcpy(ranap_msg->l2h, data, len);
        }

-       map = context_map_find_or_create_by_rua_ctx_id(hnb, context_id, is_ps);
+       map = find_or_create_context_map(hnb, context_id, is_ps, ranap_msg);
        if (!map) {
                LOGHNB(hnb, DRUA, LOGL_ERROR,
                       "Failed to create context map for %s: rx RUA %s with %u 
bytes RANAP data\n",

--
To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/33127
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-hnbgw
Gerrit-Branch: master
Gerrit-Change-Id: Ifc5242547260154eb5aecd3a9d9c2aac8419e8db
Gerrit-Change-Number: 33127
Gerrit-PatchSet: 2
Gerrit-Owner: neels <nhofm...@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <lafo...@osmocom.org>
Gerrit-Reviewer: neels <nhofm...@sysmocom.de>
Gerrit-Reviewer: pespin <pes...@sysmocom.de>
Gerrit-MessageType: merged

Reply via email to