[asterisk-scf-commits] asterisk-scf/integration/sip.git branch "telephone-events" created.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Tue Jul 5 17:06:14 CDT 2011
branch "telephone-events" has been created
at bd25df69bafa9d87b5c427a11422fc0c0c0fc5bd (commit)
- Log -----------------------------------------------------------------
commit bd25df69bafa9d87b5c427a11422fc0c0c0fc5bd
Author: Mark Michelson <mmichelson at digium.com>
Date: Tue Jul 5 17:06:06 2011 -0500
Add initial parsing of DTMF INFO requests.
diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 46ecafd..ff47c0e 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -22,6 +22,7 @@
#include "SipStateReplicator.h"
#include <IceUtil/UUID.h>
+#include <boost/lexical_cast.hpp>
#include <AsteriskSCF/Core/Endpoint/EndpointIf.h>
#include <AsteriskSCF/Core/Routing/RoutingIf.h>
@@ -911,9 +912,84 @@ void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdat
enqueueSessionWork(new HandleReferOperation(inv, tsx, tdata, replaces_param, to_tag_param, from_tag_param, target, session, mSessionRouter, mModule.id), inv);
}
+bool PJSipSessionModule::isDTMF(pjsip_rx_data *rdata)
+{
+ // We should determine how to handle matters based on the "Info-Package" header,
+ // but DTMF via INFO existed long before the Info-Package RFC was published.
+ // An official document defining DTMF over INFO is still in the draft stage as
+ // of July 2011. We will thus use the Info-Package or the Content-Type header
+ // to determine if this is DTMF.
+
+ pj_str_t str_info_pkg;
+ pj_cstr(&str_info_pkg, "Info-Package");
+ pjsip_generic_string_hdr *info_package =
+ static_cast<pjsip_generic_string_hdr *>(pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_info_pkg, NULL));
+
+ pj_str_t dtmf;
+ pj_cstr(&dtmf, "dtmf");
+ if (info_package && !pj_strcmp(&info_package->hvalue, &dtmf))
+ {
+ return true;
+ }
+
+ //No biggie. I just said that not many are actually going to use Info-Package.
+ //Check if the content-type is "application/dtmf-relay"
+ pj_str_t application;
+ pj_str_t dtmf_relay;
+ pj_cstr(&application, "application");
+ pj_cstr(&dtmf_relay, "dtmf-relay");
+ if (!pj_strcmp(&rdata->msg_info.ctype->media.type, &application) &&
+ !pj_strcmp(&rdata->msg_info.ctype->media.subtype, &dtmf_relay))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+char PJSipSessionModule::getDTMFInfoSignal(pjsip_msg_body *body)
+{
+ char *data = static_cast<char *>(body->data);
+ std::string dataStr(data, body->len);
+
+ size_t signalPos = dataStr.find("Signal= ");
+ if (signalPos == std::string::npos)
+ {
+ //XXX Uh...
+ }
+
+ return dataStr.at(signalPos + sizeof("Signal= "));
+}
+
+int PJSipSessionModule::getDTMFInfoDuration(pjsip_msg_body *body)
+{
+ char *data = static_cast<char *>(body->data);
+ std::string dataStr(data, body->len);
+
+ size_t durationPos = dataStr.find("Duration= ");
+ if (durationPos == std::string::npos)
+ {
+ //XXX Uh...
+ }
+
+ std::string duration(dataStr.substr(durationPos + sizeof("Duration= ")));
+ return boost::lexical_cast<int>(duration);
+}
+
void PJSipSessionModule::handleInfo(pjsip_inv_session *inv, pjsip_rx_data *rdata)
{
- //STUB
+ // The only INFO package we handle for now is "dtmf". We need to verify that
+ // what we have received is actually DTMF and not some other INFO package.
+
+ if (!isDTMF(rdata))
+ {
+ return;
+ }
+
+ //It's DTMF! Grab the info we need! HA THAT WAS A PUN YOU JERK!
+ char dtmf = getDTMFInfoSignal(rdata->msg_info.msg->body);
+ int duration = getDTMFInfoDuration(rdata->msg_info.msg->body);
+
return;
}
diff --git a/src/PJSipSessionModule.h b/src/PJSipSessionModule.h
index 5b08405..6337e57 100644
--- a/src/PJSipSessionModule.h
+++ b/src/PJSipSessionModule.h
@@ -122,6 +122,9 @@ private:
void handleInviteResponse(pjsip_inv_session *inv, pjsip_rx_data *rdata, pjsip_dialog *dlg);
void handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdata);
void handleInfo(pjsip_inv_session *inv, pjsip_rx_data *rdata);
+ bool isDTMF(pjsip_rx_data *rdata);
+ char getDTMFInfoSignal(pjsip_msg_body *body);
+ int getDTMFInfoDuration(pjsip_msg_body *body);
pjsip_inv_callback mInvCallback;
pjsip_ua_init_param mUaParam;
const std::string mName;
commit 5c5e10ab63ed39300e37d63cac1f8154956db1a5
Author: Mark Michelson <mmichelson at digium.com>
Date: Tue Jul 5 16:07:26 2011 -0500
Initial code to be able to detect an incoming INFO.
diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index b6719d5..46ecafd 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -911,6 +911,12 @@ void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdat
enqueueSessionWork(new HandleReferOperation(inv, tsx, tdata, replaces_param, to_tag_param, from_tag_param, target, session, mSessionRouter, mModule.id), inv);
}
+void PJSipSessionModule::handleInfo(pjsip_inv_session *inv, pjsip_rx_data *rdata)
+{
+ //STUB
+ return;
+}
+
pj_bool_t PJSipSessionModule::on_rx_request(pjsip_rx_data *rdata)
{
pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
@@ -929,12 +935,20 @@ pj_bool_t PJSipSessionModule::on_rx_request(pjsip_rx_data *rdata)
}
break;
case PJSIP_OTHER_METHOD:
+ pj_str_t info;
+ pj_cstr(&info, "INFO");
if (dlg && !pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, pjsip_get_refer_method()))
{
// We are essentially stopping the pjsip code from sending a 500 here, but this will actually be handled
// within the transaction code
break;
}
+ //PJSIP has no knowledge of the INFO method, so we do a straight string comparison dot dot dot
+ else if (dlg && !pj_strcmp(&rdata->msg_info.msg->line.req.method.name, &info))
+ {
+ // Like with REFER, we actually handle this in the transaction code.
+ break;
+ }
default:
pjsip_endpt_respond_stateless(mEndpoint, rdata, 405, NULL, NULL, NULL);
break;
@@ -1322,6 +1336,14 @@ void PJSipSessionModule::invOnTsxStateChanged(pjsip_inv_session *inv, pjsip_tran
{
handleRefer(inv, e->body.tsx_state.src.rdata);
}
+
+ pj_str_t info;
+ pj_cstr(&info, "INFO");
+ if (tsx->role == PJSIP_ROLE_UAS && tsx->state == PJSIP_TSX_STATE_TRYING &&
+ !pj_strcmp(&tsx->method.name, &info))
+ {
+ handleInfo(inv, e->body.tsx_state.src.rdata);
+ }
//This will be our key point for updating transaction state. This function will not be called until after a module
//has registered itself as the transaction user, so this won't be called on the initial INVITE we receive.
//
diff --git a/src/PJSipSessionModule.h b/src/PJSipSessionModule.h
index 7b4cd30..5b08405 100644
--- a/src/PJSipSessionModule.h
+++ b/src/PJSipSessionModule.h
@@ -121,6 +121,7 @@ private:
void handleNewInvite(pjsip_rx_data *rdata);
void handleInviteResponse(pjsip_inv_session *inv, pjsip_rx_data *rdata, pjsip_dialog *dlg);
void handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdata);
+ void handleInfo(pjsip_inv_session *inv, pjsip_rx_data *rdata);
pjsip_inv_callback mInvCallback;
pjsip_ua_init_param mUaParam;
const std::string mName;
-----------------------------------------------------------------------
--
asterisk-scf/integration/sip.git
More information about the asterisk-scf-commits
mailing list