MtpProperty.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  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. #define LOG_TAG "MtpProperty"
  17. #include <inttypes.h>
  18. #include <cutils/compiler.h>
  19. #include <iomanip>
  20. #include <sstream>
  21. #include <string>
  22. #include "MtpDataPacket.h"
  23. #include "MtpDebug.h"
  24. #include "MtpProperty.h"
  25. #include "MtpStringBuffer.h"
  26. #include "MtpUtils.h"
  27. namespace android {
  28. MtpProperty::MtpProperty()
  29. : mCode(0),
  30. mType(0),
  31. mWriteable(false),
  32. mDefaultArrayLength(0),
  33. mDefaultArrayValues(NULL),
  34. mCurrentArrayLength(0),
  35. mCurrentArrayValues(NULL),
  36. mGroupCode(0),
  37. mFormFlag(kFormNone),
  38. mEnumLength(0),
  39. mEnumValues(NULL)
  40. {
  41. memset(&mDefaultValue, 0, sizeof(mDefaultValue));
  42. memset(&mCurrentValue, 0, sizeof(mCurrentValue));
  43. memset(&mMinimumValue, 0, sizeof(mMinimumValue));
  44. memset(&mMaximumValue, 0, sizeof(mMaximumValue));
  45. }
  46. MtpProperty::MtpProperty(MtpPropertyCode propCode,
  47. MtpDataType type,
  48. bool writeable,
  49. int defaultValue)
  50. : mCode(propCode),
  51. mType(type),
  52. mWriteable(writeable),
  53. mDefaultArrayLength(0),
  54. mDefaultArrayValues(NULL),
  55. mCurrentArrayLength(0),
  56. mCurrentArrayValues(NULL),
  57. mGroupCode(0),
  58. mFormFlag(kFormNone),
  59. mEnumLength(0),
  60. mEnumValues(NULL)
  61. {
  62. memset(&mDefaultValue, 0, sizeof(mDefaultValue));
  63. memset(&mCurrentValue, 0, sizeof(mCurrentValue));
  64. memset(&mMinimumValue, 0, sizeof(mMinimumValue));
  65. memset(&mMaximumValue, 0, sizeof(mMaximumValue));
  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. ALOGE("unknown type %04X in MtpProperty::MtpProperty", type);
  94. }
  95. }
  96. }
  97. MtpProperty::~MtpProperty() {
  98. if (mType == MTP_TYPE_STR) {
  99. // free all strings
  100. free(mDefaultValue.str);
  101. free(mCurrentValue.str);
  102. free(mMinimumValue.str);
  103. free(mMaximumValue.str);
  104. if (mDefaultArrayValues) {
  105. for (uint32_t i = 0; i < mDefaultArrayLength; i++)
  106. free(mDefaultArrayValues[i].str);
  107. }
  108. if (mCurrentArrayValues) {
  109. for (uint32_t i = 0; i < mCurrentArrayLength; i++)
  110. free(mCurrentArrayValues[i].str);
  111. }
  112. if (mEnumValues) {
  113. for (uint16_t i = 0; i < mEnumLength; i++)
  114. free(mEnumValues[i].str);
  115. }
  116. }
  117. delete[] mDefaultArrayValues;
  118. delete[] mCurrentArrayValues;
  119. delete[] mEnumValues;
  120. }
  121. bool MtpProperty::read(MtpDataPacket& packet) {
  122. uint8_t temp8;
  123. if (!packet.getUInt16(mCode)) return false;
  124. bool deviceProp = isDeviceProperty();
  125. if (!packet.getUInt16(mType)) return false;
  126. if (!packet.getUInt8(temp8)) return false;
  127. mWriteable = (temp8 == 1);
  128. switch (mType) {
  129. case MTP_TYPE_AINT8:
  130. case MTP_TYPE_AUINT8:
  131. case MTP_TYPE_AINT16:
  132. case MTP_TYPE_AUINT16:
  133. case MTP_TYPE_AINT32:
  134. case MTP_TYPE_AUINT32:
  135. case MTP_TYPE_AINT64:
  136. case MTP_TYPE_AUINT64:
  137. case MTP_TYPE_AINT128:
  138. case MTP_TYPE_AUINT128:
  139. mDefaultArrayValues = readArrayValues(packet, mDefaultArrayLength);
  140. if (!mDefaultArrayValues) return false;
  141. if (deviceProp) {
  142. mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength);
  143. if (!mCurrentArrayValues) return false;
  144. }
  145. break;
  146. default:
  147. if (!readValue(packet, mDefaultValue)) return false;
  148. if (deviceProp) {
  149. if (!readValue(packet, mCurrentValue)) return false;
  150. }
  151. }
  152. if (!deviceProp) {
  153. if (!packet.getUInt32(mGroupCode)) return false;
  154. }
  155. if (!packet.getUInt8(mFormFlag)) return false;
  156. if (mFormFlag == kFormRange) {
  157. if (!readValue(packet, mMinimumValue)) return false;
  158. if (!readValue(packet, mMaximumValue)) return false;
  159. if (!readValue(packet, mStepSize)) return false;
  160. } else if (mFormFlag == kFormEnum) {
  161. if (!packet.getUInt16(mEnumLength)) return false;
  162. mEnumValues = new MtpPropertyValue[mEnumLength];
  163. for (int i = 0; i < mEnumLength; i++) {
  164. if (!readValue(packet, mEnumValues[i])) return false;
  165. }
  166. }
  167. return true;
  168. }
  169. void MtpProperty::write(MtpDataPacket& packet) {
  170. bool deviceProp = isDeviceProperty();
  171. packet.putUInt16(mCode);
  172. packet.putUInt16(mType);
  173. packet.putUInt8(mWriteable ? 1 : 0);
  174. switch (mType) {
  175. case MTP_TYPE_AINT8:
  176. case MTP_TYPE_AUINT8:
  177. case MTP_TYPE_AINT16:
  178. case MTP_TYPE_AUINT16:
  179. case MTP_TYPE_AINT32:
  180. case MTP_TYPE_AUINT32:
  181. case MTP_TYPE_AINT64:
  182. case MTP_TYPE_AUINT64:
  183. case MTP_TYPE_AINT128:
  184. case MTP_TYPE_AUINT128:
  185. writeArrayValues(packet, mDefaultArrayValues, mDefaultArrayLength);
  186. if (deviceProp)
  187. writeArrayValues(packet, mCurrentArrayValues, mCurrentArrayLength);
  188. break;
  189. default:
  190. writeValue(packet, mDefaultValue);
  191. if (deviceProp)
  192. writeValue(packet, mCurrentValue);
  193. }
  194. if (!deviceProp)
  195. packet.putUInt32(mGroupCode);
  196. packet.putUInt8(mFormFlag);
  197. if (mFormFlag == kFormRange) {
  198. writeValue(packet, mMinimumValue);
  199. writeValue(packet, mMaximumValue);
  200. writeValue(packet, mStepSize);
  201. } else if (mFormFlag == kFormEnum) {
  202. packet.putUInt16(mEnumLength);
  203. for (int i = 0; i < mEnumLength; i++)
  204. writeValue(packet, mEnumValues[i]);
  205. }
  206. }
  207. void MtpProperty::setDefaultValue(const uint16_t* string) {
  208. free(mDefaultValue.str);
  209. if (string) {
  210. MtpStringBuffer buffer(string);
  211. mDefaultValue.str = strdup(buffer);
  212. }
  213. else
  214. mDefaultValue.str = NULL;
  215. }
  216. void 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. void MtpProperty::setCurrentValue(MtpDataPacket& packet) {
  226. free(mCurrentValue.str);
  227. mCurrentValue.str = NULL;
  228. readValue(packet, mCurrentValue);
  229. }
  230. void MtpProperty::setFormRange(int min, int max, int step) {
  231. mFormFlag = kFormRange;
  232. switch (mType) {
  233. case MTP_TYPE_INT8:
  234. mMinimumValue.u.i8 = min;
  235. mMaximumValue.u.i8 = max;
  236. mStepSize.u.i8 = step;
  237. break;
  238. case MTP_TYPE_UINT8:
  239. mMinimumValue.u.u8 = min;
  240. mMaximumValue.u.u8 = max;
  241. mStepSize.u.u8 = step;
  242. break;
  243. case MTP_TYPE_INT16:
  244. mMinimumValue.u.i16 = min;
  245. mMaximumValue.u.i16 = max;
  246. mStepSize.u.i16 = step;
  247. break;
  248. case MTP_TYPE_UINT16:
  249. mMinimumValue.u.u16 = min;
  250. mMaximumValue.u.u16 = max;
  251. mStepSize.u.u16 = step;
  252. break;
  253. case MTP_TYPE_INT32:
  254. mMinimumValue.u.i32 = min;
  255. mMaximumValue.u.i32 = max;
  256. mStepSize.u.i32 = step;
  257. break;
  258. case MTP_TYPE_UINT32:
  259. mMinimumValue.u.u32 = min;
  260. mMaximumValue.u.u32 = max;
  261. mStepSize.u.u32 = step;
  262. break;
  263. case MTP_TYPE_INT64:
  264. mMinimumValue.u.i64 = min;
  265. mMaximumValue.u.i64 = max;
  266. mStepSize.u.i64 = step;
  267. break;
  268. case MTP_TYPE_UINT64:
  269. mMinimumValue.u.u64 = min;
  270. mMaximumValue.u.u64 = max;
  271. mStepSize.u.u64 = step;
  272. break;
  273. default:
  274. ALOGE("unsupported type for MtpProperty::setRange");
  275. break;
  276. }
  277. }
  278. void MtpProperty::setFormEnum(const int* values, int count) {
  279. mFormFlag = kFormEnum;
  280. delete[] mEnumValues;
  281. mEnumValues = new MtpPropertyValue[count];
  282. mEnumLength = count;
  283. for (int i = 0; i < count; i++) {
  284. int value = *values++;
  285. switch (mType) {
  286. case MTP_TYPE_INT8:
  287. mEnumValues[i].u.i8 = value;
  288. break;
  289. case MTP_TYPE_UINT8:
  290. mEnumValues[i].u.u8 = value;
  291. break;
  292. case MTP_TYPE_INT16:
  293. mEnumValues[i].u.i16 = value;
  294. break;
  295. case MTP_TYPE_UINT16:
  296. mEnumValues[i].u.u16 = value;
  297. break;
  298. case MTP_TYPE_INT32:
  299. mEnumValues[i].u.i32 = value;
  300. break;
  301. case MTP_TYPE_UINT32:
  302. mEnumValues[i].u.u32 = value;
  303. break;
  304. case MTP_TYPE_INT64:
  305. mEnumValues[i].u.i64 = value;
  306. break;
  307. case MTP_TYPE_UINT64:
  308. mEnumValues[i].u.u64 = value;
  309. break;
  310. default:
  311. ALOGE("unsupported type for MtpProperty::setEnum");
  312. break;
  313. }
  314. }
  315. }
  316. void MtpProperty::setFormDateTime() {
  317. mFormFlag = kFormDateTime;
  318. }
  319. void MtpProperty::print() {
  320. std::string buffer;
  321. bool deviceProp = isDeviceProperty();
  322. if (deviceProp)
  323. ALOGI(" %s (%04X)", MtpDebug::getDevicePropCodeName(mCode), mCode);
  324. else
  325. ALOGI(" %s (%04X)", MtpDebug::getObjectPropCodeName(mCode), mCode);
  326. ALOGI(" type %04X", mType);
  327. ALOGI(" writeable %s", (mWriteable ? "true" : "false"));
  328. buffer = " default value: ";
  329. print(mDefaultValue, buffer);
  330. ALOGI("%s", buffer.c_str());
  331. if (deviceProp) {
  332. buffer = " current value: ";
  333. print(mCurrentValue, buffer);
  334. ALOGI("%s", buffer.c_str());
  335. }
  336. switch (mFormFlag) {
  337. case kFormNone:
  338. break;
  339. case kFormRange:
  340. buffer = " Range (";
  341. print(mMinimumValue, buffer);
  342. buffer += ", ";
  343. print(mMaximumValue, buffer);
  344. buffer += ", ";
  345. print(mStepSize, buffer);
  346. buffer += ")";
  347. ALOGI("%s", buffer.c_str());
  348. break;
  349. case kFormEnum:
  350. buffer = " Enum { ";
  351. for (int i = 0; i < mEnumLength; i++) {
  352. print(mEnumValues[i], buffer);
  353. buffer += " ";
  354. }
  355. buffer += "}";
  356. ALOGI("%s", buffer.c_str());
  357. break;
  358. case kFormDateTime:
  359. ALOGI(" DateTime\n");
  360. break;
  361. default:
  362. ALOGI(" form %d\n", mFormFlag);
  363. break;
  364. }
  365. }
  366. void MtpProperty::print(MtpPropertyValue& value, std::string& buffer) {
  367. std::ostringstream s;
  368. switch (mType) {
  369. case MTP_TYPE_INT8:
  370. buffer += std::to_string(value.u.i8);
  371. break;
  372. case MTP_TYPE_UINT8:
  373. buffer += std::to_string(value.u.u8);
  374. break;
  375. case MTP_TYPE_INT16:
  376. buffer += std::to_string(value.u.i16);
  377. break;
  378. case MTP_TYPE_UINT16:
  379. buffer += std::to_string(value.u.u16);
  380. break;
  381. case MTP_TYPE_INT32:
  382. buffer += std::to_string(value.u.i32);
  383. break;
  384. case MTP_TYPE_UINT32:
  385. buffer += std::to_string(value.u.u32);
  386. break;
  387. case MTP_TYPE_INT64:
  388. buffer += std::to_string(value.u.i64);
  389. break;
  390. case MTP_TYPE_UINT64:
  391. buffer += std::to_string(value.u.u64);
  392. break;
  393. case MTP_TYPE_INT128:
  394. for (auto i : value.u.i128) {
  395. s << std::hex << std::setfill('0') << std::uppercase << i;
  396. }
  397. buffer += s.str();
  398. break;
  399. case MTP_TYPE_UINT128:
  400. for (auto i : value.u.u128) {
  401. s << std::hex << std::setfill('0') << std::uppercase << i;
  402. }
  403. buffer += s.str();
  404. break;
  405. case MTP_TYPE_STR:
  406. buffer += value.str;
  407. break;
  408. default:
  409. ALOGE("unsupported type for MtpProperty::print\n");
  410. break;
  411. }
  412. }
  413. bool MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) {
  414. MtpStringBuffer stringBuffer;
  415. switch (mType) {
  416. case MTP_TYPE_INT8:
  417. case MTP_TYPE_AINT8:
  418. if (!packet.getInt8(value.u.i8)) return false;
  419. break;
  420. case MTP_TYPE_UINT8:
  421. case MTP_TYPE_AUINT8:
  422. if (!packet.getUInt8(value.u.u8)) return false;
  423. break;
  424. case MTP_TYPE_INT16:
  425. case MTP_TYPE_AINT16:
  426. if (!packet.getInt16(value.u.i16)) return false;
  427. break;
  428. case MTP_TYPE_UINT16:
  429. case MTP_TYPE_AUINT16:
  430. if (!packet.getUInt16(value.u.u16)) return false;
  431. break;
  432. case MTP_TYPE_INT32:
  433. case MTP_TYPE_AINT32:
  434. if (!packet.getInt32(value.u.i32)) return false;
  435. break;
  436. case MTP_TYPE_UINT32:
  437. case MTP_TYPE_AUINT32:
  438. if (!packet.getUInt32(value.u.u32)) return false;
  439. break;
  440. case MTP_TYPE_INT64:
  441. case MTP_TYPE_AINT64:
  442. if (!packet.getInt64(value.u.i64)) return false;
  443. break;
  444. case MTP_TYPE_UINT64:
  445. case MTP_TYPE_AUINT64:
  446. if (!packet.getUInt64(value.u.u64)) return false;
  447. break;
  448. case MTP_TYPE_INT128:
  449. case MTP_TYPE_AINT128:
  450. if (!packet.getInt128(value.u.i128)) return false;
  451. break;
  452. case MTP_TYPE_UINT128:
  453. case MTP_TYPE_AUINT128:
  454. if (!packet.getUInt128(value.u.u128)) return false;
  455. break;
  456. case MTP_TYPE_STR:
  457. if (!packet.getString(stringBuffer)) return false;
  458. value.str = strdup(stringBuffer);
  459. break;
  460. default:
  461. ALOGE("unknown type %04X in MtpProperty::readValue", mType);
  462. return false;
  463. }
  464. return true;
  465. }
  466. void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) {
  467. MtpStringBuffer stringBuffer;
  468. switch (mType) {
  469. case MTP_TYPE_INT8:
  470. case MTP_TYPE_AINT8:
  471. packet.putInt8(value.u.i8);
  472. break;
  473. case MTP_TYPE_UINT8:
  474. case MTP_TYPE_AUINT8:
  475. packet.putUInt8(value.u.u8);
  476. break;
  477. case MTP_TYPE_INT16:
  478. case MTP_TYPE_AINT16:
  479. packet.putInt16(value.u.i16);
  480. break;
  481. case MTP_TYPE_UINT16:
  482. case MTP_TYPE_AUINT16:
  483. packet.putUInt16(value.u.u16);
  484. break;
  485. case MTP_TYPE_INT32:
  486. case MTP_TYPE_AINT32:
  487. packet.putInt32(value.u.i32);
  488. break;
  489. case MTP_TYPE_UINT32:
  490. case MTP_TYPE_AUINT32:
  491. packet.putUInt32(value.u.u32);
  492. break;
  493. case MTP_TYPE_INT64:
  494. case MTP_TYPE_AINT64:
  495. packet.putInt64(value.u.i64);
  496. break;
  497. case MTP_TYPE_UINT64:
  498. case MTP_TYPE_AUINT64:
  499. packet.putUInt64(value.u.u64);
  500. break;
  501. case MTP_TYPE_INT128:
  502. case MTP_TYPE_AINT128:
  503. packet.putInt128(value.u.i128);
  504. break;
  505. case MTP_TYPE_UINT128:
  506. case MTP_TYPE_AUINT128:
  507. packet.putUInt128(value.u.u128);
  508. break;
  509. case MTP_TYPE_STR:
  510. if (value.str)
  511. packet.putString(value.str);
  512. else
  513. packet.putEmptyString();
  514. break;
  515. default:
  516. ALOGE("unknown type %04X in MtpProperty::writeValue", mType);
  517. }
  518. }
  519. MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, uint32_t& length) {
  520. if (!packet.getUInt32(length)) return NULL;
  521. // Fail if resulting array is over 2GB. This is because the maximum array
  522. // size may be less than SIZE_MAX on some platforms.
  523. if ( CC_UNLIKELY(
  524. length == 0 ||
  525. length >= INT32_MAX / sizeof(MtpPropertyValue)) ) {
  526. length = 0;
  527. return NULL;
  528. }
  529. MtpPropertyValue* result = new MtpPropertyValue[length];
  530. for (uint32_t i = 0; i < length; i++)
  531. if (!readValue(packet, result[i])) {
  532. delete [] result;
  533. return NULL;
  534. }
  535. return result;
  536. }
  537. void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, uint32_t length) {
  538. packet.putUInt32(length);
  539. for (uint32_t i = 0; i < length; i++)
  540. writeValue(packet, values[i]);
  541. }
  542. } // namespace android