X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?p=staging%2Fsoundmanager.git;a=blobdiff_plain;f=sample%2Fphone%2Ftelephony-binding%2Ftelephony-binding.c;fp=sample%2Fphone%2Ftelephony-binding%2Ftelephony-binding.c;h=d58aeab06aca1b1faf6c69510193468827f1d97a;hp=0000000000000000000000000000000000000000;hb=fde77416ce98487a0bb50f5e049e7cb640ffa079;hpb=2e602801b372b0b68111316b89f567213e3ea378 diff --git a/sample/phone/telephony-binding/telephony-binding.c b/sample/phone/telephony-binding/telephony-binding.c new file mode 100644 index 0000000..d58aeab --- /dev/null +++ b/sample/phone/telephony-binding/telephony-binding.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2017 Konsulko Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _GNU_SOURCE + +#include +#include + +#include +#include + +#include "ofono_manager.h" +#include "ofono_voicecallmanager.h" +#include "ofono_voicecall.h" + +static const struct afb_binding_interface *interface; + +static OrgOfonoVoiceCallManager *vcm; +static OrgOfonoVoiceCall *incoming_call, *voice_call; + +static void dial(struct afb_req request) +{ + struct json_object *query, *val; + const char *number; + + query = afb_req_json(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) { + ERROR(interface, "dial: cannot dial with active call"); + afb_req_fail(request, "active call", NULL); + } else { + DEBUG(interface, "dial: %s...\n", number); + if (ofono_voicecallmanager_dial(vcm, (gchar *)number, "")) { + afb_req_success(request, NULL, NULL); + } else { + ERROR(interface, "dial: failed to dial number\n"); + afb_req_fail(request, "failed dial", NULL); + } + } + } else { + ERROR(interface, "dial: no phone number parameter\n"); + afb_req_fail(request, "no number", NULL); + } +} + +static void hangup(struct afb_req request) +{ + if (voice_call) { + DEBUG(interface, "Hangup voice call\n"); + ofono_voicecall_hangup(voice_call); + afb_req_success(request, NULL, NULL); + } else if (incoming_call) { + DEBUG(interface, "Reject incoming call\n"); + ofono_voicecall_hangup(incoming_call); + afb_req_success(request, NULL, NULL); + } else { + ERROR(interface, "Hangup: no active call"); + afb_req_fail(request, "failed hangup", NULL); + } +} + +static void answer(struct afb_req request) +{ + if (incoming_call) { + DEBUG(interface, "Answer voice call\n"); + voice_call = incoming_call; + ofono_voicecall_answer(voice_call); + } else { + ERROR(interface, "Answer: no incoming call"); + } +} + +static void call_state_changed_cb(OrgOfonoVoiceCall *vc, gchar *state) +{ + struct json_object *call_state; + call_state = json_object_new_object(); + json_object_object_add(call_state, "state", json_object_new_string(state)); + afb_daemon_broadcast_event(interface->daemon, "callStateChanged", call_state); +} + +static void incoming_call_cb(OrgOfonoVoiceCallManager *manager, gchar *op, gchar *clip) +{ + struct json_object *call_info; + + call_info = json_object_new_object(); + json_object_object_add(call_info, "clip", json_object_new_string(clip)); + afb_daemon_broadcast_event(interface->daemon, "incomingCall", call_info); + incoming_call = ofono_voicecall_new(interface, op, call_state_changed_cb); +} + +static void dialing_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_daemon_broadcast_event(interface->daemon, "dialingCall", call_info); + voice_call = ofono_voicecall_new(interface, 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; + + afb_daemon_broadcast_event(interface->daemon, "terminatedCall", NULL); +} + +static void *main_loop_thread(void *unused) +{ + GMainLoop *loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(loop); + return NULL; +} + +static int ofono_init(void) +{ + pthread_t tid; + int ret = 0; + + /* Start the main loop thread */ + pthread_create(&tid, NULL, main_loop_thread, NULL); + + ret = ofono_manager_init(interface); + if (ret == 0) { + const gchar *modem_path = ofono_manager_get_default_modem_path(); + if (modem_path) { + DEBUG(interface, "modem_path: %s\n", modem_path); + vcm = ofono_voicecallmanager_init(interface, modem_path, + incoming_call_cb, + dialing_call_cb, + terminated_call_cb); + if (!vcm) { + ERROR(interface, "[telephony] failed to initialize voice call manager\n"); + ret = -1; + } + } else { + ERROR(interface, "[telephony] default modem not set\n"); + ret = -1; + } + } else { + ERROR(interface, "[telephony] failed to initialize ofono manager: " \ + "HFP device not connected or Bluetooth disabled\n"); + } + + return ret; +} + +static const struct afb_verb_desc_v1 verbs[]= { + { + .name = "dial", + .session = AFB_SESSION_NONE, + .callback = dial, + .info = "Dial phone" + }, + { + .name = "hangup", + .session = AFB_SESSION_NONE, + .callback = hangup, + .info = "Hangup phone" + }, + { + .name = "answer", + .session = AFB_SESSION_NONE, + .callback = answer, + .info = "Answer phone" + }, + {NULL} +}; + +static const struct afb_binding binding_desc = { + .type = AFB_BINDING_VERSION_1, + .v1 = { + .info = "telephony service", + .prefix = "telephony", + .verbs = verbs + } +}; + +const struct afb_binding *afbBindingV1Register (const struct afb_binding_interface *itf) +{ + interface = itf; + + return &binding_desc; +} + +int afbBindingV1ServiceInit(struct afb_service service) +{ + DEBUG(interface, "Initializing telephony service\n"); + + return ofono_init(); +}