smf_app.cpp 79 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
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
6
7
8
 * the OAI Public License, Version 1.1  (the "License"); you may not use this
 * file except in compliance with the License. You may obtain a copy of the
 * License at
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 *      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 smf_app.cpp
23
24
25
26
27
 \brief
 \author  Lionel GAUTHIER, Tien-Thinh NGUYEN
 \company Eurecom
 \date 2019
 \email: lionel.gauthier@eurecom.fr, tien-thinh.nguyen@eurecom.fr
28
 */
29

30
#include "smf_app.hpp"
31

32
#include <boost/uuid/random_generator.hpp>
33
#include <boost/algorithm/string.hpp>
34
#include <boost/uuid/uuid_io.hpp>
35
#include <cstdlib>
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
36
37
#include <iostream>
#include <stdexcept>
38

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
39
40
41
42
#include "3gpp_24.007.h"
#include "3gpp_24.501.h"
#include "3gpp_29.500.h"
#include "3gpp_29.502.h"
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
43
#include "3gpp_conversions.hpp"
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
44
45
46
47
48
49
#include "ProblemDetails.h"
#include "RefToBinaryData.h"
#include "SmContextCreateError.h"
#include "SmContextCreatedData.h"
#include "SmContextMessage.h"
#include "SmContextUpdateError.h"
50
51
52
53
#include "async_shell_cmd.hpp"
#include "common_defs.h"
#include "conversions.hpp"
#include "itti.hpp"
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
54
#include "itti_msg_nx.hpp"
55
#include "logger.hpp"
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
56
#include "pfcp.hpp"
57
#include "smf.h"
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
58
#include "smf_event.hpp"
59
#include "smf_n1.hpp"
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
60
#include "smf_sbi.hpp"
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
61
62
63
#include "smf_n4.hpp"
#include "smf_paa_dynamic.hpp"
#include "string.hpp"
64

65
extern "C" {
66
#include "dynamic_memory_check.h"
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
67
#include "nas_message.h"
68
69
70
71
}

using namespace smf;

72
73
extern util::async_shell_cmd* async_shell_cmd_inst;
extern smf_app* smf_app_inst;
74
extern smf_config smf_cfg;
75
smf_n4* smf_n4_inst   = nullptr;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
76
smf_sbi* smf_sbi_inst = nullptr;
77
extern itti_mw* itti_inst;
78

79
void smf_app_task(void*);
80
81

//------------------------------------------------------------------------------
82
int smf_app::apply_config(const smf_config& cfg) {
83
84
  Logger::smf_app().info("Apply config...");

85
  paa_t paa = {};
86
87
88
  for (int ia = 0; ia < cfg.num_dnn; ia++) {
    if (cfg.dnn[ia].pool_id_iv4 >= 0) {
      int pool_id = cfg.dnn[ia].pool_id_iv4;
89
      int range   = be32toh(cfg.ue_pool_range_high[pool_id].s_addr) -
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
90
91
92
93
                  be32toh(cfg.ue_pool_range_low[pool_id].s_addr);
      paa_dynamic::get_instance().add_pool(
          cfg.dnn[ia].dnn, pool_id, cfg.ue_pool_range_low[pool_id], range);
      // TODO: check with dnn_label
94
      Logger::smf_app().info("Applied config %s", cfg.dnn[ia].dnn.c_str());
95
      paa.ipv4_address = cfg.ue_pool_range_low[pool_id];
96
    }
97
98
    if (cfg.dnn[ia].pool_id_iv6 >= 0) {
      int pool_id = cfg.dnn[ia].pool_id_iv6;
99
100
101
      paa_dynamic::get_instance().add_pool(
          cfg.dnn[ia].dnn, pool_id, cfg.paa_pool6_prefix[pool_id],
          cfg.paa_pool6_prefix_len[pool_id]);
102
103
      paa.ipv6_address = cfg.paa_pool6_prefix[pool_id];

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
104
      // TODO: check with dnn_label
105
106
      Logger::smf_app().info(
          "Applied config for IPv6 %s", cfg.dnn[ia].dnn.c_str());
107
108
109
110
    }
  }

  Logger::smf_app().info("Applied config");
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
111
  return RETURNok;
112
113
114
115
116
}

//------------------------------------------------------------------------------
uint64_t smf_app::generate_seid() {
  std::unique_lock<std::mutex> ls(m_seid_n4_generator);
117
  uint64_t seid = ++seid_n4_generator;
118
  while ((is_seid_n4_exist(seid)) || (seid == UNASSIGNED_SEID)) {
119
    seid = ++seid_n4_generator;
120
121
122
123
124
125
  }
  set_seid_n4.insert(seid);
  ls.unlock();
  return seid;
}

126
//------------------------------------------------------------------------------
127
void smf_app::generate_smf_context_ref(std::string& smf_ref) {
128
129
130
131
  smf_ref = std::to_string(sm_context_ref_generator.get_uid());
}

//------------------------------------------------------------------------------
132
scid_t smf_app::generate_smf_context_ref() {
133
134
135
  return sm_context_ref_generator.get_uid();
}

