| Karthikeyan Ramasubramanian | f5484ed | 2012-07-18 19:25:37 -0600 | [diff] [blame] | 1 | /* Copyright (c) 2012, 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 | #ifndef _QMI_ENCDEC_H_ | 
 | 14 | #define _QMI_ENCDEC_H_ | 
 | 15 |  | 
 | 16 | #include <linux/types.h> | 
 | 17 | #include <linux/errno.h> | 
 | 18 | #include <linux/mm.h> | 
 | 19 | #include <linux/list.h> | 
 | 20 | #include <linux/socket.h> | 
 | 21 | #include <linux/gfp.h> | 
 | 22 |  | 
 | 23 | #define QMI_REQUEST_CONTROL_FLAG 0x00 | 
 | 24 | #define QMI_RESPONSE_CONTROL_FLAG 0x02 | 
 | 25 | #define QMI_INDICATION_CONTROL_FLAG 0x04 | 
 | 26 | #define QMI_HEADER_SIZE 7 | 
 | 27 |  | 
 | 28 | /** | 
 | 29 |  * elem_type - Enum to identify the data type of elements in a data | 
 | 30 |  *             structure. | 
 | 31 |  */ | 
 | 32 | enum elem_type { | 
 | 33 | 	QMI_OPT_FLAG = 1, | 
 | 34 | 	QMI_DATA_LEN, | 
 | 35 | 	QMI_UNSIGNED_1_BYTE, | 
 | 36 | 	QMI_UNSIGNED_2_BYTE, | 
 | 37 | 	QMI_UNSIGNED_4_BYTE, | 
 | 38 | 	QMI_UNSIGNED_8_BYTE, | 
 | 39 | 	QMI_SIGNED_2_BYTE_ENUM, | 
 | 40 | 	QMI_SIGNED_4_BYTE_ENUM, | 
 | 41 | 	QMI_STRUCT, | 
 | 42 | 	QMI_EOTI, | 
 | 43 | }; | 
 | 44 |  | 
 | 45 | /** | 
 | 46 |  * array_type - Enum to identify if an element in a data structure is | 
 | 47 |  *              an array. If so, then is it a static length array or a | 
 | 48 |  *              variable length array. | 
 | 49 |  */ | 
 | 50 | enum array_type { | 
 | 51 | 	NO_ARRAY = 0, | 
 | 52 | 	STATIC_ARRAY = 1, | 
 | 53 | 	VAR_LEN_ARRAY = 2, | 
 | 54 | }; | 
 | 55 |  | 
 | 56 | /** | 
 | 57 |  * elem_info - Data structure to specify information about an element | 
 | 58 |  *               in a data structure. An array of this data structure | 
 | 59 |  *               can be used to specify info about a complex data | 
 | 60 |  *               structure to be encoded/decoded. | 
 | 61 |  * | 
 | 62 |  * @data_type: Data type of this element. | 
 | 63 |  * @elem_len: Array length of this element, if an array. | 
 | 64 |  * @elem_size: Size of a single instance of this data type. | 
 | 65 |  * @is_array: Array type of this element. | 
 | 66 |  * @tlv_type: QMI message specific type to identify which element | 
 | 67 |  *            is present in an incoming message. | 
 | 68 |  * @offset: To identify the address of the first instance of this | 
 | 69 |  *          element in the data structure. | 
 | 70 |  * @ei_array: Array to provide information about the nested structure | 
 | 71 |  *            within a data structure to be encoded/decoded. | 
 | 72 |  */ | 
 | 73 | struct elem_info { | 
 | 74 | 	enum elem_type data_type; | 
 | 75 | 	uint32_t elem_len; | 
 | 76 | 	uint32_t elem_size; | 
 | 77 | 	enum array_type is_array; | 
 | 78 | 	uint8_t tlv_type; | 
 | 79 | 	uint32_t offset; | 
 | 80 | 	struct elem_info *ei_array; | 
 | 81 | }; | 
 | 82 |  | 
 | 83 | /** | 
 | 84 |  * @msg_desc - Describe about the main/outer structure to be | 
 | 85 |  *		  encoded/decoded. | 
 | 86 |  * | 
 | 87 |  * @max_msg_len: Maximum possible length of the QMI message. | 
 | 88 |  * @ei_array: Array to provide information about a data structure. | 
 | 89 |  */ | 
 | 90 | struct msg_desc { | 
 | 91 | 	uint16_t msg_id; | 
 | 92 | 	int max_msg_len; | 
 | 93 | 	struct elem_info *ei_array; | 
 | 94 | }; | 
 | 95 |  | 
 | 96 | struct qmi_header { | 
 | 97 | 	unsigned char cntl_flag; | 
 | 98 | 	uint16_t txn_id; | 
 | 99 | 	uint16_t msg_id; | 
 | 100 | 	uint16_t msg_len; | 
 | 101 | } __attribute__((__packed__)); | 
 | 102 |  | 
 | 103 | static inline void encode_qmi_header(unsigned char *buf, | 
 | 104 | 			unsigned char cntl_flag, uint16_t txn_id, | 
 | 105 | 			uint16_t msg_id, uint16_t msg_len) | 
 | 106 | { | 
 | 107 | 	struct qmi_header *hdr = (struct qmi_header *)buf; | 
 | 108 |  | 
 | 109 | 	hdr->cntl_flag = cntl_flag; | 
 | 110 | 	hdr->txn_id = txn_id; | 
 | 111 | 	hdr->msg_id = msg_id; | 
 | 112 | 	hdr->msg_len = msg_len; | 
 | 113 | } | 
 | 114 |  | 
 | 115 | static inline void decode_qmi_header(unsigned char *buf, | 
 | 116 | 			unsigned char *cntl_flag, uint16_t *txn_id, | 
 | 117 | 			uint16_t *msg_id, uint16_t *msg_len) | 
 | 118 | { | 
 | 119 | 	struct qmi_header *hdr = (struct qmi_header *)buf; | 
 | 120 |  | 
 | 121 | 	*cntl_flag = hdr->cntl_flag; | 
 | 122 | 	*txn_id = hdr->txn_id; | 
 | 123 | 	*msg_id = hdr->msg_id; | 
 | 124 | 	*msg_len = hdr->msg_len; | 
 | 125 | } | 
 | 126 |  | 
 | 127 | #ifdef CONFIG_QMI_ENCDEC | 
 | 128 | /** | 
 | 129 |  * qmi_kernel_encode() - Encode to QMI message wire format | 
 | 130 |  * @desc: Pointer to structure descriptor. | 
 | 131 |  * @out_buf: Buffer to hold the encoded QMI message. | 
 | 132 |  * @out_buf_len: Length of the out buffer. | 
 | 133 |  * @in_c_struct: C Structure to be encoded. | 
 | 134 |  * | 
 | 135 |  * @return: size of encoded message on success, < 0 on error. | 
 | 136 |  */ | 
 | 137 | int qmi_kernel_encode(struct msg_desc *desc, | 
 | 138 | 		      void *out_buf, uint32_t out_buf_len, | 
 | 139 | 		      void *in_c_struct); | 
 | 140 |  | 
 | 141 | /** | 
 | 142 |  * qmi_kernel_decode() - Decode to C Structure format | 
 | 143 |  * @desc: Pointer to structure descriptor. | 
 | 144 |  * @out_c_struct: Buffer to hold the decoded C structure. | 
 | 145 |  * @in_buf: Buffer containg the QMI message to be decoded. | 
 | 146 |  * @in_buf_len: Length of the incoming QMI message. | 
 | 147 |  * | 
 | 148 |  * @return: 0 on success, < 0 on error. | 
 | 149 |  */ | 
 | 150 | int qmi_kernel_decode(struct msg_desc *desc, void *out_c_struct, | 
 | 151 | 		      void *in_buf, uint32_t in_buf_len); | 
 | 152 |  | 
 | 153 | #else | 
 | 154 | static inline int qmi_kernel_encode(struct msg_desc *desc, | 
 | 155 | 				    void *out_buf, uint32_t out_buf_len, | 
 | 156 | 				    void *in_c_struct) | 
 | 157 | { | 
 | 158 | 	return -EOPNOTSUPP; | 
 | 159 | } | 
 | 160 |  | 
 | 161 | static inline int qmi_kernel_decode(struct msg_desc *desc, | 
 | 162 | 				    void *out_c_struct, | 
 | 163 | 				    void *in_buf, uint32_t in_buf_len) | 
 | 164 | { | 
 | 165 | 	return -EOPNOTSUPP; | 
 | 166 | } | 
 | 167 | #endif | 
 | 168 |  | 
 | 169 | #endif |