Sync code with Tizen 3.0 branch
[platform/core/connectivity/mtp-responder.git] / src / entity / mtp_property.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 <glib.h>
18 #include "mtp_property.h"
19 #include "mtp_media_info.h"
20 #include "mtp_support.h"
21 #include "mtp_transport.h"
22
23 /*
24  * EXTERN AND GLOBAL VARIABLES
25  */
26 obj_interdep_proplist_t interdep_proplist;
27 /*
28  * STATIC VARIABLES
29  */
30 static obj_prop_desc_t props_list_mp3[NUM_OBJECT_PROP_DESC_MP3];
31 static obj_prop_desc_t props_list_wma[NUM_OBJECT_PROP_DESC_WMA];
32 static obj_prop_desc_t props_list_wmv[NUM_OBJECT_PROP_DESC_WMV];
33 static obj_prop_desc_t props_list_album[NUM_OBJECT_PROP_DESC_ALBUM];
34 static obj_prop_desc_t props_list_default[NUM_OBJECT_PROP_DESC_DEFAULT];
35
36 /*
37  * STATIC FUNCTIONS
38  */
39 static mtp_uint16 __get_ptp_array_elem_size(data_type_t type);
40 static mtp_bool __check_object_propcode(obj_prop_desc_t *prop,
41                 mtp_uint32 propcode, mtp_uint32 group_code);
42 static mtp_bool __create_prop_integer(mtp_obj_t *obj,
43                 mtp_uint16 propcode, mtp_uint64 value);
44 static mtp_bool __create_prop_string(mtp_obj_t *obj, mtp_uint16 propcode,
45                 mtp_wchar *value);
46 static mtp_bool __create_prop_array(mtp_obj_t *obj, mtp_uint16 propcode,
47                 mtp_char *arr, mtp_uint32 size);
48 #ifdef MTP_SUPPORT_PROPERTY_SAMPLE
49 static mtp_bool __create_prop_sample(mtp_obj_t *obj);
50 static void __build_supported_sample_props(mtp_uchar *count,
51                 obj_prop_desc_t *prop);
52 #endif /*MTP_SUPPORT_PROPERTY_SAMPLE*/
53 static mtp_bool __update_prop_values_audio(mtp_obj_t *obj);
54 static mtp_bool __update_prop_values_video(mtp_obj_t *obj);
55 static mtp_bool __update_prop_values_image(mtp_obj_t *obj);
56 static mtp_bool __prop_common_metadata(mtp_obj_t *obj,
57                 common_meta_t *p_metata);
58 static void __build_supported_common_props(mtp_uchar *count,
59                 obj_prop_desc_t *prop);
60 /* PtpString Functions */
61 #ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
62 static ptp_string_t *__alloc_ptpstring(void);
63 #else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
64 static ptp_string_t *__alloc_ptpstring(mtp_uint32 size);
65 #endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
66 static void __init_obj_propval(obj_prop_val_t *val, obj_prop_desc_t *prop);
67 static void __init_ptptimestring(ptp_time_string_t *pstring);
68 static mtp_uint32 __size_curval_device_prop(device_prop_desc_t *prop);
69 static void __init_obj_prop_desc(obj_prop_desc_t *prop, mtp_uint16 propcode,
70                 mtp_uint16 data_type, mtp_uchar get_set, mtp_uchar form_flag,
71                 mtp_uint32 group_code);
72 static mtp_uint32 __get_size_default_val_obj_prop_desc(obj_prop_desc_t *prop);
73 static void __destroy_obj_prop_desc(obj_prop_desc_t *prop);
74 static mtp_uint32 __count_obj_proplist(obj_proplist_t *plist);
75 static mtp_bool __append_obj_proplist(obj_proplist_t *prop_list, mtp_uint32 obj_handle,
76                 mtp_uint16 prop_code, mtp_uint32 data_type, mtp_uchar *val);
77 #ifdef MTP_SUPPORT_INTERDEPENDENTPROP
78 static mtp_bool __append_interdep_prop(interdep_prop_config_t *config,
79                 obj_prop_desc_t *prop);
80 #endif /* MTP_SUPPORT_INTERDEPENDENTPROP */
81 static mtp_uint32 __count_interdep_proplist(obj_interdep_proplist_t *config_list,
82                 mtp_uint32 format_code);
83 /*
84  * FUNCTIONS
85  */
86 static mtp_bool __check_object_propcode(obj_prop_desc_t *prop,
87                 mtp_uint32 propcode, mtp_uint32 group_code)
88 {
89         if ((prop->propinfo.prop_code == propcode) ||
90                         ((propcode == PTP_PROPERTY_ALL) &&
91                          !(prop->group_code & GROUP_CODE_SLOW)) ||
92                         ((propcode == PTP_PROPERTY_UNDEFINED) &&
93                          (prop->group_code & group_code))) {
94                 return TRUE;
95         }
96
97         return FALSE;
98 }
99
100 static mtp_bool __create_prop_integer(mtp_obj_t *obj,
101                 mtp_uint16 propcode, mtp_uint64 value)
102 {
103         obj_prop_desc_t *prop = NULL;
104         obj_prop_val_t *prop_val = NULL;
105         mtp_uint32 fmt_code = obj->obj_info->obj_fmt;
106
107         retv_if(obj == NULL, FALSE);
108         retv_if(obj->obj_info == NULL, FALSE);
109
110         prop = _prop_get_obj_prop_desc(fmt_code, propcode);
111         if (NULL == prop) {
112                 ERR("Create property Fail.. Prop = [0x%X]\n", propcode);
113                 return FALSE;
114         }
115
116         propvalue_alloc_and_check(prop_val);
117         _prop_set_current_integer_val(prop_val, value);
118         node_alloc_and_append();
119
120         return TRUE;
121 }
122
123 static mtp_bool __create_prop_string(mtp_obj_t *obj, mtp_uint16 propcode,
124                 mtp_wchar *value)
125 {
126         ptp_string_t ptp_str = {0};
127         obj_prop_desc_t *prop = NULL;
128         obj_prop_val_t *prop_val = NULL;
129         mtp_uint32 fmt_code = obj->obj_info->obj_fmt;
130
131         retv_if(obj == NULL, FALSE);
132         retv_if(obj->obj_info == NULL, FALSE);
133
134         prop = _prop_get_obj_prop_desc(fmt_code, propcode);
135         if (NULL == prop) {
136                 ERR("Create property Fail.. Prop = [0x%X]\n", propcode);
137                 return FALSE;
138         }
139
140         propvalue_alloc_and_check(prop_val);
141         _prop_copy_char_to_ptpstring(&ptp_str, value, WCHAR_TYPE);
142         _prop_set_current_string_val(prop_val, &ptp_str);
143         node_alloc_and_append();
144
145         return TRUE;
146 }
147
148 static mtp_bool __create_prop_timestring(mtp_obj_t *obj,
149         mtp_uint32 propcode, ptp_time_string_t *value)
150 {
151         obj_prop_desc_t *prop = NULL;
152         obj_prop_val_t *prop_val = NULL;
153         mtp_uint32 fmt_code = obj->obj_info->obj_fmt;
154
155         retv_if(obj == NULL, FALSE);
156         retv_if(obj->obj_info == NULL, FALSE);
157
158         prop = _prop_get_obj_prop_desc(fmt_code, propcode);
159         if (NULL == prop) {
160                 ERR("Create property Fail.. Prop = [0x%X]\n", propcode);
161                 return FALSE;
162         }
163
164         propvalue_alloc_and_check(prop_val);
165         _prop_set_current_string_val(prop_val, (ptp_string_t *)value);
166         node_alloc_and_append();
167
168         return TRUE;
169 }
170
171 static mtp_bool __create_prop_array(mtp_obj_t *obj, mtp_uint16 propcode,
172                 mtp_char *arr, mtp_uint32 size)
173 {
174         obj_prop_desc_t *prop = NULL;
175         obj_prop_val_t *prop_val = NULL;
176         mtp_uint32 fmt_code = obj->obj_info->obj_fmt;
177
178         retv_if(obj == NULL, FALSE);
179         retv_if(obj->obj_info == NULL, FALSE);
180
181         prop = _prop_get_obj_prop_desc(fmt_code, propcode);
182         if (NULL == prop) {
183                 ERR("Create property Fail.. Prop = [0x%X]\n", propcode);
184                 return FALSE;
185         }
186
187         propvalue_alloc_and_check(prop_val);
188         _prop_set_current_array_val(prop_val, (mtp_uchar *)arr, size);
189         node_alloc_and_append();
190
191         return TRUE;
192 }
193
194 static mtp_bool __update_prop_values_audio(mtp_obj_t *obj)
195 {
196         mtp_bool success = TRUE;
197         mtp_int32 converted_rating = 0;
198         comp_audio_meta_t audio_data = {{0}, {0} };
199
200         retv_if(obj == NULL, FALSE);
201         retv_if(obj->obj_info == NULL, FALSE);
202
203         if (_util_get_audio_metadata(obj->file_path, &audio_data) == FALSE) {
204                 if (_util_get_audio_meta_from_extractor(obj->file_path,
205                                         &audio_data) == FALSE) {
206                         success = FALSE;
207                         goto DONE;
208                 }
209         }
210
211         /*Update common metadata information*/
212         if (FALSE == __prop_common_metadata(obj,
213                                 &(audio_data.commonmeta))) {
214                 ERR("Common  metadata update Fail");
215                 success = FALSE;
216                 goto DONE;
217         }
218
219
220         /*--------------TRACK--------------*/
221         if (FALSE == __create_prop_integer(obj,
222                                 MTP_OBJ_PROPERTYCODE_TRACK, audio_data.audiometa.track)) {
223                 success = FALSE;
224                 goto DONE;
225         }
226
227         /*--------------USER RATING--------------*/
228         /* DCM rating -> MTP (WMP) rating */
229         switch (audio_data.commonmeta.rating) {
230         case 1:
231                 converted_rating = 1;   /* 1-12 */
232                 break;
233         case 2:
234                 converted_rating = 25;  /* 13-37 */
235                 break;
236         case 3:
237                 converted_rating = 50;  /* 37-62 */
238                 break;
239         case 4:
240                 converted_rating = 75;  /* 63-86 */
241                 break;
242         case 5:
243                 converted_rating = 99;  /* 87-100 */
244                 break;
245         default:
246                 converted_rating = 0;   /* otherwise */
247                 break;
248         }
249
250         if (FALSE == __create_prop_integer(obj,
251                                 MTP_OBJ_PROPERTYCODE_USERRATING, converted_rating)) {
252                 success = FALSE;
253                 goto DONE;
254
255         }
256
257         /*-------------AUDIOWAVECODEC--------------*/
258         if (FALSE == __create_prop_integer(obj,
259                                 MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC,
260                                 MTP_WAVEFORMAT_UNKNOWN)) {
261                 success = FALSE;
262                 goto DONE;
263         }
264
265 DONE:
266         _util_free_common_meta(&(audio_data.commonmeta));
267         return success;
268 }
269
270 static mtp_bool __update_prop_values_video(mtp_obj_t *obj)
271 {
272         mtp_bool success = TRUE;
273         mtp_int32 converted_rating = 0;
274         comp_video_meta_t video_data = { {0,}, {0,} };
275         video_meta_t *viddata = &(video_data.videometa);
276         mtp_wchar buf[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
277
278         retv_if(obj == NULL, FALSE);
279         retv_if(obj->obj_info == NULL, FALSE);
280         retv_if(obj->file_path == NULL, FALSE);
281
282         if (_util_get_video_metadata(obj->file_path, &video_data) == FALSE) {
283                 if (_util_get_video_meta_from_extractor(obj->file_path,
284                                         &video_data) == FALSE) {
285                         success = FALSE;
286                         goto DONE;
287                 }
288         }
289
290         /*Update common metadata information*/
291         if (FALSE == __prop_common_metadata(obj,
292                                 &(video_data.commonmeta))) {
293                 ERR("Common  metadata update Fail");
294                 success = FALSE;
295                 goto DONE;
296         }
297
298         /*--------------TRACK--------------*/
299         if ((viddata->track != NULL) && strlen(viddata->track) > 0) {
300                 if (FALSE == __create_prop_integer(obj,
301                                         MTP_OBJ_PROPERTYCODE_TRACK,
302                                         atoi(viddata->track))) {
303                         success = FALSE;
304                         goto DONE;
305                 }
306         }
307
308         /*--------------AUDIO WAVE CODEC--------------*/
309         if (FALSE == __create_prop_integer(obj,
310                                 MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC, 0)) {
311                 success = FALSE;
312                 goto DONE;
313         }
314
315         /*--------------VIDEO CODEC--------------*/
316         /*
317          * Conversion needs to be decided from audio_codec to
318          * exact format by spec
319          */
320         if (FALSE == __create_prop_integer(obj,
321                                 MTP_OBJ_PROPERTYCODE_VIDEOFOURCCCODEC, 0)) {
322                 success = FALSE;
323                 goto DONE;
324         }
325
326         /*--------------VIDEO FRAMES PER 1K SECONDS--------------*/
327         if (FALSE == __create_prop_integer(obj,
328                                 MTP_OBJ_PROPERTYCODE_FRAMESPER1KSECONDS,
329                                 viddata->video_fps * 1000)) {
330                 success = FALSE;
331                 goto DONE;
332         }
333
334         /*--------------VIDEO BITRATE--------------*/
335         if (FALSE == __create_prop_integer(obj,
336                                 MTP_OBJ_PROPERTYCODE_VIDEOBITRATE,
337                                 viddata->video_br)) {
338                 success = FALSE;
339                 goto DONE;
340         }
341
342         /*--------------VIDEO WIDTH--------------*/
343         if (FALSE == __create_prop_integer(obj,
344                                 MTP_OBJ_PROPERTYCODE_WIDTH, viddata->video_w)) {
345                 success = FALSE;
346                 goto DONE;
347         }
348
349         /*--------------VIDEO HEIGHT--------------*/
350         if (FALSE == __create_prop_integer(obj,
351                                 MTP_OBJ_PROPERTYCODE_HEIGHT, viddata->video_h)) {
352                 success = FALSE;
353                 goto DONE;
354         }
355
356         /*--------------USER RATING--------------*/
357         switch (video_data.commonmeta.rating) {
358         case 1:
359                 converted_rating = 1;   /* 1-12 */
360                 break;
361         case 2:
362                 converted_rating = 25;  /* 13-37 */
363                 break;
364         case 3:
365                 converted_rating = 50;  /* 37-62 */
366                 break;
367         case 4:
368                 converted_rating = 75;  /* 63-86 */
369                 break;
370         case 5:
371                 converted_rating = 99;  /* 87-100 */
372                 break;
373         default:
374                 converted_rating = 0;   /* otherwise */
375                 break;
376         }
377
378         if (FALSE == __create_prop_integer(obj,
379                                 MTP_OBJ_PROPERTYCODE_USERRATING, converted_rating)) {
380                 success = FALSE;
381                 goto DONE;
382         }
383
384         /*----------ENCODING PROFILE----------*/
385         _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ, "");
386         if (FALSE == __create_prop_string(obj,
387                                 MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO, buf)) {
388                 success = FALSE;
389                 goto DONE;
390         }
391
392         /*----------METAGENRE-----------*/
393         if (FALSE == __create_prop_integer(obj,
394                                 MTP_OBJ_PROPERTYCODE_METAGENRE, 0x00)) {
395                 success = FALSE;
396                 goto DONE;
397         }
398
399         /*---------SCAN TYPE---------*/
400         if (FALSE == __create_prop_integer(obj,
401                                 MTP_OBJ_PROPERTYCODE_SCANTYPE, 0x00)) {
402                 success = FALSE;
403                 goto DONE;
404         }
405
406 DONE:
407         _util_free_common_meta(&(video_data.commonmeta));
408         _util_free_video_meta(&(video_data.videometa));
409         return success;
410 }
411
412 static mtp_bool __update_prop_values_image(mtp_obj_t *obj)
413 {
414         image_meta_t image_data;
415
416         retv_if(obj == NULL, FALSE);
417         retv_if(obj->obj_info == NULL, FALSE);
418
419         if (_util_get_image_ht_wt(obj->file_path, &image_data) == FALSE)
420                 return FALSE;
421
422         /*--------------IMAGE WIDTH--------------*/
423         if (FALSE == __create_prop_integer(obj, MTP_OBJ_PROPERTYCODE_WIDTH,
424                                 image_data.wt))
425                 return FALSE;
426
427         /*--------------IMAGE HEIGHT--------------*/
428         if (FALSE == __create_prop_integer(obj, MTP_OBJ_PROPERTYCODE_HEIGHT,
429                                 image_data.ht))
430                 return FALSE;
431
432         return TRUE;
433 }
434
435 static mtp_bool __prop_common_metadata(mtp_obj_t *obj,
436                 common_meta_t *p_metata)
437 {
438         mtp_wchar buf[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
439
440         /*--------------ARTIST--------------*/
441         if (p_metata->artist != NULL && strlen(p_metata->artist) > 0) {
442                 _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
443                                 p_metata->artist);
444         }
445 #ifdef MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN
446         else {
447                 DBG("got null artist");
448                 _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
449                                 MTP_UNKNOWN_METADATA);
450         }
451 #endif /*MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN*/
452
453         if (FALSE == __create_prop_string(obj,
454                                 MTP_OBJ_PROPERTYCODE_ARTIST, buf)) {
455                 return FALSE;
456         }
457
458         /*--------------ALBUM--------------*/
459         if (p_metata->album != NULL && strlen(p_metata->album) > 0) {
460                 _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
461                                 p_metata->album);
462         }
463 #ifdef MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN
464         else {
465                 DBG("got null album");
466                 _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
467                                 MTP_UNKNOWN_METADATA);
468         }
469 #endif /*MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN*/
470
471         if (FALSE == __create_prop_string(obj,
472                                 MTP_OBJ_PROPERTYCODE_ALBUMNAME, buf)) {
473                 return FALSE;
474         }
475
476         /*--------------GENRE--------------*/
477         if (p_metata->genre != NULL && strlen(p_metata->genre) > 0) {
478                 _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
479                                 p_metata->genre);
480         }
481 #ifdef MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN
482         else {
483                 DBG("got null genre");
484                 _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
485                                 MTP_UNKNOWN_METADATA);
486         }
487 #endif /*MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN*/
488
489         if (FALSE == __create_prop_string(obj,
490                                 MTP_OBJ_PROPERTYCODE_GENRE, buf)) {
491                 return FALSE;
492         }
493
494         /*--------------AUTHOR--------------*/
495         if (p_metata->author != NULL && strlen(p_metata->author) > 0) {
496                 _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
497                                 p_metata->author);
498         }
499 #ifdef MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN
500         else {
501                 DBG("got null author");
502                 _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
503                                 MTP_UNKNOWN_METADATA);
504         }
505 #endif /*MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN*/
506
507         if (FALSE == __create_prop_string(obj,
508                                 MTP_OBJ_PROPERTYCODE_COMPOSER, buf)) {
509                 return FALSE;
510         }
511
512         /*--------------COPYRIGHT--------------*/
513         if ((p_metata->copyright != NULL) && strlen(p_metata->copyright) > 0) {
514                 _util_utf8_to_utf16(buf,
515                                 sizeof(buf) / WCHAR_SIZ,
516                                 p_metata->copyright);
517         } else {
518                 _util_utf8_to_utf16(buf,
519                                 sizeof(buf) / WCHAR_SIZ, "");
520         }
521
522         if (FALSE == __create_prop_string(obj,
523                                 MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO, buf)) {
524                 return FALSE;
525         }
526
527         /*--------------DURATION--------------*/
528         if (FALSE == __create_prop_integer(obj,
529                                 MTP_OBJ_PROPERTYCODE_DURATION, p_metata->duration)) {
530                 return FALSE;
531         }
532
533         /*--------------AUDIO BITRATE--------------*/
534         if (FALSE == __create_prop_integer(obj,
535                                 MTP_OBJ_PROPERTYCODE_AUDIOBITRATE, p_metata->audio_bitrate)) {
536                 return FALSE;
537         }
538
539         /*--------------RELEASE YEAR--------------*/
540         if ((p_metata->year != NULL) && strlen(p_metata->year) > 0) {
541                 _util_utf8_to_utf16(buf,
542                                 sizeof(buf) / WCHAR_SIZ,
543                                 p_metata->year);
544         } else {
545                 _util_utf8_to_utf16(buf,
546                                 sizeof(buf) / WCHAR_SIZ, "");
547         }
548
549         if (FALSE == __create_prop_string(obj,
550                                 MTP_OBJ_PROPERTYCODE_ORIGINALRELEASEDATE, buf)) {
551                 return FALSE;
552         }
553
554         /*--------------DESCRIPTION--------------*/
555         if ((p_metata->description != NULL) &&
556                         strlen(p_metata->description) > 0) {
557                 _util_utf8_to_utf16(buf,
558                                 sizeof(buf) / WCHAR_SIZ,
559                                 p_metata->description);
560         } else {
561                 _util_utf8_to_utf16(buf,
562                                 sizeof(buf) / WCHAR_SIZ, "");
563         }
564
565         if (FALSE == __create_prop_string(obj,
566                                 MTP_OBJ_PROPERTYCODE_DESCRIPTION, buf)) {
567                 return FALSE;
568         }
569
570         /*--------------SAMPLE RATE--------------*/
571         if (FALSE == __create_prop_integer(obj,
572                                 MTP_OBJ_PROPERTYCODE_SAMPLERATE, p_metata->sample_rate)) {
573                 return FALSE;
574         }
575
576         /*-------------NUMBEROFCHANNELS--------------*/
577         if (FALSE == __create_prop_integer(obj,
578                                 MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS, p_metata->num_channel)) {
579                 return FALSE;
580         }
581
582         return TRUE;
583 }
584
585 static void __build_supported_common_props(mtp_uchar *count,
586                 obj_prop_desc_t *prop)
587 {
588         mtp_uchar i = 0;
589         mtp_wchar str[MTP_MAX_REG_STRING + 1] = { 0 };
590         mtp_uint32 default_val;
591
592         _util_utf8_to_utf16(str, sizeof(str) / WCHAR_SIZ, "");
593
594         /*
595          * MTP_OBJ_PROPERTYCODE_ARTIST (1)
596          */
597         __init_obj_prop_desc((prop + i),
598                         MTP_OBJ_PROPERTYCODE_ARTIST,
599                         PTP_DATATYPE_STRING,
600                         PTP_PROPGETSET_GETONLY,
601                         NONE,
602                         MTP_PROP_GROUPCODE_OBJECT);
603         _prop_set_default_string(&(prop[i].propinfo), str);
604         i++;
605
606         /*
607          * MTP_OBJ_PROPERTYCODE_DURATION (2)
608          */
609         __init_obj_prop_desc((prop + i),
610                         MTP_OBJ_PROPERTYCODE_DURATION,
611                         PTP_DATATYPE_UINT32,
612                         PTP_PROPGETSET_GETONLY,
613                         RANGE_FORM,
614                         MTP_PROP_GROUPCODE_OBJECT);
615
616         default_val = 0x0;
617         _prop_set_range_integer(&(prop[i].propinfo), 0, 0xffffffff, 1L);
618         _prop_set_default_integer(&((prop[i].propinfo)), (mtp_uchar *) &default_val);
619         i++;
620
621         /*
622          * MTP_OBJ_PROPERTYCODE_USERRATING (3)
623          */
624         __init_obj_prop_desc((prop + i),
625                         MTP_OBJ_PROPERTYCODE_USERRATING,
626                         PTP_DATATYPE_UINT16,
627                         PTP_PROPGETSET_GETONLY,
628                         RANGE_FORM,
629                         MTP_PROP_GROUPCODE_OBJECT);
630
631         default_val = 0x0;
632         _prop_set_range_integer(&(prop[i].propinfo), 0, 100, 1L);
633         _prop_set_default_integer(&(prop[i].propinfo),
634                         (mtp_uchar *) &default_val);
635         i++;
636
637         /*
638          * MTP_OBJ_PROPERTYCODE_TRACK (4)
639          */
640         __init_obj_prop_desc((prop + i),
641                         MTP_OBJ_PROPERTYCODE_TRACK,
642                         PTP_DATATYPE_UINT16,
643                         PTP_PROPGETSET_GETONLY,
644                         NONE,
645                         MTP_PROP_GROUPCODE_OBJECT);
646
647         default_val = 0x0;
648         _prop_set_default_integer(&(prop[i].propinfo),
649                         (mtp_uchar *) &default_val);
650         i++;
651
652         /*
653          * MTP_OBJ_PROPERTYCODE_GENRE (5)
654          */
655         __init_obj_prop_desc((prop + i),
656                         MTP_OBJ_PROPERTYCODE_GENRE,
657                         PTP_DATATYPE_STRING,
658                         PTP_PROPGETSET_GETONLY,
659                         NONE,
660                         MTP_PROP_GROUPCODE_OBJECT);
661         _prop_set_default_string(&(prop[i].propinfo), str);
662         i++;
663
664         /*
665          * MTP_OBJ_PROPERTYCODE_ORIGINALRELEASEDATE (6)
666          */
667         __init_obj_prop_desc((prop + i),
668                         MTP_OBJ_PROPERTYCODE_ORIGINALRELEASEDATE,
669                         PTP_DATATYPE_STRING,
670                         PTP_PROPGETSET_GETONLY,
671                         DATE_TIME_FORM,
672                         MTP_PROP_GROUPCODE_OBJECT);
673         _prop_set_default_string(&(prop[i].propinfo), str);
674         i++;
675
676         /*
677          * MTP_OBJ_PROPERTYCODE_ALBUMNAME (7)
678          */
679         __init_obj_prop_desc((prop + i),
680                         MTP_OBJ_PROPERTYCODE_ALBUMNAME,
681                         PTP_DATATYPE_STRING,
682                         PTP_PROPGETSET_GETONLY,
683                         NONE,
684                         MTP_PROP_GROUPCODE_OBJECT);
685         _prop_set_default_string(&(prop[i].propinfo), str);
686         i++;
687
688         /*
689          * MTP_OBJ_PROPERTYCODE_COMPOSER (8)
690          */
691         __init_obj_prop_desc((prop + i),
692                         MTP_OBJ_PROPERTYCODE_COMPOSER,
693                         PTP_DATATYPE_STRING,
694                         PTP_PROPGETSET_GETONLY,
695                         NONE,
696                         MTP_PROP_GROUPCODE_OBJECT);
697         _prop_set_default_string(&(prop[i].propinfo), str);
698         i++;
699
700         *count += i;
701
702         return;
703 }
704
705 /* PTP Array Functions */
706 void _prop_init_ptparray(ptp_array_t *parray, data_type_t type)
707 {
708         mtp_uint16 size = 0;
709         parray->num_ele = 0;
710         parray->type = type;
711
712         size = __get_ptp_array_elem_size(type);
713         if (size == 0)
714                 return;
715
716         parray->array_entry = g_malloc(size * INITIAL_ARRAY_SIZE);
717         if (parray->array_entry == NULL) {
718                 parray->arr_size = 0;
719         } else {
720                 parray->arr_size = INITIAL_ARRAY_SIZE;
721                 memset(parray->array_entry, 0, size * INITIAL_ARRAY_SIZE);
722         }
723         return;
724 }
725
726 ptp_array_t *_prop_alloc_ptparray(data_type_t type)
727 {
728         ptp_array_t *parray;
729         parray = (ptp_array_t *)g_malloc(sizeof(ptp_array_t));
730         if (parray != NULL)
731                 _prop_init_ptparray(parray, type);
732
733         return (parray);
734 }
735
736 mtp_uint32 _prop_get_size_ptparray(ptp_array_t *parray)
737 {
738         mtp_uint16 size = 0;
739
740         if (parray == NULL) {
741                 ERR("ptp_array_t is NULL");
742                 return 0;
743         }
744
745         size = __get_ptp_array_elem_size(parray->type);
746         if (size == 0)
747                 return 0;
748
749         return (sizeof(mtp_uint32) + (size *parray->num_ele));
750 }
751
752 mtp_uint32 _prop_get_size_ptparray_without_elemsize(ptp_array_t *parray)
753 {
754         mtp_uint16 size = 0;
755
756         size = __get_ptp_array_elem_size(parray->type);
757         if (size == 0)
758                 return 0;
759
760         return (size * parray->num_ele);
761 }
762
763 mtp_bool _prop_grow_ptparray(ptp_array_t *parray, mtp_uint32 new_size)
764 {
765         mtp_uint16 size = 0;
766
767         size = __get_ptp_array_elem_size(parray->type);
768         if (size == 0)
769                 return FALSE;
770
771         if (parray->arr_size == 0)
772                 _prop_init_ptparray(parray, parray->type);
773
774         if (new_size < parray->arr_size)
775                 return TRUE;
776
777         parray->array_entry =
778                 g_realloc(parray->array_entry, size * new_size);
779         if (parray->array_entry == NULL) {
780                 parray->arr_size = 0;
781                 return FALSE;
782         }
783         parray->arr_size = new_size;
784
785         return TRUE;
786 }
787
788 mtp_int32 _prop_find_ele_ptparray(ptp_array_t *parray, mtp_uint32 element)
789 {
790         mtp_uchar *ptr8 = NULL;
791         mtp_uint16 *ptr16 = NULL;
792         mtp_uint32 *ptr32 = NULL;
793         mtp_int32 ii;
794
795         retv_if(parray->array_entry == NULL, ELEMENT_NOT_FOUND);
796
797         switch (parray->type) {
798         case UINT8_TYPE:
799                 ptr8 = parray->array_entry;
800                 for (ii = 0; ii < parray->num_ele; ii++) {
801                         if (ptr8[ii] == (mtp_uchar) element)
802                                 return ii;
803                 }
804                 break;
805
806         case UINT16_TYPE:
807                 ptr16 = parray->array_entry;
808                 for (ii = 0; ii < parray->num_ele; ii++) {
809                         if (ptr16[ii] == (mtp_uint16) element)
810                                 return ii;
811                 }
812                 break;
813
814         case PTR_TYPE:
815         case UINT32_TYPE:
816                 ptr32 = parray->array_entry;
817                 for (ii = 0; ii < parray->num_ele; ii++) {
818                         if (ptr32[ii] == (mtp_uint32)element)
819                                 return ii;
820                 }
821                 break;
822
823         default:
824                 break;
825         }
826         return ELEMENT_NOT_FOUND;
827 }
828
829 mtp_bool _prop_get_ele_ptparray(ptp_array_t *parray, mtp_uint32 index, void *ele)
830 {
831         mtp_uchar *ptr8 = NULL;
832         mtp_uint16 *ptr16 = NULL;
833         mtp_uint32 *ptr32 = NULL;
834
835         retv_if(parray->array_entry == NULL, FALSE);
836
837         if (index >= parray->num_ele)
838                 return FALSE;
839
840         switch (parray->type) {
841         case UINT8_TYPE:
842                 ptr8 = parray->array_entry;
843                 *((mtp_uchar *)ele) = ptr8[index];
844                 break;
845         case UINT16_TYPE:
846                 ptr16 = parray->array_entry;
847                 *((mtp_uint16 *)ele) = ptr16[index];
848                 break;
849
850         case PTR_TYPE:
851         case UINT32_TYPE:
852                 ptr32 = parray->array_entry;
853                 *((mtp_uint32 *)ele) = ptr32[index];
854                 break;
855         default:
856                 return FALSE;
857         }
858         return TRUE;
859 }
860
861 mtp_bool _prop_append_ele_ptparray(ptp_array_t *parray, mtp_uint32 element)
862 {
863
864         mtp_uchar *ptr8 = NULL;
865         mtp_uint16 *ptr16 = NULL;
866         mtp_uint32 *ptr32 = NULL;
867
868         if (parray->num_ele >= parray->arr_size) {
869                 ERR("parray->num_ele [%d] is bigger than parray->arr_size [%d]\n",
870                                 parray->num_ele, parray->arr_size);
871                 if (FALSE == _prop_grow_ptparray(parray,
872                                         ((parray->arr_size * 3) >> 1) + 2))
873                         return FALSE;
874         }
875
876         switch (parray->type) {
877         case UINT8_TYPE:
878                 ptr8 = parray->array_entry;
879                 ptr8[parray->num_ele++] = (mtp_uchar)element;
880                 break;
881
882         case UINT16_TYPE:
883                 ptr16 = parray->array_entry;
884                 ptr16[parray->num_ele++] = (mtp_uint16) element;
885                 break;
886
887         case PTR_TYPE:
888         case UINT32_TYPE:
889                 ptr32 = parray->array_entry;
890                 ptr32[parray->num_ele++] = (mtp_uint32)element;
891                 break;
892
893         default:
894                 break;
895         }
896
897         return TRUE;
898 }
899
900 mtp_bool _prop_append_ele128_ptparray(ptp_array_t *parray, mtp_uint64 *element)
901 {
902         mtp_uchar *ptr = NULL;
903         mtp_bool ret = FALSE;
904         if (parray->num_ele >= parray->arr_size) {
905                 if (FALSE == _prop_grow_ptparray(parray,
906                                         ((parray->arr_size * 3) >> 1) + 2))
907                         return FALSE;
908         }
909
910         switch (parray->type) {
911         case UINT128_TYPE:
912                 ptr = parray->array_entry;
913                 memcpy(&(ptr[(parray->num_ele * 16)]), element,
914                                 sizeof(mtp_uint64) * 2);
915                 parray->num_ele++;
916                 ret = TRUE;
917                 break;
918
919         default:
920                 break;
921         }
922
923         return ret;
924 }
925
926 mtp_bool _prop_copy_ptparray(ptp_array_t *dst, ptp_array_t *src)
927 {
928         mtp_uchar *ptr8src = NULL;
929         mtp_uint16 *ptr16src = NULL;
930         mtp_uint32 *ptr32src = NULL;
931         mtp_uint32 ii;
932
933         dst->type = src->type;
934
935         switch (src->type) {
936         case UINT8_TYPE:
937                 ptr8src = src->array_entry;
938                 for (ii = 0; ii < src->num_ele; ii++)
939                         _prop_append_ele_ptparray(dst, ptr8src[ii]);
940                 break;
941
942         case UINT16_TYPE:
943                 ptr16src = src->array_entry;
944                 for (ii = 0; ii < src->num_ele; ii++)
945                         _prop_append_ele_ptparray(dst, ptr16src[ii]);
946                 break;
947
948         case PTR_TYPE:
949         case UINT32_TYPE:
950                 ptr32src = src->array_entry;
951                 for (ii = 0; ii < src->num_ele; ii++)
952                         _prop_append_ele_ptparray(dst, ptr32src[ii]);
953                 break;
954
955         default:
956                 return 0;
957         }
958         return TRUE;
959 }
960
961 mtp_uint32 _prop_pack_ptparray(ptp_array_t *parray, mtp_uchar *buf,
962                 mtp_uint32 bufsize)
963 {
964         if (parray == NULL || buf == NULL) {
965                 ERR("pArray or buf is NULL");
966                 return 0;
967         }
968
969         mtp_uint16 size = 1;
970
971         size = __get_ptp_array_elem_size(parray->type);
972         if (size == 0)
973                 return 0;
974
975         if ((buf == NULL) || (bufsize < (sizeof(mtp_uint32) +
976                                         parray->num_ele * size)))
977                 return 0;
978
979         memcpy(buf, &(parray->num_ele), sizeof(mtp_uint32));
980 #ifdef __BIG_ENDIAN__
981         _util_conv_byte_order(buf, sizeof(mtp_uint32));
982 #endif /* __BIG_ENDIAN__ */
983
984         if (parray->num_ele != 0) {
985 #ifdef __BIG_ENDIAN__
986                 mtp_uint32 ii;
987                 mtp_uchar *temp = buf + sizeof(mtp_uint32);
988                 mtp_uchar *ptr_entry = parray->array_entry;
989
990                 for (ii = 0; ii < parray->num_ele; ii++) {
991                         memcpy(temp, ptr_entry, size);
992                         _util_conv_byte_order(temp, size);
993                         temp += size;
994                         ptr_entry += size;
995                 }
996 #else /* __BIG_ENDIAN__ */
997                 memcpy(buf + sizeof(mtp_uint32), parray->array_entry,
998                                 parray->num_ele * size);
999 #endif /* __BIG_ENDIAN__ */
1000         }
1001         return (sizeof(mtp_uint32) + parray->num_ele * size);
1002 }
1003
1004 mtp_uint32 _prop_pack_ptparray_without_elemsize(ptp_array_t *parray,
1005                 mtp_uchar *buf, mtp_uint32 bufsize)
1006 {
1007         mtp_uint16 size = 1;
1008 #ifdef __BIG_ENDIAN__
1009         mtp_uchar *temp;
1010         mtp_uint32 ii;
1011 #endif /* __BIG_ENDIAN__ */
1012
1013         size = __get_ptp_array_elem_size(parray->type);
1014         if (size == 0)
1015                 return 0;
1016
1017         if ((buf == NULL) || (bufsize < (parray->num_ele * size)))
1018                 return 0;
1019
1020         if (parray->num_ele != 0)
1021                 memcpy(buf, parray->array_entry, parray->num_ele * size);
1022
1023 #ifdef __BIG_ENDIAN__
1024         /* Swap all the elements */
1025         temp = buf;
1026         for (ii = 0; ii < parray->num_ele; ii++) {
1027                 _util_conv_byte_order(temp, size);
1028                 temp += size;
1029         }
1030 #endif /* __BIG_ENDIAN__ */
1031
1032         return (parray->num_ele * size);
1033 }
1034
1035 mtp_bool _prop_rem_elem_ptparray(ptp_array_t *parray, mtp_uint32 element)
1036 {
1037         mtp_uchar *ptr8 = NULL;
1038         mtp_uint16 *ptr16 = NULL;
1039         mtp_uint32 *ptr32 = NULL;
1040         mtp_int32 ii;
1041
1042         ii = _prop_find_ele_ptparray(parray, element);
1043
1044         if (ii == ELEMENT_NOT_FOUND)
1045                 return FALSE;
1046
1047         switch (parray->type) {
1048         case UINT8_TYPE:
1049                 ptr8 = parray->array_entry;
1050                 for (; ii < (parray->num_ele - 1); ii++)
1051                         ptr8[ii] = ptr8[ii + 1];
1052                 break;
1053
1054         case UINT16_TYPE:
1055                 ptr16 = parray->array_entry;
1056                 for (; ii < (parray->num_ele - 1); ii++)
1057                         ptr16[ii] = ptr16[ii + 1];
1058                 break;
1059
1060         case UINT32_TYPE:
1061                 ptr32 = parray->array_entry;
1062                 for (; ii < (parray->num_ele - 1); ii++)
1063                         ptr32[ii] = ptr32[ii + 1];
1064                 break;
1065
1066         case PTR_TYPE:
1067                 ptr32 = parray->array_entry;
1068                 for (; ii < (parray->num_ele - 1); ii++)
1069                         ptr32[ii] = ptr32[ii + 1];
1070                 break;
1071
1072         default:
1073                 break;
1074         }
1075
1076         parray->num_ele--;
1077
1078         return TRUE;
1079
1080 }
1081
1082 void _prop_deinit_ptparray(ptp_array_t *parray)
1083 {
1084         parray->num_ele = 0;
1085         parray->arr_size = 0;
1086         if (parray->array_entry)
1087                 g_free(parray->array_entry);
1088
1089         parray->array_entry = NULL;
1090         return;
1091 }
1092
1093 void _prop_destroy_ptparray(ptp_array_t *parray)
1094 {
1095         if (parray == NULL)
1096                 return;
1097
1098         if (parray->array_entry != NULL)
1099                 g_free(parray->array_entry);
1100
1101         parray->arr_size = 0;
1102         parray->num_ele = 0;
1103         g_free(parray);
1104         return;
1105 }
1106
1107 mtp_uint16 __get_ptp_array_elem_size(data_type_t type)
1108 {
1109         mtp_uint16 size = 0;
1110
1111         switch (type) {
1112         case UINT8_TYPE:
1113                 size = 1;
1114                 break;
1115         case UINT16_TYPE:
1116                 size = 2;
1117                 break;
1118         case PTR_TYPE:
1119         case UINT32_TYPE:
1120                 size = 4;
1121                 break;
1122         case UINT128_TYPE:
1123                 size = 16;
1124                 break;
1125         default:
1126                 size = 0;
1127                 break;
1128         }
1129
1130         return size;
1131 }
1132
1133 /* PtpString Functions */
1134 #ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
1135 static ptp_string_t *__alloc_ptpstring(void)
1136 {
1137         ptp_string_t *pstring = NULL;
1138
1139         pstring = (ptp_string_t *)g_malloc(sizeof(ptp_string_t));
1140         if (pstring != NULL)
1141                 _prop_init_ptpstring(pstring);
1142
1143         return (pstring);
1144 }
1145 #else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
1146 static ptp_string_t *__alloc_ptpstring(mtp_uint32 size)
1147 {
1148         ptp_string_t *pstring = NULL;
1149         mtp_int32 size_tmp = 0;
1150         mtp_int32 alloc_size = 0;
1151
1152         size_tmp = sizeof(wchar_t) * size + sizeof(wchar_t) * 2;
1153         alloc_size = ((size_tmp >> 5) + 1) << 5;        /* multiple of 32 */
1154
1155         pstring = (ptp_string_t *)g_malloc(alloc_size); /* for margin */
1156         if (pstring != NULL)
1157                 _prop_init_ptpstring(pstring);
1158
1159         return (pstring);
1160 }
1161 #endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
1162
1163 void _prop_init_ptpstring(ptp_string_t *pstring)
1164 {
1165         pstring->num_chars = 0;
1166         return;
1167 }
1168
1169 static void __init_ptptimestring(ptp_time_string_t *pstring)
1170 {
1171         pstring->num_chars = 0;
1172 }
1173
1174 void _prop_copy_char_to_ptpstring(ptp_string_t *pstring, void *str,
1175                 char_mode_t cmode)
1176 {
1177         if (pstring == NULL)
1178                 return;
1179
1180         mtp_char *pchar = NULL;
1181         mtp_wchar *pwchar = NULL;
1182         mtp_uchar i = 0;
1183
1184         pchar = (mtp_char *)str;
1185         pwchar = (mtp_wchar *)str;
1186
1187         if (str == NULL) {
1188                 pstring->num_chars = 0;
1189                 return;
1190         }
1191
1192         if (cmode == CHAR_TYPE) {
1193                 if (pchar[0] == 0) {
1194                         pstring->num_chars = 0;
1195                         return;
1196                 }
1197                 for (i = 0; i < MAX_PTP_STRING_CHARS && pchar[i]; i++)
1198                         pstring->str[i] = (mtp_wchar)pchar[i];
1199         } else if (cmode == WCHAR_TYPE) {
1200                 if (pwchar[0] == 0) {
1201                         pstring->num_chars = 0;
1202                         return;
1203                 }
1204                 for (i = 0; i < MAX_PTP_STRING_CHARS && pwchar[i]; i++)
1205                         pstring->str[i] = pwchar[i];
1206         } else {
1207                 ERR("Unknown character mode : %d\n", cmode);
1208                 pstring->num_chars = 0;
1209                 return;
1210         }
1211
1212         if (i == MAX_PTP_STRING_CHARS)
1213                 pstring->num_chars = i;
1214         else
1215                 pstring->num_chars = i + 1;
1216
1217         pstring->str[pstring->num_chars - 1] = (mtp_wchar)0;
1218
1219         return;
1220 }
1221
1222 void _prop_copy_time_to_ptptimestring(ptp_time_string_t *pstring,
1223                 system_time_t *sys_time)
1224 {
1225         char time[17] = { 0 };
1226
1227         if (sys_time == NULL) {
1228                 __init_ptptimestring(pstring);
1229         } else {
1230 #if defined(NEED_TO_PORT)
1231                 _util_wchar_swprintf(pstring->str, sizeof(pstring->str) / WCHAR_SIZ,
1232                                 "%04d%02d%02dT%02d%02d%02d.%01d",
1233                                 sys_time->year, sys_time->month,
1234                                 sys_time->day, sys_time->hour,
1235                                 sys_time->minute, sys_time->second,
1236                                 (sys_time->millisecond) / 100);
1237 #else
1238                 g_snprintf(time, sizeof(time), "%04d%02d%02dT%02d%02d%02d.%01d",
1239                                 sys_time->year, sys_time->month, sys_time->day,
1240                                 sys_time->hour, sys_time->minute,
1241                                 sys_time->second, (sys_time->millisecond) / 100);
1242
1243                 _util_utf8_to_utf16(pstring->str, sizeof(pstring->str) / WCHAR_SIZ, time);
1244 #endif
1245                 pstring->num_chars = 17;
1246                 pstring->str[17] = '\0';
1247         }
1248         return;
1249 }
1250
1251 void _prop_copy_ptpstring(ptp_string_t *dst, ptp_string_t *src)
1252 {
1253         mtp_uint16 ii;
1254
1255         dst->num_chars = src->num_chars;
1256         for (ii = 0; ii < src->num_chars; ii++)
1257                 dst->str[ii] = src->str[ii];
1258
1259         return;
1260 }
1261
1262 void _prop_copy_ptptimestring(ptp_time_string_t *dst, ptp_time_string_t *src)
1263 {
1264         mtp_uint16 ii;
1265
1266         dst->num_chars = src->num_chars;
1267         for (ii = 0; ii < src->num_chars; ii++)
1268                 dst->str[ii] = src->str[ii];
1269
1270         return;
1271 }
1272
1273 mtp_bool _prop_is_equal_ptpstring(ptp_string_t *dst, ptp_string_t *src)
1274 {
1275         mtp_uint16 ii;
1276
1277         if (dst->num_chars != src->num_chars)
1278                 return FALSE;
1279
1280         for (ii = 0; ii < dst->num_chars; ii++) {
1281                 if (dst->str[ii] != src->str[ii])
1282                         return FALSE;
1283         }
1284         return TRUE;
1285 }
1286
1287 mtp_uint32 _prop_size_ptpstring(ptp_string_t *pstring)
1288 {
1289         if (pstring == NULL)
1290                 return 0;
1291
1292         return (pstring->num_chars * sizeof(mtp_wchar) + 1);
1293 }
1294
1295 mtp_uint32 _prop_size_ptptimestring(ptp_time_string_t *pstring)
1296 {
1297         if (pstring == NULL)
1298                 return 0;
1299
1300         return (pstring->num_chars * sizeof(mtp_wchar) + 1);
1301 }
1302
1303 mtp_uint32 _prop_pack_ptpstring(ptp_string_t *pstring, mtp_uchar *buf,
1304                 mtp_uint32 size)
1305 {
1306         mtp_uint32 bytes_written = 0;
1307         mtp_uint32 ii;
1308         mtp_uchar *pchar = NULL;
1309 #ifdef __BIG_ENDIAN__
1310         mtp_wchar conv_str[MAX_PTP_STRING_CHARS];
1311 #endif /* __BIG_ENDIAN__ */
1312
1313         if ((buf == NULL) || (pstring == NULL) || (size == 0) ||
1314                         (size < _prop_size_ptpstring(pstring))) {
1315                 return bytes_written;
1316         }
1317
1318         if (pstring->num_chars == 0) {
1319                 buf[0] = 0;
1320                 bytes_written = 1;
1321         } else {
1322 #ifdef __BIG_ENDIAN__
1323                 memcpy(conv_str, pstring->str,
1324                                 pstring->num_chars * sizeof(mtp_wchar));
1325                 _util_conv_byte_orderForWString(conv_str, pstring->num_chars);
1326                 pchar = (mtp_uchar *) conv_str;
1327 #else /* __BIG_ENDIAN__ */
1328                 pchar = (mtp_uchar *) pstring->str;
1329 #endif /* __BIG_ENDIAN__ */
1330                 buf[0] = pstring->num_chars;
1331
1332                 bytes_written = _prop_size_ptpstring(pstring);
1333                 for (ii = 0; ii < (bytes_written - 1); ii++)
1334                         buf[ii + 1] = pchar[ii];
1335         }
1336         return bytes_written;
1337 }
1338
1339 mtp_uint32 _prop_pack_ptptimestring(ptp_time_string_t *pstring, mtp_uchar *buf,
1340                 mtp_uint32 size)
1341 {
1342         mtp_uint32 bytes_written = 0;
1343         mtp_uchar *pchar = NULL;
1344 #ifdef __BIG_ENDIAN__
1345         mtp_wchar conv_str[MAX_PTP_STRING_CHARS];
1346 #endif /* __BIG_ENDIAN__ */
1347
1348         if ((buf == NULL) || (pstring == NULL) || (size == 0) ||
1349                         (size < _prop_size_ptptimestring(pstring))) {
1350                 return bytes_written;
1351         }
1352
1353         if (pstring->num_chars == 0) {
1354                 buf[0] = 0;
1355                 bytes_written = 1;
1356         } else {
1357 #ifdef __BIG_ENDIAN__
1358                 memcpy(conv_str, pstring->str,
1359                                 pstring->num_chars * sizeof(mtp_wchar));
1360                 _util_conv_byte_order_wstring(conv_str, pstring->num_chars);
1361                 pchar = (mtp_uchar *)conv_str;
1362 #else /* __BIG_ENDIAN__ */
1363                 pchar = (mtp_uchar *)pstring->str;
1364 #endif /* __BIG_ENDIAN__ */
1365                 buf[0] = pstring->num_chars;
1366
1367                 bytes_written = _prop_size_ptptimestring(pstring);
1368
1369                 memcpy(&buf[1], pchar, bytes_written - 1);
1370
1371         }
1372         return bytes_written;
1373 }
1374
1375 mtp_uint32 _prop_parse_rawstring(ptp_string_t *pstring, mtp_uchar *buf,
1376                 mtp_uint32 size)
1377 {
1378         mtp_uint16 ii;
1379
1380         if (buf == NULL)
1381                 return 0;
1382
1383         if (buf[0] == 0) {
1384                 pstring->num_chars = 0;
1385                 return 1;
1386         } else {
1387                 pstring->num_chars = buf[0];
1388                 ii = (mtp_uint16) ((size - 1) / sizeof(mtp_wchar));
1389                 if (pstring->num_chars > ii)
1390                         pstring->num_chars = (mtp_uchar)ii;
1391
1392                 for (ii = 1; ii <= pstring->num_chars; ii++) {
1393 #ifdef __BIG_ENDIAN__
1394                         pstring->str[ii - 1] =
1395                                 buf[2 * ii] | (buf[2 * ii - 1] << 8);
1396 #else /* __BIG_ENDIAN__ */
1397                         pstring->str[ii - 1] =
1398                                 buf[2 * ii - 1] | (buf[2 * ii] << 8);
1399 #endif /* __BIG_ENDIAN__ */
1400                 }
1401                 pstring->str[pstring->num_chars - 1] = (mtp_wchar) 0;
1402                 return _prop_size_ptpstring(pstring);
1403         }
1404 }
1405
1406 void _prop_destroy_ptpstring(ptp_string_t *pstring)
1407 {
1408         if (pstring != NULL)
1409                 g_free(pstring);
1410
1411         return;
1412 }
1413
1414 mtp_bool _prop_is_valid_integer(prop_info_t *prop_info, mtp_uint64 value)
1415 {
1416         if ((prop_info->data_type & PTP_DATATYPE_VALUEMASK) !=
1417                         PTP_DATATYPE_VALUE) {
1418                 return FALSE;
1419         }
1420
1421         if (prop_info->form_flag == RANGE_FORM) {
1422                 if ((value >= prop_info->range.min_val) &&
1423                                 (value <= prop_info->range.max_val)) {
1424                         return TRUE;
1425                 } else {
1426                         /* invalid value */
1427                         return FALSE;
1428                 }
1429         } else if (prop_info->form_flag == ENUM_FORM) {
1430                 slist_node_t *node = prop_info->supp_value_list.start;
1431                 mtp_uint32 ii;
1432                 for (ii = 0; ii < prop_info->supp_value_list.nnodes;
1433                                 ii++, node = node->link) {
1434                         if (value == (mtp_uint32) node->value)
1435                                 return TRUE;
1436                 }
1437
1438                 /* if it hits here, must be an invalid value */
1439                 return FALSE;
1440         } else if (prop_info->form_flag == NONE) {
1441                 /* No restrictions */
1442                 return TRUE;
1443         }
1444
1445         /* shouldn't be here */
1446         return FALSE;
1447 }
1448
1449 mtp_bool _prop_is_valid_string(prop_info_t *prop_info, ptp_string_t *pstring)
1450 {
1451         if ((prop_info->data_type != PTP_DATATYPE_STRING) || (pstring == NULL))
1452                 return FALSE;
1453
1454         if (prop_info->form_flag == ENUM_FORM) {
1455                 slist_node_t *node = NULL;
1456                 mtp_uint32 ii;
1457                 ptp_string_t *ele_str = NULL;
1458
1459                 node = prop_info->supp_value_list.start;
1460                 for (ii = 0; ii < prop_info->supp_value_list.nnodes;
1461                                 ii++, node = node->link) {
1462                         ele_str = (ptp_string_t *) node->value;
1463                         if (ele_str != NULL) {
1464                                 if (_prop_is_equal_ptpstring(pstring, ele_str)) {
1465                                         /* value found in the list of supported values */
1466                                         return TRUE;
1467                                 }
1468                         }
1469                 }
1470                 /* if it hits here, must be an invalid value */
1471                 return FALSE;
1472         } else if (prop_info->form_flag == NONE) {
1473                 /* No restrictions */
1474                 return TRUE;
1475         } else if (prop_info->form_flag == DATE_TIME_FORM) {
1476                 mtp_wchar *date_time = pstring->str;
1477                 if ((date_time[8] != L'T') && (pstring->num_chars > 9)) {
1478                         ERR("invalid data time format");
1479                         return FALSE;
1480                 }
1481                 return TRUE;
1482         } else if (prop_info->form_flag == REGULAR_EXPRESSION_FORM) {
1483                 return TRUE;
1484         }
1485
1486         return TRUE;
1487 }
1488
1489 mtp_bool _prop_set_default_string(prop_info_t *prop_info, mtp_wchar *val)
1490 {
1491         if (prop_info->data_type == PTP_DATATYPE_STRING) {
1492                 _prop_destroy_ptpstring(prop_info->default_val.str);
1493 #ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
1494                 prop_info->default_val.str = __alloc_ptpstring();
1495 #else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
1496                 prop_info->default_val.str = __alloc_ptpstring(_util_wchar_len(val));
1497 #endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
1498                 if (NULL == prop_info->default_val.str)
1499                         return FALSE;
1500
1501                 _prop_copy_char_to_ptpstring(prop_info->default_val.str,
1502                                 val, WCHAR_TYPE);
1503                 return TRUE;
1504         } else {
1505                 return FALSE;
1506         }
1507 }
1508
1509 mtp_bool _prop_set_default_integer(prop_info_t *prop_info, mtp_uchar *value)
1510 {
1511         if ((prop_info->data_type & PTP_DATATYPE_VALUEMASK) ==
1512                         PTP_DATATYPE_VALUE) {
1513                 memcpy(prop_info->default_val.integer, value,
1514                                 prop_info->dts_size);
1515                 return TRUE;
1516         } else {
1517                 return FALSE;
1518         }
1519 }
1520
1521 mtp_bool _prop_set_default_array(prop_info_t *prop_info, mtp_uchar *parray,
1522                 mtp_uint32 num_ele)
1523 {
1524         /* Allocate memory for the PTP array */
1525         if ((prop_info->data_type == PTP_DATATYPE_AUINT8) ||
1526                         (prop_info->data_type == PTP_DATATYPE_AINT8))
1527                 prop_info->default_val.array = _prop_alloc_ptparray(UINT8_TYPE);
1528         else if ((prop_info->data_type == PTP_DATATYPE_AUINT16) ||
1529                         (prop_info->data_type == PTP_DATATYPE_AINT16))
1530                 prop_info->default_val.array = _prop_alloc_ptparray(UINT16_TYPE);
1531         else if ((prop_info->data_type == PTP_DATATYPE_AUINT32) ||
1532                         (prop_info->data_type == PTP_DATATYPE_AINT32))
1533                 prop_info->default_val.array = _prop_alloc_ptparray(UINT32_TYPE);
1534         else
1535                 return FALSE;
1536
1537         if (prop_info->default_val.array == NULL)
1538                 return FALSE;
1539
1540         /* Copies the data into the PTP array */
1541         if ((prop_info->default_val.array != NULL) && (num_ele != 0)) {
1542                 mtp_uchar *ptr8 = NULL;
1543                 mtp_uint16 *ptr16 = NULL;
1544                 mtp_uint32 *ptr32 = NULL;
1545                 mtp_uint32 ii;
1546
1547                 _prop_grow_ptparray(prop_info->default_val.array, num_ele);
1548
1549                 if ((prop_info->data_type == PTP_DATATYPE_AUINT8) ||
1550                                 (prop_info->data_type == PTP_DATATYPE_AINT8)) {
1551                         ptr8 = (mtp_uchar *) parray;
1552                         for (ii = 0; ii < num_ele; ii++)
1553                                 _prop_append_ele_ptparray(prop_info->default_val.array,
1554                                                 ptr8[ii]);
1555
1556                 } else if ((prop_info->data_type == PTP_DATATYPE_AUINT16) ||
1557                                 (prop_info->data_type == PTP_DATATYPE_AINT16)) {
1558
1559                         ptr16 = (mtp_uint16 *) parray;
1560                         for (ii = 0; ii < num_ele; ii++)
1561                                 _prop_append_ele_ptparray(prop_info->default_val.array,
1562                                                 ptr16[ii]);
1563
1564                 } else if ((prop_info->data_type == PTP_DATATYPE_AUINT32) ||
1565                                 (prop_info->data_type == PTP_DATATYPE_AINT32)) {
1566
1567                         ptr32 = (mtp_uint32 *)parray;
1568                         for (ii = 0; ii < num_ele; ii++)
1569                                 _prop_append_ele_ptparray(prop_info->default_val.array,
1570                                                 ptr32[ii]);
1571                 }
1572                 return TRUE;
1573         }
1574         return FALSE;
1575 }
1576
1577 mtp_bool _prop_set_current_integer(device_prop_desc_t *prop, mtp_uint32 val)
1578 {
1579         if (_prop_is_valid_integer(&(prop->propinfo), val)) {
1580                 mtp_int32 ii;
1581                 mtp_uchar *ptr;
1582
1583                 ptr = (mtp_uchar *) &val;
1584
1585                 for (ii = 0; ii < sizeof(mtp_uint32); ii++)
1586                         prop->current_val.integer[ii] = ptr[ii];
1587
1588                 return TRUE;
1589         } else {
1590                 /* setting invalid value */
1591                 return FALSE;
1592         }
1593 }
1594
1595 mtp_bool _prop_set_current_string(device_prop_desc_t *prop, ptp_string_t *str)
1596 {
1597         if (_prop_is_valid_string(&(prop->propinfo), str)) {
1598                 _prop_destroy_ptpstring(prop->current_val.str);
1599 #ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
1600                 prop->current_val.str = __alloc_ptpstring();
1601 #else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
1602                 prop->current_val.str = __alloc_ptpstring(str->num_chars);
1603 #endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
1604                 if (prop->current_val.str != NULL) {
1605                         _prop_copy_ptpstring(prop->current_val.str, str);
1606                         return TRUE;
1607                 } else {
1608                         _prop_destroy_ptpstring(prop->current_val.str);
1609                         return FALSE;
1610                 }
1611         } else {
1612                 /* setting invalid value */
1613                 return FALSE;
1614         }
1615 }
1616
1617 mtp_bool _prop_set_current_array(device_prop_desc_t *prop, mtp_uchar *arr)
1618 {
1619         mtp_uint32 num_ele = 0;
1620         mtp_uchar *pval = NULL;
1621         memcpy(&num_ele, arr, sizeof(mtp_uint32));
1622         pval = arr + sizeof(mtp_uint32);
1623
1624 #ifdef __BIG_ENDIAN__
1625         /* Byte swap the number of elements */
1626         _util_conv_byte_order(&num_ele, sizeof(mtp_uint32));
1627 #endif /* __BIG_ENDIAN__ */
1628
1629         /* Allocate memory for the PTP array */
1630         if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT8) ||
1631                         (prop->propinfo.data_type == PTP_DATATYPE_AINT8)) {
1632                 _prop_destroy_ptparray(prop->current_val.array);
1633                 prop->current_val.array = _prop_alloc_ptparray(UINT8_TYPE);
1634
1635         } else if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT16) ||
1636                         (prop->propinfo.data_type == PTP_DATATYPE_AINT16)) {
1637
1638                 _prop_destroy_ptparray(prop->current_val.array);
1639                 prop->current_val.array = _prop_alloc_ptparray(UINT16_TYPE);
1640
1641         } else if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT32) ||
1642                         (prop->propinfo.data_type == PTP_DATATYPE_AINT32)) {
1643
1644                 _prop_destroy_ptparray(prop->current_val.array);
1645                 prop->current_val.array = _prop_alloc_ptparray(UINT32_TYPE);
1646
1647         } else
1648                 return FALSE;
1649
1650         /* Copies the data into the PTP array */
1651         if ((prop->current_val.array != NULL) && (num_ele != 0)) {
1652                 mtp_uchar *ptr8 = NULL;
1653                 mtp_uint16 *ptr16 = NULL;
1654                 mtp_uint32 *ptr32 = NULL;
1655                 mtp_uint32 ii;
1656 #ifdef __BIG_ENDIAN__
1657                 /* Some temporary variables for swapping the bytes */
1658                 mtp_uint16 swap16;
1659                 mtp_uint32 swap32;
1660 #endif /* __BIG_ENDIAN__ */
1661
1662                 _prop_grow_ptparray(prop->current_val.array, num_ele);
1663
1664                 if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT8) ||
1665                                 (prop->propinfo.data_type == PTP_DATATYPE_AINT8)) {
1666
1667                         ptr8 = (mtp_uchar *) pval;
1668                         for (ii = 0; ii < num_ele; ii++)
1669                                 _prop_append_ele_ptparray(prop->current_val.array,
1670                                                 ptr8[ii]);
1671
1672                 } else if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT16) ||
1673                                 (prop->propinfo.data_type == PTP_DATATYPE_AINT16)) {
1674
1675                         ptr16 = (mtp_uint16 *) pval;
1676                         for (ii = 0; ii < num_ele; ii++) {
1677 #ifdef __BIG_ENDIAN__
1678                                 swap16 = ptr16[ii];
1679                                 _util_conv_byte_order(&swap16, sizeof(mtp_uint16));
1680                                 _prop_append_ele_ptparray(prop->current_val.array,
1681                                                 swap16);
1682 #else /* __BIG_ENDIAN__ */
1683                                 _prop_append_ele_ptparray(prop->current_val.array,
1684                                                 ptr16[ii]);
1685 #endif /* __BIG_ENDIAN__ */
1686                         }
1687                 } else if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT32) ||
1688                                 (prop->propinfo.data_type == PTP_DATATYPE_AINT32)) {
1689
1690                         ptr32 = (mtp_uint32 *) pval;
1691                         for (ii = 0; ii < num_ele; ii++) {
1692 #ifdef __BIG_ENDIAN__
1693                                 swap32 = ptr32[ii];
1694                                 _util_conv_byte_order(&swap32, sizeof(mtp_uint32));
1695                                 _prop_append_ele_ptparray(prop->current_val.array,
1696                                                 swap32);
1697 #else /* __BIG_ENDIAN__ */
1698                                 _prop_append_ele_ptparray(prop->current_val.array,
1699                                                 ptr32[ii]);
1700 #endif /* __BIG_ENDIAN__ */
1701                         }
1702                 }
1703                 return TRUE;
1704         }
1705
1706         return FALSE;
1707 }
1708
1709 mtp_bool _prop_set_current_device_prop(device_prop_desc_t *prop, mtp_uchar *val,
1710                 mtp_uint32 size)
1711 {
1712         if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
1713                 ptp_string_t str;
1714                 _prop_init_ptpstring(&str);
1715                 _prop_parse_rawstring(&str, val, size);
1716                 return _prop_set_current_string(prop, &str);
1717
1718         } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
1719                         PTP_DATATYPE_ARRAY) {
1720
1721                 mtp_uint32 *ptr = (mtp_uint32 *) val;
1722                 if (size < sizeof(mtp_uint32))
1723                         return FALSE;
1724
1725                 if (size < sizeof(mtp_uint32) + ptr[0] * prop->propinfo.dts_size)
1726                         return FALSE;
1727
1728                 return _prop_set_current_array(prop, val);
1729
1730         } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
1731                         PTP_DATATYPE_VALUE) {
1732
1733                 if (prop->propinfo.dts_size > size)
1734                         return FALSE;
1735
1736                 if ((prop->propinfo.data_type == PTP_DATATYPE_INT64) ||
1737                                 (prop->propinfo.data_type == PTP_DATATYPE_UINT64) ||
1738                                 (prop->propinfo.data_type == PTP_DATATYPE_INT128) ||
1739                                 (prop->propinfo.data_type == PTP_DATATYPE_UINT128)) {
1740
1741                         /* No validation at this time */
1742                         memcpy(prop->current_val.integer, val,
1743                                         prop->propinfo.dts_size);
1744 #ifdef __BIG_ENDIAN__
1745                         _util_conv_byte_order(prop->current_val.integer,
1746                                         prop->propinfo.dts_size);
1747 #endif /* __BIG_ENDIAN__ */
1748                         return TRUE;
1749                 } else {
1750                         /* avoid using new_val = *(ddword*)val; */
1751                         mtp_uint32 new_val = (mtp_uint32)0;
1752                         memcpy(&new_val, val, size);
1753 #ifdef __BIG_ENDIAN__
1754                         _util_conv_byte_order(&new_val, sizeof(mtp_uint32));
1755 #endif /* __BIG_ENDIAN__ */
1756                         return _prop_set_current_integer(prop, new_val);
1757                 }
1758         }
1759
1760         return FALSE;
1761 }
1762
1763 mtp_bool _prop_set_current_integer_val(obj_prop_val_t *pval, mtp_uint64 val)
1764 {
1765         if (_prop_is_valid_integer(&(pval->prop->propinfo), val)) {
1766                 memset(pval->current_val.integer, 0,
1767                                 pval->prop->propinfo.dts_size * sizeof(mtp_byte));
1768                 memcpy(pval->current_val.integer, &val,
1769                                 pval->prop->propinfo.dts_size * sizeof(mtp_byte));
1770                 return TRUE;
1771         } else {
1772                 /* setting invalid value */
1773                 return FALSE;
1774         }
1775 }
1776
1777 mtp_bool _prop_set_current_string_val(obj_prop_val_t *pval, ptp_string_t *str)
1778 {
1779         if (_prop_is_valid_string(&(pval->prop->propinfo), str)) {
1780                 _prop_destroy_ptpstring(pval->current_val.str);
1781 #ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
1782                 pval->current_val.str = __alloc_ptpstring();
1783 #else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
1784                 pval->current_val.str = __alloc_ptpstring(str->num_chars);
1785 #endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
1786                 if (pval->current_val.str != NULL) {
1787                         _prop_copy_ptpstring(pval->current_val.str, str);
1788                         return TRUE;
1789                 } else
1790                         return FALSE;
1791         } else {
1792                 /* setting invalid value */
1793                 return FALSE;
1794         }
1795 }
1796
1797 mtp_bool _prop_set_current_array_val(obj_prop_val_t *pval, mtp_uchar *arr,
1798                 mtp_uint32 size)
1799 {
1800         mtp_uint32 num_ele = 0;
1801         mtp_uchar *value = NULL;
1802         prop_info_t *propinfo = NULL;
1803
1804         propinfo = &(pval->prop->propinfo);
1805
1806         if (propinfo->data_type == PTP_DATATYPE_STRING) {
1807                 ptp_string_t str;
1808                 _prop_init_ptpstring(&str);
1809                 _prop_parse_rawstring(&str, arr, size);
1810                 return _prop_set_current_string_val(pval, &str);
1811
1812         } else if ((propinfo->data_type & PTP_DATATYPE_ARRAYMASK) ==
1813                         PTP_DATATYPE_ARRAY) {
1814
1815                 if (size < sizeof(mtp_uint32))
1816                         return FALSE;
1817
1818                 memcpy(&num_ele, arr, sizeof(mtp_uint32));
1819                 DBG("parsed array num [%d]\n", num_ele);
1820
1821                 if (size < sizeof(mtp_uint32) +
1822                                 num_ele * (propinfo->dts_size)) {
1823
1824                         ERR("buffer size is not enough [%d]\n", size);
1825                         return FALSE;
1826                 }
1827
1828                 value = arr + sizeof(mtp_uint32);
1829
1830                 if ((propinfo->data_type == PTP_DATATYPE_AUINT8) ||
1831                                 (propinfo->data_type == PTP_DATATYPE_AINT8)) {
1832
1833                         _prop_destroy_ptparray(pval->current_val.array);
1834                         pval->current_val.array = _prop_alloc_ptparray(UINT8_TYPE);
1835
1836                 } else if ((propinfo->data_type == PTP_DATATYPE_AUINT16) ||
1837                                 (propinfo->data_type == PTP_DATATYPE_AINT16)) {
1838
1839                         _prop_destroy_ptparray(pval->current_val.array);
1840                         pval->current_val.array = _prop_alloc_ptparray(UINT16_TYPE);
1841
1842                 } else if ((propinfo->data_type == PTP_DATATYPE_AUINT32) ||
1843                                 (propinfo->data_type == PTP_DATATYPE_AINT32)) {
1844
1845                         _prop_destroy_ptparray(pval->current_val.array);
1846                         pval->current_val.array = _prop_alloc_ptparray(UINT32_TYPE);
1847                 }
1848
1849                 /* Copies the data into the PTP array */
1850                 if ((pval->current_val.array != NULL) && (num_ele != 0)) {
1851                         mtp_uchar *ptr8 = NULL;
1852                         mtp_uint16 *ptr16 = NULL;
1853                         mtp_uint32 *ptr32 = NULL;
1854                         mtp_uint32 ii;
1855
1856                         _prop_grow_ptparray(pval->current_val.array, num_ele);
1857
1858                         if ((propinfo->data_type == PTP_DATATYPE_AUINT8) ||
1859                                         (propinfo->data_type == PTP_DATATYPE_AINT8)) {
1860
1861                                 ptr8 = (mtp_uchar *) value;
1862                                 for (ii = 0; ii < num_ele; ii++)
1863                                         _prop_append_ele_ptparray(pval->current_val.array,
1864                                                         ptr8[ii]);
1865
1866                         } else if ((propinfo->data_type == PTP_DATATYPE_AUINT16) ||
1867                                         (propinfo->data_type == PTP_DATATYPE_AINT16)) {
1868                                 ptr16 = (mtp_uint16 *) value;
1869                                 for (ii = 0; ii < num_ele; ii++)
1870                                         _prop_append_ele_ptparray(pval->current_val.array,
1871                                                         ptr16[ii]);
1872
1873                         } else if ((propinfo->data_type == PTP_DATATYPE_AUINT32) ||
1874                                         (propinfo->data_type == PTP_DATATYPE_AINT32)) {
1875
1876                                 ptr32 = (mtp_uint32 *)value;
1877                                 for (ii = 0; ii < num_ele; ii++)
1878                                         _prop_append_ele_ptparray(pval->current_val.array,
1879                                                         ptr32[ii]);
1880                         }
1881                 }
1882                 return TRUE;
1883         } else if ((propinfo->data_type & PTP_DATATYPE_VALUEMASK) ==
1884                         PTP_DATATYPE_VALUE) {
1885
1886                 if (propinfo->dts_size > size)
1887                         return FALSE;
1888
1889                 if ((propinfo->data_type == PTP_DATATYPE_INT64) ||
1890                                 (propinfo->data_type == PTP_DATATYPE_UINT64) ||
1891                                 (propinfo->data_type == PTP_DATATYPE_INT128) ||
1892                                 (propinfo->data_type == PTP_DATATYPE_UINT128)) {
1893
1894                         if (propinfo->data_type == PTP_DATATYPE_UINT64) {
1895                                 memcpy(pval->current_val.integer, arr,
1896                                                 propinfo->dts_size);
1897                         }
1898                         memcpy(pval->current_val.integer, arr,
1899                                         propinfo->dts_size);
1900                         return TRUE;
1901                 } else {
1902
1903                         mtp_uint32 new_val = 0;
1904                         memcpy(&new_val, arr, propinfo->dts_size);
1905                         return _prop_set_current_integer_val(pval,
1906                                         new_val);
1907                 }
1908         }
1909         return FALSE;
1910 }
1911
1912 #ifdef __BIG_ENDIAN__
1913 mtp_bool _prop_set_current_array_val_usbrawdata(obj_prop_val_t *pval,
1914                 mtp_uchar *arr, mtp_uint32 size)
1915 {
1916         mtp_uint32 num_ele = 0;
1917         mtp_uchar *value = NULL;
1918         prop_info_t *propinfo = NULL;
1919
1920         propinfo = &(pval->prop->propinfo);
1921
1922         if (propinfo->data_type == PTP_DATATYPE_STRING) {
1923                 ptp_string_t str;
1924                 _prop_init_ptpstring(&str);
1925                 _prop_parse_rawstring(&str, arr, size);
1926                 return _prop_set_current_string_val(pval, &str);
1927
1928         } else if ((propinfo->data_type & PTP_DATATYPE_ARRAYMASK) ==
1929                         PTP_DATATYPE_ARRAY) {
1930
1931                 if (size < sizeof(mtp_uint32))
1932                         return FALSE;
1933
1934                 memcpy(&num_ele, arr, sizeof(mtp_uint32));
1935 #ifdef __BIG_ENDIAN__
1936                 _util_conv_byte_order(&num_ele, sizeof(mtp_uint32));
1937 #endif /* __BIG_ENDIAN__ */
1938                 if (size < sizeof(mtp_uint32) + num_ele * propinfo->dts_size)
1939                         return FALSE;
1940
1941                 value = arr + sizeof(mtp_uint32);
1942
1943                 if ((propinfo->data_type == PTP_DATATYPE_AUINT8) ||
1944                                 (propinfo->data_type == PTP_DATATYPE_AINT8)) {
1945
1946                         _prop_destroy_ptparray(pval->current_val.array);
1947                         pval->current_val.array = _prop_alloc_ptparray(UINT8_TYPE);
1948
1949                 } else if ((propinfo->data_type == PTP_DATATYPE_AUINT16) ||
1950                                 (propinfo->data_type == PTP_DATATYPE_AINT16)) {
1951
1952                         _prop_destroy_ptparray(pval->current_val.array);
1953                         pval->current_val.array = _prop_alloc_ptparray(UINT16_TYPE);
1954
1955                 } else if ((propinfo->data_type == PTP_DATATYPE_AUINT32) ||
1956                                 (propinfo->data_type == PTP_DATATYPE_AINT32)) {
1957
1958                         _prop_destroy_ptparray(pval->current_val.array);
1959                         pval->current_val.array = _prop_alloc_ptparray(UINT32_TYPE);
1960
1961                 }
1962
1963                 /* Copies the data into the PTP array */
1964                 if ((pval->current_val.array != NULL) && (num_ele != 0)) {
1965
1966                         mtp_uchar *ptr8 = NULL;
1967                         mtp_uint16 *ptr16 = NULL;
1968                         mtp_uint32 *ptr32 = NULL;
1969                         mtp_uint32 ii;
1970
1971                         _prop_grow_ptparray(pval->current_val.array, num_ele);
1972
1973                         if ((propinfo->data_type == PTP_DATATYPE_AUINT8) ||
1974                                         (propinfo->data_type == PTP_DATATYPE_AINT8)) {
1975
1976                                 ptr8 = (mtp_uchar *) arr;
1977                                 for (ii = 0; ii < num_ele; ii++)
1978                                         _prop_append_ele_ptparray(pval->current_val.array,
1979                                                         ptr8[ii]);
1980
1981                         } else if ((propinfo->data_type == PTP_DATATYPE_AUINT16) ||
1982                                         (propinfo->data_type ==
1983                                          PTP_DATATYPE_AINT16)) {
1984
1985                                 ptr16 = (mtp_uint16 *) arr;
1986 #ifdef __BIG_ENDIAN__
1987                                 _util_conv_byte_order_gen_str(ptr16,
1988                                                 num_ele, sizeof(mtp_uint16));
1989 #endif /* __BIG_ENDIAN__ */
1990                                 for (ii = 0; ii < num_ele; ii++)
1991                                         _prop_append_ele_ptparray(pval->current_val.array,
1992                                                         ptr16[ii]);
1993
1994                         } else if ((propinfo->data_type == PTP_DATATYPE_AUINT32) ||
1995                                         (propinfo->data_type ==
1996                                          PTP_DATATYPE_AINT32)) {
1997
1998                                 ptr32 = (mtp_uint32 *) arr;
1999 #ifdef __BIG_ENDIAN__
2000                                 _util_conv_byte_order_gen_str(ptr32, num_ele,
2001                                                 sizeof(mtp_uint32));
2002 #endif /* __BIG_ENDIAN__ */
2003                                 for (ii = 0; ii < num_ele; ii++)
2004                                         _prop_append_ele_ptparray(pval->current_val.array,
2005                                                         ptr32[ii]);
2006                         }
2007                 }
2008                 return TRUE;
2009         } else if ((propinfo->data_type & PTP_DATATYPE_VALUEMASK) ==
2010                         PTP_DATATYPE_VALUE) {
2011
2012                 if (propinfo->dts_size > size)
2013                         return FALSE;
2014
2015                 if ((propinfo->data_type == PTP_DATATYPE_INT64) ||
2016                                 (propinfo->data_type == PTP_DATATYPE_UINT64) ||
2017                                 (propinfo->data_type == PTP_DATATYPE_INT128) ||
2018                                 (propinfo->data_type == PTP_DATATYPE_UINT128)) {
2019
2020                         memcpy(pval->current_val.integer, arr,
2021                                         propinfo->dts_size);
2022 #ifdef __BIG_ENDIAN__
2023                         _util_conv_byte_order(pval->current_val.integer,
2024                                         propinfo->dts_size);
2025 #endif /* __BIG_ENDIAN__ */
2026                         return TRUE;
2027                 } else {
2028                         mtp_uint32 new_val = 0;
2029                         memcpy(&new_val, arr, propinfo->dts_size);
2030                         return _prop_set_current_integer_val(pval, new_val);
2031                 }
2032         }
2033         return FALSE;
2034 }
2035 #endif /* __BIG_ENDIAN__ */
2036
2037 mtp_bool _prop_set_range_integer(prop_info_t *prop_info, mtp_uint32 min,
2038                 mtp_uint32 max, mtp_uint32 step)
2039 {
2040         if (((prop_info->data_type & PTP_DATATYPE_VALUEMASK) !=
2041                                 PTP_DATATYPE_VALUE) || (prop_info->form_flag != RANGE_FORM)) {
2042                 return FALSE;
2043
2044         } else {
2045                 prop_info->range.min_val = min;
2046                 prop_info->range.max_val = max;
2047                 prop_info->range.step_size = step;
2048                 return TRUE;
2049         }
2050 }
2051
2052 mtp_bool _prop_set_regexp(obj_prop_desc_t *prop, mtp_wchar *regex)
2053 {
2054         ptp_string_t *str;
2055
2056         if ((prop->propinfo.data_type != PTP_DATATYPE_STRING) ||
2057                         (prop->propinfo.form_flag != REGULAR_EXPRESSION_FORM)) {
2058                 return FALSE;
2059         }
2060 #ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
2061         str = __alloc_ptpstring();
2062 #else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
2063         str = __alloc_ptpstring(_util_wchar_len(regex));
2064 #endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
2065         if (str == NULL)
2066                 return FALSE;
2067
2068         _prop_copy_char_to_ptpstring(str, regex, WCHAR_TYPE);
2069         prop->prop_forms.reg_exp = str;
2070
2071         return TRUE;
2072 }
2073
2074 mtp_bool _prop_set_maxlen(obj_prop_desc_t *prop, mtp_uint32 max)
2075 {
2076         if ((prop->propinfo.form_flag != BYTE_ARRAY_FORM) &&
2077                         (prop->propinfo.form_flag != LONG_STRING_FORM)) {
2078                 return FALSE;
2079         }
2080
2081         if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) !=
2082                         PTP_DATATYPE_ARRAY) {
2083                 return FALSE;
2084         }
2085
2086         prop->prop_forms.max_len = max;
2087         return TRUE;
2088
2089 }
2090
2091 /* DeviceObjectPropDesc Functions */
2092 void _prop_init_device_property_desc(device_prop_desc_t *prop,
2093                 mtp_uint16 propcode, mtp_uint16 data_type, mtp_uchar get_set,
2094                 mtp_uchar form_flag)
2095 {
2096         mtp_int32 ii;
2097
2098         prop->propinfo.prop_code = propcode;
2099         prop->propinfo.data_type = data_type;
2100         prop->propinfo.get_set = get_set;
2101         prop->propinfo.default_val.str = NULL;
2102         prop->current_val.str = NULL;
2103         prop->propinfo.form_flag = form_flag;
2104
2105         for (ii = 0; ii < 16; ii++) {
2106                 prop->current_val.integer[ii] = 0;
2107                 prop->propinfo.default_val.integer[ii] = 0;
2108         }
2109
2110         /* size of default value: DTS */
2111         switch (prop->propinfo.data_type) {
2112         case PTP_DATATYPE_UINT8:
2113         case PTP_DATATYPE_INT8:
2114         case PTP_DATATYPE_AINT8:
2115         case PTP_DATATYPE_AUINT8:
2116                 prop->propinfo.dts_size = sizeof(mtp_uchar);
2117                 break;
2118
2119         case PTP_DATATYPE_UINT16:
2120         case PTP_DATATYPE_INT16:
2121         case PTP_DATATYPE_AINT16:
2122         case PTP_DATATYPE_AUINT16:
2123                 prop->propinfo.dts_size = sizeof(mtp_uint16);
2124                 break;
2125
2126         case PTP_DATATYPE_UINT32:
2127         case PTP_DATATYPE_INT32:
2128         case PTP_DATATYPE_AINT32:
2129         case PTP_DATATYPE_AUINT32:
2130                 prop->propinfo.dts_size = sizeof(mtp_uint32);
2131                 break;
2132
2133         case PTP_DATATYPE_UINT64:
2134         case PTP_DATATYPE_INT64:
2135         case PTP_DATATYPE_AINT64:
2136         case PTP_DATATYPE_AUINT64:
2137                 prop->propinfo.dts_size = sizeof(mtp_int64);
2138                 break;
2139
2140         case PTP_DATATYPE_UINT128:
2141         case PTP_DATATYPE_INT128:
2142         case PTP_DATATYPE_AINT128:
2143         case PTP_DATATYPE_AUINT128:
2144                 prop->propinfo.dts_size = 2 * sizeof(mtp_int64);
2145                 break;
2146
2147         case PTP_DATATYPE_STRING:
2148         default:
2149                 /* don't know how to handle at this point (including PTP_DATATYPE_STRING) */
2150                 prop->propinfo.dts_size = 0;
2151                 break;
2152         }
2153
2154         _util_init_list(&(prop->propinfo.supp_value_list));
2155
2156         return;
2157 }
2158
2159 mtp_uint32 _prop_size_device_prop_desc(device_prop_desc_t *prop)
2160 {
2161         /* size :PropCode,Datatype,Getset,formflag */
2162         mtp_uint32 size = sizeof(mtp_uint16) + sizeof(mtp_uint16) +
2163                 sizeof(mtp_uchar) + sizeof(mtp_uchar);
2164
2165         /* size of default value: DTS */
2166         /* size of current value: DTS */
2167         if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
2168
2169                 size += _prop_size_ptpstring(prop->propinfo.default_val.str);
2170                 size += _prop_size_ptpstring(prop->current_val.str);
2171
2172
2173         } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
2174                         PTP_DATATYPE_ARRAY) {
2175
2176                 size += _prop_get_size_ptparray(prop->propinfo.default_val.array);
2177                 size += _prop_get_size_ptparray(prop->current_val.array);
2178
2179         } else {
2180                 size += 2 * prop->propinfo.dts_size;
2181         }
2182
2183         /* Add the size of the Form followed */
2184         switch (prop->propinfo.form_flag) {
2185         case NONE:
2186                 break;
2187
2188         case RANGE_FORM:
2189                 size += 3 * prop->propinfo.dts_size;
2190                 break;
2191
2192         case ENUM_FORM:
2193                 /* Number of Values */
2194                 size += sizeof(mtp_uint16);
2195                 if (prop->propinfo.data_type != PTP_DATATYPE_STRING) {
2196
2197                         size += prop->propinfo.supp_value_list.nnodes *
2198                                 prop->propinfo.dts_size;
2199
2200                 } else {
2201                         slist_node_t *node = NULL;
2202                         mtp_uint16 ii;
2203
2204                         for (ii = 0, node = prop->propinfo.supp_value_list.start;
2205                                         ii < prop->propinfo.supp_value_list.nnodes;
2206                                         ii++, node = node->link) {
2207
2208                                 size += _prop_size_ptpstring((ptp_string_t *) node->value);
2209                         }
2210                 }
2211                 break;
2212
2213         default:
2214                 /* don't know how to handle */
2215                 break;
2216
2217         }
2218
2219         return size;
2220 }
2221
2222 static mtp_uint32 __size_curval_device_prop(device_prop_desc_t *prop)
2223 {
2224         mtp_uint32 size = 0;
2225
2226         if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
2227
2228                 size = _prop_size_ptpstring(prop->current_val.str);
2229
2230         } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
2231                         PTP_DATATYPE_ARRAY) {
2232
2233                 size = _prop_get_size_ptparray(prop->current_val.array);
2234
2235         } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
2236                         PTP_DATATYPE_VALUE) {
2237
2238                 size = prop->propinfo.dts_size;
2239         }
2240         return size;
2241 }
2242
2243 mtp_uint32 _prop_pack_device_prop_desc(device_prop_desc_t *prop,
2244                 mtp_uchar *buf, mtp_uint32 size)
2245 {
2246         mtp_uchar *temp = buf;
2247         mtp_uint32 count = 0;
2248         mtp_uint32 bytes_to_write = 0;
2249         slist_node_t *node = NULL;
2250         mtp_uint32 ii;
2251
2252         if (!buf || size < _prop_size_device_prop_desc(prop))
2253                 return 0;
2254
2255         /* Pack propcode, data_type, & get_set */
2256         bytes_to_write = sizeof(mtp_uint16);
2257         memcpy(temp, &(prop->propinfo.prop_code), bytes_to_write);
2258 #ifdef __BIG_ENDIAN__
2259         _util_conv_byte_order(temp, bytes_to_write);
2260 #endif /* __BIG_ENDIAN__ */
2261         temp += bytes_to_write;
2262
2263         bytes_to_write = sizeof(mtp_uint16);
2264         memcpy(temp, &(prop->propinfo.data_type), bytes_to_write);
2265 #ifdef __BIG_ENDIAN__
2266         _util_conv_byte_order(temp, bytes_to_write);
2267 #endif /* __BIG_ENDIAN__ */
2268         temp += bytes_to_write;
2269
2270         bytes_to_write = sizeof(mtp_uchar);
2271         memcpy(temp, &(prop->propinfo.get_set), bytes_to_write);
2272 #ifdef __BIG_ENDIAN__
2273         _util_conv_byte_order(temp, bytes_to_write);
2274 #endif /* __BIG_ENDIAN__ */
2275         temp += bytes_to_write;
2276
2277         /* Pack Default/Current Value: DTS */
2278         if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
2279
2280                 bytes_to_write = _prop_size_ptpstring(prop->propinfo.default_val.str);
2281                 if (bytes_to_write !=
2282                                 _prop_pack_ptpstring(prop->propinfo.default_val.str,
2283                                         temp, bytes_to_write)) {
2284
2285                         return (mtp_uint32)(temp - buf);
2286                 }
2287                 temp += bytes_to_write;
2288
2289                 bytes_to_write = _prop_size_ptpstring(prop->current_val.str);
2290                 if (bytes_to_write !=
2291                                 _prop_pack_ptpstring(prop->current_val.str,
2292                                         temp, bytes_to_write)) {
2293
2294                         return (mtp_uint32)(temp - buf);
2295                 }
2296                 temp += bytes_to_write;
2297
2298         } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
2299                         PTP_DATATYPE_ARRAY) {
2300
2301                 bytes_to_write = _prop_get_size_ptparray(prop->propinfo.default_val.array);
2302                 if (bytes_to_write !=
2303                                 _prop_pack_ptparray(prop->propinfo.default_val.array,
2304                                         temp, bytes_to_write)) {
2305
2306                         return (mtp_uint32)(temp - buf);
2307                 }
2308                 temp += bytes_to_write;
2309
2310                 bytes_to_write = _prop_get_size_ptparray(prop->current_val.array);
2311                 if (bytes_to_write !=
2312                                 _prop_pack_ptparray(prop->current_val.array,
2313                                         temp, bytes_to_write)) {
2314
2315                         return (mtp_uint32)(temp - buf);
2316                 }
2317                 temp += bytes_to_write;
2318
2319                 /* Add support for other array data types */
2320         } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
2321                         PTP_DATATYPE_VALUE) {
2322
2323                 bytes_to_write = prop->propinfo.dts_size;
2324                 memcpy(temp, prop->propinfo.default_val.integer, bytes_to_write);
2325 #ifdef __BIG_ENDIAN__
2326                 _util_conv_byte_order(temp, bytes_to_write);
2327 #endif /* __BIG_ENDIAN__ */
2328                 temp += bytes_to_write;
2329
2330                 memcpy(temp, prop->current_val.integer, bytes_to_write);
2331 #ifdef __BIG_ENDIAN__
2332                 _util_conv_byte_order(temp, bytes_to_write);
2333 #endif /* __BIG_ENDIAN__ */
2334                 temp += bytes_to_write;
2335         }
2336
2337
2338         /* Now pack the FormFlag */
2339         memcpy(temp, &(prop->propinfo.form_flag), sizeof(mtp_uchar));
2340         temp += sizeof(mtp_uchar);
2341
2342         /* Finally pack the Form followed */
2343         switch (prop->propinfo.form_flag) {
2344         case NONE:
2345                 break;
2346
2347         case RANGE_FORM:
2348                 /* Min, Max, & Step */
2349                 memcpy(temp, &(prop->propinfo.range.min_val),
2350                                 prop->propinfo.dts_size);
2351                 temp += prop->propinfo.dts_size;
2352                 memcpy(temp, &(prop->propinfo.range.max_val),
2353                                 prop->propinfo.dts_size);
2354                 temp += prop->propinfo.dts_size;
2355                 memcpy(temp, &(prop->propinfo.range.step_size),
2356                                 prop->propinfo.dts_size);
2357                 temp += prop->propinfo.dts_size;
2358                 break;
2359
2360         case ENUM_FORM:
2361
2362                 /* Pack Number of Values in this enumeration */
2363                 count = prop->propinfo.supp_value_list.nnodes;
2364
2365                 memcpy(temp, &count, sizeof(mtp_uint16));
2366 #ifdef __BIG_ENDIAN__
2367                 _util_conv_byte_order(temp, sizeof(mtp_uint16));
2368 #endif /* __BIG_ENDIAN__ */
2369                 temp += sizeof(mtp_uint16);
2370
2371                 if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
2372
2373                         for (ii = 0, node = prop->propinfo.supp_value_list.start;
2374                                         ii < prop->propinfo.supp_value_list.nnodes;
2375                                         ii++, node = node->link) {
2376
2377                                 bytes_to_write =
2378                                         _prop_size_ptpstring((ptp_string_t *) node->value);
2379                                 if (bytes_to_write !=
2380                                                 _prop_pack_ptpstring((ptp_string_t *) node->value,
2381                                                         temp, bytes_to_write)) {
2382
2383                                         return (mtp_uint32)(temp - buf);
2384                                 }
2385                                 temp += bytes_to_write;
2386                         }
2387
2388                 } else {
2389                         mtp_uint32 value = 0;
2390
2391                         for (ii = 0, node = prop->propinfo.supp_value_list.start;
2392                                         ii < prop->propinfo.supp_value_list.nnodes;
2393                                         ii++, node = node->link) {
2394
2395                                 value = (mtp_uint32)node->value;
2396                                 memcpy(temp, &value, prop->propinfo.dts_size);
2397 #ifdef __BIG_ENDIAN__
2398                                 _util_conv_byte_order(temp, prop->propinfo.dts_size);
2399 #endif /* __BIG_ENDIAN__ */
2400                                 temp += prop->propinfo.dts_size;
2401                         }
2402                 }
2403                 break;
2404
2405         default:
2406                 /*don't know how to handle */
2407                 break;
2408
2409         }
2410
2411         return (mtp_uint32)(temp - buf);
2412 }
2413
2414 mtp_uint32 _prop_pack_curval_device_prop_desc(device_prop_desc_t *prop,
2415                 mtp_uchar *buf, mtp_uint32 size)
2416 {
2417         mtp_uint32 bytes_to_write;
2418
2419         bytes_to_write = __size_curval_device_prop(prop);
2420
2421         if ((!bytes_to_write) || (buf == NULL) || (size < bytes_to_write))
2422                 return 0;
2423
2424         if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
2425                 if (bytes_to_write != _prop_pack_ptpstring(prop->current_val.str,
2426                                         buf, bytes_to_write)) {
2427                         return 0;
2428                 }
2429         } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
2430                         PTP_DATATYPE_ARRAY) {
2431
2432                 if (bytes_to_write != _prop_pack_ptparray(prop->current_val.array,
2433                                         buf, bytes_to_write)) {
2434                         return 0;
2435                 }
2436         } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
2437                         PTP_DATATYPE_VALUE) {
2438                 /* this property is of type UINT8, ... */
2439                 memcpy(buf, prop->current_val.integer, bytes_to_write);
2440 #ifdef __BIG_ENDIAN__
2441                 _util_conv_byte_order(buf, bytes_to_write);
2442 #endif /* __BIG_ENDIAN__ */
2443         } else {
2444                 return 0;
2445         }
2446
2447         return bytes_to_write;
2448 }
2449
2450 void _prop_reset_device_prop_desc(device_prop_desc_t *prop)
2451 {
2452         ret_if(prop == NULL);
2453
2454         if (prop->propinfo.get_set == PTP_PROPGETSET_GETONLY)
2455                 return;
2456
2457         if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
2458
2459                 _prop_destroy_ptpstring(prop->current_val.str);
2460 #ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
2461                 prop->current_val.str = __alloc_ptpstring();
2462 #else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
2463                 prop->current_val.str = __alloc_ptpstring(prop->propinfo.default_val.str->num_chars);
2464 #endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
2465                 if (NULL == prop->current_val.str)
2466                         return;
2467
2468                 _prop_copy_ptpstring(prop->current_val.str,
2469                                 prop->propinfo.default_val.str);
2470
2471         } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
2472                         PTP_DATATYPE_ARRAY) {
2473
2474                 _prop_destroy_ptparray(prop->current_val.array);
2475                 prop->current_val.array = _prop_alloc_ptparray(UINT32_TYPE);
2476                 if (NULL == prop->current_val.array)
2477                         return;
2478
2479                 _prop_copy_ptparray(prop->current_val.array,
2480                                 prop->propinfo.default_val.array);
2481
2482         } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
2483                         PTP_DATATYPE_VALUE) {
2484
2485                 mtp_int32 ii;
2486                 for (ii = 0; ii < 16; ii++)
2487                         prop->current_val.integer[ii] =
2488                                 prop->propinfo.default_val.integer[ii];
2489         }
2490 }
2491
2492 /* ObjectPropVal Functions */
2493 obj_prop_val_t * _prop_alloc_obj_propval(obj_prop_desc_t *prop)
2494 {
2495         obj_prop_val_t *pval = NULL;
2496         pval = (obj_prop_val_t *)g_malloc(sizeof(obj_prop_val_t));
2497
2498         if (pval != NULL)
2499                 __init_obj_propval(pval, prop);
2500
2501         return pval;
2502 }
2503
2504 static void __init_obj_propval(obj_prop_val_t *pval, obj_prop_desc_t *prop)
2505 {
2506         mtp_int32 ii;
2507
2508         pval->prop = prop;
2509
2510         for (ii = 0; ii < 16; ii++)
2511                 pval->current_val.integer[ii] = 0;
2512
2513         if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
2514
2515 #ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
2516                 pval->current_val.str = __alloc_ptpstring();
2517 #else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
2518                 pval->current_val.str = __alloc_ptpstring(prop->propinfo.default_val.str->num_chars);
2519 #endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
2520                 if (NULL == pval->current_val.str)
2521                         return;
2522                 _prop_copy_ptpstring(pval->current_val.str,
2523                                 prop->propinfo.default_val.str);
2524         } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
2525                         PTP_DATATYPE_VALUE) {
2526
2527                 memcpy(pval->current_val.integer,
2528                                 prop->propinfo.default_val.integer,
2529                                 prop->propinfo.dts_size);
2530         } else {
2531                 if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT8) ||
2532                                 (prop->propinfo.data_type == PTP_DATATYPE_AINT8)) {
2533
2534                         pval->current_val.array = _prop_alloc_ptparray(UINT8_TYPE);
2535                         if (NULL == pval->current_val.array)
2536                                 return;
2537
2538                         _prop_copy_ptparray(pval->current_val.array,
2539                                         prop->propinfo.default_val.array);
2540
2541                 } else if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT16) ||
2542                                 (prop->propinfo.data_type == PTP_DATATYPE_AINT16)) {
2543
2544                         pval->current_val.array = _prop_alloc_ptparray(UINT16_TYPE);
2545                         if (NULL == pval->current_val.array)
2546                                 return;
2547
2548                         _prop_copy_ptparray(pval->current_val.array,
2549                                         prop->propinfo.default_val.array);
2550
2551                 } else if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT32) ||
2552                                 (prop->propinfo.data_type == PTP_DATATYPE_AINT32)) {
2553
2554                         pval->current_val.array = _prop_alloc_ptparray(UINT32_TYPE);
2555                         if (NULL == pval->current_val.array)
2556                                 return;
2557
2558                         _prop_copy_ptparray(pval->current_val.array,
2559                                         prop->propinfo.default_val.array);
2560                 }
2561
2562                 /* Add support for other array data types */
2563         }
2564         return;
2565 }
2566
2567 obj_prop_val_t *_prop_get_prop_val(mtp_obj_t *obj, mtp_uint32 propcode)
2568 {
2569         obj_prop_val_t *prop_val = NULL;
2570         slist_node_t *node = NULL;
2571         mtp_uint32 ii = 0;
2572
2573         /*Update the properties if count is zero*/
2574         if (obj->propval_list.nnodes == 0)
2575                 _prop_update_property_values_list(obj);
2576
2577         for (ii = 0, node = obj->propval_list.start;
2578                         ii < obj->propval_list.nnodes; ii++, node = node->link) {
2579                 if (node == NULL || node->value == NULL)
2580                         goto ERROR_CATCH;
2581
2582                 prop_val = (obj_prop_val_t *)node->value;
2583                 if (prop_val) {
2584                         if (prop_val->prop->propinfo.prop_code == propcode)
2585                                 return prop_val;
2586                 }
2587         }
2588
2589         return NULL;
2590
2591 ERROR_CATCH:
2592         /* update property and try again */
2593         _prop_update_property_values_list(obj);
2594
2595         for (ii = 0, node = obj->propval_list.start;
2596                         ii < obj->propval_list.nnodes;
2597                         ii++, node = node->link) {
2598                 if (node == NULL || node->value == NULL)
2599                         break;
2600
2601                 prop_val = (obj_prop_val_t *)node->value;
2602                 if ((prop_val) && (prop_val->prop->propinfo.prop_code ==
2603                                         propcode)) {
2604                         return prop_val;
2605                 }
2606         }
2607         ERR("node or node->value is null. try again but not found");
2608         return NULL;
2609 }
2610
2611 mtp_uint32 _prop_pack_obj_propval(obj_prop_val_t *pval, mtp_uchar *buf,
2612                 mtp_uint32 size)
2613 {
2614         mtp_uint32 bytes_to_write = _prop_size_obj_propval(pval);
2615
2616         if ((!bytes_to_write) || (buf == NULL) || (size < bytes_to_write))
2617                 return 0;
2618
2619         if (pval->prop->propinfo.data_type == PTP_DATATYPE_STRING) {
2620
2621                 if (bytes_to_write != _prop_pack_ptpstring(pval->current_val.str,
2622                                         buf, bytes_to_write)) {
2623                         return 0;
2624                 }
2625         } else if ((pval->prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
2626                         PTP_DATATYPE_ARRAY) {
2627
2628                 if (bytes_to_write != _prop_pack_ptparray(pval->current_val.array,
2629                                         buf, size)) {
2630                         return 0;
2631                 }
2632
2633         } else if ((pval->prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
2634                         PTP_DATATYPE_VALUE) {
2635
2636                 /* this property is of type UINT8, ... */
2637                 memcpy(buf, pval->current_val.integer, bytes_to_write);
2638 #ifdef __BIG_ENDIAN__
2639                 _util_conv_byte_order(buf, bytes_to_write);
2640 #endif /* __BIG_ENDIAN__ */
2641         } else {
2642                 return 0;
2643         }
2644
2645         return bytes_to_write;
2646 }
2647
2648
2649 mtp_uint32 _prop_size_obj_propval(obj_prop_val_t *pval)
2650 {
2651         mtp_uint32 size = 0;
2652
2653         if (pval == NULL || pval->prop == NULL)
2654                 return size;
2655
2656         if (pval->prop->propinfo.data_type == PTP_DATATYPE_STRING) {
2657                 if (pval->current_val.str == NULL)
2658                         size = 0;
2659                 else
2660                         size = _prop_size_ptpstring(pval->current_val.str);
2661
2662         } else if ((pval->prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
2663                         PTP_DATATYPE_ARRAY) {
2664                 size = _prop_get_size_ptparray(pval->current_val.array);
2665
2666         } else if ((pval->prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
2667                         PTP_DATATYPE_VALUE) {
2668                 size = pval->prop->propinfo.dts_size;
2669         }
2670
2671         return size;
2672 }
2673
2674 void _prop_destroy_obj_propval(obj_prop_val_t *pval)
2675 {
2676         if (pval == NULL)
2677                 return;
2678
2679         if (pval->prop == NULL) {
2680                 g_free(pval);
2681                 pval = NULL;
2682                 return;
2683         }
2684
2685         if (pval->prop->propinfo.data_type == PTP_DATATYPE_STRING) {
2686                 if (pval->current_val.str) {
2687                         _prop_destroy_ptpstring(pval->current_val.str);
2688                         pval->current_val.str = NULL;
2689                 }
2690         } else if ((pval->prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
2691                         PTP_DATATYPE_ARRAY) {
2692                 _prop_destroy_ptparray(pval->current_val.array);
2693                 pval->current_val.array = NULL;
2694         }
2695
2696         if (pval != NULL) {
2697                 g_free(pval);
2698                 pval = NULL;
2699         }
2700
2701         return;
2702 }
2703
2704 static void __init_obj_prop_desc(obj_prop_desc_t *prop, mtp_uint16 propcode,
2705                 mtp_uint16 data_type, mtp_uchar get_set, mtp_uchar form_flag,
2706                 mtp_uint32 group_code)
2707 {
2708         mtp_int32 ii;
2709         prop->propinfo.prop_code = propcode;/*Property code for this property*/
2710         prop->propinfo.data_type = data_type;   /* 2=byte, 4=word,
2711                                                                                          * 6=dword, 0xFFFF=String)
2712                                                                                          */
2713         prop->propinfo.get_set = get_set;       /* 0=get-only, 1=get-set */
2714         prop->propinfo.default_val.str = NULL; /* Default value for a String value type */
2715
2716         prop->propinfo.form_flag = form_flag;
2717
2718         if (prop->propinfo.form_flag == BYTE_ARRAY_FORM)
2719                 prop->propinfo.data_type = PTP_DATATYPE_AUINT8;
2720         else if (prop->propinfo.form_flag == LONG_STRING_FORM)
2721                 prop->propinfo.data_type = PTP_DATATYPE_AUINT16;
2722
2723         prop->group_code = group_code;
2724
2725         /* Zero out the integer byte array */
2726         for (ii = 0; ii < 16; ii++)
2727                 prop->propinfo.default_val.integer[ii] = 0;
2728
2729         /* size of default value: DTS */
2730         switch (prop->propinfo.data_type) {
2731
2732         case PTP_DATATYPE_UINT8:
2733         case PTP_DATATYPE_INT8:
2734         case PTP_DATATYPE_AINT8:
2735         case PTP_DATATYPE_AUINT8:
2736                 prop->propinfo.dts_size = sizeof(mtp_uchar);
2737                 break;
2738
2739         case PTP_DATATYPE_UINT16:
2740         case PTP_DATATYPE_INT16:
2741         case PTP_DATATYPE_AINT16:
2742         case PTP_DATATYPE_AUINT16:
2743                 prop->propinfo.dts_size = sizeof(mtp_uint16);
2744                 break;
2745
2746         case PTP_DATATYPE_UINT32:
2747         case PTP_DATATYPE_INT32:
2748         case PTP_DATATYPE_AINT32:
2749         case PTP_DATATYPE_AUINT32:
2750                 prop->propinfo.dts_size = sizeof(mtp_uint32);
2751                 break;
2752
2753         case PTP_DATATYPE_UINT64:
2754         case PTP_DATATYPE_INT64:
2755         case PTP_DATATYPE_AINT64:
2756         case PTP_DATATYPE_AUINT64:
2757                 prop->propinfo.dts_size = sizeof(mtp_int64);
2758                 break;
2759
2760         case PTP_DATATYPE_UINT128:
2761         case PTP_DATATYPE_INT128:
2762         case PTP_DATATYPE_AINT128:
2763         case PTP_DATATYPE_AUINT128:
2764                 prop->propinfo.dts_size = 2 * sizeof(mtp_int64);
2765                 break;
2766
2767         case PTP_DATATYPE_STRING:
2768         default:
2769                 prop->propinfo.dts_size = 0;
2770                 break;
2771         }
2772
2773         _util_init_list(&(prop->propinfo.supp_value_list));
2774
2775         prop->prop_forms.reg_exp = NULL;
2776         prop->prop_forms.max_len = 0;
2777
2778         return;
2779 }
2780
2781 static mtp_uint32 __get_size_default_val_obj_prop_desc(obj_prop_desc_t *prop)
2782 {
2783         mtp_uint32 size = 0;
2784
2785         if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
2786
2787                 size = _prop_size_ptpstring(prop->propinfo.default_val.str);
2788
2789         } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
2790                         PTP_DATATYPE_ARRAY) {
2791
2792                 size = _prop_get_size_ptparray(prop->propinfo.default_val.array);
2793
2794         } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
2795                         PTP_DATATYPE_VALUE) {
2796
2797                 size = prop->propinfo.dts_size;
2798         }
2799
2800         return size;
2801 }
2802
2803 mtp_uint32 _prop_size_obj_prop_desc(obj_prop_desc_t *prop)
2804 {
2805         mtp_uint32 size =
2806                 sizeof(mtp_uint16) + sizeof(mtp_uint16) + sizeof(mtp_uchar) +
2807                 sizeof(mtp_uint32) + sizeof(mtp_uchar);
2808
2809         /* size of default value: DTS */
2810         if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
2811
2812                 size += _prop_size_ptpstring(prop->propinfo.default_val.str);
2813
2814         } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
2815                         PTP_DATATYPE_ARRAY) {
2816
2817                 size += _prop_get_size_ptparray(prop->propinfo.default_val.array);
2818
2819         } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
2820                         PTP_DATATYPE_VALUE) {
2821
2822                 size += prop->propinfo.dts_size;
2823         }
2824
2825         /* Add the size of the Form followed */
2826         switch (prop->propinfo.form_flag) {
2827         case NONE:
2828                 break;
2829
2830         case RANGE_FORM:
2831                 if (prop->propinfo.data_type != PTP_DATATYPE_STRING)
2832                         size += 3 * prop->propinfo.dts_size;/* Min,Max,Step */
2833
2834                 break;
2835
2836         case ENUM_FORM:
2837                 /* Number of Values */
2838                 size += sizeof(mtp_uint16);
2839                 if (prop->propinfo.data_type != PTP_DATATYPE_STRING) {
2840                         size += prop->propinfo.supp_value_list.nnodes *
2841                                 prop->propinfo.dts_size;
2842                 } else {
2843                         slist_node_t *node = NULL;
2844                         mtp_uint32 ii;
2845
2846                         for (ii = 0, node = prop->propinfo.supp_value_list.start;
2847                                         ii < prop->propinfo.supp_value_list.nnodes;
2848                                         ii++, node = node->link) {
2849
2850                                 size += _prop_size_ptpstring((ptp_string_t *) node->value);
2851                         }
2852                 }
2853                 break;
2854
2855         case DATE_TIME_FORM:
2856                 break;
2857
2858         case REGULAR_EXPRESSION_FORM:
2859                 size += _prop_size_ptpstring(prop->prop_forms.reg_exp);
2860                 break;
2861
2862         case BYTE_ARRAY_FORM:
2863         case LONG_STRING_FORM:
2864                 size += sizeof(prop->prop_forms.max_len);
2865                 break;
2866
2867         default:
2868                 /*don't know how to handle */
2869                 break;
2870
2871         }
2872
2873         return size;
2874 }
2875
2876 mtp_uint32 _prop_pack_obj_prop_desc(obj_prop_desc_t *prop, mtp_uchar *buf,
2877                 mtp_uint32 size)
2878 {
2879         mtp_uchar *temp = buf;
2880         mtp_uint32 count = 0;
2881         mtp_uint32 bytes_to_write = 0;
2882         slist_node_t *node = NULL;
2883         mtp_uint16 ii;
2884
2885         if (!buf || size < _prop_size_obj_prop_desc(prop))
2886                 return 0;
2887
2888         /* Pack propcode, data_type, & get_set */
2889         bytes_to_write = sizeof(mtp_uint16);
2890         memcpy(temp, &(prop->propinfo.prop_code), bytes_to_write);
2891 #ifdef __BIG_ENDIAN__
2892         _util_conv_byte_order(temp, bytes_to_write);
2893 #endif /* __BIG_ENDIAN__ */
2894         temp += bytes_to_write;
2895
2896         bytes_to_write = sizeof(mtp_uint16);
2897         memcpy(temp, &(prop->propinfo.data_type), bytes_to_write);
2898 #ifdef __BIG_ENDIAN__
2899         _util_conv_byte_order(temp, bytes_to_write);
2900 #endif /* __BIG_ENDIAN__ */
2901         temp += bytes_to_write;
2902
2903         bytes_to_write = sizeof(mtp_uchar);
2904         memcpy(temp, &(prop->propinfo.get_set), bytes_to_write);
2905 #ifdef __BIG_ENDIAN__
2906         _util_conv_byte_order(temp, bytes_to_write);
2907 #endif /* __BIG_ENDIAN__ */
2908         temp += bytes_to_write;
2909
2910         /* Pack Default Value: DTS */
2911         if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
2912
2913                 bytes_to_write =
2914                         _prop_size_ptpstring(prop->propinfo.default_val.str);
2915                 if (bytes_to_write != _prop_pack_ptpstring(prop->propinfo.default_val.str,
2916                                         temp, bytes_to_write)) {
2917                         return (mtp_uint32)(temp - buf);
2918                 }
2919                 temp += bytes_to_write;
2920
2921         } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
2922                         PTP_DATATYPE_ARRAY) {
2923
2924                 bytes_to_write = _prop_get_size_ptparray(prop->propinfo.default_val.array);
2925                 if (bytes_to_write != _prop_pack_ptparray(prop->propinfo.default_val.array,
2926                                         temp, bytes_to_write)) {
2927                         return (mtp_uint32)(temp - buf);
2928                 }
2929                 temp += bytes_to_write;
2930
2931         } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
2932                         PTP_DATATYPE_VALUE) {
2933
2934                 bytes_to_write = prop->propinfo.dts_size;
2935                 memcpy(temp, prop->propinfo.default_val.integer, bytes_to_write);
2936 #ifdef __BIG_ENDIAN__
2937                 _util_conv_byte_order(temp, bytes_to_write);
2938 #endif /* __BIG_ENDIAN__ */
2939                 temp += bytes_to_write;
2940         }
2941
2942         /* Pack group_code */
2943         memcpy(temp, &(prop->group_code), sizeof(mtp_uint32));
2944 #ifdef __BIG_ENDIAN__
2945         _util_conv_byte_order(temp, sizeof(mtp_uint32));
2946 #endif /* __BIG_ENDIAN__ */
2947         temp += sizeof(mtp_uint32);
2948
2949         /* Pack the FormFlag */
2950         memcpy(temp, &(prop->propinfo.form_flag), sizeof(mtp_uchar));
2951 #ifdef __BIG_ENDIAN__
2952         _util_conv_byte_order(temp, sizeof(mtp_uchar));
2953 #endif /* __BIG_ENDIAN__ */
2954         temp += sizeof(mtp_uchar);
2955
2956         /* Pack the Form Flag values */
2957         switch (prop->propinfo.form_flag) {
2958         case NONE:
2959                 break;
2960
2961         case RANGE_FORM:
2962                 /* Min, Max, & Step */
2963                 memcpy(temp, &(prop->propinfo.range.min_val),
2964                                 prop->propinfo.dts_size);
2965 #ifdef __BIG_ENDIAN__
2966                 _util_conv_byte_order(temp, prop->propinfo.dts_size);
2967 #endif /* __BIG_ENDIAN__ */
2968                 temp += prop->propinfo.dts_size;
2969                 memcpy(temp, &(prop->propinfo.range.max_val),
2970                                 prop->propinfo.dts_size);
2971 #ifdef __BIG_ENDIAN__
2972                 _util_conv_byte_order(temp, prop->propinfo.dts_size);
2973 #endif /* __BIG_ENDIAN__ */
2974                 temp += prop->propinfo.dts_size;
2975                 memcpy(temp, &(prop->propinfo.range.step_size),
2976                                 prop->propinfo.dts_size);
2977 #ifdef __BIG_ENDIAN__
2978                 _util_conv_byte_order(temp, prop->propinfo.dts_size);
2979 #endif /* __BIG_ENDIAN__ */
2980                 temp += prop->propinfo.dts_size;
2981                 break;
2982
2983         case ENUM_FORM:
2984
2985                 /* Pack Number of Values in this enumeration */
2986                 count = prop->propinfo.supp_value_list.nnodes;
2987
2988                 memcpy(temp, &count, sizeof(mtp_uint16));
2989 #ifdef __BIG_ENDIAN__
2990                 _util_conv_byte_order(temp, sizeof(mtp_uint16));
2991 #endif /* __BIG_ENDIAN__ */
2992                 temp += sizeof(mtp_uint16);
2993
2994                 if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
2995
2996                         for (ii = 0, node = prop->propinfo.supp_value_list.start;
2997                                         ii < prop->propinfo.supp_value_list.nnodes;
2998                                         ii++, node = node->link) {
2999
3000                                 bytes_to_write =
3001                                         _prop_size_ptpstring((ptp_string_t *) node->value);
3002                                 if (bytes_to_write !=
3003                                                 _prop_pack_ptpstring((ptp_string_t *) node->value,
3004                                                         temp, bytes_to_write)) {
3005                                         return (mtp_uint32) (temp - buf);
3006                                 }
3007                                 temp += bytes_to_write;
3008                         }
3009                 } else {
3010                         mtp_uint32 value = 0;
3011
3012                         for (ii = 0, node = prop->propinfo.supp_value_list.start;
3013                                         ii < prop->propinfo.supp_value_list.nnodes;
3014                                         ii++, node = node->link) {
3015
3016                                 value = (mtp_uint32)node->value;
3017                                 memcpy(temp, &value, prop->propinfo.dts_size);
3018 #ifdef __BIG_ENDIAN__
3019                                 _util_conv_byte_order(temp, prop->propinfo.dts_size);
3020 #endif /* __BIG_ENDIAN__ */
3021                                 temp += prop->propinfo.dts_size;
3022                         }
3023                 }
3024                 break;
3025
3026         case DATE_TIME_FORM:
3027                 break;
3028
3029         case REGULAR_EXPRESSION_FORM:
3030                 bytes_to_write = _prop_size_ptpstring(prop->prop_forms.reg_exp);
3031                 if (bytes_to_write !=
3032                                 _prop_pack_ptpstring(prop->prop_forms.reg_exp,
3033                                         temp, bytes_to_write)) {
3034
3035                         return (mtp_uint32)(temp - buf);
3036                 }
3037                 temp += bytes_to_write;
3038                 break;
3039
3040         case BYTE_ARRAY_FORM:
3041         case LONG_STRING_FORM:
3042                 memcpy(temp, &prop->prop_forms.max_len,
3043                                 sizeof(prop->prop_forms.max_len));
3044 #ifdef __BIG_ENDIAN__
3045                 _util_conv_byte_order(temp, sizeof(prop->prop_forms.max_len));
3046 #endif /* __BIG_ENDIAN__ */
3047                 temp += sizeof(prop->prop_forms.max_len);
3048                 break;
3049
3050         default:
3051                 /*don't know how to handle */
3052                 break;
3053
3054         }
3055
3056         return (mtp_uint32)(temp - buf);
3057 }
3058
3059 mtp_uint32 _prop_pack_default_val_obj_prop_desc(obj_prop_desc_t *prop,
3060                 mtp_uchar *buf, mtp_uint32 size)
3061 {
3062         mtp_uint32 bytes_to_write;
3063
3064         bytes_to_write = __get_size_default_val_obj_prop_desc(prop);
3065
3066         if ((!bytes_to_write) || (buf == NULL) || (size < bytes_to_write))
3067                 return 0;
3068
3069         if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
3070                 if (bytes_to_write !=
3071                                 _prop_pack_ptpstring(prop->propinfo.default_val.str,
3072                                         buf, bytes_to_write)) {
3073                         return 0;
3074                 }
3075         } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
3076                         PTP_DATATYPE_ARRAY) {
3077                 if (bytes_to_write !=
3078                                 _prop_pack_ptparray(prop->propinfo.default_val.array,
3079                                         buf, bytes_to_write)) {
3080                         return 0;
3081                 }
3082         } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
3083                         PTP_DATATYPE_VALUE) {
3084                 /* this property is of type UINT8, ... */
3085                 memcpy(buf, prop->propinfo.default_val.integer, bytes_to_write);
3086 #ifdef __BIG_ENDIAN__
3087                 _util_conv_byte_order(buf, bytes_to_write);
3088 #endif /* __BIG_ENDIAN__ */
3089         } else {
3090                 return 0;
3091         }
3092
3093         return bytes_to_write;
3094 }
3095
3096 obj_prop_desc_t *_prop_get_obj_prop_desc(mtp_uint32 format_code,
3097                 mtp_uint32 propcode)
3098 {
3099         mtp_uint32 i = 0;
3100         int num_default_obj_props = 0;
3101
3102         /*Default*/
3103         if (_get_oma_drm_status() == TRUE)
3104                 num_default_obj_props = NUM_OBJECT_PROP_DESC_DEFAULT;
3105         else
3106                 num_default_obj_props = NUM_OBJECT_PROP_DESC_DEFAULT - 1;
3107
3108         for (i = 0; i < num_default_obj_props; i++) {
3109                 if (props_list_default[i].propinfo.prop_code == propcode)
3110                         return &(props_list_default[i]);
3111         }
3112
3113         switch (format_code) {
3114         case PTP_FMT_MP3:
3115         case PTP_FMT_WAVE:
3116                 for (i = 0; i < NUM_OBJECT_PROP_DESC_MP3; i++) {
3117                         if (props_list_mp3[i].propinfo.prop_code == propcode)
3118                                 return &(props_list_mp3[i]);
3119                 }
3120                 break;
3121         case MTP_FMT_WMA:
3122                 for (i = 0; i < NUM_OBJECT_PROP_DESC_WMA; i++) {
3123                         if (props_list_wma[i].propinfo.prop_code == propcode)
3124                                 return &(props_list_wma[i]);
3125                 }
3126                 break;
3127         case MTP_FMT_WMV:
3128         case PTP_FMT_ASF:
3129         case MTP_FMT_MP4:
3130         case PTP_FMT_AVI:
3131         case PTP_FMT_MPEG:
3132         case MTP_FMT_3GP:
3133                 for (i = 0; i < NUM_OBJECT_PROP_DESC_WMV; i++) {
3134                         if (props_list_wmv[i].propinfo.prop_code == propcode)
3135                                 return &(props_list_wmv[i]);
3136                 }
3137                 break;
3138         case MTP_FMT_ABSTRACT_AUDIO_ALBUM:
3139         case PTP_FMT_IMG_EXIF:
3140         case PTP_FMT_IMG_GIF:
3141         case PTP_FMT_IMG_BMP:
3142         case PTP_FMT_IMG_PNG:
3143                 for (i = 0; i < NUM_OBJECT_PROP_DESC_ALBUM; i++) {
3144                         if (props_list_album[i].propinfo.prop_code == propcode)
3145                                 return &(props_list_album[i]);
3146                 }
3147                 break;
3148
3149         default:
3150                 break;
3151         }
3152
3153         ERR("No matched property[0x%x], format[0x%x]!!\n", propcode,
3154                         format_code);
3155         return NULL;
3156 }
3157
3158 static void __destroy_obj_prop_desc(obj_prop_desc_t *prop)
3159 {
3160         slist_node_t *node = NULL;
3161         slist_node_t *next_node = NULL;
3162         mtp_uint32 ii;
3163
3164         if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
3165
3166                 if (prop->propinfo.default_val.str) {
3167
3168                         _prop_destroy_ptpstring(prop->propinfo.default_val.str);
3169                         prop->propinfo.default_val.str = NULL;
3170                 }
3171
3172                 if (prop->propinfo.form_flag == ENUM_FORM) {
3173
3174                         for (node = prop->propinfo.supp_value_list.start, ii = 0;
3175                                         ii < prop->propinfo.supp_value_list.nnodes;
3176                                         node = node->link, ii++) {
3177                                 _prop_destroy_ptpstring((ptp_string_t *) node->value);
3178                         }
3179                 }
3180
3181                 if (prop->propinfo.form_flag == REGULAR_EXPRESSION_FORM) {
3182
3183                         if (prop->prop_forms.reg_exp != NULL) {
3184                                 _prop_destroy_ptpstring(prop->prop_forms.reg_exp);
3185                                 prop->prop_forms.reg_exp = NULL;
3186                         }
3187                 }
3188         } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
3189                         PTP_DATATYPE_ARRAY) {
3190
3191                 if (prop->propinfo.default_val.array) {
3192
3193                         _prop_destroy_ptparray(prop->propinfo.default_val.array);
3194                         prop->propinfo.default_val.array = NULL;
3195                 }
3196         }
3197
3198         /* deallocate memory consumed by list elements  */
3199         next_node = prop->propinfo.supp_value_list.start;
3200         for (ii = 0; ii < prop->propinfo.supp_value_list.nnodes; ii++) {
3201                 node = next_node;
3202                 next_node = next_node->link;
3203                 g_free(node);
3204         }
3205         return;
3206 }
3207
3208 /* Objectproplist functions */
3209 static mtp_uint32 __count_obj_proplist(obj_proplist_t *prop_list)
3210 {
3211         return prop_list->prop_quad_list.nnodes;
3212 }
3213
3214 mtp_uint32 _prop_size_obj_proplist(obj_proplist_t *prop_list)
3215 {
3216         prop_quad_t *quad = NULL;
3217         slist_node_t *node = NULL;
3218         mtp_uint32 ii;
3219         mtp_uint32 size;
3220
3221         /* for the NumberOfElements field in objpropvalList Dataset */
3222         size = sizeof(mtp_uint32);
3223
3224         /* add all the fixed length members of the list */
3225         size += prop_list->prop_quad_list.nnodes * (sizeof(mtp_uint32) +
3226                         sizeof(mtp_uint16) + sizeof(mtp_uint16));
3227         node = prop_list->prop_quad_list.start;
3228         for (ii = 0; ii < prop_list->prop_quad_list.nnodes; ii++) {
3229                 quad = (prop_quad_t *) node->value;
3230                 if (quad)
3231                         size += quad->val_size;
3232
3233                 node = node->link;
3234         }
3235         return size;
3236 }
3237
3238 mtp_uint32 _prop_get_obj_proplist(mtp_obj_t *obj, mtp_uint32 propcode,
3239                 mtp_uint32 group_code, obj_proplist_t *prop_list)
3240 {
3241         obj_prop_val_t *propval = NULL;
3242         slist_node_t *node = NULL;
3243         mtp_uint32 ii = 0;
3244
3245         if (obj->propval_list.nnodes == 0) {
3246                 if (FALSE == _prop_update_property_values_list(obj)) {
3247                         ERR("update Property Values FAIL!!");
3248                         return 0;
3249                 }
3250         }
3251         for (ii = 0, node = obj->propval_list.start;
3252                         ii < obj->propval_list.nnodes;
3253                         ii++, node = node->link) {
3254                 propval = (obj_prop_val_t *)node->value;
3255
3256                 if (NULL == propval)
3257                         continue;
3258
3259                 if (FALSE == __check_object_propcode(propval->prop,
3260                                         propcode, group_code)) {
3261                         continue;
3262                 }
3263                 __append_obj_proplist(prop_list, obj->obj_handle,
3264                                 propval->prop->propinfo.prop_code,
3265                                 propval->prop->propinfo.data_type,
3266                                 (mtp_uchar *)propval->current_val.integer);
3267         }
3268
3269         return __count_obj_proplist(prop_list);
3270 }
3271
3272 mtp_bool _prop_update_property_values_list(mtp_obj_t *obj)
3273 {
3274         mtp_uint32 ii = 0;
3275         mtp_char guid[16] = { 0 };
3276         slist_node_t *node = NULL;
3277         slist_node_t *next_node = NULL;
3278         ptp_time_string_t create_tm, modify_tm;
3279         mtp_uint32 fmt_code = obj->obj_info->obj_fmt;
3280         mtp_wchar buf[MTP_MAX_PATHNAME_SIZE+1] = { 0 };
3281         mtp_char file_name[MTP_MAX_FILENAME_SIZE + 1] = { 0 };
3282         mtp_wchar w_file_name[MTP_MAX_FILENAME_SIZE + 1] = { 0 };
3283         char filename_wo_extn[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
3284         mtp_wchar object_fullpath[MTP_MAX_PATHNAME_SIZE * 2 + 1] = { 0 };
3285
3286         retv_if(obj == NULL, FALSE);
3287         retv_if(obj->obj_info == NULL, FALSE);
3288
3289         if (obj->propval_list.nnodes > 0) {
3290                 /*
3291                  * Remove all the old property value,
3292                  * and ready to set up new list
3293                  */
3294                 for (ii = 0, next_node = obj->propval_list.start;
3295                                 ii < obj->propval_list.nnodes; ii++) {
3296                         node = next_node;
3297                         next_node = node->link;
3298                         _prop_destroy_obj_propval((obj_prop_val_t *)
3299                                         node->value);
3300                         g_free(node);
3301                 }
3302                 obj->propval_list.start = NULL;
3303                 obj->propval_list.end = NULL;
3304                 obj->propval_list.nnodes = 0;
3305                 node = NULL;
3306         }
3307
3308         /* Populate Object Info to Object properties */
3309         if (obj->file_path == NULL || obj->file_path[0] != '/') {
3310                 ERR_SECURE("Path is not valid.. path = [%s]\n",
3311                                 obj->file_path);
3312                 return FALSE;
3313         }
3314
3315         /*STORAGE ID*/
3316         retv_if(FALSE == __create_prop_integer(obj,
3317                                 MTP_OBJ_PROPERTYCODE_STORAGEID,
3318                                 obj->obj_info->store_id), FALSE);
3319
3320         /*OBJECT FORMAT*/
3321         retv_if(FALSE == __create_prop_integer(obj,
3322                                 MTP_OBJ_PROPERTYCODE_OBJECTFORMAT,
3323                                 obj->obj_info->obj_fmt), FALSE);
3324
3325         /*PROTECTION STATUS*/
3326         retv_if(FALSE == __create_prop_integer(obj,
3327                                 MTP_OBJ_PROPERTYCODE_PROTECTIONSTATUS,
3328                                 obj->obj_info->protcn_status), FALSE);
3329
3330         /*OBJECT SIZE*/
3331         retv_if(FALSE == __create_prop_integer(obj,
3332                                 MTP_OBJ_PROPERTYCODE_OBJECTSIZE,
3333                                 obj->obj_info->file_size), FALSE);
3334
3335         /*OBJECT FILENAME*/
3336         _util_get_file_name(obj->file_path, file_name);
3337         _util_utf8_to_utf16(w_file_name, sizeof(w_file_name) / WCHAR_SIZ, file_name);
3338         retv_if(FALSE == __create_prop_string(obj,
3339                                 MTP_OBJ_PROPERTYCODE_OBJECTFILENAME, w_file_name), FALSE);
3340
3341         /*PARENT*/
3342         retv_if(FALSE == __create_prop_integer(obj,
3343                                 MTP_OBJ_PROPERTYCODE_PARENT, obj->obj_info->h_parent), FALSE);
3344
3345         /*PERSISTENT GUID*/
3346         _util_utf8_to_utf16(object_fullpath,
3347                         sizeof(object_fullpath) / WCHAR_SIZ, obj->file_path);
3348         _util_conv_wstr_to_guid(object_fullpath, (mtp_uint64 *) guid);
3349         retv_if((FALSE == __create_prop_array(obj,
3350                                         MTP_OBJ_PROPERTYCODE_PERSISTENTGUID,
3351                                         guid, sizeof(guid))), FALSE);
3352
3353         /*NON-CONSUMABLE*/
3354         retv_if(FALSE == __create_prop_integer(obj,
3355                                 MTP_OBJ_PROPERTYCODE_NONCONSUMABLE, 0), FALSE);
3356
3357         _entity_get_file_times(obj, &create_tm, &modify_tm);
3358         /*DATE MODIFIED*/
3359         retv_if(FALSE == __create_prop_timestring(obj, MTP_OBJ_PROPERTYCODE_DATEMODIFIED,
3360                 &modify_tm), FALSE);
3361
3362         /*DATE CREATED*/
3363         retv_if(FALSE == __create_prop_timestring(obj, MTP_OBJ_PROPERTYCODE_DATECREATED,
3364                 &create_tm), FALSE);
3365
3366         /* NAME */
3367         _util_get_file_name_wo_extn(obj->file_path,
3368                         filename_wo_extn);
3369         _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ, filename_wo_extn);
3370         retv_if(FALSE == __create_prop_string(obj,
3371                                 MTP_OBJ_PROPERTYCODE_NAME, buf), FALSE);
3372
3373         /*ASSOCIATION TYPE*/
3374         retv_if(FALSE == __create_prop_integer(obj,
3375                                 MTP_OBJ_PROPERTYCODE_ASSOCIATIONTYPE,
3376                                 obj->obj_info->association_type), FALSE);
3377
3378         /* OMADRM STATUS */
3379         if (_get_oma_drm_status() == TRUE) {
3380                 retv_if(FALSE == __create_prop_integer(obj,
3381                                         MTP_OBJ_PROPERTYCODE_OMADRMSTATUS, 0), FALSE);
3382         }
3383
3384         /*Get DCM data*/
3385         if (fmt_code == PTP_FMT_MP3 ||
3386                         fmt_code == MTP_FMT_WMA ||
3387                         fmt_code == PTP_FMT_WAVE ||
3388                         fmt_code == MTP_FMT_FLAC) {
3389                 __update_prop_values_audio(obj);
3390
3391         } else if (fmt_code == MTP_FMT_WMV ||
3392                         fmt_code == PTP_FMT_ASF ||
3393                         fmt_code == MTP_FMT_MP4 ||
3394                         fmt_code == PTP_FMT_AVI ||
3395                         fmt_code == PTP_FMT_MPEG) {
3396                 __update_prop_values_video(obj);
3397
3398         } else if (fmt_code == PTP_FMT_IMG_EXIF ||
3399                         fmt_code == PTP_FMT_IMG_BMP ||
3400                         fmt_code == PTP_FMT_IMG_GIF ||
3401                         fmt_code == PTP_FMT_IMG_PNG) {
3402                 __update_prop_values_image(obj);
3403         }
3404
3405         return TRUE;
3406 }
3407
3408 static mtp_bool __append_obj_proplist(obj_proplist_t *prop_list, mtp_uint32 obj_handle,
3409                 mtp_uint16 propcode, mtp_uint32 data_type, mtp_uchar *val)
3410 {
3411         ptp_string_t *str = NULL;
3412         prop_quad_t *quad = NULL;
3413         ptp_array_t *arr_uint8;
3414         ptp_array_t *arr_uint16;
3415         ptp_array_t *arr_uint32;
3416
3417         quad = (prop_quad_t *)g_malloc(sizeof(prop_quad_t));
3418         if (NULL == quad)
3419                 return FALSE;
3420
3421         quad->obj_handle = obj_handle;
3422         quad->prop_code =  propcode;
3423         quad->data_type =  data_type;
3424         quad->pval = val;
3425
3426         switch (data_type) {
3427         case PTP_DATATYPE_UINT8:
3428         case PTP_DATATYPE_INT8:
3429                 quad->val_size = sizeof(mtp_uchar);
3430                 break;
3431
3432         case PTP_DATATYPE_UINT16:
3433         case PTP_DATATYPE_INT16:
3434                 quad->val_size = sizeof(mtp_uint16);
3435                 break;
3436
3437         case PTP_DATATYPE_UINT32:
3438         case PTP_DATATYPE_INT32:
3439                 quad->val_size = sizeof(mtp_uint32);
3440                 break;
3441
3442         case PTP_DATATYPE_UINT64:
3443         case PTP_DATATYPE_INT64:
3444                 quad->val_size = sizeof(mtp_int64);
3445                 break;
3446
3447         case PTP_DATATYPE_UINT128:
3448         case PTP_DATATYPE_INT128:
3449                 quad->val_size = 2 * sizeof(mtp_int64);
3450                 break;
3451
3452         case PTP_DATATYPE_AUINT8:
3453         case PTP_DATATYPE_AINT8:
3454                 memcpy(&arr_uint8, val, sizeof(ptp_array_t *));
3455                 quad->val_size = (arr_uint8 != NULL) ?
3456                         _prop_get_size_ptparray(arr_uint8) : 0;
3457                 quad->pval = (mtp_uchar *)arr_uint8;
3458                 break;
3459
3460         case PTP_DATATYPE_AUINT16:
3461         case PTP_DATATYPE_AINT16:
3462                 memcpy(&arr_uint16, val, sizeof(ptp_array_t *));
3463                 quad->val_size = (arr_uint16 != NULL) ?
3464                         _prop_get_size_ptparray(arr_uint16) : 0;
3465                 quad->pval = (mtp_uchar *)arr_uint16;
3466                 break;
3467
3468         case PTP_DATATYPE_AUINT32:
3469         case PTP_DATATYPE_AINT32:
3470                 memcpy(&arr_uint32, val, sizeof(ptp_array_t *));
3471                 quad->val_size = (arr_uint32 != NULL) ? _prop_get_size_ptparray(arr_uint32) : 0;
3472                 quad->pval = (mtp_uchar *)arr_uint32;
3473                 break;
3474
3475         case PTP_DATATYPE_STRING:
3476                 memcpy(&str, val, sizeof(ptp_string_t *));
3477                 quad->val_size = (str != NULL) ? _prop_size_ptpstring(str) : 1;
3478                 quad->pval = (mtp_uchar *)str;
3479                 break;
3480         default:
3481                 /* don't know  */
3482                 quad->val_size = 0;
3483                 break;
3484         }
3485
3486         _util_add_node(&(prop_list->prop_quad_list), quad);
3487         return TRUE;
3488 }
3489
3490 mtp_uint32 _prop_pack_obj_proplist(obj_proplist_t *prop_list, mtp_uchar *buf,
3491                 mtp_uint32 size)
3492 {
3493         mtp_uchar *temp = buf;
3494         ptp_string_t *str = NULL;
3495         prop_quad_t *quad = NULL;
3496         mtp_uint32 ii;
3497         slist_node_t *node = NULL;
3498
3499         if (!buf || size < _prop_size_obj_proplist(prop_list))
3500                 return 0;
3501
3502         *(mtp_uint32 *) buf = prop_list->prop_quad_list.nnodes;
3503 #ifdef __BIG_ENDIAN__
3504         _util_conv_byte_order(temp, sizeof(mtp_uint32));
3505 #endif /* __BIG_ENDIAN__ */
3506         temp += sizeof(mtp_uint32);
3507
3508         /* Pack the array elements */
3509         node = prop_list->prop_quad_list.start;
3510         for (ii = 0; ii < prop_list->prop_quad_list.nnodes; ii++) {
3511                 quad = (prop_quad_t *) node->value;
3512                 node = node->link;
3513                 /* pack the fixed length members */
3514                 memcpy(temp, &quad->obj_handle, sizeof(mtp_uint32));
3515 #ifdef __BIG_ENDIAN__
3516                 _util_conv_byte_order(temp, sizeof(mtp_uint32));
3517 #endif /* __BIG_ENDIAN__ */
3518                 temp += sizeof(mtp_uint32);
3519
3520                 memcpy(temp, &quad->prop_code, sizeof(mtp_uint16));
3521 #ifdef __BIG_ENDIAN__
3522                 _util_conv_byte_order(temp, sizeof(mtp_uint32));
3523 #endif /* __BIG_ENDIAN__ */
3524                 temp += sizeof(mtp_uint16);
3525
3526                 memcpy(temp, &quad->data_type, sizeof(mtp_uint16));
3527 #ifdef __BIG_ENDIAN__
3528                 _util_conv_byte_order(temp, sizeof(mtp_uint32));
3529 #endif /* __BIG_ENDIAN__ */
3530                 temp += sizeof(mtp_uint16);
3531
3532                 /* Pack property value */
3533                 if ((quad->data_type & PTP_DATATYPE_VALUEMASK) ==
3534                                 PTP_DATATYPE_VALUE) {
3535
3536                         memcpy(temp, quad->pval, quad->val_size);
3537 #ifdef __BIG_ENDIAN__
3538                         _util_conv_byte_order(temp, quad->val_size);
3539 #endif /* __BIG_ENDIAN__ */
3540                         temp += quad->val_size;
3541
3542                 } else if (quad->data_type == PTP_DATATYPE_STRING) {
3543
3544                         str = (ptp_string_t *) quad->pval;
3545                         if (str) {
3546                                 temp += _prop_pack_ptpstring(str, temp,
3547                                                 _prop_size_ptpstring(str));
3548                         } else {
3549                                 /* Put in an empty string: NumOfChars = 0; */
3550                                 *temp++ = 0;
3551                         }
3552                 } else if ((quad->data_type & PTP_DATATYPE_ARRAYMASK) ==
3553                                 PTP_DATATYPE_ARRAY) {
3554
3555                         if (quad->pval != NULL) {
3556
3557                                 if (quad->val_size !=
3558                                                 _prop_pack_ptparray((ptp_array_t *)quad->pval,
3559                                                         temp, quad->val_size)) {
3560                                         return (mtp_uint32) (temp - buf);
3561                                 }
3562                                 temp += quad->val_size;
3563                         } else {
3564                                 /* Fill in an empty array: mtp_uint32 */
3565                                 mtp_uint32 zero = 0;
3566                                 memcpy(temp, &zero, sizeof(mtp_uint32));
3567                                 temp += sizeof(mtp_uint32);
3568                         }
3569                 }
3570         }
3571
3572         return (mtp_uint32)(temp - buf);
3573 }
3574
3575 void _prop_destroy_obj_proplist(obj_proplist_t *prop_list)
3576 {
3577         slist_node_t *node = NULL;
3578         slist_node_t *next_node = NULL;
3579         mtp_uint32 ii;
3580
3581         for (ii = 0, node = prop_list->prop_quad_list.start;
3582                         ii < prop_list->prop_quad_list.nnodes; ii++, node = node->link) {
3583                 g_free(node->value);
3584         }
3585
3586         next_node = prop_list->prop_quad_list.start;
3587
3588         for (ii = 0; ii < prop_list->prop_quad_list.nnodes; ii++) {
3589                 node = next_node;
3590                 next_node = node->link;
3591                 g_free(node);
3592         }
3593         return;
3594 }
3595
3596 mtp_bool _prop_add_supp_integer_val(prop_info_t *prop_info, mtp_uint32 value)
3597 {
3598         if (((prop_info->data_type & PTP_DATATYPE_VALUEMASK) !=
3599                                 PTP_DATATYPE_VALUE) || (prop_info->form_flag != ENUM_FORM)) {
3600                 return FALSE;
3601         }
3602
3603         /* Create the node and append it. */
3604         _util_add_node(&(prop_info->supp_value_list), (void *)value);
3605
3606         return TRUE;
3607 }
3608
3609 mtp_bool _prop_add_supp_string_val(prop_info_t *prop_info, mtp_wchar *val)
3610 {
3611         ptp_string_t *str = NULL;
3612         mtp_bool ret;
3613
3614         if ((prop_info->data_type != PTP_DATATYPE_STRING) ||
3615                         (prop_info->form_flag != ENUM_FORM)) {
3616                 return FALSE;
3617         }
3618 #ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
3619         str = __alloc_ptpstring();
3620 #else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
3621         str = __alloc_ptpstring(_util_wchar_len(val));
3622 #endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
3623
3624         if (str != NULL) {
3625                 _prop_copy_char_to_ptpstring(str, val, WCHAR_TYPE);
3626                 ret = _util_add_node(&(prop_info->supp_value_list), (void *)str);
3627                 if (ret == FALSE) {
3628                         ERR("List add Fail");
3629                         g_free(str);
3630                         return FALSE;
3631                 }
3632                 return TRUE;
3633         }
3634         return FALSE;
3635 }
3636
3637 /* ObjectProp Functions */
3638 mtp_uint32 _prop_get_supp_obj_props(mtp_uint32 format_code,
3639                 ptp_array_t *supp_props)
3640 {
3641         mtp_uint32 i = 0;
3642         mtp_uint32 num_default_obj_props = 0;
3643
3644         /*Default*/
3645         if (_get_oma_drm_status() == TRUE)
3646                 num_default_obj_props = NUM_OBJECT_PROP_DESC_DEFAULT;
3647         else
3648                 num_default_obj_props = NUM_OBJECT_PROP_DESC_DEFAULT - 1;
3649
3650         for (i = 0; i < num_default_obj_props; i++) {
3651                 _prop_append_ele_ptparray(supp_props,
3652                                 props_list_default[i].propinfo.prop_code);
3653         }
3654
3655         switch (format_code) {
3656         case PTP_FMT_MP3:
3657         case PTP_FMT_WAVE:
3658                 for (i = 0; i < NUM_OBJECT_PROP_DESC_MP3; i++) {
3659                         _prop_append_ele_ptparray(supp_props,
3660                                         props_list_mp3[i].propinfo.prop_code);
3661                 }
3662                 break;
3663         case MTP_FMT_WMA:
3664                 for (i = 0; i < NUM_OBJECT_PROP_DESC_WMA; i++) {
3665                         _prop_append_ele_ptparray(supp_props,
3666                                         props_list_wma[i].propinfo.prop_code);
3667                 }
3668                 break;
3669         case MTP_FMT_WMV:
3670         case PTP_FMT_ASF:
3671         case MTP_FMT_MP4:
3672         case PTP_FMT_AVI:
3673         case PTP_FMT_MPEG:
3674         case MTP_FMT_3GP:
3675                 for (i = 0; i < NUM_OBJECT_PROP_DESC_WMV; i++) {
3676                         _prop_append_ele_ptparray(supp_props,
3677                                         props_list_wmv[i].propinfo.prop_code);
3678                 }
3679                 break;
3680         case MTP_FMT_ABSTRACT_AUDIO_ALBUM:
3681         case PTP_FMT_IMG_EXIF:
3682         case PTP_FMT_IMG_GIF:
3683         case PTP_FMT_IMG_BMP:
3684         case PTP_FMT_IMG_PNG:
3685                 for (i = 0; i < NUM_OBJECT_PROP_DESC_ALBUM; i++) {
3686                         _prop_append_ele_ptparray(supp_props,
3687                                         props_list_album[i].propinfo.prop_code);
3688                 }
3689                 break;
3690         default:
3691                 break;
3692         }
3693         DBG("getsupp_props : format [0x%x], supported list [%d]\n",
3694                         format_code, supp_props->num_ele);
3695         return supp_props->num_ele;
3696 }
3697
3698 mtp_bool _prop_build_supp_props_default(void)
3699 {
3700         mtp_wchar temp[MTP_MAX_REG_STRING + 1] = { 0 };
3701         static mtp_bool initialized = FALSE;
3702         mtp_uchar i = 0;
3703         mtp_uint32 default_val;
3704
3705         if (initialized == TRUE) {
3706                 DBG("already supported list is in there. just return!!");
3707                 return TRUE;
3708         }
3709
3710         /*
3711          * MTP_OBJ_PROPERTYCODE_STORAGEID (1)
3712          */
3713         __init_obj_prop_desc(&(props_list_default[i]),
3714                         MTP_OBJ_PROPERTYCODE_STORAGEID,
3715                         PTP_DATATYPE_UINT32,
3716                         PTP_PROPGETSET_GETONLY,
3717                         NONE,
3718                         MTP_PROP_GROUPCODE_GENERAL);
3719
3720         default_val = 0x0;
3721         _prop_set_default_integer(&(props_list_default[i].propinfo),
3722                         (mtp_uchar *)&default_val);
3723         i++;
3724
3725         /*
3726          * MTP_OBJ_PROPERTYCODE_OBJECTFORMAT (2)
3727          */
3728         __init_obj_prop_desc(&(props_list_default[i]),
3729                         MTP_OBJ_PROPERTYCODE_OBJECTFORMAT,
3730                         PTP_DATATYPE_UINT16,
3731                         PTP_PROPGETSET_GETONLY,
3732                         NONE,
3733                         MTP_PROP_GROUPCODE_GENERAL);
3734
3735         default_val = PTP_FMT_UNDEF;
3736         _prop_set_default_integer(&(props_list_default[i].propinfo),
3737                         (mtp_uchar *)&default_val);
3738         i++;
3739
3740         /*
3741          * MTP_OBJ_PROPERTYCODE_PROTECTIONSTATUS (3)
3742          */
3743         __init_obj_prop_desc(&(props_list_default[i]),
3744                         MTP_OBJ_PROPERTYCODE_PROTECTIONSTATUS,
3745                         PTP_DATATYPE_UINT16,
3746                         PTP_PROPGETSET_GETONLY,
3747                         ENUM_FORM,
3748                         MTP_PROP_GROUPCODE_GENERAL);
3749
3750         default_val = PTP_PROTECTIONSTATUS_NOPROTECTION;
3751         _prop_add_supp_integer_val(&(props_list_default[i].propinfo),
3752                         PTP_PROTECTIONSTATUS_NOPROTECTION);
3753         _prop_add_supp_integer_val(&(props_list_default[i].propinfo),
3754                         PTP_PROTECTIONSTATUS_READONLY);
3755         _prop_add_supp_integer_val(&(props_list_default[i].propinfo),
3756                         MTP_PROTECTIONSTATUS_READONLY_DATA);
3757         _prop_add_supp_integer_val(&(props_list_default[i].propinfo),
3758                         (mtp_uint32)MTP_PROTECTIONSTATUS_NONTRANSFERABLE_DATA);
3759         _prop_set_default_integer(&(props_list_default[i].propinfo),
3760                         (mtp_uchar *)&default_val);
3761         i++;
3762
3763         /*
3764          * MTP_OBJ_PROPERTYCODE_OBJECTSIZE (4)
3765          */
3766         __init_obj_prop_desc(&(props_list_default[i]),
3767                         MTP_OBJ_PROPERTYCODE_OBJECTSIZE,
3768                         PTP_DATATYPE_UINT64,
3769                         PTP_PROPGETSET_GETONLY,
3770                         NONE,
3771                         MTP_PROP_GROUPCODE_GENERAL);
3772
3773         _prop_add_supp_integer_val(&(props_list_default[i].propinfo), 0x0);
3774         i++;
3775
3776         /*
3777          * MTP_OBJ_PROPERTYCODE_OBJECTFILENAME (5)
3778          */
3779         __init_obj_prop_desc(&(props_list_default[i]),
3780                         MTP_OBJ_PROPERTYCODE_OBJECTFILENAME,
3781                         PTP_DATATYPE_STRING,
3782                         PTP_PROPGETSET_GETSET,
3783                         REGULAR_EXPRESSION_FORM,
3784                         MTP_PROP_GROUPCODE_GENERAL);
3785
3786         _util_utf8_to_utf16(temp, sizeof(temp) / WCHAR_SIZ,
3787                         "[a-zA-Z!#\\$%&`\\(\\)\\-0-9@\\^_\\'\\{\\}\\~]{1,8}\\.[[a-zA-Z!#\\$%&`\\(\\)\\-0-9@\\^_\\'\\{\\}\\~]{1,3}]");
3788         _prop_set_regexp(&(props_list_default[i]), temp);
3789
3790         _util_utf8_to_utf16(temp, sizeof(temp) / WCHAR_SIZ, "");
3791         _prop_set_default_string(&(props_list_default[i].propinfo), temp);
3792         i++;
3793
3794         /*
3795          * MTP_OBJ_PROPERTYCODE_PARENT (6)
3796          */
3797         __init_obj_prop_desc(&(props_list_default[i]),
3798                         MTP_OBJ_PROPERTYCODE_PARENT,
3799                         PTP_DATATYPE_UINT32,
3800                         PTP_PROPGETSET_GETONLY,
3801                         NONE,
3802                         MTP_PROP_GROUPCODE_GENERAL);
3803
3804         default_val = 0x0;
3805         _prop_set_default_integer(&(props_list_default[i].propinfo),
3806                         (mtp_uchar *) &default_val);
3807         i++;
3808
3809         /*
3810          * MTP_OBJ_PROPERTYCODE_PERSISTENTGUID (7)
3811          */
3812         __init_obj_prop_desc(&(props_list_default[i]),
3813                         MTP_OBJ_PROPERTYCODE_PERSISTENTGUID,
3814                         PTP_DATATYPE_UINT128,
3815                         PTP_PROPGETSET_GETONLY,
3816                         NONE,
3817                         MTP_PROP_GROUPCODE_GENERAL);
3818
3819         {
3820                 mtp_uchar guid[16] = { 0 };
3821                 _prop_set_default_integer(&(props_list_default[i].propinfo),
3822                                 guid);
3823         }
3824         i++;
3825
3826         /*
3827          * MTP_OBJ_PROPERTYCODE_NONCONSUMABLE (8)
3828          */
3829         __init_obj_prop_desc(&(props_list_default[i]),
3830                         MTP_OBJ_PROPERTYCODE_NONCONSUMABLE,
3831                         PTP_DATATYPE_UINT8,
3832                         PTP_PROPGETSET_GETONLY,
3833                         ENUM_FORM,
3834                         MTP_PROP_GROUPCODE_GENERAL);
3835
3836         default_val = 0x0;
3837         _prop_add_supp_integer_val(&(props_list_default[i].propinfo), 0x0);
3838         _prop_add_supp_integer_val(&(props_list_default[i].propinfo), 0x1);
3839         _prop_set_default_integer(&(props_list_default[i].propinfo),
3840                         (mtp_uchar *)&default_val);
3841         i++;
3842
3843         /*
3844          *MTP_OBJ_PROPERTYCODE_DATEMODIFIED (9)
3845          */
3846         __init_obj_prop_desc(&(props_list_default[i]),
3847                         MTP_OBJ_PROPERTYCODE_DATEMODIFIED,
3848                         PTP_DATATYPE_STRING,
3849                         PTP_PROPGETSET_GETONLY,
3850                         DATE_TIME_FORM,
3851                         MTP_PROP_GROUPCODE_GENERAL);
3852
3853         _prop_set_default_string(&(props_list_default[i].propinfo), temp);
3854         i++;
3855
3856         /*
3857          * MTP_OBJ_PROPERTYCODE_DATECREATED (10)
3858          */
3859         __init_obj_prop_desc(&(props_list_default[i]),
3860                         MTP_OBJ_PROPERTYCODE_DATECREATED,
3861                         PTP_DATATYPE_STRING,
3862                         PTP_PROPGETSET_GETONLY,
3863                         DATE_TIME_FORM,
3864                         MTP_PROP_GROUPCODE_GENERAL);
3865
3866         _prop_set_default_string(&(props_list_default[i].propinfo), temp);
3867         i++;
3868
3869         /*
3870          * MTP_OBJ_PROPERTYCODE_NAME (11)
3871          */
3872         __init_obj_prop_desc(&(props_list_default[i]),
3873                         MTP_OBJ_PROPERTYCODE_NAME,
3874                         PTP_DATATYPE_STRING,
3875                         PTP_PROPGETSET_GETONLY,
3876                         NONE,
3877                         MTP_PROP_GROUPCODE_GENERAL);
3878
3879         _prop_set_default_string(&(props_list_default[i].propinfo), temp);
3880         i++;
3881
3882         /*
3883          * MTP_OBJ_PROPERTYCODE_ASSOCIATIONTYPE (12)
3884          */
3885         __init_obj_prop_desc(&(props_list_default[i]),
3886                         MTP_OBJ_PROPERTYCODE_ASSOCIATIONTYPE,
3887                         PTP_DATATYPE_UINT16,
3888                         PTP_PROPGETSET_GETSET,
3889                         ENUM_FORM,
3890                         MTP_PROP_GROUPCODE_GENERAL);
3891
3892         default_val = PTP_ASSOCIATIONTYPE_UNDEFINED;
3893         _prop_add_supp_integer_val(&(props_list_default[i].propinfo),
3894                         PTP_ASSOCIATIONTYPE_UNDEFINED);
3895         _prop_add_supp_integer_val(&(props_list_default[i].propinfo),
3896                         PTP_ASSOCIATIONTYPE_FOLDER);
3897         _prop_set_default_integer(&(props_list_default[i].propinfo),
3898                         (mtp_uchar *)&default_val);
3899
3900         if (_get_oma_drm_status() == TRUE) {
3901                 /*
3902                  * MTP_OBJ_PROPERTYCODE_OMADRMSTATUS (13)
3903                  */
3904                 i++;
3905                 __init_obj_prop_desc(&(props_list_default[i]),
3906                                 MTP_OBJ_PROPERTYCODE_OMADRMSTATUS,
3907                                 PTP_DATATYPE_UINT8,
3908                                 PTP_PROPGETSET_GETONLY,
3909                                 ENUM_FORM,
3910                                 MTP_PROP_GROUPCODE_GENERAL);
3911
3912                 default_val = 0;
3913                 _prop_add_supp_integer_val(&(props_list_default[i].propinfo), 0);
3914                 _prop_add_supp_integer_val(&(props_list_default[i].propinfo), 1);
3915                 _prop_set_default_integer(&(props_list_default[i].propinfo),
3916                                 (mtp_uchar *)&default_val);
3917         }
3918
3919         initialized = TRUE;
3920
3921         return TRUE;
3922 }
3923
3924 mtp_bool _prop_build_supp_props_mp3(void)
3925 {
3926         static mtp_bool initialized = FALSE;
3927         mtp_uchar i = 0;
3928         mtp_uint32 default_val;
3929
3930         if (initialized == TRUE) {
3931                 DBG("already supported list is in there. just return!!");
3932                 return TRUE;
3933         }
3934
3935         /*Common properties 1 - 8 */
3936         __build_supported_common_props(&i, &props_list_mp3[i]);
3937
3938         /*
3939          * MTP_OBJ_PROPERTYCODE_AUDIOBITRATE (9)
3940          */
3941         __init_obj_prop_desc(&(props_list_mp3[i]),
3942                         MTP_OBJ_PROPERTYCODE_AUDIOBITRATE,
3943                         PTP_DATATYPE_UINT32,
3944                         PTP_PROPGETSET_GETONLY,
3945                         RANGE_FORM,
3946                         MTP_PROP_GROUPCODE_OBJECT);
3947
3948         default_val = MTP_AUDIO_BITRATE_UNKNOWN;
3949         _prop_set_range_integer(&(props_list_mp3[i].propinfo),
3950                         MTP_AUDIO_BITRATE_UNKNOWN, MTP_AUDIO_BITRATE_BLUERAY, 1L);
3951         _prop_set_default_integer(&(props_list_mp3[i].propinfo),
3952                         (mtp_uchar *)&default_val);
3953         i++;
3954
3955         /*
3956          * MTP_OBJ_PROPERTYCODE_SAMPLERATE (10)
3957          */
3958         __init_obj_prop_desc(&(props_list_mp3[i]),
3959                         MTP_OBJ_PROPERTYCODE_SAMPLERATE,
3960                         PTP_DATATYPE_UINT32,
3961                         PTP_PROPGETSET_GETONLY,
3962                         RANGE_FORM,
3963                         MTP_PROP_GROUPCODE_OBJECT);
3964
3965         default_val = MTP_AUDIO_SAMPLERATE_UNKNOWN;
3966         _prop_set_range_integer(&(props_list_mp3[i].propinfo),
3967                         MTP_AUDIO_SAMPLERATE_8K, MTP_AUDIO_SAMPLERATE_48K, 1L);
3968         _prop_set_default_integer(&(props_list_mp3[i].propinfo),
3969                         (mtp_uchar *)&default_val);
3970         i++;
3971
3972         /*
3973          * MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS (11)
3974          */
3975         __init_obj_prop_desc(&(props_list_mp3[i]),
3976                         MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS,
3977                         PTP_DATATYPE_UINT16,
3978                         PTP_PROPGETSET_GETONLY,
3979                         ENUM_FORM,
3980                         MTP_PROP_GROUPCODE_OBJECT);
3981
3982         default_val = MTP_CHANNELS_MONO;
3983         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
3984                         MTP_CHANNELS_NOT_USED);
3985         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
3986                         MTP_CHANNELS_MONO);
3987         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
3988                         MTP_CHANNELS_STEREO);
3989         _prop_set_default_integer(&(props_list_mp3[i].propinfo),
3990                         (mtp_uchar *)&default_val);
3991         i++;
3992
3993         /*
3994          * MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC (12)
3995          */
3996         __init_obj_prop_desc(&(props_list_mp3[i]),
3997                         MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC,
3998                         PTP_DATATYPE_UINT32,
3999                         PTP_PROPGETSET_GETONLY,
4000                         ENUM_FORM,
4001                         MTP_PROP_GROUPCODE_OBJECT);
4002
4003         default_val = MTP_WAVEFORMAT_UNKNOWN;
4004         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4005                         MTP_WAVEFORMAT_UNKNOWN);
4006         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4007                         MTP_WAVEFORMAT_PCM);
4008         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4009                         MTP_WAVEFORMAT_ADPCM);
4010         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4011                         MTP_WAVEFORMAT_IEEEFLOAT);
4012         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4013                         MTP_WAVEFORMAT_DTS);
4014         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4015                         MTP_WAVEFORMAT_DRM);
4016         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4017                         MTP_WAVEFORMAT_WMSP2);
4018         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4019                         MTP_WAVEFORMAT_GSM610);
4020         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4021                         MTP_WAVEFORMAT_MSNAUDIO);
4022         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4023                         MTP_WAVEFORMAT_MPEG);
4024         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4025                         MTP_WAVEFORMAT_MPEGLAYER3);
4026         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4027                         MTP_WAVEFORMAT_MSAUDIO1);
4028         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4029                         MTP_WAVEFORMAT_MSAUDIO2);
4030         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4031                         MTP_WAVEFORMAT_MSAUDIO3);
4032         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4033                         MTP_WAVEFORMAT_WMAUDIOLOSSLESS);
4034         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4035                         MTP_WAVEFORMAT_WMASPDIF);
4036         _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
4037                         MTP_WAVEFORMAT_AAC);
4038         _prop_set_default_integer(&(props_list_mp3[i].propinfo),
4039                         (mtp_uchar *)&default_val);
4040         i++;
4041
4042         /*
4043          * MTP_OBJ_PROPERTYCODE_DESCRIPTION (13)
4044          */
4045         __init_obj_prop_desc(&(props_list_mp3[i]),
4046                         MTP_OBJ_PROPERTYCODE_DESCRIPTION,
4047                         PTP_DATATYPE_AUINT16,
4048                         PTP_PROPGETSET_GETONLY,
4049                         LONG_STRING_FORM,
4050                         MTP_PROP_GROUPCODE_GENERAL);
4051
4052         _prop_set_maxlen(&(props_list_mp3[i]), MAX_PTP_STRING_CHARS);
4053         _prop_set_default_array(&(props_list_mp3[i].propinfo), NULL, 0);
4054         i++;
4055
4056         /*
4057          * MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO (14)
4058          */
4059         __init_obj_prop_desc(&(props_list_mp3[i]),
4060                         MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO,
4061                         PTP_DATATYPE_AUINT16,
4062                         PTP_PROPGETSET_GETONLY,
4063                         LONG_STRING_FORM,
4064                         MTP_PROP_GROUPCODE_GENERAL);
4065
4066         _prop_set_maxlen(&(props_list_mp3[i]), MAX_PTP_STRING_CHARS);
4067         _prop_set_default_array(&(props_list_mp3[i].propinfo), NULL, 0);
4068
4069         initialized = TRUE;
4070         return TRUE;
4071 }
4072
4073 mtp_bool _prop_build_supp_props_wma(void)
4074 {
4075         static mtp_bool initialized = FALSE;
4076         mtp_uchar i = 0;
4077         mtp_uint32 default_val;
4078
4079         if (initialized == TRUE) {
4080                 DBG("already supported list is in there. just return!!");
4081                 return TRUE;
4082         }
4083
4084         /*Common properties 1 - 8 */
4085         __build_supported_common_props(&i, &props_list_wma[i]);
4086         /*
4087          * MTP_OBJ_PROPERTYCODE_AUDIOBITRATE (9)
4088          */
4089         __init_obj_prop_desc(&(props_list_wma[i]),
4090                         MTP_OBJ_PROPERTYCODE_AUDIOBITRATE,
4091                         PTP_DATATYPE_UINT32,
4092                         PTP_PROPGETSET_GETONLY,
4093                         RANGE_FORM,
4094                         MTP_PROP_GROUPCODE_OBJECT);
4095
4096         default_val = MTP_AUDIO_BITRATE_UNKNOWN;
4097         _prop_set_range_integer(&(props_list_wma[i].propinfo),
4098                         MTP_AUDIO_BITRATE_UNKNOWN, MTP_AUDIO_BITRATE_BLUERAY, 1L);
4099         _prop_set_default_integer(&(props_list_wma[i].propinfo),
4100                         (mtp_uchar *)&default_val);
4101         i++;
4102
4103         /*
4104          * MTP_OBJ_PROPERTYCODE_SAMPLERATE (10)
4105          */
4106         __init_obj_prop_desc(&(props_list_wma[i]),
4107                         MTP_OBJ_PROPERTYCODE_SAMPLERATE,
4108                         PTP_DATATYPE_UINT32,
4109                         PTP_PROPGETSET_GETONLY,
4110                         RANGE_FORM,
4111                         MTP_PROP_GROUPCODE_OBJECT);
4112
4113         default_val = MTP_AUDIO_SAMPLERATE_UNKNOWN;
4114         _prop_set_range_integer(&(props_list_wma[i].propinfo),
4115                         MTP_AUDIO_SAMPLERATE_8K, MTP_AUDIO_SAMPLERATE_48K, 1L);
4116         _prop_set_default_integer(&(props_list_wma[i]).propinfo,
4117                         (mtp_uchar *)&default_val);
4118         i++;
4119
4120         /*
4121          * MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS (11)
4122          */
4123         __init_obj_prop_desc(&(props_list_wma[i]),
4124                         MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS,
4125                         PTP_DATATYPE_UINT16,
4126                         PTP_PROPGETSET_GETONLY,
4127                         ENUM_FORM,
4128                         MTP_PROP_GROUPCODE_OBJECT);
4129
4130         default_val = MTP_CHANNELS_MONO;
4131         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4132                         MTP_CHANNELS_NOT_USED);
4133         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4134                         MTP_CHANNELS_MONO);
4135         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4136                         MTP_CHANNELS_STEREO);
4137         _prop_set_default_integer(&(props_list_wma[i].propinfo),
4138                         (mtp_uchar *)&default_val);
4139         i++;
4140
4141         /*
4142          * MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC (12)
4143          */
4144         __init_obj_prop_desc(&(props_list_wma[i]),
4145                         MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC,
4146                         PTP_DATATYPE_UINT32,
4147                         PTP_PROPGETSET_GETONLY,
4148                         ENUM_FORM,
4149                         MTP_PROP_GROUPCODE_OBJECT);
4150
4151         default_val = MTP_WAVEFORMAT_UNKNOWN;
4152         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4153                         MTP_WAVEFORMAT_UNKNOWN);
4154         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4155                         MTP_WAVEFORMAT_PCM);
4156         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4157                         MTP_WAVEFORMAT_ADPCM);
4158         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4159                         MTP_WAVEFORMAT_IEEEFLOAT);
4160         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4161                         MTP_WAVEFORMAT_DTS);
4162         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4163                         MTP_WAVEFORMAT_DRM);
4164         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4165                         MTP_WAVEFORMAT_WMSP2);
4166         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4167                         MTP_WAVEFORMAT_GSM610);
4168         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4169                         MTP_WAVEFORMAT_MSNAUDIO);
4170         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4171                         MTP_WAVEFORMAT_MPEG);
4172         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4173                         MTP_WAVEFORMAT_MPEGLAYER3);
4174         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4175                         MTP_WAVEFORMAT_MSAUDIO1);
4176         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4177                         MTP_WAVEFORMAT_MSAUDIO2);
4178         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4179                         MTP_WAVEFORMAT_MSAUDIO3);
4180         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4181                         MTP_WAVEFORMAT_WMAUDIOLOSSLESS);
4182         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4183                         MTP_WAVEFORMAT_WMASPDIF);
4184         _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
4185                         MTP_WAVEFORMAT_AAC);
4186         _prop_set_default_integer(&(props_list_wma[i].propinfo),
4187                         (mtp_uchar *)&default_val);
4188         i++;
4189
4190         /*
4191          * MTP_OBJ_PROPERTYCODE_DESCRIPTION (13)
4192          */
4193         __init_obj_prop_desc(&(props_list_wma[i]),
4194                         MTP_OBJ_PROPERTYCODE_DESCRIPTION,
4195                         PTP_DATATYPE_AUINT16,
4196                         PTP_PROPGETSET_GETONLY,
4197                         LONG_STRING_FORM,
4198                         MTP_PROP_GROUPCODE_GENERAL);
4199
4200         _prop_set_maxlen(&(props_list_wma[i]), MAX_PTP_STRING_CHARS);
4201         _prop_set_default_array(&(props_list_wma[i].propinfo), NULL, 0);
4202         i++;
4203
4204         /*
4205          * MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO (14)
4206          */
4207         __init_obj_prop_desc(&(props_list_wma[i]),
4208                         MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO,
4209                         PTP_DATATYPE_AUINT16,
4210                         PTP_PROPGETSET_GETONLY,
4211                         LONG_STRING_FORM,
4212                         MTP_PROP_GROUPCODE_GENERAL);
4213
4214         _prop_set_maxlen(&(props_list_wma[i]), MAX_PTP_STRING_CHARS);
4215         _prop_set_default_array(&(props_list_wma[i].propinfo), NULL, 0);
4216
4217         /*-------------------------------------------------------------
4218          * Valid Configurations for interdependent Object properties
4219          *-------------------------------------------------------------
4220          */
4221 #ifdef MTP_SUPPORT_INTERDEPENDENTPROP
4222         {
4223                 interdep_prop_config_t *ptr_interdep_prop_cfg = NULL;
4224                 obj_prop_desc_t *prop = NULL;
4225                 mtp_uint32 default_val;
4226
4227                 _util_init_list(&(interdep_proplist.plist));
4228
4229                 prop = (obj_prop_desc_t *)g_malloc(sizeof(obj_prop_desc_t) * 4);
4230                 if (!prop) {
4231                         ERR("prop g_malloc fail");
4232                         return FALSE;
4233                 }
4234                 /* Valid config. 1 for Bit Rate and Sample Rate */
4235                 ptr_interdep_prop_cfg =
4236                         (interdep_prop_config_t *)g_malloc(sizeof(interdep_prop_config_t));
4237                 if (!ptr_interdep_prop_cfg) {
4238                         g_free(prop);
4239                         ERR("ptr_interdep_prop_config g_malloc fail");
4240                         return FALSE;
4241                 }
4242
4243                 _util_init_list(&(ptr_interdep_prop_cfg->propdesc_list));
4244                 if (!ptr_interdep_prop_cfg) {
4245                         g_free(prop);
4246                         return FALSE;
4247                 }
4248                 ptr_interdep_prop_cfg->format_code = MTP_FMT_WMA;
4249                 i = 0;
4250
4251                 __init_obj_prop_desc(&(prop[i]),
4252                                 MTP_OBJ_PROPERTYCODE_TOTALBITRATE,
4253                                 PTP_DATATYPE_UINT32,
4254                                 PTP_PROPGETSET_GETONLY,
4255                                 RANGE_FORM, MTP_PROP_GROUPCODE_GENERAL);
4256
4257                 default_val = MTP_AUDIO_BITRATE_192K;
4258                 _prop_set_range_integer(&(prop[i].propinfo),
4259                                 MTP_AUDIO_BITRATE_192K,
4260                                 MTP_AUDIO_BITRATE_256K, 1000L);
4261                 _prop_set_default_integer(&(prop[i].propinfo),
4262                                 (mtp_uchar *)&default_val);
4263                 __append_interdep_prop(ptr_interdep_prop_cfg, &(prop[i]));
4264                 i++;
4265
4266                 __init_obj_prop_desc(&(prop[i]),
4267                                 MTP_OBJ_PROPERTYCODE_SAMPLERATE,
4268                                 PTP_DATATYPE_UINT32,
4269                                 PTP_PROPGETSET_GETONLY,
4270                                 ENUM_FORM, MTP_PROP_GROUPCODE_GENERAL);
4271
4272                 _prop_add_supp_integer_val(&(prop[i].propinfo),
4273                                 MTP_AUDIO_SAMPLERATE_DVD);
4274                 _prop_set_default_integer(&(prop[i].propinfo),
4275                                 (mtp_uchar *)MTP_AUDIO_SAMPLERATE_DVD);
4276                 __append_interdep_prop(ptr_interdep_prop_cfg, &(prop[i]));
4277                 i++;
4278
4279                 /* Created one valid configuration */
4280
4281                 mtp_bool ret;
4282                 ret = _util_add_node(&(interdep_proplist.plist),
4283                                 (void *)ptr_interdep_prop_cfg);
4284                 if (ret == FALSE) {
4285                         g_free(prop);
4286                         ERR("List add Fail");
4287                         return FALSE;
4288                 }
4289
4290                 /* Valid config. 2 for Bit Rate and Sample Rate */
4291                 ptr_interdep_prop_cfg =
4292                         (interdep_prop_config_t *)g_malloc(sizeof(interdep_prop_config_t));
4293                 if (!ptr_interdep_prop_cfg) {
4294                         g_free(prop);
4295                         ERR("ptr_interdep_prop_cfg g_malloc fail");
4296                         return FALSE;
4297                 }
4298                 _util_init_list(&(ptr_interdep_prop_cfg->propdesc_list));
4299
4300                 if (!ptr_interdep_prop_cfg) {
4301                         g_free(prop);
4302                         return FALSE;
4303                 }
4304                 ptr_interdep_prop_cfg->format_code = MTP_FMT_WMA;
4305
4306                 __init_obj_prop_desc(&(prop[i]),
4307                                 MTP_OBJ_PROPERTYCODE_TOTALBITRATE,
4308                                 PTP_DATATYPE_UINT32,
4309                                 PTP_PROPGETSET_GETONLY,
4310                                 RANGE_FORM, MTP_PROP_GROUPCODE_GENERAL);
4311
4312                 default_val = 0x0;
4313                 _prop_set_range_integer(&(prop[i].propinfo),
4314                                 MTP_AUDIO_BITRATE_GSM,
4315                                 MTP_AUDIO_BITRATE_BLUERAY, 1L);
4316                 _prop_set_default_integer(&(prop[i].propinfo),
4317                                 (mtp_uchar *)&default_val);
4318                 __append_interdep_prop(ptr_interdep_prop_cfg, &(prop[i]));
4319                 i++;
4320
4321                 __init_obj_prop_desc(&(prop[i]),
4322                                 MTP_OBJ_PROPERTYCODE_SAMPLERATE,
4323                                 PTP_DATATYPE_UINT32,
4324                                 PTP_PROPGETSET_GETONLY,
4325                                 ENUM_FORM, MTP_PROP_GROUPCODE_GENERAL);
4326
4327                 default_val = MTP_AUDIO_SAMPLERATE_CD;
4328                 _prop_add_supp_integer_val(&(prop[i].propinfo),
4329                                 MTP_AUDIO_SAMPLERATE_32K);
4330                 _prop_add_supp_integer_val(&(prop[i].propinfo),
4331                                 MTP_AUDIO_SAMPLERATE_CD);
4332                 _prop_set_default_integer(&(prop[i].propinfo),
4333                                 (mtp_uchar *)&default_val);
4334                 __append_interdep_prop(ptr_interdep_prop_cfg, &(prop[i]));
4335                 i++;
4336
4337                 /* Created one valid configuration */
4338                 ret = _util_add_node(&(interdep_proplist.plist),
4339                                 (void *)ptr_interdep_prop_cfg);
4340                 if (ret == FALSE) {
4341                         g_free(prop);
4342                         ERR("List add Fail");
4343                         return FALSE;
4344                 }
4345                 g_free(prop);
4346         }
4347 #endif /*MTP_SUPPORT_INTERDEPENDENTPROP*/
4348
4349         initialized = TRUE;
4350
4351         return TRUE;
4352 }
4353
4354 mtp_bool _prop_build_supp_props_wmv(void)
4355 {
4356         static mtp_bool initialized = FALSE;
4357         mtp_wchar buff[3] = { 0 };
4358         mtp_uchar i = 0;
4359         mtp_uint32 default_val;
4360
4361         if (initialized == TRUE) {
4362                 DBG("already supported list is in there. just return!!");
4363                 return TRUE;
4364         }
4365         _util_utf8_to_utf16(buff, sizeof(buff) / WCHAR_SIZ, "");
4366
4367         /*Common properties 1 - 8 */
4368         __build_supported_common_props(&i, &props_list_wmv[i]);
4369
4370         /*
4371          * MTP_OBJ_PROPERTYCODE_WIDTH (9)
4372          */
4373         __init_obj_prop_desc(&(props_list_wmv[i]),
4374                         MTP_OBJ_PROPERTYCODE_WIDTH,
4375                         PTP_DATATYPE_UINT32,
4376                         PTP_PROPGETSET_GETONLY,
4377                         RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
4378
4379         default_val = 0x0;
4380         _prop_set_range_integer(&(props_list_wmv[i].propinfo),
4381                         MTP_MIN_VIDEO_WIDTH, MTP_MAX_VIDEO_WIDTH,
4382                         MTP_VIDEO_HEIGHT_WIDTH_INTERVAL);
4383         _prop_set_default_integer(&(props_list_wmv[i].propinfo),
4384                         (mtp_uchar *)&default_val);
4385         i++;
4386
4387         /*
4388          * MTP_OBJ_PROPERTYCODE_HEIGHT (10)
4389          */
4390         __init_obj_prop_desc(&(props_list_wmv[i]),
4391                         MTP_OBJ_PROPERTYCODE_HEIGHT,
4392                         PTP_DATATYPE_UINT32,
4393                         PTP_PROPGETSET_GETONLY,
4394                         RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
4395
4396         default_val = 0x0;
4397         _prop_set_range_integer(&(props_list_wmv[i].propinfo),
4398                         MTP_MIN_VIDEO_HEIGHT, MTP_MAX_VIDEO_HEIGHT,
4399                         MTP_VIDEO_HEIGHT_WIDTH_INTERVAL);
4400         _prop_set_default_integer(&(props_list_wmv[i].propinfo),
4401                         (mtp_uchar *)&default_val);
4402
4403         i++;
4404
4405         /*
4406          * MTP_OBJ_PROPERTYCODE_SAMPLERATE (11)
4407          */
4408         __init_obj_prop_desc(&(props_list_wmv[i]),
4409                         MTP_OBJ_PROPERTYCODE_SAMPLERATE,
4410                         PTP_DATATYPE_UINT32,
4411                         PTP_PROPGETSET_GETONLY,
4412                         RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
4413
4414         default_val = MTP_AUDIO_SAMPLERATE_8K;
4415         _prop_set_range_integer(&(props_list_wmv[i]).propinfo,
4416                         MTP_AUDIO_SAMPLERATE_8K,
4417                         MTP_AUDIO_SAMPLERATE_DVD, MTP_AUDIO_SAMPLE_RATE_INTERVAL);
4418         _prop_set_default_integer(&(props_list_wmv[i].propinfo),
4419                         (mtp_uchar *)&default_val);
4420         i++;
4421
4422         /*
4423          * MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS (12)
4424          */
4425         __init_obj_prop_desc(&(props_list_wmv[i]),
4426                         MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS,
4427                         PTP_DATATYPE_UINT16,
4428                         PTP_PROPGETSET_GETONLY,
4429                         ENUM_FORM, MTP_PROP_GROUPCODE_OBJECT);
4430
4431         default_val = MTP_CHANNELS_MONO;
4432         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4433                         MTP_CHANNELS_NOT_USED);
4434         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4435                         MTP_CHANNELS_MONO);
4436         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4437                         MTP_CHANNELS_STEREO);
4438         _prop_set_default_integer(&(props_list_wmv[i].propinfo),
4439                         (mtp_uchar *)&default_val);
4440         i++;
4441
4442         /*
4443          * MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC (13)
4444          */
4445         __init_obj_prop_desc(&(props_list_wmv[i]),
4446                         MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC,
4447                         PTP_DATATYPE_UINT32,
4448                         PTP_PROPGETSET_GETONLY,
4449                         ENUM_FORM, MTP_PROP_GROUPCODE_OBJECT);
4450
4451         default_val = MTP_WAVEFORMAT_UNKNOWN;
4452         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4453                         MTP_WAVEFORMAT_UNKNOWN);
4454         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4455                         MTP_WAVEFORMAT_MPEGLAYER3);
4456         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4457                         MTP_WAVEFORMAT_MSAUDIO1);
4458         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4459                         MTP_WAVEFORMAT_MSAUDIO2);
4460         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4461                         MTP_WAVEFORMAT_PCM);
4462         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4463                         MTP_WAVEFORMAT_ADPCM);
4464         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4465                         MTP_WAVEFORMAT_MSAUDIO3);
4466         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4467                         MTP_WAVEFORMAT_RAW_AAC1);
4468         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4469                         MTP_WAVEFORMAT_MPEG_HEAAC);
4470         _prop_set_default_integer(&(props_list_wmv[i].propinfo),
4471                         (mtp_uchar *)&default_val);
4472         i++;
4473
4474         /*
4475          * MTP_OBJ_PROPERTYCODE_AUDIOBITRATE (14)
4476          */
4477         __init_obj_prop_desc(&(props_list_wmv[i]),
4478                         MTP_OBJ_PROPERTYCODE_AUDIOBITRATE,
4479                         PTP_DATATYPE_UINT32,
4480                         PTP_PROPGETSET_GETONLY,
4481                         RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
4482
4483         default_val = MTP_AUDIO_BITRATE_UNKNOWN;
4484         _prop_set_range_integer(&(props_list_wmv[i].propinfo),
4485                         MTP_AUDIO_BITRATE_UNKNOWN,
4486                         MTP_AUDIO_BITRATE_BLUERAY, 1L);
4487         _prop_set_default_integer(&(props_list_wmv[i].propinfo),
4488                         (mtp_uchar *)&default_val);
4489         i++;
4490
4491         /*
4492          * MTP_OBJ_PROPERTYCODE_VIDEOFOURCCCODEC (15)
4493          */
4494         __init_obj_prop_desc(&(props_list_wmv[i]),
4495                         MTP_OBJ_PROPERTYCODE_VIDEOFOURCCCODEC,
4496                         PTP_DATATYPE_UINT32,
4497                         PTP_PROPGETSET_GETONLY,
4498                         ENUM_FORM, MTP_PROP_GROUPCODE_OBJECT);
4499
4500         default_val = MTP_VIDEOFOURCC_MP42;
4501         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4502                         MTP_VIDEOFOURCC_UNKNOWN);
4503         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4504                         MTP_VIDEOFOURCC_H263);
4505         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4506                         MTP_VIDEOFOURCC_H264);
4507         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4508                         MTP_VIDEOFOURCC_MP42);
4509         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4510                         MTP_VIDEOFOURCC_MP43);
4511         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4512                         MTP_VIDEOFOURCC_WMV1);
4513         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4514                         MTP_VIDEOFOURCC_WMV2);
4515         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4516                         MTP_VIDEOFOURCC_WMV3);
4517         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4518                         MTP_VIDEOFOURCC_DIVX);
4519         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4520                         MTP_VIDEOFOURCC_XVID);
4521         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4522                         MTP_VIDEOFOURCC_M4S2);
4523         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4524                         MTP_VIDEOFOURCC_MP4V);
4525         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4526                         MTP_VIDEOFOURCC_AVC1);
4527         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4528                         MTP_VIDEOFOURCC_h264);
4529         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4530                         MTP_VIDEOFOURCC_X264);
4531         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4532                         MTP_VIDEOFOURCC_N264);
4533         _prop_set_default_integer(&(props_list_wmv[i].propinfo),
4534                         (mtp_uchar *)&default_val);
4535         i++;
4536
4537         /*
4538          * MTP_OBJ_PROPERTYCODE_VIDEOBITRATE (16)
4539          */
4540         __init_obj_prop_desc(&(props_list_wmv[i]),
4541                         MTP_OBJ_PROPERTYCODE_VIDEOBITRATE,
4542                         PTP_DATATYPE_UINT32,
4543                         PTP_PROPGETSET_GETONLY,
4544                         RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
4545
4546         default_val = MTP_MIN_VIDEO_BITRATE;
4547         _prop_set_range_integer(&(props_list_wmv[i].propinfo),
4548                         MTP_MIN_VIDEO_BITRATE, MTP_MAX_VIDEO_BITRATE, 1L);
4549         _prop_set_default_integer(&(props_list_wmv[i].propinfo),
4550                         (mtp_uchar *)&default_val);
4551         i++;
4552
4553         /*
4554          * MTP_OBJ_PROPERTYCODE_FRAMESPER1KSECONDS (17)
4555          */
4556         __init_obj_prop_desc(&(props_list_wmv[i]),
4557                         MTP_OBJ_PROPERTYCODE_FRAMESPER1KSECONDS,
4558                         PTP_DATATYPE_UINT32,
4559                         PTP_PROPGETSET_GETONLY,
4560                         RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
4561
4562         default_val = MTP_MIN_VIDEO_FPS;
4563         _prop_set_range_integer(&(props_list_wmv[i].propinfo), MTP_MIN_VIDEO_FPS,
4564                         MTP_MAX_VIDEO_FPS, 1L);
4565         _prop_set_default_integer(&(props_list_wmv[i].propinfo),
4566                         (mtp_uchar *)&default_val);
4567         i++;
4568
4569         /*
4570          * MTP_OBJ_PROPERTYCODE_DESCRIPTION (18)
4571          */
4572         __init_obj_prop_desc(&(props_list_wmv[i]),
4573                         MTP_OBJ_PROPERTYCODE_DESCRIPTION,
4574                         PTP_DATATYPE_AUINT16,
4575                         PTP_PROPGETSET_GETONLY,
4576                         LONG_STRING_FORM,
4577                         MTP_PROP_GROUPCODE_GENERAL);
4578
4579         _prop_set_maxlen(&(props_list_wmv[i]), MAX_PTP_STRING_CHARS);
4580         _prop_set_default_array(&(props_list_wmv[i].propinfo), NULL, 0);
4581         i++;
4582
4583         /*
4584          * MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO (19)
4585          */
4586         __init_obj_prop_desc(&(props_list_wmv[i]),
4587                         MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO,
4588                         PTP_DATATYPE_AUINT16,
4589                         PTP_PROPGETSET_GETONLY,
4590                         LONG_STRING_FORM,
4591                         MTP_PROP_GROUPCODE_GENERAL);
4592
4593         _prop_set_maxlen(&(props_list_wmv[i]), MAX_PTP_STRING_CHARS);
4594         _prop_set_default_array(&(props_list_wmv[i].propinfo), NULL, 0);
4595         i++;
4596
4597         /*
4598          * MTP_OBJ_PROPERTYCODE_ENCODINGPROFILE (20)
4599          */
4600         __init_obj_prop_desc(&(props_list_wmv[i]),
4601                         MTP_OBJ_PROPERTYCODE_ENCODINGPROFILE,
4602                         PTP_DATATYPE_STRING,
4603                         PTP_PROPGETSET_GETONLY,
4604                         ENUM_FORM, MTP_PROP_GROUPCODE_OBJECT);
4605
4606         _util_utf8_to_utf16(buff, sizeof(buff) / WCHAR_SIZ, "SP");
4607         _prop_add_supp_string_val(&(props_list_wmv[i].propinfo), buff);
4608         _util_utf8_to_utf16(buff, sizeof(buff) / WCHAR_SIZ, "MP");
4609         _prop_add_supp_string_val(&(props_list_wmv[i].propinfo), buff);
4610         _util_utf8_to_utf16(buff, sizeof(buff) / WCHAR_SIZ, "SP");
4611         _prop_set_default_string(&(props_list_wmv[i].propinfo), buff);
4612         i++;
4613
4614         /*
4615          * MTP_OBJ_PROPERTYCODE_METAGENRE (21)
4616          */
4617         __init_obj_prop_desc(&(props_list_wmv[i]),
4618                         MTP_OBJ_PROPERTYCODE_METAGENRE,
4619                         PTP_DATATYPE_UINT16,
4620                         PTP_PROPGETSET_GETONLY,
4621                         ENUM_FORM, MTP_PROP_GROUPCODE_OBJECT);
4622
4623         default_val = MTP_METAGENRE_NOT_USED;
4624         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4625                         MTP_METAGENRE_NOT_USED);
4626         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4627                         MTP_METAGENRE_GENERIC_MUSIC_AUDIO_FILE);
4628         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4629                         MTP_METAGENRE_GENERIC_NONMUSIC_AUDIO_FILE);
4630         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4631                         MTP_METAGENRE_SPOKEN_WORD_AUDIO_BOOK_FILES);
4632         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4633                         MTP_METAGENRE_SPOKEN_WORD_NONAUDIO_BOOK_FILES);
4634         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4635                         MTP_METAGENRE_SPOKEN_WORD_NEWS);
4636         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4637                         MTP_METAGENRE_GENERIC_VIDEO_FILE);
4638         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4639                         MTP_METAGENRE_NEWS_VIDEO_FILE);
4640         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4641                         MTP_METAGENRE_MUSIC_VIDEO_FILE);
4642         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4643                         MTP_METAGENRE_HOME_VIDEO_FILE);
4644         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4645                         MTP_METAGENRE_FEATURE_FILM_VIDEO_FILE);
4646         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4647                         MTP_METAGENRE_TV_SHOW_VIDEO_FILE);
4648         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4649                         MTP_METAGENRE_TRAINING_VIDEO_FILE);
4650         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4651                         MTP_METAGENRE_PHOTO_MONTAGE_VIDEO_FILE);
4652         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4653                         MTP_METAGENRE_GENERIC_NONAUDIO_NONVIDEO_FILE);
4654         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4655                         MTP_METAGENRE_AUDIO_MEDIA_CAST_FILE);
4656         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4657                         MTP_METAGENRE_VIDEO_MEDIA_CAST_FILE);
4658         _prop_set_default_integer(&(props_list_wmv[i].propinfo),
4659                         (mtp_uchar *)&default_val);
4660         i++;
4661
4662         /*
4663          * MTP_OBJ_PROPERTYCODE_SCANTYPE (22)
4664          */
4665         __init_obj_prop_desc(&(props_list_wmv[i]),
4666                         MTP_OBJ_PROPERTYCODE_SCANTYPE,
4667                         PTP_DATATYPE_UINT16,
4668                         PTP_PROPGETSET_GETONLY,
4669                         ENUM_FORM, MTP_PROP_GROUPCODE_OBJECT);
4670
4671         default_val = MTP_SCANTYPE_NOT_USED;
4672         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4673                         MTP_SCANTYPE_NOT_USED);
4674         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4675                         MTP_SCANTYPE_PROGESSIVE);
4676         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4677                         MTP_SCANTYPE_FIELDINTERLEAVEDUPPERFIRST);
4678         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4679                         MTP_SCANTYPE_FIELDINTERLEAVEDLOWERFIRST);
4680         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4681                         MTP_SCANTYPE_FIELDSINGLEUPPERFIRST);
4682         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4683                         MTP_SCANTYPE_FIELDSINGLELOWERFIRST);
4684         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4685                         MTP_SCANTYPE_MIXEDINTERLACE);
4686         _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
4687                         MTP_SCANTYPE_MIXEDINTERLACEANDPROGRESSIVE);
4688         _prop_set_default_integer(&(props_list_wmv[i].propinfo),
4689                         (mtp_uchar *)&default_val);
4690
4691 #ifdef MTP_SUPPORT_PROPERTY_SAMPLE
4692         __build_supported_sample_props(&i, &props_list_wmv[i]);
4693 #endif /*MTP_SUPPORT_PROPERTY_SAMPLE*/
4694
4695         initialized = TRUE;
4696
4697         return TRUE;
4698 }
4699
4700 mtp_bool _prop_build_supp_props_album(void)
4701 {
4702         static mtp_bool initialized = FALSE;
4703         mtp_uchar i = 0;
4704         mtp_uint32 default_val;
4705
4706         if (initialized == TRUE) {
4707                 DBG("already supported list is in there. just return!!");
4708                 return TRUE;
4709         }
4710
4711         /*
4712          * MTP_OBJ_PROPERTYCODE_WIDTH (1)
4713          */
4714         __init_obj_prop_desc(&(props_list_album[i]),
4715                         MTP_OBJ_PROPERTYCODE_WIDTH,
4716                         PTP_DATATYPE_UINT32,
4717                         PTP_PROPGETSET_GETONLY,
4718                         RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
4719
4720         default_val = 0x0;
4721         _prop_set_range_integer(&(props_list_album[i].propinfo), 0,
4722                         MTP_MAX_IMG_WIDTH, 1L);
4723         _prop_set_default_integer(&(props_list_album[i].propinfo),
4724                         (mtp_uchar *)&default_val);
4725         i++;
4726
4727         /*
4728          * MTP_OBJ_PROPERTYCODE_HEIGHT (2)
4729          */
4730         __init_obj_prop_desc(&(props_list_album[i]),
4731                         MTP_OBJ_PROPERTYCODE_HEIGHT,
4732                         PTP_DATATYPE_UINT32,
4733                         PTP_PROPGETSET_GETONLY,
4734                         RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
4735
4736         default_val = 0x0;
4737         _prop_set_range_integer(&(props_list_album[i].propinfo), 0,
4738                         MTP_MAX_IMG_HEIGHT, 1L);
4739         _prop_set_default_integer(&(props_list_album[i].propinfo),
4740                         (mtp_uchar *)&default_val);
4741
4742         /*
4743          * SAMPLE PROPERTIES (3-8)
4744          */
4745 #ifdef MTP_SUPPORT_PROPERTY_SAMPLE
4746         i++
4747                 __build_supported_sample_props(&i, &props_list_album[i]);
4748 #endif /*MTP_SUPPORT_PROPERTY_SAMPLE*/
4749
4750         initialized = TRUE;
4751
4752         return TRUE;
4753 }
4754
4755 void _prop_destroy_supp_obj_props(void)
4756 {
4757         mtp_uint32 i = 0;
4758         int num_default_obj_prps = 0;
4759
4760         for (i = 0; i < NUM_OBJECT_PROP_DESC_MP3; i++)
4761                 __destroy_obj_prop_desc(&(props_list_mp3[i]));
4762
4763         for (i = 0; i < NUM_OBJECT_PROP_DESC_WMA; i++)
4764                 __destroy_obj_prop_desc(&(props_list_wma[i]));
4765
4766         for (i = 0; i < NUM_OBJECT_PROP_DESC_WMV; i++)
4767                 __destroy_obj_prop_desc(&(props_list_wmv[i]));
4768
4769         for (i = 0; i < NUM_OBJECT_PROP_DESC_ALBUM; i++)
4770                 __destroy_obj_prop_desc(&(props_list_album[i]));
4771
4772         if (_get_oma_drm_status() == TRUE)
4773                 num_default_obj_prps = NUM_OBJECT_PROP_DESC_DEFAULT;
4774         else
4775                 num_default_obj_prps = NUM_OBJECT_PROP_DESC_DEFAULT - 1;
4776
4777         for (i = 0; i < num_default_obj_prps; i++)
4778                 __destroy_obj_prop_desc(&(props_list_default[i]));
4779
4780         return;
4781 }
4782
4783 #ifdef MTP_SUPPORT_INTERDEPENDENTPROP
4784 static mtp_bool __append_interdep_prop(interdep_prop_config_t *prop_config,
4785                 obj_prop_desc_t *prop)
4786 {
4787         mtp_bool ret;
4788         if (prop != NULL) {
4789                 ret = _util_add_node(&(prop_config->propdesc_list),
4790                                 (void*)prop);
4791                 if (ret == FALSE) {
4792                         ERR("list add Fail");
4793                         return FALSE;
4794                 }
4795                 return TRUE;
4796         }
4797         return FALSE;
4798 }
4799 #endif /* MTP_SUPPORT_INTERDEPENDENTPROP */
4800
4801 mtp_uint32 _prop_get_size_interdep_prop(interdep_prop_config_t *prop_config)
4802 {
4803         obj_prop_desc_t *prop = NULL;
4804         slist_node_t *node;
4805         mtp_int32 ii;
4806         mtp_uint32 size = sizeof(mtp_uint32);
4807
4808         node = prop_config->propdesc_list.start;
4809         for (ii = 0; ii < prop_config->propdesc_list.nnodes; ii++) {
4810                 prop = node->value;
4811                 if (prop)
4812                         size += _prop_size_obj_prop_desc(prop);
4813         }
4814         return size;
4815 }
4816
4817 mtp_uint32 _prop_pack_interdep_prop(interdep_prop_config_t *prop_config,
4818                 mtp_uchar *buf, mtp_uint32 size)
4819 {
4820         mtp_uchar *temp = buf;
4821         obj_prop_desc_t *prop = NULL;
4822         slist_node_t *node;
4823         mtp_uint32 ele_size = 0;
4824         mtp_int32 ii;
4825
4826         if (!buf || size < _prop_get_size_interdep_prop(prop_config))
4827                 return 0;
4828
4829         *(mtp_uint32 *) buf = prop_config->propdesc_list.nnodes;
4830 #ifdef __BIG_ENDIAN__
4831         _util_conv_byte_order(buf, sizeof(mtp_uint32));
4832 #endif /* __BIG_ENDIAN__ */
4833         temp += sizeof(mtp_uint32);
4834
4835         node = prop_config->propdesc_list.start;
4836         for (ii = 0; ii < prop_config->propdesc_list.nnodes; ii++) {
4837                 prop = node->value;
4838
4839                 if (prop) {
4840                         ele_size = _prop_size_obj_prop_desc(prop);
4841                         _prop_pack_obj_prop_desc(prop, temp, ele_size);
4842                         temp += ele_size;
4843                 }
4844         }
4845
4846         return (mtp_uint32)(temp - buf);
4847 }
4848
4849 static mtp_uint32 __count_interdep_proplist(obj_interdep_proplist_t *config_list,
4850                 mtp_uint32 format_code)
4851 {
4852         mtp_uint32 count = 0;
4853         interdep_prop_config_t *prop_config = NULL;
4854         slist_node_t *node;
4855         mtp_int32 ii;
4856
4857         node = config_list->plist.start;
4858
4859         for (ii = 0; ii < config_list->plist.nnodes; ii++) {
4860                 prop_config = node->value;
4861                 if ((prop_config->format_code == format_code) ||
4862                                 (prop_config->format_code == PTP_FORMATCODE_NOTUSED)) {
4863                         count++;
4864                 }
4865         }
4866         return count;
4867 }
4868
4869 mtp_uint32 _prop_get_size_interdep_proplist(obj_interdep_proplist_t *config_list,
4870                 mtp_uint32 format_code)
4871 {
4872         mtp_uint32 size = sizeof(mtp_uint32);
4873         interdep_prop_config_t *prop_config = NULL;
4874         slist_node_t *node;
4875         mtp_int32 ii;
4876
4877         node = config_list->plist.start;
4878
4879         for (ii = 0; ii < config_list->plist.nnodes; ii++) {
4880                 prop_config = node->value;
4881                 if ((prop_config->format_code == format_code) ||
4882                                 (prop_config->format_code == PTP_FORMATCODE_NOTUSED)) {
4883
4884                         size += _prop_get_size_interdep_prop(prop_config);
4885                 }
4886         }
4887         return size;
4888 }
4889
4890 mtp_uint32 _prop_pack_interdep_proplist(obj_interdep_proplist_t *config_list,
4891                 mtp_uint32 format_code, mtp_uchar *buf, mtp_uint32 size)
4892 {
4893         mtp_uchar *temp = buf;
4894         interdep_prop_config_t *prop_config = NULL;
4895         slist_node_t *node;
4896         mtp_int32 ii;
4897         mtp_uint32 ele_size = 0;
4898
4899         if (!buf ||
4900                         size < _prop_get_size_interdep_proplist(config_list, format_code)) {
4901                 return 0;
4902         }
4903
4904         *(mtp_uint32 *)buf = __count_interdep_proplist(config_list,
4905                         format_code);
4906 #ifdef __BIG_ENDIAN__
4907         _util_conv_byte_order(buf, sizeof(mtp_uint32));
4908 #endif /* __BIG_ENDIAN__ */
4909         temp += sizeof(mtp_uint32);
4910
4911         node = config_list->plist.start;
4912
4913         for (ii = 0; ii < config_list->plist.nnodes; ii++) {
4914
4915                 prop_config = node->value;
4916                 if ((prop_config->format_code == format_code) ||
4917                                 (prop_config->format_code == PTP_FORMATCODE_NOTUSED)) {
4918
4919                         ele_size = _prop_get_size_interdep_prop(prop_config);
4920                         _prop_pack_interdep_prop(prop_config, temp, ele_size);
4921                         temp += ele_size;
4922                 }
4923         }
4924
4925         return (mtp_uint32)(temp - buf);
4926 }
4927
4928 mtp_bool _get_oma_drm_status(void)
4929 {
4930 #ifdef MTP_SUPPORT_OMADRM_EXTENSION
4931         return TRUE;
4932 #else /* MTP_SUPPORT_OMADRM_EXTENSION */
4933         return FALSE;
4934 #endif /* MTP_SUPPORT_OMADRM_EXTENSION */
4935 }