Merge remote-tracking branch 'origin/NR_SA_itti_sim_wk48' into integration_2021_wk05
This commit is contained in:
@@ -485,7 +485,6 @@ add_custom_target (
|
||||
|
||||
add_library(NR_RRC_LIB ${nr_rrc_h} ${nr_rrc_source}
|
||||
${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1_msg.c
|
||||
${OPENAIR2_DIR}/RRC/NR/nr_ngap_gNB.c
|
||||
)
|
||||
add_dependencies(NR_RRC_LIB nr_rrc_flag)
|
||||
include_directories ("${NR_RRC_FULL_DIR}")
|
||||
@@ -2588,6 +2587,13 @@ if(ITTI_SIM)
|
||||
|
||||
set(libnrnas_emm_msg_OBJS
|
||||
${NAS_SRC}COMMON/EMM/MSG/RegistrationRequest.c
|
||||
${NAS_SRC}COMMON/EMM/MSG/RegistrationAccept.c
|
||||
${NAS_SRC}COMMON/EMM/MSG/FGSIdentityResponse.c
|
||||
${NAS_SRC}COMMON/EMM/MSG/FGSAuthenticationResponse.c
|
||||
${NAS_SRC}COMMON/EMM/MSG/FGSNASSecurityModeComplete.c
|
||||
${NAS_SRC}COMMON/EMM/MSG/RegistrationComplete.c
|
||||
${NAS_SRC}COMMON/EMM/MSG/FGSUplinkNasTransport.c
|
||||
${NAS_SRC}COMMON/ESM/MSG/PduSessionEstablishRequest.c
|
||||
)
|
||||
|
||||
set(libnrnas_ies_OBJS
|
||||
@@ -2595,8 +2601,11 @@ if(ITTI_SIM)
|
||||
${NAS_SRC}COMMON/IES/FGSMobileIdentity.c
|
||||
${NAS_SRC}COMMON/IES/FGSRegistrationType.c
|
||||
${NAS_SRC}COMMON/IES/SpareHalfOctet.c
|
||||
${NAS_SRC}COMMON/IES/FGSRegistrationResult.c
|
||||
${NAS_SRC}COMMON/IES/FGMMCapability.c
|
||||
${NAS_SRC}COMMON/IES/NrUESecurityCapability.c
|
||||
${NAS_SRC}COMMON/IES/FGCNasMessageContainer.c
|
||||
${NAS_SRC}COMMON/IES/SORTransparentContainer.c
|
||||
)
|
||||
|
||||
add_library(LIB_NAS_SIMUE
|
||||
@@ -3290,7 +3299,7 @@ add_executable(nr_dlsim
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
target_link_libraries(nr_dlsim
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN -Wl,--end-group
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group
|
||||
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
|
||||
)
|
||||
target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR)
|
||||
@@ -3309,7 +3318,7 @@ add_executable(nr_prachsim
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES})
|
||||
target_link_libraries(nr_prachsim
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN -Wl,--end-group
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group
|
||||
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl)
|
||||
|
||||
add_executable(nr_ulschsim
|
||||
@@ -3342,7 +3351,7 @@ add_executable(nr_ulsim
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
target_link_libraries(nr_ulsim
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN -Wl,--end-group
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group
|
||||
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
|
||||
)
|
||||
target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR)
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "NwGtpv1uMsg.h"
|
||||
#include "NwGtpv1uPrivate.h"
|
||||
#include "gtpv1u_eNB_defs.h"
|
||||
#include "gtpv1u_gNB_defs.h"
|
||||
|
||||
#include "PHY/defs_L1_NB_IoT.h"
|
||||
#include "RRC/LTE/defs_NB_IoT.h"
|
||||
@@ -109,6 +110,8 @@ typedef struct {
|
||||
struct gNB_MAC_INST_s **nrmac;
|
||||
/// GTPu descriptor
|
||||
gtpv1u_data_t *gtpv1u_data_g;
|
||||
/// NR GTPu descriptor
|
||||
nr_gtpv1u_data_t *nr_gtpv1u_data_g;
|
||||
/// RU descriptors. These describe what each radio unit is supposed to do and contain the necessary functions for fronthaul interfaces
|
||||
struct RU_t_s **ru;
|
||||
/// Mask to indicate fronthaul setup status of RU (hard-limit to 64 RUs)
|
||||
|
||||
@@ -48,12 +48,14 @@ typedef enum {
|
||||
MSC_MAC_ENB,
|
||||
MSC_RLC_ENB,
|
||||
MSC_PDCP_ENB,
|
||||
MSC_PDCP_GNB,
|
||||
MSC_RRC_ENB,
|
||||
MSC_RRC_GNB,
|
||||
MSC_IP_ENB,
|
||||
MSC_S1AP_ENB,
|
||||
MSC_NGAP_GNB,
|
||||
MSC_GTPU_ENB,
|
||||
MSC_GTPU_GNB,
|
||||
MSC_GTPU_SGW,
|
||||
MSC_S1AP_MME,
|
||||
MSC_NGAP_AMF,
|
||||
|
||||
@@ -260,7 +260,6 @@ typedef struct IttiMsgText_s {
|
||||
#include <openair3/GTPV1-U/gtpv1u_gNB_task.h>
|
||||
void *rrc_enb_process_itti_msg(void *);
|
||||
#include <openair3/SCTP/sctp_eNB_task.h>
|
||||
#include <openair3/S1AP/s1ap_eNB.h>
|
||||
#include <openair3/NGAP/ngap_gNB.h>
|
||||
|
||||
#ifdef ITTI_SIM
|
||||
|
||||
Executable
+48
@@ -0,0 +1,48 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">Running L3 ITTI simulator</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
This page is valid on the following branches:
|
||||
|
||||
- `develop` starting from tag `2020.w48`
|
||||
|
||||
# 1. Building the ITTI simulator.
|
||||
|
||||
The ITTI simulator is available directly from the standard build.
|
||||
|
||||
```bash
|
||||
$ source oaienv
|
||||
$ cd cmake_targets
|
||||
$ sudo ./build_oai -x -w None -c -ittiSIM
|
||||
```
|
||||
|
||||
# 2. Running the ITTI simulator.
|
||||
|
||||
The ITTI simulator establishes ITTI-threaded communication between the gNB RRC task and the UE RRC task.
|
||||
|
||||
This allows to test the sequence of NGAP/RRC/NAS messages.
|
||||
|
||||
The main limitations are:
|
||||
|
||||
- NAS is a simple stub that just sends and receives messages
|
||||
- only initial Attach sequence
|
||||
|
||||
## 2.1. Starting the ITTI simulator
|
||||
|
||||
The ITTI simulator is able to run with a connected 5GC or without any.
|
||||
The develop branch tag `2020.w48` only works RRC without 5GC connection.
|
||||
|
||||
```bash
|
||||
$ sudo -E ./ran_build/build/nr-ittisim -O gnb.conf
|
||||
```
|
||||
|
||||
@@ -125,6 +125,32 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gtpv1u_create_ngu_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_gnb_create_tunnel_req_t * const create_tunnel_req_pP,
|
||||
gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gtpv1u_update_ngu_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP,
|
||||
const rnti_t prior_rnti
|
||||
){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void config_common(int Mod_idP,
|
||||
int pdsch_AntennaPorts,
|
||||
NR_ServingCellConfigCommon_t *scc
|
||||
|
||||
@@ -99,6 +99,32 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gtpv1u_create_ngu_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_gnb_create_tunnel_req_t * const create_tunnel_req_pP,
|
||||
gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gtpv1u_update_ngu_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP,
|
||||
const rnti_t prior_rnti
|
||||
){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;}
|
||||
|
||||
// Dummy function to avoid linking error at compilation of nr-prachsim
|
||||
|
||||
@@ -122,6 +122,32 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gtpv1u_create_ngu_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_gnb_create_tunnel_req_t * const create_tunnel_req_pP,
|
||||
gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gtpv1u_update_ngu_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP,
|
||||
const rnti_t prior_rnti
|
||||
){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Dummy function to avoid linking error at compilation of nr-ulsim
|
||||
int is_x2ap_enabled(void)
|
||||
{
|
||||
|
||||
@@ -30,3 +30,7 @@ MESSAGE_DEF(GTPV1U_ENB_DATA_FORWARDING_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_dat
|
||||
MESSAGE_DEF(GTPV1U_ENB_END_MARKER_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_req_t, Gtpv1uEndMarkerReq)
|
||||
MESSAGE_DEF(GTPV1U_ENB_END_MARKER_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_ind_t, Gtpv1uEndMarkerInd)
|
||||
MESSAGE_DEF(GTPV1U_ENB_S1_REQ, MESSAGE_PRIORITY_MED, Gtpv1uS1Req, gtpv1uS1Req)
|
||||
|
||||
MESSAGE_DEF(GTPV1U_GNB_DELETE_TUNNEL_REQ, MESSAGE_PRIORITY_MED, gtpv1u_gnb_delete_tunnel_req_t, NRGtpv1uDeleteTunnelReq)
|
||||
MESSAGE_DEF(GTPV1U_GNB_DELETE_TUNNEL_RESP, MESSAGE_PRIORITY_MED, gtpv1u_gnb_delete_tunnel_resp_t, NRGtpv1uDeleteTunnelResp)
|
||||
MESSAGE_DEF(GTPV1U_GNB_NG_REQ, MESSAGE_PRIORITY_MED, Gtpv1uNGReq, gtpv1uNGReq)
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
|
||||
#define GTPV1U_MAX_BEARERS_PER_UE max_val_LTE_DRB_Identity
|
||||
#define NR_GTPV1U_MAX_BEARERS_PER_UE max_val_NR_DRB_Identity
|
||||
|
||||
#define GTPV1U_ENB_UPDATE_TUNNEL_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uUpdateTunnelReq
|
||||
#define GTPV1U_ENB_UPDATE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uUpdateTunnelResp
|
||||
@@ -40,6 +41,10 @@
|
||||
|
||||
#define GTPV1U_ENB_S1_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uS1Req
|
||||
|
||||
#define GTPV1U_GNB_DELETE_TUNNEL_REQ(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uDeleteTunnelReq
|
||||
#define GTPV1U_GNB_DELETE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uDeleteTunnelResp
|
||||
#define GTPV1U_GNB_NG_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uNGReq
|
||||
|
||||
#define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF
|
||||
|
||||
typedef struct gtpv1u_enb_create_x2u_tunnel_req_s {
|
||||
@@ -172,4 +177,37 @@ typedef struct {
|
||||
tcp_udp_port_t enb_port_for_S1u_S12_S4_up;
|
||||
} Gtpv1uS1Req;
|
||||
|
||||
typedef struct {
|
||||
in_addr_t gnb_ip_address_for_NGu_up;
|
||||
tcp_udp_port_t gnb_port_for_NGu_up;
|
||||
} Gtpv1uNGReq;
|
||||
typedef struct gtpv1u_gnb_create_tunnel_req_s {
|
||||
rnti_t rnti;
|
||||
int num_tunnels;
|
||||
teid_t upf_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
|
||||
pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
transport_layer_addr_t upf_addr[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
} gtpv1u_gnb_create_tunnel_req_t;
|
||||
|
||||
typedef struct gtpv1u_gnb_create_tunnel_resp_s {
|
||||
uint8_t status; ///< Status of S1U endpoint creation (Failed = 0xFF or Success = 0x0)
|
||||
rnti_t rnti;
|
||||
int num_tunnels;
|
||||
teid_t gnb_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
|
||||
pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
transport_layer_addr_t gnb_addr;
|
||||
} gtpv1u_gnb_create_tunnel_resp_t;
|
||||
|
||||
typedef struct gtpv1u_gnb_delete_tunnel_req_s {
|
||||
rnti_t rnti;
|
||||
uint8_t num_pdusession;
|
||||
pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
} gtpv1u_gnb_delete_tunnel_req_t;
|
||||
|
||||
typedef struct gtpv1u_gnb_delete_tunnel_resp_s {
|
||||
rnti_t rnti;
|
||||
uint8_t status; ///< Status of NGU endpoint deleteion (Failed = 0xFF or Success = 0x0)
|
||||
teid_t gnb_NGu_teid; ///< local NGU Tunnel Endpoint Identifier to be deleted
|
||||
} gtpv1u_gnb_delete_tunnel_resp_t;
|
||||
|
||||
#endif /* GTPV1_U_MESSAGES_TYPES_H_ */
|
||||
|
||||
@@ -263,8 +263,8 @@ typedef struct ngap_transport_layer_addr_s {
|
||||
} while (0)
|
||||
|
||||
typedef struct pdusession_level_qos_parameter_s {
|
||||
uint8_t qci;
|
||||
|
||||
uint8_t qfi;
|
||||
uint64_t fiveQI;
|
||||
ngap_allocation_retention_priority_t allocation_retention_priority;
|
||||
} pdusession_level_qos_parameter_t;
|
||||
|
||||
@@ -291,7 +291,7 @@ typedef enum pdusession_qosflow_mapping_ind_e{
|
||||
}pdusession_qosflow_mapping_ind_t;
|
||||
|
||||
typedef struct pdusession_associate_qosflow_s{
|
||||
uint8_t qci;
|
||||
uint8_t qfi;
|
||||
pdusession_qosflow_mapping_ind_t qos_flow_mapping_ind;
|
||||
}pdusession_associate_qosflow_t;
|
||||
|
||||
@@ -738,10 +738,23 @@ typedef struct ngap_ue_release_command_s {
|
||||
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// NGAP <-- RRC messages
|
||||
typedef struct pdusession_release_s {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
uint8_t pdusession_id;
|
||||
/* Octet string data */
|
||||
uint8_t *transfer_buffer;
|
||||
/* Length of the octet string */
|
||||
uint32_t transfer_length;
|
||||
} pdusession_release_t;
|
||||
|
||||
typedef struct ngap_ue_release_req_s {
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
ngap_Cause_t cause;
|
||||
long cause_value;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
/* Number of pdusession resource in the list */
|
||||
uint8_t nb_of_pdusessions;
|
||||
/* list of pdusession resource by RRC layers */
|
||||
pdusession_release_t pdusessions[NGAP_MAX_PDUSESSION];
|
||||
ngap_Cause_t cause;
|
||||
long cause_value;
|
||||
} ngap_ue_release_req_t, ngap_ue_release_resp_t;
|
||||
|
||||
typedef struct ngap_pdusession_modify_req_s {
|
||||
@@ -775,11 +788,6 @@ typedef struct ngap_pdusession_modify_resp_s {
|
||||
pdusession_failed_t pdusessions_failed[NGAP_MAX_PDUSESSION];
|
||||
} ngap_pdusession_modify_resp_t;
|
||||
|
||||
typedef struct pdusession_release_s {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
uint8_t pdusession_id;
|
||||
} pdusession_release_t;
|
||||
|
||||
typedef struct ngap_pdusession_release_command_s {
|
||||
/* AMF UE id */
|
||||
uint64_t amf_ue_ngap_id:40;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "LTE_asn_constant.h"
|
||||
#include "NR_asn_constant.h"
|
||||
|
||||
#ifndef __PLATFORM_CONSTANTS_H__
|
||||
# define __PLATFORM_CONSTANTS_H__
|
||||
@@ -103,6 +104,7 @@
|
||||
#define DEFAULT_RAB_ID 1
|
||||
|
||||
#define NB_RB_MAX (LTE_maxDRB + 3) /* was 11, now 14, maxDRB comes from asn1_constants.h, + 3 because of 3 SRB, one invisible id 0, then id 1 and 2 */
|
||||
#define NR_NB_RB_MAX (NR_maxDRB + 3)
|
||||
|
||||
#define NB_RB_MBMS_MAX (LTE_maxSessionPerPMCH*LTE_maxServiceCount)
|
||||
|
||||
|
||||
@@ -225,7 +225,7 @@ typedef enum config_action_e {
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef uint32_t teid_t; // tunnel endpoint identifier
|
||||
typedef uint8_t ebi_t; // eps bearer id
|
||||
|
||||
typedef uint8_t pdusessionid_t;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -726,19 +726,19 @@ int RCconfig_nr_gtpu(void ) {
|
||||
|
||||
if (address) {
|
||||
MessageDef *message;
|
||||
AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_ENB_S1_REQ))!=NULL,"");
|
||||
// IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
|
||||
// LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up);
|
||||
|
||||
|
||||
if (gnb_mode == 1) { // NSA
|
||||
AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_ENB_S1_REQ))!=NULL,"");
|
||||
// IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
|
||||
// LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up);
|
||||
IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
|
||||
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up);
|
||||
GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U;
|
||||
} else {// TODO SA
|
||||
IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR gNB NG_U !\n" );
|
||||
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up);
|
||||
GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_NGU;
|
||||
AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_GNB_NG_REQ))!=NULL,"");
|
||||
IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_GNB_NG_REQ(message).gnb_ip_address_for_NGu_up, "BAD IP ADDRESS FORMAT FOR gNB NG_U !\n" );
|
||||
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_GNB_NG_REQ(message).gnb_ip_address_for_NGu_up);
|
||||
GTPV1U_GNB_NG_REQ(message).gnb_port_for_NGu_up = gnb_port_for_NGU;
|
||||
}
|
||||
|
||||
itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
|
||||
|
||||
@@ -525,6 +525,7 @@ typedef struct gNB_MAC_INST_s {
|
||||
|
||||
/// UL handle
|
||||
uint32_t ul_handle;
|
||||
//UE_info_t UE_info;
|
||||
|
||||
// MAC function execution peformance profiler
|
||||
/// processing time of eNB scheduler
|
||||
|
||||
@@ -68,6 +68,8 @@
|
||||
#include "NR_SDAP-Config.h"
|
||||
#include "NR_RRCReconfigurationComplete.h"
|
||||
#include "NR_RRCReconfigurationComplete-IEs.h"
|
||||
#include "NR_DLInformationTransfer.h"
|
||||
#include "NR_RRCReestablishmentRequest.h"
|
||||
#include "PHY/defs_nr_common.h"
|
||||
#if defined(NR_Rel16)
|
||||
#include "NR_SCS-SpecificCarrier.h"
|
||||
@@ -929,7 +931,7 @@ uint8_t do_RRCSetup(const protocol_ctxt_t *const ctxt_pP,
|
||||
int CC_id,
|
||||
uint8_t *const buffer,
|
||||
const uint8_t transaction_id,
|
||||
NR_SRB_ToAddModList_t *SRB_configList)
|
||||
NR_SRB_ToAddModList_t **SRB_configList)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
asn_enc_rval_t enc_rval;;
|
||||
@@ -961,19 +963,19 @@ uint8_t do_RRCSetup(const protocol_ctxt_t *const ctxt_pP,
|
||||
|
||||
/****************************** radioBearerConfig ******************************/
|
||||
/* Configure SRB1 */
|
||||
if (SRB_configList) {
|
||||
free(SRB_configList);
|
||||
if (*SRB_configList) {
|
||||
free(*SRB_configList);
|
||||
}
|
||||
|
||||
SRB_configList = calloc(1, sizeof(NR_SRB_ToAddModList_t));
|
||||
*SRB_configList = calloc(1, sizeof(NR_SRB_ToAddModList_t));
|
||||
// SRB1
|
||||
/* TODO */
|
||||
SRB1_config = calloc(1, sizeof(NR_SRB_ToAddMod_t));
|
||||
SRB1_config->srb_Identity = 1;
|
||||
// pdcp_Config->t_Reordering
|
||||
SRB1_config->pdcp_Config = pdcp_Config;
|
||||
ie->radioBearerConfig.srb_ToAddModList = SRB_configList;
|
||||
ASN_SEQUENCE_ADD(&SRB_configList->list, SRB1_config);
|
||||
ie->radioBearerConfig.srb_ToAddModList = *SRB_configList;
|
||||
ASN_SEQUENCE_ADD(&(*SRB_configList)->list, SRB1_config);
|
||||
|
||||
ie->radioBearerConfig.srb3_ToRelease = NULL;
|
||||
ie->radioBearerConfig.drb_ToAddModList = NULL;
|
||||
@@ -1196,8 +1198,8 @@ uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
}
|
||||
|
||||
|
||||
uint8_t do_NR_RRCConnectionRelease(uint8_t *buffer,
|
||||
uint8_t Transaction_id) {
|
||||
uint8_t do_NR_RRCRelease(uint8_t *buffer,
|
||||
uint8_t Transaction_id) {
|
||||
asn_enc_rval_t enc_rval;
|
||||
NR_DL_DCCH_Message_t dl_dcch_msg;
|
||||
NR_RRCRelease_t *rrcConnectionRelease;
|
||||
@@ -1205,12 +1207,19 @@ uint8_t do_NR_RRCConnectionRelease(uint8_t *buffer,
|
||||
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
|
||||
dl_dcch_msg.message.choice.c1=CALLOC(1,sizeof(struct NR_DL_DCCH_MessageType__c1));
|
||||
dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcRelease;
|
||||
dl_dcch_msg.message.choice.c1->choice.rrcRelease = CALLOC(1, sizeof(struct NR_RRCRelease));
|
||||
dl_dcch_msg.message.choice.c1->choice.rrcRelease = CALLOC(1, sizeof(NR_RRCRelease_t));
|
||||
rrcConnectionRelease = dl_dcch_msg.message.choice.c1->choice.rrcRelease;
|
||||
// RRCConnectionRelease
|
||||
rrcConnectionRelease->rrc_TransactionIdentifier = Transaction_id;
|
||||
rrcConnectionRelease->criticalExtensions.present = NR_RRCRelease__criticalExtensions_PR_rrcRelease;
|
||||
rrcConnectionRelease->criticalExtensions.choice.rrcRelease = NULL;
|
||||
rrcConnectionRelease->criticalExtensions.choice.rrcRelease = CALLOC(1, sizeof(NR_RRCRelease_IEs_t));
|
||||
rrcConnectionRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq =
|
||||
CALLOC(1, sizeof(struct NR_RRCRelease_IEs__deprioritisationReq));
|
||||
rrcConnectionRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType =
|
||||
NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_nr;
|
||||
rrcConnectionRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer =
|
||||
NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min10;
|
||||
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message,
|
||||
NULL,
|
||||
(void *)&dl_dcch_msg,
|
||||
@@ -1224,26 +1233,25 @@ uint8_t do_NR_RRCConnectionRelease(uint8_t *buffer,
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
uint16_t do_RRCReconfiguration(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t *buffer,
|
||||
uint8_t Transaction_id,
|
||||
gNB_RRC_INST *gnb_rrc_inst
|
||||
)
|
||||
uint8_t Transaction_id,
|
||||
NR_SRB_ToAddModList_t *SRB_configList,
|
||||
NR_DRB_ToAddModList_t *DRB_configList,
|
||||
NR_DRB_ToReleaseList_t *DRB_releaseList,
|
||||
NR_SecurityConfig_t *security_config,
|
||||
NR_SDAP_Config_t *sdap_config,
|
||||
NR_MeasConfig_t *meas_config,
|
||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
|
||||
*dedicatedNAS_MessageList,
|
||||
NR_MAC_CellGroupConfig_t *mac_CellGroupConfig)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
NR_DL_DCCH_Message_t dl_dcch_msg;
|
||||
asn_enc_rval_t enc_rval;
|
||||
NR_RRCReconfiguration_IEs_t *ie;
|
||||
NR_SRB_ToAddModList_t *SRB_configList = NULL;
|
||||
NR_SRB_ToAddModList_t *SRB_configList2 = NULL;
|
||||
NR_SRB_ToAddMod_t *SRB2_config = NULL;
|
||||
NR_DRB_ToAddModList_t *DRB_configList = NULL;
|
||||
NR_DRB_ToAddModList_t *DRB_configList2 = NULL;
|
||||
NR_DRB_ToAddMod_t *DRB_config = NULL;
|
||||
NR_SDAP_Config_t *sdap_config = NULL;
|
||||
NR_SecurityConfig_t *security_config = NULL;
|
||||
NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL;
|
||||
|
||||
memset(&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t));
|
||||
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
|
||||
@@ -1255,73 +1263,6 @@ uint16_t do_RRCReconfiguration(
|
||||
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
|
||||
|
||||
/******************** Radio Bearer Config ********************/
|
||||
/* Configure SRB2 */
|
||||
SRB_configList2 = ue_context_pP->ue_context.SRB_configList2[Transaction_id];
|
||||
SRB_configList = ue_context_pP->ue_context.SRB_configList;
|
||||
SRB_configList = CALLOC(1, sizeof(*SRB_configList));
|
||||
memset(SRB_configList, 0, sizeof(*SRB_configList));
|
||||
|
||||
if (SRB_configList2) {
|
||||
free(SRB_configList2);
|
||||
}
|
||||
|
||||
SRB_configList2 = CALLOC(1, sizeof(*SRB_configList2));
|
||||
memset(SRB_configList2, 0, sizeof(*SRB_configList2));
|
||||
SRB2_config = CALLOC(1, sizeof(*SRB2_config));
|
||||
SRB2_config->srb_Identity = 2;
|
||||
ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
|
||||
ASN_SEQUENCE_ADD(&SRB_configList2->list, SRB2_config);
|
||||
|
||||
/* Configure DRB */
|
||||
DRB_configList = ue_context_pP->ue_context.DRB_configList;
|
||||
if (DRB_configList) {
|
||||
free(DRB_configList);
|
||||
}
|
||||
|
||||
DRB_configList = CALLOC(1, sizeof(*DRB_configList));
|
||||
memset(DRB_configList, 0, sizeof(*DRB_configList));
|
||||
|
||||
DRB_configList2 = ue_context_pP->ue_context.DRB_configList2[Transaction_id];
|
||||
if (DRB_configList2) {
|
||||
free(DRB_configList2);
|
||||
}
|
||||
DRB_configList2 = CALLOC(1, sizeof(*DRB_configList2));
|
||||
memset(DRB_configList2, 0, sizeof(*DRB_configList2));
|
||||
|
||||
DRB_config = CALLOC(1, sizeof(*DRB_config));
|
||||
DRB_config->drb_Identity = 1;
|
||||
DRB_config->cnAssociation = CALLOC(1, sizeof(*DRB_config->cnAssociation));
|
||||
DRB_config->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
|
||||
// TODO sdap_Config
|
||||
sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
|
||||
memset(sdap_config, 0, sizeof(NR_SDAP_Config_t));
|
||||
DRB_config->cnAssociation->choice.sdap_Config = sdap_config;
|
||||
// TODO pdcp_Config
|
||||
DRB_config->reestablishPDCP = NULL;
|
||||
DRB_config->recoverPDCP = NULL;
|
||||
DRB_config->pdcp_Config = calloc(1, sizeof(*DRB_config->pdcp_Config));
|
||||
DRB_config->pdcp_Config->drb = calloc(1,sizeof(*DRB_config->pdcp_Config->drb));
|
||||
DRB_config->pdcp_Config->drb->discardTimer = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->discardTimer));
|
||||
*DRB_config->pdcp_Config->drb->discardTimer = NR_PDCP_Config__drb__discardTimer_ms30;
|
||||
DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL));
|
||||
*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
|
||||
DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL));
|
||||
*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
|
||||
DRB_config->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
|
||||
DRB_config->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
|
||||
|
||||
DRB_config->pdcp_Config->drb->integrityProtection = NULL;
|
||||
DRB_config->pdcp_Config->drb->statusReportRequired = NULL;
|
||||
DRB_config->pdcp_Config->drb->outOfOrderDelivery = NULL;
|
||||
DRB_config->pdcp_Config->moreThanOneRLC = NULL;
|
||||
|
||||
DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering));
|
||||
*DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0;
|
||||
DRB_config->pdcp_Config->ext1 = NULL;
|
||||
|
||||
ASN_SEQUENCE_ADD(&DRB_configList->list, DRB_config);
|
||||
ASN_SEQUENCE_ADD(&DRB_configList2->list, DRB_config);
|
||||
|
||||
/* Configure Security */
|
||||
// security_config = CALLOC(1, sizeof(NR_SecurityConfig_t));
|
||||
// security_config->securityAlgorithmConfig = CALLOC(1, sizeof(*ie->radioBearerConfig->securityConfig->securityAlgorithmConfig));
|
||||
@@ -1336,7 +1277,7 @@ uint16_t do_RRCReconfiguration(
|
||||
ie->radioBearerConfig->drb_ToAddModList = DRB_configList;
|
||||
ie->radioBearerConfig->securityConfig = security_config;
|
||||
ie->radioBearerConfig->srb3_ToRelease = NULL;
|
||||
ie->radioBearerConfig->drb_ToReleaseList = NULL;
|
||||
ie->radioBearerConfig->drb_ToReleaseList = DRB_releaseList;
|
||||
|
||||
/******************** Secondary Cell Group ********************/
|
||||
// rrc_gNB_carrier_data_t *carrier = &(gnb_rrc_inst->carrier);
|
||||
@@ -1349,16 +1290,12 @@ uint16_t do_RRCReconfiguration(
|
||||
|
||||
/******************** Meas Config ********************/
|
||||
// measConfig
|
||||
ie->measConfig = NULL;
|
||||
ie->measConfig = meas_config;
|
||||
// lateNonCriticalExtension
|
||||
ie->lateNonCriticalExtension = NULL;
|
||||
// nonCriticalExtension
|
||||
ie->nonCriticalExtension = calloc(1, sizeof(NR_RRCReconfiguration_v1530_IEs_t));
|
||||
dedicatedNAS_Message = calloc(1, sizeof(NR_DedicatedNAS_Message_t));
|
||||
dedicatedNAS_Message->buf = ue_context_pP->ue_context.nas_pdu.buffer;
|
||||
dedicatedNAS_Message->size = ue_context_pP->ue_context.nas_pdu.length;
|
||||
ie->nonCriticalExtension->dedicatedNAS_MessageList = calloc(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
|
||||
ASN_SEQUENCE_ADD(&ie->nonCriticalExtension->dedicatedNAS_MessageList->list, dedicatedNAS_Message);
|
||||
ie->nonCriticalExtension->dedicatedNAS_MessageList = dedicatedNAS_MessageList;
|
||||
|
||||
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration = ie;
|
||||
|
||||
@@ -1534,7 +1471,263 @@ LOG_D(NR_RRC,"RRCSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
int do_DLInformationTransfer_NR (void * p) {
|
||||
return 0;
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t
|
||||
do_NR_DLInformationTransfer(
|
||||
uint8_t Mod_id,
|
||||
uint8_t **buffer,
|
||||
uint8_t transaction_id,
|
||||
uint32_t pdu_length,
|
||||
uint8_t *pdu_buffer
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
ssize_t encoded;
|
||||
NR_DL_DCCH_Message_t dl_dcch_msg;
|
||||
memset(&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t));
|
||||
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
|
||||
dl_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_DL_DCCH_MessageType__c1));
|
||||
dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer;
|
||||
|
||||
dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer = CALLOC(1, sizeof(NR_DLInformationTransfer_t));
|
||||
dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->rrc_TransactionIdentifier = transaction_id;
|
||||
dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->criticalExtensions.present =
|
||||
NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer;
|
||||
|
||||
dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->
|
||||
criticalExtensions.choice.dlInformationTransfer = CALLOC(1, sizeof(NR_DLInformationTransfer_IEs_t));
|
||||
dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->
|
||||
criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
|
||||
dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->
|
||||
criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message->buf = pdu_buffer;
|
||||
dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->
|
||||
criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message->size = pdu_length;
|
||||
|
||||
encoded = uper_encode_to_new_buffer (&asn_DEF_NR_DL_DCCH_Message, NULL, (void *) &dl_dcch_msg, (void **)buffer);
|
||||
AssertFatal(encoded > 0,"ASN1 message encoding failed (%s, %ld)!\n",
|
||||
"DLInformationTransfer", encoded);
|
||||
LOG_D(NR_RRC,"DLInformationTransfer Encoded %zd bytes\n", encoded);
|
||||
return encoded;
|
||||
}
|
||||
|
||||
uint8_t do_NR_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer) {
|
||||
ssize_t encoded;
|
||||
NR_UL_DCCH_Message_t ul_dcch_msg;
|
||||
memset(&ul_dcch_msg, 0, sizeof(NR_UL_DCCH_Message_t));
|
||||
ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
|
||||
ul_dcch_msg.message.choice.c1 = CALLOC(1,sizeof(struct NR_UL_DCCH_MessageType__c1));
|
||||
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer;
|
||||
ul_dcch_msg.message.choice.c1->choice.ulInformationTransfer = CALLOC(1,sizeof(struct NR_ULInformationTransfer));
|
||||
ul_dcch_msg.message.choice.c1->choice.ulInformationTransfer->criticalExtensions.present = NR_ULInformationTransfer__criticalExtensions_PR_ulInformationTransfer;
|
||||
ul_dcch_msg.message.choice.c1->choice.ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer = CALLOC(1,sizeof(struct NR_ULInformationTransfer_IEs));
|
||||
struct NR_ULInformationTransfer_IEs *ulInformationTransfer = ul_dcch_msg.message.choice.c1->choice.ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer;
|
||||
ulInformationTransfer->dedicatedNAS_Message = CALLOC(1,sizeof(NR_DedicatedNAS_Message_t));
|
||||
ulInformationTransfer->dedicatedNAS_Message->buf = pdu_buffer;
|
||||
ulInformationTransfer->dedicatedNAS_Message->size = pdu_length;
|
||||
ulInformationTransfer->lateNonCriticalExtension = NULL;
|
||||
encoded = uper_encode_to_new_buffer (&asn_DEF_NR_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, (void **) buffer);
|
||||
AssertFatal(encoded > 0,"ASN1 message encoding failed (%s, %ld)!\n",
|
||||
"ULInformationTransfer",encoded);
|
||||
LOG_D(NR_RRC,"ULInformationTransfer Encoded %zd bytes\n",encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c_rnti) {
|
||||
asn_enc_rval_t enc_rval;
|
||||
NR_UL_CCCH_Message_t ul_ccch_msg;
|
||||
NR_RRCReestablishmentRequest_t *rrcReestablishmentRequest;
|
||||
uint8_t buf[2];
|
||||
|
||||
memset((void *)&ul_ccch_msg,0,sizeof(NR_UL_CCCH_Message_t));
|
||||
ul_ccch_msg.message.present = NR_UL_CCCH_MessageType_PR_c1;
|
||||
ul_ccch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_CCCH_MessageType__c1));
|
||||
ul_ccch_msg.message.choice.c1->present = NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest;
|
||||
ul_ccch_msg.message.choice.c1->choice.rrcReestablishmentRequest = CALLOC(1, sizeof(NR_RRCReestablishmentRequest_t));
|
||||
|
||||
rrcReestablishmentRequest = ul_ccch_msg.message.choice.c1->choice.rrcReestablishmentRequest;
|
||||
// test
|
||||
rrcReestablishmentRequest->rrcReestablishmentRequest.reestablishmentCause = NR_ReestablishmentCause_reconfigurationFailure;
|
||||
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.c_RNTI = c_rnti;
|
||||
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.physCellId = 0;
|
||||
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf = buf;
|
||||
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[0] = 0x08;
|
||||
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[1] = 0x32;
|
||||
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.size = 2;
|
||||
|
||||
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_ccch_msg);
|
||||
}
|
||||
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_CCCH_Message,
|
||||
NULL,
|
||||
(void *)&ul_ccch_msg,
|
||||
buffer,
|
||||
100);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
|
||||
LOG_D(NR_RRC,"[UE] RRCReestablishmentRequest Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t
|
||||
do_RRCReestablishment(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
int CC_id,
|
||||
uint8_t *const buffer,
|
||||
//const uint8_t transmission_mode,
|
||||
const uint8_t Transaction_id,
|
||||
NR_SRB_ToAddModList_t **SRB_configList
|
||||
) {
|
||||
asn_enc_rval_t enc_rval;
|
||||
//long *logicalchannelgroup = NULL;
|
||||
struct NR_SRB_ToAddMod *SRB1_config = NULL;
|
||||
struct NR_SRB_ToAddMod *SRB2_config = NULL;
|
||||
//gNB_RRC_INST *nrrrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
NR_DL_DCCH_Message_t dl_dcch_msg;
|
||||
NR_RRCReestablishment_t *rrcReestablishment = NULL;
|
||||
int i = 0;
|
||||
ue_context_pP->ue_context.reestablishment_xid = Transaction_id;
|
||||
NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
|
||||
SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id];
|
||||
|
||||
if (*SRB_configList2) {
|
||||
free(*SRB_configList2);
|
||||
}
|
||||
|
||||
*SRB_configList2 = CALLOC(1, sizeof(NR_SRB_ToAddModList_t));
|
||||
memset((void *)&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t));
|
||||
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
|
||||
dl_dcch_msg.message.choice.c1 = calloc(1,sizeof(struct NR_DL_DCCH_MessageType__c1));
|
||||
dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment;
|
||||
dl_dcch_msg.message.choice.c1->choice.rrcReestablishment = CALLOC(1,sizeof(NR_RRCReestablishment_t));
|
||||
rrcReestablishment = dl_dcch_msg.message.choice.c1->choice.rrcReestablishment;
|
||||
|
||||
// get old configuration of SRB2
|
||||
if (*SRB_configList != NULL) {
|
||||
for (i = 0; (i < (*SRB_configList)->list.count) && (i < 3); i++) {
|
||||
LOG_D(NR_RRC, "(*SRB_configList)->list.array[%d]->srb_Identity=%ld\n",
|
||||
i, (*SRB_configList)->list.array[i]->srb_Identity);
|
||||
|
||||
if ((*SRB_configList)->list.array[i]->srb_Identity == 2 ) {
|
||||
SRB2_config = (*SRB_configList)->list.array[i];
|
||||
} else if ((*SRB_configList)->list.array[i]->srb_Identity == 1 ) {
|
||||
SRB1_config = (*SRB_configList)->list.array[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SRB1_config == NULL) {
|
||||
// default SRB1 configuration
|
||||
LOG_W(NR_RRC,"SRB1 configuration does not exist in SRB configuration list, use default\n");
|
||||
/// SRB1
|
||||
SRB1_config = CALLOC(1, sizeof(*SRB1_config));
|
||||
SRB1_config->srb_Identity = 1;
|
||||
}
|
||||
|
||||
if (SRB2_config == NULL) {
|
||||
LOG_W(NR_RRC,"SRB2 configuration does not exist in SRB configuration list\n");
|
||||
} else {
|
||||
ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
|
||||
}
|
||||
|
||||
if (*SRB_configList) {
|
||||
free(*SRB_configList);
|
||||
}
|
||||
|
||||
*SRB_configList = CALLOC(1, sizeof(LTE_SRB_ToAddModList_t));
|
||||
ASN_SEQUENCE_ADD(&(*SRB_configList)->list,SRB1_config);
|
||||
|
||||
rrcReestablishment->rrc_TransactionIdentifier = Transaction_id;
|
||||
rrcReestablishment->criticalExtensions.present = NR_RRCReestablishment__criticalExtensions_PR_rrcReestablishment;
|
||||
rrcReestablishment->criticalExtensions.choice.rrcReestablishment = CALLOC(1,sizeof(NR_RRCReestablishment_IEs_t));
|
||||
|
||||
uint8_t KgNB_star[32] = { 0 };
|
||||
/** TODO
|
||||
uint16_t pci = nrrrc->carrier[CC_id].physCellId;
|
||||
uint32_t earfcn_dl = (uint32_t)freq_to_arfcn10(RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band,
|
||||
nrrrc->carrier[CC_id].dl_CarrierFreq);
|
||||
bool is_rel8_only = true;
|
||||
|
||||
if (earfcn_dl > 65535) {
|
||||
is_rel8_only = false;
|
||||
}
|
||||
LOG_D(NR_RRC, "pci=%d, eutra_band=%d, downlink_frequency=%d, earfcn_dl=%u, is_rel8_only=%s\n",
|
||||
pci,
|
||||
RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band,
|
||||
nrrrc->carrier[CC_id].dl_CarrierFreq,
|
||||
earfcn_dl,
|
||||
is_rel8_only == true ? "true": "false");
|
||||
*/
|
||||
|
||||
if (ue_context_pP->ue_context.nh_ncc >= 0) {
|
||||
//TODO derive_keNB_star(ue_context_pP->ue_context.nh, pci, earfcn_dl, is_rel8_only, KgNB_star);
|
||||
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount = ue_context_pP->ue_context.nh_ncc;
|
||||
} else { // first HO
|
||||
//TODO derive_keNB_star (ue_context_pP->ue_context.kgnb, pci, earfcn_dl, is_rel8_only, KgNB_star);
|
||||
// LG: really 1
|
||||
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount = 0;
|
||||
}
|
||||
// copy KgNB_star to ue_context_pP->ue_context.kgnb
|
||||
memcpy (ue_context_pP->ue_context.kgnb, KgNB_star, 32);
|
||||
ue_context_pP->ue_context.kgnb_ncc = 0;
|
||||
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->lateNonCriticalExtension = NULL;
|
||||
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nonCriticalExtension = NULL;
|
||||
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
|
||||
}
|
||||
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message,
|
||||
NULL,
|
||||
(void *)&dl_dcch_msg,
|
||||
buffer,
|
||||
100);
|
||||
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_D(NR_RRC,"RRCReestablishment Encoded %u bits (%u bytes)\n",
|
||||
(uint32_t)enc_rval.encoded, (uint32_t)(enc_rval.encoded+7)/8);
|
||||
return((enc_rval.encoded+7)/8);
|
||||
|
||||
}
|
||||
|
||||
uint8_t
|
||||
do_RRCReestablishmentComplete(uint8_t *buffer, int64_t rrc_TransactionIdentifier) {
|
||||
asn_enc_rval_t enc_rval;
|
||||
NR_UL_DCCH_Message_t ul_dcch_msg;
|
||||
NR_RRCReestablishmentComplete_t *rrcReestablishmentComplete;
|
||||
|
||||
memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
|
||||
ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
|
||||
ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1));
|
||||
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete;
|
||||
ul_dcch_msg.message.choice.c1->choice.rrcReestablishmentComplete = CALLOC(1, sizeof(NR_RRCReestablishmentComplete_t));
|
||||
|
||||
rrcReestablishmentComplete = ul_dcch_msg.message.choice.c1->choice.rrcReestablishmentComplete;
|
||||
rrcReestablishmentComplete->rrc_TransactionIdentifier = rrc_TransactionIdentifier;
|
||||
rrcReestablishmentComplete->criticalExtensions.present = NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete;
|
||||
rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete = CALLOC(1, sizeof(NR_RRCReestablishmentComplete_IEs_t));
|
||||
rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete->lateNonCriticalExtension = NULL;
|
||||
rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete->nonCriticalExtension = NULL;
|
||||
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_dcch_msg);
|
||||
}
|
||||
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message,
|
||||
NULL,
|
||||
(void *)&ul_dcch_msg,
|
||||
buffer,
|
||||
100);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
|
||||
LOG_D(NR_RRC,"[UE] RRCReestablishmentComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ uint8_t do_RRCSetup(const protocol_ctxt_t *const ctxt_pP,
|
||||
int CC_id,
|
||||
uint8_t *const buffer,
|
||||
const uint8_t transaction_id,
|
||||
NR_SRB_ToAddModList_t *SRB_configList);
|
||||
NR_SRB_ToAddModList_t **SRB_configList);
|
||||
uint8_t do_NR_SecurityModeCommand(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
@@ -103,14 +103,21 @@ uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
const uint8_t Transaction_id);
|
||||
|
||||
uint8_t do_NR_RRCConnectionRelease(uint8_t *buffer,
|
||||
uint8_t Transaction_id);
|
||||
uint8_t do_NR_RRCRelease(uint8_t *buffer,
|
||||
uint8_t Transaction_id);
|
||||
uint16_t do_RRCReconfiguration(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t *buffer,
|
||||
uint8_t Transaction_id,
|
||||
gNB_RRC_INST *gnb_rrc_inst);
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *buffer,
|
||||
uint8_t Transaction_id,
|
||||
NR_SRB_ToAddModList_t *SRB_configList,
|
||||
NR_DRB_ToAddModList_t *DRB_configList,
|
||||
NR_DRB_ToReleaseList_t *DRB_releaseList,
|
||||
NR_SecurityConfig_t *security_config,
|
||||
NR_SDAP_Config_t *sdap_config,
|
||||
NR_MeasConfig_t *meas_config,
|
||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
|
||||
*dedicatedNAS_MessageList,
|
||||
NR_MAC_CellGroupConfig_t *mac_CellGroupConfig);
|
||||
|
||||
uint8_t do_RRCSetupComplete(uint8_t Mod_id,
|
||||
uint8_t *buffer,
|
||||
@@ -126,3 +133,35 @@ uint8_t do_NR_RRCReconfigurationComplete(
|
||||
uint8_t *buffer,
|
||||
const uint8_t Transaction_id
|
||||
);
|
||||
|
||||
uint8_t
|
||||
do_NR_DLInformationTransfer(
|
||||
uint8_t Mod_id,
|
||||
uint8_t **buffer,
|
||||
uint8_t transaction_id,
|
||||
uint32_t pdu_length,
|
||||
uint8_t *pdu_buffer
|
||||
);
|
||||
|
||||
uint8_t do_NR_ULInformationTransfer(uint8_t **buffer,
|
||||
uint32_t pdu_length,
|
||||
uint8_t *pdu_buffer);
|
||||
|
||||
uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c_rnti);
|
||||
|
||||
uint8_t
|
||||
do_RRCReestablishment(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
int CC_id,
|
||||
uint8_t *const buffer,
|
||||
//const uint8_t transmission_mode,
|
||||
const uint8_t Transaction_id,
|
||||
NR_SRB_ToAddModList_t **SRB_configList
|
||||
);
|
||||
|
||||
uint8_t
|
||||
do_RRCReestablishmentComplete(
|
||||
uint8_t *buffer,
|
||||
int64_t rrc_TransactionIdentifier);
|
||||
|
||||
|
||||
@@ -257,6 +257,24 @@ typedef struct nr_rrc_guami_s {
|
||||
uint8_t amf_pointer;
|
||||
} nr_rrc_guami_t;
|
||||
|
||||
typedef enum pdu_session_satus_e {
|
||||
PDU_SESSION_STATUS_NEW,
|
||||
PDU_SESSION_STATUS_DONE,
|
||||
PDU_SESSION_STATUS_ESTABLISHED,
|
||||
PDU_SESSION_STATUS_REESTABLISHED, // after HO
|
||||
PDU_SESSION_STATUS_TOMODIFY, // ENDC NSA
|
||||
PDU_SESSION_STATUS_FAILED,
|
||||
PDU_SESSION_STATUS_TORELEASE // to release DRB between eNB and UE
|
||||
} pdu_session_status_t;
|
||||
|
||||
typedef struct pdu_session_param_s {
|
||||
pdusession_t param;
|
||||
uint8_t status;
|
||||
uint8_t xid; // transaction_id
|
||||
ngap_Cause_t cause;
|
||||
uint8_t cause_value;
|
||||
} __attribute__ ((__packed__)) pdu_session_param_t;
|
||||
|
||||
typedef struct gNB_RRC_UE_s {
|
||||
uint8_t primaryCC_id;
|
||||
LTE_SCellToAddMod_r10_t sCell_config[2];
|
||||
@@ -308,7 +326,7 @@ typedef struct gNB_RRC_UE_s {
|
||||
NR_EstablishmentCause_t establishment_cause;
|
||||
|
||||
/* Information from UE RRC ConnectionReestablishmentRequest */
|
||||
NR_ReestablishmentCause_t reestablishment_cause;
|
||||
NR_ReestablishmentCause_t reestablishment_cause;
|
||||
|
||||
/* UE id for initial connection to S1AP */
|
||||
uint16_t ue_initial_id;
|
||||
@@ -325,30 +343,44 @@ typedef struct gNB_RRC_UE_s {
|
||||
uint8_t setup_e_rabs;
|
||||
/* Number of e_rab to be setup in the list */
|
||||
uint8_t nb_of_e_rabs;
|
||||
/* Total number of pdu session already setup in the list */
|
||||
uint8_t setup_pdu_sessions;
|
||||
/* Number of pdu session to be setup in the list */
|
||||
uint8_t nb_of_pdusessions;
|
||||
/* Number of e_rab to be modified in the list */
|
||||
uint8_t nb_of_modify_e_rabs;
|
||||
uint8_t nb_of_failed_e_rabs;
|
||||
e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
|
||||
/* list of e_rab to be setup by RRC layers */
|
||||
/* list of pdu session to be setup by RRC layers */
|
||||
e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
|
||||
pdu_session_param_t pdusession[NR_NB_RB_MAX];//[NGAP_MAX_PDU_SESSION];
|
||||
//release e_rabs
|
||||
uint8_t nb_release_of_e_rabs;
|
||||
e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB];
|
||||
uint8_t nb_release_of_pdusessions;
|
||||
pdusession_failed_t pdusessions_release_failed[NGAP_MAX_PDUSESSION];
|
||||
// LG: For GTPV1 TUNNELS
|
||||
uint32_t gnb_gtp_teid[S1AP_MAX_E_RAB];
|
||||
transport_layer_addr_t gnb_gtp_addrs[S1AP_MAX_E_RAB];
|
||||
rb_id_t gnb_gtp_ebi[S1AP_MAX_E_RAB];
|
||||
rb_id_t gnb_gtp_psi[S1AP_MAX_E_RAB];
|
||||
|
||||
uint32_t ul_failure_timer;
|
||||
uint32_t ue_release_timer;
|
||||
uint32_t ue_release_timer_thres;
|
||||
uint32_t ue_release_timer_s1;
|
||||
uint32_t ue_release_timer_thres_s1;
|
||||
uint32_t ue_release_timer_ng;
|
||||
uint32_t ue_release_timer_thres_ng;
|
||||
uint32_t ue_release_timer_rrc;
|
||||
uint32_t ue_release_timer_thres_rrc;
|
||||
uint32_t ue_reestablishment_timer;
|
||||
uint32_t ue_reestablishment_timer_thres;
|
||||
uint8_t e_rab_release_command_flag;
|
||||
uint8_t pdu_session_release_command_flag;
|
||||
uint32_t ue_rrc_inactivity_timer;
|
||||
int8_t reestablishment_xid;
|
||||
//------------------------------------------------------------------------------//
|
||||
NR_CellGroupId_t cellGroupId;
|
||||
struct NR_SpCellConfig *spCellConfig;
|
||||
@@ -408,6 +440,8 @@ typedef struct {
|
||||
NR_SRB_INFO SI;
|
||||
NR_SRB_INFO Srb0;
|
||||
int initial_csi_index[MAX_NR_RRC_UE_CONTEXTS];
|
||||
int physCellId;
|
||||
int p_gNB;
|
||||
|
||||
} rrc_gNB_carrier_data_t;
|
||||
//---------------------------------------------------
|
||||
@@ -425,6 +459,8 @@ typedef struct gNB_RRC_INST_s {
|
||||
int Nb_ue;
|
||||
hash_table_t *initial_id2_s1ap_ids; // key is content is rrc_ue_s1ap_ids_t
|
||||
hash_table_t *s1ap_id2_s1ap_ids ; // key is content is rrc_ue_s1ap_ids_t
|
||||
hash_table_t *initial_id2_ngap_ids;
|
||||
hash_table_t *ngap_id2_ngap_ids ;
|
||||
|
||||
// other PLMN parameters
|
||||
/// Mobile country code
|
||||
@@ -445,7 +481,6 @@ typedef struct gNB_RRC_INST_s {
|
||||
|
||||
} gNB_RRC_INST;
|
||||
|
||||
|
||||
#include "nr_rrc_proto.h" //should be put here otherwise compilation error
|
||||
|
||||
#endif
|
||||
|
||||
@@ -116,7 +116,11 @@ rrc_gNB_generate_UECapabilityEnquiry(
|
||||
rrc_gNB_ue_context_t *const ue_context_pP
|
||||
);
|
||||
|
||||
void nr_rrc_rx_tx(void);
|
||||
void
|
||||
rrc_gNB_generate_RRCRelease(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP
|
||||
);
|
||||
|
||||
/**\brief RRC eNB task.
|
||||
\param void *args_p Pointer on arguments to start the task. */
|
||||
@@ -147,3 +151,11 @@ nr_rrc_data_req(
|
||||
int
|
||||
nr_rrc_mac_remove_ue(module_id_t mod_idP,
|
||||
rnti_t rntiP);
|
||||
|
||||
void
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration_release(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t xid,
|
||||
uint32_t nas_length,
|
||||
uint8_t *nas_buffer);
|
||||
|
||||
Regular → Executable
+1130
-91
File diff suppressed because it is too large
Load Diff
@@ -92,3 +92,52 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
) {
|
||||
rnti_t rnti;
|
||||
int i;
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
|
||||
|
||||
if (create_tunnel_resp_pP) {
|
||||
LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
create_tunnel_resp_pP->num_tunnels);
|
||||
rnti = create_tunnel_resp_pP->rnti;
|
||||
ue_context_p = rrc_gNB_get_ue_context(
|
||||
RC.nrrrc[ctxt_pP->module_id],
|
||||
ctxt_pP->rnti);
|
||||
|
||||
for (i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
|
||||
ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->gnb_NGu_teid[i];
|
||||
ue_context_p->ue_context.gnb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->gnb_addr;
|
||||
ue_context_p->ue_context.gnb_gtp_psi[inde_list[i]] = create_tunnel_resp_pP->pdusession_id[i];
|
||||
LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
create_tunnel_resp_pP->gnb_NGu_teid[i],
|
||||
ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]],
|
||||
inde_list[i],
|
||||
i,
|
||||
create_tunnel_resp_pP->pdusession_id[i],
|
||||
create_tunnel_resp_pP->gnb_addr.length);
|
||||
}
|
||||
|
||||
MSC_LOG_RX_MESSAGE(
|
||||
MSC_RRC_GNB,
|
||||
MSC_GTPU_GNB,
|
||||
NULL,0,
|
||||
MSC_AS_TIME_FMT" CREATE_TUNNEL_RESP RNTI %"PRIx16" ntuns %u psid %u enb-s1u teid %u",
|
||||
0,0,rnti,
|
||||
create_tunnel_resp_pP->num_tunnels,
|
||||
ue_context_p->ue_context.gnb_gtp_psi[0],
|
||||
ue_context_p->ue_context.gnb_gtp_teid[0]);
|
||||
(void)rnti; /* avoid gcc warning "set but not used" */
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,3 +37,12 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
);
|
||||
|
||||
int
|
||||
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
+1008
-89
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,7 @@
|
||||
|
||||
#include "NR_RRCSetupComplete-IEs.h"
|
||||
#include "NR_RegisteredAMF.h"
|
||||
#include "NR_UL-DCCH-Message.h"
|
||||
|
||||
typedef struct rrc_ue_ngap_ids_s {
|
||||
/* Tree related data */
|
||||
@@ -77,4 +78,89 @@ rrc_gNB_process_security(
|
||||
ngap_security_capabilities_t *security_capabilities_pP
|
||||
);
|
||||
|
||||
int
|
||||
rrc_gNB_process_NGAP_DOWNLINK_NAS(
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
instance_t instance,
|
||||
mui_t *rrc_gNB_mui
|
||||
);
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_UPLINK_NAS(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
NR_UL_DCCH_Message_t *const ul_dcch_msg
|
||||
);
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t xid
|
||||
);
|
||||
|
||||
int
|
||||
rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
instance_t instance
|
||||
);
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(
|
||||
const module_id_t gnb_mod_idP,
|
||||
const rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const ngap_Cause_t causeP,
|
||||
const long cause_valueP
|
||||
);
|
||||
|
||||
int
|
||||
rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ (
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
instance_t instance
|
||||
);
|
||||
|
||||
int
|
||||
rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
instance_t instance
|
||||
);
|
||||
|
||||
void
|
||||
rrc_gNB_NGAP_remove_ue_ids(
|
||||
gNB_RRC_INST *const rrc_instance_pP,
|
||||
struct rrc_ue_ngap_ids_s *const ue_ids_pP
|
||||
);
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
NR_UL_DCCH_Message_t *const ul_dcch_msg
|
||||
);
|
||||
|
||||
int
|
||||
rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
instance_t instance
|
||||
);
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t xid
|
||||
);
|
||||
|
||||
void
|
||||
nr_rrc_pdcp_config_security(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const uint8_t send_security_mode_command
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -135,6 +135,7 @@ rrc_gNB_allocate_new_UE_context(
|
||||
|
||||
for(int i = 0; i < NB_RB_MAX; i++) {
|
||||
new_p->ue_context.e_rab[i].xid = -1;
|
||||
new_p->ue_context.pdusession[i].xid = -1;
|
||||
new_p->ue_context.modify_e_rab[i].xid = -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
|
||||
if (m->nb_e_rabs_tobeadded>0) {
|
||||
for (int i=0; i<m->nb_e_rabs_tobeadded; i++) {
|
||||
// Add the new E-RABs at the corresponding rrc ue context of the gNB
|
||||
// Add the new E-RABs at the corresponding rrc ue context of the gNB
|
||||
ue_context_p->ue_context.e_rab[i].param.e_rab_id = m->e_rabs_tobeadded[i].e_rab_id;
|
||||
ue_context_p->ue_context.e_rab[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid;
|
||||
memcpy(&ue_context_p->ue_context.e_rab[i].param.sgw_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t));
|
||||
|
||||
+402
-154
@@ -117,7 +117,17 @@ uint8_t do_NR_RRCReconfigurationComplete(
|
||||
const uint8_t Transaction_id
|
||||
);
|
||||
|
||||
void rrc_ue_generate_RRCReestablishmentRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index );
|
||||
|
||||
void
|
||||
nr_rrc_ue_generate_rrcReestablishmentComplete(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
NR_RRCReestablishment_t *rrcReestablishment,
|
||||
uint8_t gNB_index
|
||||
);
|
||||
|
||||
mui_t nr_rrc_mui=0;
|
||||
uint8_t first_rrcreconfigurationcomplete = 0;
|
||||
|
||||
static Rrc_State_NR_t nr_rrc_get_state (module_id_t ue_mod_idP) {
|
||||
return NR_UE_rrc_inst[ue_mod_idP].nrRrcState;
|
||||
@@ -995,7 +1005,7 @@ int nr_decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index
|
||||
if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)
|
||||
nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE );
|
||||
|
||||
LOG_I(RRC,"SIStatus %x, SIcnt %d/%d\n",
|
||||
LOG_I(NR_RRC,"SIStatus %x, SIcnt %d/%d\n",
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt,
|
||||
sib1->si_SchedulingInfo->schedulingInfoList.list.count);
|
||||
@@ -1162,7 +1172,7 @@ int nr_decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_inde
|
||||
) {
|
||||
/* PLMN match, send a confirmation to NAS */
|
||||
MessageDef *msg_p;
|
||||
msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, NAS_CELL_SELECTION_CNF);
|
||||
msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CELL_SELECTION_CNF);
|
||||
NAS_CELL_SELECTION_CNF (msg_p).errCode = AS_SUCCESS;
|
||||
NAS_CELL_SELECTION_CNF (msg_p).cellID = BIT_STRING_to_uint32(&sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity);
|
||||
NAS_CELL_SELECTION_CNF (msg_p).tac = BIT_STRING_to_uint16(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode);
|
||||
@@ -1180,7 +1190,7 @@ int nr_decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_inde
|
||||
if (cell_valid == 0) {
|
||||
/* Cell can not be used, ask PHY to try the next one */
|
||||
MessageDef *msg_p;
|
||||
msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, PHY_FIND_NEXT_CELL_REQ);
|
||||
msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, PHY_FIND_NEXT_CELL_REQ);
|
||||
itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p);
|
||||
LOG_E(RRC,
|
||||
"Synched with a cell, but PLMN doesn't match our SIM "
|
||||
@@ -1383,9 +1393,9 @@ static void rrc_ue_generate_RRCSetupComplete(
|
||||
#ifdef ITTI_SIM
|
||||
MessageDef *message_p;
|
||||
uint8_t *message_buffer;
|
||||
message_buffer = itti_malloc (TASK_RRC_UE_SIM, TASK_RRC_GNB_SIM, size);
|
||||
message_buffer = itti_malloc (TASK_RRC_NRUE, TASK_RRC_GNB_SIM, size);
|
||||
memcpy (message_buffer, buffer, size);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, UE_RRC_DCCH_DATA_IND);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
|
||||
UE_RRC_DCCH_DATA_IND (message_p).rbid = 1;
|
||||
UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
|
||||
UE_RRC_DCCH_DATA_IND (message_p).size = size;
|
||||
@@ -1394,84 +1404,85 @@ static void rrc_ue_generate_RRCSetupComplete(
|
||||
}
|
||||
|
||||
int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB_INFO *const Srb_info, const uint8_t gNB_index ){
|
||||
NR_DL_CCCH_Message_t *dl_ccch_msg=NULL;
|
||||
asn_dec_rval_t dec_rval;
|
||||
int rval=0;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN);
|
||||
// LOG_D(RRC,"[UE %d] Decoding DL-CCCH message (%d bytes), State %d\n",ue_mod_idP,Srb_info->Rx_buffer.payload_size,
|
||||
// NR_UE_rrc_inst[ue_mod_idP].Info[gNB_index].State);
|
||||
dec_rval = uper_decode(NULL,
|
||||
&asn_DEF_NR_DL_CCCH_Message,
|
||||
(void **)&dl_ccch_msg,
|
||||
(uint8_t *)Srb_info->Rx_buffer.Payload,
|
||||
100,0,0);
|
||||
|
||||
// if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg);
|
||||
// }
|
||||
|
||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
|
||||
LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) {
|
||||
if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_SI_RECEIVED) {
|
||||
switch (dl_ccch_msg->message.choice.c1->present) {
|
||||
case NR_DL_CCCH_MessageType__c1_PR_NOTHING:
|
||||
LOG_I(NR_RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n",
|
||||
ctxt_pP->module_id,
|
||||
ctxt_pP->frame);
|
||||
rval = 0;
|
||||
break;
|
||||
|
||||
case NR_DL_CCCH_MessageType__c1_PR_rrcReject:
|
||||
LOG_I(NR_RRC,
|
||||
"[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n",
|
||||
ctxt_pP->module_id,
|
||||
ctxt_pP->frame);
|
||||
rval = 0;
|
||||
break;
|
||||
|
||||
case NR_DL_CCCH_MessageType__c1_PR_rrcSetup:
|
||||
LOG_I(NR_RRC,
|
||||
"[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %x\n",
|
||||
ctxt_pP->module_id,
|
||||
ctxt_pP->frame,
|
||||
ctxt_pP->rnti);
|
||||
// Get configuration
|
||||
// Release T300 timer
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T300_active = 0;
|
||||
|
||||
nr_rrc_ue_process_masterCellGroup(
|
||||
ctxt_pP,
|
||||
gNB_index,
|
||||
&dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup);
|
||||
nr_sa_rrc_ue_process_radioBearerConfig(
|
||||
ctxt_pP,
|
||||
gNB_index,
|
||||
&dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
|
||||
nr_rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED);
|
||||
nr_rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED);
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].rnti = ctxt_pP->rnti;
|
||||
rrc_ue_generate_RRCSetupComplete(
|
||||
ctxt_pP,
|
||||
gNB_index,
|
||||
dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity);
|
||||
rval = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(NR_RRC, "[UE%d] Frame %d : Unknown message\n",
|
||||
ctxt_pP->module_id,
|
||||
ctxt_pP->frame);
|
||||
rval = -1;
|
||||
break;
|
||||
NR_DL_CCCH_Message_t *dl_ccch_msg=NULL;
|
||||
asn_dec_rval_t dec_rval;
|
||||
int rval=0;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN);
|
||||
// LOG_D(RRC,"[UE %d] Decoding DL-CCCH message (%d bytes), State %d\n",ue_mod_idP,Srb_info->Rx_buffer.payload_size,
|
||||
// NR_UE_rrc_inst[ue_mod_idP].Info[gNB_index].State);
|
||||
dec_rval = uper_decode(NULL,
|
||||
&asn_DEF_NR_DL_CCCH_Message,
|
||||
(void **)&dl_ccch_msg,
|
||||
(uint8_t *)Srb_info->Rx_buffer.Payload,
|
||||
100,0,0);
|
||||
|
||||
// if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg);
|
||||
// }
|
||||
|
||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
|
||||
LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) {
|
||||
if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_SI_RECEIVED) {
|
||||
switch (dl_ccch_msg->message.choice.c1->present) {
|
||||
case NR_DL_CCCH_MessageType__c1_PR_NOTHING:
|
||||
LOG_I(NR_RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n",
|
||||
ctxt_pP->module_id,
|
||||
ctxt_pP->frame);
|
||||
rval = 0;
|
||||
break;
|
||||
|
||||
case NR_DL_CCCH_MessageType__c1_PR_rrcReject:
|
||||
LOG_I(NR_RRC,
|
||||
"[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n",
|
||||
ctxt_pP->module_id,
|
||||
ctxt_pP->frame);
|
||||
rval = 0;
|
||||
break;
|
||||
|
||||
case NR_DL_CCCH_MessageType__c1_PR_rrcSetup:
|
||||
LOG_I(NR_RRC,
|
||||
"[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %x\n",
|
||||
ctxt_pP->module_id,
|
||||
ctxt_pP->frame,
|
||||
ctxt_pP->rnti);
|
||||
|
||||
// Get configuration
|
||||
// Release T300 timer
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T300_active = 0;
|
||||
|
||||
nr_rrc_ue_process_masterCellGroup(
|
||||
ctxt_pP,
|
||||
gNB_index,
|
||||
&dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup);
|
||||
nr_sa_rrc_ue_process_radioBearerConfig(
|
||||
ctxt_pP,
|
||||
gNB_index,
|
||||
&dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
|
||||
nr_rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED);
|
||||
nr_rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED);
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].rnti = ctxt_pP->rnti;
|
||||
rrc_ue_generate_RRCSetupComplete(
|
||||
ctxt_pP,
|
||||
gNB_index,
|
||||
dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity);
|
||||
rval = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(NR_RRC, "[UE%d] Frame %d : Unknown message\n",
|
||||
ctxt_pP->module_id,
|
||||
ctxt_pP->frame);
|
||||
rval = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
|
||||
return rval;
|
||||
@@ -1747,11 +1758,11 @@ nr_rrc_ue_process_securityModeCommand(
|
||||
#ifdef ITTI_SIM
|
||||
MessageDef *message_p;
|
||||
uint8_t *message_buffer;
|
||||
message_buffer = itti_malloc (TASK_RRC_UE_SIM,TASK_RRC_GNB_SIM,
|
||||
message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,
|
||||
(enc_rval.encoded + 7) / 8);
|
||||
memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8);
|
||||
|
||||
message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, UE_RRC_DCCH_DATA_IND);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
|
||||
GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
|
||||
GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
|
||||
GNB_RRC_DCCH_DATA_IND (message_p).size = (enc_rval.encoded + 7) / 8;
|
||||
@@ -1789,11 +1800,11 @@ void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, cons
|
||||
}
|
||||
|
||||
LOG_T(NR_RRC,"\n");
|
||||
// NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size =
|
||||
// do_RRCSetupRequest(
|
||||
// ctxt_pP->module_id,
|
||||
// (uint8_t *)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload,
|
||||
// rv);
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size =
|
||||
do_RRCSetupRequest(
|
||||
ctxt_pP->module_id,
|
||||
(uint8_t *)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload,
|
||||
rv);
|
||||
LOG_I(NR_RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, eNB %d)\n",
|
||||
ctxt_pP->module_id, ctxt_pP->frame, NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index);
|
||||
|
||||
@@ -1808,11 +1819,11 @@ void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, cons
|
||||
#ifdef ITTI_SIM
|
||||
MessageDef *message_p;
|
||||
uint8_t *message_buffer;
|
||||
message_buffer = itti_malloc (TASK_RRC_UE_SIM,TASK_RRC_GNB_SIM,
|
||||
message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size);
|
||||
memcpy (message_buffer, (uint8_t*)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, UE_RRC_CCCH_DATA_IND);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_CCCH_DATA_IND);
|
||||
GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
|
||||
GNB_RRC_CCCH_DATA_IND (message_p).size = NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size;
|
||||
itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
|
||||
@@ -1968,7 +1979,7 @@ nr_rrc_ue_process_measConfig(
|
||||
(char *)measConfig->reportConfigToAddModList->list.array[i],
|
||||
sizeof(NR_ReportConfigToAddMod_t));
|
||||
} else {
|
||||
LOG_D(RRC,"Adding Report Configuration %ld %p \n", ind-1, measConfig->reportConfigToAddModList->list.array[i]);
|
||||
LOG_D(NR_RRC,"Adding Report Configuration %ld %p \n", ind-1, measConfig->reportConfigToAddModList->list.array[i]);
|
||||
if (reportConfig->reportConfig.present == NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR) {
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i];
|
||||
}
|
||||
@@ -2001,7 +2012,7 @@ nr_rrc_ue_process_measConfig(
|
||||
|
||||
if (measConfig->quantityConfig != NULL) {
|
||||
if (NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index]) {
|
||||
LOG_D(RRC,"Modifying Quantity Configuration \n");
|
||||
LOG_D(NR_RRC,"Modifying Quantity Configuration \n");
|
||||
memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index],
|
||||
(char *)measConfig->quantityConfig,
|
||||
sizeof(NR_QuantityConfig_t));
|
||||
@@ -2225,7 +2236,30 @@ rrc_ue_process_rrcReconfiguration(
|
||||
for (list_count = 0; list_count < ie->nonCriticalExtension->dedicatedNAS_MessageList->list.count; list_count++) {
|
||||
pdu_length = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->size;
|
||||
pdu_buffer = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->buf;
|
||||
msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, NAS_CONN_ESTABLI_CNF);
|
||||
#ifdef ITTI_SIM
|
||||
uint8_t msg_type = 0;
|
||||
if((pdu_buffer + 1) != NULL){
|
||||
if (*(pdu_buffer + 1) > 0 ) {
|
||||
if((pdu_buffer + 9) != NULL){
|
||||
msg_type = *(pdu_buffer + 9);
|
||||
} else {
|
||||
LOG_W(NR_RRC, "[UE] Received invalid downlink message\n");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if((pdu_buffer + 2) != NULL){
|
||||
msg_type = *(pdu_buffer + 2);
|
||||
} else {
|
||||
LOG_W(NR_RRC, "[UE] Received invalid downlink message\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(msg_type == REGISTRATION_ACCEPT){
|
||||
LOG_I(NR_RRC, "[UE] Received REGISTRATION ACCEPT message\n");
|
||||
}
|
||||
#endif
|
||||
msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_ESTABLI_CNF);
|
||||
NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS;
|
||||
NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = pdu_length;
|
||||
NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = pdu_buffer;
|
||||
@@ -2255,14 +2289,15 @@ void nr_rrc_ue_generate_RRCReconfigurationComplete( const protocol_ctxt_t *const
|
||||
#ifdef ITTI_SIM
|
||||
MessageDef *message_p;
|
||||
uint8_t *message_buffer;
|
||||
message_buffer = itti_malloc (TASK_RRC_UE_SIM,TASK_RRC_GNB_SIM,size);
|
||||
message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,size);
|
||||
memcpy (message_buffer, buffer, size);
|
||||
|
||||
message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, UE_RRC_DCCH_DATA_IND);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
|
||||
UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
|
||||
UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
|
||||
UE_RRC_DCCH_DATA_IND (message_p).size = size;
|
||||
itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
|
||||
|
||||
#else
|
||||
rrc_data_req_ue (
|
||||
ctxt_pP,
|
||||
@@ -2317,66 +2352,177 @@ nr_rrc_ue_decode_dcch(
|
||||
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message,(void *)dl_dcch_msg);
|
||||
// }
|
||||
|
||||
if (dl_dcch_msg->message.present == NR_DL_DCCH_MessageType_PR_c1) {
|
||||
switch (dl_dcch_msg->message.choice.c1->present) {
|
||||
case NR_DL_DCCH_MessageType__c1_PR_NOTHING:
|
||||
LOG_I(NR_RRC, "Received PR_NOTHING on DL-DCCH-Message\n");
|
||||
break;
|
||||
if (dl_dcch_msg->message.present == NR_DL_DCCH_MessageType_PR_c1) {
|
||||
switch (dl_dcch_msg->message.choice.c1->present) {
|
||||
case NR_DL_DCCH_MessageType__c1_PR_NOTHING:
|
||||
LOG_I(NR_RRC, "Received PR_NOTHING on DL-DCCH-Message\n");
|
||||
break;
|
||||
|
||||
case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration:
|
||||
rrc_ue_process_rrcReconfiguration(ctxt_pP,
|
||||
dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration,
|
||||
gNB_indexP);
|
||||
nr_rrc_ue_generate_RRCReconfigurationComplete(ctxt_pP,
|
||||
gNB_indexP,
|
||||
dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier);
|
||||
break;
|
||||
case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration:
|
||||
{
|
||||
rrc_ue_process_rrcReconfiguration(ctxt_pP,
|
||||
dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration,
|
||||
gNB_indexP);
|
||||
nr_rrc_ue_generate_RRCReconfigurationComplete(ctxt_pP,
|
||||
gNB_indexP,
|
||||
dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier);
|
||||
|
||||
case NR_DL_DCCH_MessageType__c1_PR_rrcResume:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_rrcRelease:
|
||||
msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, NAS_CONN_RELEASE_IND);
|
||||
if (first_rrcreconfigurationcomplete == 0) {
|
||||
first_rrcreconfigurationcomplete = 1;
|
||||
#ifdef ITTI_SIM
|
||||
if (AMF_MODE_ENABLED) {
|
||||
as_nas_info_t initialNasMsg;
|
||||
memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
|
||||
generateRegistrationComplete(&initialNasMsg, NULL);
|
||||
if(initialNasMsg.length > 0){
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_UPLINK_DATA_REQ);
|
||||
NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)initialNasMsg.data;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length;
|
||||
itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
|
||||
LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
|
||||
}
|
||||
as_nas_info_t pduEstablishMsg;
|
||||
memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t));
|
||||
generatePduSessionEstablishRequest(&pduEstablishMsg);
|
||||
if(initialNasMsg.length > 0){
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_UPLINK_DATA_REQ);
|
||||
NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)pduEstablishMsg.data;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length;
|
||||
itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
|
||||
LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if((dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) &&
|
||||
(dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)){
|
||||
dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer =
|
||||
NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5;
|
||||
dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType =
|
||||
NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency;
|
||||
}
|
||||
case NR_DL_DCCH_MessageType__c1_PR_rrcResume:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_rrcRelease:
|
||||
LOG_I(NR_RRC, "[UE %d] Received RRC Release (gNB %d)\n",
|
||||
ctxt_pP->module_id, gNB_indexP);
|
||||
|
||||
itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
|
||||
break;
|
||||
case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
|
||||
LOG_I(RRC, "[UE %d] Received Capability Enquiry (gNB %d)\n",
|
||||
ctxt_pP->module_id,gNB_indexP);
|
||||
nr_rrc_ue_process_ueCapabilityEnquiry(
|
||||
ctxt_pP,
|
||||
dl_dcch_msg->message.choice.c1->choice.ueCapabilityEnquiry,
|
||||
gNB_indexP);
|
||||
break;
|
||||
case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_spare3:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_spare2:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_spare1:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_counterCheck:
|
||||
break;
|
||||
case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
|
||||
LOG_I(RRC, "[UE %d] Received securityModeCommand (gNB %d)\n",
|
||||
ctxt_pP->module_id, gNB_indexP);
|
||||
nr_rrc_ue_process_securityModeCommand(
|
||||
ctxt_pP,
|
||||
dl_dcch_msg->message.choice.c1->choice.securityModeCommand,
|
||||
gNB_indexP);
|
||||
msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND);
|
||||
|
||||
break;
|
||||
if((dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) &&
|
||||
(dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)){
|
||||
dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer =
|
||||
NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5;
|
||||
dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType =
|
||||
NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency;
|
||||
}
|
||||
|
||||
itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
|
||||
break;
|
||||
case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
|
||||
LOG_I(NR_RRC, "[UE %d] Received Capability Enquiry (gNB %d)\n",
|
||||
ctxt_pP->module_id,gNB_indexP);
|
||||
nr_rrc_ue_process_ueCapabilityEnquiry(
|
||||
ctxt_pP,
|
||||
dl_dcch_msg->message.choice.c1->choice.ueCapabilityEnquiry,
|
||||
gNB_indexP);
|
||||
break;
|
||||
case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment:
|
||||
LOG_I(NR_RRC,
|
||||
"[UE%d] Frame %d : Logical Channel DL-DCCH (SRB1), Received RRCReestablishment\n",
|
||||
ctxt_pP->module_id,
|
||||
ctxt_pP->frame);
|
||||
nr_rrc_ue_generate_rrcReestablishmentComplete(
|
||||
ctxt_pP,
|
||||
dl_dcch_msg->message.choice.c1->choice.rrcReestablishment,
|
||||
gNB_indexP);
|
||||
break;
|
||||
case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
|
||||
{
|
||||
NR_DLInformationTransfer_t *dlInformationTransfer = dl_dcch_msg->message.choice.c1->choice.dlInformationTransfer;
|
||||
|
||||
if (dlInformationTransfer->criticalExtensions.present
|
||||
== NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer) {
|
||||
/* This message hold a dedicated info NAS payload, forward it to NAS */
|
||||
NR_DedicatedNAS_Message_t *dedicatedNAS_Message =
|
||||
dlInformationTransfer->criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message;
|
||||
uint32_t pdu_length;
|
||||
uint8_t *pdu_buffer;
|
||||
pdu_length = dedicatedNAS_Message->size;
|
||||
pdu_buffer = dedicatedNAS_Message->buf;
|
||||
#ifdef ITTI_SIM
|
||||
LOG_I(NR_RRC, "[UE %d] Received %s: UEid %u, length %u , buffer %p\n", ctxt_pP->module_id, messages_info[NAS_DOWNLINK_DATA_IND].name,
|
||||
ctxt_pP->module_id, pdu_length, pdu_buffer);
|
||||
as_nas_info_t initialNasMsg;
|
||||
uint8_t msg_type = 0;
|
||||
memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
|
||||
if((pdu_buffer + 1) != NULL){
|
||||
if (*(pdu_buffer + 1) > 0 ) {
|
||||
msg_type = *(pdu_buffer + 9);
|
||||
} else {
|
||||
msg_type = *(pdu_buffer + 2);
|
||||
}
|
||||
}
|
||||
if((pdu_buffer + 2) == NULL){
|
||||
LOG_W(NR_RRC, "[UE] Received invalid downlink message\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(msg_type){
|
||||
case FGS_IDENTITY_REQUEST:
|
||||
generateIdentityResponse(&initialNasMsg,*(pdu_buffer+3));
|
||||
break;
|
||||
case FGS_AUTHENTICATION_REQUEST:
|
||||
generateAuthenticationResp(&initialNasMsg, pdu_buffer);
|
||||
break;
|
||||
case FGS_SECURITY_MODE_COMMAND:
|
||||
generateSecurityModeComplete(&initialNasMsg);
|
||||
break;
|
||||
default:
|
||||
LOG_W(NR_RRC,"unknow message type %d\n",msg_type);
|
||||
break;
|
||||
}
|
||||
if(initialNasMsg.length > 0){
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_UPLINK_DATA_REQ);
|
||||
NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)initialNasMsg.data;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length;
|
||||
itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
|
||||
LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message\n");
|
||||
}
|
||||
#else
|
||||
MessageDef *msg_p;
|
||||
msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_DOWNLINK_DATA_IND);
|
||||
NAS_DOWNLINK_DATA_IND(msg_p).UEid = ctxt_pP->module_id; // TODO set the UEid to something else ?
|
||||
NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length = pdu_length;
|
||||
NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = pdu_buffer;
|
||||
itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_spare3:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_spare2:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_spare1:
|
||||
case NR_DL_DCCH_MessageType__c1_PR_counterCheck:
|
||||
break;
|
||||
case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
|
||||
LOG_I(NR_RRC, "[UE %d] Received securityModeCommand (gNB %d)\n",
|
||||
ctxt_pP->module_id, gNB_indexP);
|
||||
nr_rrc_ue_process_securityModeCommand(
|
||||
ctxt_pP,
|
||||
dl_dcch_msg->message.choice.c1->choice.securityModeCommand,
|
||||
gNB_indexP);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2429,8 +2575,8 @@ void *rrc_nrue_task( void *args_p ) {
|
||||
memcpy (srb_info_p->Rx_buffer.Payload, NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu,
|
||||
NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size);
|
||||
srb_info_p->Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size;
|
||||
// PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, RRC_MAC_CCCH_DATA_IND (msg_p).rnti, RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0);
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0);
|
||||
// PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
|
||||
nr_rrc_ue_decode_ccch (&ctxt,
|
||||
srb_info_p,
|
||||
NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
|
||||
@@ -2457,6 +2603,50 @@ void *rrc_nrue_task( void *args_p ) {
|
||||
NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
|
||||
break;
|
||||
|
||||
case NAS_UPLINK_DATA_REQ: {
|
||||
uint32_t length;
|
||||
uint8_t *buffer;
|
||||
LOG_I(NR_RRC, "[UE %d] Received %s: UEid %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), NAS_UPLINK_DATA_REQ (msg_p).UEid);
|
||||
/* Create message for PDCP (ULInformationTransfer_t) */
|
||||
length = do_NR_ULInformationTransfer(&buffer, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.data);
|
||||
/* Transfer data to PDCP */
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_UE_rrc_inst[ue_mod_id].Info[0].rnti, 0, 0,0);
|
||||
#ifdef ITTI_SIM
|
||||
MessageDef *message_p;
|
||||
uint8_t *message_buffer;
|
||||
message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,length);
|
||||
memcpy (message_buffer, buffer, length);
|
||||
|
||||
message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
|
||||
if(NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL)
|
||||
UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
|
||||
else
|
||||
UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH1;
|
||||
UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
|
||||
UE_RRC_DCCH_DATA_IND (message_p).size = length;
|
||||
itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt.instance, message_p);
|
||||
|
||||
#else
|
||||
// check if SRB2 is created, if yes request data_req on DCCH1 (SRB2)
|
||||
if(NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL) {
|
||||
rrc_data_req_ue (&ctxt,
|
||||
DCCH,
|
||||
nr_rrc_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
length, buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
} else {
|
||||
rrc_data_req_ue (&ctxt,
|
||||
DCCH1,
|
||||
nr_rrc_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
length, buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
|
||||
break;
|
||||
@@ -2503,7 +2693,7 @@ nr_rrc_ue_process_ueCapabilityEnquiry(
|
||||
NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container;
|
||||
uint8_t buffer[200];
|
||||
int i;
|
||||
LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing UECapabilityEnquiry (gNB %d)\n",
|
||||
LOG_I(NR_RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing UECapabilityEnquiry (gNB %d)\n",
|
||||
ctxt_pP->module_id,
|
||||
ctxt_pP->frame,
|
||||
gNB_index);
|
||||
@@ -2576,11 +2766,11 @@ nr_rrc_ue_process_ueCapabilityEnquiry(
|
||||
#ifdef ITTI_SIM
|
||||
MessageDef *message_p;
|
||||
uint8_t *message_buffer;
|
||||
message_buffer = itti_malloc (TASK_RRC_UE_SIM,TASK_RRC_GNB_SIM,
|
||||
message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,
|
||||
(enc_rval.encoded + 7) / 8);
|
||||
memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8);
|
||||
|
||||
message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, UE_RRC_DCCH_DATA_IND);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
|
||||
GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
|
||||
GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
|
||||
GNB_RRC_DCCH_DATA_IND (message_p).size = (enc_rval.encoded + 7) / 8;
|
||||
@@ -2598,3 +2788,61 @@ nr_rrc_ue_process_ueCapabilityEnquiry(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void rrc_ue_generate_RRCReestablishmentRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index )
|
||||
{
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size =
|
||||
do_RRCReestablishmentRequest(
|
||||
ctxt_pP->module_id,
|
||||
(uint8_t *)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload, 1);
|
||||
LOG_I(NR_RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCReestablishmentRequest (bytes %d, gNB %d)\n",
|
||||
ctxt_pP->module_id, ctxt_pP->frame, NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index);
|
||||
|
||||
for (int i=0; i<NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) {
|
||||
LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload[i]);
|
||||
}
|
||||
|
||||
LOG_T(NR_RRC,"\n");
|
||||
|
||||
#ifdef ITTI_SIM
|
||||
MessageDef *message_p;
|
||||
uint8_t *message_buffer;
|
||||
message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size);
|
||||
memcpy (message_buffer, (uint8_t*)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_CCCH_DATA_IND);
|
||||
UE_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
|
||||
UE_RRC_CCCH_DATA_IND (message_p).size = NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size;
|
||||
itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nr_rrc_ue_generate_rrcReestablishmentComplete(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
NR_RRCReestablishment_t *rrcReestablishment,
|
||||
uint8_t gNB_index
|
||||
)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
uint32_t length;
|
||||
uint8_t buffer[100];
|
||||
length = do_RRCReestablishmentComplete(buffer, rrcReestablishment->rrc_TransactionIdentifier);
|
||||
LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes%d, gNB %d)\n",
|
||||
ctxt_pP->module_id,ctxt_pP->frame, length, gNB_index);
|
||||
#ifdef ITTI_SIM
|
||||
MessageDef *message_p;
|
||||
uint8_t *message_buffer;
|
||||
message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,length);
|
||||
memcpy (message_buffer, buffer, length);
|
||||
|
||||
message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
|
||||
UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
|
||||
UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
|
||||
UE_RRC_DCCH_DATA_IND (message_p).size = length;
|
||||
itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -127,6 +127,8 @@ typedef struct NR_UE_RRC_INST_s {
|
||||
|
||||
/* KeNB as computed from parameters within USIM card */
|
||||
uint8_t kgnb[32];
|
||||
/* Used integrity/ciphering algorithms */
|
||||
//RRC_LIST_TYPE(NR_SecurityAlgorithmConfig_t, NR_SecurityAlgorithmConfig) SecurityAlgorithmConfig_list;
|
||||
NR_CipheringAlgorithm_t cipheringAlgorithm;
|
||||
e_NR_IntegrityProtAlgorithm integrityProtAlgorithm;
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ int config_sync_var=-1;
|
||||
|
||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
|
||||
volatile int start_gNB = 0;
|
||||
//volatile int start_gNB = 0;
|
||||
volatile int oai_exit = 0;
|
||||
|
||||
//static int wait_for_sync = 0;
|
||||
@@ -299,7 +299,7 @@ int create_gNB_tasks(uint32_t gnb_nb) {
|
||||
}
|
||||
}
|
||||
|
||||
if (itti_create_task (TASK_GTPV1_U, >pv1u_gNB_task, NULL) < 0) {
|
||||
if (itti_create_task (TASK_GTPV1_U, &nr_gtpv1u_gNB_task, NULL) < 0) {
|
||||
LOG_E(GTPU, "Create task for GTPV1U failed\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -369,7 +369,7 @@ void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs],
|
||||
void terminate_task(task_id_t task_id, module_id_t mod_id) {
|
||||
LOG_I(GNB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id);
|
||||
MessageDef *msg;
|
||||
msg = itti_alloc_new_message (ENB_APP, TERMINATE_MESSAGE);
|
||||
msg = itti_alloc_new_message (ENB_APP, 0, TERMINATE_MESSAGE);
|
||||
itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg);
|
||||
}
|
||||
|
||||
@@ -435,14 +435,14 @@ void *itti_sim_ue_rrc_task( void *args_p) {
|
||||
LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
|
||||
break;
|
||||
case GNB_RRC_BCCH_DATA_IND:
|
||||
message_p = itti_alloc_new_message (TASK_RRC_NRUE, NR_RRC_MAC_BCCH_DATA_IND);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, NR_RRC_MAC_BCCH_DATA_IND);
|
||||
memset (NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE);
|
||||
NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = GNB_RRC_BCCH_DATA_IND(msg_p).size;
|
||||
memcpy (NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, GNB_RRC_BCCH_DATA_IND(msg_p).sdu, GNB_RRC_BCCH_DATA_IND(msg_p).size);
|
||||
itti_send_msg_to_task (TASK_RRC_NRUE, instance, message_p);
|
||||
break;
|
||||
case GNB_RRC_CCCH_DATA_IND:
|
||||
message_p = itti_alloc_new_message (TASK_RRC_NRUE, NR_RRC_MAC_CCCH_DATA_IND);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, NR_RRC_MAC_CCCH_DATA_IND);
|
||||
printf("receive GNB_RRC_CCCH_DATA_IND\n");
|
||||
memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
|
||||
memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, GNB_RRC_CCCH_DATA_IND(msg_p).sdu, GNB_RRC_CCCH_DATA_IND(msg_p).size);
|
||||
@@ -451,7 +451,7 @@ void *itti_sim_ue_rrc_task( void *args_p) {
|
||||
break;
|
||||
case GNB_RRC_DCCH_DATA_IND:
|
||||
printf("receive GNB_RRC_DCCH_DATA_IND\n");
|
||||
message_p = itti_alloc_new_message (TASK_RRC_NRUE, NR_RRC_DCCH_DATA_IND);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, NR_RRC_DCCH_DATA_IND);
|
||||
NR_RRC_DCCH_DATA_IND (message_p).dcch_index = GNB_RRC_DCCH_DATA_IND(msg_p).rbid;
|
||||
NR_RRC_DCCH_DATA_IND (message_p).sdu_size = GNB_RRC_DCCH_DATA_IND(msg_p).size;
|
||||
NR_RRC_DCCH_DATA_IND (message_p).sdu_p = GNB_RRC_DCCH_DATA_IND(msg_p).sdu;
|
||||
@@ -492,14 +492,14 @@ void *itti_sim_gnb_rrc_task( void *args_p) {
|
||||
LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
|
||||
break;
|
||||
case UE_RRC_CCCH_DATA_IND:
|
||||
message_p = itti_alloc_new_message (TASK_RRC_GNB, NR_RRC_MAC_CCCH_DATA_IND);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, 0, NR_RRC_MAC_CCCH_DATA_IND);
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = UE_RRC_CCCH_DATA_IND(msg_p).size;
|
||||
memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
|
||||
memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, UE_RRC_CCCH_DATA_IND(msg_p).sdu, UE_RRC_CCCH_DATA_IND(msg_p).size);
|
||||
itti_send_msg_to_task (TASK_RRC_GNB, instance, message_p);
|
||||
break;
|
||||
case UE_RRC_DCCH_DATA_IND:
|
||||
message_p = itti_alloc_new_message (TASK_RRC_GNB, NR_RRC_DCCH_DATA_IND);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, 0, NR_RRC_DCCH_DATA_IND);
|
||||
NR_RRC_DCCH_DATA_IND (message_p).sdu_size = UE_RRC_DCCH_DATA_IND(msg_p).size;
|
||||
NR_RRC_DCCH_DATA_IND (message_p).dcch_index = UE_RRC_DCCH_DATA_IND(msg_p).rbid;
|
||||
NR_RRC_DCCH_DATA_IND (message_p).sdu_p = UE_RRC_DCCH_DATA_IND(msg_p).sdu;
|
||||
@@ -542,8 +542,9 @@ int main( int argc, char **argv )
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// AMF_MODE_ENABLED = !IS_SOFTMODEM_NOS1;
|
||||
AMF_MODE_ENABLED = 0;
|
||||
AMF_MODE_ENABLED = !IS_SOFTMODEM_NOS1;
|
||||
// AMF_MODE_ENABLED = 0;
|
||||
NGAP_CONF_MODE = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test;
|
||||
|
||||
#if T_TRACER
|
||||
T_Config_Init();
|
||||
|
||||
@@ -55,6 +55,8 @@ typedef enum {
|
||||
|
||||
int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
|
||||
const uint8_t key[32], uint8_t **out);
|
||||
int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
|
||||
const uint8_t key[32], uint8_t **out);
|
||||
|
||||
//#define derive_key_nas_enc(aLGiD, kEY, kNAS) derive_key(NAS_ENC_ALG, aLGiD, kEY, kNAS)
|
||||
|
||||
@@ -72,6 +74,19 @@ int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
|
||||
#define derive_key_up_int(aLGiD, kEY, kNAS) \
|
||||
derive_key(UP_INT_ALG, aLGiD, kEY, kNAS)
|
||||
|
||||
// 5G SA
|
||||
#define nr_derive_key_rrc_enc(aLGiD, kEY, kRRC) \
|
||||
nr_derive_key(RRC_ENC_ALG, aLGiD, kEY, kRRC)
|
||||
|
||||
#define nr_derive_key_rrc_int(aLGiD, kEY, kRRC) \
|
||||
nr_derive_key(RRC_INT_ALG, aLGiD, kEY, kRRC)
|
||||
|
||||
#define nr_derive_key_up_enc(aLGiD, kEY, kUP) \
|
||||
nr_derive_key(UP_ENC_ALG, aLGiD, kEY, kUP)
|
||||
|
||||
#define nr_derive_key_up_int(aLGiD, kEY, kUP) \
|
||||
nr_derive_key(UP_INT_ALG, aLGiD, kEY, kUP)
|
||||
|
||||
typedef struct {
|
||||
uint8_t *key;
|
||||
uint32_t key_length;
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#define FC_ALG_KEY_DER (0x15)
|
||||
#define FC_KASME_TO_CK (0x16)
|
||||
|
||||
#define NR_FC_ALG_KEY_DER (0x69)
|
||||
|
||||
#ifndef hton_int32
|
||||
# define hton_int32(x) \
|
||||
(((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8) | \
|
||||
|
||||
@@ -97,6 +97,34 @@ int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
|
||||
const uint8_t key[32], uint8_t **out)
|
||||
{
|
||||
uint8_t string[7];
|
||||
|
||||
/* FC */
|
||||
string[0] = NR_FC_ALG_KEY_DER;
|
||||
|
||||
/* P0 = algorithm type distinguisher */
|
||||
string[1] = (uint8_t)(alg_type & 0xFF);
|
||||
|
||||
/* L0 = length(P0) = 1 */
|
||||
string[2] = 0x00;
|
||||
string[3] = 0x01;
|
||||
|
||||
/* P1 */
|
||||
string[4] = alg_id;
|
||||
|
||||
/* L1 = length(P1) = 1 */
|
||||
string[5] = 0x00;
|
||||
string[6] = 0x01;
|
||||
|
||||
kdf(string, 7, key, 32, out, 32);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB)
|
||||
{
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "NwGtpv1uPrivate.h"
|
||||
#include "NwLog.h"
|
||||
#include "gtpv1u_eNB_defs.h"
|
||||
#include "gtpv1u_gNB_defs.h"
|
||||
#include "gtpv1_u_messages_types.h"
|
||||
#include "udp_eNB_task.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
@@ -45,7 +46,6 @@
|
||||
#include "COMMON/platform_constants.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "gtpv1u_eNB_defs.h"
|
||||
#include "gtpv1u_eNB_task.h"
|
||||
#include "gtpv1u_gNB_task.h"
|
||||
#include "rrc_eNB_GTPV1U.h"
|
||||
@@ -309,3 +309,514 @@ void *gtpv1u_gNB_task(void *args) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int nr_gtpv1u_gNB_init(void) {
|
||||
NwGtpv1uRcT rc = NW_GTPV1U_FAILURE;
|
||||
NwGtpv1uUlpEntityT ulp;
|
||||
NwGtpv1uUdpEntityT udp;
|
||||
NwGtpv1uLogMgrEntityT log;
|
||||
NwGtpv1uTimerMgrEntityT tmr;
|
||||
// enb_properties_p = enb_config_get()->properties[0];
|
||||
RC.nr_gtpv1u_data_g = (nr_gtpv1u_data_t *)calloc(sizeof(nr_gtpv1u_data_t),1);
|
||||
LOG_I(GTPU, "Initializing GTPU stack %p\n",&RC.nr_gtpv1u_data_g);
|
||||
|
||||
/* Initialize UE hashtable */
|
||||
RC.nr_gtpv1u_data_g->ue_mapping = hashtable_create (32, NULL, NULL);
|
||||
AssertFatal(RC.nr_gtpv1u_data_g->ue_mapping != NULL, " ERROR Initializing TASK_GTPV1_U task interface: in hashtable_create returned %p\n", RC.gtpv1u_data_g->ue_mapping);
|
||||
RC.nr_gtpv1u_data_g->teid_mapping = hashtable_create (256, NULL, NULL);
|
||||
AssertFatal(RC.nr_gtpv1u_data_g->teid_mapping != NULL, " ERROR Initializing TASK_GTPV1_U task interface: in hashtable_create\n");
|
||||
// RC.gtpv1u_data_g.enb_ip_address_for_S1u_S12_S4_up = enb_properties_p->enb_ipv4_address_for_S1U;
|
||||
//gtpv1u_data_g.udp_data;
|
||||
RC.nr_gtpv1u_data_g->seq_num = 0;
|
||||
RC.nr_gtpv1u_data_g->restart_counter = 0;
|
||||
|
||||
/* Initializing GTPv1-U stack */
|
||||
if ((rc = nwGtpv1uInitialize(&RC.nr_gtpv1u_data_g->gtpv1u_stack, GTPU_STACK_ENB)) != NW_GTPV1U_OK) {
|
||||
LOG_E(GTPU, "Failed to setup nwGtpv1u stack %x\n", rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((rc = nwGtpv1uSetLogLevel(RC.nr_gtpv1u_data_g->gtpv1u_stack,
|
||||
NW_LOG_LEVEL_DEBG)) != NW_GTPV1U_OK) {
|
||||
LOG_E(GTPU, "Failed to setup loglevel for stack %x\n", rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the ULP API callback. Called once message have been processed by the
|
||||
* nw-gtpv1u stack.
|
||||
*/
|
||||
ulp.ulpReqCallback = gtpv1u_gNB_process_stack_req;
|
||||
memset((void *)&(ulp.hUlp), 0, sizeof(NwGtpv1uUlpHandleT));
|
||||
|
||||
if ((rc = nwGtpv1uSetUlpEntity(RC.nr_gtpv1u_data_g->gtpv1u_stack, &ulp)) != NW_GTPV1U_OK) {
|
||||
LOG_E(GTPU, "nwGtpv1uSetUlpEntity: %x", rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* nw-gtpv1u stack requires an udp callback to send data over UDP.
|
||||
* We provide a wrapper to UDP task.
|
||||
*/
|
||||
udp.udpDataReqCallback = gtpv1u_eNB_send_udp_msg;
|
||||
memset((void *)&(udp.hUdp), 0, sizeof(NwGtpv1uUdpHandleT));
|
||||
|
||||
if ((rc = nwGtpv1uSetUdpEntity(RC.nr_gtpv1u_data_g->gtpv1u_stack, &udp)) != NW_GTPV1U_OK) {
|
||||
LOG_E(GTPU, "nwGtpv1uSetUdpEntity: %x", rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
log.logReqCallback = gtpv1u_eNB_log_request;
|
||||
memset((void *)&(log.logMgrHandle), 0, sizeof(NwGtpv1uLogMgrHandleT));
|
||||
|
||||
if ((rc = nwGtpv1uSetLogMgrEntity(RC.nr_gtpv1u_data_g->gtpv1u_stack, &log)) != NW_GTPV1U_OK) {
|
||||
LOG_E(GTPU, "nwGtpv1uSetLogMgrEntity: %x", rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Timer interface is more complicated as both wrappers doesn't send a message
|
||||
* to the timer task but call the timer API functions start/stop timer.
|
||||
*/
|
||||
tmr.tmrMgrHandle = 0;
|
||||
tmr.tmrStartCallback = gtpv1u_start_timer_wrapper;
|
||||
tmr.tmrStopCallback = gtpv1u_stop_timer_wrapper;
|
||||
|
||||
if ((rc = nwGtpv1uSetTimerMgrEntity(RC.nr_gtpv1u_data_g->gtpv1u_stack, &tmr)) != NW_GTPV1U_OK) {
|
||||
LOG_E(GTPU, "nwGtpv1uSetTimerMgrEntity: %x", rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0
|
||||
|
||||
if ((ret = gtpv1u_eNB_create_dump_socket()) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
LOG_D(GTPU, "Initializing GTPV1U interface for eNB: DONE\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int
|
||||
gtpv1u_create_ngu_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP,
|
||||
gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP)
|
||||
{
|
||||
/* Create a new nw-gtpv1-u stack req using API */
|
||||
NwGtpv1uUlpApiT stack_req;
|
||||
NwGtpv1uRcT rc = NW_GTPV1U_FAILURE;
|
||||
/* Local tunnel end-point identifier */
|
||||
teid_t ngu_teid = 0;
|
||||
nr_gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL;
|
||||
nr_gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL;
|
||||
//MessageDef *message_p = NULL;
|
||||
hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
|
||||
int i;
|
||||
pdusessionid_t pdusession_id = 0;
|
||||
// int ipv4_addr = 0;
|
||||
int ip_offset = 0;
|
||||
in_addr_t in_addr;
|
||||
int addrs_length_in_bytes= 0;
|
||||
int loop_counter = 0;
|
||||
int ret = 0;
|
||||
MSC_LOG_RX_MESSAGE(
|
||||
MSC_GTPU_GNB,
|
||||
MSC_RRC_GNB,
|
||||
NULL,0,
|
||||
MSC_AS_TIME_FMT" CREATE_TUNNEL_REQ RNTI %"PRIx16" inst %u ntuns %u psid %u upf-ngu teid %u",
|
||||
0,0,create_tunnel_req_pP->rnti, instanceP,
|
||||
create_tunnel_req_pP->num_tunnels, create_tunnel_req_pP->pdusession_id[0],
|
||||
create_tunnel_req_pP->upf_NGu_teid[0]);
|
||||
create_tunnel_resp_pP->rnti = create_tunnel_req_pP->rnti;
|
||||
create_tunnel_resp_pP->status = 0;
|
||||
create_tunnel_resp_pP->num_tunnels = 0;
|
||||
|
||||
for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) {
|
||||
ip_offset = 0;
|
||||
loop_counter = 0;
|
||||
pdusession_id = create_tunnel_req_pP->pdusession_id[i];
|
||||
LOG_D(GTPU, "Rx GTPV1U_GNB_CREATE_TUNNEL_REQ ue rnti %x pdu session id %u\n",
|
||||
create_tunnel_req_pP->rnti, pdusession_id);
|
||||
memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT));
|
||||
stack_req.apiType = NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT;
|
||||
|
||||
do {
|
||||
ngu_teid = gtpv1u_new_teid();
|
||||
LOG_D(GTPU, "gtpv1u_create_ngu_tunnel() 0x%x %u(dec)\n", ngu_teid, ngu_teid);
|
||||
stack_req.apiInfo.createTunnelEndPointInfo.teid = ngu_teid;
|
||||
stack_req.apiInfo.createTunnelEndPointInfo.hUlpSession = 0;
|
||||
stack_req.apiInfo.createTunnelEndPointInfo.hStackSession = 0;
|
||||
rc = nwGtpv1uProcessUlpReq(RC.nr_gtpv1u_data_g->gtpv1u_stack, &stack_req);
|
||||
LOG_D(GTPU, ".\n");
|
||||
loop_counter++;
|
||||
} while (rc != NW_GTPV1U_OK && loop_counter < 10);
|
||||
|
||||
if ( rc != NW_GTPV1U_OK && loop_counter == 10 ) {
|
||||
LOG_E(GTPU,"NwGtpv1uCreateTunnelEndPoint failed 10 times,start next loop\n");
|
||||
ret = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
//-----------------------
|
||||
// PDCP->GTPV1U mapping
|
||||
//-----------------------
|
||||
hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, (void **)>pv1u_ue_data_p);
|
||||
|
||||
if ((hash_rc == HASH_TABLE_KEY_NOT_EXISTS) || (hash_rc == HASH_TABLE_OK)) {
|
||||
if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) {
|
||||
gtpv1u_ue_data_p = calloc (1, sizeof(gtpv1u_ue_data_t));
|
||||
hash_rc = hashtable_insert(RC.nr_gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, gtpv1u_ue_data_p);
|
||||
AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting ue_mapping in GTPV1U hashtable");
|
||||
}
|
||||
|
||||
gtpv1u_ue_data_p->ue_id = create_tunnel_req_pP->rnti;
|
||||
gtpv1u_ue_data_p->instance_id = 0; // TO DO
|
||||
memcpy(&create_tunnel_resp_pP->gnb_addr.buffer,
|
||||
&RC.nr_gtpv1u_data_g->gnb_ip_address_for_NGu_up,
|
||||
sizeof (in_addr_t));
|
||||
|
||||
LOG_I(GTPU,"Configured GTPu address : %x\n",RC.nr_gtpv1u_data_g->gnb_ip_address_for_NGu_up);
|
||||
create_tunnel_resp_pP->gnb_addr.length = sizeof (in_addr_t);
|
||||
addrs_length_in_bytes = create_tunnel_req_pP->upf_addr[i].length / 8;
|
||||
AssertFatal((addrs_length_in_bytes == 4) ||
|
||||
(addrs_length_in_bytes == 16) ||
|
||||
(addrs_length_in_bytes == 20),
|
||||
"Bad transport layer address length %d (bits) %d (bytes)",
|
||||
create_tunnel_req_pP->upf_addr[i].length, addrs_length_in_bytes);
|
||||
|
||||
if ((addrs_length_in_bytes == 4) ||
|
||||
(addrs_length_in_bytes == 20)) {
|
||||
in_addr = *((in_addr_t *)create_tunnel_req_pP->upf_addr[i].buffer);
|
||||
ip_offset = 4;
|
||||
gtpv1u_ue_data_p->bearers[pdusession_id - GTPV1U_BEARER_OFFSET].upf_ip_addr = in_addr;
|
||||
}
|
||||
|
||||
if ((addrs_length_in_bytes == 16) ||
|
||||
(addrs_length_in_bytes == 20)) {
|
||||
memcpy(gtpv1u_ue_data_p->bearers[pdusession_id - GTPV1U_BEARER_OFFSET].upf_ip6_addr.s6_addr,
|
||||
&create_tunnel_req_pP->upf_addr[i].buffer[ip_offset],
|
||||
16);
|
||||
}
|
||||
|
||||
gtpv1u_ue_data_p->bearers[pdusession_id - GTPV1U_BEARER_OFFSET].state = BEARER_IN_CONFIG;
|
||||
gtpv1u_ue_data_p->bearers[pdusession_id - GTPV1U_BEARER_OFFSET].teid_gNB = ngu_teid;
|
||||
gtpv1u_ue_data_p->bearers[pdusession_id - GTPV1U_BEARER_OFFSET].teid_gNB_stack_session = stack_req.apiInfo.createTunnelEndPointInfo.hStackSession;
|
||||
gtpv1u_ue_data_p->bearers[pdusession_id - GTPV1U_BEARER_OFFSET].teid_upf = create_tunnel_req_pP->upf_NGu_teid[i];
|
||||
gtpv1u_ue_data_p->num_bearers++;
|
||||
create_tunnel_resp_pP->gnb_NGu_teid[i] = ngu_teid;
|
||||
|
||||
LOG_I(GTPU,"Copied to create_tunnel_resp tunnel: index %d target gNB ip %d.%d.%d.%d length %d gtp teid %u\n",
|
||||
i,
|
||||
create_tunnel_resp_pP->gnb_addr.buffer[0],
|
||||
create_tunnel_resp_pP->gnb_addr.buffer[1],
|
||||
create_tunnel_resp_pP->gnb_addr.buffer[2],
|
||||
create_tunnel_resp_pP->gnb_addr.buffer[3],
|
||||
create_tunnel_resp_pP->gnb_addr.length,
|
||||
create_tunnel_resp_pP->gnb_NGu_teid[i]);
|
||||
} else {
|
||||
create_tunnel_resp_pP->gnb_NGu_teid[i] = 0;
|
||||
create_tunnel_resp_pP->status = 0xFF;
|
||||
}
|
||||
|
||||
create_tunnel_resp_pP->pdusession_id[i] = pdusession_id;
|
||||
create_tunnel_resp_pP->num_tunnels += 1;
|
||||
//-----------------------
|
||||
// GTPV1U->PDCP mapping
|
||||
//-----------------------
|
||||
hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->teid_mapping, ngu_teid, (void **)>pv1u_teid_data_p);
|
||||
|
||||
if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) {
|
||||
gtpv1u_teid_data_p = calloc (1, sizeof(nr_gtpv1u_teid_data_t));
|
||||
gtpv1u_teid_data_p->gnb_id = 0; // TO DO
|
||||
gtpv1u_teid_data_p->ue_id = create_tunnel_req_pP->rnti;
|
||||
gtpv1u_teid_data_p->pdu_session_id = pdusession_id;
|
||||
hash_rc = hashtable_insert(RC.nr_gtpv1u_data_g->teid_mapping, ngu_teid, gtpv1u_teid_data_p);
|
||||
AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting teid mapping in GTPV1U hashtable");
|
||||
} else {
|
||||
create_tunnel_resp_pP->gnb_NGu_teid[i] = 0;
|
||||
create_tunnel_resp_pP->status = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_GTPU_GNB,
|
||||
MSC_RRC_GNB,
|
||||
NULL,0,
|
||||
"0 GTPV1U_GNB_CREATE_TUNNEL_RESP rnti %x teid %x",
|
||||
create_tunnel_resp_pP->rnti,
|
||||
ngu_teid);
|
||||
LOG_D(GTPU, "Tx GTPV1U_GNB_CREATE_TUNNEL_RESP ue rnti %x status %d\n",
|
||||
create_tunnel_req_pP->rnti,
|
||||
create_tunnel_resp_pP->status);
|
||||
//return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int gtpv1u_update_ngu_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP,
|
||||
const rnti_t prior_rnti
|
||||
) {
|
||||
/* Local tunnel end-point identifier */
|
||||
teid_t ngu_teid = 0;
|
||||
nr_gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL;
|
||||
nr_gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL;
|
||||
nr_gtpv1u_ue_data_t *gtpv1u_ue_data_new_p = NULL;
|
||||
//MessageDef *message_p = NULL;
|
||||
hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
|
||||
int i,j;
|
||||
uint8_t bearers_num = 0,bearers_total = 0;
|
||||
//-----------------------
|
||||
// PDCP->GTPV1U mapping
|
||||
//-----------------------
|
||||
hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->ue_mapping, prior_rnti, (void **)>pv1u_ue_data_p);
|
||||
|
||||
if(hash_rc != HASH_TABLE_OK) {
|
||||
LOG_E(GTPU,"Error get ue_mapping(rnti=%x) from GTPV1U hashtable error\n", prior_rnti);
|
||||
return -1;
|
||||
}
|
||||
|
||||
gtpv1u_ue_data_new_p = calloc (1, sizeof(nr_gtpv1u_ue_data_t));
|
||||
memcpy(gtpv1u_ue_data_new_p,gtpv1u_ue_data_p,sizeof(nr_gtpv1u_ue_data_t));
|
||||
gtpv1u_ue_data_new_p->ue_id = create_tunnel_req_pP->rnti;
|
||||
hash_rc = hashtable_insert(RC.nr_gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, gtpv1u_ue_data_new_p);
|
||||
|
||||
//AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting ue_mapping in GTPV1U hashtable");
|
||||
if ( hash_rc != HASH_TABLE_OK ) {
|
||||
LOG_E(GTPU,"Failed to insert ue_mapping(rnti=%x) in GTPV1U hashtable\n",create_tunnel_req_pP->rnti);
|
||||
return -1;
|
||||
} else {
|
||||
LOG_I(GTPU, "inserting ue_mapping(rnti=%x) in GTPV1U hashtable\n",
|
||||
create_tunnel_req_pP->rnti);
|
||||
}
|
||||
|
||||
hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->ue_mapping, prior_rnti);
|
||||
LOG_I(GTPU, "hashtable_remove ue_mapping(rnti=%x) in GTPV1U hashtable\n",
|
||||
prior_rnti);
|
||||
//-----------------------
|
||||
// GTPV1U->PDCP mapping
|
||||
//-----------------------
|
||||
bearers_total =gtpv1u_ue_data_new_p->num_bearers;
|
||||
|
||||
for(j = 0; j<GTPV1U_MAX_BEARERS_ID; j++) {
|
||||
if(gtpv1u_ue_data_new_p->bearers[j].state != BEARER_IN_CONFIG)
|
||||
continue;
|
||||
|
||||
bearers_num++;
|
||||
|
||||
for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) {
|
||||
if(j == (create_tunnel_req_pP->pdusession_id[i]-GTPV1U_BEARER_OFFSET))
|
||||
break;
|
||||
}
|
||||
|
||||
if(i < create_tunnel_req_pP->num_tunnels) {
|
||||
ngu_teid = gtpv1u_ue_data_new_p->bearers[j].teid_gNB;
|
||||
hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->teid_mapping, ngu_teid, (void **)>pv1u_teid_data_p);
|
||||
|
||||
if (hash_rc == HASH_TABLE_OK) {
|
||||
gtpv1u_teid_data_p->ue_id = create_tunnel_req_pP->rnti;
|
||||
gtpv1u_teid_data_p->pdu_session_id = create_tunnel_req_pP->pdusession_id[i];
|
||||
LOG_I(GTPU, "updata teid_mapping te_id %u (prior_rnti %x rnti %x) in GTPV1U hashtable\n",
|
||||
ngu_teid,prior_rnti,create_tunnel_req_pP->rnti);
|
||||
} else {
|
||||
LOG_W(GTPU, "Error get teid mapping(s1u_teid=%u) from GTPV1U hashtable", ngu_teid);
|
||||
}
|
||||
} else {
|
||||
ngu_teid = gtpv1u_ue_data_new_p->bearers[j].teid_gNB;
|
||||
hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->teid_mapping, ngu_teid);
|
||||
|
||||
if (hash_rc != HASH_TABLE_OK) {
|
||||
LOG_D(GTPU, "Removed user rnti %x , enb S1U teid %u not found\n", prior_rnti, ngu_teid);
|
||||
}
|
||||
|
||||
gtpv1u_ue_data_new_p->bearers[j].state = BEARER_DOWN;
|
||||
gtpv1u_ue_data_new_p->num_bearers--;
|
||||
LOG_I(GTPU, "delete teid_mapping te_id %u (rnti%x) bearer_id %d in GTPV1U hashtable\n",
|
||||
ngu_teid,prior_rnti,j+GTPV1U_BEARER_OFFSET);;
|
||||
}
|
||||
|
||||
if(bearers_num > bearers_total)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int gtpv1u_delete_ngu_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_gnb_delete_tunnel_req_t *const req_pP) {
|
||||
NwGtpv1uUlpApiT stack_req;
|
||||
NwGtpv1uRcT rc = NW_GTPV1U_FAILURE;
|
||||
MessageDef *message_p = NULL;
|
||||
nr_gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL;
|
||||
hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
|
||||
teid_t teid_gNB = 0;
|
||||
int pdusession_index = 0;
|
||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, 0, GTPV1U_GNB_DELETE_TUNNEL_RESP);
|
||||
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti = req_pP->rnti;
|
||||
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status = 0;
|
||||
hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->ue_mapping, req_pP->rnti, (void **)>pv1u_ue_data_p);
|
||||
|
||||
if (hash_rc == HASH_TABLE_OK) {
|
||||
for (pdusession_index = 0; pdusession_index < req_pP->num_pdusession; pdusession_index++) {
|
||||
teid_gNB = gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB;
|
||||
LOG_D(GTPU, "Rx GTPV1U_ENB_DELETE_TUNNEL user rnti %x eNB S1U teid %u eps bearer id %u\n",
|
||||
req_pP->rnti, teid_gNB, req_pP->pdusession_id[pdusession_index]);
|
||||
{
|
||||
memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT));
|
||||
stack_req.apiType = NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT;
|
||||
LOG_D(GTPU, "gtpv1u_delete_ngu_tunnel pdusession %u %u\n",
|
||||
req_pP->pdusession_id[pdusession_index],
|
||||
teid_gNB);
|
||||
stack_req.apiInfo.destroyTunnelEndPointInfo.hStackSessionHandle =
|
||||
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB_stack_session;
|
||||
rc = nwGtpv1uProcessUlpReq(RC.nr_gtpv1u_data_g->gtpv1u_stack, &stack_req);
|
||||
LOG_D(GTPU, ".\n");
|
||||
}
|
||||
|
||||
if (rc != NW_GTPV1U_OK) {
|
||||
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status |= 0xFF;
|
||||
LOG_E(GTPU, "NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT failed");
|
||||
}
|
||||
|
||||
//-----------------------
|
||||
// PDCP->GTPV1U mapping
|
||||
//-----------------------
|
||||
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].state = BEARER_DOWN;
|
||||
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB = 0;
|
||||
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_upf = 0;
|
||||
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].upf_ip_addr = 0;
|
||||
gtpv1u_ue_data_p->num_bearers -= 1;
|
||||
|
||||
if (gtpv1u_ue_data_p->num_bearers == 0) {
|
||||
hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->ue_mapping, req_pP->rnti);
|
||||
LOG_D(GTPU, "Removed user rnti %x,no more bearers configured\n", req_pP->rnti);
|
||||
}
|
||||
|
||||
//-----------------------
|
||||
// GTPV1U->PDCP mapping
|
||||
//-----------------------
|
||||
hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->teid_mapping, teid_gNB);
|
||||
|
||||
if (hash_rc != HASH_TABLE_OK) {
|
||||
LOG_D(GTPU, "Removed user rnti %x , gNB NGU teid %u not found\n", req_pP->rnti, teid_gNB);
|
||||
}
|
||||
}
|
||||
}// else silently do nothing
|
||||
|
||||
LOG_D(GTPU, "Tx GTPV1U_GNB_DELETE_TUNNEL_RESP user rnti %x gNB NGU teid %u status %u\n",
|
||||
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti,
|
||||
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).gnb_NGu_teid,
|
||||
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status);
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_GTPU_GNB,
|
||||
MSC_RRC_GNB,
|
||||
NULL,0,
|
||||
"0 GTPV1U_GNB_DELETE_TUNNEL_RESP rnti %x teid %x",
|
||||
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti,
|
||||
teid_gNB);
|
||||
return itti_send_msg_to_task(TASK_RRC_GNB, instanceP, message_p);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
static int gtpv1u_gNB_send_init_udp(const Gtpv1uNGReq *req) {
|
||||
// Create and alloc new message
|
||||
MessageDef *message_p;
|
||||
struct in_addr addr= {0};
|
||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, 0, UDP_INIT);
|
||||
|
||||
if (message_p == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
UDP_INIT(message_p).port = req->gnb_port_for_NGu_up;
|
||||
addr.s_addr = req->gnb_ip_address_for_NGu_up;
|
||||
UDP_INIT(message_p).address = inet_ntoa(addr);
|
||||
LOG_I(GTPU, "Tx UDP_INIT IP addr %s (%x)\n", UDP_INIT(message_p).address,UDP_INIT(message_p).port);
|
||||
MSC_LOG_EVENT(
|
||||
MSC_GTPU_ENB,
|
||||
"0 UDP bind %s:%u",
|
||||
UDP_INIT(message_p).address,
|
||||
UDP_INIT(message_p).port);
|
||||
return itti_send_msg_to_task(TASK_UDP, INSTANCE_DEFAULT, message_p);
|
||||
}
|
||||
|
||||
static int gtpv1u_ng_req(
|
||||
const instance_t instanceP,
|
||||
const Gtpv1uNGReq *const req) {
|
||||
memcpy(&RC.nr_gtpv1u_data_g->gnb_ip_address_for_NGu_up,
|
||||
&req->gnb_ip_address_for_NGu_up,
|
||||
sizeof (req->gnb_ip_address_for_NGu_up));
|
||||
gtpv1u_gNB_send_init_udp(req);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void *gtpv1u_gNB_process_itti_msg(void *notUsed) {
|
||||
/* Trying to fetch a message from the message queue.
|
||||
* If the queue is empty, this function will block till a
|
||||
* message is sent to the task.
|
||||
*/
|
||||
instance_t instance;
|
||||
MessageDef *received_message_p = NULL;
|
||||
int rc = 0;
|
||||
itti_receive_msg(TASK_GTPV1_U, &received_message_p);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_ENB_TASK, VCD_FUNCTION_IN);
|
||||
DevAssert(received_message_p != NULL);
|
||||
instance = received_message_p->ittiMsgHeader.originInstance;
|
||||
|
||||
switch (ITTI_MSG_ID(received_message_p)) {
|
||||
case GTPV1U_GNB_NG_REQ:
|
||||
gtpv1u_ng_req(instance, &received_message_p->ittiMsg.gtpv1uNGReq);
|
||||
break;
|
||||
|
||||
case GTPV1U_GNB_DELETE_TUNNEL_REQ:
|
||||
gtpv1u_delete_ngu_tunnel(instance, &received_message_p->ittiMsg.NRGtpv1uDeleteTunnelReq);
|
||||
break;
|
||||
|
||||
case TERMINATE_MESSAGE: {
|
||||
if (RC.nr_gtpv1u_data_g->ue_mapping != NULL) {
|
||||
hashtable_destroy (&(RC.nr_gtpv1u_data_g->ue_mapping));
|
||||
}
|
||||
|
||||
if (RC.nr_gtpv1u_data_g->teid_mapping != NULL) {
|
||||
hashtable_destroy (&(RC.nr_gtpv1u_data_g->teid_mapping));
|
||||
}
|
||||
|
||||
LOG_W(GTPU, " *** Exiting GTPU thread\n");
|
||||
itti_exit_task();
|
||||
}
|
||||
break;
|
||||
|
||||
case TIMER_HAS_EXPIRED:
|
||||
nwGtpv1uProcessTimeout(&received_message_p->ittiMsg.timer_has_expired.arg);
|
||||
break;
|
||||
|
||||
default: {
|
||||
LOG_E(GTPU, "Unkwnon message ID %d:%s\n",
|
||||
ITTI_MSG_ID(received_message_p),
|
||||
ITTI_MSG_NAME(received_message_p));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
rc = itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), received_message_p);
|
||||
AssertFatal(rc == EXIT_SUCCESS, "Failed to free memory (%d)!\n", rc);
|
||||
received_message_p = NULL;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_ENB_TASK, VCD_FUNCTION_OUT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *nr_gtpv1u_gNB_task(void *args) {
|
||||
int rc = 0;
|
||||
rc = nr_gtpv1u_gNB_init();
|
||||
AssertFatal(rc == 0, "gtpv1u_gNB_init Failed");
|
||||
itti_mark_task_ready(TASK_GTPV1_U);
|
||||
MSC_START_USE();
|
||||
|
||||
while(1) {
|
||||
(void) gtpv1u_gNB_process_itti_msg (NULL);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file gtpv1u_gNB_defs.h
|
||||
* \brief
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
* \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
* (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
*/
|
||||
|
||||
#include "hashtable.h"
|
||||
#include "NR_asn_constant.h"
|
||||
|
||||
#ifndef GTPV1U_GNB_DEFS_H_
|
||||
#define GTPV1U_GNB_DEFS_H_
|
||||
|
||||
#include "NwGtpv1u.h"
|
||||
|
||||
#define GTPV1U_UDP_PORT (2152)
|
||||
|
||||
#define NR_GTPV1U_MAX_BEARERS_ID (max_val_NR_DRB_Identity - 3)
|
||||
|
||||
#define GTPV1U_SOURCE_GNB (0)
|
||||
#define GTPV1U_TARGET_GNB (1)
|
||||
#define GTPV1U_MSG_FROM_SOURCE_GNB (0)
|
||||
#define GTPV1U_MSG_FROM_UPF (1)
|
||||
|
||||
|
||||
typedef struct nr_gtpv1u_teid_data_s {
|
||||
/* UE identifier for oaisim stack */
|
||||
module_id_t gnb_id;
|
||||
rnti_t ue_id;
|
||||
pdusessionid_t pdu_session_id;
|
||||
} nr_gtpv1u_teid_data_t;
|
||||
|
||||
|
||||
typedef struct nr_gtpv1u_bearer_s {
|
||||
/* TEID used in dl and ul */
|
||||
teid_t teid_gNB; ///< gNB TEID
|
||||
uintptr_t teid_gNB_stack_session; ///< gNB TEID
|
||||
teid_t teid_upf; ///< Remote TEID
|
||||
in_addr_t upf_ip_addr;
|
||||
struct in6_addr upf_ip6_addr;
|
||||
teid_t teid_tgNB;
|
||||
in_addr_t tgnb_ip_addr; ///< target gNB ipv4
|
||||
struct in6_addr tgnb_ip6_addr; ///< target gNB ipv6
|
||||
tcp_udp_port_t port;
|
||||
//NwGtpv1uStackSessionHandleT stack_session;
|
||||
bearer_state_t state;
|
||||
} nr_gtpv1u_bearer_t;
|
||||
|
||||
typedef struct nr_gtpv1u_ue_data_s {
|
||||
/* UE identifier for oaisim stack */
|
||||
rnti_t ue_id;
|
||||
|
||||
/* Unique identifier used between PDCP and GTP-U to distinguish UEs */
|
||||
uint32_t instance_id;
|
||||
int num_bearers;
|
||||
/* Bearer related data.
|
||||
* Note that the first LCID available for data is 3 and we fixed the maximum
|
||||
* number of e-rab per UE to be (32 [id range]), max RB is 11. The real rb id will 3 + rab_id (3..32).
|
||||
*/
|
||||
nr_gtpv1u_bearer_t bearers[NR_GTPV1U_MAX_BEARERS_ID];
|
||||
|
||||
//RB_ENTRY(gtpv1u_ue_data_s) gtpv1u_ue_node;
|
||||
} nr_gtpv1u_ue_data_t;
|
||||
|
||||
typedef struct nr_gtpv1u_data_s {
|
||||
/* nwgtpv1u stack internal data */
|
||||
NwGtpv1uStackHandleT gtpv1u_stack;
|
||||
|
||||
/* RB tree of UEs */
|
||||
hash_table_t *ue_mapping; // PDCP->GTPV1U
|
||||
hash_table_t *teid_mapping; // GTPV1U -> PDCP
|
||||
|
||||
//RB_HEAD(gtpv1u_ue_map, gtpv1u_ue_data_s) gtpv1u_ue_map_head;
|
||||
/* Local IP address to use */
|
||||
in_addr_t gnb_ip_address_for_NGu_up;
|
||||
/* UDP internal data */
|
||||
//udp_data_t udp_data;
|
||||
|
||||
uint16_t seq_num;
|
||||
uint8_t restart_counter;
|
||||
|
||||
#ifdef GTPU_IN_KERNEL
|
||||
char *interface_name;
|
||||
int interface_index;
|
||||
|
||||
struct iovec *malloc_ring;
|
||||
void *sock_mmap_ring[16];
|
||||
int sock_desc[16]; // indexed by marking
|
||||
#endif
|
||||
} nr_gtpv1u_data_t;
|
||||
|
||||
|
||||
#endif /* GTPV1U_GNB_DEFS_H_ */
|
||||
@@ -32,6 +32,20 @@ int gtpv1u_gNB_init(void);
|
||||
|
||||
void *gtpv1u_gNB_task(void *args);
|
||||
|
||||
void *nr_gtpv1u_gNB_task(void *args);
|
||||
|
||||
int
|
||||
gtpv1u_create_ngu_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_gnb_create_tunnel_req_t * const create_tunnel_req_pP,
|
||||
gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP);
|
||||
|
||||
int
|
||||
gtpv1u_update_ngu_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP,
|
||||
const rnti_t prior_rnti
|
||||
);
|
||||
|
||||
#endif /* GTPV1U_GNB_TASK_H_ */
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file FGSAuthenticationResponse.c
|
||||
|
||||
\brief authentication response procedures
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nas_log.h"
|
||||
|
||||
#include "FGSAuthenticationResponse.h"
|
||||
|
||||
|
||||
int encode_fgs_authentication_response(fgs_authentication_response_msg *authentication_response, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
int encoded = 0;
|
||||
int encode_result = 0;
|
||||
|
||||
|
||||
if ((encode_result =
|
||||
encode_authentication_response_parameter(&authentication_response->authenticationresponseparameter,
|
||||
AUTHENTICATION_RESPONSE_PARAMETER_IEI, buffer + encoded, len - encoded)) < 0) //Return in case of error
|
||||
return encode_result;
|
||||
else
|
||||
encoded += encode_result;
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file FGSAuthenticationResponse.h
|
||||
|
||||
\brief authentication response procedures
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ExtendedProtocolDiscriminator.h"
|
||||
#include "SecurityHeaderType.h"
|
||||
#include "SpareHalfOctet.h"
|
||||
#include "MessageType.h"
|
||||
#include "AuthenticationResponseParameter.h"
|
||||
|
||||
#ifndef FGS_AUTHENTICATION_RESPONSE_H_
|
||||
#define FGS_AUTHENTICATION_RESPONSE_H_
|
||||
|
||||
#define AUTHENTICATION_RESPONSE_PARAMETER_IEI 0x2d
|
||||
|
||||
/*
|
||||
* Message name: Identity response
|
||||
* Description: This message is sent by the UE to the AMF to provide the requested identity. See table 8.2.22.1.
|
||||
* Significance: dual
|
||||
* Direction: UE to AMF
|
||||
*/
|
||||
|
||||
typedef struct fgs_authentication_response_msg_tag {
|
||||
/* Mandatory fields */
|
||||
ExtendedProtocolDiscriminator protocoldiscriminator;
|
||||
SecurityHeaderType securityheadertype:4;
|
||||
SpareHalfOctet sparehalfoctet:4;
|
||||
MessageType messagetype;
|
||||
AuthenticationResponseParameter authenticationresponseparameter;
|
||||
} fgs_authentication_response_msg;
|
||||
|
||||
int encode_fgs_authentication_response(fgs_authentication_response_msg *authentication_response, uint8_t *buffer, uint32_t len);
|
||||
|
||||
#endif /* ! defined(FGS_AUTHENTICATION_RESPONSE_H_) */
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -20,38 +18,39 @@
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
#include <openair2/RRC/LTE/MESSAGES/asn1_msg.h>
|
||||
#include <openair2/RRC/NR/nr_rrc_proto.h>
|
||||
|
||||
void rrc_gNB_process_NGAP_DOWNLINK_NAS (void ) {
|
||||
do_DLInformationTransfer(0,NULL,0,0,NULL);
|
||||
// send it as DL data
|
||||
/*
|
||||
rrc_data_req (
|
||||
&ctxt,
|
||||
srb_id,
|
||||
(*rrc_eNB_mui)++,
|
||||
SDU_CONFIRM_NO,
|
||||
length,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
/*! \file FGSIdentityResponse.c
|
||||
|
||||
\brief identity response procedures for gNB
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nas_log.h"
|
||||
|
||||
#include "FGSIdentityResponse.h"
|
||||
|
||||
|
||||
int encode_identiy_response(fgs_identiy_response_msg *fgs_identity_reps, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
int encoded = 0;
|
||||
int encode_result = 0;
|
||||
|
||||
if ((encode_result =
|
||||
encode_5gs_mobile_identity(&fgs_identity_reps->fgsmobileidentity, 0, buffer +
|
||||
encoded, len - encoded)) < 0) //Return in case of error
|
||||
return encode_result;
|
||||
else
|
||||
encoded += encode_result;
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
void rrc_gNB_send_NGAP_NAS_FIRST_REQ(void ) {
|
||||
// We are noCore only now
|
||||
// create message that should come from 5GC
|
||||
|
||||
// send it dow
|
||||
rrc_gNB_process_NGAP_DOWNLINK_NAS();
|
||||
}
|
||||
|
||||
void nr_rrc_rx_tx() {
|
||||
// check timers
|
||||
|
||||
// check if UEs are lost, to remove them from upper layers
|
||||
|
||||
//
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file FGSIdentityResponse.h
|
||||
|
||||
\brief identity response procedures for gNB
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ExtendedProtocolDiscriminator.h"
|
||||
#include "SecurityHeaderType.h"
|
||||
#include "SpareHalfOctet.h"
|
||||
#include "FGSMobileIdentity.h"
|
||||
#include "MessageType.h"
|
||||
|
||||
#ifndef FGS_IDENTITY_RESPONSE_H_
|
||||
#define FGS_IDENTITY_RESPONSE_H_
|
||||
|
||||
/*
|
||||
* Message name: Identity response
|
||||
* Description: This message is sent by the UE to the AMF to provide the requested identity. See table 8.2.22.1.
|
||||
* Significance: dual
|
||||
* Direction: UE to AMF
|
||||
*/
|
||||
|
||||
typedef struct fgs_identiy_response_msg_tag {
|
||||
/* Mandatory fields */
|
||||
ExtendedProtocolDiscriminator protocoldiscriminator;
|
||||
SecurityHeaderType securityheadertype:4;
|
||||
SpareHalfOctet sparehalfoctet:4;
|
||||
MessageType messagetype;
|
||||
FGSMobileIdentity fgsmobileidentity;
|
||||
|
||||
} fgs_identiy_response_msg;
|
||||
|
||||
int encode_identiy_response(fgs_identiy_response_msg *fgs_identity_reps, uint8_t *buffer, uint32_t len);
|
||||
|
||||
#endif /* ! defined(FGS_IDENTITY_RESPONSE_H_) */
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file FGSNASSecurityModeComplete.c
|
||||
|
||||
\brief security mode complete procedures for gNB
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nas_log.h"
|
||||
|
||||
#include "FGSNASSecurityModeComplete.h"
|
||||
#include "FGSMobileIdentity.h"
|
||||
#include "FGCNasMessageContainer.h"
|
||||
|
||||
int encode_fgs_security_mode_complete(fgs_security_mode_complete_msg *fgs_security_mode_comp, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
int encoded = 0;
|
||||
int encode_result = 0;
|
||||
|
||||
if ((encode_result =
|
||||
encode_5gs_mobile_identity(&fgs_security_mode_comp->fgsmobileidentity, 0x77, buffer +
|
||||
encoded, len - encoded)) < 0) { //Return in case of error
|
||||
return encode_result;
|
||||
} else {
|
||||
encoded += encode_result;
|
||||
if ((encode_result =
|
||||
encode_fgc_nas_message_container(&fgs_security_mode_comp->fgsnasmessagecontainer, 0x71, buffer +
|
||||
encoded, len - encoded)) < 0) {
|
||||
return encode_result;
|
||||
} else {
|
||||
encoded += encode_result;
|
||||
}
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file FGSNASSecurityModeComplete.h
|
||||
|
||||
\brief security mode complete procedures for gNB
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ExtendedProtocolDiscriminator.h"
|
||||
#include "SecurityHeaderType.h"
|
||||
#include "SpareHalfOctet.h"
|
||||
#include "FGSMobileIdentity.h"
|
||||
#include "MessageType.h"
|
||||
#include "FGCNasMessageContainer.h"
|
||||
|
||||
#ifndef FGS_NAS_SECURITY_MODE_COMPLETE_H_
|
||||
#define FGS_NAS_SECURITY_MODE_COMPLETE_H_
|
||||
|
||||
/*
|
||||
* Message name: security mode complete
|
||||
* Description: This message is sent by the UE to the AMF in response to a SECURITY MODE COMMAND message. See table 8.2.26.1.1.
|
||||
* Significance: dual
|
||||
* Direction: UE to AMF
|
||||
*/
|
||||
|
||||
typedef struct fgs_security_mode_complete_msg_tag {
|
||||
/* Mandatory fields */
|
||||
ExtendedProtocolDiscriminator protocoldiscriminator;
|
||||
SecurityHeaderType securityheadertype:4;
|
||||
SpareHalfOctet sparehalfoctet:4;
|
||||
MessageType messagetype;
|
||||
FGSMobileIdentity fgsmobileidentity;
|
||||
FGCNasMessageContainer fgsnasmessagecontainer;
|
||||
} fgs_security_mode_complete_msg;
|
||||
|
||||
int encode_fgs_security_mode_complete(fgs_security_mode_complete_msg *fgs_security_mode_comp, uint8_t *buffer, uint32_t len);
|
||||
|
||||
#endif /* ! defined(FGS_NAS_SECURITY_MODE_COMPLETE_H_) */
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file FGSUplinkNasTransport.c
|
||||
|
||||
\brief uplink nas transport procedures
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "FGSUplinkNasTransport.h"
|
||||
#include "TLVEncoder.h"
|
||||
|
||||
int encode_fgs_payload_container(FGSPayloadContainer *paycontainer, uint8_t iei, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
int encode_result;
|
||||
|
||||
if (iei > 0) {
|
||||
*buffer = iei;
|
||||
encoded++;
|
||||
}
|
||||
|
||||
encoded += 2;
|
||||
|
||||
if ((encode_result = encode_octet_string(&paycontainer->payloadcontainercontents, buffer + encoded, len - encoded)) < 0) {
|
||||
return encode_result;
|
||||
} else {
|
||||
encoded += encode_result;
|
||||
}
|
||||
if(iei > 0){
|
||||
*(uint16_t*) (buffer+1) = htons(encoded - 3);
|
||||
} else {
|
||||
*(uint16_t*) (buffer) = htons(encoded - 2);
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
int encode_nssai(OctetString *nssai, uint8_t iei, uint8_t *buffer)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
int encode_result;
|
||||
|
||||
if (iei > 0) {
|
||||
*buffer = iei;
|
||||
encoded++;
|
||||
}
|
||||
|
||||
*(buffer + encoded) = nssai->length;
|
||||
encoded++;
|
||||
|
||||
|
||||
if ((encode_result = encode_octet_string(nssai, buffer + encoded, nssai->length)) < 0) {
|
||||
return encode_result;
|
||||
} else {
|
||||
encoded += encode_result;
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
int encode_dnn(OctetString *dnn, uint8_t iei, uint8_t *buffer)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
int encode_result;
|
||||
|
||||
if (iei > 0) {
|
||||
*buffer = iei;
|
||||
encoded++;
|
||||
}
|
||||
|
||||
*(buffer + encoded) = dnn->length;
|
||||
encoded++;
|
||||
|
||||
if ((encode_result = encode_octet_string(dnn, buffer + encoded, dnn->length)) < 0) {
|
||||
return encode_result;
|
||||
} else {
|
||||
encoded += encode_result;
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
int encode_fgs_uplink_nas_transport(fgs_uplink_nas_transport_msg *fgs_up_nas_transport, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
int encoded = 0;
|
||||
int encode_result = 0;
|
||||
|
||||
*(buffer + encoded) = (fgs_up_nas_transport->payloadcontainertype.iei << 4) | (fgs_up_nas_transport->payloadcontainertype.type &0xf);
|
||||
encoded++;
|
||||
|
||||
if ((encode_result = encode_fgs_payload_container(&fgs_up_nas_transport->fgspayloadcontainer,
|
||||
0, buffer +encoded, len - encoded)) < 0) {
|
||||
return encode_result;
|
||||
} else {
|
||||
encoded += encode_result;
|
||||
}
|
||||
|
||||
*(buffer + encoded) = 0x12;
|
||||
encoded++;
|
||||
|
||||
IES_ENCODE_U8(buffer, encoded, fgs_up_nas_transport->pdusessionid);
|
||||
|
||||
// set request type
|
||||
*(buffer + encoded) = (0x8<<4)|(fgs_up_nas_transport->requesttype &0x7);
|
||||
encoded++;
|
||||
|
||||
if ((encode_result = encode_nssai(&fgs_up_nas_transport->snssai, 0x22, buffer +encoded)) < 0) {
|
||||
return encode_result;
|
||||
} else {
|
||||
encoded += encode_result;
|
||||
}
|
||||
|
||||
if ((encode_result = encode_dnn(&fgs_up_nas_transport->dnn, 0x25, buffer +encoded)) < 0) {
|
||||
return encode_result;
|
||||
} else {
|
||||
encoded += encode_result;
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file FGSUplinkNasTransport.h
|
||||
|
||||
\brief uplink nas transport procedures
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ExtendedProtocolDiscriminator.h"
|
||||
#include "SecurityHeaderType.h"
|
||||
#include "SpareHalfOctet.h"
|
||||
#include "MessageType.h"
|
||||
|
||||
#ifndef FGS_UPLINK_NAS_TRANSPORT_H_
|
||||
#define FGS_UPLINK_NAS_TRANSPORT_H_
|
||||
|
||||
/*
|
||||
* Message name: uplink nas transpaort
|
||||
* Description: The UL NAS TRANSPORT message transports message payload and associated information to the AMF. See table 8.2.10.1.1.
|
||||
* Significance: dual
|
||||
* Direction: UE to network
|
||||
*/
|
||||
|
||||
typedef struct PayloadContainerType_tag{
|
||||
uint8_t iei:4;
|
||||
uint8_t type:4;
|
||||
}PayloadContainerType;
|
||||
typedef struct FGSPayloadContainer_tag {
|
||||
OctetString payloadcontainercontents;
|
||||
} FGSPayloadContainer;
|
||||
|
||||
typedef struct fgs_uplink_nas_transport_msg_tag {
|
||||
/* Mandatory fields */
|
||||
ExtendedProtocolDiscriminator protocoldiscriminator;
|
||||
SecurityHeaderType securityheadertype:4;
|
||||
SpareHalfOctet sparehalfoctet:4;
|
||||
MessageType messagetype;
|
||||
PayloadContainerType payloadcontainertype;
|
||||
FGSPayloadContainer fgspayloadcontainer;
|
||||
/* Optional fields */
|
||||
uint16_t pdusessionid;
|
||||
uint8_t requesttype;
|
||||
OctetString snssai;
|
||||
OctetString dnn;
|
||||
} fgs_uplink_nas_transport_msg;
|
||||
|
||||
int encode_fgs_uplink_nas_transport(fgs_uplink_nas_transport_msg *fgs_security_mode_comp, uint8_t *buffer, uint32_t len);
|
||||
|
||||
#endif /* ! defined(FGS_UPLINK_NAS_TRANSPORT_H_) */
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file RegistrationAccept.c
|
||||
|
||||
\brief 5GS registration accept procedures
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "TLVEncoder.h"
|
||||
#include "TLVDecoder.h"
|
||||
#include "RegistrationAccept.h"
|
||||
#include "assertions.h"
|
||||
|
||||
int decode_registration_accept(registration_accept_msg *registration_accept, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
uint32_t decoded = 0;
|
||||
int decoded_result = 0;
|
||||
|
||||
/* Decoding mandatory fields */
|
||||
if ((decoded_result = decode_fgs_registration_result(®istration_accept->fgsregistrationresult, 0, *(buffer + decoded), len - decoded)) < 0)
|
||||
return decoded_result;
|
||||
|
||||
decoded += decoded_result;
|
||||
|
||||
// todo ,Decoding optional fields
|
||||
return decoded;
|
||||
}
|
||||
|
||||
int encode_registration_accept(registration_accept_msg *registration_accept, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
int encoded = 0;
|
||||
|
||||
LOG_FUNC_IN;
|
||||
|
||||
|
||||
*(buffer + encoded) = encode_fgs_registration_result(®istration_accept->fgsregistrationresult);
|
||||
encoded = encoded + 2;
|
||||
|
||||
// todo ,Encoding optional fields
|
||||
LOG_FUNC_RETURN(encoded);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file RegistrationAccept.h
|
||||
|
||||
\brief 5GS registration accept procedures
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "ExtendedProtocolDiscriminator.h"
|
||||
#include "SecurityHeaderType.h"
|
||||
#include "SpareHalfOctet.h"
|
||||
#include "MessageType.h"
|
||||
#include "FGSRegistrationResult.h"
|
||||
|
||||
#ifndef REGISTRATION_ACCEPT_H_
|
||||
#define REGISTRATION_ACCEPT_H_
|
||||
|
||||
/*
|
||||
* Message name: Registration accept
|
||||
* Description: The REGISTRATION ACCEPT message is sent by the AMF to the UE. See table 8.2.7.1.1.
|
||||
* Significance: dual
|
||||
* Direction: network to UE
|
||||
*/
|
||||
|
||||
typedef struct registration_accept_msg_tag {
|
||||
/* Mandatory fields */
|
||||
ExtendedProtocolDiscriminator protocoldiscriminator;
|
||||
SecurityHeaderType securityheadertype:4;
|
||||
SpareHalfOctet sparehalfoctet:4;
|
||||
MessageType messagetype;
|
||||
FGSRegistrationResult fgsregistrationresult;
|
||||
} registration_accept_msg;
|
||||
|
||||
int decode_registration_accept(registration_accept_msg *registrationaccept, uint8_t *buffer, uint32_t len);
|
||||
|
||||
int encode_registration_accept(registration_accept_msg *registrationaccept, uint8_t *buffer, uint32_t len);
|
||||
|
||||
#endif /* ! defined(REGISTRATION_ACCEPT_H_) */
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "TLVEncoder.h"
|
||||
#include "TLVDecoder.h"
|
||||
#include "RegistrationComplete.h"
|
||||
#include "SORTransparentContainer.h"
|
||||
|
||||
int decode_registration_complete(registration_complete_msg *registration_complete, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
uint32_t decoded = 0;
|
||||
int decoded_result = 0;
|
||||
|
||||
/* Decoding mandatory fields */
|
||||
if ((decoded_result = decode_sor_transparent_container(®istration_complete->sortransparentcontainer, 0, buffer + decoded, len - decoded)) < 0)
|
||||
return decoded_result;
|
||||
else
|
||||
decoded += decoded_result;
|
||||
|
||||
return decoded;
|
||||
}
|
||||
|
||||
int encode_registration_complete(registration_complete_msg *registration_complete, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
int encoded = 0;
|
||||
int encode_result = 0;
|
||||
|
||||
if ((encode_result =
|
||||
encode_sor_transparent_container(®istration_complete->sortransparentcontainer, 0,
|
||||
buffer + encoded, len - encoded)) < 0) //Return in case of error
|
||||
return encode_result;
|
||||
else
|
||||
encoded += encode_result;
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file RegistrationRequest.h
|
||||
|
||||
\brief registration request procedures for gNB
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ExtendedProtocolDiscriminator.h"
|
||||
#include "SecurityHeaderType.h"
|
||||
#include "SpareHalfOctet.h"
|
||||
#include "MessageType.h"
|
||||
#include "SORTransparentContainer.h"
|
||||
|
||||
#ifndef REGISTRATION_COMPLETE_H_
|
||||
#define REGISTRATION_COMPLETE_H_
|
||||
|
||||
|
||||
typedef struct registration_complete_msg_tag {
|
||||
/* Mandatory fields */
|
||||
ExtendedProtocolDiscriminator protocoldiscriminator;
|
||||
SecurityHeaderType securityheadertype:4;
|
||||
SpareHalfOctet sparehalfoctet:4;
|
||||
MessageType messagetype;
|
||||
|
||||
/* Optional fields */
|
||||
SORTransparentContainer sortransparentcontainer;
|
||||
} registration_complete_msg;
|
||||
|
||||
|
||||
int decode_registration_complete(registration_complete_msg *registrationcomplete, uint8_t *buffer, uint32_t len);
|
||||
|
||||
int encode_registration_complete(registration_complete_msg *registrationcomplete, uint8_t *buffer, uint32_t len);
|
||||
|
||||
#endif /* ! defined(REGISTRATION_COMPLETE_H_) */
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file PduSessionEstablishRequest.c
|
||||
|
||||
\brief pdu session establishment request procedures
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "TLVEncoder.h"
|
||||
#include "TLVDecoder.h"
|
||||
#include "PduSessionEstablishRequest.h"
|
||||
|
||||
|
||||
int encode_pdu_session_establishment_request(pdu_session_establishment_request_msg *pdusessionestablishrequest, uint8_t *buffer)
|
||||
{
|
||||
int encoded = 0;
|
||||
|
||||
|
||||
*(buffer + encoded) = pdusessionestablishrequest->protocoldiscriminator;
|
||||
encoded++;
|
||||
*(buffer + encoded) = pdusessionestablishrequest->pdusessionid;
|
||||
encoded++;
|
||||
*(buffer + encoded) = pdusessionestablishrequest->pti;
|
||||
encoded++;
|
||||
*(buffer + encoded) = pdusessionestablishrequest->pdusessionestblishmsgtype;
|
||||
encoded++;
|
||||
|
||||
IES_ENCODE_U16(buffer, encoded, pdusessionestablishrequest->maxdatarate);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file PduSessionEstablishRequest.h
|
||||
|
||||
\brief pdu session establishment request procedures
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ExtendedProtocolDiscriminator.h"
|
||||
#include "MessageType.h"
|
||||
|
||||
#ifndef PDU_SESSION_ESTABLISHMENT_REQUEST_H_
|
||||
#define PDU_SESSION_ESTABLISHMENT_REQUEST_H_
|
||||
|
||||
|
||||
/*
|
||||
* Message name: pdu session establishment request
|
||||
* Description: The PDU SESSION ESTABLISHMENT REQUEST message is sent by the UE to the SMF to initiate establishment of a PDU session. See table 8.3.1.1.1.
|
||||
* Significance: dual
|
||||
* Direction: UE to network
|
||||
*/
|
||||
|
||||
typedef struct pdu_session_establishment_request_msg_tag {
|
||||
/* Mandatory fields */
|
||||
ExtendedProtocolDiscriminator protocoldiscriminator;
|
||||
uint8_t pdusessionid;
|
||||
uint8_t pti;
|
||||
MessageType pdusessionestblishmsgtype;
|
||||
uint16_t maxdatarate;
|
||||
/* Optional fields */
|
||||
} pdu_session_establishment_request_msg;
|
||||
|
||||
|
||||
int encode_pdu_session_establishment_request(pdu_session_establishment_request_msg *pdusessionestablishrequest, uint8_t *buffer);
|
||||
|
||||
#endif /* ! defined(PDU_SESSION_ESTABLISHMENT_REQUEST_H_) */
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file FGCNasMessageContainer.c
|
||||
|
||||
\brief security mode complete procedures for gNB
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "TLVEncoder.h"
|
||||
#include "TLVDecoder.h"
|
||||
#include "FGCNasMessageContainer.h"
|
||||
|
||||
int decode_fgc_nas_message_container(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
int decoded = 0;
|
||||
uint8_t ielen = 0;
|
||||
int decode_result;
|
||||
|
||||
if (iei > 0) {
|
||||
CHECK_IEI_DECODER(iei, *buffer);
|
||||
decoded++;
|
||||
}
|
||||
|
||||
ielen = *(buffer + decoded);
|
||||
decoded += 2;
|
||||
CHECK_LENGTH_DECODER(len - decoded, ielen);
|
||||
|
||||
if ((decode_result = decode_octet_string(&nasmessagecontainer->nasmessagecontainercontents, ielen, buffer + decoded, len - decoded)) < 0)
|
||||
return decode_result;
|
||||
else
|
||||
decoded += decode_result;
|
||||
|
||||
return decoded;
|
||||
}
|
||||
int encode_fgc_nas_message_container(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
int encode_result;
|
||||
/* Checking IEI and pointer */
|
||||
CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, FGC_NAS_MESSAGE_CONTAINER_MINIMUM_LENGTH, len);
|
||||
|
||||
if (iei > 0) {
|
||||
*buffer = iei;
|
||||
encoded++;
|
||||
}
|
||||
|
||||
encoded += 2;
|
||||
|
||||
if ((encode_result = encode_octet_string(&nasmessagecontainer->nasmessagecontainercontents, buffer + encoded, len - encoded)) < 0) {
|
||||
return encode_result;
|
||||
} else {
|
||||
*(uint16_t*) (buffer+1) = htons(encoded + encode_result - 3);
|
||||
encoded += encode_result;
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
void dump_fgc_nas_message_container_xml(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei)
|
||||
{
|
||||
printf("<Nas Message Container>\n");
|
||||
|
||||
if (iei > 0)
|
||||
/* Don't display IEI if = 0 */
|
||||
printf(" <IEI>0x%X</IEI>\n", iei);
|
||||
|
||||
printf("%s", dump_octet_string_xml(&nasmessagecontainer->nasmessagecontainercontents));
|
||||
printf("</Nas Message Container>\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file FGCNasMessageContainer.h
|
||||
|
||||
\brief security mode complete procedures for gNB
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "OctetString.h"
|
||||
|
||||
#ifndef FGC_NAS_MESSAGE_CONTAINER_H_
|
||||
#define FGC_NAS_MESSAGE_CONTAINER_H_
|
||||
|
||||
#define FGC_NAS_MESSAGE_CONTAINER_MINIMUM_LENGTH 4
|
||||
#define FGC_NAS_MESSAGE_CONTAINER_MAXIMUM_LENGTH 65535
|
||||
|
||||
typedef struct FGCNasMessageContainer_tag {
|
||||
OctetString nasmessagecontainercontents;
|
||||
} FGCNasMessageContainer;
|
||||
|
||||
int encode_fgc_nas_message_container(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei, uint8_t *buffer, uint32_t len);
|
||||
|
||||
int decode_fgc_nas_message_container(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei, uint8_t *buffer, uint32_t len);
|
||||
|
||||
void dump_fgc_nas_message_container_xml(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei);
|
||||
|
||||
#endif /* FGC NAS MESSAGE CONTAINER_H_ */
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
static int decode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer);
|
||||
|
||||
static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer);
|
||||
static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_t *buffer);
|
||||
static int encode_imeisv_5gs_mobile_identity(Imeisv5GSMobileIdentity_t *imeisv, uint8_t *buffer);
|
||||
|
||||
int decode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
@@ -87,11 +89,26 @@ int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei
|
||||
buffer + encoded);
|
||||
}
|
||||
|
||||
if (fgsmobileidentity->suci.typeofidentity == FGS_MOBILE_IDENTITY_SUCI) {
|
||||
encoded_rc = encode_suci_5gs_mobile_identity(&fgsmobileidentity->suci,
|
||||
buffer + encoded);
|
||||
}
|
||||
|
||||
if (fgsmobileidentity->imeisv.typeofidentity == FGS_MOBILE_IDENTITY_IMEISV) {
|
||||
encoded_rc = encode_imeisv_5gs_mobile_identity(&fgsmobileidentity->imeisv,
|
||||
buffer + encoded);
|
||||
}
|
||||
|
||||
if (encoded_rc < 0) {
|
||||
return encoded_rc;
|
||||
}
|
||||
|
||||
*(uint16_t*) buffer = htons(encoded + encoded_rc - 2 - ((iei > 0) ? 1 : 0));
|
||||
if(iei > 0){
|
||||
*(uint16_t*) (buffer+1) = htons(encoded + encoded_rc - 3);
|
||||
} else {
|
||||
*(uint16_t*) buffer = htons(encoded + encoded_rc - 2);
|
||||
}
|
||||
|
||||
return (encoded + encoded_rc);
|
||||
}
|
||||
|
||||
@@ -166,10 +183,57 @@ static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_
|
||||
*(buffer + encoded) = guti->amfregionid;
|
||||
encoded++;
|
||||
|
||||
temp = 0x00 | ((guti->amfsetid & 0x3f) << 6) | (guti->amfpointer & 0x3f);
|
||||
temp = 0x00 | ((guti->amfsetid) << 6) | (guti->amfpointer & 0x3f);
|
||||
|
||||
IES_ENCODE_U16(buffer, encoded, temp);
|
||||
IES_ENCODE_U32(buffer, encoded, guti->tmsi);
|
||||
return encoded;
|
||||
}
|
||||
|
||||
|
||||
static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_t *buffer)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
*(buffer + encoded) = 0x00 | (suci->supiformat << 4) | (suci->typeofidentity);
|
||||
encoded++;
|
||||
*(buffer + encoded) = 0x00 | ((suci->mccdigit2 & 0xf) << 4) |
|
||||
(suci->mccdigit1 & 0xf);
|
||||
encoded++;
|
||||
*(buffer + encoded) = 0x00 | ((suci->mncdigit3 & 0xf) << 4) |
|
||||
(suci->mccdigit3 & 0xf);
|
||||
encoded++;
|
||||
*(buffer + encoded) = 0x00 | ((suci->mncdigit2 & 0xf) << 4) |
|
||||
(suci->mncdigit1 & 0xf);
|
||||
encoded++;
|
||||
|
||||
*(buffer + encoded) = 0x00 | ((suci->routingindicatordigit2 & 0xf) << 4) |
|
||||
(suci->routingindicatordigit1 & 0xf);
|
||||
encoded++;
|
||||
|
||||
*(buffer + encoded) = 0x00 | ((suci->routingindicatordigit4 & 0xf) << 4) |
|
||||
(suci->routingindicatordigit3 & 0xf);
|
||||
encoded++;
|
||||
|
||||
*(buffer + encoded) = 0x00 | (suci->protectionschemeId & 0xf);
|
||||
encoded++;
|
||||
|
||||
*(buffer + encoded) = suci->homenetworkpki;
|
||||
encoded++;
|
||||
|
||||
IES_ENCODE_U32(buffer, encoded, suci->schemeoutput);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static int encode_imeisv_5gs_mobile_identity(Imeisv5GSMobileIdentity_t *imeisv, uint8_t *buffer)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
*(buffer + encoded) = 0x00 | (imeisv->digit1 << 4) | (imeisv->oddeven << 3) | (imeisv->typeofidentity);
|
||||
encoded++;
|
||||
|
||||
*(buffer + encoded) = 0x00 | (imeisv->digitp1 << 4) | (imeisv->digitp);
|
||||
encoded++;
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ typedef struct {
|
||||
uint8_t spare6:1;
|
||||
uint8_t protectionschemeId:4;
|
||||
uint8_t homenetworkpki;
|
||||
uint32_t schemeoutput;
|
||||
} Suci5GSMobileIdentity_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file FGSRegistrationResult.c
|
||||
|
||||
\brief 5GS Registration result for registration request procedures
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "TLVEncoder.h"
|
||||
#include "TLVDecoder.h"
|
||||
#include "FGSRegistrationResult.h"
|
||||
|
||||
|
||||
int decode_fgs_registration_result(FGSRegistrationResult *fgsregistrationresult, uint8_t iei, uint16_t value, uint32_t len)
|
||||
{
|
||||
int decoded = 0;
|
||||
uint16_t *buffer = &value;
|
||||
fgsregistrationresult->registrationresult = *buffer & 0x7;
|
||||
fgsregistrationresult->smsallowed = *buffer & 0x8;
|
||||
decoded = decoded+2;
|
||||
return decoded;
|
||||
}
|
||||
|
||||
uint16_t encode_fgs_registration_result(FGSRegistrationResult *fgsregistrationresult)
|
||||
{
|
||||
uint16_t bufferReturn;
|
||||
uint16_t *buffer = &bufferReturn;
|
||||
uint8_t encoded = 0;
|
||||
*(buffer + encoded) = 0x00 | (fgsregistrationresult->smsallowed & 0x8) |
|
||||
(fgsregistrationresult->registrationresult & 0x7);
|
||||
encoded= encoded+2;
|
||||
|
||||
return bufferReturn;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file FGSRegistrationResult.h
|
||||
|
||||
\brief 5GS Registration result for registration request procedures
|
||||
\author Yoshio INOUE, Masayuki HARADA
|
||||
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
\date 2020
|
||||
\version 0.1
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "OctetString.h"
|
||||
|
||||
|
||||
|
||||
#ifndef FGS_REGISTRATION_RESULT_H_
|
||||
#define FGS_REGISTRATION_RESULT_H_
|
||||
#define FGS_REGISTRATION_RESULT_3GPP 0b001
|
||||
#define FGS_REGISTRATION_RESULT_NON_3GPP 0b010
|
||||
#define FGS_REGISTRATION_RESULT_3GPP_AND_NON_3GPP 0b011
|
||||
|
||||
typedef struct {
|
||||
uint8_t iei;
|
||||
uint8_t resultlength;
|
||||
uint8_t spare:4;
|
||||
uint8_t smsallowed:1;
|
||||
uint8_t registrationresult:3;
|
||||
} FGSRegistrationResult;
|
||||
|
||||
|
||||
uint16_t encode_fgs_registration_result(FGSRegistrationResult *fgsregistrationresult);
|
||||
|
||||
int decode_fgs_registration_result(FGSRegistrationResult *fgsregistrationresult, uint8_t iei, uint16_t value, uint32_t len);
|
||||
|
||||
#endif /* FGS REGISTRATION RESULT_H_*/
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "TLVEncoder.h"
|
||||
#include "TLVDecoder.h"
|
||||
#include "SORTransparentContainer.h"
|
||||
#include "nas_log.h"
|
||||
|
||||
//#define NAS_DEBUG 1
|
||||
|
||||
int decode_sor_transparent_container(SORTransparentContainer *sortransparentcontainer, uint8_t iei, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
int decoded = 0;
|
||||
int decode_result;
|
||||
uint16_t ielen;
|
||||
|
||||
LOG_FUNC_IN;
|
||||
|
||||
if (iei > 0) {
|
||||
CHECK_IEI_DECODER(iei, *buffer);
|
||||
decoded++;
|
||||
}
|
||||
|
||||
DECODE_LENGTH_U16(buffer + decoded, ielen, decoded);
|
||||
|
||||
CHECK_LENGTH_DECODER(len - decoded, ielen);
|
||||
|
||||
|
||||
if ((decode_result = decode_octet_string(&sortransparentcontainer->sortransparentcontainercontents, ielen, buffer + decoded, len - decoded)) < 0) {
|
||||
LOG_FUNC_RETURN(decode_result);
|
||||
} else {
|
||||
decoded += decode_result;
|
||||
}
|
||||
|
||||
#if defined (NAS_DEBUG)
|
||||
dump_sor_transparent_container_xml(sortransparentcontainer, iei);
|
||||
#endif
|
||||
LOG_FUNC_RETURN(decoded);
|
||||
}
|
||||
|
||||
int encode_sor_transparent_container(SORTransparentContainer *sortransparentcontainer, uint8_t iei, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
uint8_t *lenPtr;
|
||||
uint32_t encoded = 0;
|
||||
int32_t encode_result;
|
||||
/* Checking IEI and pointer */
|
||||
CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, SOR_TRANSPARENT_CONTAINER_MINIMUM_LENGTH, len);
|
||||
#if defined (NAS_DEBUG)
|
||||
dump_sor_transparent_container_xml(sortransparentcontainer, iei);
|
||||
#endif
|
||||
|
||||
if (iei > 0) {
|
||||
*buffer = iei;
|
||||
encoded++;
|
||||
}
|
||||
|
||||
lenPtr = (buffer + encoded);
|
||||
|
||||
//encoded += 2;
|
||||
//if ((encode_result = encode_octet_string(&sortransparentcontainer->sortransparentcontainercontents, buffer + sizeof(uint16_t), len - sizeof(uint16_t))) < 0)
|
||||
if ((encode_result = encode_octet_string(&sortransparentcontainer->sortransparentcontainercontents, lenPtr + sizeof(uint16_t), len - sizeof(uint16_t))) < 0)
|
||||
return encode_result;
|
||||
else
|
||||
encoded += encode_result;
|
||||
|
||||
ENCODE_U16(lenPtr, encode_result, encoded);
|
||||
return encoded;
|
||||
}
|
||||
|
||||
void dump_sor_transparent_container_xml(SORTransparentContainer *sortransparentcontainer, uint8_t iei)
|
||||
{
|
||||
printf("<SOR Transparent Container>\n");
|
||||
|
||||
if (iei > 0)
|
||||
/* Don't display IEI if = 0 */
|
||||
printf(" <IEI>0x%X</IEI>\n", iei);
|
||||
|
||||
printf("%s", dump_octet_string_xml(&sortransparentcontainer->sortransparentcontainercontents));
|
||||
printf("</SOR Transparent Container>\n");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "OctetString.h"
|
||||
|
||||
#ifndef SOR_TRANSPARENT_CONTAINER_H_
|
||||
#define SOR_TRANSPARENT_CONTAINER_H_
|
||||
|
||||
#define SOR_TRANSPARENT_CONTAINER_MINIMUM_LENGTH 2 // [length]+[length]
|
||||
#define SOR_TRANSPARENT_CONTAINER_MAXIMUM_LENGTH 65538 // [IEI]+[length]+[length]+[ESM msg]
|
||||
|
||||
typedef struct SORTransparentContainer_tag {
|
||||
OctetString sortransparentcontainercontents;
|
||||
} SORTransparentContainer;
|
||||
|
||||
int encode_sor_transparent_container(SORTransparentContainer *sortransparentcontainer, uint8_t iei, uint8_t *buffer, uint32_t len);
|
||||
|
||||
int decode_sor_transparent_container(SORTransparentContainer *sortransparentcontainer, uint8_t iei, uint8_t *buffer, uint32_t len);
|
||||
|
||||
void dump_sor_transparent_container_xml(SORTransparentContainer *sortransparentcontainer, uint8_t iei);
|
||||
|
||||
#endif /* ESM MESSAGE CONTAINER_H_ */
|
||||
|
||||
@@ -35,7 +35,41 @@
|
||||
#include "TLVDecoder.h"
|
||||
#include "TLVEncoder.h"
|
||||
#include "nr_nas_msg_sim.h"
|
||||
#include "aka_functions.h"
|
||||
#include "secu_defs.h"
|
||||
#include "PduSessionEstablishRequest.h"
|
||||
char netName[] = "5G:mnc093.mcc208.3gppnetwork.org";
|
||||
char imsi[] = "2089300007487";
|
||||
// USIM_API_K: 5122250214c33e723a5dd523fc145fc0
|
||||
uint8_t k[16] = {0x51, 0x22, 0x25, 0x02, 0x14,0xc3, 0x3e, 0x72, 0x3a, 0x5d, 0xd5, 0x23, 0xfc, 0x14, 0x5f, 0xc0};
|
||||
// OPC: 981d464c7c52eb6e5036234984ad0bcf
|
||||
const uint8_t opc[16] = {0x98, 0x1d, 0x46, 0x4c,0x7c,0x52,0xeb, 0x6e, 0x50, 0x36, 0x23, 0x49, 0x84, 0xad, 0x0b, 0xcf};
|
||||
|
||||
uint8_t *registration_request_buf;
|
||||
uint32_t registration_request_len;
|
||||
|
||||
static int nas_protected_security_header_encode(
|
||||
char *buffer,
|
||||
const fgs_nas_message_security_header_t *header,
|
||||
int length)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
int size = 0;
|
||||
|
||||
/* Encode the protocol discriminator) */
|
||||
ENCODE_U8(buffer, header->protocol_discriminator, size);
|
||||
|
||||
/* Encode the security header type */
|
||||
ENCODE_U8(buffer+size, (header->security_header_type & 0xf), size);
|
||||
|
||||
/* Encode the message authentication code */
|
||||
ENCODE_U32(buffer+size, header->message_authentication_code, size);
|
||||
/* Encode the sequence number */
|
||||
ENCODE_U8(buffer+size, header->sequence_number, size);
|
||||
|
||||
LOG_FUNC_RETURN (size);
|
||||
}
|
||||
|
||||
static int _nas_mm_msg_encode_header(const mm_msg_header_t *header,
|
||||
uint8_t *buffer, uint32_t len) {
|
||||
@@ -86,7 +120,18 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) {
|
||||
case REGISTRATION_REQUEST:
|
||||
encode_result = encode_registration_request(&mm_msg->registration_request, buffer, len);
|
||||
break;
|
||||
|
||||
case FGS_IDENTITY_RESPONSE:
|
||||
encode_result = encode_identiy_response(&mm_msg->fgs_identity_response, buffer, len);
|
||||
break;
|
||||
case FGS_AUTHENTICATION_RESPONSE:
|
||||
encode_result = encode_fgs_authentication_response(&mm_msg->fgs_auth_response, buffer, len);
|
||||
break;
|
||||
case FGS_SECURITY_MODE_COMPLETE:
|
||||
encode_result = encode_fgs_security_mode_complete(&mm_msg->fgs_security_mode_complete, buffer, len);
|
||||
break;
|
||||
case FGS_UPLINK_NAS_TRANSPORT:
|
||||
encode_result = encode_fgs_uplink_nas_transport(&mm_msg->uplink_nas_transport, buffer, len);
|
||||
break;
|
||||
default:
|
||||
LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x",
|
||||
mm_msg->header.message_type);
|
||||
@@ -106,7 +151,104 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) {
|
||||
LOG_FUNC_RETURN (header_result + encode_result);
|
||||
}
|
||||
|
||||
void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], uint8_t *output) {
|
||||
uint8_t S[100];
|
||||
S[0] = 0x6B;
|
||||
int netNamesize = strlen(netName);
|
||||
memcpy(&S[1], netName, netNamesize);
|
||||
S[1 + netNamesize] = (netNamesize & 0xff00) >> 8;
|
||||
S[2 + netNamesize] = (netNamesize & 0x00ff);
|
||||
for (int i = 0; i < 16; i++)
|
||||
S[3 + netNamesize + i] = rand[i];
|
||||
S[19 + netNamesize] = 0x00;
|
||||
S[20 + netNamesize] = 0x10;
|
||||
for (int i = 0; i < 8; i++)
|
||||
S[21 + netNamesize + i] = input[i];
|
||||
S[29 + netNamesize] = 0x00;
|
||||
S[30 + netNamesize] = 0x08;
|
||||
|
||||
uint8_t plmn[3] = { 0x02, 0xf8, 0x39 };
|
||||
uint8_t oldS[100];
|
||||
oldS[0] = 0x6B;
|
||||
memcpy(&oldS[1], plmn, 3);
|
||||
oldS[4] = 0x00;
|
||||
oldS[5] = 0x03;
|
||||
for (int i = 0; i < 16; i++)
|
||||
oldS[6 + i] = rand[i];
|
||||
oldS[22] = 0x00;
|
||||
oldS[23] = 0x10;
|
||||
for (int i = 0; i < 8; i++)
|
||||
oldS[24 + i] = input[i];
|
||||
oldS[32] = 0x00;
|
||||
oldS[33] = 0x08;
|
||||
|
||||
|
||||
uint8_t key[32];
|
||||
memcpy(&key[0], ck, 16);
|
||||
memcpy(&key[16], ik, 16); //KEY
|
||||
uint8_t out[32];
|
||||
kdf(key, 32, S, 31 + netNamesize, out, 32);
|
||||
for (int i = 0; i < 16; i++)
|
||||
output[i] = out[16 + i];
|
||||
}
|
||||
|
||||
void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32]) {
|
||||
uint8_t S[100];
|
||||
uint8_t key[32];
|
||||
int netNamesize = strlen(netName);
|
||||
memcpy(&key[0], ck, 16);
|
||||
memcpy(&key[16], ik, 16); //KEY
|
||||
S[0] = 0x6A;
|
||||
memcpy(&S[1], netName, netNamesize);
|
||||
S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
|
||||
S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
S[3 + netNamesize + i] = sqn[i];
|
||||
}
|
||||
S[9 + netNamesize] = 0x00;
|
||||
S[10 + netNamesize] = 0x06;
|
||||
kdf(key, 32, S, 11 + netNamesize, kausf, 32);
|
||||
}
|
||||
|
||||
void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32]) {
|
||||
uint8_t S[100];
|
||||
int netNamesize = strlen(netName);
|
||||
S[0] = 0x6C; //FC
|
||||
memcpy(&S[1], netName, netNamesize);
|
||||
S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
|
||||
S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
|
||||
kdf(kausf, 32, S, 3 + netNamesize, kseaf, 32);
|
||||
}
|
||||
|
||||
void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba) {
|
||||
int imsiLen = strlen(imsi);
|
||||
uint8_t S[100];
|
||||
S[0] = 0x6D; //FC = 0x6D
|
||||
memcpy(&S[1], imsi, imsiLen);
|
||||
S[1 + imsiLen] = (uint8_t)((imsiLen & 0xff00) >> 8);
|
||||
S[2 + imsiLen] = (uint8_t)(imsiLen & 0x00ff);
|
||||
S[3 + imsiLen] = abba & 0x00ff;
|
||||
S[4 + imsiLen] = (abba & 0xff00) >> 8;
|
||||
S[5 + imsiLen] = 0x00;
|
||||
S[6 + imsiLen] = 0x02;
|
||||
kdf(kseaf, 32, S, 7 + imsiLen, kamf, 32);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t kamf[32], uint8_t *knas_int) {
|
||||
uint8_t S[20];
|
||||
uint8_t out[32] = { 0 };
|
||||
S[0] = 0x69; //FC
|
||||
S[1] = (uint8_t)(nas_alg_type & 0xFF);
|
||||
S[2] = 0x00;
|
||||
S[3] = 0x01;
|
||||
S[4] = nas_alg_id;
|
||||
S[5] = 0x00;
|
||||
S[6] = 0x01;
|
||||
kdf(kamf, 32, S, 7, out, 32);
|
||||
for (int i = 0; i < 16; i++)
|
||||
knas_int[i] = out[16 + i];
|
||||
}
|
||||
|
||||
void generateRegistrationRequest(as_nas_info_t *initialNasMsg) {
|
||||
int size = sizeof(mm_msg_header_t);
|
||||
@@ -129,20 +271,35 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg) {
|
||||
mm_msg->registration_request.messagetype = REGISTRATION_REQUEST;
|
||||
size += 1;
|
||||
mm_msg->registration_request.fgsregistrationtype = INITIAL_REGISTRATION;
|
||||
mm_msg->registration_request.naskeysetidentifier.naskeysetidentifier = NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE;
|
||||
mm_msg->registration_request.naskeysetidentifier.naskeysetidentifier = 1;
|
||||
size += 1;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.typeofidentity = FGS_MOBILE_IDENTITY_5G_GUTI;
|
||||
// mm_msg->registration_request.fgsmobileidentity.guti.amfregionid = 1;
|
||||
// mm_msg->registration_request.fgsmobileidentity.guti.amfpointer = 1;
|
||||
// mm_msg->registration_request.fgsmobileidentity.guti.amfsetid = 1;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.tmsi = 10;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.mncdigit1 = 9;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.mncdigit2 = 3;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.mccdigit1 = 2;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.mccdigit2 = 0;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.mccdigit3 = 8;
|
||||
if(1){
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.typeofidentity = FGS_MOBILE_IDENTITY_5G_GUTI;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.amfregionid = 0xca;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.amfpointer = 0;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.amfsetid = 1016;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.tmsi = 10;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.mncdigit1 = 9;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.mncdigit2 = 3;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.mncdigit3 = 0xf;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.mccdigit1 = 2;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.mccdigit2 = 0;
|
||||
mm_msg->registration_request.fgsmobileidentity.guti.mccdigit3 = 8;
|
||||
|
||||
size += 13;
|
||||
size += 13;
|
||||
|
||||
} else {
|
||||
mm_msg->registration_request.fgsmobileidentity.suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI;
|
||||
mm_msg->registration_request.fgsmobileidentity.suci.mncdigit1 = 9;
|
||||
mm_msg->registration_request.fgsmobileidentity.suci.mncdigit2 = 3;
|
||||
mm_msg->registration_request.fgsmobileidentity.suci.mncdigit3 = 0xf;
|
||||
mm_msg->registration_request.fgsmobileidentity.suci.mccdigit1 = 2;
|
||||
mm_msg->registration_request.fgsmobileidentity.suci.mccdigit2 = 0;
|
||||
mm_msg->registration_request.fgsmobileidentity.suci.mccdigit3 = 8;
|
||||
mm_msg->registration_request.fgsmobileidentity.suci.schemeoutput = 0x4778;
|
||||
|
||||
size += 14;
|
||||
}
|
||||
|
||||
mm_msg->registration_request.presencemask |= REGISTRATION_REQUEST_5GMM_CAPABILITY_PRESENT;
|
||||
mm_msg->registration_request.fgmmcapability.iei = REGISTRATION_REQUEST_5GMM_CAPABILITY_IEI;
|
||||
@@ -159,10 +316,377 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg) {
|
||||
mm_msg->registration_request.nruesecuritycapability.EIA = 0;
|
||||
size += 10;
|
||||
|
||||
// encode the message
|
||||
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
|
||||
registration_request_buf = initialNasMsg->data;
|
||||
|
||||
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
|
||||
registration_request_len = initialNasMsg->length;
|
||||
|
||||
}
|
||||
|
||||
void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype) {
|
||||
int size = sizeof(mm_msg_header_t);
|
||||
fgs_nas_message_t nas_msg;
|
||||
memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
|
||||
MM_msg *mm_msg;
|
||||
|
||||
mm_msg = &nas_msg.plain.mm_msg;
|
||||
// set header
|
||||
mm_msg->header.ex_protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
|
||||
mm_msg->header.security_header_type = PLAIN_5GS_MSG;
|
||||
mm_msg->header.message_type = FGS_IDENTITY_RESPONSE;
|
||||
|
||||
|
||||
// set identity response
|
||||
mm_msg->fgs_identity_response.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
|
||||
size += 1;
|
||||
mm_msg->fgs_identity_response.securityheadertype = PLAIN_5GS_MSG;
|
||||
size += 1;
|
||||
mm_msg->fgs_identity_response.messagetype = FGS_IDENTITY_RESPONSE;
|
||||
size += 1;
|
||||
if(identitytype == FGS_MOBILE_IDENTITY_SUCI){
|
||||
mm_msg->fgs_identity_response.fgsmobileidentity.suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI;
|
||||
mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit1 = 9;
|
||||
mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit2 = 3;
|
||||
mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit3 = 0xf;
|
||||
mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit1 = 2;
|
||||
mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit2 = 0;
|
||||
mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit3 = 8;
|
||||
mm_msg->fgs_identity_response.fgsmobileidentity.suci.schemeoutput = 0x4778;
|
||||
|
||||
size += 14;
|
||||
}
|
||||
|
||||
// encode the message
|
||||
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
|
||||
|
||||
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
|
||||
|
||||
}
|
||||
|
||||
OctetString knas_int;
|
||||
void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){
|
||||
|
||||
uint8_t ak[6];
|
||||
|
||||
uint8_t kausf[32];
|
||||
uint8_t sqn[6];
|
||||
uint8_t kseaf[32];
|
||||
uint8_t kamf[32];
|
||||
OctetString res;
|
||||
|
||||
// get RAND for authentication request
|
||||
unsigned char rand[16];
|
||||
for(int index = 0; index < 16;index++){
|
||||
rand[index] = buf[8+index];
|
||||
}
|
||||
|
||||
uint8_t resTemp[16];
|
||||
uint8_t ck[16], ik[16], output[16];
|
||||
f2345(k, rand, resTemp, ck, ik, ak, opc);
|
||||
|
||||
transferRES(ck, ik, resTemp, rand, output);
|
||||
|
||||
// get knas_int
|
||||
knas_int.length = 16;
|
||||
knas_int.value = malloc(knas_int.length);
|
||||
for(int index = 0; index < 6; index++){
|
||||
sqn[index] = buf[26+index];
|
||||
}
|
||||
|
||||
derive_kausf(ck, ik, sqn, kausf);
|
||||
derive_kseaf(kausf, kseaf);
|
||||
derive_kamf(kseaf, kamf, 0x0000);
|
||||
derive_knas(0x02, 2, kamf, knas_int.value);
|
||||
|
||||
printf("kausf:");
|
||||
for(int i = 0; i < 32; i++){
|
||||
printf("%x ", kausf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("kseaf:");
|
||||
for(int i = 0; i < 32; i++){
|
||||
printf("%x ", kseaf[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("kamf:");
|
||||
for(int i = 0; i < 32; i++){
|
||||
printf("%x ", kamf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("knas_int:\n");
|
||||
for(int i = 0; i < 16; i++){
|
||||
printf("%x ", knas_int.value[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// set res
|
||||
res.length = 16;
|
||||
res.value = output;
|
||||
|
||||
int size = sizeof(mm_msg_header_t);
|
||||
fgs_nas_message_t nas_msg;
|
||||
memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
|
||||
MM_msg *mm_msg;
|
||||
|
||||
mm_msg = &nas_msg.plain.mm_msg;
|
||||
// set header
|
||||
mm_msg->header.ex_protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
|
||||
mm_msg->header.security_header_type = PLAIN_5GS_MSG;
|
||||
mm_msg->header.message_type = FGS_AUTHENTICATION_RESPONSE;
|
||||
|
||||
// set authentication response
|
||||
mm_msg->fgs_identity_response.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
|
||||
size += 1;
|
||||
mm_msg->fgs_identity_response.securityheadertype = PLAIN_5GS_MSG;
|
||||
size += 1;
|
||||
mm_msg->fgs_identity_response.messagetype = FGS_AUTHENTICATION_RESPONSE;
|
||||
size += 1;
|
||||
|
||||
//set response parameter
|
||||
mm_msg->fgs_auth_response.authenticationresponseparameter.res = res;
|
||||
size += 18;
|
||||
// encode the message
|
||||
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
|
||||
|
||||
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
|
||||
}
|
||||
|
||||
void generateSecurityModeComplete(as_nas_info_t *initialNasMsg)
|
||||
{
|
||||
int size = sizeof(mm_msg_header_t);
|
||||
fgs_nas_message_t nas_msg;
|
||||
memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
|
||||
|
||||
MM_msg *mm_msg;
|
||||
nas_stream_cipher_t stream_cipher;
|
||||
uint8_t mac[4];
|
||||
// set security protected header
|
||||
nas_msg.header.protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
|
||||
nas_msg.header.security_header_type = INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX;
|
||||
size += 7;
|
||||
|
||||
mm_msg = &nas_msg.security_protected.plain.mm_msg;
|
||||
|
||||
// set header
|
||||
mm_msg->header.ex_protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
|
||||
mm_msg->header.security_header_type = PLAIN_5GS_MSG;
|
||||
mm_msg->header.message_type = FGS_SECURITY_MODE_COMPLETE;
|
||||
|
||||
// set security mode complete
|
||||
mm_msg->fgs_security_mode_complete.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
|
||||
size += 1;
|
||||
mm_msg->fgs_security_mode_complete.securityheadertype = PLAIN_5GS_MSG;
|
||||
size += 1;
|
||||
mm_msg->fgs_security_mode_complete.messagetype = FGS_SECURITY_MODE_COMPLETE;
|
||||
size += 1;
|
||||
|
||||
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.typeofidentity = FGS_MOBILE_IDENTITY_IMEISV;
|
||||
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digit1 = 1;
|
||||
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digitp1 = 1;
|
||||
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digitp = 1;
|
||||
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.oddeven = 0;
|
||||
size += 5;
|
||||
|
||||
mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.value = registration_request_buf;
|
||||
mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.length = registration_request_len;
|
||||
size += (registration_request_len + 2);
|
||||
|
||||
// encode the message
|
||||
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
|
||||
|
||||
int security_header_len = nas_protected_security_header_encode((char*)(initialNasMsg->data),&(nas_msg.header), size);
|
||||
|
||||
initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len);
|
||||
|
||||
stream_cipher.key = knas_int.value;
|
||||
stream_cipher.key_length = 16;
|
||||
stream_cipher.count = 0;
|
||||
stream_cipher.bearer = 1;
|
||||
stream_cipher.direction = 0;
|
||||
stream_cipher.message = (unsigned char *)(initialNasMsg->data + 6);
|
||||
/* length in bits */
|
||||
stream_cipher.blength = (initialNasMsg->length - 6) << 3;
|
||||
|
||||
// only for Type of integrity protection algorithm: 128-5G-IA2 (2)
|
||||
nas_stream_encrypt_eia2(
|
||||
&stream_cipher,
|
||||
mac);
|
||||
|
||||
printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]);
|
||||
for(int i = 0; i < 4; i++){
|
||||
initialNasMsg->data[2+i] = mac[i];
|
||||
}
|
||||
}
|
||||
|
||||
void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer) {
|
||||
//wait send RRCReconfigurationComplete and InitialContextSetupResponse
|
||||
sleep(1);
|
||||
int length = 0;
|
||||
int size = 0;
|
||||
fgs_nas_message_t nas_msg;
|
||||
nas_stream_cipher_t stream_cipher;
|
||||
uint8_t mac[4];
|
||||
memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
|
||||
fgs_nas_message_security_protected_t *sp_msg;
|
||||
|
||||
sp_msg = &nas_msg.security_protected;
|
||||
// set header
|
||||
sp_msg->header.protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
|
||||
sp_msg->header.security_header_type = INTEGRITY_PROTECTED_AND_CIPHERED;
|
||||
sp_msg->header.message_authentication_code = 0;
|
||||
sp_msg->header.sequence_number = 1;
|
||||
length = 7;
|
||||
sp_msg->plain.mm_msg.registration_complete.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
|
||||
length += 1;
|
||||
sp_msg->plain.mm_msg.registration_complete.securityheadertype = PLAIN_5GS_MSG;
|
||||
sp_msg->plain.mm_msg.registration_complete.sparehalfoctet = 0;
|
||||
length += 1;
|
||||
sp_msg->plain.mm_msg.registration_complete.messagetype = REGISTRATION_COMPLETE;
|
||||
length += 1;
|
||||
|
||||
if(sortransparentcontainer) {
|
||||
length += sortransparentcontainer->sortransparentcontainercontents.length;
|
||||
}
|
||||
|
||||
// encode the message
|
||||
initialNasMsg->data = (Byte_t *)malloc(length * sizeof(Byte_t));
|
||||
|
||||
/* Encode the first octet of the header (extended protocol discriminator) */
|
||||
ENCODE_U8(initialNasMsg->data + size, sp_msg->header.protocol_discriminator, size);
|
||||
|
||||
/* Encode the security header type */
|
||||
ENCODE_U8(initialNasMsg->data + size, sp_msg->header.security_header_type, size);
|
||||
|
||||
/* Encode the message authentication code */
|
||||
ENCODE_U32(initialNasMsg->data + size, sp_msg->header.message_authentication_code, size);
|
||||
|
||||
/* Encode the sequence number */
|
||||
ENCODE_U8(initialNasMsg->data + size, sp_msg->header.sequence_number, size);
|
||||
|
||||
|
||||
/* Encode the extended protocol discriminator */
|
||||
ENCODE_U8(initialNasMsg->data + size, sp_msg->plain.mm_msg.registration_complete.protocoldiscriminator, size);
|
||||
|
||||
/* Encode the security header type */
|
||||
ENCODE_U8(initialNasMsg->data + size, sp_msg->plain.mm_msg.registration_complete.securityheadertype, size);
|
||||
|
||||
/* Encode the message type */
|
||||
ENCODE_U8(initialNasMsg->data + size, sp_msg->plain.mm_msg.registration_complete.messagetype, size);
|
||||
|
||||
if(sortransparentcontainer) {
|
||||
encode_registration_complete(&sp_msg->plain.mm_msg.registration_complete, initialNasMsg->data + size, length - size);
|
||||
}
|
||||
|
||||
initialNasMsg->length = length;
|
||||
stream_cipher.key = knas_int.value;
|
||||
stream_cipher.key_length = 16;
|
||||
stream_cipher.count = 1;
|
||||
stream_cipher.bearer = 1;
|
||||
stream_cipher.direction = 0;
|
||||
stream_cipher.message = (unsigned char *)(initialNasMsg->data + 6);
|
||||
/* length in bits */
|
||||
stream_cipher.blength = (initialNasMsg->length - 6) << 3;
|
||||
|
||||
// only for Type of integrity protection algorithm: 128-5G-IA2 (2)
|
||||
nas_stream_encrypt_eia2(
|
||||
&stream_cipher,
|
||||
mac);
|
||||
|
||||
printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]);
|
||||
for(int i = 0; i < 4; i++){
|
||||
initialNasMsg->data[2+i] = mac[i];
|
||||
}
|
||||
}
|
||||
|
||||
void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){
|
||||
//wait send RegistrationComplete
|
||||
usleep(100*150);
|
||||
int size = 0;
|
||||
fgs_nas_message_t nas_msg;
|
||||
memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
|
||||
|
||||
// setup pdu session establishment request
|
||||
uint16_t req_length = 6;
|
||||
uint8_t *req_buffer = malloc(req_length);
|
||||
pdu_session_establishment_request_msg pdu_session_establish;
|
||||
pdu_session_establish.protocoldiscriminator = FGS_SESSION_MANAGEMENT_MESSAGE;
|
||||
pdu_session_establish.pdusessionid = 10;
|
||||
pdu_session_establish.pti = 0;
|
||||
pdu_session_establish.pdusessionestblishmsgtype = FGS_PDU_SESSION_ESTABLISHMENT_REQ;
|
||||
pdu_session_establish.maxdatarate = 0xffff;
|
||||
encode_pdu_session_establishment_request(&pdu_session_establish, req_buffer);
|
||||
|
||||
|
||||
|
||||
MM_msg *mm_msg;
|
||||
nas_stream_cipher_t stream_cipher;
|
||||
uint8_t mac[4];
|
||||
uint8_t nssai[]={1,1,2,3};
|
||||
uint8_t dnn[9]={0x8,0x69,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74};
|
||||
// set security protected header
|
||||
nas_msg.header.protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
|
||||
nas_msg.header.security_header_type = INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX;
|
||||
size += 7;
|
||||
|
||||
mm_msg = &nas_msg.security_protected.plain.mm_msg;
|
||||
|
||||
// set header
|
||||
mm_msg->header.ex_protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
|
||||
mm_msg->header.security_header_type = PLAIN_5GS_MSG;
|
||||
mm_msg->header.message_type = FGS_UPLINK_NAS_TRANSPORT;
|
||||
|
||||
// set uplink nas transport
|
||||
mm_msg->uplink_nas_transport.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
|
||||
size += 1;
|
||||
mm_msg->uplink_nas_transport.securityheadertype = PLAIN_5GS_MSG;
|
||||
size += 1;
|
||||
mm_msg->uplink_nas_transport.messagetype = FGS_UPLINK_NAS_TRANSPORT;
|
||||
size += 1;
|
||||
|
||||
mm_msg->uplink_nas_transport.payloadcontainertype.iei = 0;
|
||||
mm_msg->uplink_nas_transport.payloadcontainertype.type = 1;
|
||||
size += 1;
|
||||
mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.length = req_length;
|
||||
mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.value = req_buffer;
|
||||
size += (2+req_length);
|
||||
mm_msg->uplink_nas_transport.pdusessionid = 10;
|
||||
mm_msg->uplink_nas_transport.requesttype = 1;
|
||||
size += 3;
|
||||
mm_msg->uplink_nas_transport.snssai.length = 4;
|
||||
mm_msg->uplink_nas_transport.snssai.value = nssai;
|
||||
size += (1+1+4);
|
||||
mm_msg->uplink_nas_transport.dnn.length = 9;
|
||||
mm_msg->uplink_nas_transport.dnn.value = dnn;
|
||||
size += (1+1+9);
|
||||
|
||||
// encode the message
|
||||
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
|
||||
int security_header_len = nas_protected_security_header_encode((char*)(initialNasMsg->data),&(nas_msg.header), size);
|
||||
|
||||
initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len);
|
||||
|
||||
stream_cipher.key = knas_int.value;
|
||||
stream_cipher.key_length = 16;
|
||||
stream_cipher.count = 0;
|
||||
stream_cipher.bearer = 1;
|
||||
stream_cipher.direction = 0;
|
||||
stream_cipher.message = (unsigned char *)(initialNasMsg->data + 6);
|
||||
/* length in bits */
|
||||
stream_cipher.blength = (initialNasMsg->length - 6) << 3;
|
||||
|
||||
// only for Type of integrity protection algorithm: 128-5G-IA2 (2)
|
||||
nas_stream_encrypt_eia2(
|
||||
&stream_cipher,
|
||||
mac);
|
||||
|
||||
printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]);
|
||||
for(int i = 0; i < 4; i++){
|
||||
initialNasMsg->data[2+i] = mac[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +33,33 @@
|
||||
#define __NR_NAS_MSG_SIM_H__
|
||||
|
||||
#include "RegistrationRequest.h"
|
||||
#include "FGSIdentityResponse.h"
|
||||
#include "FGSAuthenticationResponse.h"
|
||||
#include "FGSNASSecurityModeComplete.h"
|
||||
#include "RegistrationComplete.h"
|
||||
#include "as_message.h"
|
||||
|
||||
#include "FGSUplinkNasTransport.h"
|
||||
|
||||
#define PLAIN_5GS_MSG 0b0000
|
||||
#define INTEGRITY_PROTECTED 0b0001
|
||||
#define INTEGRITY_PROTECTED_AND_CIPHERED 0b0010
|
||||
#define INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX 0b0011 // only for SECURITY MODE COMMAND
|
||||
#define INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX 0b0100 // only for SECURITY MODE COMPLETE
|
||||
|
||||
#define REGISTRATION_REQUEST 0b01000001 /* 65 = 0x41 */
|
||||
#define REGISTRATION_ACCEPT 0b01000010 /* 66 = 0x42 */
|
||||
#define REGISTRATION_COMPLETE 0b01000011 /* 67 = 0x43 */
|
||||
#define FGS_AUTHENTICATION_REQUEST 0b01010110 /* 86 = 0x56 */
|
||||
#define FGS_AUTHENTICATION_RESPONSE 0b01010111 /* 87 = 0x57 */
|
||||
#define FGS_IDENTITY_REQUEST 0b01011011 /* 91 = 0x5b */
|
||||
#define FGS_IDENTITY_RESPONSE 0b01011100 /* 92 = 0x5c */
|
||||
#define FGS_SECURITY_MODE_COMMAND 0b01011101 /* 93 = 0x5d */
|
||||
#define FGS_SECURITY_MODE_COMPLETE 0b01011110 /* 94 = 0x5e */
|
||||
#define FGS_UPLINK_NAS_TRANSPORT 0b01100111 /* 103= 0x67 */
|
||||
|
||||
// message type for 5GS session management
|
||||
#define FGS_PDU_SESSION_ESTABLISHMENT_REQ 0b11000001 /* 193= 0xc1 */
|
||||
|
||||
#define INITIAL_REGISTRATION 0b001
|
||||
|
||||
|
||||
@@ -69,6 +89,11 @@ typedef struct {
|
||||
typedef union {
|
||||
mm_msg_header_t header;
|
||||
registration_request_msg registration_request;
|
||||
fgs_identiy_response_msg fgs_identity_response;
|
||||
fgs_authentication_response_msg fgs_auth_response;
|
||||
fgs_security_mode_complete_msg fgs_security_mode_complete;
|
||||
registration_complete_msg registration_complete;
|
||||
fgs_uplink_nas_transport_msg uplink_nas_transport;
|
||||
} MM_msg;
|
||||
|
||||
|
||||
@@ -90,5 +115,13 @@ typedef union {
|
||||
} fgs_nas_message_t;
|
||||
|
||||
void generateRegistrationRequest(as_nas_info_t *initialNasMsg);
|
||||
void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype);
|
||||
void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf);
|
||||
void generateSecurityModeComplete(as_nas_info_t *initialNasMsg);
|
||||
void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer);
|
||||
void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg);
|
||||
|
||||
#endif /* __NR_NAS_MSG_SIM_H__*/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -61,6 +61,9 @@
|
||||
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#if defined(TEST_S1C_AMF)
|
||||
#include "oaisim_amf_test_s1c.h"
|
||||
#endif
|
||||
|
||||
ngap_gNB_config_t ngap_config;
|
||||
|
||||
@@ -95,6 +98,7 @@ static void ngap_gNB_register_amf(ngap_gNB_instance_t *instance_p,
|
||||
MessageDef *message_p = NULL;
|
||||
sctp_new_association_req_t *sctp_new_association_req_p = NULL;
|
||||
ngap_gNB_amf_data_t *ngap_amf_data_p = NULL;
|
||||
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(amf_ip_address != NULL);
|
||||
message_p = itti_alloc_new_message(TASK_NGAP, 0, SCTP_NEW_ASSOCIATION_REQ);
|
||||
@@ -119,8 +123,8 @@ static void ngap_gNB_register_amf(ngap_gNB_instance_t *instance_p,
|
||||
ngap_amf_data_p->assoc_id = -1;
|
||||
ngap_amf_data_p->broadcast_plmn_num = broadcast_plmn_num;
|
||||
memcpy(&ngap_amf_data_p->amf_s1_ip,
|
||||
amf_ip_address,
|
||||
sizeof(*amf_ip_address));
|
||||
amf_ip_address,
|
||||
sizeof(*amf_ip_address));
|
||||
for (int i = 0; i < broadcast_plmn_num; ++i)
|
||||
ngap_amf_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i];
|
||||
|
||||
@@ -130,14 +134,13 @@ static void ngap_gNB_register_amf(ngap_gNB_instance_t *instance_p,
|
||||
* but not yet associated.
|
||||
*/
|
||||
RB_INSERT(ngap_amf_map, &instance_p->ngap_amf_head, ngap_amf_data_p);
|
||||
ngap_amf_data_p->state = NGAP_GNB_STATE_WAITING;
|
||||
ngap_amf_data_p->state = NGAP_GNB_STATE_DISCONNECTED;
|
||||
instance_p->ngap_amf_nb ++;
|
||||
instance_p->ngap_amf_pending_nb ++;
|
||||
|
||||
itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p);
|
||||
}
|
||||
|
||||
|
||||
void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_gnb_req_t *ngap_register_gNB) {
|
||||
ngap_gNB_instance_t *new_instance;
|
||||
uint8_t index;
|
||||
@@ -255,10 +258,13 @@ static
|
||||
void ngap_gNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) {
|
||||
int result;
|
||||
DevAssert(sctp_data_ind != NULL);
|
||||
|
||||
#if defined(TEST_S1C_AMF)
|
||||
amf_test_s1_notify_sctp_data_ind(sctp_data_ind->assoc_id, sctp_data_ind->stream,
|
||||
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
|
||||
#else
|
||||
ngap_gNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream,
|
||||
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
|
||||
|
||||
#endif
|
||||
result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "ngap_gNB_nas_procedures.h"
|
||||
#include "ngap_gNB_management_procedures.h"
|
||||
#include "ngap_gNB_context_management_procedures.h"
|
||||
#include "NGAP_PDUSessionResourceItemCxtRelReq.h"
|
||||
#include "msc.h"
|
||||
|
||||
|
||||
@@ -203,6 +204,21 @@ int ngap_ue_context_release_req(instance_t instance,
|
||||
ie->value.choice.RAN_UE_NGAP_ID = ue_release_req_p->gNB_ue_ngap_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
/* optional */
|
||||
if (ue_release_req_p->nb_of_pdusessions > 0) {
|
||||
ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceListCxtRelReq;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_PDUSessionResourceListCxtRelReq;
|
||||
for (int i = 0; i < ue_release_req_p->nb_of_pdusessions; i++) {
|
||||
NGAP_PDUSessionResourceItemCxtRelReq_t *item;
|
||||
item = (NGAP_PDUSessionResourceItemCxtRelReq_t *)calloc(1,sizeof(NGAP_PDUSessionResourceItemCxtRelReq_t));
|
||||
item->pDUSessionID = ue_release_req_p->pdusessions[i].pdusession_id;
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceListCxtRelReq.list, item);
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_Cause;
|
||||
|
||||
@@ -73,7 +73,7 @@ int ngap_gNB_encode_pdu(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
//ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#include "msc.h"
|
||||
#include "NGAP_NonDynamic5QIDescriptor.h"
|
||||
|
||||
static
|
||||
int ngap_gNB_handle_ng_setup_response(uint32_t assoc_id,
|
||||
@@ -882,11 +883,11 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id,
|
||||
}
|
||||
|
||||
/* Initial context request = UE-related procedure -> stream != 0 */
|
||||
if (stream == 0) {
|
||||
NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
|
||||
assoc_id, stream);
|
||||
return -1;
|
||||
}
|
||||
//if (stream == 0) {
|
||||
// NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
|
||||
// assoc_id, stream);
|
||||
// return -1;
|
||||
//}
|
||||
|
||||
ue_desc_p->rx_stream = stream;
|
||||
ue_desc_p->amf_ue_ngap_id = amf_ue_ngap_id;
|
||||
@@ -955,7 +956,7 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id,
|
||||
}
|
||||
|
||||
|
||||
dec_rval = uper_decode(NULL,
|
||||
dec_rval = aper_decode(NULL,
|
||||
&asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer,
|
||||
(void **)&pdusessionTransfer_p,
|
||||
item_p->pDUSessionResourceSetupRequestTransfer.buf,
|
||||
@@ -1028,7 +1029,7 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id,
|
||||
qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.array[qosIdx];
|
||||
|
||||
/* Set the QOS informations */
|
||||
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].qci = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
|
||||
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
|
||||
|
||||
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].allocation_retention_priority.priority_level =
|
||||
qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.priorityLevelARP;
|
||||
@@ -1289,11 +1290,11 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id,
|
||||
}
|
||||
|
||||
/* Initial context request = UE-related procedure -> stream != 0 */
|
||||
if (stream == 0) {
|
||||
NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
|
||||
assoc_id, stream);
|
||||
return -1;
|
||||
}
|
||||
// if (stream == 0) {
|
||||
// NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
|
||||
// assoc_id, stream);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
ue_desc_p->rx_stream = stream;
|
||||
|
||||
@@ -1338,7 +1339,7 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id,
|
||||
NGAP_WARN("NAS PDU is not provided, generate a PDUSESSION_SETUP Failure (TBD) back to AMF \n");
|
||||
}
|
||||
|
||||
dec_rval = uper_decode(NULL,
|
||||
dec_rval = aper_decode(NULL,
|
||||
&asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer,
|
||||
(void **)&pdusessionTransfer_p,
|
||||
item_p->pDUSessionResourceSetupRequestTransfer.buf,
|
||||
@@ -1407,8 +1408,13 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id,
|
||||
qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.array[qosIdx];
|
||||
|
||||
/* Set the QOS informations */
|
||||
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].qci = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
|
||||
|
||||
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
|
||||
if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI){
|
||||
if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI != NULL){
|
||||
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].fiveQI =
|
||||
(uint64_t)qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI->fiveQI;
|
||||
}
|
||||
}
|
||||
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.priority_level =
|
||||
qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.priorityLevelARP;
|
||||
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability =
|
||||
@@ -1668,7 +1674,7 @@ int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id,
|
||||
continue;
|
||||
}
|
||||
|
||||
dec_rval = uper_decode(NULL,
|
||||
dec_rval = aper_decode(NULL,
|
||||
&asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer,
|
||||
(void **)&pdusessionTransfer_p,
|
||||
item_p->pDUSessionResourceModifyRequestTransfer.buf,
|
||||
@@ -1709,7 +1715,7 @@ int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id,
|
||||
qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.array[qosIdx];
|
||||
|
||||
/* Set the QOS informations */
|
||||
NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].qci = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
|
||||
NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
|
||||
if(qosFlowItem_p->qosFlowLevelQosParameters) {
|
||||
NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.priority_level =
|
||||
qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority.priorityLevelARP;
|
||||
@@ -1748,7 +1754,7 @@ int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id,
|
||||
|
||||
return 0;
|
||||
}
|
||||
// handle e-rab release command and send it to rrc_end
|
||||
// handle pdu session release command and send it to rrc_end
|
||||
static
|
||||
int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
@@ -1766,7 +1772,7 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
|
||||
container = &pdu->choice.initiatingMessage->value.choice.PDUSessionResourceReleaseCommand;
|
||||
|
||||
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
|
||||
NGAP_ERROR("[SCTP %d] Received E-RAB release command for non existing AMF context\n", assoc_id);
|
||||
NGAP_ERROR("[SCTP %d] Received pdu session release command for non existing AMF context\n", assoc_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1799,11 +1805,11 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
|
||||
}
|
||||
|
||||
/* Initial context request = UE-related procedure -> stream != 0 */
|
||||
if (stream == 0) {
|
||||
NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
|
||||
assoc_id, stream);
|
||||
return -1;
|
||||
}
|
||||
// if (stream == 0) {
|
||||
// NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
|
||||
// assoc_id, stream);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
ue_desc_p->rx_stream = stream;
|
||||
|
||||
@@ -1812,7 +1818,7 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
|
||||
(uint64_t)ue_desc_p->amf_ue_ngap_id, amf_ue_ngap_id);
|
||||
}
|
||||
|
||||
NGAP_DEBUG("[SCTP %d] Received E-RAB release command for gNB_UE_NGAP_ID %lu amf_ue_ngap_id %lu\n",
|
||||
NGAP_DEBUG("[SCTP %d] Received pdu session release command for gNB_UE_NGAP_ID %lu amf_ue_ngap_id %lu\n",
|
||||
assoc_id, gnb_ue_ngap_id, amf_ue_ngap_id);
|
||||
message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_RELEASE_COMMAND);
|
||||
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).gNB_ue_ngap_id = gnb_ue_ngap_id;
|
||||
@@ -1844,7 +1850,18 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
|
||||
item_p = (NGAP_PDUSessionResourceToReleaseItemRelCmd_t *)ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.array[i];
|
||||
|
||||
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].pdusession_id = item_p->pDUSessionID;
|
||||
NGAP_DEBUG("[SCTP] Received E-RAB release command for pDUSessionID id %ld\n", item_p->pDUSessionID);
|
||||
if(item_p->pDUSessionResourceReleaseCommandTransfer.size > 0) {
|
||||
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_length = item_p->pDUSessionResourceReleaseCommandTransfer.size;
|
||||
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer = malloc(sizeof(uint8_t) * item_p->pDUSessionResourceReleaseCommandTransfer.size);
|
||||
memcpy(NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer,
|
||||
item_p->pDUSessionResourceReleaseCommandTransfer.buf,
|
||||
item_p->pDUSessionResourceReleaseCommandTransfer.size);
|
||||
}else {
|
||||
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_length = 0;
|
||||
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer = NULL;
|
||||
NGAP_ERROR("[NGAP] Received pdu session release command for pDUSessionResourceReleaseCommandTransfer is NULL!\n");
|
||||
}
|
||||
NGAP_DEBUG("[NGAP] Received pdu session release command for pDUSessionID id %ld\n", item_p->pDUSessionID);
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
|
||||
@@ -344,11 +344,11 @@ int ngap_gNB_handle_nas_downlink(uint32_t assoc_id,
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
/* UE-related procedure -> stream != 0 */
|
||||
if (stream == 0) {
|
||||
NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream == 0\n",
|
||||
assoc_id);
|
||||
return -1;
|
||||
}
|
||||
// if (stream == 0) {
|
||||
// NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream == 0\n",
|
||||
// assoc_id);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
|
||||
NGAP_ERROR(
|
||||
@@ -469,6 +469,7 @@ int ngap_gNB_nas_uplink(instance_t instance, ngap_uplink_nas_t *ngap_uplink_nas_
|
||||
/* Prepare the NGAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage = (NGAP_InitiatingMessage_t *)calloc(1,sizeof(NGAP_InitiatingMessage_t));
|
||||
pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UplinkNASTransport;
|
||||
pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore;
|
||||
pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_UplinkNASTransport;
|
||||
@@ -503,6 +504,7 @@ int ngap_gNB_nas_uplink(instance_t instance, ngap_uplink_nas_t *ngap_uplink_nas_
|
||||
ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_UserLocationInformation;
|
||||
|
||||
ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR;
|
||||
ie->value.choice.UserLocationInformation.choice.userLocationInformationNR = CALLOC(1,sizeof(struct NGAP_UserLocationInformationNR));
|
||||
userinfo_nr_p = ie->value.choice.UserLocationInformation.choice.userLocationInformationNR;
|
||||
|
||||
/* Set nRCellIdentity. default userLocationInformationNR */
|
||||
@@ -579,6 +581,7 @@ int ngap_gNB_nas_non_delivery_ind(instance_t instance,
|
||||
/* Prepare the NGAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage = (NGAP_InitiatingMessage_t *)calloc(1,sizeof(NGAP_InitiatingMessage_t));
|
||||
pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_NASNonDeliveryIndication;
|
||||
pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore;
|
||||
pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_NASNonDeliveryIndication;
|
||||
@@ -685,6 +688,7 @@ int ngap_gNB_initial_ctxt_resp(
|
||||
/* Prepare the NGAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome;
|
||||
pdu.choice.successfulOutcome = (NGAP_SuccessfulOutcome_t *)calloc(1,sizeof(struct NGAP_SuccessfulOutcome));
|
||||
pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_InitialContextSetup;
|
||||
pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject;
|
||||
pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_InitialContextSetupResponse;
|
||||
@@ -704,73 +708,74 @@ int ngap_gNB_initial_ctxt_resp(
|
||||
ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_RAN_UE_NGAP_ID;
|
||||
ie->value.choice.RAN_UE_NGAP_ID = initial_ctxt_resp_p->gNB_ue_ngap_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
/* optional */
|
||||
ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtRes;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_PDUSessionResourceSetupListCxtRes;
|
||||
if (initial_ctxt_resp_p->nb_of_pdusessions){
|
||||
ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtRes;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_PDUSessionResourceSetupListCxtRes;
|
||||
for (i = 0; i < initial_ctxt_resp_p->nb_of_pdusessions; i++) {
|
||||
NGAP_PDUSessionResourceSetupItemCxtRes_t *item;
|
||||
NGAP_PDUSessionResourceSetupResponseTransfer_t *pdusessionTransfer_p = NULL;
|
||||
|
||||
for (i = 0; i < initial_ctxt_resp_p->nb_of_pdusessions; i++) {
|
||||
NGAP_PDUSessionResourceSetupItemCxtRes_t *item;
|
||||
NGAP_PDUSessionResourceSetupResponseTransfer_t *pdusessionTransfer_p = NULL;
|
||||
|
||||
/* mandatory */
|
||||
item = (NGAP_PDUSessionResourceSetupItemCxtRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupItemCxtRes_t));
|
||||
/* mandatory */
|
||||
item = (NGAP_PDUSessionResourceSetupItemCxtRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupItemCxtRes_t));
|
||||
|
||||
/* pDUSessionID */
|
||||
item->pDUSessionID = initial_ctxt_resp_p->pdusessions[i].pdusession_id;
|
||||
/* pDUSessionID */
|
||||
item->pDUSessionID = initial_ctxt_resp_p->pdusessions[i].pdusession_id;
|
||||
|
||||
/* dLQosFlowPerTNLInformation */
|
||||
pdusessionTransfer_p = (NGAP_PDUSessionResourceSetupResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseTransfer_t));
|
||||
/* dLQosFlowPerTNLInformation */
|
||||
pdusessionTransfer_p = (NGAP_PDUSessionResourceSetupResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseTransfer_t));
|
||||
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel;
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel;
|
||||
|
||||
GTP_TEID_TO_ASN1(initial_ctxt_resp_p->pdusessions[i].gtp_teid, &pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->gTP_TEID);
|
||||
GTP_TEID_TO_ASN1(initial_ctxt_resp_p->pdusessions[i].gtp_teid, &pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->gTP_TEID);
|
||||
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf = malloc(initial_ctxt_resp_p->pdusessions[i].gNB_addr.length);
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf = malloc(initial_ctxt_resp_p->pdusessions[i].gNB_addr.length);
|
||||
|
||||
memcpy(pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf,
|
||||
initial_ctxt_resp_p->pdusessions[i].gNB_addr.buffer,
|
||||
initial_ctxt_resp_p->pdusessions[i].gNB_addr.length);
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size = initial_ctxt_resp_p->pdusessions[i].gNB_addr.length;
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.bits_unused = 0;
|
||||
memcpy(pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf,
|
||||
initial_ctxt_resp_p->pdusessions[i].gNB_addr.buffer,
|
||||
initial_ctxt_resp_p->pdusessions[i].gNB_addr.length);
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size = initial_ctxt_resp_p->pdusessions[i].gNB_addr.length;
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.bits_unused = 0;
|
||||
|
||||
NGAP_DEBUG("initial_ctxt_resp_p: pdusession ID %ld, gnb_addr %d.%d.%d.%d, SIZE %ld \n",
|
||||
item->pDUSessionID,
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[0],
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[1],
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[2],
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[3],
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size);
|
||||
NGAP_DEBUG("initial_ctxt_resp_p: pdusession ID %ld, gnb_addr %d.%d.%d.%d, SIZE %ld \n",
|
||||
item->pDUSessionID,
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[0],
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[1],
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[2],
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[3],
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size);
|
||||
|
||||
/* associatedQosFlowList. number of 1? */
|
||||
for(int j=0; j < initial_ctxt_resp_p->pdusessions[i].nb_of_qos_flow; j++) {
|
||||
NGAP_AssociatedQosFlowItem_t *ass_qos_item_p;
|
||||
ass_qos_item_p = (NGAP_AssociatedQosFlowItem_t *)calloc(1, sizeof(NGAP_AssociatedQosFlowItem_t));
|
||||
/* associatedQosFlowList. number of 1? */
|
||||
for(int j=0; j < initial_ctxt_resp_p->pdusessions[i].nb_of_qos_flow; j++) {
|
||||
NGAP_AssociatedQosFlowItem_t *ass_qos_item_p;
|
||||
ass_qos_item_p = (NGAP_AssociatedQosFlowItem_t *)calloc(1, sizeof(NGAP_AssociatedQosFlowItem_t));
|
||||
|
||||
/* qosFlowIdentifier */
|
||||
ass_qos_item_p->qosFlowIdentifier = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qci;
|
||||
/* qosFlowIdentifier */
|
||||
ass_qos_item_p->qosFlowIdentifier = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qfi;
|
||||
|
||||
/* qosFlowMappingIndication */
|
||||
if(initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) {
|
||||
ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication));
|
||||
*ass_qos_item_p->qosFlowMappingIndication = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind;
|
||||
/* qosFlowMappingIndication */
|
||||
if(initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) {
|
||||
ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication));
|
||||
*ass_qos_item_p->qosFlowMappingIndication = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind;
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p);
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p);
|
||||
}
|
||||
|
||||
memset(&res, 0, sizeof(res));
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
|
||||
item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer;
|
||||
item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded;
|
||||
memset(&res, 0, sizeof(res));
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
|
||||
item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer;
|
||||
item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded;
|
||||
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
|
||||
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceSetupListCxtRes.list, item);
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceSetupListCxtRes.list, item);
|
||||
}
|
||||
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
}
|
||||
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
/* optional */
|
||||
if (initial_ctxt_resp_p->nb_of_pdusessions_failed) {
|
||||
ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t));
|
||||
@@ -847,21 +852,22 @@ int ngap_gNB_initial_ctxt_resp(
|
||||
return -1;
|
||||
}
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_NGAP_GNB,
|
||||
MSC_NGAP_AMF,
|
||||
(const char *)buffer,
|
||||
length,
|
||||
MSC_AS_TIME_FMT" InitialContextSetup successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %u",
|
||||
0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
|
||||
initial_ctxt_resp_p->gNB_ue_ngap_id,
|
||||
ue_context_p->amf_ue_ngap_id);
|
||||
/* UE associated signalling -> use the allocated stream */
|
||||
ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance,
|
||||
ue_context_p->amf_ref->assoc_id, buffer,
|
||||
length, ue_context_p->tx_stream);
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_NGAP_GNB,
|
||||
MSC_NGAP_AMF,
|
||||
(const char *)buffer,
|
||||
length,
|
||||
MSC_AS_TIME_FMT" InitialContextSetup successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %u",
|
||||
0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
|
||||
initial_ctxt_resp_p->gNB_ue_ngap_id,
|
||||
ue_context_p->amf_ue_ngap_id);
|
||||
/* UE associated signalling -> use the allocated stream */
|
||||
LOG_I(NR_RRC,"Send message to sctp: NGAP_InitialContextSetupResponse\n");
|
||||
ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance,
|
||||
ue_context_p->amf_ref->assoc_id, buffer,
|
||||
length, ue_context_p->tx_stream);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -903,6 +909,7 @@ int ngap_gNB_ue_capabilities(instance_t instance,
|
||||
/* Prepare the NGAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage = (NGAP_InitiatingMessage_t *)calloc(1,sizeof(NGAP_InitiatingMessage_t));
|
||||
pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UERadioCapabilityInfoIndication;
|
||||
pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore;
|
||||
pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_UERadioCapabilityInfoIndication;
|
||||
@@ -996,6 +1003,7 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance,
|
||||
/* Prepare the NGAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome;
|
||||
pdu.choice.successfulOutcome = (NGAP_SuccessfulOutcome_t *)calloc(1,sizeof(struct NGAP_SuccessfulOutcome));
|
||||
pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceSetup;
|
||||
pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject;
|
||||
pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceSetupResponse;
|
||||
@@ -1036,6 +1044,8 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance,
|
||||
pdusessionTransfer_p = (NGAP_PDUSessionResourceSetupResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseTransfer_t));
|
||||
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel;
|
||||
pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel =
|
||||
calloc(1, sizeof(struct NGAP_GTPTunnel));
|
||||
|
||||
GTP_TEID_TO_ASN1(pdusession_setup_resp_p->pdusessions[i].gtp_teid, &pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->gTP_TEID);
|
||||
|
||||
@@ -1061,20 +1071,28 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance,
|
||||
ass_qos_item_p = (NGAP_AssociatedQosFlowItem_t *)calloc(1, sizeof(NGAP_AssociatedQosFlowItem_t));
|
||||
|
||||
/* qosFlowIdentifier */
|
||||
ass_qos_item_p->qosFlowIdentifier = pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qci;
|
||||
ass_qos_item_p->qosFlowIdentifier = pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qfi;
|
||||
|
||||
/* qosFlowMappingIndication */
|
||||
if(pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) {
|
||||
ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication));
|
||||
*ass_qos_item_p->qosFlowMappingIndication = pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind;
|
||||
}
|
||||
//if(pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) {
|
||||
// ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication));
|
||||
// *ass_qos_item_p->qosFlowMappingIndication = pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind;
|
||||
//}
|
||||
ASN_SEQUENCE_ADD(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p);
|
||||
}
|
||||
|
||||
memset(&res, 0, sizeof(res));
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
|
||||
item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer;
|
||||
item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded;
|
||||
// res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
|
||||
// item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer;
|
||||
// item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded;
|
||||
uint8_t buffer[100];
|
||||
asn_enc_rval_t enc_rval = aper_encode_to_buffer(&asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer,
|
||||
NULL,
|
||||
pdusessionTransfer_p,
|
||||
buffer,100);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
|
||||
item->pDUSessionResourceSetupResponseTransfer.buf = buffer;
|
||||
item->pDUSessionResourceSetupResponseTransfer.size = enc_rval.encoded;
|
||||
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
|
||||
|
||||
@@ -1218,6 +1236,7 @@ int ngap_gNB_pdusession_modify_resp(instance_t instance,
|
||||
/* Prepare the NGAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome;
|
||||
pdu.choice.successfulOutcome = (NGAP_SuccessfulOutcome_t *)calloc(1,sizeof(struct NGAP_SuccessfulOutcome));
|
||||
pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceModify;
|
||||
pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject;
|
||||
pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceModifyResponse;
|
||||
@@ -1378,6 +1397,7 @@ int ngap_gNB_pdusession_release_resp(instance_t instance,
|
||||
/* Prepare the NGAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome;
|
||||
pdu.choice.successfulOutcome = (NGAP_SuccessfulOutcome_t *)calloc(1,sizeof(struct NGAP_SuccessfulOutcome));
|
||||
pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceRelease;
|
||||
pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject;
|
||||
pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceReleaseResponse;
|
||||
@@ -1397,21 +1417,41 @@ int ngap_gNB_pdusession_release_resp(instance_t instance,
|
||||
ie->value.choice.RAN_UE_NGAP_ID = pdusession_release_resp_p->gNB_ue_ngap_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
/* optional */
|
||||
if (pdusession_release_resp_p->nb_of_pdusessions_released > 0) {
|
||||
ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_PDUSessionResourceReleasedListRelRes;
|
||||
/* optional */
|
||||
if (pdusession_release_resp_p->nb_of_pdusessions_released > 0) {
|
||||
ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_PDUSessionResourceReleasedListRelRes;
|
||||
|
||||
for (i = 0; i < pdusession_release_resp_p->nb_of_pdusessions_released; i++) {
|
||||
NGAP_PDUSessionResourceReleasedItemRelRes_t *item;
|
||||
item = (NGAP_PDUSessionResourceReleasedItemRelRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleasedItemRelRes_t));
|
||||
|
||||
item->pDUSessionID = pdusession_release_resp_p->pdusession_release[i].pdusession_id;
|
||||
NGAP_DEBUG("pdusession_release_resp: pdusession ID %ld\n", item->pDUSessionID);
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceReleasedListRelRes.list, item);
|
||||
}
|
||||
for (i = 0; i < pdusession_release_resp_p->nb_of_pdusessions_released; i++) {
|
||||
NGAP_PDUSessionResourceReleasedItemRelRes_t *item;
|
||||
item = (NGAP_PDUSessionResourceReleasedItemRelRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleasedItemRelRes_t));
|
||||
|
||||
item->pDUSessionID = pdusession_release_resp_p->pdusession_release[i].pdusession_id;
|
||||
if(pdusession_release_resp_p->pdusession_release[i].transfer_length > 0){
|
||||
item->pDUSessionResourceReleaseResponseTransfer.size = pdusession_release_resp_p->pdusession_release[i].transfer_length;
|
||||
item->pDUSessionResourceReleaseResponseTransfer.buf = malloc(sizeof(uint8_t) * pdusession_release_resp_p->pdusession_release[i].transfer_length);
|
||||
memcpy(item->pDUSessionResourceReleaseResponseTransfer.buf,
|
||||
pdusession_release_resp_p->pdusession_release[i].transfer_buffer,
|
||||
pdusession_release_resp_p->pdusession_release[i].transfer_length);
|
||||
}else {
|
||||
item->pDUSessionResourceReleaseResponseTransfer.size = 0;
|
||||
item->pDUSessionResourceReleaseResponseTransfer.buf = NULL;
|
||||
NGAP_DEBUG("pdusession_release_resp: transfer_buffer is NULL!\n");
|
||||
#ifdef ITTI_SIM
|
||||
//For testing only
|
||||
item->pDUSessionResourceReleaseResponseTransfer.buf = malloc(sizeof(uint8_t) * 1);
|
||||
item->pDUSessionResourceReleaseResponseTransfer.size = 1;
|
||||
uint8_t temp = 0;
|
||||
memcpy(item->pDUSessionResourceReleaseResponseTransfer.buf,
|
||||
&temp,
|
||||
item->pDUSessionResourceReleaseResponseTransfer.size);
|
||||
#endif
|
||||
}
|
||||
NGAP_DEBUG("pdusession_release_resp: pdusession ID %ld\n", item->pDUSessionID);
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceReleasedListRelRes.list, item);
|
||||
}
|
||||
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
}
|
||||
|
||||
@@ -82,8 +82,8 @@ struct ngap_gNB_ue_context_s *ngap_gNB_get_ue_context(
|
||||
|
||||
memset(&temp, 0, sizeof(struct ngap_gNB_ue_context_s));
|
||||
|
||||
/* gNB ue ngap id = 24 bits wide */
|
||||
temp.gNB_ue_ngap_id = gNB_ue_ngap_id & 0x00FFFFFF;
|
||||
/* gNB ue ngap id = 32 bits wide */
|
||||
temp.gNB_ue_ngap_id = gNB_ue_ngap_id & 0xFFFFFFFF;
|
||||
|
||||
return RB_FIND(ngap_ue_map, &instance_p->ngap_ue_head, &temp);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user