136
//------------------------------------------------------------------------------
137
void smf_app::generate_ev_subscription_id(std::string& sub_id) {
138
139
140
141
142
143
144
145
  sub_id = std::to_string(evsub_id_generator.get_uid());
}

//------------------------------------------------------------------------------
evsub_id_t smf_app::generate_ev_subscription_id() {
  return evsub_id_generator.get_uid();
}

146
//------------------------------------------------------------------------------
147
bool smf_app::is_seid_n4_exist(const uint64_t& seid) const {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
148
  return bool{set_seid_n4.count(seid) > 0};
149
150
151
}

//------------------------------------------------------------------------------
152
void smf_app::free_seid_n4(const uint64_t& seid) {
153
  std::unique_lock<std::mutex> ls(m_seid_n4_generator);
154
  set_seid_n4.erase(seid);
155
  ls.unlock();
156
157
158
}

//------------------------------------------------------------------------------
159
160
void smf_app::set_seid_2_smf_context(
    const seid_t& seid, std::shared_ptr<smf_context>& pc) {
161
162
163
164
165
  std::unique_lock lock(m_seid2smf_context);
  seid2smf_context[seid] = pc;
}

//------------------------------------------------------------------------------
166
167
bool smf_app::seid_2_smf_context(
    const seid_t& seid, std::shared_ptr<smf_context>& pc) const {
168
  std::shared_lock lock(m_seid2smf_context);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
169
170
  std::map<seid_t, std::shared_ptr<smf_context>>::const_iterator it =
      seid2smf_context.find(seid);
171
172
173
174
175
176
177
178
  if (it != seid2smf_context.end()) {
    pc = it->second;
    return true;
  }
  return false;
}

//------------------------------------------------------------------------------
179
void smf_app::delete_smf_context(std::shared_ptr<smf_context> spc) {
180
  supi64_t supi64 = smf_supi_to_u64(spc.get()->get_supi());
181
182
183
184
185
  std::unique_lock lock(m_supi2smf_context);
  supi2smf_context.erase(supi64);
}

//------------------------------------------------------------------------------
186
void smf_app::restore_n4_sessions(const seid_t& seid) const {
187
  std::shared_lock lock(m_seid2smf_context);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
188
  // TODO
189
190
191
}

//------------------------------------------------------------------------------
192
void smf_app_task(void*) {
193
194
195
196
197
  const task_id_t task_id = TASK_SMF_APP;
  itti_inst->notify_task_ready(task_id);

  do {
    std::shared_ptr<itti_msg> shared_msg = itti_inst->receive_msg(task_id);
198
    auto* msg                            = shared_msg.get();
199
    switch (msg->msg_type) {
200
      case N4_SESSION_ESTABLISHMENT_RESPONSE:
201
202
        if (itti_n4_session_establishment_response* m =
                dynamic_cast<itti_n4_session_establishment_response*>(msg)) {
203
204
205
          smf_app_inst->handle_itti_msg(std::ref(*m));
        }
        break;
206

207
      case N4_SESSION_MODIFICATION_RESPONSE:
208
209
        if (itti_n4_session_modification_response* m =
                dynamic_cast<itti_n4_session_modification_response*>(msg)) {
210
211
212
          smf_app_inst->handle_itti_msg(std::ref(*m));
        }
        break;
213

214
      case N4_SESSION_DELETION_RESPONSE:
215
216
        if (itti_n4_session_deletion_response* m =
                dynamic_cast<itti_n4_session_deletion_response*>(msg)) {
217
218
219
          smf_app_inst->handle_itti_msg(std::ref(*m));
        }
        break;
220

221
222
223
224
225
226
227
228
229
230
231
      case N4_SESSION_REPORT_REQUEST:
        smf_app_inst->handle_itti_msg(
            std::static_pointer_cast<itti_n4_session_report_request>(
                shared_msg));
        break;

      case N4_NODE_FAILURE:
        smf_app_inst->handle_itti_msg(
            std::static_pointer_cast<itti_n4_node_failure>(shared_msg));
        break;

232
      case N11_SESSION_N1N2_MESSAGE_TRANSFER_RESPONSE_STATUS:
233
234
        if (itti_n11_n1n2_message_transfer_response_status* m =
                dynamic_cast<itti_n11_n1n2_message_transfer_response_status*>(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
235
                    msg)) {
236
237
238
          smf_app_inst->handle_itti_msg(std::ref(*m));
        }
        break;
239

240
      case N11_SESSION_UPDATE_PDU_SESSION_STATUS:
241
242
        if (itti_n11_update_pdu_session_status* m =
                dynamic_cast<itti_n11_update_pdu_session_status*>(msg)) {
243
244
245
246
          smf_app_inst->handle_itti_msg(std::ref(*m));
        }
        break;

247
      case N11_SESSION_CREATE_SM_CONTEXT_RESPONSE:
248
249
        if (itti_n11_create_sm_context_response* m =
                dynamic_cast<itti_n11_create_sm_context_response*>(msg)) {
250
251
252
253
254
          smf_app_inst->handle_itti_msg(std::ref(*m));
        }
        break;

      case N11_SESSION_UPDATE_SM_CONTEXT_RESPONSE:
255
256
        if (itti_n11_update_sm_context_response* m =
                dynamic_cast<itti_n11_update_sm_context_response*>(msg)) {
257
258
259
260
261
          smf_app_inst->handle_itti_msg(std::ref(*m));
        }
        break;

      case N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE:
262
263
        if (itti_n11_release_sm_context_response* m =
                dynamic_cast<itti_n11_release_sm_context_response*>(msg)) {
264
265
266
267
          smf_app_inst->handle_itti_msg(std::ref(*m));
        }
        break;

268
      case N11_REGISTER_NF_INSTANCE_RESPONSE:
269
270
        if (itti_n11_register_nf_instance_response* m =
                dynamic_cast<itti_n11_register_nf_instance_response*>(msg)) {
271
272
273
274
          smf_app_inst->handle_itti_msg(std::ref(*m));
        }
        break;

275
      case N11_UPDATE_NF_INSTANCE_RESPONSE:
276
277
        if (itti_n11_update_nf_instance_response* m =
                dynamic_cast<itti_n11_update_nf_instance_response*>(msg)) {
278
279
280
281
          smf_app_inst->handle_itti_msg(std::ref(*m));
        }
        break;

282
      case TIME_OUT:
283
        if (itti_msg_timeout* to = dynamic_cast<itti_msg_timeout*>(msg)) {
284
285
286
287
288
          Logger::smf_app().info("TIME-OUT event timer id %d", to->timer_id);
          switch (to->arg1_user) {
            case TASK_SMF_APP_TRIGGER_T3591:
              smf_app_inst->timer_t3591_timeout(to->timer_id, to->arg2_user);
              break;
289
            case TASK_SMF_APP_TIMEOUT_NRF_HEARTBEAT:
290
291
              smf_app_inst->timer_nrf_heartbeat_timeout(
                  to->timer_id, to->arg2_user);
292
              break;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
293
            case TASK_SMF_APP_TIMEOUT_NRF_DEREGISTRATION:
294
295
              smf_app_inst->timer_nrf_deregistration(
                  to->timer_id, to->arg2_user);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
296
              break;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
297
            default:;
298
          }
299
        }
300
        break;
301

302
      case TERMINATE:
303
304
        if (itti_msg_terminate* terminate =
                dynamic_cast<itti_msg_terminate*>(msg)) {
305
306
307
          Logger::smf_app().info("Received terminate message");
          return;
        }
308
309
        break;

310
311
      case HEALTH_PING:
        break;
312

313
314
      default:
        Logger::smf_app().info("no handler for msg type %d", msg->msg_type);
315
316
317
318
319
    }
  } while (true);
}

