Return-Path: From: Andrei Emeltchenko To: linux-bluetooth@vger.kernel.org Subject: [PATCHv4 08/10] android/health: Add handling for ECHO service Date: Fri, 27 Jun 2014 18:16:09 +0300 Message-Id: <1403882171-16308-8-git-send-email-Andrei.Emeltchenko.news@gmail.com> In-Reply-To: <1403882171-16308-1-git-send-email-Andrei.Emeltchenko.news@gmail.com> References: <1403882171-16308-1-git-send-email-Andrei.Emeltchenko.news@gmail.com> Sender: linux-bluetooth-owner@vger.kernel.org List-ID: From: Andrei Emeltchenko Reply received buffer back for ECHO service. --- android/health.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/android/health.c b/android/health.c index 8bd857d..1796d7c 100644 --- a/android/health.c +++ b/android/health.c @@ -1056,9 +1056,71 @@ static int get_dcpsm(sdp_list_t *recs, uint16_t *dcpsm) return -1; } +static int send_echo_data(int sock, const void *buf, uint32_t size) +{ + const uint8_t *buf_b = buf; + uint32_t sent = 0; + + while (sent < size) { + int n = write(sock, buf_b + sent, size - sent); + if (n < 0) + return -1; + sent += n; + } + + return 0; +} + +static gboolean serve_echo(GIOChannel *io, GIOCondition cond, gpointer data) +{ + struct health_channel *channel = data; + uint8_t buf[MCAP_DC_MTU]; + int fd, len, ret; + + DBG("channel %p", channel); + + if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) { + DBG("Error condition on channel"); + return FALSE; + } + + fd = g_io_channel_unix_get_fd(io); + + len = read(fd, buf, sizeof(buf)); + if (len < 0) { + DBG("Error reading ECHO"); + return FALSE; + } + + ret = send_echo_data(fd, buf, len); + if (ret != len) + DBG("Error sending ECHO back"); + + return FALSE; +} + static void mcap_mdl_connected_cb(struct mcap_mdl *mdl, void *data) { - DBG("Not Implemeneted"); + struct health_channel *channel = data; + + if (!channel->mdl) + channel->mdl = mcap_mdl_ref(mdl); + + DBG("Data channel connected: mdl %p channel %p", mdl, channel); + + if (channel->mdep_id == MDEP_ECHO) { + GIOChannel *io; + int fd; + + fd = mcap_mdl_get_fd(channel->mdl); + if (fd < 0) + return; + + io = g_io_channel_unix_new(fd); + g_io_add_watch(io, G_IO_ERR | G_IO_HUP | G_IO_NVAL | G_IO_IN, + serve_echo, channel); + g_io_channel_unref(io); + } } static void mcap_mdl_closed_cb(struct mcap_mdl *mdl, void *data) -- 1.8.3.2