Hi Claudio, On 02/28/2013 12:52 PM, Claudio Takahasi wrote: > This patch moves the SCO socket handling from hfp_hf_bluez5 plugin to > handsfree-audio.c file. > > This is the initial step to be able to support sending the file > descriptor through the Agent NewConnection method. > --- > plugins/hfp_hf_bluez5.c | 102 +---------------------------------------------- > src/handsfree-audio.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++- > 2 files changed, 103 insertions(+), 102 deletions(-) > > diff --git a/src/handsfree-audio.c b/src/handsfree-audio.c > index b2d4b97..14488ac 100644 > --- a/src/handsfree-audio.c > +++ b/src/handsfree-audio.c > @@ -25,12 +25,19 @@ > > #include > #include > +#include > #include > +#include > +#include > +#include > > #include > +#include Why do you need this? > > +#include Or this? > #include > > +#include "bluetooth.h" > #include "ofono.h" > > #define HFP_AUDIO_MANAGER_INTERFACE OFONO_SERVICE ".HandsfreeAudioManager" > @@ -60,6 +67,97 @@ struct agent { > static struct agent *agent = NULL; > static int ref_count = 0; > static GSList *card_list = 0; > +static guint sco_watch = 0; > +static uint16_t local_hfp_version = HFP_VERSION_1_6; Why do we need this? > + > +static ofono_bool_t slc_match(struct ofono_modem *modem, void *userdata) > +{ > + const char *remote = userdata; > + const char *value = ofono_modem_get_string(modem, "Remote"); > + > + if (value == NULL) > + return FALSE; > + > + /* Make sure SLC has been established */ > + if (ofono_modem_get_powered(modem) != TRUE) > + return FALSE; > + > + return g_str_equal(remote, value); The matching should be done on cards, not modems. > +} > + > +static gboolean sco_accept(GIOChannel *io, GIOCondition cond, > + gpointer user_data) > +{ > + struct sockaddr_sco saddr; > + socklen_t alen; > + int sk, nsk; > + char remote[18]; > + > + if (cond& (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) > + return FALSE; > + > + sk = g_io_channel_unix_get_fd(io); > + > + memset(&saddr, 0, sizeof(saddr)); > + alen = sizeof(saddr); > + > + nsk = accept(sk, (struct sockaddr *)&saddr,&alen); > + if (nsk< 0) > + return TRUE; > + > + bt_ba2str(&saddr.sco_bdaddr, remote); > + > + if (ofono_modem_find(slc_match, remote) == NULL) { > + ofono_error("Rejecting SCO: No SLC connection found!"); > + close(nsk); > + return TRUE; > + } > + > + return TRUE; > +} > + > +static int sco_init(void) > +{ > + GIOChannel *sco_io; > + struct sockaddr_sco saddr; > + int sk, defer_setup = 1; > + > + sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET | O_NONBLOCK | SOCK_CLOEXEC, > + BTPROTO_SCO); > + if (sk< 0) > + return -errno; > + > + /* Bind to local address */ > + memset(&saddr, 0, sizeof(saddr)); > + saddr.sco_family = AF_BLUETOOTH; > + bt_bacpy(&saddr.sco_bdaddr, BDADDR_ANY); > + > + if (bind(sk, (struct sockaddr *)&saddr, sizeof(saddr))< 0) { > + close(sk); > + return -errno; > + } > + > + if (setsockopt(sk, SOL_BLUETOOTH, BT_DEFER_SETUP, > + &defer_setup, sizeof(defer_setup))< 0) { > + ofono_warn("Can't enable deferred setup: %s (%d)", > + strerror(errno), errno); > + local_hfp_version = HFP_VERSION_1_5; > + } > + > + if (listen(sk, 5)< 0) { > + close(sk); > + return -errno; > + } > + > + sco_io = g_io_channel_unix_new(sk); > + sco_watch = g_io_add_watch(sco_io, > + G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, > + sco_accept, NULL); > + > + g_io_channel_unref(sco_io); > + > + return 0; > +} > > static void card_append_properties(struct ofono_handsfree_card *card, > DBusMessageIter *dict) > @@ -430,7 +528,7 @@ void ofono_handsfree_audio_unref(void) > > int __ofono_handsfree_audio_manager_init(void) > { > - return 0; > + return sco_init(); > } > > void __ofono_handsfree_audio_manager_cleanup(void) > @@ -443,4 +541,7 @@ void __ofono_handsfree_audio_manager_cleanup(void) > > ref_count = 1; > ofono_handsfree_audio_unref(); > + > + if (sco_watch> 0) > + g_source_remove(sco_watch); > } Regards, -Denis