[EDIT:This has been released as gem. check the code page]
At the moment i’m trying to create a ruby module to integrate some upnp functionality in the language.
Get miniupnp to compile
--- a/Makefile +++ b/Makefile HEADERS = miniupnpc.h miniwget.h upnpcommands.h igd_desc_parse.h \ upnpreplyparse.h upnperrors.h LIBRARY = libminiupnpc.a -SHAREDLIBRARY = libminiupnpc.so +SHAREDLIBRARY = libminiupnpc.dylib SONAME = $(SHAREDLIBRARY).$(APIVERSION) EXECUTABLES = upnpc-static upnpc-shared \ testminixml minixmlvalid testupnpreplyparse @@ -83,7 +83,7 @@ $(LIBRARY): $(LIBOBJS) $(AR) crs $@ $? $(SHAREDLIBRARY): $(LIBOBJS) - $(CC) -shared -Wl,-soname,$(SONAME) -o $@ $^ + $(CC) -dynamiclib -o $@ $^ upnpc-static: upnpc.o $(LIBRARY) $(CC) -o $@ $^
--- a/miniupnpc.h
+++ b/miniupnpc.h
@@ -16,7 +16,7 @@ extern "C" {
#endif
/* Structures definitions : */
-struct UPNParg { const char * elt; const char * val; };
+struct UPNParg { char * elt; char * val; };
int simpleUPnPcommand(int, const char *, const char *,
const char *, struct UPNParg *,
Get Glue Code
%module miniupnp
%{
#include "miniupnpc.h"
%}
%include "cpointer.i"
%pointer_functions(unsigned int, uintp);
%import declspec.h
%include miniupnpc.h
%include upnpcommands.h
%include igd_desc_parse.h
Make the Module
miniupnpc.h, upnpcommands.h and igd_desc_parse.h and a struct i have added to ease the use of the library. Swig is then calledswig -ruby upnp.i
gcc -fPIC upnp_wrap.c -c -o upnp_wrap.o -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0/
upnp_wrap.c glue code which must be compiled with the ruby includes. From this point there is a decision to take, if the miniupnp library is to be linked to the module as an external shared library or be included in it as static code.gcc -fPIC -bundle -undefined dynamic_lookup upnp_wrap.o -o miniupnp.bundle -lruby -lminiupnpc -L<miniupnpc install path>
gcc -fPIC -bundle -undefined dynamic_lookup upnp_wrap.o -o miniupnp.bundle -lruby miniwget.o minixml.o igd_desc_parse.o minisoap.o miniupnpc.o upnpreplyparse.o upnpcommands.o minissdpc.o upnperrors.o
Test it
# system install
cp miniupnp.bundle /Library/Ruby/Site/1.8/
# setup path, bundle_path is where the
# bundle is (for instance $PWD)
export RUBYLIB=bundle_path
# The feature name begins with a lowercase letter...
require 'miniupnp'
# max time to wait for the upnp devices
MAX_WAIT_TIME = 1000
# discover upnp
list = Miniupnp.upnpDiscover(MAX_WAIT_TIME,nil,nil)
if list == nil then
puts "No UPNP device found"
exit 1
end
puts "URL : #{list.descURL}"
# get valid internet gateway device
urls = Miniupnp::UPNPUrls.new
datas = Miniupnp::IGDdatas.new
lan = ""*16
r = Miniupnp.UPNP_GetValidIGD(list,urls,datas,lan,16)
case r
when 0
puts "No IGD found"
exit 2
when 1
puts "A valid connected IGD has been found"
when 2
puts "A valid IGD has been found but it is reported as not connected"
when 3
puts "An UPnP device has been found but was not recognized as an IGD"
exit 3
end
puts "Client LAN IP: #{lan}"
ext=""*16
r = Miniupnp.UPNP_GetExternalIPAddress(urls.controlURL,datas.servicetype,ext)
if r == 0 then
puts "External IP: #{ext}"
else
puts "Error while retriving the external ip address"
end
# print urls
puts "*** urls"
puts "controlURL: #{urls.controlURL}"
puts "ipcondescURL: #{urls.ipcondescURL}"
puts "controlURL_CIF: #{urls.controlURL_CIF}"
# print datas
puts "*** datas"
puts "cureltname: #{datas.cureltname}"
puts "urlbase: #{datas.urlbase}"
puts "level: #{datas.level}"
puts "state: #{datas.state}"
puts "controlurl_CIF: #{datas.controlurl_CIF}"
puts "eventsuburl_CIF: #{datas.eventsuburl_CIF}"
puts "scpdurl_CIF: #{datas.scpdurl_CIF}"
puts "servicetype_CIF: #{datas.servicetype_CIF}"
puts "devicetype_CIF: #{datas.devicetype_CIF}"
puts "controlurl: #{datas.controlurl}"
puts "eventsuburl: #{datas.eventsuburl}"
puts "scpdurl: #{datas.scpdurl}"
puts "servicetype: #{datas.servicetype}"
puts "devicetype: #{datas.devicetype}"
puts "Get maximum bandwith"
up=Miniupnp.new_uintp()
down=Miniupnp.new_uintp()
Miniupnp.UPNP_GetLinkLayerMaxBitRates(urls.controlURL_CIF,datas.servicetype_CIF,down,up)
puts "up: #{Miniupnp.uintp_value(up)} down: #{Miniupnp.uintp_value(down)}"
Miniupnp.delete_uintp(up)
Miniupnp.delete_uintp(down)
# release memory
Miniupnp.freeUPNPDevlist(list)
Miniupnp.FreeUPNPUrls(urls)
an and ext variables, it should be “” repeated 16 times. The result should be something like thisURL : http://192.168.0.1:49152/gateway.xml A valid connected IGD has been found Client LAN IP: 192.168.0.100 External IP: ***.***.***.243 *** urls controlURL: http://192.168.0.1:49152/upnp/control/WANIPConnection ipcondescURL: http://192.168.0.1:49152/ipcfg.xml controlURL_CIF: http://192.168.0.1:49152/upnp/control/ WANCommonInterfaceConfig *** datas cureltname: presentationURL urlbase: http://192.168.0.1:49152 level: 0 state: 3 controlurl_CIF: /upnp/control/WANCommonInterfaceConfig eventsuburl_CIF: /upnp/event/WANCommonInterfaceConfig scpdurl_CIF: /cmnicfg.xml servicetype_CIF: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1 devicetype_CIF: urn:schemas-upnp-org:device:WANDevice:1wayDevice:1 controlurl: /upnp/control/WANIPConnection eventsuburl: /upnp/event/WANIPConnection scpdurl: /ipcfg.xml servicetype: urn:schemas-upnp-org:service:WANIPConnection:1 devicetype: urn:schemas-upnp-org:device:WANConnectionDevice:1 Maximum bandwith up: 352000 down: 2464000
This is just a start, I’ll make more testing and i’ll make sure it works. There may be some more things to add to upnp.i
Full code can be found in the code page
Edit 15-06-08: Module name changed to miniupnp from upnp
[Continued by: UPnP Wrapper]
[EDIT:This has been released as gem. check the code page]
Posted by Dario Meloni