Skip to content

Commit

Permalink
Make gmediarender compile with version libupnp 1.6.7 ... 1.6.16.
Browse files Browse the repository at this point in the history
With version 1.6.7 and above, the UPNP library maintainers made a questionable
API choice to register the webserver callbacks one-by-one, instead of having a
struct with the callbacks which is certainly a better and 'typical' C API
choice. They removed the UpnpVirtualDirCallbacks in the course of that.
Because it breaks code, it has been reverted in version 1.6.16
(see http://sourceforge.net/p/pupnp/bugs/29/ ), but we essentially have a
broken version between 1.6.7 ... 1.6.16.

Assuming that they will go on with this broken idea and eventually remove
the support for the VirtualDirCallbacks in new major versions, we now
register the callbacks separately when upnp-version >= 1.6.7
  • Loading branch information
hzeller committed Jul 21, 2013
1 parent aed31b8 commit d0fc9f7
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
8 changes: 2 additions & 6 deletions src/upnp_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,12 +424,8 @@ static gboolean initialize_device(struct upnp_device_descriptor *device_def,
return FALSE;
}

rc = UpnpSetVirtualDirCallbacks(&virtual_dir_callbacks);
if (UPNP_E_SUCCESS != rc) {
Log_error("upnp", "UpnpSetVirtualDirCallbacks() Error: %s (%d)",
UpnpGetErrorMessage(rc), rc);
return FALSE;
}
if (!webserver_register_callbacks())
return FALSE;

rc = UpnpAddVirtualDir("/upnp");
if (UPNP_E_SUCCESS != rc) {
Expand Down
38 changes: 37 additions & 1 deletion src/webserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <assert.h>

#include <upnp/upnp.h>
#include <upnp/upnptools.h> // UpnpGetErrorMessage
#include <upnp/ithread.h>

#include "logging.h"
Expand Down Expand Up @@ -247,11 +248,46 @@ static int webserver_close(UpnpWebFileHandle fh)
return 0;
}

struct UpnpVirtualDirCallbacks virtual_dir_callbacks = {
#if (UPNP_VERSION < 10607)
// Older versions had a nice struct to register callbacks, just as you would
// expect from a proper C API
static struct UpnpVirtualDirCallbacks virtual_dir_callbacks = {
webserver_get_info,
webserver_open,
webserver_read,
webserver_write,
webserver_seek,
webserver_close
};

gboolean webserver_register_callbacks(void) {
int rc = UpnpSetVirtualDirCallbacks(&virtual_dir_callbacks);
if (UPNP_E_SUCCESS != rc) {
Log_error("webserver", "UpnpSetVirtualDirCallbacks() Error: %s (%d)",
UpnpGetErrorMessage(rc), rc);
return FALSE;
}
return TRUE;
}
#else
// With version 1.6.7 and above, the UPNP library maintainers made a questionable
// API choice to register the callbacks one-by-one, instead of having a
// struct with the callbacks which is certainly a better and 'typical' C API
// choice. They removed the UpnpVirtualDirCallbacks in the course of that.
// Because it breaks code, it has been reverted in version 1.6.16
// (see http://sourceforge.net/p/pupnp/bugs/29/ ), but we essentially have a
// broken version between 1.6.7 ... 1.6.16.
// Assuming that they will go on with this broken idea and eventually remove
// the support for the VirtualDirCallbacks in new major versions, we use the
// newer (may I emphasize: questionable) API to register the callbacks.
gboolean webserver_register_callbacks(void) {
gboolean result =
(UpnpVirtualDir_set_GetInfoCallback(webserver_get_info) == UPNP_E_SUCCESS
&& UpnpVirtualDir_set_OpenCallback(webserver_open) == UPNP_E_SUCCESS
&& UpnpVirtualDir_set_ReadCallback(webserver_read) == UPNP_E_SUCCESS
&& UpnpVirtualDir_set_WriteCallback(webserver_write) == UPNP_E_SUCCESS
&& UpnpVirtualDir_set_SeekCallback(webserver_seek) == UPNP_E_SUCCESS
&& UpnpVirtualDir_set_CloseCallback(webserver_close) == UPNP_E_SUCCESS);
return result;
}
#endif
5 changes: 4 additions & 1 deletion src/webserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
#ifndef _WEBSERVER_H
#define _WEBSERVER_H

extern struct UpnpVirtualDirCallbacks virtual_dir_callbacks;
#include <glib.h>

// Start the webserver with the registered files.
gboolean webserver_register_callbacks(void);

int webserver_register_buf(const char *path, const char *contents,
const char *content_type);
Expand Down

1 comment on commit d0fc9f7

@kgha
Copy link

@kgha kgha commented on d0fc9f7 Jul 22, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's very good,thank you!

Please sign in to comment.