Fix in paging: iterate list of MCC/MNC/TAC
This commit is contained in:
+118
-116
@@ -1849,125 +1849,127 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance
|
|||||||
for (uint16_t tai_size = 0; tai_size < S1AP_PAGING_IND(msg_p).tai_size; tai_size++) {
|
for (uint16_t tai_size = 0; tai_size < S1AP_PAGING_IND(msg_p).tai_size; tai_size++) {
|
||||||
LOG_D(RRC,"[eNB %d] In S1AP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc,
|
LOG_D(RRC,"[eNB %d] In S1AP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc,
|
||||||
S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, S1AP_PAGING_IND(msg_p).tac[tai_size]);
|
S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, S1AP_PAGING_IND(msg_p).tac[tai_size]);
|
||||||
if (RC.rrc[instance]->configuration.mcc == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc
|
for (uint8_t j = 0; j < RC.rrc[instance]->configuration.num_plmn; j++) {
|
||||||
&& RC.rrc[instance]->configuration.mnc == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc
|
if (RC.rrc[instance]->configuration.mcc[j] == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc
|
||||||
&& RC.rrc[instance]->configuration.tac == S1AP_PAGING_IND(msg_p).tac[tai_size]) {
|
&& RC.rrc[instance]->configuration.mnc[j] == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc
|
||||||
for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
&& RC.rrc[instance]->configuration.tac == S1AP_PAGING_IND(msg_p).tac[tai_size]) {
|
||||||
lte_frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type;
|
for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||||
/* get nB from configuration */
|
lte_frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type;
|
||||||
/* get default DRX cycle from configuration */
|
/* get nB from configuration */
|
||||||
Tc = (uint8_t)RC.rrc[instance]->configuration.pcch_defaultPagingCycle[CC_id];
|
/* get default DRX cycle from configuration */
|
||||||
if (Tc < PCCH_Config__defaultPagingCycle_rf32 || Tc > PCCH_Config__defaultPagingCycle_rf256) {
|
Tc = (uint8_t)RC.rrc[instance]->configuration.pcch_defaultPagingCycle[CC_id];
|
||||||
continue;
|
if (Tc < PCCH_Config__defaultPagingCycle_rf32 || Tc > PCCH_Config__defaultPagingCycle_rf256) {
|
||||||
}
|
continue;
|
||||||
Tue = (uint8_t)S1AP_PAGING_IND(msg_p).paging_drx;
|
}
|
||||||
/* set T = min(Tc,Tue) */
|
Tue = (uint8_t)S1AP_PAGING_IND(msg_p).paging_drx;
|
||||||
T = Tc < Tue ? Ttab[Tc] : Ttab[Tue];
|
/* set T = min(Tc,Tue) */
|
||||||
/* set pcch_nB = PCCH-Config->nB */
|
T = Tc < Tue ? Ttab[Tc] : Ttab[Tue];
|
||||||
pcch_nB = (uint32_t)RC.rrc[instance]->configuration.pcch_nB[CC_id];
|
/* set pcch_nB = PCCH-Config->nB */
|
||||||
switch (pcch_nB) {
|
pcch_nB = (uint32_t)RC.rrc[instance]->configuration.pcch_nB[CC_id];
|
||||||
case PCCH_Config__nB_fourT:
|
switch (pcch_nB) {
|
||||||
Ns = 4;
|
case PCCH_Config__nB_fourT:
|
||||||
break;
|
Ns = 4;
|
||||||
case PCCH_Config__nB_twoT:
|
break;
|
||||||
Ns = 2;
|
case PCCH_Config__nB_twoT:
|
||||||
break;
|
Ns = 2;
|
||||||
default:
|
break;
|
||||||
Ns = 1;
|
default:
|
||||||
break;
|
Ns = 1;
|
||||||
}
|
break;
|
||||||
/* set N = min(T,nB) */
|
}
|
||||||
if (pcch_nB > PCCH_Config__nB_oneT) {
|
/* set N = min(T,nB) */
|
||||||
switch (pcch_nB) {
|
if (pcch_nB > PCCH_Config__nB_oneT) {
|
||||||
case PCCH_Config__nB_halfT:
|
switch (pcch_nB) {
|
||||||
N = T/2;
|
case PCCH_Config__nB_halfT:
|
||||||
break;
|
N = T/2;
|
||||||
case PCCH_Config__nB_quarterT:
|
break;
|
||||||
N = T/4;
|
case PCCH_Config__nB_quarterT:
|
||||||
break;
|
N = T/4;
|
||||||
case PCCH_Config__nB_oneEighthT:
|
break;
|
||||||
N = T/8;
|
case PCCH_Config__nB_oneEighthT:
|
||||||
break;
|
N = T/8;
|
||||||
case PCCH_Config__nB_oneSixteenthT:
|
break;
|
||||||
N = T/16;
|
case PCCH_Config__nB_oneSixteenthT:
|
||||||
break;
|
N = T/16;
|
||||||
case PCCH_Config__nB_oneThirtySecondT:
|
break;
|
||||||
N = T/32;
|
case PCCH_Config__nB_oneThirtySecondT:
|
||||||
break;
|
N = T/32;
|
||||||
default:
|
break;
|
||||||
/* pcch_nB error */
|
default:
|
||||||
LOG_E(RRC, "[eNB %d] In S1AP_PAGING_IND: pcch_nB error (pcch_nB %d) \n",
|
/* pcch_nB error */
|
||||||
instance, pcch_nB);
|
LOG_E(RRC, "[eNB %d] In S1AP_PAGING_IND: pcch_nB error (pcch_nB %d) \n",
|
||||||
return (-1);
|
instance, pcch_nB);
|
||||||
}
|
return (-1);
|
||||||
} else {
|
|
||||||
N = T;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* insert data to UE_PF_PO or update data in UE_PF_PO */
|
|
||||||
pthread_mutex_lock(&ue_pf_po_mutex);
|
|
||||||
uint16_t i = 0;
|
|
||||||
for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
|
||||||
if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value))
|
|
||||||
|| (UE_PF_PO[CC_id][i].enable_flag != TRUE)) {
|
|
||||||
/* set T = min(Tc,Tue) */
|
|
||||||
UE_PF_PO[CC_id][i].T = T;
|
|
||||||
/* set UE_ID */
|
|
||||||
UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)S1AP_PAGING_IND(msg_p).ue_index_value;
|
|
||||||
/* calculate PF and PO */
|
|
||||||
/* set PF_min : SFN mod T = (T div N)*(UE_ID mod N) */
|
|
||||||
UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N);
|
|
||||||
/* set PO */
|
|
||||||
/* i_s = floor(UE_ID/N) mod Ns */
|
|
||||||
i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns);
|
|
||||||
if (Ns == 1) {
|
|
||||||
UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? 9 : 0;
|
|
||||||
} else if (Ns==2) {
|
|
||||||
UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4+(5*i_s)) : (5*i_s);
|
|
||||||
} else if (Ns==4) {
|
|
||||||
UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1)));
|
|
||||||
}
|
}
|
||||||
if (UE_PF_PO[CC_id][i].enable_flag == TRUE) {
|
} else {
|
||||||
//paging exist UE log
|
N = T;
|
||||||
LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO);
|
}
|
||||||
} else {
|
|
||||||
/* set enable_flag */
|
|
||||||
UE_PF_PO[CC_id][i].enable_flag = TRUE;
|
|
||||||
//paging new UE log
|
|
||||||
LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&ue_pf_po_mutex);
|
|
||||||
|
|
||||||
uint32_t length;
|
/* insert data to UE_PF_PO or update data in UE_PF_PO */
|
||||||
uint8_t buffer[RRC_BUF_SIZE];
|
pthread_mutex_lock(&ue_pf_po_mutex);
|
||||||
uint8_t *message_buffer;
|
uint8_t i = 0;
|
||||||
/* Transfer data to PDCP */
|
for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
||||||
MessageDef *message_p;
|
if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value))
|
||||||
message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_PCCH_DATA_REQ);
|
|| (UE_PF_PO[CC_id][i].enable_flag != TRUE)) {
|
||||||
/* Create message for PDCP (DLInformationTransfer_t) */
|
/* set T = min(Tc,Tue) */
|
||||||
length = do_Paging (instance,
|
UE_PF_PO[CC_id][i].T = T;
|
||||||
buffer,
|
/* set UE_ID */
|
||||||
S1AP_PAGING_IND(msg_p).ue_paging_identity,
|
UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)S1AP_PAGING_IND(msg_p).ue_index_value;
|
||||||
S1AP_PAGING_IND(msg_p).cn_domain);
|
/* calculate PF and PO */
|
||||||
if(length == -1)
|
/* set PF_min : SFN mod T = (T div N)*(UE_ID mod N) */
|
||||||
{
|
UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N);
|
||||||
LOG_I(RRC, "do_Paging error");
|
/* set PO */
|
||||||
return -1;
|
/* i_s = floor(UE_ID/N) mod Ns */
|
||||||
|
i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns);
|
||||||
|
if (Ns == 1) {
|
||||||
|
UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? 9 : 0;
|
||||||
|
} else if (Ns==2) {
|
||||||
|
UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4+(5*i_s)) : (5*i_s);
|
||||||
|
} else if (Ns==4) {
|
||||||
|
UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1)));
|
||||||
|
}
|
||||||
|
if (UE_PF_PO[CC_id][i].enable_flag == TRUE) {
|
||||||
|
//paging exist UE log
|
||||||
|
LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO);
|
||||||
|
} else {
|
||||||
|
/* set enable_flag */
|
||||||
|
UE_PF_PO[CC_id][i].enable_flag = TRUE;
|
||||||
|
//paging new UE log
|
||||||
|
LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&ue_pf_po_mutex);
|
||||||
|
|
||||||
|
uint32_t length;
|
||||||
|
uint8_t buffer[RRC_BUF_SIZE];
|
||||||
|
uint8_t *message_buffer;
|
||||||
|
/* Transfer data to PDCP */
|
||||||
|
MessageDef *message_p;
|
||||||
|
message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_PCCH_DATA_REQ);
|
||||||
|
/* Create message for PDCP (DLInformationTransfer_t) */
|
||||||
|
length = do_Paging (instance,
|
||||||
|
buffer,
|
||||||
|
S1AP_PAGING_IND(msg_p).ue_paging_identity,
|
||||||
|
S1AP_PAGING_IND(msg_p).cn_domain);
|
||||||
|
if(length == -1)
|
||||||
|
{
|
||||||
|
LOG_I(RRC, "do_Paging error");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
message_buffer = itti_malloc (TASK_RRC_ENB, TASK_PDCP_ENB, length);
|
||||||
|
/* Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). */
|
||||||
|
memcpy (message_buffer, buffer, length);
|
||||||
|
RRC_PCCH_DATA_REQ (message_p).sdu_size = length;
|
||||||
|
RRC_PCCH_DATA_REQ (message_p).sdu_p = message_buffer;
|
||||||
|
RRC_PCCH_DATA_REQ (message_p).mode = PDCP_TRANSMISSION_MODE_TRANSPARENT; /* not used */
|
||||||
|
RRC_PCCH_DATA_REQ (message_p).rnti = P_RNTI;
|
||||||
|
RRC_PCCH_DATA_REQ (message_p).ue_index = i;
|
||||||
|
RRC_PCCH_DATA_REQ (message_p).CC_id = CC_id;
|
||||||
|
LOG_D(RRC, "[eNB %d] CC_id %d In S1AP_PAGING_IND: send encdoed buffer to PDCP buffer_size %d\n", instance, CC_id, length);
|
||||||
|
itti_send_msg_to_task (TASK_PDCP_ENB, instance, message_p);
|
||||||
}
|
}
|
||||||
message_buffer = itti_malloc (TASK_RRC_ENB, TASK_PDCP_ENB, length);
|
|
||||||
/* Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). */
|
|
||||||
memcpy (message_buffer, buffer, length);
|
|
||||||
RRC_PCCH_DATA_REQ (message_p).sdu_size = length;
|
|
||||||
RRC_PCCH_DATA_REQ (message_p).sdu_p = message_buffer;
|
|
||||||
RRC_PCCH_DATA_REQ (message_p).mode = PDCP_TRANSMISSION_MODE_TRANSPARENT; /* not used */
|
|
||||||
RRC_PCCH_DATA_REQ (message_p).rnti = P_RNTI;
|
|
||||||
RRC_PCCH_DATA_REQ (message_p).ue_index = i;
|
|
||||||
RRC_PCCH_DATA_REQ (message_p).CC_id = CC_id;
|
|
||||||
LOG_D(RRC, "[eNB %d] CC_id %d In S1AP_PAGING_IND: send encdoed buffer to PDCP buffer_size %d\n", instance, CC_id, length);
|
|
||||||
itti_send_msg_to_task (TASK_PDCP_ENB, instance, message_p);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user