AC_SUBST(PACKAGE_URL, [http://0pointer.de/lennart/projects/polypaudio/])
AC_SUBST(PA_API_VERSION, 8)
+AC_SUBST(PA_PROTOCOL_VERSION, 8)
if type -p stow > /dev/null && test -d /usr/local/stow ; then
AC_MSG_NOTICE([*** Found /usr/local/stow: default install prefix set to /usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION} ***])
switch(c->state) {
case PA_CONTEXT_AUTHORIZING: {
pa_tagstruct *reply;
+
+ if (pa_tagstruct_getu32(t, &c->version) < 0 ||
+ !pa_tagstruct_eof(t)) {
+ pa_context_fail(c, PA_ERR_PROTOCOL);
+ goto finish;
+ }
+
+ /* Minimum supported version */
+ if (c->version < 8) {
+ pa_context_fail(c, PA_ERR_VERSION);
+ goto finish;
+ }
+
reply = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
pa_tagstruct_puts(reply, c->name);
pa_pstream_send_tagstruct(c->pstream, reply);
}
t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag);
+ pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION);
pa_tagstruct_put_arbitrary(t, c->conf->cookie, sizeof(c->conf->cookie));
pa_pstream_send_tagstruct_with_creds(c->pstream, t, 1);
pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c);
return c->server;
}
+uint32_t pa_context_get_protocol_version(pa_context *c) {
+ return PA_PROTOCOL_VERSION;
+}
+
+uint32_t pa_context_get_server_protocol_version(pa_context *c) {
+ assert(c);
+ assert(c->ref >= 1);
+
+ return c->version;
+}
+
pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag) {
pa_tagstruct *t;
/** Return the server name this context is connected to. \since 0.7 */
const char* pa_context_get_server(pa_context *c);
+/** Return the protocol version of the library. \since 0.8 */
+uint32_t pa_context_get_protocol_version(pa_context *c);
+
+/** Return the protocol version of the connected server. \since 0.8 */
+uint32_t pa_context_get_server_protocol_version(pa_context *c);
+
PA_C_DECL_END
#endif
PA_ERR_MODINITFAILED, /**< Module initialization failed */
PA_ERR_BADSTATE, /**< Bad state */
PA_ERR_NODATA, /**< No data */
+ PA_ERR_VERSION, /**< Incompatible protocol version \since 0.8 */
PA_ERR_MAX /**< Not really an error but the first invalid error code */
};
[PA_ERR_MODINITFAILED] = "Module initalization failed",
[PA_ERR_BADSTATE] = "Bad state",
[PA_ERR_NODATA] = "No data",
+ [PA_ERR_VERSION] = "Incompatible protocol version",
};
const char*pa_strerror(int error) {
PA_LLIST_HEAD(pa_stream, streams);
PA_LLIST_HEAD(pa_operation, operations);
+ uint32_t version;
uint32_t ctag;
uint32_t csyncid;
uint32_t error;
* PA_API_VERSION undefined. */
#define PA_API_VERSION @PA_API_VERSION@
+/** The current protocol version. Version 8 relates to polypaudio 0.8.
+ * \since 0.8 */
+#define PA_PROTOCOL_VERSION @PA_PROTOCOL_VERSION@
+
PA_C_DECL_END
#endif
#include <stdlib.h>
#include <unistd.h>
+#include <polyp/version.h>
+
#include <polypcore/native-common.h>
#include <polypcore/packet.h>
#include <polypcore/client.h>
struct connection {
int authorized;
+ uint32_t version;
pa_protocol_native *protocol;
pa_client *client;
pa_pstream *pstream;
static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
struct connection *c = userdata;
const void*cookie;
+ pa_tagstruct *reply;
assert(c && t);
- if (pa_tagstruct_get_arbitrary(t, &cookie, PA_NATIVE_COOKIE_LENGTH) < 0 ||
+ if (pa_tagstruct_getu32(t, &c->version) < 0 ||
+ pa_tagstruct_get_arbitrary(t, &cookie, PA_NATIVE_COOKIE_LENGTH) < 0 ||
!pa_tagstruct_eof(t)) {
protocol_error(c);
return;
}
+ /* Minimum supported version */
+ if (c->version < 8) {
+ pa_pstream_send_error(c->pstream, tag, PA_ERR_VERSION);
+ return;
+ }
+
if (!c->authorized) {
int success = 0;
c->auth_timeout_event = NULL;
}
}
-
- pa_pstream_send_simple_ack(c->pstream, tag);
+
+ reply = reply_new(tag);
+ pa_tagstruct_putu32(reply, PA_PROTOCOL_VERSION);
+ pa_pstream_send_tagstruct(c->pstream, reply);
}
static void command_set_client_name(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {