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;
66 int storage_ext_get_space(int storage_id,
67 unsigned long long *total, unsigned long long *available)
69 storage_state_e state;
72 unsigned long long t = 0, a = 0;
73 storage_ext_device *dev;
78 dev = calloc(1, sizeof(storage_ext_device));
80 //LCOV_EXCL_START System Error
86 ret = storage_ext_get_device_info(storage_id, dev);
88 _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
92 ret = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, &state);
94 _E("Failed to get state of storage (id:%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
98 if (state >= STORAGE_STATE_MOUNTED) {
99 #ifndef __USE_FILE_OFFSET64
100 ret = storage_get_external_memory_size_with_path(dev->mount_point, &s);
102 ret = storage_get_external_memory_size64_with_path(dev->mount_point, &s);
105 _E("Failed to get external memory size of (%s)(ret:%d)", dev->mount_point, ret); //LCOV_EXCL_LINE
109 t = (unsigned long long)s.f_frsize*s.f_blocks;
110 a = (unsigned long long)s.f_bsize*s.f_bavail;
120 storage_ext_release_device(&dev);
124 int storage_ext_foreach_device_list(storage_device_supported_cb callback, void *user_data)
128 dd_list *list = NULL, *elem;
129 storage_ext_device *dev;
130 storage_state_e state;
135 ret = storage_ext_get_list(&list);
137 _E("Failed to get external storage list from deviced (%d)", errno); //LCOV_EXCL_LINE
141 DD_LIST_FOREACH(list, elem, dev) {
142 ret = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, &state);
144 _E("Failed to get storage state (devnode:%s, ret:%d)", dev->devnode, ret); //LCOV_EXCL_LINE
148 ret_cb = callback(dev->storage_id, STORAGE_TYPE_EXTERNAL,
149 state, dev->mount_point, user_data);
155 storage_ext_release_list(&list);
159 //LCOV_EXCL_START Not called Callback
160 static int storage_ext_id_changed(storage_ext_device *dev, enum storage_ext_state blk_state, void *data)
162 enum storage_cb_type type = (enum storage_cb_type)data;
163 struct storage_cb_info *cb_info;
165 storage_state_e state;
171 if (type != STORAGE_CALLBACK_ID)
174 ret = storage_ext_get_dev_state(dev, blk_state, &state);
176 _E("Failed to get storage state (devnode:%s, ret:%d)", dev->devnode, ret);
180 DD_LIST_FOREACH(cb_list[STORAGE_CALLBACK_ID], elem, cb_info)
181 cb_info->state_cb(cb_info->id, state, cb_info->user_data);
186 static int storage_ext_type_changed(storage_ext_device *dev, enum storage_ext_state blk_state, void *data)
188 enum storage_cb_type type = (enum storage_cb_type)data;
189 struct storage_cb_info *cb_info;
191 storage_state_e state;
193 storage_dev_e strdev;
194 const char *fstype, *fsuuid, *mountpath;
199 if (type != STORAGE_CALLBACK_TYPE)
202 ret = storage_ext_get_dev_state(dev, blk_state, &state);
204 _E("Failed to get storage state (devnode:%s, ret:%d)", dev->devnode, ret);
208 if (dev->type == STORAGE_EXT_SCSI)
209 strdev = STORAGE_DEV_EXT_USB_MASS_STORAGE;
210 else if (dev->type == STORAGE_EXT_MMC)
211 strdev = STORAGE_DEV_EXT_SDCARD;
213 _E("Invalid dev type (%d)", dev->type);
217 fstype = (dev->fs_type ? (const char *)dev->fs_type : "");
218 fsuuid = (dev->fs_uuid ? (const char *)dev->fs_uuid : "");
219 mountpath = (dev->mount_point ? (const char *)dev->mount_point : "");
221 DD_LIST_FOREACH(cb_list[STORAGE_CALLBACK_TYPE], elem, cb_info)
222 if (cb_info->type_cb)
223 cb_info->type_cb(dev->storage_id, strdev, state,
224 fstype, fsuuid, mountpath, dev->primary,
225 dev->flags, cb_info->user_data);
232 static bool check_if_callback_exist(enum storage_cb_type type,
233 struct storage_cb_info *info, struct storage_cb_info **cb_data)
235 struct storage_cb_info *cb_info;
241 if (type == STORAGE_CALLBACK_ID) {
242 DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
243 if (cb_info->id == info->id &&
244 cb_info->state_cb == info->state_cb) {
250 if (type == STORAGE_CALLBACK_TYPE) {
251 DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
252 if (cb_info->type == info->type &&
253 cb_info->type_cb == info->type_cb)
267 int storage_ext_register_cb(enum storage_cb_type type, struct storage_cb_info *info)
269 struct storage_cb_info *cb_info;
271 storage_ext_changed_cb callback;
277 case STORAGE_CALLBACK_ID:
278 callback = storage_ext_id_changed;
280 case STORAGE_CALLBACK_TYPE:
281 callback = storage_ext_type_changed;
284 _E("Invalid callback type (%d)", type);
288 n = DD_LIST_LENGTH(cb_list[type]);
290 ret = storage_ext_register_device_change(callback, (void *)type);
295 if (check_if_callback_exist(type, info, NULL)) {
296 _E("The callback is already registered");
300 /* add device changed callback to list (local) */
301 cb_info = malloc(sizeof(struct storage_cb_info));
305 memcpy(cb_info, info, sizeof(struct storage_cb_info));
306 DD_LIST_APPEND(cb_list[type], cb_info);
311 int storage_ext_unregister_cb(enum storage_cb_type type, struct storage_cb_info *info)
313 struct storage_cb_info *cb_info;
315 storage_ext_changed_cb callback;
321 case STORAGE_CALLBACK_ID:
322 callback = storage_ext_id_changed;
324 case STORAGE_CALLBACK_TYPE:
325 callback = storage_ext_type_changed;
328 _E("Invalid callback type (%d)", type);
332 if (!check_if_callback_exist(type, info, &cb_info)) {
333 _E("The callback is not registered");
337 /* remove device callback from list (local) */
339 DD_LIST_REMOVE(cb_list[type], cb_info);
343 /* check if this callback is last element */
344 n = DD_LIST_LENGTH(cb_list[type]);
346 storage_ext_unregister_device_change(callback);
351 int storage_ext_get_root(int storage_id, char *path, size_t len)
353 storage_ext_device *dev;
362 dev = calloc(1, sizeof(storage_ext_device));
364 //LCOV_EXCL_START System Error
370 ret = storage_ext_get_device_info(storage_id, dev);
372 _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
376 snprintf(path, len, "%s", dev->mount_point);
380 storage_ext_release_device(&dev);
384 int storage_ext_get_state(int storage_id, storage_state_e *state)
386 storage_ext_device *dev;
395 dev = calloc(1, sizeof(storage_ext_device));
397 //LCOV_EXCL_START System Error
403 ret = storage_ext_get_device_info(storage_id, dev);
405 _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
409 ret = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, state);
411 _E("Failed to get state of storage id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
414 storage_ext_release_device(&dev);
418 int storage_ext_get_primary_mmc_path(char *path, size_t len)
420 dd_list *list = NULL, *elem;
421 storage_ext_device *dev;
424 ret = storage_ext_get_list(&list);
426 _E("Failed to get external storage list from deviced (%d)", errno); //LCOV_EXCL_LINE
430 DD_LIST_FOREACH(list, elem, dev) {
432 snprintf(path, len, "%s", dev->mount_point);
442 storage_ext_release_list(&list);