//------------------------------------------------------------------------------
320
smf_app::smf_app(const std::string& config_file)
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
321
322
323
324
325
326
    : m_seid2smf_context(),
      m_supi2smf_context(),
      m_scid2smf_context(),
      m_sm_context_create_promises(),
      m_sm_context_update_promises(),
      m_sm_context_release_promises() {
327
328
  Logger::smf_app().startup("Starting...");

329
330
  supi2smf_context  = {};
  set_seid_n4       = {};
331
  seid_n4_generator = 0;
332

333
  apply_config(smf_cfg);
334

335
336
337
  if (itti_inst->create_task(TASK_SMF_APP, smf_app_task, nullptr)) {
    Logger::smf_app().error("Cannot create task TASK_SMF_APP");
    throw std::runtime_error("Cannot create task TASK_SMF_APP");
338
339
340
  }

  try {
341
    smf_n4_inst  = new smf_n4();
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
342
    smf_sbi_inst = new smf_sbi();
343
  } catch (std::exception& e) {
344
    Logger::smf_app().error("Cannot create SMF_APP: %s", e.what());
345
346
347
    throw;
  }

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
348
349
  // TODO: should be done when SMF select UPF for a particular UE (should be
  // verified)
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
350
  for (std::vector<pfcp::node_id_t>::const_iterator it = smf_cfg.upfs.begin();
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
351
       it != smf_cfg.upfs.end(); ++it) {
352
353
354
    start_upf_association(*it);
  }

355
  if (smf_cfg.discover_upf) {
356
357
    // Trigger NFStatusNotify subscription to be noticed when a new UPF becomes
    // available (if this option is enabled)
358
359
360
361
362
    trigger_upf_status_notification_subscribe();
  }

  // Register to NRF (if this option is enabled)
  if (smf_cfg.register_nrf) {
363
364
    unsigned int microsecond = 10000;  // 10ms
    usleep(microsecond);
365
    register_to_nrf();
366
  }
367

368
  Logger::smf_app().startup("Started");
369
370
}

