summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2013-04-07 20:17:30 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2013-04-07 20:17:30 +0200
commite1f164dd2f1e67f34cf92e43c3e8888eb5646016 (patch)
tree46094f8cb775a57fb0bbd1b10e1b8af67fccbf42 /src
parentb64b2b031344b354b7a59f1eb4c1f97d457613f3 (diff)
parentb36ad2debed2906674b0dc92062437d38994901e (diff)
Merge branch 'zecke/jolly-lapdm-fixes'
* Squashed fix and testcase into one.
Diffstat (limited to 'src')
-rw-r--r--src/gsm/lapd_core.c10
-rw-r--r--src/gsm/lapdm.c21
2 files changed, 25 insertions, 6 deletions
diff --git a/src/gsm/lapd_core.c b/src/gsm/lapd_core.c
index b33cf6eb..f351308d 100644
--- a/src/gsm/lapd_core.c
+++ b/src/gsm/lapd_core.c
@@ -820,7 +820,12 @@ static int lapd_rx_u(struct msgb *msg, struct lapd_msg_ctx *lctx)
"frame established state\n");
/* If link is lost on the remote side, we start over
* and send DL-ESTABLISH indication again. */
- if (dl->v_send != dl->v_recv) {
+ /* Additionally, continue in case of content resoltion
+ * (GSM network). This happens, if the mobile has not
+ * yet received UA or another mobile (collision) tries
+ * to establish connection. The mobile must receive
+ * UA again. */
+ if (!dl->cont_res && dl->v_send != dl->v_recv) {
LOGP(DLLAPD, LOGL_INFO, "Remote reestablish\n");
mdl_error(MDL_CAUSE_SABM_MF, lctx);
break;
@@ -831,7 +836,8 @@ static int lapd_rx_u(struct msgb *msg, struct lapd_msg_ctx *lctx)
#ifdef TEST_CONTENT_RESOLUTION_NETWORK
dl->cont_res->data[0] ^= 0x01;
#endif
- if (memcmp(dl->cont_res, msg->data, length)) {
+ if (memcmp(dl->cont_res->data, msg->data,
+ length)) {
LOGP(DLLAPD, LOGL_INFO, "Another SABM "
"with diffrent content - "
"ignoring!\n");
diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c
index 2bda48ae..71045aa1 100644
--- a/src/gsm/lapdm.c
+++ b/src/gsm/lapdm.c
@@ -687,7 +687,8 @@ int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le)
if (oph->sap != SAP_GSM_PH) {
LOGP(DLLAPD, LOGL_ERROR, "primitive for unknown SAP %u\n",
oph->sap);
- return -ENODEV;
+ rc = -ENODEV;
+ goto free;
}
switch (oph->primitive) {
@@ -695,7 +696,8 @@ int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le)
if (oph->operation != PRIM_OP_INDICATION) {
LOGP(DLLAPD, LOGL_ERROR, "PH_DATA is not INDICATION %u\n",
oph->operation);
- return -ENODEV;
+ rc = -ENODEV;
+ goto free;
}
rc = l2_ph_data_ind(oph->msg, le, pp->u.data.chan_nr,
pp->u.data.link_id);
@@ -704,7 +706,8 @@ int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le)
if (oph->operation != PRIM_OP_INDICATION) {
LOGP(DLLAPD, LOGL_ERROR, "PH_RTS is not INDICATION %u\n",
oph->operation);
- return -ENODEV;
+ rc = -ENODEV;
+ goto free;
}
rc = l2_ph_data_conf(oph->msg, le);
break;
@@ -718,12 +721,22 @@ int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le)
rc = l2_ph_chan_conf(oph->msg, le, pp->u.rach_ind.fn);
break;
default:
- return -EIO;
+ rc = -EIO;
+ goto free;
}
break;
+ default:
+ LOGP(DLLAPD, LOGL_ERROR, "Unknown primitive %u\n",
+ oph->primitive);
+ rc = -EINVAL;
+ goto free;
}
return rc;
+
+free:
+ msgb_free(oph->msg);
+ return rc;
}