Sync code with Tizen 3.0 branch
[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 mtp_uint32 _get_device_info_size(void)
409 {
410         mtp_uint32 size = 0;
411         device_info_t *info = &(g_device.device_info);
412
413         size += sizeof(info->std_version);
414         size += sizeof(info->vendor_extn_id);
415         size += sizeof(info->vendor_extn_version);
416         size += _prop_size_ptpstring(&(info->vendor_extn_desc));
417         size += sizeof(info->functional_mode);
418         size += sizeof(mtp_uint32);     /*for number of supported ops*/
419         size += sizeof(g_ops_supported);
420         size += sizeof(mtp_uint32);
421         size += sizeof(g_event_supported);
422         size += sizeof(mtp_uint32);
423         size += NUM_DEVICE_PROPERTIES * sizeof(mtp_uint16);
424         size += sizeof(mtp_uint32);
425         size += sizeof(g_capture_fmts);
426         size += sizeof(mtp_uint32);
427         size += sizeof(g_object_fmts);
428         size += _prop_size_ptpstring(&(info->manufacturer));
429         size += _prop_size_ptpstring(&(info->model));
430         size += _prop_size_ptpstring(&(info->device_version));
431         size += _prop_size_ptpstring(&(info->serial_no));
432
433         return size;
434 }
435
436 mtp_uint32 _pack_device_info(mtp_uchar *buf, mtp_uint32 buf_sz)
437 {
438         mtp_uint16 ii = 0;
439         mtp_uchar *ptr = buf;
440         mtp_uint32 count = 0;
441         device_info_t *info = &(g_device.device_info);
442
443         retv_if(NULL == buf, 0);
444
445         if (buf_sz < _get_device_info_size()) {
446                 ERR("buffer size [%d] is less than device_info Size\n", buf_sz);
447                 return 0;
448         }
449
450         memcpy(ptr, &info->std_version, sizeof(info->std_version));
451 #ifdef __BIG_ENDIAN__
452         _util_conv_byte_order(ptr, sizeof(info->std_version));
453 #endif /*__BIG_ENDIAN__*/
454         ptr += sizeof(info->std_version);
455
456         memcpy(ptr, &info->vendor_extn_id, sizeof(info->vendor_extn_id));
457 #ifdef __BIG_ENDIAN__
458         _util_conv_byte_order(ptr, sizeof(info->vendor_extn_id));
459 #endif /*__BIG_ENDIAN__*/
460         ptr += sizeof(info->vendor_extn_id);
461
462         memcpy(ptr, &info->vendor_extn_version,
463                         sizeof(info->vendor_extn_version));
464 #ifdef __BIG_ENDIAN__
465         _util_conv_byte_order(ptr, sizeof(info->vendor_extn_version));
466 #endif /*__BIG_ENDIAN__*/
467         ptr += sizeof(info->vendor_extn_version);
468
469         ptr += _prop_pack_ptpstring(&(info->vendor_extn_desc), ptr,
470                         _prop_size_ptpstring(&(info->vendor_extn_desc)));
471
472         memcpy(ptr, &info->functional_mode, sizeof(info->functional_mode));
473 #ifdef __BIG_ENDIAN__
474         _util_conv_byte_order(ptr, sizeof(info->functional_mode));
475 #endif /*__BIG_ENDIAN__*/
476         ptr += sizeof(info->functional_mode);
477
478         count = (sizeof(g_ops_supported) / sizeof(mtp_uint16));
479         memcpy(ptr, &count, sizeof(count));
480
481 #ifdef __BIG_ENDIAN__
482         _util_conv_byte_order(ptr, sizeof(count));
483 #endif /*__BIG_ENDIAN__*/
484         ptr += sizeof(count);
485         for (ii = 0; ii < count; ii++) {
486                 memcpy(ptr, (void *)&(info->ops_supported[ii]),
487                                 sizeof(mtp_uint16));
488 #ifdef __BIG_ENDIAN__
489                 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
490 #endif /*__BIG_ENDIAN__*/
491                 ptr += sizeof(mtp_uint16);
492         }
493
494         count = (sizeof(g_event_supported) / sizeof(mtp_uint16));
495         memcpy(ptr, &count, sizeof(count));
496
497 #ifdef __BIG_ENDIAN__
498         _util_conv_byte_order(ptr, sizeof(count));
499 #endif /*__BIG_ENDIAN__*/
500         ptr += sizeof(count);
501         for (ii = 0; ii < count; ii++) {
502                 memcpy(ptr, (void *)&(info->events_supported[ii]),
503                                 sizeof(mtp_uint16));
504 #ifdef __BIG_ENDIAN__
505                 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
506 #endif /*__BIG_ENDIAN__*/
507                 ptr += sizeof(mtp_uint16);
508         }
509
510         count = NUM_DEVICE_PROPERTIES;
511         memcpy(ptr, &count, sizeof(count));
512 #ifdef __BIG_ENDIAN__
513         _util_conv_byte_order(ptr, sizeof(count));
514 #endif /*__BIG_ENDIAN__*/
515         ptr += sizeof(count);
516         for (ii = 0; ii < NUM_DEVICE_PROPERTIES; ii++) {
517                 memcpy(ptr, (void *)&(info->device_prop_supported[ii]),
518                                 sizeof(mtp_uint16));
519 #ifdef __BIG_ENDIAN__
520                 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
521 #endif /*__BIG_ENDIAN__*/
522                 ptr += sizeof(mtp_uint16);
523         }
524
525         count = (sizeof(g_capture_fmts) / sizeof(mtp_uint16));
526         memcpy(ptr, &count, sizeof(count));
527 #ifdef __BIG_ENDIAN__
528         _util_conv_byte_order(ptr, sizeof(count));
529 #endif /*__BIG_ENDIAN__*/
530         ptr += sizeof(count);
531
532         for (ii = 0; ii < count; ii++) {
533                 memcpy(ptr, (void *)&(info->capture_fmts[ii]),
534                                 sizeof(mtp_uint16));
535 #ifdef __BIG_ENDIAN__
536                 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
537 #endif /*__BIG_ENDIAN__*/
538                 ptr += sizeof(mtp_uint16);
539         }
540
541         count = (sizeof(g_object_fmts) / sizeof(mtp_uint16));
542         memcpy(ptr, &count, sizeof(count));
543 #ifdef __BIG_ENDIAN__
544         _util_conv_byte_order(ptr, sizeof(count));
545 #endif /*__BIG_ENDIAN__*/
546         ptr += sizeof(count);
547         for (ii = 0; ii < count; ii++) {
548                 memcpy(ptr, (void *)&(info->object_fmts[ii]),
549                                 sizeof(mtp_uint16));
550 #ifdef __BIG_ENDIAN__
551                 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
552 #endif /*__BIG_ENDIAN__*/
553                 ptr += sizeof(mtp_uint16);
554         }
555
556         ptr += _prop_pack_ptpstring(&(info->manufacturer), ptr,
557                         _prop_size_ptpstring(&(info->manufacturer)));
558
559         ptr += _prop_pack_ptpstring(&(info->model), ptr,
560                         _prop_size_ptpstring(&(info->model)));
561
562         ptr += _prop_pack_ptpstring(&(info->device_version), ptr,
563                         _prop_size_ptpstring(&(info->device_version)));
564
565         ptr += _prop_pack_ptpstring(&(info->serial_no), ptr,
566                         _prop_size_ptpstring(&(info->serial_no)));
567
568         return (mtp_uint32)(ptr - buf);
569 }
570
571 void _reset_mtp_device(void)
572 {
573         _transport_set_control_event(0);
574         _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
575
576         /* resets device state to ok/Ready */
577         /* reset device phase to idle */
578
579         g_device.status = DEVICE_STATUSOK;
580         g_device.phase = DEVICE_PHASE_IDLE;
581         return;
582 }
583
584 device_prop_desc_t *_device_get_device_property(mtp_uint32 prop_code)
585 {
586         mtp_uint16 ii = 0;
587
588         for (ii = 0; ii < NUM_DEVICE_PROPERTIES; ii++) {
589                 if (g_device.device_prop_list[ii].propinfo.prop_code == prop_code)
590                         return &(g_device.device_prop_list[ii]);
591         }
592         return NULL;
593 }
594
595 /*
596  * static mtp_bool _device_add_store(store_type_t store_type)
597  * This function will add the store to the device.
598  * @param[in]   store_type      Store Number
599  * @return      TRUE if success, otherwise FALSE.
600  */
601 static mtp_bool __add_store_to_device(store_type_t store_type)
602 {
603         mtp_char *storage_path = NULL;
604         mtp_uint32 store_id = 0;
605         file_attr_t attrs = { 0, };
606         char sto_path[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
607
608         switch (store_type) {
609         case MTP_STORAGE_INTERNAL:
610                 _util_get_internal_path(sto_path);
611                 storage_path = (mtp_char *)sto_path;
612                 store_id = MTP_INTERNAL_STORE_ID;
613                 break;
614         case MTP_STORAGE_EXTERNAL:
615                 _util_get_external_path(sto_path);
616                 storage_path = (mtp_char *)sto_path;
617                 store_id = MTP_EXTERNAL_STORE_ID;
618                 break;
619         default:
620                 ERR("Unknown Storage [%d]\n", store_id);
621                 return FALSE;
622         }
623
624         if (FALSE == _util_get_file_attrs(storage_path, &attrs)) {
625                 ERR("_util_get_file_attrs() Fail");
626                 return FALSE;
627         }
628
629         if (MTP_FILE_ATTR_INVALID == attrs.attribute ||
630                         !(attrs.attribute & MTP_FILE_ATTR_MODE_DIR)) {
631                 ERR("attribute [0x%x], dir[0x%x]\n",
632                                 attrs.attribute, MTP_FILE_ATTR_MODE_DIR);
633                 ERR("Storage [%d]\n", store_id);
634                 return FALSE;
635         }
636
637
638         if (g_device.num_stores + 1 > MAX_NUM_DEVICE_STORES) {
639                 ERR("reached to max [%d]\n", MAX_NUM_DEVICE_STORES);
640                 return FALSE;
641         }
642
643         if (FALSE == _entity_init_mtp_store(&(g_device.store_list[g_device.num_stores]),
644                                 store_id, storage_path)) {
645                 ERR("_entity_init_mtp_store() Fail");
646                 return FALSE;
647         }
648
649         g_device.num_stores++;
650         g_device.is_mounted[store_type] = TRUE;
651
652         return TRUE;
653 }
654
655 /*
656  * static mtp_bool _device_remove_store(store_type_t store_type)
657  * This function will remove the store from the device.
658  * @param[in]   store_type      Store type
659  * @return      TRUE if success, otherwise FALSE.
660  */
661 static mtp_bool __remove_store_from_device(store_type_t store_type)
662 {
663         mtp_int32 ii = 0;
664         mtp_device_t *device = &g_device;
665         mtp_store_t *store = NULL;
666         mtp_uint32 store_id = 0;
667
668         switch (store_type) {
669         case MTP_STORAGE_INTERNAL:
670                 store_id = MTP_INTERNAL_STORE_ID;
671                 break;
672         case MTP_STORAGE_EXTERNAL:
673                 store_id = MTP_EXTERNAL_STORE_ID;
674                 break;
675         default:
676                 ERR("Unknown Storage [%d]\n", store_type);
677                 return FALSE;
678         }
679
680         for (ii = 0; ii < device->num_stores; ii++) {
681                 store = &(device->store_list[ii]);
682                 if (store->store_id == store_id) {
683                         __clear_store_data(store->store_id);
684                         device->is_mounted[store_type] = FALSE;
685                         break;
686                 }
687         }
688
689         return TRUE;
690 }
691
692 mtp_bool _device_is_store_mounted(mtp_int32 store_type)
693 {
694         if (store_type < MTP_STORAGE_INTERNAL ||
695                         store_type >= MTP_STORAGE_ALL) {
696                 ERR("unknown storage(%d)\n", store_type);
697                 return FALSE;
698         }
699
700         return g_device.is_mounted[store_type];
701 }
702
703 mtp_bool _device_install_storage(mtp_int32 type)
704 {
705         mtp_int32 int_status = TRUE;
706         mtp_int32 ext_status = TRUE;
707         mtp_bool mounted;
708         mtp_bool lock_status;
709
710         switch (type) {
711         case MTP_ADDREM_AUTO:
712                 DBG(" case MTP_ADDREM_AUTO:");
713
714                 lock_status = _util_get_local_lock_status();
715                 if (lock_status == MTP_PHONE_LOCK_OFF) {
716                         int_status = _device_is_store_mounted(MTP_STORAGE_INTERNAL);
717                         if (int_status == FALSE)
718                                 __add_store_to_device(MTP_STORAGE_INTERNAL);
719                 }
720
721                 mounted = _util_get_local_mmc_status();
722                 if (mounted == MTP_PHONE_MMC_INSERTED) {
723
724                         ext_status =
725                                 _device_is_store_mounted(MTP_STORAGE_EXTERNAL);
726                         if (ext_status == FALSE)
727                                 __add_store_to_device(MTP_STORAGE_EXTERNAL);
728                 }
729                 break;
730
731         case MTP_ADDREM_INTERNAL:
732                 DBG("case MTP_ADDREM_INTERNAL:");
733                 if (MTP_PHONE_LOCK_OFF != _util_get_local_lock_status())
734                         break;
735                 if (FALSE == _device_is_store_mounted(MTP_STORAGE_INTERNAL))
736                         __add_store_to_device(MTP_STORAGE_INTERNAL);
737                 break;
738
739         case MTP_ADDREM_EXTERNAL:
740                 DBG(" case MTP_ADDREM_EXTERNAL:");
741                 if (MTP_PHONE_MMC_INSERTED != _util_get_local_mmc_status())
742                         break;
743                 mounted = _device_is_store_mounted(MTP_STORAGE_EXTERNAL);
744                 if (mounted == FALSE) {
745                         if (__add_store_to_device(MTP_STORAGE_EXTERNAL) == FALSE) {
746                                 ERR("__add_store_to_device() Fail");
747                                 return FALSE;
748                         }
749                 }
750                 break;
751
752         case MTP_ADDREM_ALL:
753                 DBG(" case MTP_ADDREM_ALL:");
754                 __add_store_to_device(MTP_STORAGE_INTERNAL);
755                 __add_store_to_device(MTP_STORAGE_EXTERNAL);
756                 break;
757
758         default:
759                 ERR("_device_install_storage : unknown type [%d]\n", type);
760                 break;
761         }
762
763         return TRUE;
764 }
765
766 mtp_bool _device_uninstall_storage(mtp_int32 type)
767 {
768         switch (type) {
769         case MTP_ADDREM_AUTO:
770                 if (TRUE == _device_is_store_mounted(MTP_STORAGE_EXTERNAL))
771                         __remove_store_from_device(MTP_STORAGE_EXTERNAL);
772                 if (TRUE == _device_is_store_mounted(MTP_STORAGE_INTERNAL))
773                         __remove_store_from_device(MTP_STORAGE_INTERNAL);
774                 break;
775         case MTP_ADDREM_INTERNAL:
776                 if (TRUE == _device_is_store_mounted(MTP_STORAGE_INTERNAL))
777                         __remove_store_from_device(MTP_STORAGE_INTERNAL);
778                 break;
779         case MTP_ADDREM_EXTERNAL:
780                 if (TRUE == _device_is_store_mounted(MTP_STORAGE_EXTERNAL))
781                         __remove_store_from_device(MTP_STORAGE_EXTERNAL);
782                 break;
783         case MTP_ADDREM_ALL:
784                 __remove_store_from_device(MTP_STORAGE_INTERNAL);
785                 __remove_store_from_device(MTP_STORAGE_EXTERNAL);
786                 break;
787         default:
788                 ERR("unknown mode [%d]\n", type);
789                 break;
790         }
791
792         return TRUE;
793 }
794
795 /*
796  * static mtp_err_t __device_clear_store_data(mtp_uint32 store_id)
797  * This function removes the storage entry.
798  * @param[in]   store_id        Specifies the storage id to remove
799  * @return      This function returns MTP_ERROR_NONE on success
800  *              ERROR number on failure.
801  */
802 static mtp_err_t __clear_store_data(mtp_uint32 store_id)
803 {
804         mtp_uint16 idx = 0;
805         mtp_store_t *store = NULL;
806         mtp_uint32 count = g_device.num_stores;
807
808         for (idx = 0; idx < count; idx++) {
809                 if (g_device.store_list[idx].store_id == store_id) {
810
811                         _entity_destroy_mtp_store(&(g_device.store_list[idx]));
812
813                         store = &(g_device.store_list[idx]);
814                         store->store_id = 0;
815                         store->is_hidden = FALSE;
816                         g_free(store->root_path);
817                         store->root_path = NULL;
818
819                         for (; idx < count - 1; idx++) {
820                                 _entity_copy_store_data(&(g_device.store_list[idx]),
821                                                 &(g_device.store_list[idx + 1]));
822                         }
823
824                         g_device.store_list[count - 1].store_id = 0;
825                         g_device.store_list[count - 1].root_path = NULL;
826                         g_device.store_list[count - 1].is_hidden = FALSE;
827                         _util_init_list(&(g_device.store_list[count - 1].obj_list));
828
829                         /*Initialize the destroyed store*/
830                         g_device.num_stores--;
831                         return MTP_ERROR_NONE;
832                 }
833         }
834         return MTP_ERROR_GENERAL;
835 }
836
837 mtp_store_t *_device_get_store(mtp_uint32 store_id)
838 {
839         mtp_int32 ii = 0;
840         mtp_store_t *store = NULL;
841
842         for (ii = 0; ii < g_device.num_stores; ii++) {
843
844                 store = &(g_device.store_list[ii]);
845                 if (store->store_id == store_id)
846                         return store;
847         }
848         return NULL;
849 }
850
851 mtp_uint32 _device_get_store_ids(ptp_array_t *store_ids)
852 {
853         mtp_store_t *store = NULL;
854         mtp_int32 ii = 0;
855
856         for (ii = g_device.num_stores - 1; ii >= 0; ii--) {
857
858                 store = &(g_device.store_list[ii]);
859                 if ((store != NULL) && (FALSE == store->is_hidden))
860                         _prop_append_ele_ptparray(store_ids, store->store_id);
861         }
862         return store_ids->num_ele;
863 }
864
865 mtp_uint32 _device_get_num_objects(mtp_uint32 store_id)
866 {
867         mtp_uint32 num_objs = 0;
868         mtp_store_t *store = NULL;
869         mtp_uint32 ii = 0;
870
871         for (ii = 0; ii < g_device.num_stores; ii++) {
872
873                 store = &(g_device.store_list[ii]);
874                 if ((store->store_id == store_id) ||
875                                 (store_id == PTP_STORAGEID_ALL)) {
876                         num_objs += store->obj_list.nnodes;
877                 }
878         }
879
880         return num_objs;
881 }
882
883 mtp_uint32 _device_get_num_objects_with_format(mtp_uint32 store_id,
884                 mtp_uint32 format)
885 {
886         mtp_uint32 num_objs = 0;
887         mtp_store_t *store = NULL;
888         mtp_uint32 ii = 0;
889
890         for (ii = 0; ii < g_device.num_stores; ii++) {
891
892                 store = &(g_device.store_list[ii]);
893                 if ((store->store_id != store_id) &&
894                                 (store_id != PTP_STORAGEID_ALL)) {
895                         continue;
896                 }
897                 num_objs += _entity_get_num_object_with_same_format(store,
898                                 format);
899         }
900
901         return num_objs;
902 }
903
904 mtp_obj_t *_device_get_object_with_handle(mtp_uint32 obj_handle)
905 {
906         mtp_int32 ii = 0;
907         mtp_obj_t *obj = NULL;
908         mtp_store_t *store = NULL;
909
910         for (ii = 0; ii < g_device.num_stores; ii++) {
911
912                 store = &(g_device.store_list[ii]);
913                 obj = _entity_get_object_from_store(store, obj_handle);
914                 if (obj == NULL)
915                         continue;
916                 break;
917         }
918         return obj;
919 }
920
921 mtp_obj_t* _device_get_object_with_path(mtp_char *full_path)
922 {
923         mtp_int32 i = 0;
924         mtp_obj_t *obj = NULL;
925         mtp_store_t *store = NULL;
926
927         retv_if(NULL == full_path, NULL);
928
929         for (i = 0; i < g_device.num_stores; i++) {
930                 store = &(g_device.store_list[i]);
931                 obj = _entity_get_object_from_store_by_path(store, full_path);
932                 if (obj == NULL)
933                         continue;
934                 break;
935         }
936         return obj;
937 }
938
939 mtp_uint16 _device_delete_object(mtp_uint32 obj_handle, mtp_uint32 fmt)
940 {
941         mtp_uint32 ii = 0;
942         mtp_uint16 response = PTP_RESPONSE_OK;
943         mtp_store_t *store = NULL;
944         mtp_bool all_del = TRUE;
945         mtp_bool atlst_one = FALSE;
946
947         if (PTP_OBJECTHANDLE_ALL != obj_handle) {
948                 store = _device_get_store_containing_obj(obj_handle);
949                 if (store == NULL) {
950                         response = PTP_RESPONSE_INVALID_OBJ_HANDLE;
951                 } else {
952                         response = _entity_delete_obj_mtp_store(store,
953                                         obj_handle, fmt, TRUE);
954                 }
955                 return response;
956         }
957
958         for (ii = 0; ii < g_device.num_stores; ii++) {
959                 store = &(g_device.store_list[ii]);
960                 response = _entity_delete_obj_mtp_store(store, obj_handle,
961                                 fmt, TRUE);
962                 switch (response) {
963                 case PTP_RESPONSE_STORE_READONLY:
964                         all_del = FALSE;
965                         break;
966                 case PTP_RESPONSE_PARTIAL_DELETION:
967                         all_del = FALSE;
968                         atlst_one = TRUE;
969                         break;
970                 case PTP_RESPONSE_OBJ_WRITEPROTECTED:
971                 case PTP_RESPONSE_ACCESSDENIED:
972                         all_del = FALSE;
973                         break;
974                 case PTP_RESPONSE_OK:
975                 default:
976                         atlst_one = TRUE;
977                         break;
978                 }
979         }
980
981         if (all_del)
982                 response = PTP_RESPONSE_OK;
983         else if (atlst_one)
984                 response = PTP_RESPONSE_PARTIAL_DELETION;
985
986         return response;
987 }
988
989 mtp_store_t *_device_get_store_containing_obj(mtp_uint32 obj_handle)
990 {
991         mtp_uint32 ii = 0;
992         mtp_obj_t *obj = NULL;
993         mtp_store_t *store = NULL;
994
995         for (ii = 0; ii < g_device.num_stores; ii++) {
996                 store = &(g_device.store_list[ii]);
997                 obj = _entity_get_object_from_store(store, obj_handle);
998                 if (obj != NULL)
999                         return store;
1000         }
1001         return NULL;
1002 }
1003
1004 mtp_store_t *_device_get_store_at_index(mtp_uint32 index)
1005 {
1006         if (index >= g_device.num_stores) {
1007                 ERR("Index not valid");
1008                 return NULL;
1009         }
1010
1011         return &(g_device.store_list[index]);
1012 }
1013
1014 device_prop_desc_t *_device_get_ref_prop_list(void)
1015 {
1016         return g_device.device_prop_list;
1017 }
1018
1019 mtp_bool _device_get_playback_obj(mtp_uint32 *playback_obj)
1020 {
1021         device_prop_desc_t *device_prop = NULL;
1022
1023         device_prop = _device_get_device_property(MTP_PROPERTYCODE_PLAYBACK_OBJECT);
1024         if (NULL == device_prop) {
1025                 ERR("device_prop is NULL");
1026                 return FALSE;
1027         }
1028         memcpy(playback_obj, device_prop->current_val.integer,
1029                         sizeof(mtp_uint32));
1030
1031         return TRUE;
1032 }
1033
1034 mtp_bool _device_set_playback_obj(mtp_uint32 playback_obj)
1035 {
1036         device_prop_desc_t *device_prop = NULL;
1037         cmd_container_t event = { 0, };
1038
1039         device_prop = _device_get_device_property(MTP_PROPERTYCODE_PLAYBACK_OBJECT);
1040         if (device_prop == NULL) {
1041                 ERR("device_prop is NULL");
1042                 return FALSE;
1043         }
1044         _prop_set_current_integer(device_prop, playback_obj);
1045         _hdlr_init_event_container(&event,
1046                         PTP_EVENTCODE_DEVICEPROPCHANGED, 0, 0, 0);
1047         _hdlr_send_event_container(&event);
1048         return TRUE;
1049 }
1050
1051 void _device_get_serial(mtp_char *serial_no, mtp_uint32 len)
1052 {
1053         ret_if(serial_no == NULL);
1054
1055         _util_utf16_to_utf8(serial_no, len,
1056                         g_device.device_info.serial_no.str);
1057         return;
1058 }
1059
1060 void _device_set_phase(device_phase_t phase)
1061 {
1062         DBG("Devie phase is set [%d]\n", phase);
1063         g_device.phase = phase;
1064         return;
1065 }
1066
1067 device_phase_t _device_get_phase(void)
1068 {
1069         return g_device.phase;
1070 }
1071
1072 mtp_uint32 _device_get_default_store_id(void)
1073 {
1074         return g_device.default_store_id;
1075 }
1076
1077 mtp_uint32 _device_get_default_parent_handle(void)
1078 {
1079         return g_device.default_hparent;
1080 }
1081
1082 mtp_uint32 _device_get_num_stores(void)
1083 {
1084         return g_device.num_stores;
1085 }
1086
1087 device_status_t _device_get_status(void)
1088 {
1089         return g_device.status;
1090 }
1091
1092 mtp_char *_device_get_device_name(void)
1093 {
1094         return g_strdup(g_device.device_name);
1095 }
1096
1097 void _device_set_device_name(mtp_char *dev_name)
1098 {
1099         ret_if(dev_name == NULL);
1100
1101         g_strlcpy(g_device.device_name, dev_name, sizeof(g_device.device_name));
1102         return;
1103 }
1104
1105 mtp_char *_device_get_sync_partner(void)
1106 {
1107         return g_strdup(g_device.sync_partner);
1108 }
1109
1110 void _device_set_sync_partner(mtp_char *sync_ptr)
1111 {
1112         ret_if(sync_ptr == NULL);
1113
1114         g_strlcpy(g_device.sync_partner, sync_ptr,
1115                         sizeof(g_device.sync_partner));
1116         return;
1117 }