aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gprs_sndcp.c
diff options
context:
space:
mode:
authorPhilipp <pmaier@sysmocom.de>2016-12-22 14:15:20 +0100
committerPhilipp <pmaier@sysmocom.de>2016-12-23 11:19:15 +0100
commitdb142dc59dc8d79d8ee608c9165bc865d240b97d (patch)
treea4c1ec7fdece679b7dd252ac321b28c60e3492d2 /openbsc/src/gprs/gprs_sndcp.c
parenta191dcd8f01767b266b85578d0fb445d864dfabd (diff)
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
Diffstat (limited to 'openbsc/src/gprs/gprs_sndcp.c')
-rw-r--r--openbsc/src/gprs/gprs_sndcp.c25
1 files changed, 11 insertions, 14 deletions
diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c
index 1cbeede09..60455b518 100644
--- a/openbsc/src/gprs/gprs_sndcp.c
+++ b/openbsc/src/gprs/gprs_sndcp.c
@@ -960,8 +960,13 @@ static int gprs_llc_gen_sndcp_xid(uint8_t *bytes, int bytes_len, uint8_t nsapi)
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 sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication,
int rc;
int compclass;
+ int version;
struct llist_head *comp_fields;
struct gprs_sndcp_comp_field *comp_field;
@@ -1115,22 +1121,13 @@ int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication,
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 @@ int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication,
/* 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 @@ int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf,
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 @@ int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf,
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);