summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/gsm/gsm0808.h26
-rw-r--r--src/gsm/gsm0808.c45
-rw-r--r--src/gsm/libosmogsm.map1
3 files changed, 60 insertions, 12 deletions
diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h
index 5b05dbc8..93195b50 100644
--- a/include/osmocom/gsm/gsm0808.h
+++ b/include/osmocom/gsm/gsm0808.h
@@ -194,9 +194,29 @@ struct gsm0808_handover_request {
};
struct msgb *gsm0808_create_handover_request(const struct gsm0808_handover_request *params);
-struct msgb *gsm0808_create_handover_request_ack(const uint8_t *l3_info, uint8_t l3_info_len,
- uint8_t chosen_channel, uint8_t chosen_encr_alg,
- uint8_t chosen_speech_version);
+struct gsm0808_handover_request_ack {
+ const uint8_t *l3_info;
+ uint8_t l3_info_len;
+
+ bool chosen_channel_present;
+ uint8_t chosen_channel;
+
+ /*! For A5/N set chosen_encr_alg = N+1, e.g. chosen_encr_alg = 1 means A5/0 (no encryption), 2 means A5/1, 4
+ * means A5/3. Set chosen_encr_alg = 0 to omit the Chosen Encryption Algorithm IE. */
+ uint8_t chosen_encr_alg;
+
+ /* chosen_speech_version == 0 omits the IE */
+ enum gsm0808_permitted_speech chosen_speech_version;
+
+ bool speech_codec_chosen_present;
+ struct gsm0808_speech_codec speech_codec_chosen;
+
+ const struct sockaddr_storage *aoip_transport_layer;
+
+ /* more items are defined in the spec and may be added later */
+ bool more_items; /*!< always set this to false */
+};
+struct msgb *gsm0808_create_handover_request_ack2(const struct gsm0808_handover_request_ack *params);
struct gsm0808_handover_command {
const uint8_t *l3_info;
diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c
index 4406043a..3c77c77a 100644
--- a/src/gsm/gsm0808.c
+++ b/src/gsm/gsm0808.c
@@ -983,9 +983,7 @@ struct msgb *gsm0808_create_handover_request(const struct gsm0808_handover_reque
/*! Create BSSMAP HANDOVER REQUEST ACKNOWLEDGE message, 3GPP TS 48.008 3.2.1.10.
* Sent from the MT BSC back to the MSC when it has allocated an lchan to handover to.
* l3_info is the RR Handover Command that the MO BSC sends to the MS to move over. */
-struct msgb *gsm0808_create_handover_request_ack(const uint8_t *l3_info, uint8_t l3_info_len,
- uint8_t chosen_channel, uint8_t chosen_encr_alg,
- uint8_t chosen_speech_version)
+struct msgb *gsm0808_create_handover_request_ack2(const struct gsm0808_handover_request_ack *params)
{
struct msgb *msg;
@@ -996,13 +994,25 @@ struct msgb *gsm0808_create_handover_request_ack(const uint8_t *l3_info, uint8_t
/* Message Type, 3.2.2.1 */
msgb_v_put(msg, BSS_MAP_MSG_HANDOVER_RQST_ACKNOWLEDGE);
- /* Layer 3 Information, 3.2.2.24 */
- msgb_tlv_put(msg, GSM0808_IE_LAYER_3_INFORMATION, l3_info_len, l3_info);
+ /* Layer 3 Information, 3.2.2.24 -- it is actually mandatory, but rather compose a nonstandard message than
+ * segfault or return NULL without a log message. */
+ if (params->l3_info && params->l3_info_len)
+ msgb_tlv_put(msg, GSM0808_IE_LAYER_3_INFORMATION, params->l3_info_len, params->l3_info);
- msgb_tv_put(msg, GSM0808_IE_CHOSEN_CHANNEL, chosen_channel);
- msgb_tv_put(msg, GSM0808_IE_CHOSEN_ENCR_ALG, chosen_encr_alg);
- if (chosen_speech_version != 0)
- msgb_tv_put(msg, GSM0808_IE_SPEECH_VERSION, chosen_speech_version);
+ if (params->chosen_channel_present)
+ msgb_tv_put(msg, GSM0808_IE_CHOSEN_CHANNEL, params->chosen_channel);
+ if (params->chosen_encr_alg)
+ msgb_tv_put(msg, GSM0808_IE_CHOSEN_ENCR_ALG, params->chosen_encr_alg);
+
+ if (params->chosen_speech_version != 0)
+ msgb_tv_put(msg, GSM0808_IE_SPEECH_VERSION, params->chosen_speech_version);
+
+ if (params->aoip_transport_layer)
+ gsm0808_enc_aoip_trasp_addr(msg, params->aoip_transport_layer);
+
+ /* AoIP: Speech Codec (Chosen) 3.2.2.104 */
+ if (params->speech_codec_chosen_present)
+ gsm0808_enc_speech_codec(msg, &params->speech_codec_chosen);
/* prepend header with final length */
msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
@@ -1010,6 +1020,23 @@ struct msgb *gsm0808_create_handover_request_ack(const uint8_t *l3_info, uint8_t
return msg;
}
+/*! Same as gsm0808_create_handover_request_ack2() but with less parameters.
+ * In particular, this lacks the AoIP Transport Layer address. */
+struct msgb *gsm0808_create_handover_request_ack(const uint8_t *l3_info, uint8_t l3_info_len,
+ uint8_t chosen_channel, uint8_t chosen_encr_alg,
+ uint8_t chosen_speech_version)
+{
+ struct gsm0808_handover_request_ack params = {
+ .l3_info = l3_info,
+ .l3_info_len = l3_info_len,
+ .chosen_channel = chosen_channel,
+ .chosen_encr_alg = chosen_encr_alg,
+ .chosen_speech_version = chosen_speech_version,
+ };
+
+ return gsm0808_create_handover_request_ack2(&params);
+}
+
/*! Create BSSMAP HANDOVER COMMAND message, 3GPP TS 48.008 3.2.1.11.
* Sent from the MSC to the old BSS to transmit the RR Handover Command received from the new BSS. */
struct msgb *gsm0808_create_handover_command(const struct gsm0808_handover_command *params)
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 9c5123e7..adfa096f 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -187,6 +187,7 @@ gsm0808_create_handover_required;
gsm0808_create_handover_required_reject;
gsm0808_create_handover_request;
gsm0808_create_handover_request_ack;
+gsm0808_create_handover_request_ack2;
gsm0808_create_handover_command;
gsm0808_create_handover_detect;
gsm0808_create_handover_succeeded;