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(meid, transmitter);
181 mdclog_write(MDCLOG_INFO,"Subscription SUCCESSFUL in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
188 void Xapp::startup_get_policies(void){
190 int policy_id = HELLOWORLD_POLICY_ID;
192 std::string policy_query = "{\"policy_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);
204 void Xapp::set_rnib_gnblist(void) {
208 void *result = getListGnbIds();
209 if(strlen((char*)result) < 1){
210 mdclog_write(MDCLOG_ERR, "ERROR: no data from getListGnbIds\n");
214 mdclog_write(MDCLOG_INFO, "GNB List in R-NIB %s\n", (char*)result);
218 ParseResult parseJson = doc.Parse((char*)result);
220 std::cerr << "JSON parse error: %s (%u)", GetParseErrorFunc(parseJson.Code());
224 if(!doc.HasMember("gnb_list")){
225 mdclog_write(MDCLOG_INFO, "JSON Has No GNB List Object");
228 assert(doc.HasMember("gnb_list"));
230 const Value& gnblist = doc["gnb_list"];
231 if (gnblist.IsNull())
234 if(!gnblist.IsArray()){
235 mdclog_write(MDCLOG_INFO, "GNB List is not an array");
240 assert(gnblist.IsArray());
241 for (SizeType i = 0; i < gnblist.Size(); i++) // Uses SizeType instead of size_t
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);