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 #ifdef _USE_UDS_SOCKET_
35 #include <sys/socket.h>
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"
51 extern GAsyncQueue *scan_queue;
52 GAsyncQueue* ret_queue;
54 extern GMutex *scanner_mutex;
56 typedef struct ms_req_owner_data
60 #ifdef _USE_UDS_SOCKET_
61 struct sockaddr_un *client_addr;
63 struct sockaddr_in *client_addr;
67 int _ms_add_owner(ms_req_owner_data *owner_data)
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);
73 owner_data->index = -1;
74 g_array_append_val(owner_list, owner_data);
76 return MS_MEDIA_ERR_NONE;
79 int _ms_find_owner(int pid, ms_req_owner_data **owner_data)
82 int len = owner_list->len;
83 ms_req_owner_data *data = NULL;
87 MS_DBG("length list : %d", len);
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) {
100 return MS_MEDIA_ERR_NONE;
103 int _ms_delete_owner(ms_req_owner_data *owner_data)
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");
112 return MS_MEDIA_ERR_NONE;
115 gboolean ms_read_socket(GIOChannel *src, GIOCondition condition, gpointer data)
117 #ifdef _USE_UDS_SOCKET_
118 struct sockaddr_un *client_addr = NULL;
120 struct sockaddr_in *client_addr = NULL;
122 socklen_t client_addr_len;
123 ms_comm_msg_s recv_msg;
124 ms_comm_msg_s scan_msg;
126 int sockfd = MS_SOCK_NOT_ALLOCATE;
132 g_mutex_lock(scanner_mutex);
134 sockfd = g_io_channel_unix_get_fd(src);
136 MS_DBG_ERR("sock fd is invalid!");
137 g_mutex_unlock(scanner_mutex);
141 /* Socket is readable */
142 #ifdef _USE_UDS_SOCKET_
143 MS_MALLOC(client_addr, sizeof(struct sockaddr_un));
145 MS_MALLOC(client_addr, sizeof(struct sockaddr_in));
147 if (client_addr == NULL) {
148 MS_DBG_ERR("malloc failed");
149 g_mutex_unlock(scanner_mutex);
152 #ifdef _USE_UDS_SOCKET_
153 client_addr_len = sizeof(struct sockaddr_un);
155 client_addr_len = sizeof(struct sockaddr_in);
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);
165 MS_DBG("receive msg from [%d] %d, %s", recv_msg.pid, recv_msg.msg_type, recv_msg.msg);
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;
171 /*NEED IMPLEMETATION*/
172 MS_SAFE_FREE(client_addr);
173 g_mutex_unlock(scanner_mutex);
177 /* copy received data */
178 req_num = recv_msg.msg_type;
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 */
189 ms_req_owner_data *owner_data = NULL;
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);
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;
210 _ms_add_owner(owner_data);
212 /* create send message for media scanner */
213 scan_msg.msg_type = req_num;
215 scan_msg.msg_size = msg_size;
216 ms_strcopy(scan_msg.msg, path_size, "%s", recv_msg.msg);
218 g_mutex_unlock(scanner_mutex);
220 if (ms_get_scanner_status()) {
221 MS_DBG("Scanner is ready");
222 ms_send_scan_request(&scan_msg);
224 MS_DBG("Scanner starts");
225 ret = ms_scanner_start();
226 if(ret == MS_MEDIA_ERR_NONE) {
227 ms_send_scan_request(&scan_msg);
229 MS_DBG("Scanner starting failed. %d", ret);
233 /* NEED IMPLEMENTATION */
234 MS_SAFE_FREE(client_addr);
235 g_mutex_unlock(scanner_mutex);
243 gboolean ms_receive_message_from_scanner(GIOChannel *src, GIOCondition condition, gpointer data)
245 ms_comm_msg_s recv_msg;
246 int sockfd = MS_SOCK_NOT_ALLOCATE;
250 sockfd = g_io_channel_unix_get_fd(src);
252 MS_DBG_ERR("sock fd is invalid!");
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));
263 MS_DBG("receive msg from [%d] %d, %s", recv_msg.pid, recv_msg.msg_type, recv_msg.msg);
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;
274 _ms_find_owner(recv_msg.pid, &owner_data);
275 if (owner_data != NULL) {
276 MS_DBG("PID : %d", owner_data->pid);
278 if (msg_type == MS_MSG_SCANNER_RESULT) {
279 MS_DBG("DIRECTORY SCANNING IS DONE");
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);
287 _ms_delete_owner(owner_data);
290 /* owner data does not exist*/
291 /* this is result of request of media server*/
294 MS_DBG_ERR("This result message is wrong : %d", recv_msg.msg_type );
300 int ms_send_scan_request(ms_comm_msg_s *send_msg)
303 int res = MS_MEDIA_ERR_NONE;
307 #ifdef _USE_UDS_SOCKET_
308 ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd, MS_SCAN_DAEMON_PORT);
310 ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd);
312 if (ret != MS_MEDIA_ERR_NONE)
313 return MS_MEDIA_ERR_SOCKET_CONN;
315 ret = ms_ipc_send_msg_to_server(sockfd, MS_SCAN_DAEMON_PORT, send_msg, NULL);
316 if (ret != MS_MEDIA_ERR_NONE)
324 int ms_send_storage_scan_request(ms_storage_type_t storage_type, ms_dir_scan_type_t scan_type)
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 */
338 scan_msg.msg_type = MS_MSG_STORAGE_PARTIAL;
341 scan_msg.msg_type = MS_MSG_STORAGE_ALL;
343 case MS_SCAN_INVALID:
344 scan_msg.msg_type = MS_MSG_STORAGE_INVALID;
347 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
348 MS_DBG_ERR("ms_send_storage_scan_request invalid parameter");
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 );
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 );
364 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
365 MS_DBG_ERR("ms_send_storage_scan_request invalid parameter");
370 g_mutex_lock(scanner_mutex);
372 if (ms_get_scanner_status()) {
373 ms_send_scan_request(&scan_msg);
374 g_mutex_unlock(scanner_mutex);
376 g_mutex_unlock(scanner_mutex);
378 ret = ms_scanner_start();
379 if(ret == MS_MEDIA_ERR_NONE) {
380 ms_send_scan_request(&scan_msg);
382 MS_DBG("Scanner starting failed. ");
391 gboolean ms_read_db_socket(GIOChannel *src, GIOCondition condition, gpointer data)
393 #ifdef _USE_UDS_SOCKET_
394 struct sockaddr_un client_addr;
396 struct sockaddr_in client_addr;
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;
405 char * sql_query = NULL;
407 memset(&recv_msg, 0, sizeof(recv_msg));
409 sockfd = g_io_channel_unix_get_fd(src);
411 MS_DBG_ERR("sock fd is invalid!");
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");
421 // MS_DBG("msg_type[%d], msg_size[%d] msg[%s]", recv_msg.msg_type, recv_msg.msg_size, recv_msg.msg);
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);
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);
435 MS_SAFE_FREE(sql_query);
437 send_msg = MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
440 memset(&msg, 0x0, sizeof(ms_comm_msg_s));
441 msg.result = send_msg;
443 ms_ipc_send_msg_to_client(sockfd, &msg, &client_addr);
451 gboolean ms_read_db_tcp_socket(GIOChannel *src, GIOCondition condition, gpointer data)
453 #ifdef _USE_UDS_SOCKET_
454 struct sockaddr_un client_addr;
455 #elif defined(_USE_UDS_SOCKET_TCP_)
456 struct sockaddr_un client_addr;
458 struct sockaddr_in client_addr;
460 unsigned int client_addr_len;
462 ms_comm_msg_s recv_msg;
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;
471 sock = g_io_channel_unix_get_fd(src);
473 MS_DBG_ERR("sock fd is invalid!");
476 memset((void *)&recv_msg, 0, sizeof(ms_comm_msg_s));
478 if ((client_sock = accept(sock, (struct sockaddr*)&client_addr, &client_addr_len)) < 0) {
479 MS_DBG_ERR("accept failed : %s", strerror(errno));
483 MS_DBG("Client[%d] is accepted", client_sock);
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));
490 if (errno == EWOULDBLOCK) {
491 MS_DBG_ERR("Timeout. Can't try any more");
492 return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT;
494 MS_DBG_ERR("recv failed : %s", strerror(errno));
495 return MS_MEDIA_ERR_SOCKET_RECEIVE;
499 // MS_DBG("Received [%d](%d) [%s]", recv_msg.msg_type, recv_msg.msg_size, recv_msg.msg);
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);
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);
520 MS_SAFE_FREE(sql_query);
523 if (send(client_sock, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) {
524 MS_DBG_ERR("send failed : %s", strerror(errno));
526 MS_DBG("Sent successfully");
529 if (recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_END)
532 memset((void *)&recv_msg, 0, sizeof(ms_comm_msg_s));
534 MS_DBG_ERR("MS_MALLOC failed");