1/* 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 17#define LOG_TAG "MtpDataPacket" 18 19#include <stdio.h> 20#include <sys/types.h> 21#include <fcntl.h> 22 23#include <usbhost/usbhost.h> 24 25#include "MtpDataPacket.h" 26#include "MtpStringBuffer.h" 27 28namespace android { 29 30MtpDataPacket::MtpDataPacket() 31 : MtpPacket(MTP_BUFFER_SIZE), // MAX_USBFS_BUFFER_SIZE 32 mOffset(MTP_CONTAINER_HEADER_SIZE) 33{ 34} 35 36MtpDataPacket::~MtpDataPacket() { 37} 38 39void MtpDataPacket::reset() { 40 MtpPacket::reset(); 41 mOffset = MTP_CONTAINER_HEADER_SIZE; 42} 43 44void MtpDataPacket::setOperationCode(MtpOperationCode code) { 45 MtpPacket::putUInt16(MTP_CONTAINER_CODE_OFFSET, code); 46} 47 48void MtpDataPacket::setTransactionID(MtpTransactionID id) { 49 MtpPacket::putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id); 50} 51 52bool MtpDataPacket::getUInt8(uint8_t& value) { 53 if (mPacketSize - mOffset < sizeof(value)) 54 return false; 55 value = mBuffer[mOffset++]; 56 return true; 57} 58 59bool MtpDataPacket::getUInt16(uint16_t& value) { 60 if (mPacketSize - mOffset < sizeof(value)) 61 return false; 62 int offset = mOffset; 63 value = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8); 64 mOffset += sizeof(value); 65 return true; 66} 67 68bool MtpDataPacket::getUInt32(uint32_t& value) { 69 if (mPacketSize - mOffset < sizeof(value)) 70 return false; 71 int offset = mOffset; 72 value = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) | 73 ((uint32_t)mBuffer[offset + 2] << 16) | ((uint32_t)mBuffer[offset + 3] << 24); 74 mOffset += sizeof(value); 75 return true; 76} 77 78bool MtpDataPacket::getUInt64(uint64_t& value) { 79 if (mPacketSize - mOffset < sizeof(value)) 80 return false; 81 int offset = mOffset; 82 value = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) | 83 ((uint64_t)mBuffer[offset + 2] << 16) | ((uint64_t)mBuffer[offset + 3] << 24) | 84 ((uint64_t)mBuffer[offset + 4] << 32) | ((uint64_t)mBuffer[offset + 5] << 40) | 85 ((uint64_t)mBuffer[offset + 6] << 48) | ((uint64_t)mBuffer[offset + 7] << 56); 86 mOffset += sizeof(value); 87 return true; 88} 89 90bool MtpDataPacket::getUInt128(uint128_t& value) { 91 return getUInt32(value[0]) && getUInt32(value[1]) && getUInt32(value[2]) && getUInt32(value[3]); 92} 93 94bool MtpDataPacket::getString(MtpStringBuffer& string) 95{ 96 return string.readFromPacket(this); 97} 98 99Int8List* MtpDataPacket::getAInt8() { 100 uint32_t count; 101 if (!getUInt32(count)) 102 return NULL; 103 Int8List* result = new Int8List; 104 for (uint32_t i = 0; i < count; i++) { 105 int8_t value; 106 if (!getInt8(value)) { 107 delete result; 108 return NULL; 109 } 110 result->push(value); 111 } 112 return result; 113} 114 115UInt8List* MtpDataPacket::getAUInt8() { 116 uint32_t count; 117 if (!getUInt32(count)) 118 return NULL; 119 UInt8List* result = new UInt8List; 120 for (uint32_t i = 0; i < count; i++) { 121 uint8_t value; 122 if (!getUInt8(value)) { 123 delete result; 124 return NULL; 125 } 126 result->push(value); 127 } 128 return result; 129} 130 131Int16List* MtpDataPacket::getAInt16() { 132 uint32_t count; 133 if (!getUInt32(count)) 134 return NULL; 135 Int16List* result = new Int16List; 136 for (uint32_t i = 0; i < count; i++) { 137 int16_t value; 138 if (!getInt16(value)) { 139 delete result; 140 return NULL; 141 } 142 result->push(value); 143 } 144 return result; 145} 146 147UInt16List* MtpDataPacket::getAUInt16() { 148 uint32_t count; 149 if (!getUInt32(count)) 150 return NULL; 151 UInt16List* result = new UInt16List; 152 for (uint32_t i = 0; i < count; i++) { 153 uint16_t value; 154 if (!getUInt16(value)) { 155 delete result; 156 return NULL; 157 } 158 result->push(value); 159 } 160 return result; 161} 162 163Int32List* MtpDataPacket::getAInt32() { 164 uint32_t count; 165 if (!getUInt32(count)) 166 return NULL; 167 Int32List* result = new Int32List; 168 for (uint32_t i = 0; i < count; i++) { 169 int32_t value; 170 if (!getInt32(value)) { 171 delete result; 172 return NULL; 173 } 174 result->push(value); 175 } 176 return result; 177} 178 179UInt32List* MtpDataPacket::getAUInt32() { 180 uint32_t count; 181 if (!getUInt32(count)) 182 return NULL; 183 UInt32List* result = new UInt32List; 184 for (uint32_t i = 0; i < count; i++) { 185 uint32_t value; 186 if (!getUInt32(value)) { 187 delete result; 188 return NULL; 189 } 190 result->push(value); 191 } 192 return result; 193} 194 195Int64List* MtpDataPacket::getAInt64() { 196 uint32_t count; 197 if (!getUInt32(count)) 198 return NULL; 199 Int64List* result = new Int64List; 200 for (uint32_t i = 0; i < count; i++) { 201 int64_t value; 202 if (!getInt64(value)) { 203 delete result; 204 return NULL; 205 } 206 result->push(value); 207 } 208 return result; 209} 210 211UInt64List* MtpDataPacket::getAUInt64() { 212 uint32_t count; 213 if (!getUInt32(count)) 214 return NULL; 215 UInt64List* result = new UInt64List; 216 for (uint32_t i = 0; i < count; i++) { 217 uint64_t value; 218 if (!getUInt64(value)) { 219 delete result; 220 return NULL; 221 } 222 result->push(value); 223 } 224 return result; 225} 226 227void MtpDataPacket::putInt8(int8_t value) { 228 allocate(mOffset + 1); 229 mBuffer[mOffset++] = (uint8_t)value; 230 if (mPacketSize < mOffset) 231 mPacketSize = mOffset; 232} 233 234void MtpDataPacket::putUInt8(uint8_t value) { 235 allocate(mOffset + 1); 236 mBuffer[mOffset++] = (uint8_t)value; 237 if (mPacketSize < mOffset) 238 mPacketSize = mOffset; 239} 240 241void MtpDataPacket::putInt16(int16_t value) { 242 allocate(mOffset + 2); 243 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 244 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 245 if (mPacketSize < mOffset) 246 mPacketSize = mOffset; 247} 248 249void MtpDataPacket::putUInt16(uint16_t value) { 250 allocate(mOffset + 2); 251 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 252 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 253 if (mPacketSize < mOffset) 254 mPacketSize = mOffset; 255} 256 257void MtpDataPacket::putInt32(int32_t value) { 258 allocate(mOffset + 4); 259 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 260 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 261 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 262 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 263 if (mPacketSize < mOffset) 264 mPacketSize = mOffset; 265} 266 267void MtpDataPacket::putUInt32(uint32_t value) { 268 allocate(mOffset + 4); 269 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 270 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 271 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 272 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 273 if (mPacketSize < mOffset) 274 mPacketSize = mOffset; 275} 276 277void MtpDataPacket::putInt64(int64_t value) { 278 allocate(mOffset + 8); 279 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 280 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 281 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 282 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 283 mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF); 284 mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF); 285 mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF); 286 mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF); 287 if (mPacketSize < mOffset) 288 mPacketSize = mOffset; 289} 290 291void MtpDataPacket::putUInt64(uint64_t value) { 292 allocate(mOffset + 8); 293 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 294 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 295 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 296 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 297 mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF); 298 mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF); 299 mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF); 300 mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF); 301 if (mPacketSize < mOffset) 302 mPacketSize = mOffset; 303} 304 305void MtpDataPacket::putInt128(const int128_t& value) { 306 putInt32(value[0]); 307 putInt32(value[1]); 308 putInt32(value[2]); 309 putInt32(value[3]); 310} 311 312void MtpDataPacket::putUInt128(const uint128_t& value) { 313 putUInt32(value[0]); 314 putUInt32(value[1]); 315 putUInt32(value[2]); 316 putUInt32(value[3]); 317} 318 319void MtpDataPacket::putInt128(int64_t value) { 320 putInt64(value); 321 putInt64(value < 0 ? -1 : 0); 322} 323 324void MtpDataPacket::putUInt128(uint64_t value) { 325 putUInt64(value); 326 putUInt64(0); 327} 328 329void MtpDataPacket::putAInt8(const int8_t* values, int count) { 330 putUInt32(count); 331 for (int i = 0; i < count; i++) 332 putInt8(*values++); 333} 334 335void MtpDataPacket::putAUInt8(const uint8_t* values, int count) { 336 putUInt32(count); 337 for (int i = 0; i < count; i++) 338 putUInt8(*values++); 339} 340 341void MtpDataPacket::putAInt16(const int16_t* values, int count) { 342 putUInt32(count); 343 for (int i = 0; i < count; i++) 344 putInt16(*values++); 345} 346 347void MtpDataPacket::putAUInt16(const uint16_t* values, int count) { 348 putUInt32(count); 349 for (int i = 0; i < count; i++) 350 putUInt16(*values++); 351} 352 353void MtpDataPacket::putAUInt16(const UInt16List* values) { 354 size_t count = (values ? values->size() : 0); 355 putUInt32(count); 356 for (size_t i = 0; i < count; i++) 357 putUInt16((*values)[i]); 358} 359 360void MtpDataPacket::putAInt32(const int32_t* values, int count) { 361 putUInt32(count); 362 for (int i = 0; i < count; i++) 363 putInt32(*values++); 364} 365 366void MtpDataPacket::putAUInt32(const uint32_t* values, int count) { 367 putUInt32(count); 368 for (int i = 0; i < count; i++) 369 putUInt32(*values++); 370} 371 372void MtpDataPacket::putAUInt32(const UInt32List* list) { 373 if (!list) { 374 putEmptyArray(); 375 } else { 376 size_t size = list->size(); 377 putUInt32(size); 378 for (size_t i = 0; i < size; i++) 379 putUInt32((*list)[i]); 380 } 381} 382 383void MtpDataPacket::putAInt64(const int64_t* values, int count) { 384 putUInt32(count); 385 for (int i = 0; i < count; i++) 386 putInt64(*values++); 387} 388 389void MtpDataPacket::putAUInt64(const uint64_t* values, int count) { 390 putUInt32(count); 391 for (int i = 0; i < count; i++) 392 putUInt64(*values++); 393} 394 395void MtpDataPacket::putString(const MtpStringBuffer& string) { 396 string.writeToPacket(this); 397} 398 399void MtpDataPacket::putString(const char* s) { 400 MtpStringBuffer string(s); 401 string.writeToPacket(this); 402} 403 404void MtpDataPacket::putString(const uint16_t* string) { 405 int count = 0; 406 for (int i = 0; i <= MTP_STRING_MAX_CHARACTER_NUMBER; i++) { 407 if (string[i]) 408 count++; 409 else 410 break; 411 } 412 putUInt8(count > 0 ? count + 1 : 0); 413 for (int i = 0; i < count; i++) 414 putUInt16(string[i]); 415 // only terminate with zero if string is not empty 416 if (count > 0) 417 putUInt16(0); 418} 419 420#ifdef MTP_DEVICE 421int MtpDataPacket::read(int fd) { 422 int ret = ::read(fd, mBuffer, MTP_BUFFER_SIZE); 423 if (ret < MTP_CONTAINER_HEADER_SIZE) 424 return -1; 425 mPacketSize = ret; 426 mOffset = MTP_CONTAINER_HEADER_SIZE; 427 return ret; 428} 429 430int MtpDataPacket::write(int fd) { 431 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize); 432 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 433 int ret = ::write(fd, mBuffer, mPacketSize); 434 return (ret < 0 ? ret : 0); 435} 436 437int MtpDataPacket::writeData(int fd, void* data, uint32_t length) { 438 allocate(length + MTP_CONTAINER_HEADER_SIZE); 439 memcpy(mBuffer + MTP_CONTAINER_HEADER_SIZE, data, length); 440 length += MTP_CONTAINER_HEADER_SIZE; 441 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length); 442 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 443 int ret = ::write(fd, mBuffer, length); 444 return (ret < 0 ? ret : 0); 445} 446 447#endif // MTP_DEVICE 448 449#ifdef MTP_HOST 450int MtpDataPacket::read(struct usb_request *request) { 451 // first read the header 452 request->buffer = mBuffer; 453 request->buffer_length = mBufferSize; 454 int length = transfer(request); 455 if (length >= MTP_CONTAINER_HEADER_SIZE) { 456 // look at the length field to see if the data spans multiple packets 457 uint32_t totalLength = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET); 458 allocate(totalLength); 459 while (totalLength > static_cast<uint32_t>(length)) { 460 request->buffer = mBuffer + length; 461 request->buffer_length = totalLength - length; 462 int ret = transfer(request); 463 if (ret >= 0) 464 length += ret; 465 else { 466 length = ret; 467 break; 468 } 469 } 470 } 471 if (length >= 0) 472 mPacketSize = length; 473 return length; 474} 475 476int MtpDataPacket::readData(struct usb_request *request, void* buffer, int length) { 477 int read = 0; 478 while (read < length) { 479 request->buffer = (char *)buffer + read; 480 request->buffer_length = length - read; 481 int ret = transfer(request); 482 if (ret < 0) { 483 return ret; 484 } 485 read += ret; 486 } 487 return read; 488} 489 490// Queue a read request. Call readDataWait to wait for result 491int MtpDataPacket::readDataAsync(struct usb_request *req) { 492 if (usb_request_queue(req)) { 493 ALOGE("usb_endpoint_queue failed, errno: %d", errno); 494 return -1; 495 } 496 return 0; 497} 498 499// Wait for result of readDataAsync 500int MtpDataPacket::readDataWait(struct usb_device *device) { 501 struct usb_request *req = usb_request_wait(device); 502 return (req ? req->actual_length : -1); 503} 504 505int MtpDataPacket::readDataHeader(struct usb_request *request) { 506 request->buffer = mBuffer; 507 request->buffer_length = request->max_packet_size; 508 int length = transfer(request); 509 if (length >= 0) 510 mPacketSize = length; 511 return length; 512} 513 514int MtpDataPacket::writeDataHeader(struct usb_request *request, uint32_t length) { 515 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length); 516 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 517 request->buffer = mBuffer; 518 request->buffer_length = MTP_CONTAINER_HEADER_SIZE; 519 int ret = transfer(request); 520 return (ret < 0 ? ret : 0); 521} 522 523int MtpDataPacket::write(struct usb_request *request) { 524 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize); 525 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 526 request->buffer = mBuffer; 527 request->buffer_length = mPacketSize; 528 int ret = transfer(request); 529 return (ret < 0 ? ret : 0); 530} 531 532int MtpDataPacket::write(struct usb_request *request, void* buffer, uint32_t length) { 533 request->buffer = buffer; 534 request->buffer_length = length; 535 int ret = transfer(request); 536 return (ret < 0 ? ret : 0); 537} 538 539#endif // MTP_HOST 540 541void* MtpDataPacket::getData(int* outLength) const { 542 int length = mPacketSize - MTP_CONTAINER_HEADER_SIZE; 543 if (length > 0) { 544 void* result = malloc(length); 545 if (result) { 546 memcpy(result, mBuffer + MTP_CONTAINER_HEADER_SIZE, length); 547 *outLength = length; 548 return result; 549 } 550 } 551 *outLength = 0; 552 return NULL; 553} 554 555} // namespace android 556