diff --git a/src/inputs/librespot-c/Makefile.am b/src/inputs/librespot-c/Makefile.am index 08106ab9..6916a28a 100644 --- a/src/inputs/librespot-c/Makefile.am +++ b/src/inputs/librespot-c/Makefile.am @@ -11,16 +11,31 @@ PROTO_SRC = \ src/proto/mercury.pb-c.c src/proto/mercury.pb-c.h \ src/proto/metadata.pb-c.c src/proto/metadata.pb-c.h +HTTP_PROTO_SRC = \ + src/proto/connectivity.pb-c.c src/proto/connectivity.pb-c.h \ + src/proto/clienttoken.pb-c.c src/proto/clienttoken.pb-c.h \ + src/proto/login5_user_info.pb-c.h src/proto/login5_user_info.pb-c.c \ + src/proto/login5.pb-c.h src/proto/login5.pb-c.c \ + src/proto/login5_identifiers.pb-c.h src/proto/login5_identifiers.pb-c.c \ + src/proto/login5_credentials.pb-c.h src/proto/login5_credentials.pb-c.c \ + src/proto/login5_client_info.pb-c.h src/proto/login5_client_info.pb-c.c \ + src/proto/login5_challenges_hashcash.pb-c.h src/proto/login5_challenges_hashcash.pb-c.c \ + src/proto/login5_challenges_code.pb-c.h src/proto/login5_challenges_code.pb-c.c \ + src/proto/google_duration.pb-c.h src/proto/google_duration.pb-c.c \ + src/proto/storage_resolve.pb-c.h src/proto/storage_resolve.pb-c.c + CORE_SRC = \ - src/librespot-c.c src/connection.c src/channel.c src/crypto.c src/commands.c + src/librespot-c.c src/connection.c src/channel.c src/crypto.c src/commands.c \ + src/http.c librespot_c_a_SOURCES = \ $(CORE_SRC) \ $(SHANNON_SRC) \ - $(PROTO_SRC) + $(PROTO_SRC) \ + $(HTTP_PROTO_SRC) noinst_HEADERS = \ librespot-c.h src/librespot-c-internal.h src/connection.h \ - src/channel.h src/crypto.h src/commands.h + src/channel.h src/crypto.h src/commands.h src/http.h EXTRA_DIST = README.md LICENSE diff --git a/src/inputs/librespot-c/configure.ac b/src/inputs/librespot-c/configure.ac index 10b76dfa..9b0647f8 100644 --- a/src/inputs/librespot-c/configure.ac +++ b/src/inputs/librespot-c/configure.ac @@ -1,10 +1,15 @@ AC_INIT([librespot-c], [0.1]) AC_CONFIG_AUX_DIR([.]) AM_INIT_AUTOMAKE([foreign subdir-objects]) +AM_SILENT_RULES([yes]) + AC_PROG_CC AM_PROG_AR AC_PROG_RANLIB +AM_CPPFLAGS="-Wall" +AC_SUBST([AM_CPPFLAGS]) + AC_CHECK_HEADERS_ONCE([sys/utsname.h]) AC_CHECK_HEADERS([endian.h sys/endian.h libkern/OSByteOrder.h], [found_endian_headers=yes; break;]) diff --git a/src/inputs/librespot-c/librespot-c.h b/src/inputs/librespot-c/librespot-c.h index ab4f224f..37306470 100644 --- a/src/inputs/librespot-c/librespot-c.h +++ b/src/inputs/librespot-c/librespot-c.h @@ -6,7 +6,7 @@ #include #define LIBRESPOT_C_VERSION_MAJOR 0 -#define LIBRESPOT_C_VERSION_MINOR 2 +#define LIBRESPOT_C_VERSION_MINOR 4 struct sp_session; @@ -37,9 +37,13 @@ struct sp_metadata size_t file_len; }; +// How to identify towards Spotify. The device_id can be set to an actual value +// identifying the client, but the rest are unfortunately best left as zeroes, +// which will make librespot-c use defaults that spoof whitelisted clients. struct sp_sysinfo { char client_name[16]; + char client_id[33]; char client_version[16]; char client_build_id[16]; char device_id[41]; // librespot gives a 20 byte id (so 40 char hex + 1 zero term) @@ -47,8 +51,7 @@ struct sp_sysinfo struct sp_callbacks { - // Bring your own https client and tcp connector - int (*https_get)(char **body, const char *url); + // Bring your own tcp connector int (*tcp_connect)(const char *address, unsigned short port); void (*tcp_disconnect)(int fd); @@ -60,10 +63,9 @@ struct sp_callbacks void (*logmsg)(const char *fmt, ...); }; - - +// Deprecated, use login_token and login_stored_cred instead struct sp_session * -librespotc_login_password(const char *username, const char *password); +librespotc_login_password(const char *username, const char *password) __attribute__ ((deprecated)); struct sp_session * librespotc_login_stored_cred(const char *username, uint8_t *stored_cred, size_t stored_cred_len); @@ -74,6 +76,9 @@ librespotc_login_token(const char *username, const char *token); int librespotc_logout(struct sp_session *session); +int +librespotc_legacy_set(struct sp_session *session, int use_legacy); + int librespotc_bitrate_set(struct sp_session *session, enum sp_bitrates bitrate); diff --git a/src/inputs/librespot-c/src/channel.c b/src/inputs/librespot-c/src/channel.c index fb4255e5..659fe61d 100644 --- a/src/inputs/librespot-c/src/channel.c +++ b/src/inputs/librespot-c/src/channel.c @@ -63,6 +63,8 @@ channel_get(uint32_t channel_id, struct sp_session *session) void channel_free(struct sp_channel *channel) { + int i; + if (!channel || channel->state == SP_CHANNEL_STATE_UNALLOCATED) return; @@ -82,6 +84,9 @@ channel_free(struct sp_channel *channel) free(channel->file.path); + for (i = 0; i < ARRAY_SIZE(channel->file.cdnurl); i++) + free(channel->file.cdnurl[i]); + memset(channel, 0, sizeof(struct sp_channel)); channel->audio_fd[0] = -1; @@ -208,7 +213,8 @@ channel_seek_internal(struct sp_channel *channel, size_t pos, bool do_flush) channel->seek_pos = pos; // If seek + header isn't word aligned we will get up to 3 bytes before the - // actual seek position. We will remove those when they are received. + // actual seek position with the legacy protocol. We will remove those when + // they are received. channel->seek_align = (pos + SP_OGG_HEADER_LEN) % 4; seek_words = (pos + SP_OGG_HEADER_LEN) / 4; @@ -218,8 +224,8 @@ channel_seek_internal(struct sp_channel *channel, size_t pos, bool do_flush) RETURN_ERROR(SP_ERR_DECRYPTION, sp_errmsg); // Set the offset and received counter to match the seek - channel->file.offset_words = seek_words; - channel->file.received_words = seek_words; + channel->file.offset_bytes = 4 * seek_words; + channel->file.received_bytes = 4 * seek_words; return 0; @@ -241,14 +247,14 @@ channel_pause(struct sp_channel *channel) channel->state = SP_CHANNEL_STATE_PAUSED; } -// After a disconnect we connect to another one and try to resume. To make that -// work some data elements need to be reset. +// After a disconnect we connect to another AP and try to resume. To make that +// work during playback some data elements need to be reset. void channel_retry(struct sp_channel *channel) { size_t pos; - if (!channel) + if (!channel || channel->state != SP_CHANNEL_STATE_PLAYING) return; channel->is_data_mode = false; @@ -256,7 +262,7 @@ channel_retry(struct sp_channel *channel) memset(&channel->header, 0, sizeof(struct sp_channel_header)); memset(&channel->body, 0, sizeof(struct sp_channel_body)); - pos = 4 * channel->file.received_words - SP_OGG_HEADER_LEN; + pos = channel->file.received_bytes - SP_OGG_HEADER_LEN; channel_seek_internal(channel, pos, false); // false => don't flush } @@ -316,12 +322,12 @@ channel_header_handle(struct sp_channel *channel, struct sp_channel_header *head } memcpy(&be32, header->data, sizeof(be32)); - channel->file.len_words = be32toh(be32); + channel->file.len_bytes = 4 * be32toh(be32); } } static ssize_t -channel_header_trailer_read(struct sp_channel *channel, uint8_t *msg, size_t msg_len, struct sp_session *session) +channel_header_trailer_read(struct sp_channel *channel, uint8_t *msg, size_t msg_len) { ssize_t parsed_len; ssize_t consumed_len; @@ -333,10 +339,10 @@ channel_header_trailer_read(struct sp_channel *channel, uint8_t *msg, size_t msg if (msg_len == 0) { channel->file.end_of_chunk = true; - channel->file.end_of_file = (channel->file.received_words >= channel->file.len_words); + channel->file.end_of_file = (channel->file.received_bytes >= channel->file.len_bytes); // In preparation for next chunk - channel->file.offset_words += SP_CHUNK_LEN_WORDS; + channel->file.offset_bytes += SP_CHUNK_LEN; channel->is_data_mode = false; return 0; @@ -369,22 +375,19 @@ channel_header_trailer_read(struct sp_channel *channel, uint8_t *msg, size_t msg return ret; } -static ssize_t -channel_data_read(struct sp_channel *channel, uint8_t *msg, size_t msg_len, struct sp_session *session) +static int +channel_data_read(struct sp_channel *channel, uint8_t *msg, size_t msg_len) { const char *errmsg; int ret; - assert (msg_len % 4 == 0); - - channel->file.received_words += msg_len / 4; + channel->file.received_bytes += msg_len; ret = crypto_aes_decrypt(msg, msg_len, &channel->file.decrypt, &errmsg); if (ret < 0) RETURN_ERROR(SP_ERR_DECRYPTION, errmsg); // Skip Spotify header - // TODO What to do here when seeking if (!channel->is_spotify_header_received) { if (msg_len < SP_OGG_HEADER_LEN) @@ -464,7 +467,7 @@ channel_msg_read(uint16_t *channel_id, uint8_t *msg, size_t msg_len, struct sp_s msg_len -= sizeof(be); // Will set data_mode, end_of_file and end_of_chunk as appropriate - consumed_len = channel_header_trailer_read(channel, msg, msg_len, session); + consumed_len = channel_header_trailer_read(channel, msg, msg_len); if (consumed_len < 0) RETURN_ERROR((int)consumed_len, sp_errmsg); @@ -477,9 +480,9 @@ channel_msg_read(uint16_t *channel_id, uint8_t *msg, size_t msg_len, struct sp_s if (!channel->is_data_mode || !(msg_len > 0)) return 0; // Not in data mode or no data to read - consumed_len = channel_data_read(channel, msg, msg_len, session); - if (consumed_len < 0) - RETURN_ERROR((int)consumed_len, sp_errmsg); + ret = channel_data_read(channel, msg, msg_len); + if (ret < 0) + RETURN_ERROR(ret, sp_errmsg); return 0; @@ -487,3 +490,21 @@ channel_msg_read(uint16_t *channel_id, uint8_t *msg, size_t msg_len, struct sp_s return ret; } +// With http there is the Spotify Ogg header, but no chunk header/trailer +int +channel_http_body_read(struct sp_channel *channel, uint8_t *body, size_t body_len) +{ + int ret; + + ret = channel_data_read(channel, body, body_len); + if (ret < 0) + goto error; + + channel->file.end_of_chunk = true; + channel->file.end_of_file = (channel->file.received_bytes >= channel->file.len_bytes); + channel->file.offset_bytes += SP_CHUNK_LEN; + return 0; + + error: + return ret; +} diff --git a/src/inputs/librespot-c/src/channel.h b/src/inputs/librespot-c/src/channel.h index db664e66..be406f7f 100644 --- a/src/inputs/librespot-c/src/channel.h +++ b/src/inputs/librespot-c/src/channel.h @@ -30,3 +30,6 @@ channel_retry(struct sp_channel *channel); int channel_msg_read(uint16_t *channel_id, uint8_t *msg, size_t msg_len, struct sp_session *session); + +int +channel_http_body_read(struct sp_channel *channel, uint8_t *body, size_t body_len); diff --git a/src/inputs/librespot-c/src/connection.c b/src/inputs/librespot-c/src/connection.c index d021daf6..47a72e00 100644 --- a/src/inputs/librespot-c/src/connection.c +++ b/src/inputs/librespot-c/src/connection.c @@ -1,3 +1,5 @@ +#define _GNU_SOURCE // For asprintf and vasprintf + #include #include #include @@ -15,6 +17,12 @@ #include "librespot-c-internal.h" #include "connection.h" #include "channel.h" +#include "http.h" + +#define MERCURY_REQ_SIZE_MAX 4096 + +// Forgot how I arrived at this upper bound +#define HASHCASH_ITERATIONS_MAX 100000 static struct timeval sp_idle_tv = { SP_AP_DISCONNECT_SECS, 0 }; @@ -34,6 +42,23 @@ static struct sp_err_map sp_login_errors[] = { { ERROR_CODE__ApplicationBanned, "Application banned" }, }; +static struct sp_err_map sp_login5_warning_map[] = { + { SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__WARNINGS__UNKNOWN_WARNING, "Unknown warning" }, + { SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__WARNINGS__DEPRECATED_PROTOCOL_VERSION, "Deprecated protocol" }, +}; + +static struct sp_err_map sp_login5_error_map[] = { + { SPOTIFY__LOGIN5__V3__LOGIN_ERROR__UNKNOWN_ERROR, "Unknown error" }, + { SPOTIFY__LOGIN5__V3__LOGIN_ERROR__INVALID_CREDENTIALS, "Invalid credentials" }, + { SPOTIFY__LOGIN5__V3__LOGIN_ERROR__BAD_REQUEST, "Bad request" }, + { SPOTIFY__LOGIN5__V3__LOGIN_ERROR__UNSUPPORTED_LOGIN_PROTOCOL, "Unsupported login protocol" }, + { SPOTIFY__LOGIN5__V3__LOGIN_ERROR__TIMEOUT, "Timeout" }, + { SPOTIFY__LOGIN5__V3__LOGIN_ERROR__UNKNOWN_IDENTIFIER, "Unknown identifier" }, + { SPOTIFY__LOGIN5__V3__LOGIN_ERROR__TOO_MANY_ATTEMPTS, "Too many attempts" }, + { SPOTIFY__LOGIN5__V3__LOGIN_ERROR__INVALID_PHONENUMBER, "Invalid phonenumber" }, + { SPOTIFY__LOGIN5__V3__LOGIN_ERROR__TRY_AGAIN_LATER, "Try again later" }, +}; + /* ---------------------------------- MOCKING ------------------------------- */ #ifdef DEBUG_MOCK @@ -87,6 +112,23 @@ debug_mock_response(struct sp_message *msg, struct sp_connection *conn) /* --------------------------------- Helpers -------------------------------- */ +static char * +asprintf_or_die(const char *fmt, ...) +{ + char *ret = NULL; + va_list va; + + va_start(va, fmt); + if (vasprintf(&ret, fmt, va) < 0) + { + sp_cb.logmsg("Out of memory for asprintf\n"); + abort(); + } + va_end(va); + + return ret; +} + #ifdef HAVE_SYS_UTSNAME_H static void system_info_from_uname(SystemInfo *system_info) @@ -185,76 +227,22 @@ file_select(uint8_t *out, size_t out_len, Track *track, enum sp_bitrates bitrate return 0; } +static const char * +err2txt(int err, struct sp_err_map *map, size_t map_size) +{ + for (int i = 0; i < map_size; i++) + { + if (err == map[i].errorcode) + return map[i].errmsg; + } + + return "(unknown error code)"; +} /* --------------------------- Connection handling -------------------------- */ -// Connects to access point resolver and selects the first access point (unless -// it matches "avoid", i.e. an access point that previously failed) -static int -ap_resolve(char **address, unsigned short *port, const char *avoid) -{ - char *body = NULL; - json_object *jresponse = NULL; - json_object *ap_list; - json_object *ap; - char *ap_address = NULL; - char *ap_port; - int ap_num; - int ret; - int i; - - free(*address); - *address = NULL; - - ret = sp_cb.https_get(&body, SP_AP_RESOLVE_URL); - if (ret < 0) - RETURN_ERROR(SP_ERR_NOCONNECTION, "Could not connect to access point resolver"); - - jresponse = json_tokener_parse(body); - if (!jresponse) - RETURN_ERROR(SP_ERR_NOCONNECTION, "Could not parse reply from access point resolver"); - - if (! (json_object_object_get_ex(jresponse, SP_AP_RESOLVE_KEY, &ap_list) || json_object_get_type(ap_list) == json_type_array)) - RETURN_ERROR(SP_ERR_NOCONNECTION, "Unexpected reply from access point resolver"); - - ap_num = json_object_array_length(ap_list); - - for (i = 0; i < ap_num; i++) - { - ap = json_object_array_get_idx(ap_list, i); - if (! (ap && json_object_get_type(ap) == json_type_string)) - RETURN_ERROR(SP_ERR_NOCONNECTION, "Unexpected reply from access point resolver"); - - if (avoid && strncmp(avoid, json_object_get_string(ap), strlen(avoid)) == 0) - continue; // This AP has failed on us previously, so avoid - - ap_address = strdup(json_object_get_string(ap)); - break; - } - - if (!ap_address) - RETURN_ERROR(SP_ERR_NOCONNECTION, "Unexpected reply from access point resolver, no suitable access point"); - if (! (ap_port = strchr(ap_address, ':'))) - RETURN_ERROR(SP_ERR_NOCONNECTION, "Unexpected reply from access point resolver, missing port"); - *ap_port = '\0'; - ap_port += 1; - - *address = ap_address; - *port = (unsigned short)atoi(ap_port); - - json_object_put(jresponse); - free(body); - return 0; - - error: - free(ap_address); - json_object_put(jresponse); - free(body); - return ret; -} - static void -connection_clear(struct sp_connection *conn) +tcp_connection_clear(struct sp_connection *conn) { if (!conn) return; @@ -271,24 +259,14 @@ connection_clear(struct sp_connection *conn) if (conn->incoming) evbuffer_free(conn->incoming); - free(conn->ap_address); free(conn->keys.shared_secret); memset(conn, 0, sizeof(struct sp_connection)); conn->response_fd = -1; } -void -ap_disconnect(struct sp_connection *conn) -{ - if (conn->is_connected) - sp_cb.tcp_disconnect(conn->response_fd); - - connection_clear(conn); -} - static void -connection_idle_cb(int fd, short what, void *arg) +tcp_connection_idle_cb(int fd, short what, void *arg) { struct sp_connection *conn = arg; @@ -298,20 +276,13 @@ connection_idle_cb(int fd, short what, void *arg) } static int -connection_make(struct sp_connection *conn, const char *ap_avoid, struct sp_conn_callbacks *cb, void *response_cb_arg) +tcp_connection_make(struct sp_connection *conn, struct sp_server *server, struct sp_conn_callbacks *cb, void *cb_arg) { int response_fd; int ret; - if (!conn->ap_address || !conn->ap_port) - { - ret = ap_resolve(&conn->ap_address, &conn->ap_port, ap_avoid); - if (ret < 0) - RETURN_ERROR(ret, sp_errmsg); - } - #ifndef DEBUG_MOCK - response_fd = sp_cb.tcp_connect(conn->ap_address, conn->ap_port); + response_fd = sp_cb.tcp_connect(server->address, server->port); if (response_fd < 0) RETURN_ERROR(SP_ERR_NOCONNECTION, "Could not connect to access point"); #else @@ -319,11 +290,14 @@ connection_make(struct sp_connection *conn, const char *ap_avoid, struct sp_conn response_fd = debug_mock_pipe[0]; #endif - conn->response_fd = response_fd; - conn->response_ev = event_new(cb->evbase, response_fd, EV_READ | EV_PERSIST, cb->response_cb, response_cb_arg); - conn->timeout_ev = evtimer_new(cb->evbase, cb->timeout_cb, conn); + server->last_connect_ts = time(NULL); + conn->server = server; - conn->idle_ev = evtimer_new(cb->evbase, connection_idle_cb, conn); + conn->response_fd = response_fd; + conn->response_ev = event_new(cb->evbase, response_fd, EV_READ | EV_PERSIST, cb->response_cb, cb_arg); + conn->timeout_ev = evtimer_new(cb->evbase, cb->timeout_cb, cb_arg); + + conn->idle_ev = evtimer_new(cb->evbase, tcp_connection_idle_cb, conn); conn->handshake_packets = evbuffer_new(); conn->incoming = evbuffer_new(); @@ -339,47 +313,65 @@ connection_make(struct sp_connection *conn, const char *ap_avoid, struct sp_conn return 0; error: + server->last_failed_ts = time(NULL); return ret; } +static int +must_resolve(struct sp_server *server) +{ + time_t now = time(NULL); + + return (server->last_resolved_ts == 0) || (server->last_failed_ts + SP_AP_AVOID_SECS > now); +} + +void +ap_disconnect(struct sp_connection *conn) +{ + if (conn->is_connected) + sp_cb.tcp_disconnect(conn->response_fd); + + tcp_connection_clear(conn); +} + enum sp_error -ap_connect(struct sp_connection *conn, enum sp_msg_type type, time_t *cooldown_ts, const char *ap_avoid, struct sp_conn_callbacks *cb, void *cb_arg) +ap_connect(struct sp_connection *conn, struct sp_server *server, time_t *cooldown_ts, struct sp_conn_callbacks *cb, void *cb_arg) { int ret; time_t now; - if (!conn->is_connected) - { - // Protection against flooding the access points with reconnection attempts - // Note that cooldown_ts can't be part of the connection struct because - // the struct is reset between connection attempts. - now = time(NULL); - if (now > *cooldown_ts + SP_AP_COOLDOWN_SECS) // Last attempt was a long time ago - *cooldown_ts = now; - else if (now >= *cooldown_ts) // Last attempt was recent, so disallow more attempts for a while - *cooldown_ts = now + SP_AP_COOLDOWN_SECS; - else - RETURN_ERROR(SP_ERR_NOCONNECTION, "Cannot connect to access point, cooldown after disconnect is in effect"); + if (must_resolve(server)) + RETURN_ERROR(SP_ERR_NOCONNECTION, "Cannot connect to access point, it has recently failed"); - ret = connection_make(conn, ap_avoid, cb, cb_arg); - if (ret < 0) - RETURN_ERROR(ret, sp_errmsg); - } + // Protection against flooding the access points with reconnection attempts + // Note that cooldown_ts can't be part of the connection struct because + // the struct is reset between connection attempts. + now = time(NULL); + if (now > *cooldown_ts + SP_AP_COOLDOWN_SECS) // Last attempt was a long time ago + *cooldown_ts = now; + else if (now >= *cooldown_ts) // Last attempt was recent, so disallow more attempts for a while + *cooldown_ts = now + SP_AP_COOLDOWN_SECS; + else + RETURN_ERROR(SP_ERR_NOCONNECTION, "Cannot connect to access point, cooldown after disconnect is in effect"); - if (msg_is_handshake(type) || conn->handshake_completed) - return SP_OK_DONE; // Proceed right away + if (conn->is_connected) + ap_disconnect(conn); - return SP_OK_WAIT; // Caller must login again + ret = tcp_connection_make(conn, server, cb, cb_arg); + if (ret < 0) + RETURN_ERROR(ret, sp_errmsg); + + return SP_OK_DONE; error: ap_disconnect(conn); return ret; } -const char * -ap_address_get(struct sp_connection *conn) +void +ap_blacklist(struct sp_server *server) { - return conn->ap_address; + server->last_failed_ts = time(NULL); } /* ------------------------------ Raw packets ------------------------------- */ @@ -561,17 +553,161 @@ mercury_parse(struct sp_mercury *mercury, uint8_t *payload, size_t payload_len) } +/* ---------------------Request preparation (dependencies) ------------------ */ + +static enum sp_error +prepare_tcp_handshake(struct sp_seq_request *request, struct sp_conn_callbacks *cb, struct sp_session *session) +{ + int ret; + + if (!session->conn.is_connected) + { + ret = ap_connect(&session->conn, &session->accesspoint, &session->cooldown_ts, cb, session); + if (ret == SP_ERR_NOCONNECTION) + { + seq_next_set(session, request->seq_type); + session->request = seq_request_get(SP_SEQ_LOGIN, 0, session->use_legacy); + return SP_OK_WAIT; + } + else if (ret < 0) + RETURN_ERROR(ret, sp_errmsg); + } + + return SP_OK_DONE; + + error: + return ret; +} + +static enum sp_error +prepare_tcp(struct sp_seq_request *request, struct sp_conn_callbacks *cb, struct sp_session *session) +{ + int ret; + + ret = prepare_tcp_handshake(request, cb, session); + if (ret != SP_OK_DONE) + return ret; // SP_OK_WAIT if the current AP failed and we need to try a new one + + if (!session->conn.handshake_completed) + { + // Queue the current request + seq_next_set(session, request->seq_type); + session->request = seq_request_get(SP_SEQ_LOGIN, 0, session->use_legacy); + return SP_OK_WAIT; + } + + return SP_OK_DONE; +} + + /* --------------------------- Incoming messages ---------------------------- */ static enum sp_error -response_client_hello(uint8_t *msg, size_t msg_len, struct sp_session *session) +resolve_server_info_set(struct sp_server *server, const char *key, json_object *jresponse) { - struct sp_connection *conn = &session->conn; - APResponseMessage *apresponse; - size_t header_len = 4; // TODO make a define + json_object *list; + json_object *instance; + size_t address_len; + const char *s; + char *colon; + bool is_same; + bool has_failed; + int ret; + int n; + int i; + + has_failed = (server->last_failed_ts + SP_AP_AVOID_SECS > time(NULL)); + + if (! (json_object_object_get_ex(jresponse, key, &list) || json_object_get_type(list) == json_type_array)) + RETURN_ERROR(SP_ERR_NOCONNECTION, "No address list in response from access point resolver"); + + n = json_object_array_length(list); + for (i = 0, s = NULL; i < n && !s; i++) + { + instance = json_object_array_get_idx(list, i); + if (! (instance && json_object_get_type(instance) == json_type_string)) + RETURN_ERROR(SP_ERR_NOCONNECTION, "Unexpected data in response from access point resolver"); + + s = json_object_get_string(instance); // This string includes the port + address_len = strlen(server->address); + is_same = (address_len > 0) && (strncmp(s, server->address, address_len) == 0); + + if (is_same && has_failed) + s = NULL; // This AP has failed on us recently, so avoid + } + + if (!s) + RETURN_ERROR(SP_ERR_NOCONNECTION, "Response from access port resolver had no valid servers"); + + if (!is_same) + { + memset(server, 0, sizeof(struct sp_server)); + ret = snprintf(server->address, sizeof(server->address), "%s", s); + if (ret < 0 || ret >= sizeof(server->address)) + RETURN_ERROR(SP_ERR_INVALID, "AP resolver returned an address that is too long"); + + colon = strchr(server->address, ':'); + if (colon) + *colon = '\0'; + + server->port = colon ? (unsigned short)atoi(colon + 1) : 443; + } + + server->last_resolved_ts = time(NULL); + return SP_OK_DONE; + + error: + return ret; +} + +static enum sp_error +handle_ap_resolve(struct sp_message *msg, struct sp_session *session) +{ + struct http_response *hres = &msg->payload.hres; + json_object *jresponse = NULL; int ret; - apresponse = apresponse_message__unpack(NULL, msg_len - header_len, msg + header_len); + if (hres->code != HTTP_OK) + RETURN_ERROR(SP_ERR_NOCONNECTION, "AP resolver returned an error"); + + jresponse = json_tokener_parse((char *)hres->body); + if (!jresponse) + RETURN_ERROR(SP_ERR_NOCONNECTION, "Could not parse reply from access point resolver"); + + ret = resolve_server_info_set(&session->accesspoint, "accesspoint", jresponse); + if (ret < 0) + goto error; + + ret = resolve_server_info_set(&session->spclient, "spclient", jresponse); + if (ret < 0) + goto error; + + ret = resolve_server_info_set(&session->dealer, "dealer", jresponse); + if (ret < 0) + goto error; + + json_object_put(jresponse); + return SP_OK_DONE; + + error: + json_object_put(jresponse); + return ret; +} + +static enum sp_error +handle_client_hello(struct sp_message *msg, struct sp_session *session) +{ + uint8_t *payload = msg->payload.tmsg.data; + size_t payload_len = msg->payload.tmsg.len; + APResponseMessage *apresponse; + struct sp_connection *conn = &session->conn; + int ret; + + // The first 4 bytes should be the size of the message + if (payload_len < 4) + RETURN_ERROR(SP_ERR_INVALID, "Invalid apresponse from access point"); + + apresponse = apresponse_message__unpack(NULL, payload_len - 4, payload + 4); if (!apresponse) RETURN_ERROR(SP_ERR_INVALID, "Could not unpack apresponse from access point"); @@ -597,7 +733,7 @@ response_client_hello(uint8_t *msg, size_t msg_len, struct sp_session *session) } static enum sp_error -response_apwelcome(uint8_t *payload, size_t payload_len, struct sp_session *session) +handle_apwelcome(uint8_t *payload, size_t payload_len, struct sp_session *session) { APWelcome *apwelcome; int ret; @@ -627,7 +763,7 @@ response_apwelcome(uint8_t *payload, size_t payload_len, struct sp_session *sess } static enum sp_error -response_aplogin_failed(uint8_t *payload, size_t payload_len, struct sp_session *session) +handle_aplogin_failed(uint8_t *payload, size_t payload_len, struct sp_session *session) { APLoginFailed *aplogin_failed; @@ -638,15 +774,7 @@ response_aplogin_failed(uint8_t *payload, size_t payload_len, struct sp_session return SP_ERR_LOGINFAILED; } - sp_errmsg = "(unknown login error)"; - for (int i = 0; i < sizeof(sp_login_errors)/sizeof(sp_login_errors[0]); i++) - { - if (sp_login_errors[i].errorcode != aplogin_failed->error_code) - continue; - - sp_errmsg = sp_login_errors[i].errmsg; - break; - } + sp_errmsg = err2txt(aplogin_failed->error_code, sp_login_errors, ARRAY_SIZE(sp_login_errors)); aplogin_failed__free_unpacked(aplogin_failed, NULL); @@ -654,7 +782,7 @@ response_aplogin_failed(uint8_t *payload, size_t payload_len, struct sp_session } static enum sp_error -response_chunk_res(uint8_t *payload, size_t payload_len, struct sp_session *session) +handle_chunk_res(uint8_t *payload, size_t payload_len, struct sp_session *session) { struct sp_channel *channel; uint16_t channel_id; @@ -679,7 +807,7 @@ response_chunk_res(uint8_t *payload, size_t payload_len, struct sp_session *sess } static enum sp_error -response_aes_key(uint8_t *payload, size_t payload_len, struct sp_session *session) +handle_aes_key(uint8_t *payload, size_t payload_len, struct sp_session *session) { struct sp_channel *channel; const char *errmsg; @@ -711,7 +839,7 @@ response_aes_key(uint8_t *payload, size_t payload_len, struct sp_session *sessio } static enum sp_error -response_aes_key_error(uint8_t *payload, size_t payload_len, struct sp_session *session) +handle_aes_key_error(uint8_t *payload, size_t payload_len, struct sp_session *session) { sp_errmsg = "Did not get key for decrypting track"; @@ -723,7 +851,7 @@ response_aes_key_error(uint8_t *payload, size_t payload_len, struct sp_session * // (see response_cb) retry with another access point. An example of this issue // is here https://github.com/librespot-org/librespot/issues/972 static enum sp_error -response_channel_error(uint8_t *payload, size_t payload_len, struct sp_session *session) +handle_channel_error(uint8_t *payload, size_t payload_len, struct sp_session *session) { sp_errmsg = "The accces point returned a channel error"; @@ -731,7 +859,7 @@ response_channel_error(uint8_t *payload, size_t payload_len, struct sp_session * } static enum sp_error -response_mercury_req(uint8_t *payload, size_t payload_len, struct sp_session *session) +handle_mercury_req(uint8_t *payload, size_t payload_len, struct sp_session *session) { struct sp_mercury mercury = { 0 }; struct sp_channel *channel; @@ -768,7 +896,7 @@ response_mercury_req(uint8_t *payload, size_t payload_len, struct sp_session *se } static enum sp_error -response_ping(uint8_t *payload, size_t payload_len, struct sp_session *session) +handle_ping(uint8_t *payload, size_t payload_len, struct sp_session *session) { msg_pong(session); @@ -776,46 +904,297 @@ response_ping(uint8_t *payload, size_t payload_len, struct sp_session *session) } static enum sp_error -response_generic(uint8_t *msg, size_t msg_len, struct sp_session *session) +handle_clienttoken(struct sp_message *msg, struct sp_session *session) { - enum sp_cmd_type cmd; - uint8_t *payload; - size_t payload_len; + struct http_response *hres = &msg->payload.hres; + struct sp_token *token = &session->http_clienttoken; + Spotify__Clienttoken__Http__V0__ClientTokenResponse *response = NULL; int ret; - cmd = msg[0]; - payload = msg + 3; - payload_len = msg_len - 3 - 4; + if (hres->code != HTTP_OK) + RETURN_ERROR(SP_ERR_INVALID, "Request to clienttoken returned an error"); + + response = spotify__clienttoken__http__v0__client_token_response__unpack(NULL, hres->body_len, hres->body); + if (!response) + RETURN_ERROR(SP_ERR_INVALID, "Could not parse clienttoken response"); + + if (response->response_type == SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE_TYPE__RESPONSE_GRANTED_TOKEN_RESPONSE) + { + ret = snprintf(token->value, sizeof(token->value), "%s", response->granted_token->token); + if (ret < 0 || ret >= sizeof(token->value)) + RETURN_ERROR(SP_ERR_INVALID, "Unexpected clienttoken length"); + + token->expires_after_seconds = response->granted_token->expires_after_seconds; + token->refresh_after_seconds = response->granted_token->refresh_after_seconds; + token->received_ts = time(NULL); + } + else if (response->response_type == SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE_TYPE__RESPONSE_CHALLENGES_RESPONSE) + RETURN_ERROR(SP_ERR_INVALID, "Unsupported clienttoken response"); + else + RETURN_ERROR(SP_ERR_INVALID, "Unknown clienttoken response"); + + spotify__clienttoken__http__v0__client_token_response__free_unpacked(response, NULL); + return SP_OK_DONE; + + error: + spotify__clienttoken__http__v0__client_token_response__free_unpacked(response, NULL); + return ret; +} + +static void +hashcash_challenges_free(struct crypto_hashcash_challenge **challenges, int *n_challenges) +{ + for (int i = 0; i < *n_challenges; i++) + free(challenges[i]->ctx); + + free(*challenges); + *challenges = NULL; + *n_challenges = 0; +} + +static enum sp_error +handle_login5_challenges(Spotify__Login5__V3__Challenges *challenges, uint8_t *login_ctx, size_t login_ctx_len, struct sp_session *session) +{ + Spotify__Login5__V3__Challenge *this_challenge; + struct crypto_hashcash_challenge *crypto_challenge; + int ret; + int i; + + session->n_hashcash_challenges = challenges->n_challenges; + session->hashcash_challenges = calloc(challenges->n_challenges, sizeof(struct crypto_hashcash_challenge)); + + for (i = 0, crypto_challenge = session->hashcash_challenges; i < session->n_hashcash_challenges; i++, crypto_challenge++) + { + this_challenge = challenges->challenges[i]; + + if (this_challenge->challenge_case != SPOTIFY__LOGIN5__V3__CHALLENGE__CHALLENGE_HASHCASH) + RETURN_ERROR(SP_ERR_INVALID, "Received unsupported login5 challenge"); + + if (this_challenge->hashcash->prefix.len != sizeof(crypto_challenge->prefix)) + RETURN_ERROR(SP_ERR_INVALID, "Received hashcash challenge with unexpected prefix length"); + + crypto_challenge->ctx_len = login_ctx_len; + crypto_challenge->ctx = malloc(login_ctx_len); + memcpy(crypto_challenge->ctx, login_ctx, login_ctx_len); + + memcpy(crypto_challenge->prefix, this_challenge->hashcash->prefix.data, sizeof(crypto_challenge->prefix)); + crypto_challenge->wanted_zero_bits = this_challenge->hashcash->length; + crypto_challenge->max_iterations = HASHCASH_ITERATIONS_MAX; + + } + + return SP_OK_DONE; + + error: + hashcash_challenges_free(&session->hashcash_challenges, &session->n_hashcash_challenges); + return ret; +} + +static enum sp_error +handle_login5(struct sp_message *msg, struct sp_session *session) +{ + struct http_response *hres = &msg->payload.hres; + struct sp_token *token = &session->http_accesstoken; + Spotify__Login5__V3__LoginResponse *response = NULL; + int ret; + int i; + + if (hres->code != HTTP_OK) + RETURN_ERROR(SP_ERR_INVALID, "Request to login5 returned an error"); + + response = spotify__login5__v3__login_response__unpack(NULL, hres->body_len, hres->body); + if (!response) + RETURN_ERROR(SP_ERR_INVALID, "Could not parse login5 response"); + + for (i = 0; i < response->n_warnings; i++) + sp_cb.logmsg("Got login5 warning '%s'", err2txt(response->warnings[i], sp_login5_warning_map, ARRAY_SIZE(sp_login5_warning_map))); + + switch (response->response_case) + { + case SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__RESPONSE_OK: + ret = snprintf(token->value, sizeof(token->value), "%s", response->ok->access_token); + if (ret < 0 || ret >= sizeof(token->value)) + RETURN_ERROR(SP_ERR_INVALID, "Unexpected access_token length"); + + token->expires_after_seconds = response->ok->access_token_expires_in; + token->received_ts = time(NULL); + break; + case SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__RESPONSE_CHALLENGES: + sp_cb.logmsg("Login %zu challenges\n", response->challenges->n_challenges); + ret = handle_login5_challenges(response->challenges, response->login_context.data, response->login_context.len, session); + if (ret != SP_OK_DONE) + goto error; + break; + case SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__RESPONSE_ERROR: + RETURN_ERROR(SP_ERR_LOGINFAILED, err2txt(response->error, sp_login5_error_map, ARRAY_SIZE(sp_login5_error_map))); + default: + RETURN_ERROR(SP_ERR_LOGINFAILED, "Login5 failed with unknown error type"); + } + + spotify__login5__v3__login_response__free_unpacked(response, NULL); + return SP_OK_DONE; + + error: + spotify__login5__v3__login_response__free_unpacked(response, NULL); + return ret; +} + +static enum sp_error +handle_metadata_get(struct sp_message *msg, struct sp_session *session) +{ + struct http_response *hres = &msg->payload.hres; + struct sp_channel *channel = session->now_streaming_channel; + Track *response = NULL; + int ret; + + if (hres->code != HTTP_OK) + RETURN_ERROR(SP_ERR_INVALID, "Request for metadata returned an error"); + + // FIXME Use Episode object for file.media_type == SP_MEDIA_EPISODE + response = track__unpack(NULL, hres->body_len, hres->body); + if (!response) + RETURN_ERROR(SP_ERR_INVALID, "Could not parse metadata response"); + + ret = file_select(channel->file.id, sizeof(channel->file.id), response, session->bitrate_preferred); + if (ret < 0) + RETURN_ERROR(SP_ERR_INVALID, "Could not find track data"); + + track__free_unpacked(response, NULL); + return SP_OK_DONE; + + error: + track__free_unpacked(response, NULL); + return ret; +} + +static enum sp_error +handle_storage_resolve(struct sp_message *msg, struct sp_session *session) +{ + struct http_response *hres = &msg->payload.hres; + Spotify__Download__Proto__StorageResolveResponse *response = NULL; + struct sp_channel *channel = session->now_streaming_channel; + int i; + int ret; + + if (hres->code != HTTP_OK) + RETURN_ERROR(SP_ERR_INVALID, "Request to storage-resolve returned an error"); + + response = spotify__download__proto__storage_resolve_response__unpack(NULL, hres->body_len, hres->body); + if (!response) + RETURN_ERROR(SP_ERR_INVALID, "Could not parse storage-resolve response"); + + switch (response->result) + { + case SPOTIFY__DOWNLOAD__PROTO__STORAGE_RESOLVE_RESPONSE__RESULT__CDN: + for (i = 0; i < response->n_cdnurl && i < ARRAY_SIZE(channel->file.cdnurl); i++) + channel->file.cdnurl[i] = strdup(response->cdnurl[i]); + break; + case SPOTIFY__DOWNLOAD__PROTO__STORAGE_RESOLVE_RESPONSE__RESULT__STORAGE: + RETURN_ERROR(SP_ERR_INVALID, "Track not available via CDN storage"); + case SPOTIFY__DOWNLOAD__PROTO__STORAGE_RESOLVE_RESPONSE__RESULT__RESTRICTED: + RETURN_ERROR(SP_ERR_INVALID, "Can't resolve storage, track access restricted"); + default: + RETURN_ERROR(SP_ERR_INVALID, "Can't resolve storage, unknown error"); + } + + spotify__download__proto__storage_resolve_response__free_unpacked(response, NULL); + return SP_OK_DONE; + + error: + spotify__download__proto__storage_resolve_response__free_unpacked(response, NULL); + return ret; +} + +static int +file_size_get(struct sp_channel *channel, struct http_response *hres) +{ + char *content_range; + const char *colon; + int sz; + + content_range = http_response_header_find("Content-Range", hres); + if (!content_range || !(colon = strchr(content_range, '/'))) + return -1; + + sz = atoi(colon + 1); + if (sz <= 0) + return -1; + + channel->file.len_bytes = sz; + return 0; +} + +// Ref. chunked_reader.go +static enum sp_error +handle_media_get(struct sp_message *msg, struct sp_session *session) +{ + struct http_response *hres = &msg->payload.hres; + struct sp_channel *channel = session->now_streaming_channel; + int ret; + + if (hres->code != HTTP_PARTIALCONTENT) + RETURN_ERROR(SP_ERR_NOCONNECTION, "Request for Spotify media returned an error"); + + if (channel->file.len_bytes == 0 && file_size_get(channel, hres) < 0) + RETURN_ERROR(SP_ERR_INVALID, "Invalid content-range, can't determine media size"); + + sp_cb.logmsg("Received %zu bytes, size is %d\n", hres->body_len, channel->file.len_bytes); + + // Not sure if the channel concept even makes sense for http, but nonetheless + // we use it to stay consistent with the old tcp protocol + ret = channel_http_body_read(channel, hres->body, hres->body_len); + if (ret < 0) + goto error; + + // Save any audio data to a buffer that will be written to audio_fd[1] when + // it is writable. Note that request for next chunk will also happen then. + evbuffer_add(channel->audio_buf, channel->body.data, channel->body.data_len); + + return SP_OK_DATA; + + error: + return ret; +} + +static enum sp_error +handle_tcp_generic(struct sp_message *msg, struct sp_session *session) +{ + uint8_t *data = msg->payload.tmsg.data; + size_t data_len = msg->payload.tmsg.len; + enum sp_cmd_type cmd = data[0]; + uint8_t *payload = data + 3; + size_t payload_len = data_len - 3 - 4; + int ret; switch (cmd) { case CmdAPWelcome: - ret = response_apwelcome(payload, payload_len, session); + ret = handle_apwelcome(payload, payload_len, session); break; case CmdAuthFailure: - ret = response_aplogin_failed(payload, payload_len, session); + ret = handle_aplogin_failed(payload, payload_len, session); break; case CmdPing: - ret = response_ping(payload, payload_len, session); + ret = handle_ping(payload, payload_len, session); break; case CmdStreamChunkRes: - ret = response_chunk_res(payload, payload_len, session); + ret = handle_chunk_res(payload, payload_len, session); break; case CmdCountryCode: memcpy(session->country, payload, sizeof(session->country) - 1); ret = SP_OK_OTHER; break; case CmdAesKey: - ret = response_aes_key(payload, payload_len, session); + ret = handle_aes_key(payload, payload_len, session); break; case CmdAesKeyError: - ret = response_aes_key_error(payload, payload_len, session); + ret = handle_aes_key_error(payload, payload_len, session); break; case CmdMercuryReq: - ret = response_mercury_req(payload, payload_len, session); + ret = handle_mercury_req(payload, payload_len, session); break; case CmdChannelError: - ret = response_channel_error(payload, payload_len, session); + ret = handle_channel_error(payload, payload_len, session); break; case CmdLegacyWelcome: // 0 bytes, ignored by librespot case CmdSecretBlock: // ignored by librespot @@ -829,8 +1208,59 @@ response_generic(uint8_t *msg, size_t msg_len, struct sp_session *session) } static enum sp_error -msg_read_one(uint8_t **out, size_t *out_len, uint8_t *in, size_t in_len, struct sp_connection *conn) +msg_tcp_handle(struct sp_message *msg, struct sp_session *session) { + struct sp_seq_request *request = session->request; + + // We have a tcp request waiting for a response + if (request && request->proto == SP_PROTO_TCP && request->response_handler) + { +// sp_cb.logmsg("Handling response to %s\n", request->name); + return request->response_handler(msg, session); + } + +// sp_cb.logmsg("Handling incoming tcp message\n"); + // Not waiting for anything, could be a ping + return handle_tcp_generic(msg, session); +} + +static enum sp_error +msg_http_handle(struct sp_message *msg, struct sp_session *session) +{ + struct sp_seq_request *request = session->request; + + // We have a http request waiting for a response + if (request && request->proto == SP_PROTO_HTTP && request->response_handler) + { +// sp_cb.logmsg("Handling response to %s\n", request->name); + return request->response_handler(msg, session); + } + + sp_errmsg = "Received unexpected http response"; + return SP_ERR_INVALID; +} + +// Handler must return SP_OK_DONE if the message is a response to a request. +// It must return SP_OK_OTHER if the message is something else (e.g. a ping), +// SP_ERR_xxx if the response indicates an error. Finally, SP_OK_DATA is like +// DONE except it also means that there is new audio data to write. +enum sp_error +msg_handle(struct sp_message *msg, struct sp_session *session) +{ + if (msg->type == SP_MSG_TYPE_TCP) + return msg_tcp_handle(msg, session); + else if (msg->type == SP_MSG_TYPE_HTTP_RES) + return msg_http_handle(msg, session); + + sp_errmsg = "Invalid message passed to msg_handle()"; + return SP_ERR_INVALID; +} + +enum sp_error +msg_tcp_read_one(struct sp_tcp_message *tmsg, struct sp_connection *conn) +{ + size_t in_len = evbuffer_get_length(conn->incoming); + uint8_t *in = evbuffer_pullup(conn->incoming, -1); uint32_t be32; ssize_t msg_len; int ret; @@ -844,9 +1274,9 @@ msg_read_one(uint8_t **out, size_t *out_len, uint8_t *in, size_t in_len, struct if (msg_len > in_len) return SP_OK_WAIT; - *out = malloc(msg_len); - *out_len = msg_len; - evbuffer_remove(conn->incoming, *out, msg_len); + tmsg->data = malloc(msg_len); + tmsg->len = msg_len; + evbuffer_remove(conn->incoming, tmsg->data, msg_len); return SP_OK_DONE; } @@ -877,9 +1307,9 @@ msg_read_one(uint8_t **out, size_t *out_len, uint8_t *in, size_t in_len, struct } // At this point we have a complete, decrypted message. - *out = malloc(msg_len); - *out_len = msg_len; - evbuffer_remove(conn->incoming, *out, msg_len); + tmsg->data = malloc(msg_len); + tmsg->len = msg_len; + evbuffer_remove(conn->incoming, tmsg->data, msg_len); return SP_OK_DONE; @@ -887,51 +1317,26 @@ msg_read_one(uint8_t **out, size_t *out_len, uint8_t *in, size_t in_len, struct return ret; } -enum sp_error -response_read(struct sp_session *session) -{ - struct sp_connection *conn = &session->conn; - uint8_t *in; - size_t in_len; - uint8_t *msg; - size_t msg_len; - int ret; - - in_len = evbuffer_get_length(conn->incoming); - in = evbuffer_pullup(conn->incoming, -1); - - ret = msg_read_one(&msg, &msg_len, in, in_len, conn); - if (ret != SP_OK_DONE) - goto error; - - if (msg_len < 128) - sp_cb.hexdump("Received message\n", msg, msg_len); - else - sp_cb.hexdump("Received message (truncated)\n", msg, 128); - - if (!session->response_handler) - RETURN_ERROR(SP_ERR_INVALID, "Unexpected response from Spotify, aborting"); - - // Handler must return SP_OK_DONE if the message is a response to a request. - // It must return SP_OK_OTHER if the message is something else (e.g. a ping), - // SP_ERR_xxx if the response indicates an error. Finally, SP_OK_DATA is like - // DONE except it also means that there is new audio data to write. - ret = session->response_handler(msg, msg_len, session); - free(msg); - - return ret; - - error: - return ret; -} - /* --------------------------- Outgoing messages ---------------------------- */ -// This message is constructed like librespot does it, see handshake.rs -static ssize_t -msg_make_client_hello(uint8_t *out, size_t out_len, struct sp_session *session) +static int +msg_make_ap_resolve(struct sp_message *msg, struct sp_session *session) { + struct http_request *hreq = &msg->payload.hreq; + + if (!must_resolve(&session->accesspoint) && !must_resolve(&session->spclient) && !must_resolve(&session->dealer)) + return 1; // Skip + + hreq->url = strdup("https://apresolve.spotify.com/?type=accesspoint&type=spclient&type=dealer"); + return 0; +} + +// This message is constructed like librespot does it, see handshake.rs +static int +msg_make_client_hello(struct sp_message *msg, struct sp_session *session) +{ + struct sp_tcp_message *tmsg = &msg->payload.tmsg; ClientHello client_hello = CLIENT_HELLO__INIT; BuildInfo build_info = BUILD_INFO__INIT; LoginCryptoHelloUnion login_crypto = LOGIN_CRYPTO_HELLO_UNION__INIT; @@ -939,7 +1344,6 @@ msg_make_client_hello(uint8_t *out, size_t out_len, struct sp_session *session) Cryptosuite crypto_suite = CRYPTOSUITE__CRYPTO_SUITE_SHANNON; uint8_t padding[1] = { 0x1e }; uint8_t nonce[16] = { 0 }; - size_t len; build_info.product = PRODUCT__PRODUCT_PARTNER; build_info.platform = PLATFORM__PLATFORM_LINUX_X86; @@ -961,13 +1365,14 @@ msg_make_client_hello(uint8_t *out, size_t out_len, struct sp_session *session) client_hello.padding.len = sizeof(padding); client_hello.padding.data = padding; - len = client_hello__get_packed_size(&client_hello); - if (len > out_len) - return -1; + tmsg->len = client_hello__get_packed_size(&client_hello); + tmsg->data = malloc(tmsg->len); - client_hello__pack(&client_hello, out); + client_hello__pack(&client_hello, tmsg->data); - return len; + tmsg->add_version_header = true; + + return 0; } static int @@ -992,15 +1397,15 @@ client_response_crypto(uint8_t **challenge, size_t *challenge_len, struct sp_con return ret; } -static ssize_t -msg_make_client_response_plaintext(uint8_t *out, size_t out_len, struct sp_session *session) +static int +msg_make_client_response_plaintext(struct sp_message *msg, struct sp_session *session) { + struct sp_tcp_message *tmsg = &msg->payload.tmsg; ClientResponsePlaintext client_response = CLIENT_RESPONSE_PLAINTEXT__INIT; LoginCryptoResponseUnion login_crypto_response = LOGIN_CRYPTO_RESPONSE_UNION__INIT; LoginCryptoDiffieHellmanResponse diffie_hellman = LOGIN_CRYPTO_DIFFIE_HELLMAN_RESPONSE__INIT; uint8_t *challenge; size_t challenge_len; - ssize_t len; int ret; ret = client_response_crypto(&challenge, &challenge_len, &session->conn); @@ -1014,28 +1419,24 @@ msg_make_client_response_plaintext(uint8_t *out, size_t out_len, struct sp_sessi client_response.login_crypto_response = &login_crypto_response; - len = client_response_plaintext__get_packed_size(&client_response); - if (len > out_len) - { - free(challenge); - return -1; - } + tmsg->len = client_response_plaintext__get_packed_size(&client_response); + tmsg->data = malloc(tmsg->len); - client_response_plaintext__pack(&client_response, out); + client_response_plaintext__pack(&client_response, tmsg->data); free(challenge); - return len; + return 0; } -static ssize_t -msg_make_client_response_encrypted(uint8_t *out, size_t out_len, struct sp_session *session) +static int +msg_make_client_response_encrypted(struct sp_message *msg, struct sp_session *session) { + struct sp_tcp_message *tmsg = &msg->payload.tmsg; ClientResponseEncrypted client_response = CLIENT_RESPONSE_ENCRYPTED__INIT; LoginCredentials login_credentials = LOGIN_CREDENTIALS__INIT; SystemInfo system_info = SYSTEM_INFO__INIT; char system_information_string[64]; char version_string[64]; - ssize_t len; login_credentials.has_auth_data = 1; login_credentials.username = session->credentials.username; @@ -1076,21 +1477,23 @@ msg_make_client_response_encrypted(uint8_t *out, size_t out_len, struct sp_sessi client_response.system_info = &system_info; client_response.version_string = version_string; - len = client_response_encrypted__get_packed_size(&client_response); - if (len > out_len) - return -1; + tmsg->len = client_response_encrypted__get_packed_size(&client_response); + tmsg->data = malloc(tmsg->len); - client_response_encrypted__pack(&client_response, out); + client_response_encrypted__pack(&client_response, tmsg->data); - return len; + tmsg->cmd = CmdLogin; + tmsg->encrypt = true; + + return 0; } // From librespot-golang: // Mercury is the protocol implementation for Spotify Connect playback control and metadata fetching. It works as a // PUB/SUB system, where you, as an audio sink, subscribes to the events of a specified user (playlist changes) but // also access various metadata normally fetched by external players (tracks metadata, playlists, artists, etc). -static ssize_t -msg_make_mercury_req(uint8_t *out, size_t out_len, struct sp_mercury *mercury) +static int +msg_make_mercury_req(size_t *total_len, uint8_t *out, size_t out_len, struct sp_mercury *mercury) { Header header = HEADER__INIT; uint8_t *ptr; @@ -1158,12 +1561,14 @@ msg_make_mercury_req(uint8_t *out, size_t out_len, struct sp_mercury *mercury) assert(ptr - out == header_len + prefix_len + body_len); - return header_len + prefix_len + body_len; + *total_len = header_len + prefix_len + body_len; + return 0; } -static ssize_t -msg_make_mercury_track_get(uint8_t *out, size_t out_len, struct sp_session *session) +static int +msg_make_mercury_track_get(struct sp_message *msg, struct sp_session *session) { + struct sp_tcp_message *tmsg = &msg->payload.tmsg; struct sp_mercury mercury = { 0 }; struct sp_channel *channel = session->now_streaming_channel; char uri[256]; @@ -1182,12 +1587,17 @@ msg_make_mercury_track_get(uint8_t *out, size_t out_len, struct sp_session *sess mercury.seq = channel->id; mercury.uri = uri; - return msg_make_mercury_req(out, out_len, &mercury); + tmsg->data = malloc(MERCURY_REQ_SIZE_MAX); + tmsg->cmd = CmdMercuryReq; + tmsg->encrypt = true; + + return msg_make_mercury_req(&tmsg->len, tmsg->data, MERCURY_REQ_SIZE_MAX, &mercury); } -static ssize_t -msg_make_mercury_episode_get(uint8_t *out, size_t out_len, struct sp_session *session) +static int +msg_make_mercury_episode_get(struct sp_message *msg, struct sp_session *session) { + struct sp_tcp_message *tmsg = &msg->payload.tmsg; struct sp_mercury mercury = { 0 }; struct sp_channel *channel = session->now_streaming_channel; char uri[256]; @@ -1206,24 +1616,39 @@ msg_make_mercury_episode_get(uint8_t *out, size_t out_len, struct sp_session *se mercury.seq = channel->id; mercury.uri = uri; - return msg_make_mercury_req(out, out_len, &mercury); + tmsg->data = malloc(MERCURY_REQ_SIZE_MAX); + tmsg->cmd = CmdMercuryReq; + tmsg->encrypt = true; + + return msg_make_mercury_req(&tmsg->len, tmsg->data, MERCURY_REQ_SIZE_MAX, &mercury); } -static ssize_t -msg_make_audio_key_get(uint8_t *out, size_t out_len, struct sp_session *session) +static int +msg_make_mercury_metadata_get(struct sp_message *msg, struct sp_session *session) { struct sp_channel *channel = session->now_streaming_channel; - size_t required_len; + + if (channel->file.media_type == SP_MEDIA_TRACK) + return msg_make_mercury_track_get(msg, session); + else if (channel->file.media_type == SP_MEDIA_EPISODE) + return msg_make_mercury_episode_get(msg, session); + + return -1; +} + +static int +msg_make_audio_key_get(struct sp_message *msg, struct sp_session *session) +{ + struct sp_tcp_message *tmsg = &msg->payload.tmsg; + struct sp_channel *channel = session->now_streaming_channel; + uint8_t *ptr; uint32_t be32; uint16_t be; - uint8_t *ptr; - required_len = sizeof(channel->file.id) + sizeof(channel->file.media_id) + sizeof(be32) + sizeof(be); + tmsg->len = sizeof(channel->file.id) + sizeof(channel->file.media_id) + sizeof(be32) + sizeof(be); + tmsg->data = malloc(tmsg->len); - if (required_len > out_len) - return -1; - - ptr = out; + ptr = tmsg->data; memcpy(ptr, channel->file.id, sizeof(channel->file.id)); ptr += sizeof(channel->file.id); @@ -1239,26 +1664,28 @@ msg_make_audio_key_get(uint8_t *out, size_t out_len, struct sp_session *session) memcpy(ptr, &be, sizeof(be)); ptr += sizeof(be); - return required_len; + tmsg->cmd = CmdRequestKey; + tmsg->encrypt = true; + + return 0; } -static ssize_t -msg_make_chunk_request(uint8_t *out, size_t out_len, struct sp_session *session) +static int +msg_make_chunk_request(struct sp_message *msg, struct sp_session *session) { + struct sp_tcp_message *tmsg = &msg->payload.tmsg; struct sp_channel *channel = session->now_streaming_channel; uint8_t *ptr; uint16_t be; uint32_t be32; - size_t required_len; if (!channel) return -1; - ptr = out; + tmsg->len = 3 * sizeof(be) + sizeof(channel->file.id) + 5 * sizeof(be32); + tmsg->data = malloc(tmsg->len); - required_len = 3 * sizeof(be) + sizeof(channel->file.id) + 5 * sizeof(be32); - if (required_len > out_len) - return -1; + ptr = tmsg->data; be = htobe16(channel->id); memcpy(ptr, &be, sizeof(be)); @@ -1287,104 +1714,490 @@ msg_make_chunk_request(uint8_t *out, size_t out_len, struct sp_session *session) memcpy(ptr, channel->file.id, sizeof(channel->file.id)); ptr += sizeof(channel->file.id); - be32 = htobe32(channel->file.offset_words); + be32 = htobe32(channel->file.offset_bytes / 4); memcpy(ptr, &be32, sizeof(be32)); ptr += sizeof(be32); // x4 - be32 = htobe32(channel->file.offset_words + SP_CHUNK_LEN_WORDS); + be32 = htobe32(channel->file.offset_bytes / 4 + SP_CHUNK_LEN / 4); memcpy(ptr, &be32, sizeof(be32)); ptr += sizeof(be32); // x5 - assert(required_len == ptr - out); - assert(required_len == 46); + assert(tmsg->len == ptr - tmsg->data); + assert(tmsg->len == 46); - return required_len; + tmsg->cmd = CmdStreamChunk; + tmsg->encrypt = true; + + return 0; } -bool -msg_is_handshake(enum sp_msg_type type) +static int +msg_make_pong(struct sp_message *msg, struct sp_session *session) { - return ( type == MSG_TYPE_CLIENT_HELLO || - type == MSG_TYPE_CLIENT_RESPONSE_PLAINTEXT || - type == MSG_TYPE_CLIENT_RESPONSE_ENCRYPTED ); + struct sp_tcp_message *tmsg = &msg->payload.tmsg; + + tmsg->len = 4; + tmsg->data = calloc(1, tmsg->len); // librespot just replies with zeroes + + tmsg->cmd = CmdPong; + tmsg->encrypt = true; + + return 0; } -int -msg_make(struct sp_message *msg, enum sp_msg_type type, struct sp_session *session) +// Ref. session/clienttoken.go +static int +msg_make_clienttoken(struct sp_message *msg, struct sp_session *session) { - memset(msg, 0, sizeof(struct sp_message)); - msg->type = type; + struct http_request *hreq = &msg->payload.hreq; + Spotify__Clienttoken__Http__V0__ClientTokenRequest treq = SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST__INIT; + Spotify__Clienttoken__Http__V0__ClientDataRequest dreq = SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_DATA_REQUEST__INIT; + Spotify__Clienttoken__Data__V0__ConnectivitySdkData sdk_data = SPOTIFY__CLIENTTOKEN__DATA__V0__CONNECTIVITY_SDK_DATA__INIT; + Spotify__Clienttoken__Data__V0__PlatformSpecificData platform_data = SPOTIFY__CLIENTTOKEN__DATA__V0__PLATFORM_SPECIFIC_DATA__INIT; + struct sp_token *token = &session->http_clienttoken; + time_t now = time(NULL); + bool must_refresh; - switch (type) + must_refresh = (now > token->received_ts + token->expires_after_seconds) || (now > token->received_ts + token->refresh_after_seconds); + if (!must_refresh) + return 1; // We have a valid token, tell caller to go to next request + +#ifdef HAVE_SYS_UTSNAME_H + Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData desktop_macos = SPOTIFY__CLIENTTOKEN__DATA__V0__NATIVE_DESKTOP_MAC_OSDATA__INIT; + Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData desktop_linux = SPOTIFY__CLIENTTOKEN__DATA__V0__NATIVE_DESKTOP_LINUX_DATA__INIT; + struct utsname uts = { 0 }; + + uname(&uts); + if (strcmp(uts.sysname, "Linux") == 0) { - case MSG_TYPE_CLIENT_HELLO: - msg->len = msg_make_client_hello(msg->data, sizeof(msg->data), session); - msg->type_next = MSG_TYPE_CLIENT_RESPONSE_PLAINTEXT; - msg->add_version_header = true; - msg->response_handler = response_client_hello; - break; - case MSG_TYPE_CLIENT_RESPONSE_PLAINTEXT: - msg->len = msg_make_client_response_plaintext(msg->data, sizeof(msg->data), session); - msg->type_next = MSG_TYPE_CLIENT_RESPONSE_ENCRYPTED; - msg->response_handler = NULL; // No response expected - break; - case MSG_TYPE_CLIENT_RESPONSE_ENCRYPTED: - msg->len = msg_make_client_response_encrypted(msg->data, sizeof(msg->data), session); - msg->cmd = CmdLogin; - msg->encrypt = true; - msg->response_handler = response_generic; - break; - case MSG_TYPE_MERCURY_TRACK_GET: - msg->len = msg_make_mercury_track_get(msg->data, sizeof(msg->data), session); - msg->cmd = CmdMercuryReq; - msg->encrypt = true; - msg->type_next = MSG_TYPE_AUDIO_KEY_GET; - msg->response_handler = response_generic; - break; - case MSG_TYPE_MERCURY_EPISODE_GET: - msg->len = msg_make_mercury_episode_get(msg->data, sizeof(msg->data), session); - msg->cmd = CmdMercuryReq; - msg->encrypt = true; - msg->type_next = MSG_TYPE_AUDIO_KEY_GET; - msg->response_handler = response_generic; - break; - case MSG_TYPE_AUDIO_KEY_GET: - msg->len = msg_make_audio_key_get(msg->data, sizeof(msg->data), session); - msg->cmd = CmdRequestKey; - msg->encrypt = true; - msg->type_next = MSG_TYPE_CHUNK_REQUEST; - msg->response_handler = response_generic; - break; - case MSG_TYPE_CHUNK_REQUEST: - msg->len = msg_make_chunk_request(msg->data, sizeof(msg->data), session); - msg->cmd = CmdStreamChunk; - msg->encrypt = true; - msg->response_handler = response_generic; - break; - case MSG_TYPE_PONG: - msg->len = 4; - msg->cmd = CmdPong; - msg->encrypt = true; - memset(msg->data, 0, msg->len); // librespot just replies with zeroes - break; - default: - msg->len = -1; + desktop_linux.system_name = uts.sysname; + desktop_linux.system_release = uts.release; + desktop_linux.system_version = uts.version; + desktop_linux.hardware = uts.machine; + platform_data.desktop_linux = &desktop_linux; + platform_data.data_case = SPOTIFY__CLIENTTOKEN__DATA__V0__PLATFORM_SPECIFIC_DATA__DATA_DESKTOP_LINUX; + } + else if (strcmp(uts.sysname, "Darwin") == 0) + { + desktop_macos.system_version = uts.version; + desktop_macos.hw_model = uts.machine; + desktop_macos.compiled_cpu_type = uts.machine; + platform_data.desktop_macos = &desktop_macos; + platform_data.data_case = SPOTIFY__CLIENTTOKEN__DATA__V0__PLATFORM_SPECIFIC_DATA__DATA_DESKTOP_MACOS; + } +#endif + + sdk_data.platform_specific_data = &platform_data; + sdk_data.device_id = sp_sysinfo.device_id; // e.g. "bcbae1f3062baac486045f13935c6c95ad4191ff" + + dreq.connectivity_sdk_data = &sdk_data; + dreq.data_case = SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_DATA_REQUEST__DATA_CONNECTIVITY_SDK_DATA; + dreq.client_version = sp_sysinfo.client_version; // e.g. "0.0.0" (SpotifyLikeClient) + dreq.client_id = sp_sysinfo.client_id; + + treq.client_data = &dreq; + treq.request_type = SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST_TYPE__REQUEST_CLIENT_DATA_REQUEST; + treq.request_case = SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST__REQUEST_CLIENT_DATA; + + hreq->body_len = spotify__clienttoken__http__v0__client_token_request__get_packed_size(&treq); + hreq->body = malloc(hreq->body_len); + + spotify__clienttoken__http__v0__client_token_request__pack(&treq, hreq->body); + + hreq->url = strdup("https://clienttoken.spotify.com/v1/clienttoken"); + + hreq->headers[0] = strdup("Accept: application/x-protobuf"); + hreq->headers[1] = strdup("Content-Type: application/x-protobuf"); + + return 0; +} + +static void +challenge_solutions_clear(Spotify__Login5__V3__ChallengeSolutions *solutions) +{ + Spotify__Login5__V3__ChallengeSolution *this_solution; + int i; + + if (!solutions->solutions) + return; + + for (i = 0; i < solutions->n_solutions; i++) + { + this_solution = solutions->solutions[i]; + if (!this_solution) + continue; + + free(this_solution->hashcash->duration); + free(this_solution->hashcash->suffix.data); + free(this_solution->hashcash); + free(this_solution); } - return (msg->len < 0) ? -1 : 0; + free(solutions->solutions); +} + +// Finds solutions to the challenges stored in *challenges and adds them to *solutions +static int +challenge_solutions_append(Spotify__Login5__V3__ChallengeSolutions *solutions, struct crypto_hashcash_challenge *challenges, int n_challenges) +{ + Spotify__Login5__V3__ChallengeSolution *this_solution; + struct crypto_hashcash_challenge *crypto_challenge; + struct crypto_hashcash_solution crypto_solution; + size_t suffix_len = sizeof(crypto_solution.suffix); + int ret; + int i; + + solutions->n_solutions = n_challenges; + solutions->solutions = calloc(n_challenges, sizeof(Spotify__Login5__V3__ChallengeSolution *)); + if (!solutions->solutions) + RETURN_ERROR(SP_ERR_OOM, "Out of memory allocating hashcash solutions"); + + for (i = 0, crypto_challenge = challenges; i < n_challenges; i++, crypto_challenge++) + { + ret = crypto_hashcash_solve(&crypto_solution, crypto_challenge, &sp_errmsg); + if (ret < 0) + RETURN_ERROR(SP_ERR_INVALID, sp_errmsg); + + this_solution = malloc(sizeof(Spotify__Login5__V3__ChallengeSolution)); + spotify__login5__v3__challenge_solution__init(this_solution); + this_solution->solution_case = SPOTIFY__LOGIN5__V3__CHALLENGE_SOLUTION__SOLUTION_HASHCASH; + + this_solution->hashcash = malloc(sizeof(Spotify__Login5__V3__Challenges__HashcashSolution)); + spotify__login5__v3__challenges__hashcash_solution__init(this_solution->hashcash); + + this_solution->hashcash->duration = malloc(sizeof(Google__Protobuf__Duration)); + google__protobuf__duration__init(this_solution->hashcash->duration); + + this_solution->hashcash->suffix.len = suffix_len; + this_solution->hashcash->suffix.data = malloc(suffix_len); + memcpy(this_solution->hashcash->suffix.data, crypto_solution.suffix, suffix_len); + + this_solution->hashcash->duration->seconds = crypto_solution.duration.tv_sec; + this_solution->hashcash->duration->nanos = crypto_solution.duration.tv_nsec; + + solutions->solutions[i] = this_solution; + } + + return 0; + + error: + challenge_solutions_clear(solutions); + return ret; +} + +// Ref. login5/login5.go +static int +msg_make_login5(struct sp_message *msg, struct sp_session *session) +{ + struct http_request *hreq = &msg->payload.hreq; + Spotify__Login5__V3__LoginRequest req = SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__INIT; + Spotify__Login5__V3__ChallengeSolutions solutions = SPOTIFY__LOGIN5__V3__CHALLENGE_SOLUTIONS__INIT; + Spotify__Login5__V3__ClientInfo client_info = SPOTIFY__LOGIN5__V3__CLIENT_INFO__INIT; + Spotify__Login5__V3__Credentials__StoredCredential stored_credential = SPOTIFY__LOGIN5__V3__CREDENTIALS__STORED_CREDENTIAL__INIT; + struct sp_token *token = &session->http_accesstoken; + uint8_t *login_context = NULL; + size_t login_context_len; + time_t now = time(NULL); + bool must_refresh; + int ret; + + must_refresh = (now > token->received_ts + token->expires_after_seconds); + if (!must_refresh) + return 1; // We have a valid token, tell caller to go to next request + + if (session->credentials.stored_cred_len == 0) + return -1; + + // This is our second login5 request - Spotify returned challenges after the first. + // The login_context is echoed from Spotify's response to the first login5. + if (session->hashcash_challenges) + { + login_context_len = session->hashcash_challenges->ctx_len; + login_context = malloc(login_context_len); + memcpy(login_context, session->hashcash_challenges->ctx, login_context_len); + + ret = challenge_solutions_append(&solutions, session->hashcash_challenges, session->n_hashcash_challenges); + hashcash_challenges_free(&session->hashcash_challenges, &session->n_hashcash_challenges); + if (ret < 0) + goto error; + + req.challenge_solutions = &solutions; + req.login_context.data = login_context; + req.login_context.len = login_context_len; + } + + client_info.client_id = sp_sysinfo.client_id; + client_info.device_id = sp_sysinfo.device_id; + + req.client_info = &client_info; + + stored_credential.username = session->credentials.username; + stored_credential.data.data = session->credentials.stored_cred; + stored_credential.data.len = session->credentials.stored_cred_len; + + req.login_method_case = SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__LOGIN_METHOD_STORED_CREDENTIAL; + req.stored_credential = &stored_credential; + + hreq->body_len = spotify__login5__v3__login_request__get_packed_size(&req); + hreq->body = malloc(hreq->body_len); + + spotify__login5__v3__login_request__pack(&req, hreq->body); + + hreq->url = strdup("https://login5.spotify.com/v3/login"); + + hreq->headers[0] = asprintf_or_die("Accept: application/x-protobuf"); + hreq->headers[1] = asprintf_or_die("Content-Type: application/x-protobuf"); + hreq->headers[2] = asprintf_or_die("Client-Token: %s", session->http_clienttoken.value); + + challenge_solutions_clear(&solutions); + free(login_context); + return 0; + + error: + challenge_solutions_clear(&solutions); + free(login_context); + return -1; +} + +static int +msg_make_login5_challenges(struct sp_message *msg, struct sp_session *session) +{ + // Spotify didn't give us any challenges during login5, so we can just proceed + if (!session->hashcash_challenges) + return 1; // Continue to next message + + // Otherwise make another login5 request that includes the challenge responses + return msg_make_login5(msg, session); +} + +// Ref. spclient/spclient.go +static int +msg_make_metadata_get(struct sp_message *msg, struct sp_session *session) +{ + struct http_request *hreq = &msg->payload.hreq; + struct sp_server *server = &session->spclient; + struct sp_channel *channel = session->now_streaming_channel; + const char *path; + char *media_id = NULL; + char *ptr; + int i; + + if (channel->file.media_type == SP_MEDIA_TRACK) + path = "metadata/4/track"; + else if (channel->file.media_type == SP_MEDIA_EPISODE) + path = "metadata/4/episode"; + else + return -1; + + media_id = malloc(2 * sizeof(channel->file.media_id) + 1); + for (i = 0, ptr = media_id; i < sizeof(channel->file.media_id); i++) + ptr += sprintf(ptr, "%02x", channel->file.media_id[i]); + + hreq->url = asprintf_or_die("https://%s:%d/%s/%s", server->address, server->port, path, media_id); + + hreq->headers[0] = asprintf_or_die("Accept: application/x-protobuf"); + hreq->headers[1] = asprintf_or_die("Client-Token: %s", session->http_clienttoken.value); + hreq->headers[2] = asprintf_or_die("Authorization: Bearer %s", session->http_accesstoken.value); + + free(media_id); + return 0; +} + +// Resolve storage, this will just be a GET request +// Ref. spclient/spclient.go +static int +msg_make_storage_resolve(struct sp_message *msg, struct sp_session *session) +{ + struct http_request *hreq = &msg->payload.hreq; + struct sp_server *server = &session->spclient; + struct sp_channel *channel = session->now_streaming_channel; + char *track_id = NULL; + char *ptr; + int i; + + track_id = malloc(2 * sizeof(channel->file.id) + 1); + for (i = 0, ptr = track_id; i < sizeof(channel->file.id); i++) + ptr += sprintf(ptr, "%02x", channel->file.id[i]); + + hreq->url = asprintf_or_die("https://%s:%d/storage-resolve/files/audio/interactive/%s", server->address, server->port, track_id); + + hreq->headers[0] = asprintf_or_die("Accept: application/x-protobuf"); + hreq->headers[1] = asprintf_or_die("Client-Token: %s", session->http_clienttoken.value); + hreq->headers[2] = asprintf_or_die("Authorization: Bearer %s", session->http_accesstoken.value); + + free(track_id); + return 0; +} + +static int +msg_make_media_get(struct sp_message *msg, struct sp_session *session) +{ + struct http_request *hreq = &msg->payload.hreq; + struct sp_channel *channel = session->now_streaming_channel; + size_t bytes_from; + size_t bytes_to; + + bytes_from = channel->file.offset_bytes; + + if (!channel->file.len_bytes || channel->file.len_bytes > channel->file.offset_bytes + SP_CHUNK_LEN) + bytes_to = channel->file.offset_bytes + SP_CHUNK_LEN - 1; + else + bytes_to = channel->file.len_bytes - 1; + + hreq->url = strdup(channel->file.cdnurl[0]); + + hreq->headers[0] = asprintf_or_die("Range: bytes=%zu-%zu", bytes_from, bytes_to); + +// sp_cb.logmsg("Asking for %s\n", hreq->headers[0]); + + return 0; +} + +// Must be large enough to also include null terminating elements +static struct sp_seq_request seq_requests[][7] = +{ + { + // Just a dummy so that the array is aligned with the enum + { SP_SEQ_STOP }, + }, + { + // Resolve will be skipped if already done and servers haven't failed on us + { SP_SEQ_LOGIN, "AP_RESOLVE", SP_PROTO_HTTP, msg_make_ap_resolve, NULL, handle_ap_resolve, }, + { SP_SEQ_LOGIN, "CLIENT_HELLO", SP_PROTO_TCP, msg_make_client_hello, prepare_tcp_handshake, handle_client_hello, }, + { SP_SEQ_LOGIN, "CLIENT_RESPONSE_PLAINTEXT", SP_PROTO_TCP, msg_make_client_response_plaintext, prepare_tcp_handshake, NULL, }, + { SP_SEQ_LOGIN, "CLIENT_RESPONSE_ENCRYPTED", SP_PROTO_TCP, msg_make_client_response_encrypted, prepare_tcp_handshake, handle_tcp_generic, }, + }, + { + // The first two will be skipped if valid tokens already exist + { SP_SEQ_MEDIA_OPEN, "CLIENTTOKEN", SP_PROTO_HTTP, msg_make_clienttoken, NULL, handle_clienttoken, }, + { SP_SEQ_MEDIA_OPEN, "LOGIN5", SP_PROTO_HTTP, msg_make_login5, NULL, handle_login5, }, + { SP_SEQ_MEDIA_OPEN, "LOGIN5_CHALLENGES", SP_PROTO_HTTP, msg_make_login5_challenges, NULL, handle_login5, }, + { SP_SEQ_MEDIA_OPEN, "METADATA_GET", SP_PROTO_HTTP, msg_make_metadata_get, NULL, handle_metadata_get, }, + { SP_SEQ_MEDIA_OPEN, "AUDIO_KEY_GET", SP_PROTO_TCP, msg_make_audio_key_get, prepare_tcp, handle_tcp_generic, }, + { SP_SEQ_MEDIA_OPEN, "STORAGE_RESOLVE", SP_PROTO_HTTP, msg_make_storage_resolve, NULL, handle_storage_resolve, }, + { SP_SEQ_MEDIA_OPEN, "MEDIA_PREFETCH", SP_PROTO_HTTP, msg_make_media_get, NULL, handle_media_get, }, + }, + { + { SP_SEQ_MEDIA_GET, "MEDIA_GET", SP_PROTO_HTTP, msg_make_media_get, NULL, handle_media_get, }, + }, + { + { SP_SEQ_PONG, "PONG", SP_PROTO_TCP, msg_make_pong, prepare_tcp, NULL, }, + }, +}; + +// Must be large enough to also include null terminating elements +static struct sp_seq_request seq_requests_legacy[][7] = +{ + { + // Just a dummy so that the array is aligned with the enum + { SP_SEQ_STOP }, + }, + { + { SP_SEQ_LOGIN, "AP_RESOLVE", SP_PROTO_HTTP, msg_make_ap_resolve, NULL, handle_ap_resolve, }, + { SP_SEQ_LOGIN, "CLIENT_HELLO", SP_PROTO_TCP, msg_make_client_hello, prepare_tcp_handshake, handle_client_hello, }, + { SP_SEQ_LOGIN, "CLIENT_RESPONSE_PLAINTEXT", SP_PROTO_TCP, msg_make_client_response_plaintext, prepare_tcp_handshake, NULL, }, + { SP_SEQ_LOGIN, "CLIENT_RESPONSE_ENCRYPTED", SP_PROTO_TCP, msg_make_client_response_encrypted, prepare_tcp_handshake, handle_tcp_generic, }, + }, + { + { SP_SEQ_MEDIA_OPEN, "MERCURY_METADATA_GET", SP_PROTO_TCP, msg_make_mercury_metadata_get, prepare_tcp, handle_tcp_generic, }, + { SP_SEQ_MEDIA_OPEN, "AUDIO_KEY_GET", SP_PROTO_TCP, msg_make_audio_key_get, prepare_tcp, handle_tcp_generic, }, + { SP_SEQ_MEDIA_OPEN, "CHUNK_PREFETCH", SP_PROTO_TCP, msg_make_chunk_request, prepare_tcp, handle_tcp_generic, }, + }, + { + { SP_SEQ_MEDIA_GET, "CHUNK_REQUEST", SP_PROTO_TCP, msg_make_chunk_request, prepare_tcp, handle_tcp_generic, }, + }, + { + { SP_SEQ_PONG, "PONG", SP_PROTO_TCP, msg_make_pong, prepare_tcp, NULL, }, + }, +}; + +int +seq_requests_check(void) +{ + for (int i = 0; i < ARRAY_SIZE(seq_requests); i++) + { + if (i != seq_requests[i]->seq_type) + return -1; + } + for (int i = 0; i < ARRAY_SIZE(seq_requests_legacy); i++) + { + if (i != seq_requests_legacy[i]->seq_type) + return -1; + } + + return 0; +} + +struct sp_seq_request * +seq_request_get(enum sp_seq_type seq_type, int n, bool use_legacy) +{ + if (use_legacy) + return &seq_requests_legacy[seq_type][n]; + + return &seq_requests[seq_type][n]; +} + +// This is just a wrapper to help debug if we are unintentionally overwriting +// a queued sequence +void +seq_next_set(struct sp_session *session, enum sp_seq_type seq_type) +{ + bool will_overwrite = (seq_type != SP_SEQ_STOP && session->next_seq != SP_SEQ_STOP && seq_type != session->next_seq); + + if (will_overwrite) + sp_cb.logmsg("Bug! Sequence is being overwritten (prev %d, new %d)", session->next_seq, seq_type); + + assert(!will_overwrite); + + session->next_seq = seq_type; +} + +enum sp_error +seq_request_prepare(struct sp_seq_request *request, struct sp_conn_callbacks *cb, struct sp_session *session) +{ + if (!request->request_prepare) + return SP_OK_DONE; + + return request->request_prepare(request, cb, session); +} + +void +msg_clear(struct sp_message *msg) +{ + if (!msg) + return; + + if (msg->type == SP_MSG_TYPE_HTTP_REQ) + http_request_free(&msg->payload.hreq, true); + else if (msg->type == SP_MSG_TYPE_HTTP_RES) + http_response_free(&msg->payload.hres, true); + else if (msg->type == SP_MSG_TYPE_TCP) + free(msg->payload.tmsg.data); + + memset(msg, 0, sizeof(struct sp_message)); } int -msg_send(struct sp_message *msg, struct sp_connection *conn) +msg_make(struct sp_message *msg, struct sp_seq_request *req, struct sp_session *session) +{ + memset(msg, 0, sizeof(struct sp_message)); + + msg->type = (req->proto == SP_PROTO_HTTP) ? SP_MSG_TYPE_HTTP_REQ : SP_MSG_TYPE_TCP; + + return req->payload_make(msg, session); +} + +enum sp_error +msg_tcp_send(struct sp_tcp_message *tmsg, struct sp_connection *conn) { uint8_t pkt[4096]; ssize_t pkt_len; int ret; if (conn->is_encrypted) - pkt_len = packet_make_encrypted(pkt, sizeof(pkt), msg->cmd, msg->data, msg->len, &conn->encrypt); + pkt_len = packet_make_encrypted(pkt, sizeof(pkt), tmsg->cmd, tmsg->data, tmsg->len, &conn->encrypt); else - pkt_len = packet_make_plain(pkt, sizeof(pkt), msg->data, msg->len, msg->add_version_header); + pkt_len = packet_make_plain(pkt, sizeof(pkt), tmsg->data, tmsg->len, tmsg->add_version_header); if (pkt_len < 0) RETURN_ERROR(SP_ERR_INVALID, "Error constructing packet to Spotify"); @@ -1394,13 +2207,13 @@ msg_send(struct sp_message *msg, struct sp_connection *conn) if (ret != pkt_len) RETURN_ERROR(SP_ERR_NOCONNECTION, "Error sending packet to Spotify"); -// sp_cb.logmsg("Sent pkt type %d (cmd=0x%02x) with size %zu (fd=%d)\n", msg->type, msg->cmd, pkt_len, conn->response_fd); +// sp_cb.logmsg("Sent pkt type %d (cmd=0x%02x) with size %zu (fd=%d)\n", tmsg->type, tmsg->cmd, pkt_len, conn->response_fd); #else ret = debug_mock_response(msg, conn); if (ret < 0) RETURN_ERROR(SP_ERR_NOCONNECTION, "Error mocking send packet to Spotify"); - sp_cb.logmsg("Mocked send/response pkt type %d (cmd=0x%02x) with size %zu\n", msg->type, msg->cmd, pkt_len); + sp_cb.logmsg("Mocked send/response pkt type %d (cmd=0x%02x) with size %zu\n", tmsg->type, tmsg->cmd, pkt_len); #endif // Save sent packet for MAC calculation later @@ -1410,28 +2223,54 @@ msg_send(struct sp_message *msg, struct sp_connection *conn) // Reset the disconnect timer event_add(conn->idle_ev, &sp_idle_tv); - return 0; + return SP_OK_DONE; error: return ret; } -int -msg_pong(struct sp_session *session) +enum sp_error +msg_http_send(struct http_response *hres, struct http_request *hreq, struct http_session *hses) { - struct sp_message msg; int ret; - ret = msg_make(&msg, MSG_TYPE_PONG, session); + hreq->user_agent = sp_sysinfo.client_name; + +// sp_cb.logmsg("Making http request to %s\n", hreq->url); + + ret = http_request(hres, hreq, hses); + if (ret < 0) + RETURN_ERROR(SP_ERR_NOCONNECTION, "No connection to Spotify for http request"); + + return SP_OK_DONE; + + error: + return ret; +} + +enum sp_error +msg_pong(struct sp_session *session) +{ + struct sp_seq_request *req; + struct sp_message msg = { 0 }; + int ret; + + req = seq_request_get(SP_SEQ_PONG, 0, session->use_legacy); + + ret = msg_make(&msg, req, session); if (ret < 0) RETURN_ERROR(SP_ERR_INVALID, "Error constructing pong message to Spotify"); - ret = msg_send(&msg, &session->conn); + ret = msg_tcp_send(&msg.payload.tmsg, &session->conn); if (ret < 0) RETURN_ERROR(ret, sp_errmsg); - return 0; + msg_clear(&msg); + + return SP_OK_DONE; error: + msg_clear(&msg); + return ret; } diff --git a/src/inputs/librespot-c/src/connection.h b/src/inputs/librespot-c/src/connection.h index 5f1aa8bf..cb804b7e 100644 --- a/src/inputs/librespot-c/src/connection.h +++ b/src/inputs/librespot-c/src/connection.h @@ -2,22 +2,40 @@ void ap_disconnect(struct sp_connection *conn); enum sp_error -ap_connect(struct sp_connection *conn, enum sp_msg_type type, time_t *cooldown_ts, const char *ap_address, struct sp_conn_callbacks *cb, void *cb_arg); +ap_connect(struct sp_connection *conn, struct sp_server *server, time_t *cooldown_ts, struct sp_conn_callbacks *cb, void *cb_arg); -const char * -ap_address_get(struct sp_connection *conn); +void +ap_blacklist(struct sp_server *server); + +int +seq_requests_check(void); + +struct sp_seq_request * +seq_request_get(enum sp_seq_type seq_type, int n, bool use_legacy); + +void +seq_next_set(struct sp_session *session, enum sp_seq_type seq_type); enum sp_error -response_read(struct sp_session *session); +seq_request_prepare(struct sp_seq_request *request, struct sp_conn_callbacks *cb, struct sp_session *session); -bool -msg_is_handshake(enum sp_msg_type type); +enum sp_error +msg_tcp_read_one(struct sp_tcp_message *tmsg, struct sp_connection *conn); + +enum sp_error +msg_handle(struct sp_message *msg, struct sp_session *session); + +void +msg_clear(struct sp_message *msg); int -msg_make(struct sp_message *msg, enum sp_msg_type type, struct sp_session *session); +msg_make(struct sp_message *msg, struct sp_seq_request *req, struct sp_session *session); -int -msg_send(struct sp_message *msg, struct sp_connection *conn); +enum sp_error +msg_tcp_send(struct sp_tcp_message *tmsg, struct sp_connection *conn); -int +enum sp_error +msg_http_send(struct http_response *hres, struct http_request *hreq, struct http_session *hses); + +enum sp_error msg_pong(struct sp_session *session); diff --git a/src/inputs/librespot-c/src/crypto.c b/src/inputs/librespot-c/src/crypto.c index b056cf45..5ef29374 100644 --- a/src/inputs/librespot-c/src/crypto.c +++ b/src/inputs/librespot-c/src/crypto.c @@ -13,6 +13,7 @@ /* ----------------------------------- Crypto ------------------------------- */ #define SHA512_DIGEST_LENGTH 64 +#define SHA1_DIGEST_LENGTH 20 #define bnum_new(bn) \ do { \ if (!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P)) { \ @@ -56,7 +57,7 @@ static const uint8_t prime_bytes[] = }; static void -crypto_log(const char *fmt, ...) +crypto_debug(const char *fmt, ...) { return; } @@ -237,14 +238,14 @@ crypto_decrypt(uint8_t *encrypted, size_t encrypted_len, struct crypto_cipher *c size_t header_len = sizeof(cipher->last_header); size_t payload_len; - crypto_log("Decrypting %zu bytes with nonce %u\n", encrypted_len, cipher->nonce); + crypto_debug("Decrypting %zu bytes with nonce %u\n", encrypted_len, cipher->nonce); // crypto_hexdump("Key\n", cipher->key, sizeof(cipher->key)); // crypto_hexdump("Encrypted\n", encrypted, encrypted_len); // In case we didn't even receive the basics, header and mac, then return. if (encrypted_len < header_len + sizeof(mac)) { - crypto_log("Waiting for %zu header bytes, have %zu\n", header_len + sizeof(mac), encrypted_len); + crypto_debug("Waiting for %zu header bytes, have %zu\n", header_len + sizeof(mac), encrypted_len); return 0; } @@ -264,7 +265,7 @@ crypto_decrypt(uint8_t *encrypted, size_t encrypted_len, struct crypto_cipher *c payload_len = payload_len_get(cipher->last_header); -// crypto_log("Payload len is %zu\n", payload_len); +// crypto_debug("Payload len is %zu\n", payload_len); // crypto_hexdump("Decrypted header\n", encrypted, header_len); } @@ -275,7 +276,7 @@ crypto_decrypt(uint8_t *encrypted, size_t encrypted_len, struct crypto_cipher *c // Not enough data for decrypting the entire packet if (payload_len > encrypted_len) { - crypto_log("Waiting for %zu payload bytes, have %zu\n", payload_len, encrypted_len); + crypto_debug("Waiting for %zu payload bytes, have %zu\n", payload_len, encrypted_len); return 0; } @@ -288,7 +289,7 @@ crypto_decrypt(uint8_t *encrypted, size_t encrypted_len, struct crypto_cipher *c // crypto_hexdump("mac our\n", mac, sizeof(mac)); if (memcmp(mac, encrypted + payload_len, sizeof(mac)) != 0) { - crypto_log("MAC VALIDATION FAILED\n"); // TODO + crypto_debug("MAC validation failed\n"); memset(cipher->last_header, 0, header_len); return -1; } @@ -354,6 +355,8 @@ crypto_aes_seek(struct crypto_aes_cipher *cipher, size_t seek, const char **errm size_t num_blocks; size_t offset; + assert(cipher->aes); + iv_len = gcry_cipher_get_algo_blklen(GCRY_CIPHER_AES128); assert(iv_len == sizeof(iv)); @@ -462,3 +465,129 @@ crypto_base62_to_bin(uint8_t *out, size_t out_len, const char *in) bnum_free(base); return -1; } + +static int +count_trailing_zero_bits(uint8_t *data, size_t data_len) +{ + int zero_bits = 0; + size_t idx; + int bit; + + for (idx = data_len - 1; idx >= 0; idx--) + { + for (bit = 0; bit < 8; bit++) + { + if (data[idx] & (1 << bit)) + return zero_bits; + + zero_bits++; + } + } + + return zero_bits; +} + +static void +sha1_sum(uint8_t *digest, uint8_t *data, size_t data_len, gcry_md_hd_t hdl) +{ + gcry_md_reset(hdl); + + gcry_md_write(hdl, data, data_len); + gcry_md_final(hdl); + + memcpy(digest, gcry_md_read(hdl, GCRY_MD_SHA1), SHA1_DIGEST_LENGTH); +} + +static void +sha1_two_part_sum(uint8_t *digest, uint8_t *data1, size_t data1_len, uint8_t *data2, size_t data2_len, gcry_md_hd_t hdl) +{ + gcry_md_reset(hdl); + + gcry_md_write(hdl, data1, data1_len); + gcry_md_write(hdl, data2, data2_len); + gcry_md_final(hdl); + + memcpy(digest, gcry_md_read(hdl, GCRY_MD_SHA1), SHA1_DIGEST_LENGTH); +} + +static inline void +increase_hashcash(uint8_t *data, int idx) +{ + while (++data[idx] == 0 && idx > 0) + idx--; +} + +static void +timespec_sub(struct timespec *a, struct timespec *b, struct timespec *result) +{ + result->tv_sec = a->tv_sec - b->tv_sec; + result->tv_nsec = a->tv_nsec - b->tv_nsec; + if (result->tv_nsec < 0) + { + --result->tv_sec; + result->tv_nsec += 1000000000L; + } +} + +// Example challenge: +// - loginctx 0300c798435c4b0beb91e3b1db591d0a7f2e32816744a007af41cc7c8043b9295e1ed8a13cc323e4af2d0a3c42463b7a358ed116c33695989e0bfade0dab9c6bc6f7f928df5d49069e8ca4c04c34034669fc97e93da1ca17a7c11b2ffbb9b85f2265b10f6c83f7ef672240cb535eb122265da9b6f8d1a55af522fcbb40efc4eb753756ea38a63aff95d3228219afb0ab887075ac2fe941f7920fd19d32226052fe0956c71f0cb63ba702dd72d50d769920cd99ec6a45e00c85af5287b5d0031d6be4072efe71c59dffa5baa4077cd2eab4f22143eff18c31c69b8647e7f517468c84ed9548943fb1ba6b750ef63cdf9ce0a0fd07cb22d19484f4baa8ee6fa35fc573d9 +// - prefix 48859603d6c16c3202292df155501c55 +// - length (difficulty) 10 +// Solution: +// - suffix 7f7e558bd10c37d200000000000002c7 +int +crypto_hashcash_solve(struct crypto_hashcash_solution *solution, struct crypto_hashcash_challenge *challenge, const char **errmsg) +{ + gcry_md_hd_t hdl; + struct timespec start_ts; + struct timespec stop_ts; + uint8_t digest[SHA1_DIGEST_LENGTH]; + bool solution_found = false; + int i; + + // 1. Hash loginctx + // 2. Create a 16 byte suffix, fill first 8 bytes with last 8 bytes of hash, last with zeroes + // 3. Hash challenge prefix + suffix + // 4. Check if X last bits of hash is zeroes, where X is challenge length + // 5. If not, increment both 8-byte parts of suffix and goto 3 + + memset(solution, 0, sizeof(struct crypto_hashcash_solution)); + + if (gcry_md_open(&hdl, GCRY_MD_SHA1, 0) != GPG_ERR_NO_ERROR) + { + *errmsg = "Error initialising SHA1 hasher"; + return -1; + } + + sha1_sum(digest, challenge->ctx, challenge->ctx_len, hdl); + + memcpy(solution->suffix, digest + SHA1_DIGEST_LENGTH - 8, 8); + + clock_gettime(CLOCK_MONOTONIC, &start_ts); + + for (i = 0; i < challenge->max_iterations; i++) + { + sha1_two_part_sum(digest, challenge->prefix, sizeof(challenge->prefix), solution->suffix, sizeof(solution->suffix), hdl); + + solution_found = (count_trailing_zero_bits(digest, SHA1_DIGEST_LENGTH) >= challenge->wanted_zero_bits); + if (solution_found) + break; + + increase_hashcash(solution->suffix, 7); + increase_hashcash(solution->suffix + 8, 7); + } + + clock_gettime(CLOCK_MONOTONIC, &stop_ts); + + timespec_sub(&stop_ts, &start_ts, &solution->duration); + + gcry_md_close(hdl); + + if (!solution_found) + { + *errmsg = "Could not find a hashcash solution"; + return -1; + } + + return 0; +} diff --git a/src/inputs/librespot-c/src/crypto.h b/src/inputs/librespot-c/src/crypto.h index 2cba11b6..f9721a3d 100644 --- a/src/inputs/librespot-c/src/crypto.h +++ b/src/inputs/librespot-c/src/crypto.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "shannon/Shannon.h" @@ -33,6 +34,26 @@ struct crypto_keys size_t shared_secret_len; }; +struct crypto_hashcash_challenge +{ + uint8_t *ctx; + size_t ctx_len; + uint8_t prefix[16]; + + // Required number of trailing zero bits in the SHA1 of prefix and suffix. + // More bits -> more difficult. + int wanted_zero_bits; + + // Give up limit + int max_iterations; +}; + +struct crypto_hashcash_solution +{ + uint8_t suffix[16]; + struct timespec duration; +}; + void crypto_shared_secret(uint8_t **shared_secret_bytes, size_t *shared_secret_bytes_len, @@ -72,4 +93,7 @@ crypto_aes_decrypt(uint8_t *encrypted, size_t encrypted_len, struct crypto_aes_c int crypto_base62_to_bin(uint8_t *out, size_t out_len, const char *in); +int +crypto_hashcash_solve(struct crypto_hashcash_solution *solution, struct crypto_hashcash_challenge *challenge, const char **errmsg); + #endif /* __CRYPTO_H__ */ diff --git a/src/inputs/librespot-c/src/http.c b/src/inputs/librespot-c/src/http.c new file mode 100644 index 00000000..39bae6e7 --- /dev/null +++ b/src/inputs/librespot-c/src/http.c @@ -0,0 +1,216 @@ +#define _GNU_SOURCE // For asprintf and vasprintf +#include +#include +#include +#include // strncasecmp +#include +#include +#include +#include + +#include +#include + +#include "http.h" + +// Number of seconds the client will wait for a response before aborting +#define HTTP_CLIENT_TIMEOUT 8 + +void +http_session_init(struct http_session *session) +{ + session->internal = curl_easy_init(); +} + +void +http_session_deinit(struct http_session *session) +{ + curl_easy_cleanup(session->internal); +} + +void +http_request_free(struct http_request *request, bool only_content) +{ + int i; + + if (!request) + return; + + free(request->url); + free(request->body); + + for (i = 0; request->headers[i]; i++) + free(request->headers[i]); + + if (only_content) + memset(request, 0, sizeof(struct http_request)); + else + free(request); +} + +void +http_response_free(struct http_response *response, bool only_content) +{ + int i; + + if (!response) + return; + + free(response->body); + + for (i = 0; response->headers[i]; i++) + free(response->headers[i]); + + if (only_content) + memset(response, 0, sizeof(struct http_response)); + else + free(response); +} + +static void +headers_save(struct http_response *response, CURL *curl) +{ + struct curl_header *prev = NULL; + struct curl_header *header; + int i = 0; + + while ((header = curl_easy_nextheader(curl, CURLH_HEADER, 0, prev)) && i < HTTP_MAX_HEADERS) + { + if (asprintf(&response->headers[i], "%s:%s", header->name, header->value) < 0) + return; + + prev = header; + i++; + } + } + +static size_t +body_cb(char *ptr, size_t size, size_t nmemb, void *userdata) +{ + struct http_response *response = userdata; + size_t realsize = size * nmemb; + size_t new_size; + uint8_t *new; + + if (realsize == 0) + { + return 0; + } + + // Make sure the size is +1 larger than needed so we can zero terminate for safety + new_size = response->body_len + realsize + 1; + new = realloc(response->body, new_size); + if (!new) + { + free(response->body); + response->body = NULL; + response->body_len = 0; + return 0; + } + + memcpy(new + response->body_len, ptr, realsize); + response->body_len += realsize; + + memset(new + response->body_len, 0, 1); // Zero terminate in case we need to address as C string + response->body = new; + return nmemb; +} + +int +http_request(struct http_response *response, struct http_request *request, struct http_session *session) +{ + CURL *curl; + CURLcode res; + struct curl_slist *headers = NULL; + long response_code; + long opt; + curl_off_t content_length; + int i; + + if (session) + { + curl = session->internal; + curl_easy_reset(curl); + } + else + { + curl = curl_easy_init(); + } + if (!curl) + return -1; + + memset(response, 0, sizeof(struct http_response)); + + curl_easy_setopt(curl, CURLOPT_URL, request->url); + + // Set optional params + if (request->user_agent) + curl_easy_setopt(curl, CURLOPT_USERAGENT, request->user_agent); + for (i = 0; i < HTTP_MAX_HEADERS && request->headers[i]; i++) + headers = curl_slist_append(headers, request->headers[i]); + if (headers) + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + if ((opt = request->ssl_verify_peer)) + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, opt); + + if (request->headers_only) + { + curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); // Makes curl make a HEAD request + } + else if (request->body && request->body_len > 0) + { + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request->body); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, request->body_len); + } + + curl_easy_setopt(curl, CURLOPT_TIMEOUT, HTTP_CLIENT_TIMEOUT); + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, body_cb); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, response); + + // Allow redirects + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5); + + res = curl_easy_perform(curl); + if (res != CURLE_OK) + goto error; + + res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + response->code = (res == CURLE_OK) ? (int) response_code : -1; + + res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &content_length); + response->content_length = (res == CURLE_OK) ? (ssize_t)content_length : -1; + + headers_save(response, curl); + + curl_slist_free_all(headers); + if (!session) + curl_easy_cleanup(curl); + + return 0; + + error: + curl_slist_free_all(headers); + if (!session) + curl_easy_cleanup(curl); + + return -1; +} + +char * +http_response_header_find(const char *key, struct http_response *response) +{ + char **header; + size_t key_len; + + key_len = strlen(key); + + for (header = response->headers; *header; header++) + { + if (strncasecmp(key, *header, key_len) == 0 && (*header)[key_len] == ':') + return *header + key_len + 1; + } + + return NULL; +} diff --git a/src/inputs/librespot-c/src/http.h b/src/inputs/librespot-c/src/http.h new file mode 100644 index 00000000..30183803 --- /dev/null +++ b/src/inputs/librespot-c/src/http.h @@ -0,0 +1,83 @@ +#ifndef __HTTP_H__ +#define __HTTP_H__ + +#include +#include + +#define HTTP_MAX_HEADERS 32 + +/* Response codes from event2/http.h with 206 added */ +#define HTTP_CONTINUE 100 /**< client should proceed to send */ +#define HTTP_SWITCH_PROTOCOLS 101 /**< switching to another protocol */ +#define HTTP_PROCESSING 102 /**< processing the request, but no response is available yet */ +#define HTTP_EARLYHINTS 103 /**< return some response headers */ +#define HTTP_OK 200 /**< request completed ok */ +#define HTTP_CREATED 201 /**< new resource is created */ +#define HTTP_ACCEPTED 202 /**< accepted for processing */ +#define HTTP_NONAUTHORITATIVE 203 /**< returning a modified version of the origin's response */ +#define HTTP_NOCONTENT 204 /**< request does not have content */ +#define HTTP_PARTIALCONTENT 206 /**< partial content returned*/ +#define HTTP_MOVEPERM 301 /**< the uri moved permanently */ +#define HTTP_MOVETEMP 302 /**< the uri moved temporarily */ +#define HTTP_NOTMODIFIED 304 /**< page was not modified from last */ +#define HTTP_BADREQUEST 400 /**< invalid http request was made */ +#define HTTP_UNAUTHORIZED 401 /**< authentication is required */ +#define HTTP_PAYMENTREQUIRED 402 /**< user exceeded limit on requests */ +#define HTTP_FORBIDDEN 403 /**< user not having the necessary permissions */ +#define HTTP_NOTFOUND 404 /**< could not find content for uri */ +#define HTTP_BADMETHOD 405 /**< method not allowed for this uri */ +#define HTTP_ENTITYTOOLARGE 413 /**< request is larger than the server is able to process */ +#define HTTP_EXPECTATIONFAILED 417 /**< we can't handle this expectation */ +#define HTTP_INTERNAL 500 /**< internal error */ +#define HTTP_NOTIMPLEMENTED 501 /**< not implemented */ +#define HTTP_BADGATEWAY 502 /**< received an invalid response from the upstream */ +#define HTTP_SERVUNAVAIL 503 /**< the server is not available */ + +struct http_session +{ + void *internal; +}; + +struct http_request +{ + char *url; + + const char *user_agent; + bool headers_only; // HEAD request + bool ssl_verify_peer; + + char *headers[HTTP_MAX_HEADERS]; + uint8_t *body; // If not NULL and body_len > 0 -> POST request + size_t body_len; +}; + +struct http_response +{ + int code; + ssize_t content_length; // -1 = unknown + + char *headers[HTTP_MAX_HEADERS]; + uint8_t *body; // Allocated, must be freed by caller + size_t body_len; +}; + +void +http_session_init(struct http_session *session); + +void +http_session_deinit(struct http_session *session); + +void +http_request_free(struct http_request *request, bool only_content); + +void +http_response_free(struct http_response *response, bool only_content); + +// The session is optional but increases performance when making many requests. +int +http_request(struct http_response *response, struct http_request *request, struct http_session *session); + +char * +http_response_header_find(const char *key, struct http_response *response); + +#endif /* !__HTTP_H__ */ diff --git a/src/inputs/librespot-c/src/librespot-c-internal.h b/src/inputs/librespot-c/src/librespot-c-internal.h index f5add799..45d51040 100644 --- a/src/inputs/librespot-c/src/librespot-c-internal.h +++ b/src/inputs/librespot-c/src/librespot-c-internal.h @@ -27,16 +27,19 @@ #define be64toh(x) OSSwapBigToHostInt64(x) #endif +#define ARRAY_SIZE(x) ((unsigned int)(sizeof(x) / sizeof((x)[0]))) + #include "librespot-c.h" #include "crypto.h" +#include "http.h" #include "proto/keyexchange.pb-c.h" #include "proto/authentication.pb-c.h" #include "proto/mercury.pb-c.h" #include "proto/metadata.pb-c.h" - -#define SP_AP_RESOLVE_URL "https://APResolve.spotify.com/" -#define SP_AP_RESOLVE_KEY "ap_list" +#include "proto/clienttoken.pb-c.h" +#include "proto/login5.pb-c.h" +#include "proto/storage_resolve.pb-c.h" // Disconnect from AP after this number of secs idle #define SP_AP_DISCONNECT_SECS 60 @@ -48,6 +51,9 @@ // we get the hint and won't try reconnecting again until after this cooldown #define SP_AP_COOLDOWN_SECS 30 +// How long after a connection failure we try to avoid an AP +#define SP_AP_AVOID_SECS 3600 + // If client hasn't requested anything in particular #define SP_BITRATE_DEFAULT SP_BITRATE_320 @@ -68,15 +74,22 @@ // Download in chunks of 32768 bytes. The chunks shouldn't be too large because // it makes seeking slow (seeking involves jumping around in the file), but // large enough that the file can be probed from the first chunk. -#define SP_CHUNK_LEN_WORDS 1024 * 8 +// For comparison, Spotify for Windows seems to request 7300 byte chunks. +#define SP_CHUNK_LEN 32768 // Used to create default sysinfo, which should be librespot_[short sha]_[random 8 characters build id], // ref https://github.com/plietar/librespot/pull/218. User may override, but // as of 20220516 Spotify seems to have whitelisting of client name. #define SP_CLIENT_NAME_DEFAULT "librespot" -#define SP_CLIENT_VERSION_DEFAULT "000000" +#define SP_CLIENT_VERSION_DEFAULT "0.0.0" #define SP_CLIENT_BUILD_ID_DEFAULT "aabbccdd" +// ClientIdHex from client_id.go. This seems to be the id that Spotify's own app +// uses. It is used in the call to https://clienttoken.spotify.com/v1/clienttoken. +// The endpoint doesn't accept client ID's of app registered at +// develop.spotify.com, so unfortunately spoofing is required. +#define SP_CLIENT_ID_DEFAULT "65b708073fc0480ea92a077233ca87bd" + // Shorthand for error handling #define RETURN_ERROR(r, m) \ do { ret = (r); sp_errmsg = (m); goto error; } while(0) @@ -100,15 +113,24 @@ enum sp_error enum sp_msg_type { - MSG_TYPE_NONE, - MSG_TYPE_CLIENT_HELLO, - MSG_TYPE_CLIENT_RESPONSE_PLAINTEXT, - MSG_TYPE_CLIENT_RESPONSE_ENCRYPTED, - MSG_TYPE_PONG, - MSG_TYPE_MERCURY_TRACK_GET, - MSG_TYPE_MERCURY_EPISODE_GET, - MSG_TYPE_AUDIO_KEY_GET, - MSG_TYPE_CHUNK_REQUEST, + SP_MSG_TYPE_HTTP_REQ, + SP_MSG_TYPE_HTTP_RES, + SP_MSG_TYPE_TCP, +}; + +enum sp_seq_type +{ + SP_SEQ_STOP = 0, + SP_SEQ_LOGIN, + SP_SEQ_MEDIA_OPEN, + SP_SEQ_MEDIA_GET, + SP_SEQ_PONG, +}; + +enum sp_proto +{ + SP_PROTO_TCP, + SP_PROTO_HTTP, }; enum sp_media_type @@ -177,6 +199,7 @@ struct sp_cmdargs int fd_write; size_t seek_pos; enum sp_bitrates bitrate; + int use_legacy; sp_progress_cb progress_cb; void *cb_arg; @@ -190,32 +213,45 @@ struct sp_conn_callbacks event_callback_fn timeout_cb; }; -struct sp_message +struct sp_tcp_message { - enum sp_msg_type type; enum sp_cmd_type cmd; bool encrypt; bool add_version_header; - enum sp_msg_type type_next; - enum sp_msg_type type_queued; + size_t len; + uint8_t *data; +}; - int (*response_handler)(uint8_t *msg, size_t msg_len, struct sp_session *session); +struct sp_message +{ + enum sp_msg_type type; - ssize_t len; - uint8_t data[4096]; + union payload + { + struct sp_tcp_message tmsg; + struct http_request hreq; + struct http_response hres; + } payload; +}; + +struct sp_server +{ + char address[256]; // e.g. ap-gue1.spotify.com + unsigned short port; // normally 433 or 4070 + time_t last_connect_ts; + time_t last_resolved_ts; + time_t last_failed_ts; }; struct sp_connection { + struct sp_server *server; // NULL or pointer to session.accesspoint + bool is_connected; bool is_encrypted; - // Resolved access point - char *ap_address; - unsigned short ap_port; - // Where we receive data from Spotify int response_fd; struct event *response_ev; @@ -237,6 +273,14 @@ struct sp_connection struct crypto_cipher decrypt; }; +struct sp_token +{ + char value[512]; // base64 string, actual size 360 bytes + int32_t expires_after_seconds; + int32_t refresh_after_seconds; + time_t received_ts; +}; + struct sp_mercury { char *uri; @@ -263,14 +307,18 @@ struct sp_file uint8_t media_id[16]; // Decoded value of the URIs base62 enum sp_media_type media_type; // track or episode from URI + // For files that are served via http/"new protocol" (we may receive multiple + // urls). + char *cdnurl[4]; + uint8_t key[16]; uint16_t channel_id; // Length and download progress - size_t len_words; // Length of file in words (32 bit) - size_t offset_words; - size_t received_words; + size_t len_bytes; + size_t offset_bytes; + size_t received_bytes; bool end_of_file; bool end_of_chunk; bool open; @@ -326,11 +374,22 @@ struct sp_channel // Linked list of sessions struct sp_session { + struct sp_server accesspoint; + struct sp_server spclient; + struct sp_server dealer; + struct sp_connection conn; time_t cooldown_ts; - // Address of an access point we want to avoid due to previous failure - char *ap_avoid; + // Use legacy protocol (non http, see seq_requests_legacy) + bool use_legacy; + + struct http_session http_session; + struct sp_token http_clienttoken; + struct sp_token http_accesstoken; + + int n_hashcash_challenges; + struct crypto_hashcash_challenge *hashcash_challenges; bool is_logged_in; struct sp_credentials credentials; @@ -344,24 +403,35 @@ struct sp_session // the current track is also available struct sp_channel *now_streaming_channel; + // Current request in the sequence + struct sp_seq_request *request; + // Go to next step in a request sequence struct event *continue_ev; - // Current, next and subsequent message being processed - enum sp_msg_type msg_type_last; - enum sp_msg_type msg_type_next; - enum sp_msg_type msg_type_queued; - int (*response_handler)(uint8_t *, size_t, struct sp_session *); + // Which sequence comes next + enum sp_seq_type next_seq; struct sp_session *next; }; +struct sp_seq_request +{ + enum sp_seq_type seq_type; + const char *name; // Name of request (for logging) + enum sp_proto proto; + int (*payload_make)(struct sp_message *, struct sp_session *); + enum sp_error (*request_prepare)(struct sp_seq_request *, struct sp_conn_callbacks *, struct sp_session *); + enum sp_error (*response_handler)(struct sp_message *, struct sp_session *); +}; + struct sp_err_map { - ErrorCode errorcode; + int errorcode; const char *errmsg; }; + extern struct sp_callbacks sp_cb; extern struct sp_sysinfo sp_sysinfo; extern const char *sp_errmsg; diff --git a/src/inputs/librespot-c/src/librespot-c.c b/src/inputs/librespot-c/src/librespot-c.c index fb404d6e..c57e0ae2 100644 --- a/src/inputs/librespot-c/src/librespot-c.c +++ b/src/inputs/librespot-c/src/librespot-c.c @@ -23,8 +23,8 @@ /* -Illustration of the general flow, where receive and writing the result are async -operations. For some commands, e.g. open and seek, the entire sequence is +Illustration of the general tcp flow, where receive and writing the result are +async operations. For some commands, e.g. open and seek, the entire sequence is encapsulated in a sync command, which doesn't return until final "done, error or timeout". The command play is async, so all "done/error/timeout" is returned via callbacks. Also, play will loop the flow, i.e. after writing a chunk of data it @@ -79,9 +79,8 @@ static int debug_disconnect_counter; #endif // Forwards -static int -request_make(enum sp_msg_type type, struct sp_session *session); - +static void +sequence_continue(struct sp_session *session); /* -------------------------------- Session --------------------------------- */ @@ -97,7 +96,8 @@ session_free(struct sp_session *session) event_free(session->continue_ev); - free(session->ap_avoid); + http_session_deinit(&session->http_session); + free(session); } @@ -133,6 +133,8 @@ session_new(struct sp_session **out, struct sp_cmdargs *cmdargs, event_callback_ if (!session) RETURN_ERROR(SP_ERR_OOM, "Out of memory creating session"); + http_session_init(&session->http_session); + session->continue_ev = evtimer_new(sp_evbase, cb, session); if (!session->continue_ev) RETURN_ERROR(SP_ERR_OOM, "Out of memory creating session event"); @@ -227,7 +229,7 @@ session_return(struct sp_session *session, enum sp_error err) static void session_error(struct sp_session *session, enum sp_error err) { - sp_cb.logmsg("Session error: %d (occurred before msg %d, queue %d)\n", err, session->msg_type_next, session->msg_type_queued); + sp_cb.logmsg("Session error %d: %s\n", err, sp_errmsg); session_return(session, err); @@ -245,71 +247,32 @@ session_error(struct sp_session *session, enum sp_error err) // Called if an access point disconnects. Will clear current connection and // start a flow where the same request will be made to another access point. +// This is currently only implemented for the non-http connection. static void session_retry(struct sp_session *session) { struct sp_channel *channel = session->now_streaming_channel; - enum sp_msg_type type = session->msg_type_last; - const char *ap_address = ap_address_get(&session->conn); - int ret; - sp_cb.logmsg("Retrying after disconnect (occurred at msg %d)\n", type); + sp_cb.logmsg("Retrying after disconnect\n"); channel_retry(channel); - free(session->ap_avoid); - session->ap_avoid = strdup(ap_address); + ap_blacklist(session->conn.server); ap_disconnect(&session->conn); - // If we were in the middle of a handshake when disconnected we must restart - if (msg_is_handshake(type)) - type = MSG_TYPE_CLIENT_HELLO; + // If we were doing something other than login, queue that + if (session->request->seq_type != SP_SEQ_LOGIN) + seq_next_set(session, session->request->seq_type); - ret = request_make(type, session); - if (ret < 0) - session_error(session, ret); + // Trigger login on a new server + session->request = seq_request_get(SP_SEQ_LOGIN, 0, session->use_legacy); + sequence_continue(session); } + /* ------------------------ Main sequence control --------------------------- */ -// This callback must determine if a new request should be made, or if we are -// done and should return to caller -static void -continue_cb(int fd, short what, void *arg) -{ - struct sp_session *session = arg; - enum sp_msg_type type = MSG_TYPE_NONE; - int ret; - - // type_next has priority, since this is what we use to chain a sequence, e.g. - // the handshake sequence. type_queued is what comes after, e.g. first a - // handshake (type_next) and then a chunk request (type_queued) - if (session->msg_type_next != MSG_TYPE_NONE) - { -// sp_cb.logmsg(">>> msg_next >>>\n"); - - type = session->msg_type_next; - session->msg_type_next = MSG_TYPE_NONE; - } - else if (session->msg_type_queued != MSG_TYPE_NONE) - { -// sp_cb.logmsg(">>> msg_queued >>>\n"); - - type = session->msg_type_queued; - session->msg_type_queued = MSG_TYPE_NONE; - } - - if (type != MSG_TYPE_NONE) - { - ret = request_make(type, session); - if (ret < 0) - session_error(session, ret); - } - else - session_return(session, SP_OK_DONE); // All done, yay! -} - // This callback is triggered by response_cb when the message response handler // said that there was data to write. If not all data can be written in one pass // it will re-add the event. @@ -343,7 +306,7 @@ audio_write_cb(int fd, short what, void *arg) } static void -timeout_cb(int fd, short what, void *arg) +timeout_tcp_cb(int fd, short what, void *arg) { struct sp_session *session = arg; @@ -353,11 +316,24 @@ timeout_cb(int fd, short what, void *arg) } static void -response_cb(int fd, short what, void *arg) +audio_data_received(struct sp_session *session) +{ + struct sp_channel *channel = session->now_streaming_channel; + + if (channel->state == SP_CHANNEL_STATE_PLAYING && !channel->file.end_of_file) + seq_next_set(session, SP_SEQ_MEDIA_GET); + if (channel->progress_cb) + channel->progress_cb(channel->audio_fd[0], channel->cb_arg, channel->file.received_bytes - SP_OGG_HEADER_LEN, channel->file.len_bytes - SP_OGG_HEADER_LEN); + + event_add(channel->audio_write_ev, NULL); +} + +static void +incoming_tcp_cb(int fd, short what, void *arg) { struct sp_session *session = arg; struct sp_connection *conn = &session->conn; - struct sp_channel *channel = session->now_streaming_channel; + struct sp_message msg = { .type = SP_MSG_TYPE_TCP }; int ret; if (what == EV_READ) @@ -367,7 +343,7 @@ response_cb(int fd, short what, void *arg) debug_disconnect_counter++; if (debug_disconnect_counter == 1000) { - sp_cb.logmsg("Simulating a disconnection from the access point (last request type was %d)\n", session->msg_type_last); + sp_cb.logmsg("Simulating a disconnection from the access point (last request was %s)\n", session->request->name); ret = 0; } #endif @@ -376,23 +352,29 @@ response_cb(int fd, short what, void *arg) RETURN_ERROR(SP_ERR_NOCONNECTION, "The access point disconnected"); else if (ret < 0) RETURN_ERROR(SP_ERR_NOCONNECTION, "Connection to Spotify returned an error"); - -// sp_cb.logmsg("Received data len %d\n", ret); } - ret = response_read(session); + // Allocates *data in msg + ret = msg_tcp_read_one(&msg.payload.tmsg, conn); + if (ret == SP_OK_WAIT) + return; + else if (ret < 0) + goto error; + + if (msg.payload.tmsg.len < 128) + sp_cb.hexdump("Received tcp message\n", msg.payload.tmsg.data, msg.payload.tmsg.len); + else + sp_cb.hexdump("Received tcp message (truncated)\n", msg.payload.tmsg.data, 128); + + ret = msg_handle(&msg, session); switch (ret) { case SP_OK_WAIT: // Incomplete, wait for more data break; case SP_OK_DATA: - if (channel->state == SP_CHANNEL_STATE_PLAYING && !channel->file.end_of_file) - session->msg_type_next = MSG_TYPE_CHUNK_REQUEST; - if (channel->progress_cb) - channel->progress_cb(channel->audio_fd[0], channel->cb_arg, 4 * channel->file.received_words - SP_OGG_HEADER_LEN, 4 * channel->file.len_words - SP_OGG_HEADER_LEN); + audio_data_received(session); event_del(conn->timeout_ev); - event_add(channel->audio_write_ev, NULL); break; case SP_OK_DONE: // Got the response we expected, but possibly more to process if (evbuffer_get_length(conn->incoming) > 0) @@ -410,77 +392,140 @@ response_cb(int fd, short what, void *arg) goto error; } + msg_clear(&msg); return; error: + msg_clear(&msg); + if (ret == SP_ERR_NOCONNECTION) session_retry(session); else session_error(session, ret); } -static int -relogin(enum sp_msg_type type, struct sp_session *session) +static enum sp_error +msg_send(struct sp_message *msg, struct sp_session *session) { - int ret; + struct sp_message res; + struct sp_connection *conn = &session->conn; + enum sp_error ret; - ret = request_make(MSG_TYPE_CLIENT_HELLO, session); - if (ret < 0) - RETURN_ERROR(ret, sp_errmsg); + if (session->request->proto == SP_PROTO_TCP) + { + if (msg->payload.tmsg.encrypt) + conn->is_encrypted = true; - // In case we lost connection to the AP we have to make a new handshake for - // the non-handshake message types. So queue the message until the handshake - // is complete. - session->msg_type_queued = type; - return 0; + ret = msg_tcp_send(&msg->payload.tmsg, conn); + if (ret < 0) + RETURN_ERROR(ret, sp_errmsg); + + // Only start timeout timer if a response is expected, otherwise go + // straight to next message + if (session->request->response_handler) + event_add(conn->timeout_ev, &sp_response_timeout_tv); + else + event_active(session->continue_ev, 0, 0); + } + else if (session->request->proto == SP_PROTO_HTTP) + { + res.type = SP_MSG_TYPE_HTTP_RES; + + // Using http_session ensures that Curl will use keepalive and doesn't + // need to reconnect with every request + ret = msg_http_send(&res.payload.hres, &msg->payload.hreq, &session->http_session); + if (ret < 0) + RETURN_ERROR(ret, sp_errmsg); + + // Since http requests are currently sync we can handle the response right + // away. In an async future we would need to make an incoming event and + // have a callback func for msg_handle, like for tcp. + ret = msg_handle(&res, session); + msg_clear(&res); + if (ret < 0) + RETURN_ERROR(ret, sp_errmsg); + else if (ret == SP_OK_DATA) + audio_data_received(session); + else + event_active(session->continue_ev, 0, 0); + } + else + RETURN_ERROR(SP_ERR_INVALID, "Bug! Request is missing protocol type"); + + return SP_OK_DONE; error: return ret; } -static int -request_make(enum sp_msg_type type, struct sp_session *session) +static void +sequence_continue(struct sp_session *session) { - struct sp_message msg; - struct sp_connection *conn = &session->conn; - struct sp_conn_callbacks cb = { sp_evbase, response_cb, timeout_cb }; + struct sp_conn_callbacks cb = { sp_evbase, incoming_tcp_cb, timeout_tcp_cb }; + struct sp_message msg = { 0 }; int ret; -// sp_cb.logmsg("Making request %d\n", type); +// sp_cb.logmsg("Preparing request '%s'\n", session->request->name); - // Make sure the connection is in a state suitable for sending this message - ret = ap_connect(&session->conn, type, &session->cooldown_ts, session->ap_avoid, &cb, session); + // Checks if the dependencies for making the request are met - e.g. do we have + // a connection and a valid token. If not, tries to satisfy them. + ret = seq_request_prepare(session->request, &cb, session); if (ret == SP_OK_WAIT) - return relogin(type, session); // Can't proceed right now, the handshake needs to complete first + sp_cb.logmsg("Sequence queued, first making request '%s'\n", session->request->name); else if (ret < 0) RETURN_ERROR(ret, sp_errmsg); - ret = msg_make(&msg, type, session); - if (ret < 0) + ret = msg_make(&msg, session->request, session); + if (ret > 0) + { + event_active(session->continue_ev, 0, 0); + return; + } + else if (ret < 0) RETURN_ERROR(SP_ERR_INVALID, "Error constructing message to Spotify"); - if (msg.encrypt) - conn->is_encrypted = true; - - ret = msg_send(&msg, conn); + ret = msg_send(&msg, session); if (ret < 0) RETURN_ERROR(ret, sp_errmsg); - // Only start timeout timer if a response is expected, otherwise go straight - // to next message - if (msg.response_handler) - event_add(conn->timeout_ev, &sp_response_timeout_tv); - else - event_active(session->continue_ev, 0, 0); - - session->msg_type_last = type; - session->msg_type_next = msg.type_next; - session->response_handler = msg.response_handler; - - return 0; + msg_clear(&msg); + return; // Proceed in sequence_continue_cb error: - return ret; + msg_clear(&msg); + session_error(session, ret); +} + +static void +sequence_continue_cb(int fd, short what, void *arg) +{ + struct sp_session *session = arg; + + // If set, we are in a sequence and should proceed to the next request + if (session->request) + session->request++; + + // Starting a sequence, or ending one and should possibly start the next + if (!session->request || !session->request->name) + { + session->request = seq_request_get(session->next_seq, 0, session->use_legacy); + seq_next_set(session, SP_SEQ_STOP); + } + + if (session->request && session->request->name) + sequence_continue(session); + else + session_return(session, SP_OK_DONE); // All done, yay! +} + +// All errors that may occur during a sequence are called back async +static void +sequence_start(enum sp_seq_type seq_type, struct sp_session *session) +{ + session->request = NULL; + seq_next_set(session, seq_type); + + event_active(session->continue_ev, 0, 0); } @@ -507,9 +552,7 @@ track_write(void *arg, int *retval) channel_play(channel); - ret = request_make(MSG_TYPE_CHUNK_REQUEST, session); - if (ret < 0) - RETURN_ERROR(ret, sp_errmsg); + sequence_start(SP_SEQ_MEDIA_GET, session); channel->progress_cb = cmdargs->progress_cb; channel->cb_arg = cmdargs->cb_arg; @@ -517,7 +560,7 @@ track_write(void *arg, int *retval) return COMMAND_END; error: - sp_cb.logmsg("Error %d: %s", ret, sp_errmsg); + sp_cb.logmsg("Error %d: %s\n", ret, sp_errmsg); return COMMAND_END; } @@ -548,7 +591,7 @@ track_pause(void *arg, int *retval) } channel_pause(channel); - session->msg_type_next = MSG_TYPE_NONE; + seq_next_set(session, SP_SEQ_STOP); // TODO test if this will work *retval = 1; return COMMAND_PENDING; @@ -580,9 +623,7 @@ track_seek(void *arg, int *retval) // AES decryptor to match the new position. It also flushes the pipe. channel_seek(channel, cmdargs->seek_pos); - ret = request_make(MSG_TYPE_CHUNK_REQUEST, session); - if (ret < 0) - RETURN_ERROR(ret, sp_errmsg); + sequence_start(SP_SEQ_MEDIA_GET, session); *retval = 1; return COMMAND_PENDING; @@ -620,7 +661,6 @@ media_open(void *arg, int *retval) struct sp_cmdargs *cmdargs = arg; struct sp_session *session = cmdargs->session; struct sp_channel *channel = NULL; - enum sp_msg_type type; int ret; ret = session_check(session); @@ -636,22 +676,13 @@ media_open(void *arg, int *retval) cmdargs->fd_read = channel->audio_fd[0]; - // Must be set before calling request_make() because this info is needed for + // Must be set before calling sequence_start() because this info is needed for // making the request session->now_streaming_channel = channel; - if (channel->file.media_type == SP_MEDIA_TRACK) - type = MSG_TYPE_MERCURY_TRACK_GET; - else if (channel->file.media_type == SP_MEDIA_EPISODE) - type = MSG_TYPE_MERCURY_EPISODE_GET; - else - RETURN_ERROR(SP_ERR_INVALID, "Unknown media type in Spotify path"); - // Kicks of a sequence where we first get file info, then get the AES key and // then the first chunk (incl. headers) - ret = request_make(type, session); - if (ret < 0) - RETURN_ERROR(ret, sp_errmsg); + sequence_start(SP_SEQ_MEDIA_OPEN, session); *retval = 1; return COMMAND_PENDING; @@ -685,13 +716,11 @@ login(void *arg, int *retval) struct sp_session *session = NULL; int ret; - ret = session_new(&session, cmdargs, continue_cb); + ret = session_new(&session, cmdargs, sequence_continue_cb); if (ret < 0) goto error; - ret = request_make(MSG_TYPE_CLIENT_HELLO, session); - if (ret < 0) - goto error; + sequence_start(SP_SEQ_LOGIN, session); cmdargs->session = session; @@ -736,6 +765,27 @@ logout(void *arg, int *retval) return COMMAND_END; } +static enum command_state +legacy_set(void *arg, int *retval) +{ + struct sp_cmdargs *cmdargs = arg; + struct sp_session *session = cmdargs->session; + int ret; + + ret = session_check(session); + if (ret < 0) + RETURN_ERROR(SP_ERR_NOSESSION, "Session has disappeared, cannot set legacy mode"); + + if (session->request && session->request->name) + RETURN_ERROR(SP_ERR_INVALID, "Can't switch mode while session is active"); + + session->use_legacy = cmdargs->use_legacy; + + error: + *retval = ret; + return COMMAND_END; +} + static enum command_state metadata_get(void *arg, int *retval) { @@ -749,7 +799,7 @@ metadata_get(void *arg, int *retval) RETURN_ERROR(SP_ERR_NOSESSION, "Session has disappeared, cannot get metadata"); memset(metadata, 0, sizeof(struct sp_metadata)); - metadata->file_len = 4 * session->now_streaming_channel->file.len_words - SP_OGG_HEADER_LEN;; + metadata->file_len = session->now_streaming_channel->file.len_bytes - SP_OGG_HEADER_LEN;; error: *retval = ret; @@ -909,6 +959,17 @@ librespotc_logout(struct sp_session *session) return commands_exec_sync(sp_cmdbase, logout, NULL, &cmdargs); } +int +librespotc_legacy_set(struct sp_session *session, int use_legacy) +{ + struct sp_cmdargs cmdargs = { 0 }; + + cmdargs.session = session; + cmdargs.use_legacy = use_legacy; + + return commands_exec_sync(sp_cmdbase, legacy_set, NULL, &cmdargs); +} + int librespotc_metadata_get(struct sp_metadata *metadata, int fd) { @@ -953,11 +1014,13 @@ system_info_set(struct sp_sysinfo *si_out, struct sp_sysinfo *si_user) { memcpy(si_out, si_user, sizeof(struct sp_sysinfo)); - if (si_out->client_name[9] == '\0') + if (si_out->client_name[0] == '\0') snprintf(si_out->client_name, sizeof(si_out->client_name), SP_CLIENT_NAME_DEFAULT); - if (si_out->client_version[9] == '\0') + if (si_out->client_id[0] == '\0') + snprintf(si_out->client_id, sizeof(si_out->client_id), SP_CLIENT_ID_DEFAULT); + if (si_out->client_version[0] == '\0') snprintf(si_out->client_version, sizeof(si_out->client_version), SP_CLIENT_VERSION_DEFAULT); - if (si_out->client_build_id[9] == '\0') + if (si_out->client_build_id[0] == '\0') snprintf(si_out->client_build_id, sizeof(si_out->client_build_id), SP_CLIENT_BUILD_ID_DEFAULT); } @@ -969,8 +1032,11 @@ librespotc_init(struct sp_sysinfo *sysinfo, struct sp_callbacks *callbacks) if (sp_initialized) RETURN_ERROR(SP_ERR_INVALID, "librespot-c already initialized"); + ret = seq_requests_check(); + if (ret < 0) + RETURN_ERROR(SP_ERR_INVALID, "Bug! Misalignment between enum seq_type and seq_requests"); + sp_cb = *callbacks; - sp_initialized = true; system_info_set(&sp_sysinfo, sysinfo); @@ -989,6 +1055,7 @@ librespotc_init(struct sp_sysinfo *sysinfo, struct sp_callbacks *callbacks) if (sp_cb.thread_name_set) sp_cb.thread_name_set(sp_tid); + sp_initialized = true; return 0; error: diff --git a/src/inputs/librespot-c/src/proto/ad-hermes-proxy.proto b/src/inputs/librespot-c/src/proto/ad-hermes-proxy.proto deleted file mode 100644 index 219bbcbf..00000000 --- a/src/inputs/librespot-c/src/proto/ad-hermes-proxy.proto +++ /dev/null @@ -1,51 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/appstore.proto b/src/inputs/librespot-c/src/proto/appstore.proto deleted file mode 100644 index bddaaf30..00000000 --- a/src/inputs/librespot-c/src/proto/appstore.proto +++ /dev/null @@ -1,95 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/clienttoken.pb-c.c b/src/inputs/librespot-c/src/proto/clienttoken.pb-c.c new file mode 100644 index 00000000..2902ba53 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/clienttoken.pb-c.c @@ -0,0 +1,1676 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: clienttoken.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "clienttoken.pb-c.h" +void spotify__clienttoken__http__v0__client_token_request__init + (Spotify__Clienttoken__Http__V0__ClientTokenRequest *message) +{ + static const Spotify__Clienttoken__Http__V0__ClientTokenRequest init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__client_token_request__get_packed_size + (const Spotify__Clienttoken__Http__V0__ClientTokenRequest *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_token_request__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__client_token_request__pack + (const Spotify__Clienttoken__Http__V0__ClientTokenRequest *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_token_request__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__client_token_request__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ClientTokenRequest *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_token_request__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__ClientTokenRequest * + spotify__clienttoken__http__v0__client_token_request__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__ClientTokenRequest *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__client_token_request__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__client_token_request__free_unpacked + (Spotify__Clienttoken__Http__V0__ClientTokenRequest *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_token_request__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__client_data_request__init + (Spotify__Clienttoken__Http__V0__ClientDataRequest *message) +{ + static const Spotify__Clienttoken__Http__V0__ClientDataRequest init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_DATA_REQUEST__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__client_data_request__get_packed_size + (const Spotify__Clienttoken__Http__V0__ClientDataRequest *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_data_request__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__client_data_request__pack + (const Spotify__Clienttoken__Http__V0__ClientDataRequest *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_data_request__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__client_data_request__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ClientDataRequest *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_data_request__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__ClientDataRequest * + spotify__clienttoken__http__v0__client_data_request__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__ClientDataRequest *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__client_data_request__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__client_data_request__free_unpacked + (Spotify__Clienttoken__Http__V0__ClientDataRequest *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_data_request__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__challenge_answers_request__init + (Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest *message) +{ + static const Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_ANSWERS_REQUEST__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__challenge_answers_request__get_packed_size + (const Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenge_answers_request__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__challenge_answers_request__pack + (const Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenge_answers_request__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__challenge_answers_request__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenge_answers_request__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest * + spotify__clienttoken__http__v0__challenge_answers_request__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__challenge_answers_request__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__challenge_answers_request__free_unpacked + (Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenge_answers_request__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__client_token_response__init + (Spotify__Clienttoken__Http__V0__ClientTokenResponse *message) +{ + static const Spotify__Clienttoken__Http__V0__ClientTokenResponse init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__client_token_response__get_packed_size + (const Spotify__Clienttoken__Http__V0__ClientTokenResponse *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_token_response__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__client_token_response__pack + (const Spotify__Clienttoken__Http__V0__ClientTokenResponse *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_token_response__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__client_token_response__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ClientTokenResponse *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_token_response__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__ClientTokenResponse * + spotify__clienttoken__http__v0__client_token_response__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__ClientTokenResponse *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__client_token_response__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__client_token_response__free_unpacked + (Spotify__Clienttoken__Http__V0__ClientTokenResponse *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_token_response__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__token_domain__init + (Spotify__Clienttoken__Http__V0__TokenDomain *message) +{ + static const Spotify__Clienttoken__Http__V0__TokenDomain init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__TOKEN_DOMAIN__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__token_domain__get_packed_size + (const Spotify__Clienttoken__Http__V0__TokenDomain *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__token_domain__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__token_domain__pack + (const Spotify__Clienttoken__Http__V0__TokenDomain *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__token_domain__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__token_domain__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__TokenDomain *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__token_domain__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__TokenDomain * + spotify__clienttoken__http__v0__token_domain__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__TokenDomain *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__token_domain__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__token_domain__free_unpacked + (Spotify__Clienttoken__Http__V0__TokenDomain *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__token_domain__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__granted_token_response__init + (Spotify__Clienttoken__Http__V0__GrantedTokenResponse *message) +{ + static const Spotify__Clienttoken__Http__V0__GrantedTokenResponse init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__GRANTED_TOKEN_RESPONSE__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__granted_token_response__get_packed_size + (const Spotify__Clienttoken__Http__V0__GrantedTokenResponse *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__granted_token_response__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__granted_token_response__pack + (const Spotify__Clienttoken__Http__V0__GrantedTokenResponse *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__granted_token_response__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__granted_token_response__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__GrantedTokenResponse *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__granted_token_response__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__GrantedTokenResponse * + spotify__clienttoken__http__v0__granted_token_response__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__GrantedTokenResponse *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__granted_token_response__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__granted_token_response__free_unpacked + (Spotify__Clienttoken__Http__V0__GrantedTokenResponse *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__granted_token_response__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__challenges_response__init + (Spotify__Clienttoken__Http__V0__ChallengesResponse *message) +{ + static const Spotify__Clienttoken__Http__V0__ChallengesResponse init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGES_RESPONSE__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__challenges_response__get_packed_size + (const Spotify__Clienttoken__Http__V0__ChallengesResponse *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenges_response__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__challenges_response__pack + (const Spotify__Clienttoken__Http__V0__ChallengesResponse *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenges_response__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__challenges_response__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ChallengesResponse *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenges_response__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__ChallengesResponse * + spotify__clienttoken__http__v0__challenges_response__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__ChallengesResponse *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__challenges_response__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__challenges_response__free_unpacked + (Spotify__Clienttoken__Http__V0__ChallengesResponse *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenges_response__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__client_secret_parameters__init + (Spotify__Clienttoken__Http__V0__ClientSecretParameters *message) +{ + static const Spotify__Clienttoken__Http__V0__ClientSecretParameters init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_SECRET_PARAMETERS__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__client_secret_parameters__get_packed_size + (const Spotify__Clienttoken__Http__V0__ClientSecretParameters *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_secret_parameters__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__client_secret_parameters__pack + (const Spotify__Clienttoken__Http__V0__ClientSecretParameters *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_secret_parameters__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__client_secret_parameters__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ClientSecretParameters *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_secret_parameters__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__ClientSecretParameters * + spotify__clienttoken__http__v0__client_secret_parameters__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__ClientSecretParameters *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__client_secret_parameters__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__client_secret_parameters__free_unpacked + (Spotify__Clienttoken__Http__V0__ClientSecretParameters *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_secret_parameters__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__evaluate_jsparameters__init + (Spotify__Clienttoken__Http__V0__EvaluateJSParameters *message) +{ + static const Spotify__Clienttoken__Http__V0__EvaluateJSParameters init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__EVALUATE_JSPARAMETERS__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__evaluate_jsparameters__get_packed_size + (const Spotify__Clienttoken__Http__V0__EvaluateJSParameters *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__evaluate_jsparameters__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__evaluate_jsparameters__pack + (const Spotify__Clienttoken__Http__V0__EvaluateJSParameters *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__evaluate_jsparameters__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__evaluate_jsparameters__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__EvaluateJSParameters *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__evaluate_jsparameters__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__EvaluateJSParameters * + spotify__clienttoken__http__v0__evaluate_jsparameters__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__EvaluateJSParameters *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__evaluate_jsparameters__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__evaluate_jsparameters__free_unpacked + (Spotify__Clienttoken__Http__V0__EvaluateJSParameters *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__evaluate_jsparameters__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__hash_cash_parameters__init + (Spotify__Clienttoken__Http__V0__HashCashParameters *message) +{ + static const Spotify__Clienttoken__Http__V0__HashCashParameters init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__HASH_CASH_PARAMETERS__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__hash_cash_parameters__get_packed_size + (const Spotify__Clienttoken__Http__V0__HashCashParameters *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__hash_cash_parameters__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__hash_cash_parameters__pack + (const Spotify__Clienttoken__Http__V0__HashCashParameters *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__hash_cash_parameters__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__hash_cash_parameters__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__HashCashParameters *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__hash_cash_parameters__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__HashCashParameters * + spotify__clienttoken__http__v0__hash_cash_parameters__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__HashCashParameters *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__hash_cash_parameters__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__hash_cash_parameters__free_unpacked + (Spotify__Clienttoken__Http__V0__HashCashParameters *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__hash_cash_parameters__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__challenge__init + (Spotify__Clienttoken__Http__V0__Challenge *message) +{ + static const Spotify__Clienttoken__Http__V0__Challenge init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__challenge__get_packed_size + (const Spotify__Clienttoken__Http__V0__Challenge *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenge__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__challenge__pack + (const Spotify__Clienttoken__Http__V0__Challenge *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenge__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__challenge__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__Challenge *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenge__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__Challenge * + spotify__clienttoken__http__v0__challenge__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__Challenge *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__challenge__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__challenge__free_unpacked + (Spotify__Clienttoken__Http__V0__Challenge *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenge__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__client_secret_hmacanswer__init + (Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer *message) +{ + static const Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_SECRET_HMACANSWER__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__client_secret_hmacanswer__get_packed_size + (const Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_secret_hmacanswer__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__client_secret_hmacanswer__pack + (const Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_secret_hmacanswer__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__client_secret_hmacanswer__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_secret_hmacanswer__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer * + spotify__clienttoken__http__v0__client_secret_hmacanswer__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__client_secret_hmacanswer__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__client_secret_hmacanswer__free_unpacked + (Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_secret_hmacanswer__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__evaluate_jsanswer__init + (Spotify__Clienttoken__Http__V0__EvaluateJSAnswer *message) +{ + static const Spotify__Clienttoken__Http__V0__EvaluateJSAnswer init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__EVALUATE_JSANSWER__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__evaluate_jsanswer__get_packed_size + (const Spotify__Clienttoken__Http__V0__EvaluateJSAnswer *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__evaluate_jsanswer__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__evaluate_jsanswer__pack + (const Spotify__Clienttoken__Http__V0__EvaluateJSAnswer *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__evaluate_jsanswer__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__evaluate_jsanswer__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__EvaluateJSAnswer *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__evaluate_jsanswer__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__EvaluateJSAnswer * + spotify__clienttoken__http__v0__evaluate_jsanswer__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__EvaluateJSAnswer *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__evaluate_jsanswer__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__evaluate_jsanswer__free_unpacked + (Spotify__Clienttoken__Http__V0__EvaluateJSAnswer *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__evaluate_jsanswer__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__hash_cash_answer__init + (Spotify__Clienttoken__Http__V0__HashCashAnswer *message) +{ + static const Spotify__Clienttoken__Http__V0__HashCashAnswer init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__HASH_CASH_ANSWER__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__hash_cash_answer__get_packed_size + (const Spotify__Clienttoken__Http__V0__HashCashAnswer *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__hash_cash_answer__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__hash_cash_answer__pack + (const Spotify__Clienttoken__Http__V0__HashCashAnswer *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__hash_cash_answer__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__hash_cash_answer__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__HashCashAnswer *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__hash_cash_answer__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__HashCashAnswer * + spotify__clienttoken__http__v0__hash_cash_answer__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__HashCashAnswer *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__hash_cash_answer__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__hash_cash_answer__free_unpacked + (Spotify__Clienttoken__Http__V0__HashCashAnswer *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__hash_cash_answer__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__challenge_answer__init + (Spotify__Clienttoken__Http__V0__ChallengeAnswer *message) +{ + static const Spotify__Clienttoken__Http__V0__ChallengeAnswer init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_ANSWER__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__challenge_answer__get_packed_size + (const Spotify__Clienttoken__Http__V0__ChallengeAnswer *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenge_answer__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__challenge_answer__pack + (const Spotify__Clienttoken__Http__V0__ChallengeAnswer *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenge_answer__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__challenge_answer__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ChallengeAnswer *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenge_answer__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__ChallengeAnswer * + spotify__clienttoken__http__v0__challenge_answer__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__ChallengeAnswer *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__challenge_answer__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__challenge_answer__free_unpacked + (Spotify__Clienttoken__Http__V0__ChallengeAnswer *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__challenge_answer__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__http__v0__client_token_bad_request__init + (Spotify__Clienttoken__Http__V0__ClientTokenBadRequest *message) +{ + static const Spotify__Clienttoken__Http__V0__ClientTokenBadRequest init_value = SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_BAD_REQUEST__INIT; + *message = init_value; +} +size_t spotify__clienttoken__http__v0__client_token_bad_request__get_packed_size + (const Spotify__Clienttoken__Http__V0__ClientTokenBadRequest *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_token_bad_request__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__http__v0__client_token_bad_request__pack + (const Spotify__Clienttoken__Http__V0__ClientTokenBadRequest *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_token_bad_request__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__http__v0__client_token_bad_request__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ClientTokenBadRequest *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_token_bad_request__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Http__V0__ClientTokenBadRequest * + spotify__clienttoken__http__v0__client_token_bad_request__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Http__V0__ClientTokenBadRequest *) + protobuf_c_message_unpack (&spotify__clienttoken__http__v0__client_token_bad_request__descriptor, + allocator, len, data); +} +void spotify__clienttoken__http__v0__client_token_bad_request__free_unpacked + (Spotify__Clienttoken__Http__V0__ClientTokenBadRequest *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__http__v0__client_token_bad_request__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__client_token_request__field_descriptors[3] = +{ + { + "request_type", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__ClientTokenRequest, request_type), + &spotify__clienttoken__http__v0__client_token_request_type__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "client_data", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Http__V0__ClientTokenRequest, request_case), + offsetof(Spotify__Clienttoken__Http__V0__ClientTokenRequest, client_data), + &spotify__clienttoken__http__v0__client_data_request__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "challenge_answers", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Http__V0__ClientTokenRequest, request_case), + offsetof(Spotify__Clienttoken__Http__V0__ClientTokenRequest, challenge_answers), + &spotify__clienttoken__http__v0__challenge_answers_request__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__client_token_request__field_indices_by_name[] = { + 2, /* field[2] = challenge_answers */ + 1, /* field[1] = client_data */ + 0, /* field[0] = request_type */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__client_token_request__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 3 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__client_token_request__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.ClientTokenRequest", + "ClientTokenRequest", + "Spotify__Clienttoken__Http__V0__ClientTokenRequest", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__ClientTokenRequest), + 3, + spotify__clienttoken__http__v0__client_token_request__field_descriptors, + spotify__clienttoken__http__v0__client_token_request__field_indices_by_name, + 1, spotify__clienttoken__http__v0__client_token_request__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__client_token_request__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__client_data_request__field_descriptors[3] = +{ + { + "client_version", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__ClientDataRequest, client_version), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "client_id", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__ClientDataRequest, client_id), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "connectivity_sdk_data", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Http__V0__ClientDataRequest, data_case), + offsetof(Spotify__Clienttoken__Http__V0__ClientDataRequest, connectivity_sdk_data), + &spotify__clienttoken__data__v0__connectivity_sdk_data__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__client_data_request__field_indices_by_name[] = { + 1, /* field[1] = client_id */ + 0, /* field[0] = client_version */ + 2, /* field[2] = connectivity_sdk_data */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__client_data_request__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 3 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__client_data_request__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.ClientDataRequest", + "ClientDataRequest", + "Spotify__Clienttoken__Http__V0__ClientDataRequest", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__ClientDataRequest), + 3, + spotify__clienttoken__http__v0__client_data_request__field_descriptors, + spotify__clienttoken__http__v0__client_data_request__field_indices_by_name, + 1, spotify__clienttoken__http__v0__client_data_request__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__client_data_request__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__challenge_answers_request__field_descriptors[2] = +{ + { + "state", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest, state), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "answers", + 2, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest, n_answers), + offsetof(Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest, answers), + &spotify__clienttoken__http__v0__challenge_answer__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__challenge_answers_request__field_indices_by_name[] = { + 1, /* field[1] = answers */ + 0, /* field[0] = state */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__challenge_answers_request__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__challenge_answers_request__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.ChallengeAnswersRequest", + "ChallengeAnswersRequest", + "Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest), + 2, + spotify__clienttoken__http__v0__challenge_answers_request__field_descriptors, + spotify__clienttoken__http__v0__challenge_answers_request__field_indices_by_name, + 1, spotify__clienttoken__http__v0__challenge_answers_request__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__challenge_answers_request__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__client_token_response__field_descriptors[3] = +{ + { + "response_type", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__ClientTokenResponse, response_type), + &spotify__clienttoken__http__v0__client_token_response_type__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "granted_token", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Http__V0__ClientTokenResponse, response_case), + offsetof(Spotify__Clienttoken__Http__V0__ClientTokenResponse, granted_token), + &spotify__clienttoken__http__v0__granted_token_response__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "challenges", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Http__V0__ClientTokenResponse, response_case), + offsetof(Spotify__Clienttoken__Http__V0__ClientTokenResponse, challenges), + &spotify__clienttoken__http__v0__challenges_response__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__client_token_response__field_indices_by_name[] = { + 2, /* field[2] = challenges */ + 1, /* field[1] = granted_token */ + 0, /* field[0] = response_type */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__client_token_response__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 3 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__client_token_response__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.ClientTokenResponse", + "ClientTokenResponse", + "Spotify__Clienttoken__Http__V0__ClientTokenResponse", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__ClientTokenResponse), + 3, + spotify__clienttoken__http__v0__client_token_response__field_descriptors, + spotify__clienttoken__http__v0__client_token_response__field_indices_by_name, + 1, spotify__clienttoken__http__v0__client_token_response__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__client_token_response__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__token_domain__field_descriptors[1] = +{ + { + "domain", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__TokenDomain, domain), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__token_domain__field_indices_by_name[] = { + 0, /* field[0] = domain */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__token_domain__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 1 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__token_domain__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.TokenDomain", + "TokenDomain", + "Spotify__Clienttoken__Http__V0__TokenDomain", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__TokenDomain), + 1, + spotify__clienttoken__http__v0__token_domain__field_descriptors, + spotify__clienttoken__http__v0__token_domain__field_indices_by_name, + 1, spotify__clienttoken__http__v0__token_domain__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__token_domain__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__granted_token_response__field_descriptors[4] = +{ + { + "token", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__GrantedTokenResponse, token), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "expires_after_seconds", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__GrantedTokenResponse, expires_after_seconds), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "refresh_after_seconds", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__GrantedTokenResponse, refresh_after_seconds), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "domains", + 4, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Http__V0__GrantedTokenResponse, n_domains), + offsetof(Spotify__Clienttoken__Http__V0__GrantedTokenResponse, domains), + &spotify__clienttoken__http__v0__token_domain__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__granted_token_response__field_indices_by_name[] = { + 3, /* field[3] = domains */ + 1, /* field[1] = expires_after_seconds */ + 2, /* field[2] = refresh_after_seconds */ + 0, /* field[0] = token */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__granted_token_response__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 4 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__granted_token_response__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.GrantedTokenResponse", + "GrantedTokenResponse", + "Spotify__Clienttoken__Http__V0__GrantedTokenResponse", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__GrantedTokenResponse), + 4, + spotify__clienttoken__http__v0__granted_token_response__field_descriptors, + spotify__clienttoken__http__v0__granted_token_response__field_indices_by_name, + 1, spotify__clienttoken__http__v0__granted_token_response__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__granted_token_response__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__challenges_response__field_descriptors[2] = +{ + { + "state", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__ChallengesResponse, state), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "challenges", + 2, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Http__V0__ChallengesResponse, n_challenges), + offsetof(Spotify__Clienttoken__Http__V0__ChallengesResponse, challenges), + &spotify__clienttoken__http__v0__challenge__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__challenges_response__field_indices_by_name[] = { + 1, /* field[1] = challenges */ + 0, /* field[0] = state */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__challenges_response__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__challenges_response__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.ChallengesResponse", + "ChallengesResponse", + "Spotify__Clienttoken__Http__V0__ChallengesResponse", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__ChallengesResponse), + 2, + spotify__clienttoken__http__v0__challenges_response__field_descriptors, + spotify__clienttoken__http__v0__challenges_response__field_indices_by_name, + 1, spotify__clienttoken__http__v0__challenges_response__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__challenges_response__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__client_secret_parameters__field_descriptors[1] = +{ + { + "salt", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__ClientSecretParameters, salt), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__client_secret_parameters__field_indices_by_name[] = { + 0, /* field[0] = salt */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__client_secret_parameters__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 1 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__client_secret_parameters__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.ClientSecretParameters", + "ClientSecretParameters", + "Spotify__Clienttoken__Http__V0__ClientSecretParameters", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__ClientSecretParameters), + 1, + spotify__clienttoken__http__v0__client_secret_parameters__field_descriptors, + spotify__clienttoken__http__v0__client_secret_parameters__field_indices_by_name, + 1, spotify__clienttoken__http__v0__client_secret_parameters__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__client_secret_parameters__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__evaluate_jsparameters__field_descriptors[2] = +{ + { + "code", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__EvaluateJSParameters, code), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "libraries", + 2, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_STRING, + offsetof(Spotify__Clienttoken__Http__V0__EvaluateJSParameters, n_libraries), + offsetof(Spotify__Clienttoken__Http__V0__EvaluateJSParameters, libraries), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__evaluate_jsparameters__field_indices_by_name[] = { + 0, /* field[0] = code */ + 1, /* field[1] = libraries */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__evaluate_jsparameters__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__evaluate_jsparameters__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.EvaluateJSParameters", + "EvaluateJSParameters", + "Spotify__Clienttoken__Http__V0__EvaluateJSParameters", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__EvaluateJSParameters), + 2, + spotify__clienttoken__http__v0__evaluate_jsparameters__field_descriptors, + spotify__clienttoken__http__v0__evaluate_jsparameters__field_indices_by_name, + 1, spotify__clienttoken__http__v0__evaluate_jsparameters__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__evaluate_jsparameters__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__hash_cash_parameters__field_descriptors[2] = +{ + { + "length", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__HashCashParameters, length), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "prefix", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__HashCashParameters, prefix), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__hash_cash_parameters__field_indices_by_name[] = { + 0, /* field[0] = length */ + 1, /* field[1] = prefix */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__hash_cash_parameters__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__hash_cash_parameters__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.HashCashParameters", + "HashCashParameters", + "Spotify__Clienttoken__Http__V0__HashCashParameters", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__HashCashParameters), + 2, + spotify__clienttoken__http__v0__hash_cash_parameters__field_descriptors, + spotify__clienttoken__http__v0__hash_cash_parameters__field_indices_by_name, + 1, spotify__clienttoken__http__v0__hash_cash_parameters__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__hash_cash_parameters__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__challenge__field_descriptors[4] = +{ + { + "type", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__Challenge, type), + &spotify__clienttoken__http__v0__challenge_type__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "client_secret_parameters", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Http__V0__Challenge, parameters_case), + offsetof(Spotify__Clienttoken__Http__V0__Challenge, client_secret_parameters), + &spotify__clienttoken__http__v0__client_secret_parameters__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "evaluate_js_parameters", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Http__V0__Challenge, parameters_case), + offsetof(Spotify__Clienttoken__Http__V0__Challenge, evaluate_js_parameters), + &spotify__clienttoken__http__v0__evaluate_jsparameters__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "evaluate_hashcash_parameters", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Http__V0__Challenge, parameters_case), + offsetof(Spotify__Clienttoken__Http__V0__Challenge, evaluate_hashcash_parameters), + &spotify__clienttoken__http__v0__hash_cash_parameters__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__challenge__field_indices_by_name[] = { + 1, /* field[1] = client_secret_parameters */ + 3, /* field[3] = evaluate_hashcash_parameters */ + 2, /* field[2] = evaluate_js_parameters */ + 0, /* field[0] = type */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__challenge__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 4 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__challenge__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.Challenge", + "Challenge", + "Spotify__Clienttoken__Http__V0__Challenge", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__Challenge), + 4, + spotify__clienttoken__http__v0__challenge__field_descriptors, + spotify__clienttoken__http__v0__challenge__field_indices_by_name, + 1, spotify__clienttoken__http__v0__challenge__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__challenge__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__client_secret_hmacanswer__field_descriptors[1] = +{ + { + "hmac", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer, hmac), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__client_secret_hmacanswer__field_indices_by_name[] = { + 0, /* field[0] = hmac */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__client_secret_hmacanswer__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 1 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__client_secret_hmacanswer__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.ClientSecretHMACAnswer", + "ClientSecretHMACAnswer", + "Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer), + 1, + spotify__clienttoken__http__v0__client_secret_hmacanswer__field_descriptors, + spotify__clienttoken__http__v0__client_secret_hmacanswer__field_indices_by_name, + 1, spotify__clienttoken__http__v0__client_secret_hmacanswer__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__client_secret_hmacanswer__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__evaluate_jsanswer__field_descriptors[1] = +{ + { + "result", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__EvaluateJSAnswer, result), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__evaluate_jsanswer__field_indices_by_name[] = { + 0, /* field[0] = result */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__evaluate_jsanswer__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 1 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__evaluate_jsanswer__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.EvaluateJSAnswer", + "EvaluateJSAnswer", + "Spotify__Clienttoken__Http__V0__EvaluateJSAnswer", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__EvaluateJSAnswer), + 1, + spotify__clienttoken__http__v0__evaluate_jsanswer__field_descriptors, + spotify__clienttoken__http__v0__evaluate_jsanswer__field_indices_by_name, + 1, spotify__clienttoken__http__v0__evaluate_jsanswer__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__evaluate_jsanswer__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__hash_cash_answer__field_descriptors[1] = +{ + { + "suffix", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__HashCashAnswer, suffix), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__hash_cash_answer__field_indices_by_name[] = { + 0, /* field[0] = suffix */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__hash_cash_answer__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 1 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__hash_cash_answer__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.HashCashAnswer", + "HashCashAnswer", + "Spotify__Clienttoken__Http__V0__HashCashAnswer", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__HashCashAnswer), + 1, + spotify__clienttoken__http__v0__hash_cash_answer__field_descriptors, + spotify__clienttoken__http__v0__hash_cash_answer__field_indices_by_name, + 1, spotify__clienttoken__http__v0__hash_cash_answer__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__hash_cash_answer__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__challenge_answer__field_descriptors[4] = +{ + { + "ChallengeType", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__ChallengeAnswer, challengetype), + &spotify__clienttoken__http__v0__challenge_type__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "client_secret", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Http__V0__ChallengeAnswer, answer_case), + offsetof(Spotify__Clienttoken__Http__V0__ChallengeAnswer, client_secret), + &spotify__clienttoken__http__v0__client_secret_hmacanswer__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "evaluate_js", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Http__V0__ChallengeAnswer, answer_case), + offsetof(Spotify__Clienttoken__Http__V0__ChallengeAnswer, evaluate_js), + &spotify__clienttoken__http__v0__evaluate_jsanswer__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "hash_cash", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Http__V0__ChallengeAnswer, answer_case), + offsetof(Spotify__Clienttoken__Http__V0__ChallengeAnswer, hash_cash), + &spotify__clienttoken__http__v0__hash_cash_answer__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__challenge_answer__field_indices_by_name[] = { + 0, /* field[0] = ChallengeType */ + 1, /* field[1] = client_secret */ + 2, /* field[2] = evaluate_js */ + 3, /* field[3] = hash_cash */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__challenge_answer__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 4 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__challenge_answer__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.ChallengeAnswer", + "ChallengeAnswer", + "Spotify__Clienttoken__Http__V0__ChallengeAnswer", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__ChallengeAnswer), + 4, + spotify__clienttoken__http__v0__challenge_answer__field_descriptors, + spotify__clienttoken__http__v0__challenge_answer__field_indices_by_name, + 1, spotify__clienttoken__http__v0__challenge_answer__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__challenge_answer__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__http__v0__client_token_bad_request__field_descriptors[1] = +{ + { + "message", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Http__V0__ClientTokenBadRequest, message), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__http__v0__client_token_bad_request__field_indices_by_name[] = { + 0, /* field[0] = message */ +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__client_token_bad_request__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 1 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__client_token_bad_request__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.ClientTokenBadRequest", + "ClientTokenBadRequest", + "Spotify__Clienttoken__Http__V0__ClientTokenBadRequest", + "spotify.clienttoken.http.v0", + sizeof(Spotify__Clienttoken__Http__V0__ClientTokenBadRequest), + 1, + spotify__clienttoken__http__v0__client_token_bad_request__field_descriptors, + spotify__clienttoken__http__v0__client_token_bad_request__field_indices_by_name, + 1, spotify__clienttoken__http__v0__client_token_bad_request__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__http__v0__client_token_bad_request__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCEnumValue spotify__clienttoken__http__v0__client_token_request_type__enum_values_by_number[3] = +{ + { "REQUEST_UNKNOWN", "SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST_TYPE__REQUEST_UNKNOWN", 0 }, + { "REQUEST_CLIENT_DATA_REQUEST", "SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST_TYPE__REQUEST_CLIENT_DATA_REQUEST", 1 }, + { "REQUEST_CHALLENGE_ANSWERS_REQUEST", "SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST_TYPE__REQUEST_CHALLENGE_ANSWERS_REQUEST", 2 }, +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__client_token_request_type__value_ranges[] = { +{0, 0},{0, 3} +}; +static const ProtobufCEnumValueIndex spotify__clienttoken__http__v0__client_token_request_type__enum_values_by_name[3] = +{ + { "REQUEST_CHALLENGE_ANSWERS_REQUEST", 2 }, + { "REQUEST_CLIENT_DATA_REQUEST", 1 }, + { "REQUEST_UNKNOWN", 0 }, +}; +const ProtobufCEnumDescriptor spotify__clienttoken__http__v0__client_token_request_type__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.ClientTokenRequestType", + "ClientTokenRequestType", + "Spotify__Clienttoken__Http__V0__ClientTokenRequestType", + "spotify.clienttoken.http.v0", + 3, + spotify__clienttoken__http__v0__client_token_request_type__enum_values_by_number, + 3, + spotify__clienttoken__http__v0__client_token_request_type__enum_values_by_name, + 1, + spotify__clienttoken__http__v0__client_token_request_type__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; +static const ProtobufCEnumValue spotify__clienttoken__http__v0__client_token_response_type__enum_values_by_number[3] = +{ + { "RESPONSE_UNKNOWN", "SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE_TYPE__RESPONSE_UNKNOWN", 0 }, + { "RESPONSE_GRANTED_TOKEN_RESPONSE", "SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE_TYPE__RESPONSE_GRANTED_TOKEN_RESPONSE", 1 }, + { "RESPONSE_CHALLENGES_RESPONSE", "SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE_TYPE__RESPONSE_CHALLENGES_RESPONSE", 2 }, +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__client_token_response_type__value_ranges[] = { +{0, 0},{0, 3} +}; +static const ProtobufCEnumValueIndex spotify__clienttoken__http__v0__client_token_response_type__enum_values_by_name[3] = +{ + { "RESPONSE_CHALLENGES_RESPONSE", 2 }, + { "RESPONSE_GRANTED_TOKEN_RESPONSE", 1 }, + { "RESPONSE_UNKNOWN", 0 }, +}; +const ProtobufCEnumDescriptor spotify__clienttoken__http__v0__client_token_response_type__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.ClientTokenResponseType", + "ClientTokenResponseType", + "Spotify__Clienttoken__Http__V0__ClientTokenResponseType", + "spotify.clienttoken.http.v0", + 3, + spotify__clienttoken__http__v0__client_token_response_type__enum_values_by_number, + 3, + spotify__clienttoken__http__v0__client_token_response_type__enum_values_by_name, + 1, + spotify__clienttoken__http__v0__client_token_response_type__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; +static const ProtobufCEnumValue spotify__clienttoken__http__v0__challenge_type__enum_values_by_number[4] = +{ + { "CHALLENGE_UNKNOWN", "SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_TYPE__CHALLENGE_UNKNOWN", 0 }, + { "CHALLENGE_CLIENT_SECRET_HMAC", "SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_TYPE__CHALLENGE_CLIENT_SECRET_HMAC", 1 }, + { "CHALLENGE_EVALUATE_JS", "SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_TYPE__CHALLENGE_EVALUATE_JS", 2 }, + { "CHALLENGE_HASH_CASH", "SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_TYPE__CHALLENGE_HASH_CASH", 3 }, +}; +static const ProtobufCIntRange spotify__clienttoken__http__v0__challenge_type__value_ranges[] = { +{0, 0},{0, 4} +}; +static const ProtobufCEnumValueIndex spotify__clienttoken__http__v0__challenge_type__enum_values_by_name[4] = +{ + { "CHALLENGE_CLIENT_SECRET_HMAC", 1 }, + { "CHALLENGE_EVALUATE_JS", 2 }, + { "CHALLENGE_HASH_CASH", 3 }, + { "CHALLENGE_UNKNOWN", 0 }, +}; +const ProtobufCEnumDescriptor spotify__clienttoken__http__v0__challenge_type__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "spotify.clienttoken.http.v0.ChallengeType", + "ChallengeType", + "Spotify__Clienttoken__Http__V0__ChallengeType", + "spotify.clienttoken.http.v0", + 4, + spotify__clienttoken__http__v0__challenge_type__enum_values_by_number, + 4, + spotify__clienttoken__http__v0__challenge_type__enum_values_by_name, + 1, + spotify__clienttoken__http__v0__challenge_type__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; diff --git a/src/inputs/librespot-c/src/proto/clienttoken.pb-c.h b/src/inputs/librespot-c/src/proto/clienttoken.pb-c.h new file mode 100644 index 00000000..433cb21e --- /dev/null +++ b/src/inputs/librespot-c/src/proto/clienttoken.pb-c.h @@ -0,0 +1,678 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: clienttoken.proto */ + +#ifndef PROTOBUF_C_clienttoken_2eproto__INCLUDED +#define PROTOBUF_C_clienttoken_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# 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 1004001 < 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 + +#include "connectivity.pb-c.h" + +typedef struct Spotify__Clienttoken__Http__V0__ClientTokenRequest Spotify__Clienttoken__Http__V0__ClientTokenRequest; +typedef struct Spotify__Clienttoken__Http__V0__ClientDataRequest Spotify__Clienttoken__Http__V0__ClientDataRequest; +typedef struct Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest; +typedef struct Spotify__Clienttoken__Http__V0__ClientTokenResponse Spotify__Clienttoken__Http__V0__ClientTokenResponse; +typedef struct Spotify__Clienttoken__Http__V0__TokenDomain Spotify__Clienttoken__Http__V0__TokenDomain; +typedef struct Spotify__Clienttoken__Http__V0__GrantedTokenResponse Spotify__Clienttoken__Http__V0__GrantedTokenResponse; +typedef struct Spotify__Clienttoken__Http__V0__ChallengesResponse Spotify__Clienttoken__Http__V0__ChallengesResponse; +typedef struct Spotify__Clienttoken__Http__V0__ClientSecretParameters Spotify__Clienttoken__Http__V0__ClientSecretParameters; +typedef struct Spotify__Clienttoken__Http__V0__EvaluateJSParameters Spotify__Clienttoken__Http__V0__EvaluateJSParameters; +typedef struct Spotify__Clienttoken__Http__V0__HashCashParameters Spotify__Clienttoken__Http__V0__HashCashParameters; +typedef struct Spotify__Clienttoken__Http__V0__Challenge Spotify__Clienttoken__Http__V0__Challenge; +typedef struct Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer; +typedef struct Spotify__Clienttoken__Http__V0__EvaluateJSAnswer Spotify__Clienttoken__Http__V0__EvaluateJSAnswer; +typedef struct Spotify__Clienttoken__Http__V0__HashCashAnswer Spotify__Clienttoken__Http__V0__HashCashAnswer; +typedef struct Spotify__Clienttoken__Http__V0__ChallengeAnswer Spotify__Clienttoken__Http__V0__ChallengeAnswer; +typedef struct Spotify__Clienttoken__Http__V0__ClientTokenBadRequest Spotify__Clienttoken__Http__V0__ClientTokenBadRequest; + + +/* --- enums --- */ + +typedef enum _Spotify__Clienttoken__Http__V0__ClientTokenRequestType { + SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST_TYPE__REQUEST_UNKNOWN = 0, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST_TYPE__REQUEST_CLIENT_DATA_REQUEST = 1, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST_TYPE__REQUEST_CHALLENGE_ANSWERS_REQUEST = 2 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST_TYPE) +} Spotify__Clienttoken__Http__V0__ClientTokenRequestType; +typedef enum _Spotify__Clienttoken__Http__V0__ClientTokenResponseType { + SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE_TYPE__RESPONSE_UNKNOWN = 0, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE_TYPE__RESPONSE_GRANTED_TOKEN_RESPONSE = 1, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE_TYPE__RESPONSE_CHALLENGES_RESPONSE = 2 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE_TYPE) +} Spotify__Clienttoken__Http__V0__ClientTokenResponseType; +typedef enum _Spotify__Clienttoken__Http__V0__ChallengeType { + SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_TYPE__CHALLENGE_UNKNOWN = 0, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_TYPE__CHALLENGE_CLIENT_SECRET_HMAC = 1, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_TYPE__CHALLENGE_EVALUATE_JS = 2, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_TYPE__CHALLENGE_HASH_CASH = 3 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_TYPE) +} Spotify__Clienttoken__Http__V0__ChallengeType; + +/* --- messages --- */ + +typedef enum { + SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST__REQUEST__NOT_SET = 0, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST__REQUEST_CLIENT_DATA = 2, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST__REQUEST_CHALLENGE_ANSWERS = 3 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST__REQUEST__CASE) +} Spotify__Clienttoken__Http__V0__ClientTokenRequest__RequestCase; + +struct Spotify__Clienttoken__Http__V0__ClientTokenRequest +{ + ProtobufCMessage base; + Spotify__Clienttoken__Http__V0__ClientTokenRequestType request_type; + Spotify__Clienttoken__Http__V0__ClientTokenRequest__RequestCase request_case; + union { + Spotify__Clienttoken__Http__V0__ClientDataRequest *client_data; + Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest *challenge_answers; + }; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__client_token_request__descriptor) \ + , SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST_TYPE__REQUEST_UNKNOWN, SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_REQUEST__REQUEST__NOT_SET, {0} } + + +typedef enum { + SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_DATA_REQUEST__DATA__NOT_SET = 0, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_DATA_REQUEST__DATA_CONNECTIVITY_SDK_DATA = 3 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_DATA_REQUEST__DATA__CASE) +} Spotify__Clienttoken__Http__V0__ClientDataRequest__DataCase; + +struct Spotify__Clienttoken__Http__V0__ClientDataRequest +{ + ProtobufCMessage base; + char *client_version; + char *client_id; + Spotify__Clienttoken__Http__V0__ClientDataRequest__DataCase data_case; + union { + Spotify__Clienttoken__Data__V0__ConnectivitySdkData *connectivity_sdk_data; + }; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_DATA_REQUEST__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__client_data_request__descriptor) \ + , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_DATA_REQUEST__DATA__NOT_SET, {0} } + + +struct Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest +{ + ProtobufCMessage base; + char *state; + size_t n_answers; + Spotify__Clienttoken__Http__V0__ChallengeAnswer **answers; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_ANSWERS_REQUEST__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__challenge_answers_request__descriptor) \ + , (char *)protobuf_c_empty_string, 0,NULL } + + +typedef enum { + SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE__RESPONSE__NOT_SET = 0, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE__RESPONSE_GRANTED_TOKEN = 2, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE__RESPONSE_CHALLENGES = 3 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE__RESPONSE__CASE) +} Spotify__Clienttoken__Http__V0__ClientTokenResponse__ResponseCase; + +struct Spotify__Clienttoken__Http__V0__ClientTokenResponse +{ + ProtobufCMessage base; + Spotify__Clienttoken__Http__V0__ClientTokenResponseType response_type; + Spotify__Clienttoken__Http__V0__ClientTokenResponse__ResponseCase response_case; + union { + Spotify__Clienttoken__Http__V0__GrantedTokenResponse *granted_token; + Spotify__Clienttoken__Http__V0__ChallengesResponse *challenges; + }; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__client_token_response__descriptor) \ + , SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE_TYPE__RESPONSE_UNKNOWN, SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_RESPONSE__RESPONSE__NOT_SET, {0} } + + +struct Spotify__Clienttoken__Http__V0__TokenDomain +{ + ProtobufCMessage base; + char *domain; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__TOKEN_DOMAIN__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__token_domain__descriptor) \ + , (char *)protobuf_c_empty_string } + + +struct Spotify__Clienttoken__Http__V0__GrantedTokenResponse +{ + ProtobufCMessage base; + char *token; + int32_t expires_after_seconds; + int32_t refresh_after_seconds; + size_t n_domains; + Spotify__Clienttoken__Http__V0__TokenDomain **domains; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__GRANTED_TOKEN_RESPONSE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__granted_token_response__descriptor) \ + , (char *)protobuf_c_empty_string, 0, 0, 0,NULL } + + +struct Spotify__Clienttoken__Http__V0__ChallengesResponse +{ + ProtobufCMessage base; + char *state; + size_t n_challenges; + Spotify__Clienttoken__Http__V0__Challenge **challenges; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGES_RESPONSE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__challenges_response__descriptor) \ + , (char *)protobuf_c_empty_string, 0,NULL } + + +struct Spotify__Clienttoken__Http__V0__ClientSecretParameters +{ + ProtobufCMessage base; + char *salt; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_SECRET_PARAMETERS__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__client_secret_parameters__descriptor) \ + , (char *)protobuf_c_empty_string } + + +struct Spotify__Clienttoken__Http__V0__EvaluateJSParameters +{ + ProtobufCMessage base; + char *code; + size_t n_libraries; + char **libraries; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__EVALUATE_JSPARAMETERS__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__evaluate_jsparameters__descriptor) \ + , (char *)protobuf_c_empty_string, 0,NULL } + + +struct Spotify__Clienttoken__Http__V0__HashCashParameters +{ + ProtobufCMessage base; + int32_t length; + char *prefix; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__HASH_CASH_PARAMETERS__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__hash_cash_parameters__descriptor) \ + , 0, (char *)protobuf_c_empty_string } + + +typedef enum { + SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE__PARAMETERS__NOT_SET = 0, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE__PARAMETERS_CLIENT_SECRET_PARAMETERS = 2, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE__PARAMETERS_EVALUATE_JS_PARAMETERS = 3, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE__PARAMETERS_EVALUATE_HASHCASH_PARAMETERS = 4 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE__PARAMETERS__CASE) +} Spotify__Clienttoken__Http__V0__Challenge__ParametersCase; + +struct Spotify__Clienttoken__Http__V0__Challenge +{ + ProtobufCMessage base; + Spotify__Clienttoken__Http__V0__ChallengeType type; + Spotify__Clienttoken__Http__V0__Challenge__ParametersCase parameters_case; + union { + Spotify__Clienttoken__Http__V0__ClientSecretParameters *client_secret_parameters; + Spotify__Clienttoken__Http__V0__EvaluateJSParameters *evaluate_js_parameters; + Spotify__Clienttoken__Http__V0__HashCashParameters *evaluate_hashcash_parameters; + }; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__challenge__descriptor) \ + , SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_TYPE__CHALLENGE_UNKNOWN, SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE__PARAMETERS__NOT_SET, {0} } + + +struct Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer +{ + ProtobufCMessage base; + char *hmac; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_SECRET_HMACANSWER__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__client_secret_hmacanswer__descriptor) \ + , (char *)protobuf_c_empty_string } + + +struct Spotify__Clienttoken__Http__V0__EvaluateJSAnswer +{ + ProtobufCMessage base; + char *result; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__EVALUATE_JSANSWER__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__evaluate_jsanswer__descriptor) \ + , (char *)protobuf_c_empty_string } + + +struct Spotify__Clienttoken__Http__V0__HashCashAnswer +{ + ProtobufCMessage base; + char *suffix; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__HASH_CASH_ANSWER__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__hash_cash_answer__descriptor) \ + , (char *)protobuf_c_empty_string } + + +typedef enum { + SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_ANSWER__ANSWER__NOT_SET = 0, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_ANSWER__ANSWER_CLIENT_SECRET = 2, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_ANSWER__ANSWER_EVALUATE_JS = 3, + SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_ANSWER__ANSWER_HASH_CASH = 4 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_ANSWER__ANSWER__CASE) +} Spotify__Clienttoken__Http__V0__ChallengeAnswer__AnswerCase; + +struct Spotify__Clienttoken__Http__V0__ChallengeAnswer +{ + ProtobufCMessage base; + Spotify__Clienttoken__Http__V0__ChallengeType challengetype; + Spotify__Clienttoken__Http__V0__ChallengeAnswer__AnswerCase answer_case; + union { + Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer *client_secret; + Spotify__Clienttoken__Http__V0__EvaluateJSAnswer *evaluate_js; + Spotify__Clienttoken__Http__V0__HashCashAnswer *hash_cash; + }; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_ANSWER__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__challenge_answer__descriptor) \ + , SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_TYPE__CHALLENGE_UNKNOWN, SPOTIFY__CLIENTTOKEN__HTTP__V0__CHALLENGE_ANSWER__ANSWER__NOT_SET, {0} } + + +struct Spotify__Clienttoken__Http__V0__ClientTokenBadRequest +{ + ProtobufCMessage base; + char *message; +}; +#define SPOTIFY__CLIENTTOKEN__HTTP__V0__CLIENT_TOKEN_BAD_REQUEST__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__http__v0__client_token_bad_request__descriptor) \ + , (char *)protobuf_c_empty_string } + + +/* Spotify__Clienttoken__Http__V0__ClientTokenRequest methods */ +void spotify__clienttoken__http__v0__client_token_request__init + (Spotify__Clienttoken__Http__V0__ClientTokenRequest *message); +size_t spotify__clienttoken__http__v0__client_token_request__get_packed_size + (const Spotify__Clienttoken__Http__V0__ClientTokenRequest *message); +size_t spotify__clienttoken__http__v0__client_token_request__pack + (const Spotify__Clienttoken__Http__V0__ClientTokenRequest *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__client_token_request__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ClientTokenRequest *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__ClientTokenRequest * + spotify__clienttoken__http__v0__client_token_request__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__client_token_request__free_unpacked + (Spotify__Clienttoken__Http__V0__ClientTokenRequest *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__ClientDataRequest methods */ +void spotify__clienttoken__http__v0__client_data_request__init + (Spotify__Clienttoken__Http__V0__ClientDataRequest *message); +size_t spotify__clienttoken__http__v0__client_data_request__get_packed_size + (const Spotify__Clienttoken__Http__V0__ClientDataRequest *message); +size_t spotify__clienttoken__http__v0__client_data_request__pack + (const Spotify__Clienttoken__Http__V0__ClientDataRequest *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__client_data_request__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ClientDataRequest *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__ClientDataRequest * + spotify__clienttoken__http__v0__client_data_request__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__client_data_request__free_unpacked + (Spotify__Clienttoken__Http__V0__ClientDataRequest *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest methods */ +void spotify__clienttoken__http__v0__challenge_answers_request__init + (Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest *message); +size_t spotify__clienttoken__http__v0__challenge_answers_request__get_packed_size + (const Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest *message); +size_t spotify__clienttoken__http__v0__challenge_answers_request__pack + (const Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__challenge_answers_request__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest * + spotify__clienttoken__http__v0__challenge_answers_request__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__challenge_answers_request__free_unpacked + (Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__ClientTokenResponse methods */ +void spotify__clienttoken__http__v0__client_token_response__init + (Spotify__Clienttoken__Http__V0__ClientTokenResponse *message); +size_t spotify__clienttoken__http__v0__client_token_response__get_packed_size + (const Spotify__Clienttoken__Http__V0__ClientTokenResponse *message); +size_t spotify__clienttoken__http__v0__client_token_response__pack + (const Spotify__Clienttoken__Http__V0__ClientTokenResponse *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__client_token_response__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ClientTokenResponse *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__ClientTokenResponse * + spotify__clienttoken__http__v0__client_token_response__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__client_token_response__free_unpacked + (Spotify__Clienttoken__Http__V0__ClientTokenResponse *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__TokenDomain methods */ +void spotify__clienttoken__http__v0__token_domain__init + (Spotify__Clienttoken__Http__V0__TokenDomain *message); +size_t spotify__clienttoken__http__v0__token_domain__get_packed_size + (const Spotify__Clienttoken__Http__V0__TokenDomain *message); +size_t spotify__clienttoken__http__v0__token_domain__pack + (const Spotify__Clienttoken__Http__V0__TokenDomain *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__token_domain__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__TokenDomain *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__TokenDomain * + spotify__clienttoken__http__v0__token_domain__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__token_domain__free_unpacked + (Spotify__Clienttoken__Http__V0__TokenDomain *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__GrantedTokenResponse methods */ +void spotify__clienttoken__http__v0__granted_token_response__init + (Spotify__Clienttoken__Http__V0__GrantedTokenResponse *message); +size_t spotify__clienttoken__http__v0__granted_token_response__get_packed_size + (const Spotify__Clienttoken__Http__V0__GrantedTokenResponse *message); +size_t spotify__clienttoken__http__v0__granted_token_response__pack + (const Spotify__Clienttoken__Http__V0__GrantedTokenResponse *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__granted_token_response__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__GrantedTokenResponse *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__GrantedTokenResponse * + spotify__clienttoken__http__v0__granted_token_response__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__granted_token_response__free_unpacked + (Spotify__Clienttoken__Http__V0__GrantedTokenResponse *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__ChallengesResponse methods */ +void spotify__clienttoken__http__v0__challenges_response__init + (Spotify__Clienttoken__Http__V0__ChallengesResponse *message); +size_t spotify__clienttoken__http__v0__challenges_response__get_packed_size + (const Spotify__Clienttoken__Http__V0__ChallengesResponse *message); +size_t spotify__clienttoken__http__v0__challenges_response__pack + (const Spotify__Clienttoken__Http__V0__ChallengesResponse *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__challenges_response__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ChallengesResponse *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__ChallengesResponse * + spotify__clienttoken__http__v0__challenges_response__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__challenges_response__free_unpacked + (Spotify__Clienttoken__Http__V0__ChallengesResponse *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__ClientSecretParameters methods */ +void spotify__clienttoken__http__v0__client_secret_parameters__init + (Spotify__Clienttoken__Http__V0__ClientSecretParameters *message); +size_t spotify__clienttoken__http__v0__client_secret_parameters__get_packed_size + (const Spotify__Clienttoken__Http__V0__ClientSecretParameters *message); +size_t spotify__clienttoken__http__v0__client_secret_parameters__pack + (const Spotify__Clienttoken__Http__V0__ClientSecretParameters *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__client_secret_parameters__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ClientSecretParameters *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__ClientSecretParameters * + spotify__clienttoken__http__v0__client_secret_parameters__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__client_secret_parameters__free_unpacked + (Spotify__Clienttoken__Http__V0__ClientSecretParameters *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__EvaluateJSParameters methods */ +void spotify__clienttoken__http__v0__evaluate_jsparameters__init + (Spotify__Clienttoken__Http__V0__EvaluateJSParameters *message); +size_t spotify__clienttoken__http__v0__evaluate_jsparameters__get_packed_size + (const Spotify__Clienttoken__Http__V0__EvaluateJSParameters *message); +size_t spotify__clienttoken__http__v0__evaluate_jsparameters__pack + (const Spotify__Clienttoken__Http__V0__EvaluateJSParameters *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__evaluate_jsparameters__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__EvaluateJSParameters *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__EvaluateJSParameters * + spotify__clienttoken__http__v0__evaluate_jsparameters__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__evaluate_jsparameters__free_unpacked + (Spotify__Clienttoken__Http__V0__EvaluateJSParameters *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__HashCashParameters methods */ +void spotify__clienttoken__http__v0__hash_cash_parameters__init + (Spotify__Clienttoken__Http__V0__HashCashParameters *message); +size_t spotify__clienttoken__http__v0__hash_cash_parameters__get_packed_size + (const Spotify__Clienttoken__Http__V0__HashCashParameters *message); +size_t spotify__clienttoken__http__v0__hash_cash_parameters__pack + (const Spotify__Clienttoken__Http__V0__HashCashParameters *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__hash_cash_parameters__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__HashCashParameters *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__HashCashParameters * + spotify__clienttoken__http__v0__hash_cash_parameters__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__hash_cash_parameters__free_unpacked + (Spotify__Clienttoken__Http__V0__HashCashParameters *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__Challenge methods */ +void spotify__clienttoken__http__v0__challenge__init + (Spotify__Clienttoken__Http__V0__Challenge *message); +size_t spotify__clienttoken__http__v0__challenge__get_packed_size + (const Spotify__Clienttoken__Http__V0__Challenge *message); +size_t spotify__clienttoken__http__v0__challenge__pack + (const Spotify__Clienttoken__Http__V0__Challenge *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__challenge__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__Challenge *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__Challenge * + spotify__clienttoken__http__v0__challenge__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__challenge__free_unpacked + (Spotify__Clienttoken__Http__V0__Challenge *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer methods */ +void spotify__clienttoken__http__v0__client_secret_hmacanswer__init + (Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer *message); +size_t spotify__clienttoken__http__v0__client_secret_hmacanswer__get_packed_size + (const Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer *message); +size_t spotify__clienttoken__http__v0__client_secret_hmacanswer__pack + (const Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__client_secret_hmacanswer__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer * + spotify__clienttoken__http__v0__client_secret_hmacanswer__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__client_secret_hmacanswer__free_unpacked + (Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__EvaluateJSAnswer methods */ +void spotify__clienttoken__http__v0__evaluate_jsanswer__init + (Spotify__Clienttoken__Http__V0__EvaluateJSAnswer *message); +size_t spotify__clienttoken__http__v0__evaluate_jsanswer__get_packed_size + (const Spotify__Clienttoken__Http__V0__EvaluateJSAnswer *message); +size_t spotify__clienttoken__http__v0__evaluate_jsanswer__pack + (const Spotify__Clienttoken__Http__V0__EvaluateJSAnswer *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__evaluate_jsanswer__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__EvaluateJSAnswer *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__EvaluateJSAnswer * + spotify__clienttoken__http__v0__evaluate_jsanswer__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__evaluate_jsanswer__free_unpacked + (Spotify__Clienttoken__Http__V0__EvaluateJSAnswer *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__HashCashAnswer methods */ +void spotify__clienttoken__http__v0__hash_cash_answer__init + (Spotify__Clienttoken__Http__V0__HashCashAnswer *message); +size_t spotify__clienttoken__http__v0__hash_cash_answer__get_packed_size + (const Spotify__Clienttoken__Http__V0__HashCashAnswer *message); +size_t spotify__clienttoken__http__v0__hash_cash_answer__pack + (const Spotify__Clienttoken__Http__V0__HashCashAnswer *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__hash_cash_answer__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__HashCashAnswer *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__HashCashAnswer * + spotify__clienttoken__http__v0__hash_cash_answer__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__hash_cash_answer__free_unpacked + (Spotify__Clienttoken__Http__V0__HashCashAnswer *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__ChallengeAnswer methods */ +void spotify__clienttoken__http__v0__challenge_answer__init + (Spotify__Clienttoken__Http__V0__ChallengeAnswer *message); +size_t spotify__clienttoken__http__v0__challenge_answer__get_packed_size + (const Spotify__Clienttoken__Http__V0__ChallengeAnswer *message); +size_t spotify__clienttoken__http__v0__challenge_answer__pack + (const Spotify__Clienttoken__Http__V0__ChallengeAnswer *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__challenge_answer__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ChallengeAnswer *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__ChallengeAnswer * + spotify__clienttoken__http__v0__challenge_answer__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__challenge_answer__free_unpacked + (Spotify__Clienttoken__Http__V0__ChallengeAnswer *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Http__V0__ClientTokenBadRequest methods */ +void spotify__clienttoken__http__v0__client_token_bad_request__init + (Spotify__Clienttoken__Http__V0__ClientTokenBadRequest *message); +size_t spotify__clienttoken__http__v0__client_token_bad_request__get_packed_size + (const Spotify__Clienttoken__Http__V0__ClientTokenBadRequest *message); +size_t spotify__clienttoken__http__v0__client_token_bad_request__pack + (const Spotify__Clienttoken__Http__V0__ClientTokenBadRequest *message, + uint8_t *out); +size_t spotify__clienttoken__http__v0__client_token_bad_request__pack_to_buffer + (const Spotify__Clienttoken__Http__V0__ClientTokenBadRequest *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Http__V0__ClientTokenBadRequest * + spotify__clienttoken__http__v0__client_token_bad_request__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__http__v0__client_token_bad_request__free_unpacked + (Spotify__Clienttoken__Http__V0__ClientTokenBadRequest *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Spotify__Clienttoken__Http__V0__ClientTokenRequest_Closure) + (const Spotify__Clienttoken__Http__V0__ClientTokenRequest *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__ClientDataRequest_Closure) + (const Spotify__Clienttoken__Http__V0__ClientDataRequest *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest_Closure) + (const Spotify__Clienttoken__Http__V0__ChallengeAnswersRequest *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__ClientTokenResponse_Closure) + (const Spotify__Clienttoken__Http__V0__ClientTokenResponse *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__TokenDomain_Closure) + (const Spotify__Clienttoken__Http__V0__TokenDomain *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__GrantedTokenResponse_Closure) + (const Spotify__Clienttoken__Http__V0__GrantedTokenResponse *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__ChallengesResponse_Closure) + (const Spotify__Clienttoken__Http__V0__ChallengesResponse *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__ClientSecretParameters_Closure) + (const Spotify__Clienttoken__Http__V0__ClientSecretParameters *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__EvaluateJSParameters_Closure) + (const Spotify__Clienttoken__Http__V0__EvaluateJSParameters *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__HashCashParameters_Closure) + (const Spotify__Clienttoken__Http__V0__HashCashParameters *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__Challenge_Closure) + (const Spotify__Clienttoken__Http__V0__Challenge *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer_Closure) + (const Spotify__Clienttoken__Http__V0__ClientSecretHMACAnswer *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__EvaluateJSAnswer_Closure) + (const Spotify__Clienttoken__Http__V0__EvaluateJSAnswer *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__HashCashAnswer_Closure) + (const Spotify__Clienttoken__Http__V0__HashCashAnswer *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__ChallengeAnswer_Closure) + (const Spotify__Clienttoken__Http__V0__ChallengeAnswer *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Http__V0__ClientTokenBadRequest_Closure) + (const Spotify__Clienttoken__Http__V0__ClientTokenBadRequest *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCEnumDescriptor spotify__clienttoken__http__v0__client_token_request_type__descriptor; +extern const ProtobufCEnumDescriptor spotify__clienttoken__http__v0__client_token_response_type__descriptor; +extern const ProtobufCEnumDescriptor spotify__clienttoken__http__v0__challenge_type__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__client_token_request__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__client_data_request__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__challenge_answers_request__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__client_token_response__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__token_domain__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__granted_token_response__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__challenges_response__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__client_secret_parameters__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__evaluate_jsparameters__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__hash_cash_parameters__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__challenge__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__client_secret_hmacanswer__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__evaluate_jsanswer__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__hash_cash_answer__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__challenge_answer__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__http__v0__client_token_bad_request__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_clienttoken_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/clienttoken.proto b/src/inputs/librespot-c/src/proto/clienttoken.proto new file mode 100644 index 00000000..4b261a09 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/clienttoken.proto @@ -0,0 +1,122 @@ +syntax = "proto3"; + +package spotify.clienttoken.http.v0; + +import "connectivity.proto"; + +message ClientTokenRequest { + ClientTokenRequestType request_type = 1; + + oneof request { + ClientDataRequest client_data = 2; + ChallengeAnswersRequest challenge_answers = 3; + } +} + +message ClientDataRequest { + string client_version = 1; + string client_id = 2; + + oneof data { + spotify.clienttoken.data.v0.ConnectivitySdkData connectivity_sdk_data = 3; + } +} + +message ChallengeAnswersRequest { + string state = 1; + repeated ChallengeAnswer answers = 2; +} + +message ClientTokenResponse { + ClientTokenResponseType response_type = 1; + + oneof response { + GrantedTokenResponse granted_token = 2; + ChallengesResponse challenges = 3; + } +} + +message TokenDomain { + string domain = 1; +} + +message GrantedTokenResponse { + string token = 1; + int32 expires_after_seconds = 2; + int32 refresh_after_seconds = 3; + repeated TokenDomain domains = 4; +} + +message ChallengesResponse { + string state = 1; + repeated Challenge challenges = 2; +} + +message ClientSecretParameters { + string salt = 1; +} + +message EvaluateJSParameters { + string code = 1; + repeated string libraries = 2; +} + +message HashCashParameters { + int32 length = 1; + string prefix = 2; +} + +message Challenge { + ChallengeType type = 1; + + oneof parameters { + ClientSecretParameters client_secret_parameters = 2; + EvaluateJSParameters evaluate_js_parameters = 3; + HashCashParameters evaluate_hashcash_parameters = 4; + } +} + +message ClientSecretHMACAnswer { + string hmac = 1; +} + +message EvaluateJSAnswer { + string result = 1; +} + +message HashCashAnswer { + string suffix = 1; +} + +message ChallengeAnswer { + ChallengeType ChallengeType = 1; + + oneof answer { + ClientSecretHMACAnswer client_secret = 2; + EvaluateJSAnswer evaluate_js = 3; + HashCashAnswer hash_cash = 4; + } +} + +message ClientTokenBadRequest { + string message = 1; +} + +enum ClientTokenRequestType { + REQUEST_UNKNOWN = 0; + REQUEST_CLIENT_DATA_REQUEST = 1; + REQUEST_CHALLENGE_ANSWERS_REQUEST = 2; +} + +enum ClientTokenResponseType { + RESPONSE_UNKNOWN = 0; + RESPONSE_GRANTED_TOKEN_RESPONSE = 1; + RESPONSE_CHALLENGES_RESPONSE = 2; +} + +enum ChallengeType { + CHALLENGE_UNKNOWN = 0; + CHALLENGE_CLIENT_SECRET_HMAC = 1; + CHALLENGE_EVALUATE_JS = 2; + CHALLENGE_HASH_CASH = 3; +} diff --git a/src/inputs/librespot-c/src/proto/connectivity.pb-c.c b/src/inputs/librespot-c/src/proto/connectivity.pb-c.c new file mode 100644 index 00000000..2aa9a257 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/connectivity.pb-c.c @@ -0,0 +1,1091 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: connectivity.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "connectivity.pb-c.h" +void spotify__clienttoken__data__v0__connectivity_sdk_data__init + (Spotify__Clienttoken__Data__V0__ConnectivitySdkData *message) +{ + static const Spotify__Clienttoken__Data__V0__ConnectivitySdkData init_value = SPOTIFY__CLIENTTOKEN__DATA__V0__CONNECTIVITY_SDK_DATA__INIT; + *message = init_value; +} +size_t spotify__clienttoken__data__v0__connectivity_sdk_data__get_packed_size + (const Spotify__Clienttoken__Data__V0__ConnectivitySdkData *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__connectivity_sdk_data__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__data__v0__connectivity_sdk_data__pack + (const Spotify__Clienttoken__Data__V0__ConnectivitySdkData *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__connectivity_sdk_data__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__data__v0__connectivity_sdk_data__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__ConnectivitySdkData *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__connectivity_sdk_data__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Data__V0__ConnectivitySdkData * + spotify__clienttoken__data__v0__connectivity_sdk_data__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Data__V0__ConnectivitySdkData *) + protobuf_c_message_unpack (&spotify__clienttoken__data__v0__connectivity_sdk_data__descriptor, + allocator, len, data); +} +void spotify__clienttoken__data__v0__connectivity_sdk_data__free_unpacked + (Spotify__Clienttoken__Data__V0__ConnectivitySdkData *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__data__v0__connectivity_sdk_data__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__data__v0__platform_specific_data__init + (Spotify__Clienttoken__Data__V0__PlatformSpecificData *message) +{ + static const Spotify__Clienttoken__Data__V0__PlatformSpecificData init_value = SPOTIFY__CLIENTTOKEN__DATA__V0__PLATFORM_SPECIFIC_DATA__INIT; + *message = init_value; +} +size_t spotify__clienttoken__data__v0__platform_specific_data__get_packed_size + (const Spotify__Clienttoken__Data__V0__PlatformSpecificData *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__platform_specific_data__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__data__v0__platform_specific_data__pack + (const Spotify__Clienttoken__Data__V0__PlatformSpecificData *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__platform_specific_data__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__data__v0__platform_specific_data__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__PlatformSpecificData *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__platform_specific_data__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Data__V0__PlatformSpecificData * + spotify__clienttoken__data__v0__platform_specific_data__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Data__V0__PlatformSpecificData *) + protobuf_c_message_unpack (&spotify__clienttoken__data__v0__platform_specific_data__descriptor, + allocator, len, data); +} +void spotify__clienttoken__data__v0__platform_specific_data__free_unpacked + (Spotify__Clienttoken__Data__V0__PlatformSpecificData *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__data__v0__platform_specific_data__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__data__v0__native_android_data__init + (Spotify__Clienttoken__Data__V0__NativeAndroidData *message) +{ + static const Spotify__Clienttoken__Data__V0__NativeAndroidData init_value = SPOTIFY__CLIENTTOKEN__DATA__V0__NATIVE_ANDROID_DATA__INIT; + *message = init_value; +} +size_t spotify__clienttoken__data__v0__native_android_data__get_packed_size + (const Spotify__Clienttoken__Data__V0__NativeAndroidData *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_android_data__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__data__v0__native_android_data__pack + (const Spotify__Clienttoken__Data__V0__NativeAndroidData *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_android_data__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__data__v0__native_android_data__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__NativeAndroidData *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_android_data__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Data__V0__NativeAndroidData * + spotify__clienttoken__data__v0__native_android_data__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Data__V0__NativeAndroidData *) + protobuf_c_message_unpack (&spotify__clienttoken__data__v0__native_android_data__descriptor, + allocator, len, data); +} +void spotify__clienttoken__data__v0__native_android_data__free_unpacked + (Spotify__Clienttoken__Data__V0__NativeAndroidData *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_android_data__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__data__v0__native_iosdata__init + (Spotify__Clienttoken__Data__V0__NativeIOSData *message) +{ + static const Spotify__Clienttoken__Data__V0__NativeIOSData init_value = SPOTIFY__CLIENTTOKEN__DATA__V0__NATIVE_IOSDATA__INIT; + *message = init_value; +} +size_t spotify__clienttoken__data__v0__native_iosdata__get_packed_size + (const Spotify__Clienttoken__Data__V0__NativeIOSData *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_iosdata__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__data__v0__native_iosdata__pack + (const Spotify__Clienttoken__Data__V0__NativeIOSData *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_iosdata__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__data__v0__native_iosdata__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__NativeIOSData *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_iosdata__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Data__V0__NativeIOSData * + spotify__clienttoken__data__v0__native_iosdata__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Data__V0__NativeIOSData *) + protobuf_c_message_unpack (&spotify__clienttoken__data__v0__native_iosdata__descriptor, + allocator, len, data); +} +void spotify__clienttoken__data__v0__native_iosdata__free_unpacked + (Spotify__Clienttoken__Data__V0__NativeIOSData *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_iosdata__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__data__v0__native_desktop_windows_data__init + (Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData *message) +{ + static const Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData init_value = SPOTIFY__CLIENTTOKEN__DATA__V0__NATIVE_DESKTOP_WINDOWS_DATA__INIT; + *message = init_value; +} +size_t spotify__clienttoken__data__v0__native_desktop_windows_data__get_packed_size + (const Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_desktop_windows_data__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__data__v0__native_desktop_windows_data__pack + (const Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_desktop_windows_data__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__data__v0__native_desktop_windows_data__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_desktop_windows_data__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData * + spotify__clienttoken__data__v0__native_desktop_windows_data__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData *) + protobuf_c_message_unpack (&spotify__clienttoken__data__v0__native_desktop_windows_data__descriptor, + allocator, len, data); +} +void spotify__clienttoken__data__v0__native_desktop_windows_data__free_unpacked + (Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_desktop_windows_data__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__data__v0__native_desktop_linux_data__init + (Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData *message) +{ + static const Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData init_value = SPOTIFY__CLIENTTOKEN__DATA__V0__NATIVE_DESKTOP_LINUX_DATA__INIT; + *message = init_value; +} +size_t spotify__clienttoken__data__v0__native_desktop_linux_data__get_packed_size + (const Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_desktop_linux_data__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__data__v0__native_desktop_linux_data__pack + (const Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_desktop_linux_data__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__data__v0__native_desktop_linux_data__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_desktop_linux_data__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData * + spotify__clienttoken__data__v0__native_desktop_linux_data__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData *) + protobuf_c_message_unpack (&spotify__clienttoken__data__v0__native_desktop_linux_data__descriptor, + allocator, len, data); +} +void spotify__clienttoken__data__v0__native_desktop_linux_data__free_unpacked + (Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_desktop_linux_data__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__data__v0__native_desktop_mac_osdata__init + (Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData *message) +{ + static const Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData init_value = SPOTIFY__CLIENTTOKEN__DATA__V0__NATIVE_DESKTOP_MAC_OSDATA__INIT; + *message = init_value; +} +size_t spotify__clienttoken__data__v0__native_desktop_mac_osdata__get_packed_size + (const Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_desktop_mac_osdata__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__data__v0__native_desktop_mac_osdata__pack + (const Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_desktop_mac_osdata__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__data__v0__native_desktop_mac_osdata__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_desktop_mac_osdata__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData * + spotify__clienttoken__data__v0__native_desktop_mac_osdata__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData *) + protobuf_c_message_unpack (&spotify__clienttoken__data__v0__native_desktop_mac_osdata__descriptor, + allocator, len, data); +} +void spotify__clienttoken__data__v0__native_desktop_mac_osdata__free_unpacked + (Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__data__v0__native_desktop_mac_osdata__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__clienttoken__data__v0__screen__init + (Spotify__Clienttoken__Data__V0__Screen *message) +{ + static const Spotify__Clienttoken__Data__V0__Screen init_value = SPOTIFY__CLIENTTOKEN__DATA__V0__SCREEN__INIT; + *message = init_value; +} +size_t spotify__clienttoken__data__v0__screen__get_packed_size + (const Spotify__Clienttoken__Data__V0__Screen *message) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__screen__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__clienttoken__data__v0__screen__pack + (const Spotify__Clienttoken__Data__V0__Screen *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__screen__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__clienttoken__data__v0__screen__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__Screen *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__clienttoken__data__v0__screen__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Clienttoken__Data__V0__Screen * + spotify__clienttoken__data__v0__screen__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Clienttoken__Data__V0__Screen *) + protobuf_c_message_unpack (&spotify__clienttoken__data__v0__screen__descriptor, + allocator, len, data); +} +void spotify__clienttoken__data__v0__screen__free_unpacked + (Spotify__Clienttoken__Data__V0__Screen *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__clienttoken__data__v0__screen__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCFieldDescriptor spotify__clienttoken__data__v0__connectivity_sdk_data__field_descriptors[2] = +{ + { + "platform_specific_data", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__ConnectivitySdkData, platform_specific_data), + &spotify__clienttoken__data__v0__platform_specific_data__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "device_id", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__ConnectivitySdkData, device_id), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__data__v0__connectivity_sdk_data__field_indices_by_name[] = { + 1, /* field[1] = device_id */ + 0, /* field[0] = platform_specific_data */ +}; +static const ProtobufCIntRange spotify__clienttoken__data__v0__connectivity_sdk_data__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__connectivity_sdk_data__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.data.v0.ConnectivitySdkData", + "ConnectivitySdkData", + "Spotify__Clienttoken__Data__V0__ConnectivitySdkData", + "spotify.clienttoken.data.v0", + sizeof(Spotify__Clienttoken__Data__V0__ConnectivitySdkData), + 2, + spotify__clienttoken__data__v0__connectivity_sdk_data__field_descriptors, + spotify__clienttoken__data__v0__connectivity_sdk_data__field_indices_by_name, + 1, spotify__clienttoken__data__v0__connectivity_sdk_data__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__data__v0__connectivity_sdk_data__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__data__v0__platform_specific_data__field_descriptors[5] = +{ + { + "android", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Data__V0__PlatformSpecificData, data_case), + offsetof(Spotify__Clienttoken__Data__V0__PlatformSpecificData, android), + &spotify__clienttoken__data__v0__native_android_data__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "ios", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Data__V0__PlatformSpecificData, data_case), + offsetof(Spotify__Clienttoken__Data__V0__PlatformSpecificData, ios), + &spotify__clienttoken__data__v0__native_iosdata__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "desktop_macos", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Data__V0__PlatformSpecificData, data_case), + offsetof(Spotify__Clienttoken__Data__V0__PlatformSpecificData, desktop_macos), + &spotify__clienttoken__data__v0__native_desktop_mac_osdata__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "desktop_windows", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Data__V0__PlatformSpecificData, data_case), + offsetof(Spotify__Clienttoken__Data__V0__PlatformSpecificData, desktop_windows), + &spotify__clienttoken__data__v0__native_desktop_windows_data__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "desktop_linux", + 5, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Clienttoken__Data__V0__PlatformSpecificData, data_case), + offsetof(Spotify__Clienttoken__Data__V0__PlatformSpecificData, desktop_linux), + &spotify__clienttoken__data__v0__native_desktop_linux_data__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__data__v0__platform_specific_data__field_indices_by_name[] = { + 0, /* field[0] = android */ + 4, /* field[4] = desktop_linux */ + 2, /* field[2] = desktop_macos */ + 3, /* field[3] = desktop_windows */ + 1, /* field[1] = ios */ +}; +static const ProtobufCIntRange spotify__clienttoken__data__v0__platform_specific_data__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 5 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__platform_specific_data__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.data.v0.PlatformSpecificData", + "PlatformSpecificData", + "Spotify__Clienttoken__Data__V0__PlatformSpecificData", + "spotify.clienttoken.data.v0", + sizeof(Spotify__Clienttoken__Data__V0__PlatformSpecificData), + 5, + spotify__clienttoken__data__v0__platform_specific_data__field_descriptors, + spotify__clienttoken__data__v0__platform_specific_data__field_indices_by_name, + 1, spotify__clienttoken__data__v0__platform_specific_data__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__data__v0__platform_specific_data__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__data__v0__native_android_data__field_descriptors[8] = +{ + { + "screen_dimensions", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeAndroidData, screen_dimensions), + &spotify__clienttoken__data__v0__screen__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "android_version", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeAndroidData, android_version), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "api_version", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeAndroidData, api_version), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "device_name", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeAndroidData, device_name), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "model_str", + 5, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeAndroidData, model_str), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "vendor", + 6, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeAndroidData, vendor), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "vendor_2", + 7, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeAndroidData, vendor_2), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "unknown_value_8", + 8, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeAndroidData, unknown_value_8), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__data__v0__native_android_data__field_indices_by_name[] = { + 1, /* field[1] = android_version */ + 2, /* field[2] = api_version */ + 3, /* field[3] = device_name */ + 4, /* field[4] = model_str */ + 0, /* field[0] = screen_dimensions */ + 7, /* field[7] = unknown_value_8 */ + 5, /* field[5] = vendor */ + 6, /* field[6] = vendor_2 */ +}; +static const ProtobufCIntRange spotify__clienttoken__data__v0__native_android_data__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 8 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__native_android_data__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.data.v0.NativeAndroidData", + "NativeAndroidData", + "Spotify__Clienttoken__Data__V0__NativeAndroidData", + "spotify.clienttoken.data.v0", + sizeof(Spotify__Clienttoken__Data__V0__NativeAndroidData), + 8, + spotify__clienttoken__data__v0__native_android_data__field_descriptors, + spotify__clienttoken__data__v0__native_android_data__field_indices_by_name, + 1, spotify__clienttoken__data__v0__native_android_data__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__data__v0__native_android_data__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__data__v0__native_iosdata__field_descriptors[5] = +{ + { + "user_interface_idiom", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeIOSData, user_interface_idiom), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "target_iphone_simulator", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BOOL, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeIOSData, target_iphone_simulator), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "hw_machine", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeIOSData, hw_machine), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "system_version", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeIOSData, system_version), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "simulator_model_identifier", + 5, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeIOSData, simulator_model_identifier), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__data__v0__native_iosdata__field_indices_by_name[] = { + 2, /* field[2] = hw_machine */ + 4, /* field[4] = simulator_model_identifier */ + 3, /* field[3] = system_version */ + 1, /* field[1] = target_iphone_simulator */ + 0, /* field[0] = user_interface_idiom */ +}; +static const ProtobufCIntRange spotify__clienttoken__data__v0__native_iosdata__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 5 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__native_iosdata__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.data.v0.NativeIOSData", + "NativeIOSData", + "Spotify__Clienttoken__Data__V0__NativeIOSData", + "spotify.clienttoken.data.v0", + sizeof(Spotify__Clienttoken__Data__V0__NativeIOSData), + 5, + spotify__clienttoken__data__v0__native_iosdata__field_descriptors, + spotify__clienttoken__data__v0__native_iosdata__field_indices_by_name, + 1, spotify__clienttoken__data__v0__native_iosdata__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__data__v0__native_iosdata__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__data__v0__native_desktop_windows_data__field_descriptors[8] = +{ + { + "os_version", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData, os_version), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "os_build", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData, os_build), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "platform_id", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData, platform_id), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "unknown_value_5", + 5, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData, unknown_value_5), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "unknown_value_6", + 6, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData, unknown_value_6), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "image_file_machine", + 7, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData, image_file_machine), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "pe_machine", + 8, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData, pe_machine), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "unknown_value_10", + 10, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BOOL, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData, unknown_value_10), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__data__v0__native_desktop_windows_data__field_indices_by_name[] = { + 5, /* field[5] = image_file_machine */ + 1, /* field[1] = os_build */ + 0, /* field[0] = os_version */ + 6, /* field[6] = pe_machine */ + 2, /* field[2] = platform_id */ + 7, /* field[7] = unknown_value_10 */ + 3, /* field[3] = unknown_value_5 */ + 4, /* field[4] = unknown_value_6 */ +}; +static const ProtobufCIntRange spotify__clienttoken__data__v0__native_desktop_windows_data__number_ranges[3 + 1] = +{ + { 1, 0 }, + { 3, 1 }, + { 10, 7 }, + { 0, 8 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__native_desktop_windows_data__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.data.v0.NativeDesktopWindowsData", + "NativeDesktopWindowsData", + "Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData", + "spotify.clienttoken.data.v0", + sizeof(Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData), + 8, + spotify__clienttoken__data__v0__native_desktop_windows_data__field_descriptors, + spotify__clienttoken__data__v0__native_desktop_windows_data__field_indices_by_name, + 3, spotify__clienttoken__data__v0__native_desktop_windows_data__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__data__v0__native_desktop_windows_data__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__data__v0__native_desktop_linux_data__field_descriptors[4] = +{ + { + "system_name", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData, system_name), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "system_release", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData, system_release), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "system_version", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData, system_version), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "hardware", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData, hardware), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__data__v0__native_desktop_linux_data__field_indices_by_name[] = { + 3, /* field[3] = hardware */ + 0, /* field[0] = system_name */ + 1, /* field[1] = system_release */ + 2, /* field[2] = system_version */ +}; +static const ProtobufCIntRange spotify__clienttoken__data__v0__native_desktop_linux_data__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 4 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__native_desktop_linux_data__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.data.v0.NativeDesktopLinuxData", + "NativeDesktopLinuxData", + "Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData", + "spotify.clienttoken.data.v0", + sizeof(Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData), + 4, + spotify__clienttoken__data__v0__native_desktop_linux_data__field_descriptors, + spotify__clienttoken__data__v0__native_desktop_linux_data__field_indices_by_name, + 1, spotify__clienttoken__data__v0__native_desktop_linux_data__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__data__v0__native_desktop_linux_data__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__data__v0__native_desktop_mac_osdata__field_descriptors[3] = +{ + { + "system_version", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData, system_version), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "hw_model", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData, hw_model), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "compiled_cpu_type", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData, compiled_cpu_type), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__data__v0__native_desktop_mac_osdata__field_indices_by_name[] = { + 2, /* field[2] = compiled_cpu_type */ + 1, /* field[1] = hw_model */ + 0, /* field[0] = system_version */ +}; +static const ProtobufCIntRange spotify__clienttoken__data__v0__native_desktop_mac_osdata__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 3 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__native_desktop_mac_osdata__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.data.v0.NativeDesktopMacOSData", + "NativeDesktopMacOSData", + "Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData", + "spotify.clienttoken.data.v0", + sizeof(Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData), + 3, + spotify__clienttoken__data__v0__native_desktop_mac_osdata__field_descriptors, + spotify__clienttoken__data__v0__native_desktop_mac_osdata__field_indices_by_name, + 1, spotify__clienttoken__data__v0__native_desktop_mac_osdata__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__data__v0__native_desktop_mac_osdata__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__clienttoken__data__v0__screen__field_descriptors[5] = +{ + { + "width", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__Screen, width), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "height", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__Screen, height), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "density", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__Screen, density), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "unknown_value_4", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__Screen, unknown_value_4), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "unknown_value_5", + 5, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Clienttoken__Data__V0__Screen, unknown_value_5), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__clienttoken__data__v0__screen__field_indices_by_name[] = { + 2, /* field[2] = density */ + 1, /* field[1] = height */ + 3, /* field[3] = unknown_value_4 */ + 4, /* field[4] = unknown_value_5 */ + 0, /* field[0] = width */ +}; +static const ProtobufCIntRange spotify__clienttoken__data__v0__screen__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 5 } +}; +const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__screen__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.clienttoken.data.v0.Screen", + "Screen", + "Spotify__Clienttoken__Data__V0__Screen", + "spotify.clienttoken.data.v0", + sizeof(Spotify__Clienttoken__Data__V0__Screen), + 5, + spotify__clienttoken__data__v0__screen__field_descriptors, + spotify__clienttoken__data__v0__screen__field_indices_by_name, + 1, spotify__clienttoken__data__v0__screen__number_ranges, + (ProtobufCMessageInit) spotify__clienttoken__data__v0__screen__init, + NULL,NULL,NULL /* reserved[123] */ +}; diff --git a/src/inputs/librespot-c/src/proto/connectivity.pb-c.h b/src/inputs/librespot-c/src/proto/connectivity.pb-c.h new file mode 100644 index 00000000..1eaad39f --- /dev/null +++ b/src/inputs/librespot-c/src/proto/connectivity.pb-c.h @@ -0,0 +1,378 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: connectivity.proto */ + +#ifndef PROTOBUF_C_connectivity_2eproto__INCLUDED +#define PROTOBUF_C_connectivity_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# 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 1004001 < 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 Spotify__Clienttoken__Data__V0__ConnectivitySdkData Spotify__Clienttoken__Data__V0__ConnectivitySdkData; +typedef struct Spotify__Clienttoken__Data__V0__PlatformSpecificData Spotify__Clienttoken__Data__V0__PlatformSpecificData; +typedef struct Spotify__Clienttoken__Data__V0__NativeAndroidData Spotify__Clienttoken__Data__V0__NativeAndroidData; +typedef struct Spotify__Clienttoken__Data__V0__NativeIOSData Spotify__Clienttoken__Data__V0__NativeIOSData; +typedef struct Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData; +typedef struct Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData; +typedef struct Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData; +typedef struct Spotify__Clienttoken__Data__V0__Screen Spotify__Clienttoken__Data__V0__Screen; + + +/* --- enums --- */ + + +/* --- messages --- */ + +struct Spotify__Clienttoken__Data__V0__ConnectivitySdkData +{ + ProtobufCMessage base; + Spotify__Clienttoken__Data__V0__PlatformSpecificData *platform_specific_data; + char *device_id; +}; +#define SPOTIFY__CLIENTTOKEN__DATA__V0__CONNECTIVITY_SDK_DATA__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__data__v0__connectivity_sdk_data__descriptor) \ + , NULL, (char *)protobuf_c_empty_string } + + +typedef enum { + SPOTIFY__CLIENTTOKEN__DATA__V0__PLATFORM_SPECIFIC_DATA__DATA__NOT_SET = 0, + SPOTIFY__CLIENTTOKEN__DATA__V0__PLATFORM_SPECIFIC_DATA__DATA_ANDROID = 1, + SPOTIFY__CLIENTTOKEN__DATA__V0__PLATFORM_SPECIFIC_DATA__DATA_IOS = 2, + SPOTIFY__CLIENTTOKEN__DATA__V0__PLATFORM_SPECIFIC_DATA__DATA_DESKTOP_MACOS = 3, + SPOTIFY__CLIENTTOKEN__DATA__V0__PLATFORM_SPECIFIC_DATA__DATA_DESKTOP_WINDOWS = 4, + SPOTIFY__CLIENTTOKEN__DATA__V0__PLATFORM_SPECIFIC_DATA__DATA_DESKTOP_LINUX = 5 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__CLIENTTOKEN__DATA__V0__PLATFORM_SPECIFIC_DATA__DATA__CASE) +} Spotify__Clienttoken__Data__V0__PlatformSpecificData__DataCase; + +struct Spotify__Clienttoken__Data__V0__PlatformSpecificData +{ + ProtobufCMessage base; + Spotify__Clienttoken__Data__V0__PlatformSpecificData__DataCase data_case; + union { + Spotify__Clienttoken__Data__V0__NativeAndroidData *android; + Spotify__Clienttoken__Data__V0__NativeIOSData *ios; + Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData *desktop_macos; + Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData *desktop_windows; + Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData *desktop_linux; + }; +}; +#define SPOTIFY__CLIENTTOKEN__DATA__V0__PLATFORM_SPECIFIC_DATA__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__data__v0__platform_specific_data__descriptor) \ + , SPOTIFY__CLIENTTOKEN__DATA__V0__PLATFORM_SPECIFIC_DATA__DATA__NOT_SET, {0} } + + +struct Spotify__Clienttoken__Data__V0__NativeAndroidData +{ + ProtobufCMessage base; + Spotify__Clienttoken__Data__V0__Screen *screen_dimensions; + char *android_version; + int32_t api_version; + char *device_name; + char *model_str; + char *vendor; + char *vendor_2; + int32_t unknown_value_8; +}; +#define SPOTIFY__CLIENTTOKEN__DATA__V0__NATIVE_ANDROID_DATA__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__data__v0__native_android_data__descriptor) \ + , NULL, (char *)protobuf_c_empty_string, 0, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, 0 } + + +struct Spotify__Clienttoken__Data__V0__NativeIOSData +{ + ProtobufCMessage base; + /* + * https://developer.apple.com/documentation/uikit/uiuserinterfaceidiom + */ + int32_t user_interface_idiom; + protobuf_c_boolean target_iphone_simulator; + char *hw_machine; + char *system_version; + char *simulator_model_identifier; +}; +#define SPOTIFY__CLIENTTOKEN__DATA__V0__NATIVE_IOSDATA__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__data__v0__native_iosdata__descriptor) \ + , 0, 0, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string } + + +struct Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData +{ + ProtobufCMessage base; + int32_t os_version; + int32_t os_build; + /* + * https://docs.microsoft.com/en-us/dotnet/api/system.platformid?view=net-6.0 + */ + int32_t platform_id; + int32_t unknown_value_5; + int32_t unknown_value_6; + /* + * https://docs.microsoft.com/en-us/dotnet/api/system.reflection.imagefilemachine?view=net-6.0 + */ + int32_t image_file_machine; + /* + * https://docs.microsoft.com/en-us/dotnet/api/system.reflection.portableexecutable.machine?view=net-6.0 + */ + int32_t pe_machine; + protobuf_c_boolean unknown_value_10; +}; +#define SPOTIFY__CLIENTTOKEN__DATA__V0__NATIVE_DESKTOP_WINDOWS_DATA__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__data__v0__native_desktop_windows_data__descriptor) \ + , 0, 0, 0, 0, 0, 0, 0, 0 } + + +struct Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData +{ + ProtobufCMessage base; + /* + * uname -s + */ + char *system_name; + /* + * -r + */ + char *system_release; + /* + * -v + */ + char *system_version; + /* + * -i + */ + char *hardware; +}; +#define SPOTIFY__CLIENTTOKEN__DATA__V0__NATIVE_DESKTOP_LINUX_DATA__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__data__v0__native_desktop_linux_data__descriptor) \ + , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string } + + +struct Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData +{ + ProtobufCMessage base; + char *system_version; + char *hw_model; + char *compiled_cpu_type; +}; +#define SPOTIFY__CLIENTTOKEN__DATA__V0__NATIVE_DESKTOP_MAC_OSDATA__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__data__v0__native_desktop_mac_osdata__descriptor) \ + , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string } + + +struct Spotify__Clienttoken__Data__V0__Screen +{ + ProtobufCMessage base; + int32_t width; + int32_t height; + int32_t density; + int32_t unknown_value_4; + int32_t unknown_value_5; +}; +#define SPOTIFY__CLIENTTOKEN__DATA__V0__SCREEN__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__clienttoken__data__v0__screen__descriptor) \ + , 0, 0, 0, 0, 0 } + + +/* Spotify__Clienttoken__Data__V0__ConnectivitySdkData methods */ +void spotify__clienttoken__data__v0__connectivity_sdk_data__init + (Spotify__Clienttoken__Data__V0__ConnectivitySdkData *message); +size_t spotify__clienttoken__data__v0__connectivity_sdk_data__get_packed_size + (const Spotify__Clienttoken__Data__V0__ConnectivitySdkData *message); +size_t spotify__clienttoken__data__v0__connectivity_sdk_data__pack + (const Spotify__Clienttoken__Data__V0__ConnectivitySdkData *message, + uint8_t *out); +size_t spotify__clienttoken__data__v0__connectivity_sdk_data__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__ConnectivitySdkData *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Data__V0__ConnectivitySdkData * + spotify__clienttoken__data__v0__connectivity_sdk_data__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__data__v0__connectivity_sdk_data__free_unpacked + (Spotify__Clienttoken__Data__V0__ConnectivitySdkData *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Data__V0__PlatformSpecificData methods */ +void spotify__clienttoken__data__v0__platform_specific_data__init + (Spotify__Clienttoken__Data__V0__PlatformSpecificData *message); +size_t spotify__clienttoken__data__v0__platform_specific_data__get_packed_size + (const Spotify__Clienttoken__Data__V0__PlatformSpecificData *message); +size_t spotify__clienttoken__data__v0__platform_specific_data__pack + (const Spotify__Clienttoken__Data__V0__PlatformSpecificData *message, + uint8_t *out); +size_t spotify__clienttoken__data__v0__platform_specific_data__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__PlatformSpecificData *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Data__V0__PlatformSpecificData * + spotify__clienttoken__data__v0__platform_specific_data__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__data__v0__platform_specific_data__free_unpacked + (Spotify__Clienttoken__Data__V0__PlatformSpecificData *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Data__V0__NativeAndroidData methods */ +void spotify__clienttoken__data__v0__native_android_data__init + (Spotify__Clienttoken__Data__V0__NativeAndroidData *message); +size_t spotify__clienttoken__data__v0__native_android_data__get_packed_size + (const Spotify__Clienttoken__Data__V0__NativeAndroidData *message); +size_t spotify__clienttoken__data__v0__native_android_data__pack + (const Spotify__Clienttoken__Data__V0__NativeAndroidData *message, + uint8_t *out); +size_t spotify__clienttoken__data__v0__native_android_data__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__NativeAndroidData *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Data__V0__NativeAndroidData * + spotify__clienttoken__data__v0__native_android_data__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__data__v0__native_android_data__free_unpacked + (Spotify__Clienttoken__Data__V0__NativeAndroidData *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Data__V0__NativeIOSData methods */ +void spotify__clienttoken__data__v0__native_iosdata__init + (Spotify__Clienttoken__Data__V0__NativeIOSData *message); +size_t spotify__clienttoken__data__v0__native_iosdata__get_packed_size + (const Spotify__Clienttoken__Data__V0__NativeIOSData *message); +size_t spotify__clienttoken__data__v0__native_iosdata__pack + (const Spotify__Clienttoken__Data__V0__NativeIOSData *message, + uint8_t *out); +size_t spotify__clienttoken__data__v0__native_iosdata__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__NativeIOSData *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Data__V0__NativeIOSData * + spotify__clienttoken__data__v0__native_iosdata__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__data__v0__native_iosdata__free_unpacked + (Spotify__Clienttoken__Data__V0__NativeIOSData *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData methods */ +void spotify__clienttoken__data__v0__native_desktop_windows_data__init + (Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData *message); +size_t spotify__clienttoken__data__v0__native_desktop_windows_data__get_packed_size + (const Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData *message); +size_t spotify__clienttoken__data__v0__native_desktop_windows_data__pack + (const Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData *message, + uint8_t *out); +size_t spotify__clienttoken__data__v0__native_desktop_windows_data__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData * + spotify__clienttoken__data__v0__native_desktop_windows_data__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__data__v0__native_desktop_windows_data__free_unpacked + (Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData methods */ +void spotify__clienttoken__data__v0__native_desktop_linux_data__init + (Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData *message); +size_t spotify__clienttoken__data__v0__native_desktop_linux_data__get_packed_size + (const Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData *message); +size_t spotify__clienttoken__data__v0__native_desktop_linux_data__pack + (const Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData *message, + uint8_t *out); +size_t spotify__clienttoken__data__v0__native_desktop_linux_data__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData * + spotify__clienttoken__data__v0__native_desktop_linux_data__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__data__v0__native_desktop_linux_data__free_unpacked + (Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData methods */ +void spotify__clienttoken__data__v0__native_desktop_mac_osdata__init + (Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData *message); +size_t spotify__clienttoken__data__v0__native_desktop_mac_osdata__get_packed_size + (const Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData *message); +size_t spotify__clienttoken__data__v0__native_desktop_mac_osdata__pack + (const Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData *message, + uint8_t *out); +size_t spotify__clienttoken__data__v0__native_desktop_mac_osdata__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData * + spotify__clienttoken__data__v0__native_desktop_mac_osdata__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__data__v0__native_desktop_mac_osdata__free_unpacked + (Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData *message, + ProtobufCAllocator *allocator); +/* Spotify__Clienttoken__Data__V0__Screen methods */ +void spotify__clienttoken__data__v0__screen__init + (Spotify__Clienttoken__Data__V0__Screen *message); +size_t spotify__clienttoken__data__v0__screen__get_packed_size + (const Spotify__Clienttoken__Data__V0__Screen *message); +size_t spotify__clienttoken__data__v0__screen__pack + (const Spotify__Clienttoken__Data__V0__Screen *message, + uint8_t *out); +size_t spotify__clienttoken__data__v0__screen__pack_to_buffer + (const Spotify__Clienttoken__Data__V0__Screen *message, + ProtobufCBuffer *buffer); +Spotify__Clienttoken__Data__V0__Screen * + spotify__clienttoken__data__v0__screen__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__clienttoken__data__v0__screen__free_unpacked + (Spotify__Clienttoken__Data__V0__Screen *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Spotify__Clienttoken__Data__V0__ConnectivitySdkData_Closure) + (const Spotify__Clienttoken__Data__V0__ConnectivitySdkData *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Data__V0__PlatformSpecificData_Closure) + (const Spotify__Clienttoken__Data__V0__PlatformSpecificData *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Data__V0__NativeAndroidData_Closure) + (const Spotify__Clienttoken__Data__V0__NativeAndroidData *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Data__V0__NativeIOSData_Closure) + (const Spotify__Clienttoken__Data__V0__NativeIOSData *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData_Closure) + (const Spotify__Clienttoken__Data__V0__NativeDesktopWindowsData *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData_Closure) + (const Spotify__Clienttoken__Data__V0__NativeDesktopLinuxData *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData_Closure) + (const Spotify__Clienttoken__Data__V0__NativeDesktopMacOSData *message, + void *closure_data); +typedef void (*Spotify__Clienttoken__Data__V0__Screen_Closure) + (const Spotify__Clienttoken__Data__V0__Screen *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__connectivity_sdk_data__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__platform_specific_data__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__native_android_data__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__native_iosdata__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__native_desktop_windows_data__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__native_desktop_linux_data__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__native_desktop_mac_osdata__descriptor; +extern const ProtobufCMessageDescriptor spotify__clienttoken__data__v0__screen__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_connectivity_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/connectivity.proto b/src/inputs/librespot-c/src/proto/connectivity.proto new file mode 100644 index 00000000..48494a0d --- /dev/null +++ b/src/inputs/librespot-c/src/proto/connectivity.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; + +package spotify.clienttoken.data.v0; + +message ConnectivitySdkData { + PlatformSpecificData platform_specific_data = 1; + string device_id = 2; +} + +message PlatformSpecificData { + oneof data { + NativeAndroidData android = 1; + NativeIOSData ios = 2; + NativeDesktopMacOSData desktop_macos = 3; + NativeDesktopWindowsData desktop_windows = 4; + NativeDesktopLinuxData desktop_linux = 5; + } +} + +message NativeAndroidData { + Screen screen_dimensions = 1; + string android_version = 2; + int32 api_version = 3; + string device_name = 4; + string model_str = 5; + string vendor = 6; + string vendor_2 = 7; + int32 unknown_value_8 = 8; +} + +message NativeIOSData { + // https://developer.apple.com/documentation/uikit/uiuserinterfaceidiom + int32 user_interface_idiom = 1; + bool target_iphone_simulator = 2; + string hw_machine = 3; + string system_version = 4; + string simulator_model_identifier = 5; +} + +message NativeDesktopWindowsData { + int32 os_version = 1; + int32 os_build = 3; + // https://docs.microsoft.com/en-us/dotnet/api/system.platformid?view=net-6.0 + int32 platform_id = 4; + int32 unknown_value_5 = 5; + int32 unknown_value_6 = 6; + // https://docs.microsoft.com/en-us/dotnet/api/system.reflection.imagefilemachine?view=net-6.0 + int32 image_file_machine = 7; + // https://docs.microsoft.com/en-us/dotnet/api/system.reflection.portableexecutable.machine?view=net-6.0 + int32 pe_machine = 8; + bool unknown_value_10 = 10; +} + +message NativeDesktopLinuxData { + string system_name = 1; // uname -s + string system_release = 2; // -r + string system_version = 3; // -v + string hardware = 4; // -i +} + +message NativeDesktopMacOSData { + string system_version = 1; + string hw_model = 2; + string compiled_cpu_type = 3; +} + +message Screen { + int32 width = 1; + int32 height = 2; + int32 density = 3; + int32 unknown_value_4 = 4; + int32 unknown_value_5 = 5; +} diff --git a/src/inputs/librespot-c/src/proto/facebook-publish.proto b/src/inputs/librespot-c/src/proto/facebook-publish.proto deleted file mode 100644 index 4edef249..00000000 --- a/src/inputs/librespot-c/src/proto/facebook-publish.proto +++ /dev/null @@ -1,51 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/facebook.proto b/src/inputs/librespot-c/src/proto/facebook.proto deleted file mode 100644 index 8227c5a1..00000000 --- a/src/inputs/librespot-c/src/proto/facebook.proto +++ /dev/null @@ -1,183 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/google_duration.pb-c.c b/src/inputs/librespot-c/src/proto/google_duration.pb-c.c new file mode 100644 index 00000000..893b434e --- /dev/null +++ b/src/inputs/librespot-c/src/proto/google_duration.pb-c.c @@ -0,0 +1,105 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: google_duration.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "google_duration.pb-c.h" +void google__protobuf__duration__init + (Google__Protobuf__Duration *message) +{ + static const Google__Protobuf__Duration init_value = GOOGLE__PROTOBUF__DURATION__INIT; + *message = init_value; +} +size_t google__protobuf__duration__get_packed_size + (const Google__Protobuf__Duration *message) +{ + assert(message->base.descriptor == &google__protobuf__duration__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t google__protobuf__duration__pack + (const Google__Protobuf__Duration *message, + uint8_t *out) +{ + assert(message->base.descriptor == &google__protobuf__duration__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t google__protobuf__duration__pack_to_buffer + (const Google__Protobuf__Duration *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &google__protobuf__duration__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Google__Protobuf__Duration * + google__protobuf__duration__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Google__Protobuf__Duration *) + protobuf_c_message_unpack (&google__protobuf__duration__descriptor, + allocator, len, data); +} +void google__protobuf__duration__free_unpacked + (Google__Protobuf__Duration *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &google__protobuf__duration__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCFieldDescriptor google__protobuf__duration__field_descriptors[2] = +{ + { + "seconds", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT64, + 0, /* quantifier_offset */ + offsetof(Google__Protobuf__Duration, seconds), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "nanos", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Google__Protobuf__Duration, nanos), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned google__protobuf__duration__field_indices_by_name[] = { + 1, /* field[1] = nanos */ + 0, /* field[0] = seconds */ +}; +static const ProtobufCIntRange google__protobuf__duration__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor google__protobuf__duration__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "google.protobuf.Duration", + "Duration", + "Google__Protobuf__Duration", + "google.protobuf", + sizeof(Google__Protobuf__Duration), + 2, + google__protobuf__duration__field_descriptors, + google__protobuf__duration__field_indices_by_name, + 1, google__protobuf__duration__number_ranges, + (ProtobufCMessageInit) google__protobuf__duration__init, + NULL,NULL,NULL /* reserved[123] */ +}; diff --git a/src/inputs/librespot-c/src/proto/google_duration.pb-c.h b/src/inputs/librespot-c/src/proto/google_duration.pb-c.h new file mode 100644 index 00000000..14600ba7 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/google_duration.pb-c.h @@ -0,0 +1,72 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: google_duration.proto */ + +#ifndef PROTOBUF_C_google_5fduration_2eproto__INCLUDED +#define PROTOBUF_C_google_5fduration_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# 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 1004001 < 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 Google__Protobuf__Duration Google__Protobuf__Duration; + + +/* --- enums --- */ + + +/* --- messages --- */ + +struct Google__Protobuf__Duration +{ + ProtobufCMessage base; + int64_t seconds; + int32_t nanos; +}; +#define GOOGLE__PROTOBUF__DURATION__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&google__protobuf__duration__descriptor) \ + , 0, 0 } + + +/* Google__Protobuf__Duration methods */ +void google__protobuf__duration__init + (Google__Protobuf__Duration *message); +size_t google__protobuf__duration__get_packed_size + (const Google__Protobuf__Duration *message); +size_t google__protobuf__duration__pack + (const Google__Protobuf__Duration *message, + uint8_t *out); +size_t google__protobuf__duration__pack_to_buffer + (const Google__Protobuf__Duration *message, + ProtobufCBuffer *buffer); +Google__Protobuf__Duration * + google__protobuf__duration__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void google__protobuf__duration__free_unpacked + (Google__Protobuf__Duration *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Google__Protobuf__Duration_Closure) + (const Google__Protobuf__Duration *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCMessageDescriptor google__protobuf__duration__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_google_5fduration_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/google_duration.proto b/src/inputs/librespot-c/src/proto/google_duration.proto new file mode 100644 index 00000000..39c7907b --- /dev/null +++ b/src/inputs/librespot-c/src/proto/google_duration.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +package google.protobuf; + +message Duration { + int64 seconds = 1; + int32 nanos = 2; +} diff --git a/src/inputs/librespot-c/src/proto/login5.pb-c.c b/src/inputs/librespot-c/src/proto/login5.pb-c.c new file mode 100644 index 00000000..17065cde --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5.pb-c.c @@ -0,0 +1,947 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: login5.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "login5.pb-c.h" +void spotify__login5__v3__challenges__init + (Spotify__Login5__V3__Challenges *message) +{ + static const Spotify__Login5__V3__Challenges init_value = SPOTIFY__LOGIN5__V3__CHALLENGES__INIT; + *message = init_value; +} +size_t spotify__login5__v3__challenges__get_packed_size + (const Spotify__Login5__V3__Challenges *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__challenges__pack + (const Spotify__Login5__V3__Challenges *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__challenges__pack_to_buffer + (const Spotify__Login5__V3__Challenges *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Challenges * + spotify__login5__v3__challenges__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Challenges *) + protobuf_c_message_unpack (&spotify__login5__v3__challenges__descriptor, + allocator, len, data); +} +void spotify__login5__v3__challenges__free_unpacked + (Spotify__Login5__V3__Challenges *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__challenges__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__challenge__init + (Spotify__Login5__V3__Challenge *message) +{ + static const Spotify__Login5__V3__Challenge init_value = SPOTIFY__LOGIN5__V3__CHALLENGE__INIT; + *message = init_value; +} +size_t spotify__login5__v3__challenge__get_packed_size + (const Spotify__Login5__V3__Challenge *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenge__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__challenge__pack + (const Spotify__Login5__V3__Challenge *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenge__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__challenge__pack_to_buffer + (const Spotify__Login5__V3__Challenge *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenge__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Challenge * + spotify__login5__v3__challenge__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Challenge *) + protobuf_c_message_unpack (&spotify__login5__v3__challenge__descriptor, + allocator, len, data); +} +void spotify__login5__v3__challenge__free_unpacked + (Spotify__Login5__V3__Challenge *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__challenge__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__challenge_solutions__init + (Spotify__Login5__V3__ChallengeSolutions *message) +{ + static const Spotify__Login5__V3__ChallengeSolutions init_value = SPOTIFY__LOGIN5__V3__CHALLENGE_SOLUTIONS__INIT; + *message = init_value; +} +size_t spotify__login5__v3__challenge_solutions__get_packed_size + (const Spotify__Login5__V3__ChallengeSolutions *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenge_solutions__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__challenge_solutions__pack + (const Spotify__Login5__V3__ChallengeSolutions *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenge_solutions__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__challenge_solutions__pack_to_buffer + (const Spotify__Login5__V3__ChallengeSolutions *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenge_solutions__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__ChallengeSolutions * + spotify__login5__v3__challenge_solutions__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__ChallengeSolutions *) + protobuf_c_message_unpack (&spotify__login5__v3__challenge_solutions__descriptor, + allocator, len, data); +} +void spotify__login5__v3__challenge_solutions__free_unpacked + (Spotify__Login5__V3__ChallengeSolutions *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__challenge_solutions__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__challenge_solution__init + (Spotify__Login5__V3__ChallengeSolution *message) +{ + static const Spotify__Login5__V3__ChallengeSolution init_value = SPOTIFY__LOGIN5__V3__CHALLENGE_SOLUTION__INIT; + *message = init_value; +} +size_t spotify__login5__v3__challenge_solution__get_packed_size + (const Spotify__Login5__V3__ChallengeSolution *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenge_solution__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__challenge_solution__pack + (const Spotify__Login5__V3__ChallengeSolution *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenge_solution__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__challenge_solution__pack_to_buffer + (const Spotify__Login5__V3__ChallengeSolution *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenge_solution__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__ChallengeSolution * + spotify__login5__v3__challenge_solution__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__ChallengeSolution *) + protobuf_c_message_unpack (&spotify__login5__v3__challenge_solution__descriptor, + allocator, len, data); +} +void spotify__login5__v3__challenge_solution__free_unpacked + (Spotify__Login5__V3__ChallengeSolution *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__challenge_solution__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__login_request__init + (Spotify__Login5__V3__LoginRequest *message) +{ + static const Spotify__Login5__V3__LoginRequest init_value = SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__INIT; + *message = init_value; +} +size_t spotify__login5__v3__login_request__get_packed_size + (const Spotify__Login5__V3__LoginRequest *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__login_request__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__login_request__pack + (const Spotify__Login5__V3__LoginRequest *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__login_request__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__login_request__pack_to_buffer + (const Spotify__Login5__V3__LoginRequest *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__login_request__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__LoginRequest * + spotify__login5__v3__login_request__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__LoginRequest *) + protobuf_c_message_unpack (&spotify__login5__v3__login_request__descriptor, + allocator, len, data); +} +void spotify__login5__v3__login_request__free_unpacked + (Spotify__Login5__V3__LoginRequest *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__login_request__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__login_ok__init + (Spotify__Login5__V3__LoginOk *message) +{ + static const Spotify__Login5__V3__LoginOk init_value = SPOTIFY__LOGIN5__V3__LOGIN_OK__INIT; + *message = init_value; +} +size_t spotify__login5__v3__login_ok__get_packed_size + (const Spotify__Login5__V3__LoginOk *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__login_ok__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__login_ok__pack + (const Spotify__Login5__V3__LoginOk *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__login_ok__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__login_ok__pack_to_buffer + (const Spotify__Login5__V3__LoginOk *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__login_ok__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__LoginOk * + spotify__login5__v3__login_ok__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__LoginOk *) + protobuf_c_message_unpack (&spotify__login5__v3__login_ok__descriptor, + allocator, len, data); +} +void spotify__login5__v3__login_ok__free_unpacked + (Spotify__Login5__V3__LoginOk *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__login_ok__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__login_response__init + (Spotify__Login5__V3__LoginResponse *message) +{ + static const Spotify__Login5__V3__LoginResponse init_value = SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__INIT; + *message = init_value; +} +size_t spotify__login5__v3__login_response__get_packed_size + (const Spotify__Login5__V3__LoginResponse *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__login_response__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__login_response__pack + (const Spotify__Login5__V3__LoginResponse *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__login_response__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__login_response__pack_to_buffer + (const Spotify__Login5__V3__LoginResponse *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__login_response__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__LoginResponse * + spotify__login5__v3__login_response__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__LoginResponse *) + protobuf_c_message_unpack (&spotify__login5__v3__login_response__descriptor, + allocator, len, data); +} +void spotify__login5__v3__login_response__free_unpacked + (Spotify__Login5__V3__LoginResponse *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__login_response__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCFieldDescriptor spotify__login5__v3__challenges__field_descriptors[1] = +{ + { + "challenges", + 1, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__Challenges, n_challenges), + offsetof(Spotify__Login5__V3__Challenges, challenges), + &spotify__login5__v3__challenge__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__challenges__field_indices_by_name[] = { + 0, /* field[0] = challenges */ +}; +static const ProtobufCIntRange spotify__login5__v3__challenges__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 1 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__challenges__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.Challenges", + "Challenges", + "Spotify__Login5__V3__Challenges", + "spotify.login5.v3", + sizeof(Spotify__Login5__V3__Challenges), + 1, + spotify__login5__v3__challenges__field_descriptors, + spotify__login5__v3__challenges__field_indices_by_name, + 1, spotify__login5__v3__challenges__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__challenges__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__challenge__field_descriptors[2] = +{ + { + "hashcash", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__Challenge, challenge_case), + offsetof(Spotify__Login5__V3__Challenge, hashcash), + &spotify__login5__v3__challenges__hashcash_challenge__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "code", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__Challenge, challenge_case), + offsetof(Spotify__Login5__V3__Challenge, code), + &spotify__login5__v3__challenges__code_challenge__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__challenge__field_indices_by_name[] = { + 1, /* field[1] = code */ + 0, /* field[0] = hashcash */ +}; +static const ProtobufCIntRange spotify__login5__v3__challenge__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__challenge__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.Challenge", + "Challenge", + "Spotify__Login5__V3__Challenge", + "spotify.login5.v3", + sizeof(Spotify__Login5__V3__Challenge), + 2, + spotify__login5__v3__challenge__field_descriptors, + spotify__login5__v3__challenge__field_indices_by_name, + 1, spotify__login5__v3__challenge__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__challenge__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__challenge_solutions__field_descriptors[1] = +{ + { + "solutions", + 1, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__ChallengeSolutions, n_solutions), + offsetof(Spotify__Login5__V3__ChallengeSolutions, solutions), + &spotify__login5__v3__challenge_solution__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__challenge_solutions__field_indices_by_name[] = { + 0, /* field[0] = solutions */ +}; +static const ProtobufCIntRange spotify__login5__v3__challenge_solutions__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 1 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__challenge_solutions__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.ChallengeSolutions", + "ChallengeSolutions", + "Spotify__Login5__V3__ChallengeSolutions", + "spotify.login5.v3", + sizeof(Spotify__Login5__V3__ChallengeSolutions), + 1, + spotify__login5__v3__challenge_solutions__field_descriptors, + spotify__login5__v3__challenge_solutions__field_indices_by_name, + 1, spotify__login5__v3__challenge_solutions__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__challenge_solutions__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__challenge_solution__field_descriptors[2] = +{ + { + "hashcash", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__ChallengeSolution, solution_case), + offsetof(Spotify__Login5__V3__ChallengeSolution, hashcash), + &spotify__login5__v3__challenges__hashcash_solution__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "code", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__ChallengeSolution, solution_case), + offsetof(Spotify__Login5__V3__ChallengeSolution, code), + &spotify__login5__v3__challenges__code_solution__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__challenge_solution__field_indices_by_name[] = { + 1, /* field[1] = code */ + 0, /* field[0] = hashcash */ +}; +static const ProtobufCIntRange spotify__login5__v3__challenge_solution__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__challenge_solution__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.ChallengeSolution", + "ChallengeSolution", + "Spotify__Login5__V3__ChallengeSolution", + "spotify.login5.v3", + sizeof(Spotify__Login5__V3__ChallengeSolution), + 2, + spotify__login5__v3__challenge_solution__field_descriptors, + spotify__login5__v3__challenge_solution__field_indices_by_name, + 1, spotify__login5__v3__challenge_solution__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__challenge_solution__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__login_request__field_descriptors[12] = +{ + { + "client_info", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__LoginRequest, client_info), + &spotify__login5__v3__client_info__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "login_context", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__LoginRequest, login_context), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "challenge_solutions", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__LoginRequest, challenge_solutions), + &spotify__login5__v3__challenge_solutions__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "stored_credential", + 100, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__LoginRequest, login_method_case), + offsetof(Spotify__Login5__V3__LoginRequest, stored_credential), + &spotify__login5__v3__credentials__stored_credential__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "password", + 101, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__LoginRequest, login_method_case), + offsetof(Spotify__Login5__V3__LoginRequest, password), + &spotify__login5__v3__credentials__password__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "facebook_access_token", + 102, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__LoginRequest, login_method_case), + offsetof(Spotify__Login5__V3__LoginRequest, facebook_access_token), + &spotify__login5__v3__credentials__facebook_access_token__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "phone_number", + 103, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__LoginRequest, login_method_case), + offsetof(Spotify__Login5__V3__LoginRequest, phone_number), + &spotify__login5__v3__identifiers__phone_number__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "one_time_token", + 104, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__LoginRequest, login_method_case), + offsetof(Spotify__Login5__V3__LoginRequest, one_time_token), + &spotify__login5__v3__credentials__one_time_token__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "parent_child_credential", + 105, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__LoginRequest, login_method_case), + offsetof(Spotify__Login5__V3__LoginRequest, parent_child_credential), + &spotify__login5__v3__credentials__parent_child_credential__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "apple_sign_in_credential", + 106, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__LoginRequest, login_method_case), + offsetof(Spotify__Login5__V3__LoginRequest, apple_sign_in_credential), + &spotify__login5__v3__credentials__apple_sign_in_credential__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "samsung_sign_in_credential", + 107, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__LoginRequest, login_method_case), + offsetof(Spotify__Login5__V3__LoginRequest, samsung_sign_in_credential), + &spotify__login5__v3__credentials__samsung_sign_in_credential__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "google_sign_in_credential", + 108, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__LoginRequest, login_method_case), + offsetof(Spotify__Login5__V3__LoginRequest, google_sign_in_credential), + &spotify__login5__v3__credentials__google_sign_in_credential__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__login_request__field_indices_by_name[] = { + 9, /* field[9] = apple_sign_in_credential */ + 2, /* field[2] = challenge_solutions */ + 0, /* field[0] = client_info */ + 5, /* field[5] = facebook_access_token */ + 11, /* field[11] = google_sign_in_credential */ + 1, /* field[1] = login_context */ + 7, /* field[7] = one_time_token */ + 8, /* field[8] = parent_child_credential */ + 4, /* field[4] = password */ + 6, /* field[6] = phone_number */ + 10, /* field[10] = samsung_sign_in_credential */ + 3, /* field[3] = stored_credential */ +}; +static const ProtobufCIntRange spotify__login5__v3__login_request__number_ranges[2 + 1] = +{ + { 1, 0 }, + { 100, 3 }, + { 0, 12 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__login_request__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.LoginRequest", + "LoginRequest", + "Spotify__Login5__V3__LoginRequest", + "spotify.login5.v3", + sizeof(Spotify__Login5__V3__LoginRequest), + 12, + spotify__login5__v3__login_request__field_descriptors, + spotify__login5__v3__login_request__field_indices_by_name, + 2, spotify__login5__v3__login_request__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__login_request__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__login_ok__field_descriptors[4] = +{ + { + "username", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__LoginOk, username), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "access_token", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__LoginOk, access_token), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "stored_credential", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__LoginOk, stored_credential), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "access_token_expires_in", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__LoginOk, access_token_expires_in), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__login_ok__field_indices_by_name[] = { + 1, /* field[1] = access_token */ + 3, /* field[3] = access_token_expires_in */ + 2, /* field[2] = stored_credential */ + 0, /* field[0] = username */ +}; +static const ProtobufCIntRange spotify__login5__v3__login_ok__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 4 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__login_ok__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.LoginOk", + "LoginOk", + "Spotify__Login5__V3__LoginOk", + "spotify.login5.v3", + sizeof(Spotify__Login5__V3__LoginOk), + 4, + spotify__login5__v3__login_ok__field_descriptors, + spotify__login5__v3__login_ok__field_indices_by_name, + 1, spotify__login5__v3__login_ok__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__login_ok__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCEnumValue spotify__login5__v3__login_response__warnings__enum_values_by_number[2] = +{ + { "UNKNOWN_WARNING", "SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__WARNINGS__UNKNOWN_WARNING", 0 }, + { "DEPRECATED_PROTOCOL_VERSION", "SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__WARNINGS__DEPRECATED_PROTOCOL_VERSION", 1 }, +}; +static const ProtobufCIntRange spotify__login5__v3__login_response__warnings__value_ranges[] = { +{0, 0},{0, 2} +}; +static const ProtobufCEnumValueIndex spotify__login5__v3__login_response__warnings__enum_values_by_name[2] = +{ + { "DEPRECATED_PROTOCOL_VERSION", 1 }, + { "UNKNOWN_WARNING", 0 }, +}; +const ProtobufCEnumDescriptor spotify__login5__v3__login_response__warnings__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "spotify.login5.v3.LoginResponse.Warnings", + "Warnings", + "Spotify__Login5__V3__LoginResponse__Warnings", + "spotify.login5.v3", + 2, + spotify__login5__v3__login_response__warnings__enum_values_by_number, + 2, + spotify__login5__v3__login_response__warnings__enum_values_by_name, + 1, + spotify__login5__v3__login_response__warnings__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__login_response__field_descriptors[7] = +{ + { + "ok", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__LoginResponse, response_case), + offsetof(Spotify__Login5__V3__LoginResponse, ok), + &spotify__login5__v3__login_ok__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "error", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + offsetof(Spotify__Login5__V3__LoginResponse, response_case), + offsetof(Spotify__Login5__V3__LoginResponse, error), + &spotify__login5__v3__login_error__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "challenges", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Login5__V3__LoginResponse, response_case), + offsetof(Spotify__Login5__V3__LoginResponse, challenges), + &spotify__login5__v3__challenges__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "warnings", + 4, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_ENUM, + offsetof(Spotify__Login5__V3__LoginResponse, n_warnings), + offsetof(Spotify__Login5__V3__LoginResponse, warnings), + &spotify__login5__v3__login_response__warnings__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_PACKED, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "login_context", + 5, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__LoginResponse, login_context), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "identifier_token", + 6, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__LoginResponse, identifier_token), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "user_info", + 7, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__LoginResponse, user_info), + &spotify__login5__v3__user_info__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__login_response__field_indices_by_name[] = { + 2, /* field[2] = challenges */ + 1, /* field[1] = error */ + 5, /* field[5] = identifier_token */ + 4, /* field[4] = login_context */ + 0, /* field[0] = ok */ + 6, /* field[6] = user_info */ + 3, /* field[3] = warnings */ +}; +static const ProtobufCIntRange spotify__login5__v3__login_response__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 7 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__login_response__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.LoginResponse", + "LoginResponse", + "Spotify__Login5__V3__LoginResponse", + "spotify.login5.v3", + sizeof(Spotify__Login5__V3__LoginResponse), + 7, + spotify__login5__v3__login_response__field_descriptors, + spotify__login5__v3__login_response__field_indices_by_name, + 1, spotify__login5__v3__login_response__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__login_response__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCEnumValue spotify__login5__v3__login_error__enum_values_by_number[9] = +{ + { "UNKNOWN_ERROR", "SPOTIFY__LOGIN5__V3__LOGIN_ERROR__UNKNOWN_ERROR", 0 }, + { "INVALID_CREDENTIALS", "SPOTIFY__LOGIN5__V3__LOGIN_ERROR__INVALID_CREDENTIALS", 1 }, + { "BAD_REQUEST", "SPOTIFY__LOGIN5__V3__LOGIN_ERROR__BAD_REQUEST", 2 }, + { "UNSUPPORTED_LOGIN_PROTOCOL", "SPOTIFY__LOGIN5__V3__LOGIN_ERROR__UNSUPPORTED_LOGIN_PROTOCOL", 3 }, + { "TIMEOUT", "SPOTIFY__LOGIN5__V3__LOGIN_ERROR__TIMEOUT", 4 }, + { "UNKNOWN_IDENTIFIER", "SPOTIFY__LOGIN5__V3__LOGIN_ERROR__UNKNOWN_IDENTIFIER", 5 }, + { "TOO_MANY_ATTEMPTS", "SPOTIFY__LOGIN5__V3__LOGIN_ERROR__TOO_MANY_ATTEMPTS", 6 }, + { "INVALID_PHONENUMBER", "SPOTIFY__LOGIN5__V3__LOGIN_ERROR__INVALID_PHONENUMBER", 7 }, + { "TRY_AGAIN_LATER", "SPOTIFY__LOGIN5__V3__LOGIN_ERROR__TRY_AGAIN_LATER", 8 }, +}; +static const ProtobufCIntRange spotify__login5__v3__login_error__value_ranges[] = { +{0, 0},{0, 9} +}; +static const ProtobufCEnumValueIndex spotify__login5__v3__login_error__enum_values_by_name[9] = +{ + { "BAD_REQUEST", 2 }, + { "INVALID_CREDENTIALS", 1 }, + { "INVALID_PHONENUMBER", 7 }, + { "TIMEOUT", 4 }, + { "TOO_MANY_ATTEMPTS", 6 }, + { "TRY_AGAIN_LATER", 8 }, + { "UNKNOWN_ERROR", 0 }, + { "UNKNOWN_IDENTIFIER", 5 }, + { "UNSUPPORTED_LOGIN_PROTOCOL", 3 }, +}; +const ProtobufCEnumDescriptor spotify__login5__v3__login_error__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "spotify.login5.v3.LoginError", + "LoginError", + "Spotify__Login5__V3__LoginError", + "spotify.login5.v3", + 9, + spotify__login5__v3__login_error__enum_values_by_number, + 9, + spotify__login5__v3__login_error__enum_values_by_name, + 1, + spotify__login5__v3__login_error__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; diff --git a/src/inputs/librespot-c/src/proto/login5.pb-c.h b/src/inputs/librespot-c/src/proto/login5.pb-c.h new file mode 100644 index 00000000..b0a98359 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5.pb-c.h @@ -0,0 +1,373 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: login5.proto */ + +#ifndef PROTOBUF_C_login5_2eproto__INCLUDED +#define PROTOBUF_C_login5_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# 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 1004001 < 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 + +#include "login5_client_info.pb-c.h" +#include "login5_user_info.pb-c.h" +#include "login5_challenges_code.pb-c.h" +#include "login5_challenges_hashcash.pb-c.h" +#include "login5_credentials.pb-c.h" +#include "login5_identifiers.pb-c.h" + +typedef struct Spotify__Login5__V3__Challenges Spotify__Login5__V3__Challenges; +typedef struct Spotify__Login5__V3__Challenge Spotify__Login5__V3__Challenge; +typedef struct Spotify__Login5__V3__ChallengeSolutions Spotify__Login5__V3__ChallengeSolutions; +typedef struct Spotify__Login5__V3__ChallengeSolution Spotify__Login5__V3__ChallengeSolution; +typedef struct Spotify__Login5__V3__LoginRequest Spotify__Login5__V3__LoginRequest; +typedef struct Spotify__Login5__V3__LoginOk Spotify__Login5__V3__LoginOk; +typedef struct Spotify__Login5__V3__LoginResponse Spotify__Login5__V3__LoginResponse; + + +/* --- enums --- */ + +typedef enum _Spotify__Login5__V3__LoginResponse__Warnings { + SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__WARNINGS__UNKNOWN_WARNING = 0, + SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__WARNINGS__DEPRECATED_PROTOCOL_VERSION = 1 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__WARNINGS) +} Spotify__Login5__V3__LoginResponse__Warnings; +typedef enum _Spotify__Login5__V3__LoginError { + SPOTIFY__LOGIN5__V3__LOGIN_ERROR__UNKNOWN_ERROR = 0, + SPOTIFY__LOGIN5__V3__LOGIN_ERROR__INVALID_CREDENTIALS = 1, + SPOTIFY__LOGIN5__V3__LOGIN_ERROR__BAD_REQUEST = 2, + SPOTIFY__LOGIN5__V3__LOGIN_ERROR__UNSUPPORTED_LOGIN_PROTOCOL = 3, + SPOTIFY__LOGIN5__V3__LOGIN_ERROR__TIMEOUT = 4, + SPOTIFY__LOGIN5__V3__LOGIN_ERROR__UNKNOWN_IDENTIFIER = 5, + SPOTIFY__LOGIN5__V3__LOGIN_ERROR__TOO_MANY_ATTEMPTS = 6, + SPOTIFY__LOGIN5__V3__LOGIN_ERROR__INVALID_PHONENUMBER = 7, + SPOTIFY__LOGIN5__V3__LOGIN_ERROR__TRY_AGAIN_LATER = 8 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__LOGIN5__V3__LOGIN_ERROR) +} Spotify__Login5__V3__LoginError; + +/* --- messages --- */ + +struct Spotify__Login5__V3__Challenges +{ + ProtobufCMessage base; + size_t n_challenges; + Spotify__Login5__V3__Challenge **challenges; +}; +#define SPOTIFY__LOGIN5__V3__CHALLENGES__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__challenges__descriptor) \ + , 0,NULL } + + +typedef enum { + SPOTIFY__LOGIN5__V3__CHALLENGE__CHALLENGE__NOT_SET = 0, + SPOTIFY__LOGIN5__V3__CHALLENGE__CHALLENGE_HASHCASH = 1, + SPOTIFY__LOGIN5__V3__CHALLENGE__CHALLENGE_CODE = 2 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__LOGIN5__V3__CHALLENGE__CHALLENGE__CASE) +} Spotify__Login5__V3__Challenge__ChallengeCase; + +struct Spotify__Login5__V3__Challenge +{ + ProtobufCMessage base; + Spotify__Login5__V3__Challenge__ChallengeCase challenge_case; + union { + Spotify__Login5__V3__Challenges__HashcashChallenge *hashcash; + Spotify__Login5__V3__Challenges__CodeChallenge *code; + }; +}; +#define SPOTIFY__LOGIN5__V3__CHALLENGE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__challenge__descriptor) \ + , SPOTIFY__LOGIN5__V3__CHALLENGE__CHALLENGE__NOT_SET, {0} } + + +struct Spotify__Login5__V3__ChallengeSolutions +{ + ProtobufCMessage base; + size_t n_solutions; + Spotify__Login5__V3__ChallengeSolution **solutions; +}; +#define SPOTIFY__LOGIN5__V3__CHALLENGE_SOLUTIONS__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__challenge_solutions__descriptor) \ + , 0,NULL } + + +typedef enum { + SPOTIFY__LOGIN5__V3__CHALLENGE_SOLUTION__SOLUTION__NOT_SET = 0, + SPOTIFY__LOGIN5__V3__CHALLENGE_SOLUTION__SOLUTION_HASHCASH = 1, + SPOTIFY__LOGIN5__V3__CHALLENGE_SOLUTION__SOLUTION_CODE = 2 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__LOGIN5__V3__CHALLENGE_SOLUTION__SOLUTION__CASE) +} Spotify__Login5__V3__ChallengeSolution__SolutionCase; + +struct Spotify__Login5__V3__ChallengeSolution +{ + ProtobufCMessage base; + Spotify__Login5__V3__ChallengeSolution__SolutionCase solution_case; + union { + Spotify__Login5__V3__Challenges__HashcashSolution *hashcash; + Spotify__Login5__V3__Challenges__CodeSolution *code; + }; +}; +#define SPOTIFY__LOGIN5__V3__CHALLENGE_SOLUTION__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__challenge_solution__descriptor) \ + , SPOTIFY__LOGIN5__V3__CHALLENGE_SOLUTION__SOLUTION__NOT_SET, {0} } + + +typedef enum { + SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__LOGIN_METHOD__NOT_SET = 0, + SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__LOGIN_METHOD_STORED_CREDENTIAL = 100, + SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__LOGIN_METHOD_PASSWORD = 101, + SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__LOGIN_METHOD_FACEBOOK_ACCESS_TOKEN = 102, + SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__LOGIN_METHOD_PHONE_NUMBER = 103, + SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__LOGIN_METHOD_ONE_TIME_TOKEN = 104, + SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__LOGIN_METHOD_PARENT_CHILD_CREDENTIAL = 105, + SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__LOGIN_METHOD_APPLE_SIGN_IN_CREDENTIAL = 106, + SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__LOGIN_METHOD_SAMSUNG_SIGN_IN_CREDENTIAL = 107, + SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__LOGIN_METHOD_GOOGLE_SIGN_IN_CREDENTIAL = 108 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__LOGIN_METHOD__CASE) +} Spotify__Login5__V3__LoginRequest__LoginMethodCase; + +struct Spotify__Login5__V3__LoginRequest +{ + ProtobufCMessage base; + Spotify__Login5__V3__ClientInfo *client_info; + ProtobufCBinaryData login_context; + Spotify__Login5__V3__ChallengeSolutions *challenge_solutions; + Spotify__Login5__V3__LoginRequest__LoginMethodCase login_method_case; + union { + Spotify__Login5__V3__Credentials__StoredCredential *stored_credential; + Spotify__Login5__V3__Credentials__Password *password; + Spotify__Login5__V3__Credentials__FacebookAccessToken *facebook_access_token; + Spotify__Login5__V3__Identifiers__PhoneNumber *phone_number; + Spotify__Login5__V3__Credentials__OneTimeToken *one_time_token; + Spotify__Login5__V3__Credentials__ParentChildCredential *parent_child_credential; + Spotify__Login5__V3__Credentials__AppleSignInCredential *apple_sign_in_credential; + Spotify__Login5__V3__Credentials__SamsungSignInCredential *samsung_sign_in_credential; + Spotify__Login5__V3__Credentials__GoogleSignInCredential *google_sign_in_credential; + }; +}; +#define SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__login_request__descriptor) \ + , NULL, {0,NULL}, NULL, SPOTIFY__LOGIN5__V3__LOGIN_REQUEST__LOGIN_METHOD__NOT_SET, {0} } + + +struct Spotify__Login5__V3__LoginOk +{ + ProtobufCMessage base; + char *username; + char *access_token; + ProtobufCBinaryData stored_credential; + int32_t access_token_expires_in; +}; +#define SPOTIFY__LOGIN5__V3__LOGIN_OK__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__login_ok__descriptor) \ + , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, {0,NULL}, 0 } + + +typedef enum { + SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__RESPONSE__NOT_SET = 0, + SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__RESPONSE_OK = 1, + SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__RESPONSE_ERROR = 2, + SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__RESPONSE_CHALLENGES = 3 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__RESPONSE__CASE) +} Spotify__Login5__V3__LoginResponse__ResponseCase; + +struct Spotify__Login5__V3__LoginResponse +{ + ProtobufCMessage base; + size_t n_warnings; + Spotify__Login5__V3__LoginResponse__Warnings *warnings; + ProtobufCBinaryData login_context; + char *identifier_token; + Spotify__Login5__V3__UserInfo *user_info; + Spotify__Login5__V3__LoginResponse__ResponseCase response_case; + union { + Spotify__Login5__V3__LoginOk *ok; + Spotify__Login5__V3__LoginError error; + Spotify__Login5__V3__Challenges *challenges; + }; +}; +#define SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__login_response__descriptor) \ + , 0,NULL, {0,NULL}, (char *)protobuf_c_empty_string, NULL, SPOTIFY__LOGIN5__V3__LOGIN_RESPONSE__RESPONSE__NOT_SET, {0} } + + +/* Spotify__Login5__V3__Challenges methods */ +void spotify__login5__v3__challenges__init + (Spotify__Login5__V3__Challenges *message); +size_t spotify__login5__v3__challenges__get_packed_size + (const Spotify__Login5__V3__Challenges *message); +size_t spotify__login5__v3__challenges__pack + (const Spotify__Login5__V3__Challenges *message, + uint8_t *out); +size_t spotify__login5__v3__challenges__pack_to_buffer + (const Spotify__Login5__V3__Challenges *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Challenges * + spotify__login5__v3__challenges__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__challenges__free_unpacked + (Spotify__Login5__V3__Challenges *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__Challenge methods */ +void spotify__login5__v3__challenge__init + (Spotify__Login5__V3__Challenge *message); +size_t spotify__login5__v3__challenge__get_packed_size + (const Spotify__Login5__V3__Challenge *message); +size_t spotify__login5__v3__challenge__pack + (const Spotify__Login5__V3__Challenge *message, + uint8_t *out); +size_t spotify__login5__v3__challenge__pack_to_buffer + (const Spotify__Login5__V3__Challenge *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Challenge * + spotify__login5__v3__challenge__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__challenge__free_unpacked + (Spotify__Login5__V3__Challenge *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__ChallengeSolutions methods */ +void spotify__login5__v3__challenge_solutions__init + (Spotify__Login5__V3__ChallengeSolutions *message); +size_t spotify__login5__v3__challenge_solutions__get_packed_size + (const Spotify__Login5__V3__ChallengeSolutions *message); +size_t spotify__login5__v3__challenge_solutions__pack + (const Spotify__Login5__V3__ChallengeSolutions *message, + uint8_t *out); +size_t spotify__login5__v3__challenge_solutions__pack_to_buffer + (const Spotify__Login5__V3__ChallengeSolutions *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__ChallengeSolutions * + spotify__login5__v3__challenge_solutions__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__challenge_solutions__free_unpacked + (Spotify__Login5__V3__ChallengeSolutions *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__ChallengeSolution methods */ +void spotify__login5__v3__challenge_solution__init + (Spotify__Login5__V3__ChallengeSolution *message); +size_t spotify__login5__v3__challenge_solution__get_packed_size + (const Spotify__Login5__V3__ChallengeSolution *message); +size_t spotify__login5__v3__challenge_solution__pack + (const Spotify__Login5__V3__ChallengeSolution *message, + uint8_t *out); +size_t spotify__login5__v3__challenge_solution__pack_to_buffer + (const Spotify__Login5__V3__ChallengeSolution *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__ChallengeSolution * + spotify__login5__v3__challenge_solution__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__challenge_solution__free_unpacked + (Spotify__Login5__V3__ChallengeSolution *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__LoginRequest methods */ +void spotify__login5__v3__login_request__init + (Spotify__Login5__V3__LoginRequest *message); +size_t spotify__login5__v3__login_request__get_packed_size + (const Spotify__Login5__V3__LoginRequest *message); +size_t spotify__login5__v3__login_request__pack + (const Spotify__Login5__V3__LoginRequest *message, + uint8_t *out); +size_t spotify__login5__v3__login_request__pack_to_buffer + (const Spotify__Login5__V3__LoginRequest *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__LoginRequest * + spotify__login5__v3__login_request__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__login_request__free_unpacked + (Spotify__Login5__V3__LoginRequest *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__LoginOk methods */ +void spotify__login5__v3__login_ok__init + (Spotify__Login5__V3__LoginOk *message); +size_t spotify__login5__v3__login_ok__get_packed_size + (const Spotify__Login5__V3__LoginOk *message); +size_t spotify__login5__v3__login_ok__pack + (const Spotify__Login5__V3__LoginOk *message, + uint8_t *out); +size_t spotify__login5__v3__login_ok__pack_to_buffer + (const Spotify__Login5__V3__LoginOk *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__LoginOk * + spotify__login5__v3__login_ok__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__login_ok__free_unpacked + (Spotify__Login5__V3__LoginOk *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__LoginResponse methods */ +void spotify__login5__v3__login_response__init + (Spotify__Login5__V3__LoginResponse *message); +size_t spotify__login5__v3__login_response__get_packed_size + (const Spotify__Login5__V3__LoginResponse *message); +size_t spotify__login5__v3__login_response__pack + (const Spotify__Login5__V3__LoginResponse *message, + uint8_t *out); +size_t spotify__login5__v3__login_response__pack_to_buffer + (const Spotify__Login5__V3__LoginResponse *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__LoginResponse * + spotify__login5__v3__login_response__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__login_response__free_unpacked + (Spotify__Login5__V3__LoginResponse *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Spotify__Login5__V3__Challenges_Closure) + (const Spotify__Login5__V3__Challenges *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__Challenge_Closure) + (const Spotify__Login5__V3__Challenge *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__ChallengeSolutions_Closure) + (const Spotify__Login5__V3__ChallengeSolutions *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__ChallengeSolution_Closure) + (const Spotify__Login5__V3__ChallengeSolution *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__LoginRequest_Closure) + (const Spotify__Login5__V3__LoginRequest *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__LoginOk_Closure) + (const Spotify__Login5__V3__LoginOk *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__LoginResponse_Closure) + (const Spotify__Login5__V3__LoginResponse *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCEnumDescriptor spotify__login5__v3__login_error__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__challenges__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__challenge__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__challenge_solutions__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__challenge_solution__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__login_request__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__login_ok__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__login_response__descriptor; +extern const ProtobufCEnumDescriptor spotify__login5__v3__login_response__warnings__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_login5_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/login5.proto b/src/inputs/librespot-c/src/proto/login5.proto new file mode 100644 index 00000000..f2cc95f1 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5.proto @@ -0,0 +1,87 @@ +syntax = "proto3"; + +package spotify.login5.v3; + +import "login5_client_info.proto"; +import "login5_user_info.proto"; +import "login5_challenges_code.proto"; +import "login5_challenges_hashcash.proto"; +import "login5_credentials.proto"; +import "login5_identifiers.proto"; + +message Challenges { + repeated Challenge challenges = 1; +} + +message Challenge { + oneof challenge { + challenges.HashcashChallenge hashcash = 1; + challenges.CodeChallenge code = 2; + } +} + +message ChallengeSolutions { + repeated ChallengeSolution solutions = 1; +} + +message ChallengeSolution { + oneof solution { + challenges.HashcashSolution hashcash = 1; + challenges.CodeSolution code = 2; + } +} + +message LoginRequest { + ClientInfo client_info = 1; + bytes login_context = 2; + ChallengeSolutions challenge_solutions = 3; + + oneof login_method { + credentials.StoredCredential stored_credential = 100; + credentials.Password password = 101; + credentials.FacebookAccessToken facebook_access_token = 102; + identifiers.PhoneNumber phone_number = 103; + credentials.OneTimeToken one_time_token = 104; + credentials.ParentChildCredential parent_child_credential = 105; + credentials.AppleSignInCredential apple_sign_in_credential = 106; + credentials.SamsungSignInCredential samsung_sign_in_credential = 107; + credentials.GoogleSignInCredential google_sign_in_credential = 108; + } +} + +message LoginOk { + string username = 1; + string access_token = 2; + bytes stored_credential = 3; + int32 access_token_expires_in = 4; +} + +message LoginResponse { + repeated Warnings warnings = 4; + enum Warnings { + UNKNOWN_WARNING = 0; + DEPRECATED_PROTOCOL_VERSION = 1; + } + + bytes login_context = 5; + string identifier_token = 6; + UserInfo user_info = 7; + + oneof response { + LoginOk ok = 1; + LoginError error = 2; + Challenges challenges = 3; + } +} + +enum LoginError { + UNKNOWN_ERROR = 0; + INVALID_CREDENTIALS = 1; + BAD_REQUEST = 2; + UNSUPPORTED_LOGIN_PROTOCOL = 3; + TIMEOUT = 4; + UNKNOWN_IDENTIFIER = 5; + TOO_MANY_ATTEMPTS = 6; + INVALID_PHONENUMBER = 7; + TRY_AGAIN_LATER = 8; +} diff --git a/src/inputs/librespot-c/src/proto/login5_challenges_code.pb-c.c b/src/inputs/librespot-c/src/proto/login5_challenges_code.pb-c.c new file mode 100644 index 00000000..429b6d08 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_challenges_code.pb-c.c @@ -0,0 +1,242 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: login5_challenges_code.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "login5_challenges_code.pb-c.h" +void spotify__login5__v3__challenges__code_challenge__init + (Spotify__Login5__V3__Challenges__CodeChallenge *message) +{ + static const Spotify__Login5__V3__Challenges__CodeChallenge init_value = SPOTIFY__LOGIN5__V3__CHALLENGES__CODE_CHALLENGE__INIT; + *message = init_value; +} +size_t spotify__login5__v3__challenges__code_challenge__get_packed_size + (const Spotify__Login5__V3__Challenges__CodeChallenge *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__code_challenge__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__challenges__code_challenge__pack + (const Spotify__Login5__V3__Challenges__CodeChallenge *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__code_challenge__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__challenges__code_challenge__pack_to_buffer + (const Spotify__Login5__V3__Challenges__CodeChallenge *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__code_challenge__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Challenges__CodeChallenge * + spotify__login5__v3__challenges__code_challenge__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Challenges__CodeChallenge *) + protobuf_c_message_unpack (&spotify__login5__v3__challenges__code_challenge__descriptor, + allocator, len, data); +} +void spotify__login5__v3__challenges__code_challenge__free_unpacked + (Spotify__Login5__V3__Challenges__CodeChallenge *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__challenges__code_challenge__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__challenges__code_solution__init + (Spotify__Login5__V3__Challenges__CodeSolution *message) +{ + static const Spotify__Login5__V3__Challenges__CodeSolution init_value = SPOTIFY__LOGIN5__V3__CHALLENGES__CODE_SOLUTION__INIT; + *message = init_value; +} +size_t spotify__login5__v3__challenges__code_solution__get_packed_size + (const Spotify__Login5__V3__Challenges__CodeSolution *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__code_solution__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__challenges__code_solution__pack + (const Spotify__Login5__V3__Challenges__CodeSolution *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__code_solution__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__challenges__code_solution__pack_to_buffer + (const Spotify__Login5__V3__Challenges__CodeSolution *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__code_solution__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Challenges__CodeSolution * + spotify__login5__v3__challenges__code_solution__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Challenges__CodeSolution *) + protobuf_c_message_unpack (&spotify__login5__v3__challenges__code_solution__descriptor, + allocator, len, data); +} +void spotify__login5__v3__challenges__code_solution__free_unpacked + (Spotify__Login5__V3__Challenges__CodeSolution *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__challenges__code_solution__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCEnumValue spotify__login5__v3__challenges__code_challenge__method__enum_values_by_number[2] = +{ + { "UNKNOWN", "SPOTIFY__LOGIN5__V3__CHALLENGES__CODE_CHALLENGE__METHOD__UNKNOWN", 0 }, + { "SMS", "SPOTIFY__LOGIN5__V3__CHALLENGES__CODE_CHALLENGE__METHOD__SMS", 1 }, +}; +static const ProtobufCIntRange spotify__login5__v3__challenges__code_challenge__method__value_ranges[] = { +{0, 0},{0, 2} +}; +static const ProtobufCEnumValueIndex spotify__login5__v3__challenges__code_challenge__method__enum_values_by_name[2] = +{ + { "SMS", 1 }, + { "UNKNOWN", 0 }, +}; +const ProtobufCEnumDescriptor spotify__login5__v3__challenges__code_challenge__method__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "spotify.login5.v3.challenges.CodeChallenge.Method", + "Method", + "Spotify__Login5__V3__Challenges__CodeChallenge__Method", + "spotify.login5.v3.challenges", + 2, + spotify__login5__v3__challenges__code_challenge__method__enum_values_by_number, + 2, + spotify__login5__v3__challenges__code_challenge__method__enum_values_by_name, + 1, + spotify__login5__v3__challenges__code_challenge__method__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__challenges__code_challenge__field_descriptors[4] = +{ + { + "method", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Challenges__CodeChallenge, method), + &spotify__login5__v3__challenges__code_challenge__method__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "code_length", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Challenges__CodeChallenge, code_length), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "expires_in", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Challenges__CodeChallenge, expires_in), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "canonical_phone_number", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Challenges__CodeChallenge, canonical_phone_number), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__challenges__code_challenge__field_indices_by_name[] = { + 3, /* field[3] = canonical_phone_number */ + 1, /* field[1] = code_length */ + 2, /* field[2] = expires_in */ + 0, /* field[0] = method */ +}; +static const ProtobufCIntRange spotify__login5__v3__challenges__code_challenge__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 4 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__challenges__code_challenge__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.challenges.CodeChallenge", + "CodeChallenge", + "Spotify__Login5__V3__Challenges__CodeChallenge", + "spotify.login5.v3.challenges", + sizeof(Spotify__Login5__V3__Challenges__CodeChallenge), + 4, + spotify__login5__v3__challenges__code_challenge__field_descriptors, + spotify__login5__v3__challenges__code_challenge__field_indices_by_name, + 1, spotify__login5__v3__challenges__code_challenge__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__challenges__code_challenge__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__challenges__code_solution__field_descriptors[1] = +{ + { + "code", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Challenges__CodeSolution, code), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__challenges__code_solution__field_indices_by_name[] = { + 0, /* field[0] = code */ +}; +static const ProtobufCIntRange spotify__login5__v3__challenges__code_solution__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 1 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__challenges__code_solution__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.challenges.CodeSolution", + "CodeSolution", + "Spotify__Login5__V3__Challenges__CodeSolution", + "spotify.login5.v3.challenges", + sizeof(Spotify__Login5__V3__Challenges__CodeSolution), + 1, + spotify__login5__v3__challenges__code_solution__field_descriptors, + spotify__login5__v3__challenges__code_solution__field_indices_by_name, + 1, spotify__login5__v3__challenges__code_solution__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__challenges__code_solution__init, + NULL,NULL,NULL /* reserved[123] */ +}; diff --git a/src/inputs/librespot-c/src/proto/login5_challenges_code.pb-c.h b/src/inputs/librespot-c/src/proto/login5_challenges_code.pb-c.h new file mode 100644 index 00000000..6cbdcf03 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_challenges_code.pb-c.h @@ -0,0 +1,114 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: login5_challenges_code.proto */ + +#ifndef PROTOBUF_C_login5_5fchallenges_5fcode_2eproto__INCLUDED +#define PROTOBUF_C_login5_5fchallenges_5fcode_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# 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 1004001 < 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 Spotify__Login5__V3__Challenges__CodeChallenge Spotify__Login5__V3__Challenges__CodeChallenge; +typedef struct Spotify__Login5__V3__Challenges__CodeSolution Spotify__Login5__V3__Challenges__CodeSolution; + + +/* --- enums --- */ + +typedef enum _Spotify__Login5__V3__Challenges__CodeChallenge__Method { + SPOTIFY__LOGIN5__V3__CHALLENGES__CODE_CHALLENGE__METHOD__UNKNOWN = 0, + SPOTIFY__LOGIN5__V3__CHALLENGES__CODE_CHALLENGE__METHOD__SMS = 1 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__LOGIN5__V3__CHALLENGES__CODE_CHALLENGE__METHOD) +} Spotify__Login5__V3__Challenges__CodeChallenge__Method; + +/* --- messages --- */ + +struct Spotify__Login5__V3__Challenges__CodeChallenge +{ + ProtobufCMessage base; + Spotify__Login5__V3__Challenges__CodeChallenge__Method method; + int32_t code_length; + int32_t expires_in; + char *canonical_phone_number; +}; +#define SPOTIFY__LOGIN5__V3__CHALLENGES__CODE_CHALLENGE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__challenges__code_challenge__descriptor) \ + , SPOTIFY__LOGIN5__V3__CHALLENGES__CODE_CHALLENGE__METHOD__UNKNOWN, 0, 0, (char *)protobuf_c_empty_string } + + +struct Spotify__Login5__V3__Challenges__CodeSolution +{ + ProtobufCMessage base; + char *code; +}; +#define SPOTIFY__LOGIN5__V3__CHALLENGES__CODE_SOLUTION__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__challenges__code_solution__descriptor) \ + , (char *)protobuf_c_empty_string } + + +/* Spotify__Login5__V3__Challenges__CodeChallenge methods */ +void spotify__login5__v3__challenges__code_challenge__init + (Spotify__Login5__V3__Challenges__CodeChallenge *message); +size_t spotify__login5__v3__challenges__code_challenge__get_packed_size + (const Spotify__Login5__V3__Challenges__CodeChallenge *message); +size_t spotify__login5__v3__challenges__code_challenge__pack + (const Spotify__Login5__V3__Challenges__CodeChallenge *message, + uint8_t *out); +size_t spotify__login5__v3__challenges__code_challenge__pack_to_buffer + (const Spotify__Login5__V3__Challenges__CodeChallenge *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Challenges__CodeChallenge * + spotify__login5__v3__challenges__code_challenge__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__challenges__code_challenge__free_unpacked + (Spotify__Login5__V3__Challenges__CodeChallenge *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__Challenges__CodeSolution methods */ +void spotify__login5__v3__challenges__code_solution__init + (Spotify__Login5__V3__Challenges__CodeSolution *message); +size_t spotify__login5__v3__challenges__code_solution__get_packed_size + (const Spotify__Login5__V3__Challenges__CodeSolution *message); +size_t spotify__login5__v3__challenges__code_solution__pack + (const Spotify__Login5__V3__Challenges__CodeSolution *message, + uint8_t *out); +size_t spotify__login5__v3__challenges__code_solution__pack_to_buffer + (const Spotify__Login5__V3__Challenges__CodeSolution *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Challenges__CodeSolution * + spotify__login5__v3__challenges__code_solution__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__challenges__code_solution__free_unpacked + (Spotify__Login5__V3__Challenges__CodeSolution *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Spotify__Login5__V3__Challenges__CodeChallenge_Closure) + (const Spotify__Login5__V3__Challenges__CodeChallenge *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__Challenges__CodeSolution_Closure) + (const Spotify__Login5__V3__Challenges__CodeSolution *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCMessageDescriptor spotify__login5__v3__challenges__code_challenge__descriptor; +extern const ProtobufCEnumDescriptor spotify__login5__v3__challenges__code_challenge__method__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__challenges__code_solution__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_login5_5fchallenges_5fcode_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/login5_challenges_code.proto b/src/inputs/librespot-c/src/proto/login5_challenges_code.proto new file mode 100644 index 00000000..8e6e6a2b --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_challenges_code.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package spotify.login5.v3.challenges; + +message CodeChallenge { + Method method = 1; + enum Method { + UNKNOWN = 0; + SMS = 1; + } + + int32 code_length = 2; + int32 expires_in = 3; + string canonical_phone_number = 4; +} + +message CodeSolution { + string code = 1; +} diff --git a/src/inputs/librespot-c/src/proto/login5_challenges_hashcash.pb-c.c b/src/inputs/librespot-c/src/proto/login5_challenges_hashcash.pb-c.c new file mode 100644 index 00000000..53c463ac --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_challenges_hashcash.pb-c.c @@ -0,0 +1,201 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: login5_challenges_hashcash.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "login5_challenges_hashcash.pb-c.h" +void spotify__login5__v3__challenges__hashcash_challenge__init + (Spotify__Login5__V3__Challenges__HashcashChallenge *message) +{ + static const Spotify__Login5__V3__Challenges__HashcashChallenge init_value = SPOTIFY__LOGIN5__V3__CHALLENGES__HASHCASH_CHALLENGE__INIT; + *message = init_value; +} +size_t spotify__login5__v3__challenges__hashcash_challenge__get_packed_size + (const Spotify__Login5__V3__Challenges__HashcashChallenge *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__hashcash_challenge__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__challenges__hashcash_challenge__pack + (const Spotify__Login5__V3__Challenges__HashcashChallenge *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__hashcash_challenge__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__challenges__hashcash_challenge__pack_to_buffer + (const Spotify__Login5__V3__Challenges__HashcashChallenge *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__hashcash_challenge__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Challenges__HashcashChallenge * + spotify__login5__v3__challenges__hashcash_challenge__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Challenges__HashcashChallenge *) + protobuf_c_message_unpack (&spotify__login5__v3__challenges__hashcash_challenge__descriptor, + allocator, len, data); +} +void spotify__login5__v3__challenges__hashcash_challenge__free_unpacked + (Spotify__Login5__V3__Challenges__HashcashChallenge *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__challenges__hashcash_challenge__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__challenges__hashcash_solution__init + (Spotify__Login5__V3__Challenges__HashcashSolution *message) +{ + static const Spotify__Login5__V3__Challenges__HashcashSolution init_value = SPOTIFY__LOGIN5__V3__CHALLENGES__HASHCASH_SOLUTION__INIT; + *message = init_value; +} +size_t spotify__login5__v3__challenges__hashcash_solution__get_packed_size + (const Spotify__Login5__V3__Challenges__HashcashSolution *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__hashcash_solution__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__challenges__hashcash_solution__pack + (const Spotify__Login5__V3__Challenges__HashcashSolution *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__hashcash_solution__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__challenges__hashcash_solution__pack_to_buffer + (const Spotify__Login5__V3__Challenges__HashcashSolution *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__challenges__hashcash_solution__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Challenges__HashcashSolution * + spotify__login5__v3__challenges__hashcash_solution__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Challenges__HashcashSolution *) + protobuf_c_message_unpack (&spotify__login5__v3__challenges__hashcash_solution__descriptor, + allocator, len, data); +} +void spotify__login5__v3__challenges__hashcash_solution__free_unpacked + (Spotify__Login5__V3__Challenges__HashcashSolution *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__challenges__hashcash_solution__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCFieldDescriptor spotify__login5__v3__challenges__hashcash_challenge__field_descriptors[2] = +{ + { + "prefix", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Challenges__HashcashChallenge, prefix), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "length", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Challenges__HashcashChallenge, length), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__challenges__hashcash_challenge__field_indices_by_name[] = { + 1, /* field[1] = length */ + 0, /* field[0] = prefix */ +}; +static const ProtobufCIntRange spotify__login5__v3__challenges__hashcash_challenge__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__challenges__hashcash_challenge__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.challenges.HashcashChallenge", + "HashcashChallenge", + "Spotify__Login5__V3__Challenges__HashcashChallenge", + "spotify.login5.v3.challenges", + sizeof(Spotify__Login5__V3__Challenges__HashcashChallenge), + 2, + spotify__login5__v3__challenges__hashcash_challenge__field_descriptors, + spotify__login5__v3__challenges__hashcash_challenge__field_indices_by_name, + 1, spotify__login5__v3__challenges__hashcash_challenge__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__challenges__hashcash_challenge__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__challenges__hashcash_solution__field_descriptors[2] = +{ + { + "suffix", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Challenges__HashcashSolution, suffix), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "duration", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Challenges__HashcashSolution, duration), + &google__protobuf__duration__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__challenges__hashcash_solution__field_indices_by_name[] = { + 1, /* field[1] = duration */ + 0, /* field[0] = suffix */ +}; +static const ProtobufCIntRange spotify__login5__v3__challenges__hashcash_solution__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__challenges__hashcash_solution__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.challenges.HashcashSolution", + "HashcashSolution", + "Spotify__Login5__V3__Challenges__HashcashSolution", + "spotify.login5.v3.challenges", + sizeof(Spotify__Login5__V3__Challenges__HashcashSolution), + 2, + spotify__login5__v3__challenges__hashcash_solution__field_descriptors, + spotify__login5__v3__challenges__hashcash_solution__field_indices_by_name, + 1, spotify__login5__v3__challenges__hashcash_solution__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__challenges__hashcash_solution__init, + NULL,NULL,NULL /* reserved[123] */ +}; diff --git a/src/inputs/librespot-c/src/proto/login5_challenges_hashcash.pb-c.h b/src/inputs/librespot-c/src/proto/login5_challenges_hashcash.pb-c.h new file mode 100644 index 00000000..58ce5d5e --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_challenges_hashcash.pb-c.h @@ -0,0 +1,108 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: login5_challenges_hashcash.proto */ + +#ifndef PROTOBUF_C_login5_5fchallenges_5fhashcash_2eproto__INCLUDED +#define PROTOBUF_C_login5_5fchallenges_5fhashcash_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# 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 1004001 < 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 + +#include "google_duration.pb-c.h" + +typedef struct Spotify__Login5__V3__Challenges__HashcashChallenge Spotify__Login5__V3__Challenges__HashcashChallenge; +typedef struct Spotify__Login5__V3__Challenges__HashcashSolution Spotify__Login5__V3__Challenges__HashcashSolution; + + +/* --- enums --- */ + + +/* --- messages --- */ + +struct Spotify__Login5__V3__Challenges__HashcashChallenge +{ + ProtobufCMessage base; + ProtobufCBinaryData prefix; + int32_t length; +}; +#define SPOTIFY__LOGIN5__V3__CHALLENGES__HASHCASH_CHALLENGE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__challenges__hashcash_challenge__descriptor) \ + , {0,NULL}, 0 } + + +struct Spotify__Login5__V3__Challenges__HashcashSolution +{ + ProtobufCMessage base; + ProtobufCBinaryData suffix; + Google__Protobuf__Duration *duration; +}; +#define SPOTIFY__LOGIN5__V3__CHALLENGES__HASHCASH_SOLUTION__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__challenges__hashcash_solution__descriptor) \ + , {0,NULL}, NULL } + + +/* Spotify__Login5__V3__Challenges__HashcashChallenge methods */ +void spotify__login5__v3__challenges__hashcash_challenge__init + (Spotify__Login5__V3__Challenges__HashcashChallenge *message); +size_t spotify__login5__v3__challenges__hashcash_challenge__get_packed_size + (const Spotify__Login5__V3__Challenges__HashcashChallenge *message); +size_t spotify__login5__v3__challenges__hashcash_challenge__pack + (const Spotify__Login5__V3__Challenges__HashcashChallenge *message, + uint8_t *out); +size_t spotify__login5__v3__challenges__hashcash_challenge__pack_to_buffer + (const Spotify__Login5__V3__Challenges__HashcashChallenge *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Challenges__HashcashChallenge * + spotify__login5__v3__challenges__hashcash_challenge__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__challenges__hashcash_challenge__free_unpacked + (Spotify__Login5__V3__Challenges__HashcashChallenge *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__Challenges__HashcashSolution methods */ +void spotify__login5__v3__challenges__hashcash_solution__init + (Spotify__Login5__V3__Challenges__HashcashSolution *message); +size_t spotify__login5__v3__challenges__hashcash_solution__get_packed_size + (const Spotify__Login5__V3__Challenges__HashcashSolution *message); +size_t spotify__login5__v3__challenges__hashcash_solution__pack + (const Spotify__Login5__V3__Challenges__HashcashSolution *message, + uint8_t *out); +size_t spotify__login5__v3__challenges__hashcash_solution__pack_to_buffer + (const Spotify__Login5__V3__Challenges__HashcashSolution *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Challenges__HashcashSolution * + spotify__login5__v3__challenges__hashcash_solution__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__challenges__hashcash_solution__free_unpacked + (Spotify__Login5__V3__Challenges__HashcashSolution *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Spotify__Login5__V3__Challenges__HashcashChallenge_Closure) + (const Spotify__Login5__V3__Challenges__HashcashChallenge *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__Challenges__HashcashSolution_Closure) + (const Spotify__Login5__V3__Challenges__HashcashSolution *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCMessageDescriptor spotify__login5__v3__challenges__hashcash_challenge__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__challenges__hashcash_solution__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_login5_5fchallenges_5fhashcash_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/login5_challenges_hashcash.proto b/src/inputs/librespot-c/src/proto/login5_challenges_hashcash.proto new file mode 100644 index 00000000..544d19a7 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_challenges_hashcash.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package spotify.login5.v3.challenges; + +import "google_duration.proto"; + +message HashcashChallenge { + bytes prefix = 1; + int32 length = 2; +} + +message HashcashSolution { + bytes suffix = 1; + google.protobuf.Duration duration = 2; +} diff --git a/src/inputs/librespot-c/src/proto/login5_client_info.pb-c.c b/src/inputs/librespot-c/src/proto/login5_client_info.pb-c.c new file mode 100644 index 00000000..fe9d8a8b --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_client_info.pb-c.c @@ -0,0 +1,105 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: login5_client_info.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "login5_client_info.pb-c.h" +void spotify__login5__v3__client_info__init + (Spotify__Login5__V3__ClientInfo *message) +{ + static const Spotify__Login5__V3__ClientInfo init_value = SPOTIFY__LOGIN5__V3__CLIENT_INFO__INIT; + *message = init_value; +} +size_t spotify__login5__v3__client_info__get_packed_size + (const Spotify__Login5__V3__ClientInfo *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__client_info__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__client_info__pack + (const Spotify__Login5__V3__ClientInfo *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__client_info__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__client_info__pack_to_buffer + (const Spotify__Login5__V3__ClientInfo *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__client_info__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__ClientInfo * + spotify__login5__v3__client_info__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__ClientInfo *) + protobuf_c_message_unpack (&spotify__login5__v3__client_info__descriptor, + allocator, len, data); +} +void spotify__login5__v3__client_info__free_unpacked + (Spotify__Login5__V3__ClientInfo *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__client_info__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCFieldDescriptor spotify__login5__v3__client_info__field_descriptors[2] = +{ + { + "client_id", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__ClientInfo, client_id), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "device_id", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__ClientInfo, device_id), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__client_info__field_indices_by_name[] = { + 0, /* field[0] = client_id */ + 1, /* field[1] = device_id */ +}; +static const ProtobufCIntRange spotify__login5__v3__client_info__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__client_info__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.ClientInfo", + "ClientInfo", + "Spotify__Login5__V3__ClientInfo", + "spotify.login5.v3", + sizeof(Spotify__Login5__V3__ClientInfo), + 2, + spotify__login5__v3__client_info__field_descriptors, + spotify__login5__v3__client_info__field_indices_by_name, + 1, spotify__login5__v3__client_info__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__client_info__init, + NULL,NULL,NULL /* reserved[123] */ +}; diff --git a/src/inputs/librespot-c/src/proto/login5_client_info.pb-c.h b/src/inputs/librespot-c/src/proto/login5_client_info.pb-c.h new file mode 100644 index 00000000..a51cc6ae --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_client_info.pb-c.h @@ -0,0 +1,72 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: login5_client_info.proto */ + +#ifndef PROTOBUF_C_login5_5fclient_5finfo_2eproto__INCLUDED +#define PROTOBUF_C_login5_5fclient_5finfo_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# 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 1004001 < 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 Spotify__Login5__V3__ClientInfo Spotify__Login5__V3__ClientInfo; + + +/* --- enums --- */ + + +/* --- messages --- */ + +struct Spotify__Login5__V3__ClientInfo +{ + ProtobufCMessage base; + char *client_id; + char *device_id; +}; +#define SPOTIFY__LOGIN5__V3__CLIENT_INFO__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__client_info__descriptor) \ + , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string } + + +/* Spotify__Login5__V3__ClientInfo methods */ +void spotify__login5__v3__client_info__init + (Spotify__Login5__V3__ClientInfo *message); +size_t spotify__login5__v3__client_info__get_packed_size + (const Spotify__Login5__V3__ClientInfo *message); +size_t spotify__login5__v3__client_info__pack + (const Spotify__Login5__V3__ClientInfo *message, + uint8_t *out); +size_t spotify__login5__v3__client_info__pack_to_buffer + (const Spotify__Login5__V3__ClientInfo *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__ClientInfo * + spotify__login5__v3__client_info__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__client_info__free_unpacked + (Spotify__Login5__V3__ClientInfo *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Spotify__Login5__V3__ClientInfo_Closure) + (const Spotify__Login5__V3__ClientInfo *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCMessageDescriptor spotify__login5__v3__client_info__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_login5_5fclient_5finfo_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/login5_client_info.proto b/src/inputs/librespot-c/src/proto/login5_client_info.proto new file mode 100644 index 00000000..b1b1fe1a --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_client_info.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +package spotify.login5.v3; + +message ClientInfo { + string client_id = 1; + string device_id = 2; +} diff --git a/src/inputs/librespot-c/src/proto/login5_credentials.pb-c.c b/src/inputs/librespot-c/src/proto/login5_credentials.pb-c.c new file mode 100644 index 00000000..22a504d2 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_credentials.pb-c.c @@ -0,0 +1,816 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: login5_credentials.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "login5_credentials.pb-c.h" +void spotify__login5__v3__credentials__stored_credential__init + (Spotify__Login5__V3__Credentials__StoredCredential *message) +{ + static const Spotify__Login5__V3__Credentials__StoredCredential init_value = SPOTIFY__LOGIN5__V3__CREDENTIALS__STORED_CREDENTIAL__INIT; + *message = init_value; +} +size_t spotify__login5__v3__credentials__stored_credential__get_packed_size + (const Spotify__Login5__V3__Credentials__StoredCredential *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__stored_credential__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__credentials__stored_credential__pack + (const Spotify__Login5__V3__Credentials__StoredCredential *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__stored_credential__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__credentials__stored_credential__pack_to_buffer + (const Spotify__Login5__V3__Credentials__StoredCredential *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__stored_credential__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Credentials__StoredCredential * + spotify__login5__v3__credentials__stored_credential__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Credentials__StoredCredential *) + protobuf_c_message_unpack (&spotify__login5__v3__credentials__stored_credential__descriptor, + allocator, len, data); +} +void spotify__login5__v3__credentials__stored_credential__free_unpacked + (Spotify__Login5__V3__Credentials__StoredCredential *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__credentials__stored_credential__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__credentials__password__init + (Spotify__Login5__V3__Credentials__Password *message) +{ + static const Spotify__Login5__V3__Credentials__Password init_value = SPOTIFY__LOGIN5__V3__CREDENTIALS__PASSWORD__INIT; + *message = init_value; +} +size_t spotify__login5__v3__credentials__password__get_packed_size + (const Spotify__Login5__V3__Credentials__Password *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__password__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__credentials__password__pack + (const Spotify__Login5__V3__Credentials__Password *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__password__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__credentials__password__pack_to_buffer + (const Spotify__Login5__V3__Credentials__Password *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__password__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Credentials__Password * + spotify__login5__v3__credentials__password__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Credentials__Password *) + protobuf_c_message_unpack (&spotify__login5__v3__credentials__password__descriptor, + allocator, len, data); +} +void spotify__login5__v3__credentials__password__free_unpacked + (Spotify__Login5__V3__Credentials__Password *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__credentials__password__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__credentials__facebook_access_token__init + (Spotify__Login5__V3__Credentials__FacebookAccessToken *message) +{ + static const Spotify__Login5__V3__Credentials__FacebookAccessToken init_value = SPOTIFY__LOGIN5__V3__CREDENTIALS__FACEBOOK_ACCESS_TOKEN__INIT; + *message = init_value; +} +size_t spotify__login5__v3__credentials__facebook_access_token__get_packed_size + (const Spotify__Login5__V3__Credentials__FacebookAccessToken *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__facebook_access_token__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__credentials__facebook_access_token__pack + (const Spotify__Login5__V3__Credentials__FacebookAccessToken *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__facebook_access_token__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__credentials__facebook_access_token__pack_to_buffer + (const Spotify__Login5__V3__Credentials__FacebookAccessToken *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__facebook_access_token__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Credentials__FacebookAccessToken * + spotify__login5__v3__credentials__facebook_access_token__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Credentials__FacebookAccessToken *) + protobuf_c_message_unpack (&spotify__login5__v3__credentials__facebook_access_token__descriptor, + allocator, len, data); +} +void spotify__login5__v3__credentials__facebook_access_token__free_unpacked + (Spotify__Login5__V3__Credentials__FacebookAccessToken *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__credentials__facebook_access_token__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__credentials__one_time_token__init + (Spotify__Login5__V3__Credentials__OneTimeToken *message) +{ + static const Spotify__Login5__V3__Credentials__OneTimeToken init_value = SPOTIFY__LOGIN5__V3__CREDENTIALS__ONE_TIME_TOKEN__INIT; + *message = init_value; +} +size_t spotify__login5__v3__credentials__one_time_token__get_packed_size + (const Spotify__Login5__V3__Credentials__OneTimeToken *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__one_time_token__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__credentials__one_time_token__pack + (const Spotify__Login5__V3__Credentials__OneTimeToken *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__one_time_token__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__credentials__one_time_token__pack_to_buffer + (const Spotify__Login5__V3__Credentials__OneTimeToken *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__one_time_token__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Credentials__OneTimeToken * + spotify__login5__v3__credentials__one_time_token__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Credentials__OneTimeToken *) + protobuf_c_message_unpack (&spotify__login5__v3__credentials__one_time_token__descriptor, + allocator, len, data); +} +void spotify__login5__v3__credentials__one_time_token__free_unpacked + (Spotify__Login5__V3__Credentials__OneTimeToken *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__credentials__one_time_token__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__credentials__parent_child_credential__init + (Spotify__Login5__V3__Credentials__ParentChildCredential *message) +{ + static const Spotify__Login5__V3__Credentials__ParentChildCredential init_value = SPOTIFY__LOGIN5__V3__CREDENTIALS__PARENT_CHILD_CREDENTIAL__INIT; + *message = init_value; +} +size_t spotify__login5__v3__credentials__parent_child_credential__get_packed_size + (const Spotify__Login5__V3__Credentials__ParentChildCredential *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__parent_child_credential__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__credentials__parent_child_credential__pack + (const Spotify__Login5__V3__Credentials__ParentChildCredential *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__parent_child_credential__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__credentials__parent_child_credential__pack_to_buffer + (const Spotify__Login5__V3__Credentials__ParentChildCredential *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__parent_child_credential__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Credentials__ParentChildCredential * + spotify__login5__v3__credentials__parent_child_credential__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Credentials__ParentChildCredential *) + protobuf_c_message_unpack (&spotify__login5__v3__credentials__parent_child_credential__descriptor, + allocator, len, data); +} +void spotify__login5__v3__credentials__parent_child_credential__free_unpacked + (Spotify__Login5__V3__Credentials__ParentChildCredential *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__credentials__parent_child_credential__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__credentials__apple_sign_in_credential__init + (Spotify__Login5__V3__Credentials__AppleSignInCredential *message) +{ + static const Spotify__Login5__V3__Credentials__AppleSignInCredential init_value = SPOTIFY__LOGIN5__V3__CREDENTIALS__APPLE_SIGN_IN_CREDENTIAL__INIT; + *message = init_value; +} +size_t spotify__login5__v3__credentials__apple_sign_in_credential__get_packed_size + (const Spotify__Login5__V3__Credentials__AppleSignInCredential *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__apple_sign_in_credential__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__credentials__apple_sign_in_credential__pack + (const Spotify__Login5__V3__Credentials__AppleSignInCredential *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__apple_sign_in_credential__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__credentials__apple_sign_in_credential__pack_to_buffer + (const Spotify__Login5__V3__Credentials__AppleSignInCredential *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__apple_sign_in_credential__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Credentials__AppleSignInCredential * + spotify__login5__v3__credentials__apple_sign_in_credential__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Credentials__AppleSignInCredential *) + protobuf_c_message_unpack (&spotify__login5__v3__credentials__apple_sign_in_credential__descriptor, + allocator, len, data); +} +void spotify__login5__v3__credentials__apple_sign_in_credential__free_unpacked + (Spotify__Login5__V3__Credentials__AppleSignInCredential *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__credentials__apple_sign_in_credential__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__credentials__samsung_sign_in_credential__init + (Spotify__Login5__V3__Credentials__SamsungSignInCredential *message) +{ + static const Spotify__Login5__V3__Credentials__SamsungSignInCredential init_value = SPOTIFY__LOGIN5__V3__CREDENTIALS__SAMSUNG_SIGN_IN_CREDENTIAL__INIT; + *message = init_value; +} +size_t spotify__login5__v3__credentials__samsung_sign_in_credential__get_packed_size + (const Spotify__Login5__V3__Credentials__SamsungSignInCredential *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__samsung_sign_in_credential__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__credentials__samsung_sign_in_credential__pack + (const Spotify__Login5__V3__Credentials__SamsungSignInCredential *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__samsung_sign_in_credential__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__credentials__samsung_sign_in_credential__pack_to_buffer + (const Spotify__Login5__V3__Credentials__SamsungSignInCredential *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__samsung_sign_in_credential__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Credentials__SamsungSignInCredential * + spotify__login5__v3__credentials__samsung_sign_in_credential__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Credentials__SamsungSignInCredential *) + protobuf_c_message_unpack (&spotify__login5__v3__credentials__samsung_sign_in_credential__descriptor, + allocator, len, data); +} +void spotify__login5__v3__credentials__samsung_sign_in_credential__free_unpacked + (Spotify__Login5__V3__Credentials__SamsungSignInCredential *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__credentials__samsung_sign_in_credential__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__login5__v3__credentials__google_sign_in_credential__init + (Spotify__Login5__V3__Credentials__GoogleSignInCredential *message) +{ + static const Spotify__Login5__V3__Credentials__GoogleSignInCredential init_value = SPOTIFY__LOGIN5__V3__CREDENTIALS__GOOGLE_SIGN_IN_CREDENTIAL__INIT; + *message = init_value; +} +size_t spotify__login5__v3__credentials__google_sign_in_credential__get_packed_size + (const Spotify__Login5__V3__Credentials__GoogleSignInCredential *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__google_sign_in_credential__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__credentials__google_sign_in_credential__pack + (const Spotify__Login5__V3__Credentials__GoogleSignInCredential *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__google_sign_in_credential__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__credentials__google_sign_in_credential__pack_to_buffer + (const Spotify__Login5__V3__Credentials__GoogleSignInCredential *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__credentials__google_sign_in_credential__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Credentials__GoogleSignInCredential * + spotify__login5__v3__credentials__google_sign_in_credential__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Credentials__GoogleSignInCredential *) + protobuf_c_message_unpack (&spotify__login5__v3__credentials__google_sign_in_credential__descriptor, + allocator, len, data); +} +void spotify__login5__v3__credentials__google_sign_in_credential__free_unpacked + (Spotify__Login5__V3__Credentials__GoogleSignInCredential *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__credentials__google_sign_in_credential__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCFieldDescriptor spotify__login5__v3__credentials__stored_credential__field_descriptors[2] = +{ + { + "username", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__StoredCredential, username), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "data", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__StoredCredential, data), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__credentials__stored_credential__field_indices_by_name[] = { + 1, /* field[1] = data */ + 0, /* field[0] = username */ +}; +static const ProtobufCIntRange spotify__login5__v3__credentials__stored_credential__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__credentials__stored_credential__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.credentials.StoredCredential", + "StoredCredential", + "Spotify__Login5__V3__Credentials__StoredCredential", + "spotify.login5.v3.credentials", + sizeof(Spotify__Login5__V3__Credentials__StoredCredential), + 2, + spotify__login5__v3__credentials__stored_credential__field_descriptors, + spotify__login5__v3__credentials__stored_credential__field_indices_by_name, + 1, spotify__login5__v3__credentials__stored_credential__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__credentials__stored_credential__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__credentials__password__field_descriptors[3] = +{ + { + "id", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__Password, id), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "password", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__Password, password), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "padding", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__Password, padding), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__credentials__password__field_indices_by_name[] = { + 0, /* field[0] = id */ + 2, /* field[2] = padding */ + 1, /* field[1] = password */ +}; +static const ProtobufCIntRange spotify__login5__v3__credentials__password__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 3 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__credentials__password__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.credentials.Password", + "Password", + "Spotify__Login5__V3__Credentials__Password", + "spotify.login5.v3.credentials", + sizeof(Spotify__Login5__V3__Credentials__Password), + 3, + spotify__login5__v3__credentials__password__field_descriptors, + spotify__login5__v3__credentials__password__field_indices_by_name, + 1, spotify__login5__v3__credentials__password__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__credentials__password__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__credentials__facebook_access_token__field_descriptors[2] = +{ + { + "fb_uid", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__FacebookAccessToken, fb_uid), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "access_token", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__FacebookAccessToken, access_token), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__credentials__facebook_access_token__field_indices_by_name[] = { + 1, /* field[1] = access_token */ + 0, /* field[0] = fb_uid */ +}; +static const ProtobufCIntRange spotify__login5__v3__credentials__facebook_access_token__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__credentials__facebook_access_token__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.credentials.FacebookAccessToken", + "FacebookAccessToken", + "Spotify__Login5__V3__Credentials__FacebookAccessToken", + "spotify.login5.v3.credentials", + sizeof(Spotify__Login5__V3__Credentials__FacebookAccessToken), + 2, + spotify__login5__v3__credentials__facebook_access_token__field_descriptors, + spotify__login5__v3__credentials__facebook_access_token__field_indices_by_name, + 1, spotify__login5__v3__credentials__facebook_access_token__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__credentials__facebook_access_token__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__credentials__one_time_token__field_descriptors[1] = +{ + { + "token", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__OneTimeToken, token), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__credentials__one_time_token__field_indices_by_name[] = { + 0, /* field[0] = token */ +}; +static const ProtobufCIntRange spotify__login5__v3__credentials__one_time_token__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 1 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__credentials__one_time_token__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.credentials.OneTimeToken", + "OneTimeToken", + "Spotify__Login5__V3__Credentials__OneTimeToken", + "spotify.login5.v3.credentials", + sizeof(Spotify__Login5__V3__Credentials__OneTimeToken), + 1, + spotify__login5__v3__credentials__one_time_token__field_descriptors, + spotify__login5__v3__credentials__one_time_token__field_indices_by_name, + 1, spotify__login5__v3__credentials__one_time_token__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__credentials__one_time_token__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__credentials__parent_child_credential__field_descriptors[2] = +{ + { + "child_id", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__ParentChildCredential, child_id), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "parent_stored_credential", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__ParentChildCredential, parent_stored_credential), + &spotify__login5__v3__credentials__stored_credential__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__credentials__parent_child_credential__field_indices_by_name[] = { + 0, /* field[0] = child_id */ + 1, /* field[1] = parent_stored_credential */ +}; +static const ProtobufCIntRange spotify__login5__v3__credentials__parent_child_credential__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__credentials__parent_child_credential__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.credentials.ParentChildCredential", + "ParentChildCredential", + "Spotify__Login5__V3__Credentials__ParentChildCredential", + "spotify.login5.v3.credentials", + sizeof(Spotify__Login5__V3__Credentials__ParentChildCredential), + 2, + spotify__login5__v3__credentials__parent_child_credential__field_descriptors, + spotify__login5__v3__credentials__parent_child_credential__field_indices_by_name, + 1, spotify__login5__v3__credentials__parent_child_credential__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__credentials__parent_child_credential__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__credentials__apple_sign_in_credential__field_descriptors[3] = +{ + { + "auth_code", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__AppleSignInCredential, auth_code), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "redirect_uri", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__AppleSignInCredential, redirect_uri), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "bundle_id", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__AppleSignInCredential, bundle_id), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__credentials__apple_sign_in_credential__field_indices_by_name[] = { + 0, /* field[0] = auth_code */ + 2, /* field[2] = bundle_id */ + 1, /* field[1] = redirect_uri */ +}; +static const ProtobufCIntRange spotify__login5__v3__credentials__apple_sign_in_credential__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 3 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__credentials__apple_sign_in_credential__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.credentials.AppleSignInCredential", + "AppleSignInCredential", + "Spotify__Login5__V3__Credentials__AppleSignInCredential", + "spotify.login5.v3.credentials", + sizeof(Spotify__Login5__V3__Credentials__AppleSignInCredential), + 3, + spotify__login5__v3__credentials__apple_sign_in_credential__field_descriptors, + spotify__login5__v3__credentials__apple_sign_in_credential__field_indices_by_name, + 1, spotify__login5__v3__credentials__apple_sign_in_credential__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__credentials__apple_sign_in_credential__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__credentials__samsung_sign_in_credential__field_descriptors[4] = +{ + { + "auth_code", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__SamsungSignInCredential, auth_code), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "redirect_uri", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__SamsungSignInCredential, redirect_uri), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "id_token", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__SamsungSignInCredential, id_token), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "token_endpoint_url", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__SamsungSignInCredential, token_endpoint_url), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__credentials__samsung_sign_in_credential__field_indices_by_name[] = { + 0, /* field[0] = auth_code */ + 2, /* field[2] = id_token */ + 1, /* field[1] = redirect_uri */ + 3, /* field[3] = token_endpoint_url */ +}; +static const ProtobufCIntRange spotify__login5__v3__credentials__samsung_sign_in_credential__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 4 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__credentials__samsung_sign_in_credential__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.credentials.SamsungSignInCredential", + "SamsungSignInCredential", + "Spotify__Login5__V3__Credentials__SamsungSignInCredential", + "spotify.login5.v3.credentials", + sizeof(Spotify__Login5__V3__Credentials__SamsungSignInCredential), + 4, + spotify__login5__v3__credentials__samsung_sign_in_credential__field_descriptors, + spotify__login5__v3__credentials__samsung_sign_in_credential__field_indices_by_name, + 1, spotify__login5__v3__credentials__samsung_sign_in_credential__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__credentials__samsung_sign_in_credential__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__credentials__google_sign_in_credential__field_descriptors[2] = +{ + { + "auth_code", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__GoogleSignInCredential, auth_code), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "redirect_uri", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Credentials__GoogleSignInCredential, redirect_uri), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__credentials__google_sign_in_credential__field_indices_by_name[] = { + 0, /* field[0] = auth_code */ + 1, /* field[1] = redirect_uri */ +}; +static const ProtobufCIntRange spotify__login5__v3__credentials__google_sign_in_credential__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__credentials__google_sign_in_credential__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.credentials.GoogleSignInCredential", + "GoogleSignInCredential", + "Spotify__Login5__V3__Credentials__GoogleSignInCredential", + "spotify.login5.v3.credentials", + sizeof(Spotify__Login5__V3__Credentials__GoogleSignInCredential), + 2, + spotify__login5__v3__credentials__google_sign_in_credential__field_descriptors, + spotify__login5__v3__credentials__google_sign_in_credential__field_indices_by_name, + 1, spotify__login5__v3__credentials__google_sign_in_credential__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__credentials__google_sign_in_credential__init, + NULL,NULL,NULL /* reserved[123] */ +}; diff --git a/src/inputs/librespot-c/src/proto/login5_credentials.pb-c.h b/src/inputs/librespot-c/src/proto/login5_credentials.pb-c.h new file mode 100644 index 00000000..ab0b1f4e --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_credentials.pb-c.h @@ -0,0 +1,320 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: login5_credentials.proto */ + +#ifndef PROTOBUF_C_login5_5fcredentials_2eproto__INCLUDED +#define PROTOBUF_C_login5_5fcredentials_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# 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 1004001 < 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 Spotify__Login5__V3__Credentials__StoredCredential Spotify__Login5__V3__Credentials__StoredCredential; +typedef struct Spotify__Login5__V3__Credentials__Password Spotify__Login5__V3__Credentials__Password; +typedef struct Spotify__Login5__V3__Credentials__FacebookAccessToken Spotify__Login5__V3__Credentials__FacebookAccessToken; +typedef struct Spotify__Login5__V3__Credentials__OneTimeToken Spotify__Login5__V3__Credentials__OneTimeToken; +typedef struct Spotify__Login5__V3__Credentials__ParentChildCredential Spotify__Login5__V3__Credentials__ParentChildCredential; +typedef struct Spotify__Login5__V3__Credentials__AppleSignInCredential Spotify__Login5__V3__Credentials__AppleSignInCredential; +typedef struct Spotify__Login5__V3__Credentials__SamsungSignInCredential Spotify__Login5__V3__Credentials__SamsungSignInCredential; +typedef struct Spotify__Login5__V3__Credentials__GoogleSignInCredential Spotify__Login5__V3__Credentials__GoogleSignInCredential; + + +/* --- enums --- */ + + +/* --- messages --- */ + +struct Spotify__Login5__V3__Credentials__StoredCredential +{ + ProtobufCMessage base; + char *username; + ProtobufCBinaryData data; +}; +#define SPOTIFY__LOGIN5__V3__CREDENTIALS__STORED_CREDENTIAL__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__credentials__stored_credential__descriptor) \ + , (char *)protobuf_c_empty_string, {0,NULL} } + + +struct Spotify__Login5__V3__Credentials__Password +{ + ProtobufCMessage base; + char *id; + char *password; + ProtobufCBinaryData padding; +}; +#define SPOTIFY__LOGIN5__V3__CREDENTIALS__PASSWORD__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__credentials__password__descriptor) \ + , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, {0,NULL} } + + +struct Spotify__Login5__V3__Credentials__FacebookAccessToken +{ + ProtobufCMessage base; + char *fb_uid; + char *access_token; +}; +#define SPOTIFY__LOGIN5__V3__CREDENTIALS__FACEBOOK_ACCESS_TOKEN__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__credentials__facebook_access_token__descriptor) \ + , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string } + + +struct Spotify__Login5__V3__Credentials__OneTimeToken +{ + ProtobufCMessage base; + char *token; +}; +#define SPOTIFY__LOGIN5__V3__CREDENTIALS__ONE_TIME_TOKEN__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__credentials__one_time_token__descriptor) \ + , (char *)protobuf_c_empty_string } + + +struct Spotify__Login5__V3__Credentials__ParentChildCredential +{ + ProtobufCMessage base; + char *child_id; + Spotify__Login5__V3__Credentials__StoredCredential *parent_stored_credential; +}; +#define SPOTIFY__LOGIN5__V3__CREDENTIALS__PARENT_CHILD_CREDENTIAL__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__credentials__parent_child_credential__descriptor) \ + , (char *)protobuf_c_empty_string, NULL } + + +struct Spotify__Login5__V3__Credentials__AppleSignInCredential +{ + ProtobufCMessage base; + char *auth_code; + char *redirect_uri; + char *bundle_id; +}; +#define SPOTIFY__LOGIN5__V3__CREDENTIALS__APPLE_SIGN_IN_CREDENTIAL__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__credentials__apple_sign_in_credential__descriptor) \ + , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string } + + +struct Spotify__Login5__V3__Credentials__SamsungSignInCredential +{ + ProtobufCMessage base; + char *auth_code; + char *redirect_uri; + char *id_token; + char *token_endpoint_url; +}; +#define SPOTIFY__LOGIN5__V3__CREDENTIALS__SAMSUNG_SIGN_IN_CREDENTIAL__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__credentials__samsung_sign_in_credential__descriptor) \ + , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string } + + +struct Spotify__Login5__V3__Credentials__GoogleSignInCredential +{ + ProtobufCMessage base; + char *auth_code; + char *redirect_uri; +}; +#define SPOTIFY__LOGIN5__V3__CREDENTIALS__GOOGLE_SIGN_IN_CREDENTIAL__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__credentials__google_sign_in_credential__descriptor) \ + , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string } + + +/* Spotify__Login5__V3__Credentials__StoredCredential methods */ +void spotify__login5__v3__credentials__stored_credential__init + (Spotify__Login5__V3__Credentials__StoredCredential *message); +size_t spotify__login5__v3__credentials__stored_credential__get_packed_size + (const Spotify__Login5__V3__Credentials__StoredCredential *message); +size_t spotify__login5__v3__credentials__stored_credential__pack + (const Spotify__Login5__V3__Credentials__StoredCredential *message, + uint8_t *out); +size_t spotify__login5__v3__credentials__stored_credential__pack_to_buffer + (const Spotify__Login5__V3__Credentials__StoredCredential *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Credentials__StoredCredential * + spotify__login5__v3__credentials__stored_credential__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__credentials__stored_credential__free_unpacked + (Spotify__Login5__V3__Credentials__StoredCredential *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__Credentials__Password methods */ +void spotify__login5__v3__credentials__password__init + (Spotify__Login5__V3__Credentials__Password *message); +size_t spotify__login5__v3__credentials__password__get_packed_size + (const Spotify__Login5__V3__Credentials__Password *message); +size_t spotify__login5__v3__credentials__password__pack + (const Spotify__Login5__V3__Credentials__Password *message, + uint8_t *out); +size_t spotify__login5__v3__credentials__password__pack_to_buffer + (const Spotify__Login5__V3__Credentials__Password *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Credentials__Password * + spotify__login5__v3__credentials__password__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__credentials__password__free_unpacked + (Spotify__Login5__V3__Credentials__Password *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__Credentials__FacebookAccessToken methods */ +void spotify__login5__v3__credentials__facebook_access_token__init + (Spotify__Login5__V3__Credentials__FacebookAccessToken *message); +size_t spotify__login5__v3__credentials__facebook_access_token__get_packed_size + (const Spotify__Login5__V3__Credentials__FacebookAccessToken *message); +size_t spotify__login5__v3__credentials__facebook_access_token__pack + (const Spotify__Login5__V3__Credentials__FacebookAccessToken *message, + uint8_t *out); +size_t spotify__login5__v3__credentials__facebook_access_token__pack_to_buffer + (const Spotify__Login5__V3__Credentials__FacebookAccessToken *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Credentials__FacebookAccessToken * + spotify__login5__v3__credentials__facebook_access_token__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__credentials__facebook_access_token__free_unpacked + (Spotify__Login5__V3__Credentials__FacebookAccessToken *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__Credentials__OneTimeToken methods */ +void spotify__login5__v3__credentials__one_time_token__init + (Spotify__Login5__V3__Credentials__OneTimeToken *message); +size_t spotify__login5__v3__credentials__one_time_token__get_packed_size + (const Spotify__Login5__V3__Credentials__OneTimeToken *message); +size_t spotify__login5__v3__credentials__one_time_token__pack + (const Spotify__Login5__V3__Credentials__OneTimeToken *message, + uint8_t *out); +size_t spotify__login5__v3__credentials__one_time_token__pack_to_buffer + (const Spotify__Login5__V3__Credentials__OneTimeToken *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Credentials__OneTimeToken * + spotify__login5__v3__credentials__one_time_token__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__credentials__one_time_token__free_unpacked + (Spotify__Login5__V3__Credentials__OneTimeToken *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__Credentials__ParentChildCredential methods */ +void spotify__login5__v3__credentials__parent_child_credential__init + (Spotify__Login5__V3__Credentials__ParentChildCredential *message); +size_t spotify__login5__v3__credentials__parent_child_credential__get_packed_size + (const Spotify__Login5__V3__Credentials__ParentChildCredential *message); +size_t spotify__login5__v3__credentials__parent_child_credential__pack + (const Spotify__Login5__V3__Credentials__ParentChildCredential *message, + uint8_t *out); +size_t spotify__login5__v3__credentials__parent_child_credential__pack_to_buffer + (const Spotify__Login5__V3__Credentials__ParentChildCredential *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Credentials__ParentChildCredential * + spotify__login5__v3__credentials__parent_child_credential__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__credentials__parent_child_credential__free_unpacked + (Spotify__Login5__V3__Credentials__ParentChildCredential *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__Credentials__AppleSignInCredential methods */ +void spotify__login5__v3__credentials__apple_sign_in_credential__init + (Spotify__Login5__V3__Credentials__AppleSignInCredential *message); +size_t spotify__login5__v3__credentials__apple_sign_in_credential__get_packed_size + (const Spotify__Login5__V3__Credentials__AppleSignInCredential *message); +size_t spotify__login5__v3__credentials__apple_sign_in_credential__pack + (const Spotify__Login5__V3__Credentials__AppleSignInCredential *message, + uint8_t *out); +size_t spotify__login5__v3__credentials__apple_sign_in_credential__pack_to_buffer + (const Spotify__Login5__V3__Credentials__AppleSignInCredential *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Credentials__AppleSignInCredential * + spotify__login5__v3__credentials__apple_sign_in_credential__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__credentials__apple_sign_in_credential__free_unpacked + (Spotify__Login5__V3__Credentials__AppleSignInCredential *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__Credentials__SamsungSignInCredential methods */ +void spotify__login5__v3__credentials__samsung_sign_in_credential__init + (Spotify__Login5__V3__Credentials__SamsungSignInCredential *message); +size_t spotify__login5__v3__credentials__samsung_sign_in_credential__get_packed_size + (const Spotify__Login5__V3__Credentials__SamsungSignInCredential *message); +size_t spotify__login5__v3__credentials__samsung_sign_in_credential__pack + (const Spotify__Login5__V3__Credentials__SamsungSignInCredential *message, + uint8_t *out); +size_t spotify__login5__v3__credentials__samsung_sign_in_credential__pack_to_buffer + (const Spotify__Login5__V3__Credentials__SamsungSignInCredential *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Credentials__SamsungSignInCredential * + spotify__login5__v3__credentials__samsung_sign_in_credential__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__credentials__samsung_sign_in_credential__free_unpacked + (Spotify__Login5__V3__Credentials__SamsungSignInCredential *message, + ProtobufCAllocator *allocator); +/* Spotify__Login5__V3__Credentials__GoogleSignInCredential methods */ +void spotify__login5__v3__credentials__google_sign_in_credential__init + (Spotify__Login5__V3__Credentials__GoogleSignInCredential *message); +size_t spotify__login5__v3__credentials__google_sign_in_credential__get_packed_size + (const Spotify__Login5__V3__Credentials__GoogleSignInCredential *message); +size_t spotify__login5__v3__credentials__google_sign_in_credential__pack + (const Spotify__Login5__V3__Credentials__GoogleSignInCredential *message, + uint8_t *out); +size_t spotify__login5__v3__credentials__google_sign_in_credential__pack_to_buffer + (const Spotify__Login5__V3__Credentials__GoogleSignInCredential *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Credentials__GoogleSignInCredential * + spotify__login5__v3__credentials__google_sign_in_credential__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__credentials__google_sign_in_credential__free_unpacked + (Spotify__Login5__V3__Credentials__GoogleSignInCredential *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Spotify__Login5__V3__Credentials__StoredCredential_Closure) + (const Spotify__Login5__V3__Credentials__StoredCredential *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__Credentials__Password_Closure) + (const Spotify__Login5__V3__Credentials__Password *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__Credentials__FacebookAccessToken_Closure) + (const Spotify__Login5__V3__Credentials__FacebookAccessToken *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__Credentials__OneTimeToken_Closure) + (const Spotify__Login5__V3__Credentials__OneTimeToken *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__Credentials__ParentChildCredential_Closure) + (const Spotify__Login5__V3__Credentials__ParentChildCredential *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__Credentials__AppleSignInCredential_Closure) + (const Spotify__Login5__V3__Credentials__AppleSignInCredential *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__Credentials__SamsungSignInCredential_Closure) + (const Spotify__Login5__V3__Credentials__SamsungSignInCredential *message, + void *closure_data); +typedef void (*Spotify__Login5__V3__Credentials__GoogleSignInCredential_Closure) + (const Spotify__Login5__V3__Credentials__GoogleSignInCredential *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCMessageDescriptor spotify__login5__v3__credentials__stored_credential__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__credentials__password__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__credentials__facebook_access_token__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__credentials__one_time_token__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__credentials__parent_child_credential__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__credentials__apple_sign_in_credential__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__credentials__samsung_sign_in_credential__descriptor; +extern const ProtobufCMessageDescriptor spotify__login5__v3__credentials__google_sign_in_credential__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_login5_5fcredentials_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/login5_credentials.proto b/src/inputs/librespot-c/src/proto/login5_credentials.proto new file mode 100644 index 00000000..7fe07292 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_credentials.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; + +package spotify.login5.v3.credentials; + +message StoredCredential { + string username = 1; + bytes data = 2; +} + +message Password { + string id = 1; + string password = 2; + bytes padding = 3; +} + +message FacebookAccessToken { + string fb_uid = 1; + string access_token = 2; +} + +message OneTimeToken { + string token = 1; +} + +message ParentChildCredential { + string child_id = 1; + StoredCredential parent_stored_credential = 2; +} + +message AppleSignInCredential { + string auth_code = 1; + string redirect_uri = 2; + string bundle_id = 3; +} + +message SamsungSignInCredential { + string auth_code = 1; + string redirect_uri = 2; + string id_token = 3; + string token_endpoint_url = 4; +} + +message GoogleSignInCredential { + string auth_code = 1; + string redirect_uri = 2; +} diff --git a/src/inputs/librespot-c/src/proto/login5_identifiers.pb-c.c b/src/inputs/librespot-c/src/proto/login5_identifiers.pb-c.c new file mode 100644 index 00000000..5fb0c5a1 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_identifiers.pb-c.c @@ -0,0 +1,118 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: login5_identifiers.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "login5_identifiers.pb-c.h" +void spotify__login5__v3__identifiers__phone_number__init + (Spotify__Login5__V3__Identifiers__PhoneNumber *message) +{ + static const Spotify__Login5__V3__Identifiers__PhoneNumber init_value = SPOTIFY__LOGIN5__V3__IDENTIFIERS__PHONE_NUMBER__INIT; + *message = init_value; +} +size_t spotify__login5__v3__identifiers__phone_number__get_packed_size + (const Spotify__Login5__V3__Identifiers__PhoneNumber *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__identifiers__phone_number__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__identifiers__phone_number__pack + (const Spotify__Login5__V3__Identifiers__PhoneNumber *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__identifiers__phone_number__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__identifiers__phone_number__pack_to_buffer + (const Spotify__Login5__V3__Identifiers__PhoneNumber *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__identifiers__phone_number__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__Identifiers__PhoneNumber * + spotify__login5__v3__identifiers__phone_number__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__Identifiers__PhoneNumber *) + protobuf_c_message_unpack (&spotify__login5__v3__identifiers__phone_number__descriptor, + allocator, len, data); +} +void spotify__login5__v3__identifiers__phone_number__free_unpacked + (Spotify__Login5__V3__Identifiers__PhoneNumber *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__identifiers__phone_number__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCFieldDescriptor spotify__login5__v3__identifiers__phone_number__field_descriptors[3] = +{ + { + "number", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Identifiers__PhoneNumber, number), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "iso_country_code", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Identifiers__PhoneNumber, iso_country_code), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "country_calling_code", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__Identifiers__PhoneNumber, country_calling_code), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__identifiers__phone_number__field_indices_by_name[] = { + 2, /* field[2] = country_calling_code */ + 1, /* field[1] = iso_country_code */ + 0, /* field[0] = number */ +}; +static const ProtobufCIntRange spotify__login5__v3__identifiers__phone_number__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 3 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__identifiers__phone_number__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.identifiers.PhoneNumber", + "PhoneNumber", + "Spotify__Login5__V3__Identifiers__PhoneNumber", + "spotify.login5.v3.identifiers", + sizeof(Spotify__Login5__V3__Identifiers__PhoneNumber), + 3, + spotify__login5__v3__identifiers__phone_number__field_descriptors, + spotify__login5__v3__identifiers__phone_number__field_indices_by_name, + 1, spotify__login5__v3__identifiers__phone_number__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__identifiers__phone_number__init, + NULL,NULL,NULL /* reserved[123] */ +}; diff --git a/src/inputs/librespot-c/src/proto/login5_identifiers.pb-c.h b/src/inputs/librespot-c/src/proto/login5_identifiers.pb-c.h new file mode 100644 index 00000000..43ee9d47 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_identifiers.pb-c.h @@ -0,0 +1,73 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: login5_identifiers.proto */ + +#ifndef PROTOBUF_C_login5_5fidentifiers_2eproto__INCLUDED +#define PROTOBUF_C_login5_5fidentifiers_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# 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 1004001 < 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 Spotify__Login5__V3__Identifiers__PhoneNumber Spotify__Login5__V3__Identifiers__PhoneNumber; + + +/* --- enums --- */ + + +/* --- messages --- */ + +struct Spotify__Login5__V3__Identifiers__PhoneNumber +{ + ProtobufCMessage base; + char *number; + char *iso_country_code; + char *country_calling_code; +}; +#define SPOTIFY__LOGIN5__V3__IDENTIFIERS__PHONE_NUMBER__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__identifiers__phone_number__descriptor) \ + , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string } + + +/* Spotify__Login5__V3__Identifiers__PhoneNumber methods */ +void spotify__login5__v3__identifiers__phone_number__init + (Spotify__Login5__V3__Identifiers__PhoneNumber *message); +size_t spotify__login5__v3__identifiers__phone_number__get_packed_size + (const Spotify__Login5__V3__Identifiers__PhoneNumber *message); +size_t spotify__login5__v3__identifiers__phone_number__pack + (const Spotify__Login5__V3__Identifiers__PhoneNumber *message, + uint8_t *out); +size_t spotify__login5__v3__identifiers__phone_number__pack_to_buffer + (const Spotify__Login5__V3__Identifiers__PhoneNumber *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__Identifiers__PhoneNumber * + spotify__login5__v3__identifiers__phone_number__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__identifiers__phone_number__free_unpacked + (Spotify__Login5__V3__Identifiers__PhoneNumber *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Spotify__Login5__V3__Identifiers__PhoneNumber_Closure) + (const Spotify__Login5__V3__Identifiers__PhoneNumber *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCMessageDescriptor spotify__login5__v3__identifiers__phone_number__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_login5_5fidentifiers_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/login5_identifiers.proto b/src/inputs/librespot-c/src/proto/login5_identifiers.proto new file mode 100644 index 00000000..326c570e --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_identifiers.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package spotify.login5.v3.identifiers; + +message PhoneNumber { + string number = 1; + string iso_country_code = 2; + string country_calling_code = 3; +} diff --git a/src/inputs/librespot-c/src/proto/login5_user_info.pb-c.c b/src/inputs/librespot-c/src/proto/login5_user_info.pb-c.c new file mode 100644 index 00000000..ff39aea6 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_user_info.pb-c.c @@ -0,0 +1,215 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: login5_user_info.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "login5_user_info.pb-c.h" +void spotify__login5__v3__user_info__init + (Spotify__Login5__V3__UserInfo *message) +{ + static const Spotify__Login5__V3__UserInfo init_value = SPOTIFY__LOGIN5__V3__USER_INFO__INIT; + *message = init_value; +} +size_t spotify__login5__v3__user_info__get_packed_size + (const Spotify__Login5__V3__UserInfo *message) +{ + assert(message->base.descriptor == &spotify__login5__v3__user_info__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__login5__v3__user_info__pack + (const Spotify__Login5__V3__UserInfo *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__login5__v3__user_info__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__login5__v3__user_info__pack_to_buffer + (const Spotify__Login5__V3__UserInfo *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__login5__v3__user_info__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Login5__V3__UserInfo * + spotify__login5__v3__user_info__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Login5__V3__UserInfo *) + protobuf_c_message_unpack (&spotify__login5__v3__user_info__descriptor, + allocator, len, data); +} +void spotify__login5__v3__user_info__free_unpacked + (Spotify__Login5__V3__UserInfo *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__login5__v3__user_info__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCEnumValue spotify__login5__v3__user_info__gender__enum_values_by_number[4] = +{ + { "UNKNOWN", "SPOTIFY__LOGIN5__V3__USER_INFO__GENDER__UNKNOWN", 0 }, + { "MALE", "SPOTIFY__LOGIN5__V3__USER_INFO__GENDER__MALE", 1 }, + { "FEMALE", "SPOTIFY__LOGIN5__V3__USER_INFO__GENDER__FEMALE", 2 }, + { "NEUTRAL", "SPOTIFY__LOGIN5__V3__USER_INFO__GENDER__NEUTRAL", 3 }, +}; +static const ProtobufCIntRange spotify__login5__v3__user_info__gender__value_ranges[] = { +{0, 0},{0, 4} +}; +static const ProtobufCEnumValueIndex spotify__login5__v3__user_info__gender__enum_values_by_name[4] = +{ + { "FEMALE", 2 }, + { "MALE", 1 }, + { "NEUTRAL", 3 }, + { "UNKNOWN", 0 }, +}; +const ProtobufCEnumDescriptor spotify__login5__v3__user_info__gender__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "spotify.login5.v3.UserInfo.Gender", + "Gender", + "Spotify__Login5__V3__UserInfo__Gender", + "spotify.login5.v3", + 4, + spotify__login5__v3__user_info__gender__enum_values_by_number, + 4, + spotify__login5__v3__user_info__gender__enum_values_by_name, + 1, + spotify__login5__v3__user_info__gender__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; +static const ProtobufCFieldDescriptor spotify__login5__v3__user_info__field_descriptors[8] = +{ + { + "name", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__UserInfo, name), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "email", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__UserInfo, email), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "email_verified", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BOOL, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__UserInfo, email_verified), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "birthdate", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__UserInfo, birthdate), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "gender", + 5, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__UserInfo, gender), + &spotify__login5__v3__user_info__gender__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "phone_number", + 6, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__UserInfo, phone_number), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "phone_number_verified", + 7, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BOOL, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__UserInfo, phone_number_verified), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "email_already_registered", + 8, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BOOL, + 0, /* quantifier_offset */ + offsetof(Spotify__Login5__V3__UserInfo, email_already_registered), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__login5__v3__user_info__field_indices_by_name[] = { + 3, /* field[3] = birthdate */ + 1, /* field[1] = email */ + 7, /* field[7] = email_already_registered */ + 2, /* field[2] = email_verified */ + 4, /* field[4] = gender */ + 0, /* field[0] = name */ + 5, /* field[5] = phone_number */ + 6, /* field[6] = phone_number_verified */ +}; +static const ProtobufCIntRange spotify__login5__v3__user_info__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 8 } +}; +const ProtobufCMessageDescriptor spotify__login5__v3__user_info__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.login5.v3.UserInfo", + "UserInfo", + "Spotify__Login5__V3__UserInfo", + "spotify.login5.v3", + sizeof(Spotify__Login5__V3__UserInfo), + 8, + spotify__login5__v3__user_info__field_descriptors, + spotify__login5__v3__user_info__field_indices_by_name, + 1, spotify__login5__v3__user_info__number_ranges, + (ProtobufCMessageInit) spotify__login5__v3__user_info__init, + NULL,NULL,NULL /* reserved[123] */ +}; diff --git a/src/inputs/librespot-c/src/proto/login5_user_info.pb-c.h b/src/inputs/librespot-c/src/proto/login5_user_info.pb-c.h new file mode 100644 index 00000000..1be704a9 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_user_info.pb-c.h @@ -0,0 +1,86 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: login5_user_info.proto */ + +#ifndef PROTOBUF_C_login5_5fuser_5finfo_2eproto__INCLUDED +#define PROTOBUF_C_login5_5fuser_5finfo_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# 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 1004001 < 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 Spotify__Login5__V3__UserInfo Spotify__Login5__V3__UserInfo; + + +/* --- enums --- */ + +typedef enum _Spotify__Login5__V3__UserInfo__Gender { + SPOTIFY__LOGIN5__V3__USER_INFO__GENDER__UNKNOWN = 0, + SPOTIFY__LOGIN5__V3__USER_INFO__GENDER__MALE = 1, + SPOTIFY__LOGIN5__V3__USER_INFO__GENDER__FEMALE = 2, + SPOTIFY__LOGIN5__V3__USER_INFO__GENDER__NEUTRAL = 3 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__LOGIN5__V3__USER_INFO__GENDER) +} Spotify__Login5__V3__UserInfo__Gender; + +/* --- messages --- */ + +struct Spotify__Login5__V3__UserInfo +{ + ProtobufCMessage base; + char *name; + char *email; + protobuf_c_boolean email_verified; + char *birthdate; + Spotify__Login5__V3__UserInfo__Gender gender; + char *phone_number; + protobuf_c_boolean phone_number_verified; + protobuf_c_boolean email_already_registered; +}; +#define SPOTIFY__LOGIN5__V3__USER_INFO__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__login5__v3__user_info__descriptor) \ + , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, 0, (char *)protobuf_c_empty_string, SPOTIFY__LOGIN5__V3__USER_INFO__GENDER__UNKNOWN, (char *)protobuf_c_empty_string, 0, 0 } + + +/* Spotify__Login5__V3__UserInfo methods */ +void spotify__login5__v3__user_info__init + (Spotify__Login5__V3__UserInfo *message); +size_t spotify__login5__v3__user_info__get_packed_size + (const Spotify__Login5__V3__UserInfo *message); +size_t spotify__login5__v3__user_info__pack + (const Spotify__Login5__V3__UserInfo *message, + uint8_t *out); +size_t spotify__login5__v3__user_info__pack_to_buffer + (const Spotify__Login5__V3__UserInfo *message, + ProtobufCBuffer *buffer); +Spotify__Login5__V3__UserInfo * + spotify__login5__v3__user_info__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__login5__v3__user_info__free_unpacked + (Spotify__Login5__V3__UserInfo *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Spotify__Login5__V3__UserInfo_Closure) + (const Spotify__Login5__V3__UserInfo *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCMessageDescriptor spotify__login5__v3__user_info__descriptor; +extern const ProtobufCEnumDescriptor spotify__login5__v3__user_info__gender__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_login5_5fuser_5finfo_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/login5_user_info.proto b/src/inputs/librespot-c/src/proto/login5_user_info.proto new file mode 100644 index 00000000..f03b69a9 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/login5_user_info.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +package spotify.login5.v3; + +message UserInfo { + string name = 1; + string email = 2; + bool email_verified = 3; + string birthdate = 4; + + Gender gender = 5; + enum Gender { + UNKNOWN = 0; + MALE = 1; + FEMALE = 2; + NEUTRAL = 3; + } + + string phone_number = 6; + bool phone_number_verified = 7; + bool email_already_registered = 8; +} diff --git a/src/inputs/librespot-c/src/proto/mergedprofile.proto b/src/inputs/librespot-c/src/proto/mergedprofile.proto deleted file mode 100644 index e283e1de..00000000 --- a/src/inputs/librespot-c/src/proto/mergedprofile.proto +++ /dev/null @@ -1,10 +0,0 @@ -syntax = "proto2"; - -message MergedProfileRequest { -} - -message MergedProfileReply { - optional string username = 0x1; - optional string artistid = 0x2; -} - diff --git a/src/inputs/librespot-c/src/proto/playlist4changes.proto b/src/inputs/librespot-c/src/proto/playlist4changes.proto deleted file mode 100644 index 6b424b71..00000000 --- a/src/inputs/librespot-c/src/proto/playlist4changes.proto +++ /dev/null @@ -1,87 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/playlist4content.proto b/src/inputs/librespot-c/src/proto/playlist4content.proto deleted file mode 100644 index 50d197fa..00000000 --- a/src/inputs/librespot-c/src/proto/playlist4content.proto +++ /dev/null @@ -1,37 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/playlist4issues.proto b/src/inputs/librespot-c/src/proto/playlist4issues.proto deleted file mode 100644 index 3808d532..00000000 --- a/src/inputs/librespot-c/src/proto/playlist4issues.proto +++ /dev/null @@ -1,43 +0,0 @@ -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; - } -} - diff --git a/src/inputs/librespot-c/src/proto/playlist4meta.proto b/src/inputs/librespot-c/src/proto/playlist4meta.proto deleted file mode 100644 index 4c22a9f0..00000000 --- a/src/inputs/librespot-c/src/proto/playlist4meta.proto +++ /dev/null @@ -1,52 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/playlist4ops.proto b/src/inputs/librespot-c/src/proto/playlist4ops.proto deleted file mode 100644 index dbbfcaa9..00000000 --- a/src/inputs/librespot-c/src/proto/playlist4ops.proto +++ /dev/null @@ -1,103 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/popcount.proto b/src/inputs/librespot-c/src/proto/popcount.proto deleted file mode 100644 index 7a0bac84..00000000 --- a/src/inputs/librespot-c/src/proto/popcount.proto +++ /dev/null @@ -1,13 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/presence.proto b/src/inputs/librespot-c/src/proto/presence.proto deleted file mode 100644 index 5e9be377..00000000 --- a/src/inputs/librespot-c/src/proto/presence.proto +++ /dev/null @@ -1,94 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/pubsub.proto b/src/inputs/librespot-c/src/proto/pubsub.proto deleted file mode 100644 index a781c377..00000000 --- a/src/inputs/librespot-c/src/proto/pubsub.proto +++ /dev/null @@ -1,8 +0,0 @@ -syntax = "proto2"; - -message Subscription { - optional string uri = 0x1; - optional int32 expiry = 0x2; - optional int32 status_code = 0x3; -} - diff --git a/src/inputs/librespot-c/src/proto/radio.proto b/src/inputs/librespot-c/src/proto/radio.proto deleted file mode 100644 index 7a8f3bde..00000000 --- a/src/inputs/librespot-c/src/proto/radio.proto +++ /dev/null @@ -1,58 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/search.proto b/src/inputs/librespot-c/src/proto/search.proto deleted file mode 100644 index 38b717f7..00000000 --- a/src/inputs/librespot-c/src/proto/search.proto +++ /dev/null @@ -1,44 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/social.proto b/src/inputs/librespot-c/src/proto/social.proto deleted file mode 100644 index 58d39a18..00000000 --- a/src/inputs/librespot-c/src/proto/social.proto +++ /dev/null @@ -1,12 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/socialgraph.proto b/src/inputs/librespot-c/src/proto/socialgraph.proto deleted file mode 100644 index 3adc1306..00000000 --- a/src/inputs/librespot-c/src/proto/socialgraph.proto +++ /dev/null @@ -1,49 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/storage_resolve.pb-c.c b/src/inputs/librespot-c/src/proto/storage_resolve.pb-c.c new file mode 100644 index 00000000..461c891b --- /dev/null +++ b/src/inputs/librespot-c/src/proto/storage_resolve.pb-c.c @@ -0,0 +1,149 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: storage_resolve.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "storage_resolve.pb-c.h" +void spotify__download__proto__storage_resolve_response__init + (Spotify__Download__Proto__StorageResolveResponse *message) +{ + static const Spotify__Download__Proto__StorageResolveResponse init_value = SPOTIFY__DOWNLOAD__PROTO__STORAGE_RESOLVE_RESPONSE__INIT; + *message = init_value; +} +size_t spotify__download__proto__storage_resolve_response__get_packed_size + (const Spotify__Download__Proto__StorageResolveResponse *message) +{ + assert(message->base.descriptor == &spotify__download__proto__storage_resolve_response__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__download__proto__storage_resolve_response__pack + (const Spotify__Download__Proto__StorageResolveResponse *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__download__proto__storage_resolve_response__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__download__proto__storage_resolve_response__pack_to_buffer + (const Spotify__Download__Proto__StorageResolveResponse *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__download__proto__storage_resolve_response__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Download__Proto__StorageResolveResponse * + spotify__download__proto__storage_resolve_response__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Download__Proto__StorageResolveResponse *) + protobuf_c_message_unpack (&spotify__download__proto__storage_resolve_response__descriptor, + allocator, len, data); +} +void spotify__download__proto__storage_resolve_response__free_unpacked + (Spotify__Download__Proto__StorageResolveResponse *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__download__proto__storage_resolve_response__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCEnumValue spotify__download__proto__storage_resolve_response__result__enum_values_by_number[3] = +{ + { "CDN", "SPOTIFY__DOWNLOAD__PROTO__STORAGE_RESOLVE_RESPONSE__RESULT__CDN", 0 }, + { "STORAGE", "SPOTIFY__DOWNLOAD__PROTO__STORAGE_RESOLVE_RESPONSE__RESULT__STORAGE", 1 }, + { "RESTRICTED", "SPOTIFY__DOWNLOAD__PROTO__STORAGE_RESOLVE_RESPONSE__RESULT__RESTRICTED", 3 }, +}; +static const ProtobufCIntRange spotify__download__proto__storage_resolve_response__result__value_ranges[] = { +{0, 0},{3, 2},{0, 3} +}; +static const ProtobufCEnumValueIndex spotify__download__proto__storage_resolve_response__result__enum_values_by_name[3] = +{ + { "CDN", 0 }, + { "RESTRICTED", 2 }, + { "STORAGE", 1 }, +}; +const ProtobufCEnumDescriptor spotify__download__proto__storage_resolve_response__result__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "spotify.download.proto.StorageResolveResponse.Result", + "Result", + "Spotify__Download__Proto__StorageResolveResponse__Result", + "spotify.download.proto", + 3, + spotify__download__proto__storage_resolve_response__result__enum_values_by_number, + 3, + spotify__download__proto__storage_resolve_response__result__enum_values_by_name, + 2, + spotify__download__proto__storage_resolve_response__result__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; +static const ProtobufCFieldDescriptor spotify__download__proto__storage_resolve_response__field_descriptors[3] = +{ + { + "result", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(Spotify__Download__Proto__StorageResolveResponse, result), + &spotify__download__proto__storage_resolve_response__result__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "cdnurl", + 2, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_STRING, + offsetof(Spotify__Download__Proto__StorageResolveResponse, n_cdnurl), + offsetof(Spotify__Download__Proto__StorageResolveResponse, cdnurl), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "fileid", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Spotify__Download__Proto__StorageResolveResponse, fileid), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__download__proto__storage_resolve_response__field_indices_by_name[] = { + 1, /* field[1] = cdnurl */ + 2, /* field[2] = fileid */ + 0, /* field[0] = result */ +}; +static const ProtobufCIntRange spotify__download__proto__storage_resolve_response__number_ranges[2 + 1] = +{ + { 1, 0 }, + { 4, 2 }, + { 0, 3 } +}; +const ProtobufCMessageDescriptor spotify__download__proto__storage_resolve_response__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.download.proto.StorageResolveResponse", + "StorageResolveResponse", + "Spotify__Download__Proto__StorageResolveResponse", + "spotify.download.proto", + sizeof(Spotify__Download__Proto__StorageResolveResponse), + 3, + spotify__download__proto__storage_resolve_response__field_descriptors, + spotify__download__proto__storage_resolve_response__field_indices_by_name, + 2, spotify__download__proto__storage_resolve_response__number_ranges, + (ProtobufCMessageInit) spotify__download__proto__storage_resolve_response__init, + NULL,NULL,NULL /* reserved[123] */ +}; diff --git a/src/inputs/librespot-c/src/proto/storage_resolve.pb-c.h b/src/inputs/librespot-c/src/proto/storage_resolve.pb-c.h new file mode 100644 index 00000000..6e739bd0 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/storage_resolve.pb-c.h @@ -0,0 +1,81 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: storage_resolve.proto */ + +#ifndef PROTOBUF_C_storage_5fresolve_2eproto__INCLUDED +#define PROTOBUF_C_storage_5fresolve_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# 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 1004001 < 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 Spotify__Download__Proto__StorageResolveResponse Spotify__Download__Proto__StorageResolveResponse; + + +/* --- enums --- */ + +typedef enum _Spotify__Download__Proto__StorageResolveResponse__Result { + SPOTIFY__DOWNLOAD__PROTO__STORAGE_RESOLVE_RESPONSE__RESULT__CDN = 0, + SPOTIFY__DOWNLOAD__PROTO__STORAGE_RESOLVE_RESPONSE__RESULT__STORAGE = 1, + SPOTIFY__DOWNLOAD__PROTO__STORAGE_RESOLVE_RESPONSE__RESULT__RESTRICTED = 3 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__DOWNLOAD__PROTO__STORAGE_RESOLVE_RESPONSE__RESULT) +} Spotify__Download__Proto__StorageResolveResponse__Result; + +/* --- messages --- */ + +struct Spotify__Download__Proto__StorageResolveResponse +{ + ProtobufCMessage base; + Spotify__Download__Proto__StorageResolveResponse__Result result; + size_t n_cdnurl; + char **cdnurl; + ProtobufCBinaryData fileid; +}; +#define SPOTIFY__DOWNLOAD__PROTO__STORAGE_RESOLVE_RESPONSE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__download__proto__storage_resolve_response__descriptor) \ + , SPOTIFY__DOWNLOAD__PROTO__STORAGE_RESOLVE_RESPONSE__RESULT__CDN, 0,NULL, {0,NULL} } + + +/* Spotify__Download__Proto__StorageResolveResponse methods */ +void spotify__download__proto__storage_resolve_response__init + (Spotify__Download__Proto__StorageResolveResponse *message); +size_t spotify__download__proto__storage_resolve_response__get_packed_size + (const Spotify__Download__Proto__StorageResolveResponse *message); +size_t spotify__download__proto__storage_resolve_response__pack + (const Spotify__Download__Proto__StorageResolveResponse *message, + uint8_t *out); +size_t spotify__download__proto__storage_resolve_response__pack_to_buffer + (const Spotify__Download__Proto__StorageResolveResponse *message, + ProtobufCBuffer *buffer); +Spotify__Download__Proto__StorageResolveResponse * + spotify__download__proto__storage_resolve_response__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__download__proto__storage_resolve_response__free_unpacked + (Spotify__Download__Proto__StorageResolveResponse *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Spotify__Download__Proto__StorageResolveResponse_Closure) + (const Spotify__Download__Proto__StorageResolveResponse *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCMessageDescriptor spotify__download__proto__storage_resolve_response__descriptor; +extern const ProtobufCEnumDescriptor spotify__download__proto__storage_resolve_response__result__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_storage_5fresolve_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/storage_resolve.proto b/src/inputs/librespot-c/src/proto/storage_resolve.proto new file mode 100644 index 00000000..8bee32d8 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/storage_resolve.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package spotify.download.proto; + +message StorageResolveResponse { + Result result = 1; + enum Result { + CDN = 0; + STORAGE = 1; + RESTRICTED = 3; + } + + repeated string cdnurl = 2; + bytes fileid = 4; +} diff --git a/src/inputs/librespot-c/src/proto/suggest.proto b/src/inputs/librespot-c/src/proto/suggest.proto deleted file mode 100644 index ef45f1e2..00000000 --- a/src/inputs/librespot-c/src/proto/suggest.proto +++ /dev/null @@ -1,43 +0,0 @@ -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; -} - diff --git a/src/inputs/librespot-c/src/proto/toplist.proto b/src/inputs/librespot-c/src/proto/toplist.proto deleted file mode 100644 index 1a12159f..00000000 --- a/src/inputs/librespot-c/src/proto/toplist.proto +++ /dev/null @@ -1,6 +0,0 @@ -syntax = "proto2"; - -message Toplist { - repeated string items = 0x1; -} - diff --git a/src/inputs/librespot-c/tests/.gitignore b/src/inputs/librespot-c/tests/.gitignore index a5bce3fd..bae42c55 100644 --- a/src/inputs/librespot-c/tests/.gitignore +++ b/src/inputs/librespot-c/tests/.gitignore @@ -1 +1,2 @@ test1 +test2 diff --git a/src/inputs/librespot-c/tests/Makefile.am b/src/inputs/librespot-c/tests/Makefile.am index 893e0857..b347ed42 100644 --- a/src/inputs/librespot-c/tests/Makefile.am +++ b/src/inputs/librespot-c/tests/Makefile.am @@ -7,4 +7,8 @@ test1_SOURCES = test1.c test1_LDADD = $(top_builddir)/librespot-c.a -lpthread $(TEST_LIBS) test1_CFLAGS = $(TEST_CFLAGS) -check_PROGRAMS = test1 +test2_SOURCES = test2.c +test2_LDADD = $(top_builddir)/librespot-c.a -lpthread $(TEST_LIBS) +test2_CFLAGS = $(TEST_CFLAGS) + +check_PROGRAMS = test1 test2 diff --git a/src/inputs/librespot-c/tests/test1.c b/src/inputs/librespot-c/tests/test1.c index 011f0a09..9f5bec34 100644 --- a/src/inputs/librespot-c/tests/test1.c +++ b/src/inputs/librespot-c/tests/test1.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -75,64 +76,6 @@ logmsg(const char *fmt, ...) va_end(ap); } -static size_t -https_write_cb(char *data, size_t size, size_t nmemb, void *userdata) -{ - char **body; - size_t realsize; - - realsize = size * nmemb; - body = (char **)userdata; - - *body = malloc(realsize + 1); - memcpy(*body, data, realsize); - (*body)[realsize] = 0; - - return realsize; -} - -static int -https_get(char **body, const char *url) -{ - CURL *curl; - CURLcode res; - long response_code; - - curl = curl_easy_init(); - if (!curl) - { - printf("Could not initialize CURL\n"); - goto error; - } - - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, https_write_cb); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, body); - - res = curl_easy_perform(curl); - if (res != CURLE_OK) - { - printf("CURL could not make request (%d)\n", (int)res); - goto error; - } - - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); - if (response_code != 200) - { - printf("HTTP response code %d\n", (int)response_code); - goto error; - } - - curl_easy_cleanup(curl); - - return 0; - - error: - curl_easy_cleanup(curl); - return -1; -} - static int tcp_connect(const char *address, unsigned short port) { @@ -223,7 +166,6 @@ audio_read_cb(int fd, short what, void *arg) struct sp_callbacks callbacks = { - .https_get = https_get, .tcp_connect = tcp_connect, .tcp_disconnect = tcp_disconnect, @@ -241,20 +183,15 @@ main(int argc, char * argv[]) struct sp_credentials credentials; struct sp_metadata metadata; struct event *read_ev; + uint8_t stored_cred[256]; + size_t stored_cred_len; // struct event *stop_ev; // struct timeval tv = { 0 }; int ret; if (argc != 4) { - printf("%s spotify_path username password|token\n", argv[0]); - goto error; - } - - test_file = open("testfile.ogg", O_CREAT | O_RDWR, 0664); - if (test_file < 0) - { - printf("Error opening file: %s\n", strerror(errno)); + printf("%s spotify_path username access_token\n", argv[0]); goto error; } @@ -268,17 +205,14 @@ main(int argc, char * argv[]) goto error; } - if (strlen(argv[3]) < 100) - session = librespotc_login_password(argv[2], argv[3]); - else - session = librespotc_login_token(argv[2], argv[3]); // Length of token should be 194 + session = librespotc_login_token(argv[2], argv[3]); if (!session) { - printf("Error logging in: %s\n", librespotc_last_errmsg()); + printf("Error logging in with token: %s\n", librespotc_last_errmsg()); goto error; } - printf("\n --- Login OK --- \n"); + printf("\n--- Login with token OK ---\n\n"); ret = librespotc_credentials_get(&credentials, session); if (ret < 0) @@ -287,7 +221,30 @@ main(int argc, char * argv[]) goto error; } - printf("Username is %s\n", credentials.username); + printf("=== CREDENTIALS ===\n"); + printf("Username:\n%s\n", credentials.username); + hexdump("Stored credentials:\n", credentials.stored_cred, credentials.stored_cred_len); + printf("===================\n"); + + // "Store" the credentials + stored_cred_len = credentials.stored_cred_len; + if (stored_cred_len > sizeof(stored_cred)) + { + printf("Unexpected length of stored credentials\n"); + goto error; + } + memcpy(stored_cred, credentials.stored_cred, stored_cred_len); + + librespotc_logout(session); + + session = librespotc_login_stored_cred(argv[2], stored_cred, stored_cred_len); + if (!session) + { + printf("Error logging in with stored credentials: %s\n", librespotc_last_errmsg()); + goto error; + } + + printf("\n--- Login with stored credentials OK ---\n\n"); audio_fd = librespotc_open(argv[1], session); if (audio_fd < 0) @@ -312,6 +269,13 @@ main(int argc, char * argv[]) goto error; } + test_file = open("testfile.ogg", O_CREAT | O_RDWR, 0664); + if (test_file < 0) + { + printf("Error opening testfile.ogg: %s\n", strerror(errno)); + goto error; + } + evbase = event_base_new(); audio_buf = evbuffer_new(); @@ -329,14 +293,14 @@ main(int argc, char * argv[]) // event_free(stop_ev); event_free(read_ev); + close(test_file); + evbuffer_free(audio_buf); event_base_free(evbase); librespotc_close(audio_fd); - close(test_file); - librespotc_logout(session); librespotc_deinit(); @@ -344,10 +308,10 @@ main(int argc, char * argv[]) return 0; error: - if (audio_fd >= 0) - librespotc_close(audio_fd); if (test_file >= 0) close(test_file); + if (audio_fd >= 0) + librespotc_close(audio_fd); if (session) librespotc_logout(session); diff --git a/src/inputs/librespot-c/tests/test2.c b/src/inputs/librespot-c/tests/test2.c new file mode 100644 index 00000000..9f8a4e45 --- /dev/null +++ b/src/inputs/librespot-c/tests/test2.c @@ -0,0 +1,283 @@ +#include +#include +#include +#include +#include +#include +#include +#include // for isprint() + +#include +#include +#include + +// For file output +#include +#include + +#include +#include + +#include "librespot-c.h" + +static int audio_fd = -1; +static int test_file = -1; +static struct event_base *evbase; +static struct evbuffer *audio_buf; + +static int total_bytes; + +static void +hexdump(const char *msg, uint8_t *mem, size_t len) +{ + int i, j; + int hexdump_cols = 16; + + if (msg) + printf("%s", msg); + + for (i = 0; i < len + ((len % hexdump_cols) ? (hexdump_cols - len % hexdump_cols) : 0); i++) + { + if(i % hexdump_cols == 0) + printf("0x%06x: ", i); + + if (i < len) + printf("%02x ", 0xFF & ((char*)mem)[i]); + else + printf(" "); + + if (i % hexdump_cols == (hexdump_cols - 1)) + { + for (j = i - (hexdump_cols - 1); j <= i; j++) + { + if (j >= len) + putchar(' '); + else if (isprint(((char*)mem)[j])) + putchar(0xFF & ((char*)mem)[j]); + else + putchar('.'); + } + + putchar('\n'); + } + } +} + +static void +logmsg(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); +} + +static int +tcp_connect(const char *address, unsigned short port) +{ + struct addrinfo hints = { 0 }; + struct addrinfo *servinfo; + struct addrinfo *ptr; + char strport[8]; + int fd; + int ret; + + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = AF_UNSPEC; + + snprintf(strport, sizeof(strport), "%hu", port); + ret = getaddrinfo(address, strport, &hints, &servinfo); + if (ret < 0) + { + printf("Could not connect to %s (port %u): %s\n", address, port, gai_strerror(ret)); + return -1; + } + + for (ptr = servinfo; ptr; ptr = ptr->ai_next) + { + fd = socket(ptr->ai_family, SOCK_STREAM, ptr->ai_protocol); + if (fd < 0) + { + continue; + } + + ret = connect(fd, ptr->ai_addr, ptr->ai_addrlen); + if (ret < 0) + { + close(fd); + continue; + } + + break; + } + + freeaddrinfo(servinfo); + + if (!ptr) + { + printf("Could not connect to '%s' (port %u): %s\n", address, port, strerror(errno)); + return -1; + } + + printf("Connected to %s (port %u)\n", address, port); + + return fd; +} + +static void +tcp_disconnect(int fd) +{ + if (fd < 0) + return; + + close(fd); +} + +static void +progress_cb(int fd, void *arg, size_t received, size_t len) +{ + printf("Progress on fd %d is %zu/%zu\n", fd, received, len); +} + +// This thread +static void +audio_read_cb(int fd, short what, void *arg) +{ + int got; + + got = evbuffer_read(audio_buf, fd, -1); + if (got <= 0) + { + printf("Playback ended (%d)\n", got); + event_base_loopbreak(evbase); + return; + } + + total_bytes += got; + + printf("Got %d bytes of audio, total received is %d bytes\n", got, total_bytes); + + evbuffer_write(audio_buf, test_file); +} + +struct sp_callbacks callbacks = +{ + .tcp_connect = tcp_connect, + .tcp_disconnect = tcp_disconnect, + + .thread_name_set = NULL, + + .hexdump = hexdump, + .logmsg = logmsg, +}; + +int +main(int argc, char * argv[]) +{ + struct sp_session *session = NULL; + struct sp_sysinfo sysinfo = { 0 }; +// struct sp_credentials credentials; + struct sp_metadata metadata; + struct event *read_ev; + FILE *f_stored_cred = NULL; + uint8_t stored_cred[256]; + size_t stored_cred_len; +// struct event *stop_ev; +// struct timeval tv = { 0 }; + int ret; + + if (argc != 4) + { + printf("%s spotify_path username stored_credentials_file\n", argv[0]); + goto error; + } + + snprintf(sysinfo.device_id, sizeof(sysinfo.device_id), "622682995d5c1db29722de8dd85f6c3acd6fc592"); + + ret = librespotc_init(&sysinfo, &callbacks); + if (ret < 0) + { + printf("Error initializing Spotify: %s\n", librespotc_last_errmsg()); + goto error; + } + + f_stored_cred = fopen(argv[3], "rb"); + if (!f_stored_cred) + { + printf("Error opening file with stored credentials\n"); + goto error; + } + + stored_cred_len = fread(stored_cred, 1, sizeof(stored_cred), f_stored_cred); + if (stored_cred_len == 0) + { + printf("Stored credentials file is empty\n"); + goto error; + } + + session = librespotc_login_stored_cred(argv[2], stored_cred, stored_cred_len); + if (!session) + { + printf("Error logging in with stored credentials: %s\n", librespotc_last_errmsg()); + goto error; + } + + printf("\n--- Login with stored credentials OK ---\n\n"); + + audio_fd = librespotc_open(argv[1], session); + if (audio_fd < 0) + { + printf("Error opening file: %s\n", librespotc_last_errmsg()); + goto error; + } + + ret = librespotc_metadata_get(&metadata, audio_fd); + if (ret < 0) + { + printf("Error getting track metadata: %s\n", librespotc_last_errmsg()); + goto error; + } + + printf("File is open, length is %zu\n", metadata.file_len); + + test_file = open("testfile.ogg", O_CREAT | O_RDWR, 0664); + if (test_file < 0) + { + printf("Error opening testfile.ogg: %s\n", strerror(errno)); + goto error; + } + + evbase = event_base_new(); + audio_buf = evbuffer_new(); + + read_ev = event_new(evbase, audio_fd, EV_READ | EV_PERSIST, audio_read_cb, NULL); + event_add(read_ev, NULL); + + librespotc_write(audio_fd, progress_cb, NULL); + +// stop_ev = evtimer_new(evbase, stop, &audio_fd); +// tv.tv_sec = 2; +// event_add(stop_ev, &tv); + + event_base_dispatch(evbase); + +// event_free(stop_ev); + event_free(read_ev); + + close(test_file); + + evbuffer_free(audio_buf); + event_base_free(evbase); + + error: + if (audio_fd >= 0) + librespotc_close(audio_fd); + if (session) + librespotc_logout(session); + if (f_stored_cred) + fclose(f_stored_cred); + + librespotc_deinit(); + return ret; +} diff --git a/src/inputs/spotify.c b/src/inputs/spotify.c index fd3293e4..d070e16e 100644 --- a/src/inputs/spotify.c +++ b/src/inputs/spotify.c @@ -72,14 +72,14 @@ spotify_deinit(void) } int -spotify_login_token(const char *username, const char *token, const char **errmsg) +spotify_login(const char *username, const char *token, const char **errmsg) { struct spotify_backend *backend = backend_set(); - if (!backend || !backend->login_token) + if (!backend || !backend->login) return -1; - return backend->login_token(username, token, errmsg); + return backend->login(username, token, errmsg); } void diff --git a/src/inputs/spotify.h b/src/inputs/spotify.h index 027b04d3..5bfbd06c 100644 --- a/src/inputs/spotify.h +++ b/src/inputs/spotify.h @@ -16,8 +16,7 @@ struct spotify_backend { int (*init)(void); void (*deinit)(void); - int (*login)(const char *username, const char *password, const char **errmsg); - int (*login_token)(const char *username, const char *token, const char **errmsg); + int (*login)(const char *username, const char *token, const char **errmsg); void (*logout)(void); int (*relogin)(void); void (*uri_register)(const char *uri); @@ -31,7 +30,7 @@ void spotify_deinit(void); int -spotify_login_token(const char *username, const char *token, const char **errmsg); +spotify_login(const char *username, const char *token, const char **errmsg); void spotify_logout(void); diff --git a/src/inputs/spotify_librespotc.c b/src/inputs/spotify_librespotc.c index d973bf8a..7b47938e 100644 --- a/src/inputs/spotify_librespotc.c +++ b/src/inputs/spotify_librespotc.c @@ -217,40 +217,6 @@ progress_cb(int fd, void *cb_arg, size_t received, size_t len) DPRINTF(E_SPAM, L_SPOTIFY, "Progress %zu/%zu\n", received, len); } -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, NULL); - if (ret < 0 || ctx.response_code != HTTP_OK) - { - DPRINTF(E_LOG, L_SPOTIFY, "Failed to get 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) { @@ -289,7 +255,6 @@ hexdump_cb(const char *msg, uint8_t *data, size_t data_len) /* ------------------------ librespot-c initialization ---------------------- */ struct sp_callbacks callbacks = { - .https_get = https_get_cb, .tcp_connect = tcp_connect, .tcp_disconnect = tcp_disconnect, @@ -641,40 +606,7 @@ struct input_definition input_spotify = /* Called from other threads than the input thread */ static int -login(const char *username, const char *password, const char **errmsg) -{ - struct global_ctx *ctx = &spotify_ctx; - int ret; - - pthread_mutex_lock(&spotify_ctx_lock); - - ctx->session = librespotc_login_password(username, password); - if (!ctx->session) - goto error; - - ret = postlogin(ctx); - if (ret < 0) - goto error; - - pthread_mutex_unlock(&spotify_ctx_lock); - - return 0; - - error: - if (ctx->session) - librespotc_logout(ctx->session); - ctx->session = NULL; - - if (errmsg) - *errmsg = librespotc_last_errmsg(); - - pthread_mutex_unlock(&spotify_ctx_lock); - - return -1; -} - -static int -login_token(const char *username, const char *token, const char **errmsg) +login(const char *username, const char *token, const char **errmsg) { struct global_ctx *ctx = &spotify_ctx; int ret; @@ -782,7 +714,6 @@ status_get(struct spotify_status *status) struct spotify_backend spotify_librespotc = { .login = login, - .login_token = login_token, .logout = logout, .relogin = relogin, .status_get = status_get, diff --git a/src/library/spotify_webapi.c b/src/library/spotify_webapi.c index 24f825ef..8e8e61b8 100644 --- a/src/library/spotify_webapi.c +++ b/src/library/spotify_webapi.c @@ -2188,7 +2188,7 @@ spotifywebapi_oauth_callback(struct evkeyvalq *param, const char *redirect_uri, if (!code) { *errmsg = "Error: Didn't receive a code from Spotify"; - return -1; + goto error; } DPRINTF(E_DBG, L_SPOTIFY, "Received OAuth code: %s\n", code); @@ -2198,11 +2198,8 @@ spotifywebapi_oauth_callback(struct evkeyvalq *param, const char *redirect_uri, goto error; credentials_user_token_get(&user, &access_token); - ret = spotify_login_token(user, access_token, errmsg); - - free(user); - free(access_token); + ret = spotify_login(user, access_token, errmsg); if (ret < 0) goto error; @@ -2211,9 +2208,13 @@ spotifywebapi_oauth_callback(struct evkeyvalq *param, const char *redirect_uri, listener_notify(LISTENER_SPOTIFY); + free(user); + free(access_token); return 0; error: + free(user); + free(access_token); return -1; }