5G-MAG Reference Tools - MBMS Modem
Rrc.cpp
Go to the documentation of this file.
1 // 5G-MAG Reference Tools
2 // MBMS Modem Process
3 //
4 // Copyright (C) 2021 Klaus Kühnhammer (Österreichische Rundfunksender GmbH & Co KG)
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU Affero General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
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 Affero General Public License for more details.
15 //
16 // You should have received a copy of the GNU Affero General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 //
19 
20 #include "Rrc.h"
21 #include "spdlog/spdlog.h"
22 #include "srsran/asn1/rrc_utils.h"
23 
24 using asn1::rrc::mcch_msg_type_c;
25 using asn1::rrc::bcch_dl_sch_msg_mbms_s;
26 using asn1::rrc::bcch_dl_sch_msg_s;
27 using asn1::rrc::bcch_dl_sch_msg_type_mbms_r14_c;
28 using asn1::rrc::sib_type1_mbms_r14_s;
29 using asn1::rrc::sib_type_mbms_r14_e;
30 using asn1::rrc::sched_info_mbms_r14_s;
31 using asn1::rrc::sys_info_r8_ies_s;
32 using asn1::rrc::sib_info_item_c;
33 
34 void Rrc::write_pdu_mch(uint32_t /*lcid*/, srsran::unique_byte_buffer_t pdu) {
35  spdlog::trace("rrc: write_pdu_mch");
36  if (pdu->N_bytes <= 0 || pdu->N_bytes >= SRSRAN_MAX_BUFFER_SIZE_BITS) {
37  return;
38  }
39  asn1::cbit_ref bref(pdu->msg, pdu->N_bytes);
40  asn1::rrc::mcch_msg_s msg;
41  if (msg.unpack(bref) != asn1::SRSASN_SUCCESS ||
42  msg.msg.type().value != mcch_msg_type_c::types_opts::c1) {
43  spdlog::error("Failed to unpack MCCH message");
44  return;
45  }
46  asn1::json_writer json_writer;
47  msg.to_json(json_writer);
48  spdlog::debug("BCCH-DLSCH message content:\n{}", json_writer.to_string());
49 
50  srsran::mcch_msg_t mcch = srsran::make_mcch_msg(msg);
51 
52  // add bearers for all LCIDs
53  for (uint32_t i = 0; i < mcch.nof_pmch_info; i++) {
54  for (uint32_t j = 0; j < mcch.pmch_info_list[i].nof_mbms_session_info; j++) {
55  uint32_t lcid = mcch.pmch_info_list[i].mbms_session_info_list[j].lc_ch_id;
56  if (!_rlc.has_bearer_mrb(i, lcid)) {
57  _rlc.add_bearer_mrb(i, lcid);
58  }
59  }
60  }
61 
62  _phy.set_mbsfn_config(mcch);
63  _phy.set_decode_mcch(false);
64  _state = STREAMING;
65 }
66 
67 void Rrc::write_pdu_bcch_dlsch(srsran::unique_byte_buffer_t pdu) {
68  // Stop BCCH search after successful reception of 1 BCCH block
69  // mac->bcch_stop_rx();
70 
71  bcch_dl_sch_msg_mbms_s dlsch_msg;
72  asn1::cbit_ref dlsch_bref(pdu->msg, pdu->N_bytes);
73  asn1::SRSASN_CODE err = dlsch_msg.unpack(dlsch_bref);
74 
75  if (err != asn1::SRSASN_SUCCESS || dlsch_msg.msg.type().value != bcch_dl_sch_msg_type_mbms_r14_c::types_opts::c1) {
76  spdlog::debug("Could not unpack BCCH DL-SCH MBMS message ({} B), trying as BCCH DL-SCH.", pdu->N_bytes);
77 
78  bcch_dl_sch_msg_s dlsch_msg1;
79  asn1::cbit_ref dlsch_bref(pdu->msg, pdu->N_bytes);
80  asn1::SRSASN_CODE err = dlsch_msg1.unpack(dlsch_bref);
81 
82  asn1::json_writer json_writer;
83  dlsch_msg1.to_json(json_writer);
84  spdlog::debug("BCCH-DLSCH message content:\n{}", json_writer.to_string());
85  return;
86  }
87 
88  asn1::json_writer json_writer;
89  dlsch_msg.to_json(json_writer);
90  spdlog::debug("BCCH-DLSCH MBMS message content:\n{}", json_writer.to_string());
91 
92  if (dlsch_msg.msg.c1().type() == bcch_dl_sch_msg_type_mbms_r14_c::c1_c_::types::sib_type1_mbms_r14) {
93  spdlog::debug("Processing SIB1-MBMS (1/1)");
94  handle_sib1(dlsch_msg.msg.c1().sib_type1_mbms_r14());
95  } else {
96  sys_info_r8_ies_s::sib_type_and_info_l_& sib_list =
97  dlsch_msg.msg.c1().sys_info_mbms_r14().crit_exts.sys_info_r8().sib_type_and_info;
98  for (auto& sib : sib_list) {
99  switch (sib.type().value) {
100  case sib_info_item_c::types::sib2:
101  spdlog::debug("Handling SIB2\n");
102  //handle_sib2();
103  break;
104  case sib_info_item_c::types::sib13_v920:
105  spdlog::debug("Handling SIB13\n");
106  _phy.set_mch_scheduling_info( srsran::make_sib13(sib.sib13_v920()));
107  if (!_rlc.has_bearer_mrb(0, 0)) {
108  _rlc.add_bearer_mrb(0, 0);
109  }
110  _phy.set_decode_mcch(true);
112  //handle_sib13();
113  break;
114  default:
115  spdlog::debug("SIB{} is not supported\n", sib.type().to_number());
116  }
117  }
118  }
119 }
120 
121 void Rrc::handle_sib1(const sib_type1_mbms_r14_s& sib1) {
122  spdlog::debug("SIB1-MBMS received, si_window={}",
123  sib1.si_win_len_r14.to_number());
124 
125  // Print SIB scheduling info
126  for (auto& i : sib1.sched_info_list_mbms_r14) {
127  sched_info_mbms_r14_s::si_periodicity_r14_e_ p = i.si_periodicity_r14;
128  for (auto t : i.sib_map_info_r14) {
129  spdlog::info("SIB scheduling info, sib_type={}, si_periodicity={}",
130  t.to_number(), p.to_number());
131  }
132  }
133 
134  _phy.set_mch_scheduling_info( srsran::make_sib13(sib1.sib_type13_r14));
135  if (!_rlc.has_bearer_mrb(0, 0)) {
136  _rlc.add_bearer_mrb(0, 0);
137  }
138 
139  _phy.set_decode_mcch(true);
141 }
142 
void set_decode_mcch(bool d)
Enable MCCH decoding.
Definition: Phy.h:148
void set_mch_scheduling_info(const srsran::sib13_t &sib13)
Set the values received in SIB13.
Definition: Phy.cpp:224
void set_mbsfn_config(const srsran::mcch_msg_t &mcch)
Set MBSFN configuration values.
Definition: Phy.cpp:260
void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) override
Handle a MCH PDU.
Definition: Rrc.cpp:34
void write_pdu_bcch_dlsch(srsran::unique_byte_buffer_t pdu) override
Handle SIB1(SIB13) from BCCH/DLSCH, and set the scheduling info in PHY.
Definition: Rrc.cpp:67
rrc_state_t _state
Definition: Rrc.h:81
@ ACQUIRE_AREA_CONFIG
Definition: Rrc.h:53
@ STREAMING
Definition: Rrc.h:54
void handle_sib1(const asn1::rrc::sib_type1_mbms_r14_s &sib1)
Definition: Rrc.cpp:121
Phy & _phy
Definition: Rrc.h:85
srsran::rlc & _rlc
Definition: Rrc.h:84