![]() |
![]() |
![]() |
GUPnP Reference Manual | ![]() |
---|
In this tutorial we will write an application which fetches the external IP
address from an UPnP-compliant ADSL modem. To do this a Control
Point is created, which searches for services of the type
urn:schemas-upnp-org:service:WANIPConnection:1
. As
services are found Service Proxy objects are created
to allow interaction with the service, on which we can call
GetExternalIPAddress
to fetch the external IP address.
First, we initialize GUPnP and create a control point targeting the service type. Then we connect a signal handler so that we are notified when services we are interested in are found.
#include <libgupnp/gupnp-control-point.h> static GMainLoop *main_loop; int main (int argc, char **argv) { GError *error = NULL; GUPnPContext *context; GUPnPControlPoint *cp; /* Required initialisation */ g_thread_init (NULL); g_type_init (); /* Create a new GUPnP Context. By here we are using the default GLib main context, and connecting to the current machine's default IP on an automatically generated port. */ context = gupnp_context_new (NULL, NULL, 0, &error); if (error) g_error (error->message); /* Create a Control Point targeting WAN IP Connection services */ cp = gupnp_control_point_new (context, "urn:schemas-upnp-org:service:WANIPConnection:1"); /* The service-proxy-available signal is emitted when any services which match our target are found, so connect to it */ g_signal_connect (cp, "service-proxy-available", G_CALLBACK (service_proxy_available_cb), NULL); /* Tell the Control Point to start searching */ gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), TRUE); /* Enter the main loop. This will start the search and result in callbacks to service_proxy_available_cb. */ main_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (main_loop); /* Clean up */ g_main_loop_unref (main_loop); g_object_unref (cp); g_object_unref (context); return 0; } static void service_proxy_available_cb (GUPnPControlPoint *cp, GUPnPServiceProxy *proxy) { /* ... */ }
Now we have an application which searches for the service we specified and
calls service_proxy_available_cb
for each one it found.
To get the external IP address we need to invoke the
GetExternalIPAddress
action. This action takes no in
arguments, and has a single out argument called "NewExternalIPAddress".
GUPnP has a set of methods to invoke actions (which will be very familiar
to anyone who has used dbus-glib
) where you pass a
NULL
-terminated varargs list of (name, GType, value)
tuples for the in arguments, then a NULL
-terminated
varargs list of (name, GType, return location) tuples for the out
arguments.
static void service_proxy_available_cb (GUPnPControlPoint *cp, GUPnPServiceProxy *proxy) { GError *error = NULL; char *ip = NULL; gupnp_service_proxy_send_action (proxy, /* Action name and error location */ "GetExternalIPAddress", &error, /* IN args */ NULL, /* OUT args */ "NewExternalIPAddress", G_TYPE_STRING, &ip, NULL); if (error == NULL) { g_print ("External IP address is %s\n", ip); g_free (ip); } else { g_printerr ("Error: %s\n", error->message); g_error_free (error); } g_main_loop_quit (main_loop); }
Note that _send_action
blocks until the service has replied. If you
need to make non-blocking calls then
use gupnp_service_proxy_begin_action
which takes a callback.