fapi_nr_ue_l1.c 11.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

22
/* \file fapi_nr_ue_l1.c
23
 * \brief functions for NR UE FAPI-like interface
24
 * \author R. Knopp, K.H. HSU
25 26
 * \date 2018
 * \version 0.1
27 28
 * \company Eurecom / NTUST
 * \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr
29 30 31 32
 * \note
 * \warning
 */

33 34
#include <stdio.h>

35 36
#include "fapi_nr_ue_interface.h"
#include "fapi_nr_ue_l1.h"
37
#include "harq_nr.h"
38 39 40
//#include "PHY/phy_vars_nr_ue.h"

#include "PHY/defs_nr_UE.h"
Agustin's avatar
Agustin committed
41
#include "PHY/impl_defs_nr.h"
42

43
extern PHY_VARS_NR_UE ***PHY_vars_UE_g;
44

45
const char *dl_pdu_type[]={"DCI", "DLSCH", "RA_DLSCH", "SI_DLSCH", "P_DLSCH"};
cig's avatar
cig committed
46 47
const char *ul_pdu_type[]={"PRACH", "PUCCH", "PUSCH", "SRS"};

48
int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
49

50
  bool found = false;
51
  if(scheduled_response != NULL){
52 53 54

    module_id_t module_id = scheduled_response->module_id;
    uint8_t cc_id = scheduled_response->CC_id, thread_id;
55
    uint32_t i;
56 57
    int slot = scheduled_response->slot;

58
    // Note: we have to handle the thread IDs for this. To be revisited completely.
59
    thread_id = scheduled_response->thread_id;
60
    NR_UE_DLSCH_t *dlsch0 = NULL;
61
    NR_UE_PDCCH *pdcch_vars = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0];
62
    NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0][0];
63
    NR_UE_PUCCH *pucch_vars = PHY_vars_UE_g[module_id][cc_id]->pucch_vars[thread_id][0];
Agustin's avatar
Agustin committed
64

65 66
    if(scheduled_response->dl_config != NULL){
      fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config;
67

68
      pdcch_vars->nb_search_space = 0;
69

70
      for (i = 0; i < dl_config->number_pdus; ++i){
71 72
        AssertFatal(dl_config->number_pdus < FAPI_NR_DL_CONFIG_LIST_NUM,"dl_config->number_pdus %d out of bounds\n",dl_config->number_pdus);
        AssertFatal(dl_config->dl_config_list[i].pdu_type<=FAPI_NR_DL_CONFIG_TYPES,"pdu_type %d > 2\n",dl_config->dl_config_list[i].pdu_type);
francescomani's avatar
francescomani committed
73 74
        LOG_D(PHY, "In %s: frame %d slot %d received 1 DL %s PDU of %d total DL PDUs:\n",
              __FUNCTION__, scheduled_response->frame, slot, dl_pdu_type[dl_config->dl_config_list[i].pdu_type - 1], dl_config->number_pdus);
cig's avatar
cig committed
75

76 77 78 79 80
        if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DCI) {

          fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15;
          memcpy((void*)&pdcch_vars->pdcch_config[pdcch_vars->nb_search_space],(void*)pdcch_config,sizeof(*pdcch_config));
          pdcch_vars->nb_search_space = pdcch_vars->nb_search_space + 1;
81 82
          pdcch_vars->sfn = scheduled_response->frame;
          pdcch_vars->slot = slot;
83 84
          LOG_D(PHY,"Number of DCI SearchSpaces %d\n",pdcch_vars->nb_search_space);

cig's avatar
cig committed
85 86
        } else {

87 88 89
          fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
          uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;

cig's avatar
cig committed
90 91 92 93 94
          if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DLSCH){
            dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0];
          }
          else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH){
            dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_ra[0];
rmagueta's avatar
rmagueta committed
95
            dlsch0->rnti_type = _RA_RNTI_;
96
            dlsch0->harq_processes[current_harq_pid]->status = ACTIVE;
cig's avatar
cig committed
97
          }
