Database::Ptr Database::getDatabase(cDevice *dev) { checkInitialDatabaseSetup();  for (int i=0;i<cDevice::NumDevices();i++) if (databases[i] && databases[i]->device==dev) return databases[i]; DeliverySystem system; for (int i=0;i<cDevice::NumDevices();i++) { cDevice  *idev=cDevice::GetDevice(i); if (idev==dev && !noReceptionDatabases[i]) { if ((system=getDeliverySystem(idev)) != DeliverySystemNone) { databases[i]=new Database(idev, system); return databases[i]; } else noReceptionDatabases[i]=true; } } return 0; }  Database::Ptr Database::getDatabase(int numDevice) { checkInitialDatabaseSetup();  DeliverySystem system; cDevice  *idev=cDevice::GetDevice(numDevice); if (!databases[numDevice] && !noReceptionDatabases[numDevice]) { if ((system=getDeliverySystem(idev)) != DeliverySystemNone) databases[numDevice]=new Database(idev, system); else noReceptionDatabases[numDevice]=true; } return databases[numDevice]; }    Database::Ptr Database::getDatabaseForChannel(int nid, int tid, int sid, bool shallBeTunedTo, cChannel **chan) {
bool Database::getDatabases(std::list<Database::Ptr> &list) { for (uint i=0;i<databases.size();i++) list.push_back(databases[i]); return databases.size(); }
namespace DvbSi {Database::DatabaseArray Database::databases;Database::DispatchThread *Database::dispatchThread=new Database::DispatchThread();bool *Database::noReceptionDatabases=0;int Database::primaryIndex = -1;int Database::getNumberOfValidDatabases() {   int count=getNumberOfDatabases();   for (uint i=0;i<databases.size();i++)      if (noReceptionDatabases[i])         count--;   return count;}Database::Ptr Database::getPrimaryDatabase() {   checkInitialDatabaseSetup();         if (primaryIndex != -1)      return databases[primaryIndex];      DeliverySystem system;   int indexOfPrimary=cDevice::PrimaryDevice()->DeviceNumber();   if (!databases[indexOfPrimary] && !noReceptionDatabases[indexOfPrimary]) {          if ((system=getDeliverySystem(cDevice::PrimaryDevice())) != DeliverySystemNone) {         primaryIndex=indexOfPrimary;         databases[primaryIndex]=new Database(cDevice::PrimaryDevice(), system);         return databases[primaryIndex];      } else         noReceptionDatabases[indexOfPrimary]=true;   }      Database::Ptr db(0);   for (int i=0;i<cDevice::NumDevices();i++) {      if ( (db=getDatabase(i)) ) {         primaryIndex=i;         return db;      }   }   esyslog("Could not find a device which can receive a broadcast");   return 0;}Database::Ptr Database::getDatabase(cDevice *dev) {   checkInitialDatabaseSetup();      for (int i=0;i<cDevice::NumDevices();i++)      if (databases[i] && databases[i]->device==dev)         return databases[i];   DeliverySystem system;   for (int i=0;i<cDevice::NumDevices();i++) {      cDevice  *idev=cDevice::GetDevice(i);      if (idev==dev && !noReceptionDatabases[i]) {         if ((system=getDeliverySystem(idev)) != DeliverySystemNone) {            databases[i]=new Database(idev, system);            return databases[i];         } else            noReceptionDatabases[i]=true;      }   }   return 0;}Database::Ptr Database::getDatabase(int numDevice) {   checkInitialDatabaseSetup();      DeliverySystem system;   cDevice  *idev=cDevice::GetDevice(numDevice);   if (!databases[numDevice] && !noReceptionDatabases[numDevice]) {      if ((system=getDeliverySystem(idev)) != DeliverySystemNone)         databases[numDevice]=new Database(idev, system);      else         noReceptionDatabases[numDevice]=true;   }   return databases[numDevice];}Database::Ptr Database::getDatabaseForChannel(int nid, int tid, int sid, bool shallBeTunedTo, cChannel **chan) {   ReadLock rwlock(&Channels);   std::vector<cChannel *> list;   findChannels(nid, tid, sid, list);      std::vector<cChannel *>::iterator it;   Database::Ptr db(0);   for (it=list.begin(); it != list.end();++it) {      if ( (db=shallBeTunedTo ? getDatabaseTunedForChannel(*it) : getDatabaseForChannel(*it)) )         break;   }      if (chan != 0)      *chan=(*it);   return db;}Database::Ptr Database::getDatabaseForChannel(int source, int nid, int tid, int sid, bool shallBeTunedTo) {   cChannel *channel=0;   ReadLock rwlock(&Channels);         tChannelID cid(source, nid, tid, sid);   channel=Channels.GetByChannelID(cid);      Database::Ptr db= shallBeTunedTo ? getDatabaseTunedForChannel(channel) : getDatabaseForChannel(channel);      return db;}      //to be used with Channels rwlockedDatabase::Ptr Database::getDatabaseForChannel(cChannel *channel) {   if (channel) {      //first try primary database      Database::Ptr db=getPrimaryDatabase();      if (db->device && db->device->ProvidesTransponder(channel))         return db;            //then try created databases      for (int i=0;i<cDevice::NumDevices();i++) {         if ( (db=databases[i]) )            if (db->device && db->device->ProvidesTransponder(channel))               return db;      }            //then try all possibilities      for (int i=0;i<cDevice::NumDevices();i++) {         if ( (db=getDatabase(i)) )            if (db->device && db->device->ProvidesTransponder(channel))               return db;      }   }   return 0;}      //to be used with Channels rwlockedDatabase::Ptr Database::getDatabaseTunedForChannel(cChannel *channel) {   bool needsDetachReceivers;   if (channel) {      //first try primary database      Database::Ptr db=getPrimaryDatabase();      if (db->device && db->device->ProvidesChannel(channel, Setup.PrimaryLimit, &needsDetachReceivers) && !needsDetachReceivers)         return db;            //then try created databases      for (int i=0;i<cDevice::NumDevices();i++) {         if ( (db=databases[i]) )            if (db->device && db->device->ProvidesChannel(channel, Setup.PrimaryLimit, &needsDetachReceivers) && !needsDetachReceivers)               return db;      }            //then try all possibilities      for (int i=0;i<cDevice::NumDevices();i++) {         if ( (db=getDatabase(i)) )            if (db->device && db->device->ProvidesChannel(channel, Setup.PrimaryLimit, &needsDetachReceivers) && !needsDetachReceivers)               return db;      }   }   return 0;}      //to be used with Channels rwlockedvoid Database::findChannels(int nid, int tid, int sid, std::vector<cChannel *> &list) {   ReadLock rwlock(&Channels);      for (cChannel *channel=Channels.First(); channel; channel = Channels.Next(channel)) {      //printf("Channel %s\n", channel->Name());      if (!channel->GroupSep() && channel->Sid()==sid && channel->Tid()==tid && channel->Nid()==nid ) {         printf("Adding channel %p\n", channel);         list.push_back(channel);      }            }   }int Database::getCurrentSource() {   ReadLock rwlock(&Channels);   if (device)      return Channels.GetByNumber(device->CurrentChannel())->Source();   else      return 0;}bool Database::retrievePat(SI::PAT &Pat) {   if (HasState(TuningStatePat)) {      DatabaseLock lock(this);      Pat=pat;      return true;   }   return false;}PMTServicesRequest *Database::retrievePMTServices(Listener *listener, IdTracker *serviceIds, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStatePat))      return 0;   return new PMTServicesRequest(this, listener, serviceIds, mode, appData);}NetworksRequest *Database::retrieveNetworks(Listener *listener, IdTracker *networkIds, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStateChannel))      return 0;   return new NetworksRequest(this, listener, networkIds, mode, appData);}NetworksRequest *Database::retrieveActualNetwork(Listener *listener, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStateChannel))      return 0;   return new NetworksRequest(this, listener, new IdTracker(getNetworkId()), mode, appData);}TransportStreamDescriptionRequest *Database::retrieveTransportStreamDescription(Listener *listener, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStateChannel))      return 0;   return new TransportStreamDescriptionRequest(this, listener, mode, appData);}ActualTransportStreamRequest *Database::retrieveActualTransportStream(Listener *listener, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStatePat))      return 0;   return new ActualTransportStreamRequest(this, listener, mode, appData);}ServiceTableRequest *Database::retrieveServiceTable(Listener *listener, IdTracker *transportStreamIds, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStateChannel))      return 0;   return new ServiceTableRequest(this, listener, transportStreamIds, mode, appData);}PMTElementaryStreamRequest *Database::retrievePMTElementaryStreams(Listener *listener, int serviceId, IdTracker *componentTags, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStatePat))      return 0;   return new PMTElementaryStreamRequest(this, listener, serviceId, componentTags, mode, appData);}EventTableRequest *Database::retrieveEventTable(Listener *listener, bool presentFollowingOrOther,                                                 IdTracker *serviceIds, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStateChannel))      return 0;   return new EventTableRequest(this, listener, presentFollowingOrOther, serviceIds, mode, appData);}EventTableOtherRequest *Database::retrieveEventTableOther(Listener *listener, bool presentFollowingOrOther,                                                 IdTracker *serviceIds, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStateChannel))      return 0;   return new EventTableOtherRequest(this, listener, presentFollowingOrOther, serviceIds, mode, appData);}BouquetsRequest *Database::retrieveBouquets(Listener *listener, IdTracker *bouquetIds, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStateChannel))      return 0;   return new BouquetsRequest(this, listener, bouquetIds, mode, appData);}TDTRequest *Database::retrieveTDT(Listener *listener, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStateChannel))      return 0;   return new TDTRequest(this, listener, mode, appData);}TOTRequest *Database::retrieveTOT(Listener *listener, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStateChannel))      return 0;   return new TOTRequest(this, listener, mode, appData);}ServicesRequest *Database::retrieveServices(Listener *listener, int originalNetworkId, IdTracker *transportStreamIds,                   IdTracker * serviceIds, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStateChannel))      return 0;   return new ServicesRequest(this, listener, originalNetworkId, transportStreamIds, serviceIds, mode, appData);}ActualServicesRequest *Database::retrieveActualServices(Listener *listener, IdTracker *serviceIds, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStatePat))      return 0;   return new ActualServicesRequest(this, listener, serviceIds, mode, appData);}PresentFollowingEventRequest *Database::retrievePresentFollowingEvent(Listener *listener,          int tid, int sid, bool presentOrFollowing, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStatePat))      return 0;   return new PresentFollowingEventRequest(this, listener, tid, sid, presentOrFollowing, mode, appData);}ScheduleEventRequest *Database::retrieveScheduledEvents(Listener *listener,                         int tid, int sid, RetrieveMode mode, void *appData) {   //DatabaseLock lock(this);   cMutexLock lock(&switchMutex);   if (!WaitForDefinedState(TuningStatePat))      return 0;   return new ScheduleEventRequest(this, listener, tid, sid, mode, appData);}void Database::CleanUp() {   delete dispatchThread;   dispatchThread=0;   for (uint i=0;i<databases.size();i++) {      if (databases[i]) {         databases[i]->Stop();         databases[i]=0;      }   }}Database::Database(cDevice *dev, DeliverySystem system)   : patFilter(this), nid(-1), tid(-1), state(TuningStateUnknown), device(dev), deliverySystem(system){   printf("Creating database for device %d\n", dev->DeviceNumber());   //channelMonitor=new ChannelMonitor(this);   //new ChannelMonitor();   //new cStatus;   //patFilter is _not_ attached by its constructor, since at that time this->device is still 0!   Attach(&patFilter);   Add(&patFilter, false); //schedule}