mirror of https://gerrit.osmocom.org/libosmocore
improve API for osmo_routing_area_id
Code review for [1] has asked for providing proper API for struct osmo_routing_area_id. For historical reasons, we have struct gprs_ra_id and struct osmo_routing_area_id serving the exact same purpose: represent a decoded 3GPP TS 24.008 § 10.5.5.15 Routing area identification. The "better" one is struct osmo_routing_area_id: it allows using API like osmo_plmn_cmp(), because it is made up of meaningful sub-structs. Implement de/coding using the functions already available for the sub-struct osmo_location_area_id, and simply add the RAC. Add a test in gsm0408_test.c. Note that other utility functions are already available for struct osmo_routing_area_id: osmo_rai_name2(), osmo_rai_cmp(). There is no real need to deprecate struct gprs_ra_id, because there is not really anything wrong with it. It just isn't as well integrated with other utility API as struct osmo_routing_area_id is. Just add comments. [1] osmo-hnbgw.git: cnpool: extract Mobile Identity from RANAP payload https://gerrit.osmocom.org/c/osmo-hnbgw/+/33133 I373d665c9684b607207f68094188eab63209db51 Change-Id: Ic5e0406d9e20b0d4e1372fa30ba11a1e69f5cc94
This commit is contained in:
parent
eb9edbab54
commit
8d42394c89
|
@ -20,7 +20,9 @@
|
|||
* To mark an invalid / unset MNC, this value shall be used. */
|
||||
#define GSM_MCC_MNC_INVALID 0xFFFF
|
||||
|
||||
/* A parsed GPRS routing area */
|
||||
/* A parsed GPRS routing area.
|
||||
* Preferably use struct osmo_routing_area_id, it is better integrated with API like osmo_plmn_cmp().
|
||||
*/
|
||||
struct gprs_ra_id {
|
||||
uint16_t mcc;
|
||||
uint16_t mnc;
|
||||
|
@ -104,6 +106,9 @@ int osmo_mobile_identity_encode_buf(uint8_t *buf, size_t buflen, const struct os
|
|||
int osmo_mobile_identity_encode_msgb(struct msgb *msg, const struct osmo_mobile_identity *mi, bool allow_hex);
|
||||
|
||||
/* Parse Routeing Area Identifier */
|
||||
int osmo_routing_area_id_decode(struct osmo_routing_area_id *dst, const uint8_t *ra_data, size_t ra_data_len);
|
||||
int osmo_routing_area_id_encode_buf(uint8_t *buf, size_t buflen, const struct osmo_routing_area_id *src);
|
||||
int osmo_routing_area_id_encode_msgb(struct msgb *msg, const struct osmo_routing_area_id *src);
|
||||
void gsm48_parse_ra(struct gprs_ra_id *raid, const uint8_t *buf);
|
||||
void gsm48_encode_ra(struct gsm48_ra_id *out, const struct gprs_ra_id *raid);
|
||||
int gsm48_construct_ra(uint8_t *buf, const struct gprs_ra_id *raid) OSMO_DEPRECATED("Use gsm48_encode_ra() instead");
|
||||
|
|
|
@ -1334,7 +1334,64 @@ int gsm48_mi_to_string(char *string, int str_len, const uint8_t *mi, int mi_len)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*! Parse TS 04.08 Routing Area Identifier
|
||||
/*! Decode to struct osmo_routing_area_id from a 3GPP TS 24.008 § 10.5.5.15 Routing area identification.
|
||||
* \param[out] dst Store the decoded result here.
|
||||
* \param[in] ra_data The start of a Routing Area ID in encoded form, to be decoded.
|
||||
* \param[in] ra_data_len Buffer size available to read from at *ra_data.
|
||||
* \return the number of decoded bytes on success, or negative on error (if the input buffer is too small).
|
||||
*/
|
||||
int osmo_routing_area_id_decode(struct osmo_routing_area_id *dst, const uint8_t *ra_data, size_t ra_data_len)
|
||||
{
|
||||
const struct gsm48_ra_id *ra_id;
|
||||
if (ra_data_len < sizeof(*ra_id))
|
||||
return -ENOSPC;
|
||||
|
||||
gsm48_decode_lai2((void *)ra_data, &dst->lac);
|
||||
|
||||
ra_id = (void *)ra_data;
|
||||
dst->rac = ra_id->rac;
|
||||
|
||||
return sizeof(*ra_id);
|
||||
}
|
||||
|
||||
/*! Encode struct osmo_routing_area_id to a 3GPP TS 24.008 § 10.5.5.15 Routing area identification: write to a buffer.
|
||||
* \param[out] buf Return buffer for encoded Mobile Identity.
|
||||
* \param[in] buflen sizeof(buf).
|
||||
* \param[in] src RA to encode.
|
||||
* \return Amount of bytes written to buf, or negative on error.
|
||||
*/
|
||||
int osmo_routing_area_id_encode_buf(uint8_t *buf, size_t buflen, const struct osmo_routing_area_id *src)
|
||||
{
|
||||
struct gsm48_ra_id *ra_id;
|
||||
if (buflen < sizeof(*ra_id))
|
||||
return -ENOSPC;
|
||||
|
||||
gsm48_generate_lai2((void *)buf, &src->lac);
|
||||
|
||||
ra_id = (void *)buf;
|
||||
ra_id->rac = src->rac;
|
||||
|
||||
return sizeof(*ra_id);
|
||||
}
|
||||
|
||||
/*! Encode struct osmo_routing_area_id to a 3GPP TS 24.008 § 10.5.5.15 Routing area identification: append to msgb.
|
||||
* To succeed, the msgb must have tailroom >= sizeof(struct gsm48_ra_id).
|
||||
* \param[out] msg Append to this msgb.
|
||||
* \param[in] src Encode this Routing Area ID.
|
||||
* \return Number of bytes appended to msgb, or negative on error.
|
||||
*/
|
||||
int osmo_routing_area_id_encode_msgb(struct msgb *msg, const struct osmo_routing_area_id *src)
|
||||
{
|
||||
int rc = osmo_routing_area_id_encode_buf(msg->tail, msgb_tailroom(msg), src);
|
||||
if (rc <= 0)
|
||||
return rc;
|
||||
msgb_put(msg, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*! Parse TS 04.08 Routing Area Identifier.
|
||||
* Preferably use osmo_routing_area_id_decode() instead: struct osmo_routing_area_id is better integrated with other API
|
||||
* like osmo_plmn_cmp().
|
||||
* \param[out] Caller-provided memory for decoded RA ID
|
||||
* \param[in] buf Input buffer pointing to RAI IE value */
|
||||
void gsm48_parse_ra(struct gprs_ra_id *raid, const uint8_t *buf)
|
||||
|
|
|
@ -415,6 +415,9 @@ osmo_mobile_identity_decode_from_l3;
|
|||
osmo_mobile_identity_encoded_len;
|
||||
osmo_mobile_identity_encode_buf;
|
||||
osmo_mobile_identity_encode_msgb;
|
||||
osmo_routing_area_id_decode;
|
||||
osmo_routing_area_id_encode_buf;
|
||||
osmo_routing_area_id_encode_msgb;
|
||||
gsm48_mm_att_tlvdef;
|
||||
gsm48_number_of_paging_subchannels;
|
||||
gsm48_parse_ra;
|
||||
|
|
|
@ -341,6 +341,171 @@ static void test_lai_encode_decode(void)
|
|||
}
|
||||
}
|
||||
|
||||
static struct osmo_routing_area_id test_osmo_routing_area_id_items[] = {
|
||||
{
|
||||
.lac = {
|
||||
.plmn = {
|
||||
.mcc = 77,
|
||||
.mnc = 121,
|
||||
},
|
||||
.lac = 666,
|
||||
},
|
||||
.rac = 5,
|
||||
},
|
||||
{
|
||||
.lac = {
|
||||
.plmn = {
|
||||
.mcc = 84,
|
||||
.mnc = 98,
|
||||
},
|
||||
.lac = 11,
|
||||
},
|
||||
.rac = 89,
|
||||
},
|
||||
{
|
||||
.lac = {
|
||||
.plmn = {
|
||||
.mcc = 0,
|
||||
.mnc = 0,
|
||||
.mnc_3_digits = false,
|
||||
/* expecting 000-00, BCD = 00 f0 00 */
|
||||
},
|
||||
.lac = 0,
|
||||
},
|
||||
.rac = 0,
|
||||
},
|
||||
{
|
||||
.lac = {
|
||||
.plmn = {
|
||||
.mcc = 0,
|
||||
.mnc = 0,
|
||||
.mnc_3_digits = true,
|
||||
/* expecting 000-000, BCD = 00 00 00 */
|
||||
},
|
||||
.lac = 0,
|
||||
},
|
||||
.rac = 0,
|
||||
},
|
||||
{
|
||||
.lac = {
|
||||
.plmn = {
|
||||
.mcc = 999,
|
||||
.mnc = 999,
|
||||
},
|
||||
.lac = 65535,
|
||||
},
|
||||
.rac = 255,
|
||||
},
|
||||
{
|
||||
.lac = {
|
||||
.plmn = {
|
||||
.mcc = 1,
|
||||
.mnc = 2,
|
||||
.mnc_3_digits = false,
|
||||
/* expecting 001-02, BCD = 00 f1 20 */
|
||||
},
|
||||
.lac = 23,
|
||||
},
|
||||
.rac = 42,
|
||||
},
|
||||
{
|
||||
.lac = {
|
||||
.plmn = {
|
||||
.mcc = 1,
|
||||
.mnc = 2,
|
||||
.mnc_3_digits = true,
|
||||
/* expecting 001-002, BCD = 00 21 00 */
|
||||
},
|
||||
.lac = 23,
|
||||
},
|
||||
.rac = 42,
|
||||
},
|
||||
{
|
||||
.lac = {
|
||||
.plmn = {
|
||||
.mcc = 12,
|
||||
.mnc = 34,
|
||||
.mnc_3_digits = false,
|
||||
/* expecting 012-34, BCD = 10 f2 43 */
|
||||
},
|
||||
.lac = 56,
|
||||
},
|
||||
.rac = 78,
|
||||
},
|
||||
{
|
||||
.lac = {
|
||||
.plmn = {
|
||||
.mcc = 12,
|
||||
.mnc = 34,
|
||||
.mnc_3_digits = true,
|
||||
/* expecting 012-034, BCD = 10 42 30 */
|
||||
},
|
||||
.lac = 23,
|
||||
},
|
||||
.rac = 42,
|
||||
},
|
||||
{
|
||||
.lac = {
|
||||
.plmn = {
|
||||
.mcc = 123,
|
||||
.mnc = 456,
|
||||
.mnc_3_digits = false,
|
||||
/* expecting 123-456, BCD = 21 63 54 (false flag has no effect) */
|
||||
},
|
||||
.lac = 23,
|
||||
},
|
||||
.rac = 42,
|
||||
},
|
||||
{
|
||||
.lac = {
|
||||
.plmn = {
|
||||
.mcc = 123,
|
||||
.mnc = 456,
|
||||
.mnc_3_digits = true,
|
||||
/* expecting 123-456, BCD = 21 63 54 (same) */
|
||||
},
|
||||
.lac = 23,
|
||||
},
|
||||
.rac = 42,
|
||||
},
|
||||
};
|
||||
|
||||
static inline void dump_osmo_routing_area_id(const struct osmo_routing_area_id *raid)
|
||||
{
|
||||
printf("%s%s", osmo_rai_name2(raid), raid->lac.plmn.mnc_3_digits ? " (3-digit MNC)" : "");
|
||||
}
|
||||
|
||||
static inline void check_osmo_routing_area_id(const struct osmo_routing_area_id *raid)
|
||||
{
|
||||
uint8_t buf[sizeof(struct gsm48_ra_id)] = {};
|
||||
struct osmo_routing_area_id raid0 = {};
|
||||
int rc;
|
||||
|
||||
printf("RA ID: ");
|
||||
dump_osmo_routing_area_id(raid);
|
||||
|
||||
rc = osmo_routing_area_id_encode_buf(buf, sizeof(buf), raid);
|
||||
printf("osmo_routing_area_id_encode_buf(): %src=%d\n", osmo_hexdump(buf, sizeof(buf)), rc);
|
||||
|
||||
rc = osmo_routing_area_id_decode(&raid0, buf, sizeof(buf));
|
||||
printf("osmo_routing_area_id_decode(): ");
|
||||
dump_osmo_routing_area_id(&raid0);
|
||||
printf(" rc=%d\n", rc);
|
||||
|
||||
if (osmo_rai_cmp(raid, &raid0))
|
||||
printf("FAIL\n");
|
||||
else
|
||||
printf("ok\n");
|
||||
}
|
||||
|
||||
static void test_osmo_routing_area_id(void)
|
||||
{
|
||||
int i;
|
||||
printf("==%s()==\n", __func__);
|
||||
for (i = 0; i < ARRAY_SIZE(test_osmo_routing_area_id_items); i++)
|
||||
check_osmo_routing_area_id(&test_osmo_routing_area_id_items[i]);
|
||||
}
|
||||
|
||||
static void dump_cm3(struct gsm48_classmark3 *cm3)
|
||||
{
|
||||
printf("mult_band_supp=%02x\n", cm3->mult_band_supp);
|
||||
|
@ -1792,6 +1957,7 @@ int main(int argc, char **argv)
|
|||
test_bcd_number_encode_decode();
|
||||
test_ra_cap();
|
||||
test_lai_encode_decode();
|
||||
test_osmo_routing_area_id();
|
||||
test_decode_classmark3();
|
||||
|
||||
test_si_range_helpers();
|
||||
|
|
|
@ -386,6 +386,40 @@ RA test...passed
|
|||
Encoded 21 63 54 00 17
|
||||
gsm48_decode_lai2() gives 123-456-23 (3-digit MNC)
|
||||
passed
|
||||
==test_osmo_routing_area_id()==
|
||||
RA ID: 077-121-666-5osmo_routing_area_id_encode_buf(): 70 17 21 02 9a 05 rc=6
|
||||
osmo_routing_area_id_decode(): 077-121-666-5 (3-digit MNC) rc=6
|
||||
ok
|
||||
RA ID: 084-98-11-89osmo_routing_area_id_encode_buf(): 80 f4 89 00 0b 59 rc=6
|
||||
osmo_routing_area_id_decode(): 084-98-11-89 rc=6
|
||||
ok
|
||||
RA ID: 000-00-0-0osmo_routing_area_id_encode_buf(): 00 f0 00 00 00 00 rc=6
|
||||
osmo_routing_area_id_decode(): 000-00-0-0 rc=6
|
||||
ok
|
||||
RA ID: 000-000-0-0 (3-digit MNC)osmo_routing_area_id_encode_buf(): 00 00 00 00 00 00 rc=6
|
||||
osmo_routing_area_id_decode(): 000-000-0-0 (3-digit MNC) rc=6
|
||||
ok
|
||||
RA ID: 999-999-65535-255osmo_routing_area_id_encode_buf(): 99 99 99 ff ff ff rc=6
|
||||
osmo_routing_area_id_decode(): 999-999-65535-255 (3-digit MNC) rc=6
|
||||
ok
|
||||
RA ID: 001-02-23-42osmo_routing_area_id_encode_buf(): 00 f1 20 00 17 2a rc=6
|
||||
osmo_routing_area_id_decode(): 001-02-23-42 rc=6
|
||||
ok
|
||||
RA ID: 001-002-23-42 (3-digit MNC)osmo_routing_area_id_encode_buf(): 00 21 00 00 17 2a rc=6
|
||||
osmo_routing_area_id_decode(): 001-002-23-42 (3-digit MNC) rc=6
|
||||
ok
|
||||
RA ID: 012-34-56-78osmo_routing_area_id_encode_buf(): 10 f2 43 00 38 4e rc=6
|
||||
osmo_routing_area_id_decode(): 012-34-56-78 rc=6
|
||||
ok
|
||||
RA ID: 012-034-23-42 (3-digit MNC)osmo_routing_area_id_encode_buf(): 10 42 30 00 17 2a rc=6
|
||||
osmo_routing_area_id_decode(): 012-034-23-42 (3-digit MNC) rc=6
|
||||
ok
|
||||
RA ID: 123-456-23-42osmo_routing_area_id_encode_buf(): 21 63 54 00 17 2a rc=6
|
||||
osmo_routing_area_id_decode(): 123-456-23-42 (3-digit MNC) rc=6
|
||||
ok
|
||||
RA ID: 123-456-23-42 (3-digit MNC)osmo_routing_area_id_encode_buf(): 21 63 54 00 17 2a rc=6
|
||||
osmo_routing_area_id_decode(): 123-456-23-42 (3-digit MNC) rc=6
|
||||
ok
|
||||
=====cm3_1=====
|
||||
mult_band_supp=06
|
||||
a5_bits=00
|
||||
|
|
Loading…
Reference in New Issue