diff options
Diffstat (limited to 'binding/telephony-binding.c')
-rw-r--r-- | binding/telephony-binding.c | 188 |
1 files changed, 165 insertions, 23 deletions
diff --git a/binding/telephony-binding.c b/binding/telephony-binding.c index 10c00fc..9e47c76 100644 --- a/binding/telephony-binding.c +++ b/binding/telephony-binding.c @@ -30,15 +30,25 @@ #define OFONO_MODEM_INTERFACE "org.ofono.Modem" static OrgOfonoVoiceCallManager *vcm; -static OrgOfonoVoiceCall *incoming_call, *voice_call; +static OrgOfonoVoiceCall *incoming_call; static afb_event_t call_state_changed_event; static afb_event_t dialing_call_event; static afb_event_t incoming_call_event; +static afb_event_t waiting_call_event; static afb_event_t terminated_call_event; static afb_event_t online_event; static afb_event_t battery_event; static afb_event_t signal_event; +static GList *voice_calls = NULL; + +static void remover(gpointer data, gchar *path) { + if (!g_strcmp0(path, g_dbus_proxy_get_object_path(G_DBUS_PROXY((OrgOfonoVoiceCall*)data)))) { + ofono_voicecall_free((OrgOfonoVoiceCall*)data); + voice_calls = g_list_remove(voice_calls, (gconstpointer)data); + } +} + static void dial(afb_req_t request) { struct json_object *query, *val; @@ -48,7 +58,7 @@ static void dial(afb_req_t request) json_object_object_get_ex(query, "value", &val); if (json_object_is_type(val, json_type_string)) { number = json_object_get_string(val); - if (voice_call) { + if (voice_calls) { AFB_ERROR("dial: cannot dial with active call"); afb_req_fail(request, "active call", NULL); } else { @@ -68,7 +78,7 @@ static void dial(afb_req_t request) static void last_dial(afb_req_t request) { - if (voice_call) { + if (voice_calls) { AFB_ERROR("dial: cannot dial with active call"); afb_req_fail(request, "active call", NULL); } else { @@ -85,7 +95,7 @@ static void send_tones(afb_req_t request) { const char *value = afb_req_value(request, "value"); - if (!voice_call) { + if (!voice_calls) { AFB_ERROR("send_tones: cannot send tone without active call"); afb_req_fail(request, "there is no active call", NULL); } else { @@ -98,19 +108,43 @@ static void send_tones(afb_req_t request) } } -static void hangup(afb_req_t request) +static void hangup_all (afb_req_t request) { - if (voice_call) { - AFB_DEBUG("Hangup voice call\n"); - ofono_voicecall_hangup(voice_call); - afb_req_success(request, NULL, NULL); - } else if (incoming_call) { - AFB_DEBUG("Reject incoming call\n"); - ofono_voicecall_hangup(incoming_call); - afb_req_success(request, NULL, NULL); + if (!voice_calls) { + AFB_ERROR("hangup_all: cannot hang up without active call"); + afb_req_fail(request, "there is no active call", NULL); } else { + ofono_voicecallmanager_hangup_all(vcm); + afb_req_success(request, NULL, NULL); + } +} + +static void hangup(afb_req_t request) +{ + const char* value = afb_req_value(request, "id"); + const gchar *modem = ofono_manager_get_default_modem_path(); + gchar *op = g_strconcat(modem, "/" , value, NULL); + if (g_list_length(voice_calls) > 0) { + GList *list; + for (list = voice_calls; list != NULL; list = list->next) + { + if (!g_strcmp0(op, g_dbus_proxy_get_object_path(G_DBUS_PROXY((OrgOfonoVoiceCall*)list->data)))) { + AFB_ERROR("object path = %s", g_dbus_proxy_get_object_path(G_DBUS_PROXY((OrgOfonoVoiceCall*)list->data))); + ofono_voicecall_hangup((OrgOfonoVoiceCall*)list->data); + afb_req_success(request, NULL, NULL); + g_free(op); + return; + } + } + AFB_ERROR("Hangup: Invalid ID"); + afb_req_fail(request, "Invalid ID", NULL); + g_free(op); + return; + } + else { AFB_ERROR("Hangup: no active call"); afb_req_fail(request, "failed hangup", NULL); + return; } } @@ -118,13 +152,86 @@ static void answer(afb_req_t request) { if (incoming_call) { AFB_DEBUG("Answer voice call\n"); - voice_call = incoming_call; - ofono_voicecall_answer(voice_call); + voice_calls = g_list_append(voice_calls, (gpointer)incoming_call); + ofono_voicecall_answer(incoming_call); + ofono_voicecall_free(incoming_call); + incoming_call = NULL; } else { AFB_ERROR("Answer: no incoming call"); } } +static void hangup_multiparty(afb_req_t request) +{ + if (g_list_length(voice_calls) < 2) { + afb_req_fail(request, "failed hangup multiparty", NULL); + } else { + ofono_voicecallmanager_hangup_multiparty(vcm); + afb_req_success(request, NULL, NULL); + } +} + +static void create_multiparty(afb_req_t request) +{ + gchar **reply = NULL; + if (g_list_length(voice_calls) > 1) { + reply = ofono_voicecallmanager_create_multiparty(vcm); + if (reply) + afb_req_success(request, NULL, NULL); + else + afb_req_fail(request, "failed create multiparty", NULL); + } + else { + AFB_ERROR("Create MultiParty: It should be greater than 1 active call"); + afb_req_fail(request, "failed create multiparty", NULL); + } +} + +static void hold_and_answer(afb_req_t request) +{ + if (g_list_length(voice_calls) > 1) { + if (ofono_voicecallmanager_hold_and_answer(vcm)) { + afb_req_success(request, NULL, NULL); + } else { + AFB_ERROR("hold_and_answer: failed"); + afb_req_fail(request, "failed hold and answer", NULL); + } + } else { + AFB_ERROR("hold_and_answer: cannot hold and answer without waiting call"); + afb_req_fail(request, "no waiting call", NULL); + } +} + +static void release_and_answer(afb_req_t request) +{ + if (g_list_length(voice_calls) > 1) { + if (ofono_voicecallmanager_release_and_answer(vcm)) { + afb_req_success(request, NULL, NULL); + } else { + AFB_ERROR("release_and_answer: failed to release and answer\n"); + afb_req_fail(request, "failed release and answer", NULL); + } + } else { + AFB_ERROR("release_and_answer: cannot release and answer without waiting call"); + afb_req_fail(request, "does not exist waiting call", NULL); + } +} + +static void swap_calls(afb_req_t request) +{ + if (g_list_length(voice_calls) > 1) { + if (ofono_voicecallmanager_swap_calls(vcm)) { + afb_req_success(request, NULL, NULL); + } else { + AFB_ERROR("dial: failed to swap calls\n"); + afb_req_fail(request, "failed swap_calls", NULL); + } + } else { + AFB_ERROR("swap: there is no waiting call"); + afb_req_fail(request, "swap calls", NULL); + } +} + static void get_battery_level(afb_req_t request) { const gchar *device; @@ -171,6 +278,8 @@ static void subscribe(afb_req_t request) afb_req_subscribe(request, dialing_call_event); } else if (!strcasecmp(value, "incomingCall")) { afb_req_subscribe(request, incoming_call_event); + } else if (!strcasecmp(value, "waitingCall")) { + afb_req_subscribe(request, waiting_call_event); } else if (!strcasecmp(value, "terminatedCall")) { afb_req_subscribe(request, terminated_call_event); } else if (!strcasecmp(value, "battery")) { @@ -204,6 +313,8 @@ static void unsubscribe(afb_req_t request) afb_req_unsubscribe(request, dialing_call_event); } else if (!strcasecmp(value, "incomingCall")) { afb_req_unsubscribe(request, incoming_call_event); + } else if (!strcasecmp(value, "waitingCall")) { + afb_req_unsubscribe(request, waiting_call_event); } else if (!strcasecmp(value, "terminatedCall")) { afb_req_unsubscribe(request, terminated_call_event); } else { @@ -231,6 +342,7 @@ static void incoming_call_cb(OrgOfonoVoiceCallManager *manager, gchar *op, gchar json_object_object_add(call_info, "clip", json_object_new_string(clip)); afb_event_push(incoming_call_event, call_info); incoming_call = ofono_voicecall_new(op, call_state_changed_cb); + voice_calls = g_list_append(voice_calls, (gpointer)incoming_call); } static void dialing_call_cb(OrgOfonoVoiceCallManager *manager, gchar *op, gchar *colp) @@ -240,18 +352,22 @@ static void dialing_call_cb(OrgOfonoVoiceCallManager *manager, gchar *op, gchar call_info = json_object_new_object(); json_object_object_add(call_info, "colp", json_object_new_string(colp)); afb_event_push(dialing_call_event, call_info); - voice_call = ofono_voicecall_new(op, call_state_changed_cb); + voice_calls = g_list_append(voice_calls, (gpointer)ofono_voicecall_new(op, call_state_changed_cb)); +} + +static void waiting_call_cb(OrgOfonoVoiceCallManager *manager, gchar *op, gchar *colp) +{ + struct json_object *call_info; + call_info = json_object_new_object(); + json_object_object_add(call_info, "colp", json_object_new_string(colp)); + afb_event_push(waiting_call_event, call_info); + voice_calls = g_list_append(voice_calls, (gpointer)ofono_voicecall_new(op, call_state_changed_cb)); } static void terminated_call_cb(OrgOfonoVoiceCallManager *manager, gchar *op) { - if (incoming_call) { - ofono_voicecall_free(incoming_call); - incoming_call = NULL; - } else if (voice_call) { - ofono_voicecall_free(voice_call); - } - voice_call = NULL; + if (g_list_length(voice_calls) > 0) + g_list_foreach(voice_calls, (GFunc)remover, op); afb_event_push(terminated_call_event, NULL); } @@ -271,6 +387,7 @@ static int ofono_init_default_modem(void) vcm = ofono_voicecallmanager_init(modem_path, incoming_call_cb, dialing_call_cb, + waiting_call_cb, terminated_call_cb); if (!vcm) { AFB_ERROR("failed to initialize voice call manager\n"); @@ -455,6 +572,7 @@ static int ofono_init(afb_api_t api) call_state_changed_event = afb_daemon_make_event("callStateChanged"); dialing_call_event = afb_daemon_make_event("dialingCall"); incoming_call_event = afb_daemon_make_event("incomingCall"); + waiting_call_event = afb_daemon_make_event("waitingCall"); terminated_call_event = afb_daemon_make_event("terminatedCall"); online_event = afb_daemon_make_event("online"); battery_event = afb_daemon_make_event("battery"); @@ -492,10 +610,34 @@ static const afb_verb_t verbs[]= { .callback = hangup, }, { + .verb = "hangup_all", + .callback = hangup_all, + }, + { .verb = "answer", .callback = answer, }, { + .verb = "hangup_multiparty", + .callback = hangup_multiparty, + }, + { + .verb = "create_multiparty", + .callback = create_multiparty, + }, + { + .verb = "swap_calls", + .callback = swap_calls, + }, + { + .verb = "hold_and_answer", + .callback = hold_and_answer, + }, + { + .verb = "release_and_answer", + .callback = release_and_answer, + }, + { .verb = "get_battery_level", .callback = get_battery_level, }, |