amf_n1.cpp 159 KB
Newer Older
1 2 3 4 5
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
Niuhaiwen's avatar
Niuhaiwen committed
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this
7 8
 * file except in compliance with the License. You may obtain a copy of the
 * License at
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

/*! \file amf_n1.cpp
 \brief
24
 \author Keliang DU (BUPT), Tien-Thinh NGUYEN (EURECOM)
25 26 27 28
 \date 2020
 \email: contact@openairinterface.org
 */

dukl's avatar
dukl committed
29
#include "amf_n1.hpp"
30

31
#include "AuthenticationFailure.hpp"
32 33 34 35 36 37 38
#include "amf_n2.hpp"
#include "amf_n11.hpp"
#include "amf_app.hpp"
#include "itti.hpp"
#include "logger.hpp"
#include "RegistrationRequest.hpp"
#include "RegistrationReject.hpp"
dukl's avatar
dukl committed
39 40
#include "AuthenticationRequest.hpp"
#include "AuthenticationResponse.hpp"
41
#include "DeregistrationAccept.hpp"
42
#include "DeregistrationRequest.hpp"
dukl's avatar
dukl committed
43 44
#include "IdentityRequest.hpp"
#include "IdentityResponse.hpp"
45
#include "RegistrationAccept.hpp"
46
#include "RegistrationReject.hpp"
47 48
#include "RegistrationRequest.hpp"
#include "SecurityModeCommand.hpp"
dukl's avatar
dukl committed
49
#include "ServiceAccept.hpp"
50
#include "ServiceRequest.hpp"
dukl's avatar
dukl committed
51
#include "String2Value.hpp"
52 53 54 55 56 57 58 59 60 61 62
#include "ULNASTransport.hpp"
#include "amf_app.hpp"
#include "amf_config.hpp"
#include "amf_n11.hpp"
#include "amf_n2.hpp"
#include "comUt.hpp"
#include "itti.hpp"
#include "itti_msg_n11.hpp"
#include "itti_msg_n2.hpp"
#include "logger.hpp"
#include "nas_algorithms.hpp"
dukl's avatar
dukl committed
63
#include "sha256.hpp"
64
#include <nlohmann/json.hpp>
65

yangjian's avatar
yangjian committed
66 67 68
#include "AuthenticationInfo.h"
#include "ConfirmationData.h"
#include "ConfirmationDataResponse.h"
Niuhaiwen's avatar
Niuhaiwen committed
69
#include "UEAuthenticationCtx.h"
yangjian's avatar
yangjian committed
70 71
#include <curl/curl.h>

Keliang's avatar
Keliang committed
72
extern "C" {
73
#include "bstrlib.h"
74
#include "dynamic_memory_check.h"
75 76
}

yangjian's avatar
yangjian committed
77 78
using namespace oai::amf::model;

dukl's avatar
dukl committed
79
using namespace nas;
dukl's avatar
dukl committed
80
using namespace amf_application;
dukl's avatar
dukl committed
81
using namespace config;
dukl's avatar
dukl committed
82

Niuhaiwen's avatar
Niuhaiwen committed
83 84 85
extern itti_mw *itti_inst;
extern amf_n1 *amf_n1_inst;
extern amf_n11 *amf_n11_inst;
dukl's avatar
dukl committed
86
extern amf_config amf_cfg;
Niuhaiwen's avatar
Niuhaiwen committed
87 88
extern amf_app *amf_app_inst;
extern amf_n2 *amf_n2_inst;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
89
extern statistics stacs;
Niuhaiwen's avatar
Niuhaiwen committed
90 91
extern void convert_string_2_hex(std::string &input, std::string &output);
extern unsigned char *format_string_as_hex(std::string str);
92
extern void octet_stream_2_hex_stream(uint8_t *buf, int len, std::string &out);
Niuhaiwen's avatar
Niuhaiwen committed
93
extern int ncc;
dukl's avatar
dukl committed
94
Sha256 ctx;
95 96
random_state_t random_state;
static uint8_t no_random_delta = 0;
Niuhaiwen's avatar
Niuhaiwen committed
97 98 99
static std::map<std::string, std::string> rand_record;

void amf_n1_task(void *);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
100

101
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
102
void amf_n1_task(void *) {
dukl's avatar
dukl committed
103 104
  const task_id_t task_id = TASK_AMF_N1;
  itti_inst->notify_task_ready(task_id);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
105
  do {
dukl's avatar
dukl committed
106
    std::shared_ptr<itti_msg> shared_msg = itti_inst->receive_msg(task_id);
Niuhaiwen's avatar
Niuhaiwen committed
107
    auto *msg = shared_msg.get();
108

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
109
    switch (msg->msg_type) {
Niuhaiwen's avatar
Niuhaiwen committed
110 111 112 113 114 115 116 117 118 119 120 121 122 123
    case UL_NAS_DATA_IND: { // receive nas message buffer from amf_n2
      Logger::amf_n1().info("Received UL_NAS_DATA_IND");
      itti_uplink_nas_data_ind *m =
          dynamic_cast<itti_uplink_nas_data_ind *>(msg);
      amf_n1_inst->handle_itti_message(ref(*m));
    } break;
    case DOWNLINK_NAS_TRANSFER: {
      Logger::amf_n1().info("Received DOWNLINK_NAS_TRANSFER");
      itti_downlink_nas_transfer *m =
          dynamic_cast<itti_downlink_nas_transfer *>(msg);
      amf_n1_inst->handle_itti_message(ref(*m));
    } break;
    default:
      Logger::amf_n1().error("No handler for msg type %d", msg->msg_type);
dukl's avatar
dukl committed
124
    }
125
  } while (true);
dukl's avatar
dukl committed
126 127
}

128
//------------------------------------------------------------------------------
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
129 130
amf_n1::amf_n1() {
  if (itti_inst->create_task(TASK_AMF_N1, amf_n1_task, nullptr)) {
131 132
    Logger::amf_n1().error("Cannot create task TASK_AMF_N1");
    throw std::runtime_error("Cannot create task TASK_AMF_N1");
dukl's avatar
dukl committed
133
  }
134 135 136
  Logger::amf_n1().startup("Started");
  Logger::amf_n1().debug("Construct amf_n1 successfully");
}
dukl's avatar
dukl committed
137

138
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
139
amf_n1::~amf_n1() {}
dukl's avatar
dukl committed
140

141
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
142 143
void amf_n1::handle_itti_message(itti_downlink_nas_transfer &itti_msg) {
  long amf_ue_ngap_id = itti_msg.amf_ue_ngap_id;
dukl's avatar
dukl committed
144 145
  uint32_t ran_ue_ngap_id = itti_msg.ran_ue_ngap_id;
  std::shared_ptr<nas_context> nc;
146
  if (is_amf_ue_id_2_nas_context(amf_ue_ngap_id))
dukl's avatar
dukl committed
147
    nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
148
  else {
Niuhaiwen's avatar
Niuhaiwen committed
149 150
    Logger::amf_n1().warn("No existed nas_context with amf_ue_ngap_id(0x%x)",
                          amf_ue_ngap_id);
dukl's avatar
dukl committed
151 152
    return;
  }
Niuhaiwen's avatar
Niuhaiwen committed
153
  nas_secu_ctx *secu = nc.get()->security_ctx;
dukl's avatar
dukl committed
154
  bstring protected_nas;
Niuhaiwen's avatar
Niuhaiwen committed
155 156 157 158
  encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
                               NAS_MESSAGE_DOWNLINK,
                               (uint8_t *)bdata(itti_msg.dl_nas),
                               blength(itti_msg.dl_nas), protected_nas);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
159
  if (itti_msg.is_n2sm_set) {
Niuhaiwen's avatar
Niuhaiwen committed
160
    if (itti_msg.n2sm_info_type.compare("PDU_RES_REL_CMD") ==
Niuhaiwen's avatar
Niuhaiwen committed
161 162 163 164 165 166
        0) { // PDU SESSION RESOURCE RELEASE COMMAND
      itti_pdu_session_resource_release_command *release_command =
          new itti_pdu_session_resource_release_command(TASK_AMF_N1,
                                                        TASK_AMF_N2);
      release_command->nas = protected_nas;
      release_command->n2sm = itti_msg.n2sm;
167 168 169
      release_command->amf_ue_ngap_id = amf_ue_ngap_id;
      release_command->ran_ue_ngap_id = ran_ue_ngap_id;
      release_command->pdu_session_id = itti_msg.pdu_session_id;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
170
      std::shared_ptr<itti_pdu_session_resource_release_command> i =
Niuhaiwen's avatar
Niuhaiwen committed
171 172
          std::shared_ptr<itti_pdu_session_resource_release_command>(
              release_command);
173 174 175 176 177 178
      int ret = itti_inst->send_msg(i);
      if (0 != ret) {
        Logger::amf_n1().error(
            "Could not send ITTI message %s to task TASK_AMF_N2",
            i->get_msg_name());
      }
Niuhaiwen's avatar
Niuhaiwen committed
179 180
    } else { // PDU SESSION RESOURCE SETUP_REQUEST
      itti_pdu_session_resource_setup_request *psrsr =
181
          new itti_pdu_session_resource_setup_request(TASK_AMF_N1, TASK_AMF_N2);
Niuhaiwen's avatar
Niuhaiwen committed
182 183
      psrsr->nas = protected_nas;
      psrsr->n2sm = itti_msg.n2sm;
184 185 186 187
      psrsr->amf_ue_ngap_id = amf_ue_ngap_id;
      psrsr->ran_ue_ngap_id = ran_ue_ngap_id;
      psrsr->pdu_session_id = itti_msg.pdu_session_id;
      std::shared_ptr<itti_pdu_session_resource_setup_request> i =
Niuhaiwen's avatar
Niuhaiwen committed
188
          std::shared_ptr<itti_pdu_session_resource_setup_request>(psrsr);
189 190 191 192 193 194
      int ret = itti_inst->send_msg(i);
      if (0 != ret) {
        Logger::amf_n1().error(
            "Could not send ITTI message %s to task TASK_AMF_N2",
            i->get_msg_name());
      }
dukl's avatar
dukl committed
195
    }
196

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
197
  } else {
Niuhaiwen's avatar
Niuhaiwen committed
198
    itti_dl_nas_transport *dnt =
Niuhaiwen's avatar
Niuhaiwen committed
199
        new itti_dl_nas_transport(TASK_AMF_N1, TASK_AMF_N2);
Niuhaiwen's avatar
Niuhaiwen committed
200
    dnt->nas = protected_nas;
dukl's avatar
dukl committed
201 202
    dnt->amf_ue_ngap_id = amf_ue_ngap_id;
    dnt->ran_ue_ngap_id = ran_ue_ngap_id;
Niuhaiwen's avatar
Niuhaiwen committed
203 204
    std::shared_ptr<itti_dl_nas_transport> i =
        std::shared_ptr<itti_dl_nas_transport>(dnt);
dukl's avatar
dukl committed
205 206
    int ret = itti_inst->send_msg(i);
    if (0 != ret) {
207 208 209
      Logger::amf_n1().error(
          "Could not send ITTI message %s to task TASK_AMF_N2",
          i->get_msg_name());
dukl's avatar
dukl committed
210 211 212 213
    }
  }
}

214
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
215 216
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;
dukl's avatar
dukl committed
217
  uint32_t ran_ue_ngap_id = nas_data_ind.ran_ue_ngap_id;
Niuhaiwen's avatar
Niuhaiwen committed
218
  std::string nas_context_key =
219
      "app_ue_ranid_" + to_string(ran_ue_ngap_id) + "-amfid_" +
Niuhaiwen's avatar
Niuhaiwen committed
220
      to_string(amf_ue_ngap_id); // key for nas_context, option 1
dukl's avatar
dukl committed
221
  std::string snn;
Niuhaiwen's avatar
Niuhaiwen committed
222
  if (nas_data_ind.mnc.length() == 2) // TODO: remove hardcoded value
Niuhaiwen's avatar
Niuhaiwen committed
223 224
    snn = "5G:mnc0" + nas_data_ind.mnc + ".mcc" + nas_data_ind.mcc +
          ".3gppnetwork.org";
dukl's avatar
dukl committed
225
  else
Niuhaiwen's avatar
Niuhaiwen committed
226 227
    snn = "5G:mnc" + nas_data_ind.mnc + ".mcc" + nas_data_ind.mcc +
          ".3gppnetwork.org";
228 229
  Logger::amf_n1().debug("Serving network name %s", snn.c_str());
  plmn_t plmn = {};
Niuhaiwen's avatar
Niuhaiwen committed
230 231
  plmn.mnc = nas_data_ind.mnc;
  plmn.mcc = nas_data_ind.mcc;
dukl's avatar
dukl committed
232

dukl's avatar
dukl committed
233 234
  bstring recved_nas_msg = nas_data_ind.nas_msg;
  bstring decoded_plain_msg;
dukl's avatar
dukl committed
235

dukl's avatar
dukl committed
236
  std::shared_ptr<nas_context> nc;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
237
  if (nas_data_ind.is_guti_valid) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
238
    std::string guti = nas_data_ind.guti;
239 240
    if (is_guti_2_nas_context(guti))
      nc = guti_2_nas_context(guti);
241 242 243 244 245

       //TODO HSX 从udsf找是否存在



Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
246
    else {
Niuhaiwen's avatar
Niuhaiwen committed
247 248
      Logger::amf_n1().error("No existing nas_context with GUTI %s",
                             nas_data_ind.guti.c_str());
Niuhaiwen's avatar
Niuhaiwen committed
249
      // return;
dukl's avatar
dukl committed
250
    }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
251
  } else {
252
    if (is_amf_ue_id_2_nas_context(amf_ue_ngap_id))
dukl's avatar
dukl committed
253
      nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
yangjian's avatar
yangjian committed
254

255 256 257
      //TODO HSX 从udsf找是否存在


dukl's avatar
dukl committed
258
    else
Niuhaiwen's avatar
Niuhaiwen committed
259 260
      Logger::amf_n1().warn("No existing nas_context with amf_ue_ngap_id 0x%x",
                            amf_ue_ngap_id);
dukl's avatar
dukl committed
261
  }
dukl's avatar
dukl committed
262

263
  SecurityHeaderType type = {};
Niuhaiwen's avatar
Niuhaiwen committed
264
  if (!check_security_header_type(type, (uint8_t *)bdata(recved_nas_msg))) {
265
    Logger::amf_n1().error("Not 5GS MOBILITY MANAGEMENT message");
dukl's avatar
dukl committed
266 267
    return;
  }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
268
  uint8_t ulCount = 0;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
269
  switch (type) {
Niuhaiwen's avatar
Niuhaiwen committed
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
  case PlainNasMsg: {
    Logger::amf_n1().debug("Received plain NAS message");
    decoded_plain_msg = recved_nas_msg;
  } break;
  case IntegrityProtected: {
    Logger::amf_n1().debug("Received integrity protected NAS message");
    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;
  case IntegrityProtectedWithNew5GNASSecurityContext: {
    Logger::amf_n1().debug(
        "Received integrity protected with new security context NAS message");
  } // break;
  case IntegrityProtectedAndCipheredWithNew5GNASSecurityContext: {
    Logger::amf_n1().debug(
        "Received integrity protected and ciphered with new security context "
        "NAS message");
    if (nc.get() == nullptr) {
294
      Logger::amf_n1().debug(
Niuhaiwen's avatar
Niuhaiwen committed
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
          "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
      // TODO:
    } else {
      bool isMatched = false;
      uint8_t *buf = (uint8_t *)bdata(recved_nas_msg);
      int buf_len = blength(recved_nas_msg);
      uint32_t mac32_recv = ntohl((((uint32_t *)(buf + 2))[0]));
      Logger::amf_n1().debug("Received mac32 (0x%x) from the message",
                             mac32_recv);
      if (mac32 == mac32_recv) {
        isMatched = true;
        Logger::amf_n1().error("Integrity matched");
        // nc.get()->security_ctx->ul_count.seq_num ++;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
316
      }
Niuhaiwen's avatar
Niuhaiwen committed
317 318 319
      if (!isMatched) {
        Logger::amf_n1().error("Received message not integrity matched");
        return;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
320
      } else {
Niuhaiwen's avatar
Niuhaiwen committed
321 322 323 324 325
        bstring ciphered = blk2bstr(buf + 7, buf_len - 7);
        if (!nas_message_cipher_protected(nc.get()->security_ctx,
                                          NAS_MESSAGE_UPLINK, ciphered,
                                          decoded_plain_msg)) {
          Logger::amf_n1().error("Decrypt NAS message failure");
dukl's avatar
dukl committed
326 327 328
          return;
        }
      }
Niuhaiwen's avatar
Niuhaiwen committed
329 330
    }
  } break;
331
  }
332

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
333
  if (nas_data_ind.is_nas_signalling_estab_req) {
334
    Logger::amf_n1().debug("Received NAS signalling establishment request...");
Niuhaiwen's avatar
Niuhaiwen committed
335 336
    // dump_nas_message((uint8_t*)bdata(decoded_plain_msg),
    // blength(decoded_plain_msg));
Niuhaiwen's avatar
Niuhaiwen committed
337 338 339
    print_buffer("amf_n1", "Decoded plain NAS Message buffer",
                 (uint8_t *)bdata(decoded_plain_msg),
                 blength(decoded_plain_msg));
Niuhaiwen's avatar
Niuhaiwen committed
340 341 342
    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);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
343
  } else {
344
    Logger::amf_n1().debug("Received uplink NAS message...");
Niuhaiwen's avatar
Niuhaiwen committed
345 346 347 348 349
    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, plmn);
dukl's avatar
dukl committed
350 351 352
  }
}

353 354
// handlers for lower layer
//------------------------------------------------------------------------------
355 356 357 358
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) {
Niuhaiwen's avatar
Niuhaiwen committed
359
  // 1. Create nas context, or update nas context
360
  if ((nc.get() == nullptr) && (type == PlainNasMsg)) {
361 362 363
    Logger::amf_n1().debug(
        "No existing nas_context with amf_ue_ngap_id 0x%x --> Create a new one",
        amf_ue_ngap_id);
dukl's avatar
dukl committed
364
    nc = std::shared_ptr<nas_context>(new nas_context);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
365
    if (!nc.get()) {
366 367
      Logger::amf_n1().error(
          "Cannot allocate memory for new nas_context, exit...");
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
368 369
      return;
    }
dukl's avatar
dukl committed
370
    set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
371
    nc.get()->ctx_avaliability_ind = false;
Niuhaiwen's avatar
Niuhaiwen committed
372
    // change UE connection status CM-IDLE -> CM-CONNECTED
Niuhaiwen's avatar
Niuhaiwen committed
373 374 375
    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;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
376
    nc.get()->serving_network = snn;
Niuhaiwen's avatar
Niuhaiwen committed
377
    // stacs.UE_connected += 1;
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
    

    /**********************   hxs add *******************************/
    string auts;
    octet_stream_2_hex_stream((uint8_t*) bdata(nc.get()->auts), blength(nc.get()->auts), auts);
    std::string udsf_url = "http://10.112.202.24:7123/nudsf-dr/v1/amfdata/" + std::string("nas_context/records/") + to_string(nc.get()->amf_ue_ngap_id) ;
    nlohmann::json udsf_nas_context;
    nlohmann::json udsf_response;
    udsf_nas_context["meta"] ["tags"] = {
                                       {"RECORD_ID",nlohmann::json::array({to_string(nc.get()->amf_ue_ngap_id)})},
                                       {"from_nf_ID",nlohmann::json::array({"AMF_1234"})}
                                       } ;    
    udsf_nas_context["blocks"] = nlohmann::json::array({
                                                  {{"Content-ID", "ctx_avaliability_ind"},{"Content-Type", "varchar(32)"},{"content", to_string(nc.get()->ctx_avaliability_ind)}},
                                                  {{"Content-ID", "is_stacs_available"},{"Content-Type", "varchar(32)"},{"content", to_string(nc.get()->is_stacs_available)}},
                                                  {{"Content-ID", "amf_ue_ngap_id"},{"Content-Type", "varchar(32)"},{"content", to_string(nc.get()->amf_ue_ngap_id)}},
                                                  {{"Content-ID", "ran_ue_ngap_id"},{"Content-Type", "varchar(32)"},{"content", to_string(nc.get()->ran_ue_ngap_id)}},
                                                  {{"Content-ID", "nas_status"},{"Content-Type", "varchar(32)"},{"content", nc->nas_status }},
                                                  {{"Content-ID", "_5gmm_state"},{"Content-Type", "varchar(32)"},{"content", to_string( nc->_5gmm_state)}},
                                                  
                                                  {{"Content-ID", "registration_type"},{"Content-Type", "varchar(32)"},{"content", to_string( nc->registration_type)}},
                                                  {{"Content-ID", "follow_on_req_pending_ind"},{"Content-Type", "varchar(32)"},{"content",  to_string( nc->follow_on_req_pending_ind)}},
                                                  {{"Content-ID", "ngKsi"},{"Content-Type", "varchar(32)"},{"content", to_string( nc->ngKsi)}},
                                                  
                                                  {{"Content-ID", "imsi"},{"Content-Type", "varchar(32)"},{"content", nc->imsi}},
                                                  {{"Content-ID", "mmCapability"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->mmCapability)}},
                                                  {{"Content-ID", "ueSecurityCaplen"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->ueSecurityCaplen)}},
                                                  {{"Content-ID", "ueSecurityCapEnc"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->ueSecurityCapEnc)}},
                                                  {{"Content-ID", "ueSecurityCapInt"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->ueSecurityCapInt)}},
                                                  {{"Content-ID", "serving_network"},{"Content-Type", "varchar(32)"},{"content",  nc->serving_network}},
                                                  {{"Content-ID", "auts"},{"Content-Type", "varchar(32)"},{"content",  auts}},
                                                  
                                                  {{"Content-ID", "is_specific_procedure_for_registration_running"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->is_specific_procedure_for_registration_running)}},
                                                  {{"Content-ID", "is_specific_procedure_for_deregistration_running"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->is_specific_procedure_for_deregistration_running)}},
                                                  {{"Content-ID", "is_specific_procedure_for_eCell_inactivity_running"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->is_specific_procedure_for_eCell_inactivity_running)}},
                                                  {{"Content-ID", "is_common_procedure_for_authentication_running"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->is_common_procedure_for_authentication_running)}},
                                                  {{"Content-ID", "is_common_procedure_for_identification_running"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->is_common_procedure_for_identification_running)}},
                                                  {{"Content-ID", "is_common_procedure_for_security_mode_control_running"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->is_common_procedure_for_security_mode_control_running)}},
                                                  {{"Content-ID", "is_common_procedure_for_nas_transport_running"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->is_common_procedure_for_nas_transport_running)}},
                                                  
                                                  {{"Content-ID", "Href"},{"Content-Type", "varchar(32)"},{"content",  nc->Href}},
                                                  {{"Content-ID", "is_current_security_available"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->is_current_security_available)}},
                                                  {{"Content-ID", "registration_attempt_counter"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->registration_attempt_counter)}},
                                                  
                                                  {{"Content-ID", "is_imsi_present"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->is_imsi_present)}},
                                                  {{"Content-ID", "is_5g_guti_present"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->is_5g_guti_present)}},
                                                  {{"Content-ID", "is_auth_vectors_present"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->is_auth_vectors_present)}},
                                                  {{"Content-ID", "to_be_register_by_new_suci"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->to_be_register_by_new_suci)}},
                                              });
   // std::vector<nas::SNSSAI_t> requestedNssai
    nlohmann::json requestedNssai = {};
    nlohmann::json requestedNssai_m = {};
    requestedNssai["Content-ID"]="requestedNssai";
    requestedNssai["Content-Type"]="JSON";
    requestedNssai["content"] = {};
    for(int i=0;i<nc->requestedNssai.size();i++)
      {
       requestedNssai_m["sst"]=to_string(nc->requestedNssai[i].sst);
       requestedNssai_m["sd"]=to_string(nc->requestedNssai[i].sd);
       requestedNssai_m["mHplmnSst"]=to_string(nc->requestedNssai[i].mHplmnSst);
       requestedNssai_m["mHplmnSd"]=to_string(nc->requestedNssai[i].mHplmnSd);
       requestedNssai["content"].push_back(requestedNssai_m);

      }
    udsf_nas_context["blocks"].push_back(requestedNssai);

//auc_vector_t _vector[MAX_5GS_AUTH_VECTORS]
445

446 447 448 449 450 451 452 453 454 455 456 457 458 459
    nlohmann::json _vector = {};
    nlohmann::json _vector_m = {};
    _vector["Content-ID"]="_vector";
    _vector["Content-Type"]="JSON";
   for(int i=0;i < MAX_5GS_AUTH_VECTORS;i++)
    {
      _vector_m["rand_new"]=to_string(nc->_vector[i].rand_new);
      _vector_m["rand"]=to_string(*(nc->_vector[i].rand));
      _vector_m["xres"]=to_string(*nc->_vector[i].xres);
      _vector_m["autn"]=to_string(*nc->_vector[i].autn);
      _vector_m["kasme"]=to_string(*nc->_vector[i].kasme);
      _vector["content"].push_back(_vector_m);

    }
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
    udsf_nas_context["blocks"].push_back(_vector);

//_5g_he_av
    nlohmann::json _5g_he_av = {};
    nlohmann::json _5g_he_av_m = {};
    _5g_he_av["Content-ID"]="_5g_he_av";
    _5g_he_av["Content-Type"]="JSON";
   for(int i=0;i < MAX_5GS_AUTH_VECTORS;i++)
    {
      _5g_he_av_m["avType"]=to_string(nc->_5g_he_av[i].avType);
      _5g_he_av_m["rand"]=to_string(*(nc->_5g_he_av[i].rand));
      _5g_he_av_m["xres"]=to_string(*nc->_5g_he_av[i].xres);
      _5g_he_av_m["autn"]=to_string(*nc->_5g_he_av[i].autn);
      _5g_he_av_m["xresStar"]=to_string(*nc->_5g_he_av[i].xresStar);
      _5g_he_av_m["kausf"]=to_string(*nc->_5g_he_av[i].kausf);
      _5g_he_av["content"].push_back(_5g_he_av_m);
    }
    udsf_nas_context["blocks"].push_back(_5g_he_av);

//_5g_av
    nlohmann::json _5g_av = {};
    nlohmann::json _5g_av_m = {};
    _5g_av["Content-ID"]="_5g_av";
    _5g_av["Content-Type"]="JSON";
   for(int i=0;i < MAX_5GS_AUTH_VECTORS;i++)
    {
      _5g_av_m["avType"]=to_string(nc->_5g_av[i].avType);
      _5g_av_m["rand"]=to_string(*(nc->_5g_av[i].rand));
      _5g_av_m["hxres"]=to_string(*nc->_5g_av[i].hxres);
      _5g_av_m["autn"]=to_string(*nc->_5g_av[i].autn);
      _5g_av_m["hxresStar"]=to_string(*nc->_5g_av[i].hxresStar);
      _5g_av_m["kseaf"]=to_string(*nc->_5g_av[i].kseaf);
      _5g_av["content"].push_back(_5g_av_m);
    }
    udsf_nas_context["blocks"].push_back(_5g_av);

//kamf
    nlohmann::json kamf = {};
    nlohmann::json kamf_m = {};
    kamf["Content-ID"]="kamf";
    kamf["Content-Type"]="JSON";
    for(int i=0;i < MAX_5GS_AUTH_VECTORS;i++){
      for(int j=0;j<32;j++)
      {
        kamf_m=to_string(nc->kamf[i][j]);
      }
    kamf["content"].push_back(kamf_m);
    }
    udsf_nas_context["blocks"].push_back(kamf);

