@ -33,158 +33,151 @@
namespace srsepc {
namespace srsepc {
s1ap_ctx_mngmt_proc * s1ap_ctx_mngmt_proc : : m_instance = NULL ;
s1ap_ctx_mngmt_proc * s1ap_ctx_mngmt_proc : : m_instance = NULL ;
pthread_mutex_t s1ap_ctx_mngmt_proc_instance_mutex = PTHREAD_MUTEX_INITIALIZER ;
pthread_mutex_t s1ap_ctx_mngmt_proc_instance_mutex = PTHREAD_MUTEX_INITIALIZER ;
s1ap_ctx_mngmt_proc : : s1ap_ctx_mngmt_proc ( ) { }
s1ap_ctx_mngmt_proc : : ~ s1ap_ctx_mngmt_proc ( ) { }
s1ap_ctx_mngmt_proc : : s1ap_ctx_mngmt_proc ( )
s1ap_ctx_mngmt_proc * s1ap_ctx_mngmt_proc : : get_instance ( void )
{
}
s1ap_ctx_mngmt_proc : : ~ s1ap_ctx_mngmt_proc ( )
{
}
s1ap_ctx_mngmt_proc *
s1ap_ctx_mngmt_proc : : get_instance ( void )
{
{
pthread_mutex_lock ( & s1ap_ctx_mngmt_proc_instance_mutex ) ;
pthread_mutex_lock ( & s1ap_ctx_mngmt_proc_instance_mutex ) ;
if ( NULL = = m_instance ) {
if ( NULL = = m_instance ) {
m_instance = new s1ap_ctx_mngmt_proc ( ) ;
m_instance = new s1ap_ctx_mngmt_proc ( ) ;
}
}
pthread_mutex_unlock ( & s1ap_ctx_mngmt_proc_instance_mutex ) ;
pthread_mutex_unlock ( & s1ap_ctx_mngmt_proc_instance_mutex ) ;
return ( m_instance ) ;
return ( m_instance ) ;
}
}
void
void s1ap_ctx_mngmt_proc : : cleanup ( void )
s1ap_ctx_mngmt_proc : : cleanup ( void )
{
{
pthread_mutex_lock ( & s1ap_ctx_mngmt_proc_instance_mutex ) ;
pthread_mutex_lock ( & s1ap_ctx_mngmt_proc_instance_mutex ) ;
if ( NULL ! = m_instance ) {
if ( NULL ! = m_instance ) {
delete m_instance ;
delete m_instance ;
m_instance = NULL ;
m_instance = NULL ;
}
}
pthread_mutex_unlock ( & s1ap_ctx_mngmt_proc_instance_mutex ) ;
pthread_mutex_unlock ( & s1ap_ctx_mngmt_proc_instance_mutex ) ;
}
}
void
void s1ap_ctx_mngmt_proc : : init ( void )
s1ap_ctx_mngmt_proc : : init ( void )
{
{
m_s1ap = s1ap : : get_instance ( ) ;
m_s1ap = s1ap : : get_instance ( ) ;
m_mme_gtpc = mme_gtpc : : get_instance ( ) ;
m_mme_gtpc = mme_gtpc : : get_instance ( ) ;
m_s1ap_log = m_s1ap - > m_s1ap_log ;
m_s1ap_log = m_s1ap - > m_s1ap_log ;
m_s1ap_args = m_s1ap - > m_s1ap_args ;
m_s1ap_args = m_s1ap - > m_s1ap_args ;
m_pool = srslte : : byte_buffer_pool : : get_instance ( ) ;
m_pool = srslte : : byte_buffer_pool : : get_instance ( ) ;
m_s1ap_nas_transport = s1ap_nas_transport : : get_instance ( ) ;
m_s1ap_nas_transport = s1ap_nas_transport : : get_instance ( ) ;
}
}
bool
bool s1ap_ctx_mngmt_proc : : send_initial_context_setup_request ( nas * nas_ctx , uint16_t erab_to_setup )
s1ap_ctx_mngmt_proc : : send_initial_context_setup_request ( nas * nas_ctx , uint16_t erab_to_setup )
{
{
// Prepare reply PDU
// Prepare reply PDU
LIBLTE_S1AP_S1AP_PDU_STRUCT pdu ;
LIBLTE_S1AP_S1AP_PDU_STRUCT pdu ;
bzero ( & pdu , sizeof ( LIBLTE_S1AP_S1AP_PDU_STRUCT ) ) ;
bzero ( & pdu , sizeof ( LIBLTE_S1AP_S1AP_PDU_STRUCT ) ) ;
pdu . choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE ;
pdu . choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE ;
LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT * init = & pdu . choice . initiatingMessage ;
LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT * init = & pdu . choice . initiatingMessage ;
init - > procedureCode = LIBLTE_S1AP_PROC_ID_INITIALCONTEXTSETUP ;
init - > procedureCode = LIBLTE_S1AP_PROC_ID_INITIALCONTEXTSETUP ;
init - > choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_INITIALCONTEXTSETUPREQUEST ;
init - > choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_INITIALCONTEXTSETUPREQUEST ;
LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT * in_ctxt_req = & init - > choice . InitialContextSetupRequest ;
LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT * in_ctxt_req = & init - > choice . InitialContextSetupRequest ;
m_s1ap_log - > info ( " Preparing to send Initial Context Setup request \n " ) ;
m_s1ap_log - > info ( " Preparing to send Initial Context Setup request \n " ) ;
// Get UE Context/E-RAB Context to setup
// Get UE Context/E-RAB Context to setup
emm_ctx_t * emm_ctx = & nas_ctx - > m_emm_ctx ;
emm_ctx_t * emm_ctx = & nas_ctx - > m_emm_ctx ;
ecm_ctx_t * ecm_ctx = & nas_ctx - > m_ecm_ctx ;
ecm_ctx_t * ecm_ctx = & nas_ctx - > m_ecm_ctx ;
esm_ctx_t * esm_ctx = & nas_ctx - > m_esm_ctx [ erab_to_setup ] ;
esm_ctx_t * esm_ctx = & nas_ctx - > m_esm_ctx [ erab_to_setup ] ;
sec_ctx_t * sec_ctx = & nas_ctx - > m_sec_ctx ;
sec_ctx_t * sec_ctx = & nas_ctx - > m_sec_ctx ;
// Add MME and eNB S1AP Ids
// Add MME and eNB S1AP Ids
in_ctxt_req - > MME_UE_S1AP_ID . MME_UE_S1AP_ID = ecm_ctx - > mme_ue_s1ap_id ;
in_ctxt_req - > MME_UE_S1AP_ID . MME_UE_S1AP_ID = ecm_ctx - > mme_ue_s1ap_id ;
in_ctxt_req - > eNB_UE_S1AP_ID . ENB_UE_S1AP_ID = ecm_ctx - > enb_ue_s1ap_id ;
in_ctxt_req - > eNB_UE_S1AP_ID . ENB_UE_S1AP_ID = ecm_ctx - > enb_ue_s1ap_id ;
// Set UE-AMBR
// Set UE-AMBR
in_ctxt_req - > uEaggregateMaximumBitrate . uEaggregateMaximumBitRateDL . BitRate = 1000000000 ;
in_ctxt_req - > uEaggregateMaximumBitrate . uEaggregateMaximumBitRateDL . BitRate = 1000000000 ;
in_ctxt_req - > uEaggregateMaximumBitrate . uEaggregateMaximumBitRateUL . BitRate = 1000000000 ;
in_ctxt_req - > uEaggregateMaximumBitrate . uEaggregateMaximumBitRateUL . BitRate = 1000000000 ;
// Number of E-RABs to be setup
// Number of E-RABs to be setup
in_ctxt_req - > E_RABToBeSetupListCtxtSUReq . len = 1 ;
in_ctxt_req - > E_RABToBeSetupListCtxtSUReq . len = 1 ;
//Setup eRAB context
// Setup eRAB context
LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT * erab_ctx_req = & in_ctxt_req - > E_RABToBeSetupListCtxtSUReq . buffer [ 0 ] ;
LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT * erab_ctx_req = & in_ctxt_req - > E_RABToBeSetupListCtxtSUReq . buffer [ 0 ] ;
erab_ctx_req - > e_RAB_ID . E_RAB_ID = esm_ctx - > erab_id ;
erab_ctx_req - > e_RAB_ID . E_RAB_ID = esm_ctx - > erab_id ;
//Setup E-RAB QoS parameters
// Setup E-RAB QoS parameters
erab_ctx_req - > e_RABlevelQoSParameters . qCI . QCI = esm_ctx - > qci ;
erab_ctx_req - > e_RABlevelQoSParameters . qCI . QCI = esm_ctx - > qci ;
erab_ctx_req - > e_RABlevelQoSParameters . allocationRetentionPriority . priorityLevel . PriorityLevel = 15 ; //Lowest
erab_ctx_req - > e_RABlevelQoSParameters . allocationRetentionPriority . priorityLevel . PriorityLevel = 15 ; // Lowest
erab_ctx_req - > e_RABlevelQoSParameters . allocationRetentionPriority . pre_emptionCapability = LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_SHALL_NOT_TRIGGER_PRE_EMPTION ;
erab_ctx_req - > e_RABlevelQoSParameters . allocationRetentionPriority . pre_emptionCapability =
erab_ctx_req - > e_RABlevelQoSParameters . allocationRetentionPriority . pre_emptionVulnerability = LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_PRE_EMPTABLE ;
LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_SHALL_NOT_TRIGGER_PRE_EMPTION ;
erab_ctx_req - > e_RABlevelQoSParameters . gbrQosInformation_present = false ;
erab_ctx_req - > e_RABlevelQoSParameters . allocationRetentionPriority . pre_emptionVulnerability =
LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_PRE_EMPTABLE ;
//Set E-RAB S-GW F-TEID
erab_ctx_req - > e_RABlevelQoSParameters . gbrQosInformation_present = false ;
erab_ctx_req - > transportLayerAddress . n_bits = 32 ; //IPv4
uint32_t sgw_s1u_ip = htonl ( esm_ctx - > sgw_s1u_fteid . ipv4 ) ;
// Set E-RAB S-GW F-TEID
uint8_t * tmp_ptr = erab_ctx_req - > transportLayerAddress . buffer ;
erab_ctx_req - > transportLayerAddress . n_bits = 32 ; // IPv4
uint32_t sgw_s1u_ip = htonl ( esm_ctx - > sgw_s1u_fteid . ipv4 ) ;
uint8_t * tmp_ptr = erab_ctx_req - > transportLayerAddress . buffer ;
liblte_value_2_bits ( sgw_s1u_ip , & tmp_ptr , 32 ) ;
liblte_value_2_bits ( sgw_s1u_ip , & tmp_ptr , 32 ) ;
uint32_t sgw_s1u_teid = esm_ctx - > sgw_s1u_fteid . teid ;
uint32_t sgw_s1u_teid = esm_ctx - > sgw_s1u_fteid . teid ;
srslte : : uint32_to_uint8 ( sgw_s1u_teid , erab_ctx_req - > gTP_TEID . buffer ) ;
srslte : : uint32_to_uint8 ( sgw_s1u_teid , erab_ctx_req - > gTP_TEID . buffer ) ;
// Set UE security capabilities and k_enb
// Set UE security capabilities and k_enb
bzero ( in_ctxt_req - > UESecurityCapabilities . encryptionAlgorithms . buffer , sizeof ( uint8_t ) * 16 ) ;
bzero ( in_ctxt_req - > UESecurityCapabilities . encryptionAlgorithms . buffer , sizeof ( uint8_t ) * 16 ) ;
bzero ( in_ctxt_req - > UESecurityCapabilities . integrityProtectionAlgorithms . buffer , sizeof ( uint8_t ) * 16 ) ;
bzero ( in_ctxt_req - > UESecurityCapabilities . integrityProtectionAlgorithms . buffer , sizeof ( uint8_t ) * 16 ) ;
for ( int i = 0 ; i < 3 ; i + + ) {
for ( int i = 0 ; i < 3 ; i + + ) {
if ( sec_ctx - > ue_network_cap . eea [ i + 1 ] = = true ) {
if ( sec_ctx - > ue_network_cap . eea [ i + 1 ] = = true ) {
in_ctxt_req - > UESecurityCapabilities . encryptionAlgorithms . buffer [ i ] = 1 ; // EEA supported
in_ctxt_req - > UESecurityCapabilities . encryptionAlgorithms . buffer [ i ] = 1 ; // EEA supported
} else {
} else {
in_ctxt_req - > UESecurityCapabilities . encryptionAlgorithms . buffer [ i ] = 0 ; // EEA not supported
in_ctxt_req - > UESecurityCapabilities . encryptionAlgorithms . buffer [ i ] = 0 ; // EEA not supported
}
}
if ( sec_ctx - > ue_network_cap . eia [ i + 1 ] = = true ) {
if ( sec_ctx - > ue_network_cap . eia [ i + 1 ] = = true ) {
in_ctxt_req - > UESecurityCapabilities . integrityProtectionAlgorithms . buffer [ i ] = 1 ; // EEA supported
in_ctxt_req - > UESecurityCapabilities . integrityProtectionAlgorithms . buffer [ i ] = 1 ; // EEA supported
} else {
} else {
in_ctxt_req - > UESecurityCapabilities . integrityProtectionAlgorithms . buffer [ i ] = 0 ; // EEA not supported
in_ctxt_req - > UESecurityCapabilities . integrityProtectionAlgorithms . buffer [ i ] = 0 ; // EEA not supported
}
}
}
}
// Get K eNB
// Get K eNB
liblte_unpack ( sec_ctx - > k_enb , 32 , in_ctxt_req - > SecurityKey . buffer ) ;
liblte_unpack ( sec_ctx - > k_enb , 32 , in_ctxt_req - > SecurityKey . buffer ) ;
m_s1ap_log - > info_hex ( sec_ctx - > k_enb , 32 , " Initial Context Setup Request -- Key eNB (k_enb) \n " ) ;
m_s1ap_log - > info_hex ( sec_ctx - > k_enb , 32 , " Initial Context Setup Request -- Key eNB (k_enb) \n " ) ;
srslte : : byte_buffer_t * nas_buffer = m_pool - > allocate ( ) ;
srslte : : byte_buffer_t * nas_buffer = m_pool - > allocate ( ) ;
if ( emm_ctx - > state = = EMM_STATE_DEREGISTERED ) {
if ( emm_ctx - > state = = EMM_STATE_DEREGISTERED ) {
// Attach procedure initiated from an attach request
// Attach procedure initiated from an attach request
m_s1ap_log - > console ( " Adding attach accept to Initial Context Setup Request \n " ) ;
m_s1ap_log - > console ( " Adding attach accept to Initial Context Setup Request \n " ) ;
m_s1ap_log - > info ( " Adding attach accept to Initial Context Setup Request \n " ) ;
m_s1ap_log - > info ( " Adding attach accept to Initial Context Setup Request \n " ) ;
nas_ctx - > pack_attach_accept ( nas_buffer ) ;
nas_ctx - > pack_attach_accept ( nas_buffer ) ;
// Add nas message to context setup request
// Add nas message to context setup request
erab_ctx_req - > nAS_PDU_present = true ;
erab_ctx_req - > nAS_PDU_present = true ;
memcpy ( erab_ctx_req - > nAS_PDU . buffer , nas_buffer - > msg , nas_buffer - > N_bytes ) ;
memcpy ( erab_ctx_req - > nAS_PDU . buffer , nas_buffer - > msg , nas_buffer - > N_bytes ) ;
erab_ctx_req - > nAS_PDU . n_octets = nas_buffer - > N_bytes ;
erab_ctx_req - > nAS_PDU . n_octets = nas_buffer - > N_bytes ;
}
}
srslte : : byte_buffer_t * reply_buffer = m_pool - > allocate ( ) ;
srslte : : byte_buffer_t * reply_buffer = m_pool - > allocate ( ) ;
LIBLTE_ERROR_ENUM err = liblte_s1ap_pack_s1ap_pdu ( & pdu , ( LIBLTE_BYTE_MSG_STRUCT * ) reply_buffer ) ;
LIBLTE_ERROR_ENUM err = liblte_s1ap_pack_s1ap_pdu ( & pdu , ( LIBLTE_BYTE_MSG_STRUCT * ) reply_buffer ) ;
if ( err ! = LIBLTE_SUCCESS ) {
if ( err ! = LIBLTE_SUCCESS ) {
m_s1ap_log - > error ( " Could not pack Initial Context Setup Request Message \n " ) ;
m_s1ap_log - > error ( " Could not pack Initial Context Setup Request Message \n " ) ;
return false ;
return false ;
}
}
if ( ! m_s1ap - > s1ap_tx_pdu ( reply_buffer , & ecm_ctx - > enb_sri ) ) {
if ( ! m_s1ap - > s1ap_tx_pdu ( reply_buffer , & ecm_ctx - > enb_sri ) ) {
m_s1ap_log - > error ( " Error sending Initial Context Setup Request. \n " ) ;
m_s1ap_log - > error ( " Error sending Initial Context Setup Request. \n " ) ;
return false ;
return false ;
}
}
// Change E-RAB state to Context Setup Requested and save S-GW control F-TEID
// Change E-RAB state to Context Setup Requested and save S-GW control F-TEID
esm_ctx - > state = ERAB_CTX_REQUESTED ;
esm_ctx - > state = ERAB_CTX_REQUESTED ;
struct in_addr addr ;
struct in_addr addr ;
addr . s_addr = htonl ( sgw_s1u_ip ) ;
addr . s_addr = htonl ( sgw_s1u_ip ) ;
m_s1ap_log - > info ( " Sent Initial Context Setup Request. E-RAB id %d \n " , erab_ctx_req - > e_RAB_ID . E_RAB_ID ) ;
m_s1ap_log - > info ( " Sent Initial Context Setup Request. E-RAB id %d \n " , erab_ctx_req - > e_RAB_ID . E_RAB_ID ) ;
m_s1ap_log - > info ( " Initial Context -- S1-U TEID 0x%x. IP %s \n " , sgw_s1u_teid , inet_ntoa ( addr ) ) ;
m_s1ap_log - > info ( " Initial Context -- S1-U TEID 0x%x. IP %s \n " , sgw_s1u_teid , inet_ntoa ( addr ) ) ;
m_s1ap_log - > console ( " Initial Context Setup Request -- eNB UE S1AP Id %d, MME UE S1AP Id %d \n " , in_ctxt_req - > eNB_UE_S1AP_ID . ENB_UE_S1AP_ID , in_ctxt_req - > MME_UE_S1AP_ID . MME_UE_S1AP_ID ) ;
m_s1ap_log - > console ( " Initial Context Setup Request -- eNB UE S1AP Id %d, MME UE S1AP Id %d \n " ,
m_s1ap_log - > console ( " Initial Context Setup Request -- E-RAB id %d \n " , erab_ctx_req - > e_RAB_ID . E_RAB_ID ) ;
in_ctxt_req - > eNB_UE_S1AP_ID . ENB_UE_S1AP_ID , in_ctxt_req - > MME_UE_S1AP_ID . MME_UE_S1AP_ID ) ;
m_s1ap_log - > console ( " Initial Context Setup Request -- S1-U TEID 0x%x. IP %s \n " , sgw_s1u_teid , inet_ntoa ( addr ) ) ;
m_s1ap_log - > console ( " Initial Context Setup Request -- E-RAB id %d \n " , erab_ctx_req - > e_RAB_ID . E_RAB_ID ) ;
m_s1ap_log - > console ( " Initial Context Setup Request -- S1-U TEID 0x%x. IP %s \n " , sgw_s1u_teid , inet_ntoa ( addr ) ) ;
m_s1ap_log - > console ( " Initial Context Setup Request -- S1-U TEID 0x%x. IP %s \n " , sgw_s1u_teid , inet_ntoa ( addr ) ) ;
m_s1ap_log - > console ( " Initial Context Setup Request -- S1-U TEID 0x%x. IP %s \n " , sgw_s1u_teid , inet_ntoa ( addr ) ) ;
m_s1ap_log - > console ( " Initial Context Setup Request -- QCI %d \n " , erab_ctx_req - > e_RABlevelQoSParameters . qCI . QCI ) ;
m_s1ap_log - > console ( " Initial Context Setup Request -- QCI %d \n " , erab_ctx_req - > e_RABlevelQoSParameters . qCI . QCI ) ;
m_pool - > deallocate ( reply_buffer ) ;
m_pool - > deallocate ( reply_buffer ) ;
@ -192,48 +185,47 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(nas *nas_ctx, uint16_t e
return true ;
return true ;
}
}
bool
bool s1ap_ctx_mngmt_proc : : handle_initial_context_setup_response (
s1ap_ctx_mngmt_proc : : handle_initial_context_setup_response ( LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT * in_ctxt_resp )
LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT * in_ctxt_resp )
{
{
uint32_t mme_ue_s1ap_id = in_ctxt_resp - > MME_UE_S1AP_ID . MME_UE_S1AP_ID ;
uint32_t mme_ue_s1ap_id = in_ctxt_resp - > MME_UE_S1AP_ID . MME_UE_S1AP_ID ;
nas * nas_ctx = m_s1ap - > find_nas_ctx_from_mme_ue_s1ap_id ( mme_ue_s1ap_id ) ;
nas * nas_ctx = m_s1ap - > find_nas_ctx_from_mme_ue_s1ap_id ( mme_ue_s1ap_id ) ;
if ( nas_ctx = = NULL ) {
if ( nas_ctx = = NULL ) {
m_s1ap_log - > error ( " Could not find UE's context in active UE's map \n " ) ;
m_s1ap_log - > error ( " Could not find UE's context in active UE's map \n " ) ;
return false ;
return false ;
}
}
emm_ctx_t * emm_ctx = & nas_ctx - > m_emm_ctx ;
emm_ctx_t * emm_ctx = & nas_ctx - > m_emm_ctx ;
ecm_ctx_t * ecm_ctx = & nas_ctx - > m_ecm_ctx ;
ecm_ctx_t * ecm_ctx = & nas_ctx - > m_ecm_ctx ;
m_s1ap_log - > console ( " Received Initial Context Setup Response \n " ) ;
m_s1ap_log - > console ( " Received Initial Context Setup Response \n " ) ;
// Setup E-RABs
// Setup E-RABs
for ( uint32_t i = 0 ; i < in_ctxt_resp - > E_RABSetupListCtxtSURes . len ; i + + ) {
for ( uint32_t i = 0 ; i < in_ctxt_resp - > E_RABSetupListCtxtSURes . len ; i + + ) {
uint8_t erab_id = in_ctxt_resp - > E_RABSetupListCtxtSURes . buffer [ i ] . e_RAB_ID . E_RAB_ID ;
uint8_t erab_id = in_ctxt_resp - > E_RABSetupListCtxtSURes . buffer [ i ] . e_RAB_ID . E_RAB_ID ;
esm_ctx_t * esm_ctx = & nas_ctx - > m_esm_ctx [ erab_id ] ;
esm_ctx_t * esm_ctx = & nas_ctx - > m_esm_ctx [ erab_id ] ;
if ( esm_ctx - > state ! = ERAB_CTX_REQUESTED ) {
if ( esm_ctx - > state ! = ERAB_CTX_REQUESTED ) {
m_s1ap_log - > error ( " E-RAB requested was not previously requested %d \n " , erab_id ) ;
m_s1ap_log - > error ( " E-RAB requested was not previously requested %d \n " , erab_id ) ;
return false ;
return false ;
}
}
// Mark E-RAB with context setup
// Mark E-RAB with context setup
esm_ctx - > state = ERAB_CTX_SETUP ;
esm_ctx - > state = ERAB_CTX_SETUP ;
// Set the GTP information
// Set the GTP information
uint8_t * bit_ptr = in_ctxt_resp - > E_RABSetupListCtxtSURes . buffer [ i ] . transportLayerAddress . buffer ;
uint8_t * bit_ptr = in_ctxt_resp - > E_RABSetupListCtxtSURes . buffer [ i ] . transportLayerAddress . buffer ;
esm_ctx - > enb_fteid . ipv4 = htonl ( liblte_bits_2_value ( & bit_ptr , 32 ) ) ;
esm_ctx - > enb_fteid . ipv4 = htonl ( liblte_bits_2_value ( & bit_ptr , 32 ) ) ;
memcpy ( & esm_ctx - > enb_fteid . teid , in_ctxt_resp - > E_RABSetupListCtxtSURes . buffer [ i ] . gTP_TEID . buffer , 4 ) ;
memcpy ( & esm_ctx - > enb_fteid . teid , in_ctxt_resp - > E_RABSetupListCtxtSURes . buffer [ i ] . gTP_TEID . buffer , 4 ) ;
esm_ctx - > enb_fteid . teid = ntohl ( esm_ctx - > enb_fteid . teid ) ;
esm_ctx - > enb_fteid . teid = ntohl ( esm_ctx - > enb_fteid . teid ) ;
char enb_addr_str [ INET_ADDRSTRLEN + 1 ] ;
char enb_addr_str [ INET_ADDRSTRLEN + 1 ] ;
const char * err = inet_ntop ( AF_INET , & esm_ctx - > enb_fteid . ipv4 , enb_addr_str , sizeof ( enb_addr_str ) ) ;
const char * err = inet_ntop ( AF_INET , & esm_ctx - > enb_fteid . ipv4 , enb_addr_str , sizeof ( enb_addr_str ) ) ;
if ( err = = NULL ) {
if ( err = = NULL ) {
m_s1ap_log - > error ( " Error converting IP to string \n " ) ;
m_s1ap_log - > error ( " Error converting IP to string \n " ) ;
}
}
m_s1ap_log - > info ( " E-RAB Context Setup. E-RAB id %d \n " , esm_ctx - > erab_id ) ;
m_s1ap_log - > info ( " E-RAB Context Setup. E-RAB id %d \n " , esm_ctx - > erab_id ) ;
m_s1ap_log - > info ( " E-RAB Context -- eNB TEID 0x%x, eNB Address %s \n " , esm_ctx - > enb_fteid . teid , enb_addr_str ) ;
m_s1ap_log - > info ( " E-RAB Context -- eNB TEID 0x%x, eNB Address %s \n " , esm_ctx - > enb_fteid . teid , enb_addr_str ) ;
m_s1ap_log - > console ( " E-RAB Context Setup. E-RAB id %d \n " , esm_ctx - > erab_id ) ;
m_s1ap_log - > console ( " E-RAB Context Setup. E-RAB id %d \n " , esm_ctx - > erab_id ) ;
m_s1ap_log - > console ( " E-RAB Context -- eNB TEID 0x%x; eNB GTP-U Address %s \n " , esm_ctx - > enb_fteid . teid , enb_addr_str ) ;
m_s1ap_log - > console ( " E-RAB Context -- eNB TEID 0x%x; eNB GTP-U Address %s \n " , esm_ctx - > enb_fteid . teid ,
enb_addr_str ) ;
}
}
if ( emm_ctx - > state = = EMM_STATE_REGISTERED ) {
if ( emm_ctx - > state = = EMM_STATE_REGISTERED ) {
@ -244,8 +236,9 @@ s1ap_ctx_mngmt_proc::handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_I
return true ;
return true ;
}
}
bool
bool s1ap_ctx_mngmt_proc : : handle_ue_context_release_request ( LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT * ue_rel ,
s1ap_ctx_mngmt_proc : : handle_ue_context_release_request ( LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT * ue_rel , struct sctp_sndrcvinfo * enb_sri , srslte : : byte_buffer_t * reply_buffer , bool * reply_flag )
struct sctp_sndrcvinfo * enb_sri ,
srslte : : byte_buffer_t * reply_buffer , bool * reply_flag )
{
{
LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT ue_rel_req ;
LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT ue_rel_req ;
@ -294,28 +287,27 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECON
return true ;
return true ;
}
}
bool
bool s1ap_ctx_mngmt_proc : : send_ue_context_release_command ( nas * nas_ctx )
s1ap_ctx_mngmt_proc : : send_ue_context_release_command ( nas * nas_ctx )
{
{
srslte : : byte_buffer_t * reply_buffer = m_pool - > allocate ( ) ;
srslte : : byte_buffer_t * reply_buffer = m_pool - > allocate ( ) ;
// Prepare reply PDU
// Prepare reply PDU
LIBLTE_S1AP_S1AP_PDU_STRUCT pdu ;
LIBLTE_S1AP_S1AP_PDU_STRUCT pdu ;
bzero ( & pdu , sizeof ( LIBLTE_S1AP_S1AP_PDU_STRUCT ) ) ;
bzero ( & pdu , sizeof ( LIBLTE_S1AP_S1AP_PDU_STRUCT ) ) ;
pdu . choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE ;
pdu . choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE ;
LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT * init = & pdu . choice . initiatingMessage ;
LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT * init = & pdu . choice . initiatingMessage ;
init - > procedureCode = LIBLTE_S1AP_PROC_ID_UECONTEXTRELEASE ;
init - > procedureCode = LIBLTE_S1AP_PROC_ID_UECONTEXTRELEASE ;
init - > choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTRELEASECOMMAND ;
init - > choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTRELEASECOMMAND ;
LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMMAND_STRUCT * ctx_rel_cmd = & init - > choice . UEContextReleaseCommand ;
LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMMAND_STRUCT * ctx_rel_cmd = & init - > choice . UEContextReleaseCommand ;
ctx_rel_cmd - > UE_S1AP_IDs . choice_type = LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_UE_S1AP_ID_PAIR ;
ctx_rel_cmd - > UE_S1AP_IDs . choice_type = LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_UE_S1AP_ID_PAIR ;
ctx_rel_cmd - > UE_S1AP_IDs . choice . uE_S1AP_ID_pair . mME_UE_S1AP_ID . MME_UE_S1AP_ID = nas_ctx - > m_ecm_ctx . mme_ue_s1ap_id ;
ctx_rel_cmd - > UE_S1AP_IDs . choice . uE_S1AP_ID_pair . mME_UE_S1AP_ID . MME_UE_S1AP_ID = nas_ctx - > m_ecm_ctx . mme_ue_s1ap_id ;
ctx_rel_cmd - > UE_S1AP_IDs . choice . uE_S1AP_ID_pair . eNB_UE_S1AP_ID . ENB_UE_S1AP_ID = nas_ctx - > m_ecm_ctx . enb_ue_s1ap_id ;
ctx_rel_cmd - > UE_S1AP_IDs . choice . uE_S1AP_ID_pair . eNB_UE_S1AP_ID . ENB_UE_S1AP_ID = nas_ctx - > m_ecm_ctx . enb_ue_s1ap_id ;
ctx_rel_cmd - > Cause . choice_type = LIBLTE_S1AP_CAUSE_CHOICE_NAS ;
ctx_rel_cmd - > Cause . choice_type = LIBLTE_S1AP_CAUSE_CHOICE_NAS ;
ctx_rel_cmd - > Cause . choice . nas . ext = false ;
ctx_rel_cmd - > Cause . choice . nas . ext = false ;
ctx_rel_cmd - > Cause . choice . nas . e = LIBLTE_S1AP_CAUSENAS_NORMAL_RELEASE ;
ctx_rel_cmd - > Cause . choice . nas . e = LIBLTE_S1AP_CAUSENAS_NORMAL_RELEASE ;
LIBLTE_ERROR_ENUM err = liblte_s1ap_pack_s1ap_pdu ( & pdu , ( LIBLTE_BYTE_MSG_STRUCT * ) reply_buffer ) ;
LIBLTE_ERROR_ENUM err = liblte_s1ap_pack_s1ap_pdu ( & pdu , ( LIBLTE_BYTE_MSG_STRUCT * ) reply_buffer ) ;
if ( err ! = LIBLTE_SUCCESS ) {
if ( err ! = LIBLTE_SUCCESS ) {
@ -324,8 +316,8 @@ s1ap_ctx_mngmt_proc::send_ue_context_release_command(nas *nas_ctx)
return false ;
return false ;
}
}
// Send Reply to eNB
// Send Reply to eNB
if ( ! m_s1ap - > s1ap_tx_pdu ( reply_buffer , & nas_ctx - > m_ecm_ctx . enb_sri ) ) {
if ( ! m_s1ap - > s1ap_tx_pdu ( reply_buffer , & nas_ctx - > m_ecm_ctx . enb_sri ) ) {
m_s1ap_log - > error ( " Error sending UE Context Release Command. \n " ) ;
m_s1ap_log - > error ( " Error sending UE Context Release Command. \n " ) ;
m_pool - > deallocate ( reply_buffer ) ;
m_pool - > deallocate ( reply_buffer ) ;
return false ;
return false ;
@ -335,8 +327,8 @@ s1ap_ctx_mngmt_proc::send_ue_context_release_command(nas *nas_ctx)
return true ;
return true ;
}
}
bool
bool s1ap_ctx_mngmt_proc : : handle_ue_context_release_complete (
s1ap_ctx_mngmt_proc : : handle_ue_context_release_complete ( LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMPLETE_STRUCT * rel_comp )
LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMPLETE_STRUCT * rel_comp )
{
{
uint32_t mme_ue_s1ap_id = rel_comp - > MME_UE_S1AP_ID . MME_UE_S1AP_ID ;
uint32_t mme_ue_s1ap_id = rel_comp - > MME_UE_S1AP_ID . MME_UE_S1AP_ID ;
m_s1ap_log - > info ( " Received UE Context Release Complete. MME-UE S1AP Id: %d \n " , mme_ue_s1ap_id ) ;
m_s1ap_log - > info ( " Received UE Context Release Complete. MME-UE S1AP Id: %d \n " , mme_ue_s1ap_id ) ;
@ -351,14 +343,14 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_complete(LIBLTE_S1AP_MESSAGE_UECO
emm_ctx_t * emm_ctx = & nas_ctx - > m_emm_ctx ;
emm_ctx_t * emm_ctx = & nas_ctx - > m_emm_ctx ;
ecm_ctx_t * ecm_ctx = & nas_ctx - > m_ecm_ctx ;
ecm_ctx_t * ecm_ctx = & nas_ctx - > m_ecm_ctx ;
// Delete user plane context at the SPGW (but keep GTP-C connection).
// Delete user plane context at the SPGW (but keep GTP-C connection).
if ( ecm_ctx - > state = = ECM_STATE_CONNECTED ) {
if ( ecm_ctx - > state = = ECM_STATE_CONNECTED ) {
// There are active E-RABs, send release access mearers request
// There are active E-RABs, send release access mearers request
m_s1ap_log - > console ( " There are active E-RABs, send release access m earers request" ) ;
m_s1ap_log - > console ( " There are active E-RABs, send release access b earers request" ) ;
m_s1ap_log - > info ( " There are active E-RABs, send release access m earers request" ) ;
m_s1ap_log - > info ( " There are active E-RABs, send release access b earers request" ) ;
m_mme_gtpc - > send_release_access_bearers_request ( emm_ctx - > imsi ) ;
m_mme_gtpc - > send_release_access_bearers_request ( emm_ctx - > imsi ) ;
//The handle_rele e ase_access_bearers_response function will make sure to mark E-RABS DEACTIVATED
//The handle_rele ase_access_bearers_response function will make sure to mark E-RABS DEACTIVATED
//It will release the UEs downstream S1- u and keep the upstream S1-U connection active.
//It will release the UEs downstream S1- U and keep the upstream S1-U connection active.
} else {
} else {
//No ECM Context to release
//No ECM Context to release
m_s1ap_log - > info ( " UE is not ECM connected. No need to release S1-U. MME UE S1AP Id %d \n " , mme_ue_s1ap_id ) ;
m_s1ap_log - > info ( " UE is not ECM connected. No need to release S1-U. MME UE S1AP Id %d \n " , mme_ue_s1ap_id ) ;
@ -375,6 +367,4 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_complete(LIBLTE_S1AP_MESSAGE_UECO
m_s1ap_log - > console ( " UE Context Release Completed. \n " ) ;
m_s1ap_log - > console ( " UE Context Release Completed. \n " ) ;
return true ;
return true ;
}
}
} //namespace srsepc
} //namespace srsepc