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