summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2006-11-22 15:00:59 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2006-11-22 15:00:59 +0000
commit12bb1a4aafde063214a0c6aa2a9abffd2e079725 (patch)
treefe09fbb2cdcc724dca0fd50c6ec21bd58a78f06c
parent62281b2196470bee19d906bf5d4edba81d7e4020 (diff)
Implement ring timer and CancelRinging method
-rw-r--r--audio/headset.c83
1 files changed, 78 insertions, 5 deletions
diff --git a/audio/headset.c b/audio/headset.c
index d50de1a5..f26fcfed 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -50,6 +50,8 @@
#include "logging.h"
#include "glib-ectomy.c"
+#define RING_INTERVAL 3000
+
#define HEADSET_PATH "/org/bluez/headset"
static const char *hs_path = HEADSET_PATH;
@@ -65,6 +67,7 @@ struct hs_connection {
char address[18];
GIOChannel *rfcomm;
GIOChannel *sco;
+ guint ring_timer;
};
static gboolean connect_in_progress = FALSE;
@@ -89,6 +92,7 @@ static DBusHandlerResult hs_connect(DBusConnection *conn, DBusMessage *msg,
const char *address);
static DBusHandlerResult hs_disconnect(DBusConnection *conn, DBusMessage *msg);
static DBusHandlerResult hs_ring(DBusConnection *conn, DBusMessage *msg);
+static DBusHandlerResult hs_cancel_ringing(DBusConnection *conn, DBusMessage *msg);
static int set_nonblocking(int fd, int *err)
{
@@ -207,6 +211,11 @@ static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond, struct hs_conn
printf("%s\n", buf);
}
+ if (connected_hs->ring_timer) {
+ g_timeout_remove(connected_hs->ring_timer);
+ connected_hs->ring_timer = 0;
+ }
+
return TRUE;
failed:
@@ -734,6 +743,9 @@ static DBusHandlerResult hs_message(DBusConnection *conn,
if (strcmp(member, "Ring") == 0)
return hs_ring(conn, msg);
+ if (strcmp(member, "CancelRinging") == 0)
+ return hs_cancel_ringing(conn, msg);
+
/* Handle Headset interface methods here */
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -1064,11 +1076,41 @@ static DBusHandlerResult hs_connect(DBusConnection *conn, DBusMessage *msg,
return DBUS_HANDLER_RESULT_HANDLED;;
}
+static int send_ring(GIOChannel *io)
+{
+ const char *ring_str = "\r\nRING\r\n";
+ int sk, written, len;
+
+ sk = g_io_channel_unix_get_fd(connected_hs->rfcomm);
+
+ len = strlen(ring_str);
+ written = 0;
+
+ while (written < len) {
+ int ret;
+
+ ret = write(sk, ring_str + written, len - written);
+
+ if (ret < 0)
+ return ret;
+
+ written += ret;
+ }
+
+ return 0;
+}
+
+static gboolean ring_timer(gpointer user_data)
+{
+ if (send_ring(connected_hs->rfcomm) < 0)
+ error("Sending RING failed");
+
+ return TRUE;
+}
+
static DBusHandlerResult hs_ring(DBusConnection *conn, DBusMessage *msg)
{
DBusMessage *reply;
- const char *ring_str = "\r\nRING\r\n";
- int sk, ret;
if (!connected_hs)
return err_not_connected(conn, msg);
@@ -1077,14 +1119,45 @@ static DBusHandlerResult hs_ring(DBusConnection *conn, DBusMessage *msg)
if (!reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
- sk = g_io_channel_unix_get_fd(connected_hs->rfcomm);
+ if (connected_hs->ring_timer) {
+ debug("Got Ring method call while ringing already in progress");
+ goto done;
+ }
- ret = write(sk, ring_str, strlen(ring_str));
- if (ret < strlen(ring_str)) {
+ if (send_ring(connected_hs->rfcomm) < 0) {
dbus_message_unref(reply);
return err_failed(conn, msg);
}
+ connected_hs->ring_timer = g_timeout_add(RING_INTERVAL, ring_timer, NULL);
+
+done:
+ dbus_connection_send(conn, reply, NULL);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult hs_cancel_ringing(DBusConnection *conn, DBusMessage *msg)
+{
+ DBusMessage *reply;
+
+ if (!connected_hs)
+ return err_not_connected(conn, msg);
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+ if (!connected_hs->ring_timer) {
+ debug("Got CancelRinging method call but ringing is not in progress");
+ goto done;
+ }
+
+ g_timeout_remove(connected_hs->ring_timer);
+ connected_hs->ring_timer = 0;
+
+done:
dbus_connection_send(conn, reply, NULL);
dbus_message_unref(reply);