mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	raop: Cosmetic fixes / Match coding style
Reviewed-by: Anton Lundin <glance@acc.umu.se>
This commit is contained in:
		
							parent
							
								
									d623c689e6
								
							
						
					
					
						commit
						6665acac56
					
				
					 8 changed files with 252 additions and 222 deletions
				
			
		| 
						 | 
					@ -17,10 +17,10 @@
 | 
				
			||||||
  along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
 | 
					  along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
***/
 | 
					***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/***
 | 
				
			||||||
  This file was originally inspired by a file developed by
 | 
					  This file was originally inspired by a file developed by
 | 
				
			||||||
  Kungliga Tekniska högskolan
 | 
					  Kungliga Tekniska högskolan
 | 
				
			||||||
*/
 | 
					***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_CONFIG_H
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
#include <config.h>
 | 
					#include <config.h>
 | 
				
			||||||
| 
						 | 
					@ -37,11 +37,17 @@ static const char base64_chars[] =
 | 
				
			||||||
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 | 
					    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pos(char c) {
 | 
					static int pos(char c) {
 | 
				
			||||||
    if (c >= 'A' && c <= 'Z') return c - 'A' + 0;
 | 
					    if (c >= 'A' && c <= 'Z')
 | 
				
			||||||
    if (c >= 'a' && c <= 'z') return c - 'a' + 26;
 | 
					        return c - 'A' + 0;
 | 
				
			||||||
    if (c >= '0' && c <= '9') return c - '0' + 52;
 | 
					    if (c >= 'a' && c <= 'z')
 | 
				
			||||||
    if (c == '+') return 62;
 | 
					        return c - 'a' + 26;
 | 
				
			||||||
    if (c == '/') return 63;
 | 
					    if (c >= '0' && c <= '9')
 | 
				
			||||||
 | 
					        return c - '0' + 52;
 | 
				
			||||||
 | 
					    if (c == '+')
 | 
				
			||||||
 | 
					        return 62;
 | 
				
			||||||
 | 
					    if (c == '/')
 | 
				
			||||||
 | 
					        return 63;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,8 +79,10 @@ int pa_base64_encode(const void *data, int size, char **str) {
 | 
				
			||||||
            p[2] = '=';
 | 
					            p[2] = '=';
 | 
				
			||||||
        p += 4;
 | 
					        p += 4;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    *p = 0;
 | 
					    *p = 0;
 | 
				
			||||||
    *str = s;
 | 
					    *str = s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return strlen(s);
 | 
					    return strlen(s);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,6 +92,7 @@ static unsigned int token_decode(const char *token) {
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
    unsigned int val = 0;
 | 
					    unsigned int val = 0;
 | 
				
			||||||
    int marker = 0;
 | 
					    int marker = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (strlen(token) < 4)
 | 
					    if (strlen(token) < 4)
 | 
				
			||||||
        return DECODE_ERROR;
 | 
					        return DECODE_ERROR;
 | 
				
			||||||
    for (i = 0; i < 4; i++) {
 | 
					    for (i = 0; i < 4; i++) {
 | 
				
			||||||
| 
						 | 
					@ -99,8 +108,10 @@ static unsigned int token_decode(const char *token) {
 | 
				
			||||||
            val += lpos;
 | 
					            val += lpos;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (marker > 2)
 | 
					    if (marker > 2)
 | 
				
			||||||
        return DECODE_ERROR;
 | 
					        return DECODE_ERROR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (marker << 24) | val;
 | 
					    return (marker << 24) | val;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -120,5 +131,6 @@ int pa_base64_decode(const char *str, void *data) {
 | 
				
			||||||
        if (marker < 1)
 | 
					        if (marker < 1)
 | 
				
			||||||
            *q++ = val & 0xff;
 | 
					            *q++ = val & 0xff;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return q - (unsigned char *) data;
 | 
					    return q - (unsigned char *) data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,10 +21,10 @@
 | 
				
			||||||
  along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
 | 
					  along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
***/
 | 
					***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/***
 | 
				
			||||||
  This file was originally inspired by a file developed by
 | 
					  This file was originally inspired by a file developed by
 | 
				
			||||||
  Kungliga Tekniska högskolan
 | 
					  Kungliga Tekniska högskolan
 | 
				
			||||||
*/
 | 
					***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa_base64_encode(const void *data, int size, char **str);
 | 
					int pa_base64_encode(const void *data, int size, char **str);
 | 
				
			||||||
int pa_base64_decode(const char *str, void *data);
 | 
					int pa_base64_decode(const char *str, void *data);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,6 +52,17 @@ PA_MODULE_LOAD_ONCE(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SERVICE_TYPE_SINK "_raop._tcp"
 | 
					#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[] = {
 | 
					static const char* const valid_modargs[] = {
 | 
				
			||||||
    NULL
 | 
					    NULL
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -63,16 +74,6 @@ struct tunnel {
 | 
				
			||||||
    uint32_t module_index;
 | 
					    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) {
 | 
					static unsigned tunnel_hash(const void *p) {
 | 
				
			||||||
    const struct tunnel *t = p;
 | 
					    const struct tunnel *t = p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,8 +106,8 @@ static int tunnel_compare(const void *a, const void *b) {
 | 
				
			||||||
static struct tunnel* tunnel_new(
 | 
					static struct tunnel* tunnel_new(
 | 
				
			||||||
        AvahiIfIndex interface, AvahiProtocol protocol,
 | 
					        AvahiIfIndex interface, AvahiProtocol protocol,
 | 
				
			||||||
        const char *name, const char *type, const char *domain) {
 | 
					        const char *name, const char *type, const char *domain) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct tunnel *t;
 | 
					    struct tunnel *t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    t = pa_xnew(struct tunnel, 1);
 | 
					    t = pa_xnew(struct tunnel, 1);
 | 
				
			||||||
    t->interface = interface;
 | 
					    t->interface = interface;
 | 
				
			||||||
    t->protocol = protocol;
 | 
					    t->protocol = protocol;
 | 
				
			||||||
| 
						 | 
					@ -114,6 +115,7 @@ static struct tunnel *tunnel_new(
 | 
				
			||||||
    t->type = pa_xstrdup(type);
 | 
					    t->type = pa_xstrdup(type);
 | 
				
			||||||
    t->domain = pa_xstrdup(domain);
 | 
					    t->domain = pa_xstrdup(domain);
 | 
				
			||||||
    t->module_index = PA_IDXSET_INVALID;
 | 
					    t->module_index = PA_IDXSET_INVALID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return t;
 | 
					    return t;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -134,21 +136,21 @@ static void resolver_cb(
 | 
				
			||||||
        AvahiStringList *txt,
 | 
					        AvahiStringList *txt,
 | 
				
			||||||
        AvahiLookupResultFlags flags,
 | 
					        AvahiLookupResultFlags flags,
 | 
				
			||||||
        void *userdata) {
 | 
					        void *userdata) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct userdata *u = userdata;
 | 
					    struct userdata *u = userdata;
 | 
				
			||||||
    struct tunnel *tnl;
 | 
					    struct tunnel *tnl;
 | 
				
			||||||
 | 
					    char *device = NULL, *nicename, *dname, *vname, *args;
 | 
				
			||||||
 | 
					    char at[AVAHI_ADDRESS_STR_MAX];
 | 
				
			||||||
 | 
					    AvahiStringList *l;
 | 
				
			||||||
 | 
					    pa_module *m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(u);
 | 
					    pa_assert(u);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tnl = tunnel_new(interface, protocol, name, type, domain);
 | 
					    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)));
 | 
					        pa_log("Resolving of '%s' failed: %s", name, avahi_strerror(avahi_client_errno(u->client)));
 | 
				
			||||||
    else {
 | 
					        goto  finish;
 | 
				
			||||||
        char *device = NULL, *nicename, *dname, *vname, *args;
 | 
					    }
 | 
				
			||||||
        char at[AVAHI_ADDRESS_STR_MAX];
 | 
					 | 
				
			||||||
        AvahiStringList *l;
 | 
					 | 
				
			||||||
        pa_module *m;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((nicename = strstr(name, "@"))) {
 | 
					    if ((nicename = strstr(name, "@"))) {
 | 
				
			||||||
        ++nicename;
 | 
					        ++nicename;
 | 
				
			||||||
| 
						 | 
					@ -165,10 +167,10 @@ static void resolver_cb(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        pa_log_debug("Found key: '%s' with value: '%s'", key, value);
 | 
					        pa_log_debug("Found key: '%s' with value: '%s'", key, value);
 | 
				
			||||||
        if (pa_streq(key, "device")) {
 | 
					        if (pa_streq(key, "device")) {
 | 
				
			||||||
                pa_xfree(device);
 | 
					 | 
				
			||||||
            device = value;
 | 
					            device = value;
 | 
				
			||||||
            value = NULL;
 | 
					            value = NULL;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        avahi_free(key);
 | 
					        avahi_free(key);
 | 
				
			||||||
        avahi_free(value);
 | 
					        avahi_free(value);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -184,6 +186,8 @@ static void resolver_cb(
 | 
				
			||||||
        pa_xfree(dname);
 | 
					        pa_xfree(dname);
 | 
				
			||||||
        goto finish;
 | 
					        goto finish;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    avahi_free(device);
 | 
				
			||||||
    pa_xfree(dname);
 | 
					    pa_xfree(dname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (nicename) {
 | 
					    if (nicename) {
 | 
				
			||||||
| 
						 | 
					@ -211,11 +215,8 @@ static void resolver_cb(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_xfree(vname);
 | 
					    pa_xfree(vname);
 | 
				
			||||||
    pa_xfree(args);
 | 
					    pa_xfree(args);
 | 
				
			||||||
        avahi_free(device);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
finish:
 | 
					finish:
 | 
				
			||||||
 | 
					 | 
				
			||||||
    avahi_service_resolver_free(r);
 | 
					    avahi_service_resolver_free(r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (tnl)
 | 
					    if (tnl)
 | 
				
			||||||
| 
						 | 
					@ -229,7 +230,6 @@ static void browser_cb(
 | 
				
			||||||
        const char *name, const char *type, const char *domain,
 | 
					        const char *name, const char *type, const char *domain,
 | 
				
			||||||
        AvahiLookupResultFlags flags,
 | 
					        AvahiLookupResultFlags flags,
 | 
				
			||||||
        void *userdata) {
 | 
					        void *userdata) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct userdata *u = userdata;
 | 
					    struct userdata *u = userdata;
 | 
				
			||||||
    struct tunnel *t;
 | 
					    struct tunnel *t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -248,7 +248,7 @@ static void browser_cb(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* We ignore the returned resolver object here, since the we don'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
 | 
					         * 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) {
 | 
					    } else if (event == AVAHI_BROWSER_REMOVE) {
 | 
				
			||||||
        struct tunnel *t2;
 | 
					        struct tunnel *t2;
 | 
				
			||||||
| 
						 | 
					@ -275,9 +275,7 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda
 | 
				
			||||||
        case AVAHI_CLIENT_S_REGISTERING:
 | 
					        case AVAHI_CLIENT_S_REGISTERING:
 | 
				
			||||||
        case AVAHI_CLIENT_S_RUNNING:
 | 
					        case AVAHI_CLIENT_S_RUNNING:
 | 
				
			||||||
        case AVAHI_CLIENT_S_COLLISION:
 | 
					        case AVAHI_CLIENT_S_COLLISION:
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (!u->sink_browser) {
 | 
					            if (!u->sink_browser) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (!(u->sink_browser = avahi_service_browser_new(
 | 
					                if (!(u->sink_browser = avahi_service_browser_new(
 | 
				
			||||||
                              c,
 | 
					                              c,
 | 
				
			||||||
                              AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
 | 
					                              AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
 | 
				
			||||||
| 
						 | 
					@ -299,16 +297,16 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                pa_log_debug("Avahi daemon disconnected.");
 | 
					                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))) {
 | 
					                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_log("avahi_client_new() failed: %s", avahi_strerror(error));
 | 
				
			||||||
                    pa_module_unload_request(u->module, true);
 | 
					                    pa_module_unload_request(u->module, true);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Fall through */
 | 
					            /* Fall through. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case AVAHI_CLIENT_CONNECTING:
 | 
					        case AVAHI_CLIENT_CONNECTING:
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (u->sink_browser) {
 | 
					            if (u->sink_browser) {
 | 
				
			||||||
                avahi_service_browser_free(u->sink_browser);
 | 
					                avahi_service_browser_free(u->sink_browser);
 | 
				
			||||||
                u->sink_browser = NULL;
 | 
					                u->sink_browser = NULL;
 | 
				
			||||||
| 
						 | 
					@ -316,12 +314,12 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        default: ;
 | 
					        default:
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa__init(pa_module *m) {
 | 
					int pa__init(pa_module *m) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct userdata *u;
 | 
					    struct userdata *u;
 | 
				
			||||||
    pa_modargs *ma = NULL;
 | 
					    pa_modargs *ma = NULL;
 | 
				
			||||||
    int error;
 | 
					    int error;
 | 
				
			||||||
| 
						 | 
					@ -360,6 +358,7 @@ fail:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa__done(pa_module *m) {
 | 
					void pa__done(pa_module *m) {
 | 
				
			||||||
    struct userdata *u;
 | 
					    struct userdata *u;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(m);
 | 
					    pa_assert(m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(u = m->userdata))
 | 
					    if (!(u = m->userdata))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,7 +124,7 @@ enum {
 | 
				
			||||||
    SINK_MESSAGE_RIP_SOCKET
 | 
					    SINK_MESSAGE_RIP_SOCKET
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Forward declaration */
 | 
					/* Forward declarations: */
 | 
				
			||||||
static void sink_set_volume_cb(pa_sink *);
 | 
					static void sink_set_volume_cb(pa_sink *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void on_connection(int fd, void *userdata) {
 | 
					static void on_connection(int fd, void *userdata) {
 | 
				
			||||||
| 
						 | 
					@ -143,7 +143,7 @@ static void on_connection(int fd, void*userdata) {
 | 
				
			||||||
        pa_sink_set_max_request(u->sink, PA_MAX((size_t) so_sndbuf, u->block_size));
 | 
					        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);
 | 
					    sink_set_volume_cb(u->sink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_log_debug("Connection authenticated, handing fd to IO thread...");
 | 
					    pa_log_debug("Connection authenticated, handing fd to IO thread...");
 | 
				
			||||||
| 
						 | 
					@ -174,7 +174,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    pa_smoother_pause(u->smoother, pa_rtclock_now());
 | 
					                    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) {
 | 
					                    if (u->fd >= 0) {
 | 
				
			||||||
                        pa_raop_flush(u->raop);
 | 
					                        pa_raop_flush(u->raop);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
| 
						 | 
					@ -187,7 +187,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
 | 
				
			||||||
                        pa_smoother_resume(u->smoother, pa_rtclock_now(), true);
 | 
					                        pa_smoother_resume(u->smoother, pa_rtclock_now(), true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        /* The connection can be closed when idle, so check to
 | 
					                        /* 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)
 | 
					                        if (u->fd < 0)
 | 
				
			||||||
                            pa_raop_connect(u->raop);
 | 
					                            pa_raop_connect(u->raop);
 | 
				
			||||||
                        else
 | 
					                        else
 | 
				
			||||||
| 
						 | 
					@ -226,7 +226,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
 | 
				
			||||||
            /*pollfd->events = */pollfd->revents = 0;
 | 
					            /*pollfd->events = */pollfd->revents = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (u->sink->thread_info.state == PA_SINK_SUSPENDED) {
 | 
					            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);
 | 
					                pa_raop_flush(u->raop);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
| 
						 | 
					@ -268,19 +268,19 @@ static void sink_set_volume_cb(pa_sink *s) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(u);
 | 
					    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)
 | 
					    if (s->muted)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Calculate the max volume of all channels.
 | 
					    /* Calculate the max volume of all channels.
 | 
				
			||||||
       We'll use this as our (single) volume on the APEX device and emulate
 | 
					     * We'll use this as our (single) volume on the APEX device and emulate
 | 
				
			||||||
       any variation in channel volumes in software */
 | 
					     * any variation in channel volumes in software. */
 | 
				
			||||||
    v = pa_cvolume_max(&s->real_volume);
 | 
					    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);
 | 
					    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_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_log_debug("Requested volume: %s", pa_cvolume_snprint_verbose(t, sizeof(t), &s->real_volume, &s->channel_map, false));
 | 
				
			||||||
| 
						 | 
					@ -289,7 +289,7 @@ static void sink_set_volume_cb(pa_sink *s) {
 | 
				
			||||||
                 pa_cvolume_snprint_verbose(t, sizeof(t), &s->soft_volume, &s->channel_map, true));
 | 
					                 pa_cvolume_snprint_verbose(t, sizeof(t), &s->soft_volume, &s->channel_map, true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Any necessary software volume manipulation is done so set
 | 
					    /* 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);
 | 
					    pa_raop_client_set_volume(u->raop, v);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -333,7 +333,7 @@ static void thread_func(void *userdata) {
 | 
				
			||||||
            struct pollfd *pollfd;
 | 
					            struct pollfd *pollfd;
 | 
				
			||||||
            pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
 | 
					            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) {
 | 
					            if (/*PA_SINK_IS_OPENED(u->sink->thread_info.state) && */pollfd->revents) {
 | 
				
			||||||
                pa_usec_t usec;
 | 
					                pa_usec_t usec;
 | 
				
			||||||
                int64_t n;
 | 
					                int64_t n;
 | 
				
			||||||
| 
						 | 
					@ -364,29 +364,29 @@ static void thread_func(void *userdata) {
 | 
				
			||||||
                        if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
 | 
					                        if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
 | 
				
			||||||
                            size_t rl;
 | 
					                            size_t rl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            /* We render real data */
 | 
					                            /* We render real data. */
 | 
				
			||||||
                            if (u->raw_memchunk.length <= 0) {
 | 
					                            if (u->raw_memchunk.length <= 0) {
 | 
				
			||||||
                                if (u->raw_memchunk.memblock)
 | 
					                                if (u->raw_memchunk.memblock)
 | 
				
			||||||
                                    pa_memblock_unref(u->raw_memchunk.memblock);
 | 
					                                    pa_memblock_unref(u->raw_memchunk.memblock);
 | 
				
			||||||
                                pa_memchunk_reset(&u->raw_memchunk);
 | 
					                                pa_memchunk_reset(&u->raw_memchunk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                /* Grab unencoded data */
 | 
					                                /* Grab unencoded data. */
 | 
				
			||||||
                                pa_sink_render(u->sink, u->block_size, &u->raw_memchunk);
 | 
					                                pa_sink_render(u->sink, u->block_size, &u->raw_memchunk);
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            pa_assert(u->raw_memchunk.length > 0);
 | 
					                            pa_assert(u->raw_memchunk.length > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            /* Encode it */
 | 
					                            /* Encode it. */
 | 
				
			||||||
                            rl = u->raw_memchunk.length;
 | 
					                            rl = u->raw_memchunk.length;
 | 
				
			||||||
                            u->encoding_overhead += u->next_encoding_overhead;
 | 
					                            u->encoding_overhead += u->next_encoding_overhead;
 | 
				
			||||||
                            pa_raop_client_encode_sample(u->raop, &u->raw_memchunk, &u->encoded_memchunk);
 | 
					                            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->next_encoding_overhead = (u->encoded_memchunk.length - (rl - u->raw_memchunk.length));
 | 
				
			||||||
                            u->encoding_ratio = u->encoded_memchunk.length / (rl - u->raw_memchunk.length);
 | 
					                            u->encoding_ratio = u->encoded_memchunk.length / (rl - u->raw_memchunk.length);
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            /* We render some silence into our memchunk */
 | 
					                            /* We render some silence into our memchunk. */
 | 
				
			||||||
                            memcpy(&u->encoded_memchunk, &silence, sizeof(pa_memchunk));
 | 
					                            memcpy(&u->encoded_memchunk, &silence, sizeof(pa_memchunk));
 | 
				
			||||||
                            pa_memblock_ref(silence.memblock);
 | 
					                            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->next_encoding_overhead = silence_overhead;
 | 
				
			||||||
                            u->encoding_ratio = silence_ratio;
 | 
					                            u->encoding_ratio = silence_ratio;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
| 
						 | 
					@ -405,8 +405,7 @@ static void thread_func(void *userdata) {
 | 
				
			||||||
                            continue;
 | 
					                            continue;
 | 
				
			||||||
                        else if (errno == EAGAIN) {
 | 
					                        else if (errno == EAGAIN) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            /* OK, we filled all socket buffers up
 | 
					                            /* OK, we filled all socket buffers up now. */
 | 
				
			||||||
                             * now. */
 | 
					 | 
				
			||||||
                            goto filled_up;
 | 
					                            goto filled_up;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
| 
						 | 
					@ -423,22 +422,21 @@ static void thread_func(void *userdata) {
 | 
				
			||||||
                        pollfd->revents = 0;
 | 
					                        pollfd->revents = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        if (u->encoded_memchunk.length > 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;
 | 
					                            u->encoding_overhead += u->next_encoding_overhead;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            /* OK, we wrote less that we asked for,
 | 
					                            /* OK, we wrote less that we asked for,
 | 
				
			||||||
                             * hence we can assume that the socket
 | 
					                             * hence we can assume that the socket
 | 
				
			||||||
                             * buffers are full now */
 | 
					                             * buffers are full now. */
 | 
				
			||||||
                            goto filled_up;
 | 
					                            goto filled_up;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            filled_up:
 | 
					            filled_up:
 | 
				
			||||||
 | 
					 | 
				
			||||||
                /* At this spot we know that the socket buffers are
 | 
					                /* At this spot we know that the socket buffers are
 | 
				
			||||||
                 * fully filled up. This is the best time to estimate
 | 
					                 * 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;
 | 
					                n = u->offset - u->encoding_overhead;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -460,7 +458,7 @@ static void thread_func(void *userdata) {
 | 
				
			||||||
                pa_smoother_put(u->smoother, pa_rtclock_now(), usec);
 | 
					                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;*/
 | 
					            pollfd->events = POLLOUT; /*PA_SINK_IS_OPENED(u->sink->thread_info.state)  ? POLLOUT : 0;*/
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -482,7 +480,7 @@ static void thread_func(void *userdata) {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                /* We expect this to happen on occasion if we are not sending data.
 | 
					                /* 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)
 | 
					                if (u->rtpoll_item)
 | 
				
			||||||
                    pa_rtpoll_item_free(u->rtpoll_item);
 | 
					                    pa_rtpoll_item_free(u->rtpoll_item);
 | 
				
			||||||
                u->rtpoll_item = NULL;
 | 
					                u->rtpoll_item = NULL;
 | 
				
			||||||
| 
						 | 
					@ -492,7 +490,7 @@ static void thread_func(void *userdata) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fail:
 | 
					fail:
 | 
				
			||||||
    /* If this was no regular exit from the loop we have to continue
 | 
					    /* 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_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_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,9 +95,9 @@ struct pa_raop_client {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Encryption Related bits */
 | 
					    /* Encryption Related bits */
 | 
				
			||||||
    AES_KEY aes;
 | 
					    AES_KEY aes;
 | 
				
			||||||
    uint8_t aes_iv[AES_CHUNKSIZE]; /* initialization vector 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_nv[AES_CHUNKSIZE]; /* Next vector for aes-cbc */
 | 
				
			||||||
    uint8_t aes_key[AES_CHUNKSIZE]; /* key for aes-cbc */
 | 
					    uint8_t aes_key[AES_CHUNKSIZE]; /* Key for aes-cbc */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_socket_client *sc;
 | 
					    pa_socket_client *sc;
 | 
				
			||||||
    int fd;
 | 
					    int fd;
 | 
				
			||||||
| 
						 | 
					@ -130,32 +130,32 @@ static inline void bit_writer(uint8_t **buffer, uint8_t *bit_pos, int *size, uin
 | 
				
			||||||
    if (!*bit_pos)
 | 
					    if (!*bit_pos)
 | 
				
			||||||
        *size += 1;
 | 
					        *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;
 | 
					    bits_left = 7 - *bit_pos  + 1;
 | 
				
			||||||
    /* Calc the overflow of bits in relation to how much space we have left... */
 | 
					    /* Calc the overflow of bits in relation to how much space we have left... */
 | 
				
			||||||
    bit_overflow = bits_left - data_bit_len;
 | 
					    bit_overflow = bits_left - data_bit_len;
 | 
				
			||||||
    if (bit_overflow >= 0) {
 | 
					    if (bit_overflow >= 0) {
 | 
				
			||||||
        /* We can fit the new data in our current byte */
 | 
					        /* 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 */
 | 
					         * As we write from MSB->LSB we need to left shift by the overflow amount. */
 | 
				
			||||||
        bit_data = data << bit_overflow;
 | 
					        bit_data = data << bit_overflow;
 | 
				
			||||||
        if (*bit_pos)
 | 
					        if (*bit_pos)
 | 
				
			||||||
            **buffer |= bit_data;
 | 
					            **buffer |= bit_data;
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            **buffer = bit_data;
 | 
					            **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) {
 | 
					        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;
 | 
					            *buffer += 1;
 | 
				
			||||||
            *bit_pos = 0;
 | 
					            *bit_pos = 0;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            *bit_pos += data_bit_len;
 | 
					            *bit_pos += data_bit_len;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        /* bit_overflow is negative, there for we will need a new byte from our buffer */
 | 
					        /* 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 */
 | 
					         * Firstly fill up what's left in the current byte. */
 | 
				
			||||||
        bit_data = data >> -bit_overflow;
 | 
					        bit_data = data >> -bit_overflow;
 | 
				
			||||||
        **buffer |= bit_data;
 | 
					        **buffer |= bit_data;
 | 
				
			||||||
        /* Increment our buffer pointer and size counter*/
 | 
					        /* Increment our buffer pointer and size counter. */
 | 
				
			||||||
        *buffer += 1;
 | 
					        *buffer += 1;
 | 
				
			||||||
        *size += 1;
 | 
					        *size += 1;
 | 
				
			||||||
        **buffer = data << (8 + bit_overflow);
 | 
					        **buffer = data << (8 + bit_overflow);
 | 
				
			||||||
| 
						 | 
					@ -263,12 +263,12 @@ static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* he
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            pa_log_debug("RAOP: CONNECTED");
 | 
					            pa_log_debug("RAOP: CONNECTED");
 | 
				
			||||||
            ip = pa_rtsp_localip(c->rtsp);
 | 
					            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);
 | 
					            url = pa_sprintf_malloc("rtsp://%s/%s", ip, c->sid);
 | 
				
			||||||
            pa_rtsp_set_url(c->rtsp, url);
 | 
					            pa_rtsp_set_url(c->rtsp, url);
 | 
				
			||||||
            pa_xfree(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);
 | 
					            i = rsa_encrypt(c->aes_key, AES_CHUNKSIZE, rsakey);
 | 
				
			||||||
            pa_base64_encode(rsakey, i, &key);
 | 
					            pa_base64_encode(rsakey, i, &key);
 | 
				
			||||||
            rtrimchar(key, '=');
 | 
					            rtrimchar(key, '=');
 | 
				
			||||||
| 
						 | 
					@ -367,7 +367,7 @@ static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* he
 | 
				
			||||||
            pa_rtsp_client_free(c->rtsp);
 | 
					            pa_rtsp_client_free(c->rtsp);
 | 
				
			||||||
            c->rtsp = NULL;
 | 
					            c->rtsp = NULL;
 | 
				
			||||||
            if (c->fd > 0) {
 | 
					            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;
 | 
					                c->fd = -1;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (c->sc) {
 | 
					            if (c->sc) {
 | 
				
			||||||
| 
						 | 
					@ -410,6 +410,7 @@ pa_raop_client* pa_raop_client_new(pa_core *core, const char* host) {
 | 
				
			||||||
        pa_raop_client_free(c);
 | 
					        pa_raop_client_free(c);
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return c;
 | 
					    return c;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -441,19 +442,20 @@ int pa_raop_connect(pa_raop_client* c) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c->rtsp = pa_rtsp_client_new(c->core->mainloop, c->host, c->port, "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 */
 | 
					    /* Initialise the AES encryption system. */
 | 
				
			||||||
    pa_random(c->aes_iv, sizeof(c->aes_iv));
 | 
					    pa_random(c->aes_iv, sizeof(c->aes_iv));
 | 
				
			||||||
    pa_random(c->aes_key, sizeof(c->aes_key));
 | 
					    pa_random(c->aes_key, sizeof(c->aes_key));
 | 
				
			||||||
    memcpy(c->aes_nv, c->aes_iv, sizeof(c->aes_nv));
 | 
					    memcpy(c->aes_nv, c->aes_iv, sizeof(c->aes_nv));
 | 
				
			||||||
    AES_set_encrypt_key(c->aes_key, 128, &c->aes);
 | 
					    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));
 | 
					    pa_random(&rand_data, sizeof(rand_data));
 | 
				
			||||||
    c->sid = pa_sprintf_malloc("%u", rand_data.a);
 | 
					    c->sid = pa_sprintf_malloc("%u", rand_data.a);
 | 
				
			||||||
    sci = pa_sprintf_malloc("%08x%08x",rand_data.b, rand_data.c);
 | 
					    sci = pa_sprintf_malloc("%08x%08x",rand_data.b, rand_data.c);
 | 
				
			||||||
    pa_rtsp_add_header(c->rtsp, "Client-Instance", sci);
 | 
					    pa_rtsp_add_header(c->rtsp, "Client-Instance", sci);
 | 
				
			||||||
    pa_xfree(sci);
 | 
					    pa_xfree(sci);
 | 
				
			||||||
    pa_rtsp_set_callback(c->rtsp, rtsp_cb, c);
 | 
					    pa_rtsp_set_callback(c->rtsp, rtsp_cb, c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return pa_rtsp_connect(c->rtsp);
 | 
					    return pa_rtsp_connect(c->rtsp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -479,9 +481,10 @@ int pa_raop_client_set_volume(pa_raop_client* c, pa_volume_t volume) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    param = pa_sprintf_malloc("volume: %0.6f\r\n",  db);
 | 
					    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);
 | 
					    rv = pa_rtsp_setparameter(c->rtsp, param);
 | 
				
			||||||
    pa_xfree(param);
 | 
					    pa_xfree(param);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return rv;
 | 
					    return rv;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -513,25 +516,25 @@ int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchun
 | 
				
			||||||
    bsize = (int)(raw->length / 4);
 | 
					    bsize = (int)(raw->length / 4);
 | 
				
			||||||
    length = bsize * 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;
 | 
					    bufmax = length + header_size + 16;
 | 
				
			||||||
    pa_memchunk_reset(encoded);
 | 
					    pa_memchunk_reset(encoded);
 | 
				
			||||||
    encoded->memblock = pa_memblock_new(c->core->mempool, bufmax);
 | 
					    encoded->memblock = pa_memblock_new(c->core->mempool, bufmax);
 | 
				
			||||||
    b = pa_memblock_acquire(encoded->memblock);
 | 
					    b = pa_memblock_acquire(encoded->memblock);
 | 
				
			||||||
    memcpy(b, header, header_size);
 | 
					    memcpy(b, header, header_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Now write the actual samples */
 | 
					    /* Now write the actual samples. */
 | 
				
			||||||
    bp = b + header_size;
 | 
					    bp = b + header_size;
 | 
				
			||||||
    size = bpos = 0;
 | 
					    size = bpos = 0;
 | 
				
			||||||
    bit_writer(&bp,&bpos,&size,1,3); /* channel=1, stereo */
 | 
					    bit_writer(&bp,&bpos,&size,1,3); /* channel=1, stereo */
 | 
				
			||||||
    bit_writer(&bp,&bpos,&size,0,4); /* unknown */
 | 
					    bit_writer(&bp,&bpos,&size,0,4); /* Unknown */
 | 
				
			||||||
    bit_writer(&bp,&bpos,&size,0,8); /* unknown */
 | 
					    bit_writer(&bp,&bpos,&size,0,8); /* Unknown */
 | 
				
			||||||
    bit_writer(&bp,&bpos,&size,0,4); /* unknown */
 | 
					    bit_writer(&bp,&bpos,&size,0,4); /* Unknown */
 | 
				
			||||||
    bit_writer(&bp,&bpos,&size,1,1); /* hassize */
 | 
					    bit_writer(&bp,&bpos,&size,1,1); /* Hassize */
 | 
				
			||||||
    bit_writer(&bp,&bpos,&size,0,2); /* unused */
 | 
					    bit_writer(&bp,&bpos,&size,0,2); /* Unused */
 | 
				
			||||||
    bit_writer(&bp,&bpos,&size,1,1); /* is-not-compressed */
 | 
					    bit_writer(&bp,&bpos,&size,1,1); /* Is-not-compressed */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* size of data, integer, big endian */
 | 
					    /* Size of data, integer, big endian. */
 | 
				
			||||||
    bit_writer(&bp,&bpos,&size,(bsize>>24)&0xff,8);
 | 
					    bit_writer(&bp,&bpos,&size,(bsize>>24)&0xff,8);
 | 
				
			||||||
    bit_writer(&bp,&bpos,&size,(bsize>>16)&0xff,8);
 | 
					    bit_writer(&bp,&bpos,&size,(bsize>>16)&0xff,8);
 | 
				
			||||||
    bit_writer(&bp,&bpos,&size,(bsize>>8)&0xff,8);
 | 
					    bit_writer(&bp,&bpos,&size,(bsize>>8)&0xff,8);
 | 
				
			||||||
| 
						 | 
					@ -540,7 +543,7 @@ int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchun
 | 
				
			||||||
    ibp = p = pa_memblock_acquire(raw->memblock);
 | 
					    ibp = p = pa_memblock_acquire(raw->memblock);
 | 
				
			||||||
    maxibp = p + raw->length - 4;
 | 
					    maxibp = p + raw->length - 4;
 | 
				
			||||||
    while (ibp <= maxibp) {
 | 
					    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+1),8);
 | 
				
			||||||
        bit_writer(&bp,&bpos,&size,*(ibp+0),8);
 | 
					        bit_writer(&bp,&bpos,&size,*(ibp+0),8);
 | 
				
			||||||
        bit_writer(&bp,&bpos,&size,*(ibp+3),8);
 | 
					        bit_writer(&bp,&bpos,&size,*(ibp+3),8);
 | 
				
			||||||
| 
						 | 
					@ -552,15 +555,15 @@ int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchun
 | 
				
			||||||
    pa_memblock_release(raw->memblock);
 | 
					    pa_memblock_release(raw->memblock);
 | 
				
			||||||
    encoded->length = header_size + size;
 | 
					    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;
 | 
					    len = size + header_size - 4;
 | 
				
			||||||
    *(b + 2) = len >> 8;
 | 
					    *(b + 2) = len >> 8;
 | 
				
			||||||
    *(b + 3) = len & 0xff;
 | 
					    *(b + 3) = len & 0xff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* encrypt our data */
 | 
					    /* Encrypt our data. */
 | 
				
			||||||
    aes_encrypt(c, (b + header_size), size);
 | 
					    aes_encrypt(c, (b + header_size), size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* We're done with the chunk */
 | 
					    /* We're done with the chunk. */
 | 
				
			||||||
    pa_memblock_release(encoded->memblock);
 | 
					    pa_memblock_release(encoded->memblock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -444,12 +444,17 @@ static int rtsp_exec(pa_rtsp_client* c, const char* cmd,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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);
 | 
					    pa_assert(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!sdp)
 | 
					    if (!sdp)
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c->state = STATE_ANNOUNCE;
 | 
					    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) {
 | 
					int pa_rtsp_setup(pa_rtsp_client *c) {
 | 
				
			||||||
| 
						 | 
					@ -463,16 +468,18 @@ int pa_rtsp_setup(pa_rtsp_client* c) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c->state = STATE_SETUP;
 | 
					    c->state = STATE_SETUP;
 | 
				
			||||||
    rv = rtsp_exec(c, "SETUP", NULL, NULL, 1, headers);
 | 
					    rv = rtsp_exec(c, "SETUP", NULL, NULL, 1, headers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_headerlist_free(headers);
 | 
					    pa_headerlist_free(headers);
 | 
				
			||||||
    return rv;
 | 
					    return rv;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa_rtsp_record(pa_rtsp_client *c, uint16_t *seq, uint32_t *rtptime) {
 | 
					int pa_rtsp_record(pa_rtsp_client *c, uint16_t *seq, uint32_t *rtptime) {
 | 
				
			||||||
    pa_headerlist *headers;
 | 
					    pa_headerlist *headers;
 | 
				
			||||||
    int rv;
 | 
					 | 
				
			||||||
    char *info;
 | 
					    char *info;
 | 
				
			||||||
 | 
					    int rv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(c);
 | 
					    pa_assert(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!c->session) {
 | 
					    if (!c->session) {
 | 
				
			||||||
        /* No session in progress */
 | 
					        /* No session in progress */
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
| 
						 | 
					@ -489,30 +496,40 @@ int pa_rtsp_record(pa_rtsp_client* c, uint16_t* seq, uint32_t* rtptime) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c->state = STATE_RECORD;
 | 
					    c->state = STATE_RECORD;
 | 
				
			||||||
    rv = rtsp_exec(c, "RECORD", NULL, NULL, 1, headers);
 | 
					    rv = rtsp_exec(c, "RECORD", NULL, NULL, 1, headers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_headerlist_free(headers);
 | 
					    pa_headerlist_free(headers);
 | 
				
			||||||
    return rv;
 | 
					    return rv;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa_rtsp_teardown(pa_rtsp_client *c) {
 | 
					int pa_rtsp_teardown(pa_rtsp_client *c) {
 | 
				
			||||||
 | 
					    int rv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(c);
 | 
					    pa_assert(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c->state = STATE_TEARDOWN;
 | 
					    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);
 | 
					    pa_assert(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!param)
 | 
					    if (!param)
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c->state = STATE_SET_PARAMETER;
 | 
					    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) {
 | 
					int pa_rtsp_flush(pa_rtsp_client *c, uint16_t seq, uint32_t rtptime) {
 | 
				
			||||||
    pa_headerlist* headers;
 | 
					    pa_headerlist* headers;
 | 
				
			||||||
    int rv;
 | 
					 | 
				
			||||||
    char *info;
 | 
					    char *info;
 | 
				
			||||||
 | 
					    int rv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(c);
 | 
					    pa_assert(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -523,6 +540,7 @@ int pa_rtsp_flush(pa_rtsp_client *c, uint16_t seq, uint32_t rtptime) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c->state = STATE_FLUSH;
 | 
					    c->state = STATE_FLUSH;
 | 
				
			||||||
    rv = rtsp_exec(c, "FLUSH", NULL, NULL, 1, headers);
 | 
					    rv = rtsp_exec(c, "FLUSH", NULL, NULL, 1, headers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_headerlist_free(headers);
 | 
					    pa_headerlist_free(headers);
 | 
				
			||||||
    return rv;
 | 
					    return rv;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue