1 #include "stdafx.h"
2 #include "CurrentCostMeterTCP.h"
3 #include "../main/Logger.h"
4 #include "../main/Helper.h"
5 #include "../main/localtime_r.h"
6 #include <iostream>
7
8 #define RETRY_DELAY 30
9
CurrentCostMeterTCP(const int ID,const std::string & IPAddress,const unsigned short usIPPort)10 CurrentCostMeterTCP::CurrentCostMeterTCP(const int ID, const std::string &IPAddress, const unsigned short usIPPort):
11 m_retrycntr(RETRY_DELAY),
12 m_szIPAddress(IPAddress),
13 m_usIPPort(usIPPort),
14 m_socket(INVALID_SOCKET)
15 {
16 m_HwdID=ID;
17 }
18
~CurrentCostMeterTCP(void)19 CurrentCostMeterTCP::~CurrentCostMeterTCP(void)
20 {
21 }
22
StartHardware()23 bool CurrentCostMeterTCP::StartHardware()
24 {
25 RequestStart();
26
27 memset(&m_addr,0,sizeof(sockaddr_in));
28 m_addr.sin_family = AF_INET;
29 m_addr.sin_port = htons(m_usIPPort);
30
31 unsigned long ip;
32 ip=inet_addr(m_szIPAddress.c_str());
33
34 // if we have a error in the ip, it means we have entered a string
35 if(ip!=INADDR_NONE)
36 {
37 m_addr.sin_addr.s_addr=ip;
38 }
39 else
40 {
41 // change Hostname in serveraddr
42 hostent *he=gethostbyname(m_szIPAddress.c_str());
43 if(he==NULL)
44 {
45 return false;
46 }
47 else
48 {
49 memcpy(&(m_addr.sin_addr),he->h_addr_list[0],4);
50 }
51 }
52
53 //force connect the next first time
54 m_retrycntr=RETRY_DELAY;
55 m_bIsStarted=true;
56
57 //Start worker thread
58 m_thread = std::make_shared<std::thread>(&CurrentCostMeterTCP::Do_Work, this);
59 SetThreadNameInt(m_thread->native_handle());
60 return (m_thread != nullptr);
61 }
62
isConnected()63 bool CurrentCostMeterTCP::isConnected()
64 {
65 return (m_socket != INVALID_SOCKET);
66 }
67
StopHardware()68 bool CurrentCostMeterTCP::StopHardware()
69 {
70 if (m_thread)
71 {
72 RequestStop();
73 disconnect(); //force socket close to unblock the read request in the thread
74 m_thread->join();
75 m_thread.reset();
76 }
77 m_bIsStarted=false;
78 return true;
79 }
80
ConnectInternal()81 bool CurrentCostMeterTCP::ConnectInternal()
82 {
83 m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
84 if (m_socket == INVALID_SOCKET)
85 {
86 Log(LOG_ERROR,"could not create a TCP/IP socket!");
87 return false;
88 }
89
90 // connect to the server
91 int nRet;
92 nRet = connect(m_socket,(const sockaddr*)&m_addr, sizeof(m_addr));
93 if (nRet == SOCKET_ERROR)
94 {
95 closesocket(m_socket);
96 m_socket=INVALID_SOCKET;
97 Log(LOG_ERROR,"could not connect to: %s:%d",m_szIPAddress.c_str(),m_usIPPort);
98 return false;
99 }
100
101 Log(LOG_STATUS,"connected to: %s:%d", m_szIPAddress.c_str(), m_usIPPort);
102
103 Init();
104
105 sOnConnected(this);
106 return true;
107 }
108
disconnect()109 void CurrentCostMeterTCP::disconnect()
110 {
111 if (m_socket==INVALID_SOCKET)
112 return;
113 closesocket(m_socket);
114 m_socket=INVALID_SOCKET;
115 }
116
117
Do_Work()118 void CurrentCostMeterTCP::Do_Work()
119 {
120 int sec_counter = 0;
121 while (!IsStopRequested(100))
122 {
123 if (m_socket == INVALID_SOCKET)
124 {
125 if (!IsStopRequested(900)) //+100 = 1000
126 {
127 sec_counter++;
128
129 if (sec_counter % 12 == 0) {
130 m_LastHeartbeat = mytime(NULL);
131 }
132
133 m_retrycntr++;
134 if (m_retrycntr >= RETRY_DELAY)
135 {
136 m_retrycntr = 0;
137 if (!ConnectInternal())
138 {
139 Log(LOG_STATUS, "retrying in %d seconds...", RETRY_DELAY);
140 continue;
141 }
142 }
143 }
144 }
145 else
146 {
147 char data[1028];
148 int bread=recv(m_socket,data,sizeof(data),0);
149 if (IsStopRequested(100))
150 break;
151 m_LastHeartbeat=mytime(NULL);
152 if ((bread==0)||(bread<0))
153 {
154 disconnect();
155 Log(LOG_ERROR, "TCP/IP connection closed!, retrying in %d seconds...", RETRY_DELAY);
156 m_retrycntr = 0;
157 continue;
158 }
159 ParseData(data, bread);
160 }
161 }
162 Log(LOG_STATUS,"TCP/IP Worker stopped...");
163 }
164
write(const char *,size_t)165 void CurrentCostMeterTCP::write(const char* /*data*/, size_t /*size*/)
166 {
167 }
168
WriteToHardware(const char * pdata,const unsigned char length)169 bool CurrentCostMeterTCP::WriteToHardware(const char *pdata, const unsigned char length)
170 {
171 if (!isConnected())
172 return false;
173 write(pdata,length);
174 return true;
175 }
176