Add support for IPv6 RAOP sessions

This commit is contained in:
Julien BLACHE 2010-05-14 17:38:16 +02:00
parent b1d265b0ea
commit 7d858d6c9f
1 changed files with 111 additions and 38 deletions

View File

@ -1346,13 +1346,35 @@ raop_session_cleanup(struct raop_session *rs)
}
static struct raop_session *
raop_session_make(struct raop_device *rd, raop_status_cb cb)
raop_session_make(struct raop_device *rd, int family, raop_status_cb cb)
{
struct raop_session *rs;
char *address;
unsigned short port;
int ret;
if (!rd->v4_address)
return NULL;
switch (family)
{
case AF_INET:
/* We always have the v4 services, so no need to check */
if (!rd->v4_address)
return NULL;
address = rd->v4_address;
port = rd->v4_port;
break;
case AF_INET6:
if (!rd->v6_address || (timing_6svc.fd < 0) || (control_6svc.fd < 0))
return NULL;
address = rd->v6_address;
port = rd->v6_port;
break;
default:
return NULL;
}
rs = (struct raop_session *)malloc(sizeof(struct raop_session));
if (!rs)
@ -1372,19 +1394,7 @@ raop_session_make(struct raop_device *rd, raop_status_cb cb)
rs->password = rd->password;
rs->timing_svc = &timing_4svc;
rs->control_svc = &control_4svc;
rs->sa.sin.sin_family = AF_INET;
ret = inet_pton(AF_INET, rd->v4_address, &rs->sa.sin.sin_addr.s_addr);
if (ret <= 0)
{
DPRINTF(E_LOG, L_RAOP, "Device address not valid (%s)\n", rd->v4_address);
goto out_free_rs;
}
rs->ctrl = evrtsp_connection_new(rd->v4_address, rd->v4_port);
rs->ctrl = evrtsp_connection_new(address, port);
if (!rs->ctrl)
{
DPRINTF(E_LOG, L_RAOP, "Could not create control connection\n");
@ -1394,14 +1404,45 @@ raop_session_make(struct raop_device *rd, raop_status_cb cb)
evrtsp_connection_set_base(rs->ctrl, evbase_player);
rs->sa.ss.ss_family = family;
switch (family)
{
case AF_INET:
rs->timing_svc = &timing_4svc;
rs->control_svc = &control_4svc;
ret = inet_pton(AF_INET, address, &rs->sa.sin.sin_addr);
break;
case AF_INET6:
rs->timing_svc = &timing_6svc;
rs->control_svc = &control_6svc;
ret = inet_pton(AF_INET6, address, &rs->sa.sin6.sin6_addr);
break;
default:
ret = -1;
break;
}
if (ret <= 0)
{
DPRINTF(E_LOG, L_RAOP, "Device address not valid (%s)\n", address);
goto out_free_evcon;
}
rs->devname = strdup(rd->name);
rs->address = strdup(rd->v4_address);
rs->address = strdup(address);
rs->next = sessions;
sessions = rs;
return rs;
out_free_evcon:
evrtsp_connection_free(rs->ctrl);
out_free_rs:
free(rs);
@ -2789,23 +2830,38 @@ raop_device_probe(struct raop_device *rd, raop_status_cb cb)
struct raop_session *rs;
int ret;
rs = raop_session_make(rd, cb);
if (!rs)
return -1;
/* Send an OPTIONS request to test our ability to connect to the device,
* including the need for and/or validity of the password
*/
rs = raop_session_make(rd, AF_INET6, cb);
if (rs)
{
ret = raop_send_req_options(rs, raop_cb_probe_options);
if (ret == 0)
return 0;
else
{
DPRINTF(E_WARN, L_RAOP, "Could not send OPTIONS request on IPv6 (probe)\n");
raop_session_cleanup(rs);
}
}
rs = raop_session_make(rd, AF_INET, cb);
if (!rs)
return -1;
ret = raop_send_req_options(rs, raop_cb_probe_options);
if (ret < 0)
goto cleanup;
{
DPRINTF(E_WARN, L_RAOP, "Could not send OPTIONS request on IPv4 (probe)\n");
raop_session_cleanup(rs);
return -1;
}
return 0;
cleanup:
raop_session_cleanup(rs);
return -1;
}
int
@ -2814,26 +2870,43 @@ raop_device_start(struct raop_device *rd, raop_status_cb cb, uint64_t rtptime)
struct raop_session *rs;
int ret;
rs = raop_session_make(rd, cb);
/* Send an OPTIONS request to establish the connection
* After that, we can determine our local address and build our session URL
* for all subsequent requests.
*/
rs = raop_session_make(rd, AF_INET6, cb);
if (rs)
{
rs->start_rtptime = rtptime;
ret = raop_send_req_options(rs, raop_cb_startup_options);
if (ret == 0)
return 0;
else
{
DPRINTF(E_WARN, L_RAOP, "Could not send OPTIONS request on IPv6 (start)\n");
raop_session_cleanup(rs);
}
}
rs = raop_session_make(rd, AF_INET, cb);
if (!rs)
return -1;
rs->start_rtptime = rtptime;
/* Send an OPTIONS request to establish the connection
* After that, we can determine our local address and build our session URL
* for all subsequent requests.
*/
ret = raop_send_req_options(rs, raop_cb_startup_options);
if (ret < 0)
goto cleanup;
{
DPRINTF(E_WARN, L_RAOP, "Could not send OPTIONS request on IPv4 (start)\n");
raop_session_cleanup(rs);
return -1;
}
return 0;
cleanup:
raop_session_cleanup(rs);
return -1;
}
void