diff options
-rw-r--r-- | audio/headset.c | 444 | ||||
-rw-r--r-- | audio/headset.h | 1 | ||||
-rw-r--r-- | audio/telephony-dummy.c | 48 | ||||
-rw-r--r-- | audio/telephony.h | 97 |
4 files changed, 283 insertions, 307 deletions
diff --git a/audio/headset.c b/audio/headset.c index 102d0bca..40cd23f5 100644 --- a/audio/headset.c +++ b/audio/headset.c @@ -62,9 +62,6 @@ #define RING_INTERVAL 3000 -/* Number of indicator events that can be queued */ -#define EV_BUF_SIZE 4 - #define BUF_SIZE 1024 #define HEADSET_GAIN_SPEAKER 'S' @@ -77,24 +74,23 @@ static struct { int er_mode; /* Event reporting mode */ int er_ind; /* Event reporting for indicators */ int rh; /* Response and Hold state */ - gboolean ev_buf_active; /* Buffer indicator events */ - struct { - int index; /* HFP indicator index */ - int val; /* new indicator value */ - } ev_buf[EV_BUF_SIZE]; /* Indicator event buffer */ + char *number; /* Incoming phone number */ + int number_type; /* Incoming number type */ + guint ring_timer; /* For incoming call indication */ } ag = { .telephony_ready = FALSE, .features = 0, .er_mode = 3, .er_ind = 0, .rh = -1, - .ev_buf_active = FALSE, - .ev_buf = { { 0, 0 } }, + .number = NULL, + .number_type = 0, + .ring_timer = 0, }; static gboolean sco_hci = TRUE; -static struct audio_device *active_telephony_device = NULL; +static GSList *active_devices = NULL; static char *str_state[] = { "HEADSET_STATE_DISCONNECTED", @@ -132,8 +128,6 @@ struct headset { gboolean auto_dc; - guint ring_timer; - guint dc_timer; char buf[BUF_SIZE]; @@ -143,8 +137,6 @@ struct headset { gboolean hfp_active; gboolean search_hfp; gboolean cli_active; - char *ph_number; - int type; headset_state_t state; struct pending_connect *pending; @@ -253,16 +245,13 @@ static void print_hf_features(uint32_t features) g_free(str); } -static int headset_send(struct headset *hs, char *format, ...) +static int headset_send_valist(struct headset *hs, char *format, va_list ap) { char rsp[BUF_SIZE]; - va_list ap; ssize_t total_written, written, count; int fd; - va_start(ap, format); count = vsnprintf(rsp, sizeof(rsp), format, ap); - va_end(ap); if (count < 0) return -EINVAL; @@ -286,47 +275,16 @@ static int headset_send(struct headset *hs, char *format, ...) return 0; } -static int buffer_event(int index) -{ - int i; - - for (i = 0; i < EV_BUF_SIZE; i++) { - if (ag.ev_buf[i].index == 0) { - ag.ev_buf[i].index = index + 1; - ag.ev_buf[i].val = ag.indicators[index].val; - return 0; - } - } - - error("No space in event buffer"); - return -ENOSPC; -} - -static int flush_events(void) +static int headset_send(struct headset *hs, char *format, ...) { - int i; - struct headset *hs; - - if (!active_telephony_device) - return -ENODEV; - - hs = active_telephony_device->headset; - - for (i = 0; i < EV_BUF_SIZE; i++) { - int ret; - - if (ag.ev_buf[i].index == 0) - break; - - ret = headset_send(hs, "\r\n+CIEV:%d,%d\r\n", - ag.ev_buf[i].index, ag.ev_buf[i].val); - if (ret < 0) - return ret; + va_list ap; + int ret; - ag.ev_buf[i].index = 0; - } + va_start(ap, format); + ret = headset_send_valist(hs, format, ap); + va_end(ap); - return 0; + return ret; } static int supported_features(struct audio_device *device, const char *buf) @@ -587,10 +545,42 @@ static void hfp_slc_complete(struct audio_device *dev) pending_connect_finalize(dev); } -static int event_reporting(struct audio_device *dev, const char *buf) +static int telephony_generic_rsp(struct audio_device *device, cme_error_t err) { - struct headset *hs = dev->headset; + struct headset *hs = device->headset; + + if (err != CME_ERROR_NONE) + return headset_send(hs, "\r\n+CME ERROR:%d\r\n", err); + + return headset_send(hs, "\r\nOK\r\n"); +} + +int telephony_event_reporting_rsp(void *telephony_device, cme_error_t err) +{ + struct audio_device *device = telephony_device; + struct headset *hs = device->headset; int ret; + + if (err != CME_ERROR_NONE) + return headset_send(hs, "\r\n+CME ERROR:%d\r\n", err); + + ret = headset_send(hs, "\r\nOK\r\n"); + if (ret < 0) + return ret; + + if (hs->state != HEADSET_STATE_CONNECT_IN_PROGRESS) + return 0; + + if (ag.features & AG_FEATURE_THREE_WAY_CALLING) + return 0; + + hfp_slc_complete(device); + + return 0; +} + +static int event_reporting(struct audio_device *dev, const char *buf) +{ char **tokens; /* <mode>, <keyp>, <disp>, <ind>, <bfr> */ if (strlen(buf) < 13) @@ -614,24 +604,12 @@ static int event_reporting(struct audio_device *dev, const char *buf) switch (ag.er_ind) { case 0: case 1: - telephony_event_reporting_req(ag.er_ind); + telephony_event_reporting_req(dev, ag.er_ind); break; default: return -EINVAL; } - ret = headset_send(hs, "\r\nOK\r\n"); - if (ret < 0) - return ret; - - if (hs->state != HEADSET_STATE_CONNECT_IN_PROGRESS) - return 0; - - if (ag.features & AG_FEATURE_THREE_WAY_CALLING) - return 0; - - hfp_slc_complete(dev); - return 0; } @@ -664,70 +642,78 @@ static int button_press(struct audio_device *device, const char *buf) AUDIO_HEADSET_INTERFACE, "AnswerRequested", DBUS_TYPE_INVALID); - if (hs->ring_timer) { - g_source_remove(hs->ring_timer); - hs->ring_timer = 0; + if (ag.ring_timer) { + g_source_remove(ag.ring_timer); + ag.ring_timer = 0; } return headset_send(hs, "\r\nOK\r\n"); } -static int answer_call(struct audio_device *device, const char *buf) +int telephony_answer_call_rsp(void *telephony_device, cme_error_t err) { + struct audio_device *device = telephony_device; struct headset *hs = device->headset; - ag.ev_buf_active = TRUE; - - if (telephony_answer_call_req() < 0) { - headset_send(hs, "\r\nERROR\r\n"); - return 0; - } - - flush_events(); - ag.ev_buf_active = FALSE; + if (err != CME_ERROR_NONE) + return headset_send(hs, "\r\n+CME ERROR:%d\r\n", err); - if (hs->ring_timer) { - g_source_remove(hs->ring_timer); - hs->ring_timer = 0; + if (ag.ring_timer) { + g_source_remove(ag.ring_timer); + ag.ring_timer = 0; } - if (hs->ph_number) { - g_free(hs->ph_number); - hs->ph_number = NULL; + if (ag.number) { + g_free(ag.number); + ag.number = NULL; } return headset_send(hs, "\r\nOK\r\n"); } -static int terminate_call(struct audio_device *device, const char *buf) +int telephony_anser_call_rsp(void *telephony_device, cme_error_t err) { - struct headset *hs = device->headset; + return telephony_generic_rsp(telephony_device, err); +} - ag.ev_buf_active = TRUE; +static int answer_call(struct audio_device *device, const char *buf) +{ + telephony_answer_call_req(device); - if (telephony_terminate_call_req() < 0) { - headset_send(hs, "\r\nERROR\r\n"); - return 0; - } + return 0; +} + +int telephony_terminate_call_rsp(void *telephony_device, + cme_error_t err) +{ + struct audio_device *device = telephony_device; + struct headset *hs = device->headset; - flush_events(); - ag.ev_buf_active = FALSE; + if (err != CME_ERROR_NONE) + return headset_send(hs, "\r\n+CME ERROR:%d\r\n", err); g_dbus_emit_signal(device->conn, device->path, AUDIO_HEADSET_INTERFACE, "CallTerminated", DBUS_TYPE_INVALID); - if (hs->ph_number) { - g_free(hs->ph_number); - hs->ph_number = NULL; + if (ag.number) { + g_free(ag.number); + ag.number = NULL; } - if (hs->ring_timer) { - g_source_remove(hs->ring_timer); - hs->ring_timer = 0; + if (ag.ring_timer) { + g_source_remove(ag.ring_timer); + ag.ring_timer = 0; } - return headset_send(hs, "\r\nOK\n\r"); + return headset_send(hs, "\r\nOK\r\n"); +} + +static int terminate_call(struct audio_device *device, const char *buf) +{ + telephony_terminate_call_req(device); + + return 0; } static int cli_notification(struct audio_device *device, const char *buf) @@ -742,6 +728,11 @@ static int cli_notification(struct audio_device *device, const char *buf) return headset_send(hs, "\r\nOK\r\n"); } +int telephony_response_and_hold_rsp(void *telephony_device, cme_error_t err) +{ + return telephony_generic_rsp(telephony_device, err); +} + static int response_and_hold(struct audio_device *device, const char *buf) { struct headset *hs = device->headset; @@ -749,52 +740,40 @@ static int response_and_hold(struct audio_device *device, const char *buf) if (strlen(buf) < 8) return -EINVAL; - if (buf[7] == '=') { - if (telephony_response_and_hold_req(atoi(&buf[8]) < 0)) { - headset_send(hs, "\r\nERROR\r\n"); - return 0; - } - } else if (ag.rh >= 0) - headset_send(hs, "\r\n+BTRH:%d\r\n", ag.rh); + if (buf[7] == '=') + telephony_response_and_hold_req(device, atoi(&buf[8]) < 0); + else if (ag.rh >= 0) + return headset_send(hs, "\r\n+BTRH:%d\r\n", ag.rh); + else + return headset_send(hs, "\r\nOK\r\n", ag.rh); - return headset_send(hs, "\r\nOK\n\r", ag.rh); + return 0; } -static int last_dialed_number(struct audio_device *device, const char *buf) +int telephony_last_dialed_number_rsp(void *telephony_device, cme_error_t err) { - struct headset *hs = device->headset; - - ag.ev_buf_active = TRUE; + return telephony_generic_rsp(telephony_device, err); +} - if (telephony_last_dialed_number_req() < 0) { - headset_send(hs, "\r\nERROR\r\n"); - return 0; - } +static int last_dialed_number(struct audio_device *device, const char *buf) +{ + telephony_last_dialed_number_req(device); - flush_events(); - ag.ev_buf_active = FALSE; + return 0; +} - return headset_send(hs, "\r\nOK\n\r"); +int telephony_dial_number_rsp(void *telephony_device, cme_error_t err) +{ + return telephony_generic_rsp(telephony_device, err); } static int dial_number(struct audio_device *device, const char *buf) { - struct headset *hs = device->headset; - - ag.ev_buf_active = TRUE; - - if (telephony_dial_number_req(&buf[3]) < 0) { - headset_send(hs, "\r\nERROR\r\n"); - return 0; - } - - flush_events(); - ag.ev_buf_active = FALSE; + telephony_dial_number_req(device, &buf[3]); - return headset_send(hs, "\r\nOK\n\r"); + return 0; } - static int signal_gain_setting(struct audio_device *device, const char *buf) { struct headset *hs = device->headset; @@ -840,33 +819,33 @@ ok: return headset_send(hs, "\r\nOK\r\n"); } -static int dtmf_tone(struct audio_device *device, const char *buf) +int telephony_transmit_dtmf_rsp(void *telephony_device, cme_error_t err) { - struct headset *hs = device->headset; + return telephony_generic_rsp(telephony_device, err); +} +static int dtmf_tone(struct audio_device *device, const char *buf) +{ if (strlen(buf) < 8) { error("Too short string for DTMF tone"); return -EINVAL; } - if (telephony_transmit_dtmf_req(buf[7]) < 0) { - headset_send(hs, "\r\nERROR\r\n"); - return 0; - } + telephony_transmit_dtmf_req(device, buf[7]); - return headset_send(hs, "\r\nOK\n\r"); + return 0; } -static int subscriber_number(struct audio_device *device, const char *buf) +int telephony_subscriber_number_rsp(void *telephony_device, cme_error_t err) { - struct headset *hs = device->headset; + return telephony_generic_rsp(telephony_device, err); +} - if (telephony_subscriber_number_req() < 0) { - headset_send(hs, "\r\nERROR\r\n"); - return 0; - } +static int subscriber_number(struct audio_device *device, const char *buf) +{ + telephony_subscriber_number_req(device); - return headset_send(hs, "\r\nOK\n\r"); + return 0; } static struct event event_callbacks[] = { @@ -1330,23 +1309,22 @@ static DBusMessage *hs_connect(DBusConnection *conn, DBusMessage *msg, static gboolean ring_timer_cb(gpointer data) { - struct audio_device *device = data; - struct headset *hs = device->headset; - int err; - - err = headset_send(hs, "\r\nRING\r\n"); + GSList *l; - if (err < 0) - error("Error while sending RING: %s (%d)", - strerror(-err), -err); + for (l = active_devices; l != NULL; l = l->next) { + struct audio_device *device = l->data; + struct headset *hs = device->headset; + int ret; - if (hs->cli_active && hs->ph_number) { - err = headset_send(hs, "\r\n+CLIP:\"%s\",%d\r\n", - hs->ph_number, hs->type); + ret = headset_send(hs, "\r\nRING\r\n"); + if (ret < 0) { + error("Unable to send to headset"); + continue; + } - if (err < 0) - error("Error while sending CLIP: %s (%d)", - strerror(-err), -err); + if (hs->cli_active && ag.number) + headset_send(hs, "\r\n+CLIP:\"%s\",%d\r\n", + ag.number, ag.number_type); } return TRUE; @@ -1369,7 +1347,7 @@ static DBusMessage *hs_ring(DBusConnection *conn, DBusMessage *msg, if (!reply) return NULL; - if (hs->ring_timer) { + if (ag.ring_timer) { debug("IndicateCall received when already indicating"); goto done; } @@ -1381,18 +1359,8 @@ static DBusMessage *hs_ring(DBusConnection *conn, DBusMessage *msg, "%s", strerror(-err)); } - if (hs->cli_active && hs->ph_number) { - err = headset_send(hs, "\r\n+CLIP:\"%s\",%d\r\n", - hs->ph_number, hs->type); - if (err < 0) { - dbus_message_unref(reply); - return g_dbus_create_error(msg, ERROR_INTERFACE - ".Failed", "%s", - strerror(-err)); - } - } - - hs->ring_timer = g_timeout_add(RING_INTERVAL, ring_timer_cb, device); + ring_timer_cb(NULL); + ag.ring_timer = g_timeout_add(RING_INTERVAL, ring_timer_cb, NULL); done: return reply; @@ -1415,9 +1383,9 @@ static DBusMessage *hs_cancel_call(DBusConnection *conn, if (!reply) return NULL; - if (hs->ring_timer) { - g_source_remove(hs->ring_timer); - hs->ring_timer = 0; + if (ag.ring_timer) { + g_source_remove(ag.ring_timer); + ag.ring_timer = 0; } else debug("Got CancelCall method call but no call is active"); @@ -1733,7 +1701,6 @@ struct headset *headset_init(struct audio_device *dev, sdp_record_t *record, hs->search_hfp = server_is_enabled(&dev->src, HANDSFREE_SVCLASS_ID); hs->hfp_active = FALSE; hs->cli_active = FALSE; - hs->ph_number = NULL; if (!record) goto register_iface; @@ -1920,16 +1887,11 @@ int headset_connect_sco(struct audio_device *dev, GIOChannel *io) return 0; } -int headset_close_rfcomm(struct audio_device *dev) +static int headset_close_rfcomm(struct audio_device *dev) { struct headset *hs = dev->headset; GIOChannel *rfcomm = hs->tmp_rfcomm ? hs->tmp_rfcomm : hs->rfcomm; - if (hs->ring_timer) { - g_source_remove(hs->ring_timer); - hs->ring_timer = 0; - } - if (rfcomm) { g_io_channel_close(rfcomm); g_io_channel_unref(rfcomm); @@ -1984,9 +1946,8 @@ void headset_set_state(struct audio_device *dev, headset_state_t state) AUDIO_HEADSET_INTERFACE, "Disconnected", DBUS_TYPE_INVALID); - telephony_event_reporting_req(0); - if (dev == active_telephony_device) - active_telephony_device = NULL; + telephony_device_disconnected(dev); + active_devices = g_slist_remove(active_devices, dev); break; case HEADSET_STATE_CONNECT_IN_PROGRESS: break; @@ -1997,8 +1958,8 @@ void headset_set_state(struct audio_device *dev, headset_state_t state) AUDIO_HEADSET_INTERFACE, "Connected", DBUS_TYPE_INVALID); - if (!active_telephony_device) - active_telephony_device = dev; + active_devices = g_slist_append(active_devices, dev); + telephony_device_connected(dev); } else if (hs->state == HEADSET_STATE_PLAYING) { g_dbus_emit_signal(dev->conn, dev->path, AUDIO_HEADSET_INTERFACE, @@ -2112,99 +2073,90 @@ int headset_get_sco_fd(struct audio_device *dev) return g_io_channel_unix_get_fd(hs->sco); } -int telephony_event_ind(int index) +static void send_foreach_headset(GSList *devices, char *format, ...) { - struct headset *hs; + GSList *l; + va_list ap; - if (!active_telephony_device) - return -ENODEV; + for (l = devices; l != NULL; l = l->next) { + struct audio_device *device = l->data; + struct headset *hs = device->headset; + int ret; - hs = active_telephony_device->headset; + if (!hs->hfp_active) + continue; - if (!hs->hfp_active) - return -EINVAL; + va_start(ap, format); + ret = headset_send_valist(hs, format, ap); + if (ret < 0) + error("Failed to send to headset: %s (%d)", + strerror(-ret), -ret); + va_end(ap); + } +} + +int telephony_event_ind(int index) +{ + if (!active_devices) + return -ENODEV; if (!ag.er_ind) { debug("telephony_report_event called but events are disabled"); return -EINVAL; } - if (ag.ev_buf_active) - return buffer_event(index); - - return headset_send(hs, "\r\n+CIEV:%d,%d\r\n", index + 1, + send_foreach_headset(active_devices, "\r\n+CIEV:%d,%d\r\n", index + 1, ag.indicators[index].val); + + return 0; } int telephony_response_and_hold_ind(int rh) { - struct headset *hs; - - if (!active_telephony_device) + if (!active_devices) return -ENODEV; - hs = active_telephony_device->headset; - - if (!hs->hfp_active) - return -EINVAL; - ag.rh = rh; /* If we aren't in any response and hold state don't send anything */ if (ag.rh < 0) return 0; - return headset_send(hs, "\r\n+BTRH:%d\r\n", ag.rh); + send_foreach_headset(active_devices, "\r\n+BTRH:%d\r\n", ag.rh); + + return 0; } -int telephony_calling_started_ind(const char *number) +int telephony_incoming_call_ind(const char *number, int type) { - struct headset *hs; - - if (!active_telephony_device) + if (!active_devices) return -ENODEV; - hs = active_telephony_device->headset; - - if (hs->ring_timer) { - debug("telephony_notify_call: already calling"); + if (ag.ring_timer) { + debug("telephony_incoming_call_ind: already calling"); return -EBUSY; } - if (hs->ph_number) { - g_free(hs->ph_number); - hs->ph_number = NULL; - } - - if (number) - hs->ph_number = g_strdup(number); + g_free(ag.number); + ag.number = g_strdup(number); + ag.number_type = type; - headset_send(hs, "\r\nRING\r\n"); - - if (hs->cli_active && hs->ph_number) - headset_send(hs, "\r\n+CLIP:\"%s\",%d\r\n", - hs->ph_number, hs->type); - - hs->ring_timer = g_timeout_add(RING_INTERVAL, ring_timer_cb, - active_telephony_device); + ring_timer_cb(NULL); + ag.ring_timer = g_timeout_add(RING_INTERVAL, ring_timer_cb, NULL); return 0; } int telephony_calling_stopped_ind(void) { - struct headset *hs; - - if (!active_telephony_device) + if (!active_devices) return -ENODEV; - hs = active_telephony_device->headset; - - if (!hs->ring_timer) + if (!ag.ring_timer) return -EINVAL; - g_source_remove(hs->ring_timer); - hs->ring_timer = 0; + g_source_remove(ag.ring_timer); + ag.ring_timer = 0; return 0; } diff --git a/audio/headset.h b/audio/headset.h index a211d7dd..9152401d 100644 --- a/audio/headset.h +++ b/audio/headset.h @@ -60,7 +60,6 @@ void set_hfp_active(struct audio_device *dev, gboolean active); void headset_set_authorized(struct audio_device *dev); int headset_connect_rfcomm(struct audio_device *dev, GIOChannel *chan); -int headset_close_rfcomm(struct audio_device *dev); int headset_connect_sco(struct audio_device *dev, GIOChannel *io); headset_state_t headset_get_state(struct audio_device *dev); diff --git a/audio/telephony-dummy.c b/audio/telephony-dummy.c index 315501a4..7fd75cc4 100644 --- a/audio/telephony-dummy.c +++ b/audio/telephony-dummy.c @@ -58,70 +58,84 @@ static struct indicator dummy_indicators[] = { NULL } }; -int telephony_event_reporting_req(int ind) +void telephony_device_connected(void *telephony_device) +{ +} + +void telephony_device_disconnected(void *telephony_device) +{ + events_enabled = FALSE; +} + +void telephony_event_reporting_req(void *telephony_device, int ind) { events_enabled = ind == 1 ? TRUE : FALSE; - return 0; + telephony_event_reporting_rsp(telephony_device, CME_ERROR_NONE); } -int telephony_response_and_hold_req(int rh) +void telephony_response_and_hold_req(void *telephony_device, int rh) { response_and_hold = rh; telephony_response_and_hold_ind(response_and_hold); - return 0; + telephony_response_and_hold_rsp(telephony_device, CME_ERROR_NONE); } -int telephony_last_dialed_number_req(void) +void telephony_last_dialed_number_req(void *telephony_device) { + telephony_last_dialed_number_rsp(telephony_device, CME_ERROR_NONE); + /* Notify outgoing call set-up successfully initiated */ telephony_update_indicator(dummy_indicators, "callsetup", EV_CALLSETUP_OUTGOING); telephony_update_indicator(dummy_indicators, "callsetup", EV_CALLSETUP_ALERTING); - return 0; } -int telephony_terminate_call_req(void) +void telephony_terminate_call_req(void *telephony_device) { + telephony_terminate_call_rsp(telephony_device, CME_ERROR_NONE); + if (telephony_get_indicator(dummy_indicators, "callsetup") > 0) telephony_update_indicator(dummy_indicators, "callsetup", EV_CALLSETUP_INACTIVE); else telephony_update_indicator(dummy_indicators, "call", EV_CALL_INACTIVE); - return 0; } -int telephony_answer_call_req(void) +void telephony_answer_call_req(void *telephony_device) { + telephony_answer_call_rsp(telephony_device, CME_ERROR_NONE); + telephony_update_indicator(dummy_indicators, "call", EV_CALL_ACTIVE); telephony_update_indicator(dummy_indicators, "callsetup", EV_CALLSETUP_INACTIVE); - return 0; } -int telephony_dial_number_req(const char *number) +void telephony_dial_number_req(void *telephony_device, const char *number) { + telephony_dial_number_rsp(telephony_device, CME_ERROR_NONE); + /* Notify outgoing call set-up successfully initiated */ telephony_update_indicator(dummy_indicators, "callsetup", EV_CALLSETUP_OUTGOING); telephony_update_indicator(dummy_indicators, "callsetup", EV_CALLSETUP_ALERTING); - return 0; } -int telephony_transmit_dtmf_req(char tone) +void telephony_transmit_dtmf_req(void *telephony_device, char tone) { debug("telephony-dummy: transmit dtmf: %c", tone); - return 0; + telephony_transmit_dtmf_rsp(telephony_device, CME_ERROR_NONE); } -int telephony_subscriber_number_req(void) +void telephony_subscriber_number_req(void *telephony_device) { - return 0; + debug("telephony-dummy: subscriber number request"); + telephony_subscriber_number_rsp(telephony_device, CME_ERROR_NONE); } /* D-Bus method handlers */ @@ -158,7 +172,7 @@ static DBusMessage *incoming_call(DBusConnection *conn, DBusMessage *msg, telephony_update_indicator(dummy_indicators, "callsetup", EV_CALLSETUP_INCOMING); - telephony_calling_started_ind(number); + telephony_incoming_call_ind(number, 0); return dbus_message_new_method_return(msg); } diff --git a/audio/telephony.h b/audio/telephony.h index 50c1a57b..72608dc5 100644 --- a/audio/telephony.h +++ b/audio/telephony.h @@ -65,29 +65,31 @@ #define EV_ROAM_ACTIVE 1 /* Extended Audio Gateway Error Result Codes */ -#define CME_ERROR_NONE -1 -#define CME_ERROR_AG_FAILURE 0 -#define CME_ERROR_NO_PHONE_CONNECTION 1 -#define CME_ERROR_NOT_ALLOWED 3 -#define CME_ERROR_NOT_SUPPORTED 4 -#define CME_ERROR_PH_SIM_PIN_REQUIRED 5 -#define CME_ERROR_SIM_NOT_INSERTED 10 -#define CME_ERROR_SIM_PIN_REQUIRED 11 -#define CME_ERROR_SIM_PUK_REQUIRED 12 -#define CME_ERROR_SIM_FAILURE 13 -#define CME_ERROR_SIM_BUSY 14 -#define CME_ERROR_INCORRECT_PASSWORD 16 -#define CME_ERROR_SIM_PIN2_REQUIRED 17 -#define CME_ERROR_SIM_PUK2_REQUIRED 18 -#define CME_ERROR_MEMORY_FULL 20 -#define CME_ERROR_INVALID_INDEX 21 -#define CME_ERROR_MEMORY_FAILURE 23 -#define CME_ERROR_TEXT_STRING_TOO_LONG 24 -#define CME_ERROR_INVALID_TEXT_STRING 25 -#define CME_ERROR_DIAL_STRING_TOO_LONG 26 -#define CME_ERROR_INVALID_DIAL_STRING 27 -#define CME_ERROR_NO_NETWORK_SERVICE 30 -#define CME_ERROR_NETWORK_NOT_ALLOWED 32 +typedef enum { + CME_ERROR_NONE = -1, + CME_ERROR_AG_FAILURE = 0, + CME_ERROR_NO_PHONE_CONNECTION = 1, + CME_ERROR_NOT_ALLOWED = 3, + CME_ERROR_NOT_SUPPORTED = 4, + CME_ERROR_PH_SIM_PIN_REQUIRED = 5, + CME_ERROR_SIM_NOT_INSERTED = 10, + CME_ERROR_SIM_PIN_REQUIRED = 11, + CME_ERROR_SIM_PUK_REQUIRED = 12, + CME_ERROR_SIM_FAILURE = 13, + CME_ERROR_SIM_BUSY = 14, + CME_ERROR_INCORRECT_PASSWORD = 16, + CME_ERROR_SIM_PIN2_REQUIRED = 17, + CME_ERROR_SIM_PUK2_REQUIRED = 18, + CME_ERROR_MEMORY_FULL = 20, + CME_ERROR_INVALID_INDEX = 21, + CME_ERROR_MEMORY_FAILURE = 23, + CME_ERROR_TEXT_STRING_TOO_LONG = 24, + CME_ERROR_INVALID_TEXT_STRING = 25, + CME_ERROR_DIAL_STRING_TOO_LONG = 26, + CME_ERROR_INVALID_DIAL_STRING = 27, + CME_ERROR_NO_NETWORK_SERVICE = 30, + CME_ERROR_NETWORK_NOT_ALLOWED = 32, +} cme_error_t; struct indicator { const char *desc; @@ -95,33 +97,42 @@ struct indicator { int val; }; -int telephony_event_reporting_req(int ind); +/* Notify telephony-*.c of connected/disconnected devices. Implemented by + * telephony-*.c + */ +void telephony_device_connected(void *telephony_device); +void telephony_device_disconnected(void *telephony_device); +/* HF requests (sent by the handsfree device). These are implemented by + * telephony-*.c + */ +void telephony_event_reporting_req(void *telephony_device, int ind); +void telephony_response_and_hold_req(void *telephony_device, int rh); +void telephony_last_dialed_number_req(void *telephony_device); +void telephony_terminate_call_req(void *telephony_device); +void telephony_answer_call_req(void *telephony_device); +void telephony_dial_number_req(void *telephony_device, const char *number); +void telephony_transmit_dtmf_req(void *telephony_device, char tone); +void telephony_subscriber_number_req(void *telephony_device); + +/* AG responses to HF requests. These are implemented by headset.c */ +int telephony_event_reporting_rsp(void *telephony_device, cme_error_t err); +int telephony_response_and_hold_rsp(void *telephony_device, cme_error_t err); +int telephony_last_dialed_number_rsp(void *telephony_device, cme_error_t err); +int telephony_terminate_call_rsp(void *telephony_device, cme_error_t err); +int telephony_answer_call_rsp(void *telephony_device, cme_error_t err); +int telephony_dial_number_rsp(void *telephony_device, cme_error_t err); +int telephony_transmit_dtmf_rsp(void *telephony_device, cme_error_t err); +int telephony_subscriber_number_rsp(void *telephony_device, cme_error_t err); + +/* Event indications by AG. These are implemented by headset.c */ int telephony_event_ind(int index); - -int telephony_response_and_hold_req(int rh); - int telephony_response_and_hold_ind(int rh); - -int telephony_last_dialed_number_req(void); - -int telephony_terminate_call_req(void); - -int telephony_answer_call_req(void); - -int telephony_dial_number_req(const char *number); - -int telephony_calling_started_ind(const char *number); - +int telephony_incoming_call_ind(const char *number, int type); int telephony_calling_stopped_ind(void); - int telephony_ready_ind(uint32_t features, const struct indicator *indicators, int rh); -int telephony_transmit_dtmf_req(char tone); - -int telephony_subscriber_number_req(void); - /* Helper function for quick indicator updates */ static inline int telephony_update_indicator(struct indicator *indicators, const char *desc, |