<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/13013">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">gprs_ns: Add code for SNS-SIZE and SNS-CONFIG encoding<br><br>Modern NS specifications contain a SNS (Sub Network Service) for<br>negotiating IP/port/weight parameters of NS-over-IP links dynamically.<br><br>This patch adds message encoding routines for SNS-CONFIG, SNS-SIZE<br>and their respective acknowledgements.<br><br>Related: OS#3372<br>Change-Id: I5c47e1c3c10deb89a7470ee2c03adfc174accc93<br>---<br>M include/osmocom/gprs/protocol/gsm_08_16.h<br>M src/gb/Makefile.am<br>A src/gb/gb_internal.h<br>M src/gb/gprs_ns.c<br>4 files changed, 207 insertions(+), 3 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/gprs/protocol/gsm_08_16.h b/include/osmocom/gprs/protocol/gsm_08_16.h</span><br><span>index fc74336..15d92d3 100644</span><br><span>--- a/include/osmocom/gprs/protocol/gsm_08_16.h</span><br><span>+++ b/include/osmocom/gprs/protocol/gsm_08_16.h</span><br><span>@@ -17,6 +17,15 @@</span><br><span>    uint8_t data[0];        /*!< variable-length payload */</span><br><span> } __attribute__((packed));</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Section 10.3.2c List of IP4 Elements */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_ns_ie_ip4_elem {</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t ip_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint16_t udp_port;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t sig_weight;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t data_weight;</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> extern const struct value_string gprs_ns_pdu_strings[];</span><br><span> </span><br><span> /*! NS PDU Type (TS 08.16, Section 10.3.7, Table 14) */</span><br><span>diff --git a/src/gb/Makefile.am b/src/gb/Makefile.am</span><br><span>index 65b73fe..d074092 100644</span><br><span>--- a/src/gb/Makefile.am</span><br><span>+++ b/src/gb/Makefile.am</span><br><span>@@ -6,7 +6,7 @@</span><br><span> AM_CFLAGS = -Wall ${GCC_FVISIBILITY_HIDDEN} -fno-strict-aliasing $(TALLOC_CFLAGS)</span><br><span> </span><br><span> # FIXME: this should eventually go into a milenage/Makefile.am</span><br><span style="color: hsl(0, 100%, 40%);">-noinst_HEADERS = common_vty.h</span><br><span style="color: hsl(120, 100%, 40%);">+noinst_HEADERS = common_vty.h gb_internal.h</span><br><span> </span><br><span> if ENABLE_GB</span><br><span> lib_LTLIBRARIES = libosmogb.la</span><br><span>diff --git a/src/gb/gb_internal.h b/src/gb/gb_internal.h</span><br><span>new file mode 100644</span><br><span>index 0000000..c1fa8e1</span><br><span>--- /dev/null</span><br><span>+++ b/src/gb/gb_internal.h</span><br><span>@@ -0,0 +1,19 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/tlv.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gprs/gprs_ns.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns_tx_sns_ack(struct gprs_nsvc *nsvc, uint8_t trans_id, uint8_t *cause,</span><br><span style="color: hsl(120, 100%, 40%);">+                    const struct gprs_ns_ie_ip4_elem *ip4_elems,unsigned int num_ip4_elems);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns_tx_sns_config(struct gprs_nsvc *nsvc, bool end_flag,</span><br><span style="color: hsl(120, 100%, 40%);">+                     const struct gprs_ns_ie_ip4_elem *ip4_elems,</span><br><span style="color: hsl(120, 100%, 40%);">+                          unsigned int num_ip4_elems);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns_tx_sns_config_ack(struct gprs_nsvc *nsvc, uint8_t *cause);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns_tx_sns_size(struct gprs_nsvc *nsvc, bool reset_flag, uint16_t max_nr_nsvc,</span><br><span style="color: hsl(120, 100%, 40%);">+                    uint16_t *ip4_ep_nr, uint16_t *ip6_ep_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns_tx_sns_size_ack(struct gprs_nsvc *nsvc, uint8_t *cause);</span><br><span>diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c</span><br><span>index 976a101..660dfec 100644</span><br><span>--- a/src/gb/gprs_ns.c</span><br><span>+++ b/src/gb/gprs_ns.c</span><br><span>@@ -1,8 +1,9 @@</span><br><span> /*! \file gprs_ns.c</span><br><span>  * GPRS Networks Service (NS) messages on the Gb interface.</span><br><span style="color: hsl(0, 100%, 40%);">- * 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05). */</span><br><span style="color: hsl(120, 100%, 40%);">+ * 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05)</span><br><span style="color: hsl(120, 100%, 40%);">+ * as well as its successor 3GPP TS 48.016 */</span><br><span> /*</span><br><span style="color: hsl(0, 100%, 40%);">- * (C) 2009-2017 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2009-2018 by Harald Welte <laforge@gnumonks.org></span><br><span>  * (C) 2016-2017 sysmocom - s.f.m.c. GmbH</span><br><span>  *</span><br><span>  * All Rights Reserved</span><br><span>@@ -86,6 +87,7 @@</span><br><span> #include <osmocom/gprs/gprs_ns_frgre.h></span><br><span> </span><br><span> #include "common_vty.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "gb_internal.h"</span><br><span> </span><br><span> #define ns_set_state(ns_, st_) ns_set_state_with_log(ns_, st_, false, __FILE__, __LINE__)</span><br><span> #define ns_set_remote_state(ns_, st_) ns_set_state_with_log(ns_, st_, true, __FILE__, __LINE__)</span><br><span>@@ -99,6 +101,12 @@</span><br><span>          [NS_IE_PDU]     = { TLV_TYPE_TvLV, 0 },</span><br><span>              [NS_IE_BVCI]    = { TLV_TYPE_TvLV, 0 },</span><br><span>              [NS_IE_NSEI]    = { TLV_TYPE_TvLV, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+               [NS_IE_IPv4_LIST] = { TLV_TYPE_TvLV, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+             [NS_IE_IPv6_LIST] = { TLV_TYPE_TvLV, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+             [NS_IE_MAX_NR_NSVC] = { TLV_TYPE_FIXED, 2 },</span><br><span style="color: hsl(120, 100%, 40%);">+          [NS_IE_IPv4_EP_NR] = { TLV_TYPE_FIXED, 2 },</span><br><span style="color: hsl(120, 100%, 40%);">+           [NS_IE_IPv6_EP_NR] = { TLV_TYPE_FIXED, 2 },</span><br><span style="color: hsl(120, 100%, 40%);">+           [NS_IE_RESET_FLAG] = { TLV_TYPE_TV, 0 },</span><br><span>     },</span><br><span> };</span><br><span> </span><br><span>@@ -750,6 +758,174 @@</span><br><span>         return gprs_ns_tx(nsvc, msg);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Encode + Transmit a SNS-ACK as per Section 9.3.1.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] nsvc NS-VC through which to transmit the ACK</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] trans_id Transaction ID which to acknowledge</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] cause Pointer to cause value (NULL if no cause to be sent)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] ip4_elems Array of IPv4 Elements</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] num_ip4_elems number of ip4_elems</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success; negative in case of error */</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns_tx_sns_ack(struct gprs_nsvc *nsvc, uint8_t trans_id, uint8_t *cause,</span><br><span style="color: hsl(120, 100%, 40%);">+                      const struct gprs_ns_ie_ip4_elem *ip4_elems,</span><br><span style="color: hsl(120, 100%, 40%);">+                  unsigned int num_ip4_elems)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct msgb *msg = gprs_ns_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gprs_ns_hdr *nsh;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t nsei;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      log_set_context(LOG_CTX_GB_NSVC, nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     nsei = osmo_htons(nsvc->nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   msg->l2h = msgb_put(msg, sizeof(*nsh));</span><br><span style="color: hsl(120, 100%, 40%);">+    nsh = (struct gprs_ns_hdr *) msg->l2h;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   nsh->pdu_type = SNS_PDUT_ACK;</span><br><span style="color: hsl(120, 100%, 40%);">+      msgb_tvlv_put(msg, NS_IE_NSEI, 2, (uint8_t *)&nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+      msgb_v_put(msg, trans_id);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (cause)</span><br><span style="color: hsl(120, 100%, 40%);">+            msgb_tvlv_put(msg, NS_IE_CAUSE, 1, cause);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (ip4_elems) {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* List of IP4 Elements 10.3.2c */</span><br><span style="color: hsl(120, 100%, 40%);">+            msgb_tvlv_put(msg, NS_IE_IPv4_LIST,</span><br><span style="color: hsl(120, 100%, 40%);">+                         num_ip4_elems*sizeof(struct gprs_ns_ie_ip4_elem),</span><br><span style="color: hsl(120, 100%, 40%);">+                             (const uint8_t *)ip4_elems);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     /* FIXME: List of IP6 elements 10.3.2d */</span><br><span style="color: hsl(120, 100%, 40%);">+     return gprs_ns_tx(nsvc, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Encode + Transmit a SNS-CONFIG as per Section 9.3.4.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] nsvc NS-VC through which to transmit the SNS-CONFIG</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] end_flag Whether or not this is the last SNS-CONFIG</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] ip4_elems Array of IPv4 Elements</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] num_ip4_elems number of ip4_elems</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success; negative in case of error */</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns_tx_sns_config(struct gprs_nsvc *nsvc, bool end_flag,</span><br><span style="color: hsl(120, 100%, 40%);">+                      const struct gprs_ns_ie_ip4_elem *ip4_elems,</span><br><span style="color: hsl(120, 100%, 40%);">+                          unsigned int num_ip4_elems)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct msgb *msg = gprs_ns_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gprs_ns_hdr *nsh;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t nsei;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      log_set_context(LOG_CTX_GB_NSVC, nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     nsei = osmo_htons(nsvc->nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   msg->l2h = msgb_put(msg, sizeof(*nsh));</span><br><span style="color: hsl(120, 100%, 40%);">+    nsh = (struct gprs_ns_hdr *) msg->l2h;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   nsh->pdu_type = SNS_PDUT_CONFIG;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_v_put(msg, end_flag ? 0x01 : 0x00);</span><br><span style="color: hsl(120, 100%, 40%);">+      msgb_tvlv_put(msg, NS_IE_NSEI, 2, (uint8_t *)&nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* List of IP4 Elements 10.3.2c */</span><br><span style="color: hsl(120, 100%, 40%);">+    msgb_tvlv_put(msg, NS_IE_IPv4_LIST, num_ip4_elems*sizeof(struct gprs_ns_ie_ip4_elem),</span><br><span style="color: hsl(120, 100%, 40%);">+                 (const uint8_t *)ip4_elems);</span><br><span style="color: hsl(120, 100%, 40%);">+  /* FIXME: List of IP6 elements 10.3.2d */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return gprs_ns_tx(nsvc, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Encode + Transmit a SNS-CONFIG-ACK as per Section 9.3.5.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] nsvc NS-VC through which to transmit the SNS-CONFIG-ACK</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] cause Pointer to cause value (NULL if no cause to be sent)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success; negative in case of error */</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns_tx_sns_config_ack(struct gprs_nsvc *nsvc, uint8_t *cause)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct msgb *msg = gprs_ns_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gprs_ns_hdr *nsh;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t nsei;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      log_set_context(LOG_CTX_GB_NSVC, nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     nsei = osmo_htons(nsvc->nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   msg->l2h = msgb_put(msg, sizeof(*nsh));</span><br><span style="color: hsl(120, 100%, 40%);">+    nsh = (struct gprs_ns_hdr *) msg->l2h;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   nsh->pdu_type = SNS_PDUT_CONFIG_ACK;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     msgb_tvlv_put(msg, NS_IE_NSEI, 2, (uint8_t *)&nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (cause)</span><br><span style="color: hsl(120, 100%, 40%);">+            msgb_tvlv_put(msg, NS_IE_CAUSE, 1, cause);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return gprs_ns_tx(nsvc, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Encode + transmit a SNS-SIZE as per Section 9.3.7.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] nsvc NS-VC through which to transmit the SNS-SIZE</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] reset_flag Whether or not to add a RESET flag</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] max_nr_nsvc Maximum number of NS-VCs</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] ip4_ep_nr Number of IPv4 endpoints (NULL if none)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] ip6_ep_nr Number of IPv6 endpoints (NULL if none)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success; negative in case of error */</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns_tx_sns_size(struct gprs_nsvc *nsvc, bool reset_flag, uint16_t max_nr_nsvc,</span><br><span style="color: hsl(120, 100%, 40%);">+                        uint16_t *ip4_ep_nr, uint16_t *ip6_ep_nr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct msgb *msg = gprs_ns_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gprs_ns_hdr *nsh;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t nsei;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      log_set_context(LOG_CTX_GB_NSVC, nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     nsei = osmo_htons(nsvc->nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   msg->l2h = msgb_put(msg, sizeof(*nsh));</span><br><span style="color: hsl(120, 100%, 40%);">+    nsh = (struct gprs_ns_hdr *) msg->l2h;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   nsh->pdu_type = SNS_PDUT_SIZE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_tvlv_put(msg, NS_IE_NSEI, 2, (uint8_t *)&nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+      msgb_tv_put(msg, NS_IE_RESET_FLAG, reset_flag ? 0x01 : 0x00);</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_tv16_put(msg, NS_IE_MAX_NR_NSVC, max_nr_nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (ip4_ep_nr)</span><br><span style="color: hsl(120, 100%, 40%);">+                msgb_tv16_put(msg, NS_IE_IPv4_EP_NR, *ip4_ep_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (ip6_ep_nr)</span><br><span style="color: hsl(120, 100%, 40%);">+                msgb_tv16_put(msg, NS_IE_IPv6_EP_NR, *ip6_ep_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return gprs_ns_tx(nsvc, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Encode + Transmit a SNS-SIZE-ACK as per Section 9.3.8.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] nsvc NS-VC through which to transmit the SNS-SIZE-ACK</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] cause Pointer to cause value (NULL if no cause to be sent)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success; negative in case of error */</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns_tx_sns_size_ack(struct gprs_nsvc *nsvc, uint8_t *cause)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct msgb *msg = gprs_ns_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gprs_ns_hdr *nsh;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t nsei;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      log_set_context(LOG_CTX_GB_NSVC, nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     nsei = osmo_htons(nsvc->nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   msg->l2h = msgb_put(msg, sizeof(*nsh));</span><br><span style="color: hsl(120, 100%, 40%);">+    nsh = (struct gprs_ns_hdr *) msg->l2h;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   nsh->pdu_type = SNS_PDUT_SIZE_ACK;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       msgb_tvlv_put(msg, NS_IE_NSEI, 2, (uint8_t *)&nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (cause)</span><br><span style="color: hsl(120, 100%, 40%);">+            msgb_tvlv_put(msg, NS_IE_CAUSE, 1, cause);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return gprs_ns_tx(nsvc, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! High-level function for transmitting a NS-UNITDATA messsage</span><br><span>  *  \param[in] nsi NS-instance on which we shall transmit</span><br><span>  *  \param[in] msg struct msgb to be trasnmitted</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13013">change 13013</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/13013"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I5c47e1c3c10deb89a7470ee2c03adfc174accc93 </div>
<div style="display:none"> Gerrit-Change-Number: 13013 </div>
<div style="display:none"> Gerrit-PatchSet: 5 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-CC: Max <msuraev@sysmocom.de> </div>