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; try { uri.Replace(aLocation); } catch (UriError&) { return false; } iLock.Wait(); Endpoint endpt(0, uri.Host()); NetworkAdapter* nif = iCpStack.Env().NetworkAdapterList().CurrentAdapter("CpiDeviceListUpnp::IsLocationReachable"); if (nif != NULL) { if (nif->Address() == iInterface && nif->ContainsAddress(endpt.Address())) { reachable = true; } nif->RemoveRef("CpiDeviceListUpnp::IsLocationReachable"); } iLock.Signal(); return reachable; }
void InvocationUpnp::WriteRequest(const Uri& aUri) { Sws<1024> writeBuffer(iSocket); WriterHttpRequest writerRequest(writeBuffer); Bwh body; try { Endpoint endpoint(aUri.Port(), aUri.Host()); TUint timeout = iCpStack.Env().InitParams()->TcpConnectTimeoutMs(); iSocket.Connect(endpoint, timeout); } catch (NetworkTimeout&) { iInvocation.SetError(Error::eSocket, Error::eCodeTimeout, Error::kDescriptionSocketTimeout); THROW(NetworkTimeout); } try { InvocationBodyWriter::Write(iInvocation, body); WriteHeaders(writerRequest, aUri, body.Bytes()); writeBuffer.Write(body); writeBuffer.WriteFlush(); } catch (WriterError) { iInvocation.SetError(Error::eHttp, Error::kCodeUnknown, Error::kDescriptionUnknown); THROW(WriterError); } }
void Http::WriteHeaderHostAndPort(WriterHttpHeader& aWriter, const Uri& aUri) { IWriterAscii& writer = aWriter.WriteHeaderField(Http::kHeaderHost); writer.Write(aUri.Host()); writer.Write(':'); writer.WriteUint(aUri.Port()); writer.WriteNewline(); }
void CpiDeviceUpnp::GetServiceUri(Uri& aUri, const TChar* aType, const ServiceType& aServiceType) { Brn root = XmlParserBasic::Find("root", iXml); Brn device = XmlParserBasic::Find("device", root); Brn udn = XmlParserBasic::Find("UDN", device); if (!CpiDeviceUpnp::UdnMatches(udn, Udn())) { Brn deviceList = XmlParserBasic::Find("deviceList", device); do { Brn remaining; device.Set(XmlParserBasic::Find("device", deviceList, remaining)); udn.Set(XmlParserBasic::Find("UDN", device)); deviceList.Set(remaining); } while (!CpiDeviceUpnp::UdnMatches(udn, Udn())); } Brn serviceList = XmlParserBasic::Find("serviceList", device); Brn service; Brn serviceType; Brn devServiceTypeNoVer; const Brx& targServiceType = aServiceType.FullName(); // Must have backwards compatibility. Need to compare service type and version separately. Parser serviceParser = targServiceType; serviceParser.Next(':'); // urn serviceParser.Next(':'); // schema url serviceParser.Next(':'); // service serviceParser.Next(':'); // name Brn targServiceTypeNoVer(targServiceType.Ptr(), serviceParser.Index()); // full name minus ":x" (where x is version) do { Brn remaining; service.Set(XmlParserBasic::Find("service", serviceList, remaining)); serviceType.Set(XmlParserBasic::Find("serviceType", service)); serviceList.Set(remaining); // Parse service type and version separately. serviceParser.Set(serviceType); serviceParser.Next(':'); // urn serviceParser.Next(':'); // schema url serviceParser.Next(':'); // service serviceParser.Next(':'); // name devServiceTypeNoVer.Set(serviceType.Ptr(), serviceParser.Index()); // full name minus ":x" (where x is version) // MUST allow use of device with version >= target version } while (devServiceTypeNoVer != targServiceTypeNoVer); Brn path = XmlParserBasic::Find(aType, service); if (path.Bytes() == 0) { // no event url => service doesn't have any evented state variables THROW(XmlError); } // now create a uri using the scheme/host/port of the device xml location // plus the path we've just constructed Bws<40> base; // just need space for http://xxx.xxx.xxx.xxx:xxxxx aUri.Replace(iLocation); base.Append(aUri.Scheme()); base.Append("://"); base.Append(aUri.Host()); base.Append(':'); Ascii::AppendDec(base, aUri.Port()); aUri.Replace(base, path); }
void EventUpnp::Unsubscribe(const Uri& aPublisher, const Brx& aSid) { iSocket.Open(iCpStack.Env()); Endpoint endpoint(aPublisher.Port(), aPublisher.Host()); TUint timeout = iCpStack.Env().InitParams()->TcpConnectTimeoutMs(); iSocket.Connect(endpoint, timeout); UnsubscribeWriteRequest(aPublisher, aSid); UnsubscribeReadResponse(); }
void EventUpnp::Subscribe(const Uri& aPublisher, const Uri& aSubscriber, TUint& aDurationSecs) { iSocket.Open(iCpStack.Env()); iSubscription.SetInterruptHandler(this); Endpoint endpoint(aPublisher.Port(), aPublisher.Host()); TUint timeout = iCpStack.Env().InitParams()->TcpConnectTimeoutMs(); iSocket.Connect(endpoint, timeout); SubscribeWriteRequest(aPublisher, aSubscriber, aDurationSecs); Brh sid; SubscribeReadResponse(sid, aDurationSecs); iSubscription.SetSid(sid); }
void EventUpnp::RenewSubscription(const Uri& aPublisher, TUint& aDurationSecs) { iSocket.Open(iCpStack.Env()); iSubscription.SetInterruptHandler(this); Endpoint endpoint(aPublisher.Port(), aPublisher.Host()); TUint timeout = iCpStack.Env().InitParams()->TcpConnectTimeoutMs(); iSocket.Connect(endpoint, timeout); RenewSubscriptionWriteRequest(aPublisher, aDurationSecs); Brh tmp; SubscribeReadResponse(tmp, aDurationSecs); if (tmp != iSubscription.Sid()) { THROW(HttpError); } }
void CpiDeviceUpnp::GetServiceUri(Uri& aUri, const TChar* aType, const ServiceType& aServiceType) { Brn root = XmlParserBasic::Find("root", iXml); Brn device = XmlParserBasic::Find("device", root); Brn udn = XmlParserBasic::Find("UDN", device); if (!CpiDeviceUpnp::UdnMatches(udn, Udn())) { Brn deviceList = XmlParserBasic::Find("deviceList", device); do { Brn remaining; device.Set(XmlParserBasic::Find("device", deviceList, remaining)); udn.Set(XmlParserBasic::Find("UDN", device)); deviceList.Set(remaining); } while (!CpiDeviceUpnp::UdnMatches(udn, Udn())); } Brn serviceList = XmlParserBasic::Find("serviceList", device); Brn service; Brn serviceType; const Brx& targServiceType = aServiceType.FullName(); do { Brn remaining; service.Set(XmlParserBasic::Find("service", serviceList, remaining)); serviceType.Set(XmlParserBasic::Find("serviceType", service)); serviceList.Set(remaining); } while (serviceType != targServiceType); Brn path = XmlParserBasic::Find(aType, service); if (path.Bytes() == 0) { // no event url => service doesn't have any evented state variables THROW(XmlError); } // now create a uri using the scheme/host/port of the device xml location // plus the path we've just constructed Bws<40> base; // just need space for http://xxx.xxx.xxx.xxx:xxxxx aUri.Replace(iLocation); base.Append(aUri.Scheme()); base.Append("://"); base.Append(aUri.Host()); base.Append(':'); Ascii::AppendDec(base, aUri.Port()); aUri.Replace(base, path); }
EndpointHttp::EndpointHttp(const Uri& aUri) { SetAddress(aUri.Host()); SetPort(aUri.Port() == -1 ? 80 : aUri.Port()); }
void Http::WriteHeaderHost(WriterHttpHeader& aWriter, const Uri& aUri) { aWriter.WriteHeader(Http::kHeaderHost, aUri.Host()); }