2017-03-08 06:27:48 +00:00
|
|
|
#define TRACE_MODULE _s1ap_build
|
2017-02-06 10:12:10 +00:00
|
|
|
|
2017-02-06 11:54:31 +00:00
|
|
|
#include "core_debug.h"
|
2017-03-26 06:34:34 +00:00
|
|
|
|
2017-04-06 10:20:33 +00:00
|
|
|
#include "mme_context.h"
|
2017-03-26 06:34:34 +00:00
|
|
|
|
2017-02-20 10:46:58 +00:00
|
|
|
#include "s1ap_build.h"
|
2017-02-10 12:51:56 +00:00
|
|
|
#include "s1ap_conv.h"
|
2017-02-06 10:12:10 +00:00
|
|
|
|
|
|
|
status_t s1ap_build_setup_rsp(pkbuf_t **pkbuf)
|
|
|
|
{
|
|
|
|
int erval;
|
|
|
|
int i, j;
|
|
|
|
|
2017-03-06 00:07:59 +00:00
|
|
|
s1ap_message_t message;
|
2017-02-06 10:12:10 +00:00
|
|
|
S1ap_S1SetupResponseIEs_t *ies = NULL;
|
2017-02-06 12:52:20 +00:00
|
|
|
int numServedGUMMEI = 0;
|
2017-02-07 02:35:22 +00:00
|
|
|
S1ap_ServedGUMMEIsItem_t *servedGUMMEI;
|
|
|
|
S1ap_PLMNidentity_t *plmnIdentity;
|
|
|
|
S1ap_MME_Group_ID_t *mmeGroupId;
|
|
|
|
S1ap_MME_Code_t *mmeCode;
|
2017-02-06 11:54:31 +00:00
|
|
|
|
2017-03-06 00:07:59 +00:00
|
|
|
memset(&message, 0, sizeof(s1ap_message_t));
|
2017-02-06 10:12:10 +00:00
|
|
|
|
2017-03-05 02:46:42 +00:00
|
|
|
ies = &message.s1ap_S1SetupResponseIEs;
|
2017-02-06 10:12:10 +00:00
|
|
|
|
2017-02-06 12:52:20 +00:00
|
|
|
numServedGUMMEI = 1;
|
2017-02-07 02:35:22 +00:00
|
|
|
servedGUMMEI = (S1ap_ServedGUMMEIsItem_t *)
|
2017-02-10 12:51:56 +00:00
|
|
|
core_calloc(numServedGUMMEI, sizeof(S1ap_ServedGUMMEIsItem_t));
|
2017-02-06 12:52:20 +00:00
|
|
|
for (i = 0; i < numServedGUMMEI; i++)
|
2017-02-06 10:12:10 +00:00
|
|
|
{
|
|
|
|
srvd_gummei_t *srvd_gummei = &mme_self()->srvd_gummei;
|
|
|
|
|
2017-02-06 11:54:31 +00:00
|
|
|
for (j = 0; j < srvd_gummei->num_of_plmn_id; j++)
|
2017-02-06 10:12:10 +00:00
|
|
|
{
|
2017-02-07 02:35:22 +00:00
|
|
|
plmnIdentity = (S1ap_PLMNidentity_t *)
|
2017-03-24 13:52:55 +00:00
|
|
|
core_calloc(1, sizeof(S1ap_PLMNidentity_t));
|
|
|
|
s1ap_buffer_to_OCTET_STRING(
|
|
|
|
&srvd_gummei->plmn_id[j], PLMN_ID_LEN, plmnIdentity);
|
2017-02-07 02:35:22 +00:00
|
|
|
ASN_SEQUENCE_ADD(&servedGUMMEI->servedPLMNs, plmnIdentity);
|
2017-02-06 10:12:10 +00:00
|
|
|
}
|
|
|
|
|
2017-02-13 05:41:20 +00:00
|
|
|
for (j = 0; j < srvd_gummei->num_of_mme_gid; j++)
|
2017-02-06 10:12:10 +00:00
|
|
|
{
|
2017-02-07 02:35:22 +00:00
|
|
|
mmeGroupId = (S1ap_MME_Group_ID_t *)
|
2017-03-24 13:52:55 +00:00
|
|
|
core_calloc(1, sizeof(S1ap_MME_Group_ID_t));
|
2017-03-05 02:29:15 +00:00
|
|
|
s1ap_uint16_to_OCTET_STRING(
|
2017-02-13 05:41:20 +00:00
|
|
|
srvd_gummei->mme_gid[j], mmeGroupId);
|
2017-02-07 02:35:22 +00:00
|
|
|
ASN_SEQUENCE_ADD(&servedGUMMEI->servedGroupIDs, mmeGroupId);
|
2017-02-06 10:12:10 +00:00
|
|
|
}
|
|
|
|
|
2017-02-13 05:41:20 +00:00
|
|
|
for (j = 0; j < srvd_gummei->num_of_mme_code; j++)
|
2017-02-06 10:12:10 +00:00
|
|
|
{
|
2017-02-07 02:35:22 +00:00
|
|
|
mmeCode = (S1ap_MME_Code_t *)
|
2017-03-24 13:52:55 +00:00
|
|
|
core_calloc(1, sizeof(S1ap_MME_Code_t));
|
2017-03-05 02:29:15 +00:00
|
|
|
s1ap_uint8_to_OCTET_STRING(
|
2017-02-13 05:41:20 +00:00
|
|
|
srvd_gummei->mme_code[j], mmeCode);
|
2017-02-07 02:35:22 +00:00
|
|
|
ASN_SEQUENCE_ADD(&servedGUMMEI->servedMMECs, mmeCode);
|
2017-02-06 10:12:10 +00:00
|
|
|
}
|
|
|
|
}
|
2017-02-07 02:35:22 +00:00
|
|
|
ASN_SEQUENCE_ADD(&ies->servedGUMMEIs, servedGUMMEI);
|
2017-02-14 00:09:01 +00:00
|
|
|
|
|
|
|
ies->relativeMMECapacity = mme_self()->relative_capacity;
|
|
|
|
|
2017-02-06 10:12:10 +00:00
|
|
|
message.procedureCode = S1ap_ProcedureCode_id_S1Setup;
|
|
|
|
message.direction = S1AP_PDU_PR_successfulOutcome;
|
|
|
|
|
|
|
|
erval = s1ap_encode_pdu(pkbuf, &message);
|
2017-02-09 14:15:08 +00:00
|
|
|
s1ap_free_pdu(&message);
|
2017-02-07 02:35:22 +00:00
|
|
|
|
2017-02-06 10:12:10 +00:00
|
|
|
if (erval < 0)
|
2017-02-07 02:35:22 +00:00
|
|
|
{
|
|
|
|
d_error("s1ap_encode_error : (%d)", erval);
|
2017-02-06 10:12:10 +00:00
|
|
|
return CORE_ERROR;
|
2017-02-07 02:35:22 +00:00
|
|
|
}
|
2017-02-06 10:12:10 +00:00
|
|
|
|
|
|
|
return CORE_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-13 11:10:05 +00:00
|
|
|
status_t s1ap_build_setup_failure(pkbuf_t **pkbuf, S1ap_Cause_t cause)
|
|
|
|
{
|
|
|
|
int erval;
|
|
|
|
|
2017-03-06 00:07:59 +00:00
|
|
|
s1ap_message_t message;
|
2017-02-13 11:10:05 +00:00
|
|
|
S1ap_S1SetupFailureIEs_t *ies = NULL;
|
|
|
|
|
2017-03-06 00:07:59 +00:00
|
|
|
memset(&message, 0, sizeof(s1ap_message_t));
|
2017-02-13 11:10:05 +00:00
|
|
|
|
2017-03-05 02:46:42 +00:00
|
|
|
ies = &message.s1ap_S1SetupFailureIEs;
|
2017-02-13 11:10:05 +00:00
|
|
|
ies->cause = cause;
|
|
|
|
|
|
|
|
message.procedureCode = S1ap_ProcedureCode_id_S1Setup;
|
|
|
|
message.direction = S1AP_PDU_PR_unsuccessfulOutcome;
|
|
|
|
|
|
|
|
erval = s1ap_encode_pdu(pkbuf, &message);
|
|
|
|
s1ap_free_pdu(&message);
|
|
|
|
|
|
|
|
if (erval < 0)
|
|
|
|
{
|
|
|
|
d_error("s1ap_encode_error : (%d)", erval);
|
|
|
|
return CORE_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CORE_OK;
|
|
|
|
}
|
2017-04-13 02:08:42 +00:00
|
|
|
|
2017-04-13 08:46:26 +00:00
|
|
|
status_t s1ap_build_downlink_nas_transport(
|
|
|
|
pkbuf_t **s1apbuf, mme_ue_t *ue, pkbuf_t *emmbuf)
|
2017-04-13 02:08:42 +00:00
|
|
|
{
|
2017-04-13 10:58:58 +00:00
|
|
|
char buf[INET_ADDRSTRLEN];
|
|
|
|
|
2017-04-13 03:21:47 +00:00
|
|
|
int encoded;
|
|
|
|
s1ap_message_t message;
|
|
|
|
S1ap_DownlinkNASTransport_IEs_t *ies =
|
|
|
|
&message.s1ap_DownlinkNASTransport_IEs;
|
|
|
|
S1ap_NAS_PDU_t *nasPdu = &ies->nas_pdu;
|
2017-04-13 08:46:26 +00:00
|
|
|
|
|
|
|
d_assert(emmbuf, return CORE_ERROR, "Null param");
|
|
|
|
d_assert(ue, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
memset(&message, 0, sizeof(s1ap_message_t));
|
|
|
|
|
|
|
|
ies->mme_ue_s1ap_id = ue->mme_ue_s1ap_id;
|
|
|
|
ies->eNB_UE_S1AP_ID = ue->enb_ue_s1ap_id;
|
|
|
|
|
|
|
|
nasPdu->size = emmbuf->len;
|
|
|
|
nasPdu->buf = core_calloc(nasPdu->size, sizeof(c_uint8_t));
|
|
|
|
memcpy(nasPdu->buf, emmbuf->payload, nasPdu->size);
|
|
|
|
|
|
|
|
message.procedureCode = S1ap_ProcedureCode_id_downlinkNASTransport;
|
|
|
|
message.direction = S1AP_PDU_PR_initiatingMessage;
|
|
|
|
|
|
|
|
encoded = s1ap_encode_pdu(s1apbuf, &message);
|
|
|
|
s1ap_free_pdu(&message);
|
|
|
|
|
|
|
|
d_assert(s1apbuf && encoded >= 0,return CORE_ERROR,);
|
|
|
|
pkbuf_free(emmbuf);
|
|
|
|
|
2017-04-13 10:58:58 +00:00
|
|
|
d_info("[S1AP] downlinkNASTransport : "
|
|
|
|
"UE[eNB-UE-S1AP-ID(%d)] <-- eNB[%s:%d]",
|
|
|
|
ue->enb_ue_s1ap_id,
|
|
|
|
INET_NTOP(&ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
|
|
|
|
ue->enb->enb_id);
|
|
|
|
|
2017-04-13 08:46:26 +00:00
|
|
|
return CORE_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
status_t s1ap_build_initial_context_setup_request(
|
2017-04-13 10:15:53 +00:00
|
|
|
pkbuf_t **s1apbuf, mme_bearer_t *bearer, pkbuf_t *emmbuf)
|
2017-04-13 08:46:26 +00:00
|
|
|
{
|
2017-04-13 10:58:58 +00:00
|
|
|
char buf[INET_ADDRSTRLEN];
|
|
|
|
|
2017-04-13 08:46:26 +00:00
|
|
|
int encoded;
|
|
|
|
s1ap_message_t message;
|
|
|
|
S1ap_InitialContextSetupRequestIEs_t *ies =
|
|
|
|
&message.s1ap_InitialContextSetupRequestIEs;
|
|
|
|
S1ap_E_RABToBeSetupItemCtxtSUReq_t *e_rab = NULL;
|
|
|
|
S1ap_NAS_PDU_t *nasPdu = NULL;
|
2017-04-13 03:21:47 +00:00
|
|
|
mme_ue_t *ue = NULL;
|
2017-04-13 08:46:26 +00:00
|
|
|
pdn_t *pdn = NULL;
|
2017-04-13 03:21:47 +00:00
|
|
|
|
|
|
|
d_assert(emmbuf, return CORE_ERROR, "Null param");
|
2017-04-13 10:15:53 +00:00
|
|
|
d_assert(bearer, return CORE_ERROR, "Null param");
|
|
|
|
ue = bearer->ue;
|
2017-04-13 03:21:47 +00:00
|
|
|
d_assert(ue, return CORE_ERROR, "Null param");
|
2017-04-13 10:15:53 +00:00
|
|
|
pdn = bearer->pdn;
|
2017-04-13 08:46:26 +00:00
|
|
|
d_assert(pdn, return CORE_ERROR, "Null param");
|
2017-04-13 03:21:47 +00:00
|
|
|
|
|
|
|
memset(&message, 0, sizeof(s1ap_message_t));
|
|
|
|
|
|
|
|
ies->mme_ue_s1ap_id = ue->mme_ue_s1ap_id;
|
|
|
|
ies->eNB_UE_S1AP_ID = ue->enb_ue_s1ap_id;
|
|
|
|
|
2017-04-13 08:46:26 +00:00
|
|
|
asn_uint642INTEGER(
|
|
|
|
&ies->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateUL,
|
|
|
|
ue->max_bandwidth_ul);
|
|
|
|
asn_uint642INTEGER(
|
|
|
|
&ies->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateDL,
|
|
|
|
ue->max_bandwidth_dl);
|
|
|
|
|
|
|
|
e_rab = (S1ap_E_RABToBeSetupItemCtxtSUReq_t *)
|
|
|
|
core_calloc(1, sizeof(S1ap_E_RABToBeSetupItemCtxtSUReq_t));
|
2017-04-13 10:15:53 +00:00
|
|
|
e_rab->e_RAB_ID = bearer->ebi;
|
2017-04-13 08:46:26 +00:00
|
|
|
e_rab->e_RABlevelQoSParameters.qCI = pdn->qci;
|
|
|
|
|
|
|
|
e_rab->e_RABlevelQoSParameters.allocationRetentionPriority.
|
|
|
|
priorityLevel = pdn->priority_level;
|
|
|
|
e_rab->e_RABlevelQoSParameters.allocationRetentionPriority.
|
|
|
|
pre_emptionCapability =
|
|
|
|
S1ap_Pre_emptionCapability_shall_not_trigger_pre_emption;
|
|
|
|
e_rab->e_RABlevelQoSParameters.allocationRetentionPriority.
|
|
|
|
pre_emptionVulnerability =
|
|
|
|
S1ap_Pre_emptionVulnerability_not_pre_emptable;
|
|
|
|
e_rab->transportLayerAddress.size = 4;
|
|
|
|
e_rab->transportLayerAddress.buf =
|
|
|
|
core_calloc(e_rab->transportLayerAddress.size, sizeof(c_uint8_t));
|
2017-04-13 10:15:53 +00:00
|
|
|
memcpy(e_rab->transportLayerAddress.buf, &bearer->sgw_s1u_addr,
|
2017-04-13 08:46:26 +00:00
|
|
|
e_rab->transportLayerAddress.size);
|
|
|
|
|
2017-04-13 10:15:53 +00:00
|
|
|
s1ap_uint32_to_OCTET_STRING(bearer->sgw_s1u_teid, &e_rab->gTP_TEID);
|
2017-04-13 08:46:26 +00:00
|
|
|
|
|
|
|
nasPdu = (S1ap_NAS_PDU_t *)core_calloc(1, sizeof(S1ap_NAS_PDU_t));
|
2017-04-13 03:21:47 +00:00
|
|
|
nasPdu->size = emmbuf->len;
|
|
|
|
nasPdu->buf = core_calloc(nasPdu->size, sizeof(c_uint8_t));
|
|
|
|
memcpy(nasPdu->buf, emmbuf->payload, nasPdu->size);
|
2017-04-13 08:46:26 +00:00
|
|
|
e_rab->nAS_PDU = nasPdu;
|
2017-04-13 03:21:47 +00:00
|
|
|
|
2017-04-13 08:46:26 +00:00
|
|
|
ASN_SEQUENCE_ADD(&ies->e_RABToBeSetupListCtxtSUReq, e_rab);
|
|
|
|
|
|
|
|
ies->securityKey.size = 32;
|
|
|
|
ies->securityKey.buf =
|
|
|
|
core_calloc(ies->securityKey.size, sizeof(c_uint8_t));
|
|
|
|
|
|
|
|
message.procedureCode = S1ap_ProcedureCode_id_InitialContextSetup;
|
2017-04-13 03:21:47 +00:00
|
|
|
message.direction = S1AP_PDU_PR_initiatingMessage;
|
|
|
|
|
|
|
|
encoded = s1ap_encode_pdu(s1apbuf, &message);
|
|
|
|
s1ap_free_pdu(&message);
|
|
|
|
|
|
|
|
d_assert(s1apbuf && encoded >= 0,return CORE_ERROR,);
|
2017-04-13 08:46:26 +00:00
|
|
|
pkbuf_free(emmbuf);
|
2017-04-13 03:21:47 +00:00
|
|
|
|
2017-04-13 10:58:58 +00:00
|
|
|
d_info("[S1AP] Initial Context Setup Request : "
|
|
|
|
"UE[eNB-UE-S1AP-ID(%d)] <-- eNB[%s:%d]",
|
|
|
|
ue->enb_ue_s1ap_id,
|
|
|
|
INET_NTOP(&ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
|
|
|
|
ue->enb->enb_id);
|
|
|
|
|
2017-04-13 02:08:42 +00:00
|
|
|
return CORE_OK;
|
|
|
|
}
|