[PATCH 1/2] libpulse: Support new environment variable: PULSE_PROTOCOL_VERSION_LIMIT.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



---
 src/pulse/context.c  |   53 +++++++++++++++++++++++++++++++++++++------------
 src/pulse/internal.h |    4 ++-
 2 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/src/pulse/context.c b/src/pulse/context.c
index 1480af5..317377d 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -431,27 +431,29 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
             pa_tagstruct *reply;
             pa_bool_t shm_on_remote = FALSE;
 
-            if (pa_tagstruct_getu32(t, &c->version) < 0 ||
+            if (pa_tagstruct_getu32(t, &c->server_protocol_version) < 0 ||
                 !pa_tagstruct_eof(t)) {
                 pa_context_fail(c, PA_ERR_PROTOCOL);
                 goto finish;
             }
 
+            /* Starting with protocol version 13 the MSB of the version
+               tag reflects if shm is available for this connection or
+               not. */
+            if (c->server_protocol_version >= 13) {
+                shm_on_remote = !!(c->server_protocol_version & 0x80000000U);
+                c->server_protocol_version &= 0x7FFFFFFFU;
+            }
+
+            c->version = PA_MIN(c->server_protocol_version, c->protocol_version_limit);
+
             /* Minimum supported version */
             if (c->version < 8) {
                 pa_context_fail(c, PA_ERR_VERSION);
                 goto finish;
             }
 
-            /* Starting with protocol version 13 the MSB of the version
-               tag reflects if shm is available for this connection or
-               not. */
-            if (c->version >= 13) {
-                shm_on_remote = !!(c->version & 0x80000000U);
-                c->version &= 0x7FFFFFFFU;
-            }
-
-            pa_log_debug("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION);
+            pa_log_debug("Protocol version: remote %u, local %u, effective %u", c->server_protocol_version, PA_PROTOCOL_VERSION, c->version);
 
             /* Enable shared memory support if possible */
             if (c->do_shm)
@@ -512,6 +514,7 @@ finish:
 static void setup_context(pa_context *c, pa_iochannel *io) {
     pa_tagstruct *t;
     uint32_t tag;
+    char *d;
 
     pa_assert(c);
     pa_assert(io);
@@ -539,9 +542,33 @@ static void setup_context(pa_context *c, pa_iochannel *io) {
 
     pa_log_debug("SHM possible: %s", pa_yes_no(c->do_shm));
 
+    c->protocol_version_limit = PA_PROTOCOL_VERSION;
+
+    /* If PULSE_PROTOCOL_VERSION_LIMIT is set, then we lie to the
+     * server about the protocol version that we support.
+     *
+     * This environment variable exists just to work around the
+     * protocol incompatibility in the N900 version of Pulseaudio:
+     * it says that it supports v16, but it's not the official v16.
+     * V15 works fine on the N900, so setting this environment
+     * variable to "15" on a remote client will avoid triggering the
+     * incompatibility. */
+    if ((d = getenv("PULSE_PROTOCOL_VERSION_LIMIT")) && *d) {
+        if (pa_atou(d, &c->protocol_version_limit) >= 0) {
+            if ((c->protocol_version_limit >= 8) && (c->protocol_version_limit <= PA_PROTOCOL_VERSION))
+                pa_log_debug("Limiting the protocol version to %u.", c->protocol_version_limit);
+            else {
+                pa_log_warn("Environment variable PULSE_PROTOCOL_VERSION_LIMIT is set to %u, which is outside the supported "
+                            "range of 8-%u. Ignoring the variable.", c->protocol_version_limit, PA_PROTOCOL_VERSION);
+                c->protocol_version_limit = PA_PROTOCOL_VERSION;
+            }
+        } else
+            pa_log_warn("Failed to parse environment variable PULSE_PROTOCOL_VERSION_LIMIT.");
+    }
+
     /* Starting with protocol version 13 we use the MSB of the version
      * tag for informing the other side if we could do SHM or not */
-    pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION | (c->do_shm ? 0x80000000U : 0));
+    pa_tagstruct_putu32(t, c->protocol_version_limit | (c->do_shm ? 0x80000000U : 0));
     pa_tagstruct_put_arbitrary(t, c->conf->cookie, sizeof(c->conf->cookie));
 
 #ifdef HAVE_CREDS
@@ -1304,7 +1331,7 @@ const char* pa_context_get_server(pa_context *c) {
 }
 
 uint32_t pa_context_get_protocol_version(pa_context *c) {
-    return PA_PROTOCOL_VERSION;
+    return c->protocol_version_limit;
 }
 
 uint32_t pa_context_get_server_protocol_version(pa_context *c) {
@@ -1314,7 +1341,7 @@ uint32_t pa_context_get_server_protocol_version(pa_context *c) {
     PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
     PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, PA_INVALID_INDEX);
 
-    return c->version;
+    return c->server_protocol_version;
 }
 
 pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag) {
diff --git a/src/pulse/internal.h b/src/pulse/internal.h
index 40f6804..5d5d431 100644
--- a/src/pulse/internal.h
+++ b/src/pulse/internal.h
@@ -69,7 +69,9 @@ struct pa_context {
     PA_LLIST_HEAD(pa_stream, streams);
     PA_LLIST_HEAD(pa_operation, operations);
 
-    uint32_t version;
+    uint32_t version; /* min(server_protocol_version, protocol_version_limit) */
+    uint32_t server_protocol_version;
+    uint32_t protocol_version_limit;
     uint32_t ctag;
     uint32_t csyncid;
     int error;
-- 
1.7.5.3



[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux