| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| |
| #include <usbhost/usbhost.h> |
| |
| #include "MtpPacket.h" |
| #include "mtp.h" |
| |
| namespace android { |
| |
| MtpPacket::MtpPacket(int bufferSize) |
| : mBuffer(NULL), |
| mBufferSize(bufferSize), |
| mAllocationIncrement(bufferSize), |
| mPacketSize(0) |
| { |
| mBuffer = (uint8_t *)malloc(bufferSize); |
| if (!mBuffer) { |
| fprintf(stderr, "out of memory!\n"); |
| abort(); |
| } |
| } |
| |
| MtpPacket::~MtpPacket() { |
| if (mBuffer) |
| free(mBuffer); |
| } |
| |
| void MtpPacket::reset() { |
| allocate(MTP_CONTAINER_HEADER_SIZE); |
| mPacketSize = MTP_CONTAINER_HEADER_SIZE; |
| memset(mBuffer, 0, mBufferSize); |
| } |
| |
| void MtpPacket::allocate(int length) { |
| if (length > mBufferSize) { |
| int newLength = length + mAllocationIncrement; |
| mBuffer = (uint8_t *)realloc(mBuffer, newLength); |
| if (!mBuffer) { |
| fprintf(stderr, "out of memory!\n"); |
| abort(); |
| } |
| mBufferSize = newLength; |
| } |
| } |
| |
| void MtpPacket::dump() { |
| for (int i = 0; i < mPacketSize; i++) { |
| printf("%02X ", mBuffer[i]); |
| if (i % 16 == 15) |
| printf("\n"); |
| } |
| printf("\n\n"); |
| } |
| |
| uint16_t MtpPacket::getUInt16(int offset) const { |
| return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset]; |
| } |
| |
| uint32_t MtpPacket::getUInt32(int offset) const { |
| return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) | |
| ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset]; |
| } |
| |
| void MtpPacket::putUInt16(int offset, uint16_t value) { |
| mBuffer[offset++] = (uint8_t)(value & 0xFF); |
| mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF); |
| } |
| |
| void MtpPacket::putUInt32(int offset, uint32_t value) { |
| mBuffer[offset++] = (uint8_t)(value & 0xFF); |
| mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF); |
| mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF); |
| mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF); |
| } |
| |
| uint16_t MtpPacket::getContainerCode() const { |
| return getUInt16(MTP_CONTAINER_CODE_OFFSET); |
| } |
| |
| void MtpPacket::setContainerCode(uint16_t code) { |
| putUInt16(MTP_CONTAINER_CODE_OFFSET, code); |
| } |
| |
| MtpTransactionID MtpPacket::getTransactionID() const { |
| return getUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET); |
| } |
| |
| void MtpPacket::setTransactionID(MtpTransactionID id) { |
| putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id); |
| } |
| |
| uint32_t MtpPacket::getParameter(int index) const { |
| if (index < 1 || index > 5) { |
| fprintf(stderr, "index %d out of range in MtpRequestPacket::getParameter\n", index); |
| return 0; |
| } |
| return getUInt32(MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t)); |
| } |
| |
| void MtpPacket::setParameter(int index, uint32_t value) { |
| if (index < 1 || index > 5) { |
| fprintf(stderr, "index %d out of range in MtpResponsePacket::setParameter\n", index); |
| return; |
| } |
| int offset = MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t); |
| if (mPacketSize < offset + sizeof(uint32_t)) |
| mPacketSize = offset + sizeof(uint32_t); |
| putUInt32(offset, value); |
| } |
| |
| #ifdef MTP_HOST |
| int MtpPacket::transfer(struct usb_endpoint *ep, void* buffer, int length) { |
| if (usb_endpoint_queue(ep, buffer, length)) { |
| printf("usb_endpoint_queue failed, errno: %d\n", errno); |
| return -1; |
| } |
| int ep_num; |
| return usb_endpoint_wait(usb_endpoint_get_device(ep), &ep_num); |
| } |
| #endif |
| |
| } // namespace android |