summaryrefslogtreecommitdiffstats
path: root/src/gsm
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2018-04-13 03:30:14 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2018-04-13 05:38:47 +0200
commit250e7f7d30c5d90e39293f67bf7553d2d3d094f6 (patch)
treefe82a5c3a070ac54f22324e036e791d7870c38e6 /src/gsm
parenta78b22ba203d9674bb797623b9c1dd985b523663 (diff)
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
Diffstat (limited to 'src/gsm')
-rw-r--r--src/gsm/gsm0808_utils.c51
-rw-r--r--src/gsm/libosmogsm.map2
2 files changed, 53 insertions, 0 deletions
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;