summaryrefslogtreecommitdiffstats
path: root/src/voicecall.c
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2011-07-14 19:15:53 -0500
committerDenis Kenzior <denkenz@gmail.com>2011-07-14 19:15:53 -0500
commite825cf3ee4b6a3e6556312bf3472d88e0a2b7ad8 (patch)
tree5f6990175f83358e0909059122ccf37d5708309e /src/voicecall.c
parent70df9939dbc7f265002edff6e3b2d2ef560f3a95 (diff)
downloadofono-e825cf3ee4b6a3e6556312bf3472d88e0a2b7ad8.tar.bz2
voicecall: dial_request_user_cancel is not safe
It is not safe to call dial_request_user_cancel directly. This is because there might be a situation where the SIM requested the calls to be dropped first. If we're still executing the release_all_active request and someone calls hangup -> crash. Instead it is safer to throttle the hangup requests until the call is actually dialing. In similar fashion, we should not allow hanging up a specific call if a dial request is active, unless that call is part of the SIM dial request. Note that by default this is not known until the driver's dial implementation returns and the call is in the dialing (or alerting / connected) state.
Diffstat (limited to 'src/voicecall.c')
-rw-r--r--src/voicecall.c22
1 files changed, 8 insertions, 14 deletions
diff --git a/src/voicecall.c b/src/voicecall.c
index 6b1c42c4..5d5a8867 100644
--- a/src/voicecall.c
+++ b/src/voicecall.c
@@ -497,16 +497,6 @@ static DBusMessage *voicecall_deflect(DBusConnection *conn,
return NULL;
}
-static void dial_request_user_cancel(struct ofono_voicecall *vc,
- struct voicecall *call)
-{
- if (vc->dial_req == NULL)
- return;
-
- if (call == NULL || call == vc->dial_req->call)
- dial_request_finish(vc);
-}
-
static DBusMessage *voicecall_hangup(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -518,7 +508,8 @@ static DBusMessage *voicecall_hangup(DBusConnection *conn,
if (vc->pending || vc->pending_em)
return __ofono_error_busy(msg);
- dial_request_user_cancel(vc, v);
+ if (vc->dial_req && vc->dial_req->call != v)
+ return __ofono_error_busy(msg);
switch (call->status) {
case CALL_STATUS_DISCONNECTED:
@@ -1681,6 +1672,9 @@ static DBusMessage *manager_hangup_all(DBusConnection *conn,
if (vc->pending || vc->pending_em)
return __ofono_error_busy(msg);
+ if (vc->dial_req && vc->dial_req->call == NULL)
+ return __ofono_error_busy(msg);
+
if (vc->driver->hangup_all == NULL &&
(vc->driver->release_specific == NULL ||
vc->driver->hangup_active == NULL))
@@ -1700,8 +1694,6 @@ static DBusMessage *manager_hangup_all(DBusConnection *conn,
} else
vc->driver->hangup_all(vc, generic_callback, vc);
- dial_request_user_cancel(vc, NULL);
-
return NULL;
}
@@ -2837,6 +2829,9 @@ static void emulator_chup_cb(struct ofono_emulator *em,
if (vc->pending || vc->pending_em)
goto fail;
+ if (vc->dial_req && vc->dial_req->call == NULL)
+ goto fail;
+
if (vc->driver->release_specific == NULL &&
vc->driver->hangup_active == NULL)
goto fail;
@@ -2866,7 +2861,6 @@ static void emulator_chup_cb(struct ofono_emulator *em,
voicecalls_release_next(vc);
done:
- dial_request_user_cancel(vc, NULL);
break;
default: