Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Copyright (C) 2012 ichbtm
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
- #endif
- #include <windows.h>
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include "StdAfx.h"
- #pragma comment (lib, "Ws2_32.lib")
- #define SIZE_MTU 1400
- #define SIZE_BUF64 8192
- class IOTCPSocket
- {
- public:
- IOTCPSocket(std::wstring swUserAgent, std::wstring swUrl);
- virtual ~IOTCPSocket();
- int RunOnce();
- static void *RunLoop(void *pThis);
- bool StartThread(bool bRestart=true);
- bool StopThread(const bool bAutoTerminate=false);
- int SendCommand(std::wstring swCommand);
- bool m_bAvail;
- CRITICAL_SECTION m_CriticalSection;
- protected:
- int TCPIO_Init(void);
- SOCKADDR_IN* TCPIO_CreateSOCKADDR(const char *sTarget);
- int TCPIO_Connect();
- int TCPIO_Close();
- int TCPIO_Cleanup(void);
- int TCPIO_Send(const BYTE *pData, unsigned int nDataLen);
- int TCPIO_Recv(BYTE **pInData, unsigned int *pnInDataLen);
- int TCPIO_WSelect();
- int TCPIO_RSelect();
- int SendBuffer(BYTE *pBuffer, unsigned int nBufLen);
- int RecvString(char ** pBuffer, unsigned int *nBufLen);
- BYTE *AllocatePacket(BYTE *pBuffer, unsigned int size, unsigned int *nPktLen);
- virtual int SendOutput() {return 0;};
- virtual int GetInput();
- virtual void ParseCommand(std::wstring swCommand, char** pBuffer, unsigned int* nBufLen) {};
- virtual int ParseAnswer(char* pBuffer, int nBufLen) {return 0;};
- virtual void IfDisconnected(void);
- SOCKADDR_IN* m_saddr;
- SOCKET m_s;
- std::wstring m_url;
- DWORD m_LastConnectTime;
- bool m_bDisconnected;
- bool m_bCommandToSend;
- std::wstring m_hostname;
- std::wstring m_useragent;
- std::wstring m_verb;
- std::wstring m_hdrs;
- bool m_stream;
- HANDLE m_hThread;
- DWORD m_nThreadID;
- bool m_bRunning;
- bool m_bRestart;
- };
- #include <shellapi.h>
- #include <sstream>
- #include "PlayerSQBOX.h"
- const int WMSQB_EXIT = 0x0401;
- std::wstring stows(LPCSTR str, int codepage=CP_ACP);
- std::string wstos(LPCWSTR str, int codepage=CP_ACP);
- std::wstring utf8tows(LPCSTR str);
- std::string wstoutf8(LPCWSTR str);
- std::string stoutf8(LPCSTR str, int codepage=CP_ACP);
- class IO_jsonCommand : public IOTCPSocket {
- public:
- IO_jsonCommand(std::wstring swUserAgent, std::wstring swUrl);
- virtual ~IO_jsonCommand();
- int SendOutput();
- void ParseCommand(std::wstring swCommand, char** pBuffer, unsigned int* nBufLen);
- int ParseAnswer(char* pBuffer, int nBufLen);
- void IfDisconnected(void);
- int CreateCommand(std::wstring swCommand);
- std::wstring m_client;
- std::wstring m_command;
- };
- class IO_GETCover : public IOTCPSocket {
- public:
- IO_GETCover(std::wstring swUserAgent, std::wstring swUrl);
- virtual ~IO_GETCover();
- int SendOutput();
- void ParseCommand(std::wstring swCommand, char** pBuffer, unsigned int* nBufLen);
- int ParseAnswer(char* pBuffer, int nBufLen);
- void IfDisconnected(void);
- int CreateCommand(std::wstring swCommand);
- std::string BreakDownCommand(std::string instr, std::string command);
- std::wstring m_coverpath;
- std::wstring m_command;
- HANDLE m_hFile;
- unsigned int m_filepos;
- unsigned int m_pngsize;
- };
- class IO_cometSubscribe : public IOTCPSocket {
- public:
- IO_cometSubscribe(std::wstring swUserAgent, std::wstring swAddress);
- virtual ~IO_cometSubscribe();
- int SendOutput();
- void ParseCommand(std::wstring swCommand, char** pBuffer, unsigned int* nBufLen);
- int ParseAnswer(char* pBuffer, int nBufLen);
- void IfDisconnected(void);
- std::wstring BreakDownCommand(std::wstring instr, std::wstring command);
- std::wstring m_client;
- std::wstring m_clientID;
- std::wstring m_songid;
- StateType m_State;
- std::wstring m_Artist;
- std::wstring m_Title;
- std::wstring m_Album;
- std::wstring m_Lyrics;
- std::wstring m_CoverPath;
- std::wstring m_FilePath;
- UINT m_Connected;
- UINT m_Duration;
- UINT m_Position;
- UINT m_Rating;
- UINT m_Volume;
- bool m_Shuffle;
- bool m_Repeat;
- bool m_bHandshakeSent;
- bool m_bConnectionSent;
- bool m_bSubscriptionSent;
- bool m_bNeedHandshake;
- bool m_bNeedConnection;
- bool m_bNeedSubscription;
- };
- IO_cometSubscribe* g_pcometSubscribeHandler;
- IO_jsonCommand* g_pCommandHandler;
- IO_GETCover* g_pCoverHandler;
- CPlayer* CPlayerSQBOX::c_Player = NULL;
- CPlayerSQBOX::CPlayerSQBOX(std::wstring swPlayerPath) : CPlayer(),
- m_Window(),
- m_LastCheckTime(0),
- m_LastPosition(0),
- m_playerPath(swPlayerPath),
- m_server(),
- m_nwebPort(0)
- {
- if (m_playerPath==L"") return;
- LSLog(LOG_NOTICE, NULL, L"SQBOX : CplayerSQBOX()");
- WCHAR* pbuffer=NULL;
- int len=GetTempPath(0, NULL);
- WCHAR* buffer = new WCHAR[len+1];
- GetTempPath(len, buffer);
- m_CoverPath = buffer;
- m_CoverPath += L"SQBOXCover.png";
- DeleteFile(m_CoverPath.c_str());
- size_t pos;
- std::wstring sTemp=m_playerPath;
- pos = sTemp.find(L":");
- std::wstring server = sTemp.substr(0,pos);
- sTemp = sTemp.substr(pos+1,std::wstring::npos);
- pos = sTemp.find(L" ");
- std::wstring webport = sTemp.substr(0,pos);
- sTemp = sTemp.substr(pos+1,std::wstring::npos);
- m_server = server+L":"+webport;
- g_pCommandHandler = new IO_jsonCommand(L"Rainmeter SQBOX Nowplaying Pluggin", m_server);
- g_pCommandHandler->m_client = sTemp;
- g_pCommandHandler->StartThread();
- g_pCoverHandler = new IO_GETCover(L"Rainmeter SQBOX Nowplaying Pluggin", m_server);
- g_pCoverHandler->m_coverpath = m_CoverPath;
- g_pCoverHandler->StartThread();
- g_pcometSubscribeHandler = new IO_cometSubscribe(L"Rainmeter SQBOX Nowplaying Pluggin", m_server);
- g_pcometSubscribeHandler->m_client = sTemp;
- g_pcometSubscribeHandler->StartThread();
- m_LastCheckTime = GetTickCount();
- m_Initialized = true;
- }
- CPlayerSQBOX::~CPlayerSQBOX()
- {
- m_Initialized = false;
- LSLog(LOG_NOTICE, NULL, L"SQBOX : ~CPlayerSQBOX()");
- c_Player = NULL;
- if (g_pcometSubscribeHandler) {
- delete g_pcometSubscribeHandler;
- }
- if (g_pCommandHandler) {
- delete g_pCommandHandler;
- }
- if (g_pCoverHandler) {
- delete g_pCoverHandler;
- }
- }
- /*
- ** Create
- **
- ** Creates a shared class object.
- **
- */
- CPlayer* CPlayerSQBOX::Create(std::wstring swPlayerPath)
- {
- LSLog(LOG_NOTICE, NULL, L"SQBOX : Create()");
- if (!c_Player)
- {
- c_Player = new CPlayerSQBOX(swPlayerPath);
- }
- return c_Player;
- }
- // UpdateData
- void CPlayerSQBOX::UpdateData()
- {
- EnterCriticalSection(&g_pcometSubscribeHandler->m_CriticalSection);
- m_State = (StateType) g_pcometSubscribeHandler->m_State;
- if (m_Artist!=g_pcometSubscribeHandler->m_Artist || m_Title!=g_pcometSubscribeHandler->m_Title)
- ++m_TrackCount;
- m_Artist = g_pcometSubscribeHandler->m_Artist;
- if (m_Album!=g_pcometSubscribeHandler->m_Album) {
- g_pCoverHandler->CreateCommand(L"/music/" + g_pcometSubscribeHandler->m_songid + L"/cover_96x96_p.png");
- }
- m_Title = g_pcometSubscribeHandler->m_Title;
- m_Album = g_pcometSubscribeHandler->m_Album;
- m_Duration = g_pcometSubscribeHandler->m_Duration;
- if ((m_State == STATE_PLAYING) && (m_LastPosition == g_pcometSubscribeHandler->m_Position)) {
- m_Position = m_LastPosition + (DWORD)(GetTickCount()-m_LastCheckTime)/1000;
- }
- else {
- m_LastPosition = g_pcometSubscribeHandler->m_Position;
- m_Position = m_LastPosition;
- m_LastCheckTime = GetTickCount();
- }
- m_Rating = g_pcometSubscribeHandler->m_Rating;
- m_Volume = g_pcometSubscribeHandler->m_Volume;
- m_Shuffle = g_pcometSubscribeHandler->m_Shuffle;
- m_Repeat = g_pcometSubscribeHandler->m_Repeat;
- LeaveCriticalSection(&g_pcometSubscribeHandler->m_CriticalSection);
- }
- // Play
- void CPlayerSQBOX::Play()
- {
- g_pCommandHandler->CreateCommand(L"play 1");
- }
- // Stop
- void CPlayerSQBOX::Stop()
- {
- g_pCommandHandler->CreateCommand(L"stop 1");
- }
- // Pause
- void CPlayerSQBOX::Pause()
- {
- g_pCommandHandler->CreateCommand(L"pause 1");
- }
- // Next
- void CPlayerSQBOX::Next()
- {
- g_pCommandHandler->CreateCommand(L"button jump_fwd");
- }
- // Previous
- void CPlayerSQBOX::Previous()
- {
- g_pCommandHandler->CreateCommand(L"button jump_rew");
- }
- // SetPosition
- void CPlayerSQBOX::SetPosition(int position)
- {
- wstringstream REQ;
- REQ << L"time ";
- REQ << position;
- g_pCommandHandler->CreateCommand(REQ.str());
- }
- // SetRating
- void CPlayerSQBOX::SetRating(int rating)
- {
- }
- // SetVolume
- void CPlayerSQBOX::SetVolume(int volume)
- {
- wstringstream REQ;
- REQ << L"mixer volume ";
- REQ << volume;
- g_pCommandHandler->CreateCommand(REQ.str());
- }
- // SetShuffle
- void CPlayerSQBOX::SetShuffle(bool state)
- {
- wstringstream REQ;
- REQ << L"playlist shuffle ";
- if (state) REQ << 1; else REQ << 0;
- g_pCommandHandler->CreateCommand(REQ.str());
- }
- // SetRepeat
- void CPlayerSQBOX::SetRepeat(bool state)
- {
- wstringstream REQ;
- REQ << L"playlist repeat ";
- if (state) REQ << 1; else REQ << 0;
- g_pCommandHandler->CreateCommand(REQ.str());
- }
- // ClosePlayer
- void CPlayerSQBOX::ClosePlayer()
- {
- //pause
- g_pCommandHandler->CreateCommand(L"button power");
- }
- // OpenPlayer
- void CPlayerSQBOX::OpenPlayer(std::wstring& path)
- {
- if (!m_Initialized)
- {
- if (path.empty())
- ShellExecute(NULL, L"open", path.c_str(), NULL, NULL, SW_SHOW);
- }
- else
- {
- // Already active, restore the window
- ShowWindow(m_Window, SW_SHOWNORMAL);
- BringWindowToTop(m_Window);
- }
- }
- IO_jsonCommand::IO_jsonCommand(std:: wstring swUserAgent, std::wstring swUrl) : IOTCPSocket(swUserAgent, swUrl),
- m_client(),
- m_command()
- {
- m_verb=L"POST";
- m_hdrs=L"";
- }
- IO_jsonCommand::~IO_jsonCommand(){
- }
- void IO_jsonCommand::IfDisconnected(void)
- {
- m_command=L"";
- IOTCPSocket::IfDisconnected();
- }
- int IO_jsonCommand::CreateCommand(std::wstring sCommand)
- {
- int ret = 0;
- if ((m_command==L"")) {
- m_command=sCommand;
- m_bCommandToSend=true;
- ret=1;
- }
- return ret;
- }
- int IO_jsonCommand::SendOutput()
- {
- int ret = 0;
- if(m_command!=L"") {
- ret = SendCommand(m_command);
- m_command=L"";
- }
- return ret;
- }
- void IO_jsonCommand::ParseCommand(std::wstring swCommand, char** pBuffer, unsigned int* nBufLen)
- {
- std::wstringstream REQ;
- size_t pos;
- std::wstring swTemp=m_command;
- std::wstring swTemp2;
- REQ << "{\"id\":1,\"method\":\"slim.request\",\"params\":[\"" << m_client.c_str() << "\",[";
- pos = swTemp.find_first_of(L" ");
- if (pos != std::string::npos) {
- swTemp2 = swTemp.substr(0,pos);
- REQ << "\"" << swTemp2.c_str() << "\"";
- swTemp = swTemp.substr(pos+1,std::string::npos);
- }
- pos = swTemp.find_first_of(L" ");
- if (pos != std::string::npos) {
- swTemp2 = swTemp.substr(0,pos);
- REQ << ",\"" << swTemp2.c_str() << "\"";
- swTemp = swTemp.substr(pos+1,std::string::npos);
- }
- pos = swTemp.find_first_of(L" ");
- if (pos != std::string::npos) {
- swTemp2 = swTemp.substr(0,pos);
- REQ << ",\"" << swTemp2.c_str() << "\"";
- } else {
- REQ << ",\"" << swTemp.c_str() << "\"";
- }
- REQ << "]]}";
- swTemp = REQ.str();
- std::wstringstream packet;
- packet << m_verb << L" /jsonrpc.js" << L" HTTP/1.1\r\n";
- packet << L"User-Agent:" << m_useragent << L"\r\n";
- //packet << m_hdrs << L"\r\n";
- packet << L"Content-Length:" << swTemp.length() << L"\r\n";
- packet << L"\r\n";
- packet << swTemp;
- std::wstring swTemp3 = packet.str();
- char* str1;
- std::string sTemp = wstos(swTemp3.c_str());
- str1=const_cast<char*>(sTemp.c_str());
- *nBufLen=(unsigned int) swTemp3.length();
- *pBuffer=(char*)new BYTE[*nBufLen];
- std::memcpy(*pBuffer, str1, *nBufLen);
- }
- int IO_jsonCommand::ParseAnswer(char* pBuffer, int nBufLen)
- {
- //on remet l'état intitial
- return 0;
- }
- IO_GETCover::IO_GETCover(std:: wstring swUserAgent, std::wstring swUrl) : IOTCPSocket(swUserAgent, swUrl),
- m_coverpath(),
- m_command()
- {
- m_verb=L"GET";
- m_hdrs=L"";
- }
- IO_GETCover::~IO_GETCover(){
- }
- void IO_GETCover::IfDisconnected(void)
- {
- m_command=L"";
- IOTCPSocket::IfDisconnected();
- }
- int IO_GETCover::CreateCommand(std::wstring sCommand)
- {
- m_filepos=0;
- DeleteFile(m_coverpath.c_str());
- m_command=sCommand;
- m_bCommandToSend=true;
- return 1;
- }
- int IO_GETCover::SendOutput()
- {
- int ret = 0;
- ret = SendCommand(m_command);
- return ret;
- }
- void IO_GETCover::ParseCommand(std::wstring swCommand, char** pBuffer, unsigned int* nBufLen)
- {
- std::wstringstream packet;
- packet << m_verb << L" " << m_command << L" HTTP/1.1\r\n";
- packet << L"User-Agent:" << m_useragent << L"\r\n";
- //packet << m_hdrs << L"\r\n";
- packet << L"Content-Length:0\r\n";
- packet << L"\r\n";
- std::wstring swTemp = packet.str();
- char* str1;
- std::string sTemp = wstos(swTemp.c_str());
- str1=const_cast<char*>(sTemp.c_str());
- *nBufLen=(unsigned int) swTemp.length();
- *pBuffer=(char*)new BYTE[*nBufLen];
- std::memcpy(*pBuffer, str1, *nBufLen);
- }
- int IO_GETCover::ParseAnswer(char* pBuffer, int nBufLen)
- {
- unsigned int top = SIZE_BUF64;
- DWORD dwSize = 0;
- size_t pos=0;
- if (m_filepos==0) {
- m_pngsize=0;
- std::string header = pBuffer;
- pos=header.find("PNG");
- if (pos != std::string::npos) {
- pos-=1;
- pBuffer+=pos;
- nBufLen-=pos;
- m_filepos= pos;
- top -= pos;
- std::string sSize=BreakDownCommand(header, "Content-Length: ");
- m_pngsize=atoi(sSize.c_str());
- }
- } else m_filepos+=nBufLen;
- m_hFile = CreateFile(m_coverpath.c_str(), // name of the write
- FILE_APPEND_DATA, // open for writing
- 0, // do not share
- NULL, // default security
- OPEN_ALWAYS, // create new file only
- FILE_ATTRIBUTE_NORMAL, // normal file
- NULL); // no attr. template
- if (m_hFile != INVALID_HANDLE_VALUE) {
- WriteFile(
- m_hFile, // open file handle
- pBuffer, // start of data to write
- nBufLen, // number of bytes to write
- &dwSize, // number of bytes that were written
- NULL); // no overlapped structure
- CloseHandle(m_hFile);
- }
- return 0;
- }
- std::string IO_GETCover::BreakDownCommand(std::string instr, std::string command)
- {
- std::string outstr;
- size_t pos = instr.find(command);
- if(pos==std::string::npos) return "";
- pos += command.length();
- size_t start = pos;
- //seek end of value
- while (pos<instr.length()) {
- if (instr[pos]!=L'\r') pos++;
- else break;
- }
- return instr.substr(start,pos-start);
- }
- IO_cometSubscribe::IO_cometSubscribe(std::wstring swUserAgent, std::wstring swUrl) : IOTCPSocket(swUserAgent, swUrl),
- m_client(),
- m_clientID(),
- m_songid(),
- m_State(STATE_STOPPED),
- m_Artist(),
- m_Title(),
- m_Album(),
- m_Lyrics(),
- m_CoverPath(),
- m_FilePath(),
- m_Duration(0),
- m_Position(0),
- m_Rating(0),
- m_Volume(0),
- m_Shuffle(false),
- m_Repeat(false),
- m_bNeedHandshake(true),
- m_bNeedConnection(false),
- m_bNeedSubscription(false),
- m_bHandshakeSent(false),
- m_bSubscriptionSent(false),
- m_bConnectionSent(false),
- m_Connected(false)
- {
- m_verb=L"POST";
- m_hdrs=L"Content-Type: text/json";
- m_bCommandToSend=true;
- }
- IO_cometSubscribe::~IO_cometSubscribe(){
- }
- void IO_cometSubscribe::IfDisconnected(void) {
- m_songid=L"";
- m_State=STATE_STOPPED;
- m_Artist=L"";
- m_Title=L"";
- m_Album=L"";
- m_Lyrics=L"";
- m_CoverPath=L"";
- m_FilePath=L"";
- m_Duration=0;
- m_Position=0;
- m_Rating=0;
- m_Volume=0;
- m_Shuffle=false;
- m_Repeat=false;
- m_bNeedHandshake=true;
- m_bNeedConnection=false;
- m_bNeedSubscription=false;
- m_bHandshakeSent=false;
- m_bSubscriptionSent=false;
- m_bConnectionSent=false;
- m_Connected=false;
- IOTCPSocket::IfDisconnected();
- m_bCommandToSend=true;
- }
- int IO_cometSubscribe::SendOutput()
- {
- int ret = 0;
- if(!m_bHandshakeSent && m_bNeedHandshake) {
- std::wstringstream REQ1;
- REQ1 << "[{\"channel\":\"\\/meta\\/handshake\","
- "\"supportedConnectionTypes\":[\"streaming\"],"
- "\"version\":\"1.0\"}]";
- ret=SendCommand(REQ1.str());
- m_bHandshakeSent=true;
- }
- if (!m_bConnectionSent && m_bNeedConnection) {
- std::wstringstream REQ2;
- REQ2 << "[{\"clientId\":\"";
- REQ2 << m_clientID;
- REQ2 << "\",\"connectionType\":\"streaming\",\"channel\":\"\\/meta\\/connect\"},"
- "{\"clientId\":\"";
- REQ2 << m_clientID;
- REQ2 << "\",\"subscription\":\"\\/";
- REQ2 << m_clientID;
- REQ2 << "\\/**\",\"channel\":\"\\/meta\\/subscribe\"}] ";
- ret=SendCommand(REQ2.str());
- m_bConnectionSent=true;
- }
- if(!m_bSubscriptionSent && m_bNeedSubscription) {
- std::wstringstream REQ3;
- REQ3 << "[{\"id\":1,\"data\":{\"request\":[\"";
- REQ3 << m_client.c_str();
- REQ3 << "\",[\"status\",\"-\",\"1\",\"subscribe:30\"]],"
- "\"response\":\"\\/";
- REQ3 << m_clientID;
- REQ3 << "\\/slim\\/status\"},"
- "\"channel\":\"\\/slim\\/subscribe\"}] ";
- ret = SendCommand(REQ3.str());
- m_bSubscriptionSent=true;
- }
- return ret;
- }
- void IO_cometSubscribe::ParseCommand(std::wstring swCommand, char** pBuffer, unsigned int* nBufLen)
- {
- char* str1;
- std::wstringstream packet;
- packet << m_verb << L" /cometd HTTP/1.1\r\n";
- packet << L"User-Agent:" << m_useragent << L"\r\n";
- packet << m_hdrs << L"\r\n";
- packet << L"Content-Length:" << swCommand.length() << L"\r\n";
- packet << L"\r\n";
- packet << swCommand;
- std::wstring swTemp = packet.str();
- std::string sTemp = wstos(swTemp.c_str());
- str1=const_cast<char*>(sTemp.c_str());
- *nBufLen=(unsigned int) sTemp.length();
- *pBuffer=(char*)new BYTE[*nBufLen];
- memcpy(*pBuffer, str1, *nBufLen);
- }
- int IO_cometSubscribe::ParseAnswer(char* pBuffer, int nBufLen)
- {
- if(pBuffer==NULL) return 0;
- std::string sBuffer=(char*)pBuffer;
- std::wstring swAnswer=utf8tows(sBuffer.c_str());
- size_t pos = swAnswer.find(L"[{\"data");
- if (pos != std::string::npos) {
- std::wstring swError = BreakDownCommand(swAnswer, L"error");
- if(swError!=L"") {
- return -1;
- }
- std::wstring swMode = BreakDownCommand(swAnswer, L"mode");
- if (swMode==L"play") m_State = STATE_PLAYING;
- else if (swMode==L"stop") m_State = STATE_STOPPED;
- else if (swMode==L"pause") m_State = STATE_PAUSED;
- else m_State = STATE_PAUSED;
- std::wstring swConnected = BreakDownCommand(swAnswer, L"player_connected");
- if(swConnected!=L"") m_Connected = _wtoi(swConnected.c_str());
- if(m_Connected==0) m_State = STATE_STOPPED;
- std::wstring swSongID = BreakDownCommand(swAnswer, L"id");
- if(swSongID!=L"") m_songid = swSongID.c_str();
- std::wstring swTime = BreakDownCommand(swAnswer, L"time");
- if(swTime!=L"") m_Position = _wtoi(swTime.c_str());
- std::wstring swRate = BreakDownCommand(swAnswer, L"rate");
- if(swRate!=L"") m_Rating = _wtoi(swRate.c_str());
- std::wstring swDuration = BreakDownCommand(swAnswer, L"duration");
- if(swDuration!=L"") m_Duration = _wtoi(swDuration.c_str());
- std::wstring swVolume = BreakDownCommand(swAnswer, L"mixer volume");
- if(swVolume!=L"") m_Volume = _wtoi(swVolume.c_str());
- std::wstring swArtist = BreakDownCommand(swAnswer, L"artist");
- if(swArtist!=L"") m_Artist = swArtist.c_str();
- std::wstring swTitle = BreakDownCommand(swAnswer, L"title");
- if(swTitle!=L"") m_Title = swTitle.c_str();
- std::wstring swAlbum = BreakDownCommand(swAnswer, L"album");
- if(swAlbum!=L"") m_Album = swAlbum.c_str();
- std::wstring swShuffle = BreakDownCommand(swAnswer, L"playlist shuffle");
- if(swShuffle!=L"") m_Shuffle = (bool) _wtoi(swShuffle.c_str());
- std::wstring swRepeat = BreakDownCommand(swAnswer, L"playlist repeat");
- if(swRepeat!=L"") m_Repeat = (bool) _wtoi(swRepeat.c_str());
- } else if (m_bNeedHandshake) {
- std::wstring swClientID = BreakDownCommand(swAnswer, L"clientId");
- if(swClientID!=L"") {
- m_clientID = swClientID.c_str();
- m_bNeedHandshake=false;
- m_bNeedConnection=true;
- m_bCommandToSend=true;
- } else {
- return -1;
- }
- } else if (m_bNeedConnection) {
- std::wstring swSubs = BreakDownCommand(swAnswer, L"successful");
- if(swSubs==L"true") {
- m_bNeedConnection=false;
- m_bNeedSubscription=true;
- m_bCommandToSend=true;
- } else {
- return -1;
- }
- } else if (m_bNeedSubscription) {
- std::wstring swSubs = BreakDownCommand(swAnswer, L"successful");
- if(swSubs==L"true") {
- m_bNeedSubscription=false;
- } else {
- return -1;
- }
- }
- return 0;
- }
- std::wstring IO_cometSubscribe::BreakDownCommand(std::wstring instr, std::wstring command)
- {
- std::wstring outstr;
- size_t pos = instr.find(command);
- if(pos==std::wstring::npos) return L"";
- pos += command.length()+2;
- bool btext=false;
- if (instr[pos]==L'\"') {
- pos+=1;
- btext=true;
- }
- size_t start = pos;
- //seek end of value
- while (pos<instr.length()) {
- if (btext) {
- if (instr[pos]!=L'\"') pos++;
- else break;
- }
- if (!btext) {
- if (instr[pos]!=L'}' && instr[pos]!=L'\"' && instr[pos]!=L',') pos++;
- else break;
- }
- }
- return instr.substr(start,pos-start);
- }
- IOTCPSocket::IOTCPSocket(std::wstring swUserAgent, std::wstring swUrl):
- m_bCommandToSend(false),
- m_bRunning(false),
- m_bRestart(false),
- m_url(swUrl),
- m_useragent(swUserAgent),
- m_verb(),
- m_hdrs(),
- m_s(0),
- m_saddr(NULL),
- m_bDisconnected(true),
- m_LastConnectTime(NULL)
- {
- InitializeCriticalSection(&m_CriticalSection);
- TCPIO_Init();
- }
- IOTCPSocket::~IOTCPSocket(){
- StopThread();
- TCPIO_Cleanup();
- WSACleanup();
- }
- void IOTCPSocket::IfDisconnected(void) {
- m_bDisconnected=true;
- m_bCommandToSend=false;
- TCPIO_Cleanup();
- }
- //OK
- int IOTCPSocket::TCPIO_Cleanup(void)
- {
- if (m_s!=NULL) {
- TCPIO_Close();
- m_s=0;
- }
- if (m_saddr) {
- free(m_saddr);
- m_saddr=NULL;
- }
- return 0;
- }
- //OK
- int IOTCPSocket::TCPIO_Connect()
- {
- if ((GetTickCount()-m_LastConnectTime)<30000) return 0;
- m_LastConnectTime=GetTickCount();
- std::string sTemp = wstos(m_url.c_str());
- m_saddr=TCPIO_CreateSOCKADDR(const_cast<const char*>(sTemp.c_str()));
- if (m_saddr==NULL) {
- return 0;
- }
- // Create socket
- SOCKET s;
- int res;
- s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
- if(s==INVALID_SOCKET) return NULL;
- //setblocking
- u_long argp = 0;
- res = ioctlsocket(s, FIONBIO, &argp);
- if (res==SOCKET_ERROR) {
- int err = WSAGetLastError();
- return NULL;
- }
- int on=1;
- res = setsockopt(s,SOL_SOCKET,SO_REUSEADDR, (const char *)&on, sizeof(on));
- if (res==SOCKET_ERROR) {
- int err = WSAGetLastError();
- return NULL;
- }
- struct linger l;
- l.l_onoff = 0;
- res=setsockopt(s,SOL_SOCKET,SO_LINGER, (const char *)&l,sizeof(l));
- if (res==SOCKET_ERROR) {
- int err = WSAGetLastError();
- return NULL;
- }
- bool ndelay = TRUE;
- res=setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&ndelay,sizeof(BOOL));
- if (res==SOCKET_ERROR) {
- int err = WSAGetLastError();
- return NULL;
- }
- // Connect to remote host
- res=connect(s, (const SOCKADDR*)m_saddr,sizeof(SOCKADDR_IN));
- if (res==SOCKET_ERROR) {
- int err = WSAGetLastError();
- //if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) {
- closesocket(s);
- return NULL;
- //}
- }
- //setnonblocking
- u_long argp = 1;
- res = ioctlsocket(s, FIONBIO, &argp);
- if (res==SOCKET_ERROR) {
- int err = WSAGetLastError();
- return NULL;
- }
- m_s=s;
- return (int)s;
- }
- int IOTCPSocket::TCPIO_Close()
- {
- closesocket(m_s);
- m_s=0;
- return 0;
- }
- bool IOTCPSocket::StartThread(bool bRestart)
- {
- m_bRestart=bRestart;
- m_hThread = CreateThread(NULL, 0, (DWORD (__stdcall *)(LPVOID))&this->RunLoop, this, 0, &m_nThreadID);
- if (m_hThread) return true;
- else return false;
- }
- bool IOTCPSocket::StopThread(const bool bAutoTerminate)
- {
- if (!m_bRunning) return true; //no thread
- while (PostThreadMessage(m_nThreadID, WMSQB_EXIT, 0, NULL) == 0)
- Sleep(100);
- if(!bAutoTerminate) {
- if (WaitForSingleObject(m_hThread, 50000) == WAIT_OBJECT_0)
- return true; //OK
- else
- return false;
- }
- return true;
- }
- void *IOTCPSocket::RunLoop(void *pThis)
- {
- MSG msg;
- IOTCPSocket *pIO;
- pIO=(IOTCPSocket*)pThis;
- pIO->m_bRunning=true;
- do {
- if (pIO->RunOnce()==-1) break;
- if (PeekMessage(&msg,0, WMSQB_EXIT, WMSQB_EXIT, PM_NOREMOVE) != 0)
- break;
- } while (pIO->m_bRestart);
- pIO->m_bRunning=false;
- return NULL;
- }
- int IOTCPSocket::RunOnce()
- {
- int ret=0;
- if (m_bCommandToSend && m_bDisconnected) {
- m_s=TCPIO_Connect();
- if (m_s==0) {
- IfDisconnected();
- } else m_bDisconnected=false;
- }
- if (!m_bDisconnected && m_bCommandToSend && TCPIO_WSelect()>0) {
- ret=SendOutput();
- if (ret==-1) {
- IfDisconnected();
- }
- m_bCommandToSend=false;
- }
- if (!m_bDisconnected && TCPIO_RSelect()>0) {
- ret=GetInput();
- if (ret==-1) {
- IfDisconnected();
- }
- }
- Sleep(100);
- return 0;
- }
- int IOTCPSocket::SendCommand(std::wstring swCommand)
- {
- BYTE* pBuffer=NULL;
- unsigned int nBufLen=0;
- ParseCommand(swCommand, (char **)&pBuffer, &nBufLen);
- int ret = SendBuffer(pBuffer, nBufLen);
- free(pBuffer);
- return ret;
- }
- int IOTCPSocket::GetInput()
- {
- int ret=0;
- BYTE *pBuffer;
- unsigned int nBufLen=0;
- // Check connected socket
- ret=TCPIO_Recv(&pBuffer,&nBufLen);
- if(ret<0) {
- return -1;
- }
- if (ret ==0) {
- }
- if(ret>0) {
- // Breakdown command into response
- if (nBufLen>0) {
- EnterCriticalSection(&m_CriticalSection);
- ret = ParseAnswer((char*)pBuffer, nBufLen);
- LeaveCriticalSection(&m_CriticalSection);
- std::free(pBuffer);
- }
- }
- return ret;
- }
- //OK
- int IOTCPSocket::TCPIO_Init(void)
- {
- WSADATA wsaData;
- WORD wVersionRequested = MAKEWORD(2, 2);
- int err = WSAStartup(wVersionRequested, &wsaData );
- if (err != 0) return -1;
- return 1;
- }
- //OK
- SOCKADDR_IN* IOTCPSocket::TCPIO_CreateSOCKADDR(const char *sTarget)
- {
- // Get target port
- char svHost[256],*sPort,*sptr;
- strncpy(svHost,sTarget,256);
- svHost[255] = '\0';
- for(sptr=svHost;((*sptr)!=':') && (*sptr);sptr++);
- if((*sptr)==':') {
- *sptr='\0';
- sptr++;
- sPort=sptr;
- }
- else {
- return 0;
- }
- // Resolve hostname
- SOCKADDR_IN* saddr;
- saddr = (SOCKADDR_IN*)malloc(sizeof(SOCKADDR_IN));
- SOCKADDR_IN* sockaddr_ipv4=NULL;
- struct addrinfo *result = NULL;
- struct addrinfo *ptr = NULL;
- int gRet = getaddrinfo( svHost, sPort, NULL, &result);
- if(gRet!=0) {
- return 0;
- }
- for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
- switch (ptr->ai_family) {
- case AF_INET:
- sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
- break;
- default:
- break;
- }
- if (sockaddr_ipv4!=NULL) break;
- }
- if (sockaddr_ipv4==NULL) {
- freeaddrinfo(result);
- return NULL;
- }
- // Create socket address
- std::memcpy(saddr,sockaddr_ipv4,sizeof(SOCKADDR_IN));
- freeaddrinfo(result);
- return saddr;
- }
- //OK
- int IOTCPSocket::TCPIO_WSelect()
- {
- int ret;
- TIMEVAL tm;
- fd_set wfds;
- FD_ZERO(&wfds);
- FD_SET(m_s,&wfds);
- tm.tv_sec=0;
- tm.tv_usec=0;
- ret=select((int)m_s+1,NULL,&wfds,NULL,&tm);
- return ret;
- }
- //OK
- int IOTCPSocket::TCPIO_RSelect()
- {
- int ret;
- TIMEVAL tm;
- fd_set rfds;
- FD_ZERO(&rfds);
- FD_SET(m_s,&rfds);
- tm.tv_sec=0;
- tm.tv_usec=0;
- ret=select((int)m_s+1,&rfds,NULL,NULL,&tm);
- return ret;
- }
- //OK
- int IOTCPSocket::SendBuffer(BYTE *pBuffer, unsigned int len)
- {
- if ( (pBuffer == NULL) )
- return 0;
- BYTE *buf;
- int ret;
- int pos=0;
- int size=0;
- unsigned int lBufLen;
- if(len==0) {
- return 0;
- } else {
- while(len>0) {
- size=((len-pos)<SIZE_MTU ) ? len : SIZE_MTU;
- buf=AllocatePacket((BYTE *)pBuffer+pos, size, &lBufLen);
- ret = TCPIO_Send(buf, lBufLen);
- free(buf);
- pos+=size;
- len-=size;
- if (ret==SOCKET_ERROR) break;
- }
- }
- return ret;
- }
- //OK
- BYTE *IOTCPSocket::AllocatePacket(BYTE *pBuffer, unsigned int size, unsigned int *nPktLen)
- {
- BYTE *pTemp;
- int buflen=0;
- if(pBuffer!=NULL) {
- buflen = size;
- }
- pTemp=(BYTE *) malloc(buflen);
- if(pTemp==NULL) {
- return NULL;
- }
- if(pBuffer!=NULL) {
- std::memcpy(pTemp,pBuffer,size);
- }
- *nPktLen=buflen;
- return pTemp;
- }
- //OK
- int IOTCPSocket::TCPIO_Send(const BYTE *pData, unsigned int nDataLen)
- {
- // Make single packet
- void *pkt=malloc(nDataLen);
- if(pkt==NULL) {
- return -1;
- }
- std::memcpy((BYTE *)pkt,pData,nDataLen);
- // Send packet
- int ret;
- char *ppkt=(char *)pkt;
- int count=nDataLen;
- do {
- ret=send(m_s,ppkt,count,0);
- if(ret==SOCKET_ERROR) {
- break;
- }
- count-=ret;
- ppkt+=ret;
- //if(count>0) Sleep(20);
- } while(count>0);
- free(pkt);
- return ret;
- }
- int IOTCPSocket::TCPIO_Recv(BYTE **pInData, unsigned int *pnInDataLen)
- {
- *pnInDataLen=0;
- *pInData=NULL;
- if (m_s==0) {
- return -1;
- }
- // Get length of rest of data
- DWORD nPktLen=SIZE_BUF64;
- int lenret;
- // Allocate buffer for data
- BYTE *buf=(BYTE *)std::malloc(nPktLen+2);
- if(buf==NULL) {
- return -1;
- }
- int i=0;
- while (i<nPktLen+2) {
- buf[i]=0xAA;
- i++;
- }
- // Receive data
- char *pbuf=(char *)buf;
- int count=nPktLen;
- do {
- lenret=recv(m_s,pbuf,count,0);
- if(lenret==0) {
- //Disconnection from server
- free(buf);
- *pInData=NULL;
- *pnInDataLen=0;
- return -1;
- }
- if(lenret==SOCKET_ERROR) {
- if (WSAEWOULDBLOCK != WSAGetLastError()) {
- free(buf);
- *pInData=NULL;
- *pnInDataLen=0;
- return -1;
- }
- break;
- }
- count-=lenret;
- pbuf+=lenret;
- *pnInDataLen+=lenret;
- if(lenret!=0 && lenret<count ) {
- break;
- }
- //if(count>0) Sleep(20);
- } while(count>0);
- // Pass data back to application
- pbuf[0]=0;
- *pInData=buf;
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement