1
2
3
4
5
6#ifndef __QMI_HELPERS_H__
7#define __QMI_HELPERS_H__
8
9#include <linux/completion.h>
10#include <linux/idr.h>
11#include <linux/list.h>
12#include <linux/qrtr.h>
13#include <linux/types.h>
14#include <linux/workqueue.h>
15
16struct socket;
17
18
19
20
21
22
23
24
25struct qmi_header {
26 u8 type;
27 u16 txn_id;
28 u16 msg_id;
29 u16 msg_len;
30} __packed;
31
32#define QMI_REQUEST 0
33#define QMI_RESPONSE 2
34#define QMI_INDICATION 4
35
36#define QMI_COMMON_TLV_TYPE 0
37
38enum qmi_elem_type {
39 QMI_EOTI,
40 QMI_OPT_FLAG,
41 QMI_DATA_LEN,
42 QMI_UNSIGNED_1_BYTE,
43 QMI_UNSIGNED_2_BYTE,
44 QMI_UNSIGNED_4_BYTE,
45 QMI_UNSIGNED_8_BYTE,
46 QMI_SIGNED_2_BYTE_ENUM,
47 QMI_SIGNED_4_BYTE_ENUM,
48 QMI_STRUCT,
49 QMI_STRING,
50};
51
52enum qmi_array_type {
53 NO_ARRAY,
54 STATIC_ARRAY,
55 VAR_LEN_ARRAY,
56};
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71struct qmi_elem_info {
72 enum qmi_elem_type data_type;
73 u32 elem_len;
74 u32 elem_size;
75 enum qmi_array_type array_type;
76 u8 tlv_type;
77 u32 offset;
78 struct qmi_elem_info *ei_array;
79};
80
81#define QMI_RESULT_SUCCESS_V01 0
82#define QMI_RESULT_FAILURE_V01 1
83
84#define QMI_ERR_NONE_V01 0
85#define QMI_ERR_MALFORMED_MSG_V01 1
86#define QMI_ERR_NO_MEMORY_V01 2
87#define QMI_ERR_INTERNAL_V01 3
88#define QMI_ERR_CLIENT_IDS_EXHAUSTED_V01 5
89#define QMI_ERR_INVALID_ID_V01 41
90#define QMI_ERR_ENCODING_V01 58
91#define QMI_ERR_DISABLED_V01 69
92#define QMI_ERR_INCOMPATIBLE_STATE_V01 90
93#define QMI_ERR_NOT_SUPPORTED_V01 94
94
95
96
97
98
99
100struct qmi_response_type_v01 {
101 u16 result;
102 u16 error;
103};
104
105extern struct qmi_elem_info qmi_response_type_v01_ei[];
106
107
108
109
110
111
112
113
114
115
116
117struct qmi_service {
118 unsigned int service;
119 unsigned int version;
120 unsigned int instance;
121
122 unsigned int node;
123 unsigned int port;
124
125 void *priv;
126 struct list_head list_node;
127};
128
129struct qmi_handle;
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146struct qmi_ops {
147 int (*new_server)(struct qmi_handle *qmi, struct qmi_service *svc);
148 void (*del_server)(struct qmi_handle *qmi, struct qmi_service *svc);
149 void (*net_reset)(struct qmi_handle *qmi);
150 void (*msg_handler)(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
151 const void *data, size_t count);
152 void (*bye)(struct qmi_handle *qmi, unsigned int node);
153 void (*del_client)(struct qmi_handle *qmi,
154 unsigned int node, unsigned int port);
155};
156
157
158
159
160
161
162
163
164
165
166
167struct qmi_txn {
168 struct qmi_handle *qmi;
169
170 u16 id;
171
172 struct mutex lock;
173 struct completion completion;
174 int result;
175
176 struct qmi_elem_info *ei;
177 void *dest;
178};
179
180
181
182
183
184
185
186
187
188struct qmi_msg_handler {
189 unsigned int type;
190 unsigned int msg_id;
191
192 struct qmi_elem_info *ei;
193
194 size_t decoded_size;
195 void (*fn)(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
196 struct qmi_txn *txn, const void *decoded);
197};
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216struct qmi_handle {
217 struct socket *sock;
218 struct mutex sock_lock;
219
220 struct sockaddr_qrtr sq;
221
222 struct work_struct work;
223 struct workqueue_struct *wq;
224
225 void *recv_buf;
226 size_t recv_buf_size;
227
228 struct list_head lookups;
229 struct list_head lookup_results;
230 struct list_head services;
231
232 struct qmi_ops ops;
233
234 struct idr txns;
235 struct mutex txn_lock;
236
237 const struct qmi_msg_handler *handlers;
238};
239
240int qmi_add_lookup(struct qmi_handle *qmi, unsigned int service,
241 unsigned int version, unsigned int instance);
242int qmi_add_server(struct qmi_handle *qmi, unsigned int service,
243 unsigned int version, unsigned int instance);
244
245int qmi_handle_init(struct qmi_handle *qmi, size_t max_msg_len,
246 const struct qmi_ops *ops,
247 const struct qmi_msg_handler *handlers);
248void qmi_handle_release(struct qmi_handle *qmi);
249
250ssize_t qmi_send_request(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
251 struct qmi_txn *txn, int msg_id, size_t len,
252 struct qmi_elem_info *ei, const void *c_struct);
253ssize_t qmi_send_response(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
254 struct qmi_txn *txn, int msg_id, size_t len,
255 struct qmi_elem_info *ei, const void *c_struct);
256ssize_t qmi_send_indication(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
257 int msg_id, size_t len, struct qmi_elem_info *ei,
258 const void *c_struct);
259
260void *qmi_encode_message(int type, unsigned int msg_id, size_t *len,
261 unsigned int txn_id, struct qmi_elem_info *ei,
262 const void *c_struct);
263
264int qmi_decode_message(const void *buf, size_t len,
265 struct qmi_elem_info *ei, void *c_struct);
266
267int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn,
268 struct qmi_elem_info *ei, void *c_struct);
269int qmi_txn_wait(struct qmi_txn *txn, unsigned long timeout);
270void qmi_txn_cancel(struct qmi_txn *txn);
271
272#endif
273