Commit 1ad1fcf9 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Update from Bupt

parent ea9769b8
build/amf/build
tags
*.log
The OpenAirInterface Software Alliance (OSA)
OAI Public License (Version 1.1)
LICENSE TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION OF OPENAIR 5G SOFTWARE.
1. Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution set forth
in this document.
“Licensor” shall mean the OpenAirInterface Software Alliance.
“Legal Entity” shall mean the union, at the time an acting entity joins the Alliance, of the
acting entity and all other entities that control, are controlled by, or are under common control
with that entity. For the purposes of this definition, “control” means (i) the power, direct or
indirect, to cause the direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii)
beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by
this License.
“Source” form shall mean the preferred form for making modifications, including but not
limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of
a Source form, including but not limited to compiled object code, generated documentation,
and conversions to other media types.
“OpenAirInterface Software Alliance” shall mean the endowment fund established at the
initiative of Eurecom, an educational and research establishment located at Campus Sophia
Tech, 450 Route des Chappes, 06410 Biot, France, which statutes were signed on 18
November 2014.
“Work” shall mean the work of authorship, whether in Source or Object form, made available
under the License, as indicated by a copyright notice that is included in or attached to the
work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on
(or derived from) the Work and for which the editorial revisions, annotations, elaborations, or
other modifications represent, as a whole, an original work of authorship. For the purposes of
this License, Derivative Works shall not include works that remain separable from, or merely
link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship that is intentionally submitted to Licensor
for inclusion in the Work by the copyright owner or by an individual or Legal Entity
authorized to submit on behalf of the copyright owner. For the purposes of this definition,
“submitted” means any form of electronic, , or written communication sent to the Licensor or
its representatives, including but not limited to communication on electronic mailing lists,
source code control systems, and issue tracking systems that are managed by, or on behalf of,
the Licensor for the purpose of discussing and improving the Work
“Contributor License Agreement” shall mean the agreement signed by any Contributor setting
forth the terms and conditions applicable to its Contribution.
“Contributor” shall mean any individual or Legal Entity on behalf of whom a Contribution
has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of this License, Licensor and each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of, publicly display, publicly
perform, and distribute the Work and such Derivative Works in Source or Object form
3. Grant of Patent License.
3.1 Grant of Patent License for study, testing and research purposes:
Subject to the terms and conditions of this License, Licensor and each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made, use, and otherwise
transfer (excluding selling) the Work, solely for study, testing and research purposes, where
such license applies only to those patent claims licensable by Licensor or such Contributor
that are necessarily infringed respectively by the Work and/or the said Contributor
Contribution(s) alone or by combination of their Contribution(s) with the Work to which
such Contribution(s) was submitted (“Essential Patents”).
3.2 Grant of Patent License for purposes other than study and research:
For purposes other than study, testing and research, and subject to the terms and conditions of
this License, You commit to be prepared to negotiate a non-exclusive, non-transferable, non-
assignable license of Essential Patents with each Contributor and/or the Licensor on Fair,
Reasonable and Non-Discriminatory (“FRAND”) terms and conditions for the use of the
Work or Contribution(s) incorporated within the Work.
Licensor and/or each Contributor, by submitting a Contribution, will identify any of its known
Essential Patent it owns related to the Work and/or its Contribution.
3.3 Patent Litigation
If You institute patent litigation against any entity making use of the Work solely for study,
testing and research purposes (including a cross-claim or counterclaim in a lawsuit) alleging
that the Work or a Contribution incorporated within the Work constitutes direct or
contributory patent infringement, then the patent licenses granted to You under section 3.1 of
this License for that Work shall terminate as of the date such litigation is filed.
4. Sublicensing
You may grant sublicenses under the licenses granted under sections 2 and 3.1 provided that
the sublicense is subject to and inclusive of all the terms of and rights under this License to
which the Work is or was distributed by the OpenAirInterface Software Alliance.
5. Redistribution
Subject to terms and conditions set forth in sections 2 and 3, You may reproduce and
distribute copies of the Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You meet the following
conditions:
1. You must give any other recipients of the Work or Derivative Works a copy of this
License; and
2. You must cause any modified files by You to carry prominent notices stating that You
changed the files; and
3. You must retain, in the Source form of any Derivative Works that You distribute, all
copyright, patent, trademark, and attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of the Derivative Works; and
4. If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative
Works that You distribute must include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not pertain to any part of the
Derivative Works, in at least one of the following places: within a NOTICE text file
distributed as part of the Derivative Works; within the Source form or documentation, if
provided along with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of the
NOTICE file are for informational purposes only and do not modify the License. You may
add Your own attribution notices within Derivative Works that You distribute, alongside or as
an addendum to the NOTICE text from the Work, provided that such additional attribution
notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or distribution of
Your modifications, or for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with the conditions stated in
this License.
6. Submission of Contributions.
Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be
under the terms and conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of any
separate license agreement such as the Contributor License Agreement You may have
executed with Licensor regarding such Contributions.
7. Trademarks.
This License does not grant permission to use the trade names, trademarks, service marks, or
product names of the Licensor, except as required for reasonable and customary use in
describing the origin of the Work and reproducing the content of the NOTICE file.
8. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the Work (and
each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including,
without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely
responsible for determining the appropriateness of using or redistributing the Work and
assume any risks associated with your exercise of permissions under this License.
9. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence), contract, or
otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or
agreed to in writing, shall Licensor and any Contributor, as such, be liable to You for
damages, including any direct, indirect, special, incidental, or consequential damages of any
character arising as a result of this License or out of Your use or inability to use the Work
(including but not limited to damages for loss of goodwill, work stoppage, computer failure or
malfunction, or any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
10. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to offer, and
charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations
and/or rights consistent with this License. However, in accepting such obligations, You may
act only on Your own behalf and on Your sole responsibility, not on behalf of any other
Contributor and/or the Licensor, and only if You agree to indemnify, defend, and hold each
Contributor and/or the Licensor harmless for any liability incurred by, or claims asserted
against, such Contributor and/or Licensor by reason of Your accepting any such warranty or
additional liability.
11. Applicable law.
The present license shall be governed by the laws of France.
END OF TERMS AND CONDITIONS
1. APPENDIX: How to apply the PRESENT OPENAIR 5G License to your work
To apply the present License to your work, attach the following boilerplate notice, with the
fields enclosed by brackets “[]” replaced with your own identifying information. (Don’t
include the brackets!) The text should be enclosed in the appropriate comment syntax for the
file format. We also recommend that a file or class name and description of purpose be
included on the same “printed page” as the copyright notice for easier identification within
third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the License terms and conditions for use, reproduction, and distribution of
OPENAIR 5G software (the “License”);
you may not use this file except in compliance with the License. You may obtain a copy of
the License at
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.
# amf_bupt
# Private Repository for initial development on OpenAir Core-Network 5G #
**AMF Repository**
## amf configuration file
AMF =
{
INSTANCE_ID = 10;
PID_DIRECTORY = "/var/run";
######################################################################## NG SETUP RESPONSE IEs ############################################################
AMF_NAME = "bupt-amf";
GUAMI:{MCC = "208"; MNC = "95"; RegionID = "128"; AMFSetID = "1"; AMFPointer = "1"}
ServedGUAMIList = (
{MCC = "208"; MNC = "95"; RegionID = "10"; AMFSetID = "1"; AMFPointer = "0"}, #48bits <MCC><MNC><RegionID><AMFSetID><AMFPointer>
{MCC = "460"; MNC = "11"; RegionID = "10"; AMFSetID = "1"; AMFPointer = "1"} #48bits <MCC><MNC><RegionID><AMFSetID><AMFPointer>
);
RelativeAMFCapacity = 30;
PLMNSupportList = (
{MCC = "208"; MNC = "95"; TAC = 0xa000;
SliceSupportList = (
{SST = "222"; SD = "123"},
{SST = "1"; SD = "none"},
{SST = "1"; SD = "12"}
)
}
);
##################################################################### clause 9.2.6.2, 3gpp ts38.413 ####################################################
STATISTICS_TIMER_INTERVAL = 20; #second
INTERFACES:{
NGAP_AMF:{
INTERFACE_NAME = "ens3";
IPV4_ADDRESS = "read";
SCTP_PORT = 38412;
PPID = 60;
};
N11:{
SMF_INSTANCES_POOL = (
{SMF_INSTANCE_ID = 1; IPV4_ADDRESS = "192.168.122.168"; PORT = "80"; VERSION = "v2"; SELECTED = "true"},
{SMF_INSTANCE_ID = 2; IPV4_ADDRESS = "10.103.238.21"; PORT = "8181"; VERSION = "v1"; SELECTED = "false"}
);
};
};
CORE_CONFIGURATION:{
EMERGENCY_SUPPORT = "false";
};
AUTHENTICATION:{
MYSQL_server = "127.0.0.1";
MYSQL_user = "root"; # Database server login
MYSQL_pass = "linux"; # Database server password
MYSQL_db = "oai_db";
OPERATOR_key = "63bfa50ee6523365ff14c1f45f88737d"; # op 0x63bfa50ee6523365ff14c1f45f88737d
#Key: 0x0C0A34601D4F07677303652C0462535B
RANDOM = "true";
};
NAS:{
#ORDERED_SUPPORTED_INTEGRITY_ALGORITHM_LIST = [ "NIA2" , "NIA1" , "NIA0" ];
ORDERED_SUPPORTED_INTEGRITY_ALGORITHM_LIST = [ "NIA0" , "NIA1" , "NIA1" ];
ORDERED_SUPPORTED_CIPHERING_ALGORITHM_LIST = [ "NEA0" , "NEA1" , "NEA2" ];
#ORDERED_SUPPORTED_CIPHERING_ALGORITHM_LIST = [ "NEA1" , "NEA1" , "NEA1" ];
};
};
MODULES =
{
NGAP_MESSAGE = (
{MSG_NAME = "NGSetupRequest"; ProcedureCode = 21; TypeOfMessage = "initialMessage"}
);
};
......@@ -28,6 +28,8 @@ extern statistics stacs;
void amf_app_task(void*);
uint32_t golbal_tmsi = 1;
amf_app::amf_app(const amf_config &amf_cfg){
Logger::amf_app().startup("Creating amf application functionality layer");
if(itti_inst->create_task(TASK_AMF_APP, amf_app_task, nullptr)){
......@@ -119,6 +121,20 @@ void amf_app::set_amf_ue_ngap_id_2_ue_context(const long & amf_ue_ngap_id, std::
amf_ue_ngap_id2ue_ctx[amf_ue_ngap_id] = uc;
}
bool amf_app::is_ran_amf_id_2_ue_context(const string & ue_context_key) const {
std::shared_lock lock(m_ue_ctx_key);
return bool{ue_ctx_key.count(ue_context_key) > 0};
}
std::shared_ptr<ue_context> amf_app::ran_amf_id_2_ue_context(const string & ue_context_key) const{
std::shared_lock lock(m_ue_ctx_key);
return ue_ctx_key.at(ue_context_key);
}
void amf_app::set_ran_amf_id_2_ue_context(const string & ue_context_key, std::shared_ptr<ue_context> uc){
std::shared_lock lock(m_ue_ctx_key);
ue_ctx_key[ue_context_key] = uc;
}
/****************************** itti handlers *******************************/
void amf_app::handle_itti_message(itti_n1n2_message_transfer_request & itti_msg){
//1. encode DL NAS TRANSPORT message(NAS message)
......@@ -162,13 +178,16 @@ void amf_app::handle_itti_message(itti_nas_signalling_establishment_request & it
if(amf_ue_ngap_id = itti_msg.amf_ue_ngap_id == -1){
amf_ue_ngap_id = generate_amf_ue_ngap_id();
}
if(!is_amf_ue_id_2_ue_context(amf_ue_ngap_id)){
Logger::amf_app().debug("no existed ue_context, Create one");
string ue_context_key = "app_ue_ranid_"+to_string(itti_msg.ran_ue_ngap_id)+":amfid_"+to_string(amf_ue_ngap_id);
//if(!is_amf_ue_id_2_ue_context(amf_ue_ngap_id)){
if(!is_ran_amf_id_2_ue_context(ue_context_key)){
Logger::amf_app().debug("no existed ue_context, Create one with ran_amf_id(%s)", ue_context_key.c_str());
uc = std::shared_ptr<ue_context>(new ue_context());
set_amf_ue_ngap_id_2_ue_context(amf_ue_ngap_id, uc);
//set_amf_ue_ngap_id_2_ue_context(amf_ue_ngap_id, uc);
set_ran_amf_id_2_ue_context(ue_context_key, uc);
}
if(uc.get() == nullptr){
Logger::amf_app().error("Failed to create ue_context with amf_ue_ngap_id(0x%x)", amf_ue_ngap_id);
Logger::amf_app().error("Failed to create ue_context with ran_amf_id(%s)", ue_context_key.c_str());
}else{
uc.get()->cgi = itti_msg.cgi;
uc.get()->tai = itti_msg.tai;
......@@ -214,3 +233,18 @@ void amf_app::handle_itti_message(itti_nas_signalling_establishment_request & it
void amf_app::handle_post_sm_context_response_error_400(){
Logger::amf_app().error("post sm context response error 400");
}
bool amf_app::generate_5g_guti(uint32_t ranid, long amfid, string &mcc, string &mnc, uint32_t& tmsi){
string ue_context_key = "app_ue_ranid_"+to_string(ranid)+":amfid_"+to_string(amfid);
if(!is_ran_amf_id_2_ue_context(ue_context_key)){
Logger::amf_app().error("no ue context for ran_amf_id(%s), exit", ue_context_key.c_str());
return false;
}
std::shared_ptr<ue_context> uc;
uc = ran_amf_id_2_ue_context(ue_context_key);
mcc = uc.get()->tai.mcc;
mnc = uc.get()->tai.mnc;
tmsi = golbal_tmsi;
golbal_tmsi ++;
return true;
}
......@@ -6,12 +6,14 @@
#include <shared_mutex>
#include <string>
#include <thread>
#include <sstream>
#include "amf_config.hpp"
#include "amf_module_from_config.hpp"
#include "itti_msg_amf_app.hpp"
#include "ue_context.hpp"
using namespace config;
using namespace std;
static uint32_t amf_app_ue_ngap_id_generator = 1;
......@@ -32,12 +34,20 @@ public://itti handlers
public://context management
std::map<long, std::shared_ptr<ue_context>> amf_ue_ngap_id2ue_ctx;
mutable std::shared_mutex m_amf_ue_ngap_id2ue_ctx;
std::map<std::string, std::shared_ptr<ue_context>> ue_ctx_key;
mutable std::shared_mutex m_ue_ctx_key;
bool is_amf_ue_id_2_ue_context(const long & amf_ue_ngap_id) const;
std::shared_ptr<ue_context> amf_ue_id_2_ue_context(const long & amf_ue_ngap_id) const;
void set_amf_ue_ngap_id_2_ue_context(const long & amf_ue_ngap_id, std::shared_ptr<ue_context> uc);
bool is_ran_amf_id_2_ue_context(const string & ue_context_key) const;
std::shared_ptr<ue_context> ran_amf_id_2_ue_context(const string & ue_context_key) const;
void set_ran_amf_id_2_ue_context(const string & ue_context_key, std::shared_ptr<ue_context> uc);
public:/*** SMF Client response handlers ****/
void handle_post_sm_context_response_error_400();
public:
bool generate_5g_guti(uint32_t ranid, long amfid, string &mcc, string &mnc, uint32_t& tmsi);
};
......
......@@ -33,6 +33,7 @@ extern amf_n1 * amf_n1_inst;
extern amf_n11 * amf_n11_inst;
extern amf_config amf_cfg;
extern amf_app * amf_app_inst;
extern statistics stacs;
Sha256 ctx;
......@@ -118,6 +119,7 @@ void amf_n1::handle_itti_message(itti_downlink_nas_transfer & itti_msg){
void amf_n1::handle_itti_message(itti_uplink_nas_data_ind & nas_data_ind){
long amf_ue_ngap_id = nas_data_ind.amf_ue_ngap_id;
uint32_t ran_ue_ngap_id = nas_data_ind.ran_ue_ngap_id;
string nas_context_key = "app_ue_ranid_"+to_string(ran_ue_ngap_id)+":amfid_"+to_string(amf_ue_ngap_id);// key for nas_context, option 1
std::string snn;
if(nas_data_ind.mnc.length() ==2)
snn = "5G:mnc0"+nas_data_ind.mnc+".mcc"+nas_data_ind.mcc+".3gppnetwork.org";
......@@ -130,7 +132,8 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind & nas_data_ind){
std::shared_ptr<nas_context> nc;
if(nas_data_ind.is_guti_valid){
std::string guti = "1234567890";//need modify
//std::string guti = "1234567890";//need modify
std::string guti = nas_data_ind.guti;
if(is_guti_2_nas_context(guti))
nc = guti_2_nas_context(guti);
else{
......@@ -149,6 +152,7 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind & nas_data_ind){
Logger::amf_n1().error("not 5GS MOBILITY MANAGEMENT message");
return;
}
uint8_t ulCount = 0;
switch(type){
case PlainNasMsg:{
Logger::amf_n1().debug("received plain nas message");
......@@ -156,7 +160,10 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind & nas_data_ind){
}break;
case IntegrityProtected:{
Logger::amf_n1().debug("received integrity protected nas message");
}//break;
ulCount = *((uint8_t*)bdata(recved_nas_msg)+6);
Logger::amf_n1().info("integrity protected message: ulCount(%d)", ulCount);
decoded_plain_msg = blk2bstr((uint8_t*)bdata(recved_nas_msg)+7, blength(recved_nas_msg)-7);
}break;
case IntegrityProtectedAndCiphered:{
Logger::amf_n1().debug("received integrity protected and ciphered nas message");
}//break;
......@@ -165,6 +172,10 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind & nas_data_ind){
}//break;
case IntegrityProtectedAndCipheredWithNew5GNASSecurityContext:{
Logger::amf_n1().debug("received integrity protected and ciphered with new security context nas message");
if(nc.get() == nullptr){
Logger::amf_n1().debug("abnormal condition: no existed nas_context. exit...");
return;
}
uint32_t mac32 = 0;
if(!nas_message_integrity_protected(nc.get()->security_ctx, NAS_MESSAGE_UPLINK, (uint8_t*)bdata(recved_nas_msg)+6, blength(recved_nas_msg)-6, mac32)){
//IA0_5G
......@@ -194,45 +205,56 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind & nas_data_ind){
if(nas_data_ind.is_nas_signalling_estab_req){
Logger::amf_n1().debug("recv nas signalling establishment request ...");
//dump_nas_message((uint8_t*)bdata(decoded_plain_msg), blength(decoded_plain_msg));
print_buffer("amf_n1", "Received Nas Message Buffer", (uint8_t*)bdata(decoded_plain_msg), blength(decoded_plain_msg));
nas_signalling_establishment_request_handle(nc, nas_data_ind.ran_ue_ngap_id, nas_data_ind.amf_ue_ngap_id, decoded_plain_msg, snn);
//change UE connection status CM-IDLE -> CM-CONNECTED
print_buffer("amf_n1", "decoded plain nas Message buffer", (uint8_t*)bdata(decoded_plain_msg), blength(decoded_plain_msg));
nas_signalling_establishment_request_handle(type, nc, nas_data_ind.ran_ue_ngap_id, nas_data_ind.amf_ue_ngap_id, decoded_plain_msg, snn, ulCount);
}else{
Logger::amf_n1().debug("recv uplink nas message ...");
print_buffer("amf_n1", "Received Nas Message Buffer", (uint8_t*)bdata(decoded_plain_msg), blength(decoded_plain_msg));
print_buffer("amf_n1", "decoded nas message buffer", (uint8_t*)bdata(decoded_plain_msg), blength(decoded_plain_msg));
uplink_nas_msg_handle(nas_data_ind.ran_ue_ngap_id, nas_data_ind.amf_ue_ngap_id, decoded_plain_msg);
}
}
/***************************************************** handlers for lower layer *************************/
void amf_n1::nas_signalling_establishment_request_handle(std::shared_ptr<nas_context> nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg, std::string snn){
void amf_n1::nas_signalling_establishment_request_handle(SecurityHeaderType type, std::shared_ptr<nas_context> nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg, std::string snn, uint8_t ulCount){
//1. Create nas context, or update nas context
if(nc.get() == nullptr){
if(nc.get() == nullptr && type == PlainNasMsg){
Logger::amf_n1().debug("no existing nas_context with amf_ue_ngap_id(0x%x) --> Create new one",amf_ue_ngap_id);
nc = std::shared_ptr<nas_context>(new nas_context);
set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
}else{
//Logger::amf_n1().debug("existing nas_context with amf_ue_ngap_id(0x%x) --> Update",amf_ue_ngap_id);
//nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
}
if(nc.get() == nullptr){
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id, amf_ue_ngap_id);
if(!nc.get()){
Logger::amf_n1().error("cannot allocate memory for new nas_context, exit...");
return;
}
set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
nc.get()->ctx_avaliability_ind = false;
nc.get()->ran_ue_ngap_id = ran_ue_ngap_id;
//change UE connection status CM-IDLE -> CM-CONNECTED
nc.get()->nas_status = "CM-CONNECTED";
nc.get()->amf_ue_ngap_id = amf_ue_ngap_id;
nc.get()->ran_ue_ngap_id = ran_ue_ngap_id;
nc.get()->serving_network = snn;
//stacs.UE_connected += 1;
}else{
//Logger::amf_n1().debug("existing nas_context with amf_ue_ngap_id(0x%x) --> Update",amf_ue_ngap_id);
//nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
}
//if(nc.get() == nullptr){
// response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id, amf_ue_ngap_id);
// return;
//}
//nc.get()->ctx_avaliability_ind = false;
//nc.get()->ran_ue_ngap_id = ran_ue_ngap_id;
//nc.get()->amf_ue_ngap_id = amf_ue_ngap_id;
//nc.get()->serving_network = snn;
uint8_t * buf = (uint8_t*)bdata(plain_msg);
uint8_t message_type = *(buf+2);
Logger::amf_n1().debug("nas message type(0x%x)", message_type);
switch(message_type){
case REGISTRATION_REQUEST:{//registration request
Logger::amf_n1().debug("received registration request messgae , handle ...");
registration_request_handle(true, nc, ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
registration_request_handle(true, nc, ran_ue_ngap_id, amf_ue_ngap_id, snn, plain_msg);
}break;
case SERVICE_REQUEST:{
Logger::amf_n1().debug("received service request messgae , handle ...");
nc.get()->security_ctx->ul_count.seq_num = ulCount;
service_request_handle(true, nc, ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
}break;
default:
......@@ -245,7 +267,7 @@ void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
uint8_t message_type = *(buf+2);
switch(message_type){
case REGISTRATION_REQUEST:{//registration request
registration_request_handle(false, nullptr,ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
//registration_request_handle(false, nullptr,ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
}break;
case AUTHENTICATION_RESPONSE:{
Logger::amf_n1().debug("received authentication response messgae , handle ...");
......@@ -267,6 +289,10 @@ void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
Logger::amf_n1().debug("received ul nas transport messgae , handle ...");
ul_nas_transport_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
}break;
case UE_INIT_DEREGISTER:{
Logger::amf_n1().debug("received de-registration request messgae , handle ...");
ue_initiate_de_registration_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
}break;
}
}
......@@ -292,6 +318,8 @@ bool amf_n1::check_security_header_type(SecurityHeaderType & type, uint8_t *buff
void amf_n1::service_request_handle(bool isNasSig, std::shared_ptr<nas_context> nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas){
//std::shared_ptr<nas_context> nc;
//nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
Logger::amf_n1().info("nas_context pointer(%p)", nc.get());
nas_secu_ctx * secu = nc.get()->security_ctx;
ServiceRequest *serReq = new ServiceRequest();
serReq->decodefrombuffer(nullptr, (uint8_t*)bdata(nas), blength(nas));
......@@ -306,15 +334,26 @@ void amf_n1::service_request_handle(bool isNasSig, std::shared_ptr<nas_context>
uint8_t *kamf = nc.get()->kamf[secu->vector_pointer];
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
Logger::amf_n1().debug("uplink count", secu->ul_count.seq_num);
Logger::amf_n1().debug("uplink count(%d)", secu->ul_count.seq_num);
print_buffer("amf_n1", "kamf", kamf, 32);
Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
bstring kgnb_bs = blk2bstr(kgnb, 32);
string supi = "imsi-" + nc.get()->imsi;
/* by liuyu */
supi2amfId[supi] = amf_ue_ngap_id;
Logger::amf_n1().debug("amf_ue_ngap_id-----------------------------------liuyu(%d)", amf_ue_ngap_id);
supi2ranId[supi] = ran_ue_ngap_id;
Logger::amf_n1().debug("ran_ue_ngap_id-----------------------------------liuyu(%d)",ran_ue_ngap_id);
Logger::amf_n1().debug("Key for pdu session context: supi(%s)", supi.c_str());
std::shared_ptr<pdu_session_context> psc;
if(amf_n11_inst->is_supi_to_pdu_ctx(supi)){
psc = amf_n11_inst->supi_to_pdu_ctx(supi);
if(!psc){
Logger::amf_n1().error("connot get pdu_session_context");
return;
}
}else{
Logger::amf_n1().error("Cannot get pdu_session_context with supi(%s)", supi.c_str());
}
......@@ -327,7 +366,7 @@ void amf_n1::service_request_handle(bool isNasSig, std::shared_ptr<nas_context>
itti_msg->is_sr = true;//service request indicator
itti_msg->pdu_session_id = psc.get()->pdu_session_id;
itti_msg->n2sm = psc.get()->n2sm;
Logger::amf_n1().debug("n2sm size in amf_n1(%d)", blength(psc.get()->n2sm));
//Logger::amf_n1().debug("n2sm size in amf_n1(%d)", blength(psc.get()->n2sm));
std::shared_ptr<itti_initial_context_setup_request> i = std::shared_ptr<itti_initial_context_setup_request>(itti_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
......@@ -335,23 +374,96 @@ void amf_n1::service_request_handle(bool isNasSig, std::shared_ptr<nas_context>
}
}
void amf_n1::registration_request_handle(bool isNasSig, std::shared_ptr<nas_context>nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring reg){
void amf_n1::update_ue_information_statics(ue_infos &ueItem, const string connStatus, const string registerStatus, uint32_t ranid, uint32_t amfid, string imsi, string guti, string mcc, string mnc, uint32_t cellId){
if(connStatus != "")
ueItem.connStatus = connStatus;
if(registerStatus != "")
ueItem.registerStatus = registerStatus;
if(ranid != 0)
ueItem.ranid = ranid;
if(amfid != 0)
ueItem.amfid = amfid;
if( imsi != "")
ueItem.imsi = imsi;
if(guti != "")
ueItem.guti = guti;
if(mcc != "")
ueItem.mcc = mcc;
if(mnc != "")
ueItem.mnc = mnc;
if(cellId != 0)
ueItem.cellId = cellId;
}
void amf_n1::registration_request_handle(bool isNasSig, std::shared_ptr<nas_context>nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, std::string snn, bstring reg){
//1. decode registration request message from liuyu
RegistrationRequest *regReq = new RegistrationRequest();
regReq->decodefrombuffer(nullptr, (uint8_t*)bdata(reg), blength(reg));
//2.4 check ie 5gs mobility identity(Mondantary IE)
std::string guti;
uint8_t mobility_id_type = regReq->getMobilityIdentityType();
switch(mobility_id_type){
case SUCI:{
nas::SUCI_imsi_t imsi;
if(!regReq->getSuciSupiFormatImsi(imsi)){
Logger::amf_n1().warn("No SUCI and IMSI for SUPI Format");
}else{
nc.get()->is_imsi_present = true;
nc.get()->imsi = imsi.mcc + imsi.mnc + imsi.msin;
Logger::amf_n1().debug("received imsi(%s)", nc.get()->imsi.c_str());
supi2amfId[("imsi-"+nc.get()->imsi)] = amf_ue_ngap_id;
supi2ranId[("imsi-"+nc.get()->imsi)] = ran_ue_ngap_id;
imsi2nas_context[("imsi-"+nc.get()->imsi)] = nc;
Logger::amf_n1().info("associating imsi(%s) with nas_context(%p)", ("imsi-"+nc.get()->imsi).c_str(), nc.get());
if(!nc.get()->is_stacs_available){
string ue_context_key = "app_ue_ranid_"+to_string(ran_ue_ngap_id)+":amfid_"+to_string(amf_ue_ngap_id);
std::shared_ptr<ue_context> uc;
//uc = amf_app_inst->amf_ue_id_2_ue_context(amf_ue_ngap_id);
Logger::amf_n1().info("try to find ue_context in amf_app using ran_amf_id(%s)", ue_context_key.c_str());
uc = amf_app_inst->ran_amf_id_2_ue_context(ue_context_key);
ue_infos ueItem;
update_ue_information_statics(ueItem, "CM-CONNECTED", "REGISTRATION-INITIATING", ran_ue_ngap_id, amf_ue_ngap_id, nc.get()->imsi, "", uc.get()->cgi.mcc, uc.get()->cgi.mnc, uc.get()->cgi.nrCellID);
nc.get()->is_stacs_available = true;
stacs.ues.push_back(ueItem);
}
//nc.get()->imsi = //need interface to transfer SUCI_imsi_t to string
}
}break;
case _5G_GUTI:{
guti = regReq->get_5g_guti();
if(!guti.compare("error")){
Logger::amf_n1().warn("No GUTI IE");
}
}break;
}
//2.4.1 try to get supi and format imsi
//2.4.2 try to get 5g-guti
//2.4.3 try to get ...
//3. create nas context
if(nc.get() == nullptr){
Logger::amf_n1().error("no nas context exists");
//try to get the GUTI -> nas_context
if(is_guti_2_nas_context(guti)){
nc = guti_2_nas_context(guti);
set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
supi2amfId[("imsi-"+nc.get()->imsi)] = amf_ue_ngap_id;
supi2ranId[("imsi-"+nc.get()->imsi)] = ran_ue_ngap_id;
}
else{
Logger::amf_n1().error("No existed nas_context with guti(%s)", guti.c_str());
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id, amf_ue_ngap_id);
return;
}
}else{
Logger::amf_n1().debug("existing nas_context --> Update");
//nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
}
if(nc.get() == nullptr){
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id, amf_ue_ngap_id);
return;
}
//if(nc.get() == nullptr){
// response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id, amf_ue_ngap_id);
// return;
//}
nc.get()->ran_ue_ngap_id = ran_ue_ngap_id;
nc.get()->amf_ue_ngap_id = amf_ue_ngap_id;
nc.get()->serving_network = snn;
//2. analysis the message IEs(encode RegistrationReject, if possible)
//2.2 check ie 5GS_Registration_type(Mandontary IE)
uint8_t reg_type; bool is_follow_on_req_pending;
......@@ -372,26 +484,6 @@ void amf_n1::registration_request_handle(bool isNasSig, std::shared_ptr<nas_cont
}
nc.get()->ngKsi = ngKSI;
//2.4 check ie 5gs mobility identity(Mondantary IE)
uint8_t mobility_id_type = regReq->getMobilityIdentityType();
switch(mobility_id_type){
case SUCI:{
nas::SUCI_imsi_t imsi;
if(!regReq->getSuciSupiFormatImsi(imsi)){
Logger::amf_n1().warn("No SUCI and IMSI for SUPI Format");
}else{
nc.get()->is_imsi_present = true;
nc.get()->imsi = imsi.mcc + imsi.mnc + imsi.msin;
Logger::amf_n1().debug("received imsi(%s)", nc.get()->imsi.c_str());
supi2amfId[("imsi-"+nc.get()->imsi)] = nc.get()->amf_ue_ngap_id;
supi2ranId[("imsi-"+nc.get()->imsi)] = nc.get()->ran_ue_ngap_id;
//nc.get()->imsi = //need interface to transfer SUCI_imsi_t to string
}
}break;
}
//2.4.1 try to get supi and format imsi
//2.4.2 try to get 5g-guti
//2.4.3 try to get ...
//2.5 try to get ie non-current native nas key set identity(Optional IE), used for inter-system change from S1 to N1
//2.6 try to get ie 5GMM Capability(Optional IE), not included for periodic registration updating procedure
uint8_t _5g_mm_cap = regReq->get5GMMCapability();
......@@ -412,6 +504,7 @@ void amf_n1::registration_request_handle(bool isNasSig, std::shared_ptr<nas_cont
Logger::amf_n1().warn("No Optional IE RequestedNssai avaliable");
}
nc.get()->requestedNssai = requestedNssai;
nc.get()->ctx_avaliability_ind = true;
//2.9 try to get ie Last visited registred TAI(OPtional IE), if provided
//2.10 try to get ie S1 Ue network capability(OPtional IE), if ue supports S1 mode
//2.11 try to get ie uplink data status(Optional IE), if UE has uplink user data to be sent
......@@ -421,6 +514,7 @@ void amf_n1::registration_request_handle(bool isNasSig, std::shared_ptr<nas_cont
switch(reg_type){
case INITIAL_REGISTRATION:{
run_initial_registration_procedure();//IEs?
run_registration_procedure(nc);
}break;
case MOBILITY_REGISTRATION_UPDATING:{
Logger::amf_n1().error("The network handling mobility registration ...");
......@@ -438,8 +532,7 @@ void amf_n1::registration_request_handle(bool isNasSig, std::shared_ptr<nas_cont
}break;
}
//5. run specific procedure for registration
nc.get()->ctx_avaliability_ind = true;
run_registration_procedure(nc);
//run_registration_procedure(nc);
//generation authentication vector, refer to openair-cn/tree/v0.5.0 (_emm_attach_identify())
//if(!generate_authentication_vector()){}
//encode AUTHENTICATION REQUEST message from liuyu
......@@ -526,7 +619,11 @@ void amf_n1::run_registration_procedure(std::shared_ptr<nas_context> &nc){
if(!nc.get()->is_auth_vectors_present){
Logger::amf_n1().debug("authentication vector in nas_context is not avaliable");
if(auth_vectors_generator(nc)){// all authentication in one(AMF)
nc.get()->ngKsi = 0x01;
ngksi_t ngksi = 0;
if(nc.get()->security_ctx && nc.get()->ngKsi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE){
ngksi = (nc.get()->ngKsi + 1) % (NGKSI_MAX_VALUE + 1);
}
nc.get()->ngKsi = ngksi;
handle_auth_vector_successful_result(nc);
}else{
Logger::amf_n1().error("request authentication vectors failure");
......@@ -535,10 +632,13 @@ void amf_n1::run_registration_procedure(std::shared_ptr<nas_context> &nc){
}else{
Logger::amf_n1().debug("authentication vector in nas_context is avaliable");
ngksi_t ngksi = 0;
if(nc.get()->security_ctx && nc.get()->security_ctx->ngksi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE){
ngksi = (nc.get()->security_ctx->ngksi + 1) % (NGKSI_MAX_VALUE + 1);
if(nc.get()->security_ctx && nc.get()->ngKsi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE){
ngksi = (nc.get()->ngKsi + 1) % (NGKSI_MAX_VALUE + 1);
Logger::amf_n1().debug("new ngKsi(%d)", ngksi);
// ... how to handle?
}
nc.get()->ngKsi = ngksi;
handle_auth_vector_successful_result(nc);
}
}else if(nc.get()->is_5g_guti_present){
nc.get()->is_auth_vectors_present = false;
......@@ -577,10 +677,10 @@ bool amf_n1::authentication_vectors_generator_in_ausf(std::shared_ptr<nas_contex
uint8_t kseaf[32];
Authentication_5gaka::derive_kseaf(nc.get()->serving_network, nc.get()->_5g_he_av[i].kausf, kseaf);
memcpy(nc.get()->_5g_av[i].kseaf, kseaf, 32);
print_buffer("amf_n1", "5G AV: rand", nc.get()->_5g_av[i].rand, 16);
print_buffer("amf_n1", "5G AV: autn", nc.get()->_5g_av[i].autn, 16);
print_buffer("amf_n1", "5G AV: kseaf", nc.get()->_5g_av[i].kseaf, 32);
print_buffer("amf_n1", "5G AV: hxres*", nc.get()->_5g_av[i].hxresStar, 16);
//print_buffer("amf_n1", "5G AV: rand", nc.get()->_5g_av[i].rand, 16);
//print_buffer("amf_n1", "5G AV: autn", nc.get()->_5g_av[i].autn, 16);
//print_buffer("amf_n1", "5G AV: kseaf", nc.get()->_5g_av[i].kseaf, 32);
//print_buffer("amf_n1", "5G AV: hxres*", nc.get()->_5g_av[i].hxresStar, 16);
}
return true;
}
......@@ -620,22 +720,22 @@ bool amf_n1::authentication_vectors_generator_in_udm(std::shared_ptr<nas_context
//uint8_t sqnak[6] = {0xb6, 0x22, 0xb7, 0x87, 0x4e, 0x86};
//test_generate_5g_he_av_in_udm(mysql_resp.opc, mysql_resp.key, sqnak, nc.get()->serving_network, vector[i]);
/******* end ***********/
uint8_t rand_[16] = {0x02, 0x27, 0x40, 0x55, 0xea, 0x5a, 0x2f, 0x7e, 0x3e, 0x87, 0x16, 0x4b, 0xdf, 0x80, 0xff, 0x32};
uint8_t sqn_[6] = {0x00, 0x00, 0x00, 0x00, 0x20, 0x9e};
memcpy(vector[i].rand, rand_, 16);
generate_5g_he_av_in_udm(mysql_resp.opc, nc.get()->imsi, mysql_resp.key, sqn_, nc.get()->serving_network, vector[i]);//serving network name
//uint8_t rand_[16] = {0x02, 0x27, 0x40, 0x55, 0xea, 0x5a, 0x2f, 0x7e, 0x3e, 0x87, 0x16, 0x4b, 0xdf, 0x80, 0xff, 0x32};
//uint8_t sqn_[6] = {0x00, 0x00, 0x00, 0x00, 0x20, 0x9e};
//memcpy(vector[i].rand, rand_, 16);
generate_5g_he_av_in_udm(mysql_resp.opc, nc.get()->imsi, mysql_resp.key, sqn, nc.get()->serving_network, vector[i]);//serving network name
}
mysql_push_rand_sqn (nc.get()->imsi, vector[MAX_5GS_AUTH_VECTORS - 1].rand, sqn);
}else{
Logger::amf_n1().debug("no auts ...");
Logger::amf_n1().debug("receive information from mysql with imsi(%s)", nc.get()->imsi.c_str());
print_buffer("amf_n1", "Received from MYSQL: rand", mysql_resp.rand, 16);
print_buffer("amf_n1", "Received from MYSQL: opc", mysql_resp.opc, 16);
print_buffer("amf_n1", "Received from MYSQL: key", mysql_resp.key, 16);
print_buffer("amf_n1", "Received from MYSQL: sqn", mysql_resp.sqn, 6);
//print_buffer("amf_n1", "Received from MYSQL: rand", mysql_resp.rand, 16);
//print_buffer("amf_n1", "Received from MYSQL: opc", mysql_resp.opc, 16);
//print_buffer("amf_n1", "Received from MYSQL: key", mysql_resp.key, 16);
//print_buffer("amf_n1", "Received from MYSQL: sqn", mysql_resp.sqn, 6);
for(int i=0; i< MAX_5GS_AUTH_VECTORS; i++){
generate_random (vector[i].rand, RAND_LENGTH);
print_buffer("amf_n1", "generated random: rand(5G HE AV)", vector[i].rand, 16);
//print_buffer("amf_n1", "generated random: rand(5G HE AV)", vector[i].rand, 16);
sqn = mysql_resp.sqn;
/** for test data *******/
//uint8_t newRAND[16] = {0x2c, 0x6e, 0xad, 0x35, 0x82, 0x7d, 0x01, 0xca, 0x4a, 0xc0, 0xfb, 0xf0, 0xaa, 0x31, 0x98, 0x4a};
......@@ -681,23 +781,16 @@ void amf_n1::test_generate_5g_he_av_in_udm(const uint8_t opc[16], uint8_t key[1
void amf_n1::generate_random(uint8_t *random_p, ssize_t length){
gmp_randinit_default(random_state.state);
gmp_randseed_ui(random_state.state, time(NULL));
Logger::amf_n1().debug("generate rand");
if(!amf_cfg.auth_para.random.compare("true")){
Logger::amf_n1().debug("amf config random -> true");
random_t random_nb;
mpz_init(random_nb);
Logger::amf_n1().debug("debug test point 1.1");
mpz_init_set_ui(random_nb, 0);
Logger::amf_n1().debug("debug test point 1.2");
pthread_mutex_lock(&random_state.lock);
Logger::amf_n1().debug("debug test point 1.3");
mpz_urandomb(random_nb, random_state.state, 8 * length);
Logger::amf_n1().debug("debug test point 1.4");
pthread_mutex_unlock(&random_state.lock);
Logger::amf_n1().debug("debug test point 1.5");
mpz_export(random_p, NULL, 1, length, 0, 0, random_nb);
int r = 0, mask = 0, shift;
Logger::amf_n1().debug("debug test point 1");
for (int i = 0; i < length; i++) {
if ((i % sizeof(i)) == 0)
r = rand();
......@@ -705,7 +798,6 @@ void amf_n1::generate_random(uint8_t *random_p, ssize_t length){
mask = 0xFF << shift;
random_p[i] = (r & mask) >> shift;
}
Logger::amf_n1().debug("debug test point 2");
}else{
Logger::amf_n1().error("amf config random -> false");
pthread_mutex_lock(&random_state.lock);
......@@ -724,30 +816,29 @@ void amf_n1::generate_random(uint8_t *random_p, ssize_t length){
uint8_t ik[16];
uint8_t ak[6];
uint64_t _imsi = fromString<uint64_t>(imsi);
Logger::amf_n1().debug("call f1");
//f1(key, vector.rand, sqn, amf, mac_a);// to compute MAC, Figure 7, ts33.102
print_buffer("amf_n1", "Parameters For Authentication-Algorithms: rand", vector.rand, 16);
print_buffer("amf_n1", "Parameters For Key-Derive-Function: snn", (uint8_t*)serving_network.c_str(), serving_network.size());
//print_buffer("amf_n1", "Parameters For Authentication-Algorithms: rand", vector.rand, 16);
//print_buffer("amf_n1", "Parameters For Key-Derive-Function: snn", (uint8_t*)serving_network.c_str(), serving_network.size());
Authentication_5gaka::f1(opc, key, vector.rand, sqn, amf, mac_a);// to compute MAC, Figure 7, ts33.102
print_buffer("amf_n1", "Result For F1-Alg: mac_a", mac_a, 8);
Logger::amf_n1().debug("call f2345");
//print_buffer("amf_n1", "Result For F1-Alg: mac_a", mac_a, 8);
//Logger::amf_n1().debug("call f2345");
//f2345(key, vector.rand, vector.xres, ck, ik, ak);// to compute XRES, CK, IK, AK
Authentication_5gaka::f2345(opc, key, vector.rand, vector.xres, ck, ik, ak);// to compute XRES, CK, IK, AK
print_buffer("amf_n1", "Result For F2345-Alg: xres", vector.xres, 8);
print_buffer("amf_n1", "Result For F2345-Alg: ck", ck, 16);
print_buffer("amf_n1", "Result For F2345-Alg: ik", ik, 16);
print_buffer("amf_n1", "Result For F2345-Alg: ak", ak, 6);
//print_buffer("amf_n1", "Result For F2345-Alg: xres", vector.xres, 8);
//print_buffer("amf_n1", "Result For F2345-Alg: ck", ck, 16);
//print_buffer("amf_n1", "Result For F2345-Alg: ik", ik, 16);
//print_buffer("amf_n1", "Result For F2345-Alg: ak", ak, 6);
annex_a_4_33501(ck, ik, vector.xres, vector.rand, serving_network, vector.xresStar);
print_buffer("amf_n1", "Result For KDF: xres*(5G HE AV)", vector.xresStar, 16);
Logger::amf_n1().debug("generate autn");
//print_buffer("amf_n1", "Result For KDF: xres*(5G HE AV)", vector.xresStar, 16);
//Logger::amf_n1().debug("generate autn");
Authentication_5gaka::generate_autn(sqn, ak, amf, mac_a, vector.autn);// generate AUTN
print_buffer("amf_n1", "generated autn(5G HE AV)", vector.autn, 16);
Logger::amf_n1().debug("derive kausf");
//print_buffer("amf_n1", "generated autn(5G HE AV)", vector.autn, 16);
//Logger::amf_n1().debug("derive kausf");
Authentication_5gaka::derive_kausf(ck, ik, serving_network, sqn, ak, vector.kausf);//derive Kausf
print_buffer("amf_n1", "Result For KDF: Kausf(5G HE AV)", vector.kausf, 32);
Logger::amf_n1().debug("generate_5g_he_av_in_udm finished!");
ue_authentication_simulator(vector.rand, vector.autn);
//print_buffer("amf_n1", "Result For KDF: Kausf(5G HE AV)", vector.kausf, 32);
//Logger::amf_n1().debug("generate_5g_he_av_in_udm finished!");
//ue_authentication_simulator(vector.rand, vector.autn);
return;
}
......@@ -757,7 +848,6 @@ void amf_n1::annex_a_4_33501(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uin
uint8_t S[100];
S[0] = 0x6B;
memcpy (&S[1], netName.buf, netName.size);
printf("snn length(0x%x)\n", netName.size);
S[1+netName.size] = (netName.size & 0xff00)>>8;
S[2+netName.size] = (netName.size & 0x00ff);
for(int i=0; i<16; i++)
......@@ -800,11 +890,13 @@ void amf_n1::handle_auth_vector_successful_result(std::shared_ptr<nas_context> n
Logger::amf_n1().debug("Received security vectors from AUSF/UDM, try to setup security with the UE");
nc.get()->is_auth_vectors_present = true;
ngksi_t ngksi = 0;
if(!nc.get()->security_ctx){
nc.get()->security_ctx = new nas_secu_ctx();
if(nc.get()->security_ctx && nc.get()->security_ctx->ngksi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE)
if(nc.get()->security_ctx && nc.get()->ngKsi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE)
ngksi = (nc.get()->security_ctx->ngksi + 1) % (NGKSI_MAX_VALUE + 1);
// ensure which vector is avaliable?
nc.get()->ngKsi = ngksi;
}
int vindex = nc.get()->security_ctx->vector_pointer;
if(!start_authentication_procedure(nc, vindex, nc.get()->ngKsi)){
Logger::amf_n1().error("start authentication procedure failure, reject...");
......@@ -877,12 +969,14 @@ bool amf_n1::check_nas_common_procedure_on_going(std::shared_ptr<nas_context> nc
void amf_n1::authentication_response_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg){
std::shared_ptr<nas_context> nc;
Logger::amf_n1().info("Try to find nas_context using amf_ue_ngap_id(0x%x)", amf_ue_ngap_id);
if(!is_amf_ue_id_2_nas_context(amf_ue_ngap_id)){
Logger::amf_n1().error("No existed nas context for UE with amf_ue_ngap_id(0x%x)", amf_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id, amf_ue_ngap_id);//cause?
return;
}
nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
Logger::amf_n1().info("Found nas_context(%p) with amf_ue_ngap_id(0x%x)", nc.get(), amf_ue_ngap_id);
//0. stop timer? common procedure finished!
nc.get()->is_common_procedure_for_authentication_running = false;
// MM state: COMMON-PROCEDURE-INITIATED -> DEREGISTRED
......@@ -1031,7 +1125,7 @@ bool amf_n1::start_security_mode_control_procedure(std::shared_ptr<nas_context>n
itti_send_dl_nas_buffer_to_task_n2(intProtctedNas, nc.get()->ran_ue_ngap_id, nc.get()->amf_ue_ngap_id);
//secu_ctx->dl_count.seq_num ++;
return true;
}
int amf_n1::security_select_algorithms(uint8_t nea, uint8_t nia, uint8_t &amf_nea, uint8_t &amf_nia){
......@@ -1054,14 +1148,24 @@ int amf_n1::security_select_algorithms(uint8_t nea, uint8_t nia, uint8_t &amf_ne
void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas_msg){
Logger::amf_n1().debug("handling security mode complete ...");
string ue_context_key = "app_ue_ranid_"+to_string(ran_ue_ngap_id)+":amfid_"+to_string(amf_ue_ngap_id);
std::shared_ptr<ue_context> uc;
uc = amf_app_inst->amf_ue_id_2_ue_context(amf_ue_ngap_id);
//uc = amf_app_inst->amf_ue_id_2_ue_context(amf_ue_ngap_id);
Logger::amf_n1().info("Try to find ue_context in amf_app using ran_amf_id(%s)", ue_context_key.c_str());
uc = amf_app_inst->ran_amf_id_2_ue_context(ue_context_key);
Logger::amf_n1().info("Found ue_context(%p) in amf_app using ran_amf_id(%s)", uc.get(), ue_context_key.c_str());
// encoding REGISTRATION ACCEPT
RegistrationAccept * regAccept = new RegistrationAccept();
regAccept->setHeader(PLAIN_5GS_MSG);
regAccept->set_5GS_Registration_Result(false, false, false, 0x01);
regAccept->set5G_GUTI(amf_cfg.guami.mcc, amf_cfg.guami.mnc, amf_cfg.guami.regionID, amf_cfg.guami.AmfSetID, amf_cfg.guami.AmfPointer, 0x264a34c0);
string mcc;
string mnc;
uint32_t tmsi;
if(!amf_app_inst->generate_5g_guti(ran_ue_ngap_id, amf_ue_ngap_id, mcc, mnc, tmsi)){
Logger::amf_n1().error("generate 5G GTUI error! exit");
return;
}
regAccept->set5G_GUTI(mcc, mnc, amf_cfg.guami.regionID, amf_cfg.guami.AmfSetID, amf_cfg.guami.AmfPointer, tmsi);
std::vector<p_tai_t> tai_list;
p_tai_t item0;
......@@ -1076,15 +1180,15 @@ void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id, long amf_ue_
std::vector<struct SNSSAI_s> nssai;
SNSSAI_t snssai;
snssai.sst = 0;
snssai.sst = 1;
snssai.sd = -1;
snssai.mHplmnSst = -1;
snssai.mHplmnSd = -1;
nssai.push_back(snssai);
regAccept->setALLOWED_NSSAI(nssai);
//std::string guti = amf_cfg.guami.mcc + amf_cfg.guami.mnc + amf_cfg.guami.regionID + amf_cfg.guami.AmfSetID + amf_cfg.guami.AmfPointer + "0001";
std::string guti = "1234567890";
std::string guti = mcc + mnc + amf_cfg.guami.regionID + amf_cfg.guami.AmfSetID + amf_cfg.guami.AmfPointer + std::to_string(tmsi);
//std::string guti = "1234567890";
Logger::amf_n1().debug("allocated guti %s", guti.c_str());
regAccept->set_5GS_Network_Feature_Support(0x00, 0x00);
......@@ -1106,9 +1210,19 @@ void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id, long amf_ue_
//encoding InitialContextSetupRequest(NGAP message) back
std::shared_ptr<nas_context> nc;
nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
Logger::amf_n1().info("UE[imsi:%s][guti:%s][current ranid:%d][current amfid:%d] has been registred into network", nc.get()->imsi.c_str(), guti.c_str(), ran_ue_ngap_id, amf_ue_ngap_id);
if(nc.get()->is_stacs_available){
int index = 0;
for(int i=0; i<stacs.ues.size(); i++){
if(!(nc.get()->imsi).compare(stacs.ues[i].imsi)){
index = i; break;
}
}
update_ue_information_statics(stacs.ues[index], "", "RM-REGISTRED", ran_ue_ngap_id, amf_ue_ngap_id, "", guti, "", "", 0);
}
//Logger::amf_n1().info("security mode complete: nas_context pointer(%p)", nc.get());
set_guti_2_nas_context(guti, nc);
nc.get()->is_common_procedure_for_security_mode_control_running = false;
nas_secu_ctx * secu = nc.get()->security_ctx;
//protect nas message
bstring protectedNas;
......@@ -1117,6 +1231,7 @@ void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id, long amf_ue_
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
Authentication_5gaka::derive_kgnb(0, 0x01, kamf, kgnb);
print_buffer("amf_n1", "kamf", kamf, 32);
//Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
bstring kgnb_bs = blk2bstr(kgnb, 32);
itti_initial_context_setup_request * itti_msg = new itti_initial_context_setup_request(TASK_AMF_N1, TASK_AMF_N2);
......@@ -1271,6 +1386,15 @@ bool amf_n1::nas_message_cipher_protected(nas_secu_ctx *nsc, uint8_t direction,
void amf_n1::run_initial_registration_procedure(){
}
void amf_n1::ue_initiate_de_registration_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas){
string guti = "1234567890";//need modify
std::shared_ptr<nas_context> nc;
nc = guti_2_nas_context(guti);
nc.get()-> is_auth_vectors_present = false;
nc.get()-> is_current_security_avaliable = false;
nc.get()->security_ctx->sc_type = SECURITY_CTX_TYPE_NOT_AVAILABLE;
}
void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas){
//1. decode UL_NAS_TRANSPORT message
Logger::amf_n1().debug("ul_nas_transport_handle");
......@@ -1279,10 +1403,13 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_i
uint8_t payload_type = ulNas->getPayloadContainerType();
uint8_t pdu_session_id = ulNas->getPduSessionId();
uint8_t request_type = ulNas->getRequestType();
bstring dnn;
bstring dnn = bfromcstr("default");
bstring sm_msg;
if(ulNas->getDnn(dnn)){
} else {
dnn = bfromcstr("default");
}
print_buffer("amf_n1", "decoded dnn bitstring out", (uint8_t*)bdata(dnn), blength(dnn));
switch(payload_type){
case N1_SM_INFORMATION:{
if(!ulNas->getPayloadContainer(sm_msg)){
......@@ -1381,7 +1508,7 @@ void amf_n1::run_mobility_registration_update_procedure(std::shared_ptr<nas_cont
regAccept->setALLOWED_NSSAI(nssai);
//std::string guti = amf_cfg.guami.mcc + amf_cfg.guami.mnc + amf_cfg.guami.regionID + amf_cfg.guami.AmfSetID + amf_cfg.guami.AmfPointer + "0001";
std::string guti = "1234567890";
std::string guti = "1234567890";//need modify
Logger::amf_n1().debug("allocated guti %s", guti.c_str());
regAccept->set_5GS_Network_Feature_Support(0x00, 0x00);
......@@ -1412,6 +1539,7 @@ void amf_n1::run_mobility_registration_update_procedure(std::shared_ptr<nas_cont
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
print_buffer("amf_n1", "kamf", kamf, 32);
//Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
bstring kgnb_bs = blk2bstr(kgnb, 32);
itti_initial_context_setup_request * itti_msg = new itti_initial_context_setup_request(TASK_AMF_N1, TASK_AMF_N2);
......
......@@ -8,6 +8,7 @@
#include "itti_msg_n1.hpp"
#include "bstrlib.h"
#include "3gpp_ts24501.hpp"
#include "amf_statistics.hpp"
#include <pthread.h>
#include <stdlib.h>
......@@ -42,12 +43,13 @@ public:
void handle_itti_message(itti_uplink_nas_data_ind&);
void handle_itti_message(itti_downlink_nas_transfer & itti_msg);
public: // nas message decode
void nas_signalling_establishment_request_handle(std::shared_ptr<nas_context> nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg, std::string snn);
void nas_signalling_establishment_request_handle(SecurityHeaderType type, std::shared_ptr<nas_context> nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg, std::string snn, uint8_t ulCount);
void uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg);
bool check_security_header_type(SecurityHeaderType & type, uint8_t *buffer);
public:
std::map<long, std::shared_ptr<nas_context>> amfueid2nas_context; // amf ue ngap id
std::map<string, std::shared_ptr<nas_context>> imsi2nas_context;
std::map<std::string, long> supi2amfId;
std::map<std::string, uint32_t> supi2ranId;
......@@ -64,7 +66,8 @@ public:
database_t *db_desc;
private://nas message handlers
void registration_request_handle(bool isNasSig, std::shared_ptr<nas_context>nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring reg);
void ue_initiate_de_registration_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas);
void registration_request_handle(bool isNasSig, std::shared_ptr<nas_context>nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, std::string snn, bstring reg);
void authentication_response_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg);
void authentication_failure_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg);
void security_mode_complete_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas_msg);
......@@ -110,6 +113,8 @@ public:
void annex_a_4_33501(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], std::string serving_network, uint8_t *output);
public:
void send_itti_to_smf_services_consumer(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, uint8_t request_type, uint8_t pdu_session_id, bstring dnn, bstring sm_msg);
public:
void update_ue_information_statics(ue_infos &ueItem, const string connStatus, const string registerStatus, uint32_t ranid, uint32_t amfid, string imsi, string guti, string mcc, string mnc, uint32_t cellId);
};
}
......
......@@ -77,6 +77,11 @@ void amf_n11_task(void*){
itti_smf_services_consumer *m = dynamic_cast<itti_smf_services_consumer*>(msg);
amf_n11_inst->handle_itti_message(ref(*m));
}break;
case NSMF_PDU_SESS_UPDATE_SMCTX:{
Logger::task_amf_n11().info("receive NSMF_PDU_SESS_UPDATE_SMCTX, handling ...");
itti_nsmf_pdusession_update_sm_context *m = dynamic_cast<itti_nsmf_pdusession_update_sm_context*>(msg);
amf_n11_inst->handle_itti_message(ref(*m));
}break;
case PDU_SESS_RES_SET_RESP:{
Logger::task_amf_n11().info("receive PDU_SESS_RES_SET_RESP, handling ...");
itti_pdu_session_resource_setup_response *m = dynamic_cast<itti_pdu_session_resource_setup_response*>(msg);
......@@ -98,7 +103,8 @@ amf_n11::amf_n11(){
amf_n11::~amf_n11(){}
/***************************** itti message handlers *********************************/
void amf_n11::handle_itti_message(itti_pdu_session_resource_setup_response &itti_msg){
void amf_n11::handle_itti_message(itti_pdu_session_resource_setup_response &itti_msg){}
void amf_n11::handle_itti_message(itti_nsmf_pdusession_update_sm_context &itti_msg){
string supi = pduid2supi.at(itti_msg.pdu_session_id);
Logger::amf_n11().debug("Try to find supi(%s) from pdusession_id(%d)", supi.c_str(), itti_msg.pdu_session_id);
std::shared_ptr<pdu_session_context> psc;
......@@ -117,7 +123,7 @@ void amf_n11::handle_itti_message(itti_pdu_session_resource_setup_response &itti
}else{
smf_selection_from_context(smf_addr);
}
string remote_uri = smf_addr + "/nsmf-pdusession/v2/sm-contexts/" + supi + "/modify";
string remote_uri = smf_addr + "/nsmf-pdusession/v2/sm-contexts/" + "1" + "/modify";//scid
nlohmann::json pdu_session_update_request;
pdu_session_update_request["n2SmInfoType"] = "PDU_RES_SETUP_RSP";
pdu_session_update_request["n2SmInfo"]["contentId"] = "n2SmMsg";
......@@ -139,13 +145,22 @@ void amf_n11::handle_itti_message(itti_smf_services_consumer& smf){
psc = std::shared_ptr<pdu_session_context>(new pdu_session_context());
set_supi_to_pdu_ctx(supi, psc);
}
pduid2supi[smf.pdu_sess_id] = supi;
psc.get()->amf_ue_ngap_id = nc.get()->amf_ue_ngap_id;
psc.get()->ran_ue_ngap_id = nc.get()->ran_ue_ngap_id;
psc.get()->req_type = smf.req_type;
psc.get()->pdu_session_id = smf.pdu_sess_id;
//parse binary dnn and store
bstring bdnn = smf.dnn;
string dnn = bstring2charString(bdnn);
std::string dnn = "default";
if ((smf.dnn != nullptr) && (blength(smf.dnn) > 0)){
char * tmp = bstring2charString(smf.dnn);
dnn = tmp;
free (tmp);
tmp = nullptr;
}
Logger::amf_n11().debug("requested DNN: %s", dnn.c_str());
psc.get()->dnn = dnn;
......@@ -176,14 +191,14 @@ void amf_n11::handle_pdu_session_initial_request(string supi, std::shared_ptr<pd
pdu_session_establishment_request["supi"] = supi.c_str();
pdu_session_establishment_request["pei"] = "imei-200000000000001";
pdu_session_establishment_request["gpsi"] = "msisdn-200000000001";
pdu_session_establishment_request["dnn"] = "carrier.com";
pdu_session_establishment_request["sNssai"]["sst"] = 222;
pdu_session_establishment_request["sNssai"]["sd"] = "123";
pdu_session_establishment_request["dnn"] = dnn.c_str();
pdu_session_establishment_request["sNssai"]["sst"] = 1;
pdu_session_establishment_request["sNssai"]["sd"] = "0";
pdu_session_establishment_request["pduSessionId"] = psc.get()->pdu_session_id;
pdu_session_establishment_request["requestType"] = "INITIAL_REQUEST";
pdu_session_establishment_request["servingNfId"] = "servingNfId";
pdu_session_establishment_request["servingNetwork"]["mcc"] = "208";
pdu_session_establishment_request["servingNetwork"]["mnc"] = "95";
pdu_session_establishment_request["servingNetwork"]["mcc"] = "460";
pdu_session_establishment_request["servingNetwork"]["mnc"] = "011";
pdu_session_establishment_request["anType"] = "3GPP_ACCESS";
pdu_session_establishment_request["smContextStatusUri"] = "smContextStatusUri";
......@@ -278,36 +293,29 @@ void amf_n11::curl_http_client(string remoteUri, string jsonData, string n1SmMsg
//curl_mime_name (part, "n1SmMsg");
}
Logger::amf_n11().debug("is there ok?");
if(n2SmMsg != ""){
Logger::amf_n11().debug("is there ok? n2");
unsigned char *n2_msg_hex = format_string_as_hex(n2SmMsg);
part = curl_mime_addpart(mime);
curl_mime_data(part, reinterpret_cast<const char*>(n2_msg_hex), n2SmMsg.length()/2);
curl_mime_type(part, "application/vnd.3gpp.5gngap");
curl_mime_type(part, "application/vnd.3gpp.ngap");
//curl_mime_name (part, "n2SmMsg");
}
Logger::amf_n11().debug("is there ok?1");
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
//res = curl_easy_perform(curl);
Logger::amf_n11().debug("is there ok?2");
// Response information.
long httpCode(0);
std::unique_ptr<std::string> httpData(new std::string());
Logger::amf_n11().debug("is there ok?3");
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
Logger::amf_n11().debug("is there ok?4");
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
Logger::amf_n11().debug("is there ok?5");
//get cause from the response
string response = *httpData.get();
string jsonData = "";
......
......@@ -17,6 +17,7 @@ public:
void handle_itti_message(itti_smf_services_consumer &);
void handle_pdu_session_initial_request(string supi, std::shared_ptr<pdu_session_context> psc, string smf_addr, bstring sm_msg, string dnn);
void handle_itti_message(itti_pdu_session_resource_setup_response &itti_msg);
void handle_itti_message(itti_nsmf_pdusession_update_sm_context &itti_msg);
public:
std::map<string, std::shared_ptr<pdu_session_context>> supi2pdu; // amf ue ngap id
mutable std::shared_mutex m_supi2pdu;
......
......@@ -121,6 +121,8 @@ void amf_n2::handle_itti_message(itti_ng_setup_request & itti_msg){
Logger::amf_n2().debug("Update gNB context with assoc id (%d)", itti_msg.assoc_id);
}
gnb_infos gnbItem;
//Get IE Global RAN Node ID
uint32_t gnb_id; string gnb_mcc; string gnb_mnc;
if(!itti_msg.ngSetupReq->getGlobalGnbID(gnb_id, gnb_mcc, gnb_mnc)){
......@@ -129,12 +131,14 @@ void amf_n2::handle_itti_message(itti_ng_setup_request & itti_msg){
}
Logger::amf_n2().debug("IE GlobalGNBID(0x%x)",gnb_id);
gc->globalRanNodeId = gnb_id;
gnbItem.gnb_id = gnb_id;
string gnb_name;
if(!itti_msg.ngSetupReq->getRanNodeName(gnb_name)){
Logger::amf_n2().warn("IE RanNodeName not existed");
}else{
gc->gnb_name = gnb_name;
gnbItem.gnb_name = gnb_name;
Logger::amf_n2().debug("IE RanNodeName(%s)",gnb_name.c_str());
}
......@@ -149,7 +153,9 @@ void amf_n2::handle_itti_message(itti_ng_setup_request & itti_msg){
if(!itti_msg.ngSetupReq->getSupportedTAList(s_ta_list)){//getSupportedTAList
return;
}
gnbItem.mcc = s_ta_list[0].b_plmn_list[0].mcc;
gnbItem.mnc = s_ta_list[0].b_plmn_list[0].mnc;
gnbItem.tac = s_ta_list[0].tac;
//association GlobalRANNodeID with assoc_id
//store RAN Node Name in gNB context, if present
//verify PLMN Identity and TAC with configuration and store supportedTAList in gNB context, if verified; else response NG SETUP FAILURE with cause "Unknown PLMN"(9.3.1.2, ts38413)
......@@ -208,6 +214,7 @@ void amf_n2::handle_itti_message(itti_ng_setup_request & itti_msg){
gc.get()->ng_state = NGAP_READY;
Logger::amf_n2().debug("gnb with [gnb_id(0x%x), assoc_id(%d)] has been attached to AMF", gc.get()->globalRanNodeId, itti_msg.assoc_id);
stacs.gNB_connected += 1;
stacs.gnbs.push_back(gnbItem);
return;
}
......@@ -243,47 +250,36 @@ void amf_n2::handle_itti_message(itti_initial_ue_message &init_ue_msg){
if(!is_ran_ue_id_2_ne_ngap_context(ran_ue_ngap_id)){
Logger::amf_n2().debug("Create a new ue ngap context with ran_ue_ngap_id(0x%x)", ran_ue_ngap_id);
unc = std::shared_ptr<ue_ngap_context>(new ue_ngap_context());
Logger::amf_n2().debug("testing 1");
set_ran_ue_ngap_id_2_ue_ngap_context(ran_ue_ngap_id, unc);
Logger::amf_n2().debug("testing 2");
}else{
unc = ran_ue_id_2_ue_ngap_context(ran_ue_ngap_id);
}
if(unc.get() == nullptr){
Logger::amf_n2().error("Failed to get ue ngap context for ran_ue_ngap_id(0x%x)",21);
}else{
Logger::amf_n2().debug("testing 3");
//store information into ue ngap context
unc.get()->ran_ue_ngap_id = ran_ue_ngap_id;
Logger::amf_n2().debug("testing 4");
unc.get()->sctp_stream_recv = init_ue_msg.stream;
Logger::amf_n2().debug("testing 5");
unc.get()->sctp_stream_send == gc.get()->next_sctp_stream;
Logger::amf_n2().debug("testing 6");
gc.get()->next_sctp_stream += 1;
if(gc.get()->next_sctp_stream >= gc.get()->instreams)
gc.get()->next_sctp_stream = 1;
unc.get()->gnb_assoc_id = init_ue_msg.assoc_id;
NrCgi_t cgi;
Tai_t tai;
Logger::amf_n2().debug("testing 7");
if(init_ue_msg.initUeMsg->getUserLocationInfoNR(cgi, tai)){
Logger::amf_n2().debug("testing 8");
itti_msg->cgi = cgi;
itti_msg->tai = tai;
}else{
Logger::amf_n2().error("Missing Mondontary IE UserLocationInfoNR");
return;
}
Logger::amf_n2().debug("testing 9");
if(init_ue_msg.initUeMsg->getRRCEstablishmentCause() == -1){
Logger::amf_n2().warn("IE RRCEstablishmentCause not present");
itti_msg->rrc_cause = -1;//not present
}else{
itti_msg->rrc_cause = init_ue_msg.initUeMsg->getRRCEstablishmentCause();
Logger::amf_n2().debug("testing 10");
}
Logger::amf_n2().debug("testing 11");
#if 0
if(init_ue_msg.initUeMsg->getUeContextRequest() == -1){
Logger::amf_n2().warn("IE UeContextRequest not present");
......@@ -303,8 +299,6 @@ void amf_n2::handle_itti_message(itti_initial_ue_message &init_ue_msg){
Logger::amf_n2().debug("5g_s_tmsi true");
}
Logger::amf_n2().debug("testing 13");
uint8_t *nas_buf;
size_t nas_len = 0;
if(init_ue_msg.initUeMsg->getNasPdu(nas_buf,nas_len)){
......@@ -349,7 +343,7 @@ void amf_n2::handle_itti_message(itti_ul_nas_transport &ul_nas_transport){
}
if(unc.get()->ng_ue_state != NGAP_UE_CONNECTED){
Logger::amf_n2().error("Received NGAP UPLINK_NAS_TRANSPORT while UE in state != NGAP_UE_CONNECTED");
return;
//return;
}
itti_uplink_nas_data_ind * itti_msg = new itti_uplink_nas_data_ind(TASK_AMF_N2, TASK_AMF_N1);
itti_msg->is_nas_signalling_estab_req = false;
......@@ -437,30 +431,23 @@ void amf_n2::handle_itti_message(itti_initial_context_setup_request &itti_msg){
std::vector<PDUSessionResourceSetupRequestItem_t>list;
PDUSessionResourceSetupRequestItem_t item;
item.pduSessionId = itti_msg.pdu_session_id;
item.s_nssai.sst = "00";
item.s_nssai.sd = "none";
item.s_nssai.sst = "01";
item.s_nssai.sd = "";
item.pduSessionNAS_PDU = NULL;
Logger::amf_n2().debug("Encoding parameters for service request, testing point 0");
bstring n2sm = itti_msg.n2sm;
Logger::amf_n2().debug("Encoding parameters for service request, testing point 0.1 n2sm_size(%d)", blength(itti_msg.n2sm));
Logger::amf_n2().debug("Encoding parameters for service request, testing point 1");
if(blength(itti_msg.n2sm) != 0){
item.pduSessionResourceSetupRequestTransfer.buf = (uint8_t*)bdata(itti_msg.n2sm);
Logger::amf_n2().debug("Encoding parameters for service request, testing point 1.1");
item.pduSessionResourceSetupRequestTransfer.size = blength(itti_msg.n2sm);
}else{
Logger::amf_n2().error("n2sm empty!");
}
list.push_back(item);
Logger::amf_n2().debug("Encoding parameters for service request, testing point 2");
msg->setPduSessionResourceSetupRequestList(list);
Logger::amf_n2().debug("Encoding parameters for service request, testing point 3");
msg->setUEAggregateMaxBitRate(0x08a7d8c0, 0x20989680);
Logger::amf_n2().debug("Encoding parameters for service request, testing point 4");
}
uint8_t buffer[7000];
int encoded_size = msg->encode2buffer(buffer, 7000);
uint8_t buffer[10000];
int encoded_size = msg->encode2buffer(buffer, 10000);
bstring b = blk2bstr(buffer, encoded_size);
sctp_s_38412.sctp_send_msg(gc.get()->sctp_assoc_id, unc.get()->sctp_stream_send,&b);
}
......@@ -491,8 +478,8 @@ void amf_n2::handle_itti_message(itti_pdu_session_resource_setup_request &itti_m
nas_pdu[blength(itti_msg.nas)] = '\0';
item.pduSessionNAS_PDU = nas_pdu;//(uint8_t*)bdata(itti_msg.nas);
item.sizeofpduSessionNAS_PDU = blength(itti_msg.nas);
item.s_nssai.sst = "00";
item.s_nssai.sd = "none";
item.s_nssai.sst = "01";
item.s_nssai.sd = "";
item.pduSessionResourceSetupRequestTransfer.buf = (uint8_t*)bdata(itti_msg.n2sm);
item.pduSessionResourceSetupRequestTransfer.size = blength(itti_msg.n2sm);
list.push_back(item);
......@@ -505,30 +492,19 @@ void amf_n2::handle_itti_message(itti_pdu_session_resource_setup_request &itti_m
}
void amf_n2::handle_itti_message(itti_ue_context_release_request &itti_msg){
Logger::amf_n2().debug("handle_itti_message ...");
Logger::amf_n2().debug("handling ue context release request ...");
unsigned long amf_ue_ngap_id = itti_msg.ueCtxRel->getAmfUeNgapId();
Logger::amf_n2().debug("handle_itti_message ... test point 0");
uint32_t ran_ue_ngap_id = itti_msg.ueCtxRel->getRanUeNgapId();
Logger::amf_n2().debug("handle_itti_message ... test point 1");
e_Ngap_CauseRadioNetwork cause;
Logger::amf_n2().debug("handle_itti_message ... test point 2");
itti_msg.ueCtxRel->getCauseRadioNetwork(cause);
Logger::amf_n2().debug("handle_itti_message ... test point 3");
UEContextReleaseCommandMsg * ueCtxRelCmd = new UEContextReleaseCommandMsg();
Logger::amf_n2().debug("handle_itti_message ... test point 4");
ueCtxRelCmd->setMessageType();
Logger::amf_n2().debug("handle_itti_message ... test point 5");
ueCtxRelCmd->setUeNgapIdPair(amf_ue_ngap_id, ran_ue_ngap_id);
Logger::amf_n2().debug("handle_itti_message ... test point 6");
ueCtxRelCmd->setCauseRadioNetwork(cause);
Logger::amf_n2().debug("handle_itti_message ... test point 7");
uint8_t buffer[200];
int encoded_size = ueCtxRelCmd->encode2buffer(buffer, 200);
Logger::amf_n2().debug("handle_itti_message ... test point 8");
bstring b = blk2bstr(buffer, encoded_size);
Logger::amf_n2().debug("handle_itti_message ... test point 9");
sctp_s_38412.sctp_send_msg(itti_msg.assoc_id, itti_msg.stream, &b);
Logger::amf_n2().debug("handle_itti_message ... test point 10");
}
void amf_n2::handle_itti_message(itti_ue_radio_capability_indication &itti_msg){
......
......@@ -6,11 +6,27 @@ using namespace std;
void statistics::display(){
cout<<endl;
Logger::amf_app().info("--------------------------------------------------");
Logger::amf_app().info("| connected gNBs | connected UEs | registred UEs |");
Logger::amf_app().info("--------------------------------------------------");
Logger::amf_app().info("| %d | %d | %d |",gNB_connected,UE_connected,UE_registred);
Logger::amf_app().info("--------------------------------------------------");
//Logger::amf_app().info("--------------------------------------------------");
//Logger::amf_app().info("| connected gNBs | connected UEs | registred UEs |");
//Logger::amf_app().info("--------------------------------------------------");
//Logger::amf_app().info("| %d | %d | %d |",gNB_connected,UE_connected,UE_registred);
//Logger::amf_app().info("--------------------------------------------------");
Logger::amf_app().info("|--------------------------------------------------------------------------------------------------------------------|");
Logger::amf_app().info("-----------------------------------------------------------------------------------------------------------------");
Logger::amf_app().info("|----------------------------------------------------gNBs' information--------------------------------------------|");
for(int i=0; i<gnbs.size(); i++){
Logger::amf_app().info("[index %d][connected][GlobalID: 0x%x][gnb name: %s][Tracking Area: plmn(%s), tac(%d)]", i+1, gnbs[i].gnb_id, gnbs[i].gnb_name.c_str(), (gnbs[i].mcc+gnbs[i].mnc).c_str(), gnbs[i].tac);
}
Logger::amf_app().info("-----------------------------------------------------------------------------------------------------------------"); cout<<endl;
Logger::amf_app().info("-----------------------------------------------------------------------------------------------------------------");
Logger::amf_app().info("|----------------------------------------------------UEs' information--------------------------------------------|");
for(int i=0; i<ues.size();i++){
Logger::amf_app().info("[index %d][%s][%s][imsi %s][guti %s]", i+1, ues[i].connStatus.c_str(), ues[i].registerStatus.c_str(), ues[i].imsi.c_str(), ues[i].guti.c_str());
Logger::amf_app().info("Current ran_ue_ngap_id[%d]; Current amf_ue_ngap_id[%d]", ues[i].ranid, ues[i].amfid);
Logger::amf_app().info("Location[NrCgi][PLMN(%s), cellID(%d)]", (ues[i].mcc+ues[i].mnc).c_str(), ues[i].cellId); cout<<endl;
}
Logger::amf_app().info("-----------------------------------------------------------------------------------------------------------------");
Logger::amf_app().info("|--------------------------------------------------------------------------------------------------------------------|"); cout<<endl;
}
statistics::statistics(){
......
......@@ -4,6 +4,31 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <vector>
#include <string>
using namespace std;
typedef struct{
uint32_t gnb_id;
string mcc;
string mnc;
string gnb_name;
uint32_t tac;
//long nrCellId;
}gnb_infos;
typedef struct{
string connStatus;
string registerStatus;
uint32_t ranid;
long amfid;
string imsi;
string guti;
string mcc;
string mnc;
uint32_t cellId;
}ue_infos;
class statistics{
public:
......@@ -15,7 +40,8 @@ public:
uint32_t UE_connected;
uint32_t UE_registred;
//uint32_t system_pdu_sessions;
vector<gnb_infos> gnbs;
vector<ue_infos> ues;
};
......
#include "nas_context.hpp"
nas_context::nas_context(){
security_ctx = NULL;
is_imsi_present = false;
is_stacs_available = false;
is_auth_vectors_present = false;
is_specific_procedure_for_registration_running = false;
is_specific_procedure_for_deregistration_running = false;
......
......@@ -15,8 +15,10 @@ public:
~nas_context();
public:
bool ctx_avaliability_ind;
bool is_stacs_available;
long amf_ue_ngap_id;
uint32_t ran_ue_ngap_id;
string nas_status;
/************ parameters from Registration request *************/
uint8_t registration_type:3;
......
......@@ -73,6 +73,7 @@ typedef enum {
NAS_SIG_ESTAB_REQ,//task amf_app
N1N2_MESSAGE_TRANSFER_REQ,
SMF_SERVICES_CONSUMER,
NSMF_PDU_SESS_UPDATE_SMCTX,
PDU_SESS_RES_SET_RESP,
TIME_OUT,
HEALTH_PING,
......
......@@ -3,6 +3,7 @@
#include "bstrlib.h"
#include "itti_msg.hpp"
#include <string>
class itti_msg_n11 : public itti_msg{
public:
......@@ -42,6 +43,14 @@ public:
bstring n2sm;
};
class itti_nsmf_pdusession_update_sm_context : public itti_msg_n11{
public:
itti_nsmf_pdusession_update_sm_context(const task_id_t origin, const task_id_t destination) : itti_msg_n11(NSMF_PDU_SESS_UPDATE_SMCTX, origin, destination){}
itti_nsmf_pdusession_update_sm_context(const itti_nsmf_pdusession_update_sm_context &i) : itti_msg_n11(i){}
public:
uint8_t pdu_session_id;
bstring n2sm;
};
......
......@@ -36,7 +36,7 @@
#define SERVICE_REQUEST 0b01001100
#define SERVICE_REJECT 0b01001101
#define SERVICE_ACCEPT 0b01001110
#define UE_INIT_DEREGISTER 0b01000101
/********* registration type ***************/
......
......@@ -392,36 +392,36 @@ int _5GSMobilityIdentity::suci_decodefrombuffer(uint8_t *buf, int len, int ie_le
octet = *(buf+decoded_size);
decoded_size++;
mcc += (octet & 0x0f);
Logger::nas_mm().debug("mcc(%s)",std::to_string(mcc).c_str());
Logger::nas_mm().debug("buffer(0x%x)",octet);
//Logger::nas_mm().debug("mcc(%s)",std::to_string(mcc).c_str());
//Logger::nas_mm().debug("buffer(0x%x)",octet);
if((octet&0xf0) == 0xf0){
octet = *(buf+decoded_size);
decoded_size++;
mnc += ((octet & 0x0f)*10 + ((octet&0xf0)>>4));
Logger::nas_mm().debug("mnc(2 digits)(%s)",std::to_string(mnc).c_str());
//Logger::nas_mm().debug("mnc(2 digits)(%s)",std::to_string(mnc).c_str());
}else{
mnc += ((octet&0xf0)>>4);
octet = *(buf+decoded_size);
Logger::nas_mm().debug("buffer(0x%x)",octet);
//Logger::nas_mm().debug("buffer(0x%x)",octet);
decoded_size++;
mnc += ((octet & 0x0f)*100 + ((octet&0xf0)>>4)*10);
Logger::nas_mm().debug("mnc(3 digits)(%s)",std::to_string(mnc).c_str());
//Logger::nas_mm().debug("mnc(3 digits)(%s)",std::to_string(mnc).c_str());
}
Logger::nas_mm().debug("mcc(%s) mnc(%s)",std::to_string(mcc).c_str(),std::to_string(mnc).c_str());
supi_format_imsi->mcc = (const string)(std::to_string(mcc));
supi_format_imsi->mnc = (const string)(std::to_string(mnc));
int routid = 0; uint8_t digit[4];
octet = *(buf+decoded_size); decoded_size++;
Logger::nas_mm().debug("octet(0x%x)",octet);
//Logger::nas_mm().debug("octet(0x%x)",octet);
digit[0] = octet & 0x0f;
digit[1] = (octet & 0xf0)>>4;
octet = *(buf+decoded_size); decoded_size++;
Logger::nas_mm().debug("octet(0x%x)",octet);
//Logger::nas_mm().debug("octet(0x%x)",octet);
digit[2] = octet & 0x0f;
digit[3] = (octet & 0xf0)>>4;
if(!digit[0] && digit[1]==0x0f && digit[2]==0x0f && digit[3]==0x0f) {
supi_format_imsi->routingIndicator = (const string)("none");
Logger::nas_mm().debug("routing indicator(%s)",supi_format_imsi->routingIndicator.c_str());
//Logger::nas_mm().debug("routing indicator(%s)",supi_format_imsi->routingIndicator.c_str());
}
else{
string result = "";
......@@ -437,15 +437,15 @@ int _5GSMobilityIdentity::suci_decodefrombuffer(uint8_t *buf, int len, int ie_le
supi_format_imsi->protectionSchemeId = 0x0f & octet;
octet = *(buf+decoded_size); decoded_size++;
supi_format_imsi->homeNetworkPKI = octet;
Logger::nas_mm().debug("decoded homeNetworkPKI(%x)",supi_format_imsi->homeNetworkPKI);
//Logger::nas_mm().debug("decoded homeNetworkPKI(%x)",supi_format_imsi->homeNetworkPKI);
string msin = "";
int digit_low = 0, digit_high = 0, numMsin = ie_len-decoded_size;
Logger::nas_mm().debug("number of msin(%d)",numMsin);
//Logger::nas_mm().debug("number of msin(%d)",numMsin);
for(int i=0; i< numMsin; i++){
octet = *(buf+decoded_size); decoded_size++;
digit_high = (octet & 0xf0) >> 4;
digit_low = octet & 0x0f;
Logger::amf_n1().debug("msin(%d), %d %d", i, digit_high, digit_low);
//Logger::amf_n1().debug("msin(%d), %d %d", i, digit_high, digit_low);
msin += ((const string)(std::to_string(digit_low)) + (const string)(std::to_string(digit_high)));
}
supi_format_imsi->msin = msin;
......
......@@ -18,7 +18,9 @@ DNN::~DNN() {}
_value = value;
}*/
void DNN::getValue(bstring &dnn) {
dnn = bstrcpy(_DNN);
//dnn = _DNN;
//dnn = bstrcpy(_DNN);
dnn = blk2bstr((uint8_t*)bdata(_DNN)+1, blength(_DNN)-1);
}
int DNN::encode2buffer(uint8_t *buf, int len) {
Logger::nas_mm().debug("encoding DNN iei(0x%x)", _iei);
......@@ -52,8 +54,9 @@ int DNN::decodefrombuffer(uint8_t *buf, int len, bool is_option) {
length = *(buf + decoded_size); decoded_size++;
decode_bstring(&_DNN, length, (buf + decoded_size), len - decoded_size);
decoded_size += length;
for (int i = 0; i < length; i++) {
Logger::nas_mm().debug("decoded DNN value(0x%x)", (uint8_t*)_DNN->data[i]);
for (int i = 0; i < blength(_DNN); i++) {
Logger::nas_mm().debug("decoded DNN value(0x%x)", (uint8_t*)bdata(_DNN)[i]);
//print_buffer("amf_n1", "decoded dnn bitstring", (uint8_t*)bdata(_DNN), blength(_DNN));
}
Logger::nas_mm().debug("decoded DNN len(%d)", decoded_size);
return decoded_size;
......
......@@ -5,7 +5,6 @@
using namespace nas;
RegistrationRequest::RegistrationRequest(){
Logger::nas_mm().debug("initiating class RegistrationRequest");
plain_header = NULL;
ie_5gsregistrationtype = NULL;
ie_ngKSI = NULL;
......@@ -82,6 +81,17 @@ bool RegistrationRequest::getSuciSupiFormatImsi(nas::SUCI_imsi_t &imsi) {
}
else { return false; }
}
std::string RegistrationRequest::get_5g_guti(){
if(ie_5gs_mobility_id){
nas::_5G_GUTI_t guti;
ie_5gs_mobility_id->get5GGUTI(guti);
return "1234567890";
}else{
return "error";
}
}
//Additional_GUTI
void RegistrationRequest::setAdditional_GUTI_SUCI_SUPI_format_IMSI(const string mcc, const string mnc, uint8_t amf_region_id, uint8_t amf_set_id, uint8_t amf_pointer, const string _5g_tmsi) {
/*if (amf_pointer&0x80) {
......@@ -123,9 +133,10 @@ void RegistrationRequest::set5G_MM_capability(uint8_t value){
ie_5g_mm_capability = new _5GMMCapability(0x10,value);
}
uint8_t RegistrationRequest::get5GMMCapability(){
if (ie_5g_mm_capability != nullptr)
if(ie_5g_mm_capability)
return ie_5g_mm_capability->getValue();
else return -1;
else
return -1;
}
void RegistrationRequest::setUE_Security_Capability(uint8_t g_EASel, uint8_t g_IASel) {
ie_ue_security_capability = new UESecurityCapability(0x2E, g_EASel, g_IASel);
......
......@@ -55,6 +55,7 @@ void setLast_Visited_Registered_TAI(uint8_t MNC_MCC1, uint8_t MNC_MCC2, uint8_t
bool get5GSRegistrationType(bool &is_for, uint8_t &reg_type/*3bits*/);//返回获取IE的状态,成功或者失败
uint8_t getngKSI();//return -1;表示获取IE失败
uint8_t getMobilityIdentityType();//return -1;表示获取IE失败
std::string get_5g_guti();//"error" for missing IE GUTI
bool getSuciSupiFormatImsi(nas::SUCI_imsi_t &imsi);
uint8_t getNonCurrentNativeNasKSI();//return -1;表示获取IE失败
uint8_t get5GMMCapability();//return -1;表示获取IE失败; set接口可能有bug
......
......@@ -9,6 +9,14 @@ ULNASTransport::ULNASTransport() {
plain_header = NULL;
ie_payload_container_type = NULL;
ie_payload_container = NULL;
ie_pdu_session_identity_2 = NULL;
ie_old_pdu_session_identity_2 = NULL;
ie_request_type = NULL;
ie_s_nssai = NULL;
ie_dnn = NULL;
ie_additional_information = NULL;
ie_ma_pdu_session_information = NULL;
ie_release_assistance_indication = NULL;
}
ULNASTransport::~ULNASTransport() {}
......@@ -85,9 +93,9 @@ void ULNASTransport::setDNN(bstring dnn) {
bool ULNASTransport::getDnn(bstring &dnn) {
if (ie_dnn) {
ie_dnn->getValue(dnn);
return 0;
return true;
}
else { return -1; }
else { return false; }
}
void ULNASTransport::setAdditional_Information(uint8_t _length, uint8_t value) {
ie_additional_information = new Additional_Information(0x24,_length, value);
......
......@@ -253,6 +253,8 @@ NativeEnumerated_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
}
ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);
//printf("test0515 Decoding %s as NativeEnumerated\n", td->name);
if(ct->flags & APC_EXTENSIBLE) {
int inext = per_get_few_bits(pd, 1);
......@@ -291,6 +293,7 @@ NativeEnumerated_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
*native = specs->value2enum[value].nat_value;
ASN_DEBUG("Decoded %s = %ld", td->name, *native);
//printf("test0515 Decoded %s = %ld\n", td->name, *native);
return rval;
}
......
......@@ -332,6 +332,7 @@ NativeInteger_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
(void)opt_codec_ctx;
ASN_DEBUG("Decoding NativeInteger %s (APER)", td->name);
//printf("test0515 Decoding NativeInteger %s (APER)\n", td->name);
if(!native) {
native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
......@@ -346,9 +347,11 @@ NativeInteger_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
? asn_INTEGER2ulong(&tmpint, (unsigned long *)native)
: asn_INTEGER2long(&tmpint, native))
rval.code = RC_FAIL;
else
else{
ASN_DEBUG("NativeInteger %s got value %ld",
td->name, *native);
//printf("test0515 NativeInteger %s got value %ld\n", td->name, *native);
}
}
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
......
......@@ -1050,6 +1050,7 @@ CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
if(value < 0) ASN__DECODE_STARVED;
ASN_DEBUG("CHOICE %s got index %d in range %d",
td->name, value, ct->range_bits);
//printf("test0515 CHOICE %s got index %d in range %d\n", td->name, value, ct->range_bits);
if(value > ct->upper_bound)
ASN__DECODE_FAILED;
} else {
......@@ -1078,6 +1079,7 @@ CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
memb_ptr2 = &memb_ptr;
}
ASN_DEBUG("Discovered CHOICE %s encodes %s", td->name, elm->name);
//printf("test0515 Discovered CHOICE %s encodes %s\n", td->name, elm->name);
if(ct && ct->range_bits >= 0) {
rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type,
......@@ -1087,9 +1089,11 @@ CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
elm->encoding_constraints.per_constraints, memb_ptr2, pd);
}
if(rv.code != RC_OK)
if(rv.code != RC_OK){
ASN_DEBUG("Failed to decode %s in %s (CHOICE) %d",
elm->name, td->name, rv.code);
//printf("test0515 Failed to decode %s in %s (CHOICE) %d\n", elm->name, td->name, rv.code);
}
return rv;
}
......@@ -1106,6 +1110,7 @@ CHOICE_encode_aper(const asn_TYPE_descriptor_t *td,
if(!sptr) ASN__ENCODE_FAILED;
ASN_DEBUG("Encoding %s as CHOICE using ALIGNED PER", td->name);
//printf("test0515 Encoding %s as CHOICE using ALIGNED PER\n", td->name);
if(constraints) ct = &constraints->value;
else if(td->encoding_constraints.per_constraints)
......
......@@ -1507,6 +1507,7 @@ SEQUENCE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
}
ASN_DEBUG("Decoding %s as SEQUENCE (APER)", td->name);
//printf("test0515 Decoding %s as SEQUENCE (APER)\n", td->name);
/* Handle extensions */
if(specs->first_extension < 0) {
......@@ -1579,6 +1580,9 @@ SEQUENCE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)",
td->name, elm->name, present,
(int)opmd.nboff, (int)opmd.nbits);
//printf("test0515 Member %s->%s is optional, p=%d (%d->%d)\n",
// td->name, elm->name, present,
// (int)opmd.nboff, (int)opmd.nbits);
if(present == 0) {
/* This element is not present */
if(elm->default_value_set) {
......@@ -1597,6 +1601,7 @@ SEQUENCE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
/* Fetch the member from the stream */
ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
//printf("test0515 Decoding member \"%s\" in %s\n", elm->name, td->name);
if(elm->flags & ATF_OPEN_TYPE) {
rv = OPEN_TYPE_aper_get(opt_codec_ctx, td, st, elm, pd);
......
......@@ -410,6 +410,7 @@ aper_open_type_get_simple(const asn_codec_ctx_t *ctx,
ASN__STACK_OVERFLOW_CHECK(ctx);
ASN_DEBUG("Getting open type %s...", td->name);
//printf("test0515 Getting open type %s...\n", td->name);
do {
chunk_bytes = aper_get_length(pd, -1, -1, &repeat);
......@@ -436,6 +437,8 @@ aper_open_type_get_simple(const asn_codec_ctx_t *ctx,
ASN_DEBUG("Getting open type %s encoded in %ld bytes", td->name,
(long)bufLen);
//printf("test0515 Getting open type %s encoded in %ld bytes\n", td->name,
//(long)bufLen);
memset(&spd, 0, sizeof(spd));
spd.buffer = buf;
......
......@@ -33,7 +33,7 @@ namespace ngap{
bool AMFPointer::decodefrombitstring(Ngap_AMFPointer_t &amfpointer)
{
if(!amfpointer.buf) return false;
pointer = *amfpointer.buf & 0x3f;
pointer = (amfpointer.buf[0] & 0xfc)>>2;//1111 1100
return true;
}
......
......@@ -35,7 +35,15 @@ namespace ngap{
bool AMFSetID::decodefrombitstring(Ngap_AMFSetID_t &amfsetid)
{
if(!amfsetid.buf) return false;
setid = *(uint16_t *)amfsetid.buf & 0x3ff;
printf("test for amfsetid\n");
for(int i=0; i<amfsetid.size; i++){
printf("%x ", amfsetid.buf[i]);
}
printf("\n");
uint16_t temp = 0;
temp |= amfsetid.buf[0]<<8;
temp |= amfsetid.buf[1];
setid = (temp&0xffc0)>>6;//1111 1111 11 00 0000
return true;
}
......
......@@ -9,12 +9,12 @@ FiveGSTmsi::~FiveGSTmsi(){}
bool FiveGSTmsi::decodefrompdu(Ngap_FiveG_S_TMSI_t pdu){
amfSetid.decodefrombitstring(pdu.aMFSetID);
amfPointer.decodefrombitstring(pdu.aMFPointer);
uint8_t * tmsi = pdu.fiveG_TMSI.buf;
uint32_t tmsi = ntohl(*(uint32_t*)pdu.fiveG_TMSI.buf);
int size = pdu.fiveG_TMSI.size;
std::string setId, pointer;
amfSetid.getAMFSetID(setId);
amfPointer.getAMFPointer(pointer);
_5g_s_tmsi = setId+pointer;
_5g_s_tmsi = setId+pointer+std::to_string(tmsi);
return true;
}
......
......@@ -185,6 +185,9 @@ namespace ngap{
if(initialUEMessagePdu->present == Ngap_NGAP_PDU_PR_initiatingMessage)
{
//cout<<"test0515: procedureCode "<<initialUEMessagePdu->choice.initiatingMessage->procedureCode<<endl;
//cout<<"test0515: criticality "<<initialUEMessagePdu->choice.initiatingMessage->criticality<<endl;
//cout<<"test0515: present "<<initialUEMessagePdu->choice.initiatingMessage->value.present<<endl;
if(initialUEMessagePdu->choice.initiatingMessage && initialUEMessagePdu->choice.initiatingMessage->procedureCode == Ngap_ProcedureCode_id_InitialUEMessage && initialUEMessagePdu->choice.initiatingMessage->criticality == Ngap_Criticality_ignore && initialUEMessagePdu->choice.initiatingMessage->value.present == Ngap_InitiatingMessage__value_PR_InitialUEMessage)
{
initialUEMessageIEs = &initialUEMessagePdu->choice.initiatingMessage->value.choice.InitialUEMessage;
......
......@@ -5,6 +5,7 @@
#include "itti.hpp"
#include "NGSetupRequest.hpp"
#include "PduSessionResourceSetupResponse.hpp"
#include "InitialContextSetupResponse.hpp"
//extern "C"{
// #include "Ngap_NGAP-PDU.h"
//}
......@@ -81,7 +82,34 @@ int ngap_amf_handle_uplink_nas_transport(const sctp_assoc_id_t assoc
}
int ngap_amf_handle_initial_context_setup_response(const sctp_assoc_id_t assoc_id, const sctp_stream_id_t stream, struct Ngap_NGAP_PDU *message_p){
Logger::ngap().debug("sending itti initial context setup response to TASK_AMF_N2");
Logger::ngap().debug("sending itti initial context setup response to TASK_AMF_N11");
InitialContextSetupResponseMsg * initCtxResp = new InitialContextSetupResponseMsg();
if(!initCtxResp->decodefrompdu(message_p)){
Logger::ngap().error("decoding InitialContextSetupResponse message error");
return -1;
}
std::vector<PDUSessionResourceSetupResponseItem_t> list;
if(!initCtxResp->getPduSessionResourceSetupResponseList(list)){
Logger::ngap().error("decoding PduSessionResourceSetupResponseMsg getPduSessionResourceSetupResponseList IE error or this IE is not avaliable");
return 0;
}
uint8_t transferIe[500];
memcpy(transferIe, list[0].pduSessionResourceSetupResponseTransfer.buf, list[0].pduSessionResourceSetupResponseTransfer.size);
bstring n2sm = blk2bstr(transferIe, list[0].pduSessionResourceSetupResponseTransfer.size);
itti_nsmf_pdusession_update_sm_context * itti_msg = new itti_nsmf_pdusession_update_sm_context(TASK_NGAP, TASK_AMF_N11);
itti_msg->pdu_session_id = list[0].pduSessionId;
itti_msg->n2sm = n2sm;
std::shared_ptr<itti_nsmf_pdusession_update_sm_context> i = std::shared_ptr<itti_nsmf_pdusession_update_sm_context>(itti_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::ngap().error( "Could not send ITTI message %s to task TASK_AMF_N11", i->get_msg_name());
}
return 0;
}
int ngap_amf_handle_initial_context_setup_failure(const sctp_assoc_id_t assoc_id, const sctp_stream_id_t stream, struct Ngap_NGAP_PDU *message_p){
Logger::ngap().debug("sending itti initial context setup failure to TASK_AMF_N2");
return 0;
}
......@@ -127,7 +155,7 @@ int ngap_amf_handle_ue_context_release_complete(const sctp_assoc_id_t assoc_id,
}
int ngap_amf_handle_pdu_session_resource_setup_response(const sctp_assoc_id_t assoc_id, const sctp_stream_id_t stream, struct Ngap_NGAP_PDU *message_p){
Logger::ngap().debug("sending itti pdu_session_resource_setup_response to TASK_AMF_N2");
Logger::ngap().debug("sending itti pdu_session_resource_setup_response to TASK_AMF_N11");
#if 1
PduSessionResourceSetupResponseMsg * pduresp = new PduSessionResourceSetupResponseMsg();
if(!pduresp->decodefrompdu(message_p)){
......@@ -143,13 +171,13 @@ int ngap_amf_handle_pdu_session_resource_setup_response(const sctp_assoc_id_t as
memcpy(transferIe, list[0].pduSessionResourceSetupResponseTransfer.buf, list[0].pduSessionResourceSetupResponseTransfer.size);
bstring n2sm = blk2bstr(transferIe, list[0].pduSessionResourceSetupResponseTransfer.size);
itti_pdu_session_resource_setup_response * itti_msg = new itti_pdu_session_resource_setup_response(TASK_NGAP, TASK_AMF_N11);
itti_nsmf_pdusession_update_sm_context * itti_msg = new itti_nsmf_pdusession_update_sm_context(TASK_NGAP, TASK_AMF_N11);
itti_msg->pdu_session_id = list[0].pduSessionId;
itti_msg->n2sm = n2sm;
std::shared_ptr<itti_pdu_session_resource_setup_response> i = std::shared_ptr<itti_pdu_session_resource_setup_response>(itti_msg);
std::shared_ptr<itti_nsmf_pdusession_update_sm_context> i = std::shared_ptr<itti_nsmf_pdusession_update_sm_context>(itti_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::ngap().error( "Could not send ITTI message %s to task TASK_AMF_N2", i->get_msg_name());
Logger::ngap().error( "Could not send ITTI message %s to task TASK_AMF_N11", i->get_msg_name());
}
#endif
return 0;
......@@ -197,7 +225,7 @@ ngap_message_decoded_callback messages_callback[][3] = {
{0,0,0}, /*11 HandoverNotification*/
{0,0,0}, /*12 HandoverPreparation*/
{0,0,0}, /*13 HandoverResourceAllocation*/
{0,ngap_amf_handle_initial_context_setup_response,0/*ngap_amf_handle_initial_context_setup_failure*/}, /*InitialContextSetup*/
{0,ngap_amf_handle_initial_context_setup_response,ngap_amf_handle_initial_context_setup_failure}, /*InitialContextSetup*/
{ngap_amf_handle_initial_ue_message,0,0},//15 {ngap_amf_handle_initial_ue_message,0,0}, /*InitialUEMessage*/
{0,0,0}, /*16 LocationReportingControl*/
{0,0,0}, /*17 LocationReportingFailureIndication*/
......
......@@ -75,6 +75,8 @@ int main(int argc, char **argv){
//hexTest();
//send_pdu_session_establishment_request();
//sleep(5);
//send_pdu_session_update_sm_context_establishment();
//send_pdu_session_update_sm_context_establishment();
//smf_client_test();
//f1_test();
......
......@@ -159,7 +159,7 @@ void send_pdu_session_update_sm_context_establishment()
std::cout << "[AMF N11] send_pdu_session_update_sm_context_establishment"<<std::endl;
nlohmann::json pdu_session_modification_request;
std::string n2_msg = "0003e0ac0a0501000000010000";
std::string n2_msg = "0003e0c0a8029d56ba263c003c";
//format string as hex
unsigned char *n2_msg_hex = format_string_as_hex(n2_msg);
......@@ -206,7 +206,7 @@ void send_pdu_session_update_sm_context_establishment()
std::string supi_str;
//std::string url = std::string("http://172.16.1.101/nsmf-pdusession/v2/sm-contexts");
//std::string url = std::string("http://172.16.1.101/nsmf-pdusession/v2/sm-contexts/imsi-200000000000001/modify");
std::string url = std::string("http://10.103.238.82:8889/nsmf-pdusession/v2/sm-contexts/1/modify");
std::string url = std::string("http://192.168.2.189:8889/nsmf-pdusession/v2/sm-contexts/1/modify");
//Fill the json part
pdu_session_modification_request["n2SmInfoType"] = "PDU_RES_SETUP_RSP";
......
......@@ -278,29 +278,29 @@ void Authentication_5gaka::kdf(uint8_t * key, uint16_t key_len, uint8_t * s, uin
void Authentication_5gaka::derive_kseaf(std::string serving_network, uint8_t kausf[32], uint8_t kseaf[32]){
Logger::amf_n1().debug("derive_kseaf ...");
Logger::amf_n1().debug("inputstring: snn(%s)", serving_network.c_str());
//Logger::amf_n1().debug("inputstring: snn(%s)", serving_network.c_str());
OCTET_STRING_t netName;
OCTET_STRING_fromBuf(&netName, serving_network.c_str(), serving_network.length());
print_buffer("amf_n1", "inputstring: snn(hex)", netName.buf, netName.size);
//print_buffer("amf_n1", "inputstring: snn(hex)", netName.buf, netName.size);
uint8_t S[100];
S[0] = 0x6C;//FC
memcpy(&S[1], netName.buf, netName.size);
//memcpy (&S[1+netName.size], &netName.size, 2);
S[1+netName.size] = (uint8_t)((netName.size & 0xff00) >> 8);
S[2+netName.size] = (uint8_t)(netName.size & 0x00ff);
print_buffer("amf_n1", "inputstring S", S, 3+netName.size);
print_buffer("amf_n1", "key KEY", kausf, 32);
//print_buffer("amf_n1", "inputstring S", S, 3+netName.size);
//print_buffer("amf_n1", "key KEY", kausf, 32);
kdf(kausf, 32, S, 3+netName.size, kseaf, 32);
print_buffer("amf_n1", "KDF out: Kseaf", kseaf, 32);
Logger::amf_n1().debug("derive kseaf finished!");
//print_buffer("amf_n1", "KDF out: Kseaf", kseaf, 32);
//Logger::amf_n1().debug("derive kseaf finished!");
}
void Authentication_5gaka::derive_kausf(uint8_t ck[16], uint8_t ik[16], std::string serving_network, uint8_t sqn[6], uint8_t ak[6], uint8_t kausf[32]){
Logger::amf_n1().debug("derive_kausf ...");
Logger::amf_n1().debug("inputstring: snn(%s)", serving_network.c_str());
//Logger::amf_n1().debug("inputstring: snn(%s)", serving_network.c_str());
OCTET_STRING_t netName;
OCTET_STRING_fromBuf(&netName, serving_network.c_str(), serving_network.length());
print_buffer("amf_n1", "inputstring: snn(hex)", netName.buf, netName.size);
//print_buffer("amf_n1", "inputstring: snn(hex)", netName.buf, netName.size);
uint8_t S[100];
uint8_t key[32];
memcpy (&key[0], ck, 16);
......@@ -315,17 +315,17 @@ void Authentication_5gaka::derive_kausf(uint8_t ck[16], uint8_t ik[16], std::str
}
S[9+netName.size] = 0x00;
S[10+netName.size] = 0x06;
print_buffer("amf_n1", "inputstring S", S, 11+netName.size);
print_buffer("amf_n1", "key KEY", key, 32);
//print_buffer("amf_n1", "inputstring S", S, 11+netName.size);
//print_buffer("amf_n1", "key KEY", key, 32);
kdf(key, 32, S, 11+netName.size, kausf, 32);
print_buffer("amf_n1", "KDF out: Kausf", kausf, 32);
Logger::amf_n1().debug("derive kausf finished!");
//print_buffer("amf_n1", "KDF out: Kausf", kausf, 32);
//Logger::amf_n1().debug("derive kausf finished!");
}
void Authentication_5gaka::derive_kamf(std::string imsi, uint8_t *kseaf, uint8_t *kamf, uint16_t abba){
Logger::amf_n1().debug("derive_kamf ...");
std::string ueSupi = imsi;//OK
Logger::amf_n1().debug("inputstring: supi(%s)", ueSupi.c_str());
//Logger::amf_n1().debug("inputstring: supi(%s)", ueSupi.c_str());
//int supiLen = (imsi.length()*sizeof(unsigned char))/2;
//unsigned char * supi = (unsigned char*)calloc(1, supiLen);
//hexStr2Byte(imsi.c_str(), supi, imsi.length());
......@@ -333,7 +333,7 @@ void Authentication_5gaka::derive_kamf(std::string imsi, uint8_t *kseaf, uint8_t
OCTET_STRING_fromBuf(&supi, ueSupi.c_str(), ueSupi.length());
//uint8_t supi[8] = {0x64, 0xf0, 0x11, 0x10, 0x32, 0x54, 0x76, 0x98};
int supiLen = supi.size;
print_buffer("amf_n1", "inputstring: supi(hex)", supi.buf, supiLen);
//print_buffer("amf_n1", "inputstring: supi(hex)", supi.buf, supiLen);
uint8_t S[100];
S[0] = 0x6D;//FC = 0x6D
memcpy (&S[1], supi.buf, supiLen);
......@@ -344,11 +344,11 @@ void Authentication_5gaka::derive_kamf(std::string imsi, uint8_t *kseaf, uint8_t
S[4+supiLen] = (abba & 0xff00)>>8;
S[5+supiLen] = 0x00;
S[6+supiLen] = 0x02;
print_buffer("amf_n1", "inputstring S", S, 7+supiLen);
print_buffer("amf_n1", "key KEY", kseaf, 32);
//print_buffer("amf_n1", "inputstring S", S, 7+supiLen);
//print_buffer("amf_n1", "key KEY", kseaf, 32);
kdf(kseaf, 32, S, 7+supiLen, kamf, 32);
print_buffer("amf_n1", "KDF out: Kamf", kamf, 32);
Logger::amf_n1().debug("derive kamf finished!");
//print_buffer("amf_n1", "KDF out: Kamf", kamf, 32);
//Logger::amf_n1().debug("derive kamf finished!");
}
void Authentication_5gaka::derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t kamf[32], uint8_t * knas){
......@@ -362,14 +362,14 @@ void Authentication_5gaka::derive_knas(algorithm_type_dist_t nas_alg_type, uint8
S[4] = nas_alg_id;
S[5] = 0x00;
S[6] = 0x01;
print_buffer("amf_n1", "inputstring S", S, 7);
print_buffer("amf_n1", "key KEY", kamf, 32);
//print_buffer("amf_n1", "inputstring S", S, 7);
//print_buffer("amf_n1", "key KEY", kamf, 32);
kdf (kamf, 32, S, 7, out, 32);
//memcpy (knas, &out[31 - 16 + 1], 16);
for(int i=0; i<16; i++)
knas[i] = out[16+i];
print_buffer("amf_n1", "knas", knas, 16);
Logger::amf_n1().debug("derive knas finished!");
//print_buffer("amf_n1", "knas", knas, 16);
//Logger::amf_n1().debug("derive knas finished!");
}
void Authentication_5gaka::derive_kgnb(uint32_t uplinkCount, uint8_t accessType, uint8_t kamf[32], uint8_t * kgnb){
......@@ -382,11 +382,11 @@ void Authentication_5gaka::derive_kgnb(uint32_t uplinkCount, uint8_t accessType,
S[7] = accessType;
S[8] = 0x00;
S[9] = 0x01;
print_buffer("amf_n1", "inputstring S", S, 10);
print_buffer("amf_n1", "key KEY", kamf, 32);
//print_buffer("amf_n1", "inputstring S", S, 10);
//print_buffer("amf_n1", "key KEY", kamf, 32);
kdf(kamf, 32, S, 10, kgnb, 32);
print_buffer("amf_n1", "kgnb", kgnb, 32);
Logger::amf_n1().debug("derive kgnb finished!");
//print_buffer("amf_n1", "kgnb", kgnb, 32);
//Logger::amf_n1().debug("derive kgnb finished!");
}
void Authentication_5gaka::derive_kasme(uint8_t ck[16], uint8_t ik[16], uint8_t plmn[3], uint8_t sqn[6], uint8_t ak[6], uint8_t * kasme){
......
......@@ -73,7 +73,7 @@ void Authentication_5gaka::RijndaelKeySchedule(const uint8_t key[16]){
*/
}
//#if AUTH_ALG_ON
#if 1
#if 0
for(int m=0; m<11; m++){
printf("roundKeys(%d)\n0x", m);
for(int i=0; i<16; i++)
......
......@@ -74,6 +74,8 @@ char* bstring2charString(bstring b){
for(int i=0; i<blength(b); i++)
buf[i] = (char)value[i];
buf[blength(b)] = '\0';
free(value);
value = nullptr;
return buf;
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment