blob: b1fd2173b917dd7a938b8ad053c4203808edf0f5 [file] [log] [blame]
Karthikeyan Ramasubramanian0714f1b2013-01-08 17:21:53 -07001/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Karthikeyan Ramasubramaniand9522582012-07-18 19:25:37 -06002 *
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_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 */
50enum 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 */
73struct 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 */
90struct msg_desc {
91 uint16_t msg_id;
92 int max_msg_len;
93 struct elem_info *ei_array;
94};
95
96struct 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
103static 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
115static 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 */
137int 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 */
150int qmi_kernel_decode(struct msg_desc *desc, void *out_c_struct,
151 void *in_buf, uint32_t in_buf_len);
152
Karthikeyan Ramasubramanian0714f1b2013-01-08 17:21:53 -0700153/**
154 * qmi_verify_max_msg_len() - Verify the maximum length of a QMI message
155 * @desc: Pointer to structure descriptor.
156 *
157 * @return: true if the maximum message length embedded in structure
158 * descriptor matches the calculated value, else false.
159 */
160bool qmi_verify_max_msg_len(struct msg_desc *desc);
161
Karthikeyan Ramasubramaniand9522582012-07-18 19:25:37 -0600162#else
163static inline int qmi_kernel_encode(struct msg_desc *desc,
164 void *out_buf, uint32_t out_buf_len,
165 void *in_c_struct)
166{
167 return -EOPNOTSUPP;
168}
169
170static inline int qmi_kernel_decode(struct msg_desc *desc,
171 void *out_c_struct,
172 void *in_buf, uint32_t in_buf_len)
173{
174 return -EOPNOTSUPP;
175}
Karthikeyan Ramasubramanian0714f1b2013-01-08 17:21:53 -0700176
177static inline bool qmi_verify_max_msg_len(struct msg_desc *desc)
178{
179 return false;
180}
Karthikeyan Ramasubramaniand9522582012-07-18 19:25:37 -0600181#endif
182
183#endif