sndcp: Allow empty SNDCP-XID indications
In some rare cases the modem might send a xid indication that does
not contain anything except the version number field. The sgsn
ignors such SNDCP-XID indications by stripping the entire field
from the response. We found a modem in the wild that started to
act problematic when the empty SNDCP-XID was missing in the
response. This patch changes the XID negotiation behaviour in
a way that if a modem should send empty SNDCP-XID indications,
the reply will also contain an empty SNDCP-XID indication. Apart
from that the SNDCP-XID version number is now parsed and echoed
in the response. This ensures that we always reply with the version
number that the modem expects. (The version was 0 in all cases we
observed so far)
Change-Id: I097a770cb4907418f53e620a051ebb8cd110c5f2
Related: OS#1794
diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c
index 1cbeede..60455b5 100644
--- a/openbsc/src/gprs/gprs_sndcp.c
+++ b/openbsc/src/gprs/gprs_sndcp.c
@@ -960,8 +960,13 @@
llist_add(&v42bis_comp_field.list, &comp_fields);
}
+ /* Do not attempt to compile anything if there is no data in the list */
+ if (llist_empty(&comp_fields))
+ return 0;
+
/* Compile bytestream */
- return gprs_sndcp_compile_xid(bytes, bytes_len, &comp_fields);
+ return gprs_sndcp_compile_xid(bytes, bytes_len, &comp_fields,
+ DEFAULT_SNDCP_VERSION);
}
/* Set of SNDCP-XID bnegotiation (See also: TS 144 065,
@@ -1106,6 +1111,7 @@
int rc;
int compclass;
+ int version;
struct llist_head *comp_fields;
struct gprs_sndcp_comp_field *comp_field;
@@ -1115,22 +1121,13 @@
OSMO_ASSERT(lle);
/* Parse SNDCP-CID XID-Field */
- comp_fields = gprs_sndcp_parse_xid(lle->llme,
+ comp_fields = gprs_sndcp_parse_xid(&version, lle->llme,
xid_field_indication->data,
xid_field_indication->data_len,
NULL);
if (!comp_fields)
return -EINVAL;
- /* Don't bother with empty indications */
- if (llist_empty(comp_fields)) {
- xid_field_response->data = NULL;
- xid_field_response->data_len = 0;
- DEBUGP(DSNDCP,
- "SNDCP-XID indication did not contain any parameters!\n");
- return 0;
- }
-
/* Handle compression entites */
DEBUGP(DSNDCP, "SNDCP-XID-IND (ms):\n");
gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG);
@@ -1168,7 +1165,7 @@
/* Compile modified SNDCP-XID bytes */
rc = gprs_sndcp_compile_xid(xid_field_response->data,
xid_field_indication->data_len,
- comp_fields);
+ comp_fields, 0);
if (rc > 0)
xid_field_response->data_len = rc;
@@ -1210,7 +1207,7 @@
OSMO_ASSERT(xid_field_request);
/* Parse SNDCP-CID XID-Field */
- comp_fields_req = gprs_sndcp_parse_xid(lle->llme,
+ comp_fields_req = gprs_sndcp_parse_xid(NULL, lle->llme,
xid_field_request->data,
xid_field_request->data_len,
NULL);
@@ -1221,7 +1218,7 @@
gprs_sndcp_dump_comp_fields(comp_fields_req, LOGL_DEBUG);
/* Parse SNDCP-CID XID-Field */
- comp_fields_conf = gprs_sndcp_parse_xid(lle->llme,
+ comp_fields_conf = gprs_sndcp_parse_xid(NULL, lle->llme,
xid_field_conf->data,
xid_field_conf->data_len,
comp_fields_req);