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