void CpiDeviceUpnp::CheckStillAvailable(CpiDeviceUpnp* aNewLocation) { iLock.Wait(); if (iNewLocation != NULL) { if (iNewLocation->Location() == aNewLocation->Location()) { iLock.Signal(); aNewLocation->iDevice->RemoveRef(); return; } CpiDevice* d = iNewLocation->iDevice; iNewLocation = aNewLocation; iLock.Signal(); d->RemoveRef(); return; } iNewLocation = aNewLocation; XmlFetchManager& xmlFetchManager = iDevice->GetCpStack().XmlFetchManager(); ASSERT(iXmlCheck == NULL); iXmlCheck = xmlFetchManager.Fetch(); Uri* uri = new Uri(iLocation); iDevice->AddRef(); FunctorAsync functor = MakeFunctorAsync(*this, &CpiDeviceUpnp::XmlCheckCompleted); iXmlCheck->CheckContactable(uri, functor); xmlFetchManager.Fetch(iXmlCheck); iLock.Signal(); }
TBool CpiDeviceListUpnp::Update(const Brx& aUdn, const Brx& aLocation, TUint aMaxAge) { if (!IsLocationReachable(aLocation)) { return false; } iLock.Wait(); CpiDevice* device = RefDeviceLocked(aUdn); if (device != NULL) { CpiDeviceUpnp* deviceUpnp = reinterpret_cast<CpiDeviceUpnp*>(device->OwnerData()); if (deviceUpnp->Location() != aLocation) { /* Device appears to have moved to a new location. Ask it to check whether the old location is still contactable. If it is, stick with the older location; if it isn't, remove the old device and add a new one. */ iLock.Signal(); CpiDeviceUpnp* newDevice = new CpiDeviceUpnp(iCpStack, aUdn, aLocation, aMaxAge, *this, *this); deviceUpnp->CheckStillAvailable(newDevice); device->RemoveRef(); return true; } deviceUpnp->UpdateMaxAge(aMaxAge); iLock.Signal(); device->RemoveRef(); return !iRefreshing; } iLock.Signal(); return false; }
CpDeviceCpp::CpDeviceCpp(CpiDevice& aDevice) : iDevice(aDevice) , iUdn((const char*)aDevice.Udn().Ptr(), aDevice.Udn().Bytes()) , iRefCount(1) { iDevice.AddRef(); }
TBool CpiDeviceListUpnp::Update(const Brx& aUdn, TUint aMaxAge) { AutoMutex a(iLock); CpiDevice* device = RefDeviceLocked(aUdn); if (device != NULL) { reinterpret_cast<CpiDeviceUpnp*>(device->OwnerData())->UpdateMaxAge(aMaxAge); device->RemoveRef(); return !iRefreshing; } return false; }
CpiService::CpiService(const TChar* aDomain, const TChar* aName, TUint aVersion, CpiDevice& aDevice) : Service(aDevice.GetCpStack().Env(), aDomain, aName, aDevice.Version(aDomain, aName, aVersion)) , iDevice(aDevice) , iLock("SRVM") , iPendingInvocations(0) , iShutdownSignal("SRVS", 0) , iInterrupt(false) , iSubscription(NULL) { iDevice.AddRef(); iDevice.GetCpStack().Env().AddObject(this); if (aVersion != iServiceType.Version()) { const Brx& serviceName = iServiceType.FullName(); const Brx& udn = iDevice.Udn(); LOG(kService, "CpiService: addr=%p, serviceType=%.*s, device=%.*s, proxy: v%u, device: v%u\n", this, PBUF(serviceName), PBUF(udn), aVersion, iServiceType.Version()); } }
void CpDeviceList::Removed(CpiDevice& aDevice) { Brn udn(aDevice.Udn()); Map::iterator it = iMap.find(udn); if (it != iMap.end()) { CpDevice* device = it->second; iRemoved(*device); device->RemoveRef(); iMap.erase(it); } }
CpiService::CpiService(const TChar* aDomain, const TChar* aName, TUint aVersion, CpiDevice& aDevice) : Service(aDevice.GetCpStack().Env(), aDomain, aName, aVersion) , iDevice(aDevice) , iLock("SRVM") , iPendingInvocations(0) , iShutdownSignal("SRVS", 0) , iInterrupt(false) , iSubscription(NULL) { iDevice.AddRef(); iDevice.GetCpStack().Env().AddObject(this); }
CpiDeviceListUpnp::~CpiDeviceListUpnp() { TUint xmlWaitCount = 0; iLock.Wait(); iActive = false; iLock.Signal(); Stack::NetworkInterfaceList().RemoveCurrentChangeListener(iInterfaceChangeListenerId); Stack::NetworkInterfaceList().RemoveSubnetChangeListener(iSubnetChangeListenerId); if (iMulticastListener != NULL) { iMulticastListener->RemoveNotifyHandler(iNotifyHandlerId); Stack::MulticastListenerRelease(iInterface); } delete iUnicastListener; iXmlFetchLock.Wait(); iLock.Wait(); Map::iterator it = iMap.begin(); while (it != iMap.end()) { CpiDevice* device = reinterpret_cast<CpiDevice*>(it->second); if (!device->IsReady()) { reinterpret_cast<CpiDeviceUpnp*>(device->OwnerData())->InterruptXmlFetch(); xmlWaitCount++; } it++; } iXmlFetchSem.Clear(); iLock.Signal(); iXmlFetchLock.Signal(); while (xmlWaitCount > 0) { iXmlFetchSem.Wait(); xmlWaitCount--; } iXmlFetchLock.Wait(); // XmlFetchCompleted will signal iXmlFetchSem. // Ensure it gets to exit before we complete the dtor and delete iXmlFetchLock which it holds iXmlFetchLock.Signal(); delete iRefreshTimer; }
TBool CpiDeviceListUpnp::Update(const Brx& aUdn, const Brx& aLocation, TUint aMaxAge) { if (!IsLocationReachable(aLocation)) { return false; } iLock.Wait(); iCpStack.Env().Mutex().Wait(); if (iRefreshing && iPendingRefreshCount > 1) { // we need at most one final msearch once a network card starts working following an adapter change iPendingRefreshCount = 1; } iCpStack.Env().Mutex().Signal(); CpiDevice* device = RefDeviceLocked(aUdn); if (device != NULL) { CpiDeviceUpnp* deviceUpnp = reinterpret_cast<CpiDeviceUpnp*>(device->OwnerData()); if (deviceUpnp->Location() != aLocation) { // device appears to have moved to a new location. // Remove the old record, leaving the caller to add the new one. iLock.Signal(); Remove(aUdn); device->RemoveRef(); return false; } deviceUpnp->UpdateMaxAge(aMaxAge); device->RemoveRef(); iLock.Signal(); LOG(kTrace, "Device alive {udn{"); LOG(kTrace, aUdn); LOG(kTrace, "}, location{"); LOG(kTrace, aLocation); LOG(kTrace, "}}\n"); return !iRefreshing; } iLock.Signal(); return false; }
CpiSubscription::CpiSubscription(CpiDevice& aDevice, IEventProcessor& aEventProcessor, const OpenHome::Net::ServiceType& aServiceType) : iLock("SUBM") , iSubscriberLock("SBM2") , iDevice(aDevice) , iEventProcessor(&aEventProcessor) , iServiceType(aServiceType) , iPendingOperation(eNone) , iRefCount(1) , iInterruptHandler(NULL) { iTimer = new Timer(aDevice.GetCpStack().Env(), MakeFunctor(*this, &CpiSubscription::Renew)); iDevice.AddRef(); iRejectFutureOperations = false; Schedule(eSubscribe); iDevice.GetCpStack().Env().AddObject(this); }
TBool CpiDeviceListUpnp::IsDeviceReady(CpiDevice& aDevice) { reinterpret_cast<CpiDeviceUpnp*>(aDevice.OwnerData())->FetchXml(); return false; }