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 <algorithm>
6#include <cstdint>
7
9
10#include "dsmccreceiver.h"
11#include "dsmccbiop.h"
12#include "dsmcccache.h"
13#include "dsmcc.h"
14
15//static constexpr uint8_t DSMCC_SYNC_BYTE { 0x47 };
16//static constexpr uint8_t DSMCC_TRANSPORT_ERROR { 0x80 };
17//static constexpr uint8_t DSMCC_START_INDICATOR { 0x40 };
18
23};
24
25enum DSMCC_SECTIONS : std::uint8_t {
29};
30
31static constexpr ptrdiff_t DSMCC_SECTION_OFFSET { 0 };
32static constexpr ptrdiff_t DSMCC_MSGHDR_OFFSET { 8 };
33static constexpr ptrdiff_t DSMCC_DATAHDR_OFFSET { 8 };
34static constexpr ptrdiff_t DSMCC_DSI_OFFSET { 20 };
35static constexpr ptrdiff_t DSMCC_DII_OFFSET { 20 };
36static constexpr ptrdiff_t DSMCC_DDB_OFFSET { 20 };
37static constexpr ptrdiff_t DSMCC_BIOP_OFFSET { 24 };
38
39static uint32_t crc32(const unsigned char *data, int len);
40
44ObjCarousel *Dsmcc::GetCarouselById(unsigned int carouselId)
45{
46 auto it = std::ranges::find(m_carousels, carouselId, &ObjCarousel::m_id);
47 if (it != m_carousels.end())
48 return *it;
49 return nullptr;
50}
51
60ObjCarousel *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.push_back(car);
70 car->m_id = carouselId;
71 }
72
73 // Add this only if it's not already there.
74 std::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_tableId = 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_tableIdExtension = (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
131void Dsmcc::ProcessDownloadServerInitiate(const unsigned char *data,
132 int length)
133{
134 /* 0-19 Server id = 20 * 0xFF */
135 int off = 0;
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+1] != 0)
148 {
149 LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] DSI non zero compatibilityDescriptorLen");
150 return;
151 }
152 off += 2;
153
154 // 22,23 privateData length
155 int data_len = (data[off] << 8) | data[off+1];
156 off += 2;
157 if (data_len + off > length)
158 {
159 LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] DSI ServiceGatewayInfo too big");
160 return;
161 }
162
163 // 24.. IOP::IOR
164 BiopIor gatewayProfile;
165 int ret = gatewayProfile.Process(data+DSMCC_BIOP_OFFSET);
166 if (ret <= 0)
167 return; /* error */
168
169 if (gatewayProfile.m_typeId != "srg")
170 {
171 LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] IOR unexpected type_id: '%1'")
172 .arg(QString::fromStdString(gatewayProfile.m_typeId)));
173 return; /* error */
174 }
175 if (ret + 4 > data_len)
176 {
177 LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] DSI IOP:IOR too big");
178 return; /* error */
179 }
180
181 off += ret;
182
183 // Process any new taps
184 gatewayProfile.AddTap(this);
185
186 DSMCCCacheReference *ref = gatewayProfile.m_profileBody->GetReference();
187 unsigned carouselId = ref->m_nCarouselId;
188 ObjCarousel *car = GetCarouselById(carouselId);
189
190 // This provides us with a map from component tag to carousel ID.
191 auto *full = dynamic_cast<ProfileBodyFull*>(gatewayProfile.m_profileBody);
192 if (full)
193 {
194 LOG(VB_DSMCC, LOG_DEBUG, QString("[dsmcc] DSI ServiceGateway"
195 " carousel %1 tag %2 module %3 key %4")
196 .arg(carouselId).arg(full->m_dsmConn.m_tap.m_assocTag)
197 .arg(ref->m_nModuleId).arg(ref->m_key.toString()));
198
199 // Add the tap to the map and create a new carousel if necessary.
200 car = AddTap(full->m_dsmConn.m_tap.m_assocTag, carouselId);
201 }
202 else
203 {
204 LOG(VB_DSMCC, LOG_INFO, QString("[dsmcc] DSI ServiceGateway"
205 " carousel %1 module %2 key %3")
206 .arg(carouselId).arg(ref->m_nModuleId)
207 .arg(ref->m_key.toString()));
208 }
209
210 // Set the gateway (if it isn't already set).
211 if (car)
212 car->m_fileCache.SetGateway(*ref);
213
214 // The UK profile says that we can have the file to boot in
215 // the serviceContextList but in practice this seems not to
216 // be used and all these counts are zero.
217 unsigned short downloadTapsCount = data[off];
218 off++;
219 if (downloadTapsCount)
220 {
221 LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] DSI unexpected downloadTap");
222 // TODO off += downloadTapsCount * sizeof(DSM::Tap);
223 }
224
225 unsigned short serviceContextListCount = data[off];
226 off++;
227 if (serviceContextListCount)
228 {
229 LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] DSI unexpected serviceContextList");
230 // TODO off += serviceContextListCount * sizeof serviceContextList;
231 }
232
233 unsigned short userInfoLength = (data[off] << 8) | data[off+1];
234 // off += 2;
235 if (userInfoLength)
236 {
237 LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] DSI unexpected userInfo");
238 // off += userInfoLength;
239 }
240}
241
242void Dsmcc::ProcessDownloadInfoIndication(const unsigned char *data,
243 unsigned short streamTag)
244{
245 DsmccDii dii;
246 int off = 0;
247
248 dii.m_downloadId = COMBINE32(data, 0);
249
251
252 if (car == nullptr)
253 {
254 LOG(VB_DSMCC, LOG_ERR, QString("[dsmcc] Section Info for "
255 "unknown carousel %1")
256 .arg(dii.m_downloadId));
257 // No known carousels yet (possible?)
258 return;
259 }
260
261 off += 4;
262 dii.m_blockSize = data[off] << 8 | data[off+1];
263 off += 2;
264
265 off += 6; /* not used fields */
266 dii.m_tcDownloadScenario = COMBINE32(data, off);
267 off += 4;
268
269 /* skip unused compatibility descriptor len */
270 off += 2;
271 dii.m_numberModules = (data[off] << 8) | data[off + 1];
272 off += 2;
274
275 for (uint i = 0; i < dii.m_numberModules; i++)
276 {
277 dii.m_modules[i].m_moduleId = (data[off] << 8) | data[off + 1];
278 off += 2;
279 dii.m_modules[i].m_moduleSize = COMBINE32(data, off);
280 off += 4;
281 dii.m_modules[i].m_moduleVersion = data[off++];
282 dii.m_modules[i].m_moduleInfoLen = data[off++];
283
284 LOG(VB_DSMCC, LOG_DEBUG, QString("[dsmcc] Module %1 -> "
285 "Size = %2 Version = %3")
286 .arg(dii.m_modules[i].m_moduleId)
287 .arg(dii.m_modules[i].m_moduleSize)
288 .arg(dii.m_modules[i].m_moduleVersion));
289
290 int ret = dii.m_modules[i].m_modInfo.Process(data + off);
291
292 if (ret > 0)
293 {
294 off += ret;
295 }
296 else
297 {
298 return; // Error
299 }
300 }
301
302 dii.m_privateDataLen = (data[off] << 8) | data[off + 1];
303
304 car->AddModuleInfo(&dii, this, streamTag);
305}
306
307// DSI or DII message.
308void Dsmcc::ProcessSectionIndication(const unsigned char *data,
309 int length, unsigned short streamTag)
310{
311 DsmccSectionHeader section {};
312 if (!ProcessSectionHeader(&section, data + DSMCC_SECTION_OFFSET, length))
313 return;
314
315 const unsigned char *hdrData = data + DSMCC_MSGHDR_OFFSET;
316
317 unsigned char protocol = hdrData[0];
318 if (protocol != 0x11)
319 {
320 LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] Server/Info invalid protocol %1")
321 .arg(protocol));
322 return;
323 }
324
325 unsigned char header_type = hdrData[1];
326 if (header_type != 0x03)
327 {
328 LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] Server/Info invalid header type %1")
329 .arg(header_type));
330 return;
331 }
332
333 unsigned message_id = (hdrData[2] << 8) | hdrData[3];
334
335// unsigned long transaction_id = (hdrData[4] << 24) | (hdrData[5] << 16) |
336// (hdrData[6] << 8) | hdrData[7];
337
338 /* Data[8] - reserved */
339 /* Data[9] - adapationLength 0x00 */
340
341 unsigned message_len = (hdrData[10] << 8) | hdrData[11];
342 if (message_len > 4076) // Beyond valid length
343 {
344 LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] Server/Info invalid length %1")
345 .arg(message_len));
346 return;
347 }
348
349 if (message_id == DSMCC_MESSAGE_DSI)
350 {
351 LOG(VB_DSMCC, LOG_DEBUG, "[dsmcc] Server Gateway");
352 // We only process DSI messages if they are received on the initial
353 // stream. Because we add taps eagerly we could see a DSI on a
354 // different stream before we see the one we actually want.
355 if (streamTag == m_startTag)
356 {
358 length - DSMCC_DSI_OFFSET);
359 }
360 else
361 {
362 LOG(VB_DSMCC, LOG_WARNING,
363 QString("[dsmcc] Discarding DSI from tag %1") .arg(streamTag));
364 }
365 // Otherwise discard it.
366 }
367 else if (message_id == DSMCC_MESSAGE_DII)
368 {
369 LOG(VB_DSMCC, LOG_DEBUG, "[dsmcc] Module Info");
371 }
372 else
373 {
374 LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] Unknown section");
375 /* Error */
376 }
377
378}
379
380// DDB Message.
381void Dsmcc::ProcessSectionData(const unsigned char *data, int length)
382{
383 DsmccSectionHeader section {};
384 if (!ProcessSectionHeader(&section, data + DSMCC_SECTION_OFFSET, length))
385 return;
386
387 const unsigned char *hdrData = data + DSMCC_DATAHDR_OFFSET;
388
389 unsigned char protocol = hdrData[0];
390 if (protocol != 0x11)
391 {
392 LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] Data invalid protocol %1")
393 .arg(protocol));
394 return;
395 }
396
397 unsigned char header_type = hdrData[1];
398 if (header_type != 0x03)
399 {
400 LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] Data invalid header type %1")
401 .arg(header_type));
402 return;
403 }
404
405 unsigned message_id = (hdrData[2] << 8) | hdrData[3];
406 if (message_id != DSMCC_MESSAGE_DDB)
407 {
408 LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] Data unknown section");
409 return;
410 }
411
412 unsigned long download_id = COMBINE32(hdrData, 4);
413 /* skip reserved byte */
414// char adaptation_len = hdrData[9];
415 unsigned message_len = (hdrData[10] << 8) | hdrData[11];
416
417 const unsigned char *blockData = data + DSMCC_DDB_OFFSET;
418 DsmccDb ddb;
419
420 ddb.m_moduleId = (blockData[0] << 8) | blockData[1];
421 ddb.m_moduleVersion = blockData[2];
422 /* skip reserved byte */
423 ddb.m_blockNumber = (blockData[4] << 8) | blockData[5];
424 ddb.m_len = message_len - 6;
425
426 LOG(VB_DSMCC, LOG_DEBUG,
427 QString("[dsmcc] Data Block ModID %1 Pos %2 Version %3")
428 .arg(ddb.m_moduleId).arg(ddb.m_blockNumber).arg(ddb.m_moduleVersion));
429
430 ObjCarousel *car = GetCarouselById(download_id);
431 if (car != nullptr)
432 {
433 car->AddModuleData(&ddb, blockData + 6);
434 }
435 else
436 {
437 LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] Data Block ModID %1 Pos %2"
438 " unknown carousel %3")
439 .arg(ddb.m_moduleId).arg(ddb.m_blockNumber).arg(download_id));
440 }
441}
442
443void Dsmcc::ProcessSectionDesc(const unsigned char *data, int length)
444{
445 DsmccSectionHeader section {};
446 ProcessSectionHeader(&section, data + DSMCC_SECTION_OFFSET, length);
447
448 /* TODO */
449}
450
451// Called with a complete section. Check it for integrity and then process it.
452void Dsmcc::ProcessSection(const unsigned char *data, int length,
453 int componentTag, unsigned carouselId,
454 int dataBroadcastId)
455{
456 // Does this component tag match one of our carousels?
457 LOG(VB_DSMCC, LOG_DEBUG, QString("[dsmcc] Read block size %1 from tag %2 "
458 "carousel id %3 data broadcast Id %4")
459 .arg(length).arg(componentTag)
460 .arg(carouselId).arg(dataBroadcastId,0,16));
461
462 bool found = false;
463 for (auto *car : m_carousels)
464 {
465 // Is the component tag one of the ones we know?
466 std::vector<unsigned short>::iterator it2;
467 for (it2 = car->m_Tags.begin(); it2 != car->m_Tags.end(); ++it2)
468 {
469 if (*it2 == componentTag)
470 {
471 found = true;
472 break;
473 }
474 }
475 if (found)
476 break;
477 }
478 if (!found && dataBroadcastId == 0x0106)
479 {
480 // We haven't seen this stream before but it has the correct
481 // data_broadcast_id. Create a carousel for it.
482 // This will only happen at start-up
483 if (AddTap(componentTag, carouselId))
484 {
485 LOG(VB_DSMCC, LOG_INFO, QString("[dsmcc] Initial stream tag %1").arg(componentTag));
486 m_startTag = componentTag;
487 found = true;
488 }
489 }
490
491 if (!found)
492 {
493 LOG(VB_DSMCC, LOG_INFO, QString("[dsmcc] Dropping block size %1 with tag %2"
494 ", carouselID %3, dataBroadcastID 0x%4")
495 .arg(length).arg(componentTag).arg(carouselId)
496 .arg(dataBroadcastId,0,16));
497
498 return; // Ignore this stream.
499 }
500
501 unsigned short section_len = ((data[1] & 0xF) << 8) | (data[2]);
502 section_len += 3;/* 3 bytes before length count starts */
503 if (section_len > length)
504 {
505 LOG(VB_DSMCC, LOG_WARNING, "[dsmcc] section length > data length");
506 return;
507 }
508
509 /* Check CRC before trying to parse */
510 unsigned long crc32_decode = crc32(data, section_len);
511
512 if (crc32_decode != 0)
513 {
514 LOG(VB_DSMCC, LOG_WARNING,
515 QString("[dsmcc] Dropping corrupt section (Got %1)")
516 .arg(crc32_decode));
517 return;
518 }
519
520 switch (data[0])
521 {
523 LOG(VB_DSMCC, LOG_DEBUG, "[dsmcc] Server/Info Section");
524 ProcessSectionIndication(data, length, componentTag);
525 break;
527 LOG(VB_DSMCC, LOG_DEBUG, "[dsmcc] Data Section");
528 ProcessSectionData(data, length);
529 break;
531 LOG(VB_DSMCC, LOG_DEBUG, "[dsmcc] Descriptor Section");
532 ProcessSectionDesc(data, length);
533 break;
534 default:
535 LOG(VB_DSMCC, LOG_WARNING, QString("[dsmcc] Unknown Section %1")
536 .arg(data[0]));
537 break;
538 }
539}
540
541// Reset the object carousel and clear the caches.
543{
544 LOG(VB_DSMCC, LOG_INFO, "[dsmcc] Resetting carousel");
545 for (const auto & carousel : m_carousels)
546 delete carousel;
547 m_carousels.clear();
548 m_startTag = 0;
549}
550
551int Dsmcc::GetDSMCCObject(QStringList &objectPath, QByteArray &result)
552{
553 auto it = m_carousels.begin();
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
571static const std::array<const uint32_t,256> crc_table
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
618static uint32_t crc32(const unsigned char *data, int len)
619{
620 uint32_t crc = 0xffffffff;
621
622 for (int i = 0; i < len; i++)
623 crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *data++) & 0xff];
624
625 return crc;
626}
void AddTap(Dsmcc *pStatus) const
Definition: dsmccbiop.cpp:559
std::string m_typeId
Definition: dsmccbiop.h:138
int Process(const unsigned char *data)
Definition: dsmccbiop.cpp:509
ProfileBody * m_profileBody
Definition: dsmccbiop.h:141
int Process(const unsigned char *Data)
Definition: dsmccbiop.cpp:334
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:318
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:224
unsigned short m_moduleId
Definition: dsmccbiop.h:222
unsigned char m_moduleInfoLen
Definition: dsmccbiop.h:225
BiopModuleInfo m_modInfo
Definition: dsmccbiop.h:228
unsigned long m_moduleSize
Definition: dsmccbiop.h:223
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:242
void ProcessDownloadServerInitiate(const unsigned char *data, int length)
Process a DSI message.
Definition: dsmcc.cpp:131
static void ProcessSectionDesc(const unsigned char *data, int length)
Definition: dsmcc.cpp:443
int GetDSMCCObject(QStringList &objectPath, QByteArray &result)
Definition: dsmcc.cpp:551
std::list< ObjCarousel * > m_carousels
Definition: dsmcc.h:114
void ProcessSectionData(const unsigned char *data, int length)
Definition: dsmcc.cpp:381
ObjCarousel * GetCarouselById(unsigned int carouselId)
Returns a carousel with the given ID.
Definition: dsmcc.cpp:44
void Reset()
Definition: dsmcc.cpp:542
unsigned short m_startTag
Definition: dsmcc.h:117
static bool ProcessSectionHeader(DsmccSectionHeader *header, const unsigned char *data, int length)
Definition: dsmcc.cpp:90
void ProcessSection(const unsigned char *data, int length, int componentTag, unsigned carouselId, int dataBroadcastId)
Definition: dsmcc.cpp:452
ObjCarousel * AddTap(unsigned short componentTag, unsigned carouselId)
Add a tap.
Definition: dsmcc.cpp:60
void ProcessSectionIndication(const unsigned char *data, int length, unsigned short streamTag)
Definition: dsmcc.cpp:308
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
unsigned int uint
Definition: compat.h:60
static constexpr ptrdiff_t DSMCC_DII_OFFSET
Definition: dsmcc.cpp:35
static uint32_t crc32(const unsigned char *data, int len)
Definition: dsmcc.cpp:618
static const std::array< const uint32_t, 256 > crc_table
Definition: dsmcc.cpp:572
static constexpr ptrdiff_t DSMCC_SECTION_OFFSET
Definition: dsmcc.cpp:31
static constexpr ptrdiff_t DSMCC_DATAHDR_OFFSET
Definition: dsmcc.cpp:33
DSMCC_MESSAGES
Definition: dsmcc.cpp:19
@ DSMCC_MESSAGE_DDB
Definition: dsmcc.cpp:22
@ DSMCC_MESSAGE_DSI
Definition: dsmcc.cpp:20
@ DSMCC_MESSAGE_DII
Definition: dsmcc.cpp:21
DSMCC_SECTIONS
Definition: dsmcc.cpp:25
@ DSMCC_SECTION_DESCR
Definition: dsmcc.cpp:28
@ DSMCC_SECTION_DATA
Definition: dsmcc.cpp:27
@ DSMCC_SECTION_INDICATION
Definition: dsmcc.cpp:26
static constexpr ptrdiff_t DSMCC_DDB_OFFSET
Definition: dsmcc.cpp:36
static constexpr ptrdiff_t DSMCC_MSGHDR_OFFSET
Definition: dsmcc.cpp:32
static constexpr ptrdiff_t DSMCC_BIOP_OFFSET
Definition: dsmcc.cpp:37
static constexpr ptrdiff_t DSMCC_DSI_OFFSET
Definition: dsmcc.cpp:34
static constexpr uint32_t COMBINE32(const uint8_t *data, int idx)
Definition: dsmcc.h:120
static pid_list_t::iterator find(const PIDInfoMap &map, pid_list_t &list, pid_list_t::iterator begin, pid_list_t::iterator end, bool find_open)
unsigned short uint16_t
Definition: iso6937tables.h:3
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39