pespin has submitted this change. ( 
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, 95 insertions(+), 16 deletions(-)

Approvals:
  Jenkins Builder: Verified
  fixeria: Looks good to me, but someone else must approve
  msuraev: Looks good to me, but someone else must approve
  pespin: Looks good to me, approved



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..252ba06 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 comp_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, sne,
                                           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 09c37b7..63591d7 100644
--- a/src/sndcp/sndcp_prim.c
+++ b/src/sndcp/sndcp_prim.c
@@ -206,6 +206,17 @@
        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)
 {
@@ -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: 4
Gerrit-Owner: pespin <pes...@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanits...@sysmocom.de>
Gerrit-Reviewer: msuraev <msur...@sysmocom.de>
Gerrit-Reviewer: pespin <pes...@sysmocom.de>
Gerrit-CC: daniel <dwillm...@sysmocom.de>
Gerrit-CC: laforge <lafo...@osmocom.org>
Gerrit-CC: lynxis lazus <lyn...@fe80.eu>
Gerrit-MessageType: merged

Reply via email to