PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
- by the Free Software Foundation; either version 2 of the License,
+ by the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
PulseAudio is distributed in the hope that it will be useful, but
#include <config.h>
#endif
-#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
-#include <arpa/inet.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <pulsecore/core-error.h>
#include <pulsecore/core-util.h>
+#include <pulsecore/iochannel.h>
#include <pulsecore/socket-util.h>
#include <pulsecore/log.h>
+#include <pulsecore/parseaddr.h>
#include <pulsecore/macro.h>
-#include <pulsecore/strbuf.h>
+#include <pulsecore/memchunk.h>
#include <pulsecore/random.h>
-#include <pulsecore/poll.h>
#include "raop_client.h"
#include "rtsp_client.h"
#define VOLUME_MIN -144
#define VOLUME_MAX 0
+#define RAOP_PORT 5000
struct pa_raop_client {
pa_core *core;
char *host;
+ uint16_t port;
char *sid;
pa_rtsp_client *rtsp;
if (!data_bit_len)
return;
- /* If bit pos is zero, we will definatly use at least one bit from the current byte so size increments. */
+ /* If bit pos is zero, we will definately use at least one bit from the current byte so size increments. */
if (!*bit_pos)
*size += 1;
**buffer = bit_data;
/* If our data fits exactly into the current byte, we need to increment our pointer */
if (0 == bit_overflow) {
- /* Do not increment size as it will be incremeneted on next call as bit_pos is zero */
+ /* Do not increment size as it will be incremented on next call as bit_pos is zero */
*buffer += 1;
*bit_pos = 0;
} else {
return size;
}
-static int aes_encrypt(pa_raop_client* c, uint8_t *data, int size)
-{
+static int aes_encrypt(pa_raop_client* c, uint8_t *data, int size) {
uint8_t *buf;
int i=0, j;
return i;
}
-static inline void rtrimchar(char *str, char rc)
-{
+static inline void rtrimchar(char *str, char rc) {
char *sp = str + strlen(str) - 1;
while (sp >= str && *sp == rc) {
*sp = '\0';
c->fd = pa_iochannel_get_send_fd(io);
- pa_iochannel_set_noclose(io, TRUE);
- pa_iochannel_socket_set_sndbuf(io, 1024);
+ pa_iochannel_set_noclose(io, true);
pa_iochannel_free(io);
pa_make_tcp_socket_low_delay(c->fd);
c->callback(c->fd, c->userdata);
}
-static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* headers, void *userdata)
-{
+static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* headers, void *userdata) {
pa_raop_client* c = userdata;
pa_assert(c);
pa_assert(rtsp);
while ((token = pa_split(aj, delimiters, &token_state))) {
if ((pc = strstr(token, "="))) {
*pc = 0;
- if (!strcmp(token, "type") && !strcmp(pc+1, "digital")) {
+ if (pa_streq(token, "type") && pa_streq(pc+1, "digital")) {
c->jack_type = JACK_TYPE_DIGITAL;
}
} else {
- if (!strcmp(token,"connected"))
+ if (pa_streq(token, "connected"))
c->jack_status = JACK_STATUS_CONNECTED;
}
pa_xfree(token);
uint32_t port = pa_rtsp_serverport(c->rtsp);
pa_log_debug("RAOP: RECORDED");
- if (!(c->sc = pa_socket_client_new_string(c->core->mainloop, c->host, port))) {
+ if (!(c->sc = pa_socket_client_new_string(c->core->mainloop, true, c->host, port))) {
pa_log("failed to connect to server '%s:%d'", c->host, port);
return;
}
break;
case STATE_TEARDOWN:
+ pa_log_debug("RAOP: TEARDOWN");
+ break;
+
case STATE_SET_PARAMETER:
pa_log_debug("RAOP: SET_PARAMETER");
break;
+
case STATE_DISCONNECTED:
pa_assert(c->closed_callback);
pa_assert(c->rtsp);
}
}
-pa_raop_client* pa_raop_client_new(pa_core *core, const char* host)
-{
+pa_raop_client* pa_raop_client_new(pa_core *core, const char* host) {
+ pa_parsed_address a;
pa_raop_client* c = pa_xnew0(pa_raop_client, 1);
pa_assert(core);
pa_assert(host);
+ if (pa_parse_address(host, &a) < 0 || a.type == PA_PARSED_ADDRESS_UNIX)
+ return NULL;
+
c->core = core;
c->fd = -1;
- c->host = pa_xstrdup(host);
+
+ c->host = pa_xstrdup(a.path_or_host);
+ if (a.port)
+ c->port = a.port;
+ else
+ c->port = RAOP_PORT;
if (pa_raop_connect(c)) {
pa_raop_client_free(c);
return c;
}
-
-void pa_raop_client_free(pa_raop_client* c)
-{
+void pa_raop_client_free(pa_raop_client* c) {
pa_assert(c);
if (c->rtsp)
pa_rtsp_client_free(c->rtsp);
+ if (c->sid)
+ pa_xfree(c->sid);
pa_xfree(c->host);
pa_xfree(c);
}
-
-int pa_raop_connect(pa_raop_client* c)
-{
+int pa_raop_connect(pa_raop_client* c) {
char *sci;
struct {
uint32_t a;
return 0;
}
- c->rtsp = pa_rtsp_client_new(c->core->mainloop, c->host, 5000, "iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)");
+ c->rtsp = pa_rtsp_client_new(c->core->mainloop, c->host, c->port, "iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)");
/* Initialise the AES encryption system */
pa_random(c->aes_iv, sizeof(c->aes_iv));
return pa_rtsp_connect(c->rtsp);
}
-
-int pa_raop_flush(pa_raop_client* c)
-{
+int pa_raop_flush(pa_raop_client* c) {
pa_assert(c);
pa_rtsp_flush(c->rtsp, c->seq, c->rtptime);
return 0;
}
-
-int pa_raop_client_set_volume(pa_raop_client* c, pa_volume_t volume)
-{
+int pa_raop_client_set_volume(pa_raop_client* c, pa_volume_t volume) {
int rv;
double db;
char *param;
return rv;
}
-
-int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchunk* encoded)
-{
+int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchunk* encoded) {
uint16_t len;
size_t bufmax;
uint8_t *bp, bpos;
pa_memblock_release(raw->memblock);
encoded->length = header_size + size;
- /* store the lenght (endian swapped: make this better) */
+ /* store the length (endian swapped: make this better) */
len = size + header_size - 4;
*(b + 2) = len >> 8;
*(b + 3) = len & 0xff;
return 0;
}
-
-void pa_raop_client_set_callback(pa_raop_client* c, pa_raop_client_cb_t callback, void *userdata)
-{
+void pa_raop_client_set_callback(pa_raop_client* c, pa_raop_client_cb_t callback, void *userdata) {
pa_assert(c);
c->callback = callback;
c->userdata = userdata;
}
-void pa_raop_client_set_closed_callback(pa_raop_client* c, pa_raop_client_closed_cb_t callback, void *userdata)
-{
+void pa_raop_client_set_closed_callback(pa_raop_client* c, pa_raop_client_closed_cb_t callback, void *userdata) {
pa_assert(c);
c->closed_callback = callback;