aboutsummaryrefslogtreecommitdiffstats
path: root/src/gsm/bssmap_le.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gsm/bssmap_le.c')
-rw-r--r--src/gsm/bssmap_le.c85
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, &params->lcs_qos);
+
if (params->apdu_present) {
int rc = osmo_bssmap_le_ie_enc_apdu(msg, &params->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,
&params->location_type);
@@ -513,11 +566,18 @@ static int osmo_bssmap_le_dec_perform_loc_req(struct bssmap_le_perform_loc_req *
&params->cell_id);
DEC_IE_OPTIONAL_FLAG(msgt, BSSMAP_LE_IEI_LCS_CLIENT_TYPE, osmo_bssmap_le_ie_dec_lcs_client_type,
&params->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,
+ &params->lcs_priority, params->lcs_priority_present);
+ DEC_IE_OPTIONAL_FLAG(msgt, BSSMAP_LE_IEI_LCS_QoS, osmo_bssmap_le_ie_dec_lcs_qos,
+ &params->lcs_qos, params->lcs_qos_present);
DEC_IE_OPTIONAL_FLAG(msgt, BSSMAP_LE_IEI_APDU, osmo_bssmap_le_ie_dec_apdu, &params->apdu,
params->apdu_present);
DEC_IE_OPTIONAL(msgt, BSSMAP_LE_IEI_IMSI, osmo_bssmap_le_ie_dec_imsi, &params->imsi);
DEC_IE_OPTIONAL(msgt, BSSMAP_LE_IEI_IMEI, osmo_bssmap_le_ie_dec_imei, &params->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, &params->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, &params->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)