diff options
author | pcadach <pcadach@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-09-28 10:41:38 +0000 |
---|---|---|
committer | pcadach <pcadach@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-09-28 10:41:38 +0000 |
commit | 4ac9afef329d9525cda5dd82a8af1e4af0b054bf (patch) | |
tree | 549d5d4dee7804215437b180a6be243074532c9b /channels/h323 | |
parent | 732c0b576358d2e9fa5544274a73b23bdccf6476 (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')
-rw-r--r-- | channels/h323/ast_h323.cxx | 103 | ||||
-rw-r--r-- | channels/h323/ast_h323.h | 23 | ||||
-rw-r--r-- | channels/h323/chan_h323.h | 12 |
3 files changed, 135 insertions, 3 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) diff --git a/channels/h323/ast_h323.h b/channels/h323/ast_h323.h index 7199b0f34..f933217b2 100644 --- a/channels/h323/ast_h323.h +++ b/channels/h323/ast_h323.h @@ -93,6 +93,11 @@ public: virtual BOOL HandleSignalPDU(H323SignalPDU &pdu); BOOL EmbedTunneledInfo(H323SignalPDU &pdu); #endif +#ifdef H323_H450 + virtual void OnReceivedLocalCallHold(int linkedId); + virtual void OnReceivedLocalCallRetrieve(int linkedId); +#endif + void MyHoldCall(BOOL localHold); PString sourceAliases; PString destAliases; @@ -108,6 +113,7 @@ public: int tunnelOptions; #endif + unsigned holdHandling; unsigned progressSetup; unsigned progressAlert; int cause; @@ -156,6 +162,23 @@ public: void Main(); }; +#ifdef H323_H450 +#include <h450pdu.h> + +class MyH4504Handler : public H4504Handler +{ + PCLASSINFO(MyH4504Handler, H4504Handler); + +public: + MyH4504Handler(MyH323Connection &_conn, H450xDispatcher &_disp); + virtual void OnReceivedLocalCallHold(int linkedId); + virtual void OnReceivedLocalCallRetrieve(int linkedId); + +private: + MyH323Connection *conn; +}; +#endif + #include "compat_h323.h" #endif /* !defined AST_H323_H */ diff --git a/channels/h323/chan_h323.h b/channels/h323/chan_h323.h index 13296ed1a..c8bd6a3d9 100644 --- a/channels/h323/chan_h323.h +++ b/channels/h323/chan_h323.h @@ -39,6 +39,10 @@ #define H323_TUNNEL_CISCO (1 << 0) #define H323_TUNNEL_QSIG (1 << 1) +#define H323_HOLD_NOTIFY (1 << 0) +#define H323_HOLD_Q931ONLY (1 << 1) +#define H323_HOLD_H450 (1 << 2) + /** call_option struct holds various bits * of information for each call */ typedef struct call_options { @@ -58,6 +62,7 @@ typedef struct call_options { int bridge; int nat; int tunnelOptions; + int holdHandling; struct ast_codec_pref prefs; } call_options_t; @@ -184,6 +189,9 @@ extern setcapabilities_cb on_setcapabilities; typedef void (*setpeercapabilities_cb)(unsigned, const char *, int, struct ast_codec_pref *); extern setpeercapabilities_cb on_setpeercapabilities; +typedef void (*onhold_cb)(unsigned, const char *, int); +extern onhold_cb on_hold; + /* debug flag */ extern int h323debug; @@ -224,7 +232,8 @@ extern "C" { rfc2833_cb, hangup_cb, setcapabilities_cb, - setpeercapabilities_cb); + setpeercapabilities_cb, + onhold_cb); int h323_set_capabilities(const char *, int, int, struct ast_codec_pref *, int); int h323_set_alias(struct oh323_alias *); int h323_set_gk(int, char *, char *); @@ -249,6 +258,7 @@ extern "C" { int h323_answering_call(const char *token, int); int h323_soft_hangup(const char *data); int h323_show_codec(int fd, int argc, char *argv[]); + int h323_hold_call(const char *token, int); #ifdef __cplusplus } |