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 #ifndef _MTP_DATA_PACKET_H
18 #define _MTP_DATA_PACKET_H
19 
20 #include "MtpPacket.h"
21 #include "mtp.h"
22 
23 struct usb_device;
24 struct usb_request;
25 
26 namespace android {
27 
28 class IMtpHandle;
29 class MtpStringBuffer;
30 
31 class MtpDataPacket : public MtpPacket {
32 private:
33     // current offset for get/put methods
34     size_t              mOffset;
35 
36 public:
37                         MtpDataPacket();
38     virtual             ~MtpDataPacket();
39 
40     virtual void        reset();
41 
42     void                setOperationCode(MtpOperationCode code);
43     void                setTransactionID(MtpTransactionID id);
44 
getData()45     inline const uint8_t*     getData() const { return mBuffer + MTP_CONTAINER_HEADER_SIZE; }
46 
47     bool                getUInt8(uint8_t& value);
getInt8(int8_t & value)48     inline bool         getInt8(int8_t& value) { return getUInt8((uint8_t&)value); }
49     bool                getUInt16(uint16_t& value);
getInt16(int16_t & value)50     inline bool         getInt16(int16_t& value) { return getUInt16((uint16_t&)value); }
51     bool                getUInt32(uint32_t& value);
getInt32(int32_t & value)52     inline bool         getInt32(int32_t& value) { return getUInt32((uint32_t&)value); }
53     bool                getUInt64(uint64_t& value);
getInt64(int64_t & value)54     inline bool         getInt64(int64_t& value) { return getUInt64((uint64_t&)value); }
55     bool                getUInt128(uint128_t& value);
getInt128(int128_t & value)56     inline bool         getInt128(int128_t& value) { return getUInt128((uint128_t&)value); }
57     bool                getString(MtpStringBuffer& string);
58 
59     Int8List*           getAInt8();
60     UInt8List*          getAUInt8();
61     Int16List*          getAInt16();
62     UInt16List*         getAUInt16();
63     Int32List*          getAInt32();
64     UInt32List*         getAUInt32();
65     Int64List*          getAInt64();
66     UInt64List*         getAUInt64();
67 
68     void                putInt8(int8_t value);
69     void                putUInt8(uint8_t value);
70     void                putInt16(int16_t value);
71     void                putUInt16(uint16_t value);
72     void                putInt32(int32_t value);
73     void                putUInt32(uint32_t value);
74     void                putInt64(int64_t value);
75     void                putUInt64(uint64_t value);
76     void                putInt128(const int128_t& value);
77     void                putUInt128(const uint128_t& value);
78     void                putInt128(int64_t value);
79     void                putUInt128(uint64_t value);
80 
81     void                putAInt8(const int8_t* values, int count);
82     void                putAUInt8(const uint8_t* values, int count);
83     void                putAInt16(const int16_t* values, int count);
84     void                putAUInt16(const uint16_t* values, int count);
85     void                putAUInt16(const UInt16List* values);
86     void                putAInt32(const int32_t* values, int count);
87     void                putAUInt32(const uint32_t* values, int count);
88     void                putAUInt32(const UInt32List* list);
89     void                putAInt64(const int64_t* values, int count);
90     void                putAUInt64(const uint64_t* values, int count);
91     void                putString(const MtpStringBuffer& string);
92     void                putString(const char* string);
93     void                putString(const uint16_t* string);
putEmptyString()94     inline void         putEmptyString() { putUInt8(0); }
putEmptyArray()95     inline void         putEmptyArray() { putUInt32(0); }
96 
97 #ifdef MTP_DEVICE
98     // fill our buffer with data from the given usb handle
99     int                 read(IMtpHandle *h);
100 
101     // write our data to the given usb handle
102     int                 write(IMtpHandle *h);
103     int                 writeData(IMtpHandle *h, void* data, uint32_t length);
104 #endif
105 
106 #ifdef MTP_HOST
107     int                 read(struct usb_request *request);
108     int                 readData(struct usb_request *request, void* buffer, int length);
109     int                 readDataAsync(struct usb_request *req);
110     int                 readDataWait(struct usb_device *device);
111     int                 readDataHeader(struct usb_request *ep);
112 
113     // Write a whole data packet with payload to the end point given by a request. |divisionMode|
114     // specifies whether to divide header and payload. See |UrbPacketDivisionMode| for meanings of
115     // each value. Return the number of bytes (including header size) sent to the device on success.
116     // Otherwise -1.
117     int                 write(struct usb_request *request, UrbPacketDivisionMode divisionMode);
118     // Similar to previous write method but it reads the payload from |fd|. If |size| is larger than
119     // MTP_BUFFER_SIZE, the data will be sent by multiple bulk transfer requests.
120     // Return type (int64_t) is used to handle the case that the size can be larger than 2GB.
121     int64_t             write(struct usb_request *request, UrbPacketDivisionMode divisionMode,
122                               int fd, size_t size);
123 #endif
124 
hasData()125     inline bool         hasData() const { return mPacketSize > MTP_CONTAINER_HEADER_SIZE; }
getContainerLength()126     inline uint32_t     getContainerLength() const { return MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET); }
127     void*               getData(int* outLength) const;
128 };
129 
130 }; // namespace android
131 
132 #endif // _MTP_DATA_PACKET_H
133