#include "raop.h"
#include "raop_buffer.h"
#include "netutils.h"
+#include "utils.h"
#include "compat.h"
#include "logger.h"
logger_t *logger;
raop_callbacks_t callbacks;
+ /* Buffer to handle all resends */
raop_buffer_t *buffer;
+ /* Remote address as sockaddr */
+ struct sockaddr_storage remote_saddr;
+ socklen_t remote_saddr_len;
+
/* These variables only edited mutex locked */
int running;
int joined;
unsigned short timing_lport;
unsigned short data_lport;
+ /* Initialized after the first control packet */
struct sockaddr_storage control_saddr;
socklen_t control_saddr_len;
unsigned short control_seqnum;
};
+static int
+raop_rtp_parse_remote(raop_rtp_t *raop_rtp, const char *remote)
+{
+ char *original;
+ char *current;
+ char *tmpstr;
+ int family;
+ int ret;
+
+ assert(raop_rtp);
+
+ current = original = strdup(remote);
+ if (!original) {
+ return -1;
+ }
+ tmpstr = utils_strsep(¤t, " ");
+ if (strcmp(tmpstr, "IN")) {
+ free(original);
+ return -1;
+ }
+ tmpstr = utils_strsep(¤t, " ");
+ if (!strcmp(tmpstr, "IP4") && current) {
+ family = AF_INET;
+ } else if (!strcmp(tmpstr, "IP6") && current) {
+ family = AF_INET6;
+ } else {
+ free(original);
+ return -1;
+ }
+ ret = netutils_parse_address(family, current,
+ &raop_rtp->remote_saddr,
+ sizeof(raop_rtp->remote_saddr));
+ if (ret < 0) {
+ free(original);
+ return -1;
+ }
+ raop_rtp->remote_saddr_len = ret;
+ free(original);
+ return 0;
+}
+
raop_rtp_t *
-raop_rtp_init(logger_t *logger, raop_callbacks_t *callbacks, const char *fmtp,
- const unsigned char *aeskey, const unsigned char *aesiv)
+raop_rtp_init(logger_t *logger, raop_callbacks_t *callbacks, const char *remote,
+ const char *fmtp, const unsigned char *aeskey, const unsigned char *aesiv)
{
raop_rtp_t *raop_rtp;
assert(logger);
+ assert(callbacks);
+ assert(remote);
+ assert(fmtp);
raop_rtp = calloc(1, sizeof(raop_rtp_t));
if (!raop_rtp) {
free(raop_rtp);
return NULL;
}
+ if (raop_rtp_parse_remote(raop_rtp, remote) < 0) {
+ free(raop_rtp);
+ return NULL;
+ }
raop_rtp->running = 0;
raop_rtp->joined = 1;
unsigned short ourseqnum;
struct sockaddr *addr;
socklen_t addrlen;
+ int ret;
addr = (struct sockaddr *)&raop_rtp->control_saddr;
addrlen = raop_rtp->control_saddr_len;
packet[6] = (count >> 8);
packet[7] = count;
- sendto(raop_rtp->csock, (const char *)packet, sizeof(packet), 0, addr, addrlen);
+ ret = sendto(raop_rtp->csock, (const char *)packet, sizeof(packet), 0, addr, addrlen);
+ if (ret == -1) {
+ logger_log(raop_rtp->logger, LOGGER_WARNING, "Resend failed: %d\n", SOCKET_GET_ERROR());
+ }
+
return 0;
}
unsigned int packetlen;
struct sockaddr_storage saddr;
socklen_t saddrlen;
+ float volume = 0.0;
const ALACSpecificConfig *config;
void *cb_data = NULL;
while(1) {
int volume_changed;
- float volume = 0.0;
int flush;
fd_set rfds;
packetlen = recvfrom(raop_rtp->csock, (char *)packet, sizeof(packet), 0,
(struct sockaddr *)&saddr, &saddrlen);
- /* FIXME: Get destination address here */
+ /* Get the destination address here, because we need the sin6_scope_id */
memcpy(&raop_rtp->control_saddr, &saddr, saddrlen);
raop_rtp->control_saddr_len = saddrlen;
int stream_fd = -1;
unsigned char packet[RAOP_PACKET_LEN];
unsigned int packetlen = 0;
+ float volume = 0.0;
const ALACSpecificConfig *config;
void *cb_data = NULL;
while (1) {
int volume_changed;
- float volume = 0.0;
fd_set rfds;
struct timeval tv;
raop_rtp_start(raop_rtp_t *raop_rtp, int use_udp, unsigned short control_rport, unsigned short timing_rport,
unsigned short *control_lport, unsigned short *timing_lport, unsigned short *data_lport)
{
+ int use_ipv6 = 0;
+
assert(raop_rtp);
MUTEX_LOCK(raop_rtp->run_mutex);
/* Initialize ports and sockets */
raop_rtp->control_rport = control_rport;
raop_rtp->timing_rport = timing_rport;
- if (raop_rtp_init_sockets(raop_rtp, 1, use_udp) < 0) {
+ if (raop_rtp->remote_saddr.ss_family == AF_INET6) {
+ use_ipv6 = 1;
+ }
+ if (raop_rtp_init_sockets(raop_rtp, use_ipv6, use_udp) < 0) {
logger_log(raop_rtp->logger, LOGGER_INFO, "Initializing sockets failed\n");
MUTEX_UNLOCK(raop_rtp->run_mutex);
return;