Commit ec8c6d21 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Fix issue for API server to deal with multipart/related message

parent bd99e507
...@@ -10,8 +10,29 @@ ...@@ -10,8 +10,29 @@
* Do not edit the class manually. * Do not edit the class manually.
*/ */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "IndividualSMContextApi.h" #include "IndividualSMContextApi.h"
#include "SmContextReleaseMessage.h"
#include "logger.hpp" #include "logger.hpp"
#include "Helpers.h" #include "Helpers.h"
extern "C" { extern "C" {
...@@ -55,6 +76,7 @@ void IndividualSMContextApi::setupRoutes() { ...@@ -55,6 +76,7 @@ void IndividualSMContextApi::setupRoutes() {
void IndividualSMContextApi::release_sm_context_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { void IndividualSMContextApi::release_sm_context_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
//TODO: to be updated as update_sm_context_handler
Logger::smf_api_server().info("Received a Nsmf_PDUSession_UpdateSMContext: PDU Session Release request from AMF"); Logger::smf_api_server().info("Received a Nsmf_PDUSession_UpdateSMContext: PDU Session Release request from AMF");
Logger::smf_api_server().debug("Request body: %s\n",request.body().c_str()); Logger::smf_api_server().debug("Request body: %s\n",request.body().c_str());
SmContextReleaseMessage smContextReleaseMessage; SmContextReleaseMessage smContextReleaseMessage;
...@@ -139,10 +161,12 @@ void IndividualSMContextApi::update_sm_context_handler(const Pistache::Rest::Req ...@@ -139,10 +161,12 @@ void IndividualSMContextApi::update_sm_context_handler(const Pistache::Rest::Req
Logger::smf_api_server().info("Received a SM context update request from AMF"); Logger::smf_api_server().info("Received a SM context update request from AMF");
Logger::smf_api_server().debug("Request body: %s\n",request.body().c_str()); Logger::smf_api_server().debug("Request body: %s\n",request.body().c_str());
SmContextUpdateMessage smContextUpdateMessage;
// Getting the path params std::size_t found = request.body().find("Content-Type");
auto smContextRef = request.param(":smContextRef").as<std::string>(); std::string boundary_str = request.body().substr(2, found - 4);
Logger::smf_api_server().debug("Boundary: %s", boundary_str.c_str());
SmContextUpdateMessage smContextUpdateMessage;
//step 1. use multipartparser to decode the request //step 1. use multipartparser to decode the request
multipartparser_callbacks_init(&g_callbacks); multipartparser_callbacks_init(&g_callbacks);
...@@ -157,19 +181,33 @@ void IndividualSMContextApi::update_sm_context_handler(const Pistache::Rest::Req ...@@ -157,19 +181,33 @@ void IndividualSMContextApi::update_sm_context_handler(const Pistache::Rest::Req
multipartparser parser; multipartparser parser;
init_globals(); init_globals();
multipartparser_init(&parser, BOUNDARY); multipartparser_init(&parser, reinterpret_cast<const char*>(boundary_str.c_str()));
if ((multipartparser_execute(&parser, &g_callbacks, request.body().c_str(), strlen(request.body().c_str())) != strlen(request.body().c_str())) or (!g_body_begin_called)){
response.send(Pistache::Http::Code::Bad_Request, ""); unsigned int str_len = request.body().length();
return; unsigned char *data = (unsigned char *)malloc(str_len + 1);
memset(data,0,str_len + 1);
memcpy ((void *)data, (void *)request.body().c_str(),str_len);
//if ((multipartparser_execute(&parser, &g_callbacks, request.body().c_str(), strlen(request.body().c_str())) != strlen(request.body().c_str())) or (!g_body_begin_called)){
if ((multipartparser_execute(&parser, &g_callbacks, reinterpret_cast<const char*>(data), str_len) != strlen(request.body().c_str())) or (!g_body_begin_called)){
Logger::smf_api_server().warn("The received message can not be parsed properly!");
//TODO: fix this issue
//response.send(Pistache::Http::Code::Bad_Request, "");
//return;
} }
free(data);
data = nullptr;
uint8_t size = g_parts.size();
Logger::smf_api_server().debug("Number of g_parts %d", g_parts.size());
part p0 = g_parts.front(); g_parts.pop_front(); part p0 = g_parts.front(); g_parts.pop_front();
Logger::smf_api_server().debug("Request body, part 1: \n%s", p0.body.c_str()); Logger::smf_api_server().debug("Request body, part 1: %s", p0.body.c_str());
part p1 = {}; part p1 = {};
if (g_parts.size() >= 2){ if (size > 1){
p1 = g_parts.front(); g_parts.pop_front(); p1 = g_parts.front(); g_parts.pop_front();
Logger::smf_api_server().debug("Request body, part 2: \n %s",p1.body.c_str()); Logger::smf_api_server().debug("Request body, part 2: %s (%d bytes)",p1.body.c_str(), p1.body.length());
//part p2 = g_parts.front(); g_parts.pop_front(); //part p2 = g_parts.front(); g_parts.pop_front();
//Logger::smf_api_server().debug("Request body, part 3: \n %s",p2.body.c_str()); //Logger::smf_api_server().debug("Request body, part 3: \n %s",p2.body.c_str());
} }
...@@ -180,28 +218,33 @@ void IndividualSMContextApi::update_sm_context_handler(const Pistache::Rest::Req ...@@ -180,28 +218,33 @@ void IndividualSMContextApi::update_sm_context_handler(const Pistache::Rest::Req
nlohmann::json::parse(p0.body.c_str()).get_to(smContextUpdateData); nlohmann::json::parse(p0.body.c_str()).get_to(smContextUpdateData);
smContextUpdateMessage.setJsonData(smContextUpdateData); smContextUpdateMessage.setJsonData(smContextUpdateData);
if (g_parts.size() >= 2){ if (size > 1){
if (smContextUpdateData.n2SmInfoIsSet()){ if (smContextUpdateData.n2SmInfoIsSet()){
//N2 SM (for Session establishment, or for session modification) //N2 SM (for Session establishment, or for session modification)
smContextUpdateMessage.setBinaryDataN2SmInformation(p1.body.c_str()); Logger::smf_api_server().debug("N2 SM information is set");
smContextUpdateMessage.setBinaryDataN2SmInformation(p1.body);
} }
if (smContextUpdateData.n1SmMsgIsSet()){ if (smContextUpdateData.n1SmMsgIsSet()){
//N1 SM (for session modification, UE-initiated) //N1 SM (for session modification, UE-initiated)
Logger::smf_api_server().debug("N1 SM message is set");
smContextUpdateMessage.setBinaryDataN1SmMessage(p1.body.c_str()); smContextUpdateMessage.setBinaryDataN1SmMessage(p1.body.c_str());
} }
} }
// Getting the path params
auto smContextRef = request.param(":smContextRef").as<std::string>();
this->update_sm_context(smContextRef, smContextUpdateMessage, response); this->update_sm_context(smContextRef, smContextUpdateMessage, response);
} catch (nlohmann::detail::exception &e) { } catch (nlohmann::detail::exception &e) {
//send a 400 error //send a 400 error
Logger::smf_api_server().warn("Error in parsing json, send a msg with a 400 error code to AMF");
response.send(Pistache::Http::Code::Bad_Request, e.what()); response.send(Pistache::Http::Code::Bad_Request, e.what());
return; return;
} catch (std::exception &e) { } catch (std::exception &e) {
//send a 500 error //send a 500 error
Logger::smf_api_server().warn("Send a msg with a 500 error code to AMF");
response.send(Pistache::Http::Code::Internal_Server_Error, e.what()); response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
return; return;
} }
} }
void IndividualSMContextApi::individual_sm_context_api_default_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { void IndividualSMContextApi::individual_sm_context_api_default_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) {
......
...@@ -15,6 +15,29 @@ ...@@ -15,6 +15,29 @@
* *
*/ */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef IndividualSMContextApi_H_ #ifndef IndividualSMContextApi_H_
#define IndividualSMContextApi_H_ #define IndividualSMContextApi_H_
...@@ -34,7 +57,11 @@ ...@@ -34,7 +57,11 @@
#include "SmContextUpdatedData.h" #include "SmContextUpdatedData.h"
#include "SmContextUpdateMessage.h" #include "SmContextUpdateMessage.h"
#include "SmContextReleaseMessage.h" #include "SmContextReleaseMessage.h"
#include <string>
#include "SmContextMessage.h"
#include "SmContextCreateError.h"
#include "SmContextCreatedData.h"
namespace oai { namespace oai {
namespace smf_server { namespace smf_server {
...@@ -48,7 +75,7 @@ public: ...@@ -48,7 +75,7 @@ public:
virtual ~IndividualSMContextApi() {} virtual ~IndividualSMContextApi() {}
void init(); void init();
const std::string base = "/nsmf-pdusession/v1"; const std::string base = "/nsmf-pdusession/v2";
private: private:
void setupRoutes(); void setupRoutes();
......
...@@ -54,82 +54,92 @@ using namespace oai::smf_server::helpers; ...@@ -54,82 +54,92 @@ using namespace oai::smf_server::helpers;
using namespace oai::smf_server::model; using namespace oai::smf_server::model;
SMContextsCollectionApi::SMContextsCollectionApi(std::shared_ptr<Pistache::Rest::Router> rtr) { SMContextsCollectionApi::SMContextsCollectionApi(std::shared_ptr<Pistache::Rest::Router> rtr) {
router = rtr; router = rtr;
} }
void SMContextsCollectionApi::init() { void SMContextsCollectionApi::init() {
setupRoutes(); setupRoutes();
} }
void SMContextsCollectionApi::setupRoutes() { void SMContextsCollectionApi::setupRoutes() {
using namespace Pistache::Rest; using namespace Pistache::Rest;
Routes::Post(*router, base + "/sm-contexts", Routes::bind(&SMContextsCollectionApi::post_sm_contexts_handler, this)); Routes::Post(*router, base + "/sm-contexts", Routes::bind(&SMContextsCollectionApi::post_sm_contexts_handler, this));
// Default handler, called when a route is not found // Default handler, called when a route is not found
router->addCustomHandler(Routes::bind(&SMContextsCollectionApi::sm_contexts_collection_api_default_handler, this)); router->addCustomHandler(Routes::bind(&SMContextsCollectionApi::sm_contexts_collection_api_default_handler, this));
} }
void SMContextsCollectionApi::post_sm_contexts_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { void SMContextsCollectionApi::post_sm_contexts_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
Logger::smf_api_server().info("Received a SM context create request from AMF"); Logger::smf_api_server().info("Received a SM context create request from AMF");
Logger::smf_api_server().debug("Request body: %s\n",request.body().c_str()); Logger::smf_api_server().debug("Request body: %s\n",request.body().c_str());
SmContextMessage smContextMessage;
SmContextCreateData smContextCreateData; std::size_t found = request.body().find("Content-Type");
std::string boundary_str = request.body().substr(2, found - 4);
//step 1. use multipartparser to decode the request Logger::smf_api_server().debug("Boundary: %s", boundary_str.c_str());
multipartparser_callbacks_init(&g_callbacks);
g_callbacks.on_body_begin = &on_body_begin; SmContextMessage smContextMessage;
g_callbacks.on_part_begin = &on_part_begin; SmContextCreateData smContextCreateData;
g_callbacks.on_header_field = &on_header_field;
g_callbacks.on_header_value = &on_header_value; //step 1. use multipartparser to decode the request
g_callbacks.on_headers_complete = &on_headers_complete; multipartparser_callbacks_init(&g_callbacks);
g_callbacks.on_data = &on_data; g_callbacks.on_body_begin = &on_body_begin;
g_callbacks.on_part_end = &on_part_end; g_callbacks.on_part_begin = &on_part_begin;
g_callbacks.on_body_end = &on_body_end; g_callbacks.on_header_field = &on_header_field;
g_callbacks.on_header_value = &on_header_value;
multipartparser parser; g_callbacks.on_headers_complete = &on_headers_complete;
init_globals(); g_callbacks.on_data = &on_data;
multipartparser_init(&parser, BOUNDARY); g_callbacks.on_part_end = &on_part_end;
if ((multipartparser_execute(&parser, &g_callbacks, request.body().c_str(), strlen(request.body().c_str())) != strlen(request.body().c_str())) or (!g_body_begin_called)){ g_callbacks.on_body_end = &on_body_end;
response.send(Pistache::Http::Code::Bad_Request, "");
return; multipartparser parser;
} init_globals();
multipartparser_init(&parser, reinterpret_cast<const char*>(boundary_str.c_str()));
//at least 2 parts for Json data and N1 (+ N2) if ((multipartparser_execute(&parser, &g_callbacks, request.body().c_str(), strlen(request.body().c_str())) != strlen(request.body().c_str())) or (!g_body_begin_called)){
if (g_parts.size() < 2){ Logger::smf_api_server().warn("The received message can not be parsed properly!");
response.send(Pistache::Http::Code::Bad_Request, ""); //TODO: fix this issue
return; //response.send(Pistache::Http::Code::Bad_Request, "");
} //return;
part p0 = g_parts.front(); g_parts.pop_front(); }
Logger::smf_api_server().debug("Request body, part 1: \n%s", p0.body.c_str());
part p1 = g_parts.front(); g_parts.pop_front(); Logger::smf_api_server().debug("Number of g_parts %d", g_parts.size());
Logger::smf_api_server().debug("Request body, part 2: \n %s",p1.body.c_str()); //at least 2 parts for Json data and N1 (+ N2)
if (g_parts.size() == 3) { if (g_parts.size() < 2){
part p2 = g_parts.front(); g_parts.pop_front(); response.send(Pistache::Http::Code::Bad_Request, "");
Logger::smf_api_server().debug("Request body, part 3: \n %s",p2.body.c_str()); return;
} }
//step 2. process the request part p0 = g_parts.front(); g_parts.pop_front();
try { Logger::smf_api_server().debug("Request body, part 1: \n%s", p0.body.c_str());
nlohmann::json::parse(p0.body.c_str()).get_to(smContextCreateData); part p1 = g_parts.front(); g_parts.pop_front();
smContextMessage.setJsonData(smContextCreateData); Logger::smf_api_server().debug("Request body, part 2: \n %s",p1.body.c_str());
smContextMessage.setBinaryDataN1SmMessage(p1.body.c_str()); if (g_parts.size() > 0) {
this->post_sm_contexts(smContextMessage, response); part p2 = g_parts.front(); g_parts.pop_front();
} catch (nlohmann::detail::exception &e) { Logger::smf_api_server().debug("Request body, part 3: \n %s",p2.body.c_str());
//send a 400 error }
response.send(Pistache::Http::Code::Bad_Request, e.what());
return; //step 2. process the request
} catch (std::exception &e) { try {
//send a 500 error nlohmann::json::parse(p0.body.c_str()).get_to(smContextCreateData);
response.send(Pistache::Http::Code::Internal_Server_Error, e.what()); smContextMessage.setJsonData(smContextCreateData);
return; smContextMessage.setBinaryDataN1SmMessage(p1.body.c_str());
} this->post_sm_contexts(smContextMessage, response);
} catch (nlohmann::detail::exception &e) {
//send a 400 error
Logger::smf_api_server().warn("Can not parse the json data!");
response.send(Pistache::Http::Code::Bad_Request, e.what());
return;
} catch (std::exception &e) {
//send a 500 error
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
return;
}
} }
void SMContextsCollectionApi::sm_contexts_collection_api_default_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { void SMContextsCollectionApi::sm_contexts_collection_api_default_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) {
response.send(Pistache::Http::Code::Not_Found, "The requested method does not exist"); response.send(Pistache::Http::Code::Not_Found, "The requested method does not exist");
} }
} }
......
...@@ -15,6 +15,28 @@ ...@@ -15,6 +15,28 @@
* *
*/ */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef SMContextsCollectionApi_H_ #ifndef SMContextsCollectionApi_H_
#define SMContextsCollectionApi_H_ #define SMContextsCollectionApi_H_
......
...@@ -45,6 +45,8 @@ IndividualSMContextApiImpl::IndividualSMContextApiImpl(std::shared_ptr<Pistache: ...@@ -45,6 +45,8 @@ IndividualSMContextApiImpl::IndividualSMContextApiImpl(std::shared_ptr<Pistache:
{ } { }
void IndividualSMContextApiImpl::release_sm_context(const std::string &smContextRef, const SmContextReleaseMessage &smContextReleaseMessage, Pistache::Http::ResponseWriter &response) { void IndividualSMContextApiImpl::release_sm_context(const std::string &smContextRef, const SmContextReleaseMessage &smContextReleaseMessage, Pistache::Http::ResponseWriter &response) {
//TODO: to be updated as update_sm_context_handler
Logger::smf_api_server().info("release_sm_context..."); Logger::smf_api_server().info("release_sm_context...");
//handle Nsmf_PDUSession_UpdateSMContext Request //handle Nsmf_PDUSession_UpdateSMContext Request
...@@ -92,21 +94,16 @@ void IndividualSMContextApiImpl::update_sm_context(const std::string &smContextR ...@@ -92,21 +94,16 @@ void IndividualSMContextApiImpl::update_sm_context(const std::string &smContextR
if (smContextUpdateData.n2SmInfoIsSet()){ if (smContextUpdateData.n2SmInfoIsSet()){
//N2 SM (for Session establishment) //N2 SM (for Session establishment)
std::string n2_sm_information = smContextUpdateMessage.getBinaryDataN2SmInformation(); std::string n2_sm_information = smContextUpdateMessage.getBinaryDataN2SmInformation();
//std::string n2_sm_information = (smContextUpdateData.getN2SmInfo()).getContentId();
std::string n2_sm_msg_hex;
m_smf_app->convert_string_2_hex(n2_sm_information, n2_sm_msg_hex);
Logger::smf_api_server().debug("smContextMessage, n2 sm information %s", n2_sm_information.c_str()); Logger::smf_api_server().debug("smContextMessage, n2 sm information %s", n2_sm_information.c_str());
std::string n2_sm_info_type = smContextUpdateData.getN2SmInfoType(); std::string n2_sm_info_type = smContextUpdateData.getN2SmInfoType();
sm_context_req_msg.set_n2_sm_information(n2_sm_msg_hex); sm_context_req_msg.set_n2_sm_information(n2_sm_information);
sm_context_req_msg.set_n2_sm_info_type(n2_sm_info_type); sm_context_req_msg.set_n2_sm_info_type(n2_sm_info_type);
} else if (smContextUpdateData.n1SmMsgIsSet()){ } else if (smContextUpdateData.n1SmMsgIsSet()){
//N1 SM (for session modification) //N1 SM (for session modification)
std::string n1_sm_message = smContextUpdateMessage.getBinaryDataN1SmMessage(); std::string n1_sm_message = smContextUpdateMessage.getBinaryDataN1SmMessage();
std::string n1_sm_msg_hex;
m_smf_app->convert_string_2_hex(n1_sm_message, n1_sm_msg_hex);
Logger::smf_api_server().debug("smContextMessage, n1 sm message %s", n1_sm_message.c_str()); Logger::smf_api_server().debug("smContextMessage, n1 sm message %s", n1_sm_message.c_str());
sm_context_req_msg.set_n1_sm_message(n1_sm_msg_hex); sm_context_req_msg.set_n1_sm_message(n1_sm_message);
} }
//Step 2. TODO: initialize necessary values for sm context req from smContextUpdateData //Step 2. TODO: initialize necessary values for sm context req from smContextUpdateData
......
...@@ -15,6 +15,26 @@ ...@@ -15,6 +15,26 @@
* *
* *
*/ */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef INDIVIDUAL_SM_CONTEXT_API_IMPL_H_ #ifndef INDIVIDUAL_SM_CONTEXT_API_IMPL_H_
#define INDIVIDUAL_SM_CONTEXT_API_IMPL_H_ #define INDIVIDUAL_SM_CONTEXT_API_IMPL_H_
......
...@@ -15,6 +15,26 @@ ...@@ -15,6 +15,26 @@
* *
* *
*/ */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef SM_CONTEXTS_COLLECTION_API_IMPL_H_ #ifndef SM_CONTEXTS_COLLECTION_API_IMPL_H_
#define SM_CONTEXTS_COLLECTION_API_IMPL_H_ #define SM_CONTEXTS_COLLECTION_API_IMPL_H_
......
...@@ -9,7 +9,26 @@ ...@@ -9,7 +9,26 @@
* https://openapi-generator.tech * https://openapi-generator.tech
* Do not edit the class manually. * Do not edit the class manually.
*/ */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "pistache/endpoint.h" #include "pistache/endpoint.h"
#include "pistache/http.h" #include "pistache/http.h"
......
...@@ -10,6 +10,27 @@ ...@@ -10,6 +10,27 @@
* Do not edit the class manually. * Do not edit the class manually.
*/ */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "pistache/endpoint.h" #include "pistache/endpoint.h"
#include "pistache/http.h" #include "pistache/http.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment