gprs_ns2: inform the NS user (BSSGP) about the MTU of a NSE
The BSSGP layer needs to know the MTU of the NS UNIDATA payload.
The MTU can be 0 if the NSE doesn't contain any NSVC.
Every status indication will contain the mtu value.
The MTU in the status indication contains the maximum transfer
unit of a BSSGP message. From NS side the maximum SDU.
Related: OS#4889
Change-Id: I5016b295db6185ec131d83089cf6c806e34ef1b6
diff --git a/src/gb/gprs_ns2.c b/src/gb/gprs_ns2.c
index 99a7415..9302a16 100644
--- a/src/gb/gprs_ns2.c
+++ b/src/gb/gprs_ns2.c
@@ -217,6 +217,7 @@
{ GPRS_NS2_AFF_CAUSE_RECOVERY, "NSE recovery" },
{ GPRS_NS2_AFF_CAUSE_SNS_CONFIGURED, "NSE SNS configured" },
{ GPRS_NS2_AFF_CAUSE_SNS_FAILURE, "NSE SNS failure" },
+ { GPRS_NS2_AFF_CAUSE_MTU_CHANGE, "NSE MTU changed" },
{ 0, NULL }
};
@@ -496,15 +497,20 @@
nsp.u.status.transfer = ns2_count_transfer_cap(nse, bvci);
nsp.u.status.first = nse->first;
nsp.u.status.persistent = nse->persistent;
+ if (nse->mtu < 4)
+ nsp.u.status.mtu = 0;
+ else
+ nsp.u.status.mtu = nse->mtu - 4; /* 1 Byte NS PDU type, 1 Byte NS SDU control, 2 Byte BVCI */
+
if (nsvc) {
nsp.u.status.nsvc = gprs_ns2_ll_str_buf(nsvc_str, sizeof(nsvc_str), nsvc);
- LOGNSVC(nsvc, LOGL_NOTICE, "NS-STATUS.ind(bvci=%05u): cause=%s, transfer=%d, first=%d\n",
+ LOGNSVC(nsvc, LOGL_NOTICE, "NS-STATUS.ind(bvci=%05u): cause=%s, transfer=%d, first=%d, mtu=%d\n",
nsp.bvci, gprs_ns2_aff_cause_prim_str(nsp.u.status.cause),
- nsp.u.status.transfer, nsp.u.status.first);
+ nsp.u.status.transfer, nsp.u.status.first, nse->mtu);
} else {
- LOGNSE(nse, LOGL_NOTICE, "NS-STATUS.ind(bvci=%05u): cause=%s, transfer=%d, first=%d\n",
+ LOGNSE(nse, LOGL_NOTICE, "NS-STATUS.ind(bvci=%05u): cause=%s, transfer=%d, first=%d, mtu=%d\n",
nsp.bvci, gprs_ns2_aff_cause_prim_str(nsp.u.status.cause),
- nsp.u.status.transfer, nsp.u.status.first);
+ nsp.u.status.transfer, nsp.u.status.first, nse->mtu);
}
osmo_prim_init(&nsp.oph, SAP_NS, GPRS_NS2_PRIM_STATUS, PRIM_OP_INDICATION, NULL);
@@ -548,6 +554,7 @@
llist_add(&nsvc->list, &nse->nsvc);
llist_add(&nsvc->blist, &bind->nsvc);
+ ns2_nse_update_mtu(nse);
return nsvc;
@@ -746,6 +753,7 @@
nse->nsei = nsei;
nse->nsi = nsi;
nse->first = true;
+ nse->mtu = 0;
llist_add(&nse->list, &nsi->nse);
INIT_LLIST_HEAD(&nse->nsvc);
@@ -1334,6 +1342,31 @@
array[i] = bind;
}
+void ns2_nse_update_mtu(struct gprs_ns2_nse *nse)
+{
+ struct gprs_ns2_vc *nsvc;
+ int mtu = 0;
+
+ if (llist_empty(&nse->nsvc)) {
+ nse->mtu = 0;
+ return;
+ }
+
+ llist_for_each_entry(nsvc, &nse->nsvc, list) {
+ if (mtu == 0)
+ mtu = nsvc->bind->mtu;
+ else if (mtu > nsvc->bind->mtu)
+ mtu = nsvc->bind->mtu;
+ }
+
+ if (nse->mtu == mtu)
+ return;
+
+ nse->mtu = mtu;
+ if (nse->alive)
+ ns2_prim_status_ind(nsvc->nse, NULL, 0, GPRS_NS2_AFF_CAUSE_MTU_CHANGE);
+}
+
/*! calculate the transfer capabilities for a nse
* \param nse the nse to count the transfer capability
* \param bvci a bvci - unused