void SolarMaxTCP::Do_Work() { char buf[1024]; bool bFirstTime = true; int sec_counter = POLL_INTERVAL-5; while (!m_stoprequested) { sleep_seconds(1); sec_counter++; if (sec_counter % 12 == 0) { m_LastHeartbeat=mytime(NULL); } if ( (m_socket == INVALID_SOCKET) && (!m_stoprequested) ) { if (m_stoprequested) break; m_retrycntr++; if (m_retrycntr >= RETRY_DELAY) { m_retrycntr = 0; if (!ConnectInternal()) { _log.Log(LOG_STATUS, "SolarMax: retrying in %d seconds...", RETRY_DELAY); } } } else { if ((sec_counter % POLL_INTERVAL == 0) || (bFirstTime)) { bFirstTime = false; //Request data from inverter std::string reqString = MakeRequestString(); write(reqString.c_str(), reqString.size()); //this could take a long time... maybe there will be no data received at all, //so it's no good to-do the heartbeat timing here int bread = recv(m_socket, (char*)&buf, sizeof(buf), 0); if (m_stoprequested) break; if (bread <= 0) { _log.Log(LOG_ERROR, "SolarMax: TCP/IP connection closed! %s", m_szIPAddress.c_str()); closesocket(m_socket); m_socket = INVALID_SOCKET; if (!m_stoprequested) { _log.Log(LOG_STATUS, "SolarMax: retrying in %d seconds...", RETRY_DELAY); m_retrycntr = 0; continue; } } else { boost::lock_guard<boost::mutex> l(readQueueMutex); ParseData((const unsigned char *)&buf, bread); } } } } _log.Log(LOG_STATUS, "SolarMax: TCP/IP Worker stopped..."); }
bool CHttpRequest::GetHTTP(float HTTPVersion) { /* HTTP request */ CString Request; MakeRequestString(HTTPVersion, &Request); Trace(tagHttp, levInfo, ("CHttpRequest - Request {\n%s}", Request.GetBuffer())); if (m_Dump) { cout << "-=-=-=-=-=-=-=-=- Request -=-=-=-=-=-=-=-=-" << endl << Request << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl; } if (!m_ClientSocket.Write(Request)) return false; /* HTTP response, header */ m_ClientSocket.ReadLine(&m_RStatusString); Trace(tagHttp, levInfo, ("CHttpRequest - StatusString {%s}", m_RStatusString.GetBuffer())); if (! ParseStatusString()) { m_RData = m_RStatusString; } if (m_RStatusValue > 0) { // finish reading headers CString OneLine; m_ClientSocket.ReadLine(&OneLine); if (m_Dump) { cout << "-=-=-=-=-=-=-=-=- Response -=-=-=-=-=-=-=-" << endl << m_RStatusString << endl; } Trace(tagHttp, levInfo, ("CHttpRequest - Response (start) : %s", m_RStatusString.GetBuffer())); while (OneLine.GetLength()) { if (m_Dump) { cout << OneLine << endl; } CStringTable Table; CString Name, Value; if (CMimeParser::ParseLine(OneLine, Name, Value, Table)) { Trace(tagHttp, levInfo, ("CHttpRequest - Response (continued): %d | %s <table> (%d)", OneLine.GetLength(), Name.GetBuffer(), Table.GetSize())); Trace(tagHttp, levInfo, ("CHttpRequest - %s", OneLine.GetBuffer())); m_RFields.Add(Name, Table); m_RPairFields.Add(CStringPair(Name, Value)); } else { Trace(tagHttp, levInfo, ("CHttpRequest - Response (continued): %s (parser failed, ignoring)", OneLine.GetBuffer())); // ignore malformed lines // $(TODO): support P3P, which looks like P3P CP= ... // m_RStatusValue = 400 // return false; } m_ClientSocket.ReadLine(&OneLine); } if (m_Dump) { cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl; } Trace(tagHttp, levInfo, ("CHttpRequest - Response (done)")); } if ((m_RequestMethod != htGet)&&(m_RequestMethod != htPost)) return true; CString ContentLengthString = m_RFields.FindElement(g_strHttpContentLength).GetValue(g_strHttpContentLength); int ContentLengthExpected = 0; if (! ContentLengthString.IsInt(& ContentLengthExpected)) ContentLengthExpected = -1; Trace(tagHttp, levInfo, ("CHttpRequest::GetHTTP() - expected content-length: %s {%d}", ContentLengthString.GetBuffer(), ContentLengthExpected)); m_RData.Empty(); // document is going to be larger than the current maximum document size limit if ((ContentLengthExpected > 0) && (m_RequestSizeLimit > 0) && (m_RequestSizeLimit < ContentLengthExpected)) { m_RStatusValue = 206; // partial content } else { if (ContentLengthExpected > 0) { m_ClientSocket.Read(& m_RData, ContentLengthExpected); if (ContentLengthExpected != (int) m_RData.GetLength()) { Trace(tagHttp, levInfo, ("CHttpRequest::GetHTTP() - expected %d bytes, read %d. (207 Partial Content)", ContentLengthExpected, m_RData.GetLength())); m_RStatusValue = 207; // partial Content-Length return false; } } else if ((ContentLengthExpected < 0) && (m_RStatusValue == 200)) { // content-length was not explicitly zero and the status value says that data should be available m_ClientSocket.Read(& m_RData, m_RequestSizeLimit); } if (m_RStatusValue <= 0) { m_RStatusValue = (m_RData.GetLength() > 0) ? 200 : 204; if (!m_RData.GetLength()) return false; } } Trace(tagHttp, levInfo, ("CHttpRequest::GetHTTP() - m_RStatusValue {%d}", m_RStatusValue)); Trace(tagHttp, levInfo, ("CHttpRequest::GetHTTP() - m_RData.Length {%d}", m_RData.GetLength())); return true; }