merge the implemention of Paging, RRCConnectionRelease, RRCConnectionReestablishment, E-RAB Modify, E-RAB Release
This commit is contained in:
@@ -766,6 +766,7 @@ gtpv1u_create_s1u_tunnel(
|
||||
gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_eNB = s1u_teid;
|
||||
gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_eNB_stack_session = stack_req.apiInfo.createTunnelEndPointInfo.hStackSession;
|
||||
gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_sgw = create_tunnel_req_pP->sgw_S1u_teid[i];
|
||||
gtpv1u_ue_data_p->num_bearers++;
|
||||
create_tunnel_resp_pP->enb_S1u_teid[i] = s1u_teid;
|
||||
|
||||
} else {
|
||||
@@ -807,7 +808,47 @@ gtpv1u_create_s1u_tunnel(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gtpv1u_update_s1u_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_enb_create_tunnel_req_t * const create_tunnel_req_pP,
|
||||
const rnti_t prior_rnti
|
||||
)
|
||||
{
|
||||
/* Local tunnel end-point identifier */
|
||||
teid_t s1u_teid = 0;
|
||||
gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL;
|
||||
gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL;
|
||||
//MessageDef *message_p = NULL;
|
||||
hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
|
||||
int i;
|
||||
ebi_t eps_bearer_id = 0;
|
||||
|
||||
//-----------------------
|
||||
// PDCP->GTPV1U mapping
|
||||
//-----------------------
|
||||
hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, prior_rnti, (void **)>pv1u_ue_data_p);
|
||||
AssertFatal(hash_rc == HASH_TABLE_OK, "Error get ue_mapping(rnti=%x) from GTPV1U hashtable error\n", prior_rnti);
|
||||
|
||||
gtpv1u_ue_data_p->ue_id = create_tunnel_req_pP->rnti;
|
||||
hash_rc = hashtable_insert(RC.gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, gtpv1u_ue_data_p);
|
||||
AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting ue_mapping in GTPV1U hashtable");
|
||||
LOG_I(GTPU, "inserting ue_mapping(rnti=%x) in GTPV1U hashtable\n",
|
||||
create_tunnel_req_pP->rnti);
|
||||
|
||||
//-----------------------
|
||||
// GTPV1U->PDCP mapping
|
||||
//-----------------------
|
||||
for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) {
|
||||
eps_bearer_id = create_tunnel_req_pP->eps_bearer_id[i];
|
||||
s1u_teid = gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_eNB;
|
||||
hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, s1u_teid, (void**)>pv1u_teid_data_p);
|
||||
AssertFatal(hash_rc == HASH_TABLE_OK, "Error get teid mapping(s1u_teid=%u) from GTPV1U hashtable", s1u_teid);
|
||||
|
||||
gtpv1u_teid_data_p->ue_id = create_tunnel_req_pP->rnti;
|
||||
gtpv1u_teid_data_p->eps_bearer_id = eps_bearer_id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
static int gtpv1u_delete_s1u_tunnel(
|
||||
|
||||
@@ -49,5 +49,9 @@ gtpv1u_create_s1u_tunnel(
|
||||
const gtpv1u_enb_create_tunnel_req_t * const create_tunnel_req_pP,
|
||||
gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP);
|
||||
|
||||
|
||||
int
|
||||
gtpv1u_update_s1u_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_enb_create_tunnel_req_t * const create_tunnel_req_pP,
|
||||
const rnti_t prior_rnti);
|
||||
#endif /* GTPV1U_ENB_TASK_H_ */
|
||||
|
||||
@@ -364,6 +364,12 @@ void *s1ap_eNB_task(void *arg)
|
||||
&S1AP_E_RAB_SETUP_RESP(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_E_RAB_MODIFY_RESP: {
|
||||
s1ap_eNB_e_rab_modify_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&S1AP_E_RAB_MODIFY_RESP(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_NAS_NON_DELIVERY_IND: {
|
||||
s1ap_eNB_nas_non_delivery_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
@@ -397,6 +403,12 @@ void *s1ap_eNB_task(void *arg)
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_E_RAB_RELEASE_RESPONSE: {
|
||||
s1ap_eNB_e_rab_release_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&S1AP_E_RAB_RELEASE_RESPONSE(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
S1AP_ERROR("Received unhandled message: %d:%s\n",
|
||||
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
|
||||
|
||||
@@ -108,7 +108,15 @@ static int s1ap_eNB_decode_initiating_message(s1ap_message *message,
|
||||
ret = s1ap_decode_s1ap_pagingies(
|
||||
&message->msg.s1ap_PagingIEs, &initiating_p->value);
|
||||
s1ap_xer_print_s1ap_paging(s1ap_xer__print2sp, message_string, message);
|
||||
S1AP_ERROR("TODO Paging initiating message\n");
|
||||
message_id = S1AP_PAGING_LOG;
|
||||
message_string_size = strlen(message_string);
|
||||
message_p = itti_alloc_new_message_sized(TASK_S1AP,
|
||||
message_id,
|
||||
message_string_size + sizeof (IttiMsgText));
|
||||
message_p->ittiMsg.s1ap_paging_log.size = message_string_size;
|
||||
memcpy(&message_p->ittiMsg.s1ap_paging_log.text, message_string, message_string_size);
|
||||
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
|
||||
S1AP_INFO("Paging initiating message\n");
|
||||
free(message_string);
|
||||
break;
|
||||
|
||||
@@ -128,12 +136,36 @@ static int s1ap_eNB_decode_initiating_message(s1ap_message *message,
|
||||
free(message_string);
|
||||
S1AP_INFO("E_RABSetup initiating message\n");
|
||||
break;
|
||||
case S1ap_ProcedureCode_id_E_RABRelease:
|
||||
ret = s1ap_decode_s1ap_e_rabreleasecommandies(&message->msg.s1ap_E_RABReleaseCommandIEs,
|
||||
&initiating_p->value);
|
||||
//s1ap_xer_print_s1ap_e_rabsetuprequest(s1ap_xer__print2sp, message_string, message);
|
||||
S1AP_INFO("TODO E_RABRelease nitiating message\n");
|
||||
|
||||
case S1ap_ProcedureCode_id_E_RABModify:
|
||||
ret = s1ap_decode_s1ap_e_rabmodifyrequesties(
|
||||
&message->msg.s1ap_E_RABModifyRequestIEs, &initiating_p->value);
|
||||
message_id = S1AP_E_RAB_MODIFY_REQUEST_LOG;
|
||||
message_string_size = strlen(message_string);
|
||||
message_p = itti_alloc_new_message_sized(TASK_S1AP,
|
||||
message_id,
|
||||
message_string_size + sizeof (IttiMsgText));
|
||||
message_p->ittiMsg.s1ap_e_rab_modify_request_log.size = message_string_size;
|
||||
memcpy(&message_p->ittiMsg.s1ap_e_rab_modify_request_log.text, message_string, message_string_size);
|
||||
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
|
||||
free(message_string);
|
||||
S1AP_INFO("E_RABModify initiating message\n");
|
||||
break;
|
||||
|
||||
case S1ap_ProcedureCode_id_E_RABRelease:
|
||||
ret = s1ap_decode_s1ap_e_rabreleasecommandies(
|
||||
&message->msg.s1ap_E_RABReleaseCommandIEs, &initiating_p->value);
|
||||
s1ap_xer_print_s1ap_e_rabreleasecommand(s1ap_xer__print2sp, message_string, message);
|
||||
message_id = S1AP_E_RAB_RELEASE_REQUEST_LOG;
|
||||
message_string_size = strlen(message_string);
|
||||
message_p = itti_alloc_new_message_sized(TASK_S1AP,
|
||||
message_id,
|
||||
message_string_size + sizeof (IttiMsgText));
|
||||
message_p->ittiMsg.s1ap_e_rab_release_request_log.size = message_string_size;
|
||||
memcpy(&message_p->ittiMsg.s1ap_e_rab_release_request_log.text, message_string, message_string_size);
|
||||
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
|
||||
free(message_string);
|
||||
S1AP_INFO("TODO E_RABRelease nitiating message\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -100,6 +100,16 @@ int s1ap_eNB_encode_e_rab_setup_response(S1ap_E_RABSetupResponseIEs_t *E_RABSet
|
||||
uint8_t **buffer,
|
||||
uint32_t *length);
|
||||
|
||||
static inline
|
||||
int s1ap_eNB_encode_e_rab_modify_response(S1ap_E_RABModifyResponseIEs_t *E_RABModifyResponseIEs,
|
||||
uint8_t **buffer,
|
||||
uint32_t *length);
|
||||
|
||||
static inline
|
||||
int s1ap_eNB_encode_e_rab_release_response(S1ap_E_RABReleaseResponseIEs_t *s1ap_E_RABReleaseResponseIEs,
|
||||
uint8_t **buffer,
|
||||
uint32_t *length);
|
||||
|
||||
int s1ap_eNB_encode_pdu(s1ap_message *message, uint8_t **buffer, uint32_t *len)
|
||||
{
|
||||
DevAssert(message != NULL);
|
||||
@@ -264,6 +274,32 @@ int s1ap_eNB_encode_successfull_outcome(s1ap_message *s1ap_message_p,
|
||||
free(message_string);
|
||||
S1AP_INFO("E_RABSetup successful message\n");
|
||||
break;
|
||||
|
||||
case S1ap_ProcedureCode_id_E_RABModify:
|
||||
ret = s1ap_eNB_encode_e_rab_modify_response (
|
||||
&s1ap_message_p->msg.s1ap_E_RABModifyResponseIEs, buffer, len);
|
||||
message_id = S1AP_E_RAB_MODIFY_RESPONSE_LOG ;
|
||||
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, message_string_size + sizeof (IttiMsgText));
|
||||
message_p->ittiMsg.s1ap_e_rab_modify_response_log.size = message_string_size;
|
||||
memcpy(&message_p->ittiMsg.s1ap_e_rab_modify_response_log.text, message_string, message_string_size);
|
||||
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
|
||||
free(message_string);
|
||||
S1AP_INFO("E_RABModify successful message\n");
|
||||
break;
|
||||
|
||||
case S1ap_ProcedureCode_id_E_RABRelease:
|
||||
ret = s1ap_eNB_encode_e_rab_release_response (
|
||||
&s1ap_message_p->msg.s1ap_E_RABReleaseResponseIEs, buffer, len);
|
||||
s1ap_xer_print_s1ap_e_rabreleaseresponse(s1ap_xer__print2sp, message_string, s1ap_message_p);
|
||||
message_id = S1AP_E_RAB_RELEASE_RESPONSE_LOG ;
|
||||
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, message_string_size + sizeof (IttiMsgText));
|
||||
message_p->ittiMsg.s1ap_e_rab_release_response_log.size = message_string_size;
|
||||
memcpy(&message_p->ittiMsg.s1ap_e_rab_release_response_log.text, message_string, message_string_size);
|
||||
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
|
||||
free(message_string);
|
||||
S1AP_INFO("E_RAB Release successful message\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
S1AP_WARN("Unknown procedure ID (%d) for successfull outcome message\n",
|
||||
(int)s1ap_message_p->procedureCode);
|
||||
@@ -563,3 +599,48 @@ int s1ap_eNB_encode_e_rab_setup_response(S1ap_E_RABSetupResponseIEs_t *s1ap_E_R
|
||||
&asn_DEF_S1ap_E_RABSetupResponse,
|
||||
e_rab_setup_response_p);
|
||||
}
|
||||
|
||||
static inline
|
||||
int s1ap_eNB_encode_e_rab_modify_response(S1ap_E_RABModifyResponseIEs_t *s1ap_E_RABModifyResponseIEs,
|
||||
uint8_t **buffer,
|
||||
uint32_t *length)
|
||||
{
|
||||
S1ap_E_RABModifyResponse_t e_rab_modify_response;
|
||||
S1ap_E_RABModifyResponse_t *e_rab_modify_response_p = &e_rab_modify_response;
|
||||
|
||||
memset((void *)e_rab_modify_response_p, 0,
|
||||
sizeof(e_rab_modify_response));
|
||||
|
||||
if (s1ap_encode_s1ap_e_rabmodifyresponseies (e_rab_modify_response_p, s1ap_E_RABModifyResponseIEs) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return s1ap_generate_successfull_outcome(buffer,
|
||||
length,
|
||||
S1ap_ProcedureCode_id_E_RABModify,
|
||||
S1ap_Criticality_reject,
|
||||
&asn_DEF_S1ap_E_RABModifyResponse,
|
||||
e_rab_modify_response_p);
|
||||
}
|
||||
static inline
|
||||
int s1ap_eNB_encode_e_rab_release_response(S1ap_E_RABReleaseResponseIEs_t *s1ap_E_RABReleaseResponseIEs,
|
||||
uint8_t **buffer,
|
||||
uint32_t *length)
|
||||
{
|
||||
S1ap_E_RABReleaseResponse_t e_rab_release_response;
|
||||
S1ap_E_RABReleaseResponse_t *e_rab_release_response_p = &e_rab_release_response;
|
||||
|
||||
memset((void *)e_rab_release_response_p, 0,
|
||||
sizeof(e_rab_release_response));
|
||||
|
||||
if (s1ap_encode_s1ap_e_rabreleaseresponseies (e_rab_release_response_p, s1ap_E_RABReleaseResponseIEs) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return s1ap_generate_successfull_outcome(buffer,
|
||||
length,
|
||||
S1ap_ProcedureCode_id_E_RABRelease,
|
||||
S1ap_Criticality_reject,
|
||||
&asn_DEF_S1ap_E_RABReleaseResponse,
|
||||
e_rab_release_response_p);
|
||||
}
|
||||
|
||||
@@ -81,6 +81,20 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
struct s1ap_message_s *s1ap_message_p);
|
||||
|
||||
static
|
||||
int s1ap_eNB_handle_paging(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
struct s1ap_message_s *message_p);
|
||||
|
||||
static
|
||||
int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
struct s1ap_message_s *s1ap_message_p);
|
||||
|
||||
static
|
||||
int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
struct s1ap_message_s *s1ap_message_p);
|
||||
|
||||
/* Handlers matrix. Only eNB related procedure present here */
|
||||
s1ap_message_decoded_callback messages_callback[][3] = {
|
||||
@@ -90,11 +104,11 @@ s1ap_message_decoded_callback messages_callback[][3] = {
|
||||
{ 0, 0, 0 }, /* PathSwitchRequest */
|
||||
{ 0, 0, 0 }, /* HandoverCancel */
|
||||
{ s1ap_eNB_handle_e_rab_setup_request, 0, 0 }, /* E_RABSetup */
|
||||
{ 0, 0, 0 }, /* E_RABModify */
|
||||
{ 0, 0, 0 }, /* E_RABRelease */
|
||||
{ s1ap_eNB_handle_e_rab_modify_request, 0, 0 }, /* E_RABModify */
|
||||
{ s1ap_eNB_handle_e_rab_release_command, 0, 0 }, /* E_RABRelease */
|
||||
{ 0, 0, 0 }, /* E_RABReleaseIndication */
|
||||
{ s1ap_eNB_handle_initial_context_request, 0, 0 }, /* InitialContextSetup */
|
||||
{ 0, 0, 0 }, /* Paging */
|
||||
{ s1ap_eNB_handle_paging, 0, 0 }, /* Paging */
|
||||
{ s1ap_eNB_handle_nas_downlink, 0, 0 }, /* downlinkNASTransport */
|
||||
{ 0, 0, 0 }, /* initialUEMessage */
|
||||
{ 0, 0, 0 }, /* uplinkNASTransport */
|
||||
@@ -950,7 +964,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id,
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer = NULL;
|
||||
|
||||
S1AP_WARN("NAS PDU is not provided, generate a E_RAB_SETUP Failure (TBD) back to MME \n");
|
||||
return -1;
|
||||
// return -1;
|
||||
}
|
||||
|
||||
/* Set the transport layer address */
|
||||
@@ -983,4 +997,382 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int s1ap_eNB_handle_paging(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
struct s1ap_message_s *s1ap_message_p)
|
||||
{
|
||||
S1ap_PagingIEs_t *paging_p;
|
||||
s1ap_eNB_mme_data_t *mme_desc_p = NULL;
|
||||
s1ap_eNB_instance_t *s1ap_eNB_instance = NULL;
|
||||
MessageDef *message_p = NULL;
|
||||
|
||||
DevAssert(s1ap_message_p != NULL);
|
||||
// received Paging Message from MME
|
||||
S1AP_DEBUG("[SCTP %d] Received Paging Message From MME\n",assoc_id);
|
||||
|
||||
paging_p = &s1ap_message_p->msg.s1ap_PagingIEs;
|
||||
|
||||
/* Paging procedure -> stream != 0 */
|
||||
if (stream == 0) {
|
||||
S1AP_ERROR("[SCTP %d] Received Paging procedure on stream (%d)\n",
|
||||
assoc_id, stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
|
||||
S1AP_ERROR("[SCTP %d] Received Paging for non "
|
||||
"existing MME context\n", assoc_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
s1ap_eNB_instance = mme_desc_p->s1ap_eNB_instance;
|
||||
if (s1ap_eNB_instance == NULL) {
|
||||
S1AP_ERROR("[SCTP %d] Received Paging for non existing MME context : s1ap_eNB_instance is NULL\n",
|
||||
assoc_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_PAGING_IND);
|
||||
|
||||
/* convert S1ap_PagingIEs_t to s1ap_paging_ind_t */
|
||||
/* convert UE Identity Index value */
|
||||
S1AP_PAGING_IND(message_p).ue_index_value = BIT_STRING_to_uint32(&paging_p->ueIdentityIndexValue);
|
||||
S1AP_DEBUG("[SCTP %d] Received Paging ue_index_value (%d)\n",
|
||||
assoc_id,(uint32_t)S1AP_PAGING_IND(message_p).ue_index_value);
|
||||
|
||||
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code = 0;
|
||||
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi = 0;
|
||||
|
||||
/* convert UE Paging Identity */
|
||||
if (paging_p->uePagingID.present == S1ap_UEPagingID_PR_s_TMSI) {
|
||||
S1AP_PAGING_IND(message_p).ue_paging_identity.presenceMask = UE_PAGING_IDENTITY_s_tmsi;
|
||||
OCTET_STRING_TO_INT8(&paging_p->uePagingID.choice.s_TMSI.mMEC, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code);
|
||||
OCTET_STRING_TO_INT32(&paging_p->uePagingID.choice.s_TMSI.m_TMSI, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi);
|
||||
} else if (paging_p->uePagingID.present == S1ap_UEPagingID_PR_iMSI) {
|
||||
S1AP_PAGING_IND(message_p).ue_paging_identity.presenceMask = UE_PAGING_IDENTITY_imsi;
|
||||
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length = 0;
|
||||
for (int i = 0; i < paging_p->uePagingID.choice.iMSI.size; i++) {
|
||||
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i] = (uint8_t)(paging_p->uePagingID.choice.iMSI.buf[i] & 0x0F );
|
||||
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length++;
|
||||
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1] = (uint8_t)((paging_p->uePagingID.choice.iMSI.buf[i]>>4) & 0x0F);
|
||||
LOG_D(S1AP,"paging : i %d %d imsi %d %d \n",2*i,2*i+1,S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1]);
|
||||
if (S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1] == 0x0F) {
|
||||
if(i != paging_p->uePagingID.choice.iMSI.size - 1){
|
||||
/* invalid paging_p->uePagingID.choise.iMSI.buffer */
|
||||
S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI error(i %d 0x0F)\n", assoc_id,i);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length++;
|
||||
}
|
||||
}
|
||||
if (S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length >= S1AP_IMSI_LENGTH) {
|
||||
/* invalid paging_p->uePagingID.choise.iMSI.size */
|
||||
S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI.size(%d) is over IMSI length(%d)\n", assoc_id, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length, S1AP_IMSI_LENGTH);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* invalid paging_p->uePagingID.present */
|
||||
S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.present(%d) is unknown\n", assoc_id, paging_p->uePagingID.present);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* convert Paging DRX(optional) */
|
||||
if (paging_p->presenceMask & S1AP_PAGINGIES_PAGINGDRX_PRESENT) {
|
||||
switch(paging_p->pagingDRX) {
|
||||
case S1ap_PagingDRX_v32:
|
||||
S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_32;
|
||||
break;
|
||||
case S1ap_PagingDRX_v64:
|
||||
S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_64;
|
||||
break;
|
||||
case S1ap_PagingDRX_v128:
|
||||
S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_128;
|
||||
break;
|
||||
case S1ap_PagingDRX_v256:
|
||||
S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_256;
|
||||
break;
|
||||
default:
|
||||
// when UE Paging DRX is no value
|
||||
S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_256;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_256;
|
||||
|
||||
/* convert cnDomain */
|
||||
if (paging_p->cnDomain == S1ap_CNDomain_ps) {
|
||||
S1AP_PAGING_IND(message_p).cn_domain = CN_DOMAIN_PS;
|
||||
} else if (paging_p->cnDomain == S1ap_CNDomain_cs) {
|
||||
S1AP_PAGING_IND(message_p).cn_domain = CN_DOMAIN_CS;
|
||||
} else {
|
||||
/* invalid paging_p->cnDomain */
|
||||
S1AP_ERROR("[SCTP %d] Received Paging : cnDomain(%ld) is unknown\n", assoc_id, paging_p->cnDomain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset (&S1AP_PAGING_IND(message_p).plmn_identity[0], 0, sizeof(plmn_identity_t)*256);
|
||||
memset (&S1AP_PAGING_IND(message_p).tac[0], 0, sizeof(int16_t)*256);
|
||||
S1AP_PAGING_IND(message_p).tai_size = 0;
|
||||
|
||||
for (int i = 0; i < paging_p->taiList.s1ap_TAIItem.count; i++) {
|
||||
S1AP_INFO("[SCTP %d] Received Paging taiList: i %d, count %d\n", assoc_id, i, paging_p->taiList.s1ap_TAIItem.count);
|
||||
S1ap_TAIItem_t s1ap_TAIItem;
|
||||
memset (&s1ap_TAIItem, 0, sizeof(S1ap_TAIItem_t));
|
||||
|
||||
memcpy(&s1ap_TAIItem, paging_p->taiList.s1ap_TAIItem.array[i], sizeof(S1ap_TAIItem_t));
|
||||
|
||||
TBCD_TO_MCC_MNC(&s1ap_TAIItem.tAI.pLMNidentity, S1AP_PAGING_IND(message_p).plmn_identity[i].mcc,
|
||||
S1AP_PAGING_IND(message_p).plmn_identity[i].mnc,
|
||||
S1AP_PAGING_IND(message_p).plmn_identity[i].mnc_digit_length);
|
||||
OCTET_STRING_TO_INT16(&s1ap_TAIItem.tAI.tAC, S1AP_PAGING_IND(message_p).tac[i]);
|
||||
S1AP_PAGING_IND(message_p).tai_size++;
|
||||
S1AP_DEBUG("[SCTP %d] Received Paging: MCC %d, MNC %d, TAC %d\n", assoc_id, S1AP_PAGING_IND(message_p).plmn_identity[i].mcc, S1AP_PAGING_IND(message_p).plmn_identity[i].mnc, S1AP_PAGING_IND(message_p).tac[i]);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// CSG Id(optional) List is not used
|
||||
if (paging_p->presenceMask & S1AP_PAGINGIES_CSG_IDLIST_PRESENT) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
/* convert pagingPriority (optional) if has value */
|
||||
if (paging_p->presenceMask & S1AP_PAGINGIES_PAGINGPRIORITY_PRESENT) {
|
||||
switch(paging_p->pagingPriority) {
|
||||
case S1ap_PagingPriority_priolevel1:
|
||||
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL1;
|
||||
break;
|
||||
case S1ap_PagingPriority_priolevel2:
|
||||
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL2;
|
||||
break;
|
||||
case S1ap_PagingPriority_priolevel3:
|
||||
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL3;
|
||||
break;
|
||||
case S1ap_PagingPriority_priolevel4:
|
||||
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL4;
|
||||
break;
|
||||
case S1ap_PagingPriority_priolevel5:
|
||||
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL5;
|
||||
break;
|
||||
case S1ap_PagingPriority_priolevel6:
|
||||
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL6;
|
||||
break;
|
||||
case S1ap_PagingPriority_priolevel7:
|
||||
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL7;
|
||||
break;
|
||||
case S1ap_PagingPriority_priolevel8:
|
||||
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL8;
|
||||
break;
|
||||
default:
|
||||
/* invalid paging_p->pagingPriority */
|
||||
S1AP_ERROR("[SCTP %d] Received paging : pagingPriority(%ld) is invalid\n", assoc_id, paging_p->pagingPriority);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//paging parameter values
|
||||
S1AP_DEBUG("[SCTP %d] Received Paging parameters: ue_index_value %d cn_domain %d paging_drx %d paging_priority %d\n",assoc_id,
|
||||
S1AP_PAGING_IND(message_p).ue_index_value, S1AP_PAGING_IND(message_p).cn_domain,
|
||||
S1AP_PAGING_IND(message_p).paging_drx, S1AP_PAGING_IND(message_p).paging_priority);
|
||||
S1AP_DEBUG("[SCTP %d] Received Paging parameters(ue): presenceMask %d s_tmsi.m_tmsi %d s_tmsi.mme_code %d IMSI length %d (0-5) %d%d%d%d%d%d\n",assoc_id,
|
||||
S1AP_PAGING_IND(message_p).ue_paging_identity.presenceMask, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi,
|
||||
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length,
|
||||
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[0], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[1],
|
||||
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[3],
|
||||
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[4], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[5]);
|
||||
|
||||
/* send message to RRC */
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, s1ap_eNB_instance->instance, message_p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
struct s1ap_message_s *s1ap_message_p) {
|
||||
|
||||
int i;
|
||||
|
||||
s1ap_eNB_mme_data_t *mme_desc_p = NULL;
|
||||
s1ap_eNB_ue_context_t *ue_desc_p = NULL;
|
||||
MessageDef *message_p = NULL;
|
||||
int nb_of_e_rabs_failed = 0;
|
||||
|
||||
S1ap_E_RABModifyRequestIEs_t *s1ap_E_RABModifyRequest;
|
||||
DevAssert(s1ap_message_p != NULL);
|
||||
|
||||
s1ap_E_RABModifyRequest = &s1ap_message_p->msg.s1ap_E_RABModifyRequestIEs;
|
||||
|
||||
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
|
||||
S1AP_ERROR("[SCTP %d] Received E-RAB modify request for non "
|
||||
"existing MME context\n", assoc_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance,
|
||||
s1ap_E_RABModifyRequest->eNB_UE_S1AP_ID)) == NULL) {
|
||||
S1AP_ERROR("[SCTP %d] Received E-RAB modify request for non "
|
||||
"existing UE context 0x%06lx\n", assoc_id,
|
||||
s1ap_E_RABModifyRequest->eNB_UE_S1AP_ID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* E-RAB modify request = UE-related procedure -> stream != 0 */
|
||||
if (stream == 0) {
|
||||
S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
|
||||
assoc_id, stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ue_desc_p->rx_stream = stream;
|
||||
|
||||
if ( ue_desc_p->mme_ue_s1ap_id != s1ap_E_RABModifyRequest->mme_ue_s1ap_id){
|
||||
S1AP_WARN("UE context mme_ue_s1ap_id is different form that of the message (%d != %ld)",
|
||||
ue_desc_p->mme_ue_s1ap_id, s1ap_E_RABModifyRequest->mme_ue_s1ap_id);
|
||||
message_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP);
|
||||
|
||||
S1AP_E_RAB_MODIFY_RESP (message_p).eNB_ue_s1ap_id = s1ap_E_RABModifyRequest->eNB_UE_S1AP_ID;
|
||||
// S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs[S1AP_MAX_E_RAB];
|
||||
S1AP_E_RAB_MODIFY_RESP (message_p).nb_of_e_rabs = 0;
|
||||
|
||||
for(nb_of_e_rabs_failed = 0; nb_of_e_rabs_failed < s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.count; nb_of_e_rabs_failed++) {
|
||||
S1AP_E_RAB_MODIFY_RESP (message_p).e_rabs_failed[nb_of_e_rabs_failed].e_rab_id =
|
||||
((S1ap_E_RABToBeModifiedItemBearerModReq_t *)s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.array[nb_of_e_rabs_failed])->e_RAB_ID;
|
||||
S1AP_E_RAB_MODIFY_RESP (message_p).e_rabs_failed[nb_of_e_rabs_failed].cause = S1AP_CAUSE_RADIO_NETWORK;
|
||||
S1AP_E_RAB_MODIFY_RESP (message_p).e_rabs_failed[nb_of_e_rabs_failed].cause_value = 13;//S1ap_CauseRadioNetwork_unknown_mme_ue_s1ap_id;
|
||||
}
|
||||
S1AP_E_RAB_MODIFY_RESP (message_p).nb_of_e_rabs_failed = nb_of_e_rabs_failed;
|
||||
|
||||
s1ap_eNB_e_rab_modify_resp(mme_desc_p->s1ap_eNB_instance->instance,
|
||||
&S1AP_E_RAB_MODIFY_RESP(message_p));
|
||||
|
||||
message_p = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_MODIFY_REQ);
|
||||
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id;
|
||||
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).mme_ue_s1ap_id = s1ap_E_RABModifyRequest->mme_ue_s1ap_id;
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).eNB_ue_s1ap_id = s1ap_E_RABModifyRequest->eNB_UE_S1AP_ID;
|
||||
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).nb_e_rabs_tomodify =
|
||||
s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.count;
|
||||
|
||||
for (i = 0; i < s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.count; i++) {
|
||||
S1ap_E_RABToBeModifiedItemBearerModReq_t *item_p;
|
||||
|
||||
item_p = (S1ap_E_RABToBeModifiedItemBearerModReq_t *)s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.array[i];
|
||||
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].e_rab_id = item_p->e_RAB_ID;
|
||||
|
||||
// check for the NAS PDU
|
||||
if (item_p->nAS_PDU.size > 0 ) {
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.length = item_p->nAS_PDU.size;
|
||||
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU.size);
|
||||
|
||||
memcpy(S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer,
|
||||
item_p->nAS_PDU.buf, item_p->nAS_PDU.size);
|
||||
} else {
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.length = 0;
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Set the QOS informations */
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.qci = item_p->e_RABLevelQoSParameters.qCI;
|
||||
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.priority_level =
|
||||
item_p->e_RABLevelQoSParameters.allocationRetentionPriority.priorityLevel;
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.pre_emp_capability =
|
||||
item_p->e_RABLevelQoSParameters.allocationRetentionPriority.pre_emptionCapability;
|
||||
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.pre_emp_vulnerability =
|
||||
item_p->e_RABLevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability;
|
||||
|
||||
}
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
// handle e-rab release command and send it to rrc_end
|
||||
static
|
||||
int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
struct s1ap_message_s *s1ap_message_p) {
|
||||
|
||||
int i;
|
||||
|
||||
s1ap_eNB_mme_data_t *mme_desc_p = NULL;
|
||||
s1ap_eNB_ue_context_t *ue_desc_p = NULL;
|
||||
MessageDef *message_p = NULL;
|
||||
|
||||
S1ap_E_RABReleaseCommandIEs_t *s1ap_E_RABReleaseCommand;
|
||||
DevAssert(s1ap_message_p != NULL);
|
||||
s1ap_E_RABReleaseCommand = &s1ap_message_p->msg.s1ap_E_RABReleaseCommandIEs;
|
||||
|
||||
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
|
||||
S1AP_ERROR("[SCTP %d] Received E-RAB release command for non existing MME context\n", assoc_id);
|
||||
return -1;
|
||||
}
|
||||
if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance,
|
||||
s1ap_E_RABReleaseCommand->eNB_UE_S1AP_ID)) == NULL) {
|
||||
S1AP_ERROR("[SCTP %d] Received E-RAB release command for non existing UE context 0x%06lx\n", assoc_id,
|
||||
s1ap_E_RABReleaseCommand->eNB_UE_S1AP_ID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Initial context request = UE-related procedure -> stream != 0 */
|
||||
if (stream == 0) {
|
||||
S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
|
||||
assoc_id, stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ue_desc_p->rx_stream = stream;
|
||||
|
||||
if ( ue_desc_p->mme_ue_s1ap_id != s1ap_E_RABReleaseCommand->mme_ue_s1ap_id){
|
||||
S1AP_WARN("UE context mme_ue_s1ap_id is different form that of the message (%d != %ld)",
|
||||
ue_desc_p->mme_ue_s1ap_id, s1ap_E_RABReleaseCommand->mme_ue_s1ap_id);
|
||||
}
|
||||
|
||||
S1AP_DEBUG("[SCTP %d] Received E-RAB release command for eNB_UE_S1AP_ID %ld mme_ue_s1ap_id %ld\n",
|
||||
assoc_id, s1ap_E_RABReleaseCommand->eNB_UE_S1AP_ID, s1ap_E_RABReleaseCommand->mme_ue_s1ap_id);
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_RELEASE_COMMAND);
|
||||
|
||||
S1AP_E_RAB_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = s1ap_E_RABReleaseCommand->eNB_UE_S1AP_ID;
|
||||
S1AP_E_RAB_RELEASE_COMMAND(message_p).mme_ue_s1ap_id = s1ap_E_RABReleaseCommand->mme_ue_s1ap_id;
|
||||
if(s1ap_E_RABReleaseCommand->nas_pdu.size > 0 ){
|
||||
S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.length = s1ap_E_RABReleaseCommand->nas_pdu.size;
|
||||
|
||||
S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer =
|
||||
malloc(sizeof(uint8_t) * s1ap_E_RABReleaseCommand->nas_pdu.size);
|
||||
|
||||
memcpy(S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer,
|
||||
s1ap_E_RABReleaseCommand->nas_pdu.buf,
|
||||
s1ap_E_RABReleaseCommand->nas_pdu.size);
|
||||
} else {
|
||||
S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.length = 0;
|
||||
S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer = NULL;
|
||||
}
|
||||
|
||||
S1AP_E_RAB_RELEASE_COMMAND(message_p).nb_e_rabs_torelease = s1ap_E_RABReleaseCommand->e_RABToBeReleasedList.s1ap_E_RABItem.count;
|
||||
for(i=0; i < s1ap_E_RABReleaseCommand->e_RABToBeReleasedList.s1ap_E_RABItem.count; i++){
|
||||
S1ap_E_RABItem_t *item_p;
|
||||
item_p = (S1ap_E_RABItem_t*)s1ap_E_RABReleaseCommand->e_RABToBeReleasedList.s1ap_E_RABItem.array[i];
|
||||
S1AP_E_RAB_RELEASE_COMMAND(message_p).e_rab_release_params[i].e_rab_id = item_p->e_RAB_ID;
|
||||
S1AP_DEBUG("[SCTP] Received E-RAB release command for e-rab id %ld\n", item_p->e_RAB_ID);
|
||||
}
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -837,3 +837,282 @@ int s1ap_eNB_e_rab_setup_resp(instance_t instance,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int s1ap_eNB_e_rab_modify_resp(instance_t instance,
|
||||
s1ap_e_rab_modify_resp_t *e_rab_modify_resp_p)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL;
|
||||
struct s1ap_eNB_ue_context_s *ue_context_p = NULL;
|
||||
|
||||
S1ap_E_RABModifyResponseIEs_t *initial_ies_p = NULL;
|
||||
|
||||
s1ap_message message;
|
||||
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t length;
|
||||
int ret = -1;
|
||||
int i;
|
||||
|
||||
/* Retrieve the S1AP eNB instance associated with Mod_id */
|
||||
s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance);
|
||||
|
||||
DevAssert(e_rab_modify_resp_p != NULL);
|
||||
DevAssert(s1ap_eNB_instance_p != NULL);
|
||||
|
||||
if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
|
||||
e_rab_modify_resp_p->eNB_ue_s1ap_id)) == NULL) {
|
||||
/* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
|
||||
S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n",
|
||||
e_rab_modify_resp_p->eNB_ue_s1ap_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Uplink NAS transport can occur either during an s1ap connected state
|
||||
* or during initial attach (for example: NAS authentication).
|
||||
*/
|
||||
if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED ||
|
||||
ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) {
|
||||
S1AP_WARN("You are attempting to send NAS data over non-connected "
|
||||
"eNB ue s1ap id: %06x, current state: %d\n",
|
||||
e_rab_modify_resp_p->eNB_ue_s1ap_id, ue_context_p->ue_state);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Prepare the S1AP message to encode */
|
||||
memset(&message, 0, sizeof(s1ap_message));
|
||||
|
||||
message.direction = S1AP_PDU_PR_successfulOutcome;
|
||||
message.procedureCode = S1ap_ProcedureCode_id_E_RABModify;
|
||||
message.criticality = S1ap_Criticality_reject;
|
||||
|
||||
initial_ies_p = &message.msg.s1ap_E_RABModifyResponseIEs;
|
||||
|
||||
initial_ies_p->eNB_UE_S1AP_ID = e_rab_modify_resp_p->eNB_ue_s1ap_id;
|
||||
initial_ies_p->mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id;
|
||||
|
||||
if ( e_rab_modify_resp_p->nb_of_e_rabs >= 1 )
|
||||
initial_ies_p->presenceMask |= S1AP_E_RABMODIFYRESPONSEIES_E_RABMODIFYLISTBEARERMODRES_PRESENT;
|
||||
|
||||
for (i = 0; i < e_rab_modify_resp_p->nb_of_e_rabs; i++) {
|
||||
S1ap_E_RABModifyItemBearerModRes_t *modify_item;
|
||||
|
||||
modify_item = calloc(1, sizeof(S1ap_E_RABModifyItemBearerModRes_t));
|
||||
|
||||
modify_item->e_RAB_ID = e_rab_modify_resp_p->e_rabs[i].e_rab_id;
|
||||
|
||||
S1AP_DEBUG("e_rab_modify_resp: modified e_rab ID %ld\n",
|
||||
modify_item->e_RAB_ID);
|
||||
|
||||
S1ap_IE_t *ie = s1ap_new_ie(S1ap_ProtocolIE_ID_id_E_RABModifyItemBearerModRes,
|
||||
S1ap_Criticality_ignore,
|
||||
&asn_DEF_S1ap_E_RABModifyItemBearerModRes,
|
||||
modify_item);
|
||||
|
||||
ASN_SEQUENCE_ADD(&initial_ies_p->e_RABModifyListBearerModRes.s1ap_E_RABModifyItemBearerModRes,
|
||||
ie);
|
||||
}
|
||||
|
||||
if ( e_rab_modify_resp_p->nb_of_e_rabs_failed >= 1 )
|
||||
initial_ies_p->presenceMask |= S1AP_E_RABMODIFYRESPONSEIES_E_RABFAILEDTOMODIFYLIST_PRESENT;
|
||||
|
||||
for (i = 0; i < e_rab_modify_resp_p->nb_of_e_rabs_failed; i++) {
|
||||
S1ap_E_RABItem_t *failed_item;
|
||||
|
||||
failed_item = calloc(1, sizeof(S1ap_E_RABItem_t));
|
||||
|
||||
failed_item->e_RAB_ID = e_rab_modify_resp_p->e_rabs_failed[i].e_rab_id;
|
||||
switch(e_rab_modify_resp_p->e_rabs_failed[i].cause)
|
||||
{
|
||||
case S1AP_CAUSE_RADIO_NETWORK:
|
||||
failed_item->cause.present = S1ap_Cause_PR_radioNetwork;
|
||||
failed_item->cause.choice.radioNetwork = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
|
||||
break;
|
||||
case S1AP_CAUSE_TRANSPORT:
|
||||
failed_item->cause.present = S1ap_Cause_PR_transport;
|
||||
failed_item->cause.choice.transport = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
|
||||
break;
|
||||
case S1AP_CAUSE_NAS:
|
||||
failed_item->cause.present = S1ap_Cause_PR_nas;
|
||||
failed_item->cause.choice.nas = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
|
||||
break;
|
||||
case S1AP_CAUSE_PROTOCOL:
|
||||
failed_item->cause.present = S1ap_Cause_PR_protocol;
|
||||
failed_item->cause.choice.protocol = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
|
||||
break;
|
||||
case S1AP_CAUSE_MISC:
|
||||
failed_item->cause.present = S1ap_Cause_PR_misc;
|
||||
failed_item->cause.choice.misc = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
S1AP_DEBUG("e_rab_modify_resp: failed e_rab ID %ld\n",
|
||||
failed_item->e_RAB_ID);
|
||||
|
||||
S1ap_IE_t *ie = s1ap_new_ie(S1ap_ProtocolIE_ID_id_E_RABItem,
|
||||
S1ap_Criticality_ignore,
|
||||
&asn_DEF_S1ap_E_RABItem,
|
||||
failed_item);
|
||||
|
||||
ASN_SEQUENCE_ADD(&initial_ies_p->e_RABFailedToModifyList.s1ap_E_RABItem,
|
||||
ie);
|
||||
}
|
||||
|
||||
fprintf(stderr, "start encode\n");
|
||||
if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) {
|
||||
S1AP_ERROR("Failed to encode uplink transport\n");
|
||||
/* Encode procedure has failed... */
|
||||
return -1;
|
||||
}
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_S1AP_ENB,
|
||||
MSC_S1AP_MME,
|
||||
(const char *)buffer,
|
||||
length,
|
||||
MSC_AS_TIME_FMT" E_RAN Modify successful Outcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u",
|
||||
0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
|
||||
initial_ies_p->eNB_UE_S1AP_ID,
|
||||
initial_ies_p->mme_ue_s1ap_id);
|
||||
|
||||
/* UE associated signalling -> use the allocated stream */
|
||||
s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance,
|
||||
ue_context_p->mme_ref->assoc_id, buffer,
|
||||
length, ue_context_p->tx_stream);
|
||||
|
||||
return ret;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
int s1ap_eNB_e_rab_release_resp(instance_t instance,
|
||||
s1ap_e_rab_release_resp_t *e_rab_release_resp_p)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL;
|
||||
struct s1ap_eNB_ue_context_s *ue_context_p = NULL;
|
||||
|
||||
S1ap_E_RABReleaseResponseIEs_t *release_response_ies_p = NULL;
|
||||
|
||||
s1ap_message message;
|
||||
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t length;
|
||||
int ret = -1;
|
||||
int i;
|
||||
/* Retrieve the S1AP eNB instance associated with Mod_id */
|
||||
s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance);
|
||||
DevAssert(e_rab_release_resp_p != NULL);
|
||||
DevAssert(s1ap_eNB_instance_p != NULL);
|
||||
|
||||
/* Prepare the S1AP message to encode */
|
||||
memset(&message, 0, sizeof(s1ap_message));
|
||||
|
||||
message.direction = S1AP_PDU_PR_successfulOutcome;
|
||||
message.procedureCode = S1ap_ProcedureCode_id_E_RABRelease;
|
||||
message.criticality = S1ap_Criticality_ignore;
|
||||
|
||||
if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
|
||||
e_rab_release_resp_p->eNB_ue_s1ap_id)) == NULL) {
|
||||
/* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
|
||||
S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %u\n",
|
||||
e_rab_release_resp_p->eNB_ue_s1ap_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
release_response_ies_p = &message.msg.s1ap_E_RABReleaseResponseIEs;
|
||||
release_response_ies_p->eNB_UE_S1AP_ID = e_rab_release_resp_p->eNB_ue_s1ap_id;
|
||||
release_response_ies_p->mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id;
|
||||
|
||||
if ( e_rab_release_resp_p->nb_of_e_rabs_released > 0 )
|
||||
release_response_ies_p->presenceMask |= S1AP_E_RABRELEASERESPONSEIES_E_RABRELEASELISTBEARERRELCOMP_PRESENT;
|
||||
|
||||
//release
|
||||
for (i = 0; i < e_rab_release_resp_p->nb_of_e_rabs_released; i++) {
|
||||
|
||||
S1ap_E_RABReleaseItemBearerRelComp_t *new_item;
|
||||
|
||||
new_item = calloc(1, sizeof(S1ap_E_RABReleaseItemBearerRelComp_t));
|
||||
|
||||
new_item->e_RAB_ID = e_rab_release_resp_p->e_rab_release[i].e_rab_id;
|
||||
|
||||
S1AP_DEBUG("e_rab_release_resp: e_rab ID %ld\n",new_item->e_RAB_ID);
|
||||
|
||||
ASN_SEQUENCE_ADD(&release_response_ies_p->e_RABReleaseListBearerRelComp.s1ap_E_RABReleaseItemBearerRelComp,
|
||||
new_item);
|
||||
|
||||
}
|
||||
|
||||
if ( e_rab_release_resp_p->nb_of_e_rabs_failed > 0 )
|
||||
release_response_ies_p->presenceMask |= S1AP_E_RABRELEASERESPONSEIES_E_RABFAILEDTORELEASELIST_PRESENT;
|
||||
|
||||
//release failed
|
||||
for (i = 0; i < e_rab_release_resp_p->nb_of_e_rabs_failed; i++) {
|
||||
S1ap_E_RABItem_t *new_rabitem;
|
||||
new_rabitem = calloc(1, sizeof(S1ap_E_RABItem_t));
|
||||
//e_rab_id
|
||||
new_rabitem->e_RAB_ID = e_rab_release_resp_p->e_rabs_failed[i].e_rab_id;
|
||||
//cause
|
||||
switch(e_rab_release_resp_p->e_rabs_failed[i].cause)
|
||||
{
|
||||
case S1AP_CAUSE_NOTHING:
|
||||
new_rabitem->cause.present = S1ap_Cause_PR_NOTHING;
|
||||
break;
|
||||
|
||||
case S1AP_CAUSE_RADIO_NETWORK:
|
||||
new_rabitem->cause.present = S1ap_Cause_PR_radioNetwork;
|
||||
new_rabitem->cause.choice.radioNetwork = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
|
||||
break;
|
||||
|
||||
case S1AP_CAUSE_TRANSPORT:
|
||||
new_rabitem->cause.present = S1ap_Cause_PR_transport;
|
||||
new_rabitem->cause.choice.transport = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
|
||||
break;
|
||||
|
||||
case S1AP_CAUSE_NAS:
|
||||
new_rabitem->cause.present = S1ap_Cause_PR_nas;
|
||||
new_rabitem->cause.choice.nas = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
|
||||
break;
|
||||
|
||||
case S1AP_CAUSE_PROTOCOL:
|
||||
new_rabitem->cause.present = S1ap_Cause_PR_protocol;
|
||||
new_rabitem->cause.choice.protocol = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
|
||||
break;
|
||||
|
||||
case S1AP_CAUSE_MISC:
|
||||
default:
|
||||
new_rabitem->cause.present = S1ap_Cause_PR_misc;
|
||||
new_rabitem->cause.choice.misc = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
|
||||
break;
|
||||
}
|
||||
S1AP_DEBUG("e_rab_release_resp: failed e_rab ID %ld\n",new_rabitem->e_RAB_ID);
|
||||
ASN_SEQUENCE_ADD(&release_response_ies_p->e_RABFailedToReleaseList.s1ap_E_RABItem, new_rabitem);
|
||||
}
|
||||
|
||||
fprintf(stderr, "start encode\n");
|
||||
if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) {
|
||||
S1AP_ERROR("Failed to encode release response\n");
|
||||
/* Encode procedure has failed... */
|
||||
return -1;
|
||||
}
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_S1AP_ENB,
|
||||
MSC_S1AP_MME,
|
||||
(const char *)buffer,
|
||||
length,
|
||||
MSC_AS_TIME_FMT" E_RAN Release successfulOutcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u",
|
||||
0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
|
||||
e_rab_release_resp_p->eNB_ue_s1ap_id,
|
||||
ue_context_p->mme_ue_s1ap_id);
|
||||
|
||||
/* UE associated signalling -> use the allocated stream */
|
||||
s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance,
|
||||
ue_context_p->mme_ref->assoc_id, buffer,
|
||||
length, ue_context_p->tx_stream);
|
||||
|
||||
S1AP_INFO("e_rab_release_response sended eNB_UE_S1AP_ID %d mme_ue_s1ap_id %d nb_of_e_rabs_released %d nb_of_e_rabs_failed %d\n",
|
||||
e_rab_release_resp_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id,e_rab_release_resp_p->nb_of_e_rabs_released,e_rab_release_resp_p->nb_of_e_rabs_failed);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -44,4 +44,9 @@ int s1ap_eNB_ue_capabilities(instance_t instance,
|
||||
int s1ap_eNB_e_rab_setup_resp(instance_t instance,
|
||||
s1ap_e_rab_setup_resp_t *e_rab_setup_resp_p);
|
||||
|
||||
int s1ap_eNB_e_rab_modify_resp(instance_t instance,
|
||||
s1ap_e_rab_modify_resp_t *e_rab_modify_resp_p);
|
||||
|
||||
int s1ap_eNB_e_rab_release_resp(instance_t instance,
|
||||
s1ap_e_rab_release_resp_t *e_rab_release_resp_p);
|
||||
#endif /* S1AP_ENB_NAS_PROCEDURES_H_ */
|
||||
|
||||
@@ -63,3 +63,43 @@ int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB
|
||||
}
|
||||
#endif
|
||||
|
||||
int derive_keNB_star(
|
||||
const uint8_t *kenb_32,
|
||||
const uint16_t pci,
|
||||
const uint32_t earfcn_dl,
|
||||
const bool is_rel8_only,
|
||||
uint8_t *kenb_star)
|
||||
{
|
||||
// see 33.401 section A.5 KeNB* derivation function
|
||||
uint8_t s[10] = {0};
|
||||
|
||||
// FC = 0x13
|
||||
s[0] = FC_KENB_STAR;
|
||||
// P0 = PCI (target physical cell id)
|
||||
s[1] = (pci & 0x0000ff00) >> 8;
|
||||
s[2] = (pci & 0x000000ff);
|
||||
// L0 = length of PCI (i.e. 0x00 0x02)
|
||||
s[3] = 0x00;
|
||||
s[4] = 0x02;
|
||||
// P1 = EARFCN-DL (target physical cell downlink frequency)
|
||||
if (is_rel8_only) {
|
||||
s[5] = (earfcn_dl & 0x0000ff00) >> 8;
|
||||
s[6] = (earfcn_dl & 0x000000ff);
|
||||
s[7] = 0x00;
|
||||
s[8] = 0x02;
|
||||
kdf (kenb_32, 32, s, 9, kenb_star, 32);
|
||||
} else {
|
||||
s[5] = (earfcn_dl & 0x00ff0000) >> 16;
|
||||
s[6] = (earfcn_dl & 0x0000ff00) >> 8;
|
||||
s[7] = (earfcn_dl & 0x000000ff);
|
||||
s[8] = 0x00;
|
||||
s[9] = 0x03;
|
||||
kdf (kenb_32, 32, s, 10, kenb_star, 32);
|
||||
}
|
||||
// L1 length of EARFCN-DL (i.e. L1 = 0x00 0x02 if EARFCN-DL is between 0 and 65535, and L1 = 0x00 0x03 if EARFCN-DL is between 65536 and 262143)
|
||||
// NOTE: The length of EARFCN-DL cannot be generally set to 3 bytes for backward compatibility reasons: A Rel-8
|
||||
// entity (UE or eNB) would always assume an input parameter length of 2 bytes for the EARFCN-DL. This
|
||||
// would lead to different derived keys if another entity assumed an input parameter length of 3 bytes for the
|
||||
// EARFCN-DL.
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#define SECU_DEFS_H_
|
||||
|
||||
#include "security_types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#define EIA0_ALG_ID 0x00
|
||||
#define EIA1_128_ALG_ID 0x01
|
||||
@@ -44,6 +45,9 @@ void kdf(const uint8_t *key,
|
||||
|
||||
int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB);
|
||||
|
||||
int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl,
|
||||
const bool is_rel8_only, uint8_t * kenb_star);
|
||||
|
||||
int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
|
||||
const uint8_t kasme[32], uint8_t *knas);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user