along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
***/
-/*
+/***
This file was originally inspired by a file developed by
Kungliga Tekniska högskolan
-*/
+***/
#ifdef HAVE_CONFIG_H
#include <config.h>
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static int pos(char c) {
- if (c >= 'A' && c <= 'Z') return c - 'A' + 0;
- if (c >= 'a' && c <= 'z') return c - 'a' + 26;
- if (c >= '0' && c <= '9') return c - '0' + 52;
- if (c == '+') return 62;
- if (c == '/') return 63;
+ if (c >= 'A' && c <= 'Z')
+ return c - 'A' + 0;
+ if (c >= 'a' && c <= 'z')
+ return c - 'a' + 26;
+ if (c >= '0' && c <= '9')
+ return c - '0' + 52;
+ if (c == '+')
+ return 62;
+ if (c == '/')
+ return 63;
+
return -1;
}
p[2] = '=';
p += 4;
}
+
*p = 0;
*str = s;
+
return strlen(s);
}
int i;
unsigned int val = 0;
int marker = 0;
+
if (strlen(token) < 4)
return DECODE_ERROR;
for (i = 0; i < 4; i++) {
val += lpos;
}
}
+
if (marker > 2)
return DECODE_ERROR;
+
return (marker << 24) | val;
}
if (marker < 1)
*q++ = val & 0xff;
}
+
return q - (unsigned char *) data;
}
along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
***/
-/*
+/***
This file was originally inspired by a file developed by
Kungliga Tekniska högskolan
-*/
+***/
int pa_base64_encode(const void *data, int size, char **str);
int pa_base64_decode(const char *str, void *data);
#define SERVICE_TYPE_SINK "_raop._tcp"
+struct userdata {
+ pa_core *core;
+ pa_module *module;
+
+ AvahiPoll *avahi_poll;
+ AvahiClient *client;
+ AvahiServiceBrowser *sink_browser;
+
+ pa_hashmap *tunnels;
+};
+
static const char* const valid_modargs[] = {
NULL
};
uint32_t module_index;
};
-struct userdata {
- pa_core *core;
- pa_module *module;
- AvahiPoll *avahi_poll;
- AvahiClient *client;
- AvahiServiceBrowser *sink_browser;
-
- pa_hashmap *tunnels;
-};
-
static unsigned tunnel_hash(const void *p) {
const struct tunnel *t = p;
return 0;
}
-static struct tunnel *tunnel_new(
+static struct tunnel* tunnel_new(
AvahiIfIndex interface, AvahiProtocol protocol,
const char *name, const char *type, const char *domain) {
-
struct tunnel *t;
+
t = pa_xnew(struct tunnel, 1);
t->interface = interface;
t->protocol = protocol;
t->type = pa_xstrdup(type);
t->domain = pa_xstrdup(domain);
t->module_index = PA_IDXSET_INVALID;
+
return t;
}
AvahiStringList *txt,
AvahiLookupResultFlags flags,
void *userdata) {
-
struct userdata *u = userdata;
struct tunnel *tnl;
+ char *device = NULL, *nicename, *dname, *vname, *args;
+ char at[AVAHI_ADDRESS_STR_MAX];
+ AvahiStringList *l;
+ pa_module *m;
pa_assert(u);
tnl = tunnel_new(interface, protocol, name, type, domain);
- if (event != AVAHI_RESOLVER_FOUND)
+ if (event != AVAHI_RESOLVER_FOUND) {
pa_log("Resolving of '%s' failed: %s", name, avahi_strerror(avahi_client_errno(u->client)));
- else {
- char *device = NULL, *nicename, *dname, *vname, *args;
- char at[AVAHI_ADDRESS_STR_MAX];
- AvahiStringList *l;
- pa_module *m;
-
- if ((nicename = strstr(name, "@"))) {
- ++nicename;
- if (strlen(nicename) > 0) {
- pa_log_debug("Found RAOP: %s", nicename);
- nicename = pa_escape(nicename, "\"'");
- } else
- nicename = NULL;
- }
+ goto finish;
+ }
- for (l = txt; l; l = l->next) {
- char *key, *value;
- pa_assert_se(avahi_string_list_get_pair(l, &key, &value, NULL) == 0);
+ if ((nicename = strstr(name, "@"))) {
+ ++nicename;
+ if (strlen(nicename) > 0) {
+ pa_log_debug("Found RAOP: %s", nicename);
+ nicename = pa_escape(nicename, "\"'");
+ } else
+ nicename = NULL;
+ }
- pa_log_debug("Found key: '%s' with value: '%s'", key, value);
- if (pa_streq(key, "device")) {
- pa_xfree(device);
- device = value;
- value = NULL;
- }
- avahi_free(key);
- avahi_free(value);
+ for (l = txt; l; l = l->next) {
+ char *key, *value;
+ pa_assert_se(avahi_string_list_get_pair(l, &key, &value, NULL) == 0);
+
+ pa_log_debug("Found key: '%s' with value: '%s'", key, value);
+ if (pa_streq(key, "device")) {
+ device = value;
+ value = NULL;
}
- if (device)
- dname = pa_sprintf_malloc("raop.%s.%s", host_name, device);
- else
- dname = pa_sprintf_malloc("raop.%s", host_name);
+ avahi_free(key);
+ avahi_free(value);
+ }
- if (!(vname = pa_namereg_make_valid_name(dname))) {
- pa_log("Cannot construct valid device name from '%s'.", dname);
- avahi_free(device);
- pa_xfree(dname);
- goto finish;
- }
+ if (device)
+ dname = pa_sprintf_malloc("raop.%s.%s", host_name, device);
+ else
+ dname = pa_sprintf_malloc("raop.%s", host_name);
+
+ if (!(vname = pa_namereg_make_valid_name(dname))) {
+ pa_log("Cannot construct valid device name from '%s'.", dname);
+ avahi_free(device);
pa_xfree(dname);
+ goto finish;
+ }
- if (nicename) {
- args = pa_sprintf_malloc("server=[%s]:%u "
- "sink_name=%s "
- "sink_properties='device.description=\"%s\"'",
- avahi_address_snprint(at, sizeof(at), a), port,
- vname,
- nicename);
- pa_xfree(nicename);
- } else {
- args = pa_sprintf_malloc("server=[%s]:%u "
- "sink_name=%s",
- avahi_address_snprint(at, sizeof(at), a), port,
- vname);
- }
+ avahi_free(device);
+ pa_xfree(dname);
+
+ if (nicename) {
+ args = pa_sprintf_malloc("server=[%s]:%u "
+ "sink_name=%s "
+ "sink_properties='device.description=\"%s\"'",
+ avahi_address_snprint(at, sizeof(at), a), port,
+ vname,
+ nicename);
+ pa_xfree(nicename);
+ } else {
+ args = pa_sprintf_malloc("server=[%s]:%u "
+ "sink_name=%s",
+ avahi_address_snprint(at, sizeof(at), a), port,
+ vname);
+ }
- pa_log_debug("Loading module-raop-sink with arguments '%s'", args);
+ pa_log_debug("Loading module-raop-sink with arguments '%s'", args);
- if ((m = pa_module_load(u->core, "module-raop-sink", args))) {
- tnl->module_index = m->index;
- pa_hashmap_put(u->tunnels, tnl, tnl);
- tnl = NULL;
- }
-
- pa_xfree(vname);
- pa_xfree(args);
- avahi_free(device);
+ if ((m = pa_module_load(u->core, "module-raop-sink", args))) {
+ tnl->module_index = m->index;
+ pa_hashmap_put(u->tunnels, tnl, tnl);
+ tnl = NULL;
}
-finish:
+ pa_xfree(vname);
+ pa_xfree(args);
+finish:
avahi_service_resolver_free(r);
if (tnl)
const char *name, const char *type, const char *domain,
AvahiLookupResultFlags flags,
void *userdata) {
-
struct userdata *u = userdata;
struct tunnel *t;
/* We ignore the returned resolver object here, since the we don't
* need to attach any special data to it, and we can still destroy
- * it from the callback */
+ * it from the callback. */
} else if (event == AVAHI_BROWSER_REMOVE) {
struct tunnel *t2;
case AVAHI_CLIENT_S_REGISTERING:
case AVAHI_CLIENT_S_RUNNING:
case AVAHI_CLIENT_S_COLLISION:
-
if (!u->sink_browser) {
-
if (!(u->sink_browser = avahi_service_browser_new(
c,
AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
pa_log_debug("Avahi daemon disconnected.");
+ /* Try to reconnect. */
if (!(u->client = avahi_client_new(u->avahi_poll, AVAHI_CLIENT_NO_FAIL, client_callback, u, &error))) {
pa_log("avahi_client_new() failed: %s", avahi_strerror(error));
pa_module_unload_request(u->module, true);
}
}
- /* Fall through */
+ /* Fall through. */
case AVAHI_CLIENT_CONNECTING:
-
if (u->sink_browser) {
avahi_service_browser_free(u->sink_browser);
u->sink_browser = NULL;
break;
- default: ;
+ default:
+ break;
}
}
-int pa__init(pa_module*m) {
-
+int pa__init(pa_module *m) {
struct userdata *u;
pa_modargs *ma = NULL;
int error;
return -1;
}
-void pa__done(pa_module*m) {
- struct userdata*u;
+void pa__done(pa_module *m) {
+ struct userdata *u;
+
pa_assert(m);
if (!(u = m->userdata))
SINK_MESSAGE_RIP_SOCKET
};
-/* Forward declaration */
+/* Forward declarations: */
static void sink_set_volume_cb(pa_sink *);
-static void on_connection(int fd, void*userdata) {
+static void on_connection(int fd, void *userdata) {
int so_sndbuf = 0;
socklen_t sl = sizeof(int);
struct userdata *u = userdata;
pa_sink_set_max_request(u->sink, PA_MAX((size_t) so_sndbuf, u->block_size));
}
- /* Set the initial volume */
+ /* Set the initial volume. */
sink_set_volume_cb(u->sink);
pa_log_debug("Connection authenticated, handing fd to IO thread...");
pa_smoother_pause(u->smoother, pa_rtclock_now());
- /* Issue a FLUSH if we are connected */
+ /* Issue a FLUSH if we are connected. */
if (u->fd >= 0) {
pa_raop_flush(u->raop);
}
pa_smoother_resume(u->smoother, pa_rtclock_now(), true);
/* The connection can be closed when idle, so check to
- see if we need to reestablish it */
+ * see if we need to reestablish it. */
if (u->fd < 0)
pa_raop_connect(u->raop);
else
/*pollfd->events = */pollfd->revents = 0;
if (u->sink->thread_info.state == PA_SINK_SUSPENDED) {
- /* Our stream has been suspended so we just flush it.... */
+ /* Our stream has been suspended so we just flush it... */
pa_raop_flush(u->raop);
}
return 0;
pa_assert(u);
- /* If we're muted we don't need to do anything */
+ /* If we're muted we don't need to do anything. */
if (s->muted)
return;
/* Calculate the max volume of all channels.
- We'll use this as our (single) volume on the APEX device and emulate
- any variation in channel volumes in software */
+ * We'll use this as our (single) volume on the APEX device and emulate
+ * any variation in channel volumes in software. */
v = pa_cvolume_max(&s->real_volume);
- /* Create a pa_cvolume version of our single value */
+ /* Create a pa_cvolume version of our single value. */
pa_cvolume_set(&hw, s->sample_spec.channels, v);
- /* Perform any software manipulation of the volume needed */
+ /* Perform any software manipulation of the volume needed. */
pa_sw_cvolume_divide(&s->soft_volume, &s->real_volume, &hw);
pa_log_debug("Requested volume: %s", pa_cvolume_snprint_verbose(t, sizeof(t), &s->real_volume, &s->channel_map, false));
pa_cvolume_snprint_verbose(t, sizeof(t), &s->soft_volume, &s->channel_map, true));
/* Any necessary software volume manipulation is done so set
- our hw volume (or v as a single value) on the device */
+ * our hw volume (or v as a single value) on the device. */
pa_raop_client_set_volume(u->raop, v);
}
struct pollfd *pollfd;
pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
- /* Render some data and write it to the fifo */
+ /* Render some data and write it to the fifo. */
if (/*PA_SINK_IS_OPENED(u->sink->thread_info.state) && */pollfd->revents) {
pa_usec_t usec;
int64_t n;
if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
size_t rl;
- /* We render real data */
+ /* We render real data. */
if (u->raw_memchunk.length <= 0) {
if (u->raw_memchunk.memblock)
pa_memblock_unref(u->raw_memchunk.memblock);
pa_memchunk_reset(&u->raw_memchunk);
- /* Grab unencoded data */
+ /* Grab unencoded data. */
pa_sink_render(u->sink, u->block_size, &u->raw_memchunk);
}
pa_assert(u->raw_memchunk.length > 0);
- /* Encode it */
+ /* Encode it. */
rl = u->raw_memchunk.length;
u->encoding_overhead += u->next_encoding_overhead;
pa_raop_client_encode_sample(u->raop, &u->raw_memchunk, &u->encoded_memchunk);
u->next_encoding_overhead = (u->encoded_memchunk.length - (rl - u->raw_memchunk.length));
u->encoding_ratio = u->encoded_memchunk.length / (rl - u->raw_memchunk.length);
} else {
- /* We render some silence into our memchunk */
+ /* We render some silence into our memchunk. */
memcpy(&u->encoded_memchunk, &silence, sizeof(pa_memchunk));
pa_memblock_ref(silence.memblock);
- /* Calculate/store some values to be used with the smoother */
+ /* Calculate/store some values to be used with the smoother. */
u->next_encoding_overhead = silence_overhead;
u->encoding_ratio = silence_ratio;
}
continue;
else if (errno == EAGAIN) {
- /* OK, we filled all socket buffers up
- * now. */
+ /* OK, we filled all socket buffers up now. */
goto filled_up;
} else {
pollfd->revents = 0;
if (u->encoded_memchunk.length > 0) {
- /* we've completely written the encoded data, so update our overhead */
+ /* We've completely written the encoded data, so update our overhead. */
u->encoding_overhead += u->next_encoding_overhead;
/* OK, we wrote less that we asked for,
* hence we can assume that the socket
- * buffers are full now */
+ * buffers are full now. */
goto filled_up;
}
}
}
filled_up:
-
/* At this spot we know that the socket buffers are
* fully filled up. This is the best time to estimate
- * the playback position of the server */
+ * the playback position of the server. */
n = u->offset - u->encoding_overhead;
pa_smoother_put(u->smoother, pa_rtclock_now(), usec);
}
- /* Hmm, nothing to do. Let's sleep */
+ /* Hmm, nothing to do. Let's sleep... */
pollfd->events = POLLOUT; /*PA_SINK_IS_OPENED(u->sink->thread_info.state) ? POLLOUT : 0;*/
}
}
/* We expect this to happen on occasion if we are not sending data.
- It's perfectly natural and normal and natural */
+ * It's perfectly natural and normal and natural. */
if (u->rtpoll_item)
pa_rtpoll_item_free(u->rtpoll_item);
u->rtpoll_item = NULL;
fail:
/* If this was no regular exit from the loop we have to continue
- * processing messages until we received PA_MESSAGE_SHUTDOWN */
+ * processing messages until we received PA_MESSAGE_SHUTDOWN. */
pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
pa_log_debug("Thread shutting down");
}
-int pa__init(pa_module*m) {
+int pa__init(pa_module *m) {
struct userdata *u = NULL;
pa_sample_spec ss;
pa_modargs *ma = NULL;
return pa_sink_linked_by(u->sink);
}
-void pa__done(pa_module*m) {
+void pa__done(pa_module *m) {
struct userdata *u;
pa_assert(m);
/* Encryption Related bits */
AES_KEY aes;
- uint8_t aes_iv[AES_CHUNKSIZE]; /* initialization vector for aes-cbc */
- uint8_t aes_nv[AES_CHUNKSIZE]; /* next vector for aes-cbc */
- uint8_t aes_key[AES_CHUNKSIZE]; /* key for aes-cbc */
+ uint8_t aes_iv[AES_CHUNKSIZE]; /* Initialization vector for aes-cbc */
+ uint8_t aes_nv[AES_CHUNKSIZE]; /* Next vector for aes-cbc */
+ uint8_t aes_key[AES_CHUNKSIZE]; /* Key for aes-cbc */
pa_socket_client *sc;
int fd;
uint32_t rtptime;
pa_raop_client_cb_t callback;
- void* userdata;
+ void *userdata;
pa_raop_client_closed_cb_t closed_callback;
- void* closed_userdata;
+ void *closed_userdata;
};
/**
if (!*bit_pos)
*size += 1;
- /* Calc the number of bits left in the current byte of buffer */
+ /* Calc the number of bits left in the current byte of buffer. */
bits_left = 7 - *bit_pos + 1;
/* Calc the overflow of bits in relation to how much space we have left... */
bit_overflow = bits_left - data_bit_len;
if (bit_overflow >= 0) {
- /* We can fit the new data in our current byte */
- /* As we write from MSB->LSB we need to left shift by the overflow amount */
+ /* We can fit the new data in our current byte.
+ * As we write from MSB->LSB we need to left shift by the overflow amount. */
bit_data = data << bit_overflow;
if (*bit_pos)
**buffer |= bit_data;
else
**buffer = bit_data;
- /* If our data fits exactly into the current byte, we need to increment our pointer */
+ /* 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 incremented 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 {
*bit_pos += data_bit_len;
}
} else {
- /* bit_overflow is negative, there for we will need a new byte from our buffer */
- /* Firstly fill up what's left in the current byte */
+ /* bit_overflow is negative, there for we will need a new byte from our buffer
+ * Firstly fill up what's left in the current byte. */
bit_data = data >> -bit_overflow;
**buffer |= bit_data;
- /* Increment our buffer pointer and size counter*/
+ /* Increment our buffer pointer and size counter. */
*buffer += 1;
*size += 1;
**buffer = data << (8 + bit_overflow);
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;
c->callback(c->fd, c->userdata);
}
-static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* headers, void *userdata) {
- pa_raop_client* c = 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);
pa_assert(rtsp == c->rtsp);
pa_log_debug("RAOP: CONNECTED");
ip = pa_rtsp_localip(c->rtsp);
- /* First of all set the url properly */
+ /* First of all set the url properly. */
url = pa_sprintf_malloc("rtsp://%s/%s", ip, c->sid);
pa_rtsp_set_url(c->rtsp, url);
pa_xfree(url);
- /* Now encrypt our aes_public key to send to the device */
+ /* Now encrypt our aes_public key to send to the device. */
i = rsa_encrypt(c->aes_key, AES_CHUNKSIZE, rsakey);
pa_base64_encode(rsakey, i, &key);
rtrimchar(key, '=');
pa_rtsp_client_free(c->rtsp);
c->rtsp = NULL;
if (c->fd > 0) {
- /* We do not close the fd, we leave it to the closed callback to do that */
+ /* We do not close the fd, we leave it to the closed callback to do that. */
c->fd = -1;
}
if (c->sc) {
}
}
-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_raop_client_free(c);
return NULL;
}
+
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_xfree(c);
}
-int pa_raop_connect(pa_raop_client* c) {
+int pa_raop_connect(pa_raop_client *c) {
char *sci;
struct {
uint32_t a;
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 */
+ /* Initialise the AES encryption system. */
pa_random(c->aes_iv, sizeof(c->aes_iv));
pa_random(c->aes_key, sizeof(c->aes_key));
memcpy(c->aes_nv, c->aes_iv, sizeof(c->aes_nv));
AES_set_encrypt_key(c->aes_key, 128, &c->aes);
- /* Generate random instance id */
+ /* Generate random instance id. */
pa_random(&rand_data, sizeof(rand_data));
c->sid = pa_sprintf_malloc("%u", rand_data.a);
sci = pa_sprintf_malloc("%08x%08x",rand_data.b, rand_data.c);
pa_rtsp_add_header(c->rtsp, "Client-Instance", sci);
pa_xfree(sci);
pa_rtsp_set_callback(c->rtsp, rtsp_cb, c);
+
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;
param = pa_sprintf_malloc("volume: %0.6f\r\n", db);
- /* We just hit and hope, cannot wait for the callback */
+ /* We just hit and hope, cannot wait for the callback. */
rv = pa_rtsp_setparameter(c->rtsp, param);
pa_xfree(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;
bsize = (int)(raw->length / 4);
length = bsize * 4;
- /* Leave 16 bytes extra to allow for the ALAC header which is about 55 bits */
+ /* Leave 16 bytes extra to allow for the ALAC header which is about 55 bits. */
bufmax = length + header_size + 16;
pa_memchunk_reset(encoded);
encoded->memblock = pa_memblock_new(c->core->mempool, bufmax);
b = pa_memblock_acquire(encoded->memblock);
memcpy(b, header, header_size);
- /* Now write the actual samples */
+ /* Now write the actual samples. */
bp = b + header_size;
size = bpos = 0;
bit_writer(&bp,&bpos,&size,1,3); /* channel=1, stereo */
- bit_writer(&bp,&bpos,&size,0,4); /* unknown */
- bit_writer(&bp,&bpos,&size,0,8); /* unknown */
- bit_writer(&bp,&bpos,&size,0,4); /* unknown */
- bit_writer(&bp,&bpos,&size,1,1); /* hassize */
- bit_writer(&bp,&bpos,&size,0,2); /* unused */
- bit_writer(&bp,&bpos,&size,1,1); /* is-not-compressed */
-
- /* size of data, integer, big endian */
+ bit_writer(&bp,&bpos,&size,0,4); /* Unknown */
+ bit_writer(&bp,&bpos,&size,0,8); /* Unknown */
+ bit_writer(&bp,&bpos,&size,0,4); /* Unknown */
+ bit_writer(&bp,&bpos,&size,1,1); /* Hassize */
+ bit_writer(&bp,&bpos,&size,0,2); /* Unused */
+ bit_writer(&bp,&bpos,&size,1,1); /* Is-not-compressed */
+
+ /* Size of data, integer, big endian. */
bit_writer(&bp,&bpos,&size,(bsize>>24)&0xff,8);
bit_writer(&bp,&bpos,&size,(bsize>>16)&0xff,8);
bit_writer(&bp,&bpos,&size,(bsize>>8)&0xff,8);
ibp = p = pa_memblock_acquire(raw->memblock);
maxibp = p + raw->length - 4;
while (ibp <= maxibp) {
- /* Byte swap stereo data */
+ /* Byte swap stereo data. */
bit_writer(&bp,&bpos,&size,*(ibp+1),8);
bit_writer(&bp,&bpos,&size,*(ibp+0),8);
bit_writer(&bp,&bpos,&size,*(ibp+3),8);
pa_memblock_release(raw->memblock);
encoded->length = header_size + size;
- /* store the length (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;
- /* encrypt our data */
+ /* Encrypt our data. */
aes_encrypt(c, (b + header_size), size);
- /* We're done with the chunk */
+ /* We're done with the chunk. */
pa_memblock_release(encoded->memblock);
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;
typedef struct pa_raop_client pa_raop_client;
-pa_raop_client* pa_raop_client_new(pa_core *core, const char* host);
-void pa_raop_client_free(pa_raop_client* c);
+pa_raop_client* pa_raop_client_new(pa_core *core, const char *host);
+void pa_raop_client_free(pa_raop_client *c);
-int pa_raop_connect(pa_raop_client* c);
-int pa_raop_flush(pa_raop_client* c);
+int pa_raop_connect(pa_raop_client *c);
+int pa_raop_flush(pa_raop_client *c);
-int pa_raop_client_set_volume(pa_raop_client* c, pa_volume_t volume);
-int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchunk* encoded);
+int pa_raop_client_set_volume(pa_raop_client *c, pa_volume_t volume);
+int pa_raop_client_encode_sample(pa_raop_client *c, pa_memchunk *raw, pa_memchunk *encoded);
typedef void (*pa_raop_client_cb_t)(int fd, void *userdata);
-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);
typedef void (*pa_raop_client_closed_cb_t)(void *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);
#endif
char *transport;
};
-pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char* hostname, uint16_t port, const char* useragent) {
+pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char *hostname, uint16_t port, const char *useragent) {
pa_rtsp_client *c;
pa_assert(mainloop);
return c;
}
-void pa_rtsp_client_free(pa_rtsp_client* c) {
+void pa_rtsp_client_free(pa_rtsp_client *c) {
pa_assert(c);
if (c->sc)
c->ioline = NULL;
}
-const char* pa_rtsp_localip(pa_rtsp_client* c) {
+const char* pa_rtsp_localip(pa_rtsp_client *c) {
pa_assert(c);
return c->localip;
}
-uint32_t pa_rtsp_serverport(pa_rtsp_client* c) {
+uint32_t pa_rtsp_serverport(pa_rtsp_client *c) {
pa_assert(c);
return c->rtp_port;
}
-void pa_rtsp_set_url(pa_rtsp_client* c, const char* url) {
+void pa_rtsp_set_url(pa_rtsp_client *c, const char *url) {
pa_assert(c);
c->url = pa_xstrdup(url);
}
-void pa_rtsp_add_header(pa_rtsp_client *c, const char* key, const char* value) {
+void pa_rtsp_add_header(pa_rtsp_client *c, const char *key, const char *value) {
pa_assert(c);
pa_assert(key);
pa_assert(value);
pa_headerlist_puts(c->headers, key, value);
}
-void pa_rtsp_remove_header(pa_rtsp_client *c, const char* key) {
+void pa_rtsp_remove_header(pa_rtsp_client *c, const char *key) {
pa_assert(c);
pa_assert(key);
pa_headerlist_remove(c->headers, key);
}
-static int rtsp_exec(pa_rtsp_client* c, const char* cmd,
- const char* content_type, const char* content,
+static int rtsp_exec(pa_rtsp_client *c, const char *cmd,
+ const char *content_type, const char *content,
int expect_response,
- pa_headerlist* headers) {
- pa_strbuf* buf;
- char* hdrs;
+ pa_headerlist *headers) {
+ pa_strbuf *buf;
+ char *hdrs;
pa_assert(c);
pa_assert(c->url);
return 0;
}
-int pa_rtsp_announce(pa_rtsp_client *c, const char* sdp) {
+int pa_rtsp_announce(pa_rtsp_client *c, const char *sdp) {
+ int rv;
+
pa_assert(c);
+
if (!sdp)
return -1;
c->state = STATE_ANNOUNCE;
- return rtsp_exec(c, "ANNOUNCE", "application/sdp", sdp, 1, NULL);
+ rv = rtsp_exec(c, "ANNOUNCE", "application/sdp", sdp, 1, NULL);
+
+ return rv;
}
-int pa_rtsp_setup(pa_rtsp_client* c) {
- pa_headerlist* headers;
+int pa_rtsp_setup(pa_rtsp_client *c) {
+ pa_headerlist *headers;
int rv;
pa_assert(c);
c->state = STATE_SETUP;
rv = rtsp_exec(c, "SETUP", NULL, NULL, 1, headers);
+
pa_headerlist_free(headers);
return rv;
}
-int pa_rtsp_record(pa_rtsp_client* c, uint16_t* seq, uint32_t* rtptime) {
- pa_headerlist* headers;
- int rv;
+int pa_rtsp_record(pa_rtsp_client *c, uint16_t *seq, uint32_t *rtptime) {
+ pa_headerlist *headers;
char *info;
+ int rv;
pa_assert(c);
+
if (!c->session) {
/* No session in progress */
return -1;
c->state = STATE_RECORD;
rv = rtsp_exec(c, "RECORD", NULL, NULL, 1, headers);
+
pa_headerlist_free(headers);
return rv;
}
int pa_rtsp_teardown(pa_rtsp_client *c) {
+ int rv;
+
pa_assert(c);
c->state = STATE_TEARDOWN;
- return rtsp_exec(c, "TEARDOWN", NULL, NULL, 0, NULL);
+ rv = rtsp_exec(c, "TEARDOWN", NULL, NULL, 0, NULL);
+
+ return rv;
}
-int pa_rtsp_setparameter(pa_rtsp_client *c, const char* param) {
+int pa_rtsp_setparameter(pa_rtsp_client *c, const char *param) {
+ int rv;
+
pa_assert(c);
+
if (!param)
return -1;
c->state = STATE_SET_PARAMETER;
- return rtsp_exec(c, "SET_PARAMETER", "text/parameters", param, 1, NULL);
+ rv = rtsp_exec(c, "SET_PARAMETER", "text/parameters", param, 1, NULL);
+
+ return rv;
}
int pa_rtsp_flush(pa_rtsp_client *c, uint16_t seq, uint32_t rtptime) {
pa_headerlist* headers;
- int rv;
char *info;
+ int rv;
pa_assert(c);
c->state = STATE_FLUSH;
rv = rtsp_exec(c, "FLUSH", NULL, NULL, 1, headers);
+
pa_headerlist_free(headers);
return rv;
}
STATE_SET_PARAMETER,
STATE_DISCONNECTED
} pa_rtsp_state;
-typedef void (*pa_rtsp_cb_t)(pa_rtsp_client *c, pa_rtsp_state state, pa_headerlist* hl, void *userdata);
+typedef void (*pa_rtsp_cb_t)(pa_rtsp_client *c, pa_rtsp_state state, pa_headerlist *hl, void *userdata);
-pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char* hostname, uint16_t port, const char* useragent);
-void pa_rtsp_client_free(pa_rtsp_client* c);
+pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char *hostname, uint16_t port, const char *useragent);
+void pa_rtsp_client_free(pa_rtsp_client *c);
-int pa_rtsp_connect(pa_rtsp_client* c);
+int pa_rtsp_connect(pa_rtsp_client *c);
void pa_rtsp_set_callback(pa_rtsp_client *c, pa_rtsp_cb_t callback, void *userdata);
-void pa_rtsp_disconnect(pa_rtsp_client* c);
+void pa_rtsp_disconnect(pa_rtsp_client *c);
-const char* pa_rtsp_localip(pa_rtsp_client* c);
-uint32_t pa_rtsp_serverport(pa_rtsp_client* c);
-void pa_rtsp_set_url(pa_rtsp_client* c, const char* url);
-void pa_rtsp_add_header(pa_rtsp_client *c, const char* key, const char* value);
-void pa_rtsp_remove_header(pa_rtsp_client *c, const char* key);
+const char* pa_rtsp_localip(pa_rtsp_client *c);
+uint32_t pa_rtsp_serverport(pa_rtsp_client *c);
+void pa_rtsp_set_url(pa_rtsp_client *c, const char *url);
+void pa_rtsp_add_header(pa_rtsp_client *c, const char *key, const char *value);
+void pa_rtsp_remove_header(pa_rtsp_client *c, const char *key);
-int pa_rtsp_announce(pa_rtsp_client* c, const char* sdp);
+int pa_rtsp_announce(pa_rtsp_client *c, const char *sdp);
-int pa_rtsp_setup(pa_rtsp_client* c);
-int pa_rtsp_record(pa_rtsp_client* c, uint16_t* seq, uint32_t* rtptime);
-int pa_rtsp_teardown(pa_rtsp_client* c);
+int pa_rtsp_setup(pa_rtsp_client *c);
+int pa_rtsp_record(pa_rtsp_client *c, uint16_t *seq, uint32_t *rtptime);
+int pa_rtsp_teardown(pa_rtsp_client *c);
-int pa_rtsp_setparameter(pa_rtsp_client* c, const char* param);
-int pa_rtsp_flush(pa_rtsp_client* c, uint16_t seq, uint32_t rtptime);
+int pa_rtsp_setparameter(pa_rtsp_client *c, const char *param);
+int pa_rtsp_flush(pa_rtsp_client *c, uint16_t seq, uint32_t rtptime);
#endif