Aug 28, 2012 at 7:20 PM
Edited Aug 28, 2012 at 7:21 PM
Basically, I am aware that we are able to use some or many parts of the .NET Framework by creating a wrapper around it (COM Wrapper) so the wrapper becomes like an interface or a gateway to allow you to communicate with a particular part of the .NET Framework
using a typical Visual Basic 6 (VB6) application, as long as you reference this COM Wrapper that you've created in your VB6 Project Properties. This idea is called Visual Basic Fusion (fusing .NET with VB6).
Based on this, I was wondering and have wanted to know if this would be possible to do with ManagedUPnP? I don't see why it wouldn't be possible, but I'm just curious to see if anyone here has talked about it or considered it, since the creation of the Wrapper
COM Library is pretty much an automated process, this doesn't really require any work or re-coding on the developers part or even the users part.
I would love to hear people's opinion on this (and please, no flames re me using VB6 - I use .NET whenever I can but you know how it is, some applications are still being developed in VB6).
Aug 28, 2012 at 11:26 PM
Edited Aug 28, 2012 at 11:28 PM
Thankyou for posting your idea.
Yes, this would definitely be possible, however i'm wondering if there would be a lot of point to it, this is because Managed UPnP is a wrapper around the Microsoft UPnP Endpoint COM Objects (along with its own code). So you would end up with this sort of
UPnP COM Objects -> Managed UPnP -> Wrapper COM Objects -> VB6
Although there is no problem with this, and it would certainly work, as you can see you would simply be wrapping it back to COM Objects.
Instead I would suggest that you grab the source code to Managed UPnP and re-write it in native VB6 using the COM Objects directly, you wouldnt need to convert it all (you can exclude the code generation and descriptions namespace).
Just my 2c :)
Sep 1, 2012 at 5:41 PM
Edited Sep 1, 2012 at 5:47 PM
Thank you for your response, and I understand what you are saying (makes a lot of sense). I would like to add a few things to this though.
I have been using the upnp.dll Com Object for some time now, and I can assure you it's been a pain to work with, especially in VB6 because it does not support some of the datatypes that are required (used) by the upnp.dll file.
I've had to generate (view) the Type Library of upnp.dll (using oleview.exe) and then I've had to change all Unsigned Long's to Long's because VB6 doesn't support any unsigned types (except for the Byte type, which is the only unsigned variable in VB6, for
values between 0 and 255 only, not much use). Then, I've had to recompile the new TypeLib (with the 'Unsigned' words removed) and register the new .tbl on my machine. This solves some problems, but then there were more datatype problems that were not fixable
by altering the TypeLib, and I had to resort to the CopyMemory function (imported) to mess with the UI4 and UI2 (unsigned 4 byte and 2 byte integers) variables straight in the applications memory... (if anyone's curious, it was solved here):
Then, there are just these mysterious problems and error numbers that come up, it doesn't even tell you what the problem is, and even a google search on the error numbers turns out (usually) blank, because it's such a rarely used component. Just to give
you an example, under WanIPConnection Service, I can only read 3 out of 17 of the state variables. Every other variable returns this error number -2147220972 (80040214) with the generic "failed" description message. If you search google for -2147220972
there are no hits, if you remove the - sign, there are several but all pointing to different meanings, and if you put the word upnp next to it you get 0 hits! Now, if you search for "80040214 upnp" (without the quotes, of course) you get a wopping
8 hits, and that's almost entirely users running into errors using UPnP enabled software and copying/pasting their error logs. It isn't programmers reporting the error numbers and asking for help and receiving solutions or answers (would have been great).
When I go on stackoverflow to speak to others, no one's really used this dll and cannot provide help from a UPnP perspective (only from a Com perspective). If you have happened to come across this error or have it in your constant's list, I would love to know
what it means.
I'm not sure what the deal is with Delphi programmers, or other non-.NET Win32 programing languages (if they have similar problems or even just a subset of the problems I have), but I have been thinking that the only real solution to my problem is to either
solve all these problems (and most of them I have) or to use a library where people have already solved these problems (I'm not sure how you guys have done it, but I'm impressed). So, I'm not sure if it's just me, or if upnp.dll is just poorly coded or designed.
My area of expertise (one thing I can say I know inside out) is microsofts WebBrowser Control, not sure if you've ever used it, very very useful control, but terrible design and implementation. My point being, microsoft seems to design their pipework terribly,
provide little to no documentation and expect people to just figure things out (sort of understandable since these things are not part of a Programmers Framework and mainly built for them to use). I'm guessing you guys wrote this because upnp.dll is so poor
in its design? I noticed that UPnP doesn't exist in the .NET Framework, not even a wrapper.
My understanding is that you've dramatically improved the usefulness and user-friendliness of the upnp.dll with your wrapper, and for this reason, it might be worth while for some people to over-wrap it, while keeping in mind and understanding/noticing that
they are over-wrapping something, and recognizing that performance will take a small hit, etc. What are your thoughts? Do you think the increase in quality of your wrapper makes it worth over-wrapping?
Thanks for listening and excuse my rambling, you have no idea how rare it is to find someone on the internet that speaks UPnP lol (really really rare).
Sep 1, 2012 at 11:20 PM
Edited Sep 1, 2012 at 11:29 PM
Thats unfortunate that VB6 dosnt support longer unsigned data types, i had actually forgotten about that (its been quite a while since my VB6 days). And you are right, it might be easier to write a COM object wrapper around the objects in Managed UPnP.
Just to let you know that a LOT of UPnP devices will report error 80040214 ( Constant UPNP_E_DEVICE_ERROR = 0x80040214 - Generic UPnP error reported by device ) - (you can test this using the sample application that comes with my framework) when
querying most state variables, this is because originally the UPnP standard stated that the state variables were to be used to query and retrieve quick information. However, later on, the UPnP standard changed and now state variables are really only mostly
used to just DESCRIBE the parameters for the actions (meaning restrictions - range, grain, possible values). Because of this, a lot of the state variables that are on devices are ONLY there to describe action patameters and therefore will return error number 80040214
when queried or attached to for events.
No other language I have used has the problems with the signed values, delphi has a rich set of data types just like other languages (Except VB6 unfortunately). UPnP.DLL is poorly coded thats for sure, for starters there are numerous bugs relating to the
URLs sent in the XML from the devices with UPnP.DLL where it will not build relative URLs properly, this creates a gross incompatibility with a lot of UPnP devices unless you build the URL your self (which my Managed UPnP framework does do). There are other
problems with it as well including problems with multi-threaded apartment applications and using the objects returned by the asynchronous searching methods within UPnP.DLL. However, it should be noted that the implementation of UPnP.DLL in Windows 7 (and even
Windows Vista to a point) is much better than the implementation under Windows XP.
Not sure why they didn't include an implementation in the .NET framework for the UPnP.DLL, but I suspect as you said its due to the bad implementation. The Managed UPnP framework does definitely improve on the implementation in UPnP.DLL significantly and
due to your problems with the VB6 data-types it may be worth it to write a COM compatible wrapper for use in VB6.
However, it would also be possible to write a normal Win32 or Win64 DLL in C++ or delphi to expose the UPnP.DLL only using compatible VB6 data types. Then you can use the interop functions in VB to call these methods, this would be a much more direct
and lighter option but would require building all of the smarts of Managed UPnP into the new interop DLL.
Basically the interop DLL would use HANDLES (which are actually memory pointer locations to the underlying COM objects) and call flat API functions within the interop DLL which map either directly or indirectly to the COM objects methods and properties.
Essentially you would be flattening the COM UPnP.DLL implementation into procedures using Handle Identifiers and only using compatible VB6 datatypes, these then would be converted internally by the interop DLL and pass to the UPnP.DLL COM objects.
Which ever way you want to do it im sure it would work and the performance hit, as you said, should be quite small.
I have noticed that UPnP is not a popular topic, im not sure why, seen as how so many technologies these days are based on it (DLNA being one example), Let me know what you decide to do :)
Sep 22, 2012 at 12:51 PM
Edited Sep 22, 2012 at 4:13 PM
[The following response was re-edited, to increase readability and flow, on the day following the original post date (Aus-EST).]
Hey thetoid, thanks for your detailed response.
I was quite amazed by the point you've made, that essentially the vendors are deliberately not implementing the State Variables because
the UPNP Service Design has decided to obscure State Variables overtime. I had read they were trying to phase them out, but I hadn't realized that the vendors were actually phasing them out as yet. I noticed that some vendors return state variables that other
vendors don't, and vice versa. In my testing, with WANIPConnection, there are 17 state variables, and sometimes 4 of them return data, and with another vendor, i think 8 of them return data. With WANPPPConnection, its 19 state variables, with I think an extra
one or two returning data, depending on the vendor. So, basically, they are saying, use the Action Methods instead to get this data. Is this correct? (I'm just trying to confirm that my understanding is correct, or if I've missed something).
Basically, I am working on an interface for people to be able to get in and alter data on their UPNP devices; however, I am also writing
a feature that I think will be useful to several people. This feature would allow you to change your IP address as quickly as possible (all of this will be 100% freeware). To do this, I am trying to use RequestConnection, and I will try to use it on WanPPPConnection
first, and if it fails, then I will try to use it on WanIPConnection. Now, if they both fail, I attempt to do a ForceTermination. After the ForceTermination, I wait until the internet connection has disconnected or my loop times out), once either of these
have happened, I attempt to do a RequestConnection again. I do this ForceTermination & RequestConnection method on both services, so the 3rd overall attempt would be on the WanPPP, and if that doesn't work, the 4th overall attempt would be on the WanIP.
So FT is attempted before RQ on both 3rd and 4th attempts. The 1st & 2nd attempts don't do FT, but just an RC each. I noticed this is the fastest way to change an IP address (assuming user isn't on a static IP), so this is the set of things I try first.
One thing I’d be interested in finding out is, what percentage of devices do you think RequestConnection works on? Because I noticed
on some devices, it does nothing. Also, if you think any of my methods mentioned herein are a waste of time or just bad/unnecessary logic, feel free to let me know.
Now, if none of that works, I know there is another way to reconnect the device, but I am not sure how to use it. I believe there is
a RebootAP (and a RebootSTA) Action Method in the urn:wifialliance-org:serviceId:WFAWLANConfig1 service, but after having scrolled through Google and even the design/service documents on WFAWLANConfig, I was unable to decipher the usage of these Actions. The
service documents, although normally barely-understandable, kept referring to the argument that needs to be sent as a "Message" (NewAPSettings) without specifying what that message needs to contain (in terms of exact text), it's almost as though
they deliberately sounds more vague in the hopes that they will seem more professional (have you read an RFC before? OMG LOL). You're supposed to be able to get APSetting from the State Variable, but that isn't available either (as in, it won't return data).
Otherwise, I would just get what is in APSetting and use it as the one and only argument for RebootAP.
The only clue I have was a tweet sent by a random person somewhere on the interwebs, where he mentions sending a command "RebootAP
10.0.0.1" - now, I'm not sure if that is a pure UPNP command that he is sending, or a command to something that is a wrapper around the UPNP service. If it's a wrapper, the wrapper probably only needs to know which AP to reboot, which would make sense
if he is a sys-admin who has many AP's. I'm guessing the wrapper would probably determine the one and only argument it needs to send (NewAPSettings) to the RebootAP Action (that being, not "10.0.0.1") on the specified AP (10.0.0.1), and he'll get
his reboot. Now, my only question about RebootAP is - what is the text/argument that needs to be sent? Is it the actual IP address or something else? Because I have tried so many things and nothing has worked for me.
If you have any ideas, or other methods by which one can change their IP address (or, that I can do programmatically), I would love to
hear them. Of course, the order of importance is whichever the quickest method is, I would go for that first, however, in case the quickest method doesn't work, I would try the next quickest method, and if that does not work, I would try the following quickest
method. In fact, I am willing to program up to 6 or 7 different methods for redundancy (to ensure that at least one works). I know there probably won't be 6 or 7 ways, but I'm just trying to describe my enthusiasm as far as this problem is concerned. I understand
rebooting the router would probably be the slowest method, but I haven't even figured out how to do that yet.
So my question to you is, if you know of anything off the top of your head, anything relating to RebootAP/RebootSTA, or any OTHER method
that you know of that I haven't mentioned herein. Feel free to let me know or provide a lead, and I will research it until there is nothing left to research (and report back if you are interested). The more methods I can put together, the better the outcome.
Even if you or anyone know of methods outside the whole router world, that would also be worth mentioning. As my users will just be random Windows Users, who are on average more tech savvy than most given that they'll be downloading UPNP software, I'm mainly
putting all my work into UPNP/Router based IP changing because I'm assuming most people use a router to connect to the internet (and since UPNP is enabled by default now ways, it’s the most productive place to target right now). If anyone knows the %
of people on routers and % of people on other connection types, feel free to include that in a response, what do you think is the 2nd or 3rd most commonly used connection type apart from a UPNP enabled router in the United States? Depending on what these are,
I can focus my research on how to automate IP reconnection on these connection types as well, but since I'm thinking (assuming, uneducated guess) that probably 80% of users are on a UPNP-compatible router, I figured this would be the best place to start.
Also, I have a bit of UPNP code I’ve written, in a upnp.bas module (a module in VB6 doesn't require instantiation). In the module
I have several functions that just make life a little easier, I can do a copy & paste of them if anyone likes. Thank you for reading,
and once I have the time, I'm looking forward to having a play around with your Managed UPNP Class, and I've started playing around with your Managed UPnP stack, and I was impressed by how comprehensive it is,
you have definitely put quite a lot of thought behind it, and it is impressively detailed so I am having a lot of fun playing around with it. If there is an area or new feature idea that you'd like me to contribute towards, I'd be happy to code it up for you
anytime. In fact, I wholeheartedly support the motivation behind this project and I would be honoured to make a contribution towards it - anytime, just hit me up.
Sep 22, 2012 at 7:41 PM
Edited Sep 22, 2012 at 7:45 PM
In answer to your questions, yes, basically they do expect us to use Actions over state variables due to this inconsistency, my old Netgear DG834 was really crappy this way, with the older firmware you would need to use actions for the WAN traffic information,
but with the new firmware only the state variables worked, so when I wrote my UPnP Traffic Monitor program I did both, basically it attempts to get the data using the state vars first, if that fails then it marks the device as supporting Actions only and uses
them from that point forward.
As for the WFAWLANConfig:1 service type and the RebootAP, you will notice that the data type for those parameters are Bin.Base64, this tells me that its not just a simple string message.
I think I have the information you require here:
From page 50 onwards is information describing the message format for these functions along with their parameters, it still seems a little convoluted and you will probably have to find other sources to actually work out the Bin.Base64 data, but this should
give you a nice starting point.
Let me know how you go!