mirror of git://git.sysmocom.de/ofono
hfpmodem: Fix release-and-swap without +CIEV
Some phones do not send the corresponding call state update (+CIEV) after a successful release-and-swap operation (AT+CHLD=1). This has been observed with a Nokia 500, while testing ReleaseAndSwap() while an active and a held call exist: ofonod[20414]: > AT+CLCC\r ofonod[20414]: < \r\n+CLCC: 1,0,1,0,0,"<number1>",145\r\n ofonod[20414]: < \r\n+CLCC: 2,0,0,0,0,"<number2>",145\r\n ofonod[20414]: < \r\nOK\r\n ofonod[20414]: > AT+CHLD=1\r ofonod[20414]: < \r\nOK\r\n After this, no +CIEV is received, but the call has been hung up. The proposed approach to solve this consists of using AT+CLCC, unless a call release has been received within a specific time period. The result fixes the problem as can be seen below: ofonod[20847]: < \r\n+CLCC: 1,0,1,0,0,"<number1>",145\r\n ofonod[20847]: < \r\n+CLCC: 2,0,0,0,0,"<number2>",145\r\n ofonod[20847]: < \r\nOK\r\n ofonod[20847]: > AT+CHLD=1\r ofonod[20847]: < \r\nOK\r\n ofonod[20847]: > AT+CLCC\r ofonod[20847]: < \r\n+CLCC: 1,0,0,0,0,"<number1>",145\r\n ofonod[20847]: < \r\nOK\r\n ofonod[20847]: < \r\n+CIEV: 5,2\r\n ofonod[20847]: < \r\n+CIEV: 5,0\r\n
This commit is contained in:
parent
cbb784e734
commit
843bd71169
|
@ -43,6 +43,7 @@
|
|||
|
||||
#define POLL_CLCC_INTERVAL 2000
|
||||
#define POLL_CLCC_DELAY 50
|
||||
#define EXPECT_RELEASE_DELAY 50
|
||||
#define CLIP_TIMEOUT 500
|
||||
|
||||
static const char *none_prefix[] = { NULL };
|
||||
|
@ -57,6 +58,7 @@ struct voicecall_data {
|
|||
int cind_val[HFP_INDICATOR_LAST];
|
||||
unsigned int local_release;
|
||||
unsigned int clcc_source;
|
||||
unsigned int expect_release_source;
|
||||
unsigned int clip_source;
|
||||
};
|
||||
|
||||
|
@ -194,6 +196,11 @@ static void release_with_status(struct ofono_voicecall *vc, int status)
|
|||
c = c->next;
|
||||
g_slist_free_1(t);
|
||||
}
|
||||
|
||||
if (vd->expect_release_source) {
|
||||
g_source_remove(vd->expect_release_source);
|
||||
vd->expect_release_source = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void clcc_poll_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
|
@ -471,13 +478,47 @@ static void hfp_set_udub(struct ofono_voicecall *vc,
|
|||
CALLBACK_WITH_FAILURE(cb, data);
|
||||
}
|
||||
|
||||
static gboolean expect_release(gpointer user_data)
|
||||
{
|
||||
struct ofono_voicecall *vc = user_data;
|
||||
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
|
||||
|
||||
g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
|
||||
clcc_poll_cb, vc, NULL);
|
||||
|
||||
vd->expect_release_source = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void release_all_active_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct change_state_req *req = user_data;
|
||||
struct voicecall_data *vd = ofono_voicecall_get_data(req->vc);
|
||||
|
||||
if (!ok)
|
||||
goto out;
|
||||
|
||||
if (vd->expect_release_source)
|
||||
g_source_remove(vd->expect_release_source);
|
||||
|
||||
vd->expect_release_source = g_timeout_add(EXPECT_RELEASE_DELAY,
|
||||
expect_release,
|
||||
req->vc);
|
||||
|
||||
out:
|
||||
generic_cb(ok, result, user_data);
|
||||
}
|
||||
|
||||
static void hfp_release_all_active(struct ofono_voicecall *vc,
|
||||
ofono_voicecall_cb_t cb, void *data)
|
||||
{
|
||||
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
|
||||
|
||||
if (vd->ag_mpty_features & AG_CHLD_1) {
|
||||
hfp_template("AT+CHLD=1", vc, generic_cb, 0x1, cb, data);
|
||||
hfp_template("AT+CHLD=1", vc, release_all_active_cb, 0x1, cb,
|
||||
data);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1111,6 +1152,9 @@ static void hfp_voicecall_remove(struct ofono_voicecall *vc)
|
|||
if (vd->clip_source)
|
||||
g_source_remove(vd->clip_source);
|
||||
|
||||
if (vd->expect_release_source)
|
||||
g_source_remove(vd->expect_release_source);
|
||||
|
||||
g_slist_foreach(vd->calls, (GFunc) g_free, NULL);
|
||||
g_slist_free(vd->calls);
|
||||
|
||||
|
|
Loading…
Reference in New Issue