7 |
#include <stdio.h> |
#include <stdio.h> |
8 |
#include <stdlib.h> |
#include <stdlib.h> |
9 |
#include <unistd.h> |
#include <unistd.h> |
10 |
|
#include <fcntl.h> |
11 |
|
#include <sys/types.h> |
12 |
|
#include <sys/socket.h> |
13 |
|
|
14 |
CPPUNIT_TEST_SUITE_REGISTRATION(LSCPTest); |
CPPUNIT_TEST_SUITE_REGISTRATION(LSCPTest); |
15 |
|
|
21 |
static Sampler* pSampler = NULL; |
static Sampler* pSampler = NULL; |
22 |
static LSCPServer* pLSCPServer = NULL; |
static LSCPServer* pLSCPServer = NULL; |
23 |
static int hSocket = -1; |
static int hSocket = -1; |
|
static FILE* hServerIn = NULL; |
|
24 |
|
|
25 |
/// Returns first token from \a sentence and removes that token (and evtl. delimiter) from \a sentence. |
/// Returns first token from \a sentence and removes that token (and evtl. delimiter) from \a sentence. |
26 |
static optional<string> __ExtractFirstToken(string* pSentence, const string Delimiter) { |
static optional<string> __ExtractFirstToken(string* pSentence, const string Delimiter) { |
132 |
return false; |
return false; |
133 |
} |
} |
134 |
|
|
135 |
hServerIn = fdopen(hSocket, "r"); |
// set non-blocking mode |
136 |
|
int socket_flags = fcntl(hSocket, F_GETFL, 0); |
137 |
|
fcntl(hSocket, F_SETFL, socket_flags | O_NONBLOCK); |
138 |
|
|
139 |
return true; |
return true; |
140 |
} |
} |
141 |
|
|
142 |
bool LSCPTest::closeConnectionToLSCPServer() { |
bool LSCPTest::closeConnectionToLSCPServer() { |
143 |
//cout << "closeConnectionToLSCPServer()\n" << flush; |
//cout << "closeConnectionToLSCPServer()\n" << flush; |
|
hServerIn = NULL; |
|
144 |
if (hSocket >= 0) { |
if (hSocket >= 0) { |
145 |
close(hSocket); |
close(hSocket); |
146 |
hSocket = -1; |
hSocket = -1; |
175 |
|
|
176 |
/// wait until LSCP server answers with the given \a delimiter token at the end (throws LinuxSamplerException if optional timeout exceeded or socket error occured) |
/// wait until LSCP server answers with the given \a delimiter token at the end (throws LinuxSamplerException if optional timeout exceeded or socket error occured) |
177 |
string LSCPTest::receiveAnswerFromLSCPServer(string delimiter, uint timeout_seconds) throw (LinuxSamplerException) { |
string LSCPTest::receiveAnswerFromLSCPServer(string delimiter, uint timeout_seconds) throw (LinuxSamplerException) { |
|
if (!hServerIn) { |
|
|
cout << "receiveAnswerFromLSCPServer() error: client socket not ready\n" << flush; |
|
|
return ""; |
|
|
} |
|
178 |
string message; |
string message; |
179 |
char c; |
char c; |
180 |
fd_set sockSet; |
fd_set sockSet; |
187 |
timeout.tv_sec = timeout_seconds; |
timeout.tv_sec = timeout_seconds; |
188 |
timeout.tv_usec = 0; |
timeout.tv_usec = 0; |
189 |
int res = select(hSocket + 1, &sockSet, NULL, NULL, &timeout); |
int res = select(hSocket + 1, &sockSet, NULL, NULL, &timeout); |
190 |
if (!res) throw LinuxSamplerException("LSCPTest::receiveAnswerFromLSCPServer(): timeout (" + ToString(timeout_seconds) + "s) exceeded waiting for expected answer (end)"); |
if (!res) { // if timeout exceeded |
191 |
else if (res < 0) throw LinuxSamplerException("LSCPTest::receiveAnswerFromLSCPServer(): select error"); |
if (!message.size()) throw LinuxSamplerException("LSCPTest::receiveAnswerFromLSCPServer(): timeout (" + ToString(timeout_seconds) + "s) exceeded, no answer received"); |
192 |
|
else throw LinuxSamplerException("LSCPTest::receiveAnswerFromLSCPServer(): timeout (" + ToString(timeout_seconds) + "s) exceeded waiting for expected answer (end), received answer: \'" + message + "\'"); |
193 |
|
} |
194 |
|
else if (res < 0) { |
195 |
|
throw LinuxSamplerException("LSCPTest::receiveAnswerFromLSCPServer(): select error"); |
196 |
|
} |
197 |
} |
} |
198 |
|
|
199 |
// there's something to read, so read one character |
// there's something to read, so read one character |
200 |
c = fgetc(hServerIn); |
int res = recv(hSocket, &c, 1, 0); |
201 |
if (c == EOF) { |
if (!res) throw LinuxSamplerException("LSCPTest::receiveAnswerFromLSCPServer(): connection to LSCP server closed"); |
202 |
cout << "receiveAnswerFromLSCPServer() error: EOF reached\n" << flush; |
else if (res < 0) { |
203 |
return ""; |
switch(errno) { |
204 |
|
case EBADF: |
205 |
|
throw LinuxSamplerException("The argument s is an invalid descriptor"); |
206 |
|
case ECONNREFUSED: |
207 |
|
throw LinuxSamplerException("A remote host refused to allow the network connection (typically because it is not running the requested service)."); |
208 |
|
case ENOTCONN: |
209 |
|
throw LinuxSamplerException("The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2))."); |
210 |
|
case ENOTSOCK: |
211 |
|
throw LinuxSamplerException("The argument s does not refer to a socket."); |
212 |
|
case EAGAIN: |
213 |
|
continue; |
214 |
|
//throw LinuxSamplerException("The socket is marked non-blocking and the receive operation would block, or a receive timeout had been set and the timeout expired before data was received."); |
215 |
|
case EINTR: |
216 |
|
throw LinuxSamplerException("The receive was interrupted by delivery of a signal before any data were available."); |
217 |
|
case EFAULT: |
218 |
|
throw LinuxSamplerException("The receive buffer pointer(s) point outside the process's address space."); |
219 |
|
case EINVAL: |
220 |
|
throw LinuxSamplerException("Invalid argument passed."); |
221 |
|
case ENOMEM: |
222 |
|
throw LinuxSamplerException("Could not allocate memory for recvmsg."); |
223 |
|
default: |
224 |
|
throw LinuxSamplerException("Unknown recv() error."); |
225 |
|
} |
226 |
} |
} |
227 |
|
|
228 |
message += c; |
message += c; |
229 |
string::size_type pos = message.rfind(delimiter); // ouch, but this is only a test case, right? ;) |
string::size_type pos = message.rfind(delimiter); // ouch, but this is only a test case, right? ;) |
230 |
if (pos != string::npos) return message; |
if (pos != string::npos) return message; |