2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <sys/statvfs.h>
24 #include <tzplatform_config.h>
29 #include "storage-external-dbus.h"
31 static dd_list *cb_list[STORAGE_CALLBACK_MAX];
33 static int storage_ext_get_dev_state(storage_ext_device *dev,
34 enum storage_ext_state blk_state,
35 storage_state_e *state)
41 case STORAGE_EXT_ADDED:
42 *state = STORAGE_STATE_UNMOUNTABLE;
44 case STORAGE_EXT_REMOVED:
45 *state = STORAGE_STATE_REMOVED;
47 case STORAGE_EXT_CHANGED:
49 case STORAGE_EXT_UNMOUNTED:
50 *state = STORAGE_STATE_UNMOUNTABLE;
52 case STORAGE_EXT_MOUNTED:
53 if (dev->flags & MOUNT_READONLY)
54 *state = STORAGE_STATE_MOUNTED_READ_ONLY;
56 *state = STORAGE_STATE_MOUNTED;
61 case STORAGE_EXT_BLOCKED:
62 *state = STORAGE_STATE_UNMOUNTABLE;
69 int storage_ext_get_space(int storage_id,
70 unsigned long long *total, unsigned long long *available)
72 storage_state_e state;
75 unsigned long long t = 0, a = 0;
76 storage_ext_device *dev;
81 dev = calloc(1, sizeof(storage_ext_device));
83 //LCOV_EXCL_START System Error
89 ret = storage_ext_get_device_info(storage_id, dev);
91 _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
95 ret = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, &state);
97 _E("Failed to get state of storage (id:%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
101 if (state >= STORAGE_STATE_MOUNTED) {
102 #ifndef __USE_FILE_OFFSET64
103 ret = storage_get_external_memory_size_with_path(dev->mount_point, &s);
105 ret = storage_get_external_memory_size64_with_path(dev->mount_point, &s);
108 _E("Failed to get external memory size of (%s)(ret:%d)", dev->mount_point, ret); //LCOV_EXCL_LINE
112 t = (unsigned long long)s.f_frsize*s.f_blocks;
113 a = (unsigned long long)s.f_bsize*s.f_bavail;
123 storage_ext_release_device(&dev);
127 int storage_ext_foreach_device_list(storage_device_supported_cb callback, void *user_data)
131 dd_list *list = NULL, *elem;
132 storage_ext_device *dev;
133 storage_state_e state;
138 ret = storage_ext_get_list(&list);
140 _E("Failed to get external storage list from deviced (%d)", errno); //LCOV_EXCL_LINE
144 DD_LIST_FOREACH(list, elem, dev) {
145 ret = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, &state);
147 _E("Failed to get storage state (devnode:%s, ret:%d)", dev->devnode, ret); //LCOV_EXCL_LINE
151 ret_cb = callback(dev->storage_id, STORAGE_TYPE_EXTERNAL,
152 state, dev->mount_point, user_data);
158 storage_ext_release_list(&list);
162 //LCOV_EXCL_START Not called Callback
163 static int storage_ext_id_changed(storage_ext_device *dev, enum storage_ext_state blk_state, void *data)
165 enum storage_cb_type type = (enum storage_cb_type)data;
166 struct storage_cb_info *cb_info;
168 storage_state_e state;
174 if (type != STORAGE_CALLBACK_ID)
177 ret = storage_ext_get_dev_state(dev, blk_state, &state);
179 _E("Failed to get storage state (devnode:%s, ret:%d)", dev->devnode, ret);
183 DD_LIST_FOREACH(cb_list[STORAGE_CALLBACK_ID], elem, cb_info)
184 cb_info->state_cb(cb_info->id, state, cb_info->user_data);
189 static int storage_ext_type_changed(storage_ext_device *dev, enum storage_ext_state blk_state, void *data)
191 enum storage_cb_type type = (enum storage_cb_type)data;
192 struct storage_cb_info *cb_info;
194 storage_state_e state;
196 storage_dev_e strdev;
197 const char *fstype, *fsuuid, *mountpath;
202 if (type != STORAGE_CALLBACK_TYPE)
205 ret = storage_ext_get_dev_state(dev, blk_state, &state);
207 _E("Failed to get storage state (devnode:%s, ret:%d)", dev->devnode, ret);
211 if (dev->type == STORAGE_EXT_SCSI)
212 strdev = STORAGE_DEV_EXT_USB_MASS_STORAGE;
213 else if (dev->type == STORAGE_EXT_MMC)
214 strdev = STORAGE_DEV_EXT_SDCARD;
216 _E("Invalid dev type (%d)", dev->type);
220 fstype = (dev->fs_type ? (const char *)dev->fs_type : "");
221 fsuuid = (dev->fs_uuid ? (const char *)dev->fs_uuid : "");
222 mountpath = (dev->mount_point ? (const char *)dev->mount_point : "");
224 DD_LIST_FOREACH(cb_list[STORAGE_CALLBACK_TYPE], elem, cb_info)
225 if (cb_info->type_cb)
226 cb_info->type_cb(dev->storage_id, strdev, state,
227 fstype, fsuuid, mountpath, dev->primary,
228 dev->flags, cb_info->user_data);
235 static bool check_if_callback_exist(enum storage_cb_type type,
236 struct storage_cb_info *info, struct storage_cb_info **cb_data)
238 struct storage_cb_info *cb_info;
244 if (type == STORAGE_CALLBACK_ID) {
245 DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
246 if (cb_info->id == info->id &&
247 cb_info->state_cb == info->state_cb) {
253 if (type == STORAGE_CALLBACK_TYPE) {
254 DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
255 if (cb_info->type == info->type &&
256 cb_info->type_cb == info->type_cb)
270 int storage_ext_register_cb(enum storage_cb_type type, struct storage_cb_info *info)
272 struct storage_cb_info *cb_info;
274 storage_ext_changed_cb callback;
280 case STORAGE_CALLBACK_ID:
281 callback = storage_ext_id_changed;
283 case STORAGE_CALLBACK_TYPE:
284 callback = storage_ext_type_changed;
287 _E("Invalid callback type (%d)", type);
291 n = DD_LIST_LENGTH(cb_list[type]);
293 ret = storage_ext_register_device_change(callback, (void *)type);
298 if (check_if_callback_exist(type, info, NULL)) {
299 _E("The callback is already registered");
303 /* add device changed callback to list (local) */
304 cb_info = malloc(sizeof(struct storage_cb_info));
308 memcpy(cb_info, info, sizeof(struct storage_cb_info));
309 DD_LIST_APPEND(cb_list[type], cb_info);
314 int storage_ext_unregister_cb(enum storage_cb_type type, struct storage_cb_info *info)
316 struct storage_cb_info *cb_info;
318 storage_ext_changed_cb callback;
324 case STORAGE_CALLBACK_ID:
325 callback = storage_ext_id_changed;
327 case STORAGE_CALLBACK_TYPE:
328 callback = storage_ext_type_changed;
331 _E("Invalid callback type (%d)", type);
335 if (!check_if_callback_exist(type, info, &cb_info)) {
336 _E("The callback is not registered");
340 /* remove device callback from list (local) */
342 DD_LIST_REMOVE(cb_list[type], cb_info);
346 /* check if this callback is last element */
347 n = DD_LIST_LENGTH(cb_list[type]);
349 storage_ext_unregister_device_change(callback);
354 int storage_ext_get_root(int storage_id, char *path, size_t len)
356 storage_ext_device *dev;
365 dev = calloc(1, sizeof(storage_ext_device));
367 //LCOV_EXCL_START System Error
373 ret = storage_ext_get_device_info(storage_id, dev);
375 _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
379 snprintf(path, len, "%s", dev->mount_point);
383 storage_ext_release_device(&dev);
387 int storage_ext_get_state(int storage_id, storage_state_e *state)
389 storage_ext_device *dev;
398 dev = calloc(1, sizeof(storage_ext_device));
400 //LCOV_EXCL_START System Error
406 ret = storage_ext_get_device_info(storage_id, dev);
408 _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
412 ret = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, state);
414 _E("Failed to get state of storage id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
417 storage_ext_release_device(&dev);
421 int storage_ext_get_primary_mmc_path(char *path, size_t len)
423 dd_list *list = NULL, *elem;
424 storage_ext_device *dev;
427 ret = storage_ext_get_list(&list);
429 _E("Failed to get external storage list from deviced (%d)", errno); //LCOV_EXCL_LINE
433 DD_LIST_FOREACH(list, elem, dev) {
435 snprintf(path, len, "%s", dev->mount_point);
445 storage_ext_release_list(&list);