qmi_encdec.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877
  1. /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. */
  13. #include <linux/slab.h>
  14. #include <linux/uaccess.h>
  15. #include <linux/module.h>
  16. #include <linux/kernel.h>
  17. #include <linux/errno.h>
  18. #include <linux/io.h>
  19. #include <linux/string.h>
  20. #include <linux/qmi_encdec.h>
  21. #include "qmi_encdec_priv.h"
  22. #define TLV_LEN_SIZE sizeof(uint16_t)
  23. #define TLV_TYPE_SIZE sizeof(uint8_t)
  24. #define OPTIONAL_TLV_TYPE_START 0x10
  25. #ifdef CONFIG_QMI_ENCDEC_DEBUG
  26. #define qmi_encdec_dump(prefix_str, buf, buf_len) do { \
  27. const u8 *ptr = buf; \
  28. int i, linelen, remaining = buf_len; \
  29. int rowsize = 16, groupsize = 1; \
  30. unsigned char linebuf[256]; \
  31. for (i = 0; i < buf_len; i += rowsize) { \
  32. linelen = min(remaining, rowsize); \
  33. remaining -= linelen; \
  34. hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize, \
  35. linebuf, sizeof(linebuf), false); \
  36. pr_debug("%s: %s\n", prefix_str, linebuf); \
  37. } \
  38. } while (0)
  39. #define QMI_ENCODE_LOG_MSG(buf, buf_len) \
  40. qmi_encdec_dump("QMI_ENCODE_MSG", buf, buf_len)
  41. #define QMI_DECODE_LOG_MSG(buf, buf_len) \
  42. qmi_encdec_dump("QMI_DECODE_MSG", buf, buf_len)
  43. #define QMI_ENCODE_LOG_ELEM(level, elem_len, elem_size, buf) do { \
  44. pr_debug("QMI_ENCODE_ELEM lvl: %d, len: %d, size: %d\n", \
  45. level, elem_len, elem_size); \
  46. qmi_encdec_dump("QMI_ENCODE_ELEM", buf, (elem_len * elem_size)); \
  47. } while (0)
  48. #define QMI_DECODE_LOG_ELEM(level, elem_len, elem_size, buf) do { \
  49. pr_debug("QMI_DECODE_ELEM lvl: %d, len: %d, size: %d\n", \
  50. level, elem_len, elem_size); \
  51. qmi_encdec_dump("QMI_DECODE_ELEM", buf, (elem_len * elem_size)); \
  52. } while (0)
  53. #define QMI_ENCODE_LOG_TLV(tlv_type, tlv_len) \
  54. pr_debug("QMI_ENCODE_TLV type: %d, len: %d\n", tlv_type, tlv_len)
  55. #define QMI_DECODE_LOG_TLV(tlv_type, tlv_len) \
  56. pr_debug("QMI_DECODE_TLV type: %d, len: %d\n", tlv_type, tlv_len)
  57. #else
  58. #define QMI_ENCODE_LOG_MSG(buf, buf_len) { }
  59. #define QMI_DECODE_LOG_MSG(buf, buf_len) { }
  60. #define QMI_ENCODE_LOG_ELEM(level, elem_len, elem_size, buf) { }
  61. #define QMI_DECODE_LOG_ELEM(level, elem_len, elem_size, buf) { }
  62. #define QMI_ENCODE_LOG_TLV(tlv_type, tlv_len) { }
  63. #define QMI_DECODE_LOG_TLV(tlv_type, tlv_len) { }
  64. #endif
  65. static int _qmi_kernel_encode(struct elem_info *ei_array,
  66. void *out_buf, void *in_c_struct,
  67. uint32_t out_buf_len, int enc_level);
  68. static int _qmi_kernel_decode(struct elem_info *ei_array,
  69. void *out_c_struct,
  70. void *in_buf, uint32_t in_buf_len,
  71. int dec_level);
  72. static struct elem_info *skip_to_next_elem(struct elem_info *ei_array,
  73. int level);
  74. /**
  75. * qmi_calc_max_msg_len() - Calculate the maximum length of a QMI message
  76. * @ei_array: Struct info array describing the structure.
  77. * @level: Level to identify the depth of the nested structures.
  78. *
  79. * @return: expected maximum length of the QMI message or 0 on failure.
  80. */
  81. static int qmi_calc_max_msg_len(struct elem_info *ei_array,
  82. int level)
  83. {
  84. int max_msg_len = 0;
  85. struct elem_info *temp_ei;
  86. if (!ei_array)
  87. return max_msg_len;
  88. for (temp_ei = ei_array; temp_ei->data_type != QMI_EOTI; temp_ei++) {
  89. /* Flag to identify the optional element is not encoded */
  90. if (temp_ei->data_type == QMI_OPT_FLAG)
  91. continue;
  92. if (temp_ei->data_type == QMI_DATA_LEN) {
  93. max_msg_len += (temp_ei->elem_size == sizeof(uint8_t) ?
  94. sizeof(uint8_t) : sizeof(uint16_t));
  95. continue;
  96. } else if (temp_ei->data_type == QMI_STRUCT) {
  97. max_msg_len += (temp_ei->elem_len *
  98. qmi_calc_max_msg_len(temp_ei->ei_array,
  99. (level + 1)));
  100. } else if (temp_ei->data_type == QMI_STRING) {
  101. if (level > 1)
  102. max_msg_len += temp_ei->elem_len <= U8_MAX ?
  103. sizeof(uint8_t) : sizeof(uint16_t);
  104. max_msg_len += temp_ei->elem_len * temp_ei->elem_size;
  105. } else {
  106. max_msg_len += (temp_ei->elem_len * temp_ei->elem_size);
  107. }
  108. /*
  109. * Type & Length info. not prepended for elements in the
  110. * nested structure.
  111. */
  112. if (level == 1)
  113. max_msg_len += (TLV_TYPE_SIZE + TLV_LEN_SIZE);
  114. }
  115. return max_msg_len;
  116. }
  117. /**
  118. * qmi_calc_min_msg_len() - Calculate the minimum length of a QMI message
  119. * @ei_array: Struct info array describing the structure.
  120. * @level: Level to identify the depth of the nested structures.
  121. *
  122. * @return: expected minimum length of the QMI message or 0 on failure.
  123. */
  124. static int qmi_calc_min_msg_len(struct elem_info *ei_array,
  125. int level)
  126. {
  127. int min_msg_len = 0;
  128. struct elem_info *temp_ei = ei_array;
  129. if (!ei_array)
  130. return min_msg_len;
  131. while (temp_ei->data_type != QMI_EOTI) {
  132. /* Optional elements do not count in minimum length */
  133. if (temp_ei->data_type == QMI_OPT_FLAG) {
  134. temp_ei = skip_to_next_elem(temp_ei, level);
  135. continue;
  136. }
  137. if (temp_ei->data_type == QMI_DATA_LEN) {
  138. min_msg_len += (temp_ei->elem_size == sizeof(uint8_t) ?
  139. sizeof(uint8_t) : sizeof(uint16_t));
  140. temp_ei++;
  141. continue;
  142. } else if (temp_ei->data_type == QMI_STRUCT) {
  143. min_msg_len += qmi_calc_min_msg_len(temp_ei->ei_array,
  144. (level + 1));
  145. temp_ei++;
  146. } else if (temp_ei->data_type == QMI_STRING) {
  147. if (level > 1)
  148. min_msg_len += temp_ei->elem_len <= U8_MAX ?
  149. sizeof(uint8_t) : sizeof(uint16_t);
  150. min_msg_len += temp_ei->elem_len * temp_ei->elem_size;
  151. temp_ei++;
  152. } else {
  153. min_msg_len += (temp_ei->elem_len * temp_ei->elem_size);
  154. temp_ei++;
  155. }
  156. /*
  157. * Type & Length info. not prepended for elements in the
  158. * nested structure.
  159. */
  160. if (level == 1)
  161. min_msg_len += (TLV_TYPE_SIZE + TLV_LEN_SIZE);
  162. }
  163. return min_msg_len;
  164. }
  165. /**
  166. * qmi_verify_max_msg_len() - Verify the maximum length of a QMI message
  167. * @desc: Pointer to structure descriptor.
  168. *
  169. * @return: true if the maximum message length embedded in structure
  170. * descriptor matches the calculated value, else false.
  171. */
  172. bool qmi_verify_max_msg_len(struct msg_desc *desc)
  173. {
  174. int calc_max_msg_len;
  175. if (!desc)
  176. return false;
  177. calc_max_msg_len = qmi_calc_max_msg_len(desc->ei_array, 1);
  178. if (calc_max_msg_len != desc->max_msg_len) {
  179. pr_err("%s: Calc. len %d != Passed len %d\n",
  180. __func__, calc_max_msg_len, desc->max_msg_len);
  181. return false;
  182. }
  183. return true;
  184. }
  185. /**
  186. * qmi_kernel_encode() - Encode to QMI message wire format
  187. * @desc: Pointer to structure descriptor.
  188. * @out_buf: Buffer to hold the encoded QMI message.
  189. * @out_buf_len: Length of the out buffer.
  190. * @in_c_struct: C Structure to be encoded.
  191. *
  192. * @return: size of encoded message on success, < 0 for error.
  193. */
  194. int qmi_kernel_encode(struct msg_desc *desc,
  195. void *out_buf, uint32_t out_buf_len,
  196. void *in_c_struct)
  197. {
  198. int enc_level = 1;
  199. int ret, calc_max_msg_len, calc_min_msg_len;
  200. if (!desc)
  201. return -EINVAL;
  202. /* Check the possibility of a zero length QMI message */
  203. if (!in_c_struct) {
  204. calc_min_msg_len = qmi_calc_min_msg_len(desc->ei_array, 1);
  205. if (calc_min_msg_len) {
  206. pr_err("%s: Calc. len %d != 0, but NULL in_c_struct\n",
  207. __func__, calc_min_msg_len);
  208. return -EINVAL;
  209. } else {
  210. return 0;
  211. }
  212. }
  213. /*
  214. * Not a zero-length message. Ensure the output buffer and
  215. * element information array are not NULL.
  216. */
  217. if (!out_buf || !desc->ei_array)
  218. return -EINVAL;
  219. if (desc->max_msg_len < out_buf_len)
  220. return -ETOOSMALL;
  221. ret = _qmi_kernel_encode(desc->ei_array, out_buf,
  222. in_c_struct, out_buf_len, enc_level);
  223. if (ret == -ETOOSMALL) {
  224. calc_max_msg_len = qmi_calc_max_msg_len(desc->ei_array, 1);
  225. pr_err("%s: Calc. len %d != Out buf len %d\n",
  226. __func__, calc_max_msg_len, out_buf_len);
  227. }
  228. return ret;
  229. }
  230. EXPORT_SYMBOL(qmi_kernel_encode);
  231. /**
  232. * qmi_encode_basic_elem() - Encodes elements of basic/primary data type
  233. * @buf_dst: Buffer to store the encoded information.
  234. * @buf_src: Buffer containing the elements to be encoded.
  235. * @elem_len: Number of elements, in the buf_src, to be encoded.
  236. * @elem_size: Size of a single instance of the element to be encoded.
  237. *
  238. * @return: number of bytes of encoded information.
  239. *
  240. * This function encodes the "elem_len" number of data elements, each of
  241. * size "elem_size" bytes from the source buffer "buf_src" and stores the
  242. * encoded information in the destination buffer "buf_dst". The elements are
  243. * of primary data type which include uint8_t - uint64_t or similar. This
  244. * function returns the number of bytes of encoded information.
  245. */
  246. static int qmi_encode_basic_elem(void *buf_dst, void *buf_src,
  247. uint32_t elem_len, uint32_t elem_size)
  248. {
  249. uint32_t i, rc = 0;
  250. for (i = 0; i < elem_len; i++) {
  251. QMI_ENCDEC_ENCODE_N_BYTES(buf_dst, buf_src, elem_size);
  252. rc += elem_size;
  253. }
  254. return rc;
  255. }
  256. /**
  257. * qmi_encode_struct_elem() - Encodes elements of struct data type
  258. * @ei_array: Struct info array descibing the struct element.
  259. * @buf_dst: Buffer to store the encoded information.
  260. * @buf_src: Buffer containing the elements to be encoded.
  261. * @elem_len: Number of elements, in the buf_src, to be encoded.
  262. * @out_buf_len: Available space in the encode buffer.
  263. * @enc_level: Depth of the nested structure from the main structure.
  264. *
  265. * @return: Number of bytes of encoded information, on success.
  266. * < 0 on error.
  267. *
  268. * This function encodes the "elem_len" number of struct elements, each of
  269. * size "ei_array->elem_size" bytes from the source buffer "buf_src" and
  270. * stores the encoded information in the destination buffer "buf_dst". The
  271. * elements are of struct data type which includes any C structure. This
  272. * function returns the number of bytes of encoded information.
  273. */
  274. static int qmi_encode_struct_elem(struct elem_info *ei_array,
  275. void *buf_dst, void *buf_src,
  276. uint32_t elem_len, uint32_t out_buf_len,
  277. int enc_level)
  278. {
  279. int i, rc, encoded_bytes = 0;
  280. struct elem_info *temp_ei = ei_array;
  281. for (i = 0; i < elem_len; i++) {
  282. rc = _qmi_kernel_encode(temp_ei->ei_array, buf_dst, buf_src,
  283. (out_buf_len - encoded_bytes),
  284. enc_level);
  285. if (rc < 0) {
  286. pr_err("%s: STRUCT Encode failure\n", __func__);
  287. return rc;
  288. }
  289. buf_dst = buf_dst + rc;
  290. buf_src = buf_src + temp_ei->elem_size;
  291. encoded_bytes += rc;
  292. }
  293. return encoded_bytes;
  294. }
  295. /**
  296. * qmi_encode_string_elem() - Encodes elements of string data type
  297. * @ei_array: Struct info array descibing the string element.
  298. * @buf_dst: Buffer to store the encoded information.
  299. * @buf_src: Buffer containing the elements to be encoded.
  300. * @out_buf_len: Available space in the encode buffer.
  301. * @enc_level: Depth of the string element from the main structure.
  302. *
  303. * @return: Number of bytes of encoded information, on success.
  304. * < 0 on error.
  305. *
  306. * This function encodes a string element of maximum length "ei_array->elem_len"
  307. * bytes from the source buffer "buf_src" and stores the encoded information in
  308. * the destination buffer "buf_dst". This function returns the number of bytes
  309. * of encoded information.
  310. */
  311. static int qmi_encode_string_elem(struct elem_info *ei_array,
  312. void *buf_dst, void *buf_src,
  313. uint32_t out_buf_len, int enc_level)
  314. {
  315. int rc;
  316. int encoded_bytes = 0;
  317. struct elem_info *temp_ei = ei_array;
  318. uint32_t string_len = 0;
  319. uint32_t string_len_sz = 0;
  320. string_len = strlen(buf_src);
  321. string_len_sz = temp_ei->elem_len <= U8_MAX ?
  322. sizeof(uint8_t) : sizeof(uint16_t);
  323. if (string_len > temp_ei->elem_len) {
  324. pr_err("%s: String to be encoded is longer - %d > %d\n",
  325. __func__, string_len, temp_ei->elem_len);
  326. return -EINVAL;
  327. }
  328. if (enc_level == 1) {
  329. if (string_len + TLV_LEN_SIZE + TLV_TYPE_SIZE >
  330. out_buf_len) {
  331. pr_err("%s: Output len %d > Out Buf len %d\n",
  332. __func__, string_len, out_buf_len);
  333. return -ETOOSMALL;
  334. }
  335. } else {
  336. if (string_len + string_len_sz > out_buf_len) {
  337. pr_err("%s: Output len %d > Out Buf len %d\n",
  338. __func__, string_len, out_buf_len);
  339. return -ETOOSMALL;
  340. }
  341. rc = qmi_encode_basic_elem(buf_dst, &string_len,
  342. 1, string_len_sz);
  343. encoded_bytes += rc;
  344. }
  345. rc = qmi_encode_basic_elem(buf_dst + encoded_bytes, buf_src,
  346. string_len, temp_ei->elem_size);
  347. encoded_bytes += rc;
  348. QMI_ENCODE_LOG_ELEM(enc_level, string_len, temp_ei->elem_size, buf_src);
  349. return encoded_bytes;
  350. }
  351. /**
  352. * skip_to_next_elem() - Skip to next element in the structure to be encoded
  353. * @ei_array: Struct info describing the element to be skipped.
  354. * @level: Depth level of encoding/decoding to identify nested structures.
  355. *
  356. * @return: Struct info of the next element that can be encoded.
  357. *
  358. * This function is used while encoding optional elements. If the flag
  359. * corresponding to an optional element is not set, then encoding the
  360. * optional element can be skipped. This function can be used to perform
  361. * that operation.
  362. */
  363. static struct elem_info *skip_to_next_elem(struct elem_info *ei_array,
  364. int level)
  365. {
  366. struct elem_info *temp_ei = ei_array;
  367. uint8_t tlv_type;
  368. if (level > 1) {
  369. temp_ei = temp_ei + 1;
  370. } else {
  371. do {
  372. tlv_type = temp_ei->tlv_type;
  373. temp_ei = temp_ei + 1;
  374. } while (tlv_type == temp_ei->tlv_type);
  375. }
  376. return temp_ei;
  377. }
  378. /**
  379. * _qmi_kernel_encode() - Core Encode Function
  380. * @ei_array: Struct info array describing the structure to be encoded.
  381. * @out_buf: Buffer to hold the encoded QMI message.
  382. * @in_c_struct: Pointer to the C structure to be encoded.
  383. * @out_buf_len: Available space in the encode buffer.
  384. * @enc_level: Encode level to indicate the depth of the nested structure,
  385. * within the main structure, being encoded.
  386. *
  387. * @return: Number of bytes of encoded information, on success.
  388. * < 0 on error.
  389. */
  390. static int _qmi_kernel_encode(struct elem_info *ei_array,
  391. void *out_buf, void *in_c_struct,
  392. uint32_t out_buf_len, int enc_level)
  393. {
  394. struct elem_info *temp_ei = ei_array;
  395. uint8_t opt_flag_value = 0;
  396. uint32_t data_len_value = 0, data_len_sz;
  397. uint8_t *buf_dst = (uint8_t *)out_buf;
  398. uint8_t *tlv_pointer;
  399. uint32_t tlv_len;
  400. uint8_t tlv_type;
  401. uint32_t encoded_bytes = 0;
  402. void *buf_src;
  403. int encode_tlv = 0;
  404. int rc;
  405. tlv_pointer = buf_dst;
  406. tlv_len = 0;
  407. if (enc_level == 1)
  408. buf_dst = buf_dst + (TLV_LEN_SIZE + TLV_TYPE_SIZE);
  409. while (temp_ei->data_type != QMI_EOTI) {
  410. buf_src = in_c_struct + temp_ei->offset;
  411. tlv_type = temp_ei->tlv_type;
  412. if (temp_ei->is_array == NO_ARRAY) {
  413. data_len_value = 1;
  414. } else if (temp_ei->is_array == STATIC_ARRAY) {
  415. data_len_value = temp_ei->elem_len;
  416. } else if (data_len_value <= 0 ||
  417. temp_ei->elem_len < data_len_value) {
  418. pr_err("%s: Invalid data length\n", __func__);
  419. return -EINVAL;
  420. }
  421. switch (temp_ei->data_type) {
  422. case QMI_OPT_FLAG:
  423. rc = qmi_encode_basic_elem(&opt_flag_value, buf_src,
  424. 1, sizeof(uint8_t));
  425. if (opt_flag_value)
  426. temp_ei = temp_ei + 1;
  427. else
  428. temp_ei = skip_to_next_elem(temp_ei, enc_level);
  429. break;
  430. case QMI_DATA_LEN:
  431. memcpy(&data_len_value, buf_src, temp_ei->elem_size);
  432. data_len_sz = temp_ei->elem_size == sizeof(uint8_t) ?
  433. sizeof(uint8_t) : sizeof(uint16_t);
  434. /* Check to avoid out of range buffer access */
  435. if ((data_len_sz + encoded_bytes + TLV_LEN_SIZE +
  436. TLV_TYPE_SIZE) > out_buf_len) {
  437. pr_err("%s: Too Small Buffer @DATA_LEN\n",
  438. __func__);
  439. return -ETOOSMALL;
  440. }
  441. rc = qmi_encode_basic_elem(buf_dst, &data_len_value,
  442. 1, data_len_sz);
  443. UPDATE_ENCODE_VARIABLES(temp_ei, buf_dst,
  444. encoded_bytes, tlv_len, encode_tlv, rc);
  445. if (!data_len_value)
  446. temp_ei = skip_to_next_elem(temp_ei, enc_level);
  447. else
  448. encode_tlv = 0;
  449. break;
  450. case QMI_UNSIGNED_1_BYTE:
  451. case QMI_UNSIGNED_2_BYTE:
  452. case QMI_UNSIGNED_4_BYTE:
  453. case QMI_UNSIGNED_8_BYTE:
  454. case QMI_SIGNED_2_BYTE_ENUM:
  455. case QMI_SIGNED_4_BYTE_ENUM:
  456. /* Check to avoid out of range buffer access */
  457. if (((data_len_value * temp_ei->elem_size) +
  458. encoded_bytes + TLV_LEN_SIZE + TLV_TYPE_SIZE) >
  459. out_buf_len) {
  460. pr_err("%s: Too Small Buffer @data_type:%d\n",
  461. __func__, temp_ei->data_type);
  462. return -ETOOSMALL;
  463. }
  464. rc = qmi_encode_basic_elem(buf_dst, buf_src,
  465. data_len_value, temp_ei->elem_size);
  466. QMI_ENCODE_LOG_ELEM(enc_level, data_len_value,
  467. temp_ei->elem_size, buf_src);
  468. UPDATE_ENCODE_VARIABLES(temp_ei, buf_dst,
  469. encoded_bytes, tlv_len, encode_tlv, rc);
  470. break;
  471. case QMI_STRUCT:
  472. rc = qmi_encode_struct_elem(temp_ei, buf_dst, buf_src,
  473. data_len_value, (out_buf_len - encoded_bytes),
  474. (enc_level + 1));
  475. if (rc < 0)
  476. return rc;
  477. UPDATE_ENCODE_VARIABLES(temp_ei, buf_dst,
  478. encoded_bytes, tlv_len, encode_tlv, rc);
  479. break;
  480. case QMI_STRING:
  481. rc = qmi_encode_string_elem(temp_ei, buf_dst, buf_src,
  482. out_buf_len - encoded_bytes, enc_level);
  483. if (rc < 0)
  484. return rc;
  485. UPDATE_ENCODE_VARIABLES(temp_ei, buf_dst,
  486. encoded_bytes, tlv_len, encode_tlv, rc);
  487. break;
  488. default:
  489. pr_err("%s: Unrecognized data type\n", __func__);
  490. return -EINVAL;
  491. }
  492. if (encode_tlv && enc_level == 1) {
  493. QMI_ENCDEC_ENCODE_TLV(tlv_type, tlv_len, tlv_pointer);
  494. QMI_ENCODE_LOG_TLV(tlv_type, tlv_len);
  495. encoded_bytes += (TLV_TYPE_SIZE + TLV_LEN_SIZE);
  496. tlv_pointer = buf_dst;
  497. tlv_len = 0;
  498. buf_dst = buf_dst + TLV_LEN_SIZE + TLV_TYPE_SIZE;
  499. encode_tlv = 0;
  500. }
  501. }
  502. QMI_ENCODE_LOG_MSG(out_buf, encoded_bytes);
  503. return encoded_bytes;
  504. }
  505. /**
  506. * qmi_kernel_decode() - Decode to C Structure format
  507. * @desc: Pointer to structure descriptor.
  508. * @out_c_struct: Buffer to hold the decoded C structure.
  509. * @in_buf: Buffer containg the QMI message to be decoded.
  510. * @in_buf_len: Length of the incoming QMI message.
  511. *
  512. * @return: 0 on success, < 0 on error.
  513. */
  514. int qmi_kernel_decode(struct msg_desc *desc, void *out_c_struct,
  515. void *in_buf, uint32_t in_buf_len)
  516. {
  517. int dec_level = 1;
  518. int rc = 0;
  519. if (!desc || !desc->ei_array)
  520. return -EINVAL;
  521. if (!out_c_struct || !in_buf || !in_buf_len)
  522. return -EINVAL;
  523. if (desc->max_msg_len < in_buf_len)
  524. return -EINVAL;
  525. rc = _qmi_kernel_decode(desc->ei_array, out_c_struct,
  526. in_buf, in_buf_len, dec_level);
  527. if (rc < 0)
  528. return rc;
  529. else
  530. return 0;
  531. }
  532. EXPORT_SYMBOL(qmi_kernel_decode);
  533. /**
  534. * qmi_decode_basic_elem() - Decodes elements of basic/primary data type
  535. * @buf_dst: Buffer to store the decoded element.
  536. * @buf_src: Buffer containing the elements in QMI wire format.
  537. * @elem_len: Number of elements to be decoded.
  538. * @elem_size: Size of a single instance of the element to be decoded.
  539. *
  540. * @return: Total size of the decoded data elements, in bytes.
  541. *
  542. * This function decodes the "elem_len" number of elements in QMI wire format,
  543. * each of size "elem_size" bytes from the source buffer "buf_src" and stores
  544. * the decoded elements in the destination buffer "buf_dst". The elements are
  545. * of primary data type which include uint8_t - uint64_t or similar. This
  546. * function returns the number of bytes of decoded information.
  547. */
  548. static int qmi_decode_basic_elem(void *buf_dst, void *buf_src,
  549. uint32_t elem_len, uint32_t elem_size)
  550. {
  551. uint32_t i, rc = 0;
  552. for (i = 0; i < elem_len; i++) {
  553. QMI_ENCDEC_DECODE_N_BYTES(buf_dst, buf_src, elem_size);
  554. rc += elem_size;
  555. }
  556. return rc;
  557. }
  558. /**
  559. * qmi_decode_struct_elem() - Decodes elements of struct data type
  560. * @ei_array: Struct info array descibing the struct element.
  561. * @buf_dst: Buffer to store the decoded element.
  562. * @buf_src: Buffer containing the elements in QMI wire format.
  563. * @elem_len: Number of elements to be decoded.
  564. * @tlv_len: Total size of the encoded inforation corresponding to
  565. * this struct element.
  566. * @dec_level: Depth of the nested structure from the main structure.
  567. *
  568. * @return: Total size of the decoded data elements, on success.
  569. * < 0 on error.
  570. *
  571. * This function decodes the "elem_len" number of elements in QMI wire format,
  572. * each of size "(tlv_len/elem_len)" bytes from the source buffer "buf_src"
  573. * and stores the decoded elements in the destination buffer "buf_dst". The
  574. * elements are of struct data type which includes any C structure. This
  575. * function returns the number of bytes of decoded information.
  576. */
  577. static int qmi_decode_struct_elem(struct elem_info *ei_array, void *buf_dst,
  578. void *buf_src, uint32_t elem_len,
  579. uint32_t tlv_len, int dec_level)
  580. {
  581. int i, rc, decoded_bytes = 0;
  582. struct elem_info *temp_ei = ei_array;
  583. for (i = 0; i < elem_len && decoded_bytes < tlv_len; i++) {
  584. rc = _qmi_kernel_decode(temp_ei->ei_array, buf_dst, buf_src,
  585. (tlv_len - decoded_bytes), dec_level);
  586. if (rc < 0)
  587. return rc;
  588. buf_src = buf_src + rc;
  589. buf_dst = buf_dst + temp_ei->elem_size;
  590. decoded_bytes += rc;
  591. }
  592. if ((dec_level <= 2 && decoded_bytes != tlv_len) ||
  593. (dec_level > 2 && (i < elem_len || decoded_bytes > tlv_len))) {
  594. pr_err("%s: Fault in decoding: dl(%d), db(%d), tl(%d), i(%d), el(%d)\n",
  595. __func__, dec_level, decoded_bytes, tlv_len,
  596. i, elem_len);
  597. return -EFAULT;
  598. }
  599. return decoded_bytes;
  600. }
  601. /**
  602. * qmi_decode_string_elem() - Decodes elements of string data type
  603. * @ei_array: Struct info array descibing the string element.
  604. * @buf_dst: Buffer to store the decoded element.
  605. * @buf_src: Buffer containing the elements in QMI wire format.
  606. * @tlv_len: Total size of the encoded inforation corresponding to
  607. * this string element.
  608. * @dec_level: Depth of the string element from the main structure.
  609. *
  610. * @return: Total size of the decoded data elements, on success.
  611. * < 0 on error.
  612. *
  613. * This function decodes the string element of maximum length
  614. * "ei_array->elem_len" from the source buffer "buf_src" and puts it into
  615. * the destination buffer "buf_dst". This function returns number of bytes
  616. * decoded from the input buffer.
  617. */
  618. static int qmi_decode_string_elem(struct elem_info *ei_array, void *buf_dst,
  619. void *buf_src, uint32_t tlv_len,
  620. int dec_level)
  621. {
  622. int rc;
  623. int decoded_bytes = 0;
  624. uint32_t string_len = 0;
  625. uint32_t string_len_sz = 0;
  626. struct elem_info *temp_ei = ei_array;
  627. if (dec_level == 1) {
  628. string_len = tlv_len;
  629. } else {
  630. string_len_sz = temp_ei->elem_len <= U8_MAX ?
  631. sizeof(uint8_t) : sizeof(uint16_t);
  632. rc = qmi_decode_basic_elem(&string_len, buf_src,
  633. 1, string_len_sz);
  634. decoded_bytes += rc;
  635. }
  636. if (string_len > temp_ei->elem_len) {
  637. pr_err("%s: String len %d > Max Len %d\n",
  638. __func__, string_len, temp_ei->elem_len);
  639. return -ETOOSMALL;
  640. } else if (string_len > tlv_len) {
  641. pr_err("%s: String len %d > Input Buffer Len %d\n",
  642. __func__, string_len, tlv_len);
  643. return -EFAULT;
  644. }
  645. rc = qmi_decode_basic_elem(buf_dst, buf_src + decoded_bytes,
  646. string_len, temp_ei->elem_size);
  647. *((char *)buf_dst + string_len) = '\0';
  648. decoded_bytes += rc;
  649. QMI_DECODE_LOG_ELEM(dec_level, string_len, temp_ei->elem_size, buf_dst);
  650. return decoded_bytes;
  651. }
  652. /**
  653. * find_ei() - Find element info corresponding to TLV Type
  654. * @ei_array: Struct info array of the message being decoded.
  655. * @type: TLV Type of the element being searched.
  656. *
  657. * @return: Pointer to struct info, if found
  658. *
  659. * Every element that got encoded in the QMI message will have a type
  660. * information associated with it. While decoding the QMI message,
  661. * this function is used to find the struct info regarding the element
  662. * that corresponds to the type being decoded.
  663. */
  664. static struct elem_info *find_ei(struct elem_info *ei_array,
  665. uint32_t type)
  666. {
  667. struct elem_info *temp_ei = ei_array;
  668. while (temp_ei->data_type != QMI_EOTI) {
  669. if (temp_ei->tlv_type == (uint8_t)type)
  670. return temp_ei;
  671. temp_ei = temp_ei + 1;
  672. }
  673. return NULL;
  674. }
  675. /**
  676. * _qmi_kernel_decode() - Core Decode Function
  677. * @ei_array: Struct info array describing the structure to be decoded.
  678. * @out_c_struct: Buffer to hold the decoded C struct
  679. * @in_buf: Buffer containing the QMI message to be decoded
  680. * @in_buf_len: Length of the QMI message to be decoded
  681. * @dec_level: Decode level to indicate the depth of the nested structure,
  682. * within the main structure, being decoded
  683. *
  684. * @return: Number of bytes of decoded information, on success
  685. * < 0 on error.
  686. */
  687. static int _qmi_kernel_decode(struct elem_info *ei_array,
  688. void *out_c_struct,
  689. void *in_buf, uint32_t in_buf_len,
  690. int dec_level)
  691. {
  692. struct elem_info *temp_ei = ei_array;
  693. uint8_t opt_flag_value = 1;
  694. uint32_t data_len_value = 0, data_len_sz = 0;
  695. uint8_t *buf_dst = out_c_struct;
  696. uint8_t *tlv_pointer;
  697. uint32_t tlv_len = 0;
  698. uint32_t tlv_type;
  699. uint32_t decoded_bytes = 0;
  700. void *buf_src = in_buf;
  701. int rc;
  702. QMI_DECODE_LOG_MSG(in_buf, in_buf_len);
  703. while (decoded_bytes < in_buf_len) {
  704. if (dec_level >= 2 && temp_ei->data_type == QMI_EOTI)
  705. return decoded_bytes;
  706. if (dec_level == 1) {
  707. tlv_pointer = buf_src;
  708. QMI_ENCDEC_DECODE_TLV(&tlv_type,
  709. &tlv_len, tlv_pointer);
  710. QMI_DECODE_LOG_TLV(tlv_type, tlv_len);
  711. buf_src += (TLV_TYPE_SIZE + TLV_LEN_SIZE);
  712. decoded_bytes += (TLV_TYPE_SIZE + TLV_LEN_SIZE);
  713. temp_ei = find_ei(ei_array, tlv_type);
  714. if (!temp_ei && (tlv_type < OPTIONAL_TLV_TYPE_START)) {
  715. pr_err("%s: Inval element info\n", __func__);
  716. return -EINVAL;
  717. } else if (!temp_ei) {
  718. UPDATE_DECODE_VARIABLES(buf_src,
  719. decoded_bytes, tlv_len);
  720. continue;
  721. }
  722. } else {
  723. /*
  724. * No length information for elements in nested
  725. * structures. So use remaining decodable buffer space.
  726. */
  727. tlv_len = in_buf_len - decoded_bytes;
  728. }
  729. buf_dst = out_c_struct + temp_ei->offset;
  730. if (temp_ei->data_type == QMI_OPT_FLAG) {
  731. memcpy(buf_dst, &opt_flag_value, sizeof(uint8_t));
  732. temp_ei = temp_ei + 1;
  733. buf_dst = out_c_struct + temp_ei->offset;
  734. }
  735. if (temp_ei->data_type == QMI_DATA_LEN) {
  736. data_len_sz = temp_ei->elem_size == sizeof(uint8_t) ?
  737. sizeof(uint8_t) : sizeof(uint16_t);
  738. rc = qmi_decode_basic_elem(&data_len_value, buf_src,
  739. 1, data_len_sz);
  740. memcpy(buf_dst, &data_len_value, sizeof(uint32_t));
  741. temp_ei = temp_ei + 1;
  742. buf_dst = out_c_struct + temp_ei->offset;
  743. tlv_len -= data_len_sz;
  744. UPDATE_DECODE_VARIABLES(buf_src, decoded_bytes, rc);
  745. }
  746. if (temp_ei->is_array == NO_ARRAY) {
  747. data_len_value = 1;
  748. } else if (temp_ei->is_array == STATIC_ARRAY) {
  749. data_len_value = temp_ei->elem_len;
  750. } else if (data_len_value > temp_ei->elem_len) {
  751. pr_err("%s: Data len %d > max spec %d\n",
  752. __func__, data_len_value, temp_ei->elem_len);
  753. return -ETOOSMALL;
  754. }
  755. switch (temp_ei->data_type) {
  756. case QMI_UNSIGNED_1_BYTE:
  757. case QMI_UNSIGNED_2_BYTE:
  758. case QMI_UNSIGNED_4_BYTE:
  759. case QMI_UNSIGNED_8_BYTE:
  760. case QMI_SIGNED_2_BYTE_ENUM:
  761. case QMI_SIGNED_4_BYTE_ENUM:
  762. rc = qmi_decode_basic_elem(buf_dst, buf_src,
  763. data_len_value, temp_ei->elem_size);
  764. QMI_DECODE_LOG_ELEM(dec_level, data_len_value,
  765. temp_ei->elem_size, buf_dst);
  766. UPDATE_DECODE_VARIABLES(buf_src, decoded_bytes, rc);
  767. break;
  768. case QMI_STRUCT:
  769. rc = qmi_decode_struct_elem(temp_ei, buf_dst, buf_src,
  770. data_len_value, tlv_len, (dec_level + 1));
  771. if (rc < 0)
  772. return rc;
  773. UPDATE_DECODE_VARIABLES(buf_src, decoded_bytes, rc);
  774. break;
  775. case QMI_STRING:
  776. rc = qmi_decode_string_elem(temp_ei, buf_dst, buf_src,
  777. tlv_len, dec_level);
  778. if (rc < 0)
  779. return rc;
  780. UPDATE_DECODE_VARIABLES(buf_src, decoded_bytes, rc);
  781. break;
  782. default:
  783. pr_err("%s: Unrecognized data type\n", __func__);
  784. return -EINVAL;
  785. }
  786. temp_ei = temp_ei + 1;
  787. }
  788. return decoded_bytes;
  789. }
  790. MODULE_DESCRIPTION("QMI kernel enc/dec");
  791. MODULE_LICENSE("GPL v2");