diff --git a/srsue/test/ttcn3/hdr/ttcn3_drb_interface.h b/srsue/test/ttcn3/hdr/ttcn3_drb_interface.h index 529e76480..a5c315d55 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_drb_interface.h +++ b/srsue/test/ttcn3/hdr/ttcn3_drb_interface.h @@ -85,11 +85,53 @@ private: document.Accept(writer); log->info("Received JSON with %d B\n%s\n", json_len, (char*)buffer.GetString()); - // TODO: call handler + // check for common + assert(document.HasMember("Common")); + assert(document["Common"].IsObject()); + + // Check for user data + assert(document.HasMember("U_Plane")); + assert(document["U_Plane"].IsObject()); + + // Handle Pdus + const Value& uplane = document["U_Plane"]; + assert(uplane.HasMember("SubframeDataList")); + assert(uplane["SubframeDataList"].IsArray()); + + uint32_t lcid = document["Common"]["RoutingInfo"]["RadioBearerId"]["Drb"].GetInt() + 2; + + for (auto& sfdata : uplane["SubframeDataList"].GetArray()) { + assert(sfdata.HasMember("PduSduList")); + assert(sfdata["PduSduList"].IsObject()); + assert(sfdata["PduSduList"].HasMember("PdcpSdu")); + assert(sfdata["PduSduList"]["PdcpSdu"].IsArray()); + + const Value& sdulist = sfdata["PduSduList"]["PdcpSdu"]; + for (auto& sdu : sdulist.GetArray()) { + assert(sdu.IsString()); + string sdustr = sdu.GetString(); + asn1::dyn_octstring octstr(sdustr.size()); + octstr.from_string(sdustr); + + handle_sdu(document, lcid, octstr.data(), octstr.size(), ttcn3_helpers::get_follow_on_flag(document)); + } + } return SRSLTE_SUCCESS; } + void handle_sdu(Document& document, const uint16_t lcid, const uint8_t* payload, const uint16_t len, bool follow_on) + { + log->info_hex(payload, len, "Received DRB PDU (lcid=%d)\n", lcid); + + // pack into byte buffer + unique_byte_buffer_t pdu = pool_allocate_blocking; + pdu->N_bytes = len; + memcpy(pdu->msg, payload, pdu->N_bytes); + + syssim->add_dcch_pdu(ttcn3_helpers::get_timing_info(document), lcid, std::move(pdu), follow_on); + } + ss_srb_interface* syssim = nullptr; byte_buffer_pool* pool = nullptr; }; diff --git a/srsue/test/ttcn3/hdr/ttcn3_interfaces.h b/srsue/test/ttcn3/hdr/ttcn3_interfaces.h index 98e42a0dd..64440994d 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_interfaces.h +++ b/srsue/test/ttcn3/hdr/ttcn3_interfaces.h @@ -58,6 +58,9 @@ public: virtual void add_srb(const ttcn3_helpers::timing_info_t timing, const uint32_t lcid, const srslte::pdcp_config_t pdcp_config) = 0; virtual void del_srb(const ttcn3_helpers::timing_info_t timing, const uint32_t lcid) = 0; + virtual void + add_drb(const ttcn3_helpers::timing_info_t timing, const uint32_t lcid, const srslte::pdcp_config_t pdcp_config) = 0; + virtual void del_drb(const ttcn3_helpers::timing_info_t timing, const uint32_t lcid) = 0; virtual void set_as_security(const ttcn3_helpers::timing_info_t timing, const std::array k_rrc_enc, @@ -104,4 +107,4 @@ public: virtual void new_tb(const srsue::mac_interface_phy_lte::mac_grant_dl_t mac_grant, const uint8_t* data) = 0; }; -#endif // SRSUE_TTCN3_INTERFACES_H \ No newline at end of file +#endif // SRSUE_TTCN3_INTERFACES_H diff --git a/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h b/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h index f0f9128fe..b74291d4f 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h +++ b/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h @@ -316,9 +316,22 @@ private: } } else if (id.HasMember("Drb")) { log->info("Configure DRB%d\n", id["Drb"].GetInt()); - } - // TODO: actually do configuration + const Value& config = (*itr)["Config"]; + if (config.HasMember("AddOrReconfigure")) { + const Value& aor = config["AddOrReconfigure"]; + uint32_t lcid = aor["LogicalChannelId"].GetInt(); + if (lcid > 0) { + pdcp_config_t pdcp_cfg = make_drb_pdcp_config_t(static_cast(lcid), false); + syssim->add_drb(ttcn3_helpers::get_timing_info(document), lcid, pdcp_cfg); + } + } else if (config.HasMember("Release")) { + uint32_t lcid = id["Drb"].GetInt() + 2; + syssim->del_drb(ttcn3_helpers::get_timing_info(document), lcid); + } else { + log->error("Unknown config.\n"); + } + } } std::string resp = ttcn3_helpers::get_basic_sys_req_cnf(cell_id.GetString(), "RadioBearerList"); diff --git a/srsue/test/ttcn3/hdr/ttcn3_syssim.h b/srsue/test/ttcn3/hdr/ttcn3_syssim.h index c9dc22cee..2fada7cc4 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_syssim.h +++ b/srsue/test/ttcn3/hdr/ttcn3_syssim.h @@ -152,15 +152,18 @@ public: void step_stack(); void add_srb(const ttcn3_helpers::timing_info_t timing, const uint32_t lcid, const pdcp_config_t pdcp_config); - void add_srb_impl(const uint32_t lcid, const pdcp_config_t pdcp_config); void reestablish_bearer(uint32_t lcid); void del_srb(const ttcn3_helpers::timing_info_t timing, const uint32_t lcid); - void del_srb_impl(uint32_t lcid); + void add_drb(const ttcn3_helpers::timing_info_t timing, const uint32_t lcid, const pdcp_config_t pdcp_config); + void add_drb_impl(const uint32_t lcid, const pdcp_config_t pdcp_config); + void del_drb(const ttcn3_helpers::timing_info_t timing, const uint32_t lcid); + void del_drb_impl(uint32_t lcid); + // RRC interface for PDCP, PDCP calls RRC to push RRC SDU void write_pdu(uint32_t lcid, unique_byte_buffer_t pdu); diff --git a/srsue/test/ttcn3/src/ttcn3_syssim.cc b/srsue/test/ttcn3/src/ttcn3_syssim.cc index 6baba95f3..2d2f9d123 100644 --- a/srsue/test/ttcn3/src/ttcn3_syssim.cc +++ b/srsue/test/ttcn3/src/ttcn3_syssim.cc @@ -972,6 +972,47 @@ void ttcn3_syssim::del_srb_impl(uint32_t lcid) } } +void ttcn3_syssim::add_drb(const ttcn3_helpers::timing_info_t timing, + const uint32_t lcid, + const srslte::pdcp_config_t pdcp_config) +{ + if (timing.now) { + add_drb_impl(lcid, pdcp_config); + } else { + log->debug("Scheduling DRB%d addition for TTI=%d\n", lcid - 2, timing.tti); + tti_actions[timing.tti].push_back([this, lcid, pdcp_config]() { add_drb_impl(lcid, pdcp_config); }); + } +} + +void ttcn3_syssim::add_drb_impl(const uint32_t lcid, const pdcp_config_t pdcp_config) +{ + if (lcid > 2) { + log->info("Adding DRB%d\n", lcid - 2); + pdcp.add_bearer(lcid, pdcp_config); + rlc.add_bearer(lcid, srslte::rlc_config_t::default_rlc_am_config()); + } +} + +void ttcn3_syssim::del_drb(const ttcn3_helpers::timing_info_t timing, const uint32_t lcid) +{ + if (timing.now) { + del_drb_impl(lcid); + } else { + log->debug("Scheduling DRB%d deletion for TTI=%d\n", lcid - 2, timing.tti); + tti_actions[timing.tti].push_back([this, lcid]() { del_drb_impl(lcid); }); + } +} + +void ttcn3_syssim::del_drb_impl(uint32_t lcid) +{ + // Only delete DRB + if (lcid > 2) { + log->info("Deleting DRB%d\n", lcid - 2); + pdcp.del_bearer(lcid); + rlc.del_bearer(lcid); + } +} + // RRC interface for PDCP, PDCP calls RRC to push RRC SDU void ttcn3_syssim::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) { @@ -999,7 +1040,11 @@ void ttcn3_syssim::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) pdu->N_bytes++; // push content to Titan - srb.tx(std::move(pdu)); + if (lcid <= 2) { + srb.tx(std::move(pdu)); + } else { + drb.tx(std::move(pdu)); + } } // Not supported right now