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