From: Adam Pigg <piggz1@gmail.com>
To: ofono@lists.linux.dev
Subject: RFC - Add AT interface to qmi device
Date: Tue, 30 Apr 2024 22:49:05 +0100 [thread overview]
Message-ID: <2269874.vFx2qVVIhK@adam-laptop-hp> (raw)
Hi
I would appreciate views on this patch I need for the Pinephone modem. This
adds code to the gobi plugin and qmi_device to get a handle to the GAtChat Aux
interface. The voicecall and sms drivers can then use this interface to
trigger call/sms notification.
This is done in addition to the QMI interface, because it seems that
_sometimes_ the modem does not always send the QMI notification, or it is
missed due to the phone being in a deep sleep state. The AT interface is
always triggered.
I do not expect to upstream this, but there may be useful parts, or you may be
able to suggest another method?
Thanks
Adam
diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c
index 69a0e535..d94c5498 100644
--- a/drivers/qmimodem/qmi.c
+++ b/drivers/qmimodem/qmi.c
@@ -39,6 +39,7 @@
#include <ell/ell.h>
#include <ofono/log.h>
+#include <gatchat.h>
#include "qmi.h"
#include "ctl.h"
@@ -106,6 +107,7 @@ struct qmi_device {
bool writer_active : 1;
bool shutting_down : 1;
bool destroyed : 1;
+ GAtChat *atmodem;
};
struct qmi_device_qmux {
@@ -1053,6 +1055,22 @@ bool qmi_device_has_service(struct qmi_device *device,
uint16_t type)
return __find_service_info_by_type(device, type);
}
+void qmi_device_set_atmodem(struct qmi_device *device, GAtChat* atmodem)
+{
+ if (device == NULL)
+ return;
+
+ device->atmodem = atmodem;
+}
+
+GAtChat* qmi_device_get_atmodem(struct qmi_device *device)
+{
+ if (device == NULL)
+ return NULL;
+
+ return device->atmodem;
+}
+
struct discover_data {
struct discovery super;
struct qmi_device *device;
diff --git a/drivers/qmimodem/qmi.h b/drivers/qmimodem/qmi.h
index 0075f738..7bc423aa 100644
--- a/drivers/qmimodem/qmi.h
+++ b/drivers/qmimodem/qmi.h
@@ -21,6 +21,7 @@
#include <stdbool.h>
#include <stdint.h>
+#include <gatchat.h>
#define QMI_SERVICE_CONTROL 0 /* Control service */
#define QMI_SERVICE_WDS 1 /* Wireless data service
*/
@@ -77,6 +78,9 @@ typedef void (*qmi_destroy_func_t)(void *user_data);
struct qmi_device;
+void qmi_device_set_atmodem(struct qmi_device *device, GAtChat* atmodem);
+GAtChat* qmi_device_get_atmodem(struct qmi_device *device);
+
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);
diff --git a/drivers/qmimodem/sms.c b/drivers/qmimodem/sms.c
index c6252d9d..f8882ab9 100644
--- a/drivers/qmimodem/sms.c
+++ b/drivers/qmimodem/sms.c
@@ -30,6 +30,8 @@
#include <ofono/modem.h>
#include <ofono/sms.h>
+#include <gatchat.h>
+
#include "qmi.h"
#include "wms.h"
#include "util.h"
@@ -776,6 +778,15 @@ static void create_wms_cb(struct qmi_service *service,
void *user_data)
ofono_sms_register(sms);
}
+static void qmi_sms_at_notify(GAtResult *result, gpointer user_data)
+{
+ struct ofono_sms *sms = user_data;
+
+ DBG("");
+
+ get_msg_list(sms);
+}
+
static int qmi_sms_probe(struct ofono_sms *sms,
unsigned int vendor, void
*user_data)
{
@@ -790,6 +801,12 @@ static int qmi_sms_probe(struct ofono_sms *sms,
qmi_service_create(device, QMI_SERVICE_WMS, create_wms_cb, sms,
NULL);
+ GAtChat* atmodem = qmi_device_get_atmodem(device);
+ if (atmodem) {
+ guint ret = g_at_chat_register(atmodem, "+CMTI:",
qmi_sms_at_notify, FALSE, sms, NULL);
+ DBG("SMS AT CHAT REGISTER %d", ret);
+ }
+
return 0;
}
diff --git a/drivers/qmimodem/voicecall.c b/drivers/qmimodem/voicecall.c
index c6383a56..4b01b784 100644
--- a/drivers/qmimodem/voicecall.c
+++ b/drivers/qmimodem/voicecall.c
@@ -24,12 +24,15 @@
#include <config.h>
#endif
+#include <ofono.h>
#include <ofono/log.h>
#include <ofono/modem.h>
#include <ofono/voicecall.h>
#include <src/common.h>
#include <ell/ell.h>
+#include <gatchat.h>
+
#include "voice.h"
#include "qmi.h"
@@ -750,6 +753,17 @@ static void create_voice_cb(struct qmi_service *service,
void *user_data)
ofono_voicecall_register(vc);
}
+static void qmi_voicecall_ring_notify(GAtResult *result, gpointer user_data)
{
+ struct ofono_voicecall *vc = user_data;
+ struct voicecall_data *data = ofono_voicecall_get_data(vc);
+
+ DBG("DETECTED AT RING");
+
+ qmi_service_send(data->voice, QMI_VOICE_ALL_CALL_STATUS_IND, NULL,
+ all_call_status_ind, vc, NULL);
+
+}
+
static int qmi_voicecall_probe(struct ofono_voicecall *vc,
unsigned int vendor,
void *user_data)
{
@@ -766,6 +780,15 @@ static int qmi_voicecall_probe(struct ofono_voicecall
*vc,
qmi_service_create(device, QMI_SERVICE_VOICE,
create_voice_cb, vc,
NULL);
+ //Get a handle to the modem serial interface to detect RING signals
+ //Sometimes the QMI notify doesnt come through if the phone is
+ //asleep
+ GAtChat* atmodem = qmi_device_get_atmodem(device);
+ if (atmodem) {
+ guint ret = g_at_chat_register(atmodem, "RING",
qmi_voicecall_ring_notify, FALSE, vc, NULL);
+ DBG("VOICE AT CHAT REGISTER %d", ret);
+ }
+
return 0;
}
diff --git a/plugins/gobi.c b/plugins/gobi.c
index 550ce787..4a4d9d1b 100644
--- a/plugins/gobi.c
+++ b/plugins/gobi.c
@@ -29,6 +29,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <net/if.h>
+#include <gatchat.h>
#define OFONO_API_SUBJECT_TO_CHANGE
#include <ofono/plugin.h>
@@ -60,6 +61,12 @@
#include <drivers/qmimodem/wda.h>
#include <drivers/qmimodem/util.h>
+//Define function from atutil.h as it cant be uncluded
+GAtChat *at_util_open_device(struct ofono_modem *modem, const char *key,
+ GAtDebugFunc debug_func, char
*debug_prefix,
+ char *tty_option, ...);
+
+
#define GOBI_DMS (1 << 0)
#define GOBI_NAS (1 << 1)
#define GOBI_WMS (1 << 2)
@@ -448,6 +455,15 @@ static int gobi_enable(struct ofono_modem *modem)
if (getenv("OFONO_QMI_DEBUG"))
qmi_device_set_debug(data->device, gobi_debug, "QMI: ");
+ //Get a handle to an AT interface if one was found, and attach it
to the qmi_device
+ GAtChat *atchat = at_util_open_device(modem, "Aux", NULL, "Aux: ",
NULL);
+ if (!atchat) {
+ DBG("No Aux");
+ } else {
+ DBG("Have atmodem");
+ }
+ qmi_device_set_atmodem(data->device, atchat); //Will set to NULL if
doesnt exist
+
r = qmi_device_discover(data->device, discover_cb, modem, NULL);
if (!r)
return -EINPROGRESS;
diff --git a/plugins/udevng.c b/plugins/udevng.c
index b9d115f1..3f72ec3f 100644
--- a/plugins/udevng.c
+++ b/plugins/udevng.c
@@ -2085,6 +2085,12 @@ static void check_usb_device(struct udev_device
*device)
const char *syspath, *devname, *driver;
const char *vendor = NULL, *model = NULL;
const char *kernel_driver;
+ const char* devsyspath = udev_device_get_syspath(device);
+
+ if (devsyspath == NULL) {
+ return;
+ }
+ DBG("devsyspath: %s", devsyspath);
usb_device = udev_device_get_parent_with_subsystem_devtype(device,
"usb", "usb_device");
@@ -2156,10 +2162,39 @@ static void check_usb_device(struct udev_device
*device)
if (driver == NULL)
return;
- }
- add_device(syspath, devname, driver, vendor, model, MODEM_TYPE_USB,
+ add_device(syspath, devname, driver, vendor, model,
MODEM_TYPE_USB,
device, kernel_driver);
+
+ return;
+ }
+
+ //Now handle device as opposed to parent device
+ driver = udev_device_get_property_value(device, "ID_USB_DRIVER");
+ DBG("driver: %s", driver);
+
+ for (unsigned int i = 0; vendor_list[i].driver; i++) {
+ if (g_str_equal(vendor_list[i].drv, driver) == FALSE)
+ continue;
+
+ if (vendor_list[i].vid) {
+ if (!g_str_equal(vendor_list[i].vid, vendor))
+ continue;
+ }
+
+ if (vendor_list[i].pid) {
+ if (!g_str_equal(vendor_list[i].pid, model))
+ continue;
+ }
+
+ driver = vendor_list[i].driver;
+ }
+
+ if (driver == NULL)
+ return;
+
+ add_device(devsyspath, devname, driver, vendor, model,
MODEM_TYPE_USB,
+ device, kernel_driver);
}
static const struct {
next reply other threads:[~2024-04-30 21:49 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-30 21:49 Adam Pigg [this message]
2024-05-01 21:01 ` RFC - Add AT interface to qmi device Denis Kenzior
2024-05-19 18:26 ` Tony Lindgren
2024-05-20 18:58 ` Denis Kenzior
2024-05-21 3:11 ` Tony Lindgren
-- strict thread matches above, loose matches on Subject: below --
2024-04-30 21:43 Adam Pigg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2269874.vFx2qVVIhK@adam-laptop-hp \
--to=piggz1@gmail.com \
--cc=ofono@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).