aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2024-02-20 10:31:10 -0600
committerDenis Kenzior <denkenz@gmail.com>2024-02-21 10:28:22 -0600
commit7cf914bdd49592f60c535cd2335238d3ff88f100 (patch)
tree620a7acd929bfdbbfaa01368e3dd7fde700eba2b
parent9e8452edbc614a838997d1d8506ac2693aed1797 (diff)
downloadofono-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.c67
-rw-r--r--drivers/qmimodem/qmi.h4
-rw-r--r--plugins/gobi.c11
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: ");