98 99
          else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH){
            dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_SI[0];
100
            dlsch0->rnti_type = _SI_RNTI_;
101
            dlsch0->harq_processes[current_harq_pid]->status = ACTIVE;
102
          }
103 104 105 106

          dlsch0->current_harq_pid = current_harq_pid;
          dlsch0->active = 1;
          dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti;
cig's avatar
cig committed
107

108 109
          LOG_D(PHY,"current_harq_pid = %d\n", current_harq_pid);

110
          NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
cig's avatar
cig committed
111 112
          if (dlsch0_harq){

113 114 115 116 117 118 119 120
            dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart;
            dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize;
            dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs;
            dlsch0_harq->start_rb = dlsch_config_pdu->start_rb;
            dlsch0_harq->nb_symbols = dlsch_config_pdu->number_symbols;
            dlsch0_harq->start_symbol = dlsch_config_pdu->start_symbol;
            dlsch0_harq->dlDmrsSymbPos = dlsch_config_pdu->dlDmrsSymbPos;
            dlsch0_harq->dmrsConfigType = dlsch_config_pdu->dmrsConfigType;
121
            dlsch0_harq->n_dmrs_cdm_groups = dlsch_config_pdu->n_dmrs_cdm_groups;
122 123 124
            dlsch0_harq->mcs = dlsch_config_pdu->mcs;
            dlsch0_harq->rvidx = dlsch_config_pdu->rv;
            dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
125 126 127 128 129 130
            //get nrOfLayers from DCI info
            uint8_t Nl = 0;
            for (i = 0; i < 4; i++) {
              if (dlsch_config_pdu->dmrs_ports[i] >= i) Nl += 1;
            }
            dlsch0_harq->Nl = Nl;
131
            dlsch0_harq->mcs_table=dlsch_config_pdu->mcs_table;
132
            downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch_config_pdu->rv, dlsch0->rnti_type);
133 134 135 136 137
            if (dlsch0_harq->status != ACTIVE) {
              // dlsch0_harq->status not ACTIVE may be due to false retransmission. Reset the 
              // following flag to skip PDSCH procedures in that case.
              dlsch0->active = 0;
            }
138 139 140 141 142 143 144
            /* PTRS */
            dlsch0_harq->PTRSFreqDensity = dlsch_config_pdu->PTRSFreqDensity;
            dlsch0_harq->PTRSTimeDensity = dlsch_config_pdu->PTRSTimeDensity;
            dlsch0_harq->PTRSPortIndex = dlsch_config_pdu->PTRSPortIndex;
            dlsch0_harq->nEpreRatioOfPDSCHToPTRS = dlsch_config_pdu->nEpreRatioOfPDSCHToPTRS;
            dlsch0_harq->PTRSReOffset = dlsch_config_pdu->PTRSReOffset;
            dlsch0_harq->pduBitmap = dlsch_config_pdu->pduBitmap;
145
            LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs);
146
          }
147
        }
148
      }
cig's avatar
cig committed
149
      dl_config->number_pdus = 0;
150 151
    }

