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