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