<p>Max has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/12959">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Restructure IA Rest Octets encoders<br><br>In preparation for upcoming patches with 11 bit RACH and TA support,<br>let's restructure existing encoders to simplify further modifications:<br><br>* move consistency checks to top-level Imm. Ass. encoder<br>* use consistent formatting<br>* constify pointers where appropriate<br>* split SBA and MBA encoders into separate functions<br><br>Those changes also make it obvious which parameters are necessary for<br>Rest Octets in each specific case (DL, UL-SBA, UL-MBA, UL-SBA-EGPRS,<br>UL-MBA-EGPRS).<br><br>There're no functional code changes so there's no need to adjust tests.<br><br>Change-Id: I0ad1bc786c3a8055ea9666f64ae82c512bd01603<br>Related: OS#1548<br>---<br>M src/encoding.cpp<br>1 file changed, 132 insertions(+), 123 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/12959/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/encoding.cpp b/src/encoding.cpp</span><br><span>index 2c89819..2648b02 100644</span><br><span>--- a/src/encoding.cpp</span><br><span>+++ b/src/encoding.cpp</span><br><span>@@ -87,18 +87,11 @@</span><br><span>                 bitvec_write_field(dest, &wp, ts, 3);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int write_ia_rest_downlink(</span><br><span style="color: hsl(0, 100%, 40%);">-    gprs_rlcmac_dl_tbf *tbf,</span><br><span style="color: hsl(0, 100%, 40%);">-        bitvec * dest, unsigned& wp,</span><br><span style="color: hsl(0, 100%, 40%);">-        bool polling, bool ta_valid, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-       uint8_t alpha, uint8_t gamma, int8_t ta_idx)</span><br><span style="color: hsl(120, 100%, 40%);">+static int write_ia_rest_downlink(const gprs_rlcmac_dl_tbf *tbf, bitvec * dest, bool polling, bool ta_valid,</span><br><span style="color: hsl(120, 100%, 40%);">+                              uint32_t fn, uint8_t alpha, uint8_t gamma, int8_t ta_idx, unsigned& wp)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!tbf) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGP(DRLCMACDL, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-                     "Cannot encode DL IMMEDIATE ASSIGNMENT without TBF\n");</span><br><span style="color: hsl(0, 100%, 40%);">-               return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-       // GSM 04.08 10.5.2.16 IA Rest Octets</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        bitvec_write_field(dest, &wp, 3, 2);   // "HH"</span><br><span>         bitvec_write_field(dest, &wp, 1, 2);   // "01" Packet Downlink Assignment</span><br><span>      bitvec_write_field(dest, &wp,tbf->tlli(),32); // TLLI</span><br><span>@@ -127,128 +120,126 @@</span><br><span>       //              bitvec_write_field(dest, &wp,0x1,1);   // P0 not present</span><br><span>         //              bitvec_write_field(dest, &wp,,0xb,4);</span><br><span>    if (tbf->is_egprs_enabled()) {</span><br><span style="color: hsl(0, 100%, 40%);">-               /* see GMS 44.018, 10.5.2.16 */</span><br><span>              bitvec_write_field(dest, &wp, 1, 1);  // "H"</span><br><span>           write_ws(dest, &wp, tbf->window_size()); // EGPRS Window Size</span><br><span>                 bitvec_write_field(dest, &wp, 0x0, 2);    // LINK_QUALITY_MEASUREMENT_MODE</span><br><span>               bitvec_write_field(dest, &wp, 0, 1);      // BEP_PERIOD2 not present</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     return rc;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int write_ia_rest_uplink(</span><br><span style="color: hsl(0, 100%, 40%);">-     gprs_rlcmac_ul_tbf *tbf,</span><br><span style="color: hsl(0, 100%, 40%);">-        bitvec * dest, unsigned& wp,</span><br><span style="color: hsl(0, 100%, 40%);">-        uint8_t usf, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-       uint8_t alpha, uint8_t gamma, int8_t ta_idx)</span><br><span style="color: hsl(120, 100%, 40%);">+static int write_ia_rest_uplink_sba(bitvec *dest, uint32_t fn, uint8_t alpha, uint8_t gamma, int8_t ta_idx,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 unsigned& wp)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(!tbf || !tbf->is_egprs_enabled());</span><br><span style="color: hsl(120, 100%, 40%);">+     int rc = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- // GMS 04.08 10.5.2.37b 10.5.2.16</span><br><span style="color: hsl(0, 100%, 40%);">-       bitvec_write_field(dest, &wp, 3, 2);    // "HH"</span><br><span style="color: hsl(0, 100%, 40%);">-   bitvec_write_field(dest, &wp, 0, 2);    // "0" Packet Uplink Assignment</span><br><span style="color: hsl(0, 100%, 40%);">-   if (tbf == NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">-              bitvec_write_field(dest, &wp, 0, 1);    // Block Allocation : Single Block Allocation</span><br><span style="color: hsl(0, 100%, 40%);">-               if (alpha) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    bitvec_write_field(dest, &wp,0x1,1);   // ALPHA = present</span><br><span style="color: hsl(0, 100%, 40%);">-                   bitvec_write_field(dest, &wp,alpha,4);   // ALPHA = present</span><br><span style="color: hsl(0, 100%, 40%);">-         } else</span><br><span style="color: hsl(0, 100%, 40%);">-                  bitvec_write_field(dest, &wp,0x0,1);   // ALPHA = not present</span><br><span style="color: hsl(0, 100%, 40%);">-               bitvec_write_field(dest, &wp,gamma,5);   // GAMMA power control parameter</span><br><span style="color: hsl(0, 100%, 40%);">-           write_tai(dest, wp, ta_idx);</span><br><span style="color: hsl(0, 100%, 40%);">-            bitvec_write_field(dest, &wp, 1, 1);    // TBF_STARTING_TIME_FLAG</span><br><span style="color: hsl(0, 100%, 40%);">-           bitvec_write_field(dest, &wp,(fn / (26 * 51)) % 32,5); // T1'</span><br><span style="color: hsl(0, 100%, 40%);">-           bitvec_write_field(dest, &wp,fn % 51,6);               // T3</span><br><span style="color: hsl(0, 100%, 40%);">-                bitvec_write_field(dest, &wp,fn % 26,5);               // T2</span><br><span style="color: hsl(0, 100%, 40%);">-        } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                bitvec_write_field(dest, &wp, 1, 1);    // Block Allocation : Not Single Block Allocation</span><br><span style="color: hsl(0, 100%, 40%);">-           bitvec_write_field(dest, &wp, tbf->tfi(), 5);  // TFI_ASSIGNMENT Temporary Flow Identity</span><br><span style="color: hsl(0, 100%, 40%);">-         bitvec_write_field(dest, &wp, 0, 1);    // POLLING</span><br><span style="color: hsl(0, 100%, 40%);">-          bitvec_write_field(dest, &wp, 0, 1);    // ALLOCATION_TYPE: dynamic</span><br><span style="color: hsl(0, 100%, 40%);">-         bitvec_write_field(dest, &wp, usf, 3);    // USF</span><br><span style="color: hsl(0, 100%, 40%);">-            bitvec_write_field(dest, &wp, 0, 1);    // USF_GRANULARITY</span><br><span style="color: hsl(0, 100%, 40%);">-          bitvec_write_field(dest, &wp, 0, 1);   // "0" power control: Not Present</span><br><span style="color: hsl(0, 100%, 40%);">-          bitvec_write_field(dest, &wp, tbf->current_cs().to_num()-1, 2);    // CHANNEL_CODING_COMMAND</span><br><span style="color: hsl(0, 100%, 40%);">-             bitvec_write_field(dest, &wp, 1, 1);    // TLLI_BLOCK_CHANNEL_CODING</span><br><span style="color: hsl(0, 100%, 40%);">-                if (alpha) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    bitvec_write_field(dest, &wp,0x1,1);   // ALPHA = present</span><br><span style="color: hsl(0, 100%, 40%);">-                   bitvec_write_field(dest, &wp,alpha,4);   // ALPHA</span><br><span style="color: hsl(0, 100%, 40%);">-           } else</span><br><span style="color: hsl(0, 100%, 40%);">-                  bitvec_write_field(dest, &wp,0x0,1);   // ALPHA = not present</span><br><span style="color: hsl(0, 100%, 40%);">-               bitvec_write_field(dest, &wp,gamma,5);   // GAMMA power control parameter</span><br><span style="color: hsl(0, 100%, 40%);">-           /* note: there is no choise for TAI and no starting time */</span><br><span style="color: hsl(0, 100%, 40%);">-             bitvec_write_field(dest, &wp, 0, 1);   // switch TIMING_ADVANCE_INDEX = off</span><br><span style="color: hsl(0, 100%, 40%);">-         bitvec_write_field(dest, &wp, 0, 1);    // TBF_STARTING_TIME_FLAG</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     bitvec_write_field(dest, &wp, 0, 1); // Block Allocation: Single Block Allocation</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (alpha) {</span><br><span style="color: hsl(120, 100%, 40%);">+          bitvec_write_field(dest, &wp, 0x1, 1);   // ALPHA = present</span><br><span style="color: hsl(120, 100%, 40%);">+               bitvec_write_field(dest, &wp, alpha, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+  } else</span><br><span style="color: hsl(120, 100%, 40%);">+                bitvec_write_field(dest, &wp, 0x0, 1);   // ALPHA = not present</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ bitvec_write_field(dest, &wp, gamma, 5);       // GAMMA power control parameter</span><br><span style="color: hsl(120, 100%, 40%);">+   write_tai(dest, wp, ta_idx);</span><br><span style="color: hsl(120, 100%, 40%);">+  bitvec_write_field(dest, &wp, 1, 1);         // TBF_STARTING_TIME_FLAG</span><br><span style="color: hsl(120, 100%, 40%);">+    bitvec_write_field(dest, &wp, (fn / (26 * 51)) % 32, 5); // T1'</span><br><span style="color: hsl(120, 100%, 40%);">+       bitvec_write_field(dest, &wp, fn % 51, 6);               // T3</span><br><span style="color: hsl(120, 100%, 40%);">+    bitvec_write_field(dest, &wp, fn % 26, 5);               // T2</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return rc;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int write_ia_rest_egprs_uplink(</span><br><span style="color: hsl(0, 100%, 40%);">-       gprs_rlcmac_ul_tbf *tbf,</span><br><span style="color: hsl(0, 100%, 40%);">-        bitvec * dest, unsigned& wp,</span><br><span style="color: hsl(0, 100%, 40%);">-        uint8_t usf, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-       uint8_t alpha, uint8_t gamma, int8_t ta_idx,</span><br><span style="color: hsl(0, 100%, 40%);">-    enum ph_burst_type burst_type, uint16_t ra)</span><br><span style="color: hsl(120, 100%, 40%);">+static int write_ia_rest_uplink_mba(const gprs_rlcmac_ul_tbf *tbf, bitvec *dest, uint8_t usf,</span><br><span style="color: hsl(120, 100%, 40%);">+                                uint8_t alpha, uint8_t gamma, unsigned& wp)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        uint8_t extended_ra = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      int rc = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- extended_ra = (ra & 0x1F);</span><br><span style="color: hsl(120, 100%, 40%);">+        bitvec_write_field(dest, &wp, 1, 1);    // Block Allocation: Not Single Block Allocation</span><br><span style="color: hsl(120, 100%, 40%);">+  bitvec_write_field(dest, &wp, tbf->tfi(), 5);  // TFI_ASSIGNMENT Temporary Flow Identity</span><br><span style="color: hsl(120, 100%, 40%);">+       bitvec_write_field(dest, &wp, 0, 1);    // POLLING</span><br><span style="color: hsl(120, 100%, 40%);">+        bitvec_write_field(dest, &wp, 0, 1);    // ALLOCATION_TYPE: dynamic</span><br><span style="color: hsl(120, 100%, 40%);">+       bitvec_write_field(dest, &wp, usf, 3);    // USF</span><br><span style="color: hsl(120, 100%, 40%);">+  bitvec_write_field(dest, &wp, 0, 1);    // USF_GRANULARITY</span><br><span style="color: hsl(120, 100%, 40%);">+        bitvec_write_field(dest, &wp, 0, 1);   // "0" power control: Not Present</span><br><span style="color: hsl(120, 100%, 40%);">+        bitvec_write_field(dest, &wp, tbf->current_cs().to_num() - 1, 2);    // CHANNEL_CODING_COMMAND</span><br><span style="color: hsl(120, 100%, 40%);">+ bitvec_write_field(dest, &wp, 1, 1);    // TLLI_BLOCK_CHANNEL_CODING</span><br><span style="color: hsl(120, 100%, 40%);">+      if (alpha) {</span><br><span style="color: hsl(120, 100%, 40%);">+          bitvec_write_field(dest, &wp, 0x1, 1);   // ALPHA = present</span><br><span style="color: hsl(120, 100%, 40%);">+               bitvec_write_field(dest, &wp, alpha, 4);   // ALPHA</span><br><span style="color: hsl(120, 100%, 40%);">+       } else</span><br><span style="color: hsl(120, 100%, 40%);">+                bitvec_write_field(dest, &wp, 0x0, 1);   // ALPHA = not present</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- bitvec_write_field(dest, &wp, 1, 2);    /* LH */</span><br><span style="color: hsl(0, 100%, 40%);">-    bitvec_write_field(dest, &wp, 0, 2);    /* 0 EGPRS Uplink Assignment */</span><br><span style="color: hsl(0, 100%, 40%);">-     bitvec_write_field(dest, &wp, extended_ra, 5);    /* Extended RA */</span><br><span style="color: hsl(0, 100%, 40%);">- bitvec_write_field(dest, &wp, 0, 1);    /* Access technology Request */</span><br><span style="color: hsl(120, 100%, 40%);">+   bitvec_write_field(dest, &wp, gamma, 5);   // GAMMA power control parameter</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     if (tbf == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+    /* note: there is no choise for TAI and no starting time */</span><br><span style="color: hsl(120, 100%, 40%);">+   bitvec_write_field(dest, &wp, 0, 1);   // switch TIMING_ADVANCE_INDEX = off</span><br><span style="color: hsl(120, 100%, 40%);">+       bitvec_write_field(dest, &wp, 0, 1);    // TBF_STARTING_TIME_FLAG</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-               bitvec_write_field(dest, &wp, 0, 1); /* multiblock allocation */</span><br><span style="color: hsl(120, 100%, 40%);">+  return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-               if (alpha) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    bitvec_write_field(dest, &wp, 0x1, 1); /* ALPHA =yes */</span><br><span style="color: hsl(0, 100%, 40%);">-                     bitvec_write_field(dest, &wp, alpha, 4); /* ALPHA */</span><br><span style="color: hsl(0, 100%, 40%);">-                } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        bitvec_write_field(dest, &wp, 0x0, 1); /* ALPHA = no */</span><br><span style="color: hsl(0, 100%, 40%);">-             }</span><br><span style="color: hsl(120, 100%, 40%);">+static int write_ia_rest_egprs_uplink_mba(bitvec * dest, uint32_t fn, uint8_t alpha, uint8_t gamma, unsigned& wp)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   int rc = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-         bitvec_write_field(dest, &wp, gamma, 5); /* GAMMA power contrl */</span><br><span style="color: hsl(0, 100%, 40%);">-           bitvec_write_field(dest, &wp, (fn / (26 * 51)) % 32, 5);/* T1' */</span><br><span style="color: hsl(0, 100%, 40%);">-               bitvec_write_field(dest, &wp, fn % 51, 6);              /* T3 */</span><br><span style="color: hsl(0, 100%, 40%);">-            bitvec_write_field(dest, &wp, fn % 26, 5);              /* T2 */</span><br><span style="color: hsl(0, 100%, 40%);">-            bitvec_write_field(dest, &wp, 0, 2); /* Radio block allocation */</span><br><span style="color: hsl(120, 100%, 40%);">+ bitvec_write_field(dest, &wp, 0, 1); /* multiblock allocation */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                bitvec_write_field(dest, &wp, 0, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+      if (alpha) {</span><br><span style="color: hsl(120, 100%, 40%);">+          bitvec_write_field(dest, &wp, 0x1, 1); /* ALPHA =yes */</span><br><span style="color: hsl(120, 100%, 40%);">+           bitvec_write_field(dest, &wp, alpha, 4); /* ALPHA */</span><br><span>     } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                bitvec_write_field(dest, &wp, 1, 1);     /* single block alloc */</span><br><span style="color: hsl(0, 100%, 40%);">-           bitvec_write_field(dest, &wp, tbf->tfi(), 5);/* TFI assignment */</span><br><span style="color: hsl(0, 100%, 40%);">-                bitvec_write_field(dest, &wp, 0, 1);     /* polling bit */</span><br><span style="color: hsl(0, 100%, 40%);">-          bitvec_write_field(dest, &wp, 0, 1);     /* constant */</span><br><span style="color: hsl(0, 100%, 40%);">-             bitvec_write_field(dest, &wp, usf, 3);   /* USF bit */</span><br><span style="color: hsl(0, 100%, 40%);">-              bitvec_write_field(dest, &wp, 0, 1);     /* USF granularity */</span><br><span style="color: hsl(0, 100%, 40%);">-              bitvec_write_field(dest, &wp, 0, 1);     /* P0 */</span><br><span style="color: hsl(0, 100%, 40%);">-           /* MCS */</span><br><span style="color: hsl(0, 100%, 40%);">-               bitvec_write_field(dest, &wp, tbf->current_cs().to_num()-1, 4);</span><br><span style="color: hsl(0, 100%, 40%);">-          /* tlli channel block */</span><br><span style="color: hsl(0, 100%, 40%);">-                bitvec_write_field(dest, &wp, tbf->tlli(), 1);</span><br><span style="color: hsl(0, 100%, 40%);">-           bitvec_write_field(dest, &wp, 0, 1);   /* BEP period present */</span><br><span style="color: hsl(0, 100%, 40%);">-             bitvec_write_field(dest, &wp, 0, 1);   /* resegmentation */</span><br><span style="color: hsl(0, 100%, 40%);">-         write_ws(dest, &wp, tbf->window_size()); /* EGPRS window size */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         if (alpha) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    bitvec_write_field(dest, &wp, 0x1, 1);   /* ALPHA =yes */</span><br><span style="color: hsl(0, 100%, 40%);">-                   bitvec_write_field(dest, &wp, alpha, 4); /* ALPHA */</span><br><span style="color: hsl(0, 100%, 40%);">-                } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        bitvec_write_field(dest, &wp, 0x0, 1);   /* ALPHA = no */</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               bitvec_write_field(dest, &wp, gamma, 5); /* GAMMA power contrl */</span><br><span style="color: hsl(0, 100%, 40%);">-           bitvec_write_field(dest, &wp, 0, 1); /* TIMING_ADVANCE_INDEX */</span><br><span style="color: hsl(0, 100%, 40%);">-             bitvec_write_field(dest, &wp, 0, 1); /* TBF_STARTING_TIME_FLAG */</span><br><span style="color: hsl(0, 100%, 40%);">-           bitvec_write_field(dest, &wp, 0, 1); /* NULL */</span><br><span style="color: hsl(120, 100%, 40%);">+           bitvec_write_field(dest, &wp, 0x0, 1); /* ALPHA = no */</span><br><span>  }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     bitvec_write_field(dest, &wp, gamma, 5); /* GAMMA power contrl */</span><br><span style="color: hsl(120, 100%, 40%);">+ bitvec_write_field(dest, &wp, (fn / (26 * 51)) % 32, 5);/* T1' */</span><br><span style="color: hsl(120, 100%, 40%);">+     bitvec_write_field(dest, &wp, fn % 51, 6);              /* T3 */</span><br><span style="color: hsl(120, 100%, 40%);">+  bitvec_write_field(dest, &wp, fn % 26, 5);              /* T2 */</span><br><span style="color: hsl(120, 100%, 40%);">+  bitvec_write_field(dest, &wp, 0, 2); /* Radio block allocation */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       bitvec_write_field(dest, &wp, 0, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return rc;</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%);">+static int write_ia_rest_egprs_uplink_sba(const gprs_rlcmac_ul_tbf *tbf, bitvec * dest, uint8_t usf,</span><br><span style="color: hsl(120, 100%, 40%);">+                                   uint8_t alpha, uint8_t gamma, unsigned& wp)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  int rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ bitvec_write_field(dest, &wp, 1, 1);     /* single block allocation */</span><br><span style="color: hsl(120, 100%, 40%);">+    bitvec_write_field(dest, &wp, tbf->tfi(), 5); /* TFI assignment */</span><br><span style="color: hsl(120, 100%, 40%);">+     bitvec_write_field(dest, &wp, 0, 1);     /* polling bit */</span><br><span style="color: hsl(120, 100%, 40%);">+        bitvec_write_field(dest, &wp, 0, 1);     /* constant */</span><br><span style="color: hsl(120, 100%, 40%);">+   bitvec_write_field(dest, &wp, usf, 3);   /* USF bit */</span><br><span style="color: hsl(120, 100%, 40%);">+    bitvec_write_field(dest, &wp, 0, 1);     /* USF granularity */</span><br><span style="color: hsl(120, 100%, 40%);">+    bitvec_write_field(dest, &wp, 0, 1);     /* P0 */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* MCS */</span><br><span style="color: hsl(120, 100%, 40%);">+     bitvec_write_field(dest, &wp, tbf->current_cs().to_num() - 1, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* TLLI channel block */</span><br><span style="color: hsl(120, 100%, 40%);">+      bitvec_write_field(dest, &wp, tbf->tlli(), 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ bitvec_write_field(dest, &wp, 0, 1);   /* BEP period present */</span><br><span style="color: hsl(120, 100%, 40%);">+   bitvec_write_field(dest, &wp, 0, 1);   /* resegmentation */</span><br><span style="color: hsl(120, 100%, 40%);">+       write_ws(dest, &wp, tbf->window_size()); /* EGPRS window size */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (alpha) {</span><br><span style="color: hsl(120, 100%, 40%);">+          bitvec_write_field(dest, &wp, 0x1, 1);   /* ALPHA = yes */</span><br><span style="color: hsl(120, 100%, 40%);">+                bitvec_write_field(dest, &wp, alpha, 4); /* ALPHA */</span><br><span style="color: hsl(120, 100%, 40%);">+      } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              bitvec_write_field(dest, &wp, 0x0, 1);   /* ALPHA = no */</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%);">+   bitvec_write_field(dest, &wp, gamma, 5); /* GAMMA power contrl */</span><br><span style="color: hsl(120, 100%, 40%);">+ bitvec_write_field(dest, &wp, 0, 1); /* TIMING_ADVANCE_INDEX */</span><br><span style="color: hsl(120, 100%, 40%);">+   bitvec_write_field(dest, &wp, 0, 1); /* TBF_STARTING_TIME_FLAG */</span><br><span style="color: hsl(120, 100%, 40%);">+ bitvec_write_field(dest, &wp, 0, 1); /* NULL */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span> }</span><br><span> </span><br><span> /*</span><br><span>@@ -396,19 +387,37 @@</span><br><span> </span><br><span>        plen = wp / 8;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      if (downlink)</span><br><span style="color: hsl(0, 100%, 40%);">-           rc = write_ia_rest_downlink(as_dl_tbf(tbf), dest, wp,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       polling, gsm48_ta_is_valid(ta), fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                 alpha, gamma, ta_idx);</span><br><span style="color: hsl(0, 100%, 40%);">-  else if (((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) ||</span><br><span style="color: hsl(0, 100%, 40%);">-                 (burst_type == GSM_L1_BURST_TYPE_ACCESS_2)))</span><br><span style="color: hsl(0, 100%, 40%);">-            rc = write_ia_rest_egprs_uplink(as_ul_tbf(tbf), dest, wp,</span><br><span style="color: hsl(0, 100%, 40%);">-                       usf, fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                        alpha, gamma, ta_idx, burst_type, ra);</span><br><span style="color: hsl(0, 100%, 40%);">-  else</span><br><span style="color: hsl(0, 100%, 40%);">-            rc = write_ia_rest_uplink(as_ul_tbf(tbf), dest, wp,</span><br><span style="color: hsl(0, 100%, 40%);">-                     usf, fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                        alpha, gamma, ta_idx);</span><br><span style="color: hsl(120, 100%, 40%);">+        /* 3GPP TS 44.018 ยง10.5.2.16 IA Rest Octets */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (downlink) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (!as_dl_tbf(tbf)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        LOGP(DRLCMACDL, LOGL_ERROR, "Cannot encode DL IMMEDIATE ASSIGNMENT without TBF\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = write_ia_rest_downlink(as_dl_tbf(tbf), dest, polling, gsm48_ta_is_valid(ta), fn, alpha, gamma,</span><br><span style="color: hsl(120, 100%, 40%);">+                                       ta_idx, wp);</span><br><span style="color: hsl(120, 100%, 40%);">+      } else if (((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || (burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) {</span><br><span style="color: hsl(120, 100%, 40%);">+              bitvec_write_field(dest, &wp, 1, 2);    /* LH */</span><br><span style="color: hsl(120, 100%, 40%);">+          bitvec_write_field(dest, &wp, 0, 2);    /* 0 EGPRS Uplink Assignment */</span><br><span style="color: hsl(120, 100%, 40%);">+           bitvec_write_field(dest, &wp, ra & 0x1F, 5);    /* Extended RA */</span><br><span style="color: hsl(120, 100%, 40%);">+             bitvec_write_field(dest, &wp, 0, 1);    /* Access technology Request */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         if (as_ul_tbf(tbf) != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 rc = write_ia_rest_egprs_uplink_sba(as_ul_tbf(tbf), dest, usf, alpha, gamma, wp);</span><br><span style="color: hsl(120, 100%, 40%);">+             } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      rc = write_ia_rest_egprs_uplink_mba(dest, fn, alpha, gamma, wp);</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%);">+              OSMO_ASSERT(!tbf || !tbf->is_egprs_enabled());</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           bitvec_write_field(dest, &wp, 3, 2);    // "HH"</span><br><span style="color: hsl(120, 100%, 40%);">+         bitvec_write_field(dest, &wp, 0, 2);    // "0" Packet Uplink Assignment</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               if (as_ul_tbf(tbf) != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 rc = write_ia_rest_uplink_mba(as_ul_tbf(tbf), dest, usf, alpha, gamma, wp);</span><br><span style="color: hsl(120, 100%, 40%);">+           } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      rc = write_ia_rest_uplink_sba(dest, fn, alpha, gamma, ta_idx, wp);</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span> </span><br><span>        if (rc < 0) {</span><br><span>             LOGP(DRLCMAC, LOGL_ERROR,</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/12959">change 12959</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/12959"/><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-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I0ad1bc786c3a8055ea9666f64ae82c512bd01603 </div>
<div style="display:none"> Gerrit-Change-Number: 12959 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Max <msuraev@sysmocom.de> </div>