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