mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-09 11:28:25 +00:00
implement transfer and call forwarding. Bug #221
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@1482 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -1089,6 +1089,61 @@ if (!p) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Call-back function that gets called on transfer
|
||||||
|
*
|
||||||
|
* Returns 1 on success
|
||||||
|
*/
|
||||||
|
int setup_transfer_call(unsigned call_reference, const char *extension)
|
||||||
|
{
|
||||||
|
struct oh323_pvt *p;
|
||||||
|
struct ast_channel *c = NULL;
|
||||||
|
char exten[AST_MAX_EXTENSION];
|
||||||
|
char *context;
|
||||||
|
|
||||||
|
p = find_call(call_reference);
|
||||||
|
|
||||||
|
if (!p) {
|
||||||
|
ast_log(LOG_WARNING, "No such call %d.\n", call_reference);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p->owner) {
|
||||||
|
ast_log(LOG_WARNING, "Call %d has no owner.\n", call_reference);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(exten, extension, sizeof(exten));
|
||||||
|
|
||||||
|
c = p->owner;
|
||||||
|
if (c && c->bridge) {
|
||||||
|
strncpy(exten, extension, sizeof(exten) - 1);
|
||||||
|
context = strchr(exten, '@');
|
||||||
|
if (context) {
|
||||||
|
*context = '\0';
|
||||||
|
context++;
|
||||||
|
} else
|
||||||
|
context = c->context;
|
||||||
|
if (!strlen(context))
|
||||||
|
context = c->bridge->context;
|
||||||
|
if (ast_exists_extension(c->bridge, context, exten, 1, c->bridge->callerid)) {
|
||||||
|
|
||||||
|
ast_log(LOG_NOTICE, "Transfering call %s to %s@%s.\n", c->bridge->name, exten, context);
|
||||||
|
|
||||||
|
if (!ast_async_goto(c->bridge, context, exten, 1, 1))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ast_log(LOG_WARNING, "Failed to transfer.\n");
|
||||||
|
} else {
|
||||||
|
ast_log(LOG_WARNING, "No such extension '%s' exists.\n", exten);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ast_log(LOG_WARNING, "There is no call to transfer\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call-back function that gets called for each rtp channel opened
|
* Call-back function that gets called for each rtp channel opened
|
||||||
*
|
*
|
||||||
@@ -1714,11 +1769,13 @@ int load_module()
|
|||||||
/* Register our callback functions */
|
/* Register our callback functions */
|
||||||
h323_callback_register(setup_incoming_call,
|
h323_callback_register(setup_incoming_call,
|
||||||
setup_outgoing_call,
|
setup_outgoing_call,
|
||||||
|
setup_transfer_call,
|
||||||
create_connection,
|
create_connection,
|
||||||
setup_rtp_connection,
|
setup_rtp_connection,
|
||||||
cleanup_connection,
|
cleanup_connection,
|
||||||
connection_made, send_digit);
|
connection_made, send_digit);
|
||||||
|
|
||||||
|
|
||||||
/* start the h.323 listener */
|
/* start the h.323 listener */
|
||||||
if (h323_start_listener(port, bindaddr)) {
|
if (h323_start_listener(port, bindaddr)) {
|
||||||
ast_log(LOG_ERROR, "Unable to create H323 listener.\n");
|
ast_log(LOG_ERROR, "Unable to create H323 listener.\n");
|
||||||
|
|||||||
@@ -269,6 +269,24 @@ void MyH323EndPoint::OnClosedLogicalChannel(H323Connection & connection, const H
|
|||||||
H323EndPoint::OnClosedLogicalChannel(connection, channel);
|
H323EndPoint::OnClosedLogicalChannel(connection, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL MyH323EndPoint::OnConnectionForwarded(H323Connection & connection,
|
||||||
|
const PString & forwardParty,
|
||||||
|
const H323SignalPDU & pdu)
|
||||||
|
{
|
||||||
|
if (h323debug)
|
||||||
|
cout << " -- Call Forwarded to " << forwardParty << endl;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL MyH323EndPoint::ForwardConnection(H323Connection & connection,
|
||||||
|
const PString & forwardParty,
|
||||||
|
const H323SignalPDU & pdu)
|
||||||
|
{
|
||||||
|
if (h323debug)
|
||||||
|
cout << " -- Forwarding call to " << forwardParty << endl;
|
||||||
|
return H323EndPoint::ForwardConnection(connection, forwardParty, pdu);
|
||||||
|
}
|
||||||
|
|
||||||
void MyH323EndPoint::OnConnectionEstablished(H323Connection & connection, const PString & estCallToken)
|
void MyH323EndPoint::OnConnectionEstablished(H323Connection & connection, const PString & estCallToken)
|
||||||
{
|
{
|
||||||
if (h323debug)
|
if (h323debug)
|
||||||
@@ -389,6 +407,48 @@ H323Connection * MyH323EndPoint::CreateConnection(unsigned callReference, void *
|
|||||||
return new MyH323Connection(*this, callReference, options);
|
return new MyH323Connection(*this, callReference, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
H323Connection * MyH323EndPoint::SetupTransfer(const PString & token,
|
||||||
|
const PString & callIdentity,
|
||||||
|
const PString & remoteParty,
|
||||||
|
PString & newToken,
|
||||||
|
void * userData)
|
||||||
|
{
|
||||||
|
PString alias;
|
||||||
|
H323TransportAddress address;
|
||||||
|
|
||||||
|
H323Connection * connection;
|
||||||
|
|
||||||
|
if (h323debug) {
|
||||||
|
cout << " -- Setup transfer of " << callIdentity << ":" << endl;
|
||||||
|
cout << " -- Call from " << token << endl;
|
||||||
|
cout << " -- Remote Party " << remoteParty << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
connection = FindConnectionWithLock(token);
|
||||||
|
|
||||||
|
if (connection != NULL) {
|
||||||
|
unsigned int old_call_reference = connection->GetCallReference();
|
||||||
|
|
||||||
|
if (h323debug)
|
||||||
|
cout << " -- Old call reference " << old_call_reference << endl;
|
||||||
|
connection->Unlock();
|
||||||
|
|
||||||
|
if (on_transfer_call(old_call_reference, remoteParty)) {
|
||||||
|
if (h323debug)
|
||||||
|
cout << " -- Transfer succeded " << endl;
|
||||||
|
if (connection->ClearCall(H323Connection::EndedByCallForwarded))
|
||||||
|
return NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (h323debug)
|
||||||
|
cout << " -- Transfer failed " << endl;
|
||||||
|
|
||||||
|
if (connection != NULL) {
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* MyH323Connection */
|
/* MyH323Connection */
|
||||||
MyH323Connection::MyH323Connection(MyH323EndPoint & ep,
|
MyH323Connection::MyH323Connection(MyH323EndPoint & ep,
|
||||||
@@ -736,6 +796,7 @@ void h323_debug(int flag, unsigned level)
|
|||||||
/** Installs the callback functions on behalf of the PBX application */
|
/** Installs the callback functions on behalf of the PBX application */
|
||||||
void h323_callback_register(setup_incoming_cb ifunc,
|
void h323_callback_register(setup_incoming_cb ifunc,
|
||||||
setup_outbound_cb sfunc,
|
setup_outbound_cb sfunc,
|
||||||
|
setup_transfer_cb tfunc,
|
||||||
on_connection_cb confunc,
|
on_connection_cb confunc,
|
||||||
start_logchan_cb lfunc,
|
start_logchan_cb lfunc,
|
||||||
clear_con_cb clfunc,
|
clear_con_cb clfunc,
|
||||||
@@ -744,6 +805,7 @@ void h323_callback_register(setup_incoming_cb ifunc,
|
|||||||
{
|
{
|
||||||
on_incoming_call = ifunc;
|
on_incoming_call = ifunc;
|
||||||
on_outgoing_call = sfunc;
|
on_outgoing_call = sfunc;
|
||||||
|
on_transfer_call = tfunc;
|
||||||
on_create_connection = confunc;
|
on_create_connection = confunc;
|
||||||
on_start_logical_channel = lfunc;
|
on_start_logical_channel = lfunc;
|
||||||
on_connection_cleared = clfunc;
|
on_connection_cleared = clfunc;
|
||||||
|
|||||||
@@ -111,8 +111,12 @@ class MyH323EndPoint : public H323EndPoint {
|
|||||||
void OnConnectionEstablished(H323Connection &, const PString &);
|
void OnConnectionEstablished(H323Connection &, const PString &);
|
||||||
void OnConnectionCleared(H323Connection &, const PString &);
|
void OnConnectionCleared(H323Connection &, const PString &);
|
||||||
H323Connection * CreateConnection(unsigned, void *);
|
H323Connection * CreateConnection(unsigned, void *);
|
||||||
|
H323Connection * SetupTransfer(const PString &, const PString &, const PString &, PString &, void *);
|
||||||
void SendUserTone(const PString &, char);
|
void SendUserTone(const PString &, char);
|
||||||
H323Capabilities GetCapabilities(void);
|
H323Capabilities GetCapabilities(void);
|
||||||
|
BOOL OnConnectionForwarded(H323Connection &, const PString &, const H323SignalPDU &);
|
||||||
|
|
||||||
|
BOOL ForwardConnection(H323Connection &, const PString &, const H323SignalPDU &);
|
||||||
|
|
||||||
PStringArray SupportedPrefixes;
|
PStringArray SupportedPrefixes;
|
||||||
|
|
||||||
@@ -133,10 +137,10 @@ class MyH323Connection : public H323Connection {
|
|||||||
H323Channel * CreateRealTimeLogicalChannel(const H323Capability &, H323Channel::Directions, unsigned,
|
H323Channel * CreateRealTimeLogicalChannel(const H323Capability &, H323Channel::Directions, unsigned,
|
||||||
const H245_H2250LogicalChannelParameters *);
|
const H245_H2250LogicalChannelParameters *);
|
||||||
H323Connection::AnswerCallResponse OnAnswerCall(const PString &, const H323SignalPDU &, H323SignalPDU &);
|
H323Connection::AnswerCallResponse OnAnswerCall(const PString &, const H323SignalPDU &, H323SignalPDU &);
|
||||||
|
void OnReceivedReleaseComplete(const H323SignalPDU &);
|
||||||
BOOL OnAlerting(const H323SignalPDU &, const PString &);
|
BOOL OnAlerting(const H323SignalPDU &, const PString &);
|
||||||
BOOL OnSendReleaseComplete(H323SignalPDU &);
|
BOOL OnSendReleaseComplete(H323SignalPDU &);
|
||||||
BOOL OnReceivedSignalSetup(const H323SignalPDU &);
|
BOOL OnReceivedSignalSetup(const H323SignalPDU &);
|
||||||
void OnReceivedReleaseComplete(const H323SignalPDU &);
|
|
||||||
BOOL OnReceivedFacility(const H323SignalPDU &);
|
BOOL OnReceivedFacility(const H323SignalPDU &);
|
||||||
BOOL OnSendSignalSetup(H323SignalPDU &);
|
BOOL OnSendSignalSetup(H323SignalPDU &);
|
||||||
BOOL OnStartLogicalChannel(H323Channel &);
|
BOOL OnStartLogicalChannel(H323Channel &);
|
||||||
|
|||||||
@@ -131,6 +131,11 @@ setup_incoming_cb on_incoming_call;
|
|||||||
typedef int (*setup_outbound_cb)(call_details_t);
|
typedef int (*setup_outbound_cb)(call_details_t);
|
||||||
setup_outbound_cb on_outgoing_call;
|
setup_outbound_cb on_outgoing_call;
|
||||||
|
|
||||||
|
/* This is a callback prototype function, called upon
|
||||||
|
a transfer. */
|
||||||
|
typedef int (*setup_transfer_cb)(unsigned int, const char *);
|
||||||
|
setup_transfer_cb on_transfer_call;
|
||||||
|
|
||||||
/* This is a callback prototype function, called when the openh323
|
/* This is a callback prototype function, called when the openh323
|
||||||
OnStartLogicalChannel is invoked. */
|
OnStartLogicalChannel is invoked. */
|
||||||
typedef void (*start_logchan_cb)(unsigned int, const char *, int);
|
typedef void (*start_logchan_cb)(unsigned int, const char *, int);
|
||||||
@@ -164,7 +169,15 @@ extern "C" {
|
|||||||
void h323_debug(int, unsigned);
|
void h323_debug(int, unsigned);
|
||||||
|
|
||||||
/* callback function handler*/
|
/* callback function handler*/
|
||||||
void h323_callback_register(setup_incoming_cb, setup_outbound_cb, on_connection_cb, start_logchan_cb, clear_con_cb, con_established_cb, send_digit_cb);
|
void h323_callback_register(setup_incoming_cb,
|
||||||
|
setup_outbound_cb,
|
||||||
|
setup_transfer_cb,
|
||||||
|
on_connection_cb,
|
||||||
|
start_logchan_cb,
|
||||||
|
clear_con_cb,
|
||||||
|
con_established_cb,
|
||||||
|
send_digit_cb);
|
||||||
|
|
||||||
|
|
||||||
int h323_set_capability(int, int);
|
int h323_set_capability(int, int);
|
||||||
int h323_set_alias(struct oh323_alias *);
|
int h323_set_alias(struct oh323_alias *);
|
||||||
|
|||||||
Reference in New Issue
Block a user