smf-http2-server.cpp 21.2 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
 *
 *      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
 */

22
23
24
25
26
27
28
29
/*! \file smf_http2-server.cpp
 \brief
 \author  Tien-Thinh NGUYEN
 \company Eurecom
 \date 2020
 \email: tien-thinh.nguyen@eurecom.fr
 */

30
31
32
33
34
35
36
37
38
39
40
41
42
#include "smf-http2-server.h"
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
#include <nlohmann/json.hpp>

#include "logger.hpp"
#include "smf_msg.hpp"
#include "itti_msg_n11.hpp"
#include "3gpp_29.502.h"
#include "mime_parser.hpp"
#include "3gpp_29.500.h"
43
#include "smf_config.hpp"
44
#include "smf.h"
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
45
#include "3gpp_conversions.hpp"
46
47
48
49
50

using namespace nghttp2::asio_http2;
using namespace nghttp2::asio_http2::server;
using namespace oai::smf_server::model;

51
52
extern smf::smf_config smf_cfg;

53
54
55
56
//------------------------------------------------------------------------------
void smf_http2_server::start() {
  boost::system::error_code ec;

57
  Logger::smf_api_server().info("HTTP2 server started");
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
  // Create SM Context Request
  server.handle(
      NSMF_PDU_SESSION_BASE + smf_cfg.sbi_api_version +
          NSMF_PDU_SESSION_SM_CONTEXT_CREATE_URL,
      [&](const request& request, const response& response) {
        request.on_data([&](const uint8_t* data, std::size_t len) {
          if (len > 0) {
            std::string msg((char*) data, len);
            Logger::smf_api_server().debug("");
            Logger::smf_api_server().info(
                "Received a SM context create request from AMF.");
            Logger::smf_api_server().debug(
                "Message content \n %s", msg.c_str());
            // check HTTP method manually
            if (request.method().compare("POST") != 0) {
              // error
              Logger::smf_api_server().debug(
                  "This method (%s) is not supported",
                  request.method().c_str());
              response.write_head(
                  http_status_code_e::HTTP_STATUS_CODE_405_METHOD_NOT_ALLOWED);
              response.end();
              return;
            }

            SmContextMessage smContextMessage       = {};
            SmContextCreateData smContextCreateData = {};

            // simple parser
            mime_parser sp = {};
88
89
90
91
92
93
94
            if (!sp.parse(msg)) {
              // send reply!!!
              response.write_head(
                  http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
              response.end();
              return;
            }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

            std::vector<mime_part> parts = {};
            sp.get_mime_parts(parts);
            uint8_t size = parts.size();
            Logger::smf_api_server().debug("Number of MIME parts %d", size);
            // at least 2 parts for Json data and N1 (+ N2)
            if (size < 2) {
              // send reply!!!
              response.write_head(
                  http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
              response.end();
              return;
            }

            // step 2. process the request
            try {
              nlohmann::json::parse(parts[0].body.c_str())
                  .get_to(smContextCreateData);
              smContextMessage.setJsonData(smContextCreateData);
              if (parts[1].content_type.compare("application/vnd.3gpp.5gnas") ==
                  0) {
                smContextMessage.setBinaryDataN1SmMessage(parts[1].body);
              } else if (
                  parts[1].content_type.compare("application/vnd.3gpp.ngap") ==
                  0) {
                smContextMessage.setBinaryDataN2SmInformation(parts[1].body);
              }
              // process the request
              this->create_sm_contexts_handler(smContextMessage, response);
            } catch (nlohmann::detail::exception& e) {
              Logger::smf_api_server().warn(
                  "Can not parse the json data (error: %s)!", e.what());
              response.write_head(
                  http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
              response.end();
              return;
            } catch (std::exception& e) {
              Logger::smf_api_server().warn("Error: %s!", e.what());
              response.write_head(
                  http_status_code_e::
                      HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR);
              response.end();
              return;
            }
          }
        });
      });

  // Update SM Context Request
  server.handle(
      NSMF_PDU_SESSION_BASE + smf_cfg.sbi_api_version +
          NSMF_PDU_SESSION_SM_CONTEXT_UPDATE_URL,
      [&](const request& request, const response& response) {
        request.on_data([&](const uint8_t* data, std::size_t len) {
          if (len > 0) {
            std::string msg((char*) data, len);
            Logger::smf_api_server().debug("");
            Logger::smf_api_server().info(
                "Received a SM context update request from AMF.");
            Logger::smf_api_server().debug(
                "Message content \n %s", msg.c_str());

            // Get the smf reference context and method
            std::vector<std::string> split_result;
            boost::split(
                split_result, request.uri().path, boost::is_any_of("/"));
            if (split_result.size() != 6) {
              Logger::smf_api_server().warn("Requested URL is not implemented");
              response.write_head(
                  http_status_code_e::HTTP_STATUS_CODE_501_NOT_IMPLEMENTED);
              response.end();
              return;
            }

            std::string smf_ref = split_result[split_result.size() - 2];
            std::string method  = split_result[split_result.size() - 1];
            Logger::smf_api_server().info(
                "smf_ref %s, method %s",
                split_result[split_result.size() - 2].c_str(),
                split_result[split_result.size() - 1].c_str());

            if (method.compare("modify") == 0) {  // Update SM Context Request
              Logger::smf_api_server().info(
                  "Handle Update SM Context Request from AMF");

              SmContextUpdateMessage smContextUpdateMessage = {};
              SmContextUpdateData smContextUpdateData       = {};

              // simple parser
              mime_parser sp = {};
185
186
187
188
189
190
191
              if (!sp.parse(msg)) {
                // send reply!!!
                response.write_head(
                    http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
                response.end();
                return;
              }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

              std::vector<mime_part> parts = {};
              sp.get_mime_parts(parts);
              uint8_t size = parts.size();
              Logger::smf_api_server().debug("Number of MIME parts %d", size);

              try {
                if (size > 0) {
                  nlohmann::json::parse(parts[0].body.c_str())
                      .get_to(smContextUpdateData);
                } else {
                  nlohmann::json::parse(msg.c_str())
                      .get_to(smContextUpdateData);
                }
                smContextUpdateMessage.setJsonData(smContextUpdateData);

                for (int i = 1; i < size; i++) {
                  if (parts[i].content_type.compare(
                          "application/vnd.3gpp.5gnas") == 0) {
                    smContextUpdateMessage.setBinaryDataN1SmMessage(
                        parts[i].body);
                    Logger::smf_api_server().debug("N1 SM message is set");
                  } else if (
                      parts[i].content_type.compare(
                          "application/vnd.3gpp.ngap") == 0) {
                    smContextUpdateMessage.setBinaryDataN2SmInformation(
                        parts[i].body);
                    Logger::smf_api_server().debug("N2 SM information is set");
                  }
                }
                this->update_sm_context_handler(
                    smf_ref, smContextUpdateMessage, response);

              } catch (nlohmann::detail::exception& e) {
                Logger::smf_api_server().warn(
                    "Can not parse the json data (error: %s)!", e.what());
                response.write_head(
                    http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
                response.end();
                return;
              } catch (std::exception& e) {
                Logger::smf_api_server().warn("Error: %s!", e.what());
                response.write_head(
                    http_status_code_e::
                        HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR);
                response.end();
                return;
              }

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
241
            } else if (
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
242
                method.compare("release") == 0) {  // smContextReleaseMessage
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
243
244
245
              Logger::smf_api_server().info(
                  "Handle Release SM Context Request from AMF");

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
246
247
248
249
              SmContextReleaseMessage smContextReleaseMessage = {};

              // simple parser
              mime_parser sp = {};
250
251
252
253
254
255
256
              if (!sp.parse(msg)) {
                // send reply!!!
                response.write_head(
                    http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
                response.end();
                return;
              }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
257
258
259
260
261
262
263

              std::vector<mime_part> parts = {};
              sp.get_mime_parts(parts);
              uint8_t size = parts.size();
              Logger::smf_api_server().debug("Number of MIME parts %d", size);

              // Getting the body param
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
264
265
              SmContextReleaseData smContextReleaseData = {};
              try {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
                if (size > 0) {
                  nlohmann::json::parse(parts[0].body.c_str())
                      .get_to(smContextReleaseData);
                } else {
                  nlohmann::json::parse(msg.c_str())
                      .get_to(smContextReleaseData);
                }

                smContextReleaseMessage.setJsonData(smContextReleaseData);

                for (int i = 1; i < size; i++) {
                  if (parts[i].content_type.compare(
                          "application/vnd.3gpp.ngap") == 0) {
                    smContextReleaseMessage.setBinaryDataN2SmInformation(
                        parts[i].body);
                    Logger::smf_api_server().debug("N2 SM information is set");
                  }
                }

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
285
                this->release_sm_context_handler(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
286
                    smf_ref, smContextReleaseMessage, response);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

              } catch (nlohmann::detail::exception& e) {
                Logger::smf_api_server().warn(
                    "Can not parse the json data (error: %s)!", e.what());
                response.write_head(
                    http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
                response.end();
                return;
              } catch (std::exception& e) {
                Logger::smf_api_server().warn("Error: %s!", e.what());
                response.write_head(
                    http_status_code_e::
                        HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR);
                response.end();
                return;
              }

            } else if (
                method.compare("retrieve") == 0) {  // smContextRetrieveData
              // TODO: retrieve_sm_context_handler

            } else {  // Unknown method
              Logger::smf_api_server().warn("Unknown method");
              response.write_head(
                  http_status_code_e::HTTP_STATUS_CODE_405_METHOD_NOT_ALLOWED);
              response.end();
              return;
            }
          }
        });
      });
318
319
320
321
322
323
324
325

  if (server.listen_and_serve(ec, m_address, std::to_string(m_port))) {
    std::cerr << "HTTP Server error: " << ec.message() << std::endl;
  }
}

//------------------------------------------------------------------------------
void smf_http2_server::create_sm_contexts_handler(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
326
    const SmContextMessage& smContextMessage, const response& response) {
327
328
329
330
331
332
333
  Logger::smf_api_server().info(
      "Handle PDU Session Create SM Context Request.");

  SmContextCreateData smContextCreateData = smContextMessage.getJsonData();
  std::string n1_sm_msg = smContextMessage.getBinaryDataN1SmMessage();
  Logger::smf_api_server().debug("N1 SM message: %s", n1_sm_msg.c_str());

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
334
  // Create a pdu_session_create_sm_context_request message and store
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
335
  // the necessary information
336
  Logger::smf_api_server().debug(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
337
338
339
      "Create a pdu_session_create_sm_context_request message and store the "
      "necessary information");
  smf::pdu_session_create_sm_context_request sm_context_req_msg = {};
340

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
341
342
343
344
345
  // Convert from SmContextMessage to pdu_session_create_sm_context_request
  xgpp_conv::sm_context_create_from_openapi(
      smContextMessage, sm_context_req_msg);

  // Set api root to be used as location header in HTTP response
346
  sm_context_req_msg.set_api_root(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
347
      // m_address + ":" + std::to_string(m_port) +
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
348
349
      NSMF_PDU_SESSION_BASE + smf_cfg.sbi_api_version +
      NSMF_PDU_SESSION_SM_CONTEXT_CREATE_URL);
350

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
351
352
353
  boost::shared_ptr<
      boost::promise<smf::pdu_session_create_sm_context_response> >
      p = boost::make_shared<
354
355
356
357
          boost::promise<smf::pdu_session_create_sm_context_response> >();
  boost::shared_future<smf::pdu_session_create_sm_context_response> f;
  f = p->get_future();

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
358
  // Generate ID for this promise (to be used in SMF-APP)
359
360
361
362
  uint32_t promise_id = generate_promise_id();
  Logger::smf_api_server().debug("Promise ID generated %d", promise_id);
  m_smf_app->add_promise(promise_id, p);

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
363
  // Handle the pdu_session_create_sm_context_request message in smf_app
364
  std::shared_ptr<itti_n11_create_sm_context_request> itti_msg =
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
365
      std::make_shared<itti_n11_create_sm_context_request>(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
366
          TASK_SMF_SBI, TASK_SMF_APP, promise_id);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
367
  itti_msg->req          = sm_context_req_msg;
368
369
370
  itti_msg->http_version = 2;
  m_smf_app->handle_pdu_session_create_sm_context_request(itti_msg);

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
371
  // Wait for the result from APP and send reply to AMF
372
373
  smf::pdu_session_create_sm_context_response sm_context_response = f.get();
  Logger::smf_api_server().debug("Got result for promise ID %d", promise_id);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
374
  nlohmann::json json_data = {};
375
  sm_context_response.get_json_data(json_data);
376
377
  std::string json_format;
  sm_context_response.get_json_format(json_format);
378

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
379
  // Add header
380
  header_map h;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
381
  // Location header
382
383
384
385
  if (sm_context_response.get_smf_context_uri().size() > 0) {
    Logger::smf_api_server().debug(
        "Add location header %s",
        sm_context_response.get_smf_context_uri().c_str());
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
386
387
388
    h.emplace(
        "location",
        header_value{sm_context_response.get_smf_context_uri().c_str()});
389
  }
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
390
391
  // content-type header
  h.emplace("content-type", header_value{json_format});
392
393
  response.write_head(sm_context_response.get_http_code(), h);

394
395
396
397
398
  response.end(json_data.dump().c_str());
}

//------------------------------------------------------------------------------
void smf_http2_server::update_sm_context_handler(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
399
400
401
    const std::string& smf_ref,
    const SmContextUpdateMessage& smContextUpdateMessage,
    const response& response) {
402
403
404
  Logger::smf_api_server().info(
      "Handle PDU Session Update SM Context Request.");

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
405
  // Get the SmContextUpdateData from this message and process in smf_app
406
407
408
  Logger::smf_api_server().info(
      "Received a PDUSession_UpdateSMContext Request from AMF.");

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
409
  smf::pdu_session_update_sm_context_request sm_context_req_msg = {};
410

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
411
412
413
414
  // Convert from SmContextUpdateMessage to
  // pdu_session_update_sm_context_request
  xgpp_conv::sm_context_update_from_openapi(
      smContextUpdateMessage, sm_context_req_msg);
415

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
416
417
418
  boost::shared_ptr<
      boost::promise<smf::pdu_session_update_sm_context_response> >
      p = boost::make_shared<
419
420
421
422
          boost::promise<smf::pdu_session_update_sm_context_response> >();
  boost::shared_future<smf::pdu_session_update_sm_context_response> f;
  f = p->get_future();

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
423
  // Generate ID for this promise (to be used in SMF-APP)
424
425
426
427
  uint32_t promise_id = generate_promise_id();
  Logger::smf_api_server().debug("Promise ID generated %d", promise_id);
  m_smf_app->add_promise(promise_id, p);

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
428
  // Handle the itti_n11_update_sm_context_request message in smf_app
429
  std::shared_ptr<itti_n11_update_sm_context_request> itti_msg =
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
430
      std::make_shared<itti_n11_update_sm_context_request>(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
431
          TASK_SMF_SBI, TASK_SMF_APP, promise_id, smf_ref);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
432
  itti_msg->req          = sm_context_req_msg;
433
434
435
  itti_msg->http_version = 2;
  m_smf_app->handle_pdu_session_update_sm_context_request(itti_msg);

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
436
  // Wait for the result from APP and send reply to AMF
437
438
439
  smf::pdu_session_update_sm_context_response sm_context_response = f.get();
  Logger::smf_api_server().debug("Got result for promise ID %d", promise_id);

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
440
441
442
  nlohmann::json json_data = {};
  std::string body         = {};
  header_map h             = {};
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
443
  std::string json_format  = {};
444

445
  sm_context_response.get_json_format(json_format);
446
447
448
  sm_context_response.get_json_data(json_data);
  Logger::smf_api_server().debug("Json data %s", json_data.dump().c_str());

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
449
450
  if (sm_context_response.n1_sm_msg_is_set() and
      sm_context_response.n2_sm_info_is_set()) {
451
    mime_parser::create_multipart_related_content(
452
453
        body, json_data.dump(), CURL_MIME_BOUNDARY,
        sm_context_response.get_n1_sm_message(),
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
454
        sm_context_response.get_n2_sm_information(), json_format);
455
    h.emplace(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
456
457
        "content-type", header_value{"multipart/related; boundary=" +
                                     std::string(CURL_MIME_BOUNDARY)});
458
  } else if (sm_context_response.n1_sm_msg_is_set()) {
459
    mime_parser::create_multipart_related_content(
460
461
        body, json_data.dump(), CURL_MIME_BOUNDARY,
        sm_context_response.get_n1_sm_message(),
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
462
        multipart_related_content_part_e::NAS, json_format);
463
    h.emplace(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
464
465
        "content-type", header_value{"multipart/related; boundary=" +
                                     std::string(CURL_MIME_BOUNDARY)});
466
  } else if (sm_context_response.n2_sm_info_is_set()) {
467
    mime_parser::create_multipart_related_content(
468
469
        body, json_data.dump(), CURL_MIME_BOUNDARY,
        sm_context_response.get_n2_sm_information(),
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
470
        multipart_related_content_part_e::NGAP, json_format);
471
    h.emplace(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
472
473
        "content-type", header_value{"multipart/related; boundary=" +
                                     std::string(CURL_MIME_BOUNDARY)});
474
  } else {
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
475
    h.emplace("content-type", header_value{json_format});
476
477
478
479
480
481
482
483
484
    body = json_data.dump().c_str();
  }

  response.write_head(sm_context_response.get_http_code(), h);
  response.end(body);
}

//------------------------------------------------------------------------------
void smf_http2_server::release_sm_context_handler(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
485
    const std::string& smf_ref,
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
486
    const SmContextReleaseMessage& smContextReleaseMessage,
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
487
    const response& response) {
488
489
490
  Logger::smf_api_server().info(
      "Handle PDU Session Release SM Context Request.");

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
491
492
493
494
495
496
  smf::pdu_session_release_sm_context_request sm_context_req_msg = {};
  // Convert from SmContextReleaseMessage to
  // pdu_session_release_sm_context_request
  xgpp_conv::sm_context_release_from_openapi(
      smContextReleaseMessage, sm_context_req_msg);

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
497
498
499
  boost::shared_ptr<
      boost::promise<smf::pdu_session_release_sm_context_response> >
      p = boost::make_shared<
500
501
502
503
          boost::promise<smf::pdu_session_release_sm_context_response> >();
  boost::shared_future<smf::pdu_session_release_sm_context_response> f;
  f = p->get_future();

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
504
  // Generate ID for this promise (to be used in SMF-APP)
505
506
507
508
  uint32_t promise_id = generate_promise_id();
  Logger::smf_api_server().debug("Promise ID generated %d", promise_id);
  m_smf_app->add_promise(promise_id, p);

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
509
  // handle Nsmf_PDUSession_UpdateSMContext Request
510
  Logger::smf_api_server().info(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
511
512
      "Received a PDUSession_ReleaseSMContext Request: PDU Session Release "
      "request from AMF.");
513
  std::shared_ptr<itti_n11_release_sm_context_request> itti_msg =
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
514
      std::make_shared<itti_n11_release_sm_context_request>(
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
515
          TASK_SMF_SBI, TASK_SMF_APP, promise_id, smf_ref);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
516
  itti_msg->req          = sm_context_req_msg;
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
517
  itti_msg->scid         = smf_ref;
518
519
520
  itti_msg->http_version = 2;
  m_smf_app->handle_pdu_session_release_sm_context_request(itti_msg);

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
521
  // wait for the result from APP and send reply to AMF
522
523
524
525
526
527
  smf::pdu_session_release_sm_context_response sm_context_response = f.get();
  Logger::smf_api_server().debug("Got result for promise ID %d", promise_id);

  response.write_head(sm_context_response.get_http_code());
  response.end();
}
528
529
530
531
532

//------------------------------------------------------------------------------
void smf_http2_server::stop() {
  server.stop();
}