371
//------------------------------------------------------------------------------
372
void smf_app::start_upf_association(const pfcp::node_id_t& node_id) {
373
  std::time_t time_epoch = std::time(nullptr);
374
  uint64_t tv_ntp        = time_epoch + SECONDS_SINCE_FIRST_EPOCH;
375
376

  pfcp_associations::get_instance().add_peer_candidate_node(node_id);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
377
378
379
  std::shared_ptr<itti_n4_association_setup_request> n4_asc =
      std::shared_ptr<itti_n4_association_setup_request>(
          new itti_n4_association_setup_request(TASK_SMF_APP, TASK_SMF_N4));
380

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
381
  // n4_asc->trxn_id = smf_n4_inst->generate_trxn_id();
382
  pfcp::cp_function_features_s cp_function_features;
383
  cp_function_features      = {};
384
385
386
  cp_function_features.load = 1;
  cp_function_features.ovrl = 1;

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
387
  pfcp::node_id_t this_node_id = {};
388
389
  if (smf_cfg.get_pfcp_node_id(this_node_id) == RETURNok) {
    n4_asc->pfcp_ies.set(this_node_id);
390
    pfcp::recovery_time_stamp_t r = {.recovery_time_stamp = (uint32_t) tv_ntp};
391
392
393
394
    n4_asc->pfcp_ies.set(r);

    n4_asc->pfcp_ies.set(cp_function_features);
    if (node_id.node_id_type == pfcp::NODE_ID_TYPE_IPV4_ADDRESS) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
395
396
      n4_asc->r_endpoint =
          endpoint(node_id.u1.ipv4_address, pfcp::default_port);
397
398
      int ret = itti_inst->send_msg(n4_asc);
      if (RETURNok != ret) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
399
400
401
        Logger::smf_app().error(
            "Could not send ITTI message %s to task TASK_SMF_N4",
            n4_asc.get()->get_msg_name());
402
403
      }
    } else {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
404
      Logger::smf_app().warn("Start_association() node_id IPV6, FQDN!");
405
406
407
408
    }
  }
}

409
410
411
412
413
414
//------------------------------------------------------------------------------
void smf_app::start_upf_association(
    const pfcp::node_id_t& node_id, const upf_profile& profile) {
  std::time_t time_epoch = std::time(nullptr);
  uint64_t tv_ntp        = time_epoch + SECONDS_SINCE_FIRST_EPOCH;

415
  pfcp_associations::get_instance().add_peer_candidate_node(node_id, profile);
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
445
446
447
  std::shared_ptr<itti_n4_association_setup_request> n4_asc =
      std::shared_ptr<itti_n4_association_setup_request>(
          new itti_n4_association_setup_request(TASK_SMF_APP, TASK_SMF_N4));

  // n4_asc->trxn_id = smf_n4_inst->generate_trxn_id();
  pfcp::cp_function_features_s cp_function_features;
  cp_function_features      = {};
  cp_function_features.load = 1;
  cp_function_features.ovrl = 1;

  pfcp::node_id_t this_node_id = {};
  if (smf_cfg.get_pfcp_node_id(this_node_id) == RETURNok) {
    n4_asc->pfcp_ies.set(this_node_id);
    pfcp::recovery_time_stamp_t r = {.recovery_time_stamp = (uint32_t) tv_ntp};
    n4_asc->pfcp_ies.set(r);

    n4_asc->pfcp_ies.set(cp_function_features);
    if (node_id.node_id_type == pfcp::NODE_ID_TYPE_IPV4_ADDRESS) {
      n4_asc->r_endpoint =
          endpoint(node_id.u1.ipv4_address, pfcp::default_port);
      int ret = itti_inst->send_msg(n4_asc);
      if (RETURNok != ret) {
        Logger::smf_app().error(
            "Could not send ITTI message %s to task TASK_SMF_N4",
            n4_asc.get()->get_msg_name());
      }
    } else {
      Logger::smf_app().warn("Start_association() node_id IPV6, FQDN!");
    }
  }
}

448
//------------------------------------------------------------------------------
449
void smf_app::handle_itti_msg(itti_n4_session_establishment_response& seresp) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
450
  std::shared_ptr<smf_context> pc = {};
451
452
453
  if (seid_2_smf_context(seresp.seid, pc)) {
    pc.get()->handle_itti_msg(seresp);
  } else {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
454
    Logger::smf_app().debug(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
455
456
        "Received N4 Session Establishment Response seid" TEID_FMT
        "  pfcp_tx_id %" PRIX64 ", smf_context not found, discarded!",
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
457
        seresp.seid, seresp.trxn_id);
458
459
460
461
  }
}

//------------------------------------------------------------------------------
462
void smf_app::handle_itti_msg(itti_n4_session_modification_response& smresp) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
463
  std::shared_ptr<smf_context> pc = {};
464
465
466
  if (seid_2_smf_context(smresp.seid, pc)) {
    pc.get()->handle_itti_msg(smresp);
  } else {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
467
    Logger::smf_app().debug(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
468
469
        "Received N4 Session Modification Response seid" TEID_FMT
        "  pfcp_tx_id %" PRIX64 ", smf_context not found, discarded!",
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
470
        smresp.seid, smresp.trxn_id);
471
472
473
474
  }
}

//------------------------------------------------------------------------------
475
void smf_app::handle_itti_msg(itti_n4_session_deletion_response& smresp) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
476
  std::shared_ptr<smf_context> pc = {};
477
478
479
  if (seid_2_smf_context(smresp.seid, pc)) {
    pc.get()->handle_itti_msg(smresp);

480
    if (pc->get_number_dnn_contexts() == 0) {
481
482
483
      delete_smf_context(pc);
    }
  } else {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
484
    Logger::smf_app().debug(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
485
486
        "Received N4 Session Deletion Response seid" TEID_FMT
        "  pfcp_tx_id %" PRIX64 ", smf_context not found, discarded!",
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
487
        smresp.seid, smresp.trxn_id);
488
489
490
491
  }
}

