コード例 #1
0
ファイル: pdcp_sequence_manager.c プロジェクト: a4a881d4/oai
/**
 * 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
 */
BOOL pdcp_is_rx_seq_number_valid(u16 seq_num, pdcp_t* pdcp_entity)
{
  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;

  /*
   * XXX Since we do not implement reordering window yet we expect to receive 
   * exactly the next SN from lower layer. When reordering window is implemented 
   * the operator utilized here should be >= as stated in 5.1.2.1.2
   */
  if (seq_num == pdcp_entity->next_pdcp_rx_sn) {
    // Incoming sequence number is in accordance with the RX window so 
    // update PDCP status for next expected RX sequence number
    msg("[PDCP] Next expected SN arrived, advancing RX window\n");

    return pdcp_advance_rx_window(pdcp_entity);
  } else {
    // XXX This is an error just because we don't have a reordering window!
    msg("[PDCP] D'oh! Incoming SN is not the one we expected to receive! (Incoming:%d, Expected:%d)\n", \
        seq_num, pdcp_entity->next_pdcp_rx_sn);

    return FALSE;
  } 
}
コード例 #2
0
/**
 * 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;

#if 0
  LOG_D(PDCP, "Incoming RX Sequence number is %04d\n", seq_num);
#endif

  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) {
#if 0
    LOG_I(PDCP, "Received sequence number successfuly marked\n");
#endif
  } 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 0

    if (seq_num != pdcp_entity->next_pdcp_rx_sn) {
      LOG_D(PDCP,"Re-adjusting the sequence number to %d\n", seq_num);
    }

#endif
    //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:
#if 0
        LOG_D(PDCP,"Re-adjusting the sequence number to %d\n", seq_num);
#endif
      } 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;
}