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