blob: 8ad39dc83be79ca209faea87caa86daad891c59d [file] [log] [blame]
Mike Lockwood755fd612010-05-25 19:08:48 -04001/*
2 * Copyright (C) 2010 The Android Open Source Project
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
Mike Lockwood90f48732010-06-05 22:45:01 -040017#define LOG_TAG "MtpDevice"
Mike Lockwood3e6616d2010-06-29 18:11:52 -040018
19#include "MtpDebug.h"
20#include "MtpDevice.h"
21#include "MtpDeviceInfo.h"
22#include "MtpObjectInfo.h"
23#include "MtpProperty.h"
24#include "MtpStorageInfo.h"
25#include "MtpStringBuffer.h"
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -040026#include "MtpUtils.h"
Mike Lockwood90f48732010-06-05 22:45:01 -040027
Mike Lockwood755fd612010-05-25 19:08:48 -040028#include <stdio.h>
29#include <stdlib.h>
30#include <sys/types.h>
31#include <sys/ioctl.h>
32#include <sys/stat.h>
33#include <fcntl.h>
34#include <errno.h>
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -040035#include <endian.h>
Mike Lockwood755fd612010-05-25 19:08:48 -040036
37#include <usbhost/usbhost.h>
38
Mike Lockwood755fd612010-05-25 19:08:48 -040039namespace android {
40
41MtpDevice::MtpDevice(struct usb_device* device, int interface,
42 struct usb_endpoint *ep_in, struct usb_endpoint *ep_out,
43 struct usb_endpoint *ep_intr)
44 : mDevice(device),
45 mInterface(interface),
46 mEndpointIn(ep_in),
47 mEndpointOut(ep_out),
48 mEndpointIntr(ep_intr),
49 mDeviceInfo(NULL),
50 mID(usb_device_get_unique_id(device)),
51 mSessionID(0),
52 mTransactionID(0)
53{
54}
55
56MtpDevice::~MtpDevice() {
57 close();
Mike Lockwood90f48732010-06-05 22:45:01 -040058 for (int i = 0; i < mDeviceProperties.size(); i++)
59 delete mDeviceProperties[i];
Mike Lockwood755fd612010-05-25 19:08:48 -040060}
61
62void MtpDevice::initialize() {
63 openSession();
64 mDeviceInfo = getDeviceInfo();
65 if (mDeviceInfo) {
Mike Lockwood90f48732010-06-05 22:45:01 -040066 if (mDeviceInfo->mDeviceProperties) {
67 int count = mDeviceInfo->mDeviceProperties->size();
68 for (int i = 0; i < count; i++) {
69 MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i];
70 MtpProperty* property = getDevicePropDesc(propCode);
Mike Lockwoode4880e42010-12-07 11:24:28 -080071 if (property)
Mike Lockwood90f48732010-06-05 22:45:01 -040072 mDeviceProperties.push(property);
Mike Lockwood90f48732010-06-05 22:45:01 -040073 }
74 }
Mike Lockwood755fd612010-05-25 19:08:48 -040075 }
76}
77
78void MtpDevice::close() {
79 if (mDevice) {
80 usb_device_release_interface(mDevice, mInterface);
81 usb_device_close(mDevice);
82 mDevice = NULL;
83 }
84}
85
Mike Lockwoode4880e42010-12-07 11:24:28 -080086void MtpDevice::print() {
87 if (mDeviceInfo) {
88 mDeviceInfo->print();
89
90 if (mDeviceInfo->mDeviceProperties) {
91 LOGI("***** DEVICE PROPERTIES *****\n");
92 int count = mDeviceInfo->mDeviceProperties->size();
93 for (int i = 0; i < count; i++) {
94 MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i];
95 MtpProperty* property = getDevicePropDesc(propCode);
96 if (property) {
97 property->print();
98 }
99 }
100 }
101 }
102
103 if (mDeviceInfo->mPlaybackFormats) {
104 LOGI("***** OBJECT PROPERTIES *****\n");
105 int count = mDeviceInfo->mPlaybackFormats->size();
106 for (int i = 0; i < count; i++) {
107 MtpObjectFormat format = (*mDeviceInfo->mPlaybackFormats)[i];
108 LOGI("*** FORMAT: %s\n", MtpDebug::getFormatCodeName(format));
109 MtpObjectPropertyList* props = getObjectPropsSupported(format);
110 if (props) {
111 for (int j = 0; j < props->size(); j++) {
112 MtpObjectProperty prop = (*props)[j];
Mike Lockwooda194cc72010-12-07 18:53:04 -0800113 MtpProperty* property = getObjectPropDesc(prop, format);
Mike Lockwoode4880e42010-12-07 11:24:28 -0800114 if (property)
115 property->print();
116 else
117 LOGE("could not fetch property: %s",
118 MtpDebug::getObjectPropCodeName(prop));
119 }
120 }
121 }
122 }
123}
124
Mike Lockwood755fd612010-05-25 19:08:48 -0400125const char* MtpDevice::getDeviceName() {
126 if (mDevice)
127 return usb_device_get_name(mDevice);
128 else
129 return "???";
130}
131
132bool MtpDevice::openSession() {
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400133 Mutex::Autolock autoLock(mMutex);
134
Mike Lockwood755fd612010-05-25 19:08:48 -0400135 mSessionID = 0;
136 mTransactionID = 0;
137 MtpSessionID newSession = 1;
138 mRequest.reset();
139 mRequest.setParameter(1, newSession);
140 if (!sendRequest(MTP_OPERATION_OPEN_SESSION))
141 return false;
142 MtpResponseCode ret = readResponse();
143 if (ret == MTP_RESPONSE_SESSION_ALREADY_OPEN)
144 newSession = mResponse.getParameter(1);
145 else if (ret != MTP_RESPONSE_OK)
146 return false;
147
148 mSessionID = newSession;
149 mTransactionID = 1;
150 return true;
151}
152
153bool MtpDevice::closeSession() {
154 // FIXME
155 return true;
156}
157
158MtpDeviceInfo* MtpDevice::getDeviceInfo() {
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400159 Mutex::Autolock autoLock(mMutex);
160
Mike Lockwood755fd612010-05-25 19:08:48 -0400161 mRequest.reset();
162 if (!sendRequest(MTP_OPERATION_GET_DEVICE_INFO))
163 return NULL;
164 if (!readData())
165 return NULL;
166 MtpResponseCode ret = readResponse();
Mike Lockwood755fd612010-05-25 19:08:48 -0400167 if (ret == MTP_RESPONSE_OK) {
168 MtpDeviceInfo* info = new MtpDeviceInfo;
169 info->read(mData);
170 return info;
171 }
172 return NULL;
173}
174
175MtpStorageIDList* MtpDevice::getStorageIDs() {
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400176 Mutex::Autolock autoLock(mMutex);
177
Mike Lockwood755fd612010-05-25 19:08:48 -0400178 mRequest.reset();
179 if (!sendRequest(MTP_OPERATION_GET_STORAGE_IDS))
180 return NULL;
181 if (!readData())
182 return NULL;
183 MtpResponseCode ret = readResponse();
184 if (ret == MTP_RESPONSE_OK) {
185 return mData.getAUInt32();
186 }
187 return NULL;
188}
189
190MtpStorageInfo* MtpDevice::getStorageInfo(MtpStorageID storageID) {
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400191 Mutex::Autolock autoLock(mMutex);
192
Mike Lockwood755fd612010-05-25 19:08:48 -0400193 mRequest.reset();
194 mRequest.setParameter(1, storageID);
195 if (!sendRequest(MTP_OPERATION_GET_STORAGE_INFO))
196 return NULL;
197 if (!readData())
198 return NULL;
199 MtpResponseCode ret = readResponse();
Mike Lockwood755fd612010-05-25 19:08:48 -0400200 if (ret == MTP_RESPONSE_OK) {
201 MtpStorageInfo* info = new MtpStorageInfo(storageID);
202 info->read(mData);
203 return info;
204 }
205 return NULL;
206}
207
208MtpObjectHandleList* MtpDevice::getObjectHandles(MtpStorageID storageID,
209 MtpObjectFormat format, MtpObjectHandle parent) {
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400210 Mutex::Autolock autoLock(mMutex);
211
Mike Lockwood755fd612010-05-25 19:08:48 -0400212 mRequest.reset();
213 mRequest.setParameter(1, storageID);
214 mRequest.setParameter(2, format);
215 mRequest.setParameter(3, parent);
216 if (!sendRequest(MTP_OPERATION_GET_OBJECT_HANDLES))
217 return NULL;
218 if (!readData())
219 return NULL;
220 MtpResponseCode ret = readResponse();
Mike Lockwood755fd612010-05-25 19:08:48 -0400221 if (ret == MTP_RESPONSE_OK) {
222 return mData.getAUInt32();
223 }
224 return NULL;
225}
226
227MtpObjectInfo* MtpDevice::getObjectInfo(MtpObjectHandle handle) {
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400228 Mutex::Autolock autoLock(mMutex);
229
Mike Lockwoode0a89f62010-06-11 16:34:52 -0400230 // FIXME - we might want to add some caching here
231
Mike Lockwood755fd612010-05-25 19:08:48 -0400232 mRequest.reset();
233 mRequest.setParameter(1, handle);
234 if (!sendRequest(MTP_OPERATION_GET_OBJECT_INFO))
235 return NULL;
236 if (!readData())
237 return NULL;
238 MtpResponseCode ret = readResponse();
Mike Lockwood755fd612010-05-25 19:08:48 -0400239 if (ret == MTP_RESPONSE_OK) {
240 MtpObjectInfo* info = new MtpObjectInfo(handle);
241 info->read(mData);
242 return info;
243 }
244 return NULL;
245}
246
Mike Lockwooddda56862010-06-10 16:34:20 -0400247void* MtpDevice::getThumbnail(MtpObjectHandle handle, int& outLength) {
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400248 Mutex::Autolock autoLock(mMutex);
249
Mike Lockwooddda56862010-06-10 16:34:20 -0400250 mRequest.reset();
251 mRequest.setParameter(1, handle);
252 if (sendRequest(MTP_OPERATION_GET_THUMB) && readData()) {
253 MtpResponseCode ret = readResponse();
254 if (ret == MTP_RESPONSE_OK) {
255 return mData.getData(outLength);
256 }
257 }
258 outLength = 0;
259 return NULL;
Mike Lockwoode0a89f62010-06-11 16:34:52 -0400260}
Mike Lockwooddda56862010-06-10 16:34:20 -0400261
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400262MtpObjectHandle MtpDevice::sendObjectInfo(MtpObjectInfo* info) {
263 Mutex::Autolock autoLock(mMutex);
264
265 mRequest.reset();
266 MtpObjectHandle parent = info->mParent;
267 if (parent == 0)
268 parent = MTP_PARENT_ROOT;
269
270 mRequest.setParameter(1, info->mStorageID);
271 mRequest.setParameter(2, info->mParent);
272
273 mData.putUInt32(info->mStorageID);
274 mData.putUInt16(info->mFormat);
275 mData.putUInt16(info->mProtectionStatus);
276 mData.putUInt32(info->mCompressedSize);
277 mData.putUInt16(info->mThumbFormat);
278 mData.putUInt32(info->mThumbCompressedSize);
279 mData.putUInt32(info->mThumbPixWidth);
280 mData.putUInt32(info->mThumbPixHeight);
281 mData.putUInt32(info->mImagePixWidth);
282 mData.putUInt32(info->mImagePixHeight);
283 mData.putUInt32(info->mImagePixDepth);
284 mData.putUInt32(info->mParent);
285 mData.putUInt16(info->mAssociationType);
286 mData.putUInt32(info->mAssociationDesc);
287 mData.putUInt32(info->mSequenceNumber);
288 mData.putString(info->mName);
289
290 char created[100], modified[100];
291 formatDateTime(info->mDateCreated, created, sizeof(created));
292 formatDateTime(info->mDateModified, modified, sizeof(modified));
293
294 mData.putString(created);
295 mData.putString(modified);
296 if (info->mKeywords)
297 mData.putString(info->mKeywords);
298 else
299 mData.putEmptyString();
300
301 if (sendRequest(MTP_OPERATION_SEND_OBJECT_INFO) && sendData()) {
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400302 MtpResponseCode ret = readResponse();
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400303 if (ret == MTP_RESPONSE_OK) {
304 info->mStorageID = mResponse.getParameter(1);
305 info->mParent = mResponse.getParameter(2);
306 info->mHandle = mResponse.getParameter(3);
307 return info->mHandle;
308 }
309 }
310 return (MtpObjectHandle)-1;
311}
312
313bool MtpDevice::sendObject(MtpObjectInfo* info, int srcFD) {
314 Mutex::Autolock autoLock(mMutex);
315
316 int remaining = info->mCompressedSize;
317 mRequest.reset();
318 mRequest.setParameter(1, info->mHandle);
319 if (sendRequest(MTP_OPERATION_SEND_OBJECT)) {
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400320 // send data header
321 writeDataHeader(MTP_OPERATION_SEND_OBJECT, remaining);
322
323 char buffer[65536];
324 while (remaining > 0) {
325 int count = read(srcFD, buffer, sizeof(buffer));
326 if (count > 0) {
327 int written = mData.write(mEndpointOut, buffer, count);
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400328 // FIXME check error
329 remaining -= count;
330 } else {
331 break;
332 }
333 }
334 }
335 MtpResponseCode ret = readResponse();
336 return (remaining == 0 && ret == MTP_RESPONSE_OK);
337}
338
Mike Lockwoode0a89f62010-06-11 16:34:52 -0400339bool MtpDevice::deleteObject(MtpObjectHandle handle) {
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400340 Mutex::Autolock autoLock(mMutex);
341
Mike Lockwoode0a89f62010-06-11 16:34:52 -0400342 mRequest.reset();
343 mRequest.setParameter(1, handle);
344 if (sendRequest(MTP_OPERATION_DELETE_OBJECT)) {
345 MtpResponseCode ret = readResponse();
346 if (ret == MTP_RESPONSE_OK)
347 return true;
348 }
349 return false;
350}
351
352MtpObjectHandle MtpDevice::getParent(MtpObjectHandle handle) {
353 MtpObjectInfo* info = getObjectInfo(handle);
354 if (info)
355 return info->mParent;
356 else
357 return -1;
358}
359
360MtpObjectHandle MtpDevice::getStorageID(MtpObjectHandle handle) {
361 MtpObjectInfo* info = getObjectInfo(handle);
362 if (info)
363 return info->mStorageID;
364 else
365 return -1;
Mike Lockwooddda56862010-06-10 16:34:20 -0400366}
367
Mike Lockwood5768f102010-12-07 10:58:56 -0800368MtpObjectPropertyList* MtpDevice::getObjectPropsSupported(MtpObjectFormat format) {
369 Mutex::Autolock autoLock(mMutex);
370
371 mRequest.reset();
372 mRequest.setParameter(1, format);
373 if (!sendRequest(MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED))
374 return NULL;
375 if (!readData())
376 return NULL;
377 MtpResponseCode ret = readResponse();
378 if (ret == MTP_RESPONSE_OK) {
379 return mData.getAUInt16();
380 }
381 return NULL;
382
383}
384
Mike Lockwood90f48732010-06-05 22:45:01 -0400385MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) {
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400386 Mutex::Autolock autoLock(mMutex);
387
Mike Lockwood90f48732010-06-05 22:45:01 -0400388 mRequest.reset();
389 mRequest.setParameter(1, code);
390 if (!sendRequest(MTP_OPERATION_GET_DEVICE_PROP_DESC))
391 return NULL;
392 if (!readData())
393 return NULL;
394 MtpResponseCode ret = readResponse();
395 if (ret == MTP_RESPONSE_OK) {
396 MtpProperty* property = new MtpProperty;
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400397 property->read(mData);
Mike Lockwood90f48732010-06-05 22:45:01 -0400398 return property;
399 }
400 return NULL;
401}
402
Mike Lockwooda194cc72010-12-07 18:53:04 -0800403MtpProperty* MtpDevice::getObjectPropDesc(MtpObjectProperty code, MtpObjectFormat format) {
Mike Lockwood5768f102010-12-07 10:58:56 -0800404 Mutex::Autolock autoLock(mMutex);
405
406 mRequest.reset();
407 mRequest.setParameter(1, code);
Mike Lockwooda194cc72010-12-07 18:53:04 -0800408 mRequest.setParameter(2, format);
Mike Lockwood5768f102010-12-07 10:58:56 -0800409 if (!sendRequest(MTP_OPERATION_GET_OBJECT_PROP_DESC))
410 return NULL;
411 if (!readData())
412 return NULL;
413 MtpResponseCode ret = readResponse();
414 if (ret == MTP_RESPONSE_OK) {
415 MtpProperty* property = new MtpProperty;
416 property->read(mData);
417 return property;
418 }
419 return NULL;
420}
421
Mike Lockwood954c2672010-11-19 11:20:19 -0500422// reads the object's data and writes it to the specified file path
Mike Lockwood929b3da2010-11-19 13:52:20 -0500423bool MtpDevice::readObject(MtpObjectHandle handle, const char* destPath, int group, int perm) {
Mike Lockwood954c2672010-11-19 11:20:19 -0500424 LOGD("readObject: %s", destPath);
425 int fd = ::open(destPath, O_RDWR | O_CREAT | O_TRUNC);
426 if (fd < 0) {
427 LOGE("open failed for %s", destPath);
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400428 return false;
429 }
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400430
Mike Lockwood929b3da2010-11-19 13:52:20 -0500431 fchown(fd, getuid(), group);
432 // set permissions
433 int mask = umask(0);
434 fchmod(fd, perm);
435 umask(mask);
436
Mike Lockwood954c2672010-11-19 11:20:19 -0500437 Mutex::Autolock autoLock(mMutex);
438 bool result = false;
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400439
Mike Lockwood954c2672010-11-19 11:20:19 -0500440 mRequest.reset();
441 mRequest.setParameter(1, handle);
442 if (sendRequest(MTP_OPERATION_GET_OBJECT)
443 && mData.readDataHeader(mEndpointIn)) {
444 uint32_t length = mData.getContainerLength();
445 if (length < MTP_CONTAINER_HEADER_SIZE)
446 goto fail;
447 length -= MTP_CONTAINER_HEADER_SIZE;
448 uint32_t remaining = length;
449
450 int initialDataLength = 0;
451 void* initialData = mData.getData(initialDataLength);
452 if (initialData) {
453 if (initialDataLength > 0) {
454 if (write(fd, initialData, initialDataLength) != initialDataLength)
455 goto fail;
456 remaining -= initialDataLength;
457 }
458 free(initialData);
459 }
460
461 // USB reads greater than 16K don't work
462 char buffer1[16384], buffer2[16384];
463 char* readBuffer = buffer1;
464 char* writeBuffer = NULL;
465 int writeLength = 0;
466
467 while (remaining > 0 || writeBuffer) {
468 if (remaining > 0) {
469 // queue up a read request
470 int readSize = (remaining > sizeof(buffer1) ? sizeof(buffer1) : remaining);
471 if (mData.readDataAsync(mEndpointIn, readBuffer, readSize)) {
472 LOGE("readDataAsync failed");
473 goto fail;
474 }
475 } else {
476 readBuffer = NULL;
477 }
478
479 if (writeBuffer) {
480 // write previous buffer
481 if (write(fd, writeBuffer, writeLength) != writeLength) {
482 LOGE("write failed");
483 // wait for pending read before failing
484 if (readBuffer)
485 mData.readDataWait(mEndpointIn);
486 goto fail;
487 }
488 writeBuffer = NULL;
489 }
490
491 // wait for read to complete
492 if (readBuffer) {
493 int read = mData.readDataWait(mEndpointIn);
494 if (read < 0)
495 goto fail;
496
497 writeBuffer = readBuffer;
498 writeLength = read;
499 remaining -= read;
500 readBuffer = (readBuffer == buffer1 ? buffer2 : buffer1);
501 }
502 }
503
504 MtpResponseCode response = readResponse();
505 if (response == MTP_RESPONSE_OK)
506 result = true;
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400507 }
Mike Lockwood954c2672010-11-19 11:20:19 -0500508
509fail:
510 ::close(fd);
511 return result;
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400512}
Mike Lockwood90f48732010-06-05 22:45:01 -0400513
Mike Lockwood755fd612010-05-25 19:08:48 -0400514bool MtpDevice::sendRequest(MtpOperationCode operation) {
Mike Lockwood456d8e62010-07-27 11:50:34 -0400515 LOGV("sendRequest: %s\n", MtpDebug::getOperationCodeName(operation));
Mike Lockwood755fd612010-05-25 19:08:48 -0400516 mRequest.setOperationCode(operation);
517 if (mTransactionID > 0)
518 mRequest.setTransactionID(mTransactionID++);
519 int ret = mRequest.write(mEndpointOut);
520 mRequest.dump();
521 return (ret > 0);
522}
523
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400524bool MtpDevice::sendData() {
Mike Lockwood456d8e62010-07-27 11:50:34 -0400525 LOGV("sendData\n");
Mike Lockwood755fd612010-05-25 19:08:48 -0400526 mData.setOperationCode(mRequest.getOperationCode());
527 mData.setTransactionID(mRequest.getTransactionID());
528 int ret = mData.write(mEndpointOut);
529 mData.dump();
530 return (ret > 0);
531}
532
533bool MtpDevice::readData() {
534 mData.reset();
535 int ret = mData.read(mEndpointIn);
Mike Lockwood456d8e62010-07-27 11:50:34 -0400536 LOGV("readData returned %d\n", ret);
Mike Lockwood755fd612010-05-25 19:08:48 -0400537 if (ret >= MTP_CONTAINER_HEADER_SIZE) {
538 mData.dump();
539 return true;
540 }
541 else {
Mike Lockwood456d8e62010-07-27 11:50:34 -0400542 LOGV("readResponse failed\n");
Mike Lockwood755fd612010-05-25 19:08:48 -0400543 return false;
544 }
545}
546
Mike Lockwoodbc4cb0b2010-07-26 20:40:45 -0400547bool MtpDevice::writeDataHeader(MtpOperationCode operation, int dataLength) {
548 mData.setOperationCode(operation);
549 mData.setTransactionID(mRequest.getTransactionID());
550 return (!mData.writeDataHeader(mEndpointOut, dataLength));
551}
552
Mike Lockwood755fd612010-05-25 19:08:48 -0400553MtpResponseCode MtpDevice::readResponse() {
Mike Lockwood456d8e62010-07-27 11:50:34 -0400554 LOGV("readResponse\n");
Mike Lockwood755fd612010-05-25 19:08:48 -0400555 int ret = mResponse.read(mEndpointIn);
556 if (ret >= MTP_CONTAINER_HEADER_SIZE) {
557 mResponse.dump();
558 return mResponse.getResponseCode();
559 }
560 else {
Mike Lockwood90f48732010-06-05 22:45:01 -0400561 LOGD("readResponse failed\n");
Mike Lockwood755fd612010-05-25 19:08:48 -0400562 return -1;
563 }
564}
565
566} // namespace android