mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-27 23:55:57 -05:00
Start implementing DAAP updates
Stall update requests if revision-number == current revision. This is a first step that is necessary to get clients to work properly (eg Remote).
This commit is contained in:
parent
7ddd135e2b
commit
42f39938d5
115
src/httpd_daap.c
115
src/httpd_daap.c
@ -59,6 +59,12 @@ struct daap_session {
|
||||
int id;
|
||||
};
|
||||
|
||||
struct daap_update_request {
|
||||
struct evhttp_request *req;
|
||||
|
||||
struct daap_update_request *next;
|
||||
};
|
||||
|
||||
#define DMAP_TYPE_BYTE 0x01
|
||||
#define DMAP_TYPE_UBYTE 0x02
|
||||
#define DMAP_TYPE_SHORT 0x03
|
||||
@ -340,6 +346,9 @@ static avl_tree_t *dmap_fields_hash;
|
||||
static avl_tree_t *daap_sessions;
|
||||
static int next_session_id;
|
||||
|
||||
/* Update requests */
|
||||
static struct daap_update_request *update_requests;
|
||||
|
||||
|
||||
static int
|
||||
daap_session_compare(const void *aa, const void *bb)
|
||||
@ -648,6 +657,36 @@ daap_session_find(struct evhttp_request *req, struct evkeyvalq *query, struct ev
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Update requests helpers */
|
||||
static void
|
||||
update_fail_cb(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
struct daap_update_request *ur;
|
||||
struct daap_update_request *p;
|
||||
|
||||
ur = (struct daap_update_request *)arg;
|
||||
|
||||
DPRINTF(E_DBG, L_DAAP, "Update request failed\n");
|
||||
|
||||
if (ur == update_requests)
|
||||
update_requests = ur->next;
|
||||
else
|
||||
{
|
||||
for (p = update_requests; p && (p->next != ur); p = p->next)
|
||||
;
|
||||
|
||||
if (!p)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "WARNING: struct update_request not found in list; BUG!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
p->next = ur->next;
|
||||
}
|
||||
|
||||
free(ur);
|
||||
}
|
||||
|
||||
|
||||
static struct dmap_field_map *
|
||||
dmap_find_field(uint32_t hash)
|
||||
@ -987,28 +1026,73 @@ daap_reply_logout(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
|
||||
static void
|
||||
daap_reply_update(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query)
|
||||
{
|
||||
struct daap_update_request *ur;
|
||||
const char *param;
|
||||
int current_rev = 2;
|
||||
int reqd_rev;
|
||||
int ret;
|
||||
|
||||
/* Just send back the current time.
|
||||
*
|
||||
* This probably doesn't cut it, but then again we don't claim to support
|
||||
* updates, so... that support should be added eventually.
|
||||
*/
|
||||
param = evhttp_find_header(query, "revision-number");
|
||||
if (!param)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Missing revision-number in update request\n");
|
||||
|
||||
ret = evbuffer_expand(evbuf, 32);
|
||||
daap_send_error(req, "mupd", "Invalid request");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = safe_atoi(param, &reqd_rev);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not expand evbuffer for DAAP update reply\n");
|
||||
DPRINTF(E_LOG, L_DAAP, "Parameter revision-number not an integer\n");
|
||||
|
||||
daap_send_error(req, "mupd", "Invalid request");
|
||||
return;
|
||||
}
|
||||
|
||||
if (reqd_rev == 1) /* Or revision is not valid */
|
||||
{
|
||||
ret = evbuffer_expand(evbuf, 32);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not expand evbuffer for DAAP update reply\n");
|
||||
|
||||
daap_send_error(req, "mupd", "Out of memory");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send back current revision */
|
||||
dmap_add_container(evbuf, "mupd", 24);
|
||||
dmap_add_int(evbuf, "mstt", 200); /* 12 */
|
||||
dmap_add_int(evbuf, "musr", current_rev); /* 12 */
|
||||
|
||||
evhttp_send_reply(req, HTTP_OK, "OK", evbuf);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Else, just let the request hang until we have changes to push back */
|
||||
ur = (struct daap_update_request *)malloc(sizeof(struct daap_update_request));
|
||||
if (!ur)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Out of memory for update request\n");
|
||||
|
||||
daap_send_error(req, "mupd", "Out of memory");
|
||||
return;
|
||||
}
|
||||
|
||||
dmap_add_container(evbuf, "mupd", 24);
|
||||
dmap_add_int(evbuf, "mstt", 200); /* 12 */
|
||||
dmap_add_int(evbuf, "musr", (int)time(NULL)); /* 12 */
|
||||
/* NOTE: we may need to keep reqd_rev in there too */
|
||||
ur->req = req;
|
||||
|
||||
evhttp_send_reply(req, HTTP_OK, "OK", evbuf);
|
||||
ur->next = update_requests;
|
||||
update_requests = ur;
|
||||
|
||||
/* Set fail_cb; this is an extension to the stock evhttp and will
|
||||
* get called if the connection fails before we have an update to
|
||||
* push out to the client.
|
||||
*/
|
||||
req->fail_cb = update_fail_cb;
|
||||
req->fail_cb_arg = ur;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2394,6 +2478,7 @@ daap_init(void)
|
||||
int ret;
|
||||
|
||||
next_session_id = 100; /* gotta start somewhere, right? */
|
||||
update_requests = NULL;
|
||||
|
||||
ret = daap_query_init();
|
||||
if (ret < 0)
|
||||
@ -2469,6 +2554,7 @@ daap_init(void)
|
||||
void
|
||||
daap_deinit(void)
|
||||
{
|
||||
struct daap_update_request *ur;
|
||||
int i;
|
||||
|
||||
daap_query_deinit();
|
||||
@ -2478,4 +2564,11 @@ daap_deinit(void)
|
||||
|
||||
avl_free_tree(daap_sessions);
|
||||
avl_free_tree(dmap_fields_hash);
|
||||
|
||||
for (ur = update_requests; update_requests; ur = update_requests)
|
||||
{
|
||||
update_requests = ur->next;
|
||||
|
||||
free(ur);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user