static void lastcause_cb(struct ril_msg *message, gpointer user_data) { struct lastcause_req *reqdata = user_data; struct ofono_voicecall *vc = reqdata->vc; int id = reqdata->id; enum ofono_disconnect_reason reason = OFONO_DISCONNECT_REASON_ERROR; int last_cause = CALL_FAIL_ERROR_UNSPECIFIED; struct parcel rilp; ril_util_init_parcel(message, &rilp); if (parcel_r_int32(&rilp) > 0) last_cause = parcel_r_int32(&rilp); DBG("Call %d ended with RIL cause %d", id, last_cause); if (last_cause == CALL_FAIL_NORMAL || last_cause == CALL_FAIL_BUSY) { reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP; } ofono_voicecall_disconnected(vc, id, reason, NULL); }
static void clcc_poll_cb(struct ril_msg *message, gpointer user_data) { struct ofono_voicecall *vc = user_data; struct voicecall_data *vd = ofono_voicecall_get_data(vc); GSList *calls; GSList *n, *o; struct ofono_call *nc, *oc; struct ofono_error error; if (message->error != RIL_E_SUCCESS) { ofono_error("We are polling CLCC and received an error"); ofono_error("All bets are off for call management"); return; } calls = ril_util_parse_clcc(vd->ril, message); n = calls; o = vd->calls; while (n || o) { nc = n ? n->data : NULL; oc = o ? o->data : NULL; if (oc && (nc == NULL || (nc->id > oc->id))) { if (vd->local_release & (1 << oc->id)) { ofono_voicecall_disconnected(vc, oc->id, OFONO_DISCONNECT_REASON_LOCAL_HANGUP, NULL); } else { /* Get disconnect cause before informing oFono core */ struct lastcause_req *reqdata = g_try_new0(struct lastcause_req, 1); if (reqdata) { reqdata->vc = user_data; reqdata->id = oc->id; g_ril_send(vd->ril, RIL_REQUEST_LAST_CALL_FAIL_CAUSE, NULL, 0, lastcause_cb, reqdata, g_free); } } clear_dtmf_queue(vd); o = o->next; } else if (nc && (oc == NULL || (nc->id < oc->id))) { /* new call, signal it */ if (nc->type) { ofono_voicecall_notify(vc, nc); if (vd->cb) { ofono_voicecall_cb_t cb = vd->cb; decode_ril_error(&error, "OK"); cb(&error, vd->data); vd->cb = NULL; vd->data = NULL; } } n = n->next; } else { /* * Always use the clip_validity from old call * the only place this is truly told to us is * in the CLIP notify, the rest are fudged * anyway. Useful when RING, CLIP is used, * and we're forced to use CLCC and clip_validity * is 1 */ if (oc->clip_validity == 1) nc->clip_validity = oc->clip_validity; nc->cnap_validity = oc->cnap_validity; /* * CDIP doesn't arrive as part of CLCC, always * re-use from the old call */ memcpy(&nc->called_number, &oc->called_number, sizeof(oc->called_number)); /* * If the CLIP is not provided and the CLIP never * arrives, or RING is used, then signal the call * here */ if (nc->status == CALL_STATUS_INCOMING && (vd->flags & FLAG_NEED_CLIP)) { if (nc->type) ofono_voicecall_notify(vc, nc); vd->flags &= ~FLAG_NEED_CLIP; } else if (memcmp(nc, oc, sizeof(*nc)) && nc->type) ofono_voicecall_notify(vc, nc); n = n->next; o = o->next; } }
static void clcc_poll_cb(struct ril_msg *message, gpointer user_data) { struct ofono_voicecall *vc = user_data; struct voicecall_data *vd = ofono_voicecall_get_data(vc); GSList *calls; GSList *n, *o; struct ofono_call *nc, *oc; if (message->error != RIL_E_SUCCESS) { ofono_error("We are polling CLCC and received an error"); ofono_error("All bets are off for call management"); return; } calls = ril_util_parse_clcc(message); n = calls; o = vd->calls; while (n || o) { nc = n ? n->data : NULL; oc = o ? o->data : NULL; if (oc && (nc == NULL || (nc->id > oc->id))) { enum ofono_disconnect_reason reason; if (vd->local_release & (1 << oc->id)) reason = OFONO_DISCONNECT_REASON_LOCAL_HANGUP; else reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP; if (oc->type) ofono_voicecall_disconnected(vc, oc->id, reason, NULL); o = o->next; } else if (nc && (oc == NULL || (nc->id < oc->id))) { /* new call, signal it */ if (nc->type) ofono_voicecall_notify(vc, nc); n = n->next; } else { /* * Always use the clip_validity from old call * the only place this is truly told to us is * in the CLIP notify, the rest are fudged * anyway. Useful when RING, CLIP is used, * and we're forced to use CLCC and clip_validity * is 1 */ if (oc->clip_validity == 1) nc->clip_validity = oc->clip_validity; nc->cnap_validity = oc->cnap_validity; /* * CDIP doesn't arrive as part of CLCC, always * re-use from the old call */ memcpy(&nc->called_number, &oc->called_number, sizeof(oc->called_number)); /* * If the CLIP is not provided and the CLIP never * arrives, or RING is used, then signal the call * here */ if (nc->status == CALL_STATUS_INCOMING && (vd->flags & FLAG_NEED_CLIP)) { if (nc->type) ofono_voicecall_notify(vc, nc); vd->flags &= ~FLAG_NEED_CLIP; } else if (memcmp(nc, oc, sizeof(*nc)) && nc->type) ofono_voicecall_notify(vc, nc); n = n->next; o = o->next; } } /* No other calls, get audioflinger into normal state */ if (vd->calls && !calls) { audioflinger_set_normal_mode(); } g_slist_foreach(vd->calls, (GFunc) g_free, NULL); g_slist_free(vd->calls); vd->calls = calls; vd->local_release = 0; }