/* piano wrapper: prepare/execute http request and pass result back to * libpiano (updates data structures) * @param piano handle * @param request type * @param waitress handle * @param data pointer (used as request data) * @return 1 on success, 0 otherwise */ int BarUiPianoCall (PianoHandle_t *ph, PianoRequestType_t type, WaitressHandle_t *waith, void *data, PianoReturn_t *pRet, WaitressReturn_t *wRet) { PianoRequest_t req; memset (&req, 0, sizeof (req)); /* repeat as long as there are http requests to do */ do { req.data = data; *pRet = PianoRequest (ph, &req, type); if (*pRet != PIANO_RET_OK) { BarUiMsg (MSG_NONE, "Error: %s\n", PianoErrorToStr (*pRet)); PianoDestroyRequest (&req); return 0; } *wRet = BarPianoHttpRequest (waith, &req); if (*wRet != WAITRESS_RET_OK) { BarUiMsg (MSG_NONE, "Network error: %s\n", WaitressErrorToStr (*wRet)); PianoDestroyRequest (&req); if (req.responseData != NULL) { free (req.responseData); } return 0; } *pRet = PianoResponse (ph, &req); if (*pRet != PIANO_RET_CONTINUE_REQUEST) { if (*pRet != PIANO_RET_OK) { BarUiMsg (MSG_NONE, "Error: %s\n", PianoErrorToStr (*pRet)); PianoDestroyRequest (&req); if (req.responseData != NULL) { free (req.responseData); } return 0; } else { BarUiMsg (MSG_NONE, "Ok.\n"); } } /* we can destroy the request at this point, even when this call needs * more than one http request. persistend data (step counter, e.g.) is * stored in req.data */ if (req.responseData != NULL) { free (req.responseData); } PianoDestroyRequest (&req); } while (*pRet == PIANO_RET_CONTINUE_REQUEST); return 1; }
/* piano wrapper: prepare/execute http request and pass result back to * libpiano (updates data structures) * @param app handle * @param request type * @param request data * @param stores piano return code * @param stores waitress return code * @return 1 on success, 0 otherwise */ int BarUiPianoCall (BarApp_t * const app, PianoRequestType_t type, void *data, PianoReturn_t *pRet, WaitressReturn_t *wRet) { PianoRequest_t req; memset (&req, 0, sizeof (req)); /* repeat as long as there are http requests to do */ do { req.data = data; *pRet = PianoRequest (&app->ph, &req, type); if (*pRet != PIANO_RET_OK) { BarUiMsg (&app->settings, MSG_NONE, "Error: %s\n", PianoErrorToStr (*pRet)); PianoDestroyRequest (&req); return 0; } *wRet = BarPianoHttpRequest (&app->waith, &req); if (*wRet != WAITRESS_RET_OK) { BarUiMsg (&app->settings, MSG_NONE, "Network error: %s\n", WaitressErrorToStr (*wRet)); if (req.responseData != NULL) { free (req.responseData); } PianoDestroyRequest (&req); return 0; } *pRet = PianoResponse (&app->ph, &req); if (*pRet != PIANO_RET_CONTINUE_REQUEST) { /* checking for request type avoids infinite loops */ if (*pRet == PIANO_RET_P_INVALID_AUTH_TOKEN && type != PIANO_REQUEST_LOGIN) { /* reauthenticate */ PianoReturn_t authpRet; WaitressReturn_t authwRet; PianoRequestDataLogin_t reqData; reqData.user = app->settings.username; reqData.password = app->settings.password; reqData.step = 0; BarUiMsg (&app->settings, MSG_NONE, "Reauthentication required... "); if (!BarUiPianoCall (app, PIANO_REQUEST_LOGIN, &reqData, &authpRet, &authwRet)) { *pRet = authpRet; *wRet = authwRet; if (req.responseData != NULL) { free (req.responseData); } PianoDestroyRequest (&req); return 0; } else { /* try again */ *pRet = PIANO_RET_CONTINUE_REQUEST; BarUiMsg (&app->settings, MSG_INFO, "Trying again... "); } } else if (*pRet != PIANO_RET_OK) { BarUiMsg (&app->settings, MSG_NONE, "Error: %s\n", PianoErrorToStr (*pRet)); if (req.responseData != NULL) { free (req.responseData); } PianoDestroyRequest (&req); return 0; } else { BarUiMsg (&app->settings, MSG_NONE, "Ok.\n"); } } /* we can destroy the request at this point, even when this call needs * more than one http request. persistent data (step counter, e.g.) is * stored in req.data */ if (req.responseData != NULL) { free (req.responseData); } PianoDestroyRequest (&req); } while (*pRet == PIANO_RET_CONTINUE_REQUEST); return 1; }
int MythPianoService::PianoCall(PianoRequestType_t type, void *data, PianoReturn_t *pRet, WaitressReturn_t *wRet) { if (!m_Piano) return -1; PianoRequest_t req; memset (&req, 0, sizeof (req)); /* repeat as long as there are http requests to do */ do { req.data = data; *pRet = PianoRequest (m_Piano, &req, type); if (*pRet != PIANO_RET_OK) { BroadcastMessage("Error: %s\n", PianoErrorToStr (*pRet)); PianoDestroyRequest (&req); return 0; } *wRet = PianoHttpRequest(&m_Waith, &req); if (*wRet != WAITRESS_RET_OK) { BroadcastMessage ("Network error: %s\n", WaitressErrorToStr (*wRet)); if (req.responseData != NULL) { free (req.responseData); } PianoDestroyRequest (&req); return 0; } *pRet = PianoResponse (m_Piano, &req); if (*pRet != PIANO_RET_CONTINUE_REQUEST) { /* checking for request type avoids infinite loops */ if (*pRet == PIANO_RET_AUTH_TOKEN_INVALID && type != PIANO_REQUEST_LOGIN) { /* reauthenticate */ PianoReturn_t authpRet; WaitressReturn_t authwRet; PianoRequestDataLogin_t reqData; QString username = gCoreContext->GetSetting("pandora-username"); QString password = gCoreContext->GetSetting("pandora-password"); //wtf really? char* usernameBuff = strndup(username.toUtf8().data(), 1024); char* passwordBuff = strndup(password.toUtf8().data(), 1024); reqData.user = usernameBuff; reqData.password = passwordBuff; reqData.step = 0; BroadcastMessage ("Reauthentication required... "); if (!PianoCall(PIANO_REQUEST_LOGIN, &reqData, &authpRet, &authwRet)) { *pRet = authpRet; *wRet = authwRet; if (req.responseData != NULL) { free (req.responseData); } PianoDestroyRequest (&req); return 0; } else { /* try again */ *pRet = PIANO_RET_CONTINUE_REQUEST; BroadcastMessage("Trying again... "); } // wtf free(usernameBuff); free(passwordBuff); } else if (*pRet != PIANO_RET_OK) { BroadcastMessage("Error: %s\n", PianoErrorToStr (*pRet)); if (req.responseData != NULL) { free (req.responseData); } PianoDestroyRequest (&req); return 0; } else { BroadcastMessage("Login Ok.\n"); } } /* we can destroy the request at this point, even when this call needs * more than one http request. persistent data (step counter, e.g.) is * stored in req.data */ if (req.responseData != NULL) { free (req.responseData); } PianoDestroyRequest (&req); } while (*pRet == PIANO_RET_CONTINUE_REQUEST); return 1; }
/* piano wrapper: prepare/execute http request and pass result back to * libpiano */ bool BarUiPianoCall (BarApp_t * const app, const PianoRequestType_t type, void * const data, PianoReturn_t * const pRet, CURLcode * const wRet) { PianoReturn_t pRetLocal = PIANO_RET_OK; CURLcode wRetLocal = CURLE_OK; bool ret = false; /* repeat as long as there are http requests to do */ do { PianoRequest_t req = { .data = data, .responseData = NULL }; pRetLocal = PianoRequest (&app->ph, &req, type); if (pRetLocal != PIANO_RET_OK) { BarUiMsg (&app->settings, MSG_NONE, "Error: %s\n", PianoErrorToStr (pRetLocal)); goto cleanup; } wRetLocal = BarPianoHttpRequest (app->http, &app->settings, &req); if (wRetLocal == CURLE_ABORTED_BY_CALLBACK) { BarUiMsg (&app->settings, MSG_NONE, "Interrupted.\n"); goto cleanup; } else if (wRetLocal != CURLE_OK) { BarUiMsg (&app->settings, MSG_NONE, "Network error: %s\n", curl_easy_strerror (wRetLocal)); goto cleanup; } pRetLocal = PianoResponse (&app->ph, &req); if (pRetLocal != PIANO_RET_CONTINUE_REQUEST) { /* checking for request type avoids infinite loops */ if (pRetLocal == PIANO_RET_P_INVALID_AUTH_TOKEN && type != PIANO_REQUEST_LOGIN) { /* reauthenticate */ PianoRequestDataLogin_t reqData; reqData.user = app->settings.username; reqData.password = app->settings.password; reqData.step = 0; BarUiMsg (&app->settings, MSG_NONE, "Reauthentication required... "); if (!BarUiPianoCall (app, PIANO_REQUEST_LOGIN, &reqData, &pRetLocal, &wRetLocal)) { goto cleanup; } else { /* try again */ pRetLocal = PIANO_RET_CONTINUE_REQUEST; BarUiMsg (&app->settings, MSG_INFO, "Trying again... "); } } else if (pRetLocal != PIANO_RET_OK) { BarUiMsg (&app->settings, MSG_NONE, "Error: %s\n", PianoErrorToStr (pRetLocal)); goto cleanup; } else { BarUiMsg (&app->settings, MSG_NONE, "Ok.\n"); ret = true; } } cleanup: /* persistent data is stored in req.data */ free (req.responseData); PianoDestroyRequest (&req); } while (pRetLocal == PIANO_RET_CONTINUE_REQUEST); *pRet = pRetLocal; *wRet = wRetLocal; return ret; }