First release
[sim/ns3-o-ran-e2.git] / model / asn1c-types.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2022 Northeastern University
4  * Copyright (c) 2022 Sapienza, University of Rome
5  * Copyright (c) 2022 University of Padova
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation;
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * Author: Andrea Lacava <thecave003@gmail.com>
21  *                 Tommaso Zugno <tommasozugno@gmail.com>
22  *                 Michele Polese <michele.polese@gmail.com>
23  */
24
25 #include <ns3/asn1c-types.h>
26 #include <ns3/log.h>
27
28 NS_LOG_COMPONENT_DEFINE ("Asn1Types");
29
30 namespace ns3 {
31
32 OctetString::OctetString (std::string value, size_t size)
33 {
34   NS_LOG_FUNCTION (this);
35   CreateBaseOctetString (size);
36   memcpy (m_octetString->buf, value.c_str (), size);
37 }
38
39 void OctetString::CreateBaseOctetString (size_t size)
40 {
41   NS_LOG_FUNCTION (this);
42   m_octetString = (OCTET_STRING_t *) calloc (1, sizeof (OCTET_STRING_t));
43   m_octetString->buf = (uint8_t *) calloc (1, size);
44   m_octetString->size = size;
45 }
46
47 OctetString::OctetString (void *value, size_t size)
48 {
49   NS_LOG_FUNCTION (this);
50   CreateBaseOctetString (size);
51   memcpy (m_octetString->buf, value, size);
52 }
53
54 OctetString::~OctetString ()
55 {
56   NS_LOG_FUNCTION (this);
57   // if (m_octetString->buf != NULL)
58     // free (m_octetString->buf);
59   free (m_octetString);
60 }
61
62 OCTET_STRING_t *
63 OctetString::GetPointer ()
64 {
65   return m_octetString;
66 }
67
68 OCTET_STRING_t
69 OctetString::GetValue ()
70 {
71   return *m_octetString;
72 }
73
74 std::string OctetString::DecodeContent(){
75   int size = this->GetValue ().size;
76   char out[size + 1];
77   std::memcpy (out, this->GetValue ().buf, size);
78   out[size] = '\0';
79
80   return std::string (out);
81 }
82
83 BitString::BitString (std::string value, size_t size)
84
85 {
86   NS_LOG_FUNCTION (this);
87   m_bitString = (BIT_STRING_t *) calloc (1, sizeof (BIT_STRING_t));
88   m_bitString->buf = (uint8_t *) calloc (1, size);
89   m_bitString->size = size;
90   memcpy (m_bitString->buf, value.c_str(), size);
91 }
92
93 BitString::BitString (std::string value, size_t size, size_t bits_unused)
94     : BitString::BitString (value, size)
95 {
96   NS_LOG_FUNCTION (this);
97   m_bitString->bits_unused = bits_unused;
98 }
99
100 BitString::~BitString ()
101 {
102   NS_LOG_FUNCTION (this);
103   free (m_bitString);
104 }
105
106 BIT_STRING_t *
107 BitString::GetPointer ()
108 {
109   return m_bitString;
110 }
111
112 BIT_STRING_t
113 BitString::GetValue ()
114 {
115   return *m_bitString;
116 }
117
118 NrCellId::NrCellId (uint16_t value)
119 {
120   NS_LOG_FUNCTION (this);
121   
122   // TODO check why with more than 15 cells is not working
123   // if (value > 15)
124   // {
125   //   NS_FATAL_ERROR ("TODO: update the encoding to support more than 15 cells");
126   // }
127   
128   // convert value to a char array
129   // char ar [5] {};
130   // ar [4] = value * 16; // multiply by 16 to obtain a left shift of 4 bits
131   uint16_t shifted = value * 16;
132   std::string str_shift = std::to_string (shifted);
133   m_bitString = Create<BitString> (str_shift, 5, 4);
134 }
135
136 NrCellId::~NrCellId ()
137 {  
138 }
139
140 BIT_STRING_t
141 NrCellId::GetValue ()
142 {
143   return m_bitString->GetValue ();
144 }
145
146 BIT_STRING_t*
147 NrCellId::GetPointer ()
148 {
149   return m_bitString->GetPointer ();
150 }
151
152 Snssai::Snssai (std::string sst)
153 {
154   m_sNssai = (SNSSAI_t *) calloc (1, sizeof (SNSSAI_t));
155   m_sst = (OCTET_STRING_t *) calloc (1, sizeof (OCTET_STRING_t));
156   m_sst->buf = (uint8_t *) calloc (1, sst.size ());
157   m_sst->size = sst.size ();
158   memcpy (m_sst->buf, sst.c_str (), sst.size ());
159   m_sNssai->sST = *m_sst;
160 }
161 Snssai::Snssai (std::string sst, std::string sd) : Snssai (sst)
162 {
163   m_sd = (OCTET_STRING_t *) calloc (1, sizeof (OCTET_STRING_t));
164   m_sd->buf = (uint8_t *) calloc (1, sst.size ());
165   m_sd->size = sd.size ();
166   memcpy (m_sd->buf, sd.c_str (), sd.size ());
167   m_sNssai->sD = m_sd;
168 }
169
170 Snssai::~Snssai ()
171 {
172   if (m_sNssai != NULL)
173     ASN_STRUCT_FREE (asn_DEF_SNSSAI, m_sNssai);
174
175   // if (m_sst != NULL)
176   //   ASN_STRUCT_FREE (asn_DEF_OCTET_STRING, m_sst);
177   // if (m_sd != NULL)
178   //   ASN_STRUCT_FREE (asn_DEF_OCTET_STRING, m_sd);
179 }
180
181 SNSSAI_t *
182 Snssai::GetPointer ()
183 {
184   return m_sNssai;
185 }
186
187 SNSSAI_t
188 Snssai::GetValue ()
189 {
190   return *m_sNssai;
191 }
192
193 void
194 MeasQuantityResultsWrap::AddRsrp (long rsrp)
195 {
196
197   m_measQuantityResults->rsrp = (RSRP_Range_t *) calloc (1, sizeof (RSRP_Range_t));
198   *m_measQuantityResults->rsrp = rsrp;
199 }
200
201 void
202 MeasQuantityResultsWrap::AddRsrq (long rsrq)
203 {
204   m_measQuantityResults->rsrq = (RSRQ_Range_t *) calloc (1, sizeof (RSRQ_Range_t));
205   *m_measQuantityResults->rsrq = rsrq;
206 }
207
208 void
209 MeasQuantityResultsWrap::AddSinr (long sinr)
210 {
211   m_measQuantityResults->sinr = (SINR_Range_t *) calloc (1, sizeof (SINR_Range_t));
212   *m_measQuantityResults->sinr = sinr;
213 }
214
215 MeasQuantityResultsWrap::MeasQuantityResultsWrap ()
216 {
217   m_measQuantityResults = (MeasQuantityResults_t *) calloc (1, sizeof (MeasQuantityResults_t));
218 }
219
220 MeasQuantityResultsWrap::~MeasQuantityResultsWrap ()
221 {
222   // if (m_measQuantityResults->sinr != NULL)
223   //   ASN_STRUCT_FREE (asn_DEF_SINR_Range, m_measQuantityResults->sinr);
224
225   // if (m_measQuantityResults->rsrp != NULL)
226   //   ASN_STRUCT_FREE (asn_DEF_RSRP_Range, m_measQuantityResults->rsrp);
227
228   // if (m_measQuantityResults->rsrq != NULL)
229   //   ASN_STRUCT_FREE (asn_DEF_RSRQ_Range, m_measQuantityResults->rsrq);
230
231   // if (m_measQuantityResults != NULL){
232   //     free (m_measQuantityResults);
233   //   }
234 }
235
236 MeasQuantityResults_t *
237 MeasQuantityResultsWrap::GetPointer ()
238 {
239   return m_measQuantityResults;
240 }
241
242 MeasQuantityResults_t
243 MeasQuantityResultsWrap::GetValue ()
244 {
245   return *m_measQuantityResults;
246 }
247
248 ResultsPerCsiRsIndex::ResultsPerCsiRsIndex (long csiRsIndex, MeasQuantityResults_t *csiRsResults)
249     : ResultsPerCsiRsIndex (csiRsIndex)
250 {
251   m_resultsPerCsiRsIndex->csi_RS_Results = csiRsResults;
252 }
253
254 ResultsPerCsiRsIndex::ResultsPerCsiRsIndex (long csiRsIndex)
255 {
256   m_resultsPerCsiRsIndex =
257       (ResultsPerCSI_RS_Index_t *) calloc (1, sizeof (ResultsPerCSI_RS_Index_t));
258   m_resultsPerCsiRsIndex->csi_RS_Index = csiRsIndex;
259 }
260
261 ResultsPerCSI_RS_Index_t *
262 ResultsPerCsiRsIndex::GetPointer ()
263 {
264   return m_resultsPerCsiRsIndex;
265 }
266
267 ResultsPerCSI_RS_Index_t
268 ResultsPerCsiRsIndex::GetValue ()
269 {
270   return *m_resultsPerCsiRsIndex;
271 }
272
273 ResultsPerSSBIndex::ResultsPerSSBIndex (long ssbIndex, MeasQuantityResults_t *ssbResults)
274     : ResultsPerSSBIndex (ssbIndex)
275 {
276   m_resultsPerSSBIndex->ssb_Results = ssbResults;
277 }
278
279 ResultsPerSSBIndex::ResultsPerSSBIndex (long ssbIndex)
280 {
281   m_resultsPerSSBIndex = (ResultsPerSSB_Index_t *) calloc (1, sizeof (ResultsPerSSB_Index_t));
282   m_resultsPerSSBIndex->ssb_Index = ssbIndex;
283 }
284
285 ResultsPerSSB_Index_t *
286 ResultsPerSSBIndex::GetPointer ()
287 {
288   return m_resultsPerSSBIndex;
289 }
290
291 ResultsPerSSB_Index_t
292 ResultsPerSSBIndex::GetValue ()
293 {
294   return *m_resultsPerSSBIndex;
295 }
296
297 void
298 MeasResultNr::AddCellResults (MeasResultNr::ResultCell cell, MeasQuantityResults_t *results)
299 {
300   switch (cell)
301     {
302     case MeasResultNr::ResultCell::SSB:
303
304       m_measResultNr->measResult.cellResults.resultsSSB_Cell = results;
305       break;
306
307     case MeasResultNr::ResultCell::CSI_RS:
308
309       m_measResultNr->measResult.cellResults.resultsCSI_RS_Cell = results;
310       break;
311
312     default:
313       NS_LOG_ERROR ("Unrecognized cell identifier.");
314       break;
315     }
316 }
317
318 void
319 MeasResultNr::AddPerSsbIndexResults (ResultsPerSSB_Index_t *resultsSSB_Index)
320 {
321   ASN_SEQUENCE_ADD (m_measResultNr->measResult.rsIndexResults->resultsSSB_Indexes,
322                     resultsSSB_Index);
323 }
324
325 void
326 MeasResultNr::AddPerCsiRsIndexResults (ResultsPerCSI_RS_Index_t *resultsCSI_RS_Index)
327 {
328   ASN_SEQUENCE_ADD (m_measResultNr->measResult.rsIndexResults->resultsCSI_RS_Indexes,
329                     resultsCSI_RS_Index);
330 }
331
332 void MeasResultNr::AddPhyCellId (long physCellId)
333 {
334   PhysCellId_t *s_physCellId = (PhysCellId_t *) calloc (1, sizeof (PhysCellId_t));
335   *s_physCellId = physCellId;
336   m_measResultNr->physCellId = s_physCellId;
337 }
338
339 MeasResultNr::MeasResultNr (long physCellId) : MeasResultNr ()
340 {
341   AddPhyCellId (physCellId);
342 }
343
344 MeasResultNr::MeasResultNr ()
345 {
346   m_measResultNr = (MeasResultNR_t *) calloc (1, sizeof (MeasResultNR_t));
347   m_shouldFree = false;
348 }
349
350 MeasResultNr::~MeasResultNr ()
351 {
352   if (m_shouldFree)
353     {
354       free (m_measResultNr);
355     }
356 }
357
358 MeasResultNR_t *
359 MeasResultNr::GetPointer ()
360 {
361   // Fallback procedure, this should not happen if correctly used;
362   m_shouldFree = false;
363   return m_measResultNr;
364 }
365
366 MeasResultNR_t
367 MeasResultNr::GetValue ()
368 {
369   m_shouldFree = true;
370   return *m_measResultNr;
371 }
372
373 MeasResultEutra::MeasResultEutra (long eutraPhysCellId, long rsrp, long rsrq, long sinr)
374     : MeasResultEutra (eutraPhysCellId)
375 {
376   AddRsrp (rsrp);
377   AddRsrq (rsrq);
378   AddSinr (sinr);
379 }
380
381 MeasResultEutra::MeasResultEutra (long eutraPhysCellId)
382 {
383   m_measResultEutra = (MeasResultEUTRA_t *) calloc (1, sizeof (MeasResultEUTRA_t));
384   m_measResultEutra->eutra_PhysCellId = eutraPhysCellId;
385 }
386
387 void
388 MeasResultEutra::AddRsrp (long rsrp)
389 {
390   m_measResultEutra->measResult.rsrp =
391       (RSRP_RangeEUTRA_t *) calloc (1, sizeof (RSRP_RangeEUTRA_t));
392   *m_measResultEutra->measResult.rsrp = rsrp;
393 }
394 void
395 MeasResultEutra::AddRsrq (long rsrq)
396 {
397   m_measResultEutra->measResult.rsrq =
398       (RSRQ_RangeEUTRA_t *) calloc (1, sizeof (RSRQ_RangeEUTRA_t));
399   *m_measResultEutra->measResult.rsrq = rsrq;
400 }
401 void
402 MeasResultEutra::AddSinr (long sinr)
403 {
404   m_measResultEutra->measResult.sinr =
405       (SINR_RangeEUTRA_t *) calloc (1, sizeof (SINR_RangeEUTRA_t));
406   *m_measResultEutra->measResult.sinr = sinr;
407 }
408
409 MeasResultEUTRA_t *
410 MeasResultEutra::GetPointer ()
411 {
412   return m_measResultEutra;
413 }
414
415 MeasResultEUTRA_t
416 MeasResultEutra::GetValue ()
417 {
418   return *m_measResultEutra;
419 }
420
421 MeasResultPCellWrap::MeasResultPCellWrap (long eutraPhysCellId, long rsrpResult, long rsrqResult)
422     : MeasResultPCellWrap (eutraPhysCellId)
423 {
424   AddRsrpResult (rsrpResult);
425   AddRsrqResult (rsrqResult);
426 }
427
428 MeasResultPCellWrap::MeasResultPCellWrap (long eutraPhysCellId)
429 {
430   m_measResultPCell = (MeasResultPCell_t *) calloc (1, sizeof (MeasResultPCell_t));
431   m_measResultPCell->eutra_PhysCellId = eutraPhysCellId;
432 }
433
434 void
435 MeasResultPCellWrap::AddRsrpResult (long rsrpResult)
436 {
437   m_measResultPCell->rsrpResult = rsrpResult;
438 }
439
440 void
441 MeasResultPCellWrap::AddRsrqResult (long rsrqResult)
442 {
443   m_measResultPCell->rsrqResult = rsrqResult;
444 }
445
446 MeasResultPCell_t *
447 MeasResultPCellWrap::GetPointer ()
448 {
449   return m_measResultPCell;
450 }
451
452 MeasResultPCell_t
453 MeasResultPCellWrap::GetValue ()
454 {
455   return *m_measResultPCell;
456 }
457
458 MeasResultServMo::MeasResultServMo (long servCellId, MeasResultNR_t measResultServingCell,
459                                     MeasResultNR_t *measResultBestNeighCell)
460     : MeasResultServMo (servCellId, measResultServingCell)
461 {
462   m_measResultServMo->measResultBestNeighCell = measResultBestNeighCell;
463 }
464
465 MeasResultServMo::MeasResultServMo (long servCellId, MeasResultNR_t measResultServingCell)
466 {
467   m_measResultServMo = (MeasResultServMO_t *) calloc (1, sizeof (MeasResultServMO_t));
468   m_measResultServMo->servCellId = servCellId;
469   m_measResultServMo->measResultServingCell = measResultServingCell;
470 }
471
472 MeasResultServMO_t *
473 MeasResultServMo::GetPointer ()
474 {
475   return m_measResultServMo;
476 }
477
478 MeasResultServMO_t
479 MeasResultServMo::GetValue ()
480 {
481   return *m_measResultServMo;
482 }
483
484 void
485 ServingCellMeasurementsWrap::AddMeasResultPCell (MeasResultPCell_t *measResultPCell)
486 {
487   if (m_servingCellMeasurements->present != ServingCellMeasurements_PR_eutra_measResultPCell)
488     {
489       NS_LOG_ERROR ("Wrong measurement item for this present, it will not be added.");
490     }
491   m_servingCellMeasurements->choice.eutra_measResultPCell = measResultPCell;
492 }
493
494 void
495 ServingCellMeasurementsWrap::AddMeasResultServMo (MeasResultServMO_t *measResultServMO)
496 {
497   if (m_servingCellMeasurements->present != ServingCellMeasurements_PR_nr_measResultServingMOList)
498     {
499       NS_LOG_ERROR ("Wrong measurement item for this present, it will not be added.");
500     }
501
502   ASN_SEQUENCE_ADD (&m_nr_measResultServingMOList->list, measResultServMO);
503 }
504
505 ServingCellMeasurementsWrap::ServingCellMeasurementsWrap (ServingCellMeasurements_PR present)
506 {
507   m_servingCellMeasurements =
508       (ServingCellMeasurements_t *) calloc (1, sizeof (ServingCellMeasurements_t));
509   m_servingCellMeasurements->present = present;
510
511   if (m_servingCellMeasurements->present == ServingCellMeasurements_PR_nr_measResultServingMOList)
512     {
513       m_nr_measResultServingMOList =
514           (MeasResultServMOList_t *) calloc (1, sizeof (MeasResultServMOList_t));
515       m_servingCellMeasurements->choice.nr_measResultServingMOList = m_nr_measResultServingMOList;
516     }
517 }
518
519 ServingCellMeasurements_t *
520 ServingCellMeasurementsWrap::GetPointer ()
521 {
522   return m_servingCellMeasurements;
523 }
524
525 ServingCellMeasurements_t
526 ServingCellMeasurementsWrap::GetValue ()
527 {
528   return *m_servingCellMeasurements;
529 }
530
531 Ptr<L3RrcMeasurements>
532 L3RrcMeasurements::CreateL3RrcUeSpecificSinrServing (long servingCellId, long physCellId, long sinr)
533 {
534   Ptr<L3RrcMeasurements> l3RrcMeasurement = Create<L3RrcMeasurements> (RRCEvent_b1);
535   Ptr<ServingCellMeasurementsWrap> servingCellMeasurements =
536       Create<ServingCellMeasurementsWrap> (ServingCellMeasurements_PR_nr_measResultServingMOList);
537
538   Ptr<MeasResultNr> measResultNr = Create<MeasResultNr> (physCellId);
539   Ptr<MeasQuantityResultsWrap> measQuantityResultWrap = Create<MeasQuantityResultsWrap> ();
540   measQuantityResultWrap->AddSinr (sinr);
541   measResultNr->AddCellResults (MeasResultNr::SSB, measQuantityResultWrap->GetPointer ());
542   Ptr<MeasResultServMo> measResultServMo =
543       Create<MeasResultServMo> (servingCellId, measResultNr->GetValue ());
544   servingCellMeasurements->AddMeasResultServMo (measResultServMo->GetPointer ());
545   l3RrcMeasurement->AddServingCellMeasurement (servingCellMeasurements->GetPointer ());
546   return l3RrcMeasurement;
547 }
548
549 Ptr<L3RrcMeasurements>
550 L3RrcMeasurements::CreateL3RrcUeSpecificSinrNeigh ()
551 {
552   return Create<L3RrcMeasurements> (RRCEvent_b1);
553 }
554
555 void
556 L3RrcMeasurements::AddNeighbourCellMeasurement (long neighCellId, long sinr)
557 {
558   Ptr<MeasResultNr> measResultNr = Create<MeasResultNr> (neighCellId);
559   Ptr<MeasQuantityResultsWrap> measQuantityResultWrap = Create<MeasQuantityResultsWrap> ();
560   measQuantityResultWrap->AddSinr (sinr);
561   measResultNr->AddCellResults (MeasResultNr::SSB, measQuantityResultWrap->GetPointer ());
562
563   this->AddMeasResultNRNeighCells (measResultNr->GetPointer ()); // MAX 8 UE per message (standard)
564 }
565
566 void
567 L3RrcMeasurements::AddServingCellMeasurement (ServingCellMeasurements_t *servingCellMeasurements)
568 {
569   m_l3RrcMeasurements->servingCellMeasurements = servingCellMeasurements;
570 }
571
572 void
573 L3RrcMeasurements::AddMeasResultEUTRANeighCells (MeasResultEUTRA_t *measResultItemEUTRA)
574 {
575   if (m_measItemsCounter == L3RrcMeasurements::MAX_MEAS_RESULTS_ITEMS)
576     {
577       NS_LOG_ERROR ("Maximum number of items ("
578                     << L3RrcMeasurements::MAX_MEAS_RESULTS_ITEMS
579                     << ")for the standard reached. This item will not be "
580                        "inserted in the list");
581       return;
582     }
583
584   if (m_l3RrcMeasurements->measResultNeighCells == NULL)
585     {
586       addMeasResultNeighCells (MeasResultNeighCells_PR_measResultListEUTRA);
587     }
588
589   if (m_l3RrcMeasurements->measResultNeighCells->present !=
590       MeasResultNeighCells_PR_measResultListEUTRA)
591     {
592       NS_LOG_ERROR ("Wrong measurement item for this list, it will not be added.");
593       return;
594     }
595
596   m_measItemsCounter++;
597   ASN_SEQUENCE_ADD (&m_measResultListEUTRA->list, measResultItemEUTRA);
598 }
599
600 void
601 L3RrcMeasurements::AddMeasResultNRNeighCells (MeasResultNR_t *measResultItemNR)
602 {
603   if (m_measItemsCounter == L3RrcMeasurements::MAX_MEAS_RESULTS_ITEMS)
604     {
605       NS_LOG_ERROR ("Maximum number of items ("
606                     << L3RrcMeasurements::MAX_MEAS_RESULTS_ITEMS
607                     << ")for the standard reached. This item will not be "
608                        "inserted in the list");
609       return;
610     }
611
612   if (m_l3RrcMeasurements->measResultNeighCells == NULL)
613     {
614       addMeasResultNeighCells (MeasResultNeighCells_PR_measResultListNR);
615     }
616
617   if (m_l3RrcMeasurements->measResultNeighCells->present !=
618       MeasResultNeighCells_PR_measResultListNR)
619     {
620       NS_LOG_ERROR ("Wrong measurement item for this list, it will not be added.");
621       return;
622     }
623
624   m_measItemsCounter++;
625   ASN_SEQUENCE_ADD (&m_measResultListNR->list, measResultItemNR);
626 }
627
628 void
629 L3RrcMeasurements::addMeasResultNeighCells (MeasResultNeighCells_PR present)
630 {
631   m_l3RrcMeasurements->measResultNeighCells =
632       (MeasResultNeighCells_t *) calloc (1, sizeof (MeasResultNeighCells_t));
633   m_l3RrcMeasurements->measResultNeighCells->present = present;
634
635   switch (present)
636     {
637       case MeasResultNeighCells_PR_measResultListEUTRA: {
638         m_measResultListEUTRA =
639             (MeasResultListEUTRA_t *) calloc (1, sizeof (MeasResultListEUTRA_t));
640         m_l3RrcMeasurements->measResultNeighCells->choice.measResultListEUTRA =
641             m_measResultListEUTRA;
642         break;
643       }
644
645       case MeasResultNeighCells_PR_measResultListNR: {
646         m_measResultListNR = (MeasResultListNR_t *) calloc (1, sizeof (MeasResultListNR_t));
647         m_l3RrcMeasurements->measResultNeighCells->choice.measResultListNR = m_measResultListNR;
648         break;
649       }
650
651       default: {
652         NS_LOG_ERROR ("Unrecognized present for Measurment result.");
653         break;
654       }
655     }
656 }
657
658 L3RrcMeasurements::L3RrcMeasurements (RRCEvent_t rrcEvent)
659 {
660   m_l3RrcMeasurements = (L3_RRC_Measurements_t *) calloc (1, sizeof (L3_RRC_Measurements_t));
661   m_l3RrcMeasurements->rrcEvent = rrcEvent;
662   m_measItemsCounter = 0;
663 }
664
665 L3RrcMeasurements::L3RrcMeasurements (L3_RRC_Measurements_t *l3RrcMeasurements)
666 {
667   m_l3RrcMeasurements = l3RrcMeasurements;
668 }
669
670 L3RrcMeasurements::~L3RrcMeasurements ()
671 {
672   // Memory deallocation is handled by RIC Indication Message 
673   // if (m_l3RrcMeasurements != NULL)
674   //   {
675   //     ASN_STRUCT_FREE (asn_DEF_L3_RRC_Measurements, m_l3RrcMeasurements);
676   //   }
677 }
678
679 L3_RRC_Measurements *
680 L3RrcMeasurements::GetPointer ()
681 {
682   return m_l3RrcMeasurements;
683 }
684
685 L3_RRC_Measurements
686 L3RrcMeasurements::GetValue ()
687 {
688   return *m_l3RrcMeasurements;
689 }
690
691 // TODO change definition and return the values
692 // this function shall be finished for decoding
693 void
694 L3RrcMeasurements::ExtractMeasurementsFromL3RrcMeas (L3_RRC_Measurements_t *l3RrcMeasurements)
695 {
696   RRCEvent_t rrcEvent = l3RrcMeasurements->rrcEvent; // Mandatory
697   switch (rrcEvent)
698     {
699       case RRCEvent_b1: {
700         NS_LOG_DEBUG ("RRCEvent_b1");
701       }
702       break;
703
704       case RRCEvent_a3: {
705         NS_LOG_DEBUG ("RRCEvent_a3");
706       }
707       break;
708       case RRCEvent_a5: {
709         NS_LOG_DEBUG ("RRCEvent_a5");
710       }
711       break;
712       case RRCEvent_periodic: {
713         NS_LOG_DEBUG ("RRCEvent_periodic");
714       }
715       break;
716
717       default: {
718         NS_LOG_ERROR ("Rrc event unrecognised");
719       }
720       break;
721     }
722
723   if (l3RrcMeasurements->measResultNeighCells)
724     {
725       MeasResultNeighCells_t *measResultNeighCells = l3RrcMeasurements->measResultNeighCells;
726       switch (measResultNeighCells->present)
727         {
728           case MeasResultNeighCells_PR_NOTHING: { /* No components present */
729             NS_LOG_DEBUG ("No components present");
730           }
731           break;
732           case MeasResultNeighCells_PR_measResultListNR: {
733             NS_LOG_DEBUG ("MeasResultNeighCells_PR_measResultListNR");
734             //  measResultNeighCells->choice.measResultListNR
735           }
736           break;
737           case MeasResultNeighCells_PR_measResultListEUTRA: {
738             NS_LOG_DEBUG ("MeasResultNeighCells_PR_measResultListEUTRA");
739           }
740           break;
741         default:
742           NS_LOG_ERROR ("measResultNeighCells present unrecognised");
743           break;
744         }
745     }
746   if (l3RrcMeasurements->servingCellMeasurements)
747     {
748       ServingCellMeasurements_t *servingCellMeasurements =
749           l3RrcMeasurements->servingCellMeasurements;
750       switch (servingCellMeasurements->present)
751         {
752           case ServingCellMeasurements_PR_NOTHING: { /* No components present */
753             NS_LOG_DEBUG ("No components present");
754           }
755           break;
756           case ServingCellMeasurements_PR_nr_measResultServingMOList: {
757             NS_LOG_DEBUG ("ServingCellMeasurements_PR_nr_measResultServingMOList");
758           }
759           break;
760           case ServingCellMeasurements_PR_eutra_measResultPCell: {
761             NS_LOG_DEBUG ("ServingCellMeasurements_PR_eutra_measResultPCell");
762           }
763           break;
764         default:
765           NS_LOG_ERROR ("servingCellMeasurements present unrecognised");
766           break;
767         }
768     }
769 }
770
771 double 
772 L3RrcMeasurements::ThreeGppMapSinr (double sinr)
773 {
774   double inputEnd = 40;
775   double inputStart = -23;
776   double outputStart = 0;
777   double outputEnd = 127;
778   double outputSinr;
779   double slope = (outputEnd - outputStart) / (inputEnd - inputStart);
780
781   if (sinr < inputStart)
782     {
783       outputSinr = outputStart;
784     }
785   else if (sinr > inputEnd)
786     {
787       outputSinr = outputEnd;
788     }
789   else
790     {
791       outputSinr = outputStart + std::round (slope * (sinr - inputStart));
792     }
793
794   NS_LOG_DEBUG ("input sinr" << sinr << " output sinr" << outputSinr);
795
796   return outputSinr;
797 }
798
799 MeasurementItem::MeasurementItem (std::string name)
800 {
801
802   m_measurementItem = (PM_Info_Item_t *) calloc (1, sizeof (PM_Info_Item_t));
803   m_pmType = (MeasurementType_t *) calloc (1, sizeof (MeasurementType_t));
804   m_measurementItem->pmType = *m_pmType;
805
806   m_measName =
807       (MeasurementTypeName_t *) calloc (1, sizeof (MeasurementTypeName_t));
808   m_measName->buf = (uint8_t *) calloc (1, sizeof (OCTET_STRING));
809   m_measName->size = name.length ();
810   memcpy (m_measName->buf, name.c_str (), m_measName->size);
811
812   m_measurementItem->pmType.choice.measName = *m_measName;
813   m_measurementItem->pmType.present = MeasurementType_PR_measName;
814 }
815
816 MeasurementItem::MeasurementItem (std::string name, long value) : MeasurementItem (name)
817 {
818   NS_LOG_FUNCTION (this << name << "long" << value);
819   this->CreateMeasurementValue (MeasurementValue_PR_valueInt);
820   m_measurementItem->pmVal.choice.valueInt = value;
821 }
822
823 MeasurementItem::MeasurementItem (std::string name, double value) : MeasurementItem (name)
824 {
825   NS_LOG_FUNCTION (this << name << "double" << value);
826   this->CreateMeasurementValue (MeasurementValue_PR_valueReal);
827   m_measurementItem->pmVal.choice.valueReal = value;
828 }
829
830 MeasurementItem::MeasurementItem (std::string name, Ptr<L3RrcMeasurements>value)
831     : MeasurementItem (name)
832 {
833   NS_LOG_FUNCTION (this << name << "L3 RRC" << value);
834   this->CreateMeasurementValue (MeasurementValue_PR_valueRRC);
835   m_measurementItem->pmVal.choice.valueRRC = value->GetPointer ();
836 }
837
838 void
839 MeasurementItem::CreateMeasurementValue (MeasurementValue_PR measurementValue_PR)
840 {
841   m_pmVal = ((MeasurementValue_t *) calloc (1, sizeof (MeasurementValue_t)));
842   m_measurementItem->pmVal = *m_pmVal;
843   m_measurementItem->pmVal.present = measurementValue_PR;
844 }
845
846 MeasurementItem::~MeasurementItem ()
847 {
848   NS_LOG_FUNCTION (this);
849   if (m_pmVal != NULL)
850     ASN_STRUCT_FREE (asn_DEF_MeasurementValue, m_pmVal);
851
852   if (m_measName != NULL)
853     {
854       free (m_measName);
855     }
856
857   if (m_pmType != NULL)
858     ASN_STRUCT_FREE (asn_DEF_MeasurementType, m_pmType);
859 }
860
861 PM_Info_Item_t *
862 MeasurementItem::GetPointer ()
863 {
864   return m_measurementItem;
865 }
866
867 PM_Info_Item_t
868 MeasurementItem::GetValue ()
869 {
870   return *m_measurementItem;
871 }
872
873 RANParameterItem::RANParameterItem (RANParameter_Item_t *ranParameterItem)
874 {
875   m_ranParameterItem = ranParameterItem;
876 }
877
878 RANParameterItem::~RANParameterItem ()
879 {
880   if (m_ranParameterItem != NULL)
881     ASN_STRUCT_FREE (asn_DEF_RANParameter_Item, m_ranParameterItem);
882 }
883
884 std::vector<RANParameterItem>
885 RANParameterItem::ExtractRANParametersFromRANParameter (RANParameter_Item_t *ranParameterItem)
886 {
887   std::vector<RANParameterItem> ranParameterList;
888
889   // NS_LOG_DEBUG ("RAN Parameter examined:");
890   // xer_fprint (stderr, &asn_DEF_RANParameter_Item, ranParameterItem);
891   // NS_LOG_DEBUG ("----");
892   // NS_LOG_DEBUG (" ID " << ranParameterItem->ranParameterItem_ID);
893
894   switch (ranParameterItem->ranParameterItem_valueType->present)
895     {
896       case RANParameter_ValueType_PR_NOTHING: {
897         NS_LOG_DEBUG ("[E2SM] RANParameter_ValueType_PR_NOTHING");
898         break;
899       }
900       case RANParameter_ValueType_PR_ranParameter_Element: {
901         RANParameterItem newItem =
902             RANParameterItem (ranParameterItem);
903         NS_LOG_DEBUG ("[E2SM] RANParameter_ValueType_PR_ranParameter_Element");
904         RANParameter_ELEMENT_t *ranParameterElement =
905             ranParameterItem->ranParameterItem_valueType->choice.ranParameter_Element;
906         newItem.m_keyFlag = &ranParameterElement->keyFlag;
907         switch (ranParameterElement->ranParameter_Value.present)
908           {
909             case RANParameter_Value_PR_NOTHING: {
910               NS_LOG_DEBUG ("[E2SM] RANParameter_Value_PR_NOTHING");
911               newItem.m_valueType = ValueType::Nothing;
912               break;
913             }
914             case RANParameter_Value_PR_valueInt: {
915               NS_LOG_DEBUG ("[E2SM] RANParameter_Value_PR_valueInt");
916               newItem.m_valueInt = ranParameterElement->ranParameter_Value.choice.valueInt;
917               newItem.m_valueType = ValueType::Int;
918               NS_LOG_DEBUG ("[E2SM] Value: " << newItem.m_valueInt);
919               break;
920             }
921             case RANParameter_Value_PR_valueOctS: {
922               NS_LOG_DEBUG ("[E2SM] RANParameter_Value_PR_valueOctS");
923               newItem.m_valueStr = Create<OctetString> (
924                   (void *) ranParameterElement->ranParameter_Value.choice.valueOctS.buf,
925                   ranParameterElement->ranParameter_Value.choice.valueOctS.size);
926               newItem.m_valueType = ValueType::OctectString;
927               NS_LOG_DEBUG ("[E2SM] Value: OctectString");
928               break;
929             }
930           }
931         ranParameterList.push_back (newItem);
932         break;
933       }
934       case RANParameter_ValueType_PR_ranParameter_Structure: {
935         NS_LOG_DEBUG ("[E2SM] RANParameter_ValueType_PR_ranParameter_Structure");
936         RANParameter_STRUCTURE_t *ranParameterStructure =
937             ranParameterItem->ranParameterItem_valueType->choice.ranParameter_Structure;
938         int count = ranParameterStructure->sequence_of_ranParameters.list.count;
939         for (int i = 0; i < count; i++)
940           {
941             RANParameter_Item_t *childRanItem =
942                 ranParameterStructure->sequence_of_ranParameters.list.array[i];
943
944             for (RANParameterItem extractedParameter : ExtractRANParametersFromRANParameter (childRanItem))
945               {
946                 ranParameterList.push_back (extractedParameter);
947               }
948           }
949         break;
950       }
951       case RANParameter_ValueType_PR_ranParameter_List: {
952         NS_LOG_DEBUG ("[E2SM] RANParameter_ValueType_PR_ranParameter_List");
953         // No list passed for the moment from RIC, thus no parsed as case
954         // ranParameterItem->ranParameterItem_valueType->choice.ranParameter_List;
955         break;
956       }
957     }
958
959   return ranParameterList;
960 }
961
962
963 }; // namespace ns3