Sync code with Tizen 3.0 branch
[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         if (vconf_set_str(VCONFKEY_MTP_SERIAL_NUMBER_STR, serial) == -1) {
108                 ERR("vconf_set Fail for %s\n",
109                                 VCONFKEY_MTP_SERIAL_NUMBER_STR);
110                 g_free(imei_no);
111                 return TRUE;
112         }
113
114         g_free(imei_no);
115         return TRUE;
116 }
117
118 void _util_get_vendor_ext_desc(mtp_char *vendor_ext_desc, mtp_uint32 len)
119 {
120         mtp_int32 ret = SYSTEM_INFO_ERROR_NONE;
121         mtp_char *version = NULL;
122
123         ret_if(len == 0);
124         ret_if(vendor_ext_desc == NULL);
125
126         ret = system_info_get_platform_string(
127                 "http://tizen.org/feature/platform.version", &version);
128
129         if (ret != SYSTEM_INFO_ERROR_NONE) {
130                 ERR("system_info_get_value_string Fail : 0x%X\n", ret);
131                 g_strlcpy(vendor_ext_desc, MTP_VENDOR_EXTENSIONDESC_CHAR, len);
132                 return;
133         }
134         g_snprintf(vendor_ext_desc, len, "%stizen.org:%s; ",
135                         MTP_VENDOR_EXTENSIONDESC_CHAR, version);
136         g_free(version);
137         return;
138 }
139
140 void _util_get_model_name(mtp_char *model_name, mtp_uint32 len)
141 {
142         mtp_int32 ret = SYSTEM_INFO_ERROR_NONE;
143         mtp_char *model = NULL;
144
145         ret_if(len == 0);
146         ret_if(model_name == NULL);
147
148         ret = system_info_get_platform_string(
149                 "http://tizen.org/system/model_name", &model);
150
151         if (ret != SYSTEM_INFO_ERROR_NONE) {
152                 ERR("system_info_get_value_string Fail : 0x%X\n", ret);
153                 g_strlcpy(model_name, MTP_DEFAULT_MODEL_NAME, len);
154                 return;
155         }
156         g_strlcpy(model_name, model, len);
157         g_free(model);
158         return;
159 }
160
161 void _util_get_device_version(mtp_char *device_version, mtp_uint32 len)
162 {
163         mtp_int32 ret = SYSTEM_INFO_ERROR_NONE;
164         mtp_char *version = NULL;
165         mtp_char *build_info = NULL;
166
167         ret_if(len == 0);
168         ret_if(device_version == NULL);
169
170         ret = system_info_get_platform_string(
171                 "http://tizen.org/feature/platform.version", &version);
172
173         if (ret != SYSTEM_INFO_ERROR_NONE) {
174                 ERR("system_info_get_value_string Fail : 0x%X\n", ret);
175                 g_strlcpy(device_version, MTP_DEFAULT_DEVICE_VERSION, len);
176                 return;
177         }
178
179         ret = system_info_get_platform_string(
180                 "http://tizen.org/system/build.string", &build_info);
181
182         if (ret != SYSTEM_INFO_ERROR_NONE) {
183                 ERR("system_info_get_value_string Fail : 0x%X\n", ret);
184                 g_strlcpy(device_version, MTP_DEFAULT_DEVICE_VERSION, len);
185                 g_free(version);
186                 return;
187         }
188         g_snprintf(device_version, len, "TIZEN %s (%s)", version, build_info);
189         g_free(version);
190         g_free(build_info);
191         return;
192 }
193
194 void _util_gen_alt_serial(mtp_char *serial, mtp_uint32 len)
195 {
196         struct timeval st;
197         mtp_char model_name[MTP_MODEL_NAME_LEN_MAX + 1] = { 0 };
198
199         ret_if(len == 0);
200         ret_if(serial == NULL);
201
202         if (gettimeofday(&st, NULL) < 0) {
203                 ERR("gettimeofday Fail");
204                 _util_print_error();
205                 return;
206         }
207         _util_get_model_name(model_name, sizeof(model_name));
208         g_snprintf(serial, len, "%s-%010ld-%011ld", model_name,
209                         st.tv_sec, st.tv_usec);
210
211         if (vconf_set_str(VCONFKEY_MTP_SERIAL_NUMBER_STR, serial) == -1)
212                 ERR("vconf_set Fail %s\n", VCONFKEY_MTP_SERIAL_NUMBER_STR);
213
214         return;
215 }
216
217 void _util_get_usb_status(phone_status_t *val)
218 {
219         mtp_int32 ret = 0;
220         mtp_int32 state = 0;
221
222         ret = vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, &state);
223         if (ret == -1 || state == VCONFKEY_SYSMAN_USB_DISCONNECTED) {
224                 *val = MTP_PHONE_USB_DISCONNECTED;
225                 return;
226         }
227
228         *val = MTP_PHONE_USB_CONNECTED;
229         return;
230 }
231
232 phone_status_t _util_get_local_usb_status(void)
233 {
234         return g_ph_status.usb_state;
235 }
236
237 void _util_set_local_usb_status(const phone_status_t val)
238 {
239         g_ph_status.usb_state = val;
240         return;
241 }
242
243 void _util_get_mmc_status(phone_status_t *val)
244 {
245         mtp_int32 ret = 0;
246         mtp_int32 state = 0;
247
248         ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &state);
249         if (ret == -1 || state !=
250                         VCONFKEY_SYSMAN_MMC_MOUNTED) {
251                 *val = MTP_PHONE_MMC_NONE;
252                 return;
253         }
254
255         *val = MTP_PHONE_MMC_INSERTED;
256         return;
257 }
258
259 phone_status_t _util_get_local_mmc_status(void)
260 {
261         return g_ph_status.mmc_state;
262 }
263
264 void _util_set_local_mmc_status(const phone_status_t val)
265 {
266         g_ph_status.mmc_state = val;
267         return;
268 }
269
270 void _util_get_usbmode_status(phone_status_t *val)
271 {
272         mtp_int32 ret = 0;
273         mtp_int32 state = 0;
274
275         ret = vconf_get_int(VCONFKEY_USB_CUR_MODE,
276                         &state);
277         if (ret < 0) {
278                 *val = MTP_PHONE_USB_MODE_OTHER;
279                 return;
280         }
281
282         if (state == SET_USB_NONE)
283                 *val = MTP_PHONE_USB_DISCONNECTED;
284         else
285                 *val = MTP_PHONE_USB_CONNECTED;
286         return;
287 }
288
289 phone_status_t _util_get_local_usbmode_status(void)
290 {
291         return g_ph_status.usb_mode_state;
292 }
293
294 void _util_set_local_usbmode_status(const phone_status_t val)
295 {
296         g_ph_status.usb_mode_state = val;
297         return;
298 }
299
300 void _util_get_lock_status(phone_status_t *val)
301 {
302         mtp_int32 ret = 0;
303
304         struct stat st;
305 /*
306         mtp_int32 state = 0;
307
308         ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE_READ_ONLY,
309                         &state);
310 */
311         ret = stat("/opt/usr/home", &st);
312
313         if (ret == -1)
314                 *val = MTP_PHONE_LOCK_ON;
315         else
316                 *val = MTP_PHONE_LOCK_OFF;
317         return;
318 }
319
320 phone_status_t _util_get_local_lock_status(void)
321 {
322         return g_ph_status.lock_state;
323 }
324
325 void _util_set_local_lock_status(const phone_status_t val)
326 {
327         g_ph_status.lock_state = val;
328         return;
329 }
330
331 static bool _util_device_external_supported_cb(int storage_id, storage_type_e type,
332         storage_state_e state, const char *path, void *user_data)
333 {
334         char *storage_path = (char *)user_data;
335
336         //DBG("storage id: %d, path: %s", storage_id, path);
337
338         if (type == STORAGE_TYPE_EXTERNAL && path != NULL) {
339                 strncpy(storage_path, path, strlen(path));
340                 //DBG("external storage path : %s", storage_path);
341         }
342
343         return TRUE;
344 }
345
346 void _util_get_external_path(char *external_path)
347 {
348         int error = STORAGE_ERROR_NONE;
349         error = storage_foreach_device_supported(_util_device_external_supported_cb, external_path);
350
351         if (error != STORAGE_ERROR_NONE) {
352                 ERR("get external storage path Fail");
353                 strncpy(external_path, MTP_EXTERNAL_PATH_CHAR, strlen(MTP_EXTERNAL_PATH_CHAR));
354         }
355 }
356
357 static bool _util_device_internal_supported_cb(int storage_id, storage_type_e type,
358         storage_state_e state, const char *path, void *user_data)
359 {
360         char *storage_path = (char *)user_data;
361
362         //DBG("storage id: %d, path: %s", storage_id, path);
363
364         if (type == STORAGE_TYPE_INTERNAL && path != NULL) {
365                 strncpy(storage_path, path, strlen(path));
366                 //DBG("internal storage path : %s", storage_path);
367
368                 if (storage_get_root_directory(storage_id, &storage_path) != STORAGE_ERROR_NONE) {
369                         ERR("get internal storage path Fail");
370                         return FALSE;
371                 } else {
372                         //DBG("get internal storage path : %s", storage_path);
373                 }
374         }
375
376         return TRUE;
377 }
378
379 void _util_get_internal_path(char *internal_path)
380 {
381         int error = STORAGE_ERROR_NONE;
382         error = storage_foreach_device_supported(_util_device_internal_supported_cb, internal_path);
383
384         if (error != STORAGE_ERROR_NONE) {
385                 ERR("get internal storage path Fail");
386                 strncpy(internal_path, MTP_STORE_PATH_CHAR, strlen(MTP_STORE_PATH_CHAR));
387         }
388 }