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  foreach (auto car, m_carousels)
42  {
43  if (car && car->m_id == carouselId)
44  return car;
45  }
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.append(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  foreach (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  foreach (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  QLinkedList<ObjCarousel*>::iterator it = m_carousels.begin();
548 
549  if (it == m_carousels.end())
550  return 1; // Not yet loaded.
551 
552  // Can we actually have more than one carousel?
553  for (; it != m_carousels.end(); ++it)
554  {
555  int res = (*it)->m_fileCache.GetDSMObject(objectPath, result);
556  if (res != -1)
557  return res;
558  }
559 
560  return -1;
561 }
562 
563 // CRC code taken from libdtv (Rolf Hakenes)
564 // CRC32 lookup table for polynomial 0x04c11db7
565 
566 static unsigned long crc_table[256] =
567 {
568  0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
569  0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
570  0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
571  0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
572  0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
573  0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
574  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
575  0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
576  0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
577  0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
578  0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
579  0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
580  0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
581  0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
582  0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
583  0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
584  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
585  0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
586  0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
587  0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
588  0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
589  0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
590  0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
591  0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
592  0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
593  0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
594  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
595  0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
596  0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
597  0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
598  0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
599  0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
600  0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
601  0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
602  0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
603  0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
604  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
605  0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
606  0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
607  0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
608  0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
609  0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
610  0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
611 };
612 
613 static uint32_t crc32(const unsigned char *data, int len)
614 {
615  uint32_t crc = 0xffffffff;
616 
617  for (int i = 0; i < len; i++)
618  crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *data++) & 0xff];
619 
620  return crc;
621 }
unsigned char m_moduleInfoLen
Definition: dsmccbiop.h:232
void ProcessSectionIndication(const unsigned char *data, int length, unsigned short streamTag)
Definition: dsmcc.cpp:304
void AddModuleInfo(DsmccDii *dii, Dsmcc *status, unsigned short streamTag)
void ProcessDownloadServerInitiate(const unsigned char *data, int length)
Process a DSI message.
Definition: dsmcc.cpp:128
int Process(const unsigned char *data)
Definition: dsmccbiop.cpp:527
int Process(const unsigned char *Data)
Definition: dsmccbiop.cpp:351
unsigned long m_moduleSize
Definition: dsmccbiop.h:230
#define DSMCC_DDB_OFFSET
Definition: dsmcc.cpp:31
ObjCarousel * GetCarouselById(unsigned int carouselId)
Returns a carousel with the given ID.
Definition: dsmcc.cpp:39
void AddTap(Dsmcc *pStatus)
Definition: dsmccbiop.cpp:575
#define DSMCC_MESSAGE_DII
Definition: dsmcc.cpp:19
unsigned short m_startTag
Definition: dsmcc.h:114
unsigned short m_nModuleId
Definition: dsmcccache.h:52
#define DSMCC_DII_OFFSET
Definition: dsmcc.cpp:30
#define DSMCC_SECTION_DESCR
Definition: dsmcc.cpp:24
#define DSMCC_BIOP_OFFSET
Definition: dsmcc.cpp:32
unsigned long m_tcDownloadScenario
Definition: dsmccreceiver.h:21
static void ProcessSectionDesc(const unsigned char *data, int length)
Definition: dsmcc.cpp:437
unsigned short m_blockNumber
Definition: dsmccreceiver.h:63
QString toString(void) const
Definition: dsmcccache.cpp:53
unsigned short m_tableIdExtension
Definition: dsmccreceiver.h:35
#define DSMCC_MESSAGE_DSI
Definition: dsmcc.cpp:18
DSMCCCacheKey m_key
Definition: dsmcccache.h:54
#define DSMCC_DATAHDR_OFFSET
Definition: dsmcc.cpp:28
BiopModuleInfo m_modInfo
Definition: dsmccbiop.h:235
#define DSMCC_SECTION_DATA
Definition: dsmcc.cpp:23
virtual DSMCCCacheReference * GetReference()=0
unsigned char m_moduleVersion
Definition: dsmccbiop.h:231
unsigned char m_moduleVersion
Definition: dsmccreceiver.h:62
void SetGateway(const DSMCCCacheReference &ref)
Definition: dsmcccache.cpp:327
#define COMBINE32(data, idx)
Definition: dsmcc.h:117
#define DSMCC_MSGHDR_OFFSET
Definition: dsmcc.cpp:27
void ProcessDownloadInfoIndication(const unsigned char *data, unsigned short streamTag)
Definition: dsmcc.cpp:238
unsigned int uint
Definition: compat.h:140
int GetDSMCCObject(QStringList &objectPath, QByteArray &result)
Definition: dsmcc.cpp:545
static bool ProcessSectionHeader(DsmccSectionHeader *header, const unsigned char *data, int length)
Definition: dsmcc.cpp:87
unsigned long m_crc
Definition: dsmccreceiver.h:52
unsigned long m_downloadId
Definition: dsmccreceiver.h:19
#define DSMCC_SECTION_OFFSET
Definition: dsmcc.cpp:26
ObjCarousel * AddTap(unsigned short componentTag, unsigned carouselId)
Add a tap.
Definition: dsmcc.cpp:57
void Reset()
Definition: dsmcc.cpp:536
void ProcessSection(const unsigned char *data, int length, int componentTag, unsigned carouselId, int dataBroadcastId)
Definition: dsmcc.cpp:446
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
ProfileBody * m_profileBody
Definition: dsmccbiop.h:145
DsmccModuleInfo * m_modules
Definition: dsmccreceiver.h:24
unsigned long m_id
unsigned short m_moduleId
Definition: dsmccreceiver.h:61
QLinkedList< ObjCarousel * > m_carousels
Definition: dsmcc.h:111
unsigned short m_moduleId
Definition: dsmccbiop.h:229
unsigned short m_privateDataLen
Definition: dsmccreceiver.h:23
unsigned short m_blockSize
Definition: dsmccreceiver.h:20
unsigned long m_nCarouselId
Definition: dsmcccache.h:51
unsigned short m_numberModules
Definition: dsmccreceiver.h:22
unsigned int m_len
Definition: dsmccreceiver.h:64
static unsigned long crc_table[256]
Definition: dsmcc.cpp:566
#define DSMCC_MESSAGE_DDB
Definition: dsmcc.cpp:20
char * m_typeId
Definition: dsmccbiop.h:142
unsigned char m_flags2
Definition: dsmccreceiver.h:44
vector< unsigned short > m_Tags
Component tags matched to this carousel.
static uint32_t crc32(const unsigned char *data, int len)
Definition: dsmcc.cpp:613
#define DSMCC_DSI_OFFSET
Definition: dsmcc.cpp:29
void ProcessSectionData(const unsigned char *data, int length)
Definition: dsmcc.cpp:377
unsigned char m_flags[2]
Definition: dsmccreceiver.h:33
DSMCCCache m_fileCache
#define DSMCC_SECTION_INDICATION
Definition: dsmcc.cpp:22