/** \fn ObjCarousel::AddModuleData(unsigned long,DsmccDb*,const unsigned char*) * \brief We have received a block for a module. * * Add it to the module and process the module if it's now complete. */ void ObjCarousel::AddModuleData(unsigned long carousel, DsmccDb *ddb, const unsigned char *data) { LOG(VB_DSMCC, LOG_INFO, QString("[dsmcc] Data block on carousel %1").arg(m_id)); // Search the saved module info for this module QLinkedList<DSMCCCacheModuleData*>::iterator it = m_Cache.begin(); DSMCCCacheModuleData *cachep = NULL; for (; it != m_Cache.end(); ++it) { cachep = *it; if (cachep->CarouselId() == carousel && (cachep->ModuleId() == ddb->module_id)) { break; } } if (cachep == NULL) return; // Not found module info. // Add the block to the module unsigned char *tmp_data = cachep->AddModuleData(ddb, data); if (tmp_data) { // It is complete and we have the data unsigned int len = cachep->DataSize(); unsigned long curp = 0; LOG(VB_DSMCC, LOG_INFO, QString("[biop] Module size (uncompressed) = %1") .arg(len)); // Now process the BIOP tables in this module. // Tables may be file contents or the descriptions of // directories or service gateways (root directories). while (curp < len) { BiopMessage bm; if (!bm.Process(cachep, &filecache, tmp_data, &curp)) break; } free(tmp_data); } }
void ObjCarousel::AddModuleInfo(DsmccDii *dii, Dsmcc *status, unsigned short streamTag) { for (int i = 0; i < dii->number_modules; i++) { DsmccModuleInfo *info = &(dii->modules[i]); // Do we already know this module? // If so and it is the same version we don't need to do anything. // If the version has changed we have to replace it. QLinkedList<DSMCCCacheModuleData*>::iterator it = m_Cache.begin(); for ( ; it != m_Cache.end(); ++it) { DSMCCCacheModuleData *cachep = *it; if (cachep->CarouselId() == dii->download_id && cachep->ModuleId() == info->module_id) { /* already known */ if (cachep->Version() == info->module_version) { VERBOSE(VB_DSMCC, QString("[dsmcc] Already Know " "Module %1") .arg(info->module_id)); if (cachep->ModuleSize() == info->module_size) return; // It seems that when ITV4 starts broadcasting it // updates the contents of a file but doesn't // update the version. This is a work-around. VERBOSE(VB_DSMCC, QString("[dsmcc] Module %1 size " "has changed (%2 to %3) " "but version has not!!") .arg(info->module_id) .arg(info->module_size) .arg(cachep->DataSize())); } // Version has changed - Drop old data. VERBOSE(VB_DSMCC, QString("[dsmcc] Updated " "Module %1") .arg(info->module_id)); // Remove and delete the cache object. m_Cache.erase(it); delete cachep; break; } } VERBOSE(VB_DSMCC, QString("[dsmcc] Saving info for module %1") .arg(dii->modules[i].module_id)); // Create a new cache module data object. DSMCCCacheModuleData *cachep = new DSMCCCacheModuleData(dii, info, streamTag); int tag = info->modinfo.tap.assoc_tag; VERBOSE(VB_DSMCC, QString("[dsmcc] Module info tap " "identifies tag %1 with carousel %2\n") .arg(tag).arg(cachep->CarouselId())); // If a carousel with this id does not exist create it. status->AddTap(tag, cachep->CarouselId()); // Add this module to the cache. m_Cache.append(cachep); } }