64beee4a8708c2036660344767e52b6c0b8f7dd1
[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          //give the message to subscription handler, along with the transmitter.
132          strcpy((char*)meid,gnblist[i].c_str());
133
134
135          subscription_helper  din;
136          subscription_helper  dout;
137
138          subscription_request sub_req;
139          subscription_request sub_recv;
140
141          unsigned char buf[BUFFER_SIZE];
142          size_t buf_size = BUFFER_SIZE;
143          bool res;
144
145
146          //Random Data  for request
147          int request_id = 1;
148          int function_id = 0;
149          std::string event_def = "01";
150
151          din.set_request(request_id);
152          din.set_function_id(function_id);
153          din.set_event_def(event_def.c_str(), event_def.length());
154
155          std::string act_def = "01";
156
157          din.add_action(1,0,(void*)act_def.c_str(), act_def.length(), 0);
158
159          res = sub_req.encode_e2ap_subscription(&buf[0], &buf_size, din);
160
161          xapp_rmr_header rmr_header;
162          rmr_header.message_type = RIC_SUB_REQ;
163          rmr_header.payload_length = buf_size; //data_size
164          strcpy((char*)rmr_header.meid,gnblist[i].c_str());
165
166          mdclog_write(MDCLOG_INFO,"Sending subscription in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
167          
168          auto transmitter = std::bind(&XappRmr::xapp_rmr_send,rmr_ref, &rmr_header, (void*)buf );//(void*)data);
169
170          int result = subhandler_ref->manage_subscription_request(gnblist[i], transmitter);
171          
172           if(result==SUBSCR_SUCCESS){
173               mdclog_write(MDCLOG_INFO,"Subscription SUCCESSFUL in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
174           }
175            else {
176               mdclog_write(MDCLOG_ERR,"Subscription FAILED in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
177               }  
178    }
179
180 }
181
182 void Xapp::startup_get_policies(void){
183
184     int policy_id = BOUNCER_POLICY_ID;
185
186     std::string policy_query = "{\"policy_type_id\":" + std::to_string(policy_id) + "}";
187     unsigned char * message = (unsigned char *)calloc(policy_query.length(), sizeof(unsigned char));
188     memcpy(message, policy_query.c_str(),  policy_query.length());
189     xapp_rmr_header header;
190     header.payload_length = policy_query.length();
191     header.message_type = A1_POLICY_QUERY;
192     mdclog_write(MDCLOG_INFO, "Sending request for policy id %d\n", policy_id);
193     rmr_ref->xapp_rmr_send(&header, (void *)message);
194     free(message);
195
196 }
197
198 void Xapp::set_rnib_gnblist(void) {
199
200            openSdl();
201
202            void *result = getListGnbIds();
203            if(strlen((char*)result) < 1){
204                     mdclog_write(MDCLOG_ERR, "ERROR: no data from getListGnbIds\n");
205                 return;
206             }
207
208             mdclog_write(MDCLOG_INFO, "GNB List in R-NIB %s\n", (char*)result);
209
210
211             Document doc;
212             ParseResult parseJson = doc.Parse<kParseStopWhenDoneFlag>((char*)result);
213             if (!parseJson) {
214                 std::cerr << "JSON parse error: %s (%u)", GetParseErrorFunc(parseJson.Code());
215                 return;
216             }
217
218             if(!doc.HasMember("gnb_list")){
219                 mdclog_write(MDCLOG_INFO, "JSON Has No GNB List Object");
220                 return;
221             }
222             assert(doc.HasMember("gnb_list"));
223
224             const Value& gnblist = doc["gnb_list"];
225             if (gnblist.IsNull())
226               return;
227
228             if(!gnblist.IsArray()){
229                 mdclog_write(MDCLOG_INFO, "GNB List is not an array");
230                 return;
231             }
232
233
234                 assert(gnblist.IsArray());
235             for (SizeType i = 0; i < gnblist.Size(); i++) // Uses SizeType instead of size_t
236             {
237                 assert(gnblist[i].IsObject());
238                 const Value& gnbobj = gnblist[i];
239                 assert(gnbobj.HasMember("inventory_name"));
240                 assert(gnbobj["inventory_name"].IsString());
241                 std::string name = gnbobj["inventory_name"].GetString();
242                 rnib_gnblist.push_back(name);
243
244             }
245             closeSdl();
246             return;
247
248 }
249
250
251
252
253
254