MtpProperty.cpp revision b892d0e5556ed6ded3e0548f75ab16fc2e3d92c3
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 "MtpProperty" 18 19#include "MtpDataPacket.h" 20#include "MtpProperty.h" 21#include "MtpStringBuffer.h" 22#include "MtpUtils.h" 23 24namespace android { 25 26MtpProperty::MtpProperty() 27 : mCode(0), 28 mType(0), 29 mWriteable(false), 30 mDefaultArrayLength(0), 31 mDefaultArrayValues(NULL), 32 mCurrentArrayLength(0), 33 mCurrentArrayValues(NULL), 34 mGroupCode(0), 35 mFormFlag(kFormNone), 36 mEnumLength(0), 37 mEnumValues(NULL) 38{ 39 memset(&mDefaultValue, 0, sizeof(mDefaultValue)); 40 memset(&mCurrentValue, 0, sizeof(mCurrentValue)); 41 memset(&mMinimumValue, 0, sizeof(mMinimumValue)); 42 memset(&mMaximumValue, 0, sizeof(mMaximumValue)); 43} 44 45MtpProperty::MtpProperty(MtpPropertyCode propCode, 46 MtpDataType type, 47 bool writeable, 48 int defaultValue) 49 : mCode(propCode), 50 mType(type), 51 mWriteable(writeable), 52 mDefaultArrayLength(0), 53 mDefaultArrayValues(NULL), 54 mCurrentArrayLength(0), 55 mCurrentArrayValues(NULL), 56 mGroupCode(-1), // disable multiple properties in GetObjectPropList for now 57 mFormFlag(kFormNone), 58 mEnumLength(0), 59 mEnumValues(NULL) 60{ 61 memset(&mDefaultValue, 0, sizeof(mDefaultValue)); 62 memset(&mCurrentValue, 0, sizeof(mCurrentValue)); 63 memset(&mMinimumValue, 0, sizeof(mMinimumValue)); 64 memset(&mMaximumValue, 0, sizeof(mMaximumValue)); 65 66 if (defaultValue) { 67 switch (type) { 68 case MTP_TYPE_INT8: 69 mDefaultValue.u.i8 = defaultValue; 70 break; 71 case MTP_TYPE_UINT8: 72 mDefaultValue.u.u8 = defaultValue; 73 break; 74 case MTP_TYPE_INT16: 75 mDefaultValue.u.i16 = defaultValue; 76 break; 77 case MTP_TYPE_UINT16: 78 mDefaultValue.u.u16 = defaultValue; 79 break; 80 case MTP_TYPE_INT32: 81 mDefaultValue.u.i32 = defaultValue; 82 break; 83 case MTP_TYPE_UINT32: 84 mDefaultValue.u.u32 = defaultValue; 85 break; 86 case MTP_TYPE_INT64: 87 mDefaultValue.u.i64 = defaultValue; 88 break; 89 case MTP_TYPE_UINT64: 90 mDefaultValue.u.u64 = defaultValue; 91 break; 92 default: 93 LOGE("unknown type %04X in MtpProperty::MtpProperty", type); 94 } 95 } 96} 97 98MtpProperty::~MtpProperty() { 99 if (mType == MTP_TYPE_STR) { 100 // free all strings 101 free(mDefaultValue.str); 102 free(mCurrentValue.str); 103 free(mMinimumValue.str); 104 free(mMaximumValue.str); 105 if (mDefaultArrayValues) { 106 for (int i = 0; i < mDefaultArrayLength; i++) 107 free(mDefaultArrayValues[i].str); 108 } 109 if (mCurrentArrayValues) { 110 for (int i = 0; i < mCurrentArrayLength; i++) 111 free(mCurrentArrayValues[i].str); 112 } 113 if (mEnumValues) { 114 for (int i = 0; i < mEnumLength; i++) 115 free(mEnumValues[i].str); 116 } 117 } 118 delete[] mDefaultArrayValues; 119 delete[] mCurrentArrayValues; 120 delete[] mEnumValues; 121} 122 123void MtpProperty::read(MtpDataPacket& packet) { 124 bool deviceProp = isDeviceProperty(); 125 126 mCode = packet.getUInt16(); 127 mType = packet.getUInt16(); 128 mWriteable = (packet.getUInt8() == 1); 129 switch (mType) { 130 case MTP_TYPE_AINT8: 131 case MTP_TYPE_AUINT8: 132 case MTP_TYPE_AINT16: 133 case MTP_TYPE_AUINT16: 134 case MTP_TYPE_AINT32: 135 case MTP_TYPE_AUINT32: 136 case MTP_TYPE_AINT64: 137 case MTP_TYPE_AUINT64: 138 case MTP_TYPE_AINT128: 139 case MTP_TYPE_AUINT128: 140 mDefaultArrayValues = readArrayValues(packet, mDefaultArrayLength); 141 if (deviceProp) 142 mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength); 143 break; 144 default: 145 readValue(packet, mDefaultValue); 146 if (deviceProp) 147 readValue(packet, mCurrentValue); 148 } 149 if (!deviceProp) 150 mGroupCode = packet.getUInt32(); 151 mFormFlag = packet.getUInt8(); 152 153 if (mFormFlag == kFormRange) { 154 readValue(packet, mMinimumValue); 155 readValue(packet, mMaximumValue); 156 readValue(packet, mStepSize); 157 } else if (mFormFlag == kFormEnum) { 158 mEnumLength = packet.getUInt16(); 159 mEnumValues = new MtpPropertyValue[mEnumLength]; 160 for (int i = 0; i < mEnumLength; i++) 161 readValue(packet, mEnumValues[i]); 162 } 163} 164 165void MtpProperty::write(MtpDataPacket& packet) { 166 bool deviceProp = isDeviceProperty(); 167 168 packet.putUInt16(mCode); 169 packet.putUInt16(mType); 170 packet.putUInt8(mWriteable ? 1 : 0); 171 172 switch (mType) { 173 case MTP_TYPE_AINT8: 174 case MTP_TYPE_AUINT8: 175 case MTP_TYPE_AINT16: 176 case MTP_TYPE_AUINT16: 177 case MTP_TYPE_AINT32: 178 case MTP_TYPE_AUINT32: 179 case MTP_TYPE_AINT64: 180 case MTP_TYPE_AUINT64: 181 case MTP_TYPE_AINT128: 182 case MTP_TYPE_AUINT128: 183 writeArrayValues(packet, mDefaultArrayValues, mDefaultArrayLength); 184 if (deviceProp) 185 writeArrayValues(packet, mCurrentArrayValues, mCurrentArrayLength); 186 break; 187 default: 188 writeValue(packet, mDefaultValue); 189 if (deviceProp) 190 writeValue(packet, mCurrentValue); 191 } 192 packet.putUInt32(mGroupCode); 193 if (!deviceProp) 194 packet.putUInt8(mFormFlag); 195 if (mFormFlag == kFormRange) { 196 writeValue(packet, mMinimumValue); 197 writeValue(packet, mMaximumValue); 198 writeValue(packet, mStepSize); 199 } else if (mFormFlag == kFormEnum) { 200 packet.putUInt16(mEnumLength); 201 for (int i = 0; i < mEnumLength; i++) 202 writeValue(packet, mEnumValues[i]); 203 } 204} 205 206void MtpProperty::setDefaultValue(const uint16_t* string) { 207 free(mDefaultValue.str); 208 if (string) { 209 MtpStringBuffer buffer(string); 210 mDefaultValue.str = strdup(buffer); 211 } 212 else 213 mDefaultValue.str = NULL; 214} 215 216void MtpProperty::setCurrentValue(const uint16_t* string) { 217 free(mCurrentValue.str); 218 if (string) { 219 MtpStringBuffer buffer(string); 220 mCurrentValue.str = strdup(buffer); 221 } 222 else 223 mCurrentValue.str = NULL; 224} 225 226void MtpProperty::setFormRange(int min, int max, int step) { 227 mFormFlag = kFormRange; 228 switch (mType) { 229 case MTP_TYPE_INT8: 230 mMinimumValue.u.i8 = min; 231 mMaximumValue.u.i8 = max; 232 mStepSize.u.i8 = step; 233 break; 234 case MTP_TYPE_UINT8: 235 mMinimumValue.u.u8 = min; 236 mMaximumValue.u.u8 = max; 237 mStepSize.u.u8 = step; 238 break; 239 case MTP_TYPE_INT16: 240 mMinimumValue.u.i16 = min; 241 mMaximumValue.u.i16 = max; 242 mStepSize.u.i16 = step; 243 break; 244 case MTP_TYPE_UINT16: 245 mMinimumValue.u.u16 = min; 246 mMaximumValue.u.u16 = max; 247 mStepSize.u.u16 = step; 248 break; 249 case MTP_TYPE_INT32: 250 mMinimumValue.u.i32 = min; 251 mMaximumValue.u.i32 = max; 252 mStepSize.u.i32 = step; 253 break; 254 case MTP_TYPE_UINT32: 255 mMinimumValue.u.u32 = min; 256 mMaximumValue.u.u32 = max; 257 mStepSize.u.u32 = step; 258 break; 259 case MTP_TYPE_INT64: 260 mMinimumValue.u.i64 = min; 261 mMaximumValue.u.i64 = max; 262 mStepSize.u.i64 = step; 263 break; 264 case MTP_TYPE_UINT64: 265 mMinimumValue.u.u64 = min; 266 mMaximumValue.u.u64 = max; 267 mStepSize.u.u64 = step; 268 break; 269 default: 270 LOGE("unsupported type for MtpProperty::setRange"); 271 break; 272 } 273} 274 275void MtpProperty::setFormEnum(const int* values, int count) { 276 mFormFlag = kFormEnum; 277 delete[] mEnumValues; 278 mEnumValues = new MtpPropertyValue[count]; 279 mEnumLength = count; 280 281 for (int i = 0; i < count; i++) { 282 int value = *values++; 283 switch (mType) { 284 case MTP_TYPE_INT8: 285 mEnumValues[i].u.i8 = value; 286 break; 287 case MTP_TYPE_UINT8: 288 mEnumValues[i].u.u8 = value; 289 break; 290 case MTP_TYPE_INT16: 291 mEnumValues[i].u.i16 = value; 292 break; 293 case MTP_TYPE_UINT16: 294 mEnumValues[i].u.u16 = value; 295 break; 296 case MTP_TYPE_INT32: 297 mEnumValues[i].u.i32 = value; 298 break; 299 case MTP_TYPE_UINT32: 300 mEnumValues[i].u.u32 = value; 301 break; 302 case MTP_TYPE_INT64: 303 mEnumValues[i].u.i64 = value; 304 break; 305 case MTP_TYPE_UINT64: 306 mEnumValues[i].u.u64 = value; 307 break; 308 default: 309 LOGE("unsupported type for MtpProperty::setEnum"); 310 break; 311 } 312 } 313} 314 315void MtpProperty::setFormDateTime() { 316 mFormFlag = kFormDateTime; 317} 318 319void MtpProperty::print() { 320 LOGV("MtpProperty %04X\n", mCode); 321 LOGV(" type %04X\n", mType); 322 LOGV(" writeable %s\n", (mWriteable ? "true" : "false")); 323} 324 325void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) { 326 MtpStringBuffer stringBuffer; 327 328 switch (mType) { 329 case MTP_TYPE_INT8: 330 case MTP_TYPE_AINT8: 331 value.u.i8 = packet.getInt8(); 332 break; 333 case MTP_TYPE_UINT8: 334 case MTP_TYPE_AUINT8: 335 value.u.u8 = packet.getUInt8(); 336 break; 337 case MTP_TYPE_INT16: 338 case MTP_TYPE_AINT16: 339 value.u.i16 = packet.getInt16(); 340 break; 341 case MTP_TYPE_UINT16: 342 case MTP_TYPE_AUINT16: 343 value.u.u16 = packet.getUInt16(); 344 break; 345 case MTP_TYPE_INT32: 346 case MTP_TYPE_AINT32: 347 value.u.i32 = packet.getInt32(); 348 break; 349 case MTP_TYPE_UINT32: 350 case MTP_TYPE_AUINT32: 351 value.u.u32 = packet.getUInt32(); 352 break; 353 case MTP_TYPE_INT64: 354 case MTP_TYPE_AINT64: 355 value.u.i64 = packet.getInt64(); 356 break; 357 case MTP_TYPE_UINT64: 358 case MTP_TYPE_AUINT64: 359 value.u.u64 = packet.getUInt64(); 360 break; 361 case MTP_TYPE_INT128: 362 case MTP_TYPE_AINT128: 363 packet.getInt128(value.u.i128); 364 break; 365 case MTP_TYPE_UINT128: 366 case MTP_TYPE_AUINT128: 367 packet.getUInt128(value.u.u128); 368 break; 369 case MTP_TYPE_STR: 370 packet.getString(stringBuffer); 371 value.str = strdup(stringBuffer); 372 break; 373 default: 374 LOGE("unknown type %04X in MtpProperty::readValue", mType); 375 } 376} 377 378void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) { 379 MtpStringBuffer stringBuffer; 380 381 switch (mType) { 382 case MTP_TYPE_INT8: 383 case MTP_TYPE_AINT8: 384 packet.putInt8(value.u.i8); 385 break; 386 case MTP_TYPE_UINT8: 387 case MTP_TYPE_AUINT8: 388 packet.putUInt8(value.u.u8); 389 break; 390 case MTP_TYPE_INT16: 391 case MTP_TYPE_AINT16: 392 packet.putInt16(value.u.i16); 393 break; 394 case MTP_TYPE_UINT16: 395 case MTP_TYPE_AUINT16: 396 packet.putUInt16(value.u.u16); 397 break; 398 case MTP_TYPE_INT32: 399 case MTP_TYPE_AINT32: 400 packet.putInt32(value.u.i32); 401 break; 402 case MTP_TYPE_UINT32: 403 case MTP_TYPE_AUINT32: 404 packet.putUInt32(value.u.u32); 405 break; 406 case MTP_TYPE_INT64: 407 case MTP_TYPE_AINT64: 408 packet.putInt64(value.u.i64); 409 break; 410 case MTP_TYPE_UINT64: 411 case MTP_TYPE_AUINT64: 412 packet.putUInt64(value.u.u64); 413 break; 414 case MTP_TYPE_INT128: 415 case MTP_TYPE_AINT128: 416 packet.putInt128(value.u.i128); 417 break; 418 case MTP_TYPE_UINT128: 419 case MTP_TYPE_AUINT128: 420 packet.putUInt128(value.u.u128); 421 break; 422 case MTP_TYPE_STR: 423 if (value.str) 424 packet.putString(value.str); 425 else 426 packet.putEmptyString(); 427 break; 428 default: 429 LOGE("unknown type %04X in MtpProperty::writeValue", mType); 430 } 431} 432 433MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& length) { 434 length = packet.getUInt32(); 435 if (length == 0) 436 return NULL; 437 MtpPropertyValue* result = new MtpPropertyValue[length]; 438 for (int i = 0; i < length; i++) 439 readValue(packet, result[i]); 440 return result; 441} 442 443void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length) { 444 packet.putUInt32(length); 445 for (int i = 0; i < length; i++) 446 writeValue(packet, values[i]); 447} 448 449} // namespace android 450