1 #include <ciso646>
2 #include <string.h>
3 #ifdef __unix__
4 #include <unistd.h>
5 #include <stdio.h>
6 #include <sys/time.h>
7 #include <sys/socket.h>
8 #include <netinet/in.h>
9 #include <arpa/inet.h>
10 #else
11 #include <windows.h>
12 #endif
13 #include <fcntl.h>
14 #include <thread>
15 #include <chrono>
16 #include "LMS64CProtocol.h"
17 #include "Logger.h"
18 #include "threadHelper.h"
19
20 namespace lime
21 {
22
InitRemote()23 void LMS64CProtocol::InitRemote()
24 {
25 remoteOpen = true;
26 socketFd = -1;
27 const int port = 5000;
28 #ifndef __unix__
29 WSADATA wsaData;
30 if( int err = WSAStartup(0x0202, &wsaData))
31 lime::log(LOG_LEVEL_ERROR, "RemoteControl: WSAStartup error %i\n", err);
32 #endif
33
34 socketFd = socket(AF_INET, SOCK_STREAM, 0);
35 if(socketFd < 0)
36 {
37 lime::log(LOG_LEVEL_ERROR, "RemoteControl: socket error %i\n", socketFd);
38 return;
39 }
40 #ifdef __unix__
41 fcntl(socketFd, F_SETFL, O_NONBLOCK);
42 #else
43 u_long NonBlock = 1;
44 ioctlsocket(socketFd, FIONBIO, &NonBlock);
45 #endif
46
47 struct sockaddr_in host;
48 memset((void *)&host, 0, sizeof(sockaddr_in));
49 host.sin_family = AF_INET;
50 host.sin_addr.s_addr = INADDR_ANY;
51 host.sin_port = htons(port);
52 if(bind(socketFd, (struct sockaddr*)&host, sizeof(host)) < 0)
53 {
54 lime::log(LOG_LEVEL_ERROR, "RemoteControl: bind error on port %i\n", port);
55 CloseRemote();
56 return;
57 }
58
59 lime::log(LOG_LEVEL_INFO, "RemoteControl Listening on port: %i\n", port);
60 if(int error = listen(socketFd, SOMAXCONN) )
61 {
62 #ifndef __unix__
63 error = WSAGetLastError();
64 #endif
65 lime::log(LOG_LEVEL_ERROR, "RemoteControl listen error %i\n", error);
66 CloseRemote();
67 return;
68 }
69
70 remoteThread = std::thread(&LMS64CProtocol::ProcessConnections, this);
71 SetOSThreadPriority(ThreadPriority::LOW, ThreadPolicy::DEFAULT, &remoteThread);
72 if(not remoteThread.joinable())
73 {
74 lime::log(LOG_LEVEL_ERROR, "RemoteControl: Error creating listening thread\n");
75 CloseRemote();
76 return;
77 }
78 return;
79 }
80
CloseRemote()81 void LMS64CProtocol::CloseRemote()
82 {
83 if (!remoteOpen)
84 return;
85 remoteOpen = false;
86
87 if(remoteThread.joinable())
88 remoteThread.join();
89
90 if(socketFd > 0)
91 {
92 #ifndef __unix__
93 //shutdown(socketFd, SD_BOTH);
94 closesocket(socketFd);
95 #else
96 shutdown(socketFd, SHUT_RDWR);
97 close(socketFd);
98 #endif
99 }
100
101 #ifndef __unix__
102 WSACleanup();
103 #endif
104 }
105
106
ProcessConnections()107 void LMS64CProtocol::ProcessConnections()
108 {
109 struct sockaddr_in cli_addr;
110 #ifndef __unix__
111 SOCKET clientFd;
112 int clilen = sizeof(cli_addr);
113 #else
114 int clientFd;
115 unsigned int clilen = sizeof(cli_addr);
116 #endif // __unix__
117
118 while(remoteOpen && socketFd >= 0)
119 {
120 memset(&cli_addr, 0, sizeof(cli_addr));
121 clientFd = accept(socketFd, (struct sockaddr*)&cli_addr, &clilen);
122
123 //if(clientFd == EAGAIN || clientFd == EWOULDBLOCK)
124 //continue;
125 if(clientFd < 0)
126 {
127 continue;
128 }
129
130 bool connected = true;
131
132 const int msgSize = 64;
133 char data[msgSize] = {0};
134
135 while(connected && remoteOpen)
136 {
137 unsigned int r = 0;
138 do
139 {
140 int brecv = recv(clientFd, data+r, msgSize-r, 0);
141 r += brecv;
142 if(brecv == 0)
143 {
144 connected = false;
145 break;
146 }
147 if(brecv < 0 )
148 {
149 #ifndef __unix__
150 brecv = WSAGetLastError();
151 #endif
152 lime::log(LOG_LEVEL_ERROR, "RemoteControl recv with error: %d\n", brecv);
153 connected = false;
154 break;
155 }
156 }
157 while(r < msgSize);
158
159 if(not connected)
160 break;
161
162 mControlPortLock.lock();
163 Write((unsigned char*)data, msgSize);
164 Read((unsigned char*)data, msgSize);
165 mControlPortLock.unlock();
166
167 int bsent = 0;
168 while(bsent < msgSize)
169 {
170 int r = send(clientFd, data+bsent, msgSize-bsent, 0);
171 if(r < 0)
172 {
173 lime::log(LOG_LEVEL_ERROR, "RemoteControl send with error: %d\n", r);
174 connected = false;
175 break;
176 }
177 bsent += r;
178 }
179 }
180 if (clientFd >= 0)
181 {
182 #ifndef __unix__
183 //shutdown(socketFd, SD_BOTH);
184 closesocket(clientFd);
185 #else
186 shutdown(clientFd, SHUT_RDWR);
187 close(clientFd);
188 #endif
189 }
190 }
191 return;
192 }
193
194
195 }
196