152 153
    if (scheduled_response->ul_config != NULL){

154
      fapi_nr_ul_config_request_t *ul_config = scheduled_response->ul_config;
155

156
      pthread_mutex_lock(&ul_config->mutex_ul_config);
157 158
      for (i = 0; i < ul_config->number_pdus; ++i){

159
        AssertFatal(ul_config->ul_config_list[i].pdu_type <= FAPI_NR_UL_CONFIG_TYPES,"pdu_type %d out of bounds\n",ul_config->ul_config_list[i].pdu_type);
cig's avatar
cig committed
160 161
        LOG_D(PHY, "In %s: processing %s PDU of %d total UL PDUs (ul_config %p) \n", __FUNCTION__, ul_pdu_type[ul_config->ul_config_list[i].pdu_type - 1], ul_config->number_pdus, ul_config);

162
        uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, current_harq_pid, gNB_id = 0;
163
        /* PRACH */
164
        //NR_PRACH_RESOURCES_t *prach_resources;
165 166
        fapi_nr_ul_config_prach_pdu *prach_config_pdu;
        /* PUSCH */
167
        nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu;
168
        /* PUCCH */
169 170 171 172 173 174
        fapi_nr_ul_config_pucch_pdu *pucch_config_pdu;

        switch (pdu_type){

        case (FAPI_NR_UL_CONFIG_TYPE_PUSCH):
          // pusch config pdu
175 176
          pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu;
          current_harq_pid = pusch_config_pdu->pusch_data.harq_process_id;
cig's avatar
cig committed
177
          NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch0->harq_processes[current_harq_pid];
178
          harq_process_ul_ue->status = 0;
179

cig's avatar
cig committed
180 181 182 183 184 185 186 187
          if (harq_process_ul_ue){

            nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &harq_process_ul_ue->pusch_pdu;

            memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t));

            ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;

188
            if (scheduled_response->tx_request) {
189 190 191 192 193 194 195 196 197
              for (int j=0; j<scheduled_response->tx_request->number_of_pdus; j++) {
                fapi_nr_tx_request_body_t *tx_req_body = &scheduled_response->tx_request->tx_request_body[j];
                if (tx_req_body->pdu_index == i) {
                  LOG_D(PHY,"%d.%d Copying %d bytes to harq_process_ul_ue->a (harq_pid %d)\n",scheduled_response->frame,slot,tx_req_body->pdu_length,current_harq_pid);
                  memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length);
                  harq_process_ul_ue->status = ACTIVE;
                  break;
                }
              }
cig's avatar
cig committed
198 199 200 201 202 203 204 205
            }

          } else {

            LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n");
            return -1;

          }
206

207 208 209
        break;

        case (FAPI_NR_UL_CONFIG_TYPE_PUCCH):
210
          found = false;
211
          pucch_config_pdu = &ul_config->ul_config_list[i].pucch_config_pdu;
212 213
          for(int j=0; j<2; j++) {
            if(pucch_vars->active[j] == false) {
214
              LOG_D(PHY,"%d.%d Copying pucch pdu to UE PHY\n",scheduled_response->frame,slot);
215
              memcpy((void*)&(pucch_vars->pucch_pdu[j]), (void*)pucch_config_pdu, sizeof(fapi_nr_ul_config_pucch_pdu));
216
              pucch_vars->active[j] = true;
217
              found = true;
218
              break;
219 220 221 222
            }
          }
          if (!found)
            LOG_E(PHY, "Couldn't find allocation for PUCCH PDU in PUCCH VARS\n");
223 224 225 226 227
        break;

        case (FAPI_NR_UL_CONFIG_TYPE_PRACH):
          // prach config pdu
          prach_config_pdu = &ul_config->ul_config_list[i].prach_config_pdu;
228
          memcpy((void*)&(PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->prach_pdu), (void*)prach_config_pdu, sizeof(fapi_nr_ul_config_prach_pdu));
229 230 231 232 233
        break;

        default:
        break;
        }
234
      }
235 236 237 238 239 240 241
      if (scheduled_response->tx_request)
        scheduled_response->tx_request->number_of_pdus = 0;
      ul_config->sfn = 0;
      ul_config->slot = 0;
      ul_config->number_pdus = 0;
      for (int i=0; i < FAPI_NR_UL_CONFIG_LIST_NUM; i++) 
        memset(&(ul_config->ul_config_list[i]), 0, sizeof(fapi_nr_ul_config_request_pdu_t));
242
      pthread_mutex_unlock(&ul_config->mutex_ul_config);
243 244 245
    }
  }
  return 0;
246 247 248
}


249 250


251
int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config){
252

253
  fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config;
254

255
  if(phy_config != NULL) {
256
      memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t));
257
      if (PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->UE_mode[0] == NOT_SYNCHED)
258
	      PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->UE_mode[0] = PRACH;
259
  }
260
  return 0;
261
}
262

263