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