#include #include #include #include #include #include #define COMMAND_SP_LOGOUT 1 #define COMMAND_SP_PRINTUSER 2 extern uint8_t g_appkey[]; extern int g_appkey_size; void notifyMainThread(sp_session* session); void* spotifyLoop(void*); void loggedIn(sp_session* session, sp_error error); void loggedOut(sp_session* session); void logMessage(sp_session* session, const char* data); static sp_session* spotifySession; static int notify_do = 0; static int command = 0; static int logged_out = 0; static pthread_mutex_t notify_mutex; static pthread_cond_t notify_cond; static pthread_t spotifyThread; static sp_session_callbacks sessionCallbacks = { .notify_main_thread = ¬ifyMainThread, .logged_in = &loggedIn, .logged_out = &loggedOut, .log_message = &logMessage, }; static sp_session_config sessionConfig = { .api_version = SPOTIFY_API_VERSION, .cache_location = "tmp", .settings_location = "tmp", .application_key = g_appkey, .application_key_size = 0, .user_agent = "nodejs-spotify-adapter", .callbacks = &sessionCallbacks, NULL, }; void* spotifyLoop(void* nervNicht) { sp_error error; sp_session* session; int next_timeout = 0; const char* username = "SET"; const char* password = "SET"; sessionConfig.application_key_size = g_appkey_size; error = sp_session_create(&sessionConfig, &session); if(SP_ERROR_OK != error) { fprintf(stderr, "Could not create Spotify session: %s\n", sp_error_message(error)); } spotifySession = session; pthread_mutex_init(¬ify_mutex, NULL); pthread_cond_init(¬ify_cond, NULL); sp_session_login(session, username, password, 0, NULL); pthread_mutex_lock(¬ify_mutex); int log_out_called = 0; while(!logged_out) { if(log_out_called) fprintf(stdout, "Loop while logout in process, command: %d, notify: %d, timeout: %d\n", command, notify_do, next_timeout); if(next_timeout == 0) { while(notify_do == 0) { pthread_cond_wait(¬ify_cond, ¬ify_mutex); } } else { struct timespec ts; clock_serv_t cclock; mach_timespec_t mts; host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); clock_get_time(cclock, &mts); mach_port_deallocate(mach_task_self(), cclock); ts.tv_sec = mts.tv_sec + next_timeout / 1000; ts.tv_nsec = mts.tv_nsec + (next_timeout % 1000) * 1000; while(!notify_do && !command) { if(pthread_cond_timedwait(¬ify_cond, ¬ify_mutex, &ts)) break; } } if(log_out_called) fprintf(stdout, "2 Loop while logout in process, command: %d, notify: %d, timeout: %d\n", command, notify_do, next_timeout); if(command) { if(command == COMMAND_SP_LOGOUT) { sp_session_logout(spotifySession); log_out_called = 1; } else if(command == COMMAND_SP_PRINTUSER) { sp_user* user = sp_session_user(spotifySession); const char* name = sp_user_display_name(user); fprintf(stdout, "User: %s\n", name); } } command = 0; notify_do = 0; pthread_mutex_unlock(¬ify_mutex); do { if(log_out_called) fprintf(stdout, "3 Loop while logout in process, command: %d, notify: %d, timeout: %d\n", command, notify_do, next_timeout); sp_session_process_events(session, &next_timeout); if(log_out_called) fprintf(stdout, "4 Loop while logout in process, command: %d, notify: %d, timeout: %d\n", command, notify_do, next_timeout); } while(next_timeout == 0); pthread_mutex_lock(¬ify_mutex); } sp_session_release(session); fprintf(stdout, "Exiting spotify main loop\n"); return 0; } void notifyMainThread(sp_session* session) { pthread_mutex_lock(¬ify_mutex); notify_do = 1; pthread_cond_signal(¬ify_cond); pthread_mutex_unlock(¬ify_mutex); } void loggedIn(sp_session* session, sp_error error) { if(SP_ERROR_OK != error) { fprintf(stderr, "Error logging in: %s\n", sp_error_message(error)); } else { fprintf(stdout, "Service is logged in!\n"); } } void loggedOut(sp_session* session) { fprintf(stdout, "Service is logged out\n"); logged_out = 1; } void logMessage(sp_session* session, const char* data) { fprintf(stdout, "%s\n", data); } void printUser() { pthread_mutex_lock(¬ify_mutex); command = COMMAND_SP_PRINTUSER; pthread_cond_signal(¬ify_cond); pthread_mutex_unlock(¬ify_mutex); } void logout() { pthread_t caller = pthread_self(); fprintf(stdout, "Logout called by %u\n", (unsigned int)caller); pthread_mutex_lock(¬ify_mutex); command = COMMAND_SP_LOGOUT; pthread_cond_signal(¬ify_cond); pthread_mutex_unlock(¬ify_mutex); } void login() { pthread_t caller = pthread_self(); fprintf(stdout, "Login called by %u\n", (unsigned int)caller); pthread_create(&spotifyThread, NULL, spotifyLoop, NULL); }