Additional RRC procedures (RRCConnectionReconfiguration) for dedicated bearer estatblishment triggered by S1AP messages.
eNB mac scheduler for dedicated DTCH. UE MAC logical channel prioritization with additional DTCH. S1AP messages for dedicated bearer establishment (eNB and UE).
This commit is contained in:
@@ -328,6 +328,12 @@ void *s1ap_eNB_task(void *arg)
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_E_RAB_SETUP_RESP: {
|
||||
s1ap_eNB_e_rab_setup_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&S1AP_E_RAB_SETUP_RESP(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_NAS_NON_DELIVERY_IND: {
|
||||
s1ap_eNB_nas_non_delivery_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&S1AP_NAS_NON_DELIVERY_IND(received_msg));
|
||||
|
||||
@@ -120,6 +120,14 @@ static int s1ap_eNB_decode_initiating_message(s1ap_message *message,
|
||||
break;
|
||||
|
||||
|
||||
case S1ap_ProcedureCode_id_E_RABSetup:
|
||||
ret = s1ap_decode_s1ap_e_rabsetuprequesties(
|
||||
&message->msg.s1ap_E_RABSetupRequestIEs, &initiating_p->value);
|
||||
s1ap_xer_print_s1ap_paging(s1ap_xer__print2sp, message_string, message);
|
||||
//message_id = S1AP_E_RABSETUP_REQ_LOG;
|
||||
S1AP_ERROR("TODO E_RABSetup initiating message\n");
|
||||
free(message_string);
|
||||
break;
|
||||
default:
|
||||
S1AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
|
||||
(int)initiating_p->procedureCode);
|
||||
|
||||
@@ -82,6 +82,13 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
struct s1ap_message_s *s1ap_message_p);
|
||||
|
||||
|
||||
static
|
||||
int s1ap_eNB_handle_e_rab_setup_request(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] = {
|
||||
{ 0, 0, 0 }, /* HandoverPreparation */
|
||||
@@ -89,7 +96,7 @@ s1ap_message_decoded_callback messages_callback[][3] = {
|
||||
{ 0, 0, 0 }, /* HandoverNotification */
|
||||
{ 0, 0, 0 }, /* PathSwitchRequest */
|
||||
{ 0, 0, 0 }, /* HandoverCancel */
|
||||
{ 0, 0, 0 }, /* E_RABSetup */
|
||||
{ s1ap_eNB_handle_e_rab_setup_request, 0, 0 }, /* E_RABSetup */
|
||||
{ 0, 0, 0 }, /* E_RABModify */
|
||||
{ 0, 0, 0 }, /* E_RABRelease */
|
||||
{ 0, 0, 0 }, /* E_RABReleaseIndication */
|
||||
@@ -872,3 +879,107 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int s1ap_eNB_handle_e_rab_setup_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;
|
||||
|
||||
S1ap_E_RABSetupRequestIEs_t *s1ap_E_RABSetupRequest;
|
||||
DevAssert(s1ap_message_p != NULL);
|
||||
|
||||
s1ap_E_RABSetupRequest = &s1ap_message_p->msg.s1ap_E_RABSetupRequestIEs;
|
||||
|
||||
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
|
||||
S1AP_ERROR("[SCTP %d] Received initial context setup 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_RABSetupRequest->eNB_UE_S1AP_ID)) == NULL) {
|
||||
S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
|
||||
"existing UE context 0x%06x\n", assoc_id,
|
||||
s1ap_E_RABSetupRequest->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_RABSetupRequest->mme_ue_s1ap_id){
|
||||
S1AP_WARN("UE context mme_ue_s1ap_id is different form that of the message (%d != %d)",
|
||||
ue_desc_p->mme_ue_s1ap_id, s1ap_E_RABSetupRequest->mme_ue_s1ap_id);
|
||||
|
||||
}
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_SETUP_REQ);
|
||||
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id;
|
||||
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).mme_ue_s1ap_id = s1ap_E_RABSetupRequest->mme_ue_s1ap_id;
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).eNB_ue_s1ap_id = s1ap_E_RABSetupRequest->eNB_UE_S1AP_ID;
|
||||
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).nb_e_rabs_tosetup =
|
||||
s1ap_E_RABSetupRequest->e_RABToBeSetupListBearerSUReq.s1ap_E_RABToBeSetupItemBearerSUReq.count;
|
||||
|
||||
for (i = 0; i < s1ap_E_RABSetupRequest->e_RABToBeSetupListBearerSUReq.s1ap_E_RABToBeSetupItemBearerSUReq.count; i++) {
|
||||
S1ap_E_RABToBeSetupItemBearerSUReq_t *item_p;
|
||||
|
||||
item_p = (S1ap_E_RABToBeSetupItemBearerSUReq_t *)s1ap_E_RABSetupRequest->e_RABToBeSetupListBearerSUReq.s1ap_E_RABToBeSetupItemBearerSUReq.array[i];
|
||||
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_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_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.length = item_p->nAS_PDU.size;
|
||||
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU.size);
|
||||
|
||||
memcpy(S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer,
|
||||
item_p->nAS_PDU.buf, item_p->nAS_PDU.size);
|
||||
} else {
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.length = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
/* Set the transport layer address */
|
||||
memcpy(S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.buffer,
|
||||
item_p->transportLayerAddress.buf, item_p->transportLayerAddress.size);
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.length =
|
||||
item_p->transportLayerAddress.size * 8 - item_p->transportLayerAddress.bits_unused;
|
||||
|
||||
/* GTP tunnel endpoint ID */
|
||||
OCTET_STRING_TO_INT32(&item_p->gTP_TEID, S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].gtp_teid);
|
||||
|
||||
/* Set the QOS informations */
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.qci = item_p->e_RABlevelQoSParameters.qCI;
|
||||
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.allocation_retention_priority.priority_level =
|
||||
item_p->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel;
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.allocation_retention_priority.pre_emp_capability =
|
||||
item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionCapability;
|
||||
S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -686,3 +686,94 @@ int s1ap_eNB_ue_capabilities(instance_t instance,
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int s1ap_eNB_e_rab_setup_resp(instance_t instance,
|
||||
s1ap_e_rab_setup_resp_t *e_rab_setup_resp_p)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL;
|
||||
struct s1ap_eNB_ue_context_s *ue_context_p = NULL;
|
||||
|
||||
S1ap_E_RABSetupResponseIEs_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_setup_resp_p != NULL);
|
||||
DevAssert(s1ap_eNB_instance_p != NULL);
|
||||
|
||||
if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
|
||||
e_rab_setup_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_setup_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_setup_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_RABSetup;
|
||||
|
||||
initial_ies_p = &message.msg.s1ap_E_RABSetupResponseIEs;
|
||||
|
||||
initial_ies_p->eNB_UE_S1AP_ID = e_rab_setup_resp_p->eNB_ue_s1ap_id;
|
||||
initial_ies_p->mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id;
|
||||
|
||||
for (i = 0; i < e_rab_setup_resp_p->nb_of_e_rabs; i++) {
|
||||
S1ap_E_RABSetupItemBearerSURes_t *new_item;
|
||||
|
||||
new_item = calloc(1, sizeof(S1ap_E_RABSetupItemBearerSURes_t));
|
||||
|
||||
new_item->e_RAB_ID = e_rab_setup_resp_p->e_rabs[i].e_rab_id;
|
||||
GTP_TEID_TO_ASN1(e_rab_setup_resp_p->e_rabs[i].gtp_teid, &new_item->gTP_TEID);
|
||||
new_item->transportLayerAddress.buf = e_rab_setup_resp_p->e_rabs[i].eNB_addr.buffer;
|
||||
new_item->transportLayerAddress.size = e_rab_setup_resp_p->e_rabs[i].eNB_addr.length;
|
||||
new_item->transportLayerAddress.bits_unused = 0;
|
||||
|
||||
ASN_SEQUENCE_ADD(&initial_ies_p->e_RABSetupListBearerSURes.s1ap_E_RABSetupItemBearerSURes,
|
||||
new_item);
|
||||
}
|
||||
|
||||
if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) {
|
||||
S1AP_ERROR("Failed to encode uplink NAS 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 Setup successfulOutcome 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user