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/>.
 | 
			
		||||
***/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
/***
 | 
			
		||||
  This file was originally inspired by a file developed by
 | 
			
		||||
  Kungliga Tekniska högskolan
 | 
			
		||||
*/
 | 
			
		||||
***/
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -37,11 +37,17 @@ static const char base64_chars[] =
 | 
			
		|||
    "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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -73,8 +79,10 @@ int pa_base64_encode(const void *data, int size, char **str) {
 | 
			
		|||
            p[2] = '=';
 | 
			
		||||
        p += 4;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *p = 0;
 | 
			
		||||
    *str = s;
 | 
			
		||||
 | 
			
		||||
    return strlen(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +92,7 @@ static unsigned int token_decode(const char *token) {
 | 
			
		|||
    int i;
 | 
			
		||||
    unsigned int val = 0;
 | 
			
		||||
    int marker = 0;
 | 
			
		||||
 | 
			
		||||
    if (strlen(token) < 4)
 | 
			
		||||
        return DECODE_ERROR;
 | 
			
		||||
    for (i = 0; i < 4; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -99,8 +108,10 @@ static unsigned int token_decode(const char *token) {
 | 
			
		|||
            val += lpos;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (marker > 2)
 | 
			
		||||
        return DECODE_ERROR;
 | 
			
		||||
 | 
			
		||||
    return (marker << 24) | val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -120,5 +131,6 @@ int pa_base64_decode(const char *str, void *data) {
 | 
			
		|||
        if (marker < 1)
 | 
			
		||||
            *q++ = val & 0xff;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return q - (unsigned char *) data;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,10 +21,10 @@
 | 
			
		|||
  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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,6 +52,17 @@ PA_MODULE_LOAD_ONCE(true);
 | 
			
		|||
 | 
			
		||||
#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
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -63,16 +74,6 @@ struct tunnel {
 | 
			
		|||
    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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -102,11 +103,11 @@ static int tunnel_compare(const void *a, const void *b) {
 | 
			
		|||
    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;
 | 
			
		||||
| 
						 | 
				
			
			@ -114,6 +115,7 @@ static struct tunnel *tunnel_new(
 | 
			
		|||
    t->type = pa_xstrdup(type);
 | 
			
		||||
    t->domain = pa_xstrdup(domain);
 | 
			
		||||
    t->module_index = PA_IDXSET_INVALID;
 | 
			
		||||
 | 
			
		||||
    return t;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -134,88 +136,87 @@ static void resolver_cb(
 | 
			
		|||
        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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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")) {
 | 
			
		||||
                pa_xfree(device);
 | 
			
		||||
                device = value;
 | 
			
		||||
                value = NULL;
 | 
			
		||||
            }
 | 
			
		||||
            avahi_free(key);
 | 
			
		||||
            avahi_free(value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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;
 | 
			
		||||
        }
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
        goto  finish;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
finish:
 | 
			
		||||
    if ((nicename = strstr(name, "@"))) {
 | 
			
		||||
        ++nicename;
 | 
			
		||||
        if (strlen(nicename) > 0) {
 | 
			
		||||
            pa_log_debug("Found RAOP: %s", nicename);
 | 
			
		||||
            nicename = pa_escape(nicename, "\"'");
 | 
			
		||||
        } else
 | 
			
		||||
            nicename = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        avahi_free(key);
 | 
			
		||||
        avahi_free(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
finish:
 | 
			
		||||
    avahi_service_resolver_free(r);
 | 
			
		||||
 | 
			
		||||
    if (tnl)
 | 
			
		||||
| 
						 | 
				
			
			@ -229,7 +230,6 @@ static void browser_cb(
 | 
			
		|||
        const char *name, const char *type, const char *domain,
 | 
			
		||||
        AvahiLookupResultFlags flags,
 | 
			
		||||
        void *userdata) {
 | 
			
		||||
 | 
			
		||||
    struct userdata *u = userdata;
 | 
			
		||||
    struct tunnel *t;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -248,7 +248,7 @@ static void browser_cb(
 | 
			
		|||
 | 
			
		||||
        /* 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;
 | 
			
		||||
| 
						 | 
				
			
			@ -275,9 +275,7 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda
 | 
			
		|||
        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,
 | 
			
		||||
| 
						 | 
				
			
			@ -299,16 +297,16 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda
 | 
			
		|||
 | 
			
		||||
                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;
 | 
			
		||||
| 
						 | 
				
			
			@ -316,12 +314,12 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda
 | 
			
		|||
 | 
			
		||||
            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;
 | 
			
		||||
| 
						 | 
				
			
			@ -358,8 +356,9 @@ fail:
 | 
			
		|||
    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))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -124,10 +124,10 @@ enum {
 | 
			
		|||
    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;
 | 
			
		||||
| 
						 | 
				
			
			@ -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));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Set the initial volume */
 | 
			
		||||
    /* Set the initial volume. */
 | 
			
		||||
    sink_set_volume_cb(u->sink);
 | 
			
		||||
 | 
			
		||||
    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());
 | 
			
		||||
 | 
			
		||||
                    /* Issue a FLUSH if we are connected */
 | 
			
		||||
                    /* Issue a FLUSH if we are connected. */
 | 
			
		||||
                    if (u->fd >= 0) {
 | 
			
		||||
                        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);
 | 
			
		||||
 | 
			
		||||
                        /* 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
 | 
			
		||||
| 
						 | 
				
			
			@ -226,7 +226,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
 | 
			
		|||
            /*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;
 | 
			
		||||
| 
						 | 
				
			
			@ -268,19 +268,19 @@ static void sink_set_volume_cb(pa_sink *s) {
 | 
			
		|||
 | 
			
		||||
    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));
 | 
			
		||||
| 
						 | 
				
			
			@ -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));
 | 
			
		||||
 | 
			
		||||
    /* 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -333,7 +333,7 @@ static void thread_func(void *userdata) {
 | 
			
		|||
            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;
 | 
			
		||||
| 
						 | 
				
			
			@ -364,29 +364,29 @@ static void thread_func(void *userdata) {
 | 
			
		|||
                        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;
 | 
			
		||||
                        }
 | 
			
		||||
| 
						 | 
				
			
			@ -405,8 +405,7 @@ static void thread_func(void *userdata) {
 | 
			
		|||
                            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 {
 | 
			
		||||
| 
						 | 
				
			
			@ -423,22 +422,21 @@ static void thread_func(void *userdata) {
 | 
			
		|||
                        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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -460,7 +458,7 @@ static void thread_func(void *userdata) {
 | 
			
		|||
                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;*/
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -482,7 +480,7 @@ static void thread_func(void *userdata) {
 | 
			
		|||
                }
 | 
			
		||||
 | 
			
		||||
                /* 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;
 | 
			
		||||
| 
						 | 
				
			
			@ -492,7 +490,7 @@ static void thread_func(void *userdata) {
 | 
			
		|||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -502,7 +500,7 @@ finish:
 | 
			
		|||
    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;
 | 
			
		||||
| 
						 | 
				
			
			@ -645,7 +643,7 @@ int pa__get_n_used(pa_module *m) {
 | 
			
		|||
    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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -95,9 +95,9 @@ struct pa_raop_client {
 | 
			
		|||
 | 
			
		||||
    /* 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;
 | 
			
		||||
| 
						 | 
				
			
			@ -106,9 +106,9 @@ struct pa_raop_client {
 | 
			
		|||
    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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -130,32 +130,32 @@ static inline void bit_writer(uint8_t **buffer, uint8_t *bit_pos, int *size, uin
 | 
			
		|||
    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);
 | 
			
		||||
| 
						 | 
				
			
			@ -191,7 +191,7 @@ static int rsa_encrypt(uint8_t *text, int len, uint8_t *res) {
 | 
			
		|||
    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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -246,8 +246,8 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata
 | 
			
		|||
    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);
 | 
			
		||||
| 
						 | 
				
			
			@ -263,12 +263,12 @@ static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* he
 | 
			
		|||
 | 
			
		||||
            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, '=');
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
            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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -381,7 +381,7 @@ static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* he
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -410,10 +410,11 @@ pa_raop_client* pa_raop_client_new(pa_core *core, const char* host) {
 | 
			
		|||
        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)
 | 
			
		||||
| 
						 | 
				
			
			@ -424,7 +425,7 @@ void pa_raop_client_free(pa_raop_client* c) {
 | 
			
		|||
    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;
 | 
			
		||||
| 
						 | 
				
			
			@ -441,30 +442,31 @@ 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)");
 | 
			
		||||
 | 
			
		||||
    /* 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;
 | 
			
		||||
| 
						 | 
				
			
			@ -479,13 +481,14 @@ int pa_raop_client_set_volume(pa_raop_client* c, pa_volume_t volume) {
 | 
			
		|||
 | 
			
		||||
    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;
 | 
			
		||||
| 
						 | 
				
			
			@ -513,25 +516,25 @@ int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchun
 | 
			
		|||
    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 */
 | 
			
		||||
    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 */
 | 
			
		||||
    /* 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);
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
    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);
 | 
			
		||||
| 
						 | 
				
			
			@ -552,28 +555,28 @@ int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchun
 | 
			
		|||
    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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,19 +24,19 @@
 | 
			
		|||
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,7 +73,7 @@ struct pa_rtsp_client {
 | 
			
		|||
    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);
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +94,7 @@ pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char* hostna
 | 
			
		|||
    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)
 | 
			
		||||
| 
						 | 
				
			
			@ -355,25 +355,25 @@ void pa_rtsp_disconnect(pa_rtsp_client *c) {
 | 
			
		|||
    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);
 | 
			
		||||
| 
						 | 
				
			
			@ -381,19 +381,19 @@ void pa_rtsp_add_header(pa_rtsp_client *c, const char* key, const char* 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);
 | 
			
		||||
| 
						 | 
				
			
			@ -443,17 +443,22 @@ static int rtsp_exec(pa_rtsp_client* c, const char* cmd,
 | 
			
		|||
    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);
 | 
			
		||||
| 
						 | 
				
			
			@ -463,16 +468,18 @@ int pa_rtsp_setup(pa_rtsp_client* 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;
 | 
			
		||||
| 
						 | 
				
			
			@ -489,30 +496,40 @@ int pa_rtsp_record(pa_rtsp_client* c, uint16_t* seq, uint32_t* rtptime) {
 | 
			
		|||
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -523,6 +540,7 @@ int pa_rtsp_flush(pa_rtsp_client *c, uint16_t seq, uint32_t rtptime) {
 | 
			
		|||
 | 
			
		||||
    c->state = STATE_FLUSH;
 | 
			
		||||
    rv = rtsp_exec(c, "FLUSH", NULL, NULL, 1, headers);
 | 
			
		||||
 | 
			
		||||
    pa_headerlist_free(headers);
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,29 +41,29 @@ typedef enum {
 | 
			
		|||
  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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue