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 mtp_uint32 _get_device_info_size(void)
411 device_info_t *info = &(g_device.device_info);
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));
436 mtp_uint32 _pack_device_info(mtp_uchar *buf, mtp_uint32 buf_sz)
439 mtp_uchar *ptr = buf;
440 mtp_uint32 count = 0;
441 device_info_t *info = &(g_device.device_info);
443 retv_if(NULL == buf, 0);
445 if (buf_sz < _get_device_info_size()) {
446 ERR("buffer size [%d] is less than device_info Size\n", buf_sz);
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);
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);
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);
469 ptr += _prop_pack_ptpstring(&(info->vendor_extn_desc), ptr,
470 _prop_size_ptpstring(&(info->vendor_extn_desc)));
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);
478 count = (sizeof(g_ops_supported) / sizeof(mtp_uint16));
479 memcpy(ptr, &count, sizeof(count));
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]),
488 #ifdef __BIG_ENDIAN__
489 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
490 #endif /*__BIG_ENDIAN__*/
491 ptr += sizeof(mtp_uint16);
494 count = (sizeof(g_event_supported) / sizeof(mtp_uint16));
495 memcpy(ptr, &count, sizeof(count));
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]),
504 #ifdef __BIG_ENDIAN__
505 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
506 #endif /*__BIG_ENDIAN__*/
507 ptr += sizeof(mtp_uint16);
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]),
519 #ifdef __BIG_ENDIAN__
520 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
521 #endif /*__BIG_ENDIAN__*/
522 ptr += sizeof(mtp_uint16);
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);
532 for (ii = 0; ii < count; ii++) {
533 memcpy(ptr, (void *)&(info->capture_fmts[ii]),
535 #ifdef __BIG_ENDIAN__
536 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
537 #endif /*__BIG_ENDIAN__*/
538 ptr += sizeof(mtp_uint16);
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]),
550 #ifdef __BIG_ENDIAN__
551 _util_conv_byte_order(ptr, sizeof(mtp_uint16));
552 #endif /*__BIG_ENDIAN__*/
553 ptr += sizeof(mtp_uint16);
556 ptr += _prop_pack_ptpstring(&(info->manufacturer), ptr,
557 _prop_size_ptpstring(&(info->manufacturer)));
559 ptr += _prop_pack_ptpstring(&(info->model), ptr,
560 _prop_size_ptpstring(&(info->model)));
562 ptr += _prop_pack_ptpstring(&(info->device_version), ptr,
563 _prop_size_ptpstring(&(info->device_version)));
565 ptr += _prop_pack_ptpstring(&(info->serial_no), ptr,
566 _prop_size_ptpstring(&(info->serial_no)));
568 return (mtp_uint32)(ptr - buf);
571 void _reset_mtp_device(void)
573 _transport_set_control_event(0);
574 _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
576 /* resets device state to ok/Ready */
577 /* reset device phase to idle */
579 g_device.status = DEVICE_STATUSOK;
580 g_device.phase = DEVICE_PHASE_IDLE;
584 device_prop_desc_t *_device_get_device_property(mtp_uint32 prop_code)
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]);
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.
601 static mtp_bool __add_store_to_device(store_type_t store_type)
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 };
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;
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;
620 ERR("Unknown Storage [%d]\n", store_id);
624 if (FALSE == _util_get_file_attrs(storage_path, &attrs)) {
625 ERR("_util_get_file_attrs() Fail");
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);
638 if (g_device.num_stores + 1 > MAX_NUM_DEVICE_STORES) {
639 ERR("reached to max [%d]\n", MAX_NUM_DEVICE_STORES);
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");
649 g_device.num_stores++;
650 g_device.is_mounted[store_type] = TRUE;
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.
661 static mtp_bool __remove_store_from_device(store_type_t store_type)
664 mtp_device_t *device = &g_device;
665 mtp_store_t *store = NULL;
666 mtp_uint32 store_id = 0;
668 switch (store_type) {
669 case MTP_STORAGE_INTERNAL:
670 store_id = MTP_INTERNAL_STORE_ID;
672 case MTP_STORAGE_EXTERNAL:
673 store_id = MTP_EXTERNAL_STORE_ID;
676 ERR("Unknown Storage [%d]\n", store_type);
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;
692 mtp_bool _device_is_store_mounted(mtp_int32 store_type)
694 if (store_type < MTP_STORAGE_INTERNAL ||
695 store_type >= MTP_STORAGE_ALL) {
696 ERR("unknown storage(%d)\n", store_type);
700 return g_device.is_mounted[store_type];
703 mtp_bool _device_install_storage(mtp_int32 type)
705 mtp_int32 int_status = TRUE;
706 mtp_int32 ext_status = TRUE;
708 mtp_bool lock_status;
711 case MTP_ADDREM_AUTO:
712 DBG(" case MTP_ADDREM_AUTO:");
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);
721 mounted = _util_get_local_mmc_status();
722 if (mounted == MTP_PHONE_MMC_INSERTED) {
725 _device_is_store_mounted(MTP_STORAGE_EXTERNAL);
726 if (ext_status == FALSE)
727 __add_store_to_device(MTP_STORAGE_EXTERNAL);
731 case MTP_ADDREM_INTERNAL:
732 DBG("case MTP_ADDREM_INTERNAL:");
733 if (MTP_PHONE_LOCK_OFF != _util_get_local_lock_status())
735 if (FALSE == _device_is_store_mounted(MTP_STORAGE_INTERNAL))
736 __add_store_to_device(MTP_STORAGE_INTERNAL);
739 case MTP_ADDREM_EXTERNAL:
740 DBG(" case MTP_ADDREM_EXTERNAL:");
741 if (MTP_PHONE_MMC_INSERTED != _util_get_local_mmc_status())
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");
753 DBG(" case MTP_ADDREM_ALL:");
754 __add_store_to_device(MTP_STORAGE_INTERNAL);
755 __add_store_to_device(MTP_STORAGE_EXTERNAL);
759 ERR("_device_install_storage : unknown type [%d]\n", type);
766 mtp_bool _device_uninstall_storage(mtp_int32 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);
775 case MTP_ADDREM_INTERNAL:
776 if (TRUE == _device_is_store_mounted(MTP_STORAGE_INTERNAL))
777 __remove_store_from_device(MTP_STORAGE_INTERNAL);
779 case MTP_ADDREM_EXTERNAL:
780 if (TRUE == _device_is_store_mounted(MTP_STORAGE_EXTERNAL))
781 __remove_store_from_device(MTP_STORAGE_EXTERNAL);
784 __remove_store_from_device(MTP_STORAGE_INTERNAL);
785 __remove_store_from_device(MTP_STORAGE_EXTERNAL);
788 ERR("unknown mode [%d]\n", type);
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.
802 static mtp_err_t __clear_store_data(mtp_uint32 store_id)
805 mtp_store_t *store = NULL;
806 mtp_uint32 count = g_device.num_stores;
808 for (idx = 0; idx < count; idx++) {
809 if (g_device.store_list[idx].store_id == store_id) {
811 _entity_destroy_mtp_store(&(g_device.store_list[idx]));
813 store = &(g_device.store_list[idx]);
815 store->is_hidden = FALSE;
816 g_free(store->root_path);
817 store->root_path = NULL;
819 for (; idx < count - 1; idx++) {
820 _entity_copy_store_data(&(g_device.store_list[idx]),
821 &(g_device.store_list[idx + 1]));
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));
829 /*Initialize the destroyed store*/
830 g_device.num_stores--;
831 return MTP_ERROR_NONE;
834 return MTP_ERROR_GENERAL;
837 mtp_store_t *_device_get_store(mtp_uint32 store_id)
840 mtp_store_t *store = NULL;
842 for (ii = 0; ii < g_device.num_stores; ii++) {
844 store = &(g_device.store_list[ii]);
845 if (store->store_id == store_id)
851 mtp_uint32 _device_get_store_ids(ptp_array_t *store_ids)
853 mtp_store_t *store = NULL;
856 for (ii = g_device.num_stores - 1; ii >= 0; ii--) {
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);
862 return store_ids->num_ele;
865 mtp_uint32 _device_get_num_objects(mtp_uint32 store_id)
867 mtp_uint32 num_objs = 0;
868 mtp_store_t *store = NULL;
871 for (ii = 0; ii < g_device.num_stores; ii++) {
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;
883 mtp_uint32 _device_get_num_objects_with_format(mtp_uint32 store_id,
886 mtp_uint32 num_objs = 0;
887 mtp_store_t *store = NULL;
890 for (ii = 0; ii < g_device.num_stores; ii++) {
892 store = &(g_device.store_list[ii]);
893 if ((store->store_id != store_id) &&
894 (store_id != PTP_STORAGEID_ALL)) {
897 num_objs += _entity_get_num_object_with_same_format(store,
904 mtp_obj_t *_device_get_object_with_handle(mtp_uint32 obj_handle)
907 mtp_obj_t *obj = NULL;
908 mtp_store_t *store = NULL;
910 for (ii = 0; ii < g_device.num_stores; ii++) {
912 store = &(g_device.store_list[ii]);
913 obj = _entity_get_object_from_store(store, obj_handle);
921 mtp_obj_t* _device_get_object_with_path(mtp_char *full_path)
924 mtp_obj_t *obj = NULL;
925 mtp_store_t *store = NULL;
927 retv_if(NULL == full_path, NULL);
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);
939 mtp_uint16 _device_delete_object(mtp_uint32 obj_handle, mtp_uint32 fmt)
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;
947 if (PTP_OBJECTHANDLE_ALL != obj_handle) {
948 store = _device_get_store_containing_obj(obj_handle);
950 response = PTP_RESPONSE_INVALID_OBJ_HANDLE;
952 response = _entity_delete_obj_mtp_store(store,
953 obj_handle, fmt, TRUE);
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,
963 case PTP_RESPONSE_STORE_READONLY:
966 case PTP_RESPONSE_PARTIAL_DELETION:
970 case PTP_RESPONSE_OBJ_WRITEPROTECTED:
971 case PTP_RESPONSE_ACCESSDENIED:
974 case PTP_RESPONSE_OK:
982 response = PTP_RESPONSE_OK;
984 response = PTP_RESPONSE_PARTIAL_DELETION;
989 mtp_store_t *_device_get_store_containing_obj(mtp_uint32 obj_handle)
992 mtp_obj_t *obj = NULL;
993 mtp_store_t *store = NULL;
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);
1004 mtp_store_t *_device_get_store_at_index(mtp_uint32 index)
1006 if (index >= g_device.num_stores) {
1007 ERR("Index not valid");
1011 return &(g_device.store_list[index]);
1014 device_prop_desc_t *_device_get_ref_prop_list(void)
1016 return g_device.device_prop_list;
1019 mtp_bool _device_get_playback_obj(mtp_uint32 *playback_obj)
1021 device_prop_desc_t *device_prop = NULL;
1023 device_prop = _device_get_device_property(MTP_PROPERTYCODE_PLAYBACK_OBJECT);
1024 if (NULL == device_prop) {
1025 ERR("device_prop is NULL");
1028 memcpy(playback_obj, device_prop->current_val.integer,
1029 sizeof(mtp_uint32));
1034 mtp_bool _device_set_playback_obj(mtp_uint32 playback_obj)
1036 device_prop_desc_t *device_prop = NULL;
1037 cmd_container_t event = { 0, };
1039 device_prop = _device_get_device_property(MTP_PROPERTYCODE_PLAYBACK_OBJECT);
1040 if (device_prop == NULL) {
1041 ERR("device_prop is NULL");
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);
1051 void _device_get_serial(mtp_char *serial_no, mtp_uint32 len)
1053 ret_if(serial_no == NULL);
1055 _util_utf16_to_utf8(serial_no, len,
1056 g_device.device_info.serial_no.str);
1060 void _device_set_phase(device_phase_t phase)
1062 DBG("Devie phase is set [%d]\n", phase);
1063 g_device.phase = phase;
1067 device_phase_t _device_get_phase(void)
1069 return g_device.phase;
1072 mtp_uint32 _device_get_default_store_id(void)
1074 return g_device.default_store_id;
1077 mtp_uint32 _device_get_default_parent_handle(void)
1079 return g_device.default_hparent;
1082 mtp_uint32 _device_get_num_stores(void)
1084 return g_device.num_stores;
1087 device_status_t _device_get_status(void)
1089 return g_device.status;
1092 mtp_char *_device_get_device_name(void)
1094 return g_strdup(g_device.device_name);
1097 void _device_set_device_name(mtp_char *dev_name)
1099 ret_if(dev_name == NULL);
1101 g_strlcpy(g_device.device_name, dev_name, sizeof(g_device.device_name));
1105 mtp_char *_device_get_sync_partner(void)
1107 return g_strdup(g_device.sync_partner);
1110 void _device_set_sync_partner(mtp_char *sync_ptr)
1112 ret_if(sync_ptr == NULL);
1114 g_strlcpy(g_device.sync_partner, sync_ptr,
1115 sizeof(g_device.sync_partner));