2 # ==================================================================================
3 # Copyright (c) 2020 HCL Technologies Limited.
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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 # ==================================================================================
20 #define BUFFER_SIZE 1024
22 Xapp::Xapp(XappSettings &config, XappRmr &rmr){
27 subhandler_ref = NULL;
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();
39 xapp_rcv_thread.clear();
47 //Stop the xapp. Note- To be run only from unit test scripts.
48 void Xapp::stop(void){
50 std::lock_guard<std::mutex> guard(*xapp_mutex);
51 rmr_ref->set_listen(false);
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();
63 void Xapp::startup(SubscriptionHandler &sub_ref) {
65 subhandler_ref = &sub_ref;
71 startup_subscribe_requests();
74 //startup_get_policies();
78 rmr_ref->set_listen(true);
79 if(xapp_mutex == NULL){
80 xapp_mutex = new std::mutex();
82 std::lock_guard<std::mutex> guard(*xapp_mutex);
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));
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();
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));
107 void Xapp::shutdown(){
112 void Xapp::startup_subscribe_requests(void ){
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);
120 mdclog_write(MDCLOG_INFO,"Preparing to send subscription in file= %s, line=%d",__FILE__,__LINE__);
122 auto gnblist = get_rnib_gnblist();
124 int sz = gnblist.size();
127 mdclog_write(MDCLOG_INFO,"Subscriptions cannot be sent as GNBList in RNIB is NULL");
129 for(int i = 0; i<sz; i++)
132 //give the message to subscription handler, along with the transmitter.
133 strcpy((char*)meid,gnblist[i].c_str());
135 mdclog_write(MDCLOG_INFO,"GNBList size : %d", sz);
137 subscription_helper din;
138 subscription_helper dout;
140 subscription_request sub_req;
141 subscription_request sub_recv;
143 unsigned char buf[BUFFER_SIZE];
144 size_t buf_size = BUFFER_SIZE;
148 //Random Data for request
151 std::string event_def = "01";
153 din.set_request(request_id);
154 din.set_function_id(function_id);
155 din.set_event_def(event_def.c_str(), event_def.length());
157 std::string act_def = "01";
159 din.add_action(1,0,(void*)act_def.c_str(), act_def.length(), 0);
161 res = sub_req.encode_e2ap_subscription(&buf[0], &buf_size, din);
163 //mdclog_write(MDCLOG_INFO,"GNBList = %s and ith val = %d", gnblist[i], i);
165 mdclog_write(MDCLOG_INFO,"Sending subscription in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
167 xapp_rmr_header rmr_header;
168 rmr_header.message_type = RIC_SUB_REQ;
169 rmr_header.payload_length = buf_size; //data_size
171 strcpy((char*)rmr_header.meid,gnblist[i].c_str());
173 auto transmitter = std::bind(&XappRmr::xapp_rmr_send,rmr_ref, &rmr_header, (void*)buf); //(void*)data);
175 int result = subhandler_ref->manage_subscription_request(gnblist[i], transmitter);
177 if(result==SUBSCR_SUCCESS){
179 mdclog_write(MDCLOG_INFO,"Subscription SUCCESSFUL in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
182 mdclog_write(MDCLOG_ERR,"Subscription FAILED in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
187 void Xapp::startup_get_policies(void){
189 int policy_id = BOUNCER_POLICY_ID;
191 std::string policy_query = "{\"policy_type_id\":" + std::to_string(policy_id) + "}";
192 unsigned char * message = (unsigned char *)calloc(policy_query.length(), sizeof(unsigned char));
193 memcpy(message, policy_query.c_str(), policy_query.length());
194 xapp_rmr_header header;
195 header.payload_length = policy_query.length();
196 header.message_type = A1_POLICY_QUERY;
197 mdclog_write(MDCLOG_INFO, "Sending request for policy id %d\n", policy_id);
198 rmr_ref->xapp_rmr_send(&header, (void *)message);
203 void Xapp::set_rnib_gnblist(void) {
207 void *result = getListGnbIds();
208 if(strlen((char*)result) < 1){
209 mdclog_write(MDCLOG_ERR, "ERROR: no data from getListGnbIds\n");
213 mdclog_write(MDCLOG_INFO, "GNB List in R-NIB %s\n", (char*)result);
217 ParseResult parseJson = doc.Parse<kParseStopWhenDoneFlag>((char*)result);
219 std::cerr << "JSON parse error: %s (%u)", GetParseErrorFunc(parseJson.Code());
223 if(!doc.HasMember("gnb_list")){
224 mdclog_write(MDCLOG_INFO, "JSON Has No GNB List Object");
227 assert(doc.HasMember("gnb_list"));
229 const Value& gnblist = doc["gnb_list"];
230 if (gnblist.IsNull())
233 if(!gnblist.IsArray()){
234 mdclog_write(MDCLOG_INFO, "GNB List is not an array");
239 assert(gnblist.IsArray());
240 for (SizeType i = 0; i < gnblist.Size(); i++) // Uses SizeType instead of size_t
242 assert(gnblist[i].IsObject());
243 const Value& gnbobj = gnblist[i];
244 assert(gnbobj.HasMember("inventory_name"));
245 assert(gnbobj["inventory_name"].IsString());
246 std::string name = gnbobj["inventory_name"].GetString();
247 rnib_gnblist.push_back(name);