510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596

//security_context_t _security和nas_secu_ctx* security_ctx
  nlohmann::json _security = {};
  nlohmann::json ul_count = {};
  nlohmann::json dl_count = {};
  nlohmann::json capability = {};
  nlohmann::json selected_algorithms = {};
  _security["Content-ID"] = "_security";
  _security["Content-Type"] = "JSON";
  _security["content"]["vector_index"] = to_string(nc->_security.vector_index);
  _security["content"]["knas_enc"] = to_string(*nc->_security.knas_enc);
  _security["content"]["knas_int"] = to_string(*nc->_security.knas_int);
  _security["content"]["activated"] = to_string(nc->_security.activated);
  ul_count["spare"]=to_string(nc->_security.ul_count.spare);
  ul_count["overflow"]=to_string(nc->_security.ul_count.overflow);
  ul_count["seq_num"]=to_string(nc->_security.ul_count.seq_num);
  _security.update(ul_count);
  dl_count["spare"]=to_string(nc->_security.dl_count.spare);
  dl_count["overflow"]=to_string(nc->_security.dl_count.overflow);
  dl_count["seq_num"]=to_string(nc->_security.dl_count.seq_num);
  _security.update(dl_count);
  capability["eps_encryption"]=to_string(nc->_security.capability.eps_encryption);
  capability["eps_integrity"]=to_string(nc->_security.capability.eps_integrity);
  capability["umts_encryption"]=to_string(nc->_security.capability.umts_encryption);
  capability["umts_integrity"]=to_string(nc->_security.capability.umts_integrity);
  capability["gprs_encryption"]=to_string(nc->_security.capability.gprs_encryption);
  capability["umts_present"]=to_string(nc->_security.capability.umts_present);
  capability["gprs_present"]=to_string(nc->_security.capability.gprs_present);
  _security.update(capability);
  selected_algorithms["encryption"]=to_string(nc->_security.selected_algorithms.encryption);
  selected_algorithms["integrity"]=to_string(nc->_security.selected_algorithms.encryption);
  _security.update(selected_algorithms);
  udsf_nas_context["blocks"].push_back(_security);

  nlohmann::json security_ctx = {};
  nlohmann::json ul_count_ctx = {};
  nlohmann::json dl_count_ctx = {};
  nlohmann::json ue_algorithms = {};
  nlohmann::json nas_algs = {};
  security_ctx["Content-ID"] = "security_ctx";
  security_ctx["Content-Type"] = "JSON";
  security_ctx["content"] = {};
  // security_ctx["content"]["vector_pointer"] = to_string(nc->security_ctx->vector_pointer);
  // security_ctx["content"]["sc_type"] = to_string(nc->security_ctx->sc_type);
  // security_ctx["content"]["ngksi"] = to_string(nc->security_ctx->ngksi);
  // security_ctx["content"]["knas_enc"] = to_string(*nc->security_ctx->knas_enc);
  // security_ctx["content"]["knas_int"] = to_string(*nc->security_ctx->knas_int);
  // ul_count_ctx["spare"]=to_string(nc->security_ctx->ul_count.spare);
  // ul_count_ctx["overflow"]=to_string(nc->security_ctx->ul_count.overflow);
  // ul_count_ctx["seq_num"]=to_string(nc->security_ctx->ul_count.seq_num);
  // security_ctx.update(ul_count);
  // dl_count_ctx["spare"]=to_string(nc->security_ctx->dl_count.spare);
  // dl_count_ctx["overflow"]=to_string(nc->security_ctx->dl_count.overflow);
  // dl_count_ctx["seq_num"]=to_string(nc->security_ctx->dl_count.seq_num);
  // security_ctx.update(dl_count);
  // ue_algorithms["_5gs_encryption"]=to_string(nc->security_ctx->ue_algorithms._5gs_encryption);
  // ue_algorithms["overflow"]=to_string(nc->security_ctx->ue_algorithms._5gs_integrity);
  // security_ctx.update(ue_algorithms);
  // nas_algs["encryption"]=to_string(nc->security_ctx->nas_algs.encryption);
  // nas_algs["integrity"]=to_string(nc->security_ctx->nas_algs.integrity);
  // security_ctx.update(nas_algs);
  udsf_nas_context["blocks"].push_back(security_ctx);


  amf_n2_inst->curl_http_client_udsf(udsf_url,udsf_nas_context.dump(),"PUT",udsf_response);

  // udsf_url = "http://10.112.202.24:7123/nudsf-dr/v1/amfdata/" + std::string("nas_context/records/") + std::to_string(nc.get()->amf_ue_ngap_id) ;
  // if(!amf_n2_inst->curl_http_client_udsf(udsf_url,"","GET",udsf_response)){
  // Logger::amf_n2().error("No existing nas context with amf_ue_ngap_id (%d)", nc.get()->amf_ue_ngap_id);
  //   return;
  // }
  // Logger::amf_n2().debug("udsf_response: %s", udsf_response.dump().c_str());


  // nas_context *nc1 = new nas_context();
  // std::shared_ptr<nas_context> nc2;
  // nc1->nas_context_from_json(udsf_response);
  // nc2 = std::shared_ptr<nas_context>(nc1);

//printf("ran_ue_ngap_id-%d\n",nc2.get()->ran_ue_ngap_id);
//printf("amf_ue_ngap_id-%d\n",nc2.get()->amf_ue_ngap_id);
//printf("ctx_avaliability_ind-%d\n",nc2.get()->ctx_avaliability_ind);
//printf("nas_status-%d\n",nc2.get()->nas_status);
//printf("serving_network-%d\n",nc2.get()->serving_network);

    /**********************   hxs add *******************************/

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
597
  } else {
Niuhaiwen's avatar
Niuhaiwen committed
598
    // Logger::amf_n1().debug("existing nas_context with amf_ue_ngap_id(0x%x)
Keliang's avatar
Keliang committed
599 600
    // --> Update",amf_ue_ngap_id); nc =
    // amf_ue_id_2_nas_context(amf_ue_ngap_id);
dukl's avatar
dukl committed
601
  }
602

Niuhaiwen's avatar
Niuhaiwen committed
603
  uint8_t *buf = (uint8_t *)bdata(plain_msg);
604 605
  uint8_t message_type = *(buf + 2);
  Logger::amf_n1().debug("NAS message type 0x%x", message_type);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
606
  switch (message_type) {
Niuhaiwen's avatar
Niuhaiwen committed
607 608 609 610 611 612 613 614
  case REGISTRATION_REQUEST: {
    Logger::amf_n1().debug(
        "Received registration request message, handling...");
    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 message, handling...");
615
    if(nc != nullptr)
616
      nc.get()->security_ctx->ul_count.seq_num = ulCount;
Niuhaiwen's avatar
Niuhaiwen committed
617 618 619 620 621 622 623 624 625 626 627
    service_request_handle(true, nc, ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
  } break;
  case UE_INIT_DEREGISTER: {
    Logger::amf_n1().debug(
        "received initialUeMessage de-registration request messgae , handle "
        "...");
    // ue_initiate_de_registration_handle(ran_ue_ngap_id, amf_ue_ngap_id,
    // plain_msg);
  } break;
  default:
    Logger::amf_n1().error("No handler for NAS message 0x%x", message_type);
dukl's avatar
dukl committed
628 629 630
  }
}

631
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
632 633 634
void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
                                   bstring plain_msg) {
  uint8_t *buf = (uint8_t *)bdata(plain_msg);
635
  uint8_t message_type = *(buf + 2);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
636
  switch (message_type) {
Niuhaiwen's avatar
Niuhaiwen committed
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679
  case AUTHENTICATION_RESPONSE: {
    Logger::amf_n1().debug(
        "Received authentication response message, handling...");
    authentication_response_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
  } break;
  case AUTHENTICATION_FAILURE: {
    Logger::amf_n1().debug(
        "Received authentication failure message, handling...");
    authentication_failure_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
  } break;
  case SECURITY_MODE_COMPLETE: {
    Logger::amf_n1().debug(
        "Received security mode complete message, handling...");
    security_mode_complete_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
  } break;
  case SECURITY_MODE_REJECT: {
    Logger::amf_n1().debug(
        "Received security mode reject message, handling...");
    security_mode_reject_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
  } break;
  case UL_NAS_TRANSPORT: {
    Logger::amf_n1().debug("Received UL NAS transport message, handling...");
    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 message, handling...");
    ue_initiate_de_registration_handle(ran_ue_ngap_id, amf_ue_ngap_id,
                                       plain_msg);
  } break;
  case IDENTITY_RESPONSE: {
    Logger::amf_n1().debug("received identity response messgae , handle ...");
    identity_response_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
  } break;
  case REGISTRATION_COMPLETE: {
    Logger::amf_n1().debug(
        "Received registration complete message, handling...");
    registration_complete_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
    // TODO
  } break;
  default: {
    // TODO:
  }
680 681 682
  }
}

683
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
684 685 686
void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
                                   bstring plain_msg, plmn_t plmn) {
  uint8_t *buf = (uint8_t *)bdata(plain_msg);
687
  uint8_t message_type = *(buf + 2);
688
  switch (message_type) {
Niuhaiwen's avatar
Niuhaiwen committed
689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731
  case AUTHENTICATION_RESPONSE: {
    Logger::amf_n1().debug(
        "Received authentication response message, handling...");
    authentication_response_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
  } break;
  case AUTHENTICATION_FAILURE: {
    Logger::amf_n1().debug(
        "Received authentication failure message, handling...");
    authentication_failure_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
  } break;
  case SECURITY_MODE_COMPLETE: {
    Logger::amf_n1().debug(
        "Received security mode complete message, handling...");
    security_mode_complete_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
  } break;
  case SECURITY_MODE_REJECT: {
    Logger::amf_n1().debug(
        "Received security mode reject message, handling...");
    security_mode_reject_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
  } break;
  case UL_NAS_TRANSPORT: {
    Logger::amf_n1().debug("Received ul NAS transport message, handling...");
    ul_nas_transport_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg, plmn);
  } break;
  case UE_INIT_DEREGISTER: {
    Logger::amf_n1().debug(
        "Received de-registration request message, handling...");
    ue_initiate_de_registration_handle(ran_ue_ngap_id, amf_ue_ngap_id,
                                       plain_msg);
  } break;
  case IDENTITY_RESPONSE: {
    Logger::amf_n1().debug("received identity response messgae , handle ...");
    identity_response_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
  } break;
  case REGISTRATION_COMPLETE: {
    Logger::amf_n1().debug(
        "Received registration complete message, handling...");
    registration_complete_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
    // TODO
  } break;
  default: {
    // TODO:
  }
732 733
  }
}
dukl's avatar
dukl committed
734

735 736
// nas message decode
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
737 738
bool amf_n1::check_security_header_type(SecurityHeaderType &type,
                                        uint8_t *buffer) {
dukl's avatar
dukl committed
739
  uint8_t octet = 0, decoded_size = 0;
740 741
  octet = *(buffer + decoded_size);
  decoded_size++;
Niuhaiwen's avatar
Niuhaiwen committed
742 743
  if (octet != 0x7e)
    return false;
744 745
  octet = *(buffer + decoded_size);
  decoded_size++;
Niuhaiwen's avatar
Niuhaiwen committed
746
  // TODO: remove hardcoded value
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
747
  switch (octet & 0x0f) {
Niuhaiwen's avatar
Niuhaiwen committed
748 749 750 751 752 753 754 755 756 757 758 759 760 761 762
  case 0x0:
    type = PlainNasMsg;
    break;
  case 0x1:
    type = IntegrityProtected;
    break;
  case 0x2:
    type = IntegrityProtectedAndCiphered;
    break;
  case 0x3:
    type = IntegrityProtectedWithNew5GNASSecurityContext;
    break;
  case 0x4:
    type = IntegrityProtectedAndCipheredWithNew5GNASSecurityContext;
    break;
dukl's avatar
dukl committed
763
  }
dukl's avatar
dukl committed
764
  return true;
dukl's avatar
dukl committed
765 766
}

Niuhaiwen's avatar
Niuhaiwen committed
767
// nas message handlers
768

769
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
770 771 772 773 774
void amf_n1::identity_response_handle(uint32_t ran_ue_ngap_id,
                                      long amf_ue_ngap_id, bstring plain_msg) {
  IdentityResponse *ir = new IdentityResponse();
  if (!ir->decodefrombuffer(NULL, (uint8_t *)bdata(plain_msg),
                            blength(plain_msg))) {
dukl's avatar
dukl committed
775 776 777 778
    Logger::amf_n1().error("decoding identity response error");
    return;
  }
  string supi = "";
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
779
  if (ir->ie_mobility_id) {
dukl's avatar
dukl committed
780 781 782 783 784 785
    nas::SUCI_imsi_t imsi;
    ir->ie_mobility_id->getSuciWithSupiImsi(imsi);
    supi = imsi.mcc + imsi.mnc + imsi.msin;
    Logger::amf_n1().debug("identity response : suci (%s)", supi.c_str());
  }
  std::shared_ptr<nas_context> nc;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
786
  if (is_amf_ue_id_2_nas_context(amf_ue_ngap_id)) {
dukl's avatar
dukl committed
787
    nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
Niuhaiwen's avatar
Niuhaiwen committed
788 789
    Logger::amf_n1().debug("find nas_context(%p) by amf_ue_ngap_id(%d)",
                           nc.get(), amf_ue_ngap_id);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
790
  } else {
dukl's avatar
dukl committed
791 792 793 794
    nc = std::shared_ptr<nas_context>(new nas_context);
    set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
    nc.get()->ctx_avaliability_ind = false;
  }
Niuhaiwen's avatar
Niuhaiwen committed
795 796 797 798 799 800
  nc.get()->ctx_avaliability_ind = true;
  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()->is_imsi_present = true;
  nc.get()->imsi = supi;
801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851
/***************************hsx add************************/
  std::string udsf_url = "http://10.112.202.24:7123/nudsf-dr/v1/amfdata/" + std::string("nas_context/records/") + to_string(nc.get()->amf_ue_ngap_id) ;
  nlohmann::json udsf_nas_context;
  nlohmann::json udsf_response;

  udsf_nas_context["meta"] ["tags"] = {
                                       {"RECORD_ID",nlohmann::json::array({amf_ue_ngap_id})},
                                       {"from_nf_ID",nlohmann::json::array({"AMF_1234"})}
                                       } ;

  nlohmann::json ctx_avaliability_ind;
  ctx_avaliability_ind["Content-ID"] = "ctx_avaliability_ind";
  ctx_avaliability_ind["Content-Type"] = "JSON";
  ctx_avaliability_ind["content"] = nc.get()->ctx_avaliability_ind;            
  udsf_nas_context["blocks"].push_back(ctx_avaliability_ind); 

  nlohmann::json nas_status;
  nas_status["Content-ID"] = "nas_status";
  nas_status["Content-Type"] = "JSON";
  nas_status["content"] = nc.get()->nas_status;            
  udsf_nas_context["blocks"].push_back(nas_status); 

  nlohmann::json amf_ue_ngap_id_m;
  amf_ue_ngap_id_m["Content-ID"] = "amf_ue_ngap_id";
  amf_ue_ngap_id_m["Content-Type"] = "JSON";
  amf_ue_ngap_id_m["content"] = nc.get()->amf_ue_ngap_id;            
  udsf_nas_context["blocks"].push_back(amf_ue_ngap_id_m);

  nlohmann::json ran_ue_ngap_id_m;
  ran_ue_ngap_id_m["Content-ID"] = "ran_ue_ngap_id";
  ran_ue_ngap_id_m["Content-Type"] = "JSON";
  ran_ue_ngap_id_m["content"] = nc.get()->ran_ue_ngap_id;            
  udsf_nas_context["blocks"].push_back(ran_ue_ngap_id_m); 

  nlohmann::json is_imsi_present;
  is_imsi_present["Content-ID"] = "is_imsi_present";
  is_imsi_present["Content-Type"] = "JSON";
  is_imsi_present["content"] = nc.get()->is_imsi_present;            
  udsf_nas_context["blocks"].push_back(is_imsi_present); 

  nlohmann::json imsi;
  imsi["Content-ID"] = "imsi";
  imsi["Content-Type"] = "JSON";
  imsi["content"] = nc.get()->imsi;            
  udsf_nas_context["blocks"].push_back(imsi); 

  std::string json_part = udsf_nas_context.dump();
  //nlohmann::json udsf_response;
  amf_n2_inst->curl_http_client_udsf(udsf_url,json_part,"PUT",udsf_response);

/***************************hsx add************************/
852 853
  supi2amfId[("imsi-" + nc.get()->imsi)] = amf_ue_ngap_id;
  supi2ranId[("imsi-" + nc.get()->imsi)] = ran_ue_ngap_id;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
854
  if (nc.get()->to_be_register_by_new_suci) {
dukl's avatar
dukl committed
855
    run_registration_procedure(nc);
dukl's avatar
dukl committed
856 857
  }
}
858

859
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
860 861 862 863
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) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
864
  if (!nc.get()) {
Niuhaiwen's avatar
Niuhaiwen committed
865
    // service reject
dukl's avatar
dukl committed
866 867 868 869 870
    uint8_t nas[4];
    nas[0] = EPD_5GS_MM_MSG;
    nas[1] = PLAIN_5GS_MSG;
    nas[2] = SERVICE_REJECT;
    nas[3] = _5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED;
Niuhaiwen's avatar
Niuhaiwen committed
871
    itti_dl_nas_transport *dnt =
Niuhaiwen's avatar
Niuhaiwen committed
872
        new itti_dl_nas_transport(TASK_AMF_N1, TASK_AMF_N2);
Niuhaiwen's avatar
Niuhaiwen committed
873
    dnt->nas = blk2bstr(nas, 4);
dukl's avatar
dukl committed
874 875
    dnt->amf_ue_ngap_id = amf_ue_ngap_id;
    dnt->ran_ue_ngap_id = ran_ue_ngap_id;
Niuhaiwen's avatar
Niuhaiwen committed
876 877
    std::shared_ptr<itti_dl_nas_transport> i =
        std::shared_ptr<itti_dl_nas_transport>(dnt);
dukl's avatar
dukl committed
878 879
    int ret = itti_inst->send_msg(i);
    if (0 != ret) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
880 881 882
      Logger::amf_n1().error(
          "Could not send ITTI message %s to task TASK_AMF_N2",
          i->get_msg_name());
dukl's avatar
dukl committed
883
    }
884
    return;
dukl's avatar
dukl committed
885
  }
yangjian's avatar
yangjian committed
886

887
  set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
Niuhaiwen's avatar
Niuhaiwen committed
888 889 890
  nas_secu_ctx *secu = nc.get()->security_ctx;
  ServiceRequest *serReq = new ServiceRequest();
  serReq->decodefrombuffer(nullptr, (uint8_t *)bdata(nas), blength(nas));
dukl's avatar
dukl committed
891
  bdestroy(nas);
892 893
  uint16_t pdu_session_status = 0xffff;
  bstring nas_container;
Keliang's avatar
Keliang committed
894 895 896 897 898 899 900
  Logger::amf_n1().debug(
      "try to decode pdu-session-status in service_request(service_request)");
  if (serReq->getNasMessageContainer(nas_container)) {
    Logger::amf_n1().debug(
        "try to get pdu-session-status value from nas message "
        "container(length: %d)",
        blength(nas_container));
Niuhaiwen's avatar
Niuhaiwen committed
901 902 903 904
    uint8_t *buf = (uint8_t *)bdata(nas_container);
    ServiceRequest *tmp = new ServiceRequest();
    tmp->decodefrombuffer(nullptr, (uint8_t *)bdata(nas_container),
                          blength(nas_container));
dukl's avatar
dukl committed
905
    pdu_session_status = tmp->getPduSessionStatus();
Niuhaiwen's avatar
Niuhaiwen committed
906 907
    Logger::amf_n1().debug("Get pdu-session-status value: 0x%02x",
                           pdu_session_status);
908
  }
Niuhaiwen's avatar
Niuhaiwen committed
909
  ServiceAccept *serApt = new ServiceAccept();
dukl's avatar
dukl committed
910
  serApt->setHeader(PLAIN_5GS_MSG);
Niuhaiwen's avatar
Niuhaiwen committed
911
  string supi = "imsi-" + nc.get()->imsi;
dukl's avatar
dukl committed
912 913
  supi2amfId[supi] = amf_ue_ngap_id;
  supi2ranId[supi] = ran_ue_ngap_id;
Niuhaiwen's avatar
Niuhaiwen committed
914 915
  Logger::amf_n1().debug("amf_ue_ngap_id %d, ran_ue_ngap_id %d", amf_ue_ngap_id,
                         ran_ue_ngap_id);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
916
  Logger::amf_n1().debug("Key for pdu session context: SUPI %s", supi.c_str());
dukl's avatar
dukl committed
917
  std::shared_ptr<pdu_session_context> psc;
918

919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949
  //***************************stateless
  pdu_session_context *psc1 = new pdu_session_context();
  nlohmann::json udsf_response;
  std::string udsf_url = "http://10.112.202.24:7123/nudsf-dr/v1/amfdata/" + std::string("pdu_session_context/records/") + supi ;
  bool is_supi_to_pdu_ctx_udsf = amf_n2_inst->curl_http_client_udsf(udsf_url,"","GET",udsf_response);
  if(!is_supi_to_pdu_ctx_udsf){
    Logger::amf_n2().error("No existing pdu_session_context with assoc_id ");
  }
  Logger::amf_n2().debug("udsf_response: %s", udsf_response.dump().c_str());
  psc1->pdu_session_context_from_json(udsf_response);
  psc = std::shared_ptr<pdu_session_context>(psc1);
  psc.get()->ran_ue_ngap_id = ran_ue_ngap_id;
  psc.get()->amf_ue_ngap_id = amf_ue_ngap_id;
  //***************************stateless

  // 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("Cannot get pdu_session_context");
  //     delete serReq;
  //     delete serApt;
  //     return;
  //   }
  //   psc.get()->ran_ue_ngap_id = ran_ue_ngap_id;
  //   psc.get()->amf_ue_ngap_id = amf_ue_ngap_id;
  // } else {
  //   Logger::amf_n1().error("Cannot get pdu_session_context with SUPI %s",
  //                          supi.c_str());
  // }
  if (!is_supi_to_pdu_ctx_udsf || !psc.get()->isn2sm_avaliable) {
  //if (!amf_n11_inst->is_supi_to_pdu_ctx(supi) || !psc.get()->isn2sm_avaliable) {
Niuhaiwen's avatar
Niuhaiwen committed
950 951
    Logger::amf_n1().error("Cannot get pdu session information with supi(%s)",
                           supi.c_str());
952 953
    //if (amf_n11_inst->is_supi_to_pdu_ctx(supi)) {
    if (is_supi_to_pdu_ctx_udsf) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
954 955 956 957 958 959
      psc.get()->isn2sm_avaliable = true;
    }
    serApt->setPDU_session_status(0x0000);
    uint8_t buffer[BUFFER_SIZE_256];
    int encoded_size = serApt->encode2buffer(buffer, BUFFER_SIZE_256);
    bstring protectedNas;
Niuhaiwen's avatar
Niuhaiwen committed
960 961 962 963
    encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
                                 NAS_MESSAGE_DOWNLINK, buffer, encoded_size,
                                 protectedNas);
    uint8_t *kamf = nc.get()->kamf[secu->vector_pointer];
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
964 965 966 967 968 969 970
    uint8_t kgnb[32];
    uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
    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);

971 972 973 974 975 976 977 978 979 980 981 982 983 984 985

    std::string udsf_put_url = "http://10.112.202.24:7123/nudsf-dr/v1/amfdata/" + std::string("pdu_session_context/records/") + supi ;
      nlohmann::json udsf_put_pdu_session_context;
    // nlohmann::json udsf_response;
      udsf_put_pdu_session_context["meta"] ["tags"] = {
                                          {"RECORD_ID",nlohmann::json::array({supi})},
                                          {"from_nf_ID",nlohmann::json::array({"AMF_1234"})}
                                          } ;
      udsf_put_pdu_session_context["blocks"] = nlohmann::json::array({
        {{"Content-ID", "isn2sm_avaliable"},{"Content-Type", "varchar(32)"},{"content",to_string(psc.get()->isn2sm_avaliable)}},
        });
      std::string json_part = udsf_put_pdu_session_context.dump();
      amf_n2_inst->curl_http_client_udsf(udsf_put_url,json_part,"PUT",udsf_response);


Niuhaiwen's avatar
Niuhaiwen committed
986
    itti_initial_context_setup_request *itti_msg =
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
987 988 989
        new itti_initial_context_setup_request(TASK_AMF_N1, TASK_AMF_N2);
    itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
    itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
Niuhaiwen's avatar
Niuhaiwen committed
990 991 992 993
    itti_msg->nas = protectedNas;
    itti_msg->kgnb = kgnb_bs;
    itti_msg->is_sr = true; // service request indicator
    itti_msg->is_pdu_exist = false;
Niuhaiwen's avatar
Niuhaiwen committed
994 995
    std::shared_ptr<itti_initial_context_setup_request> i =
        std::shared_ptr<itti_initial_context_setup_request>(itti_msg);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
996 997 998 999 1000 1001 1002 1003
    int ret = itti_inst->send_msg(i);
    if (0 != ret) {
      Logger::amf_n1().error(
          "Could not send ITTI message %s to task TASK_AMF_N2",
          i->get_msg_name());
    }
    delete serApt;
    delete serReq;
dukl's avatar
dukl committed
1004 1005
    return;
  }
luhan Wang's avatar
luhan Wang committed
1006
  if (pdu_session_status == 0x0000) {
1007
    serApt->setPDU_session_status(0x0000);
Niuhaiwen's avatar
Niuhaiwen committed
1008
  } else {
luhan Wang's avatar
luhan Wang committed
1009
    serApt->setPDU_session_status(pdu_session_status);
Niuhaiwen's avatar
Niuhaiwen committed
1010 1011 1012
    Logger::amf_n1().debug("setting pdu session status 0x%02x",
                           htonl(pdu_session_status));
    // serApt->setPDU_session_status(0x2000);
1013
  }
dukl's avatar
dukl committed
1014
  serApt->setPDU_session_reactivation_result(0x0000);
1015 1016
  uint8_t buffer[BUFFER_SIZE_256];
  int encoded_size = serApt->encode2buffer(buffer, BUFFER_SIZE_256);
dukl's avatar
dukl committed
1017
  bstring protectedNas;
Niuhaiwen's avatar
Niuhaiwen committed
1018 1019 1020 1021
  encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
                               NAS_MESSAGE_DOWNLINK, buffer, encoded_size,
                               protectedNas);
  uint8_t *kamf = nc.get()->kamf[secu->vector_pointer];
dukl's avatar
dukl committed
1022 1023
  uint8_t kgnb[32];
  uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
dukl's avatar
dukl committed
1024
  Logger::amf_n1().debug("uplink count(%d)", secu->ul_count.seq_num);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1025
  print_buffer("amf_n1", "kamf", kamf, 32);
dukl's avatar
dukl committed
1026 1027
  Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
  bstring kgnb_bs = blk2bstr(kgnb, 32);
Niuhaiwen's avatar
Niuhaiwen committed
1028
  itti_initial_context_setup_request *itti_msg =
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1029
      new itti_initial_context_setup_request(TASK_AMF_N1, TASK_AMF_N2);
dukl's avatar
dukl committed
1030 1031
  itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
  itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
Niuhaiwen's avatar
Niuhaiwen committed
1032 1033 1034
  itti_msg->nas = protectedNas;
  itti_msg->kgnb = kgnb_bs;
  itti_msg->is_sr = true; // service request indicator
