94d190e9523ba80df499bc5f89f8c65bdacea1e3
[ric-app/bouncer.git] / Bouncer / src / xapp.cc
1 /*
2 # ==================================================================================
3 # Copyright (c) 2020 HCL Technologies Limited.
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 #include "xapp.hpp"
20 #define BUFFER_SIZE 1024
21
22  Xapp::Xapp(XappSettings &config, XappRmr &rmr){
23
24           rmr_ref = &rmr;
25           config_ref = &config;
26           xapp_mutex = NULL;
27           subhandler_ref = NULL;
28           return;
29   }
30
31 Xapp::~Xapp(void){
32
33         //Joining the threads
34         int threadcnt = xapp_rcv_thread.size();
35                 for(int i=0; i<threadcnt; i++){
36                         if(xapp_rcv_thread[i].joinable())
37                                 xapp_rcv_thread[i].join();
38         }
39         xapp_rcv_thread.clear();
40
41         if(xapp_mutex!=NULL){
42                 xapp_mutex->~mutex();
43                 delete xapp_mutex;
44         }
45 };
46
47 //Stop the xapp. Note- To be run only from unit test scripts.
48 void Xapp::stop(void){
49   // Get the mutex lock
50         std::lock_guard<std::mutex> guard(*xapp_mutex);
51         rmr_ref->set_listen(false);
52         rmr_ref->~XappRmr();
53
54         //Detaching the threads....not sure if this is the right way to stop the receiver threads.
55         //Hence function should be called only in Unit Tests
56         int threadcnt = xapp_rcv_thread.size();
57         for(int i=0; i<threadcnt; i++){
58                 xapp_rcv_thread[i].detach();
59         }
60         sleep(10);
61 }
62
63 void Xapp::startup(SubscriptionHandler &sub_ref) {
64
65         subhandler_ref = &sub_ref;
66         set_rnib_gnblist();
67
68         sleep(70);
69
70         //send subscriptions.
71         startup_subscribe_requests();
72
73         //read A1 policies
74         //startup_get_policies();
75         return;
76 }
77 void Xapp::Run(){
78         rmr_ref->set_listen(true);
79         if(xapp_mutex == NULL){
80                 xapp_mutex = new std::mutex();
81         }
82         std::lock_guard<std::mutex> guard(*xapp_mutex);
83
84         for(int j=0; j < _callbacks.size(); j++){
85                 std::thread th_recv([&](){ rmr_ref->xapp_rmr_receive(std::move(_callbacks[j]), rmr_ref);});
86                 xapp_rcv_thread.push_back(std::move(th_recv));
87         }
88
89         return;
90 }
91
92 //Starting a seperate single receiver
93 void Xapp::start_xapp_receiver(XappMsgHandler& mp_handler){
94         //start a receiver thread. Can be multiple receiver threads for more than 1 listening port.
95         rmr_ref->set_listen(true);
96         if(xapp_mutex == NULL){
97                 xapp_mutex = new std::mutex();
98         }
99
100         mdclog_write(MDCLOG_INFO,"Receiver Thread file= %s, line=%d",__FILE__,__LINE__);
101         std::lock_guard<std::mutex> guard(*xapp_mutex);
102         std::thread th_recv([&](){ rmr_ref->xapp_rmr_receive(std::move(mp_handler), rmr_ref);});
103         xapp_rcv_thread.push_back(std::move(th_recv));
104         return;
105 }
106
107 void Xapp::shutdown(){
108         return;
109 }
110
111
112 void Xapp::startup_subscribe_requests(void ){
113
114    bool res;
115    size_t data_size = ASN_BUFF_MAX_SIZE;
116    unsigned char        data[data_size];
117    unsigned char meid[RMR_MAX_MEID];
118    std::string xapp_id = config_ref->operator [](XappSettings::SettingName::XAPP_ID);
119
120    mdclog_write(MDCLOG_INFO,"Preparing to send subscription in file= %s, line=%d",__FILE__,__LINE__);
121
122    auto gnblist = get_rnib_gnblist();
123
124    int sz = gnblist.size();
125
126    if(sz <= 0)
127            mdclog_write(MDCLOG_INFO,"Subscriptions cannot be sent as GNBList in RNIB is NULL");
128
129    for(int i = 0; i<sz; i++)
130    {
131          sleep(15); 
132          //give the message to subscription handler, along with the transmitter.
133          strcpy((char*)meid,gnblist[i].c_str());
134
135          mdclog_write(MDCLOG_INFO,"GNBList size : %d", sz);
136
137          subscription_helper  din;
138          subscription_helper  dout;
139
140          subscription_request sub_req;
141          subscription_request sub_recv;
142
143          unsigned char buf[BUFFER_SIZE];
144          size_t buf_size = BUFFER_SIZE;
145          bool res;
146
147
148          //Random Data  for request
149          int request_id = 1;
150          int function_id = 0;
151          std::string event_def = "01";
152
153          din.set_request(request_id);
154          din.set_function_id(function_id);
155          din.set_event_def(event_def.c_str(), event_def.length());
156
157          std::string act_def = "01";
158
159          din.add_action(1,0,(void*)act_def.c_str(), act_def.length(), 0);
160
161          res = sub_req.encode_e2ap_subscription(&buf[0], &buf_size, din);
162
163          //mdclog_write(MDCLOG_INFO,"GNBList = %s and ith val = %d", gnblist[i], i);
164
165          mdclog_write(MDCLOG_INFO,"Sending subscription in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
166          
167          xapp_rmr_header rmr_header;
168          rmr_header.message_type = RIC_SUB_REQ;
169          rmr_header.payload_length = buf_size; //data_size
170
171          strcpy((char*)rmr_header.meid,gnblist[i].c_str());
172
173          auto transmitter = std::bind(&XappRmr::xapp_rmr_send,rmr_ref, &rmr_header, (void*)buf); //(void*)data);
174          
175          int result = subhandler_ref->manage_subscription_request(gnblist[i], transmitter);
176          
177          if(result==SUBSCR_SUCCESS){
178
179               mdclog_write(MDCLOG_INFO,"Subscription SUCCESSFUL in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
180           }
181           else {
182                  mdclog_write(MDCLOG_ERR,"Subscription FAILED in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
183               }  
184         } 
185 }
186
187 void Xapp::startup_get_policies(void){
188
189     int policy_id = BOUNCER_POLICY_ID;
190
191     std::string policy_query = "{\"policy_type_id\":" + std::to_string(policy_id) + "}";
192     unsigned char * message = (unsigned char *)calloc(policy_query.length(), sizeof(unsigned char));
193     memcpy(message, policy_query.c_str(),  policy_query.length());
194     xapp_rmr_header header;
195     header.payload_length = policy_query.length();
196     header.message_type = A1_POLICY_QUERY;
197     mdclog_write(MDCLOG_INFO, "Sending request for policy id %d\n", policy_id);
198     rmr_ref->xapp_rmr_send(&header, (void *)message);
199     free(message);
200
201 }
202
203 void Xapp::set_rnib_gnblist(void) {
204
205            openSdl();
206
207            void *result = getListGnbIds();
208            if(strlen((char*)result) < 1){
209                     mdclog_write(MDCLOG_ERR, "ERROR: no data from getListGnbIds\n");
210                 return;
211             }
212
213             mdclog_write(MDCLOG_INFO, "GNB List in R-NIB %s\n", (char*)result);
214
215
216             Document doc;
217             ParseResult parseJson = doc.Parse<kParseStopWhenDoneFlag>((char*)result);
218             if (!parseJson) {
219                 std::cerr << "JSON parse error: %s (%u)", GetParseErrorFunc(parseJson.Code());
220                 return;
221             }
222
223             if(!doc.HasMember("gnb_list")){
224                 mdclog_write(MDCLOG_INFO, "JSON Has No GNB List Object");
225                 return;
226             }
227             assert(doc.HasMember("gnb_list"));
228
229             const Value& gnblist = doc["gnb_list"];
230             if (gnblist.IsNull())
231               return;
232
233             if(!gnblist.IsArray()){
234                 mdclog_write(MDCLOG_INFO, "GNB List is not an array");
235                 return;
236             }
237
238
239                 assert(gnblist.IsArray());
240             for (SizeType i = 0; i < gnblist.Size(); i++) // Uses SizeType instead of size_t
241             {
242                 assert(gnblist[i].IsObject());
243                 const Value& gnbobj = gnblist[i];
244                 assert(gnbobj.HasMember("inventory_name"));
245                 assert(gnbobj["inventory_name"].IsString());
246                 std::string name = gnbobj["inventory_name"].GetString();
247                 rnib_gnblist.push_back(name);
248
249             }
250             closeSdl();
251             return;
252
253 }
254