2017-02-06 06:30:12 +00:00
|
|
|
#define TRACE_MODULE _s1dec
|
2017-02-04 15:49:53 +00:00
|
|
|
|
2017-02-05 06:16:32 +00:00
|
|
|
#include "core_debug.h"
|
2017-02-10 13:16:22 +00:00
|
|
|
#include "core_lib.h"
|
2017-02-15 11:16:50 +00:00
|
|
|
#include "s1ap_message.h"
|
2017-02-05 06:16:32 +00:00
|
|
|
|
|
|
|
static int s1ap_decode_initiating(s1ap_message *message,
|
|
|
|
S1ap_InitiatingMessage_t *initiating_p);
|
|
|
|
static int s1ap_decode_successfull_outcome(s1ap_message *message,
|
|
|
|
S1ap_SuccessfulOutcome_t *successfullOutcome_p);
|
|
|
|
static int s1ap_decode_unsuccessfull_outcome(s1ap_message *message,
|
|
|
|
S1ap_UnsuccessfulOutcome_t *unSuccessfulOutcome_p);
|
|
|
|
|
2017-02-10 13:16:22 +00:00
|
|
|
static void s1ap_decode_xer_print_message(
|
2017-02-05 06:16:32 +00:00
|
|
|
asn_enc_rval_t (*func)(asn_app_consume_bytes_f *cb,
|
|
|
|
void *app_key, s1ap_message *message_p),
|
|
|
|
asn_app_consume_bytes_f *cb, s1ap_message *message_p);
|
|
|
|
|
|
|
|
int s1ap_decode_pdu(s1ap_message *message, pkbuf_t *pkb)
|
2017-02-04 15:49:53 +00:00
|
|
|
{
|
2017-02-07 04:52:34 +00:00
|
|
|
int ret = -1;
|
|
|
|
|
2017-02-05 06:16:32 +00:00
|
|
|
S1AP_PDU_t pdu = {0};
|
|
|
|
S1AP_PDU_t *pdu_p = &pdu;
|
|
|
|
asn_dec_rval_t dec_ret = {0};
|
|
|
|
|
|
|
|
d_assert(pkb, return -1, "Null param");
|
|
|
|
d_assert(pkb->payload, return -1, "Null param");
|
|
|
|
memset((void *)pdu_p, 0, sizeof(S1AP_PDU_t));
|
|
|
|
dec_ret = aper_decode(NULL, &asn_DEF_S1AP_PDU, (void **)&pdu_p,
|
|
|
|
pkb->payload, pkb->len, 0, 0);
|
|
|
|
|
|
|
|
if (dec_ret.code != RC_OK)
|
|
|
|
{
|
|
|
|
d_error("Failed to decode PDU");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(message, 0, sizeof(s1ap_message));
|
|
|
|
|
|
|
|
message->direction = pdu_p->present;
|
|
|
|
switch (pdu_p->present)
|
|
|
|
{
|
|
|
|
case S1AP_PDU_PR_initiatingMessage:
|
2017-02-07 04:52:34 +00:00
|
|
|
ret = s1ap_decode_initiating(message,
|
2017-02-05 06:16:32 +00:00
|
|
|
&pdu_p->choice.initiatingMessage);
|
2017-02-07 04:52:34 +00:00
|
|
|
break;
|
2017-02-05 06:16:32 +00:00
|
|
|
|
|
|
|
case S1AP_PDU_PR_successfulOutcome:
|
2017-02-07 04:52:34 +00:00
|
|
|
ret = s1ap_decode_successfull_outcome(message,
|
2017-02-05 06:16:32 +00:00
|
|
|
&pdu_p->choice.successfulOutcome);
|
2017-02-07 04:52:34 +00:00
|
|
|
break;
|
2017-02-05 06:16:32 +00:00
|
|
|
|
|
|
|
case S1AP_PDU_PR_unsuccessfulOutcome:
|
2017-02-07 04:52:34 +00:00
|
|
|
ret = s1ap_decode_unsuccessfull_outcome(message,
|
2017-02-05 06:16:32 +00:00
|
|
|
&pdu_p->choice.unsuccessfulOutcome);
|
2017-02-07 04:52:34 +00:00
|
|
|
break;
|
2017-02-05 06:16:32 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
d_error("Unknown message outcome (%d) or not implemented",
|
|
|
|
(int)pdu_p->present);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2017-02-07 04:52:34 +00:00
|
|
|
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_S1AP_PDU, &pdu);
|
|
|
|
|
|
|
|
return ret;
|
2017-02-04 15:49:53 +00:00
|
|
|
}
|
|
|
|
|
2017-02-05 06:16:32 +00:00
|
|
|
|
2017-02-04 16:11:21 +00:00
|
|
|
static int s1ap_decode_initiating(s1ap_message *message,
|
2017-02-05 06:16:32 +00:00
|
|
|
S1ap_InitiatingMessage_t *initiating_p)
|
2017-02-04 15:49:53 +00:00
|
|
|
{
|
2017-02-05 06:36:02 +00:00
|
|
|
int ret = -1;
|
2017-02-04 15:49:53 +00:00
|
|
|
|
2017-02-04 16:11:21 +00:00
|
|
|
d_assert(initiating_p, return -1, "Null param");
|
2017-02-04 15:49:53 +00:00
|
|
|
|
2017-02-09 14:15:08 +00:00
|
|
|
message->procedureCode = initiating_p->procedureCode;
|
2017-02-04 15:49:53 +00:00
|
|
|
switch (initiating_p->procedureCode)
|
|
|
|
{
|
|
|
|
case S1ap_ProcedureCode_id_uplinkNASTransport:
|
|
|
|
ret = s1ap_decode_s1ap_uplinknastransport_ies(
|
|
|
|
&message->msg.s1ap_UplinkNASTransport_IEs,
|
|
|
|
&initiating_p->value);
|
2017-02-10 13:16:22 +00:00
|
|
|
s1ap_decode_xer_print_message(s1ap_xer_print_s1ap_uplinknastransport,
|
2017-02-05 06:16:32 +00:00
|
|
|
s1ap_xer__print2sp, message);
|
2017-02-05 06:36:02 +00:00
|
|
|
break;
|
2017-02-04 15:49:53 +00:00
|
|
|
|
|
|
|
case S1ap_ProcedureCode_id_S1Setup:
|
|
|
|
ret = s1ap_decode_s1ap_s1setuprequesties(
|
|
|
|
&message->msg.s1ap_S1SetupRequestIEs,
|
|
|
|
&initiating_p->value);
|
2017-02-10 13:16:22 +00:00
|
|
|
s1ap_decode_xer_print_message(s1ap_xer_print_s1ap_s1setuprequest,
|
2017-02-05 06:16:32 +00:00
|
|
|
s1ap_xer__print2sp, message);
|
2017-02-05 06:36:02 +00:00
|
|
|
break;
|
2017-02-04 15:49:53 +00:00
|
|
|
|
|
|
|
case S1ap_ProcedureCode_id_initialUEMessage:
|
|
|
|
ret = s1ap_decode_s1ap_initialuemessage_ies(
|
|
|
|
&message->msg.s1ap_InitialUEMessage_IEs,
|
|
|
|
&initiating_p->value);
|
2017-02-10 13:16:22 +00:00
|
|
|
s1ap_decode_xer_print_message(s1ap_xer_print_s1ap_initialuemessage,
|
2017-02-05 06:16:32 +00:00
|
|
|
s1ap_xer__print2sp, message);
|
2017-02-05 06:36:02 +00:00
|
|
|
break;
|
2017-02-04 15:49:53 +00:00
|
|
|
|
|
|
|
case S1ap_ProcedureCode_id_UEContextReleaseRequest:
|
|
|
|
ret = s1ap_decode_s1ap_uecontextreleaserequest_ies(
|
|
|
|
&message->msg.s1ap_UEContextReleaseRequest_IEs, &initiating_p->value);
|
2017-02-10 13:16:22 +00:00
|
|
|
s1ap_decode_xer_print_message(s1ap_xer_print_s1ap_uecontextreleaserequest,
|
2017-02-05 06:16:32 +00:00
|
|
|
s1ap_xer__print2sp, message);
|
2017-02-05 06:36:02 +00:00
|
|
|
break;
|
2017-02-04 15:49:53 +00:00
|
|
|
|
|
|
|
case S1ap_ProcedureCode_id_UECapabilityInfoIndication:
|
|
|
|
ret = s1ap_decode_s1ap_uecapabilityinfoindicationies(
|
|
|
|
&message->msg.s1ap_UECapabilityInfoIndicationIEs,
|
|
|
|
&initiating_p->value);
|
2017-02-10 13:16:22 +00:00
|
|
|
s1ap_decode_xer_print_message(
|
2017-02-05 06:16:32 +00:00
|
|
|
s1ap_xer_print_s1ap_uecapabilityinfoindication,
|
|
|
|
s1ap_xer__print2sp, message);
|
2017-02-05 06:36:02 +00:00
|
|
|
break;
|
2017-02-04 15:49:53 +00:00
|
|
|
|
|
|
|
case S1ap_ProcedureCode_id_NASNonDeliveryIndication:
|
|
|
|
ret = s1ap_decode_s1ap_nasnondeliveryindication_ies(
|
|
|
|
&message->msg.s1ap_NASNonDeliveryIndication_IEs,
|
|
|
|
&initiating_p->value);
|
2017-02-10 13:16:22 +00:00
|
|
|
s1ap_decode_xer_print_message(s1ap_xer_print_s1ap_nasnondeliveryindication,
|
2017-02-05 06:16:32 +00:00
|
|
|
s1ap_xer__print2sp, message);
|
2017-02-05 06:36:02 +00:00
|
|
|
break;
|
2017-02-04 15:49:53 +00:00
|
|
|
|
|
|
|
default:
|
2017-02-04 16:11:21 +00:00
|
|
|
d_error("Unknown procedure ID (%d) for initiating message",
|
2017-02-04 15:49:53 +00:00
|
|
|
(int)initiating_p->procedureCode);
|
2017-02-05 06:36:02 +00:00
|
|
|
break;
|
2017-02-04 15:49:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-02-04 16:11:21 +00:00
|
|
|
static int s1ap_decode_successfull_outcome(s1ap_message *message,
|
2017-02-04 15:49:53 +00:00
|
|
|
S1ap_SuccessfulOutcome_t *successfullOutcome_p)
|
|
|
|
{
|
2017-02-04 16:11:21 +00:00
|
|
|
int ret = -1;
|
2017-02-04 15:49:53 +00:00
|
|
|
|
2017-02-04 16:11:21 +00:00
|
|
|
d_assert(successfullOutcome_p, return -1, "Null param");
|
2017-02-04 15:49:53 +00:00
|
|
|
|
2017-02-09 14:15:08 +00:00
|
|
|
message->procedureCode = successfullOutcome_p->procedureCode;
|
2017-02-04 15:49:53 +00:00
|
|
|
switch (successfullOutcome_p->procedureCode)
|
|
|
|
{
|
2017-02-13 07:25:36 +00:00
|
|
|
case S1ap_ProcedureCode_id_S1Setup:
|
|
|
|
ret = s1ap_decode_s1ap_s1setupresponseies(
|
|
|
|
&message->msg.s1ap_S1SetupResponseIEs,
|
|
|
|
&successfullOutcome_p->value);
|
|
|
|
s1ap_decode_xer_print_message(
|
|
|
|
s1ap_xer_print_s1ap_s1setupresponse,
|
|
|
|
s1ap_xer__print2sp, message);
|
|
|
|
break;
|
2017-02-04 15:49:53 +00:00
|
|
|
case S1ap_ProcedureCode_id_InitialContextSetup:
|
|
|
|
ret = s1ap_decode_s1ap_initialcontextsetupresponseies(
|
|
|
|
&message->msg.s1ap_InitialContextSetupResponseIEs,
|
|
|
|
&successfullOutcome_p->value);
|
2017-02-10 13:16:22 +00:00
|
|
|
s1ap_decode_xer_print_message(
|
2017-02-05 06:16:32 +00:00
|
|
|
s1ap_xer_print_s1ap_initialcontextsetupresponse,
|
|
|
|
s1ap_xer__print2sp, message);
|
2017-02-05 06:36:02 +00:00
|
|
|
break;
|
2017-02-04 15:49:53 +00:00
|
|
|
|
|
|
|
case S1ap_ProcedureCode_id_UEContextRelease:
|
|
|
|
ret = s1ap_decode_s1ap_uecontextreleasecomplete_ies(
|
|
|
|
&message->msg.s1ap_UEContextReleaseComplete_IEs,
|
|
|
|
&successfullOutcome_p->value);
|
2017-02-10 13:16:22 +00:00
|
|
|
s1ap_decode_xer_print_message(
|
2017-02-05 06:16:32 +00:00
|
|
|
s1ap_xer_print_s1ap_uecontextreleasecomplete,
|
|
|
|
s1ap_xer__print2sp, message);
|
2017-02-05 06:36:02 +00:00
|
|
|
break;
|
2017-02-04 15:49:53 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
d_error("Unknown procedure ID (%ld) for successfull "
|
2017-02-04 16:11:21 +00:00
|
|
|
"outcome message", successfullOutcome_p->procedureCode);
|
2017-02-04 15:49:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-02-04 16:11:21 +00:00
|
|
|
static int s1ap_decode_unsuccessfull_outcome(s1ap_message *message,
|
2017-02-05 06:16:32 +00:00
|
|
|
S1ap_UnsuccessfulOutcome_t *unSuccessfulOutcome_p)
|
2017-02-04 15:49:53 +00:00
|
|
|
{
|
2017-02-04 16:11:21 +00:00
|
|
|
int ret = -1;
|
2017-02-04 15:49:53 +00:00
|
|
|
|
2017-02-04 16:11:21 +00:00
|
|
|
d_assert(unSuccessfulOutcome_p, return -1, "Null param");
|
2017-02-04 15:49:53 +00:00
|
|
|
|
2017-02-09 14:15:08 +00:00
|
|
|
message->procedureCode = unSuccessfulOutcome_p->procedureCode;
|
2017-02-04 15:49:53 +00:00
|
|
|
switch (unSuccessfulOutcome_p->procedureCode)
|
|
|
|
{
|
2017-02-13 11:10:05 +00:00
|
|
|
case S1ap_ProcedureCode_id_S1Setup:
|
|
|
|
ret = s1ap_decode_s1ap_s1setupfailureies(
|
|
|
|
&message->msg.s1ap_S1SetupFailureIEs,
|
|
|
|
&unSuccessfulOutcome_p->value);
|
|
|
|
s1ap_decode_xer_print_message(
|
|
|
|
s1ap_xer_print_s1ap_s1setupfailure,
|
|
|
|
s1ap_xer__print2sp, message);
|
|
|
|
break;
|
2017-02-04 15:49:53 +00:00
|
|
|
case S1ap_ProcedureCode_id_InitialContextSetup:
|
|
|
|
ret = s1ap_decode_s1ap_initialcontextsetupfailureies(
|
|
|
|
&message->msg.s1ap_InitialContextSetupFailureIEs,
|
|
|
|
&unSuccessfulOutcome_p->value);
|
2017-02-10 13:16:22 +00:00
|
|
|
s1ap_decode_xer_print_message(
|
2017-02-05 06:16:32 +00:00
|
|
|
s1ap_xer_print_s1ap_initialcontextsetupfailure,
|
|
|
|
s1ap_xer__print2sp, message);
|
2017-02-05 06:36:02 +00:00
|
|
|
break;
|
2017-02-04 15:49:53 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
d_error("Unknown procedure ID (%d) for "
|
2017-02-04 16:11:21 +00:00
|
|
|
"unsuccessfull outcome message",
|
2017-02-04 15:49:53 +00:00
|
|
|
(int)unSuccessfulOutcome_p->procedureCode);
|
2017-02-05 06:36:02 +00:00
|
|
|
break;
|
2017-02-04 15:49:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-02-10 13:16:22 +00:00
|
|
|
static void s1ap_decode_xer_print_message(
|
2017-02-05 06:16:32 +00:00
|
|
|
asn_enc_rval_t (*func)(asn_app_consume_bytes_f *cb,
|
|
|
|
void *app_key, s1ap_message *message_p),
|
|
|
|
asn_app_consume_bytes_f *cb, s1ap_message *message_p)
|
|
|
|
{
|
|
|
|
if (g_trace_mask && TRACE_MODULE >= 3)
|
2017-02-04 15:49:53 +00:00
|
|
|
{
|
2017-02-10 13:27:35 +00:00
|
|
|
char *message_string = core_calloc(HUGE_STRING_LEN, sizeof(c_uint8_t));
|
2017-02-05 06:16:32 +00:00
|
|
|
s1ap_string_total_size = 0;
|
2017-02-04 15:49:53 +00:00
|
|
|
|
2017-02-10 13:27:35 +00:00
|
|
|
func(cb, message_string, message_p);
|
2017-02-04 15:49:53 +00:00
|
|
|
|
2017-02-10 13:27:35 +00:00
|
|
|
printf("%s\n", message_string);
|
|
|
|
core_free(message_string);
|
2017-02-04 15:49:53 +00:00
|
|
|
}
|
|
|
|
}
|
2017-02-05 06:16:32 +00:00
|
|
|
|