3 * oFono - Open Source Telephony
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 #include <gatresult.h>
35 #include <ofono/log.h>
36 #include <ofono/modem.h>
37 #include <ofono/voicecall.h>
45 #define POLL_CLCC_INTERVAL 2000
46 #define POLL_CLCC_DELAY 50
47 #define EXPECT_RELEASE_DELAY 50
48 #define CLIP_TIMEOUT 500
50 static const char *none_prefix[] = { NULL };
51 static const char *clcc_prefix[] = { "+CLCC:", NULL };
53 struct voicecall_data {
56 unsigned int ag_features;
57 unsigned int ag_mpty_features;
58 unsigned char cind_pos[HFP_INDICATOR_LAST];
59 int cind_val[HFP_INDICATOR_LAST];
60 unsigned int local_release;
61 unsigned int clcc_source;
62 unsigned int expect_release_source;
63 unsigned int clip_source;
66 struct release_id_req {
67 struct ofono_voicecall *vc;
68 ofono_voicecall_cb_t cb;
73 struct change_state_req {
74 struct ofono_voicecall *vc;
75 ofono_voicecall_cb_t cb;
80 static gboolean poll_clcc(gpointer user_data);
82 static GSList *find_dialing(GSList *calls)
86 c = g_slist_find_custom(calls, GINT_TO_POINTER(CALL_STATUS_DIALING),
87 at_util_call_compare_by_status);
90 c = g_slist_find_custom(calls,
91 GINT_TO_POINTER(CALL_STATUS_ALERTING),
92 at_util_call_compare_by_status);
97 static void voicecall_notify(gpointer value, gpointer user)
99 struct ofono_call *call = value;
100 struct ofono_voicecall *vc = user;
102 ofono_voicecall_notify(vc, call);
105 static struct ofono_call *create_call(struct ofono_voicecall *vc, int type,
106 int direction, int status,
107 const char *num, int num_type, int clip)
109 struct voicecall_data *d = ofono_voicecall_get_data(vc);
110 struct ofono_call *call;
112 /* Generate a call structure for the waiting call */
113 call = g_try_new(struct ofono_call, 1);
117 ofono_call_init(call);
119 call->id = ofono_voicecall_get_next_callid(vc);
121 call->direction = direction;
122 call->status = status;
125 strncpy(call->phone_number.number, num,
126 OFONO_MAX_PHONE_NUMBER_LENGTH);
127 call->phone_number.type = num_type;
130 d->calls = g_slist_insert_sorted(d->calls, call, at_util_call_compare);
132 call->clip_validity = clip;
137 static void release_call(struct ofono_voicecall *vc, struct ofono_call *call)
139 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
140 enum ofono_disconnect_reason reason;
145 if (vd->local_release & (1 << call->id))
146 reason = OFONO_DISCONNECT_REASON_LOCAL_HANGUP;
148 reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
150 ofono_voicecall_disconnected(vc, call->id, reason, NULL);
151 vd->local_release &= ~(1 << call->id);
156 static void release_all_calls(struct ofono_voicecall *vc)
158 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
160 struct ofono_call *call;
162 for (l = vd->calls; l; l = l->next) {
165 release_call(vc, call);
168 g_slist_free(vd->calls);
172 static void release_with_status(struct ofono_voicecall *vc, int status)
174 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
176 GSList *c = vd->calls;
178 struct ofono_call *call;
183 if (call->status != status) {
189 release_call(vc, call);
201 if (vd->expect_release_source) {
202 g_source_remove(vd->expect_release_source);
203 vd->expect_release_source = 0;
207 static void clcc_poll_cb(gboolean ok, GAtResult *result, gpointer user_data)
209 struct ofono_voicecall *vc = user_data;
210 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
213 struct ofono_call *nc, *oc;
214 unsigned int num_active = 0;
215 unsigned int num_held = 0;
216 GSList *notify_calls = NULL;
217 unsigned int mpty_ids;
222 calls = at_util_parse_clcc(result, &mpty_ids);
228 nc = n ? n->data : NULL;
229 oc = o ? o->data : NULL;
231 if (nc && (nc->status == CALL_STATUS_ACTIVE))
234 if (nc && (nc->status == CALL_STATUS_HELD))
237 if (oc && (nc == NULL || (nc->id > oc->id))) {
238 enum ofono_disconnect_reason reason;
240 if (vd->local_release & (1 << oc->id))
241 reason = OFONO_DISCONNECT_REASON_LOCAL_HANGUP;
243 reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
246 ofono_voicecall_disconnected(vc, oc->id,
249 vd->local_release &= ~(1 << oc->id);
252 } else if (nc && (oc == NULL || (nc->id < oc->id))) {
253 /* new call, signal it */
255 notify_calls = g_slist_append(notify_calls, nc);
259 /* Always use the clip_validity from old call
260 * the only place this is truly told to us is
261 * in the CLIP notify, the rest are fudged
262 * anyway. Useful when RING, CLIP is used,
263 * and we're forced to use CLCC and clip_validity
266 nc->clip_validity = oc->clip_validity;
268 if (memcmp(nc, oc, sizeof(struct ofono_call)) &&
270 notify_calls = g_slist_prepend(notify_calls,
279 * Disconnections were already reported, so process the rest of the
280 * notifications. Note that the new calls are placed at the end of the
281 * list, after other state changes
283 g_slist_foreach(notify_calls, voicecall_notify, vc);
284 g_slist_free(notify_calls);
286 ofono_voicecall_mpty_hint(vc, mpty_ids);
288 g_slist_foreach(vd->calls, (GFunc) g_free, NULL);
289 g_slist_free(vd->calls);
293 /* If either active/held call is more than 1, we are in mpty calls.
294 * we won't get indicator update if any of them is released by CHLD=1x.
295 * So we have to poll it.
297 if (num_active > 1 || num_held > 1)
298 vd->clcc_source = g_timeout_add(POLL_CLCC_INTERVAL, poll_clcc,
302 static gboolean poll_clcc(gpointer user_data)
304 struct ofono_voicecall *vc = user_data;
305 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
307 g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
308 clcc_poll_cb, vc, NULL);
315 static void generic_cb(gboolean ok, GAtResult *result, gpointer user_data)
317 struct change_state_req *req = user_data;
318 struct voicecall_data *vd = ofono_voicecall_get_data(req->vc);
319 struct ofono_error error;
321 decode_at_error(&error, g_at_result_final_response(result));
323 if (ok && req->affected_types) {
325 struct ofono_call *call;
327 for (l = vd->calls; l; l = l->next) {
330 if (req->affected_types & (1 << call->status))
331 vd->local_release |= (1 << call->id);
335 req->cb(&error, req->data);
338 static void atd_cb(gboolean ok, GAtResult *result, gpointer user_data)
340 struct cb_data *cbd = user_data;
341 struct ofono_voicecall *vc = cbd->user;
342 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
343 ofono_voicecall_cb_t cb = cbd->cb;
346 struct ofono_error error;
347 struct ofono_call *call;
350 decode_at_error(&error, g_at_result_final_response(result));
355 /* On a success, make sure to put all active calls on hold */
356 for (l = vd->calls; l; l = l->next) {
359 if (call->status != CALL_STATUS_ACTIVE)
362 call->status = CALL_STATUS_HELD;
363 ofono_voicecall_notify(vc, call);
366 call = create_call(vc, 0, 0, CALL_STATUS_DIALING, NULL, type, validity);
368 ofono_error("Unable to allocate call, "
369 "call tracking will fail!");
374 cb(&error, cbd->data);
377 static void hfp_dial(struct ofono_voicecall *vc,
378 const struct ofono_phone_number *ph,
379 enum ofono_clir_option clir, ofono_voicecall_cb_t cb,
382 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
383 struct cb_data *cbd = cb_data_new(cb, data);
388 snprintf(buf, sizeof(buf), "ATD+%s", ph->number);
390 snprintf(buf, sizeof(buf), "ATD%s", ph->number);
394 if (g_at_chat_send(vd->chat, buf, none_prefix,
395 atd_cb, cbd, g_free) > 0)
400 CALLBACK_WITH_FAILURE(cb, data);
403 static void hfp_template(const char *cmd, struct ofono_voicecall *vc,
404 GAtResultFunc result_cb, unsigned int affected_types,
405 ofono_voicecall_cb_t cb, void *data)
407 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
408 struct change_state_req *req = g_try_new0(struct change_state_req, 1);
416 req->affected_types = affected_types;
418 if (g_at_chat_send(vd->chat, cmd, none_prefix,
419 result_cb, req, g_free) > 0)
425 CALLBACK_WITH_FAILURE(cb, data);
428 static void hfp_answer(struct ofono_voicecall *vc,
429 ofono_voicecall_cb_t cb, void *data)
431 hfp_template("ATA", vc, generic_cb, 0, cb, data);
434 static void hfp_hangup(struct ofono_voicecall *vc,
435 ofono_voicecall_cb_t cb, void *data)
437 unsigned int affected = (1 << CALL_STATUS_INCOMING) |
438 (1 << CALL_STATUS_DIALING) |
439 (1 << CALL_STATUS_ALERTING) |
440 (1 << CALL_STATUS_ACTIVE);
442 /* Hangup current active call */
443 hfp_template("AT+CHUP", vc, generic_cb, affected, cb, data);
446 static void hfp_hold_all_active(struct ofono_voicecall *vc,
447 ofono_voicecall_cb_t cb, void *data)
449 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
451 if (vd->ag_mpty_features & HFP_AG_CHLD_2) {
452 hfp_template("AT+CHLD=2", vc, generic_cb, 0, cb, data);
456 CALLBACK_WITH_FAILURE(cb, data);
459 static void hfp_release_all_held(struct ofono_voicecall *vc,
460 ofono_voicecall_cb_t cb, void *data)
462 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
463 unsigned int held_status = 1 << CALL_STATUS_HELD;
465 if (vd->ag_mpty_features & HFP_AG_CHLD_0) {
466 hfp_template("AT+CHLD=0", vc, generic_cb, held_status,
471 CALLBACK_WITH_FAILURE(cb, data);
474 static void hfp_set_udub(struct ofono_voicecall *vc,
475 ofono_voicecall_cb_t cb, void *data)
477 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
478 unsigned int incoming_or_waiting = 1 << CALL_STATUS_WAITING;
480 if (vd->ag_mpty_features & HFP_AG_CHLD_0) {
481 hfp_template("AT+CHLD=0", vc, generic_cb, incoming_or_waiting,
486 CALLBACK_WITH_FAILURE(cb, data);
489 static gboolean expect_release(gpointer user_data)
491 struct ofono_voicecall *vc = user_data;
492 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
494 g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
495 clcc_poll_cb, vc, NULL);
497 vd->expect_release_source = 0;
502 static void release_all_active_cb(gboolean ok, GAtResult *result,
505 struct change_state_req *req = user_data;
506 struct voicecall_data *vd = ofono_voicecall_get_data(req->vc);
511 if (vd->expect_release_source)
512 g_source_remove(vd->expect_release_source);
515 * Some phones, like Nokia 500, do not send CIEV after accepting
516 * the CHLD=1 command, even though the spec states that they should.
517 * So simply poll to force the status update if the AG is misbehaving.
519 vd->expect_release_source = g_timeout_add(EXPECT_RELEASE_DELAY,
524 generic_cb(ok, result, user_data);
527 static void hfp_release_all_active(struct ofono_voicecall *vc,
528 ofono_voicecall_cb_t cb, void *data)
530 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
532 if (vd->ag_mpty_features & HFP_AG_CHLD_1) {
533 hfp_template("AT+CHLD=1", vc, release_all_active_cb, 0x1, cb,
538 CALLBACK_WITH_FAILURE(cb, data);
541 static void release_id_cb(gboolean ok, GAtResult *result,
544 struct release_id_req *req = user_data;
545 struct voicecall_data *vd = ofono_voicecall_get_data(req->vc);
546 struct ofono_error error;
548 decode_at_error(&error, g_at_result_final_response(result));
551 vd->local_release |= (1 << req->id);
553 req->cb(&error, req->data);
556 static void hfp_release_specific(struct ofono_voicecall *vc, int id,
557 ofono_voicecall_cb_t cb, void *data)
559 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
560 struct release_id_req *req = NULL;
563 if (!(vd->ag_mpty_features & HFP_AG_CHLD_1x))
566 req = g_try_new0(struct release_id_req, 1);
576 snprintf(buf, sizeof(buf), "AT+CHLD=1%d", id);
578 if (g_at_chat_send(vd->chat, buf, none_prefix,
579 release_id_cb, req, g_free) > 0)
585 CALLBACK_WITH_FAILURE(cb, data);
588 static void hfp_private_chat(struct ofono_voicecall *vc, int id,
589 ofono_voicecall_cb_t cb, void *data)
591 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
594 if (vd->ag_mpty_features & HFP_AG_CHLD_2x) {
595 snprintf(buf, sizeof(buf), "AT+CHLD=2%d", id);
597 hfp_template(buf, vc, generic_cb, 0, cb, data);
602 CALLBACK_WITH_FAILURE(cb, data);
605 static void hfp_create_multiparty(struct ofono_voicecall *vc,
606 ofono_voicecall_cb_t cb, void *data)
608 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
610 if (vd->ag_mpty_features & HFP_AG_CHLD_3) {
611 hfp_template("AT+CHLD=3", vc, generic_cb, 0, cb, data);
616 CALLBACK_WITH_FAILURE(cb, data);
619 static void hfp_transfer(struct ofono_voicecall *vc,
620 ofono_voicecall_cb_t cb, void *data)
622 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
623 /* Transfer can puts held & active calls together and disconnects
624 * from both. However, some networks support transferring of
625 * dialing/ringing calls as well.
627 unsigned int transfer = 0x1 | 0x2 | 0x4 | 0x8;
629 if (vd->ag_mpty_features & HFP_AG_CHLD_4) {
630 hfp_template("AT+CHLD=4", vc, generic_cb, transfer, cb, data);
635 CALLBACK_WITH_FAILURE(cb, data);
638 static void hfp_send_dtmf(struct ofono_voicecall *vc, const char *dtmf,
639 ofono_voicecall_cb_t cb, void *data)
641 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
642 struct change_state_req *req = g_try_new0(struct change_state_req, 1);
652 req->affected_types = 0;
654 /* strlen("AT+VTS=) = 7 + NULL */
655 buf = g_try_new(char, strlen(dtmf) + 8);
659 sprintf(buf, "AT+VTS=%s", dtmf);
661 s = g_at_chat_send(vd->chat, buf, none_prefix,
662 generic_cb, req, g_free);
672 CALLBACK_WITH_FAILURE(cb, data);
675 static void no_carrier_notify(GAtResult *result, gpointer user_data)
680 static void ccwa_notify(GAtResult *result, gpointer user_data)
682 struct ofono_voicecall *vc = user_data;
683 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
686 int num_type, validity;
687 struct ofono_call *call;
689 /* CCWA can repeat, ignore if we already have an waiting call */
690 if (g_slist_find_custom(vd->calls,
691 GINT_TO_POINTER(CALL_STATUS_WAITING),
692 at_util_call_compare_by_status))
695 g_at_result_iter_init(&iter, result);
697 if (!g_at_result_iter_next(&iter, "+CCWA:"))
700 if (!g_at_result_iter_next_string(&iter, &num))
703 if (!g_at_result_iter_next_number(&iter, &num_type))
711 DBG("ccwa_notify: %s %d %d", num, num_type, validity);
713 call = create_call(vc, 0, 1, CALL_STATUS_WAITING, num, num_type,
717 ofono_error("malloc call struct failed. "
718 "Call management is fubar");
722 ofono_voicecall_notify(vc, call);
725 static gboolean clip_timeout(gpointer user_data)
727 struct ofono_voicecall *vc = user_data;
728 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
730 struct ofono_call *call;
732 l = g_slist_find_custom(vd->calls,
733 GINT_TO_POINTER(CALL_STATUS_INCOMING),
734 at_util_call_compare_by_status);
741 ofono_voicecall_notify(vc, call);
748 static void ring_notify(GAtResult *result, gpointer user_data)
750 struct ofono_voicecall *vc = user_data;
751 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
752 struct ofono_call *call;
755 /* RING can repeat, ignore if we already have an incoming call */
756 if (g_slist_find_custom(vd->calls,
757 GINT_TO_POINTER(CALL_STATUS_INCOMING),
758 at_util_call_compare_by_status))
761 waiting = g_slist_find_custom(vd->calls,
762 GINT_TO_POINTER(CALL_STATUS_WAITING),
763 at_util_call_compare_by_status);
765 /* If we started receiving RINGS but have a waiting call, most
766 * likely all other calls were dropped and we just didn't get
767 * notified yet, drop all other calls and update the status to
771 DBG("Triggering waiting -> incoming cleanup code");
773 vd->calls = g_slist_remove_link(vd->calls, waiting);
774 release_all_calls(vc);
777 call = waiting->data;
778 call->status = CALL_STATUS_INCOMING;
779 ofono_voicecall_notify(vc, call);
784 /* Generate an incoming call of voice type */
785 call = create_call(vc, 0, 1, CALL_STATUS_INCOMING, NULL, 128, 2);
788 ofono_error("Couldn't create call, call management is fubar!");
790 /* We don't know the number must wait for CLIP to arrive before
791 * announcing the call. If timeout, we notify the call as it is.
793 vd->clip_source = g_timeout_add(CLIP_TIMEOUT, clip_timeout, vc);
796 static void clip_notify(GAtResult *result, gpointer user_data)
798 struct ofono_voicecall *vc = user_data;
799 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
804 struct ofono_call *call;
806 l = g_slist_find_custom(vd->calls,
807 GINT_TO_POINTER(CALL_STATUS_INCOMING),
808 at_util_call_compare_by_status);
811 ofono_error("CLIP for unknown call");
815 g_at_result_iter_init(&iter, result);
817 if (!g_at_result_iter_next(&iter, "+CLIP:"))
820 if (!g_at_result_iter_next_string(&iter, &num))
823 if (!g_at_result_iter_next_number(&iter, &type))
831 /* Skip subaddr, satype, alpha and validity */
832 g_at_result_iter_skip_next(&iter);
833 g_at_result_iter_skip_next(&iter);
834 g_at_result_iter_skip_next(&iter);
835 g_at_result_iter_skip_next(&iter);
837 DBG("clip_notify: %s %d %d", num, type, validity);
841 strncpy(call->phone_number.number, num,
842 OFONO_MAX_PHONE_NUMBER_LENGTH);
843 call->phone_number.number[OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';
844 call->phone_number.type = type;
845 call->clip_validity = validity;
847 ofono_voicecall_notify(vc, call);
849 if (vd->clip_source) {
850 g_source_remove(vd->clip_source);
855 static void ciev_call_notify(struct ofono_voicecall *vc,
858 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
859 struct ofono_call *call;
863 /* If call goes to 0, then we have no held or active calls
864 * in the system. The waiting calls are promoted to incoming
865 * calls, dialing calls are kept. This also handles the
866 * situation when dialing and waiting calls exist
868 release_with_status(vc, CALL_STATUS_HELD);
869 release_with_status(vc, CALL_STATUS_ACTIVE);
871 /* Promote waiting to incoming if it is the last call */
872 if (vd->calls && vd->calls->next == NULL) {
873 call = vd->calls->data;
875 if (call->status == CALL_STATUS_WAITING) {
876 call->status = CALL_STATUS_INCOMING;
877 ofono_voicecall_notify(vc, call);
887 /* In this case either dialing/alerting or the incoming call
888 * is promoted to active
890 for (l = vd->calls; l; l = l->next) {
893 if (call->status == CALL_STATUS_DIALING ||
894 call->status == CALL_STATUS_ALERTING ||
895 call->status == CALL_STATUS_INCOMING) {
896 call->status = CALL_STATUS_ACTIVE;
897 ofono_voicecall_notify(vc, call);
908 vd->cind_val[HFP_INDICATOR_CALL] = value;
911 static void ciev_callsetup_notify(struct ofono_voicecall *vc,
914 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
915 unsigned int ciev_call = vd->cind_val[HFP_INDICATOR_CALL];
916 unsigned int ciev_callheld = vd->cind_val[HFP_INDICATOR_CALLHELD];
920 dialing = find_dialing(vd->calls);
922 waiting = g_slist_find_custom(vd->calls,
923 GINT_TO_POINTER(CALL_STATUS_WAITING),
924 at_util_call_compare_by_status);
926 /* This is a truly bizarre case not covered at all by the specification
927 * (yes, they are complete idiots). Here we assume the other side is
928 * semi sane and will send callsetup updates in case the dialing call
929 * connects or the call waiting drops. In which case we must poll
931 if (waiting && dialing) {
932 g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
933 clcc_poll_cb, vc, NULL);
939 /* call=0 and callsetup=1: reject an incoming call
940 * call=0 and callsetup=2,3: interrupt an outgoing call
942 if (ciev_call == 0) {
943 release_all_calls(vc);
947 /* If call=1 and no call is waiting or dialing, the call is
948 * active and we moved it to active state when call=1 arrived
950 if (waiting == NULL && dialing == NULL)
954 * If call=1, in the waiting case we have to poll, since we
955 * have no idea whether a waiting call gave up or we accepted
956 * using release+accept or hold+accept
958 * If call=1, in the dialing + held case we have to poll as
959 * well, we have no idea whether the call connected, or released
961 if (waiting == NULL && ciev_callheld == 0) {
962 struct ofono_call *call = dialing->data;
964 /* We assume that the implementation follows closely
965 * the sequence of events in Figure 4.21. That is
966 * call=1 arrives first, then callsetup=0
969 call->status = CALL_STATUS_ACTIVE;
970 ofono_voicecall_notify(vc, call);
972 g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
973 clcc_poll_cb, vc, NULL);
979 /* Handled in RING/CCWA */
983 /* two cases of outgoing call: dial from HF or AG.
984 * from HF: query and sync the phone number.
985 * from AG: query and create call.
987 g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
988 clcc_poll_cb, vc, NULL);
993 GSList *o = g_slist_find_custom(vd->calls,
994 GINT_TO_POINTER(CALL_STATUS_DIALING),
995 at_util_call_compare_by_status);
998 struct ofono_call *call = o->data;
1000 call->status = CALL_STATUS_ALERTING;
1001 ofono_voicecall_notify(vc, call);
1012 vd->cind_val[HFP_INDICATOR_CALLSETUP] = value;
1015 static void ciev_callheld_notify(struct ofono_voicecall *vc,
1018 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
1020 struct ofono_call *call;
1021 unsigned int callheld = vd->cind_val[HFP_INDICATOR_CALLHELD];
1025 /* We have to poll here, we have no idea whether the call was
1026 * dropped using CHLD=0 or simply retrieved, or the two calls
1029 g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
1030 clcc_poll_cb, vc, NULL);
1034 if (vd->clcc_source) {
1035 g_source_remove(vd->clcc_source);
1036 vd->clcc_source = 0;
1039 /* We have to poll here, we have no idea whether the call was
1040 * accepted by CHLD=1 or swapped by CHLD=2 or one call was
1041 * chosed for private chat by CHLD=2x
1043 g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
1044 clcc_poll_cb, vc, NULL);
1047 if (callheld == 0) {
1048 for (l = vd->calls; l; l = l->next) {
1051 if (call->status != CALL_STATUS_ACTIVE)
1054 call->status = CALL_STATUS_HELD;
1055 ofono_voicecall_notify(vc, call);
1057 } else if (callheld == 1) {
1058 if (vd->clcc_source)
1059 g_source_remove(vd->clcc_source);
1061 /* We have to schedule a poll here, we have no idea
1062 * whether active call was dropped by remote or if this
1063 * is an intermediate state during call swap
1065 vd->clcc_source = g_timeout_add(POLL_CLCC_DELAY,
1070 vd->cind_val[HFP_INDICATOR_CALLHELD] = value;
1073 static void ciev_notify(GAtResult *result, gpointer user_data)
1075 struct ofono_voicecall *vc = user_data;
1076 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
1081 g_at_result_iter_init(&iter, result);
1083 if (!g_at_result_iter_next(&iter, "+CIEV:"))
1086 if (!g_at_result_iter_next_number(&iter, &index))
1089 if (!g_at_result_iter_next_number(&iter, &value))
1092 if (index == vd->cind_pos[HFP_INDICATOR_CALL])
1093 ciev_call_notify(vc, value);
1094 else if (index == vd->cind_pos[HFP_INDICATOR_CALLSETUP])
1095 ciev_callsetup_notify(vc, value);
1096 else if (index == vd->cind_pos[HFP_INDICATOR_CALLHELD])
1097 ciev_callheld_notify(vc, value);
1100 static void hfp_clcc_cb(gboolean ok, GAtResult *result, gpointer user_data)
1102 struct ofono_voicecall *vc = user_data;
1103 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
1104 unsigned int mpty_ids;
1109 vd->calls = at_util_parse_clcc(result, &mpty_ids);
1111 g_slist_foreach(vd->calls, voicecall_notify, vc);
1112 ofono_voicecall_mpty_hint(vc, mpty_ids);
1115 static void hfp_voicecall_initialized(gboolean ok, GAtResult *result,
1118 struct ofono_voicecall *vc = user_data;
1119 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
1121 DBG("hfp_voicecall_init: registering to notifications");
1123 g_at_chat_register(vd->chat, "RING", ring_notify, FALSE, vc, NULL);
1124 g_at_chat_register(vd->chat, "+CLIP:", clip_notify, FALSE, vc, NULL);
1125 g_at_chat_register(vd->chat, "+CIEV:", ciev_notify, FALSE, vc, NULL);
1126 g_at_chat_register(vd->chat, "+CCWA:", ccwa_notify, FALSE, vc, NULL);
1128 g_at_chat_register(vd->chat, "NO CARRIER",
1129 no_carrier_notify, FALSE, vc, NULL);
1131 ofono_voicecall_register(vc);
1133 /* Populate the call list */
1134 g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix, hfp_clcc_cb, vc, NULL);
1137 static int hfp_voicecall_probe(struct ofono_voicecall *vc, unsigned int vendor,
1140 struct hfp_slc_info *info = user_data;
1141 struct voicecall_data *vd;
1143 vd = g_new0(struct voicecall_data, 1);
1145 vd->chat = g_at_chat_clone(info->chat);
1146 vd->ag_features = info->ag_features;
1147 vd->ag_mpty_features = info->ag_mpty_features;
1149 memcpy(vd->cind_pos, info->cind_pos, HFP_INDICATOR_LAST);
1150 memcpy(vd->cind_val, info->cind_val, HFP_INDICATOR_LAST);
1152 ofono_voicecall_set_data(vc, vd);
1154 g_at_chat_send(vd->chat, "AT+CLIP=1", NULL, NULL, NULL, NULL);
1155 g_at_chat_send(vd->chat, "AT+CCWA=1", NULL,
1156 hfp_voicecall_initialized, vc, NULL);
1160 static void hfp_voicecall_remove(struct ofono_voicecall *vc)
1162 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
1164 if (vd->clcc_source)
1165 g_source_remove(vd->clcc_source);
1167 if (vd->clip_source)
1168 g_source_remove(vd->clip_source);
1170 if (vd->expect_release_source)
1171 g_source_remove(vd->expect_release_source);
1173 g_slist_foreach(vd->calls, (GFunc) g_free, NULL);
1174 g_slist_free(vd->calls);
1176 ofono_voicecall_set_data(vc, NULL);
1178 g_at_chat_unref(vd->chat);
1182 static struct ofono_voicecall_driver driver = {
1184 .probe = hfp_voicecall_probe,
1185 .remove = hfp_voicecall_remove,
1187 .answer = hfp_answer,
1188 .hangup_active = hfp_hangup,
1189 .hold_all_active = hfp_hold_all_active,
1190 .release_all_held = hfp_release_all_held,
1191 .set_udub = hfp_set_udub,
1192 .release_all_active = hfp_release_all_active,
1193 .release_specific = hfp_release_specific,
1194 .private_chat = hfp_private_chat,
1195 .create_multiparty = hfp_create_multiparty,
1196 .transfer = hfp_transfer,
1198 .swap_without_accept = NULL,
1199 .send_tones = hfp_send_dtmf
1202 void hfp_voicecall_init(void)
1204 ofono_voicecall_driver_register(&driver);
1207 void hfp_voicecall_exit(void)
1209 ofono_voicecall_driver_unregister(&driver);