diff options
Diffstat (limited to 'dev.c')
-rw-r--r-- | dev.c | 99 |
1 files changed, 99 insertions, 0 deletions
@@ -27,7 +27,14 @@ #include "uqmi.h" #include "qmi-errors.h" #include "qmi-errors.c" + #include "mbim.h" +#define LIBQMI_QMI_PROXY 1 + +#ifdef LIBQMI_QMI_PROXY +#include <sys/socket.h> +#include <sys/un.h> +#endif bool cancel_all_requests = false; @@ -91,6 +98,22 @@ static void __qmi_request_complete(struct qmi_dev *qmi, struct qmi_request *req, } } +static void __mbim_proxy_request_complete(struct qmi_dev *qmi, struct mbim_command_message *msg) +{ + struct qmi_request *req = list_first_entry(&qmi->req, struct qmi_request, list); + + if (!req->pending) + return; + + req->pending = false; + list_del(&req->list); + req->ret = le32_to_cpu(msg->command_type); // actually status + if (req->complete) { + *req->complete = true; + uloop_cancelled = true; + } +} + static void qmi_process_msg(struct qmi_dev *qmi, struct qmi_msg *msg) { struct qmi_request *req; @@ -138,6 +161,9 @@ static void qmi_notify_read(struct ustream *us, int bytes) msg = (struct qmi_msg *) (buf + sizeof(*mbim)); msg_len = le32_to_cpu(mbim->header.length); if (!is_mbim_qmi(mbim)) { + if (is_mbim_proxy(mbim)) + __mbim_proxy_request_complete(qmi, mbim); + /* must consume other MBIM packets */ ustream_consume(us, msg_len); return; @@ -368,6 +394,79 @@ int qmi_device_open(struct qmi_dev *qmi, const char *path) return 0; } +#ifdef LIBQMI_QMI_PROXY + +static void no_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg) +{ +} + +int qmi_device_proxy_open(struct qmi_dev *qmi, const char *path) +{ + static struct { + struct mbim_command_message mbim; + union { + char buf[2048]; + struct qmi_msg msg; + } u; + } __packed msgbuf; + struct ustream *us = &qmi->sf.stream; + int fd; + + uloop_init(); + + fd = socket(PF_UNIX, SOCK_STREAM, 0); + if (fd < 0) + return -1; + + if (qmi->is_mbim) { + struct sockaddr_un addr = { .sun_family = AF_UNIX, .sun_path = "\0mbim-proxy" }; + fprintf(stderr,"connecting to mbim proxy\n"); + if (connect(fd, (struct sockaddr *)&addr, 13)) { + perror("failed to connect to mbim-proxy: "); + return -1; + } + } else { + struct sockaddr_un addr = { .sun_family = AF_UNIX, .sun_path = "\0qmi-proxy" }; + fprintf(stderr,"connecting to qmi proxy\n"); + if (connect(fd, (struct sockaddr *)&addr, 12)) { + perror("failed to connect to qmi-proxy: "); + return -1; + } + } + + us->notify_read = qmi_notify_read; + ustream_fd_init(&qmi->sf, fd); + INIT_LIST_HEAD(&qmi->req); + qmi->ctl_tid = 1; + qmi->buf = msgbuf.u.buf; + + if (qmi->is_mbim) { + struct qmi_request req = {}; + int len = mbim_proxy_cmd(&msgbuf.mbim, path); + dump_packet("foo", &msgbuf, 90); + ustream_write(&qmi->sf.stream, (void *)&msgbuf, len, false); + memset(&req, 0, sizeof(req)); + req.ret = -1; + req.pending = true; + list_add(&req.list, &qmi->req); + qmi_request_wait(qmi, &req); + fprintf(stderr, "got return status 0x%04x\n", req.ret); + } else { + struct qmi_request req; + struct qmi_ctl_internal_proxy_open_request sreq = { + QMI_INIT_PTR(device_path, (char *)path) + }; + + qmi_set_ctl_internal_proxy_open_request(&msgbuf.u.msg, &sreq); + dump_packet("foo", &msgbuf.u.msg, 40); + qmi_request_start(qmi, &req, no_cb); + qmi_request_wait(qmi, &req); + } + + return 0; +} +#endif + void qmi_device_close(struct qmi_dev *qmi) { struct qmi_request *req; |