mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
implement client side TCP support
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@67 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
e83b7106ac
commit
1416fef197
6 changed files with 100 additions and 10 deletions
|
|
@ -193,9 +193,10 @@ static int pa_cli_command_load(struct pa_core *c, struct pa_tokenizer *t, struct
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (*verbose)
|
||||
if (*verbose) {
|
||||
snprintf(txt, sizeof(txt), "Module successfully loaded, index: %u.\n", m->index);
|
||||
pa_strbuf_puts(buf, txt);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
61
src/polyp.c
61
src/polyp.c
|
|
@ -2,6 +2,9 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "polyp.h"
|
||||
#include "protocol-native-spec.h"
|
||||
|
|
@ -21,6 +24,7 @@
|
|||
|
||||
#define DEFAULT_TIMEOUT (5*60)
|
||||
#define DEFAULT_SERVER "/tmp/polypaudio/native"
|
||||
#define DEFAULT_PORT "4713"
|
||||
|
||||
struct pa_context {
|
||||
char *name;
|
||||
|
|
@ -284,7 +288,7 @@ static void on_connection(struct pa_socket_client *client, struct pa_iochannel*i
|
|||
struct pa_context *c = userdata;
|
||||
struct pa_tagstruct *t;
|
||||
uint32_t tag;
|
||||
assert(client && io && c && c->state == CONTEXT_CONNECTING);
|
||||
assert(client && c && c->state == CONTEXT_CONNECTING);
|
||||
|
||||
pa_socket_client_free(client);
|
||||
c->client = NULL;
|
||||
|
|
@ -318,6 +322,36 @@ static void on_connection(struct pa_socket_client *client, struct pa_iochannel*i
|
|||
c->state = CONTEXT_AUTHORIZING;
|
||||
}
|
||||
|
||||
static struct sockaddr *resolve_server(const char *server, size_t *len) {
|
||||
struct sockaddr *sa;
|
||||
struct addrinfo hints, *result = NULL;
|
||||
char *port;
|
||||
assert(server && len);
|
||||
|
||||
if ((port = strrchr(server, ':')))
|
||||
port++;
|
||||
if (!port)
|
||||
port = DEFAULT_PORT;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = 0;
|
||||
|
||||
if (getaddrinfo(server, port, &hints, &result) != 0)
|
||||
return NULL;
|
||||
assert(result);
|
||||
|
||||
sa = malloc(*len = result->ai_addrlen);
|
||||
assert(sa);
|
||||
memcpy(sa, result->ai_addr, *len);
|
||||
|
||||
freeaddrinfo(result);
|
||||
|
||||
return sa;
|
||||
|
||||
}
|
||||
|
||||
int pa_context_connect(struct pa_context *c, const char *server, void (*complete) (struct pa_context*c, int success, void *userdata), void *userdata) {
|
||||
assert(c && c->state == CONTEXT_UNCONNECTED);
|
||||
|
||||
|
|
@ -326,11 +360,34 @@ int pa_context_connect(struct pa_context *c, const char *server, void (*complete
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (!server)
|
||||
if (!(server = getenv("POLYP_SERVER")))
|
||||
server = DEFAULT_SERVER;
|
||||
|
||||
assert(!c->client);
|
||||
if (!(c->client = pa_socket_client_new_unix(c->mainloop, server ? server : DEFAULT_SERVER))) {
|
||||
|
||||
if (*server == '/') {
|
||||
if (!(c->client = pa_socket_client_new_unix(c->mainloop, server))) {
|
||||
c->error = PA_ERROR_CONNECTIONREFUSED;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
struct sockaddr* sa;
|
||||
size_t sa_len;
|
||||
|
||||
if (!(sa = resolve_server(server, &sa_len))) {
|
||||
c->error = PA_ERROR_INVALIDSERVER;
|
||||
return -1;
|
||||
}
|
||||
|
||||
c->client = pa_socket_client_new_sockaddr(c->mainloop, sa, sa_len);
|
||||
free(sa);
|
||||
|
||||
if (!c->client) {
|
||||
c->error = PA_ERROR_CONNECTIONREFUSED;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
c->connect_complete_callback = complete;
|
||||
c->connect_complete_userdata = userdata;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ enum {
|
|||
PA_ERROR_INTERNAL,
|
||||
PA_ERROR_CONNECTIONTERMINATED,
|
||||
PA_ERROR_KILLED,
|
||||
PA_ERROR_INVALIDSERVER,
|
||||
PA_ERROR_MAX
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ static void connect_fixed_cb(struct pa_mainloop_api *m, void *id, void *userdata
|
|||
|
||||
static void connect_io_cb(struct pa_mainloop_api*m, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata) {
|
||||
struct pa_socket_client *c = userdata;
|
||||
assert(m && c && c->io_source == id && fd >= 0 && events == PA_MAINLOOP_API_IO_EVENT_OUTPUT);
|
||||
assert(m && c && c->io_source == id && fd >= 0);
|
||||
m->cancel_io(m, c->io_source);
|
||||
c->io_source = NULL;
|
||||
do_call(c);
|
||||
|
|
@ -93,7 +93,7 @@ static int do_connect(struct pa_socket_client *c, const struct sockaddr *sa, soc
|
|||
pa_make_nonblock_fd(c->fd);
|
||||
|
||||
if ((r = connect(c->fd, sa, len)) < 0) {
|
||||
if (r != EINPROGRESS) {
|
||||
if (errno != EINPROGRESS) {
|
||||
fprintf(stderr, "connect(): %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -166,6 +166,33 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct pa_socket_client* pa_socket_client_new_sockaddr(struct pa_mainloop_api *m, const struct sockaddr *sa, size_t salen) {
|
||||
struct pa_socket_client *c;
|
||||
assert(m && sa);
|
||||
c = pa_socket_client_new(m);
|
||||
assert(c);
|
||||
|
||||
if ((c->fd = socket(sa->sa_family, SOCK_STREAM, 0)) < 0) {
|
||||
fprintf(stderr, "socket(): %s\n", strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (sa->sa_family == AF_INET)
|
||||
pa_socket_tcp_low_delay(c->fd);
|
||||
else
|
||||
pa_socket_low_delay(c->fd);
|
||||
|
||||
if (do_connect(c, sa, salen) < 0)
|
||||
goto fail;
|
||||
|
||||
return c;
|
||||
|
||||
fail:
|
||||
pa_socket_client_free(c);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
void pa_socket_client_free(struct pa_socket_client *c) {
|
||||
assert(c && c->mainloop);
|
||||
if (c->io_source)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ struct pa_socket_client;
|
|||
|
||||
struct pa_socket_client* pa_socket_client_new_ipv4(struct pa_mainloop_api *m, uint32_t address, uint16_t port);
|
||||
struct pa_socket_client* pa_socket_client_new_unix(struct pa_mainloop_api *m, const char *filename);
|
||||
struct pa_socket_client* pa_socket_client_new_sockaddr(struct pa_mainloop_api *m, const struct sockaddr *sa, size_t salen);
|
||||
|
||||
void pa_socket_client_free(struct pa_socket_client *c);
|
||||
|
||||
|
|
|
|||
7
src/todo
7
src/todo
|
|
@ -1,8 +1,10 @@
|
|||
- modargs memory leak
|
||||
|
||||
- clean secure directory handling (with username)
|
||||
|
||||
- native library/protocol:
|
||||
more functions (esp. latency)
|
||||
|
||||
- daemonizing
|
||||
|
||||
- prefix modules/libraries with pa_
|
||||
|
||||
- xmms+esound latency testing
|
||||
|
|
@ -25,6 +27,7 @@
|
|||
- doxygen
|
||||
- make mcalign merge chunks
|
||||
- modinfo
|
||||
- daemonizing
|
||||
|
||||
drivers:
|
||||
- libao
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue