Fix double free
[platform/core/connectivity/mtp-responder.git] / src / entity / mtp_device.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 #include <unistd.h>
18 #include <glib.h>
19 #include "mtp_support.h"
20 #include "mtp_util.h"
21 #include "ptp_datacodes.h"
22 #include "mtp_device.h"
23 #include "mtp_transport.h"
24 #include "ptp_container.h"
25
26 #define MTP_DEVICE_VERSION_CHAR         "V1.0"
27
28 /*
29  * GLOBAL AND EXTERN VARIABLES
30  */
31 static mtp_device_t g_device = { 0 };
32
33 /*
34  * STATIC VARIABLES
35  */
36 static device_prop_desc_t g_device_props[NUM_DEVICE_PROPERTIES];
37 static mtp_store_t g_store_list[MAX_NUM_DEVICE_STORES];
38 static mtp_uint16 g_device_props_supported[NUM_DEVICE_PROPERTIES];
39
40 static mtp_uint16 g_ops_supported[] = {
41         PTP_OPCODE_GETDEVICEINFO,
42         PTP_OPCODE_OPENSESSION,
43         PTP_OPCODE_CLOSESESSION,
44         PTP_OPCODE_GETSTORAGEIDS,
45         PTP_OPCODE_GETSTORAGEINFO,
46         PTP_OPCODE_GETNUMOBJECTS,
47         PTP_OPCODE_GETOBJECTHANDLES,
48         PTP_OPCODE_GETOBJECTINFO,
49         PTP_OPCODE_GETOBJECT,
50         PTP_OPCODE_DELETEOBJECT,
51         PTP_OPCODE_SENDOBJECTINFO,
52         PTP_OPCODE_SENDOBJECT,
53         PTP_OPCODE_FORMATSTORE,
54         PTP_OPCODE_GETDEVICEPROPDESC,
55         PTP_OPCODE_GETDEVICEPROPVALUE,
56         PTP_OPCODE_SETDEVICEPROPVALUE,
57         PTP_OPCODE_GETPARTIALOBJECT,
58         MTP_OPCODE_GETOBJECTREFERENCES,
59         MTP_OPCODE_SETOBJECTREFERENCES,
60         MTP_OPCODE_GETOBJECTPROPDESC,
61         MTP_OPCODE_GETOBJECTPROPSUPPORTED,
62         MTP_OPCODE_GETOBJECTPROPVALUE,
63         MTP_OPCODE_SETOBJECTPROPVALUE,
64         MTP_OPCODE_GETOBJECTPROPLIST,
65         MTP_OPCODE_SETOBJECTPROPLIST,
66 #ifndef PMP_VER
67         /*PTP_OPCODE_RESETDEVICE,*/
68         PTP_OPCODE_SELFTEST,
69 #ifdef MTP_SUPPORT_SET_PROTECTION
70         PTP_OPCODE_SETOBJECTPROTECTION,
71 #endif /* MTP_SUPPORT_SET_PROTECTION */
72         /*PTP_OPCODE_POWERDOWN,*/
73         PTP_OPCODE_RESETDEVICEPROPVALUE,
74         PTP_OPCODE_MOVEOBJECT,
75         PTP_OPCODE_COPYOBJECT,
76 #ifdef MTP_SUPPORT_INTERDEPENDENTPROP
77         MTP_OPCODE_GETINTERDEPPROPDESC,
78 #endif /*MTP_SUPPORT_INTERDEPENDENTPROP*/
79         MTP_OPCODE_SENDOBJECTPROPLIST,
80         /*PTP_CODE_VENDOR_OP1,*/
81 #endif /*PMP_VER*/
82         MTP_OPCODE_WMP_REPORTACQUIREDCONTENT,
83 };
84
85 static mtp_uint16 g_event_supported[] = {
86         /*PTP_EVENTCODE_CANCELTRANSACTION,*/
87         PTP_EVENTCODE_OBJECTADDED,
88         PTP_EVENTCODE_OBJECTREMOVED,
89         PTP_EVENTCODE_STOREADDED,
90         PTP_EVENTCODE_STOREREMOVED,
91         /* PTP_EVENTCODE_DEVICEPROPCHANGED,
92            PTP_EVENTCODE_OBJECTINFOCHANGED,
93            PTP_EVENTCODE_DEVICEINFOCHANGED,
94            PTP_EVENTCODE_REQUESTOBJECTTRANSFER,
95            PTP_EVENTCODE_STOREFULL,
96            PTP_EVENTCODE_DEVICERESET,
97            PTP_EVENTCODE_STORAGEINFOCHANGED,
98            PTP_EVENTCODE_CAPTURECOMPLETE,
99            PTP_EVENTCODE_UNREPORTEDSTATUS,
100            PTP_EVENTCODE_VENDOREXTENTION1,
101            PTP_EVENTCODE_VENDOREXTENTION2 */
102 };
103
104 static mtp_uint16 g_capture_fmts[] = {
105         /* PTP_FORMATCODE_IMAGE_EXIF */
106         0
107 };
108
109 static mtp_uint16 g_object_fmts[] = {
110         MTP_FMT_3GP,
111         MTP_FMT_MP4,
112         PTP_FMT_MP3,
113         MTP_FMT_WMA,
114         MTP_FMT_WMV,
115         PTP_FMT_IMG_EXIF,
116         PTP_FMT_ASSOCIATION,
117         MTP_FMT_FLAC,
118         PTP_FMT_UNDEF,
119 #ifndef PMP_VER
120         PTP_FMT_IMG_GIF,
121         PTP_FMT_IMG_BMP,
122         /* PTP_FORMATCODE_IMAGE_JFIF, */
123         PTP_FMT_IMG_PNG,
124         PTP_FMT_WAVE,
125         PTP_FMT_AVI,
126         PTP_FMT_MPEG,
127         PTP_FMT_ASF,
128         /* MTP_FORMATCODE_WINDOWS_IMAGE_FORMAT,
129            MTP_FORMATCODE_UNDEFINED_AUDIO,
130            MTP_FORMATCODE_UNDEFINED_VIDEO,
131            MTP_FORMATCODE_UNDEFINED_COLLECTION,
132            MTP_FORMATCODE_ABSTRACT_MULTIMEDIA_ALBUM,
133            MTP_FORMATCODE_ABSTRACT_IMAGE_ALBUM,
134            MTP_FORMATCODE_ABSTRACT_VIDEO_ALBUM,
135            MTP_FORMATCODE_ABSTRACT_CONTACT_GROUP,
136            MTP_FORMATCODE_UNDEFINED_DOCUMENT,
137            MTP_FORMATCODE_ABSTRACT_DOCUMENT,
138            MTP_FORMATCODE_UNDEFINED_MESSAGE,
139            MTP_FORMATCODE_ABSTRACT_MESSAGE,
140            MTP_FORMATCODE_UNDEFINED_CALENDAR_ITEM,
141            MTP_FORMATCODE_ABSTRACT_CALENDAR_ITEM,
142            MTP_FORMATCODE_VCALENDAR1,
143            MTP_FORMATCODE_UNDEFINED_WINDOWS_EXECUTABLE,*/
144 #endif /*PMP_VER*/
145         MTP_FMT_ABSTRACT_AUDIO_ALBUM,
146         /* MTP_FORMATCODE_UNDEFINED_FIRMWARE */
147 };
148
149 /*
150  * STATIC FUNCTIONS
151  */
152 static void __init_device_info(void);
153 static mtp_bool __init_device_props(void);
154 static mtp_err_t __clear_store_data(mtp_uint32 store_id);
155 static mtp_bool __remove_store_from_device(store_type_t store_type);
156 static mtp_bool __add_store_to_device(store_type_t store_type);
157
158 /*
159  * FUNCTIONS
160  */
161
162 /*
163  * static void __device_init_device_info()
164  * This function initializes MTP device information
165  *@return       none
166  */
167 static void __init_device_info(void)
168 {
169         mtp_int32 ii;
170         device_info_t *info = &(g_device.device_info);
171         mtp_char model_name[MTP_MODEL_NAME_LEN_MAX + 1] = { 0 };
172         mtp_char device_version[MAX_PTP_STRING_CHARS + 1] = { 0 };
173         mtp_char vendor_ext_desc[MAX_PTP_STRING_CHARS + 1] = { 0 };
174         mtp_char serial_no[MTP_SERIAL_LEN_MAX + 1] = { 0 };
175         mtp_wchar wtemp[MAX_PTP_STRING_CHARS + 1] = { 0 };
176
177         info->ops_supported = g_ops_supported;
178         info->events_supported = g_event_supported;
179         info->capture_fmts = g_capture_fmts;
180         info->object_fmts = g_object_fmts;
181         info->device_prop_supported = g_device_props_supported;
182         info->std_version = MTP_STANDARD_VERSION;
183         info->vendor_extn_id = MTP_VENDOR_EXTN_ID;
184         info->vendor_extn_version = MTP_VENDOR_EXTN_VERSION;
185         info->functional_mode = PTP_FUNCTIONMODE_SLEEP;
186
187         _prop_init_ptpstring(&(info->vendor_extn_desc));
188         _util_get_vendor_ext_desc(vendor_ext_desc, sizeof(vendor_ext_desc));
189         _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ, vendor_ext_desc);
190         _prop_copy_char_to_ptpstring(&(info->vendor_extn_desc), wtemp, WCHAR_TYPE);
191
192         for (ii = 0; ii < NUM_DEVICE_PROPERTIES; ii++) {
193                 info->device_prop_supported[ii] =
194                         g_device.device_prop_list[ii].propinfo.prop_code;
195         }
196
197         _prop_init_ptpstring(&(info->manufacturer));
198         _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ, MTP_MANUFACTURER_CHAR);
199         _prop_copy_char_to_ptpstring(&(info->manufacturer), wtemp, WCHAR_TYPE);
200
201         _prop_init_ptpstring(&(info->model));
202         _util_get_model_name(model_name, sizeof(model_name));
203         _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ, model_name);
204         _prop_copy_char_to_ptpstring(&(info->model), wtemp, WCHAR_TYPE);
205
206         _prop_init_ptpstring(&(info->device_version));
207         _util_get_device_version(device_version, sizeof(device_version));
208         _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ, device_version);
209         _prop_copy_char_to_ptpstring(&(info->device_version), wtemp, WCHAR_TYPE);
210
211         _prop_init_ptpstring(&(info->serial_no));
212         if (FALSE == _util_get_serial(serial_no, sizeof(serial_no))) {
213                 ERR("_util_get_serial() Fail");
214                 _util_gen_alt_serial(serial_no, sizeof(serial_no));
215         }
216         _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ, serial_no);
217         _prop_copy_char_to_ptpstring(&(info->serial_no), wtemp, WCHAR_TYPE);
218
219         return;
220 }
221
222 /*
223  * static mtp_bool __device_init_device_props()
224  * this function will initialise all the properties of the device.
225  * @return      TRUE if success, otherwise FALSE.
226  */
227 static mtp_bool __init_device_props()
228 {
229         static mtp_bool already_init = FALSE;
230
231         device_prop_desc_t *dev_prop = NULL;
232         mtp_uint16 i = 0;
233         ptp_string_t tmp = { 0 };
234         mtp_uint32 default_val;
235
236         if (TRUE == already_init) {
237                 ERR("Already initialized. just return...");
238                 return TRUE;
239         }
240
241         g_device.device_prop_list = g_device_props;
242 #ifdef MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL
243         /*
244          * Battery level from 0 to 100, with step of 10,
245          * won't change after a reset
246          */
247         dev_prop = &(g_device.device_prop_list[i]);
248         _prop_init_device_property_desc(dev_prop, PTP_PROPERTYCODE_BATTERYLEVEL,
249                         PTP_DATATYPE_UINT8, PTP_PROPGETSET_GETONLY, RANGE_FORM);
250         {
251                 mtp_int32 batt_level = 0;
252
253                 batt_level = _util_get_battery_level();
254                 _prop_set_range_integer(&(dev_prop->propinfo), 0, 100, 5);
255                 _prop_set_current_integer(dev_prop, batt_level);
256                 default_val = 100;
257                 _prop_set_default_integer(&(dev_prop->propinfo),
258                                 (mtp_uchar *)&default_val);
259         }
260         i++;
261 #endif /*MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL*/
262
263         /* Synchronization Partner */
264         dev_prop = &(g_device.device_prop_list[i]);
265         _prop_init_device_property_desc(dev_prop,
266                         MTP_PROPERTYCODE_SYNCHRONIZATIONPARTNER,
267                         PTP_DATATYPE_STRING, PTP_PROPGETSET_GETSET, NONE);
268 #ifdef MTP_USE_INFORMATION_REGISTRY
269         {
270                 mtp_char *sync_ptr = NULL;
271                 mtp_wchar wtemp[MTP_MAX_REG_STRING + 1] = { 0 };
272                 mtp_wchar wpartner[MTP_MAX_REG_STRING + 1] = { 0 };
273
274                 sync_ptr = _device_get_sync_partner();
275                 if (sync_ptr == NULL) {
276                         _util_utf8_to_utf16(wtemp, sizeof(wpartner) / WCHAR_SIZ,
277                                         MTP_DEV_PROPERTY_SYNCPARTNER);
278                 } else {
279                         _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ,
280                                         sync_ptr);
281                 }
282
283                 _util_utf8_to_utf16(wpartner, sizeof(wpartner) / WCHAR_SIZ,
284                                 MTP_DEV_PROPERTY_SYNCPARTNER);
285                 _prop_copy_char_to_ptpstring(&tmp, wtemp, WCHAR_TYPE);
286                 _prop_set_current_string(dev_prop, &tmp);
287                 _prop_set_default_string(&(dev_prop->propinfo), wpartner);
288                 g_free(sync_ptr);
289         }
290 #else/*MTP_USE_INFORMATION_REGISTRY*/
291         {
292                 mtp_wchar wtemp[MTP_MAX_REG_STRING + 1] = { 0 };
293
294                 _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ,
295                                 MTP_DEV_PROPERTY_SYNCPARTNER);
296                 _prop_copy_char_to_ptpstring(&tmp, wtemp, WCHAR_TYPE);
297                 _prop_set_current_string(dev_prop, &tmp);
298                 _prop_set_default_string(&(dev_prop->propinfo), wtemp);
299         }
300 #endif/*MTP_USE_INFORMATION_REGISTRY*/
301         i++;
302
303         /* Device Friendly Name */
304         dev_prop = &(g_device.device_prop_list[i]);
305         _prop_init_device_property_desc(dev_prop, MTP_PROPERTYCODE_DEVICEFRIENDLYNAME,
306                         PTP_DATATYPE_STRING, PTP_PROPGETSET_GETONLY, NONE);
307 #ifdef MTP_USE_INFORMATION_REGISTRY
308         {
309                 mtp_char *dev_ptr = NULL;
310                 mtp_wchar wmodel[MTP_MAX_REG_STRING + 1] = { 0 };
311
312                 dev_ptr = _device_get_device_name();
313                 if (dev_ptr == NULL) {
314                         ERR("_device_get_device_name() Fail");
315                         _util_utf8_to_utf16(wmodel, sizeof(wmodel) / WCHAR_SIZ,
316                                         MTP_DEV_PROPERTY_FRIENDLYNAME);
317                 } else {
318                         _util_utf8_to_utf16(wmodel, sizeof(wmodel) / WCHAR_SIZ,
319                                         dev_ptr);
320                         g_free(dev_ptr);
321                 }
322                 _prop_copy_char_to_ptpstring(&tmp, wmodel, WCHAR_TYPE);
323                 _prop_set_current_string(dev_prop, &tmp);
324                 _prop_set_default_string(&(dev_prop->propinfo), wmodel);
325         }
326 #else /*MTP_USE_INFORMATION_REGISTRY*/
327         {
328                 mtp_wchar wmodel[MTP_MAX_REG_STRING + 1] = { 0 };
329
330                 _util_utf8_to_utf16(wmodel, sizeof(wmodel) / WCHAR_SIZ,
331                                 MTP_DEV_PROPERTY_FRIENDLYNAME);
332                 _prop_copy_char_to_ptpstring(&tmp, wmodel, WCHAR_TYPE);
333                 _prop_set_current_string(dev_prop, &tmp);
334                 _prop_set_default_string(&(dev_prop->propinfo), wmodel);
335         }
336 #endif /*MTP_USE_INFORMATION_REGISTRY*/
337         i++;
338
339         /* supported formats ordered */
340         dev_prop = &(g_device.device_prop_list[i]);
341         _prop_init_device_property_desc(dev_prop,
342                         MTP_PROPERTYCODE_SUPPORTEDFORMATSORDERED,
343                         PTP_DATATYPE_UINT8, PTP_PROPGETSET_GETONLY, NONE);
344         {
345                 default_val = 1;
346                 _prop_set_default_integer(&(dev_prop->propinfo), (mtp_uchar *) &default_val);
347                 _prop_set_current_integer(dev_prop, (mtp_uint32)1);
348         }
349         i++;
350
351 #ifdef MTP_SUPPORT_DEVICE_CLASS
352         /* Perceived Device Type */
353         dev_prop = &(g_device.device_prop_list[i]);
354         _prop_init_device_property_desc(dev_prop,
355                         MTP_PROPERTYCODE_PERCEIVEDDEVICETYPE,
356                         PTP_DATATYPE_UINT32, PTP_PROPGETSET_GETONLY, NONE);
357         {
358                 /*
359                  * 0:generic, 1: DSC, 2: Media Player, 3: mobile,
360                  * 4: digital video camera, 5: PDA, 6: audio recoder
361                  */
362                 default_val = 0x3;
363                 _prop_set_default_integer(&(dev_prop->propinfo), (mtp_uchar *)&default_val);
364                 _prop_set_current_integer(dev_prop, (mtp_uint32)0x3);
365         }
366         i++;
367 #endif /*MTP_SUPPORT_DEVICE_CLASS*/
368
369         dev_prop = &(g_device.device_prop_list[i]);
370         _prop_init_device_property_desc(dev_prop, MTP_PROPERTYCODE_DEVICEICON,
371                         PTP_DATATYPE_AUINT8, PTP_PROPGETSET_GETONLY, NONE);
372         i++;
373
374         already_init = TRUE;
375
376         return TRUE;
377 }
378
379 void _init_mtp_device(void)
380 {
381         static mtp_bool already_init = FALSE;
382
383         if (TRUE == already_init) {
384                 DBG("Device is already initialized");
385                 return;
386         }
387
388         already_init = TRUE;
389
390         g_device.status = DEVICE_STATUSOK;
391         g_device.phase = DEVICE_PHASE_IDLE;
392         g_device.num_stores = 0;
393         g_device.store_list = g_store_list;
394         g_device.default_store_id = MTP_INTERNAL_STORE_ID;
395         g_device.default_hparent = PTP_OBJECTHANDLE_ROOT;
396
397         __init_device_props();
398         _prop_build_supp_props_mp3();
399         _prop_build_supp_props_wmv();
400         _prop_build_supp_props_wma();
401         _prop_build_supp_props_album();
402         _prop_build_supp_props_default();
403         __init_device_info();
404
405         return;
406 }
407
408 /* LCOV_EXCL_START */
409 mtp_uint32 _get_device_info_size(void)
410 {
411         mtp_uint32 size = 0;
412         device_info_t *info = &(g_device.device_info);
413
414         size += sizeof(info->std_version);
415         size += sizeof(info->vendor_extn_id);
416         size += sizeof(info->vendor_extn_version);
417         size += _prop_size_ptpstring(&(info->vendor_extn_desc));
418         size += sizeof(info->functional_mode);
419         size += sizeof(mtp_uint32);     /*for number of supported ops*/
420         size += sizeof(g_ops_supported);
421         size += sizeof(mtp_uint32);
422         size += sizeof(g_event_supported);
423         size += sizeof(mtp_uint32);
424         size += NUM_DEVICE_PROPERTIES * sizeof(mtp_uint16);
425         size += sizeof(mtp_uint32);
426         size += sizeof(g_capture_fmts);
427         size += sizeof(mtp_uint32);
428         size += sizeof(g_object_fmts);
429         size += _prop_size_ptpstring(&(info->manufacturer));
430         size += _prop_size_ptpstring(&(info->model));
431         size += _prop_size_ptpstring(&(info->device_version));
432         size += _prop_size_ptpstring(&(info->serial_no));
433
434         return size;
435 }
436
437 mtp_uint32 _pack_device_info(mtp_uchar *buf, mtp_uint32 buf_sz)
438 {
439         mtp_uint16 ii = 0;
440         mtp_uchar *ptr = buf;
441         mtp_uint32 count = 0;
442         device_info_t *info = &(g_device.device_info);
443
444         retv_if(NULL == buf, 0);
445
446         if (buf_sz < _get_device_info_size()) {
447                 ERR("buffer size [%d] is less than device_info Size\n", buf_sz);
448                 return 0;
449         }
450
451         memcpy(ptr, &info->std_version, sizeof(info->std_version));
452 #ifdef __BIG_ENDIAN__
453         _util_conv_byte_order(ptr, sizeof(info->std_version));
454 #endif /*__BIG_ENDIAN__*/
455         ptr += sizeof(info->std_version);
456
457         memcpy(ptr, &info->vendor_extn_id, sizeof(info->vendor_extn_id));
458 #ifdef __BIG_ENDIAN__
459         _util_conv_byte_order(ptr, sizeof(info->vendor_extn_id));
460 #endif /*__BIG_ENDIAN__*/
461         ptr += sizeof(info->vendor_extn_id);
462
463         memcpy(ptr, &info->vendor_extn_version,
464                         sizeof(info->vendor_extn_version));
465 #ifdef __BIG_ENDIAN__
466         _util_conv_byte_order(ptr, sizeof(info->vendor_extn_version));
467 #endif /*__BIG_ENDIAN__*/
468         ptr += sizeof(info->vendor_extn_version);
469
470         ptr += _prop_pack_ptpstring(&(info->vendor_extn_desc), ptr,
471                         _prop_size_ptpstring(&(info->vendor_extn_desc)));
472
473         memcpy(ptr, &info->functional_mode, sizeof(info->functional_mode));
474 #ifdef __BIG_ENDIAN__
475         _util_conv_byte_order(ptr, sizeof(info->functional_mode));
476 #endif /*__BIG_ENDIAN__*/
477         ptr += sizeof(info->functional_mode);
478
479         count = (sizeof(g_ops_supported) / sizeof(mtp_uint16));
480         memcpy(ptr, &count, sizeof(count));
481
482 #ifdef __BIG_ENDIAN__
483         _util_conv_byte_order(ptr, sizeof(count));
484 #endif /*__BIG_ENDIAN__*/
485         ptr += sizeof(count);
486         for (ii = 0; ii < count; ii++) {
487                 memcpy(ptr, (void *)&(info->ops_supported[ii]),
488                                 sizeof(mtp_uint16));
489 #ifdef __BIG_ENDIAN__
490                 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
491 #endif /*__BIG_ENDIAN__*/
492                 ptr += sizeof(mtp_uint16);
493         }
494
495         count = (sizeof(g_event_supported) / sizeof(mtp_uint16));
496         memcpy(ptr, &count, sizeof(count));
497
498 #ifdef __BIG_ENDIAN__
499         _util_conv_byte_order(ptr, sizeof(count));
500 #endif /*__BIG_ENDIAN__*/
501         ptr += sizeof(count);
502         for (ii = 0; ii < count; ii++) {
503                 memcpy(ptr, (void *)&(info->events_supported[ii]),
504                                 sizeof(mtp_uint16));
505 #ifdef __BIG_ENDIAN__
506                 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
507 #endif /*__BIG_ENDIAN__*/
508                 ptr += sizeof(mtp_uint16);
509         }
510
511         count = NUM_DEVICE_PROPERTIES;
512         memcpy(ptr, &count, sizeof(count));
513 #ifdef __BIG_ENDIAN__
514         _util_conv_byte_order(ptr, sizeof(count));
515 #endif /*__BIG_ENDIAN__*/
516         ptr += sizeof(count);
517         for (ii = 0; ii < NUM_DEVICE_PROPERTIES; ii++) {
518                 memcpy(ptr, (void *)&(info->device_prop_supported[ii]),
519                                 sizeof(mtp_uint16));
520 #ifdef __BIG_ENDIAN__
521                 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
522 #endif /*__BIG_ENDIAN__*/
523                 ptr += sizeof(mtp_uint16);
524         }
525
526         count = (sizeof(g_capture_fmts) / sizeof(mtp_uint16));
527         memcpy(ptr, &count, sizeof(count));
528 #ifdef __BIG_ENDIAN__
529         _util_conv_byte_order(ptr, sizeof(count));
530 #endif /*__BIG_ENDIAN__*/
531         ptr += sizeof(count);
532
533         for (ii = 0; ii < count; ii++) {
534                 memcpy(ptr, (void *)&(info->capture_fmts[ii]),
535                                 sizeof(mtp_uint16));
536 #ifdef __BIG_ENDIAN__
537                 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
538 #endif /*__BIG_ENDIAN__*/
539                 ptr += sizeof(mtp_uint16);
540         }
541
542         count = (sizeof(g_object_fmts) / sizeof(mtp_uint16));
543         memcpy(ptr, &count, sizeof(count));
544 #ifdef __BIG_ENDIAN__
545         _util_conv_byte_order(ptr, sizeof(count));
546 #endif /*__BIG_ENDIAN__*/
547         ptr += sizeof(count);
548         for (ii = 0; ii < count; ii++) {
549                 memcpy(ptr, (void *)&(info->object_fmts[ii]),
550                                 sizeof(mtp_uint16));
551 #ifdef __BIG_ENDIAN__
552                 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
553 #endif /*__BIG_ENDIAN__*/
554                 ptr += sizeof(mtp_uint16);
555         }
556
557         ptr += _prop_pack_ptpstring(&(info->manufacturer), ptr,
558                         _prop_size_ptpstring(&(info->manufacturer)));
559
560         ptr += _prop_pack_ptpstring(&(info->model), ptr,
561                         _prop_size_ptpstring(&(info->model)));
562
563         ptr += _prop_pack_ptpstring(&(info->device_version), ptr,
564                         _prop_size_ptpstring(&(info->device_version)));
565
566         ptr += _prop_pack_ptpstring(&(info->serial_no), ptr,
567                         _prop_size_ptpstring(&(info->serial_no)));
568
569         return (mtp_uint32)(ptr - buf);
570 }
571
572 void _reset_mtp_device(void)
573 {
574         _transport_set_control_event(0);
575         _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
576
577         /* resets device state to ok/Ready */
578         /* reset device phase to idle */
579
580         g_device.status = DEVICE_STATUSOK;
581         g_device.phase = DEVICE_PHASE_IDLE;
582         return;
583 }
584 /* LCOV_EXCL_STOP */
585
586 device_prop_desc_t *_device_get_device_property(mtp_uint32 prop_code)
587 {
588         mtp_uint16 ii = 0;
589
590         for (ii = 0; ii < NUM_DEVICE_PROPERTIES; ii++) {
591                 if (g_device.device_prop_list[ii].propinfo.prop_code == prop_code)
592                         return &(g_device.device_prop_list[ii]);
593         }
594         return NULL;
595 }
596
597 /*
598  * static mtp_bool _device_add_store(store_type_t store_type)
599  * This function will add the store to the device.
600  * @param[in]   store_type      Store Number
601  * @return      TRUE if success, otherwise FALSE.
602  */
603 static mtp_bool __add_store_to_device(store_type_t store_type)
604 {
605         mtp_char *storage_path = NULL;
606         mtp_uint32 store_id = 0;
607         file_attr_t attrs = { 0, };
608         char sto_path[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
609
610         switch (store_type) {
611         case MTP_STORAGE_INTERNAL:
612                 _util_get_internal_path(sto_path);
613                 storage_path = (mtp_char *)sto_path;
614                 store_id = MTP_INTERNAL_STORE_ID;
615                 break;
616         case MTP_STORAGE_EXTERNAL:
617                 _util_get_external_path(sto_path);
618                 storage_path = (mtp_char *)sto_path;
619                 store_id = MTP_EXTERNAL_STORE_ID;
620                 break;
621         default:
622                 ERR("Unknown Storage [%d]\n", store_id);
623                 return FALSE;
624         }
625
626         if (FALSE == _util_get_file_attrs(storage_path, &attrs)) {
627                 ERR("_util_get_file_attrs() Fail");
628                 return FALSE;
629         }
630
631         if (MTP_FILE_ATTR_INVALID == attrs.attribute ||
632                         !(attrs.attribute & MTP_FILE_ATTR_MODE_DIR)) {
633                 ERR("attribute [0x%x], dir[0x%x]\n",
634                                 attrs.attribute, MTP_FILE_ATTR_MODE_DIR);
635                 ERR("Storage [%d]\n", store_id);
636                 return FALSE;
637         }
638
639
640         if (g_device.num_stores + 1 > MAX_NUM_DEVICE_STORES) {
641                 ERR("reached to max [%d]\n", MAX_NUM_DEVICE_STORES);
642                 return FALSE;
643         }
644
645         if (FALSE == _entity_init_mtp_store(&(g_device.store_list[g_device.num_stores]),
646                                 store_id, storage_path)) {
647                 ERR("_entity_init_mtp_store() Fail");
648                 return FALSE;
649         }
650
651         g_device.num_stores++;
652         g_device.is_mounted[store_type] = TRUE;
653
654         return TRUE;
655 }
656
657 /*
658  * static mtp_bool _device_remove_store(store_type_t store_type)
659  * This function will remove the store from the device.
660  * @param[in]   store_type      Store type
661  * @return      TRUE if success, otherwise FALSE.
662  */
663 /* LCOV_EXCL_START */
664 static mtp_bool __remove_store_from_device(store_type_t store_type)
665 {
666         mtp_int32 ii = 0;
667         mtp_device_t *device = &g_device;
668         mtp_store_t *store = NULL;
669         mtp_uint32 store_id = 0;
670
671         switch (store_type) {
672         case MTP_STORAGE_INTERNAL:
673                 store_id = MTP_INTERNAL_STORE_ID;
674                 break;
675         case MTP_STORAGE_EXTERNAL:
676                 store_id = MTP_EXTERNAL_STORE_ID;
677                 break;
678         default:
679                 ERR("Unknown Storage [%d]\n", store_type);
680                 return FALSE;
681         }
682
683         for (ii = 0; ii < device->num_stores; ii++) {
684                 store = &(device->store_list[ii]);
685                 if (store->store_id == store_id) {
686                         __clear_store_data(store->store_id);
687                         device->is_mounted[store_type] = FALSE;
688                         break;
689                 }
690         }
691
692         return TRUE;
693 }
694
695 mtp_bool _device_is_store_mounted(mtp_int32 store_type)
696 {
697         if (store_type < MTP_STORAGE_INTERNAL ||
698                         store_type >= MTP_STORAGE_ALL) {
699                 ERR("unknown storage(%d)\n", store_type);
700                 return FALSE;
701         }
702
703         return g_device.is_mounted[store_type];
704 }
705 /* LCOV_EXCL_STOP */
706
707 mtp_bool _device_install_storage(mtp_int32 type)
708 {
709         mtp_int32 int_status = TRUE;
710         mtp_int32 ext_status = TRUE;
711         mtp_bool mounted;
712         mtp_bool lock_status;
713
714         switch (type) {
715         case MTP_ADDREM_AUTO:
716                 DBG(" case MTP_ADDREM_AUTO:");
717
718                 lock_status = _util_get_local_lock_status();
719                 if (lock_status == MTP_PHONE_LOCK_OFF) {
720                         /* LCOV_EXCL_START */
721                         int_status = _device_is_store_mounted(MTP_STORAGE_INTERNAL);
722                         if (int_status == FALSE)
723                                 __add_store_to_device(MTP_STORAGE_INTERNAL);
724                         /* LCOV_EXCL_STOP */
725                 }
726
727                 mounted = _util_get_local_mmc_status();
728                 if (mounted == MTP_PHONE_MMC_INSERTED) {
729
730                         /* LCOV_EXCL_START */
731                         ext_status =
732                                 _device_is_store_mounted(MTP_STORAGE_EXTERNAL);
733                         if (ext_status == FALSE)
734                                 __add_store_to_device(MTP_STORAGE_EXTERNAL);
735                         /* LCOV_EXCL_STOP */
736                 }
737                 break;
738
739         case MTP_ADDREM_INTERNAL:
740                 DBG("case MTP_ADDREM_INTERNAL:");
741                 if (MTP_PHONE_LOCK_OFF != _util_get_local_lock_status())
742                         break;
743                 if (FALSE == _device_is_store_mounted(MTP_STORAGE_INTERNAL))
744                         __add_store_to_device(MTP_STORAGE_INTERNAL);
745                 break;
746
747         case MTP_ADDREM_EXTERNAL:
748                 DBG(" case MTP_ADDREM_EXTERNAL:");
749                 if (MTP_PHONE_MMC_INSERTED != _util_get_local_mmc_status())
750                         break;
751                 /* LCOV_EXCL_START */
752                 mounted = _device_is_store_mounted(MTP_STORAGE_EXTERNAL);
753                 if (mounted == FALSE) {
754                         if (__add_store_to_device(MTP_STORAGE_EXTERNAL) == FALSE) {
755                                 ERR("__add_store_to_device() Fail");
756                                 return FALSE;
757                         }
758                 }
759                 /* LCOV_EXCL_STOP */
760                 break;
761
762         case MTP_ADDREM_ALL:
763                 DBG(" case MTP_ADDREM_ALL:");
764                 __add_store_to_device(MTP_STORAGE_INTERNAL);
765                 __add_store_to_device(MTP_STORAGE_EXTERNAL);
766                 break;
767
768         default:
769                 ERR("_device_install_storage : unknown type [%d]\n", type);
770                 break;
771         }
772
773         return TRUE;
774 }
775
776 /* LCOV_EXCL_START */
777 mtp_bool _device_uninstall_storage(mtp_int32 type)
778 {
779         switch (type) {
780         case MTP_ADDREM_AUTO:
781                 if (TRUE == _device_is_store_mounted(MTP_STORAGE_EXTERNAL))
782                         __remove_store_from_device(MTP_STORAGE_EXTERNAL);
783                 if (TRUE == _device_is_store_mounted(MTP_STORAGE_INTERNAL))
784                         __remove_store_from_device(MTP_STORAGE_INTERNAL);
785                 break;
786         case MTP_ADDREM_INTERNAL:
787                 if (TRUE == _device_is_store_mounted(MTP_STORAGE_INTERNAL))
788                         __remove_store_from_device(MTP_STORAGE_INTERNAL);
789                 break;
790         case MTP_ADDREM_EXTERNAL:
791                 if (TRUE == _device_is_store_mounted(MTP_STORAGE_EXTERNAL))
792                         __remove_store_from_device(MTP_STORAGE_EXTERNAL);
793                 break;
794         case MTP_ADDREM_ALL:
795                 __remove_store_from_device(MTP_STORAGE_INTERNAL);
796                 __remove_store_from_device(MTP_STORAGE_EXTERNAL);
797                 break;
798         default:
799                 ERR("unknown mode [%d]\n", type);
800                 break;
801         }
802
803         return TRUE;
804 }
805
806 /*
807  * static mtp_err_t __device_clear_store_data(mtp_uint32 store_id)
808  * This function removes the storage entry.
809  * @param[in]   store_id        Specifies the storage id to remove
810  * @return      This function returns MTP_ERROR_NONE on success
811  *              ERROR number on failure.
812  */
813 static mtp_err_t __clear_store_data(mtp_uint32 store_id)
814 {
815         mtp_uint16 idx = 0;
816         mtp_store_t *store = NULL;
817         mtp_uint32 count = g_device.num_stores;
818
819         for (idx = 0; idx < count; idx++) {
820                 if (g_device.store_list[idx].store_id == store_id) {
821
822                         _entity_destroy_mtp_store(&(g_device.store_list[idx]));
823
824                         store = &(g_device.store_list[idx]);
825                         store->store_id = 0;
826                         store->is_hidden = FALSE;
827                         g_free(store->root_path);
828                         store->root_path = NULL;
829
830                         for (; idx < count - 1; idx++) {
831                                 _entity_copy_store_data(&(g_device.store_list[idx]),
832                                                 &(g_device.store_list[idx + 1]));
833                         }
834
835                         g_device.store_list[count - 1].store_id = 0;
836                         g_device.store_list[count - 1].root_path = NULL;
837                         g_device.store_list[count - 1].is_hidden = FALSE;
838                         _util_init_list(&(g_device.store_list[count - 1].obj_list));
839
840                         /*Initialize the destroyed store*/
841                         g_device.num_stores--;
842                         return MTP_ERROR_NONE;
843                 }
844         }
845         return MTP_ERROR_GENERAL;
846 }
847 /* LCOV_EXCL_STOP */
848
849 mtp_store_t *_device_get_store(mtp_uint32 store_id)
850 {
851         mtp_int32 ii = 0;
852         mtp_store_t *store = NULL;
853
854         for (ii = 0; ii < g_device.num_stores; ii++) {
855
856                 store = &(g_device.store_list[ii]);
857                 if (store->store_id == store_id)
858                         return store;
859         }
860         return NULL;
861 }
862
863 mtp_uint32 _device_get_store_ids(ptp_array_t *store_ids)
864 {
865         mtp_store_t *store = NULL;
866         mtp_int32 ii = 0;
867
868         for (ii = g_device.num_stores - 1; ii >= 0; ii--) {
869
870                 store = &(g_device.store_list[ii]);
871                 if ((store != NULL) && (FALSE == store->is_hidden))
872                         _prop_append_ele_ptparray(store_ids, store->store_id);
873         }
874         return store_ids->num_ele;
875 }
876
877 mtp_uint32 _device_get_num_objects(mtp_uint32 store_id)
878 {
879         mtp_uint32 num_objs = 0;
880         mtp_store_t *store = NULL;
881         mtp_uint32 ii = 0;
882
883         for (ii = 0; ii < g_device.num_stores; ii++) {
884
885                 store = &(g_device.store_list[ii]);
886                 if ((store->store_id == store_id) ||
887                                 (store_id == PTP_STORAGEID_ALL)) {
888                         num_objs += store->obj_list.nnodes;
889                 }
890         }
891
892         return num_objs;
893 }
894
895 /* LCOV_EXCL_START */
896 mtp_uint32 _device_get_num_objects_with_format(mtp_uint32 store_id,
897                 mtp_uint32 format)
898 {
899         mtp_uint32 num_objs = 0;
900         mtp_store_t *store = NULL;
901         mtp_uint32 ii = 0;
902
903         for (ii = 0; ii < g_device.num_stores; ii++) {
904
905                 store = &(g_device.store_list[ii]);
906                 if ((store->store_id != store_id) &&
907                                 (store_id != PTP_STORAGEID_ALL)) {
908                         continue;
909                 }
910                 num_objs += _entity_get_num_object_with_same_format(store,
911                                 format);
912         }
913
914         return num_objs;
915 }
916 /* LCOV_EXCL_STOP */
917
918 mtp_obj_t *_device_get_object_with_handle(mtp_uint32 obj_handle)
919 {
920         mtp_int32 ii = 0;
921         mtp_obj_t *obj = NULL;
922         mtp_store_t *store = NULL;
923
924         for (ii = 0; ii < g_device.num_stores; ii++) {
925
926                 store = &(g_device.store_list[ii]);
927                 obj = _entity_get_object_from_store(store, obj_handle);
928                 if (obj == NULL)
929                         continue;
930                 break;
931         }
932         return obj;
933 }
934
935 /* LCOV_EXCL_START */
936 mtp_obj_t* _device_get_object_with_path(mtp_char *full_path)
937 {
938         mtp_int32 i = 0;
939         mtp_obj_t *obj = NULL;
940         mtp_store_t *store = NULL;
941
942         retv_if(NULL == full_path, NULL);
943
944         for (i = 0; i < g_device.num_stores; i++) {
945                 store = &(g_device.store_list[i]);
946                 obj = _entity_get_object_from_store_by_path(store, full_path);
947                 if (obj == NULL)
948                         continue;
949                 break;
950         }
951         return obj;
952 }
953 /* LCOV_EXCL_STOP */
954
955 mtp_uint16 _device_delete_object(mtp_uint32 obj_handle, mtp_uint32 fmt)
956 {
957         mtp_uint32 ii = 0;
958         mtp_uint16 response = PTP_RESPONSE_OK;
959         mtp_store_t *store = NULL;
960         mtp_bool all_del = TRUE;
961         mtp_bool atlst_one = FALSE;
962
963         if (PTP_OBJECTHANDLE_ALL != obj_handle) {
964                 store = _device_get_store_containing_obj(obj_handle);
965                 if (store == NULL) {
966                         response = PTP_RESPONSE_INVALID_OBJ_HANDLE;
967                 } else {
968                 /* LCOV_EXCL_START */
969                         response = _entity_delete_obj_mtp_store(store,
970                                         obj_handle, fmt, TRUE);
971                 }
972                 return response;
973         }
974
975         for (ii = 0; ii < g_device.num_stores; ii++) {
976                 store = &(g_device.store_list[ii]);
977                 response = _entity_delete_obj_mtp_store(store, obj_handle,
978                                 fmt, TRUE);
979                 switch (response) {
980                 case PTP_RESPONSE_STORE_READONLY:
981                         all_del = FALSE;
982                         break;
983                 case PTP_RESPONSE_PARTIAL_DELETION:
984                         all_del = FALSE;
985                         atlst_one = TRUE;
986                         break;
987                 case PTP_RESPONSE_OBJ_WRITEPROTECTED:
988                 case PTP_RESPONSE_ACCESSDENIED:
989                         all_del = FALSE;
990                         break;
991                 case PTP_RESPONSE_OK:
992                 default:
993                         atlst_one = TRUE;
994                         break;
995                 }
996         }
997
998         if (all_del)
999                 response = PTP_RESPONSE_OK;
1000         else if (atlst_one)
1001                 response = PTP_RESPONSE_PARTIAL_DELETION;
1002
1003         return response;
1004         /* LCOV_EXCL_STOP */
1005 }
1006
1007 mtp_store_t *_device_get_store_containing_obj(mtp_uint32 obj_handle)
1008 {
1009         mtp_uint32 ii = 0;
1010         mtp_obj_t *obj = NULL;
1011         mtp_store_t *store = NULL;
1012
1013         for (ii = 0; ii < g_device.num_stores; ii++) {
1014                 store = &(g_device.store_list[ii]);
1015                 obj = _entity_get_object_from_store(store, obj_handle);
1016                 if (obj != NULL)
1017                         return store;
1018         }
1019         return NULL;
1020 }
1021
1022 mtp_store_t *_device_get_store_at_index(mtp_uint32 index)
1023 {
1024         if (index >= g_device.num_stores) {
1025                 ERR("Index not valid");
1026                 return NULL;
1027         }
1028
1029         return &(g_device.store_list[index]);
1030 }
1031
1032 /* LCOV_EXCL_START */
1033 device_prop_desc_t *_device_get_ref_prop_list(void)
1034 {
1035         return g_device.device_prop_list;
1036 }
1037
1038 mtp_bool _device_get_playback_obj(mtp_uint32 *playback_obj)
1039 {
1040         device_prop_desc_t *device_prop = NULL;
1041
1042         device_prop = _device_get_device_property(MTP_PROPERTYCODE_PLAYBACK_OBJECT);
1043         if (NULL == device_prop) {
1044                 ERR("device_prop is NULL");
1045                 return FALSE;
1046         }
1047         memcpy(playback_obj, device_prop->current_val.integer,
1048                         sizeof(mtp_uint32));
1049
1050         return TRUE;
1051 }
1052
1053 mtp_bool _device_set_playback_obj(mtp_uint32 playback_obj)
1054 {
1055         device_prop_desc_t *device_prop = NULL;
1056         cmd_container_t event = { 0, };
1057
1058         device_prop = _device_get_device_property(MTP_PROPERTYCODE_PLAYBACK_OBJECT);
1059         if (device_prop == NULL) {
1060                 ERR("device_prop is NULL");
1061                 return FALSE;
1062         }
1063         _prop_set_current_integer(device_prop, playback_obj);
1064         _hdlr_init_event_container(&event,
1065                         PTP_EVENTCODE_DEVICEPROPCHANGED, 0, 0, 0);
1066         _hdlr_send_event_container(&event);
1067         return TRUE;
1068 }
1069 /* LCOV_EXCL_STOP */
1070
1071 void _device_get_serial(mtp_char *serial_no, mtp_uint32 len)
1072 {
1073         ret_if(serial_no == NULL);
1074
1075         _util_utf16_to_utf8(serial_no, len,
1076                         g_device.device_info.serial_no.str);
1077         return;
1078 }
1079
1080 /* LCOV_EXCL_START */
1081 void _device_set_phase(device_phase_t phase)
1082 {
1083         DBG("Devie phase is set [%d]\n", phase);
1084         g_device.phase = phase;
1085         return;
1086 }
1087
1088 device_phase_t _device_get_phase(void)
1089 {
1090         return g_device.phase;
1091 }
1092 /* LCOV_EXCL_STOP */
1093
1094 mtp_uint32 _device_get_default_store_id(void)
1095 {
1096         return g_device.default_store_id;
1097 }
1098
1099 mtp_uint32 _device_get_default_parent_handle(void)
1100 {
1101         return g_device.default_hparent;
1102 }
1103
1104 mtp_uint32 _device_get_num_stores(void)
1105 {
1106         return g_device.num_stores;
1107 }
1108
1109 /* LCOV_EXCL_START */
1110 device_status_t _device_get_status(void)
1111 {
1112         return g_device.status;
1113 }
1114 /* LCOV_EXCL_STOP */
1115
1116 mtp_char *_device_get_device_name(void)
1117 {
1118         return g_strdup(g_device.device_name);
1119 }
1120
1121 void _device_set_device_name(mtp_char *dev_name)
1122 {
1123         ret_if(dev_name == NULL);
1124
1125         g_strlcpy(g_device.device_name, dev_name, sizeof(g_device.device_name));
1126         return;
1127 }
1128
1129 mtp_char *_device_get_sync_partner(void)
1130 {
1131         return g_strdup(g_device.sync_partner);
1132 }
1133
1134 void _device_set_sync_partner(mtp_char *sync_ptr)
1135 {
1136         ret_if(sync_ptr == NULL);
1137
1138         g_strlcpy(g_device.sync_partner, sync_ptr,
1139                         sizeof(g_device.sync_partner));
1140         return;
1141 }