aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/configure.ac3
-rw-r--r--openbsc/include/openbsc/debug.h2
-rw-r--r--openbsc/include/openbsc/gprs_sgsn.h4
-rw-r--r--openbsc/src/gprs/Makefile.am17
-rw-r--r--openbsc/src/gprs/gprs_gmm.c69
-rw-r--r--openbsc/src/gprs/gprs_sgsn.c51
-rw-r--r--openbsc/src/gprs/osmo_sgsn.cfg59
-rw-r--r--openbsc/src/gprs/sgsn_iu.c22
-rw-r--r--openbsc/src/gprs/sgsn_libgtp.c27
-rw-r--r--openbsc/src/gprs/sgsn_main.c15
10 files changed, 216 insertions, 53 deletions
diff --git a/openbsc/configure.ac b/openbsc/configure.ac
index 24dbc30f7..e9930f1b0 100644
--- a/openbsc/configure.ac
+++ b/openbsc/configure.ac
@@ -28,6 +28,9 @@ PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.2.0)
PKG_CHECK_MODULES(LIBOSMOGB, libosmogb >= 0.6.4)
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.1)
PKG_CHECK_MODULES(LIBCRYPTO, libcrypto >= 0.9.5)
+PKG_CHECK_MODULES(LIBASN1C, libasn1c)
+PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap)
+PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran)
# Enabke/disable the NAT?
AC_ARG_ENABLE([nat], [AS_HELP_STRING([--enable-nat], [Build the BSC NAT. Requires SCCP])],
diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h
index 189ca476e..6231a2c36 100644
--- a/openbsc/include/openbsc/debug.h
+++ b/openbsc/include/openbsc/debug.h
@@ -34,6 +34,8 @@ enum {
DSMPP,
DFILTER,
DGTPHUB,
+ DSUA,
+ DRANAP,
Debug_LastEntry,
};
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h
index ea838506d..e449ccea0 100644
--- a/openbsc/include/openbsc/gprs_sgsn.h
+++ b/openbsc/include/openbsc/gprs_sgsn.h
@@ -141,6 +141,7 @@ struct sgsn_mm_ctx {
/* CSG Subscription Data */
/* LIPA Allowed */
/* Voice Support Match Indicator */
+ void *ue_ctx;
} iu;
/* VLR number */
uint32_t new_sgsn_addr;
@@ -216,10 +217,13 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
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_imsi(const char *imsi);
+struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx);
/* Allocate a new SGSN MM context */
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
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);
struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am
index f406dd795..4549547f0 100644
--- a/openbsc/src/gprs/Makefile.am
+++ b/openbsc/src/gprs/Makefile.am
@@ -2,9 +2,11 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
AM_CFLAGS=-Wall -fno-strict-aliasing $(LIBOSMOCORE_CFLAGS) \
$(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) \
$(LIBOSMOABIS_CFLAGS) $(LIBOSMOGB_CFLAGS) $(COVERAGE_CFLAGS) \
- $(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS)
+ $(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS) \
+ $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS)
+
OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \
- $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS)
+ $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) -ltalloc -lm
noinst_HEADERS = gprs_sndcp.h
@@ -16,6 +18,8 @@ bin_PROGRAMS += osmo-sgsn osmo-gtphub
endif
endif
+IUHDIR = $(top_srcdir)/../../osmo-iuh
+
osmo_gbproxy_SOURCES = gb_proxy.c gb_proxy_main.c gb_proxy_vty.c \
gb_proxy_patch.c gb_proxy_tlli.c gb_proxy_peer.c \
gprs_gb_parse.c gprs_llc_parse.c crc24.c gprs_utils.c
@@ -28,11 +32,16 @@ osmo_sgsn_SOURCES = gprs_gmm.c gprs_sgsn.c gprs_sndcp.c gprs_sndcp_vty.c \
sgsn_ctrl.c sgsn_auth.c gprs_subscriber.c \
gprs_gsup_messages.c gprs_utils.c gprs_gsup_client.c \
gsm_04_08_gprs.c sgsn_cdr.c sgsn_ares.c \
- oap.c oap_messages.c
+ oap.c oap_messages.c \
+ sgsn_iu.c
+
+#$(IUHDIR)/src/tests/ranap_common_cn.c
+
osmo_sgsn_LDADD = \
$(top_builddir)/src/libcommon/libcommon.a \
-lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \
- $(LIBCRYPTO_LIBS) -lrt
+ $(LIBCRYPTO_LIBS) -lrt \
+ $(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS)
osmo_gtphub_SOURCES = gtphub_main.c gtphub.c gtphub_sock.c gtphub_ares.c \
gtphub_vty.c sgsn_ares.c gprs_utils.c
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index 9e7197a9e..6c2213fb6 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -60,6 +60,8 @@
#define PTMSI_ALLOC
+int gprs_transp_upd_key(struct sgsn_mm_ctx *mm);
+
extern struct sgsn_instance *sgsn;
static const struct tlv_definition gsm48_gmm_att_tlvdef = {
@@ -132,12 +134,11 @@ time_t gprs_max_time_to_idle(void)
static int gsm48_gmm_sendmsg(struct msgb *msg, int command,
struct sgsn_mm_ctx *mm)
{
- if (mm) {
+ if (mm)
rate_ctr_inc(&mm->ctrg->ctr[GMM_CTR_PKTS_SIG_OUT]);
- if (mm->ran_type == MM_CTX_T_UTRAN_Iu)
- return gprs_iu_tx(msg, GPRS_SAPI_GMM, mm);
- }
-#warning "How to catch Iu-mode messages without MM context?"
+
+ if (msg->dst)
+ return gprs_iu_tx(msg, GPRS_SAPI_GMM, mm);
/* caller needs to provide TLLI, BVCI and NSEI */
return gprs_llc_tx_ui(msg, GPRS_SAPI_GMM, command, mm);
@@ -150,6 +151,7 @@ static void gmm_copy_id(struct msgb *msg, const struct msgb *old)
msgb_tlli(msg) = msgb_tlli(old);
msgb_bvci(msg) = msgb_bvci(old);
msgb_nsei(msg) = msgb_nsei(old);
+ msg->dst = old->dst;
}
/* Store BVCI/NSEI in MM context */
@@ -165,6 +167,7 @@ static void mmctx2msgid(struct msgb *msg, const struct sgsn_mm_ctx *mm)
msgb_tlli(msg) = mm->gb.tlli;
msgb_bvci(msg) = mm->gb.bvci;
msgb_nsei(msg) = mm->gb.nsei;
+ msg->dst = mm->iu.ue_ctx;
}
static void mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx, const char *log_text)
@@ -531,7 +534,11 @@ static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx,
/* FIXME: enable LLC cipheirng */
/* Check if we can let the mobile station enter */
- return gsm48_gmm_authorize(ctx);
+ rc = gsm48_gmm_authorize(ctx);
+
+ gprs_transp_upd_key(ctx);
+
+ return rc;
}
static void extract_subscr_msisdn(struct sgsn_mm_ctx *ctx)
@@ -837,7 +844,7 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
uint32_t tmsi;
char mi_string[GSM48_MI_SIZE];
struct gprs_ra_id ra_id;
- uint16_t cid;
+ uint16_t cid = 0;
enum gsm48_gmm_cause reject_cause;
int rc;
@@ -847,8 +854,8 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
* with a foreign TLLI (P-TMSI that was allocated to the MS before),
* or with random TLLI. */
-#error "how to obtain RA_ID in Iu case?"
- cid = bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
+ if (!msg->dst)
+ cid = bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
/* MS network capability 10.5.5.12 */
msnc_len = *cur++;
@@ -900,7 +907,10 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
#if 0
return gsm48_tx_gmm_att_rej(msg, GMM_CAUSE_IMSI_UNKNOWN);
#else
- ctx = sgsn_mm_ctx_alloc(0, &ra_id);
+ if (msg->dst)
+ ctx = sgsn_mm_ctx_alloc_iu(msg->dst);
+ else
+ ctx = sgsn_mm_ctx_alloc(0, &ra_id);
if (!ctx) {
reject_cause = GMM_CAUSE_NET_FAIL;
goto rejected;
@@ -923,7 +933,10 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
if (!ctx) {
/* Allocate a context as most of our code expects one.
* Context will not have an IMSI ultil ID RESP is received */
- ctx = sgsn_mm_ctx_alloc(msgb_tlli(msg), &ra_id);
+ if (msg->dst)
+ ctx = sgsn_mm_ctx_alloc_iu(msg->dst);
+ else
+ ctx = sgsn_mm_ctx_alloc(msgb_tlli(msg), &ra_id);
ctx->p_tmsi = tmsi;
}
if (ctx->ran_type == MM_CTX_T_GERAN_Gb) {
@@ -938,12 +951,22 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
reject_cause = GMM_CAUSE_MS_ID_NOT_DERIVED;
goto rejected;
}
+ {
+ ctx->auth_state = SGSN_AUTH_AUTHENTICATE;
+ /* Ki 000102030405060708090a0b0c0d0e0f */
+ ctx->auth_triplet = (struct gsm_auth_tuple ) {
+ .key_seq = 0,
+ .rand = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+ .sres = { 0x61, 0xb5, 0x69, 0xf5 },
+ .kc = { 0xd9, 0xd9, 0xc2, 0xed, 0x62, 0x7d, 0x68, 0x00 },
+ };
+ }
/* Update MM Context with currient RA and Cell ID */
ctx->ra = ra_id;
if (ctx->ran_type == MM_CTX_T_GERAN_Gb)
ctx->gb.cell_id = cid;
- else if (ctx->ran_type == MM_CTX_T_UTRAN_Iu)
- ctx->iu.sac = sac;
+ //else if (ctx->ran_type == MM_CTX_T_UTRAN_Iu)
+ //ctx->iu.sac = sac;
/* Update MM Context with other data */
ctx->drx_parms = drx_par;
@@ -1180,7 +1203,7 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
break;
}
-#error "Differentiate look-up between Iu and Gb"
+#warning "Differentiate look-up between Iu and Gb"
/* Look-up the MM context based on old RA-ID and TLLI */
mmctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &old_ra_id);
if (!mmctx || mmctx->mm_state == GMM_DEREGISTERED) {
@@ -1203,9 +1226,9 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
/* Update the MM context with the new RA-ID */
-#error "how to obtain RA_ID in Iu case?"
- bssgp_parse_cell_id(&mmctx->ra, msgb_bcid(msg));
+#warning "how to obtain RA_ID in Iu case?"
if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) {
+ bssgp_parse_cell_id(&mmctx->ra, msgb_bcid(msg));
/* Update the MM context with the new (i.e. foreign) TLLI */
mmctx->gb.tlli = msgb_tlli(msg);
}
@@ -1263,7 +1286,7 @@ rejected:
if (mmctx)
mm_ctx_cleanup_free(mmctx, "GPRS RA UPDATE REJ");
else {
- if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) {
+ if (llme) {
/* TLLI unassignment */
gprs_llgmm_assign(llme, llme->tlli, 0xffffffff,
GPRS_ALGO_GEA0, NULL);
@@ -2101,20 +2124,22 @@ int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx)
/* 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, uint32_t conn_id)
+ uint16_t *sai)
{
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
uint8_t pdisc = gh->proto_discr & 0x0f;
struct sgsn_mm_ctx *mmctx;
int rc = -EINVAL;
- mmctx = sgsn_mm_ctx_by_conn_id(conn_id);
+ DEBUGP(DMM, "rcvmsg_iu(%s)\n", osmo_hexdump(msgb_gmmh(msg), msgb_l3len(msg)));
+
+ 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_id, ra_id, sizeof(mmctx->ra_id));
- if (sai)
- mmctx->iu.sai = *sai;
+ memcpy(&mmctx->ra, ra_id, sizeof(mmctx->ra));
+ //if (sai)
+ //mmctx->iu.sai = *sai;
}
/* MMCTX can be NULL */
diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c
index f3180f343..0d8c8cc45 100644
--- a/openbsc/src/gprs/gprs_sgsn.c
+++ b/openbsc/src/gprs/gprs_sgsn.c
@@ -104,6 +104,20 @@ static inline uint32_t tlli_foreign(uint32_t tlli)
}
/* look-up a SGSN MM context based on TLLI + RAI */
+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 */
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
const struct gprs_ra_id *raid)
{
@@ -176,6 +190,7 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
return NULL;
memcpy(&ctx->ra, raid, sizeof(ctx->ra));
+ ctx->ran_type = MM_CTX_T_GERAN_Gb;
ctx->gb.tlli = tlli;
ctx->mm_state = GMM_DEREGISTERED;
ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
@@ -187,6 +202,28 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
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);
+ 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
* in libgtp! */
static void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm)
@@ -244,11 +281,13 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm)
subscr_put(subscr);
}
+ if (mm->ran_type == MM_CTX_T_GERAN_Gb) {
+ /* TLLI unassignment, must be called after sgsn_mm_ctx_free */
+ gprs_llgmm_assign(llme, tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
+ }
+
sgsn_mm_ctx_free(mm);
mm = NULL;
-
- /* TLLI unassignment, must be called after sgsn_mm_ctx_free */
- gprs_llgmm_assign(llme, tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
}
@@ -318,8 +357,10 @@ void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp)
LOGPDPCTXP(LOGL_INFO, pdp, "Forcing release of PDP context\n");
- /* Force the deactivation of the SNDCP layer */
- sndcp_sm_deactivate_ind(&pdp->mm->gb.llme->lle[pdp->sapi], pdp->nsapi);
+ if (pdp->mm->ran_type == MM_CTX_T_GERAN_Gb) {
+ /* Force the deactivation of the SNDCP layer */
+ sndcp_sm_deactivate_ind(&pdp->mm->gb.llme->lle[pdp->sapi], pdp->nsapi);
+ }
memset(&sig_data, 0, sizeof(sig_data));
sig_data.pdp = pdp;
diff --git a/openbsc/src/gprs/osmo_sgsn.cfg b/openbsc/src/gprs/osmo_sgsn.cfg
index c4c9ec1cf..a1306beb9 100644
--- a/openbsc/src/gprs/osmo_sgsn.cfg
+++ b/openbsc/src/gprs/osmo_sgsn.cfg
@@ -1,14 +1,38 @@
!
-! Osmocom SGSN (0.9.0.474-0ede2) configuration saved from vty
+! OsmoSGSN (0.15.0.145-a710-dirty) configuration saved from vty
!!
!
+log stderr
+ logging filter all 1
+ logging color 1
+ logging print category 0
+ logging timestamp 0
+ logging level all everything
+ logging level mm debug
+ logging level pag notice
+ logging level meas notice
+ logging level ref notice
+ logging level gprs debug
+ logging level ns info
+ logging level bssgp debug
+ logging level llc debug
+ logging level sndcp debug
+ logging level lglobal notice
+ logging level llapd notice
+ logging level linp notice
+ logging level lmux notice
+ logging level lmi notice
+ logging level lmib notice
+ logging level lsms notice
+ logging level lctrl notice
+ logging level lgtp notice
+ logging level lstats notice
+!
+stats interval 5
+!
line vty
no login
!
-sgsn
- gtp local-ip 192.168.100.11
- ggsn 0 remote-ip 192.168.100.239
- ggsn 0 gtp-version 1
ns
timer tns-block 3
timer tns-block-retries 3
@@ -17,7 +41,30 @@ ns
timer tns-test 30
timer tns-alive 3
timer tns-alive-retries 10
- encapsulation udp local-ip 192.168.100.11
+ encapsulation udp local-ip 192.168.0.51
encapsulation udp local-port 23000
encapsulation framerelay-gre enabled 0
bssgp
+sgsn
+ gtp local-ip 127.0.0.2
+ ggsn 0 remote-ip 192.168.0.51
+ ggsn 0 gtp-version 1
+ auth-policy closed
+ gsup oap-id 0
+ imsi-acl add 262032312854076
+ imsi-acl add 262778026147135
+ ! apn * ggsn 0
+ no cdr filename
+ cdr interval 600
+ timer t3312 600
+ timer t3322 6
+ timer t3350 6
+ timer t3360 6
+ timer t3370 6
+ timer t3313 30
+ timer t3314 44
+ timer t3316 44
+ timer t3385 8
+ timer t3386 8
+ timer t3395 8
+ timer t3397 8
diff --git a/openbsc/src/gprs/sgsn_iu.c b/openbsc/src/gprs/sgsn_iu.c
index 1cb95f587..7b8eb0e5d 100644
--- a/openbsc/src/gprs/sgsn_iu.c
+++ b/openbsc/src/gprs/sgsn_iu.c
@@ -18,10 +18,10 @@
#include <osmocom/sigtran/sccp_sap.h>
#include <openbsc/gprs_sgsn.h>
+#include <openbsc/debug.h>
-#include "ranap_ies_defs.h"
-#include "ranap_common_cn.h"
-#include "hnbgw.h"
+#include <osmocom/ranap/ranap_ies_defs.h>
+#include <osmocom/ranap/ranap_common_cn.h>
int asn1_xer_print = 1;
void *talloc_asn1_ctx;
@@ -239,7 +239,7 @@ static int ranap_handle_co_rab_ass_resp(void *ctx, RANAP_RAB_AssignmentResponseI
}
/* Entry point for connection-oriented ANAP message */
-int cn_ranap_handle_co(void *ctx, ranap_message *message)
+static void cn_ranap_handle_co(void *ctx, ranap_message *message)
{
int rc = 0;
@@ -282,8 +282,6 @@ int cn_ranap_handle_co(void *ctx, ranap_message *message)
rc = -1;
break;
}
-
- return rc;
}
static int ranap_handle_cl_reset_req(void *ctx, RANAP_ResetIEs_t *ies)
@@ -303,7 +301,7 @@ static int ranap_handle_cl_err_ind(void *ctx, RANAP_ErrorIndicationIEs_t *ies)
}
/* Entry point for connection-less RANAP message */
-int cn_ranap_handle_cl(void *ctx, ranap_message *message)
+static void cn_ranap_handle_cl(void *ctx, ranap_message *message)
{
int rc = 0;
@@ -370,7 +368,7 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link)
printf("N-CONNECT.ind(X->%u)\n", prim->u.connect.conn_id);
if (/* prim->u.connect.called_addr.ssn != OSMO_SCCP_SSN_RANAP || */
!msgb_l2(oph->msg) || msgb_l2len(oph->msg) == 0) {
- LOGP(DMAIN, LOGL_NOTICE, "Received invalid N-CONNECT.ind\n");
+ LOGP(DGPRS, LOGL_NOTICE, "Received invalid N-CONNECT.ind\n");
return 0;
}
/* FIXME: allocate UE context */
@@ -379,13 +377,13 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link)
resp = make_conn_resp(&prim->u.connect);
osmo_sua_user_link_down(link, resp);
/* then handle the RANAP payload */
- rc = cn_ranap_rx_co(ue, msgb_l2(oph->msg), msgb_l2len(oph->msg));
+ rc = ranap_cn_rx_co(cn_ranap_handle_co, ue, msgb_l2(oph->msg), msgb_l2len(oph->msg));
break;
case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION):
/* indication of disconnect */
printf("N-DISCONNECT.ind(%u)\n", prim->u.disconnect.conn_id);
ue = ue_conn_ctx_find(link, prim->u.disconnect.conn_id);
- rc = cn_ranap_rx_co(ue, msgb_l2(oph->msg), msgb_l2len(oph->msg));
+ rc = ranap_cn_rx_co(cn_ranap_handle_co, ue, msgb_l2(oph->msg), msgb_l2len(oph->msg));
break;
case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION):
/* connection-oriented data received */
@@ -393,13 +391,13 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link)
osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg)));
/* resolve UE context */
ue = ue_conn_ctx_find(link, prim->u.data.conn_id);
- rc = cn_ranap_rx_co(ue, msgb_l2(oph->msg), msgb_l2len(oph->msg));
+ rc = ranap_cn_rx_co(cn_ranap_handle_co, ue, msgb_l2(oph->msg), msgb_l2len(oph->msg));
break;
case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION):
/* connection-oriented data received */
printf("N-UNITDATA.ind(%s)\n",
osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg)));
- rc = cn_ranap_rx_cl(link, msgb_l2(oph->msg), msgb_l2len(oph->msg));
+ rc = ranap_cn_rx_cl(cn_ranap_handle_cl, link, msgb_l2(oph->msg), msgb_l2len(oph->msg));
break;
}
diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c
index cfebe1dc6..6393b1a4a 100644
--- a/openbsc/src/gprs/sgsn_libgtp.c
+++ b/openbsc/src/gprs/sgsn_libgtp.c
@@ -90,6 +90,8 @@ const struct value_string gtp_cause_strs[] = {
{ 0, NULL }
};
+int gprs_iu_rab_act(struct sgsn_mm_ctx *mm, uint32_t gtp_ip, uint32_t gtp_tei);
+
/* Generate the GTP IMSI IE according to 09.60 Section 7.9.2 */
static uint64_t imsi_str2gtp(char *str)
{
@@ -220,8 +222,14 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
/* SGSN address for user plane */
pdp->gsnlu.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr);
+#if 1
+ struct in_addr ia;
+ ia.s_addr = htonl(0xC0A80032);
+ memcpy(pdp->gsnlu.v, &ia, sizeof(ia));
+#else
memcpy(pdp->gsnlu.v, &sgsn->cfg.gtp_listenaddr.sin_addr,
sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
+#endif
/* Assume we are a GERAN system */
pdp->rattype.l = 1;
@@ -340,8 +348,14 @@ static int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
goto reject;
}
- /* Activate the SNDCP layer */
- sndcp_sm_activate_ind(&pctx->mm->gb.llme->lle[pctx->sapi], pctx->nsapi);
+ if (pctx->mm->ran_type == MM_CTX_T_GERAN_Gb) {
+ /* Activate the SNDCP layer */
+ sndcp_sm_activate_ind(&pctx->mm->gb.llme->lle[pctx->sapi], pctx->nsapi);
+ } else {
+ /* Activate a radio bearer */
+ uint32_t ggsn_ip = 0xc0a80033; /* 192.168.0.51 */
+ gprs_iu_rab_act(pctx->mm, ggsn_ip, pdp->teid_own);
+ }
/* Inform others about it */
memset(&sig_data, 0, sizeof(sig_data));
@@ -387,8 +401,13 @@ static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_DEACT, &sig_data);
if (pctx->mm) {
- /* Deactivate the SNDCP layer */
- sndcp_sm_deactivate_ind(&pctx->mm->gb.llme->lle[pctx->sapi], pctx->nsapi);
+ if (pctx->mm->ran_type == MM_CTX_T_GERAN_Gb) {
+ /* Deactivate the SNDCP layer */
+ sndcp_sm_deactivate_ind(&pctx->mm->gb.llme->lle[pctx->sapi], pctx->nsapi);
+ } else {
+ /* Activate a radio bearer */
+ gprs_iu_rab_deact(&pctx->mm);
+ }
/* Confirm deactivation of PDP context to MS */
rc = gsm48_tx_gsm_deact_pdp_acc(pctx);
diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c
index 2d3a0e4a9..7da87ea09 100644
--- a/openbsc/src/gprs/sgsn_main.c
+++ b/openbsc/src/gprs/sgsn_main.c
@@ -230,6 +230,8 @@ static void handle_options(int argc, char **argv)
}
}
+extern int asn_debug;
+
/* default categories */
static struct log_info_cat gprs_categories[] = {
[DMM] = {
@@ -279,6 +281,16 @@ static struct log_info_cat gprs_categories[] = {
.description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
.enabled = 1, .loglevel = LOGL_DEBUG,
},
+ [DSUA] = {
+ .name = "DSUA",
+ .description = "SCCP User Adaptation (SUA)",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
+ [DRANAP] = {
+ .name = "DRANAP",
+ .description = "RAN Application Part (RANAP)",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
};
static const struct log_info gprs_log_info = {
@@ -390,6 +402,9 @@ int main(int argc, char **argv)
}
}
+ asn_debug = 0;
+ sgsn_iu_init(tall_bsc_ctx);
+
if (daemonize) {
rc = osmo_daemonize();
if (rc < 0) {