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

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">gsm0808: add BSSMAP Cell Identifier matching API<br><br>Add<br>* osmo_lai_cmp() (to use in gsm0808_cell_id_u_matches())<br>* osmo_cgi_cmp() (to use in gsm0808_cell_id_u_matches())<br>* gsm0808_cell_id_u_match() (to re-use for single IDs and lists)<br>* gsm0808_cell_ids_match()<br>* gsm0808_cell_id_matches_list()<br>* Unit tests in gsm0808_test.c<br><br>Rationale:<br><br>For inter-BSC handover, it is interesting to find matches between *differing*<br>Cell Identity kinds. For example, if a cell as CGI 23-42-3-5, and a HO for<br>LAC-CI 3-5 should be handled, we need to see the match.<br><br>This is most interesting for osmo-msc, i.e. to direct the BSSMAP Handover<br>Request towards the correct BSC or MSC.<br><br>It is also interesting for osmo-bsc's VTY interface, to be able to manage<br>cells' neighbors and to trigger manual handovers by various Cell Identity<br>handles, as the user would expect them.<br><br>Change-Id: I5535f0d149c2173294538df75764dd181b023312<br>---<br>M include/osmocom/gsm/gsm0808_utils.h<br>M include/osmocom/gsm/gsm23003.h<br>M src/gsm/gsm0808_utils.c<br>M src/gsm/gsm23003.c<br>M src/gsm/libosmogsm.map<br>M tests/gsm0808/gsm0808_test.c<br>M tests/gsm0808/gsm0808_test.ok<br>7 files changed, 645 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h</span><br><span>index 7c6f707..e1e345d 100644</span><br><span>--- a/include/osmocom/gsm/gsm0808_utils.h</span><br><span>+++ b/include/osmocom/gsm/gsm0808_utils.h</span><br><span>@@ -78,6 +78,9 @@</span><br><span> int gsm0808_cell_id_list_name_buf(char *buf, size_t buflen, const struct gsm0808_cell_id_list2 *cil);</span><br><span> int gsm0808_cell_id_u_name(char *buf, size_t buflen,</span><br><span>                     enum CELL_IDENT id_discr, const union gsm0808_cell_id_u *u);</span><br><span style="color: hsl(120, 100%, 40%);">+bool gsm0808_cell_ids_match(const struct gsm0808_cell_id *id1, const struct gsm0808_cell_id *id2, bool exact_match);</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm0808_cell_id_matches_list(const struct gsm0808_cell_id *id, const struct gsm0808_cell_id_list2 *list,</span><br><span style="color: hsl(120, 100%, 40%);">+                            unsigned int match_nr, bool exact_match);</span><br><span> </span><br><span> uint8_t gsm0808_enc_cause(struct msgb *msg, uint16_t cause);</span><br><span> uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg,</span><br><span>diff --git a/include/osmocom/gsm/gsm23003.h b/include/osmocom/gsm/gsm23003.h</span><br><span>index b5c8dcd..b34a677 100644</span><br><span>--- a/include/osmocom/gsm/gsm23003.h</span><br><span>+++ b/include/osmocom/gsm/gsm23003.h</span><br><span>@@ -122,6 +122,8 @@</span><br><span> </span><br><span> int osmo_mnc_cmp(uint16_t a_mnc, bool a_mnc_3_digits, uint16_t b_mnc, bool b_mnc_3_digits);</span><br><span> int osmo_plmn_cmp(const struct osmo_plmn_id *a, const struct osmo_plmn_id *b);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_lai_cmp(const struct osmo_location_area_id *a, const struct osmo_location_area_id *b);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_cgi_cmp(const struct osmo_cell_global_id *a, const struct osmo_cell_global_id *b);</span><br><span> </span><br><span> int osmo_gen_home_network_domain(char *out, const struct osmo_plmn_id *plmn);</span><br><span> int osmo_parse_home_network_domain(struct osmo_plmn_id *out, const char *in);</span><br><span>diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c</span><br><span>index 9fcccae..54ec19c 100644</span><br><span>--- a/src/gsm/gsm0808_utils.c</span><br><span>+++ b/src/gsm/gsm0808_utils.c</span><br><span>@@ -1391,6 +1391,151 @@</span><br><span>       }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Store individual Cell Identifier information in a CGI, without clearing the remaining ones.</span><br><span style="color: hsl(120, 100%, 40%);">+ * This is useful to supplement one CGI with information from more than one Cell Identifier,</span><br><span style="color: hsl(120, 100%, 40%);">+ * which in turn is useful to match Cell Identifiers of differing kinds to each other.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Before first invocation, clear the *dst struct externally, this function does only write those members</span><br><span style="color: hsl(120, 100%, 40%);">+ * that are present in parameter u.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void cell_id_to_cgi(struct osmo_cell_global_id *dst,</span><br><span style="color: hsl(120, 100%, 40%);">+                       enum CELL_IDENT discr, const union gsm0808_cell_id_u *u)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (discr) {</span><br><span style="color: hsl(120, 100%, 40%);">+      case CELL_IDENT_WHOLE_GLOBAL:</span><br><span style="color: hsl(120, 100%, 40%);">+         *dst = u->global;</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     case CELL_IDENT_LAC_AND_CI:</span><br><span style="color: hsl(120, 100%, 40%);">+           dst->lai.lac = u->lac_and_ci.lac;</span><br><span style="color: hsl(120, 100%, 40%);">+               dst->cell_identity = u->lac_and_ci.ci;</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     case CELL_IDENT_CI:</span><br><span style="color: hsl(120, 100%, 40%);">+           dst->cell_identity = u->ci;</span><br><span style="color: hsl(120, 100%, 40%);">+             return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     case CELL_IDENT_LAI_AND_LAC:</span><br><span style="color: hsl(120, 100%, 40%);">+          dst->lai = u->lai_and_lac;</span><br><span style="color: hsl(120, 100%, 40%);">+              return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     case CELL_IDENT_LAC:</span><br><span style="color: hsl(120, 100%, 40%);">+          dst->lai.lac = u->lac;</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     case CELL_IDENT_NO_CELL:</span><br><span style="color: hsl(120, 100%, 40%);">+      case CELL_IDENT_BSS:</span><br><span style="color: hsl(120, 100%, 40%);">+  case CELL_IDENT_UTRAN_PLMN_LAC_RNC:</span><br><span style="color: hsl(120, 100%, 40%);">+   case CELL_IDENT_UTRAN_RNC:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CELL_IDENT_UTRAN_LAC_RNC:</span><br><span style="color: hsl(120, 100%, 40%);">+                /* No values to set. */</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Return true if the common information between the two Cell Identifiers match.</span><br><span style="color: hsl(120, 100%, 40%);">+ * For example, if a LAC+CI is compared to LAC, return true if the LAC are the same.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Note that CELL_IDENT_NO_CELL will always return false.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Also CELL_IDENT_BSS will always return false, since this function cannot possibly</span><br><span style="color: hsl(120, 100%, 40%);">+ * know the bounds of the BSS, so the caller must handle CELL_IDENT_BSS specially.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] discr1  Cell Identifier type.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] u1  Cell Identifier value.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] discr2  Other Cell Identifier type.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] u2  Other Cell Identifier value.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] exact_match  If true, return true only if the CELL_IDENT types and all values are identical.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns True if the common fields of the above match.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static bool gsm0808_cell_id_u_match(enum CELL_IDENT discr1, const union gsm0808_cell_id_u *u1,</span><br><span style="color: hsl(120, 100%, 40%);">+                                enum CELL_IDENT discr2, const union gsm0808_cell_id_u *u2,</span><br><span style="color: hsl(120, 100%, 40%);">+                                    bool exact_match)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct osmo_cell_global_id a = {};</span><br><span style="color: hsl(120, 100%, 40%);">+    struct osmo_cell_global_id b = {};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (exact_match && discr1 != discr2)</span><br><span style="color: hsl(120, 100%, 40%);">+          return false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* First handle the odd wildcard like CELL_IDENT kinds. We can't really match any of these. */</span><br><span style="color: hsl(120, 100%, 40%);">+    switch (discr1) {</span><br><span style="color: hsl(120, 100%, 40%);">+     case CELL_IDENT_NO_CELL:</span><br><span style="color: hsl(120, 100%, 40%);">+      case CELL_IDENT_BSS:</span><br><span style="color: hsl(120, 100%, 40%);">+          return discr1 == discr2;</span><br><span style="color: hsl(120, 100%, 40%);">+      case CELL_IDENT_UTRAN_PLMN_LAC_RNC:</span><br><span style="color: hsl(120, 100%, 40%);">+   case CELL_IDENT_UTRAN_RNC:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CELL_IDENT_UTRAN_LAC_RNC:</span><br><span style="color: hsl(120, 100%, 40%);">+                return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     switch (discr2) {</span><br><span style="color: hsl(120, 100%, 40%);">+     case CELL_IDENT_NO_CELL:</span><br><span style="color: hsl(120, 100%, 40%);">+      case CELL_IDENT_UTRAN_PLMN_LAC_RNC:</span><br><span style="color: hsl(120, 100%, 40%);">+   case CELL_IDENT_UTRAN_RNC:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CELL_IDENT_UTRAN_LAC_RNC:</span><br><span style="color: hsl(120, 100%, 40%);">+        case CELL_IDENT_BSS:</span><br><span style="color: hsl(120, 100%, 40%);">+          return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</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%);">+   /* Enrich both sides to full CGI, then compare those. First set the *other* ID's values in case</span><br><span style="color: hsl(120, 100%, 40%);">+    * they assign more items. For example:</span><br><span style="color: hsl(120, 100%, 40%);">+        * u1 = LAC:42</span><br><span style="color: hsl(120, 100%, 40%);">+         * u2 = LAC+CI:23+5</span><br><span style="color: hsl(120, 100%, 40%);">+    * 1) a <- LAC+CI:23+5</span><br><span style="color: hsl(120, 100%, 40%);">+      * 2) a <- LAC:42 so that a = LAC+CI:42+5</span><br><span style="color: hsl(120, 100%, 40%);">+   * Now we can compare those two and find a mismatch. If the LAC were the same, we would get</span><br><span style="color: hsl(120, 100%, 40%);">+    * identical LAC+CI and hence a match. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   cell_id_to_cgi(&a, discr2, u2);</span><br><span style="color: hsl(120, 100%, 40%);">+   cell_id_to_cgi(&a, discr1, u1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ cell_id_to_cgi(&b, discr1, u1);</span><br><span style="color: hsl(120, 100%, 40%);">+   cell_id_to_cgi(&b, discr2, u2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return osmo_cgi_cmp(&a, &b) == 0;</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%);">+/*! Return true if the common information between the two Cell Identifiers match.</span><br><span style="color: hsl(120, 100%, 40%);">+ * For example, if a LAC+CI is compared to LAC, return true if the LAC are the same.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Note that CELL_IDENT_NO_CELL will always return false.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Also CELL_IDENT_BSS will always return false, since this function cannot possibly</span><br><span style="color: hsl(120, 100%, 40%);">+ * know the bounds of the BSS, so the caller must handle CELL_IDENT_BSS specially.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] id1  Cell Identifier.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] id2  Other Cell Identifier.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] exact_match  If true, return true only if the CELL_IDENT types and all values are identical.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns True if the common fields of the above match.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+bool gsm0808_cell_ids_match(const struct gsm0808_cell_id *id1, const struct gsm0808_cell_id *id2, bool exact_match)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      return gsm0808_cell_id_u_match(id1->id_discr, &id1->id, id2->id_discr, &id2->id, exact_match);</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%);">+/*! Find an index in a Cell Identifier list that matches a given single Cell Identifer.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Compare \a id against each entry in \a list using gsm0808_cell_ids_match(), and return the list index</span><br><span style="color: hsl(120, 100%, 40%);">+ * if a match is found. \a match_nr allows iterating all matches in the list. A match_nr <= 0 returns the</span><br><span style="color: hsl(120, 100%, 40%);">+ * first match in the list, match_nr == 1 the second match, etc., and if match_nr exceeds the available</span><br><span style="color: hsl(120, 100%, 40%);">+ * matches in the list, -1 is returned.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] id  Cell Identifier to match.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] list  Cell Identifier list to search in.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] match_nr  Ignore this many matches.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] exact_match  If true, consider as match only if the CELL_IDENT types and all values are identical.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns -1 if no match is found, list index if a match is found.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm0808_cell_id_matches_list(const struct gsm0808_cell_id *id, const struct gsm0808_cell_id_list2 *list,</span><br><span style="color: hsl(120, 100%, 40%);">+                          unsigned int match_nr, bool exact_match)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  int i;</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i = 0; i < list->id_list_len; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (gsm0808_cell_id_u_match(id->id_discr, &id->id, list->id_discr, &list->id_list[i], exact_match)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (match_nr)</span><br><span style="color: hsl(120, 100%, 40%);">+                         match_nr--;</span><br><span style="color: hsl(120, 100%, 40%);">+                   else</span><br><span style="color: hsl(120, 100%, 40%);">+                          return i;</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%);">+     return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! value_string[] for enum CELL_IDENT. */</span><br><span> const struct value_string gsm0808_cell_id_discr_names[] = {</span><br><span>         { CELL_IDENT_WHOLE_GLOBAL, "CGI" },</span><br><span>diff --git a/src/gsm/gsm23003.c b/src/gsm/gsm23003.c</span><br><span>index 1d9cefe..95fca91 100644</span><br><span>--- a/src/gsm/gsm23003.c</span><br><span>+++ b/src/gsm/gsm23003.c</span><br><span>@@ -324,6 +324,40 @@</span><br><span>    return osmo_mnc_cmp(a->mnc, a->mnc_3_digits, b->mnc, b->mnc_3_digits);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Compare two LAI.</span><br><span style="color: hsl(120, 100%, 40%);">+ * The order of comparison is MCC, MNC, LAC. See also osmo_plmn_cmp().</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param a[in]  "Left" side LAI.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param b[in]  "Right" side LAI.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns 0 if the LAI are equal, -1 if a < b, 1 if a > b. */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_lai_cmp(const struct osmo_location_area_id *a, const struct osmo_location_area_id *b)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc = osmo_plmn_cmp(&a->plmn, &b->plmn);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc)</span><br><span style="color: hsl(120, 100%, 40%);">+               return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (a->lac < b->lac)</span><br><span style="color: hsl(120, 100%, 40%);">+         return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (a->lac > b->lac)</span><br><span style="color: hsl(120, 100%, 40%);">+         return 1;</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 style="color: hsl(120, 100%, 40%);">+/* Compare two CGI.</span><br><span style="color: hsl(120, 100%, 40%);">+ * The order of comparison is MCC, MNC, LAC, CI. See also osmo_lai_cmp().</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param a[in]  "Left" side CGI.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param b[in]  "Right" side CGI.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns 0 if the CGI are equal, -1 if a < b, 1 if a > b. */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_cgi_cmp(const struct osmo_cell_global_id *a, const struct osmo_cell_global_id *b)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       int rc = osmo_lai_cmp(&a->lai, &b->lai);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (rc)</span><br><span style="color: hsl(120, 100%, 40%);">+               return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (a->cell_identity < b->cell_identity)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (a->cell_identity > b->cell_identity)</span><br><span style="color: hsl(120, 100%, 40%);">+             return 1;</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> /*! Generate TS 23.003 Section 19.2 Home Network Realm/Domain (text form)</span><br><span>  *  \param out[out] caller-provided output buffer, at least 33 bytes long</span><br><span>  *  \param plmn[in] Osmocom representation of PLMN ID (MCC + MNC)</span><br><span>diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map</span><br><span>index c440a79..ea8c9be 100644</span><br><span>--- a/src/gsm/libosmogsm.map</span><br><span>+++ b/src/gsm/libosmogsm.map</span><br><span>@@ -210,6 +210,8 @@</span><br><span> gsm0808_cell_id_list_name_buf;</span><br><span> gsm0808_cell_id_discr_names;</span><br><span> gsm0808_cell_id_u_name;</span><br><span style="color: hsl(120, 100%, 40%);">+gsm0808_cell_ids_match;</span><br><span style="color: hsl(120, 100%, 40%);">+gsm0808_cell_id_matches_list;</span><br><span> gsm0808_chan_type_to_speech_codec;</span><br><span> gsm0808_speech_codec_from_chan_type;</span><br><span> gsm0808_sc_cfg_from_gsm48_mr_cfg;</span><br><span>diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c</span><br><span>index 90bef21..f06e8b7 100644</span><br><span>--- a/tests/gsm0808/gsm0808_test.c</span><br><span>+++ b/tests/gsm0808/gsm0808_test.c</span><br><span>@@ -1937,6 +1937,275 @@</span><br><span>          (GSM0808_SC_CFG_DEFAULT_AMR_7_95 | GSM0808_SC_CFG_DEFAULT_AMR_12_2);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct test_cell_id_matching_data {</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gsm0808_cell_id id;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gsm0808_cell_id match_id;</span><br><span style="color: hsl(120, 100%, 40%);">+      bool expect_match;</span><br><span style="color: hsl(120, 100%, 40%);">+    bool expect_exact_match;</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%);">+#define lac_23 { .id_discr = CELL_IDENT_LAC, .id.lac = 23, }</span><br><span style="color: hsl(120, 100%, 40%);">+#define lac_42 { .id_discr = CELL_IDENT_LAC, .id.lac = 42, }</span><br><span style="color: hsl(120, 100%, 40%);">+#define ci_5 { .id_discr = CELL_IDENT_CI, .id.ci = 5, }</span><br><span style="color: hsl(120, 100%, 40%);">+#define ci_6 { .id_discr = CELL_IDENT_CI, .id.ci = 6, }</span><br><span style="color: hsl(120, 100%, 40%);">+#define lac_ci_23_5 { \</span><br><span style="color: hsl(120, 100%, 40%);">+         .id_discr = CELL_IDENT_LAC_AND_CI, \</span><br><span style="color: hsl(120, 100%, 40%);">+          .id.lac_and_ci = { .lac = 23, .ci = 5, }, \</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+#define lac_ci_42_6 { \</span><br><span style="color: hsl(120, 100%, 40%);">+            .id_discr = CELL_IDENT_LAC_AND_CI, \</span><br><span style="color: hsl(120, 100%, 40%);">+          .id.lac_and_ci = { .lac = 42, .ci = 6, }, \</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+#define lai_23_042_23 { \</span><br><span style="color: hsl(120, 100%, 40%);">+          .id_discr = CELL_IDENT_LAI_AND_LAC, \</span><br><span style="color: hsl(120, 100%, 40%);">+         .id.lai_and_lac = { .plmn = { .mcc = 23, .mnc = 42, .mnc_3_digits = true }, .lac = 23, }, \</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+#define lai_23_042_42 { \</span><br><span style="color: hsl(120, 100%, 40%);">+          .id_discr = CELL_IDENT_LAI_AND_LAC, \</span><br><span style="color: hsl(120, 100%, 40%);">+         .id.lai_and_lac = { .plmn = { .mcc = 23, .mnc = 42, .mnc_3_digits = true }, .lac = 42, }, \</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+#define lai_23_99_23 { \</span><br><span style="color: hsl(120, 100%, 40%);">+           .id_discr = CELL_IDENT_LAI_AND_LAC, \</span><br><span style="color: hsl(120, 100%, 40%);">+         .id.lai_and_lac = { .plmn = { .mcc = 23, .mnc = 99, .mnc_3_digits = false }, .lac = 23, }, \</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+#define lai_23_42_23 { \</span><br><span style="color: hsl(120, 100%, 40%);">+           .id_discr = CELL_IDENT_LAI_AND_LAC, \</span><br><span style="color: hsl(120, 100%, 40%);">+         .id.lai_and_lac = { .plmn = { .mcc = 23, .mnc = 42, .mnc_3_digits = false }, .lac = 23, }, \</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+#define cgi_23_042_23_5 { \</span><br><span style="color: hsl(120, 100%, 40%);">+                .id_discr = CELL_IDENT_WHOLE_GLOBAL, \</span><br><span style="color: hsl(120, 100%, 40%);">+                .id.global = { \</span><br><span style="color: hsl(120, 100%, 40%);">+                      .lai = { .plmn = { .mcc = 23, .mnc = 42, .mnc_3_digits = true }, .lac = 23, }, \</span><br><span style="color: hsl(120, 100%, 40%);">+                      .cell_identity = 5, \</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%);">+#define cgi_23_042_42_6 { \</span><br><span style="color: hsl(120, 100%, 40%);">+                .id_discr = CELL_IDENT_WHOLE_GLOBAL, \</span><br><span style="color: hsl(120, 100%, 40%);">+                .id.global = { \</span><br><span style="color: hsl(120, 100%, 40%);">+                      .lai = { .plmn = { .mcc = 23, .mnc = 42, .mnc_3_digits = true }, .lac = 42, }, \</span><br><span style="color: hsl(120, 100%, 40%);">+                      .cell_identity = 6, \</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%);">+#define cgi_23_99_23_5 { \</span><br><span style="color: hsl(120, 100%, 40%);">+         .id_discr = CELL_IDENT_WHOLE_GLOBAL, \</span><br><span style="color: hsl(120, 100%, 40%);">+                .id.global = { \</span><br><span style="color: hsl(120, 100%, 40%);">+                      .lai = { .plmn = { .mcc = 23, .mnc = 99, .mnc_3_digits = false }, .lac = 23, }, \</span><br><span style="color: hsl(120, 100%, 40%);">+                     .cell_identity = 5, \</span><br><span style="color: hsl(120, 100%, 40%);">+         }, \</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct test_cell_id_matching_data test_cell_id_matching_tests[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+       { .id = lac_23, .match_id = lac_23, .expect_match = true, .expect_exact_match = true },</span><br><span style="color: hsl(120, 100%, 40%);">+       { .id = lac_23, .match_id = lac_42, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+     { .id = lac_23, .match_id = ci_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { .id = lac_23, .match_id = ci_6, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { .id = lac_23, .match_id = lac_ci_23_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .id = lac_23, .match_id = lac_ci_42_6, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { .id = lac_23, .match_id = lai_23_042_23, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+       { .id = lac_23, .match_id = lai_23_042_42, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+      { .id = lac_23, .match_id = lai_23_99_23, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { .id = lac_23, .match_id = lai_23_42_23, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { .id = lac_23, .match_id = cgi_23_042_23_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+     { .id = lac_23, .match_id = cgi_23_042_42_6, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+    { .id = lac_23, .match_id = cgi_23_99_23_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+      { .id = ci_5, .match_id = lac_23, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { .id = ci_5, .match_id = lac_42, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { .id = ci_5, .match_id = ci_5, .expect_match = true, .expect_exact_match = true },</span><br><span style="color: hsl(120, 100%, 40%);">+   { .id = ci_5, .match_id = ci_6, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .id = ci_5, .match_id = lac_ci_23_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+   { .id = ci_5, .match_id = lac_ci_42_6, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+  { .id = ci_5, .match_id = lai_23_042_23, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .id = ci_5, .match_id = lai_23_042_42, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .id = ci_5, .match_id = lai_23_99_23, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+  { .id = ci_5, .match_id = lai_23_42_23, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+  { .id = ci_5, .match_id = cgi_23_042_23_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+       { .id = ci_5, .match_id = cgi_23_042_42_6, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+      { .id = ci_5, .match_id = cgi_23_99_23_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { .id = lac_ci_23_5, .match_id = lac_23, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .id = lac_ci_23_5, .match_id = lac_42, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { .id = lac_ci_23_5, .match_id = ci_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+   { .id = lac_ci_23_5, .match_id = ci_6, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+  { .id = lac_ci_23_5, .match_id = lac_ci_23_5, .expect_match = true, .expect_exact_match = true },</span><br><span style="color: hsl(120, 100%, 40%);">+     { .id = lac_ci_23_5, .match_id = lac_ci_42_6, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+   { .id = lac_ci_23_5, .match_id = lai_23_042_23, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+  { .id = lac_ci_23_5, .match_id = lai_23_042_42, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .id = lac_ci_23_5, .match_id = lai_23_99_23, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+   { .id = lac_ci_23_5, .match_id = lai_23_42_23, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+   { .id = lac_ci_23_5, .match_id = cgi_23_042_23_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { .id = lac_ci_23_5, .match_id = cgi_23_042_42_6, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+       { .id = lac_ci_23_5, .match_id = cgi_23_99_23_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .id = lai_23_042_23, .match_id = lac_23, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+       { .id = lai_23_042_23, .match_id = lac_42, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+      { .id = lai_23_042_23, .match_id = ci_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .id = lai_23_042_23, .match_id = ci_6, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .id = lai_23_042_23, .match_id = lac_ci_23_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+  { .id = lai_23_042_23, .match_id = lac_ci_42_6, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .id = lai_23_042_23, .match_id = lai_23_042_23, .expect_match = true, .expect_exact_match = true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .id = lai_23_042_23, .match_id = lai_23_042_42, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+       { .id = lai_23_042_23, .match_id = lai_23_99_23, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { .id = lai_23_042_23, .match_id = lai_23_42_23, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { .id = lai_23_042_23, .match_id = cgi_23_042_23_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+      { .id = lai_23_042_23, .match_id = cgi_23_042_42_6, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+     { .id = lai_23_042_23, .match_id = cgi_23_99_23_5, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+      { .id = cgi_23_042_23_5, .match_id = lac_23, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+     { .id = cgi_23_042_23_5, .match_id = lac_42, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+    { .id = cgi_23_042_23_5, .match_id = ci_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+       { .id = cgi_23_042_23_5, .match_id = ci_6, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+      { .id = cgi_23_042_23_5, .match_id = lac_ci_23_5, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { .id = cgi_23_042_23_5, .match_id = lac_ci_42_6, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+       { .id = cgi_23_042_23_5, .match_id = lai_23_042_23, .expect_match = true, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+      { .id = cgi_23_042_23_5, .match_id = lai_23_042_42, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+     { .id = cgi_23_042_23_5, .match_id = lai_23_99_23, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+      { .id = cgi_23_042_23_5, .match_id = lai_23_42_23, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+      { .id = cgi_23_042_23_5, .match_id = cgi_23_042_23_5, .expect_match = true, .expect_exact_match = true },</span><br><span style="color: hsl(120, 100%, 40%);">+     { .id = cgi_23_042_23_5, .match_id = cgi_23_042_42_6, .expect_match = false, .expect_exact_match = false },</span><br><span style="color: hsl(120, 100%, 40%);">+   { .id = cgi_23_042_23_5, .match_id = cgi_23_99_23_5, .expect_match = false, .expect_exact_match = false },</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 void test_cell_id_matching()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      int i;</span><br><span style="color: hsl(120, 100%, 40%);">+        bool ok = true;</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("\n%s\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       for (i = 0; i < ARRAY_SIZE(test_cell_id_matching_tests); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+            const struct test_cell_id_matching_data *d = &test_cell_id_matching_tests[i];</span><br><span style="color: hsl(120, 100%, 40%);">+             int exact_match;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            for (exact_match = 0; exact_match < 2; exact_match++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    bool result;</span><br><span style="color: hsl(120, 100%, 40%);">+                  bool expect_result = exact_match ? d->expect_exact_match : d->expect_match;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   result = gsm0808_cell_ids_match(&d->id, &d->match_id, (bool)exact_match);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                     printf("[%d] %s %s %s%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                        i,</span><br><span style="color: hsl(120, 100%, 40%);">+                            gsm0808_cell_id_name(&d->id),</span><br><span style="color: hsl(120, 100%, 40%);">+                          gsm0808_cell_id_name2(&d->match_id),</span><br><span style="color: hsl(120, 100%, 40%);">+                           result ? "MATCH" : "don't match",</span><br><span style="color: hsl(120, 100%, 40%);">+                             exact_match ? " exactly" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (result != expect_result) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                printf("  ERROR: expected %s\n", d->expect_match ? "MATCH" : "no match");</span><br><span style="color: hsl(120, 100%, 40%);">+                            ok = false;</span><br><span style="color: hsl(120, 100%, 40%);">+                   }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_ASSERT(ok);</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 test_cell_id_list_matching_discrs(bool test_match,</span><br><span style="color: hsl(120, 100%, 40%);">+                                       enum CELL_IDENT id_discr,</span><br><span style="color: hsl(120, 100%, 40%);">+                                             enum CELL_IDENT list_discr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  int i, j;</span><br><span style="color: hsl(120, 100%, 40%);">+     const struct gsm0808_cell_id *id = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm0808_cell_id_list2 list = {};</span><br><span style="color: hsl(120, 100%, 40%);">+       int match_idx = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+   int result;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < ARRAY_SIZE(test_cell_id_matching_tests); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+            const struct test_cell_id_matching_data *d = &test_cell_id_matching_tests[i];</span><br><span style="color: hsl(120, 100%, 40%);">+             if (id_discr != d->id.id_discr)</span><br><span style="color: hsl(120, 100%, 40%);">+                    continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             id = &d->id;</span><br><span style="color: hsl(120, 100%, 40%);">+           break;</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 (!id) {</span><br><span style="color: hsl(120, 100%, 40%);">+            printf("Did not find any entry for %s\n", gsm0808_cell_id_discr_name(id_discr));</span><br><span style="color: hsl(120, 100%, 40%);">+            return 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%);">+   /* Collect those entries with exactly this id on the left, of type list_discr on the right.</span><br><span style="color: hsl(120, 100%, 40%);">+    * Collect the mismatches first, for more interesting match indexes in the results. */</span><br><span style="color: hsl(120, 100%, 40%);">+        for (j = 0; j < 2; j++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          bool collect_matches = (bool)j;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             /* If we want to have a mismatching list, don't add any entries that match. */</span><br><span style="color: hsl(120, 100%, 40%);">+            if (!test_match && collect_matches)</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%);">+           for (i = 0; i < ARRAY_SIZE(test_cell_id_matching_tests); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    const struct test_cell_id_matching_data *d = &test_cell_id_matching_tests[i];</span><br><span style="color: hsl(120, 100%, 40%);">+                     struct gsm0808_cell_id_list2 add;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   /* Ignore those with a different d->id */</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (!gsm0808_cell_ids_match(&d->id, id, true))</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%);">+                   /* Ignore those with a different d->match_id discr */</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (d->match_id.id_discr != list_discr)</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%);">+                   if (collect_matches != d->expect_match)</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%);">+                   if (match_idx < 0 && d->expect_match) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         match_idx = list.id_list_len;</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%);">+                   gsm0808_cell_id_to_list(&add, &d->match_id);</span><br><span style="color: hsl(120, 100%, 40%);">+                       gsm0808_cell_id_list_add(&list, &add);</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!list.id_list_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("%s vs. %s: No match_id entries to test %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                      gsm0808_cell_id_name(id),</span><br><span style="color: hsl(120, 100%, 40%);">+                     gsm0808_cell_id_discr_name(list_discr),</span><br><span style="color: hsl(120, 100%, 40%);">+                       test_match ? "MATCH" : "mismatch");</span><br><span style="color: hsl(120, 100%, 40%);">+                return 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%);">+   result = gsm0808_cell_id_matches_list(id, &list, 0, false);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("%s and %s: ",</span><br><span style="color: hsl(120, 100%, 40%);">+              gsm0808_cell_id_name(id),</span><br><span style="color: hsl(120, 100%, 40%);">+             gsm0808_cell_id_list_name(&list));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (result >= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+           printf("MATCH at [%d]\n", result);</span><br><span style="color: hsl(120, 100%, 40%);">+  else</span><br><span style="color: hsl(120, 100%, 40%);">+          printf("mismatch\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (test_match</span><br><span style="color: hsl(120, 100%, 40%);">+            && (result < 0 || result != match_idx)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("  ERROR: expected MATCH at %d\n", match_idx);</span><br><span style="color: hsl(120, 100%, 40%);">+               return false;</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 (!test_match && result >= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+          printf("  ERROR: expected mismatch\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return false;</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%);">+   return 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%);">+static void test_cell_id_list_matching(bool test_match)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int i, j;</span><br><span style="color: hsl(120, 100%, 40%);">+     bool ok = true;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     const enum CELL_IDENT discrs[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+            CELL_IDENT_LAC, CELL_IDENT_CI, CELL_IDENT_LAC_AND_CI, CELL_IDENT_LAI_AND_LAC,</span><br><span style="color: hsl(120, 100%, 40%);">+         CELL_IDENT_WHOLE_GLOBAL,</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%);">+  printf("\n%s(%s)\n", __func__, test_match ? "test match" : "test mismatch");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Autogenerate Cell ID lists from above dataset, which should match / not match. */</span><br><span style="color: hsl(120, 100%, 40%);">+  for (i = 0; i < ARRAY_SIZE(discrs); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         for (j = 0; j < ARRAY_SIZE(discrs); j++)</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (!test_cell_id_list_matching_discrs(test_match,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                           discrs[i], discrs[j]))</span><br><span style="color: hsl(120, 100%, 40%);">+                         ok = false;</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%);">+   OSMO_ASSERT(ok);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int main(int argc, char **argv)</span><br><span> {</span><br><span>        void *ctx = talloc_named_const(NULL, 0, "gsm0808 test");</span><br><span>@@ -2002,6 +2271,10 @@</span><br><span>  test_gsm0808_sc_cfg_from_gsm48_mr_cfg();</span><br><span>     test_gsm48_mr_cfg_from_gsm0808_sc_cfg();</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+  test_cell_id_matching();</span><br><span style="color: hsl(120, 100%, 40%);">+      test_cell_id_list_matching(true);</span><br><span style="color: hsl(120, 100%, 40%);">+     test_cell_id_list_matching(false);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         printf("Done\n");</span><br><span>  return EXIT_SUCCESS;</span><br><span> }</span><br><span>diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok</span><br><span>index 8e6d262..aae8959 100644</span><br><span>--- a/tests/gsm0808/gsm0808_test.ok</span><br><span>+++ b/tests/gsm0808/gsm0808_test.ok</span><br><span>@@ -439,4 +439,190 @@</span><br><span>  m10_2= 0</span><br><span>  m12_2= 1</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+test_cell_id_matching</span><br><span style="color: hsl(120, 100%, 40%);">+[0] LAC:23 LAC:23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[0] LAC:23 LAC:23 MATCH exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[1] LAC:23 LAC:42 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[1] LAC:23 LAC:42 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[2] LAC:23 CI:5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[2] LAC:23 CI:5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[3] LAC:23 CI:6 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[3] LAC:23 CI:6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[4] LAC:23 LAC-CI:23-5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[4] LAC:23 LAC-CI:23-5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[5] LAC:23 LAC-CI:42-6 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[5] LAC:23 LAC-CI:42-6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[6] LAC:23 LAI:023-042-23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[6] LAC:23 LAI:023-042-23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[7] LAC:23 LAI:023-042-42 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[7] LAC:23 LAI:023-042-42 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[8] LAC:23 LAI:023-99-23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[8] LAC:23 LAI:023-99-23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[9] LAC:23 LAI:023-42-23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[9] LAC:23 LAI:023-42-23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[10] LAC:23 CGI:023-042-23-5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[10] LAC:23 CGI:023-042-23-5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[11] LAC:23 CGI:023-042-42-6 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[11] LAC:23 CGI:023-042-42-6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[12] LAC:23 CGI:023-99-23-5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[12] LAC:23 CGI:023-99-23-5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[13] CI:5 LAC:23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[13] CI:5 LAC:23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[14] CI:5 LAC:42 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[14] CI:5 LAC:42 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[15] CI:5 CI:5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[15] CI:5 CI:5 MATCH exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[16] CI:5 CI:6 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[16] CI:5 CI:6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[17] CI:5 LAC-CI:23-5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[17] CI:5 LAC-CI:23-5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[18] CI:5 LAC-CI:42-6 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[18] CI:5 LAC-CI:42-6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[19] CI:5 LAI:023-042-23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[19] CI:5 LAI:023-042-23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[20] CI:5 LAI:023-042-42 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[20] CI:5 LAI:023-042-42 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[21] CI:5 LAI:023-99-23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[21] CI:5 LAI:023-99-23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[22] CI:5 LAI:023-42-23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[22] CI:5 LAI:023-42-23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[23] CI:5 CGI:023-042-23-5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[23] CI:5 CGI:023-042-23-5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[24] CI:5 CGI:023-042-42-6 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[24] CI:5 CGI:023-042-42-6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[25] CI:5 CGI:023-99-23-5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[25] CI:5 CGI:023-99-23-5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[26] LAC-CI:23-5 LAC:23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[26] LAC-CI:23-5 LAC:23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[27] LAC-CI:23-5 LAC:42 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[27] LAC-CI:23-5 LAC:42 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[28] LAC-CI:23-5 CI:5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[28] LAC-CI:23-5 CI:5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[29] LAC-CI:23-5 CI:6 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[29] LAC-CI:23-5 CI:6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[30] LAC-CI:23-5 LAC-CI:23-5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[30] LAC-CI:23-5 LAC-CI:23-5 MATCH exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[31] LAC-CI:23-5 LAC-CI:42-6 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[31] LAC-CI:23-5 LAC-CI:42-6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[32] LAC-CI:23-5 LAI:023-042-23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[32] LAC-CI:23-5 LAI:023-042-23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[33] LAC-CI:23-5 LAI:023-042-42 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[33] LAC-CI:23-5 LAI:023-042-42 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[34] LAC-CI:23-5 LAI:023-99-23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[34] LAC-CI:23-5 LAI:023-99-23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[35] LAC-CI:23-5 LAI:023-42-23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[35] LAC-CI:23-5 LAI:023-42-23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[36] LAC-CI:23-5 CGI:023-042-23-5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[36] LAC-CI:23-5 CGI:023-042-23-5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[37] LAC-CI:23-5 CGI:023-042-42-6 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[37] LAC-CI:23-5 CGI:023-042-42-6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[38] LAC-CI:23-5 CGI:023-99-23-5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[38] LAC-CI:23-5 CGI:023-99-23-5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[39] LAI:023-042-23 LAC:23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[39] LAI:023-042-23 LAC:23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[40] LAI:023-042-23 LAC:42 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[40] LAI:023-042-23 LAC:42 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[41] LAI:023-042-23 CI:5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[41] LAI:023-042-23 CI:5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[42] LAI:023-042-23 CI:6 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[42] LAI:023-042-23 CI:6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[43] LAI:023-042-23 LAC-CI:23-5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[43] LAI:023-042-23 LAC-CI:23-5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[44] LAI:023-042-23 LAC-CI:42-6 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[44] LAI:023-042-23 LAC-CI:42-6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[45] LAI:023-042-23 LAI:023-042-23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[45] LAI:023-042-23 LAI:023-042-23 MATCH exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[46] LAI:023-042-23 LAI:023-042-42 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[46] LAI:023-042-23 LAI:023-042-42 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[47] LAI:023-042-23 LAI:023-99-23 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[47] LAI:023-042-23 LAI:023-99-23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[48] LAI:023-042-23 LAI:023-42-23 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[48] LAI:023-042-23 LAI:023-42-23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[49] LAI:023-042-23 CGI:023-042-23-5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[49] LAI:023-042-23 CGI:023-042-23-5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[50] LAI:023-042-23 CGI:023-042-42-6 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[50] LAI:023-042-23 CGI:023-042-42-6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[51] LAI:023-042-23 CGI:023-99-23-5 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[51] LAI:023-042-23 CGI:023-99-23-5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[52] CGI:023-042-23-5 LAC:23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[52] CGI:023-042-23-5 LAC:23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[53] CGI:023-042-23-5 LAC:42 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[53] CGI:023-042-23-5 LAC:42 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[54] CGI:023-042-23-5 CI:5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[54] CGI:023-042-23-5 CI:5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[55] CGI:023-042-23-5 CI:6 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[55] CGI:023-042-23-5 CI:6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[56] CGI:023-042-23-5 LAC-CI:23-5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[56] CGI:023-042-23-5 LAC-CI:23-5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[57] CGI:023-042-23-5 LAC-CI:42-6 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[57] CGI:023-042-23-5 LAC-CI:42-6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[58] CGI:023-042-23-5 LAI:023-042-23 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[58] CGI:023-042-23-5 LAI:023-042-23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[59] CGI:023-042-23-5 LAI:023-042-42 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[59] CGI:023-042-23-5 LAI:023-042-42 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[60] CGI:023-042-23-5 LAI:023-99-23 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[60] CGI:023-042-23-5 LAI:023-99-23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[61] CGI:023-042-23-5 LAI:023-42-23 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[61] CGI:023-042-23-5 LAI:023-42-23 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[62] CGI:023-042-23-5 CGI:023-042-23-5 MATCH</span><br><span style="color: hsl(120, 100%, 40%);">+[62] CGI:023-042-23-5 CGI:023-042-23-5 MATCH exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[63] CGI:023-042-23-5 CGI:023-042-42-6 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[63] CGI:023-042-23-5 CGI:023-042-42-6 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+[64] CGI:023-042-23-5 CGI:023-99-23-5 don't match</span><br><span style="color: hsl(120, 100%, 40%);">+[64] CGI:023-042-23-5 CGI:023-99-23-5 don't match exactly</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+test_cell_id_list_matching(test match)</span><br><span style="color: hsl(120, 100%, 40%);">+LAC:23 and LAC[2]:{42, 23}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+LAC:23 and CI[2]:{5, 6}: MATCH at [0]</span><br><span style="color: hsl(120, 100%, 40%);">+LAC:23 and LAC-CI[2]:{42-6, 23-5}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+LAC:23 and LAI[4]:{023-042-42, 023-042-23, 023-99-23, 023-42-23}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+LAC:23 and CGI[3]:{023-042-42-6, 023-042-23-5, 023-99-23-5}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+CI:5 and LAC[2]:{23, 42}: MATCH at [0]</span><br><span style="color: hsl(120, 100%, 40%);">+CI:5 and CI[2]:{6, 5}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+CI:5 and LAC-CI[2]:{42-6, 23-5}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+CI:5 and LAI[4]:{023-042-23, 023-042-42, 023-99-23, 023-42-23}: MATCH at [0]</span><br><span style="color: hsl(120, 100%, 40%);">+CI:5 and CGI[3]:{023-042-42-6, 023-042-23-5, 023-99-23-5}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+LAC-CI:23-5 and LAC[2]:{42, 23}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+LAC-CI:23-5 and CI[2]:{6, 5}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+LAC-CI:23-5 and LAC-CI[2]:{42-6, 23-5}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+LAC-CI:23-5 and LAI[4]:{023-042-42, 023-042-23, 023-99-23, 023-42-23}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+LAC-CI:23-5 and CGI[3]:{023-042-42-6, 023-042-23-5, 023-99-23-5}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+LAI:023-042-23 and LAC[2]:{42, 23}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+LAI:023-042-23 and CI[2]:{5, 6}: MATCH at [0]</span><br><span style="color: hsl(120, 100%, 40%);">+LAI:023-042-23 and LAC-CI[2]:{42-6, 23-5}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+LAI:023-042-23 and LAI[4]:{023-042-42, 023-99-23, 023-42-23, 023-042-23}: MATCH at [3]</span><br><span style="color: hsl(120, 100%, 40%);">+LAI:023-042-23 and CGI[3]:{023-042-42-6, 023-99-23-5, 023-042-23-5}: MATCH at [2]</span><br><span style="color: hsl(120, 100%, 40%);">+CGI:023-042-23-5 and LAC[2]:{42, 23}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+CGI:023-042-23-5 and CI[2]:{6, 5}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+CGI:023-042-23-5 and LAC-CI[2]:{42-6, 23-5}: MATCH at [1]</span><br><span style="color: hsl(120, 100%, 40%);">+CGI:023-042-23-5 and LAI[4]:{023-042-42, 023-99-23, 023-42-23, 023-042-23}: MATCH at [3]</span><br><span style="color: hsl(120, 100%, 40%);">+CGI:023-042-23-5 and CGI[3]:{023-042-42-6, 023-99-23-5, 023-042-23-5}: MATCH at [2]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+test_cell_id_list_matching(test mismatch)</span><br><span style="color: hsl(120, 100%, 40%);">+LAC:23 and LAC[1]:{42}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+LAC:23 vs. CI: No match_id entries to test mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+LAC:23 and LAC-CI[1]:{42-6}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+LAC:23 and LAI[1]:{023-042-42}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+LAC:23 and CGI[1]:{023-042-42-6}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+CI:5 vs. LAC: No match_id entries to test mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+CI:5 and CI[1]:{6}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+CI:5 and LAC-CI[1]:{42-6}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+CI:5 vs. LAI: No match_id entries to test mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+CI:5 and CGI[1]:{023-042-42-6}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+LAC-CI:23-5 and LAC[1]:{42}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+LAC-CI:23-5 and CI[1]:{6}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+LAC-CI:23-5 and LAC-CI[1]:{42-6}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+LAC-CI:23-5 and LAI[1]:{023-042-42}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+LAC-CI:23-5 and CGI[1]:{023-042-42-6}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+LAI:023-042-23 and LAC[1]:{42}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+LAI:023-042-23 vs. CI: No match_id entries to test mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+LAI:023-042-23 and LAC-CI[1]:{42-6}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+LAI:023-042-23 and LAI[3]:{023-042-42, 023-99-23, 023-42-23}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+LAI:023-042-23 and CGI[2]:{023-042-42-6, 023-99-23-5}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+CGI:023-042-23-5 and LAC[1]:{42}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+CGI:023-042-23-5 and CI[1]:{6}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+CGI:023-042-23-5 and LAC-CI[1]:{42-6}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+CGI:023-042-23-5 and LAI[3]:{023-042-42, 023-99-23, 023-42-23}: mismatch</span><br><span style="color: hsl(120, 100%, 40%);">+CGI:023-042-23-5 and CGI[2]:{023-042-42-6, 023-99-23-5}: mismatch</span><br><span> Done</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/11504">change 11504</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/11504"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I5535f0d149c2173294538df75764dd181b023312 </div>
<div style="display:none"> Gerrit-Change-Number: 11504 </div>
<div style="display:none"> Gerrit-PatchSet: 12 </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: Max <msuraev@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Vadim Yanitskiy <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-CC: Pau Espin Pedrol <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-CC: Stefan Sperling <stsp@stsp.name> </div>