dukl's avatar
dukl committed
1035
  itti_msg->pdu_session_id = psc.get()->pdu_session_id;
Niuhaiwen's avatar
Niuhaiwen committed
1036
  itti_msg->is_pdu_exist = true;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1037
  if (psc.get()->isn2sm_avaliable) {
Niuhaiwen's avatar
Niuhaiwen committed
1038
    itti_msg->n2sm = psc.get()->n2sm;
dukl's avatar
dukl committed
1039
    itti_msg->isn2sm_avaliable = true;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1040
  } else {
dukl's avatar
dukl committed
1041
    itti_msg->isn2sm_avaliable = false;
1042
    Logger::amf_n1().error("Cannot get pdu session information");
dukl's avatar
dukl committed
1043
  }
Niuhaiwen's avatar
Niuhaiwen committed
1044 1045
  std::shared_ptr<itti_initial_context_setup_request> i =
      std::shared_ptr<itti_initial_context_setup_request>(itti_msg);
dukl's avatar
dukl committed
1046 1047
  int ret = itti_inst->send_msg(i);
  if (0 != ret) {
Niuhaiwen's avatar
Niuhaiwen committed
1048 1049
    Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2",
                           i->get_msg_name());
dukl's avatar
dukl committed
1050
  }
dukl's avatar
dukl committed
1051 1052
  delete serApt;
  delete serReq;
dukl's avatar
dukl committed
1053 1054
}

1055
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
1056 1057 1058 1059 1060
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) {
Niuhaiwen's avatar
Niuhaiwen committed
1061
  // Decode registration request message
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083
  nlohmann::json imsi_json;
  nlohmann::json is_stacs_available;
  nlohmann::json is_5g_guti_present;
  nlohmann::json is_auth_vectors_present;
  nlohmann::json is_current_security_available;
  nlohmann::json security_ctx;
  nlohmann::json ctx_avaliability_ind;
  nlohmann::json nas_status_json;
  nlohmann::json amf_ue_ngap_id_json;
  nlohmann::json ran_ue_ngap_id_json;
  nlohmann::json serving_network;
  nlohmann::json to_be_register_by_new_suci;
  nlohmann::json ngKsi;
  nlohmann::json registration_type;
  nlohmann::json follow_on_req_pending_ind;
  nlohmann::json mmCapability;
  nlohmann::json ueSecurityCapEnc;
  nlohmann::json ueSecurityCapInt;
  nlohmann::json ueSecurityCaplen;
  nlohmann::json requestedNssai_json;
  nlohmann::json udsf_nas_context;
  nlohmann::json is_imsi_present;
1084
  nlohmann::json _5gmm_state;
1085

Niuhaiwen's avatar
Niuhaiwen committed
1086 1087 1088
  RegistrationRequest *regReq = new RegistrationRequest();
  regReq->decodefrombuffer(nullptr, (uint8_t *)bdata(reg), blength(reg));
  bdestroy(reg); // free buffer
Niuhaiwen's avatar
Niuhaiwen committed
1089
  // Check 5gs Mobility Identity (Mandatory IE)
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1090 1091
  std::string guti;
  uint8_t mobility_id_type = regReq->getMobilityIdentityType();
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1092
  switch (mobility_id_type) {
Niuhaiwen's avatar
Niuhaiwen committed
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106
  case SUCI: {
    nas::SUCI_imsi_t imsi;
    if (!regReq->getSuciSupiFormatImsi(imsi)) {
      Logger::amf_n1().warn("No SUCI and IMSI for SUPI Format");
    } else {
      if (!nc.get()) {
        nc = std::shared_ptr<nas_context>(new nas_context);
        set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
        nc.get()->ctx_avaliability_ind = false;
        // 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;
1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130
        ctx_avaliability_ind["Content-ID"] = "ctx_avaliability_ind";
        ctx_avaliability_ind["Content-Type"] = "varchar(32)";
        ctx_avaliability_ind["content"] =to_string(nc.get()->ctx_avaliability_ind);
        udsf_nas_context["blocks"].push_back(ctx_avaliability_ind);
        
        nas_status_json["Content-ID"] = "nas_status";
        nas_status_json["Content-Type"] = "varchar(32)";
        nas_status_json["content"] =(nc.get()->nas_status);
        udsf_nas_context["blocks"].push_back(nas_status_json);
        
        amf_ue_ngap_id_json["Content-ID"] = "amf_ue_ngap_id";
        amf_ue_ngap_id_json["Content-Type"] = "varchar(32)";
        amf_ue_ngap_id_json["content"] =to_string(nc.get()->amf_ue_ngap_id);
        udsf_nas_context["blocks"].push_back(amf_ue_ngap_id_json);
        
        ran_ue_ngap_id_json["Content-ID"] = "ran_ue_ngap_id";
        ran_ue_ngap_id_json["Content-Type"] = "varchar(32)";
        ran_ue_ngap_id_json["content"] =to_string(nc.get()->ran_ue_ngap_id);
        udsf_nas_context["blocks"].push_back(ran_ue_ngap_id_json);
        
        serving_network["Content-ID"] = "serving_network";
        serving_network["Content-Type"] = "varchar(32)";
        serving_network["content"] =(nc.get()->serving_network);
        udsf_nas_context["blocks"].push_back(serving_network);
Niuhaiwen's avatar
Niuhaiwen committed
1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
      }
      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;
      // try to find old nas_context and release
      std::shared_ptr<nas_context> old_nc =
          imsi2nas_context[("imsi-" + nc.get()->imsi)];
      if (old_nc.get()) {
        // release
        old_nc.reset();
      }
      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());
1147 1148 1149 1150 1151 1152 1153 1154 1155
                            
      is_imsi_present["Content-ID"] = "is_imsi_present";
      is_imsi_present["Content-Type"] = "varchar(32)";
      is_imsi_present["content"] = to_string(nc.get()->is_imsi_present);
      udsf_nas_context["blocks"].push_back(is_imsi_present);
      imsi_json["Content-ID"] = "imsi";
      imsi_json["Content-Type"] = "varchar(32)";
      imsi_json["content"] = (nc.get()->imsi);
      udsf_nas_context["blocks"].push_back(imsi_json);
Niuhaiwen's avatar
Niuhaiwen committed
1156 1157
      if (!nc.get()->is_stacs_available) {
        string ue_context_key = "app_ue_ranid_" + to_string(ran_ue_ngap_id) +
1158
                                "-amfid_" + to_string(amf_ue_ngap_id);
Niuhaiwen's avatar
Niuhaiwen committed
1159 1160
        std::shared_ptr<ue_context> uc;
        // uc = amf_app_inst->amf_ue_id_2_ue_context(amf_ue_ngap_id);
Niuhaiwen's avatar
Niuhaiwen committed
1161
        Logger::amf_n1().info(
Niuhaiwen's avatar
Niuhaiwen committed
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179
            "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_info_t ueItem;
        ueItem.connStatus = "5GMM-CONNECTED"; //"CM-CONNECTED";
        ueItem.registerStatus =
            "5GMM-REG-INITIATED"; // 5GMM-COMMON-PROCEDURE-INITIATED
        ueItem.ranid = ran_ue_ngap_id;
        ueItem.amfid = amf_ue_ngap_id;
        ueItem.imsi = nc.get()->imsi;
        ueItem.mcc = uc.get()->cgi.mcc;
        ueItem.mnc = uc.get()->cgi.mnc;
        ueItem.cellId = uc.get()->cgi.nrCellID;

        stacs.update_ue_info(ueItem);
        set_5gmm_state(nc, _5GMM_COMMON_PROCEDURE_INITIATED);
        nc.get()->is_stacs_available = true;
1180
        is_stacs_available["Content-ID"] = "is_stacs_available";
1181 1182 1183
        is_stacs_available["Content-Type"] = "varchar(32)";
        is_stacs_available["content"] = to_string(nc.get()->is_stacs_available);
        udsf_nas_context["blocks"].push_back(is_stacs_available);
1184 1185 1186 1187 1188

        _5gmm_state["Content-ID"] = "_5gmm_state";
        _5gmm_state["Content-Type"] = "varchar(32)";
        _5gmm_state["content"] = to_string(nc.get()->_5gmm_state);
        udsf_nas_context["blocks"].push_back(_5gmm_state);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206
          /*
           bool add_new_ue = true;
           for(int i=0; i< stacs.ues.size(); i++){
           if(!stacs.ues[i].imsi.compare(nc.get()->imsi)){
           stacs.ues[i].connStatus = ueItem.connStatus;
           stacs.ues[i].registerStatus = ueItem.registerStatus;
           stacs.ues[i].ranid = ueItem.ranid;
           stacs.ues[i].amfid = ueItem.amfid;
           stacs.ues[i].guti = ueItem.guti;
           stacs.ues[i].mcc = ueItem.mcc;
           stacs.ues[i].mnc = ueItem.mnc;
           stacs.ues[i].cellId = ueItem.cellId;
           add_new_ue = false;
           break;
           }
           }
           if(add_new_ue)
           stacs.ues.push_back(ueItem);
1207 1208
           */
      }
Niuhaiwen's avatar
Niuhaiwen committed
1209
          // nc.get()->imsi = //need interface to transfer SUCI_imsi_t to string
Niuhaiwen's avatar
Niuhaiwen committed
1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220
    }
  } break;
  case _5G_GUTI: {
    guti = regReq->get_5g_guti();
    Logger::amf_n1().debug("Decoded GUTI from registeration request message");
    if (!guti.compare("error")) {
      Logger::amf_n1().warn("No GUTI IE");
    }
    if (nc.get()) {
      nc.get()->is_5g_guti_present = true;
      nc.get()->to_be_register_by_new_suci = true;
1221 1222 1223 1224 1225 1226 1227 1228 1229
      is_5g_guti_present["Content-ID"] = "is_5g_guti_present";
      is_5g_guti_present["Content-Type"] = "varchar(32)";
      is_5g_guti_present ["content"] = to_string( nc.get()->is_5g_guti_present);
      udsf_nas_context["blocks"].push_back(is_5g_guti_present);
      
      to_be_register_by_new_suci["Content-ID"] = "to_be_register_by_new_suci";
      to_be_register_by_new_suci["Content-Type"] = "varchar(32)";
      to_be_register_by_new_suci ["content"] = to_string( nc.get()->to_be_register_by_new_suci);
      udsf_nas_context["blocks"].push_back(to_be_register_by_new_suci);
Niuhaiwen's avatar
Niuhaiwen committed
1230 1231 1232 1233 1234 1235 1236 1237
    } else 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;
      nc.get()->is_auth_vectors_present = false;
      nc.get()->is_current_security_available = false;
      nc.get()->security_ctx->sc_type = SECURITY_CTX_TYPE_NOT_AVAILABLE;
1238
      is_auth_vectors_present["Content-ID"] = "is_auth_vectors_present";
1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251
      is_auth_vectors_present["Content-Type"] = "varchar(32)";
      is_auth_vectors_present ["content"] = to_string( nc.get()->is_auth_vectors_present);
      udsf_nas_context["blocks"].push_back(is_auth_vectors_present);
      
      is_current_security_available["Content-ID"] = "is_current_security_available";
      is_current_security_available["Content-Type"] = "varchar(32)";
      is_current_security_available ["content"] = to_string( nc.get()->is_current_security_available);
      udsf_nas_context["blocks"].push_back(is_current_security_available);
      
      security_ctx["Content-ID"] = "security_ctx";
      security_ctx["Content-Type"] = "varchar(32)";
      security_ctx ["content"]["sc_type"] = to_string( nc.get()->security_ctx->sc_type);
      udsf_nas_context["blocks"].push_back(security_ctx);
Niuhaiwen's avatar
Niuhaiwen committed
1252 1253 1254 1255 1256 1257 1258 1259 1260 1261
    } else {
      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);
      if (!nc.get()) {
        Logger::amf_n1().error(
            "Cannot allocate memory for new nas_context, exit...");
        return;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1262
      }
Niuhaiwen's avatar
Niuhaiwen committed
1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278
      Logger::amf_n1().info(
          "Created new nas_context (%p) associated with amf_ue_ngap_id (%d) "
          "for nas_signalling_establishment_request",
          nc.get(), amf_ue_ngap_id);
      set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
      nc.get()->ctx_avaliability_ind = false;
      // 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;
      nc.get()->is_5g_guti_present = true;
      nc.get()->to_be_register_by_new_suci = true;
      nc.get()->ngKsi = 100;
      // supi2amfId[("imsi-"+nc.get()->imsi)] = amf_ue_ngap_id;
      // supi2ranId[("imsi-"+nc.get()->imsi)] = ran_ue_ngap_id;
1279
      ctx_avaliability_ind["Content-ID"] = "ctx_avaliability_ind";
1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324
      ctx_avaliability_ind["Content-Type"] = "varchar(32)";
      ctx_avaliability_ind ["content"] = to_string( nc.get()->ctx_avaliability_ind);
      udsf_nas_context["blocks"].push_back(ctx_avaliability_ind);

      
      nas_status_json["Content-ID"] = "nas_status";
      nas_status_json["Content-Type"] = "varchar(32)";
      nas_status_json["content"] = (nc.get()->nas_status);
      udsf_nas_context["blocks"].push_back(nas_status_json);

      
      amf_ue_ngap_id_json["Content-ID"] = "amf_ue_ngap_id";
      amf_ue_ngap_id_json["Content-Type"] = "varchar(32)";
      amf_ue_ngap_id_json ["content"] = to_string( nc.get()->amf_ue_ngap_id);
      udsf_nas_context["blocks"].push_back(amf_ue_ngap_id_json);

      
      ran_ue_ngap_id_json["Content-ID"] = "ran_ue_ngap_id";
      ran_ue_ngap_id_json["Content-Type"] = "varchar(32)";
      ran_ue_ngap_id_json ["content"] = to_string( nc.get()->ran_ue_ngap_id);
      udsf_nas_context["blocks"].push_back(ran_ue_ngap_id_json);

      
      serving_network["Content-ID"] = "serving_network";
      serving_network["Content-Type"] = "varchar(32)";
      serving_network ["content"] = ( nc.get()->serving_network);
      udsf_nas_context["blocks"].push_back(serving_network);

     
      is_5g_guti_present["Content-ID"] = "is_5g_guti_present";
      is_5g_guti_present["Content-Type"] = "varchar(32)";
      is_5g_guti_present ["content"] = to_string( nc.get()->is_5g_guti_present);
      udsf_nas_context["blocks"].push_back(is_5g_guti_present);

      
      to_be_register_by_new_suci["Content-ID"] = "to_be_register_by_new_suci";
      to_be_register_by_new_suci["Content-Type"] = "varchar(32)";
      to_be_register_by_new_suci ["content"] = to_string( nc.get()->to_be_register_by_new_suci);
      udsf_nas_context["blocks"].push_back(to_be_register_by_new_suci);

      
      ngKsi["Content-ID"] = "ngKsi";
      ngKsi["Content-Type"] = "varchar(32)";
      ngKsi ["content"] = to_string( nc.get()->ngKsi);
      udsf_nas_context["blocks"].push_back(ngKsi);
Niuhaiwen's avatar
Niuhaiwen committed
1325 1326
    }
  } break;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1327
  }
dukl's avatar
dukl committed
1328

Niuhaiwen's avatar
Niuhaiwen committed
1329
  // Create NAS context
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1330
  if (nc.get() == nullptr) {
Niuhaiwen's avatar
Niuhaiwen committed
1331
    // try to get the GUTI -> nas_context
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1332
    if (is_guti_2_nas_context(guti)) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1333
      nc = guti_2_nas_context(guti);
dukl's avatar
dukl committed
1334
      set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1335 1336 1337
      supi2amfId[("imsi-" + nc.get()->imsi)] = amf_ue_ngap_id;
      supi2ranId[("imsi-" + nc.get()->imsi)] = ran_ue_ngap_id;

Niuhaiwen's avatar
Niuhaiwen committed
1338
      // test  5g guti //
Niuhaiwen's avatar
Niuhaiwen committed
1339
      nc.get()->is_auth_vectors_present = false;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1340
      nc.get()->is_current_security_available = false;
Niuhaiwen's avatar
Niuhaiwen committed
1341
      nc.get()->security_ctx->sc_type = SECURITY_CTX_TYPE_NOT_AVAILABLE;
1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357

      is_auth_vectors_present["Content-ID"] = "is_auth_vectors_present";
      is_auth_vectors_present["Content-Type"] = "varchar(32)";
      is_auth_vectors_present ["content"] = to_string( nc.get()->is_auth_vectors_present);
      udsf_nas_context["blocks"].push_back(is_auth_vectors_present);

      is_current_security_available["Content-ID"] = "is_current_security_available";
      is_current_security_available["Content-Type"] = "varchar(32)";
      is_current_security_available ["content"] = to_string( nc.get()->is_current_security_available);
      udsf_nas_context["blocks"].push_back(is_current_security_available);

      security_ctx["Content-ID"] = "security_ctx";
      security_ctx["Content-Type"] = "JSON";
      security_ctx["content"]["sc_type"] = nc.get()->security_ctx->sc_type;
      udsf_nas_context["blocks"].push_back(security_ctx);

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1358
    } else {
Niuhaiwen's avatar
Niuhaiwen committed
1359
      Logger::amf_n1().error("No nas_context with GUTI (%s)", guti.c_str());
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1360 1361 1362
      response_registration_reject_msg(
          _5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED, ran_ue_ngap_id,
          amf_ue_ngap_id);
Niuhaiwen's avatar
Niuhaiwen committed
1363 1364
      // release ue_ngap_context and ue_context
      string ue_context_key = "app_ue_ranid_" + to_string(ran_ue_ngap_id) +
1365
                              "-amfid_" + to_string(amf_ue_ngap_id);
Niuhaiwen's avatar
Niuhaiwen committed
1366 1367
      std::shared_ptr<ue_context> uc =
          amf_app_inst->ran_amf_id_2_ue_context(ue_context_key);
Niuhaiwen's avatar
Niuhaiwen committed
1368 1369
      if (uc.get())
        uc.reset();
Niuhaiwen's avatar
Niuhaiwen committed
1370 1371
      std::shared_ptr<ue_ngap_context> unc =
          amf_n2_inst->ran_ue_id_2_ue_ngap_context(ran_ue_ngap_id);
Niuhaiwen's avatar
Niuhaiwen committed
1372 1373
      if (unc.get())
        unc.reset();
dukl's avatar
dukl committed
1374
      delete regReq;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1375 1376
      return;
    }
Keliang's avatar
Keliang committed
1377
  } else {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1378
    Logger::amf_n1().debug("Existing nas_context --> Update");
Keliang's avatar
Keliang committed
1379
    // nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
dukl's avatar
dukl committed
1380
  }
Niuhaiwen's avatar
Niuhaiwen committed
1381 1382
  nc.get()->ran_ue_ngap_id = ran_ue_ngap_id;
  nc.get()->amf_ue_ngap_id = amf_ue_ngap_id;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1383
  nc.get()->serving_network = snn;
1384

1385 1386 1387 1388 1389 1390 1391 1392 1393 1394
  amf_ue_ngap_id_json["Content-ID"] = "amf_ue_ngap_id";
  amf_ue_ngap_id_json["Content-Type"] = "varchar(32)";
  amf_ue_ngap_id_json["content"] =to_string(nc.get()->amf_ue_ngap_id);
  udsf_nas_context["blocks"].push_back(amf_ue_ngap_id_json);
  
  ran_ue_ngap_id_json["Content-ID"] = "ran_ue_ngap_id";
  ran_ue_ngap_id_json["Content-Type"] = "varchar(32)";
  ran_ue_ngap_id_json["content"] =to_string(nc.get()->ran_ue_ngap_id);
  udsf_nas_context["blocks"].push_back(ran_ue_ngap_id_json);
  
liuyu's avatar
liuyu committed
1395
  serving_network["Content-ID"] = "serving_network";
1396 1397 1398 1399
  serving_network["Content-Type"] = "varchar(32)";
  serving_network["content"] =(nc.get()->serving_network);
  udsf_nas_context["blocks"].push_back(serving_network);

Niuhaiwen's avatar
Niuhaiwen committed
1400
  // Check 5GS_Registration_type IE (Mandatory IE)
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1401 1402 1403 1404
  uint8_t reg_type;
  bool is_follow_on_req_pending;
  if (!regReq->get5GSRegistrationType(is_follow_on_req_pending, reg_type)) {
    Logger::amf_n1().error("Missing Mandatory IE 5GS Registration type...");
Niuhaiwen's avatar
Niuhaiwen committed
1405 1406
    response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
                                     ran_ue_ngap_id, amf_ue_ngap_id);
dukl's avatar
dukl committed
1407
    delete regReq;
1408

1409
    return;
dukl's avatar
dukl committed
1410
  }
Niuhaiwen's avatar
Niuhaiwen committed
1411
  nc.get()->registration_type = reg_type;
dukl's avatar
dukl committed
1412 1413
  nc.get()->follow_on_req_pending_ind = is_follow_on_req_pending;

1414
  registration_type["Content-ID"] = "registration_type";
1415 1416 1417 1418 1419 1420 1421 1422 1423
  registration_type["Content-Type"] = "varchar(32)";
  registration_type["content"] =to_string(nc.get()->registration_type);
  udsf_nas_context["blocks"].push_back(registration_type);
  
  follow_on_req_pending_ind["Content-ID"] = "follow_on_req_pending_ind";
  follow_on_req_pending_ind["Content-Type"] = "varchar(32)";
  follow_on_req_pending_ind["content"] =to_string(nc.get()->follow_on_req_pending_ind);
  udsf_nas_context["blocks"].push_back(follow_on_req_pending_ind);

Niuhaiwen's avatar
Niuhaiwen committed
1424
  // Check ngKSI (Mandatory IE)
dukl's avatar
dukl committed
1425
  uint8_t ngKSI = regReq->getngKSI();
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1426
  if (ngKSI == -1) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1427
    Logger::amf_n1().error("Missing Mandatory IE ngKSI...");
Niuhaiwen's avatar
Niuhaiwen committed
1428 1429
    response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
                                     ran_ue_ngap_id, amf_ue_ngap_id);
dukl's avatar
dukl committed
1430
    delete regReq;
1431
    return;
dukl's avatar
dukl committed
1432 1433
  }
  nc.get()->ngKsi = ngKSI;
1434 1435 1436 1437
  ngKsi["Content-ID"] = "ngKsi";
  ngKsi["Content-Type"] = "varchar(32)";
  ngKsi ["content"] = to_string( nc.get()->ngKsi);
  udsf_nas_context["blocks"].push_back(ngKsi);
dukl's avatar
dukl committed
1438

Niuhaiwen's avatar
Niuhaiwen committed
1439 1440 1441
  // Get non-current native nas key set identity (Optional IE), used for
  // inter-system change from S1 to N1 Get 5GMM Capability IE (optional), not
  // included for periodic registration updating procedure
dukl's avatar
dukl committed
1442
  uint8_t _5g_mm_cap = regReq->get5GMMCapability();
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1443 1444
  if (_5g_mm_cap == -1) {
    Logger::amf_n1().warn("No Optional IE 5GMMCapability available");
dukl's avatar
dukl committed
1445
  }
1446
  nc.get()->mmCapability = _5g_mm_cap;
1447
  mmCapability["Content-ID"] = "mmCapability";
1448 1449 1450
  mmCapability["Content-Type"] = "varchar(32)";
  mmCapability ["content"] = to_string( nc.get()->mmCapability);
  udsf_nas_context["blocks"].push_back(mmCapability);
1451

Niuhaiwen's avatar
Niuhaiwen committed
1452 1453
  // Get UE Security Capability IE (optional), not included for periodic
  // registration updating procedure
Niuhaiwen's avatar
Niuhaiwen committed
1454
  uint8_t encrypt_alg = {0};
Niuhaiwen's avatar
Niuhaiwen committed
1455
  uint8_t integrity_alg = {0};
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1456 1457
  if (!regReq->getUeSecurityCapability(encrypt_alg, integrity_alg)) {
    Logger::amf_n1().warn("No Optional IE UESecurityCapability available");
dukl's avatar
dukl committed
1458
  }
1459 1460
  else{
    nc.get()->ueSecurityCaplen = regReq->ie_ue_security_capability->getLenght();
1461 1462 1463 1464 1465
    
    ueSecurityCaplen["Content-ID"] = "ueSecurityCaplen";
    ueSecurityCaplen["Content-Type"] = "varchar(32)";
    ueSecurityCaplen ["content"] = to_string( nc.get()->ueSecurityCaplen);
    udsf_nas_context["blocks"].push_back(ueSecurityCaplen);
yangjian's avatar
yangjian committed
1466 1467 1468

    nc.get()->ueSecurityCapEEnc = regReq->ie_ue_security_capability->getEEASel();
    nc.get()->ueSecurityCapEInt = regReq->ie_ue_security_capability->getEIASel();
1469
  }
1470 1471
  nc.get()->ueSecurityCapEnc = encrypt_alg;
  nc.get()->ueSecurityCapInt = integrity_alg;
1472 1473 1474
  ueSecurityCapEnc["Content-ID"] = "ueSecurityCapEnc";
  ueSecurityCapEnc["Content-Type"] = "varchar(32)";
  ueSecurityCapEnc ["content"] = to_string( nc.get()->ueSecurityCapEnc);
liuyu's avatar
liuyu committed
1475
  udsf_nas_context["blocks"].push_back(ueSecurityCapEnc);
1476 1477 1478 1479 1480 1481 1482 1483
  
  ueSecurityCapInt["Content-ID"] = "ueSecurityCapInt";
  ueSecurityCapInt["Content-Type"] = "varchar(32)";
  ueSecurityCapInt ["content"] = to_string( nc.get()->ueSecurityCapInt);
  udsf_nas_context["blocks"].push_back(ueSecurityCapInt);
  
 

1484 1485 1486 1487 1488 1489 1490

  uint16_t pdu_session_status = 0xffff;
  pdu_session_status = regReq->getPduSessionStatus();
  bool is_messagecontainer = false;
  bstring nas_msg;
  is_messagecontainer = regReq->getNasMessageContainer(nas_msg);

1491

Niuhaiwen's avatar
Niuhaiwen committed
1492 1493
  // Get Requested NSSAI (Optional IE), if provided
  std::vector<SNSSAI_t> requestedNssai = {};
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1494 1495
  if (!regReq->getRequestedNssai(requestedNssai)) {
    Logger::amf_n1().warn("No Optional IE RequestedNssai available");
dukl's avatar
dukl committed
1496
  }
Niuhaiwen's avatar
Niuhaiwen committed
1497 1498
  delete regReq; // free after getting values from message
  nc.get()->requestedNssai = requestedNssai;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1499
  nc.get()->ctx_avaliability_ind = true;
1500
  requestedNssai_json["Content-ID"] = "requestedNssai";
liuyu's avatar
liuyu committed
1501
  requestedNssai_json["Content-Type"] = "JSON";
1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518
  requestedNssai_json ["content"] = {};
  nlohmann::json requestedNssai_m = {};
  for(int i=0;i<nc->requestedNssai.size();i++)
    {
      requestedNssai_m["sst"]=to_string(nc->requestedNssai[i].sst);
      requestedNssai_m["sd"]=to_string(nc->requestedNssai[i].sd);
      requestedNssai_m["mHplmnSst"]=to_string(nc->requestedNssai[i].mHplmnSst);
      requestedNssai_m["mHplmnSd"]=to_string(nc->requestedNssai[i].mHplmnSd);
      requestedNssai_json["content"].push_back(requestedNssai_m);

    }
  udsf_nas_context["blocks"].push_back(requestedNssai_json);
  ctx_avaliability_ind["Content-ID"] = "ctx_avaliability_ind";
  ctx_avaliability_ind["Content-Type"] = "varchar(32)";
  ctx_avaliability_ind ["content"] = to_string( nc.get()->ctx_avaliability_ind);
  udsf_nas_context["blocks"].push_back(ctx_avaliability_ind);

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1519

