1 /* 2 * uqmi -- tiny QMI support implementation 3 * 4 * Copyright (C) 2014-2015 Felix Fietkau <nbd@openwrt.org> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the 18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301 USA. 20 */ 21 22 #ifndef __UQMI_H 23 #define __UQMI_H 24 25 #include <stdbool.h> 26 27 #include <libubox/uloop.h> 28 #include <libubox/ustream.h> 29 30 #include "qmi-message.h" 31 32 #ifdef DEBUG_PACKET 33 void dump_packet(const char *prefix, void *ptr, int len); 34 #else 35 static inline void dump_packet(const char *prefix, void *ptr, int len) 36 { 37 } 38 #endif 39 40 #define __qmi_services \ 41 __qmi_service(QMI_SERVICE_WDS), \ 42 __qmi_service(QMI_SERVICE_DMS), \ 43 __qmi_service(QMI_SERVICE_NAS), \ 44 __qmi_service(QMI_SERVICE_QOS), \ 45 __qmi_service(QMI_SERVICE_WMS), \ 46 __qmi_service(QMI_SERVICE_PDS), \ 47 __qmi_service(QMI_SERVICE_AUTH), \ 48 __qmi_service(QMI_SERVICE_AT), \ 49 __qmi_service(QMI_SERVICE_VOICE), \ 50 __qmi_service(QMI_SERVICE_CAT2), \ 51 __qmi_service(QMI_SERVICE_UIM), \ 52 __qmi_service(QMI_SERVICE_PBM), \ 53 __qmi_service(QMI_SERVICE_LOC), \ 54 __qmi_service(QMI_SERVICE_SAR), \ 55 __qmi_service(QMI_SERVICE_RMTFS), \ 56 __qmi_service(QMI_SERVICE_CAT), \ 57 __qmi_service(QMI_SERVICE_RMS), \ 58 __qmi_service(QMI_SERVICE_OMA), \ 59 __qmi_service(QMI_SERVICE_WDA) 60 61 #define __qmi_service(_n) __##_n 62 enum { 63 __qmi_services, 64 __QMI_SERVICE_LAST 65 }; 66 #undef __qmi_service 67 68 struct qmi_dev; 69 struct qmi_request; 70 struct qmi_msg; 71 72 typedef void (*request_cb)(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg); 73 74 struct qmi_dev { 75 struct ustream_fd sf; 76 77 struct list_head req; 78 79 struct { 80 bool connected; 81 uint8_t client_id; 82 uint16_t tid; 83 } service_data[__QMI_SERVICE_LAST]; 84 85 uint32_t service_connected; 86 uint32_t service_keep_cid; 87 uint32_t service_release_cid; 88 89 uint8_t ctl_tid; 90 void *buf; 91 92 bool is_mbim; 93 }; 94 95 struct qmi_request { 96 struct list_head list; 97 98 request_cb cb; 99 100 bool *complete; 101 bool pending; 102 bool no_error_cb; 103 uint8_t service; 104 uint16_t tid; 105 int ret; 106 }; 107 108 extern bool cancel_all_requests; 109 int qmi_device_open(struct qmi_dev *qmi, const char *path); 110 void qmi_device_close(struct qmi_dev *qmi); 111 112 int qmi_request_start(struct qmi_dev *qmi, struct qmi_request *req, request_cb cb); 113 void qmi_request_cancel(struct qmi_dev *qmi, struct qmi_request *req); 114 int qmi_request_wait(struct qmi_dev *qmi, struct qmi_request *req); 115 116 static inline bool qmi_request_pending(struct qmi_request *req) 117 { 118 return req->pending; 119 } 120 121 int qmi_service_connect(struct qmi_dev *qmi, QmiService svc, int client_id); 122 int qmi_service_get_client_id(struct qmi_dev *qmi, QmiService svc); 123 int qmi_service_release_client_id(struct qmi_dev *qmi, QmiService svc); 124 QmiService qmi_service_get_by_name(const char *str); 125 126 static inline uint8_t *uqmi_hexstring_parse(uint8_t *output, 127 const uint8_t *hexstr, 128 size_t hexstr_size) 129 { 130 uint8_t *out = output; 131 size_t i; 132 133 for (i = 0; i < hexstr_size; i += 2) { 134 if (hexstr[i] >= '' && hexstr[i] <= '9') 135 *out = (hexstr[i] - '') << 4; 136 else if (hexstr[i] >= 'a' && hexstr[i] <= 'f') 137 *out = (hexstr[i] - 'a' + 10) << 4; 138 else if (hexstr[i] >= 'A' && hexstr[i] <= 'F') 139 *out = (hexstr[i] - 'A' + 10) << 4; 140 else 141 return NULL; 142 143 if (i + 1 >= hexstr_size) 144 return NULL; 145 146 if (hexstr[i + 1] >= '' && hexstr[i + 1] <= '9') 147 *out |= hexstr[i + 1] - ''; 148 else if (hexstr[i + 1] >= 'a' && hexstr[i + 1] <= 'f') 149 *out |= hexstr[i + 1] - 'a' + 10; 150 else if (hexstr[i + 1] >= 'A' && hexstr[i + 1] <= 'F') 151 *out |= hexstr[i + 1] - 'A' + 10; 152 else 153 return NULL; 154 155 out++; 156 } 157 158 return output; 159 } 160 161 static inline uint8_t *uqmi_hexstring_create(uint8_t *output, 162 const uint8_t *data, 163 size_t data_size) 164 { 165 uint8_t *out = output; 166 size_t i; 167 168 for (i = 0; i < data_size; i++) { 169 *out++ = "0123456789abcdef"[data[i] >> 4]; 170 *out++ = "0123456789abcdef"[data[i] & 0xf]; 171 } 172 173 return output; 174 } 175 176 #endif 177
This page was automatically generated by LXR 0.3.1. • OpenWrt