forked from acouzens/open5gs
[CSFB] MT in idle-mode
This commit is contained in:
parent
5e0c10bcb4
commit
16a8bea96b
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue