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