[spotify] Introduce own spotifyc as replacement for libspotify
This commit is contained in:
parent
d3cc8a52f8
commit
a67c74ba6c
23
configure.ac
23
configure.ac
|
@ -286,19 +286,22 @@ AS_IF([[test "x$with_avahi" = "xno"]],
|
||||||
[AC_MSG_ERROR([[Avahi client or Bonjour DNS_SD required, please install one.]])])])
|
[AC_MSG_ERROR([[Avahi client or Bonjour DNS_SD required, please install one.]])])])
|
||||||
AM_CONDITIONAL([COND_AVAHI], [[test "x$with_avahi" = "xyes"]])
|
AM_CONDITIONAL([COND_AVAHI], [[test "x$with_avahi" = "xyes"]])
|
||||||
|
|
||||||
dnl Spotify with dynamic linking to libspotify
|
dnl Spotify support
|
||||||
OWNTONE_ARG_ENABLE([Spotify support], [spotify], [SPOTIFY],
|
OWNTONE_ARG_ENABLE([Spotify support], [spotify], [SPOTIFY],
|
||||||
[AS_IF([[test "x$with_libevent_pthreads" = "xno"]],
|
[AS_IF([[test "x$with_libevent_pthreads" = "xno"]],
|
||||||
[AC_MSG_ERROR([[Spotify support requires libevent_pthreads]])])
|
[AC_MSG_ERROR([[Spotify support requires libevent_pthreads]])])
|
||||||
OWNTONE_MODULES_CHECK([SPOTIFY], [LIBSPOTIFY], [libspotify],
|
OWNTONE_MODULES_CHECK([OWNTONE_OPTS], [LIBPROTOBUF_C],
|
||||||
[], [libspotify/api.h])
|
[libprotobuf-c >= 1.0.0], [protobuf_c_message_pack],
|
||||||
AC_DEFINE([HAVE_SPOTIFY_H], 1,
|
[protobuf-c/protobuf-c.h], [],
|
||||||
[Define to 1 if you have the <libspotify/api.h> header file.])
|
[OWNTONE_FUNC_REQUIRE([OWNTONE_OPTS], [v0 libprotobuf-c],
|
||||||
dnl Don't link with libspotify, use dynamic linking
|
[LIBPROTOBUF_OLD], [protobuf-c],
|
||||||
AC_SEARCH_LIBS([dlopen], [dl], [],
|
[protobuf_c_message_pack],
|
||||||
[AC_MSG_ERROR([[Spotify support requires dlopen]])])
|
[google/protobuf-c/protobuf-c.h],
|
||||||
OWNTONE_VAR_PREPEND([OWNTONE_OPTS_CPPFLAGS], [$SPOTIFY_CPPFLAGS])
|
[AC_DEFINE([HAVE_PROTOBUF_OLD], 1,
|
||||||
OWNTONE_VAR_PREPEND([OWNTONE_OPTS_LIBS], [-rdynamic])
|
[Define to 1 if you have libprotobuf < 1.0.0])
|
||||||
|
[protobuf_old=yes]],
|
||||||
|
[AC_MSG_ERROR([[Spotify support requires protobuf-c]])])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
AM_CONDITIONAL([COND_SPOTIFY], [[test "x$enable_spotify" = "xyes"]])
|
AM_CONDITIONAL([COND_SPOTIFY], [[test "x$enable_spotify" = "xyes"]])
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,16 @@
|
||||||
sbin_PROGRAMS = owntone
|
sbin_PROGRAMS = owntone
|
||||||
|
|
||||||
if COND_SPOTIFY
|
if COND_SPOTIFY
|
||||||
SPOTIFY_SRC=spotify.c spotify.h spotify_webapi.c spotify_webapi.h inputs/spotify.c
|
SPOTIFY_SRC = \
|
||||||
|
library/spotify_webapi.c library/spotify_webapi.h \
|
||||||
|
inputs/spotify.c inputs/spotify.h \
|
||||||
|
inputs/spotifyc/spotifyc.c inputs/spotifyc/spotifyc.h \
|
||||||
|
inputs/spotifyc/shannon/ShannonFast.c \
|
||||||
|
inputs/spotifyc/shannon/ShannonInternal.h inputs/spotifyc/shannon/Shannon.h \
|
||||||
|
inputs/spotifyc/proto/keyexchange.pb-c.c inputs/spotifyc/proto/keyexchange.pb-c.h \
|
||||||
|
inputs/spotifyc/proto/authentication.pb-c.c inputs/spotifyc/proto/authentication.pb-c.h \
|
||||||
|
inputs/spotifyc/proto/mercury.pb-c.c inputs/spotifyc/proto/mercury.pb-c.h \
|
||||||
|
inputs/spotifyc/proto/metadata.pb-c.c inputs/spotifyc/proto/metadata.pb-c.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if COND_LASTFM
|
if COND_LASTFM
|
||||||
|
|
|
@ -45,8 +45,8 @@
|
||||||
|
|
||||||
#include "artwork.h"
|
#include "artwork.h"
|
||||||
|
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
# include "spotify_webapi.h"
|
# include "library/spotify_webapi.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This artwork module will look for artwork by consulting a set of sources one
|
/* This artwork module will look for artwork by consulting a set of sources one
|
||||||
|
@ -1608,7 +1608,7 @@ source_item_coverartarchive_get(struct artwork_ctx *ctx)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
static int
|
static int
|
||||||
source_item_spotifywebapi_track_get(struct artwork_ctx *ctx)
|
source_item_spotifywebapi_track_get(struct artwork_ctx *ctx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,9 +55,9 @@
|
||||||
#include "remote_pairing.h"
|
#include "remote_pairing.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "smartpl_query.h"
|
#include "smartpl_query.h"
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
# include "spotify_webapi.h"
|
# include "library/spotify_webapi.h"
|
||||||
# include "spotify.h"
|
# include "inputs/spotify.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -1201,11 +1201,11 @@ jsonapi_reply_spotify(struct httpd_request *hreq)
|
||||||
|
|
||||||
CHECK_NULL(L_WEB, jreply = json_object_new_object());
|
CHECK_NULL(L_WEB, jreply = json_object_new_object());
|
||||||
|
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
int httpd_port;
|
int httpd_port;
|
||||||
char redirect_uri[256];
|
char redirect_uri[256];
|
||||||
char *oauth_uri;
|
char *oauth_uri;
|
||||||
struct spotify_status_info info;
|
struct spotify_status sp_status;
|
||||||
struct spotifywebapi_status_info webapi_info;
|
struct spotifywebapi_status_info webapi_info;
|
||||||
struct spotifywebapi_access_token webapi_token;
|
struct spotifywebapi_access_token webapi_token;
|
||||||
|
|
||||||
|
@ -1225,10 +1225,10 @@ jsonapi_reply_spotify(struct httpd_request *hreq)
|
||||||
json_object_object_add(jreply, "oauth_uri", json_object_new_string(oauth_uri));
|
json_object_object_add(jreply, "oauth_uri", json_object_new_string(oauth_uri));
|
||||||
free(oauth_uri);
|
free(oauth_uri);
|
||||||
|
|
||||||
spotify_status_info_get(&info);
|
spotify_status_get(&sp_status);
|
||||||
json_object_object_add(jreply, "libspotify_installed", json_object_new_boolean(info.libspotify_installed));
|
json_object_object_add(jreply, "libspotify_installed", json_object_new_boolean(sp_status.installed));
|
||||||
json_object_object_add(jreply, "libspotify_logged_in", json_object_new_boolean(info.libspotify_logged_in));
|
json_object_object_add(jreply, "libspotify_logged_in", json_object_new_boolean(sp_status.logged_in));
|
||||||
safe_json_add_string(jreply, "libspotify_user", info.libspotify_user);
|
safe_json_add_string(jreply, "libspotify_user", sp_status.username);
|
||||||
|
|
||||||
spotifywebapi_status_info_get(&webapi_info);
|
spotifywebapi_status_info_get(&webapi_info);
|
||||||
json_object_object_add(jreply, "webapi_token_valid", json_object_new_boolean(webapi_info.token_valid));
|
json_object_object_add(jreply, "webapi_token_valid", json_object_new_boolean(webapi_info.token_valid));
|
||||||
|
@ -1255,12 +1255,12 @@ jsonapi_reply_spotify(struct httpd_request *hreq)
|
||||||
static int
|
static int
|
||||||
jsonapi_reply_spotify_login(struct httpd_request *hreq)
|
jsonapi_reply_spotify_login(struct httpd_request *hreq)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
struct evbuffer *in_evbuf;
|
struct evbuffer *in_evbuf;
|
||||||
json_object* request;
|
json_object* request;
|
||||||
const char *user;
|
const char *user;
|
||||||
const char *password;
|
const char *password;
|
||||||
char *errmsg = NULL;
|
const char *errmsg;
|
||||||
json_object* jreply;
|
json_object* jreply;
|
||||||
json_object* errors;
|
json_object* errors;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1294,7 +1294,6 @@ jsonapi_reply_spotify_login(struct httpd_request *hreq)
|
||||||
{
|
{
|
||||||
json_object_object_add(jreply, "success", json_object_new_boolean(true));
|
json_object_object_add(jreply, "success", json_object_new_boolean(true));
|
||||||
}
|
}
|
||||||
free(errmsg);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1323,7 +1322,7 @@ jsonapi_reply_spotify_login(struct httpd_request *hreq)
|
||||||
static int
|
static int
|
||||||
jsonapi_reply_spotify_logout(struct httpd_request *hreq)
|
jsonapi_reply_spotify_logout(struct httpd_request *hreq)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
spotify_logout();
|
spotify_logout();
|
||||||
#endif
|
#endif
|
||||||
return HTTP_NOCONTENT;
|
return HTTP_NOCONTENT;
|
||||||
|
|
|
@ -32,14 +32,14 @@
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "conffile.h"
|
#include "conffile.h"
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
# include "spotify_webapi.h"
|
# include "library/spotify_webapi.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------- REPLY HANDLERS ------------------------------- */
|
/* --------------------------- REPLY HANDLERS ------------------------------- */
|
||||||
|
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
static int
|
static int
|
||||||
oauth_reply_spotify(struct httpd_request *hreq)
|
oauth_reply_spotify(struct httpd_request *hreq)
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,7 +58,7 @@ extern struct input_definition input_file;
|
||||||
extern struct input_definition input_http;
|
extern struct input_definition input_http;
|
||||||
extern struct input_definition input_pipe;
|
extern struct input_definition input_pipe;
|
||||||
extern struct input_definition input_timer;
|
extern struct input_definition input_timer;
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
extern struct input_definition input_spotify;
|
extern struct input_definition input_spotify;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ static struct input_definition *inputs[] = {
|
||||||
&input_http,
|
&input_http,
|
||||||
&input_pipe,
|
&input_pipe,
|
||||||
&input_timer,
|
&input_timer,
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
&input_spotify,
|
&input_spotify,
|
||||||
#endif
|
#endif
|
||||||
NULL
|
NULL
|
||||||
|
@ -171,7 +171,7 @@ map_data_kind(int data_kind)
|
||||||
case DATA_KIND_PIPE:
|
case DATA_KIND_PIPE:
|
||||||
return INPUT_TYPE_PIPE;
|
return INPUT_TYPE_PIPE;
|
||||||
|
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
case DATA_KIND_SPOTIFY:
|
case DATA_KIND_SPOTIFY:
|
||||||
return INPUT_TYPE_SPOTIFY;
|
return INPUT_TYPE_SPOTIFY;
|
||||||
#endif
|
#endif
|
||||||
|
@ -420,6 +420,7 @@ setup(struct input_source *source, struct db_queue_item *queue_item, int seek_ms
|
||||||
source->id = queue_item->file_id;
|
source->id = queue_item->file_id;
|
||||||
source->len_ms = queue_item->song_length;
|
source->len_ms = queue_item->song_length;
|
||||||
source->path = safe_strdup(queue_item->path);
|
source->path = safe_strdup(queue_item->path);
|
||||||
|
source->evbase = evbase_input;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_PLAYER, "Setting up input item '%s' (item id %" PRIu32 ")\n", source->path, source->item_id);
|
DPRINTF(E_DBG, L_PLAYER, "Setting up input item '%s' (item id %" PRIu32 ")\n", source->path, source->item_id);
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ enum input_types
|
||||||
INPUT_TYPE_HTTP,
|
INPUT_TYPE_HTTP,
|
||||||
INPUT_TYPE_PIPE,
|
INPUT_TYPE_PIPE,
|
||||||
INPUT_TYPE_TIMER,
|
INPUT_TYPE_TIMER,
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
INPUT_TYPE_SPOTIFY,
|
INPUT_TYPE_SPOTIFY,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -62,6 +62,10 @@ struct input_source
|
||||||
// Opaque pointer to data that the input backend sets up when start() is
|
// Opaque pointer to data that the input backend sets up when start() is
|
||||||
// called, and that is cleaned up by the backend when stop() is called
|
// called, and that is cleaned up by the backend when stop() is called
|
||||||
void *input_ctx;
|
void *input_ctx;
|
||||||
|
|
||||||
|
// The input's event base that the input backend can use for own events
|
||||||
|
struct event_base *evbase;
|
||||||
|
|
||||||
// Private evbuf. Alloc'ed by backend at start() and free'd at stop()
|
// Private evbuf. Alloc'ed by backend at start() and free'd at stop()
|
||||||
struct evbuffer *evbuf;
|
struct evbuffer *evbuf;
|
||||||
// Private source quality storage
|
// Private source quality storage
|
||||||
|
@ -128,7 +132,7 @@ struct input_definition
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------- Interface towards input backends ------------------ */
|
/* ---------------------- Interface towards input backends ------------------ */
|
||||||
/* Thread: input and spotify */
|
/* Thread: input */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transfer stream data to the player's input buffer. Data must be PCM-LE
|
* Transfer stream data to the player's input buffer. Data must be PCM-LE
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2017 Espen Jurgensen
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
@ -21,63 +19,512 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <event2/event.h>
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include "misc.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
#include "http.h"
|
||||||
|
#include "db.h"
|
||||||
|
#include "transcode.h"
|
||||||
#include "spotify.h"
|
#include "spotify.h"
|
||||||
|
#include "spotifyc/spotifyc.h"
|
||||||
|
|
||||||
// How many retries to start playback if resource is still loading
|
#define SPOTIFY_PROBE_SIZE_MIN 65536
|
||||||
#define SPOTIFY_SETUP_RETRIES 5
|
|
||||||
// How long to wait between retries in microseconds (500000 = 0.5 seconds)
|
|
||||||
#define SPOTIFY_SETUP_RETRY_WAIT 500000
|
|
||||||
|
|
||||||
static int
|
struct global_ctx
|
||||||
setup(struct input_source *source)
|
|
||||||
{
|
{
|
||||||
int i = 0;
|
pthread_mutex_t lock;
|
||||||
int ret;
|
pthread_cond_t cond;
|
||||||
|
|
||||||
while((ret = spotify_playback_setup(source->path)) == SPOTIFY_SETUP_ERROR_IS_LOADING)
|
struct sp_session *session;
|
||||||
|
bool response_pending; // waiting for a response from spotifyc
|
||||||
|
struct spotify_status status;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct playback_ctx
|
||||||
|
{
|
||||||
|
struct transcode_ctx *xcode;
|
||||||
|
|
||||||
|
int read_fd;
|
||||||
|
struct evbuffer *read_buf;
|
||||||
|
size_t read_bytes;
|
||||||
|
|
||||||
|
uint32_t len_ms;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct global_ctx spotify_ctx;
|
||||||
|
|
||||||
|
static bool db_is_initialized;
|
||||||
|
static struct media_quality spotify_quality = { 44100, 16, 2, 0 };
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------ Utility funcs ----------------------------- */
|
||||||
|
|
||||||
|
static void
|
||||||
|
hextobin(uint8_t *data, size_t data_len, const char *hexstr, size_t hexstr_len)
|
||||||
|
{
|
||||||
|
char hex[] = { 0, 0, 0 };
|
||||||
|
const char *ptr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (2 * data_len < hexstr_len)
|
||||||
{
|
{
|
||||||
if (i >= SPOTIFY_SETUP_RETRIES)
|
memset(data, 0, data_len);
|
||||||
break;
|
return;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_SPOTIFY, "Resource still loading (%d)\n", i);
|
|
||||||
usleep(SPOTIFY_SETUP_RETRY_WAIT);
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0)
|
ptr = hexstr;
|
||||||
return -1;
|
for (i = 0; i < data_len; i++, ptr+=2)
|
||||||
|
{
|
||||||
|
memcpy(hex, ptr, 2);
|
||||||
|
data[i] = strtol(hex, NULL, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = spotify_playback_play();
|
|
||||||
if (ret < 0)
|
/* -------------------- Callbacks from spotifyc thread ---------------------- */
|
||||||
return -1;
|
|
||||||
|
static void
|
||||||
|
got_reply(struct global_ctx *ctx)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&ctx->lock);
|
||||||
|
|
||||||
|
ctx->response_pending = false;
|
||||||
|
|
||||||
|
pthread_cond_signal(&ctx->cond);
|
||||||
|
pthread_mutex_unlock(&ctx->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
error_cb(void *cb_arg, int err, const char *errmsg)
|
||||||
|
{
|
||||||
|
struct global_ctx *ctx = cb_arg;
|
||||||
|
|
||||||
|
got_reply(ctx);
|
||||||
|
|
||||||
|
DPRINTF(E_LOG, L_SPOTIFY, "%s (error code %d)\n", errmsg, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
logged_in_cb(struct sp_session *session, void *cb_arg, struct sp_credentials *credentials)
|
||||||
|
{
|
||||||
|
struct global_ctx *ctx = cb_arg;
|
||||||
|
char *db_stored_cred;
|
||||||
|
char *ptr;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!db_is_initialized)
|
||||||
|
{
|
||||||
|
ret = db_perthread_init();
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_SPOTIFY, "Error: DB init failed (spotify thread)\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db_is_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINTF(E_LOG, L_SPOTIFY, "Logged into Spotify succesfully\n");
|
||||||
|
|
||||||
|
if (!credentials->username || !credentials->stored_cred)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_SPOTIFY, "No credentials returned by Spotify, automatic login will not be possible\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db_stored_cred = malloc(2 * credentials->stored_cred_len +1);
|
||||||
|
for (i = 0, ptr = db_stored_cred; i < credentials->stored_cred_len; i++)
|
||||||
|
ptr += sprintf(ptr, "%02x", credentials->stored_cred[i]);
|
||||||
|
|
||||||
|
db_admin_set("spotify_username", credentials->username);
|
||||||
|
db_admin_set("spotify_stored_cred", db_stored_cred);
|
||||||
|
|
||||||
|
free(db_stored_cred);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&ctx->lock);
|
||||||
|
|
||||||
|
ctx->response_pending = false;
|
||||||
|
ctx->status.logged_in = true;
|
||||||
|
snprintf(ctx->status.username, sizeof(ctx->status.username), "%s", credentials->username);
|
||||||
|
|
||||||
|
pthread_cond_signal(&ctx->cond);
|
||||||
|
pthread_mutex_unlock(&ctx->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
logged_out_cb(void *cb_arg)
|
||||||
|
{
|
||||||
|
db_admin_delete("spotify_username");
|
||||||
|
db_admin_delete("spotify_stored_cred");
|
||||||
|
|
||||||
|
if (db_is_initialized)
|
||||||
|
db_perthread_deinit();
|
||||||
|
|
||||||
|
db_is_initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
track_opened_cb(struct sp_session *session, void *cb_arg, int fd)
|
||||||
|
{
|
||||||
|
struct global_ctx *ctx = cb_arg;
|
||||||
|
|
||||||
|
DPRINTF(E_DBG, L_SPOTIFY, "track_opened_cb()\n");
|
||||||
|
|
||||||
|
pthread_mutex_lock(&ctx->lock);
|
||||||
|
|
||||||
|
ctx->response_pending = false;
|
||||||
|
ctx->status.track_opened = true;
|
||||||
|
|
||||||
|
pthread_cond_signal(&ctx->cond);
|
||||||
|
pthread_mutex_unlock(&ctx->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
track_closed_cb(struct sp_session *session, void *cb_arg, int fd)
|
||||||
|
{
|
||||||
|
struct global_ctx *ctx = cb_arg;
|
||||||
|
|
||||||
|
DPRINTF(E_DBG, L_SPOTIFY, "track_closed_cb()\n");
|
||||||
|
|
||||||
|
pthread_mutex_lock(&ctx->lock);
|
||||||
|
|
||||||
|
ctx->response_pending = false;
|
||||||
|
ctx->status.track_opened = false;
|
||||||
|
|
||||||
|
pthread_cond_signal(&ctx->cond);
|
||||||
|
pthread_mutex_unlock(&ctx->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
https_get_cb(char **out, const char *url)
|
||||||
|
{
|
||||||
|
struct http_client_ctx ctx = { 0 };
|
||||||
|
char *body;
|
||||||
|
size_t len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ctx.url = url;
|
||||||
|
ctx.input_body = evbuffer_new();
|
||||||
|
|
||||||
|
ret = http_client_request(&ctx);
|
||||||
|
if (ret < 0 || ctx.response_code != HTTP_OK)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_SPOTIFY, "Failed to AP list from '%s' (return %d, error code %d)\n", ctx.url, ret, ctx.response_code);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = evbuffer_get_length(ctx.input_body);
|
||||||
|
body = malloc(len + 1);
|
||||||
|
|
||||||
|
evbuffer_remove(ctx.input_body, body, len);
|
||||||
|
body[len] = '\0'; // For safety
|
||||||
|
|
||||||
|
*out = body;
|
||||||
|
|
||||||
|
evbuffer_free(ctx.input_body);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
evbuffer_free(ctx.input_body);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tcp_connect(const char *address, unsigned short port)
|
||||||
|
{
|
||||||
|
return net_connect(address, port, SOCK_STREAM, "spotify");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tcp_disconnect(int fd)
|
||||||
|
{
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
logmsg_cb(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
DVPRINTF(E_DBG, L_SPOTIFY, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
hexdump_cb(const char *msg, uint8_t *data, size_t data_len)
|
||||||
|
{
|
||||||
|
// DHEXDUMP(E_DBG, L_SPOTIFY, data, data_len, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------- Implementation (input thread) ---------------------- */
|
||||||
|
|
||||||
|
struct sp_callbacks callbacks = {
|
||||||
|
.error = error_cb,
|
||||||
|
.logged_in = logged_in_cb,
|
||||||
|
.logged_out = logged_out_cb,
|
||||||
|
.track_opened = track_opened_cb,
|
||||||
|
.track_closed = track_closed_cb,
|
||||||
|
|
||||||
|
.https_get = https_get_cb,
|
||||||
|
.tcp_connect = tcp_connect,
|
||||||
|
.tcp_disconnect = tcp_disconnect,
|
||||||
|
|
||||||
|
.hexdump = hexdump_cb,
|
||||||
|
.logmsg = logmsg_cb,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Has to be called after we have started receiving data, since ffmpeg needs to
|
||||||
|
// probe the data to find the audio streams
|
||||||
|
static int
|
||||||
|
playback_xcode_setup(struct playback_ctx *playback)
|
||||||
|
{
|
||||||
|
struct transcode_ctx *xcode;
|
||||||
|
|
||||||
|
CHECK_NULL(L_SPOTIFY, xcode = malloc(sizeof(struct transcode_ctx)));
|
||||||
|
|
||||||
|
xcode->decode_ctx = transcode_decode_setup(XCODE_OGG, NULL, DATA_KIND_SPOTIFY, NULL, playback->read_buf, playback->len_ms);
|
||||||
|
if (!xcode->decode_ctx)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
xcode->encode_ctx = transcode_encode_setup(XCODE_PCM16, NULL, xcode->decode_ctx, NULL, 0, 0);
|
||||||
|
if (!xcode->encode_ctx)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
playback->xcode = xcode;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
transcode_cleanup(&xcode);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
playback_free(struct playback_ctx *playback)
|
||||||
|
{
|
||||||
|
if (!playback)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (playback->read_buf)
|
||||||
|
evbuffer_free(playback->read_buf);
|
||||||
|
if (playback->read_fd >= 0)
|
||||||
|
close(playback->read_fd);
|
||||||
|
|
||||||
|
transcode_cleanup(&playback->xcode);
|
||||||
|
free(playback);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct playback_ctx *
|
||||||
|
playback_new(struct input_source *source, int fd)
|
||||||
|
{
|
||||||
|
struct playback_ctx *playback;
|
||||||
|
|
||||||
|
CHECK_NULL(L_SPOTIFY, playback = calloc(1, sizeof(struct playback_ctx)));
|
||||||
|
CHECK_NULL(L_SPOTIFY, playback->read_buf = evbuffer_new());
|
||||||
|
|
||||||
|
playback->read_fd = fd;
|
||||||
|
playback->len_ms = source->len_ms;
|
||||||
|
|
||||||
|
return playback;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
stop(struct input_source *source)
|
stop(struct input_source *source)
|
||||||
{
|
{
|
||||||
int ret;
|
struct global_ctx *ctx = &spotify_ctx;
|
||||||
|
struct playback_ctx *playback = source->input_ctx;
|
||||||
|
|
||||||
ret = spotify_playback_stop();
|
pthread_mutex_lock(&ctx->lock);
|
||||||
if (ret < 0)
|
|
||||||
return -1;
|
if (playback)
|
||||||
|
{
|
||||||
|
// Only need to request stop if spotifyc still has the track open
|
||||||
|
if (ctx->status.track_opened)
|
||||||
|
spotifyc_stop(playback->read_fd);
|
||||||
|
|
||||||
|
playback_free(playback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source->evbuf)
|
||||||
|
evbuffer_free(source->evbuf);
|
||||||
|
|
||||||
|
source->input_ctx = NULL;
|
||||||
|
source->evbuf = NULL;
|
||||||
|
|
||||||
|
ctx->status.track_opened = false;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&ctx->lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
seek(struct input_source *source, int seek_ms)
|
setup(struct input_source *source)
|
||||||
{
|
{
|
||||||
|
struct global_ctx *ctx = &spotify_ctx;
|
||||||
|
int ret;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&ctx->lock);
|
||||||
|
|
||||||
|
fd = spotifyc_open(source->path, ctx->session);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_SPOTIFY, "Could not create fd for Spotify playback\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->response_pending = true;
|
||||||
|
while (ctx->response_pending)
|
||||||
|
pthread_cond_wait(&ctx->cond, &ctx->lock);
|
||||||
|
|
||||||
|
if (!ctx->status.track_opened)
|
||||||
|
{
|
||||||
|
close(fd);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seems we have a valid source, now setup a read + decoding context. The
|
||||||
|
// closing of the fd is from now on part of closing the playback_ctx, which is
|
||||||
|
// done in stop().
|
||||||
|
source->evbuf = evbuffer_new();
|
||||||
|
source->input_ctx = playback_new(source, fd);
|
||||||
|
if (!source->evbuf || !source->input_ctx)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
source->quality = spotify_quality;
|
||||||
|
|
||||||
|
// FIXME This makes sure we get the beginning of the file for ffmpeg to probe,
|
||||||
|
// but it doesn't work well if the player seeks after setup()
|
||||||
|
ret = spotifyc_play(fd);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&ctx->lock);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
pthread_mutex_unlock(&ctx->lock);
|
||||||
|
stop(source);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
play(struct input_source *source)
|
||||||
|
{
|
||||||
|
struct playback_ctx *playback = source->input_ctx;
|
||||||
|
int got;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = spotify_playback_seek(seek_ms);
|
got = evbuffer_read(playback->read_buf, playback->read_fd, -1);
|
||||||
if (ret < 0)
|
if (got < 0)
|
||||||
return -1;
|
goto error;
|
||||||
|
|
||||||
return ret;
|
// ffmpeg requires enough data to be able to probe the Ogg
|
||||||
|
playback->read_bytes += got;
|
||||||
|
if (playback->read_bytes < SPOTIFY_PROBE_SIZE_MIN)
|
||||||
|
{
|
||||||
|
input_wait();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!playback->xcode)
|
||||||
|
{
|
||||||
|
ret = playback_xcode_setup(playback);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode the Ogg Vorbis to PCM in chunks of 16 packets, which seems to keep
|
||||||
|
// the input buffer nice and full
|
||||||
|
ret = transcode(source->evbuf, NULL, playback->xcode, 16);
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
input_write(source->evbuf, &source->quality, INPUT_FLAG_EOF);
|
||||||
|
stop(source);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
// debug_count++;
|
||||||
|
// if (debug_count % 100 == 0)
|
||||||
|
// DPRINTF(E_DBG, L_SPOTIFY, "source->evbuf is %zu, playback->read_buf %zu, got is %d\n",
|
||||||
|
// evbuffer_get_length(source->evbuf), evbuffer_get_length(playback->read_buf), got);
|
||||||
|
|
||||||
|
input_write(source->evbuf, &source->quality, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
input_write(NULL, NULL, INPUT_FLAG_ERROR);
|
||||||
|
stop(source);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
seek(struct input_source *source, int seek_ms)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
init(void)
|
||||||
|
{
|
||||||
|
char *username = NULL;
|
||||||
|
char *db_stored_cred = NULL;
|
||||||
|
size_t db_stored_cred_len;
|
||||||
|
uint8_t *stored_cred = NULL;
|
||||||
|
size_t stored_cred_len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
CHECK_ERR(L_SPOTIFY, mutex_init(&spotify_ctx.lock));
|
||||||
|
CHECK_ERR(L_SPOTIFY, pthread_cond_init(&spotify_ctx.cond, NULL));
|
||||||
|
|
||||||
|
ret = spotifyc_init(&callbacks, &spotify_ctx);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if ( db_admin_get(&username, "spotify_username") < 0 ||
|
||||||
|
db_admin_get(&db_stored_cred, "spotify_stored_cred") < 0 ||
|
||||||
|
!username || !db_stored_cred )
|
||||||
|
goto end; // User not logged in yet
|
||||||
|
|
||||||
|
db_stored_cred_len = strlen(db_stored_cred);
|
||||||
|
stored_cred_len = db_stored_cred_len / 2;
|
||||||
|
|
||||||
|
CHECK_NULL(L_SPOTIFY, stored_cred = malloc(stored_cred_len));
|
||||||
|
hextobin(stored_cred, stored_cred_len, db_stored_cred, db_stored_cred_len);
|
||||||
|
|
||||||
|
spotify_ctx.session = spotifyc_login_stored_cred(username, stored_cred, stored_cred_len);
|
||||||
|
if (!spotify_ctx.session)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
end:
|
||||||
|
free(username);
|
||||||
|
free(db_stored_cred);
|
||||||
|
free(stored_cred);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
free(username);
|
||||||
|
free(db_stored_cred);
|
||||||
|
free(stored_cred);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
deinit(void)
|
||||||
|
{
|
||||||
|
spotifyc_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct input_definition input_spotify =
|
struct input_definition input_spotify =
|
||||||
|
@ -87,6 +534,67 @@ struct input_definition input_spotify =
|
||||||
.disabled = 0,
|
.disabled = 0,
|
||||||
.setup = setup,
|
.setup = setup,
|
||||||
.stop = stop,
|
.stop = stop,
|
||||||
|
.play = play,
|
||||||
.seek = seek,
|
.seek = seek,
|
||||||
|
.init = init,
|
||||||
|
.deinit = deinit,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------ Functions exposed via spotify.h (foreign threads) ----------- */
|
||||||
|
|
||||||
|
int
|
||||||
|
spotify_login_user(const char *user, const char *password, const char **errmsg)
|
||||||
|
{
|
||||||
|
struct global_ctx *ctx = &spotify_ctx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&ctx->lock);
|
||||||
|
|
||||||
|
ctx->response_pending = true;
|
||||||
|
|
||||||
|
ctx->session = spotifyc_login_password(user, password);
|
||||||
|
if (!ctx->session)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&ctx->lock);
|
||||||
|
*errmsg = "Error creating Spotify session";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ctx->response_pending)
|
||||||
|
pthread_cond_wait(&ctx->cond, &ctx->lock);
|
||||||
|
|
||||||
|
ret = ctx->status.logged_in ? 0 : -1;
|
||||||
|
if (ret < 0)
|
||||||
|
*errmsg = spotifyc_last_errmsg();
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&ctx->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spotify_login(char **arglist)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spotify_logout(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spotify_status_get(struct spotify_status *status)
|
||||||
|
{
|
||||||
|
struct global_ctx *ctx = &spotify_ctx;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&ctx->lock);
|
||||||
|
|
||||||
|
memcpy(status->username, ctx->status.username, sizeof(status->username));
|
||||||
|
status->logged_in = ctx->status.logged_in;
|
||||||
|
status->installed = true;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&ctx->lock);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef __SPOTIFY_H__
|
||||||
|
#define __SPOTIFY_H__
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
struct spotify_status
|
||||||
|
{
|
||||||
|
bool installed;
|
||||||
|
bool logged_in;
|
||||||
|
bool track_opened;
|
||||||
|
char username[100];
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
spotify_login_user(const char *user, const char *password, const char **errmsg);
|
||||||
|
|
||||||
|
void
|
||||||
|
spotify_login(char **arglist);
|
||||||
|
|
||||||
|
void
|
||||||
|
spotify_logout(void);
|
||||||
|
|
||||||
|
void
|
||||||
|
spotify_status_get(struct spotify_status *status);
|
||||||
|
|
||||||
|
#endif /* !__SPOTIFY_H__ */
|
|
@ -0,0 +1,51 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message Rule {
|
||||||
|
optional string type = 0x1;
|
||||||
|
optional uint32 times = 0x2;
|
||||||
|
optional uint64 interval = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AdRequest {
|
||||||
|
optional string client_language = 0x1;
|
||||||
|
optional string product = 0x2;
|
||||||
|
optional uint32 version = 0x3;
|
||||||
|
optional string type = 0x4;
|
||||||
|
repeated string avoidAds = 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AdQueueResponse {
|
||||||
|
repeated AdQueueEntry adQueueEntry = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AdFile {
|
||||||
|
optional string id = 0x1;
|
||||||
|
optional string format = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AdQueueEntry {
|
||||||
|
optional uint64 start_time = 0x1;
|
||||||
|
optional uint64 end_time = 0x2;
|
||||||
|
optional double priority = 0x3;
|
||||||
|
optional string token = 0x4;
|
||||||
|
optional uint32 ad_version = 0x5;
|
||||||
|
optional string id = 0x6;
|
||||||
|
optional string type = 0x7;
|
||||||
|
optional string campaign = 0x8;
|
||||||
|
optional string advertiser = 0x9;
|
||||||
|
optional string url = 0xa;
|
||||||
|
optional uint64 duration = 0xb;
|
||||||
|
optional uint64 expiry = 0xc;
|
||||||
|
optional string tracking_url = 0xd;
|
||||||
|
optional string banner_type = 0xe;
|
||||||
|
optional string html = 0xf;
|
||||||
|
optional string image = 0x10;
|
||||||
|
optional string background_image = 0x11;
|
||||||
|
optional string background_url = 0x12;
|
||||||
|
optional string background_color = 0x13;
|
||||||
|
optional string title = 0x14;
|
||||||
|
optional string caption = 0x15;
|
||||||
|
repeated AdFile file = 0x16;
|
||||||
|
repeated Rule rule = 0x17;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message AppInfo {
|
||||||
|
optional string identifier = 0x1;
|
||||||
|
optional int32 version_int = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AppInfoList {
|
||||||
|
repeated AppInfo items = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SemanticVersion {
|
||||||
|
optional int32 major = 0x1;
|
||||||
|
optional int32 minor = 0x2;
|
||||||
|
optional int32 patch = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RequestHeader {
|
||||||
|
optional string market = 0x1;
|
||||||
|
optional Platform platform = 0x2;
|
||||||
|
enum Platform {
|
||||||
|
WIN32_X86 = 0x0;
|
||||||
|
OSX_X86 = 0x1;
|
||||||
|
LINUX_X86 = 0x2;
|
||||||
|
IPHONE_ARM = 0x3;
|
||||||
|
SYMBIANS60_ARM = 0x4;
|
||||||
|
OSX_POWERPC = 0x5;
|
||||||
|
ANDROID_ARM = 0x6;
|
||||||
|
WINCE_ARM = 0x7;
|
||||||
|
LINUX_X86_64 = 0x8;
|
||||||
|
OSX_X86_64 = 0x9;
|
||||||
|
PALM_ARM = 0xa;
|
||||||
|
LINUX_SH = 0xb;
|
||||||
|
FREEBSD_X86 = 0xc;
|
||||||
|
FREEBSD_X86_64 = 0xd;
|
||||||
|
BLACKBERRY_ARM = 0xe;
|
||||||
|
SONOS_UNKNOWN = 0xf;
|
||||||
|
LINUX_MIPS = 0x10;
|
||||||
|
LINUX_ARM = 0x11;
|
||||||
|
LOGITECH_ARM = 0x12;
|
||||||
|
LINUX_BLACKFIN = 0x13;
|
||||||
|
ONKYO_ARM = 0x15;
|
||||||
|
QNXNTO_ARM = 0x16;
|
||||||
|
BADPLATFORM = 0xff;
|
||||||
|
}
|
||||||
|
optional AppInfoList app_infos = 0x6;
|
||||||
|
optional string bridge_identifier = 0x7;
|
||||||
|
optional SemanticVersion bridge_version = 0x8;
|
||||||
|
optional DeviceClass device_class = 0x9;
|
||||||
|
enum DeviceClass {
|
||||||
|
DESKTOP = 0x1;
|
||||||
|
TABLET = 0x2;
|
||||||
|
MOBILE = 0x3;
|
||||||
|
WEB = 0x4;
|
||||||
|
TV = 0x5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message AppItem {
|
||||||
|
optional string identifier = 0x1;
|
||||||
|
optional Requirement requirement = 0x2;
|
||||||
|
enum Requirement {
|
||||||
|
REQUIRED_INSTALL = 0x1;
|
||||||
|
LAZYLOAD = 0x2;
|
||||||
|
OPTIONAL_INSTALL = 0x3;
|
||||||
|
}
|
||||||
|
optional string manifest = 0x4;
|
||||||
|
optional string checksum = 0x5;
|
||||||
|
optional string bundle_uri = 0x6;
|
||||||
|
optional string small_icon_uri = 0x7;
|
||||||
|
optional string large_icon_uri = 0x8;
|
||||||
|
optional string medium_icon_uri = 0x9;
|
||||||
|
optional Type bundle_type = 0xa;
|
||||||
|
enum Type {
|
||||||
|
APPLICATION = 0x0;
|
||||||
|
FRAMEWORK = 0x1;
|
||||||
|
BRIDGE = 0x2;
|
||||||
|
}
|
||||||
|
optional SemanticVersion version = 0xb;
|
||||||
|
optional uint32 ttl_in_seconds = 0xc;
|
||||||
|
optional IdentifierList categories = 0xd;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AppList {
|
||||||
|
repeated AppItem items = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message IdentifierList {
|
||||||
|
repeated string identifiers = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BannerConfig {
|
||||||
|
optional string json = 0x1;
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,697 @@
|
||||||
|
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||||
|
/* Generated from: proto/authentication.proto */
|
||||||
|
|
||||||
|
#ifndef PROTOBUF_C_proto_2fauthentication_2eproto__INCLUDED
|
||||||
|
#define PROTOBUF_C_proto_2fauthentication_2eproto__INCLUDED
|
||||||
|
|
||||||
|
#include <protobuf-c/protobuf-c.h>
|
||||||
|
|
||||||
|
PROTOBUF_C__BEGIN_DECLS
|
||||||
|
|
||||||
|
#if PROTOBUF_C_VERSION_NUMBER < 1000000
|
||||||
|
# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers.
|
||||||
|
#elif 1003003 < PROTOBUF_C_MIN_COMPILER_VERSION
|
||||||
|
# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _ClientResponseEncrypted ClientResponseEncrypted;
|
||||||
|
typedef struct _LoginCredentials LoginCredentials;
|
||||||
|
typedef struct _FingerprintResponseUnion FingerprintResponseUnion;
|
||||||
|
typedef struct _FingerprintGrainResponse FingerprintGrainResponse;
|
||||||
|
typedef struct _FingerprintHmacRipemdResponse FingerprintHmacRipemdResponse;
|
||||||
|
typedef struct _PeerTicketUnion PeerTicketUnion;
|
||||||
|
typedef struct _PeerTicketPublicKey PeerTicketPublicKey;
|
||||||
|
typedef struct _PeerTicketOld PeerTicketOld;
|
||||||
|
typedef struct _SystemInfo SystemInfo;
|
||||||
|
typedef struct _LibspotifyAppKey LibspotifyAppKey;
|
||||||
|
typedef struct _ClientInfo ClientInfo;
|
||||||
|
typedef struct _ClientInfoFacebook ClientInfoFacebook;
|
||||||
|
typedef struct _APWelcome APWelcome;
|
||||||
|
typedef struct _AccountInfo AccountInfo;
|
||||||
|
typedef struct _AccountInfoSpotify AccountInfoSpotify;
|
||||||
|
typedef struct _AccountInfoFacebook AccountInfoFacebook;
|
||||||
|
|
||||||
|
|
||||||
|
/* --- enums --- */
|
||||||
|
|
||||||
|
typedef enum _AuthenticationType {
|
||||||
|
AUTHENTICATION_TYPE__AUTHENTICATION_USER_PASS = 0,
|
||||||
|
AUTHENTICATION_TYPE__AUTHENTICATION_STORED_SPOTIFY_CREDENTIALS = 1,
|
||||||
|
AUTHENTICATION_TYPE__AUTHENTICATION_STORED_FACEBOOK_CREDENTIALS = 2,
|
||||||
|
AUTHENTICATION_TYPE__AUTHENTICATION_SPOTIFY_TOKEN = 3,
|
||||||
|
AUTHENTICATION_TYPE__AUTHENTICATION_FACEBOOK_TOKEN = 4
|
||||||
|
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(AUTHENTICATION_TYPE)
|
||||||
|
} AuthenticationType;
|
||||||
|
typedef enum _AccountCreation {
|
||||||
|
ACCOUNT_CREATION__ACCOUNT_CREATION_ALWAYS_PROMPT = 1,
|
||||||
|
ACCOUNT_CREATION__ACCOUNT_CREATION_ALWAYS_CREATE = 3
|
||||||
|
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(ACCOUNT_CREATION)
|
||||||
|
} AccountCreation;
|
||||||
|
typedef enum _CpuFamily {
|
||||||
|
CPU_FAMILY__CPU_UNKNOWN = 0,
|
||||||
|
CPU_FAMILY__CPU_X86 = 1,
|
||||||
|
CPU_FAMILY__CPU_X86_64 = 2,
|
||||||
|
CPU_FAMILY__CPU_PPC = 3,
|
||||||
|
CPU_FAMILY__CPU_PPC_64 = 4,
|
||||||
|
CPU_FAMILY__CPU_ARM = 5,
|
||||||
|
CPU_FAMILY__CPU_IA64 = 6,
|
||||||
|
CPU_FAMILY__CPU_SH = 7,
|
||||||
|
CPU_FAMILY__CPU_MIPS = 8,
|
||||||
|
CPU_FAMILY__CPU_BLACKFIN = 9
|
||||||
|
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(CPU_FAMILY)
|
||||||
|
} CpuFamily;
|
||||||
|
typedef enum _Brand {
|
||||||
|
BRAND__BRAND_UNBRANDED = 0,
|
||||||
|
BRAND__BRAND_INQ = 1,
|
||||||
|
BRAND__BRAND_HTC = 2,
|
||||||
|
BRAND__BRAND_NOKIA = 3
|
||||||
|
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(BRAND)
|
||||||
|
} Brand;
|
||||||
|
typedef enum _Os {
|
||||||
|
OS__OS_UNKNOWN = 0,
|
||||||
|
OS__OS_WINDOWS = 1,
|
||||||
|
OS__OS_OSX = 2,
|
||||||
|
OS__OS_IPHONE = 3,
|
||||||
|
OS__OS_S60 = 4,
|
||||||
|
OS__OS_LINUX = 5,
|
||||||
|
OS__OS_WINDOWS_CE = 6,
|
||||||
|
OS__OS_ANDROID = 7,
|
||||||
|
OS__OS_PALM = 8,
|
||||||
|
OS__OS_FREEBSD = 9,
|
||||||
|
OS__OS_BLACKBERRY = 10,
|
||||||
|
OS__OS_SONOS = 11,
|
||||||
|
OS__OS_LOGITECH = 12,
|
||||||
|
OS__OS_WP7 = 13,
|
||||||
|
OS__OS_ONKYO = 14,
|
||||||
|
OS__OS_PHILIPS = 15,
|
||||||
|
OS__OS_WD = 16,
|
||||||
|
OS__OS_VOLVO = 17,
|
||||||
|
OS__OS_TIVO = 18,
|
||||||
|
OS__OS_AWOX = 19,
|
||||||
|
OS__OS_MEEGO = 20,
|
||||||
|
OS__OS_QNXNTO = 21,
|
||||||
|
OS__OS_BCO = 22
|
||||||
|
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(OS)
|
||||||
|
} Os;
|
||||||
|
typedef enum _AccountType {
|
||||||
|
ACCOUNT_TYPE__Spotify = 0,
|
||||||
|
ACCOUNT_TYPE__Facebook = 1
|
||||||
|
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(ACCOUNT_TYPE)
|
||||||
|
} AccountType;
|
||||||
|
|
||||||
|
/* --- messages --- */
|
||||||
|
|
||||||
|
struct _ClientResponseEncrypted
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
LoginCredentials *login_credentials;
|
||||||
|
protobuf_c_boolean has_account_creation;
|
||||||
|
AccountCreation account_creation;
|
||||||
|
FingerprintResponseUnion *fingerprint_response;
|
||||||
|
PeerTicketUnion *peer_ticket;
|
||||||
|
SystemInfo *system_info;
|
||||||
|
char *platform_model;
|
||||||
|
char *version_string;
|
||||||
|
LibspotifyAppKey *appkey;
|
||||||
|
ClientInfo *client_info;
|
||||||
|
};
|
||||||
|
#define CLIENT_RESPONSE_ENCRYPTED__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&client_response_encrypted__descriptor) \
|
||||||
|
, NULL, 0, ACCOUNT_CREATION__ACCOUNT_CREATION_ALWAYS_PROMPT, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
|
||||||
|
|
||||||
|
|
||||||
|
struct _LoginCredentials
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
char *username;
|
||||||
|
AuthenticationType typ;
|
||||||
|
protobuf_c_boolean has_auth_data;
|
||||||
|
ProtobufCBinaryData auth_data;
|
||||||
|
};
|
||||||
|
#define LOGIN_CREDENTIALS__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&login_credentials__descriptor) \
|
||||||
|
, NULL, AUTHENTICATION_TYPE__AUTHENTICATION_USER_PASS, 0, {0,NULL} }
|
||||||
|
|
||||||
|
|
||||||
|
struct _FingerprintResponseUnion
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
FingerprintGrainResponse *grain;
|
||||||
|
FingerprintHmacRipemdResponse *hmac_ripemd;
|
||||||
|
};
|
||||||
|
#define FINGERPRINT_RESPONSE_UNION__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&fingerprint_response_union__descriptor) \
|
||||||
|
, NULL, NULL }
|
||||||
|
|
||||||
|
|
||||||
|
struct _FingerprintGrainResponse
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
ProtobufCBinaryData encrypted_key;
|
||||||
|
};
|
||||||
|
#define FINGERPRINT_GRAIN_RESPONSE__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&fingerprint_grain_response__descriptor) \
|
||||||
|
, {0,NULL} }
|
||||||
|
|
||||||
|
|
||||||
|
struct _FingerprintHmacRipemdResponse
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
ProtobufCBinaryData hmac;
|
||||||
|
};
|
||||||
|
#define FINGERPRINT_HMAC_RIPEMD_RESPONSE__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&fingerprint_hmac_ripemd_response__descriptor) \
|
||||||
|
, {0,NULL} }
|
||||||
|
|
||||||
|
|
||||||
|
struct _PeerTicketUnion
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
PeerTicketPublicKey *public_key;
|
||||||
|
PeerTicketOld *old_ticket;
|
||||||
|
};
|
||||||
|
#define PEER_TICKET_UNION__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&peer_ticket_union__descriptor) \
|
||||||
|
, NULL, NULL }
|
||||||
|
|
||||||
|
|
||||||
|
struct _PeerTicketPublicKey
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
ProtobufCBinaryData public_key;
|
||||||
|
};
|
||||||
|
#define PEER_TICKET_PUBLIC_KEY__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&peer_ticket_public_key__descriptor) \
|
||||||
|
, {0,NULL} }
|
||||||
|
|
||||||
|
|
||||||
|
struct _PeerTicketOld
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
ProtobufCBinaryData peer_ticket;
|
||||||
|
ProtobufCBinaryData peer_ticket_signature;
|
||||||
|
};
|
||||||
|
#define PEER_TICKET_OLD__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&peer_ticket_old__descriptor) \
|
||||||
|
, {0,NULL}, {0,NULL} }
|
||||||
|
|
||||||
|
|
||||||
|
struct _SystemInfo
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
CpuFamily cpu_family;
|
||||||
|
protobuf_c_boolean has_cpu_subtype;
|
||||||
|
uint32_t cpu_subtype;
|
||||||
|
protobuf_c_boolean has_cpu_ext;
|
||||||
|
uint32_t cpu_ext;
|
||||||
|
protobuf_c_boolean has_brand;
|
||||||
|
Brand brand;
|
||||||
|
protobuf_c_boolean has_brand_flags;
|
||||||
|
uint32_t brand_flags;
|
||||||
|
Os os;
|
||||||
|
protobuf_c_boolean has_os_version;
|
||||||
|
uint32_t os_version;
|
||||||
|
protobuf_c_boolean has_os_ext;
|
||||||
|
uint32_t os_ext;
|
||||||
|
char *system_information_string;
|
||||||
|
char *device_id;
|
||||||
|
};
|
||||||
|
#define SYSTEM_INFO__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&system_info__descriptor) \
|
||||||
|
, CPU_FAMILY__CPU_UNKNOWN, 0, 0, 0, 0, 0, BRAND__BRAND_UNBRANDED, 0, 0, OS__OS_UNKNOWN, 0, 0, 0, 0, NULL, NULL }
|
||||||
|
|
||||||
|
|
||||||
|
struct _LibspotifyAppKey
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
uint32_t version;
|
||||||
|
ProtobufCBinaryData devkey;
|
||||||
|
ProtobufCBinaryData signature;
|
||||||
|
char *useragent;
|
||||||
|
ProtobufCBinaryData callback_hash;
|
||||||
|
};
|
||||||
|
#define LIBSPOTIFY_APP_KEY__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&libspotify_app_key__descriptor) \
|
||||||
|
, 0, {0,NULL}, {0,NULL}, NULL, {0,NULL} }
|
||||||
|
|
||||||
|
|
||||||
|
struct _ClientInfo
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
protobuf_c_boolean has_limited;
|
||||||
|
protobuf_c_boolean limited;
|
||||||
|
ClientInfoFacebook *fb;
|
||||||
|
char *language;
|
||||||
|
};
|
||||||
|
#define CLIENT_INFO__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&client_info__descriptor) \
|
||||||
|
, 0, 0, NULL, NULL }
|
||||||
|
|
||||||
|
|
||||||
|
struct _ClientInfoFacebook
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
char *machine_id;
|
||||||
|
};
|
||||||
|
#define CLIENT_INFO_FACEBOOK__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&client_info_facebook__descriptor) \
|
||||||
|
, NULL }
|
||||||
|
|
||||||
|
|
||||||
|
struct _APWelcome
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
char *canonical_username;
|
||||||
|
AccountType account_type_logged_in;
|
||||||
|
AccountType credentials_type_logged_in;
|
||||||
|
AuthenticationType reusable_auth_credentials_type;
|
||||||
|
ProtobufCBinaryData reusable_auth_credentials;
|
||||||
|
protobuf_c_boolean has_lfs_secret;
|
||||||
|
ProtobufCBinaryData lfs_secret;
|
||||||
|
AccountInfo *account_info;
|
||||||
|
AccountInfoFacebook *fb;
|
||||||
|
};
|
||||||
|
#define APWELCOME__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&apwelcome__descriptor) \
|
||||||
|
, NULL, ACCOUNT_TYPE__Spotify, ACCOUNT_TYPE__Spotify, AUTHENTICATION_TYPE__AUTHENTICATION_USER_PASS, {0,NULL}, 0, {0,NULL}, NULL, NULL }
|
||||||
|
|
||||||
|
|
||||||
|
struct _AccountInfo
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
AccountInfoSpotify *spotify;
|
||||||
|
AccountInfoFacebook *facebook;
|
||||||
|
};
|
||||||
|
#define ACCOUNT_INFO__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&account_info__descriptor) \
|
||||||
|
, NULL, NULL }
|
||||||
|
|
||||||
|
|
||||||
|
struct _AccountInfoSpotify
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
};
|
||||||
|
#define ACCOUNT_INFO_SPOTIFY__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&account_info_spotify__descriptor) \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct _AccountInfoFacebook
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
char *access_token;
|
||||||
|
char *machine_id;
|
||||||
|
};
|
||||||
|
#define ACCOUNT_INFO_FACEBOOK__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&account_info_facebook__descriptor) \
|
||||||
|
, NULL, NULL }
|
||||||
|
|
||||||
|
|
||||||
|
/* ClientResponseEncrypted methods */
|
||||||
|
void client_response_encrypted__init
|
||||||
|
(ClientResponseEncrypted *message);
|
||||||
|
size_t client_response_encrypted__get_packed_size
|
||||||
|
(const ClientResponseEncrypted *message);
|
||||||
|
size_t client_response_encrypted__pack
|
||||||
|
(const ClientResponseEncrypted *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t client_response_encrypted__pack_to_buffer
|
||||||
|
(const ClientResponseEncrypted *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
ClientResponseEncrypted *
|
||||||
|
client_response_encrypted__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void client_response_encrypted__free_unpacked
|
||||||
|
(ClientResponseEncrypted *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* LoginCredentials methods */
|
||||||
|
void login_credentials__init
|
||||||
|
(LoginCredentials *message);
|
||||||
|
size_t login_credentials__get_packed_size
|
||||||
|
(const LoginCredentials *message);
|
||||||
|
size_t login_credentials__pack
|
||||||
|
(const LoginCredentials *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t login_credentials__pack_to_buffer
|
||||||
|
(const LoginCredentials *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
LoginCredentials *
|
||||||
|
login_credentials__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void login_credentials__free_unpacked
|
||||||
|
(LoginCredentials *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* FingerprintResponseUnion methods */
|
||||||
|
void fingerprint_response_union__init
|
||||||
|
(FingerprintResponseUnion *message);
|
||||||
|
size_t fingerprint_response_union__get_packed_size
|
||||||
|
(const FingerprintResponseUnion *message);
|
||||||
|
size_t fingerprint_response_union__pack
|
||||||
|
(const FingerprintResponseUnion *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t fingerprint_response_union__pack_to_buffer
|
||||||
|
(const FingerprintResponseUnion *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
FingerprintResponseUnion *
|
||||||
|
fingerprint_response_union__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void fingerprint_response_union__free_unpacked
|
||||||
|
(FingerprintResponseUnion *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* FingerprintGrainResponse methods */
|
||||||
|
void fingerprint_grain_response__init
|
||||||
|
(FingerprintGrainResponse *message);
|
||||||
|
size_t fingerprint_grain_response__get_packed_size
|
||||||
|
(const FingerprintGrainResponse *message);
|
||||||
|
size_t fingerprint_grain_response__pack
|
||||||
|
(const FingerprintGrainResponse *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t fingerprint_grain_response__pack_to_buffer
|
||||||
|
(const FingerprintGrainResponse *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
FingerprintGrainResponse *
|
||||||
|
fingerprint_grain_response__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void fingerprint_grain_response__free_unpacked
|
||||||
|
(FingerprintGrainResponse *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* FingerprintHmacRipemdResponse methods */
|
||||||
|
void fingerprint_hmac_ripemd_response__init
|
||||||
|
(FingerprintHmacRipemdResponse *message);
|
||||||
|
size_t fingerprint_hmac_ripemd_response__get_packed_size
|
||||||
|
(const FingerprintHmacRipemdResponse *message);
|
||||||
|
size_t fingerprint_hmac_ripemd_response__pack
|
||||||
|
(const FingerprintHmacRipemdResponse *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t fingerprint_hmac_ripemd_response__pack_to_buffer
|
||||||
|
(const FingerprintHmacRipemdResponse *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
FingerprintHmacRipemdResponse *
|
||||||
|
fingerprint_hmac_ripemd_response__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void fingerprint_hmac_ripemd_response__free_unpacked
|
||||||
|
(FingerprintHmacRipemdResponse *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* PeerTicketUnion methods */
|
||||||
|
void peer_ticket_union__init
|
||||||
|
(PeerTicketUnion *message);
|
||||||
|
size_t peer_ticket_union__get_packed_size
|
||||||
|
(const PeerTicketUnion *message);
|
||||||
|
size_t peer_ticket_union__pack
|
||||||
|
(const PeerTicketUnion *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t peer_ticket_union__pack_to_buffer
|
||||||
|
(const PeerTicketUnion *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
PeerTicketUnion *
|
||||||
|
peer_ticket_union__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void peer_ticket_union__free_unpacked
|
||||||
|
(PeerTicketUnion *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* PeerTicketPublicKey methods */
|
||||||
|
void peer_ticket_public_key__init
|
||||||
|
(PeerTicketPublicKey *message);
|
||||||
|
size_t peer_ticket_public_key__get_packed_size
|
||||||
|
(const PeerTicketPublicKey *message);
|
||||||
|
size_t peer_ticket_public_key__pack
|
||||||
|
(const PeerTicketPublicKey *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t peer_ticket_public_key__pack_to_buffer
|
||||||
|
(const PeerTicketPublicKey *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
PeerTicketPublicKey *
|
||||||
|
peer_ticket_public_key__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void peer_ticket_public_key__free_unpacked
|
||||||
|
(PeerTicketPublicKey *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* PeerTicketOld methods */
|
||||||
|
void peer_ticket_old__init
|
||||||
|
(PeerTicketOld *message);
|
||||||
|
size_t peer_ticket_old__get_packed_size
|
||||||
|
(const PeerTicketOld *message);
|
||||||
|
size_t peer_ticket_old__pack
|
||||||
|
(const PeerTicketOld *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t peer_ticket_old__pack_to_buffer
|
||||||
|
(const PeerTicketOld *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
PeerTicketOld *
|
||||||
|
peer_ticket_old__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void peer_ticket_old__free_unpacked
|
||||||
|
(PeerTicketOld *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* SystemInfo methods */
|
||||||
|
void system_info__init
|
||||||
|
(SystemInfo *message);
|
||||||
|
size_t system_info__get_packed_size
|
||||||
|
(const SystemInfo *message);
|
||||||
|
size_t system_info__pack
|
||||||
|
(const SystemInfo *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t system_info__pack_to_buffer
|
||||||
|
(const SystemInfo *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
SystemInfo *
|
||||||
|
system_info__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void system_info__free_unpacked
|
||||||
|
(SystemInfo *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* LibspotifyAppKey methods */
|
||||||
|
void libspotify_app_key__init
|
||||||
|
(LibspotifyAppKey *message);
|
||||||
|
size_t libspotify_app_key__get_packed_size
|
||||||
|
(const LibspotifyAppKey *message);
|
||||||
|
size_t libspotify_app_key__pack
|
||||||
|
(const LibspotifyAppKey *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t libspotify_app_key__pack_to_buffer
|
||||||
|
(const LibspotifyAppKey *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
LibspotifyAppKey *
|
||||||
|
libspotify_app_key__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void libspotify_app_key__free_unpacked
|
||||||
|
(LibspotifyAppKey *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* ClientInfo methods */
|
||||||
|
void client_info__init
|
||||||
|
(ClientInfo *message);
|
||||||
|
size_t client_info__get_packed_size
|
||||||
|
(const ClientInfo *message);
|
||||||
|
size_t client_info__pack
|
||||||
|
(const ClientInfo *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t client_info__pack_to_buffer
|
||||||
|
(const ClientInfo *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
ClientInfo *
|
||||||
|
client_info__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void client_info__free_unpacked
|
||||||
|
(ClientInfo *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* ClientInfoFacebook methods */
|
||||||
|
void client_info_facebook__init
|
||||||
|
(ClientInfoFacebook *message);
|
||||||
|
size_t client_info_facebook__get_packed_size
|
||||||
|
(const ClientInfoFacebook *message);
|
||||||
|
size_t client_info_facebook__pack
|
||||||
|
(const ClientInfoFacebook *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t client_info_facebook__pack_to_buffer
|
||||||
|
(const ClientInfoFacebook *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
ClientInfoFacebook *
|
||||||
|
client_info_facebook__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void client_info_facebook__free_unpacked
|
||||||
|
(ClientInfoFacebook *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* APWelcome methods */
|
||||||
|
void apwelcome__init
|
||||||
|
(APWelcome *message);
|
||||||
|
size_t apwelcome__get_packed_size
|
||||||
|
(const APWelcome *message);
|
||||||
|
size_t apwelcome__pack
|
||||||
|
(const APWelcome *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t apwelcome__pack_to_buffer
|
||||||
|
(const APWelcome *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
APWelcome *
|
||||||
|
apwelcome__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void apwelcome__free_unpacked
|
||||||
|
(APWelcome *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* AccountInfo methods */
|
||||||
|
void account_info__init
|
||||||
|
(AccountInfo *message);
|
||||||
|
size_t account_info__get_packed_size
|
||||||
|
(const AccountInfo *message);
|
||||||
|
size_t account_info__pack
|
||||||
|
(const AccountInfo *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t account_info__pack_to_buffer
|
||||||
|
(const AccountInfo *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
AccountInfo *
|
||||||
|
account_info__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void account_info__free_unpacked
|
||||||
|
(AccountInfo *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* AccountInfoSpotify methods */
|
||||||
|
void account_info_spotify__init
|
||||||
|
(AccountInfoSpotify *message);
|
||||||
|
size_t account_info_spotify__get_packed_size
|
||||||
|
(const AccountInfoSpotify *message);
|
||||||
|
size_t account_info_spotify__pack
|
||||||
|
(const AccountInfoSpotify *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t account_info_spotify__pack_to_buffer
|
||||||
|
(const AccountInfoSpotify *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
AccountInfoSpotify *
|
||||||
|
account_info_spotify__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void account_info_spotify__free_unpacked
|
||||||
|
(AccountInfoSpotify *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* AccountInfoFacebook methods */
|
||||||
|
void account_info_facebook__init
|
||||||
|
(AccountInfoFacebook *message);
|
||||||
|
size_t account_info_facebook__get_packed_size
|
||||||
|
(const AccountInfoFacebook *message);
|
||||||
|
size_t account_info_facebook__pack
|
||||||
|
(const AccountInfoFacebook *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t account_info_facebook__pack_to_buffer
|
||||||
|
(const AccountInfoFacebook *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
AccountInfoFacebook *
|
||||||
|
account_info_facebook__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void account_info_facebook__free_unpacked
|
||||||
|
(AccountInfoFacebook *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* --- per-message closures --- */
|
||||||
|
|
||||||
|
typedef void (*ClientResponseEncrypted_Closure)
|
||||||
|
(const ClientResponseEncrypted *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*LoginCredentials_Closure)
|
||||||
|
(const LoginCredentials *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*FingerprintResponseUnion_Closure)
|
||||||
|
(const FingerprintResponseUnion *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*FingerprintGrainResponse_Closure)
|
||||||
|
(const FingerprintGrainResponse *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*FingerprintHmacRipemdResponse_Closure)
|
||||||
|
(const FingerprintHmacRipemdResponse *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*PeerTicketUnion_Closure)
|
||||||
|
(const PeerTicketUnion *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*PeerTicketPublicKey_Closure)
|
||||||
|
(const PeerTicketPublicKey *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*PeerTicketOld_Closure)
|
||||||
|
(const PeerTicketOld *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*SystemInfo_Closure)
|
||||||
|
(const SystemInfo *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*LibspotifyAppKey_Closure)
|
||||||
|
(const LibspotifyAppKey *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*ClientInfo_Closure)
|
||||||
|
(const ClientInfo *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*ClientInfoFacebook_Closure)
|
||||||
|
(const ClientInfoFacebook *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*APWelcome_Closure)
|
||||||
|
(const APWelcome *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*AccountInfo_Closure)
|
||||||
|
(const AccountInfo *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*AccountInfoSpotify_Closure)
|
||||||
|
(const AccountInfoSpotify *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*AccountInfoFacebook_Closure)
|
||||||
|
(const AccountInfoFacebook *message,
|
||||||
|
void *closure_data);
|
||||||
|
|
||||||
|
/* --- services --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* --- descriptors --- */
|
||||||
|
|
||||||
|
extern const ProtobufCEnumDescriptor authentication_type__descriptor;
|
||||||
|
extern const ProtobufCEnumDescriptor account_creation__descriptor;
|
||||||
|
extern const ProtobufCEnumDescriptor cpu_family__descriptor;
|
||||||
|
extern const ProtobufCEnumDescriptor brand__descriptor;
|
||||||
|
extern const ProtobufCEnumDescriptor os__descriptor;
|
||||||
|
extern const ProtobufCEnumDescriptor account_type__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor client_response_encrypted__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor login_credentials__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor fingerprint_response_union__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor fingerprint_grain_response__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor fingerprint_hmac_ripemd_response__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor peer_ticket_union__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor peer_ticket_public_key__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor peer_ticket_old__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor system_info__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor libspotify_app_key__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor client_info__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor client_info_facebook__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor apwelcome__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor account_info__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor account_info_spotify__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor account_info_facebook__descriptor;
|
||||||
|
|
||||||
|
PROTOBUF_C__END_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* PROTOBUF_C_proto_2fauthentication_2eproto__INCLUDED */
|
|
@ -0,0 +1,165 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message ClientResponseEncrypted {
|
||||||
|
required LoginCredentials login_credentials = 0xa;
|
||||||
|
optional AccountCreation account_creation = 0x14;
|
||||||
|
optional FingerprintResponseUnion fingerprint_response = 0x1e;
|
||||||
|
optional PeerTicketUnion peer_ticket = 0x28;
|
||||||
|
required SystemInfo system_info = 0x32;
|
||||||
|
optional string platform_model = 0x3c;
|
||||||
|
optional string version_string = 0x46;
|
||||||
|
optional LibspotifyAppKey appkey = 0x50;
|
||||||
|
optional ClientInfo client_info = 0x5a;
|
||||||
|
}
|
||||||
|
|
||||||
|
message LoginCredentials {
|
||||||
|
optional string username = 0xa;
|
||||||
|
required AuthenticationType typ = 0x14;
|
||||||
|
optional bytes auth_data = 0x1e;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum AuthenticationType {
|
||||||
|
AUTHENTICATION_USER_PASS = 0x0;
|
||||||
|
AUTHENTICATION_STORED_SPOTIFY_CREDENTIALS = 0x1;
|
||||||
|
AUTHENTICATION_STORED_FACEBOOK_CREDENTIALS = 0x2;
|
||||||
|
AUTHENTICATION_SPOTIFY_TOKEN = 0x3;
|
||||||
|
AUTHENTICATION_FACEBOOK_TOKEN = 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum AccountCreation {
|
||||||
|
ACCOUNT_CREATION_ALWAYS_PROMPT = 0x1;
|
||||||
|
ACCOUNT_CREATION_ALWAYS_CREATE = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FingerprintResponseUnion {
|
||||||
|
optional FingerprintGrainResponse grain = 0xa;
|
||||||
|
optional FingerprintHmacRipemdResponse hmac_ripemd = 0x14;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FingerprintGrainResponse {
|
||||||
|
required bytes encrypted_key = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FingerprintHmacRipemdResponse {
|
||||||
|
required bytes hmac = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PeerTicketUnion {
|
||||||
|
optional PeerTicketPublicKey public_key = 0xa;
|
||||||
|
optional PeerTicketOld old_ticket = 0x14;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PeerTicketPublicKey {
|
||||||
|
required bytes public_key = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PeerTicketOld {
|
||||||
|
required bytes peer_ticket = 0xa;
|
||||||
|
required bytes peer_ticket_signature = 0x14;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SystemInfo {
|
||||||
|
required CpuFamily cpu_family = 0xa;
|
||||||
|
optional uint32 cpu_subtype = 0x14;
|
||||||
|
optional uint32 cpu_ext = 0x1e;
|
||||||
|
optional Brand brand = 0x28;
|
||||||
|
optional uint32 brand_flags = 0x32;
|
||||||
|
required Os os = 0x3c;
|
||||||
|
optional uint32 os_version = 0x46;
|
||||||
|
optional uint32 os_ext = 0x50;
|
||||||
|
optional string system_information_string = 0x5a;
|
||||||
|
optional string device_id = 0x64;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CpuFamily {
|
||||||
|
CPU_UNKNOWN = 0x0;
|
||||||
|
CPU_X86 = 0x1;
|
||||||
|
CPU_X86_64 = 0x2;
|
||||||
|
CPU_PPC = 0x3;
|
||||||
|
CPU_PPC_64 = 0x4;
|
||||||
|
CPU_ARM = 0x5;
|
||||||
|
CPU_IA64 = 0x6;
|
||||||
|
CPU_SH = 0x7;
|
||||||
|
CPU_MIPS = 0x8;
|
||||||
|
CPU_BLACKFIN = 0x9;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Brand {
|
||||||
|
BRAND_UNBRANDED = 0x0;
|
||||||
|
BRAND_INQ = 0x1;
|
||||||
|
BRAND_HTC = 0x2;
|
||||||
|
BRAND_NOKIA = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Os {
|
||||||
|
OS_UNKNOWN = 0x0;
|
||||||
|
OS_WINDOWS = 0x1;
|
||||||
|
OS_OSX = 0x2;
|
||||||
|
OS_IPHONE = 0x3;
|
||||||
|
OS_S60 = 0x4;
|
||||||
|
OS_LINUX = 0x5;
|
||||||
|
OS_WINDOWS_CE = 0x6;
|
||||||
|
OS_ANDROID = 0x7;
|
||||||
|
OS_PALM = 0x8;
|
||||||
|
OS_FREEBSD = 0x9;
|
||||||
|
OS_BLACKBERRY = 0xa;
|
||||||
|
OS_SONOS = 0xb;
|
||||||
|
OS_LOGITECH = 0xc;
|
||||||
|
OS_WP7 = 0xd;
|
||||||
|
OS_ONKYO = 0xe;
|
||||||
|
OS_PHILIPS = 0xf;
|
||||||
|
OS_WD = 0x10;
|
||||||
|
OS_VOLVO = 0x11;
|
||||||
|
OS_TIVO = 0x12;
|
||||||
|
OS_AWOX = 0x13;
|
||||||
|
OS_MEEGO = 0x14;
|
||||||
|
OS_QNXNTO = 0x15;
|
||||||
|
OS_BCO = 0x16;
|
||||||
|
}
|
||||||
|
|
||||||
|
message LibspotifyAppKey {
|
||||||
|
required uint32 version = 0x1;
|
||||||
|
required bytes devkey = 0x2;
|
||||||
|
required bytes signature = 0x3;
|
||||||
|
required string useragent = 0x4;
|
||||||
|
required bytes callback_hash = 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ClientInfo {
|
||||||
|
optional bool limited = 0x1;
|
||||||
|
optional ClientInfoFacebook fb = 0x2;
|
||||||
|
optional string language = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ClientInfoFacebook {
|
||||||
|
optional string machine_id = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message APWelcome {
|
||||||
|
required string canonical_username = 0xa;
|
||||||
|
required AccountType account_type_logged_in = 0x14;
|
||||||
|
required AccountType credentials_type_logged_in = 0x19;
|
||||||
|
required AuthenticationType reusable_auth_credentials_type = 0x1e;
|
||||||
|
required bytes reusable_auth_credentials = 0x28;
|
||||||
|
optional bytes lfs_secret = 0x32;
|
||||||
|
optional AccountInfo account_info = 0x3c;
|
||||||
|
optional AccountInfoFacebook fb = 0x46;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum AccountType {
|
||||||
|
Spotify = 0x0;
|
||||||
|
Facebook = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AccountInfo {
|
||||||
|
optional AccountInfoSpotify spotify = 0x1;
|
||||||
|
optional AccountInfoFacebook facebook = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AccountInfoSpotify {
|
||||||
|
}
|
||||||
|
|
||||||
|
message AccountInfoFacebook {
|
||||||
|
optional string access_token = 0x1;
|
||||||
|
optional string machine_id = 0x2;
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message EventReply {
|
||||||
|
optional int32 queued = 0x1;
|
||||||
|
optional RetryInfo retry = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RetryInfo {
|
||||||
|
optional int32 retry_delay = 0x1;
|
||||||
|
optional int32 max_retry = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Id {
|
||||||
|
optional string uri = 0x1;
|
||||||
|
optional int64 start_time = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Start {
|
||||||
|
optional int32 length = 0x1;
|
||||||
|
optional string context_uri = 0x2;
|
||||||
|
optional int64 end_time = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Seek {
|
||||||
|
optional int64 end_time = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Pause {
|
||||||
|
optional int32 seconds_played = 0x1;
|
||||||
|
optional int64 end_time = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Resume {
|
||||||
|
optional int32 seconds_played = 0x1;
|
||||||
|
optional int64 end_time = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message End {
|
||||||
|
optional int32 seconds_played = 0x1;
|
||||||
|
optional int64 end_time = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Event {
|
||||||
|
optional Id id = 0x1;
|
||||||
|
optional Start start = 0x2;
|
||||||
|
optional Seek seek = 0x3;
|
||||||
|
optional Pause pause = 0x4;
|
||||||
|
optional Resume resume = 0x5;
|
||||||
|
optional End end = 0x6;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,183 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message Credential {
|
||||||
|
optional string facebook_uid = 0x1;
|
||||||
|
optional string access_token = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message EnableRequest {
|
||||||
|
optional Credential credential = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message EnableReply {
|
||||||
|
optional Credential credential = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DisableRequest {
|
||||||
|
optional Credential credential = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RevokeRequest {
|
||||||
|
optional Credential credential = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message InspectCredentialRequest {
|
||||||
|
optional Credential credential = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message InspectCredentialReply {
|
||||||
|
optional Credential alternative_credential = 0x1;
|
||||||
|
optional bool app_user = 0x2;
|
||||||
|
optional bool permanent_error = 0x3;
|
||||||
|
optional bool transient_error = 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UserState {
|
||||||
|
optional Credential credential = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateUserStateRequest {
|
||||||
|
optional Credential credential = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message OpenGraphError {
|
||||||
|
repeated string permanent = 0x1;
|
||||||
|
repeated string invalid_token = 0x2;
|
||||||
|
repeated string retries = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message OpenGraphScrobble {
|
||||||
|
optional int32 create_delay = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message OpenGraphConfig {
|
||||||
|
optional OpenGraphError error = 0x1;
|
||||||
|
optional OpenGraphScrobble scrobble = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AuthConfig {
|
||||||
|
optional string url = 0x1;
|
||||||
|
repeated string permissions = 0x2;
|
||||||
|
repeated string blacklist = 0x3;
|
||||||
|
repeated string whitelist = 0x4;
|
||||||
|
repeated string cancel = 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ConfigReply {
|
||||||
|
optional string domain = 0x1;
|
||||||
|
optional string app_id = 0x2;
|
||||||
|
optional string app_namespace = 0x3;
|
||||||
|
optional AuthConfig auth = 0x4;
|
||||||
|
optional OpenGraphConfig og = 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UserFields {
|
||||||
|
optional bool app_user = 0x1;
|
||||||
|
optional bool display_name = 0x2;
|
||||||
|
optional bool first_name = 0x3;
|
||||||
|
optional bool middle_name = 0x4;
|
||||||
|
optional bool last_name = 0x5;
|
||||||
|
optional bool picture_large = 0x6;
|
||||||
|
optional bool picture_square = 0x7;
|
||||||
|
optional bool gender = 0x8;
|
||||||
|
optional bool email = 0x9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UserOptions {
|
||||||
|
optional bool cache_is_king = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UserRequest {
|
||||||
|
optional UserOptions options = 0x1;
|
||||||
|
optional UserFields fields = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message User {
|
||||||
|
optional string spotify_username = 0x1;
|
||||||
|
optional string facebook_uid = 0x2;
|
||||||
|
optional bool app_user = 0x3;
|
||||||
|
optional string display_name = 0x4;
|
||||||
|
optional string first_name = 0x5;
|
||||||
|
optional string middle_name = 0x6;
|
||||||
|
optional string last_name = 0x7;
|
||||||
|
optional string picture_large = 0x8;
|
||||||
|
optional string picture_square = 0x9;
|
||||||
|
optional string gender = 0xa;
|
||||||
|
optional string email = 0xb;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FriendsFields {
|
||||||
|
optional bool app_user = 0x1;
|
||||||
|
optional bool display_name = 0x2;
|
||||||
|
optional bool picture_large = 0x6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FriendsOptions {
|
||||||
|
optional int32 limit = 0x1;
|
||||||
|
optional int32 offset = 0x2;
|
||||||
|
optional bool cache_is_king = 0x3;
|
||||||
|
optional bool app_friends = 0x4;
|
||||||
|
optional bool non_app_friends = 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FriendsRequest {
|
||||||
|
optional FriendsOptions options = 0x1;
|
||||||
|
optional FriendsFields fields = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FriendsReply {
|
||||||
|
repeated User friends = 0x1;
|
||||||
|
optional bool more = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ShareRequest {
|
||||||
|
optional Credential credential = 0x1;
|
||||||
|
optional string uri = 0x2;
|
||||||
|
optional string message_text = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ShareReply {
|
||||||
|
optional string post_id = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message InboxRequest {
|
||||||
|
optional Credential credential = 0x1;
|
||||||
|
repeated string facebook_uids = 0x3;
|
||||||
|
optional string message_text = 0x4;
|
||||||
|
optional string message_link = 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message InboxReply {
|
||||||
|
optional string message_id = 0x1;
|
||||||
|
optional string thread_id = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PermissionsOptions {
|
||||||
|
optional bool cache_is_king = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PermissionsRequest {
|
||||||
|
optional Credential credential = 0x1;
|
||||||
|
optional PermissionsOptions options = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PermissionsReply {
|
||||||
|
repeated string permissions = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GrantPermissionsRequest {
|
||||||
|
optional Credential credential = 0x1;
|
||||||
|
repeated string permissions = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GrantPermissionsReply {
|
||||||
|
repeated string granted = 0x1;
|
||||||
|
repeated string failed = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TransferRequest {
|
||||||
|
optional Credential credential = 0x1;
|
||||||
|
optional string source_username = 0x2;
|
||||||
|
optional string target_username = 0x3;
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,228 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message ClientHello {
|
||||||
|
required BuildInfo build_info = 0xa;
|
||||||
|
repeated Fingerprint fingerprints_supported = 0x14;
|
||||||
|
repeated Cryptosuite cryptosuites_supported = 0x1e;
|
||||||
|
repeated Powscheme powschemes_supported = 0x28;
|
||||||
|
required LoginCryptoHelloUnion login_crypto_hello = 0x32;
|
||||||
|
required bytes client_nonce = 0x3c;
|
||||||
|
optional bytes padding = 0x46;
|
||||||
|
optional FeatureSet feature_set = 0x50;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message BuildInfo {
|
||||||
|
required Product product = 0xa;
|
||||||
|
repeated ProductFlags product_flags = 0x14;
|
||||||
|
required Platform platform = 0x1e;
|
||||||
|
required uint64 version = 0x28;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Product {
|
||||||
|
PRODUCT_CLIENT = 0x0;
|
||||||
|
PRODUCT_LIBSPOTIFY= 0x1;
|
||||||
|
PRODUCT_MOBILE = 0x2;
|
||||||
|
PRODUCT_PARTNER = 0x3;
|
||||||
|
PRODUCT_LIBSPOTIFY_EMBEDDED = 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ProductFlags {
|
||||||
|
PRODUCT_FLAG_NONE = 0x0;
|
||||||
|
PRODUCT_FLAG_DEV_BUILD = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Platform {
|
||||||
|
PLATFORM_WIN32_X86 = 0x0;
|
||||||
|
PLATFORM_OSX_X86 = 0x1;
|
||||||
|
PLATFORM_LINUX_X86 = 0x2;
|
||||||
|
PLATFORM_IPHONE_ARM = 0x3;
|
||||||
|
PLATFORM_S60_ARM = 0x4;
|
||||||
|
PLATFORM_OSX_PPC = 0x5;
|
||||||
|
PLATFORM_ANDROID_ARM = 0x6;
|
||||||
|
PLATFORM_WINDOWS_CE_ARM = 0x7;
|
||||||
|
PLATFORM_LINUX_X86_64 = 0x8;
|
||||||
|
PLATFORM_OSX_X86_64 = 0x9;
|
||||||
|
PLATFORM_PALM_ARM = 0xa;
|
||||||
|
PLATFORM_LINUX_SH = 0xb;
|
||||||
|
PLATFORM_FREEBSD_X86 = 0xc;
|
||||||
|
PLATFORM_FREEBSD_X86_64 = 0xd;
|
||||||
|
PLATFORM_BLACKBERRY_ARM = 0xe;
|
||||||
|
PLATFORM_SONOS = 0xf;
|
||||||
|
PLATFORM_LINUX_MIPS = 0x10;
|
||||||
|
PLATFORM_LINUX_ARM = 0x11;
|
||||||
|
PLATFORM_LOGITECH_ARM = 0x12;
|
||||||
|
PLATFORM_LINUX_BLACKFIN = 0x13;
|
||||||
|
PLATFORM_WP7_ARM = 0x14;
|
||||||
|
PLATFORM_ONKYO_ARM = 0x15;
|
||||||
|
PLATFORM_QNXNTO_ARM = 0x16;
|
||||||
|
PLATFORM_BCO_ARM = 0x17;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Fingerprint {
|
||||||
|
FINGERPRINT_GRAIN = 0x0;
|
||||||
|
FINGERPRINT_HMAC_RIPEMD = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Cryptosuite {
|
||||||
|
CRYPTO_SUITE_SHANNON = 0x0;
|
||||||
|
CRYPTO_SUITE_RC4_SHA1_HMAC = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Powscheme {
|
||||||
|
POW_HASH_CASH = 0x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message LoginCryptoHelloUnion {
|
||||||
|
optional LoginCryptoDiffieHellmanHello diffie_hellman = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message LoginCryptoDiffieHellmanHello {
|
||||||
|
required bytes gc = 0xa;
|
||||||
|
required uint32 server_keys_known = 0x14;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message FeatureSet {
|
||||||
|
optional bool autoupdate2 = 0x1;
|
||||||
|
optional bool current_location = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message APResponseMessage {
|
||||||
|
optional APChallenge challenge = 0xa;
|
||||||
|
optional UpgradeRequiredMessage upgrade = 0x14;
|
||||||
|
optional APLoginFailed login_failed = 0x1e;
|
||||||
|
}
|
||||||
|
|
||||||
|
message APChallenge {
|
||||||
|
required LoginCryptoChallengeUnion login_crypto_challenge = 0xa;
|
||||||
|
required FingerprintChallengeUnion fingerprint_challenge = 0x14;
|
||||||
|
required PoWChallengeUnion pow_challenge = 0x1e;
|
||||||
|
required CryptoChallengeUnion crypto_challenge = 0x28;
|
||||||
|
required bytes server_nonce = 0x32;
|
||||||
|
optional bytes padding = 0x3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
message LoginCryptoChallengeUnion {
|
||||||
|
optional LoginCryptoDiffieHellmanChallenge diffie_hellman = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
message LoginCryptoDiffieHellmanChallenge {
|
||||||
|
required bytes gs = 0xa;
|
||||||
|
required int32 server_signature_key = 0x14;
|
||||||
|
required bytes gs_signature = 0x1e;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FingerprintChallengeUnion {
|
||||||
|
optional FingerprintGrainChallenge grain = 0xa;
|
||||||
|
optional FingerprintHmacRipemdChallenge hmac_ripemd = 0x14;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message FingerprintGrainChallenge {
|
||||||
|
required bytes kek = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message FingerprintHmacRipemdChallenge {
|
||||||
|
required bytes challenge = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message PoWChallengeUnion {
|
||||||
|
optional PoWHashCashChallenge hash_cash = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PoWHashCashChallenge {
|
||||||
|
optional bytes prefix = 0xa;
|
||||||
|
optional int32 length = 0x14;
|
||||||
|
optional int32 target = 0x1e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message CryptoChallengeUnion {
|
||||||
|
optional CryptoShannonChallenge shannon = 0xa;
|
||||||
|
optional CryptoRc4Sha1HmacChallenge rc4_sha1_hmac = 0x14;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message CryptoShannonChallenge {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message CryptoRc4Sha1HmacChallenge {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message UpgradeRequiredMessage {
|
||||||
|
required bytes upgrade_signed_part = 0xa;
|
||||||
|
required bytes signature = 0x14;
|
||||||
|
optional string http_suffix = 0x1e;
|
||||||
|
}
|
||||||
|
|
||||||
|
message APLoginFailed {
|
||||||
|
required ErrorCode error_code = 0xa;
|
||||||
|
optional int32 retry_delay = 0x14;
|
||||||
|
optional int32 expiry = 0x1e;
|
||||||
|
optional string error_description = 0x28;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ErrorCode {
|
||||||
|
ProtocolError = 0x0;
|
||||||
|
TryAnotherAP = 0x2;
|
||||||
|
BadConnectionId = 0x5;
|
||||||
|
TravelRestriction = 0x9;
|
||||||
|
PremiumAccountRequired = 0xb;
|
||||||
|
BadCredentials = 0xc;
|
||||||
|
CouldNotValidateCredentials = 0xd;
|
||||||
|
AccountExists = 0xe;
|
||||||
|
ExtraVerificationRequired = 0xf;
|
||||||
|
InvalidAppKey = 0x10;
|
||||||
|
ApplicationBanned = 0x11;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ClientResponsePlaintext {
|
||||||
|
required LoginCryptoResponseUnion login_crypto_response = 0xa;
|
||||||
|
required PoWResponseUnion pow_response = 0x14;
|
||||||
|
required CryptoResponseUnion crypto_response = 0x1e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message LoginCryptoResponseUnion {
|
||||||
|
optional LoginCryptoDiffieHellmanResponse diffie_hellman = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message LoginCryptoDiffieHellmanResponse {
|
||||||
|
required bytes hmac = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message PoWResponseUnion {
|
||||||
|
optional PoWHashCashResponse hash_cash = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message PoWHashCashResponse {
|
||||||
|
required bytes hash_suffix = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message CryptoResponseUnion {
|
||||||
|
optional CryptoShannonResponse shannon = 0xa;
|
||||||
|
optional CryptoRc4Sha1HmacResponse rc4_sha1_hmac = 0x14;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message CryptoShannonResponse {
|
||||||
|
optional int32 dummy = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message CryptoRc4Sha1HmacResponse {
|
||||||
|
optional int32 dummy = 0x1;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,720 @@
|
||||||
|
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||||
|
/* Generated from: proto/mercury.proto */
|
||||||
|
|
||||||
|
/* Do not generate deprecated warnings for self */
|
||||||
|
#ifndef PROTOBUF_C__NO_DEPRECATED
|
||||||
|
#define PROTOBUF_C__NO_DEPRECATED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mercury.pb-c.h"
|
||||||
|
void mercury_multi_get_request__init
|
||||||
|
(MercuryMultiGetRequest *message)
|
||||||
|
{
|
||||||
|
static const MercuryMultiGetRequest init_value = MERCURY_MULTI_GET_REQUEST__INIT;
|
||||||
|
*message = init_value;
|
||||||
|
}
|
||||||
|
size_t mercury_multi_get_request__get_packed_size
|
||||||
|
(const MercuryMultiGetRequest *message)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &mercury_multi_get_request__descriptor);
|
||||||
|
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||||
|
}
|
||||||
|
size_t mercury_multi_get_request__pack
|
||||||
|
(const MercuryMultiGetRequest *message,
|
||||||
|
uint8_t *out)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &mercury_multi_get_request__descriptor);
|
||||||
|
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||||
|
}
|
||||||
|
size_t mercury_multi_get_request__pack_to_buffer
|
||||||
|
(const MercuryMultiGetRequest *message,
|
||||||
|
ProtobufCBuffer *buffer)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &mercury_multi_get_request__descriptor);
|
||||||
|
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||||
|
}
|
||||||
|
MercuryMultiGetRequest *
|
||||||
|
mercury_multi_get_request__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data)
|
||||||
|
{
|
||||||
|
return (MercuryMultiGetRequest *)
|
||||||
|
protobuf_c_message_unpack (&mercury_multi_get_request__descriptor,
|
||||||
|
allocator, len, data);
|
||||||
|
}
|
||||||
|
void mercury_multi_get_request__free_unpacked
|
||||||
|
(MercuryMultiGetRequest *message,
|
||||||
|
ProtobufCAllocator *allocator)
|
||||||
|
{
|
||||||
|
if(!message)
|
||||||
|
return;
|
||||||
|
assert(message->base.descriptor == &mercury_multi_get_request__descriptor);
|
||||||
|
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||||
|
}
|
||||||
|
void mercury_multi_get_reply__init
|
||||||
|
(MercuryMultiGetReply *message)
|
||||||
|
{
|
||||||
|
static const MercuryMultiGetReply init_value = MERCURY_MULTI_GET_REPLY__INIT;
|
||||||
|
*message = init_value;
|
||||||
|
}
|
||||||
|
size_t mercury_multi_get_reply__get_packed_size
|
||||||
|
(const MercuryMultiGetReply *message)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &mercury_multi_get_reply__descriptor);
|
||||||
|
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||||
|
}
|
||||||
|
size_t mercury_multi_get_reply__pack
|
||||||
|
(const MercuryMultiGetReply *message,
|
||||||
|
uint8_t *out)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &mercury_multi_get_reply__descriptor);
|
||||||
|
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||||
|
}
|
||||||
|
size_t mercury_multi_get_reply__pack_to_buffer
|
||||||
|
(const MercuryMultiGetReply *message,
|
||||||
|
ProtobufCBuffer *buffer)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &mercury_multi_get_reply__descriptor);
|
||||||
|
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||||
|
}
|
||||||
|
MercuryMultiGetReply *
|
||||||
|
mercury_multi_get_reply__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data)
|
||||||
|
{
|
||||||
|
return (MercuryMultiGetReply *)
|
||||||
|
protobuf_c_message_unpack (&mercury_multi_get_reply__descriptor,
|
||||||
|
allocator, len, data);
|
||||||
|
}
|
||||||
|
void mercury_multi_get_reply__free_unpacked
|
||||||
|
(MercuryMultiGetReply *message,
|
||||||
|
ProtobufCAllocator *allocator)
|
||||||
|
{
|
||||||
|
if(!message)
|
||||||
|
return;
|
||||||
|
assert(message->base.descriptor == &mercury_multi_get_reply__descriptor);
|
||||||
|
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||||
|
}
|
||||||
|
void mercury_request__init
|
||||||
|
(MercuryRequest *message)
|
||||||
|
{
|
||||||
|
static const MercuryRequest init_value = MERCURY_REQUEST__INIT;
|
||||||
|
*message = init_value;
|
||||||
|
}
|
||||||
|
size_t mercury_request__get_packed_size
|
||||||
|
(const MercuryRequest *message)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &mercury_request__descriptor);
|
||||||
|
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||||
|
}
|
||||||
|
size_t mercury_request__pack
|
||||||
|
(const MercuryRequest *message,
|
||||||
|
uint8_t *out)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &mercury_request__descriptor);
|
||||||
|
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||||
|
}
|
||||||
|
size_t mercury_request__pack_to_buffer
|
||||||
|
(const MercuryRequest *message,
|
||||||
|
ProtobufCBuffer *buffer)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &mercury_request__descriptor);
|
||||||
|
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||||
|
}
|
||||||
|
MercuryRequest *
|
||||||
|
mercury_request__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data)
|
||||||
|
{
|
||||||
|
return (MercuryRequest *)
|
||||||
|
protobuf_c_message_unpack (&mercury_request__descriptor,
|
||||||
|
allocator, len, data);
|
||||||
|
}
|
||||||
|
void mercury_request__free_unpacked
|
||||||
|
(MercuryRequest *message,
|
||||||
|
ProtobufCAllocator *allocator)
|
||||||
|
{
|
||||||
|
if(!message)
|
||||||
|
return;
|
||||||
|
assert(message->base.descriptor == &mercury_request__descriptor);
|
||||||
|
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||||
|
}
|
||||||
|
void mercury_reply__init
|
||||||
|
(MercuryReply *message)
|
||||||
|
{
|
||||||
|
static const MercuryReply init_value = MERCURY_REPLY__INIT;
|
||||||
|
*message = init_value;
|
||||||
|
}
|
||||||
|
size_t mercury_reply__get_packed_size
|
||||||
|
(const MercuryReply *message)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &mercury_reply__descriptor);
|
||||||
|
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||||
|
}
|
||||||
|
size_t mercury_reply__pack
|
||||||
|
(const MercuryReply *message,
|
||||||
|
uint8_t *out)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &mercury_reply__descriptor);
|
||||||
|
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||||
|
}
|
||||||
|
size_t mercury_reply__pack_to_buffer
|
||||||
|
(const MercuryReply *message,
|
||||||
|
ProtobufCBuffer *buffer)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &mercury_reply__descriptor);
|
||||||
|
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||||
|
}
|
||||||
|
MercuryReply *
|
||||||
|
mercury_reply__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data)
|
||||||
|
{
|
||||||
|
return (MercuryReply *)
|
||||||
|
protobuf_c_message_unpack (&mercury_reply__descriptor,
|
||||||
|
allocator, len, data);
|
||||||
|
}
|
||||||
|
void mercury_reply__free_unpacked
|
||||||
|
(MercuryReply *message,
|
||||||
|
ProtobufCAllocator *allocator)
|
||||||
|
{
|
||||||
|
if(!message)
|
||||||
|
return;
|
||||||
|
assert(message->base.descriptor == &mercury_reply__descriptor);
|
||||||
|
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||||
|
}
|
||||||
|
void header__init
|
||||||
|
(Header *message)
|
||||||
|
{
|
||||||
|
static const Header init_value = HEADER__INIT;
|
||||||
|
*message = init_value;
|
||||||
|
}
|
||||||
|
size_t header__get_packed_size
|
||||||
|
(const Header *message)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &header__descriptor);
|
||||||
|
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||||
|
}
|
||||||
|
size_t header__pack
|
||||||
|
(const Header *message,
|
||||||
|
uint8_t *out)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &header__descriptor);
|
||||||
|
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||||
|
}
|
||||||
|
size_t header__pack_to_buffer
|
||||||
|
(const Header *message,
|
||||||
|
ProtobufCBuffer *buffer)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &header__descriptor);
|
||||||
|
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||||
|
}
|
||||||
|
Header *
|
||||||
|
header__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data)
|
||||||
|
{
|
||||||
|
return (Header *)
|
||||||
|
protobuf_c_message_unpack (&header__descriptor,
|
||||||
|
allocator, len, data);
|
||||||
|
}
|
||||||
|
void header__free_unpacked
|
||||||
|
(Header *message,
|
||||||
|
ProtobufCAllocator *allocator)
|
||||||
|
{
|
||||||
|
if(!message)
|
||||||
|
return;
|
||||||
|
assert(message->base.descriptor == &header__descriptor);
|
||||||
|
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||||
|
}
|
||||||
|
void user_field__init
|
||||||
|
(UserField *message)
|
||||||
|
{
|
||||||
|
static const UserField init_value = USER_FIELD__INIT;
|
||||||
|
*message = init_value;
|
||||||
|
}
|
||||||
|
size_t user_field__get_packed_size
|
||||||
|
(const UserField *message)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &user_field__descriptor);
|
||||||
|
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||||
|
}
|
||||||
|
size_t user_field__pack
|
||||||
|
(const UserField *message,
|
||||||
|
uint8_t *out)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &user_field__descriptor);
|
||||||
|
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||||
|
}
|
||||||
|
size_t user_field__pack_to_buffer
|
||||||
|
(const UserField *message,
|
||||||
|
ProtobufCBuffer *buffer)
|
||||||
|
{
|
||||||
|
assert(message->base.descriptor == &user_field__descriptor);
|
||||||
|
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||||
|
}
|
||||||
|
UserField *
|
||||||
|
user_field__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data)
|
||||||
|
{
|
||||||
|
return (UserField *)
|
||||||
|
protobuf_c_message_unpack (&user_field__descriptor,
|
||||||
|
allocator, len, data);
|
||||||
|
}
|
||||||
|
void user_field__free_unpacked
|
||||||
|
(UserField *message,
|
||||||
|
ProtobufCAllocator *allocator)
|
||||||
|
{
|
||||||
|
if(!message)
|
||||||
|
return;
|
||||||
|
assert(message->base.descriptor == &user_field__descriptor);
|
||||||
|
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||||
|
}
|
||||||
|
static const ProtobufCFieldDescriptor mercury_multi_get_request__field_descriptors[1] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"request",
|
||||||
|
1,
|
||||||
|
PROTOBUF_C_LABEL_REPEATED,
|
||||||
|
PROTOBUF_C_TYPE_MESSAGE,
|
||||||
|
offsetof(MercuryMultiGetRequest, n_request),
|
||||||
|
offsetof(MercuryMultiGetRequest, request),
|
||||||
|
&mercury_request__descriptor,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
static const unsigned mercury_multi_get_request__field_indices_by_name[] = {
|
||||||
|
0, /* field[0] = request */
|
||||||
|
};
|
||||||
|
static const ProtobufCIntRange mercury_multi_get_request__number_ranges[1 + 1] =
|
||||||
|
{
|
||||||
|
{ 1, 0 },
|
||||||
|
{ 0, 1 }
|
||||||
|
};
|
||||||
|
const ProtobufCMessageDescriptor mercury_multi_get_request__descriptor =
|
||||||
|
{
|
||||||
|
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||||
|
"MercuryMultiGetRequest",
|
||||||
|
"MercuryMultiGetRequest",
|
||||||
|
"MercuryMultiGetRequest",
|
||||||
|
"",
|
||||||
|
sizeof(MercuryMultiGetRequest),
|
||||||
|
1,
|
||||||
|
mercury_multi_get_request__field_descriptors,
|
||||||
|
mercury_multi_get_request__field_indices_by_name,
|
||||||
|
1, mercury_multi_get_request__number_ranges,
|
||||||
|
(ProtobufCMessageInit) mercury_multi_get_request__init,
|
||||||
|
NULL,NULL,NULL /* reserved[123] */
|
||||||
|
};
|
||||||
|
static const ProtobufCFieldDescriptor mercury_multi_get_reply__field_descriptors[1] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"reply",
|
||||||
|
1,
|
||||||
|
PROTOBUF_C_LABEL_REPEATED,
|
||||||
|
PROTOBUF_C_TYPE_MESSAGE,
|
||||||
|
offsetof(MercuryMultiGetReply, n_reply),
|
||||||
|
offsetof(MercuryMultiGetReply, reply),
|
||||||
|
&mercury_reply__descriptor,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
static const unsigned mercury_multi_get_reply__field_indices_by_name[] = {
|
||||||
|
0, /* field[0] = reply */
|
||||||
|
};
|
||||||
|
static const ProtobufCIntRange mercury_multi_get_reply__number_ranges[1 + 1] =
|
||||||
|
{
|
||||||
|
{ 1, 0 },
|
||||||
|
{ 0, 1 }
|
||||||
|
};
|
||||||
|
const ProtobufCMessageDescriptor mercury_multi_get_reply__descriptor =
|
||||||
|
{
|
||||||
|
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||||
|
"MercuryMultiGetReply",
|
||||||
|
"MercuryMultiGetReply",
|
||||||
|
"MercuryMultiGetReply",
|
||||||
|
"",
|
||||||
|
sizeof(MercuryMultiGetReply),
|
||||||
|
1,
|
||||||
|
mercury_multi_get_reply__field_descriptors,
|
||||||
|
mercury_multi_get_reply__field_indices_by_name,
|
||||||
|
1, mercury_multi_get_reply__number_ranges,
|
||||||
|
(ProtobufCMessageInit) mercury_multi_get_reply__init,
|
||||||
|
NULL,NULL,NULL /* reserved[123] */
|
||||||
|
};
|
||||||
|
static const ProtobufCFieldDescriptor mercury_request__field_descriptors[4] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"uri",
|
||||||
|
1,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_STRING,
|
||||||
|
0, /* quantifier_offset */
|
||||||
|
offsetof(MercuryRequest, uri),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content_type",
|
||||||
|
2,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_STRING,
|
||||||
|
0, /* quantifier_offset */
|
||||||
|
offsetof(MercuryRequest, content_type),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body",
|
||||||
|
3,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_BYTES,
|
||||||
|
offsetof(MercuryRequest, has_body),
|
||||||
|
offsetof(MercuryRequest, body),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"etag",
|
||||||
|
4,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_BYTES,
|
||||||
|
offsetof(MercuryRequest, has_etag),
|
||||||
|
offsetof(MercuryRequest, etag),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
static const unsigned mercury_request__field_indices_by_name[] = {
|
||||||
|
2, /* field[2] = body */
|
||||||
|
1, /* field[1] = content_type */
|
||||||
|
3, /* field[3] = etag */
|
||||||
|
0, /* field[0] = uri */
|
||||||
|
};
|
||||||
|
static const ProtobufCIntRange mercury_request__number_ranges[1 + 1] =
|
||||||
|
{
|
||||||
|
{ 1, 0 },
|
||||||
|
{ 0, 4 }
|
||||||
|
};
|
||||||
|
const ProtobufCMessageDescriptor mercury_request__descriptor =
|
||||||
|
{
|
||||||
|
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||||
|
"MercuryRequest",
|
||||||
|
"MercuryRequest",
|
||||||
|
"MercuryRequest",
|
||||||
|
"",
|
||||||
|
sizeof(MercuryRequest),
|
||||||
|
4,
|
||||||
|
mercury_request__field_descriptors,
|
||||||
|
mercury_request__field_indices_by_name,
|
||||||
|
1, mercury_request__number_ranges,
|
||||||
|
(ProtobufCMessageInit) mercury_request__init,
|
||||||
|
NULL,NULL,NULL /* reserved[123] */
|
||||||
|
};
|
||||||
|
static const ProtobufCEnumValue mercury_reply__cache_policy__enum_values_by_number[3] =
|
||||||
|
{
|
||||||
|
{ "CACHE_NO", "MERCURY_REPLY__CACHE_POLICY__CACHE_NO", 1 },
|
||||||
|
{ "CACHE_PRIVATE", "MERCURY_REPLY__CACHE_POLICY__CACHE_PRIVATE", 2 },
|
||||||
|
{ "CACHE_PUBLIC", "MERCURY_REPLY__CACHE_POLICY__CACHE_PUBLIC", 3 },
|
||||||
|
};
|
||||||
|
static const ProtobufCIntRange mercury_reply__cache_policy__value_ranges[] = {
|
||||||
|
{1, 0},{0, 3}
|
||||||
|
};
|
||||||
|
static const ProtobufCEnumValueIndex mercury_reply__cache_policy__enum_values_by_name[3] =
|
||||||
|
{
|
||||||
|
{ "CACHE_NO", 0 },
|
||||||
|
{ "CACHE_PRIVATE", 1 },
|
||||||
|
{ "CACHE_PUBLIC", 2 },
|
||||||
|
};
|
||||||
|
const ProtobufCEnumDescriptor mercury_reply__cache_policy__descriptor =
|
||||||
|
{
|
||||||
|
PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
|
||||||
|
"MercuryReply.CachePolicy",
|
||||||
|
"CachePolicy",
|
||||||
|
"MercuryReply__CachePolicy",
|
||||||
|
"",
|
||||||
|
3,
|
||||||
|
mercury_reply__cache_policy__enum_values_by_number,
|
||||||
|
3,
|
||||||
|
mercury_reply__cache_policy__enum_values_by_name,
|
||||||
|
1,
|
||||||
|
mercury_reply__cache_policy__value_ranges,
|
||||||
|
NULL,NULL,NULL,NULL /* reserved[1234] */
|
||||||
|
};
|
||||||
|
static const ProtobufCFieldDescriptor mercury_reply__field_descriptors[7] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"status_code",
|
||||||
|
1,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_SINT32,
|
||||||
|
offsetof(MercuryReply, has_status_code),
|
||||||
|
offsetof(MercuryReply, status_code),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"status_message",
|
||||||
|
2,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_STRING,
|
||||||
|
0, /* quantifier_offset */
|
||||||
|
offsetof(MercuryReply, status_message),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cache_policy",
|
||||||
|
3,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_ENUM,
|
||||||
|
offsetof(MercuryReply, has_cache_policy),
|
||||||
|
offsetof(MercuryReply, cache_policy),
|
||||||
|
&mercury_reply__cache_policy__descriptor,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ttl",
|
||||||
|
4,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_SINT32,
|
||||||
|
offsetof(MercuryReply, has_ttl),
|
||||||
|
offsetof(MercuryReply, ttl),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"etag",
|
||||||
|
5,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_BYTES,
|
||||||
|
offsetof(MercuryReply, has_etag),
|
||||||
|
offsetof(MercuryReply, etag),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content_type",
|
||||||
|
6,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_STRING,
|
||||||
|
0, /* quantifier_offset */
|
||||||
|
offsetof(MercuryReply, content_type),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body",
|
||||||
|
7,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_BYTES,
|
||||||
|
offsetof(MercuryReply, has_body),
|
||||||
|
offsetof(MercuryReply, body),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
static const unsigned mercury_reply__field_indices_by_name[] = {
|
||||||
|
6, /* field[6] = body */
|
||||||
|
2, /* field[2] = cache_policy */
|
||||||
|
5, /* field[5] = content_type */
|
||||||
|
4, /* field[4] = etag */
|
||||||
|
0, /* field[0] = status_code */
|
||||||
|
1, /* field[1] = status_message */
|
||||||
|
3, /* field[3] = ttl */
|
||||||
|
};
|
||||||
|
static const ProtobufCIntRange mercury_reply__number_ranges[1 + 1] =
|
||||||
|
{
|
||||||
|
{ 1, 0 },
|
||||||
|
{ 0, 7 }
|
||||||
|
};
|
||||||
|
const ProtobufCMessageDescriptor mercury_reply__descriptor =
|
||||||
|
{
|
||||||
|
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||||
|
"MercuryReply",
|
||||||
|
"MercuryReply",
|
||||||
|
"MercuryReply",
|
||||||
|
"",
|
||||||
|
sizeof(MercuryReply),
|
||||||
|
7,
|
||||||
|
mercury_reply__field_descriptors,
|
||||||
|
mercury_reply__field_indices_by_name,
|
||||||
|
1, mercury_reply__number_ranges,
|
||||||
|
(ProtobufCMessageInit) mercury_reply__init,
|
||||||
|
NULL,NULL,NULL /* reserved[123] */
|
||||||
|
};
|
||||||
|
static const ProtobufCFieldDescriptor header__field_descriptors[5] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"uri",
|
||||||
|
1,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_STRING,
|
||||||
|
0, /* quantifier_offset */
|
||||||
|
offsetof(Header, uri),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content_type",
|
||||||
|
2,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_STRING,
|
||||||
|
0, /* quantifier_offset */
|
||||||
|
offsetof(Header, content_type),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method",
|
||||||
|
3,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_STRING,
|
||||||
|
0, /* quantifier_offset */
|
||||||
|
offsetof(Header, method),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"status_code",
|
||||||
|
4,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_SINT32,
|
||||||
|
offsetof(Header, has_status_code),
|
||||||
|
offsetof(Header, status_code),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user_fields",
|
||||||
|
6,
|
||||||
|
PROTOBUF_C_LABEL_REPEATED,
|
||||||
|
PROTOBUF_C_TYPE_MESSAGE,
|
||||||
|
offsetof(Header, n_user_fields),
|
||||||
|
offsetof(Header, user_fields),
|
||||||
|
&user_field__descriptor,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
static const unsigned header__field_indices_by_name[] = {
|
||||||
|
1, /* field[1] = content_type */
|
||||||
|
2, /* field[2] = method */
|
||||||
|
3, /* field[3] = status_code */
|
||||||
|
0, /* field[0] = uri */
|
||||||
|
4, /* field[4] = user_fields */
|
||||||
|
};
|
||||||
|
static const ProtobufCIntRange header__number_ranges[2 + 1] =
|
||||||
|
{
|
||||||
|
{ 1, 0 },
|
||||||
|
{ 6, 4 },
|
||||||
|
{ 0, 5 }
|
||||||
|
};
|
||||||
|
const ProtobufCMessageDescriptor header__descriptor =
|
||||||
|
{
|
||||||
|
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||||
|
"Header",
|
||||||
|
"Header",
|
||||||
|
"Header",
|
||||||
|
"",
|
||||||
|
sizeof(Header),
|
||||||
|
5,
|
||||||
|
header__field_descriptors,
|
||||||
|
header__field_indices_by_name,
|
||||||
|
2, header__number_ranges,
|
||||||
|
(ProtobufCMessageInit) header__init,
|
||||||
|
NULL,NULL,NULL /* reserved[123] */
|
||||||
|
};
|
||||||
|
static const ProtobufCFieldDescriptor user_field__field_descriptors[2] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"key",
|
||||||
|
1,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_STRING,
|
||||||
|
0, /* quantifier_offset */
|
||||||
|
offsetof(UserField, key),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value",
|
||||||
|
2,
|
||||||
|
PROTOBUF_C_LABEL_OPTIONAL,
|
||||||
|
PROTOBUF_C_TYPE_BYTES,
|
||||||
|
offsetof(UserField, has_value),
|
||||||
|
offsetof(UserField, value),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0, /* flags */
|
||||||
|
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
static const unsigned user_field__field_indices_by_name[] = {
|
||||||
|
0, /* field[0] = key */
|
||||||
|
1, /* field[1] = value */
|
||||||
|
};
|
||||||
|
static const ProtobufCIntRange user_field__number_ranges[1 + 1] =
|
||||||
|
{
|
||||||
|
{ 1, 0 },
|
||||||
|
{ 0, 2 }
|
||||||
|
};
|
||||||
|
const ProtobufCMessageDescriptor user_field__descriptor =
|
||||||
|
{
|
||||||
|
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||||
|
"UserField",
|
||||||
|
"UserField",
|
||||||
|
"UserField",
|
||||||
|
"",
|
||||||
|
sizeof(UserField),
|
||||||
|
2,
|
||||||
|
user_field__field_descriptors,
|
||||||
|
user_field__field_indices_by_name,
|
||||||
|
1, user_field__number_ranges,
|
||||||
|
(ProtobufCMessageInit) user_field__init,
|
||||||
|
NULL,NULL,NULL /* reserved[123] */
|
||||||
|
};
|
|
@ -0,0 +1,274 @@
|
||||||
|
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||||
|
/* Generated from: proto/mercury.proto */
|
||||||
|
|
||||||
|
#ifndef PROTOBUF_C_proto_2fmercury_2eproto__INCLUDED
|
||||||
|
#define PROTOBUF_C_proto_2fmercury_2eproto__INCLUDED
|
||||||
|
|
||||||
|
#include <protobuf-c/protobuf-c.h>
|
||||||
|
|
||||||
|
PROTOBUF_C__BEGIN_DECLS
|
||||||
|
|
||||||
|
#if PROTOBUF_C_VERSION_NUMBER < 1000000
|
||||||
|
# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers.
|
||||||
|
#elif 1003003 < PROTOBUF_C_MIN_COMPILER_VERSION
|
||||||
|
# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _MercuryMultiGetRequest MercuryMultiGetRequest;
|
||||||
|
typedef struct _MercuryMultiGetReply MercuryMultiGetReply;
|
||||||
|
typedef struct _MercuryRequest MercuryRequest;
|
||||||
|
typedef struct _MercuryReply MercuryReply;
|
||||||
|
typedef struct _Header Header;
|
||||||
|
typedef struct _UserField UserField;
|
||||||
|
|
||||||
|
|
||||||
|
/* --- enums --- */
|
||||||
|
|
||||||
|
typedef enum _MercuryReply__CachePolicy {
|
||||||
|
MERCURY_REPLY__CACHE_POLICY__CACHE_NO = 1,
|
||||||
|
MERCURY_REPLY__CACHE_POLICY__CACHE_PRIVATE = 2,
|
||||||
|
MERCURY_REPLY__CACHE_POLICY__CACHE_PUBLIC = 3
|
||||||
|
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(MERCURY_REPLY__CACHE_POLICY)
|
||||||
|
} MercuryReply__CachePolicy;
|
||||||
|
|
||||||
|
/* --- messages --- */
|
||||||
|
|
||||||
|
struct _MercuryMultiGetRequest
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
size_t n_request;
|
||||||
|
MercuryRequest **request;
|
||||||
|
};
|
||||||
|
#define MERCURY_MULTI_GET_REQUEST__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&mercury_multi_get_request__descriptor) \
|
||||||
|
, 0,NULL }
|
||||||
|
|
||||||
|
|
||||||
|
struct _MercuryMultiGetReply
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
size_t n_reply;
|
||||||
|
MercuryReply **reply;
|
||||||
|
};
|
||||||
|
#define MERCURY_MULTI_GET_REPLY__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&mercury_multi_get_reply__descriptor) \
|
||||||
|
, 0,NULL }
|
||||||
|
|
||||||
|
|
||||||
|
struct _MercuryRequest
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
char *uri;
|
||||||
|
char *content_type;
|
||||||
|
protobuf_c_boolean has_body;
|
||||||
|
ProtobufCBinaryData body;
|
||||||
|
protobuf_c_boolean has_etag;
|
||||||
|
ProtobufCBinaryData etag;
|
||||||
|
};
|
||||||
|
#define MERCURY_REQUEST__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&mercury_request__descriptor) \
|
||||||
|
, NULL, NULL, 0, {0,NULL}, 0, {0,NULL} }
|
||||||
|
|
||||||
|
|
||||||
|
struct _MercuryReply
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
protobuf_c_boolean has_status_code;
|
||||||
|
int32_t status_code;
|
||||||
|
char *status_message;
|
||||||
|
protobuf_c_boolean has_cache_policy;
|
||||||
|
MercuryReply__CachePolicy cache_policy;
|
||||||
|
protobuf_c_boolean has_ttl;
|
||||||
|
int32_t ttl;
|
||||||
|
protobuf_c_boolean has_etag;
|
||||||
|
ProtobufCBinaryData etag;
|
||||||
|
char *content_type;
|
||||||
|
protobuf_c_boolean has_body;
|
||||||
|
ProtobufCBinaryData body;
|
||||||
|
};
|
||||||
|
#define MERCURY_REPLY__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&mercury_reply__descriptor) \
|
||||||
|
, 0, 0, NULL, 0, MERCURY_REPLY__CACHE_POLICY__CACHE_NO, 0, 0, 0, {0,NULL}, NULL, 0, {0,NULL} }
|
||||||
|
|
||||||
|
|
||||||
|
struct _Header
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
char *uri;
|
||||||
|
char *content_type;
|
||||||
|
char *method;
|
||||||
|
protobuf_c_boolean has_status_code;
|
||||||
|
int32_t status_code;
|
||||||
|
size_t n_user_fields;
|
||||||
|
UserField **user_fields;
|
||||||
|
};
|
||||||
|
#define HEADER__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&header__descriptor) \
|
||||||
|
, NULL, NULL, NULL, 0, 0, 0,NULL }
|
||||||
|
|
||||||
|
|
||||||
|
struct _UserField
|
||||||
|
{
|
||||||
|
ProtobufCMessage base;
|
||||||
|
char *key;
|
||||||
|
protobuf_c_boolean has_value;
|
||||||
|
ProtobufCBinaryData value;
|
||||||
|
};
|
||||||
|
#define USER_FIELD__INIT \
|
||||||
|
{ PROTOBUF_C_MESSAGE_INIT (&user_field__descriptor) \
|
||||||
|
, NULL, 0, {0,NULL} }
|
||||||
|
|
||||||
|
|
||||||
|
/* MercuryMultiGetRequest methods */
|
||||||
|
void mercury_multi_get_request__init
|
||||||
|
(MercuryMultiGetRequest *message);
|
||||||
|
size_t mercury_multi_get_request__get_packed_size
|
||||||
|
(const MercuryMultiGetRequest *message);
|
||||||
|
size_t mercury_multi_get_request__pack
|
||||||
|
(const MercuryMultiGetRequest *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t mercury_multi_get_request__pack_to_buffer
|
||||||
|
(const MercuryMultiGetRequest *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
MercuryMultiGetRequest *
|
||||||
|
mercury_multi_get_request__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void mercury_multi_get_request__free_unpacked
|
||||||
|
(MercuryMultiGetRequest *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* MercuryMultiGetReply methods */
|
||||||
|
void mercury_multi_get_reply__init
|
||||||
|
(MercuryMultiGetReply *message);
|
||||||
|
size_t mercury_multi_get_reply__get_packed_size
|
||||||
|
(const MercuryMultiGetReply *message);
|
||||||
|
size_t mercury_multi_get_reply__pack
|
||||||
|
(const MercuryMultiGetReply *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t mercury_multi_get_reply__pack_to_buffer
|
||||||
|
(const MercuryMultiGetReply *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
MercuryMultiGetReply *
|
||||||
|
mercury_multi_get_reply__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void mercury_multi_get_reply__free_unpacked
|
||||||
|
(MercuryMultiGetReply *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* MercuryRequest methods */
|
||||||
|
void mercury_request__init
|
||||||
|
(MercuryRequest *message);
|
||||||
|
size_t mercury_request__get_packed_size
|
||||||
|
(const MercuryRequest *message);
|
||||||
|
size_t mercury_request__pack
|
||||||
|
(const MercuryRequest *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t mercury_request__pack_to_buffer
|
||||||
|
(const MercuryRequest *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
MercuryRequest *
|
||||||
|
mercury_request__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void mercury_request__free_unpacked
|
||||||
|
(MercuryRequest *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* MercuryReply methods */
|
||||||
|
void mercury_reply__init
|
||||||
|
(MercuryReply *message);
|
||||||
|
size_t mercury_reply__get_packed_size
|
||||||
|
(const MercuryReply *message);
|
||||||
|
size_t mercury_reply__pack
|
||||||
|
(const MercuryReply *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t mercury_reply__pack_to_buffer
|
||||||
|
(const MercuryReply *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
MercuryReply *
|
||||||
|
mercury_reply__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void mercury_reply__free_unpacked
|
||||||
|
(MercuryReply *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* Header methods */
|
||||||
|
void header__init
|
||||||
|
(Header *message);
|
||||||
|
size_t header__get_packed_size
|
||||||
|
(const Header *message);
|
||||||
|
size_t header__pack
|
||||||
|
(const Header *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t header__pack_to_buffer
|
||||||
|
(const Header *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
Header *
|
||||||
|
header__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void header__free_unpacked
|
||||||
|
(Header *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* UserField methods */
|
||||||
|
void user_field__init
|
||||||
|
(UserField *message);
|
||||||
|
size_t user_field__get_packed_size
|
||||||
|
(const UserField *message);
|
||||||
|
size_t user_field__pack
|
||||||
|
(const UserField *message,
|
||||||
|
uint8_t *out);
|
||||||
|
size_t user_field__pack_to_buffer
|
||||||
|
(const UserField *message,
|
||||||
|
ProtobufCBuffer *buffer);
|
||||||
|
UserField *
|
||||||
|
user_field__unpack
|
||||||
|
(ProtobufCAllocator *allocator,
|
||||||
|
size_t len,
|
||||||
|
const uint8_t *data);
|
||||||
|
void user_field__free_unpacked
|
||||||
|
(UserField *message,
|
||||||
|
ProtobufCAllocator *allocator);
|
||||||
|
/* --- per-message closures --- */
|
||||||
|
|
||||||
|
typedef void (*MercuryMultiGetRequest_Closure)
|
||||||
|
(const MercuryMultiGetRequest *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*MercuryMultiGetReply_Closure)
|
||||||
|
(const MercuryMultiGetReply *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*MercuryRequest_Closure)
|
||||||
|
(const MercuryRequest *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*MercuryReply_Closure)
|
||||||
|
(const MercuryReply *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*Header_Closure)
|
||||||
|
(const Header *message,
|
||||||
|
void *closure_data);
|
||||||
|
typedef void (*UserField_Closure)
|
||||||
|
(const UserField *message,
|
||||||
|
void *closure_data);
|
||||||
|
|
||||||
|
/* --- services --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* --- descriptors --- */
|
||||||
|
|
||||||
|
extern const ProtobufCMessageDescriptor mercury_multi_get_request__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor mercury_multi_get_reply__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor mercury_request__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor mercury_reply__descriptor;
|
||||||
|
extern const ProtobufCEnumDescriptor mercury_reply__cache_policy__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor header__descriptor;
|
||||||
|
extern const ProtobufCMessageDescriptor user_field__descriptor;
|
||||||
|
|
||||||
|
PROTOBUF_C__END_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* PROTOBUF_C_proto_2fmercury_2eproto__INCLUDED */
|
|
@ -0,0 +1,46 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message MercuryMultiGetRequest {
|
||||||
|
repeated MercuryRequest request = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MercuryMultiGetReply {
|
||||||
|
repeated MercuryReply reply = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MercuryRequest {
|
||||||
|
optional string uri = 0x1;
|
||||||
|
optional string content_type = 0x2;
|
||||||
|
optional bytes body = 0x3;
|
||||||
|
optional bytes etag = 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MercuryReply {
|
||||||
|
optional sint32 status_code = 0x1;
|
||||||
|
optional string status_message = 0x2;
|
||||||
|
optional CachePolicy cache_policy = 0x3;
|
||||||
|
enum CachePolicy {
|
||||||
|
CACHE_NO = 0x1;
|
||||||
|
CACHE_PRIVATE = 0x2;
|
||||||
|
CACHE_PUBLIC = 0x3;
|
||||||
|
}
|
||||||
|
optional sint32 ttl = 0x4;
|
||||||
|
optional bytes etag = 0x5;
|
||||||
|
optional string content_type = 0x6;
|
||||||
|
optional bytes body = 0x7;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message Header {
|
||||||
|
optional string uri = 0x01;
|
||||||
|
optional string content_type = 0x02;
|
||||||
|
optional string method = 0x03;
|
||||||
|
optional sint32 status_code = 0x04;
|
||||||
|
repeated UserField user_fields = 0x06;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UserField {
|
||||||
|
optional string key = 0x01;
|
||||||
|
optional bytes value = 0x02;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message MergedProfileRequest {
|
||||||
|
}
|
||||||
|
|
||||||
|
message MergedProfileReply {
|
||||||
|
optional string username = 0x1;
|
||||||
|
optional string artistid = 0x2;
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,266 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message TopTracks {
|
||||||
|
optional string country = 0x1;
|
||||||
|
repeated Track track = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ActivityPeriod {
|
||||||
|
optional sint32 start_year = 0x1;
|
||||||
|
optional sint32 end_year = 0x2;
|
||||||
|
optional sint32 decade = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Artist {
|
||||||
|
optional bytes gid = 0x1;
|
||||||
|
optional string name = 0x2;
|
||||||
|
optional sint32 popularity = 0x3;
|
||||||
|
repeated TopTracks top_track = 0x4;
|
||||||
|
repeated AlbumGroup album_group = 0x5;
|
||||||
|
repeated AlbumGroup single_group = 0x6;
|
||||||
|
repeated AlbumGroup compilation_group = 0x7;
|
||||||
|
repeated AlbumGroup appears_on_group = 0x8;
|
||||||
|
repeated string genre = 0x9;
|
||||||
|
repeated ExternalId external_id = 0xa;
|
||||||
|
repeated Image portrait = 0xb;
|
||||||
|
repeated Biography biography = 0xc;
|
||||||
|
repeated ActivityPeriod activity_period = 0xd;
|
||||||
|
repeated Restriction restriction = 0xe;
|
||||||
|
repeated Artist related = 0xf;
|
||||||
|
optional bool is_portrait_album_cover = 0x10;
|
||||||
|
optional ImageGroup portrait_group = 0x11;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AlbumGroup {
|
||||||
|
repeated Album album = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Date {
|
||||||
|
optional sint32 year = 0x1;
|
||||||
|
optional sint32 month = 0x2;
|
||||||
|
optional sint32 day = 0x3;
|
||||||
|
optional sint32 hour = 0x4;
|
||||||
|
optional sint32 minute = 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Album {
|
||||||
|
optional bytes gid = 0x1;
|
||||||
|
optional string name = 0x2;
|
||||||
|
repeated Artist artist = 0x3;
|
||||||
|
optional Type typ = 0x4;
|
||||||
|
enum Type {
|
||||||
|
ALBUM = 0x1;
|
||||||
|
SINGLE = 0x2;
|
||||||
|
COMPILATION = 0x3;
|
||||||
|
EP = 0x4;
|
||||||
|
}
|
||||||
|
optional string label = 0x5;
|
||||||
|
optional Date date = 0x6;
|
||||||
|
optional sint32 popularity = 0x7;
|
||||||
|
repeated string genre = 0x8;
|
||||||
|
repeated Image cover = 0x9;
|
||||||
|
repeated ExternalId external_id = 0xa;
|
||||||
|
repeated Disc disc = 0xb;
|
||||||
|
repeated string review = 0xc;
|
||||||
|
repeated Copyright copyright = 0xd;
|
||||||
|
repeated Restriction restriction = 0xe;
|
||||||
|
repeated Album related = 0xf;
|
||||||
|
repeated SalePeriod sale_period = 0x10;
|
||||||
|
optional ImageGroup cover_group = 0x11;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Track {
|
||||||
|
optional bytes gid = 0x1;
|
||||||
|
optional string name = 0x2;
|
||||||
|
optional Album album = 0x3;
|
||||||
|
repeated Artist artist = 0x4;
|
||||||
|
optional sint32 number = 0x5;
|
||||||
|
optional sint32 disc_number = 0x6;
|
||||||
|
optional sint32 duration = 0x7;
|
||||||
|
optional sint32 popularity = 0x8;
|
||||||
|
optional bool explicit = 0x9;
|
||||||
|
repeated ExternalId external_id = 0xa;
|
||||||
|
repeated Restriction restriction = 0xb;
|
||||||
|
repeated AudioFile file = 0xc;
|
||||||
|
repeated Track alternative = 0xd;
|
||||||
|
repeated SalePeriod sale_period = 0xe;
|
||||||
|
repeated AudioFile preview = 0xf;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Image {
|
||||||
|
optional bytes file_id = 0x1;
|
||||||
|
optional Size size = 0x2;
|
||||||
|
enum Size {
|
||||||
|
DEFAULT = 0x0;
|
||||||
|
SMALL = 0x1;
|
||||||
|
LARGE = 0x2;
|
||||||
|
XLARGE = 0x3;
|
||||||
|
}
|
||||||
|
optional sint32 width = 0x3;
|
||||||
|
optional sint32 height = 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ImageGroup {
|
||||||
|
repeated Image image = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Biography {
|
||||||
|
optional string text = 0x1;
|
||||||
|
repeated Image portrait = 0x2;
|
||||||
|
repeated ImageGroup portrait_group = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Disc {
|
||||||
|
optional sint32 number = 0x1;
|
||||||
|
optional string name = 0x2;
|
||||||
|
repeated Track track = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Copyright {
|
||||||
|
optional Type typ = 0x1;
|
||||||
|
enum Type {
|
||||||
|
P = 0x0;
|
||||||
|
C = 0x1;
|
||||||
|
}
|
||||||
|
optional string text = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Restriction {
|
||||||
|
enum Catalogue {
|
||||||
|
AD = 0;
|
||||||
|
SUBSCRIPTION = 1;
|
||||||
|
CATALOGUE_ALL = 2;
|
||||||
|
SHUFFLE = 3;
|
||||||
|
COMMERCIAL = 4;
|
||||||
|
}
|
||||||
|
enum Type {
|
||||||
|
STREAMING = 0x0;
|
||||||
|
}
|
||||||
|
repeated Catalogue catalogue = 0x1;
|
||||||
|
optional string countries_allowed = 0x2;
|
||||||
|
optional string countries_forbidden = 0x3;
|
||||||
|
optional Type typ = 0x4;
|
||||||
|
|
||||||
|
repeated string catalogue_str = 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Availability {
|
||||||
|
repeated string catalogue_str = 0x1;
|
||||||
|
optional Date start = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SalePeriod {
|
||||||
|
repeated Restriction restriction = 0x1;
|
||||||
|
optional Date start = 0x2;
|
||||||
|
optional Date end = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ExternalId {
|
||||||
|
optional string typ = 0x1;
|
||||||
|
optional string id = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AudioFile {
|
||||||
|
optional bytes file_id = 0x1;
|
||||||
|
optional Format format = 0x2;
|
||||||
|
enum Format {
|
||||||
|
OGG_VORBIS_96 = 0x0;
|
||||||
|
OGG_VORBIS_160 = 0x1;
|
||||||
|
OGG_VORBIS_320 = 0x2;
|
||||||
|
MP3_256 = 0x3;
|
||||||
|
MP3_320 = 0x4;
|
||||||
|
MP3_160 = 0x5;
|
||||||
|
MP3_96 = 0x6;
|
||||||
|
MP3_160_ENC = 0x7;
|
||||||
|
// v4
|
||||||
|
// AAC_24 = 0x8;
|
||||||
|
// AAC_48 = 0x9;
|
||||||
|
MP4_128_DUAL = 0x8;
|
||||||
|
OTHER3 = 0x9;
|
||||||
|
AAC_160 = 0xa;
|
||||||
|
AAC_320 = 0xb;
|
||||||
|
MP4_128 = 0xc;
|
||||||
|
OTHER5 = 0xd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message VideoFile {
|
||||||
|
optional bytes file_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Podcast Protos
|
||||||
|
message Show {
|
||||||
|
enum MediaType {
|
||||||
|
MIXED = 0;
|
||||||
|
AUDIO = 1;
|
||||||
|
VIDEO = 2;
|
||||||
|
}
|
||||||
|
enum ConsumptionOrder {
|
||||||
|
SEQUENTIAL = 1;
|
||||||
|
EPISODIC = 2;
|
||||||
|
RECENT = 3;
|
||||||
|
}
|
||||||
|
enum PassthroughEnum {
|
||||||
|
UNKNOWN = 0;
|
||||||
|
NONE = 1;
|
||||||
|
ALLOWED = 2;
|
||||||
|
}
|
||||||
|
optional bytes gid = 0x1;
|
||||||
|
optional string name = 0x2;
|
||||||
|
optional string description = 0x40;
|
||||||
|
optional sint32 deprecated_popularity = 0x41;
|
||||||
|
optional string publisher = 0x42;
|
||||||
|
optional string language = 0x43;
|
||||||
|
optional bool explicit = 0x44;
|
||||||
|
optional ImageGroup covers = 0x45;
|
||||||
|
repeated Episode episode = 0x46;
|
||||||
|
repeated Copyright copyright = 0x47;
|
||||||
|
repeated Restriction restriction = 0x48;
|
||||||
|
repeated string keyword = 0x49;
|
||||||
|
optional MediaType media_type = 0x4A;
|
||||||
|
optional ConsumptionOrder consumption_order = 0x4B;
|
||||||
|
optional bool interpret_restriction_using_geoip = 0x4C;
|
||||||
|
repeated Availability availability = 0x4E;
|
||||||
|
optional string country_of_origin = 0x4F;
|
||||||
|
repeated Category categories = 0x50;
|
||||||
|
optional PassthroughEnum passthrough = 0x51;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Episode {
|
||||||
|
optional bytes gid = 0x1;
|
||||||
|
optional string name = 0x2;
|
||||||
|
optional sint32 duration = 0x7;
|
||||||
|
optional sint32 popularity = 0x8;
|
||||||
|
repeated AudioFile file = 0xc;
|
||||||
|
optional string description = 0x40;
|
||||||
|
optional sint32 number = 0x41;
|
||||||
|
optional Date publish_time = 0x42;
|
||||||
|
optional sint32 deprecated_popularity = 0x43;
|
||||||
|
optional ImageGroup covers = 0x44;
|
||||||
|
optional string language = 0x45;
|
||||||
|
optional bool explicit = 0x46;
|
||||||
|
optional Show show = 0x47;
|
||||||
|
repeated VideoFile video = 0x48;
|
||||||
|
repeated VideoFile video_preview = 0x49;
|
||||||
|
repeated AudioFile audio_preview = 0x4A;
|
||||||
|
repeated Restriction restriction = 0x4B;
|
||||||
|
optional ImageGroup freeze_frame = 0x4C;
|
||||||
|
repeated string keyword = 0x4D;
|
||||||
|
// Order of these two flags might be wrong!
|
||||||
|
optional bool suppress_monetization = 0x4E;
|
||||||
|
optional bool interpret_restriction_using_geoip = 0x4F;
|
||||||
|
|
||||||
|
optional bool allow_background_playback = 0x51;
|
||||||
|
repeated Availability availability = 0x52;
|
||||||
|
optional string external_url = 0x53;
|
||||||
|
optional OriginalAudio original_audio = 0x54;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Category {
|
||||||
|
optional string name = 0x1;
|
||||||
|
repeated Category subcategories = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message OriginalAudio {
|
||||||
|
optional bytes uuid = 0x1;
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
import "playlist4ops.proto";
|
||||||
|
import "playlist4meta.proto";
|
||||||
|
import "playlist4content.proto";
|
||||||
|
import "playlist4issues.proto";
|
||||||
|
|
||||||
|
message ChangeInfo {
|
||||||
|
optional string user = 0x1;
|
||||||
|
optional int32 timestamp = 0x2;
|
||||||
|
optional bool admin = 0x3;
|
||||||
|
optional bool undo = 0x4;
|
||||||
|
optional bool redo = 0x5;
|
||||||
|
optional bool merge = 0x6;
|
||||||
|
optional bool compressed = 0x7;
|
||||||
|
optional bool migration = 0x8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Delta {
|
||||||
|
optional bytes base_version = 0x1;
|
||||||
|
repeated Op ops = 0x2;
|
||||||
|
optional ChangeInfo info = 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Merge {
|
||||||
|
optional bytes base_version = 0x1;
|
||||||
|
optional bytes merge_version = 0x2;
|
||||||
|
optional ChangeInfo info = 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ChangeSet {
|
||||||
|
optional Kind kind = 0x1;
|
||||||
|
enum Kind {
|
||||||
|
KIND_UNKNOWN = 0x0;
|
||||||
|
DELTA = 0x2;
|
||||||
|
MERGE = 0x3;
|
||||||
|
}
|
||||||
|
optional Delta delta = 0x2;
|
||||||
|
optional Merge merge = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RevisionTaggedChangeSet {
|
||||||
|
optional bytes revision = 0x1;
|
||||||
|
optional ChangeSet change_set = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Diff {
|
||||||
|
optional bytes from_revision = 0x1;
|
||||||
|
repeated Op ops = 0x2;
|
||||||
|
optional bytes to_revision = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListDump {
|
||||||
|
optional bytes latestRevision = 0x1;
|
||||||
|
optional int32 length = 0x2;
|
||||||
|
optional ListAttributes attributes = 0x3;
|
||||||
|
optional ListChecksum checksum = 0x4;
|
||||||
|
optional ListItems contents = 0x5;
|
||||||
|
repeated Delta pendingDeltas = 0x7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListChanges {
|
||||||
|
optional bytes baseRevision = 0x1;
|
||||||
|
repeated Delta deltas = 0x2;
|
||||||
|
optional bool wantResultingRevisions = 0x3;
|
||||||
|
optional bool wantSyncResult = 0x4;
|
||||||
|
optional ListDump dump = 0x5;
|
||||||
|
repeated int32 nonces = 0x6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SelectedListContent {
|
||||||
|
optional bytes revision = 0x1;
|
||||||
|
optional int32 length = 0x2;
|
||||||
|
optional ListAttributes attributes = 0x3;
|
||||||
|
optional ListChecksum checksum = 0x4;
|
||||||
|
optional ListItems contents = 0x5;
|
||||||
|
optional Diff diff = 0x6;
|
||||||
|
optional Diff syncResult = 0x7;
|
||||||
|
repeated bytes resultingRevisions = 0x8;
|
||||||
|
optional bool multipleHeads = 0x9;
|
||||||
|
optional bool upToDate = 0xa;
|
||||||
|
repeated ClientResolveAction resolveAction = 0xc;
|
||||||
|
repeated ClientIssue issues = 0xd;
|
||||||
|
repeated int32 nonces = 0xe;
|
||||||
|
optional string owner_username =0x10;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
import "playlist4meta.proto";
|
||||||
|
import "playlist4issues.proto";
|
||||||
|
|
||||||
|
message Item {
|
||||||
|
optional string uri = 0x1;
|
||||||
|
optional ItemAttributes attributes = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListItems {
|
||||||
|
optional int32 pos = 0x1;
|
||||||
|
optional bool truncated = 0x2;
|
||||||
|
repeated Item items = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ContentRange {
|
||||||
|
optional int32 pos = 0x1;
|
||||||
|
optional int32 length = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListContentSelection {
|
||||||
|
optional bool wantRevision = 0x1;
|
||||||
|
optional bool wantLength = 0x2;
|
||||||
|
optional bool wantAttributes = 0x3;
|
||||||
|
optional bool wantChecksum = 0x4;
|
||||||
|
optional bool wantContent = 0x5;
|
||||||
|
optional ContentRange contentRange = 0x6;
|
||||||
|
optional bool wantDiff = 0x7;
|
||||||
|
optional bytes baseRevision = 0x8;
|
||||||
|
optional bytes hintRevision = 0x9;
|
||||||
|
optional bool wantNothingIfUpToDate = 0xa;
|
||||||
|
optional bool wantResolveAction = 0xc;
|
||||||
|
repeated ClientIssue issues = 0xd;
|
||||||
|
repeated ClientResolveAction resolveAction = 0xe;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message ClientIssue {
|
||||||
|
optional Level level = 0x1;
|
||||||
|
enum Level {
|
||||||
|
LEVEL_UNKNOWN = 0x0;
|
||||||
|
LEVEL_DEBUG = 0x1;
|
||||||
|
LEVEL_INFO = 0x2;
|
||||||
|
LEVEL_NOTICE = 0x3;
|
||||||
|
LEVEL_WARNING = 0x4;
|
||||||
|
LEVEL_ERROR = 0x5;
|
||||||
|
}
|
||||||
|
optional Code code = 0x2;
|
||||||
|
enum Code {
|
||||||
|
CODE_UNKNOWN = 0x0;
|
||||||
|
CODE_INDEX_OUT_OF_BOUNDS = 0x1;
|
||||||
|
CODE_VERSION_MISMATCH = 0x2;
|
||||||
|
CODE_CACHED_CHANGE = 0x3;
|
||||||
|
CODE_OFFLINE_CHANGE = 0x4;
|
||||||
|
CODE_CONCURRENT_CHANGE = 0x5;
|
||||||
|
}
|
||||||
|
optional int32 repeatCount = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ClientResolveAction {
|
||||||
|
optional Code code = 0x1;
|
||||||
|
enum Code {
|
||||||
|
CODE_UNKNOWN = 0x0;
|
||||||
|
CODE_NO_ACTION = 0x1;
|
||||||
|
CODE_RETRY = 0x2;
|
||||||
|
CODE_RELOAD = 0x3;
|
||||||
|
CODE_DISCARD_LOCAL_CHANGES = 0x4;
|
||||||
|
CODE_SEND_DUMP = 0x5;
|
||||||
|
CODE_DISPLAY_ERROR_MESSAGE = 0x6;
|
||||||
|
}
|
||||||
|
optional Initiator initiator = 0x2;
|
||||||
|
enum Initiator {
|
||||||
|
INITIATOR_UNKNOWN = 0x0;
|
||||||
|
INITIATOR_SERVER = 0x1;
|
||||||
|
INITIATOR_CLIENT = 0x2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message ListChecksum {
|
||||||
|
optional int32 version = 0x1;
|
||||||
|
optional bytes sha1 = 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DownloadFormat {
|
||||||
|
optional Codec codec = 0x1;
|
||||||
|
enum Codec {
|
||||||
|
CODEC_UNKNOWN = 0x0;
|
||||||
|
OGG_VORBIS = 0x1;
|
||||||
|
FLAC = 0x2;
|
||||||
|
MPEG_1_LAYER_3 = 0x3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListAttributes {
|
||||||
|
optional string name = 0x1;
|
||||||
|
optional string description = 0x2;
|
||||||
|
optional bytes picture = 0x3;
|
||||||
|
optional bool collaborative = 0x4;
|
||||||
|
optional string pl3_version = 0x5;
|
||||||
|
optional bool deleted_by_owner = 0x6;
|
||||||
|
optional bool restricted_collaborative = 0x7;
|
||||||
|
optional int64 deprecated_client_id = 0x8;
|
||||||
|
optional bool public_starred = 0x9;
|
||||||
|
optional string client_id = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ItemAttributes {
|
||||||
|
optional string added_by = 0x1;
|
||||||
|
optional int64 timestamp = 0x2;
|
||||||
|
optional string message = 0x3;
|
||||||
|
optional bool seen = 0x4;
|
||||||
|
optional int64 download_count = 0x5;
|
||||||
|
optional DownloadFormat download_format = 0x6;
|
||||||
|
optional string sevendigital_id = 0x7;
|
||||||
|
optional int64 sevendigital_left = 0x8;
|
||||||
|
optional int64 seen_at = 0x9;
|
||||||
|
optional bool public = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StringAttribute {
|
||||||
|
optional string key = 0x1;
|
||||||
|
optional string value = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StringAttributes {
|
||||||
|
repeated StringAttribute attribute = 0x1;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
import "playlist4meta.proto";
|
||||||
|
import "playlist4content.proto";
|
||||||
|
|
||||||
|
message Add {
|
||||||
|
optional int32 fromIndex = 0x1;
|
||||||
|
repeated Item items = 0x2;
|
||||||
|
optional ListChecksum list_checksum = 0x3;
|
||||||
|
optional bool addLast = 0x4;
|
||||||
|
optional bool addFirst = 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Rem {
|
||||||
|
optional int32 fromIndex = 0x1;
|
||||||
|
optional int32 length = 0x2;
|
||||||
|
repeated Item items = 0x3;
|
||||||
|
optional ListChecksum list_checksum = 0x4;
|
||||||
|
optional ListChecksum items_checksum = 0x5;
|
||||||
|
optional ListChecksum uris_checksum = 0x6;
|
||||||
|
optional bool itemsAsKey = 0x7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Mov {
|
||||||
|
optional int32 fromIndex = 0x1;
|
||||||
|
optional int32 length = 0x2;
|
||||||
|
optional int32 toIndex = 0x3;
|
||||||
|
optional ListChecksum list_checksum = 0x4;
|
||||||
|
optional ListChecksum items_checksum = 0x5;
|
||||||
|
optional ListChecksum uris_checksum = 0x6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ItemAttributesPartialState {
|
||||||
|
optional ItemAttributes values = 0x1;
|
||||||
|
repeated ItemAttributeKind no_value = 0x2;
|
||||||
|
|
||||||
|
enum ItemAttributeKind {
|
||||||
|
ITEM_UNKNOWN = 0x0;
|
||||||
|
ITEM_ADDED_BY = 0x1;
|
||||||
|
ITEM_TIMESTAMP = 0x2;
|
||||||
|
ITEM_MESSAGE = 0x3;
|
||||||
|
ITEM_SEEN = 0x4;
|
||||||
|
ITEM_DOWNLOAD_COUNT = 0x5;
|
||||||
|
ITEM_DOWNLOAD_FORMAT = 0x6;
|
||||||
|
ITEM_SEVENDIGITAL_ID = 0x7;
|
||||||
|
ITEM_SEVENDIGITAL_LEFT = 0x8;
|
||||||
|
ITEM_SEEN_AT = 0x9;
|
||||||
|
ITEM_PUBLIC = 0xa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListAttributesPartialState {
|
||||||
|
optional ListAttributes values = 0x1;
|
||||||
|
repeated ListAttributeKind no_value = 0x2;
|
||||||
|
|
||||||
|
enum ListAttributeKind {
|
||||||
|
LIST_UNKNOWN = 0x0;
|
||||||
|
LIST_NAME = 0x1;
|
||||||
|
LIST_DESCRIPTION = 0x2;
|
||||||
|
LIST_PICTURE = 0x3;
|
||||||
|
LIST_COLLABORATIVE = 0x4;
|
||||||
|
LIST_PL3_VERSION = 0x5;
|
||||||
|
LIST_DELETED_BY_OWNER = 0x6;
|
||||||
|
LIST_RESTRICTED_COLLABORATIVE = 0x7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateItemAttributes {
|
||||||
|
optional int32 index = 0x1;
|
||||||
|
optional ItemAttributesPartialState new_attributes = 0x2;
|
||||||
|
optional ItemAttributesPartialState old_attributes = 0x3;
|
||||||
|
optional ListChecksum list_checksum = 0x4;
|
||||||
|
optional ListChecksum old_attributes_checksum = 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateListAttributes {
|
||||||
|
optional ListAttributesPartialState new_attributes = 0x1;
|
||||||
|
optional ListAttributesPartialState old_attributes = 0x2;
|
||||||
|
optional ListChecksum list_checksum = 0x3;
|
||||||
|
optional ListChecksum old_attributes_checksum = 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Op {
|
||||||
|
optional Kind kind = 0x1;
|
||||||
|
enum Kind {
|
||||||
|
KIND_UNKNOWN = 0x0;
|
||||||
|
ADD = 0x2;
|
||||||
|
REM = 0x3;
|
||||||
|
MOV = 0x4;
|
||||||
|
UPDATE_ITEM_ATTRIBUTES = 0x5;
|
||||||
|
UPDATE_LIST_ATTRIBUTES = 0x6;
|
||||||
|
}
|
||||||
|
optional Add add = 0x2;
|
||||||
|
optional Rem rem = 0x3;
|
||||||
|
optional Mov mov = 0x4;
|
||||||
|
optional UpdateItemAttributes update_item_attributes = 0x5;
|
||||||
|
optional UpdateListAttributes update_list_attributes = 0x6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message OpList {
|
||||||
|
repeated Op ops = 0x1;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message PopcountRequest {
|
||||||
|
}
|
||||||
|
|
||||||
|
message PopcountResult {
|
||||||
|
optional sint64 count = 0x1;
|
||||||
|
optional bool truncated = 0x2;
|
||||||
|
repeated string user = 0x3;
|
||||||
|
repeated sint64 subscriptionTimestamps = 0x4;
|
||||||
|
repeated sint64 insertionTimestamps = 0x5;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message PlaylistPublishedState {
|
||||||
|
optional string uri = 0x1;
|
||||||
|
optional int64 timestamp = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PlaylistTrackAddedState {
|
||||||
|
optional string playlist_uri = 0x1;
|
||||||
|
optional string track_uri = 0x2;
|
||||||
|
optional int64 timestamp = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TrackFinishedPlayingState {
|
||||||
|
optional string uri = 0x1;
|
||||||
|
optional string context_uri = 0x2;
|
||||||
|
optional int64 timestamp = 0x3;
|
||||||
|
optional string referrer_uri = 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FavoriteAppAddedState {
|
||||||
|
optional string app_uri = 0x1;
|
||||||
|
optional int64 timestamp = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TrackStartedPlayingState {
|
||||||
|
optional string uri = 0x1;
|
||||||
|
optional string context_uri = 0x2;
|
||||||
|
optional int64 timestamp = 0x3;
|
||||||
|
optional string referrer_uri = 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UriSharedState {
|
||||||
|
optional string uri = 0x1;
|
||||||
|
optional string message = 0x2;
|
||||||
|
optional int64 timestamp = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ArtistFollowedState {
|
||||||
|
optional string uri = 0x1;
|
||||||
|
optional string artist_name = 0x2;
|
||||||
|
optional string artist_cover_uri = 0x3;
|
||||||
|
optional int64 timestamp = 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeviceInformation {
|
||||||
|
optional string os = 0x1;
|
||||||
|
optional string type = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GenericPresenceState {
|
||||||
|
optional int32 type = 0x1;
|
||||||
|
optional int64 timestamp = 0x2;
|
||||||
|
optional string item_uri = 0x3;
|
||||||
|
optional string item_name = 0x4;
|
||||||
|
optional string item_image = 0x5;
|
||||||
|
optional string context_uri = 0x6;
|
||||||
|
optional string context_name = 0x7;
|
||||||
|
optional string context_image = 0x8;
|
||||||
|
optional string referrer_uri = 0x9;
|
||||||
|
optional string referrer_name = 0xa;
|
||||||
|
optional string referrer_image = 0xb;
|
||||||
|
optional string message = 0xc;
|
||||||
|
optional DeviceInformation device_information = 0xd;
|
||||||
|
}
|
||||||
|
|
||||||
|
message State {
|
||||||
|
optional int64 timestamp = 0x1;
|
||||||
|
optional Type type = 0x2;
|
||||||
|
enum Type {
|
||||||
|
PLAYLIST_PUBLISHED = 0x1;
|
||||||
|
PLAYLIST_TRACK_ADDED = 0x2;
|
||||||
|
TRACK_FINISHED_PLAYING = 0x3;
|
||||||
|
FAVORITE_APP_ADDED = 0x4;
|
||||||
|
TRACK_STARTED_PLAYING = 0x5;
|
||||||
|
URI_SHARED = 0x6;
|
||||||
|
ARTIST_FOLLOWED = 0x7;
|
||||||
|
GENERIC = 0xb;
|
||||||
|
}
|
||||||
|
optional string uri = 0x3;
|
||||||
|
optional PlaylistPublishedState playlist_published = 0x4;
|
||||||
|
optional PlaylistTrackAddedState playlist_track_added = 0x5;
|
||||||
|
optional TrackFinishedPlayingState track_finished_playing = 0x6;
|
||||||
|
optional FavoriteAppAddedState favorite_app_added = 0x7;
|
||||||
|
optional TrackStartedPlayingState track_started_playing = 0x8;
|
||||||
|
optional UriSharedState uri_shared = 0x9;
|
||||||
|
optional ArtistFollowedState artist_followed = 0xa;
|
||||||
|
optional GenericPresenceState generic = 0xb;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StateList {
|
||||||
|
repeated State states = 0x1;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message Subscription {
|
||||||
|
optional string uri = 0x1;
|
||||||
|
optional int32 expiry = 0x2;
|
||||||
|
optional int32 status_code = 0x3;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message RadioRequest {
|
||||||
|
repeated string uris = 0x1;
|
||||||
|
optional int32 salt = 0x2;
|
||||||
|
optional int32 length = 0x4;
|
||||||
|
optional string stationId = 0x5;
|
||||||
|
repeated string lastTracks = 0x6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MultiSeedRequest {
|
||||||
|
repeated string uris = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Feedback {
|
||||||
|
optional string uri = 0x1;
|
||||||
|
optional string type = 0x2;
|
||||||
|
optional double timestamp = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Tracks {
|
||||||
|
repeated string gids = 0x1;
|
||||||
|
optional string source = 0x2;
|
||||||
|
optional string identity = 0x3;
|
||||||
|
repeated string tokens = 0x4;
|
||||||
|
repeated Feedback feedback = 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Station {
|
||||||
|
optional string id = 0x1;
|
||||||
|
optional string title = 0x2;
|
||||||
|
optional string titleUri = 0x3;
|
||||||
|
optional string subtitle = 0x4;
|
||||||
|
optional string subtitleUri = 0x5;
|
||||||
|
optional string imageUri = 0x6;
|
||||||
|
optional double lastListen = 0x7;
|
||||||
|
repeated string seeds = 0x8;
|
||||||
|
optional int32 thumbsUp = 0x9;
|
||||||
|
optional int32 thumbsDown = 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Rules {
|
||||||
|
optional string js = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StationResponse {
|
||||||
|
optional Station station = 0x1;
|
||||||
|
repeated Feedback feedback = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StationList {
|
||||||
|
repeated Station stations = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message LikedPlaylist {
|
||||||
|
optional string uri = 0x1;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message SearchRequest {
|
||||||
|
optional string query = 0x1;
|
||||||
|
optional Type type = 0x2;
|
||||||
|
enum Type {
|
||||||
|
TRACK = 0x0;
|
||||||
|
ALBUM = 0x1;
|
||||||
|
ARTIST = 0x2;
|
||||||
|
PLAYLIST = 0x3;
|
||||||
|
USER = 0x4;
|
||||||
|
}
|
||||||
|
optional int32 limit = 0x3;
|
||||||
|
optional int32 offset = 0x4;
|
||||||
|
optional bool did_you_mean = 0x5;
|
||||||
|
optional string spotify_uri = 0x2;
|
||||||
|
repeated bytes file_id = 0x3;
|
||||||
|
optional string url = 0x4;
|
||||||
|
optional string slask_id = 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Playlist {
|
||||||
|
optional string uri = 0x1;
|
||||||
|
optional string name = 0x2;
|
||||||
|
repeated Image image = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message User {
|
||||||
|
optional string username = 0x1;
|
||||||
|
optional string full_name = 0x2;
|
||||||
|
repeated Image image = 0x3;
|
||||||
|
optional sint32 followers = 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SearchReply {
|
||||||
|
optional sint32 hits = 0x1;
|
||||||
|
repeated Track track = 0x2;
|
||||||
|
repeated Album album = 0x3;
|
||||||
|
repeated Artist artist = 0x4;
|
||||||
|
repeated Playlist playlist = 0x5;
|
||||||
|
optional string did_you_mean = 0x6;
|
||||||
|
repeated User user = 0x7;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message DecorationData {
|
||||||
|
optional string username = 0x1;
|
||||||
|
optional string full_name = 0x2;
|
||||||
|
optional string image_url = 0x3;
|
||||||
|
optional string large_image_url = 0x5;
|
||||||
|
optional string first_name = 0x6;
|
||||||
|
optional string last_name = 0x7;
|
||||||
|
optional string facebook_uid = 0x8;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message CountReply {
|
||||||
|
repeated int32 counts = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UserListRequest {
|
||||||
|
optional string last_result = 0x1;
|
||||||
|
optional int32 count = 0x2;
|
||||||
|
optional bool include_length = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UserListReply {
|
||||||
|
repeated User users = 0x1;
|
||||||
|
optional int32 length = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message User {
|
||||||
|
optional string username = 0x1;
|
||||||
|
optional int32 subscriber_count = 0x2;
|
||||||
|
optional int32 subscription_count = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ArtistListReply {
|
||||||
|
repeated Artist artists = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Artist {
|
||||||
|
optional string artistid = 0x1;
|
||||||
|
optional int32 subscriber_count = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StringListRequest {
|
||||||
|
repeated string args = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StringListReply {
|
||||||
|
repeated string reply = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TopPlaylistsRequest {
|
||||||
|
optional string username = 0x1;
|
||||||
|
optional int32 count = 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TopPlaylistsReply {
|
||||||
|
repeated string uris = 0x1;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message Frame {
|
||||||
|
optional uint32 version = 0x1;
|
||||||
|
optional string ident = 0x2;
|
||||||
|
optional string protocol_version = 0x3;
|
||||||
|
optional uint32 seq_nr = 0x4;
|
||||||
|
optional MessageType typ = 0x5;
|
||||||
|
optional DeviceState device_state = 0x7;
|
||||||
|
optional Goodbye goodbye = 0xb;
|
||||||
|
optional State state = 0xc;
|
||||||
|
optional uint32 position = 0xd;
|
||||||
|
optional uint32 volume = 0xe;
|
||||||
|
optional int64 state_update_id = 0x11;
|
||||||
|
repeated string recipient = 0x12;
|
||||||
|
optional bytes context_player_state = 0x13;
|
||||||
|
optional string new_name = 0x14;
|
||||||
|
optional Metadata metadata = 0x19;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MessageType {
|
||||||
|
kMessageTypeHello = 0x1;
|
||||||
|
kMessageTypeGoodbye = 0x2;
|
||||||
|
kMessageTypeProbe = 0x3;
|
||||||
|
kMessageTypeNotify = 0xa;
|
||||||
|
kMessageTypeLoad = 0x14;
|
||||||
|
kMessageTypePlay = 0x15;
|
||||||
|
kMessageTypePause = 0x16;
|
||||||
|
kMessageTypePlayPause = 0x17;
|
||||||
|
kMessageTypeSeek = 0x18;
|
||||||
|
kMessageTypePrev = 0x19;
|
||||||
|
kMessageTypeNext = 0x1a;
|
||||||
|
kMessageTypeVolume = 0x1b;
|
||||||
|
kMessageTypeShuffle = 0x1c;
|
||||||
|
kMessageTypeRepeat = 0x1d;
|
||||||
|
kMessageTypeVolumeDown = 0x1f;
|
||||||
|
kMessageTypeVolumeUp = 0x20;
|
||||||
|
kMessageTypeReplace = 0x21;
|
||||||
|
kMessageTypeLogout = 0x22;
|
||||||
|
kMessageTypeAction = 0x23;
|
||||||
|
kMessageTypeRename = 0x24;
|
||||||
|
kMessageTypeUpdateMetadata = 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeviceState {
|
||||||
|
optional string sw_version = 0x1;
|
||||||
|
optional bool is_active = 0xa;
|
||||||
|
optional bool can_play = 0xb;
|
||||||
|
optional uint32 volume = 0xc;
|
||||||
|
optional string name = 0xd;
|
||||||
|
optional uint32 error_code = 0xe;
|
||||||
|
optional int64 became_active_at = 0xf;
|
||||||
|
optional string error_message = 0x10;
|
||||||
|
repeated Capability capabilities = 0x11;
|
||||||
|
optional string context_player_error = 0x14;
|
||||||
|
repeated Metadata metadata = 0x19;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Capability {
|
||||||
|
optional CapabilityType typ = 0x1;
|
||||||
|
repeated int64 intValue = 0x2;
|
||||||
|
repeated string stringValue = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CapabilityType {
|
||||||
|
kSupportedContexts = 0x1;
|
||||||
|
kCanBePlayer = 0x2;
|
||||||
|
kRestrictToLocal = 0x3;
|
||||||
|
kDeviceType = 0x4;
|
||||||
|
kGaiaEqConnectId = 0x5;
|
||||||
|
kSupportsLogout = 0x6;
|
||||||
|
kIsObservable = 0x7;
|
||||||
|
kVolumeSteps = 0x8;
|
||||||
|
kSupportedTypes = 0x9;
|
||||||
|
kCommandAcks = 0xa;
|
||||||
|
kSupportsRename = 0xb;
|
||||||
|
kHidden = 0xc;
|
||||||
|
kSupportsPlaylistV2 = 0xd;
|
||||||
|
kSupportsExternalEpisodes = 0xe;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Goodbye {
|
||||||
|
optional string reason = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message State {
|
||||||
|
optional string context_uri = 0x2;
|
||||||
|
optional uint32 index = 0x3;
|
||||||
|
optional uint32 position_ms = 0x4;
|
||||||
|
optional PlayStatus status = 0x5;
|
||||||
|
optional uint64 position_measured_at = 0x7;
|
||||||
|
optional string context_description = 0x8;
|
||||||
|
optional bool shuffle = 0xd;
|
||||||
|
optional bool repeat = 0xe;
|
||||||
|
optional string last_command_ident = 0x14;
|
||||||
|
optional uint32 last_command_msgid = 0x15;
|
||||||
|
optional bool playing_from_fallback = 0x18;
|
||||||
|
optional uint32 row = 0x19;
|
||||||
|
optional uint32 playing_track_index = 0x1a;
|
||||||
|
repeated TrackRef track = 0x1b;
|
||||||
|
optional Ad ad = 0x1c;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PlayStatus {
|
||||||
|
kPlayStatusStop = 0x0;
|
||||||
|
kPlayStatusPlay = 0x1;
|
||||||
|
kPlayStatusPause = 0x2;
|
||||||
|
kPlayStatusLoading = 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TrackRef {
|
||||||
|
optional bytes gid = 0x1;
|
||||||
|
optional string uri = 0x2;
|
||||||
|
optional bool queued = 0x3;
|
||||||
|
optional string context = 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Ad {
|
||||||
|
optional int32 next = 0x1;
|
||||||
|
optional bytes ogg_fid = 0x2;
|
||||||
|
optional bytes image_fid = 0x3;
|
||||||
|
optional int32 duration = 0x4;
|
||||||
|
optional string click_url = 0x5;
|
||||||
|
optional string impression_url = 0x6;
|
||||||
|
optional string product = 0x7;
|
||||||
|
optional string advertiser = 0x8;
|
||||||
|
optional bytes gid = 0x9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Metadata {
|
||||||
|
optional string type = 0x1;
|
||||||
|
optional string metadata = 0x2;
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message Track {
|
||||||
|
optional bytes gid = 0x1;
|
||||||
|
optional string name = 0x2;
|
||||||
|
optional bytes image = 0x3;
|
||||||
|
repeated string artist_name = 0x4;
|
||||||
|
repeated bytes artist_gid = 0x5;
|
||||||
|
optional uint32 rank = 0x6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Artist {
|
||||||
|
optional bytes gid = 0x1;
|
||||||
|
optional string name = 0x2;
|
||||||
|
optional bytes image = 0x3;
|
||||||
|
optional uint32 rank = 0x6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Album {
|
||||||
|
optional bytes gid = 0x1;
|
||||||
|
optional string name = 0x2;
|
||||||
|
optional bytes image = 0x3;
|
||||||
|
repeated string artist_name = 0x4;
|
||||||
|
repeated bytes artist_gid = 0x5;
|
||||||
|
optional uint32 rank = 0x6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Playlist {
|
||||||
|
optional string uri = 0x1;
|
||||||
|
optional string name = 0x2;
|
||||||
|
optional string image_uri = 0x3;
|
||||||
|
optional string owner_name = 0x4;
|
||||||
|
optional string owner_uri = 0x5;
|
||||||
|
optional uint32 rank = 0x6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Suggestions {
|
||||||
|
repeated Track track = 0x1;
|
||||||
|
repeated Album album = 0x2;
|
||||||
|
repeated Artist artist = 0x3;
|
||||||
|
repeated Playlist playlist = 0x4;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message Toplist {
|
||||||
|
repeated string items = 0x1;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/* $Id: $ */
|
||||||
|
/* Shannon: Shannon stream cipher and MAC header files */
|
||||||
|
|
||||||
|
/*
|
||||||
|
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND AGAINST
|
||||||
|
INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SHN_DEFINED
|
||||||
|
#define _SHN_DEFINED 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define SHANNON_N 16
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t R[SHANNON_N]; /* Working storage for the shift register */
|
||||||
|
uint32_t CRC[SHANNON_N]; /* Working storage for CRC accumulation */
|
||||||
|
uint32_t initR[SHANNON_N]; /* saved register contents */
|
||||||
|
uint32_t konst; /* key dependent semi-constant */
|
||||||
|
uint32_t sbuf; /* encryption buffer */
|
||||||
|
uint32_t mbuf; /* partial word MAC buffer */
|
||||||
|
int nbuf; /* number of part-word stream bits buffered */
|
||||||
|
} shn_ctx;
|
||||||
|
|
||||||
|
/* interface definitions */
|
||||||
|
void shn_key(shn_ctx *c, const uint8_t key[], int keylen); /* set key */
|
||||||
|
void shn_nonce(shn_ctx *c, const uint8_t nonce[], int nlen); /* set Init Vector */
|
||||||
|
void shn_stream(shn_ctx *c, uint8_t *buf, int nbytes); /* stream cipher */
|
||||||
|
void shn_maconly(shn_ctx *c, uint8_t *buf, int nbytes); /* accumulate MAC */
|
||||||
|
void shn_encrypt(shn_ctx *c, uint8_t *buf, int nbytes); /* encrypt + MAC */
|
||||||
|
void shn_decrypt(shn_ctx *c, uint8_t *buf, int nbytes); /* decrypt + MAC */
|
||||||
|
void shn_finish(shn_ctx *c, uint8_t *buf, int nbytes); /* finalise MAC */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _SHN_DEFINED */
|
|
@ -0,0 +1,626 @@
|
||||||
|
/* $Id: shnfast.c 442 2006-05-12 23:22:21Z ggr $ */
|
||||||
|
/* ShannonFast: Shannon stream cipher and MAC -- fast implementation */
|
||||||
|
|
||||||
|
/*
|
||||||
|
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND AGAINST
|
||||||
|
INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* interface, multiplication table and SBox */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "ShannonInternal.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FOLD is how many register cycles need to be performed after combining the
|
||||||
|
* last byte of key and non-linear feedback, before every byte depends on every
|
||||||
|
* byte of the key. This depends on the feedback and nonlinear functions, and
|
||||||
|
* on where they are combined into the register. Making it same as the
|
||||||
|
* register length is a safe and conservative choice.
|
||||||
|
*/
|
||||||
|
#define FOLD N /* how many iterations of folding to do */
|
||||||
|
#define INITKONST 0x6996c53a /* value of KONST to use during key loading */
|
||||||
|
#define KEYP 13 /* where to insert key/MAC words */
|
||||||
|
|
||||||
|
#define Byte(x,i) ((UCHAR)(((x) >> (8*i)) & 0xFF))
|
||||||
|
|
||||||
|
/* define IS_LITTLE_ENDIAN for faster operation when appropriate */
|
||||||
|
#ifdef IS_LITTLE_ENDIAN
|
||||||
|
/* Useful macros -- little endian words on a little endian machine */
|
||||||
|
#define BYTE2WORD(b) (*(WORD *)(b))
|
||||||
|
#define WORD2BYTE(w, b) ((*(WORD *)(b)) = w)
|
||||||
|
#define XORWORD(w, b) ((*(WORD *)(b)) ^= w)
|
||||||
|
#else
|
||||||
|
/* Useful macros -- machine independent little-endian version */
|
||||||
|
#define BYTE2WORD(b) ( \
|
||||||
|
(((WORD)(b)[3] & 0xFF)<<24) | \
|
||||||
|
(((WORD)(b)[2] & 0xFF)<<16) | \
|
||||||
|
(((WORD)(b)[1] & 0xFF)<<8) | \
|
||||||
|
(((WORD)(b)[0] & 0xFF)) \
|
||||||
|
)
|
||||||
|
#define WORD2BYTE(w, b) { \
|
||||||
|
(b)[3] = Byte(w,3); \
|
||||||
|
(b)[2] = Byte(w,2); \
|
||||||
|
(b)[1] = Byte(w,1); \
|
||||||
|
(b)[0] = Byte(w,0); \
|
||||||
|
}
|
||||||
|
#define XORWORD(w, b) { \
|
||||||
|
(b)[3] ^= Byte(w,3); \
|
||||||
|
(b)[2] ^= Byte(w,2); \
|
||||||
|
(b)[1] ^= Byte(w,1); \
|
||||||
|
(b)[0] ^= Byte(w,0); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* give correct offset for the current position of the register,
|
||||||
|
* where logically R[0] is at position "zero". Note that this works for
|
||||||
|
* both the stream register and the CRC register.
|
||||||
|
*/
|
||||||
|
#define OFF(zero, i) (((zero)+(i)) % N)
|
||||||
|
|
||||||
|
/* step the shift register */
|
||||||
|
/* After stepping, "zero" moves right one place */
|
||||||
|
#define STEP(c,z) \
|
||||||
|
{ \
|
||||||
|
t = c->R[OFF(z,12)] ^ c->R[OFF(z,13)] ^ c->konst; \
|
||||||
|
/* Sbox 1 */ \
|
||||||
|
t ^= ROTL(t, 5) | ROTL(t, 7); \
|
||||||
|
t ^= ROTL(t, 19) | ROTL(t, 22); \
|
||||||
|
c->R[OFF(z,0)] = t ^ ROTL(c->R[OFF(z,0)],1); \
|
||||||
|
t = c->R[OFF((z+1),2)] ^ c->R[OFF((z+1),15)]; \
|
||||||
|
/* Sbox 2 */ \
|
||||||
|
t ^= ROTL(t, 7) | ROTL(t, 22); \
|
||||||
|
t ^= ROTL(t, 5) | ROTL(t, 19); \
|
||||||
|
c->R[OFF((z+1),0)] ^= t; \
|
||||||
|
c->sbuf = t ^ c->R[OFF((z+1),8)] ^ c->R[OFF((z+1),12)]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cycle(shn_ctx *c)
|
||||||
|
{
|
||||||
|
WORD t;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* nonlinear feedback function */
|
||||||
|
STEP(c,0);
|
||||||
|
/* shift register */
|
||||||
|
t = c->R[0];
|
||||||
|
for (i = 1; i < N; ++i)
|
||||||
|
c->R[i-1] = c->R[i];
|
||||||
|
c->R[N-1] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The Shannon MAC function is modelled after the concepts of Phelix and SHA.
|
||||||
|
* Basically, words to be accumulated in the MAC are incorporated in two
|
||||||
|
* different ways:
|
||||||
|
* 1. They are incorporated into the stream cipher register at a place
|
||||||
|
* where they will immediately have a nonlinear effect on the state
|
||||||
|
* 2. They are incorporated into bit-parallel CRC-16 registers; the
|
||||||
|
* contents of these registers will be used in MAC finalization.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Accumulate a CRC of input words, later to be fed into MAC.
|
||||||
|
* This is actually 32 parallel CRC-16s, using the IBM CRC-16
|
||||||
|
* polynomial x^16 + x^15 + x^2 + 1.
|
||||||
|
*/
|
||||||
|
#define CRCFUNC(c,i,z) \
|
||||||
|
{ \
|
||||||
|
c->CRC[OFF(z,0)] ^= c->CRC[OFF(z,2)] ^ c->CRC[OFF(z,15)] ^ i; \
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
crcfunc(shn_ctx *c, WORD i)
|
||||||
|
{
|
||||||
|
WORD t;
|
||||||
|
|
||||||
|
CRCFUNC(c, i, 0);
|
||||||
|
/* now correct alignment of CRC accumulator */
|
||||||
|
t = c->CRC[0];
|
||||||
|
for (i = 1; i < N; ++i)
|
||||||
|
c->CRC[i-1] = c->CRC[i];
|
||||||
|
c->CRC[N-1] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Normal MAC word processing: do both SHA and CRC.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
macfunc(shn_ctx *c, WORD i)
|
||||||
|
{
|
||||||
|
crcfunc(c, i);
|
||||||
|
c->R[KEYP] ^= i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialise to known state
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
shn_initstate(shn_ctx *c)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Register initialised to Fibonacci numbers; Counter zeroed. */
|
||||||
|
c->R[0] = 1;
|
||||||
|
c->R[1] = 1;
|
||||||
|
for (i = 2; i < N; ++i)
|
||||||
|
c->R[i] = c->R[i-1] + c->R[i-2];
|
||||||
|
c->konst = INITKONST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the current register state
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
shn_savestate(shn_ctx *c)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < N; ++i)
|
||||||
|
c->initR[i] = c->R[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialise to previously saved register state
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
shn_reloadstate(shn_ctx *c)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < N; ++i)
|
||||||
|
c->R[i] = c->initR[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialise "konst"
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
shn_genkonst(shn_ctx *c)
|
||||||
|
{
|
||||||
|
c->konst = c->R[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load key material into the register
|
||||||
|
*/
|
||||||
|
#define ADDKEY(k) \
|
||||||
|
c->R[KEYP] ^= (k);
|
||||||
|
|
||||||
|
/* nonlinear diffusion of register for key and MAC */
|
||||||
|
#define DROUND(z) { register WORD t; STEP(c,z); }
|
||||||
|
static void
|
||||||
|
shn_diffuse(shn_ctx *c)
|
||||||
|
{
|
||||||
|
/* relies on FOLD == N! */
|
||||||
|
DROUND(0);
|
||||||
|
DROUND(1);
|
||||||
|
DROUND(2);
|
||||||
|
DROUND(3);
|
||||||
|
DROUND(4);
|
||||||
|
DROUND(5);
|
||||||
|
DROUND(6);
|
||||||
|
DROUND(7);
|
||||||
|
DROUND(8);
|
||||||
|
DROUND(9);
|
||||||
|
DROUND(10);
|
||||||
|
DROUND(11);
|
||||||
|
DROUND(12);
|
||||||
|
DROUND(13);
|
||||||
|
DROUND(14);
|
||||||
|
DROUND(15);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* common actions for loading key material
|
||||||
|
* Allow non-word-multiple key and nonce materianl
|
||||||
|
* Note also initializes the CRC register as a side effect.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
shn_loadkey(shn_ctx *c, const uint8_t key[], int keylen)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
WORD k;
|
||||||
|
uint8_t xtra[4];
|
||||||
|
|
||||||
|
/* start folding in key */
|
||||||
|
for (i = 0; i < (keylen & ~0x3); i += 4)
|
||||||
|
{
|
||||||
|
k = BYTE2WORD(&key[i]);
|
||||||
|
ADDKEY(k);
|
||||||
|
cycle(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if there were any extra key bytes, zero pad to a word */
|
||||||
|
if (i < keylen) {
|
||||||
|
for (j = 0 /* i unchanged */; i < keylen; ++i)
|
||||||
|
xtra[j++] = key[i];
|
||||||
|
for (/* j unchanged */; j < 4; ++j)
|
||||||
|
xtra[j] = 0;
|
||||||
|
k = BYTE2WORD(xtra);
|
||||||
|
ADDKEY(k);
|
||||||
|
cycle(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* also fold in the length of the key */
|
||||||
|
ADDKEY(keylen);
|
||||||
|
cycle(c);
|
||||||
|
|
||||||
|
/* save a copy of the register */
|
||||||
|
for (i = 0; i < N; ++i)
|
||||||
|
c->CRC[i] = c->R[i];
|
||||||
|
|
||||||
|
/* now diffuse */
|
||||||
|
shn_diffuse(c);
|
||||||
|
|
||||||
|
/* now xor the copy back -- makes key loading irreversible */
|
||||||
|
for (i = 0; i < N; ++i)
|
||||||
|
c->R[i] ^= c->CRC[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Published "key" interface
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
shn_key(shn_ctx *c, const uint8_t key[], int keylen)
|
||||||
|
{
|
||||||
|
shn_initstate(c);
|
||||||
|
shn_loadkey(c, key, keylen);
|
||||||
|
shn_genkonst(c);
|
||||||
|
shn_savestate(c);
|
||||||
|
c->nbuf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Published "nonce" interface
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
shn_nonce(shn_ctx *c, const uint8_t nonce[], int noncelen)
|
||||||
|
{
|
||||||
|
shn_reloadstate(c);
|
||||||
|
c->konst = INITKONST;
|
||||||
|
shn_loadkey(c, nonce, noncelen);
|
||||||
|
shn_genkonst(c);
|
||||||
|
c->nbuf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XOR pseudo-random bytes into buffer
|
||||||
|
* Note: doesn't play well with MAC functions.
|
||||||
|
*/
|
||||||
|
#define SROUND(z) \
|
||||||
|
{ register WORD t; \
|
||||||
|
STEP(c,z); \
|
||||||
|
XORWORD(c->sbuf, buf+(z*4)); \
|
||||||
|
}
|
||||||
|
void
|
||||||
|
shn_stream(shn_ctx *c, uint8_t *buf, int nbytes)
|
||||||
|
{
|
||||||
|
/* handle any previously buffered bytes */
|
||||||
|
while (c->nbuf != 0 && nbytes != 0) {
|
||||||
|
*buf++ ^= c->sbuf & 0xFF;
|
||||||
|
c->sbuf >>= 8;
|
||||||
|
c->nbuf -= 8;
|
||||||
|
--nbytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do lots at a time, if there's enough to do */
|
||||||
|
while (nbytes >= N*4)
|
||||||
|
{
|
||||||
|
SROUND(0);
|
||||||
|
SROUND(1);
|
||||||
|
SROUND(2);
|
||||||
|
SROUND(3);
|
||||||
|
SROUND(4);
|
||||||
|
SROUND(5);
|
||||||
|
SROUND(6);
|
||||||
|
SROUND(7);
|
||||||
|
SROUND(8);
|
||||||
|
SROUND(9);
|
||||||
|
SROUND(10);
|
||||||
|
SROUND(11);
|
||||||
|
SROUND(12);
|
||||||
|
SROUND(13);
|
||||||
|
SROUND(14);
|
||||||
|
SROUND(15);
|
||||||
|
buf += 4*N;
|
||||||
|
nbytes -= N*4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do small or odd size buffers the slow way */
|
||||||
|
while (4 <= nbytes) {
|
||||||
|
cycle(c);
|
||||||
|
XORWORD(c->sbuf, buf);
|
||||||
|
buf += 4;
|
||||||
|
nbytes -= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle any trailing bytes */
|
||||||
|
if (nbytes != 0) {
|
||||||
|
cycle(c);
|
||||||
|
c->nbuf = 32;
|
||||||
|
while (c->nbuf != 0 && nbytes != 0) {
|
||||||
|
*buf++ ^= c->sbuf & 0xFF;
|
||||||
|
c->sbuf >>= 8;
|
||||||
|
c->nbuf -= 8;
|
||||||
|
--nbytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* accumulate words into MAC without encryption
|
||||||
|
* Note that plaintext is accumulated for MAC.
|
||||||
|
*/
|
||||||
|
#define MROUND(z) \
|
||||||
|
{ register WORD t, t1; \
|
||||||
|
t1 = BYTE2WORD(buf+(z*4)); \
|
||||||
|
STEP(c,z); \
|
||||||
|
CRCFUNC(c,t1,z); \
|
||||||
|
c->R[OFF(z+1,KEYP)] ^= t1; \
|
||||||
|
}
|
||||||
|
void
|
||||||
|
shn_maconly(shn_ctx *c, uint8_t *buf, int nbytes)
|
||||||
|
{
|
||||||
|
/* handle any previously buffered bytes */
|
||||||
|
if (c->nbuf != 0) {
|
||||||
|
while (c->nbuf != 0 && nbytes != 0) {
|
||||||
|
c->mbuf ^= (*buf++) << (32 - c->nbuf);
|
||||||
|
c->nbuf -= 8;
|
||||||
|
--nbytes;
|
||||||
|
}
|
||||||
|
if (c->nbuf != 0) /* not a whole word yet */
|
||||||
|
return;
|
||||||
|
/* LFSR already cycled */
|
||||||
|
macfunc(c, c->mbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do lots at a time, if there's enough to do */
|
||||||
|
while (4*N <= nbytes)
|
||||||
|
{
|
||||||
|
MROUND( 0);
|
||||||
|
MROUND( 1);
|
||||||
|
MROUND( 2);
|
||||||
|
MROUND( 3);
|
||||||
|
MROUND( 4);
|
||||||
|
MROUND( 5);
|
||||||
|
MROUND( 6);
|
||||||
|
MROUND( 7);
|
||||||
|
MROUND( 8);
|
||||||
|
MROUND( 9);
|
||||||
|
MROUND(10);
|
||||||
|
MROUND(11);
|
||||||
|
MROUND(12);
|
||||||
|
MROUND(13);
|
||||||
|
MROUND(14);
|
||||||
|
MROUND(15);
|
||||||
|
buf += 4*N;
|
||||||
|
nbytes -= 4*N;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do small or odd size buffers the slow way */
|
||||||
|
while (4 <= nbytes) {
|
||||||
|
cycle(c);
|
||||||
|
macfunc(c, BYTE2WORD(buf));
|
||||||
|
buf += 4;
|
||||||
|
nbytes -= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle any trailing bytes */
|
||||||
|
if (nbytes != 0) {
|
||||||
|
cycle(c);
|
||||||
|
c->mbuf = 0;
|
||||||
|
c->nbuf = 32;
|
||||||
|
while (nbytes != 0) {
|
||||||
|
c->mbuf ^= (*buf++) << (32 - c->nbuf);
|
||||||
|
c->nbuf -= 8;
|
||||||
|
--nbytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Combined MAC and encryption.
|
||||||
|
* Note that plaintext is accumulated for MAC.
|
||||||
|
*/
|
||||||
|
#define EROUND(z) \
|
||||||
|
{ register WORD t, t3; \
|
||||||
|
STEP(c,z); \
|
||||||
|
t3 = BYTE2WORD(buf+(z*4)); \
|
||||||
|
CRCFUNC(c,t3,z); \
|
||||||
|
c->R[OFF((z+1),KEYP)] ^= t3; \
|
||||||
|
t3 ^= c->sbuf; \
|
||||||
|
WORD2BYTE(t3,buf+(z*4)); \
|
||||||
|
}
|
||||||
|
void
|
||||||
|
shn_encrypt(shn_ctx *c, uint8_t *buf, int nbytes)
|
||||||
|
{
|
||||||
|
WORD t3 = 0;
|
||||||
|
|
||||||
|
/* handle any previously buffered bytes */
|
||||||
|
if (c->nbuf != 0) {
|
||||||
|
while (c->nbuf != 0 && nbytes != 0) {
|
||||||
|
c->mbuf ^= *buf << (32 - c->nbuf);
|
||||||
|
*buf ^= (c->sbuf >> (32 - c->nbuf)) & 0xFF;
|
||||||
|
++buf;
|
||||||
|
c->nbuf -= 8;
|
||||||
|
--nbytes;
|
||||||
|
}
|
||||||
|
if (c->nbuf != 0) /* not a whole word yet */
|
||||||
|
return;
|
||||||
|
/* LFSR already cycled */
|
||||||
|
macfunc(c, c->mbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do lots at a time, if there's enough to do */
|
||||||
|
while (4*N <= nbytes)
|
||||||
|
{
|
||||||
|
EROUND( 0);
|
||||||
|
EROUND( 1);
|
||||||
|
EROUND( 2);
|
||||||
|
EROUND( 3);
|
||||||
|
EROUND( 4);
|
||||||
|
EROUND( 5);
|
||||||
|
EROUND( 6);
|
||||||
|
EROUND( 7);
|
||||||
|
EROUND( 8);
|
||||||
|
EROUND( 9);
|
||||||
|
EROUND(10);
|
||||||
|
EROUND(11);
|
||||||
|
EROUND(12);
|
||||||
|
EROUND(13);
|
||||||
|
EROUND(14);
|
||||||
|
EROUND(15);
|
||||||
|
buf += 4*N;
|
||||||
|
nbytes -= 4*N;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do small or odd size buffers the slow way */
|
||||||
|
while (4 <= nbytes) {
|
||||||
|
cycle(c);
|
||||||
|
t3 = BYTE2WORD(buf);
|
||||||
|
macfunc(c, t3);
|
||||||
|
t3 ^= c->sbuf;
|
||||||
|
WORD2BYTE(t3, buf);
|
||||||
|
nbytes -= 4;
|
||||||
|
buf += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle any trailing bytes */
|
||||||
|
if (nbytes != 0) {
|
||||||
|
cycle(c);
|
||||||
|
c->mbuf = 0;
|
||||||
|
c->nbuf = 32;
|
||||||
|
while (c->nbuf != 0 && nbytes != 0) {
|
||||||
|
c->mbuf ^= *buf << (32 - c->nbuf);
|
||||||
|
*buf ^= (c->sbuf >> (32 - c->nbuf)) & 0xFF;
|
||||||
|
++buf;
|
||||||
|
c->nbuf -= 8;
|
||||||
|
--nbytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Combined MAC and decryption.
|
||||||
|
* Note that plaintext is accumulated for MAC.
|
||||||
|
*/
|
||||||
|
#undef DROUND
|
||||||
|
#define DROUND(z) \
|
||||||
|
{ register WORD t, t3; \
|
||||||
|
STEP(c,z); \
|
||||||
|
t3 = BYTE2WORD(buf+(z*4)); \
|
||||||
|
t3 ^= c->sbuf; \
|
||||||
|
CRCFUNC(c,t3,z); \
|
||||||
|
c->R[OFF((z+1),KEYP)] ^= t3; \
|
||||||
|
WORD2BYTE(t3, buf+(z*4)); \
|
||||||
|
}
|
||||||
|
void
|
||||||
|
shn_decrypt(shn_ctx *c, uint8_t *buf, int nbytes)
|
||||||
|
{
|
||||||
|
WORD t3 = 0;
|
||||||
|
|
||||||
|
/* handle any previously buffered bytes */
|
||||||
|
if (c->nbuf != 0) {
|
||||||
|
while (c->nbuf != 0 && nbytes != 0) {
|
||||||
|
*buf ^= (c->sbuf >> (32 - c->nbuf)) & 0xFF;
|
||||||
|
c->mbuf ^= *buf << (32 - c->nbuf);
|
||||||
|
++buf;
|
||||||
|
c->nbuf -= 8;
|
||||||
|
--nbytes;
|
||||||
|
}
|
||||||
|
if (c->nbuf != 0) /* not a whole word yet */
|
||||||
|
return;
|
||||||
|
/* LFSR already cycled */
|
||||||
|
macfunc(c, c->mbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now do lots at a time, if there's enough */
|
||||||
|
while (4*N <= nbytes)
|
||||||
|
{
|
||||||
|
DROUND( 0);
|
||||||
|
DROUND( 1);
|
||||||
|
DROUND( 2);
|
||||||
|
DROUND( 3);
|
||||||
|
DROUND( 4);
|
||||||
|
DROUND( 5);
|
||||||
|
DROUND( 6);
|
||||||
|
DROUND( 7);
|
||||||
|
DROUND( 8);
|
||||||
|
DROUND( 9);
|
||||||
|
DROUND(10);
|
||||||
|
DROUND(11);
|
||||||
|
DROUND(12);
|
||||||
|
DROUND(13);
|
||||||
|
DROUND(14);
|
||||||
|
DROUND(15);
|
||||||
|
buf += 4*N;
|
||||||
|
nbytes -= 4*N;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do small or odd size buffers the slow way */
|
||||||
|
while (4 <= nbytes) {
|
||||||
|
cycle(c);
|
||||||
|
t3 = BYTE2WORD(buf);
|
||||||
|
t3 ^= c->sbuf;
|
||||||
|
macfunc(c, t3);
|
||||||
|
WORD2BYTE(t3, buf);
|
||||||
|
nbytes -= 4;
|
||||||
|
buf += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle any trailing bytes */
|
||||||
|
if (nbytes != 0) {
|
||||||
|
cycle(c);
|
||||||
|
c->mbuf = 0;
|
||||||
|
c->nbuf = 32;
|
||||||
|
while (c->nbuf != 0 && nbytes != 0) {
|
||||||
|
*buf ^= (c->sbuf >> (32 - c->nbuf)) & 0xFF;
|
||||||
|
c->mbuf ^= *buf << (32 - c->nbuf);
|
||||||
|
++buf;
|
||||||
|
c->nbuf -= 8;
|
||||||
|
--nbytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Having accumulated a MAC, finish processing and return it.
|
||||||
|
* Note that any unprocessed bytes are treated as if
|
||||||
|
* they were encrypted zero bytes, so plaintext (zero) is accumulated.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
shn_finish(shn_ctx *c, uint8_t *buf, int nbytes)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* handle any previously buffered bytes */
|
||||||
|
if (c->nbuf != 0) {
|
||||||
|
/* LFSR already cycled */
|
||||||
|
macfunc(c, c->mbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* perturb the MAC to mark end of input.
|
||||||
|
* Note that only the stream register is updated, not the CRC. This is an
|
||||||
|
* action that can't be duplicated by passing in plaintext, hence
|
||||||
|
* defeating any kind of extension attack.
|
||||||
|
*/
|
||||||
|
cycle(c);
|
||||||
|
ADDKEY(INITKONST ^ (c->nbuf << 3));
|
||||||
|
c->nbuf = 0;
|
||||||
|
|
||||||
|
/* now add the CRC to the stream register and diffuse it */
|
||||||
|
for (i = 0; i < N; ++i)
|
||||||
|
c->R[i] ^= c->CRC[i];
|
||||||
|
shn_diffuse(c);
|
||||||
|
|
||||||
|
/* produce output from the stream buffer */
|
||||||
|
while (nbytes > 0) {
|
||||||
|
cycle(c);
|
||||||
|
if (nbytes >= 4) {
|
||||||
|
WORD2BYTE(c->sbuf, buf);
|
||||||
|
nbytes -= 4;
|
||||||
|
buf += 4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (i = 0; i < nbytes; ++i)
|
||||||
|
buf[i] = Byte(c->sbuf, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef SHANNONINTERNAL_H
|
||||||
|
#define SHANNONINTERNAL_H
|
||||||
|
|
||||||
|
#include "Shannon.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#define N SHANNON_N
|
||||||
|
#define WORDSIZE 32
|
||||||
|
#define UCHAR unsigned char
|
||||||
|
|
||||||
|
#define WORD uint32_t
|
||||||
|
#define WORD_MAX UINT32_MAX
|
||||||
|
|
||||||
|
#if WORD_MAX == 0xffffffff
|
||||||
|
#define ROTL(w,x) (((w) << (x))|((w) >> (32 - (x))))
|
||||||
|
#define ROTR(w,x) (((w) >> (x))|((w) << (32 - (x))))
|
||||||
|
#else
|
||||||
|
#define ROTL(w,x) (((w) << (x))|(((w) & 0xffffffff) >> (32 - (x))))
|
||||||
|
#define ROTR(w,x) ((((w) & 0xffffffff) >> (x))|((w) << (32 - (x))))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,90 @@
|
||||||
|
#ifndef __SPOTIFYC_H__
|
||||||
|
#define __SPOTIFYC_H__
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
struct sp_session;
|
||||||
|
|
||||||
|
enum sp_bitrates
|
||||||
|
{
|
||||||
|
SP_BITRATE_96,
|
||||||
|
SP_BITRATE_160,
|
||||||
|
SP_BITRATE_320,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sp_credentials
|
||||||
|
{
|
||||||
|
char *username;
|
||||||
|
char *password;
|
||||||
|
|
||||||
|
uint8_t stored_cred[256]; // Actual size is 146, but leave room for some more
|
||||||
|
size_t stored_cred_len;
|
||||||
|
uint8_t token[256]; // Actual size is 190, but leave room for some more
|
||||||
|
size_t token_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sp_callbacks
|
||||||
|
{
|
||||||
|
void (*logged_in)(struct sp_session *session, void *cb_arg, struct sp_credentials *credentials);
|
||||||
|
void (*logged_out)(void *cb_arg);
|
||||||
|
void (*track_opened)(struct sp_session *session, void *cb_arg, int fd);
|
||||||
|
void (*track_closed)(struct sp_session *session, void *cb_arg, int fd);
|
||||||
|
void (*track_seeked)(struct sp_session *session, void *cb_arg, int fd);
|
||||||
|
void (*error)(void *cb_arg, int err, const char *errmsg);
|
||||||
|
|
||||||
|
// Bring your own https client and tcp connector
|
||||||
|
int (*https_get)(char **body, const char *url);
|
||||||
|
int (*tcp_connect)(const char *address, unsigned short port);
|
||||||
|
void (*tcp_disconnect)(int fd);
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
void (*hexdump)(const char *msg, uint8_t *data, size_t data_len);
|
||||||
|
void (*logmsg)(const char *fmt, ...);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Async interface
|
||||||
|
|
||||||
|
struct sp_session *
|
||||||
|
spotifyc_login_password(const char *username, const char *password);
|
||||||
|
|
||||||
|
struct sp_session *
|
||||||
|
spotifyc_login_stored_cred(const char *username, uint8_t *stored_cred, size_t stored_cred_len);
|
||||||
|
|
||||||
|
struct sp_session *
|
||||||
|
spotifyc_login_token(const char *username, uint8_t *token, size_t token_len);
|
||||||
|
|
||||||
|
void
|
||||||
|
spotifyc_logout(struct sp_session *session);
|
||||||
|
|
||||||
|
int
|
||||||
|
spotifyc_open(const char *path, struct sp_session *session);
|
||||||
|
|
||||||
|
void
|
||||||
|
spotifyc_bitrate_set(enum sp_bitrates bitrate, struct sp_session *session);
|
||||||
|
|
||||||
|
// Starts writing audio to the file descriptor
|
||||||
|
int
|
||||||
|
spotifyc_play(int fd);
|
||||||
|
|
||||||
|
int
|
||||||
|
spotifyc_seek(int seek_ms, int fd);
|
||||||
|
|
||||||
|
int
|
||||||
|
spotifyc_stop(int fd);
|
||||||
|
|
||||||
|
|
||||||
|
// Sync interface
|
||||||
|
|
||||||
|
const char *
|
||||||
|
spotifyc_last_errmsg(void);
|
||||||
|
|
||||||
|
// This Spotify implementation is entirely async, so first the caller must set
|
||||||
|
// up callbacks
|
||||||
|
int
|
||||||
|
spotifyc_init(struct sp_callbacks *callbacks, void *cb_arg);
|
||||||
|
|
||||||
|
void
|
||||||
|
spotifyc_deinit(void);
|
||||||
|
|
||||||
|
#endif /* !__SPOTIFYC_H__ */
|
|
@ -79,14 +79,14 @@ static pthread_t tid_library;
|
||||||
struct event_base *evbase_lib;
|
struct event_base *evbase_lib;
|
||||||
|
|
||||||
extern struct library_source filescanner;
|
extern struct library_source filescanner;
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
extern struct library_source spotifyscanner;
|
extern struct library_source spotifyscanner;
|
||||||
#endif
|
#endif
|
||||||
extern struct library_source rssscanner;
|
extern struct library_source rssscanner;
|
||||||
|
|
||||||
static struct library_source *sources[] = {
|
static struct library_source *sources[] = {
|
||||||
&filescanner,
|
&filescanner,
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
&spotifyscanner,
|
&spotifyscanner,
|
||||||
#endif
|
#endif
|
||||||
&rssscanner,
|
&rssscanner,
|
||||||
|
|
|
@ -67,7 +67,7 @@
|
||||||
#ifdef LASTFM
|
#ifdef LASTFM
|
||||||
# include "lastfm.h"
|
# include "lastfm.h"
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
# include "spotify.h"
|
# include "spotify.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -701,7 +701,7 @@ process_file(char *file, struct stat *sb, enum file_type file_type, int scan_typ
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FILE_CTRL_SPOTIFY:
|
case FILE_CTRL_SPOTIFY:
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef SPOTIFY
|
||||||
if (flags & F_SCAN_BULK)
|
if (flags & F_SCAN_BULK)
|
||||||
DPRINTF(E_LOG, L_SCAN, "Bulk scan will ignore '%s' (to process, add it after startup)\n", file);
|
DPRINTF(E_LOG, L_SCAN, "Bulk scan will ignore '%s' (to process, add it after startup)\n", file);
|
||||||
else
|
else
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
#include "listener.h"
|
#include "listener.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "misc_json.h"
|
#include "misc_json.h"
|
||||||
#include "spotify.h"
|
|
||||||
|
|
||||||
|
|
||||||
enum spotify_request_type {
|
enum spotify_request_type {
|
||||||
|
@ -1471,8 +1470,6 @@ track_add(struct spotify_track *track, struct spotify_album *album, const char *
|
||||||
free_mfi(&mfi, 1);
|
free_mfi(&mfi, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
spotify_uri_register(track->uri);
|
|
||||||
|
|
||||||
if (album && album->uri)
|
if (album && album->uri)
|
||||||
cache_artwork_ping(track->uri, album->mtime, 0);
|
cache_artwork_ping(track->uri, album->mtime, 0);
|
||||||
else
|
else
|
||||||
|
@ -1814,21 +1811,6 @@ initscan()
|
||||||
|
|
||||||
spotify_saved_plid = 0;
|
spotify_saved_plid = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
* Login to spotify needs to be done before scanning tracks from the web api.
|
|
||||||
* (Scanned tracks need to be registered with libspotify for playback)
|
|
||||||
*/
|
|
||||||
ret = spotify_relogin();
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_SPOTIFY, "libspotify-login failed. In order to use Spotify, "
|
|
||||||
"provide valid credentials for libspotify by visiting http://owntone.local:3689\n");
|
|
||||||
|
|
||||||
db_spotify_purge();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan saved tracks from the web api
|
* Scan saved tracks from the web api
|
||||||
*/
|
*/
|
||||||
|
@ -2066,12 +2048,9 @@ spotifywebapi_access_token_get(struct spotifywebapi_access_token *info)
|
||||||
static int
|
static int
|
||||||
spotifywebapi_init()
|
spotifywebapi_init()
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
|
|
||||||
CHECK_ERR(L_SPOTIFY, mutex_init(&token_lck));
|
CHECK_ERR(L_SPOTIFY, mutex_init(&token_lck));
|
||||||
ret = spotify_init();
|
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2079,8 +2058,6 @@ spotifywebapi_deinit()
|
||||||
{
|
{
|
||||||
CHECK_ERR(L_SPOTIFY, pthread_mutex_destroy(&token_lck));
|
CHECK_ERR(L_SPOTIFY, pthread_mutex_destroy(&token_lck));
|
||||||
|
|
||||||
spotify_deinit();
|
|
||||||
|
|
||||||
free_credentials();
|
free_credentials();
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,9 @@ struct artwork_get_param
|
||||||
int is_loaded;
|
int is_loaded;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
spotify_playback_stop_nonblock(void);
|
||||||
|
|
||||||
/* --- Globals --- */
|
/* --- Globals --- */
|
||||||
// Spotify thread
|
// Spotify thread
|
||||||
static pthread_t tid_spotify;
|
static pthread_t tid_spotify;
|
||||||
|
|
|
@ -26,20 +26,20 @@ spotify_playback_play();
|
||||||
int
|
int
|
||||||
spotify_playback_pause();
|
spotify_playback_pause();
|
||||||
|
|
||||||
void
|
//void
|
||||||
spotify_playback_pause_nonblock(void);
|
//spotify_playback_pause_nonblock(void);
|
||||||
|
|
||||||
int
|
int
|
||||||
spotify_playback_stop(void);
|
spotify_playback_stop(void);
|
||||||
|
|
||||||
void
|
//void
|
||||||
spotify_playback_stop_nonblock(void);
|
//spotify_playback_stop_nonblock(void);
|
||||||
|
|
||||||
int
|
int
|
||||||
spotify_playback_seek(int ms);
|
spotify_playback_seek(int ms);
|
||||||
|
|
||||||
int
|
//int
|
||||||
spotify_artwork_get(struct evbuffer *evbuf, char *path, int max_w, int max_h);
|
//spotify_artwork_get(struct evbuffer *evbuf, char *path, int max_w, int max_h);
|
||||||
|
|
||||||
int
|
int
|
||||||
spotify_relogin();
|
spotify_relogin();
|
||||||
|
|
|
@ -242,6 +242,11 @@ init_settings(struct settings_ctx *settings, enum transcode_profile profile, str
|
||||||
settings->sample_format = AV_SAMPLE_FMT_S16P;
|
settings->sample_format = AV_SAMPLE_FMT_S16P;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case XCODE_OGG:
|
||||||
|
settings->encode_audio = 1;
|
||||||
|
settings->in_format = "ogg";
|
||||||
|
break;
|
||||||
|
|
||||||
case XCODE_JPEG:
|
case XCODE_JPEG:
|
||||||
settings->encode_video = 1;
|
settings->encode_video = 1;
|
||||||
settings->silent = 1;
|
settings->silent = 1;
|
||||||
|
|
|
@ -19,13 +19,15 @@ enum transcode_profile
|
||||||
XCODE_PCM16,
|
XCODE_PCM16,
|
||||||
XCODE_PCM24,
|
XCODE_PCM24,
|
||||||
XCODE_PCM32,
|
XCODE_PCM32,
|
||||||
// Transcodes the best audio stream into MP3
|
// Transcodes the best audio stream to MP3
|
||||||
XCODE_MP3,
|
XCODE_MP3,
|
||||||
// Transcodes the best audio stream into OPUS
|
// Transcodes the best audio stream to OPUS
|
||||||
XCODE_OPUS,
|
XCODE_OPUS,
|
||||||
// Transcodes the best audio stream into ALAC
|
// Transcodes the best audio stream to ALAC
|
||||||
XCODE_ALAC,
|
XCODE_ALAC,
|
||||||
// Transcodes the best video stream into JPEG/PNG/VP8
|
// Transcodes the best audio stream from OGG
|
||||||
|
XCODE_OGG,
|
||||||
|
// Transcodes the best video stream to JPEG/PNG/VP8
|
||||||
XCODE_JPEG,
|
XCODE_JPEG,
|
||||||
XCODE_PNG,
|
XCODE_PNG,
|
||||||
XCODE_VP8,
|
XCODE_VP8,
|
||||||
|
|
Loading…
Reference in New Issue