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