2 ==================================================================================
4 Copyright (c) 2019-2020 AT&T Intellectual Property.
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
10 http://www.apache.org/licenses/LICENSE-2.0
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 ==================================================================================
22 * Mar, 2020 (Shraboni Jana)
26 #define BUFFER_SIZE 1024
28 Xapp::Xapp(XappSettings &config, XappRmr &rmr){
33 subhandler_ref = NULL;
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();
45 xapp_rcv_thread.clear();
53 //Stop the xapp. Note- To be run only from unit test scripts.
54 void Xapp::stop(void){
56 std::lock_guard<std::mutex> guard(*xapp_mutex);
57 rmr_ref->set_listen(false);
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();
69 void Xapp::startup(SubscriptionHandler &sub_ref) {
71 subhandler_ref = &sub_ref;
75 startup_subscribe_requests();
78 startup_get_policies();
82 rmr_ref->set_listen(true);
83 if(xapp_mutex == NULL){
84 xapp_mutex = new std::mutex();
86 std::lock_guard<std::mutex> guard(*xapp_mutex);
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));
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();
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));
112 void Xapp::shutdown(){
119 void Xapp::startup_subscribe_requests(void ){
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);
127 mdclog_write(MDCLOG_INFO,"Preparing to send subscription in file= %s, line=%d",__FILE__,__LINE__);
129 auto gnblist = get_rnib_gnblist();
131 int sz = gnblist.size();
134 mdclog_write(MDCLOG_INFO,"Subscriptions cannot be sent as GNBList in RNIB is NULL");
136 for(int i = 0; i<sz; i++){
138 //give the message to subscription handler, along with the transmitter.
139 strcpy((char*)meid,gnblist[i].c_str());
141 // char *strMsg = "Subscription Request from HelloWorld XApp\0";
142 // strncpy((char *)data,strMsg,strlen(strMsg));
143 // data_size = strlen(strMsg);
145 subscription_helper din;
146 subscription_helper dout;
148 subscription_request sub_req;
149 subscription_request sub_recv;
151 unsigned char buf[BUFFER_SIZE];
152 size_t buf_size = BUFFER_SIZE;
156 //Random Data for request
159 std::string event_def = "HelloWorld Event Definition";
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());
165 std::string act_def = "HelloWorld Action Definition";
167 din.add_action(1,1,(void*)act_def.c_str(), act_def.length(), 0);
169 res = sub_req.encode_e2ap_subscription(&buf[0], &buf_size, din);
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());
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);
179 int result = subhandler_ref->manage_subscription_request(gnblist[i], transmitter);
180 if(result==SUBSCR_SUCCESS){
181 mdclog_write(MDCLOG_INFO,"Subscription SUCCESSFUL in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
184 mdclog_write(MDCLOG_ERR,"Subscription FAILED in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
190 void Xapp::startup_get_policies(void){
192 int policy_id = HELLOWORLD_POLICY_ID;
194 std::string policy_query = "{\"policy_type_id\":" + std::to_string(policy_id) + "}";
195 unsigned char * message = (unsigned char *)calloc(policy_query.length(), sizeof(unsigned char));
196 memcpy(message, policy_query.c_str(), policy_query.length());
197 xapp_rmr_header header;
198 header.payload_length = policy_query.length();
199 header.message_type = A1_POLICY_QUERY;
200 mdclog_write(MDCLOG_INFO, "Sending request for policy id %d\n", policy_id);
201 rmr_ref->xapp_rmr_send(&header, (void *)message);
206 void Xapp::set_rnib_gnblist(void) {
210 void *result = getListGnbIds();
211 if(strlen((char*)result) < 1){
212 mdclog_write(MDCLOG_ERR, "ERROR: no data from getListGnbIds\n");
216 mdclog_write(MDCLOG_INFO, "GNB List in R-NIB %s\n", (char*)result);
220 ParseResult parseJson = doc.Parse<kParseStopWhenDoneFlag>((char*)result);
222 std::cerr << "JSON parse error: %s (%u)", GetParseErrorFunc(parseJson.Code());
226 if(!doc.HasMember("gnb_list")){
227 mdclog_write(MDCLOG_INFO, "JSON Has No GNB List Object");
230 assert(doc.HasMember("gnb_list"));
232 const Value& gnblist = doc["gnb_list"];
233 if (gnblist.IsNull())
236 if(!gnblist.IsArray()){
237 mdclog_write(MDCLOG_INFO, "GNB List is not an array");
242 assert(gnblist.IsArray());
243 for (SizeType i = 0; i < gnblist.Size(); i++) // Uses SizeType instead of size_t
245 assert(gnblist[i].IsObject());
246 const Value& gnbobj = gnblist[i];
247 assert(gnbobj.HasMember("inventory_name"));
248 assert(gnbobj["inventory_name"].IsString());
249 std::string name = gnbobj["inventory_name"].GetString();
250 rnib_gnblist.push_back(name);