cnpool: allow separate cs7 for IuPS and IuCS
Prepare for CN pooling; allow using separate SS7 instances for IuCS and IuPS. New struct hnbgw_sccp_user describes a RANAP SCCP user, one per cs7. Limit struct hnbgw_cnlink to describing a CN peer, using whichever SCCP instance that is indicated by hnbgw_sccp_user. Chart sccp.dot shows the changes made. Related: SYS#6412 Change-Id: Iea1824f1c586723d989c80a909bae16bd2866e08
This commit is contained in:
parent
e96b52b158
commit
f3caea850b
|
@ -9,29 +9,50 @@ labelloc=t; label="SCCP/SS7 use in OsmoHNBGW"
|
|||
ss0 -> ss0ab
|
||||
|
||||
msc0a [label="2.2.2"]
|
||||
sgsn0a [label="3.3.3"]
|
||||
ss0ab -> msc0a,sgsn0a
|
||||
ss0ab -> msc0a
|
||||
}
|
||||
|
||||
iucs_addr [label=".iucs_addr -> 2.2.2"]
|
||||
iups_addr [label=".iups_addr -> 3.3.3"]
|
||||
msc0a -> iucs_addr [dir=back]
|
||||
sgsn0a -> iups_addr [dir=back]
|
||||
cnlink [label="hnbgw_cnlink (singleton)\n .osmo_sccp_instance\n .osmo_ss7_user SSN: RANAP"];
|
||||
ss0 -> cnlink [dir=back]
|
||||
sccp0 [label="hnbgw_sccp_user for '0'\n .osmo_ss7_instance 0\n .osmo_sccp_user SSN: RANAP\n PC: ss7 primary = 1.1.1"];
|
||||
ss0 -> sccp0 [dir=back]
|
||||
|
||||
msc0 [label="hnbgw_cnlink for IuCS\n .remote_addr -> 2.2.2"]
|
||||
sccp0 -> msc0 [dir=back]
|
||||
msc0a -> msc0 [dir=back]
|
||||
|
||||
cs0 [label="UE CS conn\n hnbgw_context_map"]
|
||||
cs1 [label="UE CS conn\n hnbgw_context_map"]
|
||||
msc0 -> cs0,cs1
|
||||
|
||||
subgraph cluster_ss1 {
|
||||
label=""
|
||||
ss1 [label="cs7 instance 1\n local pc: 4.4.4"]
|
||||
ss1ab [label="address book"]
|
||||
ss1 -> ss1ab
|
||||
|
||||
sgsn0a [label="3.3.3"]
|
||||
ss1ab -> sgsn0a
|
||||
}
|
||||
|
||||
sccp1 [label="hnbgw_sccp_user for '1'\n .osmo_ss7_instance 1\n .osmo_sccp_user SSN: RANAP\n PC: ss7 primary = 4.4.4"];
|
||||
ss1 -> sccp1 [dir=back]
|
||||
|
||||
sgsn0 [label="hnbgw_cnlink for IuPS\n .remote_addr -> 3.3.3"]
|
||||
sccp1 -> sgsn0 [dir=back]
|
||||
sgsn0a -> sgsn0 [dir=back]
|
||||
|
||||
ps0 [label="UE PS conn\n hnbgw_context_map"]
|
||||
ps1 [label="UE PS conn\n hnbgw_context_map"]
|
||||
cnlink -> cs0,cs1,ps0,ps1
|
||||
iucs_addr -> cs0,cs1 [style=dotted,dir=none]
|
||||
iups_addr -> ps0,ps1 [style=dotted,dir=none]
|
||||
sgsn0 -> ps0,ps1
|
||||
|
||||
subgraph cluster_sccp_inst {
|
||||
label="global sccp.users (llist)"
|
||||
sccp0
|
||||
sccp1
|
||||
}
|
||||
|
||||
subgraph cluster_hnbgw {
|
||||
label="global hnb_gw"
|
||||
cnlink
|
||||
iucs_addr
|
||||
iups_addr
|
||||
label="global hnbgw"
|
||||
msc0
|
||||
sgsn0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,11 +74,14 @@ struct hnbgw_cnlink;
|
|||
|
||||
struct hnbgw_context_map {
|
||||
/* entry in the per-CN list of mappings */
|
||||
struct llist_head cn_list;
|
||||
struct llist_head hnbgw_cnlink_entry;
|
||||
/* entry in the per-HNB list of mappings. If hnb_ctx == NULL, then this llist entry has been llist_del()eted and
|
||||
* must not be used. */
|
||||
struct llist_head hnb_list;
|
||||
|
||||
/* entry in the per-SCCP-conn-id hashtable */
|
||||
struct hlist_node hnbgw_sccp_user_entry;
|
||||
|
||||
/* Pointer to HNB for this map, to transceive RUA. If the HNB has disconnected without releasing the RUA
|
||||
* context, this is NULL. */
|
||||
struct hnb_context *hnb_ctx;
|
||||
|
@ -88,7 +91,7 @@ struct hnbgw_context_map {
|
|||
struct osmo_fsm_inst *rua_fi;
|
||||
|
||||
/* Pointer to CN, to transceive SCCP. */
|
||||
struct hnbgw_cnlink *cn_link;
|
||||
struct hnbgw_cnlink *cnlink;
|
||||
/* SCCP User SAP connection ID used in SCCP messages to/from the cn_link. */
|
||||
uint32_t scu_conn_id;
|
||||
/* FSM handling the SCCP state for scu_conn_id. */
|
||||
|
@ -133,17 +136,12 @@ enum hnbgw_context_map_state context_map_get_state(struct hnbgw_context_map *map
|
|||
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_alloc_by_hnb(struct hnb_context *hnb, uint32_t rua_ctx_id,
|
||||
bool is_ps,
|
||||
struct hnbgw_cnlink *cn_if_new);
|
||||
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);
|
||||
|
||||
void map_rua_fsm_alloc(struct hnbgw_context_map *map);
|
||||
void map_sccp_fsm_alloc(struct hnbgw_context_map *map);
|
||||
|
||||
struct hnbgw_context_map *
|
||||
context_map_by_cn(struct hnbgw_cnlink *cn, uint32_t scu_conn_id);
|
||||
|
||||
void context_map_hnb_released(struct hnbgw_context_map *map);
|
||||
|
||||
#define map_rua_dispatch(MAP, EVENT, MSGB) \
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/hashtable.h>
|
||||
#include <osmocom/core/write_queue.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/sigtran/sccp_sap.h>
|
||||
#include <osmocom/sigtran/osmo_ss7.h>
|
||||
#include <osmocom/ctrl/control_if.h>
|
||||
#include <osmocom/ranap/RANAP_CN-DomainIndicator.h>
|
||||
|
||||
#define DEBUG
|
||||
#include <osmocom/core/logging.h>
|
||||
|
||||
|
@ -29,6 +32,9 @@ extern struct vty_app_info hnbgw_vty_info;
|
|||
#define LOGHNB(HNB_CTX, ss, lvl, fmt, args ...) \
|
||||
LOGP(ss, lvl, "(%s) " fmt, hnb_context_name(HNB_CTX), ## args)
|
||||
|
||||
#define DOMAIN_CS RANAP_CN_DomainIndicator_cs_domain
|
||||
#define DOMAIN_PS RANAP_CN_DomainIndicator_ps_domain
|
||||
|
||||
enum hnb_ctrl_node {
|
||||
CTRL_NODE_HNB = _LAST_CTRL_NODE,
|
||||
_LAST_CTRL_NODE_HNB
|
||||
|
@ -40,6 +46,10 @@ enum hnb_ctrl_node {
|
|||
#define HNBGW_IUCS_REMOTE_IP_DEFAULT "127.0.0.1"
|
||||
#define HNBGW_IUPS_REMOTE_IP_DEFAULT "127.0.0.1"
|
||||
|
||||
#define DEFAULT_PC_HNBGW ((23 << 3) + 5)
|
||||
#define DEFAULT_PC_MSC ((23 << 3) + 1)
|
||||
#define DEFAULT_PC_SGSN ((23 << 3) + 4)
|
||||
|
||||
/* 25.467 Section 7.1 */
|
||||
#define IUH_DEFAULT_SCTP_PORT 29169
|
||||
#define RNA_DEFAULT_SCTP_PORT 25471
|
||||
|
@ -61,17 +71,79 @@ struct umts_cell_id {
|
|||
uint32_t cid; /*!< Cell ID */
|
||||
};
|
||||
|
||||
struct hnbgw_cnlink {
|
||||
struct llist_head list;
|
||||
/* osmo-hnbgw keeps a single hnbgw_sccp_user per osmo_sccp_instance, for the local point-code and SSN == RANAP.
|
||||
* This relates the (opaque) osmo_sccp_user to osmo-hnbgw's per-ss7 state. */
|
||||
struct hnbgw_sccp_user {
|
||||
/* entry in g_hnbgw->sccp.users */
|
||||
struct llist_head entry;
|
||||
|
||||
/* reference to the SCCP User SAP by which we communicate */
|
||||
struct osmo_sccp_instance *sccp;
|
||||
/* logging context */
|
||||
char *name;
|
||||
|
||||
/* Which 'cs7 instance' is this for? Below sccp_user is registered at the osmo_sccp_instance ss7->sccp. */
|
||||
struct osmo_ss7_instance *ss7;
|
||||
|
||||
/* Local address: cs7 instance's primary PC if present, else the default HNBGW PC; with SSN == RANAP. */
|
||||
struct osmo_sccp_addr local_addr;
|
||||
|
||||
/* osmo_sccp API state for above local address on above ss7 instance. */
|
||||
struct osmo_sccp_user *sccp_user;
|
||||
|
||||
/* Fast access to the hnbgw_context_map responsible for a given SCCP conn_id of the ss7->sccp instance.
|
||||
* hlist_node: hnbgw_context_map->hnbgw_sccp_user_entry. */
|
||||
DECLARE_HASHTABLE(hnbgw_context_map_by_conn_id, 6);
|
||||
};
|
||||
|
||||
#define LOG_HSI(HNBGW_SCCP_INST, SUBSYS, LEVEL, FMT, ARGS...) \
|
||||
LOGP(SUBSYS, LEVEL, "(%s) " FMT, (HNBGW_SCCP_INST) ? (HNBGW_SCCP_INST)->name : "null", ##ARGS)
|
||||
|
||||
/* A CN peer, like MSC or SGSN. */
|
||||
struct hnbgw_cnlink {
|
||||
/* To print in logging/VTY */
|
||||
char *name;
|
||||
|
||||
/* IuCS or IuPS? */
|
||||
RANAP_CN_DomainIndicator_t domain;
|
||||
|
||||
/* cs7 address book entry to indicate both the remote point-code of the peer, as well as which cs7 instance to
|
||||
* use. */
|
||||
const char *remote_addr_name;
|
||||
|
||||
/* Copy of the address pointed at by remote_addr_name. */
|
||||
struct osmo_sccp_addr remote_addr;
|
||||
|
||||
/* The SCCP instance for the cs7 instance indicated by remote_addr_name. (Multiple hnbgw_cnlinks may use the
|
||||
* same hnbgw_sccp_user -- there is exactly one hnbgw_sccp_user per configured cs7 instance.) */
|
||||
struct hnbgw_sccp_user *hnbgw_sccp_user;
|
||||
|
||||
/* linked list of hnbgw_context_map */
|
||||
struct llist_head map_list;
|
||||
};
|
||||
|
||||
#define LOG_CNLINK(CNLINK, SUBSYS, LEVEL, FMT, ARGS...) \
|
||||
LOGP(SUBSYS, LEVEL, "(%s) " FMT, (CNLINK) ? (CNLINK)->name : "null", ##ARGS)
|
||||
|
||||
static inline bool cnlink_is_cs(const struct hnbgw_cnlink *cnlink)
|
||||
{
|
||||
return cnlink && cnlink->domain == DOMAIN_CS;
|
||||
}
|
||||
|
||||
static inline bool cnlink_is_ps(const struct hnbgw_cnlink *cnlink)
|
||||
{
|
||||
return cnlink && cnlink->domain == DOMAIN_PS;
|
||||
}
|
||||
|
||||
static inline struct osmo_sccp_instance *cnlink_sccp(const struct hnbgw_cnlink *cnlink)
|
||||
{
|
||||
if (!cnlink)
|
||||
return NULL;
|
||||
if (!cnlink->hnbgw_sccp_user)
|
||||
return NULL;
|
||||
if (!cnlink->hnbgw_sccp_user->ss7)
|
||||
return NULL;
|
||||
return cnlink->hnbgw_sccp_user->ss7->sccp;
|
||||
}
|
||||
|
||||
/* The lifecycle of the hnb_context object is the same as its conn */
|
||||
struct hnb_context {
|
||||
/*! Entry in HNB-global list of HNB */
|
||||
|
@ -139,11 +211,11 @@ struct hnbgw {
|
|||
struct ctrl_handle *ctrl;
|
||||
/* currently active CN links for CS and PS */
|
||||
struct {
|
||||
struct osmo_sccp_instance *client;
|
||||
struct hnbgw_cnlink *cnlink;
|
||||
struct osmo_sccp_addr local_addr;
|
||||
struct osmo_sccp_addr iucs_remote_addr;
|
||||
struct osmo_sccp_addr iups_remote_addr;
|
||||
/* List of hnbgw_sccp_user */
|
||||
struct llist_head users;
|
||||
/* FUTURE: cnlink_iucs, cnlink_iups will be replaced with llist cnpool. */
|
||||
struct hnbgw_cnlink *cnlink_iucs;
|
||||
struct hnbgw_cnlink *cnlink_iups;
|
||||
} sccp;
|
||||
/* MGW pool, also includes the single MGCP client as fallback if no
|
||||
* pool is configured. */
|
||||
|
|
|
@ -2,6 +2,12 @@
|
|||
|
||||
#include <osmocom/hnbgw/hnbgw.h>
|
||||
|
||||
int hnbgw_cnlink_init(const char *stp_host, uint16_t stp_port, const char *local_ip);
|
||||
struct hnbgw_cnlink *hnbgw_cnlink_alloc(const char *remote_addr_name, RANAP_CN_DomainIndicator_t domain);
|
||||
|
||||
const struct osmo_sccp_addr *hnbgw_cn_get_remote_addr(bool is_ps);
|
||||
|
||||
struct hnbgw_cnlink *hnbgw_cnlink_find_by_addr(const struct hnbgw_sccp_user *hsu,
|
||||
const struct osmo_sccp_addr *remote_addr);
|
||||
struct hnbgw_cnlink *hnbgw_cnlink_select(bool is_ps);
|
||||
|
||||
char *cnlink_sccp_addr_to_str(struct hnbgw_cnlink *cnlink, const struct osmo_sccp_addr *addr);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include <osmocom/sigtran/sccp_helpers.h>
|
||||
|
||||
#include <osmocom/hnbgw/hnbgw.h>
|
||||
#include <osmocom/hnbgw/hnbgw_cn.h>
|
||||
#include <osmocom/hnbgw/context_map.h>
|
||||
#include <osmocom/hnbgw/mgw_fsm.h>
|
||||
#include <osmocom/hnbgw/ps_rab_ass_fsm.h>
|
||||
|
@ -53,16 +53,16 @@ enum hnbgw_context_map_state context_map_get_state(struct hnbgw_context_map *map
|
|||
}
|
||||
|
||||
/* Map from a HNB + ContextID to the SCCP-side Connection ID */
|
||||
struct hnbgw_context_map *
|
||||
context_map_alloc_by_hnb(struct hnb_context *hnb, uint32_t rua_ctx_id,
|
||||
bool is_ps,
|
||||
struct hnbgw_cnlink *cn_if_new)
|
||||
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 *map;
|
||||
uint32_t 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->cn_link != cn_if_new)
|
||||
if (map->is_ps != is_ps)
|
||||
continue;
|
||||
|
||||
/* Matching on RUA context id -- only match for RUA context that has not been disconnected yet. If an
|
||||
|
@ -71,24 +71,39 @@ context_map_alloc_by_hnb(struct hnb_context *hnb, uint32_t rua_ctx_id,
|
|||
if (!map_rua_is_active(map))
|
||||
continue;
|
||||
|
||||
if (map->rua_ctx_id == rua_ctx_id
|
||||
&& map->is_ps == is_ps) {
|
||||
return map;
|
||||
}
|
||||
if (map->rua_ctx_id != rua_ctx_id)
|
||||
continue;
|
||||
|
||||
/* Already exists */
|
||||
return map;
|
||||
}
|
||||
|
||||
new_scu_conn_id = osmo_sccp_instance_next_conn_id(map->cn_link->sccp);
|
||||
if (new_scu_conn_id < 0) {
|
||||
LOGHNB(hnb, DMAIN, LOGL_ERROR, "Unable to allocate CN connection ID\n");
|
||||
/* Does not exist yet, create a new hnbgw_context_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;
|
||||
}
|
||||
|
||||
LOGHNB(hnb, DMAIN, LOGL_INFO, "Creating new Mapping RUA CTX %p/%u <-> SCU Conn ID %p/%u\n",
|
||||
hnb, rua_ctx_id, cn_if_new, new_scu_conn_id);
|
||||
/* 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. */
|
||||
map = talloc_zero(hnb, struct hnbgw_context_map);
|
||||
map->cn_link = cn_if_new;
|
||||
map->cnlink = cnlink;
|
||||
map->hnb_ctx = hnb;
|
||||
map->rua_ctx_id = rua_ctx_id;
|
||||
map->is_ps = is_ps;
|
||||
|
@ -99,9 +114,12 @@ context_map_alloc_by_hnb(struct hnb_context *hnb, uint32_t rua_ctx_id,
|
|||
map_rua_fsm_alloc(map);
|
||||
map_sccp_fsm_alloc(map);
|
||||
|
||||
/* put it into both lists */
|
||||
llist_add_tail(&map->hnb_list, &hnb->map_list);
|
||||
llist_add_tail(&map->cn_list, &cn_if_new->map_list);
|
||||
llist_add_tail(&map->hnbgw_cnlink_entry, &cnlink->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);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
@ -133,30 +151,6 @@ unsigned int msg_has_l2_data(const struct msgb *msg)
|
|||
return msg && msgb_l2(msg) ? msgb_l2len(msg) : 0;
|
||||
}
|
||||
|
||||
/* Map from a CN + Connection ID to HNB + Context ID */
|
||||
struct hnbgw_context_map *
|
||||
context_map_by_cn(struct hnbgw_cnlink *cn, uint32_t scu_conn_id)
|
||||
{
|
||||
struct hnbgw_context_map *map;
|
||||
|
||||
llist_for_each_entry(map, &cn->map_list, cn_list) {
|
||||
/* Matching on SCCP conn id -- only match for SCCP conn that has not been disconnected yet. If an
|
||||
* inactive context map for an scu_conn_id is still around, we may have two entries for the same
|
||||
* scu_conn_id around at the same time. That should only stay until its RUA side is done releasing. */
|
||||
if (!map_sccp_is_active(map))
|
||||
continue;
|
||||
|
||||
if (map->scu_conn_id == scu_conn_id) {
|
||||
return map;
|
||||
}
|
||||
}
|
||||
/* we don't allocate new mappings in the CN->HNB
|
||||
* direction, as the RUA=SCCP=SUA connections are always
|
||||
* established from HNB towards CN. */
|
||||
LOGP(DMAIN, LOGL_NOTICE, "Unable to resolve map for CN " "connection ID %p/%u\n", cn, scu_conn_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void context_map_hnb_released(struct hnbgw_context_map *map)
|
||||
{
|
||||
/* When a HNB disconnects from RUA, the hnb_context will be freed. This hnbgw_context_map was allocated as a
|
||||
|
@ -199,8 +193,10 @@ void context_map_free(struct hnbgw_context_map *map)
|
|||
hnbgw_gtpmap_release(map);
|
||||
#endif
|
||||
|
||||
if (map->cn_link)
|
||||
llist_del(&map->cn_list);
|
||||
if (map->cnlink) {
|
||||
llist_del(&map->hnbgw_cnlink_entry);
|
||||
hash_del(&map->hnbgw_sccp_user_entry);
|
||||
}
|
||||
if (map->hnb_ctx)
|
||||
llist_del(&map->hnb_list);
|
||||
|
||||
|
|
|
@ -124,6 +124,11 @@ static int tx_sccp_cr(struct osmo_fsm_inst *fi, struct msgb *ranap_msg)
|
|||
struct osmo_scu_prim *prim;
|
||||
int rc;
|
||||
|
||||
if (!map->cnlink || !map->cnlink->hnbgw_sccp_user) {
|
||||
LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP Connection Request: no CN link\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ranap_msg) {
|
||||
/* prepare a msgb to send an empty N-Connect prim (but this should never happen in practice) */
|
||||
ranap_msg = hnbgw_ranap_msg_alloc("SCCP-CR-empty");
|
||||
|
@ -132,13 +137,13 @@ static int tx_sccp_cr(struct osmo_fsm_inst *fi, struct msgb *ranap_msg)
|
|||
prim = (struct osmo_scu_prim *)msgb_push(ranap_msg, sizeof(*prim));
|
||||
osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, ranap_msg);
|
||||
prim->u.connect.called_addr = *hnbgw_cn_get_remote_addr(map->is_ps);
|
||||
prim->u.connect.calling_addr = g_hnbgw->sccp.local_addr;
|
||||
prim->u.connect.calling_addr = map->cnlink->hnbgw_sccp_user->local_addr;
|
||||
prim->u.connect.sccp_class = 2;
|
||||
prim->u.connect.conn_id = map->scu_conn_id;
|
||||
|
||||
rc = osmo_sccp_user_sap_down_nofree(map->cn_link->sccp_user, &prim->oph);
|
||||
rc = osmo_sccp_user_sap_down_nofree(map->cnlink->hnbgw_sccp_user->sccp_user, &prim->oph);
|
||||
if (rc)
|
||||
LOGPFSML(fi, LOGL_ERROR, "Failed to forward SCCP Connectoin Request to CN\n");
|
||||
LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP Connection Request to CN\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -151,20 +156,31 @@ static int tx_sccp_df1(struct osmo_fsm_inst *fi, struct msgb *ranap_msg)
|
|||
if (!msg_has_l2_data(ranap_msg))
|
||||
return 0;
|
||||
|
||||
if (!map->cnlink || !map->cnlink->hnbgw_sccp_user) {
|
||||
LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP Data Form 1: no CN link\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
prim = (struct osmo_scu_prim *)msgb_push(ranap_msg, sizeof(*prim));
|
||||
osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST, ranap_msg);
|
||||
prim->u.data.conn_id = map->scu_conn_id;
|
||||
|
||||
rc = osmo_sccp_user_sap_down_nofree(map->cn_link->sccp_user, &prim->oph);
|
||||
rc = osmo_sccp_user_sap_down_nofree(map->cnlink->hnbgw_sccp_user->sccp_user, &prim->oph);
|
||||
if (rc)
|
||||
LOGPFSML(fi, LOGL_ERROR, "Failed to forward SCCP Data Form 1 to CN\n");
|
||||
LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP Data Form 1 to CN\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int tx_sccp_rlsd(struct osmo_fsm_inst *fi)
|
||||
{
|
||||
struct hnbgw_context_map *map = fi->priv;
|
||||
return osmo_sccp_tx_disconn(map->cn_link->sccp_user, map->scu_conn_id, NULL, 0);
|
||||
|
||||
if (!map->cnlink || !map->cnlink->hnbgw_sccp_user) {
|
||||
LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP RLSD: no CN link\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return osmo_sccp_tx_disconn(map->cnlink->hnbgw_sccp_user->sccp_user, map->scu_conn_id, NULL, 0);
|
||||
}
|
||||
|
||||
static int destruct_ranap_ran_rx_co_ies(ranap_message *ranap_message_p)
|
||||
|
@ -468,7 +484,7 @@ static int map_sccp_fsm_timer_cb(struct osmo_fsm_inst *fi)
|
|||
/* send SCCP RLSD. libosmo-sigtran/sccp_scoc.c will do the SCCP connection cleanup.
|
||||
* (It will repeatedly send SCCP RLSD until the peer responded with SCCP RLC, or until the
|
||||
* sccp_connection->t_int timer expires, and the sccp_connection is freed.) */
|
||||
if (map->cn_link && map->cn_link->sccp_user)
|
||||
if (map->cnlink)
|
||||
tx_sccp_rlsd(fi);
|
||||
map_sccp_fsm_state_chg(MAP_SCCP_ST_DISCONNECTED);
|
||||
return 0;
|
||||
|
|
|
@ -51,6 +51,7 @@ void g_hnbgw_alloc(void *ctx)
|
|||
g_hnbgw->next_ue_ctx_id = 23;
|
||||
INIT_LLIST_HEAD(&g_hnbgw->hnb_list);
|
||||
INIT_LLIST_HEAD(&g_hnbgw->ue_list);
|
||||
INIT_LLIST_HEAD(&g_hnbgw->sccp.users);
|
||||
|
||||
g_hnbgw->mgw_pool = mgcp_client_pool_alloc(g_hnbgw);
|
||||
g_hnbgw->config.mgcp_client = talloc_zero(g_hnbgw, struct mgcp_client_conf);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include <osmocom/hnbgw/hnbgw.h>
|
||||
#include <osmocom/hnbgw/hnbgw_rua.h>
|
||||
#include <osmocom/hnbgw/hnbgw_cn.h>
|
||||
#include <osmocom/ranap/ranap_ies_defs.h>
|
||||
#include <osmocom/ranap/ranap_msg_factory.h>
|
||||
#include <osmocom/hnbgw/context_map.h>
|
||||
|
@ -47,33 +48,47 @@ static int transmit_rst(struct hnbgw_cnlink *cnlink)
|
|||
.choice. transmissionNetwork = RANAP_CauseTransmissionNetwork_signalling_transport_resource_failure,
|
||||
};
|
||||
|
||||
LOGP(DRANAP, LOGL_NOTICE, "Tx RESET to %s %s\n",
|
||||
domain == RANAP_CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS",
|
||||
osmo_sccp_inst_addr_name(g_hnbgw->sccp.cnlink->sccp, remote_addr));
|
||||
if (!cnlink)
|
||||
return -1;
|
||||
|
||||
msg = ranap_new_msg_reset(domain, &cause);
|
||||
if (!cnlink->hnbgw_sccp_user) {
|
||||
LOG_CNLINK(cnlink, DRANAP, LOGL_ERROR, "cannot send RANAP RESET: no CN link\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return osmo_sccp_tx_unitdata_msg(g_hnbgw->sccp.cnlink->sccp_user,
|
||||
&g_hnbgw->sccp.local_addr,
|
||||
remote_addr,
|
||||
LOG_CNLINK(cnlink, DRANAP, LOGL_NOTICE, "Tx RANAP RESET to %s %s\n",
|
||||
cnlink_is_cs(cnlink) ? "IuCS" : "IuPS",
|
||||
osmo_sccp_inst_addr_name(cnlink->hnbgw_sccp_user->sccp, &cnlink->remote_addr));
|
||||
|
||||
msg = ranap_new_msg_reset(cnlink->domain, &cause);
|
||||
|
||||
return osmo_sccp_tx_unitdata_msg(cnlink->hnbgw_sccp_user->sccp_user,
|
||||
&cnlink->local_addr,
|
||||
&cnlink->remote_addr,
|
||||
msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int transmit_reset_ack(RANAP_CN_DomainIndicator_t domain,
|
||||
const struct osmo_sccp_addr *remote_addr)
|
||||
static int transmit_reset_ack(struct hnbgw_cnlink *cnlink)
|
||||
{
|
||||
struct msgb *msg;
|
||||
struct osmo_sccp_instance *sccp = cnlink_sccp(cnlink);
|
||||
|
||||
LOGP(DRANAP, LOGL_NOTICE, "Tx RESET ACK to %s %s\n",
|
||||
domain == RANAP_CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS",
|
||||
osmo_sccp_inst_addr_name(g_hnbgw->sccp.cnlink->sccp, remote_addr));
|
||||
if (!sccp) {
|
||||
LOG_CNLINK(cnlink, DRANAP, LOGL_ERROR, "cannot send RANAP RESET ACK: no CN link\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg = ranap_new_msg_reset_ack(domain, NULL);
|
||||
LOG_CNLINK(cnlink, DRANAP, LOGL_NOTICE, "Tx RANAP RESET ACK %s %s --> %s\n",
|
||||
cnlink_is_cs(cnlink) ? "IuCS" : "IuPS",
|
||||
cnlink_sccp_addr_to_str(cnlink, &cnlink->hnbgw_sccp_user->local_addr),
|
||||
cnlink_sccp_addr_to_str(cnlink, &cnlink->remote_addr));
|
||||
|
||||
return osmo_sccp_tx_unitdata_msg(g_hnbgw->sccp.cnlink->sccp_user,
|
||||
&g_hnbgw->sccp.local_addr,
|
||||
remote_addr,
|
||||
msg = ranap_new_msg_reset_ack(cnlink->domain, NULL);
|
||||
|
||||
return osmo_sccp_tx_unitdata_msg(cnlink->hnbgw_sccp_user->sccp_user,
|
||||
&cnlink->hnbgw_sccp_user->local_addr,
|
||||
&cnlink->remote_addr,
|
||||
msg);
|
||||
}
|
||||
|
||||
|
@ -93,16 +108,16 @@ static int cn_ranap_rx_reset_cmd(struct hnbgw_cnlink *cnlink,
|
|||
domain = ies.cN_DomainIndicator;
|
||||
ranap_free_reseties(&ies);
|
||||
|
||||
LOGP(DRANAP, LOGL_NOTICE, "Rx RESET from %s %s, returning ACK\n",
|
||||
domain == RANAP_CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS",
|
||||
osmo_sccp_inst_addr_name(cnlink->sccp, &unitdata->calling_addr));
|
||||
LOG_CNLINK(cnlink, DRANAP, LOGL_NOTICE, "Rx RESET from %s %s, returning ACK\n",
|
||||
domain == DOMAIN_CS ? "IuCS" : "IuPS",
|
||||
osmo_sccp_inst_addr_name(cnlink_sccp(cnlink), &unitdata->calling_addr));
|
||||
|
||||
/* FIXME: actually reset connections, if any */
|
||||
|
||||
if (transmit_reset_ack(domain, &unitdata->calling_addr))
|
||||
if (transmit_reset_ack(cnlink))
|
||||
LOGP(DRANAP, LOGL_ERROR, "Error: cannot send RESET ACK to %s %s\n",
|
||||
domain == RANAP_CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS",
|
||||
osmo_sccp_inst_addr_name(cnlink->sccp, &unitdata->calling_addr));
|
||||
domain == DOMAIN_CS ? "IuCS" : "IuPS",
|
||||
osmo_sccp_inst_addr_name(cnlink_sccp(cnlink), &unitdata->calling_addr));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -246,101 +261,94 @@ static int handle_cn_ranap(struct hnbgw_cnlink *cnlink, const struct osmo_scu_un
|
|||
return rc;
|
||||
}
|
||||
|
||||
static bool pc_and_ssn_match(const struct osmo_sccp_addr *a, const struct osmo_sccp_addr *b)
|
||||
static struct hnbgw_cnlink *cnlink_from_addr(struct hnbgw_sccp_user *hsu, const struct osmo_sccp_addr *calling_addr,
|
||||
const struct osmo_prim_hdr *oph)
|
||||
{
|
||||
return (a == b)
|
||||
|| ((a->pc == b->pc)
|
||||
&& (a->ssn == b->ssn));
|
||||
struct hnbgw_cnlink *cnlink = NULL;
|
||||
cnlink = hnbgw_cnlink_find_by_addr(hsu, calling_addr);
|
||||
if (!cnlink) {
|
||||
LOG_HSI(hsu, DRANAP, LOGL_ERROR, "Rx from unknown SCCP peer: %s: %s\n",
|
||||
osmo_sccp_inst_addr_name(hsu->ss7->sccp, calling_addr),
|
||||
osmo_scu_prim_hdr_name_c(OTC_SELECT, oph));
|
||||
return NULL;
|
||||
}
|
||||
return cnlink;
|
||||
}
|
||||
|
||||
static int classify_cn_remote_addr(const struct osmo_sccp_addr *cn_remote_addr,
|
||||
bool *is_ps)
|
||||
static struct hnbgw_context_map *map_from_conn_id(struct hnbgw_sccp_user *hsu, uint32_t conn_id,
|
||||
const struct osmo_prim_hdr *oph)
|
||||
{
|
||||
if (pc_and_ssn_match(cn_remote_addr, &g_hnbgw->sccp.iucs_remote_addr)) {
|
||||
if (is_ps)
|
||||
*is_ps = false;
|
||||
return 0;
|
||||
}
|
||||
if (pc_and_ssn_match(cn_remote_addr, &g_hnbgw->sccp.iups_remote_addr)) {
|
||||
if (is_ps)
|
||||
*is_ps = true;
|
||||
return 0;
|
||||
}
|
||||
LOGP(DMAIN, LOGL_ERROR, "Unexpected remote address, matches neither CS nor PS address: %s\n",
|
||||
osmo_sccp_addr_dump(cn_remote_addr));
|
||||
return -1;
|
||||
struct hnbgw_context_map *map;
|
||||
hash_for_each_possible(hsu->hnbgw_context_map_by_conn_id, map, hnbgw_sccp_user_entry, conn_id)
|
||||
return map;
|
||||
LOGP(DRANAP, LOGL_ERROR, "Rx for unknown SCCP connection ID: %u: %s\n",
|
||||
conn_id, osmo_scu_prim_hdr_name_c(OTC_SELECT, oph));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int handle_cn_unitdata(struct hnbgw_cnlink *cnlink,
|
||||
static int handle_cn_unitdata(struct hnbgw_sccp_user *hsu,
|
||||
const struct osmo_scu_unitdata_param *param,
|
||||
struct osmo_prim_hdr *oph)
|
||||
{
|
||||
struct hnbgw_cnlink *cnlink = cnlink_from_addr(hsu, ¶m->calling_addr, oph);
|
||||
if (!cnlink)
|
||||
return -ENOENT;
|
||||
|
||||
if (param->called_addr.ssn != OSMO_SCCP_SSN_RANAP) {
|
||||
LOGP(DMAIN, LOGL_NOTICE, "N-UNITDATA.ind for unknown SSN %u\n",
|
||||
param->called_addr.ssn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (classify_cn_remote_addr(¶m->calling_addr, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
return handle_cn_ranap(cnlink, param, msgb_l2(oph->msg), msgb_l2len(oph->msg));
|
||||
}
|
||||
|
||||
static int handle_cn_conn_conf(struct hnbgw_cnlink *cnlink,
|
||||
static int handle_cn_conn_conf(struct hnbgw_sccp_user *hsu,
|
||||
const struct osmo_scu_connect_param *param,
|
||||
struct osmo_prim_hdr *oph)
|
||||
{
|
||||
struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(g_hnbgw->sccp.client);
|
||||
struct hnbgw_context_map *map;
|
||||
|
||||
map = map_from_conn_id(hsu, param->conn_id, oph);
|
||||
if (!map || !map->cnlink)
|
||||
return -ENOENT;
|
||||
|
||||
LOGP(DMAIN, LOGL_DEBUG, "handle_cn_conn_conf() conn_id=%d, addrs: called=%s calling=%s responding=%s\n",
|
||||
param->conn_id,
|
||||
osmo_sccp_addr_to_str_c(OTC_SELECT, ss7, ¶m->called_addr),
|
||||
osmo_sccp_addr_to_str_c(OTC_SELECT, ss7, ¶m->calling_addr),
|
||||
osmo_sccp_addr_to_str_c(OTC_SELECT, ss7, ¶m->responding_addr));
|
||||
|
||||
map = context_map_by_cn(cnlink, param->conn_id);
|
||||
if (!map) {
|
||||
/* We have no such SCCP connection. Ignore. */
|
||||
return 0;
|
||||
}
|
||||
cnlink_sccp_addr_to_str(map->cnlink, ¶m->called_addr),
|
||||
cnlink_sccp_addr_to_str(map->cnlink, ¶m->calling_addr),
|
||||
cnlink_sccp_addr_to_str(map->cnlink, ¶m->responding_addr));
|
||||
|
||||
map_sccp_dispatch(map, MAP_SCCP_EV_RX_CONNECTION_CONFIRM, oph->msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_cn_data_ind(struct hnbgw_cnlink *cnlink,
|
||||
static int handle_cn_data_ind(struct hnbgw_sccp_user *hsu,
|
||||
const struct osmo_scu_data_param *param,
|
||||
struct osmo_prim_hdr *oph)
|
||||
{
|
||||
struct hnbgw_context_map *map;
|
||||
|
||||
map = context_map_by_cn(cnlink, param->conn_id);
|
||||
if (!map) {
|
||||
/* We have no such SCCP connection. Ignore. */
|
||||
return 0;
|
||||
}
|
||||
map = map_from_conn_id(hsu, param->conn_id, oph);
|
||||
if (!map || !map->cnlink)
|
||||
return -ENOENT;
|
||||
|
||||
return map_sccp_dispatch(map, MAP_SCCP_EV_RX_DATA_INDICATION, oph->msg);
|
||||
}
|
||||
|
||||
static int handle_cn_disc_ind(struct hnbgw_cnlink *cnlink,
|
||||
static int handle_cn_disc_ind(struct hnbgw_sccp_user *hsu,
|
||||
const struct osmo_scu_disconn_param *param,
|
||||
struct osmo_prim_hdr *oph)
|
||||
{
|
||||
struct hnbgw_context_map *map;
|
||||
|
||||
LOGP(DMAIN, LOGL_DEBUG, "handle_cn_disc_ind() conn_id=%d originator=%d\n",
|
||||
param->conn_id, param->originator);
|
||||
LOGP(DMAIN, LOGL_DEBUG, "handle_cn_disc_ind() responding_addr=%s\n",
|
||||
inet_ntoa(param->responding_addr.ip.v4));
|
||||
map = map_from_conn_id(hsu, param->conn_id, oph);
|
||||
if (!map || !map->cnlink)
|
||||
return -ENOENT;
|
||||
|
||||
map = context_map_by_cn(cnlink, param->conn_id);
|
||||
if (!map) {
|
||||
/* We have no connection. Ignore. */
|
||||
return 0;
|
||||
}
|
||||
LOGP(DMAIN, LOGL_DEBUG, "handle_cn_disc_ind() conn_id=%u responding_addr=%s\n",
|
||||
param->conn_id,
|
||||
cnlink_sccp_addr_to_str(map->cnlink, ¶m->responding_addr));
|
||||
|
||||
return map_sccp_dispatch(map, MAP_SCCP_EV_RX_RELEASED, oph->msg);
|
||||
}
|
||||
|
@ -349,7 +357,7 @@ static int handle_cn_disc_ind(struct hnbgw_cnlink *cnlink,
|
|||
static int sccp_sap_up(struct osmo_prim_hdr *oph, void *ctx)
|
||||
{
|
||||
struct osmo_sccp_user *scu = ctx;
|
||||
struct hnbgw_cnlink *cnlink;
|
||||
struct hnbgw_sccp_user *hsu;
|
||||
struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph;
|
||||
int rc = 0;
|
||||
|
||||
|
@ -362,10 +370,10 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *ctx)
|
|||
return -1;
|
||||
}
|
||||
|
||||
cnlink = osmo_sccp_user_get_priv(scu);
|
||||
if (!cnlink) {
|
||||
hsu = osmo_sccp_user_get_priv(scu);
|
||||
if (!hsu) {
|
||||
LOGP(DMAIN, LOGL_ERROR,
|
||||
"sccp_sap_up(): NULL hnbgw_cnlink, cannot send prim (sap %u prim %u op %d)\n",
|
||||
"sccp_sap_up(): NULL hnbgw_sccp_user, cannot send prim (sap %u prim %u op %d)\n",
|
||||
oph->sap, oph->primitive, oph->operation);
|
||||
return -1;
|
||||
}
|
||||
|
@ -374,16 +382,16 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *ctx)
|
|||
|
||||
switch (OSMO_PRIM_HDR(oph)) {
|
||||
case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION):
|
||||
rc = handle_cn_unitdata(cnlink, &prim->u.unitdata, oph);
|
||||
rc = handle_cn_unitdata(hsu, &prim->u.unitdata, oph);
|
||||
break;
|
||||
case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM):
|
||||
rc = handle_cn_conn_conf(cnlink, &prim->u.connect, oph);
|
||||
rc = handle_cn_conn_conf(hsu, &prim->u.connect, oph);
|
||||
break;
|
||||
case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION):
|
||||
rc = handle_cn_data_ind(cnlink, &prim->u.data, oph);
|
||||
rc = handle_cn_data_ind(hsu, &prim->u.data, oph);
|
||||
break;
|
||||
case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION):
|
||||
rc = handle_cn_disc_ind(cnlink, &prim->u.disconnect, oph);
|
||||
rc = handle_cn_disc_ind(hsu, &prim->u.disconnect, oph);
|
||||
break;
|
||||
case OSMO_PRIM(OSMO_SCU_PRIM_N_PCSTATE, PRIM_OP_INDICATION):
|
||||
LOGP(DMAIN, LOGL_DEBUG, "Ignoring prim %s from SCCP USER SAP\n",
|
||||
|
@ -412,8 +420,6 @@ static int resolve_addr_name(struct osmo_sccp_addr *dest, struct osmo_ss7_instan
|
|||
const char *addr_name, const char *label,
|
||||
uint32_t default_pc)
|
||||
{
|
||||
struct osmo_ss7_instance *ss7_tmp;
|
||||
|
||||
if (!addr_name) {
|
||||
osmo_sccp_make_addr_pc_ssn(dest, default_pc, OSMO_SCCP_SSN_RANAP);
|
||||
LOGP(DMAIN, LOGL_INFO, "%s remote addr not configured, using default: %s\n", label,
|
||||
|
@ -421,21 +427,13 @@ static int resolve_addr_name(struct osmo_sccp_addr *dest, struct osmo_ss7_instan
|
|||
return 0;
|
||||
}
|
||||
|
||||
ss7_tmp = osmo_sccp_addr_by_name(dest, addr_name);
|
||||
if (!ss7_tmp) {
|
||||
*ss7 = osmo_sccp_addr_by_name(dest, addr_name);
|
||||
if (!*ss7) {
|
||||
LOGP(DMAIN, LOGL_ERROR, "%s remote addr: no such SCCP address book entry: '%s'\n",
|
||||
label, addr_name);
|
||||
label, addr_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*ss7 && (*ss7 != ss7_tmp)) {
|
||||
LOGP(DMAIN, LOGL_ERROR, "IuCS and IuPS cannot be served from separate CS7 instances,"
|
||||
" cs7 instance %d != %d\n", (*ss7)->cfg.id, ss7_tmp->cfg.id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*ss7 = ss7_tmp;
|
||||
|
||||
osmo_sccp_addr_set_ssn(dest, OSMO_SCCP_SSN_RANAP);
|
||||
|
||||
if (!addr_has_pc_and_ssn(dest)) {
|
||||
|
@ -449,74 +447,197 @@ static int resolve_addr_name(struct osmo_sccp_addr *dest, struct osmo_ss7_instan
|
|||
return 0;
|
||||
}
|
||||
|
||||
int hnbgw_cnlink_init(const char *stp_host, uint16_t stp_port, const char *local_ip)
|
||||
/* If not present yet, set up all of osmo_ss7_instance, osmo_sccp_instance and hnbgw_sccp_user for the given cnlink.
|
||||
* The cs7 instance nr to use is determined by cnlink->remote_addr_name, or cs7 instance 0 if that is not present.
|
||||
* Set cnlink->hnbgw_sccp_user to the new SCCP instance. Return 0 on success, negative on error. */
|
||||
int cnlink_ensure_sccp(struct hnbgw_cnlink *cnlink)
|
||||
{
|
||||
struct hnbgw_cnlink *cnlink;
|
||||
struct osmo_ss7_instance *ss7;
|
||||
struct osmo_ss7_instance *ss7 = NULL;
|
||||
struct osmo_sccp_instance *sccp;
|
||||
struct osmo_sccp_user *sccp_user;
|
||||
uint32_t local_pc;
|
||||
struct hnbgw_sccp_user *hsu;
|
||||
|
||||
OSMO_ASSERT(!g_hnbgw->sccp.client);
|
||||
OSMO_ASSERT(!g_hnbgw->sccp.cnlink);
|
||||
/* If a hnbgw_sccp_user has already been set up, use that. */
|
||||
if (cnlink->hnbgw_sccp_user) {
|
||||
LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "SCCP instance already set up, using %s\n",
|
||||
cnlink->hnbgw_sccp_user->name);
|
||||
return 0;
|
||||
}
|
||||
LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "no SCCP instance selected yet\n");
|
||||
|
||||
ss7 = NULL;
|
||||
if (resolve_addr_name(&g_hnbgw->sccp.iucs_remote_addr, &ss7,
|
||||
g_hnbgw->config.iucs_remote_addr_name, "IuCS", (23 << 3) + 1))
|
||||
return -1;
|
||||
if (resolve_addr_name(&g_hnbgw->sccp.iups_remote_addr, &ss7,
|
||||
g_hnbgw->config.iups_remote_addr_name, "IuPS", (23 << 3) + 4))
|
||||
return -1;
|
||||
/* Figure out which cs7 instance to use. If cnlink->remote_addr_name is set, it points to an address book entry
|
||||
* in a specific cs7 instance. If it is not set, leave ss7 == NULL to use cs7 instance 0. */
|
||||
if (cnlink->remote_addr_name) {
|
||||
LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "resolving 'remote-addr %s'\n", cnlink->remote_addr_name);
|
||||
if (resolve_addr_name(&cnlink->remote_addr, &ss7, cnlink->remote_addr_name, cnlink->name,
|
||||
DEFAULT_PC_HNBGW)) {
|
||||
LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "cannot initialize SCCP: there is no SCCP address named '%s'\n",
|
||||
cnlink->remote_addr_name);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "remote-addr is '%s', using cs7 instance %u\n",
|
||||
cnlink->remote_addr_name, ss7->cfg.id);
|
||||
} else {
|
||||
/* If no address is configured, use the default remote CN address, according to legacy behavior. */
|
||||
uint32_t remote_pc;
|
||||
switch (cnlink->domain) {
|
||||
case DOMAIN_CS:
|
||||
remote_pc = DEFAULT_PC_MSC;
|
||||
break;
|
||||
case DOMAIN_PS:
|
||||
remote_pc = DEFAULT_PC_SGSN;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
osmo_sccp_make_addr_pc_ssn(&cnlink->remote_addr, remote_pc, OSMO_SCCP_SSN_RANAP);
|
||||
}
|
||||
|
||||
/* If no 'cs7 instance' has been selected by the address, see if there already is a cs7 0 we can use by default.
|
||||
* If it doesn't exist, it will get created by osmo_sccp_simple_client_on_ss7_id(). */
|
||||
if (!ss7) {
|
||||
LOGP(DRANAP, LOGL_NOTICE, "No cs7 instance configured for IuCS nor IuPS,"
|
||||
" creating default instance\n");
|
||||
ss7 = osmo_ss7_instance_find_or_create(g_hnbgw, 0);
|
||||
if (!ss7)
|
||||
return -1;
|
||||
ss7->cfg.primary_pc = (23 << 3) + 5;
|
||||
ss7 = osmo_ss7_instance_find(0);
|
||||
LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "Using default 'cs7 instance 0' (%s)\n", ss7 ? "already exists" : "will create");
|
||||
}
|
||||
|
||||
if (!osmo_ss7_pc_is_valid(ss7->cfg.primary_pc)) {
|
||||
LOGP(DMAIN, LOGL_ERROR, "IuCS/IuPS uplink cannot be setup: CS7 instance %d has no point-code set\n",
|
||||
ss7->cfg.id);
|
||||
if (ss7) {
|
||||
/* Has another cnlink already set up an SCCP instance for this ss7? */
|
||||
llist_for_each_entry(hsu, &g_hnbgw->sccp.users, entry) {
|
||||
if (hsu->ss7 != ss7)
|
||||
continue;
|
||||
cnlink->hnbgw_sccp_user = hsu;
|
||||
LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, "using existing SCCP instance %s on cs7 instance %u\n",
|
||||
hsu->name, ss7->cfg.id);
|
||||
return 0;
|
||||
}
|
||||
/* else cnlink->hnbgw_sccp_user stays NULL and is set up below. */
|
||||
LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "cs7 instance %u has no SCCP instance yet\n", ss7->cfg.id);
|
||||
|
||||
/* All SCCP instances should originate from this function. So if there is no hnbgw_sccp_user for the cs7
|
||||
* instance, then the cs7 instance should not have an SCCP instance yet. */
|
||||
OSMO_ASSERT(!ss7->sccp);
|
||||
}
|
||||
|
||||
/* No SCCP instance yet for this ss7. Create it. If no address name is given that resolves to a
|
||||
* particular cs7 instance above, use 'cs7 instance 0'. */
|
||||
sccp = osmo_sccp_simple_client_on_ss7_id(g_hnbgw, ss7 ? ss7->cfg.id : 0, cnlink->name, DEFAULT_PC_HNBGW,
|
||||
OSMO_SS7_ASP_PROT_M3UA, 0, "localhost", -1, "localhost");
|
||||
if (!sccp) {
|
||||
LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "Failed to configure 'cs7 instance %u'\n", ss7->cfg.id);
|
||||
return -1;
|
||||
}
|
||||
local_pc = ss7->cfg.primary_pc;
|
||||
ss7 = osmo_sccp_get_ss7(sccp);
|
||||
LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, "created SCCP instance on cs7 instance %u\n", ss7->cfg.id);
|
||||
|
||||
osmo_sccp_make_addr_pc_ssn(&g_hnbgw->sccp.local_addr, local_pc, OSMO_SCCP_SSN_RANAP);
|
||||
LOGP(DRANAP, LOGL_NOTICE, "Local SCCP addr: %s\n", osmo_sccp_addr_name(ss7, &g_hnbgw->sccp.local_addr));
|
||||
/* Bind the SCCP user, using the cs7 instance's default point-code if one is configured, or osmo-hnbgw's default
|
||||
* local PC. */
|
||||
if (osmo_ss7_pc_is_valid(ss7->cfg.primary_pc))
|
||||
local_pc = ss7->cfg.primary_pc;
|
||||
else
|
||||
local_pc = DEFAULT_PC_HNBGW;
|
||||
|
||||
g_hnbgw->sccp.client = osmo_sccp_simple_client_on_ss7_id(g_hnbgw, ss7->cfg.id, "OsmoHNBGW",
|
||||
local_pc, OSMO_SS7_ASP_PROT_M3UA,
|
||||
0, local_ip, stp_port, stp_host);
|
||||
if (!g_hnbgw->sccp.client) {
|
||||
LOGP(DMAIN, LOGL_ERROR, "Failed to init SCCP Client\n");
|
||||
return -1;
|
||||
}
|
||||
LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "binding OsmoHNBGW user to cs7 instance %u, local PC %u = %s\n",
|
||||
ss7->cfg.id, local_pc, osmo_ss7_pointcode_print(ss7, local_pc));
|
||||
|
||||
cnlink = talloc_zero(g_hnbgw, struct hnbgw_cnlink);
|
||||
INIT_LLIST_HEAD(&cnlink->map_list);
|
||||
|
||||
cnlink->sccp_user = osmo_sccp_user_bind_pc(g_hnbgw->sccp.client, "OsmoHNBGW", sccp_sap_up,
|
||||
OSMO_SCCP_SSN_RANAP, g_hnbgw->sccp.local_addr.pc);
|
||||
if (!cnlink->sccp_user) {
|
||||
sccp_user = osmo_sccp_user_bind_pc(sccp, "OsmoHNBGW", sccp_sap_up, OSMO_SCCP_SSN_RANAP, local_pc);
|
||||
if (!sccp_user) {
|
||||
LOGP(DMAIN, LOGL_ERROR, "Failed to init SCCP User\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOGP(DRANAP, LOGL_NOTICE, "Remote SCCP addr: IuCS: %s\n",
|
||||
osmo_sccp_addr_name(ss7, &g_hnbgw->sccp.iucs_remote_addr));
|
||||
LOGP(DRANAP, LOGL_NOTICE, "Remote SCCP addr: IuPS: %s\n",
|
||||
osmo_sccp_addr_name(ss7, &g_hnbgw->sccp.iups_remote_addr));
|
||||
hsu = talloc_zero(cnlink, struct hnbgw_sccp_user);
|
||||
*hsu = (struct hnbgw_sccp_user){
|
||||
.name = talloc_asprintf(hsu, "cs7-%u.sccp", ss7->cfg.id),
|
||||
.ss7 = ss7,
|
||||
.sccp_user = sccp_user,
|
||||
};
|
||||
osmo_sccp_make_addr_pc_ssn(&hsu->local_addr, local_pc, OSMO_SCCP_SSN_RANAP);
|
||||
hash_init(hsu->hnbgw_context_map_by_conn_id);
|
||||
osmo_sccp_user_set_priv(sccp_user, hsu);
|
||||
|
||||
/* In sccp_sap_up() we expect the cnlink in the user's priv. */
|
||||
osmo_sccp_user_set_priv(cnlink->sccp_user, cnlink);
|
||||
|
||||
g_hnbgw->sccp.cnlink = cnlink;
|
||||
llist_add_tail(&hsu->entry, &g_hnbgw->sccp.users);
|
||||
|
||||
cnlink->hnbgw_sccp_user = hsu;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct hnbgw_cnlink *hnbgw_cnlink_alloc(const char *remote_addr_name, RANAP_CN_DomainIndicator_t domain)
|
||||
{
|
||||
struct hnbgw_cnlink *cnlink;
|
||||
|
||||
cnlink = talloc_zero(g_hnbgw, struct hnbgw_cnlink);
|
||||
*cnlink = (struct hnbgw_cnlink){
|
||||
.name = (domain == DOMAIN_CS ? "msc-0" : "sgsn-0"),
|
||||
.domain = domain,
|
||||
.remote_addr_name = talloc_strdup(cnlink, remote_addr_name),
|
||||
};
|
||||
|
||||
INIT_LLIST_HEAD(&cnlink->map_list);
|
||||
|
||||
if (cnlink_ensure_sccp(cnlink)) {
|
||||
/* error logging already in cnlink_ensure_sccp() */
|
||||
talloc_free(cnlink);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (domain) {
|
||||
case DOMAIN_CS:
|
||||
OSMO_ASSERT(!g_hnbgw->sccp.cnlink_iucs);
|
||||
g_hnbgw->sccp.cnlink_iucs = cnlink;
|
||||
break;
|
||||
case DOMAIN_PS:
|
||||
OSMO_ASSERT(!g_hnbgw->sccp.cnlink_iups);
|
||||
g_hnbgw->sccp.cnlink_iups = cnlink;
|
||||
break;
|
||||
default:
|
||||
OSMO_ASSERT(false);
|
||||
}
|
||||
|
||||
return cnlink;
|
||||
}
|
||||
|
||||
const struct osmo_sccp_addr *hnbgw_cn_get_remote_addr(bool is_ps)
|
||||
{
|
||||
return is_ps ? &g_hnbgw->sccp.iups_remote_addr : &g_hnbgw->sccp.iucs_remote_addr;
|
||||
struct hnbgw_cnlink *cnlink = is_ps ? g_hnbgw->sccp.cnlink_iups : g_hnbgw->sccp.cnlink_iucs;
|
||||
if (!cnlink)
|
||||
return NULL;
|
||||
return &cnlink->remote_addr;
|
||||
}
|
||||
|
||||
static bool cnlink_matches(const struct hnbgw_cnlink *cnlink, const struct hnbgw_sccp_user *hsu, const struct osmo_sccp_addr *remote_addr)
|
||||
{
|
||||
if (cnlink->hnbgw_sccp_user != hsu)
|
||||
return false;
|
||||
if (osmo_sccp_addr_cmp(&cnlink->remote_addr, remote_addr, OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
struct hnbgw_cnlink *hnbgw_cnlink_find_by_addr(const struct hnbgw_sccp_user *hsu,
|
||||
const struct osmo_sccp_addr *remote_addr)
|
||||
{
|
||||
/* FUTURE: loop over llist g_hnb_gw->sccp.cnpool */
|
||||
if (cnlink_matches(g_hnbgw->sccp.cnlink_iucs, hsu, remote_addr))
|
||||
return g_hnbgw->sccp.cnlink_iucs;
|
||||
if (cnlink_matches(g_hnbgw->sccp.cnlink_iups, hsu, remote_addr))
|
||||
return g_hnbgw->sccp.cnlink_iups;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct hnbgw_cnlink *hnbgw_cnlink_select(bool is_ps)
|
||||
{
|
||||
/* FUTURE: soon we will pick one of many configurable CN peers from a pool. There will be more input arguments
|
||||
* (MI, or TMSI, or NRI decoded from RANAP) and this function will do round robin for new subscribers. */
|
||||
if (is_ps)
|
||||
return g_hnbgw->sccp.cnlink_iups;
|
||||
return g_hnbgw->sccp.cnlink_iucs;
|
||||
}
|
||||
|
||||
char *cnlink_sccp_addr_to_str(struct hnbgw_cnlink *cnlink, const struct osmo_sccp_addr *addr)
|
||||
{
|
||||
struct osmo_sccp_instance *sccp = cnlink_sccp(cnlink);
|
||||
if (!sccp)
|
||||
return osmo_sccp_addr_dump(addr);
|
||||
return osmo_sccp_inst_addr_to_str_c(OTC_SELECT, sccp, addr);
|
||||
}
|
||||
|
|
|
@ -200,7 +200,6 @@ static int rua_to_scu(struct hnb_context *hnb,
|
|||
{
|
||||
struct msgb *ranap_msg = NULL;
|
||||
struct hnbgw_context_map *map = NULL;
|
||||
struct hnbgw_cnlink *cn = g_hnbgw->sccp.cnlink;
|
||||
bool is_ps;
|
||||
|
||||
switch (cN_DomainIndicator) {
|
||||
|
@ -215,11 +214,6 @@ static int rua_to_scu(struct hnb_context *hnb,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (!cn) {
|
||||
LOGHNB(hnb, DRUA, LOGL_NOTICE, "CN=NULL, discarding message\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If there is RANAP data, include it in the msgb. In RUA there is always data in practice, but theoretically it
|
||||
* could be an empty Connect or Disconnect. */
|
||||
if (data && len) {
|
||||
|
@ -230,8 +224,13 @@ static int rua_to_scu(struct hnb_context *hnb,
|
|||
memcpy(ranap_msg->l2h, data, len);
|
||||
}
|
||||
|
||||
map = context_map_alloc_by_hnb(hnb, context_id, is_ps, cn);
|
||||
OSMO_ASSERT(map);
|
||||
map = context_map_find_or_create_by_rua_ctx_id(hnb, context_id, is_ps);
|
||||
if (!map) {
|
||||
LOGHNB(hnb, DRUA, LOGL_ERROR,
|
||||
"Failed to create context map for %s: rx RUA %s with %u bytes RANAP data\n",
|
||||
is_ps ? "IuPS" : "IuCS", rua_procedure_code_name(rua_procedure), data ? len : 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_MAP(map, DRUA, LOGL_DEBUG, "rx RUA %s with %u bytes RANAP data\n",
|
||||
rua_procedure_code_name(rua_procedure), data ? len : 0);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <osmocom/hnbgw/vty.h>
|
||||
|
||||
#include <osmocom/hnbgw/hnbgw.h>
|
||||
#include <osmocom/hnbgw/hnbgw_cn.h>
|
||||
#include <osmocom/hnbgw/context_map.h>
|
||||
#include <osmocom/hnbgw/tdefs.h>
|
||||
#include <osmocom/sigtran/protocol/sua.h>
|
||||
|
@ -108,36 +109,51 @@ int hnbgw_vty_go_parent(struct vty *vty)
|
|||
return vty->node;
|
||||
}
|
||||
|
||||
static void _show_cnlink(struct vty *vty, struct hnbgw_cnlink *cnlink)
|
||||
{
|
||||
struct osmo_ss7_route *rt;
|
||||
struct osmo_ss7_instance *ss7;
|
||||
|
||||
if (!cnlink) {
|
||||
vty_out(vty, "NULL%s", VTY_NEWLINE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cnlink->hnbgw_sccp_user) {
|
||||
vty_out(vty, "no SCCP state%s", VTY_NEWLINE);
|
||||
return;
|
||||
}
|
||||
|
||||
ss7 = cnlink->hnbgw_sccp_user->ss7;
|
||||
if (!ss7) {
|
||||
vty_out(vty, "no cs7 instance%s", VTY_NEWLINE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cnlink->hnbgw_sccp_user->sccp_user) {
|
||||
vty_out(vty, "no SCCP user%s", VTY_NEWLINE);
|
||||
return;
|
||||
}
|
||||
|
||||
vty_out(vty, "%s <->",
|
||||
osmo_sccp_user_name(cnlink->hnbgw_sccp_user->sccp_user));
|
||||
vty_out(vty, " %s%s%s%s",
|
||||
cnlink->remote_addr_name ? : "",
|
||||
cnlink->remote_addr_name ? "=" : "",
|
||||
cnlink_sccp_addr_to_str(cnlink, &cnlink->remote_addr),
|
||||
VTY_NEWLINE);
|
||||
|
||||
rt = osmo_ss7_route_lookup(ss7, cnlink->remote_addr.pc);
|
||||
vty_out(vty, " SS7 route: %s%s", osmo_ss7_route_name(rt, true), VTY_NEWLINE);
|
||||
}
|
||||
|
||||
DEFUN(show_cnlink, show_cnlink_cmd, "show cnlink",
|
||||
SHOW_STR "Display information on core network link\n")
|
||||
{
|
||||
struct osmo_ss7_route *rt;
|
||||
struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(g_hnbgw->sccp.client);
|
||||
#define GUARD(STR) \
|
||||
STR ? STR : "", \
|
||||
STR ? ":" : ""
|
||||
|
||||
vty_out(vty, "IuCS: %s <->",
|
||||
osmo_sccp_user_name(g_hnbgw->sccp.cnlink->sccp_user));
|
||||
vty_out(vty, " %s%s%s%s",
|
||||
GUARD(g_hnbgw->config.iucs_remote_addr_name),
|
||||
osmo_sccp_inst_addr_name(g_hnbgw->sccp.client, &g_hnbgw->sccp.iucs_remote_addr),
|
||||
VTY_NEWLINE);
|
||||
|
||||
rt = osmo_ss7_route_lookup(ss7, g_hnbgw->sccp.iucs_remote_addr.pc);
|
||||
vty_out(vty, " SS7 route: %s%s", osmo_ss7_route_name(rt, true), VTY_NEWLINE);
|
||||
|
||||
vty_out(vty, "IuPS: %s <->",
|
||||
osmo_sccp_user_name(g_hnbgw->sccp.cnlink->sccp_user));
|
||||
vty_out(vty, " %s%s%s%s",
|
||||
GUARD(g_hnbgw->config.iups_remote_addr_name),
|
||||
osmo_sccp_inst_addr_name(g_hnbgw->sccp.client, &g_hnbgw->sccp.iups_remote_addr),
|
||||
VTY_NEWLINE);
|
||||
|
||||
rt = osmo_ss7_route_lookup(ss7, g_hnbgw->sccp.iups_remote_addr.pc);
|
||||
vty_out(vty, " SS7 route: %s%s", osmo_ss7_route_name(rt, true), VTY_NEWLINE);
|
||||
|
||||
#undef GUARD
|
||||
vty_out(vty, "IuCS: ");
|
||||
_show_cnlink(vty, g_hnbgw->sccp.cnlink_iucs);
|
||||
vty_out(vty, "IuPS: ");
|
||||
_show_cnlink(vty, g_hnbgw->sccp.cnlink_iups);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -259,11 +259,13 @@ int main(int argc, char **argv)
|
|||
|
||||
ranap_set_log_area(DRANAP);
|
||||
|
||||
rc = hnbgw_cnlink_init("localhost", M3UA_PORT, "localhost");
|
||||
if (rc < 0) {
|
||||
if (!hnbgw_cnlink_alloc(g_hnbgw->config.iucs_remote_addr_name, DOMAIN_CS)
|
||||
|| !hnbgw_cnlink_alloc(g_hnbgw->config.iups_remote_addr_name, DOMAIN_PS)) {
|
||||
LOGP(DMAIN, LOGL_ERROR, "Failed to initialize SCCP link to CN\n");
|
||||
exit(1);
|
||||
}
|
||||
OSMO_ASSERT(g_hnbgw->sccp.cnlink_iucs);
|
||||
OSMO_ASSERT(g_hnbgw->sccp.cnlink_iups);
|
||||
|
||||
LOGP(DHNBAP, LOGL_NOTICE, "Using RNC-Id %u\n", g_hnbgw->config.rnc_id);
|
||||
|
||||
|
|
|
@ -5,19 +5,19 @@ OsmoHNBGW> enable
|
|||
OsmoHNBGW# show cs7 config
|
||||
cs7 instance 0
|
||||
point-code 0.23.5
|
||||
asp asp-clnt-OsmoHNBGW 2905 0 m3ua
|
||||
asp asp-clnt-msc-0 2905 0 m3ua
|
||||
local-ip localhost
|
||||
remote-ip localhost
|
||||
sctp-role client
|
||||
as as-clnt-OsmoHNBGW m3ua
|
||||
asp asp-clnt-OsmoHNBGW
|
||||
as as-clnt-msc-0 m3ua
|
||||
asp asp-clnt-msc-0
|
||||
routing-key 0 0.23.5
|
||||
|
||||
OsmoHNBGW# show cnlink
|
||||
IuCS: OsmoHNBGW:RI=SSN_PC,PC=0.23.5,SSN=RANAP <-> RI=SSN_PC,PC=0.23.1,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0
|
||||
IuPS: OsmoHNBGW:RI=SSN_PC,PC=0.23.5,SSN=RANAP <-> RI=SSN_PC,PC=0.23.4,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0
|
||||
|
||||
OsmoHNBGW# show running-config
|
||||
...
|
||||
|
|
|
@ -1,28 +1,25 @@
|
|||
OsmoHNBGW> enable
|
||||
|
||||
OsmoHNBGW# ### ERROR: 'one_cs7.cfg' sets 'cs7 instance 0' / 'point-code 1.1.1', but osmo-hnbgw uses 0.23.5
|
||||
OsmoHNBGW# show cs7 config
|
||||
cs7 instance 0
|
||||
point-code 0.23.5
|
||||
asp asp-clnt-OsmoHNBGW 2905 0 m3ua
|
||||
point-code 1.1.1
|
||||
asp asp-clnt-msc-0 2905 0 m3ua
|
||||
local-ip localhost
|
||||
remote-ip localhost
|
||||
sctp-role client
|
||||
as as-clnt-OsmoHNBGW m3ua
|
||||
asp asp-clnt-OsmoHNBGW
|
||||
routing-key 0 0.23.5
|
||||
as as-clnt-msc-0 m3ua
|
||||
asp asp-clnt-msc-0
|
||||
routing-key 0 1.1.1
|
||||
|
||||
OsmoHNBGW# ### ERROR: 'one_cs7.cfg' sets 'cs7 instance 0' / 'point-code 1.1.1', but osmo-hnbgw uses 0.23.5
|
||||
OsmoHNBGW# show cnlink
|
||||
IuCS: OsmoHNBGW:RI=SSN_PC,PC=0.23.5,SSN=RANAP <-> RI=SSN_PC,PC=0.23.1,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW
|
||||
IuPS: OsmoHNBGW:RI=SSN_PC,PC=0.23.5,SSN=RANAP <-> RI=SSN_PC,PC=0.23.4,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW
|
||||
IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> RI=SSN_PC,PC=0.23.1,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0
|
||||
IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> RI=SSN_PC,PC=0.23.4,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0
|
||||
|
||||
OsmoHNBGW# ### ERROR: 'one_cs7.cfg' sets 'cs7 instance 0' / 'point-code 1.1.1', but osmo-hnbgw uses 0.23.5
|
||||
OsmoHNBGW# show running-config
|
||||
...
|
||||
cs7 instance 0
|
||||
point-code 0.23.5
|
||||
point-code 1.1.1
|
||||
hnbgw
|
||||
...
|
||||
|
|
|
@ -4,12 +4,12 @@ OsmoHNBGW# ### ASP and AS were auto-configured
|
|||
OsmoHNBGW# show cs7 config
|
||||
cs7 instance 0
|
||||
point-code 1.1.1
|
||||
asp asp-clnt-OsmoHNBGW 2905 0 m3ua
|
||||
asp asp-clnt-msc-0 2905 0 m3ua
|
||||
local-ip localhost
|
||||
remote-ip localhost
|
||||
sctp-role client
|
||||
as as-clnt-OsmoHNBGW m3ua
|
||||
asp asp-clnt-OsmoHNBGW
|
||||
as as-clnt-msc-0 m3ua
|
||||
asp asp-clnt-msc-0
|
||||
routing-key 0 1.1.1
|
||||
sccp-address my-msc
|
||||
routing-indicator PC
|
||||
|
@ -20,10 +20,10 @@ cs7 instance 0
|
|||
|
||||
OsmoHNBGW# ### IuCS and IuPS were explicitly pointed to specific remote point-codes, using cs7 instance 0 addresses
|
||||
OsmoHNBGW# show cnlink
|
||||
IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-msc:RI=SSN_PC,PC=1.2.3,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW
|
||||
IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-sgsn:RI=SSN_PC,PC=1.4.2,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW
|
||||
IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-msc=RI=SSN_PC,PC=1.2.3,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0
|
||||
IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-sgsn=RI=SSN_PC,PC=1.4.2,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0
|
||||
|
||||
OsmoHNBGW# show running-config
|
||||
...
|
||||
|
|
|
@ -3,12 +3,12 @@ OsmoHNBGW> enable
|
|||
OsmoHNBGW# show cs7 config
|
||||
cs7 instance 0
|
||||
point-code 1.1.1
|
||||
asp asp-clnt-OsmoHNBGW 2905 0 m3ua
|
||||
asp asp-clnt-msc-0 2905 0 m3ua
|
||||
local-ip localhost
|
||||
remote-ip localhost
|
||||
sctp-role client
|
||||
as as-clnt-OsmoHNBGW m3ua
|
||||
asp asp-clnt-OsmoHNBGW
|
||||
as as-clnt-msc-0 m3ua
|
||||
asp asp-clnt-msc-0
|
||||
routing-key 0 1.1.1
|
||||
sccp-address my-msc
|
||||
routing-indicator PC
|
||||
|
@ -16,10 +16,10 @@ cs7 instance 0
|
|||
|
||||
OsmoHNBGW# ### only IuCS was configured to go to remote-PC = 1.2.3, IuPS auto-configured to remote-PC = 0.23.4
|
||||
OsmoHNBGW# show cnlink
|
||||
IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-msc:RI=SSN_PC,PC=1.2.3,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW
|
||||
IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-msc=RI=SSN_PC,PC=1.2.3,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0
|
||||
IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> RI=SSN_PC,PC=0.23.4,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0
|
||||
|
||||
OsmoHNBGW# show running-config
|
||||
...
|
||||
|
|
|
@ -3,12 +3,12 @@ OsmoHNBGW> enable
|
|||
OsmoHNBGW# show cs7 config
|
||||
cs7 instance 0
|
||||
point-code 1.1.1
|
||||
asp asp-clnt-OsmoHNBGW 2905 0 m3ua
|
||||
asp asp-clnt-msc-0 2905 0 m3ua
|
||||
local-ip localhost
|
||||
remote-ip localhost
|
||||
sctp-role client
|
||||
as as-clnt-OsmoHNBGW m3ua
|
||||
asp asp-clnt-OsmoHNBGW
|
||||
as as-clnt-msc-0 m3ua
|
||||
asp asp-clnt-msc-0
|
||||
routing-key 0 1.1.1
|
||||
sccp-address my-sgsn
|
||||
routing-indicator PC
|
||||
|
@ -17,9 +17,9 @@ cs7 instance 0
|
|||
OsmoHNBGW# ### only IuPS was configured to go to remote-PC = 1.4.2, IuCS auto-configured to remote-PC = 0.23.1
|
||||
OsmoHNBGW# show cnlink
|
||||
IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> RI=SSN_PC,PC=0.23.1,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW
|
||||
IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-sgsn:RI=SSN_PC,PC=1.4.2,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0
|
||||
IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-sgsn=RI=SSN_PC,PC=1.4.2,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0
|
||||
|
||||
OsmoHNBGW# show running-config
|
||||
...
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# there are two cs7 instances, but auto-configuration will only use instance 0.
|
||||
|
||||
cs7 instance 0
|
||||
point-code 1.1.1
|
||||
|
||||
cs7 instance 1
|
||||
point-code 2.2.2
|
|
@ -0,0 +1,31 @@
|
|||
OsmoHNBGW> enable
|
||||
|
||||
OsmoHNBGW# ### there are two cs7 instances, but auto-configuration has only set up ASP and AS in instance 0.
|
||||
OsmoHNBGW# show cs7 config
|
||||
cs7 instance 0
|
||||
point-code 1.1.1
|
||||
asp asp-clnt-msc-0 2905 0 m3ua
|
||||
local-ip localhost
|
||||
remote-ip localhost
|
||||
sctp-role client
|
||||
as as-clnt-msc-0 m3ua
|
||||
asp asp-clnt-msc-0
|
||||
routing-key 0 1.1.1
|
||||
cs7 instance 1
|
||||
point-code 2.2.2
|
||||
|
||||
OsmoHNBGW# ### there are two cs7 instances, but auto-configuration will only use SCCP of instance 0 with local-PC = 1.1.1
|
||||
OsmoHNBGW# show cnlink
|
||||
IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> RI=SSN_PC,PC=0.23.1,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0
|
||||
IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> RI=SSN_PC,PC=0.23.4,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0
|
||||
|
||||
OsmoHNBGW# show running-config
|
||||
...
|
||||
cs7 instance 0
|
||||
point-code 1.1.1
|
||||
cs7 instance 1
|
||||
point-code 2.2.2
|
||||
hnbgw
|
||||
...
|
|
@ -0,0 +1,17 @@
|
|||
# two cs7 instances, both will be auto-configured for ASP and AS because address book entries point at both.
|
||||
|
||||
cs7 instance 0
|
||||
point-code 1.1.1
|
||||
sccp-address my-msc
|
||||
point-code 1.2.3
|
||||
|
||||
cs7 instance 1
|
||||
point-code 2.2.2
|
||||
sccp-address my-sgsn
|
||||
point-code 2.4.2
|
||||
|
||||
hnbgw
|
||||
iucs
|
||||
remote-addr my-msc
|
||||
iups
|
||||
remote-addr my-sgsn
|
|
@ -0,0 +1,57 @@
|
|||
OsmoHNBGW> enable
|
||||
|
||||
OsmoHNBGW# ### two cs7 instances, both have been auto-configured for ASP and AS because address book entries point at both.
|
||||
OsmoHNBGW# show cs7 config
|
||||
cs7 instance 0
|
||||
point-code 1.1.1
|
||||
asp asp-clnt-msc-0 2905 0 m3ua
|
||||
local-ip localhost
|
||||
remote-ip localhost
|
||||
sctp-role client
|
||||
as as-clnt-msc-0 m3ua
|
||||
asp asp-clnt-msc-0
|
||||
routing-key 0 1.1.1
|
||||
sccp-address my-msc
|
||||
routing-indicator PC
|
||||
point-code 1.2.3
|
||||
cs7 instance 1
|
||||
point-code 2.2.2
|
||||
asp asp-clnt-sgsn-0 2905 0 m3ua
|
||||
local-ip localhost
|
||||
remote-ip localhost
|
||||
sctp-role client
|
||||
as as-clnt-sgsn-0 m3ua
|
||||
asp asp-clnt-sgsn-0
|
||||
routing-key 0 2.2.2
|
||||
sccp-address my-sgsn
|
||||
routing-indicator PC
|
||||
point-code 2.4.2
|
||||
|
||||
OsmoHNBGW# ### IuCS on instance 0 with local-PC = 1.1.1, IuPS on instance 1 with local-PC = 2.2.2
|
||||
OsmoHNBGW# show cnlink
|
||||
IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-msc=RI=SSN_PC,PC=1.2.3,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0
|
||||
IuPS: OsmoHNBGW:RI=SSN_PC,PC=2.2.2,SSN=RANAP <-> my-sgsn=RI=SSN_PC,PC=2.4.2,SSN=RANAP
|
||||
SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-sgsn-0 proto=m3ua ASP asp-clnt-sgsn-0
|
||||
|
||||
OsmoHNBGW# show running-config
|
||||
...
|
||||
cs7 instance 0
|
||||
point-code 1.1.1
|
||||
sccp-address my-msc
|
||||
routing-indicator PC
|
||||
point-code 1.2.3
|
||||
cs7 instance 1
|
||||
point-code 2.2.2
|
||||
sccp-address my-sgsn
|
||||
routing-indicator PC
|
||||
point-code 2.4.2
|
||||
hnbgw
|
||||
rnc-id 23
|
||||
log-prefix hnb-id
|
||||
iuh
|
||||
iucs
|
||||
remote-addr my-msc
|
||||
iups
|
||||
remote-addr my-sgsn
|
||||
...
|
Loading…
Reference in New Issue