airplay artwork and CSpot leak fix (temporary)

This commit is contained in:
Philippe G
2022-01-09 19:40:18 -08:00
parent e9da432bfc
commit 3125a095fa
43 changed files with 396 additions and 271 deletions

View File

@@ -2,6 +2,7 @@ idf_component_register(SRC_DIRS . core core/ifaces fonts
INCLUDE_DIRS . fonts core
REQUIRES platform_config tools esp_common
PRIV_REQUIRES services freertos driver
EMBED_FILES note.jpg
)
set_source_files_properties(display.c

View File

@@ -86,7 +86,7 @@ static void SetContrast( struct GDS_Device* Device, uint8_t Contrast ) {
Device->WriteCommand( Device, Contrast );
}
static void SPIParams(int Speed, uint8_t *mode, uint8_t *CS_pre, uint8_t *CS_post) {
static void SPIParams(int Speed, uint8_t *mode, uint16_t *CS_pre, uint8_t *CS_post) {
*CS_post = Speed / (8*1000*1000);
}

View File

@@ -239,6 +239,7 @@ void GDS_SetContrast( struct GDS_Device* Device, uint8_t Contrast ) {
void GDS_SetLayout( struct GDS_Device* Device, bool HFlip, bool VFlip, bool Rotate ) { if (Device->SetLayout) Device->SetLayout( Device, HFlip, VFlip, Rotate ); }
void GDS_SetDirty( struct GDS_Device* Device ) { Device->Dirty = true; }
int GDS_GetWidth( struct GDS_Device* Device ) { return Device ? Device->Width : 0; }
void GDS_SetTextWidth( struct GDS_Device* Device, int TextWidth ) { Device->TextWidth = Device && TextWidth && TextWidth < Device->Width ? TextWidth : Device->Width; }
int GDS_GetHeight( struct GDS_Device* Device ) { return Device ? Device->Height : 0; }
int GDS_GetDepth( struct GDS_Device* Device ) { return Device ? Device->Depth : 0; }
int GDS_GetMode( struct GDS_Device* Device ) { return Device ? Device->Mode : 0; }

View File

@@ -38,6 +38,7 @@ void GDS_Update( struct GDS_Device* Device );
void GDS_SetLayout( struct GDS_Device* Device, bool HFlip, bool VFlip, bool Rotate );
void GDS_SetDirty( struct GDS_Device* Device );
int GDS_GetWidth( struct GDS_Device* Device );
void GDS_SetTextWidth( struct GDS_Device* Device, int TextWidth );
int GDS_GetHeight( struct GDS_Device* Device );
int GDS_GetDepth( struct GDS_Device* Device );
int GDS_GetMode( struct GDS_Device* Device );

View File

@@ -73,13 +73,13 @@ void GDS_FontDrawChar( struct GDS_Device* Device, char Character, int x, int y,
CharStartY+= OffsetY;
/* Do not attempt to draw if this character is entirely offscreen */
if ( CharEndX < 0 || CharStartX >= Device->Width || CharEndY < 0 || CharStartY >= Device->Height ) {
if ( CharEndX < 0 || CharStartX >= Device->TextWidth || CharEndY < 0 || CharStartY >= Device->Height ) {
ClipDebug( x, y );
return;
}
/* Do not attempt to draw past the end of the screen */
CharEndX = ( CharEndX >= Device->Width ) ? Device->Width - 1 : CharEndX;
CharEndX = ( CharEndX >= Device->TextWidth ) ? Device->TextWidth - 1 : CharEndX;
CharEndY = ( CharEndY >= Device->Height ) ? Device->Height - 1 : CharEndY;
Device->Dirty = true;
@@ -146,7 +146,7 @@ int GDS_FontGetCharWidth( struct GDS_Device* Display, char Character ) {
}
int GDS_FontGetMaxCharsPerRow( struct GDS_Device* Display ) {
return Display->Width / Display->Font->Width;
return Display->TextWidth / Display->Font->Width;
}
int GDS_FontGetMaxCharsPerColumn( struct GDS_Device* Display ) {
@@ -210,7 +210,7 @@ void GDS_FontGetAnchoredStringCoords( struct GDS_Device* Display, int* OutX, int
switch ( Anchor ) {
case TextAnchor_East: {
*OutY = ( Display->Height / 2 ) - ( StringHeight / 2 );
*OutX = ( Display->Width - StringWidth );
*OutX = ( Display->TextWidth - StringWidth );
break;
}
@@ -221,19 +221,19 @@ void GDS_FontGetAnchoredStringCoords( struct GDS_Device* Display, int* OutX, int
break;
}
case TextAnchor_North: {
*OutX = ( Display->Width / 2 ) - ( StringWidth / 2 );
*OutX = ( Display->TextWidth / 2 ) - ( StringWidth / 2 );
*OutY = 0;
break;
}
case TextAnchor_South: {
*OutX = ( Display->Width / 2 ) - ( StringWidth / 2 );
*OutX = ( Display->TextWidth / 2 ) - ( StringWidth / 2 );
*OutY = ( Display->Height - StringHeight );
break;
}
case TextAnchor_NorthEast: {
*OutX = ( Display->Width - StringWidth );
*OutX = ( Display->TextWidth - StringWidth );
*OutY = 0;
break;
@@ -246,7 +246,7 @@ void GDS_FontGetAnchoredStringCoords( struct GDS_Device* Display, int* OutX, int
}
case TextAnchor_SouthEast: {
*OutY = ( Display->Height - StringHeight );
*OutX = ( Display->Width - StringWidth );
*OutX = ( Display->TextWidth - StringWidth );
break;
}
@@ -258,7 +258,7 @@ void GDS_FontGetAnchoredStringCoords( struct GDS_Device* Display, int* OutX, int
}
case TextAnchor_Center: {
*OutY = ( Display->Height / 2 ) - ( StringHeight / 2 );
*OutX = ( Display->Width / 2 ) - ( StringWidth / 2 );
*OutX = ( Display->TextWidth / 2 ) - ( StringWidth / 2 );
break;
}

View File

@@ -167,7 +167,7 @@ static unsigned OutHandlerDirect(JDEC *Decoder, void *Bitmap, JRECT *Frame) {
static void* DecodeJPEG(uint8_t *Source, int *Width, int *Height, float Scale, bool SizeOnly, int RGB_Mode) {
JDEC Decoder;
JpegCtx Context;
char *Scratch = calloc(SCRATCH_SIZE, 1);
char *Scratch = malloc(SCRATCH_SIZE);
if (!Scratch) {
ESP_LOGE(TAG, "Cannot allocate workspace");
@@ -372,7 +372,7 @@ bool GDS_DrawJPEG(struct GDS_Device* Device, uint8_t *Source, int x, int y, int
JDEC Decoder;
JpegCtx Context;
bool Ret = false;
char *Scratch = calloc(SCRATCH_SIZE, 1);
char *Scratch = malloc(SCRATCH_SIZE);
if (!Scratch) {
ESP_LOGE(TAG, "Cannot allocate workspace");

View File

@@ -95,7 +95,7 @@ struct GDS_Device {
const struct GDS_FontDef* Font;
} Lines[MAX_LINES];
uint16_t Width;
uint16_t Width, TextWidth;
uint16_t Height;
uint8_t Depth, Mode;
@@ -125,7 +125,7 @@ struct GDS_Device {
void (*DrawRGB)( struct GDS_Device* Device, uint8_t *Image,int x, int y, int Width, int Height, int RGB_Mode );
void (*ClearWindow)( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int Color );
// may provide for tweaking
void (*SPIParams)(int Speed, uint8_t *mode, uint8_t *CS_pre, uint8_t *CS_post);
void (*SPIParams)(int Speed, uint8_t *mode, uint16_t *CS_pre, uint8_t *CS_post);
// interface-specific methods
WriteCommandProc WriteCommand;

View File

@@ -100,13 +100,13 @@ bool GDS_TextLine(struct GDS_Device* Device, int N, int Pos, int Attr, char *Tex
Width = GDS_FontMeasureString( Device, Text );
// adjusting position, erase only EoL for rigth-justified
if (Pos == GDS_TEXT_RIGHT) X = Device->Width - Width - 1;
else if (Pos == GDS_TEXT_CENTER) X = (Device->Width - Width) / 2;
if (Pos == GDS_TEXT_RIGHT) X = Device->TextWidth - Width - 1;
else if (Pos == GDS_TEXT_CENTER) X = (Device->TextWidth - Width) / 2;
// erase if requested
if (Attr & GDS_TEXT_CLEAR) {
int Y_min = max(0, Device->Lines[N].Y), Y_max = max(0, Device->Lines[N].Y + Device->Lines[N].Font->Height);
for (int c = (Attr & GDS_TEXT_CLEAR_EOL) ? X : 0; c < Device->Width; c++)
for (int c = (Attr & GDS_TEXT_CLEAR_EOL) ? X : 0; c < Device->TextWidth; c++)
for (int y = Y_min; y < Y_max; y++)
DrawPixelFast( Device, c, y, GDS_COLOR_BLACK );
}
@@ -119,7 +119,7 @@ bool GDS_TextLine(struct GDS_Device* Device, int N, int Pos, int Attr, char *Tex
Device->Dirty = true;
if (Attr & GDS_TEXT_UPDATE) GDS_Update( Device );
return Width + X < Device->Width;
return Width + X < Device->TextWidth;
}
/****************************************************************************************
@@ -146,7 +146,7 @@ int GDS_TextStretch(struct GDS_Device* Device, int N, char *String, int Max) {
// we might already fit
GDS_SetFont( Device, Device->Lines[N].Font );
if (GDS_FontMeasureString( Device, String ) <= Device->Width) return 0;
if (GDS_FontMeasureString( Device, String ) <= Device->TextWidth) return 0;
// add some space for better visual
strncat(String, Space, Max-Len);
@@ -157,7 +157,7 @@ int GDS_TextStretch(struct GDS_Device* Device, int N, char *String, int Max) {
Boundary = GDS_FontMeasureString( Device, String );
// add a full display width
while (Len < Max && GDS_FontMeasureString( Device, String ) - Boundary < Device->Width) {
while (Len < Max && GDS_FontMeasureString( Device, String ) - Boundary < Device->TextWidth) {
String[Len++] = String[Extra++];
String[Len] = '\0';
}

View File

@@ -75,7 +75,7 @@ bool GDS_I2CAttachDevice( struct GDS_Device* Device, int Width, int Height, int
Device->RSTPin = RSTPin;
Device->Backlight.Pin = BacklightPin;
Device->IF = GDS_IF_I2C;
Device->Width = Width;
Device->Width = Device->TextWidth = Width;
Device->Height = Height;
if ( RSTPin >= 0 ) {

View File

@@ -35,7 +35,7 @@ bool GDS_SPIInit( int SPI, int DC ) {
}
bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int CSPin, int RSTPin, int BackLightPin, int Speed ) {
spi_device_interface_config_t SPIDeviceConfig;
spi_device_interface_config_t SPIDeviceConfig = { };
spi_device_handle_t SPIDevice;
NullCheck( Device, return false );
@@ -45,8 +45,6 @@ bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( CSPin, 0 ), return false );
}
memset( &SPIDeviceConfig, 0, sizeof( spi_device_interface_config_t ) );
SPIDeviceConfig.clock_speed_hz = Speed > 0 ? Speed : SPI_MASTER_FREQ_8M;
SPIDeviceConfig.spics_io_num = CSPin;
SPIDeviceConfig.queue_size = 1;
@@ -63,7 +61,7 @@ bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int
Device->CSPin = CSPin;
Device->Backlight.Pin = BackLightPin;
Device->IF = GDS_IF_SPI;
Device->Width = Width;
Device->Width = Device->TextWidth = Width;
Device->Height = Height;
if ( RSTPin >= 0 ) {

View File

@@ -20,6 +20,7 @@
#include "gds_draw.h"
#include "gds_text.h"
#include "gds_font.h"
#include "gds_image.h"
static const char *TAG = "display";
@@ -30,6 +31,9 @@ static const char *TAG = "display";
#define SCROLLABLE_SIZE 384
#define HEADER_SIZE 64
#define DEFAULT_SLEEP 3600
#define ARTWORK_BORDER 1
extern const uint8_t default_artwork[] asm("_binary_note_jpg_start");
static EXT_RAM_ATTR struct {
TaskHandle_t task;
@@ -47,6 +51,12 @@ static EXT_RAM_ATTR struct {
char string[8]; // H:MM:SS
bool visible;
} duration;
struct {
bool enable, fit;
bool updated;
int tick;
int offset;
} artwork;
TickType_t tick;
} displayer;
@@ -147,6 +157,14 @@ void display_init(char *welcome) {
GDS_TextSetFontAuto(display, 2, GDS_FONT_LINE_2, -3);
displayer.metadata_config = config_alloc_get(NVS_TYPE_STR, "metadata_config");
// leave room for artwork is display is horizontal-style
if (strcasestr(displayer.metadata_config, "artwork")) {
displayer.artwork.enable = true;
displayer.artwork.fit = true;
if (height <= 64 && width > height * 2) displayer.artwork.offset = width - height - ARTWORK_BORDER;
PARSE_PARAM(displayer.metadata_config, "artwork", ':', displayer.artwork.fit);
}
}
free(config);
@@ -226,6 +244,11 @@ static void displayer_task(void *args) {
GDS_TextLine(display, 1, GDS_TEXT_LEFT, GDS_TEXT_CLEAR, displayer.header);
GDS_TextLine(display, 1, GDS_TEXT_RIGHT, GDS_TEXT_UPDATE, _line);
// if we have not received artwork after 5s, display a default icon
if (displayer.artwork.enable && !displayer.artwork.updated && tick - displayer.artwork.tick > pdMS_TO_TICKS(5000)) {
ESP_LOGI(TAG, "no artwork received, setting default");
displayer_artwork((uint8_t*) default_artwork);
}
timer_sleep = 1000;
} else timer_sleep = max(1000 - elapsed, 0);
} else timer_sleep = DEFAULT_SLEEP;
@@ -238,6 +261,25 @@ static void displayer_task(void *args) {
}
}
/****************************************************************************************
*
*/
void displayer_artwork(uint8_t *data) {
if (!displayer.artwork.enable) return;
int x = displayer.artwork.offset ? displayer.artwork.offset + ARTWORK_BORDER : 0;
int y = x ? 0 : 32;
GDS_ClearWindow(display, x, y, -1, -1, GDS_COLOR_BLACK);
if (data) {
displayer.artwork.updated = true;
GDS_DrawJPEG(display, data, x, y, GDS_IMAGE_CENTER | (displayer.artwork.fit ? GDS_IMAGE_FIT : 0));
} else {
displayer.artwork.updated = false;
displayer.artwork.tick = xTaskGetTickCount();
}
}
/****************************************************************************************
*
*/
@@ -378,6 +420,7 @@ void displayer_control(enum displayer_cmd_e cmd, ...) {
switch(cmd) {
case DISPLAYER_ACTIVATE: {
char *header = va_arg(args, char*);
bool artwork = va_arg(args, int);
strncpy(displayer.header, header, HEADER_SIZE);
displayer.header[HEADER_SIZE] = '\0';
displayer.state = DISPLAYER_ACTIVE;
@@ -388,6 +431,7 @@ void displayer_control(enum displayer_cmd_e cmd, ...) {
displayer.duration.visible = false;
displayer.offset = displayer.boundary = 0;
display_bus(&displayer, DISPLAY_BUS_TAKE);
if (artwork) GDS_SetTextWidth(display, displayer.artwork.offset);
vTaskResume(displayer.task);
break;
}
@@ -398,6 +442,8 @@ void displayer_control(enum displayer_cmd_e cmd, ...) {
break;
case DISPLAYER_SHUTDOWN:
// let the task self-suspend (we might be doing i2c_write)
GDS_SetTextWidth(display, 0);
GDS_Clear(display, GDS_COLOR_BLACK);
displayer.state = DISPLAYER_DOWN;
display_bus(&displayer, DISPLAY_BUS_GIVE);
break;

View File

@@ -38,5 +38,6 @@ bool display_is_valid_driver(const char * driver);
void displayer_scroll(char *string, int speed, int pause);
void displayer_control(enum displayer_cmd_e cmd, ...);
void displayer_metadata(char *artist, char *album, char *title);
void displayer_artwork(uint8_t *data);
void displayer_timer(enum displayer_time_e mode, int elapsed, int duration);
char * display_get_supported_drivers(void);

BIN
components/display/note.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -172,7 +172,7 @@ static bool cmd_handler(bt_sink_cmd_t cmd, ...) {
// now handle events for display
switch(cmd) {
case BT_SINK_AUDIO_STARTED:
displayer_control(DISPLAYER_ACTIVATE, "BLUETOOTH");
displayer_control(DISPLAYER_ACTIVATE, "BLUETOOTH", false);
break;
case BT_SINK_AUDIO_STOPPED:
displayer_control(DISPLAYER_SUSPEND);

View File

@@ -628,6 +628,9 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
LOG_INFO("[%p]: received metadata", ctx);
settings.ctx = &metadata;
memset(&metadata, 0, sizeof(struct metadata_s));
if (!dmap_parse(&settings, body, len)) {
LOG_INFO("[%p]: received metadata\n\tartist: %s\n\talbum: %s\n\ttitle: %s",
ctx, metadata.artist, metadata.album, metadata.title);
success = ctx->cmd_cb(RAOP_METADATA, metadata.artist, metadata.album, metadata.title);
free_metadata(&metadata);
}

View File

@@ -112,7 +112,7 @@ static bool cmd_handler(raop_event_t event, ...) {
switch(event) {
case RAOP_SETUP:
actrls_set(controls, false, NULL, actrls_ir_action);
displayer_control(DISPLAYER_ACTIVATE, "AIRPLAY");
displayer_control(DISPLAYER_ACTIVATE, "AIRPLAY", true);
break;
case RAOP_PLAY:
displayer_control(DISPLAYER_TIMER_RUN);
@@ -127,6 +127,12 @@ static bool cmd_handler(raop_event_t event, ...) {
case RAOP_METADATA: {
char *artist = va_arg(args, char*), *album = va_arg(args, char*), *title = va_arg(args, char*);
displayer_metadata(artist, album, title);
displayer_artwork(NULL);
break;
}
case RAOP_ARTWORK: {
uint8_t *data = va_arg(args, uint8_t*);
displayer_artwork(data);
break;
}
case RAOP_PROGRESS: {

View File

@@ -14,7 +14,7 @@
#define RAOP_SAMPLE_RATE 44100
typedef enum { RAOP_SETUP, RAOP_STREAM, RAOP_PLAY, RAOP_FLUSH, RAOP_METADATA, RAOP_PROGRESS, RAOP_PAUSE, RAOP_STOP,
typedef enum { RAOP_SETUP, RAOP_STREAM, RAOP_PLAY, RAOP_FLUSH, RAOP_METADATA, RAOP_ARTWORK, RAOP_PROGRESS, RAOP_PAUSE, RAOP_STOP,
RAOP_VOLUME, RAOP_TIMING, RAOP_PREV, RAOP_NEXT, RAOP_REW, RAOP_FWD,
RAOP_VOLUME_UP, RAOP_VOLUME_DOWN, RAOP_RESUME, RAOP_TOGGLE } raop_event_t ;

View File

@@ -120,7 +120,8 @@ static void cspotTask(void *pvParameters) {
case CSpotEventType::TRACK_INFO: {
TrackInfo track = std::get<TrackInfo>(event.data);
// duration is in chunks of 0.5 ms
cspot.cHandler(CSPOT_TRACK, 44100, track.duration / 2, track.artist.c_str(), track.album.c_str(), track.name.c_str());
cspot.cHandler(CSPOT_TRACK, 44100, track.duration / 2, track.artist.c_str(),
track.album.c_str(), track.name.c_str(), track.imageUrl.c_str());
break;
}
case CSpotEventType::PLAY_PAUSE: {

View File

@@ -45,5 +45,6 @@ endif()
add_library(cspot STATIC ${SOURCES} ${PROTO_SRCS})
# PUBLIC to propagate includes from bell to cspot dependents
target_compile_definitions(bell PUBLIC PB_ENABLE_MALLOC)
target_compile_definitions(bell PUBLIC PB_FIELD_32BIT)
target_link_libraries(cspot PUBLIC ${EXTRA_LIBS})
target_include_directories(cspot PUBLIC "include" ${GENERATED_INCLUDES} ${NANOPB_INCLUDE_DIRS})

View File

@@ -7,8 +7,6 @@ option(BELL_DISABLE_CODECS "Disable libhelix AAC and MP3 codecs" OFF)
#set(BELL_EXTERNAL_CJSON "" CACHE STRING "External cJSON library target name, optional")
#set(BELL_EXTERNAL_TREMOR "" CACHE STRING "External tremor library target name, optional")
add_definitions(-DPB_ENABLE_MALLOC)
# Include nanoPB library
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/nanopb/extra)
find_package(Nanopb REQUIRED)
@@ -98,3 +96,4 @@ message(${NANOPB_INCLUDE_DIRS})
# PUBLIC to propagate esp-idf includes to bell dependents
target_link_libraries(bell PUBLIC ${EXTRA_LIBS})
target_include_directories(bell PUBLIC "include" ${EXTRA_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR})
target_compile_definitions(bell PUBLIC PB_ENABLE_MALLOC)

View File

@@ -42,6 +42,10 @@ void pbDecode(T &result, const pb_msgdesc_t *fields, std::vector<uint8_t> &data)
}
}
void pbPutString(const std::string &stringToPack, char* dst);
void pbPutCharArray(const char * stringToPack, char* dst);
void pbPutBytes(const std::vector<uint8_t> &data, pb_bytes_array_t &dst);
const char* pb_encode_to_string(const pb_msgdesc_t *fields, const void *data);
pb_istream_t pb_istream_from_http(bell::HTTPClient::HTTPResponse *response, size_t length = 0);

View File

@@ -47,6 +47,22 @@ pb_bytes_array_t* vectorToPbArray(const std::vector<uint8_t>& vectorToPack)
return result;
}
void pbPutString(const std::string &stringToPack, char* dst) {
stringToPack.copy(dst, stringToPack.size());
dst[stringToPack.size()] = '\0';
}
void pbPutCharArray(const char * stringToPack, char* dst) {
// copy stringToPack into dst
strcpy(dst, stringToPack);
//dst[sizeof(stringToPack)-1] = '\0';
}
void pbPutBytes(const std::vector<uint8_t> &data, pb_bytes_array_t &dst) {
dst.size = data.size();
std::copy(data.begin(), data.end(), dst.bytes);
}
std::vector<uint8_t> pbArrayToVector(pb_bytes_array_t* pbArray) {
return std::vector<uint8_t>(pbArray->bytes, pbArray->bytes + pbArray->size);
}

View File

@@ -9,7 +9,7 @@ class Packet
private:
public:
Packet(uint8_t command, std::vector<uint8_t> &data);
Packet(uint8_t command, const std::vector<uint8_t> &data);
uint8_t command;
std::vector<uint8_t> data;
};

View File

@@ -1,6 +1,5 @@
LoginCredentials.username type:FT_POINTER
LoginCredentials.auth_data type:FT_POINTER
LoginCredentials.auth_data type:FT_POINTER
SystemInfo.system_information_string type:FT_POINTER
SystemInfo.device_id type:FT_POINTER
ClientResponseEncrypted.version_string type:FT_POINTER
LoginCredentials.username max_size:30, fixed_length:false
LoginCredentials.auth_data max_size:512, fixed_length:false
SystemInfo.system_information_string max_size:16, fixed_length:false
SystemInfo.device_id max_size:50, fixed_length:false
ClientResponseEncrypted.version_string max_size:32, fixed_length:false

View File

@@ -9,7 +9,7 @@
PB_BIND(SystemInfo, SystemInfo, 2)
PB_BIND(LoginCredentials, LoginCredentials, AUTO)
PB_BIND(LoginCredentials, LoginCredentials, 2)
PB_BIND(ClientResponseEncrypted, ClientResponseEncrypted, 2)

View File

@@ -58,23 +58,25 @@ typedef enum _AuthenticationType {
} AuthenticationType;
/* Struct definitions */
typedef PB_BYTES_ARRAY_T(512) LoginCredentials_auth_data_t;
typedef struct _LoginCredentials {
char *username;
char username[30];
AuthenticationType typ;
pb_bytes_array_t *auth_data;
LoginCredentials_auth_data_t auth_data;
} LoginCredentials;
typedef struct _SystemInfo {
CpuFamily cpu_family;
Os os;
char *system_information_string;
char *device_id;
char system_information_string[16];
char device_id[50];
} SystemInfo;
typedef struct _ClientResponseEncrypted {
LoginCredentials login_credentials;
SystemInfo system_info;
char *version_string;
bool has_version_string;
char version_string[32];
} ClientResponseEncrypted;
@@ -97,12 +99,12 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define SystemInfo_init_default {_CpuFamily_MIN, _Os_MIN, NULL, NULL}
#define LoginCredentials_init_default {NULL, _AuthenticationType_MIN, NULL}
#define ClientResponseEncrypted_init_default {LoginCredentials_init_default, SystemInfo_init_default, NULL}
#define SystemInfo_init_zero {_CpuFamily_MIN, _Os_MIN, NULL, NULL}
#define LoginCredentials_init_zero {NULL, _AuthenticationType_MIN, NULL}
#define ClientResponseEncrypted_init_zero {LoginCredentials_init_zero, SystemInfo_init_zero, NULL}
#define SystemInfo_init_default {_CpuFamily_MIN, _Os_MIN, "", ""}
#define LoginCredentials_init_default {"", _AuthenticationType_MIN, {0, {0}}}
#define ClientResponseEncrypted_init_default {LoginCredentials_init_default, SystemInfo_init_default, false, ""}
#define SystemInfo_init_zero {_CpuFamily_MIN, _Os_MIN, "", ""}
#define LoginCredentials_init_zero {"", _AuthenticationType_MIN, {0, {0}}}
#define ClientResponseEncrypted_init_zero {LoginCredentials_init_zero, SystemInfo_init_zero, false, ""}
/* Field tags (for use in manual encoding/decoding) */
#define LoginCredentials_username_tag 10
@@ -120,22 +122,22 @@ extern "C" {
#define SystemInfo_FIELDLIST(X, a) \
X(a, STATIC, REQUIRED, UENUM, cpu_family, 10) \
X(a, STATIC, REQUIRED, UENUM, os, 60) \
X(a, POINTER, OPTIONAL, STRING, system_information_string, 90) \
X(a, POINTER, OPTIONAL, STRING, device_id, 100)
X(a, STATIC, REQUIRED, STRING, system_information_string, 90) \
X(a, STATIC, REQUIRED, STRING, device_id, 100)
#define SystemInfo_CALLBACK NULL
#define SystemInfo_DEFAULT NULL
#define LoginCredentials_FIELDLIST(X, a) \
X(a, POINTER, OPTIONAL, STRING, username, 10) \
X(a, STATIC, REQUIRED, STRING, username, 10) \
X(a, STATIC, REQUIRED, UENUM, typ, 20) \
X(a, POINTER, OPTIONAL, BYTES, auth_data, 30)
X(a, STATIC, REQUIRED, BYTES, auth_data, 30)
#define LoginCredentials_CALLBACK NULL
#define LoginCredentials_DEFAULT NULL
#define ClientResponseEncrypted_FIELDLIST(X, a) \
X(a, STATIC, REQUIRED, MESSAGE, login_credentials, 10) \
X(a, STATIC, REQUIRED, MESSAGE, system_info, 50) \
X(a, POINTER, OPTIONAL, STRING, version_string, 70)
X(a, STATIC, OPTIONAL, STRING, version_string, 70)
#define ClientResponseEncrypted_CALLBACK NULL
#define ClientResponseEncrypted_DEFAULT NULL
#define ClientResponseEncrypted_login_credentials_MSGTYPE LoginCredentials
@@ -151,9 +153,9 @@ extern const pb_msgdesc_t ClientResponseEncrypted_msg;
#define ClientResponseEncrypted_fields &ClientResponseEncrypted_msg
/* Maximum encoded size of messages (where known) */
/* SystemInfo_size depends on runtime parameters */
/* LoginCredentials_size depends on runtime parameters */
/* ClientResponseEncrypted_size depends on runtime parameters */
#define ClientResponseEncrypted_size 665
#define LoginCredentials_size 550
#define SystemInfo_size 75
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -48,14 +48,14 @@ enum AuthenticationType {
message SystemInfo {
required CpuFamily cpu_family = 0xa;
required Os os = 0x3c;
optional string system_information_string = 0x5a;
optional string device_id = 0x64;
required string system_information_string = 0x5a;
required string device_id = 0x64;
}
message LoginCredentials {
optional string username = 0xa;
required string username = 0xa;
required AuthenticationType typ = 0x14;
optional bytes auth_data = 0x1e;
required bytes auth_data = 0x1e;
}
message ClientResponseEncrypted {

View File

@@ -1,2 +1,2 @@
Header.uri type:FT_POINTER
Header.method type:FT_POINTER
Header.uri max_size:64, fixed_length:false
Header.method max_size:32, fixed_length:false

View File

@@ -11,8 +11,10 @@
/* Struct definitions */
typedef struct _Header {
char *uri;
char *method;
bool has_uri;
char uri[64];
bool has_method;
char method[32];
} Header;
@@ -21,8 +23,8 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define Header_init_default {NULL, NULL}
#define Header_init_zero {NULL, NULL}
#define Header_init_default {false, "", false, ""}
#define Header_init_zero {false, "", false, ""}
/* Field tags (for use in manual encoding/decoding) */
#define Header_uri_tag 1
@@ -30,8 +32,8 @@ extern "C" {
/* Struct field encoding specification for nanopb */
#define Header_FIELDLIST(X, a) \
X(a, POINTER, OPTIONAL, STRING, uri, 1) \
X(a, POINTER, OPTIONAL, STRING, method, 3)
X(a, STATIC, OPTIONAL, STRING, uri, 1) \
X(a, STATIC, OPTIONAL, STRING, method, 3)
#define Header_CALLBACK NULL
#define Header_DEFAULT NULL
@@ -41,7 +43,7 @@ extern const pb_msgdesc_t Header_msg;
#define Header_fields &Header_msg
/* Maximum encoded size of messages (where known) */
/* Header_size depends on runtime parameters */
#define Header_size 98
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -1,18 +1,16 @@
Track.name type:FT_POINTER
Track.gid type:FT_POINTER
Track.restriction type:FT_POINTER
Track.alternative type:FT_POINTER
Track.file type:FT_POINTER
Track.artist type:FT_POINTER
AudioFile.file_id type:FT_POINTER
Image.file_id type:FT_POINTER
Artist.gid type:FT_POINTER
Artist.name type:FT_POINTER
Album.name type:FT_POINTER
Episode.gid type:FT_POINTER
Episode.name type:FT_POINTER
ImageGroup.image type:FT_POINTER
Episode.audio type:FT_POINTER
Episode.covers type:FT_POINTER
Restriction.countries_allowed type:FT_POINTER
Restriction.countries_forbidden type:FT_POINTER
Track.name max_size: 512
Track.gid max_size: 64
Track.file max_count: 16
Track.artist max_count: 8
AudioFile.file_id max_size: 128
Image.file_id max_size: 128
Artist.gid max_size: 128
Artist.name max_size: 512
Album.name max_size: 512
Episode.gid max_size: 64
Episode.name max_size: 512
ImageGroup.image max_count: 10
Episode.audio max_count: 10
Episode.covers max_count: 10
Restriction.countries_allowed max_size: 32
Restriction.countries_forbidden max_size: 32

View File

@@ -15,16 +15,16 @@ PB_BIND(Restriction, Restriction, AUTO)
PB_BIND(Image, Image, AUTO)
PB_BIND(ImageGroup, ImageGroup, AUTO)
PB_BIND(ImageGroup, ImageGroup, 2)
PB_BIND(Album, Album, AUTO)
PB_BIND(Album, Album, 2)
PB_BIND(Artist, Artist, AUTO)
PB_BIND(Artist, Artist, 2)
PB_BIND(Track, Track, AUTO)
PB_BIND(Track, Track, 4)
PB_BIND(Episode, Episode, 2)

View File

@@ -24,63 +24,78 @@ typedef enum _AudioFormat {
} AudioFormat;
/* Struct definitions */
typedef PB_BYTES_ARRAY_T(128) Artist_gid_t;
typedef struct _Artist {
pb_bytes_array_t *gid;
char *name;
bool has_gid;
Artist_gid_t gid;
bool has_name;
char name[512];
} Artist;
typedef struct _Image {
pb_bytes_array_t *file_id;
} Image;
typedef struct _ImageGroup {
pb_size_t image_count;
struct _Image *image;
} ImageGroup;
typedef struct _Restriction {
char *countries_allowed;
char *countries_forbidden;
} Restriction;
typedef struct _Album {
pb_callback_t gid;
char *name;
bool has_cover_group;
ImageGroup cover_group;
} Album;
typedef PB_BYTES_ARRAY_T(128) AudioFile_file_id_t;
typedef struct _AudioFile {
pb_bytes_array_t *file_id;
bool has_file_id;
AudioFile_file_id_t file_id;
bool has_format;
AudioFormat format;
} AudioFile;
typedef PB_BYTES_ARRAY_T(128) Image_file_id_t;
typedef struct _Image {
bool has_file_id;
Image_file_id_t file_id;
} Image;
typedef struct _Restriction {
bool has_countries_allowed;
char countries_allowed[32];
bool has_countries_forbidden;
char countries_forbidden[32];
} Restriction;
typedef struct _ImageGroup {
pb_size_t image_count;
Image image[10];
} ImageGroup;
typedef struct _Album {
pb_callback_t gid;
bool has_name;
char name[512];
bool has_cover_group;
ImageGroup cover_group;
} Album;
typedef PB_BYTES_ARRAY_T(64) Episode_gid_t;
typedef struct _Episode {
pb_bytes_array_t *gid;
char *name;
bool has_gid;
Episode_gid_t gid;
bool has_name;
char name[512];
bool has_duration;
int32_t duration;
pb_size_t audio_count;
struct _AudioFile *audio;
struct _ImageGroup *covers;
AudioFile audio[10];
bool has_covers;
ImageGroup covers;
} Episode;
typedef PB_BYTES_ARRAY_T(64) Track_gid_t;
typedef struct _Track {
pb_bytes_array_t *gid;
char *name;
bool has_gid;
Track_gid_t gid;
bool has_name;
char name[512];
bool has_album;
Album album;
pb_size_t artist_count;
struct _Artist *artist;
Artist artist[8];
bool has_duration;
int32_t duration;
pb_size_t restriction_count;
struct _Restriction *restriction;
pb_callback_t restriction;
pb_size_t file_count;
struct _AudioFile *file;
pb_size_t alternative_count;
struct _Track *alternative;
AudioFile file[16];
pb_callback_t alternative;
} Track;
@@ -95,35 +110,35 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define AudioFile_init_default {NULL, false, _AudioFormat_MIN}
#define Restriction_init_default {NULL, NULL}
#define Image_init_default {NULL}
#define ImageGroup_init_default {0, NULL}
#define Album_init_default {{{NULL}, NULL}, NULL, false, ImageGroup_init_default}
#define Artist_init_default {NULL, NULL}
#define Track_init_default {NULL, NULL, false, Album_init_default, 0, NULL, false, 0, 0, NULL, 0, NULL, 0, NULL}
#define Episode_init_default {NULL, NULL, false, 0, 0, NULL, NULL}
#define AudioFile_init_zero {NULL, false, _AudioFormat_MIN}
#define Restriction_init_zero {NULL, NULL}
#define Image_init_zero {NULL}
#define ImageGroup_init_zero {0, NULL}
#define Album_init_zero {{{NULL}, NULL}, NULL, false, ImageGroup_init_zero}
#define Artist_init_zero {NULL, NULL}
#define Track_init_zero {NULL, NULL, false, Album_init_zero, 0, NULL, false, 0, 0, NULL, 0, NULL, 0, NULL}
#define Episode_init_zero {NULL, NULL, false, 0, 0, NULL, NULL}
#define AudioFile_init_default {false, {0, {0}}, false, _AudioFormat_MIN}
#define Restriction_init_default {false, "", false, ""}
#define Image_init_default {false, {0, {0}}}
#define ImageGroup_init_default {0, {Image_init_default, Image_init_default, Image_init_default, Image_init_default, Image_init_default, Image_init_default, Image_init_default, Image_init_default, Image_init_default, Image_init_default}}
#define Album_init_default {{{NULL}, NULL}, false, "", false, ImageGroup_init_default}
#define Artist_init_default {false, {0, {0}}, false, ""}
#define Track_init_default {false, {0, {0}}, false, "", false, Album_init_default, 0, {Artist_init_default, Artist_init_default, Artist_init_default, Artist_init_default, Artist_init_default, Artist_init_default, Artist_init_default, Artist_init_default}, false, 0, {{NULL}, NULL}, 0, {AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default}, {{NULL}, NULL}}
#define Episode_init_default {false, {0, {0}}, false, "", false, 0, 0, {AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default, AudioFile_init_default}, false, ImageGroup_init_default}
#define AudioFile_init_zero {false, {0, {0}}, false, _AudioFormat_MIN}
#define Restriction_init_zero {false, "", false, ""}
#define Image_init_zero {false, {0, {0}}}
#define ImageGroup_init_zero {0, {Image_init_zero, Image_init_zero, Image_init_zero, Image_init_zero, Image_init_zero, Image_init_zero, Image_init_zero, Image_init_zero, Image_init_zero, Image_init_zero}}
#define Album_init_zero {{{NULL}, NULL}, false, "", false, ImageGroup_init_zero}
#define Artist_init_zero {false, {0, {0}}, false, ""}
#define Track_init_zero {false, {0, {0}}, false, "", false, Album_init_zero, 0, {Artist_init_zero, Artist_init_zero, Artist_init_zero, Artist_init_zero, Artist_init_zero, Artist_init_zero, Artist_init_zero, Artist_init_zero}, false, 0, {{NULL}, NULL}, 0, {AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero}, {{NULL}, NULL}}
#define Episode_init_zero {false, {0, {0}}, false, "", false, 0, 0, {AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero, AudioFile_init_zero}, false, ImageGroup_init_zero}
/* Field tags (for use in manual encoding/decoding) */
#define Artist_gid_tag 1
#define Artist_name_tag 2
#define AudioFile_file_id_tag 1
#define AudioFile_format_tag 2
#define Image_file_id_tag 1
#define ImageGroup_image_tag 1
#define Restriction_countries_allowed_tag 2
#define Restriction_countries_forbidden_tag 3
#define ImageGroup_image_tag 1
#define Album_gid_tag 1
#define Album_name_tag 2
#define Album_cover_group_tag 17
#define AudioFile_file_id_tag 1
#define AudioFile_format_tag 2
#define Episode_gid_tag 1
#define Episode_name_tag 2
#define Episode_duration_tag 7
@@ -140,52 +155,52 @@ extern "C" {
/* Struct field encoding specification for nanopb */
#define AudioFile_FIELDLIST(X, a) \
X(a, POINTER, OPTIONAL, BYTES, file_id, 1) \
X(a, STATIC, OPTIONAL, BYTES, file_id, 1) \
X(a, STATIC, OPTIONAL, UENUM, format, 2)
#define AudioFile_CALLBACK NULL
#define AudioFile_DEFAULT NULL
#define Restriction_FIELDLIST(X, a) \
X(a, POINTER, OPTIONAL, STRING, countries_allowed, 2) \
X(a, POINTER, OPTIONAL, STRING, countries_forbidden, 3)
X(a, STATIC, OPTIONAL, STRING, countries_allowed, 2) \
X(a, STATIC, OPTIONAL, STRING, countries_forbidden, 3)
#define Restriction_CALLBACK NULL
#define Restriction_DEFAULT NULL
#define Image_FIELDLIST(X, a) \
X(a, POINTER, OPTIONAL, BYTES, file_id, 1)
X(a, STATIC, OPTIONAL, BYTES, file_id, 1)
#define Image_CALLBACK NULL
#define Image_DEFAULT NULL
#define ImageGroup_FIELDLIST(X, a) \
X(a, POINTER, REPEATED, MESSAGE, image, 1)
X(a, STATIC, REPEATED, MESSAGE, image, 1)
#define ImageGroup_CALLBACK NULL
#define ImageGroup_DEFAULT NULL
#define ImageGroup_image_MSGTYPE Image
#define Album_FIELDLIST(X, a) \
X(a, CALLBACK, OPTIONAL, BYTES, gid, 1) \
X(a, POINTER, OPTIONAL, STRING, name, 2) \
X(a, STATIC, OPTIONAL, STRING, name, 2) \
X(a, STATIC, OPTIONAL, MESSAGE, cover_group, 17)
#define Album_CALLBACK pb_default_field_callback
#define Album_DEFAULT NULL
#define Album_cover_group_MSGTYPE ImageGroup
#define Artist_FIELDLIST(X, a) \
X(a, POINTER, OPTIONAL, BYTES, gid, 1) \
X(a, POINTER, OPTIONAL, STRING, name, 2)
X(a, STATIC, OPTIONAL, BYTES, gid, 1) \
X(a, STATIC, OPTIONAL, STRING, name, 2)
#define Artist_CALLBACK NULL
#define Artist_DEFAULT NULL
#define Track_FIELDLIST(X, a) \
X(a, POINTER, OPTIONAL, BYTES, gid, 1) \
X(a, POINTER, OPTIONAL, STRING, name, 2) \
X(a, STATIC, OPTIONAL, BYTES, gid, 1) \
X(a, STATIC, OPTIONAL, STRING, name, 2) \
X(a, STATIC, OPTIONAL, MESSAGE, album, 3) \
X(a, POINTER, REPEATED, MESSAGE, artist, 4) \
X(a, STATIC, REPEATED, MESSAGE, artist, 4) \
X(a, STATIC, OPTIONAL, SINT32, duration, 7) \
X(a, POINTER, REPEATED, MESSAGE, restriction, 11) \
X(a, POINTER, REPEATED, MESSAGE, file, 12) \
X(a, POINTER, REPEATED, MESSAGE, alternative, 13)
#define Track_CALLBACK NULL
X(a, CALLBACK, REPEATED, MESSAGE, restriction, 11) \
X(a, STATIC, REPEATED, MESSAGE, file, 12) \
X(a, CALLBACK, REPEATED, MESSAGE, alternative, 13)
#define Track_CALLBACK pb_default_field_callback
#define Track_DEFAULT NULL
#define Track_album_MSGTYPE Album
#define Track_artist_MSGTYPE Artist
@@ -194,11 +209,11 @@ X(a, POINTER, REPEATED, MESSAGE, alternative, 13)
#define Track_alternative_MSGTYPE Track
#define Episode_FIELDLIST(X, a) \
X(a, POINTER, OPTIONAL, BYTES, gid, 1) \
X(a, POINTER, OPTIONAL, STRING, name, 2) \
X(a, STATIC, OPTIONAL, BYTES, gid, 1) \
X(a, STATIC, OPTIONAL, STRING, name, 2) \
X(a, STATIC, OPTIONAL, SINT32, duration, 7) \
X(a, POINTER, REPEATED, MESSAGE, audio, 12) \
X(a, POINTER, OPTIONAL, MESSAGE, covers, 68)
X(a, STATIC, REPEATED, MESSAGE, audio, 12) \
X(a, STATIC, OPTIONAL, MESSAGE, covers, 68)
#define Episode_CALLBACK NULL
#define Episode_DEFAULT NULL
#define Episode_audio_MSGTYPE AudioFile
@@ -224,14 +239,14 @@ extern const pb_msgdesc_t Episode_msg;
#define Episode_fields &Episode_msg
/* Maximum encoded size of messages (where known) */
/* AudioFile_size depends on runtime parameters */
/* Restriction_size depends on runtime parameters */
/* Image_size depends on runtime parameters */
/* ImageGroup_size depends on runtime parameters */
/* Album_size depends on runtime parameters */
/* Artist_size depends on runtime parameters */
/* Track_size depends on runtime parameters */
/* Episode_size depends on runtime parameters */
#define Artist_size 645
#define AudioFile_size 133
#define Episode_size 3290
#define ImageGroup_size 1340
#define Image_size 131
#define Restriction_size 66
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -1,13 +1,12 @@
Frame.ident type:FT_POINTER
Frame.protocol_version type:FT_POINTER
Frame.recipient type:FT_POINTER
Frame.ident max_size: 64, fixed_length:false
Frame.protocol_version max_size: 64, fixed_length:false
Frame.recipient max_count: 64, max_size: 64
Capability.stringValue max_count:50, max_size: 50
Capability.intValue max_count:50
DeviceState.sw_version type:FT_POINTER
DeviceState.name type:FT_POINTER
DeviceState.sw_version max_size: 64, fixed_length:false
DeviceState.name max_size: 64, fixed_length:false
DeviceState.capabilities max_count:17, fixed_count:false
State.context_uri type:FT_POINTER
State.context_uri max_size: 256, fixed_length:false
State.track max_count:100, fixed_count:false
TrackRef.gid type:FT_POINTER
TrackRef.uri type:FT_POINTER
TrackRef.context type:FT_POINTER
TrackRef.gid max_size: 128, fixed_length:false
TrackRef.uri max_size: 256 fixed_length:false

View File

@@ -6,7 +6,7 @@
#error Regenerate this file with the current version of nanopb generator.
#endif
PB_BIND(TrackRef, TrackRef, AUTO)
PB_BIND(TrackRef, TrackRef, 2)
PB_BIND(State, State, 4)

View File

@@ -62,23 +62,28 @@ typedef struct _Capability {
char stringValue[50][50];
} Capability;
typedef PB_BYTES_ARRAY_T(128) TrackRef_gid_t;
typedef struct _TrackRef {
pb_bytes_array_t *gid;
char *uri;
bool has_gid;
TrackRef_gid_t gid;
bool has_uri;
char uri[256];
bool has_queued;
bool queued;
char *context;
pb_callback_t context;
} TrackRef;
typedef struct _DeviceState {
char *sw_version;
bool has_sw_version;
char sw_version[64];
bool has_is_active;
bool is_active;
bool has_can_play;
bool can_play;
bool has_volume;
uint32_t volume;
char *name;
bool has_name;
char name[64];
bool has_error_code;
uint32_t error_code;
bool has_became_active_at;
@@ -90,7 +95,8 @@ typedef struct _DeviceState {
} DeviceState;
typedef struct _State {
char *context_uri;
bool has_context_uri;
char context_uri[256];
bool has_index;
uint32_t index;
bool has_position_ms;
@@ -113,8 +119,10 @@ typedef struct _State {
typedef struct _Frame {
bool has_version;
uint32_t version;
char *ident;
char *protocol_version;
bool has_ident;
char ident[64];
bool has_protocol_version;
char protocol_version[64];
bool has_seq_nr;
uint32_t seq_nr;
bool has_typ;
@@ -130,7 +138,7 @@ typedef struct _Frame {
bool has_state_update_id;
int64_t state_update_id;
pb_size_t recipient_count;
char **recipient;
char recipient[64][64];
} Frame;
@@ -153,16 +161,16 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define TrackRef_init_default {NULL, NULL, false, 0, NULL}
#define State_init_default {NULL, false, 0, false, 0, false, _PlayStatus_MIN, false, 0, {{NULL}, NULL}, false, 0, false, 0, false, 0, 0, {TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default}}
#define TrackRef_init_default {false, {0, {0}}, false, "", false, 0, {{NULL}, NULL}}
#define State_init_default {false, "", false, 0, false, 0, false, _PlayStatus_MIN, false, 0, {{NULL}, NULL}, false, 0, false, 0, false, 0, 0, {TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default, TrackRef_init_default}}
#define Capability_init_default {false, _CapabilityType_MIN, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, {"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}}
#define DeviceState_init_default {NULL, false, 0, false, 0, false, 0, NULL, false, 0, false, 0, {{NULL}, NULL}, 0, {Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default}, {{NULL}, NULL}}
#define Frame_init_default {false, 0, NULL, NULL, false, 0, false, _MessageType_MIN, false, DeviceState_init_default, false, State_init_default, false, 0, false, 0, false, 0, 0, NULL}
#define TrackRef_init_zero {NULL, NULL, false, 0, NULL}
#define State_init_zero {NULL, false, 0, false, 0, false, _PlayStatus_MIN, false, 0, {{NULL}, NULL}, false, 0, false, 0, false, 0, 0, {TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero}}
#define DeviceState_init_default {false, "", false, 0, false, 0, false, 0, false, "", false, 0, false, 0, {{NULL}, NULL}, 0, {Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default, Capability_init_default}, {{NULL}, NULL}}
#define Frame_init_default {false, 0, false, "", false, "", false, 0, false, _MessageType_MIN, false, DeviceState_init_default, false, State_init_default, false, 0, false, 0, false, 0, 0, {"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}}
#define TrackRef_init_zero {false, {0, {0}}, false, "", false, 0, {{NULL}, NULL}}
#define State_init_zero {false, "", false, 0, false, 0, false, _PlayStatus_MIN, false, 0, {{NULL}, NULL}, false, 0, false, 0, false, 0, 0, {TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero, TrackRef_init_zero}}
#define Capability_init_zero {false, _CapabilityType_MIN, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, {"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}}
#define DeviceState_init_zero {NULL, false, 0, false, 0, false, 0, NULL, false, 0, false, 0, {{NULL}, NULL}, 0, {Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero}, {{NULL}, NULL}}
#define Frame_init_zero {false, 0, NULL, NULL, false, 0, false, _MessageType_MIN, false, DeviceState_init_zero, false, State_init_zero, false, 0, false, 0, false, 0, 0, NULL}
#define DeviceState_init_zero {false, "", false, 0, false, 0, false, 0, false, "", false, 0, false, 0, {{NULL}, NULL}, 0, {Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero, Capability_init_zero}, {{NULL}, NULL}}
#define Frame_init_zero {false, 0, false, "", false, "", false, 0, false, _MessageType_MIN, false, DeviceState_init_zero, false, State_init_zero, false, 0, false, 0, false, 0, 0, {"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}}
/* Field tags (for use in manual encoding/decoding) */
#define Capability_typ_tag 1
@@ -206,15 +214,15 @@ extern "C" {
/* Struct field encoding specification for nanopb */
#define TrackRef_FIELDLIST(X, a) \
X(a, POINTER, OPTIONAL, BYTES, gid, 1) \
X(a, POINTER, OPTIONAL, STRING, uri, 2) \
X(a, STATIC, OPTIONAL, BYTES, gid, 1) \
X(a, STATIC, OPTIONAL, STRING, uri, 2) \
X(a, STATIC, OPTIONAL, BOOL, queued, 3) \
X(a, POINTER, OPTIONAL, STRING, context, 4)
#define TrackRef_CALLBACK NULL
X(a, CALLBACK, OPTIONAL, STRING, context, 4)
#define TrackRef_CALLBACK pb_default_field_callback
#define TrackRef_DEFAULT NULL
#define State_FIELDLIST(X, a) \
X(a, POINTER, OPTIONAL, STRING, context_uri, 2) \
X(a, STATIC, OPTIONAL, STRING, context_uri, 2) \
X(a, STATIC, OPTIONAL, UINT32, index, 3) \
X(a, STATIC, OPTIONAL, UINT32, position_ms, 4) \
X(a, STATIC, OPTIONAL, UENUM, status, 5) \
@@ -236,11 +244,11 @@ X(a, STATIC, REPEATED, STRING, stringValue, 3)
#define Capability_DEFAULT (const pb_byte_t*)"\x08\x01\x00"
#define DeviceState_FIELDLIST(X, a) \
X(a, POINTER, OPTIONAL, STRING, sw_version, 1) \
X(a, STATIC, OPTIONAL, STRING, sw_version, 1) \
X(a, STATIC, OPTIONAL, BOOL, is_active, 10) \
X(a, STATIC, OPTIONAL, BOOL, can_play, 11) \
X(a, STATIC, OPTIONAL, UINT32, volume, 12) \
X(a, POINTER, OPTIONAL, STRING, name, 13) \
X(a, STATIC, OPTIONAL, STRING, name, 13) \
X(a, STATIC, OPTIONAL, UINT32, error_code, 14) \
X(a, STATIC, OPTIONAL, INT64, became_active_at, 15) \
X(a, CALLBACK, OPTIONAL, STRING, error_message, 16) \
@@ -252,8 +260,8 @@ X(a, CALLBACK, REPEATED, STRING, local_uris, 18)
#define Frame_FIELDLIST(X, a) \
X(a, STATIC, OPTIONAL, UINT32, version, 1) \
X(a, POINTER, OPTIONAL, STRING, ident, 2) \
X(a, POINTER, OPTIONAL, STRING, protocol_version, 3) \
X(a, STATIC, OPTIONAL, STRING, ident, 2) \
X(a, STATIC, OPTIONAL, STRING, protocol_version, 3) \
X(a, STATIC, OPTIONAL, UINT32, seq_nr, 4) \
X(a, STATIC, OPTIONAL, UENUM, typ, 5) \
X(a, STATIC, OPTIONAL, MESSAGE, device_state, 7) \
@@ -261,7 +269,7 @@ X(a, STATIC, OPTIONAL, MESSAGE, state, 12) \
X(a, STATIC, OPTIONAL, UINT32, position, 13) \
X(a, STATIC, OPTIONAL, UINT32, volume, 14) \
X(a, STATIC, OPTIONAL, INT64, state_update_id, 17) \
X(a, POINTER, REPEATED, STRING, recipient, 18)
X(a, STATIC, REPEATED, STRING, recipient, 18)
#define Frame_CALLBACK NULL
#define Frame_DEFAULT (const pb_byte_t*)"\x28\x01\x00"
#define Frame_device_state_MSGTYPE DeviceState

View File

@@ -11,7 +11,7 @@ std::map<MercuryType, std::string> MercuryTypeMap({
MercuryManager::MercuryManager(std::unique_ptr<Session> session): bell::Task("mercuryManager", 6 * 1024, 2, 1)
{
tempMercuryHeader = Header_init_default;
tempMercuryHeader = {};
this->timeProvider = std::make_shared<TimeProvider>();
this->callbacks = std::map<uint64_t, mercuryCallback>();
this->subscriptions = std::map<std::string, mercuryCallback>();
@@ -294,8 +294,11 @@ uint64_t MercuryManager::execute(MercuryType method, std::string uri, mercuryCal
// Construct mercury header
CSPOT_LOG(debug, "executing MercuryType %s", MercuryTypeMap[method].c_str());
tempMercuryHeader.uri = (char *)(uri.c_str());
tempMercuryHeader.method = (char *)(MercuryTypeMap[method].c_str());
pbPutString(uri, tempMercuryHeader.uri);
pbPutString(MercuryTypeMap[method], tempMercuryHeader.method);
tempMercuryHeader.has_method = true;
tempMercuryHeader.has_uri = true;
// GET and SEND are actually the same. Therefore the override
// The difference between them is only in header's method

View File

@@ -3,13 +3,12 @@
MercuryResponse::MercuryResponse(std::vector<uint8_t> &data)
{
// this->mercuryHeader = std::make_unique<Header>();
this->mercuryHeader = Header_init_default;
this->mercuryHeader = {};
this->parts = mercuryParts(0);
this->parseResponse(data);
}
MercuryResponse::~MercuryResponse() {
pb_release(Header_fields, &mercuryHeader);
}
void MercuryResponse::parseResponse(std::vector<uint8_t> &data)

View File

@@ -1,6 +1,6 @@
#include "Packet.h"
Packet::Packet(uint8_t command, std::vector<uint8_t> &data) {
Packet::Packet(uint8_t command, const std::vector<uint8_t> &data) {
this->command = command;
this->data = data;
};

View File

@@ -24,7 +24,8 @@ PlayerState::PlayerState(std::shared_ptr<TimeProvider> timeProvider)
innerFrame.state.repeat = false;
innerFrame.state.has_repeat = true;
innerFrame.device_state.sw_version = (char*) swVersion;
innerFrame.device_state.has_sw_version = true;
pbPutCharArray(swVersion, innerFrame.device_state.sw_version);
innerFrame.device_state.is_active = false;
innerFrame.device_state.has_is_active = true;
@@ -35,7 +36,8 @@ PlayerState::PlayerState(std::shared_ptr<TimeProvider> timeProvider)
innerFrame.device_state.volume = configMan->volume;
innerFrame.device_state.has_volume = true;
innerFrame.device_state.name = (char*) configMan->deviceName.c_str();
innerFrame.device_state.has_name = true;
pbPutString(configMan->deviceName, innerFrame.device_state.name);
// Prepare player's capabilities
addCapability(CapabilityType_kCanBePlayer, 1);
@@ -137,7 +139,8 @@ void PlayerState::updatePositionMs(uint32_t position)
void PlayerState::updateTracks()
{
CSPOT_LOG(info, "---- Track count %d", remoteFrame.state.track_count);
innerFrame.state.context_uri = remoteFrame.state.context_uri == nullptr ? nullptr : strdup(remoteFrame.state.context_uri);
strcpy(innerFrame.state.context_uri, remoteFrame.state.context_uri);
std::copy(std::begin(remoteFrame.state.track), std::end(remoteFrame.state.track), std::begin(innerFrame.state.track));
innerFrame.state.track_count = remoteFrame.state.track_count;
innerFrame.state.has_playing_track_index = true;
@@ -198,9 +201,14 @@ std::vector<uint8_t> PlayerState::encodeCurrentFrame(MessageType typ)
{
// Prepare current frame info
innerFrame.version = 1;
innerFrame.ident = (char *) deviceId;
pbPutCharArray(deviceId, innerFrame.ident);
innerFrame.has_ident = true;
innerFrame.seq_nr = this->seqNum;
innerFrame.protocol_version = (char*) protocolVersion;
pbPutCharArray(protocolVersion, innerFrame.protocol_version);
innerFrame.has_protocol_version = true;
innerFrame.typ = typ;
innerFrame.state_update_id = timeProvider->getSyncedTimestamp();
innerFrame.has_version = true;

View File

@@ -49,17 +49,26 @@ std::vector<uint8_t> Session::authenticate(std::shared_ptr<LoginBlob> blob)
authBlob = blob;
// prepare authentication request proto
authRequest.login_credentials.username = (char *)(blob->username.c_str());
authRequest.login_credentials.auth_data = vectorToPbArray(blob->authData);
pbPutString(blob->username, authRequest.login_credentials.username);
std::copy(blob->authData.begin(), blob->authData.end(), authRequest.login_credentials.auth_data.bytes);
authRequest.login_credentials.auth_data.size = blob->authData.size();
authRequest.login_credentials.typ = (AuthenticationType) blob->authType;
authRequest.system_info.cpu_family = CpuFamily_CPU_UNKNOWN;
authRequest.system_info.os = Os_OS_UNKNOWN;
authRequest.system_info.system_information_string = (char *)informationString;
authRequest.system_info.device_id = (char *)deviceId;
authRequest.version_string = (char *)versionString;
auto infoStr = std::string(informationString);
pbPutString(infoStr, authRequest.system_info.system_information_string);
auto deviceIdStr = std::string(deviceId);
pbPutString(deviceId, authRequest.system_info.device_id);
auto versionStr = std::string(versionString);
pbPutString(versionStr, authRequest.version_string);
authRequest.has_version_string = true;
auto data = pbEncode(ClientResponseEncrypted_fields, &authRequest);
free(authRequest.login_credentials.auth_data);
// Send login request
this->shanConn->sendPacket(LOGIN_REQUEST_COMMAND, data);

View File

@@ -10,8 +10,8 @@ SpotifyTrack::SpotifyTrack(std::shared_ptr<MercuryManager> manager, std::shared_
{
this->manager = manager;
this->fileId = std::vector<uint8_t>();
episodeInfo = Episode_init_default;
trackInfo = Track_init_default;
episodeInfo = {};
trackInfo = {};
mercuryCallback trackResponseLambda = [=](std::unique_ptr<MercuryResponse> res) {
this->trackInformationCallback(std::move(res), position_ms, isPaused);
@@ -53,18 +53,18 @@ bool SpotifyTrack::countryListContains(std::string countryList, std::string coun
bool SpotifyTrack::canPlayTrack()
{
for (int x = 0; x < trackInfo.restriction_count; x++)
{
if (trackInfo.restriction[x].countries_allowed != nullptr)
{
return countryListContains(std::string(trackInfo.restriction[x].countries_allowed), manager->countryCode);
}
if (trackInfo.restriction[x].countries_forbidden != nullptr)
{
return !countryListContains(std::string(trackInfo.restriction[x].countries_forbidden), manager->countryCode);
}
}
// for (int x = 0; x < trackInfo.restriction_count; x++)
// {
// if (strlen(trackInfo.restriction[x].countries_allowed) > 0)
// {
// return countryListContains(std::string(trackInfo.restriction[x].countries_allowed), manager->countryCode);
// }
//
// if (strlen(trackInfo.restriction[x].countries_forbidden) > 0)
// {
// return !countryListContains(std::string(trackInfo.restriction[x].countries_forbidden), manager->countryCode);
// }
// }
return true;
}
@@ -77,35 +77,39 @@ void SpotifyTrack::trackInformationCallback(std::unique_ptr<MercuryResponse> res
pb_release(Track_fields, &trackInfo);
pbDecode(trackInfo, Track_fields, response->parts[0]);
//
// CSPOT_LOG(info, "Track name: %s", trackInfo.name);
// CSPOT_LOG(info, "Track duration: %d", trackInfo.duration);
// CSPOT_LOG(debug, "trackInfo.restriction.size() = %d", trackInfo.restriction_count);
// int altIndex = 0;
// while (!canPlayTrack())
// {
// auto src = trackInfo.alternative[altIndex].restriction;
//// std::copy(std::begin(src), std::end(src), std::begin(trackInfo.restriction));
//// trackInfo.restriction_count = trackInfo.alternative[altIndex].restriction_count;
////
//// free(trackInfo.gid);
// trackInfo.gid = trackInfo.alternative[altIndex].gid;
// altIndex++;
// CSPOT_LOG(info, "Trying alternative %d", altIndex);
// }
CSPOT_LOG(info, "Track name: %s", trackInfo.name);
CSPOT_LOG(info, "Track duration: %d", trackInfo.duration);
CSPOT_LOG(debug, "trackInfo.restriction.size() = %d", trackInfo.restriction_count);
int altIndex = 0;
while (!canPlayTrack())
{
trackInfo.restriction = trackInfo.alternative[altIndex].restriction;
trackInfo.restriction_count = trackInfo.alternative[altIndex].restriction_count;
trackInfo.gid = trackInfo.alternative[altIndex].gid;
trackInfo.file = trackInfo.alternative[altIndex].file;
altIndex++;
CSPOT_LOG(info, "Trying alternative %d", altIndex);
}
auto trackId = pbArrayToVector(trackInfo.gid);
auto trackId = std::vector(trackInfo.gid.bytes, trackInfo.gid.bytes + trackInfo.gid.size);
this->fileId = std::vector<uint8_t>();
for (int x = 0; x < trackInfo.file_count; x++)
{
if (trackInfo.file[x].format == configMan->format)
{
this->fileId = pbArrayToVector(trackInfo.file[x].file_id);
this->fileId = std::vector(trackInfo.file[x].file_id.bytes, trackInfo.file[x].file_id.bytes + trackInfo.file[x].file_id.size);
break; // If file found stop searching
}
}
if (trackInfoReceived != nullptr)
{
auto imageId = pbArrayToVector(trackInfo.album.cover_group.image[0].file_id);
auto imageIdBytes = trackInfo.album.cover_group.image[0].file_id;
auto imageId = std::vector(imageIdBytes.bytes, imageIdBytes.bytes + imageIdBytes.size);
TrackInfo simpleTrackInfo = {
.name = std::string(trackInfo.name),
.album = std::string(trackInfo.album.name),
@@ -139,14 +143,15 @@ void SpotifyTrack::episodeInformationCallback(std::unique_ptr<MercuryResponse> r
{
if (episodeInfo.audio[x].format == AudioFormat_OGG_VORBIS_96)
{
this->fileId = pbArrayToVector(episodeInfo.audio[x].file_id);
this->fileId = std::vector(episodeInfo.audio[x].file_id.bytes, episodeInfo.audio[x].file_id.bytes + episodeInfo.audio[x].file_id.size);
break; // If file found stop searching
}
}
if (trackInfoReceived != nullptr)
{
auto imageId = pbArrayToVector(episodeInfo.covers->image[0].file_id);
auto imageFileId = episodeInfo.covers.image[0].file_id;
auto imageId = std::vector(imageFileId.bytes, imageFileId.bytes + imageFileId.size);
TrackInfo simpleTrackInfo = {
.name = std::string(episodeInfo.name),
.album = "",
@@ -159,7 +164,7 @@ void SpotifyTrack::episodeInformationCallback(std::unique_ptr<MercuryResponse> r
trackInfoReceived(simpleTrackInfo);
}
this->requestAudioKey(pbArrayToVector(episodeInfo.gid), this->fileId, episodeInfo.duration, position_ms, isPaused);
this->requestAudioKey(std::vector(episodeInfo.gid.bytes, episodeInfo.gid.bytes + episodeInfo.gid.size), this->fileId, episodeInfo.duration, position_ms, isPaused);
}
void SpotifyTrack::requestAudioKey(std::vector<uint8_t> fileId, std::vector<uint8_t> trackId, int32_t trackDuration, uint32_t position_ms, bool isPaused)

View File

@@ -3,11 +3,11 @@
TrackReference::TrackReference(TrackRef *ref)
{
if (ref->gid != nullptr)
if (ref->gid.size > 0)
{
gid = pbArrayToVector(ref->gid);
gid = std::vector(ref->gid.bytes, ref->gid.bytes + ref->gid.size);
}
else if (ref->uri != nullptr)
else if (strlen(ref->uri) > 0)
{
auto uri = std::string(ref->uri);
auto idString = uri.substr(uri.find_last_of(":") + 1, uri.size());

View File

@@ -106,7 +106,7 @@ static bool cmd_handler(cspot_event_t event, ...) {
switch(event) {
case CSPOT_SETUP:
actrls_set(controls, false, NULL, actrls_ir_action);
displayer_control(DISPLAYER_ACTIVATE, "SPOTIFY");
displayer_control(DISPLAYER_ACTIVATE, "SPOTIFY", false);
break;
case CSPOT_PLAY:
displayer_control(DISPLAYER_TIMER_RUN);