Apply implementation for /opt/usr lazy mount
[platform/core/connectivity/mtp-responder.git] / src / util / mtp_util.c
1 /*
2  * Copyright (c) 2012, 2013 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/types.h>
20 #include <fcntl.h>
21 #include <time.h>
22 #include <pthread.h>
23 #include <tapi_common.h>
24 #include <ITapiModem.h>
25 #include <system_info.h>
26 #include <vconf.h>
27 #include <gcrypt.h>
28 #include "mtp_util.h"
29 #include "mtp_support.h"
30 #include "mtp_fs.h"
31 #include <storage/storage.h>
32 #include <sys/stat.h>
33
34 static phone_state_t g_ph_status = { 0 };
35
36
37 void _util_print_error()
38 {
39         /*In glibc-2.7, the longest error message string is 50 characters
40           ("Invalid or incomplete multibyte or wide character"). */
41         mtp_char buff[100] = {0};
42
43         strerror_r(errno, buff, sizeof(buff));
44         ERR("Error: [%d]:[%s]\n", errno, buff);
45 }
46
47 mtp_int32 _util_get_battery_level(void)
48 {
49         mtp_int32 result = 0;
50         mtp_int32 battery_level = 100;
51
52         result = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
53                         &battery_level);
54         if (result != 0) {
55                 ERR("VCONFKEY_SYSMAN_BATTERY_CAPACITY Fail!");
56         }
57         return battery_level;
58 }
59
60 mtp_bool _util_get_serial(mtp_char *serial, mtp_uint32 len)
61 {
62         TapiHandle *handle = NULL;
63         mtp_char *imei_no = NULL;
64         mtp_char *serial_no = NULL;
65         mtp_uint16 i = 0;
66         char hash_value[MD5_HASH_LEN] = { 0 };
67
68         if (serial == NULL || len <= MD5_HASH_LEN * 2) {
69                 ERR("serial is null or length is less than (MD5_HASH_LEN * 2)");
70                 return FALSE;
71         }
72
73         serial_no = vconf_get_str(VCONFKEY_MTP_SERIAL_NUMBER_STR);
74         if (serial_no == NULL) {
75                 ERR("vconf_get Fail for %s\n",
76                                 VCONFKEY_MTP_SERIAL_NUMBER_STR);
77                 return FALSE;
78         }
79
80         if (strlen(serial_no) > 0) {
81                 g_strlcpy(serial, serial_no, len);
82                 g_free(serial_no);
83                 return TRUE;
84         }
85         g_free(serial_no);
86
87         handle = tel_init(NULL);
88         if (!handle) {
89                 ERR("tel_init Fail");
90                 return FALSE;
91         }
92
93         imei_no = tel_get_misc_me_imei_sync(handle);
94         if (!imei_no) {
95                 ERR("tel_get_misc_me_imei_sync Fail");
96                 tel_deinit(handle);
97                 return FALSE;
98         }
99
100         tel_deinit(handle);
101
102         gcry_md_hash_buffer(GCRY_MD_MD5, hash_value, imei_no, strlen(imei_no));
103
104         for (i = 0; i < MD5_HASH_LEN; i++) {
105                 g_snprintf(&serial[i*2], 3, "%02X", hash_value[i]);
106         }
107
108         if (vconf_set_str(VCONFKEY_MTP_SERIAL_NUMBER_STR, serial) == -1) {
109                 ERR("vconf_set Fail for %s\n",
110                                 VCONFKEY_MTP_SERIAL_NUMBER_STR);
111                 g_free(imei_no);
112                 return TRUE;
113         }
114
115         g_free(imei_no);
116         return TRUE;
117 }
118
119 void _util_get_vendor_ext_desc(mtp_char *vendor_ext_desc, mtp_uint32 len)
120 {
121         mtp_int32 ret = SYSTEM_INFO_ERROR_NONE;
122         mtp_char *version = NULL;
123
124         ret_if(len == 0);
125         ret_if(vendor_ext_desc == NULL);
126
127         ret = system_info_get_platform_string(
128                 "http://tizen.org/feature/platform.version", &version);
129
130         if (ret != SYSTEM_INFO_ERROR_NONE) {
131                 ERR("system_info_get_value_string Fail : 0x%X\n", ret);
132                 g_strlcpy(vendor_ext_desc, MTP_VENDOR_EXTENSIONDESC_CHAR, len);
133                 return;
134         }
135         g_snprintf(vendor_ext_desc, len, "%stizen.org:%s; ",
136                         MTP_VENDOR_EXTENSIONDESC_CHAR, version);
137         g_free(version);
138         return;
139 }
140
141 void _util_get_model_name(mtp_char *model_name, mtp_uint32 len)
142 {
143         mtp_int32 ret = SYSTEM_INFO_ERROR_NONE;
144         mtp_char *model = NULL;
145
146         ret_if(len == 0);
147         ret_if(model_name == NULL);
148
149         ret = system_info_get_platform_string(
150                 "http://tizen.org/system/model_name", &model);
151
152         if (ret != SYSTEM_INFO_ERROR_NONE) {
153                 ERR("system_info_get_value_string Fail : 0x%X\n", ret);
154                 g_strlcpy(model_name, MTP_DEFAULT_MODEL_NAME, len);
155                 return;
156         }
157         g_strlcpy(model_name, model, len);
158         g_free(model);
159         return;
160 }
161
162 void _util_get_device_version(mtp_char *device_version, mtp_uint32 len)
163 {
164         mtp_int32 ret = SYSTEM_INFO_ERROR_NONE;
165         mtp_char *version = NULL;
166         mtp_char *build_info = NULL;
167
168         ret_if(len == 0);
169         ret_if(device_version == NULL);
170
171         ret = system_info_get_platform_string(
172                 "http://tizen.org/feature/platform.version", &version);
173
174         if (ret != SYSTEM_INFO_ERROR_NONE) {
175                 ERR("system_info_get_value_string Fail : 0x%X\n", ret);
176                 g_strlcpy(device_version, MTP_DEFAULT_DEVICE_VERSION, len);
177                 return;
178         }
179
180         ret = system_info_get_platform_string(
181                 "http://tizen.org/system/build.string", &build_info);
182
183         if (ret != SYSTEM_INFO_ERROR_NONE) {
184                 ERR("system_info_get_value_string Fail : 0x%X\n", ret);
185                 g_strlcpy(device_version, MTP_DEFAULT_DEVICE_VERSION, len);
186                 g_free(version);
187                 return;
188         }
189         g_snprintf(device_version, len, "TIZEN %s (%s)", version, build_info);
190         g_free(version);
191         g_free(build_info);
192         return;
193 }
194
195 void _util_gen_alt_serial(mtp_char *serial, mtp_uint32 len)
196 {
197         struct timeval st;
198         mtp_char model_name[MTP_MODEL_NAME_LEN_MAX + 1] = { 0 };
199
200         ret_if(len == 0);
201         ret_if(serial == NULL);
202
203         if (gettimeofday(&st, NULL) < 0) {
204                 ERR("gettimeofday Fail");
205                 _util_print_error();
206                 return;
207         }
208         _util_get_model_name(model_name, sizeof(model_name));
209         g_snprintf(serial, len, "%s-%010ld-%011ld", model_name,
210                         st.tv_sec, st.tv_usec);
211
212         if (vconf_set_str(VCONFKEY_MTP_SERIAL_NUMBER_STR, serial) == -1) {
213                 ERR("vconf_set Fail %s\n", VCONFKEY_MTP_SERIAL_NUMBER_STR);
214         }
215
216         return;
217 }
218
219 void _util_get_usb_status(phone_status_t *val)
220 {
221         mtp_int32 ret = 0;
222         mtp_int32 state = 0;
223
224         ret = vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, &state);
225         if (ret == -1 || state == VCONFKEY_SYSMAN_USB_DISCONNECTED) {
226                 *val = MTP_PHONE_USB_DISCONNECTED;
227                 return;
228         }
229
230         *val = MTP_PHONE_USB_CONNECTED;
231         return;
232 }
233
234 phone_status_t _util_get_local_usb_status(void)
235 {
236         return g_ph_status.usb_state;
237 }
238
239 void _util_set_local_usb_status(const phone_status_t val)
240 {
241         g_ph_status.usb_state = val;
242         return;
243 }
244
245 void _util_get_mmc_status(phone_status_t *val)
246 {
247         mtp_int32 ret = 0;
248         mtp_int32 state = 0;
249
250         ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &state);
251         if (ret == -1 || state !=
252                         VCONFKEY_SYSMAN_MMC_MOUNTED) {
253                 *val = MTP_PHONE_MMC_NONE;
254                 return;
255         }
256
257         *val = MTP_PHONE_MMC_INSERTED;
258         return;
259 }
260
261 phone_status_t _util_get_local_mmc_status(void)
262 {
263         return g_ph_status.mmc_state;
264 }
265
266 void _util_set_local_mmc_status(const phone_status_t val)
267 {
268         g_ph_status.mmc_state = val;
269         return;
270 }
271
272 void _util_get_usbmode_status(phone_status_t *val)
273 {
274         mtp_int32 ret = 0;
275         mtp_int32 state = 0;
276
277         ret = vconf_get_int(VCONFKEY_USB_CUR_MODE,
278                         &state);
279         if (ret < 0) {
280                 *val = MTP_PHONE_USB_MODE_OTHER;
281                 return;
282         }
283
284         if (state == SET_USB_NONE)
285                 *val = MTP_PHONE_USB_DISCONNECTED;
286         else
287                 *val = MTP_PHONE_USB_CONNECTED;
288         return;
289 }
290
291 phone_status_t _util_get_local_usbmode_status(void)
292 {
293         return g_ph_status.usb_mode_state;
294 }
295
296 void _util_set_local_usbmode_status(const phone_status_t val)
297 {
298         g_ph_status.usb_mode_state = val;
299         return;
300 }
301
302 void _util_get_lock_status(phone_status_t *val)
303 {
304         mtp_int32 ret = 0;
305
306         struct stat st;
307 /*
308         mtp_int32 state = 0;
309
310         ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE_READ_ONLY,
311                         &state);
312 */
313         ret = stat("/opt/usr/home", &st);
314
315         if (ret == -1)
316                 *val = MTP_PHONE_LOCK_ON;
317         else
318                 *val = MTP_PHONE_LOCK_OFF;
319         return;
320 }
321
322 phone_status_t _util_get_local_lock_status(void)
323 {
324         return g_ph_status.lock_state;
325 }
326
327 void _util_set_local_lock_status(const phone_status_t val)
328 {
329         g_ph_status.lock_state = val;
330         return;
331 }
332
333 static bool _util_device_external_supported_cb(int storage_id, storage_type_e type,
334         storage_state_e state, const char *path, void *user_data)
335 {
336         char *storage_path = (char *)user_data;
337
338         DBG("storage id: %d, path: %s", storage_id, path);
339
340         if (type == STORAGE_TYPE_EXTERNAL && path != NULL) {
341                 strncpy(storage_path, path, strlen(path));
342                 DBG("external storage path : %s", storage_path);
343         }
344
345         return TRUE;
346 }
347
348 void _util_get_external_path(char *external_path)
349 {
350         int error = STORAGE_ERROR_NONE;
351         error = storage_foreach_device_supported(_util_device_external_supported_cb, external_path);
352
353         if (error != STORAGE_ERROR_NONE) {
354                 ERR("get external storage path Fail");
355                 strncpy(external_path, MTP_EXTERNAL_PATH_CHAR, strlen(MTP_EXTERNAL_PATH_CHAR));
356         }
357 }
358
359 static bool _util_device_internal_supported_cb(int storage_id, storage_type_e type,
360         storage_state_e state, const char *path, void *user_data)
361 {
362         char *storage_path = (char *)user_data;
363
364         DBG("storage id: %d, path: %s", storage_id, path);
365
366         if (type == STORAGE_TYPE_INTERNAL && path != NULL) {
367                 strncpy(storage_path, path, strlen(path));
368                 DBG("internal storage path : %s", storage_path);
369
370                 if (storage_get_root_directory(storage_id, &storage_path) != STORAGE_ERROR_NONE) {
371                         ERR("get internal storage path Fail");
372                         return FALSE;
373                 } else {
374                         DBG("get internal storage path : %s", storage_path);
375                 }
376         }
377
378         return TRUE;
379 }
380
381 void _util_get_internal_path(char *internal_path)
382 {
383         int error = STORAGE_ERROR_NONE;
384         error = storage_foreach_device_supported(_util_device_internal_supported_cb, internal_path);
385
386         if (error != STORAGE_ERROR_NONE) {
387                 ERR("get internal storage path Fail");
388                 strncpy(internal_path, MTP_STORE_PATH_CHAR, strlen(MTP_STORE_PATH_CHAR));
389         }
390 }