//------------------------------------------------------------------------------
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
492
493
void smf_app::handle_itti_msg(
    std::shared_ptr<itti_n4_session_report_request> snr) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
494
  std::shared_ptr<smf_context> pc = {};
495
496
497
  if (seid_2_smf_context(snr->seid, pc)) {
    pc.get()->handle_itti_msg(snr);
  } else {
498
499
500
501
    Logger::smf_app().debug(
        "Received N4 Session Report Request seid" TEID_FMT
        "  pfcp_tx_id %" PRIX64 ", smf_context not found, discarded!",
        snr->seid, snr->trxn_id);
502
503
504
  }
}

505
506
507
508
509
510
511
512
513
514
515
//------------------------------------------------------------------------------
void smf_app::handle_itti_msg(std::shared_ptr<itti_n4_node_failure> snf) {
  pfcp::node_id_t node_id = snf->node_id;

  for (auto it : scid2smf_context) {
    if (it.second->upf_node_id == node_id) {
      supi64_t supi64 = smf_supi_to_u64(it.second->supi);
      Logger::smf_app().debug(
          "Remove the associated PDU session (SUPI " SUPI_64_FMT
          ", PDU Sessin Id %d)",
          supi64, it.second->pdu_session_id);
516
      // TODO: remove the session
517
518
519
520
    }
  }
}

521
//------------------------------------------------------------------------------
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
522
void smf_app::handle_itti_msg(
523
    itti_n11_n1n2_message_transfer_response_status& m) {
524
  Logger::smf_app().info("Process N1N2MessageTransfer Response");
525
526

  switch (m.procedure_type) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
527
528
529
    case session_management_procedures_type_e::
        PDU_SESSION_ESTABLISHMENT_UE_REQUESTED: {
      // Update PDU Session accordingly
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
530
      Logger::smf_app().info("PDU_SESSION_ESTABLISHMENT_UE_REQUESTED");
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
531
532
533
534
535
536
537
538
      pdu_session_status_e status = {
          pdu_session_status_e::PDU_SESSION_INACTIVE};
      upCnx_state_e state = {upCnx_state_e::UPCNX_STATE_DEACTIVATED};

      if ((static_cast<http_response_codes_e>(m.response_code) ==
           http_response_codes_e::HTTP_RESPONSE_CODE_OK) or
          (static_cast<http_response_codes_e>(m.response_code) ==
           http_response_codes_e::HTTP_RESPONSE_CODE_ACCEPTED)) {
539
540
541
542
        if (m.msg_type == PDU_SESSION_ESTABLISHMENT_REJECT) {
          status = pdu_session_status_e::PDU_SESSION_INACTIVE;
        } else if (m.msg_type == PDU_SESSION_ESTABLISHMENT_ACCEPT) {
          status = pdu_session_status_e::PDU_SESSION_ESTABLISHMENT_PENDING;
543
          state  = upCnx_state_e::UPCNX_STATE_ACTIVATING;
544
545
546
547
        }
        update_pdu_session_status(m.scid, status);
        update_pdu_session_upCnx_state(m.scid, state);
        Logger::smf_app().debug(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
548
549
            "Got successful response from AMF (response code %d), set session "
            "status to %s",
550
            m.response_code,
551
            pdu_session_status_e2str.at(static_cast<int>(status)).c_str());
552
      } else {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
553
        // TODO:
554
555
        Logger::smf_app().debug(
            "Got response from AMF (response code %d)", m.response_code);
556
      }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
557
    } break;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
558

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
559
560
    case session_management_procedures_type_e::
        SERVICE_REQUEST_NETWORK_TRIGGERED: {
561
562
563
      Logger::smf_app().debug(
          "Got response from AMF (response code %d) with cause %s",
          m.response_code, m.cause.c_str());
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
564
565
566
567
      if ((static_cast<http_response_codes_e>(m.response_code) !=
           http_response_codes_e::HTTP_RESPONSE_CODE_OK) and
          (static_cast<http_response_codes_e>(m.response_code) !=
           http_response_codes_e::HTTP_RESPONSE_CODE_ACCEPTED)) {
568
        Logger::smf_app().debug("Send failure indication to UPF");
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
569
570
        // TODO: to be completed
        pfcp::node_id_t up_node_id = {};
571
572
573
574
575
576
577
578
579
        // Get UPF node
        std::shared_ptr<smf_context_ref> scf = {};
        if (smf_app_inst->is_scid_2_smf_context(m.scid)) {
          scf        = scid_2_smf_context(m.scid);
          up_node_id = scf.get()->upf_node_id;
        } else {
          Logger::smf_app().warn(
              "SM Context associated with this id " SCID_FMT " does not exit!",
              m.scid);
580
581
582
          return;
        }

583
        itti_n4_session_failure_indication* itti_n4 =
584
            new itti_n4_session_failure_indication(TASK_SMF_APP, TASK_SMF_N4);
585
        itti_n4->seid    = m.seid;
586
        itti_n4->trxn_id = m.trxn_id;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
587
588
589
590
591
        itti_n4->r_endpoint =
            endpoint(up_node_id.u1.ipv4_address, pfcp::default_port);
        std::shared_ptr<itti_n4_session_failure_indication>
            itti_n4_failure_indication =
                std::shared_ptr<itti_n4_session_failure_indication>(itti_n4);
592

593
594
595
        Logger::smf_app().info(
            "Sending ITTI message %s to task TASK_SMF_N4",
            itti_n4->get_msg_name());
596
597
598
599
600
601
602
        int ret = itti_inst->send_msg(itti_n4_failure_indication);
        if (RETURNok != ret) {
          Logger::smf_app().error(
              "Could not send ITTI message %s to task TASK_SMF_N4",
              itti_n4->get_msg_name());
          return;
        }
603
      }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
604
    } break;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
605

606
    default: {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
607
      Logger::smf_app().warn("Unknown procedure type %d", m.procedure_type);
608
609
610
611
612
    }
  }
}

