mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-30 10:33:13 +00:00
Handle HOLD/RETRIEVE notifications
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@43845 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
2
CHANGES
2
CHANGES
@@ -15,3 +15,5 @@ Changes since Asterisk 1.4-beta was branched:
|
|||||||
* Ability to use libcap to set high ToS bits when non-root
|
* Ability to use libcap to set high ToS bits when non-root
|
||||||
on Linux. If configure is unable to find libcap then you
|
on Linux. If configure is unable to find libcap then you
|
||||||
can use --with-cap to specify the path.
|
can use --with-cap to specify the path.
|
||||||
|
* H323 remote hold notification support added (by NOTIFY message
|
||||||
|
and/or H.450 supplementary service)
|
||||||
|
@@ -117,6 +117,7 @@ rfc2833_cb on_set_rfc2833_payload;
|
|||||||
hangup_cb on_hangup;
|
hangup_cb on_hangup;
|
||||||
setcapabilities_cb on_setcapabilities;
|
setcapabilities_cb on_setcapabilities;
|
||||||
setpeercapabilities_cb on_setpeercapabilities;
|
setpeercapabilities_cb on_setpeercapabilities;
|
||||||
|
onhold_cb on_hold;
|
||||||
|
|
||||||
/* global debug flag */
|
/* global debug flag */
|
||||||
int h323debug;
|
int h323debug;
|
||||||
@@ -866,7 +867,7 @@ static int oh323_indicate(struct ast_channel *c, int condition, const void *data
|
|||||||
ast_mutex_unlock(&pvt->lock);
|
ast_mutex_unlock(&pvt->lock);
|
||||||
|
|
||||||
if (h323debug)
|
if (h323debug)
|
||||||
ast_log(LOG_DEBUG, "OH323: Indicating %d on %s\n", condition, token);
|
ast_log(LOG_DEBUG, "OH323: Indicating %d on %s (%s)\n", condition, token, c->name);
|
||||||
|
|
||||||
switch(condition) {
|
switch(condition) {
|
||||||
case AST_CONTROL_RINGING:
|
case AST_CONTROL_RINGING:
|
||||||
@@ -910,11 +911,14 @@ static int oh323_indicate(struct ast_channel *c, int condition, const void *data
|
|||||||
free(token);
|
free(token);
|
||||||
return -1;
|
return -1;
|
||||||
case AST_CONTROL_HOLD:
|
case AST_CONTROL_HOLD:
|
||||||
|
h323_hold_call(token, 1);
|
||||||
|
/* We should start MOH only if remote party isn't provide audio for us */
|
||||||
ast_moh_start(c, data, NULL);
|
ast_moh_start(c, data, NULL);
|
||||||
if (token)
|
if (token)
|
||||||
free(token);
|
free(token);
|
||||||
return 0;
|
return 0;
|
||||||
case AST_CONTROL_UNHOLD:
|
case AST_CONTROL_UNHOLD:
|
||||||
|
h323_hold_call(token, 0);
|
||||||
ast_moh_stop(c);
|
ast_moh_stop(c);
|
||||||
if (token)
|
if (token)
|
||||||
free(token);
|
free(token);
|
||||||
@@ -1338,6 +1342,17 @@ static int update_common_options(struct ast_variable *v, struct call_options *op
|
|||||||
options->tunnelOptions |= H323_TUNNEL_QSIG;
|
options->tunnelOptions |= H323_TUNNEL_QSIG;
|
||||||
else
|
else
|
||||||
ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);
|
ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);
|
||||||
|
} else if (!strcasecmp(v->name, "hold")) {
|
||||||
|
if (!strcasecmp(v->value, "none"))
|
||||||
|
options->holdHandling = ~0;
|
||||||
|
else if (!strcasecmp(v->value, "notify"))
|
||||||
|
options->holdHandling |= H323_HOLD_NOTIFY;
|
||||||
|
else if (!strcasecmp(v->value, "q931only"))
|
||||||
|
options->holdHandling |= H323_HOLD_NOTIFY | H323_HOLD_Q931ONLY;
|
||||||
|
else if (!strcasecmp(v->value, "h450"))
|
||||||
|
options->holdHandling |= H323_HOLD_H450;
|
||||||
|
else
|
||||||
|
ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);
|
||||||
} else
|
} else
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@@ -1364,6 +1379,7 @@ static struct oh323_user *build_user(char *name, struct ast_variable *v, struct
|
|||||||
user->ha = (struct ast_ha *)NULL;
|
user->ha = (struct ast_ha *)NULL;
|
||||||
memcpy(&user->options, &global_options, sizeof(user->options));
|
memcpy(&user->options, &global_options, sizeof(user->options));
|
||||||
user->options.dtmfmode = 0;
|
user->options.dtmfmode = 0;
|
||||||
|
user->options.holdHandling = 0;
|
||||||
/* Set default context */
|
/* Set default context */
|
||||||
strncpy(user->context, default_context, sizeof(user->context) - 1);
|
strncpy(user->context, default_context, sizeof(user->context) - 1);
|
||||||
if (user && !found)
|
if (user && !found)
|
||||||
@@ -1410,6 +1426,10 @@ static struct oh323_user *build_user(char *name, struct ast_variable *v, struct
|
|||||||
}
|
}
|
||||||
if (!user->options.dtmfmode)
|
if (!user->options.dtmfmode)
|
||||||
user->options.dtmfmode = global_options.dtmfmode;
|
user->options.dtmfmode = global_options.dtmfmode;
|
||||||
|
if (user->options.holdHandling == ~0)
|
||||||
|
user->options.holdHandling = 0;
|
||||||
|
else if (!user->options.holdHandling)
|
||||||
|
user->options.holdHandling = global_options.holdHandling;
|
||||||
ASTOBJ_UNMARK(user);
|
ASTOBJ_UNMARK(user);
|
||||||
ast_free_ha(oldha);
|
ast_free_ha(oldha);
|
||||||
return user;
|
return user;
|
||||||
@@ -1472,6 +1492,7 @@ static struct oh323_peer *build_peer(const char *name, struct ast_variable *v, s
|
|||||||
peer->ha = NULL;
|
peer->ha = NULL;
|
||||||
memcpy(&peer->options, &global_options, sizeof(peer->options));
|
memcpy(&peer->options, &global_options, sizeof(peer->options));
|
||||||
peer->options.dtmfmode = 0;
|
peer->options.dtmfmode = 0;
|
||||||
|
peer->options.holdHandling = 0;
|
||||||
peer->addr.sin_port = htons(h323_signalling_port);
|
peer->addr.sin_port = htons(h323_signalling_port);
|
||||||
peer->addr.sin_family = AF_INET;
|
peer->addr.sin_family = AF_INET;
|
||||||
if (!found && name)
|
if (!found && name)
|
||||||
@@ -1511,6 +1532,10 @@ static struct oh323_peer *build_peer(const char *name, struct ast_variable *v, s
|
|||||||
}
|
}
|
||||||
if (!peer->options.dtmfmode)
|
if (!peer->options.dtmfmode)
|
||||||
peer->options.dtmfmode = global_options.dtmfmode;
|
peer->options.dtmfmode = global_options.dtmfmode;
|
||||||
|
if (peer->options.holdHandling == ~0)
|
||||||
|
peer->options.holdHandling = 0;
|
||||||
|
else if (!peer->options.holdHandling)
|
||||||
|
peer->options.holdHandling = global_options.holdHandling;
|
||||||
ASTOBJ_UNMARK(peer);
|
ASTOBJ_UNMARK(peer);
|
||||||
ast_free_ha(oldha);
|
ast_free_ha(oldha);
|
||||||
return peer;
|
return peer;
|
||||||
@@ -2450,6 +2475,32 @@ static void set_local_capabilities(unsigned call_reference, const char *token)
|
|||||||
ast_log(LOG_DEBUG, "Capabilities for connection %s is set\n", token);
|
ast_log(LOG_DEBUG, "Capabilities for connection %s is set\n", token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void remote_hold(unsigned call_reference, const char *token, int is_hold)
|
||||||
|
{
|
||||||
|
struct oh323_pvt *pvt;
|
||||||
|
|
||||||
|
if (h323debug)
|
||||||
|
ast_log(LOG_DEBUG, "Setting %shold status for connection %s\n", (is_hold ? "" : "un"), token);
|
||||||
|
|
||||||
|
pvt = find_call_locked(call_reference, token);
|
||||||
|
if (!pvt)
|
||||||
|
return;
|
||||||
|
if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
|
||||||
|
if (is_hold)
|
||||||
|
ast_queue_control(pvt->owner, AST_CONTROL_HOLD);
|
||||||
|
else
|
||||||
|
ast_queue_control(pvt->owner, AST_CONTROL_UNHOLD);
|
||||||
|
ast_channel_unlock(pvt->owner);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (is_hold)
|
||||||
|
pvt->newcontrol = AST_CONTROL_HOLD;
|
||||||
|
else
|
||||||
|
pvt->newcontrol = AST_CONTROL_UNHOLD;
|
||||||
|
}
|
||||||
|
ast_mutex_unlock(&pvt->lock);
|
||||||
|
}
|
||||||
|
|
||||||
static void *do_monitor(void *data)
|
static void *do_monitor(void *data)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
@@ -2767,6 +2818,7 @@ static int reload_config(int is_reload)
|
|||||||
global_options.dtmfcodec[0] = H323_DTMF_RFC2833_PT;
|
global_options.dtmfcodec[0] = H323_DTMF_RFC2833_PT;
|
||||||
global_options.dtmfcodec[1] = H323_DTMF_CISCO_PT;
|
global_options.dtmfcodec[1] = H323_DTMF_CISCO_PT;
|
||||||
global_options.dtmfmode = 0;
|
global_options.dtmfmode = 0;
|
||||||
|
global_options.holdHandling = 0;
|
||||||
global_options.capability = GLOBAL_CAPABILITY;
|
global_options.capability = GLOBAL_CAPABILITY;
|
||||||
global_options.bridge = 1; /* Do native bridging by default */
|
global_options.bridge = 1; /* Do native bridging by default */
|
||||||
strncpy(default_context, "default", sizeof(default_context) - 1);
|
strncpy(default_context, "default", sizeof(default_context) - 1);
|
||||||
@@ -2861,6 +2913,10 @@ static int reload_config(int is_reload)
|
|||||||
}
|
}
|
||||||
if (!global_options.dtmfmode)
|
if (!global_options.dtmfmode)
|
||||||
global_options.dtmfmode = H323_DTMF_RFC2833;
|
global_options.dtmfmode = H323_DTMF_RFC2833;
|
||||||
|
if (global_options.holdHandling == ~0)
|
||||||
|
global_options.holdHandling = 0;
|
||||||
|
else if (!global_options.holdHandling)
|
||||||
|
global_options.holdHandling = H323_HOLD_H450;
|
||||||
|
|
||||||
for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
|
for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
|
||||||
if (strcasecmp(cat, "general")) {
|
if (strcasecmp(cat, "general")) {
|
||||||
@@ -3175,7 +3231,8 @@ static enum ast_module_load_result load_module(void)
|
|||||||
set_dtmf_payload,
|
set_dtmf_payload,
|
||||||
hangup_connection,
|
hangup_connection,
|
||||||
set_local_capabilities,
|
set_local_capabilities,
|
||||||
set_peer_capabilities);
|
set_peer_capabilities,
|
||||||
|
remote_hold);
|
||||||
/* start the h.323 listener */
|
/* start the h.323 listener */
|
||||||
if (h323_start_listener(h323_signalling_port, bindaddr)) {
|
if (h323_start_listener(h323_signalling_port, bindaddr)) {
|
||||||
ast_log(LOG_ERROR, "Unable to create H323 listener.\n");
|
ast_log(LOG_ERROR, "Unable to create H323 listener.\n");
|
||||||
|
@@ -40,6 +40,12 @@
|
|||||||
#include <h323neg.h>
|
#include <h323neg.h>
|
||||||
#include <mediafmt.h>
|
#include <mediafmt.h>
|
||||||
#include <lid.h>
|
#include <lid.h>
|
||||||
|
#ifdef H323_H450
|
||||||
|
#include "h4501.h"
|
||||||
|
#include "h4504.h"
|
||||||
|
#include "h45011.h"
|
||||||
|
#include "h450pdu.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -528,10 +534,20 @@ MyH323Connection::MyH323Connection(MyH323EndPoint & ep, unsigned callReference,
|
|||||||
unsigned options)
|
unsigned options)
|
||||||
: H323Connection(ep, callReference, 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;
|
cause = -1;
|
||||||
sessionId = 0;
|
sessionId = 0;
|
||||||
bridging = FALSE;
|
bridging = FALSE;
|
||||||
progressSetup = progressAlert = 0;
|
holdHandling = progressSetup = progressAlert = 0;
|
||||||
dtmfMode = 0;
|
dtmfMode = 0;
|
||||||
dtmfCodec[0] = dtmfCodec[1] = (RTP_DataFrame::PayloadTypes)0;
|
dtmfCodec[0] = dtmfCodec[1] = (RTP_DataFrame::PayloadTypes)0;
|
||||||
redirect_reason = -1;
|
redirect_reason = -1;
|
||||||
@@ -664,6 +680,7 @@ void MyH323Connection::SetCallOptions(void *o, BOOL isIncoming)
|
|||||||
|
|
||||||
progressSetup = opts->progress_setup;
|
progressSetup = opts->progress_setup;
|
||||||
progressAlert = opts->progress_alert;
|
progressAlert = opts->progress_alert;
|
||||||
|
holdHandling = opts->holdHandling;
|
||||||
dtmfCodec[0] = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec[0];
|
dtmfCodec[0] = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec[0];
|
||||||
dtmfCodec[1] = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec[1];
|
dtmfCodec[1] = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec[1];
|
||||||
dtmfMode = opts->dtmfmode;
|
dtmfMode = opts->dtmfmode;
|
||||||
@@ -1641,6 +1658,48 @@ BOOL MyH323Connection::StartControlChannel(const H225_TransportAddress & h245Add
|
|||||||
return TRUE;
|
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::MyH323_ExternalRTPChannel(MyH323Connection & connection,
|
MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection,
|
||||||
const H323Capability & capability,
|
const H323Capability & capability,
|
||||||
@@ -1722,6 +1781,32 @@ BOOL MyH323_ExternalRTPChannel::OnReceivedAckPDU(const H245_H2250LogicalChannelA
|
|||||||
return FALSE;
|
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 */
|
/** IMPLEMENTATION OF C FUNCTIONS */
|
||||||
|
|
||||||
@@ -1780,7 +1865,8 @@ void h323_callback_register(setup_incoming_cb ifunc,
|
|||||||
rfc2833_cb dtmffunc,
|
rfc2833_cb dtmffunc,
|
||||||
hangup_cb hangupfunc,
|
hangup_cb hangupfunc,
|
||||||
setcapabilities_cb capabilityfunc,
|
setcapabilities_cb capabilityfunc,
|
||||||
setpeercapabilities_cb peercapabilityfunc)
|
setpeercapabilities_cb peercapabilityfunc,
|
||||||
|
onhold_cb holdfunc)
|
||||||
{
|
{
|
||||||
on_incoming_call = ifunc;
|
on_incoming_call = ifunc;
|
||||||
on_outgoing_call = sfunc;
|
on_outgoing_call = sfunc;
|
||||||
@@ -1796,6 +1882,7 @@ void h323_callback_register(setup_incoming_cb ifunc,
|
|||||||
on_hangup = hangupfunc;
|
on_hangup = hangupfunc;
|
||||||
on_setcapabilities = capabilityfunc;
|
on_setcapabilities = capabilityfunc;
|
||||||
on_setpeercapabilities = peercapabilityfunc;
|
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 cout
|
||||||
#undef endl
|
#undef endl
|
||||||
void h323_end_process(void)
|
void h323_end_process(void)
|
||||||
|
@@ -93,6 +93,11 @@ public:
|
|||||||
virtual BOOL HandleSignalPDU(H323SignalPDU &pdu);
|
virtual BOOL HandleSignalPDU(H323SignalPDU &pdu);
|
||||||
BOOL EmbedTunneledInfo(H323SignalPDU &pdu);
|
BOOL EmbedTunneledInfo(H323SignalPDU &pdu);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef H323_H450
|
||||||
|
virtual void OnReceivedLocalCallHold(int linkedId);
|
||||||
|
virtual void OnReceivedLocalCallRetrieve(int linkedId);
|
||||||
|
#endif
|
||||||
|
void MyHoldCall(BOOL localHold);
|
||||||
|
|
||||||
PString sourceAliases;
|
PString sourceAliases;
|
||||||
PString destAliases;
|
PString destAliases;
|
||||||
@@ -108,6 +113,7 @@ public:
|
|||||||
int tunnelOptions;
|
int tunnelOptions;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
unsigned holdHandling;
|
||||||
unsigned progressSetup;
|
unsigned progressSetup;
|
||||||
unsigned progressAlert;
|
unsigned progressAlert;
|
||||||
int cause;
|
int cause;
|
||||||
@@ -156,6 +162,23 @@ public:
|
|||||||
void Main();
|
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"
|
#include "compat_h323.h"
|
||||||
|
|
||||||
#endif /* !defined AST_H323_H */
|
#endif /* !defined AST_H323_H */
|
||||||
|
@@ -39,6 +39,10 @@
|
|||||||
#define H323_TUNNEL_CISCO (1 << 0)
|
#define H323_TUNNEL_CISCO (1 << 0)
|
||||||
#define H323_TUNNEL_QSIG (1 << 1)
|
#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
|
/** call_option struct holds various bits
|
||||||
* of information for each call */
|
* of information for each call */
|
||||||
typedef struct call_options {
|
typedef struct call_options {
|
||||||
@@ -58,6 +62,7 @@ typedef struct call_options {
|
|||||||
int bridge;
|
int bridge;
|
||||||
int nat;
|
int nat;
|
||||||
int tunnelOptions;
|
int tunnelOptions;
|
||||||
|
int holdHandling;
|
||||||
struct ast_codec_pref prefs;
|
struct ast_codec_pref prefs;
|
||||||
} call_options_t;
|
} call_options_t;
|
||||||
|
|
||||||
@@ -184,6 +189,9 @@ extern setcapabilities_cb on_setcapabilities;
|
|||||||
typedef void (*setpeercapabilities_cb)(unsigned, const char *, int, struct ast_codec_pref *);
|
typedef void (*setpeercapabilities_cb)(unsigned, const char *, int, struct ast_codec_pref *);
|
||||||
extern setpeercapabilities_cb on_setpeercapabilities;
|
extern setpeercapabilities_cb on_setpeercapabilities;
|
||||||
|
|
||||||
|
typedef void (*onhold_cb)(unsigned, const char *, int);
|
||||||
|
extern onhold_cb on_hold;
|
||||||
|
|
||||||
/* debug flag */
|
/* debug flag */
|
||||||
extern int h323debug;
|
extern int h323debug;
|
||||||
|
|
||||||
@@ -224,7 +232,8 @@ extern "C" {
|
|||||||
rfc2833_cb,
|
rfc2833_cb,
|
||||||
hangup_cb,
|
hangup_cb,
|
||||||
setcapabilities_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_capabilities(const char *, int, int, struct ast_codec_pref *, int);
|
||||||
int h323_set_alias(struct oh323_alias *);
|
int h323_set_alias(struct oh323_alias *);
|
||||||
int h323_set_gk(int, char *, char *);
|
int h323_set_gk(int, char *, char *);
|
||||||
@@ -249,6 +258,7 @@ extern "C" {
|
|||||||
int h323_answering_call(const char *token, int);
|
int h323_answering_call(const char *token, int);
|
||||||
int h323_soft_hangup(const char *data);
|
int h323_soft_hangup(const char *data);
|
||||||
int h323_show_codec(int fd, int argc, char *argv[]);
|
int h323_show_codec(int fd, int argc, char *argv[]);
|
||||||
|
int h323_hold_call(const char *token, int);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@@ -108,6 +108,15 @@ port = 1720
|
|||||||
;tunneling=cisco ; Enable Cisco-specific tunneling
|
;tunneling=cisco ; Enable Cisco-specific tunneling
|
||||||
;tunneling=qsig ; Enable tunneling via Q.SIG messages
|
;tunneling=qsig ; Enable tunneling via Q.SIG messages
|
||||||
;
|
;
|
||||||
|
; Specify how to pass hold notification to remote party. Default is to
|
||||||
|
; use H.450.4 supplementary service message.
|
||||||
|
;hold=none ; Do not pass hold/retrieve notifications
|
||||||
|
;hold=notify ; Use H.225 NOTIFY message
|
||||||
|
;hold=q931only ; Use stripped H.225 NOTIFY message (Q.931 part
|
||||||
|
; ; only, usable for Cisco CallManager)
|
||||||
|
;hold=h450 ; Pass notification as H.450.4 supplementary
|
||||||
|
; ; service
|
||||||
|
;
|
||||||
;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
|
;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
|
||||||
; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
|
; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
|
||||||
; H323 channel. Defaults to "no". An enabled jitterbuffer will
|
; H323 channel. Defaults to "no". An enabled jitterbuffer will
|
||||||
|
Reference in New Issue
Block a user