62a2fb92c546833400ed952bf0e066f95a979d16
[o-du/l2.git] / src / o1 / NrCellDuCb.cpp
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2020-2021] [HCL Technologies Ltd.]                          #
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 NrCellDu get and update handler . It handles
20    get and change callback for NrCellDu yang module  */
21
22 #include <sstream>
23 #include "NrCellDuCb.hpp"
24 #include "NrCellInfo.hpp"
25 #include "NrCellList.hpp"
26
27 #define XPATH_MAX_LEN 256
28 #define MAX_PLMN_MEMBER 4
29
30 using namespace std;
31
32 //Global variable
33 NRCellDU cellParams;
34 ManagedElement managedElement;
35 int plmnListNum = 0;
36
37 /*******************************************************************
38  *
39  * @brief override oper_get_items to handle callback
40  *
41  * @details
42  *
43  *    Function : oper_get_items
44  *
45  *    Functionality:
46  *      - override oper_get_items to handle callback
47  *
48  *
49  * @params[in] sysrepo::S_Session session, const char *module_name,
50  *             const char *path, const char *request_xpath,
51  *             uint32_t request_id, libyang::S_Data_Node &parent,
52  *             void *private_data
53  * @return SR_ERR_OK/SR_ERR_NOK
54  ******************************************************************/
55
56 int NrCellDuCb::oper_get_items(sysrepo::S_Session session, \
57                                        const char *module_name, \
58                                        const char *path, \
59                                        const char *request_xpath, \
60                                        uint32_t request_id, \
61                                        libyang::S_Data_Node &parent, \
62                                        void *private_data)
63 {
64    O1_LOG("\nO1 NrCellCb : Callback called for path=%s on get request", path);
65    libyang::S_Context ctx = session->get_context();
66    libyang::S_Module modMe = ctx->get_module(module_name);
67
68    //first create root of the tree then add nodes and leaves and fill data
69    parent.reset(new libyang::Data_Node(ctx, MANAGED_ELEMENT_MODULE_PATH, \
70                 nullptr, LYD_ANYDATA_CONSTSTRING, 0));
71    libyang::S_Data_Node id(new libyang::Data_Node(parent, modMe, "id", \
72                   managedElement.meId));
73    libyang::S_Module modGnbdu = ctx->get_module(GNB_DU_FUNTION_MODULE_NAME);
74    libyang::S_Data_Node gnbdu(new libyang::Data_Node(parent, modGnbdu, \
75                                   "GNBDUFunction"));
76    libyang::S_Data_Node id1 (new libyang::Data_Node(gnbdu, modGnbdu, "id", \
77                   managedElement.gnbId));
78    libyang::S_Module mod = ctx->get_module(NR_CELL_DU_MODULE_NAME);
79    libyang::S_Data_Node nrCellDu(new libyang::Data_Node(gnbdu, mod, \
80                                   "NRCellDU"));
81    id.reset(new libyang::Data_Node(nrCellDu, mod, "id", \
82                   managedElement.nrCellDuId));
83    libyang::S_Data_Node attributes(new libyang::Data_Node(nrCellDu, mod, \
84                                   "attributes"));
85
86    libyang::S_Data_Node name;
87    libyang::S_Data_Node operational_state;
88    libyang::S_Data_Node cell_state;
89    libyang::S_Data_Node administrative_state;
90
91    NrCellList & cellList  = NrCellList::instance();
92    NrCellInfo cellInfo;
93    const NrCellList::CellOpStateMap & cellOpStateMap = cellList.getCellOpStateList();
94    //read the data from CellOpStateMap
95    std::map<uint16_t, NrCellInfo>::const_iterator it;
96    for(it = cellOpStateMap.begin(); it !=cellOpStateMap.end(); it++)
97    {
98       O1_LOG("\nO1 NrCellCb : cellId = %d, opState=%d, cellState=%d", \
99               it->first, (int) it->second.getOpState(), (int) it->second.getCellState());
100       operational_state.reset(new libyang::Data_Node(attributes, mod, \
101                         "operationalState", \
102                         cellInfo.enumToOperationalStateString(it->second.getOpState()).c_str()));
103       cell_state.reset(new libyang::Data_Node(attributes, mod, "cellState", \
104                        cellInfo.enumToCellStateString(it->second.getCellState()).c_str()));
105    }
106    return SR_ERR_OK;
107 }
108
109 /*******************************************************************
110  *
111  * @brief convert administrative state string to enum
112  *
113  * @details
114  *
115  *    Function : administrativeStateToEnum
116  *
117  *    Functionality:
118  *      - convert administrative state string to enum
119  *
120  *
121  * @params[in] string AdminState
122  * @return Enum AdminState
123  ******************************************************************/
124
125 AdminState NrCellDuCb::administrativeStateToEnum(string &val)
126 {
127    AdminState state;
128    if (val=="LOCKED") {
129       state = LOCKED;
130    }
131    else if(val=="UNLOCKED") {
132       state = UNLOCKED;
133    }
134    else if(val=="SHUTTING_DOWN") {
135       state = SHUTTING_DOWN;
136    }
137    return state;
138 }
139
140 /*******************************************************************
141  *
142  * @brief fill the parameters value into the structure instance
143  *
144  * @details
145  *
146  *    Function : updateParams
147  *
148  *    Functionality:
149  *      - fill the parameters value into the structure instance
150  *
151  *
152  * @params[in] string leaf, string val
153  * @return void
154  ******************************************************************/
155
156
157 void NrCellDuCb::updateParams(string &parent, string &leaf, string &val)
158 {
159    int memberNum = plmnListNum/MAX_PLMN_MEMBER;
160    if(parent.find("attribute") != string::npos)
161    {
162       if(leaf == "cellLocalId"){
163          cellParams.cellLocalId = atoi(val.c_str());
164          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.cellLocalId);
165       }
166       else if(leaf == "administrativeState"){
167          cellParams.administrativeState = administrativeStateToEnum(val);
168          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.administrativeState);
169       }
170      else if(leaf == "nRPCI"){
171          cellParams.nRPCI = atoi(val.c_str());
172          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.nRPCI);
173       }
174       else if(leaf == "nRTAC"){
175          cellParams.nRTAC = atoi(val.c_str());
176          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.nRTAC);
177       }
178       else if(leaf == "arfcnDL"){
179          cellParams.arfcnDL = atoi(val.c_str());
180          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.arfcnDL);
181       }
182       else if(leaf == "arfcnUL"){
183          cellParams.arfcnUL = atoi(val.c_str());
184          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.arfcnUL);
185       }
186       else if(leaf == "arfcnSUL"){
187          cellParams.arfcnSUL = atoi(val.c_str());
188          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.arfcnSUL);
189       }
190       else if(leaf == "ssbFrequency"){
191          cellParams.ssbFrequency = atoi(val.c_str());
192          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.ssbFrequency);
193       }
194       else if(leaf == "ssbPeriodicity"){
195          cellParams.ssbPeriodicity = atoi(val.c_str());
196          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.ssbPeriodicity);
197       }
198       else if(leaf == "ssbSubCarrierSpacing"){
199          cellParams.ssbSubCarrierSpacing = atoi(val.c_str());
200          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.ssbSubCarrierSpacing);
201       }
202       else if(leaf == "ssbOffset"){
203          cellParams.ssbOffset = atoi(val.c_str());
204          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.ssbOffset);
205       }
206       else if(leaf == "ssbDuration"){
207          cellParams.ssbDuration = atoi(val.c_str());
208          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.ssbDuration);
209       }
210       else if(leaf == "bSChannelBwUL"){
211          cellParams.bSChannelBwUL = atoi(val.c_str());
212          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.bSChannelBwUL);
213       }
214       else if(leaf == "bSChannelBwDL"){
215          cellParams.bSChannelBwDL = atoi(val.c_str());
216          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.bSChannelBwDL);
217       }
218       else if(leaf == "bSChannelBwSUL"){
219          cellParams.bSChannelBwSUL = atoi(val.c_str());
220          O1_LOG("\nO1 NrCellDuCb : val = %d", cellParams.bSChannelBwSUL);
221       }
222    }
223    else if(parent.find("pLMNInfoList") != string::npos && memberNum < MAX_SUPPORTED_PLMN)
224    {
225          if(leaf == "mcc")
226          {
227             memset(cellParams.plmnList[memberNum].mcc, \
228                    '\0', MCC_LEN);
229             cellParams.plmnList[memberNum].mcc[0] = stoi(val.substr(0,1).c_str(),0,10);
230             cellParams.plmnList[memberNum].mcc[1] = stoi(val.substr(1,1).c_str(),0,10);
231             cellParams.plmnList[memberNum].mcc[2] = stoi(val.substr(2,1).c_str(),0,10);
232             O1_LOG("\nO1 NrCellDuCb : cellParams.plmnList[%d].mcc[2]  = %c",
233                    memberNum, cellParams.plmnList[memberNum].mcc[2]);
234          }
235          else if(leaf == "mnc")
236          {
237             memset(cellParams.plmnList[memberNum].mnc, \
238                    '\0', MNC_LEN);
239             cellParams.plmnList[memberNum].mnc[0] = stoi(val.substr(0,1).c_str(),0,10);
240             cellParams.plmnList[memberNum].mnc[1] = stoi(val.substr(1,1).c_str(),0,10);
241             cellParams.plmnList[memberNum].mnc[2] = stoi(val.substr(2,1).c_str(),0,10);
242             O1_LOG("\nO1 NrCellDuCb : cellParams.plmnList[%d].mnc[1]  = %c",
243                    memberNum, cellParams.plmnList[memberNum].mnc[1]);
244          }
245          else if(leaf == "sst")
246          {
247             cellParams.plmnList[memberNum].sst = \
248                     atoi(val.c_str());
249          O1_LOG("\nO1 NrCellDuCb : cellParams.plmnList[%d].sst  = %d", \
250                          memberNum, cellParams.plmnList[memberNum].sst);
251          }
252          else if(leaf == "sd")
253           {
254             memset(cellParams.plmnList[memberNum].sd, \
255                    '\0', SD_LEN);
256
257             cellParams.plmnList[memberNum].sd[0] = \
258                     stoi(val.substr(0,2).c_str(),0,16);
259             cellParams.plmnList[memberNum].sd[1] = \
260                     stoi(val.substr(2,2).c_str(),0,16);
261             cellParams.plmnList[memberNum].sd[2] = \
262                     stoi(val.substr(4,2).c_str(),0,16);
263             O1_LOG("\nO1 NrCellDuCb : cellParams.plmnList[%d].sd[2]  = %d",
264                     memberNum, cellParams.plmnList[memberNum].sd[SD_LEN-1]);
265          }
266          plmnListNum++;
267       }
268     else if(parent.find("ManagedElement") != string::npos)
269     {
270          if(leaf == "id")
271          {
272             strncpy(managedElement.meId, val.c_str(), strlen(val.c_str()));
273             O1_LOG("\nO1 NrCellDuCb : ManagedElement id  = %s", managedElement.meId);
274          }
275     }
276     else if(parent.find("GNBDUFunction") != string::npos)
277     {
278          if(leaf == "id")
279          {
280             strncpy(managedElement.gnbId, val.c_str(), strlen(val.c_str()));
281             O1_LOG("\nO1 NrCellDuCb : GNBDUFuntion id  = %s", managedElement.gnbId);
282          }
283     }
284     else if(parent.find("NRCellDu") != string::npos)
285     {
286          if(leaf == "id")
287          {
288             strncpy(managedElement.nrCellDuId, val.c_str(), strlen(val.c_str()));
289             O1_LOG("\nO1 NrCellDuCb : NRCELLDU id  = %s", managedElement.nrCellDuId);
290          }
291     }
292 }
293
294 /*******************************************************************
295  *
296  * @brief set cell parameters
297  *
298  * @details
299  *
300  *    Function : configureCell
301  *
302  *    Functionality:
303  *      - pass the cell Parameters to ODU high stack
304  *
305  *
306  * @params[in] void
307  * @return success/failure
308  ******************************************************************/
309
310 bool NrCellDuCb::configureCell()
311 {
312    O1_LOG("\nO1 rannetworkCb : configcell");
313 #ifndef ODU_TEST_STUB
314    if( setCellParam() != ROK)
315    {
316       O1_LOG("\nO1 rannetworkCb : fail to set cell configuration in DU");
317       return false;
318    }
319    return true;
320 #else
321    return true;
322 #endif
323 }
324
325 /*******************************************************************
326  *
327  * @brief override module_change to handle callback
328  *
329  * @details
330  *
331  *    Function : module_change
332  *
333  *    Functionality:
334  *      - override module_change to handle callback of modification of
335  *        o-ran-sc-du-hello-world yang module
336  *
337  *
338  * @params[in] sysrepo::S_Session session, const char *module_name,
339  *             const char *xpath, sr_event_t event, uint32_t request_id,
340  *             void *private_data
341  * @return SR_ERR_OK        - success
342  *         SR_ERR_INTERNAL  - failure
343  ******************************************************************/
344
345 int NrCellDuCb::module_change(sysrepo::S_Session sess, \
346                                     const char *module_name, \
347                                     const char *xpath, \
348                                     sr_event_t event, \
349                                     uint32_t request_id, \
350                                     void *private_data)
351 {
352    O1_LOG("\nO1 NrCellDuCb : Notification edit sucessful");
353
354    char change_path[XPATH_MAX_LEN];
355    plmnListNum = 0;
356
357    try {
358       O1_LOG("\nO1 NrCellDuCbCb : Notification %s", NetconfUtils::evToStr(event));
359       if (SR_EV_CHANGE == event)
360       {
361          snprintf(change_path, XPATH_MAX_LEN, "/%s:*//.", module_name);
362          auto it = sess->get_changes_iter(change_path);
363          while (auto change = sess->get_change_next(it)) {
364          //NetconfUtils::printChange(change); //enable only for debugging
365
366          if(nullptr != change->new_val())
367          {
368                //O1_LOG("\nO1 NrCellDuCb : Parameter value has been \
369 changed val=%s", change->new_val()->val_to_string().c_str());
370                string val = change->new_val()->val_to_string();
371                string parent, leaf;
372
373                NetconfUtils::getLeafInfo(change->new_val()->to_string(), \
374                                          parent, leaf);
375                O1_LOG("\nO1 NrCellDuCb : parent = [%s], leaf = [%s]", \
376                          parent.c_str(), leaf.c_str());
377                updateParams(parent, leaf ,val);
378             }
379          }
380          if(!configureCell())
381          {
382             O1_LOG("\nO1 NrCellDuCb : configcell failed");
383             return SR_ERR_INTERNAL;
384          }
385
386       }
387    }
388    catch( const std::exception& e ) {
389       O1_LOG("\nO1 rannetworkCb exception : %s\n", e.what());
390    }
391
392    return SR_ERR_OK;
393 }
394
395 /**********************************************************************
396          End of file
397 **********************************************************************/