OBECA Receive Process
Rrc.cpp
1 // OBECA - Open Broadcast Edge Cache Appliance
2 // Receive 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 "srslte/asn1/rrc_asn1_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_type_mbms_r14_c;
27 using asn1::rrc::sib_type1_mbms_r14_s;
28 using asn1::rrc::sib_type_mbms_r14_e;
29 using asn1::rrc::sched_info_mbms_r14_s;
30 
31 void Rrc::write_pdu_mch(uint32_t /*lcid*/, srslte::unique_byte_buffer_t pdu) {
32  spdlog::trace("rrc: write_pdu_mch");
33  if (pdu->N_bytes <= 0 || pdu->N_bytes >= SRSLTE_MAX_BUFFER_SIZE_BITS) {
34  return;
35  }
36  asn1::cbit_ref bref(pdu->msg, pdu->N_bytes);
37  asn1::rrc::mcch_msg_s msg;
38  if (msg.unpack(bref) != asn1::SRSASN_SUCCESS ||
39  msg.msg.type().value != mcch_msg_type_c::types_opts::c1) {
40  spdlog::error("Failed to unpack MCCH message");
41  return;
42  }
43  asn1::json_writer json_writer;
44  msg.to_json(json_writer);
45  spdlog::debug("BCCH-DLSCH message content:\n{}", json_writer.to_string());
46 
47  srslte::mcch_msg_t mcch = srslte::make_mcch_msg(msg);
48 
49  // add bearers for all LCIDs
50  for (uint32_t i = 0; i < mcch.nof_pmch_info; i++) {
51  for (uint32_t j = 0; j < mcch.pmch_info_list[i].nof_mbms_session_info; j++) {
52  uint32_t lcid = mcch.pmch_info_list[i].mbms_session_info_list[j].lc_ch_id;
53  if (!_rlc.has_bearer_mrb(lcid)) {
54  _rlc.add_bearer_mrb(lcid);
55  }
56  }
57  }
58 
59  _phy.set_mbsfn_config(mcch);
60  _phy.set_decode_mcch(false);
61  _state = STREAMING;
62 }
63 
64 void Rrc::write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t pdu) {
65  // Stop BCCH search after successful reception of 1 BCCH block
66  // mac->bcch_stop_rx();
67 
68  bcch_dl_sch_msg_mbms_s dlsch_msg;
69  asn1::cbit_ref dlsch_bref(pdu->msg, pdu->N_bytes);
70  asn1::SRSASN_CODE err = dlsch_msg.unpack(dlsch_bref);
71 
72  if (err != asn1::SRSASN_SUCCESS || dlsch_msg.msg.type().value != bcch_dl_sch_msg_type_mbms_r14_c::types_opts::c1) {
73  spdlog::error("Could not unpack BCCH DL-SCH message ({} B).", pdu->N_bytes);
74  return;
75  }
76 
77  asn1::json_writer json_writer;
78  dlsch_msg.to_json(json_writer);
79  spdlog::debug("BCCH-DLSCH message content:\n{}", json_writer.to_string());
80 
81  if (dlsch_msg.msg.c1().type() == bcch_dl_sch_msg_type_mbms_r14_c::c1_c_::types::sib_type1_mbms_r14) {
82  spdlog::debug("Processing SIB1-MBMS (1/1)");
83  handle_sib1(dlsch_msg.msg.c1().sib_type1_mbms_r14());
84  }
85 }
86 
87 void Rrc::handle_sib1(const sib_type1_mbms_r14_s& sib1) {
88  spdlog::debug("SIB1-MBMS received, si_window={}",
89  sib1.si_win_len_r14.to_number());
90 
91  // Print SIB scheduling info
92  for (auto& i : sib1.sched_info_list_mbms_r14) {
93  sched_info_mbms_r14_s::si_periodicity_r14_e_ p = i.si_periodicity_r14;
94  for (auto t : i.sib_map_info_r14) {
95  spdlog::info("SIB scheduling info, sib_type={}, si_periodicity={}",
96  t.to_number(), p.to_number());
97  }
98  }
99 
100  _phy.set_mch_scheduling_info( srslte::make_sib13(sib1.sib_type13_r14));
101  if (!_rlc.has_bearer_mrb(0)) {
102  _rlc.add_bearer_mrb(0);
103  }
104 
105  _phy.set_decode_mcch(true);
106  _state = ACQUIRE_AREA_CONFIG;
107 }
108 
Phy::set_mch_scheduling_info
void set_mch_scheduling_info(const srslte::sib13_t &sib13)
Set the values received in SIB13.
Definition: Phy.cpp:194
Rrc::write_pdu_bcch_dlsch
void write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t pdu) override
Handle SIB1(SIB13) from BCCH/DLSCH, and set the scheduling info in PHY.
Definition: Rrc.cpp:64
Rrc::write_pdu_mch
void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) override
Handle a MCH PDU.
Definition: Rrc.cpp:31
Phy::set_mbsfn_config
void set_mbsfn_config(const srslte::mcch_msg_t &mcch)
Set MBSFN configuration values.
Definition: Phy.cpp:230
Phy::set_decode_mcch
void set_decode_mcch(bool d)
Enable MCCH decoding.
Definition: Phy.h:149