Niuhaiwen's avatar
Niuhaiwen committed
1520 1521 1522 1523 1524
  // Get Last visited registered TAI(OPtional IE), if provided
  // Get S1 Ue network capability(OPtional IE), if ue supports S1 mode
  // Get uplink data status(Optional IE), if UE has uplink user data to be sent
  // Get pdu session status(OPtional IE), associated and active pdu sessions
  // available in UE
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1525

Niuhaiwen's avatar
Niuhaiwen committed
1526 1527
  // Store NAS information into nas_context
  // Run different registration procedure
1528 1529
  
  /**********************hsx add***********************/
liuyu's avatar
liuyu committed
1530
  std::string udsf_url = "http://10.112.202.24:7123/nudsf-dr/v1/amfdata/" + std::string("nas_context/records/") + to_string(nc.get()->amf_ue_ngap_id) ;
1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551
  
  nlohmann::json udsf_response;
  udsf_nas_context["meta"] ["tags"] = {
                                      {"RECORD_ID",nlohmann::json::array({to_string(nc.get()->amf_ue_ngap_id)})},
                                      {"from_nf_ID",nlohmann::json::array({"AMF_1234"})}
                                      } ;    
  // udsf_nas_context["blocks"] = nlohmann::json::array({
  //                                                 {{"Content-ID", "ctx_avaliability_ind"},{"Content-Type", "varchar(32)"},{"content", to_string(nc.get()->ctx_avaliability_ind)}},
  //                                                 {{"Content-ID", "amf_ue_ngap_id"},{"Content-Type", "varchar(32)"},{"content", to_string(nc.get()->amf_ue_ngap_id)}},
  //                                                 {{"Content-ID", "ran_ue_ngap_id"},{"Content-Type", "varchar(32)"},{"content", to_string(nc.get()->ran_ue_ngap_id)}},
  //                                                 {{"Content-ID", "registration_type"},{"Content-Type", "varchar(32)"},{"content", to_string( nc->registration_type)}},
  //                                                 {{"Content-ID", "follow_on_req_pending_ind"},{"Content-Type", "varchar(32)"},{"content",  to_string( nc->follow_on_req_pending_ind)}},
  //                                                 {{"Content-ID", "ngKsi"},{"Content-Type", "varchar(32)"},{"content", to_string( nc->ngKsi)}},
  //                                                 {{"Content-ID", "imsi"},{"Content-Type", "varchar(32)"},{"content", nc->imsi}},
  //                                                 {{"Content-ID", "mmCapability"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->mmCapability)}},
  //                                                 {{"Content-ID", "ueSecurityCaplen"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->ueSecurityCaplen)}},
  //                                                 {{"Content-ID", "ueSecurityCapEnc"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->ueSecurityCapEnc)}},
  //                                                 {{"Content-ID", "ueSecurityCapInt"},{"Content-Type", "varchar(32)"},{"content",  to_string(nc->ueSecurityCapInt)}},
  //                                                 {{"Content-ID", "serving_network"},{"Content-Type", "varchar(32)"},{"content",  nc->serving_network}}
  //                                             });
  
liuyu's avatar
liuyu committed
1552
  printf("----------------udsf_nas_context %s---------\n",udsf_nas_context.dump().c_str());
1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574
  amf_n2_inst->curl_http_client_udsf(udsf_url,udsf_nas_context.dump(),"PUT",udsf_response);

  // udsf_url = "http://10.112.202.24:7123/nudsf-dr/v1/amfdata/" + std::string("nas_context/records/") + std::to_string(nc.get()->amf_ue_ngap_id) ;
  // if(!amf_n2_inst->curl_http_client_udsf(udsf_url,"","GET",udsf_response)){
  // Logger::amf_n2().error("No existing gNG context with assoc_id (%d)", nc.get()->amf_ue_ngap_id);
  //   return;
  // }
  // Logger::amf_n2().debug("udsf_response: %s", udsf_response.dump().c_str());


  // nas_context *nc1 = new nas_context();
  // std::shared_ptr<nas_context> nc2;
  // nc1->nas_context_from_json(udsf_response);
  // nc2 = std::shared_ptr<nas_context>(nc1);

  //printf("ran_ue_ngap_id-%d\n",nc2.get()->ran_ue_ngap_id);
//printf("amf_ue_ngap_id-%d\n",nc2.get()->amf_ue_ngap_id);
//printf("ctx_avaliability_ind-%d\n",nc2.get()->ctx_avaliability_ind);
//printf("nas_status-%d\n",nc2.get()->nas_status);
//printf("serving_network-%d\n",nc2.get()->serving_network);

  /**********************hsx add***********************/
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1575
  switch (reg_type) {
Niuhaiwen's avatar
Niuhaiwen committed
1576 1577 1578 1579 1580 1581
  case INITIAL_REGISTRATION: {
    run_initial_registration_procedure(); // IEs?
    run_registration_procedure(nc);
  } break;
  case MOBILITY_REGISTRATION_UPDATING: {
    Logger::amf_n1().error("Network handling mobility registration ...");
1582 1583 1584 1585 1586
    //run_mobility_registration_update_procedure(nc);
  if(is_messagecontainer)
        run_periodic_registration_update_procedure(nc, nas_msg);
    else
        run_periodic_registration_update_procedure(nc, pdu_session_status);
Niuhaiwen's avatar
Niuhaiwen committed
1587 1588
  } break;
  case PERIODIC_REGISTRATION_UPDATING: {
1589

yangjian's avatar
yangjian committed
1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602
    char *pathvar = NULL;
    pathvar = getenv("IS_AMF_PERIODIC");
    if(pathvar && !strcmp(pathvar, "true"))
    {
      Logger::amf_n1().debug("Network handling periodic registration ...");
      if(is_messagecontainer)
          run_periodic_registration_update_procedure(nc, nas_msg);
      else
          run_periodic_registration_update_procedure(nc, pdu_session_status);
    } else{
      Logger::amf_n1().warn("Please set environment variable \"IS_AMF_PERIODIC\"");
      Logger::amf_n1().error("Network doesn't support periodic registration, reject ...");
    }
Niuhaiwen's avatar
Niuhaiwen committed
1603 1604 1605
  } break;
  case EMERGENCY_REGISTRATION: {
    if (!amf_cfg.is_emergency_support.compare("false")) {
1606
      Logger::amf_n1().error(
Niuhaiwen's avatar
Niuhaiwen committed
1607 1608 1609 1610 1611 1612
          "Network doesn't support emergency registration, reject ...");
      response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
                                       amf_ue_ngap_id); // cause?
      return;
    }
  } break;
dukl's avatar
dukl committed
1613
  }
dukl's avatar
dukl committed
1614 1615
}

1616 1617
//------------------------------------------------------------------------------
// authentication vector handlers
Niuhaiwen's avatar
Niuhaiwen committed
1618
bool amf_n1::generate_authentication_vector() {}
dukl's avatar
dukl committed
1619

1620 1621
// context management functions
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
1622
bool amf_n1::is_amf_ue_id_2_nas_context(const long &amf_ue_ngap_id) const {
dukl's avatar
dukl committed
1623
  std::shared_lock lock(m_amfueid2nas_context);
dukl's avatar
dukl committed
1624
  return bool{amfueid2nas_context.count(amf_ue_ngap_id) > 0};
dukl's avatar
dukl committed
1625 1626
}

1627
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
1628 1629
std::shared_ptr<nas_context>
amf_n1::amf_ue_id_2_nas_context(const long &amf_ue_ngap_id) const {
dukl's avatar
dukl committed
1630 1631 1632 1633
  std::shared_lock lock(m_amfueid2nas_context);
  return amfueid2nas_context.at(amf_ue_ngap_id);
}

1634
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
1635 1636
void amf_n1::set_amf_ue_ngap_id_2_nas_context(const long &amf_ue_ngap_id,
                                              std::shared_ptr<nas_context> nc) {
dukl's avatar
dukl committed
1637 1638 1639 1640
  std::shared_lock lock(m_amfueid2nas_context);
  amfueid2nas_context[amf_ue_ngap_id] = nc;
}

1641
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
1642
bool amf_n1::is_guti_2_nas_context(const std::string &guti) const {
dukl's avatar
dukl committed
1643
  std::shared_lock lock(m_guti2nas_context);
dukl's avatar
dukl committed
1644
  return bool{guti2nas_context.count(guti) > 0};
dukl's avatar
dukl committed
1645 1646
}

1647
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
1648 1649
std::shared_ptr<nas_context>
amf_n1::guti_2_nas_context(const std::string &guti) const {
dukl's avatar
dukl committed
1650 1651 1652
  std::shared_lock lock(m_guti2nas_context);
  return guti2nas_context.at(guti);
}
dukl's avatar
dukl committed
1653

1654
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
1655 1656
void amf_n1::set_guti_2_nas_context(const std::string &guti,
                                    std::shared_ptr<nas_context> nc) {
dukl's avatar
dukl committed
1657 1658 1659
  std::shared_lock lock(m_guti2nas_context);
  guti2nas_context[guti] = nc;
}
dukl's avatar
dukl committed
1660

1661 1662
// to lower layer TASK_N2
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
1663 1664 1665 1666
void amf_n1::itti_send_dl_nas_buffer_to_task_n2(bstring &b,
                                                uint32_t ran_ue_ngap_id,
                                                long amf_ue_ngap_id) {
  itti_dl_nas_transport *msg =
Niuhaiwen's avatar
Niuhaiwen committed
1667
      new itti_dl_nas_transport(TASK_AMF_N1, TASK_AMF_N2);
dukl's avatar
dukl committed
1668 1669
  msg->ran_ue_ngap_id = ran_ue_ngap_id;
  msg->amf_ue_ngap_id = amf_ue_ngap_id;
Niuhaiwen's avatar
Niuhaiwen committed
1670
  msg->nas = b;
Niuhaiwen's avatar
Niuhaiwen committed
1671 1672
  std::shared_ptr<itti_dl_nas_transport> i =
      std::shared_ptr<itti_dl_nas_transport>(msg);
dukl's avatar
dukl committed
1673 1674
  int ret = itti_inst->send_msg(i);
  if (0 != ret) {
Niuhaiwen's avatar
Niuhaiwen committed
1675 1676
    Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2",
                           i->get_msg_name());
dukl's avatar
dukl committed
1677 1678 1679
  }
}

1680 1681
//------------------------------------------------------------------------------
// response messages
Niuhaiwen's avatar
Niuhaiwen committed
1682 1683 1684 1685
void amf_n1::response_registration_reject_msg(uint8_t cause_value,
                                              uint32_t ran_ue_ngap_id,
                                              long amf_ue_ngap_id) {
  RegistrationReject *registrationRej = new RegistrationReject();
dukl's avatar
dukl committed
1686 1687
  registrationRej->setHeader(PLAIN_5GS_MSG);
  registrationRej->set_5GMM_Cause(cause_value);
Niuhaiwen's avatar
Niuhaiwen committed
1688
  uint8_t buffer[BUFFER_SIZE_1024] = {0};
1689
  int encoded_size = registrationRej->encode2buffer(buffer, BUFFER_SIZE_1024);
Niuhaiwen's avatar
Niuhaiwen committed
1690
  // dump_nas_message(buffer, encoded_size);
Niuhaiwen's avatar
Niuhaiwen committed
1691 1692
  print_buffer("amf_n1", "Registration-Reject message buffer", buffer,
               encoded_size);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1693
  if (!encoded_size) {
1694
    Logger::nas_mm().error("Encode Registration-Reject message error");
dukl's avatar
dukl committed
1695
    return;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1696
  } else {
dukl's avatar
dukl committed
1697 1698 1699
    delete registrationRej;
  }
  bstring b = blk2bstr(buffer, encoded_size);
1700
  itti_send_dl_nas_buffer_to_task_n2(b, ran_ue_ngap_id, amf_ue_ngap_id);
dukl's avatar
dukl committed
1701 1702
}

1703 1704
//------------------------------------------------------------------------------
// specific procedures running logic
Niuhaiwen's avatar
Niuhaiwen committed
1705
void amf_n1::run_registration_procedure(std::shared_ptr<nas_context> &nc) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1706
  Logger::amf_n1().debug("Start to run registration procedure");
1707 1708 1709 1710 1711 1712
  nlohmann::json udsf_nas_context;
  nlohmann::json udsf_response;
  nlohmann::json is_specific_procedure_for_registration_running;
  nlohmann::json is_auth_vectors_present;
  nlohmann::json ngksi;
  
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1713 1714
  if (!nc.get()->ctx_avaliability_ind) {
    Logger::amf_n1().error("NAS context is not available");
dukl's avatar
dukl committed
1715 1716 1717
    return;
  }
  nc.get()->is_specific_procedure_for_registration_running = true;
1718 1719 1720 1721
  is_specific_procedure_for_registration_running["Content-ID"] = "is_specific_procedure_for_registration_running";
  is_specific_procedure_for_registration_running["Content-Type"] = "varchar(32)";
  is_specific_procedure_for_registration_running["content"] = to_string(nc.get()->is_stacs_available);
  udsf_nas_context["blocks"].push_back(is_specific_procedure_for_registration_running);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1722 1723 1724 1725 1726
  if (nc.get()->is_imsi_present) {
    Logger::amf_n1().debug("SUCI SUPI format IMSI is available");
    if (!nc.get()->is_auth_vectors_present) {
      Logger::amf_n1().debug(
          "Authentication vector in nas_context is not available");
Niuhaiwen's avatar
Niuhaiwen committed
1727
      if (auth_vectors_generator(nc)) { // all authentication in one(AMF)
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1728
        ngksi_t ngksi = 0;
Niuhaiwen's avatar
Niuhaiwen committed
1729 1730 1731
        if (nc.get()->security_ctx &&
            nc.get()->ngKsi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE) {
          // ngksi = (nc.get()->ngKsi + 1) % (NGKSI_MAX_VALUE + 1);
Niuhaiwen's avatar
Niuhaiwen committed
1732
          ngksi = (nc.get()->amf_ue_ngap_id + 1); // % (NGKSI_MAX_VALUE + 1);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1733 1734
        }
        nc.get()->ngKsi = ngksi;
dukl's avatar
dukl committed
1735
        handle_auth_vector_successful_result(nc);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1736 1737
      } else {
        Logger::amf_n1().error("Request authentication vectors failure");
Niuhaiwen's avatar
Niuhaiwen committed
1738 1739 1740
        response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE,
                                         nc.get()->ran_ue_ngap_id,
                                         nc.get()->amf_ue_ngap_id); // cause?
dukl's avatar
dukl committed
1741
      }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1742 1743 1744
    } else {
      Logger::amf_n1().debug(
          "Authentication vector in nas_context is available");
dukl's avatar
dukl committed
1745
      ngksi_t ngksi = 0;
Niuhaiwen's avatar
Niuhaiwen committed
1746 1747 1748
      if (nc.get()->security_ctx &&
          nc.get()->ngKsi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE) {
        // ngksi = (nc.get()->ngKsi + 1) % (NGKSI_MAX_VALUE + 1);
Niuhaiwen's avatar
Niuhaiwen committed
1749
        ngksi = (nc.get()->amf_ue_ngap_id + 1); // % (NGKSI_MAX_VALUE + 1);
1750
        Logger::amf_n1().debug("New ngKsi(%d)", ngksi);
dukl's avatar
dukl committed
1751 1752
        // ... how to handle?
      }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1753 1754
      nc.get()->ngKsi = ngksi;
      handle_auth_vector_successful_result(nc);
dukl's avatar
dukl committed
1755
    }
1756 1757 1758 1759 1760 1761 1762

  // ngksi["Content-ID"] = "ngKsi";
  // ngksi["Content-Type"] = "varchar(32)";
  // ngksi["content"] = to_string(nc.get()->ngKsi);
  // udsf_nas_context["blocks"].push_back(ngksi);
  // std::string udsf_url = "http://10.112.202.24:7123/nudsf-dr/v1/amfdata/" + std::string("nas_context/records/") + to_string(nc.get()->amf_ue_ngap_id) ;
  // amf_n2_inst->curl_http_client_udsf(udsf_url,udsf_nas_context.dump(),"PUT",udsf_response);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1763
  } else if (nc.get()->is_5g_guti_present) {
dukl's avatar
dukl committed
1764
    Logger::amf_n1().debug("Start to run identification procedure");
dukl's avatar
dukl committed
1765 1766
    nc.get()->is_auth_vectors_present = false;
    // ... identification procedure
Niuhaiwen's avatar
Niuhaiwen committed
1767
    IdentityRequest *ir = new IdentityRequest();
Niuhaiwen's avatar
Niuhaiwen committed
1768
    // itti_msg->cause = 28;//cause nas(2)--deregister
dukl's avatar
dukl committed
1769 1770 1771 1772 1773
    ir->setHeader(PLAIN_5GS_MSG);
    ir->set_5GS_Identity_Type(SUCI);
    uint8_t buffer[100];
    int encoded_size = ir->encode2buffer(buffer, 100);
    delete ir;
1774
    itti_dl_nas_transport *dnt = new itti_dl_nas_transport(TASK_AMF_N1, TASK_AMF_N2);
Niuhaiwen's avatar
Niuhaiwen committed
1775
    dnt->nas = blk2bstr(buffer, encoded_size);
dukl's avatar
dukl committed
1776 1777
    dnt->amf_ue_ngap_id = nc.get()->amf_ue_ngap_id;
    dnt->ran_ue_ngap_id = nc.get()->ran_ue_ngap_id;
1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788
    /*************************hsx add**************************/
    std::string udsf_url = "http://10.112.202.24:7123/nudsf-dr/v1/amfdata/" + std::string("nas_context/records/") + to_string(nc.get()->amf_ue_ngap_id) ;
    udsf_nas_context["meta"] ["tags"] = {
                                        {"RECORD_ID",nlohmann::json::array({to_string(nc.get()->amf_ue_ngap_id)})},
                                        {"from_nf_ID",nlohmann::json::array({"AMF_1234"})}
                                        } ;    
    udsf_nas_context["blocks"] = nlohmann::json::array({
                                                {{"Content-ID", "is_auth_vectors_present"},{"Content-Type", "varchar(32)"},{"content", to_string(nc.get()->is_auth_vectors_present)}}    
                                            });
    amf_n2_inst->curl_http_client_udsf(udsf_url,udsf_nas_context.dump(),"PUT",udsf_response);
    /*************************hsx add**************************/
1789

1790
    std::shared_ptr<itti_dl_nas_transport> i = std::shared_ptr<itti_dl_nas_transport>(dnt);
dukl's avatar
dukl committed
1791 1792
    int ret = itti_inst->send_msg(i);
    if (0 != ret) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
1793 1794 1795
      Logger::amf_n1().error(
          "Could not send ITTI message %s to task TASK_AMF_N2",
          i->get_msg_name());
dukl's avatar
dukl committed
1796
    }
1797
  }
1798
 
dukl's avatar
dukl committed
1799 1800
}

1801 1802
//------------------------------------------------------------------------------
// authentication vectors
Niuhaiwen's avatar
Niuhaiwen committed
1803
// TODO: should be done in UDM/AUSF
Niuhaiwen's avatar
Niuhaiwen committed
1804
bool amf_n1::auth_vectors_generator(std::shared_ptr<nas_context> &nc) {
1805
  Logger::amf_n1().debug("Start to generate authentication vectors");
Keliang's avatar
Keliang committed
1806
  if (amf_cfg.is_Nausf) {
Niuhaiwen's avatar
Niuhaiwen committed
1807 1808
    if (!authentication_vectors_from_ausf(nc))
      return false;
Keliang's avatar
Keliang committed
1809
  } else {
Niuhaiwen's avatar
Niuhaiwen committed
1810
    authentication_vectors_generator_in_udm(nc);
yangjian's avatar
yangjian committed
1811 1812
    authentication_vectors_generator_in_ausf(nc);
    Logger::amf_n1().debug("Deriving kamf");
Keliang's avatar
Keliang committed
1813 1814 1815
    for (int i = 0; i < MAX_5GS_AUTH_VECTORS; i++) {
      Authentication_5gaka::derive_kamf(
          nc.get()->imsi, nc.get()->_5g_av[i].kseaf, nc.get()->kamf[i],
Niuhaiwen's avatar
Niuhaiwen committed
1816
          0x0000); // second parameter: abba
yangjian's avatar
yangjian committed
1817
    }
dukl's avatar
dukl committed
1818 1819 1820
  }
  return true;
}
yangjian's avatar
yangjian committed
1821
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
1822
#define CURL_TIMEOUT_MS 300L
yangjian's avatar
yangjian committed
1823

Niuhaiwen's avatar
Niuhaiwen committed
1824 1825
std::size_t callback_ausf(const char *in, std::size_t size, std::size_t num,
                          std::string *out) {
yangjian's avatar
yangjian committed
1826 1827 1828 1829 1830
  const std::size_t totalBytes(size * num);
  out->append(in, totalBytes);
  return totalBytes;
}

Niuhaiwen's avatar
Niuhaiwen committed
1831 1832
void amf_n1::curl_http_client(std::string remoteUri, std::string Method,
                              std::string msgBody, std::string &Response) {
yangjian's avatar
yangjian committed
1833 1834 1835
  Logger::amf_n1().info("Send HTTP message with body %s", msgBody.c_str());

  uint32_t str_len = msgBody.length();
Niuhaiwen's avatar
Niuhaiwen committed
1836
  char *body_data = (char *)malloc(str_len + 1);
yangjian's avatar
yangjian committed
1837
  memset(body_data, 0, str_len + 1);
Niuhaiwen's avatar
Niuhaiwen committed
1838
  memcpy((void *)body_data, (void *)msgBody.c_str(), str_len);
yangjian's avatar
yangjian committed
1839 1840

  curl_global_init(CURL_GLOBAL_ALL);
Niuhaiwen's avatar
Niuhaiwen committed
1841
  CURL *curl = curl_easy_init();
yangjian's avatar
yangjian committed
1842 1843

  if (curl) {
Niuhaiwen's avatar
Niuhaiwen committed
1844 1845
    CURLcode res = {};
    struct curl_slist *headers = nullptr;
Keliang's avatar
Keliang committed
1846 1847
    if (!Method.compare("POST") || !Method.compare("PATCH") ||
        !Method.compare("PUT")) {
yangjian's avatar
yangjian committed
1848 1849 1850 1851 1852 1853 1854
      std::string content_type = "Content-Type: application/json";
      headers = curl_slist_append(headers, content_type.c_str());
      curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    }
    curl_easy_setopt(curl, CURLOPT_URL, remoteUri.c_str());
    if (!Method.compare("POST"))
      curl_easy_setopt(curl, CURLOPT_HTTPPOST, 1);
Keliang's avatar
Keliang committed
1855
    else if (!Method.compare("PATCH"))
yangjian's avatar
yangjian committed
1856
      curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH");
Keliang's avatar
Keliang committed
1857 1858 1859
    else if (!Method.compare("PUT")) {
      curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
    } else
yangjian's avatar
yangjian committed
1860 1861 1862
      curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT_MS);
    curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1);
yangjian's avatar
yangjian committed
1863
    curl_easy_setopt(curl, CURLOPT_INTERFACE, amf_cfg.nausf.if_name.c_str());
yangjian's avatar
yangjian committed
1864 1865 1866 1867 1868 1869 1870 1871 1872 1873

    // Response information.
    long httpCode = {0};
    std::unique_ptr<std::string> httpData(new std::string());
    std::unique_ptr<std::string> httpHeaderData(new std::string());

    // Hook up data handling function.
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback_ausf);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, httpHeaderData.get());
Keliang's avatar
Keliang committed
1874 1875
    if (!Method.compare("POST") || !Method.compare("PATCH") ||
        !Method.compare("PUT")) {
yangjian's avatar
yangjian committed
1876 1877 1878 1879 1880 1881 1882 1883
      curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, msgBody.length());
      curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body_data);
    }

    res = curl_easy_perform(curl);
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);

    // get the response
Niuhaiwen's avatar
Niuhaiwen committed
1884
    std::string response = *httpData.get();
yangjian's avatar
yangjian committed
1885
    std::string json_data_response = "";
Niuhaiwen's avatar
Niuhaiwen committed
1886 1887
    std::string resMsg = "";
    bool is_response_ok = true;
yangjian's avatar
yangjian committed
1888 1889 1890
    Logger::amf_n1().info("Get response with httpcode (%d)", httpCode);

    if (httpCode == 0) {
Niuhaiwen's avatar
Niuhaiwen committed
1891 1892
      Logger::amf_n1().info("Cannot get response when calling %s",
                            remoteUri.c_str());
yangjian's avatar
yangjian committed
1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919
      // free curl before returning
      curl_slist_free_all(headers);
      curl_easy_cleanup(curl);
      return;
    }

    nlohmann::json response_data = {};

    if (httpCode != 200 && httpCode != 201 && httpCode != 204) {
      is_response_ok = false;
      if (response.size() < 1) {
        Logger::amf_n1().info("There's no content in the response");
        // TODO: send context response error
        return;
      }
      Logger::amf_n1().info("Wrong response code");

      return;
    }

    else {
      Response = *httpData.get();
    }

    if (!is_response_ok) {
      try {
        response_data = nlohmann::json::parse(json_data_response);
Niuhaiwen's avatar
Niuhaiwen committed
1920
      } catch (nlohmann::json::exception &e) {
yangjian's avatar
yangjian committed
1921 1922 1923 1924 1925
        Logger::amf_n1().info("Could not get Json content from the response");
        // Set the default Cause
        response_data["error"]["cause"] = "504 Gateway Timeout";
      }

Niuhaiwen's avatar
Niuhaiwen committed
1926 1927
      Logger::amf_n1().info("Get response with jsonData: %s",
                            json_data_response.c_str());
yangjian's avatar
yangjian committed
1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945

      std::string cause = response_data["error"]["cause"];
      Logger::amf_n1().info("Call Network Function services failure");
      Logger::amf_n1().info("Cause value: %s", cause.c_str());
    }
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
  }

  curl_global_cleanup();

  if (body_data) {
    free(body_data);
    body_data = NULL;
  }
  fflush(stdout);
}

