Commit 3a1252a8 authored by masayuki.harada's avatar masayuki.harada

Add PDCP reestablishment and RLC reestablishment.

parent a72e6ed6
......@@ -1459,6 +1459,272 @@ pdcp_remove_UE(
return 1;
}
//-----------------------------------------------------------------------------
boolean_t rrc_pdcp_reestablishment_asn1_req (
const protocol_ctxt_t *const ctxt_pP,
const rnti_t previous_rnti,
LTE_SRB_ToAddModList_t *const srb2add_list_pP,
LTE_DRB_ToAddModList_t *const drb2add_list_pP
)
//-----------------------------------------------------------------------------
{
long int lc_id = 0;
LTE_DRB_Identity_t srb_id = 0;
long int mch_id = 0;
rlc_mode_t rlc_type = RLC_MODE_NONE;
LTE_DRB_Identity_t drb_id = 0;
uint8_t drb_sn = 12;
uint8_t srb_sn = 5; // fixed sn for SRBs
uint8_t drb_report = 0;
long int cnt = 0;
uint16_t header_compression_profile = 0;
config_action_t action = CONFIG_ACTION_ADD;
LTE_SRB_ToAddMod_t *srb_toaddmod_p = NULL;
LTE_DRB_ToAddMod_t *drb_toaddmod_p = NULL;
pdcp_t *pdcp_p = NULL;
pdcp_t *pdcp_p_old = NULL;
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
hash_key_t old_key = HASHTABLE_NOT_A_KEY_VALUE;
hashtable_rc_t h_rc;
if (srb2add_list_pP != NULL) {
for (cnt=0; cnt<srb2add_list_pP->list.count; cnt++) {
srb_toaddmod_p = srb2add_list_pP->list.array[cnt];
srb_id = srb_toaddmod_p->srb_Identity;
rlc_type = RLC_MODE_AM;
lc_id = srb_id;
old_key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, previous_rnti, ctxt_pP->enb_flag, srb_id, SRB_FLAG_YES);
h_rc = hashtable_get(pdcp_coll_p, old_key, (void **)&pdcp_p_old);
key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, srb_id, SRB_FLAG_YES);
h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
if (h_rc == HASH_TABLE_OK) {
LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" ignore exist SRB %ld key 0x%"PRIx64"\n",
PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p),
srb_id,
key);
continue;
}
rlc_type = RLC_MODE_AM;
lc_id = srb_id;
action = CONFIG_ACTION_ADD;
pdcp_p = calloc(1, sizeof(pdcp_t));
h_rc = hashtable_insert(pdcp_coll_p, key, pdcp_p);
if (h_rc != HASH_TABLE_OK) {
LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD key 0x%"PRIx64" FAILED\n",
PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p),
key);
free(pdcp_p);
return TRUE;
} else {
LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD key 0x%"PRIx64"\n",
PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p),
key);
}
pdcp_config_req_asn1 (
ctxt_pP,
pdcp_p,
SRB_FLAG_YES,
rlc_type,
action,
lc_id,
mch_id,
srb_id,
srb_sn,
0, // drb_report
0, // header compression
0xFF,
NULL,
NULL,
NULL);
if(pdcp_p_old!=NULL) {
// TODO When upper layers request a PDCP re-establishment, the UE shall:
// - set Next_PDCP_TX_SN, and TX_HFN to 0;
// - set Next_PDCP_RX_SN, and RX_HFN to 0;
// - discard all stored PDCP SDUs and PDCP PDUs;
// - apply the ciphering and integrity protection algorithms and keys provided by upper layers during the re-establishment procedure.
// Discard all data and sn clear, so create as new bearer
}
}
}
// reset the action
if (drb2add_list_pP != NULL) {
for (cnt=0; cnt<drb2add_list_pP->list.count; cnt++) {
drb_toaddmod_p = drb2add_list_pP->list.array[cnt];
drb_id = drb_toaddmod_p->drb_Identity;// + drb_id_offset;
if (drb_toaddmod_p->logicalChannelIdentity) {
lc_id = *(drb_toaddmod_p->logicalChannelIdentity);
} else {
LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" logicalChannelIdentity is missing in DRB-ToAddMod information element!\n",
PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p));
continue;
}
if (lc_id == 1 || lc_id == 2) {
LOG_E(RLC, PROTOCOL_CTXT_FMT" logicalChannelIdentity = %ld is invalid in RRC message when adding DRB!\n", PROTOCOL_CTXT_ARGS(ctxt_pP), lc_id);
continue;
}
old_key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, previous_rnti, ctxt_pP->enb_flag, drb_id, SRB_FLAG_NO);
h_rc = hashtable_get(pdcp_coll_p, old_key, (void **)&pdcp_p_old);
DevCheck4(drb_id < LTE_maxDRB, drb_id, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti);
key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, drb_id, SRB_FLAG_NO);
h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
if (h_rc == HASH_TABLE_OK) {
LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" ignore exist DRB %ld key 0x%"PRIx64"\n",
PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p),
drb_id,
key);
continue;
}
if(pdcp_p_old!=NULL) {
// Reestablishment case
// Copy old PDCP data and insert as new hash
pdcp_p = calloc(1, sizeof(pdcp_t));
memcpy(pdcp_p,pdcp_p_old,sizeof(pdcp_t));
h_rc = hashtable_insert(pdcp_coll_p, key, pdcp_p);
if (h_rc != HASH_TABLE_OK) {
LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD key 0x%"PRIx64" FAILED\n",
PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p),
key);
free(pdcp_p);
return TRUE;
} else {
LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD key 0x%"PRIx64"\n",
PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p),
key);
}
pdcp_p->is_ue = FALSE;
pdcp_add_UE(ctxt_pP);
for(int i = 0; i<MAX_MOBILES_PER_ENB; i++) {
if(pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] == NOT_A_RNTI) {
break;
}
pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % MAX_MOBILES_PER_ENB;
}
pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti;
pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % MAX_MOBILES_PER_ENB;
LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" reestablishment DRB %ld key 0x%"PRIx64" old rnti %x old key 0x%"PRIx64"\n",
PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p),
drb_id,key,previous_rnti,old_key);
if (drb_toaddmod_p->pdcp_Config->rlc_AM) {
//??
}
if (drb_toaddmod_p->pdcp_Config->rlc_UM) {
// - set Next_PDCP_RX_SN, and RX_HFN to 0;
// - set Next_PDCP_RX_SN, and RX_HFN to 0;
pdcp_p->next_pdcp_tx_sn = 0;
pdcp_p->next_pdcp_rx_sn = 0;
pdcp_p->tx_hfn = 0;
pdcp_p->rx_hfn = 0;
}
continue;
}
// Add new bearer case
action = CONFIG_ACTION_ADD;
pdcp_p = calloc(1, sizeof(pdcp_t));
h_rc = hashtable_insert(pdcp_coll_p, key, pdcp_p);
if (h_rc != HASH_TABLE_OK) {
LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD ADD key 0x%"PRIx64" FAILED\n",
PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p),
key);
free(pdcp_p);
return TRUE;
} else {
LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD ADD key 0x%"PRIx64"\n",
PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p),
key);
}
if (drb_toaddmod_p->pdcp_Config) {
if (drb_toaddmod_p->pdcp_Config->discardTimer) {
// set the value of the timer
}
if (drb_toaddmod_p->pdcp_Config->rlc_AM) {
drb_report = drb_toaddmod_p->pdcp_Config->rlc_AM->statusReportRequired;
drb_sn = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; // default SN size
rlc_type = RLC_MODE_AM;
}
if (drb_toaddmod_p->pdcp_Config->rlc_UM) {
drb_sn = drb_toaddmod_p->pdcp_Config->rlc_UM->pdcp_SN_Size;
rlc_type =RLC_MODE_UM;
}
switch (drb_toaddmod_p->pdcp_Config->headerCompression.present) {
case LTE_PDCP_Config__headerCompression_PR_NOTHING:
case LTE_PDCP_Config__headerCompression_PR_notUsed:
header_compression_profile=0x0;
break;
case LTE_PDCP_Config__headerCompression_PR_rohc:
// parse the struc and get the rohc profile
if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0001) {
header_compression_profile=0x0001;
} else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0002) {
header_compression_profile=0x0002;
} else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0003) {
header_compression_profile=0x0003;
} else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0004) {
header_compression_profile=0x0004;
} else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0006) {
header_compression_profile=0x0006;
} else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0101) {
header_compression_profile=0x0101;
} else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0102) {
header_compression_profile=0x0102;
} else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0103) {
header_compression_profile=0x0103;
} else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0104) {
header_compression_profile=0x0104;
} else {
header_compression_profile=0x0;
LOG_W(PDCP,"unknown header compresion profile\n");
}
// set the applicable profile
break;
default:
LOG_W(PDCP,PROTOCOL_PDCP_CTXT_FMT"[RB %ld] unknown drb_toaddmod->PDCP_Config->headerCompression->present \n",
PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), drb_id);
break;
}
pdcp_config_req_asn1 (
ctxt_pP,
pdcp_p,
SRB_FLAG_NO,
rlc_type,
action,
lc_id,
mch_id,
drb_id,
drb_sn,
drb_report,
header_compression_profile,
0xFF,
NULL,
NULL,
NULL);
}
}
}
return TRUE;
}
//-----------------------------------------------------------------------------
boolean_t
......
......@@ -320,6 +320,21 @@ boolean_t rrc_pdcp_config_asn1_req (
rb_id_t *const defaultDRB
);
/*! \fn bool rrc_pdcp_reestablishment_asn1_req const protocol_ctxt_t *const ctxt_pP, const rnti_t previous_rnti, LTE_SRB_ToAddModList_t *const srb2add_list_pP, LTE_DRB_ToAddModList_t *const drb2add_list_pP)
* \brief Function for RRC to reestablish a Radio Bearer.
* \param[in] ctxt_pP Running context.
* \param[in] previous_rnti privious rnti
* \param[in] srb2add_list SRB configuration list to be created.
* \param[in] drb2add_list DRB configuration list to be created.
* \return A status about the processing, OK or error code.
*/
boolean_t rrc_pdcp_reestablishment_asn1_req (
const protocol_ctxt_t *const ctxt_pP,
const rnti_t previous_rnti,
LTE_SRB_ToAddModList_t *const srb2add_list_pP,
LTE_DRB_ToAddModList_t *const drb2add_list_pP
);
/*! \fn boolean_t pdcp_config_req_asn1 (const protocol_ctxt_t* const ctxt_pP, srb_flag_t srb_flagP, uint32_t action, rb_id_t rb_id, uint8_t rb_sn, uint8_t rb_report, uint16_t header_compression_profile, uint8_t security_mode)
* \brief Function for RRC to configure a Radio Bearer.
* \param[in] ctxt_pP Running context.
......
......@@ -619,6 +619,23 @@ rlc_op_status_t rlc_stat_req (
unsigned int *const stat_timer_poll_retransmit_timed_out,
unsigned int *const stat_timer_status_prohibit_timed_out);
/*! \fn rlc_op_status_t rrc_rlc_reestablishment_asn1_req (
const protocol_ctxt_t *const ctxt_pP,
const rnti_t previous_rnti,
const LTE_SRB_ToAddModList_t *const srb2add_listP,
const LTE_DRB_ToAddModList_t *const drb2add_listP)
* \brief Function for RRC to reestablish a Radio Bearer.
* \param[in] ctxtP Running context.
* \param[in] previous_rnti Previous RNTI.
* \param[in] srb2add_listP SRB configuration list to be created.
* \param[in] drb2add_listP DRB configuration list to be created.
* \return A status about the processing, OK or error code.
*/
rlc_op_status_t rrc_rlc_reestablishment_asn1_req (const protocol_ctxt_t *const ctxt_pP,
const rnti_t previous_rnti,
const LTE_SRB_ToAddModList_t *const srb2add_listP,
const LTE_DRB_ToAddModList_t *const drb2add_listP);
/*! \fn int rlc_module_init(int enb_flag)
* \brief RAZ the memory of the RLC layer, initialize the memory pool manager (mem_block_t structures mainly used in RLC module).
*/
......
......@@ -1032,3 +1032,79 @@ void rlc_tick(int frame, int subframe)
rlc_current_time_last_subframe = subframe;
}
}
//-----------------------------------------------------------------------------
rlc_op_status_t rrc_rlc_reestablishment_asn1_req (const protocol_ctxt_t *const ctxt_pP,
const rnti_t previous_rnti,
const LTE_SRB_ToAddModList_t *const srb2add_listP,
const LTE_DRB_ToAddModList_t *const drb2add_listP
) {
//-----------------------------------------------------------------------------
rlc_ue_t *ue;
rlc_ue_t *old_ue;
int rnti = ctxt_pP->rnti;
int module_id = ctxt_pP->module_id;
int cnt;
int srb_id=0;
int drb_id=0;
if (srb2add_listP != NULL) {
for (cnt=0; cnt<srb2add_listP->list.count; cnt++) {
rlc_manager_lock(rlc_ue_manager);
ue = rlc_manager_get_ue(rlc_ue_manager, rnti);
old_ue = rlc_manager_get_ue(rlc_ue_manager, previous_rnti);
srb_id=srb2add_listP->list.array[cnt]->srb_Identity;
//ignore already exist
if (ue->srb[srb_id-1] != NULL) {
LOG_D(RLC, "%s:%d:%s: warning SRB %d already exist for ue %d, do nothing\n",
__FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
continue;
}
rlc_manager_unlock(rlc_ue_manager);
// create new
add_srb(rnti, module_id, srb2add_listP->list.array[cnt]);
// TODO take over some parameter from old rnti. But discard all parameters
// TS36 322 5.4 Re-establishment procedure
// discard the remaining AMD PDUs and byte segments of AMD PDUs in the receiving side
// discard all RLC SDUs and AMD PDUs in the transmitting side
// discard all RLC control PDUs.
if (old_ue->srb[srb_id-1] != NULL) {
LOG_D(RLC, "%s:%d:%s: reestablishment SRB %d from %d to ue %d\n",
__FILE__, __LINE__, __FUNCTION__, srb_id, previous_rnti, rnti);
}
}
}
if (drb2add_listP != NULL) {
for (cnt=0; cnt<drb2add_listP->list.count; cnt++) {
rlc_manager_lock(rlc_ue_manager);
ue = rlc_manager_get_ue(rlc_ue_manager, rnti);
old_ue = rlc_manager_get_ue(rlc_ue_manager, previous_rnti);
drb_id=drb2add_listP->list.array[cnt]->drb_Identity;
//ignore already exist
if (ue->drb[drb_id-1] != NULL) {
LOG_D(RLC, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n",
__FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
continue;
}
rlc_manager_unlock(rlc_ue_manager);
// create new
add_drb(rnti, module_id, drb2add_listP->list.array[cnt]);
// TODO take over some parameter from old rnti. But discard all parameters
// TS36 322 5.4 Re-establishment procedure
// discard the remaining AMD PDUs and byte segments of AMD PDUs in the receiving side
// discard all RLC SDUs and AMD PDUs in the transmitting side
// discard all RLC control PDUs.
if ((old_ue->drb[drb_id-1] != NULL)) {
LOG_D(RLC, "%s:%d:%s: reestablishment DRB %d from %d to ue %d\n",
__FILE__, __LINE__, __FUNCTION__, drb_id, previous_rnti, rnti);
}
}
}
return RLC_OP_STATUS_OK;
}
\ No newline at end of file
......@@ -2173,30 +2173,17 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete(
// pdcp_remove_UE(&ctxt_prior);
// add UE info to freeList for RU_thread to remove the UE instead of remove it here
/* Refresh SRBs/DRBs */
rrc_pdcp_config_asn1_req(ctxt_pP,
rrc_pdcp_reestablishment_asn1_req(ctxt_pP,
reestablish_rnti,
*SRB_configList2, // NULL,
DRB_configList,
NULL,
0xff, // already configured during the securitymodecommand
NULL,
NULL,
NULL
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
, (LTE_PMCH_InfoList_r9_t *) NULL
#endif
, NULL);
DRB_configList);
/* Refresh SRBs/DRBs */
if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
rrc_rlc_config_asn1_req(ctxt_pP,
rrc_rlc_reestablishment_asn1_req(ctxt_pP,
reestablish_rnti,
*SRB_configList2, // NULL,
DRB_configList,
NULL
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
, (LTE_PMCH_InfoList_r9_t *) NULL,
0,
0
#endif
DRB_configList
);
}
LOG_I(RRC, "[RRCConnectionReestablishment]put UE %x into freeList\n", reestablish_rnti);
......@@ -7389,24 +7376,16 @@ rrc_eNB_decode_ccch(
MSC_AS_TIME_FMT" CONFIG_REQ UE %x SRB",
MSC_AS_TIME_ARGS(ctxt_pP),
ue_context_p->ue_context.rnti);
rrc_pdcp_config_asn1_req(ctxt_pP,
rrc_pdcp_reestablishment_asn1_req(ctxt_pP,
c_rnti,
ue_context_p->ue_context.SRB_configList,
(LTE_DRB_ToAddModList_t *) NULL,
(LTE_DRB_ToReleaseList_t *) NULL,
0xff,
NULL,
NULL,
NULL
, (LTE_PMCH_InfoList_r9_t *) NULL
,NULL);
(LTE_DRB_ToAddModList_t *) NULL);
if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
rrc_rlc_config_asn1_req(ctxt_pP,
rrc_rlc_reestablishment_asn1_req(ctxt_pP,
c_rnti,
ue_context_p->ue_context.SRB_configList,
(LTE_DRB_ToAddModList_t *) NULL,
(LTE_DRB_ToReleaseList_t *) NULL
, (LTE_PMCH_InfoList_r9_t *) NULL,
0,0
(LTE_DRB_ToAddModList_t *) NULL
);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment