1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2017, Linaro Ltd. 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 16 struct socket; 17 18 /** 19 * qmi_header - wireformat header of QMI messages 20 * @type: type of message 21 * @txn_id: transaction id 22 * @msg_id: message id 23 * @msg_len: length of message payload following header 24 */ 25 struct 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 38 enum 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 52 enum qmi_array_type { 53 NO_ARRAY, 54 STATIC_ARRAY, 55 VAR_LEN_ARRAY, 56 }; 57 58 /** 59 * struct qmi_elem_info - describes how to encode a single QMI element 60 * @data_type: Data type of this element. 61 * @elem_len: Array length of this element, if an array. 62 * @elem_size: Size of a single instance of this data type. 63 * @array_type: Array type of this element. 64 * @tlv_type: QMI message specific type to identify which element 65 * is present in an incoming message. 66 * @offset: Specifies the offset of the first instance of this 67 * element in the data structure. 68 * @ei_array: Null-terminated array of @qmi_elem_info to describe nested 69 * structures. 70 */ 71 struct 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_INCOMPATIBLE_STATE_V01 90 92 #define QMI_ERR_NOT_SUPPORTED_V01 94 93 94 /** 95 * qmi_response_type_v01 - common response header (decoded) 96 * @result: result of the transaction 97 * @error: error value, when @result is QMI_RESULT_FAILURE_V01 98 */ 99 struct qmi_response_type_v01 { 100 u16 result; 101 u16 error; 102 }; 103 104 extern struct qmi_elem_info qmi_response_type_v01_ei[]; 105 106 /** 107 * struct qmi_service - context to track lookup-results 108 * @service: service type 109 * @version: version of the @service 110 * @instance: instance id of the @service 111 * @node: node of the service 112 * @port: port of the service 113 * @priv: handle for client's use 114 * @list_node: list_head for house keeping 115 */ 116 struct qmi_service { 117 unsigned int service; 118 unsigned int version; 119 unsigned int instance; 120 121 unsigned int node; 122 unsigned int port; 123 124 void *priv; 125 struct list_head list_node; 126 }; 127 128 struct qmi_handle; 129 130 /** 131 * struct qmi_ops - callbacks for qmi_handle 132 * @new_server: inform client of a new_server lookup-result, returning 133 * successfully from this call causes the library to call 134 * @del_server as the service is removed from the 135 * lookup-result. @priv of the qmi_service can be used by 136 * the client 137 * @del_server: inform client of a del_server lookup-result 138 * @net_reset: inform client that the name service was restarted and 139 * that and any state needs to be released 140 * @msg_handler: invoked for incoming messages, allows a client to 141 * override the usual QMI message handler 142 * @bye: inform a client that all clients from a node are gone 143 * @del_client: inform a client that a particular client is gone 144 */ 145 struct qmi_ops { 146 int (*new_server)(struct qmi_handle *qmi, struct qmi_service *svc); 147 void (*del_server)(struct qmi_handle *qmi, struct qmi_service *svc); 148 void (*net_reset)(struct qmi_handle *qmi); 149 void (*msg_handler)(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, 150 const void *data, size_t count); 151 void (*bye)(struct qmi_handle *qmi, unsigned int node); 152 void (*del_client)(struct qmi_handle *qmi, 153 unsigned int node, unsigned int port); 154 }; 155 156 /** 157 * struct qmi_txn - transaction context 158 * @qmi: QMI handle this transaction is associated with 159 * @id: transaction id 160 * @lock: for synchronization between handler and waiter of messages 161 * @completion: completion object as the transaction receives a response 162 * @result: result code for the completed transaction 163 * @ei: description of the QMI encoded response (optional) 164 * @dest: destination buffer to decode message into (optional) 165 */ 166 struct qmi_txn { 167 struct qmi_handle *qmi; 168 169 int id; 170 171 struct mutex lock; 172 struct completion completion; 173 int result; 174 175 struct qmi_elem_info *ei; 176 void *dest; 177 }; 178 179 /** 180 * struct qmi_msg_handler - description of QMI message handler 181 * @type: type of message 182 * @msg_id: message id 183 * @ei: description of the QMI encoded message 184 * @decoded_size: size of the decoded object 185 * @fn: function to invoke as the message is decoded 186 */ 187 struct qmi_msg_handler { 188 unsigned int type; 189 unsigned int msg_id; 190 191 struct qmi_elem_info *ei; 192 193 size_t decoded_size; 194 void (*fn)(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, 195 struct qmi_txn *txn, const void *decoded); 196 }; 197 198 /** 199 * struct qmi_handle - QMI context 200 * @sock: socket handle 201 * @sock_lock: synchronization of @sock modifications 202 * @sq: sockaddr of @sock 203 * @work: work for handling incoming messages 204 * @wq: workqueue to post @work on 205 * @recv_buf: scratch buffer for handling incoming messages 206 * @recv_buf_size: size of @recv_buf 207 * @lookups: list of registered lookup requests 208 * @lookup_results: list of lookup-results advertised to the client 209 * @services: list of registered services (by this client) 210 * @ops: reference to callbacks 211 * @txns: outstanding transactions 212 * @txn_lock: lock for modifications of @txns 213 * @handlers: list of handlers for incoming messages 214 */ 215 struct qmi_handle { 216 struct socket *sock; 217 struct mutex sock_lock; 218 219 struct sockaddr_qrtr sq; 220 221 struct work_struct work; 222 struct workqueue_struct *wq; 223 224 void *recv_buf; 225 size_t recv_buf_size; 226 227 struct list_head lookups; 228 struct list_head lookup_results; 229 struct list_head services; 230 231 struct qmi_ops ops; 232 233 struct idr txns; 234 struct mutex txn_lock; 235 236 const struct qmi_msg_handler *handlers; 237 }; 238 239 int qmi_add_lookup(struct qmi_handle *qmi, unsigned int service, 240 unsigned int version, unsigned int instance); 241 int qmi_add_server(struct qmi_handle *qmi, unsigned int service, 242 unsigned int version, unsigned int instance); 243 244 int qmi_handle_init(struct qmi_handle *qmi, size_t max_msg_len, 245 const struct qmi_ops *ops, 246 const struct qmi_msg_handler *handlers); 247 void qmi_handle_release(struct qmi_handle *qmi); 248 249 ssize_t qmi_send_request(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, 250 struct qmi_txn *txn, int msg_id, size_t len, 251 struct qmi_elem_info *ei, const void *c_struct); 252 ssize_t qmi_send_response(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, 253 struct qmi_txn *txn, int msg_id, size_t len, 254 struct qmi_elem_info *ei, const void *c_struct); 255 ssize_t qmi_send_indication(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, 256 int msg_id, size_t len, struct qmi_elem_info *ei, 257 const void *c_struct); 258 259 void *qmi_encode_message(int type, unsigned int msg_id, size_t *len, 260 unsigned int txn_id, struct qmi_elem_info *ei, 261 const void *c_struct); 262 263 int qmi_decode_message(const void *buf, size_t len, 264 struct qmi_elem_info *ei, void *c_struct); 265 266 int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn, 267 struct qmi_elem_info *ei, void *c_struct); 268 int qmi_txn_wait(struct qmi_txn *txn, unsigned long timeout); 269 void qmi_txn_cancel(struct qmi_txn *txn); 270 271 #endif 272