blob: 039e4f5e0c2138f5d62b8b7f001d6cedf9b06e2c [file] [log] [blame]
Mike Lockwooda6c490b2010-06-05 22:45:01 -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
17#define LOG_TAG "MtpProperty"
Mike Lockwooda6c490b2010-06-05 22:45:01 -040018
Kévin PETIT377b2ec2014-02-03 12:35:36 +000019#include <inttypes.h>
Lajos Molnareb5d7f22014-03-24 16:18:36 -070020#include <cutils/compiler.h>
Mike Lockwooda6c490b2010-06-05 22:45:01 -040021#include "MtpDataPacket.h"
Mike Lockwood0c7c7c72010-12-07 11:24:28 -080022#include "MtpDebug.h"
Mike Lockwooda6c490b2010-06-05 22:45:01 -040023#include "MtpProperty.h"
24#include "MtpStringBuffer.h"
25#include "MtpUtils.h"
26
27namespace android {
28
29MtpProperty::MtpProperty()
30 : mCode(0),
31 mType(0),
32 mWriteable(false),
33 mDefaultArrayLength(0),
34 mDefaultArrayValues(NULL),
35 mCurrentArrayLength(0),
36 mCurrentArrayValues(NULL),
Mike Lockwood2bb8c0e2010-08-09 14:49:28 -040037 mGroupCode(0),
Mike Lockwooda6c490b2010-06-05 22:45:01 -040038 mFormFlag(kFormNone),
39 mEnumLength(0),
40 mEnumValues(NULL)
41{
Mike Lockwooddde37202010-09-25 21:21:05 -040042 memset(&mDefaultValue, 0, sizeof(mDefaultValue));
43 memset(&mCurrentValue, 0, sizeof(mCurrentValue));
44 memset(&mMinimumValue, 0, sizeof(mMinimumValue));
45 memset(&mMaximumValue, 0, sizeof(mMaximumValue));
Mike Lockwooda6c490b2010-06-05 22:45:01 -040046}
47
Mike Lockwood21ef7d02010-06-30 17:00:35 -040048MtpProperty::MtpProperty(MtpPropertyCode propCode,
49 MtpDataType type,
50 bool writeable,
51 int defaultValue)
52 : mCode(propCode),
53 mType(type),
54 mWriteable(writeable),
55 mDefaultArrayLength(0),
56 mDefaultArrayValues(NULL),
57 mCurrentArrayLength(0),
58 mCurrentArrayValues(NULL),
Mike Lockwood40ce1f22010-12-01 18:46:23 -050059 mGroupCode(0),
Mike Lockwood21ef7d02010-06-30 17:00:35 -040060 mFormFlag(kFormNone),
61 mEnumLength(0),
62 mEnumValues(NULL)
63{
64 memset(&mDefaultValue, 0, sizeof(mDefaultValue));
65 memset(&mCurrentValue, 0, sizeof(mCurrentValue));
66 memset(&mMinimumValue, 0, sizeof(mMinimumValue));
67 memset(&mMaximumValue, 0, sizeof(mMaximumValue));
68
69 if (defaultValue) {
70 switch (type) {
71 case MTP_TYPE_INT8:
Mike Lockwooddde37202010-09-25 21:21:05 -040072 mDefaultValue.u.i8 = defaultValue;
Mike Lockwood21ef7d02010-06-30 17:00:35 -040073 break;
74 case MTP_TYPE_UINT8:
Mike Lockwooddde37202010-09-25 21:21:05 -040075 mDefaultValue.u.u8 = defaultValue;
Mike Lockwood21ef7d02010-06-30 17:00:35 -040076 break;
77 case MTP_TYPE_INT16:
Mike Lockwooddde37202010-09-25 21:21:05 -040078 mDefaultValue.u.i16 = defaultValue;
Mike Lockwood21ef7d02010-06-30 17:00:35 -040079 break;
80 case MTP_TYPE_UINT16:
Mike Lockwooddde37202010-09-25 21:21:05 -040081 mDefaultValue.u.u16 = defaultValue;
Mike Lockwood21ef7d02010-06-30 17:00:35 -040082 break;
83 case MTP_TYPE_INT32:
Mike Lockwooddde37202010-09-25 21:21:05 -040084 mDefaultValue.u.i32 = defaultValue;
Mike Lockwood21ef7d02010-06-30 17:00:35 -040085 break;
86 case MTP_TYPE_UINT32:
Mike Lockwooddde37202010-09-25 21:21:05 -040087 mDefaultValue.u.u32 = defaultValue;
Mike Lockwood21ef7d02010-06-30 17:00:35 -040088 break;
89 case MTP_TYPE_INT64:
Mike Lockwooddde37202010-09-25 21:21:05 -040090 mDefaultValue.u.i64 = defaultValue;
Mike Lockwood21ef7d02010-06-30 17:00:35 -040091 break;
92 case MTP_TYPE_UINT64:
Mike Lockwooddde37202010-09-25 21:21:05 -040093 mDefaultValue.u.u64 = defaultValue;
Mike Lockwood21ef7d02010-06-30 17:00:35 -040094 break;
95 default:
Steve Block29357bc2012-01-06 19:20:56 +000096 ALOGE("unknown type %04X in MtpProperty::MtpProperty", type);
Mike Lockwood21ef7d02010-06-30 17:00:35 -040097 }
98 }
99}
100
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400101MtpProperty::~MtpProperty() {
102 if (mType == MTP_TYPE_STR) {
103 // free all strings
104 free(mDefaultValue.str);
105 free(mCurrentValue.str);
106 free(mMinimumValue.str);
107 free(mMaximumValue.str);
108 if (mDefaultArrayValues) {
Mike Lockwoodab063842014-11-12 14:20:06 -0800109 for (uint32_t i = 0; i < mDefaultArrayLength; i++)
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400110 free(mDefaultArrayValues[i].str);
111 }
112 if (mCurrentArrayValues) {
Mike Lockwoodab063842014-11-12 14:20:06 -0800113 for (uint32_t i = 0; i < mCurrentArrayLength; i++)
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400114 free(mCurrentArrayValues[i].str);
115 }
116 if (mEnumValues) {
Mike Lockwoodab063842014-11-12 14:20:06 -0800117 for (uint16_t i = 0; i < mEnumLength; i++)
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400118 free(mEnumValues[i].str);
119 }
120 }
121 delete[] mDefaultArrayValues;
122 delete[] mCurrentArrayValues;
123 delete[] mEnumValues;
124}
125
Mike Lockwoodab063842014-11-12 14:20:06 -0800126bool MtpProperty::read(MtpDataPacket& packet) {
127 uint8_t temp8;
128
129 if (!packet.getUInt16(mCode)) return false;
Mike Lockwood5da86482010-12-07 13:51:54 -0800130 bool deviceProp = isDeviceProperty();
Mike Lockwoodab063842014-11-12 14:20:06 -0800131 if (!packet.getUInt16(mType)) return false;
132 if (!packet.getUInt8(temp8)) return false;
133 mWriteable = (temp8 == 1);
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400134 switch (mType) {
135 case MTP_TYPE_AINT8:
136 case MTP_TYPE_AUINT8:
137 case MTP_TYPE_AINT16:
138 case MTP_TYPE_AUINT16:
139 case MTP_TYPE_AINT32:
140 case MTP_TYPE_AUINT32:
141 case MTP_TYPE_AINT64:
142 case MTP_TYPE_AUINT64:
143 case MTP_TYPE_AINT128:
144 case MTP_TYPE_AUINT128:
145 mDefaultArrayValues = readArrayValues(packet, mDefaultArrayLength);
Mike Lockwoodab063842014-11-12 14:20:06 -0800146 if (!mDefaultArrayValues) return false;
147 if (deviceProp) {
Mike Lockwood7cee5d32010-09-25 08:37:59 -0400148 mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength);
Mike Lockwoodab063842014-11-12 14:20:06 -0800149 if (!mCurrentArrayValues) return false;
150 }
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400151 break;
152 default:
Mike Lockwoodab063842014-11-12 14:20:06 -0800153 if (!readValue(packet, mDefaultValue)) return false;
154 if (deviceProp) {
155 if (!readValue(packet, mCurrentValue)) return false;
156 }
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400157 }
Mike Lockwoodab063842014-11-12 14:20:06 -0800158 if (!deviceProp) {
159 if (!packet.getUInt32(mGroupCode)) return false;
160 }
161 if (!packet.getUInt8(mFormFlag)) return false;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400162
163 if (mFormFlag == kFormRange) {
Mike Lockwoodab063842014-11-12 14:20:06 -0800164 if (!readValue(packet, mMinimumValue)) return false;
165 if (!readValue(packet, mMaximumValue)) return false;
166 if (!readValue(packet, mStepSize)) return false;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400167 } else if (mFormFlag == kFormEnum) {
Mike Lockwoodab063842014-11-12 14:20:06 -0800168 if (!packet.getUInt16(mEnumLength)) return false;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400169 mEnumValues = new MtpPropertyValue[mEnumLength];
Mike Lockwoodab063842014-11-12 14:20:06 -0800170 for (int i = 0; i < mEnumLength; i++) {
171 if (!readValue(packet, mEnumValues[i])) return false;
172 }
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400173 }
Mike Lockwoodab063842014-11-12 14:20:06 -0800174
175 return true;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400176}
177
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400178void MtpProperty::write(MtpDataPacket& packet) {
Mike Lockwood7cee5d32010-09-25 08:37:59 -0400179 bool deviceProp = isDeviceProperty();
180
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400181 packet.putUInt16(mCode);
182 packet.putUInt16(mType);
183 packet.putUInt8(mWriteable ? 1 : 0);
184
185 switch (mType) {
186 case MTP_TYPE_AINT8:
187 case MTP_TYPE_AUINT8:
188 case MTP_TYPE_AINT16:
189 case MTP_TYPE_AUINT16:
190 case MTP_TYPE_AINT32:
191 case MTP_TYPE_AUINT32:
192 case MTP_TYPE_AINT64:
193 case MTP_TYPE_AUINT64:
194 case MTP_TYPE_AINT128:
195 case MTP_TYPE_AUINT128:
196 writeArrayValues(packet, mDefaultArrayValues, mDefaultArrayLength);
Mike Lockwood7cee5d32010-09-25 08:37:59 -0400197 if (deviceProp)
198 writeArrayValues(packet, mCurrentArrayValues, mCurrentArrayLength);
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400199 break;
200 default:
201 writeValue(packet, mDefaultValue);
Mike Lockwood7cee5d32010-09-25 08:37:59 -0400202 if (deviceProp)
203 writeValue(packet, mCurrentValue);
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400204 }
Mike Lockwood7cee5d32010-09-25 08:37:59 -0400205 if (!deviceProp)
Mike Lockwood0fa848d2014-03-07 13:29:59 -0800206 packet.putUInt32(mGroupCode);
207 packet.putUInt8(mFormFlag);
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400208 if (mFormFlag == kFormRange) {
209 writeValue(packet, mMinimumValue);
210 writeValue(packet, mMaximumValue);
211 writeValue(packet, mStepSize);
212 } else if (mFormFlag == kFormEnum) {
213 packet.putUInt16(mEnumLength);
214 for (int i = 0; i < mEnumLength; i++)
215 writeValue(packet, mEnumValues[i]);
216 }
217}
218
Mike Lockwooddde37202010-09-25 21:21:05 -0400219void MtpProperty::setDefaultValue(const uint16_t* string) {
220 free(mDefaultValue.str);
221 if (string) {
222 MtpStringBuffer buffer(string);
223 mDefaultValue.str = strdup(buffer);
224 }
225 else
226 mDefaultValue.str = NULL;
227}
228
229void MtpProperty::setCurrentValue(const uint16_t* string) {
230 free(mCurrentValue.str);
231 if (string) {
232 MtpStringBuffer buffer(string);
233 mCurrentValue.str = strdup(buffer);
234 }
235 else
236 mCurrentValue.str = NULL;
237}
238
Daichi Hirono66a9abe2016-03-24 20:56:13 +0900239void MtpProperty::setCurrentValue(MtpDataPacket& packet) {
240 free(mCurrentValue.str);
241 mCurrentValue.str = NULL;
242 readValue(packet, mCurrentValue);
243}
244
Mike Lockwood01817262010-11-10 12:48:39 -0500245void MtpProperty::setFormRange(int min, int max, int step) {
246 mFormFlag = kFormRange;
247 switch (mType) {
248 case MTP_TYPE_INT8:
249 mMinimumValue.u.i8 = min;
250 mMaximumValue.u.i8 = max;
251 mStepSize.u.i8 = step;
252 break;
253 case MTP_TYPE_UINT8:
254 mMinimumValue.u.u8 = min;
255 mMaximumValue.u.u8 = max;
256 mStepSize.u.u8 = step;
257 break;
258 case MTP_TYPE_INT16:
259 mMinimumValue.u.i16 = min;
260 mMaximumValue.u.i16 = max;
261 mStepSize.u.i16 = step;
262 break;
263 case MTP_TYPE_UINT16:
264 mMinimumValue.u.u16 = min;
265 mMaximumValue.u.u16 = max;
266 mStepSize.u.u16 = step;
267 break;
268 case MTP_TYPE_INT32:
269 mMinimumValue.u.i32 = min;
270 mMaximumValue.u.i32 = max;
271 mStepSize.u.i32 = step;
272 break;
273 case MTP_TYPE_UINT32:
274 mMinimumValue.u.u32 = min;
275 mMaximumValue.u.u32 = max;
276 mStepSize.u.u32 = step;
277 break;
278 case MTP_TYPE_INT64:
279 mMinimumValue.u.i64 = min;
280 mMaximumValue.u.i64 = max;
281 mStepSize.u.i64 = step;
282 break;
283 case MTP_TYPE_UINT64:
284 mMinimumValue.u.u64 = min;
285 mMaximumValue.u.u64 = max;
286 mStepSize.u.u64 = step;
287 break;
288 default:
Steve Block29357bc2012-01-06 19:20:56 +0000289 ALOGE("unsupported type for MtpProperty::setRange");
Mike Lockwood01817262010-11-10 12:48:39 -0500290 break;
291 }
292}
293
294void MtpProperty::setFormEnum(const int* values, int count) {
295 mFormFlag = kFormEnum;
296 delete[] mEnumValues;
297 mEnumValues = new MtpPropertyValue[count];
298 mEnumLength = count;
299
300 for (int i = 0; i < count; i++) {
301 int value = *values++;
302 switch (mType) {
303 case MTP_TYPE_INT8:
304 mEnumValues[i].u.i8 = value;
305 break;
306 case MTP_TYPE_UINT8:
307 mEnumValues[i].u.u8 = value;
308 break;
309 case MTP_TYPE_INT16:
310 mEnumValues[i].u.i16 = value;
311 break;
312 case MTP_TYPE_UINT16:
313 mEnumValues[i].u.u16 = value;
314 break;
315 case MTP_TYPE_INT32:
316 mEnumValues[i].u.i32 = value;
317 break;
318 case MTP_TYPE_UINT32:
319 mEnumValues[i].u.u32 = value;
320 break;
321 case MTP_TYPE_INT64:
322 mEnumValues[i].u.i64 = value;
323 break;
324 case MTP_TYPE_UINT64:
325 mEnumValues[i].u.u64 = value;
326 break;
327 default:
Steve Block29357bc2012-01-06 19:20:56 +0000328 ALOGE("unsupported type for MtpProperty::setEnum");
Mike Lockwood01817262010-11-10 12:48:39 -0500329 break;
330 }
331 }
332}
333
Mike Lockwoodb892d0e2010-11-23 18:38:55 -0500334void MtpProperty::setFormDateTime() {
335 mFormFlag = kFormDateTime;
336}
337
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400338void MtpProperty::print() {
Mike Lockwood0c7c7c72010-12-07 11:24:28 -0800339 MtpString buffer;
340 bool deviceProp = isDeviceProperty();
341 if (deviceProp)
Steve Blockdf64d152012-01-04 20:05:49 +0000342 ALOGI(" %s (%04X)", MtpDebug::getDevicePropCodeName(mCode), mCode);
Mike Lockwood0c7c7c72010-12-07 11:24:28 -0800343 else
Steve Blockdf64d152012-01-04 20:05:49 +0000344 ALOGI(" %s (%04X)", MtpDebug::getObjectPropCodeName(mCode), mCode);
345 ALOGI(" type %04X", mType);
346 ALOGI(" writeable %s", (mWriteable ? "true" : "false"));
Mike Lockwood0c7c7c72010-12-07 11:24:28 -0800347 buffer = " default value: ";
348 print(mDefaultValue, buffer);
Steve Blockdf64d152012-01-04 20:05:49 +0000349 ALOGI("%s", (const char *)buffer);
Mike Lockwood0c7c7c72010-12-07 11:24:28 -0800350 if (deviceProp) {
351 buffer = " current value: ";
352 print(mCurrentValue, buffer);
Steve Blockdf64d152012-01-04 20:05:49 +0000353 ALOGI("%s", (const char *)buffer);
Mike Lockwood0c7c7c72010-12-07 11:24:28 -0800354 }
355 switch (mFormFlag) {
356 case kFormNone:
357 break;
358 case kFormRange:
359 buffer = " Range (";
360 print(mMinimumValue, buffer);
361 buffer += ", ";
362 print(mMaximumValue, buffer);
363 buffer += ", ";
364 print(mStepSize, buffer);
Mike Lockwoodfd346262010-12-08 16:08:01 -0800365 buffer += ")";
Steve Blockdf64d152012-01-04 20:05:49 +0000366 ALOGI("%s", (const char *)buffer);
Mike Lockwood0c7c7c72010-12-07 11:24:28 -0800367 break;
368 case kFormEnum:
369 buffer = " Enum { ";
370 for (int i = 0; i < mEnumLength; i++) {
371 print(mEnumValues[i], buffer);
372 buffer += " ";
373 }
374 buffer += "}";
Steve Blockdf64d152012-01-04 20:05:49 +0000375 ALOGI("%s", (const char *)buffer);
Mike Lockwood0c7c7c72010-12-07 11:24:28 -0800376 break;
377 case kFormDateTime:
Steve Blockdf64d152012-01-04 20:05:49 +0000378 ALOGI(" DateTime\n");
Mike Lockwood0c7c7c72010-12-07 11:24:28 -0800379 break;
380 default:
Steve Blockdf64d152012-01-04 20:05:49 +0000381 ALOGI(" form %d\n", mFormFlag);
Mike Lockwood0c7c7c72010-12-07 11:24:28 -0800382 break;
383 }
384}
385
386void MtpProperty::print(MtpPropertyValue& value, MtpString& buffer) {
387 switch (mType) {
388 case MTP_TYPE_INT8:
389 buffer.appendFormat("%d", value.u.i8);
390 break;
391 case MTP_TYPE_UINT8:
392 buffer.appendFormat("%d", value.u.u8);
393 break;
394 case MTP_TYPE_INT16:
395 buffer.appendFormat("%d", value.u.i16);
396 break;
397 case MTP_TYPE_UINT16:
398 buffer.appendFormat("%d", value.u.u16);
399 break;
400 case MTP_TYPE_INT32:
401 buffer.appendFormat("%d", value.u.i32);
402 break;
403 case MTP_TYPE_UINT32:
404 buffer.appendFormat("%d", value.u.u32);
405 break;
406 case MTP_TYPE_INT64:
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000407 buffer.appendFormat("%" PRId64, value.u.i64);
Mike Lockwood0c7c7c72010-12-07 11:24:28 -0800408 break;
409 case MTP_TYPE_UINT64:
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000410 buffer.appendFormat("%" PRIu64, value.u.u64);
Mike Lockwood0c7c7c72010-12-07 11:24:28 -0800411 break;
412 case MTP_TYPE_INT128:
413 buffer.appendFormat("%08X%08X%08X%08X", value.u.i128[0], value.u.i128[1],
414 value.u.i128[2], value.u.i128[3]);
415 break;
416 case MTP_TYPE_UINT128:
417 buffer.appendFormat("%08X%08X%08X%08X", value.u.u128[0], value.u.u128[1],
418 value.u.u128[2], value.u.u128[3]);
419 break;
420 case MTP_TYPE_STR:
421 buffer.appendFormat("%s", value.str);
422 break;
423 default:
Steve Block29357bc2012-01-06 19:20:56 +0000424 ALOGE("unsupported type for MtpProperty::print\n");
Mike Lockwood0c7c7c72010-12-07 11:24:28 -0800425 break;
426 }
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400427}
428
Mike Lockwoodab063842014-11-12 14:20:06 -0800429bool MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) {
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400430 MtpStringBuffer stringBuffer;
431
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400432 switch (mType) {
433 case MTP_TYPE_INT8:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400434 case MTP_TYPE_AINT8:
Mike Lockwoodab063842014-11-12 14:20:06 -0800435 if (!packet.getInt8(value.u.i8)) return false;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400436 break;
437 case MTP_TYPE_UINT8:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400438 case MTP_TYPE_AUINT8:
Mike Lockwoodab063842014-11-12 14:20:06 -0800439 if (!packet.getUInt8(value.u.u8)) return false;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400440 break;
441 case MTP_TYPE_INT16:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400442 case MTP_TYPE_AINT16:
Mike Lockwoodab063842014-11-12 14:20:06 -0800443 if (!packet.getInt16(value.u.i16)) return false;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400444 break;
445 case MTP_TYPE_UINT16:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400446 case MTP_TYPE_AUINT16:
Mike Lockwoodab063842014-11-12 14:20:06 -0800447 if (!packet.getUInt16(value.u.u16)) return false;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400448 break;
449 case MTP_TYPE_INT32:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400450 case MTP_TYPE_AINT32:
Mike Lockwoodab063842014-11-12 14:20:06 -0800451 if (!packet.getInt32(value.u.i32)) return false;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400452 break;
453 case MTP_TYPE_UINT32:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400454 case MTP_TYPE_AUINT32:
Mike Lockwoodab063842014-11-12 14:20:06 -0800455 if (!packet.getUInt32(value.u.u32)) return false;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400456 break;
457 case MTP_TYPE_INT64:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400458 case MTP_TYPE_AINT64:
Mike Lockwoodab063842014-11-12 14:20:06 -0800459 if (!packet.getInt64(value.u.i64)) return false;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400460 break;
461 case MTP_TYPE_UINT64:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400462 case MTP_TYPE_AUINT64:
Mike Lockwoodab063842014-11-12 14:20:06 -0800463 if (!packet.getUInt64(value.u.u64)) return false;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400464 break;
465 case MTP_TYPE_INT128:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400466 case MTP_TYPE_AINT128:
Mike Lockwoodab063842014-11-12 14:20:06 -0800467 if (!packet.getInt128(value.u.i128)) return false;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400468 break;
469 case MTP_TYPE_UINT128:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400470 case MTP_TYPE_AUINT128:
Mike Lockwoodab063842014-11-12 14:20:06 -0800471 if (!packet.getUInt128(value.u.u128)) return false;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400472 break;
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400473 case MTP_TYPE_STR:
Mike Lockwoodab063842014-11-12 14:20:06 -0800474 if (!packet.getString(stringBuffer)) return false;
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400475 value.str = strdup(stringBuffer);
476 break;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400477 default:
Steve Block29357bc2012-01-06 19:20:56 +0000478 ALOGE("unknown type %04X in MtpProperty::readValue", mType);
Mike Lockwoodab063842014-11-12 14:20:06 -0800479 return false;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400480 }
Mike Lockwoodab063842014-11-12 14:20:06 -0800481 return true;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400482}
483
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400484void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) {
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400485 MtpStringBuffer stringBuffer;
486
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400487 switch (mType) {
488 case MTP_TYPE_INT8:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400489 case MTP_TYPE_AINT8:
Mike Lockwooddde37202010-09-25 21:21:05 -0400490 packet.putInt8(value.u.i8);
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400491 break;
492 case MTP_TYPE_UINT8:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400493 case MTP_TYPE_AUINT8:
Mike Lockwooddde37202010-09-25 21:21:05 -0400494 packet.putUInt8(value.u.u8);
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400495 break;
496 case MTP_TYPE_INT16:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400497 case MTP_TYPE_AINT16:
Mike Lockwooddde37202010-09-25 21:21:05 -0400498 packet.putInt16(value.u.i16);
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400499 break;
500 case MTP_TYPE_UINT16:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400501 case MTP_TYPE_AUINT16:
Mike Lockwooddde37202010-09-25 21:21:05 -0400502 packet.putUInt16(value.u.u16);
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400503 break;
504 case MTP_TYPE_INT32:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400505 case MTP_TYPE_AINT32:
Mike Lockwooddde37202010-09-25 21:21:05 -0400506 packet.putInt32(value.u.i32);
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400507 break;
508 case MTP_TYPE_UINT32:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400509 case MTP_TYPE_AUINT32:
Mike Lockwooddde37202010-09-25 21:21:05 -0400510 packet.putUInt32(value.u.u32);
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400511 break;
512 case MTP_TYPE_INT64:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400513 case MTP_TYPE_AINT64:
Mike Lockwooddde37202010-09-25 21:21:05 -0400514 packet.putInt64(value.u.i64);
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400515 break;
516 case MTP_TYPE_UINT64:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400517 case MTP_TYPE_AUINT64:
Mike Lockwooddde37202010-09-25 21:21:05 -0400518 packet.putUInt64(value.u.u64);
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400519 break;
520 case MTP_TYPE_INT128:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400521 case MTP_TYPE_AINT128:
Mike Lockwooddde37202010-09-25 21:21:05 -0400522 packet.putInt128(value.u.i128);
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400523 break;
524 case MTP_TYPE_UINT128:
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400525 case MTP_TYPE_AUINT128:
Mike Lockwooddde37202010-09-25 21:21:05 -0400526 packet.putUInt128(value.u.u128);
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400527 break;
Mike Lockwood5cdceca2010-07-20 09:47:41 -0400528 case MTP_TYPE_STR:
529 if (value.str)
530 packet.putString(value.str);
531 else
532 packet.putEmptyString();
533 break;
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400534 default:
Steve Block29357bc2012-01-06 19:20:56 +0000535 ALOGE("unknown type %04X in MtpProperty::writeValue", mType);
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400536 }
537}
538
Mike Lockwoodab063842014-11-12 14:20:06 -0800539MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, uint32_t& length) {
540 if (!packet.getUInt32(length)) return NULL;
541
Lajos Molnareb5d7f22014-03-24 16:18:36 -0700542 // Fail if resulting array is over 2GB. This is because the maximum array
543 // size may be less than SIZE_MAX on some platforms.
544 if ( CC_UNLIKELY(
545 length == 0 ||
546 length >= INT32_MAX / sizeof(MtpPropertyValue)) ) {
547 length = 0;
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400548 return NULL;
Lajos Molnareb5d7f22014-03-24 16:18:36 -0700549 }
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400550 MtpPropertyValue* result = new MtpPropertyValue[length];
Mike Lockwoodab063842014-11-12 14:20:06 -0800551 for (uint32_t i = 0; i < length; i++)
552 if (!readValue(packet, result[i])) {
Daichi Hironob3be0062016-02-25 12:42:58 +0900553 delete [] result;
Mike Lockwoodab063842014-11-12 14:20:06 -0800554 return NULL;
555 }
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400556 return result;
557}
558
Mike Lockwoodab063842014-11-12 14:20:06 -0800559void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, uint32_t length) {
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400560 packet.putUInt32(length);
Mike Lockwoodab063842014-11-12 14:20:06 -0800561 for (uint32_t i = 0; i < length; i++)
Mike Lockwood21ef7d02010-06-30 17:00:35 -0400562 writeValue(packet, values[i]);
563}
564
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400565} // namespace android