diff options
| -rw-r--r-- | include/osmocom/gsm/gsm0808.h | 37 | ||||
| -rw-r--r-- | include/osmocom/gsm/protocol/gsm_08_08.h | 22 | ||||
| -rw-r--r-- | src/gsm/gsm0808.c | 70 | ||||
| -rw-r--r-- | src/gsm/libosmogsm.map | 1 | 
4 files changed, 130 insertions, 0 deletions
| diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index 369d713c..4f239e66 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -25,6 +25,7 @@  #include "tlv.h"  #include <osmocom/gsm/protocol/gsm_08_08.h> +#include <osmocom/gsm/gsm0808_utils.h>  #include <osmocom/gsm/gsm23003.h>  struct sockaddr_storage; @@ -80,6 +81,42 @@ struct msgb *gsm0808_create_paging(const char *imsi, const uint32_t *tmsi,  				   const uint8_t *chan_needed)  				   OSMO_DEPRECATED("use gsm0808_create_paging2 instead"); +/*! 3GPP TS 48.008 §3.2.2.5.8 Old BSS to New BSS information */ +struct gsm0808_old_bss_to_new_bss_info { +	bool extra_information_present; +	struct { +		bool prec; +		bool lcs; +		bool ue_prob; +	} extra_information; + +	bool current_channel_type_2_present; +	struct { +		uint8_t mode; +		uint8_t field; +	} current_channel_type_2; + +	/* more items are defined in the spec and may be added later */ +}; + +/*! 3GPP TS 48.008 §3.2.1.9 HANDOVER REQUIRED */ +struct gsm0808_handover_required { +	uint16_t cause; +	struct gsm0808_cell_id_list2 cil; + +	bool current_channel_type_1_present; +	uint8_t current_channel_type_1; + +	bool speech_version_used_present; +	uint8_t speech_version_used; + +	bool old_bss_to_new_bss_info_present; +	struct gsm0808_old_bss_to_new_bss_info old_bss_to_new_bss_info; + +	/* more items are defined in the spec and may be added later */ +}; +struct msgb *gsm0808_create_handover_required(const struct gsm0808_handover_required *params); +  struct msgb *gsm0808_create_dtap(struct msgb *msg, uint8_t link_id);  void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id); diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index b699080c..60b96812 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -295,6 +295,28 @@ enum GSM0808_IE_CODING {  	GSM0808_IE_LAST_USED_EUTRAN_PLMN_ID	= 0x95,  }; +/* 3GPP TS 48.008 3.2.3 Signalling Field Element Coding */ +enum GSM0808_SIGNALLING_FIELD_ELEMENT_CODING { +	GSM0808_FE_IE_EXTRA_INFORMATION = 0x01, /*< 3.2.3.1  */ +	GSM0808_FE_IE_CURRENT_CHANNEL_TYPE_2 = 0x02, /*< 3.2.3.2  */ +	GSM0808_FE_IE_TARGET_CELL_RADIO_INFORMATION = 0x03, /*< 3.2.3.3  */ +	GSM0808_FE_IE_GPRS_SUSPEND_INFORMATION = 0x04, /*< 3.2.3.4  */ +	GSM0808_FE_IE_MULTIRATE_CONFIGURATION_INFORMATION = 0x05, /*< 3.2.3.5  */ +	GSM0808_FE_IE_DUAL_TRANSFER_MODE_INFORMATION = 0x06, /*< 3.2.3.6  */ +	GSM0808_FE_IE_INTER_RAT_HANDOVER_INFO = 0x07, /*< 3.2.3.7  */ +	GSM0808_FE_IE_CDMA2000_CAPABILITY_INFORMATION = 0x08, /*< 3.2.3.8  */ +	GSM0808_FE_IE_DOWNLINK_CELL_LOAD_INFORMATION = 0x09, /*< 3.2.3.9  */ +	GSM0808_FE_IE_UPLINK_CELL_LOAD_INFORMATION = 0x0a, /*< 3.2.3.10 */ +	GSM0808_FE_IE_CELL_LOAD_INFORMATION_GROUP = 0x0b, /*< 3.2.3.11 */ +	GSM0808_FE_IE_CELL_LOAD_INFORMATION = 0x0c, /*< 3.2.3.12 */ +	GSM0808_FE_IE_PS_INDICATION = 0x0d, /*< 3.2.3.13 */ +	GSM0808_FE_IE_DTM_HANDOVER_COMMAND_INDICATION = 0x0e, /*< 3.2.3.14 */ +	GSM0808_FE_IE_D_RNTI = 0xfe, /*< 3.2.3.15 */ +	GSM0808_FE_IE_IRAT_MEASUREMENT_CONFIGURATION = 0x0f, /*< 3.2.3.16 */ +	GSM0808_FE_IE_SOURCE_CELL_ID = 0x10, /*< 3.2.3.17 */ +	GSM0808_FE_IE_IRAT_MEASUREMENT_CONFIGURATION_EXTENDED_E_ARFCNS = 0x11, /*< 3.2.3.18 */ +}; +  /* GSM 08.08 3.2.2.5 Cause */  enum gsm0808_cause {  	GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE			= 0, diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index 47431756..80f5e6ce 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -609,6 +609,76 @@ struct msgb *gsm0808_create_paging(const char *imsi, const uint32_t *tmsi,  	return gsm0808_create_paging2(imsi, tmsi, &cil2, chan_needed);  } +static uint8_t put_old_bss_to_new_bss_information(struct msgb *msg, +						  const struct gsm0808_old_bss_to_new_bss_info *i) +{ +	uint8_t *old_tail; +	uint8_t *tlv_len; + +	msgb_put_u8(msg, GSM0808_IE_OLD_BSS_TO_NEW_BSS_INFORMATION); +	tlv_len = msgb_put(msg, 1); +	old_tail = msg->tail; + +	if (i->extra_information_present) { +		uint8_t val = 0; +		if (i->extra_information.prec) +			val |= 1 << 0; +		if (i->extra_information.lcs) +			val |= 1 << 1; +		if (i->extra_information.ue_prob) +			val |= 1 << 2; +		msgb_tlv_put(msg, GSM0808_FE_IE_EXTRA_INFORMATION, 1, &val); +	} + +	if (i->current_channel_type_2_present) { +		uint8_t val[2] = { +			i->current_channel_type_2.mode, +			i->current_channel_type_2.field, +		}; +		msgb_tlv_put(msg, GSM0808_FE_IE_CURRENT_CHANNEL_TYPE_2, 2, val); +	} + +	*tlv_len = (uint8_t) (msg->tail - old_tail); +	return *tlv_len + 2; +} + +/*! Create BSSMAP HANDOVER REQUIRED message. + * \param[in] params  All information to be encoded. + * \returns newly allocated msgb with BSSMAP REQUIRED message. */ +struct msgb *gsm0808_create_handover_required(const struct gsm0808_handover_required *params) +{ +	struct msgb *msg; + +	msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "BSSMAP-HANDOVER-REQUIRED"); +	if (!msg) +		return NULL; + +	/* Message Type, 3.2.2.1 */ +	msgb_v_put(msg, BSS_MAP_MSG_HANDOVER_REQUIRED); + +	/* Cause, 3.2.2.5 */ +	msgb_tlv_put(msg, GSM0808_IE_CAUSE, params->cause & 0x80? 2 : 1, (const uint8_t*)¶ms->cause); + +	/* Cell Identifier List, 3.2.2.27 */ +	gsm0808_enc_cell_id_list2(msg, ¶ms->cil); + +	/* Current Channel Type 1, 3.2.2.49 */ +	if (params->current_channel_type_1_present) +		msgb_tv_fixed_put(msg, GSM0808_IE_CURRENT_CHANNEL_TYPE_1, 1, ¶ms->current_channel_type_1); + +	/* Speech Version (Used), 3.2.2.51 */ +	if (params->speech_version_used_present) +		msgb_tv_fixed_put(msg, GSM0808_IE_SPEECH_VERSION, 1, ¶ms->speech_version_used); + +	if (params->old_bss_to_new_bss_info_present) +		put_old_bss_to_new_bss_information(msg, ¶ms->old_bss_to_new_bss_info); + +	/* pre-pend the header */ +	msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + +	return msg; +} +  /*! Prepend a DTAP header to given Message Buffer   *  \param[in] msgb Message Buffer   *  \param[in] link_id Link Identifier */ diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 5a574290..58a5bfe5 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -161,6 +161,7 @@ gsm0808_create_layer3_2;  gsm0808_create_reset;  gsm0808_create_reset_ack;  gsm0808_create_sapi_reject; +gsm0808_create_handover_required;  gsm0808_prepend_dtap_header;  gsm0808_enc_aoip_trasp_addr;  gsm0808_dec_aoip_trasp_addr; | 
