aboutsummaryrefslogtreecommitdiffstats
path: root/src/gsm/gsm23003.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gsm/gsm23003.c')
-rw-r--r--src/gsm/gsm23003.c195
1 files changed, 175 insertions, 20 deletions
diff --git a/src/gsm/gsm23003.c b/src/gsm/gsm23003.c
index e20afcbc..1eed41fe 100644
--- a/src/gsm/gsm23003.c
+++ b/src/gsm/gsm23003.c
@@ -17,10 +17,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <ctype.h>
@@ -247,6 +243,43 @@ char *osmo_lai_name_c(const void *ctx, const struct osmo_location_area_id *lai)
return osmo_lai_name_buf(buf, 32, lai);
}
+/*! Return MCC-MNC-LAC-RAC as string, in caller-provided output buffer.
+ * \param[out] buf caller-allocated output buffer
+ * \param[in] buf_len size of buf in bytes
+ * \param[in] rai RAI to encode, the rac member is ignored.
+ * \returns buf
+ */
+char *osmo_rai_name2_buf(char *buf, size_t buf_len, const struct osmo_routing_area_id *rai)
+{
+ char plmn[16];
+ snprintf(buf, buf_len, "%s-%u-%u", osmo_plmn_name_buf(plmn, sizeof(plmn),
+ &rai->lac.plmn), rai->lac.lac, rai->rac);
+ return buf;
+}
+
+/*! Return MCC-MNC-LAC-RAC as string, in a static buffer.
+ * \param[in] rai RAI to encode, the rac member is ignored.
+ * \returns Static string buffer.
+ */
+const char *osmo_rai_name2(const struct osmo_routing_area_id *rai)
+{
+ static __thread char buf[32];
+ return osmo_rai_name2_buf(buf, sizeof(buf), rai);
+}
+
+/*! Return MCC-MNC-LAC-RAC as string, in a talloc-allocated output buffer.
+ * \param[in] ctx talloc context from which to allocate output buffer
+ * \param[in] rai RAI to encode, the rac member is ignored.
+ * \returns string representation of lai in dynamically allocated buffer.
+ */
+char *osmo_rai_name2_c(const void *ctx, const struct osmo_routing_area_id *rai)
+{
+ char *buf = talloc_size(ctx, 32);
+ if (!buf)
+ return NULL;
+ return osmo_rai_name2_buf(buf, 32, rai);
+}
+
/*! Return MCC-MNC-LAC-CI as string, in caller-provided output buffer.
* \param[out] buf caller-allocated output buffer
* \param[in] buf_len size of buf in bytes
@@ -291,6 +324,95 @@ char *osmo_cgi_name_c(const void *ctx, const struct osmo_cell_global_id *cgi)
return osmo_cgi_name_buf(buf, 32, cgi);
}
+/*! Return MCC-MNC-LAC-RAC-CI as string, in caller-provided output buffer.
+ * \param[out] buf caller-allocated output buffer
+ * \param[in] buf_len size of buf in bytes
+ * \param[in] cgi_ps CGI-PS to encode.
+ * \returns buf
+ */
+char *osmo_cgi_ps_name_buf(char *buf, size_t buf_len, const struct osmo_cell_global_id_ps *cgi_ps)
+{
+ snprintf(buf, buf_len, "%s-%u", osmo_rai_name2(&cgi_ps->rai), cgi_ps->cell_identity);
+ return buf;
+}
+
+/*! Return MCC-MNC-LAC-RAC-CI as string, in a static buffer.
+ * \param[in] cgi_ps CGI-PS to encode.
+ * \returns Static string buffer.
+ */
+const char *osmo_cgi_ps_name(const struct osmo_cell_global_id_ps *cgi_ps)
+{
+ static __thread char buf[32];
+ return osmo_cgi_ps_name_buf(buf, sizeof(buf), cgi_ps);
+}
+
+/*! Same as osmo_cgi_ps_name(), but uses a different static buffer.
+ * Useful for printing two distinct CGI-PSs in the same printf format.
+ * \param[in] cgi CGI-PS to encode.
+ * \returns Static string buffer.
+ */
+const char *osmo_cgi_ps_name2(const struct osmo_cell_global_id_ps *cgi_ps)
+{
+ static __thread char buf[32];
+ return osmo_cgi_ps_name_buf(buf, sizeof(buf), cgi_ps);
+}
+
+/*! Return MCC-MNC-LAC-RAC-CI as string, in a talloc-allocated output buffer.
+ * \param[in] ctx talloc context from which to allocate output buffer
+ * \param[in] cgi_ps CGI-PS to encode.
+ * \returns string representation of CGI in dynamically-allocated buffer.
+ */
+char *osmo_cgi_ps_name_c(const void *ctx, const struct osmo_cell_global_id_ps *cgi_ps)
+{
+ char *buf = talloc_size(ctx, 32);
+ return osmo_cgi_ps_name_buf(buf, 32, cgi_ps);
+}
+
+/*! Return MCC-MNC-LAC-SAC as string, in caller-provided output buffer.
+ * \param[out] buf caller-allocated output buffer
+ * \param[in] buf_len size of buf in bytes
+ * \param[in] sai SAI to encode.
+ * \returns buf
+ */
+char *osmo_sai_name_buf(char *buf, size_t buf_len, const struct osmo_service_area_id *sai)
+{
+ snprintf(buf, buf_len, "%s-%u", osmo_lai_name(&sai->lai), sai->sac);
+ return buf;
+}
+
+/*! Return MCC-MNC-LAC-SAC as string, in a static buffer.
+ * \param[in] sai SAI to encode.
+ * \returns Static string buffer.
+ */
+const char *osmo_sai_name(const struct osmo_service_area_id *sai)
+{
+ static __thread char buf[32];
+ return osmo_sai_name_buf(buf, sizeof(buf), sai);
+}
+
+/*! Same as osmo_cgi_name(), but uses a different static buffer.
+ * Useful for printing two distinct CGIs in the same printf format.
+ * \param[in] sai SAI to encode.
+ * \returns Static string buffer.
+ */
+const char *osmo_sai_name2(const struct osmo_service_area_id *sai)
+{
+ static __thread char buf[32];
+ return osmo_sai_name_buf(buf, sizeof(buf), sai);
+}
+
+/*! Return MCC-MNC-LAC-SAC as string, in a talloc-allocated output buffer.
+ * \param[in] ctx talloc context from which to allocate output buffer
+ * \param[in] sai SAI to encode.
+ * \returns string representation of CGI in dynamically-allocated buffer.
+ */
+char *osmo_sai_name_c(const void *ctx, const struct osmo_service_area_id *sai)
+{
+ char *buf = talloc_size(ctx, 32);
+ return osmo_sai_name_buf(buf, 32, sai);
+}
+
+
static void to_bcd(uint8_t *bcd, uint16_t val)
{
bcd[2] = val % 10;
@@ -368,14 +490,12 @@ void osmo_plmn_to_bcd(uint8_t *bcd_dst, const struct osmo_plmn_id *plmn)
}
}
-/* Convert given 3-byte BCD buffer to integers and write results to *mcc and
- * *mnc. The first three BCD digits result in the MCC and the remaining ones in
- * the MNC. Return mnc_3_digits as false if the MNC's most significant digit is encoded as 0xF, true
- * otherwise; i.e. true if MNC > 99 or if it is represented with leading zeros instead of 0xF.
+/* Convert given 3-byte BCD buffer to integers and write results to plmn->mcc and plmn->mnc. The first three BCD digits
+ * result in the MCC and the remaining ones in the MNC. Set plmn->mnc_3_digits as false if the MNC's most significant
+ * digit is encoded as 0xF, true otherwise; i.e. true if MNC > 99 or if it is represented with leading zeros instead of
+ * 0xF.
* \param[in] bcd_src 3-byte BCD buffer containing MCC+MNC representations.
- * \param[out] mcc MCC result buffer, or NULL.
- * \param[out] mnc MNC result buffer, or NULL.
- * \param[out] mnc_3_digits Result buffer for 3-digit flag, or NULL.
+ * \param[out] plmn user provided memory to store the result.
*/
void osmo_plmn_from_bcd(const uint8_t *bcd_src, struct osmo_plmn_id *plmn)
{
@@ -406,22 +526,23 @@ void osmo_plmn_from_bcd(const uint8_t *bcd_src, struct osmo_plmn_id *plmn)
*/
int osmo_mnc_from_str(const char *mnc_str, uint16_t *mnc, bool *mnc_3_digits)
{
- long int _mnc = 0;
+ int _mnc = 0;
bool _mnc_3_digits = false;
- char *endptr;
int rc = 0;
if (!mnc_str || !isdigit((unsigned char)mnc_str[0]) || strlen(mnc_str) > 3)
return -EINVAL;
- errno = 0;
- _mnc = strtol(mnc_str, &endptr, 10);
- if (errno)
- rc = -errno;
- else if (*endptr)
+ rc = osmo_str_to_int(&_mnc, mnc_str, 10, 0, 999);
+ /* Heed the API definition to return -EINVAL in case of surplus chars */
+ if (rc == -E2BIG)
return -EINVAL;
- if (_mnc < 0 || _mnc > 999)
- return -ERANGE;
+ /* Heed the API definition to always return negative errno */
+ if (rc > 0)
+ return -rc;
+ if (rc < 0)
+ return rc;
+
_mnc_3_digits = strlen(mnc_str) > 2;
if (mnc)
@@ -484,6 +605,23 @@ int osmo_lai_cmp(const struct osmo_location_area_id *a, const struct osmo_locati
return 0;
}
+/* Compare two RAI.
+ * The order of comparison is MCC, MNC, LAC, RAC. See also osmo_lai_cmp().
+ * \param a[in] "Left" side RAI.
+ * \param b[in] "Right" side RAI.
+ * \returns 0 if the RAI are equal, -1 if a < b, 1 if a > b. */
+int osmo_rai_cmp(const struct osmo_routing_area_id *a, const struct osmo_routing_area_id *b)
+{
+ int rc = osmo_lai_cmp(&a->lac, &b->lac);
+ if (rc)
+ return rc;
+ if (a->rac < b->rac)
+ return -1;
+ if (a->rac > b->rac)
+ return 1;
+ return 0;
+}
+
/* Compare two CGI.
* The order of comparison is MCC, MNC, LAC, CI. See also osmo_lai_cmp().
* \param a[in] "Left" side CGI.
@@ -501,6 +639,23 @@ int osmo_cgi_cmp(const struct osmo_cell_global_id *a, const struct osmo_cell_glo
return 0;
}
+/* Compare two CGI-PS.
+ * The order of comparison is MCC, MNC, LAC, RAC, CI. See also osmo_rai_cmp().
+ * \param a[in] "Left" side CGI-PS.
+ * \param b[in] "Right" side CGI-PS.
+ * \returns 0 if the CGI are equal, -1 if a < b, 1 if a > b. */
+int osmo_cgi_ps_cmp(const struct osmo_cell_global_id_ps *a, const struct osmo_cell_global_id_ps *b)
+{
+ int rc = osmo_rai_cmp(&a->rai, &b->rai);
+ if (rc)
+ return rc;
+ if (a->cell_identity < b->cell_identity)
+ return -1;
+ if (a->cell_identity > b->cell_identity)
+ return 1;
+ return 0;
+}
+
/*! Generate TS 23.003 Section 19.2 Home Network Realm/Domain (text form)
* \param out[out] caller-provided output buffer, at least 33 bytes long
* \param plmn[in] Osmocom representation of PLMN ID (MCC + MNC)