summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsamr7 <samr7@126591fb-c623-4b62-a76d-97a8e4f34109>2008-11-30 11:00:36 +0000
committersamr7 <samr7@126591fb-c623-4b62-a76d-97a8e4f34109>2008-11-30 11:00:36 +0000
commita8776cf286e9027627ad1098712d8a0a93f0259f (patch)
tree256b4e62180599a7a9db2da8d1cd9a18901119ae
parent34c5e90c0159ab63b2636c596cceeea9f5613537 (diff)
downloadnohands-a8776cf286e9027627ad1098712d8a0a93f0259f.tar.gz
Make HfpService::Connect() follow the error reporting model.
Add HfpService::Get/SetScoEnabled() to globally disable SCO support. git-svn-id: http://nohands.svn.sourceforge.net/svnroot/nohands/trunk@49 126591fb-c623-4b62-a76d-97a8e4f34109
-rw-r--r--include/libhfp/hfp.h79
-rw-r--r--libhfp/hfp.cpp66
2 files changed, 128 insertions, 17 deletions
diff --git a/include/libhfp/hfp.h b/include/libhfp/hfp.h
index 749d66f..8bf1b3f 100644
--- a/include/libhfp/hfp.h
+++ b/include/libhfp/hfp.h
@@ -99,6 +99,8 @@ private:
void Timeout(TimerNotifier*);
+ bool m_sco_enable;
+
ListItem m_autoreconnect_list;
int m_autoreconnect_timeout;
bool m_autoreconnect_set;
@@ -263,9 +265,13 @@ public:
* -# Return the HfpSession.
*
* @param[in] devp BtDevice representing the target device.
+ * @param[out] error Error information structure. If this method
+ * fails and returns @c 0, and @em error is not 0, @em error
+ * will be filled out with information on the cause of the failure.
*
* @return The HfpSession object associated with raddr, which
- * is hopefully in the Connecting or Connected state.
+ * is hopefully in the Connecting or Connected state, or @c 0
+ * on failure.
*
* @note If a device is found or created successfully, it is
* returned with an additional reference added to it, to prevent
@@ -275,7 +281,7 @@ public:
*
* @sa GetDevice(), HfpSession::Connect()
*/
- HfpSession *Connect(BtDevice *devp);
+ HfpSession *Connect(BtDevice *devp, ErrorInfo *error = 0);
/**
* @brief Initiate a connection to an audio gateway device with
@@ -290,9 +296,13 @@ public:
*
* @param[in] addr Bluetooth address of the device to be created
* and connected to.
+ * @param[out] error Error information structure. If this method
+ * fails and returns @c 0, and @em error is not 0, @em error
+ * will be filled out with information on the cause of the failure.
*
* @return The HfpSession object associated with raddr, which
- * is hopefully in the Connecting or Connected state.
+ * is hopefully in the Connecting or Connected state, or @c 0
+ * on failure.
*
* @note If a device is found or created successfully, it is
* returned with an additional reference added to it, to prevent
@@ -302,7 +312,7 @@ public:
*
* @sa GetDevice(), HfpSession::Connect()
*/
- HfpSession *Connect(bdaddr_t const &addr);
+ HfpSession *Connect(bdaddr_t const &addr, ErrorInfo *error = 0);
/**
* @brief Initiate a connection to an audio gateway device by
@@ -322,9 +332,13 @@ public:
*
* @param[in] addrstr Address of the device represented as a string,
* e.g. "00:07:61:D2:55:37" but not "Motorola" or "Logitech."
+ * @param[out] error Error information structure. If this method
+ * fails and returns @c 0, and @em error is not 0, @em error
+ * will be filled out with information on the cause of the failure.
*
* @return The HfpSession object associated with addrstr, which
- * is hopefully in the Connecting or Connected state.
+ * is hopefully in the Connecting or Connected state, or @c 0
+ * on failure.
*
* @note If a device is found or created successfully, it is
* returned with an additional reference added to it, to prevent
@@ -341,7 +355,7 @@ public:
*
* @sa GetDevice(), HfpSession::Connect()
*/
- HfpSession *Connect(const char *addrstr);
+ HfpSession *Connect(const char *addrstr, ErrorInfo *error = 0);
/**
* @brief Query the first session object
@@ -368,6 +382,56 @@ public:
{ return (HfpSession *) BtService::
GetNextSession((BtSession *)sessp); }
+ /**
+ * @brief Query whether SCO audio functionality is enabled
+ *
+ * This method retrieves the state of the SCO audio
+ * functionality. For more information, see SetScoEnabled().
+ */
+ bool GetScoEnabled(void) const { return m_sco_enable; }
+
+ /**
+ * @brief Set whether SCO audio functionality is enabled
+ *
+ * In some situations, it is desirable to use a different
+ * subsystem to handle SCO audio connections and audio
+ * processing. This option allows SCO audio support to be
+ * completely disabled, presumably so that libhfp may coexist
+ * with another subsystem that already handles SCO audio.
+ *
+ * Unfortunately, this is not terribly useful. Most packages
+ * that implement SCO audio support do so properly in the sense
+ * of only permitting it with a service-level connection of
+ * some sort. The BlueZ 4.x audio components are an example
+ * of this.
+ *
+ * If SCO support is enabled:
+ * - A SCO listener socket will be registered, and bound to
+ * the local address of the selected HCI.
+ * - Inbound SCO connections will be accepted for connected
+ * sessions, and notified through the session's
+ * HfpSession::cb_NotifyAudioConnection callback. For
+ * disconnected or incompletely connected sessions, SCO
+ * audio connections will be refused.
+ * - Outbound SCO connection requests from connected
+ * HfpSession objects, through HfpSession::SndOpen(), will
+ * not automatically fail.
+ *
+ * @param[in] sco_enable Set to @c true to enable SCO audio
+ * handling support, @c false to disable.
+ * @param[out] error Error information structure. If this method
+ * fails and returns @em false, and @em error is not 0, @em error
+ * will be filled out with information on the cause of the failure.
+ *
+ * @retval true SCO enablement value successfully changed
+ * @retval false SCO enablement value could not be changed.
+ * This can be caused by attempting to enable SCO support
+ * when the HfpSession is active and the SCO listener socket
+ * could not be created. The reason for the failure will be
+ * reported through @em error, if @em error is not @c 0.
+ */
+ bool SetScoEnabled(bool sco_enable, ErrorInfo *error = 0);
+
int GetCaps(void) const { return m_brsf_my_caps; }
void SetCaps(int caps) { m_brsf_my_caps = caps; }
@@ -1450,6 +1514,9 @@ public:
* @retval false Audio is either already connected, the
* connection attempt failed, or the @em play and/or @em capture
* parameters were @em false.
+ *
+ * @note If SCO audio support is disabled at the service level,
+ * this method will fail. See HfpService::SetScoEnabled().
*/
bool SndOpen(bool play, bool capture, ErrorInfo *error = 0);
/**
diff --git a/libhfp/hfp.cpp b/libhfp/hfp.cpp
index 81ffac4..51d3b26 100644
--- a/libhfp/hfp.cpp
+++ b/libhfp/hfp.cpp
@@ -54,7 +54,7 @@ HfpService(int caps)
: RfcommService(HANDSFREE_AGW_SVCLASS_ID),
m_sco_listen(-1), m_sco_listen_not(0),
m_brsf_my_caps(caps), m_svc_name(0), m_svc_desc(0),
- m_sdp_rec(0), m_timer(0),
+ m_sdp_rec(0), m_timer(0), m_sco_enable(true),
m_autoreconnect_timeout(15000), m_autoreconnect_set(false),
m_complaint_sco_mtu(false), m_complaint_sco_vs(false),
m_complaint_sco_listen(false)
@@ -473,7 +473,7 @@ Start(ErrorInfo *error)
if (!RfcommListen(error))
goto failed;
- if (!ScoListen(error))
+ if (m_sco_enable && !ScoListen(error))
goto failed;
if (!SdpRegister(error))
@@ -527,39 +527,74 @@ DefaultSessionFactory(BtDevice *devp)
}
HfpSession *HfpService::
-Connect(BtDevice *devp)
+Connect(BtDevice *devp, ErrorInfo *error)
{
HfpSession *sessp = GetSession(devp);
- if (sessp && !sessp->Connect()) {
+ if (!sessp) {
+ if (error)
+ error->SetNoMem();
+ return 0;
+ }
+ if (!sessp->Connect(error)) {
sessp->Put();
- sessp = 0;
+ return 0;
}
return sessp;
}
HfpSession *HfpService::
-Connect(bdaddr_t const &bdaddr)
+Connect(bdaddr_t const &bdaddr, ErrorInfo *error)
{
HfpSession *sessp = GetSession(bdaddr);
- if (sessp && !sessp->Connect()) {
+ if (!sessp) {
+ if (error)
+ error->SetNoMem();
+ return 0;
+ }
+ if (!sessp->Connect(error)) {
sessp->Put();
- sessp = 0;
+ return 0;
}
return sessp;
}
HfpSession *HfpService::
-Connect(const char *addrstr)
+Connect(const char *addrstr, ErrorInfo *error)
{
HfpSession *sessp = GetSession(addrstr);
- if (sessp && !sessp->Connect()) {
+ if (!sessp) {
+ if (error)
+ error->SetNoMem();
+ return 0;
+ }
+ if (!sessp->Connect(error)) {
sessp->Put();
- sessp = 0;
+ return 0;
}
return sessp;
}
bool HfpService::
+SetScoEnabled(bool sco_enable, ErrorInfo *error)
+{
+ if (m_sco_enable == sco_enable)
+ return true;
+
+ if (GetHub()->IsStarted()) {
+ if (!sco_enable) {
+ ScoCleanup();
+
+ }
+ else if (!ScoListen(error)) {
+ return false;
+ }
+ }
+
+ m_sco_enable = sco_enable;
+ return true;
+}
+
+bool HfpService::
SetServiceName(const char *val, ErrorInfo *error)
{
char *oldval, *newval = 0;
@@ -856,6 +891,15 @@ ScoConnect(ErrorInfo *error)
int ssock, err;
BtHci *hcip;
+ if (!GetService()->GetScoEnabled()) {
+ if (error)
+ error->Set(LIBHFP_ERROR_SUBSYS_BT,
+ LIBHFP_ERROR_BT_BAD_SCO_CONFIG,
+ "SCO audio support disabled by "
+ "configuration");
+ return false;
+ }
+
if (!IsConnected()) {
if (error)
error->Set(LIBHFP_ERROR_SUBSYS_BT,