diff --git a/spa/plugins/bluez5/backend-native.c b/spa/plugins/bluez5/backend-native.c index dc6a86d59..e96e807c6 100644 --- a/spa/plugins/bluez5/backend-native.c +++ b/spa/plugins/bluez5/backend-native.c @@ -62,6 +62,9 @@ static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.native"); #define HFP_CODEC_SWITCH_INITIAL_TIMEOUT_MSEC 5000 #define HFP_CODEC_SWITCH_TIMEOUT_MSEC 20000 +#define INTERNATIONAL_NUMBER 145 +#define NATIONAL_NUMBER 129 + enum { HFP_AG_INITIAL_CODEC_SETUP_NONE = 0, HFP_AG_INITIAL_CODEC_SETUP_SEND, @@ -170,6 +173,7 @@ struct rfcomm { unsigned int cind_call_active:1; unsigned int cind_call_notify:1; unsigned int extended_error_reporting:1; + unsigned int clip_notify:1; enum hfp_hf_state hf_state; enum hsp_hs_state hs_state; unsigned int codec; @@ -942,6 +946,15 @@ next_indicator: str++; } + rfcomm_send_reply(rfcomm, "OK"); + } else if (sscanf(buf, "AT+CLIP=%u", &value) == 1) { + if (value > 1) { + spa_log_debug(backend->log, "Unsupported AT+CLIP value: %u", value); + rfcomm_send_error(rfcomm, CMEE_AG_FAILURE); + return true; + } + + rfcomm->clip_notify = value; rfcomm_send_reply(rfcomm, "OK"); } else if (sscanf(buf, "AT+CMEE=%u", &value) == 1) { if (value > 1) { @@ -2393,17 +2406,30 @@ static void send_ciev_for_each_rfcomm(struct impl *backend, int indicator, int v static void ring_timer_event(void *data, uint64_t expirations) { struct impl *backend = data; + const char *number; + unsigned int type; struct timespec ts; const uint64_t timeout = 1 * SPA_NSEC_PER_SEC; struct rfcomm *rfcomm; + number = mm_get_incoming_call_number(backend->modemmanager); + if (number) { + if (spa_strstartswith(number, "+")) + type = INTERNATIONAL_NUMBER; + else + type = NATIONAL_NUMBER; + } + ts.tv_sec = timeout / SPA_NSEC_PER_SEC; ts.tv_nsec = timeout % SPA_NSEC_PER_SEC; spa_loop_utils_update_timer(backend->loop_utils, backend->ring_timer, &ts, NULL, false); spa_list_for_each(rfcomm, &backend->rfcomm_list, link) { - if (rfcomm->slc_configured) + if (rfcomm->slc_configured) { rfcomm_send_reply(rfcomm, "RING"); + if (rfcomm->clip_notify && number) + rfcomm_send_reply(rfcomm, "+CLIP: \"%s\",%u", number, type); + } } } diff --git a/spa/plugins/bluez5/modemmanager.c b/spa/plugins/bluez5/modemmanager.c index 66fd98438..dc34510dd 100644 --- a/spa/plugins/bluez5/modemmanager.c +++ b/spa/plugins/bluez5/modemmanager.c @@ -899,6 +899,26 @@ bool mm_hangup_call(void *modemmanager, void *user_data, enum cmee_error *error) return true; } +const char *mm_get_incoming_call_number(void *modemmanager) +{ + struct impl *this = modemmanager; + struct call *call_object, *call_tmp; + + call_object = NULL; + spa_list_for_each(call_tmp, &this->call_list, link) { + if (call_tmp->state == MM_CALL_STATE_RINGING_IN) { + call_object = call_tmp; + break; + } + } + if (!call_object) { + spa_log_debug(this->log, "No ringing in call"); + return NULL; + } + + return call_object->number; +} + void *mm_register(struct spa_log *log, void *dbus_connection, const struct mm_ops *ops, void *user_data) { struct impl *this; diff --git a/spa/plugins/bluez5/modemmanager.h b/spa/plugins/bluez5/modemmanager.h index 3631c345f..182724a8e 100644 --- a/spa/plugins/bluez5/modemmanager.h +++ b/spa/plugins/bluez5/modemmanager.h @@ -61,6 +61,7 @@ bool mm_is_available(void *modemmanager); unsigned int mm_supported_features(); bool mm_answer_call(void *modemmanager, void *user_data, enum cmee_error *error); bool mm_hangup_call(void *modemmanager, void *user_data, enum cmee_error *error); +const char *mm_get_incoming_call_number(void *modemmanager); #else void *mm_register(struct spa_log *log, void *dbus_connection, const struct mm_ops *ops, void *user_data) { @@ -94,6 +95,11 @@ bool mm_hangup_call(void *modemmanager, void *user_data, enum cmee_error *error) *error = CMEE_OPERATION_NOT_SUPPORTED; return false; } + +const char *mm_get_incoming_call_number(void *modemmanager) +{ + return NULL; +} #endif #endif