Yortw / RSSDP

Really Simple Service Discovery Protocol - a 100% .Net implementation of the SSDP protocol for publishing custom/basic devices, and discovering all device types on a network.

Home Page:http://yortw.github.io/RSSDP/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Possible to default Location to something automatically?

ronnyek opened this issue · comments

First of all this stuff works pretty well I must say.

I know this might be that the specs are just this way, but the way I want to use the SsdpPublisher, is a bit more dynamic than those examples. Ideally I'd fire this app up on my hardware, and have it use public ip for the location url plus some route postfix. The problem is I don't necessarily know ahead of time what that might be. (didnt know if there was a way within the library to say when we get an inbound request we might be able to determine what ip it came into or something).

Also, if I'm building out a device definition to publish, is there a way I can get a xml file from that?

Hi,

Thanks for letting me know the lib is working well for you, always nice to hear when someone succeeds.

I'm not 100% sure what you're asking, but I don't think the SSDP was really designed with what you want in mind. It might still be possible in theory, but RSSDP probably doesn't support it as it is. Let me clarify.

The commercial app I work on for my day job using RSSDP to expose itself as a server to mobile devices, without needing the users to enter IP addresses etc. The address it publishes itself on can be provided by explicit configuration, but usually isn't. Instead the app checks for network adapters that are 'connected', have an IPv4 address that isn't in the self assigned range, and are of type WiFi or Ethernet (not a WAN or VPN), and a bunch of heuristics like that. Normally there is only one relevant adapter once we apply all the filters. The app then creates an SsdpRootDevice instance from a mix of hardcoded values (device type etc), configuration (device id, serial # etc), and the IP address of the adapter it's decided to publish on. Then it starts a publisher and adds the device instance.

Following that the app monitors the adapter/assigned IP using standard .Net/Windows APIs. If the adapter disconnects or the IP address changes then it disposes the publisher, which sends out a notification to proxies/clients that the server has gone away. If the adapter reconnects or a new address was assigned, then it creates a new root device instance (using the new address, but otherwise the same as the previous instance), and a new publisher, and then starts publishing again. This sends out the alive notification to clients telling them where a new instance is, without requiring them to know they have to search again.

So in that way, yes, you can use the library with a 'dynamic' address. Currently if you want to publish on multiple adapters, you'd do the same thing but monitor each adapter/address and have a separate publisher for each. You don't need to know ahead of time what the address is, you detect it when your app/device/server starts and then send out changes if the address changes.

I'm not sure that's what you want to do though? You said;

if there was a way within the library to say when we get an inbound request we might be able to determine what ip it came into

This is where things get messy. First, there isn't really an address that anything came in on. Notifications are sent on an event (start/stop), and on a randomised timer period. In those cases there is no incoming packet, so no address in came in through.

Lets assume you don't care about notifications (could disable them) and just wanted to respond to m-search requests. The search requests themselves are sent to a common multicast IP address and port (always the same address/port), so the address you received the request at isn't useful. I guess you could get the address of the client that made the request and then see if you can match that back to one of your own adapters (by subnet maybe?), then use that adapter's address. I'm not sure how you'd accurately match in detail though, or if it there would always be a match to be made. Possibly you could know which adapter the packet came in on, and then just use its address - that would be most accurate, but I'm not sure exactly how you'd do that (it's been a while since I worked with the networking APIs).

In any case, RSSDP doesn't support this. Because of the notifications, and because the address usually ends up in the device description document as well, you have to specify the url for the document (which includes the address) before publishing the device. The spec requires the address the document is published on be the same as the address in the notifications (though most clients don't actually seem to care), which is why RSSDP uses a separate publisher and device instance per adapter. Technically RSSDP could be modified so the url provided was a template, and the address inserted at runtime when the search responses are sent. However it wasn't designed for that and I'm not particularly keen to make that change because of the notifications. SSDP is really a notification based system, with the search implemented so the notifications don't have to be sent on a very short interval (like every second) to handle clients (re)starting at different times.

Also, if I'm building out a device definition to publish, is there a way I can get a xml file from that?

Yes. Create an SsdpRootDevice instance and set the properties on it to the values you want in the xml. Once done, call the ToDescriptionDocument method and it will generate the required XML and return it as a string.

You can also create a Upnp10DeviceValidator instance and pass in your root device instance, it will tell you if you've missed a required property or set an invalid value.

Understood, I can make do with the addressing ideas you threw out there, and I missed the .ToDescriptionDocument(). I appreciate it.

Thanks for closing the issue. Good luck :)