//------------------------------------------------------------------------------
613
void smf_app::handle_itti_msg(itti_n11_update_pdu_session_status& m) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
614
615
  Logger::smf_app().info(
      "Set PDU Session Status to %s",
616
617
      pdu_session_status_e2str.at(static_cast<int>(m.pdu_session_status))
          .c_str());
618
619
620
  update_pdu_session_status(m.scid, m.pdu_session_status);
}

621
//------------------------------------------------------------------------------
622
void smf_app::handle_itti_msg(itti_n11_create_sm_context_response& m) {
623
624
  Logger::smf_app().debug(
      "PDU Session Create SM Context: Set promise with ID %d to ready", m.pid);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
625
  pdu_session_create_sm_context_response sm_context_response = {};
626
  std::unique_lock lock(m_sm_context_create_promises);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
627
  if (sm_context_create_promises.count(m.pid) > 0) {
628
    sm_context_create_promises[m.pid]->set_value(m.res);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
629
    // Remove this promise from list
630
631
    sm_context_create_promises.erase(m.pid);
  }
632
633
634
}

//------------------------------------------------------------------------------
635
void smf_app::handle_itti_msg(itti_n11_update_sm_context_response& m) {
636
637
  Logger::smf_app().debug(
      "PDU Session Update SM Context: Set promise with ID %d to ready", m.pid);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
638
  pdu_session_update_sm_context_response sm_context_response = {};
639
  std::unique_lock lock(m_sm_context_update_promises);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
640
  if (sm_context_update_promises.count(m.pid) > 0) {
641
    sm_context_update_promises[m.pid]->set_value(m.res);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
642
    // Remove this promise from list
643
644
    sm_context_update_promises.erase(m.pid);
  }
645
646
647
}

//------------------------------------------------------------------------------
648
void smf_app::handle_itti_msg(itti_n11_release_sm_context_response& m) {
649
650
  Logger::smf_app().debug(
      "PDU Session Release SM Context: Set promise with ID %d to ready", m.pid);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
651
  pdu_session_release_sm_context_response sm_context_response = {};
652
  std::unique_lock lock(m_sm_context_release_promises);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
653
  if (sm_context_release_promises.count(m.pid) > 0) {
654
    sm_context_release_promises[m.pid]->set_value(m.res);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
655
    // Remove this promise from list
656
657
    sm_context_release_promises.erase(m.pid);
  }
658
659
}

660
//------------------------------------------------------------------------------
661
void smf_app::handle_itti_msg(itti_n11_register_nf_instance_response& r) {
662
  Logger::smf_app().debug("Handle NF Instance Registration response");
663

664
  nf_instance_profile = r.profile;
665
  // Set heartbeat timer
666
  Logger::smf_app().debug(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
667
668
      "Set value of NRF Heartbeat timer to %d",
      r.profile.get_nf_heartBeat_timer());
669
670
671
672
  timer_nrf_heartbeat = itti_inst->timer_setup(
      r.profile.get_nf_heartBeat_timer(), 0, TASK_SMF_APP,
      TASK_SMF_APP_TIMEOUT_NRF_HEARTBEAT,
      0);  // TODO arg2_user
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
673

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
674
675
676
677
678
  /*  //Set timer to send NF Deregistration (for testing purpose)
    itti_inst->timer_setup(50, 0,
                               TASK_SMF_APP,
    TASK_SMF_APP_TIMEOUT_NRF_DEREGISTRATION, 0);  // TODO arg2_user
  */
679
680
681
}

//------------------------------------------------------------------------------
682
void smf_app::handle_itti_msg(itti_n11_update_nf_instance_response& u) {
683
684
  Logger::smf_app().debug("NF Update NF response");

685
686
687
  Logger::smf_app().debug(
      "Set NRF Heartbeat timer (%d)",
      nf_instance_profile.get_nf_heartBeat_timer());
688
689
690

  // Set heartbeat timer
  //  timer_nrf_heartbeat = itti_inst->timer_setup(
691
  //      nf_instance_profile.get_nf_heartBeat_timer(), 0, TASK_SMF_APP,
692
  //      TASK_SMF_APP_TIMEOUT_NRF_HEARTBEAT, 0); //TODO arg2_user
693
}
694

