#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 };
int cind_val[HFP_INDICATOR_LAST];
unsigned int local_release;
unsigned int clcc_source;
+ unsigned int expect_release_source;
unsigned int clip_source;
};
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)
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;
}
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);