diff options
author | Vadim Yanitskiy <vyanitskiy@sysmocom.de> | 2022-03-22 18:17:30 +0300 |
---|---|---|
committer | Vadim Yanitskiy <vyanitskiy@sysmocom.de> | 2022-03-22 18:38:19 +0300 |
commit | be1338789a8d373b927baa9a2b4b4382b1d16780 (patch) | |
tree | 3ab12fa5c4888667fa3d4f1f2bee38ec8262ae45 | |
parent | jenkins: Validate IEs are added to tlv_definition (diff) | |
download | libosmocore-be1338789a8d373b927baa9a2b4b4382b1d16780.tar.xz libosmocore-be1338789a8d373b927baa9a2b4b4382b1d16780.zip |
bssmap_le: support additional IEs in Perform Location Request
Change-Id: I8775a93cf4089b1752d040e43d2cba6b8997f955
Related: SYS#5891
-rw-r--r-- | include/osmocom/gsm/protocol/gsm_49_031.h | 27 | ||||
-rw-r--r-- | src/gsm/bssmap_le.c | 64 | ||||
-rw-r--r-- | tests/bssmap_le/bssmap_le_test.c | 30 | ||||
-rw-r--r-- | tests/bssmap_le/bssmap_le_test.ok | 1 |
4 files changed, 121 insertions, 1 deletions
diff --git a/include/osmocom/gsm/protocol/gsm_49_031.h b/include/osmocom/gsm/protocol/gsm_49_031.h index 06fcbced..8429ccc3 100644 --- a/include/osmocom/gsm/protocol/gsm_49_031.h +++ b/include/osmocom/gsm/protocol/gsm_49_031.h @@ -25,6 +25,8 @@ #include <stdint.h> #include <stdbool.h> + +#include <osmocom/core/endian.h> #include <osmocom/gsm/protocol/gsm_48_071.h> #include <osmocom/gsm/protocol/gsm_23_032.h> #include <osmocom/gsm/gsm0808_utils.h> @@ -58,6 +60,21 @@ struct lcs_cause_ie { uint8_t diag_val; }; +/* 3GPP TS 49.031 10.16 LCS QoS IE */ +struct osmo_bssmap_le_lcs_qos { +#if OSMO_IS_LITTLE_ENDIAN + uint8_t vert:1, vel:1, spare1:6; + uint8_t ha_val:7, ha_ind:1; + uint8_t va_val:7, va_ind:1; + uint8_t spare3:6, rt:2; +#elif OSMO_IS_BIG_ENDIAN + uint8_t spare1:6, vel:1, vert:1; + uint8_t ha_ind:1, ha_val:7; + uint8_t va_ind:1, va_val:7; + uint8_t rt:2, spare3:6; +#endif +} __attribute__ ((packed)); + enum bssap_le_msg_discr { BSSAP_LE_MSG_DISCR_BSSMAP_LE = 0, }; @@ -167,7 +184,15 @@ struct bssmap_le_perform_loc_req { bool apdu_present; struct bsslap_pdu apdu; - bool more_items; /*!< always set this to false */ + bool more_items; /*!< set this to true iff any fields below are used */ + + bool lcs_priority_present; + uint8_t lcs_priority; /*!< see in 3GPP TS 29.002 */ + + bool lcs_qos_present; + struct osmo_bssmap_le_lcs_qos lcs_qos; + + bool more_items2; /*!< always set this to false */ }; struct bssmap_le_perform_loc_resp { diff --git a/src/gsm/bssmap_le.c b/src/gsm/bssmap_le.c index fa0f254e..3e90a43b 100644 --- a/src/gsm/bssmap_le.c +++ b/src/gsm/bssmap_le.c @@ -261,6 +261,57 @@ static int osmo_bssmap_le_ie_dec_lcs_client_type(enum bssmap_le_lcs_client_type } } +/*! Encode full BSSMAP-LE LCS Priority IE, including IEI tag and length. + * \param[inout] msg Message buffer to append to. + * \param[in] priority Value to enconde. + * \returns length of bytes written to the msgb. + */ +static uint8_t osmo_bssmap_le_ie_enc_lcs_priority(struct msgb *msg, uint8_t priority) +{ + OSMO_ASSERT(msg); + msgb_put_u8(msg, BSSMAP_LE_IEI_LCS_PRIORITY); + /* length */ + msgb_put_u8(msg, 1); + msgb_put_u8(msg, priority); + return 3; +} + +static int osmo_bssmap_le_ie_dec_lcs_priority(uint8_t *priority, + enum bssmap_le_msgt msgt, enum bssmap_le_iei iei, + struct osmo_bssmap_le_err **err, void *err_ctx, + const uint8_t *elem, uint8_t len) +{ + if (!elem || len != 1) + DEC_ERR(-EINVAL, msgt, iei, LCS_CAUSE_UNSPECIFIED, "unexpected length"); + + *priority = elem[0]; + return 0; +} + +/*! Encode full BSSMAP-LE LCS QoS IE, including IEI tag and length. + * \param[inout] msg Message buffer to append to. + * \param[in] priority Value to enconde. + * \returns length of bytes written to the msgb. + */ +static uint8_t osmo_bssmap_le_ie_enc_lcs_qos(struct msgb *msg, const struct osmo_bssmap_le_lcs_qos *qos) +{ + OSMO_ASSERT(msg); + msgb_tlv_put(msg, BSSMAP_LE_IEI_LCS_QoS, sizeof(*qos), (const uint8_t *)qos); + return 2 + sizeof(*qos); +} + +static int osmo_bssmap_le_ie_dec_lcs_qos(struct osmo_bssmap_le_lcs_qos *qos, + enum bssmap_le_msgt msgt, enum bssmap_le_iei iei, + struct osmo_bssmap_le_err **err, void *err_ctx, + const uint8_t *elem, uint8_t len) +{ + if (!elem || len != sizeof(*qos)) + DEC_ERR(-EINVAL, msgt, iei, LCS_CAUSE_UNSPECIFIED, "unexpected length"); + + memcpy(qos, elem, len); + return 0; +} + /*! Encode the value part of 3GPP TS 49.031 10.13 LCS Cause, without IEI and len. * Identically used in 3GPP TS 48.008 3.2.2.66. Usage example: * @@ -472,6 +523,12 @@ static int osmo_bssmap_le_enc_perform_loc_req(struct msgb *msg, const struct bss if (params->lcs_client_type_present) osmo_bssmap_le_ie_enc_lcs_client_type(msg, params->lcs_client_type); + if (params->more_items && params->lcs_priority_present) + osmo_bssmap_le_ie_enc_lcs_priority(msg, params->lcs_priority); + + if (params->more_items && params->lcs_qos_present) + osmo_bssmap_le_ie_enc_lcs_qos(msg, ¶ms->lcs_qos); + if (params->apdu_present) { int rc = osmo_bssmap_le_ie_enc_apdu(msg, ¶ms->apdu); if (rc < 0) @@ -509,11 +566,18 @@ static int osmo_bssmap_le_dec_perform_loc_req(struct bssmap_le_perform_loc_req * ¶ms->cell_id); DEC_IE_OPTIONAL_FLAG(msgt, BSSMAP_LE_IEI_LCS_CLIENT_TYPE, osmo_bssmap_le_ie_dec_lcs_client_type, ¶ms->lcs_client_type, params->lcs_client_type_present); + DEC_IE_OPTIONAL_FLAG(msgt, BSSMAP_LE_IEI_LCS_PRIORITY, osmo_bssmap_le_ie_dec_lcs_priority, + ¶ms->lcs_priority, params->lcs_priority_present); + DEC_IE_OPTIONAL_FLAG(msgt, BSSMAP_LE_IEI_LCS_QoS, osmo_bssmap_le_ie_dec_lcs_qos, + ¶ms->lcs_qos, params->lcs_qos_present); DEC_IE_OPTIONAL_FLAG(msgt, BSSMAP_LE_IEI_APDU, osmo_bssmap_le_ie_dec_apdu, ¶ms->apdu, params->apdu_present); DEC_IE_OPTIONAL(msgt, BSSMAP_LE_IEI_IMSI, osmo_bssmap_le_ie_dec_imsi, ¶ms->imsi); DEC_IE_OPTIONAL(msgt, BSSMAP_LE_IEI_IMEI, osmo_bssmap_le_ie_dec_imei, ¶ms->imei); + if (params->lcs_priority_present || params->lcs_qos_present) + params->more_items = true; + return 0; } diff --git a/tests/bssmap_le/bssmap_le_test.c b/tests/bssmap_le/bssmap_le_test.c index f9ebd920..4d132b08 100644 --- a/tests/bssmap_le/bssmap_le_test.c +++ b/tests/bssmap_le/bssmap_le_test.c @@ -118,6 +118,36 @@ struct bssmap_le_pdu bssmap_le_test_pdus[] = { }, }, }, + { + .msg_type = BSSMAP_LE_MSGT_PERFORM_LOC_REQ, + .perform_loc_req = { + .location_type = { + .location_information = BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC, + }, + + .cell_id = { + .id_discr = CELL_IDENT_LAC_AND_CI, + .id.lac_and_ci = { + .lac = 23, + .ci = 42, + }, + }, + + .lcs_client_type_present = true, + .lcs_client_type = BSSMAP_LE_LCS_CTYPE_EMERG_SVC_UNSPECIFIED, + + .more_items = true, + + .lcs_priority_present = true, + .lcs_priority = 0x00, /* highest */ + + .lcs_qos_present = true, + .lcs_qos = { + .ha_ind = 1, + .ha_val = 0x12, + }, + }, + }, }; void test_bssmap_le_enc_dec() diff --git a/tests/bssmap_le/bssmap_le_test.ok b/tests/bssmap_le/bssmap_le_test.ok index a6f0dee3..8cc77039 100644 --- a/tests/bssmap_le/bssmap_le_test.ok +++ b/tests/bssmap_le/bssmap_le_test.ok @@ -9,3 +9,4 @@ [7] CONNECTION ORIENTED INFORMATON: ok (encoded len = 8) [8] CONNECTION ORIENTED INFORMATON: ok (encoded len = 13) [9] CONNECTION ORIENTED INFORMATON: ok (encoded len = 10) +[10] PERFORM LOCATION REQUEST: ok (encoded len = 25) |