Keliang's avatar
Keliang committed
1946
bool amf_n1::authentication_vectors_from_ausf(
Niuhaiwen's avatar
Niuhaiwen committed
1947
    std::shared_ptr<nas_context> &nc) {
Keliang's avatar
Keliang committed
1948 1949
  Logger::amf_n1().debug("authentication_vectors_from_ausf");
  std::string ausf_ip =
Niuhaiwen's avatar
Niuhaiwen committed
1950
      std::string(inet_ntoa(*((struct in_addr *)&amf_cfg.nausf.addr4)));
Keliang's avatar
Keliang committed
1951 1952 1953 1954 1955 1956 1957 1958 1959 1960
  std::string ausf_port = std::to_string(amf_cfg.nausf.port);
  std::string remoteUri =
      ausf_ip + ":" + ausf_port + "/nausf-auth/v1/ue-authentications";
  std::string msgBody;
  std::string Response;

  nlohmann::json authenticationinfo_j;
  AuthenticationInfo authenticationinfo;
  authenticationinfo.setSupiOrSuci(nc.get()->imsi);
  authenticationinfo.setServingNetworkName(nc.get()->serving_network);
Niuhaiwen's avatar
Niuhaiwen committed
1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007
  ResynchronizationInfo resynchronizationInfo;
  uint8_t auts_len = blength(nc.get()->auts);
  uint8_t *auts_value = (uint8_t *)bdata(nc.get()->auts);
  std::string authenticationinfo_auts;
  std::string authenticationinfo_rand;
  if (auts_value) {
    Logger::amf_n1().debug("********* has auts *********");
    char *auts_s = (char *)malloc(auts_len * 2 + 1);
    // char *rand_s = (char *)malloc(RAND_LENGTH * 2 + 1);
    memset(auts_s, 0, sizeof(auts_s));
    // memset(rand_s, 0, sizeof(rand_s));
    // uint8_t rand_value[RAND_LENGTH];

    Logger::amf_n1().debug("********* auts_len (%d) *********", auts_len);
    for (int i = 0; i < auts_len; i++) {
      sprintf(&auts_s[i * 2], "%02X", auts_value[i]);
    }

    authenticationinfo_auts = auts_s;
    print_buffer("amf_n1", "********** ausf ***********", auts_value, auts_len);
    Logger::amf_n1().info("********** ausf_s (%s) ***********", auts_s);
    // generate_random(rand_value, RAND_LENGTH);
    std::map<std::string, std::string>::iterator iter;
    iter = rand_record.find(nc.get()->imsi);
    if (iter != rand_record.end()) {
      authenticationinfo_rand = iter->second;
      Logger::amf_n1().info("********** rand_s (%s) ***********",
                            authenticationinfo_rand.c_str());
    } else {
      Logger::amf_n1().error("********** There's no last rand ***********");
    }
    //    rand_value = nc.get()->_5g_av[0].rand;
    //    for(int i=0;i<RAND_LENGTH;i++)
    //    {
    //    sprintf(&rand_s[i*2],"%02X",rand_value[i]);
    //    }
    //    authenticationinfo_rand = rand_s;
    //    print_buffer("amf_n1", "********** rand  ***********", rand_value,
    //    RAND_LENGTH);

    resynchronizationInfo.setAuts(authenticationinfo_auts);
    resynchronizationInfo.setRand(authenticationinfo_rand);
    authenticationinfo.setResynchronizationInfo(resynchronizationInfo);
    free_wrapper((void **)&auts_s);
    //    free_wrapper((void**) &rand_s);
  }

Keliang's avatar
Keliang committed
2008 2009 2010 2011 2012 2013 2014 2015 2016 2017
  to_json(authenticationinfo_j, authenticationinfo);
  msgBody = authenticationinfo_j.dump();
  curl_http_client(remoteUri, "POST", msgBody, Response);

  Logger::amf_n1().info("POST response : %s", Response.c_str());

  try {
    UEAuthenticationCtx ueauthenticationctx;
    nlohmann::json::parse(Response.c_str()).get_to(ueauthenticationctx);

Niuhaiwen's avatar
Niuhaiwen committed
2018
    unsigned char *r5gauthdata_rand =
Keliang's avatar
Keliang committed
2019 2020
        format_string_as_hex(ueauthenticationctx.getR5gAuthData().getRand());
    memcpy(nc.get()->_5g_av[0].rand, r5gauthdata_rand, 16);
Niuhaiwen's avatar
Niuhaiwen committed
2021 2022
    rand_record[nc.get()->imsi] =
        ueauthenticationctx.getR5gAuthData().getRand();
Keliang's avatar
Keliang committed
2023
    print_buffer("amf_n1", "5G AV: rand", nc.get()->_5g_av[0].rand, 16);
Niuhaiwen's avatar
Niuhaiwen committed
2024
    free_wrapper((void **)&r5gauthdata_rand);
Keliang's avatar
Keliang committed
2025

Niuhaiwen's avatar
Niuhaiwen committed
2026
    unsigned char *r5gauthdata_autn =
Keliang's avatar
Keliang committed
2027 2028 2029
        format_string_as_hex(ueauthenticationctx.getR5gAuthData().getAutn());
    memcpy(nc.get()->_5g_av[0].autn, r5gauthdata_autn, 16);
    print_buffer("amf_n1", "5G AV: autn", nc.get()->_5g_av[0].autn, 16);
Niuhaiwen's avatar
Niuhaiwen committed
2030
    free_wrapper((void **)&r5gauthdata_autn);
Keliang's avatar
Keliang committed
2031

Niuhaiwen's avatar
Niuhaiwen committed
2032
    unsigned char *r5gauthdata_hxresstar = format_string_as_hex(
Keliang's avatar
Keliang committed
2033 2034 2035
        ueauthenticationctx.getR5gAuthData().getHxresStar());
    memcpy(nc.get()->_5g_av[0].hxresStar, r5gauthdata_hxresstar, 16);
    print_buffer("amf_n1", "5G AV: hxres*", nc.get()->_5g_av[0].hxresStar, 16);
Niuhaiwen's avatar
Niuhaiwen committed
2036
    free_wrapper((void **)&r5gauthdata_hxresstar);
Keliang's avatar
Keliang committed
2037 2038 2039 2040 2041 2042 2043 2044

    std::map<std::string, LinksValueSchema>::iterator iter;
    iter = ueauthenticationctx.getLinks().find("5G_AKA");
    if (iter != ueauthenticationctx.getLinks().end()) {
      nc.get()->Href = iter->second.getHref();
      Logger::amf_n1().info("Links is: ", nc.get()->Href);
    } else {
      Logger::amf_n1().error("Not found 5G_AKA");
yangjian's avatar
yangjian committed
2045
    }
Niuhaiwen's avatar
Niuhaiwen committed
2046
  } catch (nlohmann::json::exception &e) {
Keliang's avatar
Keliang committed
2047 2048 2049 2050 2051
    Logger::amf_n1().info("Could not get Json content from AUSF response");
    // TODO: error handling
    return false;
  }
  return true;
yangjian's avatar
yangjian committed
2052 2053
}

Niuhaiwen's avatar
Niuhaiwen committed
2054 2055
bool amf_n1::_5g_aka_confirmation_from_ausf(std::shared_ptr<nas_context> &nc,
                                            bstring resStar) {
Keliang's avatar
Keliang committed
2056 2057 2058 2059 2060 2061 2062
  Logger::amf_n1().debug("_5g_aka_confirmation_from_ausf");
  std::string remoteUri = nc.get()->Href;

  std::string msgBody;
  std::string Response;
  std::string resStar_string;

Niuhaiwen's avatar
Niuhaiwen committed
2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077
  std::map<std::string, std::string>::iterator iter;
  iter = rand_record.find(nc.get()->imsi);
  rand_record.erase(iter);
  // convert_string_2_hex(resStar, resStar_string);
  uint8_t resStar_len = blength(resStar);
  uint8_t *resStar_value = (uint8_t *)bdata(resStar);
  char *resStar_s = (char *)malloc(resStar_len * 2 + 1);

  for (int i = 0; i < resStar_len; i++) {
    sprintf(&resStar_s[i * 2], "%02X", resStar_value[i]);
  }
  resStar_string = resStar_s;
  print_buffer("amf_n1", "********** resStar  ***********", resStar_value,
               resStar_len);
  Logger::amf_n1().info("********** resStar_s (%s) ***********", resStar_s);
Keliang's avatar
Keliang committed
2078 2079 2080 2081 2082 2083 2084 2085

  nlohmann::json confirmationdata_j;
  ConfirmationData confirmationdata;
  confirmationdata.setResStar(resStar_string);

  to_json(confirmationdata_j, confirmationdata);
  msgBody = confirmationdata_j.dump();
  curl_http_client(remoteUri, "PUT", msgBody, Response);
Niuhaiwen's avatar
Niuhaiwen committed
2086
  free_wrapper((void **)&resStar_s);
Keliang's avatar
Keliang committed
2087
  // free(resStar_string.c_str());
Niuhaiwen's avatar
Niuhaiwen committed
2088 2089
  Logger::amf_n1().info("Get Json content from AUSF response: %s",
                        Response.c_str());
Keliang's avatar
Keliang committed
2090 2091 2092 2093

  try {
    ConfirmationDataResponse confirmationdataresponse;
    nlohmann::json::parse(Response.c_str()).get_to(confirmationdataresponse);
Niuhaiwen's avatar
Niuhaiwen committed
2094
    unsigned char *kseaf_hex =
Keliang's avatar
Keliang committed
2095 2096 2097
        format_string_as_hex(confirmationdataresponse.getKseaf());
    memcpy(nc.get()->_5g_av[0].kseaf, kseaf_hex, 32);
    print_buffer("amf_n1", "5G AV: kseaf", nc.get()->_5g_av[0].kseaf, 32);
Niuhaiwen's avatar
Niuhaiwen committed
2098
    free_wrapper((void **)&kseaf_hex);
Keliang's avatar
Keliang committed
2099 2100 2101 2102 2103

    Logger::amf_n1().debug("Deriving kamf");
    for (int i = 0; i < MAX_5GS_AUTH_VECTORS; i++) {
      Authentication_5gaka::derive_kamf(
          nc.get()->imsi, nc.get()->_5g_av[i].kseaf, nc.get()->kamf[i],
Niuhaiwen's avatar
Niuhaiwen committed
2104
          0x0000); // second parameter: abba
Keliang's avatar
Keliang committed
2105
      print_buffer("amf_n1", "kamf", nc.get()->kamf[i], 32);
yangjian's avatar
yangjian committed
2106
    }
Niuhaiwen's avatar
Niuhaiwen committed
2107
  } catch (nlohmann::json::exception &e) {
Keliang's avatar
Keliang committed
2108 2109 2110 2111 2112
    Logger::amf_n1().info("Could not get Json content from AUSF response");
    // TODO: error handling
    return false;
  }
  return true;
yangjian's avatar
yangjian committed
2113 2114
}

2115
//------------------------------------------------------------------------------
2116
bool amf_n1::authentication_vectors_generator_in_ausf(
Niuhaiwen's avatar
Niuhaiwen committed
2117
    std::shared_ptr<nas_context> &nc) { // A.5, 3gpp ts33.501
2118
  Logger::amf_n1().debug("Authentication_vectors_generator_in_ausf");
dukl's avatar
dukl committed
2119
  uint8_t inputString[MAX_5GS_AUTH_VECTORS][40];
Niuhaiwen's avatar
Niuhaiwen committed
2120 2121
  uint8_t *xresStar[MAX_5GS_AUTH_VECTORS];
  uint8_t *rand[MAX_5GS_AUTH_VECTORS];
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2122
  for (int i = 0; i < MAX_5GS_AUTH_VECTORS; i++) {
dukl's avatar
dukl committed
2123
    xresStar[i] = nc.get()->_5g_he_av[i].xresStar;
Niuhaiwen's avatar
Niuhaiwen committed
2124
    rand[i] = nc.get()->_5g_he_av[i].rand;
dukl's avatar
dukl committed
2125
    memcpy(&inputString[i][0], rand[i], 16);
dukl's avatar
dukl committed
2126 2127
    memcpy(&inputString[i][16], xresStar[i], 16);
    unsigned char sha256Out[Sha256::DIGEST_SIZE];
Niuhaiwen's avatar
Niuhaiwen committed
2128
    sha256((unsigned char *)inputString[i], 32, sha256Out);
2129
    for (int j = 0; j < 16; j++)
Niuhaiwen's avatar
Niuhaiwen committed
2130
      nc.get()->_5g_av[i].hxresStar[j] = (uint8_t)sha256Out[j];
dukl's avatar
dukl committed
2131 2132 2133
    memcpy(nc.get()->_5g_av[i].rand, nc.get()->_5g_he_av[i].rand, 16);
    memcpy(nc.get()->_5g_av[i].autn, nc.get()->_5g_he_av[i].autn, 16);
    uint8_t kseaf[32];
Niuhaiwen's avatar
Niuhaiwen committed
2134 2135
    Authentication_5gaka::derive_kseaf(nc.get()->serving_network,
                                       nc.get()->_5g_he_av[i].kausf, kseaf);
dukl's avatar
dukl committed
2136
    memcpy(nc.get()->_5g_av[i].kseaf, kseaf, 32);
Niuhaiwen's avatar
Niuhaiwen committed
2137 2138 2139 2140 2141
    // 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);
dukl's avatar
dukl committed
2142 2143 2144
  }
  return true;
}
2145 2146

//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
2147
// TODO: Get from UDM
2148
bool amf_n1::authentication_vectors_generator_in_udm(
Niuhaiwen's avatar
Niuhaiwen committed
2149
    std::shared_ptr<nas_context> &nc) {
2150
  Logger::amf_n1().debug("Generate authentication vectors");
Niuhaiwen's avatar
Niuhaiwen committed
2151 2152 2153
  uint8_t *sqn = NULL;
  uint8_t *auts = (uint8_t *)bdata(nc.get()->auts);
  _5G_HE_AV_t *vector = nc.get()->_5g_he_av;
Niuhaiwen's avatar
Niuhaiwen committed
2154
  // Access to MySQL to fetch UE-related information
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2155
  if (!connect_to_mysql()) {
2156
    Logger::amf_n1().error("Cannot connect to MySQL");
dukl's avatar
dukl committed
2157 2158
    return false;
  }
2159 2160
  Logger::amf_n1().debug("Connected to MySQL successfully");
  mysql_auth_info_t mysql_resp = {};
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2161 2162
  if (get_mysql_auth_info(nc.get()->imsi, mysql_resp)) {
    if (auts) {
Niuhaiwen's avatar
Niuhaiwen committed
2163 2164
      sqn = Authentication_5gaka::sqn_ms_derive(mysql_resp.opc, mysql_resp.key,
                                                auts, mysql_resp.rand);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2165
      if (sqn) {
2166 2167 2168
        generate_random(vector[0].rand, RAND_LENGTH);
        mysql_push_rand_sqn(nc.get()->imsi, vector[0].rand, sqn);
        mysql_increment_sqn(nc.get()->imsi);
Niuhaiwen's avatar
Niuhaiwen committed
2169
        free_wrapper((void **)&sqn);
dukl's avatar
dukl committed
2170
      }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2171
      if (!get_mysql_auth_info(nc.get()->imsi, mysql_resp)) {
2172
        Logger::amf_n1().error("Cannot get data from MySQL");
dukl's avatar
dukl committed
2173 2174 2175
        return false;
      }
      sqn = mysql_resp.sqn;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2176
      for (int i = 0; i < MAX_5GS_AUTH_VECTORS; i++) {
dukl's avatar
dukl committed
2177
        generate_random(vector[i].rand, RAND_LENGTH);
Niuhaiwen's avatar
Niuhaiwen committed
2178 2179 2180 2181 2182
        print_buffer("amf_n1", "Generated random rand (5G HE AV)",
                     vector[i].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
dukl's avatar
dukl committed
2183
      }
Niuhaiwen's avatar
Niuhaiwen committed
2184 2185
      mysql_push_rand_sqn(nc.get()->imsi, vector[MAX_5GS_AUTH_VECTORS - 1].rand,
                          sqn);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2186
    } else {
2187
      Logger::amf_n1().debug("No auts ...");
Niuhaiwen's avatar
Niuhaiwen committed
2188 2189
      Logger::amf_n1().debug("Receive information from MySQL with IMSI %s",
                             nc.get()->imsi.c_str());
Niuhaiwen's avatar
Niuhaiwen committed
2190 2191 2192 2193 2194
      // 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);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2195
      for (int i = 0; i < MAX_5GS_AUTH_VECTORS; i++) {
2196
        generate_random(vector[i].rand, RAND_LENGTH);
Niuhaiwen's avatar
Niuhaiwen committed
2197 2198
        // print_buffer("amf_n1", "generated random: rand(5G HE AV)",
        // vector[i].rand, 16);
dukl's avatar
dukl committed
2199
        sqn = mysql_resp.sqn;
Niuhaiwen's avatar
Niuhaiwen committed
2200 2201 2202
        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
dukl's avatar
dukl committed
2203
      }
Niuhaiwen's avatar
Niuhaiwen committed
2204 2205
      mysql_push_rand_sqn(nc.get()->imsi, vector[MAX_5GS_AUTH_VECTORS - 1].rand,
                          sqn);
dukl's avatar
dukl committed
2206
    }
2207
    mysql_increment_sqn(nc.get()->imsi);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2208
  } else {
2209
    Logger::amf_n1().error("Failed to fetch user data from MySQL");
dukl's avatar
dukl committed
2210 2211 2212 2213
    return false;
  }
}

2214
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
2215 2216 2217 2218
void amf_n1::test_generate_5g_he_av_in_udm(const uint8_t opc[16],
                                           uint8_t key[16], uint8_t sqnak[6],
                                           std::string serving_network,
                                           _5G_HE_AV_t &vector) {
2219 2220 2221 2222 2223
  uint8_t amf[] = {0x90, 0x01};
  uint8_t mac_a[8];
  uint8_t ck[16];
  uint8_t ik[16];
  uint8_t ak[6];
Niuhaiwen's avatar
Niuhaiwen committed
2224 2225
  Authentication_5gaka::f2345(opc, key, vector.rand, vector.xres, ck, ik,
                              ak); // to compute XRES, CK, IK, AK
dukl's avatar
dukl committed
2226
  uint8_t sqn[6];
Niuhaiwen's avatar
Niuhaiwen committed
2227 2228 2229 2230
  for (int i = 0; i < 6; i++)
    sqn[i] = sqnak[i] ^ ak[i];
  Authentication_5gaka::f1(opc, key, vector.rand, sqn, amf,
                           mac_a); // to compute MAC, Figure 7, ts33.102
dukl's avatar
dukl committed
2231 2232 2233
  print_buffer("amf_n1", "sqn^ak", sqnak, 6);
  print_buffer("amf_n1", "rand", vector.rand, 16);
  print_buffer("amf_n1", "mac_a", mac_a, 8);
Niuhaiwen's avatar
Niuhaiwen committed
2234 2235 2236 2237 2238 2239
  annex_a_4_33501(ck, ik, vector.xres, vector.rand, serving_network,
                  vector.xresStar);
  Authentication_5gaka::generate_autn(sqn, ak, amf, mac_a,
                                      vector.autn); // generate AUTN
  Authentication_5gaka::derive_kausf(ck, ik, serving_network, sqn, ak,
                                     vector.kausf); // derive Kausf
dukl's avatar
dukl committed
2240 2241
}

2242
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
2243
void amf_n1::generate_random(uint8_t *random_p, ssize_t length) {
dukl's avatar
dukl committed
2244 2245
  gmp_randinit_default(random_state.state);
  gmp_randseed_ui(random_state.state, time(NULL));
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2246
  if (!amf_cfg.auth_para.random.compare("true")) {
2247
    Logger::amf_n1().debug("AMF config random -> true");
dukl's avatar
dukl committed
2248
    random_t random_nb;
dukl's avatar
dukl committed
2249
    mpz_init(random_nb);
dukl's avatar
dukl committed
2250 2251 2252 2253 2254
    mpz_init_set_ui(random_nb, 0);
    pthread_mutex_lock(&random_state.lock);
    mpz_urandomb(random_nb, random_state.state, 8 * length);
    pthread_mutex_unlock(&random_state.lock);
    mpz_export(random_p, NULL, 1, length, 0, 0, random_nb);
2255
    int r = 0, mask = 0, shift;
dukl's avatar
dukl committed
2256
    for (int i = 0; i < length; i++) {
Niuhaiwen's avatar
Niuhaiwen committed
2257 2258 2259 2260
      if ((i % sizeof(i)) == 0)
        r = rand();
      shift = 8 * (i % sizeof(i));
      mask = 0xFF << shift;
dukl's avatar
dukl committed
2261 2262
      random_p[i] = (r & mask) >> shift;
    }
Niuhaiwen's avatar
Niuhaiwen committed
2263 2264 2265
    Logger::amf_n1().debug(
        "*************** generate rand function %x ***************", r);

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2266
  } else {
2267
    Logger::amf_n1().error("AMF config random -> false");
dukl's avatar
dukl committed
2268 2269 2270 2271 2272 2273 2274 2275
    pthread_mutex_lock(&random_state.lock);
    for (int i = 0; i < length; i++) {
      random_p[i] = i + no_random_delta;
    }
    no_random_delta += 1;
    pthread_mutex_unlock(&random_state.lock);
  }
}
2276 2277

//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
2278
// TODO: read from UDM
Niuhaiwen's avatar
Niuhaiwen committed
2279 2280 2281 2282
void amf_n1::generate_5g_he_av_in_udm(const uint8_t opc[16], string imsi,
                                      uint8_t key[16], uint8_t sqn[6],
                                      std::string serving_network,
                                      _5G_HE_AV_t &vector) {
2283 2284 2285 2286 2287 2288 2289 2290
  Logger::amf_n1().debug("Generate 5g_he_av as in UDM");
  uint8_t amf[] = {0x90, 0x01};
  uint8_t mac_a[8];
  uint8_t ck[16];
  uint8_t ik[16];
  uint8_t ak[6];
  uint64_t _imsi = fromString<uint64_t>(imsi);

Niuhaiwen's avatar
Niuhaiwen committed
2291 2292
  Authentication_5gaka::f1(opc, key, vector.rand, sqn, amf,
                           mac_a); // to compute MAC, Figure 7, ts33.102
Niuhaiwen's avatar
Niuhaiwen committed
2293
  // print_buffer("amf_n1", "Result For F1-Alg: mac_a", mac_a, 8);
Niuhaiwen's avatar
Niuhaiwen committed
2294 2295 2296 2297
  Authentication_5gaka::f2345(opc, key, vector.rand, vector.xres, ck, ik,
                              ak); // to compute XRES, CK, IK, AK
  annex_a_4_33501(ck, ik, vector.xres, vector.rand, serving_network,
                  vector.xresStar);
Niuhaiwen's avatar
Niuhaiwen committed
2298 2299
  // print_buffer("amf_n1", "Result For KDF: xres*(5G HE AV)", vector.xresStar,
  // 16);
Niuhaiwen's avatar
Niuhaiwen committed
2300 2301
  Authentication_5gaka::generate_autn(sqn, ak, amf, mac_a,
                                      vector.autn); // generate AUTN
Niuhaiwen's avatar
Niuhaiwen committed
2302
  // print_buffer("amf_n1", "Generated autn(5G HE AV)", vector.autn, 16);
Niuhaiwen's avatar
Niuhaiwen committed
2303 2304
  Authentication_5gaka::derive_kausf(ck, ik, serving_network, sqn, ak,
                                     vector.kausf); // derive Kausf
Niuhaiwen's avatar
Niuhaiwen committed
2305 2306
  // print_buffer("amf_n1", "Result For KDF: Kausf(5G HE AV)", vector.kausf,
  // 32);
2307
  Logger::amf_n1().debug("Generate_5g_he_av_in_udm finished!");
Niuhaiwen's avatar
Niuhaiwen committed
2308
  // ue_authentication_simulator(vector.rand, vector.autn);
dukl's avatar
dukl committed
2309 2310 2311
  return;
}

2312
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
2313 2314 2315
void amf_n1::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) {
dukl's avatar
dukl committed
2316
  OCTET_STRING_t netName;
Niuhaiwen's avatar
Niuhaiwen committed
2317 2318
  OCTET_STRING_fromBuf(&netName, serving_network.c_str(),
                       serving_network.length());
dukl's avatar
dukl committed
2319 2320
  uint8_t S[100];
  S[0] = 0x6B;
2321 2322 2323
  memcpy(&S[1], netName.buf, netName.size);
  S[1 + netName.size] = (netName.size & 0xff00) >> 8;
  S[2 + netName.size] = (netName.size & 0x00ff);
Niuhaiwen's avatar
Niuhaiwen committed
2324 2325
  for (int i = 0; i < 16; i++)
    S[3 + netName.size + i] = rand[i];
2326 2327
  S[19 + netName.size] = 0x00;
  S[20 + netName.size] = 0x10;
Niuhaiwen's avatar
Niuhaiwen committed
2328 2329
  for (int i = 0; i < 8; i++)
    S[21 + netName.size + i] = input[i];
2330 2331
  S[29 + netName.size] = 0x00;
  S[30 + netName.size] = 0x08;
dukl's avatar
dukl committed
2332 2333

  uint8_t plmn[3] = {0x46, 0x0f, 0x11};
dukl's avatar
dukl committed
2334 2335 2336 2337 2338
  uint8_t oldS[100];
  oldS[0] = 0x6B;
  memcpy(&oldS[1], plmn, 3);
  oldS[4] = 0x00;
  oldS[5] = 0x03;
Niuhaiwen's avatar
Niuhaiwen committed
2339 2340
  for (int i = 0; i < 16; i++)
    oldS[6 + i] = rand[i];
dukl's avatar
dukl committed
2341 2342
  oldS[22] = 0x00;
  oldS[23] = 0x10;
Niuhaiwen's avatar
Niuhaiwen committed
2343 2344
  for (int i = 0; i < 8; i++)
    oldS[24 + i] = input[i];
dukl's avatar
dukl committed
2345 2346
  oldS[32] = 0x00;
  oldS[33] = 0x08;
2347
  print_buffer("amf_n1", "Input string: ", S, 31 + netName.size);
dukl's avatar
dukl committed
2348
  uint8_t key[32];
2349
  memcpy(&key[0], ck, 16);
Niuhaiwen's avatar
Niuhaiwen committed
2350
  memcpy(&key[16], ik, 16); // KEY
Niuhaiwen's avatar
Niuhaiwen committed
2351
  // Authentication_5gaka::kdf(key, 32, oldS, 33, output, 16);
dukl's avatar
dukl committed
2352
  uint8_t out[32];
2353
  Authentication_5gaka::kdf(key, 32, S, 31 + netName.size, out, 32);
Niuhaiwen's avatar
Niuhaiwen committed
2354 2355
  for (int i = 0; i < 16; i++)
    output[i] = out[16 + i];
dukl's avatar
dukl committed
2356 2357 2358
  print_buffer("amf_n1", "XRES*(new)", out, 32);
}

2359
//------------------------------------------------------------------------------
2360 2361 2362 2363
void amf_n1::handle_auth_vector_successful_result(
    std::shared_ptr<nas_context> nc) {
  Logger::amf_n1().debug(
      "Received security vectors, try to setup security with the UE");
2364
  nc.get()->is_auth_vectors_present = true;
Niuhaiwen's avatar
Niuhaiwen committed
2365
  ngksi_t ngksi = 0;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2366
  if (!nc.get()->security_ctx) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2367
    nc.get()->security_ctx = new nas_secu_ctx();
Niuhaiwen's avatar
Niuhaiwen committed
2368 2369
    if (nc.get()->security_ctx &&
        nc.get()->ngKsi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE)
2370
      ngksi = (nc.get()->amf_ue_ngap_id + 1) % (NGKSI_MAX_VALUE + 1);
2371
    // ensure which vector is available?
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2372 2373
    nc.get()->ngKsi = ngksi;
  }
dukl's avatar
dukl committed
2374
  int vindex = nc.get()->security_ctx->vector_pointer;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2375
  if (!start_authentication_procedure(nc, vindex, nc.get()->ngKsi)) {
2376 2377
    Logger::amf_n1().error("Start authentication procedure failure, reject...");
    Logger::amf_n1().error("Ran_ue_ngap_id 0x%x", nc.get()->ran_ue_ngap_id);
Niuhaiwen's avatar
Niuhaiwen committed
2378 2379 2380
    response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
                                     nc.get()->ran_ue_ngap_id,
                                     nc.get()->amf_ue_ngap_id); // cause?
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2381
  } else {
Niuhaiwen's avatar
Niuhaiwen committed
2382
    // update mm state -> COMMON-PROCEDURE-INITIATED
dukl's avatar
dukl committed
2383 2384 2385
  }
}

