<p>osmith has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-pcu/+/15459">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Forward ETWS Primary Notification to MS<br><br>Receive an Application Information Request from the BTS via PCU<br>interface. Construct a Packet Application Information message from it<br>(3GPP TS 44.060 11.2.47) and send it to all MS with active TBF.<br><br>The TTCN-3 test infrastructure to test this feature is not quite ready<br>yet, so I've added C unit tests instead.<br><br>Related: OS#4048<br>Change-Id: Ie35959f833f46bde5f2126314b6f96763f863b36<br>---<br>M include/osmocom/pcu/pcuif_proto.h<br>M src/Makefile.am<br>M src/bts.cpp<br>M src/bts.h<br>M src/gprs_ms.h<br>M src/gprs_rlcmac.cpp<br>M src/gprs_rlcmac.h<br>M src/gprs_rlcmac_sched.cpp<br>M src/pcu_l1_if.cpp<br>M tests/Makefile.am<br>A tests/app_info/AppInfoTest.cpp<br>A tests/app_info/AppInfoTest.err<br>A tests/app_info/AppInfoTest.ok<br>M tests/testsuite.at<br>14 files changed, 413 insertions(+), 30 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/59/15459/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/pcu/pcuif_proto.h b/include/osmocom/pcu/pcuif_proto.h</span><br><span>index 144fba6..fd989a5 100644</span><br><span>--- a/include/osmocom/pcu/pcuif_proto.h</span><br><span>+++ b/include/osmocom/pcu/pcuif_proto.h</span><br><span>@@ -13,6 +13,7 @@</span><br><span> #define PCU_IF_MSG_DATA_CNF        0x01    /* confirm (e.g. transmission on PCH) */</span><br><span> #define PCU_IF_MSG_DATA_IND 0x02    /* receive data from given channel */</span><br><span> #define PCU_IF_MSG_SUSP_REQ    0x03    /* BTS forwards GPRS SUSP REQ to PCU */</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCU_IF_MSG_APP_INFO_REQ        0x04    /* BTS asks PCU to transmit APP INFO via PACCH */</span><br><span> #define PCU_IF_MSG_RTS_REQ 0x10    /* ready to send request */</span><br><span> #define PCU_IF_MSG_DATA_CNF_DT   0x11    /* confirm (with direct tlli) */</span><br><span> #define PCU_IF_MSG_RACH_IND 0x22    /* receive RACH */</span><br><span>@@ -172,6 +173,13 @@</span><br><span>    uint8_t         identity_lv[9];</span><br><span> } __attribute__ ((packed));</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* BTS tells PCU to [once] send given application data via PACCH to all UE with active TBF */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_pcu_if_app_info_req {</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t         application_type; /* 4bit field, see TS 44.060 11.2.47 */</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t         len;              /* length of data */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t         data[162];        /* random size choice; ETWS needs 56 bytes */</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* BTS tells PCU about a GPRS SUSPENSION REQUEST received on DCCH */</span><br><span> struct gsm_pcu_if_susp_req {</span><br><span>       uint32_t        tlli;</span><br><span>@@ -198,6 +206,7 @@</span><br><span>          struct gsm_pcu_if_act_req       act_req;</span><br><span>             struct gsm_pcu_if_time_ind      time_ind;</span><br><span>            struct gsm_pcu_if_pag_req       pag_req;</span><br><span style="color: hsl(120, 100%, 40%);">+              struct gsm_pcu_if_app_info_req  app_info_req;</span><br><span>        } u;</span><br><span> } __attribute__ ((packed));</span><br><span> </span><br><span>diff --git a/src/Makefile.am b/src/Makefile.am</span><br><span>index 233e24d..7148267 100644</span><br><span>--- a/src/Makefile.am</span><br><span>+++ b/src/Makefile.am</span><br><span>@@ -69,7 +69,8 @@</span><br><span>         gprs_codel.c \</span><br><span>       coding_scheme.c \</span><br><span>    gprs_coding_scheme.cpp \</span><br><span style="color: hsl(0, 100%, 40%);">-        egprs_rlc_compression.cpp</span><br><span style="color: hsl(120, 100%, 40%);">+     egprs_rlc_compression.cpp \</span><br><span style="color: hsl(120, 100%, 40%);">+   gprs_rlcmac_sched.cpp</span><br><span> </span><br><span> bin_PROGRAMS = \</span><br><span>        osmo-pcu</span><br><span>diff --git a/src/bts.cpp b/src/bts.cpp</span><br><span>index 26dd401..6326cf3 100644</span><br><span>--- a/src/bts.cpp</span><br><span>+++ b/src/bts.cpp</span><br><span>@@ -216,6 +216,7 @@</span><br><span> {</span><br><span>         memset(&m_bts, 0, sizeof(m_bts));</span><br><span>        m_bts.bts = this;</span><br><span style="color: hsl(120, 100%, 40%);">+     m_bts.app_info = NULL;</span><br><span> </span><br><span>   /* initialize back pointers */</span><br><span>       for (size_t trx_no = 0; trx_no < ARRAY_SIZE(m_bts.trx); ++trx_no) {</span><br><span>@@ -259,6 +260,11 @@</span><br><span>                osmo_stat_item_group_free(m_statg);</span><br><span>          m_statg = NULL;</span><br><span>      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (m_bts.app_info) {</span><br><span style="color: hsl(120, 100%, 40%);">+         msgb_free(m_bts.app_info);</span><br><span style="color: hsl(120, 100%, 40%);">+            m_bts.app_info = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span> }</span><br><span> </span><br><span> BTS::~BTS()</span><br><span>diff --git a/src/bts.h b/src/bts.h</span><br><span>index 767605c..b238d44 100644</span><br><span>--- a/src/bts.h</span><br><span>+++ b/src/bts.h</span><br><span>@@ -164,6 +164,11 @@</span><br><span> </span><br><span>        /* Are we talking Gb with IP-SNS (true) or classic Gb? */</span><br><span>    bool gb_dialect_sns;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Packet Application Information (3GPP TS 44.060 11.2.47, usually ETWS primary message). We don't need to store</span><br><span style="color: hsl(120, 100%, 40%);">+   * more than one message, because they get sent so rarely. */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *app_info; /* Encoded as RLC/MAC message */</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t app_info_todo; /* Count of MS with active TBF, to which we did not send app_info yet */</span><br><span> };</span><br><span> </span><br><span> #ifdef __cplusplus</span><br><span>diff --git a/src/gprs_ms.h b/src/gprs_ms.h</span><br><span>index ad8ca1d..2bbfde1 100644</span><br><span>--- a/src/gprs_ms.h</span><br><span>+++ b/src/gprs_ms.h</span><br><span>@@ -40,6 +40,10 @@</span><br><span> struct BTS;</span><br><span> struct gprs_rlcmac_trx;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_ms {</span><br><span style="color: hsl(120, 100%, 40%);">+ bool app_info_send;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> class GprsMs {</span><br><span> public:</span><br><span>       struct Callback {</span><br><span>@@ -61,6 +65,8 @@</span><br><span>        GprsMs(BTS *bts, uint32_t tlli);</span><br><span>     ~GprsMs();</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        struct gprs_rlcmac_ms *ms_data() {return &m_ms_data;}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  void set_callback(Callback *cb) {m_cb = cb;}</span><br><span> </span><br><span>     void merge_old_ms(GprsMs *old_ms);</span><br><span>@@ -150,6 +156,7 @@</span><br><span>     gprs_rlcmac_ul_tbf *m_ul_tbf;</span><br><span>        gprs_rlcmac_dl_tbf *m_dl_tbf;</span><br><span>        LListHead<gprs_rlcmac_tbf> m_old_tbfs;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gprs_rlcmac_ms m_ms_data = {0};</span><br><span> </span><br><span>   uint32_t m_tlli;</span><br><span>     uint32_t m_new_ul_tlli;</span><br><span>diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp</span><br><span>index 5a223c1..1a62bfb 100644</span><br><span>--- a/src/gprs_rlcmac.cpp</span><br><span>+++ b/src/gprs_rlcmac.cpp</span><br><span>@@ -41,4 +41,34 @@</span><br><span>        return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Encode Application Information Request to Packet Application Information (3GPP TS 44.060 11.2.47) */</span><br><span style="color: hsl(120, 100%, 40%);">+struct msgb *gprs_rlcmac_app_info_msg(const struct gsm_pcu_if_app_info_req *req) {</span><br><span style="color: hsl(120, 100%, 40%);">+       struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t i;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t word;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     if (!req->len) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DRLCMAC, LOGL_ERROR, "Application Information Request with zero length received!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return NULL;</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%);">+   msg = msgb_alloc(req->len + 1, "app_info_msg");</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        word = 0x00;                                    /* 0-1: page mode: normal */</span><br><span style="color: hsl(120, 100%, 40%);">+  word |= (0x0F & req->application_type) << 6;       /* 2-5: application type */</span><br><span style="color: hsl(120, 100%, 40%);">+   word |= (0xC0 & req->data[0]) >> 6;                /* 6-7: first two data bits */</span><br><span style="color: hsl(120, 100%, 40%);">+        msgb_put_u8(msg, word);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i=0; i < req->len - 1; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+              word = req->data[i] << 2;              /* 0-6: last six data bits from current byte */</span><br><span style="color: hsl(120, 100%, 40%);">+               word |= (0xC0 & req->data[i + 1]) >> 6;    /* 7-8: first two data bits from next byte */</span><br><span style="color: hsl(120, 100%, 40%);">+         msgb_put_u8(msg, word);</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%);">+   word = (0xC0 & req->data[req->len -1]) << 2;    /* 0-6: last six data bits from last byte (rest is padding) */</span><br><span style="color: hsl(120, 100%, 40%);">+        msgb_put_u8(msg, word);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return msg;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h</span><br><span>index 7a3a7af..16cb05f 100644</span><br><span>--- a/src/gprs_rlcmac.h</span><br><span>+++ b/src/gprs_rlcmac.h</span><br><span>@@ -31,6 +31,7 @@</span><br><span> #include <osmocom/core/linuxlist.h></span><br><span> #include <osmocom/core/timer.h></span><br><span> #include <osmocom/core/bitvec.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/pcu/pcuif_proto.h></span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span>@@ -94,6 +95,8 @@</span><br><span> int gprs_rlcmac_paging_request(uint8_t *ptmsi, uint16_t ptmsi_len,</span><br><span>         const char *imsi);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct msgb *gprs_rlcmac_app_info_msg(const struct gsm_pcu_if_app_info_req *req);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts,</span><br><span>    uint8_t trx, uint8_t ts,</span><br><span>         uint32_t fn, uint8_t block_nr);</span><br><span>diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp</span><br><span>index 57756e3..4b74708 100644</span><br><span>--- a/src/gprs_rlcmac_sched.cpp</span><br><span>+++ b/src/gprs_rlcmac_sched.cpp</span><br><span>@@ -123,6 +123,37 @@</span><br><span>  return usf;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct msgb *sched_app_info(struct gprs_rlcmac_tbf *tbf) {</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gprs_rlcmac_ms *ms_data;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts_data;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct msgb *msg = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!tbf || !tbf->ms()->ms_data()->app_info_send)</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        ms_data = tbf->ms()->ms_data();</span><br><span style="color: hsl(120, 100%, 40%);">+ bts_data = BTS::main_bts()->bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (bts_data->app_info) {</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGP(DRLCMACSCHED, LOGL_DEBUG, "Sending Packet Application Information message\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         msg = msgb_copy(bts_data->app_info, "app_info_msg_sched");</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     else</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGP(DRLCMACSCHED, LOGL_ERROR, "MS has app_info_send flag set, but no Packet Application Information"</span><br><span style="color: hsl(120, 100%, 40%);">+                    " message stored in BTS!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        ms_data->app_info_send = false;</span><br><span style="color: hsl(120, 100%, 40%);">+    bts_data->app_info_todo--;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!bts_data->app_info_todo) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGP(DRLCMACSCHED, LOGL_DEBUG, "Packet Application Information successfully sent to all MS with active"</span><br><span style="color: hsl(120, 100%, 40%);">+                  " TBF\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             msgb_free(bts_data->app_info);</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_data->app_info = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     return msg;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static struct msgb *sched_select_ctrl_msg(</span><br><span>                   uint8_t trx, uint8_t ts, uint32_t fn,</span><br><span>                uint8_t block_nr, struct gprs_rlcmac_pdch *pdch,</span><br><span>@@ -134,37 +165,42 @@</span><br><span>         struct gprs_rlcmac_tbf *tbf = NULL;</span><br><span>  struct gprs_rlcmac_tbf *next_list[3] = { ul_ass_tbf, dl_ass_tbf, ul_ack_tbf };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      for (size_t i = 0; i < ARRAY_SIZE(next_list); ++i) {</span><br><span style="color: hsl(0, 100%, 40%);">-         tbf = next_list[(pdch->next_ctrl_prio + i) % 3];</span><br><span style="color: hsl(0, 100%, 40%);">-             if (!tbf)</span><br><span style="color: hsl(0, 100%, 40%);">-                       continue;</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Send Packet Application Information first (ETWS primary notifications) */</span><br><span style="color: hsl(120, 100%, 40%);">+  msg = sched_app_info(dl_ass_tbf);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           /*</span><br><span style="color: hsl(0, 100%, 40%);">-               * Assignments for the same direction have lower precedence,</span><br><span style="color: hsl(0, 100%, 40%);">-             * because they may kill the TBF when the CONTROL ACK is</span><br><span style="color: hsl(0, 100%, 40%);">-                 * received, thus preventing the others from being processed.</span><br><span style="color: hsl(0, 100%, 40%);">-            */</span><br><span style="color: hsl(0, 100%, 40%);">-             if (tbf == ul_ass_tbf && tbf->ul_ass_state_is(GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ))</span><br><span style="color: hsl(0, 100%, 40%);">-                      msg = ul_ass_tbf->create_packet_access_reject();</span><br><span style="color: hsl(0, 100%, 40%);">-             else if (tbf == ul_ass_tbf && tbf->direction ==</span><br><span style="color: hsl(0, 100%, 40%);">-                              GPRS_RLCMAC_DL_TBF)</span><br><span style="color: hsl(0, 100%, 40%);">-                     if (tbf->ul_ass_state_is(GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ))</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!msg) {</span><br><span style="color: hsl(120, 100%, 40%);">+           for (size_t i = 0; i < ARRAY_SIZE(next_list); ++i) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       tbf = next_list[(pdch->next_ctrl_prio + i) % 3];</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (!tbf)</span><br><span style="color: hsl(120, 100%, 40%);">+                             continue;</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%);">+                     * Assignments for the same direction have lower precedence,</span><br><span style="color: hsl(120, 100%, 40%);">+                   * because they may kill the TBF when the CONTROL ACK is</span><br><span style="color: hsl(120, 100%, 40%);">+                       * received, thus preventing the others from being processed.</span><br><span style="color: hsl(120, 100%, 40%);">+                  */</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (tbf == ul_ass_tbf && tbf->ul_ass_state_is(GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ))</span><br><span>                           msg = ul_ass_tbf->create_packet_access_reject();</span><br><span style="color: hsl(0, 100%, 40%);">-                     else</span><br><span style="color: hsl(0, 100%, 40%);">-                            msg = ul_ass_tbf->create_ul_ass(fn, ts);</span><br><span style="color: hsl(0, 100%, 40%);">-             else if (tbf == dl_ass_tbf && tbf->direction == GPRS_RLCMAC_UL_TBF)</span><br><span style="color: hsl(0, 100%, 40%);">-                  msg = dl_ass_tbf->create_dl_ass(fn, ts);</span><br><span style="color: hsl(0, 100%, 40%);">-             else if (tbf == ul_ack_tbf)</span><br><span style="color: hsl(0, 100%, 40%);">-                     msg = ul_ack_tbf->create_ul_ack(fn, ts);</span><br><span style="color: hsl(120, 100%, 40%);">+                   else if (tbf == ul_ass_tbf && tbf->direction ==</span><br><span style="color: hsl(120, 100%, 40%);">+                                    GPRS_RLCMAC_DL_TBF)</span><br><span style="color: hsl(120, 100%, 40%);">+                           if (tbf->ul_ass_state_is(GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ))</span><br><span style="color: hsl(120, 100%, 40%);">+                                 msg = ul_ass_tbf->create_packet_access_reject();</span><br><span style="color: hsl(120, 100%, 40%);">+                           else</span><br><span style="color: hsl(120, 100%, 40%);">+                                  msg = ul_ass_tbf->create_ul_ass(fn, ts);</span><br><span style="color: hsl(120, 100%, 40%);">+                   else if (tbf == dl_ass_tbf && tbf->direction == GPRS_RLCMAC_UL_TBF)</span><br><span style="color: hsl(120, 100%, 40%);">+                                msg = dl_ass_tbf->create_dl_ass(fn, ts);</span><br><span style="color: hsl(120, 100%, 40%);">+                   else if (tbf == ul_ack_tbf)</span><br><span style="color: hsl(120, 100%, 40%);">+                           msg = ul_ack_tbf->create_ul_ack(fn, ts);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-         if (!msg) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     tbf = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-                     continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (!msg) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           tbf = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+                           continue;</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%);">+                   pdch->next_ctrl_prio += 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                 pdch->next_ctrl_prio %= 3;</span><br><span style="color: hsl(120, 100%, 40%);">+                 break;</span><br><span>               }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               pdch->next_ctrl_prio += 1;</span><br><span style="color: hsl(0, 100%, 40%);">-           pdch->next_ctrl_prio %= 3;</span><br><span style="color: hsl(0, 100%, 40%);">-           break;</span><br><span>       }</span><br><span> </span><br><span>        if (!msg) {</span><br><span>diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp</span><br><span>index da85df4..90df70d 100644</span><br><span>--- a/src/pcu_l1_if.cpp</span><br><span>+++ b/src/pcu_l1_if.cpp</span><br><span>@@ -620,6 +620,42 @@</span><br><span>  return bssgp_tx_suspend(bctx->nsei, susp_req->tlli, &ra_id);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int pcu_rx_app_info_req(struct gsm_pcu_if_app_info_req *app_info_req)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      LListHead<GprsMs> *ms_iter;</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS *bts = BTS::main_bts();</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gprs_rlcmac_bts *bts_data = bts->bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      LOGP(DL1IF, LOGL_DEBUG, "Application Information Request received: type=0x%08x len=%i\n",</span><br><span style="color: hsl(120, 100%, 40%);">+        app_info_req->application_type, app_info_req->len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      bts_data->app_info_todo = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       llist_for_each(ms_iter, &bts->ms_store().ms_list()) {</span><br><span style="color: hsl(120, 100%, 40%);">+          GprsMs *ms = ms_iter->entry();</span><br><span style="color: hsl(120, 100%, 40%);">+             if (!ms->dl_tbf())</span><br><span style="color: hsl(120, 100%, 40%);">+                 continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_data->app_info_todo++;</span><br><span style="color: hsl(120, 100%, 40%);">+         ms->ms_data()->app_info_send = true;</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%);">+   if (!bts_data->app_info_todo) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGP(DL1IF, LOGL_NOTICE, "Packet Application Information will not be sent, no subscribers with active"</span><br><span style="color: hsl(120, 100%, 40%);">+                   " TBF\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return -1;</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%);">+   if (bts_data->app_info) {</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGP(DL1IF, LOGL_NOTICE, "Previous Packet Application Information was not sent to all subscribers,"</span><br><span style="color: hsl(120, 100%, 40%);">+              " overwriting with new one\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                msgb_free(bts_data->app_info);</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%);">+   LOGP(DL1IF, LOGL_INFO, "Sending Packet Application Information to %i subscribers with active TBF\n",</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_data->app_info_todo);</span><br><span style="color: hsl(120, 100%, 40%);">+     bts_data->app_info = gprs_rlcmac_app_info_msg(app_info_req);</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int pcu_rx(uint8_t msg_type, struct gsm_pcu_if *pcu_prim)</span><br><span> {</span><br><span>     int rc = 0;</span><br><span>@@ -649,6 +685,9 @@</span><br><span>    case PCU_IF_MSG_SUSP_REQ:</span><br><span>            rc = pcu_rx_susp_req(&pcu_prim->u.susp_req);</span><br><span>          break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case PCU_IF_MSG_APP_INFO_REQ:</span><br><span style="color: hsl(120, 100%, 40%);">+         rc = pcu_rx_app_info_req(&pcu_prim->u.app_info_req);</span><br><span style="color: hsl(120, 100%, 40%);">+           break;</span><br><span>       default:</span><br><span>             LOGP(DL1IF, LOGL_ERROR, "Received unknown PCU msg type %d\n",</span><br><span>                      msg_type);</span><br><span>diff --git a/tests/Makefile.am b/tests/Makefile.am</span><br><span>index 887200d..42dade9 100644</span><br><span>--- a/tests/Makefile.am</span><br><span>+++ b/tests/Makefile.am</span><br><span>@@ -1,7 +1,7 @@</span><br><span> AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGB_CFLAGS) $(LIBOSMOGSM_CFLAGS) -I$(top_srcdir)/src/ -I$(top_srcdir)/include/</span><br><span> AM_LDFLAGS = -lrt -no-install</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-check_PROGRAMS = rlcmac/RLCMACTest alloc/AllocTest alloc/MslotTest tbf/TbfTest types/TypesTest ms/MsTest llist/LListTest llc/LlcTest codel/codel_test edge/EdgeTest bitcomp/BitcompTest fn/FnTest</span><br><span style="color: hsl(120, 100%, 40%);">+check_PROGRAMS = rlcmac/RLCMACTest alloc/AllocTest alloc/MslotTest tbf/TbfTest types/TypesTest ms/MsTest llist/LListTest llc/LlcTest codel/codel_test edge/EdgeTest bitcomp/BitcompTest fn/FnTest app_info/AppInfoTest</span><br><span> noinst_PROGRAMS = emu/pcu_emu</span><br><span> </span><br><span> rlcmac_RLCMACTest_SOURCES = rlcmac/RLCMACTest.cpp</span><br><span>@@ -108,6 +108,14 @@</span><br><span>       $(LIBOSMOCORE_LIBS) \</span><br><span>        $(COMMON_LA)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+app_info_AppInfoTest_SOURCES = app_info/AppInfoTest.cpp</span><br><span style="color: hsl(120, 100%, 40%);">+app_info_AppInfoTest_LDADD = \</span><br><span style="color: hsl(120, 100%, 40%);">+     $(top_builddir)/src/libgprs.la \</span><br><span style="color: hsl(120, 100%, 40%);">+      $(LIBOSMOGB_LIBS) \</span><br><span style="color: hsl(120, 100%, 40%);">+   $(LIBOSMOGSM_LIBS) \</span><br><span style="color: hsl(120, 100%, 40%);">+  $(LIBOSMOCORE_LIBS) \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(COMMON_LA)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> # The `:;' works around a Bash 3.2 bug when the output is not writeable.</span><br><span> $(srcdir)/package.m4: $(top_srcdir)/configure.ac</span><br><span>   :;{ \</span><br><span>@@ -138,7 +146,8 @@</span><br><span>  llist/LListTest.ok llist/LListTest.err \</span><br><span>     codel/codel_test.ok \</span><br><span>        edge/EdgeTest.ok \</span><br><span style="color: hsl(0, 100%, 40%);">-      fn/FnTest.ok</span><br><span style="color: hsl(120, 100%, 40%);">+  fn/FnTest.ok \</span><br><span style="color: hsl(120, 100%, 40%);">+        app_info/AppInfoTest.ok app_info/AppInfoTest.err</span><br><span> </span><br><span> DISTCLEANFILES = atconfig</span><br><span> </span><br><span>diff --git a/tests/app_info/AppInfoTest.cpp b/tests/app_info/AppInfoTest.cpp</span><br><span>new file mode 100644</span><br><span>index 0000000..eb73067</span><br><span>--- /dev/null</span><br><span>+++ b/tests/app_info/AppInfoTest.cpp</span><br><span>@@ -0,0 +1,181 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* Copyright (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(120, 100%, 40%);">+ * modify it under the terms of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * as published by the Free Software Foundation; either version 2</span><br><span style="color: hsl(120, 100%, 40%);">+ * of the License, or (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program; if not, write to the Free Software</span><br><span style="color: hsl(120, 100%, 40%);">+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.</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%);">+#include <cstdlib></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cstring></span><br><span style="color: hsl(120, 100%, 40%);">+#include <assert.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "gprs_rlcmac.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "bts.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+extern "C" {</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/vty/telnet_interface.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/vty/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></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/core/application.h></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%);">+using namespace std;</span><br><span style="color: hsl(120, 100%, 40%);">+gprs_rlcmac_dl_tbf *tbf1, *tbf2;</span><br><span style="color: hsl(120, 100%, 40%);">+GprsMs *ms1, *ms2;</span><br><span style="color: hsl(120, 100%, 40%);">+struct msgb *sched_app_info(struct gprs_rlcmac_tbf *tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* globals used by the code */</span><br><span style="color: hsl(120, 100%, 40%);">+void *tall_pcu_ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+int16_t spoof_mnc = 0, spoof_mcc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+bool spoof_mnc_3_digits = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void test_enc_zero_len() {</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gsm_pcu_if_app_info_req req = {0, 0, {0}};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   fprintf(stderr, "--- %s ---\n",  __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+ assert(gprs_rlcmac_app_info_msg(&req) == NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+   fprintf(stderr, "\n");</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%);">+void test_enc() {</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_pcu_if_app_info_req req = {0, 15, {0xff, 0x00, 0xff}};</span><br><span style="color: hsl(120, 100%, 40%);">+     const char *exp = "03 fc 03 fc 00 00 00 00 00 00 00 00 00 00 00 00 "; /* shifted by two bits to the right */</span><br><span style="color: hsl(120, 100%, 40%);">+        struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+     char *msg_dump;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     fprintf(stderr, "--- %s ---\n",  __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = gprs_rlcmac_app_info_msg(&req);</span><br><span style="color: hsl(120, 100%, 40%);">+     msg_dump = msgb_hexdump_c(tall_pcu_ctx, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       fprintf(stderr, "exp: %s\n", exp);</span><br><span style="color: hsl(120, 100%, 40%);">+  fprintf(stderr, "msg: %s\n", msg_dump);</span><br><span style="color: hsl(120, 100%, 40%);">+     assert(strcmp(msg_dump, exp) == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+       talloc_free(msg_dump);</span><br><span style="color: hsl(120, 100%, 40%);">+        fprintf(stderr, "\n");</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%);">+void test_pcu_rx_no_subscr_with_active_tbf()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gsm_pcu_if pcu_prim = {PCU_IF_MSG_APP_INFO_REQ, };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   fprintf(stderr, "--- %s ---\n",  __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+ pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);</span><br><span style="color: hsl(120, 100%, 40%);">+       fprintf(stderr, "\n");</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%);">+void prepare_bts_with_two_dl_tbf_subscr()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   BTS *bts = BTS::main_bts();</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gprs_rlcmac_bts *bts_data;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gprs_rlcmac_trx *trx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        fprintf(stderr, "--- %s ---\n",  __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       bts_data = bts->bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+        bts_data->alloc_algorithm = alloc_algorithm_b;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   trx = bts_data->trx;</span><br><span style="color: hsl(120, 100%, 40%);">+       trx->pdch[4].enable();</span><br><span style="color: hsl(120, 100%, 40%);">+     trx->pdch[5].enable();</span><br><span style="color: hsl(120, 100%, 40%);">+     trx->pdch[6].enable();</span><br><span style="color: hsl(120, 100%, 40%);">+     trx->pdch[7].enable();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ms1 = bts->ms_alloc(10, 11);</span><br><span style="color: hsl(120, 100%, 40%);">+       tbf1 = tbf_alloc_dl_tbf(bts_data, ms1, 0, 10, 11, false);</span><br><span style="color: hsl(120, 100%, 40%);">+     ms2 = bts->ms_alloc(12, 13);</span><br><span style="color: hsl(120, 100%, 40%);">+       tbf2 = tbf_alloc_dl_tbf(bts_data, ms2, 0, 12, 13, false);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   fprintf(stderr, "\n");</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%);">+void test_sched_app_info_ok()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm_pcu_if pcu_prim = {PCU_IF_MSG_APP_INFO_REQ, };</span><br><span style="color: hsl(120, 100%, 40%);">+     struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   fprintf(stderr, "--- %s ---\n",  __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+ pcu_prim.u.app_info_req = {0, 15, {0xff, 0x00, 0xff}};</span><br><span style="color: hsl(120, 100%, 40%);">+        pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     msg = sched_app_info(tbf1);</span><br><span style="color: hsl(120, 100%, 40%);">+   assert(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     msg = sched_app_info(tbf2);</span><br><span style="color: hsl(120, 100%, 40%);">+   assert(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     fprintf(stderr, "\n");</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%);">+void test_sched_app_info_missing_app_info_in_bts()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gprs_rlcmac_bts *bts_data = BTS::main_bts()->bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gsm_pcu_if pcu_prim = {PCU_IF_MSG_APP_INFO_REQ, };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   fprintf(stderr, "--- %s ---\n",  __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+ pcu_prim.u.app_info_req = {0, 15, {0xff, 0x00, 0xff}};</span><br><span style="color: hsl(120, 100%, 40%);">+        pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     msgb_free(bts_data->app_info);</span><br><span style="color: hsl(120, 100%, 40%);">+     bts_data->app_info = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       assert(sched_app_info(tbf1) == NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       fprintf(stderr, "\n");</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%);">+void test_pcu_rx_overwrite_app_info()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm_pcu_if pcu_prim = {PCU_IF_MSG_APP_INFO_REQ, };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   fprintf(stderr, "--- %s ---\n",  __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+ pcu_prim.u.app_info_req = {0, 15, {0xff, 0x00, 0xff}};</span><br><span style="color: hsl(120, 100%, 40%);">+        pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);</span><br><span style="color: hsl(120, 100%, 40%);">+       pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);</span><br><span style="color: hsl(120, 100%, 40%);">+       fprintf(stderr, "\n");</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%);">+void cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      fprintf(stderr, "--- %s ---\n",  __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS::main_bts()->cleanup();</span><br><span style="color: hsl(120, 100%, 40%);">+        talloc_free(tbf1);</span><br><span style="color: hsl(120, 100%, 40%);">+    talloc_free(tbf2);</span><br><span style="color: hsl(120, 100%, 40%);">+    /* FIXME: talloc report disabled, because bts->ms_alloc() in prepare_bts_with_two_dl_tbf_subscr() causes leak */</span><br><span style="color: hsl(120, 100%, 40%);">+   /* talloc_report_full(tall_pcu_ctx, stderr); */</span><br><span style="color: hsl(120, 100%, 40%);">+       talloc_free(tall_pcu_ctx);</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%);">+int main(int argc, char *argv[])</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  tall_pcu_ctx = talloc_named_const(NULL, 1, "AppInfoTest");</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);</span><br><span style="color: hsl(120, 100%, 40%);">+ log_set_use_color(osmo_stderr_target, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+     log_set_print_filename(osmo_stderr_target, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+        log_parse_category_mask(osmo_stderr_target, "DL1IF,1:DRLCMAC,3:DRLCMACSCHED,1");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  test_enc_zero_len();</span><br><span style="color: hsl(120, 100%, 40%);">+  test_enc();</span><br><span style="color: hsl(120, 100%, 40%);">+   test_pcu_rx_no_subscr_with_active_tbf();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    prepare_bts_with_two_dl_tbf_subscr();</span><br><span style="color: hsl(120, 100%, 40%);">+ test_sched_app_info_ok();</span><br><span style="color: hsl(120, 100%, 40%);">+     test_sched_app_info_missing_app_info_in_bts();</span><br><span style="color: hsl(120, 100%, 40%);">+        test_pcu_rx_overwrite_app_info();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   cleanup();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/tests/app_info/AppInfoTest.err b/tests/app_info/AppInfoTest.err</span><br><span>new file mode 100644</span><br><span>index 0000000..9c89094</span><br><span>--- /dev/null</span><br><span>+++ b/tests/app_info/AppInfoTest.err</span><br><span>@@ -0,0 +1,50 @@</span><br><span style="color: hsl(120, 100%, 40%);">+--- test_enc_zero_len ---</span><br><span style="color: hsl(120, 100%, 40%);">+Application Information Request with zero length received!</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+--- test_enc ---</span><br><span style="color: hsl(120, 100%, 40%);">+exp: 03 fc 03 fc 00 00 00 00 00 00 00 00 00 00 00 00 </span><br><span style="color: hsl(120, 100%, 40%);">+msg: 03 fc 03 fc 00 00 00 00 00 00 00 00 00 00 00 00 </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+--- test_pcu_rx_no_subscr_with_active_tbf ---</span><br><span style="color: hsl(120, 100%, 40%);">+Application Information Request received: type=0x00000000 len=0</span><br><span style="color: hsl(120, 100%, 40%);">+Packet Application Information will not be sent, no subscribers with active TBF</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+--- prepare_bts_with_two_dl_tbf_subscr ---</span><br><span style="color: hsl(120, 100%, 40%);">+Creating MS object, TLLI = 0x00000000</span><br><span style="color: hsl(120, 100%, 40%);">+Modifying MS object, TLLI = 0x00000000, MS class 0 -> 10</span><br><span style="color: hsl(120, 100%, 40%);">+Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11</span><br><span style="color: hsl(120, 100%, 40%);">+[DL] algo B <multi> (suggested TRX: 0): using 4 slots</span><br><span style="color: hsl(120, 100%, 40%);">+PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001.</span><br><span style="color: hsl(120, 100%, 40%);">+PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001.</span><br><span style="color: hsl(120, 100%, 40%);">+PDCH(TS 6, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001.</span><br><span style="color: hsl(120, 100%, 40%);">+PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001.</span><br><span style="color: hsl(120, 100%, 40%);">+Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+Creating MS object, TLLI = 0x00000000</span><br><span style="color: hsl(120, 100%, 40%);">+Modifying MS object, TLLI = 0x00000000, MS class 0 -> 12</span><br><span style="color: hsl(120, 100%, 40%);">+Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 13</span><br><span style="color: hsl(120, 100%, 40%);">+[DL] algo B <multi> (suggested TRX: 0): using 3 slots</span><br><span style="color: hsl(120, 100%, 40%);">+PDCH(TS 4, TRX 0): Attaching TBF(TFI=1 TLLI=0x00000000 DIR=DL STATE=NULL), 2 TBFs, USFs = 00, TFIs = 00000003.</span><br><span style="color: hsl(120, 100%, 40%);">+PDCH(TS 5, TRX 0): Attaching TBF(TFI=1 TLLI=0x00000000 DIR=DL STATE=NULL), 2 TBFs, USFs = 00, TFIs = 00000003.</span><br><span style="color: hsl(120, 100%, 40%);">+PDCH(TS 6, TRX 0): Attaching TBF(TFI=1 TLLI=0x00000000 DIR=DL STATE=NULL), 2 TBFs, USFs = 00, TFIs = 00000003.</span><br><span style="color: hsl(120, 100%, 40%);">+Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=1 TLLI=0x00000000 DIR=DL STATE=NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+--- test_sched_app_info_ok ---</span><br><span style="color: hsl(120, 100%, 40%);">+Application Information Request received: type=0x00000000 len=15</span><br><span style="color: hsl(120, 100%, 40%);">+Sending Packet Application Information to 2 subscribers with active TBF</span><br><span style="color: hsl(120, 100%, 40%);">+Sending Packet Application Information message</span><br><span style="color: hsl(120, 100%, 40%);">+Sending Packet Application Information message</span><br><span style="color: hsl(120, 100%, 40%);">+Packet Application Information successfully sent to all MS with active TBF</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+--- test_sched_app_info_missing_app_info_in_bts ---</span><br><span style="color: hsl(120, 100%, 40%);">+Application Information Request received: type=0x00000000 len=15</span><br><span style="color: hsl(120, 100%, 40%);">+Sending Packet Application Information to 2 subscribers with active TBF</span><br><span style="color: hsl(120, 100%, 40%);">+MS has app_info_send flag set, but no Packet Application Information message stored in BTS!</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+--- test_pcu_rx_overwrite_app_info ---</span><br><span style="color: hsl(120, 100%, 40%);">+Application Information Request received: type=0x00000000 len=15</span><br><span style="color: hsl(120, 100%, 40%);">+Sending Packet Application Information to 2 subscribers with active TBF</span><br><span style="color: hsl(120, 100%, 40%);">+Application Information Request received: type=0x00000000 len=15</span><br><span style="color: hsl(120, 100%, 40%);">+Previous Packet Application Information was not sent to all subscribers, overwriting with new one</span><br><span style="color: hsl(120, 100%, 40%);">+Sending Packet Application Information to 2 subscribers with active TBF</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+--- cleanup ---</span><br><span>diff --git a/tests/app_info/AppInfoTest.ok b/tests/app_info/AppInfoTest.ok</span><br><span>new file mode 100644</span><br><span>index 0000000..e69de29</span><br><span>--- /dev/null</span><br><span>+++ b/tests/app_info/AppInfoTest.ok</span><br><span>diff --git a/tests/testsuite.at b/tests/testsuite.at</span><br><span>index 86f45a8..09b0247 100644</span><br><span>--- a/tests/testsuite.at</span><br><span>+++ b/tests/testsuite.at</span><br><span>@@ -82,3 +82,10 @@</span><br><span> cat $abs_srcdir/fn/FnTest.ok > expout</span><br><span> AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/fn/FnTest], [0], [expout], [ignore])</span><br><span> AT_CLEANUP</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AT_SETUP([app_info])</span><br><span style="color: hsl(120, 100%, 40%);">+AT_KEYWORDS([app_info])</span><br><span style="color: hsl(120, 100%, 40%);">+cat $abs_srcdir/app_info/AppInfoTest.ok > expout</span><br><span style="color: hsl(120, 100%, 40%);">+cat $abs_srcdir/app_info/AppInfoTest.err > experr</span><br><span style="color: hsl(120, 100%, 40%);">+AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/app_info/AppInfoTest], [0], [expout], [experr])</span><br><span style="color: hsl(120, 100%, 40%);">+AT_CLEANUP</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-pcu/+/15459">change 15459</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/c/osmo-pcu/+/15459"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-pcu </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ie35959f833f46bde5f2126314b6f96763f863b36 </div>
<div style="display:none"> Gerrit-Change-Number: 15459 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: osmith <osmith@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>