[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-523] Statistics Indication between DU APP...
[o-du/l2.git] / src / 5gnrmac / mac_rach.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17  *******************************************************************************/
18 /* header include files (.h) */
19 #include "common_def.h"
20 #include "lrg.h"
21 #include "lrg.x"
22 #include "du_app_mac_inf.h"
23 #include "mac_sch_interface.h"
24 #include "lwr_mac_upr_inf.h"
25 #include "mac.h"
26 #include "mac_utils.h"
27
28 /* Function pointer for sending RACH resource response from MAC to DU APP */
29 MacDuRachRsrcRspFunc macDuRachRsrcRspOpts[] =
30 {
31    packDuMacRachRsrcRsp,   /* packing for loosely coupled */
32    DuProcMacRachRsrcRsp,   /* packing for tightly coupled */
33    packDuMacRachRsrcRsp    /* packing for light weight loosly coupled */
34 };
35
36 /*******************************************************************
37  *
38  * @brief Sends RACH indication to SCH
39  *
40  * @details
41  *
42  *    Function : sendRachIndMacToSch
43  *
44  *    Functionality:
45  *     Sends RACH indication to SCH
46  *
47  * @params[in] RACH indication info
48  * @return ROK     - success
49  *         RFAILED - failure
50  *
51  * ****************************************************************/
52 uint8_t sendRachIndMacToSch(RachIndInfo *rachInd)
53 {
54    Pst pst;
55
56    FILL_PST_MAC_TO_SCH(pst, EVENT_RACH_IND_TO_SCH);
57    return(SchMessageRouter(&pst, (void *)rachInd));
58 }
59
60 /*******************************************************************
61  *
62  * @brief Adds an entry in list of RA Cb and fills RACH ind info
63  *
64  * @details
65  *
66  *    Function : createMacRaCb
67  *
68  *    Functionality:
69  *     Adds an entry in list of RA Cb and fills RACH ind info
70  *
71  * @params[in] Pointer to cellCB,
72  *             Pointer to RACH Indication information
73  * @return ROK - SUCCESS
74  *         RFAILED - FAILURE
75  *
76  * ****************************************************************/
77 uint8_t createMacRaCb(MacCellCb *cellCb, RachIndInfo *rachIndInfo)
78 {
79    int8_t ueIdx = -1;
80    uint8_t  ssbIdx = 0;
81    uint16_t crnti = 0;
82    MacUeCb  *ueCb = NULLP;
83
84    /* Search if a UE CB is already present to which the incoming preamble index was dedicated */
85    for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++) 
86    {
87       /* Check if ueCb has a crnti alloted to it. If not, it means this ueIdx
88        * has no UE context stored in it, hence searching for preamble index in
89        * this ueCb is not required */
90       if(cellCb->ueCb[ueIdx].crnti)
91       {
92          for(ssbIdx = 0; ssbIdx < cellCb->ueCb[ueIdx].cfraResource.numSsb; ssbIdx++)
93          {
94             if(cellCb->ueCb[ueIdx].cfraResource.ssbResource[ssbIdx].raPreambleIdx == rachIndInfo->preambleIdx)
95             {
96                ueCb = &cellCb->ueCb[ueIdx];
97                break;
98             }
99          }
100          if(ueCb)
101             break;
102       }
103    }
104
105    if(ueCb)
106    {
107       /* If UE context is already present as in case of handover, fetch CRNTI from
108        * UE CB allocated during UE context creation */
109       crnti = ueCb->crnti;
110    }
111    else
112    {
113       /* If UE context not present, assign CRNTI to this UE */
114       ueIdx = getFreeBitFromUeBitMap(rachIndInfo->cellId);
115       if(ueIdx == -1)
116       {
117          DU_LOG("\nERROR  -->  MAC : Failed to find free UE Idx in UE bit map of cell Id [%d]", rachIndInfo->cellId);
118          return RFAILED;
119       }
120
121       /* Calculate CRNTI from UE Index */
122       GET_CRNTI(crnti, ueIdx+1);
123
124       /* Store in raCb */
125       memset(&cellCb->macRaCb[ueIdx], 0, sizeof(MacRaCbInfo));
126       cellCb->macRaCb[ueIdx].cellId = rachIndInfo->cellId;
127       cellCb->macRaCb[ueIdx].crnti  = crnti;
128
129      /* Initialize MSG4 HARQ PROC CB */
130      cellCb->macRaCb[ueIdx].msg4HqInfo.procId = MAX_NUM_HARQ_PROC;
131
132    }
133
134    /* Store in Rach Indication message to be sent to SCH */
135    rachIndInfo->crnti  = crnti;
136    return ROK;
137 }
138
139 /*******************************************************************
140  *
141  * @brief Processes RACH indication from PHY
142  *
143  * @details
144  *
145  *    Function : fapiMacRachInd
146  *
147  *    Functionality:
148  *      Processes RACH indication from PHY
149  *
150  * @params[in] Post structure
151  *             Rach indication message
152  * @return ROK     - success
153  *         RFAILED - failure
154  *
155  * ****************************************************************/ 
156 uint8_t fapiMacRachInd(Pst *pst, RachInd *rachInd)
157 {
158    uint8_t      ret = ROK;
159    uint8_t      pduIdx = 0;
160    uint8_t      preambleIdx = 0;
161    uint16_t     cellIdx = 0;  
162    RachIndInfo  *rachIndInfo = NULLP;
163    MacCellCb    *cellCb = NULLP;
164
165    DU_LOG("\nINFO  -->  MAC : Received RACH indication");
166    /* Considering one pdu and one preamble */
167    pduIdx = 0;
168    preambleIdx = 0;
169
170    /* Validate cell Id */
171    GET_CELL_IDX(rachInd->cellId, cellIdx);
172    if(macCb.macCell[cellIdx] && (macCb.macCell[cellIdx]->cellId == rachInd->cellId))
173          cellCb = macCb.macCell[cellIdx];
174
175    if(!cellCb)
176    {
177       DU_LOG("\nERROR  --> MAC : Invalid Cell ID [%d] received in RACH Indication", rachInd->cellId);
178       return RFAILED;
179    }
180
181    MAC_ALLOC(rachIndInfo, sizeof(RachIndInfo));
182    if(!rachIndInfo)
183    {
184       DU_LOG("\nERROR  --> MAC : Memory allocation failure in fapiMacRachInd");
185       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, rachInd, sizeof(RachInd));
186       return RFAILED;
187    }
188
189    rachIndInfo->cellId = rachInd->cellId;
190    rachIndInfo->timingInfo.sfn = rachInd->timingInfo.sfn;
191    rachIndInfo->timingInfo.slot = rachInd->timingInfo.slot;
192    rachIndInfo->slotIdx = rachInd->rachPdu[pduIdx].slotIdx;
193    rachIndInfo->symbolIdx = rachInd->rachPdu[pduIdx].symbolIdx;
194    rachIndInfo->freqIdx = rachInd->rachPdu[pduIdx].freqIdx;
195    rachIndInfo->preambleIdx = rachInd->rachPdu[pduIdx].preamInfo[preambleIdx].preamIdx;
196    rachIndInfo->timingAdv = rachInd->rachPdu[pduIdx].preamInfo[preambleIdx].timingAdv;
197
198    /* Store the value in macRaCb */
199    if((ret = createMacRaCb(cellCb, rachIndInfo)) == ROK)
200    {
201       /* Send RACH Indication to SCH */
202       ret = sendRachIndMacToSch(rachIndInfo);
203    }
204
205    /* Free sharable buffer used to send RACH Indication from lower MAC to MAC */
206    MAC_FREE_SHRABL_BUF(pst->region, pst->pool, rachInd, sizeof(RachInd));
207
208    return ret;
209 }
210
211 /*******************************************************************
212  *
213  * @brief Processes RACH Resource request from DU APP
214  *
215  * @details
216  *
217  *    Function : MacProcRachRsrcReq
218  *
219  *    Functionality: Processes RACH resource request from DU APP.
220  *      Fills and sends RACH resource request towards SCH.
221  *
222  * @params[in] Post structure
223  *             RACH resource request
224  * @return ROK     - success
225  *         RFAILED - failure
226  *
227  * ****************************************************************/
228 uint8_t MacProcRachRsrcReq(Pst *pst, MacRachRsrcReq *rachRsrcReq)
229 {
230    uint8_t   ret = RFAILED;
231    uint16_t  cellIdx = 0;
232    Pst       schPst;
233    MacCellCb *cellCb = NULLP;
234    MacUeCb   *ueCb = NULLP;
235    SchRachRsrcReq *schRachRsrcReq = NULLP;
236
237    DU_LOG("\nINFO  -->  MAC : Recieved RACH Resource Request for Cell ID [%d] UE ID [%d]",\
238          rachRsrcReq->cellId, rachRsrcReq->ueId);
239
240    /* Fetch Cell Cb */
241    GET_CELL_IDX(rachRsrcReq->cellId, cellIdx);
242    if(macCb.macCell[cellIdx] && (macCb.macCell[cellIdx]->cellId == rachRsrcReq->cellId))
243    {
244       cellCb = macCb.macCell[cellIdx];
245
246       /* Fetch UE Cb */
247       if(cellCb->ueCb[rachRsrcReq->ueId-1].ueId == rachRsrcReq->ueId)
248       {
249          ueCb = &cellCb->ueCb[rachRsrcReq->ueId-1];
250          /* Allocate memory to RACH resource request to be sent to SCH */
251          MAC_ALLOC(schRachRsrcReq, sizeof(SchRachRsrcReq));
252          if(schRachRsrcReq)
253          {
254             /* Fill SCH RACH resource request from information received from DU APP to MAC */
255             schRachRsrcReq->cellId = rachRsrcReq->cellId;
256             schRachRsrcReq->crnti = ueCb->crnti;
257             schRachRsrcReq->numSsb = rachRsrcReq->numSsb;
258             memcpy(schRachRsrcReq->ssbIdx, rachRsrcReq->ssbIdx, sizeof(schRachRsrcReq->ssbIdx));
259
260             /* Send RACH resource request from MAC to SCH */
261             FILL_PST_MAC_TO_SCH(schPst, EVENT_RACH_RESOURCE_REQUEST_TO_SCH);
262             ret = SchMessageRouter(&schPst, (void *)schRachRsrcReq);
263          }
264          else
265             DU_LOG("\nERROR  -->  MAC : Memory allocation failed for RACH resource request to SCH");
266       }
267       else
268          DU_LOG("\nERROR  -->  MAC : UE ID [%d] not found", rachRsrcReq->ueId);
269    }
270    else
271       DU_LOG("\nERROR  -->  MAC : Cell ID [%d] not found", rachRsrcReq->cellId);
272
273    /* Free sharable buffer used to send RACH reource request from DU APP to MAC */
274    MAC_FREE_SHRABL_BUF(pst->region, pst->pool, rachRsrcReq, sizeof(MacRachRsrcReq));
275    return ret;
276 }
277
278 /*******************************************************************
279  *
280  * @brief Processes RACH Resource response from SCH
281  *
282  * @details
283  *
284  *    Function : MacProcSchRachRsrcRsp
285  *
286  *    Functionality: Processes RACH resource response from SCH
287  *      Fills and sends RACH resource response towards DU APP
288  *
289  * @params[in] Post structure
290  *             RACH resource response
291  * @return ROK     - success
292  *         RFAILED - failure
293  *
294  * ****************************************************************/
295 uint8_t MacProcSchRachRsrcRsp(Pst *pst, SchRachRsrcRsp *schRachRsrcRsp)
296 {
297    uint16_t cellIdx = 0;
298    Pst rspPst;
299    MacRachRsrcRsp *rachRsrcRsp = NULLP;
300    MacCellCb *cellCb = NULLP;
301    MacUeCb   *ueCb = NULLP;
302
303    DU_LOG("\nINFO  -->  MAC : Received RACH resource response from SCH : Cell ID [%d] CRNTI [%d]", \
304          schRachRsrcRsp->cellId, schRachRsrcRsp->crnti);
305
306    /* Fill RACH resource response to send to DU APP */
307    MAC_ALLOC_SHRABL_BUF(rachRsrcRsp, sizeof(MacRachRsrcRsp));
308    if(!rachRsrcRsp)
309    {
310       DU_LOG("\nERROR  -->  MAC : Memory allocation failed for RACH resource response");
311       MAC_FREE(schRachRsrcRsp, sizeof(SchRachRsrcRsp));
312       return RFAILED;
313    }
314    rachRsrcRsp->cellId = schRachRsrcRsp->cellId;
315    GET_UE_ID(schRachRsrcRsp->crnti, rachRsrcRsp->ueId);
316    rachRsrcRsp->result = MAC_DU_APP_RSP_OK;
317
318    /* Fill Pst structure to send RACH resource response from MAC to DU APP */
319    FILL_PST_MAC_TO_DUAPP(rspPst, EVENT_MAC_RACH_RESOURCE_RSP);
320
321    /* If negative response is received from SCH, send it further to DU APP */ 
322    if(schRachRsrcRsp->result == RSP_NOK)
323    {
324       DU_LOG("\nINFO  -->  MAC : RACH Resource response from SCH : Result [FAILURE]");
325       rachRsrcRsp->result = MAC_DU_APP_RSP_NOK;
326    }
327    else
328    {
329       DU_LOG("\nINFO  -->  MAC : RACH Resource response from SCH : Result [SUCCESS]");
330       
331       /* Fetch Cell Cb */
332       GET_CELL_IDX(schRachRsrcRsp->cellId, cellIdx);
333       if(macCb.macCell[cellIdx] && (macCb.macCell[cellIdx]->cellId == schRachRsrcRsp->cellId))
334       {   
335          cellCb = macCb.macCell[cellIdx];
336
337          /* Fetch UE Cb */
338          if(cellCb->ueCb[rachRsrcRsp->ueId-1].crnti == schRachRsrcRsp->crnti)
339             ueCb = &cellCb->ueCb[rachRsrcRsp->ueId-1];
340          else
341          {
342             DU_LOG("\nERROR  -->  MAC : CRNTI [%d] not found", schRachRsrcRsp->crnti);
343             rachRsrcRsp->result = MAC_DU_APP_RSP_NOK;
344          }   
345       }   
346       else
347       {   
348          DU_LOG("\nERROR  -->  MAC : Cell ID [%d] not found", schRachRsrcRsp->cellId);
349          rachRsrcRsp->result = MAC_DU_APP_RSP_NOK;
350       }   
351    }
352
353    /* Fill SSB RACH resource info if SCH has sent a positive response and 
354     * processing of SCH RACH resource response at MAC has been successful so far */
355    if(rachRsrcRsp->result == MAC_DU_APP_RSP_OK)
356    {
357       rachRsrcRsp->newCrnti = ueCb->crnti; 
358       rachRsrcRsp->cfraResource.numSsb = schRachRsrcRsp->cfraResource.numSsb;
359       memcpy(rachRsrcRsp->cfraResource.ssbResource, schRachRsrcRsp->cfraResource.ssbResource, \
360          rachRsrcRsp->cfraResource.numSsb * sizeof(MacCfraSsbResource));
361
362       /* Copy resources to UE CB in MAC */
363       memcpy(&ueCb->cfraResource, &rachRsrcRsp->cfraResource, sizeof(MacCfraResource));
364    }
365
366    /* Free SCH RACH resource response */
367    MAC_FREE(schRachRsrcRsp, sizeof(SchRachRsrcRsp));
368
369    /* Send RACH resource response to DU APP */
370    FILL_PST_MAC_TO_DUAPP(rspPst, EVENT_MAC_RACH_RESOURCE_RSP);
371    return (*macDuRachRsrcRspOpts[rspPst.selector])(&rspPst, rachRsrcRsp);
372 }
373
374
375 /*******************************************************************
376  *
377  * @brief Processes RACH Resource release from DU APP
378  *
379  * @details
380  *
381  *    Function : MacProcRachRsrcRel
382  *
383  *    Functionality: Processes RACH resource release from DU APP.
384  *      Fills and sends RACH resource release towards SCH.
385  *
386  * @params[in] Post structure
387  *             RACH resource release
388  * @return ROK     - success
389  *         RFAILED - failure
390  *
391  * ****************************************************************/
392 uint8_t MacProcRachRsrcRel(Pst *pst, MacRachRsrcRel *rachRsrcRel)
393 {
394    uint8_t   ret = RFAILED;
395    uint16_t  cellIdx = 0;
396    Pst       schPst;
397    MacCellCb *cellCb = NULLP;
398    MacUeCb   *ueCb = NULLP;
399    SchRachRsrcRel *schRachRsrcRel = NULLP;
400
401    DU_LOG("\nINFO  -->  MAC : Recieved RACH Resource Release for Cell ID [%d] UE ID [%d]",\
402          rachRsrcRel->cellId, rachRsrcRel->ueId);
403
404    /* Fetch Cell Cb */
405    GET_CELL_IDX(rachRsrcRel->cellId, cellIdx);
406    if(macCb.macCell[cellIdx] && (macCb.macCell[cellIdx]->cellId == rachRsrcRel->cellId))
407    {
408       cellCb = macCb.macCell[cellIdx];
409
410       /* Fetch UE Cb */
411       if(cellCb->ueCb[rachRsrcRel->ueId-1].ueId == rachRsrcRel->ueId)
412       {
413          ueCb = &cellCb->ueCb[rachRsrcRel->ueId-1];
414          /* Allocate memory to RACH resource release to be sent to SCH */
415          MAC_ALLOC(schRachRsrcRel, sizeof(SchRachRsrcRel));
416          if(schRachRsrcRel)
417          {
418             /* Fill SCH RACH resource release from information received from DU APP to MAC */
419             memset(schRachRsrcRel, 0, sizeof(SchRachRsrcRel));
420             schRachRsrcRel->cellId = rachRsrcRel->cellId;
421             schRachRsrcRel->crnti = ueCb->crnti;
422             memcpy(&schRachRsrcRel->cfraResource, &ueCb->cfraResource, sizeof(schRachRsrcRel->cfraResource));
423             
424             /* Release RACH resources at MAC */
425             memset(&ueCb->cfraResource, 0, sizeof(MacCfraResource));
426
427             /* Send RACH resource release from MAC to SCH */
428             FILL_PST_MAC_TO_SCH(schPst, EVENT_RACH_RESOURCE_RELEASE_TO_SCH);
429             ret = SchMessageRouter(&schPst, (void *)schRachRsrcRel);
430          }
431          else
432             DU_LOG("\nERROR  -->  MAC : Memory allocation failed for RACH resource release to SCH");
433       }
434       else
435          DU_LOG("\nERROR  -->  MAC : UE ID [%d] not found", rachRsrcRel->ueId);
436    }
437    else
438       DU_LOG("\nERROR  -->  MAC : Cell ID [%d] not found", rachRsrcRel->cellId);
439
440    /* Free sharable buffer used to send RACH reource release from DU APP to MAC */
441    MAC_FREE_SHRABL_BUF(pst->region, pst->pool, rachRsrcRel, sizeof(MacRachRsrcRel));
442    return ret;
443 }
444
445 /* spec-38.211 Table 6.3.3.1-7 */
446 uint8_t UnrestrictedSetNcsTable[MAX_ZERO_CORR_CFG_IDX] = 
447 {0, 2, 4, 6, 8, 10, 12, 13, 15, 17, 19, 23, 27, 34, 46, 69};
448
449 /*******************************************************************
450  *
451  * @brief Processes UL scheduling info from SCH
452  *
453  * @details
454  *
455  *    Function : MacProcUlSchInfo
456  *
457  *    Functionality: Processes UL scheduling info from SCH
458  *
459  * @params[in] Post structure
460  *             UL scheduling info
461  * @return ROK     - success
462  *         RFAILED - failure
463  *
464  * ****************************************************************/
465 uint8_t MacProcUlSchInfo(Pst *pst, UlSchedInfo *ulSchedInfo)
466 {
467    uint16_t  cellIdx;
468
469 #ifdef CALL_FLOW_DEBUG_LOG
470    DU_LOG("\nCall Flow: ENTSCH -> ENTMAC : EVENT_UL_SCH_INFO\n");
471 #endif
472
473    GET_CELL_IDX(ulSchedInfo->cellId, cellIdx);
474    if(ulSchedInfo != NULLP)
475    {
476       MacUlSlot *currUlSlot = 
477          &macCb.macCell[cellIdx]->ulSlot[ulSchedInfo->slotIndInfo.slot % macCb.macCell[cellIdx]->numOfSlots];
478       memcpy(&currUlSlot->ulInfo, ulSchedInfo, sizeof(UlSchedInfo)); 
479    }
480    return ROK;
481 }
482
483 /**********************************************************************
484   End of file
485  **********************************************************************/
486