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