diff options
author | Denis Kenzior <denkenz@gmail.com> | 2024-02-20 10:31:10 -0600 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2024-02-21 10:28:22 -0600 |
commit | 7cf914bdd49592f60c535cd2335238d3ff88f100 (patch) | |
tree | 620a7acd929bfdbbfaa01368e3dd7fde700eba2b | |
parent | 9e8452edbc614a838997d1d8506ac2693aed1797 (diff) | |
download | ofono-7cf914bdd49592f60c535cd2335238d3ff88f100.tar.gz |
qmi: Introduce qmi_device_new_qmux
In preparation for QRTR support, remove the existing qmi_device_new API
and rename it to qmi_device_new_qmux. Since QMUX usually runs on top of
a character device, have the constructor take in the character device
path, instead of having the caller open it manually.
As part of this refactoring, introduce the initial qmi_device_ops
structure which will be used to abstract qmi operation over QMUX and
QRTR.
-rw-r--r-- | drivers/qmimodem/qmi.c | 67 | ||||
-rw-r--r-- | drivers/qmimodem/qmi.h | 4 | ||||
-rw-r--r-- | plugins/gobi.c | 11 |
3 files changed, 56 insertions, 26 deletions
diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c index 72b55cd71..e938c13e1 100644 --- a/drivers/qmimodem/qmi.c +++ b/drivers/qmimodem/qmi.c @@ -55,6 +55,10 @@ struct qmi_version { const char *name; }; +struct qmi_device_ops { + void (*destroy)(struct qmi_device *device); +}; + struct qmi_device { int ref_count; int fd; @@ -81,10 +85,15 @@ struct qmi_device { void *shutdown_user_data; qmi_destroy_func_t shutdown_destroy; guint shutdown_source; + const struct qmi_device_ops *ops; bool shutting_down : 1; bool destroyed : 1; }; +struct qmi_device_qmux { + struct qmi_device super; +}; + struct qmi_service { int ref_count; struct qmi_device *device; @@ -905,13 +914,11 @@ static void service_destroy(void *data) service->device = NULL; } -struct qmi_device *qmi_device_new(int fd) +static int qmi_device_init(struct qmi_device *device, int fd, + const struct qmi_device_ops *ops) { - struct qmi_device *device; long flags; - device = l_new(struct qmi_device, 1); - __debug_device(device, "device %p new", device); device->ref_count = 1; @@ -920,16 +927,14 @@ struct qmi_device *qmi_device_new(int fd) device->close_on_unref = false; flags = fcntl(device->fd, F_GETFL, NULL); - if (flags < 0) { - l_free(device); - return NULL; - } + if (flags < 0) + return -EIO; if (!(flags & O_NONBLOCK)) { - if (fcntl(device->fd, F_SETFL, flags | O_NONBLOCK) < 0) { - l_free(device); - return NULL; - } + int r = fcntl(device->fd, F_SETFL, flags | O_NONBLOCK); + + if (r < 0) + return -errno; } device->io = g_io_channel_unix_new(device->fd); @@ -953,7 +958,9 @@ struct qmi_device *qmi_device_new(int fd) device->next_control_tid = 1; device->next_service_tid = 256; - return device; + device->ops = ops; + + return 0; } struct qmi_device *qmi_device_ref(struct qmi_device *device) @@ -1001,7 +1008,7 @@ void qmi_device_unref(struct qmi_device *device) if (device->shutting_down) device->destroyed = true; else - l_free(device); + device->ops->destroy(device); } void qmi_device_set_debug(struct qmi_device *device, @@ -1582,6 +1589,38 @@ done: return res; } +static void qmi_device_qmux_destroy(struct qmi_device *device) +{ + struct qmi_device_qmux *qmux = + l_container_of(device, struct qmi_device_qmux, super); + + l_free(qmux); +} + +static const struct qmi_device_ops qmux_ops = { + .destroy = qmi_device_qmux_destroy, +}; + +struct qmi_device *qmi_device_new_qmux(const char *device) +{ + struct qmi_device_qmux *qmux; + int fd; + + fd = open(device, O_RDWR | O_NONBLOCK | O_CLOEXEC); + if (fd < 0) + return NULL; + + qmux = l_new(struct qmi_device_qmux, 1); + + if (qmi_device_init(&qmux->super, fd, &qmux_ops) < 0) { + close(fd); + l_free(qmux); + return NULL; + } + + return &qmux->super; +} + struct qmi_param *qmi_param_new(void) { struct qmi_param *param; diff --git a/drivers/qmimodem/qmi.h b/drivers/qmimodem/qmi.h index fc2a30957..410ada04d 100644 --- a/drivers/qmimodem/qmi.h +++ b/drivers/qmimodem/qmi.h @@ -81,8 +81,6 @@ typedef void (*qmi_debug_func_t)(const char *str, void *user_data); typedef void (*qmi_shutdown_func_t)(void *user_data); typedef void (*qmi_discover_func_t)(void *user_data); -struct qmi_device *qmi_device_new(int fd); - struct qmi_device *qmi_device_ref(struct qmi_device *device); void qmi_device_unref(struct qmi_device *device); @@ -105,6 +103,8 @@ enum qmi_device_expected_data_format qmi_device_get_expected_data_format( bool qmi_device_set_expected_data_format(struct qmi_device *device, enum qmi_device_expected_data_format format); +struct qmi_device *qmi_device_new_qmux(const char *device); + struct qmi_param; struct qmi_param *qmi_param_new(void); diff --git a/plugins/gobi.c b/plugins/gobi.c index 020d6ba26..07994666d 100644 --- a/plugins/gobi.c +++ b/plugins/gobi.c @@ -423,7 +423,6 @@ static int gobi_enable(struct ofono_modem *modem) { struct gobi_data *data = ofono_modem_get_data(modem); const char *device; - int fd; DBG("%p", modem); @@ -431,15 +430,7 @@ static int gobi_enable(struct ofono_modem *modem) if (!device) return -EINVAL; - fd = open(device, O_RDWR | O_NONBLOCK | O_CLOEXEC); - if (fd < 0) - return -EIO; - - data->device = qmi_device_new(fd); - if (!data->device) { - close(fd); - return -ENOMEM; - } + data->device = qmi_device_new_qmux(device); if (getenv("OFONO_QMI_DEBUG")) qmi_device_set_debug(data->device, gobi_debug, "QMI: "); |