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