From f3017b966cb1866f5714650f606d7544afa7c43d Mon Sep 17 00:00:00 2001 From: samr7 Date: Thu, 13 Nov 2008 18:26:44 +0000 Subject: Documentation improvements. git-svn-id: http://nohands.svn.sourceforge.net/svnroot/nohands/trunk@33 126591fb-c623-4b62-a76d-97a8e4f34109 --- Doxyfile | 2 +- data/doxymain.h | 50 ++++++++----------- data/hfpd-dbus-doc.cs | 123 ++++++++++++++++++++++++++++++++++++++++++----- include/libhfp/bt.h | 78 ++++++++++++++++++++++-------- include/libhfp/soundio.h | 49 ++++++++++++++----- 5 files changed, 229 insertions(+), 73 deletions(-) diff --git a/Doxyfile b/Doxyfile index c73c904..58cc5e0 100644 --- a/Doxyfile +++ b/Doxyfile @@ -4,7 +4,7 @@ # Project related configuration options #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = HFP for Linux +PROJECT_NAME = libhfp PROJECT_NUMBER = OUTPUT_DIRECTORY = doc CREATE_SUBDIRS = NO diff --git a/data/doxymain.h b/data/doxymain.h index 0fed857..2825949 100644 --- a/data/doxymain.h +++ b/data/doxymain.h @@ -19,51 +19,43 @@ */ /** - * @mainpage Bluetooth Hands-Free Profile Server + * @mainpage Bluetooth Hands-Free Profile Service Library * * @section intro Introduction * - * HFP for Linux is a Bluetooth Hands-Free Profile server, allowing - * your Linux system to act as a speakerphone for your mobile phone. - * It aims to be a compliant Bluetooth HFP 1.5 Hands Free - * implementation, supporting all required commands and notifications, - * as well as streaming audio. The HFP for Linux package includes - * three main components: + * The HFP for Linux package provides a low-level library, libhfp, that + * implements the smallest details of the hands-free side of + * the Bluetooth Hands-Free Profile. libhfp is written in C++, and is + * intended to be modular and independent of any specific application + * toolkit. libhfp can be integrated with the main event loop of Qt, + * glib, or any other toolkit with support for low-level events. * - * - @b libhfp, a modular, toolkit-independent backend library with - * rich APIs. This documentation is primarily concerned with libhfp. - * - @b hfpd, a D-Bus service daemon providing D-Bus APIs. A link to - * documentation for the D-Bus APIs can be found on the HFP for Linux - * home page. - * - @b hfconsole, a PyGTK console application for controlling the + * The HFP for Linux package includes two applications that make use of + * libhfp: + * - @b hfpd, a D-Bus service daemon that uses libhfp and provides + * D-Bus APIs. Documentation for the D-Bus APIs is available in + * a separate document. hfpd is the + * backend for hfconsole, a PyGTK console application for controlling the * D-Bus service daemon. + * - @b hfstandalone, a demonstration monolithic speakerphone program built + * with libhfp and Trolltech Qt. hfstandalone uses its own instance of + * libhfp and operates independently of hfpd. * - * The package also includes @b hfstandalone, a demonstration - * monolithic speakerphone program built with Trolltech Qt. hfstandalone - * uses its own instance of libhfp and operates independently of hfpd. - * - * The developer of HFP for Linux believes that HFP is most useful in - * embedded devices, each with unique user interface requirements. - * Because of this, emphasis is placed on the internals and backend - * interfaces of libhfp, and the D-Bus interfaces of hfpd, so that it - * may be useful as a toolkit for building HFP applications and - * integrating HFP functionality into other applications. - * - * @section features Features + * @section features libhfp Features * * - Supports device scanning, connection, disconnection, and automatic * reconnection * - Supports multiple concurrently connected audio gateway devices * - Resilient to loss of Bluetooth service * - Modular, event-driven backend - * - All APIs are single-threaded, clients do not need to be concerned with - * thread synchronization + * - All APIs are single-threaded, libhfp does not force its clients to be + * concerned with threading and synchronization * - Audio handling components are completely asynchronous * - Supports the ALSA and OSS audio hardware interfaces * - Supports microphone input cleanup, including echo cancellation and - * noise reduction. + * noise reduction * - Supports simple recording and playback of stored audio files, e.g. - * for recording calls and playing ring tones. + * for recording calls and playing ring tones * * @section reqs Software Requirements and Build Options * diff --git a/data/hfpd-dbus-doc.cs b/data/hfpd-dbus-doc.cs index 18ab6df..7ed3264 100644 --- a/data/hfpd-dbus-doc.cs +++ b/data/hfpd-dbus-doc.cs @@ -34,6 +34,11 @@ * D-Bus messages. All of its status can be retrieved via D-Bus, and * changes to its status are notified through D-Bus signals. * + * The D-Bus APIs are ideally suited for constructing hands-free + * applications using high-level languages, such as Python, C#, or even + * Perl. As a lower level and much more complicated alternative, one + * may use the libhfp C++ APIs. + * * The D-Bus APIs described in this document are relatively complete. * The hfconsole application is implemented entirely in Python, and uses * dbus-python to access D-Bus APIs described in this document. It does @@ -41,9 +46,29 @@ * Python bindings. The APIs described here, and PyGTK, are the only * dependencies of hfconsole in order for it to do its job. * + * @section features HFPD Features + * + * - Supports device scanning, connection, disconnection, and automatic + * reconnection + * - Supports multiple concurrently connected audio gateway devices + * - Resilient to loss of Bluetooth service + * - Supports the ALSA and OSS audio hardware interfaces + * - Supports audio system test modes + * - Supports microphone input cleanup, including echo cancellation and + * noise reduction. + * - Supports simple recording and playback of stored audio files, e.g. + * for recording calls and playing ring tones. + * * @section access D-Bus Access * - * The hfpd process acquires the D-Bus unique name @b @c net.sf.nohands.hfpd . + * A D-Bus client wishing to make use of HFPD must be able to connect to + * D-Bus, and send and receive messages. The simplest way to do this is to + * choose an appropriate D-Bus binding for your language or toolkit. An + * + * updated list of bindings can be found connected to the + * D-Bus home page. + * + * The HFPD process acquires the D-Bus unique name @b @c net.sf.nohands.hfpd . * * The install target of the HFP for Linux Makefiles will install a * D-Bus service description file for HFPD. This allows dbus-daemon to @@ -57,18 +82,91 @@ * - @b @c /net/sf/nohands/hfpd , with interface net.sf.nohands.hfpd.HandsFree * - @b @c /net/sf/nohands/hfpd/soundio , with interface net.sf.nohands.hfpd.SoundIo * + * For each known audio gateway device, an object with interface + * net.sf.nohands.hfpd.AudioGateway will be instantiated. A new object + * of this type can be instantiated for an audio gateway device with a + * specific Bluetooth address using net.sf.nohands.hfpd.HandsFree.AddDevice(), + * and the paths of all such objects of this type are enumerated in + * net.sf.nohands.hfpd.HandsFree.AudioGateways. + * * All interfaces provided by HFPD are introspectable and should be * usable with most any language binding. * * @section property D-Bus Properties * - * HFPD D-Bus objects make extensive use of the standard D-Bus property - * interface, @c org.freedesktop.DBus.Properties. A number of D-Bus - * language bindings skimp on properties and do not provide access to - * properties in the most transparent possible way. Deficient language - * bindings include the dbus-python binding for Python. Depending - * on the language used, a D-Bus client application of HFPD may need to - * take extra measures to access properties. + * HFPD D-Bus objects make extensive use of the standard D-Bus properties + * interface, @c org.freedesktop.DBus.Properties. Ideally, one would + * expect a D-Bus language binding for an object-oriented language to + * expose properties as simple data members of the proxy objects. + * For example, in Python, the following would make a lot of sense to + * set the net.sf.nohands.hfpd.HandsFree.SecMode property on an HFPD + * instance: + * + * @code + * hfpd = dbus.Interface( + * dbus.get_object('net.sf.nohands.hfpd', + * '/net/sf/nohands/hfpd'), + * dbus_interface = 'net.sf.nohands.hfpd.HandsFree') + * hfpd.SecMode = 2 + * @endcode + * + * Unfortunately, a number of D-Bus language bindings, including + * dbus-python, skimp on properties and do not provide access to + * properties in the most transparent possible way. Depending on the + * language and bindings package used, a D-Bus client application of HFPD + * may need to take extra measures to access properties, often manually + * invoking @c org.freedesktop.DBus.Properties.Get and + * @c org.freedesktop.DBus.Properties.Set . For example, the above must + * instead be implemented as: + * + * @code + * hfpd = dbus.Interface( + * dbus.get_object('net.sf.nohands.hfpd', + * '/net/sf/nohands/hfpd'), + * dbus_interface = 'net.sf.nohands.hfpd.HandsFree') + * hfpdprop = dbus.Interface( + * dbus.get_object('net.sf.nohands.hfpd', + * '/net/sf/nohands/hfpd'), + * dbus_interface = 'org.freedesktop.DBus.Properties') + * hfpdprop.Set('net.sf.nohands.hfpd.HandsFree', 'SecMode', 2) + * @endcode + * + * For more information on the standard D-Bus properties interface, + * consult the + * + * D-Bus specification. + * + * @section clients D-Bus Client Guide + * + * The purpose of an HFPD D-Bus client is to implement the very high-level + * logic of managing audio gateway devices and voice connections, and of + * course, presenting status information to the user. It is possible to + * create a complete D-Bus client for HFPD that is very simple. Such a + * program might implement the following: + * - Keep a private configuration file, and use it to save the Bluetooth + * address of at least one audio gateway device that it is bound to. + * - Connect to HFPD using D-Bus, and claim the device(s) remembered + * in its configuration file using net.sf.nohands.hfpd.HandsFree.AddDevice(). + * - For each claimed device: + * - Set the net.sf.nohands.hfpd.AudioGateway.AutoReconnect property + * to @c true. + * - Register to receive the + * net.sf.nohands.hfpd.AudioGateway.VoiceStateChanged signal, and use + * the signal handler to start streaming audio to and from the audio + * gateway device, using + * net.sf.nohands.hfpd.SoundIo.AudioGatewayStart(), or failing that, + * close the audio connection with + * net.sf.nohands.hfpd.AudioGateway.CloseVoice(). + * - Register to receive the + * net.sf.nohands.hfpd.AudioGateway.StateChanged and + * net.sf.nohands.hfpd.AudioGateway.CallStateChanged signals, and + * use them to display simple status for the audio gateway. + * + * It is also possible to create a D-Bus client that does not claim any + * devices. Such a client might maintain a status display, and either + * depend on another client to claim and manage audio gateway devices, or + * depend on HFPD's list of permanently known audio gateway devices to + * permit incoming connections. */ namespace net.sf.nohands.hfpd { @@ -1910,7 +2008,8 @@ namespace net.sf.nohands.hfpd { * - Reject the call with HangUp(). * - Report User Determined User Busy with CallDropHeldUdub(). */ - public signal Ring(string caller_id, string caller_name); + public signal Ring(out string caller_id, + out string caller_name); /** * @brief Notification of miscellaneous audio gateway @@ -1935,8 +2034,8 @@ namespace net.sf.nohands.hfpd { * - @c "Voice Mail" 0 = no voice mail, 1 = voice mail, * nonstandard and supported by some Motorola phones */ - public signal IndicatorChanged(string indicator_name, - int32 value); + public signal IndicatorChanged(out string indicator_name, + out int32 value); /** * @brief Bluetooth name resolution complete notification @@ -1950,6 +2049,6 @@ namespace net.sf.nohands.hfpd { * @param[out] name Bluetooth name read from the audio * gateway device. */ - public signal NameResolved(string name); + public signal NameResolved(out string name); } } diff --git a/include/libhfp/bt.h b/include/libhfp/bt.h index 102323a..4a46e2e 100644 --- a/include/libhfp/bt.h +++ b/include/libhfp/bt.h @@ -357,25 +357,6 @@ public: bool SdpRecordRegister(sdp_record_t *recp); void SdpRecordUnregister(sdp_record_t *recp); - /** - * @brief Query the HCI currently used by the Bluetooth system - * - * The HCI object allows a number of special functions to be - * used, including querying the local address, the device class, - * and the SCO MTU. - * - * The Bluetooth subsystem will only actively attach to @b one - * HCI. In theory it should be possible to attach to multiple - * HCIs, but there are a few minor reasons that we don't: - * - We want to notice collisions with other SCO listeners. - * Unfortunately, the kernel interfaces only return EADDRINUSE - * when we attempt to bind a SCO socket to a specific local bdaddr. - * - Any registered SDP records that include RFCOMM channels would - * need to have the services listen on the same channels consistently - * across HCIs. For now, we only do this on one HCI. - */ - BtHci *GetHci(void) const { return m_hci; } - /** * @brief Notification that the Bluetooth system has stopped * or restarted asynchronously @@ -455,6 +436,28 @@ public: */ ~BtHub(); + /** + * @brief Query the HCI currently used by the Bluetooth system + * + * The HCI object allows a number of special functions to be + * used, including querying the local address, the device class, + * and the SCO MTU. + * + * @return A pointer to the active BtHci object, or @c 0 if the + * Bluetooth service is stopped and an HCI is unavailable. + * + * The libhfp Bluetooth subsystem will only actively attach to + * @b one HCI. In theory it should be possible to attach to multiple + * HCIs, but there are some small reasons that it does not: + * - We want to notice collisions with other SCO listeners. + * Unfortunately, the kernel interfaces only return EADDRINUSE + * when we attempt to bind a SCO socket to a specific local bdaddr. + * - Any registered SDP records that include RFCOMM channels would + * need to have the services listen on the same channels consistently + * across HCIs. For now, we only do this on one HCI. + */ + BtHci *GetHci(void) const { return m_hci; } + /** * @brief Default factory method for BtDevice objects */ @@ -873,13 +876,50 @@ public: */ bdaddr_t const &GetAddr(void) const { return m_bdaddr; } + /** + * @brief Submit an HCI task to be executed + */ int Queue(HciTask *in_task); + + /** + * @brief Cancel a pending HCI task + */ void Cancel(HciTask *taskp); + /** + * @brief Query the configured SCO MTU of the HCI + */ int GetScoMtu(uint16_t &mtu, uint16_t &pkts); + + /** + * @brief Set the SCO MTU of the HCI + * + * @note The kernel BlueZ components require superuser access + * in order to execute this command. + */ int SetScoMtu(uint16_t mtu, uint16_t pkts); + /** + * @brief Query the configured SCO voice setting of the HCI + * + * @param[out] vs On success, a bit field value containing the + * voice setting of the HCI is stored in this parameter. + * + * @retval 0 Success. + * @retval <0 Failure. The returned value is a negative @em errno + * value, e.g. -ESHUTDOWN. + * + * @sa Bluetooth specification version 2.1, volume 2, section 6.12 + * for more information on the format of @em vs. + */ int GetScoVoiceSetting(uint16_t &vs); + + /** + * @brief Set the SCO voice setting of the HCI + * + * @note The kernel BlueZ components require superuser access + * in order to execute this command. + */ int SetScoVoiceSetting(uint16_t vs); bool GetDeviceClassLocal(uint32_t &devclass); diff --git a/include/libhfp/soundio.h b/include/libhfp/soundio.h index 08c594c..b3b26da 100644 --- a/include/libhfp/soundio.h +++ b/include/libhfp/soundio.h @@ -520,10 +520,12 @@ public: }; -/* - * SoundIoDeviceList is a utility class used to communicate a list of - * detected sound card names and descriptions associated with each - * driver. +/** + * @brief Utility class used to communicate a list of detected sound + * card names and descriptions associated with each driver. + * + * An instance of this class is returned by SoundIoManager::GetDriverInfo() + * to describe local sound card devices discovered during probing. */ class SoundIoDeviceList { @@ -540,9 +542,31 @@ public: bool Add(const char *name, const char *desc); + /** + * @brief Move the internal cursor to the beginning of the list + * + * @retval true List is nonempty + * @retval false List is empty + */ bool First(void) { m_cursor = m_first; return m_cursor != 0; } + + /** + * @brief Move the internal cursor to the next element of the list + * + * @retval true End of list has not been reached + * @retval false End of list has been reached + */ bool Next(void) { m_cursor = m_cursor->m_next; return m_cursor != 0; } + + /** + * @brief Retrieve the name of the current list entry + */ const char *GetName(void) const { return m_cursor->m_name; } + + /** + * @brief Retrieve the human-readable description of the + * current list entry + */ const char *GetDesc(void) const { return m_cursor->m_desc; } }; @@ -1286,7 +1310,7 @@ public: /** * @brief Set the desired window size on output buffers * - * The method provides the client some level of control over the + * This method provides the client some level of control over the * output window size, i.e. the limit of the fill level of output * buffers above and beyond the minimum. This value has two * consequences: @@ -1335,7 +1359,8 @@ public: * The primary endpoint can be configured by driver name and option * strings. A default driver with default options will be used if no * options are provided. Clients need not have any knowledge of available - * drivers. + * drivers, but can enumerate them, as well as probe for available local + * sound card devices, using GetDriverInfo(). * * The primary endpoint is automatically opened and closed, and * has its format set to that of the secondary endpoint when the stream @@ -1347,10 +1372,10 @@ public: * loopback mode. Loopback mode is useful for qualitatively evaluating * latency. * - * This object also supports a streaming mute mode. This can be enabled at - * any time using SetMute(). When enabled, a clocked secondary endpoint - * will continue streaming while the primary endpoint is swapped out and - * closed. + * This object also supports software mute mode. Software mute can be + * enabled at any time using SetMute(). When enabled, both endpoints will + * continue streaming, but the audio data in one or both directions will + * be replaced with silence. */ class SoundIoManager { private: @@ -1469,7 +1494,7 @@ public: /** * @brief Temporarily disable and close the primary endpoint * - * Hard streaming mute mode allows the secondary endpoint to contine + * Hard streaming mute mode allows the secondary endpoint to continue * streaming while the primary is removed. The primary endpoint * may also be optionally closed. * @@ -1701,7 +1726,7 @@ public: /** * @brief Set the desired packet size for the primary endpoint * - * The method provides the client some level of control over the + * This method provides the client some level of control over the * packet size of the primary endpoint, i.e. the interrupt period * length. This value has two consequences: * - If it is too small, the number of hardware interrupts -- cgit v1.2.1