bool CHarmonyHub::SendPing() { boost::lock_guard<boost::mutex> lock(m_mutex); if (m_commandcsocket == NULL || m_szAuthorizationToken.size() == 0) { return false; } std::string strData; std::string sendData; // GENERATE A LOGIN ID REQUEST USING THE HARMONY ID AND LOGIN AUTHORIZATION TOKEN sendData = "<iq type=\"get\" id=\""; sendData.append(CONNECTION_ID); sendData.append("\"><oa xmlns=\"connect.logitech.com\" mime=\"vnd.logitech.connect/vnd.logitech.ping\">token="); sendData.append(m_szAuthorizationToken.c_str()); sendData.append(":name=foo#iOS8.3.0#iPhone</oa></iq>"); m_commandcsocket->write(sendData.c_str(), sendData.size()); bool bIsDataReadable = true; m_commandcsocket->canRead(&bIsDataReadable, 5.0f); while (bIsDataReadable) { if (memset(m_databuffer, 0, BUFFER_SIZE) > 0) { m_commandcsocket->read(m_databuffer, BUFFER_SIZE, false); std::string szNewData = std::string(m_databuffer); if (!szNewData.empty()) { strData.append(m_databuffer); m_commandcsocket->canRead(&bIsDataReadable, 0.4f); } else bIsDataReadable = false; } else bIsDataReadable = false; } if (strData.empty()) return false; CheckIfChanging(strData); return (strData.find("errorcode='200'") != std::string::npos); }
int CHarmonyHub::SubmitCommand(csocket* m_commandcsocket, const std::string& m_szAuthorizationToken, const std::string strCommand, const std::string strCommandParameterPrimary, const std::string strCommandParameterSecondary) { boost::lock_guard<boost::mutex> lock(m_mutex); int pos; if(m_commandcsocket== NULL || m_szAuthorizationToken.length() == 0) { //errorString = "SubmitCommand : NULL csocket or empty authorization token provided"; return 1; } std::string lstrCommand = strCommand; if(lstrCommand.length() == 0) { // No command provided, return query for the current activity lstrCommand = "get_current_activity_id"; } std::string strData; std::string sendData; sendData = "<iq type=\"get\" id=\""; sendData.append(CONNECTION_ID); sendData.append("\"><oa xmlns=\"connect.logitech.com\" mime=\"vnd.logitech.harmony/vnd.logitech.harmony.engine?"); // Issue the provided command if(lstrCommand == "get_current_activity_id" || lstrCommand == "get_current_activity_id_raw") { sendData.append("getCurrentActivity\" /></iq>"); } if(lstrCommand == "get_config_raw") { sendData.append("config\"></oa></iq>"); } else if (lstrCommand == "start_activity") { sendData.append("startactivity\">activityId="); sendData.append(strCommandParameterPrimary.c_str()); sendData.append(":timestamp=0</oa></iq>"); } else if (lstrCommand == "issue_device_command") { sendData.append("holdAction\">action={\"type\"::\"IRCommand\",\"deviceId\"::\""); sendData.append(strCommandParameterPrimary.c_str()); sendData.append("\",\"command\"::\""); sendData.append(strCommandParameterSecondary.c_str()); sendData.append("\"}:status=press</oa></iq>"); } m_commandcsocket->write(sendData.c_str(), sendData.length()); //memset(m_databuffer, 0, BUFFER_SIZE); //m_commandcsocket->read(m_databuffer, BUFFER_SIZE, false); //strData = m_databuffer; /* <- Expect: strData == <iq/> */ /*std::string iqTag = "<iq/>"; D = (int)strData.find(iqTag);*/ //if(pos<=0) // return 1; //error parsing the result bool bIsDataReadable = true; m_commandcsocket->canRead(&bIsDataReadable,0.4f); while(bIsDataReadable) { if(memset(m_databuffer, 0, BUFFER_SIZE)>0) { m_commandcsocket->read(m_databuffer, BUFFER_SIZE, false); strData.append(m_databuffer); m_commandcsocket->canRead(&bIsDataReadable,0.4f); } else bIsDataReadable=false; } CheckIfChanging(strData); //m_commandcsocket->canRead(&bIsDataReadable,1.0f); /*if(bIsDataReadable == false && strData == "<iq/>") { bIsDataReadable = true; }*/ //if(strCommand != "issue_device_command") //{ // /*while(bIsDataReadable) // { // memset(m_databuffer, 0, BUFFER_SIZE); // m_commandcsocket->read(m_databuffer, BUFFER_SIZE, false); // if(strlen(m_databuffer)==0) // return 1; // strData.append(m_databuffer); // m_commandcsocket->canRead(&bIsDataReadable, 1.0f); // }*/ // //check for the presence of startactivity or activityfinished // //strData.find("startActivityFinished")!=0 || // CheckIfChanging(strData); //} if(strCommand == "get_current_activity_id" || strCommand == "get_current_activity_id_raw") { std::string resultTag= "result="; std::string resultEnd= "]]>"; m_szResultString = strData; int resultStartPos = (int)m_szResultString.find(resultTag); int resultEndPos = (int)m_szResultString.find(resultEnd,resultStartPos); if(resultStartPos != std::string::npos && resultEndPos != std::string::npos) { m_szResultString = m_szResultString.substr(resultStartPos + 7, resultEndPos - resultStartPos - 7); /*if(strCommand == "get_current_activity_id") { m_szResultString.insert(0, "Current Activity ID is : "); }*/ } else { if(m_bIsChangingActivity) m_szResultString = m_szCurActivityID; //changing, so no repsonse from HH else return 1; } } else if(strCommand == "get_config" || strCommand == "get_config_raw") { m_commandcsocket->canRead(&bIsDataReadable, 0.4f); //#ifndef WIN32 // bIsDataReadable = true; //#endif // while(bIsDataReadable) { memset(m_databuffer, 0, BUFFER_SIZE); m_commandcsocket->read(m_databuffer, BUFFER_SIZE, false); strData.append(m_databuffer); m_commandcsocket->canRead(&bIsDataReadable,0.4f); } pos = strData.find("![CDATA[{"); if(pos != std::string::npos) { m_szResultString = "Logitech Harmony Configuration : \n" + strData.substr(pos + 9); } } else if (strCommand == "start_activity" || strCommand == "issue_device_command") { m_szResultString = ""; } return 0; }
bool CHarmonyHub::SubmitCommand(const std::string strCommand, const std::string strCommandParameterPrimary, const std::string strCommandParameterSecondary) { boost::lock_guard<boost::mutex> lock(m_mutex); int pos; if(m_commandcsocket== NULL || m_szAuthorizationToken.size() == 0) { //errorString = "SubmitCommand : NULL csocket or empty authorization token provided"; return false; } std::string lstrCommand = strCommand; if(lstrCommand.size() == 0) { // No command provided, return query for the current activity lstrCommand = GET_CURRENT_ACTIVITY_COMMAND; } std::string strData; std::string sendData; sendData = "<iq type=\"get\" id=\""; sendData.append(CONNECTION_ID); sendData.append("\"><oa xmlns=\"connect.logitech.com\" mime=\"vnd.logitech.harmony/vnd.logitech.harmony.engine?"); // Issue the provided command if (lstrCommand == GET_CURRENT_ACTIVITY_COMMAND || lstrCommand == GET_CURRENT_ACTIVITY_COMMAND_RAW) { sendData.append("getCurrentActivity\" /></iq>"); } else if (lstrCommand == GET_CONFIG_COMMAND_RAW) { sendData.append("config\"></oa></iq>"); } else if (lstrCommand == "start_activity") { sendData.append("startactivity\">activityId="); sendData.append(strCommandParameterPrimary.c_str()); sendData.append(":timestamp=0</oa></iq>"); } else if (lstrCommand == "issue_device_command") { sendData.append("holdAction\">action={\"type\"::\"IRCommand\",\"deviceId\"::\""); sendData.append(strCommandParameterPrimary.c_str()); sendData.append("\",\"command\"::\""); sendData.append(strCommandParameterSecondary.c_str()); sendData.append("\"}:status=press</oa></iq>"); } m_commandcsocket->write(sendData.c_str(), sendData.size()); bool bIsDataReadable = true; m_commandcsocket->canRead(&bIsDataReadable,5.0f); while(bIsDataReadable) { if(memset(m_databuffer, 0, BUFFER_SIZE)>0) { m_commandcsocket->read(m_databuffer, BUFFER_SIZE, false); std::string szNewData = std::string(m_databuffer); if (!szNewData.empty()) { strData.append(m_databuffer); m_commandcsocket->canRead(&bIsDataReadable, 0.4f); } else bIsDataReadable = false; } else bIsDataReadable=false; } if (strData.empty()) return false; CheckIfChanging(strData); if (strCommand == GET_CURRENT_ACTIVITY_COMMAND || strCommand == GET_CURRENT_ACTIVITY_COMMAND_RAW) { pos = strData.find("result="); if (pos != std::string::npos) { strData = strData.substr(pos + 7); pos = strData.find("]]>"); if (pos != std::string::npos) { strData = strData.substr(0, pos); m_szResultString = strData; return true; } } else { //No valid response received if (m_bIsChangingActivity) m_szResultString = m_szCurActivityID; //changing, so no response from HH else return false; } } else if (strCommand == GET_CONFIG_COMMAND || strCommand == GET_CONFIG_COMMAND_RAW) { m_commandcsocket->canRead(&bIsDataReadable, 2.0f); //#ifndef WIN32 // bIsDataReadable = true; //#endif // while(bIsDataReadable) { memset(m_databuffer, 0, BUFFER_SIZE); m_commandcsocket->read(m_databuffer, BUFFER_SIZE, false); std::string szNewData = std::string(m_databuffer); if (!szNewData.empty()) { strData.append(m_databuffer); m_commandcsocket->canRead(&bIsDataReadable, 0.4f); } else bIsDataReadable = false; } pos = strData.find("<![CDATA["); if (pos == std::string::npos) return false; strData=strData.substr(pos + 9); pos = strData.find("]]>"); if (pos != std::string::npos) { m_szResultString = strData.substr(0, pos); } } else if (strCommand == "start_activity" || strCommand == "issue_device_command") { m_szResultString = ""; } return true; }
void CHarmonyHub::Do_Work() { _log.Log(LOG_STATUS,"Harmony Hub: Worker thread started..."); //start with getting the activities int scounter = 0; int mcounter = 0; bool bFirstTime = true; while (!m_stoprequested) { sleep_milliseconds(500); if (m_stoprequested) break; mcounter++; if (mcounter<2) continue; mcounter = 0; scounter++; if (scounter % 12 == 0) { m_LastHeartbeat=mytime(NULL); } if (m_bDoLogin) { if ((scounter%HARMONY_RETRY_LOGIN_SECONDS == 0) || (bFirstTime)) { bFirstTime = false; if(Login() && SetupCommandSocket()) { m_bDoLogin=false; if (!UpdateCurrentActivity()) { Logout(); m_bDoLogin = true; } else { if (!UpdateActivities()) { Logout(); m_bDoLogin = true; } } } } continue; } if (scounter % HARMONY_PING_INTERVAL_SECONDS == 0) { //Ping the server if (!SendPing()) { _log.Log(LOG_STATUS, "Harmony Hub: Error pinging server.. Resetting connection."); Logout(); } continue; } bool bIsDataReadable = true; m_commandcsocket->canRead(&bIsDataReadable, 0.5f); if (bIsDataReadable) { boost::lock_guard<boost::mutex> lock(m_mutex); std::string strData; while (bIsDataReadable) { if (memset(m_databuffer, 0, BUFFER_SIZE) > 0) { m_commandcsocket->read(m_databuffer, BUFFER_SIZE, false); std::string szNewData = std::string(m_databuffer); if (!szNewData.empty()) { strData.append(m_databuffer); m_commandcsocket->canRead(&bIsDataReadable, 0.4f); } else bIsDataReadable = false; } else bIsDataReadable = false; } if (!strData.empty()) CheckIfChanging(strData); } } _log.Log(LOG_STATUS,"Harmony Hub: Worker stopped..."); }
bool CHarmonyHub::SendPing() { int res; boost::lock_guard<boost::mutex> lock(m_mutex); if (m_commandcsocket == NULL || m_szAuthorizationToken.size() == 0) { return false; } std::string strData; std::string sendData; // GENERATE A LOGIN ID REQUEST USING THE HARMONY ID AND LOGIN AUTHORIZATION TOKEN sendData = "<iq type=\"get\" id=\""; sendData.append(CONNECTION_ID); sendData.append("\"><oa xmlns=\"connect.logitech.com\" mime=\"vnd.logitech.connect/vnd.logitech.ping\">token="); sendData.append(m_szAuthorizationToken.c_str()); sendData.append(":name=foo#iOS8.3.0#iPhone</oa></iq>"); m_commandcsocket->write(sendData.c_str(), sendData.size()); bool bIsDataReadable = true; memset(m_databuffer, 0, BUFFER_SIZE); res= m_commandcsocket->read(m_databuffer, BUFFER_SIZE, false); if (res <= 0) { /* there should be some bytes received so <= 0 is not good */ return false; } strData = m_databuffer; if(strData.compare("<iq/>") == 0) { /* must be new SW version 4.10.30+ so read ping confirmation */ memset(m_databuffer, 0, BUFFER_SIZE); res= m_commandcsocket->read(m_databuffer, BUFFER_SIZE, false); if (res <= 0) { /* there should be some bytes received so <= 0 is not good */ return false; } } strData = m_databuffer; /* <- Expect: strData == 200 */ /* */ /* m_commandcsocket->canRead(&bIsDataReadable, 5.0f); */ /* while (bIsDataReadable) */ /* { */ /* if (memset(m_databuffer, 0, BUFFER_SIZE) > 0) */ /* { */ /* m_commandcsocket->read(m_databuffer, BUFFER_SIZE, false); */ /* std::string szNewData = std::string(m_databuffer); */ /* if (!szNewData.empty()) */ /* { */ /* strData.append(m_databuffer); */ /* m_commandcsocket->canRead(&bIsDataReadable, 0.4f); */ /* } */ /* else */ /* bIsDataReadable = false; */ /* } */ /* else */ /* bIsDataReadable = false; */ /* } */ /* */ if (strData.empty()) return false; CheckIfChanging(strData); return (strData.find("errorcode='200'") != std::string::npos); }
int CHarmonyHub::SubmitCommand(csocket* m_commandcsocket, const std::string& m_szAuthorizationToken, const std::string strCommand, const std::string strCommandParameterPrimary, const std::string strCommandParameterSecondary) { boost::lock_guard<boost::mutex> lock(m_mutex); if(m_commandcsocket== NULL || m_szAuthorizationToken.length() == 0) { //errorString = "SubmitCommand : NULL csocket or empty authorization token provided"; return 1; } std::string lstrCommand = strCommand; if(lstrCommand.length() == 0) { // No command provided, return query for the current activity lstrCommand = "get_current_activity_id"; return 0; } std::string strData; std::string sendData; sendData = "<iq type=\"get\" id=\""; sendData.append(CONNECTION_ID); sendData.append("\"><oa xmlns=\"connect.logitech.com\" mime=\"vnd.logitech.harmony/vnd.logitech.harmony.engine?"); // Issue the provided command if(lstrCommand == "get_current_activity_id" || lstrCommand == "get_current_activity_id_raw") { sendData.append("getCurrentActivity\" /></iq>"); } if(lstrCommand == "get_config_raw") { sendData.append("config\"></oa></iq>"); } else if (lstrCommand == "start_activity") { sendData.append("startactivity\">activityId="); sendData.append(strCommandParameterPrimary.c_str()); sendData.append(":timestamp=0</oa></iq>"); } else if (lstrCommand == "issue_device_command") { sendData.append("holdAction\">action={\"type\"::\"IRCommand\",\"deviceId\"::\""); sendData.append(strCommandParameterPrimary.c_str()); sendData.append("\",\"command\"::\""); sendData.append(strCommandParameterSecondary.c_str()); sendData.append("\"}:status=press</oa></iq>"); } m_commandcsocket->write(sendData.c_str(), sendData.length()); memset(m_databuffer, 0, 1000000); m_commandcsocket->read(m_databuffer, 1000000, false); strData = m_databuffer; /* <- Expect: strData == <iq/> */ std::string iqTag = "<iq/>"; int pos = (int)strData.find(iqTag); bool bIsDataReadable = false; bool wasChanged =false; while(pos != 0) { wasChanged = CheckIfChanging(strData); m_commandcsocket->canRead(&bIsDataReadable, 0.6f); if(bIsDataReadable) { //activity changing //read again memset(m_databuffer, 0, 1000000); m_commandcsocket->read(m_databuffer, 1000000, false); if(strlen(m_databuffer)==0) return 1; strData.append ( m_databuffer); /* <- Expect: strData == <iq/> */ pos = (int)strData.find(iqTag); } else if(wasChanged) return 0; else { //printf(strData.c_str()); //errorString = "SubmitCommand: Invalid Harmony response"; return 1; } } CheckIfChanging(strData); m_commandcsocket->canRead(&bIsDataReadable, 0.6f); if(bIsDataReadable == false && strData == "<iq/>") { bIsDataReadable = true; } if(strCommand != "issue_device_command") { while(bIsDataReadable) { memset(m_databuffer, 0, 1000000); m_commandcsocket->read(m_databuffer, 1000000, false); if(strlen(m_databuffer)==0) return 1; strData.append(m_databuffer); m_commandcsocket->canRead(&bIsDataReadable, 0.3f); } } m_szResultString = strData; //check for the presence of startactivity or activityfinished //strData.find("startActivityFinished")!=0 || CheckIfChanging(strData); if(strCommand == "get_current_activity_id" || strCommand == "get_current_activity_id_raw") { int resultStartPos = m_szResultString.find("result="); int resultEndPos = m_szResultString.find("]]>",resultStartPos); if(resultStartPos != std::string::npos && resultEndPos != std::string::npos) { m_szResultString = m_szResultString.substr(resultStartPos + 7, resultEndPos - resultStartPos - 7); if(m_szResultString.find("]]") != std::string::npos) _log.Log(LOG_STATUS,"Error"); if(strCommand == "get_current_activity_id") { m_szResultString.insert(0, "Current Activity ID is : "); } } else m_szResultString=""; } else if(strCommand == "get_config" || strCommand == "get_config_raw") { m_commandcsocket->canRead(&bIsDataReadable, 0.3f); #ifndef WIN32 bIsDataReadable = true; #endif while(bIsDataReadable) { memset(m_databuffer, 0, 1000000); m_commandcsocket->read(m_databuffer, 1000000, false); strData.append(m_databuffer); m_commandcsocket->canRead(&bIsDataReadable, 0.3f); } pos = strData.find("![CDATA[{"); if(pos != std::string::npos) { m_szResultString = "Logitech Harmony Configuration : \n" + strData.substr(pos + 9); } } else if (strCommand == "start_activity" || strCommand == "issue_device_command") { m_szResultString = ""; } return 0; }