* fixed sockethandler timespec issues
[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 am::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
47
48 am::timerCallBack::~timerCallBack()
49 {
50 }
51
52
53
54 void am::timerCallBack::timer1Callback(sh_timerHandle_t handle, void* userData)
55 {
56         std::cout<<"callback1 called"<<std::endl;
57         timespec timeout;
58         timeout.tv_nsec=0;
59         timeout.tv_sec=1;
60         shTimerCallBack *buf=&pTimer1Callback;
61         sh_timerHandle_t handle_;
62         mSocketHandler->addTimer(timeout,buf,handle_,NULL);
63 }
64
65
66
67 void am::timerCallBack::timer2Callback(sh_timerHandle_t handle, void* userData)
68 {
69         std::cout<<"callback2 called"<<std::endl;
70         timespec timeout;
71         timeout.tv_nsec=0;
72         timeout.tv_sec=1;
73         shTimerCallBack *buf=&pTimer2Callback;
74         sh_timerHandle_t handle_;
75         mSocketHandler->addTimer(timeout,buf,handle_,NULL);
76 }
77
78 void am::timerCallBack::timer3Callback(sh_timerHandle_t, void* userData)
79 {
80         std::cout<<"callback3 called"<<std::endl;
81 }
82
83 void am::timerCallBack::timer4Callback(sh_timerHandle_t, void* userData)
84 {
85         std::cout<<"callback4 called"<<std::endl;
86         mSocketHandler->stop_listening();
87 }
88
89 void* playWithSocketServer(void* data)
90 {
91         SocketHandler myHandler;
92         SamplePlugin::sockType_e type=SamplePlugin::INET;
93         SamplePlugin myplugin(&myHandler,type);
94         myHandler.start_listenting();
95 }
96
97 void* playWithUnixSocketServer(void* data)
98 {
99         SocketHandler myHandler;
100         SamplePlugin::sockType_e type=SamplePlugin::UNIX;
101         SamplePlugin myplugin(&myHandler,type);
102         myHandler.start_listenting();
103 }
104
105 TEST(sockethandlerTest,playWithUNIXSockets)
106 {
107         pthread_t serverThread;
108         char buffer[3000];
109         struct sockaddr_un servAddr;
110         int socket_;
111
112         //creates a thread that handles the serverpart
113         pthread_create(&serverThread,NULL,playWithUnixSocketServer,NULL);
114
115         sleep(1); //we need that here because the port needs to be opened
116     if ((socket_ = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
117     {
118         std::cout<<"socket problem"<<std::endl;
119
120     }
121
122     memset(&servAddr, 0, sizeof(servAddr));
123     strcpy(servAddr.sun_path, SOCK_PATH);
124     servAddr.sun_family = AF_UNIX;
125     if (connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
126     {
127         std::cout<<"ERROR: connect() failed\n"<<std::endl;
128     }
129
130         for (int i=0;i<=1000;i++)
131         {
132                 std::string string("Got It?");
133                 send(socket_,string.c_str(),string.size(),0);
134         }
135         std::string string("finish!");
136         send(socket_,string.c_str(),string.size(),0);
137
138         pthread_join(serverThread,NULL);
139 }
140
141 TEST(sockethandlerTest,playWithSockets)
142 {
143         pthread_t serverThread;
144         char buffer[3000];
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
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 ret;
239         int yes = 1;
240
241         int socketHandle;
242         struct sockaddr_in servAddr;
243         struct sockaddr_un unixAddr;
244         unsigned int servPort = 6060;
245
246         switch (socketType)
247         {
248         case UNIX:
249                 socketHandle = socket(AF_UNIX, SOCK_STREAM, 0);
250                 unixAddr.sun_family = AF_UNIX;
251                 strcpy(unixAddr.sun_path,SOCK_PATH);
252                 unlink(unixAddr.sun_path);
253                 bind(socketHandle, (struct sockaddr *)&unixAddr, strlen(unixAddr.sun_path) + sizeof(unixAddr.sun_family));
254                 break;
255         case INET:
256                 socketHandle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
257                 setsockopt(socketHandle, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
258                 memset(&servAddr, 0, sizeof(servAddr));
259                 servAddr.sin_family      = AF_INET;
260                 servAddr.sin_addr.s_addr = INADDR_ANY;
261                 servAddr.sin_port        = htons(servPort);
262             bind(socketHandle, (struct sockaddr *) &servAddr, sizeof(servAddr));
263             break;
264         default:
265                 break;
266         }
267
268     if (listen(socketHandle, 3) < 0)
269     {
270         std::cout<<"listen ok"<<std::endl;
271     } /* if */
272
273     int a=1;
274     ioctl (socketHandle, FIONBIO, (char *) &a);
275     setsockopt (socketHandle, SOL_SOCKET, SO_KEEPALIVE, (char *) &a, sizeof (a));
276
277         short events=0;
278         events |= POLLIN;
279         mySocketHandler->addFDPoll(socketHandle,events,NULL,&connectFiredCB,NULL,NULL,NULL,mConnecthandle);
280         std::cout<<"setup server - listening"<<std::endl;
281 }
282
283
284
285 void am::SamplePlugin::connectSocket(const pollfd pollfd1, const sh_pollHandle_t handle, void *userData)
286 {
287         //first, accept the connection, create a new filedescriptor
288         std::cout<<"Got a connection request !"<<std::endl;
289         struct sockaddr answer;
290         socklen_t len=sizeof(answer);
291         int receiveFD = accept(pollfd1.fd, (struct sockaddr*)&answer, &len);
292
293         //set the correct event:
294         short event = 0;
295         event |=POLLIN;
296
297         //aded the filedescriptor to the sockethandler and register the callbacks for receiving the data
298         mSocketHandler->addFDPoll(receiveFD,event,NULL,&receiveFiredCB,&sampleCheckCB,&sampleDispatchCB,NULL,mReceiveHandle);
299
300 }
301
302
303
304 void am::SamplePlugin::receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void *userData)
305 {
306         //initialize buffer
307         char buffer[10];
308         //read until buffer is full or no more data is there
309         int read=recv(pollfd.fd,buffer,7,NULL);
310         if (read>1)
311         {
312                 //read the message and store it in a queue
313                 std::string msg=std::string(buffer,read);
314                 msgList.push(msg);
315                 std::cout<<"Got a message !"<<std::endl;
316         }
317 }
318
319
320
321 bool am::SamplePlugin::dispatchData(const sh_pollHandle_t handle, void *userData)
322 {
323         //read data from the queue
324         std::cout<<"Data:"<<msgList.front()<<std::endl;
325
326         //if the message was our finish message, we quit the poll loop
327         if (msgList.front().compare("finish!")==0)
328         {
329                 mSocketHandler->stop_listening();
330         }
331         //remove the message from the queue and return false if there is no more message to read.
332         msgList.pop();
333         if (msgList.size()!=0) return true;
334         return false;
335 }
336
337 bool am::SamplePlugin::check(const sh_pollHandle_t handle, void *userData)
338 {
339         //checks if there is data to dispatch
340         std::cout<<"check!:"<<std::endl;
341         if (msgList.size()!=0) return true;
342         return false;
343 }
344
345
346
347
348
349
350
351