blob: f6e2c37aa33bab3249c5f624462a3333a4190e10 [file] [log] [blame]
Ron Shachame7dfeb82020-04-24 14:46:48 -04001// vi: ts=4 sw=4 noet:
2/*
3==================================================================================
4 Copyright (c) 2020 Nokia
5 Copyright (c) 2020 AT&T Intellectual Property.
6
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18==================================================================================
19*/
20
21/*
22 Mnemonic: ts_xapp.cpp
23 Abstract: Traffic Steering xApp;
24 1. Receives A1 Policy
25 2. Queries SDL to decide which UE to attempt Traffic Steering for
26 3. Requests prediction for UE throughput on current and neighbor cells
27 4. Receives prediction
28 5. Optionally exercises Traffic Steering action over E2
29
30 Date: 22 April 2020
31 Author: Ron Shacham
32
33*/
34
35#include <stdio.h>
36#include <string.h>
37#include <unistd.h>
38
39#include <iostream>
40#include <memory>
41
42#include <sdl/syncstorage.hpp>
43#include <set>
44#include <map>
45#include <vector>
46#include <string>
47
48#include "ricxfcpp/xapp.hpp"
49
50using Namespace = std::string;
51using Key = std::string;
52using Data = std::vector<uint8_t>;
53using DataMap = std::map<Key, Data>;
54using Keys = std::set<Key>;
55
56
57// ----------------------------------------------------------
58
59std::unique_ptr<Xapp> xfw;
60
61
62void policy_callback( Message& mbuf, int mtype, int subid, int len, Msg_component payload, void* data ) {
63
64 long now;
65 long total_count;
66
67 int sz;
68 int i;
69
70 int response_to = 0; // max timeout wating for a response
71
72 int send_mtype = 0;
73 int rmtype; // received message type
74 int delay = 1000000; // mu-sec delay; default 1s
75
76 std::unique_ptr<Message> msg;
77 Msg_component send_payload; // special type of unique pointer to the payload
78
79 fprintf( stderr, "Policy Callback got a message, type=%d , length=%d\n" , mtype, len);
80 fprintf(stderr, "payload is %s\n", payload.get());
81
82 //fprintf( stderr, "callback 1 got a message type = %d len = %d\n", mtype, len );
83 mbuf.Send_response( 101, -1, 5, (unsigned char *) "OK1\n" ); // validate that we can use the same buffer for 2 rts calls
84 mbuf.Send_response( 101, -1, 5, (unsigned char *) "OK2\n" );
85
86 mtype = 0;
87
88 fprintf(stderr, "cb 1\n");
89
90 msg = xfw->Alloc_msg( 2048 );
91
92 sz = msg->Get_available_size(); // we'll reuse a message if we received one back; ensure it's big enough
93 if( sz < 2048 ) {
94 fprintf( stderr, "<SNDR> fail: message returned did not have enough size: %d [%d]\n", sz, i );
95 exit( 1 );
96 }
97
98 fprintf(stderr, "cb 2");
99
100 send_payload = msg->Get_payload(); // direct access to payload
E. Scott Danielsf7b96952020-04-29 10:07:53 -0400101 snprintf( (char *) send_payload.get(), 2048, "{\"UEPredictionSet\" : [\"222\", \"333\", \"444\"]}" );
Ron Shachame7dfeb82020-04-24 14:46:48 -0400102
103 fprintf(stderr, "cb 3");
104
105 // payload updated in place, nothing to copy from, so payload parm is nil
106 if ( ! msg->Send_msg( mtype, Message::NO_SUBID, strlen( (char *) send_payload.get() )+1, NULL )) {
E. Scott Danielsf7b96952020-04-29 10:07:53 -0400107 fprintf( stderr, "<SNDR> send failed: %d\n", msg->Get_state() );
Ron Shachame7dfeb82020-04-24 14:46:48 -0400108 }
109
110 fprintf(stderr, "cb 4");
111
112 /*
113 msg = xfw->Receive( response_to );
114 if( msg != NULL ) {
115 rmtype = msg->Get_mtype();
116 send_payload = msg->Get_payload();
117 fprintf( stderr, "got: mtype=%d payload=(%s)\n", rmtype, (char *) send_payload.get() );
118 }
119 */
120
121}
122
123
124void prediction_callback( Message& mbuf, int mtype, int subid, int len, Msg_component payload, void* data ) {
125
126 long now;
127 long total_count;
128
129 int sz;
130 int i;
131
132 int response_to = 0; // max timeout wating for a response
133
134 int send_mtype = 0;
135 int rmtype; // received message type
136 int delay = 1000000; // mu-sec delay; default 1s
137
138 std::unique_ptr<Message> msg;
139 Msg_component send_payload; // special type of unique pointer to the payload
140
141 fprintf( stderr, "Prediction Callback got a message, type=%d , length=%d\n" , mtype, len);
142 fprintf(stderr, "payload is %s\n", payload.get());
143
144 mbuf.Send_response( 101, -1, 5, (unsigned char *) "OK1\n" ); // validate that we can use the same buffer for 2 rts calls
145 mbuf.Send_response( 101, -1, 5, (unsigned char *) "OK2\n" );
146
147 mtype = 0;
148
149 fprintf(stderr, "cb 1\n");
150
151}
152
153
154
155extern int main( int argc, char** argv ) {
156
157 std::unique_ptr<Message> msg;
158 Msg_component payload; // special type of unique pointer to the payload
159
160 int nthreads = 1;
161
162 int response_to = 0; // max timeout wating for a response
163
164 int delay = 1000000; // mu-sec delay; default 1s
165
E. Scott Danielsf7b96952020-04-29 10:07:53 -0400166 char* port = (char *) "4560";
Ron Shachame7dfeb82020-04-24 14:46:48 -0400167
168 int ai;
169
170 ai = 1;
171 while( ai < argc ) { // very simple flag processing (no bounds/error checking)
172 if( argv[ai][0] != '-' ) {
173 break;
174 }
175
176 switch( argv[ai][1] ) { // we only support -x so -xy must be -x -y
177 case 'd': // delay between messages (mu-sec)
178 delay = atoi( argv[ai+1] );
179 ai++;
180 break;
181
182 case 'p':
183 port = argv[ai+1];
184 ai++;
185 break;
186
187 case 't': // timeout in seconds; we need to convert to ms for rmr calls
188 response_to = atoi( argv[ai+1] ) * 1000;
189 ai++;
190 break;
191 }
192 ai++;
193 }
194
195 fprintf( stderr, "<XAPP> response timeout set to: %d\n", response_to );
196 fprintf( stderr, "<XAPP> listening on port: %s\n", port );
197
198 xfw = std::unique_ptr<Xapp>( new Xapp( port, true ) ); // new xAPP thing; wait for a route table
199
200 fprintf(stderr, "code1\n");
201
202 xfw->Add_msg_cb( 20010, policy_callback, NULL );
203 xfw->Add_msg_cb( 30002, prediction_callback, NULL );
204
205 fprintf(stderr, "code2\n");
206
207 std::string sdl_namespace_u = "TS-UE-metrics";
208 std::string sdl_namespace_c = "TS-cell-metrics";
209
210 fprintf(stderr, "code5\n");
211
212 std::unique_ptr<shareddatalayer::SyncStorage> sdl(shareddatalayer::SyncStorage::create());
213
214 Namespace nsu(sdl_namespace_u);
215 Namespace nsc(sdl_namespace_c);
216
217 /*
218
219 fprintf(stderr, "before sdl set\n");
220
221 try{
222 //connecting to the Redis and generating a random key for namespace "hwxapp"
223 fprintf(stderr, "IN SDL Set Data");
224 // std::string data_string = "{\"rsrp\" : -110}";
225
226
227 std::string data_string = "{\"CellID\": \"310-680-200-555001\", \"MeasTimestampPDCPBytes\": \"2020-03-18 02:23:18.220\", \"MeasPeriodPDCPBytes\": 20, \"PDCPBytesDL\": 2000000, \"PDCPBytesUL\": 1200000, \"MeasTimestampAvailPRB\": \"2020-03-18 02:23:18.220\", \"MeasPeriodAvailPRB\": 20, \"AvailPRBDL\": 30, \"AvailPRBUL\": 50 }";
228
229 DataMap dmap;
230 // char key[4]="abc";
231 char key[] = "310-680-200-555001";
232 std::cout << "KEY: "<< key << std::endl;
233 Key k = key;
234 Data d;
235 // uint8_t num = 101;
236 d.assign(data_string.begin(), data_string.end());
237 // d.push_back(num);
238 dmap.insert({k,d});
239
240 sdl->set(nsc, dmap);
241
242 data_string = "{ \"CellID\": \"310-680-200-555002\", \"MeasTimestampPDCPBytes\": \"2020-03-18 02:23:18.220\", \"MeasPeriodPDCPBytes\": 20, \"PDCPBytesDL\": 800000, \"PDCPBytesUL\": 400000, \"MeasTimestampAvailPRB\": \"2020-03-18 02:23:18.220\", \"MeasPeriodAvailPRB\": 20, \"AvailPRBDL\": 30, \"AvailPRBUL\": 45 }";
243
244 Data d2;
245 DataMap dmap2;
246 char key2[] = "310-680-200-555002";
247 std::cout << "KEY: "<< key2 << std::endl;
248 Key k2 = key2;
249 d2.assign(data_string.begin(), data_string.end());
250 // d.push_back(num);
251 dmap2.insert({k2,d});
252
253 sdl->set(nsc, dmap2);
254
255
256
257 std::string data_string = "{ \"CellID\": \"310-680-200-555003\", \"MeasTimestampPDCPBytes\": \"2020-03-18 02:23:18.220\", \"MeasPeriodPDCPBytes\": 20, \"PDCPBytesDL\": 800000, \"PDCPBytesUL\": 400000, \"MeasTimestampAvailPRB\": \"2020-03-18 02:23:18.220\", \"MeasPeriodAvailPRB\": 20, \"AvailPRBDL\": 30, \"AvailPRBUL\": 45 }";
258
259 Data d3;
260 DataMap dmap3;
261 char key3[] = "310-680-200-555003";
262 std::cout << "KEY: "<< key3 << std::endl;
263 Key k3 = key3;
264 d3.assign(data_string.begin(), data_string.end());
265 // d.push_back(num);
266 dmap3.insert({k3,d3});
267
268 sdl->set(nsc, dmap3);
269
270
271
272 data_string = "{ \"UEID\": 12345, \"ServingCellID\": \"310-680-200-555002\", \"MeasTimestampUEPDCPBytes\": \"2020-03-18 02:23:18.220\", \"MeasPeriodUEPDCPBytes\": 20,\"UEPDCPBytesDL\": 250000,\"UEPDCPBytesUL\": 100000, \"MeasTimestampUEPRBUsage\": \"2020-03-18 02:23:18.220\", \"MeasPeriodUEPRBUsage\": 20, \"UEPRBUsageDL\": 10, \"UEPRBUsageUL\": 30, \"MeasTimestampRF\": \"2020-03-18 02:23:18.210\",\"MeasPeriodRF\": 40, \"ServingCellRF\": [-115,-16,-5], \"NeighborCellRF\": [ {\"CID\": \"310-680-200-555001\",\"Cell-RF\": [-90,-13,-2.5 ] }, {\"CID\": \"310-680-200-555003\", \"Cell-RF\": [-140,-17,-6 ] } ] }";
273
274 Data d4;
275 DataMap dmap4;
276 char key4[] = "12345";
277 std::cout << "KEY: "<< key << std::endl;
278 d4.assign(data_string.begin(), data_string.end());
279 Key k4 = key4;
280 // d.push_back(num);
281 dmap4.insert({k4,d4});
282
283 sdl->set(nsu, dmap4);
284
285
286 }
287 catch(...){
288 fprintf(stderr,"SDL Error in Set Data for Namespace");
289 return false;
290 }
291
292 fprintf(stderr, "after sdl set\n");
293
294 */
295
296 fprintf(stderr, "before sdl get\n");
297
298
299 std::string prefix2="310";
300 Keys K = sdl->findKeys(nsc, prefix2); // just the prefix
301 DataMap Dk = sdl->get(nsc, K);
302
303 std::cout << "K contains " << K.size() << " elements.\n";
304
305 fprintf(stderr, "before forloop\n");
306
307 for(auto si=K.begin();si!=K.end();++si){
308 std::vector<uint8_t> val_v = Dk[(*si)]; // 4 lines to unpack a string
309 char val[val_v.size()+1]; // from Data
310 int i;
311 for(i=0;i<val_v.size();++i) val[i] = (char)(val_v[i]);
312 val[i]='\0';
313 fprintf(stderr, "KEYS and Values %s = %s\n",(*si).c_str(), val);
314 }
315
316
317 std::string prefix3="12";
318 Keys K2 = sdl->findKeys(nsu, prefix3); // just the prefix
319 DataMap Dk2 = sdl->get(nsu, K2);
320
321 std::cout << "K contains " << K2.size() << " elements.\n";
322
323 fprintf(stderr, "before forloop\n");
324
325 for(auto si=K2.begin();si!=K2.end();++si){
326 std::vector<uint8_t> val_v = Dk2[(*si)]; // 4 lines to unpack a string
327 char val[val_v.size()+1]; // from Data
328 int i;
329 for(i=0;i<val_v.size();++i) val[i] = (char)(val_v[i]);
330 val[i]='\0';
331 fprintf(stderr, "KEYS and Values %s = %s\n",(*si).c_str(), val);
332 }
333
334
335 fprintf(stderr, "after sdl get\n");
336
337 xfw->Run( nthreads );
338
339 fprintf(stderr, "code3\n");
340
341 msg = xfw->Alloc_msg( 2048 );
342
343 fprintf(stderr, "code4\n");
344
345
346}