diff --git a/TODO-RELEASE b/TODO-RELEASE index 00720f64f..16d96ecc0 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -16,3 +16,6 @@ libosmogsm gsm0808_cause_class() getter for cause class libosmogsm gsm0808_cause_ext() check for cause extended bit libosmogsm gsm0808_cause_name() use enum as parameter libosmogsm gsm0808_create_cipher_reject() use enum as parameter +libosmogsm osmo_gsup_message extended with SMS related fields +libosmogsm osmo_gsup_sms_{en|de}code_sm_rp_da GSUP SM-RP-DA coding helpers +libosmogsm osmo_gsup_sms_{en|de}code_sm_rp_oa GSUP SM-RP-OA coding helpers diff --git a/include/Makefile.am b/include/Makefile.am index ccf9e1082..86d8d1573 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -94,6 +94,7 @@ nobase_include_HEADERS = \ osmocom/gsm/gsm48_ie.h \ osmocom/gsm/gsm_utils.h \ osmocom/gsm/gsup.h \ + osmocom/gsm/gsup_sms.h \ osmocom/gsm/ipa.h \ osmocom/gsm/lapd_core.h \ osmocom/gsm/lapdm.h \ diff --git a/include/osmocom/gsm/gsup.h b/include/osmocom/gsm/gsup.h index cd6fd31f0..192b877b1 100644 --- a/include/osmocom/gsm/gsup.h +++ b/include/osmocom/gsm/gsup.h @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -88,6 +89,14 @@ enum osmo_gsup_iei { /*! Supplementary Services payload */ OSMO_GSUP_SS_INFO_IE = 0x35, + + /* SM related IEs (see 3GPP TS 29.002, section 7.6.8) */ + OSMO_GSUP_SM_RP_MR_IE = 0x40, + OSMO_GSUP_SM_RP_DA_IE = 0x41, + OSMO_GSUP_SM_RP_OA_IE = 0x42, + OSMO_GSUP_SM_RP_UI_IE = 0x43, + OSMO_GSUP_SM_RP_CAUSE_IE = 0x44, + OSMO_GSUP_SM_RP_MMS_IE = 0x45, }; /*! GSUP message type */ @@ -121,6 +130,14 @@ enum osmo_gsup_message_type { OSMO_GSUP_MSGT_PROC_SS_REQUEST = 0b00100000, OSMO_GSUP_MSGT_PROC_SS_ERROR = 0b00100001, OSMO_GSUP_MSGT_PROC_SS_RESULT = 0b00100010, + + OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST = 0b00100100, + OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR = 0b00100101, + OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT = 0b00100110, + + OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST = 0b00101000, + OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR = 0b00101001, + OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT = 0b00101010, }; #define OSMO_GSUP_IS_MSGT_REQUEST(msgt) (((msgt) & 0b00000011) == 0b00) @@ -213,6 +230,26 @@ struct osmo_gsup_message { /*! ASN.1 encoded MAP payload for Supplementary Services */ uint8_t *ss_info; size_t ss_info_len; + + /*! SM-RP-MR (see 3GPP TS 29.002, 7.6.1.1), Message Reference. + * Please note that there is no SM-RP-MR in TCAP/MAP! SM-RP-MR + * is usually mapped to TCAP's InvokeID, but we don't need it. */ + const uint8_t *sm_rp_mr; + /*! SM-RP-DA (see 3GPP TS 29.002, 7.6.8.1), Destination Address */ + enum osmo_gsup_sms_sm_rp_oda_t sm_rp_da_type; + size_t sm_rp_da_len; + const uint8_t *sm_rp_da; + /*! SM-RP-OA (see 3GPP TS 29.002, 7.6.8.2), Originating Address */ + enum osmo_gsup_sms_sm_rp_oda_t sm_rp_oa_type; + size_t sm_rp_oa_len; + const uint8_t *sm_rp_oa; + /*! SM-RP-UI (see 3GPP TS 29.002, 7.6.8.4), SMS TPDU */ + const uint8_t *sm_rp_ui; + size_t sm_rp_ui_len; + /*! SM-RP-Cause value (1 oct.) as per GSM TS 04.11, section 8.2.5.4 */ + const uint8_t *sm_rp_cause; + /*! SM-RP-MMS (More Messages to Send), section 7.6.8.7 */ + const uint8_t *sm_rp_mms; }; int osmo_gsup_decode(const uint8_t *data, size_t data_len, diff --git a/include/osmocom/gsm/gsup_sms.h b/include/osmocom/gsm/gsup_sms.h new file mode 100644 index 000000000..521412d62 --- /dev/null +++ b/include/osmocom/gsm/gsup_sms.h @@ -0,0 +1,38 @@ +#pragma once + +/*! \addtogroup gsup + * @{ + * + * This header defines SMS (Short Message Service) extensions for + * Osmocom GSUP (Generic Subscriber Update Protocol). The scope of + * this module is defined by 3GPP TS 29.002, section 12. + * + * \file gsup_sms.h + * SMS (Short Message Service) extensions for Osmocom GSUP. */ + +#include + +/*! Possible identity types for SM-RP-{OA|DA} */ +enum osmo_gsup_sms_sm_rp_oda_t { + OSMO_GSUP_SMS_SM_RP_ODA_NONE = 0x00, + OSMO_GSUP_SMS_SM_RP_ODA_IMSI = 0x01, + OSMO_GSUP_SMS_SM_RP_ODA_MSISDN = 0x02, + OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR = 0x03, + /*! Special value for noSM-RP-DA and noSM-RP-OA */ + OSMO_GSUP_SMS_SM_RP_ODA_NULL = 0xff, +}; + +struct osmo_gsup_message; +struct msgb; + +int osmo_gsup_sms_encode_sm_rp_da(struct msgb *msg, + const struct osmo_gsup_message *gsup_msg); +int osmo_gsup_sms_decode_sm_rp_da(struct osmo_gsup_message *gsup_msg, + uint8_t *data, size_t data_len); + +int osmo_gsup_sms_encode_sm_rp_oa(struct msgb *msg, + const struct osmo_gsup_message *gsup_msg); +int osmo_gsup_sms_decode_sm_rp_oa(struct osmo_gsup_message *gsup_msg, + uint8_t *data, size_t data_len); + +/*! @} */ diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index ccb38add7..3d2c5606c 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -29,7 +29,7 @@ libgsmint_la_SOURCES = a5.c rxlev_stat.c tlv_parser.c comp128.c comp128v23.c \ auth_milenage.c milenage/aes-encblock.c gea.c \ milenage/aes-internal.c milenage/aes-internal-enc.c \ milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \ - gsup.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c \ + gsup.c gsup_sms.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c \ gsm23003.c mncc.c bts_features.c oap_client.c \ gsm29118.c libgsmint_la_LDFLAGS = -no-undefined diff --git a/src/gsm/gsup.c b/src/gsm/gsup.c index 18b35806f..e43399710 100644 --- a/src/gsm/gsup.c +++ b/src/gsm/gsup.c @@ -67,6 +67,14 @@ const struct value_string osmo_gsup_message_type_names[] = { OSMO_VALUE_STRING(OSMO_GSUP_MSGT_PROC_SS_ERROR), OSMO_VALUE_STRING(OSMO_GSUP_MSGT_PROC_SS_RESULT), + OSMO_VALUE_STRING(OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST), + OSMO_VALUE_STRING(OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR), + OSMO_VALUE_STRING(OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT), + + OSMO_VALUE_STRING(OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST), + OSMO_VALUE_STRING(OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR), + OSMO_VALUE_STRING(OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT), + { 0, NULL } }; @@ -434,6 +442,35 @@ int osmo_gsup_decode(const uint8_t *const_data, size_t data_len, gsup_msg->ss_info_len = value_len; break; + case OSMO_GSUP_SM_RP_MR_IE: + gsup_msg->sm_rp_mr = value; + break; + + case OSMO_GSUP_SM_RP_DA_IE: + rc = osmo_gsup_sms_decode_sm_rp_da(gsup_msg, value, value_len); + if (rc) + return rc; + break; + + case OSMO_GSUP_SM_RP_OA_IE: + rc = osmo_gsup_sms_decode_sm_rp_oa(gsup_msg, value, value_len); + if (rc) + return rc; + break; + + case OSMO_GSUP_SM_RP_UI_IE: + gsup_msg->sm_rp_ui = value; + gsup_msg->sm_rp_ui_len = value_len; + break; + + case OSMO_GSUP_SM_RP_MMS_IE: + gsup_msg->sm_rp_mms = value; + break; + + case OSMO_GSUP_SM_RP_CAUSE_IE: + gsup_msg->sm_rp_cause = value; + break; + default: LOGP(DLGSUP, LOGL_NOTICE, "GSUP IE type %d unknown\n", iei); @@ -529,7 +566,7 @@ static void encode_auth_info(struct msgb *msg, enum osmo_gsup_iei iei, int osmo_gsup_encode(struct msgb *msg, const struct osmo_gsup_message *gsup_msg) { uint8_t u8; - int idx; + int idx, rc; uint8_t bcd_buf[GSM48_MI_SIZE] = {0}; size_t bcd_len; @@ -626,6 +663,42 @@ int osmo_gsup_encode(struct msgb *msg, const struct osmo_gsup_message *gsup_msg) gsup_msg->ss_info_len, gsup_msg->ss_info); } + if (gsup_msg->sm_rp_mr) { + msgb_tlv_put(msg, OSMO_GSUP_SM_RP_MR_IE, + sizeof(*gsup_msg->sm_rp_mr), gsup_msg->sm_rp_mr); + } + + if (gsup_msg->sm_rp_da_type) { + rc = osmo_gsup_sms_encode_sm_rp_da(msg, gsup_msg); + if (rc) { + LOGP(DLGSUP, LOGL_ERROR, "Failed to encode SM-RP-DA IE\n"); + return -EINVAL; + } + } + + if (gsup_msg->sm_rp_oa_type) { + rc = osmo_gsup_sms_encode_sm_rp_oa(msg, gsup_msg); + if (rc) { + LOGP(DLGSUP, LOGL_ERROR, "Failed to encode SM-RP-OA IE\n"); + return -EINVAL; + } + } + + if (gsup_msg->sm_rp_ui) { + msgb_tlv_put(msg, OSMO_GSUP_SM_RP_UI_IE, + gsup_msg->sm_rp_ui_len, gsup_msg->sm_rp_ui); + } + + if (gsup_msg->sm_rp_mms) { + msgb_tlv_put(msg, OSMO_GSUP_SM_RP_MMS_IE, + sizeof(*gsup_msg->sm_rp_mms), gsup_msg->sm_rp_mms); + } + + if (gsup_msg->sm_rp_cause) { + msgb_tlv_put(msg, OSMO_GSUP_SM_RP_CAUSE_IE, + sizeof(*gsup_msg->sm_rp_cause), gsup_msg->sm_rp_cause); + } + return 0; } diff --git a/src/gsm/gsup_sms.c b/src/gsm/gsup_sms.c new file mode 100644 index 000000000..d49cf20af --- /dev/null +++ b/src/gsm/gsup_sms.c @@ -0,0 +1,256 @@ +/* + * (C) 2018 by Vadim Yanitskiy + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * 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, see . + * + */ + +#include +#include +#include + +#include +#include + +#include +#include + +/*! \addtogroup gsup + * @{ + * \file gsup_sms.c + * SMS (Short Message Service) extensions for Osmocom GSUP. + */ + +/*! Encode SM-RP-DA IE (see 7.6.8.1), Destination Address. + * \param[out] msg target message buffer (caller-allocated) + * \param[in] gsup_msg abstract GSUP message structure + * \returns 0 in case of success, negative in case of error + */ +int osmo_gsup_sms_encode_sm_rp_da(struct msgb *msg, + const struct osmo_gsup_message *gsup_msg) +{ + uint8_t *id_enc; + + switch (gsup_msg->sm_rp_da_type) { + case OSMO_GSUP_SMS_SM_RP_ODA_IMSI: + case OSMO_GSUP_SMS_SM_RP_ODA_MSISDN: + case OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR: + /* Prevent NULL-pointer (or empty) dereference */ + if (gsup_msg->sm_rp_da == NULL || gsup_msg->sm_rp_da_len == 0) { + LOGP(DLGSUP, LOGL_ERROR, "Empty?!? SM-RP-DA ID " + "(type=0x%02x)!\n", gsup_msg->sm_rp_da_type); + return -EINVAL; + } + break; + + /* Special case for noSM-RP-DA */ + case OSMO_GSUP_SMS_SM_RP_ODA_NULL: + break; + + case OSMO_GSUP_SMS_SM_RP_ODA_NONE: + default: + LOGP(DLGSUP, LOGL_ERROR, "Unexpected SM-RP-DA ID " + "(type=0x%02x)!\n", gsup_msg->sm_rp_da_type); + return -EINVAL; + } + + /* SM-RP-DA tag | len | ... */ + msgb_tv_put(msg, OSMO_GSUP_SM_RP_DA_IE, gsup_msg->sm_rp_da_len + 1); + msgb_v_put(msg, gsup_msg->sm_rp_da_type); /* ... | id_type */ + + if (gsup_msg->sm_rp_da_type == OSMO_GSUP_SMS_SM_RP_ODA_NULL) + return 0; + + /* ... | id_enc */ + id_enc = msgb_put(msg, gsup_msg->sm_rp_da_len); + memcpy(id_enc, gsup_msg->sm_rp_da, gsup_msg->sm_rp_da_len); + + return 0; +} + +/*! Decode SM-RP-DA IE (see 7.6.8.1), Destination Address. + * \param[out] gsup_msg abstract GSUP message structure + * \param[in] data pointer to the raw IE payload + * \param[in] data_len length of IE pointed by \ref data + * \returns 0 in case of success, negative in case of error + */ +int osmo_gsup_sms_decode_sm_rp_da(struct osmo_gsup_message *gsup_msg, + uint8_t *data, size_t data_len) +{ + uint8_t *ptr = data; + uint8_t id_type; + + /* There should be at least id_type */ + if (data_len < 1) { + LOGP(DLGSUP, LOGL_ERROR, "Corrupted SM-RP-DA IE " + "(missing identity type)\n"); + return -EINVAL; + } + + /* ... | id_type | id_enc (optional) */ + id_type = *ptr++; + data_len--; + + /* Parse ID type */ + switch (id_type) { + case OSMO_GSUP_SMS_SM_RP_ODA_IMSI: + case OSMO_GSUP_SMS_SM_RP_ODA_MSISDN: + case OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR: + if (!data_len) { + /* ID shall not be empty (if its type != NULL) */ + LOGP(DLGSUP, LOGL_ERROR, "Corrupted SM-RP-DA IE " + "(missing encoded identity)\n"); + return -EINVAL; + } + + gsup_msg->sm_rp_da_type = id_type; + gsup_msg->sm_rp_da_len = data_len; + gsup_msg->sm_rp_da = ptr; + break; + + /* Special case for noSM-RP-DA */ + case OSMO_GSUP_SMS_SM_RP_ODA_NULL: + if (data_len != 0) { + LOGP(DLGSUP, LOGL_ERROR, "Unexpected SM-RP-DA ID, " + "(id_len != 0) for noSM-RP-DA!\n"); + return -EINVAL; + } + + gsup_msg->sm_rp_da_type = id_type; + gsup_msg->sm_rp_da_len = 0; + gsup_msg->sm_rp_da = NULL; + break; + + case OSMO_GSUP_SMS_SM_RP_ODA_NONE: + default: + LOGP(DLGSUP, LOGL_ERROR, "Unexpected SM-RP-DA ID " + "(type=0x%02x)!\n", id_type); + return -EINVAL; + } + + return 0; +} + +/*! Encode SM-RP-OA IE (see 7.6.8.2), Originating Address. + * \param[out] msg target message buffer (caller-allocated) + * \param[in] gsup_msg abstract GSUP message structure + * \returns 0 in case of success, negative in case of error + */ +int osmo_gsup_sms_encode_sm_rp_oa(struct msgb *msg, + const struct osmo_gsup_message *gsup_msg) +{ + uint8_t *id_enc; + + switch (gsup_msg->sm_rp_oa_type) { + case OSMO_GSUP_SMS_SM_RP_ODA_MSISDN: + case OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR: + /* Prevent NULL-pointer (or empty) dereference */ + if (gsup_msg->sm_rp_oa == NULL || gsup_msg->sm_rp_oa_len == 0) { + LOGP(DLGSUP, LOGL_ERROR, "Empty?!? SM-RP-OA ID " + "(type=0x%02x)!\n", gsup_msg->sm_rp_oa_type); + return -EINVAL; + } + break; + + /* Special case for noSM-RP-OA */ + case OSMO_GSUP_SMS_SM_RP_ODA_NULL: + break; + + case OSMO_GSUP_SMS_SM_RP_ODA_NONE: + default: + LOGP(DLGSUP, LOGL_ERROR, "Unexpected SM-RP-OA ID " + "(type=0x%02x)!\n", gsup_msg->sm_rp_oa_type); + return -EINVAL; + } + + /* SM-RP-OA tag | len | ... */ + msgb_tv_put(msg, OSMO_GSUP_SM_RP_OA_IE, gsup_msg->sm_rp_oa_len + 1); + msgb_v_put(msg, gsup_msg->sm_rp_oa_type); /* ... | id_type */ + + if (gsup_msg->sm_rp_oa_type == OSMO_GSUP_SMS_SM_RP_ODA_NULL) + return 0; + + /* ... | id_enc */ + id_enc = msgb_put(msg, gsup_msg->sm_rp_oa_len); + memcpy(id_enc, gsup_msg->sm_rp_oa, gsup_msg->sm_rp_oa_len); + + return 0; +} + +/*! Decode SM-RP-OA IE (see 7.6.8.2), Originating Address. + * \param[out] gsup_msg abstract GSUP message structure + * \param[in] data pointer to the raw IE payload + * \param[in] data_len length of IE pointed by \ref data + * \returns 0 in case of success, negative in case of error + */ +int osmo_gsup_sms_decode_sm_rp_oa(struct osmo_gsup_message *gsup_msg, + uint8_t *data, size_t data_len) +{ + uint8_t *ptr = data; + uint8_t id_type; + + /* There should be at least id_type */ + if (data_len < 1) { + LOGP(DLGSUP, LOGL_ERROR, "Corrupted SM-RP-OA IE " + "(missing identity type)\n"); + return -EINVAL; + } + + /* ... | id_type | id_enc (optional) */ + id_type = *ptr++; + data_len--; + + /* Parse ID type */ + switch (id_type) { + case OSMO_GSUP_SMS_SM_RP_ODA_IMSI: + case OSMO_GSUP_SMS_SM_RP_ODA_MSISDN: + case OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR: + if (!data_len) { + /* ID shall not be empty (if its type != NULL) */ + LOGP(DLGSUP, LOGL_ERROR, "Corrupted SM-RP-OA IE " + "(missing encoded identity)\n"); + return -EINVAL; + } + + gsup_msg->sm_rp_oa_type = id_type; + gsup_msg->sm_rp_oa_len = data_len; + gsup_msg->sm_rp_oa = ptr; + break; + + /* Special case for noSM-RP-DA */ + case OSMO_GSUP_SMS_SM_RP_ODA_NULL: + if (data_len != 0) { + LOGP(DLGSUP, LOGL_ERROR, "Unexpected SM-RP-OA ID, " + "(id_len != 0) for noSM-RP-DA!\n"); + return -EINVAL; + } + + gsup_msg->sm_rp_oa_type = id_type; + gsup_msg->sm_rp_oa_len = 0; + gsup_msg->sm_rp_oa = NULL; + break; + + case OSMO_GSUP_SMS_SM_RP_ODA_NONE: + default: + LOGP(DLGSUP, LOGL_ERROR, "Unexpected SM-RP-OA ID " + "(type=0x%02x)!\n", id_type); + return -EINVAL; + } + + return 0; +} + +/*! @} */ diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 959d18279..90c219544 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -523,6 +523,11 @@ osmo_gsup_message_type_names; osmo_gsup_session_state_names; osmo_gsup_get_err_msg_type; +osmo_gsup_sms_encode_sm_rp_da; +osmo_gsup_sms_decode_sm_rp_da; +osmo_gsup_sms_encode_sm_rp_oa; +osmo_gsup_sms_decode_sm_rp_oa; + osmo_oap_encode; osmo_oap_decode; diff --git a/tests/gsup/gsup_test.c b/tests/gsup/gsup_test.c index 9712d77ba..093689333 100644 --- a/tests/gsup/gsup_test.c +++ b/tests/gsup/gsup_test.c @@ -217,6 +217,69 @@ static void test_gsup_messages_dec_enc(void) 0x02, 0x01, 0x47, }; + static const uint8_t send_mo_forward_sm_req[] = { + 0x24, /* OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST */ + TEST_IMSI_IE, + + /* SM related IEs */ + 0x40, 0x01, /* SM-RP-MR (Message Reference) */ + 0xfa, + 0x41, 0x08, /* SM-RP-DA (Destination Address) */ + 0x03, /* SMSC address */ + 0x91, 0x52, 0x75, 0x47, 0x99, 0x09, 0x82, + 0x42, 0x01, /* SM-RP-OA (Originating Address) */ + 0xff, /* Special case: noSM-RP-OA */ + 0x43, 0x04, /* SM-RP-UI (TPDU) */ + 0xde, 0xad, 0xbe, 0xef, + }; + + static const uint8_t send_mt_forward_sm_req[] = { + 0x28, /* OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST */ + TEST_IMSI_IE, + + /* SM related IEs */ + 0x40, 0x01, /* SM-RP-MR (Message Reference) */ + 0xfa, + 0x41, 0x09, /* SM-RP-DA (Destination Address) */ + 0x01, /* IMSI */ + 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5, + 0x42, 0x08, /* SM-RP-OA (Originating Address) */ + 0x03, /* SMSC address */ + 0x91, 0x52, 0x75, 0x47, 0x99, 0x09, 0x82, + 0x43, 0x04, /* SM-RP-UI (TPDU) */ + 0xde, 0xad, 0xbe, 0xef, + 0x45, 0x01, /* SM-RP-MMS (More Messages to Send) */ + 0x01, + }; + + static const uint8_t send_mo_mt_forward_sm_err[] = { + 0x25, /* OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR */ + TEST_IMSI_IE, + + /* Session related IEs */ + 0x30, 0x04, /* Session ID */ + 0xde, 0xad, 0xbe, 0xef, + 0x31, 0x01, /* Session state (END) */ + 0x03, + + /* SM related IEs */ + 0x40, 0x01, /* SM-RP-MR (Message Reference) */ + 0xfa, + 0x44, 0x01, /* SM-RP-Cause value */ + 0xaf, + }; + + static const uint8_t send_mo_mt_forward_sm_rsp[] = { + 0x2a, /* OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT */ + TEST_IMSI_IE, + + /* SM related IEs */ + 0x40, 0x01, /* SM-RP-MR (Message Reference) */ + 0xfa, + 0x43, 0x04, /* SM-RP-UI (TPDU) */ + 0xde, 0xad, 0xbe, 0xef, + }; + static const struct test { char *name; const uint8_t *data; @@ -256,6 +319,14 @@ static void test_gsup_messages_dec_enc(void) send_ussd_req, sizeof(send_ussd_req)}, {"SS/USSD processUnstructuredSS-Request / ReturnResult", send_ussd_res, sizeof(send_ussd_res)}, + {"MO-ForwardSM (MSC -> SMSC) Request", + send_mo_forward_sm_req, sizeof(send_mo_forward_sm_req)}, + {"MT-ForwardSM (MSC -> SMSC) Request", + send_mt_forward_sm_req, sizeof(send_mt_forward_sm_req)}, + {"MO-/MT-ForwardSM Response", + send_mo_mt_forward_sm_rsp, sizeof(send_mo_mt_forward_sm_rsp)}, + {"MO-/MT-ForwardSM Error", + send_mo_mt_forward_sm_err, sizeof(send_mo_mt_forward_sm_err)}, }; printf("Test GSUP message decoding/encoding\n"); @@ -323,7 +394,7 @@ static void test_gsup_messages_dec_enc(void) * FIXME: share the maximal IE value somehow * in order to avoid manual updating of this */ - OSMO_ASSERT(t->data[j+0] <= OSMO_GSUP_SS_INFO_IE); + OSMO_ASSERT(t->data[j+0] <= OSMO_GSUP_SM_RP_MMS_IE); OSMO_ASSERT(t->data[j+1] <= ie_end - j - 2); ie_end = j; diff --git a/tests/gsup/gsup_test.err b/tests/gsup/gsup_test.err index ac71ac24e..4a1357c44 100644 --- a/tests/gsup/gsup_test.err +++ b/tests/gsup/gsup_test.err @@ -49,6 +49,18 @@ generated message: 22 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 03 35 08 a3 06 02 01 01 02 01 47 original message: 22 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 03 35 08 a3 06 02 01 01 02 01 47 IMSI: 123456789012345 + generated message: 24 01 08 21 43 65 87 09 21 43 f5 40 01 fa 41 08 03 91 52 75 47 99 09 82 42 01 ff 43 04 de ad be ef + original message: 24 01 08 21 43 65 87 09 21 43 f5 40 01 fa 41 08 03 91 52 75 47 99 09 82 42 01 ff 43 04 de ad be ef + IMSI: 123456789012345 + generated message: 28 01 08 21 43 65 87 09 21 43 f5 40 01 fa 41 09 01 21 43 65 87 09 21 43 f5 42 08 03 91 52 75 47 99 09 82 43 04 de ad be ef 45 01 01 + original message: 28 01 08 21 43 65 87 09 21 43 f5 40 01 fa 41 09 01 21 43 65 87 09 21 43 f5 42 08 03 91 52 75 47 99 09 82 43 04 de ad be ef 45 01 01 + IMSI: 123456789012345 + generated message: 2a 01 08 21 43 65 87 09 21 43 f5 40 01 fa 43 04 de ad be ef + original message: 2a 01 08 21 43 65 87 09 21 43 f5 40 01 fa 43 04 de ad be ef + IMSI: 123456789012345 + generated message: 25 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 03 40 01 fa 44 01 af + original message: 25 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 03 40 01 fa 44 01 af + IMSI: 123456789012345 message 0: tested 11 truncations, 11 parse failures message 1: tested 14 truncations, 13 parse failures message 2: tested 83 truncations, 81 parse failures @@ -66,21 +78,29 @@ message 14: tested 20 truncations, 18 parse failures message 15: tested 42 truncations, 39 parse failures message 16: tested 30 truncations, 27 parse failures + message 17: tested 33 truncations, 29 parse failures + message 18: tested 44 truncations, 39 parse failures + message 19: tested 20 truncations, 18 parse failures + message 20: tested 26 truncations, 22 parse failures DLGSUP Stopping DLGSUP logging message 0: tested 2816 modifications, 510 parse failures - message 1: tested 3584 modifications, 768 parse failures - message 2: tested 21248 modifications, 2571 parse failures + message 1: tested 3584 modifications, 770 parse failures + message 2: tested 21248 modifications, 2575 parse failures message 3: tested 2816 modifications, 510 parse failures - message 4: tested 3584 modifications, 768 parse failures - message 5: tested 20736 modifications, 4010 parse failures - message 6: tested 3584 modifications, 769 parse failures - message 7: tested 3584 modifications, 768 parse failures + message 4: tested 3584 modifications, 770 parse failures + message 5: tested 20736 modifications, 4022 parse failures + message 6: tested 3584 modifications, 771 parse failures + message 7: tested 3584 modifications, 770 parse failures message 8: tested 2816 modifications, 510 parse failures message 9: tested 2816 modifications, 510 parse failures - message 10: tested 3584 modifications, 768 parse failures - message 11: tested 3328 modifications, 767 parse failures - message 12: tested 54016 modifications, 4622 parse failures + message 10: tested 3584 modifications, 770 parse failures + message 11: tested 3328 modifications, 769 parse failures + message 12: tested 54016 modifications, 4626 parse failures message 13: tested 11520 modifications, 1026 parse failures - message 14: tested 5120 modifications, 1026 parse failures - message 15: tested 10752 modifications, 1256 parse failures - message 16: tested 7680 modifications, 1265 parse failures + message 14: tested 5120 modifications, 1030 parse failures + message 15: tested 10752 modifications, 1262 parse failures + message 16: tested 7680 modifications, 1271 parse failures + message 17: tested 8448 modifications, 2053 parse failures + message 18: tested 11264 modifications, 2307 parse failures + message 19: tested 5120 modifications, 1031 parse failures + message 20: tested 6656 modifications, 1546 parse failures diff --git a/tests/gsup/gsup_test.ok b/tests/gsup/gsup_test.ok index d63dd2d68..7a9455db7 100644 --- a/tests/gsup/gsup_test.ok +++ b/tests/gsup/gsup_test.ok @@ -33,4 +33,12 @@ Test GSUP message decoding/encoding SS/USSD processUnstructuredSS-Request / Invoke OK Testing SS/USSD processUnstructuredSS-Request / ReturnResult SS/USSD processUnstructuredSS-Request / ReturnResult OK + Testing MO-ForwardSM (MSC -> SMSC) Request + MO-ForwardSM (MSC -> SMSC) Request OK + Testing MT-ForwardSM (MSC -> SMSC) Request + MT-ForwardSM (MSC -> SMSC) Request OK + Testing MO-/MT-ForwardSM Response + MO-/MT-ForwardSM Response OK + Testing MO-/MT-ForwardSM Error + MO-/MT-ForwardSM Error OK Done.