aboutsummaryrefslogtreecommitdiffstats
path: root/channels/h323/ast_h323.cxx
diff options
context:
space:
mode:
authorpcadach <pcadach@f38db490-d61c-443f-a65b-d21fe96a405b>2006-09-28 10:41:38 +0000
committerpcadach <pcadach@f38db490-d61c-443f-a65b-d21fe96a405b>2006-09-28 10:41:38 +0000
commit4ac9afef329d9525cda5dd82a8af1e4af0b054bf (patch)
tree549d5d4dee7804215437b180a6be243074532c9b /channels/h323/ast_h323.cxx
parent732c0b576358d2e9fa5544274a73b23bdccf6476 (diff)
Handle HOLD/RETRIEVE notifications
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@43845 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/h323/ast_h323.cxx')
-rw-r--r--channels/h323/ast_h323.cxx103
1 files changed, 101 insertions, 2 deletions
diff --git a/channels/h323/ast_h323.cxx b/channels/h323/ast_h323.cxx
index be22ca64a..826be727b 100644
--- a/channels/h323/ast_h323.cxx
+++ b/channels/h323/ast_h323.cxx
@@ -40,6 +40,12 @@
#include <h323neg.h>
#include <mediafmt.h>
#include <lid.h>
+#ifdef H323_H450
+#include "h4501.h"
+#include "h4504.h"
+#include "h45011.h"
+#include "h450pdu.h"
+#endif
#ifdef __cplusplus
extern "C" {
@@ -528,10 +534,20 @@ MyH323Connection::MyH323Connection(MyH323EndPoint & ep, unsigned callReference,
unsigned options)
: H323Connection(ep, callReference, options)
{
+#ifdef H323_H450
+ /* Dispatcher will free out all registered handlers */
+ if (h450dispatcher)
+ delete h450dispatcher;
+ h450dispatcher = new H450xDispatcher(*this);
+ h4502handler = new H4502Handler(*this, *h450dispatcher);
+ h4504handler = new MyH4504Handler(*this, *h450dispatcher);
+ h4506handler = new H4506Handler(*this, *h450dispatcher);
+ h45011handler = new H45011Handler(*this, *h450dispatcher);
+#endif
cause = -1;
sessionId = 0;
bridging = FALSE;
- progressSetup = progressAlert = 0;
+ holdHandling = progressSetup = progressAlert = 0;
dtmfMode = 0;
dtmfCodec[0] = dtmfCodec[1] = (RTP_DataFrame::PayloadTypes)0;
redirect_reason = -1;
@@ -664,6 +680,7 @@ void MyH323Connection::SetCallOptions(void *o, BOOL isIncoming)
progressSetup = opts->progress_setup;
progressAlert = opts->progress_alert;
+ holdHandling = opts->holdHandling;
dtmfCodec[0] = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec[0];
dtmfCodec[1] = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec[1];
dtmfMode = opts->dtmfmode;
@@ -1641,6 +1658,48 @@ BOOL MyH323Connection::StartControlChannel(const H225_TransportAddress & h245Add
return TRUE;
}
+#ifdef H323_H450
+void MyH323Connection::OnReceivedLocalCallHold(int linkedId)
+{
+ if (on_hold)
+ on_hold(GetCallReference(), (const char *)GetCallToken(), 1);
+}
+
+void MyH323Connection::OnReceivedLocalCallRetrieve(int linkedId)
+{
+ if (on_hold)
+ on_hold(GetCallReference(), (const char *)GetCallToken(), 0);
+}
+#endif
+
+void MyH323Connection::MyHoldCall(BOOL isHold)
+{
+ if (((holdHandling & H323_HOLD_NOTIFY) != 0) || ((holdHandling & H323_HOLD_Q931ONLY) != 0)) {
+ PBYTEArray x ((const BYTE *)(isHold ? "\xF9" : "\xFA"), 1);
+ H323SignalPDU signal;
+ signal.BuildNotify(*this);
+ signal.GetQ931().SetIE((Q931::InformationElementCodes)39 /* Q931::NotifyIE */, x);
+ if (h323debug)
+ cout << "Sending " << (isHold ? "HOLD" : "RETRIEVE") << " notification: " << signal << endl;
+ if ((holdHandling & H323_HOLD_Q931ONLY) != 0) {
+ PBYTEArray rawData;
+ signal.GetQ931().RemoveIE(Q931::UserUserIE);
+ signal.GetQ931().Encode(rawData);
+ signallingChannel->WritePDU(rawData);
+ } else
+ WriteSignalPDU(signal);
+ }
+#ifdef H323_H450
+ if ((holdHandling & H323_HOLD_H450) != 0) {
+ if (isHold)
+ h4504handler->HoldCall(TRUE);
+ else if (IsLocalHold())
+ h4504handler->RetrieveCall();
+ }
+#endif
+}
+
+
/* MyH323_ExternalRTPChannel */
MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection,
const H323Capability & capability,
@@ -1722,6 +1781,32 @@ BOOL MyH323_ExternalRTPChannel::OnReceivedAckPDU(const H245_H2250LogicalChannelA
return FALSE;
}
+#ifdef H323_H450
+MyH4504Handler::MyH4504Handler(MyH323Connection &_conn, H450xDispatcher &_disp)
+ :H4504Handler(_conn, _disp)
+{
+ conn = &_conn;
+}
+
+void MyH4504Handler::OnReceivedLocalCallHold(int linkedId)
+{
+ if (conn) {
+ conn->Lock();
+ conn->OnReceivedLocalCallHold(linkedId);
+ conn->Unlock();
+ }
+}
+
+void MyH4504Handler::OnReceivedLocalCallRetrieve(int linkedId)
+{
+ if (conn) {
+ conn->Lock();
+ conn->OnReceivedLocalCallRetrieve(linkedId);
+ conn->Unlock();
+ }
+}
+#endif
+
/** IMPLEMENTATION OF C FUNCTIONS */
@@ -1780,7 +1865,8 @@ void h323_callback_register(setup_incoming_cb ifunc,
rfc2833_cb dtmffunc,
hangup_cb hangupfunc,
setcapabilities_cb capabilityfunc,
- setpeercapabilities_cb peercapabilityfunc)
+ setpeercapabilities_cb peercapabilityfunc,
+ onhold_cb holdfunc)
{
on_incoming_call = ifunc;
on_outgoing_call = sfunc;
@@ -1796,6 +1882,7 @@ void h323_callback_register(setup_incoming_cb ifunc,
on_hangup = hangupfunc;
on_setcapabilities = capabilityfunc;
on_setpeercapabilities = peercapabilityfunc;
+ on_hold = holdfunc;
}
/**
@@ -2097,6 +2184,18 @@ void h323_native_bridge(const char *token, const char *them, char *capability)
}
+int h323_hold_call(const char *token, int is_hold)
+{
+ MyH323Connection *conn = (MyH323Connection *)endPoint->FindConnectionWithLock(token);
+ if (!conn) {
+ cout << "ERROR: No connection found, this is bad" << endl;
+ return -1;
+ }
+ conn->MyHoldCall((BOOL)is_hold);
+ conn->Unlock();
+ return 0;
+}
+
#undef cout
#undef endl
void h323_end_process(void)