Review at https://gerrit.osmocom.org/173
gprs_gmm.c: Perform LLME operations only if we have one
In case the GMM message did not arrive over a Gb interface, there is no
LLME (and thus the associated pointer is NULL). Don't try to perform
operations on a NULL LLME.
Change-Id: If7f24161cd2826f8ee238d4bc1090adf555cea4e
---
M openbsc/src/gprs/gprs_gmm.c
1 file changed, 7 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/73/173/1
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index d521342..c8f687b 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -1208,10 +1208,12 @@
}
if (!mmctx) {
- /* send a XID reset to re-set all LLC sequence numbers
- * in the MS */
- LOGMMCTXP(LOGL_NOTICE, mmctx, "LLC XID RESET\n");
- gprs_llgmm_reset(llme);
+ if (llme) {
+ /* send a XID reset to re-set all LLC sequence numbers
+ * in the MS */
+ LOGMMCTXP(LOGL_NOTICE, mmctx, "LLC XID RESET\n");
+ gprs_llgmm_reset(llme);
+ }
/* The MS has to perform GPRS attach */
/* Device is still IMSI attached for CS but initiate GPRS ATTACH,
* see GSM 04.08, 4.7.5.1.4 and G.6 */
@@ -1314,7 +1316,7 @@
/* MMCTX can be NULL when called */
- if (!mmctx &&
+ if (llme && !mmctx &&
gh->msg_type != GSM48_MT_GMM_ATTACH_REQ &&
gh->msg_type != GSM48_MT_GMM_RA_UPD_REQ) {
LOGP(DMM, LOGL_NOTICE, "Cannot handle GMM for unknown MM CTX\n");
--
To view, visit https://gerrit.osmocom.org/173
To unsubscribe, visit https://gerrit.osmocom.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If7f24161cd2826f8ee238d4bc1090adf555cea4e
Gerrit-PatchSet: 1
Gerrit-Project: openbsc
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge(a)gnumonks.org>
Review at https://gerrit.osmocom.org/171
gprs_gmm.c: Don't try to de-reference NULL mmctx
There was a comment in the code that certain GMM messages require a
valid mmctx pointer. However, nothing actually checked if that pointer
was in fact non-NULL. We plainly crashed if a MS would send us the
wrong message in the wrong state.
Original patch by Harald Welte, but it broke message validity checking,
resulting in sgsn_test failure. This re-implements the NULL check in a
different way, as explained by in-code comment.
Change-Id: I7908de65bec91599f7042549b832cbbd7ae5a9a8
---
M openbsc/src/gprs/gprs_gmm.c
1 file changed, 32 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/71/171/1
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index 1e10701..e788e3d 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -1339,6 +1339,15 @@
return rc;
}
+ /*
+ * For a few messages, mmctx may be NULL. For most, we want to ensure a
+ * non-NULL mmctx. At the same time, we want to keep the message
+ * validity check intact, so that all message types appear in the
+ * switch statement and the default case thus means "unknown message".
+ * If we split the switch in two parts to check non-NULL halfway, the
+ * unknown-message check breaks, or we'd need to duplicate the switch
+ * cases in both parts. Just keep one large switch and add some gotos.
+ */
switch (gh->msg_type) {
case GSM48_MT_GMM_RA_UPD_REQ:
rc = gsm48_rx_gmm_ra_upd_req(mmctx, msg, llme);
@@ -1348,20 +1357,30 @@
break;
/* For all the following types mmctx can not be NULL */
case GSM48_MT_GMM_ID_RESP:
+ if (!mmctx)
+ goto null_mmctx;
rc = gsm48_rx_gmm_id_resp(mmctx, msg);
break;
case GSM48_MT_GMM_STATUS:
+ if (!mmctx)
+ goto null_mmctx;
rc = gsm48_rx_gmm_status(mmctx, msg);
break;
case GSM48_MT_GMM_DETACH_REQ:
+ if (!mmctx)
+ goto null_mmctx;
rc = gsm48_rx_gmm_det_req(mmctx, msg);
break;
case GSM48_MT_GMM_DETACH_ACK:
+ if (!mmctx)
+ goto null_mmctx;
LOGMMCTXP(LOGL_INFO, mmctx, "-> DETACH ACK\n");
mm_ctx_cleanup_free(mmctx, "GPRS DETACH ACK");
rc = 0;
break;
case GSM48_MT_GMM_ATTACH_COMPL:
+ if (!mmctx)
+ goto null_mmctx;
/* only in case SGSN offered new P-TMSI */
LOGMMCTXP(LOGL_INFO, mmctx, "-> ATTACH COMPLETE\n");
mmctx_timer_stop(mmctx, 3350);
@@ -1380,6 +1399,8 @@
osmo_signal_dispatch(SS_SGSN, S_SGSN_ATTACH, &sig_data);
break;
case GSM48_MT_GMM_RA_UPD_COMPL:
+ if (!mmctx)
+ goto null_mmctx;
/* only in case SGSN offered new P-TMSI */
LOGMMCTXP(LOGL_INFO, mmctx, "-> ROUTING AREA UPDATE COMPLETE\n");
mmctx_timer_stop(mmctx, 3350);
@@ -1398,6 +1419,8 @@
osmo_signal_dispatch(SS_SGSN, S_SGSN_UPDATE, &sig_data);
break;
case GSM48_MT_GMM_PTMSI_REALL_COMPL:
+ if (!mmctx)
+ goto null_mmctx;
LOGMMCTXP(LOGL_INFO, mmctx, "-> PTMSI REALLLICATION COMPLETE\n");
mmctx_timer_stop(mmctx, 3350);
mmctx->t3350_mode = GMM_T3350_MODE_NONE;
@@ -1409,6 +1432,8 @@
rc = 0;
break;
case GSM48_MT_GMM_AUTH_CIPH_RESP:
+ if (!mmctx)
+ goto null_mmctx;
rc = gsm48_rx_gmm_auth_ciph_resp(mmctx, msg);
break;
default:
@@ -1419,6 +1444,13 @@
}
return rc;
+
+null_mmctx:
+ LOGP(DMM, LOGL_ERROR,
+ "Received GSM 04.08 message type 0x%02x,"
+ " but no MM context available\n",
+ gh->msg_type);
+ return -EINVAL;
}
static void mmctx_timer_cb(void *_mm)
--
To view, visit https://gerrit.osmocom.org/171
To unsubscribe, visit https://gerrit.osmocom.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7908de65bec91599f7042549b832cbbd7ae5a9a8
Gerrit-PatchSet: 1
Gerrit-Project: openbsc
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <nhofmeyr(a)sysmocom.de>
Review at https://gerrit.osmocom.org/184
dyn PDCH: Add new_lchan argument to bsc_handover_start()
This is useful if the caller already allocated a new lchan, which will be used
to dynamically re-assign lchans.
The old behavior is maintained by passing NULL.
Change-Id: I2b7151f32f0c04c22f294eb5dd3c7d7dfddf35e7
---
M openbsc/include/openbsc/handover.h
M openbsc/src/libbsc/handover_decision.c
M openbsc/src/libbsc/handover_logic.c
M openbsc/src/libmsc/vty_interface_layer3.c
4 files changed, 15 insertions(+), 10 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/84/184/1
diff --git a/openbsc/include/openbsc/handover.h b/openbsc/include/openbsc/handover.h
index 3fe71a2..a4844c5 100644
--- a/openbsc/include/openbsc/handover.h
+++ b/openbsc/include/openbsc/handover.h
@@ -3,7 +3,8 @@
struct gsm_subscriber_connection;
-int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts);
+int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan,
+ struct gsm_bts *bts);
/* clear any operation for this connection */
void bsc_clear_handover(struct gsm_subscriber_connection *conn, int free_lchan);
diff --git a/openbsc/src/libbsc/handover_decision.c b/openbsc/src/libbsc/handover_decision.c
index 0f07bca..8b92177 100644
--- a/openbsc/src/libbsc/handover_decision.c
+++ b/openbsc/src/libbsc/handover_decision.c
@@ -48,7 +48,7 @@
}
/* and actually try to handover to that cell */
- return bsc_handover_start(lchan, new_bts);
+ return bsc_handover_start(lchan, NULL, new_bts);
}
/* did we get a RXLEV for a given cell in the given report? */
diff --git a/openbsc/src/libbsc/handover_logic.c b/openbsc/src/libbsc/handover_logic.c
index 641cee4..3e38fda 100644
--- a/openbsc/src/libbsc/handover_logic.c
+++ b/openbsc/src/libbsc/handover_logic.c
@@ -87,10 +87,13 @@
/* Hand over the specified logical channel to the specified new BTS. This is
* the main entry point for the actual handover algorithm, after the decision
- * whether to initiate HO to a specific BTS. */
-int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts)
+ * whether to initiate HO to a specific BTS.
+ *
+ * If new_lchan is NULL, allocate a new lchan. If not NULL, new_lchan must be a
+ * newly allocated lchan passed in by the caller. */
+int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan,
+ struct gsm_bts *new_bts)
{
- struct gsm_lchan *new_lchan;
struct bsc_handover *ho;
static uint8_t ho_ref;
int rc;
@@ -101,19 +104,20 @@
return -EBUSY;
DEBUGP(DHO, "(old_lchan on BTS %u, new BTS %u)\n",
- old_lchan->ts->trx->bts->nr, bts->nr);
+ old_lchan->ts->trx->bts->nr, new_bts->nr);
- osmo_counter_inc(bts->network->stats.handover.attempted);
+ osmo_counter_inc(new_bts->network->stats.handover.attempted);
if (!old_lchan->conn) {
LOGP(DHO, LOGL_ERROR, "Old lchan lacks connection data.\n");
return -ENOSPC;
}
- new_lchan = lchan_alloc(bts, old_lchan->type, 0);
+ if (!new_lchan)
+ new_lchan = lchan_alloc(new_bts, old_lchan->type, 0);
if (!new_lchan) {
LOGP(DHO, LOGL_NOTICE, "No free channel\n");
- osmo_counter_inc(bts->network->stats.handover.no_channel);
+ osmo_counter_inc(new_bts->network->stats.handover.no_channel);
return -ENOSPC;
}
diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c
index 5d74e04..2ad7eab 100644
--- a/openbsc/src/libmsc/vty_interface_layer3.c
+++ b/openbsc/src/libmsc/vty_interface_layer3.c
@@ -641,7 +641,7 @@
}
/* now start the handover */
- ret = bsc_handover_start(conn->lchan, bts);
+ ret = bsc_handover_start(conn->lchan, NULL, bts);
if (ret != 0) {
vty_out(vty, "%% Handover failed with errno %d.%s",
ret, VTY_NEWLINE);
--
To view, visit https://gerrit.osmocom.org/184
To unsubscribe, visit https://gerrit.osmocom.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I2b7151f32f0c04c22f294eb5dd3c7d7dfddf35e7
Gerrit-PatchSet: 1
Gerrit-Project: openbsc
Gerrit-Branch: master
Gerrit-Owner: Holger Freyther <holger(a)freyther.de>
Review at https://gerrit.osmocom.org/183
comment tweak for bsc_handover_start()
Have a comment only in the .c file to remove dup, tweak wording.
Change-Id: I6d19e2b5a794f8b5d8fb71791719447362c5ce85
---
M openbsc/include/openbsc/handover.h
M openbsc/src/libbsc/handover_logic.c
2 files changed, 3 insertions(+), 6 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/83/183/1
diff --git a/openbsc/include/openbsc/handover.h b/openbsc/include/openbsc/handover.h
index bd0d8ad..3fe71a2 100644
--- a/openbsc/include/openbsc/handover.h
+++ b/openbsc/include/openbsc/handover.h
@@ -3,9 +3,6 @@
struct gsm_subscriber_connection;
-/* Hand over the specified logical channel to the specified new BTS.
- * This is the main entry point for the actual handover algorithm,
- * after it has decided it wants to initiate HO to a specific BTS */
int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts);
/* clear any operation for this connection */
diff --git a/openbsc/src/libbsc/handover_logic.c b/openbsc/src/libbsc/handover_logic.c
index 2b8c386..641cee4 100644
--- a/openbsc/src/libbsc/handover_logic.c
+++ b/openbsc/src/libbsc/handover_logic.c
@@ -85,9 +85,9 @@
return NULL;
}
-/* Hand over the specified logical channel to the specified new BTS.
- * This is the main entry point for the actual handover algorithm,
- * after it has decided it wants to initiate HO to a specific BTS */
+/* Hand over the specified logical channel to the specified new BTS. This is
+ * the main entry point for the actual handover algorithm, after the decision
+ * whether to initiate HO to a specific BTS. */
int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts)
{
struct gsm_lchan *new_lchan;
--
To view, visit https://gerrit.osmocom.org/183
To unsubscribe, visit https://gerrit.osmocom.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6d19e2b5a794f8b5d8fb71791719447362c5ce85
Gerrit-PatchSet: 1
Gerrit-Project: openbsc
Gerrit-Branch: master
Gerrit-Owner: Holger Freyther <holger(a)freyther.de>
Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr(a)sysmocom.de>