void CpiDeviceListUpnp::HandleInterfaceChange(TBool aNewSubnet) { NetworkInterface* current = Stack::NetworkInterfaceList().CurrentInterface(); iLock.Wait(); delete iUnicastListener; iUnicastListener = NULL; if (iMulticastListener != NULL) { iMulticastListener->RemoveNotifyHandler(iNotifyHandlerId); iNotifyHandlerId = 0; Stack::MulticastListenerRelease(iInterface); iMulticastListener = NULL; } if (current == NULL) { iInterface = 0; RemoveAll(); iLock.Signal(); return; } iInterface = current->Address(); delete current; if (aNewSubnet) { RemoveAll(); } iUnicastListener = new SsdpListenerUnicast(*this, iInterface); iUnicastListener->Start(); iMulticastListener = &Stack::MulticastListenerClaim(iInterface); iNotifyHandlerId = iMulticastListener->AddNotifyHandler(this); iLock.Signal(); Refresh(); }
CpiDeviceListUpnp::CpiDeviceListUpnp(FunctorCpiDevice aAdded, FunctorCpiDevice aRemoved) : CpiDeviceList(aAdded, aRemoved) , iStarted(false) , iXmlFetchSem("DRLS", 0) , iXmlFetchLock("DRLM") { NetworkInterfaceList& ifList = Stack::NetworkInterfaceList(); NetworkInterface* current = ifList.CurrentInterface(); iRefreshTimer = new Timer(MakeFunctor(*this, &CpiDeviceListUpnp::RefreshTimerComplete)); iInterfaceChangeListenerId = ifList.AddCurrentChangeListener(MakeFunctor(*this, &CpiDeviceListUpnp::CurrentNetworkInterfaceChanged)); iSubnetChangeListenerId = ifList.AddSubnetChangeListener(MakeFunctor(*this, &CpiDeviceListUpnp::SubnetChanged)); if (current == NULL) { iInterface = 0; iUnicastListener = NULL; iMulticastListener = NULL; iNotifyHandlerId = 0; } else { iInterface = current->Address(); iUnicastListener = new SsdpListenerUnicast(*this, iInterface); iMulticastListener = &Stack::MulticastListenerClaim(iInterface); iNotifyHandlerId = iMulticastListener->AddNotifyHandler(this); delete current; } }
static void RandomiseUdn(Bwh& aUdn) { aUdn.Grow(aUdn.Bytes() + 1 + Ascii::kMaxUintStringBytes + 1); aUdn.Append('-'); Bws<Ascii::kMaxUintStringBytes> buf; NetworkInterface* nif = Stack::NetworkInterfaceList().CurrentInterface(); TUint max = nif->Address(); delete nif; (void)Ascii::AppendDec(buf, Random(max)); aUdn.Append(buf); aUdn.PtrZ(); }
TBool CpiDeviceListUpnp::IsLocationReachable(const Brx& aLocation) const { /* linux's filtering of multicast messages appears to be buggy and messages received by all interfaces are sometimes delivered to sockets which are bound to / members of a group on a single (different) interface. It'd be more correct to filter these out in SsdpListenerMulticast but that would require API changes which would be more inconvenient than just moving the filtering here. This should be reconsidered if we ever add more clients of SsdpListenerMulticast */ TBool reachable = false; Uri uri(aLocation); iLock.Wait(); Endpoint endpt(0, uri.Host()); NetworkInterface* nif = Stack::NetworkInterfaceList().CurrentInterface(); if (nif->Address() == iInterface && nif->ContainsAddress(endpt.Address())) { reachable = true; } delete nif; iLock.Signal(); return reachable; }
Soundcard::Soundcard(TIpAddress /* aSubnet */, TUint aChannel, TUint aTtl, TBool aMulticast, TBool aEnabled, TUint aPreset, ReceiverCallback aReceiverCallback, void* aReceiverPtr) : iReceiverCallback(aReceiverCallback) , iReceiverPtr(aReceiverPtr) { InitialisationParams* initParams = InitialisationParams::Create(); UpnpLibrary::Initialise(initParams); std::vector<NetworkInterface*>* list = UpnpLibrary::SubnetList(); ASSERT(list->size() > 0); NetworkInterface* iface = *list->begin(); delete (list); UpnpLibrary::SetCurrentSubnet(*iface); printf("Using %x\n", iface->Address()); UpnpLibrary::StartCombined(); Bws<kMaxUdnBytes> computer; Bws<kMaxUdnBytes> udn; Bws<kMaxUdnBytes + 1> friendly; TUint bytes = computer.MaxBytes(); if (!GetComputerName((LPSTR)computer.Ptr(), (LPDWORD)&bytes)) { THROW(SoundcardError); } computer.SetBytes(bytes); udn.Replace("ohSoundcard-"); udn.Append(computer); friendly.Replace(udn); friendly.Append('\0'); iDevice = new DvDeviceStandard(udn); iDevice->SetAttribute("Upnp.Domain", "av.openhome.org"); iDevice->SetAttribute("Upnp.Type", "Soundcard"); iDevice->SetAttribute("Upnp.Version", "1"); iDevice->SetAttribute("Upnp.FriendlyName", (TChar*)friendly.Ptr()); iDevice->SetAttribute("Upnp.Manufacturer", "Openhome"); iDevice->SetAttribute("Upnp.ManufacturerUrl", "http://www.openhome.org"); iDevice->SetAttribute("Upnp.ModelDescription", "OpenHome Soundcard"); iDevice->SetAttribute("Upnp.ModelName", "ohSoundcard"); iDevice->SetAttribute("Upnp.ModelNumber", "1"); iDevice->SetAttribute("Upnp.ModelUrl", "http://www.openhome.org"); iDevice->SetAttribute("Upnp.SerialNumber", ""); iDevice->SetAttribute("Upnp.Upc", ""); iDriver = new OhmSenderDriverWindows(); Brn icon(icon_png, icon_png_len); iSender = new OhmSender(*iDevice, *iDriver, computer, aChannel, iface->Address(), aTtl, aMulticast, aEnabled, icon, Brn("image/png"), aPreset); iDevice->SetEnabled(); iReceiverManager = new ReceiverManager3(*this, iSender->SenderUri(), iSender->SenderMetadata()); }