diff options
author | Philipp <pmaier@sysmocom.de> | 2016-12-22 14:15:20 +0100 |
---|---|---|
committer | Philipp <pmaier@sysmocom.de> | 2016-12-23 11:19:15 +0100 |
commit | db142dc59dc8d79d8ee608c9165bc865d240b97d (patch) | |
tree | a4c1ec7fdece679b7dd252ac321b28c60e3492d2 /openbsc/src/gprs/gprs_sndcp.c | |
parent | a191dcd8f01767b266b85578d0fb445d864dfabd (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.c | 25 |
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); |