Add User-level metrics
[sim/e2-interface.git] / e2sim / e2apv1sim / kpm_callbacks.cpp
1
2
3 #include <iostream>
4 #include <fstream>
5 #include <vector>
6
7
8 #include "OCUCP-PF-Container.h"
9 #include "OCTET_STRING.h"
10 #include "asn_application.h"
11 #include "E2SM-KPM-IndicationMessage.h"
12 #include "FQIPERSlicesPerPlmnListItem.h"
13 #include "E2SM-KPM-RANfunction-Description.h"
14 #include "Timestamp.h"
15 #include "E2AP-PDU.h"
16 #include "encode_kpm.hpp"
17 #include "encode_e2apv1.hpp"
18 #include "e2sim.hpp"
19
20 using namespace std;
21
22 struct neighbor_cell_entry {
23   char *cellid;
24   int rsrp;
25   int rsrq;
26   int rssinr;
27
28 };
29
30 void run_report_loop(long requestorId, long instanceId, long ranFunctionId, long actionId, int socket_fd) {
31
32   //Process simulation file
33
34   ifstream simfile;
35   string line;
36
37   long seqNum = 1;
38   
39   simfile.open("simulation.txt", ios::in);
40
41   if (simfile.is_open()) {
42
43     while (getline(simfile, line)) {
44       cout << line << "\n";
45
46       //REPORT Message 1 -- Encode and send ODU cell-level report
47
48       E2SM_KPM_IndicationMessage_t *ind_msg1 =
49         (E2SM_KPM_IndicationMessage_t*)calloc(1,sizeof(E2SM_KPM_IndicationMessage_t));
50       E2AP_PDU *pdu = (E2AP_PDU*)calloc(1,sizeof(E2AP_PDU));
51
52       long fiveqi = 7;
53       uint8_t *sst_buf = (uint8_t*)"1";
54       uint8_t *sd_buf = (uint8_t*)"100";
55       uint8_t *plmnid_buf = (uint8_t*)"747";
56       uint8_t *nrcellid_buf = (uint8_t*)"12340";
57       long dl_prbs = 100;
58       long ul_prbs = 50; 
59      
60       encode_kpm_report_style1_parameterized(ind_msg1, fiveqi, dl_prbs, ul_prbs, sst_buf, sd_buf, plmnid_buf, nrcellid_buf, &dl_prbs, &ul_prbs);
61
62       uint8_t e2smbuffer[8192];
63       size_t e2smbuffer_size = 8192;
64       asn_codec_ctx_t *opt_cod;
65
66       asn_enc_rval_t er = asn_encode_to_buffer(opt_cod,
67                                                ATS_ALIGNED_BASIC_PER,
68                                                &asn_DEF_E2SM_KPM_IndicationMessage,
69                                                ind_msg1, e2smbuffer, e2smbuffer_size);
70       
71       fprintf(stderr, "er encded is %d\n", er.encoded);
72       fprintf(stderr, "after encoding message\n");
73       uint8_t *e2smheader_buf = (uint8_t*)"header";
74
75       uint8_t *cpid_buf = (uint8_t*)"CPID";
76
77       fprintf(stderr, "About to encode Indication\n");
78       generate_e2apv1_indication_request_parameterized(pdu, requestorId,
79                                                        instanceId, ranFunctionId,
80                                                        actionId, seqNum, e2smheader_buf, 6, e2smbuffer, er.encoded);
81
82       encode_and_send_sctp_data(pdu, socket_fd);
83       
84       seqNum++;
85
86       //REPORT Message 2 -- Encode and send OCUUP cell-level report
87
88       uint8_t *buf = (uint8_t*)"GNBCUUP5";
89
90       int bytes_dl = 40000;
91       int bytes_ul = 50000;
92
93       E2SM_KPM_IndicationMessage_t *ind_msg2 =
94         (E2SM_KPM_IndicationMessage_t*)calloc(1,sizeof(E2SM_KPM_IndicationMessage_t));
95       E2AP_PDU *pdu2 = (E2AP_PDU*)calloc(1,sizeof(E2AP_PDU));
96       
97       encode_kpm_report_style5_parameterized(ind_msg2 , buf, bytes_dl, bytes_ul, sst_buf, sd_buf, plmnid_buf);
98
99       uint8_t e2smbuffer2[8192];
100       size_t e2smbuffer_size2 = 8192;
101
102
103       asn_enc_rval_t er2 = asn_encode_to_buffer(opt_cod,
104                                                ATS_ALIGNED_BASIC_PER,
105                                                &asn_DEF_E2SM_KPM_IndicationMessage,
106                                                ind_msg2, e2smbuffer2, e2smbuffer_size2);
107       
108       fprintf(stderr, "er encded is %d\n", er2.encoded);
109       fprintf(stderr, "after encoding message\n");
110       uint8_t *e2smheader_buf2 = (uint8_t*)"header";
111
112       generate_e2apv1_indication_request_parameterized(pdu2, requestorId,
113                                                        instanceId, ranFunctionId,
114                                                        actionId, seqNum, e2smheader_buf2, 6, e2smbuffer2, er2.encoded);
115
116       encode_and_send_sctp_data(pdu2, socket_fd);
117       
118       seqNum++;
119
120       //REPORT Message 3 -- Encode and send OCUCP user-level report
121
122       E2SM_KPM_IndicationMessage_t *ind_msg3 =
123         (E2SM_KPM_IndicationMessage_t*)calloc(1,sizeof(E2SM_KPM_IndicationMessage_t));
124       E2AP_PDU *pdu3 = (E2AP_PDU*)calloc(1,sizeof(E2AP_PDU));
125
126       uint8_t *crnti_buf = (uint8_t*)"12";
127       //      uint8_t *serving_buf = (uint8_t*)"RSRP10";
128       //uint8_t *neighbor_buf = (uint8_t*)"-10,-15";
129       int rsrpServ = 10;
130       int rsrqServ = 0;
131       int rssinrServ = 0;
132
133       std::string serving_str = "{\"rsrp\": " + std::to_string(rsrpServ) + ", \"rsrq\": " +
134         std::to_string(rsrqServ) + ", \"rssinr\": " + std::to_string(rssinrServ) + "}";
135       const uint8_t *serving_buf = reinterpret_cast<const uint8_t*>(serving_str.c_str());
136
137
138       neighbor_cell_entry n_entries[3];
139       n_entries[0] = {"123", 10, 0, 0};
140       n_entries[1] = {"456", 10, 0, 0};
141       n_entries[2] = {"789", 10, 0, 0};
142
143       std::string neighbor_str = "[";
144
145       for (int i=0; i < sizeof(n_entries)/sizeof(n_entries[0]); i++) {
146
147         if (i != 0) {
148           neighbor_str += ",";
149         }
150         neighbor_str += "{\"CID\" : \"" + std::string(n_entries[i].cellid) + "\", \"Cell-RF\" : \"{\"rsrp\": " + std::to_string(n_entries[i].rsrp) +
151           ", \"rsrq\": " + std::to_string(n_entries[i].rsrq) + ", \"rssinr\": " + std::to_string(n_entries[i].rsrp) + "}}";
152       }
153
154       neighbor_str += "]";
155
156       const uint8_t *neighbor_buf = reinterpret_cast<const uint8_t*>(neighbor_str.c_str());
157
158       printf("Neighbor string\n%s", neighbor_buf);
159
160       encode_kpm_report_rancontainer_cucp_parameterized(ind_msg3, plmnid_buf, nrcellid_buf, crnti_buf, serving_buf, neighbor_buf);
161       
162       uint8_t e2smbuffer3[8192];
163       size_t e2smbuffer_size3 = 8192;
164
165       asn_enc_rval_t er3 = asn_encode_to_buffer(opt_cod,
166                                                 ATS_ALIGNED_BASIC_PER,
167                                                 &asn_DEF_E2SM_KPM_IndicationMessage,
168                                                 ind_msg3, e2smbuffer3, e2smbuffer_size3);
169       
170       fprintf(stderr, "er encded is %d\n", er3.encoded);
171       fprintf(stderr, "after encoding message\n");
172       uint8_t *e2smheader_buf3 = (uint8_t*)"header";
173
174       generate_e2apv1_indication_request_parameterized(pdu3, requestorId,
175                                                        instanceId, ranFunctionId,
176                                                        actionId, seqNum, e2smheader_buf3, 6, e2smbuffer3, er3.encoded);
177
178       encode_and_send_sctp_data(pdu3, socket_fd);
179             
180       seqNum++;
181       
182       //Encode and send OCUUP user-level report
183
184
185       
186       //Encode and send ODU user-level report
187
188       
189
190       
191     }
192
193     simfile.close();
194
195   }
196
197 }
198
199 void callback_kpm_subscription_request(E2AP_PDU_t *sub_req_pdu, int socket_fd) {
200
201
202   //Record RIC Request ID
203   //Go through RIC action to be Setup List
204   //Find first entry with REPORT action Type
205   //Record ricActionID
206   //Encode subscription response
207
208   RICsubscriptionRequest_t orig_req =
209     sub_req_pdu->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
210   
211   RICsubscriptionResponse_IEs_t *ricreqid =
212     (RICsubscriptionResponse_IEs_t*)calloc(1, sizeof(RICsubscriptionResponse_IEs_t));
213                                            
214   int count = orig_req.protocolIEs.list.count;
215   int size = orig_req.protocolIEs.list.size;
216   
217   RICsubscriptionRequest_IEs_t **ies = (RICsubscriptionRequest_IEs_t**)orig_req.protocolIEs.list.array;
218
219   fprintf(stderr, "count%d\n", count);
220   fprintf(stderr, "size%d\n", size);
221
222   RICsubscriptionRequest_IEs__value_PR pres;
223
224   long reqRequestorId;
225   long reqInstanceId;
226   long reqActionId;
227
228   std::vector<long> actionIdsAccept;
229   std::vector<long> actionIdsReject;
230
231   for (int i=0; i < count; i++) {
232     RICsubscriptionRequest_IEs_t *next_ie = ies[i];
233     pres = next_ie->value.present;
234     
235     fprintf(stderr, "next present value %d\n", pres);
236
237     switch(pres) {
238     case RICsubscriptionRequest_IEs__value_PR_RICrequestID:
239       {
240         RICrequestID_t reqId = next_ie->value.choice.RICrequestID;
241         long requestorId = reqId.ricRequestorID;
242         long instanceId = reqId.ricInstanceID;
243         fprintf(stderr, "requestorId %d\n", requestorId);
244         fprintf(stderr, "instanceId %d\n", instanceId);
245         reqRequestorId = requestorId;
246         reqInstanceId = instanceId;
247
248         break;
249       }
250     case RICsubscriptionRequest_IEs__value_PR_RANfunctionID:
251       break;
252     case RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails:
253       {
254         RICsubscriptionDetails_t subDetails = next_ie->value.choice.RICsubscriptionDetails; 
255         RICeventTriggerDefinition_t triggerDef = subDetails.ricEventTriggerDefinition;
256         RICactions_ToBeSetup_List_t actionList = subDetails.ricAction_ToBeSetup_List;
257
258         //We are ignoring the trigger definition
259
260         //We identify the first action whose type is REPORT
261         //That is the only one accepted; all others are rejected
262         
263         int actionCount = actionList.list.count;
264         fprintf(stderr, "action count%d\n", actionCount);
265
266         auto **item_array = actionList.list.array;
267
268         bool foundAction = false;
269
270         for (int i=0; i < actionCount; i++) {
271
272           auto *next_item = item_array[i];
273           RICactionID_t actionId = ((RICaction_ToBeSetup_ItemIEs*)next_item)->value.choice.RICaction_ToBeSetup_Item.ricActionID;
274           RICactionType_t actionType = ((RICaction_ToBeSetup_ItemIEs*)next_item)->value.choice.RICaction_ToBeSetup_Item.ricActionType;
275
276           if (!foundAction && actionType == RICactionType_report) {
277             reqActionId = actionId;
278             actionIdsAccept.push_back(reqActionId);
279             printf("adding accept\n");
280             foundAction = true;
281           } else {
282             reqActionId = actionId;
283             printf("adding reject\n");
284             actionIdsReject.push_back(reqActionId);
285           }
286         }
287         
288         break;
289       }
290     }
291     
292   }
293
294   fprintf(stderr, "After Processing Subscription Request\n");
295
296   fprintf(stderr, "requestorId %d\n", reqRequestorId);
297   fprintf(stderr, "instanceId %d\n", reqInstanceId);
298
299
300   for (int i=0; i < actionIdsAccept.size(); i++) {
301     fprintf(stderr, "Action ID %d %ld\n", i, actionIdsAccept.at(i));
302     
303   }
304
305   E2AP_PDU *e2ap_pdu = (E2AP_PDU*)calloc(1,sizeof(E2AP_PDU));
306
307   long *accept_array = &actionIdsAccept[0];
308   long *reject_array = &actionIdsReject[0];
309   int accept_size = actionIdsAccept.size();
310   int reject_size = actionIdsReject.size();
311
312   generate_e2apv1_subscription_response_success(e2ap_pdu, accept_array, reject_array, accept_size, reject_size, reqRequestorId, reqInstanceId);
313
314   encode_and_send_sctp_data(e2ap_pdu,socket_fd);
315
316   //Start thread for sending REPORT messages
317
318   //  std::thread loop_thread;
319
320   long funcId = 1;
321
322   run_report_loop(reqRequestorId, reqInstanceId, funcId, reqActionId, socket_fd);
323
324   //  loop_thread = std::thread(&run_report_loop);
325
326 }