IuPS: osmo-sgsn: add core IuPS impl, call iu_init()
Add main Iu entry points for IuPS: * gsm0408_gprs_rcvmsg_iu() * sgsn_ranap_iu_event() * sgsn_ranap_rab_ass_resp() Add main MM context management for IuPS: * sgsn_mm_ctx_by_ue_ctx() * sgsn_mm_ctx_alloc_iu() Call iu_init() from sgsn_main.c. Add asn_debug impl ("extern" from libasn1c). Initialize asn_debug VTY command (iu_vty_init()). osmo-sgsn build: add libiu and libasn1c, libosmo-sigtran, libosmo-ranap Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5
This commit is contained in:
parent
9bc42ec47b
commit
6292c8d44d
|
@ -14,6 +14,8 @@ int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp);
|
||||||
|
|
||||||
int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
|
int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
|
||||||
bool drop_cipherable);
|
bool drop_cipherable);
|
||||||
|
int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id,
|
||||||
|
uint16_t *sai);
|
||||||
int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx);
|
int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx);
|
||||||
int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg,
|
int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg,
|
||||||
struct gprs_llc_llme *llme);
|
struct gprs_llc_llme *llme);
|
||||||
|
|
|
@ -226,6 +226,7 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
|
||||||
const struct gprs_ra_id *raid);
|
const struct gprs_ra_id *raid);
|
||||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi);
|
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi);
|
||||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi);
|
struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi);
|
||||||
|
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx);
|
||||||
|
|
||||||
/* look-up by matching TLLI and P-TMSI (think twice before using this) */
|
/* look-up by matching TLLI and P-TMSI (think twice before using this) */
|
||||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli,
|
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli,
|
||||||
|
@ -234,6 +235,8 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli,
|
||||||
/* Allocate a new SGSN MM context */
|
/* Allocate a new SGSN MM context */
|
||||||
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
|
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
|
||||||
const struct gprs_ra_id *raid);
|
const struct gprs_ra_id *raid);
|
||||||
|
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx);
|
||||||
|
|
||||||
void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx);
|
void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx);
|
||||||
|
|
||||||
struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
|
struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
|
||||||
|
|
|
@ -3,6 +3,10 @@ AM_CFLAGS=-Wall -fno-strict-aliasing $(LIBOSMOCORE_CFLAGS) \
|
||||||
$(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) \
|
$(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) \
|
||||||
$(LIBOSMOABIS_CFLAGS) $(LIBOSMOGB_CFLAGS) $(COVERAGE_CFLAGS) \
|
$(LIBOSMOABIS_CFLAGS) $(LIBOSMOGB_CFLAGS) $(COVERAGE_CFLAGS) \
|
||||||
$(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS)
|
$(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS)
|
||||||
|
if BUILD_IU
|
||||||
|
AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \
|
OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \
|
||||||
$(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS)
|
$(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS)
|
||||||
|
|
||||||
|
@ -28,9 +32,15 @@ osmo_sgsn_SOURCES = gprs_gmm.c gprs_sgsn.c gprs_sndcp.c gprs_sndcp_vty.c \
|
||||||
sgsn_cdr.c sgsn_ares.c \
|
sgsn_cdr.c sgsn_ares.c \
|
||||||
oap.c oap_messages.c gprs_llc_xid.c
|
oap.c oap_messages.c gprs_llc_xid.c
|
||||||
osmo_sgsn_LDADD = \
|
osmo_sgsn_LDADD = \
|
||||||
$(top_builddir)/src/libcommon/libcommon.a \
|
$(top_builddir)/src/libcommon/libcommon.a
|
||||||
-lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \
|
if BUILD_IU
|
||||||
|
osmo_sgsn_LDADD += $(top_builddir)/src/libiu/libiu.a
|
||||||
|
endif
|
||||||
|
osmo_sgsn_LDADD += -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \
|
||||||
$(LIBCRYPTO_LIBS) -lrt
|
$(LIBCRYPTO_LIBS) -lrt
|
||||||
|
if BUILD_IU
|
||||||
|
osmo_sgsn_LDADD += $(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS)
|
||||||
|
endif
|
||||||
|
|
||||||
osmo_gtphub_SOURCES = gtphub_main.c gtphub.c gtphub_sock.c gtphub_ares.c \
|
osmo_gtphub_SOURCES = gtphub_main.c gtphub.c gtphub_sock.c gtphub_ares.c \
|
||||||
gtphub_vty.c sgsn_ares.c gprs_utils.c
|
gtphub_vty.c sgsn_ares.c gprs_utils.c
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
|
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
|
#include "bscconfig.h"
|
||||||
|
|
||||||
#include <openbsc/db.h>
|
#include <openbsc/db.h>
|
||||||
#include <osmocom/core/msgb.h>
|
#include <osmocom/core/msgb.h>
|
||||||
#include <osmocom/gsm/tlv.h>
|
#include <osmocom/gsm/tlv.h>
|
||||||
|
@ -45,6 +47,10 @@
|
||||||
|
|
||||||
#include <osmocom/gprs/gprs_bssgp.h>
|
#include <osmocom/gprs/gprs_bssgp.h>
|
||||||
|
|
||||||
|
#ifdef BUILD_IU
|
||||||
|
#include <osmocom/ranap/ranap_ies_defs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <openbsc/debug.h>
|
#include <openbsc/debug.h>
|
||||||
#include <openbsc/gsm_data.h>
|
#include <openbsc/gsm_data.h>
|
||||||
#include <openbsc/gsm_subscriber.h>
|
#include <openbsc/gsm_subscriber.h>
|
||||||
|
@ -58,6 +64,10 @@
|
||||||
#include <openbsc/sgsn.h>
|
#include <openbsc/sgsn.h>
|
||||||
#include <openbsc/signal.h>
|
#include <openbsc/signal.h>
|
||||||
|
|
||||||
|
#ifdef BUILD_IU
|
||||||
|
#include <openbsc/iu.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <pdp.h>
|
#include <pdp.h>
|
||||||
|
|
||||||
#define PTMSI_ALLOC
|
#define PTMSI_ALLOC
|
||||||
|
@ -97,6 +107,45 @@ static const struct tlv_definition gsm48_sm_att_tlvdef = {
|
||||||
|
|
||||||
static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx);
|
static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx);
|
||||||
|
|
||||||
|
#ifdef BUILD_IU
|
||||||
|
int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies);
|
||||||
|
int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data)
|
||||||
|
{
|
||||||
|
struct sgsn_mm_ctx *mm;
|
||||||
|
int rc = -1;
|
||||||
|
|
||||||
|
mm = sgsn_mm_ctx_by_ue_ctx(ctx);
|
||||||
|
if (!mm) {
|
||||||
|
LOGP(DRANAP, LOGL_NOTICE, "Cannot find mm ctx for IU event %i!\n", type);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case IU_EVENT_RAB_ASSIGN:
|
||||||
|
rc = sgsn_ranap_rab_ass_resp(mm, (RANAP_RAB_SetupOrModifiedItemIEs_t *)data);
|
||||||
|
break;
|
||||||
|
case IU_EVENT_IU_RELEASE:
|
||||||
|
/* fall thru */
|
||||||
|
case IU_EVENT_LINK_INVALIDATED:
|
||||||
|
/* Clean up ue_conn_ctx here */
|
||||||
|
LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi);
|
||||||
|
rc = 0;
|
||||||
|
break;
|
||||||
|
case IU_EVENT_SECURITY_MODE_COMPLETE:
|
||||||
|
/* Continue authentication here */
|
||||||
|
mm->iu.ue_ctx->integrity_active = 1;
|
||||||
|
rc = gsm48_gmm_authorize(mm);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOGP(DRANAP, LOGL_NOTICE, "Unknown event received: %i\n", type);
|
||||||
|
rc = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Our implementation, should be kept in SGSN */
|
/* Our implementation, should be kept in SGSN */
|
||||||
|
|
||||||
static void mmctx_timer_cb(void *_mm);
|
static void mmctx_timer_cb(void *_mm);
|
||||||
|
@ -2193,6 +2242,45 @@ int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Main entry point for incoming 04.08 GPRS messages from Iu */
|
||||||
|
int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id,
|
||||||
|
uint16_t *sai)
|
||||||
|
{
|
||||||
|
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
|
||||||
|
uint8_t pdisc = gsm48_hdr_pdisc(gh);
|
||||||
|
struct sgsn_mm_ctx *mmctx;
|
||||||
|
int rc = -EINVAL;
|
||||||
|
|
||||||
|
mmctx = sgsn_mm_ctx_by_ue_ctx(msg->dst);
|
||||||
|
if (mmctx) {
|
||||||
|
rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
|
||||||
|
if (ra_id)
|
||||||
|
memcpy(&mmctx->ra, ra_id, sizeof(mmctx->ra));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MMCTX can be NULL */
|
||||||
|
|
||||||
|
switch (pdisc) {
|
||||||
|
case GSM48_PDISC_MM_GPRS:
|
||||||
|
rc = gsm0408_rcv_gmm(mmctx, msg, NULL, false);
|
||||||
|
#warning "set drop_cipherable arg for gsm0408_rcv_gmm() from IuPS?"
|
||||||
|
break;
|
||||||
|
case GSM48_PDISC_SM_GPRS:
|
||||||
|
rc = gsm0408_rcv_gsm(mmctx, msg, NULL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOGMMCTXP(LOGL_NOTICE, mmctx,
|
||||||
|
"Unknown GSM 04.08 discriminator 0x%02x: %s\n",
|
||||||
|
pdisc, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg)));
|
||||||
|
/* FIXME: return status message */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MMCTX can be invalid */
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/* Main entry point for incoming 04.08 GPRS messages from Gb */
|
/* Main entry point for incoming 04.08 GPRS messages from Gb */
|
||||||
int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
|
int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
|
||||||
bool drop_cipherable)
|
bool drop_cipherable)
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include <openbsc/gprs_utils.h>
|
#include <openbsc/gprs_utils.h>
|
||||||
#include <openbsc/signal.h>
|
#include <openbsc/signal.h>
|
||||||
#include "openbsc/gprs_llc.h"
|
#include "openbsc/gprs_llc.h"
|
||||||
|
#include <openbsc/iu.h>
|
||||||
|
|
||||||
#include <pdp.h>
|
#include <pdp.h>
|
||||||
|
|
||||||
|
@ -130,6 +131,20 @@ void sgsn_rate_ctr_init() {
|
||||||
sgsn->rate_ctrs = rate_ctr_group_alloc(tall_bsc_ctx, &sgsn_ctrg_desc, 0);
|
sgsn->rate_ctrs = rate_ctr_group_alloc(tall_bsc_ctx, &sgsn_ctrg_desc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* look-up an SGSN MM context based on Iu UE context (struct ue_conn_ctx)*/
|
||||||
|
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx)
|
||||||
|
{
|
||||||
|
struct sgsn_mm_ctx *ctx;
|
||||||
|
|
||||||
|
llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
|
||||||
|
if (ctx->ran_type == MM_CTX_T_UTRAN_Iu
|
||||||
|
&& uectx == ctx->iu.ue_ctx)
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* look-up a SGSN MM context based on TLLI + RAI */
|
/* look-up a SGSN MM context based on TLLI + RAI */
|
||||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
|
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
|
||||||
const struct gprs_ra_id *raid)
|
const struct gprs_ra_id *raid)
|
||||||
|
@ -218,6 +233,32 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate a new SGSN MM context */
|
||||||
|
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx)
|
||||||
|
{
|
||||||
|
struct sgsn_mm_ctx *ctx;
|
||||||
|
|
||||||
|
ctx = talloc_zero(tall_bsc_ctx, struct sgsn_mm_ctx);
|
||||||
|
if (!ctx)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ctx->ran_type = MM_CTX_T_UTRAN_Iu;
|
||||||
|
ctx->iu.ue_ctx = uectx;
|
||||||
|
ctx->mm_state = GMM_DEREGISTERED;
|
||||||
|
ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
|
||||||
|
ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, 0);
|
||||||
|
|
||||||
|
/* Need to get RAID from IU conn */
|
||||||
|
ctx->ra = ctx->iu.ue_ctx->ra_id;
|
||||||
|
|
||||||
|
INIT_LLIST_HEAD(&ctx->pdp_list);
|
||||||
|
|
||||||
|
llist_add(&ctx->list, &sgsn_mm_ctxts);
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* this is a hard _free_ function, it doesn't clean up the PDP contexts
|
/* this is a hard _free_ function, it doesn't clean up the PDP contexts
|
||||||
* in libgtp! */
|
* in libgtp! */
|
||||||
static void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm)
|
static void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm)
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "bscconfig.h"
|
||||||
|
|
||||||
#include <osmocom/core/talloc.h>
|
#include <osmocom/core/talloc.h>
|
||||||
#include <osmocom/core/select.h>
|
#include <osmocom/core/select.h>
|
||||||
#include <osmocom/core/rate_ctr.h>
|
#include <osmocom/core/rate_ctr.h>
|
||||||
|
@ -48,6 +50,11 @@
|
||||||
#include <openbsc/gprs_gmm.h>
|
#include <openbsc/gprs_gmm.h>
|
||||||
#include <openbsc/gsm_subscriber.h>
|
#include <openbsc/gsm_subscriber.h>
|
||||||
|
|
||||||
|
#ifdef BUILD_IU
|
||||||
|
#include <openbsc/iu.h>
|
||||||
|
#include <osmocom/ranap/ranap_ies_defs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <gtp.h>
|
#include <gtp.h>
|
||||||
#include <pdp.h>
|
#include <pdp.h>
|
||||||
|
|
||||||
|
@ -218,7 +225,10 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
|
||||||
memcpy(pdp->gsnlc.v, &sgsn->cfg.gtp_listenaddr.sin_addr,
|
memcpy(pdp->gsnlc.v, &sgsn->cfg.gtp_listenaddr.sin_addr,
|
||||||
sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
|
sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
|
||||||
|
|
||||||
/* SGSN address for user plane */
|
/* SGSN address for user plane
|
||||||
|
* Default to the control plane addr for now. If we are connected to a
|
||||||
|
* hnbgw via IuPS we'll need to send a PDP context update with the
|
||||||
|
* correct IP address after the RAB Assignment is complete */
|
||||||
pdp->gsnlu.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr);
|
pdp->gsnlu.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr);
|
||||||
memcpy(pdp->gsnlu.v, &sgsn->cfg.gtp_listenaddr.sin_addr,
|
memcpy(pdp->gsnlu.v, &sgsn->cfg.gtp_listenaddr.sin_addr,
|
||||||
sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
|
sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
|
||||||
|
@ -383,6 +393,72 @@ reject:
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BUILD_IU
|
||||||
|
/* Callback for RAB assignment response */
|
||||||
|
int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies)
|
||||||
|
{
|
||||||
|
uint8_t rab_id;
|
||||||
|
bool require_pdp_update = false;
|
||||||
|
struct sgsn_pdp_ctx *pdp = NULL;
|
||||||
|
RANAP_RAB_SetupOrModifiedItem_t *item = &setup_ies->raB_SetupOrModifiedItem;
|
||||||
|
|
||||||
|
rab_id = item->rAB_ID.buf[0];
|
||||||
|
|
||||||
|
pdp = sgsn_pdp_ctx_by_nsapi(ctx, rab_id);
|
||||||
|
if (!pdp) {
|
||||||
|
LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Response for unknown RAB/NSAPI=%u\n", rab_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item->transportLayerAddress) {
|
||||||
|
LOGPC(DRANAP, LOGL_INFO, " Setup: (%u/%s)", rab_id, osmo_hexdump(item->transportLayerAddress->buf,
|
||||||
|
item->transportLayerAddress->size));
|
||||||
|
switch (item->transportLayerAddress->size) {
|
||||||
|
case 7:
|
||||||
|
/* It must be IPv4 inside a X213 NSAP */
|
||||||
|
memcpy(pdp->lib->gsnlu.v, &item->transportLayerAddress->buf[3], 4);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
/* It must be a raw IPv4 address */
|
||||||
|
memcpy(pdp->lib->gsnlu.v, item->transportLayerAddress->buf, 4);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
/* TODO: It must be a raw IPv6 address */
|
||||||
|
case 19:
|
||||||
|
/* TODO: It must be IPv6 inside a X213 NSAP */
|
||||||
|
default:
|
||||||
|
LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Resp: Unknown "
|
||||||
|
"transport layer address size %u\n",
|
||||||
|
item->transportLayerAddress->size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
require_pdp_update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The TEI on the RNC side might have changed, too */
|
||||||
|
if (item->iuTransportAssociation &&
|
||||||
|
item->iuTransportAssociation->present == RANAP_IuTransportAssociation_PR_gTP_TEI &&
|
||||||
|
item->iuTransportAssociation->choice.gTP_TEI.buf &&
|
||||||
|
item->iuTransportAssociation->choice.gTP_TEI.size >= 4) {
|
||||||
|
uint32_t tei = osmo_load32be(item->iuTransportAssociation->choice.gTP_TEI.buf);
|
||||||
|
LOGP(DRANAP, LOGL_DEBUG, "Updating TEID on RNC side from 0x%08x to 0x%08x\n",
|
||||||
|
pdp->lib->teid_own, tei);
|
||||||
|
pdp->lib->teid_own = tei;
|
||||||
|
require_pdp_update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require_pdp_update)
|
||||||
|
gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0);
|
||||||
|
|
||||||
|
if (pdp->state != PDP_STATE_CR_CONF) {
|
||||||
|
send_act_pdp_cont_acc(pdp);
|
||||||
|
pdp->state = PDP_STATE_CR_CONF;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Confirmation of a PDP Context Delete */
|
/* Confirmation of a PDP Context Delete */
|
||||||
static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
|
static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,6 +56,8 @@
|
||||||
#include <openbsc/sgsn.h>
|
#include <openbsc/sgsn.h>
|
||||||
#include <openbsc/gprs_llc.h>
|
#include <openbsc/gprs_llc.h>
|
||||||
#include <openbsc/gprs_gmm.h>
|
#include <openbsc/gprs_gmm.h>
|
||||||
|
#include <openbsc/iu.h>
|
||||||
|
|
||||||
#include <osmocom/ctrl/control_if.h>
|
#include <osmocom/ctrl/control_if.h>
|
||||||
#include <osmocom/ctrl/ports.h>
|
#include <osmocom/ctrl/ports.h>
|
||||||
|
|
||||||
|
@ -300,6 +302,13 @@ static const struct log_info gprs_log_info = {
|
||||||
.num_cat = ARRAY_SIZE(gprs_categories),
|
.num_cat = ARRAY_SIZE(gprs_categories),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Implement the extern asn_debug from libasn1c to indicate whether the ASN.1
|
||||||
|
* binary code decoded and encoded during Iu communication should be logged to
|
||||||
|
* stderr. See osmocom's libasn1c, asn_internal.h, at "if (asn_debug)":
|
||||||
|
* http://git.osmocom.org/libasn1c/tree/include/asn1c/asn_internal.h */
|
||||||
|
int asn_debug = 0;
|
||||||
|
|
||||||
|
int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data);
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -326,6 +335,9 @@ int main(int argc, char **argv)
|
||||||
osmo_stats_vty_add_cmds(&gprs_log_info);
|
osmo_stats_vty_add_cmds(&gprs_log_info);
|
||||||
sgsn_vty_init();
|
sgsn_vty_init();
|
||||||
ctrl_vty_init(tall_bsc_ctx);
|
ctrl_vty_init(tall_bsc_ctx);
|
||||||
|
#ifdef BUILD_IU
|
||||||
|
iu_vty_init(&asn_debug);
|
||||||
|
#endif
|
||||||
|
|
||||||
handle_options(argc, argv);
|
handle_options(argc, argv);
|
||||||
|
|
||||||
|
@ -417,6 +429,10 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BUILD_IU
|
||||||
|
iu_init(tall_bsc_ctx, "127.0.0.2", 14001, gsm0408_gprs_rcvmsg_iu, sgsn_ranap_iu_event);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (daemonize) {
|
if (daemonize) {
|
||||||
rc = osmo_daemonize();
|
rc = osmo_daemonize();
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
|
Loading…
Reference in New Issue