5e7cf6109fb26dd6abbff6d2b4d66ce7a6f0169f
[platform/core/system/system-server.git] / ss_mmc_handler.c
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17
18 #include <unistd.h>
19 #include <sys/mount.h>
20 #include <errno.h>
21 #include <vconf.h>
22 #include <devman.h>
23 #include <fcntl.h>
24 #include <dirent.h>
25 #include <sysman.h>
26 #include "ss_log.h"
27 #include "ss_device_handler.h"
28
29 #define MOVINAND_DEV            "/dev/mmcblk0p1"
30 #define FORMAT_MMC              PREFIX"/sbin/mkfs.vfat "
31 #define FORMAT_MOVINAND         PREFIX"/bin/movi_format.sh"
32
33 int mmc_status;
34
35 int get_mmcblk_num()
36 {
37         DIR *dp;
38         struct dirent *dir;
39         struct stat stat;
40         char buf[255];
41         int fd;
42         int r;
43         int mmcblk_num;
44
45         if ((dp = opendir("/sys/block")) == NULL) {
46                 PRT_TRACE_ERR("Can not open directory..\n");
47                 return -1;
48         }
49         chdir("/sys/block");
50
51         while ((dir = readdir(dp)) != NULL) {
52                 memset(&stat, 0, sizeof(struct stat));
53                 if (lstat(dir->d_name, &stat) < 0)
54                         continue;
55                 if (S_ISDIR(stat.st_mode) || S_ISLNK(stat.st_mode)) {
56                         if (strncmp(".", dir->d_name, 1) == 0
57                             || strncmp("..", dir->d_name, 2) == 0)
58                                 continue;
59                         if (strncmp("mmcblk", dir->d_name, 6) == 0) {
60                                 snprintf(buf, 255, "/sys/block/%s/device/type",
61                                          dir->d_name);
62
63                                 fd = open(buf, O_RDONLY);
64                                 if (fd == -1) {
65                                         PRT_TRACE_ERR("%s open error: %s", buf,
66                                                       strerror(errno));
67                                         continue;
68                                 }
69                                 r = read(fd, buf, 10);
70                                 if ((r >= 0) && (r < 10))
71                                         buf[r] = '\0';
72                                 else
73                                         PRT_TRACE_ERR("%s read error: %s", buf,
74                                                       strerror(errno));
75                                 close(fd);
76                                 if (strncmp("SD", buf, 2) == 0) {
77                                         char *str_mmcblk_num = strndup((dir->d_name) + 6, 1);
78                                         if (str_mmcblk_num == NULL) {
79                                                 PRT_TRACE_ERR("Memory Allocation Failed");
80                                                 closedir(dp);
81                                                 return -1; 
82                                         }
83                                         mmcblk_num =
84                                             atoi(str_mmcblk_num);
85
86                                         free(str_mmcblk_num);
87                                         closedir(dp);
88                                         PRT_TRACE("%d \n", mmcblk_num);
89                                         return mmcblk_num;
90                                 }
91                         }
92
93                 }
94         }
95         closedir(dp);
96         PRT_TRACE_ERR("Failed to find mmc block number\n");
97         return -1;
98 }
99
100 static int ss_mmc_format(keynode_t *key_nodes, void *data)
101 {
102         PRT_TRACE_ERR("mmc format called");
103         device_set_property(DEVTYPE_MMC, MMC_PROP_FORMAT, 0);
104
105         return 0;
106 }
107
108 int ss_mmc_unmounted(int argc, char **argv)
109 {
110         int option = -1;
111
112         if (argc < 1) {
113                 PRT_TRACE_ERR("Option is wong");
114                 return -1;
115         }
116         if ((option = atoi(argv[0])) < 0) {
117                 PRT_TRACE_ERR("Option is wong : %d", option);
118                 return -1;
119         }
120
121         if (umount2(MMC_MOUNT_POINT, option) != 0) {
122                 PRT_TRACE_ERR("Failed to unmount mmc card\n");
123                 vconf_set_int(VCONFKEY_SYSMAN_MMC_UNMOUNT,
124                               VCONFKEY_SYSMAN_MMC_UNMOUNT_FAILED);
125                 return -1;
126
127         }
128         vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS,
129                       VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
130         vconf_set_int(VCONFKEY_SYSMAN_MMC_UNMOUNT,
131                       VCONFKEY_SYSMAN_MMC_UNMOUNT_COMPLETED);
132         mmc_status = VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED;
133
134         return 0;
135 }
136
137 int ss_mmc_init()
138 {
139         /* mmc card mount */
140         ss_mmc_inserted();
141
142         ss_action_entry_add_internal(PREDEF_MOUNT_MMC, ss_mmc_inserted, NULL,
143                                      NULL);
144         ss_action_entry_add_internal(PREDEF_UNMOUNT_MMC, ss_mmc_unmounted, NULL,
145                                      NULL);
146         ss_action_entry_add_internal(PREDEF_FORMAT_MMC, ss_mmc_format, NULL,
147                                      NULL);
148         return 0;
149 }
150
151 int ss_mmc_inserted()
152 {
153         char buf[NAME_MAX];
154         int blk_num, ret, retry = 0;
155         char opt[NAME_MAX];
156         char *popt = opt;
157         int r = 0;
158         if (mmc_status == VCONFKEY_SYSMAN_MMC_MOUNTED) {
159                 PRT_DBG("Mmc is already mounted.\n");
160                 vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS,
161                               VCONFKEY_SYSMAN_MMC_MOUNTED);
162                 vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT,
163                               VCONFKEY_SYSMAN_MMC_MOUNT_ALREADY);
164                 return -1;
165         }
166
167         if (access(MMC_MOUNT_POINT, R_OK) != 0) {
168                 r = mkdir(MMC_MOUNT_POINT, 0755);
169                 if(r < 0) {
170                         PRT_TRACE_ERR("Make Directory is failed");
171                         return -1;
172                 }
173         }
174
175         if ((blk_num = get_mmcblk_num()) == -1) {
176                 vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS,
177                               VCONFKEY_SYSMAN_MMC_REMOVED);
178                 vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT,
179                               VCONFKEY_SYSMAN_MMC_MOUNT_FAILED);
180                 mmc_status = VCONFKEY_SYSMAN_MMC_REMOVED;
181                 return 0;
182         }
183         popt = NULL;
184
185         snprintf(buf, sizeof(buf), "%s%d", MMC_DEV, blk_num);
186         if (mount
187             (buf, MMC_MOUNT_POINT, "vfat", 0,
188              "uid=0,gid=0,dmask=0000,fmask=0111,iocharset=iso8859-1,utf8,shortname=mixed,smackfsroot=*,smackfsdef=*")
189             == 0) {
190                 PRT_DBG("Mounted mmc card\n");
191                 vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS,
192                               VCONFKEY_SYSMAN_MMC_MOUNTED);
193                 vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT,
194                               VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED);
195                 mmc_status = VCONFKEY_SYSMAN_MMC_MOUNTED;
196                 return 0;
197         }
198         do {
199                 snprintf(buf, sizeof(buf), "%s%dp1", MMC_DEV, blk_num);
200                 if ((ret =
201                      mount(buf, MMC_MOUNT_POINT, "vfat", 0,
202                            "uid=0,gid=0,dmask=0000,fmask=0111,iocharset=iso8859-1,utf8,shortname=mixed,smackfsroot=*,smackfsdef=*"))
203                     == 0) {
204                         PRT_DBG("Mounted mmc card partition 1(%s)\n", buf);
205                         vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS,
206                                       VCONFKEY_SYSMAN_MMC_MOUNTED);
207                         vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT,
208                                       VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED);
209                         mmc_status = VCONFKEY_SYSMAN_MMC_MOUNTED;
210                         return 0;
211                 }
212                 usleep(100000);
213         } while (ret == -1 && errno == ENOENT && retry++ < 10);
214
215         vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS,
216                       VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
217         vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT,
218                       VCONFKEY_SYSMAN_MMC_MOUNT_FAILED);
219         mmc_status = VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED;
220         PRT_TRACE_ERR("Failed to mount mmc card\n");
221         return -1;
222 }
223
224 int ss_mmc_removed()
225 {
226         vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_REMOVED);
227
228         if (umount2(MMC_MOUNT_POINT, MNT_DETACH) != 0) {
229                 PRT_TRACE_ERR("Failed to unmount mmc card\n");
230         }
231         mmc_status = VCONFKEY_SYSMAN_MMC_REMOVED;
232
233         return 0;
234 }