Merge branch 'episys-merge' into episys/trial-merge-to-master
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
#include "udp_messages_types.h"
|
||||
#include "mme_app_messages_types.h"
|
||||
#include "m2ap_messages_types.h"
|
||||
#include "ngap_messages_types.h"
|
||||
|
||||
|
||||
#endif /* MESSAGES_TYPES_H_ */
|
||||
|
||||
@@ -135,7 +135,7 @@ static int gtpv1u_eNB_send_init_udp(const Gtpv1uS1Req *req) {
|
||||
// Create and alloc new message
|
||||
MessageDef *message_p;
|
||||
struct in_addr addr= {0};
|
||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, UDP_INIT);
|
||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, 0, UDP_INIT);
|
||||
|
||||
if (message_p == NULL) {
|
||||
return -1;
|
||||
@@ -184,7 +184,7 @@ NwGtpv1uRcT gtpv1u_eNB_send_udp_msg(
|
||||
// Create and alloc new message
|
||||
MessageDef *message_p = NULL;
|
||||
udp_data_req_t *udp_data_req_p = NULL;
|
||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, UDP_DATA_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, 0, UDP_DATA_REQ);
|
||||
|
||||
if (message_p) {
|
||||
#if defined(LOG_GTPU) && LOG_GTPU > 0
|
||||
@@ -285,7 +285,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
|
||||
//ue_context_p->ue_context.handover_info->state = HO_END_MARKER;
|
||||
MessageDef *msg;
|
||||
// Configure end marker
|
||||
msg = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_ENB_END_MARKER_REQ);
|
||||
msg = itti_alloc_new_message(TASK_GTPV1_U, 0, GTPV1U_ENB_END_MARKER_REQ);
|
||||
GTPV1U_ENB_END_MARKER_REQ(msg).buffer = itti_malloc(TASK_GTPV1_U, TASK_GTPV1_U, GTPU_HEADER_OVERHEAD_MAX + buffer_len);
|
||||
memcpy(>PV1U_ENB_END_MARKER_REQ(msg).buffer[GTPU_HEADER_OVERHEAD_MAX], buffer, buffer_len);
|
||||
GTPV1U_ENB_END_MARKER_REQ(msg).length = buffer_len;
|
||||
@@ -358,7 +358,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
|
||||
if (ue_context_p->ue_context.handover_info->state == HO_COMPLETE) {
|
||||
MessageDef *msg;
|
||||
// Configure target
|
||||
msg = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_ENB_DATA_FORWARDING_REQ);
|
||||
msg = itti_alloc_new_message(TASK_GTPV1_U, 0, GTPV1U_ENB_DATA_FORWARDING_REQ);
|
||||
GTPV1U_ENB_DATA_FORWARDING_REQ(msg).buffer = itti_malloc(TASK_GTPV1_U, TASK_GTPV1_U, GTPU_HEADER_OVERHEAD_MAX + buffer_len);
|
||||
memcpy(>PV1U_ENB_DATA_FORWARDING_REQ(msg).buffer[GTPU_HEADER_OVERHEAD_MAX], buffer, buffer_len);
|
||||
GTPV1U_ENB_DATA_FORWARDING_REQ(msg).length = buffer_len;
|
||||
@@ -943,6 +943,8 @@ gtpv1u_create_s1u_tunnel(
|
||||
memcpy(&create_tunnel_resp_pP->enb_addr.buffer,
|
||||
&RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up,
|
||||
sizeof (in_addr_t));
|
||||
|
||||
LOG_I(GTPU,"Configured GTPu address : %x\n",RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up);
|
||||
create_tunnel_resp_pP->enb_addr.length = sizeof (in_addr_t);
|
||||
addrs_length_in_bytes = create_tunnel_req_pP->sgw_addr[i].length / 8;
|
||||
AssertFatal((addrs_length_in_bytes == 4) ||
|
||||
@@ -971,6 +973,15 @@ gtpv1u_create_s1u_tunnel(
|
||||
gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_sgw = create_tunnel_req_pP->sgw_S1u_teid[i];
|
||||
gtpv1u_ue_data_p->num_bearers++;
|
||||
create_tunnel_resp_pP->enb_S1u_teid[i] = s1u_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->enb_addr.buffer[0],
|
||||
create_tunnel_resp_pP->enb_addr.buffer[1],
|
||||
create_tunnel_resp_pP->enb_addr.buffer[2],
|
||||
create_tunnel_resp_pP->enb_addr.buffer[3],
|
||||
create_tunnel_resp_pP->enb_addr.length,
|
||||
create_tunnel_resp_pP->enb_S1u_teid[i]);
|
||||
} else {
|
||||
create_tunnel_resp_pP->enb_S1u_teid[i] = 0;
|
||||
create_tunnel_resp_pP->status = 0xFF;
|
||||
@@ -1111,7 +1122,7 @@ int gtpv1u_delete_s1u_tunnel(
|
||||
hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
|
||||
teid_t teid_eNB = 0;
|
||||
int erab_index = 0;
|
||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_ENB_DELETE_TUNNEL_RESP);
|
||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, 0, GTPV1U_ENB_DELETE_TUNNEL_RESP);
|
||||
GTPV1U_ENB_DELETE_TUNNEL_RESP(message_p).rnti = req_pP->rnti;
|
||||
GTPV1U_ENB_DELETE_TUNNEL_RESP(message_p).status = 0;
|
||||
hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, req_pP->rnti, (void **)>pv1u_ue_data_p);
|
||||
@@ -1173,7 +1184,10 @@ int gtpv1u_delete_s1u_tunnel(
|
||||
"0 GTPV1U_ENB_DELETE_TUNNEL_RESP rnti %x teid %x",
|
||||
GTPV1U_ENB_DELETE_TUNNEL_RESP(message_p).rnti,
|
||||
teid_eNB);
|
||||
return itti_send_msg_to_task(TASK_RRC_ENB, instanceP, message_p);
|
||||
if (req_pP->from_gnb)
|
||||
return itti_send_msg_to_task(TASK_RRC_GNB, instanceP, message_p);
|
||||
else
|
||||
return itti_send_msg_to_task(TASK_RRC_ENB, instanceP, message_p);
|
||||
}
|
||||
|
||||
|
||||
@@ -1275,7 +1289,7 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) {
|
||||
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 = ITTI_MSG_INSTANCE(received_message_p);
|
||||
instance = ITTI_MSG_DESTINATION_INSTANCE(received_message_p);
|
||||
//msg_name_p = ITTI_MSG_NAME(received_message_p);
|
||||
|
||||
switch (ITTI_MSG_ID(received_message_p)) {
|
||||
|
||||
@@ -0,0 +1,822 @@
|
||||
/* 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.c
|
||||
* \brief
|
||||
* \author Sebastien ROUX, Lionel GAUTHIER, Navid Nikaein, Panos MATZAKOS
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: lionel.gauthier@eurecom.fr
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "mme_config.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "msc.h"
|
||||
|
||||
#include "gtpv1u.h"
|
||||
#include "NwGtpv1u.h"
|
||||
#include "NwGtpv1uMsg.h"
|
||||
#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"
|
||||
#include "COMMON/platform_types.h"
|
||||
#include "COMMON/platform_constants.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "gtpv1u_eNB_task.h"
|
||||
#include "gtpv1u_gNB_task.h"
|
||||
#include "rrc_eNB_GTPV1U.h"
|
||||
|
||||
#undef GTP_DUMP_SOCKET
|
||||
|
||||
extern unsigned char NB_eNB_INST;
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
extern NwGtpv1uRcT gtpv1u_eNB_send_udp_msg(
|
||||
NwGtpv1uUdpHandleT udpHandle,
|
||||
uint8_t *buffer,
|
||||
uint32_t buffer_len,
|
||||
uint32_t buffer_offset,
|
||||
uint32_t peerIpAddr,
|
||||
uint16_t peerPort);
|
||||
|
||||
extern NwGtpv1uRcT gtpv1u_eNB_log_request(NwGtpv1uLogMgrHandleT hLogMgr,
|
||||
uint32_t logLevel,
|
||||
NwCharT *file,
|
||||
uint32_t line,
|
||||
NwCharT *logStr);
|
||||
|
||||
static NwGtpv1uRcT gtpv1u_start_timer_wrapper(
|
||||
NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
||||
uint32_t timeoutSec,
|
||||
uint32_t timeoutUsec,
|
||||
uint32_t tmrType,
|
||||
void *timeoutArg,
|
||||
NwGtpv1uTimerHandleT *hTmr) {
|
||||
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
||||
long timer_id;
|
||||
|
||||
if (tmrType == NW_GTPV1U_TMR_TYPE_ONE_SHOT) {
|
||||
timer_setup(timeoutSec,
|
||||
timeoutUsec,
|
||||
TASK_GTPV1_U,
|
||||
INSTANCE_DEFAULT,
|
||||
TIMER_ONE_SHOT,
|
||||
timeoutArg,
|
||||
&timer_id);
|
||||
} else {
|
||||
timer_setup(timeoutSec,
|
||||
timeoutUsec,
|
||||
TASK_GTPV1_U,
|
||||
INSTANCE_DEFAULT,
|
||||
TIMER_PERIODIC,
|
||||
timeoutArg,
|
||||
&timer_id);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static NwGtpv1uRcT
|
||||
gtpv1u_stop_timer_wrapper(
|
||||
NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
||||
NwGtpv1uTimerHandleT hTmr) {
|
||||
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Callback called when a gtpv1u message arrived on UDP interface */
|
||||
NwGtpv1uRcT gtpv1u_gNB_process_stack_req(
|
||||
NwGtpv1uUlpHandleT hUlp,
|
||||
NwGtpv1uUlpApiT *pUlpApi) {
|
||||
boolean_t result = FALSE;
|
||||
teid_t teid = 0;
|
||||
hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
|
||||
gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL;
|
||||
protocol_ctxt_t ctxt;
|
||||
NwGtpv1uRcT rc;
|
||||
|
||||
switch(pUlpApi->apiType) {
|
||||
/* Here there are two type of messages handled:
|
||||
* - T-PDU
|
||||
* - END-MARKER
|
||||
*/
|
||||
case NW_GTPV1U_ULP_API_RECV_TPDU: {
|
||||
uint8_t buffer[4096];
|
||||
uint32_t buffer_len;
|
||||
//uint16_t msgType = NW_GTP_GPDU;
|
||||
//NwGtpv1uMsgT *pMsg = NULL;
|
||||
/* Nw-gptv1u stack has processed a PDU. we can schedule it to PDCP
|
||||
* for transmission.
|
||||
*/
|
||||
teid = pUlpApi->apiInfo.recvMsgInfo.teid;
|
||||
//pMsg = (NwGtpv1uMsgT *) pUlpApi->apiInfo.recvMsgInfo.hMsg;
|
||||
//msgType = pMsg->msgType;
|
||||
|
||||
if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg,
|
||||
buffer, &buffer_len)) {
|
||||
LOG_E(GTPU, "Error while retrieving T-PDU");
|
||||
}
|
||||
|
||||
itti_free(TASK_UDP, ((NwGtpv1uMsgT *)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBuf);
|
||||
#if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0
|
||||
gtpv1u_eNB_write_dump_socket(buffer,buffer_len);
|
||||
#endif
|
||||
rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack,
|
||||
pUlpApi->apiInfo.recvMsgInfo.hMsg);
|
||||
|
||||
if (rc != NW_GTPV1U_OK) {
|
||||
LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc);
|
||||
}
|
||||
|
||||
hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, teid, (void **)>pv1u_teid_data_p);
|
||||
|
||||
if (hash_rc == HASH_TABLE_OK) {
|
||||
#if defined(LOG_GTPU) && LOG_GTPU > 0
|
||||
LOG_D(GTPU, "Received T-PDU from gtpv1u stack teid %u size %d -> enb module id %u ue module id %u rab id %u\n",
|
||||
teid,
|
||||
buffer_len,
|
||||
gtpv1u_teid_data_p->enb_id,
|
||||
gtpv1u_teid_data_p->ue_id,
|
||||
gtpv1u_teid_data_p->eps_bearer_id);
|
||||
#endif
|
||||
//warning "LG eps bearer mapping to DRB id to do (offset -4)"
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, gtpv1u_teid_data_p->enb_id, ENB_FLAG_YES, gtpv1u_teid_data_p->ue_id, 0, 0,gtpv1u_teid_data_p->enb_id);
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_GTPU_ENB,
|
||||
MSC_PDCP_ENB,
|
||||
NULL,0,
|
||||
MSC_AS_TIME_FMT" DATA-REQ rb %u size %u",
|
||||
0,0,
|
||||
(gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4,
|
||||
buffer_len);
|
||||
|
||||
result = pdcp_data_req(
|
||||
&ctxt,
|
||||
SRB_FLAG_NO,
|
||||
(gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4,
|
||||
0, // mui
|
||||
SDU_CONFIRM_NO, // confirm
|
||||
buffer_len,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_DATA,NULL, NULL
|
||||
);
|
||||
|
||||
if ( result == FALSE ) {
|
||||
if (ctxt.configured == FALSE )
|
||||
LOG_W(GTPU, "gNB node PDCP data request failed, cause: [UE:%x]RB is not configured!\n", ctxt.rnti) ;
|
||||
else
|
||||
LOG_W(GTPU, "PDCP data request failed\n");
|
||||
|
||||
return NW_GTPV1U_FAILURE;
|
||||
}
|
||||
} else {
|
||||
LOG_W(GTPU, "Received T-PDU from gtpv1u stack teid %u unknown size %u", teid, buffer_len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
LOG_E(GTPU, "Received undefined UlpApi (%02x) from gtpv1u stack!\n",
|
||||
pUlpApi->apiType);
|
||||
}
|
||||
} // end of switch
|
||||
|
||||
return NW_GTPV1U_OK;
|
||||
}
|
||||
|
||||
int 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.gtpv1u_data_g = (gtpv1u_data_t *)calloc(sizeof(gtpv1u_data_t),1);
|
||||
LOG_I(GTPU, "Initializing GTPU stack %p\n",&RC.gtpv1u_data_g);
|
||||
//gtpv1u_data_g.gtpv1u_stack;
|
||||
/* Initialize UE hashtable */
|
||||
RC.gtpv1u_data_g->ue_mapping = hashtable_create (32, NULL, NULL);
|
||||
AssertFatal(RC.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.gtpv1u_data_g->teid_mapping = hashtable_create (256, NULL, NULL);
|
||||
AssertFatal(RC.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.gtpv1u_data_g->seq_num = 0;
|
||||
RC.gtpv1u_data_g->restart_counter = 0;
|
||||
|
||||
/* Initializing GTPv1-U stack */
|
||||
if ((rc = nwGtpv1uInitialize(&RC.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.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.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.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.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.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;
|
||||
}
|
||||
|
||||
void *gtpv1u_gNB_task(void *args) {
|
||||
int rc = 0;
|
||||
rc = gtpv1u_gNB_init();
|
||||
AssertFatal(rc == 0, "gtpv1u_eNB_init Failed");
|
||||
itti_mark_task_ready(TASK_GTPV1_U);
|
||||
MSC_START_USE();
|
||||
|
||||
while(1) {
|
||||
(void) gtpv1u_eNB_process_itti_msg (NULL);
|
||||
}
|
||||
|
||||
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_ */
|
||||
@@ -0,0 +1,51 @@
|
||||
/* 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_task.h
|
||||
* \brief
|
||||
* \author Lionel Gauthier Panos Matzakos
|
||||
* \company Eurecom
|
||||
* \email: lionel.gauthier@eurecom.fr
|
||||
*/
|
||||
|
||||
#ifndef GTPV1U_GNB_TASK_H_
|
||||
#define GTPV1U_GNB_TASK_H_
|
||||
|
||||
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_ */
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
#include "NwEvt.h"
|
||||
#include "NwLog.h"
|
||||
|
||||
#ifndef __NW_MINI_LOG_MGR_H__
|
||||
#define __NW_MINI_LOG_MGR_H__
|
||||
|
||||
#ifndef NW_ASSERT
|
||||
#define NW_ASSERT assert
|
||||
#endif
|
||||
|
||||
#ifndef __NW_MINI_LOG_MGR_H__
|
||||
#define __NW_MINI_LOG_MGR_H__
|
||||
|
||||
extern uint32_t g_log_level;
|
||||
|
||||
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
#include "NwEvt.h"
|
||||
#include "NwLog.h"
|
||||
|
||||
#ifndef __NW_MINI_TMR_MGR_H__
|
||||
#define __NW_MINI_TMR_MGR_H__
|
||||
|
||||
#ifndef NW_ASSERT
|
||||
#define NW_ASSERT assert
|
||||
#endif
|
||||
|
||||
#ifndef __NW_MINI_TMR_MGR_H__
|
||||
#define __NW_MINI_TMR_MGR_H__
|
||||
|
||||
typedef struct {
|
||||
NwEventT ev;
|
||||
void* timeoutArg;
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
#include "NwEvt.h"
|
||||
#include "NwLog.h"
|
||||
|
||||
#ifndef __NW_MINI_UDP_ENTITY_H__
|
||||
#define __NW_MINI_UDP_ENTITY_H__
|
||||
|
||||
#ifndef NW_ASSERT
|
||||
#define NW_ASSERT assert
|
||||
#endif
|
||||
|
||||
#ifndef __NW_MINI_UDP_ENTITY_H__
|
||||
#define __NW_MINI_UDP_ENTITY_H__
|
||||
|
||||
typedef struct {
|
||||
uint32_t hSocket;
|
||||
NwEventT ev;
|
||||
|
||||
+34
-20
@@ -136,12 +136,26 @@ void m3ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_associa
|
||||
//dump_trees_m3();
|
||||
|
||||
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
|
||||
M3AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
|
||||
M3AP_WARN("Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
|
||||
sctp_new_association_resp->sctp_state,
|
||||
instance,
|
||||
sctp_new_association_resp->ulp_cnx_id);
|
||||
//m3ap_handle_m3_setup_message(instance_p, m3ap_enb_data_p,
|
||||
//sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
|
||||
sleep(4);
|
||||
int index;
|
||||
/* Trying to connect to the provided list of eNB ip address */
|
||||
for (index = 0; index < instance_p->nb_m3; index++) {
|
||||
//M2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n",
|
||||
// instance_id, instance->eNB_id);
|
||||
m3ap_MCE_register_MCE(instance_p,
|
||||
&instance_p->target_mme_m3_ip_address[index],
|
||||
&instance_p->mme_m3_ip_address,
|
||||
instance_p->sctp_in_streams,
|
||||
instance_p->sctp_out_streams,
|
||||
instance_p->mce_port_for_M3C,
|
||||
instance_p->multi_sd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -215,7 +229,7 @@ int m3ap_MCE_init_sctp (m3ap_MCE_instance_t *instance_p,
|
||||
sctp_init_t *sctp_init = NULL;
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(local_ip_addr != NULL);
|
||||
message = itti_alloc_new_message (TASK_M3AP_MCE, SCTP_INIT_MSG_MULTI_REQ);
|
||||
message = itti_alloc_new_message (TASK_M3AP_MCE, 0, SCTP_INIT_MSG_MULTI_REQ);
|
||||
sctp_init = &message->ittiMsg.sctp_init_multi;
|
||||
sctp_init->port = mce_port_for_M3C;
|
||||
sctp_init->ppid = M3AP_SCTP_PPID;
|
||||
@@ -249,7 +263,7 @@ static void m3ap_MCE_register_MCE(m3ap_MCE_instance_t *instance_p,
|
||||
m3ap_MCE_data_t *m3ap_mce_data = NULL;
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(target_MCE_ip_address != NULL);
|
||||
message = itti_alloc_new_message(TASK_M3AP_MCE, SCTP_NEW_ASSOCIATION_REQ_MULTI);
|
||||
message = itti_alloc_new_message(TASK_M3AP_MCE, 0, SCTP_NEW_ASSOCIATION_REQ_MULTI);
|
||||
sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi;
|
||||
sctp_new_association_req->port = mce_port_for_M3C;
|
||||
sctp_new_association_req->ppid = M3AP_SCTP_PPID;
|
||||
@@ -299,7 +313,7 @@ void m3ap_MCE_handle_register_MCE(instance_t instance,
|
||||
DevCheck(new_instance->tac == m3ap_register_MCE->tac, new_instance->tac, m3ap_register_MCE->tac, 0);
|
||||
DevCheck(new_instance->mcc == m3ap_register_MCE->mcc, new_instance->mcc, m3ap_register_MCE->mcc, 0);
|
||||
DevCheck(new_instance->mnc == m3ap_register_MCE->mnc, new_instance->mnc, m3ap_register_MCE->mnc, 0);
|
||||
M3AP_WARN("MCE[%d] already registered\n", instance);
|
||||
M3AP_WARN("MCE[%ld] already registered\n", instance);
|
||||
} else {
|
||||
new_instance = calloc(1, sizeof(m3ap_MCE_instance_t));
|
||||
DevAssert(new_instance != NULL);
|
||||
@@ -343,7 +357,7 @@ void m3ap_MCE_handle_register_MCE(instance_t instance,
|
||||
new_instance->mce_port_for_M3C = m3ap_register_MCE->mme_port_for_M3C;
|
||||
/* Add the new instance to the list of MCE (meaningfull in virtual mode) */
|
||||
m3ap_MCE_insert_new_instance(new_instance);
|
||||
M3AP_INFO("Registered new MCE[%d] and %s MCE id %u\n",
|
||||
M3AP_INFO("Registered new MCE[%ld] and %s MCE id %u\n",
|
||||
instance,
|
||||
m3ap_register_MCE->cell_type == CELL_MACRO_ENB ? "macro" : "home",
|
||||
m3ap_register_MCE->MCE_id);
|
||||
@@ -356,7 +370,7 @@ void m3ap_MCE_handle_register_MCE(instance_t instance,
|
||||
return;
|
||||
}
|
||||
|
||||
M3AP_INFO("MCE[%d] MCE id %u acting as a listner (server)\n",
|
||||
M3AP_INFO("MCE[%ld] MCE id %u acting as a listner (server)\n",
|
||||
instance, m3ap_register_MCE->MCE_id);
|
||||
}
|
||||
}
|
||||
@@ -383,7 +397,7 @@ void m3ap_MCE_handle_sctp_init_msg_multi_cnf(
|
||||
/* Trying to connect to the provided list of MCE ip address */
|
||||
|
||||
for (index = 0; index < instance->nb_m3; index++) {
|
||||
M3AP_INFO("MCE[%d] MCE id %u acting as an initiator (client)\n",
|
||||
M3AP_INFO("MCE[%ld] MCE id %u acting as an initiator (client)\n",
|
||||
instance_id, instance->MCE_id);
|
||||
m3ap_MCE_register_MCE(instance,
|
||||
&instance->target_mme_m3_ip_address[index],
|
||||
@@ -523,7 +537,7 @@ void *m3ap_MCE_task(void *arg) {
|
||||
switch (ITTI_MSG_ID(received_msg)) {
|
||||
case MESSAGE_TEST:
|
||||
// LOG_W(M3AP,"MCE Received Test Message ... TODO\n");
|
||||
// //MessageDef * message_p = itti_alloc_new_message(TASK_M3AP, MESSAGE_TEST);
|
||||
// //MessageDef * message_p = itti_alloc_new_message(TASK_M3AP, 0, MESSAGE_TEST);
|
||||
// //itti_send_msg_to_task(TASK_M2AP_ENB, 1/*ctxt_pP->module_id*/, message_p);
|
||||
//
|
||||
// asn_dec_rval_t dec_ret;
|
||||
@@ -563,78 +577,78 @@ void *m3ap_MCE_task(void *arg) {
|
||||
break;
|
||||
|
||||
case M3AP_SUBFRAME_PROCESS:
|
||||
m3ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg));
|
||||
m3ap_check_timers(ITTI_MSG_DESTINATION_INSTANCE(received_msg));
|
||||
break;
|
||||
|
||||
case M3AP_REGISTER_MCE_REQ:
|
||||
LOG_I(M3AP,"MCE Received M3AP_REGISTER_MCE_REQ Message\n");
|
||||
|
||||
m3ap_MCE_handle_register_MCE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
m3ap_MCE_handle_register_MCE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&M3AP_REGISTER_MCE_REQ(received_msg));
|
||||
break;
|
||||
|
||||
case M3AP_MBMS_SESSION_START_RESP:
|
||||
LOG_I(M3AP,"MCE M3AP_MBMS_SESSION_START_RESP Message\n");
|
||||
MCE_send_MBMS_SESSION_START_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
MCE_send_MBMS_SESSION_START_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&M3AP_MBMS_SESSION_START_RESP(received_msg));
|
||||
|
||||
break;
|
||||
|
||||
case M3AP_MBMS_SESSION_STOP_RESP:
|
||||
LOG_I(M3AP,"MCE M3AP_MBMS_SESSION_STOP_RESP Message\n");
|
||||
MCE_send_MBMS_SESSION_STOP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
MCE_send_MBMS_SESSION_STOP_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&M3AP_MBMS_SESSION_START_RESP(received_msg));
|
||||
|
||||
break;
|
||||
|
||||
case M3AP_MBMS_SESSION_UPDATE_RESP:
|
||||
LOG_I(M3AP,"MCE M3AP_MBMS_SESSION_UPDATE_RESP Message\n");
|
||||
//MCE_send_MBMS_SESSION_UPDATE_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
//MCE_send_MBMS_SESSION_UPDATE_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
//&M3AP_MBMS_SESSION_START_RESP(received_msg));
|
||||
|
||||
break;
|
||||
|
||||
|
||||
// case M3AP_HANDOVER_REQ:
|
||||
// m3ap_eNB_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
// m3ap_eNB_handle_handover_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &M3AP_HANDOVER_REQ(received_msg));
|
||||
// break;
|
||||
//
|
||||
// case M3AP_HANDOVER_REQ_ACK:
|
||||
// m3ap_eNB_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
// m3ap_eNB_handle_handover_req_ack(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &M3AP_HANDOVER_REQ_ACK(received_msg));
|
||||
// break;
|
||||
//
|
||||
// case M3AP_UE_CONTEXT_RELEASE:
|
||||
// m3ap_eNB_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
// m3ap_eNB_ue_context_release(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &M3AP_UE_CONTEXT_RELEASE(received_msg));
|
||||
// break;
|
||||
//
|
||||
case SCTP_INIT_MSG_MULTI_CNF:
|
||||
LOG_D(M3AP,"MCE Received SCTP_INIT_MSG_MULTI_CNF Message\n");
|
||||
|
||||
m3ap_MCE_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
m3ap_MCE_handle_sctp_init_msg_multi_cnf(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_RESP:
|
||||
LOG_D(M3AP,"MCE Received SCTP_NEW_ASSOCIATION_RESP Message\n");
|
||||
|
||||
m3ap_MCE_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
m3ap_MCE_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_resp);
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_IND:
|
||||
LOG_D(M3AP,"MCE Received SCTP_NEW_ASSOCIATION Message\n");
|
||||
|
||||
m3ap_MCE_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
m3ap_MCE_handle_sctp_association_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_ind);
|
||||
break;
|
||||
|
||||
case SCTP_DATA_IND:
|
||||
LOG_D(M3AP,"MCE Received SCTP_DATA_IND Message\n");
|
||||
|
||||
m3ap_MCE_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
m3ap_MCE_handle_sctp_data_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_data_ind);
|
||||
break;
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ int m3ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stre
|
||||
}
|
||||
|
||||
/* Calling the right handler */
|
||||
LOG_I(M3AP, "Calling handler with instance %d\n",instance);
|
||||
LOG_I(M3AP, "Calling handler with instance %ld\n",instance);
|
||||
ret = (*m3ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1])
|
||||
(instance, assoc_id, stream, &pdu);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu);
|
||||
|
||||
@@ -74,7 +74,7 @@ int MCE_handle_MBMS_SESSION_START_REQUEST(instance_t instance,
|
||||
//
|
||||
// container = &pdu->choice.initiatingMessage.value.choice.SessionStartRequest;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MCE, M3AP_MBMS_SESSION_START_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MCE, 0, M3AP_MBMS_SESSION_START_REQ);
|
||||
|
||||
//
|
||||
// /* M3 Setup Request == Non UE-related procedure -> stream 0 */
|
||||
@@ -248,7 +248,7 @@ int MCE_handle_MBMS_SESSION_STOP_REQUEST(instance_t instance,
|
||||
//MCE_send_MBMS_SESSION_STOP_RESPONSE(instance,assoc_id);
|
||||
//}else
|
||||
//MCE_send_MBMS_SESSION_STOP_FAILURE(instance,assoc_id);
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MCE, M3AP_MBMS_SESSION_STOP_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MCE, 0, M3AP_MBMS_SESSION_STOP_REQ);
|
||||
|
||||
//
|
||||
// /* M3 Setup Request == Non UE-related procedure -> stream 0 */
|
||||
@@ -361,7 +361,7 @@ int MCE_handle_MBMS_SESSION_UPDATE_REQUEST(instance_t instance,
|
||||
//MCE_send_MBMS_SESSION_STOP_RESPONSE(instance,assoc_id);
|
||||
//}else
|
||||
//MCE_send_MBMS_SESSION_STOP_FAILURE(instance,assoc_id);
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MCE, M3AP_MBMS_SESSION_UPDATE_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MCE, 0, M3AP_MBMS_SESSION_UPDATE_REQ);
|
||||
|
||||
//
|
||||
// /* M3 Setup Request == Non UE-related procedure -> stream 0 */
|
||||
@@ -711,7 +711,7 @@ int MCE_handle_M3_SETUP_RESPONSE(instance_t instance,
|
||||
//int num_cells_to_activate = 0;
|
||||
//M3AP_Cells_to_be_Activated_List_Item_t *cell;
|
||||
|
||||
MessageDef *msg_p = itti_alloc_new_message (TASK_M3AP_MCE, M3AP_SETUP_RESP);
|
||||
MessageDef *msg_p = itti_alloc_new_message (TASK_M3AP_MCE, 0, M3AP_SETUP_RESP);
|
||||
|
||||
// LOG_D(M3AP, "M3AP: M3Setup-Resp: protocolIEs.list.count %d\n",
|
||||
// in->protocolIEs.list.count);
|
||||
|
||||
@@ -116,7 +116,7 @@ void dump_trees_m3(void)
|
||||
m3ap_MCE_instance_t *zz;
|
||||
STAILQ_FOREACH(zz, &m3ap_MCE_internal_data.m3ap_MCE_instances_head,
|
||||
m3ap_MCE_entries) {
|
||||
printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance);
|
||||
printf("here comes the tree (instance %ld):\n---------------------------------------------\n", zz->instance);
|
||||
dump_tree_m3(zz->m3ap_mce_head.rbh_root);
|
||||
printf("---------------------------------------------\n");
|
||||
}
|
||||
|
||||
+25
-25
@@ -105,7 +105,7 @@ void m3ap_MME_handle_sctp_association_resp(instance_t instance, sctp_new_associa
|
||||
DevAssert(sctp_new_association_resp != NULL);
|
||||
|
||||
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
|
||||
LOG_W(M3AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
|
||||
LOG_W(M3AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
|
||||
sctp_new_association_resp->sctp_state,
|
||||
instance,
|
||||
sctp_new_association_resp->ulp_cnx_id);
|
||||
@@ -233,7 +233,7 @@ int m3ap_MME_init_sctp (m3ap_MME_instance_t *instance_p,
|
||||
sctp_init_t *sctp_init = NULL;
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(local_ip_addr != NULL);
|
||||
message = itti_alloc_new_message (TASK_M3AP_MME, SCTP_INIT_MSG_MULTI_REQ);
|
||||
message = itti_alloc_new_message (TASK_M3AP_MME, 0, SCTP_INIT_MSG_MULTI_REQ);
|
||||
sctp_init = &message->ittiMsg.sctp_init_multi;
|
||||
sctp_init->port = mme_port_for_M3C;
|
||||
sctp_init->ppid = M3AP_SCTP_PPID;
|
||||
@@ -267,7 +267,7 @@ static void m3ap_MME_register_MME(m3ap_MME_instance_t *instance_p,
|
||||
// m3ap_MME_data_t *m3ap_mme_data = NULL;
|
||||
// DevAssert(instance_p != NULL);
|
||||
// DevAssert(target_MME_ip_address != NULL);
|
||||
// message = itti_alloc_new_message(TASK_M3AP_MME, SCTP_NEW_ASSOCIATION_REQ_MULTI);
|
||||
// message = itti_alloc_new_message(TASK_M3AP_MME, 0, SCTP_NEW_ASSOCIATION_REQ_MULTI);
|
||||
// sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi;
|
||||
// sctp_new_association_req->port = mme_port_for_M3C;
|
||||
// sctp_new_association_req->ppid = M3AP_SCTP_PPID;
|
||||
@@ -394,7 +394,7 @@ void m3ap_MME_handle_sctp_init_msg_multi_cnf(
|
||||
/* Trying to connect to the provided list of MME ip address */
|
||||
|
||||
for (index = 0; index < instance->nb_m3; index++) {
|
||||
M3AP_INFO("MME[%d] MME id %u acting as an initiator (client)\n",
|
||||
M3AP_INFO("MME[%ld] MME id %u acting as an initiator (client)\n",
|
||||
instance_id, instance->MME_id);
|
||||
m3ap_MME_register_MME(instance,
|
||||
&instance->target_mme_m3_ip_address[index],
|
||||
@@ -506,7 +506,7 @@ void MME_task_send_sctp_init_req(instance_t enb_id, m3ap_mme_sctp_req_t * m3ap_m
|
||||
|
||||
MessageDef *message_p = NULL;
|
||||
|
||||
message_p = itti_alloc_new_message (TASK_M3AP_MME, SCTP_INIT_MSG);
|
||||
message_p = itti_alloc_new_message (TASK_M3AP_MME, 0, SCTP_INIT_MSG);
|
||||
if(m3ap_mme_sctp_req==NULL) {
|
||||
LOG_I(M3AP, "M3AP_SCTP_REQ(create socket)\n");
|
||||
message_p->ittiMsg.sctp_init.port = M3AP_PORT_NUMBER;
|
||||
@@ -555,7 +555,7 @@ void *m3ap_MME_task(void *arg) {
|
||||
switch (ITTI_MSG_ID(received_msg)) {
|
||||
case MESSAGE_TEST:
|
||||
LOG_W(M3AP,"MME Received MESSAGE_TEST Message\n");
|
||||
//MessageDef * message_p = itti_alloc_new_message(TASK_M3AP_MME, MESSAGE_TEST);
|
||||
//MessageDef * message_p = itti_alloc_new_message(TASK_M3AP_MME, 0, MESSAGE_TEST);
|
||||
//itti_send_msg_to_task(TASK_M3AP, 1/*ctxt_pP->module_id*/, message_p);
|
||||
break;
|
||||
case TERMINATE_MESSAGE:
|
||||
@@ -564,31 +564,31 @@ void *m3ap_MME_task(void *arg) {
|
||||
break;
|
||||
|
||||
// case M3AP_SUBFRAME_PROCESS:
|
||||
// m3ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg));
|
||||
// m3ap_check_timers(ITTI_MSG_DESTINATION_INSTANCE(received_msg));
|
||||
// break;
|
||||
//
|
||||
// case M3AP_REGISTER_MME_REQ:
|
||||
// LOG_W(M3AP,"MME Received M3AP_REGISTER_MME_REQ Message\n");
|
||||
// m3ap_MME_handle_register_MME(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
// m3ap_MME_handle_register_MME(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &M3AP_REGISTER_MME_REQ(received_msg));
|
||||
// break;
|
||||
//
|
||||
|
||||
case M3AP_MME_SCTP_REQ:
|
||||
MME_task_send_sctp_init_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
MME_task_send_sctp_init_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&M3AP_MME_SCTP_REQ(received_msg));
|
||||
break;
|
||||
|
||||
case M3AP_SETUP_RESP:
|
||||
LOG_I(M3AP,"MME Received M3AP_SETUP_RESP Message\n");
|
||||
MME_send_M3_SETUP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
MME_send_M3_SETUP_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&M3AP_SETUP_RESP(received_msg));
|
||||
break;
|
||||
// break;
|
||||
//
|
||||
// case M3AP_SETUP_FAILURE:
|
||||
// LOG_W(M3AP,"MME Received M3AP_SETUP_FAILURE Message\n");
|
||||
// MME_send_M2_SETUP_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
// MME_send_M2_SETUP_FAILURE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &M3AP_SETUP_FAILURE(received_msg));
|
||||
// break;
|
||||
//
|
||||
@@ -599,83 +599,83 @@ void *m3ap_MME_task(void *arg) {
|
||||
//
|
||||
case M3AP_MBMS_SESSION_START_REQ:
|
||||
LOG_I(M3AP,"MME Received M3AP_MBMS_SESSION_START_REQ Message\n");
|
||||
MME_send_MBMS_SESSION_START_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
MME_send_MBMS_SESSION_START_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&M3AP_MBMS_SESSION_START_REQ(received_msg));
|
||||
break;
|
||||
//
|
||||
case M3AP_MBMS_SESSION_STOP_REQ:
|
||||
LOG_I(M3AP,"MME Received M3AP_MBMS_SESSION_STOP_REQ Message\n");
|
||||
MME_send_MBMS_SESSION_STOP_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
MME_send_MBMS_SESSION_STOP_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&M3AP_MBMS_SESSION_STOP_REQ(received_msg));
|
||||
break;
|
||||
//
|
||||
case M3AP_MBMS_SESSION_UPDATE_REQ:
|
||||
LOG_I(M3AP,"MME Received M3AP_MBMS_SESSION_UPDATE_REQ Message\n");
|
||||
// MME_send_MBMS_SESSION_UPDATE_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
// MME_send_MBMS_SESSION_UPDATE_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &M3AP_MBMS_SESSION_UPDATE_REQ(received_msg));
|
||||
break;
|
||||
//
|
||||
// case M3AP_RESET:
|
||||
// LOG_W(M3AP,"MME Received M3AP_RESET Message\n");
|
||||
// MME_send_RESET(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
// MME_send_RESET(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &M3AP_RESET(received_msg));
|
||||
// break;
|
||||
//
|
||||
// case M3AP_ENB_CONFIGURATION_UPDATE_ACK:
|
||||
// LOG_W(M3AP,"MME Received M3AP_ENB_CONFIGURATION_UPDATE_ACK Message\n");
|
||||
// MME_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
// MME_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &M3AP_ENB_CONFIGURATION_UPDATE_ACK(received_msg));
|
||||
// break;
|
||||
//
|
||||
// case M3AP_ENB_CONFIGURATION_UPDATE_FAILURE:
|
||||
// LOG_W(M3AP,"MME Received M3AP_ENB_CONFIGURATION_UPDATE_FAILURE Message\n");
|
||||
// MME_send_ENB_CONFIGURATION_UPDATE_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
// MME_send_ENB_CONFIGURATION_UPDATE_FAILURE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &M3AP_ENB_CONFIGURATION_UPDATE_FAILURE(received_msg))// break;
|
||||
//
|
||||
//
|
||||
// case M3AP_MME_CONFIGURATION_UPDATE:
|
||||
// LOG_W(M3AP,"MME Received M3AP_MME_CONFIGURATION_UPDATE Message\n");
|
||||
// MME_send_MME_CONFIGURATION_UPDATE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
// MME_send_MME_CONFIGURATION_UPDATE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &M3AP_MME_CONFIGURATION_UPDATE(received_msg));
|
||||
// break;
|
||||
//
|
||||
|
||||
// case M3AP_HANDOVER_REQ:
|
||||
// m3ap_MME_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
// m3ap_MME_handle_handover_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &M3AP_HANDOVER_REQ(received_msg));
|
||||
// break;
|
||||
//
|
||||
// case M3AP_HANDOVER_REQ_ACK:
|
||||
// m3ap_MME_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
// m3ap_MME_handle_handover_req_ack(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &M3AP_HANDOVER_REQ_ACK(received_msg));
|
||||
// break;
|
||||
//
|
||||
// case M3AP_UE_CONTEXT_RELEASE:
|
||||
// m3ap_MME_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
// m3ap_MME_ue_context_release(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &M3AP_UE_CONTEXT_RELEASE(received_msg));
|
||||
// break;
|
||||
//
|
||||
case SCTP_INIT_MSG_MULTI_CNF:
|
||||
LOG_E(M3AP,"MME Received SCTP_INIT_MSG_MULTI_CNF Message ... shoudn't be happening ... it doesn't at leaast with M2AP_MCEC\n");
|
||||
m3ap_MME_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
m3ap_MME_handle_sctp_init_msg_multi_cnf(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_RESP:
|
||||
LOG_D(M3AP,"MME Received SCTP_NEW_ASSOCIATION_RESP Message\n");
|
||||
m3ap_MME_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
m3ap_MME_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_resp);
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_IND:
|
||||
LOG_D(M3AP,"MME Received SCTP_NEW_ASSOCIATION Message\n");
|
||||
m3ap_MME_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
m3ap_MME_handle_sctp_association_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_ind);
|
||||
break;
|
||||
|
||||
case SCTP_DATA_IND:
|
||||
LOG_D(M3AP,"MME Received SCTP_DATA_IND Message\n");
|
||||
m3ap_MME_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
m3ap_MME_handle_sctp_data_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_data_ind);
|
||||
break;
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ int m3ap_MME_handle_message(instance_t instance, uint32_t assoc_id, int32_t stre
|
||||
}
|
||||
|
||||
/* Calling the right handler */
|
||||
LOG_I(M3AP, "Calling handler with instance %d\n",instance);
|
||||
LOG_I(M3AP, "Calling handler with instance %ld\n",instance);
|
||||
ret = (*m3ap_MME_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1])
|
||||
(instance, assoc_id, stream, &pdu);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu);
|
||||
|
||||
@@ -265,7 +265,7 @@ int MME_handle_MBMS_SESSION_START_RESPONSE(instance_t instance,
|
||||
int MCE_MBMS_M3AP_ID=-1;
|
||||
|
||||
|
||||
MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME,M3AP_MBMS_SESSION_START_RESP); //TODO
|
||||
MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME, 0,M3AP_MBMS_SESSION_START_RESP); //TODO
|
||||
|
||||
LOG_D(M3AP, "M3AP: SessionStart-Resp: protocolIEs.list.count %d\n",
|
||||
in->protocolIEs.list.count);
|
||||
@@ -403,7 +403,7 @@ int MME_handle_MBMS_SESSION_STOP_RESPONSE(instance_t instance,
|
||||
int MCE_MBMS_M3AP_ID=-1;
|
||||
|
||||
|
||||
MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME,M3AP_MBMS_SESSION_STOP_RESP); //TODO
|
||||
MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME, 0,M3AP_MBMS_SESSION_STOP_RESP); //TODO
|
||||
|
||||
LOG_D(M3AP, "M3AP: MBMSSessionStop-Resp: protocolIEs.list.count %d\n",
|
||||
in->protocolIEs.list.count);
|
||||
@@ -522,7 +522,7 @@ int MME_handle_M3_SETUP_REQUEST(instance_t instance,
|
||||
// assoc_id, stream);
|
||||
// }
|
||||
//
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MME, M3AP_SETUP_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MME, 0, M3AP_SETUP_REQ);
|
||||
//printf("M3AP_SETUP_REQ(message_p).assoc_id %d\n",M3AP_SETUP_REQ(message_p).assoc_id);
|
||||
//
|
||||
// /* assoc_id */
|
||||
@@ -1055,7 +1055,7 @@ int MME_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance,
|
||||
int MCE_MBMS_M3AP_ID=-1;
|
||||
|
||||
|
||||
MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME,M3AP_MBMS_SESSION_UPDATE_RESP); //TODO
|
||||
MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME, 0,M3AP_MBMS_SESSION_UPDATE_RESP); //TODO
|
||||
|
||||
LOG_D(M3AP, "M3AP: SessionUpdate-Resp: protocolIEs.list.count %d\n",
|
||||
in->protocolIEs.list.count);
|
||||
|
||||
@@ -116,7 +116,7 @@ void dump_mme_trees_m2(void)
|
||||
m3ap_MME_instance_t *zz;
|
||||
STAILQ_FOREACH(zz, &m3ap_MME_internal_data.m3ap_MME_instances_head,
|
||||
m3ap_MME_entries) {
|
||||
printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance);
|
||||
printf("here comes the tree (instance %ld):\n---------------------------------------------\n", zz->instance);
|
||||
dump_mme_tree_m2(zz->m3ap_mme_head.rbh_root);
|
||||
printf("---------------------------------------------\n");
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ void m3ap_MCE_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uin
|
||||
MessageDef *message_p;
|
||||
sctp_data_req_t *sctp_data_req;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MCE, SCTP_DATA_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MCE, 0, SCTP_DATA_REQ);
|
||||
|
||||
sctp_data_req = &message_p->ittiMsg.sctp_data_req;
|
||||
|
||||
@@ -56,7 +56,7 @@ void m3ap_MCE_itti_send_sctp_close_association(instance_t instance, int32_t asso
|
||||
MessageDef *message_p = NULL;
|
||||
sctp_close_association_t *sctp_close_association_p = NULL;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MCE, SCTP_CLOSE_ASSOCIATION);
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MCE, 0, SCTP_CLOSE_ASSOCIATION);
|
||||
sctp_close_association_p = &message_p->ittiMsg.sctp_close_association;
|
||||
sctp_close_association_p->assoc_id = assoc_id;
|
||||
|
||||
@@ -70,7 +70,7 @@ void m3ap_MME_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uin
|
||||
MessageDef *message_p;
|
||||
sctp_data_req_t *sctp_data_req;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MME, SCTP_DATA_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MME, 0, SCTP_DATA_REQ);
|
||||
|
||||
sctp_data_req = &message_p->ittiMsg.sctp_data_req;
|
||||
|
||||
@@ -88,7 +88,7 @@ void m3ap_MME_itti_send_sctp_close_association(instance_t instance, int32_t asso
|
||||
MessageDef *message_p = NULL;
|
||||
sctp_close_association_t *sctp_close_association_p = NULL;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MME, SCTP_CLOSE_ASSOCIATION);
|
||||
message_p = itti_alloc_new_message(TASK_M3AP_MME, 0, SCTP_CLOSE_ASSOCIATION);
|
||||
sctp_close_association_p = &message_p->ittiMsg.sctp_close_association;
|
||||
sctp_close_association_p->assoc_id = assoc_id;
|
||||
|
||||
|
||||
+14
-14
@@ -76,7 +76,7 @@ extern RAN_CONTEXT_t RC;
|
||||
// {
|
||||
// // M3AP registration
|
||||
// /* note: there is an implicit relationship between the data structure and the message name */
|
||||
// msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_REGISTER_MCE_REQ);
|
||||
// msg_p = itti_alloc_new_message (TASK_MME_APP, 0, M3AP_REGISTER_MCE_REQ);
|
||||
// //RCconfig_S1(msg_p, mce_id);
|
||||
//
|
||||
// //if (mce_id == 0)
|
||||
@@ -90,7 +90,7 @@ extern RAN_CONTEXT_t RC;
|
||||
// //if (NODE_IS_DU(node_type)) { // F1AP registration
|
||||
// // // configure F1AP here for F1C
|
||||
// // LOG_I(ENB_APP,"ngran_eNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n");
|
||||
// // msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SETUP_REQ);
|
||||
// // msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, F1AP_SETUP_REQ);
|
||||
// // RCconfig_DU_F1(msg_p, enb_id);
|
||||
//
|
||||
// // LOG_I(ENB_APP,"[eNB %d] eNB_app_register via F1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id));
|
||||
@@ -99,7 +99,7 @@ extern RAN_CONTEXT_t RC;
|
||||
// //}
|
||||
// //else { // S1AP registration
|
||||
// // /* note: there is an implicit relationship between the data structure and the message name */
|
||||
// // msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ);
|
||||
// // msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, S1AP_REGISTER_ENB_REQ);
|
||||
// // RCconfig_S1(msg_p, enb_id);
|
||||
//
|
||||
// // if (enb_id == 0) RCconfig_gtpu();
|
||||
@@ -126,7 +126,7 @@ extern RAN_CONTEXT_t RC;
|
||||
//
|
||||
// for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) {
|
||||
// {
|
||||
// msg_p = itti_alloc_new_message (TASK_ENB_APP, X2AP_REGISTER_ENB_REQ);
|
||||
// msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, X2AP_REGISTER_ENB_REQ);
|
||||
// RCconfig_X2(msg_p, mce_id);
|
||||
// itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p);
|
||||
// register_mce_x2_pending++;
|
||||
@@ -146,7 +146,7 @@ extern RAN_CONTEXT_t RC;
|
||||
// for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) {
|
||||
// {
|
||||
// // LOG_W(MME_APP,"Register commes inside ...\n");
|
||||
// msg_p = itti_alloc_new_message (TASK_MME_APP, M2AP_REGISTER_MCE_REQ);
|
||||
// msg_p = itti_alloc_new_message (TASK_MME_APP, 0, M2AP_REGISTER_MCE_REQ);
|
||||
// //RCconfig_M2_MCE(msg_p, mce_id);
|
||||
// itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p);
|
||||
// // LOG_W(MME_APP,"Register sent ...\n");
|
||||
@@ -163,7 +163,7 @@ static uint32_t MME_app_handle_m3ap_setup_req(instance_t instance){
|
||||
|
||||
//uint32_t mce_id=0;
|
||||
MessageDef *msg_p;
|
||||
msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_SETUP_RESP);
|
||||
msg_p = itti_alloc_new_message (TASK_MME_APP, 0, M3AP_SETUP_RESP);
|
||||
itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
|
||||
|
||||
return 0;
|
||||
@@ -187,7 +187,7 @@ static uint32_t MME_app_handle_m3ap_session_start_resp(instance_t instance){
|
||||
//
|
||||
// uint32_t mce_id=0;
|
||||
// MessageDef *msg_p;
|
||||
// msg_p = itti_alloc_new_message (TASK_MME_APP, M2AP_MBMS_SCHEDULING_INFORMATION);
|
||||
// msg_p = itti_alloc_new_message (TASK_MME_APP, 0, M2AP_MBMS_SCHEDULING_INFORMATION);
|
||||
// itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
|
||||
//
|
||||
// return 0;
|
||||
@@ -197,7 +197,7 @@ static uint32_t MME_app_send_m3ap_session_start_req(instance_t instance){
|
||||
|
||||
//uint32_t mce_id=0;
|
||||
MessageDef *msg_p;
|
||||
msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_MBMS_SESSION_START_REQ);
|
||||
msg_p = itti_alloc_new_message (TASK_MME_APP, 0, M3AP_MBMS_SESSION_START_REQ);
|
||||
itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
|
||||
|
||||
return 0;
|
||||
@@ -206,7 +206,7 @@ static uint32_t MME_app_send_m3ap_session_start_req(instance_t instance){
|
||||
//
|
||||
// //uint32_t mce_id=0;
|
||||
// MessageDef *msg_p;
|
||||
// msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_MBMS_SESSION_STOP_REQ);
|
||||
// msg_p = itti_alloc_new_message (TASK_MME_APP, 0, M3AP_MBMS_SESSION_STOP_REQ);
|
||||
// itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
|
||||
//
|
||||
// return 0;
|
||||
@@ -215,7 +215,7 @@ static uint32_t MME_app_send_m3ap_session_update_req(instance_t instance){
|
||||
|
||||
//uint32_t mce_id=0;
|
||||
MessageDef *msg_p;
|
||||
msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_MBMS_SESSION_UPDATE_REQ);
|
||||
msg_p = itti_alloc_new_message (TASK_MME_APP, 0, M3AP_MBMS_SESSION_UPDATE_REQ);
|
||||
itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
|
||||
|
||||
return 0;
|
||||
@@ -263,7 +263,7 @@ void *MME_app_task(void *args_p) {
|
||||
do {
|
||||
// Wait for a message
|
||||
itti_receive_msg (TASK_MME_APP, &msg_p);
|
||||
instance = ITTI_MSG_INSTANCE (msg_p);
|
||||
instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p);
|
||||
|
||||
switch (ITTI_MSG_ID(msg_p)) {
|
||||
case TERMINATE_MESSAGE:
|
||||
@@ -297,7 +297,7 @@ void *MME_app_task(void *args_p) {
|
||||
// if (registered_mce == mce_nb) {
|
||||
// /* If all MCE are registered, start L2L1 task */
|
||||
// // MessageDef *msg_init_p;
|
||||
// // msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE);
|
||||
// // msg_init_p = itti_alloc_new_message (TASK_ENB_APP, 0, INITIALIZE_MESSAGE);
|
||||
// // itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p);
|
||||
// } else {
|
||||
// LOG_W(MME_APP, " %d MCE not associated with a MME, retrying registration in %d seconds ...\n",
|
||||
@@ -341,7 +341,7 @@ void *MME_app_task(void *args_p) {
|
||||
// /* If all MCE cells are registered, start L2L1 task */
|
||||
// MessageDef *msg_init_p;
|
||||
|
||||
// //msg_init_p = itti_alloc_new_message (TASK_MME_APP, INITIALIZE_MESSAGE);
|
||||
// //msg_init_p = itti_alloc_new_message (TASK_MME_APP, 0, INITIALIZE_MESSAGE);
|
||||
// //itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p);
|
||||
|
||||
// } else {
|
||||
@@ -365,7 +365,7 @@ void *MME_app_task(void *args_p) {
|
||||
|
||||
case M3AP_DEREGISTERED_MCE_IND: //M3AP_DEREGISTERED_MCE_IND debería
|
||||
if (EPC_MODE_ENABLED) {
|
||||
LOG_W(MME_APP, "[MCE %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p),
|
||||
LOG_W(MME_APP, "[MCE %ld] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p),
|
||||
M3AP_DEREGISTERED_MCE_IND(msg_p).nb_mme);
|
||||
/* TODO handle recovering of registration */
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ int RCconfig_MME(void ) {
|
||||
|
||||
if (address) {
|
||||
MessageDef *message;
|
||||
AssertFatal((message = itti_alloc_new_message(TASK_MME_APP, M3AP_MME_SCTP_REQ))!=NULL,"");
|
||||
AssertFatal((message = itti_alloc_new_message(TASK_MME_APP, 0, M3AP_MME_SCTP_REQ))!=NULL,"");
|
||||
M3AP_MME_SCTP_REQ (message).mme_m3_ip_address.ipv6 = 0;
|
||||
M3AP_MME_SCTP_REQ (message).mme_m3_ip_address.ipv4 = 1;
|
||||
strcpy( M3AP_MME_SCTP_REQ (message).mme_m3_ip_address.ipv4_address, address);
|
||||
|
||||
@@ -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_) */
|
||||
|
||||
|
||||
@@ -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 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,114 @@
|
||||
/*
|
||||
* 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.c
|
||||
* \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 <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nas_log.h"
|
||||
|
||||
#include "RegistrationRequest.h"
|
||||
|
||||
int decode_registration_request(registration_request_msg *registration_request, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
uint32_t decoded = 0;
|
||||
int decoded_result = 0;
|
||||
|
||||
LOG_FUNC_IN;
|
||||
LOG_TRACE(INFO, "EMM - registration_request len = %d",
|
||||
len);
|
||||
|
||||
/* Decoding mandatory fields */
|
||||
if ((decoded_result = decode_5gs_registration_type(®istration_request->fgsregistrationtype, 0, *(buffer + decoded) & 0x0f, len - decoded)) < 0) {
|
||||
// return decoded_result;
|
||||
LOG_FUNC_RETURN(decoded_result);
|
||||
}
|
||||
|
||||
if ((decoded_result = decode_u8_nas_key_set_identifier(®istration_request->naskeysetidentifier, 0, *(buffer + decoded) >> 4, len - decoded)) < 0) {
|
||||
// return decoded_result;
|
||||
LOG_FUNC_RETURN(decoded_result);
|
||||
}
|
||||
|
||||
decoded++;
|
||||
|
||||
if ((decoded_result = decode_5gs_mobile_identity(®istration_request->fgsmobileidentity, 0, buffer + decoded, len - decoded)) < 0) {
|
||||
// return decoded_result;
|
||||
LOG_FUNC_RETURN(decoded_result);
|
||||
} else
|
||||
decoded += decoded_result;
|
||||
|
||||
|
||||
// TODO, Decoding optional fields
|
||||
|
||||
return decoded;
|
||||
}
|
||||
|
||||
int encode_registration_request(registration_request_msg *registration_request, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
int encoded = 0;
|
||||
int encode_result = 0;
|
||||
|
||||
*(buffer + encoded) = ((encode_u8_nas_key_set_identifier(®istration_request->naskeysetidentifier) & 0x0f) << 4) | (encode_5gs_registration_type(®istration_request->fgsregistrationtype) & 0x0f);
|
||||
encoded++;
|
||||
|
||||
if ((encode_result =
|
||||
encode_5gs_mobile_identity(®istration_request->fgsmobileidentity, 0, buffer +
|
||||
encoded, len - encoded)) < 0) //Return in case of error
|
||||
return encode_result;
|
||||
else
|
||||
encoded += encode_result;
|
||||
|
||||
if ((registration_request->presencemask & REGISTRATION_REQUEST_5GMM_CAPABILITY_PRESENT)
|
||||
== REGISTRATION_REQUEST_5GMM_CAPABILITY_PRESENT) {
|
||||
if ((encode_result = encode_5gmm_capability(®istration_request->fgmmcapability,
|
||||
REGISTRATION_REQUEST_5GMM_CAPABILITY_IEI, buffer + encoded, len -
|
||||
encoded)) < 0)
|
||||
// Return in case of error
|
||||
return encode_result;
|
||||
else
|
||||
encoded += encode_result;
|
||||
}
|
||||
|
||||
if ((registration_request->presencemask & REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_PRESENT)
|
||||
== REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_PRESENT) {
|
||||
if ((encode_result = encode_nrue_security_capability(®istration_request->nruesecuritycapability,
|
||||
REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_IEI, buffer + encoded, len -
|
||||
encoded)) < 0)
|
||||
// Return in case of error
|
||||
return encode_result;
|
||||
else
|
||||
encoded += encode_result;
|
||||
}
|
||||
|
||||
|
||||
// TODO, Encoding optional fields
|
||||
return encoded;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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 "FGSMobileIdentity.h"
|
||||
#include "NasKeySetIdentifier.h"
|
||||
#include "FGSRegistrationType.h"
|
||||
#include "MessageType.h"
|
||||
#include "FGMMCapability.h"
|
||||
#include "NrUESecurityCapability.h"
|
||||
|
||||
#ifndef REGISTRATION_REQUEST_H_
|
||||
#define REGISTRATION_REQUEST_H_
|
||||
|
||||
|
||||
# define REGISTRATION_REQUEST_NON_CURRENT_NATIVE_NAS_KEYSET_PRESENT (1<<0)
|
||||
# define REGISTRATION_REQUEST_5GMM_CAPABILITY_PRESENT (1<<1)
|
||||
# define REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_PRESENT (1<<2)
|
||||
# define REGISTRATION_REQUEST_REQUESTED_NSSAI_PRESENT (1<<3)
|
||||
# define REGISTRATION_REQUEST_LAST_VISITED_REGISTERED_TAI_PRESENT (1<<4)
|
||||
# define REGISTRATION_REQUEST_S1_UE_NETWORK_CAPABILITY_PRESENT (1<<5)
|
||||
# define REGISTRATION_REQUEST_UPLINK_DATA_STATUS_PRESENT (1<<6)
|
||||
# define REGISTRATION_REQUEST_PDU_SESSION_STATUS_PRESENT (1<<7)
|
||||
# define REGISTRATION_REQUEST_MICO_INDICATION_PRESENT (1<<8)
|
||||
# define REGISTRATION_REQUEST_UE_STATUS_PRESENT (1<<9)
|
||||
# define REGISTRATION_REQUEST_ADDITIONAL_GUTI_PRESENT (1<<10)
|
||||
# define REGISTRATION_REQUEST_ALLOWED_PDU_SESSION_STATUS_PRESENT (1<<11)
|
||||
# define REGISTRATION_REQUEST_UE_USAGE_SETTING_PRESENT (1<<12)
|
||||
# define REGISTRATION_REQUEST_REQUESTED_DRX_PARAMETERS_PRESENT (1<<13)
|
||||
# define REGISTRATION_REQUEST_EPS_NAS_MESSAGE_CONTAINER_PRESENT (1<<14)
|
||||
# define REGISTRATION_REQUEST_LADN_INDICATION_PRESENT (1<<15)
|
||||
# define REGISTRATION_REQUEST_PAYLOAD_CONTAINER_TYPE_PRESENT (1<<16)
|
||||
# define REGISTRATION_REQUEST_PAYLOAD_CONTAINER_PRESENT (1<<17)
|
||||
# define REGISTRATION_REQUEST_NETWORK_SLICING_INDICATION_PRESENT (1<<18)
|
||||
# define REGISTRATION_REQUEST_5GS_UPDATE_TYPE_PRESENT (1<<19)
|
||||
# define REGISTRATION_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT (1<<20)
|
||||
# define REGISTRATION_REQUEST_EPS_BEARER_CONTEXT_STATUS_PRESENT (1<<21)
|
||||
|
||||
typedef enum registration_request_iei_tag {
|
||||
REGISTRATION_REQUEST_NON_CURRENT_NATIVE_NAS_KEYSET_IEI = 0xC0, /* 0xC- = 192- */
|
||||
REGISTRATION_REQUEST_5GMM_CAPABILITY_IEI = 0x10, /* 0x10 = 16 */
|
||||
REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_IEI = 0x2E, /* 0x2E = 46 */
|
||||
REGISTRATION_REQUEST_REQUESTED_NSSAI_IEI = 0x2F, /* 0x2F = 47 */
|
||||
REGISTRATION_REQUEST_LAST_VISITED_REGISTERED_TAI_IEI = 0x52, /* 0x52 = 82 */
|
||||
REGISTRATION_REQUEST_S1_UE_NETWORK_CAPABILITY_IEI = 0x17, /* 0x17 = 23 */
|
||||
REGISTRATION_REQUEST_UPLINK_DATA_STATUS_IEI = 0x40, /* 0x40 = 64 */
|
||||
REGISTRATION_REQUEST_PDU_SESSION_STATUS_IEI = 0x50, /* 0x50 = 80 */
|
||||
REGISTRATION_REQUEST_MICO_INDICATION_IEI = 0xB0, /* 0xB- = 176- */
|
||||
REGISTRATION_REQUEST_UE_STATUS_IEI = 0x2B, /* 0x2B = 43 */
|
||||
REGISTRATION_REQUEST_ADDITIONAL_GUTI_IEI = 0x77, /* 0x77 = 119 */
|
||||
REGISTRATION_REQUEST_ALLOWED_PDU_SESSION_STATUS_IEI = 0x25, /* 0x25 = 37 */
|
||||
REGISTRATION_REQUEST_UE_USAGE_SETTING_IEI = 0x18, /* 0x18 = 24 */
|
||||
REGISTRATION_REQUEST_REQUESTED_DRX_PARAMETERS_IEI = 0x51, /* 0x51 = 81 */
|
||||
REGISTRATION_REQUEST_EPS_NAS_MESSAGE_CONTAINER_IEI = 0x70, /* 0x70 = 112 */
|
||||
REGISTRATION_REQUEST_LADN_INDICATION_IEI = 0x74, /* 0x74 = 116 */
|
||||
REGISTRATION_REQUEST_PAYLOAD_CONTAINER_TYPE_IEI = 0x80, /* 0x80 = 128 */
|
||||
REGISTRATION_REQUEST_PAYLOAD_CONTAINER_IEI = 0x7B, /* 0x7B = 123 */
|
||||
REGISTRATION_REQUEST_NETWORK_SLICING_INDICATION_IEI = 0x90, /* 0x90 = 144 */
|
||||
REGISTRATION_REQUEST_5GS_UPDATE_TYPE_IEI = 0x53, /* 0x53 = 83 */
|
||||
REGISTRATION_REQUEST_NAS_MESSAGE_CONTAINER_IEI = 0x71, /* 0x71 = 113 */
|
||||
REGISTRATION_REQUEST_EPS_BEARER_CONTEXT_STATUS_IEI = 0x60 /* 0x60 = 96 */
|
||||
} registration_request_iei;
|
||||
|
||||
/*
|
||||
* Message name: Registration request
|
||||
* Description: This message is sent by the UE to the AMF. See TS24.501 table 8.2.6.1.1.
|
||||
* Significance: dual
|
||||
* Direction: UE to network
|
||||
*/
|
||||
|
||||
typedef struct registration_request_msg_tag {
|
||||
/* Mandatory fields */
|
||||
ExtendedProtocolDiscriminator protocoldiscriminator;
|
||||
SecurityHeaderType securityheadertype:4;
|
||||
SpareHalfOctet sparehalfoctet:4;
|
||||
MessageType messagetype;
|
||||
FGSRegistrationType fgsregistrationtype;
|
||||
NasKeySetIdentifier naskeysetidentifier;
|
||||
FGSMobileIdentity fgsmobileidentity;
|
||||
|
||||
/* Optional fields */
|
||||
uint32_t presencemask;
|
||||
FGMMCapability fgmmcapability;
|
||||
NrUESecurityCapability nruesecuritycapability;
|
||||
} registration_request_msg;
|
||||
|
||||
int decode_registration_request(registration_request_msg *registrationrequest, uint8_t *buffer, uint32_t len);
|
||||
|
||||
int encode_registration_request(registration_request_msg *registrationrequest, uint8_t *buffer, uint32_t len);
|
||||
|
||||
#endif /* ! defined(REGISTRATION_REQUEST_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,50 @@
|
||||
/*
|
||||
* 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 ExtendedProtocolDiscriminator.c
|
||||
|
||||
\brief Extended protocol discriminator 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 "ExtendedProtocolDiscriminator.h"
|
||||
|
||||
int encode_ex_protocol_discriminator(ExtendedProtocolDiscriminator *exprotocoldiscriminator, uint8_t iei, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int decode_ex_protocol_discriminator(ExtendedProtocolDiscriminator *exprotocoldiscriminator, uint8_t iei, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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 ExtendedProtocolDiscriminator.h
|
||||
|
||||
\brief Extended protocol discriminator 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 EXTENDED_PROTOCOL_DISCRIMINATOR_H_
|
||||
#define EXTENDED_PROTOCOL_DISCRIMINATOR_H_
|
||||
|
||||
typedef uint8_t ExtendedProtocolDiscriminator;
|
||||
|
||||
int encode_ex_protocol_discriminator(ExtendedProtocolDiscriminator *exprotocoldiscriminator, uint8_t iei, uint8_t *buffer, uint32_t len);
|
||||
|
||||
int decode_ex_protocol_discriminator(ExtendedProtocolDiscriminator *exprotocoldiscriminator, uint8_t iei, uint8_t *buffer, uint32_t len);
|
||||
|
||||
#endif /* EXTENDED PROTOCOL DISCRIMINATOR_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_ */
|
||||
|
||||
@@ -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 FGMMCapability.c
|
||||
* \brief 5GS Mobile Identity 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 "FGMMCapability.h"
|
||||
|
||||
|
||||
|
||||
int encode_5gmm_capability(FGMMCapability *fgmmcapability, uint8_t iei, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
int encoded = 0;
|
||||
if(iei){
|
||||
*buffer = fgmmcapability->iei;
|
||||
encoded++;
|
||||
*(buffer+encoded) = fgmmcapability->length;
|
||||
encoded++;
|
||||
*(buffer+encoded) = fgmmcapability->value;
|
||||
encoded++;
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 FGMMCapability.h
|
||||
* \brief 5GS Mobile Capability 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 FGMM_CAPABILITY_H_
|
||||
#define FGMM_CAPABILITY_H_
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t iei;
|
||||
uint8_t length;
|
||||
uint8_t value;
|
||||
} FGMMCapability;
|
||||
|
||||
|
||||
int encode_5gmm_capability(FGMMCapability *fgmmcapability, uint8_t iei, uint8_t *buffer, uint32_t len);
|
||||
|
||||
#endif /* FGMM_CAPABILITY_H_ */
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* 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 FGSMobileIdentity.c
|
||||
* \brief 5GS Mobile Identity 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 "FGSMobileIdentity.h"
|
||||
|
||||
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)
|
||||
{
|
||||
int decoded_rc = TLV_DECODE_VALUE_DOESNT_MATCH;
|
||||
int decoded = 0;
|
||||
uint8_t ielen = 0;
|
||||
|
||||
if (iei > 0) {
|
||||
CHECK_IEI_DECODER(iei, *buffer);
|
||||
decoded++;
|
||||
}
|
||||
|
||||
ielen = *(buffer + decoded);
|
||||
decoded++;
|
||||
CHECK_LENGTH_DECODER(len - decoded, ielen);
|
||||
|
||||
uint8_t typeofidentity = *(buffer + decoded) & 0x7;
|
||||
|
||||
if (typeofidentity == FGS_MOBILE_IDENTITY_5G_GUTI) {
|
||||
decoded_rc = decode_guti_5gs_mobile_identity(&fgsmobileidentity->guti,
|
||||
buffer + decoded);
|
||||
}
|
||||
|
||||
if (decoded_rc < 0) {
|
||||
return decoded_rc;
|
||||
}
|
||||
|
||||
return (decoded + decoded_rc);
|
||||
}
|
||||
|
||||
int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
int encoded_rc = TLV_ENCODE_VALUE_DOESNT_MATCH;
|
||||
uint32_t encoded = 0;
|
||||
|
||||
if (iei > 0) {
|
||||
*buffer = iei;
|
||||
encoded++;
|
||||
}
|
||||
|
||||
encoded = encoded + 2;
|
||||
|
||||
if (fgsmobileidentity->guti.typeofidentity == FGS_MOBILE_IDENTITY_5G_GUTI) {
|
||||
encoded_rc = encode_guti_5gs_mobile_identity(&fgsmobileidentity->guti,
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static int decode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer)
|
||||
{
|
||||
int decoded = 0;
|
||||
uint16_t temp;
|
||||
guti->spare = (*(buffer + decoded) >> 4) & 0xf;
|
||||
|
||||
/*
|
||||
* For the 5G-GUTI, bits 5 to 8 of octet 3 are coded as "1111"
|
||||
*/
|
||||
if (guti->spare != 0xf) {
|
||||
return (TLV_ENCODE_VALUE_DOESNT_MATCH);
|
||||
}
|
||||
|
||||
|
||||
guti->oddeven = (*(buffer + decoded) >> 3) & 0x1;
|
||||
|
||||
/*
|
||||
* For the 5G-GUTI, bits 4 of octet 3 are coded as "0"
|
||||
*/
|
||||
if (guti->oddeven != 0) {
|
||||
return (TLV_ENCODE_VALUE_DOESNT_MATCH);
|
||||
}
|
||||
guti->typeofidentity = *(buffer + decoded) & 0x7;
|
||||
|
||||
if (guti->typeofidentity != FGS_MOBILE_IDENTITY_5G_GUTI) {
|
||||
return (TLV_ENCODE_VALUE_DOESNT_MATCH);
|
||||
}
|
||||
|
||||
decoded++;
|
||||
guti->mccdigit2 = (*(buffer + decoded) >> 4) & 0xf;
|
||||
guti->mccdigit1 = *(buffer + decoded) & 0xf;
|
||||
decoded++;
|
||||
guti->mncdigit3 = (*(buffer + decoded) >> 4) & 0xf;
|
||||
guti->mccdigit3 = *(buffer + decoded) & 0xf;
|
||||
decoded++;
|
||||
guti->mncdigit2 = (*(buffer + decoded) >> 4) & 0xf;
|
||||
guti->mncdigit1 = *(buffer + decoded) & 0xf;
|
||||
decoded++;
|
||||
|
||||
|
||||
guti->amfregionid = *(buffer+decoded);
|
||||
decoded++;
|
||||
IES_DECODE_U16(buffer, decoded, temp);
|
||||
guti->amfsetid = temp>>3;
|
||||
guti->amfpointer = temp&0x3f;
|
||||
|
||||
IES_DECODE_U32(buffer, decoded, guti->tmsi);
|
||||
return decoded;
|
||||
}
|
||||
|
||||
|
||||
static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
uint16_t temp;
|
||||
*(buffer + encoded) = 0xf0 | ((guti->oddeven & 0x1) << 3) |
|
||||
(guti->typeofidentity & 0x7);
|
||||
encoded++;
|
||||
*(buffer + encoded) = 0x00 | ((guti->mccdigit2 & 0xf) << 4) |
|
||||
(guti->mccdigit1 & 0xf);
|
||||
encoded++;
|
||||
*(buffer + encoded) = 0x00 | ((guti->mncdigit3 & 0xf) << 4) |
|
||||
(guti->mccdigit3 & 0xf);
|
||||
encoded++;
|
||||
*(buffer + encoded) = 0x00 | ((guti->mncdigit2 & 0xf) << 4) |
|
||||
(guti->mncdigit1 & 0xf);
|
||||
encoded++;
|
||||
|
||||
*(buffer + encoded) = guti->amfregionid;
|
||||
encoded++;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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 FGSMobileIdentity.h
|
||||
* \brief 5GS Mobile Identity 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_MOBILE_IDENTITY_H_
|
||||
#define FGS_MOBILE_IDENTITY_H_
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t spare:5;
|
||||
uint8_t typeofidentity:3;
|
||||
} NoIdentity5GSMobileIdentity_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t spare1:1;
|
||||
uint8_t supiformat:3;
|
||||
uint8_t spare2:1;
|
||||
uint8_t typeofidentity:3;
|
||||
uint8_t mccdigit2:4;
|
||||
uint8_t mccdigit1:4;
|
||||
uint8_t mncdigit3:4;
|
||||
uint8_t mccdigit3:4;
|
||||
uint8_t mncdigit2:4;
|
||||
uint8_t mncdigit1:4;
|
||||
uint8_t routingindicatordigit2:4;
|
||||
uint8_t routingindicatordigit1:4;
|
||||
uint8_t routingindicatordigit4:4;
|
||||
uint8_t routingindicatordigit3:4;
|
||||
uint8_t spare3:1;
|
||||
uint8_t spare4:1;
|
||||
uint8_t spare5:1;
|
||||
uint8_t spare6:1;
|
||||
uint8_t protectionschemeId:4;
|
||||
uint8_t homenetworkpki;
|
||||
uint32_t schemeoutput;
|
||||
} Suci5GSMobileIdentity_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t spare:4;
|
||||
uint8_t oddeven:1;
|
||||
uint8_t typeofidentity:3;
|
||||
uint8_t mccdigit2:4;
|
||||
uint8_t mccdigit1:4;
|
||||
uint8_t mncdigit3:4;
|
||||
uint8_t mccdigit3:4;
|
||||
uint8_t mncdigit2:4;
|
||||
uint8_t mncdigit1:4;
|
||||
uint8_t amfregionid;
|
||||
uint16_t amfsetid:10;
|
||||
uint16_t amfpointer:6;
|
||||
uint32_t tmsi;
|
||||
} Guti5GSMobileIdentity_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t digit1:4;
|
||||
uint8_t oddeven:1;
|
||||
uint8_t typeofidentity:3;
|
||||
uint8_t digitp1:4;
|
||||
uint8_t digitp:4;
|
||||
} Imei5GSMobileIdentity_t;
|
||||
|
||||
typedef Imei5GSMobileIdentity_t Imeisv5GSMobileIdentity_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t digit1:4;
|
||||
uint8_t spare:1;
|
||||
uint8_t typeofidentity:3;
|
||||
uint16_t amfsetid:10;
|
||||
uint16_t amfpointer:6;
|
||||
uint32_t tmsi;
|
||||
} Stmsi5GSMobileIdentity_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t spare:5;
|
||||
uint8_t typeofidentity:3;
|
||||
uint8_t macaddr;
|
||||
} Macaddr5GSMobileIdentity_t;
|
||||
|
||||
typedef union FGSMobileIdentity_tag {
|
||||
#define FGS_MOBILE_IDENTITY_NOIDENTITY 0b000
|
||||
#define FGS_MOBILE_IDENTITY_SUCI 0b001
|
||||
#define FGS_MOBILE_IDENTITY_5G_GUTI 0b010
|
||||
#define FGS_MOBILE_IDENTITY_IMEI 0b011
|
||||
#define FGS_MOBILE_IDENTITY_5GS_TMSI 0b100
|
||||
#define FGS_MOBILE_IDENTITY_IMEISV 0b101
|
||||
#define FGS_MOBILE_IDENTITY_MAC_ADDR 0b110
|
||||
NoIdentity5GSMobileIdentity_t noidentity;
|
||||
Suci5GSMobileIdentity_t suci;
|
||||
Guti5GSMobileIdentity_t guti;
|
||||
Imei5GSMobileIdentity_t imei;
|
||||
Stmsi5GSMobileIdentity_t stmsi;
|
||||
Imeisv5GSMobileIdentity_t imeisv;
|
||||
Macaddr5GSMobileIdentity_t macaddress;
|
||||
} FGSMobileIdentity;
|
||||
|
||||
int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len);
|
||||
|
||||
int decode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len);
|
||||
|
||||
#endif /* FGS MOBILE IDENTITY_H_ */
|
||||
|
||||
@@ -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,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 FGSRegistrationType.c
|
||||
* \brief 5GS Registration Type 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 "FGSRegistrationType.h"
|
||||
|
||||
int decode_5gs_registration_type(FGSRegistrationType *fgsregistrationtype, uint8_t iei, uint8_t value, uint32_t len)
|
||||
{
|
||||
int decoded = 0;
|
||||
uint8_t *buffer = &value;
|
||||
if (iei > 0) {
|
||||
CHECK_IEI_DECODER((*buffer & 0xf0), iei);
|
||||
}
|
||||
|
||||
*fgsregistrationtype = *buffer & 0x7;
|
||||
decoded++;
|
||||
|
||||
return decoded;
|
||||
}
|
||||
|
||||
int encode_5gs_registration_type(FGSRegistrationType *fgsregistrationtype)
|
||||
{
|
||||
uint8_t bufferReturn;
|
||||
uint8_t *buffer = &bufferReturn;
|
||||
uint8_t encoded = 0;
|
||||
uint8_t iei = 0;
|
||||
*(buffer + encoded) = 0x00 | (iei & 0xf0) | 0x8|
|
||||
(*fgsregistrationtype & 0x7);
|
||||
encoded++;
|
||||
|
||||
return bufferReturn;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 FGSRegistrationType.h
|
||||
* \brief 5GS Registration Type 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_TYPE_H_
|
||||
#define FGS_REGISTRATION_TYPE_H_
|
||||
|
||||
#define FGS_REGISTRATION_TYPE_MINIMUM_LENGTH 1
|
||||
#define FGS_REGISTRATION_TYPE_MAXIMUM_LENGTH 1
|
||||
|
||||
typedef uint8_t FGSRegistrationType;
|
||||
|
||||
|
||||
#define INITIAL_REGISTRATION 0b001
|
||||
#define MOBILITY_REGISTRATION_UPDATING 0b010
|
||||
#define PERIODIC_REGISTRATION_UPDATING 0b011
|
||||
#define EMERGENCY_REGISTRATION 0b100
|
||||
|
||||
int encode_5gs_registration_type(FGSRegistrationType *fgsregistrationtype);
|
||||
|
||||
int decode_5gs_registration_type(FGSRegistrationType *fgsregistrationtype, uint8_t iei, uint8_t value, uint32_t len);
|
||||
|
||||
|
||||
#endif /* FGS_REGISTRATION_TYPE_H_*/
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 NrUESecurityCapability.c
|
||||
* \brief 5GS UE Security Capability 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 "NrUESecurityCapability.h"
|
||||
|
||||
|
||||
|
||||
int encode_nrue_security_capability(NrUESecurityCapability *nruesecuritycapability, uint8_t iei, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
int encoded = 0;
|
||||
if(iei){
|
||||
*buffer = nruesecuritycapability->iei;
|
||||
encoded++;
|
||||
*(buffer+encoded) = nruesecuritycapability->length;
|
||||
encoded++;
|
||||
*(buffer+encoded) = nruesecuritycapability->fg_EA;
|
||||
encoded++;
|
||||
*(buffer+encoded) = nruesecuritycapability->fg_IA;
|
||||
encoded++;
|
||||
*(buffer+encoded) = nruesecuritycapability->EEA;
|
||||
encoded++;
|
||||
*(buffer+encoded) = nruesecuritycapability->EIA;
|
||||
encoded++;
|
||||
if((nruesecuritycapability->length - 4) > 0)
|
||||
encoded = encoded + nruesecuritycapability->length - 4;
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 NrUESecurityCapability.h
|
||||
* \brief 5GS UE Security Capability 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 NRUE_SECURITY_CAPABILITY_H_
|
||||
#define NRUE_SECURITY_CAPABILITY_H_
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t iei;
|
||||
uint8_t length;
|
||||
uint8_t fg_EA;
|
||||
uint8_t fg_IA;
|
||||
uint8_t EEA;
|
||||
uint8_t EIA;
|
||||
} NrUESecurityCapability;
|
||||
|
||||
|
||||
int encode_nrue_security_capability(NrUESecurityCapability *nruesecuritycapability, uint8_t iei, uint8_t *buffer, uint32_t len);
|
||||
|
||||
#endif /* NRUE_SECURITY_CAPABILITY_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_ */
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 SpareHalfOctet.c
|
||||
|
||||
\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 "TLVEncoder.h"
|
||||
#include "TLVDecoder.h"
|
||||
#include "SpareHalfOctet.h"
|
||||
|
||||
int decode_spare_half_octet(SpareHalfOctet *sparehalfoctet, uint8_t iei, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int encode_spare_half_octet(SpareHalfOctet *sparehalfoctet, uint8_t iei, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 SpareHalfOctet.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 "OctetString.h"
|
||||
|
||||
#ifndef SPARE_HALF_OCTET_H_
|
||||
#define SPARE_HALF_OCTET_H_
|
||||
|
||||
#define SPARE_HALF_OCTET_MINIMUM_LENGTH 1
|
||||
#define SPARE_HALF_OCTET_MAXIMUM_LENGTH 1
|
||||
|
||||
typedef uint8_t SpareHalfOctet;
|
||||
|
||||
int encode_spare_half_octet(SpareHalfOctet *sparehalfoctet, uint8_t iei, uint8_t *buffer, uint32_t len);
|
||||
|
||||
int decode_spare_half_octet(SpareHalfOctet *sparehalfoctet, uint8_t iei, uint8_t *buffer, uint32_t len);
|
||||
|
||||
#endif /* SPARE HALF OCTET_H_ */
|
||||
|
||||
@@ -0,0 +1,391 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
*/
|
||||
#ifndef NR_NAS_DEFS_H
|
||||
#define NR_NAS_DEFS_H
|
||||
|
||||
#include <common/utils/LOG/log.h>
|
||||
#include <openair3/UICC/usim_interface.h>
|
||||
#include <openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h>
|
||||
|
||||
/* TS 24.007 possible L3 formats:
|
||||
Table 11.1: Formats of information elements
|
||||
Format Meaning IEI present LI present Value part present
|
||||
T Type only yes no no
|
||||
V Value only no no yes
|
||||
TV Type and Value yes no yes
|
||||
LV Length and Value no yes yes
|
||||
TLV Type, Length and Value yes yes yes
|
||||
LV-E Length and Value no yes yes
|
||||
TLV-E Type, Length and Value yes yes yes
|
||||
*/
|
||||
|
||||
/* Map task id to printable name. */
|
||||
typedef struct {
|
||||
int id;
|
||||
char text[256];
|
||||
} text_info_t;
|
||||
|
||||
static inline const char * idToText(const text_info_t* table, int size, int id) {
|
||||
for(int i=0; i<size; i++)
|
||||
if (table[i].id==id)
|
||||
return table[i].text;
|
||||
LOG_E(NAS,"impossible id %x\n", id);
|
||||
return "IMPOSSIBLE";
|
||||
}
|
||||
#define idStr(TaBle, iD) idToText(TaBle, sizeof(TaBle)/sizeof(text_info_t), iD)
|
||||
|
||||
#define TO_TEXT(LabEl, nUmID) {nUmID, #LabEl},
|
||||
#define TO_ENUM(LabEl, nUmID ) LabEl = nUmID,
|
||||
|
||||
//TS 24.501, chap 9.2 => TS 24.007
|
||||
typedef enum {
|
||||
SGSsessionmanagementmessages=0x2e, //LTEbox: 0xC0 ???
|
||||
SGSmobilitymanagementmessages=0x7e,
|
||||
} Extendedprotocoldiscriminator_t;
|
||||
|
||||
#define FOREACH_TYPE(TYPE_DEF) \
|
||||
TYPE_DEF( Registrationrequest,0x41 )\
|
||||
TYPE_DEF( Registrationaccept,0x42 )\
|
||||
TYPE_DEF( Registrationcomplete,0x43 )\
|
||||
TYPE_DEF( Registrationreject,0x44 )\
|
||||
TYPE_DEF( DeregistrationrequestUEoriginating,0x45 )\
|
||||
TYPE_DEF( DeregistrationacceptUEoriginating,0x46 )\
|
||||
TYPE_DEF( DeregistrationrequestUEterminated,0x47 )\
|
||||
TYPE_DEF( DeregistrationacceptUEterminated,0x48 )\
|
||||
TYPE_DEF( Servicerequest,0x4c )\
|
||||
TYPE_DEF( Servicereject,0x4d )\
|
||||
TYPE_DEF( Serviceaccept,0x4e )\
|
||||
TYPE_DEF( Controlplaneservicerequest,0x4f )\
|
||||
TYPE_DEF( Networkslicespecificauthenticationcommand,0x50 )\
|
||||
TYPE_DEF( Networkslicespecificauthenticationcomplete,0x51 )\
|
||||
TYPE_DEF( Networkslicespecificauthenticationresult,0x52 )\
|
||||
TYPE_DEF( Configurationupdatecommand,0x54 )\
|
||||
TYPE_DEF( Configurationupdatecomplete,0x55 )\
|
||||
TYPE_DEF( Authenticationrequest,0x56 )\
|
||||
TYPE_DEF( Authenticationresponse,0x57 )\
|
||||
TYPE_DEF( Authenticationreject,0x58 )\
|
||||
TYPE_DEF( Authenticationfailure,0x59 )\
|
||||
TYPE_DEF( Authenticationresult,0x5a )\
|
||||
TYPE_DEF( Identityrequest,0x5b )\
|
||||
TYPE_DEF( Identityresponse,0x5c )\
|
||||
TYPE_DEF( Securitymodecommand,0x5d )\
|
||||
TYPE_DEF( Securitymodecomplete,0x5e )\
|
||||
TYPE_DEF( Securitymodereject,0x5f )\
|
||||
TYPE_DEF( SGMMstatus,0x64 )\
|
||||
TYPE_DEF( Notification,0x65 )\
|
||||
TYPE_DEF( Notificationresponse,0x66 )\
|
||||
TYPE_DEF( ULNAStransport,0x67 )\
|
||||
TYPE_DEF( DLNAStransport,0x68 )\
|
||||
TYPE_DEF( PDUsessionestablishmentrequest,0xc1 )\
|
||||
TYPE_DEF( PDUsessionestablishmentaccept,0xc2 )\
|
||||
TYPE_DEF( PDUsessionestablishmentreject,0xc3 )\
|
||||
TYPE_DEF( PDUsessionauthenticationcommand,0xc5 )\
|
||||
TYPE_DEF( PDUsessionauthenticationcomplete,0xc6 )\
|
||||
TYPE_DEF( PDUsessionauthenticationresult,0xc7 )\
|
||||
TYPE_DEF( PDUsessionmodificationrequest,0xc9 )\
|
||||
TYPE_DEF( PDUsessionmodificationreject,0xca )\
|
||||
TYPE_DEF( PDUsessionmodificationcommand,0xcb )\
|
||||
TYPE_DEF( PDUsessionmodificationcomplete,0xcc )\
|
||||
TYPE_DEF( PDUsessionmodificationcommandreject,0xcd )\
|
||||
TYPE_DEF( PDUsessionreleaserequest,0xd1 )\
|
||||
TYPE_DEF( PDUsessionreleasereject,0xd2 )\
|
||||
TYPE_DEF( PDUsessionreleasecommand,0xd3 )\
|
||||
TYPE_DEF( PDUsessionreleasecomplete,0xd4 )\
|
||||
TYPE_DEF( SGSMstatus,0xd6 )\
|
||||
|
||||
static const text_info_t message_text_info[] = {
|
||||
FOREACH_TYPE(TO_TEXT)
|
||||
};
|
||||
|
||||
//! Tasks id of each task
|
||||
typedef enum {
|
||||
FOREACH_TYPE(TO_ENUM)
|
||||
} SGSmobilitymanagementmessages_t;
|
||||
|
||||
// TS 24.501
|
||||
typedef enum {
|
||||
notsecurityprotected=0,
|
||||
Integrityprotected=1,
|
||||
Integrityprotectedandciphered=2,
|
||||
Integrityprotectedwithnew5GNASsecuritycontext=3,
|
||||
Integrityprotectedandcipheredwithnew5GNASsecuritycontext=4,
|
||||
} Security_header_t;
|
||||
|
||||
typedef enum {
|
||||
SUCI=1,
|
||||
SGGUTI,
|
||||
IMEI,
|
||||
SGSTMSI,
|
||||
IMEISV,
|
||||
MACaddress,
|
||||
EUI64,
|
||||
} identitytype_t;
|
||||
|
||||
|
||||
// table 9.11.3.2.1
|
||||
#define FOREACH_CAUSE(CAUSE_DEF) \
|
||||
CAUSE_DEF(Illegal_UE,0x3 )\
|
||||
CAUSE_DEF(PEI_not_accepted,0x5 )\
|
||||
CAUSE_DEF(Illegal_ME,0x6 )\
|
||||
CAUSE_DEF(SGS_services_not_allowed,0x7 )\
|
||||
CAUSE_DEF(UE_identity_cannot_be_derived_by_the_network,0x9 )\
|
||||
CAUSE_DEF(Implicitly_de_registered,0x0a )\
|
||||
CAUSE_DEF(PLMN_not_allowed,0x0b )\
|
||||
CAUSE_DEF(Tracking_area_not_allowed,0x0c )\
|
||||
CAUSE_DEF(Roaming_not_allowed_in_this_tracking_area,0x0d )\
|
||||
CAUSE_DEF(No_suitable_cells_in_tracking_area,0x0f )\
|
||||
CAUSE_DEF(MAC_failure,0x14 )\
|
||||
CAUSE_DEF(Synch_failure,0x15 )\
|
||||
CAUSE_DEF(Congestion,0x16 )\
|
||||
CAUSE_DEF(UE_security_capabilities_mismatch,0x17 )\
|
||||
CAUSE_DEF(Security_mode_rejected_unspecified,0x18 )\
|
||||
CAUSE_DEF(Non_5G_authentication_unacceptable,0x1a )\
|
||||
CAUSE_DEF(N1_mode_not_allowed,0x1b )\
|
||||
CAUSE_DEF(Restricted_service_area,0x1c )\
|
||||
CAUSE_DEF(Redirection_to_EPC_required,0x1f )\
|
||||
CAUSE_DEF(LADN_not_available,0x2b )\
|
||||
CAUSE_DEF(No_network_slices_available,0x3e )\
|
||||
CAUSE_DEF(Maximum_number_of_PDU_sessions_reached,0x41 )\
|
||||
CAUSE_DEF(Insufficient_resources_for_specific_slice_and_DNN,0x43 )\
|
||||
CAUSE_DEF(Insufficient_resources_for_specific_slice,0x45 )\
|
||||
CAUSE_DEF(ngKSI_already_in_use,0x47 )\
|
||||
CAUSE_DEF(Non_3GPP_access_to_5GCN_not_allowed,0x48 )\
|
||||
CAUSE_DEF(Serving_network_not_authorized,0x49 )\
|
||||
CAUSE_DEF(Temporarily_not_authorized_for_this_SNPN,0x4A )\
|
||||
CAUSE_DEF(Permanently_not_authorized_for_this_SNPN,0x4b )\
|
||||
CAUSE_DEF(Not_authorized_for_this_CAG_or_authorized_for_CAG_cells_only,0x4c )\
|
||||
CAUSE_DEF(Wireline_access_area_not_allowed,0x4d )\
|
||||
CAUSE_DEF(Payload_was_not_forwarded,0x5a )\
|
||||
CAUSE_DEF(DNN_not_supported_or_not_subscribed_in_the_slice,0x5b )\
|
||||
CAUSE_DEF(Insufficient_user_plane_resources_for_the_PDU_session,0x5c )\
|
||||
CAUSE_DEF(Semantically_incorrect_message,0x5f )\
|
||||
CAUSE_DEF(Invalid_mandatory_information,0x60 )\
|
||||
CAUSE_DEF(Message_type_non_existent_or_not_implemented,0x61 )\
|
||||
CAUSE_DEF(Message_type_not_compatible_with_the_protocol_state,0x62 )\
|
||||
CAUSE_DEF(Information_element_non_existent_or_not_implemented,0x63 )\
|
||||
CAUSE_DEF(Conditional_IE_error,0x64 )\
|
||||
CAUSE_DEF(Message_not_compatible_with_the_protocol_state,0x65 )\
|
||||
CAUSE_DEF(Protocol_error_unspecified,0x67 )
|
||||
|
||||
/* Map task id to printable name. */
|
||||
|
||||
#define CAUSE_TEXT(LabEl, nUmID) {nUmID, #LabEl},
|
||||
|
||||
static const text_info_t cause_text_info[] = {
|
||||
FOREACH_CAUSE(TO_TEXT)
|
||||
};
|
||||
|
||||
#define CAUSE_ENUM(LabEl, nUmID ) LabEl = nUmID,
|
||||
//! Tasks id of each task
|
||||
typedef enum {
|
||||
FOREACH_CAUSE(TO_ENUM)
|
||||
} cause_id_t;
|
||||
|
||||
//_table_9.11.4.2.1:_5GSM_cause_information_element
|
||||
#define FOREACH_CAUSE_SECU(CAUSE_SECU_DEF) \
|
||||
CAUSE_SECU_DEF(Security_Operator_determined_barring,0x08 )\
|
||||
CAUSE_SECU_DEF(Security_Insufficient_resources,0x1a )\
|
||||
CAUSE_SECU_DEF(Security_Missing_or_unknown_DNN,0x1b )\
|
||||
CAUSE_SECU_DEF(Security_Unknown_PDU_session_type,0x1c )\
|
||||
CAUSE_SECU_DEF(Security_User_authentication_or_authorization_failed,0x1d )\
|
||||
CAUSE_SECU_DEF(Security_Request_rejected_unspecified,0x1f )\
|
||||
CAUSE_SECU_DEF(Security_Service_option_not_supported,0x20 )\
|
||||
CAUSE_SECU_DEF(Security_Requested_service_option_not_subscribed,0x21 )\
|
||||
CAUSE_SECU_DEF(Security_Service_option_temporarily_out_of_order,0x22 )\
|
||||
CAUSE_SECU_DEF(Security_PTI_already_in_use,0x23 )\
|
||||
CAUSE_SECU_DEF(Security_Regular_deactivation,0x24 )\
|
||||
CAUSE_SECU_DEF(Security_Network_failure,0x26 )\
|
||||
CAUSE_SECU_DEF(Security_Reactivation_requested,0x27 )\
|
||||
CAUSE_SECU_DEF(Security_Semantic_error_in_the_TFT_operation,0x29 )\
|
||||
CAUSE_SECU_DEF(Security_Syntactical_error_in_the_TFT_operation,0x2a )\
|
||||
CAUSE_SECU_DEF(Security_Invalid_PDU_session_identity,0x2b )\
|
||||
CAUSE_SECU_DEF(Security_Semantic_errors_in_packet_filter,0x2c )\
|
||||
CAUSE_SECU_DEF(Security_Syntactical_error_in_packet_filter,0x2d )\
|
||||
CAUSE_SECU_DEF(Security_Out_of_LADN_service_area,0x2e )\
|
||||
CAUSE_SECU_DEF(Security_PTI_mismatch,0x2f )\
|
||||
CAUSE_SECU_DEF(Security_PDU_session_type_IPv4_only_allowed,0x32 )\
|
||||
CAUSE_SECU_DEF(Security_PDU_session_type_IPv6_only_allowed,0x33 )\
|
||||
CAUSE_SECU_DEF(Security_PDU_session_does_not_exist,0x36 )\
|
||||
CAUSE_SECU_DEF(Security_PDU_session_type_IPv4v6_only_allowed,0x39 )\
|
||||
CAUSE_SECU_DEF(Security_PDU_session_type_Unstructured_only_allowed,0x3a )\
|
||||
CAUSE_SECU_DEF(Security_PDU_session_type_Ethernet_only_allowed,0x3d )\
|
||||
CAUSE_SECU_DEF(Security_Insufficient_resources_for_specific_slice_and_DNN,0x43 )\
|
||||
CAUSE_SECU_DEF(Security_Not_supported_SSC_mode,0x44 )\
|
||||
CAUSE_SECU_DEF(Security_Insufficient_resources_for_specific_slice,0x45 )\
|
||||
CAUSE_SECU_DEF(Security_Missing_or_unknown_DNN_in_a_slice,0x46 )\
|
||||
CAUSE_SECU_DEF(Security_Invalid_PTI_value,0x51 )\
|
||||
CAUSE_SECU_DEF(Security_Maximum_data_rate_per_UE_for_user_plane_integrity_protection_is_too_low,0x52 )\
|
||||
CAUSE_SECU_DEF(Security_Semantic_error_in_the_QoS_operation,0x53 )\
|
||||
CAUSE_SECU_DEF(Security_Syntactical_error_in_the_QoS_operation,0x54 )\
|
||||
CAUSE_SECU_DEF(Security_Invalid_mapped_EPS_bearer_identity,0x55 )\
|
||||
CAUSE_SECU_DEF(Security_Semantically_incorrect_message,0x5f )\
|
||||
CAUSE_SECU_DEF(Security_Invalid_mandatory_information,0x60 )\
|
||||
CAUSE_SECU_DEF(Security_Message_type_non_existent_or_not_implemented,0x61 )\
|
||||
CAUSE_SECU_DEF(Security_Message_type_not_compatible_with_the_protocol_state,0x62 )\
|
||||
CAUSE_SECU_DEF(Security_Information_element_non_existent_or_not_implemented,0x63 )\
|
||||
CAUSE_SECU_DEF(Security_Conditional_IE_error,0x64 )\
|
||||
CAUSE_SECU_DEF(Security_Message_not_compatible_with_the_protocol_state,0x65 )\
|
||||
CAUSE_SECU_DEF(Security_Protocol_error_unspecified,0x6f )
|
||||
|
||||
static const text_info_t cause_secu_text_info[] = {
|
||||
FOREACH_CAUSE_SECU(TO_TEXT)
|
||||
};
|
||||
|
||||
//! Tasks id of each task
|
||||
typedef enum {
|
||||
FOREACH_CAUSE_SECU(TO_ENUM)
|
||||
} cause_secu_id_t;
|
||||
|
||||
// IEI (information element identifier) are spread in each message definition
|
||||
#define IEI_RAND 0x21
|
||||
#define IEI_AUTN 0x20
|
||||
#define IEI_EAP 0x78
|
||||
#define IEI_AuthenticationResponse 0x2d
|
||||
|
||||
//TS 24.501 sub layer states for UE
|
||||
// for network side, only 5GMMderegistered, 5GMMderegistered_initiated, 5GMMregistered, 5GMMservice_request_initiated are valid
|
||||
typedef enum {
|
||||
SGMMnull,
|
||||
SGMMderegistered,
|
||||
SGMMderegistered_initiated,
|
||||
SGMMregistered,
|
||||
SGMMregistered_initiated,
|
||||
SGMMservice_request_initiated,
|
||||
} SGMM_UE_states;
|
||||
|
||||
typedef struct {
|
||||
Extendedprotocoldiscriminator_t epd:8;
|
||||
Security_header_t sh:8;
|
||||
SGSmobilitymanagementmessages_t mt:8;
|
||||
} SGScommonHeader_t;
|
||||
|
||||
typedef struct {
|
||||
Extendedprotocoldiscriminator_t epd:8;
|
||||
Security_header_t sh:8;
|
||||
SGSmobilitymanagementmessages_t mt:8;
|
||||
identitytype_t it:8;
|
||||
} Identityrequest_t;
|
||||
|
||||
// the message continues with the identity value, depending on identity type, see TS 14.501, 9.11.3.4
|
||||
typedef struct __attribute__((packed)) {
|
||||
Extendedprotocoldiscriminator_t epd:8;
|
||||
Security_header_t sh:8;
|
||||
SGSmobilitymanagementmessages_t mt:8;
|
||||
uint16_t len;
|
||||
}
|
||||
Identityresponse_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
Identityresponse_t common;
|
||||
identitytype_t mi:8;
|
||||
unsigned int supiFormat:4;
|
||||
unsigned int identityType:4;
|
||||
unsigned int mcc1:4;
|
||||
unsigned int mcc2:4;
|
||||
unsigned int mcc3:4;
|
||||
unsigned int mnc3:4;
|
||||
unsigned int mnc1:4;
|
||||
unsigned int mnc2:4;
|
||||
unsigned int routing1:4;
|
||||
unsigned int routing2:4;
|
||||
unsigned int routing3:4;
|
||||
unsigned int routing4:4;
|
||||
unsigned int protectScheme:4;
|
||||
unsigned int spare:4;
|
||||
uint8_t hplmnId;
|
||||
}
|
||||
IdentityresponseIMSI_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
Extendedprotocoldiscriminator_t epd:8;
|
||||
Security_header_t sh:8;
|
||||
SGSmobilitymanagementmessages_t mt:8;
|
||||
unsigned int ngKSI:4;
|
||||
unsigned int spare:4;
|
||||
unsigned int ABBALen:8;
|
||||
unsigned int ABBA:16;
|
||||
uint8_t ieiRAND;
|
||||
uint8_t RAND[16];
|
||||
uint8_t ieiAUTN;
|
||||
uint8_t AUTNlen;
|
||||
uint8_t AUTN[16];
|
||||
}
|
||||
authenticationrequestHeader_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
Extendedprotocoldiscriminator_t epd:8;
|
||||
Security_header_t sh:8;
|
||||
SGSmobilitymanagementmessages_t mt:8;
|
||||
uint8_t iei;
|
||||
uint8_t RESlen;
|
||||
uint8_t RES[16];
|
||||
} authenticationresponse_t;
|
||||
|
||||
//AUTHENTICATION RESULT
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
Extendedprotocoldiscriminator_t epd:8;
|
||||
Security_header_t sh:8;
|
||||
SGSmobilitymanagementmessages_t mt:8;
|
||||
|
||||
unsigned int selectedNASsecurityalgorithms;
|
||||
unsigned int ngKSI:4; //ngKSI NAS key set identifier 9.11.3.32
|
||||
unsigned int spare:4;
|
||||
// LV 3-9 bytes Replayed UE security capabilities UE security capability 9.11.3.54
|
||||
|
||||
/* optional
|
||||
TV (E-, 1 byte) Oprional IMEISV request IMEISV request 9.11.3.28
|
||||
TV (57, 2 bytes ) Selected EPS NAS security algorithms EPS NAS security algorithms 9.11.3.25
|
||||
TLV (36, 3 bytes) Additional 5G security information Additional 5G security information 9.11.3.12
|
||||
TLV-E (78,, 7-1503 bytes) EAP message EAP message 9.11.2.2
|
||||
TLV (38, 4-n)ABBA ABBA 9.11.3.10
|
||||
TLV (19, 4-7) Replayed S1 UE security capabilities S1 UE security capability 9.11.3.48A
|
||||
*/
|
||||
|
||||
} securityModeCommand_t;
|
||||
|
||||
typedef struct {
|
||||
uicc_t *uicc;
|
||||
} nr_user_nas_t;
|
||||
|
||||
#define STATIC_ASSERT(test_for_true) _Static_assert((test_for_true), "(" #test_for_true ") failed")
|
||||
#define myCalloc(var, type) type * var=(type*)calloc(sizeof(type),1);
|
||||
#define arrayCpy(tO, FroM) STATIC_ASSERT(sizeof(tO) == sizeof(FroM)) ; memcpy(tO, FroM, sizeof(tO))
|
||||
int resToresStar(uint8_t *msg, uicc_t* uicc);
|
||||
|
||||
int identityResponse(void **msg, nr_user_nas_t *UE);
|
||||
int authenticationResponse(void **msg, nr_user_nas_t *UE);
|
||||
void UEprocessNAS(void *msg,nr_user_nas_t *UE);
|
||||
void SGSabortUE(void *msg, NRUEcontext_t *UE) ;
|
||||
void SGSregistrationReq(void *msg, NRUEcontext_t *UE);
|
||||
void SGSderegistrationUEReq(void *msg, NRUEcontext_t *UE);
|
||||
void SGSauthenticationResp(void *msg, NRUEcontext_t *UE);
|
||||
void SGSidentityResp(void *msg, NRUEcontext_t *UE);
|
||||
void SGSsecurityModeComplete(void *msg, NRUEcontext_t *UE);
|
||||
void SGSregistrationComplete(void *msg, NRUEcontext_t *UE);
|
||||
void processNAS(void *msg, NRUEcontext_t *UE);
|
||||
int identityRequest(void **msg, NRUEcontext_t *UE);
|
||||
int authenticationRequest(void **msg, NRUEcontext_t *UE);
|
||||
int securityModeCommand(void **msg, NRUEcontext_t *UE);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
Adaptatipn of SW from hereafter license
|
||||
Author: laurent.thomas@open-cells.com
|
||||
The OpenAirInterface project uses this copy under the terms of BSD
|
||||
license.
|
||||
*/
|
||||
/*
|
||||
3GPP AKA - Milenage algorithm (3GPP TS 35.205, .206, .207, .208)
|
||||
Copyright (c) 2006-2007 <j@w1.fi>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
Alternatively, this software may be distributed under the terms of BSD
|
||||
license.
|
||||
|
||||
See README and COPYING for more details.
|
||||
|
||||
This file implements an example authentication algorithm defined for 3GPP
|
||||
AKA. This can be used to implement a simple HLR/AuC into hlr_auc_gw to allow
|
||||
EAP-AKA to be tested properly with real USIM cards.
|
||||
|
||||
This implementations assumes that the r1..r5 and c1..c5 constants defined in
|
||||
TS 35.206 are used, i.e., r1=64, r2=0, r3=32, r4=64, r5=96, c1=00..00,
|
||||
c2=00..01, c3=00..02, c4=00..04, c5=00..08. The block cipher is assumed to
|
||||
be AES (Rijndael).
|
||||
*/
|
||||
|
||||
#ifndef MILENAGE_H
|
||||
#define MILENAGE_H
|
||||
#include <openssl/aes.h>
|
||||
|
||||
|
||||
#define u8 uint8_t
|
||||
/**
|
||||
milenage_f1 - Milenage f1 and f1* algorithms
|
||||
@opc: OPc = 128-bit value derived from OP and K
|
||||
@k: K = 128-bit subscriber key
|
||||
@_rand: RAND = 128-bit random challenge
|
||||
@sqn: SQN = 48-bit sequence number
|
||||
@amf: AMF = 16-bit authentication management field
|
||||
@mac_a: Buffer for MAC-A = 64-bit network authentication code, or %NULL
|
||||
@mac_s: Buffer for MAC-S = 64-bit resync authentication code, or %NULL
|
||||
Returns: true on success, false on failure
|
||||
*/
|
||||
|
||||
void aes_128_encrypt_block(const u8* key, const u8* in, u8* out) {
|
||||
AES_KEY k;
|
||||
u8 tmp[16];
|
||||
AES_set_encrypt_key(key, 128, &k);
|
||||
AES_encrypt(in, tmp, &k);
|
||||
memcpy(out, tmp, sizeof(tmp));
|
||||
}
|
||||
static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
|
||||
const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s) {
|
||||
u8 tmp1[16], tmp2[16], tmp3[16];
|
||||
int i;
|
||||
|
||||
/* tmp1 = TEMP = E_K(RAND XOR OP_C) */
|
||||
for (i = 0; i < 16; i++)
|
||||
tmp1[i] = _rand[i] ^ opc[i];
|
||||
|
||||
aes_128_encrypt_block(k, tmp1, tmp1);
|
||||
AES_KEY kTab;
|
||||
uint8_t cyphered[16];
|
||||
AES_set_encrypt_key(k, 128, &kTab);
|
||||
AES_encrypt(tmp1, cyphered, &kTab);
|
||||
/* tmp2 = IN1 = SQN || AMF || SQN || AMF */
|
||||
memcpy(tmp2, sqn, 6);
|
||||
memcpy(tmp2 + 6, amf, 2);
|
||||
memcpy(tmp2 + 8, tmp2, 8);
|
||||
|
||||
/* OUT1 = E_K(TEMP XOR rot(IN1 XOR OP_C, r1) XOR c1) XOR OP_C */
|
||||
|
||||
/* rotate (tmp2 XOR OP_C) by r1 (= 0x40 = 8 bytes) */
|
||||
for (i = 0; i < 16; i++)
|
||||
tmp3[(i + 8) % 16] = tmp2[i] ^ opc[i];
|
||||
|
||||
/* XOR with TEMP = E_K(RAND XOR OP_C) */
|
||||
for (i = 0; i < 16; i++)
|
||||
tmp3[i] ^= tmp1[i];
|
||||
|
||||
/* XOR with c1 (= ..00, i.e., NOP) */
|
||||
/* f1 || f1* = E_K(tmp3) XOR OP_c */
|
||||
aes_128_encrypt_block(k, tmp3, tmp1);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
tmp1[i] ^= opc[i];
|
||||
|
||||
if (mac_a)
|
||||
memcpy(mac_a, tmp1, 8); /* f1 */
|
||||
|
||||
if (mac_s)
|
||||
memcpy(mac_s, tmp1 + 8, 8); /* f1* */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
milenage_f2345 - Milenage f2, f3, f4, f5, f5* algorithms
|
||||
@opc: OPc = 128-bit value derived from OP and K
|
||||
@k: K = 128-bit subscriber key
|
||||
@_rand: RAND = 128-bit random challenge
|
||||
@res: Buffer for RES = 64-bit signed response (f2), or %NULL
|
||||
@ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
|
||||
@ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
|
||||
@ak: Buffer for AK = 48-bit anonymity key (f5), or %NULL
|
||||
@akstar: Buffer for AK = 48-bit anonymity key (f5*), or %NULL
|
||||
Returns: true on success, false on failure
|
||||
*/
|
||||
static bool milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand,
|
||||
u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar) {
|
||||
u8 tmp1[16], tmp2[16], tmp3[16];
|
||||
int i;
|
||||
|
||||
/* tmp2 = TEMP = E_K(RAND XOR OP_C) */
|
||||
for (i = 0; i < 16; i++)
|
||||
tmp1[i] = _rand[i] ^ opc[i];
|
||||
|
||||
aes_128_encrypt_block(k, tmp1, tmp2);
|
||||
|
||||
/* OUT2 = E_K(rot(TEMP XOR OP_C, r2) XOR c2) XOR OP_C */
|
||||
/* OUT3 = E_K(rot(TEMP XOR OP_C, r3) XOR c3) XOR OP_C */
|
||||
/* OUT4 = E_K(rot(TEMP XOR OP_C, r4) XOR c4) XOR OP_C */
|
||||
/* OUT5 = E_K(rot(TEMP XOR OP_C, r5) XOR c5) XOR OP_C */
|
||||
|
||||
/* f2 and f5 */
|
||||
/* rotate by r2 (= 0, i.e., NOP) */
|
||||
for (i = 0; i < 16; i++)
|
||||
tmp1[i] = tmp2[i] ^ opc[i];
|
||||
|
||||
tmp1[15] ^= 1; /* XOR c2 (= ..01) */
|
||||
/* f5 || f2 = E_K(tmp1) XOR OP_c */
|
||||
aes_128_encrypt_block(k, tmp1, tmp3);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
tmp3[i] ^= opc[i];
|
||||
|
||||
if (res)
|
||||
memcpy(res, tmp3 + 8, 8); /* f2 */
|
||||
|
||||
if (ak)
|
||||
memcpy(ak, tmp3, 6); /* f5 */
|
||||
|
||||
/* f3 */
|
||||
if (ck) {
|
||||
/* rotate by r3 = 0x20 = 4 bytes */
|
||||
for (i = 0; i < 16; i++)
|
||||
tmp1[(i + 12) % 16] = tmp2[i] ^ opc[i];
|
||||
|
||||
tmp1[15] ^= 2; /* XOR c3 (= ..02) */
|
||||
aes_128_encrypt_block(k, tmp1, ck);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
ck[i] ^= opc[i];
|
||||
}
|
||||
|
||||
/* f4 */
|
||||
if (ik) {
|
||||
/* rotate by r4 = 0x40 = 8 bytes */
|
||||
for (i = 0; i < 16; i++)
|
||||
tmp1[(i + 8) % 16] = tmp2[i] ^ opc[i];
|
||||
|
||||
tmp1[15] ^= 4; /* XOR c4 (= ..04) */
|
||||
aes_128_encrypt_block(k, tmp1, ik);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
ik[i] ^= opc[i];
|
||||
}
|
||||
|
||||
/* f5* */
|
||||
if (akstar) {
|
||||
/* rotate by r5 = 0x60 = 12 bytes */
|
||||
for (i = 0; i < 16; i++)
|
||||
tmp1[(i + 4) % 16] = tmp2[i] ^ opc[i];
|
||||
|
||||
tmp1[15] ^= 8; /* XOR c5 (= ..08) */
|
||||
aes_128_encrypt_block(k, tmp1, tmp1);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
akstar[i] = tmp1[i] ^ opc[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
milenage_generate - Generate AKA AUTN,IK,CK,RES
|
||||
@opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
|
||||
@amf: AMF = 16-bit authentication management field
|
||||
@k: K = 128-bit subscriber key
|
||||
@sqn: SQN = 48-bit sequence number
|
||||
@_rand: RAND = 128-bit random challenge
|
||||
@autn: Buffer for AUTN = 128-bit authentication token
|
||||
@ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
|
||||
@ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
|
||||
@res: Buffer for RES = 64-bit signed response (f2), or %NULL
|
||||
@res_len: Max length for res; set to used length or 0 on failure
|
||||
*/
|
||||
static bool milenage_generate(const u8 *opc, const u8 *amf, const u8 *k,
|
||||
const u8 *sqn, const u8 *_rand, u8 *autn, u8 *ik,
|
||||
u8 *ck, u8 *res) {
|
||||
int i;
|
||||
u8 mac_a[8], ak[6];
|
||||
|
||||
if (!milenage_f1(opc, k, _rand, sqn, amf, mac_a, NULL) ||
|
||||
!milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL))
|
||||
return false;
|
||||
|
||||
/* AUTN = (SQN ^ AK) || AMF || MAC */
|
||||
for (i = 0; i < 6; i++)
|
||||
autn[i] = sqn[i] ^ ak[i];
|
||||
|
||||
memcpy(autn + 6, amf, 2);
|
||||
memcpy(autn + 8, mac_a, 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
milenage_auts - Milenage AUTS validation
|
||||
@opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
|
||||
@k: K = 128-bit subscriber key
|
||||
@_rand: RAND = 128-bit random challenge
|
||||
@auts: AUTS = 112-bit authentication token from client
|
||||
@sqn: Buffer for SQN = 48-bit sequence number
|
||||
Returns: 0 = success (sqn filled), -1 on failure
|
||||
*/
|
||||
#define p(a) printf("%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", (int)((a)[0]), (int)((a)[1]), (int)((a)[2]), (int)((a)[3]),(int)((a)[4]), (int)((a)[5]));
|
||||
// valid code but put in comment as it is not used right now
|
||||
#if 0
|
||||
static bool milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 *auts,
|
||||
u8 *sqn) {
|
||||
u8 amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */
|
||||
u8 ak[6], mac_s[8];
|
||||
int i;
|
||||
|
||||
if (!milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak))
|
||||
return false;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
sqn[i] = auts[i] ^ ak[i];
|
||||
|
||||
//p(sqn);
|
||||
if (!milenage_f1(opc, k, _rand, sqn, amf, NULL, mac_s) ||
|
||||
memcmp(mac_s, auts + 6, 8) != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
gsm_milenage - Generate GSM-Milenage (3GPP TS 55.205) authentication triplet
|
||||
@opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
|
||||
@k: K = 128-bit subscriber key
|
||||
@_rand: RAND = 128-bit random challenge
|
||||
@sres: Buffer for SRES = 32-bit SRES
|
||||
@kc: Buffer for Kc = 64-bit Kc
|
||||
Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
static bool gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres, u8 *kc) {
|
||||
u8 res[8], ck[16], ik[16];
|
||||
int i;
|
||||
|
||||
if (milenage_f2345(opc, k, _rand, res, ck, ik, NULL, NULL))
|
||||
return false;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
kc[i] = ck[i] ^ ck[i + 8] ^ ik[i] ^ ik[i + 8];
|
||||
|
||||
#ifdef GSM_MILENAGE_ALT_SRES
|
||||
memcpy(sres, res, 4);
|
||||
#else /* GSM_MILENAGE_ALT_SRES */
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
sres[i] = res[i] ^ res[i + 4];
|
||||
|
||||
#endif /* GSM_MILENAGE_ALT_SRES */
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
milenage_generate - Generate AKA AUTN,IK,CK,RES
|
||||
@opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
|
||||
@k: K = 128-bit subscriber key
|
||||
@sqn: SQN = 48-bit sequence number
|
||||
@_rand: RAND = 128-bit random challenge
|
||||
@autn: AUTN = 128-bit authentication token
|
||||
@ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
|
||||
@ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
|
||||
@res: Buffer for RES = 64-bit signed response (f2), or %NULL
|
||||
@res_len: Variable that will be set to RES length
|
||||
@auts: 112-bit buffer for AUTS
|
||||
Returns: 0 on success, -1 on failure, or -2 on synchronization failure
|
||||
*/
|
||||
static int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand,
|
||||
const u8 *autn, u8 *ik, u8 *ck, u8 *res, size_t *res_len,
|
||||
u8 *auts) {
|
||||
int i;
|
||||
u8 mac_a[8], ak[6], rx_sqn[6];
|
||||
const u8 *amf;
|
||||
|
||||
if (milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL))
|
||||
return -1;
|
||||
|
||||
*res_len = 8;
|
||||
|
||||
/* AUTN = (SQN ^ AK) || AMF || MAC */
|
||||
for (i = 0; i < 6; i++)
|
||||
rx_sqn[i] = autn[i] ^ ak[i];
|
||||
|
||||
if (memcmp(rx_sqn, sqn, 6) <= 0) {
|
||||
u8 auts_amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */
|
||||
|
||||
if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak))
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
auts[i] = sqn[i] ^ ak[i];
|
||||
|
||||
if (milenage_f1(opc, k, _rand, sqn, auts_amf, NULL, auts + 6))
|
||||
return -1;
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
||||
amf = autn + 6;
|
||||
|
||||
if (milenage_f1(opc, k, _rand, rx_sqn, amf, mac_a, NULL))
|
||||
return -1;
|
||||
|
||||
if (memcmp(mac_a, autn + 8, 8) != 0) {
|
||||
printf( "Milenage: MAC mismatch\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void milenage_opc_gen(const u8 *k, const u8 *op, u8 *opc) {
|
||||
int i;
|
||||
/* Encrypt OP using K */
|
||||
aes_128_encrypt_block(k, op, opc);
|
||||
|
||||
/* XOR the resulting Ek(OP) with OP */
|
||||
for (i = 0; i < 16; i++)
|
||||
opc[i] = opc[i] ^ op[i];
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -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
|
||||
*
|
||||
* 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.
|
||||
* 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 <openair3/NAS/COMMON/NR_NAS_defs.h>
|
||||
#include <openair3/SECU/secu_defs.h>
|
||||
|
||||
void servingNetworkName(uint8_t *msg, char * imsiStr, int nmc_size) {
|
||||
//SNN-network-identifier in TS 24.501
|
||||
// TS 24.501: If the MNC of the serving PLMN has two digits, then a zero is added at the beginning.
|
||||
const char *format="5G:mnc000.mcc000.3gppnetwork.org";
|
||||
memcpy(msg,format, strlen(format));
|
||||
|
||||
if (nmc_size == 2)
|
||||
memcpy(msg+7, imsiStr+3, 2);
|
||||
else
|
||||
memcpy(msg+6, imsiStr+3, 3);
|
||||
|
||||
memcpy(msg+13, imsiStr, 3);
|
||||
}
|
||||
|
||||
int resToresStar(uint8_t *msg, uicc_t* uicc) {
|
||||
// TS 33.220 annex B.2 => FC=0x6B in TS 33.501 annex A.4
|
||||
//input S to KDF
|
||||
uint8_t S[128]= {0};
|
||||
S[0]=0x6B;
|
||||
uint8_t *ptr=S+1;
|
||||
servingNetworkName(ptr, uicc->imsiStr, uicc->nmc_size);
|
||||
*(uint16_t *)(ptr+strlen((char *)ptr))=htons(strlen((char *)ptr));
|
||||
ptr+=strlen((char *)ptr)+sizeof(uint16_t);
|
||||
// add rand
|
||||
memcpy(ptr, uicc->rand, sizeof(uicc->rand) ) ;
|
||||
*(uint16_t *)(ptr+sizeof(uicc->rand))=htons(sizeof(uicc->rand));
|
||||
ptr+=sizeof(uicc->rand)+sizeof(uint16_t);
|
||||
// add res
|
||||
memcpy(ptr, uicc->milenage_res, sizeof(uicc->milenage_res) ) ;
|
||||
*(uint16_t *)(ptr+sizeof(uicc->milenage_res))=htons(sizeof(uicc->milenage_res));
|
||||
ptr+=sizeof(uicc->milenage_res)+sizeof(uint16_t);
|
||||
// S is done
|
||||
uint8_t ckik[sizeof(uicc->ck) +sizeof(uicc->ik)];
|
||||
memcpy(ckik, uicc->ck, sizeof(uicc->ck));
|
||||
memcpy(ckik+sizeof(uicc->ck),uicc->ik, sizeof(uicc->ik));
|
||||
uint8_t out[32];
|
||||
kdf(S, ptr-S, ckik, 32, out, sizeof(out));
|
||||
memcpy(msg, out+16, 16);
|
||||
return 16;
|
||||
}
|
||||
@@ -0,0 +1,692 @@
|
||||
/*
|
||||
* 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 nr_nas_msg_sim.c
|
||||
* \brief simulator for nr nas message
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h> // memset
|
||||
#include <stdlib.h> // malloc, free
|
||||
|
||||
#include "nas_log.h"
|
||||
#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) {
|
||||
int size = 0;
|
||||
|
||||
/* Check the buffer length */
|
||||
if (len < sizeof(mm_msg_header_t)) {
|
||||
return (TLV_ENCODE_BUFFER_TOO_SHORT);
|
||||
}
|
||||
|
||||
/* Check the protocol discriminator */
|
||||
if (header->ex_protocol_discriminator != FGS_MOBILITY_MANAGEMENT_MESSAGE) {
|
||||
LOG_TRACE(ERROR, "ESM-MSG - Unexpected extened protocol discriminator: 0x%x",
|
||||
header->ex_protocol_discriminator);
|
||||
return (TLV_ENCODE_PROTOCOL_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
/* Encode the extendedprotocol discriminator */
|
||||
ENCODE_U8(buffer + size, header->ex_protocol_discriminator, size);
|
||||
/* Encode the security header type */
|
||||
ENCODE_U8(buffer + size, (header->security_header_type & 0xf), size);
|
||||
/* Encode the message type */
|
||||
ENCODE_U8(buffer + size, header->message_type, size);
|
||||
return (size);
|
||||
}
|
||||
|
||||
|
||||
int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) {
|
||||
LOG_FUNC_IN;
|
||||
int header_result;
|
||||
int encode_result;
|
||||
uint8_t msg_type = mm_msg->header.message_type;
|
||||
|
||||
|
||||
/* First encode the EMM message header */
|
||||
header_result = _nas_mm_msg_encode_header(&mm_msg->header, buffer, len);
|
||||
|
||||
if (header_result < 0) {
|
||||
LOG_TRACE(ERROR, "EMM-MSG - Failed to encode EMM message header "
|
||||
"(%d)", header_result);
|
||||
LOG_FUNC_RETURN(header_result);
|
||||
}
|
||||
|
||||
buffer += header_result;
|
||||
len -= header_result;
|
||||
|
||||
switch(msg_type) {
|
||||
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);
|
||||
encode_result = TLV_ENCODE_WRONG_MESSAGE_TYPE;
|
||||
break;
|
||||
/* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */
|
||||
}
|
||||
|
||||
if (encode_result < 0) {
|
||||
LOG_TRACE(ERROR, "EMM-MSG - Failed to encode L3 EMM message 0x%x "
|
||||
"(%d)", mm_msg->header.message_type, encode_result);
|
||||
}
|
||||
|
||||
if (encode_result < 0)
|
||||
LOG_FUNC_RETURN (encode_result);
|
||||
|
||||
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);
|
||||
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 = REGISTRATION_REQUEST;
|
||||
|
||||
|
||||
// set registration request
|
||||
mm_msg->registration_request.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
|
||||
size += 1;
|
||||
mm_msg->registration_request.securityheadertype = PLAIN_5GS_MSG;
|
||||
size += 1;
|
||||
mm_msg->registration_request.messagetype = REGISTRATION_REQUEST;
|
||||
size += 1;
|
||||
mm_msg->registration_request.fgsregistrationtype = INITIAL_REGISTRATION;
|
||||
mm_msg->registration_request.naskeysetidentifier.naskeysetidentifier = 1;
|
||||
size += 1;
|
||||
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;
|
||||
|
||||
} 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;
|
||||
mm_msg->registration_request.fgmmcapability.length = 1;
|
||||
mm_msg->registration_request.fgmmcapability.value = 0x7;
|
||||
size += 3;
|
||||
|
||||
mm_msg->registration_request.presencemask |= REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_PRESENT;
|
||||
mm_msg->registration_request.nruesecuritycapability.iei = REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_IEI;
|
||||
mm_msg->registration_request.nruesecuritycapability.length = 8;
|
||||
mm_msg->registration_request.nruesecuritycapability.fg_EA = 0x80;
|
||||
mm_msg->registration_request.nruesecuritycapability.fg_IA = 0x20;
|
||||
mm_msg->registration_request.nruesecuritycapability.EEA = 0;
|
||||
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];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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 nr_nas_msg_sim.h
|
||||
* \brief simulator for nr nas message
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __NR_NAS_MSG_SIM_H__
|
||||
#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
|
||||
|
||||
|
||||
typedef enum fgs_protocol_discriminator_e {
|
||||
/* Protocol discriminator identifier for 5GS Mobility Management */
|
||||
FGS_MOBILITY_MANAGEMENT_MESSAGE = 0x7E,
|
||||
|
||||
/* Protocol discriminator identifier for 5GS Session Management */
|
||||
FGS_SESSION_MANAGEMENT_MESSAGE = 0x2E,
|
||||
} fgs_protocol_discriminator_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t ex_protocol_discriminator;
|
||||
uint8_t security_header_type;
|
||||
uint8_t message_type;
|
||||
} mm_msg_header_t;
|
||||
|
||||
/* Structure of security protected header */
|
||||
typedef struct {
|
||||
fgs_protocol_discriminator_t protocol_discriminator;
|
||||
uint8_t security_header_type;
|
||||
uint32_t message_authentication_code;
|
||||
uint8_t sequence_number;
|
||||
} fgs_nas_message_security_header_t;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
MM_msg mm_msg; /* 5GS Mobility Management messages */
|
||||
} fgs_nas_message_plain_t;
|
||||
|
||||
typedef struct {
|
||||
fgs_nas_message_security_header_t header;
|
||||
fgs_nas_message_plain_t plain;
|
||||
} fgs_nas_message_security_protected_t;
|
||||
|
||||
|
||||
typedef union {
|
||||
fgs_nas_message_security_header_t header;
|
||||
fgs_nas_message_security_protected_t security_protected;
|
||||
fgs_nas_message_plain_t plain;
|
||||
} 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__*/
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
* 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 <openair3/NAS/COMMON/NR_NAS_defs.h>
|
||||
#include <openair3/SECU/secu_defs.h>
|
||||
|
||||
|
||||
void SGSabortNet(void *msg, nr_user_nas_t *UE) {
|
||||
}
|
||||
|
||||
void ue_nas_schedule(void) {
|
||||
}
|
||||
|
||||
/*
|
||||
*Message reception
|
||||
*/
|
||||
|
||||
void SGSauthenticationReq(void *msg, nr_user_nas_t *UE) {
|
||||
authenticationrequestHeader_t *amsg=(authenticationrequestHeader_t *) msg;
|
||||
arrayCpy(UE->uicc->rand,amsg->RAND);
|
||||
arrayCpy(UE->uicc->autn,amsg->AUTN);
|
||||
// AUTHENTICATION REQUEST message that contains a valid ngKSI, SQN and MAC is received
|
||||
// TBD verify ngKSI (we set it as '2', see gNB code)
|
||||
// SQN and MAC are tested in auth resp processing
|
||||
ue_nas_schedule();
|
||||
}
|
||||
|
||||
void SGSidentityReq(void *msg, nr_user_nas_t *UE) {
|
||||
Identityrequest_t *idmsg=(Identityrequest_t *) msg;
|
||||
|
||||
if (idmsg->it == SUCI ) {
|
||||
LOG_I(NAS,"Received Identity request, scheduling answer\n");
|
||||
ue_nas_schedule();
|
||||
} else
|
||||
LOG_E(NAS,"Not developped: identity request for %d\n", idmsg->it);
|
||||
}
|
||||
|
||||
void SGSsecurityModeCommand(void *msg, nr_user_nas_t *UE) {
|
||||
}
|
||||
|
||||
|
||||
void UEprocessNAS(void *msg,nr_user_nas_t *UE) {
|
||||
SGScommonHeader_t *header=(SGScommonHeader_t *) msg;
|
||||
|
||||
if ( header->sh > 4 )
|
||||
SGSabortNet(msg, UE);
|
||||
else {
|
||||
switch (header->epd) {
|
||||
case SGSmobilitymanagementmessages:
|
||||
LOG_I(NAS,"Received message: %s\n", idStr(message_text_info, header->mt));
|
||||
|
||||
switch (header->mt) {
|
||||
case Authenticationrequest:
|
||||
SGSauthenticationReq(msg, UE);
|
||||
break;
|
||||
|
||||
case Identityrequest:
|
||||
SGSidentityReq(msg, UE);
|
||||
break;
|
||||
|
||||
case Securitymodecommand:
|
||||
SGSsecurityModeCommand(msg, UE);
|
||||
break;
|
||||
|
||||
default:
|
||||
SGSabortNet(msg, UE);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SGSsessionmanagementmessages:
|
||||
SGSabortNet(msg, UE);
|
||||
break;
|
||||
|
||||
default:
|
||||
SGSabortNet(msg, UE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Messages emission
|
||||
*/
|
||||
|
||||
int identityResponse(void **msg, nr_user_nas_t *UE) {
|
||||
if (UE->uicc == NULL)
|
||||
// config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE
|
||||
UE->uicc=init_uicc("uicc");
|
||||
|
||||
// TS 24.501 9.11.3.4
|
||||
int imsiL=strlen(UE->uicc->imsiStr);
|
||||
int msinL=imsiL-3-UE->uicc->nmc_size;
|
||||
int respSize=sizeof(IdentityresponseIMSI_t) + (msinL+1)/2;
|
||||
IdentityresponseIMSI_t *resp=(IdentityresponseIMSI_t *) calloc(respSize,1);
|
||||
resp->common.epd=SGSmobilitymanagementmessages;
|
||||
resp->common.sh=0;
|
||||
resp->common.mt=Identityresponse;
|
||||
resp->common.len=htons(respSize-sizeof(Identityresponse_t));
|
||||
resp->mi=SUCI;
|
||||
resp->mcc1=UE->uicc->imsiStr[0]-'0';
|
||||
resp->mcc2=UE->uicc->imsiStr[1]-'0';
|
||||
resp->mcc3=UE->uicc->imsiStr[2]-'0';
|
||||
resp->mnc1=UE->uicc->imsiStr[3]-'0';
|
||||
resp->mnc2=UE->uicc->imsiStr[4]-'0';
|
||||
resp->mnc3=UE->uicc->nmc_size==2? 0xF : UE->uicc->imsiStr[3]-'0';
|
||||
// TBD: routing to fill (FF ?)
|
||||
char *out=(char *)(resp+1);
|
||||
char *ptr=UE->uicc->imsiStr + 3 + UE->uicc->nmc_size;
|
||||
|
||||
while ( ptr < UE->uicc->imsiStr+strlen(UE->uicc->imsiStr) ) {
|
||||
*out=((*(ptr+1)-'0')<<4) | (*(ptr) -'0');
|
||||
out++;
|
||||
ptr+=2;
|
||||
}
|
||||
|
||||
if (msinL%2 == 1)
|
||||
*out=((*(ptr-1)-'0')) | 0xF0;
|
||||
|
||||
*msg=resp;
|
||||
return respSize;
|
||||
}
|
||||
|
||||
int authenticationResponse(void **msg,nr_user_nas_t *UE) {
|
||||
if (UE->uicc == NULL)
|
||||
// config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE
|
||||
UE->uicc=init_uicc("uicc");
|
||||
|
||||
myCalloc(resp, authenticationresponse_t);
|
||||
resp->epd=SGSmobilitymanagementmessages;
|
||||
resp->sh=0;
|
||||
resp->mt=Authenticationresponse;
|
||||
resp->iei=IEI_AuthenticationResponse;
|
||||
resp->RESlen=sizeof(resp->RES); // always 16 see TS 24.501 Table 8.2.2.1.1
|
||||
// Verify the AUTN
|
||||
// a full implementation need to test several SQN
|
||||
// as the last 5bits can be any value
|
||||
// and the value can also be greater and accepted (if it is in the accepted window)
|
||||
uint8_t AUTN[16];
|
||||
uicc_milenage_generate(AUTN, UE->uicc);
|
||||
|
||||
if ( memcmp(UE->uicc->autn, AUTN, sizeof(AUTN)) == 0 ) {
|
||||
// prepare and send good answer
|
||||
resToresStar(resp->RES,UE->uicc);
|
||||
} else {
|
||||
// prepare and send autn is not compatible with our data
|
||||
abort();
|
||||
}
|
||||
|
||||
*msg=resp;
|
||||
return sizeof(authenticationresponse_t);
|
||||
}
|
||||
|
||||
int securityModeComplete(void **msg, nr_user_nas_t *UE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int registrationComplete(void **msg, nr_user_nas_t *UE) {
|
||||
return -1;
|
||||
}
|
||||
@@ -262,7 +262,7 @@ void display_usim_data(const char *filename) {
|
||||
kasme[USIM_K_ASME_SIZE] = '\0';
|
||||
memcpy(kasme, data.securityctx.Kasme.value, USIM_K_ASME_SIZE);
|
||||
printf("\tKasme\t: \"%s\"\n", kasme);
|
||||
#if 0
|
||||
#if 0 //This doesn't compile anymore due to compiler warnings about pointers
|
||||
printf("\tulNAScount\t: 0x%.8x\n",
|
||||
*(uint32_t*) data.securityctx.ulNAScount.value);
|
||||
printf("\tdlNAScount\t: 0x%.8x\n",
|
||||
|
||||
@@ -55,10 +55,6 @@ Description Defines functions used to handle EPS bearer contexts.
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#ifdef UESIM_EXPANSION
|
||||
#include "openairinterface5g_limits.h"
|
||||
extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX];
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/**************** E X T E R N A L D E F I N I T I O N S ****************/
|
||||
@@ -200,7 +196,7 @@ int esm_ebr_context_create(
|
||||
char *tmp = NULL;
|
||||
char ipv4_addr[INET_ADDRSTRLEN];
|
||||
//char ipv6_addr[INET6_ADDRSTRLEN];
|
||||
char *netmask = NULL;
|
||||
int netmask = 32;
|
||||
char broadcast[INET_ADDRSTRLEN];
|
||||
struct in_addr in_addr;
|
||||
char command_line[500];
|
||||
@@ -227,7 +223,7 @@ int esm_ebr_context_create(
|
||||
strcpy(ipv4_addr, tmp);
|
||||
|
||||
if (IN_CLASSA(ntohl(in_addr.s_addr))) {
|
||||
netmask = "255.0.0.0";
|
||||
netmask = 8;
|
||||
in_addr.s_addr = pdn->ip_addr[0] << 24 |
|
||||
((255 << 16) & 0x00FF0000) |
|
||||
((255 << 8) & 0x0000FF00) |
|
||||
@@ -239,7 +235,7 @@ int esm_ebr_context_create(
|
||||
// in_addr.s_addr);
|
||||
strcpy(broadcast, tmp);
|
||||
} else if (IN_CLASSB(ntohl(in_addr.s_addr))) {
|
||||
netmask = "255.255.0.0";
|
||||
netmask = 16;
|
||||
in_addr.s_addr = pdn->ip_addr[0] << 24 |
|
||||
((pdn->ip_addr[1] << 16) & 0x00FF0000) |
|
||||
((255 << 8) & 0x0000FF00) |
|
||||
@@ -251,7 +247,7 @@ int esm_ebr_context_create(
|
||||
// in_addr.s_addr);
|
||||
strcpy(broadcast, tmp);
|
||||
} else if (IN_CLASSC(ntohl(in_addr.s_addr))) {
|
||||
netmask = "255.255.255.0";
|
||||
netmask = 24;
|
||||
in_addr.s_addr = pdn->ip_addr[0] << 24 |
|
||||
((pdn->ip_addr[1] << 16) & 0x00FF0000) |
|
||||
((pdn->ip_addr[2] << 8) & 0x0000FF00) |
|
||||
@@ -263,56 +259,23 @@ int esm_ebr_context_create(
|
||||
// in_addr.s_addr);
|
||||
strcpy(broadcast, tmp);
|
||||
} else {
|
||||
netmask = "255.255.255.255";
|
||||
netmask = 32;
|
||||
strcpy(broadcast, ipv4_addr);
|
||||
}
|
||||
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) {
|
||||
// this is for L2 FAPI simulator.
|
||||
// change for multiple UE's like 256UEs.
|
||||
// if it's made too many tables , OS may crush so we use one table.
|
||||
if(PDCP_USE_NETLINK) {
|
||||
#ifdef UESIM_EXPANSION
|
||||
uint16_t inst_nic = (pdn->ip_addr[3] & 0x000000FF) - 2;
|
||||
res = sprintf(command_line,
|
||||
"ifconfig %s%d %s netmask %s broadcast %s up && "
|
||||
"ip rule add from %s/24 table %d && "
|
||||
"ip rule add to %s/24 table %d && "
|
||||
"ip route add default dev %s%d table %d",
|
||||
UE_NAS_USE_TUN?"oaitun_ue":"oip",
|
||||
inst_nic + 1, ipv4_addr, netmask, broadcast,
|
||||
ipv4_addr, 201,
|
||||
ipv4_addr, 201,
|
||||
UE_NAS_USE_TUN?"oaitun_ue":"oip",
|
||||
inst_nic + 1, 201);
|
||||
inst_pdcp_list[inst_nic] = ueid;
|
||||
#else
|
||||
res = sprintf(command_line,
|
||||
"ifconfig %s%d %s netmask %s broadcast %s up && "
|
||||
"ip rule add from %s/32 table %d && "
|
||||
"ip rule add to %s/32 table %d && "
|
||||
"ip route add default dev %s%d table %d",
|
||||
UE_NAS_USE_TUN?"oaitun_ue":"oip",
|
||||
ueid + 1, ipv4_addr, netmask, broadcast,
|
||||
ipv4_addr, ueid + 201,
|
||||
ipv4_addr, ueid + 201,
|
||||
UE_NAS_USE_TUN?"oaitun_ue":"oip",
|
||||
ueid + 1, ueid + 201);
|
||||
#endif
|
||||
} // PDCP_USE_NETLINK
|
||||
} else {
|
||||
res = sprintf(command_line,
|
||||
"ifconfig %s%d %s netmask %s broadcast %s up && "
|
||||
"ip rule add from %s/32 table %d && "
|
||||
"ip rule add to %s/32 table %d && "
|
||||
"ip route add default dev %s%d table %d",
|
||||
UE_NAS_USE_TUN?"oaitun_ue":"oip",
|
||||
ueid + 1, ipv4_addr, netmask, broadcast,
|
||||
ipv4_addr, ueid + 201,
|
||||
ipv4_addr, ueid + 201,
|
||||
UE_NAS_USE_TUN?"oaitun_ue":"oip",
|
||||
ueid + 1, ueid + 201);
|
||||
}
|
||||
res = sprintf(command_line,
|
||||
"ip address add %s/%d broadcast %s dev %s%d && "
|
||||
"ip link set %s%d up && "
|
||||
"ip rule add from %s/32 table %d && "
|
||||
"ip rule add to %s/32 table %d && "
|
||||
"ip route add default dev %s%d table %d",
|
||||
ipv4_addr, netmask, broadcast,
|
||||
UE_NAS_USE_TUN ? "oaitun_ue" : "oip", ueid + 1,
|
||||
UE_NAS_USE_TUN ? "oaitun_ue" : "oip", ueid + 1,
|
||||
ipv4_addr, ueid + 10000,
|
||||
ipv4_addr, ueid + 10000,
|
||||
UE_NAS_USE_TUN ? "oaitun_ue" : "oip",
|
||||
ueid + 1, ueid + 10000);
|
||||
|
||||
if ( res<0 ) {
|
||||
LOG_TRACE(WARNING, "ESM-PROC - Failed to system command string");
|
||||
|
||||
@@ -102,7 +102,7 @@ extern unsigned char NB_eNB_INST;
|
||||
|
||||
int nas_itti_kenb_refresh_req(const Byte_t kenb[32], int user_id) {
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_KENB_REFRESH_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_NAS_UE, 0, NAS_KENB_REFRESH_REQ);
|
||||
memcpy(NAS_KENB_REFRESH_REQ(message_p).kenb, kenb, sizeof(NAS_KENB_REFRESH_REQ(message_p).kenb));
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_NAS_UE,
|
||||
@@ -130,7 +130,7 @@ int nas_itti_kenb_refresh_req(const Byte_t kenb[32], int user_id) {
|
||||
|
||||
int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat, int user_id) {
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_CELL_SELECTION_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_NAS_UE, 0, NAS_CELL_SELECTION_REQ);
|
||||
NAS_CELL_SELECTION_REQ(message_p).plmnID = plmnID;
|
||||
NAS_CELL_SELECTION_REQ(message_p).rat = rat;
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
@@ -145,7 +145,7 @@ int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat, int user_id) {
|
||||
|
||||
int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data, uint32_t length, int user_id) {
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_CONN_ESTABLI_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_NAS_UE, 0, NAS_CONN_ESTABLI_REQ);
|
||||
NAS_CONN_ESTABLI_REQ(message_p).cause = cause;
|
||||
NAS_CONN_ESTABLI_REQ(message_p).type = type;
|
||||
NAS_CONN_ESTABLI_REQ(message_p).s_tmsi = s_tmsi;
|
||||
@@ -165,7 +165,7 @@ int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t
|
||||
|
||||
int nas_itti_ul_data_req(const uint32_t ue_id, void *const data, const uint32_t length, int user_id) {
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_UPLINK_DATA_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_NAS_UE, 0, NAS_UPLINK_DATA_REQ);
|
||||
NAS_UPLINK_DATA_REQ(message_p).UEid = ue_id;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = data;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = length;
|
||||
@@ -174,7 +174,7 @@ int nas_itti_ul_data_req(const uint32_t ue_id, void *const data, const uint32_t
|
||||
|
||||
int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, const nas_error_code_t errCode, int user_id) {
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_RAB_ESTABLI_RSP);
|
||||
message_p = itti_alloc_new_message(TASK_NAS_UE, 0, NAS_RAB_ESTABLI_RSP);
|
||||
NAS_RAB_ESTABLI_RSP(message_p).s_tmsi = s_tmsi;
|
||||
NAS_RAB_ESTABLI_RSP(message_p).rabID = rabID;
|
||||
NAS_RAB_ESTABLI_RSP(message_p).errCode = errCode;
|
||||
|
||||
@@ -105,7 +105,7 @@ void *nas_ue_task(void *args_p)
|
||||
nas_user_t *user = &users->item[i];
|
||||
user->ueid = i;
|
||||
|
||||
/* Get USIM data application filename */ //
|
||||
/* Get USIM data application filename */
|
||||
user->usim_data_store = memory_get_path_from_ueid(USIM_API_NVRAM_DIRNAME, USIM_API_NVRAM_FILENAME, user->ueid);
|
||||
if (user->usim_data_store == NULL)
|
||||
{
|
||||
@@ -184,7 +184,7 @@ void *nas_ue_task(void *args_p)
|
||||
for (instance = NB_eNB_INST; instance < (NB_eNB_INST + NB_UE_INST); instance++) {
|
||||
MessageDef *message_p;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_NAS_UE, DEACTIVATE_MESSAGE);
|
||||
message_p = itti_alloc_new_message(TASK_NAS_UE, 0, DEACTIVATE_MESSAGE);
|
||||
itti_send_msg_to_task(TASK_L2L1, instance, message_p);
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ void *nas_ue_task(void *args_p)
|
||||
itti_receive_msg (TASK_NAS_UE, &msg_p);
|
||||
|
||||
if (msg_p != NULL) {
|
||||
instance = ITTI_MSG_INSTANCE (msg_p);
|
||||
instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p);
|
||||
Mod_id = instance - NB_eNB_INST;
|
||||
if (instance == INSTANCE_DEFAULT) {
|
||||
printf("%s:%d: FATAL: instance is INSTANCE_DEFAULT, should not happen.\n",
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
* 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 <openair3/NAS/COMMON/NR_NAS_defs.h>
|
||||
|
||||
void SGSabortUE(void *msg, NRUEcontext_t *UE) {
|
||||
}
|
||||
void nas_schedule(void) {
|
||||
}
|
||||
/*
|
||||
*Message reception
|
||||
*/
|
||||
|
||||
void SGSregistrationReq(void *msg, NRUEcontext_t *UE) {
|
||||
}
|
||||
|
||||
void SGSderegistrationUEReq(void *msg, NRUEcontext_t *UE) {
|
||||
}
|
||||
|
||||
void SGSidentityResp(void *msg, NRUEcontext_t *UE) {
|
||||
// use the UE SUPI to load the USIM
|
||||
IdentityresponseIMSI_t *resp=(IdentityresponseIMSI_t *)msg;
|
||||
char configName[100]={0};
|
||||
char * ptr= stpcpy(configName,"uicc");
|
||||
*ptr++=resp->mcc1+'0';
|
||||
*ptr++=resp->mcc2+'0';
|
||||
*ptr++=resp->mcc3+'0';
|
||||
*ptr++=resp->mnc1+'0';
|
||||
*ptr++=resp->mnc2+'0';
|
||||
if ( resp->mnc3 != 0xF )
|
||||
*ptr++=resp->mnc3 +'0';
|
||||
int respSize=ntohs(resp->common.len);
|
||||
int msinByteSize=respSize-sizeof(IdentityresponseIMSI_t);
|
||||
uint8_t * msin=(uint8_t *) (resp+1);
|
||||
for(int i=3 ; i<msinByteSize; i++) {
|
||||
char digit1=(msin[i] >> 4) ;
|
||||
*ptr++=(msin[i] & 0xf) +'0';
|
||||
if (digit1 != 0xf)
|
||||
*ptr++=digit1 +'0';
|
||||
}
|
||||
*ptr=0;
|
||||
if (UE->uicc == NULL)
|
||||
// config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE
|
||||
UE->uicc=init_uicc(configName);
|
||||
//We schedule Authentication request
|
||||
nas_schedule();
|
||||
}
|
||||
|
||||
void SGSauthenticationResp(void *msg, NRUEcontext_t *UE) {
|
||||
// Let's check the answer
|
||||
authenticationresponse_t* resp=(authenticationresponse_t*) msg;
|
||||
uint8_t resStarLocal[16];
|
||||
resToresStar(resStarLocal,UE->uicc);
|
||||
if ( memcmp(resStarLocal, resp->RES, sizeof(resStarLocal)) == 0 ) {
|
||||
LOG_I(NAS,"UE answer to authentication resquest is correct\n");
|
||||
// we will send securityModeCommand
|
||||
nas_schedule();
|
||||
} else {
|
||||
LOG_E(NAS,"UE authentication response not good\n");
|
||||
// To be implemented ?
|
||||
}
|
||||
}
|
||||
|
||||
void SGSsecurityModeComplete(void *msg, NRUEcontext_t *UE) {
|
||||
|
||||
}
|
||||
|
||||
void SGSregistrationComplete(void *msg, NRUEcontext_t *UE) {
|
||||
}
|
||||
|
||||
void processNAS(void *msg, NRUEcontext_t *UE) {
|
||||
SGScommonHeader_t *header=(SGScommonHeader_t *) msg;
|
||||
|
||||
if ( header->sh > 4 )
|
||||
SGSabortUE(msg, UE);
|
||||
else {
|
||||
switch (header->epd) {
|
||||
case SGSmobilitymanagementmessages:
|
||||
LOG_I(NAS,"Received message: %s\n", idStr(message_text_info, header->mt));
|
||||
|
||||
switch (header->mt) {
|
||||
case Registrationrequest:
|
||||
SGSregistrationReq(msg, UE);
|
||||
break;
|
||||
|
||||
case DeregistrationrequestUEoriginating:
|
||||
SGSderegistrationUEReq(msg, UE);
|
||||
break;
|
||||
|
||||
case Authenticationresponse:
|
||||
SGSauthenticationResp(msg, UE);
|
||||
break;
|
||||
|
||||
case Identityresponse:
|
||||
SGSidentityResp(msg, UE);
|
||||
break;
|
||||
|
||||
case Securitymodecomplete:
|
||||
SGSsecurityModeComplete(msg, UE);
|
||||
break;
|
||||
|
||||
case Registrationcomplete:
|
||||
SGSregistrationComplete(msg, UE);
|
||||
break;
|
||||
|
||||
default:
|
||||
SGSabortUE(msg, UE);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SGSsessionmanagementmessages:
|
||||
SGSabortUE(msg, UE);
|
||||
break;
|
||||
|
||||
default:
|
||||
SGSabortUE(msg, UE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Messages emission
|
||||
*/
|
||||
|
||||
int identityRequest(void **msg, NRUEcontext_t *UE) {
|
||||
myCalloc(req, Identityrequest_t);
|
||||
req->epd=SGSmobilitymanagementmessages;
|
||||
req->sh=0;
|
||||
req->mt=Identityrequest;
|
||||
req->it=SUCI;
|
||||
*msg=req;
|
||||
return sizeof(Identityrequest_t);
|
||||
}
|
||||
|
||||
int authenticationRequest(void **msg, NRUEcontext_t *UE) {
|
||||
|
||||
myCalloc(req, authenticationrequestHeader_t);
|
||||
req->epd=SGSmobilitymanagementmessages;
|
||||
req->sh=0;
|
||||
req->mt=Authenticationrequest;
|
||||
// native security context => bit 4 to 0
|
||||
// probably from TS 33.501, table A-8.1
|
||||
// N-NAS-int-alg (Native NAS integrity)
|
||||
/*
|
||||
N-NAS-enc-alg 0x01
|
||||
N-NAS-int-alg 0x02
|
||||
N-RRC-enc-alg 0x03
|
||||
N-RRC-int-alg 0x04
|
||||
N-UP-enc-alg 0x05
|
||||
N-UP-int-alg 0x06
|
||||
*/
|
||||
req->ngKSI=2;
|
||||
// TS 33.501, Annex A.7.1: Initial set of security features defined for 5GS.
|
||||
req->ABBALen=2;
|
||||
req->ABBA=0;
|
||||
//rand (TV)
|
||||
req->ieiRAND=IEI_RAND;
|
||||
FILE *h=fopen("/dev/random","r");
|
||||
|
||||
if ( sizeof(req->RAND) != fread(req->RAND,1,sizeof(req->RAND),h) )
|
||||
LOG_E(NAS, "can't read /dev/random\n");
|
||||
|
||||
fclose(h);
|
||||
memcpy(UE->uicc->rand, req->RAND, sizeof(UE->uicc->rand));
|
||||
// challenge/AUTN (TLV)
|
||||
req->ieiAUTN=IEI_AUTN;
|
||||
req->AUTNlen=sizeof(req->AUTN);
|
||||
uicc_milenage_generate( req->AUTN, UE->uicc);
|
||||
// EAP message (TLV-E)
|
||||
// not developped
|
||||
*msg=req;
|
||||
return sizeof(authenticationrequestHeader_t);
|
||||
}
|
||||
|
||||
int securityModeCommand(void **msg, NRUEcontext_t *UE) {
|
||||
*msg=NULL;
|
||||
myCalloc(req, securityModeCommand_t);
|
||||
req->epd=SGSmobilitymanagementmessages;
|
||||
req->sh=0;
|
||||
req->mt=Securitymodecommand;
|
||||
|
||||
// integrity algo from 5G-IA0 (null algo) to 5G-IA7 in first 4 bits
|
||||
unsigned int ia=0;
|
||||
// cyphering algo from 5G-EA0 (null algo) to 5G-IA7 in MSB 4 bits
|
||||
unsigned int ea=0;
|
||||
// trace from commercial: 5G-IA0 (0) 128-5G-IA2 (2)
|
||||
req->selectedNASsecurityalgorithms= ea<<4 | ia;
|
||||
|
||||
// KSI: N-NAS-int-alg 0x02
|
||||
req->ngKSI=2;
|
||||
|
||||
*msg=req;
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 ngap_common.c
|
||||
* \brief ngap procedures for both gNB and AMF
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ngap_common.h"
|
||||
#include "NGAP_NGAP-PDU.h"
|
||||
|
||||
|
||||
int asn1_xer_print = 0;
|
||||
|
||||
|
||||
void ngap_handle_criticality(NGAP_Criticality_t criticality)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 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 ngap_common.h
|
||||
* \brief ngap procedures for both gNB and AMF
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
*/
|
||||
|
||||
/** @defgroup _ngap_impl_ NGAP Layer Reference Implementation
|
||||
* @ingroup _ref_implementation_
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
#if HAVE_CONFIG_H_
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef NGAP_COMMON_H_
|
||||
#define NGAP_COMMON_H_
|
||||
|
||||
|
||||
#include "common/utils/LOG/log.h"
|
||||
/* replace ASN_DEBUG defined in asn_internal.h by oai tracing system
|
||||
Would be cleaner to modify asn_internal.h but it seems to come
|
||||
from non oai source, with BSD license, so prefer to do that here..
|
||||
*/
|
||||
#ifdef ASN_DEBUG
|
||||
# undef ASN_DEBUG
|
||||
#endif
|
||||
#define ASN_DEBUG( x... ) LOG_I(ASN, x)
|
||||
|
||||
#include "NGAP_ProtocolIE-Field.h"
|
||||
#include "NGAP_NGAP-PDU.h"
|
||||
#include "NGAP_InitiatingMessage.h"
|
||||
#include "NGAP_SuccessfulOutcome.h"
|
||||
#include "NGAP_UnsuccessfulOutcome.h"
|
||||
#include "NGAP_ProtocolIE-Field.h"
|
||||
#include "NGAP_ProtocolIE-FieldPair.h"
|
||||
#include "NGAP_ProtocolIE-ContainerPair.h"
|
||||
#include "NGAP_ProtocolExtensionField.h"
|
||||
#include "NGAP_ProtocolExtensionContainer.h"
|
||||
#include "NGAP_asn_constant.h"
|
||||
#include "NGAP_SupportedTAItem.h"
|
||||
#include "NGAP_ServedGUAMIItem.h"
|
||||
#include "NGAP_BroadcastPLMNItem.h"
|
||||
#include "NGAP_SliceSupportItem.h"
|
||||
#include "NGAP_PLMNSupportItem.h"
|
||||
#include "NGAP_PDUSessionResourceSetupResponseTransfer.h"
|
||||
#include "NGAP_PDUSessionResourceSetupUnsuccessfulTransfer.h"
|
||||
#include "NGAP_PDUSessionResourceSetupItemCxtRes.h"
|
||||
#include "NGAP_PDUSessionResourceFailedToSetupItemCxtRes.h"
|
||||
#include "NGAP_PDUSessionResourceSetupItemSUReq.h"
|
||||
#include "NGAP_PDUSessionResourceSetupItemSURes.h"
|
||||
#include "NGAP_PDUSessionResourceFailedToSetupItemSURes.h"
|
||||
#include "NGAP_AssociatedQosFlowItem.h"
|
||||
#include "NGAP_PDUSessionResourceSetupRequestTransfer.h"
|
||||
#include "NGAP_PDUSessionResourceSetupItemCxtReq.h"
|
||||
#include "NGAP_QosFlowSetupRequestItem.h"
|
||||
#include "NGAP_AllowedNSSAI-Item.h"
|
||||
#include "NGAP_PDUSessionResourceModifyItemModRes.h"
|
||||
#include "NGAP_PDUSessionResourceFailedToModifyItemModRes.h"
|
||||
#include "NGAP_PDUSessionResourceModifyUnsuccessfulTransfer.h"
|
||||
#include "NGAP_PDUSessionResourceReleasedItemRelRes.h"
|
||||
#include "NGAP_PDUSessionResourceToReleaseItemRelCmd.h"
|
||||
#include "NGAP_PDUSessionResourceModifyItemModReq.h"
|
||||
#include "NGAP_PDUSessionResourceModifyRequestTransfer.h"
|
||||
#include "NGAP_QosFlowAddOrModifyRequestItem.h"
|
||||
#include "NGAP_TAIListForPagingItem.h"
|
||||
#include "NGAP_GNB-ID.h"
|
||||
#include "NGAP_GlobalGNB-ID.h"
|
||||
#include "NGAP_GTPTunnel.h"
|
||||
#include "NGAP_UE-NGAP-ID-pair.h"
|
||||
#include "NGAP_UserLocationInformationNR.h"
|
||||
|
||||
/* Checking version of ASN1C compiler */
|
||||
#if (ASN1C_ENVIRONMENT_VERSION < ASN1C_MINIMUM_VERSION)
|
||||
# error "You are compiling ngap with the wrong version of ASN1C"
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
# define FALSE (0)
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
# define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
#define NGAP_UE_ID_FMT "0x%06"PRIX32
|
||||
|
||||
extern int asn_debug;
|
||||
extern int asn1_xer_print;
|
||||
|
||||
#if defined(ENB_MODE)
|
||||
# include "common/utils/LOG/log.h"
|
||||
# include "ngap_gNB_default_values.h"
|
||||
# define NGAP_ERROR(x, args...) LOG_E(NGAP, x, ##args)
|
||||
# define NGAP_WARN(x, args...) LOG_W(NGAP, x, ##args)
|
||||
# define NGAP_TRAF(x, args...) LOG_I(NGAP, x, ##args)
|
||||
# define NGAP_INFO(x, args...) LOG_I(NGAP, x, ##args)
|
||||
# define NGAP_DEBUG(x, args...) LOG_I(NGAP, x, ##args)
|
||||
#else
|
||||
# include "amf_default_values.h"
|
||||
# define NGAP_ERROR(x, args...) do { fprintf(stdout, "[NGAP][E]"x, ##args); } while(0)
|
||||
# define NGAP_WARN(x, args...) do { fprintf(stdout, "[NGAP][W]"x, ##args); } while(0)
|
||||
# define NGAP_TRAF(x, args...) do { fprintf(stdout, "[NGAP][T]"x, ##args); } while(0)
|
||||
# define NGAP_INFO(x, args...) do { fprintf(stdout, "[NGAP][I]"x, ##args); } while(0)
|
||||
# define NGAP_DEBUG(x, args...) do { fprintf(stdout, "[NGAP][D]"x, ##args); } while(0)
|
||||
#endif
|
||||
|
||||
|
||||
#define NGAP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \
|
||||
do {\
|
||||
IE_TYPE **ptr; \
|
||||
ie = NULL; \
|
||||
for (ptr = container->protocolIEs.list.array; \
|
||||
ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; \
|
||||
ptr++) { \
|
||||
if((*ptr)->id == IE_ID) { \
|
||||
ie = *ptr; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
if (ie == NULL ) { \
|
||||
NGAP_ERROR("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\
|
||||
} \
|
||||
if (mandatory) DevAssert(ie != NULL); \
|
||||
} while(0)
|
||||
/** \brief Function callback prototype.
|
||||
**/
|
||||
typedef int (*ngap_message_decoded_callback)(
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
NGAP_NGAP_PDU_t *pdu
|
||||
);
|
||||
|
||||
/** \brief Handle criticality
|
||||
\param criticality Criticality of the IE
|
||||
@returns void
|
||||
**/
|
||||
void ngap_handle_criticality(NGAP_Criticality_t criticality);
|
||||
|
||||
#endif /* NGAP_COMMON_H_ */
|
||||
@@ -0,0 +1,540 @@
|
||||
/*
|
||||
* 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 ngap_gNB.c
|
||||
* \brief NGAP gNB task
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \date 2020
|
||||
* \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \version 1.0
|
||||
* @ingroup _ngap
|
||||
*/
|
||||
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <crypt.h>
|
||||
|
||||
#include "tree.h"
|
||||
#include "queue.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "ngap_gNB_default_values.h"
|
||||
|
||||
#include "ngap_common.h"
|
||||
|
||||
#include "ngap_gNB_defs.h"
|
||||
#include "ngap_gNB.h"
|
||||
#include "ngap_gNB_encoder.h"
|
||||
#include "ngap_gNB_handlers.h"
|
||||
#include "ngap_gNB_nnsf.h"
|
||||
|
||||
#include "ngap_gNB_nas_procedures.h"
|
||||
#include "ngap_gNB_management_procedures.h"
|
||||
#include "ngap_gNB_context_management_procedures.h"
|
||||
|
||||
#include "ngap_gNB_itti_messaging.h"
|
||||
|
||||
#include "ngap_gNB_ue_context.h" // test, to be removed
|
||||
#include "msc.h"
|
||||
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#if defined(TEST_S1C_AMF)
|
||||
#include "oaisim_amf_test_s1c.h"
|
||||
#endif
|
||||
|
||||
ngap_gNB_config_t ngap_config;
|
||||
|
||||
static int ngap_gNB_generate_ng_setup_request(
|
||||
ngap_gNB_instance_t *instance_p, ngap_gNB_amf_data_t *ngap_amf_data_p);
|
||||
|
||||
void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_gnb_req_t *ngap_register_gNB);
|
||||
|
||||
void ngap_gNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
|
||||
|
||||
uint32_t ngap_generate_gNB_id(void) {
|
||||
char *out;
|
||||
char hostname[50];
|
||||
int ret;
|
||||
uint32_t gNB_id;
|
||||
/* Retrieve the host name */
|
||||
ret = gethostname(hostname, sizeof(hostname));
|
||||
DevAssert(ret == 0);
|
||||
out = crypt(hostname, "eurecom");
|
||||
DevAssert(out != NULL);
|
||||
gNB_id = ((out[0] << 24) | (out[1] << 16) | (out[2] << 8) | out[3]);
|
||||
return gNB_id;
|
||||
}
|
||||
|
||||
static void ngap_gNB_register_amf(ngap_gNB_instance_t *instance_p,
|
||||
net_ip_address_t *amf_ip_address,
|
||||
net_ip_address_t *local_ip_addr,
|
||||
uint16_t in_streams,
|
||||
uint16_t out_streams,
|
||||
uint8_t broadcast_plmn_num,
|
||||
uint8_t broadcast_plmn_index[PLMN_LIST_MAX_SIZE]) {
|
||||
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);
|
||||
sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req;
|
||||
sctp_new_association_req_p->port = NGAP_PORT_NUMBER;
|
||||
sctp_new_association_req_p->ppid = NGAP_SCTP_PPID;
|
||||
sctp_new_association_req_p->in_streams = in_streams;
|
||||
sctp_new_association_req_p->out_streams = out_streams;
|
||||
memcpy(&sctp_new_association_req_p->remote_address,
|
||||
amf_ip_address,
|
||||
sizeof(*amf_ip_address));
|
||||
memcpy(&sctp_new_association_req_p->local_address,
|
||||
local_ip_addr,
|
||||
sizeof(*local_ip_addr));
|
||||
NGAP_INFO("[gNB %ld] check the amf registration state\n",instance_p->instance);
|
||||
|
||||
/* Create new AMF descriptor */
|
||||
ngap_amf_data_p = calloc(1, sizeof(*ngap_amf_data_p));
|
||||
DevAssert(ngap_amf_data_p != NULL);
|
||||
ngap_amf_data_p->cnx_id = ngap_gNB_fetch_add_global_cnx_id();
|
||||
sctp_new_association_req_p->ulp_cnx_id = ngap_amf_data_p->cnx_id;
|
||||
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));
|
||||
for (int i = 0; i < broadcast_plmn_num; ++i)
|
||||
ngap_amf_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i];
|
||||
|
||||
ngap_amf_data_p->ngap_gNB_instance = instance_p;
|
||||
STAILQ_INIT(&ngap_amf_data_p->served_guami);
|
||||
/* Insert the new descriptor in list of known AMF
|
||||
* 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_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;
|
||||
DevAssert(ngap_register_gNB != NULL);
|
||||
/* Look if the provided instance already exists */
|
||||
new_instance = ngap_gNB_get_instance(instance);
|
||||
|
||||
if (new_instance != NULL) {
|
||||
/* Checks if it is a retry on the same gNB */
|
||||
DevCheck(new_instance->gNB_id == ngap_register_gNB->gNB_id, new_instance->gNB_id, ngap_register_gNB->gNB_id, 0);
|
||||
DevCheck(new_instance->cell_type == ngap_register_gNB->cell_type, new_instance->cell_type, ngap_register_gNB->cell_type, 0);
|
||||
DevCheck(new_instance->num_plmn == ngap_register_gNB->num_plmn, new_instance->num_plmn, ngap_register_gNB->num_plmn, 0);
|
||||
DevCheck(new_instance->tac == ngap_register_gNB->tac, new_instance->tac, ngap_register_gNB->tac, 0);
|
||||
|
||||
for (int i = 0; i < new_instance->num_plmn; i++) {
|
||||
DevCheck(new_instance->mcc[i] == ngap_register_gNB->mcc[i], new_instance->mcc[i], ngap_register_gNB->mcc[i], 0);
|
||||
DevCheck(new_instance->mnc[i] == ngap_register_gNB->mnc[i], new_instance->mnc[i], ngap_register_gNB->mnc[i], 0);
|
||||
DevCheck(new_instance->mnc_digit_length[i] == ngap_register_gNB->mnc_digit_length[i], new_instance->mnc_digit_length[i], ngap_register_gNB->mnc_digit_length[i], 0);
|
||||
}
|
||||
|
||||
DevCheck(new_instance->default_drx == ngap_register_gNB->default_drx, new_instance->default_drx, ngap_register_gNB->default_drx, 0);
|
||||
} else {
|
||||
new_instance = calloc(1, sizeof(ngap_gNB_instance_t));
|
||||
DevAssert(new_instance != NULL);
|
||||
RB_INIT(&new_instance->ngap_ue_head);
|
||||
RB_INIT(&new_instance->ngap_amf_head);
|
||||
/* Copy usefull parameters */
|
||||
new_instance->instance = instance;
|
||||
new_instance->gNB_name = ngap_register_gNB->gNB_name;
|
||||
new_instance->gNB_id = ngap_register_gNB->gNB_id;
|
||||
new_instance->cell_type = ngap_register_gNB->cell_type;
|
||||
new_instance->tac = ngap_register_gNB->tac;
|
||||
|
||||
memcpy(&new_instance->gNB_ng_ip,
|
||||
&ngap_register_gNB->gnb_ip_address,
|
||||
sizeof(ngap_register_gNB->gnb_ip_address));
|
||||
|
||||
for (int i = 0; i < ngap_register_gNB->num_plmn; i++) {
|
||||
new_instance->mcc[i] = ngap_register_gNB->mcc[i];
|
||||
new_instance->mnc[i] = ngap_register_gNB->mnc[i];
|
||||
new_instance->mnc_digit_length[i] = ngap_register_gNB->mnc_digit_length[i];
|
||||
|
||||
new_instance->num_nssai[i] = ngap_register_gNB->num_nssai[i];
|
||||
}
|
||||
|
||||
new_instance->num_plmn = ngap_register_gNB->num_plmn;
|
||||
new_instance->default_drx = ngap_register_gNB->default_drx;
|
||||
|
||||
memcpy(new_instance->s_nssai, ngap_register_gNB->s_nssai, sizeof(ngap_register_gNB->s_nssai));
|
||||
|
||||
/* Add the new instance to the list of gNB (meaningfull in virtual mode) */
|
||||
ngap_gNB_insert_new_instance(new_instance);
|
||||
NGAP_INFO("Registered new gNB[%ld] and %s gNB id %u\n",
|
||||
instance,
|
||||
ngap_register_gNB->cell_type == CELL_MACRO_GNB ? "macro" : "home",
|
||||
ngap_register_gNB->gNB_id);
|
||||
}
|
||||
|
||||
DevCheck(ngap_register_gNB->nb_amf <= NGAP_MAX_NB_AMF_IP_ADDRESS,
|
||||
NGAP_MAX_NB_AMF_IP_ADDRESS, ngap_register_gNB->nb_amf, 0);
|
||||
|
||||
/* Trying to connect to provided list of AMF ip address */
|
||||
for (index = 0; index < ngap_register_gNB->nb_amf; index++) {
|
||||
net_ip_address_t *amf_ip = &ngap_register_gNB->amf_ip_address[index];
|
||||
struct ngap_gNB_amf_data_s *amf = NULL;
|
||||
RB_FOREACH(amf, ngap_amf_map, &new_instance->ngap_amf_head) {
|
||||
/* Compare whether IPv4 and IPv6 information is already present, in which
|
||||
* wase we do not register again */
|
||||
if (amf->amf_s1_ip.ipv4 == amf_ip->ipv4 && (!amf_ip->ipv4
|
||||
|| strncmp(amf->amf_s1_ip.ipv4_address, amf_ip->ipv4_address, 16) == 0)
|
||||
&& amf->amf_s1_ip.ipv6 == amf_ip->ipv6 && (!amf_ip->ipv6
|
||||
|| strncmp(amf->amf_s1_ip.ipv6_address, amf_ip->ipv6_address, 46) == 0))
|
||||
break;
|
||||
}
|
||||
if (amf)
|
||||
continue;
|
||||
ngap_gNB_register_amf(new_instance,
|
||||
amf_ip,
|
||||
&ngap_register_gNB->gnb_ip_address,
|
||||
ngap_register_gNB->sctp_in_streams,
|
||||
ngap_register_gNB->sctp_out_streams,
|
||||
ngap_register_gNB->broadcast_plmn_num[index],
|
||||
ngap_register_gNB->broadcast_plmn_index[index]);
|
||||
}
|
||||
}
|
||||
|
||||
void ngap_gNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
|
||||
ngap_gNB_instance_t *instance_p;
|
||||
ngap_gNB_amf_data_t *ngap_amf_data_p;
|
||||
DevAssert(sctp_new_association_resp != NULL);
|
||||
instance_p = ngap_gNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
ngap_amf_data_p = ngap_gNB_get_AMF(instance_p, -1,
|
||||
sctp_new_association_resp->ulp_cnx_id);
|
||||
DevAssert(ngap_amf_data_p != NULL);
|
||||
|
||||
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
|
||||
NGAP_WARN("Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
|
||||
sctp_new_association_resp->sctp_state,
|
||||
instance,
|
||||
sctp_new_association_resp->ulp_cnx_id);
|
||||
ngap_handle_ng_setup_message(ngap_amf_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update parameters */
|
||||
ngap_amf_data_p->assoc_id = sctp_new_association_resp->assoc_id;
|
||||
ngap_amf_data_p->in_streams = sctp_new_association_resp->in_streams;
|
||||
ngap_amf_data_p->out_streams = sctp_new_association_resp->out_streams;
|
||||
/* Prepare new NG Setup Request */
|
||||
ngap_gNB_generate_ng_setup_request(instance_p, ngap_amf_data_p);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void ngap_gNB_init(void) {
|
||||
NGAP_DEBUG("Starting NGAP layer\n");
|
||||
ngap_gNB_prepare_internal_data();
|
||||
itti_mark_task_ready(TASK_NGAP);
|
||||
MSC_START_USE();
|
||||
}
|
||||
|
||||
void *ngap_gNB_process_itti_msg(void *notUsed) {
|
||||
MessageDef *received_msg = NULL;
|
||||
int result;
|
||||
itti_receive_msg(TASK_NGAP, &received_msg);
|
||||
|
||||
switch (ITTI_MSG_ID(received_msg)) {
|
||||
case TERMINATE_MESSAGE:
|
||||
NGAP_WARN(" *** Exiting NGAP thread\n");
|
||||
itti_exit_task();
|
||||
break;
|
||||
|
||||
case NGAP_REGISTER_GNB_REQ: {
|
||||
/* Register a new gNB.
|
||||
* in Virtual mode gNBs will be distinguished using the mod_id/
|
||||
* Each gNB has to send an NGAP_REGISTER_GNB message with its
|
||||
* own parameters.
|
||||
*/
|
||||
ngap_gNB_handle_register_gNB(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_REGISTER_GNB_REQ(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_RESP: {
|
||||
ngap_gNB_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_resp);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCTP_DATA_IND: {
|
||||
ngap_gNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind);
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_NAS_FIRST_REQ: {
|
||||
ngap_gNB_handle_nas_first_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_NAS_FIRST_REQ(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_UPLINK_NAS: {
|
||||
ngap_gNB_nas_uplink(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_UPLINK_NAS(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_UE_CAPABILITIES_IND: {
|
||||
ngap_gNB_ue_capabilities(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_UE_CAPABILITIES_IND(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_INITIAL_CONTEXT_SETUP_RESP: {
|
||||
ngap_gNB_initial_ctxt_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_INITIAL_CONTEXT_SETUP_RESP(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_PDUSESSION_SETUP_RESP: {
|
||||
ngap_gNB_pdusession_setup_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_PDUSESSION_SETUP_RESP(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_PDUSESSION_MODIFY_RESP: {
|
||||
ngap_gNB_pdusession_modify_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_PDUSESSION_MODIFY_RESP(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_NAS_NON_DELIVERY_IND: {
|
||||
ngap_gNB_nas_non_delivery_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_NAS_NON_DELIVERY_IND(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_PATH_SWITCH_REQ: {
|
||||
ngap_gNB_path_switch_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_PATH_SWITCH_REQ(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_PDUSESSION_MODIFICATION_IND: {
|
||||
ngap_gNB_generate_PDUSESSION_Modification_Indication(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_PDUSESSION_MODIFICATION_IND(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_UE_CONTEXT_RELEASE_COMPLETE: {
|
||||
ngap_ue_context_release_complete(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_UE_CONTEXT_RELEASE_COMPLETE(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_UE_CONTEXT_RELEASE_REQ: {
|
||||
ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; // test
|
||||
struct ngap_gNB_ue_context_s *ue_context_p = NULL; // test
|
||||
ngap_ue_context_release_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_UE_CONTEXT_RELEASE_REQ(received_msg));
|
||||
ngap_gNB_instance_p = ngap_gNB_get_instance(ITTI_MSG_DESTINATION_INSTANCE(received_msg)); // test
|
||||
DevAssert(ngap_gNB_instance_p != NULL); // test
|
||||
|
||||
if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p,
|
||||
NGAP_UE_CONTEXT_RELEASE_REQ(received_msg).gNB_ue_ngap_id)) == NULL) { // test
|
||||
/* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */
|
||||
NGAP_ERROR("Failed to find ue context associated with gNB ue ngap id: %u\n",
|
||||
NGAP_UE_CONTEXT_RELEASE_REQ(received_msg).gNB_ue_ngap_id); // test
|
||||
} // test
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_PDUSESSION_RELEASE_RESPONSE: {
|
||||
ngap_gNB_pdusession_release_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_PDUSESSION_RELEASE_RESPONSE(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
NGAP_ERROR("Received unhandled message: %d:%s\n",
|
||||
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
|
||||
break;
|
||||
}
|
||||
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
received_msg = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void *ngap_gNB_task(void *arg) {
|
||||
ngap_gNB_init();
|
||||
|
||||
while (1) {
|
||||
(void) ngap_gNB_process_itti_msg(NULL);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* gNB generate a NG setup request towards AMF
|
||||
*/
|
||||
static int ngap_gNB_generate_ng_setup_request(
|
||||
ngap_gNB_instance_t *instance_p,
|
||||
ngap_gNB_amf_data_t *ngap_amf_data_p)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
NGAP_NGAP_PDU_t pdu;
|
||||
NGAP_NGSetupRequest_t *out = NULL;
|
||||
NGAP_NGSetupRequestIEs_t *ie = NULL;
|
||||
NGAP_SupportedTAItem_t *ta = NULL;
|
||||
NGAP_BroadcastPLMNItem_t *plmn = NULL;
|
||||
NGAP_SliceSupportItem_t *ssi = NULL;
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t len = 0;
|
||||
int ret = 0;
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(ngap_amf_data_p != NULL);
|
||||
ngap_amf_data_p->state = NGAP_GNB_STATE_WAITING;
|
||||
/* Prepare the NGAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage = CALLOC(1, sizeof(struct NGAP_InitiatingMessage));
|
||||
pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_NGSetup;
|
||||
pdu.choice.initiatingMessage->criticality = NGAP_Criticality_reject;
|
||||
pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_NGSetupRequest;
|
||||
out = &pdu.choice.initiatingMessage->value.choice.NGSetupRequest;
|
||||
/* mandatory */
|
||||
ie = (NGAP_NGSetupRequestIEs_t *)calloc(1, sizeof(NGAP_NGSetupRequestIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_GlobalRANNodeID;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_NGSetupRequestIEs__value_PR_GlobalRANNodeID;
|
||||
ie->value.choice.GlobalRANNodeID.present = NGAP_GlobalRANNodeID_PR_globalGNB_ID;
|
||||
ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID = CALLOC(1, sizeof(struct NGAP_GlobalGNB_ID));
|
||||
MCC_MNC_TO_PLMNID(instance_p->mcc[ngap_amf_data_p->broadcast_plmn_index[0]],
|
||||
instance_p->mnc[ngap_amf_data_p->broadcast_plmn_index[0]],
|
||||
instance_p->mnc_digit_length[ngap_amf_data_p->broadcast_plmn_index[0]],
|
||||
&(ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->pLMNIdentity));
|
||||
ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->gNB_ID.present = NGAP_GNB_ID_PR_gNB_ID;
|
||||
MACRO_GNB_ID_TO_BIT_STRING(instance_p->gNB_id,
|
||||
&ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->gNB_ID.choice.gNB_ID);
|
||||
NGAP_INFO("%u -> %02x%02x%02x%02x\n", instance_p->gNB_id,
|
||||
ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->gNB_ID.choice.gNB_ID.buf[0],
|
||||
ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->gNB_ID.choice.gNB_ID.buf[1],
|
||||
ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->gNB_ID.choice.gNB_ID.buf[2],
|
||||
ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->gNB_ID.choice.gNB_ID.buf[3]);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
/* optional */
|
||||
if (instance_p->gNB_name) {
|
||||
ie = (NGAP_NGSetupRequestIEs_t *)calloc(1, sizeof(NGAP_NGSetupRequestIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_RANNodeName;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_NGSetupRequestIEs__value_PR_RANNodeName;
|
||||
OCTET_STRING_fromBuf(&ie->value.choice.RANNodeName, instance_p->gNB_name,
|
||||
strlen(instance_p->gNB_name));
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_NGSetupRequestIEs_t *)calloc(1, sizeof(NGAP_NGSetupRequestIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_SupportedTAList;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_NGSetupRequestIEs__value_PR_SupportedTAList;
|
||||
{
|
||||
ta = (NGAP_SupportedTAItem_t *)calloc(1, sizeof(NGAP_SupportedTAItem_t));
|
||||
INT24_TO_OCTET_STRING(instance_p->tac, &ta->tAC);
|
||||
{
|
||||
for (int i = 0; i < ngap_amf_data_p->broadcast_plmn_num; ++i) {
|
||||
plmn = (NGAP_BroadcastPLMNItem_t *)calloc(1, sizeof(NGAP_BroadcastPLMNItem_t));
|
||||
MCC_MNC_TO_TBCD(instance_p->mcc[ngap_amf_data_p->broadcast_plmn_index[i]],
|
||||
instance_p->mnc[ngap_amf_data_p->broadcast_plmn_index[i]],
|
||||
instance_p->mnc_digit_length[ngap_amf_data_p->broadcast_plmn_index[i]],
|
||||
&plmn->pLMNIdentity);
|
||||
|
||||
for(int si = 0; si < instance_p->num_nssai[i]; si++) {
|
||||
ssi = (NGAP_SliceSupportItem_t *)calloc(1, sizeof(NGAP_SliceSupportItem_t));
|
||||
INT8_TO_OCTET_STRING(instance_p->s_nssai[i][si].sST, &ssi->s_NSSAI.sST);
|
||||
|
||||
if(instance_p->s_nssai[i]->sD_flag) {
|
||||
ssi->s_NSSAI.sD = calloc(1, sizeof(NGAP_SD_t));
|
||||
ssi->s_NSSAI.sD->buf = calloc(3, sizeof(uint8_t));
|
||||
ssi->s_NSSAI.sD->size = 3;
|
||||
ssi->s_NSSAI.sD->buf[0] = instance_p->s_nssai[i][si].sD[0];
|
||||
ssi->s_NSSAI.sD->buf[1] = instance_p->s_nssai[i][si].sD[1];
|
||||
ssi->s_NSSAI.sD->buf[2] = instance_p->s_nssai[i][si].sD[2];
|
||||
}
|
||||
|
||||
|
||||
ASN_SEQUENCE_ADD(&plmn->tAISliceSupportList.list, ssi);
|
||||
}
|
||||
|
||||
ASN_SEQUENCE_ADD(&ta->broadcastPLMNList.list, plmn);
|
||||
}
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.SupportedTAList.list, ta);
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_NGSetupRequestIEs_t *)calloc(1, sizeof(NGAP_NGSetupRequestIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_DefaultPagingDRX;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_NGSetupRequestIEs__value_PR_PagingDRX;
|
||||
ie->value.choice.PagingDRX = instance_p->default_drx;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
|
||||
if (ngap_gNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
NGAP_ERROR("Failed to encode NG setup request\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Non UE-Associated signalling -> stream = 0 */
|
||||
ngap_gNB_itti_send_sctp_data_req(instance_p->instance, ngap_amf_data_p->assoc_id, buffer, len, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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 ngap_gNB.h
|
||||
* \brief NGAP gNB task
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \date 2020
|
||||
* \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \version 1.0
|
||||
* @ingroup _ngap
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** @defgroup _ngap_impl_ NGAP Layer Reference Implementation for gNB
|
||||
* @ingroup _ref_implementation_
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef NGAP_GNB_H_
|
||||
#define NGAP_GNB_H_
|
||||
|
||||
typedef struct ngap_gNB_config_s {
|
||||
// MME related params
|
||||
unsigned char amf_enabled; ///< AMF enabled ?
|
||||
unsigned char ngap_enabled; ///< NGAP enabled ?
|
||||
} ngap_gNB_config_t;
|
||||
|
||||
extern ngap_gNB_config_t ngap_config;
|
||||
|
||||
#define AMF_MODE_ENABLED ngap_config.amf_enabled
|
||||
#define NGAP_CONF_MODE ngap_config.ngap_enabled
|
||||
|
||||
|
||||
void *ngap_gNB_process_itti_msg(void*);
|
||||
void ngap_gNB_init(void);
|
||||
void *ngap_gNB_task(void *arg);
|
||||
|
||||
uint32_t ngap_generate_gNB_id(void);
|
||||
|
||||
#endif /* NGAP_GNB_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* 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 ngap_gNB_context_management_procedures.c
|
||||
* \brief NGAP context management procedures
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \date 2020
|
||||
* \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \version 1.0
|
||||
* @ingroup _ngap
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "ngap_common.h"
|
||||
#include "ngap_gNB_defs.h"
|
||||
|
||||
#include "ngap_gNB_itti_messaging.h"
|
||||
|
||||
#include "ngap_gNB_encoder.h"
|
||||
#include "ngap_gNB_nnsf.h"
|
||||
#include "ngap_gNB_ue_context.h"
|
||||
#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"
|
||||
|
||||
|
||||
int ngap_ue_context_release_complete(instance_t instance,
|
||||
ngap_ue_release_complete_t *ue_release_complete_p)
|
||||
{
|
||||
|
||||
ngap_gNB_instance_t *ngap_gNB_instance_p = NULL;
|
||||
struct ngap_gNB_ue_context_s *ue_context_p = NULL;
|
||||
NGAP_NGAP_PDU_t pdu;
|
||||
NGAP_UEContextReleaseComplete_t *out;
|
||||
NGAP_UEContextReleaseComplete_IEs_t *ie;
|
||||
uint8_t *buffer;
|
||||
uint32_t length;
|
||||
|
||||
/* Retrieve the NGAP gNB instance associated with Mod_id */
|
||||
ngap_gNB_instance_p = ngap_gNB_get_instance(instance);
|
||||
|
||||
DevAssert(ue_release_complete_p != NULL);
|
||||
DevAssert(ngap_gNB_instance_p != NULL);
|
||||
|
||||
/*RB_FOREACH(ue_context_p, ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head) {
|
||||
NGAP_WARN("in ngap_ue_map: UE context gNB_ue_ngap_id %u amf_ue_ngap_id %u state %u\n",
|
||||
ue_context_p->gNB_ue_ngap_id, ue_context_p->amf_ue_ngap_id,
|
||||
ue_context_p->ue_state);
|
||||
}*/
|
||||
if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p,
|
||||
ue_release_complete_p->gNB_ue_ngap_id)) == NULL) {
|
||||
/* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */
|
||||
NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %u\n",
|
||||
ue_release_complete_p->gNB_ue_ngap_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Prepare the NGAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome;
|
||||
pdu.choice.successfulOutcome = CALLOC(1, sizeof(struct NGAP_SuccessfulOutcome));
|
||||
pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_UEContextRelease;
|
||||
pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject;
|
||||
pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_UEContextReleaseComplete;
|
||||
out = &pdu.choice.successfulOutcome->value.choice.UEContextReleaseComplete;
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_UEContextReleaseComplete_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseComplete_IEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_AMF_UE_NGAP_ID;
|
||||
asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_UEContextReleaseComplete_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseComplete_IEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_RAN_UE_NGAP_ID;
|
||||
ie->value.choice.RAN_UE_NGAP_ID = ue_release_complete_p->gNB_ue_ngap_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
|
||||
if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) {
|
||||
/* Encode procedure has failed... */
|
||||
NGAP_ERROR("Failed to encode UE context release complete\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_NGAP_GNB,
|
||||
MSC_NGAP_AMF,
|
||||
buffer,
|
||||
length,
|
||||
MSC_AS_TIME_FMT" UEContextRelease successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %lu",
|
||||
0,0, //MSC_AS_TIME_ARGS(ctxt_pP),
|
||||
ue_release_complete_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);
|
||||
|
||||
//LG ngap_gNB_itti_send_sctp_close_association(ngap_gNB_instance_p->instance,
|
||||
// ue_context_p->amf_ref->assoc_id);
|
||||
// release UE context
|
||||
struct ngap_gNB_ue_context_s *ue_context2_p = NULL;
|
||||
|
||||
if ((ue_context2_p = RB_REMOVE(ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head, ue_context_p))
|
||||
!= NULL) {
|
||||
NGAP_WARN("Removed UE context gNB_ue_ngap_id %u\n",
|
||||
ue_context2_p->gNB_ue_ngap_id);
|
||||
ngap_gNB_free_ue_context(ue_context2_p);
|
||||
} else {
|
||||
NGAP_WARN("Removing UE context gNB_ue_ngap_id %u: did not find context\n",
|
||||
ue_context_p->gNB_ue_ngap_id);
|
||||
}
|
||||
/*RB_FOREACH(ue_context_p, ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head) {
|
||||
NGAP_WARN("in ngap_ue_map: UE context gNB_ue_ngap_id %u amf_ue_ngap_id %u state %u\n",
|
||||
ue_context_p->gNB_ue_ngap_id, ue_context_p->amf_ue_ngap_id,
|
||||
ue_context_p->ue_state);
|
||||
}*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ngap_ue_context_release_req(instance_t instance,
|
||||
ngap_ue_release_req_t *ue_release_req_p)
|
||||
{
|
||||
ngap_gNB_instance_t *ngap_gNB_instance_p = NULL;
|
||||
struct ngap_gNB_ue_context_s *ue_context_p = NULL;
|
||||
NGAP_NGAP_PDU_t pdu;
|
||||
NGAP_UEContextReleaseRequest_t *out;
|
||||
NGAP_UEContextReleaseRequest_IEs_t *ie;
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t length;
|
||||
/* Retrieve the NGAP gNB instance associated with Mod_id */
|
||||
ngap_gNB_instance_p = ngap_gNB_get_instance(instance);
|
||||
|
||||
DevAssert(ue_release_req_p != NULL);
|
||||
DevAssert(ngap_gNB_instance_p != NULL);
|
||||
|
||||
if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p,
|
||||
ue_release_req_p->gNB_ue_ngap_id)) == NULL) {
|
||||
/* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */
|
||||
NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %u\n",
|
||||
ue_release_req_p->gNB_ue_ngap_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Prepare the NGAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage = CALLOC(1, sizeof(struct NGAP_InitiatingMessage));
|
||||
pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UEContextReleaseRequest;
|
||||
pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore;
|
||||
pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_UEContextReleaseRequest;
|
||||
out = &pdu.choice.initiatingMessage->value.choice.UEContextReleaseRequest;
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_AMF_UE_NGAP_ID;
|
||||
asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id);
|
||||
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_RAN_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_RAN_UE_NGAP_ID;
|
||||
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;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_Cause;
|
||||
|
||||
switch (ue_release_req_p->cause) {
|
||||
case NGAP_Cause_PR_radioNetwork:
|
||||
ie->value.choice.Cause.present = NGAP_Cause_PR_radioNetwork;
|
||||
ie->value.choice.Cause.choice.radioNetwork = ue_release_req_p->cause_value;
|
||||
break;
|
||||
|
||||
case NGAP_Cause_PR_transport:
|
||||
ie->value.choice.Cause.present = NGAP_Cause_PR_transport;
|
||||
ie->value.choice.Cause.choice.transport = ue_release_req_p->cause_value;
|
||||
break;
|
||||
|
||||
case NGAP_Cause_PR_nas:
|
||||
ie->value.choice.Cause.present = NGAP_Cause_PR_nas;
|
||||
ie->value.choice.Cause.choice.nas = ue_release_req_p->cause_value;
|
||||
break;
|
||||
|
||||
case NGAP_Cause_PR_protocol:
|
||||
ie->value.choice.Cause.present = NGAP_Cause_PR_protocol;
|
||||
ie->value.choice.Cause.choice.protocol = ue_release_req_p->cause_value;
|
||||
break;
|
||||
|
||||
case NGAP_Cause_PR_misc:
|
||||
ie->value.choice.Cause.present = NGAP_Cause_PR_misc;
|
||||
ie->value.choice.Cause.choice.misc = ue_release_req_p->cause_value;
|
||||
break;
|
||||
|
||||
case NGAP_Cause_PR_NOTHING:
|
||||
default:
|
||||
ie->value.choice.Cause.present = NGAP_Cause_PR_NOTHING;
|
||||
break;
|
||||
}
|
||||
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
|
||||
|
||||
if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) {
|
||||
/* Encode procedure has failed... */
|
||||
NGAP_ERROR("Failed to encode UE context release complete\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_NGAP_GNB,
|
||||
MSC_NGAP_AMF,
|
||||
buffer,
|
||||
length,
|
||||
MSC_AS_TIME_FMT" UEContextReleaseRequest initiatingMessage gNB_ue_ngap_id %u amf_ue_ngap_id %lu",
|
||||
0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
|
||||
ue_release_req_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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 ngap_gNB_context_management_procedures.h
|
||||
* \brief NGAP context management procedures
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \date 2020
|
||||
* \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \version 1.0
|
||||
* @ingroup _ngap
|
||||
*/
|
||||
|
||||
#ifndef NGAP_GNB_CONTEXT_MANAGEMENT_PROCEDURES_H_
|
||||
#define NGAP_GNB_CONTEXT_MANAGEMENT_PROCEDURES_H_
|
||||
|
||||
|
||||
int ngap_ue_context_release_complete(instance_t instance,
|
||||
ngap_ue_release_complete_t *ue_release_complete_p);
|
||||
|
||||
int ngap_ue_context_release_req(instance_t instance,
|
||||
ngap_ue_release_req_t *ue_release_req_p);
|
||||
|
||||
#endif /* NGAP_GNB_CONTEXT_MANAGEMENT_PROCEDURES_H_ */
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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 ngap_gNB_decoder.c
|
||||
* \brief ngap pdu decode procedures for gNB
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "assertions.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "ngap_common.h"
|
||||
#include "ngap_gNB_decoder.h"
|
||||
|
||||
static int ngap_gNB_decode_initiating_message(NGAP_NGAP_PDU_t *pdu) {
|
||||
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
switch(pdu->choice.initiatingMessage->procedureCode) {
|
||||
case NGAP_ProcedureCode_id_DownlinkNASTransport:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_InitialContextSetup:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_UEContextRelease:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_Paging:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
NGAP_INFO("Paging initiating message\n");
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PDUSessionResourceSetup:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("PDUSESSIONSetup initiating message\n");
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PDUSessionResourceModify:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("PDUSESSIONModify initiating message\n");
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PDUSessionResourceRelease:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("TODO PDUSESSIONRelease initiating message\n");
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_ErrorIndication:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("TODO ErrorIndication initiating message\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
NGAP_ERROR("Unknown procedure ID (%d) for initiating message\n",
|
||||
(int)pdu->choice.initiatingMessage->procedureCode);
|
||||
AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n",
|
||||
(int)pdu->choice.initiatingMessage->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ngap_gNB_decode_successful_outcome(NGAP_NGAP_PDU_t *pdu) {
|
||||
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
switch(pdu->choice.successfulOutcome->procedureCode) {
|
||||
case NGAP_ProcedureCode_id_NGSetup:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PathSwitchRequest:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PDUSessionResourceModifyIndication:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
NGAP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n",
|
||||
(int)pdu->choice.successfulOutcome->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ngap_gNB_decode_unsuccessful_outcome(NGAP_NGAP_PDU_t *pdu) {
|
||||
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
switch(pdu->choice.unsuccessfulOutcome->procedureCode) {
|
||||
case NGAP_ProcedureCode_id_NGSetup:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
case NGAP_ProcedureCode_id_PathSwitchRequest:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
NGAP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n",
|
||||
(int)pdu->choice.unsuccessfulOutcome->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ngap_gNB_decode_pdu(NGAP_NGAP_PDU_t *pdu, const uint8_t *const buffer,
|
||||
const uint32_t length) {
|
||||
asn_dec_rval_t dec_ret;
|
||||
DevAssert(pdu != NULL);
|
||||
DevAssert(buffer != NULL);
|
||||
dec_ret = aper_decode(NULL,
|
||||
&asn_DEF_NGAP_NGAP_PDU,
|
||||
(void **)&pdu,
|
||||
buffer,
|
||||
length,
|
||||
0,
|
||||
0);
|
||||
|
||||
if (dec_ret.code != RC_OK) {
|
||||
NGAP_ERROR("Failed to decode pdu\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(pdu->present) {
|
||||
case NGAP_NGAP_PDU_PR_initiatingMessage:
|
||||
return ngap_gNB_decode_initiating_message(pdu);
|
||||
|
||||
case NGAP_NGAP_PDU_PR_successfulOutcome:
|
||||
return ngap_gNB_decode_successful_outcome(pdu);
|
||||
|
||||
case NGAP_NGAP_PDU_PR_unsuccessfulOutcome:
|
||||
return ngap_gNB_decode_unsuccessful_outcome(pdu);
|
||||
|
||||
default:
|
||||
NGAP_DEBUG("Unknown presence (%d) or not implemented\n", (int)pdu->present);
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 ngap_gNB_decoder.h
|
||||
* \brief ngap pdu decode procedures for gNB
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef NGAP_GNB_DECODER_H_
|
||||
#define NGAP_GNB_DECODER_H_
|
||||
|
||||
int ngap_gNB_decode_pdu(NGAP_NGAP_PDU_t *pdu, const uint8_t *const buffer,
|
||||
const uint32_t length) __attribute__ ((warn_unused_result));
|
||||
|
||||
#endif /* NGAP_GNB_DECODER_H_ */
|
||||
@@ -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
|
||||
*/
|
||||
/*! \file ngap_gNB_default_values.h
|
||||
* \brief ngap default values
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
*/
|
||||
|
||||
#ifndef NGAP_GNB_DEFAULT_VALUES_H_
|
||||
#define NGAP_GNB_DEFAULT_VALUES_H_
|
||||
|
||||
#define GNB_TAC (1)
|
||||
#define GNB_MCC (208)
|
||||
#define GNB_MNC (92)
|
||||
|
||||
#define GNB_NAME "Eurecom GNB"
|
||||
#define GNB_NAME_FORMAT (GNB_NAME" %u")
|
||||
|
||||
#define NGAP_PORT_NUMBER (38412)
|
||||
#define NGAP_SCTP_PPID (60)
|
||||
|
||||
#define X2AP_PORT_NUMBER (36422)
|
||||
#define X2AP_SCTP_PPID (27)
|
||||
|
||||
#endif /* NGAP_GNB_DEFAULT_VALUES_H_ */
|
||||
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* 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 ngap_gNB_defs.h
|
||||
* \brief ngap define procedures for gNB
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "queue.h"
|
||||
#include "tree.h"
|
||||
|
||||
#ifndef NGAP_GNB_DEFS_H_
|
||||
#define NGAP_GNB_DEFS_H_
|
||||
|
||||
#define NGAP_GNB_NAME_LENGTH_MAX (150)
|
||||
|
||||
typedef enum {
|
||||
/* Disconnected state: initial state for any association. */
|
||||
NGAP_GNB_STATE_DISCONNECTED = 0x0,
|
||||
/* State waiting for S1 Setup response message if gNB is AMF accepted or
|
||||
* S1 Setup failure if AMF rejects the gNB.
|
||||
*/
|
||||
NGAP_GNB_STATE_WAITING = 0x1,
|
||||
/* The gNB is successfully connected to AMF, UE contexts can be created. */
|
||||
NGAP_GNB_STATE_CONNECTED = 0x2,
|
||||
/* The AMF has sent an overload start message. Once the AMF disables the
|
||||
* OVERLOAD marker, the state of the association will be
|
||||
* NGAP_GNB_STATE_CONNECTED.
|
||||
*/
|
||||
NGAP_GNB_OVERLOAD = 0x3,
|
||||
/* Max number of states available */
|
||||
NGAP_GNB_STATE_MAX,
|
||||
} ngap_gNB_state_t;
|
||||
|
||||
/* If the Overload Action IE in the OVERLOAD START message is set to
|
||||
* - “reject all RRC connection establishments for non-emergency mobile
|
||||
* originated data transfer E(i.e. reject traffic corresponding to RRC cause
|
||||
* “mo-data E(TS 36.331 [16])), or
|
||||
* - “reject all RRC connection establishments for signalling E(i.e. reject
|
||||
* traffic corresponding to RRC cause “modata Eand “mo-signalling E * (TS 38.331 [16])),or
|
||||
* - “only permit RRC connection establishments for emergency sessions and
|
||||
* mobile terminated services E(i.e. only permit traffic corresponding to RRC
|
||||
* cause “emergency Eand “mt-Access E(TS 36.331 [16])).
|
||||
*
|
||||
* NOTE: When the Overload Action IE is set to “only permit RRC connection
|
||||
* establishments for emergency sessions and mobile terminated services E
|
||||
* emergency calls with RRC cause “highPriorityAcess Efrom high priority users
|
||||
* are rejected (TS 24.301 [24]).
|
||||
*/
|
||||
typedef enum {
|
||||
NGAP_OVERLOAD_REJECT_MO_DATA = 0x0,
|
||||
NGAP_OVERLOAD_REJECT_ALL_SIGNALLING = 0x1,
|
||||
NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT = 0x2,
|
||||
NGAP_NO_OVERLOAD = 0x3,
|
||||
NGAP_OVERLOAD_MAX,
|
||||
} ngap_overload_state_t;
|
||||
|
||||
/* Served PLMN identity element */
|
||||
struct plmn_identity_s {
|
||||
uint16_t mcc;
|
||||
uint16_t mnc;
|
||||
uint8_t mnc_digit_length;
|
||||
STAILQ_ENTRY(plmn_identity_s) next;
|
||||
};
|
||||
|
||||
/* Served amf region id for a particular AMF */
|
||||
struct served_region_id_s {
|
||||
uint8_t amf_region_id;
|
||||
STAILQ_ENTRY(served_region_id_s) next;
|
||||
};
|
||||
|
||||
/* Served amf set id for a particular AMF */
|
||||
struct amf_set_id_s {
|
||||
uint16_t amf_set_id;
|
||||
STAILQ_ENTRY(amf_set_id_s) next;
|
||||
};
|
||||
|
||||
/* Served amf pointer for a particular AMF */
|
||||
struct amf_pointer_s {
|
||||
uint8_t amf_pointer;
|
||||
STAILQ_ENTRY(amf_pointer_s) next;
|
||||
};
|
||||
|
||||
|
||||
/* Served guami element */
|
||||
struct served_guami_s {
|
||||
/* Number of AMF served PLMNs */
|
||||
uint8_t nb_served_plmns;
|
||||
/* List of served PLMNs by AMF */
|
||||
STAILQ_HEAD(served_plmns_s, plmn_identity_s) served_plmns;
|
||||
|
||||
/* Number of region id in list */
|
||||
uint8_t nb_region_id;
|
||||
/* Served group id list */
|
||||
STAILQ_HEAD(served_region_ids_s, served_region_id_s) served_region_ids;
|
||||
|
||||
/* Number of AMF set id */
|
||||
uint8_t nb_amf_set_id;
|
||||
/* AMF Set id to uniquely identify an AMF within an AMF pool area */
|
||||
STAILQ_HEAD(amf_set_ids_s, amf_set_id_s) amf_set_ids;
|
||||
|
||||
/* Number of AMF pointer */
|
||||
uint8_t nb_amf_pointer;
|
||||
/* AMF pointer to uniquely identify an AMF within an AMF pool area */
|
||||
STAILQ_HEAD(amf_pointers_s, amf_pointer_s) amf_pointers;
|
||||
|
||||
/* Next GUAMI element */
|
||||
STAILQ_ENTRY(served_guami_s) next;
|
||||
};
|
||||
|
||||
/* NSSAI element */
|
||||
struct slice_support_s{
|
||||
uint8_t sST;
|
||||
uint8_t sD_flag;
|
||||
uint8_t sD[3];
|
||||
|
||||
/* Next slice element */
|
||||
STAILQ_ENTRY(slice_support_s) next;
|
||||
};
|
||||
|
||||
|
||||
/* plmn support element */
|
||||
struct plmn_support_s {
|
||||
struct plmn_identity_s plmn_identity;
|
||||
|
||||
/* Number of slice support in list */
|
||||
uint8_t nb_slice_s;
|
||||
/* Served group id list */
|
||||
STAILQ_HEAD(slice_supports_s, slice_support_s) slice_supports;
|
||||
|
||||
/* Next plmn support element */
|
||||
STAILQ_ENTRY(plmn_support_s) next;
|
||||
};
|
||||
|
||||
|
||||
struct ngap_gNB_instance_s;
|
||||
|
||||
/* This structure describes association of a gNB to a AMF */
|
||||
typedef struct ngap_gNB_amf_data_s {
|
||||
/* AMF descriptors tree, ordered by sctp assoc id */
|
||||
RB_ENTRY(ngap_gNB_amf_data_s) entry;
|
||||
|
||||
/* This is the optional name provided by the AMF */
|
||||
char *amf_name;
|
||||
|
||||
/* AMF NGAP IP address */
|
||||
net_ip_address_t amf_s1_ip;
|
||||
|
||||
/* List of served GUAMI per AMF. There is one GUAMI per RAT with a max
|
||||
* number of 8 RATs but in our case only one is used. The LTE related pool
|
||||
* configuration is included on the first place in the list.
|
||||
*/
|
||||
STAILQ_HEAD(served_guamis_s, served_guami_s) served_guami;
|
||||
|
||||
/* Relative processing capacity of an AMF with respect to the other AMFs
|
||||
* in the pool in order to load-balance AMFs within a pool as defined
|
||||
* in TS 23.401.
|
||||
*/
|
||||
uint8_t relative_amf_capacity;
|
||||
|
||||
/*
|
||||
* List of PLMN Support per AMF.
|
||||
*
|
||||
*/
|
||||
STAILQ_HEAD(plmn_supports_s, plmn_support_s) plmn_supports;
|
||||
|
||||
/* Current AMF overload information (if any). */
|
||||
ngap_overload_state_t overload_state;
|
||||
/* Current gNB->AMF NGAP association state */
|
||||
ngap_gNB_state_t state;
|
||||
|
||||
/* Next usable stream for UE signalling */
|
||||
int32_t nextstream;
|
||||
|
||||
/* Number of input/ouput streams */
|
||||
uint16_t in_streams;
|
||||
uint16_t out_streams;
|
||||
|
||||
/* Connexion id used between SCTP/NGAP */
|
||||
uint16_t cnx_id;
|
||||
|
||||
/* SCTP association id */
|
||||
int32_t assoc_id;
|
||||
|
||||
/* This is served PLMN IDs communicated to the AMF via an index over the
|
||||
* MCC/MNC array in ngap_gNB_instance */
|
||||
uint8_t broadcast_plmn_num;
|
||||
uint8_t broadcast_plmn_index[PLMN_LIST_MAX_SIZE];
|
||||
|
||||
|
||||
/* Only meaningfull in virtual mode */
|
||||
struct ngap_gNB_instance_s *ngap_gNB_instance;
|
||||
} ngap_gNB_amf_data_t;
|
||||
|
||||
typedef struct ngap_gNB_NSSAI_s{
|
||||
uint8_t sST;
|
||||
uint8_t sD_flag;
|
||||
uint8_t sD[3];
|
||||
}ngap_gNB_NSSAI_t;
|
||||
|
||||
typedef struct ngap_gNB_instance_s {
|
||||
/* Next ngap gNB association.
|
||||
* Only used for virtual mode.
|
||||
*/
|
||||
STAILQ_ENTRY(ngap_gNB_instance_s) ngap_gNB_entries;
|
||||
|
||||
/* Number of AMF requested by gNB (tree size) */
|
||||
uint32_t ngap_amf_nb;
|
||||
/* Number of AMF for which association is pending */
|
||||
uint32_t ngap_amf_pending_nb;
|
||||
/* Number of AMF successfully associated to gNB */
|
||||
uint32_t ngap_amf_associated_nb;
|
||||
/* Tree of NGAP AMF associations ordered by association ID */
|
||||
RB_HEAD(ngap_amf_map, ngap_gNB_amf_data_s) ngap_amf_head;
|
||||
|
||||
/* TODO: add a map ordered by relative AMF capacity */
|
||||
|
||||
/* Tree of UE ordered by gNB_ue_ngap_id's */
|
||||
RB_HEAD(ngap_ue_map, ngap_gNB_ue_context_s) ngap_ue_head;
|
||||
|
||||
/* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */
|
||||
instance_t instance;
|
||||
|
||||
/* Displayable name of gNB */
|
||||
char *gNB_name;
|
||||
|
||||
/* Unique gNB_id to identify the gNB within EPC.
|
||||
* In our case the gNB is a macro gNB so the id will be 20 bits long.
|
||||
* For Home gNB id, this field should be 36 bits long.
|
||||
*/
|
||||
uint32_t gNB_id;
|
||||
/* The type of the cell */
|
||||
enum cell_type_e cell_type;
|
||||
|
||||
/* Tracking area code */
|
||||
uint32_t tac;
|
||||
|
||||
/* gNB NGAP IP address */
|
||||
net_ip_address_t gNB_ng_ip;
|
||||
|
||||
/* Mobile Country Code
|
||||
* Mobile Network Code
|
||||
*/
|
||||
uint16_t mcc[PLMN_LIST_MAX_SIZE];
|
||||
uint16_t mnc[PLMN_LIST_MAX_SIZE];
|
||||
uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE];
|
||||
uint8_t num_plmn;
|
||||
|
||||
uint16_t num_nssai[PLMN_LIST_MAX_SIZE];
|
||||
ngap_gNB_NSSAI_t s_nssai[PLMN_LIST_MAX_SIZE][8];
|
||||
|
||||
/* Default Paging DRX of the gNB as defined in TS 38.304 */
|
||||
ngap_paging_drx_t default_drx;
|
||||
} ngap_gNB_instance_t;
|
||||
|
||||
typedef struct {
|
||||
/* List of served gNBs
|
||||
* Only used for virtual mode
|
||||
*/
|
||||
STAILQ_HEAD(ngap_gNB_instances_head_s, ngap_gNB_instance_s) ngap_gNB_instances_head;
|
||||
/* Nb of registered gNBs */
|
||||
uint8_t nb_registered_gNBs;
|
||||
|
||||
/* Generate a unique connexion id used between NGAP and SCTP */
|
||||
uint16_t global_cnx_id;
|
||||
} ngap_gNB_internal_data_t;
|
||||
|
||||
int ngap_gNB_compare_assoc_id(
|
||||
struct ngap_gNB_amf_data_s *p1, struct ngap_gNB_amf_data_s *p2);
|
||||
|
||||
/* Generate the tree management functions */
|
||||
RB_PROTOTYPE(ngap_amf_map, ngap_gNB_amf_data_s, entry,
|
||||
ngap_gNB_compare_assoc_id);
|
||||
|
||||
#endif /* NGAP_GNB_DEFS_H_ */
|
||||
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* 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 ngap_gNB_encoder.c
|
||||
* \brief ngap pdu encode procedures for gNB
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "ngap_common.h"
|
||||
#include "ngap_gNB_encoder.h"
|
||||
|
||||
static inline int ngap_gNB_encode_initiating(NGAP_NGAP_PDU_t *pdu,
|
||||
uint8_t **buffer,
|
||||
uint32_t *len);
|
||||
|
||||
static inline int ngap_gNB_encode_successfull_outcome(NGAP_NGAP_PDU_t *pdu,
|
||||
uint8_t **buffer, uint32_t *len);
|
||||
|
||||
static inline int ngap_gNB_encode_unsuccessfull_outcome(NGAP_NGAP_PDU_t *pdu,
|
||||
uint8_t **buffer, uint32_t *len);
|
||||
|
||||
int ngap_gNB_encode_pdu(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) {
|
||||
int ret = -1;
|
||||
DevAssert(pdu != NULL);
|
||||
DevAssert(buffer != NULL);
|
||||
DevAssert(len != NULL);
|
||||
|
||||
switch(pdu->present) {
|
||||
case NGAP_NGAP_PDU_PR_initiatingMessage:
|
||||
ret = ngap_gNB_encode_initiating(pdu, buffer, len);
|
||||
break;
|
||||
|
||||
case NGAP_NGAP_PDU_PR_successfulOutcome:
|
||||
ret = ngap_gNB_encode_successfull_outcome(pdu, buffer, len);
|
||||
break;
|
||||
|
||||
case NGAP_NGAP_PDU_PR_unsuccessfulOutcome:
|
||||
ret = ngap_gNB_encode_unsuccessfull_outcome(pdu, buffer, len);
|
||||
break;
|
||||
|
||||
default:
|
||||
NGAP_DEBUG("Unknown message outcome (%d) or not implemented",
|
||||
(int)pdu->present);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline
|
||||
int ngap_gNB_encode_initiating(NGAP_NGAP_PDU_t *pdu,
|
||||
uint8_t **buffer, uint32_t *len) {
|
||||
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
switch(pdu->choice.initiatingMessage->procedureCode) {
|
||||
case NGAP_ProcedureCode_id_NGSetup:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_UplinkNASTransport:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_UERadioCapabilityInfoIndication:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_InitialUEMessage:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_NASNonDeliveryIndication:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_UEContextReleaseRequest:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PathSwitchRequest:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PDUSessionResourceModifyIndication:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
NGAP_DEBUG("Unknown procedure ID (%d) for initiating message\n",
|
||||
(int)pdu->choice.initiatingMessage->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (asn1_xer_print) {
|
||||
xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, (void *)pdu);
|
||||
}
|
||||
|
||||
memset(&res, 0, sizeof(res));
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
*buffer = res.buffer;
|
||||
*len = res.result.encoded;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
int ngap_gNB_encode_successfull_outcome(NGAP_NGAP_PDU_t *pdu,
|
||||
uint8_t **buffer, uint32_t *len) {
|
||||
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
switch(pdu->choice.successfulOutcome->procedureCode) {
|
||||
case NGAP_ProcedureCode_id_InitialContextSetup:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_UEContextRelease:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PDUSessionResourceSetup:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("PDUSESSIONSetup successful message\n");
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PDUSessionResourceModify:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("PDUSESSIONModify successful message\n");
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PDUSessionResourceRelease:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("PDUSESSION Release successful message\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
NGAP_WARN("Unknown procedure ID (%d) for successfull outcome message\n",
|
||||
(int)pdu->choice.successfulOutcome->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (asn1_xer_print) {
|
||||
xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, (void *)pdu);
|
||||
}
|
||||
|
||||
memset(&res, 0, sizeof(res));
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
*buffer = res.buffer;
|
||||
*len = res.result.encoded;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
int ngap_gNB_encode_unsuccessfull_outcome(NGAP_NGAP_PDU_t *pdu,
|
||||
uint8_t **buffer, uint32_t *len) {
|
||||
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
switch(pdu->choice.unsuccessfulOutcome->procedureCode) {
|
||||
case NGAP_ProcedureCode_id_InitialContextSetup:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
NGAP_DEBUG("Unknown procedure ID (%d) for unsuccessfull outcome message\n",
|
||||
(int)pdu->choice.unsuccessfulOutcome->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (asn1_xer_print) {
|
||||
xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, (void *)pdu);
|
||||
}
|
||||
|
||||
memset(&res, 0, sizeof(res));
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
*buffer = res.buffer;
|
||||
*len = res.result.encoded;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 ngap_gNB_encoder.h
|
||||
* \brief ngap pdu encode procedures for gNB
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
*/
|
||||
|
||||
#ifndef NGAP_GNB_ENCODER_H_
|
||||
#define NGAP_GNB_ENCODER_H_
|
||||
|
||||
int ngap_gNB_encode_pdu(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
|
||||
__attribute__ ((warn_unused_result));
|
||||
|
||||
#endif /* NGAP_GNB_ENCODER_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 ngap_gNB_handlers.h
|
||||
* \brief ngap messages handlers for gNB part
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
*/
|
||||
|
||||
#ifndef NGAP_GNB_HANDLERS_H_
|
||||
#define NGAP_GNB_HANDLERS_H_
|
||||
|
||||
void ngap_handle_ng_setup_message(ngap_gNB_amf_data_t *amf_desc_p, int sctp_shutdown);
|
||||
|
||||
int ngap_gNB_handle_message(uint32_t assoc_id, int32_t stream,
|
||||
const uint8_t * const data, const uint32_t data_length);
|
||||
|
||||
#endif /* NGAP_GNB_HANDLERS_H_ */
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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 ngap_gNB_itti_messaging.c
|
||||
* \brief ngap itti messages handlers for gNB
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
*/
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "ngap_gNB_itti_messaging.h"
|
||||
|
||||
void ngap_gNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
|
||||
uint32_t buffer_length, uint16_t stream)
|
||||
{
|
||||
MessageDef *message_p;
|
||||
sctp_data_req_t *sctp_data_req;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_NGAP, 0, SCTP_DATA_REQ);
|
||||
|
||||
sctp_data_req = &message_p->ittiMsg.sctp_data_req;
|
||||
|
||||
sctp_data_req->assoc_id = assoc_id;
|
||||
sctp_data_req->buffer = buffer;
|
||||
sctp_data_req->buffer_length = buffer_length;
|
||||
sctp_data_req->stream = stream;
|
||||
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
}
|
||||
|
||||
void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance,
|
||||
uint16_t ue_initial_id,
|
||||
uint32_t gNB_ue_ngap_id,
|
||||
uint8_t *nas_pdu,
|
||||
uint32_t nas_pdu_length)
|
||||
{
|
||||
MessageDef *message_p;
|
||||
ngap_downlink_nas_t *ngap_downlink_nas;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_DOWNLINK_NAS);
|
||||
|
||||
ngap_downlink_nas = &message_p->ittiMsg.ngap_downlink_nas;
|
||||
|
||||
ngap_downlink_nas->ue_initial_id = ue_initial_id;
|
||||
ngap_downlink_nas->gNB_ue_ngap_id = gNB_ue_ngap_id;
|
||||
ngap_downlink_nas->nas_pdu.buffer = malloc(sizeof(uint8_t) * nas_pdu_length);
|
||||
memcpy(ngap_downlink_nas->nas_pdu.buffer, nas_pdu, nas_pdu_length);
|
||||
ngap_downlink_nas->nas_pdu.length = nas_pdu_length;
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p);
|
||||
}
|
||||
|
||||
void ngap_gNB_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id)
|
||||
{
|
||||
MessageDef *message_p = NULL;
|
||||
sctp_close_association_t *sctp_close_association_p = NULL;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_NGAP, 0, SCTP_CLOSE_ASSOCIATION);
|
||||
sctp_close_association_p = &message_p->ittiMsg.sctp_close_association;
|
||||
sctp_close_association_p->assoc_id = assoc_id;
|
||||
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 ngap_gNB_itti_messaging.h
|
||||
* \brief ngap itti messages handlers for gNB
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
*/
|
||||
|
||||
#ifndef NGAP_GNB_ITTI_MESSAGING_H_
|
||||
#define NGAP_GNB_ITTI_MESSAGING_H_
|
||||
|
||||
void ngap_gNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
|
||||
uint32_t buffer_length, uint16_t stream);
|
||||
|
||||
void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance,
|
||||
uint16_t ue_initial_id,
|
||||
uint32_t gNB_ue_ngap_id,
|
||||
uint8_t *nas_pdu,
|
||||
uint32_t nas_pdu_length);
|
||||
|
||||
void ngap_gNB_itti_send_sctp_close_association(instance_t instance,
|
||||
int32_t assoc_id);
|
||||
|
||||
|
||||
#endif /* NGAP_GNB_ITTI_MESSAGING_H_ */
|
||||
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* 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 ngap_gNB_management_procedures.c
|
||||
* \brief NGAP gNB task
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \date 2020
|
||||
* \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \version 1.0
|
||||
* @ingroup _ngap
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
|
||||
#include "ngap_common.h"
|
||||
#include "ngap_gNB_defs.h"
|
||||
#include "ngap_gNB.h"
|
||||
|
||||
ngap_gNB_internal_data_t ngap_gNB_internal_data;
|
||||
|
||||
RB_GENERATE(ngap_amf_map, ngap_gNB_amf_data_s, entry, ngap_gNB_compare_assoc_id);
|
||||
|
||||
int ngap_gNB_compare_assoc_id(
|
||||
struct ngap_gNB_amf_data_s *p1, struct ngap_gNB_amf_data_s *p2)
|
||||
{
|
||||
if (p1->assoc_id == -1) {
|
||||
if (p1->cnx_id < p2->cnx_id) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (p1->cnx_id > p2->cnx_id) {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (p1->assoc_id < p2->assoc_id) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (p1->assoc_id > p2->assoc_id) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Matching reference */
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t ngap_gNB_fetch_add_global_cnx_id(void)
|
||||
{
|
||||
return ++ngap_gNB_internal_data.global_cnx_id;
|
||||
}
|
||||
|
||||
void ngap_gNB_prepare_internal_data(void)
|
||||
{
|
||||
memset(&ngap_gNB_internal_data, 0, sizeof(ngap_gNB_internal_data));
|
||||
STAILQ_INIT(&ngap_gNB_internal_data.ngap_gNB_instances_head);
|
||||
}
|
||||
|
||||
void ngap_gNB_insert_new_instance(ngap_gNB_instance_t *new_instance_p)
|
||||
{
|
||||
DevAssert(new_instance_p != NULL);
|
||||
|
||||
STAILQ_INSERT_TAIL(&ngap_gNB_internal_data.ngap_gNB_instances_head,
|
||||
new_instance_p, ngap_gNB_entries);
|
||||
}
|
||||
|
||||
struct ngap_gNB_amf_data_s *ngap_gNB_get_AMF(
|
||||
ngap_gNB_instance_t *instance_p,
|
||||
int32_t assoc_id, uint16_t cnx_id)
|
||||
{
|
||||
struct ngap_gNB_amf_data_s temp;
|
||||
struct ngap_gNB_amf_data_s *found;
|
||||
|
||||
memset(&temp, 0, sizeof(struct ngap_gNB_amf_data_s));
|
||||
|
||||
temp.assoc_id = assoc_id;
|
||||
temp.cnx_id = cnx_id;
|
||||
|
||||
if (instance_p == NULL) {
|
||||
STAILQ_FOREACH(instance_p, &ngap_gNB_internal_data.ngap_gNB_instances_head,
|
||||
ngap_gNB_entries) {
|
||||
found = RB_FIND(ngap_amf_map, &instance_p->ngap_amf_head, &temp);
|
||||
|
||||
if (found != NULL) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return RB_FIND(ngap_amf_map, &instance_p->ngap_amf_head, &temp);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ngap_gNB_amf_data_s *ngap_gNB_get_AMF_from_instance(
|
||||
ngap_gNB_instance_t *instance_p)
|
||||
{
|
||||
|
||||
struct ngap_gNB_amf_data_s *amf = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf_next = NULL;
|
||||
|
||||
for (amf = RB_MIN(ngap_amf_map, &instance_p->ngap_amf_head); amf!=NULL ; amf = amf_next) {
|
||||
amf_next = RB_NEXT(ngap_amf_map, &instance_p->ngap_amf_head, amf);
|
||||
if (amf->ngap_gNB_instance == instance_p) {
|
||||
return amf;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ngap_gNB_instance_t *ngap_gNB_get_instance(instance_t instance)
|
||||
{
|
||||
ngap_gNB_instance_t *temp = NULL;
|
||||
|
||||
STAILQ_FOREACH(temp, &ngap_gNB_internal_data.ngap_gNB_instances_head,
|
||||
ngap_gNB_entries) {
|
||||
if (temp->instance == instance) {
|
||||
/* Matching occurence */
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ngap_gNB_remove_amf_desc(ngap_gNB_instance_t * instance)
|
||||
{
|
||||
|
||||
struct ngap_gNB_amf_data_s *amf = NULL;
|
||||
struct ngap_gNB_amf_data_s *amfNext = NULL;
|
||||
struct plmn_identity_s* plmnInfo;
|
||||
struct served_region_id_s* regionInfo;
|
||||
struct served_guami_s* guamInfo;
|
||||
struct amf_set_id_s* amfSet;
|
||||
struct amf_pointer_s* amfPoint;
|
||||
for (amf = RB_MIN(ngap_amf_map, &instance->ngap_amf_head); amf; amf = amfNext) {
|
||||
amfNext = RB_NEXT(ngap_amf_map, &instance->ngap_amf_head, amf);
|
||||
RB_REMOVE(ngap_amf_map, &instance->ngap_amf_head, amf);
|
||||
while (!STAILQ_EMPTY(&amf->served_guami)) {
|
||||
guamInfo = STAILQ_FIRST(&amf->served_guami);
|
||||
STAILQ_REMOVE_HEAD(&amf->served_guami, next);
|
||||
|
||||
while (!STAILQ_EMPTY(&guamInfo->served_plmns)) {
|
||||
plmnInfo = STAILQ_FIRST(&guamInfo->served_plmns);
|
||||
STAILQ_REMOVE_HEAD(&guamInfo->served_plmns, next);
|
||||
free(plmnInfo);
|
||||
}
|
||||
while (!STAILQ_EMPTY(&guamInfo->served_region_ids)) {
|
||||
regionInfo = STAILQ_FIRST(&guamInfo->served_region_ids);
|
||||
STAILQ_REMOVE_HEAD(&guamInfo->served_region_ids, next);
|
||||
free(regionInfo);
|
||||
}
|
||||
while (!STAILQ_EMPTY(&guamInfo->amf_set_ids)) {
|
||||
amfSet = STAILQ_FIRST(&guamInfo->amf_set_ids);
|
||||
STAILQ_REMOVE_HEAD(&guamInfo->amf_set_ids, next);
|
||||
free(amfSet);
|
||||
}
|
||||
while (!STAILQ_EMPTY(&guamInfo->amf_pointers)) {
|
||||
amfPoint = STAILQ_FIRST(&guamInfo->amf_pointers);
|
||||
STAILQ_REMOVE_HEAD(&guamInfo->amf_pointers, next);
|
||||
free(amfPoint);
|
||||
}
|
||||
free(guamInfo);
|
||||
}
|
||||
free(amf);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 ngap_gNB_management_procedures.h
|
||||
* \brief NGAP gNB task
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \date 2020
|
||||
* \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \version 1.0
|
||||
* @ingroup _ngap
|
||||
*/
|
||||
|
||||
#ifndef NGAP_GNB_MANAGEMENT_PROCEDURES_H_
|
||||
#define NGAP_GNB_MANAGEMENT_PROCEDURES_H_
|
||||
|
||||
struct ngap_gNB_amf_data_s *ngap_gNB_get_AMF(
|
||||
ngap_gNB_instance_t *instance_p,
|
||||
int32_t assoc_id, uint16_t cnx_id);
|
||||
|
||||
struct ngap_gNB_amf_data_s *ngap_gNB_get_AMF_from_instance(ngap_gNB_instance_t *instance_p);
|
||||
|
||||
void ngap_gNB_remove_amf_desc(ngap_gNB_instance_t * instance);
|
||||
|
||||
void ngap_gNB_insert_new_instance(ngap_gNB_instance_t *new_instance_p);
|
||||
|
||||
ngap_gNB_instance_t *ngap_gNB_get_instance(uint8_t mod_id);
|
||||
|
||||
uint16_t ngap_gNB_fetch_add_global_cnx_id(void);
|
||||
|
||||
void ngap_gNB_prepare_internal_data(void);
|
||||
|
||||
#endif /* NGAP_GNB_MANAGEMENT_PROCEDURES_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 ngap_gNB_nas_procedures.h
|
||||
* \brief NGAP gNb NAS procedure handler
|
||||
* \author Yoshio INOUE, Masayuki HARADA
|
||||
* \date 2020
|
||||
* \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
|
||||
* \version 1.0
|
||||
* @ingroup _ngap
|
||||
*/
|
||||
|
||||
#ifndef NGAP_GNB_NAS_PROCEDURES_H_
|
||||
#define NGAP_GNB_NAS_PROCEDURES_H_
|
||||
|
||||
int ngap_gNB_handle_nas_downlink(
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
NGAP_NGAP_PDU_t *pdu);
|
||||
|
||||
int ngap_gNB_nas_uplink(instance_t instance, ngap_uplink_nas_t *ngap_uplink_nas_p);
|
||||
|
||||
int ngap_gNB_nas_non_delivery_ind(instance_t instance,
|
||||
ngap_nas_non_delivery_ind_t *ngap_nas_non_delivery_ind);
|
||||
|
||||
int ngap_gNB_handle_nas_first_req(
|
||||
instance_t instance, ngap_nas_first_req_t *ngap_nas_first_req_p);
|
||||
|
||||
int ngap_gNB_initial_ctxt_resp(
|
||||
instance_t instance, ngap_initial_context_setup_resp_t *initial_ctxt_resp_p);
|
||||
|
||||
int ngap_gNB_ue_capabilities(instance_t instance,
|
||||
ngap_ue_cap_info_ind_t *ue_cap_info_ind_p);
|
||||
|
||||
int ngap_gNB_pdusession_setup_resp(instance_t instance,
|
||||
ngap_pdusession_setup_resp_t *pdusession_setup_resp_p);
|
||||
|
||||
int ngap_gNB_pdusession_modify_resp(instance_t instance,
|
||||
ngap_pdusession_modify_resp_t *pdusession_modify_resp_p);
|
||||
|
||||
int ngap_gNB_pdusession_release_resp(instance_t instance,
|
||||
ngap_pdusession_release_resp_t *pdusession_release_resp_p);
|
||||
|
||||
int ngap_gNB_path_switch_req(instance_t instance,
|
||||
ngap_path_switch_req_t *path_switch_req_p);
|
||||
|
||||
int ngap_gNB_generate_PDUSESSION_Modification_Indication(
|
||||
instance_t instance, ngap_pdusession_modification_ind_t *pdusession_modification_ind);
|
||||
|
||||
#endif /* NGAP_GNB_NAS_PROCEDURES_H_ */
|
||||
@@ -0,0 +1,410 @@
|
||||
/*
|
||||
* 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 ngap_gNB_nnsf.c
|
||||
* \brief ngap NAS node selection functions
|
||||
* \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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "ngap_common.h"
|
||||
|
||||
#include "ngap_gNB_defs.h"
|
||||
#include "ngap_gNB_nnsf.h"
|
||||
|
||||
struct ngap_gNB_amf_data_s *
|
||||
ngap_gNB_nnsf_select_amf(ngap_gNB_instance_t *instance_p,
|
||||
ngap_rrc_establishment_cause_t cause)
|
||||
{
|
||||
struct ngap_gNB_amf_data_s *amf_data_p = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf_highest_capacity_p = NULL;
|
||||
uint8_t current_capacity = 0;
|
||||
|
||||
RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) {
|
||||
if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between AMF and gNB is not ready for the moment,
|
||||
* go to the next known AMF.
|
||||
*/
|
||||
if (amf_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* AMF is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this AMF depending on
|
||||
* the overload state.
|
||||
*/
|
||||
if ((cause == NGAP_RRC_CAUSE_MO_DATA)
|
||||
&& (amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING)
|
||||
&& ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT)
|
||||
&& ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA)
|
||||
|| (cause == NGAP_RRC_CAUSE_HIGH_PRIO_ACCESS))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* At this point, the RRC establishment can be handled by the AMF
|
||||
* even if it is in overload state.
|
||||
*/
|
||||
} else {
|
||||
/* The AMF is not overloaded, association is simply not ready. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_capacity < amf_data_p->relative_amf_capacity) {
|
||||
/* We find a better AMF, keep a reference to it */
|
||||
current_capacity = amf_data_p->relative_amf_capacity;
|
||||
amf_highest_capacity_p = amf_data_p;
|
||||
}
|
||||
}
|
||||
|
||||
return amf_highest_capacity_p;
|
||||
}
|
||||
|
||||
struct ngap_gNB_amf_data_s *
|
||||
ngap_gNB_nnsf_select_amf_by_plmn_id(ngap_gNB_instance_t *instance_p,
|
||||
ngap_rrc_establishment_cause_t cause,
|
||||
int selected_plmn_identity)
|
||||
{
|
||||
struct ngap_gNB_amf_data_s *amf_data_p = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf_highest_capacity_p = NULL;
|
||||
uint8_t current_capacity = 0;
|
||||
|
||||
RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) {
|
||||
struct served_guami_s *guami_p = NULL;
|
||||
struct plmn_identity_s *served_plmn_p = NULL;
|
||||
if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between AMF and gNB is not ready for the moment,
|
||||
* go to the next known AMF.
|
||||
*/
|
||||
if (amf_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* AMF is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this AMF depending on
|
||||
* the overload state.
|
||||
*/
|
||||
if ((cause == NGAP_RRC_CAUSE_MO_DATA)
|
||||
&& (amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING)
|
||||
&& ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT)
|
||||
&& ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA)
|
||||
|| (cause == NGAP_RRC_CAUSE_HIGH_PRIO_ACCESS))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* At this point, the RRC establishment can be handled by the AMF
|
||||
* even if it is in overload state.
|
||||
*/
|
||||
} else {
|
||||
/* The AMF is not overloaded, association is simply not ready. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Looking for served GUAMI PLMN Identity selected matching the one provided by the UE */
|
||||
STAILQ_FOREACH(guami_p, &amf_data_p->served_guami, next) {
|
||||
STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) {
|
||||
if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) &&
|
||||
(served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* if found, we can stop the outer loop, too */
|
||||
if (served_plmn_p) break;
|
||||
}
|
||||
/* if we didn't find such a served PLMN, go on with the next AMF */
|
||||
if (!served_plmn_p) continue;
|
||||
|
||||
if (current_capacity < amf_data_p->relative_amf_capacity) {
|
||||
/* We find a better AMF, keep a reference to it */
|
||||
current_capacity = amf_data_p->relative_amf_capacity;
|
||||
amf_highest_capacity_p = amf_data_p;
|
||||
}
|
||||
}
|
||||
|
||||
return amf_highest_capacity_p;
|
||||
}
|
||||
|
||||
struct ngap_gNB_amf_data_s *
|
||||
ngap_gNB_nnsf_select_amf_by_amf_setid(ngap_gNB_instance_t *instance_p,
|
||||
ngap_rrc_establishment_cause_t cause,
|
||||
int selected_plmn_identity,
|
||||
uint8_t amf_setid)
|
||||
{
|
||||
struct ngap_gNB_amf_data_s *amf_data_p = NULL;
|
||||
|
||||
RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) {
|
||||
struct served_guami_s *guami_p = NULL;
|
||||
|
||||
if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between AMF and gNB is not ready for the moment,
|
||||
* go to the next known AMF.
|
||||
*/
|
||||
if (amf_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* AMF is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this AMF depending on
|
||||
* the overload state.
|
||||
*/
|
||||
if ((cause == NGAP_RRC_CAUSE_MO_DATA)
|
||||
&& (amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING)
|
||||
&& ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT)
|
||||
&& ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA)
|
||||
|| (cause == NGAP_RRC_CAUSE_HIGH_PRIO_ACCESS))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* At this point, the RRC establishment can be handled by the AMF
|
||||
* even if it is in overload state.
|
||||
*/
|
||||
} else {
|
||||
/* The AMF is not overloaded, association is simply not ready. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Looking for AMF code matching the one provided by NAS */
|
||||
STAILQ_FOREACH(guami_p, &amf_data_p->served_guami, next) {
|
||||
struct amf_set_id_s *amf_setid_p = NULL;
|
||||
struct plmn_identity_s *served_plmn_p = NULL;
|
||||
|
||||
STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) {
|
||||
if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) &&
|
||||
(served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
STAILQ_FOREACH(amf_setid_p, &guami_p->amf_set_ids, next) {
|
||||
if (amf_setid_p->amf_set_id == amf_setid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The AMF matches the parameters provided by the NAS layer ->
|
||||
* the AMF is knwown and the association is ready.
|
||||
* Return the reference to the AMF to use it for this UE.
|
||||
*/
|
||||
if (amf_setid_p && served_plmn_p) {
|
||||
return amf_data_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point no AMF matches the selected PLMN and AMF code. In this case,
|
||||
* return NULL. That way the RRC layer should know about it and reject RRC
|
||||
* connectivity. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ngap_gNB_amf_data_s *
|
||||
ngap_gNB_nnsf_select_amf_by_guami(ngap_gNB_instance_t *instance_p,
|
||||
ngap_rrc_establishment_cause_t cause,
|
||||
ngap_guami_t guami)
|
||||
{
|
||||
struct ngap_gNB_amf_data_s *amf_data_p = NULL;
|
||||
|
||||
RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) {
|
||||
struct served_guami_s *guami_p = NULL;
|
||||
|
||||
if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between AMF and gNB is not ready for the moment,
|
||||
* go to the next known AMF.
|
||||
*/
|
||||
if (amf_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* AMF is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this AMF depending on
|
||||
* the overload state.
|
||||
*/
|
||||
if ((cause == NGAP_RRC_CAUSE_MO_DATA)
|
||||
&& (amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING)
|
||||
&& ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT)
|
||||
&& ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA)
|
||||
|| (cause == NGAP_RRC_CAUSE_HIGH_PRIO_ACCESS))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* At this point, the RRC establishment can be handled by the AMF
|
||||
* even if it is in overload state.
|
||||
*/
|
||||
} else {
|
||||
/* The AMF is not overloaded, association is simply not ready. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Looking for AMF guami matching the one provided by NAS */
|
||||
STAILQ_FOREACH(guami_p, &amf_data_p->served_guami, next) {
|
||||
struct served_region_id_s *region_id_p = NULL;
|
||||
struct amf_set_id_s *amf_set_id_p = NULL;
|
||||
struct amf_pointer_s *pointer_p = NULL;
|
||||
struct plmn_identity_s *served_plmn_p = NULL;
|
||||
|
||||
STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) {
|
||||
if ((served_plmn_p->mcc == guami.mcc) &&
|
||||
(served_plmn_p->mnc == guami.mnc)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
STAILQ_FOREACH(region_id_p, &guami_p->served_region_ids, next) {
|
||||
if (region_id_p->amf_region_id == guami.amf_region_id) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
STAILQ_FOREACH(amf_set_id_p, &guami_p->amf_set_ids, next) {
|
||||
if (amf_set_id_p->amf_set_id == guami.amf_set_id) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
STAILQ_FOREACH(pointer_p, &guami_p->amf_pointers, next) {
|
||||
if (pointer_p->amf_pointer == guami.amf_pointer) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The AMF matches the parameters provided by the NAS layer ->
|
||||
* the AMF is knwown and the association is ready.
|
||||
* Return the reference to the AMF to use it for this UE.
|
||||
*/
|
||||
if ((region_id_p != NULL) &&
|
||||
(amf_set_id_p != NULL) &&
|
||||
(pointer_p != NULL) &&
|
||||
(served_plmn_p != NULL)) {
|
||||
return amf_data_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point no AMF matches the provided GUAMI. In this case, return
|
||||
* NULL. That way the RRC layer should know about it and reject RRC
|
||||
* connectivity. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct ngap_gNB_amf_data_s *
|
||||
ngap_gNB_nnsf_select_amf_by_guami_no_cause(ngap_gNB_instance_t *instance_p,
|
||||
ngap_guami_t guami)
|
||||
{
|
||||
struct ngap_gNB_amf_data_s *amf_data_p = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf_highest_capacity_p = NULL;
|
||||
uint8_t current_capacity = 0;
|
||||
|
||||
|
||||
RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) {
|
||||
struct served_guami_s *guami_p = NULL;
|
||||
|
||||
if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between AMF and gNB is not ready for the moment,
|
||||
* go to the next known AMF.
|
||||
*/
|
||||
if (amf_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* AMF is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this AMF depending on
|
||||
* the overload state.
|
||||
*/
|
||||
} else {
|
||||
/* The AMF is not overloaded, association is simply not ready. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_capacity < amf_data_p->relative_amf_capacity) {
|
||||
/* We find a better AMF, keep a reference to it */
|
||||
current_capacity = amf_data_p->relative_amf_capacity;
|
||||
amf_highest_capacity_p = amf_data_p;
|
||||
}
|
||||
|
||||
/* Looking for AMF guami matching the one provided by NAS */
|
||||
STAILQ_FOREACH(guami_p, &amf_data_p->served_guami, next) {
|
||||
struct served_region_id_s *region_id_p = NULL;
|
||||
struct amf_set_id_s *amf_set_id_p = NULL;
|
||||
struct plmn_identity_s *served_plmn_p = NULL;
|
||||
|
||||
STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) {
|
||||
if ((served_plmn_p->mcc == guami.mcc) &&
|
||||
(served_plmn_p->mnc == guami.mnc)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
STAILQ_FOREACH(amf_set_id_p, &guami_p->amf_set_ids, next) {
|
||||
if (amf_set_id_p->amf_set_id == guami.amf_set_id) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
STAILQ_FOREACH(region_id_p, &guami_p->served_region_ids, next) {
|
||||
if (region_id_p->amf_region_id == guami.amf_region_id) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The AMF matches the parameters provided by the NAS layer ->
|
||||
* the AMF is knwown and the association is ready.
|
||||
* Return the reference to the AMF to use it for this UE.
|
||||
*/
|
||||
if ((region_id_p != NULL) &&
|
||||
(amf_set_id_p != NULL) &&
|
||||
(served_plmn_p != NULL)) {
|
||||
return amf_data_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point no AMF matches the provided GUAMI. Select the one with the
|
||||
* highest relative capacity.
|
||||
* In case the list of known AMF is empty, simply return NULL, that way the RRC
|
||||
* layer should know about it and reject RRC connectivity.
|
||||
*/
|
||||
|
||||
return amf_highest_capacity_p;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 ngap_gNB_nnsf.h
|
||||
* \brief ngap NAS node selection functions
|
||||
* \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)
|
||||
*/
|
||||
|
||||
#ifndef NGAP_GNB_NNSF_H_
|
||||
#define NGAP_GNB_NNSF_H_
|
||||
|
||||
struct ngap_gNB_amf_data_s *
|
||||
ngap_gNB_nnsf_select_amf(ngap_gNB_instance_t *instance_p,
|
||||
ngap_rrc_establishment_cause_t cause);
|
||||
|
||||
struct ngap_gNB_amf_data_s *
|
||||
ngap_gNB_nnsf_select_amf_by_plmn_id(ngap_gNB_instance_t *instance_p,
|
||||
ngap_rrc_establishment_cause_t cause,
|
||||
int selected_plmn_identity);
|
||||
|
||||
struct ngap_gNB_amf_data_s*
|
||||
ngap_gNB_nnsf_select_amf_by_amf_setid(ngap_gNB_instance_t *instance_p,
|
||||
ngap_rrc_establishment_cause_t cause,
|
||||
int selected_plmn_identity,
|
||||
uint8_t amf_setid);
|
||||
|
||||
struct ngap_gNB_amf_data_s*
|
||||
ngap_gNB_nnsf_select_amf_by_guami(ngap_gNB_instance_t *instance_p,
|
||||
ngap_rrc_establishment_cause_t cause,
|
||||
ngap_guami_t guami);
|
||||
|
||||
struct ngap_gNB_amf_data_s*
|
||||
ngap_gNB_nnsf_select_amf_by_guami_no_cause(ngap_gNB_instance_t *instance_p,
|
||||
ngap_guami_t guami);
|
||||
|
||||
#endif /* NGAP_GNB_NNSF_H_ */
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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 ngap_gNB_overload.c
|
||||
* \brief ngap procedures for overload messages within gNB
|
||||
* \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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "ngap_common.h"
|
||||
#include "ngap_gNB_defs.h"
|
||||
|
||||
#include "ngap_gNB.h"
|
||||
#include "ngap_gNB_ue_context.h"
|
||||
#include "ngap_gNB_encoder.h"
|
||||
#include "ngap_gNB_overload.h"
|
||||
#include "ngap_gNB_management_procedures.h"
|
||||
|
||||
#include "assertions.h"
|
||||
|
||||
int ngap_gNB_handle_overload_start(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
NGAP_NGAP_PDU_t *pdu)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ngap_gNB_handle_overload_stop(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
NGAP_NGAP_PDU_t *pdu)
|
||||
{
|
||||
/* We received Overload stop message, meaning that the AMF is no more
|
||||
* overloaded. This is an empty message, with only message header and no
|
||||
* Information Element.
|
||||
*/
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
ngap_gNB_amf_data_t *amf_desc_p;
|
||||
|
||||
/* Non UE-associated signalling -> stream 0 */
|
||||
DevCheck(stream == 0, stream, 0, 0);
|
||||
|
||||
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
|
||||
/* No AMF context associated */
|
||||
return -1;
|
||||
}
|
||||
|
||||
amf_desc_p->state = NGAP_GNB_STATE_CONNECTED;
|
||||
amf_desc_p->overload_state = NGAP_NO_OVERLOAD;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 ngap_gNB_overload.h
|
||||
* \brief ngap procedures for overload messages within gNB
|
||||
* \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)
|
||||
*/
|
||||
|
||||
#ifndef NGAP_GNB_OVERLOAD_H_
|
||||
#define NGAP_GNB_OVERLOAD_H_
|
||||
|
||||
/**
|
||||
* \brief Handle an overload start message
|
||||
**/
|
||||
// int ngap_gNB_handle_overload_start(gNB_amf_desc_t *gNB_desc_p,
|
||||
// sctp_queue_item_t *packet_p,
|
||||
// struct ngap_message_s *message_p);
|
||||
int ngap_gNB_handle_overload_start(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
NGAP_NGAP_PDU_t *pdu);
|
||||
|
||||
/**
|
||||
* \brief Handle an overload stop message
|
||||
**/
|
||||
// int ngap_gNB_handle_overload_stop(gNB_amf_desc_t *gNB_desc_p,
|
||||
// sctp_queue_item_t *packet_p,
|
||||
// struct ngap_message_s *message_p);
|
||||
int ngap_gNB_handle_overload_stop(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
NGAP_NGAP_PDU_t *pdu);
|
||||
|
||||
#endif /* NGAP_GNB_OVERLOAD_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 ngap_gNB_trace.c
|
||||
* \brief ngap trace procedures for gNB
|
||||
* \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 <stdint.h>
|
||||
|
||||
#include "assertions.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "ngap_gNB_default_values.h"
|
||||
|
||||
#include "ngap_common.h"
|
||||
#include "ngap_gNB_defs.h"
|
||||
|
||||
#include "ngap_gNB.h"
|
||||
#include "ngap_gNB_ue_context.h"
|
||||
#include "ngap_gNB_encoder.h"
|
||||
#include "ngap_gNB_trace.h"
|
||||
#include "ngap_gNB_itti_messaging.h"
|
||||
#include "ngap_gNB_management_procedures.h"
|
||||
|
||||
|
||||
int ngap_gNB_handle_trace_start(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
NGAP_NGAP_PDU_t *pdu)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ngap_gNB_handle_deactivate_trace(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
NGAP_NGAP_PDU_t *message_p)
|
||||
{
|
||||
// NGAP_DeactivateTraceIEs_t *deactivate_trace_p;
|
||||
//
|
||||
// deactivate_trace_p = &message_p->msg.deactivateTraceIEs;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -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 ngap_gNB_trace.h
|
||||
* \brief ngap trace procedures for gNB
|
||||
* \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)
|
||||
*/
|
||||
|
||||
#ifndef NGAP_GNB_TRACE_H_
|
||||
#define NGAP_GNB_TRACE_H_
|
||||
|
||||
// int ngap_gNB_generate_trace_failure(sctp_data_t *sctp_data_p,
|
||||
// int32_t stream,
|
||||
// uint32_t gNB_ue_ngap_id,
|
||||
// uint32_t amf_ue_ngap_id,
|
||||
// E_UTRAN_Trace_ID_t *trace_id,
|
||||
// Cause_t *cause_p);
|
||||
|
||||
// int ngap_gNB_handle_trace_start(gNB_amf_desc_t *gNB_desc_p,
|
||||
// sctp_queue_item_t *packet_p,
|
||||
// struct ngap_message_s *message_p);
|
||||
int ngap_gNB_handle_trace_start(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
NGAP_NGAP_PDU_t *pdu);
|
||||
|
||||
// int ngap_gNB_handle_deactivate_trace(gNB_amf_desc_t *gNB_desc_p,
|
||||
// sctp_queue_item_t *packet_p,
|
||||
// struct ngap_message_s *message_p);
|
||||
int ngap_gNB_handle_deactivate_trace(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
NGAP_NGAP_PDU_t *pdu);
|
||||
|
||||
#endif /* NGAP_GNB_TRACE_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
|
||||
*/
|
||||
|
||||
/*! \file ngap_gNB_ue_context.c
|
||||
* \brief ngap UE context management within gNB
|
||||
* \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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "tree.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "ngap_common.h"
|
||||
#include "ngap_gNB_defs.h"
|
||||
#include "ngap_gNB_ue_context.h"
|
||||
|
||||
int ngap_gNB_compare_gNB_ue_ngap_id(
|
||||
struct ngap_gNB_ue_context_s *p1, struct ngap_gNB_ue_context_s *p2)
|
||||
{
|
||||
if (p1->gNB_ue_ngap_id > p2->gNB_ue_ngap_id) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (p1->gNB_ue_ngap_id < p2->gNB_ue_ngap_id) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generate the tree management functions */
|
||||
RB_GENERATE(ngap_ue_map, ngap_gNB_ue_context_s, entries,
|
||||
ngap_gNB_compare_gNB_ue_ngap_id);
|
||||
|
||||
struct ngap_gNB_ue_context_s *ngap_gNB_allocate_new_UE_context(void)
|
||||
{
|
||||
struct ngap_gNB_ue_context_s *new_p;
|
||||
|
||||
new_p = malloc(sizeof(struct ngap_gNB_ue_context_s));
|
||||
|
||||
if (new_p == NULL) {
|
||||
NGAP_ERROR("Cannot allocate new ue context\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(new_p, 0, sizeof(struct ngap_gNB_ue_context_s));
|
||||
|
||||
return new_p;
|
||||
}
|
||||
|
||||
struct ngap_gNB_ue_context_s *ngap_gNB_get_ue_context(
|
||||
ngap_gNB_instance_t *instance_p,
|
||||
uint32_t gNB_ue_ngap_id)
|
||||
{
|
||||
ngap_gNB_ue_context_t temp;
|
||||
|
||||
memset(&temp, 0, sizeof(struct ngap_gNB_ue_context_s));
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
void ngap_gNB_free_ue_context(struct ngap_gNB_ue_context_s *ue_context_p)
|
||||
{
|
||||
if (ue_context_p == NULL) {
|
||||
NGAP_ERROR("Trying to free a NULL context\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: check that context is currently not in the tree of known
|
||||
* contexts.
|
||||
*/
|
||||
|
||||
free(ue_context_p);
|
||||
}
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
/*! \file ngap_gNB_ue_context.h
|
||||
* \brief ngap UE context management within gNB
|
||||
* \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 "tree.h"
|
||||
#include "queue.h"
|
||||
|
||||
#include "ngap_gNB_defs.h"
|
||||
|
||||
#ifndef NGAP_GNB_UE_CONTEXT_H_
|
||||
#define NGAP_GNB_UE_CONTEXT_H_
|
||||
|
||||
// Forward declarations
|
||||
struct ngap_gNB_amf_data_s;
|
||||
struct ngap_ue_map;
|
||||
struct gNB_amf_desc_s;
|
||||
|
||||
typedef enum {
|
||||
/* UE has not been registered to a AMF or UE association has failed. */
|
||||
NGAP_UE_DECONNECTED = 0x0,
|
||||
/* UE ngap state is waiting for initial context setup request message. */
|
||||
NGAP_UE_WAITING_CSR = 0x1,
|
||||
/* UE association is ready and bearers are established. */
|
||||
NGAP_UE_CONNECTED = 0x2,
|
||||
NGAP_UE_STATE_MAX,
|
||||
} ngap_ue_state;
|
||||
|
||||
typedef struct ngap_gNB_ue_context_s {
|
||||
/* Tree related data */
|
||||
RB_ENTRY(ngap_gNB_ue_context_s) entries;
|
||||
|
||||
/* Uniquely identifies the UE between AMF and gNB within the gNB.
|
||||
* This id is encoded on 32bits.
|
||||
*/
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* UE id for initial connection to NGAP */
|
||||
uint16_t ue_initial_id;
|
||||
|
||||
/* Uniquely identifies the UE within AMF. Encoded on 32 bits. */
|
||||
uint64_t amf_ue_ngap_id:40;
|
||||
|
||||
/* Stream used for this particular UE */
|
||||
int32_t tx_stream;
|
||||
int32_t rx_stream;
|
||||
|
||||
/* Current UE state. */
|
||||
ngap_ue_state ue_state;
|
||||
|
||||
/* Reference to AMF data this UE is attached to */
|
||||
struct ngap_gNB_amf_data_s *amf_ref;
|
||||
|
||||
/* Signaled by the UE in RRC Connection Setup Complete and used in NAS Uplink
|
||||
* to route NAS messages correctly. 0-based, not 1-based as in TS 36.331
|
||||
* 6.2.2 RRC Connection Setup Complete! */
|
||||
int selected_plmn_identity;
|
||||
|
||||
/* Reference to gNB data this UE is attached to */
|
||||
ngap_gNB_instance_t *gNB_instance;
|
||||
} ngap_gNB_ue_context_t;
|
||||
|
||||
int ngap_gNB_compare_gNB_ue_ngap_id(
|
||||
struct ngap_gNB_ue_context_s *p1, struct ngap_gNB_ue_context_s *p2);
|
||||
|
||||
/* Generate the tree management functions prototypes */
|
||||
RB_PROTOTYPE(ngap_ue_map, ngap_gNB_ue_context_s, entries,
|
||||
ngap_gNB_compare_gNB_ue_ngap_id);
|
||||
|
||||
struct ngap_gNB_ue_context_s *ngap_gNB_allocate_new_UE_context(void);
|
||||
|
||||
struct ngap_gNB_ue_context_s *ngap_gNB_get_ue_context(
|
||||
ngap_gNB_instance_t *instance_p,
|
||||
uint32_t gNB_ue_ngap_id);
|
||||
|
||||
void ngap_gNB_free_ue_context(struct ngap_gNB_ue_context_s *ue_context_p);
|
||||
|
||||
|
||||
#endif /* NGAP_GNB_UE_CONTEXT_H_ */
|
||||
+49
-23
@@ -69,7 +69,6 @@ s1ap_eNB_config_t s1ap_config;
|
||||
static int s1ap_eNB_generate_s1_setup_request(
|
||||
s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p);
|
||||
|
||||
|
||||
void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB);
|
||||
|
||||
void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
|
||||
@@ -90,6 +89,7 @@ uint32_t s1ap_generate_eNB_id(void) {
|
||||
|
||||
static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
|
||||
net_ip_address_t *mme_ip_address,
|
||||
uint16_t mme_port,
|
||||
net_ip_address_t *local_ip_addr,
|
||||
uint16_t in_streams,
|
||||
uint16_t out_streams,
|
||||
@@ -101,9 +101,9 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
|
||||
struct s1ap_eNB_mme_data_s *mme = NULL;
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(mme_ip_address != NULL);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, SCTP_NEW_ASSOCIATION_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_NEW_ASSOCIATION_REQ);
|
||||
sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req;
|
||||
sctp_new_association_req_p->port = S1AP_PORT_NUMBER;
|
||||
sctp_new_association_req_p->port = mme_port;
|
||||
sctp_new_association_req_p->ppid = S1AP_SCTP_PPID;
|
||||
sctp_new_association_req_p->in_streams = in_streams;
|
||||
sctp_new_association_req_p->out_streams = out_streams;
|
||||
@@ -113,7 +113,7 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
|
||||
memcpy(&sctp_new_association_req_p->local_address,
|
||||
local_ip_addr,
|
||||
sizeof(*local_ip_addr));
|
||||
S1AP_INFO("[eNB %d] check the mme registration state\n",instance_p->instance);
|
||||
S1AP_INFO("[eNB %ld] check the mme registration state\n",instance_p->instance);
|
||||
mme = NULL;
|
||||
|
||||
if ( mme == NULL ) {
|
||||
@@ -127,6 +127,7 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
|
||||
memcpy(&s1ap_mme_data_p->mme_s1_ip,
|
||||
mme_ip_address,
|
||||
sizeof(*mme_ip_address));
|
||||
s1ap_mme_data_p->mme_port = mme_port;
|
||||
for (int i = 0; i < broadcast_plmn_num; ++i)
|
||||
s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i];
|
||||
|
||||
@@ -142,7 +143,7 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
|
||||
} else if (mme->state == S1AP_ENB_STATE_WAITING) {
|
||||
instance_p->s1ap_mme_pending_nb ++;
|
||||
sctp_new_association_req_p->ulp_cnx_id = mme->cnx_id;
|
||||
S1AP_INFO("[eNB %d] MME already registered, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n",
|
||||
S1AP_INFO("[eNB %ld] MME already registered, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n",
|
||||
instance_p->instance,
|
||||
mme->state, mme->cnx_id,
|
||||
instance_p->s1ap_mme_nb, instance_p->s1ap_mme_pending_nb);
|
||||
@@ -153,7 +154,7 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
|
||||
s1ap_mme_data_p->s1ap_eNB_instance = instance_p;
|
||||
*/
|
||||
} else {
|
||||
S1AP_WARN("[eNB %d] MME already registered but not in the waiting state, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n",
|
||||
S1AP_WARN("[eNB %ld] MME already registered but not in the waiting state, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n",
|
||||
instance_p->instance,
|
||||
mme->state, mme->cnx_id,
|
||||
instance_p->s1ap_mme_nb, instance_p->s1ap_mme_pending_nb);
|
||||
@@ -210,7 +211,7 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
|
||||
new_instance->default_drx = s1ap_register_eNB->default_drx;
|
||||
/* Add the new instance to the list of eNB (meaningfull in virtual mode) */
|
||||
s1ap_eNB_insert_new_instance(new_instance);
|
||||
S1AP_INFO("Registered new eNB[%d] and %s eNB id %u\n",
|
||||
S1AP_INFO("Registered new eNB[%ld] and %s eNB id %u\n",
|
||||
instance,
|
||||
s1ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home",
|
||||
s1ap_register_eNB->eNB_id);
|
||||
@@ -221,8 +222,23 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
|
||||
|
||||
/* Trying to connect to provided list of MME ip address */
|
||||
for (index = 0; index < s1ap_register_eNB->nb_mme; index++) {
|
||||
net_ip_address_t *mme_ip = &s1ap_register_eNB->mme_ip_address[index];
|
||||
uint16_t mme_port = s1ap_register_eNB->mme_port[index];
|
||||
struct s1ap_eNB_mme_data_s *mme = NULL;
|
||||
RB_FOREACH(mme, s1ap_mme_map, &new_instance->s1ap_mme_head) {
|
||||
/* Compare whether IPv4 and IPv6 information is already present, in which
|
||||
* wase we do not register again */
|
||||
if (mme->mme_s1_ip.ipv4 == mme_ip->ipv4 && (!mme_ip->ipv4
|
||||
|| strncmp(mme->mme_s1_ip.ipv4_address, mme_ip->ipv4_address, 16) == 0)
|
||||
&& mme->mme_s1_ip.ipv6 == mme_ip->ipv6 && (!mme_ip->ipv6
|
||||
|| strncmp(mme->mme_s1_ip.ipv6_address, mme_ip->ipv6_address, 46) == 0))
|
||||
break;
|
||||
}
|
||||
if (mme)
|
||||
continue;
|
||||
s1ap_eNB_register_mme(new_instance,
|
||||
&s1ap_register_eNB->mme_ip_address[index],
|
||||
mme_ip,
|
||||
mme_port,
|
||||
&s1ap_register_eNB->enb_ip_address,
|
||||
s1ap_register_eNB->sctp_in_streams,
|
||||
s1ap_register_eNB->sctp_out_streams,
|
||||
@@ -242,7 +258,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
|
||||
DevAssert(s1ap_mme_data_p != NULL);
|
||||
|
||||
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
|
||||
S1AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
|
||||
S1AP_WARN("Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
|
||||
sctp_new_association_resp->sctp_state,
|
||||
instance,
|
||||
sctp_new_association_resp->ulp_cnx_id);
|
||||
@@ -297,13 +313,13 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) {
|
||||
* Each eNB has to send an S1AP_REGISTER_ENB message with its
|
||||
* own parameters.
|
||||
*/
|
||||
s1ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
s1ap_eNB_handle_register_eNB(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&S1AP_REGISTER_ENB_REQ(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_RESP: {
|
||||
s1ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
s1ap_eNB_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_resp);
|
||||
}
|
||||
break;
|
||||
@@ -314,55 +330,61 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) {
|
||||
break;
|
||||
|
||||
case S1AP_NAS_FIRST_REQ: {
|
||||
s1ap_eNB_handle_nas_first_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
s1ap_eNB_handle_nas_first_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&S1AP_NAS_FIRST_REQ(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_UPLINK_NAS: {
|
||||
s1ap_eNB_nas_uplink(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
s1ap_eNB_nas_uplink(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&S1AP_UPLINK_NAS(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_UE_CAPABILITIES_IND: {
|
||||
s1ap_eNB_ue_capabilities(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
s1ap_eNB_ue_capabilities(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&S1AP_UE_CAPABILITIES_IND(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_INITIAL_CONTEXT_SETUP_RESP: {
|
||||
s1ap_eNB_initial_ctxt_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
s1ap_eNB_initial_ctxt_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&S1AP_INITIAL_CONTEXT_SETUP_RESP(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_E_RAB_SETUP_RESP: {
|
||||
s1ap_eNB_e_rab_setup_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
s1ap_eNB_e_rab_setup_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&S1AP_E_RAB_SETUP_RESP(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_E_RAB_MODIFY_RESP: {
|
||||
s1ap_eNB_e_rab_modify_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
s1ap_eNB_e_rab_modify_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&S1AP_E_RAB_MODIFY_RESP(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_NAS_NON_DELIVERY_IND: {
|
||||
s1ap_eNB_nas_non_delivery_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
s1ap_eNB_nas_non_delivery_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&S1AP_NAS_NON_DELIVERY_IND(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_PATH_SWITCH_REQ: {
|
||||
s1ap_eNB_path_switch_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
s1ap_eNB_path_switch_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&S1AP_PATH_SWITCH_REQ(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_E_RAB_MODIFICATION_IND: {
|
||||
s1ap_eNB_generate_E_RAB_Modification_Indication(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&S1AP_E_RAB_MODIFICATION_IND(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_UE_CONTEXT_RELEASE_COMPLETE: {
|
||||
s1ap_ue_context_release_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
s1ap_ue_context_release_complete(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&S1AP_UE_CONTEXT_RELEASE_COMPLETE(received_msg));
|
||||
}
|
||||
break;
|
||||
@@ -370,9 +392,9 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) {
|
||||
case S1AP_UE_CONTEXT_RELEASE_REQ: {
|
||||
s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; // test
|
||||
struct s1ap_eNB_ue_context_s *ue_context_p = NULL; // test
|
||||
s1ap_ue_context_release_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
s1ap_ue_context_release_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&S1AP_UE_CONTEXT_RELEASE_REQ(received_msg));
|
||||
s1ap_eNB_instance_p = s1ap_eNB_get_instance(ITTI_MESSAGE_GET_INSTANCE(received_msg)); // test
|
||||
s1ap_eNB_instance_p = s1ap_eNB_get_instance(ITTI_MSG_DESTINATION_INSTANCE(received_msg)); // test
|
||||
DevAssert(s1ap_eNB_instance_p != NULL); // test
|
||||
|
||||
if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
|
||||
@@ -385,7 +407,7 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) {
|
||||
break;
|
||||
|
||||
case S1AP_E_RAB_RELEASE_RESPONSE: {
|
||||
s1ap_eNB_e_rab_release_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
s1ap_eNB_e_rab_release_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&S1AP_E_RAB_RELEASE_RESPONSE(received_msg));
|
||||
}
|
||||
break;
|
||||
@@ -508,3 +530,7 @@ static int s1ap_eNB_generate_s1_setup_request(
|
||||
s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, s1ap_mme_data_p->assoc_id, buffer, len, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -112,6 +112,12 @@ static int s1ap_eNB_decode_successful_outcome(S1AP_S1AP_PDU_t *pdu) {
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case S1AP_ProcedureCode_id_E_RABModificationIndication:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
S1AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n",
|
||||
(int)pdu->choice.successfulOutcome.procedureCode);
|
||||
|
||||
@@ -124,8 +124,9 @@ typedef struct s1ap_eNB_mme_data_s {
|
||||
/* This is the optional name provided by the MME */
|
||||
char *mme_name;
|
||||
|
||||
/* MME S1AP IP address */
|
||||
/* MME S1AP IP address and port */
|
||||
net_ip_address_t mme_s1_ip;
|
||||
uint16_t mme_port;
|
||||
|
||||
/* List of served GUMMEI per MME. There is one GUMMEI per RAT with a max
|
||||
* number of 8 RATs but in our case only one is used. The LTE related pool
|
||||
|
||||
@@ -118,6 +118,11 @@ int s1ap_eNB_encode_initiating(S1AP_S1AP_PDU_t *pdu,
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case S1AP_ProcedureCode_id_E_RABModificationIndication:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
S1AP_DEBUG("Unknown procedure ID (%d) for initiating message\n",
|
||||
(int)pdu->choice.initiatingMessage.procedureCode);
|
||||
@@ -132,6 +137,8 @@ int s1ap_eNB_encode_initiating(S1AP_S1AP_PDU_t *pdu,
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_S1AP_S1AP_PDU, pdu);
|
||||
*buffer = res.buffer;
|
||||
*len = res.result.encoded;
|
||||
if (res.result.encoded == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -184,6 +191,8 @@ int s1ap_eNB_encode_successfull_outcome(S1AP_S1AP_PDU_t *pdu,
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_S1AP_S1AP_PDU, pdu);
|
||||
*buffer = res.buffer;
|
||||
*len = res.result.encoded;
|
||||
if (res.result.encoded == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -213,5 +222,7 @@ int s1ap_eNB_encode_unsuccessfull_outcome(S1AP_S1AP_PDU_t *pdu,
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_S1AP_S1AP_PDU, pdu);
|
||||
*buffer = res.buffer;
|
||||
*len = res.result.encoded;
|
||||
if (res.result.encoded == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -104,6 +104,11 @@ int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t assoc_
|
||||
uint32_t stream,
|
||||
S1AP_S1AP_PDU_t *pdu);
|
||||
|
||||
static
|
||||
int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
S1AP_S1AP_PDU_t *pdu);
|
||||
|
||||
/* Handlers matrix. Only eNB related procedure present here */
|
||||
s1ap_message_decoded_callback messages_callback[][3] = {
|
||||
{ 0, 0, 0 }, /* HandoverPreparation */
|
||||
@@ -154,6 +159,9 @@ s1ap_message_decoded_callback messages_callback[][3] = {
|
||||
{ 0, 0, 0 }, /* UplinkUEAssociatedLPPaTransport */
|
||||
{ 0, 0, 0 }, /* DownlinkNonUEAssociatedLPPaTransport */
|
||||
{ 0, 0, 0 }, /* UplinkNonUEAssociatedLPPaTransport */
|
||||
{ 0, 0, 0 }, /* UERadioCapabilityMatch */
|
||||
{ 0, 0, 0 }, /* PWSRestartIndication */
|
||||
{ 0, s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm, 0 }, /* E_RABModificationIndication */
|
||||
};
|
||||
char *s1ap_direction2String(int s1ap_dir) {
|
||||
static char *s1ap_direction_String[] = {
|
||||
@@ -180,7 +188,7 @@ void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shut
|
||||
/* If there are no more associated MME, inform eNB app */
|
||||
if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb == 0) {
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_DEREGISTERED_ENB_IND);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_DEREGISTERED_ENB_IND);
|
||||
S1AP_DEREGISTERED_ENB_IND(message_p).nb_mme = 0;
|
||||
itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p);
|
||||
}
|
||||
@@ -198,7 +206,7 @@ void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shut
|
||||
/* If there are no more pending messages, inform eNB app */
|
||||
if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb == 0) {
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_REGISTER_ENB_CNF);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_REGISTER_ENB_CNF);
|
||||
S1AP_REGISTER_ENB_CNF(message_p).nb_mme = mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb;
|
||||
itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p);
|
||||
}
|
||||
@@ -783,7 +791,7 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
|
||||
|
||||
ue_desc_p->rx_stream = stream;
|
||||
ue_desc_p->mme_ue_s1ap_id = mme_ue_s1ap_id;
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_INITIAL_CONTEXT_SETUP_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_INITIAL_CONTEXT_SETUP_REQ);
|
||||
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id;
|
||||
ue_desc_p->ue_initial_id = 0;
|
||||
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).eNB_ue_s1ap_id = ue_desc_p->eNB_ue_s1ap_id;
|
||||
@@ -856,22 +864,36 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
|
||||
BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms);
|
||||
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms =
|
||||
BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms);
|
||||
/* id-SecurityKey : Copy the security key */
|
||||
} else {/* ie != NULL */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* id-SecurityKey : Copy the security key */
|
||||
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container,
|
||||
S1AP_ProtocolIE_ID_id_SecurityKey, true);
|
||||
|
||||
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
|
||||
memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key,
|
||||
ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size);
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
|
||||
} else {/* ie != NULL */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* id-NRUESecurityCapabilities */
|
||||
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container,
|
||||
S1AP_ProtocolIE_ID_id_NRUESecurityCapabilities, false);
|
||||
if (ie != NULL) {
|
||||
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms =
|
||||
BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms);
|
||||
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms =
|
||||
BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms);
|
||||
} else {
|
||||
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms = 0;
|
||||
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms = 0;
|
||||
}
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -927,7 +949,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
|
||||
NULL,0,
|
||||
"0 S1AP_UE_CONTEXT_RELEASE_COMMAND/%d eNB_ue_s1ap_id "S1AP_UE_ID_FMT" ",
|
||||
enb_ue_s1ap_id);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_UE_CONTEXT_RELEASE_COMMAND);
|
||||
|
||||
if (ue_desc_p->mme_ue_s1ap_id == 0) { // case of Detach Request and switch off from RRC_IDLE mode
|
||||
ue_desc_p->mme_ue_s1ap_id = mme_ue_s1ap_id;
|
||||
@@ -1024,7 +1046,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id,
|
||||
ue_desc_p->mme_ue_s1ap_id, mme_ue_s1ap_id);
|
||||
}
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_SETUP_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_E_RAB_SETUP_REQ);
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id;
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).mme_ue_s1ap_id = mme_ue_s1ap_id;
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id;
|
||||
@@ -1118,7 +1140,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id,
|
||||
return -1;
|
||||
}
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_PAGING_IND);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_PAGING_IND);
|
||||
/* convert S1AP_PagingIEs_t to s1ap_paging_ind_t */
|
||||
/* id-UEIdentityIndexValue : convert UE Identity Index value */
|
||||
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PagingIEs_t, ie, container,
|
||||
@@ -1314,7 +1336,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id,
|
||||
if (ue_desc_p->mme_ue_s1ap_id != mme_ue_s1ap_id) {
|
||||
S1AP_WARN("UE context mme_ue_s1ap_id is different form that of the message (%d != %ld)",
|
||||
ue_desc_p->mme_ue_s1ap_id, mme_ue_s1ap_id);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_E_RAB_MODIFY_RESP);
|
||||
S1AP_E_RAB_MODIFY_RESP (message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id;
|
||||
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABModifyRequestIEs_t, ie, container,
|
||||
S1AP_ProtocolIE_ID_id_E_RABToBeModifiedListBearerModReq, true);
|
||||
@@ -1340,7 +1362,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id,
|
||||
return -1;
|
||||
}
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_MODIFY_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_E_RAB_MODIFY_REQ);
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id;
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).mme_ue_s1ap_id = mme_ue_s1ap_id;
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id;
|
||||
@@ -1451,7 +1473,7 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id,
|
||||
|
||||
S1AP_DEBUG("[SCTP %d] Received E-RAB release command for eNB_UE_S1AP_ID %ld mme_ue_s1ap_id %ld\n",
|
||||
assoc_id, enb_ue_s1ap_id, mme_ue_s1ap_id);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_RELEASE_COMMAND);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_E_RAB_RELEASE_COMMAND);
|
||||
S1AP_E_RAB_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id;
|
||||
S1AP_E_RAB_RELEASE_COMMAND(message_p).mme_ue_s1ap_id = mme_ue_s1ap_id;
|
||||
/* id-NAS-PDU */
|
||||
@@ -1521,7 +1543,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id,
|
||||
}
|
||||
|
||||
// send a message to RRC
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_PATH_SWITCH_REQ_ACK);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_PATH_SWITCH_REQ_ACK);
|
||||
/* mandatory */
|
||||
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge,
|
||||
S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true);
|
||||
@@ -1722,3 +1744,13 @@ int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t assoc_
|
||||
// TODO continue
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
S1AP_S1AP_PDU_t *pdu){
|
||||
|
||||
LOG_I(S1AP, "Received S1AP E-RAB Modification confirm message \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ void s1ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uin
|
||||
MessageDef *message_p;
|
||||
sctp_data_req_t *sctp_data_req;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, SCTP_DATA_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_DATA_REQ);
|
||||
|
||||
sctp_data_req = &message_p->ittiMsg.sctp_data_req;
|
||||
|
||||
@@ -50,7 +50,7 @@ void s1ap_eNB_itti_send_nas_downlink_ind(instance_t instance,
|
||||
MessageDef *message_p;
|
||||
s1ap_downlink_nas_t *s1ap_downlink_nas;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_DOWNLINK_NAS);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_DOWNLINK_NAS);
|
||||
|
||||
s1ap_downlink_nas = &message_p->ittiMsg.s1ap_downlink_nas;
|
||||
|
||||
@@ -68,7 +68,7 @@ void s1ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t asso
|
||||
MessageDef *message_p = NULL;
|
||||
sctp_close_association_t *sctp_close_association_p = NULL;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, SCTP_CLOSE_ASSOCIATION);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_CLOSE_ASSOCIATION);
|
||||
sctp_close_association_p = &message_p->ittiMsg.sctp_close_association;
|
||||
sctp_close_association_p->assoc_id = assoc_id;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user