diff options
Diffstat (limited to 'src/gsm/bssmap_le.c')
-rw-r--r-- | src/gsm/bssmap_le.c | 85 |
1 files changed, 73 insertions, 12 deletions
diff --git a/src/gsm/bssmap_le.c b/src/gsm/bssmap_le.c index 79546532..1ee45517 100644 --- a/src/gsm/bssmap_le.c +++ b/src/gsm/bssmap_le.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 <string.h> @@ -184,7 +180,7 @@ int osmo_bssmap_le_ie_dec_location_type(struct bssmap_le_location_type *lt, struct osmo_bssmap_le_err **err, void *err_ctx, const uint8_t *elem, uint8_t len) { - *lt = (struct bssmap_le_location_type){}; + memset(lt, 0x00, sizeof(*lt)); if (!elem || len < 1) DEC_ERR(-EINVAL, msgt, iei, LCS_CAUSE_UNSPECIFIED, "zero length"); @@ -265,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: * @@ -301,7 +348,7 @@ int osmo_lcs_cause_dec(struct lcs_cause_ie *lcs_cause, struct osmo_bssmap_le_err **err, void *err_ctx, const uint8_t *data, uint8_t len) { - *lcs_cause = (struct lcs_cause_ie){}; + memset(lcs_cause, 0x00, sizeof(*lcs_cause)); if (!data || len < 1) DEC_ERR(-EINVAL, msgt, iei, LCS_CAUSE_UNSPECIFIED, "zero length"); @@ -476,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) @@ -505,7 +558,7 @@ static int osmo_bssmap_le_dec_perform_loc_req(struct bssmap_le_perform_loc_req * struct osmo_bssmap_le_err **err, void *err_ctx, const struct tlv_parsed *tp) { - *params = (struct bssmap_le_perform_loc_req){}; + memset(params, 0x00, sizeof(*params)); DEC_IE_MANDATORY(msgt, BSSMAP_LE_IEI_LOCATION_TYPE, osmo_bssmap_le_ie_dec_location_type, ¶ms->location_type); @@ -513,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; } @@ -546,7 +606,7 @@ static int osmo_bssmap_le_dec_perform_loc_resp(struct bssmap_le_perform_loc_resp struct osmo_bssmap_le_err **err, void *err_ctx, const struct tlv_parsed *tp) { - *params = (struct bssmap_le_perform_loc_resp){}; + memset(params, 0x00, sizeof(*params)); DEC_IE_OPTIONAL_FLAG(msgt, BSSMAP_LE_IEI_GEO_LOCATION, osmo_bssmap_le_ie_dec_gad, ¶ms->location_estimate, params->location_estimate_present); @@ -570,7 +630,7 @@ static int osmo_bssmap_le_dec_perform_loc_abort(struct lcs_cause_ie *params, struct osmo_bssmap_le_err **err, void *err_ctx, const struct tlv_parsed *tp) { - *params = (struct lcs_cause_ie){}; + memset(params, 0x00, sizeof(*params)); DEC_IE_MANDATORY(msgt, BSSMAP_LE_IEI_LCS_CAUSE, osmo_lcs_cause_dec, params); return 0; @@ -587,7 +647,8 @@ static int osmo_bssmap_le_dec_conn_oriented_info(struct bssmap_le_conn_oriented_ struct osmo_bssmap_le_err **err, void *err_ctx, const struct tlv_parsed *tp) { - *params = (struct bssmap_le_conn_oriented_info){}; + memset(params, 0x00, sizeof(*params)); + DEC_IE_MANDATORY(msgt, BSSMAP_LE_IEI_APDU, osmo_bssmap_le_ie_dec_apdu, ¶ms->apdu); return 0; } @@ -651,7 +712,7 @@ static int osmo_bssmap_le_dec(struct bssmap_le_pdu *pdu, int ies_len; struct tlv_parsed tp; - *pdu = (struct bssmap_le_pdu){}; + memset(pdu, 0x00, sizeof(*pdu)); if (len < 1) DEC_ERR(-EINVAL, -1, -1, LCS_CAUSE_UNSPECIFIED, "zero length"); @@ -738,7 +799,7 @@ int osmo_bssap_le_dec(struct bssap_le_pdu *pdu, struct osmo_bssap_le_err **err, return RC; \ } while(0) - *pdu = (struct bssap_le_pdu){}; + memset(pdu, 0x00, sizeof(*pdu)); h = msgb_l2(msg); if (!h) |