5G-LENA nr-v3.1-69-g2dd513a7
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-phy-rx-trace.cc
1// Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2// Copyright (c) 2015, NYU WIRELESS, Tandon School of Engineering, New York University
3//
4// SPDX-License-Identifier: GPL-2.0-only
5
6#include "nr-phy-rx-trace.h"
7
8#include <ns3/log.h>
9#include <ns3/nr-gnb-net-device.h>
10#include <ns3/nr-ue-net-device.h>
11#include <ns3/simulator.h>
12#include <ns3/string.h>
13
14#include <stdio.h>
15#include <string>
16
17namespace ns3
18{
19
20NS_LOG_COMPONENT_DEFINE("NrPhyRxTrace");
21
22NS_OBJECT_ENSURE_REGISTERED(NrPhyRxTrace);
23
24std::ofstream NrPhyRxTrace::m_dlDataSinrFile;
25std::string NrPhyRxTrace::m_dlDataSinrFileName;
26
27std::ofstream NrPhyRxTrace::m_dlCtrlSinrFile;
28std::string NrPhyRxTrace::m_dlCtrlSinrFileName;
29
30std::ofstream NrPhyRxTrace::m_rxPacketTraceFile;
31std::string NrPhyRxTrace::m_rxPacketTraceFilename;
32std::string NrPhyRxTrace::m_simTag;
33std::string NrPhyRxTrace::m_resultsFolder;
34
35std::ofstream NrPhyRxTrace::m_rxedGnbPhyCtrlMsgsFile;
36std::string NrPhyRxTrace::m_rxedGnbPhyCtrlMsgsFileName;
37std::ofstream NrPhyRxTrace::m_txedGnbPhyCtrlMsgsFile;
38std::string NrPhyRxTrace::m_txedGnbPhyCtrlMsgsFileName;
39
40std::ofstream NrPhyRxTrace::m_rxedUePhyCtrlMsgsFile;
41std::string NrPhyRxTrace::m_rxedUePhyCtrlMsgsFileName;
42std::ofstream NrPhyRxTrace::m_txedUePhyCtrlMsgsFile;
43std::string NrPhyRxTrace::m_txedUePhyCtrlMsgsFileName;
44std::ofstream NrPhyRxTrace::m_rxedUePhyDlDciFile;
45std::string NrPhyRxTrace::m_rxedUePhyDlDciFileName;
46
47std::ofstream NrPhyRxTrace::m_dlPathlossFile;
48std::string NrPhyRxTrace::m_dlPathlossFileName;
49std::ofstream NrPhyRxTrace::m_ulPathlossFile;
50std::string NrPhyRxTrace::m_ulPathlossFileName;
51
52std::ofstream NrPhyRxTrace::m_dlCtrlPathlossFile;
53std::string NrPhyRxTrace::m_dlCtrlPathlossFileName;
54std::ofstream NrPhyRxTrace::m_dlDataPathlossFile;
55std::string NrPhyRxTrace::m_dlDataPathlossFileName;
56
57NrPhyRxTrace::NrPhyRxTrace()
58{
59}
60
61NrPhyRxTrace::~NrPhyRxTrace()
62{
63 if (m_dlDataSinrFile.is_open())
64 {
65 m_dlDataSinrFile.close();
66 }
67
68 if (m_dlCtrlSinrFile.is_open())
69 {
70 m_dlCtrlSinrFile.close();
71 }
72
73 if (m_rxPacketTraceFile.is_open())
74 {
75 m_rxPacketTraceFile.close();
76 }
77
78 if (m_rxedGnbPhyCtrlMsgsFile.is_open())
79 {
80 m_rxedGnbPhyCtrlMsgsFile.close();
81 }
82
83 if (m_txedGnbPhyCtrlMsgsFile.is_open())
84 {
85 m_txedGnbPhyCtrlMsgsFile.close();
86 }
87
88 if (m_rxedUePhyCtrlMsgsFile.is_open())
89 {
90 m_rxedUePhyCtrlMsgsFile.close();
91 }
92
93 if (m_txedUePhyCtrlMsgsFile.is_open())
94 {
95 m_txedUePhyCtrlMsgsFile.close();
96 }
97
98 if (m_rxedUePhyDlDciFile.is_open())
99 {
100 m_rxedUePhyDlDciFile.close();
101 }
102
103 if (m_dlPathlossFile.is_open())
104 {
105 m_dlPathlossFile.close();
106 }
107
108 if (m_ulPathlossFile.is_open())
109 {
110 m_ulPathlossFile.close();
111 }
112
113 if (m_dlCtrlPathlossFile.is_open())
114 {
115 m_dlCtrlPathlossFile.close();
116 }
117
118 if (m_dlDataPathlossFile.is_open())
119 {
120 m_dlDataPathlossFile.close();
121 }
122}
123
124TypeId
125NrPhyRxTrace::GetTypeId()
126{
127 static TypeId tid =
128 TypeId("ns3::NrPhyRxTrace")
129 .SetParent<Object>()
130 .AddConstructor<NrPhyRxTrace>()
131 .AddAttribute(
132 "SimTag",
133 "simulation tag that will be concatenated to output file names"
134 "in order to distinguish them, for example: RxPacketTrace-${SimTag}.out. ",
135 StringValue(""),
136 MakeStringAccessor(&NrPhyRxTrace::SetSimTag),
137 MakeStringChecker());
138 return tid;
139}
140
141void
142NrPhyRxTrace::SetSimTag(const std::string& simTag)
143{
144 m_simTag = simTag;
145}
146
147void
148NrPhyRxTrace::SetResultsFolder(const std::string& resultsFolder)
149{
150 m_resultsFolder = resultsFolder;
151}
152
153void
154NrPhyRxTrace::DlDataSinrCallback([[maybe_unused]] Ptr<NrPhyRxTrace> phyStats,
155 [[maybe_unused]] std::string path,
156 uint16_t cellId,
157 uint16_t rnti,
158 double avgSinr,
159 uint16_t bwpId)
160{
161 NS_LOG_INFO("UE" << rnti << "of " << cellId << " over bwp ID " << bwpId
162 << "->Generate RsrpSinrTrace");
163 if (!m_dlDataSinrFile.is_open())
164 {
165 std::ostringstream oss;
166 oss << m_resultsFolder << "DlDataSinr" << m_simTag.c_str() << ".txt";
167 m_dlDataSinrFileName = oss.str();
168 m_dlDataSinrFile.open(m_dlDataSinrFileName.c_str());
169
170 m_dlDataSinrFile << "Time"
171 << "\t"
172 << "CellId"
173 << "\t"
174 << "RNTI"
175 << "\t"
176 << "BWPId"
177 << "\t"
178 << "SINR(dB)" << std::endl;
179
180 if (!m_dlDataSinrFile.is_open())
181 {
182 NS_FATAL_ERROR("Could not open tracefile");
183 }
184 }
185
186 m_dlDataSinrFile << Simulator::Now().GetSeconds() << "\t" << cellId << "\t" << rnti << "\t"
187 << bwpId << "\t" << 10 * log10(avgSinr) << std::endl;
188}
189
190void
191NrPhyRxTrace::DlCtrlSinrCallback([[maybe_unused]] Ptr<NrPhyRxTrace> phyStats,
192 [[maybe_unused]] std::string path,
193 uint16_t cellId,
194 uint16_t rnti,
195 double avgSinr,
196 uint16_t bwpId)
197{
198 NS_LOG_INFO("UE" << rnti << "of " << cellId << " over bwp ID " << bwpId
199 << "->Generate DlCtrlSinrTrace");
200
201 if (!m_dlCtrlSinrFile.is_open())
202 {
203 std::ostringstream oss;
204 oss << m_resultsFolder << "DlCtrlSinr" << m_simTag.c_str() << ".txt";
205 m_dlCtrlSinrFileName = oss.str();
206 m_dlCtrlSinrFile.open(m_dlCtrlSinrFileName.c_str());
207
208 m_dlCtrlSinrFile << "Time"
209 << "\t"
210 << "CellId"
211 << "\t"
212 << "RNTI"
213 << "\t"
214 << "BWPId"
215 << "\t"
216 << "SINR(dB)" << std::endl;
217
218 if (!m_dlCtrlSinrFile.is_open())
219 {
220 NS_FATAL_ERROR("Could not open tracefile");
221 }
222 }
223
224 m_dlCtrlSinrFile << Simulator::Now().GetSeconds() << "\t" << cellId << "\t" << rnti << "\t"
225 << bwpId << "\t" << 10 * log10(avgSinr) << std::endl;
226}
227
228void
229NrPhyRxTrace::UlSinrTraceCallback(Ptr<NrPhyRxTrace> phyStats,
230 std::string path,
231 uint64_t imsi,
232 SpectrumValue& sinr,
233 SpectrumValue& power)
234{
235 NS_LOG_INFO("UE" << imsi << "->Generate UlSinrTrace");
236 uint64_t tti_count = Now().GetMicroSeconds() / 125;
237 uint32_t rb_count = 1;
238 FILE* log_file;
239 std::string fname = "UE_" + std::to_string(imsi) + "_UL_SINR_dB.txt";
240 log_file = fopen(fname.c_str(), "a");
241 Values::iterator it = sinr.ValuesBegin();
242 while (it != sinr.ValuesEnd())
243 {
244 // fprintf(log_file, "%d\t%d\t%f\t \n", tti_count/2, rb_count, 10*log10(*it));
245 fprintf(log_file,
246 "%llu\t%llu\t%d\t%f\t \n",
247 (long long unsigned)tti_count / 8 + 1,
248 (long long unsigned)tti_count % 8 + 1,
249 rb_count,
250 10 * log10(*it));
251 rb_count++;
252 it++;
253 }
254 fflush(log_file);
255 fclose(log_file);
256 // phyStats->ReportInterferenceTrace (imsi, sinr);
257 // phyStats->ReportPowerTrace (imsi, power);
258}
259
260void
262 std::string path,
263 SfnSf sfn,
264 uint16_t nodeId,
265 uint16_t rnti,
266 uint8_t bwpId,
267 Ptr<const NrControlMessage> msg)
268{
269 if (!m_rxedGnbPhyCtrlMsgsFile.is_open())
270 {
271 std::ostringstream oss;
272 oss << m_resultsFolder << "RxedGnbPhyCtrlMsgsTrace" << m_simTag.c_str() << ".txt";
273 m_rxedGnbPhyCtrlMsgsFileName = oss.str();
274 m_rxedGnbPhyCtrlMsgsFile.open(m_rxedGnbPhyCtrlMsgsFileName.c_str());
275
276 m_rxedGnbPhyCtrlMsgsFile << "Time"
277 << "\t"
278 << "Entity"
279 << "\t"
280 << "Frame"
281 << "\t"
282 << "SF"
283 << "\t"
284 << "Slot"
285 << "\t"
286 << "nodeId"
287 << "\t"
288 << "RNTI"
289 << "\t"
290 << "bwpId"
291 << "\t"
292 << "MsgType" << std::endl;
293
294 if (!m_rxedGnbPhyCtrlMsgsFile.is_open())
295 {
296 NS_FATAL_ERROR("Could not open tracefile");
297 }
298 }
299
300 m_rxedGnbPhyCtrlMsgsFile << Simulator::Now().GetNanoSeconds() / (double)1e9 << "\t"
301 << "gNB PHY Rxed"
302 << "\t" << sfn.GetFrame() << "\t"
303 << static_cast<uint32_t>(sfn.GetSubframe()) << "\t"
304 << static_cast<uint32_t>(sfn.GetSlot()) << "\t" << nodeId << "\t"
305 << rnti << "\t" << static_cast<uint32_t>(bwpId) << "\t";
306
307 if (msg->GetMessageType() == NrControlMessage::DL_CQI)
308 {
309 m_rxedGnbPhyCtrlMsgsFile << "DL_CQI";
310 }
311 else if (msg->GetMessageType() == NrControlMessage::SR)
312 {
313 m_rxedGnbPhyCtrlMsgsFile << "SR";
314 }
315 else if (msg->GetMessageType() == NrControlMessage::BSR)
316 {
317 m_rxedGnbPhyCtrlMsgsFile << "BSR";
318 }
319 else if (msg->GetMessageType() == NrControlMessage::RACH_PREAMBLE)
320 {
321 m_rxedGnbPhyCtrlMsgsFile << "RACH_PREAMBLE";
322 }
323 else if (msg->GetMessageType() == NrControlMessage::DL_HARQ)
324 {
325 m_rxedGnbPhyCtrlMsgsFile << "DL_HARQ";
326 }
327 else if (msg->GetMessageType() == NrControlMessage::SRS)
328 {
329 m_rxedGnbPhyCtrlMsgsFile << "SRS";
330 }
331 else
332 {
333 m_rxedGnbPhyCtrlMsgsFile << "Other";
334 }
335 m_rxedGnbPhyCtrlMsgsFile << std::endl;
336}
337
338void
340 std::string path,
341 SfnSf sfn,
342 uint16_t nodeId,
343 uint16_t rnti,
344 uint8_t bwpId,
345 Ptr<const NrControlMessage> msg)
346{
347 if (!m_txedGnbPhyCtrlMsgsFile.is_open())
348 {
349 std::ostringstream oss;
350 oss << m_resultsFolder << "TxedGnbPhyCtrlMsgsTrace" << m_simTag.c_str() << ".txt";
351 m_txedGnbPhyCtrlMsgsFileName = oss.str();
352 m_txedGnbPhyCtrlMsgsFile.open(m_txedGnbPhyCtrlMsgsFileName.c_str());
353
354 m_txedGnbPhyCtrlMsgsFile << "Time"
355 << "\t"
356 << "Entity"
357 << "\t"
358 << "Frame"
359 << "\t"
360 << "SF"
361 << "\t"
362 << "Slot"
363 << "\t"
364 << "nodeId"
365 << "\t"
366 << "RNTI"
367 << "\t"
368 << "bwpId"
369 << "\t"
370 << "MsgType" << std::endl;
371
372 if (!m_txedGnbPhyCtrlMsgsFile.is_open())
373 {
374 NS_FATAL_ERROR("Could not open tracefile");
375 }
376 }
377
378 m_txedGnbPhyCtrlMsgsFile << Simulator::Now().GetNanoSeconds() / (double)1e9 << "\t"
379 << "gNB PHY Txed"
380 << "\t" << sfn.GetFrame() << "\t"
381 << static_cast<uint32_t>(sfn.GetSubframe()) << "\t"
382 << static_cast<uint32_t>(sfn.GetSlot()) << "\t" << nodeId << "\t"
383 << rnti << "\t" << static_cast<uint32_t>(bwpId) << "\t";
384
385 if (msg->GetMessageType() == NrControlMessage::MIB)
386 {
387 m_txedGnbPhyCtrlMsgsFile << "MIB";
388 }
389 else if (msg->GetMessageType() == NrControlMessage::SIB1)
390 {
391 m_txedGnbPhyCtrlMsgsFile << "SIB1";
392 }
393 else if (msg->GetMessageType() == NrControlMessage::RAR)
394 {
395 m_txedGnbPhyCtrlMsgsFile << "RAR";
396 }
397 else if (msg->GetMessageType() == NrControlMessage::DL_DCI)
398 {
399 m_txedGnbPhyCtrlMsgsFile << "DL_DCI";
400 }
401 else if (msg->GetMessageType() == NrControlMessage::UL_DCI)
402 {
403 m_txedGnbPhyCtrlMsgsFile << "UL_UCI";
404 }
405 else
406 {
407 m_txedGnbPhyCtrlMsgsFile << "Other";
408 }
409 m_txedGnbPhyCtrlMsgsFile << std::endl;
410}
411
412void
414 std::string path,
415 SfnSf sfn,
416 uint16_t nodeId,
417 uint16_t rnti,
418 uint8_t bwpId,
419 Ptr<const NrControlMessage> msg)
420{
421 if (!m_rxedUePhyCtrlMsgsFile.is_open())
422 {
423 std::ostringstream oss;
424 oss << m_resultsFolder << "RxedUePhyCtrlMsgsTrace" << m_simTag.c_str() << ".txt";
425 m_rxedUePhyCtrlMsgsFileName = oss.str();
426 m_rxedUePhyCtrlMsgsFile.open(m_rxedUePhyCtrlMsgsFileName.c_str());
427
428 m_rxedUePhyCtrlMsgsFile << "Time"
429 << "\t"
430 << "Entity"
431 << "\t"
432 << "Frame"
433 << "\t"
434 << "SF"
435 << "\t"
436 << "Slot"
437 << "\t"
438 << "nodeId"
439 << "\t"
440 << "RNTI"
441 << "\t"
442 << "bwpId"
443 << "\t"
444 << "MsgType" << std::endl;
445
446 if (!m_rxedUePhyCtrlMsgsFile.is_open())
447 {
448 NS_FATAL_ERROR("Could not open tracefile");
449 }
450 }
451
452 m_rxedUePhyCtrlMsgsFile << Simulator::Now().GetNanoSeconds() / (double)1e9 << "\t"
453 << "UE PHY Rxed"
454 << "\t" << sfn.GetFrame() << "\t"
455 << static_cast<uint32_t>(sfn.GetSubframe()) << "\t"
456 << static_cast<uint32_t>(sfn.GetSlot()) << "\t" << nodeId << "\t"
457 << rnti << "\t" << static_cast<uint32_t>(bwpId) << "\t";
458
459 if (msg->GetMessageType() == NrControlMessage::UL_DCI)
460 {
461 m_rxedUePhyCtrlMsgsFile << "UL_DCI";
462 }
463 else if (msg->GetMessageType() == NrControlMessage::DL_DCI)
464 {
465 m_rxedUePhyCtrlMsgsFile << "DL_DCI";
466 }
467 else if (msg->GetMessageType() == NrControlMessage::MIB)
468 {
469 m_rxedUePhyCtrlMsgsFile << "MIB";
470 }
471 else if (msg->GetMessageType() == NrControlMessage::SIB1)
472 {
473 m_rxedUePhyCtrlMsgsFile << "SIB1";
474 }
475 else if (msg->GetMessageType() == NrControlMessage::RAR)
476 {
477 m_rxedUePhyCtrlMsgsFile << "RAR";
478 }
479 else
480 {
481 m_rxedUePhyCtrlMsgsFile << "Other";
482 }
483 m_rxedUePhyCtrlMsgsFile << std::endl;
484}
485
486void
488 std::string path,
489 SfnSf sfn,
490 uint16_t nodeId,
491 uint16_t rnti,
492 uint8_t bwpId,
493 Ptr<const NrControlMessage> msg)
494{
495 if (!m_txedUePhyCtrlMsgsFile.is_open())
496 {
497 std::ostringstream oss;
498 oss << m_resultsFolder << "TxedUePhyCtrlMsgsTrace" << m_simTag.c_str() << ".txt";
499 m_txedUePhyCtrlMsgsFileName = oss.str();
500 m_txedUePhyCtrlMsgsFile.open(m_txedUePhyCtrlMsgsFileName.c_str());
501
502 m_txedUePhyCtrlMsgsFile << "Time"
503 << "\t"
504 << "Entity"
505 << "\t"
506 << "Frame"
507 << "\t"
508 << "SF"
509 << "\t"
510 << "Slot"
511 << "\t"
512 << "nodeId"
513 << "\t"
514 << "RNTI"
515 << "\t"
516 << "bwpId"
517 << "\t"
518 << "MsgType" << std::endl;
519
520 if (!m_txedUePhyCtrlMsgsFile.is_open())
521 {
522 NS_FATAL_ERROR("Could not open tracefile");
523 }
524 }
525
526 m_txedUePhyCtrlMsgsFile << Simulator::Now().GetNanoSeconds() / (double)1e9 << "\t"
527 << "UE PHY Txed"
528 << "\t" << sfn.GetFrame() << "\t"
529 << static_cast<uint32_t>(sfn.GetSubframe()) << "\t"
530 << static_cast<uint32_t>(sfn.GetSlot()) << "\t" << nodeId << "\t"
531 << rnti << "\t" << static_cast<uint32_t>(bwpId) << "\t";
532
533 if (msg->GetMessageType() == NrControlMessage::RACH_PREAMBLE)
534 {
535 m_txedUePhyCtrlMsgsFile << "RACH_PREAMBLE";
536 }
537 else if (msg->GetMessageType() == NrControlMessage::SR)
538 {
539 m_txedUePhyCtrlMsgsFile << "SR";
540 }
541 else if (msg->GetMessageType() == NrControlMessage::BSR)
542 {
543 m_txedUePhyCtrlMsgsFile << "BSR";
544 }
545 else if (msg->GetMessageType() == NrControlMessage::DL_CQI)
546 {
547 m_txedUePhyCtrlMsgsFile << "DL_CQI";
548 }
549 else if (msg->GetMessageType() == NrControlMessage::DL_HARQ)
550 {
551 m_txedUePhyCtrlMsgsFile << "DL_HARQ";
552 }
553 else if (msg->GetMessageType() == NrControlMessage::SRS)
554 {
555 m_txedUePhyCtrlMsgsFile << "SRS";
556 }
557 else
558 {
559 m_txedUePhyCtrlMsgsFile << "Other";
560 }
561 m_txedUePhyCtrlMsgsFile << std::endl;
562}
563
564void
565NrPhyRxTrace::RxedUePhyDlDciCallback(Ptr<NrPhyRxTrace> phyStats,
566 std::string path,
567 SfnSf sfn,
568 uint16_t nodeId,
569 uint16_t rnti,
570 uint8_t bwpId,
571 uint8_t harqId,
572 uint32_t k1Delay)
573{
574 if (!m_rxedUePhyDlDciFile.is_open())
575 {
576 std::ostringstream oss;
577 oss << m_resultsFolder << "RxedUePhyDlDciTrace" << m_simTag.c_str() << ".txt";
578 m_rxedUePhyDlDciFileName = oss.str();
579 m_rxedUePhyDlDciFile.open(m_rxedUePhyDlDciFileName.c_str());
580
581 m_rxedUePhyDlDciFile << "Time"
582 << "\t"
583 << "Entity"
584 << "\t"
585 << "Frame"
586 << "\t"
587 << "SF"
588 << "\t"
589 << "Slot"
590 << "\t"
591 << "nodeId"
592 << "\t"
593 << "RNTI"
594 << "\t"
595 << "bwpId"
596 << "\t"
597 << "Harq ID"
598 << "\t"
599 << "K1 Delay" << std::endl;
600
601 if (!m_rxedUePhyDlDciFile.is_open())
602 {
603 NS_FATAL_ERROR("Could not open tracefile");
604 }
605 }
606
607 m_rxedUePhyDlDciFile << Simulator::Now().GetNanoSeconds() / (double)1e9 << "\t"
608 << "DL DCI Rxed"
609 << "\t" << sfn.GetFrame() << "\t"
610 << static_cast<uint32_t>(sfn.GetSubframe()) << "\t"
611 << static_cast<uint32_t>(sfn.GetSlot()) << "\t" << nodeId << "\t" << rnti
612 << "\t" << static_cast<uint32_t>(bwpId) << "\t"
613 << static_cast<uint32_t>(harqId) << "\t" << k1Delay << std::endl;
614}
615
616void
618 std::string path,
619 SfnSf sfn,
620 uint16_t nodeId,
621 uint16_t rnti,
622 uint8_t bwpId,
623 uint8_t harqId,
624 uint32_t k1Delay)
625{
626 if (!m_rxedUePhyDlDciFile.is_open())
627 {
628 std::ostringstream oss;
629 oss << m_resultsFolder << "RxedUePhyDlDciTrace" << m_simTag.c_str() << ".txt";
630 m_rxedUePhyDlDciFileName = oss.str();
631 m_rxedUePhyDlDciFile.open(m_rxedUePhyDlDciFileName.c_str());
632
633 m_rxedUePhyDlDciFile << "Time"
634 << "\t"
635 << "Entity"
636 << "\t"
637 << "Frame"
638 << "\t"
639 << "SF"
640 << "\t"
641 << "Slot"
642 << "\t"
643 << "nodeId"
644 << "\t"
645 << "RNTI"
646 << "\t"
647 << "bwpId"
648 << "\t"
649 << "Harq ID"
650 << "\t"
651 << "K1 Delay" << std::endl;
652
653 if (!m_rxedUePhyDlDciFile.is_open())
654 {
655 NS_FATAL_ERROR("Could not open tracefile");
656 }
657 }
658
659 m_rxedUePhyDlDciFile << Simulator::Now().GetNanoSeconds() / (double)1e9 << "\t"
660 << "HARQ FD Txed"
661 << "\t" << sfn.GetFrame() << "\t"
662 << static_cast<uint32_t>(sfn.GetSubframe()) << "\t"
663 << static_cast<uint32_t>(sfn.GetSlot()) << "\t" << nodeId << "\t" << rnti
664 << "\t" << static_cast<uint32_t>(bwpId) << "\t"
665 << static_cast<uint32_t>(harqId) << "\t" << k1Delay << std::endl;
666}
667
668void
669NrPhyRxTrace::ReportInterferenceTrace(uint64_t imsi, SpectrumValue& sinr)
670{
671 uint64_t tti_count = Now().GetMicroSeconds() / 125;
672 uint32_t rb_count = 1;
673 FILE* log_file;
674 std::string fname = "UE_" + std::to_string(imsi) + "_SINR_dB.txt";
675 log_file = fopen(fname.c_str(), "a");
676 Values::iterator it = sinr.ValuesBegin();
677 while (it != sinr.ValuesEnd())
678 {
679 // fprintf(log_file, "%d\t%d\t%f\t \n", tti_count/2, rb_count, 10*log10(*it));
680 fprintf(log_file,
681 "%llu\t%llu\t%d\t%f\t \n",
682 (long long unsigned)tti_count / 8 + 1,
683 (long long unsigned)tti_count % 8 + 1,
684 rb_count,
685 10 * log10(*it));
686 rb_count++;
687 it++;
688 }
689 fflush(log_file);
690 fclose(log_file);
691}
692
693void
694NrPhyRxTrace::ReportPowerTrace(uint64_t imsi, SpectrumValue& power)
695{
696 uint32_t tti_count = Now().GetMicroSeconds() / 125;
697 uint32_t rb_count = 1;
698 FILE* log_file;
699 std::string fname = "UE_" + std::to_string(imsi) + "_ReceivedPower_dB.txt";
700 log_file = fopen(fname.c_str(), "a");
701 Values::iterator it = power.ValuesBegin();
702 while (it != power.ValuesEnd())
703 {
704 fprintf(log_file,
705 "%llu\t%llu\t%d\t%f\t \n",
706 (long long unsigned)tti_count / 8 + 1,
707 (long long unsigned)tti_count % 8 + 1,
708 rb_count,
709 10 * log10(*it));
710 rb_count++;
711 it++;
712 }
713 fflush(log_file);
714 fclose(log_file);
715}
716
717void
718NrPhyRxTrace::ReportPacketCountUeCallback(Ptr<NrPhyRxTrace> phyStats,
719 std::string path,
720 UePhyPacketCountParameter param)
721{
722 phyStats->ReportPacketCountUe(param);
723}
724
725void
726NrPhyRxTrace::ReportPacketCountGnbCallback(Ptr<NrPhyRxTrace> phyStats,
727 std::string path,
728 GnbPhyPacketCountParameter param)
729{
730 phyStats->ReportPacketCountGnb(param);
731}
732
733void
734NrPhyRxTrace::ReportDownLinkTBSize(Ptr<NrPhyRxTrace> phyStats,
735 std::string path,
736 uint64_t imsi,
737 uint64_t tbSize)
738{
739 phyStats->ReportDLTbSize(imsi, tbSize);
740}
741
742void
743NrPhyRxTrace::ReportPacketCountUe(UePhyPacketCountParameter param)
744{
745 FILE* log_file;
746 std::string fname = "UE_" + std::to_string(param.m_imsi) + "_Packet_Trace.txt";
747 log_file = fopen(fname.c_str(), "a");
748 if (param.m_isTx)
749 {
750 fprintf(log_file, "%d\t%d\t%d\n", param.m_subframeno, param.m_noBytes, 0);
751 }
752 else
753 {
754 fprintf(log_file, "%d\t%d\t%d\n", param.m_subframeno, 0, param.m_noBytes);
755 }
756
757 fflush(log_file);
758 fclose(log_file);
759}
760
761void
762NrPhyRxTrace::ReportPacketCountGnb(GnbPhyPacketCountParameter param)
763{
764 FILE* log_file;
765 std::string fname = "BS_" + std::to_string(param.m_cellId) + "_Packet_Trace.txt";
766 log_file = fopen(fname.c_str(), "a");
767 if (param.m_isTx)
768 {
769 fprintf(log_file, "%d\t%d\t%d\n", param.m_subframeno, param.m_noBytes, 0);
770 }
771 else
772 {
773 fprintf(log_file, "%d\t%d\t%d\n", param.m_subframeno, 0, param.m_noBytes);
774 }
775
776 fflush(log_file);
777 fclose(log_file);
778}
779
780void
781NrPhyRxTrace::ReportDLTbSize(uint64_t imsi, uint64_t tbSize)
782{
783 FILE* log_file;
784 std::string fname = "UE_" + std::to_string(imsi) + "_Tb_Size.txt";
785 log_file = fopen(fname.c_str(), "a");
786
787 fprintf(log_file,
788 "%llu \t %llu\n",
789 (long long unsigned)Now().GetMicroSeconds(),
790 (long long unsigned)tbSize);
791 fprintf(log_file,
792 "%lld \t %llu \n",
793 (long long int)Now().GetMicroSeconds(),
794 (long long unsigned)tbSize);
795 fflush(log_file);
796 fclose(log_file);
797}
798
799void
800NrPhyRxTrace::RxPacketTraceUeCallback(Ptr<NrPhyRxTrace> phyStats,
801 std::string path,
802 RxPacketTraceParams params)
803{
804 if (!m_rxPacketTraceFile.is_open())
805 {
806 std::ostringstream oss;
807 oss << m_resultsFolder << "RxPacketTrace" << m_simTag.c_str() << ".txt";
808 m_rxPacketTraceFilename = oss.str();
809 m_rxPacketTraceFile.open(m_rxPacketTraceFilename.c_str());
810
811 m_rxPacketTraceFile << "Time"
812 << "\t"
813 << "direction"
814 << "\t"
815 << "frame"
816 << "\t"
817 << "subF"
818 << "\t"
819 << "slot"
820 << "\t"
821 << "1stSym"
822 << "\t"
823 << "nSymbol"
824 << "\t"
825 << "cellId"
826 << "\t"
827 << "bwpId"
828 << "\t"
829 << "rnti"
830 << "\t"
831 << "tbSize"
832 << "\t"
833 << "mcs"
834 << "\t"
835 << "rank"
836 << "\t"
837 << "rv"
838 << "\t"
839 << "SINR(dB)"
840 << "\t"
841 << "CQI"
842 << "\t"
843 << "corrupt"
844 << "\t"
845 << "TBler" << std::endl;
846
847 if (!m_rxPacketTraceFile.is_open())
848 {
849 NS_FATAL_ERROR("Could not open tracefile");
850 }
851 }
852
853 m_rxPacketTraceFile << Simulator::Now().GetNanoSeconds() / (double)1e9 << "\t"
854 << "DL"
855 << "\t" << params.m_frameNum << "\t" << (unsigned)params.m_subframeNum
856 << "\t" << (unsigned)params.m_slotNum << "\t" << (unsigned)params.m_symStart
857 << "\t" << (unsigned)params.m_numSym << "\t" << params.m_cellId << "\t"
858 << (unsigned)params.m_bwpId << "\t" << params.m_rnti << "\t"
859 << params.m_tbSize << "\t" << (unsigned)params.m_mcs << "\t"
860 << (unsigned)params.m_rank << "\t" << (unsigned)params.m_rv << "\t"
861 << 10 * log10(params.m_sinr) << "\t" << std::to_string(params.m_cqi) << "\t"
862 << params.m_corrupt << "\t" << params.m_tbler << std::endl;
863
864 if (params.m_corrupt)
865 {
866 NS_LOG_DEBUG("DL TB error\t"
867 << params.m_frameNum << "\t" << (unsigned)params.m_subframeNum << "\t"
868 << (unsigned)params.m_slotNum << "\t" << (unsigned)params.m_symStart << "\t"
869 << (unsigned)params.m_numSym << "\t" << params.m_rnti << "\t"
870 << params.m_tbSize << "\t" << (unsigned)params.m_mcs << "\t"
871 << (unsigned)params.m_rank << "\t" << (unsigned)params.m_rv << "\t"
872 << params.m_sinr << "\t" << params.m_tbler << "\t"
873 << std::to_string(params.m_cqi) << "\t" << params.m_corrupt << "\t"
874 << (unsigned)params.m_bwpId);
875 }
876}
877
878void
879NrPhyRxTrace::RxPacketTraceGnbCallback(Ptr<NrPhyRxTrace> phyStats,
880 std::string path,
881 RxPacketTraceParams params)
882{
883 if (!m_rxPacketTraceFile.is_open())
884 {
885 std::ostringstream oss;
886 oss << m_resultsFolder << "RxPacketTrace" << m_simTag.c_str() << ".txt";
887 m_rxPacketTraceFilename = oss.str();
888 m_rxPacketTraceFile.open(m_rxPacketTraceFilename.c_str());
889
890 m_rxPacketTraceFile << "Time"
891 << "\t"
892 << "direction"
893 << "\t"
894 << "frame"
895 << "\t"
896 << "subF"
897 << "\t"
898 << "slot"
899 << "\t"
900 << "1stSym"
901 << "\t"
902 << "nSymbol"
903 << "\t"
904 << "cellId"
905 << "\t"
906 << "bwpId"
907 << "\t"
908 << "rnti"
909 << "\t"
910 << "tbSize"
911 << "\t"
912 << "mcs"
913 << "\t"
914 << "rank"
915 << "\t"
916 << "rv"
917 << "\t"
918 << "SINR(dB)"
919 << "\t"
920 << "CQI"
921 << "\t"
922 << "corrupt"
923 << "\t"
924 << "TBler" << std::endl;
925
926 if (!m_rxPacketTraceFile.is_open())
927 {
928 NS_FATAL_ERROR("Could not open tracefile");
929 }
930 }
931 m_rxPacketTraceFile << Simulator::Now().GetNanoSeconds() / (double)1e9 << "\t"
932 << "UL"
933 << "\t" << params.m_frameNum << "\t" << (unsigned)params.m_subframeNum
934 << "\t" << (unsigned)params.m_slotNum << "\t" << (unsigned)params.m_symStart
935 << "\t" << (unsigned)params.m_numSym << "\t" << params.m_cellId << "\t"
936 << (unsigned)params.m_bwpId << "\t" << params.m_rnti << "\t"
937 << params.m_tbSize << "\t" << (unsigned)params.m_mcs << "\t"
938 << (unsigned)params.m_rank << "\t" << (unsigned)params.m_rv << "\t"
939 << 10 * log10(params.m_sinr) << "\t" << std::to_string(params.m_cqi) << "\t"
940 << params.m_corrupt << "\t" << params.m_tbler << std::endl;
941
942 if (params.m_corrupt)
943 {
944 NS_LOG_DEBUG("UL TB error\t"
945 << params.m_frameNum << "\t" << (unsigned)params.m_subframeNum << "\t"
946 << (unsigned)params.m_slotNum << "\t" << (unsigned)params.m_symStart << "\t"
947 << (unsigned)params.m_numSym << "\t" << params.m_rnti << "\t"
948 << params.m_tbSize << "\t" << (unsigned)params.m_mcs << "\t"
949 << (unsigned)params.m_rank << "\t" << (unsigned)params.m_rv << "\t"
950 << params.m_sinr << "\t" << params.m_tbler << "\t"
951 << std::to_string(params.m_cqi) << "\t" << params.m_corrupt << "\t"
952 << params.m_sinrMin << "\t" << params.m_bwpId);
953 }
954}
955
956void
957NrPhyRxTrace::PathlossTraceCallback(Ptr<NrPhyRxTrace> phyStats,
958 std::string path,
959 Ptr<const SpectrumPhy> txPhy,
960 Ptr<const SpectrumPhy> rxPhy,
961 double lossDb)
962{
963 Ptr<NrSpectrumPhy> txNrSpectrumPhy = txPhy->GetObject<NrSpectrumPhy>();
964 Ptr<NrSpectrumPhy> rxNrSpectrumPhy = rxPhy->GetObject<NrSpectrumPhy>();
965 if (DynamicCast<NrGnbNetDevice>(txNrSpectrumPhy->GetDevice()) != nullptr)
966 {
967 // All the gNBs are on the same channel (especially in TDD), therefore,
968 // to log real DL reception we need to make sure that the RX spectrum
969 // belongs to an UE.
970 if (DynamicCast<NrUeNetDevice>(rxNrSpectrumPhy->GetDevice()) != nullptr)
971 {
972 uint16_t txCellId =
973 txNrSpectrumPhy->GetDevice()->GetObject<NrGnbNetDevice>()->GetCellId();
974 uint16_t rxCellId =
975 rxNrSpectrumPhy->GetDevice()->GetObject<NrUeNetDevice>()->GetCellId();
976 uint16_t txBwpId = txNrSpectrumPhy->GetBwpId();
977 uint16_t rxBwpId = rxNrSpectrumPhy->GetBwpId();
978 if (txCellId == rxCellId && txBwpId == rxBwpId)
979 {
980 // We multiply loss values with -1 to get the notion of loss
981 // instead of a gain.
982 phyStats->WriteDlPathlossTrace(txNrSpectrumPhy, rxNrSpectrumPhy, lossDb * -1);
983 }
984 }
985 }
986 else
987 {
988 // All the UEs are on the same channel (especially in TDD), therefore,
989 // to log real UL reception we need to make sure that the RX spectrum
990 // belongs to a gNB.
991 if (DynamicCast<NrGnbNetDevice>(rxNrSpectrumPhy->GetDevice()) != nullptr)
992 {
993 uint16_t txCellId =
994 txNrSpectrumPhy->GetDevice()->GetObject<NrUeNetDevice>()->GetCellId();
995 uint16_t rxCellId =
996 rxNrSpectrumPhy->GetDevice()->GetObject<NrGnbNetDevice>()->GetCellId();
997 uint16_t txBwpId = txNrSpectrumPhy->GetBwpId();
998 uint16_t rxBwpId = rxNrSpectrumPhy->GetBwpId();
999 if (txCellId == rxCellId && txBwpId == rxBwpId)
1000 {
1001 // We multiply loss values with -1 to get the notion of loss
1002 // instead of a gain.
1003 phyStats->WriteUlPathlossTrace(txNrSpectrumPhy, rxNrSpectrumPhy, lossDb * -1);
1004 }
1005 }
1006 }
1007}
1008
1009void
1010NrPhyRxTrace::WriteDlPathlossTrace(Ptr<NrSpectrumPhy> txNrSpectrumPhy,
1011 Ptr<NrSpectrumPhy> rxNrSpectrumPhy,
1012 double lossDb)
1013{
1014 if (!m_dlPathlossFile.is_open())
1015 {
1016 std::ostringstream oss;
1017 oss << m_resultsFolder << "DlPathlossTrace" << m_simTag.c_str() << ".txt";
1018 m_dlPathlossFileName = oss.str();
1019 m_dlPathlossFile.open(m_dlPathlossFileName.c_str());
1020
1021 m_dlPathlossFile << "Time(sec)"
1022 << "\t"
1023 << "CellId"
1024 << "\t"
1025 << "BwpId"
1026 << "\t"
1027 << "IMSI"
1028 << "\t"
1029 << "pathLoss(dB)" << std::endl;
1030
1031 if (!m_dlPathlossFile.is_open())
1032 {
1033 NS_FATAL_ERROR("Could not open DL pathloss tracefile");
1034 }
1035 }
1036
1037 m_dlPathlossFile << Simulator::Now().GetSeconds() << "\t"
1038 << txNrSpectrumPhy->GetDevice()->GetObject<NrGnbNetDevice>()->GetCellId()
1039 << "\t" << txNrSpectrumPhy->GetBwpId() << "\t"
1040 << rxNrSpectrumPhy->GetDevice()->GetObject<NrUeNetDevice>()->GetImsi() << "\t"
1041 << lossDb << std::endl;
1042}
1043
1044void
1045NrPhyRxTrace::WriteUlPathlossTrace(Ptr<NrSpectrumPhy> txNrSpectrumPhy,
1046 Ptr<NrSpectrumPhy> rxNrSpectrumPhy,
1047 double lossDb)
1048{
1049 if (!m_ulPathlossFile.is_open())
1050 {
1051 std::ostringstream oss;
1052 oss << m_resultsFolder << "UlPathlossTrace" << m_simTag.c_str() << ".txt";
1053 m_ulPathlossFileName = oss.str();
1054 m_ulPathlossFile.open(m_ulPathlossFileName.c_str());
1055
1056 m_ulPathlossFile << "Time(sec)"
1057 << "\t"
1058 << "CellId"
1059 << "\t"
1060 << "BwpId"
1061 << "\t"
1062 << "IMSI"
1063 << "\t"
1064 << "pathLoss(dB)" << std::endl;
1065
1066 if (!m_ulPathlossFile.is_open())
1067 {
1068 NS_FATAL_ERROR("Could not open UL pathloss tracefile");
1069 }
1070 }
1071
1072 m_ulPathlossFile << Simulator::Now().GetSeconds() << "\t"
1073 << txNrSpectrumPhy->GetDevice()->GetObject<NrUeNetDevice>()->GetCellId()
1074 << "\t" << txNrSpectrumPhy->GetBwpId() << "\t"
1075 << txNrSpectrumPhy->GetDevice()->GetObject<NrUeNetDevice>()->GetImsi() << "\t"
1076 << lossDb << std::endl;
1077}
1078
1079void
1080NrPhyRxTrace::ReportDlCtrlPathloss([[maybe_unused]] Ptr<NrPhyRxTrace> phyStats,
1081 [[maybe_unused]] std::string path,
1082 uint16_t cellId,
1083 uint8_t bwpId,
1084 uint32_t ueNodeId,
1085 double lossDb)
1086{
1087 NS_LOG_INFO("UE node id:" << ueNodeId << "of " << cellId << " over bwp ID " << bwpId
1088 << "->Generate DL CTRL pathloss record: " << lossDb);
1089
1090 if (!m_dlCtrlPathlossFile.is_open())
1091 {
1092 std::ostringstream oss;
1093 oss << m_resultsFolder << "DlCtrlPathlossTrace" << m_simTag.c_str() << ".txt";
1094 m_dlCtrlPathlossFileName = oss.str();
1095 m_dlCtrlPathlossFile.open(m_dlCtrlPathlossFileName.c_str());
1096
1097 m_dlCtrlPathlossFile << "Time(sec)"
1098 << "\t"
1099 << "CellId"
1100 << "\t"
1101 << "BwpId"
1102 << "\t"
1103 << "ueNodeId"
1104 << "\t"
1105 << "pathLoss(dB)" << std::endl;
1106
1107 if (!m_dlCtrlPathlossFile.is_open())
1108 {
1109 NS_FATAL_ERROR("Could not open DL CTRL pathloss tracefile");
1110 }
1111 }
1112
1113 m_dlCtrlPathlossFile << Simulator::Now().GetSeconds() << "\t" << cellId << "\t" << +bwpId
1114 << "\t" << ueNodeId << "\t" << lossDb << std::endl;
1115}
1116
1117void
1118NrPhyRxTrace::ReportDlDataPathloss([[maybe_unused]] Ptr<NrPhyRxTrace> phyStats,
1119 [[maybe_unused]] std::string path,
1120 uint16_t cellId,
1121 uint8_t bwpId,
1122 uint32_t ueNodeId,
1123 double lossDb,
1124 uint8_t cqi)
1125{
1126 NS_LOG_INFO("UE node id:" << ueNodeId << "of " << cellId << " over bwp ID " << bwpId
1127 << "->Generate DL DATA pathloss record: " << lossDb);
1128
1129 if (!m_dlDataPathlossFile.is_open())
1130 {
1131 std::ostringstream oss;
1132 oss << m_resultsFolder << "DlDataPathlossTrace" << m_simTag.c_str() << ".txt";
1133 m_dlDataPathlossFileName = oss.str();
1134 m_dlDataPathlossFile.open(m_dlDataPathlossFileName.c_str());
1135
1136 m_dlDataPathlossFile << "Time(sec)"
1137 << "\t"
1138 << "CellId"
1139 << "\t"
1140 << "BwpId"
1141 << "\t"
1142 << "ueNodeId"
1143 << "\t"
1144 << "pathLoss(dB)"
1145 << "\t"
1146 << "CQI" << std::endl;
1147
1148 if (!m_dlDataPathlossFile.is_open())
1149 {
1150 NS_FATAL_ERROR("Could not open DL DATA pathloss tracefile");
1151 }
1152 }
1153
1154 m_dlDataPathlossFile << Simulator::Now().GetSeconds() << "\t" << cellId << "\t" << +bwpId
1155 << "\t" << ueNodeId << "\t" << lossDb << "\t" << +cqi << std::endl;
1156}
1157
1158} /* namespace ns3 */
@ UL_DCI
The resources allocation map from the BS to the attached UEs (UL)
@ DL_HARQ
DL HARQ feedback.
@ RACH_PREAMBLE
Random Access Preamble.
@ MIB
Master Information Block.
@ SR
Scheduling Request: asking for space.
@ BSR
Buffer Status Report.
@ RAR
Random Access Response.
@ SIB1
System Information Block Type 1.
@ DL_DCI
The resources allocation map from the BS to the attached UEs (DL)
The NrGnbNetDevice class.
static void RxedGnbPhyCtrlMsgsCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, Ptr< const NrControlMessage > msg)
static void ReportDlDataPathloss(Ptr< NrPhyRxTrace > phyStats, std::string path, uint16_t cellId, uint8_t bwpId, uint32_t ueNodeId, double lossDb, uint8_t cqi)
Write DL DATA pathloss values in a file.
static void PathlossTraceCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, Ptr< const SpectrumPhy > txPhy, Ptr< const SpectrumPhy > rxPhy, double lossDb)
Trace sink for spectrum channel pathloss trace.
static void TxedGnbPhyCtrlMsgsCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, Ptr< const NrControlMessage > msg)
void SetResultsFolder(const std::string &resultsFolder)
Set results folder.
static void TxedUePhyCtrlMsgsCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, Ptr< const NrControlMessage > msg)
static void TxedUePhyHarqFeedbackCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, uint8_t harqId, uint32_t k1Delay)
static void RxedUePhyCtrlMsgsCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, Ptr< const NrControlMessage > msg)
static void DlCtrlSinrCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, uint16_t cellId, uint16_t rnti, double avgSinr, uint16_t bwpId)
Trace sink for DL Average SINR of CTRL (in dB).
static void RxedUePhyDlDciCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, uint8_t harqId, uint32_t k1Delay)
void SetSimTag(const std::string &simTag)
Set simTag that will be concatenated to output file names.
static void DlDataSinrCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, uint16_t cellId, uint16_t rnti, double avgSinr, uint16_t bwpId)
Trace sink for DL Average SINR of DATA (in dB).
static void ReportDlCtrlPathloss(Ptr< NrPhyRxTrace > phyStats, std::string path, uint16_t cellId, uint8_t bwpId, uint32_t ueNodeId, double lossDb)
Write DL CTRL pathloss values in a file.
Interface between the physical layer and the channel.
The User Equipment NetDevice.
The SfnSf class.
Definition sfnsf.h:32
uint8_t GetSubframe() const
GetSubframe.
Definition sfnsf.cc:158
uint8_t GetSlot() const
GetSlot.
Definition sfnsf.cc:164
uint32_t GetFrame() const
GetFrame.
Definition sfnsf.cc:152