* wrapping DLT calls in a new Class because of performance, codesize and lazyness...
[profile/ivi/audiomanager.git] / AudioManagerDaemon / test / sockethandler / sockethandlerTest.cpp
1 /*
2  * sockethandlerTest.cpp
3  *
4  *  Created on: Dec 19, 2011
5  *      Author: christian
6  */
7
8 #include "sockethandlerTest.h"
9 #include <stdio.h>
10 #include <sys/socket.h> /* for socket(), connect(), (), and recv() */
11 #include <arpa/inet.h>  /* for sockaddr_in and inet_addr() */
12 #include <sys/ioctl.h>
13 #include <string.h>
14 #include <netdb.h>
15 #include <fcntl.h>
16 #include <sys/un.h>
17
18 #define SOCK_PATH "/tmp/mysock"
19
20 using namespace testing;
21 using namespace am;
22
23 sockethandlerTest::sockethandlerTest()
24 {
25 }
26
27 sockethandlerTest::~sockethandlerTest()
28 {
29 }
30
31 timerCallBack::timerCallBack(SocketHandler *myHandler) :
32         pTimer1Callback(this, &timerCallBack::timer1Callback), //
33         pTimer2Callback(this, &timerCallBack::timer2Callback), //
34         pTimer3Callback(this, &timerCallBack::timer3Callback), //
35         pTimer4Callback(this, &timerCallBack::timer4Callback), //
36         mSocketHandler(myHandler)
37
38 {
39 }
40
41 am::timerCallBack::~timerCallBack()
42 {
43 }
44
45 void am::timerCallBack::timer1Callback(sh_timerHandle_t handle, void* userData)
46 {
47     (void) handle;
48     (void) userData;
49     std::cout << "callback1 called" << std::endl;
50     timespec timeout;
51     timeout.tv_nsec = 0;
52     timeout.tv_sec = 1;
53     shTimerCallBack *buf = &pTimer1Callback;
54     sh_timerHandle_t handle_;
55     mSocketHandler->addTimer(timeout, buf, handle_, NULL);
56 }
57
58 void am::timerCallBack::timer2Callback(sh_timerHandle_t handle, void* userData)
59 {
60     (void) handle;
61     (void) userData;
62     std::cout << "callback2 called" << std::endl;
63     timespec timeout;
64     timeout.tv_nsec = 0;
65     timeout.tv_sec = 1;
66     shTimerCallBack *buf = &pTimer2Callback;
67     sh_timerHandle_t handle_;
68     mSocketHandler->addTimer(timeout, buf, handle_, NULL);
69 }
70
71 void am::timerCallBack::timer3Callback(sh_timerHandle_t, void* userData)
72 {
73     (void) userData;
74     std::cout << "callback3 called" << std::endl;
75 }
76
77 void am::timerCallBack::timer4Callback(sh_timerHandle_t, void* userData)
78 {
79     (void) userData;
80     std::cout << "callback4 called" << std::endl;
81     mSocketHandler->stop_listening();
82 }
83
84 void* playWithSocketServer(void* data)
85 {
86     (void) data;
87     SocketHandler myHandler;
88     SamplePlugin::sockType_e type = SamplePlugin::INET;
89     SamplePlugin myplugin(&myHandler, type);
90     myHandler.start_listenting();
91     return (NULL);
92 }
93
94 void* playWithUnixSocketServer(void* data)
95 {
96     (void) data;
97     SocketHandler myHandler;
98     SamplePlugin::sockType_e type = SamplePlugin::UNIX;
99     SamplePlugin myplugin(&myHandler, type);
100     myHandler.start_listenting();
101     return (NULL);
102 }
103
104 TEST(sockethandlerTest,playWithUNIXSockets)
105 {
106     pthread_t serverThread;
107     struct sockaddr_un servAddr;
108     int socket_;
109
110     //creates a thread that handles the serverpart
111     pthread_create(&serverThread, NULL, playWithUnixSocketServer, NULL);
112
113     sleep(1); //we need that here because the port needs to be opened
114     if ((socket_ = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
115     {
116         std::cout << "socket problem" << std::endl;
117
118     }
119
120     memset(&servAddr, 0, sizeof(servAddr));
121     strcpy(servAddr.sun_path, SOCK_PATH);
122     servAddr.sun_family = AF_UNIX;
123     if (connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
124     {
125         std::cout << "ERROR: connect() failed\n" << std::endl;
126     }
127
128     for (int i = 0; i <= 1000; i++)
129     {
130         std::string string("Got It?");
131         send(socket_, string.c_str(), string.size(), 0);
132     }
133     std::string string("finish!");
134     send(socket_, string.c_str(), string.size(), 0);
135
136     pthread_join(serverThread, NULL);
137 }
138
139 TEST(sockethandlerTest,playWithSockets)
140 {
141     pthread_t serverThread;
142     struct sockaddr_in servAddr;
143     unsigned short servPort = 6060;
144     struct hostent *host;
145     int socket_;
146
147     //creates a thread that handles the serverpart
148     pthread_create(&serverThread, NULL, playWithSocketServer, NULL);
149
150     sleep(1); //we need that here because the port needs to be opened
151     if ((socket_ = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
152     {
153         std::cout << "socket problem" << std::endl;
154
155     }
156
157     if ((host = (struct hostent*) gethostbyname("localhost")) == 0)
158     {
159         std::cout << "ERROR: gethostbyname() failed\n" << std::endl;
160         exit(1);
161     }
162
163     memset(&servAddr, 0, sizeof(servAddr));
164     servAddr.sin_family = AF_INET;
165     servAddr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr*) (host->h_addr_list[0])));
166     servAddr.sin_port = htons(servPort);
167
168     if (connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
169     {
170         std::cout << "ERROR: connect() failed\n" << std::endl;
171     }
172
173     for (int i = 0; i <= 1000; i++)
174     {
175         std::string string("Got It?");
176         send(socket_, string.c_str(), string.size(), 0);
177     }
178     std::string string("finish!");
179     send(socket_, string.c_str(), string.size(), 0);
180
181     pthread_join(serverThread, NULL);
182 }
183
184 TEST(sockethandlerTest,playWithTimers)
185 {
186     gDispatchDone = 0;
187     SocketHandler myHandler;
188     timerCallBack testCallback(&myHandler);
189     timespec timeoutTime, timeout2, timeout3, timeout4;
190     timeoutTime.tv_sec = 3;
191     timeoutTime.tv_nsec = 0;
192     timeout2.tv_nsec = 0;
193     timeout2.tv_sec = 1;
194     timeout3.tv_nsec = 000000000;
195     timeout3.tv_sec = 2;
196     timeout4.tv_nsec = 0;
197     timeout4.tv_sec = 13;
198     shTimerCallBack* buf = &testCallback.pTimer1Callback;
199     shTimerCallBack* buf2 = &testCallback.pTimer2Callback;
200     shTimerCallBack* buf3 = &testCallback.pTimer3Callback;
201     shTimerCallBack* buf4 = &testCallback.pTimer4Callback;
202     sh_timerHandle_t handle;
203     myHandler.addTimer(timeoutTime, buf, handle, NULL);
204     myHandler.addTimer(timeout2, buf2, handle, NULL);
205     myHandler.addTimer(timeout3, buf3, handle, NULL);
206     myHandler.addTimer(timeout4, buf4, handle, NULL);
207     myHandler.start_listenting();
208
209 }
210
211 void sockethandlerTest::SetUp()
212 {
213 }
214
215 void sockethandlerTest::TearDown()
216 {
217 }
218
219 int main(int argc, char **argv)
220 {
221     ::testing::InitGoogleTest(&argc, argv);
222     return RUN_ALL_TESTS();
223 }
224
225 am::SamplePlugin::SamplePlugin(SocketHandler *mySocketHandler, sockType_e socketType) :
226         connectFiredCB(this, &SamplePlugin::connectSocket), //
227         receiveFiredCB(this, &SamplePlugin::receiveData), //
228         sampleDispatchCB(this, &SamplePlugin::dispatchData), //
229         sampleCheckCB(this, &SamplePlugin::check), //
230         mSocketHandler(mySocketHandler), //
231         mConnecthandle(), //
232         mReceiveHandle(), //
233         msgList()
234 {
235     int yes = 1;
236
237     int socketHandle;
238     struct sockaddr_in servAddr;
239     struct sockaddr_un unixAddr;
240     unsigned int servPort = 6060;
241
242     switch (socketType)
243     {
244     case UNIX:
245         socketHandle = socket(AF_UNIX, SOCK_STREAM, 0);
246         unixAddr.sun_family = AF_UNIX;
247         strcpy(unixAddr.sun_path, SOCK_PATH);
248         unlink(unixAddr.sun_path);
249         bind(socketHandle, (struct sockaddr *) &unixAddr, strlen(unixAddr.sun_path) + sizeof(unixAddr.sun_family));
250         break;
251     case INET:
252         socketHandle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
253         setsockopt(socketHandle, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
254         memset(&servAddr, 0, sizeof(servAddr));
255         servAddr.sin_family = AF_INET;
256         servAddr.sin_addr.s_addr = INADDR_ANY;
257         servAddr.sin_port = htons(servPort);
258         bind(socketHandle, (struct sockaddr *) &servAddr, sizeof(servAddr));
259         break;
260     default:
261         break;
262     }
263
264     if (listen(socketHandle, 3) < 0)
265     {
266         std::cout << "listen ok" << std::endl;
267     } /* if */
268
269     int a = 1;
270     ioctl(socketHandle, FIONBIO, (char *) &a);
271     setsockopt(socketHandle, SOL_SOCKET, SO_KEEPALIVE, (char *) &a, sizeof(a));
272
273     short events = 0;
274     events |= POLLIN;
275     mySocketHandler->addFDPoll(socketHandle, events, NULL, &connectFiredCB, NULL, NULL, NULL, mConnecthandle);
276     std::cout << "setup server - listening" << std::endl;
277 }
278
279 void am::SamplePlugin::connectSocket(const pollfd pollfd1, const sh_pollHandle_t handle, void *userData)
280 {
281     (void) handle;
282     (void) userData;
283     //first, accept the connection, create a new filedescriptor
284     std::cout << "Got a connection request !" << std::endl;
285     struct sockaddr answer;
286     socklen_t len = sizeof(answer);
287     int receiveFD = accept(pollfd1.fd, (struct sockaddr*) &answer, &len);
288
289     //set the correct event:
290     short event = 0;
291     event |= POLLIN;
292
293     //aded the filedescriptor to the sockethandler and register the callbacks for receiving the data
294     mSocketHandler->addFDPoll(receiveFD, event, NULL, &receiveFiredCB, &sampleCheckCB, &sampleDispatchCB, NULL, mReceiveHandle);
295
296 }
297
298 void am::SamplePlugin::receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void *userData)
299 {
300     (void) handle;
301     (void) userData;
302     //initialize buffer
303     char buffer[10];
304     //read until buffer is full or no more data is there
305     int read = recv(pollfd.fd, buffer, 7, NULL);
306     if (read > 1)
307     {
308         //read the message and store it in a queue
309         std::string msg = std::string(buffer, read);
310         msgList.push(msg);
311         std::cout << "Got a message !" << std::endl;
312     }
313 }
314
315 bool am::SamplePlugin::dispatchData(const sh_pollHandle_t handle, void *userData)
316 {
317     (void) handle;
318     (void) userData;
319     //read data from the queue
320     std::cout << "Data:" << msgList.front() << std::endl;
321
322     //if the message was our finish message, we quit the poll loop
323     if (msgList.front().compare("finish!") == 0)
324     {
325         mSocketHandler->stop_listening();
326     }
327     //remove the message from the queue and return false if there is no more message to read.
328     msgList.pop();
329     if (msgList.size() != 0)
330         return true;
331     return false;
332 }
333
334 bool am::SamplePlugin::check(const sh_pollHandle_t handle, void *userData)
335 {
336     (void) handle;
337     (void) userData;
338     //checks if there is data to dispatch
339     std::cout << "check!:" << std::endl;
340     if (msgList.size() != 0)
341         return true;
342     return false;
343 }
344