695
//------------------------------------------------------------------------------
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
696
697
698
void smf_app::handle_pdu_session_create_sm_context_request(
    std::shared_ptr<itti_n11_create_sm_context_request> smreq) {
  Logger::smf_app().info(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
699
700
      "Handle a PDU Session Create SM Context Request from an AMF (HTTP "
      "version %d)",
701
      smreq->http_version);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
702
703
  // handle PDU Session Create SM Context Request as specified in section 4.3.2
  // 3GPP TS 23.502
704
  std::string n1_sm_message, n1_sm_message_hex;
705
706
  nas_message_t decoded_nas_msg       = {};
  cause_value_5gsm_e cause_n1         = {cause_value_5gsm_e::CAUSE_0_UNKNOWN};
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
707
708
  pdu_session_type_t pdu_session_type = {.pdu_session_type =
                                             PDU_SESSION_TYPE_E_IPV4};
709

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
710
  // Step 1. Decode NAS and get the necessary information
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
711
712
  int decoder_rc = smf_n1::get_instance().decode_n1_sm_container(
      decoded_nas_msg, smreq->req.get_n1_sm_message());
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
713

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
714
  // Failed to decode, send reply to AMF with PDU Session Establishment Reject
715
  if (decoder_rc != RETURNok) {
716
    Logger::smf_app().warn("N1 SM container cannot be decoded correctly!");
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
717

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
718
    if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
719
720
            smreq->req, n1_sm_message,
            cause_value_5gsm_e::CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE)) {
721
      smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
722
723
724
725
726
      // trigger to send reply to AMF
      trigger_create_context_error_response(
          http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
          PDU_SESSION_APPLICATION_ERROR_N1_SM_ERROR, n1_sm_message_hex,
          smreq->pid);
727
    } else {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
728
      // trigger to send reply to AMF
729
730
731
732
      trigger_http_response(
          http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
          smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
    }
733
    return;
734
  }
735

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
736
737
  // Get necessary info from NAS
  xgpp_conv::sm_context_request_from_nas(decoded_nas_msg, smreq->req);
738

739
  pdu_session_type.pdu_session_type = smreq->req.get_pdu_session_type();
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
740
  // TODO: Support IPv4 only for now
741
742
  if (pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_IPV6) {
    cause_n1 = cause_value_5gsm_e::CAUSE_50_PDU_SESSION_TYPE_IPV4_ONLY_ALLOWED;
743
744
745
  } else if (
      (pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_ETHERNET) or
      (pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_UNSTRUCTURED)) {
746
747
    cause_n1 = cause_value_5gsm_e::CAUSE_28_UNKNOWN_PDU_SESSION_TYPE;
  }
748
749
750

  if ((pdu_session_type.pdu_session_type != PDU_SESSION_TYPE_E_IPV4) and
      (pdu_session_type.pdu_session_type != PDU_SESSION_TYPE_E_IPV4V6)) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
751
752
753
    // PDU Session Establishment Reject
    if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
            smreq->req, n1_sm_message, cause_n1)) {
754
      smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
755
756
757
758
759
      // trigger to send reply to AMF
      trigger_create_context_error_response(
          http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
          PDU_SESSION_APPLICATION_ERROR_PDUTYPE_DENIED, n1_sm_message_hex,
          smreq->pid);
760
761
762
763
764
    } else {
      trigger_http_response(
          http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
          smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
    }
765
    return;
766
767
  }

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
768
769
770
771
772
  // Get SUPI, SNSSAI
  supi_t supi             = smreq->req.get_supi();
  std::string supi_prefix = smreq->req.get_supi_prefix();
  supi64_t supi64         = smf_supi_to_u64(supi);
  snssai_t snssai         = smreq->req.get_snssai();
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
773
  Logger::smf_app().info(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
774
      "Handle a PDU Session Create SM Context Request message from AMF, "
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
775
776
      "SUPI " SUPI_64_FMT ", SNSSAI SST %d, SD %s",
      supi64, snssai.sST, snssai.sD.c_str());
777

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
778
  // Step 2. Verify Procedure transaction id, pdu session id, message type,
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
779
780
781
782
783
  // request type, etc.
  // Check PTI
  procedure_transaction_id_t pti = {
      .procedure_transaction_id =
          decoded_nas_msg.plain.sm.header.procedure_transaction_identity};
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
784
785
786
  if ((pti.procedure_transaction_id ==
       PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED) ||
      (pti.procedure_transaction_id > PROCEDURE_TRANSACTION_IDENTITY_LAST)) {
787
788
    Logger::smf_app().warn(
        "Invalid PTI value (pti = %d)", pti.procedure_transaction_id);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
789
790
    // PDU Session Establishment Reject including cause "#81 Invalid PTI value"
    // (section 7.3.1 @3GPP TS 24.501)
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
791
    if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
792
793
            smreq->req, n1_sm_message,
            cause_value_5gsm_e::CAUSE_81_INVALID_PTI_VALUE)) {
794
      smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
795
796
797
798
799
      // trigger to send reply to AMF
      trigger_create_context_error_response(
          http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
          PDU_SESSION_APPLICATION_ERROR_N1_SM_ERROR, n1_sm_message_hex,
          smreq->pid);
800
801
802
803
804
    } else {
      trigger_http_response(
          http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
          smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
    }
805
    return;
806
  }
