broadband-modem-qmi: implement Time interface
Signed-off-by: Dan Williams <dan@ioncontrol.co>
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
#include "mm-iface-modem-firmware.h"
|
||||
#include "mm-iface-modem-sar.h"
|
||||
#include "mm-iface-modem-signal.h"
|
||||
#include "mm-iface-modem-time.h"
|
||||
#include "mm-iface-modem-oma.h"
|
||||
#include "mm-shared-qmi.h"
|
||||
#include "mm-sim-qmi.h"
|
||||
@@ -67,12 +68,14 @@ static void iface_modem_oma_init (MMIfaceModemOmaInterface
|
||||
static void iface_modem_firmware_init (MMIfaceModemFirmwareInterface *iface);
|
||||
static void iface_modem_sar_init (MMIfaceModemSarInterface *iface);
|
||||
static void iface_modem_signal_init (MMIfaceModemSignalInterface *iface);
|
||||
static void iface_modem_time_init (MMIfaceModemTimeInterface *iface);
|
||||
static void shared_qmi_init (MMSharedQmi *iface);
|
||||
|
||||
static MMIfaceModemCellBroadcastInterface *iface_modem_cell_broadcast_parent;
|
||||
static MMIfaceModemLocationInterface *iface_modem_location_parent;
|
||||
static MMIfaceModemMessagingInterface *iface_modem_messaging_parent;
|
||||
static MMIfaceModemVoiceInterface *iface_modem_voice_parent;
|
||||
static MMIfaceModemTimeInterface *iface_modem_time_parent;
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemQmi, mm_broadband_modem_qmi, MM_TYPE_BROADBAND_MODEM, 0,
|
||||
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
|
||||
@@ -86,6 +89,7 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemQmi, mm_broadband_modem_qmi, MM_TYPE_BRO
|
||||
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init)
|
||||
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_SAR, iface_modem_sar_init)
|
||||
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_SIGNAL, iface_modem_signal_init)
|
||||
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init)
|
||||
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_OMA, iface_modem_oma_init)
|
||||
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_FIRMWARE, iface_modem_firmware_init)
|
||||
G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_QMI, shared_qmi_init))
|
||||
@@ -190,6 +194,9 @@ struct _MMBroadbandModemQmiPrivate {
|
||||
/* Packet service state helpers when using NAS System Info and DSD
|
||||
* (not applicable when using NAS Serving System) */
|
||||
gboolean dsd_supported;
|
||||
|
||||
/* NAS doesn't support Get Network Time; chain up to parent */
|
||||
gboolean nas_time_use_parent;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -9366,6 +9373,326 @@ enable_location_gathering (MMIfaceModemLocation *self,
|
||||
task);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Load network time (Time interface) */
|
||||
|
||||
static gchar *
|
||||
modem_time_load_network_time_finish (MMIfaceModemTime *self,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
return g_task_propagate_pointer (G_TASK (res), error);
|
||||
}
|
||||
|
||||
static void
|
||||
get_time_ready (QmiClientNas *client,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
g_autoptr(QmiMessageNasGetNetworkTimeOutput) output = NULL;
|
||||
GError *error = NULL;
|
||||
guint16 year = 0;
|
||||
guint8 month = 0;
|
||||
guint8 day = 0;
|
||||
guint8 hour = 0;
|
||||
guint8 minute = 0;
|
||||
guint8 second = 0;
|
||||
gint8 tz_offset = 0;
|
||||
|
||||
output = qmi_client_nas_get_network_time_finish (client, res, &error);
|
||||
if (!output) {
|
||||
g_prefix_error (&error, "QMI operation failed: ");
|
||||
g_task_return_error (task, error);
|
||||
} else if (!qmi_message_nas_get_network_time_output_get_result (output, &error)) {
|
||||
g_prefix_error (&error, "Couldn't get network time: ");
|
||||
g_task_return_error (task, error);
|
||||
} else if (!qmi_message_nas_get_network_time_output_get_3gpp_time (output,
|
||||
&year,
|
||||
&month,
|
||||
&day,
|
||||
&hour,
|
||||
&minute,
|
||||
&second,
|
||||
NULL,
|
||||
&tz_offset,
|
||||
NULL,
|
||||
NULL,
|
||||
&error)) {
|
||||
g_prefix_error (&error, "Couldn't get 3GPP network time info: ");
|
||||
g_task_return_error (task, error);
|
||||
} else {
|
||||
gchar *iso8601p;
|
||||
|
||||
/* Return ISO-8601 format date/time string */
|
||||
iso8601p = mm_new_iso8601_time (year, month, day, hour,
|
||||
minute, second,
|
||||
TRUE, (tz_offset * 15),
|
||||
&error);
|
||||
if (iso8601p)
|
||||
g_task_return_pointer (task, iso8601p, g_free);
|
||||
else
|
||||
g_task_return_error (task, error);
|
||||
}
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
parent_load_network_time_ready (MMIfaceModemTime *self,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gchar *iso8601p;
|
||||
|
||||
iso8601p = iface_modem_time_parent->load_network_time_finish (self, res, &error);
|
||||
if (error)
|
||||
g_task_return_error (task, error);
|
||||
else
|
||||
g_task_return_pointer (task, iso8601p, g_free);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
modem_time_load_network_time (MMIfaceModemTime *_self,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
|
||||
QmiClient *client;
|
||||
GTask *task;
|
||||
GError *error = NULL;
|
||||
|
||||
task = g_task_new (self, NULL, callback, user_data);
|
||||
|
||||
if (self->priv->nas_time_use_parent) {
|
||||
iface_modem_time_parent->load_network_time (
|
||||
MM_IFACE_MODEM_TIME (self),
|
||||
(GAsyncReadyCallback) parent_load_network_time_ready,
|
||||
task);
|
||||
return;
|
||||
}
|
||||
|
||||
client = mm_shared_qmi_peek_client (MM_SHARED_QMI (self),
|
||||
QMI_SERVICE_NAS,
|
||||
MM_PORT_QMI_FLAG_DEFAULT,
|
||||
&error);
|
||||
if (!client) {
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
qmi_client_nas_get_network_time (QMI_CLIENT_NAS (client),
|
||||
NULL,
|
||||
10,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)get_time_ready,
|
||||
task);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Load network timezone (Time interface) */
|
||||
|
||||
static MMNetworkTimezone *
|
||||
modem_time_load_network_timezone_finish (MMIfaceModemTime *self,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
return g_task_propagate_pointer (G_TASK (res), error);
|
||||
}
|
||||
|
||||
static void
|
||||
get_timezone_ready (QmiClientNas *client,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
g_autoptr(QmiMessageNasGetNetworkTimeOutput) output = NULL;
|
||||
GError *error = NULL;
|
||||
gint8 tz_offset = 0;
|
||||
|
||||
output = qmi_client_nas_get_network_time_finish (client, res, &error);
|
||||
if (!output) {
|
||||
g_prefix_error (&error, "QMI operation failed: ");
|
||||
g_task_return_error (task, error);
|
||||
} else if (!qmi_message_nas_get_network_time_output_get_result (output, &error)) {
|
||||
g_prefix_error (&error, "Couldn't get network time: ");
|
||||
g_task_return_error (task, error);
|
||||
} else if (!qmi_message_nas_get_network_time_output_get_3gpp_time (output,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&tz_offset,
|
||||
NULL,
|
||||
NULL,
|
||||
&error)) {
|
||||
g_prefix_error (&error, "Couldn't get 3GPP network time info: ");
|
||||
g_task_return_error (task, error);
|
||||
} else {
|
||||
MMNetworkTimezone *tz;
|
||||
|
||||
tz = mm_network_timezone_new ();
|
||||
mm_network_timezone_set_offset (tz, tz_offset * 15);
|
||||
g_task_return_pointer (task, tz, g_object_unref);
|
||||
}
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
parent_load_network_timezone_ready (MMIfaceModemTime *self,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
GError *error = NULL;
|
||||
MMNetworkTimezone *tz;
|
||||
|
||||
tz = iface_modem_time_parent->load_network_timezone_finish (self, res, &error);
|
||||
if (error)
|
||||
g_task_return_error (task, error);
|
||||
else
|
||||
g_task_return_pointer (task, tz, g_object_unref);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
modem_time_load_network_timezone (MMIfaceModemTime *_self,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
|
||||
QmiClient *client;
|
||||
GTask *task;
|
||||
GError *error = NULL;
|
||||
|
||||
task = g_task_new (self, NULL, callback, user_data);
|
||||
|
||||
if (self->priv->nas_time_use_parent) {
|
||||
iface_modem_time_parent->load_network_timezone (
|
||||
MM_IFACE_MODEM_TIME (self),
|
||||
(GAsyncReadyCallback) parent_load_network_timezone_ready,
|
||||
task);
|
||||
return;
|
||||
}
|
||||
|
||||
client = mm_shared_qmi_peek_client (MM_SHARED_QMI (self),
|
||||
QMI_SERVICE_NAS,
|
||||
MM_PORT_QMI_FLAG_DEFAULT,
|
||||
&error);
|
||||
if (!client) {
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
qmi_client_nas_get_network_time (QMI_CLIENT_NAS (client),
|
||||
NULL,
|
||||
10,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)get_timezone_ready,
|
||||
task);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Check support (Time interface) */
|
||||
|
||||
static gboolean
|
||||
modem_time_check_support_finish (MMIfaceModemTime *self,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
return g_task_propagate_boolean (G_TASK (res), error);
|
||||
}
|
||||
|
||||
static void
|
||||
parent_time_check_support_ready (MMIfaceModemTime *_self,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
|
||||
GError *error = NULL;
|
||||
gboolean supported;
|
||||
|
||||
self->priv->nas_time_use_parent = TRUE;
|
||||
|
||||
supported = iface_modem_time_parent->check_support_finish (_self, res, &error);
|
||||
if (error)
|
||||
g_task_return_error (task, error);
|
||||
else
|
||||
g_task_return_boolean (task, supported);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
check_time_support_ready (QmiClientNas *client,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
MMBroadbandModemQmi *self;
|
||||
g_autoptr(QmiMessageNasGetNetworkTimeOutput) output = NULL;
|
||||
|
||||
self = g_task_get_source_object (task);
|
||||
|
||||
output = qmi_client_nas_get_network_time_finish (client, res, NULL);
|
||||
if (!output || !qmi_message_nas_get_network_time_output_get_result (output, NULL)) {
|
||||
/* Try parent implementation */
|
||||
if (iface_modem_time_parent->check_support &&
|
||||
iface_modem_time_parent->load_network_time &&
|
||||
iface_modem_time_parent->load_network_time_finish &&
|
||||
iface_modem_time_parent->load_network_timezone &&
|
||||
iface_modem_time_parent->load_network_timezone_finish) {
|
||||
iface_modem_time_parent->check_support (
|
||||
MM_IFACE_MODEM_TIME (self),
|
||||
(GAsyncReadyCallback) parent_time_check_support_ready,
|
||||
task);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise unsupported */
|
||||
g_task_return_boolean (task, FALSE);
|
||||
} else {
|
||||
g_task_return_boolean (task, TRUE);
|
||||
}
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
modem_time_check_support (MMIfaceModemTime *self,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
QmiClient *client;
|
||||
GTask *task;
|
||||
GError *error = NULL;
|
||||
|
||||
task = g_task_new (self, NULL, callback, user_data);
|
||||
|
||||
client = mm_shared_qmi_peek_client (MM_SHARED_QMI (self),
|
||||
QMI_SERVICE_NAS,
|
||||
MM_PORT_QMI_FLAG_DEFAULT,
|
||||
&error);
|
||||
if (!client) {
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
qmi_client_nas_get_network_time (QMI_CLIENT_NAS (client),
|
||||
NULL,
|
||||
10,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)check_time_support_ready,
|
||||
task);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Check support (OMA interface) */
|
||||
|
||||
@@ -15057,6 +15384,19 @@ iface_modem_sar_init (MMIfaceModemSarInterface *iface)
|
||||
iface->set_power_level_finish = sar_set_power_level_finish;
|
||||
}
|
||||
|
||||
static void
|
||||
iface_modem_time_init (MMIfaceModemTimeInterface *iface)
|
||||
{
|
||||
iface_modem_time_parent = g_type_interface_peek_parent (iface);
|
||||
|
||||
iface->check_support = modem_time_check_support;
|
||||
iface->check_support_finish = modem_time_check_support_finish;
|
||||
iface->load_network_time = modem_time_load_network_time;
|
||||
iface->load_network_time_finish = modem_time_load_network_time_finish;
|
||||
iface->load_network_timezone = modem_time_load_network_timezone;
|
||||
iface->load_network_timezone_finish = modem_time_load_network_timezone_finish;
|
||||
}
|
||||
|
||||
static void
|
||||
iface_modem_signal_init (MMIfaceModemSignalInterface *iface)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user