[pulseaudio-commits] r2369 - in /branches/coling/airtunes/src/modules/rtp: raop_client.c raop_client.h rtsp.c
svnmailer-noreply at 0pointer.de
svnmailer-noreply at 0pointer.de
Tue May 6 11:39:10 PDT 2008
Author: coling
Date: Tue May 6 20:39:09 2008
New Revision: 2369
URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=2369&root=pulseaudio&view=rev
Log:
Add a pa_iochannel callback for when the RAOP connection connects.
Properly handle the sequence of events that establish a connection.
Modified:
branches/coling/airtunes/src/modules/rtp/raop_client.c
branches/coling/airtunes/src/modules/rtp/raop_client.h
branches/coling/airtunes/src/modules/rtp/rtsp.c
Modified: branches/coling/airtunes/src/modules/rtp/raop_client.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/coling/airtunes/src/modules/rtp/raop_client.c?rev=2369&root=pulseaudio&r1=2368&r2=2369&view=diff
==============================================================================
--- branches/coling/airtunes/src/modules/rtp/raop_client.c (original)
+++ branches/coling/airtunes/src/modules/rtp/raop_client.c Tue May 6 20:39:09 2008
@@ -73,10 +73,10 @@
struct pa_raop_client {
- pa_rtsp_context *rtsp;
- pa_socket_client *sc;
+ pa_mainloop_api *mainloop;
const char *host;
char *sid;
+ pa_rtsp_context *rtsp;
uint8_t jack_type;
uint8_t jack_status;
@@ -87,9 +87,13 @@
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;
pa_iochannel *io;
pa_iochannel_cb_t callback;
void* userdata;
+
+ uint8_t *buffer;
+ /*pa_memchunk memchunk;*/
};
/**
@@ -219,6 +223,25 @@
return num;
}
+static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata) {
+ pa_raop_client *c = userdata;
+
+ pa_assert(sc);
+ pa_assert(c);
+ pa_assert(c->sc == sc);
+
+ pa_socket_client_unref(c->sc);
+ c->sc = NULL;
+
+ if (!io) {
+ pa_log("Connection failed: %s", pa_cstrerror(errno));
+ return;
+ }
+ pa_assert(!c->io);
+ c->io = io;
+ pa_iochannel_set_callback(c->io, c->callback, c->userdata);
+}
+
static void rtsp_cb(pa_rtsp_context *rtsp, pa_rtsp_state state, pa_headerlist* headers, void *userdata)
{
pa_raop_client* c = userdata;
@@ -235,6 +258,7 @@
const char *ip;
char *url;
+ pa_log_debug("RAOP: CONNECTED");
ip = pa_rtsp_localip(c->rtsp);
/* First of all set the url properly */
url = pa_sprintf_malloc("rtsp://%s/%s", ip, c->sid);
@@ -273,12 +297,14 @@
}
case STATE_ANNOUNCE:
+ pa_log_debug("RAOP: ANNOUNCED");
pa_rtsp_remove_header(c->rtsp, "Apple-Challenge");
pa_rtsp_setup(c->rtsp);
break;
case STATE_SETUP: {
char *aj = pa_xstrdup(pa_headerlist_gets(headers, "Audio-Jack-Status"));
+ pa_log_debug("RAOP: SETUP");
if (aj) {
char *token, *pc;
char delimiters[] = ";";
@@ -299,17 +325,24 @@
pa_xfree(token);
}
pa_xfree(aj);
- pa_rtsp_record(c->rtsp);
} else {
- pa_log("Audio Jack Status missing");
+ pa_log_warn("Audio Jack Status missing");
}
+ pa_rtsp_record(c->rtsp);
break;
}
- case STATE_RECORD:
- /* Connect to the actual stream ;) */
- /* if(raopcl_stream_connect(raopcld)) goto erexit; */
+ case STATE_RECORD: {
+ uint32_t port = pa_rtsp_serverport(c->rtsp);
+ pa_log_debug("RAOP: RECORDED");
+
+ if (!(c->sc = pa_socket_client_new_string(c->mainloop, c->host, port))) {
+ pa_log("failed to connect to server '%s:%d'", c->host, port);
+ return;
+ }
+ pa_socket_client_set_callback(c->sc, on_connection, c);
break;
+ }
case STATE_TEARDOWN:
case STATE_SET_PARAMETER:
@@ -330,6 +363,7 @@
pa_assert(c);
pa_assert(host);
+ c->mainloop = mainloop;
c->host = host;
c->rtsp = pa_rtsp_context_new("iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)");
@@ -356,5 +390,40 @@
void pa_raop_client_send_sample(pa_raop_client* c, const uint8_t* buffer, unsigned int count)
{
-
-}
+ ssize_t l;
+ uint16_t len;
+ static uint8_t header[] = {
+ 0x24, 0x00, 0x00, 0x00,
+ 0xF0, 0xFF, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ };
+ const int header_size = sizeof(header);
+
+ pa_assert(c);
+ pa_assert(buffer);
+ pa_assert(count > 0);
+
+ c->buffer = pa_xrealloc(c->buffer, (count + header_size + 16));
+ memcpy(c->buffer, header, header_size);
+ len = count + header_size - 4;
+
+ /* store the lenght (endian swapped: make this better) */
+ *(c->buffer + 2) = len >> 8;
+ *(c->buffer + 3) = len & 0xff;
+
+ memcpy((c->buffer+header_size), buffer, count);
+ aes_encrypt(c, (c->buffer + header_size), count);
+ len = header_size + count;
+
+ /* TODO: move this into a memchunk/memblock and write only in callback */
+ l = pa_iochannel_write(c->io, c->buffer, len);
+}
+
+void pa_raop_client_set_callback(pa_raop_client* c, pa_iochannel_cb_t callback, void *userdata)
+{
+ pa_assert(c);
+
+ c->callback = callback;
+ c->userdata = userdata;
+}
Modified: branches/coling/airtunes/src/modules/rtp/raop_client.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/coling/airtunes/src/modules/rtp/raop_client.h?rev=2369&root=pulseaudio&r1=2368&r2=2369&view=diff
==============================================================================
--- branches/coling/airtunes/src/modules/rtp/raop_client.h (original)
+++ branches/coling/airtunes/src/modules/rtp/raop_client.h Tue May 6 20:39:09 2008
@@ -25,6 +25,7 @@
***/
#include <pulse/mainloop-api.h>
+#include <pulsecore/iochannel.h>
typedef struct pa_raop_client pa_raop_client;
@@ -37,4 +38,6 @@
void pa_raop_client_send_sample(pa_raop_client* c, const uint8_t* buffer, unsigned int count);
+void pa_raop_client_set_callback(pa_raop_client* c, pa_iochannel_cb_t callback, void *userdata);
+
#endif
Modified: branches/coling/airtunes/src/modules/rtp/rtsp.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/coling/airtunes/src/modules/rtp/rtsp.c?rev=2369&root=pulseaudio&r1=2368&r2=2369&view=diff
==============================================================================
--- branches/coling/airtunes/src/modules/rtp/rtsp.c (original)
+++ branches/coling/airtunes/src/modules/rtp/rtsp.c Tue May 6 20:39:09 2008
@@ -172,6 +172,8 @@
/* Our packet is created... now we can send it :) */
hdrs = pa_strbuf_tostring_free(buf);
+ pa_log_debug("Submitting request:");
+ pa_log_debug(hdrs);
l = pa_iochannel_write(c->io, hdrs, strlen(hdrs));
pa_xfree(hdrs);
@@ -220,15 +222,22 @@
char delimiters[] = " ";
pa_rtsp_context *c = userdata;
pa_assert(c);
+ pa_assert(c->io == io);
+
+ if (!pa_iochannel_is_readable(c->io)) {
+ if (STATE_SETUP == c->state || STATE_ANNOUNCE == c->state) return;
+ goto do_callback;
+ }
/* TODO: convert this to a pa_ioline based reader */
- if (STATE_CONNECT == c->state) {
+ if (STATE_SETUP == c->state || STATE_ANNOUNCE == c->state) {
response_headers = pa_headerlist_new();
}
timeout = 5000;
/* read in any response headers */
if (pa_read_line(c->io, response, sizeof(response), timeout) > 0) {
const char* token_state = NULL;
+ pa_log_debug("Response Line: %s", response);
timeout = 1000;
pa_xfree(pa_split(response, delimiters, &token_state));
@@ -244,12 +253,15 @@
/* We want to return the headers? */
if (!response_headers) {
/* We have no storage, so just clear out the response. */
- while (pa_read_line(c->io, response, sizeof(response), timeout) > 0);
+ while (pa_read_line(c->io, response, sizeof(response), timeout) > 0){
+ pa_log_debug("Response Line: %s", response);
+ }
} else {
/* TODO: Move header reading into the headerlist. */
header = NULL;
buf = pa_strbuf_new();
while (pa_read_line(c->io, response, sizeof(response), timeout) > 0) {
+ pa_log_debug("Response Line: %s", response);
/* If the first character is a space, it's a continuation header */
if (header && ' ' == response[0]) {
/* Add this line to the buffer (sans the space. */
@@ -297,8 +309,8 @@
}
}
- /* Deal with a CONNECT response */
- if (STATE_CONNECT == c->state) {
+ /* Deal with a SETUP response */
+ if (STATE_SETUP == c->state) {
const char* token_state = NULL;
const char* pc = NULL;
c->session = pa_xstrdup(pa_headerlist_gets(response_headers, "Session"));
@@ -330,6 +342,7 @@
}
/* Call our callback */
+do_callback:
if (c->callback)
c->callback(c, c->state, response_headers, c->userdata);
@@ -387,6 +400,7 @@
if (res)
c->localip = pa_xstrdup(res);
}
+ pa_log_debug("Established RTSP connection from local ip %s", c->localip);
}
int pa_rtsp_connect(pa_rtsp_context *c, pa_mainloop_api *mainloop, const char* hostname, uint16_t port) {
More information about the pulseaudio-commits
mailing list