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:
Jeremy McNamara
2003-09-06 20:29:25 +00:00
parent ebae0a11be
commit 059b57438b
4 changed files with 143 additions and 7 deletions

View File

@@ -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");

View File

@@ -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,
@@ -734,16 +794,18 @@ 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,
con_established_cb efunc, con_established_cb efunc,
send_digit_cb dfunc) send_digit_cb dfunc)
{ {
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;

View File

@@ -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,14 +137,14 @@ 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 &);
BOOL OnClosingLogicalChannel(H323Channel &); BOOL OnClosingLogicalChannel(H323Channel &);
void SendUserInputTone(char, unsigned); void SendUserInputTone(char, unsigned);
void OnUserInputTone(char, unsigned, unsigned, unsigned); void OnUserInputTone(char, unsigned, unsigned, unsigned);
void OnUserInputString(const PString &value); void OnUserInputString(const PString &value);

View File

@@ -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 *);