Merge remote-tracking branch 'origin/develop' into ci-deploy-docker-compose

This commit is contained in:
Raphael Defosseux
2020-12-04 10:08:40 +01:00
207 changed files with 39759 additions and 3448 deletions
+1
View File
@@ -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_ */
@@ -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(&registration_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(&registration_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(&registration_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(&registration_request->naskeysetidentifier) & 0x0f) << 4) | (encode_5gs_registration_type(&registration_request->fgsregistrationtype) & 0x0f);
encoded++;
if ((encode_result =
encode_5gs_mobile_identity(&registration_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(&registration_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(&registration_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,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_ */
+54
View File
@@ -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;
}
+51
View File
@@ -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_ */
+175
View File
@@ -0,0 +1,175 @@
/*
* 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);
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 (encoded_rc < 0) {
return encoded_rc;
}
*(uint16_t*) buffer = htons(encoded + encoded_rc - 2 - ((iei > 0) ? 1 : 0));
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 & 0x3f) << 6) | (guti->amfpointer & 0x3f);
IES_ENCODE_U16(buffer, encoded, temp);
IES_ENCODE_U32(buffer, encoded, guti->tmsi);
return encoded;
}
+134
View File
@@ -0,0 +1,134 @@
/*
* 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;
} 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,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_ */
+50
View File
@@ -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;
}
+51
View File
@@ -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_ */
View File
+168
View File
@@ -0,0 +1,168 @@
/*
* 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"
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;
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 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 = NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE;
size += 1;
mm_msg->registration_request.fgsmobileidentity.guti.typeofidentity = FGS_MOBILE_IDENTITY_5G_GUTI;
// mm_msg->registration_request.fgsmobileidentity.guti.amfregionid = 1;
// mm_msg->registration_request.fgsmobileidentity.guti.amfpointer = 1;
// mm_msg->registration_request.fgsmobileidentity.guti.amfsetid = 1;
mm_msg->registration_request.fgsmobileidentity.guti.tmsi = 10;
mm_msg->registration_request.fgsmobileidentity.guti.mncdigit1 = 9;
mm_msg->registration_request.fgsmobileidentity.guti.mncdigit2 = 3;
mm_msg->registration_request.fgsmobileidentity.guti.mccdigit1 = 2;
mm_msg->registration_request.fgsmobileidentity.guti.mccdigit2 = 0;
mm_msg->registration_request.fgsmobileidentity.guti.mccdigit3 = 8;
size += 13;
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));
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
}
+94
View File
@@ -0,0 +1,94 @@
/*
* 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 "as_message.h"
#define PLAIN_5GS_MSG 0b0000
#define INTEGRITY_PROTECTED 0b0001
#define REGISTRATION_REQUEST 0b01000001 /* 65 = 0x41 */
#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;
} 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);
#endif /* __NR_NAS_MSG_SIM_H__*/
File diff suppressed because it is too large Load Diff
+41
View File
@@ -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)
{
}
+163
View File
@@ -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_ */
+534
View File
@@ -0,0 +1,534 @@
/*
* 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"
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, 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 %d] 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_WAITING;
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[%d] 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 %d, 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);
ngap_gNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream,
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
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_MESSAGE_GET_INSTANCE(received_msg),
&NGAP_REGISTER_GNB_REQ(received_msg));
}
break;
case SCTP_NEW_ASSOCIATION_RESP: {
ngap_gNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_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_MESSAGE_GET_INSTANCE(received_msg),
&NGAP_NAS_FIRST_REQ(received_msg));
}
break;
case NGAP_UPLINK_NAS: {
ngap_gNB_nas_uplink(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&NGAP_UPLINK_NAS(received_msg));
}
break;
case NGAP_UE_CAPABILITIES_IND: {
ngap_gNB_ue_capabilities(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&NGAP_UE_CAPABILITIES_IND(received_msg));
}
break;
case NGAP_INITIAL_CONTEXT_SETUP_RESP: {
ngap_gNB_initial_ctxt_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&NGAP_INITIAL_CONTEXT_SETUP_RESP(received_msg));
}
break;
case NGAP_PDUSESSION_SETUP_RESP: {
ngap_gNB_pdusession_setup_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&NGAP_PDUSESSION_SETUP_RESP(received_msg));
}
break;
case NGAP_PDUSESSION_MODIFY_RESP: {
ngap_gNB_pdusession_modify_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&NGAP_PDUSESSION_MODIFY_RESP(received_msg));
}
break;
case NGAP_NAS_NON_DELIVERY_IND: {
ngap_gNB_nas_non_delivery_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&NGAP_NAS_NON_DELIVERY_IND(received_msg));
}
break;
case NGAP_PATH_SWITCH_REQ: {
ngap_gNB_path_switch_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&NGAP_PATH_SWITCH_REQ(received_msg));
}
break;
case NGAP_PDUSESSION_MODIFICATION_IND: {
ngap_gNB_generate_PDUSESSION_Modification_Indication(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&NGAP_PDUSESSION_MODIFICATION_IND(received_msg));
}
break;
case NGAP_UE_CONTEXT_RELEASE_COMPLETE: {
ngap_ue_context_release_complete(ITTI_MESSAGE_GET_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_MESSAGE_GET_INSTANCE(received_msg),
&NGAP_UE_CONTEXT_RELEASE_REQ(received_msg));
ngap_gNB_instance_p = ngap_gNB_get_instance(ITTI_MESSAGE_GET_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_MESSAGE_GET_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;
}
+64
View File
@@ -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,271 @@
/*
* 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 "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);
/* 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_ */
+188
View File
@@ -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;
}
+37
View File
@@ -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_ */
+45
View File
@@ -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_ */
+298
View File
@@ -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_ */
+223
View File
@@ -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;
}
+36
View File
@@ -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
+38
View File
@@ -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_ */
+85
View File
@@ -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, 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, 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, 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);
}
+46
View File
@@ -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
+68
View File
@@ -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_ */
+410
View File
@@ -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;
}
+57
View File
@@ -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_ */
+79
View File
@@ -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;
}
+53
View File
@@ -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_ */
+66
View File
@@ -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;
}
+54
View File
@@ -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_ */
+103
View File
@@ -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 = 24 bits wide */
temp.gNB_ue_ngap_id = gNB_ue_ngap_id & 0x00FFFFFF;
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);
}
+103
View File
@@ -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_ */
+83
View File
@@ -81,6 +81,23 @@ do { \
((buf)[1]); \
} while(0)
/* Convert an integer on 24 bits to the given bUFFER */
#define INT24_TO_BUFFER(x, buf) \
do { \
(buf)[0] = (x) >> 16; \
(buf)[1] = (x) >> 8; \
(buf)[2] = (x); \
} while(0)
/* Convert an array of char containing vALUE to x */
#define BUFFER_TO_INT24(buf, x) \
do { \
x = ((buf)[0] << 16) | \
((buf)[1] << 8 ) | \
((buf)[2]); \
} while(0)
/* Convert an integer on 32 bits to the given bUFFER */
#define INT32_TO_BUFFER(x, buf) \
do { \
@@ -126,6 +143,21 @@ do { \
(aSN)->bits_unused = 0; \
} while(0)
#define INT24_TO_OCTET_STRING(x, aSN) \
do { \
(aSN)->buf = calloc(3, sizeof(uint8_t)); \
INT24_TO_BUFFER(x, ((aSN)->buf)); \
(aSN)->size = 3; \
} while(0)
#define INT24_TO_BIT_STRING(x, aSN) \
do { \
INT24_TO_OCTET_STRING(x, aSN); \
(aSN)->bits_unused = 0; \
} while(0)
#define INT8_TO_OCTET_STRING(x, aSN) \
do { \
(aSN)->buf = calloc(1, sizeof(uint8_t)); \
@@ -137,6 +169,25 @@ do { \
#define M_TMSI_TO_OCTET_STRING INT32_TO_OCTET_STRING
#define MME_GID_TO_OCTET_STRING INT16_TO_OCTET_STRING
#define AMF_REGION_TO_BIT_STRING(x, aSN) \
do { \
INT8_TO_OCTET_STRING(x, aSN); \
(aSN)->bits_unused = 0; \
} while(0)
#define AMF_SETID_TO_BIT_STRING(x, aSN) \
do { \
INT16_TO_OCTET_STRING(x, aSN); \
(aSN)->bits_unused = 6; \
} while(0)
#define AMF_POINTER_TO_BIT_STRING(x, aSN) \
do { \
INT8_TO_OCTET_STRING(x, aSN); \
(aSN)->bits_unused = 2; \
} while(0)
#define ENCRALG_TO_BIT_STRING(encralg, bitstring) \
do { \
(bitstring)->size=2; \
@@ -197,6 +248,12 @@ do { \
BUFFER_TO_INT16((aSN)->buf, x); \
} while(0)
#define OCTET_STRING_TO_INT24(aSN, x) \
do { \
DevCheck((aSN)->size == 2 || (aSN)->size == 3, (aSN)->size, 0, 0); \
BUFFER_TO_INT24((aSN)->buf, x); \
} while(0)
#define OCTET_STRING_TO_INT32(aSN, x) \
do { \
DevCheck((aSN)->size == 4, (aSN)->size, 0, 0); \
@@ -445,6 +502,19 @@ do { \
(bITsTRING)->size = 3; \
(bITsTRING)->bits_unused = 4; \
} while(0)
#define MACRO_GNB_ID_TO_BIT_STRING(mACRO, bITsTRING) \
do { \
(bITsTRING)->buf = calloc(4, sizeof(uint8_t)); \
(bITsTRING)->buf[0] = ((mACRO) >> 20); \
(bITsTRING)->buf[1] = (mACRO) >> 12; \
(bITsTRING)->buf[2] = (mACRO) >> 4; \
(bITsTRING)->buf[3] = ((mACRO) & 0x0f) << 4; \
(bITsTRING)->size = 4; \
(bITsTRING)->bits_unused = 4; \
} while(0)
/* TS 36.413 v10.9.0 section 9.2.1.38:
* E-UTRAN CGI/Cell Identity
* The leftmost bits of the Cell
@@ -462,6 +532,19 @@ do { \
(bITsTRING)->bits_unused = 4; \
} while(0)
#define MACRO_GNB_ID_TO_CELL_IDENTITY(mACRO, cELL_iD, bITsTRING) \
do { \
(bITsTRING)->buf = calloc(5, sizeof(uint8_t)); \
(bITsTRING)->buf[0] = ((mACRO) >> 20); \
(bITsTRING)->buf[1] = (mACRO) >> 12; \
(bITsTRING)->buf[2] = (mACRO) >> 4; \
(bITsTRING)->buf[3] = (((mACRO) & 0x0f) << 4) | ((cELL_iD) >> 4); \
(bITsTRING)->buf[4] = ((cELL_iD) & 0x0f) << 4; \
(bITsTRING)->size = 5; \
(bITsTRING)->bits_unused = 4; \
} while(0)
/* Used to format an uint32_t containing an ipv4 address */
#define IPV4_ADDR "%u.%u.%u.%u"
#define IPV4_ADDR_FORMAT(aDDRESS) \