summaryrefslogtreecommitdiff
path: root/include/libhfp
diff options
context:
space:
mode:
authorsamr7 <samr7@126591fb-c623-4b62-a76d-97a8e4f34109>2008-10-20 09:20:17 +0000
committersamr7 <samr7@126591fb-c623-4b62-a76d-97a8e4f34109>2008-10-20 09:20:17 +0000
commit8cbbf11def53d4dbfafc2652a798d2ba5de25702 (patch)
treec411663beac6da405d78f88e09a90c101e0c56fc /include/libhfp
parent91ce492958db5a000a39a26c47aacee6b198308e (diff)
downloadnohands-8cbbf11def53d4dbfafc2652a798d2ba5de25702.tar.gz
Add device probing to the SoundIoManager interface and net.sf.nohands.SoundIo
Add support for completion notification of HF->AG commands. Make D-Bus commands complete asynchronously and return errors from the AG. Improve completeness of supported HF->AG commands. Add complete parsers for CHLD modes and CIND/CCWA phone numbers. Add incoming call notification to hfconsole. Fix a handful of serious bugs, and probably add just as many back in. git-svn-id: http://nohands.svn.sourceforge.net/svnroot/nohands/trunk@7 126591fb-c623-4b62-a76d-97a8e4f34109
Diffstat (limited to 'include/libhfp')
-rw-r--r--include/libhfp/hfp.h237
-rw-r--r--include/libhfp/soundio-buf.h4
-rw-r--r--include/libhfp/soundio.h45
3 files changed, 238 insertions, 48 deletions
diff --git a/include/libhfp/hfp.h b/include/libhfp/hfp.h
index 0d65964..c7b5288 100644
--- a/include/libhfp/hfp.h
+++ b/include/libhfp/hfp.h
@@ -383,9 +383,74 @@ public:
}
};
+class GsmClipPhoneNumber {
+ void *operator new(size_t nb, size_t extra);
+ size_t extra;
+
+ static GsmClipPhoneNumber *Create(const char *src);
+
+public:
+ const char *number;
+ int type;
+ const char *subaddr;
+ int satype;
+ const char *alpha;
+ int cli_validity;
+
+ void operator delete(void *mem);
+ static GsmClipPhoneNumber *Parse(const char *buffer);
+ static GsmClipPhoneNumber *ParseCcwa(const char *buffer);
+ bool Compare(const GsmClipPhoneNumber *clip) const;
+ GsmClipPhoneNumber *Duplicate(void) const;
+};
+
class AtCommand;
/**
+ * @brief Audio Gateway Pending Command Object
+ * @ingroup hfp
+ *
+ * Some HfpSession methods control the connection state to the audio
+ * gateway. Others, such as HfpSession::CmdDial(), relay commands to
+ * the audio gateway device. All HfpSession methods are asynchronous,
+ * and for longer-running operations, the method will return either
+ * having started the operation, or having failed to start the
+ * operation for whatever reason.
+ *
+ * HfpSession methods that relay commands to the audio gateway,
+ * including HfpSession::CmdDial(), will return an HfpPendingCommand
+ * object. This object functions as a callback that is invoked when a
+ * reply is received from the audio gateway for the queued command.
+ *
+ * Every HfpPendingCommand object returned is guaranteed to have its
+ * registered callback invoked exactly once.
+ *
+ * The caller may also use the Cancel() method of the HfpPendingCommand
+ * object to cancel the command, although this may fail if the command
+ * has already been sent.
+ *
+ * The caller of the HfpSession method is entirely responsible for
+ * the lifecycle of the HfpPendingCommand object. If the caller is
+ * not interested in the result of the command, it should delete the
+ * HfpPendingCommand object. Likewise, it must also delete the
+ * HfpPendingCommand object after receiving a callback, or after a
+ * successful call to the Cancel() method.
+ */
+class HfpPendingCommand
+ : public Callback<void, HfpPendingCommand*, bool, const char *> {
+public:
+ /**
+ * @brief Request that the command be canceled and not sent
+ *
+ * @retval true Command has been canceled and will not be sent.
+ * @retval false Command has already been sent or has already
+ * completed.
+ */
+ virtual bool Cancel(void) = 0;
+ virtual ~HfpPendingCommand();
+};
+
+/**
* @brief Session object for Hands-Free Profile
* @ingroup hfp
*
@@ -463,6 +528,7 @@ class AtCommand;
*/
class HfpSession : public RfcommSession, public SoundIoBufferBase {
friend class HfpService;
+ friend class AtCommand;
private:
enum {
@@ -474,7 +540,7 @@ private:
bool m_conn_autoreconnect;
ListItem m_autoreconnect_links;
- AtCommand *m_cmd_cur, *m_cmd_tail;
+ ListItem m_commands;
int m_brsf;
@@ -492,17 +558,28 @@ private:
void DeleteFirstCommand(void);
void AppendCommand(AtCommand *cmdp);
void StartCommand(void);
+ bool CancelCommand(AtCommand *cmdp);
void ResponseDefault(char *buf);
+ HfpPendingCommand *PendingCommand(AtCommand *cmdp);
friend class CindRCommand;
friend class AtdCommand;
friend class AtCommandClearCallSetup;
void UpdateIndicator(int inum, const char *ival);
- void UpdateCallSetup(int val, int ring = 0, const char *cli = 0,
+ void UpdateCallSetup(int val, int ring = 0,
+ GsmClipPhoneNumber *clip = 0,
int timeout_ms = 0);
friend class ChldTCommand;
+ void SetSupportedHoldRange(int start, int end);
void SetSupportedHoldModes(const char *hold_mode_list);
+ bool m_chld_0: 1,
+ m_chld_1: 1,
+ m_chld_1x: 1,
+ m_chld_2: 1,
+ m_chld_2x: 1,
+ m_chld_3: 1,
+ m_chld_4: 1;
friend class BrsfCommand;
void SetSupportedFeatures(int ag_features) { m_brsf = ag_features; };
@@ -540,8 +617,9 @@ private:
int m_state_signal;
int m_state_roam;
int m_state_battchg;
- enum { PHONENUM_MAX_LEN = 31 };
- char m_state_incomplete_cli[PHONENUM_MAX_LEN + 1];
+
+ enum { PHONENUM_MAX_LEN = 31, };
+ GsmClipPhoneNumber *m_state_incomplete_clip;
static bool ValidPhoneNumChar(char c);
static bool ValidPhoneNum(const char *ph);
@@ -885,8 +963,8 @@ public:
* @return String pointer to the remote identity of the last
* incomplete call, or NULL if the identity was not known.
*/
- const char *WaitingCallIdentity(void) const {
- return m_state_incomplete_cli[0] ? m_state_incomplete_cli : 0;
+ const GsmClipPhoneNumber *WaitingCallIdentity(void) const {
+ return m_state_incomplete_clip;
}
@@ -1056,6 +1134,15 @@ public:
{ return (m_brsf & 256) ? true : false; }
bool FeatureIndCallSetup(void) const
{ return (m_inum_callsetup != 0); }
+
+ bool FeatureDropHeldUdub(void) const { return m_chld_0; }
+ bool FeatureSwapDropActive(void) const { return m_chld_1; }
+ bool FeatureDropActive(void) const { return m_chld_1x; }
+ bool FeatureSwapHoldActive(void) const { return m_chld_2; }
+ bool FeaturePrivateConsult(void) const { return m_chld_2x; }
+ bool FeatureLink(void) const { return m_chld_3; }
+ bool FeatureTransfer(void) const { return m_chld_4; }
+
/**
* @brief Query whether the attached device supports signal strength
* indication
@@ -1113,39 +1200,43 @@ public:
* @retval true At least one command is pending
* @retval false The command queue is empty
*/
- bool IsCommandPending(void) const { return m_cmd_cur != NULL; }
+ bool IsCommandPending(void) const { return !m_commands.Empty(); }
- bool CmdSetVoiceRecog(bool enabled);
- bool CmdSetEcnr(bool enabled);
+ HfpPendingCommand *CmdSetVoiceRecog(bool enabled);
+ HfpPendingCommand *CmdSetEcnr(bool enabled);
/**
* @brief Request that the audio gateway answer the unanswered
* incoming call
*
- * @retval true Command was queued
- * @retval false Command was not queued, e,g. because the device
- * connection was lost.
+ * @return An HfpPendingCommand to receive a notification when
+ * the command completes, with the command status, or @c 0 if
+ * the command could not be queued, e.g. because the device
+ * connection was lost
*/
- bool CmdAnswer(void);
+ HfpPendingCommand *CmdAnswer(void);
/**
* @brief Request that the audio gateway hang up the active call
*
* @retval true Command was queued
- * @retval false Command was not queued, e.g. because the device
- * connection was lost.
+ * @return An HfpPendingCommand to receive a notification when
+ * the command completes, with the command status, or @c 0 if
+ * the command could not be queued, e.g. because the device
+ * connection was lost
*/
- bool CmdHangUp(void);
+ HfpPendingCommand *CmdHangUp(void);
/**
* @brief Request that the audio gateway place a new outgoing call
*
* @param[in] phnum Phone number to be dialed
- * @retval true Command was queued
- * @retval false Command was not queued, e.g. because the device
+ * @return An HfpPendingCommand to receive a notification when
+ * the command completes, with the command status, or @c 0 if
+ * the command could not be queued, e.g. because the device
* connection was lost or the phone number is too long
*/
- bool CmdDial(const char *phnum);
+ HfpPendingCommand *CmdDial(const char *phnum);
/**
* @brief Request that the audio gateway place a new outgoing call
@@ -1155,11 +1246,12 @@ public:
* gateway, and may have been dialed before the audio gateway was
* connected to the hands-free.
*
- * @retval true Command was queued
- * @retval false Command was not queued, e.g. because the device
- * connection was lost.
+ * @return An HfpPendingCommand to receive a notification when
+ * the command completes, with the command status, or @c 0 if
+ * the command could not be queued, e.g. because the device
+ * connection was lost
*/
- bool CmdRedial(void);
+ HfpPendingCommand *CmdRedial(void);
/**
* @brief Request that the audio gateway send a DTMF tone to the
@@ -1167,54 +1259,107 @@ public:
*
* @param code DTMF code to be sent. May be numeric, #, or *.
* @retval true Command was queued
- * @retval false Command was not queued, e.g. because the device
- * connection was lost.
+ * @return An HfpPendingCommand to receive a notification when
+ * the command completes, with the command status, or @c 0 if
+ * the command could not be queued, e.g. because the device
+ * connection was lost
*/
- bool CmdSendDtmf(char code);
+ HfpPendingCommand *CmdSendDtmf(char code);
/**
- * @brief Request that the audio gateway drop the held or waiting call
+ * @brief Request that the audio gateway drop the held call, or
+ * reject the waiting call as User Declared User Busy.
*
* @note This command may only be expected to succeed if the device
- * claims support for call rejection, i.e. FeatureRejectCall().
- * @retval true Command was queued
- * @retval false Command was not queued, e.g. because the device
- * connection was lost.
+ * claims support for dropping waiting calls,
+ * i.e. FeatureDropHeldUdub() returns true.
+ * @return An HfpPendingCommand to receive a notification when
+ * the command completes, with the command status, or @c 0 if
+ * the command could not be queued, e.g. because the device
+ * connection was lost
*/
- bool CmdCallDropWaiting(void);
+ HfpPendingCommand *CmdCallDropHeldUdub(void);
/**
* @brief Request that the audio gateway drop the active call
* and activate the held or waiting call
*
- * @retval true Command was queued
- * @retval false Command was not queued, e.g. because the device
- * connection was lost.
+ * @note This command may only be expected to succeed if the
+ * device supports active call drop-swapping, i.e.
+ * FeatureSwapDropActive() returns true.
+ * @return An HfpPendingCommand to receive a notification when
+ * the command completes, with the command status, or @c 0 if
+ * the command could not be queued, e.g. because the device
+ * connection was lost
*/
- bool CmdCallSwapDropActive(void);
+ HfpPendingCommand *CmdCallSwapDropActive(void);
+
+ /**
+ * @brief Drop a specific active call
+ *
+ * @note This command may only be expected to succeed if the
+ * device supports dropping of specific active calls, i.e.
+ * FeatureDropActive() returns true.
+ * @return An HfpPendingCommand to receive a notification when
+ * the command completes, with the command status, or @c 0 if
+ * the command could not be queued, e.g. because the device
+ * connection was lost
+ */
+ HfpPendingCommand *CmdCallDropActive(unsigned int actnum);
/**
* @brief Request that the audio gateway hold the active call
* and activate the held or waiting call
*
- * @retval true Command was queued
- * @retval false Command was not queued, e.g. because the device
- * connection was lost.
+ * @note This command may only be expected to succeed if the
+ * device supports active call hold-swapping, i.e.
+ * FeatureSwapHoldActive() returns true.
+ * @return An HfpPendingCommand to receive a notification when
+ * the command completes, with the command status, or @c 0 if
+ * the command could not be queued, e.g. because the device
+ * connection was lost
+ */
+ HfpPendingCommand *CmdCallSwapHoldActive(void);
+
+ /**
+ * @brief Request private consultation mode with a call
+ *
+ * @note This command may only be expected to succeed if the
+ * device supports private consultation mode, i.e.
+ * FeaturePrivateConsult() returns true.
+ * @return An HfpPendingCommand to receive a notification when
+ * the command completes, with the command status, or @c 0 if
+ * the command could not be queued, e.g. because the device
+ * connection was lost
*/
- bool CmdCallSwapHoldActive(void);
+ HfpPendingCommand *CmdCallPrivateConsult(unsigned int callnum);
/**
* @brief Request that the audio gateway create a three-way call
* using the active call and the held or waiting call
*
* @note This command may only be expected to succeed if the
- * device supports three-way calling, i.e.
- * FeatureThreeWayCalling() returns true.
- * @retval true Command was queued
- * @retval false Command was not queued, e.g. because the device
- * connection was lost.
+ * device supports call linking, i.e. FeatureLink() returns true.
+ * @return An HfpPendingCommand to receive a notification when
+ * the command completes, with the command status, or @c 0 if
+ * the command could not be queued, e.g. because the device
+ * connection was lost
*/
- bool CmdCallLink(void);
+ HfpPendingCommand *CmdCallLink(void);
+
+ /**
+ * @brief Request that the audio gateway link the two calls
+ * and disconnect the subscriber from both calls.
+ *
+ * @note This command may only be expected to succeed if the
+ * device supports explicit call transfer,
+ * i.e. FeatureTransfer() returns true.
+ * @return An HfpPendingCommand to receive a notification when
+ * the command completes, with the command status, or @c 0 if
+ * the command could not be queued, e.g. because the device
+ * connection was lost
+ */
+ HfpPendingCommand *CmdCallTransfer(void);
/*
diff --git a/include/libhfp/soundio-buf.h b/include/libhfp/soundio-buf.h
index 669514f..e5bc5d5 100644
--- a/include/libhfp/soundio-buf.h
+++ b/include/libhfp/soundio-buf.h
@@ -333,7 +333,9 @@ public:
SoundIoBufferBase(void)
: m_input(), m_output(), m_hw_outq(0), m_abort(false),
m_abort_to(0), m_async_state(0) {}
- virtual ~SoundIoBufferBase() {}
+ virtual ~SoundIoBufferBase() {
+ BufCancelAbort();
+ }
/* Override these with methods that fill the FIFOs */
virtual void SndPushInput(bool nonblock) = 0;
diff --git a/include/libhfp/soundio.h b/include/libhfp/soundio.h
index c7532c3..c349393 100644
--- a/include/libhfp/soundio.h
+++ b/include/libhfp/soundio.h
@@ -520,6 +520,33 @@ public:
};
+/*
+ * SoundIoDeviceList is a utility class used to communicate a list of
+ * detected sound card names and descriptions associated with each
+ * driver.
+ */
+
+class SoundIoDeviceList {
+ struct InfoNode {
+ const char *m_name;
+ const char *m_desc;
+ struct InfoNode *m_next;
+
+ } *m_first, *m_last, *m_cursor;
+
+public:
+ SoundIoDeviceList(void) : m_first(0), m_last(0), m_cursor(0) {}
+ ~SoundIoDeviceList();
+
+ bool Add(const char *name, const char *desc);
+
+ bool First(void) { m_cursor = m_first; return m_cursor != 0; }
+ bool Next(void) { m_cursor = m_cursor->m_next; return m_cursor != 0; }
+ const char *GetName(void) const { return m_cursor->m_name; }
+ const char *GetDesc(void) const { return m_cursor->m_desc; }
+};
+
+
/* Factories for various flavors of SoundIo */
/**
@@ -529,6 +556,9 @@ public:
extern SoundIo *SoundIoCreateOss(DispatchInterface *dip,
const char *driveropts);
+extern SoundIoDeviceList *SoundIoGetDeviceListOss(void);
+
+
/**
* @brief Construct a SoundIo object backed by an ALSA driver
* @ingroup soundio
@@ -569,6 +599,9 @@ extern SoundIo *SoundIoCreateOss(DispatchInterface *dip,
extern SoundIo *SoundIoCreateAlsa(DispatchInterface *dip,
const char *driveropts);
+extern SoundIoDeviceList *SoundIoGetDeviceListAlsa(void);
+
+
/**
* @brief Construct a SoundIo object backed by a fixed-size memory buffer
* @ingroup soundio
@@ -1376,11 +1409,21 @@ public:
* driver, or NULL if the name is not desired.
* @param desc Address of pointer to receive descriptive text
* about the driver, or NULL if descriptive text is not desired.
+ * @param devlist Address of pointer to receive the detected
+ * device list associated with the driver, or NULL of the
+ * detected device list is not desired.
+ *
+ * @note If @em devlist is specified, and the returned
+ * pointer value is 0, this indicates a failed enumeration.
+ * A successful enumeration will return an empty
+ * SoundIoDeviceList object rather than a null pointer.
*
* @retval true Driver info retrieved.
* @retval false Driver index is invalid.
*/
- bool GetDriverInfo(int index, const char **name, const char **desc);
+ static bool GetDriverInfo(int index, const char **name,
+ const char **desc,
+ SoundIoDeviceList **devlist);
/**
* @brief Set the audio driver parameters