wwan/ofono: merge branch 'pr/771'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/771
This commit is contained in:
Thomas Haller 2021-03-15 13:32:59 +01:00
commit c96a21e3cf
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
3 changed files with 119 additions and 52 deletions

View file

@ -357,7 +357,6 @@ modem_state_cb(NMModem *modem, int new_state_i, int old_state_i, gpointer user_d
nm_device_state_changed(device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER);
return;
}
if (new_state > NM_MODEM_STATE_LOCKED && old_state == NM_MODEM_STATE_LOCKED) {

View file

@ -316,10 +316,9 @@ handle_sim_property(GDBusProxy *proxy, const char *property, GVariant *v, gpoint
static void
sim_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data)
{
GVariant *v_child = g_variant_get_child_value(v, 0);
gs_unref_variant GVariant *v_child = g_variant_get_child_value(v, 0);
handle_sim_property(proxy, property, v_child, user_data);
g_variant_unref(v_child);
}
static void
@ -330,7 +329,7 @@ sim_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_dat
gs_free_error GError *error = NULL;
gs_unref_variant GVariant *v_properties = NULL;
gs_unref_variant GVariant *v_dict = NULL;
GVariant * v;
gs_unref_variant GVariant *v = NULL;
GVariantIter i;
const char * property;
@ -370,9 +369,8 @@ sim_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_dat
*/
g_variant_iter_init(&i, v_dict);
while (g_variant_iter_next(&i, "{&sv}", &property, &v)) {
while (g_variant_iter_loop(&i, "{&sv}", &property, &v)) {
handle_sim_property(NULL, property, v, self);
g_variant_unref(v);
}
}
@ -477,10 +475,9 @@ handle_connman_property(GDBusProxy *proxy, const char *property, GVariant *v, gp
static void
connman_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data)
{
GVariant *v_child = g_variant_get_child_value(v, 0);
gs_unref_variant GVariant *v_child = g_variant_get_child_value(v, 0);
handle_connman_property(proxy, property, v_child, user_data);
g_variant_unref(v_child);
}
static void
@ -491,7 +488,7 @@ connman_get_properties_done(GObject *source, GAsyncResult *result, gpointer user
gs_free_error GError *error = NULL;
gs_unref_variant GVariant *v_properties = NULL;
gs_unref_variant GVariant *v_dict = NULL;
GVariant * v;
gs_unref_variant GVariant *v = NULL;
GVariantIter i;
const char * property;
@ -523,9 +520,8 @@ connman_get_properties_done(GObject *source, GAsyncResult *result, gpointer user
*/
g_variant_iter_init(&i, v_dict);
while (g_variant_iter_next(&i, "{&sv}", &property, &v)) {
while (g_variant_iter_loop(&i, "{&sv}", &property, &v)) {
handle_connman_property(NULL, property, v, self);
g_variant_unref(v);
}
}
@ -700,9 +696,8 @@ modem_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_d
*/
g_variant_iter_init(&i, v_dict);
while (g_variant_iter_next(&i, "{&sv}", &property, &v)) {
while (g_variant_iter_loop(&i, "{&sv}", &property, &v)) {
handle_modem_property(NULL, property, v, self);
g_variant_unref(v);
}
}
@ -726,35 +721,30 @@ stage1_prepare_done(GObject *source, GAsyncResult *result, gpointer user_data)
nm_clear_pointer(&priv->connect_properties, g_hash_table_destroy);
if (error) {
_LOGW("connection failed: %s", error->message);
nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY);
/*
* FIXME: add code to check for InProgress so that the
* connection doesn't continue to try and activate,
* leading to the connection being disabled, and a 5m
* timeout...
*/
if (!g_strstr_len(error->message,
NM_STRLEN(OFONO_ERROR_IN_PROGRESS),
OFONO_ERROR_IN_PROGRESS)) {
nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY);
}
}
}
static void
context_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data)
handle_settings(GVariant *v_dict, gpointer user_data)
{
NMModemOfono * self = NM_MODEM_OFONO(user_data);
NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
NMPlatformIP4Address addr;
gboolean ret = FALSE;
gs_unref_variant GVariant *v_dict = NULL;
const char * interface;
const char * s;
const char ** array, **iter;
guint32 address_network, gateway_network;
guint32 ip4_route_table, ip4_route_metric;
int ifindex;
GError * error = NULL;
gboolean ret = FALSE;
const char * interface;
const char * s;
const char ** array, **iter;
guint32 address_network, gateway_network;
guint32 ip4_route_table, ip4_route_metric;
int ifindex;
GError * error = NULL;
_LOGD("PropertyChanged: %s", property);
//_LOGD("PropertyChanged: %s", property);
/*
* TODO: might be a good idea and re-factor this to mimic bluez-device,
@ -762,15 +752,6 @@ context_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, g
* handle the action.
*/
if (g_strcmp0(property, "Settings") != 0)
return;
v_dict = g_variant_get_child_value(v, 0);
if (!v_dict) {
_LOGW("error getting IPv4 Settings: no v_dict");
goto out;
}
_LOGI("IPv4 static Settings:");
if (!g_variant_lookup(v_dict, "Interface", "&s", &interface)) {
@ -909,6 +890,28 @@ out:
}
}
static void
context_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data)
{
NMModemOfono * self = NM_MODEM_OFONO(user_data);
gs_unref_variant GVariant *v_dict = NULL;
_LOGD("PropertyChanged: %s", property);
if (g_strcmp0(property, "Settings") != 0)
return;
v_dict = g_variant_get_child_value(v, 0);
if (!v_dict) {
_LOGW("ofono: (%s): error getting IPv4 Settings", nm_modem_get_uid(NM_MODEM(self)));
return;
}
g_assert(g_variant_is_of_type(v_dict, G_VARIANT_TYPE_VARDICT));
handle_settings(v_dict, user_data);
}
static NMActStageReturn
static_stage3_ip4_config_start(NMModem * modem,
NMActRequest * req,
@ -935,6 +938,72 @@ static_stage3_ip4_config_start(NMModem * modem,
return NM_ACT_STAGE_RETURN_POSTPONE;
}
static void
context_properties_cb(GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
NMModemOfono * self;
NMModemOfonoPrivate *priv;
gs_free_error GError *error = NULL;
gs_unref_variant GVariant *properties = NULL;
gs_unref_variant GVariant *settings = NULL;
gs_unref_variant GVariant *v_dict = NULL;
gboolean active;
self = NM_MODEM_OFONO(user_data);
priv = NM_MODEM_OFONO_GET_PRIVATE(self);
properties = g_dbus_proxy_call_finish(proxy, result, &error);
if (!properties) {
_LOGW("ofono: connection failed: no context properties returned %s", error->message);
g_clear_error(&error);
goto error;
}
v_dict = g_variant_get_child_value(properties, 0);
if (!v_dict || !g_variant_is_of_type(v_dict, G_VARIANT_TYPE_VARDICT)) {
_LOGW("ofono: connection failed; could not read connection properties");
goto error;
}
if (!g_variant_lookup(v_dict, "Active", "b", &active)) {
_LOGW("ofono: connection failed; can not read 'Active' property");
goto error;
}
/* Watch for custom ofono PropertyChanged signals */
_nm_dbus_signal_connect(priv->context_proxy,
"PropertyChanged",
G_VARIANT_TYPE("(sv)"),
G_CALLBACK(context_property_changed),
self);
if (active) {
_LOGD("ofono: connection is already Active");
settings = g_variant_lookup_value(v_dict, "Settings", G_VARIANT_TYPE_VARDICT);
if (settings == NULL) {
_LOGW("ofono: connection failed; can not read 'Settings' property");
goto error;
}
handle_settings(settings, user_data);
} else {
g_dbus_proxy_call(priv->context_proxy,
"SetProperty",
g_variant_new("(sv)", "Active", g_variant_new("b", TRUE)),
G_DBUS_CALL_FLAGS_NONE,
20000,
NULL,
(GAsyncReadyCallback) stage1_prepare_done,
self);
}
return;
error:
nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY);
}
static void
context_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data)
{
@ -973,19 +1042,15 @@ context_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data)
*/
g_clear_object(&priv->ip4_config);
_nm_dbus_signal_connect(priv->context_proxy,
"PropertyChanged",
G_VARIANT_TYPE("(sv)"),
G_CALLBACK(context_property_changed),
self);
/* We need to directly query ConnectionContextinteface to get the current
* property values */
g_dbus_proxy_call(priv->context_proxy,
"SetProperty",
g_variant_new("(sv)", "Active", g_variant_new("b", TRUE)),
"GetProperties",
NULL,
G_DBUS_CALL_FLAGS_NONE,
20000,
priv->context_proxy_cancellable,
stage1_prepare_done,
NULL,
(GAsyncReadyCallback) context_properties_cb,
self);
}
@ -1069,6 +1134,7 @@ modem_act_stage1_prepare(NMModem * modem,
_LOGI("activating context %s", priv->context_path);
update_modem_state(self);
if (nm_modem_get_state(modem) == NM_MODEM_STATE_REGISTERED) {
do_context_activate(self);
} else {

View file

@ -25,6 +25,8 @@
#define OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT "org.ofono.ConnectionContext"
#define OFONO_DBUS_INTERFACE_SIM_MANAGER "org.ofono.SimManager"
#define OFONO_ERROR_IN_PROGRESS "org.ofono.Error.InProgress"
typedef struct _NMModemOfono NMModemOfono;
typedef struct _NMModemOfonoClass NMModemOfonoClass;