Change from INET tcp to Unix domain socket
[framework/multimedia/media-server.git] / src / server / media-server-socket.c
1 /*
2  *  Media Server
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 /**
23  * This file defines api utilities of contents manager engines.
24  *
25  * @file                media-server-thumb.c
26  * @author      Yong Yeon Kim(yy9875.kim@samsung.com)
27  * @version     1.0
28  * @brief
29  */
30 #include <arpa/inet.h>
31 #include <sys/types.h>
32 #ifdef _USE_UDS_SOCKET_
33 #include <sys/un.h>
34 #else
35 #include <sys/socket.h>
36 #endif
37 #include <errno.h>
38 #include <malloc.h>
39 #include <vconf.h>
40
41 #include "media-util.h"
42 #include "media-util-internal.h"
43 #include "media-server-ipc.h"
44 #include "media-common-utils.h"
45 #include "media-server-dbg.h"
46 #include "media-server-db-svc.h"
47 #include "media-server-scanner.h"
48 #include "media-server-socket.h"
49 #include "media-server-db.h"
50
51 extern GAsyncQueue *scan_queue;
52 GAsyncQueue* ret_queue;
53 GArray *owner_list;
54 extern GMutex *scanner_mutex;
55
56 typedef struct ms_req_owner_data
57 {
58         int pid;
59         int index;
60 #ifdef _USE_UDS_SOCKET_
61         struct sockaddr_un *client_addr;
62 #else
63         struct sockaddr_in *client_addr;
64 #endif
65 }ms_req_owner_data;
66
67 int _ms_add_owner(ms_req_owner_data *owner_data)
68 {
69 //      MS_DBG("the length of array : %d", owner_list->len);
70 //      MS_DBG("pid : %d", owner_data->pid);
71 //      MS_DBG("client_addr : %p", owner_data->client_addr);
72
73         owner_data->index = -1;
74         g_array_append_val(owner_list, owner_data);
75
76         return MS_MEDIA_ERR_NONE;
77 }
78
79 int _ms_find_owner(int pid, ms_req_owner_data **owner_data)
80 {
81         int i;
82         int len = owner_list->len;
83         ms_req_owner_data *data = NULL;
84
85         *owner_data = NULL;
86
87         MS_DBG("length list :  %d", len);
88
89         for (i=0; i < len; i++) {
90                 data = g_array_index(owner_list, ms_req_owner_data*, i);
91                 MS_DBG("%d %d", data->pid, pid);
92                 if (data->pid == pid) {
93                         data->index = i;
94                         *owner_data = data;
95                         MS_DBG("FIND OWNER");
96                         break;
97                 }
98         }
99
100         return MS_MEDIA_ERR_NONE;
101 }
102
103 int _ms_delete_owner(ms_req_owner_data *owner_data)
104 {
105         if (owner_data->index != -1) {
106                 g_array_remove_index(owner_list, owner_data->index);
107                 MS_SAFE_FREE(owner_data->client_addr);
108                 MS_SAFE_FREE(owner_data);
109                 MS_DBG("DELETE OWNER");
110         }
111
112         return MS_MEDIA_ERR_NONE;
113 }
114
115 gboolean ms_read_socket(GIOChannel *src, GIOCondition condition, gpointer data)
116 {
117 #ifdef _USE_UDS_SOCKET_
118         struct sockaddr_un *client_addr = NULL;
119 #else
120         struct sockaddr_in *client_addr = NULL;
121 #endif
122         socklen_t client_addr_len;
123         ms_comm_msg_s recv_msg;
124         ms_comm_msg_s scan_msg;
125         int msg_size;
126         int sockfd = MS_SOCK_NOT_ALLOCATE;
127         int ret;
128         int pid;
129         int req_num;
130         int path_size;
131
132         g_mutex_lock(scanner_mutex);
133
134         sockfd = g_io_channel_unix_get_fd(src);
135         if (sockfd < 0) {
136                 MS_DBG_ERR("sock fd is invalid!");
137                 g_mutex_unlock(scanner_mutex);
138                 return TRUE;
139         }
140
141         /* Socket is readable */
142 #ifdef _USE_UDS_SOCKET_
143         MS_MALLOC(client_addr, sizeof(struct sockaddr_un));
144 #else
145         MS_MALLOC(client_addr, sizeof(struct sockaddr_in));
146 #endif
147         if (client_addr == NULL) {
148                 MS_DBG_ERR("malloc failed");
149                 g_mutex_unlock(scanner_mutex);
150                 return TRUE;
151         }
152 #ifdef _USE_UDS_SOCKET_
153         client_addr_len = sizeof(struct sockaddr_un);
154 #else
155         client_addr_len = sizeof(struct sockaddr_in);
156 #endif
157         ret = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(recv_msg), client_addr, NULL);
158         if (ret != MS_MEDIA_ERR_NONE) {
159                 MS_DBG_ERR("ms_ipc_receive_message failed");
160                 MS_SAFE_FREE(client_addr);
161                 g_mutex_unlock(scanner_mutex);
162                 return TRUE;
163         }
164
165         MS_DBG("receive msg from [%d] %d, %s", recv_msg.pid, recv_msg.msg_type, recv_msg.msg);
166
167         if (recv_msg.msg_size > 0 && recv_msg.msg_size < MS_FILE_PATH_LEN_MAX) {
168                 msg_size = recv_msg.msg_size;
169                 path_size = msg_size + 1;
170         } else {
171                 /*NEED IMPLEMETATION*/
172                 MS_SAFE_FREE(client_addr);
173                 g_mutex_unlock(scanner_mutex);
174                 return TRUE;
175         }
176
177         /* copy received data */
178         req_num = recv_msg.msg_type;
179         pid = recv_msg.pid;
180
181         /* register file request
182          * media server inserts the meta data of one file into media db */
183         if (req_num == MS_MSG_DIRECTORY_SCANNING
184                 ||req_num == MS_MSG_BULK_INSERT
185                 ||req_num == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE
186                 || req_num == MS_MSG_BURSTSHOT_INSERT) {
187                 /* this request process in media scanner */
188
189                 ms_req_owner_data *owner_data = NULL;
190
191                 /* If owner list is NULL, create it */
192                 /* pid and client address are stored in ower list */
193                 /* These are used for sending result of scanning */
194                 if (owner_list == NULL) {
195                         /*create array for processing overlay data*/
196                         owner_list = g_array_new (FALSE, FALSE, sizeof (ms_req_owner_data *));
197                         if (owner_list == NULL) {
198                                 MS_DBG_ERR("g_array_new error");
199                                 MS_SAFE_FREE(client_addr);
200                                 g_mutex_unlock(scanner_mutex);
201                                 return TRUE;
202                         }
203                 }
204
205                 /* store pid and client address */
206                 MS_MALLOC(owner_data, sizeof(ms_req_owner_data));
207                 owner_data->pid = recv_msg.pid;
208                 owner_data->client_addr = client_addr;
209
210                 _ms_add_owner(owner_data);
211
212                 /* create send message for media scanner */
213                 scan_msg.msg_type = req_num;
214                 scan_msg.pid = pid;
215                 scan_msg.msg_size = msg_size;
216                 ms_strcopy(scan_msg.msg, path_size, "%s", recv_msg.msg);
217
218                 g_mutex_unlock(scanner_mutex);
219
220                 if (ms_get_scanner_status()) {
221                         MS_DBG("Scanner is ready");
222                         ms_send_scan_request(&scan_msg);
223                 } else {
224                         MS_DBG("Scanner starts");
225                         ret = ms_scanner_start();
226                         if(ret == MS_MEDIA_ERR_NONE) {
227                                 ms_send_scan_request(&scan_msg);
228                         } else {
229                                 MS_DBG("Scanner starting failed. %d", ret);
230                         }
231                 }
232         } else {
233                 /* NEED IMPLEMENTATION */
234                 MS_SAFE_FREE(client_addr);
235                 g_mutex_unlock(scanner_mutex);
236         }
237
238         /*Active flush */
239         malloc_trim(0);
240
241         return TRUE;
242 }
243 gboolean ms_receive_message_from_scanner(GIOChannel *src, GIOCondition condition, gpointer data)
244 {
245         ms_comm_msg_s recv_msg;
246         int sockfd = MS_SOCK_NOT_ALLOCATE;
247         int msg_type;
248         int ret;
249
250         sockfd = g_io_channel_unix_get_fd(src);
251         if (sockfd < 0) {
252                 MS_DBG_ERR("sock fd is invalid!");
253                 return TRUE;
254         }
255
256         /* Socket is readable */
257         ret = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(recv_msg), NULL, NULL);
258         if (ret != MS_MEDIA_ERR_NONE) {
259                 MS_DBG_ERR("ms_ipc_receive_message failed [%s]", strerror(errno));
260                 return TRUE;
261         }
262
263         MS_DBG("receive msg from [%d] %d, %s", recv_msg.pid, recv_msg.msg_type, recv_msg.msg);
264
265         msg_type = recv_msg.msg_type;
266         if ((msg_type == MS_MSG_SCANNER_RESULT) ||
267                 (msg_type == MS_MSG_SCANNER_BULK_RESULT)) {
268                 if (owner_list != NULL) {
269                         /* If the owner of result message is not media-server, media-server notify to the owner */
270                         /* The owner of message is distingushied by pid in received message*/
271                         /* find owner data */
272                         ms_req_owner_data *owner_data = NULL;
273
274                         _ms_find_owner(recv_msg.pid, &owner_data);
275                         if (owner_data != NULL) {
276                                 MS_DBG("PID : %d", owner_data->pid);
277
278                                 if (msg_type == MS_MSG_SCANNER_RESULT) {
279                                         MS_DBG("DIRECTORY SCANNING IS DONE");
280                                 }
281
282                                 /* owner data exists */
283                                 /* send result to the owner of request */
284                                 ms_ipc_send_msg_to_client(sockfd, &recv_msg, owner_data->client_addr);
285
286                                 /* free owner data*/
287                                 _ms_delete_owner(owner_data);
288                         }
289                 } else {
290                         /* owner data does not exist*/
291                         /*  this is result of request of media server*/
292                 }
293         } else {
294                 MS_DBG_ERR("This result message is wrong : %d", recv_msg.msg_type );
295         }
296
297         return TRUE;
298 }
299
300 int ms_send_scan_request(ms_comm_msg_s *send_msg)
301 {
302         int ret;
303         int res = MS_MEDIA_ERR_NONE;
304         int sockfd = -1;
305
306         /*Create Socket*/
307 #ifdef _USE_UDS_SOCKET_
308         ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd, MS_SCAN_DAEMON_PORT);
309 #else
310         ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd);
311 #endif
312         if (ret != MS_MEDIA_ERR_NONE)
313                 return MS_MEDIA_ERR_SOCKET_CONN;
314
315         ret = ms_ipc_send_msg_to_server(sockfd, MS_SCAN_DAEMON_PORT, send_msg, NULL);
316         if (ret != MS_MEDIA_ERR_NONE)
317                 res = ret;
318
319         close(sockfd);
320
321         return res;
322 }
323
324 int ms_send_storage_scan_request(ms_storage_type_t storage_type, ms_dir_scan_type_t scan_type)
325 {
326         int ret = MS_MEDIA_ERR_NONE;
327         ms_comm_msg_s scan_msg = {
328                 .msg_type = MS_MSG_STORAGE_INVALID,
329                 .pid = 0, /* pid 0 means media-server */
330                 .result = -1,
331                 .msg_size = 0,
332                 .msg = {0},
333         };
334
335         /* msg_type */
336         switch (scan_type) {
337                 case MS_SCAN_PART:
338                         scan_msg.msg_type = MS_MSG_STORAGE_PARTIAL;
339                         break;
340                 case MS_SCAN_ALL:
341                         scan_msg.msg_type = MS_MSG_STORAGE_ALL;
342                         break;
343                 case MS_SCAN_INVALID:
344                         scan_msg.msg_type = MS_MSG_STORAGE_INVALID;
345                         break;
346                 default :
347                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
348                         MS_DBG_ERR("ms_send_storage_scan_request invalid parameter");
349                         goto ERROR;
350                         break;
351         }
352
353         /* msg_size & msg */
354         switch (storage_type) {
355                 case MS_STORAGE_INTERNAL:
356                         scan_msg.msg_size = strlen(MEDIA_ROOT_PATH_INTERNAL);
357                         strncpy(scan_msg.msg, MEDIA_ROOT_PATH_INTERNAL, scan_msg.msg_size );
358                         break;
359                 case MS_STORAGE_EXTERNAL:
360                         scan_msg.msg_size = strlen(MEDIA_ROOT_PATH_SDCARD);
361                         strncpy(scan_msg.msg, MEDIA_ROOT_PATH_SDCARD, scan_msg.msg_size );
362                         break;
363                 default :
364                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
365                         MS_DBG_ERR("ms_send_storage_scan_request invalid parameter");
366                         goto ERROR;
367                         break;
368         }
369
370         g_mutex_lock(scanner_mutex);
371
372         if (ms_get_scanner_status()) {
373                 ms_send_scan_request(&scan_msg);
374                 g_mutex_unlock(scanner_mutex);
375         } else {
376                 g_mutex_unlock(scanner_mutex);
377
378                 ret = ms_scanner_start();
379                 if(ret == MS_MEDIA_ERR_NONE) {
380                         ms_send_scan_request(&scan_msg);
381                 } else {
382                         MS_DBG("Scanner starting failed. ");
383                 }
384         }
385
386 ERROR:
387
388         return ret;
389 }
390
391 gboolean ms_read_db_socket(GIOChannel *src, GIOCondition condition, gpointer data)
392 {
393 #ifdef _USE_UDS_SOCKET_
394         struct sockaddr_un client_addr;
395 #else
396         struct sockaddr_in client_addr;
397 #endif
398
399         ms_comm_msg_s recv_msg;
400         int send_msg = MS_MEDIA_ERR_NONE;
401         int sockfd = MS_SOCK_NOT_ALLOCATE;
402         int ret = MS_MEDIA_ERR_NONE;
403         MediaDBHandle *db_handle = (MediaDBHandle *)data;
404         ms_comm_msg_s msg;
405         char * sql_query = NULL;
406
407         memset(&recv_msg, 0, sizeof(recv_msg));
408
409         sockfd = g_io_channel_unix_get_fd(src);
410         if (sockfd < 0) {
411                 MS_DBG_ERR("sock fd is invalid!");
412                 return TRUE;
413         }
414
415         ret = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(recv_msg), &client_addr, NULL);
416         if (ret != MS_MEDIA_ERR_NONE) {
417                 MS_DBG_ERR("ms_ipc_receive_message failed");
418                 return TRUE;
419         }
420
421 //      MS_DBG("msg_type[%d], msg_size[%d] msg[%s]", recv_msg.msg_type, recv_msg.msg_size, recv_msg.msg);
422
423         if((recv_msg.msg_size <= 0) ||(recv_msg.msg_size > MS_FILE_PATH_LEN_MAX)  || (!MS_STRING_VALID(recv_msg.msg))) {
424                 MS_DBG_ERR("invalid query. size[%d]", recv_msg.msg_size);
425                 return TRUE;
426         }
427
428         sql_query = strndup(recv_msg.msg, recv_msg.msg_size);
429         if (sql_query != NULL) {
430                 ret = media_db_update_db(db_handle, sql_query);
431                 if (ret != MS_MEDIA_ERR_NONE)
432                         MS_DBG_ERR("media_db_update_db error : %d", ret);
433
434                 send_msg = ret;
435                 MS_SAFE_FREE(sql_query);
436         } else {
437                 send_msg = MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
438         }
439
440         memset(&msg, 0x0, sizeof(ms_comm_msg_s));
441         msg.result = send_msg;
442
443         ms_ipc_send_msg_to_client(sockfd, &msg, &client_addr);
444
445         /*Active flush */
446         malloc_trim(0);
447
448         return TRUE;
449 }
450
451 gboolean ms_read_db_tcp_socket(GIOChannel *src, GIOCondition condition, gpointer data)
452 {
453 #ifdef _USE_UDS_SOCKET_
454         struct sockaddr_un client_addr;
455 #elif defined(_USE_UDS_SOCKET_TCP_)
456         struct sockaddr_un client_addr;
457 #else
458         struct sockaddr_in client_addr;
459 #endif
460         unsigned int client_addr_len;
461
462         ms_comm_msg_s recv_msg;
463         int sock = -1;
464         int client_sock = -1;
465         int send_msg = MS_MEDIA_ERR_NONE;
466         int recv_msg_size = -1;
467         int ret = MS_MEDIA_ERR_NONE;
468         char * sql_query = NULL;
469         MediaDBHandle *db_handle = (MediaDBHandle *)data;
470
471         sock = g_io_channel_unix_get_fd(src);
472         if (sock < 0) {
473                 MS_DBG_ERR("sock fd is invalid!");
474                 return TRUE;
475         }
476         memset((void *)&recv_msg, 0, sizeof(ms_comm_msg_s));
477
478         if ((client_sock = accept(sock, (struct sockaddr*)&client_addr, &client_addr_len)) < 0) {
479                 MS_DBG_ERR("accept failed : %s", strerror(errno));
480                 return TRUE;
481         }
482
483         MS_DBG("Client[%d] is accepted", client_sock);
484
485         while(1) {
486                 if ((recv_msg_size = recv(client_sock, &recv_msg, sizeof(ms_comm_msg_s), 0)) < 0) {
487                         MS_DBG_ERR("recv failed : %s", strerror(errno));
488
489                         close(client_sock);
490                         if (errno == EWOULDBLOCK) {
491                                 MS_DBG_ERR("Timeout. Can't try any more");
492                                 return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT;
493                         } else {
494                                 MS_DBG_ERR("recv failed : %s", strerror(errno));
495                                 return MS_MEDIA_ERR_SOCKET_RECEIVE;
496                         }
497                 }
498
499 //              MS_DBG("Received [%d](%d) [%s]", recv_msg.msg_type, recv_msg.msg_size, recv_msg.msg);
500
501                 if((recv_msg.msg_size <= 0) ||(recv_msg.msg_size > MS_FILE_PATH_LEN_MAX)  || (!MS_STRING_VALID(recv_msg.msg))) {
502                         MS_DBG_ERR("invalid query. size[%d]", recv_msg.msg_size);
503                         MS_DBG_ERR("Received [%d](%d) [%s]", recv_msg.msg_type, recv_msg.msg_size, recv_msg.msg);
504                         close(client_sock);
505                         return TRUE;
506                 }
507
508                 sql_query = strndup(recv_msg.msg, recv_msg.msg_size);
509                 if (sql_query != NULL) {
510                         if (recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_START) {
511                                 ret = media_db_update_db_batch_start(sql_query);
512                         } else if(recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_END) {
513                                 ret = media_db_update_db_batch_end(db_handle, sql_query);
514                         } else if(recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH) {
515                                 ret = media_db_update_db_batch(sql_query);
516                         } else {
517
518                         }
519
520                         MS_SAFE_FREE(sql_query);
521                         send_msg = ret;
522
523                         if (send(client_sock, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) {
524                                 MS_DBG_ERR("send failed : %s", strerror(errno));
525                         } else {
526                                 MS_DBG("Sent successfully");
527                         }
528
529                         if (recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_END)
530                                 break;
531
532                         memset((void *)&recv_msg, 0, sizeof(ms_comm_msg_s));
533                 } else {
534                         MS_DBG_ERR("MS_MALLOC failed");
535                         close(client_sock);
536                         return TRUE;
537                 }
538         }
539
540         close(client_sock);
541         return TRUE;
542 }