From 7f6457aa9b7110869e89111c42651b1055728679 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Fri, 7 Aug 2020 08:08:10 +0200 Subject: Allow changing station mode Fixes #700. --- src/libpiano/piano.c | 12 ++++++++++ src/libpiano/piano.h | 20 +++++++++++++++++ src/libpiano/request.c | 30 +++++++++++++++++++++++++ src/libpiano/response.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+) (limited to 'src/libpiano') diff --git a/src/libpiano/piano.c b/src/libpiano/piano.c index a189f34..fde8789 100644 --- a/src/libpiano/piano.c +++ b/src/libpiano/piano.c @@ -183,6 +183,18 @@ static void PianoDestroyPartner (PianoPartner_t *partner) { memset (partner, 0, sizeof (*partner)); } +void PianoDestroyStationMode (PianoStationMode_t * const modes) { + PianoStationMode_t *curMode = modes; + + while (curMode != NULL) { + free (curMode->name); + free (curMode->description); + PianoStationMode_t * const lastMode = curMode; + curMode = (PianoStationMode_t *) curMode->head.next; + free (lastMode); + } +} + /* frees the whole piano handle structure * @param piano handle * @return nothing diff --git a/src/libpiano/piano.h b/src/libpiano/piano.h index 0ec6c49..f7360aa 100644 --- a/src/libpiano/piano.h +++ b/src/libpiano/piano.h @@ -155,6 +155,13 @@ typedef struct { bool explicitContentFilter; } PianoSettings_t; +typedef struct { + PianoListHead_t head; + char *name, *description; + bool isAlgorithmic, isTakeover, active; + int id; +} PianoStationMode_t; + typedef enum { /* 0 is reserved: memset (x, 0, sizeof (x)) */ PIANO_REQUEST_LOGIN = 1, @@ -179,6 +186,8 @@ typedef enum { PIANO_REQUEST_DELETE_SEED = 22, PIANO_REQUEST_GET_SETTINGS = 23, PIANO_REQUEST_CHANGE_SETTINGS = 24, + PIANO_REQUEST_GET_STATION_MODES = 25, + PIANO_REQUEST_SET_STATION_MODE = 26, } PianoRequestType_t; typedef struct PianoRequest { @@ -266,6 +275,16 @@ typedef struct { PianoTristate_t explicitContentFilter; } PianoRequestDataChangeSettings_t; +typedef struct { + PianoStation_t *station; + PianoStationMode_t *retModes; +} PianoRequestDataGetStationModes_t; + +typedef struct { + PianoStation_t *station; + unsigned int id; +} PianoRequestDataSetStationMode_t; + /* pandora error code offset */ #define PIANO_RET_OFFSET 1024 typedef enum { @@ -355,6 +374,7 @@ void PianoDestroy (PianoHandle_t *); void PianoDestroyPlaylist (PianoSong_t *); void PianoDestroySearchResult (PianoSearchResult_t *); void PianoDestroyStationInfo (PianoStationInfo_t *); +void PianoDestroyStationMode (PianoStationMode_t * const); /* pandora rpc */ PianoReturn_t PianoRequest (PianoHandle_t *, PianoRequest_t *, diff --git a/src/libpiano/request.c b/src/libpiano/request.c index 35feda9..69e49a1 100644 --- a/src/libpiano/request.c +++ b/src/libpiano/request.c @@ -369,6 +369,36 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req, break; } + case PIANO_REQUEST_GET_STATION_MODES: { + PianoRequestDataGetStationModes_t *reqData = req->data; + assert (reqData != NULL); + PianoStation_t * const station = reqData->station; + assert (station != NULL); + + json_object_object_add (j, "stationId", + json_object_new_string (station->id)); + + method = "interactiveradio.v1.getAvailableModesSimple"; + req->secure = true; + break; + } + + case PIANO_REQUEST_SET_STATION_MODE: { + PianoRequestDataSetStationMode_t *reqData = req->data; + assert (reqData != NULL); + PianoStation_t * const station = reqData->station; + assert (station != NULL); + + json_object_object_add (j, "stationId", + json_object_new_string (station->id)); + json_object_object_add (j, "modeId", + json_object_new_int (reqData->id)); + + method = "interactiveradio.v1.setAndGetAvailableModes"; + req->secure = true; + break; + } + case PIANO_REQUEST_DELETE_FEEDBACK: { PianoSong_t *song = req->data; diff --git a/src/libpiano/response.c b/src/libpiano/response.c index 4b706e2..1a0f2d5 100644 --- a/src/libpiano/response.c +++ b/src/libpiano/response.c @@ -651,6 +651,66 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) { } break; } + + case PIANO_REQUEST_GET_STATION_MODES: { + PianoRequestDataGetStationModes_t *reqData = req->data; + assert (reqData != NULL); + + int active = -1; + + json_object *activeMode; + if (json_object_object_get_ex (result, "currentModeId", &activeMode)) { + active = json_object_get_int (activeMode); + } + + json_object *availableModes; + if (json_object_object_get_ex (result, "availableModes", &availableModes)) { + for (int i = 0; i < json_object_array_length (availableModes); i++) { + json_object *val = json_object_array_get_idx (availableModes, i); + + assert (json_object_is_type (val, json_type_object)); + + PianoStationMode_t *mode; + if ((mode = calloc (1, sizeof (*mode))) == NULL) { + return PIANO_RET_OUT_OF_MEMORY; + } + + json_object *modeId; + if (json_object_object_get_ex (val, "modeId", &modeId)) { + mode->id = json_object_get_int (modeId); + mode->name = PianoJsonStrdup (val, "modeName"); + mode->description = PianoJsonStrdup (val, "modeDescription"); + mode->isAlgorithmic = getBoolDefault (val, "isAlgorithmicMode", + false); + mode->isTakeover = getBoolDefault (val, "isTakeoverMode", + false); + mode->active = active == mode->id; + } + + reqData->retModes = PianoListAppendP (reqData->retModes, + mode); + } + } + break; + } + + case PIANO_REQUEST_SET_STATION_MODE: { + PianoRequestDataSetStationMode_t *reqData = req->data; + assert (reqData != NULL); + + int active = -1; + + json_object *activeMode; + if (json_object_object_get_ex (result, "currentModeId", &activeMode)) { + active = json_object_get_int (activeMode); + } + + if (active != reqData->id) { + /* this did not work */ + return PIANO_RET_ERR; + } + break; + } } cleanup: -- cgit v1.2.3