+ ElementaryStreamInfoConstIterator es;
+ for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
+ {
+ int tmp=0;
+ switch ((*es)->getType())
+ {
+ case 0x05: // private
+ for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
+ desc != (*es)->getDescriptors()->end(); ++desc)
+ {
+ switch ((*desc)->getTag())
+ {
+ case PRIVATE_DATA_SPECIFIER_DESCRIPTOR:
+ if (((PrivateDataSpecifierDescriptor*)(*desc))->getPrivateDataSpecifier() == 190)
+ tmp |= 1;
+ break;
+ case 0x90:
+ {
+ UnknownDescriptor *descr = (UnknownDescriptor*)*desc;
+ int descr_len = descr->getLength();
+ if (descr_len == 4)
+ {
+ uint8_t data[descr_len+2];
+ descr->writeToBuffer(data);
+ if ( !data[2] && !data[3] && data[4] == 0xFF && data[5] == 0xFF )
+ tmp |= 2;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ default:
+ break;
+ }
+ if (tmp==3)
+ {
+ eServiceReferenceDVB ref;
+ if (!pmthandler->getService(ref))
+ {
+ int pid = (*es)->getPid();
+ messages.send(Message(Message::got_private_pid, ref, pid));
+ return;
+ }
+ }
+ }
+ }
+ }
+ else
+ eDebug("PMTready but no pmt!!");
+}
+
+struct date_time
+{
+ __u8 data[5];
+ time_t tm;
+ date_time( const date_time &a )
+ {
+ memcpy(data, a.data, 5);
+ tm = a.tm;
+ }
+ date_time( const __u8 data[5])
+ {
+ memcpy(this->data, data, 5);
+ tm = parseDVBtime(data[0], data[1], data[2], data[3], data[4]);
+ }
+ date_time()
+ {
+ }
+ const __u8& operator[](int pos) const
+ {
+ return data[pos];
+ }
+};
+
+struct less_datetime
+{
+ bool operator()( const date_time &a, const date_time &b ) const
+ {
+ return abs(a.tm-b.tm) < 360 ? false : a.tm < b.tm;
+ }
+};
+
+void eEPGCache::privateSectionRead(const uniqueEPGKey ¤t_service, const __u8 *data)
+{
+ contentMap &content_time_table = content_time_tables[current_service];
+ singleLock s(cache_lock);
+ std::map< date_time, std::list<uniqueEPGKey>, less_datetime > start_times;
+ eventMap &evMap = eventDB[current_service].first;
+ timeMap &tmMap = eventDB[current_service].second;
+ int ptr=8;
+ int content_id = data[ptr++] << 24;
+ content_id |= data[ptr++] << 16;
+ content_id |= data[ptr++] << 8;
+ content_id |= data[ptr++];
+
+ contentTimeMap &time_event_map =
+ content_time_table[content_id];
+ for ( contentTimeMap::iterator it( time_event_map.begin() );
+ it != time_event_map.end(); ++it )
+ {
+ eventMap::iterator evIt( evMap.find(it->second.second) );
+ if ( evIt != evMap.end() )
+ {
+ delete evIt->second;
+ evMap.erase(evIt);
+ }
+ tmMap.erase(it->second.first);
+ }
+ time_event_map.clear();
+
+ __u8 duration[3];
+ memcpy(duration, data+ptr, 3);
+ ptr+=3;
+ int duration_sec =
+ fromBCD(duration[0])*3600+fromBCD(duration[1])*60+fromBCD(duration[2]);
+
+ const __u8 *descriptors[65];
+ const __u8 **pdescr = descriptors;
+
+ int descriptors_length = (data[ptr++]&0x0F) << 8;
+ descriptors_length |= data[ptr++];
+ while ( descriptors_length > 0 )
+ {
+ int descr_type = data[ptr];
+ int descr_len = data[ptr+1];
+ descriptors_length -= (descr_len+2);
+ if ( descr_type == 0xf2 )
+ {
+ ptr+=2;
+ int tsid = data[ptr++] << 8;
+ tsid |= data[ptr++];
+ int onid = data[ptr++] << 8;
+ onid |= data[ptr++];
+ int sid = data[ptr++] << 8;
+ sid |= data[ptr++];
+ uniqueEPGKey service( sid, onid, tsid );
+ descr_len -= 6;
+ while( descr_len > 0 )
+ {
+ __u8 datetime[5];
+ datetime[0] = data[ptr++];
+ datetime[1] = data[ptr++];
+ int tmp_len = data[ptr++];
+ descr_len -= 3;
+ while( tmp_len > 0 )
+ {
+ memcpy(datetime+2, data+ptr, 3);
+ ptr+=3;
+ descr_len -= 3;
+ tmp_len -= 3;
+ start_times[datetime].push_back(service);
+ }
+ }
+ }
+ else
+ {
+ *pdescr++=data+ptr;
+ ptr += 2;
+ ptr += descr_len;
+ }
+ }
+ __u8 event[4098];
+ eit_event_struct *ev_struct = (eit_event_struct*) event;
+ ev_struct->running_status = 0;
+ ev_struct->free_CA_mode = 1;
+ memcpy(event+7, duration, 3);
+ ptr = 12;
+ const __u8 **d=descriptors;
+ while ( d < pdescr )
+ {
+ memcpy(event+ptr, *d, ((*d)[1])+2);
+ ptr+=(*d++)[1];
+ ptr+=2;
+ }
+ for ( std::map< date_time, std::list<uniqueEPGKey> >::iterator it(start_times.begin()); it != start_times.end(); ++it )
+ {
+ time_t now = eDVBLocalTimeHandler::getInstance()->nowTime();
+ if ( (it->first.tm + duration_sec) < now )
+ continue;
+ memcpy(event+2, it->first.data, 5);
+ int bptr = ptr;
+ int cnt=0;
+ for (std::list<uniqueEPGKey>::iterator i(it->second.begin()); i != it->second.end(); ++i)
+ {
+ event[bptr++] = 0x4A;
+ __u8 *len = event+(bptr++);
+ event[bptr++] = (i->tsid & 0xFF00) >> 8;
+ event[bptr++] = (i->tsid & 0xFF);
+ event[bptr++] = (i->onid & 0xFF00) >> 8;
+ event[bptr++] = (i->onid & 0xFF);
+ event[bptr++] = (i->sid & 0xFF00) >> 8;
+ event[bptr++] = (i->sid & 0xFF);
+ event[bptr++] = 0xB0;
+ bptr += sprintf((char*)(event+bptr), "Option %d", ++cnt);
+ *len = ((event+bptr) - len)-1;
+ }
+ int llen = bptr - 12;
+ ev_struct->descriptors_loop_length_hi = (llen & 0xF00) >> 8;
+ ev_struct->descriptors_loop_length_lo = (llen & 0xFF);
+
+ time_t stime = it->first.tm;
+ while( tmMap.find(stime) != tmMap.end() )
+ ++stime;
+ event[6] += (stime - it->first.tm);
+ __u16 event_id = 0;
+ while( evMap.find(event_id) != evMap.end() )
+ ++event_id;
+ event[0] = (event_id & 0xFF00) >> 8;
+ event[1] = (event_id & 0xFF);
+ time_event_map[it->first.tm]=std::pair<time_t, __u16>(stime, event_id);
+ eventData *d = new eventData( ev_struct, bptr, eEPGCache::SCHEDULE );
+ evMap[event_id] = d;
+ tmMap[stime] = d;
+ }
+}
+
+void eEPGCache::channel_data::startPrivateReader(int pid, int version)
+{
+ eDVBSectionFilterMask mask;
+ memset(&mask, 0, sizeof(mask));
+ mask.pid = pid;
+ mask.flags = eDVBSectionFilterMask::rfCRC;
+ mask.data[0] = 0xA0;
+ mask.mask[0] = 0xFF;
+ eDebug("start privatefilter for pid %04x and version %d", pid, version);
+ if (version != -1)
+ {
+ mask.data[3] = version << 1;
+ mask.mask[3] = 0x3E;
+ mask.mode[3] = 0x3E;
+ }
+ seenPrivateSections.clear();
+ m_PrivateReader->connectRead(slot(*this, &eEPGCache::channel_data::readPrivateData), m_PrivateConn);
+ m_PrivateReader->start(mask);
+#ifdef NEED_DEMUX_WORKAROUND
+ m_PrevVersion=version;
+#endif
+}
+
+void eEPGCache::channel_data::readPrivateData( const __u8 *data)
+{
+ if (!data)
+ eDebug("get Null pointer from section reader !!");
+ else
+ {
+ if ( seenPrivateSections.find( data[6] ) == seenPrivateSections.end() )
+ {
+#ifdef NEED_DEMUX_WORKAROUND
+ int version = data[5];
+ version = ((version & 0x3E) >> 1);
+ can_delete = 0;
+ if ( m_PrevVersion != version )
+ {
+ cache->privateSectionRead(m_PrivateService, data);
+ seenPrivateSections.insert(data[6]);
+ }
+ else
+ eDebug("ignore");
+#else
+ can_delete = 0;
+ cache->privateSectionRead(m_PrivateService, data);
+ seenPrivateSections.insert(data[6]);
+#endif
+ }
+ if ( seenPrivateSections.size() == (unsigned int)(data[7] + 1) )
+ {
+ eDebug("[EPGC] private finished");
+ if (!isRunning)
+ can_delete = 1;
+ int version = data[5];
+ version = ((version & 0x3E) >> 1);
+ startPrivateReader(m_PrivatePid, version);
+ }
+ }
+}