3322 lines
123 KiB
C
3322 lines
123 KiB
C
|
/*
|
||
|
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
||
|
*
|
||
|
* This file is part of Open5GS.
|
||
|
*
|
||
|
* This program is free software: you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU Affero General Public License as published by
|
||
|
* the Free Software Foundation, either version 3 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#include "ogs-sbi.h"
|
||
|
#include "yuarel.h"
|
||
|
|
||
|
#include "contrib/multipart_parser.h"
|
||
|
|
||
|
static OGS_POOL(request_pool, ogs_sbi_request_t);
|
||
|
static OGS_POOL(response_pool, ogs_sbi_response_t);
|
||
|
|
||
|
static char *build_json(ogs_sbi_message_t *message);
|
||
|
static int parse_json(ogs_sbi_message_t *message,
|
||
|
char *content_type, char *json);
|
||
|
|
||
|
static bool build_content(
|
||
|
ogs_sbi_http_message_t *http, ogs_sbi_message_t *message);
|
||
|
static int parse_content(
|
||
|
ogs_sbi_message_t *message, ogs_sbi_http_message_t *http);
|
||
|
|
||
|
static bool build_multipart(
|
||
|
ogs_sbi_http_message_t *http, ogs_sbi_message_t *message);
|
||
|
static int parse_multipart(
|
||
|
ogs_sbi_message_t *sbi_message, ogs_sbi_http_message_t *http);
|
||
|
|
||
|
static void http_message_free(ogs_sbi_http_message_t *http);
|
||
|
|
||
|
void ogs_sbi_message_init(int num_of_request_pool, int num_of_response_pool)
|
||
|
{
|
||
|
ogs_pool_init(&request_pool, num_of_request_pool);
|
||
|
ogs_pool_init(&response_pool, num_of_response_pool);
|
||
|
}
|
||
|
|
||
|
void ogs_sbi_message_final(void)
|
||
|
{
|
||
|
ogs_pool_final(&request_pool);
|
||
|
ogs_pool_final(&response_pool);
|
||
|
}
|
||
|
|
||
|
void ogs_sbi_message_free(ogs_sbi_message_t *message)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
ogs_assert(message);
|
||
|
|
||
|
/* Discovery Option */
|
||
|
if (message->param.discovery_option)
|
||
|
ogs_sbi_discovery_option_free(message->param.discovery_option);
|
||
|
|
||
|
/* JSON Data */
|
||
|
if (message->NFProfile)
|
||
|
OpenAPI_nf_profile_free(message->NFProfile);
|
||
|
if (message->ProblemDetails)
|
||
|
OpenAPI_problem_details_free(message->ProblemDetails);
|
||
|
if (message->PatchItemList) {
|
||
|
OpenAPI_lnode_t *node = NULL;
|
||
|
OpenAPI_list_for_each(message->PatchItemList, node)
|
||
|
OpenAPI_patch_item_free(node->data);
|
||
|
OpenAPI_list_free(message->PatchItemList);
|
||
|
}
|
||
|
|
||
|
if (message->SubscriptionData)
|
||
|
OpenAPI_subscription_data_free(message->SubscriptionData);
|
||
|
if (message->NotificationData)
|
||
|
OpenAPI_notification_data_free(message->NotificationData);
|
||
|
if (message->SearchResult)
|
||
|
OpenAPI_search_result_free(message->SearchResult);
|
||
|
if (message->AuthenticationInfo)
|
||
|
OpenAPI_authentication_info_free(message->AuthenticationInfo);
|
||
|
if (message->AuthenticationInfoRequest)
|
||
|
OpenAPI_authentication_info_request_free(
|
||
|
message->AuthenticationInfoRequest);
|
||
|
if (message->AuthenticationInfoResult)
|
||
|
OpenAPI_authentication_info_result_free(
|
||
|
message->AuthenticationInfoResult);
|
||
|
if (message->AuthenticationSubscription)
|
||
|
OpenAPI_authentication_subscription_free(
|
||
|
message->AuthenticationSubscription);
|
||
|
if (message->UeAuthenticationCtx)
|
||
|
OpenAPI_ue_authentication_ctx_free(message->UeAuthenticationCtx);
|
||
|
if (message->ConfirmationData)
|
||
|
OpenAPI_confirmation_data_free(message->ConfirmationData);
|
||
|
if (message->ConfirmationDataResponse)
|
||
|
OpenAPI_confirmation_data_response_free(
|
||
|
message->ConfirmationDataResponse);
|
||
|
if (message->AuthEvent)
|
||
|
OpenAPI_auth_event_free(message->AuthEvent);
|
||
|
if (message->Amf3GppAccessRegistration)
|
||
|
OpenAPI_amf3_gpp_access_registration_free(
|
||
|
message->Amf3GppAccessRegistration);
|
||
|
if (message->Amf3GppAccessRegistrationModification)
|
||
|
OpenAPI_amf3_gpp_access_registration_modification_free(
|
||
|
message->Amf3GppAccessRegistrationModification);
|
||
|
if (message->SmfRegistration)
|
||
|
OpenAPI_smf_registration_free(message->SmfRegistration);
|
||
|
if (message->AccessAndMobilitySubscriptionData)
|
||
|
OpenAPI_access_and_mobility_subscription_data_free(
|
||
|
message->AccessAndMobilitySubscriptionData);
|
||
|
if (message->SmfSelectionSubscriptionData)
|
||
|
OpenAPI_smf_selection_subscription_data_free(
|
||
|
message->SmfSelectionSubscriptionData);
|
||
|
if (message->UeContextInSmfData)
|
||
|
OpenAPI_ue_context_in_smf_data_free(message->UeContextInSmfData);
|
||
|
if (message->SmContextCreateData)
|
||
|
OpenAPI_sm_context_create_data_free(message->SmContextCreateData);
|
||
|
if (message->SmContextCreatedData)
|
||
|
OpenAPI_sm_context_created_data_free(message->SmContextCreatedData);
|
||
|
if (message->SmContextCreateError)
|
||
|
OpenAPI_sm_context_create_error_free(message->SmContextCreateError);
|
||
|
if (message->SmContextUpdateData)
|
||
|
OpenAPI_sm_context_update_data_free(message->SmContextUpdateData);
|
||
|
if (message->SmContextUpdatedData)
|
||
|
OpenAPI_sm_context_updated_data_free(message->SmContextUpdatedData);
|
||
|
if (message->SmContextUpdateError)
|
||
|
OpenAPI_sm_context_update_error_free(message->SmContextUpdateError);
|
||
|
if (message->SmContextReleaseData)
|
||
|
OpenAPI_sm_context_release_data_free(message->SmContextReleaseData);
|
||
|
if (message->SmContextReleasedData)
|
||
|
OpenAPI_sm_context_released_data_free(message->SmContextReleasedData);
|
||
|
if (message->SessionManagementSubscriptionDataList) {
|
||
|
OpenAPI_lnode_t *node = NULL;
|
||
|
OpenAPI_list_for_each(message->SessionManagementSubscriptionDataList, node)
|
||
|
OpenAPI_session_management_subscription_data_free(node->data);
|
||
|
OpenAPI_list_free(message->SessionManagementSubscriptionDataList);
|
||
|
}
|
||
|
if (message->N1N2MessageTransferReqData)
|
||
|
OpenAPI_n1_n2_message_transfer_req_data_free(
|
||
|
message->N1N2MessageTransferReqData);
|
||
|
if (message->N1N2MessageTransferRspData)
|
||
|
OpenAPI_n1_n2_message_transfer_rsp_data_free(
|
||
|
message->N1N2MessageTransferRspData);
|
||
|
if (message->N1N2MsgTxfrFailureNotification)
|
||
|
OpenAPI_n1_n2_msg_txfr_failure_notification_free(
|
||
|
message->N1N2MsgTxfrFailureNotification);
|
||
|
if (message->SmContextStatusNotification)
|
||
|
OpenAPI_sm_context_status_notification_free(
|
||
|
message->SmContextStatusNotification);
|
||
|
if (message->PolicyAssociationRequest)
|
||
|
OpenAPI_policy_association_request_free(
|
||
|
message->PolicyAssociationRequest);
|
||
|
if (message->PolicyAssociation)
|
||
|
OpenAPI_policy_association_free(message->PolicyAssociation);
|
||
|
if (message->AmPolicyData)
|
||
|
OpenAPI_am_policy_data_free(message->AmPolicyData);
|
||
|
if (message->SmPolicyContextData)
|
||
|
OpenAPI_sm_policy_context_data_free(message->SmPolicyContextData);
|
||
|
if (message->SmPolicyDecision)
|
||
|
OpenAPI_sm_policy_decision_free(message->SmPolicyDecision);
|
||
|
if (message->SmPolicyData)
|
||
|
OpenAPI_sm_policy_data_free(message->SmPolicyData);
|
||
|
if (message->SmPolicyDeleteData)
|
||
|
OpenAPI_sm_policy_delete_data_free(message->SmPolicyDeleteData);
|
||
|
if (message->AuthorizedNetworkSliceInfo)
|
||
|
OpenAPI_authorized_network_slice_info_free(
|
||
|
message->AuthorizedNetworkSliceInfo);
|
||
|
if (message->PcfBinding)
|
||
|
OpenAPI_pcf_binding_free(message->PcfBinding);
|
||
|
if (message->AppSessionContext)
|
||
|
OpenAPI_app_session_context_free(message->AppSessionContext);
|
||
|
if (message->AppSessionContextUpdateDataPatch)
|
||
|
OpenAPI_app_session_context_update_data_patch_free(message->AppSessionContextUpdateDataPatch);
|
||
|
if (message->SmPolicyNotification)
|
||
|
OpenAPI_sm_policy_notification_free(message->SmPolicyNotification);
|
||
|
if (message->TerminationNotification)
|
||
|
OpenAPI_termination_notification_free(message->TerminationNotification);
|
||
|
if (message->DeregistrationData)
|
||
|
OpenAPI_deregistration_data_free(message->DeregistrationData);
|
||
|
if (message->SDMSubscription)
|
||
|
OpenAPI_sdm_subscription_free(message->SDMSubscription);
|
||
|
if (message->ModificationNotification)
|
||
|
OpenAPI_modification_notification_free(message->ModificationNotification);
|
||
|
if (message->SecNegotiateReqData)
|
||
|
OpenAPI_sec_negotiate_req_data_free(message->SecNegotiateReqData);
|
||
|
if (message->SecNegotiateRspData)
|
||
|
OpenAPI_sec_negotiate_rsp_data_free(message->SecNegotiateRspData);
|
||
|
|
||
|
/* HTTP Part */
|
||
|
for (i = 0; i < message->num_of_part; i++) {
|
||
|
if (message->part[i].pkbuf)
|
||
|
ogs_pkbuf_free(message->part[i].pkbuf);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ogs_sbi_request_t *ogs_sbi_request_new(void)
|
||
|
{
|
||
|
ogs_sbi_request_t *request = NULL;
|
||
|
|
||
|
ogs_pool_alloc(&request_pool, &request);
|
||
|
if (!request) {
|
||
|
ogs_error("ogs_pool_alloc() failed");
|
||
|
return NULL;
|
||
|
}
|
||
|
memset(request, 0, sizeof(ogs_sbi_request_t));
|
||
|
|
||
|
request->http.params = ogs_hash_make();
|
||
|
if (!request->http.params) {
|
||
|
ogs_error("ogs_hash_make() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
request->http.headers = ogs_hash_make();
|
||
|
if (!request->http.headers) {
|
||
|
ogs_error("ogs_hash_make() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return request;
|
||
|
}
|
||
|
|
||
|
ogs_sbi_response_t *ogs_sbi_response_new(void)
|
||
|
{
|
||
|
ogs_sbi_response_t *response = NULL;
|
||
|
|
||
|
ogs_pool_alloc(&response_pool, &response);
|
||
|
if (!response) {
|
||
|
ogs_error("ogs_pool_alloc() failed");
|
||
|
return NULL;
|
||
|
}
|
||
|
memset(response, 0, sizeof(ogs_sbi_response_t));
|
||
|
|
||
|
response->http.params = ogs_hash_make();
|
||
|
if (!response->http.params) {
|
||
|
ogs_error("ogs_hash_make() failed");
|
||
|
ogs_sbi_response_free(response);
|
||
|
return NULL;
|
||
|
}
|
||
|
response->http.headers = ogs_hash_make();
|
||
|
if (!response->http.headers) {
|
||
|
ogs_error("ogs_hash_make() failed");
|
||
|
ogs_sbi_response_free(response);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return response;
|
||
|
}
|
||
|
|
||
|
void ogs_sbi_request_free(ogs_sbi_request_t *request)
|
||
|
{
|
||
|
ogs_assert(request);
|
||
|
|
||
|
if (request->h.uri)
|
||
|
ogs_free(request->h.uri);
|
||
|
|
||
|
ogs_sbi_header_free(&request->h);
|
||
|
http_message_free(&request->http);
|
||
|
|
||
|
ogs_pool_free(&request_pool, request);
|
||
|
}
|
||
|
|
||
|
void ogs_sbi_response_free(ogs_sbi_response_t *response)
|
||
|
{
|
||
|
ogs_assert(response);
|
||
|
|
||
|
if (response->h.uri)
|
||
|
ogs_free(response->h.uri);
|
||
|
|
||
|
ogs_sbi_header_free(&response->h);
|
||
|
http_message_free(&response->http);
|
||
|
|
||
|
ogs_pool_free(&response_pool, response);
|
||
|
}
|
||
|
|
||
|
ogs_sbi_request_t *ogs_sbi_build_request(ogs_sbi_message_t *message)
|
||
|
{
|
||
|
int i;
|
||
|
ogs_sbi_request_t *request = NULL;
|
||
|
OpenAPI_nf_type_e nf_type = OpenAPI_nf_type_NULL;
|
||
|
char sender_timestamp[OGS_SBI_RFC7231_DATE_LEN];
|
||
|
char *max_rsp_time = NULL;
|
||
|
|
||
|
ogs_assert(message);
|
||
|
|
||
|
request = ogs_sbi_request_new();
|
||
|
if (!request) {
|
||
|
ogs_error("ogs_pool_alloc() failed");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
if (!message->h.method) {
|
||
|
ogs_error("No Method");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
request->h.method = ogs_strdup(message->h.method);
|
||
|
if (!request->h.method) {
|
||
|
ogs_error("ogs_strdup() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
if (message->h.uri) {
|
||
|
request->h.uri = ogs_strdup(message->h.uri);
|
||
|
if (!request->h.uri) {
|
||
|
ogs_error("ogs_strdup() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
} else {
|
||
|
if (!message->h.service.name) {
|
||
|
ogs_error("No Service Name");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
request->h.service.name = ogs_strdup(message->h.service.name);
|
||
|
if (!request->h.service.name) {
|
||
|
ogs_error("ogs_strdup() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
if (!message->h.api.version) {
|
||
|
ogs_error("No API Version");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
request->h.api.version = ogs_strdup(message->h.api.version);
|
||
|
if (!request->h.api.version) {
|
||
|
ogs_error("ogs_strdup() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
if (!message->h.resource.component[0]) {
|
||
|
ogs_error("No Resource");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
for (i = 0; i < OGS_SBI_MAX_NUM_OF_RESOURCE_COMPONENT &&
|
||
|
message->h.resource.component[i]; i++) {
|
||
|
request->h.resource.component[i] = ogs_strdup(
|
||
|
message->h.resource.component[i]);
|
||
|
if (!request->h.resource.component[i]) {
|
||
|
ogs_error("ogs_strdup() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Discovery Parameter */
|
||
|
if (message->param.target_nf_type) {
|
||
|
char *v = OpenAPI_nf_type_ToString(message->param.target_nf_type);
|
||
|
if (!v) {
|
||
|
ogs_error("OpenAPI_nf_type_ToString() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_TARGET_NF_TYPE, v);
|
||
|
}
|
||
|
if (message->param.requester_nf_type) {
|
||
|
char *v = OpenAPI_nf_type_ToString(message->param.requester_nf_type);
|
||
|
if (!v) {
|
||
|
ogs_error("OpenAPI_nf_type_ToString() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_REQUESTER_NF_TYPE, v);
|
||
|
}
|
||
|
|
||
|
/* Discovery Option Parameter */
|
||
|
if (message->param.discovery_option) {
|
||
|
ogs_sbi_discovery_option_t *discovery_option =
|
||
|
message->param.discovery_option;
|
||
|
|
||
|
if (discovery_option->target_nf_instance_id) {
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_TARGET_NF_INSTANCE_ID,
|
||
|
discovery_option->target_nf_instance_id);
|
||
|
}
|
||
|
if (discovery_option->requester_nf_instance_id) {
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_REQUESTER_NF_INSTANCE_ID,
|
||
|
discovery_option->requester_nf_instance_id);
|
||
|
}
|
||
|
if (ogs_sbi_self()->discovery_config.no_service_names == false &&
|
||
|
discovery_option->num_of_service_names) {
|
||
|
|
||
|
/*
|
||
|
* Issues #1730
|
||
|
* Send NF discovery query with service-names delimited with comma
|
||
|
*
|
||
|
* OpenAPI specification for sending NF discovery query with
|
||
|
* "service-names" parameter is defined as folowing:
|
||
|
* name: service-names
|
||
|
* ...
|
||
|
* style: form
|
||
|
* explode: false
|
||
|
*
|
||
|
* According to OpenAPI specification, this means array items
|
||
|
* should be delimited with a comma character (example: /users?id=3,4,5).
|
||
|
*
|
||
|
* See also https://swagger.io/docs/specification/serialization/
|
||
|
*/
|
||
|
|
||
|
/* send array items separated by a comma */
|
||
|
char *v = ogs_sbi_discovery_option_build_service_names(
|
||
|
discovery_option);
|
||
|
if (v) {
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_SERVICE_NAMES, v);
|
||
|
ogs_free(v);
|
||
|
} else {
|
||
|
ogs_warn("build failed: service-names[%d:%s]",
|
||
|
discovery_option->num_of_service_names,
|
||
|
discovery_option->service_names[0]);
|
||
|
}
|
||
|
}
|
||
|
if (discovery_option->num_of_snssais) {
|
||
|
char *v = ogs_sbi_discovery_option_build_snssais(discovery_option);
|
||
|
if (v) {
|
||
|
/*
|
||
|
* In http.params, the CURL library automatically encodes the URL.
|
||
|
* http.headers implements open5gs to directly encode URLs.
|
||
|
*
|
||
|
* Since it is http.params, the result is sent as is.
|
||
|
*/
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_SNSSAIS, v);
|
||
|
ogs_free(v);
|
||
|
} else {
|
||
|
ogs_error("build failed: snssais(%d)[SST:%d SD:0x%x]",
|
||
|
discovery_option->num_of_snssais,
|
||
|
discovery_option->snssais[0].sst,
|
||
|
discovery_option->snssais[0].sd.v);
|
||
|
}
|
||
|
}
|
||
|
if (discovery_option->dnn) {
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_DNN, discovery_option->dnn);
|
||
|
}
|
||
|
if (discovery_option->tai_presence) {
|
||
|
char *v = ogs_sbi_discovery_option_build_tai(discovery_option);
|
||
|
if (v) {
|
||
|
ogs_sbi_header_set(request->http.params, OGS_SBI_PARAM_TAI, v);
|
||
|
ogs_free(v);
|
||
|
} else {
|
||
|
ogs_error("build failed: tai[PLMN_ID:%06x,TAC:%d]",
|
||
|
ogs_plmn_id_hexdump(
|
||
|
&discovery_option->tai.plmn_id),
|
||
|
discovery_option->tai.tac.v);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (discovery_option->num_of_target_plmn_list) {
|
||
|
char *v = ogs_sbi_discovery_option_build_plmn_list(
|
||
|
discovery_option->target_plmn_list,
|
||
|
discovery_option->num_of_target_plmn_list);
|
||
|
if (v) {
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_TARGET_PLMN_LIST, v);
|
||
|
ogs_free(v);
|
||
|
} else {
|
||
|
ogs_warn("invalid target-plmn-list failed[%d:%06x]",
|
||
|
discovery_option->num_of_target_plmn_list,
|
||
|
ogs_plmn_id_hexdump(
|
||
|
&discovery_option->target_plmn_list[0]));
|
||
|
}
|
||
|
}
|
||
|
if (discovery_option->num_of_requester_plmn_list) {
|
||
|
char *v = ogs_sbi_discovery_option_build_plmn_list(
|
||
|
discovery_option->requester_plmn_list,
|
||
|
discovery_option->num_of_requester_plmn_list);
|
||
|
if (v) {
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_REQUESTER_PLMN_LIST, v);
|
||
|
ogs_free(v);
|
||
|
} else {
|
||
|
ogs_warn("invalid target-plmn-list failed[%d:%06x]",
|
||
|
discovery_option->num_of_requester_plmn_list,
|
||
|
ogs_plmn_id_hexdump(
|
||
|
&discovery_option->requester_plmn_list[0]));
|
||
|
}
|
||
|
}
|
||
|
if (discovery_option->requester_features) {
|
||
|
char *v = ogs_uint64_to_string(
|
||
|
discovery_option->requester_features);
|
||
|
if (!v) {
|
||
|
ogs_error("ogs_uint64_to_string[0x%llx] failed",
|
||
|
(long long)discovery_option->requester_features);
|
||
|
ogs_sbi_request_free(request);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_REQUESTER_FEATURES, v);
|
||
|
ogs_free(v);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* URL Query Paramemter */
|
||
|
if (message->param.nf_id) {
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_NF_ID, message->param.nf_id);
|
||
|
}
|
||
|
if (message->param.nf_type) {
|
||
|
char *v = OpenAPI_nf_type_ToString(message->param.nf_type);
|
||
|
if (!v) {
|
||
|
ogs_error("OpenAPI_nf_type_ToString() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
ogs_sbi_header_set(request->http.params, OGS_SBI_PARAM_NF_TYPE, v);
|
||
|
}
|
||
|
if (message->param.limit) {
|
||
|
char *v = ogs_msprintf("%d", message->param.limit);
|
||
|
if (!v) {
|
||
|
ogs_error("OpenAPI_nf_type_ToString() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
ogs_sbi_header_set(request->http.params, OGS_SBI_PARAM_LIMIT, v);
|
||
|
ogs_free(v);
|
||
|
}
|
||
|
if (message->param.dnn) {
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_DNN, message->param.dnn);
|
||
|
}
|
||
|
if (message->param.plmn_id_presence) {
|
||
|
OpenAPI_plmn_id_t plmn_id;
|
||
|
|
||
|
plmn_id.mnc = ogs_plmn_id_mnc_string(&message->param.plmn_id);
|
||
|
plmn_id.mcc = ogs_plmn_id_mcc_string(&message->param.plmn_id);
|
||
|
|
||
|
if (plmn_id.mnc && plmn_id.mcc) {
|
||
|
char *v = NULL;
|
||
|
cJSON *item = NULL;
|
||
|
|
||
|
item = OpenAPI_plmn_id_convertToJSON(&plmn_id);
|
||
|
if (!item) {
|
||
|
ogs_error("OpenAPI_plmn_id_convertToJSON() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
if (plmn_id.mnc) ogs_free(plmn_id.mnc);
|
||
|
if (plmn_id.mcc) ogs_free(plmn_id.mcc);
|
||
|
|
||
|
v = cJSON_PrintUnformatted(item);
|
||
|
if (!v) {
|
||
|
ogs_error("cJSON_PrintUnformatted() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
cJSON_Delete(item);
|
||
|
|
||
|
ogs_sbi_header_set(request->http.params, OGS_SBI_PARAM_PLMN_ID, v);
|
||
|
ogs_free(v);
|
||
|
}
|
||
|
}
|
||
|
if (message->param.single_nssai_presence) {
|
||
|
char *v = ogs_sbi_s_nssai_to_json(&message->param.s_nssai);
|
||
|
if (!v) {
|
||
|
ogs_error("ogs_sbi_s_nssai_to_json() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
ogs_sbi_header_set(request->http.params, OGS_SBI_PARAM_SINGLE_NSSAI, v);
|
||
|
ogs_free(v);
|
||
|
}
|
||
|
if (message->param.snssai_presence) {
|
||
|
char *v = ogs_sbi_s_nssai_to_json(&message->param.s_nssai);
|
||
|
if (!v) {
|
||
|
ogs_error("ogs_sbi_s_nssai_to_json() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
ogs_sbi_header_set(request->http.params, OGS_SBI_PARAM_SNSSAI, v);
|
||
|
ogs_free(v);
|
||
|
}
|
||
|
if (message->param.slice_info_request_for_pdu_session_presence) {
|
||
|
OpenAPI_slice_info_for_pdu_session_t SliceInfoForPDUSession;
|
||
|
OpenAPI_snssai_t sNSSAI;
|
||
|
|
||
|
char *v = NULL;
|
||
|
cJSON *item = NULL;
|
||
|
|
||
|
if (!message->param.s_nssai.sst) {
|
||
|
ogs_error("No S-NSSAI SST");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
if (!message->param.roaming_indication) {
|
||
|
ogs_error("No Roaming Indication");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
memset(&sNSSAI, 0, sizeof(sNSSAI));
|
||
|
sNSSAI.sst = message->param.s_nssai.sst;
|
||
|
sNSSAI.sd = ogs_s_nssai_sd_to_string(message->param.s_nssai.sd);
|
||
|
|
||
|
memset(&SliceInfoForPDUSession, 0, sizeof(SliceInfoForPDUSession));
|
||
|
|
||
|
SliceInfoForPDUSession.s_nssai = &sNSSAI;
|
||
|
SliceInfoForPDUSession.roaming_indication =
|
||
|
message->param.roaming_indication;
|
||
|
|
||
|
item = OpenAPI_slice_info_for_pdu_session_convertToJSON(
|
||
|
&SliceInfoForPDUSession);
|
||
|
if (!item) {
|
||
|
ogs_error("OpenAPI_slice_info_for_pdu_session_convertToJSON() "
|
||
|
"failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
v = cJSON_PrintUnformatted(item);
|
||
|
if (!v) {
|
||
|
ogs_error("cJSON_PrintUnformatted() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
cJSON_Delete(item);
|
||
|
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_SLICE_INFO_REQUEST_FOR_PDU_SESSION, v);
|
||
|
ogs_free(v);
|
||
|
|
||
|
if (sNSSAI.sd)
|
||
|
ogs_free(sNSSAI.sd);
|
||
|
}
|
||
|
if (message->param.ipv4addr) {
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_IPV4ADDR, message->param.ipv4addr);
|
||
|
}
|
||
|
if (message->param.ipv6prefix) {
|
||
|
ogs_sbi_header_set(request->http.params,
|
||
|
OGS_SBI_PARAM_IPV6PREFIX, message->param.ipv6prefix);
|
||
|
}
|
||
|
|
||
|
if (build_content(&request->http, message) == false) {
|
||
|
ogs_error("build_content() failed");
|
||
|
ogs_sbi_request_free(request);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
if (message->http.accept) {
|
||
|
ogs_sbi_header_set(request->http.headers, OGS_SBI_ACCEPT,
|
||
|
message->http.accept);
|
||
|
} else {
|
||
|
SWITCH(message->h.method)
|
||
|
CASE(OGS_SBI_HTTP_METHOD_DELETE)
|
||
|
ogs_sbi_header_set(request->http.headers, OGS_SBI_ACCEPT,
|
||
|
OGS_SBI_CONTENT_PROBLEM_TYPE);
|
||
|
break;
|
||
|
DEFAULT
|
||
|
ogs_sbi_header_set(request->http.headers, OGS_SBI_ACCEPT,
|
||
|
OGS_SBI_CONTENT_JSON_TYPE "," OGS_SBI_CONTENT_PROBLEM_TYPE);
|
||
|
break;
|
||
|
END
|
||
|
}
|
||
|
|
||
|
nf_type = NF_INSTANCE_TYPE(ogs_sbi_self()->nf_instance);
|
||
|
if (nf_type) {
|
||
|
char *user_agent = OpenAPI_nf_type_ToString(nf_type);
|
||
|
if (user_agent)
|
||
|
ogs_sbi_header_set(request->http.headers,
|
||
|
OGS_SBI_USER_AGENT, user_agent);
|
||
|
}
|
||
|
|
||
|
ogs_assert(OGS_OK ==
|
||
|
ogs_sbi_rfc7231_string(sender_timestamp, ogs_time_now()));
|
||
|
ogs_sbi_header_set(request->http.headers,
|
||
|
OGS_SBI_OPTIONAL_CUSTOM_SENDER_TIMESTAMP, sender_timestamp);
|
||
|
|
||
|
ogs_assert(ogs_time_to_msec(ogs_local_conf()->time.message.duration));
|
||
|
max_rsp_time = ogs_msprintf("%d",
|
||
|
(int)ogs_time_to_msec(ogs_local_conf()->time.message.duration));
|
||
|
ogs_sbi_header_set(request->http.headers,
|
||
|
OGS_SBI_OPTIONAL_CUSTOM_MAX_RSP_TIME, max_rsp_time);
|
||
|
ogs_free(max_rsp_time);
|
||
|
|
||
|
if (message->http.content_encoding)
|
||
|
ogs_sbi_header_set(request->http.headers,
|
||
|
OGS_SBI_ACCEPT_ENCODING, message->http.content_encoding);
|
||
|
|
||
|
if (message->http.custom.callback)
|
||
|
ogs_sbi_header_set(request->http.headers,
|
||
|
OGS_SBI_CUSTOM_CALLBACK, message->http.custom.callback);
|
||
|
|
||
|
if (message->http.custom.nrf_uri)
|
||
|
ogs_sbi_header_set(request->http.headers,
|
||
|
OGS_SBI_CUSTOM_NRF_URI, message->http.custom.nrf_uri);
|
||
|
|
||
|
return request;
|
||
|
}
|
||
|
|
||
|
ogs_sbi_response_t *ogs_sbi_build_response(
|
||
|
ogs_sbi_message_t *message, int status)
|
||
|
{
|
||
|
ogs_sbi_response_t *response = NULL;
|
||
|
|
||
|
ogs_assert(message);
|
||
|
|
||
|
response = ogs_sbi_response_new();
|
||
|
if (!response) {
|
||
|
ogs_error("ogs_pool_alloc() failed");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
response->status = status;
|
||
|
|
||
|
if (response->status != OGS_SBI_HTTP_STATUS_NO_CONTENT) {
|
||
|
if (build_content(&response->http, message) == false) {
|
||
|
ogs_error("build_content() failed");
|
||
|
ogs_sbi_response_free(response);
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (message->http.location) {
|
||
|
ogs_sbi_header_set(response->http.headers, "Location",
|
||
|
message->http.location);
|
||
|
}
|
||
|
if (message->http.cache_control)
|
||
|
ogs_sbi_header_set(response->http.headers, "Cache-Control",
|
||
|
message->http.cache_control);
|
||
|
|
||
|
return response;
|
||
|
}
|
||
|
|
||
|
int ogs_sbi_parse_request(
|
||
|
ogs_sbi_message_t *message, ogs_sbi_request_t *request)
|
||
|
{
|
||
|
int rv;
|
||
|
ogs_hash_index_t *hi;
|
||
|
ogs_sbi_discovery_option_t *discovery_option = NULL;
|
||
|
bool discovery_option_presence = false;
|
||
|
|
||
|
ogs_assert(request);
|
||
|
ogs_assert(message);
|
||
|
|
||
|
rv = ogs_sbi_parse_header(message, &request->h);
|
||
|
if (rv != OGS_OK) {
|
||
|
ogs_error("ogs_sbi_parse_header() failed");
|
||
|
return OGS_ERROR;
|
||
|
}
|
||
|
|
||
|
discovery_option_presence = false;
|
||
|
discovery_option = ogs_sbi_discovery_option_new();
|
||
|
ogs_assert(discovery_option);
|
||
|
|
||
|
for (hi = ogs_hash_first(request->http.params);
|
||
|
hi; hi = ogs_hash_next(hi)) {
|
||
|
/* Discovery Parameter */
|
||
|
if (!strcmp(ogs_hash_this_key(hi),
|
||
|
OGS_SBI_PARAM_TARGET_NF_TYPE)) {
|
||
|
message->param.target_nf_type =
|
||
|
OpenAPI_nf_type_FromString(ogs_hash_this_val(hi));
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi),
|
||
|
OGS_SBI_PARAM_REQUESTER_NF_TYPE)) {
|
||
|
message->param.requester_nf_type =
|
||
|
OpenAPI_nf_type_FromString(ogs_hash_this_val(hi));
|
||
|
|
||
|
/* Discovery Option Parameter */
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi),
|
||
|
OGS_SBI_PARAM_TARGET_NF_INSTANCE_ID)) {
|
||
|
char *v = ogs_hash_this_val(hi);
|
||
|
|
||
|
if (v) {
|
||
|
ogs_sbi_discovery_option_set_target_nf_instance_id(
|
||
|
discovery_option, v);
|
||
|
discovery_option_presence = true;
|
||
|
}
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi),
|
||
|
OGS_SBI_PARAM_REQUESTER_NF_INSTANCE_ID)) {
|
||
|
char *v = ogs_hash_this_val(hi);
|
||
|
|
||
|
if (v) {
|
||
|
ogs_sbi_discovery_option_set_requester_nf_instance_id(
|
||
|
discovery_option, v);
|
||
|
discovery_option_presence = true;
|
||
|
}
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi),
|
||
|
OGS_SBI_PARAM_SERVICE_NAMES)) {
|
||
|
/*
|
||
|
* Issues #1730
|
||
|
* Send NF discovery query with service-names delimited with comma
|
||
|
*
|
||
|
* OpenAPI specification for sending NF discovery query with
|
||
|
* "service-names" parameter is defined as folowing:
|
||
|
* name: service-names
|
||
|
* ...
|
||
|
* style: form
|
||
|
* explode: false
|
||
|
*
|
||
|
* According to OpenAPI specification, this means array items
|
||
|
* should be delimited with a comma character (example: /users?id=3,4,5).
|
||
|
*
|
||
|
* See also https://swagger.io/docs/specification/serialization/
|
||
|
*/
|
||
|
char *v = ogs_hash_this_val(hi);
|
||
|
if (v) {
|
||
|
ogs_sbi_discovery_option_parse_service_names(
|
||
|
discovery_option, v);
|
||
|
discovery_option_presence = true;
|
||
|
}
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_SNSSAIS)) {
|
||
|
char *v = ogs_hash_this_val(hi);
|
||
|
if (v) {
|
||
|
ogs_sbi_discovery_option_parse_snssais(discovery_option, v);
|
||
|
discovery_option_presence = true;
|
||
|
}
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_DNN)) {
|
||
|
char *v = ogs_hash_this_val(hi);
|
||
|
|
||
|
if (v) {
|
||
|
ogs_sbi_discovery_option_set_dnn(discovery_option, v);
|
||
|
discovery_option_presence = true;
|
||
|
}
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_TAI)) {
|
||
|
char *v = ogs_hash_this_val(hi);
|
||
|
if (v) {
|
||
|
ogs_sbi_discovery_option_parse_tai(discovery_option, v);
|
||
|
discovery_option_presence = true;
|
||
|
}
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi),
|
||
|
OGS_SBI_PARAM_TARGET_PLMN_LIST)) {
|
||
|
char *v = ogs_hash_this_val(hi);
|
||
|
if (v) {
|
||
|
discovery_option->num_of_target_plmn_list =
|
||
|
ogs_sbi_discovery_option_parse_plmn_list(
|
||
|
discovery_option->target_plmn_list, v);
|
||
|
discovery_option_presence = true;
|
||
|
}
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi),
|
||
|
OGS_SBI_PARAM_REQUESTER_PLMN_LIST)) {
|
||
|
char *v = ogs_hash_this_val(hi);
|
||
|
if (v) {
|
||
|
discovery_option->num_of_requester_plmn_list =
|
||
|
ogs_sbi_discovery_option_parse_plmn_list(
|
||
|
discovery_option->requester_plmn_list, v);
|
||
|
discovery_option_presence = true;
|
||
|
}
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi),
|
||
|
OGS_SBI_PARAM_REQUESTER_FEATURES)) {
|
||
|
char *v = ogs_hash_this_val(hi);
|
||
|
if (v) {
|
||
|
discovery_option->requester_features =
|
||
|
ogs_uint64_from_string(v);
|
||
|
discovery_option_presence = true;
|
||
|
}
|
||
|
|
||
|
/* URL Query Parameter */
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_NF_ID)) {
|
||
|
message->param.nf_id = ogs_hash_this_val(hi);
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_NF_TYPE)) {
|
||
|
message->param.nf_type =
|
||
|
OpenAPI_nf_type_FromString(ogs_hash_this_val(hi));
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_LIMIT)) {
|
||
|
message->param.limit = atoi(ogs_hash_this_val(hi));
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_DNN)) {
|
||
|
message->param.dnn = ogs_hash_this_val(hi);
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_PLMN_ID)) {
|
||
|
char *v = NULL;
|
||
|
cJSON *item = NULL;
|
||
|
OpenAPI_plmn_id_t *plmn_id = NULL;
|
||
|
|
||
|
v = ogs_hash_this_val(hi);
|
||
|
if (v) {
|
||
|
item = cJSON_Parse(v);
|
||
|
if (item) {
|
||
|
plmn_id = OpenAPI_plmn_id_parseFromJSON(item);
|
||
|
if (plmn_id && plmn_id->mnc && plmn_id->mcc) {
|
||
|
ogs_plmn_id_build(&message->param.plmn_id,
|
||
|
atoi(plmn_id->mcc),
|
||
|
atoi(plmn_id->mnc), strlen(plmn_id->mnc));
|
||
|
message->param.plmn_id_presence = true;
|
||
|
OpenAPI_plmn_id_free(plmn_id);
|
||
|
}
|
||
|
cJSON_Delete(item);
|
||
|
}
|
||
|
}
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_SINGLE_NSSAI)) {
|
||
|
char *v = ogs_hash_this_val(hi);
|
||
|
if (v) {
|
||
|
bool rc = ogs_sbi_s_nssai_from_json(&message->param.s_nssai, v);
|
||
|
if (rc == true)
|
||
|
message->param.single_nssai_presence = true;
|
||
|
}
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_SNSSAI)) {
|
||
|
char *v = ogs_hash_this_val(hi);
|
||
|
if (v) {
|
||
|
bool rc = ogs_sbi_s_nssai_from_json(&message->param.s_nssai, v);
|
||
|
if (rc == true)
|
||
|
message->param.snssai_presence = true;
|
||
|
}
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi),
|
||
|
OGS_SBI_PARAM_SLICE_INFO_REQUEST_FOR_PDU_SESSION)) {
|
||
|
char *v = NULL;
|
||
|
cJSON *item = NULL;
|
||
|
OpenAPI_slice_info_for_pdu_session_t *SliceInfoForPduSession = NULL;
|
||
|
|
||
|
v = ogs_hash_this_val(hi);
|
||
|
if (v) {
|
||
|
item = cJSON_Parse(v);
|
||
|
if (item) {
|
||
|
SliceInfoForPduSession =
|
||
|
OpenAPI_slice_info_for_pdu_session_parseFromJSON(item);
|
||
|
if (SliceInfoForPduSession) {
|
||
|
OpenAPI_snssai_t *s_nssai =
|
||
|
SliceInfoForPduSession->s_nssai;
|
||
|
if (s_nssai) {
|
||
|
message->param.s_nssai.sst = s_nssai->sst;
|
||
|
message->param.s_nssai.sd =
|
||
|
ogs_s_nssai_sd_from_string(s_nssai->sd);
|
||
|
}
|
||
|
message->param.roaming_indication =
|
||
|
SliceInfoForPduSession->roaming_indication;
|
||
|
message->param.
|
||
|
slice_info_request_for_pdu_session_presence = true;
|
||
|
|
||
|
OpenAPI_slice_info_for_pdu_session_free(
|
||
|
SliceInfoForPduSession);
|
||
|
|
||
|
}
|
||
|
cJSON_Delete(item);
|
||
|
}
|
||
|
}
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_IPV4ADDR)) {
|
||
|
message->param.ipv4addr = ogs_hash_this_val(hi);
|
||
|
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_IPV6PREFIX)) {
|
||
|
message->param.ipv6prefix = ogs_hash_this_val(hi);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (discovery_option_presence == true)
|
||
|
/* message->param.discovery_option will be freed()
|
||
|
* in ogs_sbi_message_free() */
|
||
|
message->param.discovery_option = discovery_option;
|
||
|
else
|
||
|
ogs_sbi_discovery_option_free(discovery_option);
|
||
|
|
||
|
for (hi = ogs_hash_first(request->http.headers);
|
||
|
hi; hi = ogs_hash_next(hi)) {
|
||
|
/*
|
||
|
* <RFC 2616>
|
||
|
* Each header field consists of a name followed by a colon (":")
|
||
|
* and the field value. Field names are case-insensitive.
|
||
|
*/
|
||
|
if (!ogs_strcasecmp(ogs_hash_this_key(hi), OGS_SBI_ACCEPT_ENCODING)) {
|
||
|
message->http.content_encoding = ogs_hash_this_val(hi);
|
||
|
} else if (!ogs_strcasecmp(
|
||
|
ogs_hash_this_key(hi), OGS_SBI_CONTENT_TYPE)) {
|
||
|
message->http.content_type = ogs_hash_this_val(hi);
|
||
|
} else if (!ogs_strcasecmp(ogs_hash_this_key(hi), OGS_SBI_ACCEPT)) {
|
||
|
message->http.accept = ogs_hash_this_val(hi);
|
||
|
} else if (!ogs_strcasecmp(ogs_hash_this_key(hi),
|
||
|
OGS_SBI_CUSTOM_CALLBACK)) {
|
||
|
message->http.custom.callback = ogs_hash_this_val(hi);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (parse_content(message, &request->http) != OGS_OK) {
|
||
|
ogs_error("parse_content() failed");
|
||
|
ogs_sbi_message_free(message);
|
||
|
return OGS_ERROR;
|
||
|
}
|
||
|
|
||
|
return OGS_OK;
|
||
|
}
|
||
|
|
||
|
int ogs_sbi_parse_response(
|
||
|
ogs_sbi_message_t *message, ogs_sbi_response_t *response)
|
||
|
{
|
||
|
int rv;
|
||
|
ogs_hash_index_t *hi;
|
||
|
|
||
|
ogs_assert(response);
|
||
|
ogs_assert(message);
|
||
|
|
||
|
rv = ogs_sbi_parse_header(message, &response->h);
|
||
|
if (rv != OGS_OK) {
|
||
|
ogs_error("ogs_sbi_parse_header() failed");
|
||
|
return OGS_ERROR;
|
||
|
}
|
||
|
|
||
|
for (hi = ogs_hash_first(response->http.headers);
|
||
|
hi; hi = ogs_hash_next(hi)) {
|
||
|
if (!ogs_strcasecmp(ogs_hash_this_key(hi), OGS_SBI_CONTENT_TYPE)) {
|
||
|
message->http.content_type = ogs_hash_this_val(hi);
|
||
|
} else if (!ogs_strcasecmp(ogs_hash_this_key(hi), OGS_SBI_LOCATION)) {
|
||
|
message->http.location = ogs_hash_this_val(hi);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
message->res_status = response->status;
|
||
|
|
||
|
if (parse_content(message, &response->http) != OGS_OK) {
|
||
|
ogs_error("parse_content() failed");
|
||
|
return OGS_ERROR;
|
||
|
}
|
||
|
|
||
|
return OGS_OK;
|
||
|
}
|
||
|
|
||
|
ogs_pkbuf_t *ogs_sbi_find_part_by_content_id(
|
||
|
ogs_sbi_message_t *message, char *content_id)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
ogs_assert(message);
|
||
|
ogs_assert(content_id);
|
||
|
|
||
|
for (i = 0; i < message->num_of_part; i++) {
|
||
|
if (message->part[i].content_id &&
|
||
|
strcmp(message->part[i].content_id, content_id) == 0)
|
||
|
return message->part[i].pkbuf;
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
int ogs_sbi_parse_header(ogs_sbi_message_t *message, ogs_sbi_header_t *header)
|
||
|
{
|
||
|
struct yuarel yuarel;
|
||
|
char *saveptr = NULL;
|
||
|
char *uri = NULL, *p = NULL;
|
||
|
|
||
|
char *component = NULL;
|
||
|
int i = 0;
|
||
|
|
||
|
ogs_assert(message);
|
||
|
ogs_assert(header);
|
||
|
|
||
|
memset(message, 0, sizeof(ogs_sbi_message_t));
|
||
|
|
||
|
message->h.method = header->method;
|
||
|
message->h.uri = header->uri;
|
||
|
ogs_assert(message->h.uri);
|
||
|
|
||
|
uri = ogs_strdup(header->uri);
|
||
|
ogs_assert(uri);
|
||
|
p = uri;
|
||
|
|
||
|
if (p[0] != '/') {
|
||
|
int rv = yuarel_parse(&yuarel, p);
|
||
|
if (rv != OGS_OK) {
|
||
|
ogs_error("yuarel_parse() failed");
|
||
|
ogs_free(uri);
|
||
|
return OGS_ERROR;
|
||
|
}
|
||
|
|
||
|
p = yuarel.path;
|
||
|
}
|
||
|
|
||
|
header->service.name = ogs_sbi_parse_uri(p, "/", &saveptr);
|
||
|
if (!header->service.name) {
|
||
|
ogs_error("ogs_sbi_parse_uri() failed");
|
||
|
ogs_free(uri);
|
||
|
return OGS_ERROR;
|
||
|
}
|
||
|
message->h.service.name = header->service.name;
|
||
|
|
||
|
header->api.version = ogs_sbi_parse_uri(NULL, "/", &saveptr);
|
||
|
if (!header->api.version) {
|
||
|
ogs_error("ogs_sbi_parse_uri() failed");
|
||
|
ogs_free(uri);
|
||
|
return OGS_ERROR;
|
||
|
}
|
||
|
message->h.api.version = header->api.version;
|
||
|
|
||
|
for (i = 0; i < OGS_SBI_MAX_NUM_OF_RESOURCE_COMPONENT &&
|
||
|
(component = ogs_sbi_parse_uri(NULL, "/", &saveptr)) != NULL;
|
||
|
i++) {
|
||
|
header->resource.component[i] = component;
|
||
|
message->h.resource.component[i] = component;
|
||
|
}
|
||
|
|
||
|
ogs_free(uri);
|
||
|
|
||
|
return OGS_OK;
|
||
|
}
|
||
|
|
||
|
void ogs_sbi_header_free(ogs_sbi_header_t *h)
|
||
|
{
|
||
|
int i;
|
||
|
ogs_assert(h);
|
||
|
|
||
|
if (h->method) ogs_free(h->method);
|
||
|
if (h->service.name) ogs_free(h->service.name);
|
||
|
if (h->api.version) ogs_free(h->api.version);
|
||
|
|
||
|
for (i = 0; i < OGS_SBI_MAX_NUM_OF_RESOURCE_COMPONENT &&
|
||
|
h->resource.component[i]; i++)
|
||
|
ogs_free(h->resource.component[i]);
|
||
|
}
|
||
|
|
||
|
void ogs_sbi_http_hash_free(ogs_hash_t *hash)
|
||
|
{
|
||
|
ogs_hash_index_t *hi;
|
||
|
|
||
|
ogs_assert(hash);
|
||
|
|
||
|
for (hi = ogs_hash_first(hash); hi; hi = ogs_hash_next(hi)) {
|
||
|
char *key = (char *)ogs_hash_this_key(hi);
|
||
|
char *val = ogs_hash_this_val(hi);
|
||
|
ogs_hash_set(hash, key, strlen(key), NULL);
|
||
|
ogs_free(key);
|
||
|
ogs_free(val);
|
||
|
}
|
||
|
ogs_hash_destroy(hash);
|
||
|
}
|
||
|
|
||
|
static char *build_json(ogs_sbi_message_t *message)
|
||
|
{
|
||
|
char *content = NULL;
|
||
|
cJSON *item = NULL;
|
||
|
|
||
|
ogs_assert(message);
|
||
|
|
||
|
if (message->ProblemDetails) {
|
||
|
item = OpenAPI_problem_details_convertToJSON(message->ProblemDetails);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->NFProfile) {
|
||
|
item = OpenAPI_nf_profile_convertToJSON(message->NFProfile);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->PatchItemList) {
|
||
|
OpenAPI_lnode_t *node = NULL;
|
||
|
|
||
|
item = cJSON_CreateArray();
|
||
|
ogs_assert(item);
|
||
|
|
||
|
OpenAPI_list_for_each(message->PatchItemList, node) {
|
||
|
cJSON *patchItem = OpenAPI_patch_item_convertToJSON(node->data);
|
||
|
ogs_assert(patchItem);
|
||
|
cJSON_AddItemToArray(item, patchItem);
|
||
|
}
|
||
|
} else if (message->SubscriptionData) {
|
||
|
item = OpenAPI_subscription_data_convertToJSON(
|
||
|
message->SubscriptionData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->NotificationData) {
|
||
|
item = OpenAPI_notification_data_convertToJSON(
|
||
|
message->NotificationData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SearchResult) {
|
||
|
item = OpenAPI_search_result_convertToJSON(message->SearchResult);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->links) {
|
||
|
item = ogs_sbi_links_convertToJSON(message->links);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->AuthenticationInfo) {
|
||
|
item = OpenAPI_authentication_info_convertToJSON(
|
||
|
message->AuthenticationInfo);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->AuthenticationInfoRequest) {
|
||
|
item = OpenAPI_authentication_info_request_convertToJSON(
|
||
|
message->AuthenticationInfoRequest);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->AuthenticationInfoResult) {
|
||
|
item = OpenAPI_authentication_info_result_convertToJSON(
|
||
|
message->AuthenticationInfoResult);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->AuthenticationSubscription) {
|
||
|
item = OpenAPI_authentication_subscription_convertToJSON(
|
||
|
message->AuthenticationSubscription);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->UeAuthenticationCtx) {
|
||
|
item = OpenAPI_ue_authentication_ctx_convertToJSON(
|
||
|
message->UeAuthenticationCtx);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->ConfirmationData) {
|
||
|
item = OpenAPI_confirmation_data_convertToJSON(
|
||
|
message->ConfirmationData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->ConfirmationDataResponse) {
|
||
|
item = OpenAPI_confirmation_data_response_convertToJSON(
|
||
|
message->ConfirmationDataResponse);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->AuthEvent) {
|
||
|
item = OpenAPI_auth_event_convertToJSON(message->AuthEvent);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->Amf3GppAccessRegistration) {
|
||
|
item = OpenAPI_amf3_gpp_access_registration_convertToJSON(
|
||
|
message->Amf3GppAccessRegistration);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->Amf3GppAccessRegistrationModification) {
|
||
|
item = OpenAPI_amf3_gpp_access_registration_modification_convertToJSON(
|
||
|
message->Amf3GppAccessRegistrationModification);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmfRegistration) {
|
||
|
item = OpenAPI_smf_registration_convertToJSON(message->SmfRegistration);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->AccessAndMobilitySubscriptionData) {
|
||
|
item = OpenAPI_access_and_mobility_subscription_data_convertToJSON(
|
||
|
message->AccessAndMobilitySubscriptionData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmfSelectionSubscriptionData) {
|
||
|
item = OpenAPI_smf_selection_subscription_data_convertToJSON(
|
||
|
message->SmfSelectionSubscriptionData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->UeContextInSmfData) {
|
||
|
item = OpenAPI_ue_context_in_smf_data_convertToJSON(
|
||
|
message->UeContextInSmfData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmContextCreateData) {
|
||
|
item = OpenAPI_sm_context_create_data_convertToJSON(
|
||
|
message->SmContextCreateData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmContextCreatedData) {
|
||
|
item = OpenAPI_sm_context_created_data_convertToJSON(
|
||
|
message->SmContextCreatedData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmContextCreateError) {
|
||
|
item = OpenAPI_sm_context_create_error_convertToJSON(
|
||
|
message->SmContextCreateError);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmContextUpdateData) {
|
||
|
item = OpenAPI_sm_context_update_data_convertToJSON(
|
||
|
message->SmContextUpdateData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmContextUpdatedData) {
|
||
|
item = OpenAPI_sm_context_updated_data_convertToJSON(
|
||
|
message->SmContextUpdatedData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmContextUpdateError) {
|
||
|
item = OpenAPI_sm_context_update_error_convertToJSON(
|
||
|
message->SmContextUpdateError);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmContextReleaseData) {
|
||
|
item = OpenAPI_sm_context_release_data_convertToJSON(
|
||
|
message->SmContextReleaseData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmContextReleasedData) {
|
||
|
item = OpenAPI_sm_context_released_data_convertToJSON(
|
||
|
message->SmContextReleasedData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SessionManagementSubscriptionDataList) {
|
||
|
OpenAPI_lnode_t *node = NULL;
|
||
|
|
||
|
item = cJSON_CreateArray();
|
||
|
ogs_assert(item);
|
||
|
|
||
|
OpenAPI_list_for_each(message->SessionManagementSubscriptionDataList, node) {
|
||
|
cJSON *smSubDataItem =
|
||
|
OpenAPI_session_management_subscription_data_convertToJSON(node->data);
|
||
|
ogs_assert(smSubDataItem);
|
||
|
cJSON_AddItemToArray(item, smSubDataItem);
|
||
|
}
|
||
|
} else if (message->N1N2MessageTransferReqData) {
|
||
|
item = OpenAPI_n1_n2_message_transfer_req_data_convertToJSON(
|
||
|
message->N1N2MessageTransferReqData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->N1N2MessageTransferRspData) {
|
||
|
item = OpenAPI_n1_n2_message_transfer_rsp_data_convertToJSON(
|
||
|
message->N1N2MessageTransferRspData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->N1N2MsgTxfrFailureNotification) {
|
||
|
item = OpenAPI_n1_n2_msg_txfr_failure_notification_convertToJSON(
|
||
|
message->N1N2MsgTxfrFailureNotification);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmContextStatusNotification) {
|
||
|
item = OpenAPI_sm_context_status_notification_convertToJSON(
|
||
|
message->SmContextStatusNotification);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->PolicyAssociationRequest) {
|
||
|
item = OpenAPI_policy_association_request_convertToJSON(
|
||
|
message->PolicyAssociationRequest);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->PolicyAssociation) {
|
||
|
item = OpenAPI_policy_association_convertToJSON(
|
||
|
message->PolicyAssociation);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->AmPolicyData) {
|
||
|
item = OpenAPI_am_policy_data_convertToJSON(message->AmPolicyData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmPolicyContextData) {
|
||
|
item = OpenAPI_sm_policy_context_data_convertToJSON(
|
||
|
message->SmPolicyContextData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmPolicyDecision) {
|
||
|
item = OpenAPI_sm_policy_decision_convertToJSON(
|
||
|
message->SmPolicyDecision);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmPolicyData) {
|
||
|
item = OpenAPI_sm_policy_data_convertToJSON(message->SmPolicyData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmPolicyDeleteData) {
|
||
|
item = OpenAPI_sm_policy_delete_data_convertToJSON(
|
||
|
message->SmPolicyDeleteData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->AuthorizedNetworkSliceInfo) {
|
||
|
item = OpenAPI_authorized_network_slice_info_convertToJSON(
|
||
|
message->AuthorizedNetworkSliceInfo);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->PcfBinding) {
|
||
|
item = OpenAPI_pcf_binding_convertToJSON(message->PcfBinding);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->AppSessionContext) {
|
||
|
item = OpenAPI_app_session_context_convertToJSON(
|
||
|
message->AppSessionContext);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->AppSessionContextUpdateDataPatch) {
|
||
|
item = OpenAPI_app_session_context_update_data_patch_convertToJSON(
|
||
|
message->AppSessionContextUpdateDataPatch);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SmPolicyNotification) {
|
||
|
item = OpenAPI_sm_policy_notification_convertToJSON(
|
||
|
message->SmPolicyNotification);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->TerminationNotification) {
|
||
|
item = OpenAPI_termination_notification_convertToJSON(
|
||
|
message->TerminationNotification);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->DeregistrationData) {
|
||
|
item = OpenAPI_deregistration_data_convertToJSON(
|
||
|
message->DeregistrationData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SDMSubscription) {
|
||
|
item = OpenAPI_sdm_subscription_convertToJSON(
|
||
|
message->SDMSubscription);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->ModificationNotification) {
|
||
|
item = OpenAPI_modification_notification_convertToJSON(
|
||
|
message->ModificationNotification);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SecNegotiateReqData) {
|
||
|
item = OpenAPI_sec_negotiate_req_data_convertToJSON(
|
||
|
message->SecNegotiateReqData);
|
||
|
ogs_assert(item);
|
||
|
} else if (message->SecNegotiateRspData) {
|
||
|
item = OpenAPI_sec_negotiate_rsp_data_convertToJSON(
|
||
|
message->SecNegotiateRspData);
|
||
|
ogs_assert(item);
|
||
|
}
|
||
|
|
||
|
if (item) {
|
||
|
content = cJSON_PrintUnformatted(item);
|
||
|
ogs_assert(content);
|
||
|
ogs_log_print(OGS_LOG_TRACE, "%s", content);
|
||
|
cJSON_Delete(item);
|
||
|
}
|
||
|
|
||
|
return content;
|
||
|
}
|
||
|
|
||
|
static int parse_json(ogs_sbi_message_t *message,
|
||
|
char *content_type, char *json)
|
||
|
{
|
||
|
int rv = OGS_OK;
|
||
|
cJSON *item = NULL;
|
||
|
|
||
|
ogs_assert(message);
|
||
|
|
||
|
if (!json)
|
||
|
return OGS_OK;
|
||
|
|
||
|
if (!content_type) {
|
||
|
ogs_error("No Content-type");
|
||
|
return OGS_ERROR;
|
||
|
}
|
||
|
|
||
|
ogs_log_print(OGS_LOG_TRACE, "%s", json);
|
||
|
item = cJSON_Parse(json);
|
||
|
if (!item) {
|
||
|
ogs_error("JSON parse error [%s]", json);
|
||
|
return OGS_ERROR;
|
||
|
}
|
||
|
|
||
|
if (content_type &&
|
||
|
!strncmp(content_type, OGS_SBI_CONTENT_PROBLEM_TYPE,
|
||
|
strlen(OGS_SBI_CONTENT_PROBLEM_TYPE))) {
|
||
|
message->ProblemDetails = OpenAPI_problem_details_parseFromJSON(item);
|
||
|
} else if (content_type &&
|
||
|
!strncmp(content_type, OGS_SBI_CONTENT_PATCH_TYPE,
|
||
|
strlen(OGS_SBI_CONTENT_PATCH_TYPE))) {
|
||
|
if (item) {
|
||
|
OpenAPI_patch_item_t *patch_item = NULL;
|
||
|
cJSON *patchJSON = NULL;
|
||
|
message->PatchItemList = OpenAPI_list_create();
|
||
|
cJSON_ArrayForEach(patchJSON, item) {
|
||
|
if (!cJSON_IsObject(patchJSON)) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown JSON");
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
patch_item = OpenAPI_patch_item_parseFromJSON(patchJSON);
|
||
|
if (!patch_item) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("No PatchItem");
|
||
|
goto cleanup;
|
||
|
}
|
||
|
OpenAPI_list_add(message->PatchItemList, patch_item);
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
SWITCH(message->h.service.name)
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
|
||
|
|
||
|
SWITCH(message->h.resource.component[0])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||
|
if (message->res_status < 300) {
|
||
|
message->NFProfile =
|
||
|
OpenAPI_nf_profile_parseFromJSON(item);
|
||
|
if (!message->NFProfile) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d", message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
|
||
|
if (message->res_status < 300) {
|
||
|
message->SubscriptionData =
|
||
|
OpenAPI_subscription_data_parseFromJSON(item);
|
||
|
if (!message->SubscriptionData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d", message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_NF_STATUS_NOTIFY)
|
||
|
if (message->res_status < 300) {
|
||
|
message->NotificationData =
|
||
|
OpenAPI_notification_data_parseFromJSON(item);
|
||
|
if (!message->NotificationData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d", message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[0]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NNRF_DISC)
|
||
|
SWITCH(message->h.resource.component[0])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||
|
if (message->res_status < 300) {
|
||
|
message->SearchResult =
|
||
|
OpenAPI_search_result_parseFromJSON(item);
|
||
|
if (!message->SearchResult) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d", message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[0]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NAUSF_AUTH)
|
||
|
SWITCH(message->h.resource.component[0])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_UE_AUTHENTICATIONS)
|
||
|
SWITCH(message->h.method)
|
||
|
CASE(OGS_SBI_HTTP_METHOD_POST)
|
||
|
if (message->res_status == 0) {
|
||
|
message->AuthenticationInfo =
|
||
|
OpenAPI_authentication_info_parseFromJSON(item);
|
||
|
if (!message->AuthenticationInfo) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else if (message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_CREATED) {
|
||
|
message->UeAuthenticationCtx =
|
||
|
OpenAPI_ue_authentication_ctx_parseFromJSON(item);
|
||
|
if (!message->UeAuthenticationCtx) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
CASE(OGS_SBI_HTTP_METHOD_PUT)
|
||
|
if (message->res_status == 0) {
|
||
|
message->ConfirmationData =
|
||
|
OpenAPI_confirmation_data_parseFromJSON(item);
|
||
|
if (!message->ConfirmationData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else if (message->res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||
|
message->ConfirmationDataResponse =
|
||
|
OpenAPI_confirmation_data_response_parseFromJSON(
|
||
|
item);
|
||
|
if (!message->ConfirmationDataResponse) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown method [%s]", message->h.method);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[0]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NUDM_UEAU)
|
||
|
SWITCH(message->h.resource.component[1])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SECURITY_INFORMATION)
|
||
|
SWITCH(message->h.resource.component[2])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_GENERATE_AUTH_DATA)
|
||
|
if (message->res_status == 0) {
|
||
|
message->AuthenticationInfoRequest =
|
||
|
OpenAPI_authentication_info_request_parseFromJSON(
|
||
|
item);
|
||
|
if (!message->AuthenticationInfoRequest) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else if (message->res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||
|
message->AuthenticationInfoResult =
|
||
|
OpenAPI_authentication_info_result_parseFromJSON(
|
||
|
item);
|
||
|
if (!message->AuthenticationInfoResult) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[2]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_AUTH_EVENTS)
|
||
|
if (message->res_status < 300) {
|
||
|
message->AuthEvent = OpenAPI_auth_event_parseFromJSON(item);
|
||
|
if (!message->AuthEvent) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d", message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[1]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NUDM_UECM)
|
||
|
SWITCH(message->h.resource.component[1])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_REGISTRATIONS)
|
||
|
SWITCH(message->h.resource.component[2])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_AMF_3GPP_ACCESS)
|
||
|
SWITCH(message->h.method)
|
||
|
CASE(OGS_SBI_HTTP_METHOD_PUT)
|
||
|
if (message->res_status < 300) {
|
||
|
message->Amf3GppAccessRegistration =
|
||
|
OpenAPI_amf3_gpp_access_registration_parseFromJSON(
|
||
|
item);
|
||
|
if (!message->Amf3GppAccessRegistration) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
CASE(OGS_SBI_HTTP_METHOD_PATCH)
|
||
|
if (message->res_status < 300) {
|
||
|
message->Amf3GppAccessRegistrationModification =
|
||
|
OpenAPI_amf3_gpp_access_registration_modification_parseFromJSON(
|
||
|
item);
|
||
|
if (!message->Amf3GppAccessRegistrationModification) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown method [%s]", message->h.method);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SMF_REGISTRATIONS)
|
||
|
if (message->res_status < 300) {
|
||
|
message->SmfRegistration =
|
||
|
OpenAPI_smf_registration_parseFromJSON(item);
|
||
|
if (!message->SmfRegistration) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[2]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[1]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NUDM_SDM)
|
||
|
SWITCH(message->h.resource.component[1])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_AM_DATA)
|
||
|
if (message->res_status < 300) {
|
||
|
message->AccessAndMobilitySubscriptionData =
|
||
|
OpenAPI_access_and_mobility_subscription_data_parseFromJSON(
|
||
|
item);
|
||
|
if (!message->AccessAndMobilitySubscriptionData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d", message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SMF_SELECT_DATA)
|
||
|
if (message->res_status < 300) {
|
||
|
message->SmfSelectionSubscriptionData =
|
||
|
OpenAPI_smf_selection_subscription_data_parseFromJSON(
|
||
|
item);
|
||
|
if (!message->SmfSelectionSubscriptionData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d", message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXT_IN_SMF_DATA)
|
||
|
if (message->res_status < 300) {
|
||
|
message->UeContextInSmfData =
|
||
|
OpenAPI_ue_context_in_smf_data_parseFromJSON(item);
|
||
|
if (!message->UeContextInSmfData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d", message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SM_DATA)
|
||
|
if (message->res_status < 300) {
|
||
|
if (item) {
|
||
|
OpenAPI_session_management_subscription_data_t
|
||
|
*smsub_item = NULL;
|
||
|
cJSON *smsubJSON = NULL;
|
||
|
message->SessionManagementSubscriptionDataList =
|
||
|
OpenAPI_list_create();
|
||
|
cJSON_ArrayForEach(smsubJSON, item) {
|
||
|
if (!cJSON_IsObject(smsubJSON)) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown JSON");
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
smsub_item = OpenAPI_session_management_subscription_data_parseFromJSON(smsubJSON);
|
||
|
if (!smsub_item) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("No smsub_item");
|
||
|
goto cleanup;
|
||
|
}
|
||
|
OpenAPI_list_add(message->SessionManagementSubscriptionDataList, smsub_item);
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d", message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SDM_SUBSCRIPTIONS)
|
||
|
if (message->res_status < 300) {
|
||
|
message->SDMSubscription =
|
||
|
OpenAPI_sdm_subscription_parseFromJSON(item);
|
||
|
if (!message->SDMSubscription) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d", message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[1]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NUDR_DR)
|
||
|
SWITCH(message->h.resource.component[0])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTION_DATA)
|
||
|
SWITCH(message->h.resource.component[2])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_AUTHENTICATION_DATA)
|
||
|
SWITCH(message->h.resource.component[3])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_AUTHENTICATION_SUBSCRIPTION)
|
||
|
if (message->res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||
|
message->AuthenticationSubscription =
|
||
|
OpenAPI_authentication_subscription_parseFromJSON(item);
|
||
|
if (!message->AuthenticationSubscription) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_AUTHENTICATION_STATUS)
|
||
|
if (message->res_status < 300) {
|
||
|
message->AuthEvent =
|
||
|
OpenAPI_auth_event_parseFromJSON(item);
|
||
|
if (!message->AuthEvent) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[3]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_CONTEXT_DATA)
|
||
|
SWITCH(message->h.resource.component[3])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_AMF_3GPP_ACCESS)
|
||
|
if (message->res_status < 300) {
|
||
|
message->Amf3GppAccessRegistration =
|
||
|
OpenAPI_amf3_gpp_access_registration_parseFromJSON(
|
||
|
item);
|
||
|
if (!message->Amf3GppAccessRegistration) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SMF_REGISTRATIONS)
|
||
|
if (message->res_status < 300) {
|
||
|
message->SmfRegistration =
|
||
|
OpenAPI_smf_registration_parseFromJSON(item);
|
||
|
if (!message->SmfRegistration) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[3]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
SWITCH(message->h.resource.component[3])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_PROVISIONED_DATA)
|
||
|
SWITCH(message->h.resource.component[4])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_AM_DATA)
|
||
|
if (message->res_status < 300) {
|
||
|
message->AccessAndMobilitySubscriptionData =
|
||
|
OpenAPI_access_and_mobility_subscription_data_parseFromJSON(item);
|
||
|
if (!message->
|
||
|
AccessAndMobilitySubscriptionData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SMF_SELECTION_SUBSCRIPTION_DATA)
|
||
|
if (message->res_status < 300) {
|
||
|
message->SmfSelectionSubscriptionData =
|
||
|
OpenAPI_smf_selection_subscription_data_parseFromJSON(item);
|
||
|
if (!message->SmfSelectionSubscriptionData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXT_IN_SMF_DATA)
|
||
|
if (message->res_status < 300) {
|
||
|
message->UeContextInSmfData =
|
||
|
OpenAPI_ue_context_in_smf_data_parseFromJSON(
|
||
|
item);
|
||
|
if (!message->UeContextInSmfData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SM_DATA)
|
||
|
if (message->res_status < 300) {
|
||
|
if (item) {
|
||
|
OpenAPI_session_management_subscription_data_t *smsub_item = NULL;
|
||
|
cJSON *smsubJSON = NULL;
|
||
|
message->SessionManagementSubscriptionDataList = OpenAPI_list_create();
|
||
|
cJSON_ArrayForEach(smsubJSON, item) {
|
||
|
if (!cJSON_IsObject(smsubJSON)) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown JSON");
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
smsub_item = OpenAPI_session_management_subscription_data_parseFromJSON(smsubJSON);
|
||
|
if (!smsub_item) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("No smsub_item");
|
||
|
goto cleanup;
|
||
|
}
|
||
|
OpenAPI_list_add(message->SessionManagementSubscriptionDataList, smsub_item);
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[4]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[3]);
|
||
|
END
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_POLICY_DATA)
|
||
|
SWITCH(message->h.resource.component[1])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_UES)
|
||
|
SWITCH(message->h.resource.component[3])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_AM_DATA)
|
||
|
if (message->res_status < 300) {
|
||
|
message->AmPolicyData =
|
||
|
OpenAPI_am_policy_data_parseFromJSON(item);
|
||
|
if (!message->AmPolicyData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SM_DATA)
|
||
|
if (message->res_status < 300) {
|
||
|
message->SmPolicyData =
|
||
|
OpenAPI_sm_policy_data_parseFromJSON(item);
|
||
|
if (!message->SmPolicyData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[3]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[1]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[0]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION)
|
||
|
SWITCH(message->h.resource.component[0])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SM_CONTEXTS)
|
||
|
SWITCH(message->h.resource.component[2])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_MODIFY)
|
||
|
if (message->res_status == 0) {
|
||
|
message->SmContextUpdateData =
|
||
|
OpenAPI_sm_context_update_data_parseFromJSON(item);
|
||
|
if (!message->SmContextUpdateData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else if (message->res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||
|
message->SmContextUpdatedData =
|
||
|
OpenAPI_sm_context_updated_data_parseFromJSON(item);
|
||
|
if (!message->SmContextUpdatedData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else if (message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST ||
|
||
|
message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_FORBIDDEN ||
|
||
|
message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_NOT_FOUND ||
|
||
|
message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR ||
|
||
|
message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_SERVICE_UNAVAILABLE ||
|
||
|
message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT) {
|
||
|
message->SmContextUpdateError =
|
||
|
OpenAPI_sm_context_update_error_parseFromJSON(item);
|
||
|
if (!message->SmContextUpdateError) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_RELEASE)
|
||
|
if (message->res_status == 0) {
|
||
|
message->SmContextReleaseData =
|
||
|
OpenAPI_sm_context_release_data_parseFromJSON(item);
|
||
|
if (!message->SmContextReleaseData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else if (message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_NO_CONTENT) {
|
||
|
} else if (message->res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||
|
message->SmContextReleasedData =
|
||
|
OpenAPI_sm_context_released_data_parseFromJSON(
|
||
|
item);
|
||
|
if (!message->SmContextReleasedData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
DEFAULT
|
||
|
if (message->res_status == 0) {
|
||
|
message->SmContextCreateData =
|
||
|
OpenAPI_sm_context_create_data_parseFromJSON(item);
|
||
|
if (!message->SmContextCreateData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else if (message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_CREATED) {
|
||
|
message->SmContextCreatedData =
|
||
|
OpenAPI_sm_context_created_data_parseFromJSON(item);
|
||
|
if (!message->SmContextCreatedData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else if (message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST ||
|
||
|
message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_FORBIDDEN ||
|
||
|
message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_NOT_FOUND ||
|
||
|
message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR ||
|
||
|
message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_SERVICE_UNAVAILABLE ||
|
||
|
message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT) {
|
||
|
message->SmContextCreateError =
|
||
|
OpenAPI_sm_context_create_error_parseFromJSON(item);
|
||
|
if (!message->SmContextCreateError) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[0]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NAMF_COMM)
|
||
|
SWITCH(message->h.resource.component[0])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXTS)
|
||
|
SWITCH(message->h.resource.component[2])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_N1_N2_MESSAGES)
|
||
|
if (message->res_status == 0) {
|
||
|
message->N1N2MessageTransferReqData =
|
||
|
OpenAPI_n1_n2_message_transfer_req_data_parseFromJSON(item);
|
||
|
if (!message->N1N2MessageTransferReqData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else if (message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_OK ||
|
||
|
message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_ACCEPTED) {
|
||
|
message->N1N2MessageTransferRspData =
|
||
|
OpenAPI_n1_n2_message_transfer_rsp_data_parseFromJSON(item);
|
||
|
if (!message->N1N2MessageTransferRspData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[2]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[0]);
|
||
|
END
|
||
|
break;
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NPCF_AM_POLICY_CONTROL)
|
||
|
SWITCH(message->h.resource.component[0])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_POLICIES)
|
||
|
if (message->res_status == 0) {
|
||
|
message->PolicyAssociationRequest =
|
||
|
OpenAPI_policy_association_request_parseFromJSON(item);
|
||
|
if (!message->PolicyAssociationRequest) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else if (message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_CREATED) {
|
||
|
message->PolicyAssociation =
|
||
|
OpenAPI_policy_association_parseFromJSON(item);
|
||
|
if (!message->PolicyAssociation) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[0]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NPCF_SMPOLICYCONTROL)
|
||
|
SWITCH(message->h.resource.component[0])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SM_POLICIES)
|
||
|
if (!message->h.resource.component[1]) {
|
||
|
if (message->res_status == 0) {
|
||
|
message->SmPolicyContextData =
|
||
|
OpenAPI_sm_policy_context_data_parseFromJSON(item);
|
||
|
if (!message->SmPolicyContextData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else if (message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_CREATED) {
|
||
|
message->SmPolicyDecision =
|
||
|
OpenAPI_sm_policy_decision_parseFromJSON(item);
|
||
|
if (!message->SmPolicyDecision) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
SWITCH(message->h.resource.component[2])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_DELETE)
|
||
|
if (message->res_status == 0) {
|
||
|
message->SmPolicyDeleteData =
|
||
|
OpenAPI_sm_policy_delete_data_parseFromJSON(
|
||
|
item);
|
||
|
if (!message->SmPolicyDeleteData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[2]);
|
||
|
END
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[0]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NNSSF_NSSELECTION)
|
||
|
SWITCH(message->h.resource.component[0])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_NETWORK_SLICE_INFORMATION)
|
||
|
if (message->res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||
|
message->AuthorizedNetworkSliceInfo =
|
||
|
OpenAPI_authorized_network_slice_info_parseFromJSON(
|
||
|
item);
|
||
|
if (!message->AuthorizedNetworkSliceInfo) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[0]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NBSF_MANAGEMENT)
|
||
|
SWITCH(message->h.resource.component[0])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_PCF_BINDINGS)
|
||
|
if (message->h.resource.component[1]) {
|
||
|
if (message->res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||
|
message->PcfBinding =
|
||
|
OpenAPI_pcf_binding_parseFromJSON(item);
|
||
|
if (!message->PcfBinding) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
} else {
|
||
|
SWITCH(message->h.method)
|
||
|
CASE(OGS_SBI_HTTP_METHOD_POST)
|
||
|
if (message->res_status == 0 ||
|
||
|
message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_CREATED) {
|
||
|
message->PcfBinding =
|
||
|
OpenAPI_pcf_binding_parseFromJSON(item);
|
||
|
if (!message->PcfBinding) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_HTTP_METHOD_GET)
|
||
|
if (message->res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||
|
message->PcfBinding =
|
||
|
OpenAPI_pcf_binding_parseFromJSON(item);
|
||
|
if (!message->PcfBinding) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown method [%s]", message->h.method);
|
||
|
END
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[0]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NPCF_POLICYAUTHORIZATION)
|
||
|
SWITCH(message->h.resource.component[0])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_APP_SESSIONS)
|
||
|
if (message->h.resource.component[1]) {
|
||
|
if (message->h.resource.component[2]) {
|
||
|
SWITCH(message->h.resource.component[2])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_DELETE)
|
||
|
/* Nothing */
|
||
|
break;
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
END
|
||
|
} else {
|
||
|
SWITCH(message->h.method)
|
||
|
CASE(OGS_SBI_HTTP_METHOD_PATCH)
|
||
|
if (message->res_status < 300) {
|
||
|
message->AppSessionContextUpdateDataPatch =
|
||
|
OpenAPI_app_session_context_update_data_patch_parseFromJSON(item);
|
||
|
if (!message->AppSessionContextUpdateDataPatch) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
END
|
||
|
}
|
||
|
} else {
|
||
|
SWITCH(message->h.method)
|
||
|
CASE(OGS_SBI_HTTP_METHOD_POST)
|
||
|
if (message->res_status == 0 ||
|
||
|
message->res_status ==
|
||
|
OGS_SBI_HTTP_STATUS_CREATED) {
|
||
|
message->AppSessionContext =
|
||
|
OpenAPI_app_session_context_parseFromJSON(item);
|
||
|
if (!message->AppSessionContext) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown method [%s]", message->h.method);
|
||
|
END
|
||
|
}
|
||
|
break;
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[0]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_N32C_HANDSHAKE)
|
||
|
SWITCH(message->h.resource.component[0])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_EXCHANGE_CAPABILITY)
|
||
|
SWITCH(message->h.method)
|
||
|
CASE(OGS_SBI_HTTP_METHOD_POST)
|
||
|
if (message->res_status == 0) {
|
||
|
message->SecNegotiateReqData =
|
||
|
OpenAPI_sec_negotiate_req_data_parseFromJSON(item);
|
||
|
if (!message->SecNegotiateReqData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else if (message->res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||
|
message->SecNegotiateRspData =
|
||
|
OpenAPI_sec_negotiate_rsp_data_parseFromJSON(item);
|
||
|
if (!message->SecNegotiateRspData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown method [%s]", message->h.method);
|
||
|
END
|
||
|
break;
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[0]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NAMF_CALLBACK)
|
||
|
SWITCH(message->h.resource.component[1])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SM_CONTEXT_STATUS)
|
||
|
if (message->res_status < 300) {
|
||
|
message->SmContextStatusNotification =
|
||
|
OpenAPI_sm_context_status_notification_parseFromJSON(
|
||
|
item);
|
||
|
if (!message->SmContextStatusNotification) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d", message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_DEREG_NOTIFY)
|
||
|
if (message->res_status < 300) {
|
||
|
message->DeregistrationData =
|
||
|
OpenAPI_deregistration_data_parseFromJSON(item);
|
||
|
if (!message->DeregistrationData) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d", message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SDMSUBSCRIPTION_NOTIFY)
|
||
|
if (message->res_status < 300) {
|
||
|
message->ModificationNotification =
|
||
|
OpenAPI_modification_notification_parseFromJSON(item);
|
||
|
if (!message->ModificationNotification) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d", message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[1]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_SERVICE_NAME_NSMF_CALLBACK)
|
||
|
SWITCH(message->h.resource.component[0])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_N1_N2_FAILURE_NOTIFY)
|
||
|
if (message->res_status < 300) {
|
||
|
message->N1N2MsgTxfrFailureNotification =
|
||
|
OpenAPI_n1_n2_msg_txfr_failure_notification_parseFromJSON(
|
||
|
item);
|
||
|
if (!message->N1N2MsgTxfrFailureNotification) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d", message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_SM_POLICY_NOTIFY)
|
||
|
SWITCH(message->h.resource.component[2])
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_UPDATE)
|
||
|
if (message->res_status < 300) {
|
||
|
message->SmPolicyNotification =
|
||
|
OpenAPI_sm_policy_notification_parseFromJSON(item);
|
||
|
if (!message->SmPolicyNotification) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
CASE(OGS_SBI_RESOURCE_NAME_TERMINATE)
|
||
|
if (message->res_status < 300) {
|
||
|
message->TerminationNotification =
|
||
|
OpenAPI_termination_notification_parseFromJSON(item);
|
||
|
if (!message->TerminationNotification) {
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("JSON parse error");
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("HTTP ERROR Status : %d",
|
||
|
message->res_status);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[2]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Unknown resource name [%s]",
|
||
|
message->h.resource.component[0]);
|
||
|
END
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
rv = OGS_ERROR;
|
||
|
ogs_error("Not implemented API name [%s]",
|
||
|
message->h.service.name);
|
||
|
END
|
||
|
}
|
||
|
|
||
|
cleanup:
|
||
|
|
||
|
cJSON_Delete(item);
|
||
|
return rv;
|
||
|
}
|
||
|
|
||
|
static int parse_content(
|
||
|
ogs_sbi_message_t *message, ogs_sbi_http_message_t *http)
|
||
|
{
|
||
|
ogs_assert(message);
|
||
|
ogs_assert(http);
|
||
|
|
||
|
if (message->http.content_type &&
|
||
|
!strncmp(message->http.content_type, OGS_SBI_CONTENT_MULTIPART_TYPE,
|
||
|
strlen(OGS_SBI_CONTENT_MULTIPART_TYPE))) {
|
||
|
return parse_multipart(message, http);
|
||
|
} else {
|
||
|
return parse_json(message, message->http.content_type, http->content);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static bool build_content(
|
||
|
ogs_sbi_http_message_t *http, ogs_sbi_message_t *message)
|
||
|
{
|
||
|
ogs_assert(message);
|
||
|
ogs_assert(http);
|
||
|
|
||
|
if (message->num_of_part) {
|
||
|
if (build_multipart(http, message) == false) {
|
||
|
ogs_error("build_multipart() failed");
|
||
|
return false;
|
||
|
}
|
||
|
} else {
|
||
|
http->content = build_json(message);
|
||
|
if (http->content) {
|
||
|
http->content_length = strlen(http->content);
|
||
|
if (message->http.content_type) {
|
||
|
ogs_sbi_header_set(http->headers,
|
||
|
OGS_SBI_CONTENT_TYPE, message->http.content_type);
|
||
|
} else {
|
||
|
ogs_sbi_header_set(http->headers,
|
||
|
OGS_SBI_CONTENT_TYPE, OGS_SBI_CONTENT_JSON_TYPE);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
typedef struct multipart_parser_data_s {
|
||
|
int num_of_part;
|
||
|
struct {
|
||
|
char *content_type;
|
||
|
char *content_id;
|
||
|
char *content;
|
||
|
size_t content_length;
|
||
|
} part[OGS_SBI_MAX_NUM_OF_PART];
|
||
|
|
||
|
char *header_field;
|
||
|
} multipart_parser_data_t;
|
||
|
|
||
|
static int on_header_field(
|
||
|
multipart_parser *parser, const char *at, size_t length)
|
||
|
{
|
||
|
multipart_parser_data_t *data = NULL;
|
||
|
|
||
|
ogs_assert(parser);
|
||
|
data = multipart_parser_get_data(parser);
|
||
|
ogs_assert(data);
|
||
|
|
||
|
if (at && length) {
|
||
|
if (data->header_field)
|
||
|
ogs_free(data->header_field);
|
||
|
data->header_field = ogs_strndup(at, length);
|
||
|
ogs_assert(data->header_field);
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int on_header_value(
|
||
|
multipart_parser *parser, const char *at, size_t length)
|
||
|
{
|
||
|
multipart_parser_data_t *data = NULL;
|
||
|
|
||
|
ogs_assert(parser);
|
||
|
data = multipart_parser_get_data(parser);
|
||
|
ogs_assert(data);
|
||
|
|
||
|
if (data->num_of_part < OGS_SBI_MAX_NUM_OF_PART && at && length) {
|
||
|
if (!ogs_strcasecmp(data->header_field, OGS_SBI_CONTENT_TYPE)) {
|
||
|
ogs_assert(data->part[data->num_of_part].content_type == NULL);
|
||
|
data->part[data->num_of_part].content_type =
|
||
|
ogs_strndup(at, length);
|
||
|
ogs_assert(data->part[data->num_of_part].content_type);
|
||
|
} else if (!ogs_strcasecmp(data->header_field, OGS_SBI_CONTENT_ID)) {
|
||
|
ogs_assert(data->part[data->num_of_part].content_id == NULL);
|
||
|
data->part[data->num_of_part].content_id =
|
||
|
ogs_strndup(at, length);
|
||
|
ogs_assert(data->part[data->num_of_part].content_id);
|
||
|
} else {
|
||
|
ogs_error("Unknown header field [%s]", data->header_field);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int on_part_data(
|
||
|
multipart_parser *parser, const char *at, size_t length)
|
||
|
{
|
||
|
multipart_parser_data_t *data = NULL;
|
||
|
|
||
|
ogs_assert(parser);
|
||
|
data = multipart_parser_get_data(parser);
|
||
|
ogs_assert(data);
|
||
|
|
||
|
if (data->num_of_part < OGS_SBI_MAX_NUM_OF_PART && at && length) {
|
||
|
SWITCH(data->part[data->num_of_part].content_type)
|
||
|
CASE(OGS_SBI_CONTENT_JSON_TYPE)
|
||
|
CASE(OGS_SBI_CONTENT_5GNAS_TYPE)
|
||
|
CASE(OGS_SBI_CONTENT_NGAP_TYPE)
|
||
|
size_t offset = 0;
|
||
|
|
||
|
if (data->part[data->num_of_part].content == NULL) {
|
||
|
data->part[data->num_of_part].content_length = length;
|
||
|
data->part[data->num_of_part].content =
|
||
|
(char *)ogs_malloc(length + 1);
|
||
|
ogs_assert(data->part[data->num_of_part].content);
|
||
|
} else {
|
||
|
offset = data->part[data->num_of_part].content_length;
|
||
|
if ((data->part[data->num_of_part].content_length + length) >
|
||
|
OGS_MAX_SDU_LEN) {
|
||
|
ogs_error("Overflow length [%d:%d]",
|
||
|
(int)data->part[data->num_of_part].content_length,
|
||
|
(int)length);
|
||
|
ogs_assert_if_reached();
|
||
|
return 0;
|
||
|
}
|
||
|
data->part[data->num_of_part].content_length += length;
|
||
|
data->part[data->num_of_part].content = (char *)ogs_realloc(
|
||
|
data->part[data->num_of_part].content,
|
||
|
data->part[data->num_of_part].content_length + 1);
|
||
|
ogs_assert(data->part[data->num_of_part].content);
|
||
|
}
|
||
|
memcpy(data->part[data->num_of_part].content + offset, at, length);
|
||
|
data->part[data->num_of_part].content[
|
||
|
data->part[data->num_of_part].content_length] = 0;
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
ogs_error("Unknown content_type [%s]",
|
||
|
data->part[data->num_of_part].content_type);
|
||
|
ogs_log_hexdump(OGS_LOG_ERROR, (unsigned char *)at, length);
|
||
|
END
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int on_part_data_end(multipart_parser *parser)
|
||
|
{
|
||
|
multipart_parser_data_t *data = NULL;
|
||
|
|
||
|
ogs_assert(parser);
|
||
|
data = multipart_parser_get_data(parser);
|
||
|
ogs_assert(data);
|
||
|
|
||
|
if (data->num_of_part < OGS_SBI_MAX_NUM_OF_PART) {
|
||
|
data->num_of_part++;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int parse_multipart(
|
||
|
ogs_sbi_message_t *message, ogs_sbi_http_message_t *http)
|
||
|
{
|
||
|
char *boundary = NULL;
|
||
|
int i;
|
||
|
|
||
|
multipart_parser_settings settings;
|
||
|
multipart_parser_data_t data;
|
||
|
|
||
|
multipart_parser *parser = NULL;
|
||
|
|
||
|
ogs_assert(message);
|
||
|
ogs_assert(http);
|
||
|
|
||
|
memset(&settings, 0, sizeof(settings));
|
||
|
settings.on_header_field = &on_header_field;
|
||
|
settings.on_header_value = &on_header_value;
|
||
|
settings.on_part_data = &on_part_data;
|
||
|
settings.on_part_data_end = &on_part_data_end;
|
||
|
|
||
|
for (i = 0; i < http->content_length; i++) {
|
||
|
if (http->content[i] == '\r' && http->content[i+1] == '\n')
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (i >= http->content_length) {
|
||
|
ogs_error("Invalid HTTP content [%d]", i);
|
||
|
ogs_log_hexdump(OGS_LOG_ERROR,
|
||
|
(unsigned char *)http->content, http->content_length);
|
||
|
return OGS_ERROR;
|
||
|
}
|
||
|
|
||
|
boundary = ogs_strndup(http->content, i);
|
||
|
ogs_assert(boundary);
|
||
|
|
||
|
parser = multipart_parser_init(boundary, &settings);
|
||
|
ogs_assert(parser);
|
||
|
|
||
|
memset(&data, 0, sizeof(data));
|
||
|
multipart_parser_set_data(parser, &data);
|
||
|
multipart_parser_execute(parser, http->content, http->content_length);
|
||
|
|
||
|
multipart_parser_free(parser);
|
||
|
ogs_free(boundary);
|
||
|
|
||
|
if (data.num_of_part > OGS_SBI_MAX_NUM_OF_PART) {
|
||
|
/* Overflow Issues #1247 */
|
||
|
ogs_fatal("Overflow num_of_part[%d]", data.num_of_part);
|
||
|
ogs_assert_if_reached();
|
||
|
}
|
||
|
for (i = 0; i < data.num_of_part; i++) {
|
||
|
SWITCH(data.part[i].content_type)
|
||
|
CASE(OGS_SBI_CONTENT_JSON_TYPE)
|
||
|
parse_json(message,
|
||
|
data.part[i].content_type, data.part[i].content);
|
||
|
|
||
|
if (data.part[i].content_id)
|
||
|
ogs_free(data.part[i].content_id);
|
||
|
if (data.part[i].content_type)
|
||
|
ogs_free(data.part[i].content_type);
|
||
|
if (data.part[i].content)
|
||
|
ogs_free(data.part[i].content);
|
||
|
|
||
|
break;
|
||
|
|
||
|
CASE(OGS_SBI_CONTENT_5GNAS_TYPE)
|
||
|
CASE(OGS_SBI_CONTENT_NGAP_TYPE)
|
||
|
http->part[http->num_of_part].content_id =
|
||
|
data.part[i].content_id;
|
||
|
http->part[http->num_of_part].content_type =
|
||
|
data.part[i].content_type;
|
||
|
http->part[http->num_of_part].pkbuf =
|
||
|
ogs_pkbuf_alloc(NULL, data.part[i].content_length);
|
||
|
if (!(http->part[http->num_of_part].pkbuf)) {
|
||
|
ogs_error("ogs_pkbuf_copy() failed");
|
||
|
|
||
|
if (data.part[i].content_id)
|
||
|
ogs_free(data.part[i].content_id);
|
||
|
if (data.part[i].content_type)
|
||
|
ogs_free(data.part[i].content_type);
|
||
|
if (data.part[i].content)
|
||
|
ogs_free(data.part[i].content);
|
||
|
|
||
|
if (data.header_field)
|
||
|
ogs_free(data.header_field);
|
||
|
|
||
|
return OGS_ERROR;
|
||
|
}
|
||
|
ogs_pkbuf_put_data(http->part[http->num_of_part].pkbuf,
|
||
|
data.part[i].content, data.part[i].content_length);
|
||
|
|
||
|
message->part[message->num_of_part].content_id =
|
||
|
http->part[http->num_of_part].content_id;
|
||
|
message->part[message->num_of_part].content_type =
|
||
|
http->part[http->num_of_part].content_type;
|
||
|
message->part[message->num_of_part].pkbuf =
|
||
|
ogs_pkbuf_copy(http->part[http->num_of_part].pkbuf);
|
||
|
if (!(message->part[http->num_of_part].pkbuf)) {
|
||
|
ogs_error("ogs_pkbuf_copy() failed");
|
||
|
|
||
|
if (data.part[i].content_id)
|
||
|
ogs_free(data.part[i].content_id);
|
||
|
if (data.part[i].content_type)
|
||
|
ogs_free(data.part[i].content_type);
|
||
|
if (data.part[i].content)
|
||
|
ogs_free(data.part[i].content);
|
||
|
|
||
|
if (data.header_field)
|
||
|
ogs_free(data.header_field);
|
||
|
|
||
|
if (http->part[http->num_of_part].pkbuf)
|
||
|
ogs_pkbuf_free(http->part[http->num_of_part].pkbuf);
|
||
|
|
||
|
return OGS_ERROR;
|
||
|
}
|
||
|
|
||
|
http->num_of_part++;
|
||
|
message->num_of_part++;
|
||
|
|
||
|
if (data.part[i].content)
|
||
|
ogs_free(data.part[i].content);
|
||
|
break;
|
||
|
|
||
|
DEFAULT
|
||
|
ogs_error("Unknown content-type[%s]", data.part[i].content_type);
|
||
|
|
||
|
if (data.part[i].content_id)
|
||
|
ogs_free(data.part[i].content_id);
|
||
|
if (data.part[i].content_type)
|
||
|
ogs_free(data.part[i].content_type);
|
||
|
END
|
||
|
}
|
||
|
|
||
|
if (data.header_field)
|
||
|
ogs_free(data.header_field);
|
||
|
|
||
|
return OGS_OK;
|
||
|
}
|
||
|
|
||
|
static bool build_multipart(
|
||
|
ogs_sbi_http_message_t *http, ogs_sbi_message_t *message)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
char boundary[32];
|
||
|
unsigned char digest[16];
|
||
|
char *p = NULL, *last;
|
||
|
|
||
|
char *content_type = NULL;
|
||
|
char *json = NULL;
|
||
|
|
||
|
ogs_assert(message);
|
||
|
ogs_assert(http);
|
||
|
|
||
|
ogs_random(digest, 16);
|
||
|
strcpy(boundary, "=-");
|
||
|
ogs_base64_encode_binary(boundary + 2, digest, 16);
|
||
|
|
||
|
p = http->content = ogs_calloc(1, OGS_MAX_SDU_LEN);
|
||
|
if (!p) {
|
||
|
ogs_error("ogs_calloc() failed");
|
||
|
return false;
|
||
|
}
|
||
|
last = p + OGS_MAX_SDU_LEN;
|
||
|
|
||
|
/* First boundary */
|
||
|
p = ogs_slprintf(p, last, "--%s\r\n", boundary);
|
||
|
|
||
|
/* Encapsulated multipart part (application/json) */
|
||
|
json = build_json(message);
|
||
|
if (!json) {
|
||
|
ogs_error("build_json() failed");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
p = ogs_slprintf(p, last, "%s\r\n\r\n%s",
|
||
|
OGS_SBI_CONTENT_TYPE ": " OGS_SBI_CONTENT_JSON_TYPE, json);
|
||
|
|
||
|
ogs_free(json);
|
||
|
|
||
|
/* Add part */
|
||
|
for (i = 0; i < message->num_of_part; i++) {
|
||
|
p = ogs_slprintf(p, last, "\r\n--%s\r\n", boundary);
|
||
|
p = ogs_slprintf(p, last, "%s: %s\r\n",
|
||
|
OGS_SBI_CONTENT_ID, message->part[i].content_id);
|
||
|
p = ogs_slprintf(p, last, "%s: %s\r\n\r\n",
|
||
|
OGS_SBI_CONTENT_TYPE, message->part[i].content_type);
|
||
|
memcpy(p, message->part[i].pkbuf->data, message->part[i].pkbuf->len);
|
||
|
p += message->part[i].pkbuf->len;
|
||
|
}
|
||
|
|
||
|
/* Last boundary */
|
||
|
p = ogs_slprintf(p, last, "\r\n--%s--\r\n", boundary);
|
||
|
|
||
|
http->content_length = p - http->content;
|
||
|
|
||
|
content_type = ogs_msprintf("%s; boundary=\"%s\"",
|
||
|
OGS_SBI_CONTENT_MULTIPART_TYPE, boundary);
|
||
|
if (!content_type) {
|
||
|
ogs_error("ogs_msprintf() failed");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
ogs_sbi_header_set(http->headers, OGS_SBI_CONTENT_TYPE, content_type);
|
||
|
|
||
|
ogs_free(content_type);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
static void http_message_free(ogs_sbi_http_message_t *http)
|
||
|
{
|
||
|
int i;
|
||
|
ogs_assert(http);
|
||
|
|
||
|
if (http->params)
|
||
|
ogs_sbi_http_hash_free(http->params);
|
||
|
|
||
|
if (http->headers)
|
||
|
ogs_sbi_http_hash_free(http->headers);
|
||
|
|
||
|
if (http->content)
|
||
|
ogs_free(http->content);
|
||
|
|
||
|
for (i = 0; i < http->num_of_part; i++) {
|
||
|
if (http->part[i].pkbuf)
|
||
|
ogs_pkbuf_free(http->part[i].pkbuf);
|
||
|
if (http->part[i].content_id)
|
||
|
ogs_free(http->part[i].content_id);
|
||
|
if (http->part[i].content_type)
|
||
|
ogs_free(http->part[i].content_type);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ogs_sbi_discovery_option_t *ogs_sbi_discovery_option_new(void)
|
||
|
{
|
||
|
ogs_sbi_discovery_option_t *discovery_option = NULL;
|
||
|
|
||
|
discovery_option = ogs_calloc(1, sizeof(*discovery_option));
|
||
|
ogs_assert(discovery_option);
|
||
|
|
||
|
return discovery_option;
|
||
|
}
|
||
|
void ogs_sbi_discovery_option_free(
|
||
|
ogs_sbi_discovery_option_t *discovery_option)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
ogs_assert(discovery_option);
|
||
|
|
||
|
if (discovery_option->target_nf_instance_id)
|
||
|
ogs_free(discovery_option->target_nf_instance_id);
|
||
|
if (discovery_option->requester_nf_instance_id)
|
||
|
ogs_free(discovery_option->requester_nf_instance_id);
|
||
|
if (discovery_option->dnn)
|
||
|
ogs_free(discovery_option->dnn);
|
||
|
|
||
|
for (i = 0; i < discovery_option->num_of_service_names; i++)
|
||
|
ogs_free(discovery_option->service_names[i]);
|
||
|
|
||
|
ogs_free(discovery_option);
|
||
|
}
|
||
|
|
||
|
void ogs_sbi_discovery_option_set_target_nf_instance_id(
|
||
|
ogs_sbi_discovery_option_t *discovery_option,
|
||
|
char *target_nf_instance_id)
|
||
|
{
|
||
|
ogs_assert(discovery_option);
|
||
|
ogs_assert(target_nf_instance_id);
|
||
|
|
||
|
ogs_assert(!discovery_option->target_nf_instance_id);
|
||
|
discovery_option->target_nf_instance_id = ogs_strdup(target_nf_instance_id);
|
||
|
ogs_assert(discovery_option->target_nf_instance_id);
|
||
|
}
|
||
|
void ogs_sbi_discovery_option_set_requester_nf_instance_id(
|
||
|
ogs_sbi_discovery_option_t *discovery_option,
|
||
|
char *requester_nf_instance_id)
|
||
|
{
|
||
|
ogs_assert(discovery_option);
|
||
|
ogs_assert(requester_nf_instance_id);
|
||
|
|
||
|
ogs_assert(!discovery_option->requester_nf_instance_id);
|
||
|
discovery_option->requester_nf_instance_id =
|
||
|
ogs_strdup(requester_nf_instance_id);
|
||
|
ogs_assert(discovery_option->requester_nf_instance_id);
|
||
|
}
|
||
|
void ogs_sbi_discovery_option_set_dnn(
|
||
|
ogs_sbi_discovery_option_t *discovery_option, char *dnn)
|
||
|
{
|
||
|
ogs_assert(discovery_option);
|
||
|
ogs_assert(dnn);
|
||
|
|
||
|
ogs_assert(!discovery_option->dnn);
|
||
|
discovery_option->dnn = ogs_strdup(dnn);
|
||
|
ogs_assert(discovery_option->dnn);
|
||
|
}
|
||
|
|
||
|
void ogs_sbi_discovery_option_add_service_names(
|
||
|
ogs_sbi_discovery_option_t *discovery_option,
|
||
|
char *service_name)
|
||
|
{
|
||
|
ogs_assert(discovery_option);
|
||
|
ogs_assert(service_name);
|
||
|
|
||
|
ogs_assert(discovery_option->num_of_service_names <
|
||
|
OGS_SBI_MAX_NUM_OF_SERVICE_TYPE);
|
||
|
|
||
|
discovery_option->service_names[discovery_option->num_of_service_names] =
|
||
|
ogs_strdup(service_name);
|
||
|
ogs_assert(discovery_option->service_names
|
||
|
[discovery_option->num_of_service_names]);
|
||
|
discovery_option->num_of_service_names++;
|
||
|
}
|
||
|
|
||
|
char *ogs_sbi_discovery_option_build_service_names(
|
||
|
ogs_sbi_discovery_option_t *discovery_option)
|
||
|
{
|
||
|
int i;
|
||
|
char *service_names = NULL;
|
||
|
|
||
|
ogs_assert(discovery_option);
|
||
|
|
||
|
service_names = ogs_strdup(discovery_option->service_names[0]);
|
||
|
if (!service_names) {
|
||
|
ogs_error("ogs_strdup() failed");
|
||
|
return NULL;;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Issues #1730
|
||
|
* Send NF discovery query with service-names delimited with comma
|
||
|
*
|
||
|
* OpenAPI specification for sending NF discovery query with
|
||
|
* "service-names" parameter is defined as folowing:
|
||
|
* name: service-names
|
||
|
* ...
|
||
|
* style: form
|
||
|
* explode: false
|
||
|
*
|
||
|
* According to OpenAPI specification, this means array items
|
||
|
* should be delimited with a comma character (example: /users?id=3,4,5).
|
||
|
*
|
||
|
* See also https://swagger.io/docs/specification/serialization/
|
||
|
*/
|
||
|
if (discovery_option->num_of_service_names > 1) {
|
||
|
for (i = 1; i < discovery_option->num_of_service_names; i++)
|
||
|
service_names = ogs_mstrcatf(
|
||
|
service_names, ",%s", discovery_option->service_names[i]);
|
||
|
}
|
||
|
|
||
|
return service_names;
|
||
|
}
|
||
|
|
||
|
void ogs_sbi_discovery_option_parse_service_names(
|
||
|
ogs_sbi_discovery_option_t *discovery_option,
|
||
|
char *service_names)
|
||
|
{
|
||
|
char *v = NULL;
|
||
|
char *token = NULL;
|
||
|
char *saveptr = NULL;
|
||
|
|
||
|
ogs_assert(discovery_option);
|
||
|
ogs_assert(service_names);
|
||
|
|
||
|
v = ogs_sbi_url_decode(service_names);
|
||
|
if (!v) {
|
||
|
ogs_error("ogs_sbi_url_decode() failed : service_names[%s]",
|
||
|
service_names);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Issues #1730
|
||
|
* Send NF discovery query with service-names delimited with comma
|
||
|
*
|
||
|
* OpenAPI specification for sending NF discovery query with
|
||
|
* "service-names" parameter is defined as folowing:
|
||
|
* name: service-names
|
||
|
* ...
|
||
|
* style: form
|
||
|
* explode: false
|
||
|
*
|
||
|
* According to OpenAPI specification, this means array items
|
||
|
* should be delimited with a comma character (example: /users?id=3,4,5).
|
||
|
*
|
||
|
* See also https://swagger.io/docs/specification/serialization/
|
||
|
*/
|
||
|
token = ogs_strtok_r(v, ",", &saveptr);
|
||
|
while (token != NULL) {
|
||
|
ogs_sbi_discovery_option_add_service_names(discovery_option, token);
|
||
|
token = ogs_strtok_r(NULL, ",", &saveptr);
|
||
|
}
|
||
|
|
||
|
ogs_free(v);
|
||
|
}
|
||
|
|
||
|
void ogs_sbi_discovery_option_add_snssais(
|
||
|
ogs_sbi_discovery_option_t *discovery_option, ogs_s_nssai_t *s_nssai)
|
||
|
{
|
||
|
ogs_assert(discovery_option);
|
||
|
ogs_assert(s_nssai);
|
||
|
|
||
|
ogs_assert(discovery_option->num_of_snssais < OGS_MAX_NUM_OF_SLICE);
|
||
|
|
||
|
memcpy(&discovery_option->snssais[discovery_option->num_of_snssais],
|
||
|
s_nssai, sizeof(ogs_s_nssai_t));
|
||
|
discovery_option->num_of_snssais++;
|
||
|
}
|
||
|
char *ogs_sbi_discovery_option_build_snssais(
|
||
|
ogs_sbi_discovery_option_t *discovery_option)
|
||
|
{
|
||
|
cJSON *item = NULL;
|
||
|
char *v = NULL;
|
||
|
int i;
|
||
|
|
||
|
ogs_assert(discovery_option);
|
||
|
|
||
|
item = cJSON_CreateArray();
|
||
|
if (!item) {
|
||
|
ogs_error("cJSON_CreateArray() failed");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < discovery_option->num_of_snssais; i++) {
|
||
|
OpenAPI_snssai_t sNSSAI;
|
||
|
cJSON *snssaiItem = NULL;
|
||
|
|
||
|
memset(&sNSSAI, 0, sizeof(sNSSAI));
|
||
|
|
||
|
sNSSAI.sst = discovery_option->snssais[i].sst;
|
||
|
sNSSAI.sd = ogs_s_nssai_sd_to_string(discovery_option->snssais[i].sd);
|
||
|
|
||
|
snssaiItem = OpenAPI_snssai_convertToJSON(&sNSSAI);
|
||
|
ogs_assert(snssaiItem);
|
||
|
cJSON_AddItemToArray(item, snssaiItem);
|
||
|
|
||
|
if (sNSSAI.sd)
|
||
|
ogs_free(sNSSAI.sd);
|
||
|
}
|
||
|
|
||
|
v = cJSON_PrintUnformatted(item);
|
||
|
ogs_expect(v);
|
||
|
cJSON_Delete(item);
|
||
|
|
||
|
return v;
|
||
|
}
|
||
|
void ogs_sbi_discovery_option_parse_snssais(
|
||
|
ogs_sbi_discovery_option_t *discovery_option, char *snssais)
|
||
|
{
|
||
|
cJSON *item = NULL;
|
||
|
cJSON *snssaiItem = NULL;
|
||
|
char *v = NULL;
|
||
|
|
||
|
ogs_assert(discovery_option);
|
||
|
ogs_assert(snssais);
|
||
|
|
||
|
v = ogs_sbi_url_decode(snssais);
|
||
|
if (!v) {
|
||
|
ogs_error("ogs_sbi_url_decode() failed : snssais[%s]", snssais);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
item = cJSON_Parse(v);
|
||
|
if (!item) {
|
||
|
ogs_error("Cannot parse snssais[%s]", snssais);
|
||
|
ogs_free(v);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
cJSON_ArrayForEach(snssaiItem, item) {
|
||
|
if (cJSON_IsObject(snssaiItem)) {
|
||
|
OpenAPI_snssai_t *sNSSAI = OpenAPI_snssai_parseFromJSON(snssaiItem);
|
||
|
|
||
|
if (sNSSAI) {
|
||
|
ogs_s_nssai_t s_nssai;
|
||
|
|
||
|
s_nssai.sst = sNSSAI->sst;
|
||
|
s_nssai.sd = ogs_s_nssai_sd_from_string(sNSSAI->sd);
|
||
|
|
||
|
ogs_sbi_discovery_option_add_snssais(
|
||
|
discovery_option, &s_nssai);
|
||
|
|
||
|
OpenAPI_snssai_free(sNSSAI);
|
||
|
} else {
|
||
|
ogs_error("OpenAPI_snssai_parseFromJSON() failed : snssais[%s]",
|
||
|
snssais);
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("Invalid cJSON Type in snssias[%s]", snssais);
|
||
|
}
|
||
|
}
|
||
|
cJSON_Delete(item);
|
||
|
|
||
|
ogs_free(v);
|
||
|
}
|
||
|
|
||
|
void ogs_sbi_discovery_option_set_tai(
|
||
|
ogs_sbi_discovery_option_t *discovery_option, ogs_5gs_tai_t *tai)
|
||
|
{
|
||
|
ogs_assert(discovery_option);
|
||
|
ogs_assert(tai);
|
||
|
|
||
|
ogs_assert(discovery_option->tai_presence == false);
|
||
|
|
||
|
memcpy(&discovery_option->tai, tai, sizeof(ogs_5gs_tai_t));
|
||
|
discovery_option->tai_presence = true;
|
||
|
}
|
||
|
char *ogs_sbi_discovery_option_build_tai(
|
||
|
ogs_sbi_discovery_option_t *discovery_option)
|
||
|
{
|
||
|
OpenAPI_tai_t Tai;
|
||
|
cJSON *taiItem = NULL;
|
||
|
char *v = NULL;
|
||
|
|
||
|
ogs_assert(discovery_option);
|
||
|
ogs_assert(discovery_option->tai_presence);
|
||
|
|
||
|
memset(&Tai, 0, sizeof(Tai));
|
||
|
|
||
|
Tai.plmn_id = ogs_sbi_build_plmn_id(&discovery_option->tai.plmn_id);
|
||
|
ogs_assert(Tai.plmn_id);
|
||
|
Tai.tac = ogs_uint24_to_0string(discovery_option->tai.tac);
|
||
|
ogs_assert(Tai.tac);
|
||
|
|
||
|
taiItem = OpenAPI_tai_convertToJSON(&Tai);
|
||
|
ogs_assert(taiItem);
|
||
|
|
||
|
ogs_sbi_free_plmn_id(Tai.plmn_id);
|
||
|
ogs_free(Tai.tac);
|
||
|
|
||
|
v = cJSON_PrintUnformatted(taiItem);
|
||
|
ogs_expect(v);
|
||
|
cJSON_Delete(taiItem);
|
||
|
|
||
|
return v;
|
||
|
}
|
||
|
void ogs_sbi_discovery_option_parse_tai(
|
||
|
ogs_sbi_discovery_option_t *discovery_option, char *tai)
|
||
|
{
|
||
|
cJSON *taiItem = NULL;
|
||
|
char *v = NULL;
|
||
|
|
||
|
ogs_assert(discovery_option);
|
||
|
ogs_assert(tai);
|
||
|
|
||
|
v = ogs_sbi_url_decode(tai);
|
||
|
if (!v) {
|
||
|
ogs_error("ogs_sbi_url_decode() failed : tai[%s]", tai);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
taiItem = cJSON_Parse(v);
|
||
|
if (!taiItem) {
|
||
|
ogs_error("Cannot parse tai[%s]", tai);
|
||
|
ogs_free(v);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (cJSON_IsObject(taiItem)) {
|
||
|
OpenAPI_tai_t *Tai = OpenAPI_tai_parseFromJSON(taiItem);
|
||
|
|
||
|
if (Tai) {
|
||
|
ogs_5gs_tai_t tai;
|
||
|
|
||
|
memset(&tai, 0, sizeof(tai));
|
||
|
|
||
|
if (Tai->plmn_id)
|
||
|
ogs_sbi_parse_plmn_id(&tai.plmn_id, Tai->plmn_id);
|
||
|
if (Tai->tac)
|
||
|
tai.tac = ogs_uint24_from_string(Tai->tac);
|
||
|
|
||
|
ogs_sbi_discovery_option_set_tai(discovery_option, &tai);
|
||
|
|
||
|
OpenAPI_tai_free(Tai);
|
||
|
} else {
|
||
|
ogs_error("OpenAPI_snssai_parseFromJSON() failed : tai[%s]",
|
||
|
tai);
|
||
|
}
|
||
|
} else {
|
||
|
ogs_error("Invalid cJSON Type in snssias[%s]", tai);
|
||
|
}
|
||
|
cJSON_Delete(taiItem);
|
||
|
|
||
|
ogs_free(v);
|
||
|
}
|
||
|
|
||
|
void ogs_sbi_discovery_option_add_target_plmn_list(
|
||
|
ogs_sbi_discovery_option_t *discovery_option,
|
||
|
ogs_plmn_id_t *target_plmn_id)
|
||
|
{
|
||
|
ogs_assert(discovery_option);
|
||
|
ogs_assert(target_plmn_id);
|
||
|
|
||
|
ogs_assert(discovery_option->num_of_target_plmn_list <
|
||
|
OGS_MAX_NUM_OF_PLMN);
|
||
|
|
||
|
memcpy(&discovery_option->target_plmn_list[
|
||
|
discovery_option->num_of_target_plmn_list],
|
||
|
target_plmn_id, OGS_PLMN_ID_LEN);
|
||
|
discovery_option->num_of_target_plmn_list++;
|
||
|
}
|
||
|
|
||
|
void ogs_sbi_discovery_option_add_requester_plmn_list(
|
||
|
ogs_sbi_discovery_option_t *discovery_option,
|
||
|
ogs_plmn_id_t *requester_plmn_id)
|
||
|
{
|
||
|
ogs_assert(discovery_option);
|
||
|
ogs_assert(requester_plmn_id);
|
||
|
|
||
|
ogs_assert(discovery_option->num_of_requester_plmn_list <
|
||
|
OGS_MAX_NUM_OF_PLMN);
|
||
|
|
||
|
memcpy(&discovery_option->requester_plmn_list[
|
||
|
discovery_option->num_of_requester_plmn_list],
|
||
|
requester_plmn_id, OGS_PLMN_ID_LEN);
|
||
|
discovery_option->num_of_requester_plmn_list++;
|
||
|
}
|
||
|
|
||
|
char *ogs_sbi_discovery_option_build_plmn_list(
|
||
|
ogs_plmn_id_t *plmn_list, int num_of_plmn_list)
|
||
|
{
|
||
|
OpenAPI_list_t *PlmnList = NULL;
|
||
|
OpenAPI_plmn_id_t *PlmnId = NULL;
|
||
|
OpenAPI_lnode_t *node = NULL;
|
||
|
cJSON *item = NULL;
|
||
|
|
||
|
char *v = NULL;
|
||
|
|
||
|
ogs_assert(plmn_list);
|
||
|
ogs_assert(num_of_plmn_list);
|
||
|
|
||
|
PlmnList = ogs_sbi_build_plmn_list(plmn_list, num_of_plmn_list);
|
||
|
ogs_assert(PlmnList);
|
||
|
|
||
|
item = cJSON_CreateArray();
|
||
|
ogs_assert(item);
|
||
|
|
||
|
OpenAPI_list_for_each(PlmnList, node) {
|
||
|
PlmnId = node->data;
|
||
|
if (PlmnId) {
|
||
|
cJSON *PlmnIdItem = OpenAPI_plmn_id_convertToJSON(PlmnId);
|
||
|
ogs_assert(PlmnIdItem);
|
||
|
cJSON_AddItemToArray(item, PlmnIdItem);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
v = cJSON_PrintUnformatted(item);
|
||
|
ogs_assert(v);
|
||
|
|
||
|
cJSON_Delete(item);
|
||
|
|
||
|
ogs_sbi_free_plmn_list(PlmnList);
|
||
|
|
||
|
return v;
|
||
|
}
|
||
|
|
||
|
int ogs_sbi_discovery_option_parse_plmn_list(
|
||
|
ogs_plmn_id_t *plmn_list, char *v)
|
||
|
{
|
||
|
cJSON *item = NULL;
|
||
|
cJSON *PlmnIdJSON = NULL;
|
||
|
OpenAPI_list_t *PlmnList = NULL;
|
||
|
OpenAPI_plmn_id_t *PlmnId = NULL;
|
||
|
int num_of_plmn_list = 0;
|
||
|
|
||
|
ogs_assert(v);
|
||
|
ogs_assert(plmn_list);
|
||
|
|
||
|
item = cJSON_Parse(v);
|
||
|
if (item) {
|
||
|
PlmnList = OpenAPI_list_create();
|
||
|
ogs_assert(PlmnList);
|
||
|
cJSON_ArrayForEach(PlmnIdJSON, item) {
|
||
|
if (!cJSON_IsObject(PlmnIdJSON)) {
|
||
|
ogs_error("Unknown JSON");
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
PlmnId = OpenAPI_plmn_id_parseFromJSON(PlmnIdJSON);
|
||
|
if (!PlmnId) {
|
||
|
ogs_error("No PlmnId");
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
OpenAPI_list_add(PlmnList, PlmnId);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
num_of_plmn_list = ogs_sbi_parse_plmn_list(plmn_list, PlmnList);
|
||
|
|
||
|
cleanup:
|
||
|
ogs_sbi_free_plmn_list(PlmnList);
|
||
|
cJSON_Delete(item);
|
||
|
|
||
|
return num_of_plmn_list;
|
||
|
}
|