2386
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
2387 2388
bool amf_n1::start_authentication_procedure(std::shared_ptr<nas_context> nc,
                                            int vindex, uint8_t ngksi) {
2389
  Logger::amf_n1().debug("****Starting authentication procedure****");
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2390
  if (check_nas_common_procedure_on_going(nc)) {
2391
    Logger::amf_n1().error("Existed NAS common procedure on going, reject...");
Niuhaiwen's avatar
Niuhaiwen committed
2392 2393 2394
    response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
                                     nc.get()->ran_ue_ngap_id,
                                     nc.get()->amf_ue_ngap_id); // cause?
dukl's avatar
dukl committed
2395 2396
    return false;
  }
2397

dukl's avatar
dukl committed
2398
  nc.get()->is_common_procedure_for_authentication_running = true;
Niuhaiwen's avatar
Niuhaiwen committed
2399
  AuthenticationRequest *authReq = new AuthenticationRequest();
dukl's avatar
dukl committed
2400 2401 2402 2403 2404 2405
  authReq->setHeader(PLAIN_5GS_MSG);
  authReq->setngKSI(NAS_KEY_SET_IDENTIFIER_NATIVE, ngksi);
  uint8_t abba[2];
  abba[0] = 0x00;
  abba[1] = 0x00;
  authReq->setABBA(2, abba);
Niuhaiwen's avatar
Niuhaiwen committed
2406 2407 2408
  uint8_t *rand = nc.get()->_5g_av[vindex].rand;
  if (rand)
    authReq->setAuthentication_Parameter_RAND(rand);
2409 2410
  Logger::amf_n1().debug("Sending Authentication request with rand");
  printf("0x");
Niuhaiwen's avatar
Niuhaiwen committed
2411 2412
  for (int i = 0; i < 16; i++)
    printf("%x", rand[i]);
dukl's avatar
dukl committed
2413
  printf("\n");
2414

Niuhaiwen's avatar
Niuhaiwen committed
2415 2416 2417
  uint8_t *autn = nc.get()->_5g_av[vindex].autn;
  if (autn)
    authReq->setAuthentication_Parameter_AUTN(autn);
dukl's avatar
dukl committed
2418
  uint8_t buffer[1024] = {0};
Niuhaiwen's avatar
Niuhaiwen committed
2419
  int encoded_size = authReq->encode2buffer(buffer, 1024);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2420
  if (!encoded_size) {
2421
    Logger::nas_mm().error("Encode Authentication Request message error");
dukl's avatar
dukl committed
2422
    return false;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2423
  } else {
dukl's avatar
dukl committed
2424 2425 2426
    delete authReq;
  }
  bstring b = blk2bstr(buffer, encoded_size);
Niuhaiwen's avatar
Niuhaiwen committed
2427 2428
  print_buffer("amf_n1", "Authentication-Request message buffer",
               (uint8_t *)bdata(b), blength(b));
2429
  Logger::amf_n1().debug("amf_ue_ngap_id 0x%x", nc.get()->amf_ue_ngap_id);
2430 2431
  
  std::string udsf_url = "http://10.112.202.24:7123/nudsf-dr/v1/amfdata/" + std::string("ue_nas_context/records/") + to_string(nc.get()->amf_ue_ngap_id) ;
2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443
  nlohmann::json udsf_ue_nas_context;
  udsf_ue_nas_context["meta"] ["tags"] = {
                                      {"RECORD_ID",nlohmann::json::array({to_string(nc.get()->amf_ue_ngap_id)})},
                                      {"from_nf",nlohmann::json::array({"AMF_1234"})}
                                      } ;
  // udsf_ue_nas_context["blocks"] =; 
  //_5g_av.rand
  //nc.get()->_5g_av[0].autn
 // nc.get()->_5g_av[0].hxresStar
  // nc.get()->Href
  std::string json_part = udsf_ue_nas_context.dump();
  //amf_n2_inst->curl_http_client_udsf(udsf_url,json_part,"PUT");
2444 2445


Niuhaiwen's avatar
Niuhaiwen committed
2446 2447
  itti_send_dl_nas_buffer_to_task_n2(b, nc.get()->ran_ue_ngap_id,
                                     nc.get()->amf_ue_ngap_id);
dukl's avatar
dukl committed
2448 2449 2450
  return true;
}

2451
//------------------------------------------------------------------------------
2452 2453
bool amf_n1::check_nas_common_procedure_on_going(
    std::shared_ptr<nas_context> nc) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2454
  if (nc.get()->is_common_procedure_for_authentication_running) {
2455
    Logger::amf_n1().debug("Existed authentication procedure is running");
dukl's avatar
dukl committed
2456 2457
    return true;
  }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2458
  if (nc.get()->is_common_procedure_for_identification_running) {
2459
    Logger::amf_n1().debug("Existed identification procedure is running");
dukl's avatar
dukl committed
2460 2461
    return true;
  }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2462
  if (nc.get()->is_common_procedure_for_security_mode_control_running) {
2463
    Logger::amf_n1().debug("Existed SMC procedure is running");
dukl's avatar
dukl committed
2464 2465
    return true;
  }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2466
  if (nc.get()->is_common_procedure_for_nas_transport_running) {
2467
    Logger::amf_n1().debug("Existed NAS transport procedure is running");
dukl's avatar
dukl committed
2468 2469 2470 2471 2472
    return true;
  }
  return false;
}

2473
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
2474 2475 2476
void amf_n1::authentication_response_handle(uint32_t ran_ue_ngap_id,
                                            long amf_ue_ngap_id,
                                            bstring plain_msg) {
dukl's avatar
dukl committed
2477
  std::shared_ptr<nas_context> nc;
2478

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2479
  if (!is_amf_ue_id_2_nas_context(amf_ue_ngap_id)) {
2480 2481 2482
    Logger::amf_n1().error(
        "No existed NAS context for UE with amf_ue_ngap_id (0x%x)",
        amf_ue_ngap_id);
Niuhaiwen's avatar
Niuhaiwen committed
2483 2484
    response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
                                     amf_ue_ngap_id); // cause?
dukl's avatar
dukl committed
2485 2486 2487
    return;
  }
  nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
Niuhaiwen's avatar
Niuhaiwen committed
2488 2489
  Logger::amf_n1().info("Found nas_context(%p) with amf_ue_ngap_id (0x%x)",
                        nc.get(), amf_ue_ngap_id);
Niuhaiwen's avatar
Niuhaiwen committed
2490
  // Stop timer? common procedure finished!
dukl's avatar
dukl committed
2491 2492
  nc.get()->is_common_procedure_for_authentication_running = false;
  // MM state: COMMON-PROCEDURE-INITIATED -> DEREGISTRED
Niuhaiwen's avatar
Niuhaiwen committed
2493
  // Decode AUTHENTICATION RESPONSE message
Niuhaiwen's avatar
Niuhaiwen committed
2494 2495 2496
  AuthenticationResponse *auth = new AuthenticationResponse();
  auth->decodefrombuffer(nullptr, (uint8_t *)bdata(plain_msg),
                         blength(plain_msg));
2497 2498
  bstring resStar;
  bool isAuthOk = true;
Keliang's avatar
Keliang committed
2499
  // Get response RES*
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2500
  if (!auth->getAuthenticationResponseParameter(resStar)) {
2501 2502
    Logger::amf_n1().warn(
        "Cannot receive AuthenticationResponseParameter (RES*)");
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2503
  } else {
Keliang's avatar
Keliang committed
2504
    if (amf_cfg.is_Nausf) {
Niuhaiwen's avatar
Niuhaiwen committed
2505 2506 2507
      // std::string data = bdata(resStar);
      if (!_5g_aka_confirmation_from_ausf(nc, resStar))
        isAuthOk = false;
Keliang's avatar
Keliang committed
2508 2509
    } else {
      // Get stored XRES*
Niuhaiwen's avatar
Niuhaiwen committed
2510 2511
      int secu_index = nc.get()->security_ctx->vector_pointer;
      uint8_t *hxresStar = nc.get()->_5g_av[secu_index].hxresStar;
Keliang's avatar
Keliang committed
2512 2513 2514
      // Calculate HRES* from received RES*, then compare with XRES stored in
      // nas_context
      uint8_t inputstring[32];
Niuhaiwen's avatar
Niuhaiwen committed
2515
      uint8_t *res = (uint8_t *)bdata(resStar);
Keliang's avatar
Keliang committed
2516 2517 2518 2519
      Logger::amf_n1().debug("Start to calculate HRES* from received RES*");
      memcpy(&inputstring[0], nc.get()->_5g_av[secu_index].rand, 16);
      memcpy(&inputstring[16], res, blength(resStar));
      unsigned char sha256Out[Sha256::DIGEST_SIZE];
Niuhaiwen's avatar
Niuhaiwen committed
2520
      sha256((unsigned char *)inputstring, 16 + blength(resStar), sha256Out);
Keliang's avatar
Keliang committed
2521
      uint8_t hres[16];
Niuhaiwen's avatar
Niuhaiwen committed
2522 2523 2524 2525 2526 2527 2528 2529
      for (int i = 0; i < 16; i++)
        hres[i] = (uint8_t)sha256Out[i];
      print_buffer("amf_n1", "Received RES* From Authentication-Response", res,
                   16);
      print_buffer("amf_n1", "Stored XRES* in 5G HE AV",
                   nc.get()->_5g_he_av[secu_index].xresStar, 16);
      print_buffer("amf_n1", "Stored XRES in 5G HE AV",
                   nc.get()->_5g_he_av[secu_index].xres, 8);
Keliang's avatar
Keliang committed
2530 2531 2532
      print_buffer("amf_n1", "Computed HRES* from RES*", hres, 16);
      print_buffer("amf_n1", "Computed HXRES* from XRES*", hxresStar, 16);
      for (int i = 0; i < 16; i++) {
Niuhaiwen's avatar
Niuhaiwen committed
2533 2534
        if (hxresStar[i] != hres[i])
          isAuthOk = false;
Keliang's avatar
Keliang committed
2535
      }
dukl's avatar
dukl committed
2536 2537
    }
  }
Niuhaiwen's avatar
Niuhaiwen committed
2538 2539
  // If success, start SMC procedure; else if failure, response registration
  // reject message with corresponding cause
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2540
  if (!isAuthOk) {
2541 2542 2543
    Logger::amf_n1().error(
        "Authentication failed for UE with amf_ue_ngap_id 0x%x",
        amf_ue_ngap_id);
Niuhaiwen's avatar
Niuhaiwen committed
2544 2545
    response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
                                     amf_ue_ngap_id); // cause?
dukl's avatar
dukl committed
2546
    return;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2547
  } else {
2548
    Logger::amf_n1().debug("Authentication successful by network!");
2549
    if (!nc.get()->is_current_security_available) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2550
      if (!start_security_mode_control_procedure(nc)) {
dukl's avatar
dukl committed
2551
        Logger::amf_n1().error("Start SMC procedure failure");
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2552
      } else {
2553
        // ...
dukl's avatar
dukl committed
2554 2555 2556 2557 2558
      }
    }
  }
}

2559
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
2560 2561 2562
void amf_n1::authentication_failure_handle(uint32_t ran_ue_ngap_id,
                                           long amf_ue_ngap_id,
                                           bstring plain_msg) {
dukl's avatar
dukl committed
2563
  std::shared_ptr<nas_context> nc;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2564
  if (!is_amf_ue_id_2_nas_context(amf_ue_ngap_id)) {
2565 2566 2567
    Logger::amf_n1().error(
        "No existed NAS context for UE with amf_ue_ngap_id(0x%x)",
        amf_ue_ngap_id);
Niuhaiwen's avatar
Niuhaiwen committed
2568 2569
    response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
                                     amf_ue_ngap_id); // cause?
dukl's avatar
dukl committed
2570 2571 2572 2573
    return;
  }
  nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
  nc.get()->is_common_procedure_for_authentication_running = false;
Niuhaiwen's avatar
Niuhaiwen committed
2574
  // 1. decode AUTHENTICATION FAILURE message
Niuhaiwen's avatar
Niuhaiwen committed
2575 2576 2577
  AuthenticationFailure *authFail = new AuthenticationFailure();
  authFail->decodefrombuffer(NULL, (uint8_t *)bdata(plain_msg),
                             blength(plain_msg));
dukl's avatar
dukl committed
2578
  uint8_t mm_cause = authFail->get5GMmCause();
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2579
  if (mm_cause == -1) {
2580
    Logger::amf_n1().error("Missing mandatory IE 5G_MM_CAUSE");
Niuhaiwen's avatar
Niuhaiwen committed
2581 2582 2583
    response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
                                     ran_ue_ngap_id,
                                     amf_ue_ngap_id); // cause?
dukl's avatar
dukl committed
2584 2585
    return;
  }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2586
  switch (mm_cause) {
Niuhaiwen's avatar
Niuhaiwen committed
2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608
  case _5GMM_CAUSE_SYNCH_FAILURE: {
    Logger::amf_n1().debug("Initial new authentication procedure");
    bstring auts;
    if (!authFail->getAutsInAuthFailPara(auts)) {
      Logger::amf_n1().warn(
          "IE Authentication Failure Parameter (auts) not received");
    }
    nc.get()->auts = auts;
    printf("Received auts: 0x ");
    for (int i = 0; i < blength(auts); i++)
      printf("%x ", ((uint8_t *)bdata(auts))[i]);
    printf("\n");
    if (auth_vectors_generator(nc)) { // all authentication in one(AMF)
      handle_auth_vector_successful_result(nc);
    } else {
      Logger::amf_n1().error("Request authentication vectors failure");
      response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE,
                                       nc.get()->ran_ue_ngap_id,
                                       nc.get()->amf_ue_ngap_id); // cause?
    }
    // authentication_failure_synch_failure_handle(nc, auts);
  } break;
2609
  }
dukl's avatar
dukl committed
2610 2611
}

2612
//------------------------------------------------------------------------------
2613 2614
bool amf_n1::start_security_mode_control_procedure(
    std::shared_ptr<nas_context> nc) {
dukl's avatar
dukl committed
2615 2616
  Logger::amf_n1().debug("Start Security Mode Control procedure");
  nc.get()->is_common_procedure_for_security_mode_control_running = true;
Niuhaiwen's avatar
Niuhaiwen committed
2617 2618 2619
  bool security_context_is_new = false;
  uint8_t amf_nea = EA0_5G;
  uint8_t amf_nia = IA0_5G;
Niuhaiwen's avatar
Niuhaiwen committed
2620
  // decide which ea/ia alg used by UE, which is supported by network
Niuhaiwen's avatar
Niuhaiwen committed
2621 2622
  security_data_t *data = (security_data_t *)calloc(1, sizeof(security_data_t));
  nas_secu_ctx *secu_ctx = nc.get()->security_ctx;
2623 2624 2625
  if (!data)
    Logger::amf_n1().error("Cannot allocate memory for security_data_t");

Niuhaiwen's avatar
Niuhaiwen committed
2626 2627
  if (secu_ctx->sc_type == SECURITY_CTX_TYPE_NOT_AVAILABLE &&
      nc.get()->is_common_procedure_for_security_mode_control_running) {
2628
    Logger::amf_n1().debug(
Niuhaiwen's avatar
Niuhaiwen committed
2629 2630 2631 2632
        "Using INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX for SecurityModeControl "
        "message");
    data->saved_selected_nea =
        secu_ctx->nas_algs
Niuhaiwen's avatar
Niuhaiwen committed
2633
            .encryption; // emm_ctx->_security.selected_algorithms.encryption;
2634
    data->saved_selected_nia = secu_ctx->nas_algs.integrity;
Niuhaiwen's avatar
Niuhaiwen committed
2635
    data->saved_ngksi = secu_ctx->ngksi;
Niuhaiwen's avatar
Niuhaiwen committed
2636
    data->saved_overflow =
Niuhaiwen's avatar
Niuhaiwen committed
2637 2638 2639 2640
        secu_ctx->dl_count.overflow; // emm_ctx->_security.dl_count.overflow;
    data->saved_seq_num = secu_ctx->dl_count.seq_num;
    data->saved_sc_type = secu_ctx->sc_type;
    secu_ctx->ngksi = nc.get()->ngKsi;
dukl's avatar
dukl committed
2641
    secu_ctx->dl_count.overflow = 0;
Niuhaiwen's avatar
Niuhaiwen committed
2642
    secu_ctx->dl_count.seq_num = 0;
dukl's avatar
dukl committed
2643
    secu_ctx->ul_count.overflow = 0;
Niuhaiwen's avatar
Niuhaiwen committed
2644 2645 2646 2647 2648
    secu_ctx->ul_count.seq_num = 0;
    int rc = security_select_algorithms(nc.get()->ueSecurityCapEnc,
                                        nc.get()->ueSecurityCapInt, amf_nea,
                                        amf_nia);
    secu_ctx->nas_algs.integrity = amf_nia;
dukl's avatar
dukl committed
2649
    secu_ctx->nas_algs.encryption = amf_nea;
Niuhaiwen's avatar
Niuhaiwen committed
2650 2651 2652 2653
    secu_ctx->sc_type = SECURITY_CTX_TYPE_FULL_NATIVE;
    Authentication_5gaka::derive_knas(NAS_INT_ALG, secu_ctx->nas_algs.integrity,
                                      nc.get()->kamf[secu_ctx->vector_pointer],
                                      secu_ctx->knas_int);
Niuhaiwen's avatar
Niuhaiwen committed
2654 2655 2656
    Authentication_5gaka::derive_knas(
        NAS_ENC_ALG, secu_ctx->nas_algs.encryption,
        nc.get()->kamf[secu_ctx->vector_pointer], secu_ctx->knas_enc);
Niuhaiwen's avatar
Niuhaiwen committed
2657
    security_context_is_new = true;
2658 2659 2660
    nc.get()->is_current_security_available = true;
  }

Niuhaiwen's avatar
Niuhaiwen committed
2661
  SecurityModeCommand *smc = new SecurityModeCommand();
dukl's avatar
dukl committed
2662 2663
  smc->setHeader(PLAIN_5GS_MSG);
  smc->setNAS_Security_Algorithms(amf_nea, amf_nia);
2664
  Logger::amf_n1().debug("Encoded ngKSI 0x%x", nc.get()->ngKsi);
dukl's avatar
dukl committed
2665
  smc->setngKSI(NAS_KEY_SET_IDENTIFIER_NATIVE, nc.get()->ngKsi & 0x07);
Niuhaiwen's avatar
Niuhaiwen committed
2666 2667
  smc->setUE_Security_Capability(nc.get()->ueSecurityCapEnc,
                                 nc.get()->ueSecurityCapInt);
Keliang's avatar
Keliang committed
2668 2669
  if (smc->ie_ue_security_capability != NULL) {
    smc->ie_ue_security_capability->setLenght(nc.get()->ueSecurityCaplen);
yangjian's avatar
yangjian committed
2670 2671
    smc->ie_ue_security_capability->setEEASel(nc.get()->ueSecurityCapEEnc);
    smc->ie_ue_security_capability->setEIASel(nc.get()->ueSecurityCapEInt);
Keliang's avatar
Keliang committed
2672 2673 2674 2675
  } else {
    Logger::amf_n1().error("smc->ie_ue_security_capability is NULL");
  }

dukl's avatar
dukl committed
2676 2677
  smc->setIMEISV_Request(0xe1);
  smc->setAdditional_5G_Security_Information(true, false);
dukl's avatar
dukl committed
2678 2679
  uint8_t buffer[1024];
  int encoded_size = smc->encode2buffer(buffer, 1024);
Niuhaiwen's avatar
Niuhaiwen committed
2680 2681
  print_buffer("amf_n1", "Security-Mode-Command message buffer", buffer,
               encoded_size);
dukl's avatar
dukl committed
2682
  bstring intProtctedNas;
Niuhaiwen's avatar
Niuhaiwen committed
2683 2684 2685
  encode_nas_message_protected(
      secu_ctx, security_context_is_new, INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX,
      NAS_MESSAGE_DOWNLINK, buffer, encoded_size, intProtctedNas);
Niuhaiwen's avatar
Niuhaiwen committed
2686 2687 2688 2689
  print_buffer("amf_n1", "Encrypted Security-Mode-Command message buffer",
               (uint8_t *)bdata(intProtctedNas), blength(intProtctedNas));
  itti_send_dl_nas_buffer_to_task_n2(intProtctedNas, nc.get()->ran_ue_ngap_id,
                                     nc.get()->amf_ue_ngap_id);
Niuhaiwen's avatar
Niuhaiwen committed
2690
  // secu_ctx->dl_count.seq_num ++;
2691
  return true;
dukl's avatar
dukl committed
2692 2693
}

2694
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
2695 2696
int amf_n1::security_select_algorithms(uint8_t nea, uint8_t nia,
                                       uint8_t &amf_nea, uint8_t &amf_nia) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2697 2698
  for (int i = 0; i < 8; i++) {
    if (nea & (0x80 >> amf_cfg.nas_cfg.prefered_ciphering_algorithm[i])) {
dukl's avatar
dukl committed
2699
      amf_nea = amf_cfg.nas_cfg.prefered_ciphering_algorithm[i];
dukl's avatar
dukl committed
2700
      printf("amf_nea: 0x%x\n", amf_nea);
dukl's avatar
dukl committed
2701 2702 2703
      break;
    }
  }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2704 2705
  for (int i = 0; i < 8; i++) {
    if (nia & (0x80 >> amf_cfg.nas_cfg.prefered_integrity_algorithm[i])) {
dukl's avatar
dukl committed
2706
      amf_nia = amf_cfg.nas_cfg.prefered_integrity_algorithm[i];
dukl's avatar
dukl committed
2707
      printf("amf_nia: 0x%x\n", amf_nia);
dukl's avatar
dukl committed
2708 2709 2710 2711 2712 2713
      break;
    }
  }
  return 0;
}

2714
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
2715 2716 2717
void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id,
                                           long amf_ue_ngap_id,
                                           bstring nas_msg) {
2718
  nlohmann::json udsf_nas_context;
2719
  Logger::amf_n1().debug("Handling security mode complete ...");
Niuhaiwen's avatar
Niuhaiwen committed
2720
  string ue_context_key = "app_ue_ranid_" + to_string(ran_ue_ngap_id) +
2721
                          "-amfid_" + to_string(amf_ue_ngap_id);
dukl's avatar
dukl committed
2722
  std::shared_ptr<ue_context> uc;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2723
  uc = amf_app_inst->ran_amf_id_2_ue_context(ue_context_key);
2724
  if (uc.get() == nullptr) {
Niuhaiwen's avatar
Niuhaiwen committed
2725
    // TODO:
2726 2727 2728
    Logger::amf_n1().error(
        "ue_context in amf_app using ran_amf_id (%s) does not existed!",
        ue_context_key.c_str());
2729
  }
2730 2731 2732
  Logger::amf_n1().info(
      "Found ue_context (%p) in amf_app using ran_amf_id (%s)", uc.get(),
      ue_context_key.c_str());
2733

dukl's avatar
dukl committed
2734
  // encoding REGISTRATION ACCEPT
Niuhaiwen's avatar
Niuhaiwen committed
2735
  RegistrationAccept *regAccept = new RegistrationAccept();
dukl's avatar
dukl committed
2736 2737
  regAccept->setHeader(PLAIN_5GS_MSG);
  regAccept->set_5GS_Registration_Result(false, false, false, 0x01);
2738 2739 2740
  std::string mcc;
  std::string mnc;
  uint32_t tmsi = 0;
Niuhaiwen's avatar
Niuhaiwen committed
2741 2742
  if (!amf_app_inst->generate_5g_guti(ran_ue_ngap_id, amf_ue_ngap_id, mcc, mnc,
                                      tmsi)) {
2743
    Logger::amf_n1().error("Generate 5G GUTI error! exit");
Niuhaiwen's avatar
Niuhaiwen committed
2744
    // TODO:
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2745 2746
    return;
  }
Niuhaiwen's avatar
Niuhaiwen committed
2747 2748
  regAccept->set5G_GUTI(mcc, mnc, amf_cfg.guami.regionID,
                        amf_cfg.guami.AmfSetID, amf_cfg.guami.AmfPointer, tmsi);
dukl's avatar
dukl committed
2749

2750
  std::vector<p_tai_t> tai_list = {};
Niuhaiwen's avatar
Niuhaiwen committed
2751 2752
  p_tai_t item0 = {};
  item0.type = 0x00;
dukl's avatar
dukl committed
2753 2754 2755 2756 2757 2758 2759 2760
  nas_plmn_t plmn;
  plmn.mcc = amf_cfg.plmn_list[0].mcc;
  plmn.mnc = amf_cfg.plmn_list[0].mnc;
  item0.plmn_list.push_back(plmn);
  item0.tac_list.push_back(amf_cfg.plmn_list[0].tac);
  tai_list.push_back(item0);
  regAccept->setTaiList(tai_list);

2761
  std::vector<struct SNSSAI_s> nssai = {};
Niuhaiwen's avatar
Niuhaiwen committed
2762 2763 2764 2765 2766
  SNSSAI_t snssai = {};
  snssai.sst = 1;
  snssai.sd = -1;
  snssai.mHplmnSst = -1;
  snssai.mHplmnSd = -1;
dukl's avatar
dukl committed
2767 2768 2769
  nssai.push_back(snssai);
  regAccept->setALLOWED_NSSAI(nssai);

Niuhaiwen's avatar
Niuhaiwen committed
2770 2771 2772
  std::string guti = mcc + mnc + amf_cfg.guami.regionID +
                     amf_cfg.guami.AmfSetID + amf_cfg.guami.AmfPointer +
                     std::to_string(tmsi);
2773
  Logger::amf_n1().debug("Allocated GUTI %s", guti.c_str());
dukl's avatar
dukl committed
2774

Niuhaiwen's avatar
Niuhaiwen committed
2775
  // TODO: remove hardcoded values
luhan Wang's avatar
luhan Wang committed
2776
  regAccept->set_5GS_Network_Feature_Support(0x01, 0x00);
yangjian's avatar
yangjian committed
2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792
  char *pathvar = NULL;
  pathvar = getenv("AMF_T3512_MIN");
  uint8_t t3512_Value = 0x1e;
  if(pathvar)
  {
    uint8_t value = atoi(pathvar);
    if(value)
    {
        t3512_Value = value;
    }
  }
  else
  {
    Logger::amf_n1().warn("Please set environment variable \"AMF_T3512_MIN\"");
  }
  regAccept->setT3512_Value(0x5, t3512_Value);
Niuhaiwen's avatar
Niuhaiwen committed
2793
  uint8_t buffer[BUFFER_SIZE_1024] = {0};
2794
  int encoded_size = regAccept->encode2buffer(buffer, BUFFER_SIZE_1024);
Niuhaiwen's avatar
Niuhaiwen committed
2795 2796
  print_buffer("amf_n1", "Registration-Accept message buffer", buffer,
               encoded_size);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2797
  if (!encoded_size) {
2798
    Logger::nas_mm().error("Encode Registration-Accept message error");
dukl's avatar
dukl committed
2799
    return;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2800
  } else {
dukl's avatar
dukl committed
2801 2802 2803
    delete regAccept;
  }

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2804
  if (!uc.get()->isUeContextRequest) {
2805
    Logger::amf_n1().debug(
Niuhaiwen's avatar
Niuhaiwen committed
2806 2807
        "UE Context is not requested, UE with ran_ue_ngap_id %d, "
        "amf_ue_ngap_id %d attached",
2808
        ran_ue_ngap_id, amf_ue_ngap_id);
Niuhaiwen's avatar
Niuhaiwen committed
2809
    // send registration accept back
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2810
  } else {
Niuhaiwen's avatar
Niuhaiwen committed
2811
    // encoding InitialContextSetupRequest(NGAP message) back
dukl's avatar
dukl committed
2812 2813
    std::shared_ptr<nas_context> nc;
    nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2814
    Logger::amf_n1().info(
Niuhaiwen's avatar
Niuhaiwen committed
2815 2816
        "UE (IMSI %s, GUTI %s, current RAN ID %d, current AMF ID %d) has been "
        "registered to the network",
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2817
        nc.get()->imsi.c_str(), guti.c_str(), ran_ue_ngap_id, amf_ue_ngap_id);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2818
    if (nc.get()->is_stacs_available) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2819 2820 2821 2822 2823 2824 2825 2826
      /* int index = 0;
       for (int i = 0; i < stacs.ues.size(); i++) {
       if (!(nc.get()->imsi).compare(stacs.ues[i].imsi)) {
       index = i;
       break;
       }
       }
       */
2827
      stacs.update_5gmm_state(nc.get()->imsi, "5GMM-REGISTERED");
Niuhaiwen's avatar
Niuhaiwen committed
2828 2829
      // update_ue_information_statics(stacs.ues[index], "", "RM-REGISTRED",
      // ran_ue_ngap_id, amf_ue_ngap_id, "", guti, "", "", 0);
2830
    } else {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2831
      // ue_infos ueItem;
Niuhaiwen's avatar
Niuhaiwen committed
2832 2833 2834 2835
      // update_ue_information_statics(ueItem, "CM-CONNECTED",
      // "REGISTRATION-REGISTRED", ran_ue_ngap_id, amf_ue_ngap_id,
      // nc.get()->imsi, "", mcc, mnc, uc.get()->cgi.nrCellID);
      // stacs.ues.push_back(ueItem);
2836
       nlohmann::json is_stacs_available;
yangjian's avatar
yangjian committed
2837
      nc.get()->is_stacs_available = true;
2838 2839 2840 2841
      is_stacs_available["Content-ID"] = "is_stacs_available";
      is_stacs_available["Content-Type"] = "varchar(32)";
      is_stacs_available["content"] = to_string(nc.get()->is_stacs_available);
      udsf_nas_context["blocks"].push_back(is_stacs_available);
2842
    }
2843
    set_5gmm_state(nc, _5GMM_REGISTERED);
2844

dukl's avatar
dukl committed
2845
    set_guti_2_nas_context(guti, nc);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2846
    nc.get()->is_common_procedure_for_security_mode_control_running = false;
Niuhaiwen's avatar
Niuhaiwen committed
2847
    nas_secu_ctx *secu = nc.get()->security_ctx;
Niuhaiwen's avatar
Niuhaiwen committed
2848
    // protect nas message
dukl's avatar
dukl committed
2849
    bstring protectedNas;
Niuhaiwen's avatar
Niuhaiwen committed
2850 2851 2852 2853
    encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
                                 NAS_MESSAGE_DOWNLINK, buffer, encoded_size,
                                 protectedNas);
    uint8_t *kamf = nc.get()->kamf[secu->vector_pointer];
