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