예제 #1
0
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();
}
예제 #2
0
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;
}
예제 #3
0
CpDeviceCpp::CpDeviceCpp(CpiDevice& aDevice)
    : iDevice(aDevice)
    , iUdn((const char*)aDevice.Udn().Ptr(), aDevice.Udn().Bytes())
    , iRefCount(1)
{
    iDevice.AddRef();
}
예제 #4
0
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;
}
예제 #5
0
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());
    }
}
예제 #6
0
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);
    }
}
예제 #7
0
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);
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
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);
}
예제 #11
0
TBool CpiDeviceListUpnp::IsDeviceReady(CpiDevice& aDevice)
{
    reinterpret_cast<CpiDeviceUpnp*>(aDevice.OwnerData())->FetchXml();
    return false;
}