dukl's avatar
dukl committed
2854 2855 2856
    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);
Niuhaiwen's avatar
Niuhaiwen committed
2857
    ncc = 1;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2858
    print_buffer("amf_n1", "kamf", kamf, 32);
Niuhaiwen's avatar
Niuhaiwen committed
2859
    // Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
dukl's avatar
dukl committed
2860
    bstring kgnb_bs = blk2bstr(kgnb, 32);
Niuhaiwen's avatar
Niuhaiwen committed
2861
    itti_initial_context_setup_request *itti_msg =
2862
        new itti_initial_context_setup_request(TASK_AMF_N1, TASK_AMF_N2);
2863 2864
    itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
    itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
Niuhaiwen's avatar
Niuhaiwen committed
2865 2866 2867
    itti_msg->kgnb = kgnb_bs;
    itti_msg->nas = protectedNas;
    itti_msg->is_sr = false; // TODO: for Setup Request procedure
2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879

/****************************hsx add*****************************/
    std::string udsf_url = "http://10.28.234.76:7123/nudsf-dr/v1/amfdata/" + std::string("nas_context/records/") + to_string(nc.get()->amf_ue_ngap_id) ;
    nlohmann::json udsf_response;
    udsf_nas_context["meta"] ["tags"] = {
                                      {"RECORD_ID",nlohmann::json::array({to_string(nc.get()->amf_ue_ngap_id)})},
                                      {"from_nf_ID",nlohmann::json::array({"AMF_1234"})}
                                      } ;    
    amf_n2_inst->curl_http_client_udsf(udsf_url,udsf_nas_context.dump(),"PUT",udsf_response);

/****************************hsx add*****************************/  
   
Niuhaiwen's avatar
Niuhaiwen committed
2880 2881
    std::shared_ptr<itti_initial_context_setup_request> i =
        std::shared_ptr<itti_initial_context_setup_request>(itti_msg);
dukl's avatar
dukl committed
2882 2883
    int ret = itti_inst->send_msg(i);
    if (0 != ret) {
2884 2885 2886
      Logger::amf_n1().error(
          "Could not send ITTI message %s to task TASK_AMF_N2",
          i->get_msg_name());
dukl's avatar
dukl committed
2887 2888
    }
  }
2889

dukl's avatar
dukl committed
2890 2891
}

2892
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
2893 2894
void amf_n1::security_mode_reject_handle(uint32_t ran_ue_ngap_id,
                                         long amf_ue_ngap_id, bstring nas_msg) {
2895 2896
  Logger::amf_n1().debug(
      "Receiving security mode reject message, handling ...");
dukl's avatar
dukl committed
2897 2898
}

Niuhaiwen's avatar
Niuhaiwen committed
2899 2900 2901 2902 2903
void amf_n1::registration_complete_handle(uint32_t ran_ue_ngap_id,
                                          long amf_ue_ngap_id,
                                          bstring nas_msg) {
  Logger::amf_n1().debug(
      "receiving registration complete, encoding Configuration Update Command");
luhan Wang's avatar
luhan Wang committed
2904 2905

  time_t tt;
Niuhaiwen's avatar
Niuhaiwen committed
2906 2907 2908
  time(&tt);
  tt = tt + 8 * 3600; // transform the time zone
  tm *t = gmtime(&tt);
luhan Wang's avatar
luhan Wang committed
2909

Niuhaiwen's avatar
Niuhaiwen committed
2910
  uint8_t conf[45] = {0};
luhan Wang's avatar
luhan Wang committed
2911
  uint8_t header[3] = {0x7e, 0x00, 0x54};
Niuhaiwen's avatar
Niuhaiwen committed
2912 2913 2914 2915 2916
  uint8_t full_name[18] = {0x43, 0x10, 0x81, 0xc1, 0x76, 0x58,
                           0x9e, 0x9e, 0xbf, 0xcd, 0x74, 0x90,
                           0xb3, 0x4c, 0xbf, 0xbf, 0xe5, 0x6b};
  uint8_t short_name[11] = {0x45, 0x09, 0x81, 0xc1, 0x76, 0x58,
                            0x9e, 0x9e, 0xbf, 0xcd, 0x74};
luhan Wang's avatar
luhan Wang committed
2917
  uint8_t time_zone[2] = {0x46, 0x23};
Niuhaiwen's avatar
Niuhaiwen committed
2918 2919 2920 2921 2922 2923 2924 2925
  uint8_t time[8] = {0};
  time[0] = 0x47;
  time[1] = 0x12;
  time[2] = ((t->tm_mon + 1) & 0x0f) << 4 | ((t->tm_mon + 1) & 0xf0) >> 4;
  time[3] = ((t->tm_mday + 1) & 0x0f) << 4 | ((t->tm_mday + 1) & 0xf0) >> 4;
  time[4] = ((t->tm_hour + 1) & 0x0f) << 4 | ((t->tm_hour + 1) & 0xf0) >> 4;
  time[5] = ((t->tm_min + 1) & 0x0f) << 4 | ((t->tm_min + 1) & 0xf0) >> 4;
  time[6] = ((t->tm_sec + 1) & 0x0f) << 4 | ((t->tm_sec + 1) & 0xf0) >> 4;
luhan Wang's avatar
luhan Wang committed
2926 2927 2928
  time[7] = 0x23;
  uint8_t daylight[3] = {0x49, 0x01, 0x00};
  memcpy(conf, header, 3);
Niuhaiwen's avatar
Niuhaiwen committed
2929 2930 2931 2932 2933
  memcpy(conf + 3, full_name, 18);
  memcpy(conf + 21, short_name, 11);
  memcpy(conf + 32, time_zone, 2);
  memcpy(conf + 34, time, 8);
  memcpy(conf + 42, daylight, 3);
luhan Wang's avatar
luhan Wang committed
2934 2935 2936 2937 2938

  std::shared_ptr<nas_context> nc;
  if (is_amf_ue_id_2_nas_context(amf_ue_ngap_id))
    nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
  else {
Niuhaiwen's avatar
Niuhaiwen committed
2939 2940
    Logger::amf_n1().warn("No existed nas_context with amf_ue_ngap_id(0x%x)",
                          amf_ue_ngap_id);
luhan Wang's avatar
luhan Wang committed
2941 2942
    return;
  }
Niuhaiwen's avatar
Niuhaiwen committed
2943
  nas_secu_ctx *secu = nc.get()->security_ctx;
luhan Wang's avatar
luhan Wang committed
2944 2945
  // protect nas message
  bstring protectedNas;
Niuhaiwen's avatar
Niuhaiwen committed
2946 2947 2948 2949 2950 2951 2952
  encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
                               NAS_MESSAGE_DOWNLINK, conf, 45, protectedNas);

  itti_send_dl_nas_buffer_to_task_n2(protectedNas, ran_ue_ngap_id,
                                     amf_ue_ngap_id);
}

2953
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
2954
void amf_n1::encode_nas_message_protected(
Niuhaiwen's avatar
Niuhaiwen committed
2955 2956 2957
    nas_secu_ctx *nsc, bool is_secu_ctx_new, uint8_t security_header_type,
    uint8_t direction, uint8_t *input_nas_buf, int input_nas_len,
    bstring &protected_nas) {
2958
  Logger::amf_n1().debug("Encoding nas_message_protected...");
dukl's avatar
dukl committed
2959 2960
  uint8_t protected_nas_buf[1024];
  int encoded_size = 0;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
2961
  switch (security_header_type & 0x0f) {
Niuhaiwen's avatar
Niuhaiwen committed
2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005
  case INTEGRITY_PROTECTED: {
  } break;
  case INTEGRITY_PROTECTED_AND_CIPHERED: {
    bstring input = blk2bstr(input_nas_buf, input_nas_len);
    bstring ciphered;
    nas_message_cipher_protected(nsc, NAS_MESSAGE_DOWNLINK, input, ciphered);
    protected_nas_buf[0] = EPD_5GS_MM_MSG;
    protected_nas_buf[1] = INTEGRITY_PROTECTED_AND_CIPHERED;
    protected_nas_buf[6] = (uint8_t)nsc->dl_count.seq_num;
    memcpy(&protected_nas_buf[7], (uint8_t *)bdata(ciphered),
           blength(ciphered));
    uint32_t mac32;
    if (!(nas_message_integrity_protected(nsc, NAS_MESSAGE_DOWNLINK,
                                          protected_nas_buf + 6,
                                          input_nas_len + 1, mac32))) {
      memcpy(protected_nas_buf, input_nas_buf, input_nas_len);
      encoded_size = input_nas_len;
    } else {
      *(uint32_t *)(protected_nas_buf + 2) = htonl(mac32);
      encoded_size = 7 + input_nas_len;
    }
  } break;
  case INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX: {
    if (!nsc || !is_secu_ctx_new) {
      Logger::amf_n1().error("Security context is too old");
    }
    protected_nas_buf[0] = EPD_5GS_MM_MSG;
    protected_nas_buf[1] = INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX;
    protected_nas_buf[6] = (uint8_t)nsc->dl_count.seq_num;
    memcpy(&protected_nas_buf[7], input_nas_buf, input_nas_len);
    uint32_t mac32;
    if (!(nas_message_integrity_protected(nsc, NAS_MESSAGE_DOWNLINK,
                                          protected_nas_buf + 6,
                                          input_nas_len + 1, mac32))) {
      memcpy(protected_nas_buf, input_nas_buf, input_nas_len);
      encoded_size = input_nas_len;
    } else {
      Logger::amf_n1().debug("mac32: 0x%x", mac32);
      *(uint32_t *)(protected_nas_buf + 2) = htonl(mac32);
      encoded_size = 7 + input_nas_len;
    }
  } break;
  case INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX: {
  } break;
dukl's avatar
dukl committed
3006 3007
  }
  protected_nas = blk2bstr(protected_nas_buf, encoded_size);
3008
  nsc->dl_count.seq_num++;
dukl's avatar
dukl committed
3009
}
3010 3011

//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
3012 3013 3014 3015 3016
bool amf_n1::nas_message_integrity_protected(nas_secu_ctx *nsc,
                                             uint8_t direction,
                                             uint8_t *input_nas,
                                             int input_nas_len,
                                             uint32_t &mac32) {
dukl's avatar
dukl committed
3017
  uint32_t count = 0x00000000;
Keliang's avatar
Keliang committed
3018
  if (direction) {
Niuhaiwen's avatar
Niuhaiwen committed
3019 3020
    count = 0x00000000 | ((nsc->dl_count.overflow & 0x0000ffff) << 8) |
            ((nsc->dl_count.seq_num & 0x000000ff));
Keliang's avatar
Keliang committed
3021
  } else {
Niuhaiwen's avatar
Niuhaiwen committed
3022 3023
    count = 0x00000000 | ((nsc->ul_count.overflow & 0x0000ffff) << 8) |
            ((nsc->ul_count.seq_num & 0x000000ff));
Keliang's avatar
Keliang committed
3024
  }
dukl's avatar
dukl committed
3025
  nas_stream_cipher_t stream_cipher = {0};
dukl's avatar
dukl committed
3026 3027
  uint8_t mac[4];
  stream_cipher.key = nsc->knas_int;
Niuhaiwen's avatar
Niuhaiwen committed
3028 3029
  print_buffer("amf_n1", "Parameters for NIA: knas_int", nsc->knas_int,
               AUTH_KNAS_INT_SIZE);
dukl's avatar
dukl committed
3030
  stream_cipher.key_length = AUTH_KNAS_INT_SIZE;
Niuhaiwen's avatar
Niuhaiwen committed
3031
  stream_cipher.count = *(input_nas);
Niuhaiwen's avatar
Niuhaiwen committed
3032
  // stream_cipher.count = count;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
3033
  if (!direction) {
dukl's avatar
dukl committed
3034
    nsc->ul_count.seq_num = stream_cipher.count;
3035 3036 3037
    Logger::amf_n1().debug("Uplink count in uplink: %d", nsc->ul_count.seq_num);
  }
  Logger::amf_n1().debug("Parameters for NIA, count: 0x%x", count);
Niuhaiwen's avatar
Niuhaiwen committed
3038 3039 3040 3041
  stream_cipher.bearer = 0x01; // 33.501 section 8.1.1
  Logger::amf_n1().debug("Parameters for NIA, bearer: 0x%x",
                         stream_cipher.bearer);
  stream_cipher.direction = direction; // "1" for downlink
3042
  Logger::amf_n1().debug("Parameters for NIA, direction: 0x%x", direction);
Niuhaiwen's avatar
Niuhaiwen committed
3043 3044 3045
  stream_cipher.message = (uint8_t *)input_nas;
  print_buffer("amf_n1", "Parameters for NIA, message: ", input_nas,
               input_nas_len);
3046
  stream_cipher.blength = input_nas_len * 8;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
3047
  switch (nsc->nas_algs.integrity & 0x0f) {
Niuhaiwen's avatar
Niuhaiwen committed
3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067
  case IA0_5G: {
    Logger::amf_n1().debug("Integrity with algorithms: 5G-IA0");
    return false; // plain msg
  } break;
  case IA1_128_5G: {
    Logger::amf_n1().debug("Integrity with algorithms: 128-5G-IA1");
    nas_algorithms::nas_stream_encrypt_nia1(&stream_cipher, mac);
    print_buffer("amf_n1", "Result for NIA1, mac: ", mac, 4);
    mac32 = ntohl(*((uint32_t *)mac));
    Logger::amf_n1().debug("Result for NIA1, mac32: 0x%x", mac32);
    return true;
  } break;
  case IA2_128_5G: {
    Logger::amf_n1().debug("Integrity with algorithms: 128-5G-IA2");
    nas_algorithms::nas_stream_encrypt_nia2(&stream_cipher, mac);
    print_buffer("amf_n1", "Result for NIA2, mac: ", mac, 4);
    mac32 = ntohl(*((uint32_t *)mac));
    Logger::amf_n1().debug("Result for NIA2, mac32: 0x%x", mac32);
    return true;
  } break;
dukl's avatar
dukl committed
3068 3069 3070
  }
}

3071
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
3072 3073 3074 3075 3076
bool amf_n1::nas_message_cipher_protected(nas_secu_ctx *nsc, uint8_t direction,
                                          bstring input_nas,
                                          bstring &output_nas) {
  uint8_t *buf = (uint8_t *)bdata(input_nas);
  int buf_len = blength(input_nas);
dukl's avatar
dukl committed
3077
  uint32_t count = 0x00000000;
3078
  if (direction)
yangjian's avatar
yangjian committed
3079
  {
Niuhaiwen's avatar
Niuhaiwen committed
3080 3081
    count = 0x00000000 | ((nsc->dl_count.overflow & 0x0000ffff) << 8) |
            ((nsc->dl_count.seq_num & 0x000000ff));
yangjian's avatar
yangjian committed
3082
  }
dukl's avatar
dukl committed
3083
  else
yangjian's avatar
yangjian committed
3084 3085
  {
    Logger::amf_n1().debug("nsc->ul_count.overflow %x", nsc->ul_count.overflow);
Niuhaiwen's avatar
Niuhaiwen committed
3086 3087
    count = 0x00000000 | ((nsc->ul_count.overflow & 0x0000ffff) << 8) |
            ((nsc->ul_count.seq_num & 0x000000ff));
yangjian's avatar
yangjian committed
3088
  }
dukl's avatar
dukl committed
3089
  nas_stream_cipher_t stream_cipher = {0};
dukl's avatar
dukl committed
3090
  uint8_t mac[4];
Niuhaiwen's avatar
Niuhaiwen committed
3091
  stream_cipher.key = nsc->knas_enc;
dukl's avatar
dukl committed
3092
  stream_cipher.key_length = AUTH_KNAS_ENC_SIZE;
Niuhaiwen's avatar
Niuhaiwen committed
3093
  stream_cipher.count = count;
yangjian's avatar
yangjian committed
3094
  stream_cipher.bearer = 0x01;         // 33.501 section 8.1.1
Niuhaiwen's avatar
Niuhaiwen committed
3095 3096 3097
  stream_cipher.direction = direction; // "1" for downlink
  stream_cipher.message = (uint8_t *)bdata(input_nas);
  stream_cipher.blength = blength(input_nas) << 3;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
3098
  switch (nsc->nas_algs.encryption & 0x0f) {
Niuhaiwen's avatar
Niuhaiwen committed
3099 3100 3101 3102 3103 3104 3105
  case EA0_5G: {
    Logger::amf_n1().debug("Cipher protected with EA0_5G");
    output_nas = blk2bstr(buf, buf_len);
    return true;
  } break;
  case EA1_128_5G: {
    Logger::amf_n1().debug("Cipher protected with EA1_128_5G");
Keliang's avatar
Keliang committed
3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117
    Logger::amf_n1().debug("stream_cipher.blength %d", stream_cipher.blength);
    Logger::amf_n1().debug("stream_cipher.message %x",
                           stream_cipher.message[0]);
    print_buffer("amf_n1", "stream_cipher.key ", stream_cipher.key, 16);
    Logger::amf_n1().debug("stream_cipher.count %x", stream_cipher.count);

    uint8_t *ciphered =
        (uint8_t *)malloc(((stream_cipher.blength + 31) / 32) * 4);

    nas_algorithms::nas_stream_encrypt_nea1(&stream_cipher, ciphered);
    output_nas = blk2bstr(ciphered, ((stream_cipher.blength + 31) / 32) * 4);
    free(ciphered);
Niuhaiwen's avatar
Niuhaiwen committed
3118 3119 3120 3121 3122 3123
  } break;
  case EA2_128_5G: {
    Logger::amf_n1().debug("Cipher protected with EA2_128_5G");
    nas_algorithms::nas_stream_encrypt_nea2(&stream_cipher,
                                            (uint8_t *)bdata(output_nas));
  } break;
dukl's avatar
dukl committed
3124 3125 3126
  }
}

3127
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
3128
void amf_n1::run_initial_registration_procedure() {}
dukl's avatar
dukl committed
3129

3130
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
3131 3132 3133
void amf_n1::ue_initiate_de_registration_handle(uint32_t ran_ue_ngap_id,
                                                long amf_ue_ngap_id,
                                                bstring nas) {
3134
  Logger::amf_n1().debug("Handling UE-initiated De-registration Request");
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
3135 3136 3137 3138 3139 3140 3141 3142 3143
  /*
   string guti = "1234567890";//need modify

   _5G_GUTI_t Guti;
   _5GSMobilityIdentity *ulNas = new _5GSMobilityIdentity();
   ulNas->decodefrombuffer((uint8_t*)bdata(nas)+4, blength(nas),false);
   ulNas->get5GGUTI(Guti);
   delete ulNas;
   string amf_region_id = std::to_string(Guti.amf_region_id);
Niuhaiwen's avatar
Niuhaiwen committed
3144 3145 3146
   guti = Guti.mcc + Guti.mnc + std::to_string(Guti.amf_region_id) +
   std::to_string(Guti.amf_set_id) + std::to_string(Guti.amf_pointer) +
   std::to_string(Guti._5g_tmsi); std::shared_ptr<nas_context> nc;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
3147 3148 3149 3150 3151 3152
   if(!is_guti_2_nas_context(guti))
   return;
   nc = guti_2_nas_context(guti);
   nc.get()-> is_auth_vectors_present = false;
   nc.get()-> is_current_security_available = false;
   nc.get()->security_ctx->sc_type = SECURITY_CTX_TYPE_NOT_AVAILABLE;
Niuhaiwen's avatar
Niuhaiwen committed
3153 3154 3155
   Logger::ngap().debug("sending itti ue context release command to
   TASK_AMF_N2"); itti_ue_context_release_command * itti_msg = new
   itti_ue_context_release_command(TASK_AMF_N1, TASK_AMF_N2);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
3156 3157 3158 3159
   itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
   itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
   itti_msg->cause.setChoiceOfCause(Ngap_Cause_PR_nas);
   itti_msg->cause.setValue(2);//cause nas(2)--deregister
Niuhaiwen's avatar
Niuhaiwen committed
3160 3161 3162 3163
   std::shared_ptr<itti_ue_context_release_command> i =
   std::shared_ptr<itti_ue_context_release_command>(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());
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
3164 3165
   }
   */
3166

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
3167
  std::shared_ptr<nas_context> nc;
3168 3169 3170
  if (is_amf_ue_id_2_nas_context(amf_ue_ngap_id))
    nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
  else {
Niuhaiwen's avatar
Niuhaiwen committed
3171 3172
    Logger::amf_n1().warn("No existed nas_context with amf_ue_ngap_id(0x%x)",
                          amf_ue_ngap_id);
3173
    return;
3174 3175
  }

Niuhaiwen's avatar
Niuhaiwen committed
3176
  // decode NAS msg
Niuhaiwen's avatar
Niuhaiwen committed
3177 3178
  DeregistrationRequest *deregReq = new DeregistrationRequest();
  deregReq->decodefrombuffer(NULL, (uint8_t *)bdata(nas), blength(nas));
3179
  /*
3180 3181 3182 3183 3184 3185 3186
   _5gs_deregistration_type_t type = {};
   deregReq->getDeregistrationType(type);
   uint8_t deregType = 0;
   deregReq->getDeregistrationType(deregType);
   Logger::amf_n1().debug("Deregistration Type %X", deregType);
   */

Niuhaiwen's avatar
Niuhaiwen committed
3187
  // TODO: validate 5G Mobile Identity
3188 3189 3190
  uint8_t mobile_id_type = 0;
  deregReq->getMobilityIdentityType(mobile_id_type);
  Logger::amf_n1().debug("5G Mobile Identity %X", mobile_id_type);
3191
  switch (mobile_id_type) {
Niuhaiwen's avatar
Niuhaiwen committed
3192 3193 3194 3195
  case _5G_GUTI: {
    Logger::amf_n1().debug("5G Mobile Identity, GUTI %s",
                           deregReq->get_5g_guti().c_str());
  } break;
Keliang's avatar
Keliang committed
3196 3197
  default: {
  }
3198
  }
3199

Niuhaiwen's avatar
Niuhaiwen committed
3200
  // Prepare DeregistrationAccept
Niuhaiwen's avatar
Niuhaiwen committed
3201
  DeregistrationAccept *deregAccept = new DeregistrationAccept();
3202 3203
  deregAccept->setHeader(PLAIN_5GS_MSG);

Niuhaiwen's avatar
Niuhaiwen committed
3204
  uint8_t buffer[BUFFER_SIZE_512] = {0};
3205
  int encoded_size = deregAccept->encode2buffer(buffer, BUFFER_SIZE_512);
3206

Niuhaiwen's avatar
Niuhaiwen committed
3207 3208
  print_buffer("amf_n1", "De-registration Accept message buffer", buffer,
               encoded_size);
3209
  if (encoded_size < 1) {
3210 3211 3212 3213 3214 3215
    Logger::nas_mm().error("Encode De-registration Accept message error");
    return;
  }

  bstring b = blk2bstr(buffer, encoded_size);
  itti_send_dl_nas_buffer_to_task_n2(b, ran_ue_ngap_id, amf_ue_ngap_id);
3216

3217 3218
  set_5gmm_state(nc, _5GMM_DEREGISTERED);
  if (nc.get()->is_stacs_available) {
3219
    stacs.update_5gmm_state(nc.get()->imsi, "5GMM-DEREGISTERED");
3220
  }
3221
}
3222

3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239
//------------------------------------------------------------------------------
void amf_n1::network_initiate_de_registration_handle(uint32_t ran_ue_ngap_id,
                                                long amf_ue_ngap_id) {
  Logger::amf_n1().debug("Handling network-initiated De-registration Request");

  std::shared_ptr<nas_context> nc;
  if (is_amf_ue_id_2_nas_context(amf_ue_ngap_id))
    nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
  else {
    Logger::amf_n1().warn("No existed nas_context with amf_ue_ngap_id(0x%x)",
                          amf_ue_ngap_id);
    return;
  }

  // encode NAS msg
  DeregistrationRequest *deregReq = new DeregistrationRequest();
  deregReq->setHeader(PLAIN_5GS_MSG,DEREGISTRATION_REQUEST_UE_TERMINATED);
yangjian's avatar
yangjian committed
3240
  //deregReq->setngKSI(NAS_KEY_SET_IDENTIFIER_NATIVE,nc.get()->ngKsi);
3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253

  deregReq->setDeregistrationType(0x05);

  uint8_t buffer[BUFFER_SIZE_512] = {0};
  int encoded_size = deregReq->encode2buffer(buffer, BUFFER_SIZE_512);

  print_buffer("amf_n1", "De-registration Request message buffer", buffer,
               encoded_size);
  if (encoded_size < 1) {
    Logger::nas_mm().error("Encode De-registration Request message error");
    return;
  }

yangjian's avatar
yangjian committed
3254 3255 3256 3257 3258 3259
  bstring intProtctedNas;
  encode_nas_message_protected(
      nc.get()->security_ctx,false, INTEGRITY_PROTECTED_AND_CIPHERED,
      NAS_MESSAGE_DOWNLINK, buffer, encoded_size, intProtctedNas);

  itti_send_dl_nas_buffer_to_task_n2(intProtctedNas, ran_ue_ngap_id, amf_ue_ngap_id);
3260 3261 3262 3263 3264 3265 3266 3267

  set_5gmm_state(nc, _5GMM_DEREGISTERED);
  if (nc.get()->is_stacs_available) {
    stacs.update_5gmm_state(nc.get()->imsi, "5GMM-DEREGISTERED");
  }
}


