summaryrefslogtreecommitdiff
path: root/pjmedia
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-12-26 00:11:48 +0000
committerBenny Prijono <bennylp@teluu.com>2006-12-26 00:11:48 +0000
commit2fe9c7e503a9599ed0361e10bb6ba1c4bf311e4c (patch)
tree2c9692b2e847917e2ad7e6a364829943b1623ed0 /pjmedia
parent2c57eaea78b397d120cfe359ff5d8026dae17f60 (diff)
Added DTMF callback support all the way to PJSUA API (ticket #48)
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@863 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r--pjmedia/include/pjmedia/session.h23
-rw-r--r--pjmedia/include/pjmedia/stream.h21
-rw-r--r--pjmedia/src/pjmedia/session.c17
-rw-r--r--pjmedia/src/pjmedia/stream.c65
4 files changed, 115 insertions, 11 deletions
diff --git a/pjmedia/include/pjmedia/session.h b/pjmedia/include/pjmedia/session.h
index ad490669..b76e4de4 100644
--- a/pjmedia/include/pjmedia/session.h
+++ b/pjmedia/include/pjmedia/session.h
@@ -321,6 +321,29 @@ PJ_DECL(pj_status_t) pjmedia_session_get_dtmf( pjmedia_session *session,
unsigned *size );
/**
+ * Set callback to be called upon receiving DTMF digits. If callback is
+ * registered, the stream will not buffer incoming DTMF but rather call
+ * the callback as soon as DTMF digit is received completely.
+ *
+ * @param session The media session.
+ * @param index The stream index.
+ * @param cb Callback to be called upon receiving DTMF digits.
+ * The DTMF digits will be given to the callback as
+ * ASCII digits.
+ * @param user_data User data to be returned back when the callback
+ * is called.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_session_set_dtmf_callback(pjmedia_session *session,
+ unsigned index,
+ void (*cb)(pjmedia_stream*,
+ void *user_data,
+ int digit),
+ void *user_data);
+
+/**
* Destroy media session.
*
* @param session The media session.
diff --git a/pjmedia/include/pjmedia/stream.h b/pjmedia/include/pjmedia/stream.h
index 7a02b72a..2f862f34 100644
--- a/pjmedia/include/pjmedia/stream.h
+++ b/pjmedia/include/pjmedia/stream.h
@@ -277,6 +277,27 @@ PJ_DECL(pj_status_t) pjmedia_stream_get_dtmf( pjmedia_stream *stream,
/**
+ * Set callback to be called upon receiving DTMF digits. If callback is
+ * registered, the stream will not buffer incoming DTMF but rather call
+ * the callback as soon as DTMF digit is received completely.
+ *
+ * @param stream The media stream.
+ * @param cb Callback to be called upon receiving DTMF digits.
+ * The DTMF digits will be given to the callback as
+ * ASCII digits.
+ * @param user_data User data to be returned back when the callback
+ * is called.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_stream_set_dtmf_callback(pjmedia_stream *stream,
+ void (*cb)(pjmedia_stream*,
+ void *user_data,
+ int digit),
+ void *user_data);
+
+/**
* @}
*/
diff --git a/pjmedia/src/pjmedia/session.c b/pjmedia/src/pjmedia/session.c
index 870576de..8d7aa885 100644
--- a/pjmedia/src/pjmedia/session.c
+++ b/pjmedia/src/pjmedia/session.c
@@ -733,3 +733,20 @@ PJ_DEF(pj_status_t) pjmedia_session_get_dtmf( pjmedia_session *session,
return pjmedia_stream_get_dtmf(session->stream[index], ascii_digits,
size);
}
+
+/*
+ * Install DTMF callback.
+ */
+PJ_DEF(pj_status_t)
+pjmedia_session_set_dtmf_callback(pjmedia_session *session,
+ unsigned index,
+ void (*cb)(pjmedia_stream*,
+ void *user_data,
+ int digit),
+ void *user_data)
+{
+ PJ_ASSERT_RETURN(session && index < session->stream_cnt, PJ_EINVAL);
+ return pjmedia_stream_set_dtmf_callback(session->stream[index], cb,
+ user_data);
+}
+
diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c
index 905b98ff..0c67a15c 100644
--- a/pjmedia/src/pjmedia/stream.c
+++ b/pjmedia/src/pjmedia/stream.c
@@ -113,6 +113,10 @@ struct pjmedia_stream
pj_uint32_t last_dtmf_dur; /**< Start ts for cur digit. */
unsigned rx_dtmf_count; /**< # of digits in dtmf rx buf.*/
char rx_dtmf_buf[32];/**< Incoming DTMF buffer. */
+
+ /* DTMF callback */
+ void (*dtmf_cb)(pjmedia_stream*, void*, int);
+ void *dtmf_cb_user_data;
};
@@ -379,10 +383,11 @@ static void create_dtmf_payload(pjmedia_stream *stream,
stream->tx_dtmf_buf[0].start_ts = cur_ts;
pj_mutex_unlock(stream->jb_mutex);
- if (stream->tx_dtmf_count)
+ if (stream->tx_dtmf_count) {
PJ_LOG(5,(stream->port.info.name.ptr,
"Sending DTMF digit id %c",
digitmap[stream->tx_dtmf_buf[0].event]));
+ }
} else if (duration == 0) {
PJ_LOG(5,(stream->port.info.name.ptr, "Sending DTMF digit id %c",
@@ -663,18 +668,29 @@ static void handle_incoming_dtmf( pjmedia_stream *stream,
stream->last_dtmf = event->event;
stream->last_dtmf_dur = pj_ntohs(event->duration);
- /* By convention, we use jitter buffer's mutex to access shared
- * DTMF variables.
+ /* If DTMF callback is installed, call the callback, otherwise keep
+ * the DTMF digits in the buffer.
*/
- pj_mutex_lock(stream->jb_mutex);
- if (stream->rx_dtmf_count >= PJ_ARRAY_SIZE(stream->rx_dtmf_buf)) {
- /* DTMF digits overflow. Discard the oldest digit. */
- pj_array_erase(stream->rx_dtmf_buf, sizeof(stream->rx_dtmf_buf[0]),
- stream->rx_dtmf_count, 0);
- --stream->rx_dtmf_count;
+ if (stream->dtmf_cb) {
+
+ stream->dtmf_cb(stream, stream->dtmf_cb_user_data,
+ digitmap[event->event]);
+
+ } else {
+ /* By convention, we use jitter buffer's mutex to access shared
+ * DTMF variables.
+ */
+ pj_mutex_lock(stream->jb_mutex);
+ if (stream->rx_dtmf_count >= PJ_ARRAY_SIZE(stream->rx_dtmf_buf)) {
+ /* DTMF digits overflow. Discard the oldest digit. */
+ pj_array_erase(stream->rx_dtmf_buf,
+ sizeof(stream->rx_dtmf_buf[0]),
+ stream->rx_dtmf_count, 0);
+ --stream->rx_dtmf_count;
+ }
+ stream->rx_dtmf_buf[stream->rx_dtmf_count++] = digitmap[event->event];
+ pj_mutex_unlock(stream->jb_mutex);
}
- stream->rx_dtmf_buf[stream->rx_dtmf_count++] = digitmap[event->event];
- pj_mutex_unlock(stream->jb_mutex);
}
@@ -1368,3 +1384,30 @@ PJ_DEF(pj_status_t) pjmedia_stream_get_dtmf( pjmedia_stream *stream,
return PJ_SUCCESS;
}
+
+
+/*
+ * Set callback to be called upon receiving DTMF digits.
+ */
+PJ_DEF(pj_status_t)
+pjmedia_stream_set_dtmf_callback(pjmedia_stream *stream,
+ void (*cb)(pjmedia_stream*,
+ void *user_data,
+ int digit),
+ void *user_data)
+{
+ PJ_ASSERT_RETURN(stream, PJ_EINVAL);
+
+ /* By convention, we use jitter buffer's mutex to access DTMF
+ * digits resources.
+ */
+ pj_mutex_lock(stream->jb_mutex);
+
+ stream->dtmf_cb = cb;
+ stream->dtmf_cb_user_data = user_data;
+
+ pj_mutex_unlock(stream->jb_mutex);
+
+ return PJ_SUCCESS;
+}
+