mirror of
				https://github.com/open5gs/open5gs.git
				synced 2025-11-03 21:43:25 +00:00 
			
		
		
		
	[CSFB] MT in idle-mode
This commit is contained in:
		@@ -97,7 +97,7 @@ int fqdn_parse(char *dst, char *src, int length)
 | 
			
		||||
            dst[j++] = '.';
 | 
			
		||||
        else
 | 
			
		||||
            dst[j] = 0;
 | 
			
		||||
    } while(i < length);
 | 
			
		||||
    } while (i < length);
 | 
			
		||||
 | 
			
		||||
    return j;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -60,6 +60,7 @@ extern "C" {
 | 
			
		||||
#define MAX_APN_LEN                 100
 | 
			
		||||
#define MAX_PCO_LEN                 251
 | 
			
		||||
#define MAX_FILEPATH_LEN            256
 | 
			
		||||
#define MAX_FQDN_LEN                256
 | 
			
		||||
 | 
			
		||||
#define NEXT_ID(__id, __min, __max) \
 | 
			
		||||
    ((__id) = ((__id) == (__max) ? (__min) : ((__id) + 1)))
 | 
			
		||||
 
 | 
			
		||||
@@ -437,7 +437,6 @@ int emm_handle_tau_request(
 | 
			
		||||
     *   Update KeNB
 | 
			
		||||
     */
 | 
			
		||||
    CLEAR_PAGING_INFO(mme_ue);
 | 
			
		||||
 | 
			
		||||
    if (BEARER_CONTEXT_IS_ACTIVE(mme_ue))
 | 
			
		||||
        ogs_debug("    Bearer-Active");
 | 
			
		||||
    else
 | 
			
		||||
 
 | 
			
		||||
@@ -353,6 +353,19 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
 | 
			
		||||
                ogs_debug("    MO-CSFB-INDICATION[%d]",
 | 
			
		||||
                        mme_ue->nas_eps.service.service_type);
 | 
			
		||||
                sgsap_send_mo_csfb_indication(mme_ue);
 | 
			
		||||
            } else if (mme_ue->nas_eps.service.service_type ==
 | 
			
		||||
                    NAS_SERVICE_TYPE_CS_FALLBACK_TO_UE) {
 | 
			
		||||
                ogs_debug("    SERVICE_REQUEST[%d]",
 | 
			
		||||
                        mme_ue->nas_eps.service.service_type);
 | 
			
		||||
                sgsap_send_service_request(mme_ue);
 | 
			
		||||
            } else {
 | 
			
		||||
                ogs_warn(" Unknown CSFB Service Type[%d]",
 | 
			
		||||
                        mme_ue->nas_eps.service.service_type);
 | 
			
		||||
                rv = nas_send_service_reject(mme_ue,
 | 
			
		||||
                    EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
 | 
			
		||||
                ogs_assert(rv == OGS_OK);
 | 
			
		||||
                OGS_FSM_TRAN(s, &emm_state_exception);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            ogs_debug("    Iniital UE Message");
 | 
			
		||||
            rv = s1ap_send_initial_context_setup_request(mme_ue);
 | 
			
		||||
 
 | 
			
		||||
@@ -413,6 +413,10 @@ struct mme_ue_s {
 | 
			
		||||
#define MAX_NUM_OF_PAGING           2
 | 
			
		||||
    uint32_t        max_paging_retry;
 | 
			
		||||
 | 
			
		||||
#define SGSAP_CS_CALL_SERVICE_INDICATOR     1
 | 
			
		||||
#define SGSAP_SMS_SERVICE_INDICATOR         2
 | 
			
		||||
    uint8_t          service_indicator;
 | 
			
		||||
 | 
			
		||||
    /* UE Radio Capability */
 | 
			
		||||
    OCTET_STRING_t  ueRadioCapability;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -447,11 +447,8 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
 | 
			
		||||
* If the MME receives a Downlink Data Notification after step 2 and 
 | 
			
		||||
* before step 9, the MME shall not send S1 interface paging messages
 | 
			
		||||
*/
 | 
			
		||||
            if (ECM_IDLE(mme_ue)) {
 | 
			
		||||
                s1ap_handle_paging(mme_ue);
 | 
			
		||||
                /* Start T3413 */
 | 
			
		||||
                ogs_timer_start(mme_ue->t3413, mme_self()->t3413_value);
 | 
			
		||||
            }
 | 
			
		||||
            if (ECM_IDLE(mme_ue))
 | 
			
		||||
                s1ap_send_paging(mme_ue, S1AP_CNDomain_ps);
 | 
			
		||||
            break;
 | 
			
		||||
        case GTP_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE:
 | 
			
		||||
            mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
 | 
			
		||||
 
 | 
			
		||||
@@ -1065,7 +1065,8 @@ int s1ap_build_ue_context_release_command(
 | 
			
		||||
    return OGS_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int s1ap_build_paging(ogs_pkbuf_t **s1apbuf, mme_ue_t *mme_ue)
 | 
			
		||||
int s1ap_build_paging(ogs_pkbuf_t **s1apbuf,
 | 
			
		||||
        mme_ue_t *mme_ue, S1AP_CNDomain_t cn_domain)
 | 
			
		||||
{
 | 
			
		||||
    int rv;
 | 
			
		||||
 | 
			
		||||
@@ -1168,7 +1169,7 @@ int s1ap_build_paging(ogs_pkbuf_t **s1apbuf, mme_ue_t *mme_ue)
 | 
			
		||||
    ogs_debug("    MME_CODE[%d] M_TMSI[0x%x]",
 | 
			
		||||
            mme_ue->guti.mme_code, mme_ue->guti.m_tmsi);
 | 
			
		||||
 | 
			
		||||
    *CNDomain = S1AP_CNDomain_ps;
 | 
			
		||||
    *CNDomain = cn_domain;
 | 
			
		||||
 | 
			
		||||
    item = ogs_calloc(1, sizeof(S1AP_TAIItemIEs_t));
 | 
			
		||||
    ASN_SEQUENCE_ADD(&TAIList->list, item);
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,8 @@ int s1ap_build_e_rab_release_command(ogs_pkbuf_t **s1apbuf,
 | 
			
		||||
    mme_bearer_t *bearer, ogs_pkbuf_t *esmbuf, S1AP_Cause_PR group, long cause);
 | 
			
		||||
int s1ap_build_ue_context_release_command(
 | 
			
		||||
    ogs_pkbuf_t **s1apbuf, enb_ue_t *enb_ue, S1AP_Cause_PR group, long cause);
 | 
			
		||||
int s1ap_build_paging(ogs_pkbuf_t **s1apbuf, mme_ue_t *mme_ue);
 | 
			
		||||
int s1ap_build_paging(ogs_pkbuf_t **s1apbuf,
 | 
			
		||||
        mme_ue_t *mme_ue, S1AP_CNDomain_t cn_domain);
 | 
			
		||||
 | 
			
		||||
int s1ap_build_mme_configuration_transfer(
 | 
			
		||||
    ogs_pkbuf_t **s1apbuf, 
 | 
			
		||||
 
 | 
			
		||||
@@ -904,62 +904,6 @@ void s1ap_handle_ue_context_release_complete(
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void s1ap_handle_paging(mme_ue_t *mme_ue)
 | 
			
		||||
{
 | 
			
		||||
    ogs_pkbuf_t *s1apbuf = NULL;
 | 
			
		||||
    ogs_hash_index_t *hi = NULL;
 | 
			
		||||
    mme_enb_t *enb = NULL;
 | 
			
		||||
    int i;
 | 
			
		||||
    int rv;
 | 
			
		||||
 | 
			
		||||
    /* Find enB with matched TAI */
 | 
			
		||||
    for (hi = mme_enb_first(); hi; hi = mme_enb_next(hi)) {
 | 
			
		||||
        enb = mme_enb_this(hi);
 | 
			
		||||
        for (i = 0; i < enb->num_of_supported_ta_list; i++) {
 | 
			
		||||
            if (!memcmp(&enb->supported_ta_list[i],
 | 
			
		||||
                        &mme_ue->tai, sizeof(tai_t))) {
 | 
			
		||||
                if (mme_ue->last_paging_msg) {
 | 
			
		||||
                    s1apbuf = mme_ue->last_paging_msg;
 | 
			
		||||
                    /* Save it for later use */
 | 
			
		||||
                    mme_ue->last_paging_msg = ogs_pkbuf_copy(s1apbuf);
 | 
			
		||||
                } else {
 | 
			
		||||
                    /* Buidl S1Ap Paging message */
 | 
			
		||||
                    rv = s1ap_build_paging(&s1apbuf, mme_ue);
 | 
			
		||||
                    ogs_assert(rv == OGS_OK && s1apbuf);
 | 
			
		||||
 | 
			
		||||
                    /* Save it for later use */
 | 
			
		||||
                    mme_ue->last_paging_msg = ogs_pkbuf_copy(s1apbuf);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Send to enb */
 | 
			
		||||
                ogs_assert(s1ap_send_to_enb(
 | 
			
		||||
                        enb, s1apbuf, S1AP_NON_UE_SIGNALLING) == OGS_OK);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void s1ap_t3413_timeout(void *data)
 | 
			
		||||
{
 | 
			
		||||
    mme_ue_t *mme_ue = data;
 | 
			
		||||
    ogs_assert(mme_ue);
 | 
			
		||||
 | 
			
		||||
    if (mme_ue->max_paging_retry >= MAX_NUM_OF_PAGING) {
 | 
			
		||||
        /* Paging failed */
 | 
			
		||||
        ogs_warn("[EMM] Paging to IMSI[%s] failed. Stop paging",
 | 
			
		||||
                mme_ue->imsi_bcd);
 | 
			
		||||
        if (mme_ue->last_paging_msg) {
 | 
			
		||||
            ogs_pkbuf_free(mme_ue->last_paging_msg);
 | 
			
		||||
            mme_ue->last_paging_msg = NULL;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        mme_ue->max_paging_retry++;
 | 
			
		||||
        s1ap_handle_paging(mme_ue);
 | 
			
		||||
        /* Start T3413 */
 | 
			
		||||
        ogs_timer_start(mme_ue->t3413, mme_self()->t3413_value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void s1ap_handle_path_switch_request(
 | 
			
		||||
        mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -48,9 +48,6 @@ void s1ap_handle_ue_context_release_request(
 | 
			
		||||
void s1ap_handle_ue_context_release_complete(
 | 
			
		||||
        mme_enb_t *enb, s1ap_message_t *message);
 | 
			
		||||
 | 
			
		||||
void s1ap_handle_paging(mme_ue_t *mme_ue);
 | 
			
		||||
void s1ap_t3413_timeout(void *data);
 | 
			
		||||
 | 
			
		||||
void s1ap_handle_path_switch_request(
 | 
			
		||||
        mme_enb_t *enb, s1ap_message_t *message);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -284,6 +284,87 @@ int s1ap_send_ue_context_release_command(
 | 
			
		||||
    return OGS_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void s1ap_send_paging(mme_ue_t *mme_ue, S1AP_CNDomain_t cn_domain)
 | 
			
		||||
{
 | 
			
		||||
    ogs_pkbuf_t *s1apbuf = NULL;
 | 
			
		||||
    ogs_hash_index_t *hi = NULL;
 | 
			
		||||
    mme_enb_t *enb = NULL;
 | 
			
		||||
    int i;
 | 
			
		||||
    int rv;
 | 
			
		||||
 | 
			
		||||
    /* Find enB with matched TAI */
 | 
			
		||||
    for (hi = mme_enb_first(); hi; hi = mme_enb_next(hi)) {
 | 
			
		||||
 | 
			
		||||
        enb = mme_enb_this(hi);
 | 
			
		||||
        for (i = 0; i < enb->num_of_supported_ta_list; i++) {
 | 
			
		||||
 | 
			
		||||
            if (memcmp(&enb->supported_ta_list[i], &mme_ue->tai,
 | 
			
		||||
                        sizeof(tai_t)) == 0) {
 | 
			
		||||
 | 
			
		||||
                /* Build S1AP Paging message */
 | 
			
		||||
                rv = s1ap_build_paging(&s1apbuf, mme_ue, cn_domain);
 | 
			
		||||
                ogs_assert(rv == OGS_OK && s1apbuf);
 | 
			
		||||
 | 
			
		||||
                /* Save it for later use */
 | 
			
		||||
                ogs_assert(mme_ue->last_paging_msg == NULL);
 | 
			
		||||
                mme_ue->last_paging_msg = ogs_pkbuf_copy(s1apbuf);
 | 
			
		||||
 | 
			
		||||
                /* Send to enb */
 | 
			
		||||
                rv = s1ap_send_to_enb(enb, s1apbuf, S1AP_NON_UE_SIGNALLING);
 | 
			
		||||
                ogs_assert(rv == OGS_OK);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Start T3413 */
 | 
			
		||||
    ogs_timer_start(mme_ue->t3413, mme_self()->t3413_value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void s1ap_t3413_timeout(void *data)
 | 
			
		||||
{
 | 
			
		||||
    mme_ue_t *mme_ue = data;
 | 
			
		||||
    ogs_assert(mme_ue);
 | 
			
		||||
 | 
			
		||||
    if (mme_ue->max_paging_retry < MAX_NUM_OF_PAGING) {
 | 
			
		||||
        ogs_pkbuf_t *s1apbuf = NULL;
 | 
			
		||||
        ogs_hash_index_t *hi = NULL;
 | 
			
		||||
        mme_enb_t *enb = NULL;
 | 
			
		||||
        int i;
 | 
			
		||||
        int rv;
 | 
			
		||||
 | 
			
		||||
        /* Find enB with matched TAI */
 | 
			
		||||
        for (hi = mme_enb_first(); hi; hi = mme_enb_next(hi)) {
 | 
			
		||||
 | 
			
		||||
            enb = mme_enb_this(hi);
 | 
			
		||||
            for (i = 0; i < enb->num_of_supported_ta_list; i++) {
 | 
			
		||||
 | 
			
		||||
                if (memcmp(&enb->supported_ta_list[i], &mme_ue->tai,
 | 
			
		||||
                            sizeof(tai_t)) == 0) {
 | 
			
		||||
 | 
			
		||||
                    /* Save it for later use */
 | 
			
		||||
                    ogs_assert(mme_ue->last_paging_msg);
 | 
			
		||||
                    s1apbuf = mme_ue->last_paging_msg;
 | 
			
		||||
                    mme_ue->last_paging_msg = ogs_pkbuf_copy(s1apbuf);
 | 
			
		||||
 | 
			
		||||
                    /* Send to enb */
 | 
			
		||||
                    rv = s1ap_send_to_enb(enb, s1apbuf, S1AP_NON_UE_SIGNALLING);
 | 
			
		||||
                    ogs_assert(rv == OGS_OK);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Start T3413 */
 | 
			
		||||
        ogs_timer_start(mme_ue->t3413, mme_self()->t3413_value);
 | 
			
		||||
 | 
			
		||||
        mme_ue->max_paging_retry++;
 | 
			
		||||
    } else {
 | 
			
		||||
        /* Paging failed */
 | 
			
		||||
        ogs_warn("[EMM] Paging to IMSI[%s] failed. Stop paging",
 | 
			
		||||
                mme_ue->imsi_bcd);
 | 
			
		||||
        CLEAR_PAGING_INFO(mme_ue);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int s1ap_send_mme_configuration_transfer(
 | 
			
		||||
        mme_enb_t *target_enb,
 | 
			
		||||
        S1AP_SONConfigurationTransfer_t *SONConfigurationTransfer)
 | 
			
		||||
 
 | 
			
		||||
@@ -56,6 +56,9 @@ int s1ap_send_ue_context_release_command(
 | 
			
		||||
    enb_ue_t *enb_ue, S1AP_Cause_PR group, long cause,
 | 
			
		||||
    uint8_t action, uint32_t delay);
 | 
			
		||||
 | 
			
		||||
void s1ap_send_paging(mme_ue_t *mme_ue, S1AP_CNDomain_t cn_domain);
 | 
			
		||||
void s1ap_t3413_timeout(void *data);
 | 
			
		||||
 | 
			
		||||
int s1ap_send_mme_configuration_transfer(
 | 
			
		||||
        mme_enb_t *target_enb,
 | 
			
		||||
        S1AP_SONConfigurationTransfer_t *SONConfigurationTransfer);
 | 
			
		||||
 
 | 
			
		||||
@@ -163,11 +163,6 @@ ogs_pkbuf_t *sgsap_build_detach_indication(mme_ue_t *mme_ue)
 | 
			
		||||
    return pkbuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ogs_pkbuf_t *sgsap_build_service_request(mme_ue_t *mme_ue)
 | 
			
		||||
{
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ogs_pkbuf_t *sgsap_build_mo_csfb_indication(mme_ue_t *mme_ue)
 | 
			
		||||
{
 | 
			
		||||
    mme_vlr_t *vlr = NULL;
 | 
			
		||||
@@ -193,6 +188,34 @@ ogs_pkbuf_t *sgsap_build_mo_csfb_indication(mme_ue_t *mme_ue)
 | 
			
		||||
    return pkbuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ogs_pkbuf_t *sgsap_build_service_request(mme_ue_t *mme_ue)
 | 
			
		||||
{
 | 
			
		||||
    mme_vlr_t *vlr = NULL;
 | 
			
		||||
    ogs_tlv_t *root = NULL;
 | 
			
		||||
    ogs_pkbuf_t *pkbuf = NULL;
 | 
			
		||||
 | 
			
		||||
    ogs_assert(mme_ue);
 | 
			
		||||
    vlr = mme_ue->vlr;
 | 
			
		||||
    ogs_assert(vlr);
 | 
			
		||||
 | 
			
		||||
    root = ogs_tlv_add(NULL, SGSAP_IE_IMSI_TYPE, SGSAP_IE_IMSI_LEN, 0,
 | 
			
		||||
            &mme_ue->nas_mobile_identity_imsi);
 | 
			
		||||
 | 
			
		||||
    ogs_tlv_add(root, SGSAP_IE_SERVICE_INDICATOR_TYPE,
 | 
			
		||||
            SGSAP_IE_SERVICE_INDICATOR_LEN, 0, &mme_ue->service_indicator);
 | 
			
		||||
 | 
			
		||||
    pkbuf = ogs_pkbuf_alloc(NULL, MAX_SDU_LEN);
 | 
			
		||||
    ogs_pkbuf_put_u8(pkbuf, SGSAP_SERVICE_REQUEST);
 | 
			
		||||
    ogs_pkbuf_put(pkbuf, MAX_SDU_LEN-1);
 | 
			
		||||
 | 
			
		||||
    ogs_pkbuf_trim(pkbuf, 1+ogs_tlv_render(root,
 | 
			
		||||
            pkbuf->data+1, MAX_SDU_LEN-1, OGS_TLV_MODE_T1_L1));
 | 
			
		||||
 | 
			
		||||
    ogs_tlv_free_all(root);
 | 
			
		||||
 | 
			
		||||
    return pkbuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ogs_pkbuf_t *sgsap_build_reset_ack(mme_vlr_t *vlr)
 | 
			
		||||
{
 | 
			
		||||
    ogs_tlv_t *root = NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,7 @@ ogs_pkbuf_t *sgsap_build_tmsi_reallocation_complete(mme_ue_t *mme_ue);
 | 
			
		||||
ogs_pkbuf_t *sgsap_build_detach_indication(mme_ue_t *mme_ue);
 | 
			
		||||
ogs_pkbuf_t *sgsap_build_service_request(mme_ue_t *mme_ue);
 | 
			
		||||
ogs_pkbuf_t *sgsap_build_mo_csfb_indication(mme_ue_t *mme_ue);
 | 
			
		||||
ogs_pkbuf_t *sgsap_build_service_request(mme_ue_t *mme_ue);
 | 
			
		||||
ogs_pkbuf_t *sgsap_build_reset_ack(mme_vlr_t *vlr);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@
 | 
			
		||||
#include "mme-path.h"
 | 
			
		||||
#include "nas-conv.h"
 | 
			
		||||
#include "nas-path.h"
 | 
			
		||||
#include "s1ap-path.h"
 | 
			
		||||
 | 
			
		||||
void sgsap_handle_location_update_accept(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
 | 
			
		||||
{
 | 
			
		||||
@@ -83,6 +84,10 @@ void sgsap_handle_location_update_accept(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
 | 
			
		||||
    ogs_assert(mme_ue);
 | 
			
		||||
 | 
			
		||||
    ogs_debug("    IMSI[%s]", mme_ue->imsi_bcd);
 | 
			
		||||
    if (lai) {
 | 
			
		||||
        ogs_debug("    LAI[PLMN_ID:%06x,LAC:%d]",
 | 
			
		||||
                    plmn_id_hexdump(&lai->nas_plmn_id), lai->lac);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (nas_mobile_identity_tmsi) {
 | 
			
		||||
        if (nas_mobile_identity_tmsi->type == NAS_MOBILE_IDENTITY_TMSI) {
 | 
			
		||||
@@ -118,6 +123,7 @@ void sgsap_handle_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
 | 
			
		||||
    nas_mobile_identity_imsi_t *nas_mobile_identity_imsi = NULL;
 | 
			
		||||
    int nas_mobile_identity_imsi_len = 0;
 | 
			
		||||
    nas_emm_cause_t emm_cause = 0;
 | 
			
		||||
    nas_lai_t *lai = NULL;
 | 
			
		||||
 | 
			
		||||
    ogs_assert(vlr);
 | 
			
		||||
    ogs_assert(pkbuf);
 | 
			
		||||
@@ -137,6 +143,7 @@ void sgsap_handle_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
 | 
			
		||||
            nas_mobile_identity_imsi_len = iter->length;
 | 
			
		||||
            break;
 | 
			
		||||
        case SGSAP_IE_LAI_TYPE:
 | 
			
		||||
            lai = iter->value;
 | 
			
		||||
            break;
 | 
			
		||||
        case SGSAP_IE_REJECT_CAUSE_TYPE:
 | 
			
		||||
            emm_cause = *((uint8_t*)(iter->value));
 | 
			
		||||
@@ -165,6 +172,10 @@ void sgsap_handle_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
 | 
			
		||||
    ogs_assert(mme_ue);
 | 
			
		||||
 | 
			
		||||
    ogs_debug("    IMSI[%s] CAUSE[%d]", mme_ue->imsi_bcd, emm_cause);
 | 
			
		||||
    if (lai) {
 | 
			
		||||
        ogs_debug("    LAI[PLMN_ID:%06x,LAC:%d]",
 | 
			
		||||
                    plmn_id_hexdump(&lai->nas_plmn_id), lai->lac);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enb_ue = mme_ue->enb_ue;
 | 
			
		||||
    ogs_assert(enb_ue);
 | 
			
		||||
@@ -230,9 +241,85 @@ void sgsap_handle_detach_ack(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
 | 
			
		||||
    ogs_assert(mme_ue);
 | 
			
		||||
 | 
			
		||||
    ogs_debug("    IMSI[%s]", mme_ue->imsi_bcd);
 | 
			
		||||
 | 
			
		||||
    mme_send_delete_session_or_detach(mme_ue);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sgsap_handle_paging_request(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
 | 
			
		||||
{
 | 
			
		||||
    ogs_tlv_t *root = NULL, *iter = NULL;
 | 
			
		||||
    mme_ue_t *mme_ue = NULL;
 | 
			
		||||
 | 
			
		||||
    nas_mobile_identity_imsi_t *nas_mobile_identity_imsi = NULL;
 | 
			
		||||
    int nas_mobile_identity_imsi_len = 0;
 | 
			
		||||
    nas_lai_t *lai = NULL;
 | 
			
		||||
    char vlr_name[SGSAP_IE_VLR_NAME_LEN] = { 0, };
 | 
			
		||||
    uint8_t service_indicator = 0;
 | 
			
		||||
 | 
			
		||||
    ogs_assert(vlr);
 | 
			
		||||
    ogs_assert(pkbuf);
 | 
			
		||||
 | 
			
		||||
    ogs_debug("[SGSAP] PAGING-REQUEST");
 | 
			
		||||
 | 
			
		||||
    ogs_pkbuf_pull(pkbuf, 1);
 | 
			
		||||
 | 
			
		||||
    root = ogs_tlv_parse_block(pkbuf->len, pkbuf->data, OGS_TLV_MODE_T1_L1);
 | 
			
		||||
    ogs_assert(root);
 | 
			
		||||
 | 
			
		||||
    iter = root;
 | 
			
		||||
    while (iter) {
 | 
			
		||||
        switch (iter->type) {
 | 
			
		||||
        case SGSAP_IE_IMSI_TYPE:
 | 
			
		||||
            nas_mobile_identity_imsi = iter->value;
 | 
			
		||||
            nas_mobile_identity_imsi_len = iter->length;
 | 
			
		||||
            break;
 | 
			
		||||
        case SGSAP_IE_VLR_NAME_TYPE:
 | 
			
		||||
            fqdn_parse(vlr_name, iter->value, iter->length);
 | 
			
		||||
            break;
 | 
			
		||||
        case SGSAP_IE_LAI_TYPE:
 | 
			
		||||
            lai = iter->value;
 | 
			
		||||
            break;
 | 
			
		||||
        case SGSAP_IE_SERVICE_INDICATOR_TYPE:
 | 
			
		||||
            service_indicator = *((uint8_t*)(iter->value));
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            ogs_warn("Invalid Type [%d]", iter->type);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        iter = iter->next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ogs_tlv_free_all(root);
 | 
			
		||||
 | 
			
		||||
    ogs_assert(nas_mobile_identity_imsi);
 | 
			
		||||
    ogs_assert(nas_mobile_identity_imsi_len == SGSAP_IE_IMSI_LEN);
 | 
			
		||||
 | 
			
		||||
    if (nas_mobile_identity_imsi->type == NAS_MOBILE_IDENTITY_IMSI) {
 | 
			
		||||
        char imsi_bcd[MAX_IMSI_BCD_LEN+1];
 | 
			
		||||
 | 
			
		||||
        nas_imsi_to_bcd(nas_mobile_identity_imsi,
 | 
			
		||||
                nas_mobile_identity_imsi_len, imsi_bcd);
 | 
			
		||||
        mme_ue = mme_ue_find_by_imsi_bcd(imsi_bcd);
 | 
			
		||||
    } else 
 | 
			
		||||
        ogs_assert_if_reached();
 | 
			
		||||
 | 
			
		||||
    ogs_assert(mme_ue);
 | 
			
		||||
 | 
			
		||||
    ogs_assert(service_indicator);
 | 
			
		||||
    mme_ue->service_indicator = service_indicator;
 | 
			
		||||
 | 
			
		||||
    ogs_debug("    IMSI[%s]", mme_ue->imsi_bcd);
 | 
			
		||||
    ogs_debug("    VLR_NAME[%s]", vlr_name);
 | 
			
		||||
    ogs_debug("    SERVICE_INDICATOR[%d]", mme_ue->service_indicator);
 | 
			
		||||
 | 
			
		||||
    if (lai) {
 | 
			
		||||
        ogs_debug("    LAI[PLMN_ID:%06x,LAC:%d]",
 | 
			
		||||
                    plmn_id_hexdump(&lai->nas_plmn_id), lai->lac);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s1ap_send_paging(mme_ue, S1AP_CNDomain_cs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sgsap_handle_reset_indication(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
 | 
			
		||||
{
 | 
			
		||||
    ogs_debug("[SGSAP] RESET-INDICATION");
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@ extern "C" {
 | 
			
		||||
void sgsap_handle_location_update_accept(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
 | 
			
		||||
void sgsap_handle_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
 | 
			
		||||
void sgsap_handle_detach_ack(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
 | 
			
		||||
void sgsap_handle_paging_request(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
 | 
			
		||||
void sgsap_handle_reset_indication(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 
 | 
			
		||||
@@ -178,6 +178,23 @@ int sgsap_send_mo_csfb_indication(mme_ue_t *mme_ue)
 | 
			
		||||
    return OGS_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sgsap_send_service_request(mme_ue_t *mme_ue)
 | 
			
		||||
{
 | 
			
		||||
    int rv;
 | 
			
		||||
    ogs_pkbuf_t *pkbuf = NULL;
 | 
			
		||||
    ogs_assert(mme_ue);
 | 
			
		||||
 | 
			
		||||
    ogs_debug("[SGSAP] MO-CSFB-INDICATION");
 | 
			
		||||
    ogs_debug("    IMSI[%s]", mme_ue->imsi_bcd);
 | 
			
		||||
    ogs_debug("    SERVICE_INDICATOR[%d]", mme_ue->service_indicator);
 | 
			
		||||
 | 
			
		||||
    pkbuf = sgsap_build_service_request(mme_ue);
 | 
			
		||||
    rv = sgsap_send_to_vlr(mme_ue, pkbuf);
 | 
			
		||||
    ogs_assert(rv == OGS_OK);
 | 
			
		||||
 | 
			
		||||
    return OGS_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sgsap_send_reset_ack(mme_vlr_t *vlr)
 | 
			
		||||
{
 | 
			
		||||
    int rv;
 | 
			
		||||
 
 | 
			
		||||
@@ -46,6 +46,7 @@ int sgsap_send_location_update_request(mme_ue_t *mme_ue);
 | 
			
		||||
int sgsap_send_tmsi_reallocation_complete(mme_ue_t *mme_ue);
 | 
			
		||||
int sgsap_send_detach_indication(mme_ue_t *mme_ue);
 | 
			
		||||
int sgsap_send_mo_csfb_indication(mme_ue_t *mme_ue);
 | 
			
		||||
int sgsap_send_service_request(mme_ue_t *mme_ue);
 | 
			
		||||
int sgsap_send_reset_ack(mme_vlr_t *vlr);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 
 | 
			
		||||
@@ -127,6 +127,9 @@ void sgsap_state_connected(ogs_fsm_t *s, mme_event_t *e)
 | 
			
		||||
        case SGSAP_IMSI_DETACH_ACK:
 | 
			
		||||
            sgsap_handle_detach_ack(vlr, pkbuf);
 | 
			
		||||
            break;
 | 
			
		||||
        case SGSAP_PAGING_REQUEST:
 | 
			
		||||
            sgsap_handle_paging_request(vlr, pkbuf);
 | 
			
		||||
            break;
 | 
			
		||||
        case SGSAP_RESET_INDICATION:
 | 
			
		||||
            sgsap_handle_reset_indication(vlr, pkbuf);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ extern "C" {
 | 
			
		||||
#define SGSAP_IE_IMSI_TYPE                              1
 | 
			
		||||
#define SGSAP_IE_IMSI_LEN                               MAX_IMSI_LEN
 | 
			
		||||
#define SGSAP_IE_VLR_NAME_TYPE                          2
 | 
			
		||||
#define SGSAP_IE_VLR_NAME_LEN                           256
 | 
			
		||||
#define SGSAP_IE_VLR_NAME_LEN                           MAX_FQDN_LEN
 | 
			
		||||
#define SGSAP_IE_LAI_TYPE                               4
 | 
			
		||||
#define SGSAP_IE_LAI_LEN                                5
 | 
			
		||||
#define SGSAP_IE_MME_NAME_TYPE                          9
 | 
			
		||||
 
 | 
			
		||||
@@ -100,7 +100,7 @@ ogs_socknode_t *testsctp_client(const char *ipstr)
 | 
			
		||||
 | 
			
		||||
static ogs_sockaddr_t sctp_last_addr;
 | 
			
		||||
 | 
			
		||||
ogs_pkbuf_t *testsctp_read(ogs_socknode_t *node)
 | 
			
		||||
ogs_pkbuf_t *testsctp_read(ogs_socknode_t *node, int type)
 | 
			
		||||
{
 | 
			
		||||
    int size;
 | 
			
		||||
    ogs_pkbuf_t *recvbuf = NULL;
 | 
			
		||||
@@ -111,8 +111,8 @@ ogs_pkbuf_t *testsctp_read(ogs_socknode_t *node)
 | 
			
		||||
    recvbuf = ogs_pkbuf_alloc(NULL, MAX_SDU_LEN);
 | 
			
		||||
    ogs_pkbuf_put(recvbuf, MAX_SDU_LEN);
 | 
			
		||||
 | 
			
		||||
    size = ogs_sctp_recvdata(node->sock, 
 | 
			
		||||
            recvbuf->data, MAX_SDU_LEN, &sctp_last_addr, NULL);
 | 
			
		||||
    size = ogs_sctp_recvdata(node->sock, recvbuf->data, MAX_SDU_LEN,
 | 
			
		||||
            type == 1 ? &sctp_last_addr : NULL, NULL);
 | 
			
		||||
    if (size <= 0) {
 | 
			
		||||
        ogs_error("sgsap_recv() failed");
 | 
			
		||||
        return NULL;
 | 
			
		||||
@@ -1724,8 +1724,8 @@ int tests1ap_build_tau_request(ogs_pkbuf_t **pkbuf, int i,
 | 
			
		||||
    return OGS_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int tests1ap_build_extended_service_request(ogs_pkbuf_t **pkbuf,
 | 
			
		||||
        int i, uint32_t m_tmsi, uint8_t seq, uint8_t *knas_int)
 | 
			
		||||
int tests1ap_build_extended_service_request(ogs_pkbuf_t **pkbuf, int i,
 | 
			
		||||
        uint8_t service_type, uint32_t m_tmsi, uint8_t seq, uint8_t *knas_int)
 | 
			
		||||
{
 | 
			
		||||
    char *payload[TESTS1AP_MAX_MESSAGE] = {
 | 
			
		||||
        "",
 | 
			
		||||
@@ -1807,6 +1807,7 @@ int tests1ap_build_extended_service_request(ogs_pkbuf_t **pkbuf,
 | 
			
		||||
    *pkbuf = ogs_pkbuf_alloc(NULL, MAX_SDU_LEN);
 | 
			
		||||
    ogs_pkbuf_put_data(*pkbuf, 
 | 
			
		||||
        OGS_HEX(payload[i], strlen(payload[i]), hexbuf), len[i]);
 | 
			
		||||
    memcpy((*pkbuf)->data + 26, &service_type, sizeof service_type);
 | 
			
		||||
    m_tmsi = htonl(m_tmsi);
 | 
			
		||||
    memcpy((*pkbuf)->data + 29, &m_tmsi, sizeof m_tmsi);
 | 
			
		||||
 | 
			
		||||
@@ -3161,6 +3162,29 @@ int testsgsap_imsi_detach_ack(ogs_pkbuf_t **pkbuf, int i)
 | 
			
		||||
    return OGS_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int testsgsap_paging_request(ogs_pkbuf_t **pkbuf, int i)
 | 
			
		||||
{
 | 
			
		||||
    char *payload[TESTS1AP_MAX_MESSAGE] = {
 | 
			
		||||
        "0101082926240000 111893021003766c 72076578616d706c 65036e6574200101"
 | 
			
		||||
        "040509f1070926",
 | 
			
		||||
        "",
 | 
			
		||||
        "",
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
    uint16_t len[TESTS1AP_MAX_MESSAGE] = {
 | 
			
		||||
        39,
 | 
			
		||||
        0,
 | 
			
		||||
        0,
 | 
			
		||||
    };
 | 
			
		||||
    char hexbuf[MAX_SDU_LEN];
 | 
			
		||||
    
 | 
			
		||||
    *pkbuf = ogs_pkbuf_alloc(NULL, MAX_SDU_LEN);
 | 
			
		||||
    ogs_pkbuf_put_data(*pkbuf, 
 | 
			
		||||
        OGS_HEX(payload[i], strlen(payload[i]), hexbuf), len[i]);
 | 
			
		||||
 | 
			
		||||
    return OGS_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int testsgsap_reset_indication(ogs_pkbuf_t **pkbuf, int i)
 | 
			
		||||
{
 | 
			
		||||
    char *payload[TESTS1AP_MAX_MESSAGE] = {
 | 
			
		||||
 
 | 
			
		||||
@@ -31,15 +31,15 @@ int testpacket_final();
 | 
			
		||||
 | 
			
		||||
ogs_socknode_t *testsctp_server(const char *ipstr);
 | 
			
		||||
ogs_socknode_t *testsctp_client(const char *ipstr);
 | 
			
		||||
ogs_pkbuf_t *testsctp_read(ogs_socknode_t *node);
 | 
			
		||||
ogs_pkbuf_t *testsctp_read(ogs_socknode_t *node, int type);
 | 
			
		||||
 | 
			
		||||
#define testenb_s1ap_client testsctp_client
 | 
			
		||||
#define testenb_s1ap_read testsctp_read
 | 
			
		||||
#define testenb_s1ap_read(x) testsctp_read(x, 0);
 | 
			
		||||
int testenb_s1ap_send(ogs_socknode_t *node, ogs_pkbuf_t *sendbuf);
 | 
			
		||||
#define testenb_s1ap_close ogs_socknode_free
 | 
			
		||||
 | 
			
		||||
#define testvlr_sgsap_server testsctp_server
 | 
			
		||||
#define testvlr_sgsap_read testsctp_read
 | 
			
		||||
#define testvlr_sgsap_read(x) testsctp_read(x, 1);
 | 
			
		||||
int testvlr_sgsap_send(ogs_socknode_t *node, ogs_pkbuf_t *sendbuf);
 | 
			
		||||
#define testvlr_sgsap_close ogs_socknode_free
 | 
			
		||||
 | 
			
		||||
@@ -82,8 +82,8 @@ int tests1ap_build_service_request(ogs_pkbuf_t **pkbuf,
 | 
			
		||||
int tests1ap_build_tau_request(ogs_pkbuf_t **pkbuf, int i,
 | 
			
		||||
    uint32_t mme_ue_s1ap_id, uint32_t enb_ue_s1ap_id, uint8_t active_flag,
 | 
			
		||||
    uint32_t m_tmsi, uint8_t seq, uint32_t mac, uint8_t *knas_int);
 | 
			
		||||
int tests1ap_build_extended_service_request(ogs_pkbuf_t **pkbuf,
 | 
			
		||||
        int i, uint32_t m_tmsi, uint8_t seq, uint8_t *knas_int);
 | 
			
		||||
int tests1ap_build_extended_service_request(ogs_pkbuf_t **pkbuf, int i,
 | 
			
		||||
        uint8_t service_type, uint32_t m_tmsi, uint8_t seq, uint8_t *knas_int);
 | 
			
		||||
int tests1ap_build_pdn_connectivity_request(
 | 
			
		||||
        ogs_pkbuf_t **pkbuf, int i);
 | 
			
		||||
int tests1ap_build_pdn_disconnectivity_request(
 | 
			
		||||
@@ -134,6 +134,7 @@ int testgtpu_build_slacc_rs(ogs_pkbuf_t **sendbuf, int i);
 | 
			
		||||
int testsgsap_location_update_accept(ogs_pkbuf_t **pkbuf, int i);
 | 
			
		||||
int testsgsap_location_update_reject(ogs_pkbuf_t **pkbuf, int i);
 | 
			
		||||
int testsgsap_imsi_detach_ack(ogs_pkbuf_t **pkbuf, int i);
 | 
			
		||||
int testsgsap_paging_request(ogs_pkbuf_t **pkbuf, int i);
 | 
			
		||||
int testsgsap_reset_indication(ogs_pkbuf_t **pkbuf, int i);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 
 | 
			
		||||
@@ -744,8 +744,8 @@ static void test3_func(abts_case *tc, void *data)
 | 
			
		||||
    ABTS_INT_EQUAL(tc, OGS_OK, rv);
 | 
			
		||||
 | 
			
		||||
    /* Send Extended Service Request */
 | 
			
		||||
    rv = tests1ap_build_extended_service_request(&sendbuf,
 | 
			
		||||
            msgindex, m_tmsi, 4, mme_ue->knas_int);
 | 
			
		||||
    rv = tests1ap_build_extended_service_request(&sendbuf, msgindex,
 | 
			
		||||
            0, m_tmsi, 4, mme_ue->knas_int);
 | 
			
		||||
    ABTS_INT_EQUAL(tc, OGS_OK, rv);
 | 
			
		||||
    rv = testenb_s1ap_send(s1ap, sendbuf);
 | 
			
		||||
    ABTS_INT_EQUAL(tc, OGS_OK, rv);
 | 
			
		||||
@@ -755,7 +755,7 @@ static void test3_func(abts_case *tc, void *data)
 | 
			
		||||
    ABTS_PTR_NOTNULL(tc, recvbuf);
 | 
			
		||||
    ogs_pkbuf_free(recvbuf);
 | 
			
		||||
 | 
			
		||||
    /* Initial Context Setup Request */
 | 
			
		||||
    /* Receive Initial Context Setup Request */
 | 
			
		||||
    recvbuf = testenb_s1ap_read(s1ap);
 | 
			
		||||
    ABTS_PTR_NOTNULL(tc, recvbuf);
 | 
			
		||||
    ogs_pkbuf_free(recvbuf);
 | 
			
		||||
 
 | 
			
		||||
@@ -225,12 +225,29 @@ static void test1_func(abts_case *tc, void *data)
 | 
			
		||||
    rv = testenb_s1ap_send(s1ap, sendbuf);
 | 
			
		||||
    ABTS_INT_EQUAL(tc, OGS_OK, rv);
 | 
			
		||||
 | 
			
		||||
    /* Send Service Request */
 | 
			
		||||
    rv = tests1ap_build_service_request(&sendbuf, 0x000200, 3, 0xc340, m_tmsi);
 | 
			
		||||
    /* Send SGsAP-Paging-Request */
 | 
			
		||||
    rv = testsgsap_paging_request(&sendbuf, 0);
 | 
			
		||||
    ABTS_INT_EQUAL(tc, OGS_OK, rv);
 | 
			
		||||
    rv = testvlr_sgsap_send(sgsap, sendbuf);
 | 
			
		||||
    ABTS_INT_EQUAL(tc, OGS_OK, rv);
 | 
			
		||||
 | 
			
		||||
    /* Receive S1AP Paging */
 | 
			
		||||
    recvbuf = testenb_s1ap_read(s1ap);
 | 
			
		||||
    ABTS_PTR_NOTNULL(tc, recvbuf);
 | 
			
		||||
    ogs_pkbuf_free(recvbuf);
 | 
			
		||||
 | 
			
		||||
    /* Send Extended Service Request */
 | 
			
		||||
    rv = tests1ap_build_extended_service_request(&sendbuf, msgindex, 
 | 
			
		||||
            1, m_tmsi, 4, mme_ue->knas_int);
 | 
			
		||||
    ABTS_INT_EQUAL(tc, OGS_OK, rv);
 | 
			
		||||
    rv = testenb_s1ap_send(s1ap, sendbuf);
 | 
			
		||||
    ABTS_INT_EQUAL(tc, OGS_OK, rv);
 | 
			
		||||
 | 
			
		||||
    /* Receive Service Request */
 | 
			
		||||
    recvbuf = testvlr_sgsap_read(sgsap);
 | 
			
		||||
    ABTS_PTR_NOTNULL(tc, recvbuf);
 | 
			
		||||
    ogs_pkbuf_free(recvbuf);
 | 
			
		||||
 | 
			
		||||
    /* Receive Initial Context Setup Request */
 | 
			
		||||
    recvbuf = testenb_s1ap_read(s1ap);
 | 
			
		||||
    ABTS_PTR_NOTNULL(tc, recvbuf);
 | 
			
		||||
@@ -243,23 +260,12 @@ static void test1_func(abts_case *tc, void *data)
 | 
			
		||||
    rv = testenb_s1ap_send(s1ap, sendbuf);
 | 
			
		||||
    ABTS_INT_EQUAL(tc, OGS_OK, rv);
 | 
			
		||||
 | 
			
		||||
    /* Send Detach Request */
 | 
			
		||||
    rv = tests1ap_build_detach_request(&sendbuf, msgindex);
 | 
			
		||||
    /* Send UE Context Release Request */
 | 
			
		||||
    rv = tests1ap_build_ue_context_release_request(&sendbuf, msgindex+1);
 | 
			
		||||
    ABTS_INT_EQUAL(tc, OGS_OK, rv);
 | 
			
		||||
    rv = testenb_s1ap_send(s1ap, sendbuf);
 | 
			
		||||
    ABTS_INT_EQUAL(tc, OGS_OK, rv);
 | 
			
		||||
 | 
			
		||||
    /* Receive SGsAP IMSI-DETACH-INDICATION */
 | 
			
		||||
    recvbuf = testvlr_sgsap_read(sgsap);
 | 
			
		||||
    ABTS_PTR_NOTNULL(tc, recvbuf);
 | 
			
		||||
    ogs_pkbuf_free(recvbuf);
 | 
			
		||||
 | 
			
		||||
    /* Send SGsAP IMSI-DETACH-ACK */
 | 
			
		||||
    rv = testsgsap_imsi_detach_ack(&sendbuf, 0);
 | 
			
		||||
    ABTS_INT_EQUAL(tc, OGS_OK, rv);
 | 
			
		||||
    rv = testvlr_sgsap_send(sgsap, sendbuf);
 | 
			
		||||
    ABTS_INT_EQUAL(tc, OGS_OK, rv);
 | 
			
		||||
 | 
			
		||||
    /* Receive UE Context Release Command */
 | 
			
		||||
    recvbuf = testenb_s1ap_read(s1ap);
 | 
			
		||||
    ABTS_PTR_NOTNULL(tc, recvbuf);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user