4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 * This file defines api utilities of contents manager engines.
25 * @file media-server-thumb.c
26 * @author Yong Yeon Kim(yy9875.kim@samsung.com)
30 #include <arpa/inet.h>
31 #include <sys/types.h>
32 #include <sys/socket.h>
37 #include "media-util.h"
38 #include "media-util-internal.h"
39 #include "media-server-dbg.h"
40 #include "media-server-ipc.h"
41 #include "media-server-db-svc.h"
42 #include "media-server-utils.h"
43 #include "media-server-scanner.h"
44 #include "media-server-socket.h"
45 #include "media-server-db.h"
47 extern GAsyncQueue *scan_queue;
48 GAsyncQueue* ret_queue;
50 extern GMutex *scanner_mutex;
52 typedef struct ms_req_owner_data
55 struct sockaddr_in *client_addr;
58 int _ms_add_owner(ms_req_owner_data *owner_data)
60 // MS_DBG("the length of array : %d", owner_list->len);
61 // MS_DBG("pid : %d", owner_data->pid);
62 // MS_DBG("client_addr : %p", owner_data->client_addr);
64 g_array_append_val(owner_list, owner_data);
66 return MS_MEDIA_ERR_NONE;
69 int _ms_find_owner(int pid, ms_req_owner_data **owner_data)
72 int len = owner_list->len;
73 bool find_flag = false;
74 ms_req_owner_data *data = NULL;
76 MS_DBG("length list : %d", len);
78 for (i=0; i < len; i++) {
79 data = g_array_index(owner_list, ms_req_owner_data*, i);
80 MS_DBG("%d %d", data->pid, pid);
81 if (data->pid == pid) {
87 if (find_flag == true) {
92 MS_DBG("DO NOT FIND OWNER");
95 return MS_MEDIA_ERR_NONE;
98 int _ms_delete_owner(ms_req_owner_data *owner_data)
101 int len = owner_list->len;
102 ms_req_owner_data *data = NULL;
104 for (i=0; i < len; i++) {
105 data = g_array_index(owner_list, ms_req_owner_data*, i);
106 if (data->pid == owner_data->pid) {
107 if (data->client_addr == owner_data->client_addr) {
108 g_array_remove_index(owner_list, i);
109 MS_SAFE_FREE(owner_data->client_addr);
110 MS_SAFE_FREE(owner_data);
116 return MS_MEDIA_ERR_NONE;
119 gboolean ms_read_socket(GIOChannel *src, GIOCondition condition, gpointer data)
121 struct sockaddr_in *client_addr = NULL;
122 socklen_t client_addr_len;
123 ms_comm_msg_s recv_msg;
124 ms_comm_msg_s result_msg;
125 ms_comm_msg_s scan_msg;
127 int sockfd = MS_SOCK_NOT_ALLOCATE;
132 void **handle = data;
135 g_mutex_lock(scanner_mutex);
137 sockfd = g_io_channel_unix_get_fd(src);
139 MS_DBG_ERR("sock fd is invalid!");
140 g_mutex_unlock(scanner_mutex);
144 /* Socket is readable */
145 MS_MALLOC(client_addr, sizeof(struct sockaddr_in));
146 if (client_addr == NULL) {
147 MS_DBG_ERR("malloc failed");
148 g_mutex_unlock(scanner_mutex);
152 client_addr_len = sizeof(struct sockaddr_in);
153 ret = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(recv_msg), client_addr, NULL);
154 if (ret != MS_MEDIA_ERR_NONE) {
155 MS_DBG_ERR("ms_ipc_receive_message failed");
156 MS_SAFE_FREE(client_addr);
157 g_mutex_unlock(scanner_mutex);
161 MS_DBG("receive msg from [%d] %d, %s", recv_msg.pid, recv_msg.msg_type, recv_msg.msg);
163 if (recv_msg.msg_size > 0 && recv_msg.msg_size < MS_FILE_PATH_LEN_MAX) {
164 msg_size = recv_msg.msg_size;
165 path_size = msg_size + 1;
167 /*NEED IMPLEMETATION*/
168 MS_SAFE_FREE(client_addr);
169 g_mutex_unlock(scanner_mutex);
173 /* copy received data */
174 req_num = recv_msg.msg_type;
177 /* register file request
178 * media server inserts the meta data of one file into media db */
179 if (req_num == MS_MSG_DB_UPDATE) {
180 MS_MALLOC(path, path_size);
182 ret = ms_strcopy(path, path_size, "%s", recv_msg.msg);
183 if (ret != MS_MEDIA_ERR_NONE) {
185 MS_SAFE_FREE(client_addr);
186 g_mutex_unlock(scanner_mutex);
190 MS_DBG("REQUEST FILE REGISTER");
192 ret = ms_register_file(handle, path, ret_queue);
193 if (ret == MS_MEDIA_ERR_NOW_REGISTER_FILE) {
194 ret= GPOINTER_TO_INT(g_async_queue_pop(ret_queue)) - MS_MEDIA_ERR_MAX;
197 ret = ms_register_file(handle, path);
199 MS_DBG_INFO("register result : %d", ret);
200 /* the result of inserting to db */
201 result_msg.result = ret;
203 MS_DBG_ERR("malloc failed");
204 result_msg.result = MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
207 ms_ipc_send_msg_to_client(sockfd, &result_msg, client_addr);
210 MS_SAFE_FREE(client_addr);
212 g_mutex_unlock(scanner_mutex);
213 } else if (req_num == MS_MSG_DIRECTORY_SCANNING
214 ||req_num == MS_MSG_BULK_INSERT
215 ||req_num == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
216 /* this request process in media scanner */
218 ms_req_owner_data *owner_data = NULL;
220 /* If owner list is NULL, create it */
221 /* pid and client address are stored in ower list */
222 /* These are used for sending result of scanning */
223 if (owner_list == NULL) {
224 /*create array for processing overlay data*/
225 owner_list = g_array_new (FALSE, FALSE, sizeof (ms_req_owner_data *));
226 if (owner_list == NULL) {
227 MS_DBG_ERR("g_array_new error");
228 MS_SAFE_FREE(client_addr);
229 g_mutex_unlock(scanner_mutex);
234 /* store pid and client address */
235 MS_MALLOC(owner_data, sizeof(ms_req_owner_data));
236 owner_data->pid = recv_msg.pid;
237 owner_data->client_addr = client_addr;
239 _ms_add_owner(owner_data);
241 /* create send message for media scanner */
242 scan_msg.msg_type = req_num;
244 scan_msg.msg_size = msg_size;
245 ms_strcopy(scan_msg.msg, path_size, "%s", recv_msg.msg);
247 /* change the status of media scanner for directory scanning */
248 if (req_num == MS_MSG_DIRECTORY_SCANNING
249 || req_num == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
250 MS_DBG("DIRECTORY SCANNING IS START");
251 if (!ms_config_set_int(MS_SCAN_STATUS_DIRECTORY, P_VCONF_SCAN_DOING)) {
252 MS_DBG_ERR("ms_config_set_int failed");
256 g_mutex_unlock(scanner_mutex);
258 if (ms_get_scanner_status()) {
259 MS_DBG("Scanner is ready");
260 ms_send_scan_request(&scan_msg);
262 MS_DBG("Scanner starts");
263 ret = ms_scanner_start();
264 if(ret == MS_MEDIA_ERR_NONE) {
265 ms_send_scan_request(&scan_msg);
267 MS_DBG("Scanner starting failed. %d", ret);
271 /* NEED IMPLEMENTATION */
272 MS_SAFE_FREE(client_addr);
273 g_mutex_unlock(scanner_mutex);
281 gboolean ms_receive_message_from_scanner(GIOChannel *src, GIOCondition condition, gpointer data)
283 ms_comm_msg_s recv_msg;
284 int sockfd = MS_SOCK_NOT_ALLOCATE;
288 sockfd = g_io_channel_unix_get_fd(src);
290 MS_DBG_ERR("sock fd is invalid!");
294 /* Socket is readable */
295 ret = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(recv_msg), NULL, NULL);
296 if (ret != MS_MEDIA_ERR_NONE) {
297 MS_DBG_ERR("ms_ipc_receive_message failed [%s]", strerror(errno));
301 MS_DBG("receive msg from [%d] %d, %s", recv_msg.pid, recv_msg.msg_type, recv_msg.msg);
303 msg_type = recv_msg.msg_type;
304 if ((msg_type == MS_MSG_SCANNER_RESULT) ||
305 (msg_type == MS_MSG_SCANNER_BULK_RESULT)) {
306 if (owner_list != NULL) {
307 /* If the owner of result message is not media-server, media-server notify to the owner */
308 /* The owner of message is distingushied by pid in received message*/
309 /* find owner data */
310 ms_req_owner_data *owner_data = NULL;
312 _ms_find_owner(recv_msg.pid, &owner_data);
313 if (owner_data != NULL) {
314 MS_DBG("PID : %d", owner_data->pid);
315 ms_comm_msg_s *result_msg;
317 if (msg_type == MS_MSG_SCANNER_RESULT) {
318 MS_DBG("DIRECTORY SCANNING IS DONE");
319 if (!ms_config_set_int(MS_SCAN_STATUS_DIRECTORY, P_VCONF_SCAN_DONE)) {
320 MS_DBG_ERR("ms_config_set_int failed");
324 MS_MALLOC(result_msg, sizeof(ms_comm_msg_s));
325 /* owner data exists */
326 /* send result to the owner of request */
327 ms_ipc_send_msg_to_client(sockfd, &recv_msg, owner_data->client_addr);
330 _ms_delete_owner(owner_data);
332 MS_SAFE_FREE(result_msg);
335 /* owner data does not exist*/
336 /* this is result of request of media server*/
339 MS_DBG_ERR("This result message is wrong : %d", recv_msg.msg_type );
345 int ms_send_scan_request(ms_comm_msg_s *send_msg)
348 int res = MS_MEDIA_ERR_NONE;
352 ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd);
353 if (ret != MS_MEDIA_ERR_NONE)
354 return MS_MEDIA_ERR_SOCKET_CONN;
356 ret = ms_ipc_send_msg_to_server(sockfd, MS_SCAN_DAEMON_PORT, send_msg, NULL);
357 if (ret != MS_MEDIA_ERR_NONE)
365 int ms_send_storage_scan_request(ms_storage_type_t storage_type, ms_dir_scan_type_t scan_type)
367 int ret = MS_MEDIA_ERR_NONE;
368 ms_comm_msg_s scan_msg = {
369 .msg_type = MS_MSG_STORAGE_INVALID,
370 .pid = 0, /* pid 0 means media-server */
379 scan_msg.msg_type = MS_MSG_STORAGE_PARTIAL;
382 scan_msg.msg_type = MS_MSG_STORAGE_ALL;
384 case MS_SCAN_INVALID:
385 scan_msg.msg_type = MS_MSG_STORAGE_INVALID;
388 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
389 MS_DBG_ERR("ms_send_storage_scan_request invalid parameter");
395 switch (storage_type) {
396 case MS_STORAGE_INTERNAL:
397 scan_msg.msg_size = strlen(MEDIA_ROOT_PATH_INTERNAL);
398 strncpy(scan_msg.msg, MEDIA_ROOT_PATH_INTERNAL, scan_msg.msg_size );
400 case MS_STORAGE_EXTERNAL:
401 scan_msg.msg_size = strlen(MEDIA_ROOT_PATH_SDCARD);
402 strncpy(scan_msg.msg, MEDIA_ROOT_PATH_SDCARD, scan_msg.msg_size );
405 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
406 MS_DBG_ERR("ms_send_storage_scan_request invalid parameter");
411 g_mutex_lock(scanner_mutex);
413 if (ms_get_scanner_status()) {
414 ms_send_scan_request(&scan_msg);
415 g_mutex_unlock(scanner_mutex);
417 g_mutex_unlock(scanner_mutex);
419 ret = ms_scanner_start();
420 if(ret == MS_MEDIA_ERR_NONE) {
421 ms_send_scan_request(&scan_msg);
423 MS_DBG("Scanner starting failed. ");
432 gboolean ms_read_db_socket(GIOChannel *src, GIOCondition condition, gpointer data)
434 struct sockaddr_in client_addr;
436 ms_comm_msg_s recv_msg;
437 int send_msg = MS_MEDIA_ERR_NONE;
438 int sockfd = MS_SOCK_NOT_ALLOCATE;
439 int ret = MS_MEDIA_ERR_NONE;
440 MediaDBHandle *db_handle = (MediaDBHandle *)data;
442 char * sql_query = NULL;
443 size_t sql_query_size = 0;
445 memset(&recv_msg, 0, sizeof(recv_msg));
447 sockfd = g_io_channel_unix_get_fd(src);
449 MS_DBG_ERR("sock fd is invalid!");
453 ret = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(recv_msg), &client_addr, NULL);
454 if (ret != MS_MEDIA_ERR_NONE) {
455 MS_DBG_ERR("ms_ipc_receive_message failed");
459 // MS_DBG("msg_type[%d], msg_size[%d] msg[%s]", recv_msg.msg_type, recv_msg.msg_size, recv_msg.msg);
461 if((recv_msg.msg_size <= 0) ||(recv_msg.msg_size > MS_FILE_PATH_LEN_MAX) || (!MS_STRING_VALID(recv_msg.msg))) {
462 MS_DBG_ERR("invalid query. size[%d]", recv_msg.msg_size);
466 sql_query_size = recv_msg.msg_size + 1;
467 MS_MALLOC(sql_query, sql_query_size);
468 if (sql_query != NULL) {
469 ret = ms_strcopy(sql_query, sql_query_size, "%s", recv_msg.msg);
470 if (ret != MS_MEDIA_ERR_NONE) {
471 MS_DBG_ERR("ms_strcopy failed");
472 MS_SAFE_FREE(sql_query);
476 ret = media_db_update_db(db_handle, sql_query);
477 if (ret != MS_MEDIA_ERR_NONE)
478 MS_DBG_ERR("media_db_update_db error : %d", ret);
481 MS_SAFE_FREE(sql_query);
483 send_msg = MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
486 memset(&msg, 0x0, sizeof(ms_comm_msg_s));
487 msg.result = send_msg;
489 ms_ipc_send_msg_to_client(sockfd, &msg, &client_addr);
497 gboolean ms_read_db_tcp_socket(GIOChannel *src, GIOCondition condition, gpointer data)
499 struct sockaddr_in client_addr;
500 unsigned int client_addr_len;
502 ms_comm_msg_s recv_msg;
504 int client_sock = -1;
505 int send_msg = MS_MEDIA_ERR_NONE;
506 int recv_msg_size = -1;
507 int ret = MS_MEDIA_ERR_NONE;
508 char * sql_query = NULL;
509 size_t sql_query_size = 0;
510 MediaDBHandle *db_handle = (MediaDBHandle *)data;
512 sock = g_io_channel_unix_get_fd(src);
514 MS_DBG_ERR("sock fd is invalid!");
517 memset((void *)&recv_msg, 0, sizeof(ms_comm_msg_s));
519 if ((client_sock = accept(sock, (struct sockaddr*)&client_addr, &client_addr_len)) < 0) {
520 MS_DBG_ERR("accept failed : %s", strerror(errno));
524 MS_DBG("Client[%d] is accepted", client_sock);
527 if ((recv_msg_size = recv(client_sock, &recv_msg, sizeof(ms_comm_msg_s), 0)) < 0) {
528 MS_DBG_ERR("recv failed : %s", strerror(errno));
531 if (errno == EWOULDBLOCK) {
532 MS_DBG_ERR("Timeout. Can't try any more");
533 return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT;
535 MS_DBG_ERR("recv failed : %s", strerror(errno));
536 return MS_MEDIA_ERR_SOCKET_RECEIVE;
540 MS_DBG("Received [%d](%d) [%s]", recv_msg.msg_type, recv_msg.msg_size, recv_msg.msg);
542 if((recv_msg.msg_size <= 0) ||(recv_msg.msg_size > MS_FILE_PATH_LEN_MAX) || (!MS_STRING_VALID(recv_msg.msg))) {
543 MS_DBG_ERR("invalid query. size[%d]", recv_msg.msg_size);
548 sql_query_size = recv_msg.msg_size + 1;
549 MS_MALLOC(sql_query, sql_query_size);
550 if (sql_query != NULL) {
551 ret = ms_strcopy(sql_query, sql_query_size, "%s", recv_msg.msg);
552 if (ret != MS_MEDIA_ERR_NONE) {
553 MS_DBG_ERR("ms_strcopy failed");
554 MS_SAFE_FREE(sql_query);
559 if (recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_START) {
560 ret = media_db_update_db_batch_start(sql_query);
561 } else if(recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_END) {
562 ret = media_db_update_db_batch_end(db_handle, sql_query);
563 } else if(recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH) {
564 ret = media_db_update_db_batch(sql_query);
569 MS_SAFE_FREE(sql_query);
572 if (send(client_sock, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) {
573 MS_DBG_ERR("send failed : %s", strerror(errno));
575 MS_DBG("Sent successfully");
578 if (recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_END)
581 memset((void *)&recv_msg, 0, sizeof(ms_comm_msg_s));
583 MS_DBG_ERR("MS_MALLOC failed");