From a8d80197f32a50cce67a1a03dbcb08f96102ae4a Mon Sep 17 00:00:00 2001 From: Alfonso Sanchez-Beato Date: Thu, 21 May 2015 14:44:09 +0200 Subject: [PATCH 1/3] gprs: Add support for MMS when not powered Add a new property (PoweredForMMS) that will allow sending MMS even when we do not want internet data active. This property will let us send MMS in multi-SIM dual standby modems for the non-attached slot too, by the procedure of stealing temporalily the GPRS attachement from the attached slot. --- src/gprs.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 4 deletions(-) diff --git a/src/gprs.c b/src/gprs.c index b4bbe8ce9..710dc99ec 100644 --- a/src/gprs.c +++ b/src/gprs.c @@ -65,6 +65,8 @@ struct ofono_gprs { ofono_bool_t driver_attached; ofono_bool_t roaming_allowed; ofono_bool_t powered; + ofono_bool_t powered_for_mms; + ofono_bool_t detach_forced; ofono_bool_t suspended; int status; int flags; @@ -857,7 +859,16 @@ static void pri_activate_callback(const struct ofono_error *error, void *data) if (gc->settings->interface != NULL) { pri_ifupdown(gc->settings->interface, TRUE); - if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS && + /* + * Activate route when NetworkManager does not do that for us. + * In the case of combined contexts that can happen if we have + * not activated cellular data. + * TODO: Consider using only ofono for setting up routes to the + * MMS proxy. + */ + if ((ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS || + (ctx->type == OFONO_GPRS_CONTEXT_TYPE_INTERNET + && !ctx->gprs->powered)) && gc->settings->ipv4) pri_update_mms_context_settings(ctx); @@ -1593,6 +1604,11 @@ static void gprs_netreg_removed(struct ofono_gprs *gprs) gprs_attached_update(gprs); } +static ofono_bool_t gprs_is_powered(struct ofono_gprs *gprs) +{ + return (gprs->powered || gprs->powered_for_mms) && !gprs->detach_forced; +} + static void gprs_netreg_update(struct ofono_gprs *gprs) { ofono_bool_t attach; @@ -1602,7 +1618,7 @@ static void gprs_netreg_update(struct ofono_gprs *gprs) attach = attach || (gprs->roaming_allowed && gprs->netreg_status == NETWORK_REGISTRATION_STATUS_ROAMING); - attach = attach && gprs->powered; + attach = attach && gprs_is_powered(gprs); if (gprs->driver_attached == attach) return; @@ -1686,6 +1702,46 @@ static void notify_powered_change(struct ofono_gprs *gprs) } } +static void modem_notify_mms_powered_change(struct ofono_modem *modem, + void *data) +{ + struct ofono_atom *atom; + struct ofono_gprs *gprs; + struct ofono_modem *modem_notif = data; + struct ofono_atom *atom_notif; + struct ofono_gprs *gprs_notif; + const char *path = ofono_modem_get_path(modem); + + if (strcmp(path, ofono_modem_get_path(modem_notif)) == 0) + return; + + if (!ofono_modem_is_standby(modem)) + return; + + atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_GPRS); + if (atom == NULL) + return; + + gprs = __ofono_atom_get_data(atom); + + if (gprs->driver->set_attached == NULL) + return; + + atom_notif = __ofono_modem_find_atom(modem_notif, OFONO_ATOM_TYPE_GPRS); + gprs_notif = __ofono_atom_get_data(atom_notif); + + gprs->detach_forced = gprs_notif->powered_for_mms; + + gprs_netreg_update(gprs); +} + +static void notify_mms_powered_change(struct ofono_gprs *gprs) +{ + struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom); + + __ofono_modem_foreach(modem_notify_mms_powered_change, modem); +} + static DBusMessage *gprs_get_properties(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -1722,6 +1778,10 @@ static DBusMessage *gprs_get_properties(DBusConnection *conn, value = gprs->powered; ofono_dbus_dict_append(&dict, "Powered", DBUS_TYPE_BOOLEAN, &value); + value = gprs->powered_for_mms; + ofono_dbus_dict_append(&dict, "PoweredForMMS", + DBUS_TYPE_BOOLEAN, &value); + if (gprs->attached) { value = gprs->suspended; ofono_dbus_dict_append(&dict, "Suspended", @@ -1804,6 +1864,23 @@ static DBusMessage *gprs_set_property(DBusConnection *conn, gprs_netreg_update(gprs); notify_powered_change(gprs); + } else if (!strcmp(property, "PoweredForMMS")) { + if (gprs->driver->set_attached == NULL) + return __ofono_error_not_implemented(msg); + + if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_BOOLEAN) + return __ofono_error_invalid_args(msg); + + dbus_message_iter_get_basic(&var, &value); + + if (gprs->powered_for_mms == (ofono_bool_t) value) + return dbus_message_new_method_return(msg); + + gprs->powered_for_mms = value; + + gprs_netreg_update(gprs); + + notify_mms_powered_change(gprs); } else { return __ofono_error_invalid_args(msg); } @@ -2336,7 +2413,7 @@ static DBusMessage *gprs_reset_contexts(DBusConnection *conn, if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID)) return __ofono_error_invalid_args(msg); - if (gprs->powered) + if (gprs_is_powered(gprs)) return __ofono_error_not_allowed(msg); for (l = gprs->contexts; l; l = l->next) { @@ -2449,7 +2526,7 @@ void ofono_gprs_status_notify(struct ofono_gprs *gprs, int status) return; /* We registered without being powered */ - if (gprs->powered == FALSE) + if (gprs_is_powered(gprs) == FALSE) goto detach; if (gprs->roaming_allowed == FALSE && From f58cf1d50bf66fdfdbca964d80144e072fa15f77 Mon Sep 17 00:00:00 2001 From: Alfonso Sanchez-Beato Date: Fri, 22 May 2015 18:01:35 +0200 Subject: [PATCH 2/3] doc: Add PoweredForMMS to ConnectionManager --- doc/connman-api.txt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/doc/connman-api.txt b/doc/connman-api.txt index 035858400..56da265a9 100644 --- a/doc/connman-api.txt +++ b/doc/connman-api.txt @@ -140,8 +140,17 @@ Properties boolean Attached [readonly] boolean Powered [readwrite] Controls whether packet radio use is allowed. Setting - this value to off detaches the modem from the - Packet Domain network. + this value and PoweredForMMS to off detaches the modem + from the Packet Domain network. + + boolean PoweredForMMS [readwrite] + + As Powered, it controls whether packet radio use is + allowed. When any of them is set, the use of packet + radio is allowed. When both are false, the modem is + asked to detach from the Packet Domain. The reason for + having both is to be able to send/receive MMS without + internet data on. Connection Context hierarchy ================= From 163076a70c4589752df4ca75a683809addb478e7 Mon Sep 17 00:00:00 2001 From: Alfonso Sanchez-Beato Date: Fri, 22 May 2015 18:02:18 +0200 Subject: [PATCH 3/3] test: Add scripts to set/unset PoweredForMMS --- test/disable-mms | 20 ++++++++++++++++++++ test/enable-mms | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100755 test/disable-mms create mode 100755 test/enable-mms diff --git a/test/disable-mms b/test/disable-mms new file mode 100755 index 000000000..1bd483a38 --- /dev/null +++ b/test/disable-mms @@ -0,0 +1,20 @@ +#!/usr/bin/python3 + +import dbus +import sys + +bus = dbus.SystemBus() + +if len(sys.argv) == 2: + path = sys.argv[1] +else: + manager = dbus.Interface(bus.get_object('org.ofono', '/'), + 'org.ofono.Manager') + modems = manager.GetModems() + path = modems[0][0] + +print("Disabling MMS data on modem %s..." % path) +cm = dbus.Interface(bus.get_object('org.ofono', path), + 'org.ofono.ConnectionManager') + +cm.SetProperty("PoweredForMMS", dbus.Boolean(0)) diff --git a/test/enable-mms b/test/enable-mms new file mode 100755 index 000000000..bdb108817 --- /dev/null +++ b/test/enable-mms @@ -0,0 +1,20 @@ +#!/usr/bin/python3 + +import dbus +import sys + +bus = dbus.SystemBus() + +if len(sys.argv) == 2: + path = sys.argv[1] +else: + manager = dbus.Interface(bus.get_object('org.ofono', '/'), + 'org.ofono.Manager') + modems = manager.GetModems() + path = modems[0][0] + +print("Enabling MMS data for modem %s..." % path) +cm = dbus.Interface(bus.get_object('org.ofono', path), + 'org.ofono.ConnectionManager') + +cm.SetProperty("PoweredForMMS", dbus.Boolean(1))