Fixed up issues with last commit
[sim/e2-interface.git] / e2sim / e2sm_examples / kpm_e2sm / src / kpm / kpm_callbacks.cpp
1 /*****************************************************************************
2 #                                                                            *
3 # Copyright 2020 AT&T Intellectual Property                                  *
4 #                                                                            *
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                                    *
8 #                                                                            *
9 #      http://www.apache.org/licenses/LICENSE-2.0                            *
10 #                                                                            *
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 #                                                                            *
17 ******************************************************************************/
18
19 #include <iostream>
20 #include <fstream>
21 #include <vector>
22
23
24
25 extern "C" {
26   #include "OCUCP-PF-Container.h"
27   #include "OCTET_STRING.h"
28   #include "asn_application.h"
29   #include "E2SM-KPM-IndicationMessage.h"
30   #include "FQIPERSlicesPerPlmnListItem.h"
31   #include "E2SM-KPM-RANfunction-Description.h"
32   #include "E2SM-KPM-IndicationHeader-Format1.h"
33   #include "E2SM-KPM-IndicationHeader.h"
34   #include "Timestamp.h"
35   #include "E2AP-PDU.h"
36   #include "RICsubscriptionRequest.h"
37   #include "RICsubscriptionResponse.h"
38   #include "RICactionType.h"
39   #include "ProtocolIE-Field.h"
40   #include "ProtocolIE-SingleContainer.h"
41   #include "InitiatingMessage.h"
42 }
43
44 #include "kpm_callbacks.hpp"
45 #include "encode_kpm.hpp"
46
47 #include "encode_e2apv1.hpp"
48
49 #include <nlohmann/json.hpp>
50 #include <thread>
51
52
53 using json = nlohmann::json;
54
55 using namespace std;
56 class E2Sim;
57
58
59 E2Sim e2sim;
60
61 int main(int argc, char* argv[]) {
62
63   fprintf(stderr, "Starting KPM processor sim");
64
65   asn_codec_ctx_t *opt_cod;
66
67   E2SM_KPM_RANfunction_Description_t *ranfunc_desc =
68     (E2SM_KPM_RANfunction_Description_t*)calloc(1,sizeof(E2SM_KPM_RANfunction_Description_t));
69   encode_kpm_function_description(ranfunc_desc);
70
71   uint8_t e2smbuffer[8192];
72   size_t e2smbuffer_size = 8192;
73
74   asn_enc_rval_t er =
75     asn_encode_to_buffer(opt_cod,
76                          ATS_ALIGNED_BASIC_PER,
77                          &asn_DEF_E2SM_KPM_RANfunction_Description,
78                          ranfunc_desc, e2smbuffer, e2smbuffer_size);
79   
80   fprintf(stderr, "er encded is %d\n", er.encoded);
81   fprintf(stderr, "after encoding message\n");
82   fprintf(stderr, "here is encoded message %s\n", e2smbuffer);
83
84   uint8_t *ranfuncdesc = (uint8_t*)calloc(1,er.encoded);
85   memcpy(ranfuncdesc, e2smbuffer, er.encoded);
86
87   printf("this is the char array %s\n", (char*)ranfuncdesc);
88
89   OCTET_STRING_t *ranfunc_ostr = (OCTET_STRING_t*)calloc(1,sizeof(OCTET_STRING_t));
90   ranfunc_ostr->buf = (uint8_t*)calloc(1,er.encoded);
91   ranfunc_ostr->size = er.encoded;
92   memcpy(ranfunc_ostr->buf,e2smbuffer,er.encoded);
93
94   printf("!!!lenth of ranfuncdesc is %d\n", strlen((char*)ranfuncdesc));
95   printf("value of this index is %d\n", ranfuncdesc[0]);
96   printf("value of this index is %d\n", ranfuncdesc[1]);
97   printf("value of this index is %d\n", ranfuncdesc[2]);
98   printf("value of this index is %d\n", ranfuncdesc[3]);
99   printf("value of this index is %d\n", ranfuncdesc[4]);
100   printf("value of this index is %d\n", ranfuncdesc[5]);
101   printf("value of this index is %d\n", ranfuncdesc[6]);
102   printf("value of this index is %d\n", ranfuncdesc[10]);
103   printf("value of this index is %d\n", ranfuncdesc[15]);
104   printf("value of this index is %d\n", ranfuncdesc[100]);
105   printf("value of this index is %d\n", ranfuncdesc[101]);
106   
107   e2sim.register_e2sm(0,ranfunc_ostr);
108   e2sim.register_subscription_callback(0,&callback_kpm_subscription_request);
109
110   e2sim.run_loop(argc, argv);
111
112 }
113
114 /*
115 void run_report_loop(long requestorId, long instanceId, long ranFunctionId, long actionId) {
116
117 }
118 */
119
120 void run_report_loop(long requestorId, long instanceId, long ranFunctionId, long actionId) {
121
122   //Process simulation file
123
124   ifstream simfile;
125   string line;
126
127   long seqNum = 1;
128   
129   simfile.open("simulation.txt", ios::in);
130
131   //  cout << "step1" << endl;
132
133   std::ifstream ue_stream("/playpen/src/ueMeasReport.txt");
134   std::ifstream cell_stream("/playpen/src/cellMeasReport.txt");
135
136   json all_ues_json;
137
138   ue_stream  >> all_ues_json;
139
140   json all_cells_json;
141
142   cell_stream >> all_cells_json;
143
144   asn_codec_ctx_t *opt_cod;
145
146   //  cout << "UE RF Measurements" << endl;
147   //  cout << "******************" << endl;
148
149   int numMeasReports = (all_ues_json["/ueMeasReport/ueMeasReportList"_json_pointer]).size();
150
151   for (int i = 0; i < numMeasReports; i++) {
152     int nextCellId;
153     int nextRsrp;
154     int nextRsrq;
155     int nextRssinr;
156     //    cout << "UE number " + i << endl;
157     //    cout << "**********" << endl;
158     json::json_pointer p1(std::string("/ueMeasReport/ueMeasReportList/") + std::to_string(i) +"/nrCellIdentity");
159     nextCellId = all_ues_json[p1].get<int>();
160     //    cout << "Serving Cell " << nextCellId << endl;
161     
162     json::json_pointer p2(std::string("/ueMeasReport/ueMeasReportList/") + std::to_string(i) +"/servingCellRfReport/rsrp");
163     nextRsrp = all_ues_json[p2].get<int>();
164     //    cout << "  RSRP " << nextRsrp << endl;
165     json::json_pointer p3(std::string("/ueMeasReport/ueMeasReportList/") + std::to_string(i) +"/servingCellRfReport/rsrq");
166     nextRsrq = all_ues_json[p3].get<int>();
167     //    cout << "  RSRQ " << nextRsrq << endl;
168     json::json_pointer p4(std::string("/ueMeasReport/ueMeasReportList/") + std::to_string(i) +"/servingCellRfReport/rssinr");
169     nextRssinr = all_ues_json[p4].get<int>();
170     //    cout << "  RSSINR " << nextRssinr << endl;
171
172     json::json_pointer p5(std::string("/ueMeasReport/ueMeasReportList/") + std::to_string(i) +"/neighbourCellList");
173
174     int numNeighborCells = (all_ues_json[p5]).size();
175
176
177     //REPORT Message 3 -- Encode and send OCUCP user-level report
178     
179     E2SM_KPM_IndicationMessage_t *ind_msg3 =
180       (E2SM_KPM_IndicationMessage_t*)calloc(1,sizeof(E2SM_KPM_IndicationMessage_t));
181     E2AP_PDU *pdu3 = (E2AP_PDU*)calloc(1,sizeof(E2AP_PDU));
182     
183     uint8_t *crnti_buf = (uint8_t*)calloc(1,2);
184
185     if (nextCellId == 0) {
186       uint8_t *buf2 = (uint8_t*)"12";
187       memcpy(crnti_buf, buf2, 2);
188     } else if (nextCellId == 1) {
189       uint8_t *buf2 = (uint8_t*)"22";
190       memcpy(crnti_buf, buf2, 2);
191     }
192
193     std::string serving_str = "{\"rsrp\": " + std::to_string(nextRsrp) + ", \"rsrq\": " +
194       std::to_string(nextRsrq) + ", \"rssinr\": " + std::to_string(nextRssinr) + "}";
195     const uint8_t *serving_buf = reinterpret_cast<const uint8_t*>(serving_str.c_str());
196         
197     std::string neighbor_str = "[";
198
199     int nextNbCell;
200     int nextNbRsrp;
201     int nextNbRsrq;
202     int nextNbRssinr;
203
204     for (int j = 0; j < numNeighborCells; j++) {
205       json::json_pointer p8(std::string("/ueMeasReport/ueMeasReportList/") + std::to_string(i) +"/neighbourCellList/" + std::to_string(j) + "/nbCellIdentity");
206       nextNbCell = all_ues_json[p8].get<int>();
207       //cout << "Neighbor Cell " << all_ues_json[p8] << endl;
208       json::json_pointer p9(std::string("/ueMeasReport/ueMeasReportList/") + std::to_string(i)
209                             +"/neighbourCellList/" + std::to_string(j) + "/nbCellRfReport/rsrp");
210       nextNbRsrp = all_ues_json[p9].get<int>();
211       //cout << "  RSRP " << nextNbRsrp << endl;
212
213       json::json_pointer p10(std::string("/ueMeasReport/ueMeasReportList/") + std::to_string(i)
214                             +"/neighbourCellList/" + std::to_string(j) + "/nbCellRfReport/rsrq");
215       nextNbRsrq = all_ues_json[p10].get<int>();
216       //cout << "  RSRQ " << nextNbRsrq << endl;
217
218       json::json_pointer p11(std::string("/ueMeasReport/ueMeasReportList/") + std::to_string(i)
219                              +"/neighbourCellList/" + std::to_string(j) + "/nbCellRfReport/rssinr");
220       nextNbRssinr = all_ues_json[p11].get<int>();
221       //cout << "  RSSINR " << nextNbRssinr << endl;
222
223       if (j != 0) {
224         neighbor_str += ",";
225
226       }
227
228       neighbor_str += "{\"CID\" : \"" + std::to_string(nextNbCell) + "\", \"Cell-RF\" : \"{\"rsrp\": " + std::to_string(nextNbRsrp) +
229         ", \"rsrq\": " + std::to_string(nextNbRsrq) + ", \"rssinr\": " + std::to_string(nextNbRssinr) + "}}";
230       
231     }
232
233     neighbor_str += "]";
234     
235     const uint8_t *neighbor_buf = reinterpret_cast<const uint8_t*>(neighbor_str.c_str());
236     
237     //    printf("Neighbor string\n%s", neighbor_buf);
238
239     uint8_t *plmnid_buf = (uint8_t*)"747";
240     uint8_t *nrcellid_buf = (uint8_t*)"12340";
241
242     /*
243     encode_kpm_report_rancontainer_cucp_parameterized(ind_msg3, plmnid_buf, nrcellid_buf, crnti_buf, serving_buf, neighbor_buf);
244     
245     uint8_t e2smbuffer3[8192];
246     size_t e2smbuffer_size3 = 8192;
247
248     
249     asn_enc_rval_t er3 = asn_encode_to_buffer(opt_cod,
250                                               ATS_ALIGNED_BASIC_PER,
251                                               &asn_DEF_E2SM_KPM_IndicationMessage,
252                                               ind_msg3, e2smbuffer3, e2smbuffer_size3);
253     
254     fprintf(stderr, "er encded is %d\n", er3.encoded);
255     fprintf(stderr, "after encoding message\n");
256     uint8_t *e2smheader_buf3 = (uint8_t*)"";
257     
258     generate_e2apv1_indication_request_parameterized(pdu3, requestorId,
259                                                      instanceId, ranFunctionId,
260                                                      actionId, seqNum, e2smheader_buf3, 0, e2smbuffer3, er3.encoded);
261     
262                                                      e2sim.encode_and_send_sctp_data(pdu3);
263     */
264     
265     seqNum++;
266         
267   }
268
269
270   //  cout << "Cell Measurements" << endl;
271   //  cout << "******************" << endl;
272
273   int numCellMeasReports = (all_cells_json["/cellMeasReport/cellMeasReportList"_json_pointer]).size();
274
275   uint8_t *sst_buf = (uint8_t*)"1";
276   uint8_t *sd_buf = (uint8_t*)"100";
277   uint8_t *plmnid_buf = (uint8_t*)"747";
278   
279   for (int i = 0; i < numCellMeasReports; i++) {
280
281     int nextCellId;
282     int nextPdcpBytesDL;
283     int nextPdcpBytesUL;
284     int nextPRBBytesDL;
285     int nextPRBBytesUL;
286
287     json::json_pointer p1(std::string("/cellMeasReport/cellMeasReportList/") + std::to_string(i) +"/nrCellIdentity");
288     nextCellId = all_cells_json[p1].get<int>();
289     //    cout << std::string("Cell number ") << nextCellId << endl;
290     
291     //    cout << "**********" << endl;
292     
293     json::json_pointer p2(std::string("/cellMeasReport/cellMeasReportList/") + std::to_string(i) +"/pdcpByteMeasReport/pdcpBytesDl");
294     nextPdcpBytesDL = all_cells_json[p2].get<int>();
295     //    cout << std::string("  PDCP Bytes DL ") << nextPdcpBytesDL << endl;
296
297     json::json_pointer p3(std::string("/cellMeasReport/cellMeasReportList/") + std::to_string(i) +"/pdcpByteMeasReport/pdcpBytesUl");
298     nextPdcpBytesUL = all_cells_json[p3].get<int>();    
299     //    cout << std::string("  PDCP Bytes UL ") << nextPdcpBytesUL << endl;
300
301     uint8_t *buf = (uint8_t*)"GNBCUUP5";
302     
303     int bytes_dl = nextPdcpBytesDL;
304
305     int bytes_ul = nextPdcpBytesUL;
306
307     //    int bytes_dl = 3905;
308     //    int bytes_ul = 1609321;
309     
310     E2SM_KPM_IndicationMessage_t *ind_msg2 =
311       (E2SM_KPM_IndicationMessage_t*)calloc(1,sizeof(E2SM_KPM_IndicationMessage_t));
312     E2AP_PDU *pdu2 = (E2AP_PDU*)calloc(1,sizeof(E2AP_PDU));
313     
314     encode_kpm_report_style5_parameterized(ind_msg2 , buf, bytes_dl, bytes_ul, sst_buf, sd_buf, plmnid_buf);
315     
316     uint8_t e2smbuffer2[8192];
317     size_t e2smbuffer_size2 = 8192;
318     
319     asn_enc_rval_t er2 = asn_encode_to_buffer(opt_cod,
320                                               ATS_ALIGNED_BASIC_PER,
321                                               &asn_DEF_E2SM_KPM_IndicationMessage,
322                                               ind_msg2, e2smbuffer2, e2smbuffer_size2);
323
324     fprintf(stderr, "er encded is %d\n", er2.encoded);
325     fprintf(stderr, "after encoding message\n");
326
327     E2SM_KPM_IndicationHeader_t *ihead =
328       (E2SM_KPM_IndicationHeader_t*)calloc(1,sizeof(E2SM_KPM_IndicationHeader_t));
329
330     
331     E2SM_KPM_IndicationHeader_Format1_t* ind_header =
332       (E2SM_KPM_IndicationHeader_Format1_t*)calloc(1,sizeof(E2SM_KPM_IndicationHeader_Format1_t));
333
334     OCTET_STRING_t *plmnid = (OCTET_STRING_t*)calloc(1,sizeof(OCTET_STRING_t));
335     plmnid->buf = (uint8_t*)calloc(3,1);
336     plmnid->size = 3;
337     memcpy(plmnid->buf, plmnid_buf, plmnid->size);
338
339     long fqival = 9;
340     long qcival = 9;
341
342     OCTET_STRING_t *sst = (OCTET_STRING_t*)calloc(1, sizeof(OCTET_STRING_t));
343     sst->size = 6;
344     sst->buf = (uint8_t*)calloc(1,6);
345     memcpy(sst->buf,sst_buf,sst->size);
346     
347
348     OCTET_STRING_t *sds = (OCTET_STRING_t*)calloc(1, sizeof(OCTET_STRING_t));
349     sds->size = 3;
350     sds->buf = (uint8_t*)calloc(1,3);
351     memcpy(sds->buf, sd_buf, sds->size);
352     
353     
354     SNSSAI_t *snssai = (SNSSAI_t*)calloc(1, sizeof(SNSSAI_t));
355     ASN_STRUCT_RESET(asn_DEF_SNSSAI,snssai);
356     snssai->sST.buf = (uint8_t*)calloc(1,1);
357     snssai->sST.size = 1;
358     memcpy(snssai->sST.buf, sst_buf, 1);
359     snssai->sD = (OCTET_STRING_t*)calloc(1, sizeof(OCTET_STRING_t));
360     snssai->sD->buf = (uint8_t*)calloc(1,3);
361     snssai->sD->size = 3;
362     memcpy(snssai->sD->buf, sd_buf, 3);
363
364         
365     ind_header->pLMN_Identity = plmnid;
366     ind_header->fiveQI = &fqival;
367
368     BIT_STRING_t *nrcellid = (BIT_STRING_t*)calloc(1, sizeof(BIT_STRING_t));;
369     nrcellid->buf = (uint8_t*)calloc(1,5);
370     nrcellid->size = 5;
371     nrcellid->buf[0] = 0x22;
372     nrcellid->buf[1] = 0x5B;
373     nrcellid->buf[2] = 0xD6;
374     nrcellid->buf[3] = 0x00;
375     nrcellid->buf[4] = 0x70;
376     
377     nrcellid->bits_unused = 4;
378
379     BIT_STRING_t *gnb_bstring = (BIT_STRING_t*)calloc(1, sizeof(BIT_STRING_t));;
380     gnb_bstring->buf = (uint8_t*)calloc(1,4);
381     gnb_bstring->size = 4;
382     gnb_bstring->buf[0] = 0xB5;
383     gnb_bstring->buf[1] = 0xC6;
384     gnb_bstring->buf[2] = 0x77;
385     gnb_bstring->buf[3] = 0x88;
386     
387     gnb_bstring->bits_unused = 3;
388
389     INTEGER_t *cuup_id = (INTEGER_t*)calloc(1, sizeof(INTEGER_t));
390     uint8_t buffer[1];
391     buffer[0] = 20000;
392     cuup_id->buf = (uint8_t*)calloc(1,1);
393     memcpy(cuup_id->buf, buffer, 1);
394     cuup_id->size = 1;
395
396     ind_header->id_GlobalKPMnode_ID = (GlobalKPMnode_ID*)calloc(1,sizeof(GlobalKPMnode_ID));
397     ind_header->id_GlobalKPMnode_ID->present = GlobalKPMnode_ID_PR_gNB;
398     ind_header->id_GlobalKPMnode_ID->choice.gNB.global_gNB_ID.gnb_id.present = GNB_ID_Choice_PR_gnb_ID;
399     ind_header->id_GlobalKPMnode_ID->choice.gNB.global_gNB_ID.gnb_id.choice.gnb_ID = *gnb_bstring;
400     ind_header->id_GlobalKPMnode_ID->choice.gNB.global_gNB_ID.plmn_id = *plmnid;
401     ind_header->id_GlobalKPMnode_ID->choice.gNB.gNB_CU_UP_ID = cuup_id;
402
403     ind_header->nRCGI = (NRCGI*)calloc(1,sizeof(NRCGI));
404     ind_header->nRCGI->pLMN_Identity = *plmnid;
405     ind_header->nRCGI->nRCellIdentity = *nrcellid;
406
407     ind_header->sliceID = snssai;
408     ind_header->qci = &qcival;
409     //    ind_header->message_Type = ;
410     //    ind_header->gNB_DU_ID = ;
411
412     
413     uint8_t *buf5 = (uint8_t*)"GNBCUUP5";
414     OCTET_STRING_t *cuupname = (OCTET_STRING_t*)calloc(1, sizeof(OCTET_STRING_t));
415     cuupname->size = 8;
416     cuupname->buf = (uint8_t*)calloc(1,8);
417     memcpy(cuupname->buf, buf5, cuupname->size);    
418
419     
420     ind_header->gNB_Name = (GNB_Name*)calloc(1,sizeof(GNB_Name));
421     ind_header->gNB_Name->present = GNB_Name_PR_gNB_CU_UP_Name;
422     ind_header->gNB_Name->choice.gNB_CU_UP_Name = *cuupname;
423
424
425     ind_header->global_GNB_ID = (GlobalgNB_ID*)calloc(1,sizeof(GlobalgNB_ID));
426     ind_header->global_GNB_ID->plmn_id = *plmnid;
427     ind_header->global_GNB_ID->gnb_id.present = GNB_ID_Choice_PR_gnb_ID;
428     ind_header->global_GNB_ID->gnb_id.choice.gnb_ID = *gnb_bstring;
429     
430
431     ihead->present = E2SM_KPM_IndicationHeader_PR_indicationHeader_Format1;
432     ihead->choice.indicationHeader_Format1 = *ind_header;
433
434     printf("IndicationHeader - now printing xer\n");
435     xer_fprint(stderr, &asn_DEF_E2SM_KPM_IndicationHeader, ihead);
436     printf("IndicationHeader - done printing xer\n");      
437
438     uint8_t e2sm_header_buffer[8192];
439     size_t e2sm_header_buffer_size = 8192;
440     
441     asn_enc_rval_t er4 = asn_encode_to_buffer(opt_cod,
442                                               ATS_ALIGNED_BASIC_PER,
443                                               &asn_DEF_E2SM_KPM_IndicationHeader,
444                                               ihead, e2sm_header_buffer, e2sm_header_buffer_size);    
445     
446     uint8_t *e2smheader_buf2 = (uint8_t*)"";
447
448     int seqNum0 = 1;
449
450     if (i == 0) {
451     
452       encoding::generate_e2apv1_indication_request_parameterized(pdu2, requestorId,
453                                                                  instanceId, ranFunctionId,
454                                                                  actionId, seqNum0, e2sm_header_buffer, er4.encoded, e2smbuffer2, er2.encoded);
455       
456       e2sim.encode_and_send_sctp_data(pdu2);
457     }
458
459     seqNum++;
460
461     
462
463     json::json_pointer p4(std::string("/cellMeasReport/cellMeasReportList/") + std::to_string(i) +"/prbMeasReport/availPrbDl");
464     nextPRBBytesDL = all_cells_json[p4].get<int>();    
465     //    cout << std::string("  PRB Bytes DL ") << all_cells_json[p4] << endl;
466
467     json::json_pointer p5(std::string("/cellMeasReport/cellMeasReportList/") + std::to_string(i) +"/prbMeasReport/availPrbUl");
468     nextPRBBytesUL = all_cells_json[p5].get<int>();
469     //    cout << std::string("  PRB Bytes UL ") << all_cells_json[p5] << endl;
470
471
472     //REPORT Message 1 -- Encode and send ODU cell-level report
473     
474     E2SM_KPM_IndicationMessage_t *ind_msg1 =
475       (E2SM_KPM_IndicationMessage_t*)calloc(1,sizeof(E2SM_KPM_IndicationMessage_t));
476     E2AP_PDU *pdu = (E2AP_PDU*)calloc(1,sizeof(E2AP_PDU));
477     
478     long fiveqi = 7;
479
480     uint8_t *nrcellid_buf = (uint8_t*)"12340";
481     long dl_prbs = nextPRBBytesDL;
482     long ul_prbs = nextPRBBytesUL;
483
484     /*
485     encode_kpm_report_style1_parameterized(ind_msg1, fiveqi, dl_prbs, ul_prbs, sst_buf, sd_buf, plmnid_buf, nrcellid_buf, &dl_prbs, &ul_prbs);
486     
487     uint8_t e2smbuffer[8192];
488     size_t e2smbuffer_size = 8192;
489     
490     asn_enc_rval_t er = asn_encode_to_buffer(opt_cod,
491                                              ATS_ALIGNED_BASIC_PER,
492                                              &asn_DEF_E2SM_KPM_IndicationMessage,
493                                              ind_msg1, e2smbuffer, e2smbuffer_size);
494     
495     fprintf(stderr, "er encded is %d\n", er.encoded);
496     fprintf(stderr, "after encoding message\n");
497     uint8_t *e2smheader_buf = (uint8_t*)"";
498     
499     uint8_t *cpid_buf = (uint8_t*)"CPID";
500     
501     fprintf(stderr, "About to encode Indication\n");
502     generate_e2apv1_indication_request_parameterized(pdu, requestorId,
503                                                      instanceId, ranFunctionId,
504                                                      actionId, seqNum, e2smheader_buf, 0, e2smbuffer, er.encoded);
505     
506                                                      e2sim.encode_and_send_sctp_data(pdu);
507     */
508     seqNum++;
509     
510   }
511
512
513
514   /*
515   if (simfile.is_open()) {
516
517     while (getline(simfile, line)) {
518       cout << line << "\n";
519
520       //REPORT Message 1 -- Encode and send ODU cell-level report
521
522       E2SM_KPM_IndicationMessage_t *ind_msg1 =
523         (E2SM_KPM_IndicationMessage_t*)calloc(1,sizeof(E2SM_KPM_IndicationMessage_t));
524       E2AP_PDU *pdu = (E2AP_PDU*)calloc(1,sizeof(E2AP_PDU));
525
526       long fiveqi = 7;
527       uint8_t *sst_buf = (uint8_t*)"1";
528       uint8_t *sd_buf = (uint8_t*)"100";
529       uint8_t *plmnid_buf = (uint8_t*)"747";
530       uint8_t *nrcellid_buf = (uint8_t*)"12340";
531       long dl_prbs = 100;
532       long ul_prbs = 50; 
533      
534       encode_kpm_report_style1_parameterized(ind_msg1, fiveqi, dl_prbs, ul_prbs, sst_buf, sd_buf, plmnid_buf, nrcellid_buf, &dl_prbs, &ul_prbs);
535
536       uint8_t e2smbuffer[8192];
537       size_t e2smbuffer_size = 8192;
538       asn_codec_ctx_t *opt_cod;
539
540       asn_enc_rval_t er = asn_encode_to_buffer(opt_cod,
541                                                ATS_ALIGNED_BASIC_PER,
542                                                &asn_DEF_E2SM_KPM_IndicationMessage,
543                                                ind_msg1, e2smbuffer, e2smbuffer_size);
544       
545       fprintf(stderr, "er encded is %d\n", er.encoded);
546       fprintf(stderr, "after encoding message\n");
547       uint8_t *e2smheader_buf = (uint8_t*)"header";
548
549       uint8_t *cpid_buf = (uint8_t*)"CPID";
550
551       fprintf(stderr, "About to encode Indication\n");
552       generate_e2apv1_indication_request_parameterized(pdu, requestorId,
553                                                        instanceId, ranFunctionId,
554                                                        actionId, seqNum, e2smheader_buf, 6, e2smbuffer, er.encoded);
555
556       encode_and_send_sctp_data(pdu, socket_fd);
557       
558       seqNum++;
559
560       //REPORT Message 2 -- Encode and send OCUUP cell-level report
561
562       uint8_t *buf = (uint8_t*)"GNBCUUP5";
563
564       int bytes_dl = 40000;
565       int bytes_ul = 50000;
566
567       E2SM_KPM_IndicationMessage_t *ind_msg2 =
568         (E2SM_KPM_IndicationMessage_t*)calloc(1,sizeof(E2SM_KPM_IndicationMessage_t));
569       E2AP_PDU *pdu2 = (E2AP_PDU*)calloc(1,sizeof(E2AP_PDU));
570       
571       encode_kpm_report_style5_parameterized(ind_msg2 , buf, bytes_dl, bytes_ul, sst_buf, sd_buf, plmnid_buf);
572
573       uint8_t e2smbuffer2[8192];
574       size_t e2smbuffer_size2 = 8192;
575
576
577       asn_enc_rval_t er2 = asn_encode_to_buffer(opt_cod,
578                                                ATS_ALIGNED_BASIC_PER,
579                                                &asn_DEF_E2SM_KPM_IndicationMessage,
580                                                ind_msg2, e2smbuffer2, e2smbuffer_size2);
581       
582       fprintf(stderr, "er encded is %d\n", er2.encoded);
583       fprintf(stderr, "after encoding message\n");
584       uint8_t *e2smheader_buf2 = (uint8_t*)"header";
585
586       generate_e2apv1_indication_request_parameterized(pdu2, requestorId,
587                                                        instanceId, ranFunctionId,
588                                                        actionId, seqNum, e2smheader_buf2, 6, e2smbuffer2, er2.encoded);
589
590       encode_and_send_sctp_data(pdu2, socket_fd);
591       
592       seqNum++;
593
594       //REPORT Message 3 -- Encode and send OCUCP user-level report
595
596       E2SM_KPM_IndicationMessage_t *ind_msg3 =
597         (E2SM_KPM_IndicationMessage_t*)calloc(1,sizeof(E2SM_KPM_IndicationMessage_t));
598       E2AP_PDU *pdu3 = (E2AP_PDU*)calloc(1,sizeof(E2AP_PDU));
599
600       uint8_t *crnti_buf = (uint8_t*)"12";
601       //      uint8_t *serving_buf = (uint8_t*)"RSRP10";
602       //uint8_t *neighbor_buf = (uint8_t*)"-10,-15";
603       int rsrpServ = 10;
604       int rsrqServ = 0;
605       int rssinrServ = 0;
606
607       std::string serving_str = "{\"rsrp\": " + std::to_string(rsrpServ) + ", \"rsrq\": " +
608         std::to_string(rsrqServ) + ", \"rssinr\": " + std::to_string(rssinrServ) + "}";
609       const uint8_t *serving_buf = reinterpret_cast<const uint8_t*>(serving_str.c_str());
610
611
612       neighbor_cell_entry n_entries[3];
613       n_entries[0] = {"123", 10, 0, 0};
614       n_entries[1] = {"456", 10, 0, 0};
615       n_entries[2] = {"789", 10, 0, 0};
616
617       std::string neighbor_str = "[";
618
619       for (int i=0; i < sizeof(n_entries)/sizeof(n_entries[0]); i++) {
620
621         if (i != 0) {
622           neighbor_str += ",";
623         }
624         neighbor_str += "{\"CID\" : \"" + std::string(n_entries[i].cellid) + "\", \"Cell-RF\" : \"{\"rsrp\": " + std::to_string(n_entries[i].rsrp) +
625           ", \"rsrq\": " + std::to_string(n_entries[i].rsrq) + ", \"rssinr\": " + std::to_string(n_entries[i].rsrp) + "}}";
626       }
627
628       neighbor_str += "]";
629
630       const uint8_t *neighbor_buf = reinterpret_cast<const uint8_t*>(neighbor_str.c_str());
631
632       printf("Neighbor string\n%s", neighbor_buf);
633
634       encode_kpm_report_rancontainer_cucp_parameterized(ind_msg3, plmnid_buf, nrcellid_buf, crnti_buf, serving_buf, neighbor_buf);
635       
636       uint8_t e2smbuffer3[8192];
637       size_t e2smbuffer_size3 = 8192;
638
639       asn_enc_rval_t er3 = asn_encode_to_buffer(opt_cod,
640                                                 ATS_ALIGNED_BASIC_PER,
641                                                 &asn_DEF_E2SM_KPM_IndicationMessage,
642                                                 ind_msg3, e2smbuffer3, e2smbuffer_size3);
643       
644       fprintf(stderr, "er encded is %d\n", er3.encoded);
645       fprintf(stderr, "after encoding message\n");
646       uint8_t *e2smheader_buf3 = (uint8_t*)"header";
647
648       generate_e2apv1_indication_request_parameterized(pdu3, requestorId,
649                                                        instanceId, ranFunctionId,
650                                                        actionId, seqNum, e2smheader_buf3, 6, e2smbuffer3, er3.encoded);
651
652       encode_and_send_sctp_data(pdu3, socket_fd);
653             
654       seqNum++;
655       
656       //Encode and send OCUUP user-level report
657
658
659       
660       //Encode and send ODU user-level report
661
662       
663
664       
665     }
666
667     simfile.close();
668
669   }
670   */
671
672 }
673
674
675 void callback_kpm_subscription_request(E2AP_PDU_t *sub_req_pdu) {
676
677   fprintf(stderr, "Calling callback_kpm_subscription_request\n");
678
679   //Record RIC Request ID
680   //Go through RIC action to be Setup List
681   //Find first entry with REPORT action Type
682   //Record ricActionID
683   //Encode subscription response
684
685   RICsubscriptionRequest_t orig_req =
686     sub_req_pdu->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
687   
688   RICsubscriptionResponse_IEs_t *ricreqid =
689     (RICsubscriptionResponse_IEs_t*)calloc(1, sizeof(RICsubscriptionResponse_IEs_t));
690                                            
691   int count = orig_req.protocolIEs.list.count;
692   int size = orig_req.protocolIEs.list.size;
693   
694   RICsubscriptionRequest_IEs_t **ies = (RICsubscriptionRequest_IEs_t**)orig_req.protocolIEs.list.array;
695
696   fprintf(stderr, "count%d\n", count);
697   fprintf(stderr, "size%d\n", size);
698
699   RICsubscriptionRequest_IEs__value_PR pres;
700
701   long reqRequestorId;
702   long reqInstanceId;
703   long reqActionId;
704
705   std::vector<long> actionIdsAccept;
706   std::vector<long> actionIdsReject;
707
708   for (int i=0; i < count; i++) {
709     RICsubscriptionRequest_IEs_t *next_ie = ies[i];
710     pres = next_ie->value.present;
711     
712     fprintf(stderr, "The next present value %d\n", pres);
713
714     switch(pres) {
715     case RICsubscriptionRequest_IEs__value_PR_RICrequestID:
716       {
717         fprintf(stderr,"in case request id\n"); 
718         RICrequestID_t reqId = next_ie->value.choice.RICrequestID;
719         long requestorId = reqId.ricRequestorID;
720         long instanceId = reqId.ricInstanceID;
721         fprintf(stderr, "requestorId %d\n", requestorId);
722         fprintf(stderr, "instanceId %d\n", instanceId);
723         reqRequestorId = requestorId;
724         reqInstanceId = instanceId;
725
726         break;
727       }
728     case RICsubscriptionRequest_IEs__value_PR_RANfunctionID:
729       {
730         fprintf(stderr,"in case ran func id\n");        
731         break;
732       }
733     case RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails:
734       {
735         fprintf(stderr,"in case subscription details\n");
736         RICsubscriptionDetails_t subDetails = next_ie->value.choice.RICsubscriptionDetails;
737         fprintf(stderr,"in case subscription details 1\n");     
738         RICeventTriggerDefinition_t triggerDef = subDetails.ricEventTriggerDefinition;
739         fprintf(stderr,"in case subscription details 2\n");     
740         RICactions_ToBeSetup_List_t actionList = subDetails.ricAction_ToBeSetup_List;
741         fprintf(stderr,"in case subscription details 3\n");
742         //We are ignoring the trigger definition
743
744         //We identify the first action whose type is REPORT
745         //That is the only one accepted; all others are rejected
746         
747         int actionCount = actionList.list.count;
748         fprintf(stderr, "action count%d\n", actionCount);
749
750         auto **item_array = actionList.list.array;
751
752         bool foundAction = false;
753
754         for (int i=0; i < actionCount; i++) {
755
756           auto *next_item = item_array[i];
757           RICactionID_t actionId = ((RICaction_ToBeSetup_ItemIEs*)next_item)->value.choice.RICaction_ToBeSetup_Item.ricActionID;
758           RICactionType_t actionType = ((RICaction_ToBeSetup_ItemIEs*)next_item)->value.choice.RICaction_ToBeSetup_Item.ricActionType;
759
760           if (!foundAction && actionType == RICactionType_report) {
761             reqActionId = actionId;
762             actionIdsAccept.push_back(reqActionId);
763             printf("adding accept\n");
764             foundAction = true;
765           } else {
766             reqActionId = actionId;
767             printf("adding reject\n");
768             actionIdsReject.push_back(reqActionId);
769           }
770         }
771         
772         break;
773       }
774     default:
775       {
776         fprintf(stderr,"in case default\n");    
777         break;
778       }      
779     }
780     
781   }
782
783   fprintf(stderr, "After Processing Subscription Request\n");
784
785   fprintf(stderr, "requestorId %d\n", reqRequestorId);
786   fprintf(stderr, "instanceId %d\n", reqInstanceId);
787
788
789   for (int i=0; i < actionIdsAccept.size(); i++) {
790     fprintf(stderr, "Action ID %d %ld\n", i, actionIdsAccept.at(i));
791     
792   }
793
794   E2AP_PDU *e2ap_pdu = (E2AP_PDU*)calloc(1,sizeof(E2AP_PDU));
795
796   long *accept_array = &actionIdsAccept[0];
797   long *reject_array = &actionIdsReject[0];
798   int accept_size = actionIdsAccept.size();
799   int reject_size = actionIdsReject.size();
800
801   encoding::generate_e2apv1_subscription_response_success(e2ap_pdu, accept_array, reject_array, accept_size, reject_size, reqRequestorId, reqInstanceId);
802
803   e2sim.encode_and_send_sctp_data(e2ap_pdu);
804
805   //Start thread for sending REPORT messages
806
807   //  std::thread loop_thread;
808
809   long funcId = 1;
810
811   run_report_loop(reqRequestorId, reqInstanceId, funcId, reqActionId);
812
813   //  loop_thread = std::thread(&run_report_loop);
814
815 }