Hi Denis and Andras,

2010/12/3 Denis Kenzior <denk...@gmail.com>:
> <snip>
>> +static void modem_change_online(struct ofono_modem *modem,
>> +                             enum modem_state new_state)
>> +{
>> +     DBusConnection *conn = ofono_dbus_get_connection();
>> +     enum modem_state old_state = modem->modem_state;
>> +     ofono_bool_t new_online = new_state == MODEM_STATE_ONLINE;

I'd define a new enum modem_state for emergency mode, MODEM_STATE_EMERGENCY.

>> +     DBG("old state: %d, new state: %d", old_state, new_state);
>> +
>> +     if (new_online == modem->online)
>> +             return;
>
> You check for online not being equal here
>
>> +
>> +     modem->modem_state = new_state;
>> +     modem->online = new_online;
>> +
>> +     ofono_dbus_signal_property_changed(conn, modem->path,
>> +                                     OFONO_MODEM_INTERFACE, "Online",
>> +                                     DBUS_TYPE_BOOLEAN, &modem->online);
>> +
>> +     notify_online_watches(modem);
>> +}
>> +
>> +static void emergency_online_cb(const struct ofono_error *error, void *data)
>> +{
>> +     struct ofono_modem *modem = data;
>> +
>> +     DBG("modem: %p", modem);
>> +
>> +     if (error->type == OFONO_ERROR_TYPE_NO_ERROR &&
>> +                     modem->modem_state != MODEM_STATE_ONLINE)
>
> And perform essentially the same check here...  Seems wasteful
>
>> +             modem_change_online(modem, MODEM_STATE_ONLINE);
>> +}
>> +
>> +static void emergency_offline_cb(const struct ofono_error *error, void 
>> *data)
>> +{
>> +     struct ofono_modem *modem = data;
>> +     DBusConnection *conn = ofono_dbus_get_connection();
>> +     const char *path = ofono_modem_get_path(modem);
>> +     gboolean state = FALSE;
>> +
>> +     DBG("modem: %p", modem);
>> +
>> +     if (error->type == OFONO_ERROR_TYPE_NO_ERROR &&
>> +                     modem->modem_state == MODEM_STATE_ONLINE)
>> +             modem_change_online(modem, modem->modem_state_pre_emergency);
>
> Same comment as above
>
>> +
>> +     modem->emergency--;
>> +
>> +     ofono_dbus_signal_property_changed(conn, path,
>> +                                     OFONO_MODEM_INTERFACE,
>> +                                     "Emergency",
>> +                                     DBUS_TYPE_BOOLEAN,
>> +                                     &state);
>> +}
>> +
>> +void ofono_modem_inc_emergency(struct ofono_modem *modem)
>> +{
>> +     DBusConnection *conn = ofono_dbus_get_connection();
>> +     const char *path = ofono_modem_get_path(modem);
>> +     gboolean state = TRUE;
>> +
>> +     DBG("modem: %p", modem);
>> +
>> +     modem->emergency++;
>> +     if (modem->emergency > 1)
>> +             return;
>> +
>> +     ofono_dbus_signal_property_changed(conn, path,
>> +                                             OFONO_MODEM_INTERFACE,
>> +                                             "Emergency",
>> +                                             DBUS_TYPE_BOOLEAN,
>> +                                             &state);
>> +
>> +     modem->modem_state_pre_emergency = modem->modem_state;
>> +
>> +     if (modem->modem_state == MODEM_STATE_ONLINE)
>> +             return;
>
> So my only major concern left is here actually.  If we activate an
> emergency call and a set_property(Online, blah) is active, we get into
> some funny race conditions.  I mentioned these to Pekka on IRC.  But
> basically the worst one is if we have an Online=False operation pending.
>  In this case your call proceeds, but then gets terminated shortly
> thereafter by the offline procedure ;)

That is a tricky problem. I'd say the most straightforward way is to
return an error if there is a pending operation and push these
problems up the stack. In any case dialer has to retry ecall if user
tries to make the emergency call just after or before moving device to
offline / removing SIM card / etc. However, I'm not sure if we can
propagate the error in all cases where ofono_modem_inc_emergency()
gets called.

In order to manage the worst case in best possible manner, I'd check
for set_online in progress here. Return FALSE from
ofono_modem_get_online() immediately after the set_online(FALSE) call
is made. Also, check the emergency state again in after set_online
callback response. The online/offline watches should be called before
the set_online() call. (I have no idea what we will do should
set_online(FALSE) fail)?

-- 
Pekka.Pessi mail at nokia.com
_______________________________________________
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono

Reply via email to