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