MythTV  master
dsmcc.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) David C.J. Matthews 2005, 2006
3  * Derived from libdsmcc by Richard Palmer
4  */
5 #include <cstdint>
6 
8 
9 #include "dsmccreceiver.h"
10 #include "dsmccbiop.h"
11 #include "dsmcccache.h"
12 #include "dsmcc.h"
13 
14 //static constexpr uint8_t DSMCC_SYNC_BYTE { 0x47 };
15 //static constexpr uint8_t DSMCC_TRANSPORT_ERROR { 0x80 };
16 //static constexpr uint8_t DSMCC_START_INDICATOR { 0x40 };
17 
22 };
23 
24 enum DSMCC_SECTIONS : std::uint8_t {
28 };
29 
30 static constexpr ptrdiff_t DSMCC_SECTION_OFFSET { 0 };
31 static constexpr ptrdiff_t DSMCC_MSGHDR_OFFSET { 8 };
32 static constexpr ptrdiff_t DSMCC_DATAHDR_OFFSET { 8 };
33 static constexpr ptrdiff_t DSMCC_DSI_OFFSET { 20 };
34 static constexpr ptrdiff_t DSMCC_DII_OFFSET { 20 };
35 static constexpr ptrdiff_t DSMCC_DDB_OFFSET { 20 };
36 static constexpr ptrdiff_t DSMCC_BIOP_OFFSET { 24 };
37 
38 static uint32_t crc32(const unsigned char *data, int len);
39 
43 ObjCarousel *Dsmcc::GetCarouselById(unsigned int carouselId)
44 {
45  auto it = std::find_if(m_carousels.cbegin(), m_carousels.cend(),
46  [carouselId](ObjCarousel const * const car) -> bool
47  { return car->m_id == carouselId; });
48  if (it != m_carousels.cend())
49  return *it;
50  return nullptr;
51 }
52 
61 ObjCarousel *Dsmcc::AddTap(unsigned short componentTag, unsigned carouselId)
62 {
63  ObjCarousel *car = GetCarouselById(carouselId);
64  // I think we will nearly always already have a carousel with this id
65  // except for start-up.
66 
67  if (car == nullptr)
68  { // Need to make a new one.
69  car = new ObjCarousel(this);
70  m_carousels.push_back(car);
71  car->m_id = carouselId;
72  }
73 
74  // Add this only if it's not already there.
75  std::vector<unsigned short>::iterator it;
76  for (it = car->m_Tags.begin(); it != car->m_Tags.end(); ++it)
77  {
78  if (*it == componentTag)
79  return car;
80  }
81 
82  // Not there.
83  car->m_Tags.push_back(componentTag);
84  LOG(VB_DSMCC, LOG_INFO, QString("[dsmcc] Adding tap for stream "
85  "tag %1 with carousel %2")
86  .arg(componentTag).arg(carouselId));
87 
88  return car;
89 }
90 
92  const unsigned char *data, int length)
93 {
94  int crc_offset = 0;
95 
96  header->m_tableId = data[0];
97  header->m_flags[0] = data[1];
98  header->m_flags[1] = data[2];
99 
100  /* Check CRC is set and private_indicator is set to its complement,
101  * else skip packet */
102  if (((header->m_flags[0] & 0x80) == 0) || (header->m_flags[0] & 0x40) != 0)
103  {
104  LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] Invalid section");
105  return false;
106  }
107 
108  /* data[3] - reserved */
109 
110  header->m_tableIdExtension = (data[4] << 8) | data[5];
111 
112  header->m_flags2 = data[6];
113 
114  crc_offset = length - 4 - 1; /* 4 bytes */
115 
116  /* skip to end, read last 4 bytes and store in crc */
117 
118  header->m_crc = COMBINE32(data, crc_offset);
119 
120  return true;
121 }
122 
132 void Dsmcc::ProcessDownloadServerInitiate(const unsigned char *data,
133  int length)
134 {
135  /* 0-19 Server id = 20 * 0xFF */
136  int off = 0;
137  for (off = 0; off < 20; ++off)
138  {
139  if (data[off] != 0xff)
140  {
141  LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] DSI invalid serverID"
142  " index %1: 0x%2").arg(off).arg(data[off],0,16));
143  return;
144  }
145  }
146 
147  /* 20,21 compatibilitydescriptorlength = 0x0000 */
148  if (data[off] != 0 || data[off+1] != 0)
149  {
150  LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] DSI non zero compatibilityDescriptorLen");
151  return;
152  }
153  off += 2;
154 
155  // 22,23 privateData length
156  int data_len = (data[off] << 8) | data[off+1];
157  off += 2;
158  if (data_len + off > length)
159  {
160  LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] DSI ServiceGatewayInfo too big");
161  return;
162  }
163 
164  // 24.. IOP::IOR
165  BiopIor gatewayProfile;
166  int ret = gatewayProfile.Process(data+DSMCC_BIOP_OFFSET);
167  if (ret <= 0)
168  return; /* error */
169 
170  if (strcmp(gatewayProfile.m_typeId, "srg") != 0)
171  {
172  LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] IOR unexpected type_id: '%1'")
173  .arg(gatewayProfile.m_typeId));
174  return; /* error */
175  }
176  if (ret + 4 > data_len)
177  {
178  LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] DSI IOP:IOR too big");
179  return; /* error */
180  }
181 
182  off += ret;
183 
184  // Process any new taps
185  gatewayProfile.AddTap(this);
186 
187  DSMCCCacheReference *ref = gatewayProfile.m_profileBody->GetReference();
188  unsigned carouselId = ref->m_nCarouselId;
189  ObjCarousel *car = GetCarouselById(carouselId);
190 
191  // This provides us with a map from component tag to carousel ID.
192  auto *full = dynamic_cast<ProfileBodyFull*>(gatewayProfile.m_profileBody);
193  if (full)
194  {
195  LOG(VB_DSMCC, LOG_DEBUG, QString("[dsmcc] DSI ServiceGateway"
196  " carousel %1 tag %2 module %3 key %4")
197  .arg(carouselId).arg(full->m_dsmConn.m_tap.m_assocTag)
198  .arg(ref->m_nModuleId).arg(ref->m_key.toString()));
199 
200  // Add the tap to the map and create a new carousel if necessary.
201  car = AddTap(full->m_dsmConn.m_tap.m_assocTag, carouselId);
202  }
203  else
204  {
205  LOG(VB_DSMCC, LOG_INFO, QString("[dsmcc] DSI ServiceGateway"
206  " carousel %1 module %2 key %3")
207  .arg(carouselId).arg(ref->m_nModuleId)
208  .arg(ref->m_key.toString()));
209  }
210 
211  // Set the gateway (if it isn't already set).
212  if (car)
213  car->m_fileCache.SetGateway(*ref);
214 
215  // The UK profile says that we can have the file to boot in
216  // the serviceContextList but in practice this seems not to
217  // be used and all these counts are zero.
218  unsigned short downloadTapsCount = data[off];
219  off++;
220  if (downloadTapsCount)
221  {
222  LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] DSI unexpected downloadTap");
223  // TODO off += downloadTapsCount * sizeof(DSM::Tap);
224  }
225 
226  unsigned short serviceContextListCount = data[off];
227  off++;
228  if (serviceContextListCount)
229  {
230  LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] DSI unexpected serviceContextList");
231  // TODO off += serviceContextListCount * sizeof serviceContextList;
232  }
233 
234  unsigned short userInfoLength = (data[off] << 8) | data[off+1];
235  // off += 2;
236  if (userInfoLength)
237  {
238  LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] DSI unexpected userInfo");
239  // off += userInfoLength;
240  }
241 }
242 
243 void Dsmcc::ProcessDownloadInfoIndication(const unsigned char *data,
244  unsigned short streamTag)
245 {
246  DsmccDii dii;
247  int off = 0;
248 
249  dii.m_downloadId = COMBINE32(data, 0);
250 
252 
253  if (car == nullptr)
254  {
255  LOG(VB_DSMCC, LOG_ERR, QString("[dsmcc] Section Info for "
256  "unknown carousel %1")
257  .arg(dii.m_downloadId));
258  // No known carousels yet (possible?)
259  return;
260  }
261 
262  off += 4;
263  dii.m_blockSize = data[off] << 8 | data[off+1];
264  off += 2;
265 
266  off += 6; /* not used fields */
267  dii.m_tcDownloadScenario = COMBINE32(data, off);
268  off += 4;
269 
270  /* skip unused compatibility descriptor len */
271  off += 2;
272  dii.m_numberModules = (data[off] << 8) | data[off + 1];
273  off += 2;
275 
276  for (uint i = 0; i < dii.m_numberModules; i++)
277  {
278  dii.m_modules[i].m_moduleId = (data[off] << 8) | data[off + 1];
279  off += 2;
280  dii.m_modules[i].m_moduleSize = COMBINE32(data, off);
281  off += 4;
282  dii.m_modules[i].m_moduleVersion = data[off++];
283  dii.m_modules[i].m_moduleInfoLen = data[off++];
284 
285  LOG(VB_DSMCC, LOG_DEBUG, QString("[dsmcc] Module %1 -> "
286  "Size = %2 Version = %3")
287  .arg(dii.m_modules[i].m_moduleId)
288  .arg(dii.m_modules[i].m_moduleSize)
289  .arg(dii.m_modules[i].m_moduleVersion));
290 
291  int ret = dii.m_modules[i].m_modInfo.Process(data + off);
292 
293  if (ret > 0)
294  {
295  off += ret;
296  }
297  else
298  {
299  return; // Error
300  }
301  }
302 
303  dii.m_privateDataLen = (data[off] << 8) | data[off + 1];
304 
305  car->AddModuleInfo(&dii, this, streamTag);
306 }
307 
308 // DSI or DII message.
309 void Dsmcc::ProcessSectionIndication(const unsigned char *data,
310  int length, unsigned short streamTag)
311 {
312  DsmccSectionHeader section {};
313  if (!ProcessSectionHeader(&section, data + DSMCC_SECTION_OFFSET, length))
314  return;
315 
316  const unsigned char *hdrData = data + DSMCC_MSGHDR_OFFSET;
317 
318  unsigned char protocol = hdrData[0];
319  if (protocol != 0x11)
320  {
321  LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] Server/Info invalid protocol %1")
322  .arg(protocol));
323  return;
324  }
325 
326  unsigned char header_type = hdrData[1];
327  if (header_type != 0x03)
328  {
329  LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] Server/Info invalid header type %1")
330  .arg(header_type));
331  return;
332  }
333 
334  unsigned message_id = (hdrData[2] << 8) | hdrData[3];
335 
336 // unsigned long transaction_id = (hdrData[4] << 24) | (hdrData[5] << 16) |
337 // (hdrData[6] << 8) | hdrData[7];
338 
339  /* Data[8] - reserved */
340  /* Data[9] - adapationLength 0x00 */
341 
342  unsigned message_len = (hdrData[10] << 8) | hdrData[11];
343  if (message_len > 4076) // Beyond valid length
344  {
345  LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] Server/Info invalid length %1")
346  .arg(message_len));
347  return;
348  }
349 
350  if (message_id == DSMCC_MESSAGE_DSI)
351  {
352  LOG(VB_DSMCC, LOG_DEBUG, "[dsmcc] Server Gateway");
353  // We only process DSI messages if they are received on the initial
354  // stream. Because we add taps eagerly we could see a DSI on a
355  // different stream before we see the one we actually want.
356  if (streamTag == m_startTag)
357  {
359  length - DSMCC_DSI_OFFSET);
360  }
361  else
362  {
363  LOG(VB_DSMCC, LOG_WARNING,
364  QString("[dsmcc] Discarding DSI from tag %1") .arg(streamTag));
365  }
366  // Otherwise discard it.
367  }
368  else if (message_id == DSMCC_MESSAGE_DII)
369  {
370  LOG(VB_DSMCC, LOG_DEBUG, "[dsmcc] Module Info");
372  }
373  else
374  {
375  LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] Unknown section");
376  /* Error */
377  }
378 
379 }
380 
381 // DDB Message.
382 void Dsmcc::ProcessSectionData(const unsigned char *data, int length)
383 {
384  DsmccSectionHeader section {};
385  if (!ProcessSectionHeader(&section, data + DSMCC_SECTION_OFFSET, length))
386  return;
387 
388  const unsigned char *hdrData = data + DSMCC_DATAHDR_OFFSET;
389 
390  unsigned char protocol = hdrData[0];
391  if (protocol != 0x11)
392  {
393  LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] Data invalid protocol %1")
394  .arg(protocol));
395  return;
396  }
397 
398  unsigned char header_type = hdrData[1];
399  if (header_type != 0x03)
400  {
401  LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] Data invalid header type %1")
402  .arg(header_type));
403  return;
404  }
405 
406  unsigned message_id = (hdrData[2] << 8) | hdrData[3];
407  if (message_id != DSMCC_MESSAGE_DDB)
408  {
409  LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] Data unknown section");
410  return;
411  }
412 
413  unsigned long download_id = COMBINE32(hdrData, 4);
414  /* skip reserved byte */
415 // char adaptation_len = hdrData[9];
416  unsigned message_len = (hdrData[10] << 8) | hdrData[11];
417 
418  const unsigned char *blockData = data + DSMCC_DDB_OFFSET;
419  DsmccDb ddb;
420 
421  ddb.m_moduleId = (blockData[0] << 8) | blockData[1];
422  ddb.m_moduleVersion = blockData[2];
423  /* skip reserved byte */
424  ddb.m_blockNumber = (blockData[4] << 8) | blockData[5];
425  ddb.m_len = message_len - 6;
426 
427  LOG(VB_DSMCC, LOG_DEBUG,
428  QString("[dsmcc] Data Block ModID %1 Pos %2 Version %3")
429  .arg(ddb.m_moduleId).arg(ddb.m_blockNumber).arg(ddb.m_moduleVersion));
430 
431  ObjCarousel *car = GetCarouselById(download_id);
432  if (car != nullptr)
433  car->AddModuleData(&ddb, blockData + 6);
434  else
435  {
436  LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] Data Block ModID %1 Pos %2"
437  " unknown carousel %3")
438  .arg(ddb.m_moduleId).arg(ddb.m_blockNumber).arg(download_id));
439  }
440 }
441 
442 void Dsmcc::ProcessSectionDesc(const unsigned char *data, int length)
443 {
444  DsmccSectionHeader section {};
445  ProcessSectionHeader(&section, data + DSMCC_SECTION_OFFSET, length);
446 
447  /* TODO */
448 }
449 
450 // Called with a complete section. Check it for integrity and then process it.
451 void Dsmcc::ProcessSection(const unsigned char *data, int length,
452  int componentTag, unsigned carouselId,
453  int dataBroadcastId)
454 {
455  // Does this component tag match one of our carousels?
456  LOG(VB_DSMCC, LOG_DEBUG, QString("[dsmcc] Read block size %1 from tag %2 "
457  "carousel id %3 data broadcast Id %4")
458  .arg(length).arg(componentTag)
459  .arg(carouselId).arg(dataBroadcastId,0,16));
460 
461  bool found = false;
462  for (auto *car : m_carousels)
463  {
464  // Is the component tag one of the ones we know?
465  std::vector<unsigned short>::iterator it2;
466  for (it2 = car->m_Tags.begin(); it2 != car->m_Tags.end(); ++it2)
467  {
468  if (*it2 == componentTag)
469  {
470  found = true;
471  break;
472  }
473  }
474  if (found)
475  break;
476  }
477  if (!found && dataBroadcastId == 0x0106)
478  {
479  // We haven't seen this stream before but it has the correct
480  // data_broadcast_id. Create a carousel for it.
481  // This will only happen at start-up
482  if (AddTap(componentTag, carouselId))
483  {
484  LOG(VB_DSMCC, LOG_INFO, QString("[dsmcc] Initial stream tag %1").arg(componentTag));
485  m_startTag = componentTag;
486  found = true;
487  }
488  }
489 
490  if (!found)
491  {
492  LOG(VB_DSMCC, LOG_INFO, QString("[dsmcc] Dropping block size %1 with tag %2"
493  ", carouselID %3, dataBroadcastID 0x%4")
494  .arg(length).arg(componentTag).arg(carouselId)
495  .arg(dataBroadcastId,0,16));
496 
497  return; // Ignore this stream.
498  }
499 
500  unsigned short section_len = ((data[1] & 0xF) << 8) | (data[2]);
501  section_len += 3;/* 3 bytes before length count starts */
502  if (section_len > length)
503  {
504  LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] section length > data length");
505  return;
506  }
507 
508  /* Check CRC before trying to parse */
509  unsigned long crc32_decode = crc32(data, section_len);
510 
511  if (crc32_decode != 0)
512  {
513  LOG(VB_DSMCC, LOG_WARNING,
514  QString("[dsmcc] Dropping corrupt section (Got %1)")
515  .arg(crc32_decode));
516  return;
517  }
518 
519  switch (data[0])
520  {
522  LOG(VB_DSMCC, LOG_DEBUG, "[dsmcc] Server/Info Section");
523  ProcessSectionIndication(data, length, componentTag);
524  break;
525  case DSMCC_SECTION_DATA:
526  LOG(VB_DSMCC, LOG_DEBUG, "[dsmcc] Data Section");
527  ProcessSectionData(data, length);
528  break;
529  case DSMCC_SECTION_DESCR:
530  LOG(VB_DSMCC, LOG_DEBUG, "[dsmcc] Descriptor Section");
531  ProcessSectionDesc(data, length);
532  break;
533  default:
534  LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] Unknown Section %1")
535  .arg(data[0]));
536  break;
537  }
538 }
539 
540 // Reset the object carousel and clear the caches.
542 {
543  LOG(VB_DSMCC, LOG_INFO, "[dsmcc] Resetting carousel");
544  for (const auto & carousel : m_carousels)
545  delete carousel;
546  m_carousels.clear();
547  m_startTag = 0;
548 }
549 
550 int Dsmcc::GetDSMCCObject(QStringList &objectPath, QByteArray &result)
551 {
552  auto it = m_carousels.begin();
553  if (it == m_carousels.end())
554  return 1; // Not yet loaded.
555 
556  // Can we actually have more than one carousel?
557  for (; it != m_carousels.end(); ++it)
558  {
559  int res = (*it)->m_fileCache.GetDSMObject(objectPath, result);
560  if (res != -1)
561  return res;
562  }
563 
564  return -1;
565 }
566 
567 // CRC code taken from libdtv (Rolf Hakenes)
568 // CRC32 lookup table for polynomial 0x04c11db7
569 
570 static const std::array<const uint32_t,256> crc_table
571 {
572  0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
573  0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
574  0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
575  0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
576  0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
577  0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
578  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
579  0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
580  0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
581  0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
582  0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
583  0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
584  0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
585  0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
586  0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
587  0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
588  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
589  0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
590  0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
591  0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
592  0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
593  0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
594  0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
595  0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
596  0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
597  0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
598  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
599  0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
600  0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
601  0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
602  0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
603  0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
604  0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
605  0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
606  0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
607  0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
608  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
609  0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
610  0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
611  0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
612  0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
613  0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
614  0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
615 };
616 
617 static uint32_t crc32(const unsigned char *data, int len)
618 {
619  uint32_t crc = 0xffffffff;
620 
621  for (int i = 0; i < len; i++)
622  crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *data++) & 0xff];
623 
624  return crc;
625 }
BiopIor::m_profileBody
ProfileBody * m_profileBody
Definition: dsmccbiop.h:146
Dsmcc::ProcessDownloadServerInitiate
void ProcessDownloadServerInitiate(const unsigned char *data, int length)
Process a DSI message.
Definition: dsmcc.cpp:132
Dsmcc::ProcessSectionData
void ProcessSectionData(const unsigned char *data, int length)
Definition: dsmcc.cpp:382
DsmccModuleInfo::m_moduleVersion
unsigned char m_moduleVersion
Definition: dsmccbiop.h:232
DsmccSectionHeader
Definition: dsmccreceiver.h:28
DsmccDb
Definition: dsmccreceiver.h:55
DSMCC_SECTION_OFFSET
static constexpr ptrdiff_t DSMCC_SECTION_OFFSET
Definition: dsmcc.cpp:30
crc_table
static const std::array< const uint32_t, 256 > crc_table
Definition: dsmcc.cpp:571
DSMCC_MESSAGE_DSI
@ DSMCC_MESSAGE_DSI
Definition: dsmcc.cpp:19
Dsmcc::ProcessSectionIndication
void ProcessSectionIndication(const unsigned char *data, int length, unsigned short streamTag)
Definition: dsmcc.cpp:309
dsmcccache.h
DsmccDb::m_blockNumber
unsigned short m_blockNumber
Definition: dsmccreceiver.h:63
DSMCCCache::SetGateway
void SetGateway(const DSMCCCacheReference &ref)
Definition: dsmcccache.cpp:320
DSMCC_SECTIONS
DSMCC_SECTIONS
Definition: dsmcc.cpp:24
DsmccDii::m_downloadId
unsigned long m_downloadId
Definition: dsmccreceiver.h:19
DSMCCCacheReference::m_nCarouselId
unsigned long m_nCarouselId
Definition: dsmcccache.h:51
BiopIor::m_typeId
char * m_typeId
Definition: dsmccbiop.h:143
DsmccModuleInfo::m_moduleId
unsigned short m_moduleId
Definition: dsmccbiop.h:230
DsmccDii::m_privateDataLen
unsigned short m_privateDataLen
Definition: dsmccreceiver.h:23
DsmccDii::m_blockSize
unsigned short m_blockSize
Definition: dsmccreceiver.h:20
BiopModuleInfo::Process
int Process(const unsigned char *Data)
Definition: dsmccbiop.cpp:353
BiopIor
Definition: dsmccbiop.h:129
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
DsmccDii::m_tcDownloadScenario
unsigned long m_tcDownloadScenario
Definition: dsmccreceiver.h:21
DSMCCCacheReference::m_key
DSMCCCacheKey m_key
Definition: dsmcccache.h:54
DSMCC_DATAHDR_OFFSET
static constexpr ptrdiff_t DSMCC_DATAHDR_OFFSET
Definition: dsmcc.cpp:32
ObjCarousel::AddModuleInfo
void AddModuleInfo(DsmccDii *dii, Dsmcc *status, unsigned short streamTag)
Definition: dsmccobjcarousel.cpp:153
Dsmcc::GetCarouselById
ObjCarousel * GetCarouselById(unsigned int carouselId)
Returns a carousel with the given ID.
Definition: dsmcc.cpp:43
DsmccSectionHeader::m_tableId
char m_tableId
Definition: dsmccreceiver.h:31
DSMCC_MSGHDR_OFFSET
static constexpr ptrdiff_t DSMCC_MSGHDR_OFFSET
Definition: dsmcc.cpp:31
BiopIor::Process
int Process(const unsigned char *data)
Definition: dsmccbiop.cpp:529
Dsmcc::m_startTag
unsigned short m_startTag
Definition: dsmcc.h:117
mythlogging.h
DsmccDii
Definition: dsmccreceiver.h:10
ObjCarousel::AddModuleData
void AddModuleData(DsmccDb *ddb, const unsigned char *data)
We have received a block for a module.
Definition: dsmccobjcarousel.cpp:227
DSMCC_SECTION_DESCR
@ DSMCC_SECTION_DESCR
Definition: dsmcc.cpp:27
DSMCC_SECTION_INDICATION
@ DSMCC_SECTION_INDICATION
Definition: dsmcc.cpp:25
ProfileBody::GetReference
virtual DSMCCCacheReference * GetReference()=0
BiopIor::AddTap
void AddTap(Dsmcc *pStatus) const
Definition: dsmccbiop.cpp:577
Dsmcc::ProcessSectionDesc
static void ProcessSectionDesc(const unsigned char *data, int length)
Definition: dsmcc.cpp:442
Dsmcc::ProcessDownloadInfoIndication
void ProcessDownloadInfoIndication(const unsigned char *data, unsigned short streamTag)
Definition: dsmcc.cpp:243
ObjCarousel
Definition: dsmccobjcarousel.h:62
dsmccreceiver.h
dsmccbiop.h
DsmccDb::m_moduleVersion
unsigned char m_moduleVersion
Definition: dsmccreceiver.h:62
Dsmcc::GetDSMCCObject
int GetDSMCCObject(QStringList &objectPath, QByteArray &result)
Definition: dsmcc.cpp:550
Dsmcc::ProcessSection
void ProcessSection(const unsigned char *data, int length, int componentTag, unsigned carouselId, int dataBroadcastId)
Definition: dsmcc.cpp:451
DsmccSectionHeader::m_tableIdExtension
unsigned short m_tableIdExtension
Definition: dsmccreceiver.h:35
DSMCC_SECTION_DATA
@ DSMCC_SECTION_DATA
Definition: dsmcc.cpp:26
DsmccModuleInfo
Definition: dsmccbiop.h:227
DsmccSectionHeader::m_flags
std::array< uint8_t, 2 > m_flags
Definition: dsmccreceiver.h:33
DSMCC_BIOP_OFFSET
static constexpr ptrdiff_t DSMCC_BIOP_OFFSET
Definition: dsmcc.cpp:36
DSMCC_MESSAGE_DII
@ DSMCC_MESSAGE_DII
Definition: dsmcc.cpp:20
ObjCarousel::m_id
unsigned long m_id
Definition: dsmccobjcarousel.h:74
uint
unsigned int uint
Definition: compat.h:81
DSMCC_DDB_OFFSET
static constexpr ptrdiff_t DSMCC_DDB_OFFSET
Definition: dsmcc.cpp:35
Dsmcc::AddTap
ObjCarousel * AddTap(unsigned short componentTag, unsigned carouselId)
Add a tap.
Definition: dsmcc.cpp:61
DSMCC_MESSAGES
DSMCC_MESSAGES
Definition: dsmcc.cpp:18
Dsmcc::Reset
void Reset()
Definition: dsmcc.cpp:541
Dsmcc::ProcessSectionHeader
static bool ProcessSectionHeader(DsmccSectionHeader *header, const unsigned char *data, int length)
Definition: dsmcc.cpp:91
DSMCC_DII_OFFSET
static constexpr ptrdiff_t DSMCC_DII_OFFSET
Definition: dsmcc.cpp:34
ObjCarousel::m_Tags
std::vector< unsigned short > m_Tags
Component tags matched to this carousel.
Definition: dsmccobjcarousel.h:73
DsmccModuleInfo::m_moduleInfoLen
unsigned char m_moduleInfoLen
Definition: dsmccbiop.h:233
DsmccDb::m_len
unsigned int m_len
Definition: dsmccreceiver.h:64
DsmccSectionHeader::m_flags2
unsigned char m_flags2
Definition: dsmccreceiver.h:44
DsmccModuleInfo::m_modInfo
BiopModuleInfo m_modInfo
Definition: dsmccbiop.h:236
DsmccSectionHeader::m_crc
unsigned long m_crc
Definition: dsmccreceiver.h:52
ObjCarousel::m_fileCache
DSMCCCache m_fileCache
Definition: dsmccobjcarousel.h:70
DsmccModuleInfo::m_moduleSize
unsigned long m_moduleSize
Definition: dsmccbiop.h:231
DsmccDii::m_numberModules
unsigned short m_numberModules
Definition: dsmccreceiver.h:22
ProfileBodyFull
Definition: dsmccbiop.h:96
DSMCC_MESSAGE_DDB
@ DSMCC_MESSAGE_DDB
Definition: dsmcc.cpp:21
COMBINE32
static constexpr uint32_t COMBINE32(const uint8_t *data, int idx)
Definition: dsmcc.h:120
DsmccDii::m_modules
DsmccModuleInfo * m_modules
Definition: dsmccreceiver.h:24
uint16_t
unsigned short uint16_t
Definition: iso6937tables.h:3
DSMCCCacheReference::m_nModuleId
unsigned short m_nModuleId
Definition: dsmcccache.h:52
crc32
static uint32_t crc32(const unsigned char *data, int len)
Definition: dsmcc.cpp:617
Dsmcc::m_carousels
std::list< ObjCarousel * > m_carousels
Definition: dsmcc.h:114
dsmcc.h
DSMCC_DSI_OFFSET
static constexpr ptrdiff_t DSMCC_DSI_OFFSET
Definition: dsmcc.cpp:33
DSMCCCacheKey::toString
QString toString(void) const
Definition: dsmcccache.cpp:53
DSMCCCacheReference
Definition: dsmcccache.h:33
DsmccDb::m_moduleId
unsigned short m_moduleId
Definition: dsmccreceiver.h:61