3268
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
3269 3270
void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id,
                                     long amf_ue_ngap_id, bstring nas) {
Niuhaiwen's avatar
Niuhaiwen committed
3271
  // Decode UL_NAS_TRANSPORT message
3272
  Logger::amf_n1().debug("Handling UL NAS Transport");
Niuhaiwen's avatar
Niuhaiwen committed
3273 3274 3275
  ULNASTransport *ulNas = new ULNASTransport();
  ulNas->decodefrombuffer(NULL, (uint8_t *)bdata(nas), blength(nas));
  uint8_t payload_type = ulNas->getPayloadContainerType();
3276
  uint8_t pdu_session_id = ulNas->getPduSessionId();
Niuhaiwen's avatar
Niuhaiwen committed
3277 3278
  uint8_t request_type = ulNas->getRequestType();
  SNSSAI_t snssai = {};
3279 3280 3281
  ulNas->getSnssai(snssai);
  bstring dnn = bfromcstr("default");
  bstring sm_msg;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
3282
  if (ulNas->getDnn(dnn)) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
3283
  } else {
3284 3285
    dnn = bfromcstr("default");
  }
Niuhaiwen's avatar
Niuhaiwen committed
3286 3287
  print_buffer("amf_n1", "Decoded DNN bitstring", (uint8_t *)bdata(dnn),
               blength(dnn));
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
3288
  switch (payload_type) {
Niuhaiwen's avatar
Niuhaiwen committed
3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313
  case N1_SM_INFORMATION: {
    if (!ulNas->getPayloadContainer(sm_msg)) {
      Logger::amf_n1().error("Cannot decode Payload Container");
      return;
    }
    // send_itti_to_smf_services_consumer(ran_ue_ngap_id, amf_ue_ngap_id,
    // request_type, pdu_session_id, dnn, sm_msg);
    itti_smf_services_consumer *itti_msg =
        new itti_smf_services_consumer(TASK_AMF_N1, TASK_AMF_N11);
    itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
    itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
    itti_msg->req_type = request_type;
    itti_msg->pdu_sess_id = pdu_session_id;
    itti_msg->dnn = dnn;
    itti_msg->sm_msg = sm_msg;
    itti_msg->snssai.sST = snssai.sst;
    itti_msg->snssai.sD = std::to_string(snssai.sd);
    std::shared_ptr<itti_smf_services_consumer> i =
        std::shared_ptr<itti_smf_services_consumer>(itti_msg);
    int ret = itti_inst->send_msg(i);
    if (0 != ret) {
      Logger::amf_n1().error(
          "Could not send ITTI message %s to task TASK_AMF_N11",
          i->get_msg_name());
    }
3314

Niuhaiwen's avatar
Niuhaiwen committed
3315
  } break;
3316
  }
dukl's avatar
dukl committed
3317 3318
}

3319
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
3320 3321 3322
void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id,
                                     long amf_ue_ngap_id, bstring nas,
                                     plmn_t plmn) {
Niuhaiwen's avatar
Niuhaiwen committed
3323
  // Decode UL_NAS_TRANSPORT message
3324
  Logger::amf_n1().debug("Handling UL NAS Transport");
Niuhaiwen's avatar
Niuhaiwen committed
3325 3326 3327
  ULNASTransport *ulNas = new ULNASTransport();
  ulNas->decodefrombuffer(NULL, (uint8_t *)bdata(nas), blength(nas));
  uint8_t payload_type = ulNas->getPayloadContainerType();
3328
  uint8_t pdu_session_id = ulNas->getPduSessionId();
Niuhaiwen's avatar
Niuhaiwen committed
3329 3330
  uint8_t request_type = ulNas->getRequestType();
  SNSSAI_t snssai = {};
3331
  ulNas->getSnssai(snssai);
3332 3333 3334 3335 3336 3337
  bstring dnn = bfromcstr("default");
  bstring sm_msg;
  if (ulNas->getDnn(dnn)) {
  } else {
    dnn = bfromcstr("default");
  }
Niuhaiwen's avatar
Niuhaiwen committed
3338 3339
  print_buffer("amf_n1", "Decoded DNN bitstring", (uint8_t *)bdata(dnn),
               blength(dnn));
3340
  switch (payload_type) {
Niuhaiwen's avatar
Niuhaiwen committed
3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359
  case N1_SM_INFORMATION: {
    if (!ulNas->getPayloadContainer(sm_msg)) {
      Logger::amf_n1().error("Cannot decode Payload Container");
      return;
    }
    // send_itti_to_smf_services_consumer(ran_ue_ngap_id, amf_ue_ngap_id,
    // request_type, pdu_session_id, dnn, sm_msg);
    itti_smf_services_consumer *itti_msg =
        new itti_smf_services_consumer(TASK_AMF_N1, TASK_AMF_N11);
    itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
    itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
    itti_msg->req_type = request_type;
    itti_msg->pdu_sess_id = pdu_session_id;
    itti_msg->dnn = dnn;
    itti_msg->sm_msg = sm_msg;
    itti_msg->snssai.sST = snssai.sst;
    itti_msg->snssai.sD = std::to_string(snssai.sd);
    itti_msg->plmn.mnc = plmn.mnc;
    itti_msg->plmn.mcc = plmn.mcc;
yangjian's avatar
yangjian committed
3360
    itti_msg->plmn.tac = plmn.tac;
Niuhaiwen's avatar
Niuhaiwen committed
3361 3362 3363 3364 3365 3366 3367 3368
    std::shared_ptr<itti_smf_services_consumer> i =
        std::shared_ptr<itti_smf_services_consumer>(itti_msg);
    int ret = itti_inst->send_msg(i);
    if (0 != ret) {
      Logger::amf_n1().error(
          "Could not send ITTI message %s to task TASK_AMF_N11",
          i->get_msg_name());
    }
3369

Niuhaiwen's avatar
Niuhaiwen committed
3370
  } break;
3371 3372 3373
  }
}

3374
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
3375 3376 3377 3378 3379 3380
void amf_n1::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) {
  itti_smf_services_consumer *itti_msg =
Niuhaiwen's avatar
Niuhaiwen committed
3381
      new itti_smf_services_consumer(TASK_AMF_N1, TASK_AMF_N11);
dukl's avatar
dukl committed
3382 3383
  itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
  itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
Niuhaiwen's avatar
Niuhaiwen committed
3384 3385 3386 3387
  itti_msg->req_type = request_type;
  itti_msg->pdu_sess_id = pdu_session_id;
  itti_msg->dnn = dnn;
  itti_msg->sm_msg = sm_msg;
Niuhaiwen's avatar
Niuhaiwen committed
3388 3389
  std::shared_ptr<itti_smf_services_consumer> i =
      std::shared_ptr<itti_smf_services_consumer>(itti_msg);
dukl's avatar
dukl committed
3390 3391
  int ret = itti_inst->send_msg(i);
  if (0 != ret) {
3392 3393 3394
    Logger::amf_n1().error(
        "Could not send ITTI message %s to task TASK_AMF_N11",
        i->get_msg_name());
dukl's avatar
dukl committed
3395 3396 3397
  }
}

3398
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
3399
void amf_n1::dump_nas_message(uint8_t *buf, int len) {
3400 3401
  for (int i = 0; i < len; i++)
    Logger::amf_n1().debug("[octet%d](0x%x)", i + 1, buf[i]);
dukl's avatar
dukl committed
3402 3403
}

3404
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
3405
void amf_n1::ue_authentication_simulator(uint8_t *rand, uint8_t *autn) {
dukl's avatar
dukl committed
3406 3407
  print_buffer("amf_n1", "[ue] received rand", rand, 16);
  print_buffer("amf_n1", "[ue] received autn", autn, 16);
Niuhaiwen's avatar
Niuhaiwen committed
3408
  uint8_t opc[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
Niuhaiwen's avatar
Niuhaiwen committed
3409
                     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
Niuhaiwen's avatar
Niuhaiwen committed
3410
  uint8_t key[16] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
Niuhaiwen's avatar
Niuhaiwen committed
3411
                     0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
3412
  string serving_network = "5G:mnc011.mcc460.3gppnetwork.org";
dukl's avatar
dukl committed
3413 3414 3415 3416
  print_buffer("amf_n1", "[ue] local opc", opc, 16);
  print_buffer("amf_n1", "[ue] local key", key, 16);
  uint8_t res[8], resStar[16];
  uint8_t ck[16], ik[16], ak[6];
Niuhaiwen's avatar
Niuhaiwen committed
3417 3418
  Authentication_5gaka::f2345(opc, key, rand, res, ck, ik,
                              ak); // to compute XRES, CK, IK, AK
dukl's avatar
dukl committed
3419 3420 3421 3422 3423 3424 3425
  print_buffer("amf_n1", "[ue] Result for f2345: res", res, 8);
  print_buffer("amf_n1", "[ue] Result for f2345: ck", ck, 16);
  print_buffer("amf_n1", "[ue] Result for f2345: ik", ik, 16);
  print_buffer("amf_n1", "[ue] Result for f2345: ak", ak, 6);
  annex_a_4_33501(ck, ik, res, rand, serving_network, resStar);
  print_buffer("amf_n1", "[ue] computed RES*", resStar, 16);
  uint8_t sqn[6];
Niuhaiwen's avatar
Niuhaiwen committed
3426 3427
  for (int i = 0; i < 6; i++)
    sqn[i] = ak[i] ^ autn[i];
dukl's avatar
dukl committed
3428 3429 3430 3431 3432 3433 3434 3435
  print_buffer("amf_n1", "[ue] sqn", sqn, 6);
  uint8_t amf[2];
  amf[0] = autn[6];
  amf[1] = autn[7];
  Logger::amf_n1().debug("[ue] amf 0x%x%x", amf[0], amf[1]);
  uint8_t mac_s[8];
  Authentication_5gaka::f1(opc, key, rand, sqn, amf, mac_s);
  print_buffer("amf_n1", "[ue] mas_s", mac_s, 8);
3436
  print_buffer("amf_n1", "[ue] mas_a", autn + 8, 8);
dukl's avatar
dukl committed
3437 3438
}

3439
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
3440 3441
void amf_n1::sha256(unsigned char *message, int msg_len,
                    unsigned char *output) {
3442
  memset(output, 0, Sha256::DIGEST_SIZE);
dukl's avatar
dukl committed
3443 3444 3445 3446 3447
  ctx.init();
  ctx.update(message, msg_len);
  ctx.finalResult(output);
}

3448
//------------------------------------------------------------------------------
3449 3450
void amf_n1::run_mobility_registration_update_procedure(
    std::shared_ptr<nas_context> nc) {
dukl's avatar
dukl committed
3451
  // encoding REGISTRATION ACCEPT
Niuhaiwen's avatar
Niuhaiwen committed
3452
  RegistrationAccept *regAccept = new RegistrationAccept();
dukl's avatar
dukl committed
3453
  regAccept->setHeader(PLAIN_5GS_MSG);
3454
  regAccept->set_5GS_Registration_Result(false, false, true, 0x01);
Niuhaiwen's avatar
Niuhaiwen committed
3455 3456 3457
  regAccept->set5G_GUTI(amf_cfg.guami.mcc, amf_cfg.guami.mnc,
                        amf_cfg.guami.regionID, amf_cfg.guami.AmfSetID,
                        amf_cfg.guami.AmfPointer, 0x264a34c0);
dukl's avatar
dukl committed
3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472
  regAccept->setT3512_Value(0x5, 0x1e);

  std::vector<p_tai_t> tai_list;
  p_tai_t item0;
  item0.type = 0x00;
  nas_plmn_t plmn;
  plmn.mcc = amf_cfg.plmn_list[0].mcc;
  plmn.mnc = amf_cfg.plmn_list[0].mnc;
  item0.plmn_list.push_back(plmn);
  item0.tac_list.push_back(amf_cfg.plmn_list[0].tac);
  tai_list.push_back(item0);
  regAccept->setTaiList(tai_list);

  std::vector<struct SNSSAI_s> nssai;
  SNSSAI_t snssai;
Niuhaiwen's avatar
Niuhaiwen committed
3473 3474
  snssai.sst = 0;
  snssai.sd = -1;
dukl's avatar
dukl committed
3475
  snssai.mHplmnSst = -1;
Niuhaiwen's avatar
Niuhaiwen committed
3476
  snssai.mHplmnSd = -1;
dukl's avatar
dukl committed
3477 3478 3479
  nssai.push_back(snssai);
  regAccept->setALLOWED_NSSAI(nssai);

Niuhaiwen's avatar
Niuhaiwen committed
3480
  // std::string guti = amf_cfg.guami.mcc + amf_cfg.guami.mnc +
Keliang's avatar
Keliang committed
3481 3482
  // amf_cfg.guami.regionID + amf_cfg.guami.AmfSetID + amf_cfg.guami.AmfPointer
  // + "0001";
Niuhaiwen's avatar
Niuhaiwen committed
3483
  std::string guti = "1234567890"; // TODO: need modify
3484
  Logger::amf_n1().debug("Allocated GUTI %s", guti.c_str());
dukl's avatar
dukl committed
3485 3486

  regAccept->set_5GS_Network_Feature_Support(0x00, 0x00);
dukl's avatar
dukl committed
3487
  uint8_t buffer[1024] = {0};
Niuhaiwen's avatar
Niuhaiwen committed
3488 3489 3490
  int encoded_size = regAccept->encode2buffer(buffer, 1024);
  print_buffer("amf_n1", "Registration-Accept Message Buffer", buffer,
               encoded_size);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
3491
  if (!encoded_size) {
3492
    Logger::nas_mm().error("Encode Registration-Accept message error");
dukl's avatar
dukl committed
3493
    return;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
3494
  } else {
dukl's avatar
dukl committed
3495 3496
    delete regAccept;
  }
Niuhaiwen's avatar
Niuhaiwen committed
3497
  nas_secu_ctx *secu = nc.get()->security_ctx;
Niuhaiwen's avatar
Niuhaiwen committed
3498
  // protect nas message
dukl's avatar
dukl committed
3499
  bstring protectedNas;
Niuhaiwen's avatar
Niuhaiwen committed
3500 3501 3502
  encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
                               NAS_MESSAGE_DOWNLINK, buffer, encoded_size,
                               protectedNas);
dukl's avatar
dukl committed
3503 3504

  string supi = "imsi-" + nc.get()->imsi;
3505
  Logger::amf_n1().debug("Key for pdu session context SUPI (%s)", supi.c_str());
dukl's avatar
dukl committed
3506
  std::shared_ptr<pdu_session_context> psc;
3507 3508 3509 3510 3511 3512 3513 3514
  
  //***************************stateless
  pdu_session_context *psc1 = new pdu_session_context();
  nlohmann::json udsf_response;
  std::string udsf_url = "http://10.112.202.24:7123/nudsf-dr/v1/amfdata/" + std::string("pdu_session_context/records/") + supi ;
  if(!amf_n2_inst->curl_http_client_udsf(udsf_url,"","GET",udsf_response)){
    Logger::amf_n2().error("No existing pdu_session_context with assoc_id ");
    return;
dukl's avatar
dukl committed
3515
  }
3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526
  Logger::amf_n2().debug("udsf_response: %s", udsf_response.dump().c_str());
  psc1->pdu_session_context_from_json(udsf_response);
  psc = std::shared_ptr<pdu_session_context>(psc1);
  //***************************stateless

  // if (amf_n11_inst->is_supi_to_pdu_ctx(supi)) {
  //   psc = amf_n11_inst->supi_to_pdu_ctx(supi);
  // } else {
  //   Logger::amf_n1().error("Cannot get pdu_session_context with SUPI (%s)",
  //                          supi.c_str());
  // }
dukl's avatar
dukl committed
3527

Niuhaiwen's avatar
Niuhaiwen committed
3528
  uint8_t *kamf = nc.get()->kamf[secu->vector_pointer];
dukl's avatar
dukl committed
3529 3530 3531
  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);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
3532
  print_buffer("amf_n1", "kamf", kamf, 32);
Niuhaiwen's avatar
Niuhaiwen committed
3533
  // Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
dukl's avatar
dukl committed
3534
  bstring kgnb_bs = blk2bstr(kgnb, 32);
Niuhaiwen's avatar
Niuhaiwen committed
3535
  itti_initial_context_setup_request *itti_msg =
3536
      new itti_initial_context_setup_request(TASK_AMF_N1, TASK_AMF_N2);
3537 3538
  itti_msg->ran_ue_ngap_id = nc.get()->ran_ue_ngap_id;
  itti_msg->amf_ue_ngap_id = nc.get()->amf_ue_ngap_id;
Niuhaiwen's avatar
Niuhaiwen committed
3539 3540 3541
  itti_msg->kgnb = kgnb_bs;
  itti_msg->nas = protectedNas;
  itti_msg->is_sr = true; // service request indicator
dukl's avatar
dukl committed
3542
  itti_msg->pdu_session_id = psc.get()->pdu_session_id;
Niuhaiwen's avatar
Niuhaiwen committed
3543
  itti_msg->n2sm = psc.get()->n2sm;
Niuhaiwen's avatar
Niuhaiwen committed
3544 3545
  std::shared_ptr<itti_initial_context_setup_request> i =
      std::shared_ptr<itti_initial_context_setup_request>(itti_msg);
dukl's avatar
dukl committed
3546 3547
  int ret = itti_inst->send_msg(i);
  if (0 != ret) {
Niuhaiwen's avatar
Niuhaiwen committed
3548 3549
    Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2",
                           i->get_msg_name());
dukl's avatar
dukl committed
3550 3551
  }
}
3552

3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614
//------------------------------------------------------------------------------
void amf_n1::run_periodic_registration_update_procedure(
    std::shared_ptr<nas_context> nc,uint16_t pdu_session_status) {
  // 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);
  regAccept->setT3512_Value(0x5, 0x1e);

  std::vector<p_tai_t> tai_list;
  p_tai_t item0;
  item0.type = 0x00;
  nas_plmn_t plmn;
  plmn.mcc = amf_cfg.plmn_list[0].mcc;
  plmn.mnc = amf_cfg.plmn_list[0].mnc;
  item0.plmn_list.push_back(plmn);
  item0.tac_list.push_back(amf_cfg.plmn_list[0].tac);
  tai_list.push_back(item0);
  regAccept->setTaiList(tai_list);
//
//  std::vector<struct SNSSAI_s> nssai;
//  SNSSAI_t snssai;
//  snssai.sst = 0;
//  snssai.sd = -1;
//  snssai.mHplmnSst = -1;
//  snssai.mHplmnSd = -1;
//  nssai.push_back(snssai);
//  regAccept->setALLOWED_NSSAI(nssai);

  if (pdu_session_status == 0x0000) {
      regAccept->setPDU_session_status(0x0000);
  } else {
      regAccept->setPDU_session_status(pdu_session_status);
      Logger::amf_n1().debug("setting pdu session status 0x%02x",
                             htonl(pdu_session_status));
      // serApt->setPDU_session_status(0x2000);
  }

  regAccept->set_5GS_Network_Feature_Support(0x01, 0x00);
  uint8_t buffer[1024] = {0};
  int encoded_size = regAccept->encode2buffer(buffer, 1024);
  print_buffer("amf_n1", "Registration-Accept Message Buffer", buffer,
               encoded_size);
  if (!encoded_size) {
    Logger::nas_mm().error("Encode Registration-Accept message error");
    return;
  } else {
    delete regAccept;
  }
  nas_secu_ctx *secu = nc.get()->security_ctx;
  // protect nas message
  bstring protectedNas;
  encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
                               NAS_MESSAGE_DOWNLINK, buffer, encoded_size,
                               protectedNas);

  string supi = "imsi-" + nc.get()->imsi;
  Logger::amf_n1().debug("Key for pdu session context SUPI (%s)", supi.c_str());
  std::shared_ptr<pdu_session_context> psc;
3615 3616 3617 3618 3619 3620 3621 3622

  //***************************stateless
  pdu_session_context *psc1 = new pdu_session_context();
  nlohmann::json udsf_response;
  std::string udsf_url = "http://10.112.202.24:7123/nudsf-dr/v1/amfdata/" + std::string("pdu_session_context/records/") + supi ;
  if(!amf_n2_inst->curl_http_client_udsf(udsf_url,"","GET",udsf_response)){
    Logger::amf_n2().error("No existing pdu_session_context with assoc_id ");
    return;
3623
  }
3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634
  Logger::amf_n2().debug("udsf_response: %s", udsf_response.dump().c_str());
  psc1->pdu_session_context_from_json(udsf_response);
  psc = std::shared_ptr<pdu_session_context>(psc1);
  //***************************stateless

  // if (amf_n11_inst->is_supi_to_pdu_ctx(supi)) {
  //   psc = amf_n11_inst->supi_to_pdu_ctx(supi);
  // } else {
  //   Logger::amf_n1().error("Cannot get pdu_session_context with SUPI (%s)",
  //                          supi.c_str());
  // }
3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718

  itti_dl_nas_transport *itti_msg =
      new itti_dl_nas_transport(TASK_AMF_N1, TASK_AMF_N2);
  itti_msg->ran_ue_ngap_id = nc.get()->ran_ue_ngap_id;
  itti_msg->amf_ue_ngap_id = nc.get()->amf_ue_ngap_id;
  itti_msg->nas = protectedNas;
  std::shared_ptr<itti_dl_nas_transport> i =
      std::shared_ptr<itti_dl_nas_transport>(itti_msg);
  int ret = itti_inst->send_msg(i);
  if (0 != ret) {
    Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2",
                           i->get_msg_name());
  }
}
//------------------------------------------------------------------------------
void amf_n1::run_periodic_registration_update_procedure(
    std::shared_ptr<nas_context> nc,bstring& nas_msg) {
  // decoding REGISTRATION request
  RegistrationRequest *regReq = new RegistrationRequest();
  regReq->decodefrombuffer(nullptr, (uint8_t *)bdata(nas_msg), blength(nas_msg));
  bdestroy(nas_msg); // free buffer

  // 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);
  regAccept->setT3512_Value(0x5, 0x1e);

  std::vector<p_tai_t> tai_list;
  p_tai_t item0;
  item0.type = 0x00;
  nas_plmn_t plmn;
  plmn.mcc = amf_cfg.plmn_list[0].mcc;
  plmn.mnc = amf_cfg.plmn_list[0].mnc;
  item0.plmn_list.push_back(plmn);
  item0.tac_list.push_back(amf_cfg.plmn_list[0].tac);
  tai_list.push_back(item0);
  regAccept->setTaiList(tai_list);
//
//  std::vector<struct SNSSAI_s> nssai;
//  SNSSAI_t snssai;
//  snssai.sst = 0;
//  snssai.sd = -1;
//  snssai.mHplmnSst = -1;
//  snssai.mHplmnSd = -1;
//  nssai.push_back(snssai);
//  regAccept->setALLOWED_NSSAI(nssai);

  uint16_t pdu_session_status = 0xffff;
  pdu_session_status = regReq->getPduSessionStatus();
  if (pdu_session_status == 0x0000) {
      regAccept->setPDU_session_status(0x0000);
  } else {
      regAccept->setPDU_session_status(pdu_session_status);
      Logger::amf_n1().debug("setting pdu session status 0x%02x",
                             htonl(pdu_session_status));
      // serApt->setPDU_session_status(0x2000);
  }
  delete regReq;

  regAccept->set_5GS_Network_Feature_Support(0x01, 0x00);
  uint8_t buffer[1024] = {0};
  int encoded_size = regAccept->encode2buffer(buffer, 1024);
  print_buffer("amf_n1", "Registration-Accept Message Buffer", buffer,
               encoded_size);
  if (!encoded_size) {
    Logger::nas_mm().error("Encode Registration-Accept message error");
    return;
  } else {
    delete regAccept;
  }
  nas_secu_ctx *secu = nc.get()->security_ctx;
  // protect nas message
  bstring protectedNas;
  encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
                               NAS_MESSAGE_DOWNLINK, buffer, encoded_size,
                               protectedNas);

  string supi = "imsi-" + nc.get()->imsi;
  Logger::amf_n1().debug("Key for pdu session context SUPI (%s)", supi.c_str());
  std::shared_ptr<pdu_session_context> psc;
3719 3720 3721 3722 3723 3724 3725 3726
  
  //***************************stateless
  pdu_session_context *psc1 = new pdu_session_context();
  nlohmann::json udsf_response;
  std::string udsf_url = "http://10.112.202.24:7123/nudsf-dr/v1/amfdata/" + std::string("pdu_session_context/records/") + supi ;
  if(!amf_n2_inst->curl_http_client_udsf(udsf_url,"","GET",udsf_response)){
    Logger::amf_n2().error("No existing pdu_session_context with assoc_id ");
    return;
3727
  }
3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738
  Logger::amf_n2().debug("udsf_response: %s", udsf_response.dump().c_str());
  psc1->pdu_session_context_from_json(udsf_response);
  psc = std::shared_ptr<pdu_session_context>(psc1);
  //***************************stateless

  // if (amf_n11_inst->is_supi_to_pdu_ctx(supi)) {
  //   psc = amf_n11_inst->supi_to_pdu_ctx(supi);
  // } else {
  //   Logger::amf_n1().error("Cannot get pdu_session_context with SUPI (%s)",
  //                          supi.c_str());
  // }
3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755

  itti_dl_nas_transport *itti_msg =
      new itti_dl_nas_transport(TASK_AMF_N1, TASK_AMF_N2);
  itti_msg->ran_ue_ngap_id = nc.get()->ran_ue_ngap_id;
  itti_msg->amf_ue_ngap_id = nc.get()->amf_ue_ngap_id;
  itti_msg->nas = protectedNas;
  std::shared_ptr<itti_dl_nas_transport> i =
      std::shared_ptr<itti_dl_nas_transport>(itti_msg);
  int ret = itti_inst->send_msg(i);
  if (0 != ret) {
    Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2",
                           i->get_msg_name());
  }
}



3756
//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
3757 3758 3759 3760
void amf_n1::set_5gmm_state(std::shared_ptr<nas_context> nc,
                            _5gmm_state_t state) {
  Logger::amf_n1().debug("Set 5GMM state to %s",
                         _5gmm_state_e2str[state].c_str());
3761 3762
  std::unique_lock lock(m_nas_context);
  nc.get()->_5gmm_state = state;
Niuhaiwen's avatar
Niuhaiwen committed
3763
  // TODO:
3764 3765 3766
}

//------------------------------------------------------------------------------
Niuhaiwen's avatar
Niuhaiwen committed
3767 3768
void amf_n1::get_5gmm_state(std::shared_ptr<nas_context> nc,
                            _5gmm_state_t &state) {
Niuhaiwen's avatar
Niuhaiwen committed
3769
  // TODO:
3770 3771
  state = nc.get()->_5gmm_state;
}