807

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
808
809
810
  // Check pdu session id
  pdu_session_id_t pdu_session_id =
      decoded_nas_msg.plain.sm.header.pdu_session_identity;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
811
812
  if ((pdu_session_id == PDU_SESSION_IDENTITY_UNASSIGNED) ||
      (pdu_session_id > PDU_SESSION_IDENTITY_LAST)) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
813
    Logger::smf_app().warn("Invalid PDU Session ID value (%d)", pdu_session_id);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
814
815
    // section 7.3.2@3GPP TS 24.501; NAS N1 SM message: ignore the message
    // trigger to send reply to AMF
816
817
818
    trigger_http_response(
        http_status_code_e::HTTP_STATUS_CODE_406_NOT_ACCEPTABLE, smreq->pid,
        N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
819
    return;
820
821
  }

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
822
823
  // Check message type
  uint8_t message_type = decoded_nas_msg.plain.sm.header.message_type;
824
  if (message_type != PDU_SESSION_ESTABLISHMENT_REQUEST) {
825
826
    Logger::smf_app().warn(
        "Invalid message type (message type = %d)", message_type);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
827
828
829
830
    // PDU Session Establishment Reject
    //(24.501 (section 7.4)) implementation dependent->do similar to UE:
    // response with a 5GSM STATUS message including cause "#98 message type not
    // compatible with protocol state."
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
831
    if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
832
833
834
            smreq->req, n1_sm_message,
            cause_value_5gsm_e::
                CAUSE_98_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE)) {
835
      smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
836
837
838
839
840
      // trigger to send reply to AMF
      trigger_create_context_error_response(
          http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
          PDU_SESSION_APPLICATION_ERROR_N1_SM_ERROR, n1_sm_message_hex,
          smreq->pid);
841
842
843
844
845
    } else {
      trigger_http_response(
          http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
          smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
    }
846
    return;
847
848
  }

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
849
850
  // Check request type
  std::string request_type = smreq->req.get_request_type();
851
  if (request_type.compare("INITIAL_REQUEST") != 0) {
852
853
    Logger::smf_app().warn(
        "Invalid request type (request type = %s)", request_type.c_str());
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
854
    //"Existing PDU Session", AMF should use PDUSession_UpdateSMContext instead
855
    //(see step 3, section 4.3.2.2.1 @ 3GPP TS 23.502 v16.0.0) ignore the
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
856
    // message
857
    return;
858
859
  }

860
  // TODO:
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
861
862
863
864
865
866
  // If no DNN information from UE, set to default value
  std::string dnn = smreq->req.get_dnn();
  if (dnn.length() == 0) {
    dnn == smf_cfg.get_default_dnn();
  }

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
867
868
  // TODO: For the moment, not support PDU session authentication and
  // authorization by the external DN
869

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
870
  // Step 3. check if the DNN requested is valid
871
872
  if (not smf_cfg.is_dotted_dnn_handled(dnn, pdu_session_type)) {
    // Not a valid request...
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
873
    Logger::smf_app().warn(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
874
875
        "Received a PDU Session Create SM Context Request: unknown requested "
        "DNN %s, ignore message!",
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
876
        dnn.c_str());
877
    // PDU Session Establishment Reject
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
878
    if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
879
880
            smreq->req, n1_sm_message,
            cause_value_5gsm_e::CAUSE_27_MISSING_OR_UNKNOWN_DNN)) {
881
      smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
882
883
884
885
886
      // trigger to send reply to AMF
      trigger_create_context_error_response(
          http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
          PDU_SESSION_APPLICATION_ERROR_DNN_DENIED, n1_sm_message_hex,
          smreq->pid);
887
888
889
890
891
    } else {
      trigger_http_response(
          http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
          smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
    }
892
893
894
    return;
  }

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
895
896
  // Step 4. create a context for this supi if not existed, otherwise update
  std::shared_ptr<smf_context> sc = {};
897
  if (is_supi_2_smf_context(supi64)) {
898
899
    Logger::smf_app().debug(
        "Update SMF context with SUPI " SUPI_64_FMT "", supi64);
900
901
902
    sc = supi_2_smf_context(supi64);
    sc.get()->set_supi(supi);
  } else {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
903
904
    Logger::smf_app().debug(
        "Create a new SMF context with SUPI " SUPI_64_FMT "", supi64);
905
906
    sc = std::shared_ptr<smf_context>(new smf_context());
    sc.get()->set_supi(supi);
907
    sc.get()->set_supi_prefix(supi_prefix);
908
909
910
    set_supi_2_smf_context(supi64, sc);
  }

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
911
912
  // Step 5. Create/update context with dnn information
  std::shared_ptr<dnn_context> sd = {};
913
914

  if (!sc.get()->find_dnn_context(snssai, dnn, sd)) {
915
    if (nullptr == sd.get()) {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
916
      // create a new one and insert to the list
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
917
918
      Logger::smf_app().debug(
          "Create a DNN context and add to the SMF context");
919
920
      sd                   = std::shared_ptr<dnn_context>(new dnn_context(dnn));
      sd.get()->in_use     = true;