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-util-register.c
26 * @author Yong Yeon Kim(yy9875.kim@samsung.com)
32 #include <arpa/inet.h>
33 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <sys/syscall.h>
43 #include "media-server-ipc.h"
44 #include "media-util-internal.h"
45 #include "media-util-dbg.h"
46 #include "media-util.h"
48 typedef struct media_callback_data{
50 scan_complete_cb user_callback;
52 } media_callback_data;
54 static bool _is_valid_path(const char *path)
59 if (strncmp(path, MEDIA_ROOT_PATH_INTERNAL, strlen(MEDIA_ROOT_PATH_INTERNAL)) == 0) {
61 } else if (strncmp(path, MEDIA_ROOT_PATH_SDCARD, strlen(MEDIA_ROOT_PATH_SDCARD)) == 0) {
69 static int _check_dir_path(const char *dir_path)
74 if (!_is_valid_path(dir_path)) {
75 MSAPI_DBG("Invalid path : %s", dir_path);
76 return MS_MEDIA_ERR_INVALID_PATH;
79 if (stat(dir_path, &sb) == -1) {
80 MSAPI_DBG("stat failed");
81 dp = opendir(dir_path);
83 /*if openning directory is failed, check it exists. */
84 if (errno == ENOENT) {
85 /* this directory is deleted */
86 return MS_MEDIA_ERR_NONE;
91 return MS_MEDIA_ERR_INTERNAL;
93 if((sb.st_mode & S_IFMT) != S_IFDIR) {
94 MSAPI_DBG("Invalid path : %s is not directory", dir_path);
95 return MS_MEDIA_ERR_INVALID_PATH;
99 return MS_MEDIA_ERR_NONE;
103 /* receive message from media-server[function : ms_receive_message_from_scanner] */
104 gboolean _read_socket(GIOChannel *src, GIOCondition condition, gpointer data)
106 GSource *source = NULL;
107 scan_complete_cb user_callback;
108 void *user_data = NULL;
109 ms_comm_msg_s recv_msg;
110 media_request_result_s req_result;
114 sockfd = g_io_channel_unix_get_fd(src);
116 MSAPI_DBG("sock fd is invalid!");
120 memset(&recv_msg, 0x0, sizeof(ms_comm_msg_s));
122 /* Socket is readable */
123 ret = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(recv_msg), NULL, NULL);
124 if (ret != MS_MEDIA_ERR_NONE) {
125 MSAPI_DBG("ms_ipc_receive_message failed");
129 memset(&req_result, 0x0, sizeof(media_request_result_s));
130 req_result.pid = recv_msg.pid;
131 req_result.result = recv_msg.result;
132 if (recv_msg.msg_type ==MS_MSG_SCANNER_RESULT) {
133 req_result.complete_path = strdup(recv_msg.msg);
134 req_result.request_type = MEDIA_DIRECTORY_SCAN;
135 MSAPI_DBG("complete_path :%d", req_result.complete_path);
136 } else if (recv_msg.msg_type == MS_MSG_SCANNER_BULK_RESULT) {
137 req_result.complete_path = strdup(recv_msg.msg);
138 req_result.request_type = MEDIA_FILES_REGISTER;
141 MSAPI_DBG("pid :%d", req_result.pid);
142 MSAPI_DBG("result :%d", req_result.result);
143 MSAPI_DBG("request_type :%d", req_result.request_type);
145 source = ((media_callback_data *)data)->source;
146 user_callback = ((media_callback_data *)data)->user_callback;
147 user_data = ((media_callback_data *)data)->user_data;
149 /*call user define function*/
150 user_callback(&req_result, user_data);
152 MS_SAFE_FREE(req_result.complete_path);
154 /*close an IO channel*/
155 g_io_channel_shutdown(src, FALSE, NULL);
156 g_io_channel_unref(src);
158 g_source_destroy(source);
165 static int _attach_callback(int *sockfd, scan_complete_cb user_callback, void *user_data)
167 GIOChannel *channel = NULL;
168 GMainContext *context = NULL;
169 GSource *source = NULL;
170 media_callback_data *cb_data;
172 /*get the global default main context*/
173 context = g_main_context_default();
175 /* Create new channel to watch udp socket */
176 channel = g_io_channel_unix_new(*sockfd);
177 source = g_io_create_watch(channel, G_IO_IN);
179 cb_data = malloc(sizeof(media_callback_data));
180 cb_data->source = source;
181 cb_data->user_callback = user_callback;
182 cb_data->user_data = user_data;
184 /* Set callback to be called when socket is readable */
185 g_source_set_callback(source, (GSourceFunc)_read_socket, cb_data, NULL);
186 g_source_attach(source, context);
187 g_source_unref(source);
189 return MS_MEDIA_ERR_NONE;
192 static int __media_db_request_update_sync(ms_msg_type_e msg_type, const char *request_msg)
194 int ret = MS_MEDIA_ERR_NONE;
195 int request_msg_size = 0;
198 struct sockaddr_in serv_addr;
199 unsigned int serv_addr_len = -1;
200 int port = MS_SCANNER_PORT;
201 ms_comm_msg_s send_msg;
203 if(!MS_STRING_VALID(request_msg))
205 MSAPI_DBG_ERR("invalid query");
206 return MS_MEDIA_ERR_INVALID_PARAMETER;
209 request_msg_size = strlen(request_msg);
210 if(request_msg_size >= MAX_MSG_SIZE)
212 MSAPI_DBG_ERR("Query is Too long. [%d] query size limit is [%d]", request_msg_size, MAX_MSG_SIZE);
213 return MS_MEDIA_ERR_INVALID_PARAMETER;
216 MSAPI_DBG("querysize[%d] query[%s]", request_msg_size, request_msg);
218 memset((void *)&send_msg, 0, sizeof(ms_comm_msg_s));
219 send_msg.msg_type = msg_type;
220 send_msg.pid = syscall(__NR_getpid);
221 send_msg.msg_size= request_msg_size;
222 strncpy(send_msg.msg, request_msg, request_msg_size);
225 ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, MS_TIMEOUT_SEC_10, &sockfd);
226 MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret);
228 ret = ms_ipc_send_msg_to_server(sockfd, port, &send_msg, &serv_addr);
229 if (ret != MS_MEDIA_ERR_NONE) {
230 MSAPI_DBG_ERR("ms_ipc_send_msg_to_server failed : %d", ret);
236 ms_comm_msg_s recv_msg;
237 serv_addr_len = sizeof(serv_addr);
239 memset(&recv_msg, 0x0, sizeof(ms_comm_msg_s));
240 err = ms_ipc_wait_message(sockfd, &recv_msg, sizeof(recv_msg), &serv_addr, NULL);
241 if (err != MS_MEDIA_ERR_NONE) {
244 MSAPI_DBG("RECEIVE OK [%d]", recv_msg.result);
245 ret = recv_msg.result;
254 static int __media_db_request_update_async(ms_msg_type_e msg_type, const char *request_msg, scan_complete_cb user_callback, void *user_data)
256 int ret = MS_MEDIA_ERR_NONE;
257 int request_msg_size = 0;
259 int port = MS_SCANNER_PORT;
260 ms_comm_msg_s send_msg;
262 if(!MS_STRING_VALID(request_msg))
264 MSAPI_DBG_ERR("invalid query");
265 return MS_MEDIA_ERR_INVALID_PARAMETER;
268 MSAPI_DBG("REQUEST DIRECTORY SCANNING");
270 request_msg_size = strlen(request_msg);
271 if(request_msg_size >= MAX_MSG_SIZE)
273 MSAPI_DBG_ERR("Query is Too long. [%d] query size limit is [%d]", request_msg_size, MAX_MSG_SIZE);
274 return MS_MEDIA_ERR_INVALID_PARAMETER;
277 MSAPI_DBG("querysize[%d] query[%s]", request_msg_size, request_msg);
279 memset((void *)&send_msg, 0, sizeof(ms_comm_msg_s));
280 send_msg.msg_type = msg_type;
281 send_msg.pid = syscall(__NR_getpid);
282 send_msg.msg_size = request_msg_size;
283 strncpy(send_msg.msg, request_msg, request_msg_size);
286 ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd);
287 MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret);
289 ret = ms_ipc_send_msg_to_server(sockfd, port, &send_msg, NULL);
290 if (ret != MS_MEDIA_ERR_NONE) {
291 MSAPI_DBG_ERR("ms_ipc_send_msg_to_server failed : %d", ret);
296 ret = _attach_callback(&sockfd, user_callback ,user_data);
297 if(ret != MS_MEDIA_ERR_NONE)
304 int media_directory_scanning_async(const char *directory_path, bool recusive_on, scan_complete_cb user_callback, void *user_data)
308 ret = _check_dir_path(directory_path);
309 if(ret != MS_MEDIA_ERR_NONE)
312 if (recusive_on == TRUE)
313 ret = __media_db_request_update_async(MS_MSG_DIRECTORY_SCANNING, directory_path, user_callback, user_data);
315 ret = __media_db_request_update_async(MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE, directory_path, user_callback, user_data);
320 static int _check_file_path(const char *file_path)
325 /* check location of file */
326 /* file must exists under "/opt/usr/media" or "/opt/storage/sdcard" */
327 if(!_is_valid_path(file_path)) {
328 MSAPI_DBG("Invalid path : %s", file_path);
329 return MS_MEDIA_ERR_INVALID_PATH;
332 /* check the file exits actually */
333 exist = open(file_path, O_RDONLY);
335 MSAPI_DBG("Not exist path : %s", file_path);
336 return MS_MEDIA_ERR_INVALID_PATH;
340 /* check type of the path */
341 /* It must be a regular file */
342 memset(&file_st, 0, sizeof(struct stat));
343 if(stat(file_path, &file_st) == 0) {
344 if(!S_ISREG(file_st.st_mode)) {
345 /* In this case, it is not a regula file */
346 MSAPI_DBG("this path is not a file");
347 return MS_MEDIA_ERR_INVALID_PATH;
350 MSAPI_DBG("stat failed [%s]", strerror(errno));
351 return MS_MEDIA_ERR_INTERNAL;
354 return MS_MEDIA_ERR_NONE;
357 int media_file_register(const char *file_full_path)
361 ret = _check_file_path(file_full_path);
362 if(ret != MS_MEDIA_ERR_NONE)
365 ret = __media_db_request_update_sync(MS_MSG_DB_UPDATE, file_full_path);
367 MSAPI_DBG("client receive: %d", ret);
372 int media_files_register(const char *list_path, insert_complete_cb user_callback, void *user_data)
376 ret = __media_db_request_update_async(MS_MSG_BULK_INSERT, list_path, user_callback, user_data);
378 MSAPI_DBG("client receive: %d", ret);