bugfix: fix PDCP sequence management (plus some cleanup)
With the introduction of X2AP into develop, the UEs now have to regularly
send measurement reports.
In the logs of the eNB, we see:
[OSA] Mismatch found in integrity for algorithm 2,
got e0.a0.c2.66, expecting a5.9c.cb.57
[PDCP] [OSA][RB 1] eNB failed to validate MAC-I of incoming PDU
This is a bug in the PDCP layer that uses wrong parameters to compute the
integrity.
This commit fixes this bug.
The function pdcp_is_rx_seq_number_valid was removed. Its processing
has been directly integrated into the function pdcp_data_ind.
The function pdcp_mark_current_pdu_as_received is not called anymore.
Its processing was not used later on, so as of today, not calling it does
not introduce any functional change.
The function pdcp_validate_security takes now as parameters both
SN and HFN. Same for the function pdcp_get_next_count_rx.
Useless constants PDCP_SN_5BIT, PDCP_SN_7BIT and PDCP_SN_12BIT have been
removed.
The compilation option ENABLE_SECURITY has been removed. It's now always
on. (This may impact some use cases.)
The PDCP for DRB using RLC AM is not correct. It was not correct before
this commit (apart from the integrity bug). We should deal with a list
of PDUs and transmit packets to upper layers as detailed in the specs.
Today we transmit the PDU as soon as we get it. We don't care about
duplicates, in-order delivery, timeouts.
Also, we don't deal with "PDCP re-establishment". Not sure how that impacts
the software.
And, last but not least, there is still no ROHC.
This commit is contained in:
@@ -140,152 +140,6 @@ boolean_t pdcp_advance_rx_window(pdcp_t* pdcp_entity)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if incoming PDU has a sequence number in accordance with the RX window
|
||||
* @return 1 if SN is okay, 0 otherwise
|
||||
* XXX Reordering window should also be handled here
|
||||
*/
|
||||
boolean_t pdcp_is_rx_seq_number_valid(uint16_t seq_num, pdcp_t* pdcp_entity,srb_flag_t srb_flagP)
|
||||
{
|
||||
|
||||
uint16_t reordering_window = 0;
|
||||
|
||||
LOG_D(PDCP, "Incoming RX Sequence number is %04d\n", seq_num);
|
||||
|
||||
if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE || pdcp_is_seq_num_valid(seq_num, pdcp_entity->seq_num_size) == FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark received sequence numbers to keep track of missing ones
|
||||
* (and to build PDCP Control PDU for PDCP status report)
|
||||
*/
|
||||
if (pdcp_mark_current_pdu_as_received(seq_num, pdcp_entity) == TRUE) {
|
||||
LOG_D(PDCP, "Received sequence number successfuly marked\n");
|
||||
} else {
|
||||
LOG_W(PDCP, "Cannot mark received sequence number on the bitmap!\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* RX Procedures for SRB and DRBs as described in sec 5.1.2 of 36.323
|
||||
*/
|
||||
|
||||
if (srb_flagP) { // SRB
|
||||
|
||||
if (seq_num < pdcp_entity->next_pdcp_rx_sn) {
|
||||
// decipher and verify the integrity of the PDU (if applicable) using COUNT based on RX_HFN + 1 and the received PDCP SN
|
||||
pdcp_entity->rx_hfn++;
|
||||
pdcp_entity->rx_hfn_offset = 0;
|
||||
} else {
|
||||
// decipher and verify the integrity of the PDU (if applicable) using COUNT based using COUNT based on RX_HFN and the received PDCP SN
|
||||
pdcp_entity->rx_hfn_offset = 0;
|
||||
}
|
||||
|
||||
// Assume that integrity verification is applicable and the integrity verification is passed successfully;
|
||||
// or assume that integrity verification is not applicable:
|
||||
|
||||
// same the old next_pdcp_rx_sn to revert otherwise
|
||||
pdcp_entity->next_pdcp_rx_sn_before_integrity = pdcp_entity->next_pdcp_rx_sn;
|
||||
|
||||
if (seq_num != pdcp_entity->next_pdcp_rx_sn) {
|
||||
LOG_D(PDCP,"Re-adjusting the sequence number to %d\n", seq_num);
|
||||
}
|
||||
|
||||
//set Next_PDCP_RX_SN to the received PDCP SN +1 ;
|
||||
pdcp_entity->next_pdcp_rx_sn = seq_num;
|
||||
pdcp_advance_rx_window(pdcp_entity); // + 1, and check if it is larger than Maximum_PDCP_SN:
|
||||
|
||||
} else { // DRB
|
||||
|
||||
if (pdcp_entity->seq_num_size == PDCP_SN_7BIT) {
|
||||
reordering_window = REORDERING_WINDOW_SN_7BIT;
|
||||
} else {
|
||||
reordering_window = REORDERING_WINDOW_SN_12BIT;
|
||||
}
|
||||
|
||||
switch (pdcp_entity->rlc_mode) {
|
||||
case RLC_MODE_AM:
|
||||
if ((seq_num - pdcp_entity->last_submitted_pdcp_rx_sn > reordering_window) ||
|
||||
((0 <= pdcp_entity->last_submitted_pdcp_rx_sn - seq_num) &&
|
||||
(pdcp_entity->last_submitted_pdcp_rx_sn - seq_num < reordering_window) )) {
|
||||
|
||||
if (seq_num > pdcp_entity->next_pdcp_rx_sn) {
|
||||
/*
|
||||
* decipher the PDCP PDU as specified in the subclause 5.6, using COUNT based on RX_HFN - 1 and the received PDCP SN;
|
||||
*/
|
||||
pdcp_entity->rx_hfn_offset = -1;
|
||||
} else {
|
||||
/*
|
||||
* decipher the PDCP PDU as specified in the subclause 5.6, using COUNT based on RX_HFN and the received PDCP SN;
|
||||
*/
|
||||
pdcp_entity->rx_hfn_offset = 0;
|
||||
}
|
||||
|
||||
// discard this PDCP SDU;
|
||||
LOG_W(PDCP, "Out of the reordering window (Incoming SN:%d, Expected SN:%d): discard this PDCP SDU\n",
|
||||
seq_num, pdcp_entity->next_pdcp_rx_sn);
|
||||
return FALSE;
|
||||
} else if (pdcp_entity->next_pdcp_rx_sn - seq_num > reordering_window) {
|
||||
pdcp_entity->rx_hfn++;
|
||||
// use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU;
|
||||
pdcp_entity->rx_hfn_offset = 0;
|
||||
pdcp_entity->next_pdcp_rx_sn++;
|
||||
} else if (seq_num - pdcp_entity->next_pdcp_rx_sn >= reordering_window ) {
|
||||
// use COUNT based on RX_HFN – 1 and the received PDCP SN for deciphering the PDCP PDU;
|
||||
pdcp_entity->rx_hfn_offset = -1;
|
||||
} else if (seq_num >= pdcp_entity->next_pdcp_rx_sn ) {
|
||||
// use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU;
|
||||
pdcp_entity->rx_hfn_offset = 0;
|
||||
//set Next_PDCP_RX_SN to the received PDCP SN +1 ;
|
||||
pdcp_entity->next_pdcp_rx_sn = seq_num;
|
||||
pdcp_advance_rx_window(pdcp_entity); // + 1, anc check if it is larger than Maximum_PDCP_SN:
|
||||
LOG_D(PDCP,"Re-adjusting the sequence number to %d\n", seq_num);
|
||||
} else if (seq_num < pdcp_entity->next_pdcp_rx_sn) {
|
||||
// use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU;
|
||||
pdcp_entity->rx_hfn_offset = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RLC_MODE_UM :
|
||||
if (seq_num < pdcp_entity->next_pdcp_rx_sn) {
|
||||
pdcp_entity->rx_hfn++;
|
||||
}
|
||||
|
||||
// decipher the PDCP Data PDU using COUNT based on RX_HFN and the received PDCP SN as specified in the subclause 5.6;
|
||||
//set Next_PDCP_RX_SN to the received PDCP SN +1 ;
|
||||
pdcp_entity->next_pdcp_rx_sn = seq_num;
|
||||
pdcp_advance_rx_window(pdcp_entity); // + 1, and check if it is larger than Maximum_PDCP_SN:
|
||||
|
||||
break;
|
||||
|
||||
case RLC_MODE_TM :
|
||||
default:
|
||||
LOG_W(PDCP,"RLC mode %d not supported\n",pdcp_entity->rlc_mode);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (seq_num == pdcp_entity->next_pdcp_rx_sn) {
|
||||
LOG_I(PDCP, "Next expected SN (%d) arrived, advancing RX window\n", seq_num);
|
||||
|
||||
return pdcp_advance_rx_window(pdcp_entity);
|
||||
} else {
|
||||
LOG_E(PDCP, "Incoming SN is not the one we expected to receive! (Incoming:%d, Expected:%d)\n", \
|
||||
seq_num, pdcp_entity->next_pdcp_rx_sn);
|
||||
|
||||
|
||||
// Update first missing PDU (used in PDCP Control PDU for PDCP status report, see 6.2.6)
|
||||
if (pdcp_entity->first_missing_pdu != -1)
|
||||
pdcp_entity->first_missing_pdu = pdcp_entity->next_pdcp_rx_sn;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean_t pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entity)
|
||||
{
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user