1 /* 2 * uqmi -- tiny QMI support implementation 3 * 4 * Copyright (C) 2023 Alexander Couzens <lynxis@fe80.eu> 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 /* Used by uqmid to contain the modem state */ 23 24 #include <stdint.h> 25 #include <talloc.h> 26 27 #include "qmi-struct.h" 28 #include "qmi-enums.h" 29 #include "qmi-message.h" 30 #include "qmi-enums-uim.h" 31 32 #include "logging.h" 33 #include "utils.h" 34 35 #include "modem.h" 36 #include "services.h" 37 #include "modem_fsm.h" 38 39 #include "modem_tx.h" 40 41 /* TODO: add qmap */ 42 /* TODO: check when we have to use the endpoint number (usb) */ 43 int 44 tx_wda_set_data_format(struct modem *modem, struct qmi_service *wda, request_cb cb) 45 { 46 struct qmi_request *req = talloc_zero(wda, struct qmi_request); 47 struct qmi_msg *msg = talloc_zero_size(req, 1024); 48 49 struct qmi_wda_set_data_format_request set_data_format_req = { 0 }; 50 qmi_set(&set_data_format_req, qos_format, false); 51 qmi_set(&set_data_format_req, link_layer_protocol, QMI_WDA_LINK_LAYER_PROTOCOL_RAW_IP); 52 qmi_set(&set_data_format_req, downlink_data_aggregation_protocol, QMI_WDA_DATA_AGGREGATION_PROTOCOL_DISABLED); 53 qmi_set(&set_data_format_req, uplink_data_aggregation_protocol, QMI_WDA_DATA_AGGREGATION_PROTOCOL_DISABLED); 54 55 int ret = qmi_set_wda_set_data_format_request(msg, &set_data_format_req); 56 if (ret) { 57 modem_log(modem, LOGL_ERROR, "Failed to encode set_data_format_req"); 58 return 1; 59 } 60 61 req->msg = msg; 62 req->cb = cb; 63 req->cb_data = modem; 64 return uqmi_service_send_msg(wda, req); 65 } 66 67 68 int tx_dms_set_operating_mode(struct modem *modem, struct qmi_service *dms, uint8_t operating_mode, request_cb cb) 69 { 70 struct qmi_request *req = talloc_zero(dms, struct qmi_request); 71 struct qmi_msg *msg = talloc_zero_size(req, 1024); 72 73 struct qmi_dms_set_operating_mode_request set_op_mode_req = { QMI_INIT(mode, operating_mode) }; 74 75 int ret = qmi_set_dms_set_operating_mode_request(msg, &set_op_mode_req); 76 if (ret) { 77 LOG_ERROR("Failed to encode get version info"); 78 return 1; 79 } 80 81 req->msg = msg; 82 req->cb = cb; 83 req->cb_data = modem; 84 return uqmi_service_send_msg(dms, req); 85 } 86 87 int tx_nas_subscribe_nas_events(struct modem *modem, struct qmi_service *nas, bool action, request_cb cb) 88 { 89 struct qmi_request *req = talloc_zero(nas, struct qmi_request); 90 struct qmi_msg *msg = talloc_zero_size(req, 1024); 91 92 struct qmi_nas_register_indications_request register_req = {}; 93 qmi_set(®ister_req, serving_system_events, action); 94 qmi_set(®ister_req, subscription_info, action); 95 qmi_set(®ister_req, system_info, action); 96 qmi_set(®ister_req, signal_info, action); 97 register_req.set.network_reject_information = 1; 98 register_req.data.network_reject_information.enable_network_reject_indications = action; 99 100 int ret = qmi_set_nas_register_indications_request(msg, ®ister_req); 101 if (ret) { 102 LOG_ERROR("Failed to encode get version info"); 103 return 1; 104 } 105 106 req->msg = msg; 107 req->cb = cb; 108 req->cb_data = modem; 109 return uqmi_service_send_msg(nas, req); 110 } 111 112 int tx_wds_get_profile_list(struct modem *modem, struct qmi_service *wds, request_cb cb) 113 { 114 struct qmi_request *req = talloc_zero(wds, struct qmi_request); 115 struct qmi_msg *msg = talloc_zero_size(req, 1024); 116 117 struct qmi_wds_get_profile_list_request profile_req = { QMI_INIT(profile_type, QMI_WDS_PROFILE_TYPE_3GPP) }; 118 119 int ret = qmi_set_wds_get_profile_list_request(msg, &profile_req); 120 if (ret) { 121 LOG_ERROR("Failed to encode get profile list"); 122 return 1; 123 } 124 125 req->msg = msg; 126 req->cb = cb; 127 req->cb_data = modem; 128 return uqmi_service_send_msg(wds, req); 129 } 130 131 int tx_wds_modify_profile(struct modem *modem, struct qmi_service *wds, request_cb cb, uint8_t profile, const char *apn, 132 uint8_t pdp_type, const char *username, const char *password) 133 { 134 struct qmi_request *req = talloc_zero(wds, struct qmi_request); 135 struct qmi_msg *msg = talloc_zero_size(req, 1024); 136 137 struct qmi_wds_modify_profile_request profile_req = {}; 138 139 profile_req.set.profile_identifier = 1; 140 profile_req.data.profile_identifier.profile_type = QMI_WDS_PROFILE_TYPE_3GPP; 141 profile_req.data.profile_identifier.profile_index = profile; 142 qmi_set(&profile_req, pdp_type, pdp_type); 143 144 if (apn) 145 profile_req.data.apn_name = (char *)apn; 146 if (username) 147 profile_req.data.username = (char *)username; 148 if (password) 149 profile_req.data.password = (char *)password; 150 151 qmi_set(&profile_req, roaming_disallowed_flag, !modem->config.roaming); 152 153 int ret = qmi_set_wds_modify_profile_request(msg, &profile_req); 154 if (ret) { 155 LOG_ERROR("Failed to encode get profile list"); 156 return 1; 157 } 158 159 req->msg = msg; 160 req->cb = cb; 161 req->cb_data = modem; 162 return uqmi_service_send_msg(wds, req); 163 } 164 165 int tx_wds_start_network(struct modem *modem, struct qmi_service *wds, request_cb cb, uint8_t profile_idx, 166 uint8_t ip_family) 167 { 168 struct qmi_request *req = talloc_zero(wds, struct qmi_request); 169 struct qmi_msg *msg = talloc_zero_size(req, 1024); 170 171 struct qmi_wds_start_network_request start_req = {}; 172 qmi_set(&start_req, profile_index_3gpp, profile_idx); 173 qmi_set(&start_req, ip_family_preference, ip_family); 174 qmi_set(&start_req, enable_autoconnect, false); 175 176 int ret = qmi_set_wds_start_network_request(msg, &start_req); 177 if (ret) { 178 LOG_ERROR("Failed to encode start network request"); 179 return 1; 180 } 181 182 req->msg = msg; 183 req->cb = cb; 184 req->cb_data = modem; 185 return uqmi_service_send_msg(wds, req); 186 } 187 188 int tx_wds_stop_network(struct modem *modem, struct qmi_service *wds, request_cb cb, uint32_t packet_data_handle, 189 bool *disable_autoconnect) 190 { 191 struct qmi_request *req = talloc_zero(wds, struct qmi_request); 192 struct qmi_msg *msg = talloc_zero_size(req, 1024); 193 194 struct qmi_wds_stop_network_request stop_req = {}; 195 196 qmi_set(&stop_req, packet_data_handle, packet_data_handle); 197 198 if (disable_autoconnect) 199 qmi_set(&stop_req, disable_autoconnect, *disable_autoconnect); 200 201 int ret = qmi_set_wds_stop_network_request(msg, &stop_req); 202 if (ret) { 203 LOG_ERROR("Failed to encode start network request"); 204 return 1; 205 } 206 207 req->msg = msg; 208 req->cb = cb; 209 req->cb_data = modem; 210 return uqmi_service_send_msg(wds, req); 211 } 212 213 int tx_wds_get_current_settings(struct modem *modem, struct qmi_service *wds, request_cb cb) 214 { 215 struct qmi_request *req = talloc_zero(wds, struct qmi_request); 216 struct qmi_msg *msg = talloc_zero_size(req, 1024); 217 218 struct qmi_wds_get_current_settings_request get_settings_req = {}; 219 qmi_set(&get_settings_req, requested_settings, 220 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PDP_TYPE | 221 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DNS_ADDRESS | 222 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GRANTED_QOS | 223 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_ADDRESS | 224 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GATEWAY_INFO | 225 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_MTU | 226 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DOMAIN_NAME_LIST | 227 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_FAMILY); 228 229 int ret = qmi_set_wds_get_current_settings_request(msg, &get_settings_req); 230 if (ret) { 231 LOG_ERROR("Failed to encode start network request"); 232 return 1; 233 } 234 235 req->msg = msg; 236 req->cb = cb; 237 req->cb_data = modem; 238 return uqmi_service_send_msg(wds, req); 239 } 240 241 int tx_uim_read_transparent_file(struct modem *modem, struct qmi_service *uim, request_cb cb, uint16_t file_id, 242 uint8_t *filepath, unsigned int filepath_n) 243 { 244 struct qmi_request *req = talloc_zero(uim, struct qmi_request); 245 struct qmi_msg *msg = talloc_zero_size(req, 1024); 246 247 struct qmi_uim_read_transparent_request read_transparent_req = {}; 248 249 read_transparent_req.set.file = true; 250 read_transparent_req.data.file.file_id = file_id; 251 read_transparent_req.data.file.file_path = filepath; 252 read_transparent_req.data.file.file_path_n = filepath_n; 253 254 read_transparent_req.set.read_information = true; 255 read_transparent_req.data.read_information.length = 0; 256 read_transparent_req.data.read_information.offset = 0; 257 258 read_transparent_req.set.session = 1; 259 read_transparent_req.data.session.session_type = 0; 260 read_transparent_req.data.session.application_identifier_n = 0; 261 read_transparent_req.data.session.application_identifier = NULL; 262 263 int ret = qmi_set_uim_read_transparent_request(msg, &read_transparent_req); 264 if (ret) { 265 LOG_ERROR("Failed to encode read_transparent_file"); 266 return 1; 267 } 268 269 req->msg = msg; 270 req->cb = cb; 271 req->cb_data = modem; 272 return uqmi_service_send_msg(uim, req); 273 } 274 275 int tx_uim_unblock_pin(struct modem *modem, struct qmi_service *uim, request_cb cb, 276 QmiUimPinId pin_id, char *new_pin_value, char *puk_value) 277 { 278 struct qmi_request *req = talloc_zero(uim, struct qmi_request); 279 struct qmi_msg *msg = talloc_zero_size(req, 1024); 280 281 struct qmi_uim_unblock_pin_request puk_request = {}; 282 puk_request.set.info = true; 283 puk_request.data.info.pin_id = pin_id; 284 puk_request.data.info.new_pin = new_pin_value; 285 puk_request.data.info.puk = puk_value; 286 287 /* FIXME: test if this is ok and not QMI_UIM_SESSION_TYPE_CARD_SLOT_1 */ 288 puk_request.data.session.session_type = 0; 289 puk_request.data.session.application_identifier_n = 0; 290 puk_request.data.session.application_identifier = NULL; 291 292 int ret = qmi_set_uim_unblock_pin_request(msg, &puk_request); 293 if (ret) { 294 LOG_ERROR("Failed to encode unblock_pin_request"); 295 return 1; 296 } 297 298 req->msg = msg; 299 req->cb = cb; 300 req->cb_data = modem; 301 return uqmi_service_send_msg(uim, req); 302 } 303 304 305 int tx_uim_verify_pin(struct modem *modem, struct qmi_service *uim, request_cb cb, 306 QmiUimPinId pin_id, char *pin_value) 307 { 308 struct qmi_request *req = talloc_zero(uim, struct qmi_request); 309 struct qmi_msg *msg = talloc_zero_size(req, 1024); 310 311 struct qmi_uim_verify_pin_request pin_request = {}; 312 pin_request.set.info = true; 313 pin_request.data.info.pin_id = pin_id; 314 pin_request.data.info.pin_value = pin_value; 315 316 317 pin_request.set.session = 1; 318 /* FIXME: test if this is ok and not QMI_UIM_SESSION_TYPE_CARD_SLOT_1 */ 319 pin_request.data.session.session_type = 0; 320 pin_request.data.session.application_identifier_n = 0; 321 pin_request.data.session.application_identifier = NULL; 322 323 int ret = qmi_set_uim_verify_pin_request(msg, &pin_request); 324 if (ret) { 325 LOG_ERROR("Failed to encode verify_pin_request"); 326 return 1; 327 } 328 329 req->msg = msg; 330 req->cb = cb; 331 req->cb_data = modem; 332 return uqmi_service_send_msg(uim, req); 333 } 334
This page was automatically generated by LXR 0.3.1. • OpenWrt