2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "mtp_support.h"
21 #include "ptp_datacodes.h"
22 #include "mtp_device.h"
23 #include "mtp_transport.h"
24 #include "ptp_container.h"
26 #define MTP_DEVICE_VERSION_CHAR "V1.0"
29 * GLOBAL AND EXTERN VARIABLES
31 static mtp_device_t g_device = { 0 };
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];
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,
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,
67 /*PTP_OPCODE_RESETDEVICE,*/
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,*/
82 MTP_OPCODE_WMP_REPORTACQUIREDCONTENT,
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 */
104 static mtp_uint16 g_capture_fmts[] = {
105 /* PTP_FORMATCODE_IMAGE_EXIF */
109 static mtp_uint16 g_object_fmts[] = {
122 /* PTP_FORMATCODE_IMAGE_JFIF, */
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,*/
145 MTP_FMT_ABSTRACT_AUDIO_ALBUM,
146 /* MTP_FORMATCODE_UNDEFINED_FIRMWARE */
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);
163 * static void __device_init_device_info()
164 * This function initializes MTP device information
167 static void __init_device_info(void)
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 };
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;
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);
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;
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);
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);
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);
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));
216 _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ, serial_no);
217 _prop_copy_char_to_ptpstring(&(info->serial_no), wtemp, WCHAR_TYPE);
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.
227 static mtp_bool __init_device_props()
229 static mtp_bool already_init = FALSE;
231 device_prop_desc_t *dev_prop = NULL;
233 ptp_string_t tmp = { 0 };
234 mtp_uint32 default_val;
236 if (TRUE == already_init) {
237 ERR("Already initialized. just return...");
241 g_device.device_prop_list = g_device_props;
242 #ifdef MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL
244 * Battery level from 0 to 100, with step of 10,
245 * won't change after a reset
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);
251 mtp_int32 batt_level = 0;
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);
257 _prop_set_default_integer(&(dev_prop->propinfo),
258 (mtp_uchar *)&default_val);
261 #endif /*MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL*/
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
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 };
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);
279 _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ,
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);
290 #else/*MTP_USE_INFORMATION_REGISTRY*/
292 mtp_wchar wtemp[MTP_MAX_REG_STRING + 1] = { 0 };
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);
300 #endif/*MTP_USE_INFORMATION_REGISTRY*/
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
309 mtp_char *dev_ptr = NULL;
310 mtp_wchar wmodel[MTP_MAX_REG_STRING + 1] = { 0 };
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);
318 _util_utf8_to_utf16(wmodel, sizeof(wmodel) / WCHAR_SIZ,
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);
326 #else /*MTP_USE_INFORMATION_REGISTRY*/
328 mtp_wchar wmodel[MTP_MAX_REG_STRING + 1] = { 0 };
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);
336 #endif /*MTP_USE_INFORMATION_REGISTRY*/
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);
346 _prop_set_default_integer(&(dev_prop->propinfo), (mtp_uchar *) &default_val);
347 _prop_set_current_integer(dev_prop, (mtp_uint32)1);
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);
359 * 0:generic, 1: DSC, 2: Media Player, 3: mobile,
360 * 4: digital video camera, 5: PDA, 6: audio recoder
363 _prop_set_default_integer(&(dev_prop->propinfo), (mtp_uchar *)&default_val);
364 _prop_set_current_integer(dev_prop, (mtp_uint32)0x3);
367 #endif /*MTP_SUPPORT_DEVICE_CLASS*/
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);
379 void _init_mtp_device(void)
381 static mtp_bool already_init = FALSE;
383 if (TRUE == already_init) {
384 DBG("Device is already initialized");
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;
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();
408 /* LCOV_EXCL_START */
409 mtp_uint32 _get_device_info_size(void)
412 device_info_t *info = &(g_device.device_info);
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));
437 mtp_uint32 _pack_device_info(mtp_uchar *buf, mtp_uint32 buf_sz)
440 mtp_uchar *ptr = buf;
441 mtp_uint32 count = 0;
442 device_info_t *info = &(g_device.device_info);
444 retv_if(NULL == buf, 0);
446 if (buf_sz < _get_device_info_size()) {
447 ERR("buffer size [%d] is less than device_info Size\n", buf_sz);
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);
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);
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);
470 ptr += _prop_pack_ptpstring(&(info->vendor_extn_desc), ptr,
471 _prop_size_ptpstring(&(info->vendor_extn_desc)));
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);
479 count = (sizeof(g_ops_supported) / sizeof(mtp_uint16));
480 memcpy(ptr, &count, sizeof(count));
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]),
489 #ifdef __BIG_ENDIAN__
490 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
491 #endif /*__BIG_ENDIAN__*/
492 ptr += sizeof(mtp_uint16);
495 count = (sizeof(g_event_supported) / sizeof(mtp_uint16));
496 memcpy(ptr, &count, sizeof(count));
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]),
505 #ifdef __BIG_ENDIAN__
506 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
507 #endif /*__BIG_ENDIAN__*/
508 ptr += sizeof(mtp_uint16);
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]),
520 #ifdef __BIG_ENDIAN__
521 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
522 #endif /*__BIG_ENDIAN__*/
523 ptr += sizeof(mtp_uint16);
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);
533 for (ii = 0; ii < count; ii++) {
534 memcpy(ptr, (void *)&(info->capture_fmts[ii]),
536 #ifdef __BIG_ENDIAN__
537 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
538 #endif /*__BIG_ENDIAN__*/
539 ptr += sizeof(mtp_uint16);
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]),
551 #ifdef __BIG_ENDIAN__
552 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
553 #endif /*__BIG_ENDIAN__*/
554 ptr += sizeof(mtp_uint16);
557 ptr += _prop_pack_ptpstring(&(info->manufacturer), ptr,
558 _prop_size_ptpstring(&(info->manufacturer)));
560 ptr += _prop_pack_ptpstring(&(info->model), ptr,
561 _prop_size_ptpstring(&(info->model)));
563 ptr += _prop_pack_ptpstring(&(info->device_version), ptr,
564 _prop_size_ptpstring(&(info->device_version)));
566 ptr += _prop_pack_ptpstring(&(info->serial_no), ptr,
567 _prop_size_ptpstring(&(info->serial_no)));
569 return (mtp_uint32)(ptr - buf);
572 void _reset_mtp_device(void)
574 _transport_set_control_event(0);
575 _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
577 /* resets device state to ok/Ready */
578 /* reset device phase to idle */
580 g_device.status = DEVICE_STATUSOK;
581 g_device.phase = DEVICE_PHASE_IDLE;
586 device_prop_desc_t *_device_get_device_property(mtp_uint32 prop_code)
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]);
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.
603 static mtp_bool __add_store_to_device(store_type_t store_type)
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 };
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;
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;
622 ERR("Unknown Storage [%d]\n", store_id);
626 if (FALSE == _util_get_file_attrs(storage_path, &attrs)) {
627 ERR("_util_get_file_attrs() Fail");
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);
640 if (g_device.num_stores + 1 > MAX_NUM_DEVICE_STORES) {
641 ERR("reached to max [%d]\n", MAX_NUM_DEVICE_STORES);
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");
651 g_device.num_stores++;
652 g_device.is_mounted[store_type] = TRUE;
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.
663 /* LCOV_EXCL_START */
664 static mtp_bool __remove_store_from_device(store_type_t store_type)
667 mtp_device_t *device = &g_device;
668 mtp_store_t *store = NULL;
669 mtp_uint32 store_id = 0;
671 switch (store_type) {
672 case MTP_STORAGE_INTERNAL:
673 store_id = MTP_INTERNAL_STORE_ID;
675 case MTP_STORAGE_EXTERNAL:
676 store_id = MTP_EXTERNAL_STORE_ID;
679 ERR("Unknown Storage [%d]\n", store_type);
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;
695 mtp_bool _device_is_store_mounted(mtp_int32 store_type)
697 if (store_type < MTP_STORAGE_INTERNAL ||
698 store_type >= MTP_STORAGE_ALL) {
699 ERR("unknown storage(%d)\n", store_type);
703 return g_device.is_mounted[store_type];
707 mtp_bool _device_install_storage(mtp_int32 type)
709 mtp_int32 int_status = TRUE;
710 mtp_int32 ext_status = TRUE;
712 mtp_bool lock_status;
715 case MTP_ADDREM_AUTO:
716 DBG(" case MTP_ADDREM_AUTO:");
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);
727 mounted = _util_get_local_mmc_status();
728 if (mounted == MTP_PHONE_MMC_INSERTED) {
730 /* LCOV_EXCL_START */
732 _device_is_store_mounted(MTP_STORAGE_EXTERNAL);
733 if (ext_status == FALSE)
734 __add_store_to_device(MTP_STORAGE_EXTERNAL);
739 case MTP_ADDREM_INTERNAL:
740 DBG("case MTP_ADDREM_INTERNAL:");
741 if (MTP_PHONE_LOCK_OFF != _util_get_local_lock_status())
743 if (FALSE == _device_is_store_mounted(MTP_STORAGE_INTERNAL))
744 __add_store_to_device(MTP_STORAGE_INTERNAL);
747 case MTP_ADDREM_EXTERNAL:
748 DBG(" case MTP_ADDREM_EXTERNAL:");
749 if (MTP_PHONE_MMC_INSERTED != _util_get_local_mmc_status())
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");
763 DBG(" case MTP_ADDREM_ALL:");
764 __add_store_to_device(MTP_STORAGE_INTERNAL);
765 __add_store_to_device(MTP_STORAGE_EXTERNAL);
769 ERR("_device_install_storage : unknown type [%d]\n", type);
776 /* LCOV_EXCL_START */
777 mtp_bool _device_uninstall_storage(mtp_int32 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);
786 case MTP_ADDREM_INTERNAL:
787 if (TRUE == _device_is_store_mounted(MTP_STORAGE_INTERNAL))
788 __remove_store_from_device(MTP_STORAGE_INTERNAL);
790 case MTP_ADDREM_EXTERNAL:
791 if (TRUE == _device_is_store_mounted(MTP_STORAGE_EXTERNAL))
792 __remove_store_from_device(MTP_STORAGE_EXTERNAL);
795 __remove_store_from_device(MTP_STORAGE_INTERNAL);
796 __remove_store_from_device(MTP_STORAGE_EXTERNAL);
799 ERR("unknown mode [%d]\n", type);
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.
813 static mtp_err_t __clear_store_data(mtp_uint32 store_id)
816 mtp_store_t *store = NULL;
817 mtp_uint32 count = g_device.num_stores;
819 for (idx = 0; idx < count; idx++) {
820 if (g_device.store_list[idx].store_id == store_id) {
822 _entity_destroy_mtp_store(&(g_device.store_list[idx]));
824 store = &(g_device.store_list[idx]);
826 store->is_hidden = FALSE;
827 g_free(store->root_path);
828 store->root_path = NULL;
830 for (; idx < count - 1; idx++) {
831 _entity_copy_store_data(&(g_device.store_list[idx]),
832 &(g_device.store_list[idx + 1]));
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));
840 /*Initialize the destroyed store*/
841 g_device.num_stores--;
842 return MTP_ERROR_NONE;
845 return MTP_ERROR_GENERAL;
849 mtp_store_t *_device_get_store(mtp_uint32 store_id)
852 mtp_store_t *store = NULL;
854 for (ii = 0; ii < g_device.num_stores; ii++) {
856 store = &(g_device.store_list[ii]);
857 if (store->store_id == store_id)
863 mtp_uint32 _device_get_store_ids(ptp_array_t *store_ids)
865 mtp_store_t *store = NULL;
868 for (ii = g_device.num_stores - 1; ii >= 0; ii--) {
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);
874 return store_ids->num_ele;
877 mtp_uint32 _device_get_num_objects(mtp_uint32 store_id)
879 mtp_uint32 num_objs = 0;
880 mtp_store_t *store = NULL;
883 for (ii = 0; ii < g_device.num_stores; ii++) {
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;
895 /* LCOV_EXCL_START */
896 mtp_uint32 _device_get_num_objects_with_format(mtp_uint32 store_id,
899 mtp_uint32 num_objs = 0;
900 mtp_store_t *store = NULL;
903 for (ii = 0; ii < g_device.num_stores; ii++) {
905 store = &(g_device.store_list[ii]);
906 if ((store->store_id != store_id) &&
907 (store_id != PTP_STORAGEID_ALL)) {
910 num_objs += _entity_get_num_object_with_same_format(store,
918 mtp_obj_t *_device_get_object_with_handle(mtp_uint32 obj_handle)
921 mtp_obj_t *obj = NULL;
922 mtp_store_t *store = NULL;
924 for (ii = 0; ii < g_device.num_stores; ii++) {
926 store = &(g_device.store_list[ii]);
927 obj = _entity_get_object_from_store(store, obj_handle);
935 /* LCOV_EXCL_START */
936 mtp_obj_t* _device_get_object_with_path(mtp_char *full_path)
939 mtp_obj_t *obj = NULL;
940 mtp_store_t *store = NULL;
942 retv_if(NULL == full_path, NULL);
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);
955 mtp_uint16 _device_delete_object(mtp_uint32 obj_handle, mtp_uint32 fmt)
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;
963 if (PTP_OBJECTHANDLE_ALL != obj_handle) {
964 store = _device_get_store_containing_obj(obj_handle);
966 response = PTP_RESPONSE_INVALID_OBJ_HANDLE;
968 /* LCOV_EXCL_START */
969 response = _entity_delete_obj_mtp_store(store,
970 obj_handle, fmt, TRUE);
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,
980 case PTP_RESPONSE_STORE_READONLY:
983 case PTP_RESPONSE_PARTIAL_DELETION:
987 case PTP_RESPONSE_OBJ_WRITEPROTECTED:
988 case PTP_RESPONSE_ACCESSDENIED:
991 case PTP_RESPONSE_OK:
999 response = PTP_RESPONSE_OK;
1001 response = PTP_RESPONSE_PARTIAL_DELETION;
1004 /* LCOV_EXCL_STOP */
1007 mtp_store_t *_device_get_store_containing_obj(mtp_uint32 obj_handle)
1010 mtp_obj_t *obj = NULL;
1011 mtp_store_t *store = NULL;
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);
1022 mtp_store_t *_device_get_store_at_index(mtp_uint32 index)
1024 if (index >= g_device.num_stores) {
1025 ERR("Index not valid");
1029 return &(g_device.store_list[index]);
1032 /* LCOV_EXCL_START */
1033 device_prop_desc_t *_device_get_ref_prop_list(void)
1035 return g_device.device_prop_list;
1038 mtp_bool _device_get_playback_obj(mtp_uint32 *playback_obj)
1040 device_prop_desc_t *device_prop = NULL;
1042 device_prop = _device_get_device_property(MTP_PROPERTYCODE_PLAYBACK_OBJECT);
1043 if (NULL == device_prop) {
1044 ERR("device_prop is NULL");
1047 memcpy(playback_obj, device_prop->current_val.integer,
1048 sizeof(mtp_uint32));
1053 mtp_bool _device_set_playback_obj(mtp_uint32 playback_obj)
1055 device_prop_desc_t *device_prop = NULL;
1056 cmd_container_t event = { 0, };
1058 device_prop = _device_get_device_property(MTP_PROPERTYCODE_PLAYBACK_OBJECT);
1059 if (device_prop == NULL) {
1060 ERR("device_prop is NULL");
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);
1069 /* LCOV_EXCL_STOP */
1071 void _device_get_serial(mtp_char *serial_no, mtp_uint32 len)
1073 ret_if(serial_no == NULL);
1075 _util_utf16_to_utf8(serial_no, len,
1076 g_device.device_info.serial_no.str);
1080 /* LCOV_EXCL_START */
1081 void _device_set_phase(device_phase_t phase)
1083 DBG("Devie phase is set [%d]\n", phase);
1084 g_device.phase = phase;
1088 device_phase_t _device_get_phase(void)
1090 return g_device.phase;
1092 /* LCOV_EXCL_STOP */
1094 mtp_uint32 _device_get_default_store_id(void)
1096 return g_device.default_store_id;
1099 mtp_uint32 _device_get_default_parent_handle(void)
1101 return g_device.default_hparent;
1104 mtp_uint32 _device_get_num_stores(void)
1106 return g_device.num_stores;
1109 /* LCOV_EXCL_START */
1110 device_status_t _device_get_status(void)
1112 return g_device.status;
1114 /* LCOV_EXCL_STOP */
1116 mtp_char *_device_get_device_name(void)
1118 return g_strdup(g_device.device_name);
1121 void _device_set_device_name(mtp_char *dev_name)
1123 ret_if(dev_name == NULL);
1125 g_strlcpy(g_device.device_name, dev_name, sizeof(g_device.device_name));
1129 mtp_char *_device_get_sync_partner(void)
1131 return g_strdup(g_device.sync_partner);
1134 void _device_set_sync_partner(mtp_char *sync_ptr)
1136 ret_if(sync_ptr == NULL);
1138 g_strlcpy(g_device.sync_partner, sync_ptr,
1139 sizeof(g_device.sync_partner));