GUPNP-BINDING-TOOL(1)
π GUPNP-BINDING-TOOL(1) π
okay bestie, welcome to the gupnp-binding-tool-1.6 page β it lives in the GUPnP manual, and it's genuinely one of the most underrated little tools out there. let's get into it π«Ά
β¨ NAME β¨
gupnp-binding-tool-1.6 β literally just here to create C convenience wrappers for UPnP services. that's the whole job. iconic behaviour honestly π
π SYNOPSIS π
gupnp-binding-tool-1.6 [--prefix {PREFIX}] [--mode {client|server}]
{SCPD file}
πΈ DESCRIPTION πΈ
so here's the tea, bestie: gupnp-binding-tool-1.6 takes a SCPD file and generates convenience C functions which call the actual GUPnP functions. that's it, that's the whole vibe. β¨
the client-side bindings can be seen as a service-specific version of the GUPnPServiceProxy API, and the service-side bindings are the same deal for GUPnPService.
now why do you care?? because these generated functions are less verbose and also safer β function call parameters are correctly typed, no cap. Action, variable and query names are easier to get correct with bindings (or at least the errors will be compile-time errors instead of run-time errors, which is a massive slay), and they're also available in editor autocompletion. like. chef's kiss. π
π¦ CLIENT SIDE BINDINGS π¦
okay so as an example, bestie, take this action:
<action>
<name>DeletePortMapping</name>
<argumentList>
<argument>
<name>NewRemoteHost</name>
<direction>in</direction>
<relatedStateVariable>RemoteHost</relatedStateVariable>
</argument>
<argument>
<name>NewExternalPort</name>
<direction>in</direction>
<relatedStateVariable>ExternalPort</relatedStateVariable>
</argument>
<argument>
<name>NewProtocol</name>
<direction>in</direction>
<relatedStateVariable>PortMappingProtocol</relatedStateVariable>
</argument>
</argumentList>
</action>
will generate the following synchronous client-side (control point) function:
static inline gboolean
igd_delete_port_mapping (GUPnPServiceProxy *proxy,
const gchar *in_new_remote_host,
const guint in_new_external_port,
const gchar *in_new_protocol,
GError **error);
and as you can see π the arguments have the correct types and are prefixed with the argument direction. cute, right?
gupnp-binding-tool-1.6 generates both synchronous and asynchronous wrappers. the igd_delete_port_mapping example above is the synchronous form β the asynchronous form goes like this:
typedef void (*igd_delete_port_mapping_reply) (GUPnPServiceProxy *proxy,
GError *error,
gpointer userdata);
static inline GUPnPServiceProxyAction *
igd_delete_port_mapping_async (GUPnPServiceProxy *proxy,
const gchar *in_new_remote_host,
const guint in_new_external_port,
const gchar *in_new_protocol,
igd_delete_port_mapping_reply callback,
gpointer userdata);
the asynchronous form (implemented using gupnp_service_proxy_begin_action() and gupnp_service_proxy_end_action()) will return without blocking and later invoke the callback from the main loop when the reply is received. no waiting around, we're busy girls π
the tool also creates bindings for state variable notifications. so this state variable definition:
<stateVariable sendEvents="yes">
<name>ExternalIPAddress</name>
<dataType>string</dataType>
</stateVariable>
will create this client binding that can be used to get notifications on "ExternalIPAddress" changes:
typedef void
(*igd_external_ip_address_changed_callback) (GUPnPServiceProxy *proxy,
const gchar *external_ip_address,
gpointer userdata);
static inline gboolean
igd_external_ip_address_add_notify (GUPnPServiceProxy *proxy,
igd_external_ip_address_changed_callback callback,
gpointer userdata);
and jsyk, all of the examples were produced with:
gupnp-binding-tool-1.6 --prefix igd --mode client WANIPConnection.xml
π SERVER SIDE BINDINGS π
the corresponding server bindings for the same UPnP action (DeletePortMapping) look like this:
void
igd_delete_port_mapping_action_get (GUPnPServiceAction *action,
gchar **in_new_remote_host,
guint *in_new_external_port,
gchar **in_new_protocol);
gulong
igd_delete_port_mapping_action_connect (GUPnPService *service,
GCallback callback,
gpointer userdata);
so the generated *_action_connect() function can be used to connect the action handler. the *_action_get() and *_action_set() functions can then be used inside the action handler to get/set action variables. and if notified variables are modified, the *_variable_notify() should be used to send the notifications (see below, bestie β¬οΈ).
typedef gchar *(*igd_external_ip_address_query_callback) (GUPnPService *service,
gpointer userdata);
gulong
igd_external_ip_address_query_connect (GUPnPService *service,
igd_external_ip_address_query_callback callback,
gpointer userdata);
void
igd_external_ip_address_variable_notify (GUPnPService *service,
const gchar *external_ip_address);
the *_query_connect() function can be used to connect the service-specific query handler. and the return value of the handler is the returned state variable value. periodt. π
all of these examples were produced with:
gupnp-binding-tool-1.6 --prefix igd --mode server WANIPConnection.xml
π§ SEE ALSO π§
ngl bestie there's no SEE ALSO section in this one, so consider this your lil moment of silence. π
and that's the whole page!! mwah π this one came out of GUPnP 1.6.10, and it's filed under the GUPNP-BINDING-TOOL(1) manual page. go make some bindings, you're gonna eat. πβ¨
π¦ where this page comes from
- fedora 43: gupnp-devel 1.6.10-1.fc43 Β· LGPL-2.1-or-later
- fedora 43: gupnp-devel 1.6.10-1.fc43 Β· LGPL-2.1-or-later
- fedora 44: gupnp-devel 1.6.10-1.fc44 Β· LGPL-2.1-or-later
- fedora 44: gupnp-devel 1.6.10-1.fc44 Β· LGPL-2.1-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms