예제 #1
0
/**
 * Check if SN number is in the range according to SN size
 */
BOOL pdcp_is_seq_num_valid(u16 seq_num, u8 seq_num_size)
{
  if (seq_num > 0 && seq_num <= pdcp_calculate_max_seq_num_for_given_size(seq_num_size))
    return TRUE;

  return FALSE;
}
/**
 * Check if SN number is in the range according to SN size
 */
boolean_t pdcp_is_seq_num_valid(uint16_t seq_num, uint8_t seq_num_size)
{
  if (seq_num >= 0 && seq_num <= pdcp_calculate_max_seq_num_for_given_size(seq_num_size)) {
    return TRUE;
  }

  return FALSE;
}
예제 #3
0
BOOL pdcp_advance_rx_window(pdcp_t* pdcp_entity)
{
  if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE)
    return FALSE;

  /*
   * Update sequence numbering state and Hyper Frame Number if SN has already reached
   * its max value (see 5.1 PDCP Data Transfer Procedures)
   */
  if (pdcp_entity->next_pdcp_rx_sn == pdcp_calculate_max_seq_num_for_given_size(pdcp_entity->seq_num_size)) {
    pdcp_entity->next_pdcp_rx_sn = 0;
    pdcp_entity->rx_hfn++;
  } else {
    pdcp_entity->next_pdcp_rx_sn++;
  }

  return TRUE;
}
예제 #4
0
u16 pdcp_get_next_tx_seq_number(pdcp_t* pdcp_entity)
{
  if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE)
    return -1;

  // Sequence number should be incremented after it is assigned for a PDU
  u16 pdcp_seq_num = pdcp_entity->next_pdcp_tx_sn;

  /*
   * Update sequence numbering state and Hyper Frame Number if SN has already reached
   * its max value (see 5.1 PDCP Data Transfer Procedures)
   */
  if (pdcp_entity->next_pdcp_tx_sn == pdcp_calculate_max_seq_num_for_given_size(pdcp_entity->seq_num_size)) {
    pdcp_entity->next_pdcp_tx_sn = 0;
    pdcp_entity->tx_hfn++;
  } else {
    pdcp_entity->next_pdcp_tx_sn++;
  }

  return pdcp_seq_num;
}
예제 #5
0
파일: pdcp.c 프로젝트: huier103/virtual
BOOL pdcp_data_req(module_id_t module_id, u32_t frame, u8_t eNB_flag, rb_id_t rab_id, sdu_size_t sdu_buffer_size, \
                   unsigned char* sdu_buffer)
#endif
{
//-----------------------------------------------------------------------------
#ifdef PDCP_UNIT_TEST
  pdcp_t* pdcp = test_pdcp_entity;
#else
  pdcp_t* pdcp = &pdcp_array[module_id][rab_id];
#endif

  mem_block_t* pdcp_pdu = NULL;
  u16 pdcp_pdu_size = sdu_buffer_size + PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE;

  LOG_I(PDCP, "Data request notification for PDCP entity with module ID %d and radio bearer ID %d pdu size %d\n", module_id, rab_id,pdcp_pdu_size);

  if (sdu_buffer_size == 0) {
    LOG_W(PDCP, "Handed SDU is of size 0! Ignoring...\n");
    return FALSE;
  }

  /*
   * XXX MAX_IP_PACKET_SIZE is 4096, shouldn't this be MAX SDU size, which is 8188 bytes?
   */
  if (sdu_buffer_size > MAX_IP_PACKET_SIZE) {
    LOG_W(PDCP, "Requested SDU size (%d) is bigger than that can be handled by PDCP!\n", sdu_buffer_size);
    // XXX What does following call do?
    mac_xface->macphy_exit("");
  }

  /*
   * Allocate a new block for the new PDU (i.e. PDU header and SDU payload)
   */
  LOG_D(PDCP, "Asking for a new mem_block of size %d\n", pdcp_pdu_size);
  pdcp_pdu = get_free_mem_block(pdcp_pdu_size);

  if (pdcp_pdu != NULL) {
    /*
     * Create a Data PDU with header and append data
     *
     * Place User Plane PDCP Data PDU header first
     */
    pdcp_user_plane_data_pdu_header_with_long_sn pdu_header;
    pdu_header.dc = PDCP_DATA_PDU;
    pdu_header.sn = pdcp_get_next_tx_seq_number(pdcp);

    /*
     * Validate incoming sequence number, there might be a problem with PDCP initialization
     */
    if (pdu_header.sn > pdcp_calculate_max_seq_num_for_given_size(pdcp->seq_num_size)) {
      LOG_E(PDCP, "Generated sequence number (%lu) is greater than a sequence number could ever be!\n", pdu_header.sn);
      LOG_E(PDCP, "There must be a problem with PDCP initialization, ignoring this PDU...\n");

      free_mem_block(pdcp_pdu);
      return FALSE;
    }

    LOG_I(PDCP, "Sequence number %d is assigned to current PDU\n", pdu_header.sn);

    /*
     * Fill PDU buffer with the struct's fields
     */
    if (pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer((unsigned char*)pdcp_pdu->data, &pdu_header) == FALSE) {
      LOG_W(PDCP, "Cannot fill PDU buffer with relevant header fields!\n");
      return FALSE;
    }

    /* Then append data... */
    memcpy(&pdcp_pdu->data[PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE], sdu_buffer, sdu_buffer_size);

    /* Print octets of outgoing data in hexadecimal form */
    LOG_D(PDCP, "Following content will be sent over RLC (PDCP PDU header is the first two bytes)\n");
    util_print_hex_octets(PDCP, (unsigned char*)pdcp_pdu->data, pdcp_pdu_size);

#ifdef PDCP_UNIT_TEST
    /*
     * Here we add PDU to the list and return to test code without
     * handing it off to RLC
     */
    list_add_tail_eurecom(pdcp_pdu, test_list);

    return TRUE;
#else
    /*
     * Ask sublayer to transmit data and check return value
     * to see if RLC succeeded
     */
    rlc_op_status_t rlc_status = rlc_data_req(module_id, frame, eNB_flag, rab_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, pdcp_pdu_size, pdcp_pdu);
    switch (rlc_status) {
      case RLC_OP_STATUS_OK:
        LOG_I(PDCP, "Data sending request over RLC succeeded!\n");
	break;

      case RLC_OP_STATUS_BAD_PARAMETER:
	LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n");
	return FALSE;

      case RLC_OP_STATUS_INTERNAL_ERROR:
	LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n");
	return FALSE;

      case RLC_OP_STATUS_OUT_OF_RESSOURCES:
	LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n");
	return FALSE;

      default:
	LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status);
	return FALSE;
    }

    /*
     * Control arrives here only if rlc_data_req() returns RLC_OP_STATUS_OK
     * so we return TRUE afterwards
     */
    if (eNB_flag == 1) {
      Pdcp_stats_tx[module_id][(rab_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_id & RAB_OFFSET)-DTCH]++;
      Pdcp_stats_tx_bytes[module_id][(rab_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_id & RAB_OFFSET)-DTCH] += sdu_buffer_size;
    } else {