From 250e7f7d30c5d90e39293f67bf7553d2d3d094f6 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Fri, 13 Apr 2018 03:30:14 +0200 Subject: add gsm0808_{enc,dec}_cell_id Clarify semantics and micro-optimise for the case of single Cell Identifer IEs. Test in gsm0808_test.c So far we have gsm0808_enc_cell_id_list2(), but there also exist instances of single Cell Identifiers (3GPP TS 48.008 3.2.2.17). It is possible to decode the same using the cell identifier list API, but this forces the caller to also keep a full struct gsm0808_cell_id_list2 with all its 127 entries around. E.g. for handover, there are two Cell Identifiers (Serving and Target); I'd need two full cell id lists for each, and these would be dynamically allocated for each handover operation, whether it uses them or not. Related: OS#2283 (inter-BSC HO, BSC side) Change-Id: I9f9c528965775698ab62ac386af0516192c4b0cc --- src/gsm/gsm0808_utils.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ src/gsm/libosmogsm.map | 2 ++ 2 files changed, 53 insertions(+) (limited to 'src/gsm') diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index 996456e1..73d9362e 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -988,6 +988,57 @@ int gsm0808_cell_id_list_add(struct gsm0808_cell_id_list2 *dst, const struct gsm return added; } +/*! Encode Cell Identifier IE (3GPP TS 48.008 3.2.2.17). + * \param[out] msg Message Buffer to which IE is to be appended + * \param[in] ci Cell ID to be encoded + * \returns number of bytes appended to \a msg */ +uint8_t gsm0808_enc_cell_id(struct msgb *msg, const struct gsm0808_cell_id *ci) +{ + uint8_t rc; + uint8_t *ie_tag; + struct gsm0808_cell_id_list2 cil = { + .id_discr = ci->id_discr, + .id_list = { ci->id }, + .id_list_len = 1, + }; + + OSMO_ASSERT(msg); + OSMO_ASSERT(ci); + + ie_tag = msg->tail; + rc = gsm0808_enc_cell_id_list2(msg, &cil); + + if (rc <= 0) + return rc; + + *ie_tag = GSM0808_IE_CELL_IDENTIFIER; + return rc; +} + +/*! Decode Cell Identifier IE (3GPP TS 48.008 3.2.2.17). + * \param[out] ci Caller-provided memory to store Cell ID. + * \param[in] elem IE value to be decoded. + * \param[in] len Length of \a elem in bytes. + * \returns number of bytes parsed; negative on error */ +int gsm0808_dec_cell_id(struct gsm0808_cell_id *ci, const uint8_t *elem, uint8_t len) +{ + struct gsm0808_cell_id_list2 cil; + int rc; + rc = gsm0808_dec_cell_id_list2(&cil, elem, len); + if (rc < 0) + return rc; + if (cil.id_discr == CELL_IDENT_BSS || cil.id_discr == CELL_IDENT_NO_CELL) { + if (cil.id_list_len != 0) + return -EINVAL; + } else { + if (cil.id_list_len != 1) + return -EINVAL; + } + ci->id_discr = cil.id_discr; + ci->id = cil.id_list[0]; + return rc; +} + /*! Convert the representation of the permitted speech codec identifier * that is used in struct gsm0808_channel_type to the speech codec * representation we use in struct gsm0808_speech_codec. diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 4d009e04..388fcc04 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -177,6 +177,8 @@ gsm0808_enc_cell_id_list2; gsm0808_dec_cell_id_list; gsm0808_dec_cell_id_list2; gsm0808_cell_id_list_add; +gsm0808_enc_cell_id; +gsm0808_dec_cell_id; gsm0808_chan_type_to_speech_codec; gsm0808_speech_codec_from_chan_type; gsm0808_speech_codec_type_names; -- cgit v1.2.3