#include <string.h>
#include <stdio.h>
#include <stdlib.h>
-#include <limits.h>
#include <pulse/rtclock.h>
#include <pulse/sample.h>
#include <pulsecore/source.h>
#include <pulsecore/core-scache.h>
#include <pulsecore/sample-util.h>
-#include <pulsecore/authkey.h>
#include <pulsecore/namereg.h>
#include <pulsecore/log.h>
#include <pulsecore/core-util.h>
#include <pulsecore/macro.h>
#include <pulsecore/thread-mq.h>
#include <pulsecore/shared.h>
-
-#include "endianmacros.h"
+#include <pulsecore/endianmacros.h>
#include "protocol-esound.h"
pa_msgobject parent;
uint32_t index;
- pa_bool_t dead;
+ bool dead;
pa_esound_protocol *protocol;
pa_esound_options *options;
pa_iochannel *io;
pa_client *client;
- pa_bool_t authorized, swap_byte_order;
+ bool authorized, swap_byte_order;
void *write_data;
size_t write_data_alloc, write_data_index, write_data_length;
void *read_data;
pa_memblock *current_memblock;
size_t memblock_index;
pa_atomic_t missing;
- pa_bool_t underrun;
+ bool underrun;
} playback;
struct {
memcpy((uint8_t*) c->write_data + i, data, length);
}
-static void format_esd2native(int format, pa_bool_t swap_bytes, pa_sample_spec *ss) {
+static void format_esd2native(int format, bool swap_bytes, pa_sample_spec *ss) {
pa_assert(ss);
ss->channels = (uint8_t) (((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1);
if ((key = pa_auth_cookie_read(c->options->auth_cookie, ESD_KEY_LEN)))
if (memcmp(data, key, ESD_KEY_LEN) == 0)
- c->authorized = TRUE;
+ c->authorized = true;
}
if (!c->authorized) {
memcpy(&ekey, data, sizeof(uint32_t));
if (ekey == ESD_ENDIAN_KEY)
- c->swap_byte_order = FALSE;
+ c->swap_byte_order = false;
else if (ekey == ESD_SWAP_ENDIAN_KEY)
- c->swap_byte_order = TRUE;
+ c->swap_byte_order = true;
else {
pa_log_warn("Client sent invalid endian key");
return -1;
sdata.driver = __FILE__;
sdata.module = c->options->module;
sdata.client = c->client;
- sdata.sink = sink;
+ if (sink)
+ pa_sink_input_new_data_set_sink(&sdata, sink, false);
pa_sink_input_new_data_set_sample_spec(&sdata, &ss);
pa_sink_input_new(&c->sink_input, c->protocol->core, &sdata);
l = (size_t) ((double) pa_bytes_per_second(&ss)*PLAYBACK_BUFFER_SECONDS);
pa_sink_input_get_silence(c->sink_input, &silence);
c->input_memblockq = pa_memblockq_new(
+ "esound protocol connection input_memblockq",
0,
l,
l,
- pa_frame_size(&ss),
+ &ss,
(size_t) -1,
l/PLAYBACK_BUFFER_FRAGMENTS,
0,
c->protocol->n_player++;
- pa_atomic_store(&c->playback.missing, (int) pa_memblockq_missing(c->input_memblockq));
+ pa_atomic_store(&c->playback.missing, (int) pa_memblockq_pop_missing(c->input_memblockq));
pa_sink_input_put(c->sink_input);
sdata.driver = __FILE__;
sdata.module = c->options->module;
sdata.client = c->client;
- sdata.source = source;
+ if (source)
+ pa_source_output_new_data_set_source(&sdata, source, false);
pa_source_output_new_data_set_sample_spec(&sdata, &ss);
pa_source_output_new(&c->source_output, c->protocol->core, &sdata);
l = (size_t) (pa_bytes_per_second(&ss)*RECORD_BUFFER_SECONDS);
c->output_memblockq = pa_memblockq_new(
+ "esound protocol connection output_memblockq",
0,
l,
l,
- pa_frame_size(&ss),
+ &ss,
1,
0,
0,
if (conn->sink_input) {
pa_cvolume volume;
- pa_sink_input_get_volume(conn->sink_input, &volume, TRUE);
+ pa_sink_input_get_volume(conn->sink_input, &volume, true);
rate = (int32_t) conn->sink_input->sample_spec.rate;
lvolume = (int32_t) ((volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM);
rvolume = (int32_t) ((volume.values[volume.channels == 2 ? 1 : 0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM);
volume.values[1] = (rvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
volume.channels = conn->sink_input->sample_spec.channels;
- pa_sink_input_set_volume(conn->sink_input, &volume, TRUE, TRUE);
+ pa_sink_input_set_volume(conn->sink_input, &volume, true, true);
ok = 1;
} else
ok = 0;
pa_cvolume_remap(&volume, &stereo, &ce->channel_map);
ce->volume = volume;
- ce->volume_is_set = TRUE;
+ ce->volume_is_set = true;
ok = 1;
}
connection_write_prepare(c, sizeof(int32_t) * 2);
connection_write(c, &ok, sizeof(int32_t));
- if (request == ESD_PROTO_STANDBY)
- ok = pa_sink_suspend_all(c->protocol->core, TRUE, PA_SUSPEND_USER) >= 0;
- else {
+ pa_log_debug("%s of all sinks and sources requested by client %" PRIu32 ".",
+ request == ESD_PROTO_STANDBY ? "Suspending" : "Resuming", c->client->index);
+
+ if (request == ESD_PROTO_STANDBY) {
+ ok = pa_sink_suspend_all(c->protocol->core, true, PA_SUSPEND_USER) >= 0;
+ ok &= pa_source_suspend_all(c->protocol->core, true, PA_SUSPEND_USER) >= 0;
+ } else {
pa_assert(request == ESD_PROTO_RESUME);
- ok = pa_sink_suspend_all(c->protocol->core, FALSE, PA_SUSPEND_USER) >= 0;
+ ok = pa_sink_suspend_all(c->protocol->core, false, PA_SUSPEND_USER) >= 0;
+ ok &= pa_source_suspend_all(c->protocol->core, false, PA_SUSPEND_USER) >= 0;
}
connection_write(c, &ok, sizeof(int32_t));
c->request = PA_MAYBE_INT32_SWAP(c->swap_byte_order, c->request);
if (c->request < ESD_PROTO_CONNECT || c->request >= ESD_PROTO_MAX) {
- pa_log("recieved invalid request.");
+ pa_log("received invalid request.");
return -1;
}
/* pa_log("executing request #%u", c->request); */
if (!handler->proc) {
- pa_log("recieved unimplemented request #%u.", c->request);
+ pa_log("received unimplemented request #%u.", c->request);
return -1;
}
pa_assert(c->write_data_index < c->write_data_length);
if ((r = pa_iochannel_write(c->io, (uint8_t*) c->write_data+c->write_data_index, c->write_data_length-c->write_data_index)) < 0) {
-
- if (r < 0 && (errno == EINTR || errno == EAGAIN))
- return 0;
-
pa_log("write(): %s", pa_cstrerror(errno));
return -1;
}
if (c->write_data_index >= c->write_data_length)
c->write_data_length = c->write_data_index = 0;
+ return 1;
+
} else if (c->state == ESD_STREAMING_DATA && c->source_output) {
pa_memchunk chunk;
ssize_t r;
pa_memblock_unref(chunk.memblock);
if (r < 0) {
-
- if (r < 0 && (errno == EINTR || errno == EAGAIN))
- return 0;
-
pa_log("write(): %s", pa_cstrerror(errno));
return -1;
}
pa_memblockq_drop(c->output_memblockq, (size_t) r);
+ return 1;
}
return 0;
* here, instead of simply waiting for read() to return 0. */
goto fail;
- if (pa_iochannel_is_writable(c->io))
- if (do_write(c) < 0)
+ while (pa_iochannel_is_writable(c->io)) {
+ int r = do_write(c);
+ if (r < 0)
goto fail;
+ if (r == 0)
+ break;
+ }
return;
fail:
if (c->state == ESD_STREAMING_DATA && c->sink_input) {
- c->dead = TRUE;
+ c->dead = true;
pa_iochannel_free(c->io);
c->io = NULL;
if (pa_memblockq_is_readable(c->input_memblockq) && c->playback.underrun) {
pa_log_debug("Requesting rewind due to end of underrun.");
- pa_sink_input_request_rewind(c->sink_input, 0, FALSE, TRUE, FALSE);
+ pa_sink_input_request_rewind(c->sink_input, 0, false, true, false);
}
/* pa_log("got data, %u", pa_memblockq_get_length(c->input_memblockq)); */
if (pa_memblockq_peek(c->input_memblockq, chunk) < 0) {
- c->playback.underrun = TRUE;
+ c->playback.underrun = true;
if (c->dead && pa_sink_input_safe_to_remove(i))
pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_UNLINK_CONNECTION, NULL, 0, NULL, NULL);
} else {
size_t m;
- c->playback.underrun = FALSE;
+ c->playback.underrun = false;
chunk->length = PA_MIN(length, chunk->length);
pa_memblockq_drop(c->input_memblockq, chunk->length);
c->client->userdata = c;
c->options = pa_esound_options_ref(o);
- c->authorized = FALSE;
- c->swap_byte_order = FALSE;
- c->dead = FALSE;
+ c->authorized = false;
+ c->swap_byte_order = false;
+ c->dead = false;
c->read_data_length = 0;
c->read_data = pa_xmalloc(c->read_data_alloc = proto_map[ESD_PROTO_CONNECT].data_length);
c->playback.current_memblock = NULL;
c->playback.memblock_index = 0;
- c->playback.underrun = TRUE;
+ c->playback.underrun = true;
pa_atomic_store(&c->playback.missing, 0);
pa_memchunk_reset(&c->scache.memchunk);
if (o->auth_anonymous) {
pa_log_info("Client authenticated anonymously.");
- c->authorized = TRUE;
+ c->authorized = true;
}
if (!c->authorized &&
pa_ip_acl_check(o->auth_ip_acl, pa_iochannel_get_recv_fd(io)) > 0) {
pa_log_info("Client authenticated by IP ACL.");
- c->authorized = TRUE;
+ c->authorized = true;
}
if (!c->authorized)
while ((c = pa_idxset_first(p->connections, NULL)))
connection_unlink(c);
- pa_idxset_free(p->connections, NULL, NULL);
+ pa_idxset_free(p->connections, NULL);
pa_assert_se(pa_shared_remove(p->core, "esound-protocol") >= 0);
}
int pa_esound_options_parse(pa_esound_options *o, pa_core *c, pa_modargs *ma) {
- pa_bool_t enabled;
+ bool enabled;
const char *acl;
pa_assert(o);
o->auth_ip_acl = ipa;
}
- enabled = TRUE;
+ enabled = true;
if (pa_modargs_get_value_boolean(ma, "auth-cookie-enabled", &enabled) < 0) {
pa_log("auth-cookie-enabled= expects a boolean argument.");
return -1;
if (!(cn = pa_modargs_get_value(ma, "cookie", NULL)))
cn = DEFAULT_COOKIE_FILE;
- if (!(o->auth_cookie = pa_auth_cookie_get(c, cn, ESD_KEY_LEN)))
+ if (!(o->auth_cookie = pa_auth_cookie_get(c, cn, true, ESD_KEY_LEN)))
return -1;
} else