<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-pcu/+/25830">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">csn1: Avoid failing if optional DownlinkDualCarrierCapability_r7 is missing<br><br>All additional release fields are considered optional, and the<br>CSN_DESCR for Content_t already marks almost all as such, except<br>DownlinkDualCarrierCapability_r7.<br><br>It has been found that some MS transmits a MS RA Capability with a Length=61 bits<br>where the last bit in the buffer is setting the Exist bit for<br>DownlinkDualCarrierCapability_r7 as 1. Hence, the CSN1 decoder failed to<br>decode the whole message because it expected to keep reading there<br>despite there's no more bytes to read.<br><br>While this is could actually be considered an MS bug, let's relax our<br>expectancies and simply consider the case { 1 <end> } as it was { 0 },<br>and mark skip decoding DownlinkDualCarrierCapability_r7. That waht<br>wireshark (packet-gsm_a_gsm.c) or pycrate do for instance.<br><br>This patch itself doesn't fix the problem where actually the Exist bit<br>is stored as 1 in the output decoded structure, but simply allows keep<br>ongoing with decoding until the end. This issue will be fixed in a<br>follow-up patch.<br><br>Related: SYS#5552<br>Related: OS#4955<br>Related: OS#5020<br>Change-Id: I9a2541bd3544802a646890f32725201836abb0da<br>---<br>M src/csn1.h<br>M src/csn1_dec.c<br>M src/gsm_rlcmac.c<br>M tests/rlcmac/RLCMACTest.cpp<br>M tests/rlcmac/RLCMACTest.err<br>M tests/rlcmac/RLCMACTest.ok<br>6 files changed, 54 insertions(+), 36 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/30/25830/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/csn1.h b/src/csn1.h</span><br><span>index d470228..285ae99 100644</span><br><span>--- a/src/csn1.h</span><br><span>+++ b/src/csn1.h</span><br><span>@@ -462,6 +462,16 @@</span><br><span>         {CSN_TYPE, 0, {(const void*)CSNDESCR_##_MEMBER_TYPE}, offsetof(_STRUCT, _MEMBER), FALSE, #_MEMBER, 0, NULL}</span><br><span> </span><br><span> /******************************************************************************</span><br><span style="color: hsl(120, 100%, 40%);">+ * M_TYPE_OR_NULL(Par1, Par2, Par3)</span><br><span style="color: hsl(120, 100%, 40%);">+ * Similar to the M_TYPE except that not only the request set of bits but also the</span><br><span style="color: hsl(120, 100%, 40%);">+ * end of the message may be encountered when looking for the next element in</span><br><span style="color: hsl(120, 100%, 40%);">+ * the message.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Covers the case {null | 0 | 1 < IE >}</span><br><span style="color: hsl(120, 100%, 40%);">+ *****************************************************************************/</span><br><span style="color: hsl(120, 100%, 40%);">+#define M_TYPE_OR_NULL(_STRUCT, _MEMBER, _MEMBER_TYPE)\</span><br><span style="color: hsl(120, 100%, 40%);">+        {CSN_TYPE, 0, {(const void*)CSNDESCR_##_MEMBER_TYPE}, offsetof(_STRUCT, _MEMBER), TRUE, #_MEMBER, 0, NULL}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/******************************************************************************</span><br><span>  * M_UNION(Par1, Par2)</span><br><span>  * Informs the CSN.1 library that a union follows and how many possible choices</span><br><span>  * there are in the union. The actual value of the choice, which points out the</span><br><span>diff --git a/src/csn1_dec.c b/src/csn1_dec.c</span><br><span>index 2d3f242..4bc74f3 100644</span><br><span>--- a/src/csn1_dec.c</span><br><span>+++ b/src/csn1_dec.c</span><br><span>@@ -388,22 +388,26 @@</span><br><span>       {</span><br><span>         gint16      Status;</span><br><span>         csnStream_t arT = *ar;</span><br><span style="color: hsl(0, 100%, 40%);">-        LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);</span><br><span style="color: hsl(0, 100%, 40%);">-        csnStreamInit(&arT, bit_offset, remaining_bits_len);</span><br><span style="color: hsl(0, 100%, 40%);">-    Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));</span><br><span style="color: hsl(0, 100%, 40%);">-        LOGPC(DCSN1, LOGL_DEBUG, ": End %s | ", pDescr->sz);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (Status >= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+        if (pDescr->may_be_null && remaining_bits_len == 0)</span><br><span>         {</span><br><span style="color: hsl(0, 100%, 40%);">-          remaining_bits_len  = arT.remaining_bits_len;</span><br><span style="color: hsl(0, 100%, 40%);">-          bit_offset          = arT.bit_offset;</span><br><span style="color: hsl(0, 100%, 40%);">-          pDescr++;</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGPC(DCSN1, LOGL_DEBUG, " : %s = NULL | ", pDescr->sz);</span><br><span style="color: hsl(120, 100%, 40%);">+        } else {</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);</span><br><span style="color: hsl(120, 100%, 40%);">+          csnStreamInit(&arT, bit_offset, remaining_bits_len);</span><br><span style="color: hsl(120, 100%, 40%);">+     Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGPC(DCSN1, LOGL_DEBUG, ": End %s | ", pDescr->sz);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (Status >= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          {</span><br><span style="color: hsl(120, 100%, 40%);">+            remaining_bits_len  = arT.remaining_bits_len;</span><br><span style="color: hsl(120, 100%, 40%);">+            bit_offset          = arT.bit_offset;</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%);">+          {</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr);  */</span><br><span style="color: hsl(120, 100%, 40%);">+            return Status;</span><br><span style="color: hsl(120, 100%, 40%);">+          }</span><br><span>         }</span><br><span style="color: hsl(0, 100%, 40%);">-        else</span><br><span style="color: hsl(0, 100%, 40%);">-        {</span><br><span style="color: hsl(0, 100%, 40%);">-          /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr);  */</span><br><span style="color: hsl(0, 100%, 40%);">-          return Status;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+        pDescr++;</span><br><span>         break;</span><br><span>       }</span><br><span> </span><br><span>@@ -838,21 +842,25 @@</span><br><span>           {</span><br><span>             gint16      Status;</span><br><span>             csnStream_t arT = *ar;</span><br><span style="color: hsl(0, 100%, 40%);">-            LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);</span><br><span style="color: hsl(0, 100%, 40%);">-            csnStreamInit(&arT, bit_offset, remaining_bits_len);</span><br><span style="color: hsl(0, 100%, 40%);">-       Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));</span><br><span style="color: hsl(0, 100%, 40%);">-            LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);</span><br><span style="color: hsl(0, 100%, 40%);">-            if (Status >= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+            if (pDescr->may_be_null && remaining_bits_len == 0)</span><br><span>             {</span><br><span style="color: hsl(0, 100%, 40%);">-              remaining_bits_len = arT.remaining_bits_len;</span><br><span style="color: hsl(0, 100%, 40%);">-              bit_offset         = arT.bit_offset;</span><br><span style="color: hsl(0, 100%, 40%);">-              pDescr++;</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGPC(DCSN1, LOGL_DEBUG, " : %s = NULL | ", pDescr->sz);</span><br><span style="color: hsl(120, 100%, 40%);">+            } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);</span><br><span style="color: hsl(120, 100%, 40%);">+              csnStreamInit(&arT, bit_offset, remaining_bits_len);</span><br><span style="color: hsl(120, 100%, 40%);">+          Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);</span><br><span style="color: hsl(120, 100%, 40%);">+              if (Status >= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+              {</span><br><span style="color: hsl(120, 100%, 40%);">+                remaining_bits_len = arT.remaining_bits_len;</span><br><span style="color: hsl(120, 100%, 40%);">+                bit_offset         = arT.bit_offset;</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%);">+              { /* return error code Has already been processed:  */</span><br><span style="color: hsl(120, 100%, 40%);">+                return Status;</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span>             }</span><br><span style="color: hsl(0, 100%, 40%);">-            else</span><br><span style="color: hsl(0, 100%, 40%);">-            { /* return error code Has already been processed:  */</span><br><span style="color: hsl(0, 100%, 40%);">-              return Status;</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+            pDescr++;</span><br><span>             break;</span><br><span>           }</span><br><span> </span><br><span>diff --git a/src/gsm_rlcmac.c b/src/gsm_rlcmac.c</span><br><span>index f676645..6793602 100644</span><br><span>--- a/src/gsm_rlcmac.c</span><br><span>+++ b/src/gsm_rlcmac.c</span><br><span>@@ -928,7 +928,7 @@</span><br><span>   /* additions in release 7 */</span><br><span>   M_UINT_OR_NULL      (Content_t,  DTM_Handover_Capability,  1),</span><br><span>   M_NEXT_EXIST_OR_NULL(Content_t, Exist_DownlinkDualCarrierCapability_r7, 1),</span><br><span style="color: hsl(0, 100%, 40%);">-  M_TYPE              (Content_t, DownlinkDualCarrierCapability_r7, DownlinkDualCarrierCapability_r7_t),</span><br><span style="color: hsl(120, 100%, 40%);">+  M_TYPE_OR_NULL      (Content_t, DownlinkDualCarrierCapability_r7, DownlinkDualCarrierCapability_r7_t),</span><br><span> </span><br><span>   M_UINT_OR_NULL      (Content_t,  FlexibleTimeslotAssignment,  1),</span><br><span>   M_UINT_OR_NULL      (Content_t,  GAN_PS_HandoverCapability,  1),</span><br><span>diff --git a/tests/rlcmac/RLCMACTest.cpp b/tests/rlcmac/RLCMACTest.cpp</span><br><span>index 4875bce..88847de 100644</span><br><span>--- a/tests/rlcmac/RLCMACTest.cpp</span><br><span>+++ b/tests/rlcmac/RLCMACTest.cpp</span><br><span>@@ -806,14 +806,14 @@</span><br><span>       printf("=== Test decoding of MS RA Capability 4===\n");</span><br><span>    rc = decode_gsm_ra_cap(bv_dec, &data);</span><br><span>   printf("decode_gsm_ra_cap() returns %d\n", rc);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(rc == -5); /* FIXME: should be 0 */</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(rc == 0);</span><br><span> </span><br><span>    /* Make sure there's 3 values */</span><br><span style="color: hsl(0, 100%, 40%);">-    OSMO_ASSERT(data.Count_MS_RA_capability_value == 0); /* FIXME: should be 3 */</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(data.Count_MS_RA_capability_value == 3);</span><br><span> </span><br><span>     /* Make sure GPRS / EGPRS multislot class is parsed correctly */</span><br><span style="color: hsl(0, 100%, 40%);">-        printf("GPRS multislot class = %u\n", get_ms_class_by_capability(&data)); /* FIXME: should be 12 */</span><br><span style="color: hsl(0, 100%, 40%);">-       printf("EGPRS multislot class = %u\n", get_egprs_ms_class_by_capability(&data)); /* FIXME: should be 12 */</span><br><span style="color: hsl(120, 100%, 40%);">+      printf("GPRS multislot class = %u\n", get_ms_class_by_capability(&data));</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("EGPRS multislot class = %u\n", get_egprs_ms_class_by_capability(&data));</span><br><span> </span><br><span>   bitvec_free(bv_dec);</span><br><span> }</span><br><span>diff --git a/tests/rlcmac/RLCMACTest.err b/tests/rlcmac/RLCMACTest.err</span><br><span>index 045ba78..33a47c3 100644</span><br><span>--- a/tests/rlcmac/RLCMACTest.err</span><br><span>+++ b/tests/rlcmac/RLCMACTest.err</span><br><span>@@ -58,4 +58,4 @@</span><br><span> DCSN1 DEBUG csnStreamDecoder (EGPRS Packet Channel Request): Choice EGPRS_PacketChannelRequest_Choice = 51 |  : Content | RandomBits = 17 | : End Content | </span><br><span> DCSN1 DEBUG csnStreamDecoder (EGPRS Packet Channel Request): Choice EGPRS_PacketChannelRequest_Choice = 55 |  : Content | RandomBits = 25 | : End Content | </span><br><span> DCSN1 DEBUG csnStreamDecoder (EGPRS Packet Channel Request): DCSN1 ERROR csnStreamDecoder: error STREAM_NOT_SUPPORTED (-8) at EGPRS_PacketChannelRequest_Choice (idx 0)</span><br><span style="color: hsl(0, 100%, 40%);">-DCSN1 INFO csnStreamDecoder (RAcap): MS_RA_capability_value { | Choice MS_RA_capability_value_Choice = 1 | u.Content length = 61 | offset = 1 | RF_Power_Capability = 4 | Exist_A5_bits = 1 | A5_bits = 80 | ES_IND = 1 | PS = 1 | VGCS = 0 | VBS = 0 | Exist_Multislot_capability = 1 |  : Multislot_capability | Exist_HSCSD_multislot_class = 0 | Exist_GPRS_multislot_class = 1 | GPRS_multislot_class = 12 | GPRS_Extended_Dynamic_Allocation_Capability = 1 | Exist_SM = 0 | Exist_ECSD_multislot_class = 0 | Exist_EGPRS_multislot_class = 1 | EGPRS_multislot_class = 12 | EGPRS_Extended_Dynamic_Allocation_Capability = 1 | Exist_DTM_GPRS_multislot_class = 0 | : End Multislot_capability | Exist_Eight_PSK_Power_Capability = 1 | Eight_PSK_Power_Capability = 2 | COMPACT_Interference_Measurement_Capability = 0 | Revision_Level_Indicator = 1 | UMTS_FDD_Radio_Access_Technology_Capability = 1 | UMTS_384_TDD_Radio_Access_Technology_Capability = 0 | CDMA2000_Radio_Access_Technology_Capability = 0 | UMTS_128_TDD_Radio_Access_Technology_Capability = 0 | GERAN_Feature_Package_1 = 1 | Exist_Extended_DTM_multislot_class = 0 | Modulation_based_multislot_class_support = 0 | Exist_HighMultislotCapability = 0 | Exist_GERAN_lu_ModeCapability = 0 | GMSK_MultislotPowerProfile = 0 | EightPSK_MultislotProfile = 0 | MultipleTBF_Capability = 0 | DownlinkAdvancedReceiverPerformance = 0 | ExtendedRLC_MAC_ControlMessageSegmentionsCapability = 0 | DTM_EnhancementsCapability = 0 | Exist_DTM_GPRS_HighMultislotClass = 0 | PS_HandoverCapability = 0 | DTM_Handover_Capability = 0 | Exist_DownlinkDualCarrierCapability_r7 = 1 |  : DownlinkDualCarrierCapability_r7 | DCSN1 ERROR csnStreamDecoder: error NEED_MORE BITS TO UNPACK (-5) at MultislotCapabilityReductionForDL_DualCarrier (idx 72): End DownlinkDualCarrierCapability_r7 | </span><br><span style="color: hsl(120, 100%, 40%);">+DCSN1 INFO csnStreamDecoder (RAcap): MS_RA_capability_value { | Choice MS_RA_capability_value_Choice = 1 | u.Content length = 61 | offset = 1 | RF_Power_Capability = 4 | Exist_A5_bits = 1 | A5_bits = 80 | ES_IND = 1 | PS = 1 | VGCS = 0 | VBS = 0 | Exist_Multislot_capability = 1 |  : Multislot_capability | Exist_HSCSD_multislot_class = 0 | Exist_GPRS_multislot_class = 1 | GPRS_multislot_class = 12 | GPRS_Extended_Dynamic_Allocation_Capability = 1 | Exist_SM = 0 | Exist_ECSD_multislot_class = 0 | Exist_EGPRS_multislot_class = 1 | EGPRS_multislot_class = 12 | EGPRS_Extended_Dynamic_Allocation_Capability = 1 | Exist_DTM_GPRS_multislot_class = 0 | : End Multislot_capability | Exist_Eight_PSK_Power_Capability = 1 | Eight_PSK_Power_Capability = 2 | COMPACT_Interference_Measurement_Capability = 0 | Revision_Level_Indicator = 1 | UMTS_FDD_Radio_Access_Technology_Capability = 1 | UMTS_384_TDD_Radio_Access_Technology_Capability = 0 | CDMA2000_Radio_Access_Technology_Capability = 0 | UMTS_128_TDD_Radio_Access_Technology_Capability = 0 | GERAN_Feature_Package_1 = 1 | Exist_Extended_DTM_multislot_class = 0 | Modulation_based_multislot_class_support = 0 | Exist_HighMultislotCapability = 0 | Exist_GERAN_lu_ModeCapability = 0 | GMSK_MultislotPowerProfile = 0 | EightPSK_MultislotProfile = 0 | MultipleTBF_Capability = 0 | DownlinkAdvancedReceiverPerformance = 0 | ExtendedRLC_MAC_ControlMessageSegmentionsCapability = 0 | DTM_EnhancementsCapability = 0 | Exist_DTM_GPRS_HighMultislotClass = 0 | PS_HandoverCapability = 0 | DTM_Handover_Capability = 0 | Exist_DownlinkDualCarrierCapability_r7 = 1 |  : DownlinkDualCarrierCapability_r7 = NULL | FlexibleTimeslotAssignment = NULL | GAN_PS_HandoverCapability = NULL | RLC_Non_persistentMode = NULL | ReducedLatencyCapability = NULL | UplinkEGPRS2 = NULL | DownlinkEGPRS2 = NULL | EUTRA_FDD_Support = NULL | EUTRA_TDD_Support = NULL | GERAN_To_EUTRAN_supportInGERAN_PTM = NULL | PriorityBasedReselectionSupport = NULL | MS_RA_capability_value } | MS_RA_capability_value { | Choice MS_RA_capability_value_Choice = 3 | u.Content length = 36 | offset = 1 | RF_Power_Capability = 1 | Exist_A5_bits = 0 | ES_IND = 1 | PS = 1 | VGCS = 0 | VBS = 0 | Exist_Multislot_capability = 0 | Exist_Eight_PSK_Power_Capability = 1 | Eight_PSK_Power_Capability = 2 | COMPACT_Interference_Measurement_Capability = 0 | Revision_Level_Indicator = 1 | UMTS_FDD_Radio_Access_Technology_Capability = 1 | UMTS_384_TDD_Radio_Access_Technology_Capability = 0 | CDMA2000_Radio_Access_Technology_Capability = 0 | UMTS_128_TDD_Radio_Access_Technology_Capability = 0 | GERAN_Feature_Package_1 = 1 | Exist_Extended_DTM_multislot_class = 0 | Modulation_based_multislot_class_support = 0 | Exist_HighMultislotCapability = 0 | Exist_GERAN_lu_ModeCapability = 0 | GMSK_MultislotPowerProfile = 0 | EightPSK_MultislotProfile = 0 | MultipleTBF_Capability = 0 | DownlinkAdvancedReceiverPerformance = 0 | ExtendedRLC_MAC_ControlMessageSegmentionsCapability = 0 | DTM_EnhancementsCapability = 0 | Exist_DTM_GPRS_HighMultislotClass = 0 | PS_HandoverCapability = 0 | DTM_Handover_Capability = 0 | Exist_DownlinkDualCarrierCapability_r7 = 1 |  : DownlinkDualCarrierCapability_r7 = NULL | FlexibleTimeslotAssignment = NULL | GAN_PS_HandoverCapability = NULL | RLC_Non_persistentMode = NULL | ReducedLatencyCapability = NULL | UplinkEGPRS2 = NULL | DownlinkEGPRS2 = NULL | EUTRA_FDD_Support = NULL | EUTRA_TDD_Support = NULL | GERAN_To_EUTRAN_supportInGERAN_PTM = NULL | PriorityBasedReselectionSupport = NULL | MS_RA_capability_value } | MS_RA_capability_value { | Choice MS_RA_capability_value_Choice = 7 | u.Content length = 36 | offset = 1 | RF_Power_Capability = 4 | Exist_A5_bits = 0 | ES_IND = 1 | PS = 1 | VGCS = 0 | VBS = 0 | Exist_Multislot_capability = 0 | Exist_Eight_PSK_Power_Capability = 1 | Eight_PSK_Power_Capability = 2 | COMPACT_Interference_Measurement_Capability = 0 | Revision_Level_Indicator = 1 | UMTS_FDD_Radio_Access_Technology_Capability = 1 | UMTS_384_TDD_Radio_Access_Technology_Capability = 0 | CDMA2000_Radio_Access_Technology_Capability = 0 | UMTS_128_TDD_Radio_Access_Technology_Capability = 0 | GERAN_Feature_Package_1 = 1 | Exist_Extended_DTM_multislot_class = 0 | Modulation_based_multislot_class_support = 0 | Exist_HighMultislotCapability = 0 | Exist_GERAN_lu_ModeCapability = 0 | GMSK_MultislotPowerProfile = 0 | EightPSK_MultislotProfile = 0 | MultipleTBF_Capability = 0 | DownlinkAdvancedReceiverPerformance = 0 | ExtendedRLC_MAC_ControlMessageSegmentionsCapability = 0 | DTM_EnhancementsCapability = 0 | Exist_DTM_GPRS_HighMultislotClass = 0 | PS_HandoverCapability = 0 | DTM_Handover_Capability = 0 | Exist_DownlinkDualCarrierCapability_r7 = 1 |  : DownlinkDualCarrierCapability_r7 = NULL | FlexibleTimeslotAssignment = NULL | GAN_PS_HandoverCapability = NULL | RLC_Non_persistentMode = NULL | ReducedLatencyCapability = NULL | UplinkEGPRS2 = NULL | DownlinkEGPRS2 = NULL | EUTRA_FDD_Support = NULL | EUTRA_TDD_Support = NULL | GERAN_To_EUTRAN_supportInGERAN_PTM = NULL | PriorityBasedReselectionSupport = NULL | MS_RA_capability_value } | Padding = 0|</span><br><span>diff --git a/tests/rlcmac/RLCMACTest.ok b/tests/rlcmac/RLCMACTest.ok</span><br><span>index 27800b0..86364c4 100644</span><br><span>--- a/tests/rlcmac/RLCMACTest.ok</span><br><span>+++ b/tests/rlcmac/RLCMACTest.ok</span><br><span>@@ -214,6 +214,6 @@</span><br><span> decode_egprs_pkt_ch_req(0x7ea) returns -8</span><br><span> *** testRAcap4 ***</span><br><span> === Test decoding of MS RA Capability 4===</span><br><span style="color: hsl(0, 100%, 40%);">-decode_gsm_ra_cap() returns -5</span><br><span style="color: hsl(0, 100%, 40%);">-GPRS multislot class = 0</span><br><span style="color: hsl(0, 100%, 40%);">-EGPRS multislot class = 0</span><br><span style="color: hsl(120, 100%, 40%);">+decode_gsm_ra_cap() returns 0</span><br><span style="color: hsl(120, 100%, 40%);">+GPRS multislot class = 12</span><br><span style="color: hsl(120, 100%, 40%);">+EGPRS multislot class = 12</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-pcu/+/25830">change 25830</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/+/25830"/><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: I9a2541bd3544802a646890f32725201836abb0da </div>
<div style="display:none"> Gerrit-Change-Number: 25830 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>