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