4e20d4462e304e76756475b3c0a73e90da6d4fcf
[platform/core/connectivity/mtp-responder.git] / src / mtp_cmd_handler.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 <sys/vfs.h>
18 #include <linux/magic.h>
19 #include <sys/time.h>
20 #include <sys/syscall.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <unistd.h>
24 #include <glib.h>
25 #include <glib/gprintf.h>
26 #include <vconf.h>
27 #include "mtp_support.h"
28 #include "ptp_datacodes.h"
29 #include "mtp_media_info.h"
30 #include "mtp_usb_driver.h"
31 #include "mtp_cmd_handler.h"
32 #include "mtp_cmd_handler_util.h"
33 #include "mtp_transport.h"
34 #include "mtp_thread.h"
35
36 /*
37  * GLOBAL AND EXTERN VARIABLES
38  */
39 extern mtp_mgr_t g_mtp_mgr;
40 extern mtp_bool g_is_full_enum;
41 extern pthread_mutex_t g_cmd_inoti_mutex;
42 extern mtp_config_t g_conf;
43
44 mtp_bool g_is_sync_estab = FALSE;
45
46 /*
47  * STATIC VARIABLES
48  */
49 static mtp_mgr_t *g_mgr = &g_mtp_mgr;
50 static mtp_bool g_has_round_trip = FALSE;
51 #ifdef MTP_USE_SKIP_CONTINUOUS_OPENSESSION
52 static mtp_uint16 g_count_open_session = 0;
53 static mtp_uint32 g_old_open_session_time = 0;
54 #endif/*MTP_USE_SKIP_CONTINUOUS_OPENSESSION*/
55
56 /*
57  * STATIC FUNCTIONS
58  */
59 static void __process_commands(mtp_handler_t *hdlr, cmd_blk_t *cmd);
60 static void __open_session(mtp_handler_t *hdlr);
61 static void __get_device_info(mtp_handler_t *hdlr);
62 static void __get_storage_ids(mtp_handler_t *hdlr);
63 static void __get_storage_info(mtp_handler_t *hdlr);
64 static void __get_num_objects(mtp_handler_t *hdlr);
65 static void __get_object_handles(mtp_handler_t *hdlr);
66 static void __get_object_info(mtp_handler_t *hdlr);
67 static void __get_object(mtp_handler_t *hdlr);
68 static void __send_object_info(mtp_handler_t *hdlr);
69 static void __send_object(mtp_handler_t *hdlr);
70 static void __delete_object(mtp_handler_t *hdlr);
71 static void __format_store(mtp_handler_t *hdlr);
72 static void __reset_device(mtp_handler_t *hdlr);
73 static void __get_device_prop_desc(mtp_handler_t *hdlr);
74 static void __get_device_prop_value(mtp_handler_t *hdlr);
75 static void __set_device_prop_value(mtp_handler_t *hdlr);
76 static void __get_partial_object(mtp_handler_t *hdlr);
77 static void __get_object_references(mtp_handler_t *hdlr);
78 static void __set_object_references(mtp_handler_t *hdlr);
79 static void __get_object_prop_desc(mtp_handler_t *hdlr);
80 static void __get_object_prop_supported(mtp_handler_t *hdlr);
81 static void __get_object_prop_value(mtp_handler_t *hdlr);
82 static void __set_object_prop_value(mtp_handler_t *hdlr);
83 static void __get_object_prop_list(mtp_handler_t *hdlr);
84 static void __set_object_prop_list(mtp_handler_t *hdlr);
85 static void __report_acquired_content(mtp_handler_t *hdlr);
86 static void __send_playback_skip(mtp_handler_t *hdlr);
87 #ifndef PMP_VER
88 static void __self_test(mtp_handler_t *hdlr);
89 #ifdef MTP_SUPPORT_SET_PROTECTION
90 static void __set_object_protection(mtp_handler_t *hdlr);
91 #endif /* MTP_SUPPORT_SET_PROTECTION */
92 static void __power_down(mtp_handler_t *hdlr);
93 static void __move_object(mtp_handler_t *hdlr);
94 static void __copy_object(mtp_handler_t *hdlr);
95 static void __reset_device_prop_value(mtp_handler_t *hdlr);
96 static void __vendor_command1(mtp_handler_t *hdlr);
97 static void __get_interdep_prop_desc(mtp_handler_t *hdlr);
98 static void __send_object_prop_list(mtp_handler_t *hdlr);
99 #endif /* PMP_VER */
100 static void __close_session(mtp_handler_t *hdlr);
101 #ifdef MTP_SUPPORT_PRINT_COMMAND
102 static void __print_command(mtp_uint16 code);
103 #endif /* MTP_SUPPORT_PRINT_COMMAND */
104 static void __enum_store_not_enumerated(mtp_uint32 obj_handle,
105                 mtp_uint32 fmt, mtp_uint32 depth);
106 static mtp_bool __receive_temp_file_first_packet(mtp_char *data,
107                 mtp_int32 data_len);
108 static mtp_bool __receive_temp_file_next_packets(mtp_char *data,
109                 mtp_int32 data_len);
110 static void __finish_receiving_file_packets(mtp_char *data, mtp_int32 data_len);
111
112 /*
113  * FUNCTIONS
114  */
115 void _cmd_hdlr_reset_cmd(mtp_handler_t *hdlr)
116 {
117         if (hdlr->data4_send_obj.obj != NULL)
118                 _entity_dealloc_mtp_obj(hdlr->data4_send_obj.obj);
119
120         memset(hdlr, 0x00, sizeof(mtp_handler_t));
121
122 #ifdef MTP_USE_SKIP_CONTINUOUS_OPENSESSION
123         /* reset open session count */
124         g_count_open_session = 0;
125         g_old_open_session_time = 0;
126 #endif /* MTP_USE_SKIP_CONTINUOUS_OPENSESSION */
127 }
128
129 static void __process_commands(mtp_handler_t *hdlr, cmd_blk_t *cmd)
130 {
131         mtp_store_t *store = NULL;
132
133         /* Keep a local copy for this command */
134         _hdlr_copy_cmd_container(cmd, &(hdlr->usb_cmd));
135
136         if (hdlr->usb_cmd.code == PTP_OPCODE_GETDEVICEINFO) {
137                 DBG("COMMAND CODE = [0x%4x]!!\n", hdlr->usb_cmd.code);
138 #ifdef MTP_SUPPORT_PRINT_COMMAND
139                 __print_command(hdlr->usb_cmd.code);
140 #endif /*MTP_SUPPORT_PRINT_COMMAND*/
141                 __get_device_info(hdlr);
142                 goto DONE;
143         }
144
145         /*  Process OpenSession Command */
146         if (hdlr->usb_cmd.code == PTP_OPCODE_OPENSESSION) {
147                 DBG("COMMAND CODE = [0x%4X]!!\n", hdlr->usb_cmd.code);
148 #ifdef MTP_SUPPORT_PRINT_COMMAND
149                 __print_command(hdlr->usb_cmd.code);
150 #endif /*MTP_SUPPORT_PRINT_COMMAND*/
151 #ifdef MTP_USE_SKIP_CONTINUOUS_OPENSESSION
152                 time_t t;
153                 mtp_uint32 cur_time = 0;
154                 time(&t);
155                 cur_time = (mtp_uint32)t;
156                 /*first opensession*/
157                 if (g_count_open_session == 0) {
158                         g_old_open_session_time = cur_time;
159                 } else if (cur_time <= g_old_open_session_time + 1) {
160                         /*under 1 sec. it might be skipped*/
161                         ERR("skip continuous OPEN session");
162                         goto DONE;
163                 }
164                 ++g_count_open_session;
165
166 #endif /* MTP_USE_SKIP_CONTINUOUS_OPENSESSION */
167                 __open_session(hdlr);
168                 goto DONE;
169         }
170 #ifdef MTP_USE_SKIP_CONTINUOUS_OPENSESSION
171         g_count_open_session = 0;
172 #endif /* MTP_USE_SKIP_CONTINUOUS_OPENSESSION */
173
174         /* Check if session is open or not, if not respond */
175         if (hdlr->session_id == 0) {
176                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_SESSIONNOTOPEN);
177                 _device_set_phase(DEVICE_PHASE_IDLE);
178                 goto DONE;
179         }
180         DBG("COMMAND CODE = [0x%4x]!!\n", hdlr->usb_cmd.code);
181 #ifdef MTP_SUPPORT_PRINT_COMMAND
182         __print_command(hdlr->usb_cmd.code);
183 #endif /* MTP_SUPPORT_PRINT_COMMAND */
184
185         switch (hdlr->usb_cmd.code) {
186         case PTP_OPCODE_CLOSESESSION:
187                 __close_session(hdlr);
188                 break;
189         case PTP_OPCODE_GETSTORAGEIDS:
190                 __get_storage_ids(hdlr);
191                 break;
192         case PTP_OPCODE_GETSTORAGEINFO:
193                 __get_storage_info(hdlr);
194                 break;
195         case PTP_OPCODE_GETNUMOBJECTS:
196                 __get_num_objects(hdlr);
197                 break;
198         case PTP_OPCODE_GETOBJECTHANDLES:
199                 __get_object_handles(hdlr);
200                 break;
201         case PTP_OPCODE_GETOBJECTINFO:
202                 __get_object_info(hdlr);
203                 break;
204         case PTP_OPCODE_GETOBJECT:
205                 _eh_send_event_req_to_eh_thread(EVENT_START_DATAIN, 0, 0, NULL);
206                 __get_object(hdlr);
207                 _eh_send_event_req_to_eh_thread(EVENT_DONE_DATAIN, 0, 0, NULL);
208                 break;
209         case PTP_OPCODE_DELETEOBJECT:
210                 __delete_object(hdlr);
211                 break;
212         case PTP_OPCODE_FORMATSTORE:
213                 __format_store(hdlr);
214                 break;
215         case PTP_OPCODE_GETDEVICEPROPDESC:
216                 __get_device_prop_desc(hdlr);
217                 break;
218         case PTP_OPCODE_GETDEVICEPROPVALUE:
219                 __get_device_prop_value(hdlr);
220                 break;
221         case PTP_OPCODE_GETPARTIALOBJECT:
222                 __get_partial_object(hdlr);
223                 break;
224         case MTP_OPCODE_GETOBJECTREFERENCES:
225                 __get_object_references(hdlr);
226                 break;
227         case MTP_OPCODE_GETOBJECTPROPDESC:
228                 __get_object_prop_desc(hdlr);
229                 break;
230         case MTP_OPCODE_GETOBJECTPROPSUPPORTED:
231                 __get_object_prop_supported(hdlr);
232                 break;
233         case MTP_OPCODE_GETOBJECTPROPVALUE:
234                 __get_object_prop_value(hdlr);
235                 break;
236         case MTP_OPCODE_GETOBJECTPROPLIST:
237                 __get_object_prop_list(hdlr);
238                 break;
239 #ifndef PMP_VER
240         case PTP_OPCODE_RESETDEVICE:
241                 __reset_device(hdlr);
242                 break;
243         case PTP_OPCODE_SELFTEST:
244                 __self_test(hdlr);
245                 break;
246 #ifdef MTP_SUPPORT_SET_PROTECTION
247         case PTP_OPCODE_SETOBJECTPROTECTION:
248                 __set_object_protection(hdlr);
249                 break;
250 #endif /* MTP_SUPPORT_SET_PROTECTION */
251         case PTP_OPCODE_POWERDOWN:
252                 __power_down(hdlr);
253                 break;
254         case PTP_OPCODE_RESETDEVICEPROPVALUE:
255                 __reset_device_prop_value(hdlr);
256                 break;
257         case PTP_OPCODE_MOVEOBJECT:
258                 __move_object(hdlr);
259                 break;
260         case PTP_OPCODE_COPYOBJECT:
261                 __copy_object(hdlr);
262                 break;
263         case MTP_OPCODE_GETINTERDEPPROPDESC:
264                 __get_interdep_prop_desc(hdlr);
265                 break;
266         case PTP_CODE_VENDOR_OP1:       /* Vendor-specific operations */
267                 __vendor_command1(hdlr);
268                 break;
269 #endif /* PMP_VER */
270         case MTP_OPCODE_PLAYBACK_SKIP:  /* Playback control */
271                 __send_playback_skip(hdlr);
272                 break;
273
274         case MTP_OPCODE_WMP_REPORTACQUIREDCONTENT:
275                 /* Windows Media 11 extension*/
276                 __report_acquired_content(hdlr);
277                 break;
278         case PTP_OPCODE_SENDOBJECTINFO:
279         case PTP_OPCODE_SENDOBJECT:
280         case PTP_OPCODE_SETDEVICEPROPVALUE:
281         case MTP_OPCODE_SETOBJECTREFERENCES:
282         case MTP_OPCODE_SETOBJECTPROPVALUE:
283         case MTP_OPCODE_SETOBJECTPROPLIST:
284 #ifndef PMP_VER
285         case MTP_OPCODE_SENDOBJECTPROPLIST:
286 #endif /* PMP_VER */
287                 /* DATA_HANDLE_PHASE: Send operation will be blocked
288                  * until data packet is received
289                  */
290                 if (_device_get_phase() == DEVICE_PHASE_IDLE) {
291                         DBG("DATAOUT COMMAND PHASE!!");
292                         if (hdlr->usb_cmd.code == PTP_OPCODE_SENDOBJECT)
293                                 _eh_send_event_req_to_eh_thread(EVENT_START_DATAOUT,
294                                                 0, 0, NULL);
295                         _device_set_phase(DEVICE_PHASE_DATAOUT);
296                         return; /* in command phase, just return and wait next data */
297                 }
298                 switch (hdlr->usb_cmd.code) {
299                 case PTP_OPCODE_SENDOBJECTINFO:
300                         __send_object_info(hdlr);
301                         break;
302                 case PTP_OPCODE_SENDOBJECT:
303                         __send_object(hdlr);
304                         _eh_send_event_req_to_eh_thread(EVENT_DONE_DATAOUT,
305                                         0, 0, NULL);
306                         break;
307                 case PTP_OPCODE_SETDEVICEPROPVALUE:
308                         __set_device_prop_value(hdlr);
309                         break;
310                 case MTP_OPCODE_SETOBJECTREFERENCES:
311                         __set_object_references(hdlr);
312                         break;
313                 case MTP_OPCODE_SETOBJECTPROPVALUE:
314                         __set_object_prop_value(hdlr);
315                         break;
316                 case MTP_OPCODE_SETOBJECTPROPLIST:
317                         __set_object_prop_list(hdlr);
318                         break;
319 #ifndef PMP_VER
320                 case MTP_OPCODE_SENDOBJECTPROPLIST:
321                         __send_object_prop_list(hdlr);
322                         break;
323 #endif /* PMP_VER */
324                 }
325                 break;
326
327         default:
328                 _cmd_hdlr_send_response_code(hdlr,
329                                 PTP_RESPONSE_OP_NOT_SUPPORTED);
330                 DBG("Unsupported COMMAND[%d]\n", hdlr->usb_cmd.code);
331                 break;
332         }
333 DONE:
334         if (((hdlr->last_opcode == PTP_OPCODE_SENDOBJECTINFO) ||
335                                 (hdlr->last_opcode == MTP_OPCODE_SENDOBJECTPROPLIST)) &&
336                         ((hdlr->last_fmt_code != PTP_FMT_ASSOCIATION) &&
337                          (hdlr->last_fmt_code != PTP_FMT_UNDEF))) {
338                 DBG("Processed, last_opcode[0x%x], last_fmt_code[%d]\n",
339                                 hdlr->last_opcode, hdlr->last_fmt_code);
340
341                 if ((hdlr->usb_cmd.code != PTP_OPCODE_SENDOBJECT) &&
342                                 hdlr->data4_send_obj.is_valid &&
343                                 hdlr->data4_send_obj.is_data_sent) {
344
345                         DBG("Processed, COMMAND[0x%x]!!\n", hdlr->usb_cmd.code);
346                         store = _device_get_store(hdlr->data4_send_obj.store_id);
347                         if (store != NULL) {
348                                 /*Restore reserved space*/
349                                 store->store_info.free_space +=
350                                         hdlr->data4_send_obj.file_size;
351                         }
352
353                         if (hdlr->data4_send_obj.obj) {
354                                 _entity_dealloc_mtp_obj(hdlr->data4_send_obj.obj);
355                                 hdlr->data4_send_obj.obj = NULL;
356                         }
357                         memset(&(hdlr->data4_send_obj), 0x00,
358                                         sizeof(hdlr->data4_send_obj));
359                 }
360         }
361         hdlr->last_opcode = hdlr->usb_cmd.code; /* Last operation code*/
362 }
363
364 static void __open_session(mtp_handler_t *hdlr)
365 {
366         mtp_uint32 session_id;
367         /*Check the parameters*/
368         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
369                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
370                 /*Unknown parameters*/
371                 _cmd_hdlr_send_response_code(hdlr,
372                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
373                 return;
374         }
375         /* Validate parameters*/
376         session_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
377
378         if (session_id == 0 || (hdlr->usb_cmd.tid != 0)) {
379                 /*Session Id cannot be zero, while TransactionId must be zero.*/
380                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_INVALIDPARAM);
381                 return;
382         }
383
384         if (hdlr->session_id) { /*Session already open*/
385                 _cmd_hdlr_send_response(hdlr,
386                                 PTP_RESPONSE_SESSIONALREADYOPENED, 1,
387                                 (mtp_uint32 *)&(hdlr->session_id));
388         } else {        /*Save the Session ID*/
389                 hdlr->session_id = session_id;
390                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
391         }
392 }
393
394 static void __get_device_info(mtp_handler_t *hdlr)
395 {
396         /* Check the parameters*/
397         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0) ||
398                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
399                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
400                 /* Unknown parameters*/
401                 _cmd_hdlr_send_response_code(hdlr,
402                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
403                 return;
404         }
405
406         /* When used outside a session, both the SessionID and TransactionID
407          * in the Operation Request dataset must be 0;
408          */
409
410         if ((hdlr->session_id == 0) &&
411                         (hdlr->usb_cmd.tid != 0)) {     /*INVALIDPARAMETER*/
412                 _cmd_hdlr_send_response_code(hdlr,
413                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
414                 ERR("Invalid Session ID[%u], Transaction ID[%u]\n",
415                                 hdlr->session_id, hdlr->usb_cmd.tid);
416                 return;
417         }
418
419         /*Build the data block for device info.*/
420         data_blk_t blk = { 0 };
421         mtp_uint32 num_bytes = 0;
422         mtp_uchar *buf_ptr = NULL;
423
424         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
425         num_bytes = _get_device_info_size();
426         buf_ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
427         if (num_bytes == _pack_device_info(buf_ptr, num_bytes)) {
428                 _device_set_phase(DEVICE_PHASE_DATAIN);
429                 if (_hdlr_send_data_container(&blk)) {
430                         _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
431                 } else {
432                         /* Host Cancelled data-in transfer */
433                         _device_set_phase(DEVICE_PHASE_NOTREADY);
434                         DBG("Device phase is set to DEVICE_PHASE_NOTREADY");
435                 }
436         } else {
437                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
438         }
439
440         g_free(blk.data);
441 }
442
443 static void __get_storage_ids(mtp_handler_t *hdlr)
444 {
445         data_blk_t blk = { 0 };
446         ptp_array_t ids = { 0 };
447         mtp_uint32 resp = PTP_RESPONSE_GEN_ERROR;
448         mtp_uint32 num_bytes = 0;
449         mtp_uchar *ptr = NULL;
450
451         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0) ||
452                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
453                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
454
455                 _cmd_hdlr_send_response_code(hdlr,
456                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
457                 return;
458         }
459
460         _prop_init_ptparray(&ids, UINT32_TYPE);
461
462         if (_hutil_get_storage_ids(&ids) == MTP_ERROR_NONE) {
463                 _hdlr_init_data_container(&blk, hdlr->usb_cmd.code,
464                                 hdlr->usb_cmd.tid);
465                 num_bytes = _prop_get_size_ptparray(&ids);
466                 ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
467                 if (NULL != ptr) {
468                         /*Pack storage IDs*/
469                         _prop_pack_ptparray(&ids, ptr, num_bytes);
470                         _device_set_phase(DEVICE_PHASE_DATAIN);
471                         /*Send the data block*/
472                         if (FALSE == _hdlr_send_data_container(&blk)) {
473                                 /*Host Cancelled data-in transfer*/
474                                 _device_set_phase(DEVICE_PHASE_NOTREADY);
475                                 DBG("DEVICE_PHASE_NOTREADY!!");
476                         } else {
477                                 resp = PTP_RESPONSE_OK;
478                         }
479                 }
480                 g_free(blk.data);
481         }
482         _prop_deinit_ptparray(&ids);
483         _cmd_hdlr_send_response_code(hdlr, (mtp_uint16) resp);
484 }
485
486 static void __get_storage_info(mtp_handler_t *hdlr)
487 {
488         mtp_uint32 store_id = 0;
489         store_info_t store_info = { 0 };
490         mtp_uint32 pkt_sz = 0;
491         data_blk_t blk = { 0 };
492         mtp_uchar *ptr = NULL;
493
494         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
495                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
496                 /*Unknown parameters*/
497                 _cmd_hdlr_send_response_code(hdlr,
498                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
499                 return;
500         }
501
502         store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
503
504         if (_hutil_get_storage_entry(store_id, &store_info) != MTP_ERROR_NONE) {
505                 _cmd_hdlr_send_response_code(hdlr,
506                                 PTP_RESPONSE_INVALID_STORE_ID);
507                 return;
508         }
509
510         /* Build the data block for StorageInfo Dataset.*/
511         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
512         pkt_sz = _hutil_get_storage_info_size(&store_info);
513         ptr = _hdlr_alloc_buf_data_container(&blk, pkt_sz, pkt_sz);
514
515         if (pkt_sz == _entity_pack_store_info(&store_info, ptr, pkt_sz)) {
516                 _device_set_phase(DEVICE_PHASE_DATAIN);
517                 if (_hdlr_send_data_container(&blk)) {
518                         _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
519                 } else {
520                         /*Host Cancelled data-in transfer*/
521                         _device_set_phase(DEVICE_PHASE_NOTREADY);
522                         DBG("DEVICE_PHASE_NOTREADY!!");
523                 }
524         } else {
525                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
526         }
527
528         g_free(blk.data);
529 }
530
531 static void __get_num_objects(mtp_handler_t *hdlr)
532 {
533         mtp_uint16 resp = 0;
534         mtp_uint32 store_id = 0;
535         mtp_uint32 h_parent = 0;
536         mtp_uint32 fmt = 0;
537         mtp_uint32 num_obj = 0;
538
539         store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
540         fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
541         h_parent = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
542
543         switch (_hutil_get_num_objects(store_id, h_parent, fmt,
544                                 (mtp_uint32 *)(&num_obj))) {
545         case MTP_ERROR_INVALID_STORE:
546                 resp = PTP_RESPONSE_INVALID_STORE_ID;
547                 break;
548         case MTP_ERROR_INVALID_OBJECTHANDLE:
549                 resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
550                 break;
551         case MTP_ERROR_INVALID_PARENT:
552                 resp = PTP_RESPONSE_INVALIDPARENT;
553                 break;
554         case MTP_ERROR_STORE_NOT_AVAILABLE:
555                 resp = PTP_RESPONSE_STORENOTAVAILABLE;
556                 break;
557         case MTP_ERROR_NONE:
558                 resp = PTP_RESPONSE_OK;
559                 break;
560         default:
561                 resp = PTP_RESPONSE_GEN_ERROR;
562         }
563
564         if (resp == PTP_RESPONSE_OK)
565                 _cmd_hdlr_send_response(hdlr, resp, 1, (mtp_uint32 *)&num_obj);
566         else
567                 _cmd_hdlr_send_response_code(hdlr, resp);
568 }
569
570 static void __get_object_handles(mtp_handler_t *hdlr)
571 {
572         mtp_uint32 store_id = 0;
573         mtp_uint32 fmt = 0;
574         mtp_uint32 h_parent = 0;
575         ptp_array_t handle_arr = { 0 };
576         data_blk_t blk = { 0 };
577         mtp_uint32 num_bytes = 0;
578         mtp_uchar *ptr = NULL;
579         mtp_uint16 resp = 0;
580
581         _prop_init_ptparray(&handle_arr, UINT32_TYPE);
582
583         store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
584         fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
585         h_parent = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
586
587         DBG("store_id = [0x%x], Format Code = [0x%x], parent handle = [0x%x]\n",
588                         store_id, fmt, h_parent);
589         switch (_hutil_get_object_handles(store_id, fmt, h_parent,
590                                 &handle_arr)) {
591         case MTP_ERROR_INVALID_STORE:
592                 resp = PTP_RESPONSE_INVALID_STORE_ID;
593                 break;
594         case MTP_ERROR_INVALID_OBJECTHANDLE:
595                 resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
596                 break;
597         case MTP_ERROR_INVALID_PARENT:
598                 resp = PTP_RESPONSE_INVALIDPARENT;
599                 break;
600         case MTP_ERROR_STORE_NOT_AVAILABLE:
601                 resp = PTP_RESPONSE_STORENOTAVAILABLE;
602                 break;
603         case MTP_ERROR_NONE:
604                 resp = PTP_RESPONSE_OK;
605                 break;
606         default:
607                 resp = PTP_RESPONSE_GEN_ERROR;
608         }
609
610         if (resp != PTP_RESPONSE_OK) {
611                 _prop_deinit_ptparray(&handle_arr);
612                 _cmd_hdlr_send_response_code(hdlr, resp);
613                 return;
614         }
615
616         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
617         num_bytes = _prop_get_size_ptparray(&handle_arr);
618         ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
619         if (NULL != ptr) {
620                 _prop_pack_ptparray(&handle_arr, ptr, num_bytes);
621                 _prop_deinit_ptparray(&handle_arr);
622                 _device_set_phase(DEVICE_PHASE_DATAIN);
623                 if (_hdlr_send_data_container(&blk)) {
624                         _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
625                 } else {
626                         /*Host Cancelled data-in transfer.*/
627                         _device_set_phase(DEVICE_PHASE_NOTREADY);
628                         DBG("DEVICE_PHASE_NOTREADY!!");
629                 }
630         } else {
631                 _prop_deinit_ptparray(&handle_arr);
632                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
633         }
634
635         g_free(blk.data);
636 }
637
638 static void __get_object_info(mtp_handler_t *hdlr)
639 {
640         mtp_uint32 obj_handle = 0;
641         data_blk_t blk = { 0 };
642         mtp_uint32 num_bytes = 0;
643         mtp_uchar *ptr = NULL;
644         mtp_obj_t *obj = NULL;
645         mtp_char f_name[MTP_MAX_FILENAME_SIZE + 1] = { 0 };
646         mtp_wchar wf_name[MTP_MAX_FILENAME_SIZE + 1] = { 0 };
647         ptp_string_t ptp_string = { 0 };
648
649         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
650                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
651
652                 _cmd_hdlr_send_response_code(hdlr,
653                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
654                 return;
655         }
656         obj_handle = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
657         if (MTP_ERROR_NONE != _hutil_get_object_entry(obj_handle, &obj)) {
658                 _cmd_hdlr_send_response_code(hdlr,
659                                 PTP_RESPONSE_INVALID_OBJ_HANDLE);
660                 return;
661         }
662
663         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
664
665         _util_get_file_name(obj->file_path, f_name);
666         _util_utf8_to_utf16(wf_name, sizeof(wf_name) / WCHAR_SIZ, f_name);
667         _prop_copy_char_to_ptpstring(&ptp_string, wf_name, WCHAR_TYPE);
668
669         num_bytes = _entity_get_object_info_size(obj, &ptp_string);
670         ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
671         if (num_bytes == _entity_pack_obj_info(obj, &ptp_string, ptr,
672                                 num_bytes)) {
673                 _device_set_phase(DEVICE_PHASE_DATAIN);
674                 if (_hdlr_send_data_container(&blk)) {
675                         _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
676                 } else {
677                         /* Host Cancelled data-in transfer*/
678                         _device_set_phase(DEVICE_PHASE_NOTREADY);
679                         DBG("DEVICE_PHASE_NOTREADY!!");
680                 }
681         } else {
682                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
683         }
684
685         g_free(blk.data);
686 }
687
688 static void __get_object(mtp_handler_t *hdlr)
689 {
690         mtp_uint32 obj_handle;
691         mtp_obj_t *obj;
692         mtp_uchar *ptr;
693         data_blk_t blk;
694         mtp_char *path;
695         mtp_uint64 num_bytes;
696         mtp_uint64 total_len;
697         mtp_uint64 sent = 0;
698         mtp_uint16 resp = PTP_RESPONSE_OK;
699         mtp_uint32 packet_len;
700         mtp_uint32 read_len = 0;
701         FILE* h_file = NULL;
702         mtp_int32 error = 0;
703
704         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
705                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
706                 _cmd_hdlr_send_response_code(hdlr,
707                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
708                 return;
709         }
710
711         obj_handle = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
712         obj = _device_get_object_with_handle(obj_handle);
713         if (obj == NULL) {
714                 resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
715                 _cmd_hdlr_send_response_code(hdlr, resp);
716                 return;
717         }
718
719 #ifdef MTP_SUPPORT_SET_PROTECTION
720         /* Check to see if the data is non-transferable */
721         if (obj->obj_info->protcn_status ==
722                         MTP_PROTECTIONSTATUS_NONTRANSFERABLE_DATA) {
723                 resp = PTP_RESPONSE_ACCESSDENIED;
724                 _cmd_hdlr_send_response_code(hdlr, resp);
725                 return;
726         }
727 #endif /* MTP_SUPPORT_SET_PROTECTION */
728
729         path = obj->file_path;
730         num_bytes = obj->obj_info->file_size;
731         total_len = num_bytes + sizeof(header_container_t);
732         packet_len = total_len < g_conf.read_file_size ? num_bytes :
733                 (g_conf.read_file_size - sizeof(header_container_t));
734
735         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
736         ptr = _hdlr_alloc_buf_data_container(&blk, packet_len, num_bytes);
737         if (NULL == ptr) {
738                 ERR("_hdlr_alloc_buf_data_container() Fail");
739                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
740                 g_free(blk.data);
741                 return;
742         }
743
744         _device_set_phase(DEVICE_PHASE_DATAIN);
745         h_file = _util_file_open(path, MTP_FILE_READ, &error);
746         if (h_file == NULL) {
747                 ERR("_util_file_open() Fail");
748                 _device_set_phase(DEVICE_PHASE_NOTREADY);
749                 if (EACCES == error) {
750                         _cmd_hdlr_send_response_code(hdlr,
751                                         PTP_RESPONSE_ACCESSDENIED);
752                         g_free(blk.data);
753                         return;
754                 }
755                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
756                 g_free(blk.data);
757                 return;
758         }
759
760         _util_file_read(h_file, ptr, packet_len, &read_len);
761         if (0 == read_len) {
762                 ERR("_util_file_read() Fail");
763                 ERR_SECURE("filename[%s]", path);
764                 _device_set_phase(DEVICE_PHASE_NOTREADY);
765                 resp = PTP_RESPONSE_INCOMPLETETRANSFER;
766                 goto Done;
767         }
768
769         /* First Packet with Header */
770         if (PTP_EVENTCODE_CANCELTRANSACTION == _transport_get_control_event() ||
771                         FALSE == _hdlr_send_bulk_data(blk.data, blk.len)) {
772                 _device_set_phase(DEVICE_PHASE_NOTREADY);
773                 resp = PTP_RESPONSE_INCOMPLETETRANSFER;
774                 ERR("First Packet send Fail");
775                 ERR_SECURE("filename[%s]\n", path);
776                 goto Done;
777         }
778
779         sent = sizeof(header_container_t) + read_len;
780         ptr = blk.data;
781
782         while (sent < total_len) {
783                 _util_file_read(h_file, ptr, g_conf.read_file_size, &read_len);
784                 if (0 == read_len) {
785                         ERR("_util_file_read() Fail");
786                         ERR_SECURE("filename[%s]\n", path);
787                         _device_set_phase(DEVICE_PHASE_NOTREADY);
788                         resp = PTP_RESPONSE_INCOMPLETETRANSFER;
789                         goto Done;
790                 }
791
792                 if (PTP_EVENTCODE_CANCELTRANSACTION == _transport_get_control_event() ||
793                                 FALSE == _hdlr_send_bulk_data(ptr, read_len)) {
794                         _device_set_phase(DEVICE_PHASE_NOTREADY);
795                         resp = PTP_RESPONSE_INCOMPLETETRANSFER;
796                         ERR("Packet send Fail");
797                         ERR_SECURE("filename[%s]\n", path);
798                         goto Done;
799                 }
800
801                 sent += read_len;
802         }
803
804         if (total_len % ((mtp_uint64)_transport_get_usb_packet_len()) == 0)
805                 _transport_send_zlp();
806
807 Done:
808         _util_file_close(h_file);
809
810         g_free(blk.data);
811         _cmd_hdlr_send_response_code(hdlr, resp);
812 }
813
814 static void __send_object_info(mtp_handler_t *hdlr)
815 {
816         mtp_uint16 resp = PTP_RESPONSE_UNDEFINED;
817         mtp_uint32 store_id = 0;
818         mtp_uint32 h_parent = 0;
819         mtp_uint32 num_bytes = 0;
820         data_blk_t blk = { 0 };
821         mtp_uint32 resp_param[3] = { 0 };
822         mtp_obj_t *obj = NULL;
823         mtp_err_t ret = 0;
824         obj_data_t obdata = { 0 };
825
826         store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
827         if (store_id == 0)
828                 store_id = _device_get_default_store_id();
829
830         h_parent = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
831
832         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
833                 resp = PTP_RESPONSE_PARAM_NOTSUPPORTED;
834                 if (_device_get_phase() != DEVICE_PHASE_NOTREADY)
835                         _cmd_hdlr_send_response_code(hdlr, resp);
836
837                 return;
838         }
839
840         _device_set_phase(DEVICE_PHASE_DATAOUT);
841         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
842         num_bytes = MAX_SIZE_IN_BYTES_OF_OBJECT_INFO;
843         if (_hdlr_rcv_data_container(&blk, num_bytes) == FALSE) {
844                 _device_set_phase(DEVICE_PHASE_NOTREADY);
845         } else {
846                 if (TRUE == hdlr->data4_send_obj.is_valid) {
847                         obdata.store_id = hdlr->data4_send_obj.store_id;
848                         obdata.obj_size = hdlr->data4_send_obj.file_size;
849                         obdata.obj = hdlr->data4_send_obj.obj;
850                         hdlr->data4_send_obj.obj = NULL;
851                 }
852                 ret = _hutil_construct_object_entry(store_id, h_parent,
853                                 ((hdlr->data4_send_obj.is_valid == TRUE) ? (&obdata)
854                                  : (NULL)), &obj, _hdlr_get_payload_data(&blk),
855                                 _hdlr_get_payload_size(&blk));
856                 hdlr->data4_send_obj.is_valid = FALSE;
857                 switch (ret) {
858                 case MTP_ERROR_NONE:
859                         if (obj->obj_info->obj_fmt == PTP_FMT_ASSOCIATION) {
860                                 hdlr->data4_send_obj.obj = NULL;
861                                 hdlr->data4_send_obj.is_valid = FALSE;
862                                 hdlr->data4_send_obj.obj_handle = obj->obj_handle;
863                                 hdlr->data4_send_obj.h_parent = h_parent;
864                                 hdlr->data4_send_obj.store_id = store_id;
865                         }
866 #ifdef MTP_USE_SELFMAKE_ABSTRACTION
867                         else if (obj->obj_info->file_size == 0 &&
868                                         obj->obj_info->obj_fmt > MTP_FMT_UNDEFINED_COLLECTION &&
869                                         obj->obj_info->obj_fmt < MTP_FMT_UNDEFINED_DOC) {
870                                 hdlr->data4_send_obj.obj = NULL;
871                                 hdlr->data4_send_obj.is_valid = FALSE;
872                                 hdlr->data4_send_obj.obj_handle = obj->obj_handle;
873                                 hdlr->data4_send_obj.h_parent = h_parent;
874                                 hdlr->data4_send_obj.store_id = store_id;
875                         }
876 #endif /*MTP_USE_SELFMAKE_ABSTRACTION*/
877                         else {
878                                 hdlr->data4_send_obj.is_valid = TRUE;
879                                 hdlr->data4_send_obj.obj_handle = obj->obj_handle;
880                                 hdlr->data4_send_obj.h_parent = h_parent;
881                                 hdlr->data4_send_obj.store_id = store_id;
882                                 hdlr->data4_send_obj.obj = obj;
883                                 hdlr->data4_send_obj.file_size =
884                                         obj->obj_info->file_size;
885                         }
886                         resp = PTP_RESPONSE_OK;
887                         break;
888                 case MTP_ERROR_STORE_NOT_AVAILABLE:
889                         resp = PTP_RESPONSE_STORENOTAVAILABLE;
890                         DBG("PTP_RESPONSE_STORENOTAVAILABLE");
891                         break;
892                 case MTP_ERROR_INVALID_PARAM:
893                         resp = PTP_RESPONSE_PARAM_NOTSUPPORTED;
894                         DBG("PTP_RESPONSE_PARAM_NOTSUPPORTED");
895                         break;
896                 case MTP_ERROR_INVALID_STORE:
897                         resp = PTP_RESPONSE_INVALID_STORE_ID;
898                         DBG("PTP_RESPONSE_INVALID_STORE_ID");
899                         break;
900                 case MTP_ERROR_STORE_READ_ONLY:
901                         resp = PTP_RESPONSE_STORE_READONLY;
902                         break;
903                 case MTP_ERROR_STORE_FULL:
904                         resp = PTP_RESPONSE_STOREFULL;
905                         DBG("PTP_RESPONSE_STOREFULL");
906                         break;
907                 case MTP_ERROR_GENERAL:
908                         resp = PTP_RESPONSE_GEN_ERROR;
909                         DBG("PTP_RESPONSE_GEN_ERROR");
910                         break;
911                 case MTP_ERROR_INVALID_OBJECT_INFO:
912                         resp = MTP_RESPONSECODE_INVALIDDATASET;
913                         DBG("MTP_RESPONSECODE_INVALIDDATASET");
914                         break;
915                 case MTP_ERROR_INVALID_OBJECTHANDLE:
916                         resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
917                         DBG("PTP_RESPONSE_INVALID_OBJ_HANDLE");
918                         break;
919                 case MTP_ERROR_INVALID_PARENT:
920                         resp = PTP_RESPONSE_INVALIDPARENT;
921                         DBG("PTP_RESPONSE_INVALIDPARENT");
922                         break;
923                 case MTP_ERROR_ACCESS_DENIED:
924                         resp = PTP_RESPONSE_ACCESSDENIED;
925                         DBG("PTP_RESPONSE_ACCESSDENIED");
926                         break;
927                 default:
928                         resp = PTP_RESPONSE_GEN_ERROR;
929                         DBG("PTP_RESPONSE_GEN_ERROR");
930                         break;
931                 }
932         }
933
934         g_free(blk.data);
935         if (_device_get_phase() != DEVICE_PHASE_NOTREADY) {
936                 if (resp == PTP_RESPONSE_OK) {
937                         hdlr->last_fmt_code = obj->obj_info->obj_fmt;
938                         resp_param[0] = hdlr->data4_send_obj.store_id;
939
940                         /* PTP spec here requires that 0xFFFFFFFF be sent if root is the parent object,
941                          * while in some situations(e.g. MoveObject, CopyObject), 0x00000000 (as
942                          * PTP_OBJECTHANDLE_ROOT is defined) represents the root.
943                          */
944                         resp_param[1] = (hdlr->data4_send_obj.h_parent
945                                         != PTP_OBJECTHANDLE_ROOT) ?
946                                 hdlr->data4_send_obj.h_parent :
947                                 0xFFFFFFFF;
948                         resp_param[2] = hdlr->data4_send_obj.obj_handle;
949                         _cmd_hdlr_send_response(hdlr, resp, 3, resp_param);
950                 } else {
951                         _cmd_hdlr_send_response_code(hdlr, resp);
952                 }
953         }
954 }
955
956 static void __send_object(mtp_handler_t *hdlr)
957 {
958         data_blk_t blk = { 0 };
959         mtp_uint16 resp = PTP_RESPONSE_OK;
960         mtp_char temp_fpath[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
961
962         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0) ||
963                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
964                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
965
966                 ERR("unsupported parameter");
967                 _device_set_phase(DEVICE_PHASE_NOTREADY);
968                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_INVALIDPARAM);
969                 return;
970         }
971 #ifndef MTP_USE_SELFMAKE_ABSTRACTION
972         if (hdlr->data4_send_obj.is_valid != TRUE) {
973                 DBG("invalide object info");
974                 _device_set_phase(DEVICE_PHASE_NOTREADY);
975                 return;
976         }
977 #endif /*MTP_USE_SELFMAKE_ABSTRACTION*/
978
979         _device_set_phase(DEVICE_PHASE_DATAOUT);
980         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
981
982         if (_hdlr_rcv_file_in_data_container(&blk, temp_fpath,
983                                 MTP_MAX_PATHNAME_SIZE + 1) == FALSE) {
984                 _device_set_phase(DEVICE_PHASE_IDLE);
985
986                 ERR("_hdlr_rcv_file_in_data_container() Fail");
987                 g_free(blk.data);
988                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
989                 return;
990         }
991
992         switch (_hutil_write_file_data(hdlr->data4_send_obj.store_id,
993                                 hdlr->data4_send_obj.obj, temp_fpath)) {
994
995         case MTP_ERROR_INVALID_OBJECT_INFO:
996                 resp = PTP_RESPONSE_NOVALID_OBJINFO;
997                 DBG("PTP_RESPONSE_NOVALID_OBJINFO");
998                 break;
999 #ifdef MTP_USE_SELFMAKE_ABSTRACTION
1000         case MTP_ERROR_INVALID_PARAM:   /* association file*/
1001 #endif /*MTP_USE_SELFMAKE_ABSTRACTION*/
1002         case MTP_ERROR_NONE:
1003                 resp = PTP_RESPONSE_OK;
1004                 DBG("PTP_RESPONSE_OK");
1005                 break;
1006         case MTP_ERROR_STORE_FULL:
1007                 resp = PTP_RESPONSE_STOREFULL;
1008                 DBG("PTP_RESPONSE_STOREFULL");
1009                 break;
1010         default:
1011                 resp = PTP_RESPONSE_GEN_ERROR;
1012                 DBG("PTP_RESPONSE_GEN_ERROR");
1013         }
1014         _cmd_hdlr_send_response_code(hdlr, resp);
1015
1016         /* This object info has been consumed.*/
1017         hdlr->data4_send_obj.obj = NULL;
1018         hdlr->data4_send_obj.is_valid = FALSE;
1019
1020         g_free(blk.data);
1021 }
1022
1023 static void __delete_object(mtp_handler_t *hdlr)
1024 {
1025         mtp_uint32 obj_handle = 0;
1026         mtp_uint32 fmt = 0;
1027         mtp_uint16 resp = 0;
1028
1029         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
1030
1031                 ERR("Parameters not supported");
1032                 _cmd_hdlr_send_response_code(hdlr,
1033                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
1034                 return;
1035         }
1036
1037         obj_handle = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
1038         fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
1039         if ((PTP_FORMATCODE_NOTUSED != fmt) &&
1040                         (obj_handle != PTP_OBJECTHANDLE_ALL)) {
1041                 ERR("Invalid object format");
1042                 _cmd_hdlr_send_response_code(hdlr,
1043                                 PTP_RESPONSE_INVALID_OBJ_FMTCODE);
1044                 return;
1045         }
1046
1047         _transport_set_mtp_operation_state(MTP_STATE_DATA_PROCESSING);
1048
1049         switch (_hutil_remove_object_entry(obj_handle, fmt)) {
1050         case MTP_ERROR_NONE:
1051                 resp = PTP_RESPONSE_OK;
1052                 break;
1053         case MTP_ERROR_STORE_READ_ONLY:
1054                 resp = PTP_RESPONSE_STORE_READONLY;
1055                 break;
1056         case MTP_ERROR_PARTIAL_DELETION:
1057                 resp = PTP_RESPONSE_PARTIAL_DELETION;
1058                 break;
1059         case MTP_ERROR_OBJECT_WRITE_PROTECTED:
1060                 resp = PTP_RESPONSE_OBJ_WRITEPROTECTED;
1061                 break;
1062         case MTP_ERROR_ACCESS_DENIED:
1063                 resp = PTP_RESPONSE_ACCESSDENIED;
1064                 break;
1065         case MTP_ERROR_INVALID_OBJECTHANDLE:
1066                 resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
1067                 break;
1068         default:
1069                 resp = PTP_RESPONSE_GEN_ERROR;
1070         }
1071
1072         _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
1073         _cmd_hdlr_send_response_code(hdlr, resp);
1074 }
1075
1076 static void __format_store(mtp_handler_t *hdlr)
1077 {
1078         mtp_uint32 store_id = 0;
1079         mtp_uint32 fs_fmt = 0;
1080
1081         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
1082                 _cmd_hdlr_send_response_code(hdlr,
1083                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
1084                 return;
1085         }
1086
1087         store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
1088         fs_fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
1089
1090         _hutil_format_storage(store_id, fs_fmt);
1091
1092         /* although there is remain file, send OK */
1093         _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
1094 }
1095
1096 static void __reset_device(mtp_handler_t *hdlr)
1097 {
1098         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0) ||
1099                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
1100                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
1101
1102                 _cmd_hdlr_send_response_code(hdlr,
1103                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
1104                 return;
1105         }
1106
1107         _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
1108 }
1109
1110 static void __get_device_prop_desc(mtp_handler_t *hdlr)
1111 {
1112         device_prop_desc_t dev_prop = { { 0 }, };
1113         device_prop_desc_t *prop_ptr = NULL;
1114         ptp_string_t ptp_str = { 0, { 0 } };
1115         data_blk_t blk = { 0 };
1116         mtp_uint32 prop_id = 0;
1117         mtp_uint32 resp = 0;
1118         mtp_uint32 num_bytes = 0;
1119         mtp_uchar *ptr = NULL;
1120         mtp_wchar temp[MTP_MAX_REG_STRING + 1] = { 0 };
1121
1122         prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
1123         switch (prop_id) {
1124 #ifdef MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL
1125         case PTP_PROPERTYCODE_BATTERYLEVEL:
1126                 {
1127                         mtp_int32 batt = 0;
1128
1129                         prop_ptr = _device_get_device_property(prop_id);
1130                         if (NULL == prop_ptr) {
1131                                 ERR("prop_ptr is NULL!");
1132                                 break;
1133                         }
1134
1135                         batt = _util_get_battery_level();
1136                         if (FALSE == _prop_set_current_integer(prop_ptr, batt))
1137                                 ERR("_util_get_battery_level() Fail");
1138                         break;
1139                 }
1140 #endif /* MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL */
1141
1142         case MTP_PROPERTYCODE_DEVICEFRIENDLYNAME:
1143                 {
1144                         mtp_char *dev_name = _device_get_device_name();
1145                         if (dev_name == NULL) {
1146                                 ERR("_device_get_device_name() Fail");
1147                                 break;
1148                         }
1149
1150                         prop_ptr = _device_get_device_property(prop_id);
1151                         if (NULL == prop_ptr) {
1152                                 ERR("prop_ptr is Null");
1153                                 g_free(dev_name);
1154                                 break;
1155                         }
1156                         _util_utf8_to_utf16(temp, sizeof(temp) / WCHAR_SIZ, dev_name);
1157                         _prop_copy_char_to_ptpstring(&ptp_str, temp, WCHAR_TYPE);
1158                         _prop_set_current_string(prop_ptr, &ptp_str);
1159                         g_free(dev_name);
1160                         break;
1161                 }
1162
1163         case MTP_PROPERTYCODE_SYNCHRONIZATIONPARTNER:
1164                 {
1165                         mtp_char *sync_ptr = _device_get_sync_partner();
1166                         if (NULL == sync_ptr) {
1167                                 ERR("_device_get_sync_partner() Fail");
1168                                 break;
1169                         }
1170                         prop_ptr = _device_get_device_property(prop_id);
1171                         if (NULL == prop_ptr) {
1172                                 ERR("prop_ptr is Null");
1173                                 g_free(sync_ptr);
1174                                 break;
1175                         }
1176
1177                         _util_utf8_to_utf16(temp, sizeof(temp) / WCHAR_SIZ, sync_ptr);
1178                         _prop_copy_char_to_ptpstring(&ptp_str, temp, WCHAR_TYPE);
1179                         _prop_set_current_string(prop_ptr, &ptp_str);
1180                         g_free(sync_ptr);
1181                         break;
1182                 }
1183         case MTP_PROPERTYCODE_DEVICEICON:
1184                 {
1185                         FILE* h_file;
1186                         mtp_uint32 bytes_read = 0;
1187                         mtp_uint32 file_size = 0;
1188                         struct stat buf;
1189                         mtp_uchar *data = NULL;
1190                         mtp_int32 err = 0;
1191
1192                         prop_ptr = _device_get_device_property(prop_id);
1193                         if (NULL == prop_ptr) {
1194                                 ERR("prop_ptr is Null");
1195                                 break;
1196                         }
1197
1198                         h_file = _util_file_open(MTP_DEVICE_ICON, MTP_FILE_READ, &err);
1199                         if (h_file == NULL) {
1200                                 ERR("file handle is not valid");
1201                                 _cmd_hdlr_send_response_code(hdlr,
1202                                                 PTP_RESPONSE_GEN_ERROR);
1203                                 return;
1204                         }
1205                         if (fstat(fileno((FILE *)h_file), &buf) != 0) {
1206                                 _util_file_close(h_file);
1207                                 _cmd_hdlr_send_response_code(hdlr,
1208                                                 PTP_RESPONSE_GEN_ERROR);
1209                                 return;
1210                         }
1211                         file_size = buf.st_size;
1212                         data = (mtp_uchar *)g_malloc(file_size + sizeof(mtp_uint32));
1213                         if (data == NULL) {
1214                                 ERR("g_malloc() Fail");
1215                                 _util_file_close(h_file);
1216                                 _cmd_hdlr_send_response_code(hdlr,
1217                                                 PTP_RESPONSE_GEN_ERROR);
1218                                 return;
1219                         }
1220                         memcpy(data, &file_size, sizeof(mtp_uint32));
1221                         _util_file_read(h_file, &data[sizeof(mtp_uint32)], file_size,
1222                                         &bytes_read);
1223                         if (bytes_read != file_size) {
1224                                 ERR("Number of read bytes less than requested");
1225                                 _util_file_close(h_file);
1226                                 g_free(data);
1227                                 _cmd_hdlr_send_response_code(hdlr,
1228                                                 PTP_RESPONSE_GEN_ERROR);
1229                                 return;
1230                         }
1231
1232                         _prop_set_current_array(prop_ptr, data);
1233                         _prop_set_default_array(&(prop_ptr->propinfo),
1234                                         (mtp_uchar *)&data[sizeof(mtp_uint32)], bytes_read);
1235                         g_free(data);
1236                         _util_file_close(h_file);
1237                         break;
1238                 }
1239
1240         default:
1241                 ERR("Unknown PropId : [0x%x]\n", prop_id);
1242                 break;
1243         }
1244
1245         if (_hutil_get_device_property(prop_id, &dev_prop) != MTP_ERROR_NONE) {
1246                 ERR("_hutil_get_device_property returned error");
1247                 resp = PTP_RESPONSE_PROP_NOTSUPPORTED;
1248                 _cmd_hdlr_send_response_code(hdlr, resp);
1249                 return;
1250         }
1251         num_bytes = _prop_size_device_prop_desc(&dev_prop);
1252
1253         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
1254         ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
1255         if (ptr == NULL) {
1256                 resp = PTP_RESPONSE_GEN_ERROR;
1257                 _cmd_hdlr_send_response_code(hdlr, resp);
1258                 g_free(blk.data);
1259                 return;
1260         }
1261
1262         if (_prop_pack_device_prop_desc(&dev_prop, ptr, num_bytes) != num_bytes) {
1263                 resp = PTP_RESPONSE_GEN_ERROR;
1264                 _cmd_hdlr_send_response_code(hdlr, resp);
1265                 g_free(blk.data);
1266                 return;
1267         }
1268
1269         _device_set_phase(DEVICE_PHASE_DATAIN);
1270         if (_hdlr_send_data_container(&blk))
1271                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
1272         else {
1273                 _device_set_phase(DEVICE_PHASE_NOTREADY);
1274                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
1275         }
1276
1277         g_free(blk.data);
1278         return;
1279 }
1280
1281 static void __get_device_prop_value(mtp_handler_t *hdlr)
1282 {
1283
1284         ptp_string_t ptp_str = { 0, { 0 } };
1285         data_blk_t blk = { 0 };
1286         mtp_uint32 prop_id = 0;
1287         mtp_uint32 no_bytes = 0;
1288         mtp_uchar *ptr = NULL;
1289         mtp_wchar temp[MTP_MAX_REG_STRING + 1] = { 0 };
1290
1291         prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
1292         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
1293
1294         switch (prop_id) {
1295 #ifdef MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL
1296         case PTP_PROPERTYCODE_BATTERYLEVEL: {
1297                                                                                         mtp_int32 batt = 0;
1298
1299                                                                                         batt = _util_get_battery_level();
1300                                                                                         no_bytes = sizeof(batt);
1301
1302                                                                                         ptr = _hdlr_alloc_buf_data_container(&blk, no_bytes, no_bytes);
1303                                                                                         if (ptr == NULL) {
1304                                                                                                 _cmd_hdlr_send_response_code(hdlr,
1305                                                                                                                 PTP_RESPONSE_GEN_ERROR);
1306                                                                                                 g_free(blk.data);
1307                                                                                                 return;
1308                                                                                         }
1309                                                                                         memcpy(ptr, &batt, no_bytes);
1310 #ifdef __BIG_ENDIAN__
1311                                                                                         _util_conv_byte_order(ptr, no_bytes);
1312 #endif /*__BIG_ENDIAN__*/
1313                                                                                         break;
1314                                                                                 }
1315 #endif /* MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL */
1316
1317         case MTP_PROPERTYCODE_DEVICEFRIENDLYNAME:
1318                 {
1319
1320                                                                                                   mtp_char *device = _device_get_device_name();
1321                                                                                                   if (device == NULL) {
1322                                                                                                           ERR("_device_get_device_name() Fail");
1323                                                                                                           _cmd_hdlr_send_response_code(hdlr,
1324                                                                                                                           PTP_RESPONSE_GEN_ERROR);
1325                                                                                                           return;
1326                                                                                                   }
1327
1328                                                                                                   _util_utf8_to_utf16(temp, sizeof(temp) / WCHAR_SIZ, device);
1329                                                                                                   _prop_copy_char_to_ptpstring(&ptp_str, temp, WCHAR_TYPE);
1330                                                                                                   no_bytes = _prop_size_ptpstring(&ptp_str);
1331                                                                                                   g_free(device);
1332
1333                                                                                                   ptr = _hdlr_alloc_buf_data_container(&blk, no_bytes, no_bytes);
1334                                                                                                   if (ptr == NULL) {
1335                                                                                                           _cmd_hdlr_send_response_code(hdlr,
1336                                                                                                                           PTP_RESPONSE_GEN_ERROR);
1337                                                                                                           g_free(blk.data);
1338                                                                                                           return;
1339                                                                                                   }
1340
1341                                                                                                   if (_prop_pack_ptpstring(&ptp_str, ptr, no_bytes) != no_bytes) {
1342                                                                                                           _cmd_hdlr_send_response_code(hdlr,
1343                                                                                                                           PTP_RESPONSE_GEN_ERROR);
1344                                                                                                           g_free(blk.data);
1345                                                                                                           return;
1346                                                                                                   }
1347                                                                                                   break;
1348                                                                                           }
1349
1350         case MTP_PROPERTYCODE_SYNCHRONIZATIONPARTNER:
1351                 {
1352
1353                                                                                                           mtp_char *sync_ptr = _device_get_sync_partner();
1354                                                                                                           if (sync_ptr == NULL) {
1355                                                                                                                   ERR("_device_get_sync_partner() Fail");
1356                                                                                                                   _cmd_hdlr_send_response_code(hdlr,
1357                                                                                                                                   PTP_RESPONSE_GEN_ERROR);
1358                                                                                                                   return;
1359                                                                                                           }
1360                                                                                                           _util_utf8_to_utf16(temp, sizeof(temp) / WCHAR_SIZ, sync_ptr);
1361                                                                                                           g_free(sync_ptr);
1362
1363                                                                                                           _prop_copy_char_to_ptpstring(&ptp_str, temp, WCHAR_TYPE);
1364                                                                                                           no_bytes = _prop_size_ptpstring(&ptp_str);
1365
1366                                                                                                           ptr = _hdlr_alloc_buf_data_container(&blk, no_bytes, no_bytes);
1367                                                                                                           if (ptr == NULL) {
1368                                                                                                                   _cmd_hdlr_send_response_code(hdlr,
1369                                                                                                                                   PTP_RESPONSE_GEN_ERROR);
1370                                                                                                                   g_free(blk.data);
1371                                                                                                                   return;
1372                                                                                                           }
1373
1374                                                                                                           if (_prop_pack_ptpstring(&ptp_str, ptr, no_bytes) != no_bytes) {
1375                                                                                                                   _cmd_hdlr_send_response_code(hdlr,
1376                                                                                                                                   PTP_RESPONSE_GEN_ERROR);
1377                                                                                                                   g_free(blk.data);
1378                                                                                                                   return;
1379                                                                                                           }
1380                                                                                                           break;
1381                                                                                                   }
1382
1383         case MTP_PROPERTYCODE_DEVICEICON:
1384                 {
1385
1386                                                                                   FILE *h_file;
1387                                                                                   mtp_uint32 read_bytes = 0;
1388                                                                                   mtp_uint32 file_size = 0;
1389                                                                                   struct stat buf;
1390                                                                                   mtp_uchar *data = NULL;
1391                                                                                   mtp_int32 err = 0;
1392                                                                                   ptp_array_t val_arr = { 0 };
1393                                                                                   mtp_uint32 ii;
1394
1395                                                                                   h_file = _util_file_open(MTP_DEVICE_ICON, MTP_FILE_READ, &err);
1396                                                                                   if (h_file == NULL) {
1397                                                                                           ERR("file handle is not valid");
1398                                                                                           _cmd_hdlr_send_response_code(hdlr,
1399                                                                                                           PTP_RESPONSE_GEN_ERROR);
1400                                                                                           return;
1401                                                                                   }
1402                                                                                   if (fstat(fileno(h_file), &buf) != 0) {
1403                                                                                           _util_file_close(h_file);
1404                                                                                           _cmd_hdlr_send_response_code(hdlr,
1405                                                                                                           PTP_RESPONSE_GEN_ERROR);
1406                                                                                           return;
1407                                                                                   }
1408
1409                                                                                   file_size = buf.st_size;
1410                                                                                   data = (mtp_uchar *)g_malloc(file_size);
1411                                                                                   if (data == NULL) {
1412                                                                                           ERR("g_malloc() Fail");
1413                                                                                           _util_file_close(h_file);
1414                                                                                           _cmd_hdlr_send_response_code(hdlr,
1415                                                                                                           PTP_RESPONSE_GEN_ERROR);
1416                                                                                           return;
1417                                                                                   }
1418
1419                                                                                   _util_file_read(h_file, &data, file_size, &read_bytes);
1420                                                                                   if (read_bytes != file_size) {
1421                                                                                           ERR("Number of read bytes less than requested");
1422                                                                                           _util_file_close(h_file);
1423                                                                                           g_free(data);
1424                                                                                           _cmd_hdlr_send_response_code(hdlr,
1425                                                                                                           PTP_RESPONSE_GEN_ERROR);
1426                                                                                           return;
1427                                                                                   }
1428
1429                                                                                   _prop_init_ptparray(&val_arr, UINT8_TYPE);
1430                                                                                   _prop_grow_ptparray(&val_arr, read_bytes);
1431                                                                                   for (ii = 0; ii < read_bytes; ii++)
1432                                                                                           _prop_append_ele_ptparray(&val_arr, data[ii]);
1433
1434                                                                                   no_bytes = _prop_get_size_ptparray(&val_arr);
1435                                                                                   ptr = _hdlr_alloc_buf_data_container(&blk, no_bytes, no_bytes);
1436                                                                                   if (ptr == NULL) {
1437                                                                                           _cmd_hdlr_send_response_code(hdlr,
1438                                                                                                           PTP_RESPONSE_GEN_ERROR);
1439                                                                                           g_free(blk.data);
1440                                                                                           g_free(data);
1441                                                                                           _util_file_close(h_file);
1442                                                                                           _prop_deinit_ptparray(&val_arr);
1443                                                                                           return;
1444                                                                                   }
1445                                                                                   if (_prop_pack_ptparray(&val_arr, ptr, no_bytes) != no_bytes) {
1446                                                                                           _cmd_hdlr_send_response_code(hdlr,
1447                                                                                                           PTP_RESPONSE_GEN_ERROR);
1448                                                                                           g_free(blk.data);
1449                                                                                           g_free(data);
1450                                                                                           _prop_deinit_ptparray(&val_arr);
1451                                                                                           _util_file_close(h_file);
1452                                                                                           return;
1453                                                                                   }
1454
1455                                                                                   g_free(data);
1456                                                                                   _prop_deinit_ptparray(&val_arr);
1457                                                                                   _util_file_close(h_file);
1458
1459                                                                                   break;
1460                                                                           }
1461
1462         default:
1463                                                                           ERR("Unknown PropId : [0x%x]\n", prop_id);
1464                                                                           _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
1465                                                                           return;
1466         }
1467
1468         _device_set_phase(DEVICE_PHASE_DATAIN);
1469         if (_hdlr_send_data_container(&blk)) {
1470                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
1471         } else {
1472                 _device_set_phase(DEVICE_PHASE_NOTREADY);
1473                 _cmd_hdlr_send_response_code(hdlr,
1474                                 PTP_RESPONSE_INCOMPLETETRANSFER);
1475         }
1476         g_free(blk.data);
1477         return;
1478 }
1479
1480 static void __set_device_prop_value(mtp_handler_t *hdlr)
1481 {
1482         mtp_uint32 prop_id = 0;
1483         data_blk_t blk = { 0 };
1484         mtp_uint32 max_bytes = 0;
1485         mtp_uint16 resp = PTP_RESPONSE_OK;
1486         mtp_err_t ret = 0;
1487         mtp_char *d_raw = NULL;
1488
1489         prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
1490         _device_set_phase(DEVICE_PHASE_DATAOUT);
1491
1492         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
1493         max_bytes = MAX_SIZE_IN_BYTES_OF_PROP_VALUE;
1494
1495         if (FALSE == _hdlr_rcv_data_container(&blk, max_bytes)) {
1496                 ERR("_hdlr_rcv_data_container() Fail");
1497                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
1498                 g_free(blk.data);
1499                 return;
1500         }
1501
1502         d_raw = (mtp_char *)_hdlr_get_payload_data(&blk);
1503         if (NULL != d_raw) {
1504                 ret = _hutil_set_device_property(prop_id, d_raw,
1505                                 _hdlr_get_payload_size(&blk));
1506         } else {
1507                 ret = MTP_ERROR_INVALID_OBJ_PROP_CODE;
1508         }
1509
1510         switch (ret) {
1511         case MTP_ERROR_NONE: {
1512 #ifdef MTP_USE_INFORMATION_REGISTRY
1513
1514                                                          mtp_char temp[MTP_MAX_REG_STRING * 3 + 1] = { 0 };
1515                                                          mtp_wchar parsed_buf[MTP_MAX_REG_STRING + 1] = { 0 };
1516                                                          mtp_uchar parse_sz = 0;
1517
1518                                                          if (MTP_PROPERTYCODE_SYNCHRONIZATIONPARTNER == prop_id) {
1519                                                                  parse_sz = d_raw[0];
1520                                                                  _util_wchar_ncpy(parsed_buf, (mtp_wchar *)&d_raw[1],
1521                                                                                  parse_sz > MTP_MAX_REG_STRING ?
1522                                                                                  MTP_MAX_REG_STRING : parse_sz);
1523                                                                  _util_utf16_to_utf8(temp, sizeof(temp), parsed_buf);
1524                                                                  _device_set_sync_partner(temp);
1525                                                                  if (!g_strcmp0(temp,
1526                                                                                          MTP_DEV_PROPERTY_NULL_SYNCPARTNER)) {
1527                                                                          vconf_set_str(VCONFKEY_MTP_SYNC_PARTNER_STR,
1528                                                                                          "");
1529                                                                  } else {
1530                                                                          vconf_set_str(VCONFKEY_MTP_SYNC_PARTNER_STR,
1531                                                                                          temp);
1532                                                                  }
1533                                                          }
1534 #endif /*MTP_USE_INFORMATION_REGISTRY*/
1535                                                  }
1536                                                  resp = PTP_RESPONSE_OK;
1537                                                  break;
1538         case MTP_ERROR_ACCESS_DENIED:
1539                                                  resp = PTP_RESPONSE_ACCESSDENIED;
1540                                                  break;
1541         case MTP_ERROR_INVALID_OBJ_PROP_VALUE:
1542                                                  resp = PTP_RESPONSE_INVALIDPROPVALUE;
1543                                                  break;
1544         default:
1545                                                  resp = PTP_RESPONSE_PROP_NOTSUPPORTED;
1546         }
1547
1548         _cmd_hdlr_send_response_code(hdlr, resp);
1549
1550         g_free(blk.data);
1551         return;
1552 }
1553
1554 static void __get_partial_object(mtp_handler_t *hdlr)
1555 {
1556         mtp_uint32 h_obj = 0;
1557         off_t offset = 0;
1558         mtp_uint32 data_sz = 0;
1559         mtp_uint32 send_bytes = 0;
1560         data_blk_t blk = { 0 };
1561         mtp_uchar *ptr = NULL;
1562         mtp_uint16 resp = 0;
1563         mtp_uint64 f_size = 0;
1564         mtp_uint64 total_sz = 0;
1565
1566         offset = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
1567         data_sz = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
1568         h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
1569
1570         switch (_hutil_get_object_entry_size(h_obj, &f_size)) {
1571
1572         case MTP_ERROR_INVALID_OBJECTHANDLE:
1573                 resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
1574                 break;
1575         case MTP_ERROR_NONE:
1576                 if (data_sz > (f_size - offset))
1577                         send_bytes = f_size - offset;
1578                 else
1579                         send_bytes = data_sz;
1580                 resp = PTP_RESPONSE_OK;
1581                 break;
1582         default:
1583                 resp = PTP_RESPONSE_GEN_ERROR;
1584                 break;
1585         }
1586
1587         if (PTP_RESPONSE_OK != resp) {
1588                 _cmd_hdlr_send_response_code(hdlr, resp);
1589                 return;
1590         }
1591
1592         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
1593         ptr = _hdlr_alloc_buf_data_container(&blk, send_bytes, send_bytes);
1594
1595         if (NULL != ptr) {
1596                 switch (_hutil_read_file_data_from_offset(h_obj, offset, ptr, &send_bytes)) {
1597                 case MTP_ERROR_NONE:
1598                         resp = PTP_RESPONSE_OK;
1599                         break;
1600                 case MTP_ERROR_INVALID_OBJECTHANDLE:
1601                         resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
1602                         break;
1603                 default:
1604                         resp = PTP_RESPONSE_GEN_ERROR;
1605                 }
1606         } else {
1607                 resp = PTP_RESPONSE_GEN_ERROR;
1608         }
1609
1610         if (PTP_RESPONSE_OK == resp) {
1611                 _device_set_phase(DEVICE_PHASE_DATAIN);
1612                 if (_hdlr_send_data_container(&blk)) {
1613                         total_sz = send_bytes + sizeof(header_container_t);
1614                         if (total_sz % _transport_get_usb_packet_len() == 0)
1615                                 _transport_send_zlp();
1616                         _cmd_hdlr_send_response(hdlr, resp, 1, &send_bytes);
1617                         g_free(blk.data);
1618                         return;
1619                 }
1620
1621                 /*Host Cancelled data-in transfer*/
1622                 _device_set_phase(DEVICE_PHASE_NOTREADY);
1623                 g_free(blk.data);
1624                 return;
1625         }
1626
1627         _cmd_hdlr_send_response_code(hdlr, resp);
1628
1629         g_free(blk.data);
1630         return;
1631 }
1632
1633 static void __get_object_references(mtp_handler_t *hdlr)
1634 {
1635         mtp_uint32 h_obj = 0;
1636         ptp_array_t ref_arr = { 0 };
1637         data_blk_t blk = { 0 };
1638         mtp_uint32 num_bytes = 0;
1639         mtp_uchar *ptr = NULL;
1640         mtp_uint32 num_ele = 0;
1641         mtp_uint16 resp = 0;
1642
1643         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
1644                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
1645
1646                 ERR("Unsupported Parameters");
1647                 _cmd_hdlr_send_response_code(hdlr,
1648                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
1649                 return;
1650         }
1651
1652         h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
1653
1654         switch (_hutil_get_object_references(h_obj, &ref_arr, &num_ele)) {
1655         case MTP_ERROR_INVALID_OBJECTHANDLE:
1656                 resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
1657                 break;
1658         case MTP_ERROR_NONE:
1659                 resp = PTP_RESPONSE_OK;
1660                 break;
1661         default:
1662                 resp = PTP_RESPONSE_GEN_ERROR;
1663         }
1664
1665         if (resp != PTP_RESPONSE_OK) {
1666                 _cmd_hdlr_send_response_code(hdlr, resp);
1667                 return;
1668         }
1669
1670         if (resp == PTP_RESPONSE_OK && num_ele == 0) {
1671                 _cmd_hdlr_send_response_code(hdlr, resp);
1672                 return;
1673         }
1674
1675         num_bytes = _prop_get_size_ptparray(&ref_arr);
1676         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
1677
1678         ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
1679         if (num_bytes == _prop_pack_ptparray(&ref_arr, ptr, num_bytes)) {
1680                 _device_set_phase(DEVICE_PHASE_DATAIN);
1681                 if (_hdlr_send_data_container(&blk)) {
1682                         _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
1683                 } else {
1684                         /* Host Cancelled data-in transfer*/
1685                         _device_set_phase(DEVICE_PHASE_NOTREADY);
1686                 }
1687         } else {
1688                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
1689         }
1690
1691         _prop_deinit_ptparray(&ref_arr);
1692         g_free(blk.data);
1693
1694         return;
1695 }
1696
1697 static void __set_object_references(mtp_handler_t *hdlr)
1698 {
1699         mtp_uint32 h_obj = 0;
1700         data_blk_t blk = { 0 };
1701         mtp_uint32 max_bytes = 0;
1702         mtp_uint16 resp = PTP_RESPONSE_OK;
1703         mtp_uint32 num_ref = 0;
1704         mtp_uint32 idx = 0;
1705         mtp_uint32 *ref_ptr = NULL;
1706         mtp_uchar *ptr = NULL;
1707         mtp_uint32 ref_handle = 0;
1708
1709         h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
1710         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
1711                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
1712
1713                 resp = PTP_RESPONSE_PARAM_NOTSUPPORTED;
1714                 _cmd_hdlr_send_response_code(hdlr, resp);
1715         }
1716
1717         _device_set_phase(DEVICE_PHASE_DATAOUT);
1718         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
1719
1720         /* temporarily set a big number for data size received */
1721
1722         max_bytes = MTP_MAX_REFDB_ROWCNT * sizeof(mtp_uint32);
1723         if (_hdlr_rcv_data_container(&blk, max_bytes) == FALSE) {
1724                 DBG("_hdlr_rcv_data_container() Fail");
1725                 _device_set_phase(DEVICE_PHASE_IDLE);
1726                 resp = PTP_RESPONSE_GEN_ERROR;
1727         }
1728
1729         if (PTP_RESPONSE_OK != resp) {
1730                 _cmd_hdlr_send_response_code(hdlr, resp);
1731                 g_free(blk.data);
1732                 return;
1733         }
1734
1735         ptr = _hdlr_get_payload_data(&blk);
1736         if (ptr == NULL) {
1737                 g_free(blk.data);
1738                 return;
1739         }
1740
1741         memcpy(&num_ref, ptr, sizeof(mtp_uint32));
1742 #ifdef __BIG_ENDIAN__
1743         _util_conv_byte_order(&num_ref, sizeof(DWORD));
1744 #endif /* __BIG_ENDIAN__ */
1745
1746         ptr += sizeof(mtp_uint32);
1747         if (_hdlr_get_payload_size(&blk) < (num_ref + 1) * sizeof(mtp_uint32)) {
1748
1749                 resp = PTP_RESPONSE_GEN_ERROR;
1750                 _cmd_hdlr_send_response_code(hdlr, resp);
1751                 g_free(blk.data);
1752                 return;
1753         }
1754
1755         ref_ptr = (mtp_uint32 *)ptr;
1756         if (MTP_ERROR_NONE != _hutil_remove_object_reference(h_obj,
1757                                 PTP_OBJECTHANDLE_ALL)) {
1758                 resp = PTP_RESPONSE_GEN_ERROR;
1759                 _cmd_hdlr_send_response_code(hdlr, resp);
1760                 g_free(blk.data);
1761         }
1762
1763         for (idx = 0; idx < num_ref; idx++) {
1764                 ref_handle = ref_ptr[idx];
1765 #ifdef __BIG_ENDIAN__
1766                 _util_conv_byte_order(&ref_handle, sizeof(mtp_uint32));
1767 #endif /*__BIG_ENDIAN__*/
1768                 _device_get_object_with_handle(ref_handle);
1769         }
1770
1771         _hutil_add_object_references_enhanced(h_obj, (mtp_uchar *)ref_ptr,
1772                         num_ref);
1773         _cmd_hdlr_send_response_code(hdlr, resp);
1774
1775         g_free(blk.data);
1776         return;
1777 }
1778
1779 static void __get_object_prop_desc(mtp_handler_t *hdlr)
1780 {
1781         mtp_uint32 prop_id = 0;
1782         mtp_uint32 fmt = 0;
1783         obj_prop_desc_t prop = { { 0 }, };
1784         data_blk_t blk = { 0, };
1785         mtp_uint32 num_bytes = 0;
1786         mtp_uchar *ptr = NULL;
1787
1788         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
1789                 _cmd_hdlr_send_response_code(hdlr,
1790                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
1791                 return;
1792         }
1793
1794         prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
1795         fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
1796
1797         if (MTP_ERROR_NONE != _hutil_get_prop_desc(fmt, prop_id, &prop)) {
1798                 _cmd_hdlr_send_response_code(hdlr,
1799                                 PTP_RESPONSE_PROP_NOTSUPPORTED);
1800                 return;
1801         }
1802
1803         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
1804         num_bytes = _prop_size_obj_prop_desc(&prop);
1805         ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
1806
1807         if (num_bytes == _prop_pack_obj_prop_desc(&prop, ptr, num_bytes)) {
1808                 _device_set_phase(DEVICE_PHASE_DATAIN);
1809                 if (_hdlr_send_data_container(&blk)) {
1810                         _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
1811                 } else {
1812                         /* Host Cancelled data-in transfer */
1813                         _device_set_phase(DEVICE_PHASE_NOTREADY);
1814                 }
1815         } else {
1816                 _cmd_hdlr_send_response_code(hdlr,
1817                                 PTP_RESPONSE_GEN_ERROR);
1818         }
1819
1820         g_free(blk.data);
1821         return;
1822 }
1823
1824 static void __get_object_prop_supported(mtp_handler_t *hdlr)
1825 {
1826         mtp_uint32 fmt = 0;
1827         data_blk_t blk = { 0 };
1828         ptp_array_t props_supported = { 0 };
1829         mtp_uint32 num_bytes = 0;
1830         mtp_uchar *ptr = NULL;
1831
1832         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
1833                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
1834                 _cmd_hdlr_send_response_code(hdlr,
1835                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
1836                 return;
1837         }
1838
1839         fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
1840         _prop_init_ptparray(&props_supported, UINT16_TYPE);
1841
1842         if (MTP_ERROR_NONE != _hutil_get_object_prop_supported(fmt,
1843                                 &props_supported)) {
1844                 _prop_deinit_ptparray(&props_supported);
1845                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
1846                 return;
1847         }
1848
1849         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
1850         num_bytes = _prop_get_size_ptparray(&props_supported);
1851         ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
1852
1853         if (NULL != ptr) {
1854                 _prop_pack_ptparray(&props_supported, ptr, num_bytes);
1855                 _device_set_phase(DEVICE_PHASE_DATAIN);
1856                 if (_hdlr_send_data_container(&blk)) {
1857                         _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
1858                 } else {
1859                         /* Host Cancelled data-in transfer */
1860                         _device_set_phase(DEVICE_PHASE_NOTREADY);
1861                 }
1862         } else {
1863                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
1864         }
1865
1866         _prop_deinit_ptparray(&props_supported);
1867
1868         g_free(blk.data);
1869         return;
1870 }
1871
1872 static void __get_object_prop_value(mtp_handler_t *hdlr)
1873 {
1874         mtp_uint32 h_obj = 0;
1875         mtp_uint32 prop_id = 0;
1876         mtp_uchar *ptr = NULL;
1877         mtp_uint32 num_bytes = 0;
1878         data_blk_t blk = { 0 };
1879         obj_prop_val_t prop_val = { 0 };
1880         mtp_err_t ret = 0;
1881         mtp_obj_t *obj = NULL;
1882 #ifdef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
1883         slist_node_t *node = NULL;
1884         slist_node_t *next_node = NULL;
1885         mtp_uint32 ii = 0;
1886 #endif /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
1887
1888         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
1889                 _cmd_hdlr_send_response_code(hdlr,
1890                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
1891                 return;
1892         }
1893
1894         h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
1895         prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
1896         ret = _hutil_get_object_prop_value(h_obj, prop_id, &prop_val, &obj);
1897
1898         if (MTP_ERROR_NONE == ret) {
1899                 num_bytes = _prop_size_obj_propval(&prop_val);
1900                 _hdlr_init_data_container(&blk, hdlr->usb_cmd.code,
1901                                 hdlr->usb_cmd.tid);
1902                 ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes,
1903                                 num_bytes);
1904                 if (num_bytes ==
1905                                 _prop_pack_obj_propval(&prop_val, ptr, num_bytes)) {
1906
1907                         _device_set_phase(DEVICE_PHASE_DATAIN);
1908                         if (_hdlr_send_data_container(&blk)) {
1909                                 _cmd_hdlr_send_response_code(hdlr,
1910                                                 PTP_RESPONSE_OK);
1911                         } else {
1912                                 /* Host Cancelled data-in transfer */
1913                                 _device_set_phase(DEVICE_PHASE_NOTREADY);
1914                         }
1915                 } else {
1916                         _cmd_hdlr_send_response_code(hdlr,
1917                                         PTP_RESPONSE_GEN_ERROR);
1918                 }
1919
1920                 g_free(blk.data);
1921
1922         } else if (ret == MTP_ERROR_INVALID_OBJECTHANDLE) {
1923                 _cmd_hdlr_send_response_code(hdlr,
1924                                 PTP_RESPONSE_INVALID_OBJ_HANDLE);
1925         } else {
1926                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
1927         }
1928
1929 #ifdef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
1930         if (NULL == obj) {
1931                 ERR("Invalid object");
1932                 return;
1933         }
1934
1935         for (ii = 0, next_node = obj->propval_list.start;
1936                         ii < obj->propval_list.nnodes; ii++) {
1937                 node = next_node;
1938                 next_node = node->link;
1939                 _prop_destroy_obj_propval((obj_prop_val_t *)node->value);
1940                 g_free(node);
1941         }
1942         obj->propval_list.start = NULL;
1943         obj->propval_list.end = NULL;
1944         obj->propval_list.nnodes = 0;
1945 #endif /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
1946
1947         return;
1948 }
1949
1950 static void __set_object_prop_value(mtp_handler_t *hdlr)
1951 {
1952         mtp_uint32 h_obj = 0;
1953         mtp_uint32 prop_id = 0;
1954         mtp_uint16 resp = PTP_RESPONSE_OK;
1955         data_blk_t blk = { 0 };
1956         mtp_uint32 max_bytes = 0;
1957         mtp_err_t ret = 0;
1958
1959         h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
1960         prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
1961
1962         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
1963                 ERR("Unsupported parameters");
1964                 resp = PTP_RESPONSE_PARAM_NOTSUPPORTED;
1965                 _cmd_hdlr_send_response_code(hdlr, resp);
1966                 return;
1967         }
1968
1969         _device_set_phase(DEVICE_PHASE_DATAOUT);
1970         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
1971         max_bytes = MTP_MAX_PROP_DATASIZE;
1972
1973         if (_hdlr_rcv_data_container(&blk, max_bytes) == FALSE) {
1974                 ERR("_hdlr_rcv_data_container() Fail");
1975                 _device_set_phase(DEVICE_PHASE_IDLE);
1976                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_INVALIDPROPVALUE);
1977                 g_free(blk.data);
1978                 return;
1979         }
1980
1981         ret = _hutil_update_object_property(h_obj, prop_id, NULL,
1982                         _hdlr_get_payload_data(&blk),
1983                         _hdlr_get_payload_size(&blk), NULL);
1984         switch (ret) {
1985         case MTP_ERROR_ACCESS_DENIED:
1986                 resp = PTP_RESPONSE_ACCESSDENIED;
1987                 break;
1988         case MTP_ERROR_INVALID_OBJECTHANDLE:
1989                 resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
1990                 break;
1991         case MTP_ERROR_INVALID_OBJ_PROP_CODE:
1992                 resp = PTP_RESPONSE_PROP_NOTSUPPORTED;
1993                 break;
1994         case MTP_ERROR_GENERAL:
1995                 resp = PTP_RESPONSE_GEN_ERROR;
1996                 break;
1997         case MTP_ERROR_NONE:
1998                 resp = PTP_RESPONSE_OK;
1999                 break;
2000         default:
2001                 resp = PTP_RESPONSE_INVALIDPROPVALUE;
2002                 break;
2003         }
2004
2005         _cmd_hdlr_send_response_code(hdlr, resp);
2006
2007         g_free(blk.data);
2008         return;
2009 }
2010
2011 static void __get_object_prop_list(mtp_handler_t *hdlr)
2012 {
2013         mtp_uint32 h_obj = 0;
2014         mtp_uint32 fmt = 0;
2015         mtp_uint32 prop_id = 0;
2016         mtp_uint32 group_code = 0;
2017         mtp_uint32 depth = 0;
2018         mtp_err_t ret = 0;
2019         mtp_uint16 resp = 0;
2020         obj_proplist_t prop_list = { { 0 } };
2021         data_blk_t blk = { 0 };
2022         mtp_uint32 num_bytes = 0;
2023         mtp_uchar *ptr = NULL;
2024 #ifdef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
2025         ptp_array_t obj_arr = { 0 };
2026         slist_node_t *node = NULL;
2027         slist_node_t *next_node = NULL;
2028         mtp_uint32 ii = 0;
2029         mtp_uint32 jj = 0;
2030         mtp_obj_t *obj = NULL;
2031 #endif /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
2032
2033         h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
2034         fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
2035         prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
2036         group_code = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 3);
2037         depth = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 4);
2038
2039         __enum_store_not_enumerated(h_obj, fmt, depth);
2040
2041 #ifdef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
2042         ret = _hutil_get_object_prop_list(h_obj, fmt, prop_id, group_code,
2043                         depth, &prop_list, &obj_arr);
2044 #else /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
2045         ret = _hutil_get_object_prop_list(h_obj, fmt, prop_id, group_code,
2046                         depth, &prop_list);
2047 #endif /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
2048
2049         switch (ret) {
2050         case MTP_ERROR_NONE:
2051                 resp = PTP_RESPONSE_OK;
2052                 break;
2053         case MTP_ERROR_INVALID_OBJECTHANDLE:
2054                 resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
2055                 break;
2056         case MTP_ERROR_INVALID_PARAM:
2057                 resp = PTP_RESPONSE_INVALIDPARAM;
2058                 break;
2059         case MTP_ERROR_NO_SPEC_BY_FORMAT:
2060                 resp = PTP_RESPONSE_NOSPECIFICATIONBYFORMAT;
2061                 break;
2062         case MTP_ERROR_GENERAL:
2063         default:
2064                 resp = PTP_RESPONSE_GEN_ERROR;
2065         }
2066
2067         if (PTP_RESPONSE_OK != resp) {
2068                 _cmd_hdlr_send_response_code(hdlr, resp);
2069                 _prop_deinit_ptparray(&obj_arr);
2070                 return;
2071         }
2072
2073         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
2074         num_bytes = _prop_size_obj_proplist(&prop_list);
2075         ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
2076         if (num_bytes == _prop_pack_obj_proplist(&prop_list, ptr, num_bytes)) {
2077
2078                 _device_set_phase(DEVICE_PHASE_DATAIN);
2079                 if (_hdlr_send_data_container(&blk)) {
2080                         _cmd_hdlr_send_response_code(hdlr, resp);
2081                 } else {
2082                         /* Host Cancelled data-in transfer*/
2083                         _device_set_phase(DEVICE_PHASE_NOTREADY);
2084                 }
2085         }
2086
2087         _prop_destroy_obj_proplist(&prop_list);
2088         g_free(blk.data);
2089
2090 #ifdef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
2091         if (resp == PTP_RESPONSE_OK && obj_arr.array_entry) {
2092                 mtp_uint32 *obj_handles = obj_arr.array_entry;
2093
2094                 for (ii = 0; ii < obj_arr.num_ele; ii++) {
2095                         mtp_store_t *store = NULL;
2096
2097                         store = _device_get_store_containing_obj(obj_handles[ii]);
2098                         if (store == NULL)
2099                                 continue;
2100
2101                         obj = _entity_get_object_from_store(store, obj_handles[ii]);
2102                         if (NULL == obj || obj->propval_list.nnodes == 0)
2103                                 continue;
2104
2105                         /*Remove all the old property value, and ready to set up new */
2106                         for (jj = 0, next_node = obj->propval_list.start;
2107                                         jj < obj->propval_list.nnodes; jj++) {
2108                                 node = next_node;
2109                                 next_node = node->link;
2110                                 _prop_destroy_obj_propval
2111                                         ((obj_prop_val_t *)node->value);
2112                                 g_free(node);
2113                         }
2114                         obj->propval_list.start = NULL;
2115                         obj->propval_list.end = NULL;
2116                         obj->propval_list.nnodes = 0;
2117                         node = NULL;
2118                 }
2119         }
2120         _prop_deinit_ptparray(&obj_arr);
2121 #endif /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
2122         return;
2123 }
2124
2125 static void __set_object_prop_list(mtp_handler_t *hdlr)
2126 {
2127         mtp_uint32 i = 0;
2128         mtp_uint16 resp = PTP_RESPONSE_OK;
2129         data_blk_t blk = { 0 };
2130         mtp_uint32 max_num_obj = 0;
2131         mtp_uint32 max_bytes = 0;
2132         mtp_uint32 h_obj = 0;
2133         mtp_uint32 prop_id = 0;
2134         mtp_uint32 data_type = 0;
2135         mtp_uchar *temp = NULL;
2136         mtp_int32 bytes_left = 0;
2137         mtp_uint32 prop_val_sz = 0;
2138         mtp_uint32 num_elem = 0;
2139         mtp_err_t ret = 0;
2140
2141         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0) ||
2142                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
2143                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2) ||
2144                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 3) ||
2145                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 4)) {
2146                 resp = PTP_RESPONSE_PARAM_NOTSUPPORTED;
2147         }
2148
2149         _device_set_phase(DEVICE_PHASE_DATAOUT);
2150         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
2151
2152         /* Gestimate the amount of data we will be receiving */
2153         _hutil_get_number_of_objects(PTP_STORAGEID_ALL, &max_num_obj);
2154         max_bytes = max_num_obj * 1000;
2155
2156         /* If Host sent more data than we could receive, a device stall happens,
2157          * which cancels the data transfer
2158          */
2159         if (max_bytes > 1000000) {
2160                 max_bytes = 1000000;
2161                 ERR("max_bytes is overflowed");
2162         }
2163         if (FALSE == _hdlr_rcv_data_container(&blk, max_bytes)) {
2164                 ERR("_hdlr_rcv_data_container() Fail");
2165                 _device_set_phase(DEVICE_PHASE_NOTREADY);
2166                 resp = PTP_RESPONSE_GEN_ERROR;
2167         }
2168
2169         if (PTP_RESPONSE_OK != resp) {
2170                 _cmd_hdlr_send_response(hdlr, resp, 1, &i);
2171                 g_free(blk.data);
2172                 return;
2173         }
2174
2175         temp = _hdlr_get_payload_data(&blk);
2176         bytes_left = (mtp_int32)_hdlr_get_payload_size(&blk);
2177         if (bytes_left < sizeof(mtp_uint32)) {
2178
2179                 resp = MTP_RESPONSE_INVALIDOBJPROPFORMAT;
2180                 _cmd_hdlr_send_response(hdlr, resp, 1, &i);
2181                 g_free(blk.data);
2182
2183                 ERR("invalid object format, bytes_left [%d]:[%u]\n", bytes_left,
2184                                 sizeof(mtp_uint32));
2185                 return;
2186         }
2187
2188         num_elem = 0;
2189         memcpy(&num_elem, temp, sizeof(mtp_uint32));
2190         temp += sizeof(mtp_uint32);
2191         bytes_left -= sizeof(mtp_uint32);
2192
2193         for (i = 0; i < num_elem; i++) {
2194                 if (bytes_left < 0)
2195                         break;
2196
2197                 /*Get object handle*/
2198                 memcpy(&h_obj, temp, sizeof(mtp_uint32));
2199                 temp += sizeof(mtp_uint32);
2200                 bytes_left -= sizeof(mtp_uint32);
2201                 if (bytes_left < 0)
2202                         break;
2203
2204                 /* Get property code */
2205                 memcpy(&prop_id, temp, sizeof(mtp_uint16));
2206                 temp += sizeof(mtp_uint16);
2207                 bytes_left -= sizeof(mtp_uint16);
2208                 if (bytes_left < 0)
2209                         break;
2210
2211                 /* Get data type*/
2212                 memcpy(&data_type, temp, sizeof(mtp_uint16));
2213                 temp += sizeof(mtp_uint16);
2214                 bytes_left -= sizeof(mtp_uint16);
2215                 if (bytes_left < 0)
2216                         break;
2217
2218                 /* Update property*/
2219                 ret = _hutil_update_object_property(h_obj, prop_id,
2220                                 (mtp_uint16 *)&data_type, temp, bytes_left,
2221                                 &prop_val_sz);
2222
2223                 switch (ret) {
2224                 case MTP_ERROR_INVALID_OBJECT_PROP_FORMAT:
2225                         resp = MTP_RESPONSE_INVALIDOBJPROPFORMAT;
2226                         _cmd_hdlr_send_response(hdlr, resp, 1, &i);
2227                         g_free(blk.data);
2228                         ERR("invalid object format");
2229                         return;
2230                         break;
2231                 case MTP_ERROR_ACCESS_DENIED:
2232                         resp = PTP_RESPONSE_ACCESSDENIED;
2233                         _cmd_hdlr_send_response(hdlr, resp, 1, &i);
2234                         g_free(blk.data);
2235                         ERR("access denied");
2236                         return;
2237                         break;
2238                 case MTP_ERROR_INVALID_OBJECTHANDLE:
2239                         resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
2240                         _cmd_hdlr_send_response(hdlr, resp, 1, &i);
2241                         g_free(blk.data);
2242                         ERR("invalid object handle");
2243                         return;
2244                         break;
2245                 case MTP_ERROR_INVALID_OBJ_PROP_CODE:
2246                         resp = PTP_RESPONSE_PROP_NOTSUPPORTED;
2247                         _cmd_hdlr_send_response(hdlr, resp, 1, &i);
2248                         g_free(blk.data);
2249                         ERR("property not supported");
2250                         return;
2251                         break;
2252                 case MTP_ERROR_NONE:
2253                         temp += prop_val_sz;
2254                         bytes_left -= prop_val_sz;
2255                         break;
2256                 default:
2257                         resp = PTP_RESPONSE_INVALIDPROPVALUE;
2258                         _cmd_hdlr_send_response(hdlr, resp, 1, &i);
2259                         g_free(blk.data);
2260                         ERR("invalid property value");
2261                         return;
2262                         break;
2263                 }
2264         }
2265         i = 0;
2266         resp = PTP_RESPONSE_OK;
2267         _cmd_hdlr_send_response(hdlr, resp, 1, &i);
2268         g_free(blk.data);
2269         return;
2270 }
2271
2272 static void __report_acquired_content(mtp_handler_t *hdlr)
2273 {
2274         mtp_uint32 tid = 0;
2275         mtp_uint32 start_idx = 0;
2276         mtp_uint32 max_size = 0;
2277         mtp_uint16 resp = PTP_RESPONSE_OK;
2278         mtp_uint32 resp_param[3] = { 0 };
2279         data_blk_t blk = { 0 };
2280         mtp_uchar *ptr = NULL;
2281         ptp_array_t guid_arr = { 0 };
2282         mtp_uint32 num_mod = 0;
2283         mtp_uint32 num_bytes = 0;
2284         mtp_uint32 num_lines = 0;
2285         mtp_uint32 rem_modified = 0;
2286         FILE* h_file;
2287         time_t cur_time;
2288         time_t l_time;
2289         mtp_int32 diff_time;
2290         mtp_int32 err = 0;
2291         mtp_int32 ret = 0;
2292
2293         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 3)) {
2294
2295                 ERR("Unsupported parameters");
2296                 _cmd_hdlr_send_response_code(hdlr,
2297                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
2298                 return;
2299         }
2300
2301         tid = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
2302         start_idx = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
2303         max_size = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
2304
2305         if (tid == 0) {
2306
2307                 if (access(MTP_FILES_MODIFIED_FILES, F_OK) == 0)
2308                         if (remove(MTP_FILES_MODIFIED_FILES) < 0)
2309                                 ERR("remove(%s) Fail", MTP_FILES_MODIFIED_FILES);
2310
2311                 resp = PTP_RESPONSE_OK;
2312                 _prop_grow_ptparray(&guid_arr, 1);
2313                 _prop_append_ele_ptparray(&guid_arr, 0);
2314                 goto DONE;
2315         }
2316
2317         g_is_sync_estab = TRUE;
2318
2319         if (!g_has_round_trip && start_idx == 0) {
2320                 time(&cur_time);
2321                 ret = vconf_get_int(VCONFKEY_MTP_SYNC_TIME_INT, (int *)&l_time);
2322                 if (ret == -1) {
2323                         ERR("Error to get key value at [%s] path\n",
2324                                         VCONFKEY_MTP_SYNC_TIME_INT);
2325                         resp = PTP_RESPONSE_OK;
2326                         _prop_grow_ptparray(&guid_arr, 1);
2327                         _prop_append_ele_ptparray(&guid_arr, 0);
2328                         goto DONE;
2329                 }
2330                 diff_time = (cur_time - l_time) / 60;
2331                 if (diff_time < 0) {
2332                         resp = PTP_RESPONSE_GEN_ERROR;
2333                         _prop_init_ptparray(&guid_arr, UINT32_TYPE);
2334                         _prop_append_ele_ptparray(&guid_arr, 0);
2335                         goto DONE;
2336                 }
2337                 _entity_list_modified_files(diff_time);
2338         }
2339
2340         h_file = _util_file_open(MTP_FILES_MODIFIED_FILES, MTP_FILE_READ, &err);
2341         if (h_file == NULL) {
2342                 resp = PTP_RESPONSE_GEN_ERROR;
2343                 _prop_init_ptparray(&guid_arr, UINT32_TYPE);
2344                 _prop_append_ele_ptparray(&guid_arr, 0);
2345                 goto DONE;
2346         }
2347
2348         if (!g_has_round_trip && start_idx == 0) {
2349                 _util_count_num_lines(h_file, &g_mgr->meta_info.mod);
2350                 _util_file_seek(h_file, 0, SEEK_SET);
2351         }
2352         num_lines = g_mgr->meta_info.mod;
2353         num_mod = ((num_lines - start_idx) > max_size) ?
2354                 max_size : num_lines - start_idx;
2355
2356         rem_modified = (num_lines - start_idx > max_size) ?
2357                 (num_lines - start_idx - max_size) : 0;
2358
2359         g_has_round_trip = FALSE;
2360         _prop_init_ptparray(&guid_arr, UINT32_TYPE);
2361         _prop_grow_ptparray(&guid_arr, (num_mod * sizeof(mtp_uint32)) + 1);
2362         _prop_append_ele_ptparray(&guid_arr, num_mod);
2363         _util_fill_guid_array(&guid_arr, start_idx, h_file, num_mod);
2364
2365         _util_file_close(h_file);
2366         if (rem_modified == 0) {
2367                 if (remove(MTP_FILES_MODIFIED_FILES) < 0)
2368                         ERR("remove(%s) Fail", MTP_FILES_MODIFIED_FILES);
2369
2370                 g_mgr->meta_info.mod = 0;
2371         }
2372
2373 DONE:
2374         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
2375         num_bytes = _prop_get_size_ptparray_without_elemsize(&guid_arr);
2376         ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
2377
2378         if (NULL != ptr) {
2379                 _prop_pack_ptparray_without_elemsize(&guid_arr, ptr, num_bytes);
2380                 _device_set_phase(DEVICE_PHASE_DATAIN);
2381         }
2382
2383         if (_hdlr_send_data_container(&blk))
2384                 resp = PTP_RESPONSE_OK;
2385         else
2386                 resp = PTP_RESPONSE_GEN_ERROR;
2387
2388         _prop_deinit_ptparray(&guid_arr);
2389         g_free(blk.data);
2390
2391         if (PTP_RESPONSE_OK == resp) {
2392
2393                 resp_param[0] = hdlr->usb_cmd.tid;
2394                 resp_param[1] = rem_modified;
2395                 resp_param[2] = 0;
2396                 _cmd_hdlr_send_response(hdlr, resp, 3, resp_param);
2397         } else {
2398                 _cmd_hdlr_send_response_code(hdlr, resp);
2399         }
2400         return;
2401 }
2402
2403 static void __send_playback_skip(mtp_handler_t *hdlr)
2404 {
2405         mtp_int32 skip = 0;
2406         mtp_uint16 resp = PTP_RESPONSE_INVALIDPARAM;
2407
2408         skip = (mtp_int32) _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
2409         if (MTP_ERROR_NONE == _hutil_get_playback_skip(skip))
2410                 resp = PTP_RESPONSE_OK;
2411
2412         _cmd_hdlr_send_response_code(hdlr, resp);
2413         return;
2414 }
2415
2416 #ifndef PMP_VER
2417 static void __self_test(mtp_handler_t *hdlr)
2418 {
2419         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
2420                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
2421                 ERR("Unsupported parameters");
2422                 _cmd_hdlr_send_response_code(hdlr,
2423                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
2424                 return;
2425         }
2426
2427         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
2428         /* Do device-specific tests */
2429         /* After the test */
2430         _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
2431         return;
2432 }
2433
2434 #ifdef MTP_SUPPORT_SET_PROTECTION
2435 static void __set_object_protection(mtp_handler_t *hdlr)
2436 {
2437         mtp_uint32 h_obj = 0;
2438         mtp_uint16 protcn_status = 0;
2439         mtp_uint16 resp = 0;
2440
2441         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
2442                 ERR("Unsupported parameter");
2443                 _cmd_hdlr_send_response_code(hdlr,
2444                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
2445                 return;
2446         }
2447
2448         h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
2449         protcn_status = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
2450
2451         if ((protcn_status != PTP_PROTECTIONSTATUS_NOPROTECTION) &&
2452                         (protcn_status != PTP_PROTECTIONSTATUS_READONLY) &&
2453                         (protcn_status != MTP_PROTECTIONSTATUS_READONLY_DATA) &&
2454                         (protcn_status != MTP_PROTECTIONSTATUS_NONTRANSFERABLE_DATA)) {
2455
2456                 resp = PTP_RESPONSE_INVALIDPARAM;
2457                 _cmd_hdlr_send_response_code(hdlr, resp);
2458                 return;
2459
2460         }
2461         switch (_hutil_set_protection(h_obj, protcn_status)) {
2462         case MTP_ERROR_INVALID_OBJECTHANDLE:
2463                 resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
2464                 break;
2465         case MTP_ERROR_OBJECT_WRITE_PROTECTED:
2466                 resp = PTP_RESPONSE_OBJ_WRITEPROTECTED;
2467                 break;
2468         case MTP_ERROR_NONE:
2469                 resp = PTP_RESPONSE_OK;
2470                 break;
2471         case MTP_ERROR_OPERATION_NOT_SUPPORTED:
2472                 resp = PTP_RESPONSE_OP_NOT_SUPPORTED;
2473                 break;
2474         default:
2475                 resp = PTP_RESPONSE_GEN_ERROR;
2476         }
2477
2478         _cmd_hdlr_send_response_code(hdlr, resp);
2479         return;
2480 }
2481 #endif /* MTP_SUPPORT_SET_PROTECTION */
2482
2483 static void __power_down(mtp_handler_t *hdlr)
2484 {
2485         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0) ||
2486                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
2487                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
2488                 ERR("Unsupported Parameter");
2489                 _cmd_hdlr_send_response_code(hdlr,
2490                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
2491                 return;
2492         }
2493
2494         _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
2495         usleep(1000);
2496         _cmd_hdlr_reset_cmd(hdlr);
2497         return;
2498 }
2499
2500 static void __move_object(mtp_handler_t *hdlr)
2501 {
2502         mtp_uint32 store_id = 0;
2503         mtp_uint32 obj_handle = 0;
2504         mtp_uint32 h_parent = 0;
2505         mtp_uint32 resp = 0;
2506
2507         obj_handle = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
2508         store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
2509         h_parent = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
2510
2511         _transport_set_mtp_operation_state(MTP_STATE_DATA_PROCESSING);
2512
2513         switch (_hutil_move_object_entry(store_id, h_parent, obj_handle)) {
2514         case MTP_ERROR_NONE:
2515                 resp = PTP_RESPONSE_OK;
2516                 break;
2517         case MTP_ERROR_INVALID_OBJECTHANDLE:
2518                 resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
2519                 break;
2520         case MTP_ERROR_OBJECT_WRITE_PROTECTED:
2521                 resp = PTP_RESPONSE_OBJ_WRITEPROTECTED;
2522                 break;
2523         case MTP_ERROR_ACCESS_DENIED:
2524                 resp = PTP_RESPONSE_ACCESSDENIED;
2525                 break;
2526         case MTP_ERROR_STORE_NOT_AVAILABLE:
2527                 resp = PTP_RESPONSE_STORENOTAVAILABLE;
2528                 break;
2529         case MTP_ERROR_INVALID_PARENT:
2530                 resp = PTP_RESPONSE_INVALIDPARENT;
2531                 break;
2532         case MTP_ERROR_INVALID_PARAM:
2533                 resp = PTP_RESPONSE_INVALIDPARAM;
2534                 break;
2535         case MTP_ERROR_STORE_FULL:
2536                 resp = PTP_RESPONSE_STOREFULL;
2537                 break;
2538         default:
2539                 resp = PTP_RESPONSE_GEN_ERROR;
2540         }
2541
2542         _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
2543         _cmd_hdlr_send_response_code(hdlr, resp);
2544         return;
2545 }
2546
2547 static void __copy_object(mtp_handler_t *hdlr)
2548 {
2549         mtp_uint32 store_id = 0;
2550         mtp_uint32 h_obj = 0;
2551         mtp_uint32 h_parent = 0;
2552         mtp_uint32 new_handle = 0;
2553         mtp_uint16 resp = 0;
2554
2555         h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
2556         store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
2557         h_parent = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
2558
2559         _transport_set_mtp_operation_state(MTP_STATE_DATA_PROCESSING);
2560
2561         switch (_hutil_duplicate_object_entry(store_id, h_parent, h_obj,
2562                                 &new_handle)) {
2563         case MTP_ERROR_INVALID_OBJECTHANDLE:
2564                 resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
2565                 break;
2566         case MTP_ERROR_OBJECT_WRITE_PROTECTED:
2567                 resp = PTP_RESPONSE_OBJ_WRITEPROTECTED;
2568                 break;
2569         case MTP_ERROR_STORE_NOT_AVAILABLE:
2570                 resp = PTP_RESPONSE_STORENOTAVAILABLE;
2571                 break;
2572         case MTP_ERROR_STORE_READ_ONLY:
2573                 resp = PTP_RESPONSE_STORE_READONLY;
2574                 break;
2575         case MTP_ERROR_INVALID_PARENT:
2576                 resp = PTP_RESPONSE_INVALIDPARENT;
2577                 break;
2578         case MTP_ERROR_INVALID_PARAM:
2579                 resp = PTP_RESPONSE_INVALIDPARAM;
2580                 break;
2581         case MTP_ERROR_STORE_FULL:
2582                 resp = PTP_RESPONSE_STOREFULL;
2583                 break;
2584         case MTP_ERROR_NONE:
2585                 resp = PTP_RESPONSE_OK;
2586                 break;
2587         case MTP_ERROR_ACCESS_DENIED:
2588                 resp = PTP_RESPONSE_ACCESSDENIED;
2589                 break;
2590         default:
2591                 resp = PTP_RESPONSE_GEN_ERROR;
2592         }
2593         _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
2594
2595         if (resp == PTP_RESPONSE_OK)
2596                 _cmd_hdlr_send_response(hdlr, resp, 1, &new_handle);
2597         else
2598                 _cmd_hdlr_send_response_code(hdlr, resp);
2599
2600         return;
2601 }
2602
2603 static void __reset_device_prop_value(mtp_handler_t *hdlr)
2604 {
2605         mtp_uint32 prop_id = 0;
2606         device_prop_desc_t *prop = NULL;
2607         mtp_char temp[MTP_MAX_REG_STRING * 3 + 1] = { 0 };
2608
2609         prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
2610
2611         if (MTP_ERROR_NONE != _hutil_reset_device_entry(prop_id)) {
2612                 _cmd_hdlr_send_response_code(hdlr,
2613                                 PTP_RESPONSE_PROP_NOTSUPPORTED);
2614                 return;
2615         }
2616
2617         if (MTP_PROPERTYCODE_DEVICEFRIENDLYNAME == prop_id) {
2618                 prop = _device_get_device_property(prop_id);
2619                 if (prop == NULL) {
2620                         _cmd_hdlr_send_response_code(hdlr,
2621                                         PTP_RESPONSE_PROP_NOTSUPPORTED);
2622                         return;
2623                 }
2624
2625                 _util_utf16_to_utf8(temp, sizeof(temp),
2626                                 prop->current_val.str->str);
2627                 _device_set_device_name(temp);
2628
2629         } else if (MTP_PROPERTYCODE_SYNCHRONIZATIONPARTNER == prop_id) {
2630                 prop = _device_get_device_property(prop_id);
2631                 if (NULL == prop) {
2632                         _cmd_hdlr_send_response_code(hdlr,
2633                                         PTP_RESPONSE_PROP_NOTSUPPORTED);
2634                         return;
2635                 }
2636
2637                 _util_utf16_to_utf8(temp, sizeof(temp),
2638                                 prop->current_val.str->str);
2639                 _device_set_sync_partner(temp);
2640
2641                 if (!g_strcmp0(temp, MTP_DEV_PROPERTY_NULL_SYNCPARTNER))
2642                         vconf_set_str(VCONFKEY_MTP_SYNC_PARTNER_STR, "");
2643                 else
2644                         vconf_set_str(VCONFKEY_MTP_SYNC_PARTNER_STR, temp);
2645         }
2646         _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
2647
2648         return;
2649 }
2650
2651 /* Vendor-specific operations */
2652 #define GET_DEVICEPC_NAME       1
2653 static void __vendor_command1(mtp_handler_t *hdlr)
2654 {
2655         switch (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0)) {
2656         case GET_DEVICEPC_NAME:
2657                 break;
2658         default:
2659                 break;
2660         }
2661         /* Vendor command not properly handled*/
2662         _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
2663         return;
2664 }
2665
2666 static void __get_interdep_prop_desc(mtp_handler_t *hdlr)
2667 {
2668         mtp_uint32 fmt = 0;
2669         data_blk_t blk = { 0 };
2670         mtp_uint32 num_bytes = 0;
2671         mtp_uchar *ptr = NULL;
2672
2673         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
2674                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
2675                 _cmd_hdlr_send_response_code(hdlr,
2676                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
2677                 return;
2678         }
2679
2680         fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
2681         if (0x0 == fmt || 0xFFFFFFFF == fmt) {
2682                 ERR("Invalid format code");
2683                 _cmd_hdlr_send_response_code(hdlr,
2684                                 PTP_RESPONSE_INVALIDCODEFORMAT);
2685                 return;
2686         }
2687
2688         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
2689         _hutil_get_interdep_prop_config_list_size(&num_bytes, fmt);
2690         ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
2691
2692         if (MTP_ERROR_NONE != _hutil_get_interdep_prop_config_list_data(ptr,
2693                                 num_bytes, fmt)) {
2694                 ERR("_hutil_get_interdep_prop_config_list_data() Fail");
2695                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
2696                 g_free(blk.data);
2697                 return;
2698         }
2699
2700         _device_set_phase(DEVICE_PHASE_DATAIN);
2701         if (_hdlr_send_data_container(&blk)) {
2702                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
2703         } else {
2704                 /*Host Cancelled data-in transfer*/
2705                 _device_set_phase(DEVICE_PHASE_NOTREADY);
2706         }
2707
2708         g_free(blk.data);
2709         return;
2710 }
2711
2712 /*
2713  * void __cmd_hdlr_send_object_prop_list(mtp_handler_t *hdlr)
2714  * This function is used as an alternative first operation when the initiator
2715  * wants to send an object to the responder. This operation sends a
2716  * modified ObjectPropList dataset from the initiator to the Responder.
2717  *@param[in]            hdlr
2718  *@return               none
2719  */
2720 static void __send_object_prop_list(mtp_handler_t *hdlr)
2721 {
2722         mtp_uint32 idx = 0;
2723         mtp_uint16 resp = PTP_RESPONSE_OK;
2724         mtp_uint32 resp_param[MAX_MTP_PARAMS] = { 0 };
2725         mtp_obj_t *obj = NULL;
2726         mtp_uint16 fmt = 0;
2727         mtp_uint64 f_size = 0;
2728         mtp_uint64 fsize_hbits = 0;
2729         mtp_uint32 store_id;
2730         mtp_uint32 h_parent;
2731         data_blk_t blk = { 0 };
2732         mtp_uint32 max_bytes = 0;
2733         mtp_err_t ret = 0;
2734         obj_data_t objdata = { 0 };
2735
2736         store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
2737         h_parent = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
2738         fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
2739         fsize_hbits = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 3);
2740
2741         f_size = (fsize_hbits << 32) + _hdlr_get_param_cmd_container
2742                 (&(hdlr->usb_cmd), 4);
2743
2744         _device_set_phase(DEVICE_PHASE_DATAOUT);
2745         _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
2746
2747         max_bytes = MTP_MAX_METADATA;
2748         if (FALSE == _hdlr_rcv_data_container(&blk, max_bytes)) {
2749                 _device_set_phase(DEVICE_PHASE_IDLE);
2750                 ERR("_hdlr_rcv_data_container() Fail");
2751                 resp = PTP_RESPONSE_GEN_ERROR;
2752         }
2753
2754         idx = 0;
2755         if (store_id) {
2756                 if (!h_parent)
2757                         h_parent = _device_get_default_parent_handle();
2758                 else if (h_parent == 0xFFFFFFFF)
2759                         h_parent = PTP_OBJECTHANDLE_ROOT;
2760         } else {
2761                 store_id = _device_get_default_store_id();
2762                 if (!store_id)
2763                         resp = PTP_RESPONSE_STORENOTAVAILABLE;
2764                 if (h_parent)
2765                         /* If the second parameter is used, the first must
2766                          * also be used
2767                          * */
2768                         resp = PTP_RESPONSE_PARAM_NOTSUPPORTED;
2769                 else
2770                         h_parent = _device_get_default_parent_handle();
2771         }
2772
2773         if (f_size >= MTP_FILESIZE_4GB) {
2774
2775                 mtp_store_t *store = NULL;
2776                 struct statfs buf = { 0 };
2777                 mtp_int32 ret = 0;
2778
2779                 store = _device_get_store(store_id);
2780                 if (store == NULL) {
2781                         ERR("Store Not Available");
2782                         resp = PTP_RESPONSE_STORENOTAVAILABLE;
2783                 } else {
2784                         DBG("StorePath = [%s]\n", store->root_path);
2785                         ret = statfs(store->root_path, &buf);
2786                         if (ret < 0 || buf.f_type == MSDOS_SUPER_MAGIC) {
2787                                 ERR("File System does not support files over 4gb");
2788                                 resp = MTP_RESPONSE_OBJECT_TOO_LARGE;
2789                         }
2790                 }
2791         }
2792
2793         if (PTP_RESPONSE_OK == resp) {
2794
2795                 mtp_uchar *data = NULL;
2796
2797                 if (TRUE == hdlr->data4_send_obj.is_valid) {
2798
2799                         objdata.store_id = hdlr->data4_send_obj.store_id;
2800                         objdata.obj_size = hdlr->data4_send_obj.file_size;
2801                         objdata.obj = hdlr->data4_send_obj.obj;
2802                         hdlr->data4_send_obj.obj = NULL;
2803                 }
2804
2805                 data = _hdlr_get_payload_data(&blk);
2806                 if (data == NULL) {
2807                         g_free(blk.data);
2808                         return;
2809                 }
2810
2811                 ret = _hutil_construct_object_entry_prop_list(store_id, h_parent,
2812                                 fmt, f_size, ((hdlr->data4_send_obj.is_valid == TRUE) ?
2813                                         (&objdata) : (NULL)), &obj, data,
2814                                 _hdlr_get_payload_size(&blk), &idx);
2815                 hdlr->data4_send_obj.is_valid = FALSE;
2816
2817                 switch (ret) {
2818                 case MTP_ERROR_INVALID_STORE:
2819                         resp = PTP_RESPONSE_INVALID_STORE_ID;
2820                         break;
2821                 case MTP_ERROR_STORE_READ_ONLY:
2822                         resp = PTP_RESPONSE_STORE_READONLY;
2823                         break;
2824                 case MTP_ERROR_STORE_FULL:
2825                         resp = PTP_RESPONSE_STOREFULL;
2826                         break;
2827                 case MTP_ERROR_GENERAL:
2828                         resp = PTP_RESPONSE_GEN_ERROR;
2829                         break;
2830                 case MTP_ERROR_INVALID_DATASET:
2831                         resp = MTP_RESPONSECODE_INVALIDDATASET;
2832                         break;
2833                 case MTP_ERROR_INVALID_OBJECTHANDLE:
2834                         resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
2835                         break;
2836                 case MTP_ERROR_INVALID_OBJ_PROP_CODE:
2837                         resp = MTP_RESPONSE_INVALIDOBJPROPCODE;
2838                         break;
2839                 case MTP_ERROR_INVALID_OBJECT_PROP_FORMAT:
2840                         resp = MTP_RESPONSE_INVALIDOBJPROPFORMAT;
2841                         break;
2842                 case MTP_ERROR_INVALID_OBJ_PROP_VALUE:
2843                         resp = MTP_RESPONSE_INVALIDOBJPROPVALUE;
2844                         break;
2845                 case MTP_ERROR_INVALID_PARENT:
2846                         resp = PTP_RESPONSE_INVALIDPARENT;
2847                         break;
2848                 case MTP_ERROR_ACCESS_DENIED:
2849                         resp = PTP_RESPONSE_ACCESSDENIED;
2850                         break;
2851                 case MTP_ERROR_NONE:
2852 #ifdef MTP_USE_SELFMAKE_ABSTRACTION
2853                         if ((obj->obj_info->obj_fmt == PTP_FMT_ASSOCIATION) ||
2854                                         (obj->obj_info->file_size == 0 &&
2855                                          obj->obj_info->obj_fmt >
2856                                          MTP_FMT_UNDEFINED_COLLECTION &&
2857                                          obj->obj_info->obj_fmt <
2858                                          MTP_FMT_UNDEFINED_DOC))
2859 #else /*MTP_USE_SELFMAKE_ABSTRACTION*/
2860                                 if (obj->obj_info->obj_fmt == PTP_FMT_ASSOCIATION)
2861 #endif /*MTP_USE_SELFMAKE_ABSTRACTION*/
2862                                 {
2863                                         hdlr->data4_send_obj.obj = NULL;
2864                                         hdlr->data4_send_obj.is_valid = FALSE;
2865                                         hdlr->data4_send_obj.obj_handle = obj->obj_handle;
2866                                         hdlr->data4_send_obj.h_parent = h_parent;
2867                                         hdlr->data4_send_obj.store_id = store_id;
2868                                         hdlr->data4_send_obj.file_size = 0;
2869                                 } else {
2870                                         hdlr->data4_send_obj.is_valid = TRUE;
2871                                         hdlr->data4_send_obj.obj_handle = obj->obj_handle;
2872                                         hdlr->data4_send_obj.h_parent = h_parent;
2873                                         hdlr->data4_send_obj.store_id = store_id;
2874                                         hdlr->data4_send_obj.obj = obj;
2875                                         hdlr->data4_send_obj.file_size =
2876                                                 obj->obj_info->file_size;
2877                                 }
2878                         resp = PTP_RESPONSE_OK;
2879                         break;
2880                 default:
2881                         resp = PTP_RESPONSE_GEN_ERROR;
2882                 }
2883         }
2884
2885         if (PTP_RESPONSE_OK != resp) {
2886                 if (hdlr->data4_send_obj.obj)
2887                         _entity_dealloc_mtp_obj(hdlr->data4_send_obj.obj);
2888
2889                 hdlr->data4_send_obj.obj = NULL;
2890                 hdlr->data4_send_obj.is_valid = FALSE;
2891                 resp_param[3] = idx;
2892         } else {
2893                 resp_param[0] = hdlr->data4_send_obj.store_id;
2894
2895                 /* PTP spec here requires that 0xFFFFFFFF be sent if root is the parent,
2896                  * while in some situations (e.g. Move Object, Copy Object), 0x00000000
2897                  *(as PTP_OBJECTHANDLE_ROOT is defined) represents the root
2898                  */
2899                 resp_param[1] = (hdlr->data4_send_obj.h_parent !=
2900                                 PTP_OBJECTHANDLE_ROOT) ? hdlr->data4_send_obj.h_parent
2901                         : 0xFFFFFFFF;
2902                 resp_param[2] = hdlr->data4_send_obj.obj_handle;
2903                 resp_param[3] = 0;
2904         }
2905
2906         _cmd_hdlr_send_response(hdlr, resp, 4, resp_param);
2907
2908         g_free(blk.data);
2909         return;
2910 }
2911 #endif /*PMP_VER*/
2912
2913 void __close_session(mtp_handler_t *hdlr)
2914 {
2915         if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0) ||
2916                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
2917                         _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
2918
2919                 ERR("PTP_RESPONSE_PARAM_NOTSUPPORTED");
2920                 _cmd_hdlr_send_response_code(hdlr,
2921                                 PTP_RESPONSE_PARAM_NOTSUPPORTED);
2922
2923                 return;
2924         }
2925
2926         if (hdlr->session_id) {
2927                 hdlr->session_id = 0;
2928                 _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
2929         } else {
2930                 _cmd_hdlr_send_response_code(hdlr,
2931                                 PTP_RESPONSE_SESSIONNOTOPEN);
2932                 ERR("PTP_RESPONSE_SESSIONNOTOPEN");
2933         }
2934         return;
2935 }
2936
2937 mtp_bool _cmd_hdlr_send_response(mtp_handler_t *hdlr, mtp_uint16 resp,
2938                 mtp_uint32 num_param, mtp_uint32 *params)
2939 {
2940         mtp_bool ret = FALSE;
2941         resp_blk_t blk = { 0 };
2942
2943         _hdlr_resp_container_init(&blk, resp, hdlr->usb_cmd.tid);
2944
2945         ret = _hdlr_add_param_resp_container(&blk, num_param, params);
2946
2947         _device_set_phase(DEVICE_PHASE_RESPONSE);
2948         ret = _hdlr_send_resp_container(&blk);
2949         _device_set_phase(DEVICE_PHASE_IDLE);
2950
2951         if ((resp == PTP_RESPONSE_OK) && (ret == TRUE)) {
2952                 DBG("[%s], Opcode[0x%4x], ResponseCode[0x%4x], NumParams[%d]\n",
2953                                 "SUCCESS", hdlr->usb_cmd.code, resp, num_param);
2954         } else {
2955                 ERR("[%s], Opcode = [0x%4x] ResponseCode[0x%4x], NumParams[%u]\n",
2956                                 "FAIL", hdlr->usb_cmd.code, resp, num_param);
2957         }
2958         return ret;
2959 }
2960
2961 mtp_bool _cmd_hdlr_send_response_code(mtp_handler_t *hdlr, mtp_uint16 resp)
2962 {
2963         return _cmd_hdlr_send_response(hdlr, resp, 0, NULL);
2964 }
2965
2966 #ifdef MTP_SUPPORT_PRINT_COMMAND
2967 static void __print_command(mtp_uint16 code)
2968 {
2969         switch (code) {
2970         case PTP_OPCODE_GETDEVICEINFO:
2971                 DBG("COMMAND ======== GET DEVICE INFO===========");
2972                 break;
2973         case PTP_OPCODE_OPENSESSION:
2974                 DBG("COMMAND ======== OPEN SESSION ===========");
2975                 break;
2976         case PTP_OPCODE_CLOSESESSION:
2977                 DBG("COMMAND ======== CLOSE SESSION ===========");
2978                 break;
2979         case PTP_OPCODE_GETSTORAGEIDS:
2980                 DBG("COMMAND ======== GET STORAGE IDS ===========");
2981                 break;
2982         case PTP_OPCODE_GETSTORAGEINFO:
2983                 DBG("COMMAND ======== GET STORAGE INFO ===========");
2984                 break;
2985         case PTP_OPCODE_GETNUMOBJECTS:
2986                 DBG("COMMAND ======== GET NUM OBJECTS ===========");
2987                 break;
2988         case PTP_OPCODE_GETOBJECTHANDLES:
2989                 DBG("COMMAND ======== GET OBJECT HANDLES ===========");
2990                 break;
2991         case PTP_OPCODE_GETOBJECTINFO:
2992                 DBG("COMMAND ======== GET OBJECT INFO ===========");
2993                 break;
2994         case PTP_OPCODE_GETOBJECT:
2995                 DBG("COMMAND ======== GET OBJECT ===========");
2996                 break;
2997         case PTP_OPCODE_DELETEOBJECT:
2998                 DBG("COMMAND ======== DELETE OBJECT ===========");
2999                 break;
3000         case PTP_OPCODE_SENDOBJECTINFO:
3001                 DBG("COMMAND ======== SEND OBJECT INFO ===========");
3002                 break;
3003         case PTP_OPCODE_SENDOBJECT:
3004                 DBG("COMMAND ======== SEND OBJECT ===========");
3005                 break;
3006         case PTP_OPCODE_INITIATECAPTURE:
3007                 DBG("COMMAND ======== INITIATE CAPTURE ===========");
3008                 break;
3009         case PTP_OPCODE_FORMATSTORE:
3010                 DBG("COMMAND ======== FORMAT STORE ===========");
3011                 break;
3012         case PTP_OPCODE_RESETDEVICE:
3013                 DBG("COMMAND ======== RESET DEVICE ===========");
3014                 break;
3015         case PTP_OPCODE_SELFTEST:
3016                 DBG("COMMAND ======== SELF TEST ===========");
3017                 break;
3018         case PTP_OPCODE_SETOBJECTPROTECTION:
3019                 DBG("COMMAND ======== SET OBJECT PROTECTION ===========");
3020                 break;
3021         case PTP_OPCODE_POWERDOWN:
3022                 DBG("COMMAND ======== POWER DOWN ===========");
3023                 break;
3024         case PTP_OPCODE_GETDEVICEPROPDESC:
3025                 DBG("COMMAND ======== GET DEVICE PROP DESC ===========");
3026                 break;
3027         case PTP_OPCODE_GETDEVICEPROPVALUE:
3028                 DBG("COMMAND ======== GET DEVICE PROP VALUE ===========");
3029                 break;
3030         case PTP_OPCODE_SETDEVICEPROPVALUE:
3031                 DBG("COMMAND ======== SET DEVICE PROP VALUE ===========");
3032                 break;
3033         case PTP_OPCODE_RESETDEVICEPROPVALUE:
3034                 DBG("COMMAND ======== RESET DEVICE PROP VALUE ===========");
3035                 break;
3036         case PTP_OPCODE_TERMINATECAPTURE:
3037                 DBG("COMMAND ======== TERMINATE CAPTURE ===========");
3038                 break;
3039         case PTP_OPCODE_MOVEOBJECT:
3040                 DBG("COMMAND ======== MOVE OBJECT ===========");
3041                 break;
3042         case PTP_OPCODE_COPYOBJECT:
3043                 DBG("COMMAND ======== COPY OBJECT ===========");
3044                 break;
3045         case PTP_OPCODE_GETPARTIALOBJECT:
3046                 DBG("COMMAND ======== GET PARTIAL OBJECT ===========");
3047                 break;
3048         case PTP_OPCODE_INITIATEOPENCAPTURE:
3049                 DBG("COMMAND ======== INITIATE OPEN CAPTURE ===========");
3050                 break;
3051         case MTP_OPCODE_WMP_UNDEFINED:
3052                 DBG("COMMAND ======== WMP UNDEFINED ==========");
3053                 break;
3054         case MTP_OPCODE_WMP_REPORTACQUIREDCONTENT:
3055                 DBG("COMMAND ======= REPORT ACQUIRED CONTENT =========");
3056                 break;
3057         case MTP_OPCODE_GETOBJECTPROPSUPPORTED:
3058                 DBG("COMMAND ======= GET OBJECT PROP SUPPORTED ========");
3059                 break;
3060         case MTP_OPCODE_GETOBJECTPROPDESC:
3061                 DBG("COMMAND ======== GET OBJECT PROP DESC ==========");
3062                 break;
3063         case MTP_OPCODE_GETOBJECTPROPVALUE:
3064                 DBG("COMMAND ======== GET OBJECT PROP VALUE ==========");
3065                 break;
3066         case MTP_OPCODE_SETOBJECTPROPVALUE:
3067                 DBG("COMMAND ======== SET OBJECT PROP VALUE ==========");
3068                 break;
3069         case MTP_OPCODE_GETOBJECTPROPLIST:
3070                 DBG("COMMAND ======== GET OBJECT PROP LIST ==========");
3071                 break;
3072         case MTP_OPCODE_SETOBJECTPROPLIST:
3073                 DBG("COMMAND ======== SET OBJECT PROP LIST ==========");
3074                 break;
3075         case MTP_OPCODE_GETINTERDEPPROPDESC:
3076                 DBG("COMMAND ======== GET INTERDEP PROP DESC ==========");
3077                 break;
3078         case MTP_OPCODE_SENDOBJECTPROPLIST:
3079                 DBG("COMMAND ======== SEND OBJECT PROP LIST ==========");
3080                 break;
3081         case MTP_OPCODE_GETOBJECTREFERENCES:
3082                 DBG("COMMAND ======== GET OBJECT REFERENCES ==========");
3083                 break;
3084         case MTP_OPCODE_SETOBJECTREFERENCES:
3085                 DBG("COMMAND ======== SET OBJECT REFERENCES ==========");
3086                 break;
3087         case MTP_OPCODE_PLAYBACK_SKIP:
3088                 DBG("COMMAND ======== PLAYBACK SKIP ==========");
3089                 break;
3090         default:
3091                 DBG("======== UNKNOWN COMMAND ==========");
3092                 break;
3093         }
3094
3095         return;
3096 }
3097 #endif /*MTP_SUPPORT_PRINT_COMMAND*/
3098
3099 static void __enum_store_not_enumerated(mtp_uint32 obj_handle,
3100                 mtp_uint32 fmt, mtp_uint32 depth)
3101 {
3102         mtp_uint32 ii;
3103         mtp_store_t *store = NULL;
3104         mtp_obj_t *obj = NULL;
3105
3106         if (TRUE == g_is_full_enum) {
3107                 DBG("Full Enumeration has been already done");
3108                 return;
3109         }
3110
3111         DBG("obj_handle = [%u], format =[ %u], depth = [%u]\n", obj_handle,
3112                         fmt, depth);
3113         if (obj_handle == PTP_OBJECTHANDLE_ALL || obj_handle == PTP_OBJECTHANDLE_ROOT) {
3114                 for (ii = 0; ii < _device_get_num_stores(); ii++) {
3115                         store = _device_get_store_at_index(ii);
3116                         if (store && store->obj_list.nnodes == 0)
3117                                 _entity_store_recursive_enum_folder_objects(store, NULL);
3118                 }
3119                 g_is_full_enum = TRUE;
3120         } else if (obj_handle != PTP_OBJECTHANDLE_ROOT) {
3121                 store = _device_get_store_containing_obj(obj_handle);
3122                 obj = _entity_get_object_from_store(store, obj_handle);
3123                 if (obj == NULL) {
3124                         ERR("pObject is NULL");
3125                         return;
3126                 }
3127                 _entity_store_recursive_enum_folder_objects(store, obj);
3128         }
3129         return;
3130 }
3131
3132 void _receive_mq_data_cb(mtp_char *buffer, mtp_int32 buf_len)
3133 {
3134         cmd_blk_t cmd = { 0 };
3135         mtp_uint32 rx_size = _get_rx_pkt_size();
3136
3137         if (_transport_get_mtp_operation_state() < MTP_STATE_READY_SERVICE) {
3138                 ERR("MTP is stopped or initializing. ignore all");
3139                 return;
3140         }
3141
3142 #ifdef MTP_SUPPORT_CONTROL_REQUEST
3143         /* process control request */
3144         switch (_transport_get_control_event()) {
3145         case PTP_EVENTCODE_CANCELTRANSACTION:
3146                 DBG("PTP_EVENTCODE_CANCELTRANSACTION, just change state to IDLE");
3147                 _transport_set_control_event(PTP_EVENTCODE_CANCELTRANSACTION);
3148                 _device_set_phase(DEVICE_PHASE_IDLE);
3149                 if ((buf_len == rx_size) ||
3150                                 (buf_len < sizeof(header_container_t))) {
3151                         DBG("Cancelling Transaction. data length [%d]\n",
3152                                         buf_len);
3153                         _transport_set_control_event(PTP_EVENTCODE_CANCELTRANSACTION);
3154                         return;
3155                 }
3156
3157                 mtp_int32 i = 0;
3158                 cmd_container_t *tmp;
3159                 mtp_dword len = 0;
3160                 mtp_word type = 0;
3161                 mtp_word code = 0;
3162                 mtp_dword trid = 0;
3163
3164                 for (i = 0; i < MAX_MTP_PARAMS; i++) {  /* check size */
3165                         /* check number of parameter */
3166                         tmp = (cmd_container_t *)&buffer[buf_len -
3167                                 sizeof(header_container_t) -
3168                                 sizeof(mtp_dword) * i];
3169
3170                         len = tmp->len;
3171                         type = tmp->type;
3172
3173                         if ((len == sizeof(header_container_t)
3174                                                 + sizeof(mtp_dword) * i) &&
3175                                         (type == CONTAINER_CMD_BLK)) {
3176                                 DBG("Found Command in remaining data");
3177                                 memcpy(buffer, tmp, len);
3178                                 buf_len = len;
3179                                 break;
3180                         }
3181                         DBG("Not found command, length[%lu]\n", len);
3182                 }
3183
3184                 len = tmp->len;
3185                 type = tmp->type;
3186                 code = tmp->code;
3187                 trid = tmp->tid;
3188
3189                 DBG("len[%ld], type[0x%x], code [0x%x], trid[0x%x]\n",
3190                                 len, type, code, trid);
3191
3192                 if (_hdlr_validate_cmd_container((mtp_byte *)tmp, len)
3193                                 == FALSE) {
3194                         ERR("Cancelling Transaction, invalid header, but last packet");
3195                 } else {        /*another command, cancelling is finished*/
3196                         DBG("Cancelling Transaction, Finished.");
3197                 }
3198
3199                 _transport_set_control_event(0);
3200                 _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
3201                 if (g_mgr->ftemp_st.fhandle != NULL) {
3202                         DBG("In Cancel Transaction fclose ");
3203                         _util_file_close(g_mgr->ftemp_st.fhandle);
3204                         g_mgr->ftemp_st.fhandle = NULL;
3205                         DBG("In Cancel Transaction, remove ");
3206                         if (remove(g_mgr->ftemp_st.filepath) < 0)
3207                                 ERR_SECURE("remove(%s) Fail", g_mgr->ftemp_st.filepath);
3208                 } else {
3209                         DBG("g_mgr->ftemp_st.fhandle is not valid, return");
3210                 }
3211                 break;
3212
3213         case PTP_EVENTCODE_DEVICERESET:
3214                 DBG("Implement later, PTP_EVENTCODE_DEVICERESET");
3215                 _device_set_phase(DEVICE_PHASE_IDLE);
3216                 /* do close session, just skip save reference
3217                  * mtp_save_object_references_mtp_device(MtpHandler.pDevice);
3218                  */
3219                 g_mgr->hdlr.session_id = 0;
3220                 _transport_set_control_event(0);
3221                 _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
3222                 break;
3223
3224         default:
3225                 break;
3226         }
3227 #endif/* MTP_SUPPORT_CONTROL_REQUEST */
3228
3229         /* main processing */
3230         if (_device_get_phase() == DEVICE_PHASE_IDLE) {
3231                 if (_hdlr_validate_cmd_container((mtp_uchar *)buffer, buf_len)
3232                                 == FALSE) {
3233                         _device_set_phase(DEVICE_PHASE_NOTREADY);
3234                         ERR("MTP device phase NOT READY, invalid Command block");
3235                         return;
3236                 }
3237
3238                 _transport_save_cmd_buffer(buffer, buf_len);
3239                 _hdlr_copy_cmd_container_unknown_params((cmd_container_t *)buffer,
3240                                 &cmd);
3241 #ifdef __BIG_ENDIAN__
3242                 _hdlr_conv_cmd_container_byte_order(&cmd);
3243 #endif /* __BIG_ENDIAN__ */
3244
3245                 UTIL_LOCK_MUTEX(&g_cmd_inoti_mutex);
3246                 __process_commands(&g_mtp_mgr.hdlr, &cmd);
3247                 UTIL_UNLOCK_MUTEX(&g_cmd_inoti_mutex);
3248         } else if (_device_get_phase() == DEVICE_PHASE_DATAOUT) {
3249                 if (g_mgr->ftemp_st.data_count == 0)
3250                         __receive_temp_file_first_packet(buffer, buf_len);
3251                 else
3252                         __receive_temp_file_next_packets(buffer, buf_len);
3253                 return;
3254         } else {
3255                 /* ignore other case */
3256                 ERR("MTP device phase[%d], unknown device PHASE\n",
3257                                 _device_get_phase());
3258                 ERR("PhaseUnknown-> pData[0x%x], length=[%d]", buffer, buf_len);
3259                 _device_set_phase(DEVICE_PHASE_IDLE);
3260                 _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
3261         }
3262         return;
3263 }
3264
3265 static mtp_bool __receive_temp_file_first_packet(mtp_char *data,
3266                 mtp_int32 data_len)
3267 {
3268         mtp_char *filepath = g_mgr->ftemp_st.filepath;
3269         mtp_int32 error = 0;
3270         mtp_uint32 *data_sz = &g_mgr->ftemp_st.data_size;
3271         mtp_char *buffer = g_mgr->ftemp_st.temp_buff;
3272
3273         _transport_set_mtp_operation_state(MTP_STATE_DATA_TRANSFER_DL);
3274         if (access(filepath, F_OK) == 0) {
3275                 if (g_mgr->ftemp_st.fhandle != NULL) {
3276                         _util_file_close(g_mgr->ftemp_st.fhandle);
3277                         g_mgr->ftemp_st.fhandle = NULL; /* initialize */
3278                 }
3279
3280                 if (remove(filepath) < 0) {
3281                         ERR_SECURE("remove(%s) Fail", filepath);
3282                         __finish_receiving_file_packets(data, data_len);
3283                         return FALSE;
3284                 }
3285         }
3286
3287         g_mgr->ftemp_st.fhandle = _util_file_open(filepath, MTP_FILE_WRITE, &error);
3288         if (g_mgr->ftemp_st.fhandle == NULL) {
3289                 ERR("First file handle is invalid!!");
3290                 __finish_receiving_file_packets(data, data_len);
3291                 return FALSE;
3292         }
3293         /* consider header size */
3294         memcpy(&g_mgr->ftemp_st.header_buf, data, sizeof(header_container_t));
3295
3296         g_mgr->ftemp_st.file_size = ((header_container_t *)data)->len -
3297                 sizeof(header_container_t);
3298         *data_sz = data_len - sizeof(header_container_t);
3299
3300         /* check whether last data packet */
3301         if (*data_sz == g_mgr->ftemp_st.file_size) {
3302                 if (_util_file_write(g_mgr->ftemp_st.fhandle, &data[sizeof(header_container_t)],
3303                                         data_len - sizeof(header_container_t)) !=
3304                                 data_len - sizeof(header_container_t)) {
3305                         ERR("fwrite error!");
3306                 }
3307                 *data_sz = 0;
3308                 _util_file_close(g_mgr->ftemp_st.fhandle);
3309                 g_mgr->ftemp_st.fhandle = NULL; /* initialize */
3310                 __finish_receiving_file_packets(data, data_len);
3311         } else {
3312                 g_mgr->ftemp_st.data_count++;
3313                 g_mgr->ftemp_st.size_remaining = *data_sz;
3314
3315                 memcpy(buffer, data + sizeof(header_container_t), *data_sz);
3316         }
3317         return TRUE;
3318 }
3319
3320 static mtp_bool __receive_temp_file_next_packets(mtp_char *data,
3321                 mtp_int32 data_len)
3322 {
3323         mtp_uint32 rx_size = _get_rx_pkt_size();
3324         mtp_uint32 *data_sz = &g_mgr->ftemp_st.data_size;
3325         mtp_char *buffer = g_mgr->ftemp_st.temp_buff;
3326
3327         g_mgr->ftemp_st.data_count++;
3328         g_mgr->ftemp_st.size_remaining += data_len;
3329
3330         if ((*data_sz + (mtp_uint32)data_len) > g_conf.write_file_size) {
3331                 /* copy oversized packet to temp file */
3332                 if (_util_file_write(g_mgr->ftemp_st.fhandle, buffer, *data_sz) != *data_sz)
3333                         ERR("fwrite error writeSize=[%u]\n", *data_sz);
3334
3335                 *data_sz = 0;
3336         }
3337
3338         memcpy(&buffer[*data_sz], data, data_len);
3339         *data_sz += data_len;
3340
3341         /*Complete file is recieved, so close the file*/
3342         if (data_len < rx_size ||
3343                         g_mgr->ftemp_st.size_remaining == g_mgr->ftemp_st.file_size) {
3344
3345                 if (_util_file_write(g_mgr->ftemp_st.fhandle, buffer, *data_sz) != *data_sz)
3346                         ERR("fwrite error write size=[%u]\n", *data_sz);
3347
3348                 *data_sz = 0;
3349                 _util_file_close(g_mgr->ftemp_st.fhandle);
3350                 g_mgr->ftemp_st.fhandle = NULL;
3351                 __finish_receiving_file_packets(data, data_len);
3352         }
3353         return TRUE;
3354 }
3355
3356 static void __finish_receiving_file_packets(mtp_char *data, mtp_int32 data_len)
3357 {
3358         cmd_blk_t cmd = { 0 };
3359         mtp_uchar *cmd_buf = NULL;
3360
3361         g_mgr->ftemp_st.data_count = 0;
3362         cmd_buf = (mtp_uchar *)data;
3363
3364         if (!_hdlr_validate_cmd_container(cmd_buf, (mtp_uint32)data_len)) {
3365                 cmd_buf = (mtp_uchar *)g_mgr->ftemp_st.cmd_buf;
3366                 if (!_hdlr_validate_cmd_container(cmd_buf,
3367                                         g_mgr->ftemp_st.cmd_size)) {
3368                         _device_set_phase(DEVICE_PHASE_IDLE);
3369                         ERR("DATA PROCESS, device phase[%d], invalid Command\
3370                                         block\n", _device_get_phase());
3371                         return;
3372                 }
3373         }
3374
3375         _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
3376         _hdlr_copy_cmd_container_unknown_params((cmd_container_t *)cmd_buf,
3377                         &cmd);
3378
3379 #ifdef __BIG_ENDIAN__
3380         _hdlr_conv_cmd_container_byte_order(&cmd);
3381 #endif /* __BIG_ENDIAN__ */
3382
3383         UTIL_LOCK_MUTEX(&g_cmd_inoti_mutex);
3384         __process_commands(&g_mtp_mgr.hdlr, &cmd);
3385         UTIL_UNLOCK_MUTEX(&g_cmd_inoti_mutex);
3386
3387         DBG("MTP device phase[%d], processing Command is complete\n",
3388                         _device_get_phase());
3389
3390         return;
3391 }