1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 /* 2 /* 3 * Copyright (c) 2012-2014, The Linux Foundati 3 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2017, Linaro Ltd. 4 * Copyright (c) 2017, Linaro Ltd. 5 */ 5 */ 6 #ifndef __QMI_HELPERS_H__ 6 #ifndef __QMI_HELPERS_H__ 7 #define __QMI_HELPERS_H__ 7 #define __QMI_HELPERS_H__ 8 8 9 #include <linux/completion.h> 9 #include <linux/completion.h> 10 #include <linux/idr.h> 10 #include <linux/idr.h> 11 #include <linux/list.h> 11 #include <linux/list.h> 12 #include <linux/qrtr.h> 12 #include <linux/qrtr.h> 13 #include <linux/types.h> 13 #include <linux/types.h> 14 #include <linux/workqueue.h> 14 #include <linux/workqueue.h> 15 15 16 struct socket; 16 struct socket; 17 17 18 /** 18 /** 19 * struct qmi_header - wireformat header of QM 19 * struct qmi_header - wireformat header of QMI messages 20 * @type: type of message 20 * @type: type of message 21 * @txn_id: transaction id 21 * @txn_id: transaction id 22 * @msg_id: message id 22 * @msg_id: message id 23 * @msg_len: length of message payload foll 23 * @msg_len: length of message payload following header 24 */ 24 */ 25 struct qmi_header { 25 struct qmi_header { 26 u8 type; 26 u8 type; 27 u16 txn_id; 27 u16 txn_id; 28 u16 msg_id; 28 u16 msg_id; 29 u16 msg_len; 29 u16 msg_len; 30 } __packed; 30 } __packed; 31 31 32 #define QMI_REQUEST 0 32 #define QMI_REQUEST 0 33 #define QMI_RESPONSE 2 33 #define QMI_RESPONSE 2 34 #define QMI_INDICATION 4 34 #define QMI_INDICATION 4 35 35 36 #define QMI_COMMON_TLV_TYPE 0 36 #define QMI_COMMON_TLV_TYPE 0 37 37 38 enum qmi_elem_type { 38 enum qmi_elem_type { 39 QMI_EOTI, 39 QMI_EOTI, 40 QMI_OPT_FLAG, 40 QMI_OPT_FLAG, 41 QMI_DATA_LEN, 41 QMI_DATA_LEN, 42 QMI_UNSIGNED_1_BYTE, 42 QMI_UNSIGNED_1_BYTE, 43 QMI_UNSIGNED_2_BYTE, 43 QMI_UNSIGNED_2_BYTE, 44 QMI_UNSIGNED_4_BYTE, 44 QMI_UNSIGNED_4_BYTE, 45 QMI_UNSIGNED_8_BYTE, 45 QMI_UNSIGNED_8_BYTE, 46 QMI_SIGNED_2_BYTE_ENUM, 46 QMI_SIGNED_2_BYTE_ENUM, 47 QMI_SIGNED_4_BYTE_ENUM, 47 QMI_SIGNED_4_BYTE_ENUM, 48 QMI_STRUCT, 48 QMI_STRUCT, 49 QMI_STRING, 49 QMI_STRING, 50 }; 50 }; 51 51 52 enum qmi_array_type { 52 enum qmi_array_type { 53 NO_ARRAY, 53 NO_ARRAY, 54 STATIC_ARRAY, 54 STATIC_ARRAY, 55 VAR_LEN_ARRAY, 55 VAR_LEN_ARRAY, 56 }; 56 }; 57 57 58 /** 58 /** 59 * struct qmi_elem_info - describes how to enc 59 * struct qmi_elem_info - describes how to encode a single QMI element 60 * @data_type: Data type of this element. 60 * @data_type: Data type of this element. 61 * @elem_len: Array length of this element, 61 * @elem_len: Array length of this element, if an array. 62 * @elem_size: Size of a single instance of t 62 * @elem_size: Size of a single instance of this data type. 63 * @array_type: Array type of this element. 63 * @array_type: Array type of this element. 64 * @tlv_type: QMI message specific type to i 64 * @tlv_type: QMI message specific type to identify which element 65 * is present in an incoming mess 65 * is present in an incoming message. 66 * @offset: Specifies the offset of the fi 66 * @offset: Specifies the offset of the first instance of this 67 * element in the data structure. 67 * element in the data structure. 68 * @ei_array: Null-terminated array of @qmi_ 68 * @ei_array: Null-terminated array of @qmi_elem_info to describe nested 69 * structures. 69 * structures. 70 */ 70 */ 71 struct qmi_elem_info { 71 struct qmi_elem_info { 72 enum qmi_elem_type data_type; 72 enum qmi_elem_type data_type; 73 u32 elem_len; 73 u32 elem_len; 74 u32 elem_size; 74 u32 elem_size; 75 enum qmi_array_type array_type; 75 enum qmi_array_type array_type; 76 u8 tlv_type; 76 u8 tlv_type; 77 u32 offset; 77 u32 offset; 78 const struct qmi_elem_info *ei_array; 78 const struct qmi_elem_info *ei_array; 79 }; 79 }; 80 80 81 #define QMI_RESULT_SUCCESS_V01 81 #define QMI_RESULT_SUCCESS_V01 0 82 #define QMI_RESULT_FAILURE_V01 82 #define QMI_RESULT_FAILURE_V01 1 83 83 84 #define QMI_ERR_NONE_V01 84 #define QMI_ERR_NONE_V01 0 85 #define QMI_ERR_MALFORMED_MSG_V01 85 #define QMI_ERR_MALFORMED_MSG_V01 1 86 #define QMI_ERR_NO_MEMORY_V01 86 #define QMI_ERR_NO_MEMORY_V01 2 87 #define QMI_ERR_INTERNAL_V01 87 #define QMI_ERR_INTERNAL_V01 3 88 #define QMI_ERR_CLIENT_IDS_EXHAUSTED_V01 88 #define QMI_ERR_CLIENT_IDS_EXHAUSTED_V01 5 89 #define QMI_ERR_INVALID_ID_V01 89 #define QMI_ERR_INVALID_ID_V01 41 90 #define QMI_ERR_ENCODING_V01 90 #define QMI_ERR_ENCODING_V01 58 91 #define QMI_ERR_DISABLED_V01 91 #define QMI_ERR_DISABLED_V01 69 92 #define QMI_ERR_INCOMPATIBLE_STATE_V01 92 #define QMI_ERR_INCOMPATIBLE_STATE_V01 90 93 #define QMI_ERR_NOT_SUPPORTED_V01 93 #define QMI_ERR_NOT_SUPPORTED_V01 94 94 94 95 /** 95 /** 96 * struct qmi_response_type_v01 - common respo 96 * struct qmi_response_type_v01 - common response header (decoded) 97 * @result: result of the transaction 97 * @result: result of the transaction 98 * @error: error value, when @result is Q 98 * @error: error value, when @result is QMI_RESULT_FAILURE_V01 99 */ 99 */ 100 struct qmi_response_type_v01 { 100 struct qmi_response_type_v01 { 101 u16 result; 101 u16 result; 102 u16 error; 102 u16 error; 103 }; 103 }; 104 104 105 extern const struct qmi_elem_info qmi_response 105 extern const struct qmi_elem_info qmi_response_type_v01_ei[]; 106 106 107 /** 107 /** 108 * struct qmi_service - context to track looku 108 * struct qmi_service - context to track lookup-results 109 * @service: service type 109 * @service: service type 110 * @version: version of the @service 110 * @version: version of the @service 111 * @instance: instance id of the @service 111 * @instance: instance id of the @service 112 * @node: node of the service 112 * @node: node of the service 113 * @port: port of the service 113 * @port: port of the service 114 * @priv: handle for client's use 114 * @priv: handle for client's use 115 * @list_node: list_head for house keeping 115 * @list_node: list_head for house keeping 116 */ 116 */ 117 struct qmi_service { 117 struct qmi_service { 118 unsigned int service; 118 unsigned int service; 119 unsigned int version; 119 unsigned int version; 120 unsigned int instance; 120 unsigned int instance; 121 121 122 unsigned int node; 122 unsigned int node; 123 unsigned int port; 123 unsigned int port; 124 124 125 void *priv; 125 void *priv; 126 struct list_head list_node; 126 struct list_head list_node; 127 }; 127 }; 128 128 129 struct qmi_handle; 129 struct qmi_handle; 130 130 131 /** 131 /** 132 * struct qmi_ops - callbacks for qmi_handle 132 * struct qmi_ops - callbacks for qmi_handle 133 * @new_server: inform client of a new 133 * @new_server: inform client of a new_server lookup-result, returning 134 * successfully from this 134 * successfully from this call causes the library to call 135 * @del_server as the ser 135 * @del_server as the service is removed from the 136 * lookup-result. @priv o 136 * lookup-result. @priv of the qmi_service can be used by 137 * the client 137 * the client 138 * @del_server: inform client of a del 138 * @del_server: inform client of a del_server lookup-result 139 * @net_reset: inform client that the 139 * @net_reset: inform client that the name service was restarted and 140 * that and any state nee 140 * that and any state needs to be released 141 * @msg_handler: invoked for incoming m 141 * @msg_handler: invoked for incoming messages, allows a client to 142 * override the usual QMI 142 * override the usual QMI message handler 143 * @bye: inform a client that a 143 * @bye: inform a client that all clients from a node are gone 144 * @del_client: inform a client that a 144 * @del_client: inform a client that a particular client is gone 145 */ 145 */ 146 struct qmi_ops { 146 struct qmi_ops { 147 int (*new_server)(struct qmi_handle *q 147 int (*new_server)(struct qmi_handle *qmi, struct qmi_service *svc); 148 void (*del_server)(struct qmi_handle * 148 void (*del_server)(struct qmi_handle *qmi, struct qmi_service *svc); 149 void (*net_reset)(struct qmi_handle *q 149 void (*net_reset)(struct qmi_handle *qmi); 150 void (*msg_handler)(struct qmi_handle 150 void (*msg_handler)(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, 151 const void *data, 151 const void *data, size_t count); 152 void (*bye)(struct qmi_handle *qmi, un 152 void (*bye)(struct qmi_handle *qmi, unsigned int node); 153 void (*del_client)(struct qmi_handle * 153 void (*del_client)(struct qmi_handle *qmi, 154 unsigned int node, 154 unsigned int node, unsigned int port); 155 }; 155 }; 156 156 157 /** 157 /** 158 * struct qmi_txn - transaction context 158 * struct qmi_txn - transaction context 159 * @qmi: QMI handle this transaction is 159 * @qmi: QMI handle this transaction is associated with 160 * @id: transaction id 160 * @id: transaction id 161 * @lock: for synchronization between ha 161 * @lock: for synchronization between handler and waiter of messages 162 * @completion: completion object as the trans 162 * @completion: completion object as the transaction receives a response 163 * @result: result code for the completed 163 * @result: result code for the completed transaction 164 * @ei: description of the QMI encoded 164 * @ei: description of the QMI encoded response (optional) 165 * @dest: destination buffer to decode m 165 * @dest: destination buffer to decode message into (optional) 166 */ 166 */ 167 struct qmi_txn { 167 struct qmi_txn { 168 struct qmi_handle *qmi; 168 struct qmi_handle *qmi; 169 169 170 u16 id; 170 u16 id; 171 171 172 struct mutex lock; 172 struct mutex lock; 173 struct completion completion; 173 struct completion completion; 174 int result; 174 int result; 175 175 176 const struct qmi_elem_info *ei; 176 const struct qmi_elem_info *ei; 177 void *dest; 177 void *dest; 178 }; 178 }; 179 179 180 /** 180 /** 181 * struct qmi_msg_handler - description of QMI 181 * struct qmi_msg_handler - description of QMI message handler 182 * @type: type of message 182 * @type: type of message 183 * @msg_id: message id 183 * @msg_id: message id 184 * @ei: description of the QMI encoded 184 * @ei: description of the QMI encoded message 185 * @decoded_size: size of the decoded ob 185 * @decoded_size: size of the decoded object 186 * @fn: function to invoke as the mess 186 * @fn: function to invoke as the message is decoded 187 */ 187 */ 188 struct qmi_msg_handler { 188 struct qmi_msg_handler { 189 unsigned int type; 189 unsigned int type; 190 unsigned int msg_id; 190 unsigned int msg_id; 191 191 192 const struct qmi_elem_info *ei; 192 const struct qmi_elem_info *ei; 193 193 194 size_t decoded_size; 194 size_t decoded_size; 195 void (*fn)(struct qmi_handle *qmi, str 195 void (*fn)(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, 196 struct qmi_txn *txn, const 196 struct qmi_txn *txn, const void *decoded); 197 }; 197 }; 198 198 199 /** 199 /** 200 * struct qmi_handle - QMI context 200 * struct qmi_handle - QMI context 201 * @sock: socket handle 201 * @sock: socket handle 202 * @sock_lock: synchronization of @sock modif 202 * @sock_lock: synchronization of @sock modifications 203 * @sq: sockaddr of @sock 203 * @sq: sockaddr of @sock 204 * @work: work for handling incoming mes 204 * @work: work for handling incoming messages 205 * @wq: workqueue to post @work on 205 * @wq: workqueue to post @work on 206 * @recv_buf: scratch buffer for handling in 206 * @recv_buf: scratch buffer for handling incoming messages 207 * @recv_buf_size: size of @recv_buf 207 * @recv_buf_size: size of @recv_buf 208 * @lookups: list of registered loo 208 * @lookups: list of registered lookup requests 209 * @lookup_results: list of lookup-results 209 * @lookup_results: list of lookup-results advertised to the client 210 * @services: list of registered ser 210 * @services: list of registered services (by this client) 211 * @ops: reference to callbacks 211 * @ops: reference to callbacks 212 * @txns: outstanding transactions 212 * @txns: outstanding transactions 213 * @txn_lock: lock for modifications of @txn 213 * @txn_lock: lock for modifications of @txns 214 * @handlers: list of handlers for incoming 214 * @handlers: list of handlers for incoming messages 215 */ 215 */ 216 struct qmi_handle { 216 struct qmi_handle { 217 struct socket *sock; 217 struct socket *sock; 218 struct mutex sock_lock; 218 struct mutex sock_lock; 219 219 220 struct sockaddr_qrtr sq; 220 struct sockaddr_qrtr sq; 221 221 222 struct work_struct work; 222 struct work_struct work; 223 struct workqueue_struct *wq; 223 struct workqueue_struct *wq; 224 224 225 void *recv_buf; 225 void *recv_buf; 226 size_t recv_buf_size; 226 size_t recv_buf_size; 227 227 228 struct list_head lookups; 228 struct list_head lookups; 229 struct list_head lookup_results; 229 struct list_head lookup_results; 230 struct list_head services; 230 struct list_head services; 231 231 232 struct qmi_ops ops; 232 struct qmi_ops ops; 233 233 234 struct idr txns; 234 struct idr txns; 235 struct mutex txn_lock; 235 struct mutex txn_lock; 236 236 237 const struct qmi_msg_handler *handlers 237 const struct qmi_msg_handler *handlers; 238 }; 238 }; 239 239 240 int qmi_add_lookup(struct qmi_handle *qmi, uns 240 int qmi_add_lookup(struct qmi_handle *qmi, unsigned int service, 241 unsigned int version, unsig 241 unsigned int version, unsigned int instance); 242 int qmi_add_server(struct qmi_handle *qmi, uns 242 int qmi_add_server(struct qmi_handle *qmi, unsigned int service, 243 unsigned int version, unsig 243 unsigned int version, unsigned int instance); 244 244 245 int qmi_handle_init(struct qmi_handle *qmi, si 245 int qmi_handle_init(struct qmi_handle *qmi, size_t max_msg_len, 246 const struct qmi_ops *ops, 246 const struct qmi_ops *ops, 247 const struct qmi_msg_handl 247 const struct qmi_msg_handler *handlers); 248 void qmi_handle_release(struct qmi_handle *qmi 248 void qmi_handle_release(struct qmi_handle *qmi); 249 249 250 ssize_t qmi_send_request(struct qmi_handle *qm 250 ssize_t qmi_send_request(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, 251 struct qmi_txn *txn, 251 struct qmi_txn *txn, int msg_id, size_t len, 252 const struct qmi_elem 252 const struct qmi_elem_info *ei, const void *c_struct); 253 ssize_t qmi_send_response(struct qmi_handle *q 253 ssize_t qmi_send_response(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, 254 struct qmi_txn *txn, 254 struct qmi_txn *txn, int msg_id, size_t len, 255 const struct qmi_ele 255 const struct qmi_elem_info *ei, const void *c_struct); 256 ssize_t qmi_send_indication(struct qmi_handle 256 ssize_t qmi_send_indication(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, 257 int msg_id, size_t 257 int msg_id, size_t len, const struct qmi_elem_info *ei, 258 const void *c_stru 258 const void *c_struct); 259 259 260 void *qmi_encode_message(int type, unsigned in 260 void *qmi_encode_message(int type, unsigned int msg_id, size_t *len, 261 unsigned int txn_id, 261 unsigned int txn_id, const struct qmi_elem_info *ei, 262 const void *c_struct) 262 const void *c_struct); 263 263 264 int qmi_decode_message(const void *buf, size_t 264 int qmi_decode_message(const void *buf, size_t len, 265 const struct qmi_elem_i 265 const struct qmi_elem_info *ei, void *c_struct); 266 266 267 int qmi_txn_init(struct qmi_handle *qmi, struc 267 int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn, 268 const struct qmi_elem_info *e 268 const struct qmi_elem_info *ei, void *c_struct); 269 int qmi_txn_wait(struct qmi_txn *txn, unsigned 269 int qmi_txn_wait(struct qmi_txn *txn, unsigned long timeout); 270 void qmi_txn_cancel(struct qmi_txn *txn); 270 void qmi_txn_cancel(struct qmi_txn *txn); 271 271 272 #endif 272 #endif 273 273
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.