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