f35b4e0b791c13f4aeba695e0546414f1208303e
[platform/core/multimedia/libmm-wfd.git] / server / miracast_server.c
1 /*\r
2  * libmm-wfd\r
3  *\r
4  * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.\r
5  *\r
6  * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,\r
7  * Manoj Kumar K <manojkumar.k@samsung.com>, Hyunil Park <hyunil46.park@samsung.com>\r
8  *\r
9  * Licensed under the Apache License, Version 2.0 (the "License");\r
10  * you may not use this file except in compliance with the License.\r
11  * You may obtain a copy of the License at\r
12  *\r
13  * http://www.apache.org/licenses/LICENSE-2.0\r
14  *\r
15  * Unless required by applicable law or agreed to in writing, software\r
16  * distributed under the License is distributed on an "AS IS" BASIS,\r
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
18  * See the License for the specific language governing permissions and\r
19  * limitations under the License.\r
20  *\r
21  */\r
22 \r
23  /*===========================================================================================\r
24 |                                             |\r
25 |  INCLUDE FILES                                      |\r
26 |                                               |\r
27 ========================================================================================== */\r
28 //#define MTRACE;\r
29 #include <glib.h>\r
30 #include <mm_types.h>\r
31 #include <mm_error.h>\r
32 #include <mm_message.h>\r
33 #include <mm_wfd.h>\r
34 #include <mm_debug.h>\r
35 #include <mm_message.h>\r
36 #include <mm_error.h>\r
37 #include <mm_types.h>\r
38 \r
39 #include <iniparser.h>\r
40 #include <mm_ta.h>\r
41 #include <dlfcn.h>\r
42 #include <sys/types.h>\r
43 #include <sys/socket.h>\r
44 #include <netinet/in.h>\r
45 #include <fcntl.h>\r
46 #include <signal.h>\r
47 \r
48 #include <netdb.h>\r
49 #include <dbus/dbus.h>\r
50 #include <dbus/dbus-glib-lowlevel.h>\r
51 \r
52 #include <vconf.h>\r
53 \r
54 #define PACKAGE "mm_wfd_testsuite"\r
55 \r
56 /*===========================================================================================\r
57 |                                             |\r
58 |  LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE                      |\r
59 |                                               |\r
60 ========================================================================================== */\r
61 \r
62 #if defined(_USE_GMAINLOOP)\r
63 GMainLoop *g_loop;\r
64 #endif\r
65 \r
66 gboolean wfd_server_test_method(void *pObject, int pid, char *test_name,\r
67          int *return_code)\r
68 {\r
69   debug_log("Received test %s\n", test_name);\r
70   return TRUE;\r
71 }\r
72 \r
73 #include "wfd-structure.h"\r
74 \r
75 #define WFD_PROXY_COMM_PORT 8888\r
76 \r
77 typedef struct WfdServerObject WfdServerObject;\r
78 typedef struct WfdServerObjectClass WfdServerObjectClass;\r
79 \r
80 GType Daemon_Object_get_type(void);\r
81 struct WfdServerObject {\r
82   GObject parent;\r
83 };\r
84 \r
85 struct WfdServerObjectClass {\r
86   GObjectClass parent;\r
87 };\r
88 \r
89 #define DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT 0\r
90 \r
91 #define WFD_SERVER_TYPE_OBJECT (Daemon_Object_get_type())\r
92 \r
93 #define WFD_SERVER_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST \\r
94   ((object), WFD_SERVER_TYPE_OBJECT, WfdServerObject))\r
95 \r
96 G_DEFINE_TYPE(WfdServerObject, Daemon_Object, G_TYPE_OBJECT)\r
97 static void Daemon_Object_init(WfdServerObject * obj)\r
98 {\r
99   debug_log("Daemon_Object_init\n");\r
100 }\r
101 \r
102 static void Daemon_Object_class_init(WfdServerObjectClass * klass)\r
103 {\r
104   debug_log("Daemon_Object_class_init\n");\r
105 }\r
106 \r
107 /*---------------------------------------------------------------------------\r
108 |    LOCAL #defines:                            |\r
109 ---------------------------------------------------------------------------*/\r
110 #define MAX_STRING_LEN    2048\r
111 \r
112 /*---------------------------------------------------------------------------\r
113 |    LOCAL CONSTANT DEFINITIONS:                      |\r
114 ---------------------------------------------------------------------------*/\r
115 enum\r
116 {\r
117   CURRENT_STATUS_MAINMENU,\r
118   CURRENT_STATUS_SERVER_IP,\r
119   CURRENT_STATUS_SERVER_PORT,\r
120   CURRENT_STATUS_CONNECT,\r
121 };\r
122 \r
123 typedef struct {\r
124   int connfd;\r
125   socklen_t clilen;\r
126   struct sockaddr_in cli_addr;\r
127   GThread *thread;\r
128   char inbuff[512];\r
129   gboolean inactive;\r
130   GMutex *lock;\r
131   GIOChannel *channel;\r
132   void *parent;\r
133 } WFDClient;\r
134 \r
135 typedef struct {\r
136   int sockfd;\r
137   int portno;\r
138   struct sockaddr_in serv_addr;\r
139   GThread *thread;\r
140   GList *clients;\r
141 } WFDServer;\r
142 \r
143 /*---------------------------------------------------------------------------\r
144 |    LOCAL VARIABLE DEFINITIONS:                      |\r
145 ---------------------------------------------------------------------------*/\r
146 \r
147 int  g_current_state;\r
148 static MMHandleType g_wfd = 0;\r
149 char *g_err_name = NULL;\r
150 gboolean quit_pushing;\r
151 int socket_id = 0;\r
152 /*---------------------------------------------------------------------------\r
153 |    LOCAL FUNCTION PROTOTYPES:                       |\r
154 ---------------------------------------------------------------------------*/\r
155 static void wfd_connect();\r
156 static void wfd_start();\r
157 static void wfd_stop();\r
158 \r
159 void quit_program();\r
160 \r
161 static void wfd_set_signal();\r
162 \r
163 /*---------------------------------------------------------------------------\r
164   |    LOCAL FUNCTION DEFINITIONS:                      |\r
165   ---------------------------------------------------------------------------*/\r
166 static bool msg_callback(int message, MMMessageParamType *param, void *user_param)\r
167 {\r
168   /* TODO any error notification or state change should be forwarded to the active list of proxy apps */\r
169   switch (message) {\r
170     case MM_MESSAGE_ERROR:\r
171       {\r
172         WFDClient *client = (WFDClient *)user_param;\r
173         if(!client) return FALSE;\r
174         WFDServer *lserver = (WFDServer*) client->parent;\r
175         if(!lserver) return FALSE;\r
176         debug_log("msg_callback error : code = %x\n", param->code);\r
177         debug_log ("DESTROY..\n\n");\r
178         quit_pushing = TRUE;\r
179         shutdown (lserver->sockfd, SHUT_RDWR);\r
180             debug_log("msg_callback error call quit_program()");\r
181         quit_program();\r
182       }\r
183       break;\r
184     case MM_MESSAGE_WARNING:\r
185       // debug_log("warning : code = %d\n", param->code);\r
186       break;\r
187     case MM_MESSAGE_END_OF_STREAM:\r
188       debug_log("msg_callback end of stream\n");\r
189       mm_wfd_stop(g_wfd);\r
190       break;\r
191     case MM_MESSAGE_STATE_CHANGED:\r
192       g_current_state = param->state.current;\r
193       switch(g_current_state)\r
194       {\r
195         case MM_WFD_STATE_NULL:\r
196           debug_log("\n                                                            ==> [WFDApp] Player is [NULL]\n");\r
197           break;\r
198         case MM_WFD_STATE_READY:\r
199           debug_log("\n                                                            ==> [WFDApp] Player is [READY]\n");\r
200           break;\r
201         case MM_WFD_STATE_PLAYING:\r
202           debug_log("\n                                                            ==> [WFDApp] Player is [PLAYING]\n");\r
203           break;\r
204         case MM_WFD_STATE_PAUSED:\r
205           debug_log("\n                                                            ==> [WFDApp] Player is [PAUSED]\n");\r
206           break;\r
207       }\r
208       break;\r
209     default:\r
210       return FALSE;\r
211   }\r
212   return TRUE;\r
213 }\r
214 \r
215 static gboolean proxy_write (WFDClient *client, char *wbuf)\r
216 {\r
217   write(client->connfd, wbuf, strlen(wbuf));\r
218   return TRUE;\r
219 }\r
220 \r
221 static void input_server_ip_and_port(char *server_ip, char* port, WFDClient *client)\r
222 {\r
223   int len = strlen(server_ip);\r
224   int ret = MM_ERROR_NONE;\r
225   if ( len < 0 || len > MAX_STRING_LEN )\r
226     return;\r
227 \r
228   if (!g_wfd)\r
229   {\r
230     if ( mm_wfd_create(&g_wfd) != MM_ERROR_NONE )\r
231     {\r
232       debug_log("input_server_ip wfd create is failed\n");\r
233       return;\r
234     }\r
235     ret = mm_wfd_set_message_callback(g_wfd, msg_callback, (void*)client);\r
236     if (ret != MM_ERROR_NONE)\r
237     {\r
238       debug_log ("input_server_ip Error in setting server_port...\n");\r
239       return;\r
240     }\r
241   }\r
242   ret = mm_wfd_set_attribute(g_wfd,\r
243         &g_err_name,\r
244         "server_ip", server_ip, strlen(server_ip),\r
245         NULL);\r
246   if (ret != MM_ERROR_NONE)\r
247   {\r
248     debug_log ("input_server_ip Error in setting server_port...\n");\r
249     return;\r
250   }\r
251   ret = mm_wfd_set_attribute(g_wfd,\r
252           &g_err_name,\r
253           "server_port", port, strlen(port),\r
254           NULL);\r
255   if (ret != MM_ERROR_NONE)\r
256   {\r
257     debug_log ("input_server_port Error in setting server_port...\n");\r
258     return;\r
259   }\r
260   /*set wfd source status*/\r
261   gboolean status = VCONFKEY_MIRACAST_WFD_SOURCE_ON;\r
262   if (!vconf_set_bool(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS, status)) {\r
263     debug_log ("set VCONFKEY_MIRACAST_WFD_SOURCE_ON");\r
264   }\r
265 }\r
266 static void wfd_connect()\r
267 {\r
268   int ret = MM_ERROR_NONE;\r
269 \r
270   if (!g_wfd)\r
271   {\r
272     debug_log ("wfd_start Creating server with default values : ");\r
273     if ( mm_wfd_create(&g_wfd) != MM_ERROR_NONE )\r
274     {\r
275       debug_log("wfd_start wfd create is failed\n");\r
276       return;\r
277     }\r
278 \r
279     ret = mm_wfd_set_message_callback(g_wfd, msg_callback, (void*)g_wfd);\r
280     if (ret != MM_ERROR_NONE)\r
281     {\r
282       debug_log ("wfd_start Error in setting server_port...\n");\r
283       return;\r
284     }\r
285   }\r
286   if ( mm_wfd_realize(g_wfd) != MM_ERROR_NONE )\r
287   {\r
288     debug_log("wfd_start wfd realize is failed\n");\r
289     return;\r
290   }\r
291 \r
292   if ( mm_wfd_connect(g_wfd) != MM_ERROR_NONE )\r
293   {\r
294     debug_log("wfd_start wfd connect is failed\n");\r
295     return;\r
296   }\r
297 \r
298 }\r
299 \r
300 static void wfd_start()\r
301 {\r
302   int ret = MM_ERROR_NONE;\r
303 \r
304   if (!g_wfd)\r
305   {\r
306     debug_log ("wfd_start Creating server with default values : ");\r
307     if ( mm_wfd_create(&g_wfd) != MM_ERROR_NONE )\r
308     {\r
309       debug_log("wfd_start wfd create is failed\n");\r
310       return;\r
311     }\r
312 \r
313     ret = mm_wfd_set_message_callback(g_wfd, msg_callback, (void*)g_wfd);\r
314     if (ret != MM_ERROR_NONE)\r
315     {\r
316       debug_log ("wfd_start Error in setting server_port...\n");\r
317       return;\r
318     }\r
319 \r
320    if ( mm_wfd_realize(g_wfd) != MM_ERROR_NONE )\r
321    {\r
322      debug_log("wfd_start wfd realize is failed\n");\r
323      return;\r
324    }\r
325 \r
326    if ( mm_wfd_connect(g_wfd) != MM_ERROR_NONE )\r
327    {\r
328      debug_log("wfd_start wfd connect is failed\n");\r
329      return;\r
330     }\r
331   }\r
332 \r
333   if (mm_wfd_start(g_wfd) != MM_ERROR_NONE)\r
334   {\r
335     debug_log ("wfd_start Failed to start WFD");\r
336     return;\r
337   }\r
338 }\r
339 \r
340 static void wfd_stop()\r
341 {\r
342   int ret = MM_ERROR_NONE;\r
343 \r
344   ret = mm_wfd_stop(g_wfd);\r
345   if (ret != MM_ERROR_NONE)\r
346   {\r
347     debug_log ("wfd_stop Error to do stop...\n");\r
348     return;\r
349   }\r
350 }\r
351 \r
352 static void wfd_pause()\r
353 {\r
354   int ret = MM_ERROR_NONE;\r
355 \r
356   ret = mm_wfd_pause(g_wfd);\r
357   if (ret != MM_ERROR_NONE)\r
358   {\r
359     debug_log ("wfd_pause Error to do pausep...\n");\r
360     return;\r
361   }\r
362 }\r
363 \r
364 static void wfd_resume()\r
365 {\r
366   int ret = MM_ERROR_NONE;\r
367 \r
368   ret = mm_wfd_resume(g_wfd);\r
369   if (ret != MM_ERROR_NONE)\r
370   {\r
371     debug_log ("wfd_resume Error to do resume...\n");\r
372     return;\r
373   }\r
374 }\r
375 \r
376 static void wfd_standby()\r
377 {\r
378   int ret = MM_ERROR_NONE;\r
379   ret = mm_wfd_standby(g_wfd);\r
380   if (ret != MM_ERROR_NONE)\r
381   {\r
382     debug_log ("wfd_standby Error to do standby...\n");\r
383     return;\r
384   }\r
385 }\r
386 \r
387 void quit_program()\r
388 {\r
389   MMTA_ACUM_ITEM_SHOW_RESULT_TO(MMTA_SHOW_STDOUT);\r
390   MMTA_RELEASE();\r
391   debug_log ("quit_program...\n");\r
392 \r
393   /*set wfd source status*/\r
394   gboolean status = VCONFKEY_MIRACAST_WFD_SOURCE_OFF;\r
395   if (!vconf_set_bool(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS, status)) {\r
396     debug_log ("set VCONFKEY_MIRACAST_WFD_SOURCE_OFF");\r
397   }\r
398 \r
399   if (g_wfd) {\r
400         mm_wfd_unrealize(g_wfd);\r
401         mm_wfd_destroy(g_wfd);\r
402         g_wfd = 0;\r
403   }\r
404   g_main_loop_quit(g_loop);\r
405 }\r
406 \r
407 gchar * convert_state_to_string(MMWfdStateType aState)\r
408 {\r
409   GString *cmd_replay;\r
410   cmd_replay = g_string_new ("");\r
411   switch(aState)\r
412   {\r
413     case MM_WFD_STATE_NULL:\r
414       g_string_append_printf (cmd_replay, "MM_WFD_STATE_NULL");\r
415       break;\r
416     case MM_WFD_STATE_READY:\r
417       g_string_append_printf (cmd_replay, "MM_WFD_STATE_READY");\r
418       break;\r
419     case MM_WFD_STATE_CONNECTION_WAIT:\r
420       g_string_append_printf (cmd_replay, "MM_WFD_STATE_CONNECTION_WAIT");\r
421       break;\r
422     case MM_WFD_STATE_CONNECTED:\r
423       g_string_append_printf (cmd_replay, "MM_WFD_STATE_CONNECTED");\r
424       break;\r
425     case MM_WFD_STATE_PLAYING:\r
426       g_string_append_printf (cmd_replay, "MM_WFD_STATE_PLAYING");\r
427       break;\r
428     case MM_WFD_STATE_PAUSED:\r
429       g_string_append_printf (cmd_replay, "MM_WFD_STATE_PAUSED");\r
430       break;\r
431     case MM_WFD_STATE_NONE:\r
432       g_string_append_printf (cmd_replay, "MM_WFD_STATE_NONE");\r
433       break;\r
434     case MM_WFD_STATE_NUM:\r
435       g_string_append_printf (cmd_replay, "MM_WFD_STATE_NUM");\r
436       break;\r
437   }\r
438   return g_string_free (cmd_replay, FALSE);\r
439 }\r
440 \r
441 static void interpret (WFDClient *client, char *cmd)\r
442 {\r
443   GString *cmd_replay;\r
444   if (strstr(cmd, "WFD_PROXY_SET_IP_PORT"))\r
445   {\r
446     gchar **IP_port;\r
447     gchar **IP;\r
448     gchar **port;\r
449     debug_log ("setting attributes... WFD..\n\n");\r
450     IP_port = g_strsplit(cmd,"\r\n",0);\r
451     IP = g_strsplit(IP_port[1]," ",0);\r
452     port = g_strsplit(IP_port[2]," ",0);\r
453     debug_log ("received IP %s port %s\n", IP[1], port[1]);\r
454     input_server_ip_and_port(IP[1], port[1], client);\r
455     cmd_replay = g_string_new ("");\r
456     g_string_append_printf (cmd_replay, "REPLAY WFD_PROXY_SET_IP_PORT");\r
457     g_string_append_printf (cmd_replay, "\r\n");\r
458     g_string_append_printf (cmd_replay, "MM_ERROR_NONE");\r
459     proxy_write(client, g_string_free (cmd_replay, FALSE));\r
460     debug_log ("STATE QUERY..demon return\n\n");\r
461   }\r
462   else if (strstr(cmd, "WFD_PROXY_CONNECT"))\r
463   {\r
464     debug_log ("Starting... WFD..\n\n");\r
465     cmd_replay = g_string_new ("");\r
466     g_string_append_printf (cmd_replay, "REPLAY WFD_PROXY_CONNECT");\r
467     g_string_append_printf (cmd_replay, "\r\n");\r
468     g_string_append_printf (cmd_replay, "MM_ERROR_NONE");\r
469     proxy_write(client, g_string_free (cmd_replay, FALSE));\r
470     debug_log ("STATE QUERY..demon return\n\n");\r
471     wfd_connect();\r
472   }\r
473   else if (strstr(cmd, "WFD_PROXY_START"))\r
474   {\r
475     debug_log ("Starting... WFD..\n\n");\r
476     cmd_replay = g_string_new ("");\r
477     g_string_append_printf (cmd_replay, "REPLAY WFD_PROXY_START");\r
478     g_string_append_printf (cmd_replay, "\r\n");\r
479     g_string_append_printf (cmd_replay, "MM_ERROR_NONE");\r
480     proxy_write(client, g_string_free (cmd_replay, FALSE));\r
481     debug_log ("STATE QUERY..demon return\n\n");\r
482     wfd_start();\r
483   }\r
484   else if (strstr(cmd, "WFD_PROXY_PAUSE"))\r
485   {\r
486     debug_log ("PAUSING..\n\n");\r
487     wfd_pause();\r
488     cmd_replay = g_string_new ("");\r
489     g_string_append_printf (cmd_replay, "REPLAY WFD_PROXY_PAUSE");\r
490     g_string_append_printf (cmd_replay, "\r\n");\r
491     g_string_append_printf (cmd_replay, "MM_ERROR_NONE");\r
492     proxy_write(client, g_string_free (cmd_replay, FALSE));\r
493     debug_log ("STATE QUERY..demon return\n\n");\r
494   }\r
495   else if (strstr(cmd, "WFD_PROXY_RESUME"))\r
496   {\r
497     debug_log ("RESUMING..\n\n");\r
498     wfd_resume();\r
499     cmd_replay = g_string_new ("");\r
500     g_string_append_printf (cmd_replay, "REPLAY WFD_PROXY_RESUME");\r
501     g_string_append_printf (cmd_replay, "\r\n");\r
502     g_string_append_printf (cmd_replay, "MM_ERROR_NONE");\r
503     proxy_write(client, g_string_free (cmd_replay, FALSE));\r
504     debug_log ("STATE QUERY..demon return\n\n");\r
505   }\r
506   else if (strstr(cmd, "WFD_PROXY_STOP"))\r
507   {\r
508     debug_log ("STOPPING..\n\n");\r
509     wfd_stop();\r
510     cmd_replay = g_string_new ("");\r
511     g_string_append_printf (cmd_replay, "REPLAY WFD_PROXY_STOP");\r
512     g_string_append_printf (cmd_replay, "\r\n");\r
513     g_string_append_printf (cmd_replay, "MM_ERROR_NONE");\r
514     proxy_write(client, g_string_free (cmd_replay, FALSE));\r
515     debug_log ("STATE QUERY..demon return\n\n");\r
516   }\r
517   else if (strstr(cmd, "WFD_PROXY_DESTROY"))\r
518   {\r
519     WFDServer *lserver = (WFDServer*) client->parent;\r
520     debug_log ("DESTROY..\n\n");\r
521     cmd_replay = g_string_new ("");\r
522     g_string_append_printf (cmd_replay, "REPLAY WFD_PROXY_DESTROY");\r
523     g_string_append_printf (cmd_replay, "\r\n");\r
524     g_string_append_printf (cmd_replay, "MM_ERROR_NONE");\r
525     proxy_write(client, g_string_free (cmd_replay, FALSE));\r
526     debug_log ("STATE QUERY..demon return\n\n");\r
527     quit_pushing = TRUE;\r
528     shutdown (lserver->sockfd, SHUT_RDWR);\r
529     debug_log("interpret calll quit_program()");\r
530     quit_program();\r
531   }\r
532   else if (strstr(cmd, "WFD_PROXY_STATE_QUERY"))\r
533   {\r
534     debug_log ("STATE QUERY..\n\n");\r
535     cmd_replay = g_string_new ("");\r
536     g_string_append_printf (cmd_replay, "REPLAY WFD_PROXY_STATE_QUERY");\r
537     g_string_append_printf (cmd_replay, "\r\n");\r
538     g_string_append_printf (cmd_replay, convert_state_to_string(g_current_state));\r
539     proxy_write(client, g_string_free (cmd_replay, FALSE));\r
540     debug_log ("STATE QUERY..demon return\n\n");\r
541   }\r
542   else\r
543   {\r
544     debug_log("unknown menu \n");\r
545   }\r
546 }\r
547 \r
548 gboolean input (GIOChannel *channel, GIOCondition condition, gpointer data)\r
549 {\r
550   WFDClient *client = (WFDClient*)data;\r
551   gsize read;\r
552   GError *error = NULL;\r
553   if(condition & G_IO_IN) {\r
554     memset(&(client->inbuff),0,sizeof(client->inbuff));\r
555     g_io_channel_read(client->channel, client->inbuff, sizeof(client->inbuff), &read);\r
556     if(read)\r
557     {\r
558       client->inbuff[read] = '\0';\r
559       g_strstrip(client->inbuff);\r
560       debug_log("got command %s\n", client->inbuff);\r
561       if(!g_str_has_prefix(client->inbuff,"WFD")) goto client_cleanup;\r
562       interpret (client, client->inbuff);\r
563       debug_log("command return \n");\r
564     }\r
565     else goto client_cleanup;\r
566   }\r
567   if (condition & G_IO_HUP) goto client_cleanup;\r
568   return TRUE;\r
569 client_cleanup:\r
570   {\r
571     WFDServer *lserver = (WFDServer *)client->parent;\r
572     client->inactive = TRUE;\r
573     debug_log("client connection closed \n");\r
574     shutdown (client->connfd, SHUT_RDWR);\r
575     g_io_channel_shutdown(client->channel, TRUE, &error);\r
576     debug_log("IO channel closed \n");\r
577     if(g_list_length(lserver->clients))\r
578     {\r
579       lserver->clients = g_list_remove(lserver->clients, client);\r
580     }\r
581     free(client);\r
582     debug_log("client removed from list \n");\r
583   }\r
584   return TRUE;\r
585 }\r
586 \r
587 static void* wfd_server_thread_function(void * asrc)\r
588 {\r
589   int  newsockfd;\r
590   int i=0;\r
591   int nSockOpt = 1;\r
592   WFDServer *pserver = (WFDServer *)asrc;\r
593   pserver->sockfd = socket(AF_INET, SOCK_STREAM, 0);\r
594   debug_log("wfd_proxy_initialize socke is %d", pserver->sockfd);\r
595   if (pserver->sockfd < 0)\r
596   {\r
597     debug_log("ERROR opening socket");\r
598     goto cleanup;\r
599   }\r
600   debug_log("wfd_proxy_initialize get socket created\n");\r
601   bzero((char *) &pserver->serv_addr, sizeof(pserver->serv_addr));\r
602   pserver->portno = WFD_PROXY_COMM_PORT;\r
603   pserver->serv_addr.sin_family = AF_INET;\r
604   pserver->serv_addr.sin_addr.s_addr = INADDR_ANY;\r
605   pserver->serv_addr.sin_port = htons(pserver->portno);\r
606   debug_log("serv_addr = %p sizeof %d ", (struct sockaddr *) &pserver->serv_addr, sizeof(pserver->serv_addr));\r
607   setsockopt(pserver->sockfd, SOL_SOCKET, SO_REUSEADDR, &nSockOpt, sizeof(nSockOpt));\r
608   if (bind(pserver->sockfd, (struct sockaddr *) &pserver->serv_addr, sizeof(pserver->serv_addr)) < 0)\r
609   {\r
610     debug_log("ERROR on binding");\r
611     goto cleanup;\r
612   }\r
613   debug_log("wfd_proxy_initialize get socket bind\n");\r
614   if (listen(pserver->sockfd,5) <0)\r
615   {\r
616     debug_log("ERROR on socket listen");\r
617     goto cleanup;\r
618   }\r
619   wfd_set_signal();\r
620   MMTA_INIT();\r
621 \r
622   while(!quit_pushing)\r
623   {\r
624     socklen_t clilen = {0};\r
625     struct sockaddr_in cli_addr = {0};\r
626     WFDClient *client = NULL;\r
627     clilen = sizeof(cli_addr);\r
628     debug_log("wfd_proxy_initialize waiting for accept \n");\r
629     newsockfd = accept(pserver->sockfd, (struct sockaddr *) &cli_addr, &clilen);\r
630     if (newsockfd < 0) {\r
631       debug_log("ERROR on accept");\r
632       continue;\r
633     }\r
634     debug_log("wfd_proxy_initialize get socket accept \n");\r
635     client = g_malloc(sizeof(WFDClient));\r
636     if(!client)\r
637     {\r
638       debug_log("client malloc failed. out of memory");\r
639       continue;\r
640     }\r
641     client->connfd = newsockfd;\r
642     socket_id = newsockfd;\r
643     client->lock = g_mutex_new ();\r
644     client->inactive = 0;\r
645     client->parent = pserver;\r
646     client->channel = g_io_channel_unix_new(client->connfd);\r
647     g_io_add_watch(client->channel, G_IO_IN|G_IO_HUP|G_IO_ERR, (GIOFunc)input, client);\r
648     pserver->clients = g_list_prepend(pserver->clients, client);\r
649   }\r
650 cleanup:\r
651   debug_log("wfd_server_thread_function cleanup \n");\r
652   for(i=0;i<g_list_length(pserver->clients); i++)\r
653   {\r
654     GError *error = NULL;\r
655     WFDClient *tempclient = (WFDClient *)g_list_nth_data(pserver->clients,i);\r
656     if(tempclient) {\r
657       tempclient->inactive = TRUE;\r
658       shutdown (tempclient->connfd, SHUT_RDWR);\r
659       g_io_channel_shutdown(tempclient->channel, TRUE, &error);\r
660       pserver->clients = g_list_remove(pserver->clients, tempclient);\r
661       free(tempclient);\r
662     }\r
663   }\r
664   g_list_free(pserver->clients);\r
665   shutdown (pserver->sockfd, SHUT_RDWR);\r
666   debug_log("wfd_server_thread_function calll quit_program()");\r
667   quit_program();\r
668 \r
669   debug_log("wfd_server_thread_function THREAD EXIT \n");\r
670 \r
671   return NULL;\r
672 }\r
673 \r
674 static gboolean __func1(void *data)\r
675 {\r
676   GError *error = NULL;\r
677   WFDServer *server = (WFDServer *)data;\r
678   debug_log("__func1 enter \n");\r
679   server->thread = g_thread_create ((GThreadFunc) wfd_server_thread_function, server, TRUE, &error);\r
680   server->clients = g_list_alloc ();\r
681   debug_log("__func1 exit \n");\r
682   return FALSE;\r
683 }\r
684 \r
685 static bool __wfd_server_setup(void* pserver)\r
686 {\r
687   WFDServer *server = (WFDServer *)pserver;\r
688   DBusGConnection *conn = NULL;\r
689   GObject *object = NULL;\r
690   DBusGObjectInfo dbus_glib_wfd_server_object_info;\r
691   GError *err = NULL;\r
692   DBusError derr;\r
693   int ret = 0;\r
694   debug_log("__wfd_server_setup start\n");\r
695   dbus_g_object_type_install_info(WFD_SERVER_TYPE_OBJECT,\r
696     &dbus_glib_wfd_server_object_info);\r
697 \r
698   conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &err);\r
699   if (NULL == conn) {\r
700     debug_log("Unable to get dbus!");\r
701     return false;\r
702   }\r
703   dbus_error_init(&derr);\r
704 \r
705   ret = dbus_bus_request_name(dbus_g_connection_get_connection(conn),\r
706     "com.samsung.wfd.server",\r
707     DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, &derr);\r
708 \r
709   if (dbus_error_is_set(&derr)) {\r
710     debug_log("dbus_bus_request_name failed with error:%s", derr.message);\r
711     dbus_error_free(&derr);\r
712     return false;\r
713   }\r
714   object = g_object_new(WFD_SERVER_TYPE_OBJECT, NULL);\r
715   if (NULL == object) {\r
716     debug_log("Unable to create new object");\r
717     return false;\r
718   }\r
719   dbus_g_connection_register_g_object(conn, "/com/samsung/wfd/server", G_OBJECT(object));\r
720   g_idle_add(__func1, server);\r
721   debug_log("__wfd_server_setup end\n");\r
722   return true;\r
723 }\r
724 void wfd_signal_handler(int signo) {\r
725   quit_pushing = TRUE;\r
726   debug_log("wfd_signal_handler calll quit_program()");\r
727   shutdown (socket_id, SHUT_RDWR);\r
728   quit_program();\r
729   exit(1);\r
730 }\r
731 \r
732 static void wfd_set_signal()\r
733 {\r
734 \r
735   /*refer to signal.h*/\r
736   /*SIGABRT  A  Process abort signal.\r
737      SIGALRM   T  Alarm clock.\r
738      SIGBUS    A  Access to an undefined portion of a memory object.\r
739      SIGCHLD  I  Child process terminated, stopped,\r
740      SIGCONT  C  Continue executing, if stopped.\r
741      SIGFPE  A  Erroneous arithmetic operation.\r
742      SIGHUP  T  Hangup.\r
743      SIGILL  A  Illegal instruction.\r
744      SIGINT  T  Terminal interrupt signal.\r
745      SIGKILL  T  Kill (cannot be caught or ignored).\r
746      SIGPIPE  T  Write on a pipe with no one to read it.\r
747      SIGQUIT  A  Terminal quit signal.\r
748      SIGSEGV  A  Invalid memory reference.\r
749      SIGSTOP  S  Stop executing (cannot be caught or ignored).\r
750      SIGTERM  T  Termination signal.\r
751      SIGTSTP  S  Terminal stop signal.\r
752      SIGTTIN  S  Background process attempting read.\r
753      SIGTTOU  S  Background process attempting write.\r
754      SIGUSR1  T  User-defined signal 1.\r
755      SIGUSR2  T  User-defined signal 2.\r
756      SIGPOLL  T  Pollable event.\r
757      SIGPROF  T  Profiling timer expired.\r
758      SIGSYS  A  Bad system call.\r
759      SIGTRAP  A  Trace/breakpoint trap.\r
760      SIGURG  I  High bandwidth data is available at a socket.\r
761      SIGVTALRM  T  Virtual timer expired.\r
762      SIGXCPU  A  CPU time limit exceeded.\r
763      SIGXFSZ  A  File size limit exceeded.\r
764 \r
765 The default actions are as follows:\r
766 T : Abnormal termination of the process. The process is terminated with all the consequences of _exit()\r
767 A : Abnormal termination of the process.\r
768 I  : Ignore the signal.\r
769 S : Stop the process\r
770 */\r
771   struct sigaction act_new;\r
772   memset (&act_new, 0, sizeof (struct sigaction));\r
773 \r
774   act_new.sa_handler = wfd_signal_handler;\r
775 \r
776   sigaction(SIGABRT, &act_new, NULL);\r
777   sigaction(SIGBUS, &act_new, NULL);\r
778   sigaction(SIGINT, &act_new, NULL); //\r
779   sigaction(SIGKILL, &act_new, NULL);\r
780   sigaction(SIGPIPE, &act_new, NULL);\r
781   sigaction(SIGQUIT, &act_new, NULL); //\r
782   sigaction(SIGSEGV, &act_new, NULL);\r
783   sigaction(SIGTERM, &act_new, NULL); //\r
784   sigaction(SIGSYS, &act_new, NULL);\r
785 \r
786 }\r
787 \r
788 \r
789 \r
790 static void wifi_direct_state_change_cb(keynode_t *key, void *data)\r
791 {\r
792   WFDServer *server = (WFDServer *)data;\r
793   if(!server) return;\r
794   debug_log("wifi direct state changed");\r
795   int state = -1;\r
796   state = vconf_keynode_get_int(key);\r
797   if (state < VCONFKEY_WIFI_DIRECT_GROUP_OWNER) {\r
798     debug_log("wifi disconnected");\r
799     quit_pushing = TRUE;\r
800     shutdown (server->sockfd, SHUT_RDWR);\r
801     debug_log("wifi_direct_state_change_cb calll quit_program()");\r
802     quit_program();\r
803   }\r
804 }\r
805 \r
806 static void lcd_state_change_cb(keynode_t *key, void *data)\r
807 {\r
808   WFDServer *server = (WFDServer *)data;\r
809   if(!server)\r
810     return;\r
811   int state = -1;\r
812   state = vconf_keynode_get_int(key);\r
813   if (state == VCONFKEY_PM_STATE_NORMAL) {\r
814     debug_log("source has woke up time to wake-up-sink");\r
815     wfd_resume();\r
816   }\r
817   else if(state == VCONFKEY_PM_STATE_LCDOFF || VCONFKEY_PM_STATE_SLEEP) {\r
818     debug_log("source is sleeping time to go to sleep");\r
819     wfd_standby();\r
820   }\r
821 }\r
822 \r
823 int main(int argc, char *argv[])\r
824 {\r
825   WFDServer server;\r
826   server.thread = NULL;\r
827   server.clients = NULL;\r
828 \r
829   g_loop = g_main_loop_new(NULL, FALSE);\r
830   if(NULL == g_loop) {\r
831     debug_log("Unable to create gmain loop! Aborting wfd server\n");\r
832     exit(-1);\r
833   }\r
834   g_type_init();\r
835   debug_log("wfd_proxy_initialize\n");\r
836   if (!__wfd_server_setup(&server)) {\r
837     debug_log("Unable to initialize test server\n");\r
838     exit(-1);\r
839   }\r
840   debug_log("set vconf_notify_key_changed about wifi direct");\r
841   if (0 != vconf_notify_key_changed(VCONFKEY_WIFI_DIRECT_STATE, wifi_direct_state_change_cb, &server)) {\r
842     debug_log("vconf_notify_key_changed() failed");\r
843   }\r
844   debug_log("set vconf_notify_key_changed about LCD state");\r
845   if (0 != vconf_notify_key_changed(VCONFKEY_PM_STATE, lcd_state_change_cb, &server)) {\r
846     debug_log("vconf_notify_key_changed() failed");\r
847   }\r
848   debug_log("wfd_proxy_initialize run loop \n");\r
849   g_main_loop_run(g_loop);\r
850   g_thread_join(server.thread);\r
851   shutdown (server.sockfd, SHUT_RDWR);\r
852   debug_log("WFD SERVER EXIT \n");\r
853   exit(0);\r
854 }\r