blob: 66c3d84485eda6eddd1bbfb4a2de91fcc391f9e1 [file] [log] [blame]
Karthikeyan Ramasubramanianfafd67f12016-09-16 17:15:13 -06001/* Copyright (c) 2012-2014, 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 */
32enum 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_STRING,
43 QMI_EOTI,
44};
45
46/**
47 * array_type - Enum to identify if an element in a data structure is
48 * an array. If so, then is it a static length array or a
49 * variable length array.
50 */
51enum array_type {
52 NO_ARRAY = 0,
53 STATIC_ARRAY = 1,
54 VAR_LEN_ARRAY = 2,
55};
56
57/**
58 * elem_info - Data structure to specify information about an element
59 * in a data structure. An array of this data structure
60 * can be used to specify info about a complex data
61 * structure to be encoded/decoded.
62 *
63 * @data_type: Data type of this element.
64 * @elem_len: Array length of this element, if an array.
65 * @elem_size: Size of a single instance of this data type.
66 * @is_array: Array type of this element.
67 * @tlv_type: QMI message specific type to identify which element
68 * is present in an incoming message.
69 * @offset: To identify the address of the first instance of this
70 * element in the data structure.
71 * @ei_array: Array to provide information about the nested structure
72 * within a data structure to be encoded/decoded.
73 */
74struct elem_info {
75 enum elem_type data_type;
76 uint32_t elem_len;
77 uint32_t elem_size;
78 enum array_type is_array;
79 uint8_t tlv_type;
80 uint32_t offset;
81 struct elem_info *ei_array;
82};
83
84/**
85 * @msg_desc - Describe about the main/outer structure to be
86 * encoded/decoded.
87 *
88 * @max_msg_len: Maximum possible length of the QMI message.
89 * @ei_array: Array to provide information about a data structure.
90 */
91struct msg_desc {
92 uint16_t msg_id;
93 int max_msg_len;
94 struct elem_info *ei_array;
95};
96
97struct qmi_header {
98 unsigned char cntl_flag;
99 uint16_t txn_id;
100 uint16_t msg_id;
101 uint16_t msg_len;
102} __attribute__((__packed__));
103
104static inline void encode_qmi_header(unsigned char *buf,
105 unsigned char cntl_flag, uint16_t txn_id,
106 uint16_t msg_id, uint16_t msg_len)
107{
108 struct qmi_header *hdr = (struct qmi_header *)buf;
109
110 hdr->cntl_flag = cntl_flag;
111 hdr->txn_id = txn_id;
112 hdr->msg_id = msg_id;
113 hdr->msg_len = msg_len;
114}
115
116static inline void decode_qmi_header(unsigned char *buf,
117 unsigned char *cntl_flag, uint16_t *txn_id,
118 uint16_t *msg_id, uint16_t *msg_len)
119{
120 struct qmi_header *hdr = (struct qmi_header *)buf;
121
122 *cntl_flag = hdr->cntl_flag;
123 *txn_id = hdr->txn_id;
124 *msg_id = hdr->msg_id;
125 *msg_len = hdr->msg_len;
126}
127
128#ifdef CONFIG_QMI_ENCDEC
129/**
130 * qmi_kernel_encode() - Encode to QMI message wire format
131 * @desc: Pointer to structure descriptor.
132 * @out_buf: Buffer to hold the encoded QMI message.
133 * @out_buf_len: Length of the out buffer.
134 * @in_c_struct: C Structure to be encoded.
135 *
136 * @return: size of encoded message on success, < 0 on error.
137 */
138int qmi_kernel_encode(struct msg_desc *desc,
139 void *out_buf, uint32_t out_buf_len,
140 void *in_c_struct);
141
142/**
143 * qmi_kernel_decode() - Decode to C Structure format
144 * @desc: Pointer to structure descriptor.
145 * @out_c_struct: Buffer to hold the decoded C structure.
146 * @in_buf: Buffer containg the QMI message to be decoded.
147 * @in_buf_len: Length of the incoming QMI message.
148 *
149 * @return: 0 on success, < 0 on error.
150 */
151int qmi_kernel_decode(struct msg_desc *desc, void *out_c_struct,
152 void *in_buf, uint32_t in_buf_len);
153
154/**
155 * qmi_verify_max_msg_len() - Verify the maximum length of a QMI message
156 * @desc: Pointer to structure descriptor.
157 *
158 * @return: true if the maximum message length embedded in structure
159 * descriptor matches the calculated value, else false.
160 */
161bool qmi_verify_max_msg_len(struct msg_desc *desc);
162
163#else
164static inline int qmi_kernel_encode(struct msg_desc *desc,
165 void *out_buf, uint32_t out_buf_len,
166 void *in_c_struct)
167{
168 return -EOPNOTSUPP;
169}
170
171static inline int qmi_kernel_decode(struct msg_desc *desc,
172 void *out_c_struct,
173 void *in_buf, uint32_t in_buf_len)
174{
175 return -EOPNOTSUPP;
176}
177
178static inline bool qmi_verify_max_msg_len(struct msg_desc *desc)
179{
180 return false;
181}
182#endif
183
184#endif