pespin has uploaded this change for review. (
https://gerrit.osmocom.org/c/libosmo-gprs/+/30907 )
Change subject: sndcp: Initial support for async SN-XID.ind and SN-XID.rsp
......................................................................
sndcp: Initial support for async SN-XID.ind and SN-XID.rsp
Before this patch, the response was being crafted synchronously through
a direct function call. This patch provides initial support to trigger
the primitives so that the application using the SNDCP layer can handle
the indication and submit a response.
The different XID L3 params are still not being passed to the app, that
will be done in a subsequent patch.
Change-Id: I0a5069fd3dc0d6c3dd28aeae09b51c49dd8be92d
---
M include/osmocom/gprs/sndcp/sndcp_prim.h
M include/osmocom/gprs/sndcp/sndcp_private.h
M src/sndcp/sndcp.c
M src/sndcp/sndcp_prim.c
M tests/sndcp/sndcp_prim_test.c
M tests/sndcp/sndcp_prim_test.err
M tests/sndcp/sndcp_prim_test.ok
7 files changed, 96 insertions(+), 17 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-gprs refs/changes/07/30907/1
diff --git a/include/osmocom/gprs/sndcp/sndcp_prim.h
b/include/osmocom/gprs/sndcp/sndcp_prim.h
index 591e75f..b19498f 100644
--- a/include/osmocom/gprs/sndcp/sndcp_prim.h
+++ b/include/osmocom/gprs/sndcp/sndcp_prim.h
@@ -99,7 +99,8 @@
} xid_req;
/* OSMO_GPRS_SNDCP_SN_XID | Ind */
struct {
- uint8_t *req_xid;
+ uint8_t nsapi;
+ uint8_t *req_xid; /* TODO: theses need to be passed already decoded as in xid_req
above */
uint32_t req_xid_len;
} xid_ind;
/* OSMO_GPRS_SNDCP_SN_XID | Rsp */
diff --git a/include/osmocom/gprs/sndcp/sndcp_private.h
b/include/osmocom/gprs/sndcp/sndcp_private.h
index ac6c660..206b660 100644
--- a/include/osmocom/gprs/sndcp/sndcp_private.h
+++ b/include/osmocom/gprs/sndcp/sndcp_private.h
@@ -161,6 +161,10 @@
uint8_t *l3xid_req;
unsigned int l3xid_req_len;
+ /* Copy of the requested XID fields array we have received with the last
+ * originated XID-Request from peer. NULL if not existing (and l3xid_req_len = 0) */
+ struct llist_head *l3_xid_comp_fields_req_from_peer;
+
/* TODO: taken from lle.params and not yet set ever in code! */
uint16_t n201_u;
uint16_t n201_i;
@@ -190,6 +194,7 @@
/* sndcp_prim.c: */
struct osmo_gprs_sndcp_prim *gprs_sndcp_prim_alloc_sn_unitdata_ind(uint32_t tlli, uint8_t
sapi, uint8_t nsapi, uint8_t *npdu, size_t npdu_len);
+struct osmo_gprs_sndcp_prim *gprs_sndcp_prim_alloc_sn_xid_ind(uint32_t tlli, uint8_t
sapi, uint8_t nsapi);
struct osmo_gprs_sndcp_prim *gprs_sndcp_prim_alloc_snsm_activate_rsp(uint32_t tlli,
uint8_t nsapi);
int gprs_sndcp_prim_call_up_cb(struct osmo_gprs_sndcp_prim *sndcp_prim);
int gprs_sndcp_prim_call_down_cb(struct osmo_gprs_llc_prim *llc_prim);
@@ -206,6 +211,7 @@
int gprs_sndcp_snme_handle_llc_ll_xid_cnf(struct gprs_sndcp_mgmt_entity *snme, uint32_t
sapi, uint8_t *l3params, unsigned int l3params_len);
int gprs_sndcp_sne_handle_sn_unitdata_req(struct gprs_sndcp_entity *sne, uint8_t *npdu,
unsigned int npdu_len);
int gprs_sndcp_sne_handle_sn_xid_req(struct gprs_sndcp_entity *sne, const struct
osmo_gprs_sndcp_prim *sndcp_prim);
+int gprs_sndcp_sne_handle_sn_xid_rsp(struct gprs_sndcp_entity *sne, const struct
osmo_gprs_sndcp_prim *sndcp_prim);
#define LOGSNME(snme, level, fmt, args...) \
LOGSNDCP(level, "SNME(%08x) " fmt, \
diff --git a/src/sndcp/sndcp.c b/src/sndcp/sndcp.c
index 4ae1aac..27b4d5d 100644
--- a/src/sndcp/sndcp.c
+++ b/src/sndcp/sndcp.c
@@ -721,24 +721,30 @@
}
/* 5.1.1.7 SN-XID.response */
-/* FIXME: This is currently called directly from gprs_sndcp_snme_handle_llc_ll_xid_ind().
It should go async over SNDCP user instead */
-static int gprs_sndcp_sne_handle_sn_xid_rsp(struct gprs_sndcp_mgmt_entity *snme, uint8_t
sapi, const struct llist_head *comp_fields)
+/* FIXME: This is currently uses compo_fields stored from
gprs_sndcp_snme_handle_llc_ll_xid_ind().
+* It should use info provided by upper layers in the prim instead */
+int gprs_sndcp_sne_handle_sn_xid_rsp(struct gprs_sndcp_entity *sne, const struct
osmo_gprs_sndcp_prim *sndcp_prim)
{
struct osmo_gprs_llc_prim *llc_prim_tx;
struct msgb *msg;
int rc;
- LOGSNME(snme, LOGL_DEBUG, "SN-XID.rsp comp_fields:\n");
- gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG);
+ if (!sne->l3_xid_comp_fields_req_from_peer) {
+ LOGSNE(sne, LOGL_DEBUG, "SN-XID.rsp origianted comp_fields not found!\n");
+ return -EINVAL;
+ }
- llc_prim_tx = osmo_gprs_llc_prim_alloc_ll_xid_resp(snme->tlli, sapi, NULL, 256);
+ LOGSNE(sne, LOGL_DEBUG, "SN-XID.rsp comp_fields:\n");
+ gprs_sndcp_dump_comp_fields(sne->l3_xid_comp_fields_req_from_peer, LOGL_DEBUG);
+
+ llc_prim_tx = osmo_gprs_llc_prim_alloc_ll_xid_resp(sne->snme->tlli,
sne->llc_sapi, NULL, 256);
OSMO_ASSERT(llc_prim_tx);
msg = llc_prim_tx->oph.msg;
llc_prim_tx->ll.l3_pdu = msg->tail;
/* Compile modified SNDCP-XID bytes */
rc = gprs_sndcp_compile_xid(msg->tail,
msgb_tailroom(msg),
- comp_fields, 0);
+ sne->l3_xid_comp_fields_req_from_peer, 0);
if (rc < 0) {
msgb_free(msg);
return -EINVAL;
@@ -913,6 +919,24 @@
int version;
struct llist_head *comp_fields;
struct gprs_sndcp_comp_field *comp_field;
+ struct gprs_sndcp_entity *sne = NULL;
+ struct osmo_gprs_sndcp_prim *sndcp_prim_tx;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(snme->sne); i++) {
+ struct gprs_sndcp_entity *sne_i = snme->sne[i];
+ if (!sne_i)
+ continue;
+ if (sne_i->llc_sapi != sapi)
+ continue;
+ LOGSNE(sne_i, LOGL_DEBUG, "LL-XID.ind: Found SNE SAPI=%u\n", sapi);
+ sne = sne_i;
+ break;
+ }
+ if (!sne) {
+ LOGSNME(snme, LOGL_ERROR, "LL-XID.ind: No SNDCP entity found having sent a
LL-XID.ind (SAPI=%u)\n", sapi);
+ return -EINVAL;
+ }
/* Some phones send zero byte length SNDCP frames
* and do require a confirmation response. */
@@ -923,7 +947,7 @@
/* Parse SNDCP-CID XID-Field */
- comp_fields = gprs_sndcp_parse_xid(&version, g_ctx,
+ comp_fields = gprs_sndcp_parse_xid(&version, snme,
l3params,
l3params_len,
NULL);
@@ -954,9 +978,12 @@
}
}
- /* FIXME: push SN-XID.ind up to SGSN/MS here, and below should be part of handling
SN-XID.rsp from SGSN/MS. */
- rc = gprs_sndcp_sne_handle_sn_xid_rsp(snme, sapi, comp_fields);
- talloc_free(comp_fields);
+ TALLOC_FREE(sne->l3_xid_comp_fields_req_from_peer);
+ sne->l3_xid_comp_fields_req_from_peer = comp_fields;
+
+ /* Trigger SN-XID.ind to upper layers: */
+ sndcp_prim_tx = gprs_sndcp_prim_alloc_sn_xid_ind(sne->snme->tlli,
sne->llc_sapi, sne->nsapi);
+ rc = gprs_sndcp_prim_call_up_cb(sndcp_prim_tx);
return rc;
}
@@ -965,7 +992,7 @@
*/
int gprs_sndcp_snme_handle_llc_ll_xid_cnf(struct gprs_sndcp_mgmt_entity *snme, uint32_t
sapi, uint8_t *l3params, unsigned int l3params_len)
{
- /* Note: This function handles an incoming SNDCP-XID confirmiation.
+ /* Note: This function handles an incoming SNDCP-XID confirmation.
* Since the confirmation fields may lack important parameters we
* will reconstruct these missing fields using the original request
* we have sent. After that we will create (or delete) the
diff --git a/src/sndcp/sndcp_prim.c b/src/sndcp/sndcp_prim.c
index 7dd9d43..63591d7 100644
--- a/src/sndcp/sndcp_prim.c
+++ b/src/sndcp/sndcp_prim.c
@@ -206,11 +206,22 @@
return sndcp_prim;
}
+/* 5.1.1.5 SN-XID.indication */
+struct osmo_gprs_sndcp_prim *gprs_sndcp_prim_alloc_sn_xid_ind(uint32_t tlli, uint8_t
sapi, uint8_t nsapi)
+{
+ struct osmo_gprs_sndcp_prim *sndcp_prim;
+ sndcp_prim = sndcp_prim_sn_alloc(OSMO_GPRS_SNDCP_SN_XID, PRIM_OP_INDICATION, 0);
+ sndcp_prim->sn.tlli = tlli;
+ sndcp_prim->sn.sapi = sapi;
+ sndcp_prim->sn.xid_ind.nsapi = nsapi;
+ return sndcp_prim;
+}
+
/* 5.1.1.7 SN-XID.response */
struct osmo_gprs_sndcp_prim *osmo_gprs_sndcp_prim_alloc_sn_xid_rsp(uint32_t tlli, uint8_t
sapi, uint8_t nsapi)
{
struct osmo_gprs_sndcp_prim *sndcp_prim;
- sndcp_prim = sndcp_prim_sn_alloc(OSMO_GPRS_SNDCP_SN_XID, PRIM_OP_REQUEST, 0);
+ sndcp_prim = sndcp_prim_sn_alloc(OSMO_GPRS_SNDCP_SN_XID, PRIM_OP_RESPONSE, 0);
sndcp_prim->sn.tlli = tlli;
sndcp_prim->sn.sapi = sapi;
sndcp_prim->sn.xid_rsp.nsapi = nsapi;
@@ -358,6 +369,28 @@
return rc;
}
+/* 5.1.1.7 SN-XID.response:*/
+static int gprs_sndcp_prim_handle_sndcp_sn_xid_rsp(struct osmo_gprs_sndcp_prim
*sndcp_prim)
+{
+ int rc;
+ struct gprs_sndcp_entity *sne;
+
+ sne = gprs_sndcp_sne_by_dlci_nsapi(sndcp_prim->sn.tlli, sndcp_prim->sn.sapi,
+ sndcp_prim->sn.xid_rsp.nsapi);
+ if (!sne) {
+ LOGSNDCP(LOGL_ERROR, "Message for non-existing SNDCP Entity "
+ "(TLLI=%08x, SAPI=%u, NSAPI=%u)\n",
+ sndcp_prim->sn.tlli, sndcp_prim->sn.sapi,
+ sndcp_prim->sn.xid_rsp.nsapi);
+ rc = -EIO;
+ goto ret_free;
+ }
+ rc = gprs_sndcp_sne_handle_sn_xid_rsp(sne, sndcp_prim);
+ret_free:
+ msgb_free(sndcp_prim->oph.msg);
+ return rc;
+}
+
/* SNDCP higher layers push SNDCP primitive down to SNDCP layer: */
int osmo_gprs_sndcp_prim_upper_down(struct osmo_gprs_sndcp_prim *sndcp_prim)
{
@@ -379,6 +412,9 @@
case OSMO_PRIM(OSMO_GPRS_SNDCP_SN_XID, PRIM_OP_REQUEST):
rc = gprs_sndcp_prim_handle_sndcp_sn_xid_req(sndcp_prim);
break;
+ case OSMO_PRIM(OSMO_GPRS_SNDCP_SN_XID, PRIM_OP_RESPONSE):
+ rc = gprs_sndcp_prim_handle_sndcp_sn_xid_rsp(sndcp_prim);
+ break;
default:
rc = gprs_sndcp_prim_handle_unsupported(sndcp_prim);
}
diff --git a/tests/sndcp/sndcp_prim_test.c b/tests/sndcp/sndcp_prim_test.c
index c2e1231..e8c4a7e 100644
--- a/tests/sndcp/sndcp_prim_test.c
+++ b/tests/sndcp/sndcp_prim_test.c
@@ -137,7 +137,7 @@
rc = osmo_gprs_sndcp_prim_dispatch_snsm(sndcp_prim);
OSMO_ASSERT(rc == 0);
- /* SN-XID.Req: */
+ /* Submit SN-XID.Req, triggers rx of LL-XID.Req: */
sndcp_prim = osmo_gprs_sndcp_prim_alloc_sn_xid_req(tlli, ll_sapi, nsapi);
OSMO_ASSERT(sndcp_prim);
sndcp_prim->sn.xid_req.pcomp_rfc1144.active = true;
@@ -145,18 +145,24 @@
rc = osmo_gprs_sndcp_prim_upper_down(sndcp_prim);
OSMO_ASSERT(rc == 0);
- /* SN-XID.Cnf: */
+ /* Submit LL-XID.Cnf, triggers rx of LL-XID.cnf */
llc_prim = gprs_llc_prim_alloc_ll_xid_cnf(tlli, ll_sapi, (uint8_t *)sndcp_xid,
sizeof(sndcp_xid));
OSMO_ASSERT(llc_prim);
rc = osmo_gprs_sndcp_prim_lower_up(llc_prim);
OSMO_ASSERT(rc == 0);
- /* SN-XID.Ind: */
+ /* Submit LL-XID.Ind, triggers rx of SN-XID.Ind: */
llc_prim = gprs_llc_prim_alloc_ll_xid_ind(tlli, ll_sapi, (uint8_t *)sndcp_xid,
sizeof(sndcp_xid));
OSMO_ASSERT(llc_prim);
rc = osmo_gprs_sndcp_prim_lower_up(llc_prim);
OSMO_ASSERT(rc == 0);
+ /* Submit SN-XID.Rsp, triggers rx of LL-XID.Rsp */
+ sndcp_prim = osmo_gprs_sndcp_prim_alloc_sn_xid_rsp(tlli, ll_sapi, nsapi);
+ OSMO_ASSERT(sndcp_prim);
+ rc = osmo_gprs_sndcp_prim_upper_down(sndcp_prim);
+ OSMO_ASSERT(rc == 0);
+
OSMO_ASSERT(osmo_hexparse(sndcp_data_hex, sndcp_data, sizeof(sndcp_data)) > 0);
llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(tlli, ll_sapi, (uint8_t *)sndcp_data,
sizeof(sndcp_data));
OSMO_ASSERT(llc_prim);
diff --git a/tests/sndcp/sndcp_prim_test.err b/tests/sndcp/sndcp_prim_test.err
index 5d12fad..f27486d 100644
--- a/tests/sndcp/sndcp_prim_test.err
+++ b/tests/sndcp/sndcp_prim_test.err
@@ -75,6 +75,7 @@
DLGLOBAL DEBUG SNME(e1c5d364) Rejecting RFC1144 header compression...
DLGLOBAL DEBUG SNME(e1c5d364) Rejecting ROHC header compression...
DLGLOBAL INFO Rx from lower layers: LL-XID.indication
+DLGLOBAL DEBUG SNE(e1c5d364,SNDCP3,5) LL-XID.ind: Found SNE SAPI=3
DLGLOBAL DEBUG SNME(e1c5d364) LL-XID.cnf requested comp_fields:
DLGLOBAL DEBUG SNDCP-XID:
DLGLOBAL DEBUG struct gprs_sndcp_comp_field {
@@ -132,7 +133,8 @@
DLGLOBAL DEBUG }
DLGLOBAL DEBUG SNME(e1c5d364) Rejecting RFC1144 header compression...
DLGLOBAL DEBUG SNME(e1c5d364) Rejecting ROHC header compression...
-DLGLOBAL DEBUG SNME(e1c5d364) SN-XID.rsp comp_fields:
+DLGLOBAL INFO Rx from upper layers: SN-XID.response
+DLGLOBAL DEBUG SNE(e1c5d364,SNDCP3,5) SN-XID.rsp comp_fields:
DLGLOBAL DEBUG SNDCP-XID:
DLGLOBAL DEBUG struct gprs_sndcp_comp_field {
DLGLOBAL DEBUG entity=0;
diff --git a/tests/sndcp/sndcp_prim_test.ok b/tests/sndcp/sndcp_prim_test.ok
index 1789413..4a635fc 100644
--- a/tests/sndcp/sndcp_prim_test.ok
+++ b/tests/sndcp/sndcp_prim_test.ok
@@ -1,5 +1,6 @@
==== test_sndcp_prim() [start] ====
test_sndcp_prim_down_cb(): Rx LL-XID.request
+test_sndcp_prim_up_cb(): Rx SN-XID.indication
test_sndcp_prim_down_cb(): Rx LL-XID.response
test_sndcp_prim_up_cb(): Rx SN-UNITDATA.indication TLLI=0xe1c5d364 SAPI=SNDCP3 NSAPI=5
NPDU=[75 22 fa 7c ff d9 56 ba 86 c7 2a f3 d2 1d ce bc 88 3a 8e b6 24 7d de 26 6a 58 de 29
be 96 d2 40 94 7f 9f 4d f5 9c 61 d4 19 e9 9a 58 75 21 21 a9 fd 1f d7 96 90 a7 3f fe 5b 59
f0 e7 c1 52 2c aa a1 39 b6 c5 fd 68 2e fc f4 c0 10 9b 7a 64 9d ae 3a ff a3 0f b0 56 7d 4b
52 33 74 13 67 44 6a ce 62 45 ea cb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 ]
test_sndcp_prim_down_cb(): Rx LL-UNITDATA.request TLLI=0xe1c5d364 SAPI=SNDCP3 L3=[65 00
00 00 73 6f 6d 65 2d 6e 70 64 75 2d 64 61 74 61 2d 6c 69 6b 65 2d 61 6e 2d 69 70 2d 70 6b
74 00 ]
--
To view, visit
https://gerrit.osmocom.org/c/libosmo-gprs/+/30907
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: libosmo-gprs
Gerrit-Branch: master
Gerrit-Change-Id: I0a5069fd3dc0d6c3dd28aeae09b51c49dd8be92d
Gerrit-Change-Number: 30907
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: newchange