diff options
Diffstat (limited to 'src/gsm/gsm23003.c')
-rw-r--r-- | src/gsm/gsm23003.c | 195 |
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) |