libflute
FileDeliveryTable.cpp
Go to the documentation of this file.
1 // libflute - FLUTE/ALC library
2 //
3 // Copyright (C) 2021 Klaus Kühnhammer (Österreichische Rundfunksender GmbH & Co KG)
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Affero General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Affero General Public License for more details.
14 //
15 // You should have received a copy of the GNU Affero General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 //
18 #include "FileDeliveryTable.h"
19 #include "tinyxml2.h"
20 #include <iostream>
21 #include <string>
22 #include "spdlog/spdlog.h"
23 
24 
26  : _instance_id( instance_id )
27  , _global_fec_oti( fec_oti )
28 {
29 }
30 
31 LibFlute::FileDeliveryTable::FileDeliveryTable(uint32_t instance_id, char* buffer, size_t len)
32  : _instance_id( instance_id )
33 {
34  tinyxml2::XMLDocument doc(true, tinyxml2::COLLAPSE_WHITESPACE);
35  doc.Parse(buffer, len);
36  auto fdt_instance = doc.FirstChildElement("FDT-Instance");
37  _expires = std::stoull(fdt_instance->Attribute("Expires"));
38 
39  spdlog::debug("Received new FDT with instance ID {}", instance_id);
40 
41  uint8_t def_fec_encoding_id = 0;
42  auto val = fdt_instance->Attribute("FEC-OTI-FEC-Encoding-ID");
43  if (val != nullptr) {
44  def_fec_encoding_id = strtoul(val, nullptr, 0);
45  }
46 
47  uint32_t def_fec_max_source_block_length = 0;
48  val = fdt_instance->Attribute("FEC-OTI-Maximum-Source-Block-Length");
49  if (val != nullptr) {
50  def_fec_max_source_block_length = strtoul(val, nullptr, 0);
51  }
52 
53  uint32_t def_fec_encoding_symbol_length = 0;
54  val = fdt_instance->Attribute("FEC-OTI-Encoding-Symbol-Length");
55  if (val != nullptr) {
56  def_fec_encoding_symbol_length = strtoul(val, nullptr, 0);
57  }
58 
59  for (auto file = fdt_instance->FirstChildElement("File");
60  file != nullptr; file = file->NextSiblingElement("File")) {
61 
62  // required attributes
63  auto toi_str = file->Attribute("TOI");
64  if (toi_str == nullptr) {
65  throw "Missing TOI attribute on File element";
66  }
67  uint32_t toi = strtoull(toi_str, nullptr, 0);
68 
69  auto content_location = file->Attribute("Content-Location");
70  if (content_location == nullptr) {
71  throw "Missing Content-Location attribute on File element";
72  }
73 
74  uint32_t content_length = 0;
75  val = file->Attribute("Content-Length");
76  if (val != nullptr) {
77  content_length = strtoull(val, nullptr, 0);
78  }
79 
80  uint32_t transfer_length = 0;
81  val = file->Attribute("Transfer-Length");
82  if (val != nullptr) {
83  transfer_length = strtoull(val, nullptr, 0);
84  }
85 
86  auto content_md5 = file->Attribute("Content-MD5");
87  if (!content_md5) {
88  content_md5 = "";
89  }
90 
91  auto content_type = file->Attribute("Content-Type");
92  if (!content_type) {
93  content_type = "";
94  }
95 
96  auto encoding_id = def_fec_encoding_id;
97  val = file->Attribute("FEC-OTI-FEC-Encoding-ID");
98  if (val != nullptr) {
99  encoding_id = strtoul(val, nullptr, 0);
100  }
101 
102  auto max_source_block_length = def_fec_max_source_block_length;
103  val = file->Attribute("FEC-OTI-Maximum-Source-Block-Length");
104  if (val != nullptr) {
105  max_source_block_length = strtoul(val, nullptr, 0);
106  }
107 
108  auto encoding_symbol_length = def_fec_encoding_symbol_length;
109  val = file->Attribute("FEC-OTI-Encoding-Symbol-Length");
110  if (val != nullptr) {
111  encoding_symbol_length = strtoul(val, nullptr, 0);
112  }
113  uint32_t expires = 0;
114  auto cc = file->FirstChildElement("mbms2007:Cache-Control");
115  if (cc) {
116  auto expires_elem = cc->FirstChildElement("mbms2007:Expires");
117  if (expires_elem) {
118  expires = strtoul(expires_elem->GetText(), nullptr, 0);
119  }
120  }
121 
122  FecOti fec_oti{
123  (FecScheme)encoding_id,
124  transfer_length,
125  encoding_symbol_length,
126  max_source_block_length
127  };
128 
129  FileEntry fe{
130  toi,
131  std::string(content_location),
132  content_length,
133  std::string(content_md5),
134  std::string(content_type),
135  expires,
136  fec_oti
137  };
138  _file_entries.push_back(fe);
139  }
140 }
141 
143 {
144  _instance_id++;
145  _file_entries.push_back(fe);
146 }
147 
148 auto LibFlute::FileDeliveryTable::remove(uint32_t toi) -> void
149 {
150  for (auto it = _file_entries.cbegin(); it != _file_entries.cend();) {
151  if (it->toi == toi) {
152  it = _file_entries.erase(it);
153  } else {
154  ++it;
155  }
156  }
157  _instance_id++;
158 }
159 
160 auto LibFlute::FileDeliveryTable::to_string() const -> std::string {
161  tinyxml2::XMLDocument doc;
162  doc.InsertFirstChild( doc.NewDeclaration() );
163  auto root = doc.NewElement("FDT-Instance");
164  root->SetAttribute("Expires", std::to_string(_expires).c_str());
165  root->SetAttribute("FEC-OTI-FEC-Encoding-ID", (unsigned)_global_fec_oti.encoding_id);
166  root->SetAttribute("FEC-OTI-Maximum-Source-Block-Length", (unsigned)_global_fec_oti.max_source_block_length);
167  root->SetAttribute("FEC-OTI-Encoding-Symbol-Length", (unsigned)_global_fec_oti.encoding_symbol_length);
168  root->SetAttribute("xmlns:mbms2007", "urn:3GPP:metadata:2007:MBMS:FLUTE:FDT");
169  doc.InsertEndChild(root);
170 
171  for (const auto& file : _file_entries) {
172  auto f = doc.NewElement("File");
173  f->SetAttribute("TOI", file.toi);
174  f->SetAttribute("Content-Location", file.content_location.c_str());
175  f->SetAttribute("Content-Length", file.content_length);
176  f->SetAttribute("Transfer-Length", (unsigned)file.fec_oti.transfer_length);
177  f->SetAttribute("Content-MD5", file.content_md5.c_str());
178  f->SetAttribute("Content-Type", file.content_type.c_str());
179  auto cc = doc.NewElement("mbms2007:Cache-Control");
180  auto exp = doc.NewElement("mbms2007:Expires");
181  exp->SetText(std::to_string(file.expires).c_str());
182  cc->InsertEndChild(exp);
183  f->InsertEndChild(cc);
184  root->InsertEndChild(f);
185  }
186 
187 
188  tinyxml2::XMLPrinter printer;
189  doc.Print(&printer);
190  return std::string(printer.CStr());
191 }
uint32_t instance_id()
Get the FDT instance ID.
void remove(uint32_t toi)
Remove a file entry.
std::string to_string() const
Serialize the FDT to an XML string.
FileDeliveryTable(uint32_t instance_id, FecOti fec_oti)
Create an empty FDT.
void add(const FileEntry &entry)
Add a file entry.
static char doc[]
FecScheme
Error correction schemes.
Definition: flute_types.h:46
OTI values struct.
Definition: flute_types.h:53
An entry for a file in the FDT.