E2AP code changes
[o-du/l2.git] / src / du_app / du_cell_mgr.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
19 /* This file contains message handling functionality for DU APP */
20 #include "du_cell_mgr.h"
21 #include "du_cfg.h"
22 #include "PLMN-Identity.h"
23 #include "RICeventTriggerDefinition.h"
24
25 extern DuCfgParams duCfgParam;
26
27 extern S16 cmPkRgrCfgReq(Pst* pst, RgrCfgTransId transId, \
28       RgrCfgReqInfo *cfgReqInfo);
29
30 extern S16 duBuildAndSendMacCellCfg();
31
32 /*******************************************************************
33  *
34  * @brief Processes cells to be activated
35  *
36  * @details
37  *
38  *    Function : procCellsToBeActivated
39  *
40  *    Functionality:
41  *      - Processes cells to be activated list received in F1SetupRsp
42  *
43  * @params[in] void
44  * @return ROK     - success
45  *         RFAILED - failure
46  *
47  * ****************************************************************/
48 S16 procCellsToBeActivated(Cells_to_be_Activated_List_t cellsToActivate)
49 {
50    U16 idx;
51    S16 ret;
52
53    for(idx=0; idx<cellsToActivate.list.count; idx++)
54    {
55       U16 nci;
56       U16 pci;
57       DuCellCb *cellCb = NULLP;
58
59       Cells_to_be_Activated_List_Item_t cell = cellsToActivate.list.array[idx]->\
60           value.choice.Cells_to_be_Activated_List_Item;
61
62       bitStringToInt(&cell.nRCGI.nRCellIdentity, &nci);
63       if(cell.nRPCI)
64       {
65          pci = *cell.nRPCI;
66       }
67       if(ROK != (cmHashListFind(&(duCb.cellLst), (U8*) &nci, sizeof(nci),
68                   0, (PTR*)cellCb)))
69       {
70          return RFAILED;
71       }
72       if(!cellCb)
73       {
74                         DU_LOG("\nDU_APP : HashList Find failed for nci [%d]", nci);
75          return RFAILED;
76       }
77       cellCb->cellStatus = ACTIVATION_IN_PROGRESS; 
78       cellCb->cellInfo.nrPci = pci;
79
80       /* Now remove this cell from configured list and move to active list */
81       ret = cmHashListDelete(&(duCb.actvCellLst), (PTR)(cellCb)); 
82       if(ret != ROK)
83       {
84          DU_LOG("\nDU_APP : HashListInsert into ActvCellLst failed for [%d]", nci);
85       }
86       ret = cmHashListInsert(&(duCb.actvCellLst), (PTR)(cellCb), 
87             (U8 *)&(nci), (U16) sizeof(nci));
88
89       if(ret != ROK)
90       {
91          DU_LOG("\nDU_APP : HashListInsert into ActvCellLst failed for [%d]", nci);
92          break;
93       }
94       else
95       {
96          DU_LOG("\nDU_APP : HashListInsert into ActvCellLst successful for [%d]", nci);
97       }
98    }
99
100    /* Start sending scheduler config */
101    if(ret == ROK)
102    {
103       //TODO: uncomment later duSendSchGnbCfg(); 
104    }
105
106    return ROK;
107 }
108
109 /******************************************************************
110 *
111 * @brief Processes E2 Setup Response sent by RIC
112 *
113 * @details
114 *
115 *    Function : procE2SetupRsp
116 *
117 *    Functionality: Processes E2 Setup Response sent by RIC
118 *
119 * @params[in] E2AP_PDU_t ASN decoded E2AP message
120 * @return ROK     - success
121 *         RFAILED - failure
122 *
123 * ****************************************************************/
124 S16 procE2SetupRsp(E2AP_PDU_t *e2apMsg)
125 {
126    E2setupResponse_t *e2SetRspMsg;
127    E2apMsgDb e2SetupRspDb;
128    U8 idx; 
129
130    DU_LOG("\nE2AP : E2 Setup Response received"); 
131    duCb.e2Status = TRUE; //Set E2 status as true
132    e2SetRspMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
133
134    for(idx=0; idx<e2SetRspMsg->protocolIEs.list.count; idx++)
135    {
136       switch(e2SetRspMsg->protocolIEs.list.array[idx]->id)
137       {
138          case ProtocolIE_IDE2_id_GlobalRIC_ID:
139          {
140             /* To store the Ric Id Params */
141             U32 recvBufLen;             
142             memset(&e2SetupRspDb.plmn, 0, sizeof(PLMN_IdentityE2_t));
143
144             recvBufLen = sizeof(e2SetRspMsg->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID.pLMN_Identity);
145
146             bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID.ric_ID, &e2SetupRspDb.ricId);
147             
148             aper_decode(0, &asn_DEF_PLMN_IdentityE2, (void **)&e2SetupRspDb.plmn, &e2SetRspMsg->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID.pLMN_Identity, recvBufLen, 0, 0);
149             //xer_fprint(stdout, &asn_DEF_PLMN_IdentityE2, &e2SetupRspDb.plmn);
150
151             break;
152          }
153          default:
154             DU_LOG("\nE2AP : Invalid IE received in E2SetupRsp:%ld",
155                   e2SetRspMsg->protocolIEs.list.array[idx]->id);
156             break;
157       }
158    }
159    RETVALUE(ROK);
160 }
161
162 /******************************************************************
163 *
164 * @brief Processes RIC Subscription Req sent by RIC
165 *
166 * @details
167 *
168 *    Function : procRicSubsReq
169 *
170 *    Functionality: Processes E2 Setup Response sent by CU
171 *
172 * @params[in] E2AP_PDU_t ASN decoded E2AP message
173 * @return ROK     - success
174 *         RFAILED - failure
175 *
176 * ****************************************************************/
177
178 S16 procRicSubsReq(E2AP_PDU_t *e2apMsg)
179 {
180    S16 ret = ROK;
181    U8 idx; 
182    U8 ied; 
183    RICsubscriptionRequest_t *ricSubsReq;
184    RICaction_ToBeSetup_ItemIEs_t *actionItem;
185    E2apMsgDb ricReqDb;
186   
187    DU_LOG("\nE2AP : Ric Subscription request received"); 
188    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
189
190    for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
191    {
192       switch(ricSubsReq->protocolIEs.list.array[idx]->id)
193       {
194          case ProtocolIE_IDE2_id_RICrequestID:
195          {
196             ricReqDb.ricReqId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID;
197             ricReqDb.ricInstanceId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID;
198             break;
199          }
200          case ProtocolIE_IDE2_id_RANfunctionID:
201          {
202             ricReqDb.ranFuncId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID; 
203             break;
204          }
205          case ProtocolIE_IDE2_id_RICsubscriptionDetails:
206          {
207             U32 recvBufLen;             
208             memset(&ricReqDb.ricEventTrigger, 0, sizeof(RICeventTriggerDefinition_t));
209
210             recvBufLen = sizeof(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricEventTriggerDefinition);
211
212             aper_decode(0, &asn_DEF_RICeventTriggerDefinition, (void **)&ricReqDb.ricEventTrigger, &(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricEventTriggerDefinition), recvBufLen, 0, 0);
213             //xer_fprint(stdout, &asn_DEF_RICeventTriggerDefinition, &ricReqDb.ricEventTrigger);
214
215             actionItem = *ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.list.array;
216             
217             for(ied = 0; ied < ricSubsReq->protocolIEs.list.array[idx]->value.choice.\
218                                 RICsubscriptionDetails.ricAction_ToBeSetup_List.list.count; ied++)
219             {
220                switch(actionItem->id)
221                {
222                   case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
223                   {
224                      ricReqDb.ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
225                      ricReqDb.ricActionType = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType;
226                      break;
227                   }
228                   default:
229                      DU_LOG("\nE2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
230                   break;
231                }
232             }
233  
234             break;
235          }
236
237          default:
238             DU_LOG("\nE2AP : Invalid IE received in Ric SubsReq:%ld",
239                   ricSubsReq->protocolIEs.list.array[idx]->id);
240             break;
241       }
242    }
243    ret = BuildAndSendRicSubscriptionRsp();
244
245    RETVALUE(ret);
246 }
247
248 /******************************************************************
249 *
250 * @brief Processes F1 Setup Response sent by CU
251 *
252 * @details
253 *
254 *    Function : procF1SetupRsp
255 *
256 *    Functionality: Processes F1 Setup Response sent by CU
257 *
258 * @params[in] F1AP_PDU_t ASN decoded F1AP message
259 * @return ROK     - success
260 *         RFAILED - failure
261 *
262 * ****************************************************************/
263 S16 procF1SetupRsp(F1AP_PDU_t *f1apMsg)
264 {
265    S16 ret = ROK;
266
267    F1SetupResponse_t *f1SetRspMsg;
268    F1SetupRsp    f1SetRspDb;
269    GNB_CU_Name_t *cuName;
270    RRC_Version_t *rrc_Ver;
271    U16 idx;
272
273    DU_LOG("\nDU_APP : F1 Setup Response received"); 
274         printf("\nDU_APP : F1 Setup Response received");
275    duCb.f1Status = TRUE; //Set F1 status as true
276    f1SetRspMsg = &f1apMsg->choice.successfulOutcome->value.choice.F1SetupResponse;
277
278    for(idx=0; idx<f1SetRspMsg->protocolIEs.list.count; idx++)
279    {
280 //      F1SetupResponseIEs_t f1RspIe = f1SetRspMsg->protocolIEs.list.array[idx];
281       switch(f1SetRspMsg->protocolIEs.list.array[idx]->id)
282       {
283          case ProtocolIE_ID_id_Cells_to_be_Activated_List:
284          {
285             procCellsToBeActivated(f1SetRspMsg->protocolIEs.list.array[idx]->\
286                   value.choice.Cells_to_be_Activated_List);
287             break;
288          }
289          //TODO: where to store and how to use below variables?can they be skipped
290          case ProtocolIE_ID_id_TransactionID:
291          {
292             f1SetRspDb.transId = f1SetRspMsg->protocolIEs.list.array[idx]->\
293                                  value.choice.TransactionID;
294             break;
295          }
296          case ProtocolIE_ID_id_gNB_CU_Name:
297          {
298             cuName = &f1SetRspMsg->protocolIEs.list.array[idx]->\
299                      value.choice.GNB_CU_Name;
300             strcpy(f1SetRspDb.cuName, (const char*)cuName->buf);
301             break;
302          }
303          case ProtocolIE_ID_id_GNB_CU_RRC_Version:
304          {
305             rrc_Ver = &f1SetRspMsg->protocolIEs.list.array[idx]->\
306                       value.choice.RRC_Version;
307             strcpy(f1SetRspDb.rrcVersion.rrcVer,
308                   (const char*)rrc_Ver->latest_RRC_Version.buf);
309             break;
310          }
311          default:
312             DU_LOG("\nDU_APP : Invalid IE received in F1SetupRsp:%ld",
313                   f1SetRspMsg->protocolIEs.list.array[idx]->id);
314       }
315    }
316  
317    /* TODO :Check the deallocation */
318 #if 0
319    SPutSBuf(DU_APP_MEM_REGION, DU_POOL,(Data *)&(f1SetupRsp->protocolIEs.list.array),\
320          (Size)elementCnt * sizeof(F1SetupResponseIEs_t *));
321    SPutSBuf(DU_APP_MEM_REGION, DU_POOL,(Data *)&(f1apMsg->choice.successfulOutcome),\
322          (Size)sizeof(SuccessfulOutcome_t));
323    SPutSBuf(DU_APP_MEM_REGION, DU_POOL,(Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
324 #endif
325  
326    /* Build and send Mac Cell Cfg Paramaters */
327    //ret = duBuildAndSendMacCellCfg();
328    ret = BuildAndSendDUConfigUpdate();
329
330    return ret;
331 }
332
333 /******************************************************************
334 *
335 * @brief Send gNB cfg to scheduler via MAC
336 *
337 * @details
338 *
339 *    Function : duSendSchGnbCfg
340 *
341 *    Functionality: Send gNB cfg to scheduler via MAC
342 *
343 * @return ROK     - success
344 *         RFAILED - failure
345 *
346 * ****************************************************************/
347 S16 duSendSchGnbCfg()
348 {
349
350    RgrCfgReqInfo  *cfgReq = NULLP;
351    MacSchedGnbCfg *cfg = NULLP;
352    U32 transId = 1;
353
354    DU_ALLOC(cfgReq, sizeof(RgrCfgReqInfo));
355    if( cfgReq == NULLP)
356    {
357       DU_LOG("\nDU_APP : Mem allocation failed in duSendSchGnbCfg");
358       return RFAILED;
359    }
360
361    cfgReq->action = SCH_CONFIG;
362    cfgReq->u.cfgInfo.cfgType = MAC_GNB_CFG;
363    cfg = &(cfgReq->u.cfgInfo.u.schedGnbCfg);
364    cfg->numTxAntPorts = duCfgParam.schedCfg.numTxAntPorts;
365    cfg->ulSchdType = duCfgParam.schedCfg.ulSchdType;
366    cfg->dlSchdType = duCfgParam.schedCfg.dlSchdType;
367    cfg->numCells = duCfgParam.schedCfg.numCells;
368    cfg->maxUlUePerTti = duCfgParam.schedCfg.maxUlUePerTti;
369    cfg->maxDlUePerTti = duCfgParam.schedCfg.maxDlUePerTti;
370
371    if(ROK != duSendSchGnbCfgToMac(cfgReq, transId))
372    {
373       return RFAILED;
374    }
375
376    return ROK;
377 }
378
379 /******************************************************************
380 *
381 * @brief Send gNB cfg to scheduler via MAC
382 *
383 * @details
384 *
385 *    Function : duSendSchGnbCfgToMac 
386 *
387 *    Functionality: Send gNB cfg to scheduler via MAC
388 *
389 * @return ROK     - success
390 *         RFAILED - failure
391 *
392 * ****************************************************************/
393 S16 duSendSchGnbCfgToMac(RgrCfgReqInfo *cfgReq, U32 trans_id)
394 {
395    RgrCfgTransId transId;
396    Pst pst;
397
398    DU_SET_ZERO(&pst, sizeof(Pst));
399    DU_SET_ZERO(&transId, sizeof(RgrCfgTransId));
400
401    transId.trans[0] = MAC_GNB_CFG;
402    transId.trans[1] = cfgReq->action;
403    transId.trans[7] = trans_id & 0x000000ff; trans_id >>= 8;
404    transId.trans[6] = trans_id & 0x000000ff; trans_id >>= 8;
405    transId.trans[5] = trans_id & 0x000000ff; trans_id >>= 8;
406    transId.trans[4] = trans_id & 0x000000ff; trans_id >>= 8;
407
408    pst.selector  = DU_SELECTOR_LC;
409    pst.srcEnt    = ENTDUAPP;
410    pst.dstEnt    = ENTRG;
411    pst.dstInst   = (Inst)0;
412    pst.dstProcId = DU_PROC;
413    pst.srcProcId = DU_PROC;
414    pst.region    = duCb.init.region;
415    pst.event     = (Event) EVTMACSCHCFGREQ;
416
417    cmPkRgrCfgReq(&pst, transId, cfgReq);
418
419    return ROK;
420 }
421
422 /**********************************************************************
423   End of file
424  **********************************************************************/