Пример #1
0
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...");
}
Пример #2
0
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;
}