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

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">store classmark in vlr_subscr, not conn<br><br>Store all Classmark information in the VLR.<br><br>So, we now always know the Classmark 1 (mandatory IE for LU). This is visible<br>in the msc_vlr_tests -- they no longer indicate "assuming A5/1 is supported"<br>because classmark 1 is missing, because we now know the Classmark 1.<br><br>Rationale:<br><br>During Location Updating, we receive Classmark 1; during CM Service Request and<br>Paging Response, we receive Classmark 2. So far we stored these only for the<br>duration of the conn, so as soon as a LU is complete, we would forget CM1.<br><br>In other words, for anything else than a LU Request, we had no Classmark 1<br>available at all.<br><br>During Ciphering Mode Command, we rely on Classmark 1 to determine whether A5/1<br>is supported. That is moot if we don't even have a Classmark 1 for any CM<br>Service Request or Paging Response initiated connections.<br><br>The only reason that A5/1 worked is that we assume A5/1 to work if Classmark 1<br>is missing. To add to the confusion, if a phone indicated that it did *not*<br>support A5/1 in the Classmark 1, according to spec we're supposed to not<br>service it at all. A code comment however says that we instead want to heed the<br>flag -- which so far was only present in a Location Updating initiated<br>connection. Now we can make this decision without assuming things.<br><br>This got my attention while hacking on sending a BSSMAP Classmark Request from<br>the MSC if it finds missing Classmark information, and was surprised to see it<br>it lacking CM1 to decide about A5/1.<br><br>Change-Id: I27081bf6e9e017923b2d02607f7ea06beddad82a<br>---<br>M include/osmocom/msc/gsm_data.h<br>M include/osmocom/msc/vlr.h<br>M src/libmsc/gsm_04_08.c<br>M src/libmsc/osmo_msc.c<br>M tests/msc_vlr/msc_vlr_test_gsm_ciph.err<br>M tests/msc_vlr/msc_vlr_test_rest.err<br>6 files changed, 75 insertions(+), 69 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h</span><br><span>index 27f7fc5..ffe3afc 100644</span><br><span>--- a/include/osmocom/msc/gsm_data.h</span><br><span>+++ b/include/osmocom/msc/gsm_data.h</span><br><span>@@ -127,8 +127,6 @@</span><br><span>    /* connected via 2G or 3G? */</span><br><span>        enum ran_type via_ran;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      struct gsm_classmark classmark;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>      uint16_t lac;</span><br><span>        struct gsm_encr encr;</span><br><span> </span><br><span>diff --git a/include/osmocom/msc/vlr.h b/include/osmocom/msc/vlr.h</span><br><span>index 386a548..d52713c 100644</span><br><span>--- a/include/osmocom/msc/vlr.h</span><br><span>+++ b/include/osmocom/msc/vlr.h</span><br><span>@@ -174,6 +174,8 @@</span><br><span>             uint8_t lac;</span><br><span>                 enum ran_type attached_via_ran;</span><br><span>      } cs;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm_classmark classmark;</span><br><span> };</span><br><span> </span><br><span> enum vlr_ciph {</span><br><span>diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c</span><br><span>index 19b0572..b942a03 100644</span><br><span>--- a/src/libmsc/gsm_04_08.c</span><br><span>+++ b/src/libmsc/gsm_04_08.c</span><br><span>@@ -98,14 +98,25 @@</span><br><span>      return gsm48_conn_sendmsg(msg, conn, NULL);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static bool classmark1_is_r99(const struct gsm48_classmark1 *cm1)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    return cm1->rev_lev >= 2;</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 bool classmark2_is_r99(const uint8_t *cm2, uint8_t cm2_len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t rev_lev;</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!cm2_len)</span><br><span style="color: hsl(120, 100%, 40%);">+         return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ rev_lev = (cm2[0] >> 5) & 0x3;</span><br><span style="color: hsl(120, 100%, 40%);">+      return rev_lev >= 2;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static bool classmark_is_r99(struct gsm_classmark *cm)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     int rev_lev = 0;</span><br><span>     if (cm->classmark1_set)</span><br><span style="color: hsl(0, 100%, 40%);">-              rev_lev = cm->classmark1.rev_lev;</span><br><span style="color: hsl(0, 100%, 40%);">-    else if (cm->classmark2_len > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-          rev_lev = (cm->classmark2[0] >> 5) & 0x3;</span><br><span style="color: hsl(0, 100%, 40%);">-  return rev_lev >= 2;</span><br><span style="color: hsl(120, 100%, 40%);">+               return classmark1_is_r99(&cm->classmark1);</span><br><span style="color: hsl(120, 100%, 40%);">+     return classmark2_is_r99(cm->classmark2, cm->classmark2_len);</span><br><span> }</span><br><span> </span><br><span> /* Determine if the given CLASSMARK (1/2/3) value permits a given A5/n cipher */</span><br><span>@@ -345,9 +356,6 @@</span><br><span> </span><br><span>   msc_subscr_conn_update_id(conn, COMPLETE_LAYER3_LU, mi_string);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     conn->classmark.classmark1 = lu->classmark1;</span><br><span style="color: hsl(0, 100%, 40%);">-      conn->classmark.classmark1_set = true;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    DEBUGP(DMM, "LOCATION UPDATING REQUEST: MI(%s)=%s type=%s\n",</span><br><span>             gsm48_mi_type_name(mi_type), mi_string,</span><br><span>              get_value_string(lupd_names, lu->type));</span><br><span>@@ -402,7 +410,7 @@</span><br><span>                             &old_lai, &new_lai,</span><br><span>                          is_utran || conn->network->authentication_required,</span><br><span>                            is_utran || conn->network->a5_encryption_mask > 0x01,</span><br><span style="color: hsl(0, 100%, 40%);">-                          classmark_is_r99(&conn->classmark),</span><br><span style="color: hsl(120, 100%, 40%);">+                            classmark1_is_r99(&lu->classmark1),</span><br><span>                           is_utran,</span><br><span>                            net->vlr->cfg.assign_tmsi);</span><br><span>    if (!lu_fsm) {</span><br><span>@@ -421,6 +429,9 @@</span><br><span>                 return -EIO;</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ conn->vsub->classmark.classmark1 = lu->classmark1;</span><br><span style="color: hsl(120, 100%, 40%);">+   conn->vsub->classmark.classmark1_set = true;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         msc_subscr_conn_complete_layer_3(conn);</span><br><span>      return 0;</span><br><span> }</span><br><span>@@ -773,8 +784,6 @@</span><br><span>         msc_subscr_conn_update_id(conn, COMPLETE_LAYER3_CM_SERVICE_REQ, mi_string);</span><br><span> </span><br><span>      osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, mi_p);</span><br><span style="color: hsl(0, 100%, 40%);">-       memcpy(conn->classmark.classmark2, classmark2, classmark2_len);</span><br><span style="color: hsl(0, 100%, 40%);">-      conn->classmark.classmark2_len = classmark2_len;</span><br><span> </span><br><span>      is_utran = (conn->via_ran == RAN_UTRAN_IU);</span><br><span>       vlr_proc_acc_req(conn->fi,</span><br><span>@@ -783,9 +792,20 @@</span><br><span>                          VLR_PR_ARQ_T_CM_SERV_REQ, mi-1, &lai,</span><br><span>                    is_utran || conn->network->authentication_required,</span><br><span>                    is_utran || conn->network->a5_encryption_mask > 0x01,</span><br><span style="color: hsl(0, 100%, 40%);">-                  classmark_is_r99(&conn->classmark),</span><br><span style="color: hsl(120, 100%, 40%);">+                    classmark2_is_r99(classmark2, classmark2_len),</span><br><span>                       is_utran);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       /* From vlr_proc_acc_req() we expect an implicit dispatch of PR_ARQ_E_START we expect</span><br><span style="color: hsl(120, 100%, 40%);">+  * msc_vlr_subscr_assoc() to already have been called and completed. Has an error occured? */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!conn->vsub) {</span><br><span style="color: hsl(120, 100%, 40%);">+         LOGP(DRR, LOGL_ERROR, "%s: subscriber not allowed to do a CM Service Request\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                 mi_string);</span><br><span style="color: hsl(120, 100%, 40%);">+              return -EIO;</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%);">+   memcpy(conn->vsub->classmark.classmark2, classmark2, classmark2_len);</span><br><span style="color: hsl(120, 100%, 40%);">+   conn->vsub->classmark.classmark2_len = classmark2_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       msc_subscr_conn_complete_layer_3(conn);</span><br><span>      return 0;</span><br><span> }</span><br><span>@@ -846,11 +866,6 @@</span><br><span>                break;</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* TODO? We used to remember the subscriber's classmark1 here and</span><br><span style="color: hsl(0, 100%, 40%);">-    * stored it in the old sqlite db, but now we store it in a conn that</span><br><span style="color: hsl(0, 100%, 40%);">-    * will be discarded anyway: */</span><br><span style="color: hsl(0, 100%, 40%);">- conn->classmark.classmark1 = idi->classmark1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>  if (!vsub) {</span><br><span>                 LOGP(DMM, LOGL_ERROR, "IMSI DETACH for unknown subscriber MI(%s)=%s\n",</span><br><span>                 gsm48_mi_type_name(mi_type), mi_string);</span><br><span>@@ -860,6 +875,9 @@</span><br><span>          if (vsub->cs.is_paging)</span><br><span>                   subscr_paging_cancel(vsub, GSM_PAGING_EXPIRED);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+           /* We already got Classmark 1 during Location Updating ... but well, ok */</span><br><span style="color: hsl(120, 100%, 40%);">+            vsub->classmark.classmark1 = idi->classmark1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                vlr_subscr_rx_imsi_detach(vsub);</span><br><span>             osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_DETACHED, vsub);</span><br><span>            vlr_subscr_put(vsub);</span><br><span>@@ -986,7 +1004,7 @@</span><br><span>                is_umts ? "UMTS" : "GSM", is_umts ? "res" : "sres",</span><br><span>          osmo_hexdump_nospc(res, res_len));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   return vlr_subscr_rx_auth_resp(conn->vsub, classmark_is_r99(&conn->classmark),</span><br><span style="color: hsl(120, 100%, 40%);">+      return vlr_subscr_rx_auth_resp(conn->vsub, classmark_is_r99(&conn->vsub->classmark),</span><br><span>                                   conn->via_ran == RAN_UTRAN_IU,</span><br><span>                                    res, res_len);</span><br><span> }</span><br><span>@@ -1128,27 +1146,15 @@</span><br><span>         return rc;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static uint8_t *gsm48_cm2_get_mi(uint8_t *classmark2_lv, unsigned int tot_len)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Check the size for the classmark */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (tot_len < 1 + *classmark2_lv)</span><br><span style="color: hsl(0, 100%, 40%);">-            return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    uint8_t *mi_lv = classmark2_lv + *classmark2_lv + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-    if (tot_len < 2 + *classmark2_lv + mi_lv[0])</span><br><span style="color: hsl(0, 100%, 40%);">-         return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    return mi_lv;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* Receive a PAGING RESPONSE message from the MS */</span><br><span> static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct msgb *msg)</span><br><span> {</span><br><span>      struct gsm_network *net = conn->network;</span><br><span>  struct gsm48_hdr *gh = msgb_l3(msg);</span><br><span>         struct gsm48_pag_resp *resp;</span><br><span style="color: hsl(0, 100%, 40%);">-    uint8_t *classmark2_lv = gh->data + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       uint8_t *mi_lv;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t classmark2_len = gh->data[1];</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t *classmark2 = gh->data+2;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t *mi_lv = classmark2 + classmark2_len;</span><br><span>        uint8_t mi_type;</span><br><span>     char mi_string[GSM48_MI_SIZE];</span><br><span>       struct osmo_location_area_id lai;</span><br><span>@@ -1158,8 +1164,11 @@</span><br><span>   lai.lac = conn->lac;</span><br><span> </span><br><span>  resp = (struct gsm48_pag_resp *) &gh->data[0];</span><br><span style="color: hsl(0, 100%, 40%);">-   gsm48_paging_extract_mi(resp, msgb_l3len(msg) - sizeof(*gh),</span><br><span style="color: hsl(0, 100%, 40%);">-                            mi_string, &mi_type);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (gsm48_paging_extract_mi(resp, msgb_l3len(msg) - sizeof(*gh), mi_string, &mi_type) <= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGP(DRR, LOGL_ERROR, "PAGING RESPONSE: invalid Mobile Identity\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span> </span><br><span>        if (msc_subscr_conn_is_establishing_auth_ciph(conn)) {</span><br><span>               LOGP(DMM, LOGL_ERROR,</span><br><span>@@ -1174,17 +1183,8 @@</span><br><span> </span><br><span>   DEBUGP(DRR, "PAGING RESPONSE: MI(%s)=%s\n", gsm48_mi_type_name(mi_type), mi_string);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      mi_lv = gsm48_cm2_get_mi(classmark2_lv, msgb_l3len(msg) - sizeof(*gh));</span><br><span style="color: hsl(0, 100%, 40%);">- if (!mi_lv) {</span><br><span style="color: hsl(0, 100%, 40%);">-           LOGP(DRR, LOGL_ERROR, "PAGING RESPONSE: invalid Mobile Identity\n");</span><br><span style="color: hsl(0, 100%, 40%);">-          return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    msc_subscr_conn_update_id(conn, COMPLETE_LAYER3_PAGING_RESP, mi_string);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    memcpy(conn->classmark.classmark2, classmark2_lv+1, *classmark2_lv);</span><br><span style="color: hsl(0, 100%, 40%);">- conn->classmark.classmark2_len = *classmark2_lv;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>  is_utran = (conn->via_ran == RAN_UTRAN_IU);</span><br><span>       vlr_proc_acc_req(conn->fi,</span><br><span>                         SUBSCR_CONN_E_ACCEPTED, SUBSCR_CONN_E_CN_CLOSE, NULL,</span><br><span>@@ -1192,9 +1192,20 @@</span><br><span>                       VLR_PR_ARQ_T_PAGING_RESP, mi_lv, &lai,</span><br><span>                   is_utran || conn->network->authentication_required,</span><br><span>                    is_utran || conn->network->a5_encryption_mask > 0x01,</span><br><span style="color: hsl(0, 100%, 40%);">-                  classmark_is_r99(&conn->classmark),</span><br><span style="color: hsl(120, 100%, 40%);">+                    classmark2_is_r99(classmark2, classmark2_len),</span><br><span>                       is_utran);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       /* From vlr_proc_acc_req() we expect an implicit dispatch of PR_ARQ_E_START we expect</span><br><span style="color: hsl(120, 100%, 40%);">+  * msc_vlr_subscr_assoc() to already have been called and completed. Has an error occured? */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!conn->vsub) {</span><br><span style="color: hsl(120, 100%, 40%);">+         LOGP(DRR, LOGL_ERROR, "%s: subscriber not allowed to do a Paging Response\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    mi_string);</span><br><span style="color: hsl(120, 100%, 40%);">+              return -EIO;</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%);">+   memcpy(conn->vsub->classmark.classmark2, classmark2, classmark2_len);</span><br><span style="color: hsl(120, 100%, 40%);">+   conn->vsub->classmark.classmark2_len = classmark2_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       msc_subscr_conn_complete_layer_3(conn);</span><br><span>      return 0;</span><br><span> }</span><br><span>@@ -1390,10 +1401,10 @@</span><br><span>     gh = msgb_l3(msg);</span><br><span>   pdisc = gsm48_hdr_pdisc(gh);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        if (conn->classmark.classmark1_set && conn->classmark.classmark1.rev_lev < 2) {</span><br><span style="color: hsl(0, 100%, 40%);">-                modulo = gsm0407_determine_nsd_ret_modulo_r98(pdisc, gh->msg_type, &n_sd);</span><br><span style="color: hsl(0, 100%, 40%);">-       } else { /* R99 */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (conn->vsub && classmark_is_r99(&conn->vsub->classmark)) {</span><br><span>           modulo = gsm0407_determine_nsd_ret_modulo_r99(pdisc, gh->msg_type, &n_sd);</span><br><span style="color: hsl(120, 100%, 40%);">+     } else { /* pre R99 */</span><br><span style="color: hsl(120, 100%, 40%);">+                modulo = gsm0407_determine_nsd_ret_modulo_r98(pdisc, gh->msg_type, &n_sd);</span><br><span>    }</span><br><span>    if (modulo == 0)</span><br><span>             return false;</span><br><span>@@ -1618,7 +1629,7 @@</span><br><span> </span><br><span>                    for (i = 0; i < 8; i++) {</span><br><span>                                 if (net->a5_encryption_mask & (1 << i) &&</span><br><span style="color: hsl(0, 100%, 40%);">-                              classmark_supports_a5(&conn->classmark, i))</span><br><span style="color: hsl(120, 100%, 40%);">+                                    classmark_supports_a5(&conn->vsub->classmark, i))</span><br><span>                                      ei.perm_algo[j++] = vlr_ciph_to_gsm0808_alg_id(i);</span><br><span>                   }</span><br><span>                    ei.perm_algo_len = j;</span><br><span>diff --git a/src/libmsc/osmo_msc.c b/src/libmsc/osmo_msc.c</span><br><span>index a6618c0..1966043 100644</span><br><span>--- a/src/libmsc/osmo_msc.c</span><br><span>+++ b/src/libmsc/osmo_msc.c</span><br><span>@@ -147,23 +147,25 @@</span><br><span>                      const uint8_t *cm2, uint8_t cm2_len,</span><br><span>                 const uint8_t *cm3, uint8_t cm3_len)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_classmark *cm = &conn->vsub->classmark;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       if (cm2 && cm2_len) {</span><br><span style="color: hsl(0, 100%, 40%);">-           if (cm2_len > sizeof(conn->classmark.classmark2)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             if (cm2_len > sizeof(cm->classmark2)) {</span><br><span>                        LOGP(DRR, LOGL_NOTICE, "%s: classmark2 is %u bytes, truncating at %zu bytes\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                            vlr_subscr_name(conn->vsub), cm2_len, sizeof(conn->classmark.classmark2));</span><br><span style="color: hsl(0, 100%, 40%);">-                   cm2_len = sizeof(conn->classmark.classmark2);</span><br><span style="color: hsl(120, 100%, 40%);">+                           vlr_subscr_name(conn->vsub), cm2_len, sizeof(cm->classmark2));</span><br><span style="color: hsl(120, 100%, 40%);">+                     cm2_len = sizeof(cm->classmark2);</span><br><span>                 }</span><br><span style="color: hsl(0, 100%, 40%);">-               conn->classmark.classmark2_len = cm2_len;</span><br><span style="color: hsl(0, 100%, 40%);">-            memcpy(conn->classmark.classmark2, cm2, cm2_len);</span><br><span style="color: hsl(120, 100%, 40%);">+          cm->classmark2_len = cm2_len;</span><br><span style="color: hsl(120, 100%, 40%);">+              memcpy(cm->classmark2, cm2, cm2_len);</span><br><span>     }</span><br><span>    if (cm3 && cm3_len) {</span><br><span style="color: hsl(0, 100%, 40%);">-           if (cm3_len > sizeof(conn->classmark.classmark3)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             if (cm3_len > sizeof(cm->classmark3)) {</span><br><span>                        LOGP(DRR, LOGL_NOTICE, "%s: classmark3 is %u bytes, truncating at %zu bytes\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                            vlr_subscr_name(conn->vsub), cm3_len, sizeof(conn->classmark.classmark3));</span><br><span style="color: hsl(0, 100%, 40%);">-                   cm3_len = sizeof(conn->classmark.classmark3);</span><br><span style="color: hsl(120, 100%, 40%);">+                           vlr_subscr_name(conn->vsub), cm3_len, sizeof(cm->classmark3));</span><br><span style="color: hsl(120, 100%, 40%);">+                     cm3_len = sizeof(cm->classmark3);</span><br><span>                 }</span><br><span style="color: hsl(0, 100%, 40%);">-               conn->classmark.classmark3_len = cm3_len;</span><br><span style="color: hsl(0, 100%, 40%);">-            memcpy(conn->classmark.classmark3, cm3, cm3_len);</span><br><span style="color: hsl(120, 100%, 40%);">+          cm->classmark3_len = cm3_len;</span><br><span style="color: hsl(120, 100%, 40%);">+              memcpy(cm->classmark3, cm3, cm3_len);</span><br><span>     }</span><br><span> }</span><br><span> </span><br><span>diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.err b/tests/msc_vlr/msc_vlr_test_gsm_ciph.err</span><br><span>index 83723ab..71e34a8 100644</span><br><span>--- a/tests/msc_vlr/msc_vlr_test_gsm_ciph.err</span><br><span>+++ b/tests/msc_vlr/msc_vlr_test_gsm_ciph.err</span><br><span>@@ -237,7 +237,6 @@</span><br><span> DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()</span><br><span> DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode</span><br><span> DMM -> CIPHER MODE COMMAND MSISDN:46071</span><br><span style="color: hsl(0, 100%, 40%);">-DMSC CLASSMARK 1 unknown, assuming MS supports A5/1</span><br><span> - sending Ciphering Mode Command for MSISDN:46071: include_imeisv=0</span><br><span> - ...perm algo: 2</span><br><span> - ...key: 07fa7502e07e1c00</span><br><span>@@ -376,7 +375,6 @@</span><br><span> DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()</span><br><span> DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode</span><br><span> DMM -> CIPHER MODE COMMAND MSISDN:46071</span><br><span style="color: hsl(0, 100%, 40%);">-DMSC CLASSMARK 1 unknown, assuming MS supports A5/1</span><br><span> - sending Ciphering Mode Command for MSISDN:46071: include_imeisv=0</span><br><span> - ...perm algo: 2</span><br><span> - ...key: e2b234f807886400</span><br><span>@@ -779,7 +777,6 @@</span><br><span> DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()</span><br><span> DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode</span><br><span> DMM -> CIPHER MODE COMMAND MSISDN:46071</span><br><span style="color: hsl(0, 100%, 40%);">-DMSC CLASSMARK 1 unknown, assuming MS supports A5/1</span><br><span> - sending Ciphering Mode Command for MSISDN:46071: include_imeisv=0</span><br><span> - ...perm algo: 2</span><br><span> - ...key: 07fa7502e07e1c00</span><br><span>@@ -918,7 +915,6 @@</span><br><span> DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()</span><br><span> DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode</span><br><span> DMM -> CIPHER MODE COMMAND MSISDN:46071</span><br><span style="color: hsl(0, 100%, 40%);">-DMSC CLASSMARK 1 unknown, assuming MS supports A5/1</span><br><span> - sending Ciphering Mode Command for MSISDN:46071: include_imeisv=0</span><br><span> - ...perm algo: 2</span><br><span> - ...key: e2b234f807886400</span><br><span>@@ -2018,7 +2014,6 @@</span><br><span> DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()</span><br><span> DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode</span><br><span> DMM -> CIPHER MODE COMMAND MSISDN:42342</span><br><span style="color: hsl(0, 100%, 40%);">-DMSC CLASSMARK 1 unknown, assuming MS supports A5/1</span><br><span> - sending Ciphering Mode Command for MSISDN:42342: include_imeisv=0</span><br><span> - ...perm algo: 2</span><br><span> - ...key: da149b11d473f400</span><br><span>@@ -2147,7 +2142,6 @@</span><br><span> DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()</span><br><span> DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode</span><br><span> DMM -> CIPHER MODE COMMAND MSISDN:42342</span><br><span style="color: hsl(0, 100%, 40%);">-DMSC CLASSMARK 1 unknown, assuming MS supports A5/1</span><br><span> - sending Ciphering Mode Command for MSISDN:42342: include_imeisv=0</span><br><span> - ...perm algo: 2</span><br><span> - ...key: 26ec67fad3073000</span><br><span>diff --git a/tests/msc_vlr/msc_vlr_test_rest.err b/tests/msc_vlr/msc_vlr_test_rest.err</span><br><span>index e71295a..395a138 100644</span><br><span>--- a/tests/msc_vlr/msc_vlr_test_rest.err</span><br><span>+++ b/tests/msc_vlr/msc_vlr_test_rest.err</span><br><span>@@ -71,8 +71,7 @@</span><br><span> DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING</span><br><span> DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)</span><br><span> - BSSAP Clear --RAN_GERAN_A--> MS</span><br><span style="color: hsl(0, 100%, 40%);">-DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3</span><br><span style="color: hsl(0, 100%, 40%);">-DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Event SUBSCR_CONN_E_COMPLETE_LAYER_3 not permitted</span><br><span style="color: hsl(120, 100%, 40%);">+DRR 901700000004620: subscriber not allowed to do a CM Service Request</span><br><span> DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)</span><br><span>   bssap_clear_sent == 1</span><br><span> - conn was released</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/10985">change 10985</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/10985"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-msc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I27081bf6e9e017923b2d02607f7ea06beddad82a </div>
<div style="display:none"> Gerrit-Change-Number: 10985 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Vadim Yanitskiy <axilirator@gmail.com> </div>