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, | 
