* @retval #STORAGE_ERROR_NONE Successful
* @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #STORAGE_ERROR_NO_DEVICE No such device
+ * @retval #STORAGE_ERROR_OPERATION_FAILED Operation failed
+ * @retval #STORAGE_ERROR_OUT_OF_MEMORY Out of memory
*/
int storage_get_primary_sdcard(int *storage_id, char **path);
int storage_get_storage_level(const char *path, char **level);
/**
+ * @brief This structure defines the data for receive result of mmc operations(mount/unmount/format)
+ */
+struct mmc_contents {
+ void (*mmc_cb) (int result, void* data); /**< user callback function for receive result of mmc operations */
+ void* user_data; /**< input data for callback function's second-param(data) */
+};
+
+/**
+ * @brief This API is used to mount mmc.\n
+ *
+ * @param[in] mmc_data for receive result of mount operation
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ *
+ * @retval #STORAGE_ERROR_NONE Successful
+ * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STORAGE_ERROR_NO_DEVICE No such device
+ * @retval #STORAGE_ERROR_OPERATION_FAILED Operation failed
+ * @retval #STORAGE_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int storage_request_mount_mmc(struct mmc_contents *mmc_data);
+
+/**
+ * @brief This API is used to unmount mmc.\n
+ *
+ * @param[in] mmc_data for receive result of unmount operation
+ * @param[in] option type of unmount option \n
+ * 0 : Normal unmount \n
+ * (if other process still access a sdcard, \n
+ * unmount will be failed.) \n
+ * 1 : Force unmount \n
+ * (if other process still access a sdcard, \n
+ * this process will be received SIGTERM or SIGKILL.)
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ *
+ * @retval #STORAGE_ERROR_NONE Successful
+ * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STORAGE_ERROR_NO_DEVICE No such device
+ * @retval #STORAGE_ERROR_OPERATION_FAILED Operation failed
+ * @retval #STORAGE_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int storage_request_unmount_mmc(struct mmc_contents *mmc_data, int option);
+
+/**
+ * @brief This API is used to format mmc.\n
+ *
+ * @param[in] mmc_data for receive result of format operation
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ *
+ * @retval #STORAGE_ERROR_NONE Successful
+ * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STORAGE_ERROR_NO_DEVICE No such device
+ * @retval #STORAGE_ERROR_OPERATION_FAILED Operation failed
+ * @retval #STORAGE_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int storage_request_format_mmc(struct mmc_contents *mmc_data);
+
+/**
+ * @brief This API is used to format mmc.\n
+ *
+ * @param[in] mmc_data for receive result of format operation
+ * @param[in] option FMT_NORMAL is 0, FMT_FORCE is 1
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ *
+ * @retval #STORAGE_ERROR_NONE Successful
+ * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STORAGE_ERROR_NO_DEVICE No such device
+ * @retval #STORAGE_ERROR_OPERATION_FAILED Operation failed
+ * @retval #STORAGE_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int storage_format_mmc(struct mmc_contents *mmc_data, int option);
+
+/**
* @}
*/
guint block_id;
};
+typedef struct {
+ dbus_pending_cb func;
+ void *data;
+} pending_call_data;
+
static dd_list *changed_list;
static void storage_ext_release_internal(storage_ext_device *dev)
return conn;
}
+static void _cb_pending(GDBusConnection *conn,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GVariant *reply = NULL;
+ GError *err = NULL;
+ pending_call_data *data = (pending_call_data *)user_data;
+
+ reply = g_dbus_connection_call_finish(conn, res, &err);
+ if (!reply || err) {
+ if (!err)
+ g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Error during g_dbus_connection_call");
+
+ if (data && data->func)
+ data->func(NULL, data->data, err);
+ goto out;
+ }
+
+ if (data && data->func)
+ data->func(reply, data->data, err);
+out:
+ if (err)
+ g_error_free(err);
+ if (data)
+ free(data);
+}
+
+int dbus_method_async_with_reply_var(const char *dest, const char *path,
+ const char *iface, const char *method, GVariant *param,
+ dbus_pending_cb cb, int timeout, void *data)
+{
+ GDBusConnection *conn;
+ pending_call_data *pdata = NULL;
+ int ret = 0;
+
+ if (!dest || !path || !iface || !method)
+ return -EINVAL;
+
+ if (timeout < -1) {
+ _E("wrong timeout %d", timeout);
+ return -EINVAL;
+ }
+
+ conn = get_dbus_connection();
+ if (!conn) {
+ _E("fail to get dbus connection"); //LCOV_EXCL_LINE
+ return -1;
+ }
+
+ if (cb) {
+ pdata = (pending_call_data*)malloc(sizeof(pending_call_data));
+ if (!pdata) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ pdata->func = cb;
+ pdata->data = data;
+ }
+
+ g_dbus_connection_call(conn, dest, path, iface, method,
+ param, NULL, G_DBUS_CALL_FLAGS_NONE, timeout, NULL,
+ (GAsyncReadyCallback)_cb_pending,
+ pdata);
+
+ return ret;
+err:
+ if (param)
+ g_variant_unref(param);
+ return ret;
+}
+
GVariant *dbus_method_call_sync(const gchar *dest, const gchar *path,
const gchar *iface, const gchar *method, GVariant *param)
{
int storage_ext_get_device_info(int storage_id, storage_ext_device *info);
int storage_ext_get_storage_level(const char *path, char **level);
+typedef void (*dbus_pending_cb)(GVariant *var, void *user_data, GError *err);
+int dbus_method_async_with_reply_var(const char *dest, const char *path,
+ const char *iface, const char *method, GVariant *param,
+ dbus_pending_cb cb, int timeout, void *data);
/* storage-internal.c */
GVariant *dbus_method_call_sync(const gchar *dest, const gchar *path,
const gchar *iface, const gchar *method, GVariant *param);
#include "storage-internal.h"
#include "storage-external-dbus.h"
+#define FORMAT_TIMEOUT (120*1000)
+
/*
Get compat path from origin Multi-user path
from TZ_USER_CONTENT/.. to /opt/usr/media/..
return STORAGE_ERROR_NONE;
}
+
+static void mount_mmc_cb(GVariant *var, void *user_data, GError *err)
+{
+ struct mmc_contents *mmc_data = (struct mmc_contents*)user_data;
+ int mmc_ret = -1;
+
+ _D("mount_mmc_cb called");
+
+ if (!var) {
+ _E("no message [%s]", err->message);
+ mmc_ret = -EBADMSG;
+ goto exit;
+ }
+
+ g_variant_get(var, "(i)", &mmc_ret);
+
+ _I("Mount State : %d", mmc_ret);
+
+exit:
+ if (var)
+ g_variant_unref(var);
+ (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
+}
+
+API int storage_request_mount_mmc(struct mmc_contents *mmc_data)
+{
+ void (*mount_cb)(GVariant *, void *, GError *) = NULL;
+ void *data = NULL;
+ char *path;
+ int ret;
+ int id;
+
+ if (mmc_data && mmc_data->mmc_cb) {
+ _I("Mount callback exists");
+ mount_cb = mount_mmc_cb;
+ data = mmc_data;
+ }
+
+ ret = storage_get_primary_sdcard(&id, &path);
+ if (ret != STORAGE_ERROR_NONE)
+ return ret;
+
+ ret = dbus_method_async_with_reply_var(STORAGE_EXT_BUS_NAME,
+ STORAGE_EXT_PATH_MANAGER,
+ STORAGE_EXT_IFACE_MANAGER,
+ "Mount",
+ g_variant_new("(is)", id, ""),
+ mount_cb,
+ -1,
+ data);
+
+ _I("Mount Request %s", ret == 0 ? "Success" : "Failed");
+
+ if (ret == -ENOMEM)
+ return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
+ if (ret < 0)
+ return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+
+ return STORAGE_ERROR_NONE;
+}
+
+static void unmount_mmc_cb(GVariant *var, void *user_data, GError *err)
+{
+ struct mmc_contents *mmc_data = (struct mmc_contents*)user_data;
+ int mmc_ret;
+
+ _D("unmount_mmc_cb called");
+
+ if (!var) {
+ _E("no message [%s]", err->message);
+ mmc_ret = -EBADMSG;
+ goto exit;
+ }
+
+ g_variant_get(var, "(i)", &mmc_ret);
+
+ _I("Unmount State : %d", mmc_ret);
+
+exit:
+ if (var)
+ g_variant_unref(var);
+ (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
+}
+
+API int storage_request_unmount_mmc(struct mmc_contents *mmc_data, int option)
+{
+ void (*unmount_cb)(GVariant *, void *, GError *) = NULL;
+ void *data = NULL;
+ char *path;
+ int ret;
+ int id;
+
+ if (option < 0 || option > 1)
+ return STORAGE_ERROR_INVALID_PARAMETER;
+
+ if (mmc_data && mmc_data->mmc_cb) {
+ _I("Unmount callback exists");
+ unmount_cb = unmount_mmc_cb;
+ data = mmc_data;
+ }
+
+ ret = storage_get_primary_sdcard(&id, &path);
+ if (ret != STORAGE_ERROR_NONE)
+ return ret;
+
+ ret = dbus_method_async_with_reply_var(STORAGE_EXT_BUS_NAME,
+ STORAGE_EXT_PATH_MANAGER,
+ STORAGE_EXT_IFACE_MANAGER,
+ "Unmount",
+ g_variant_new("(ii)", id, option),
+ unmount_cb,
+ -1,
+ data);
+
+ _I("Unmount Request %s", ret == 0 ? "Success" : "Failed");
+
+ if (ret == -ENOMEM)
+ return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
+ if (ret < 0)
+ return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+
+ return STORAGE_ERROR_NONE;
+}
+
+static void format_mmc_cb(GVariant *var, void *user_data, GError *err)
+{
+ struct mmc_contents *mmc_data = (struct mmc_contents*)user_data;
+ int mmc_ret;
+
+ _D("format_mmc_cb called");
+
+ if (!var) {
+ _E("no message [%s]", err->message);
+ mmc_ret = -EBADMSG;
+ goto exit;
+ }
+
+ g_variant_get(var, "(i)", &mmc_ret);
+
+ _I("Format State : %d", mmc_ret);
+
+exit:
+ if (var)
+ g_variant_unref(var);
+ (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
+}
+
+API int storage_request_format_mmc(struct mmc_contents *mmc_data)
+{
+ return storage_format_mmc(mmc_data, 1);
+}
+
+API int storage_format_mmc(struct mmc_contents *mmc_data, int option)
+{
+ void (*format_cb)(GVariant *, void *, GError *) = NULL;
+ void *data = NULL;
+ char *path;
+ int ret;
+ int id;
+
+ if (option < 0 || option > 1)
+ return STORAGE_ERROR_INVALID_PARAMETER;
+
+ if (mmc_data && mmc_data->mmc_cb) {
+ _I("Format callback exists");
+ format_cb = format_mmc_cb;
+ data = mmc_data;
+ }
+
+ ret = storage_get_primary_sdcard(&id, &path);
+ if (ret != STORAGE_ERROR_NONE)
+ return ret;
+
+ ret = dbus_method_async_with_reply_var(STORAGE_EXT_BUS_NAME,
+ STORAGE_EXT_PATH_MANAGER,
+ STORAGE_EXT_IFACE_MANAGER,
+ "Format",
+ g_variant_new("(ii)", id, option),
+ format_cb,
+ FORMAT_TIMEOUT,
+ data);
+
+ _I("Format Request %s", ret == 0 ? "Success" : "Failed");
+
+ if (ret == -ENOMEM)
+ return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
+ if (ret < 0)
+ return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+
+ return STORAGE_ERROR_NONE;
+}