[Asterisk-cvs] asterisk/channels/h323 ast_h323.cpp, 1.65,
1.66 ast_h323.h, 1.29, 1.30 chan_h323.h, 1.34, 1.35
jeremy at lists.digium.com
jeremy at lists.digium.com
Wed Dec 15 18:27:34 CST 2004
Update of /usr/cvsroot/asterisk/channels/h323
In directory mongoose.digium.com:/tmp/cvs-serv32767/h323
Modified Files:
ast_h323.cpp ast_h323.h chan_h323.h
Log Message:
Major fixes: Fixed deadlock issue, added support for inband call progress and correct Progress Indicator messages, added configurable RTP payload to send RFC2833 DTMF and correct sending of RFC2833 User Input capability, fixed hostname parsing on peers, preliminary support for correct Q.931 cause codes and fixed bindaddr compile warning
Index: ast_h323.cpp
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/h323/ast_h323.cpp,v
retrieving revision 1.65
retrieving revision 1.66
diff -u -d -r1.65 -r1.66
--- ast_h323.cpp 11 Nov 2004 21:30:30 -0000 1.65
+++ ast_h323.cpp 15 Dec 2004 23:24:13 -0000 1.66
@@ -156,7 +156,7 @@
}
AST_G729Capability::AST_G729Capability()
- : H323AudioCapability(24, 6)
+ : H323AudioCapability(24, 2)
{
}
@@ -213,7 +213,7 @@
* transport = ip.
* port = 1720.
*/
-int MyH323EndPoint::MakeCall(const PString & dest, PString & token, unsigned int *callReference, char *cid_name, char *cid_num)
+int MyH323EndPoint::MakeCall(const PString & dest, PString & token, unsigned int *callReference, call_options_t *opts)
{
PString fullAddress;
MyH323Connection * connection;
@@ -237,20 +237,23 @@
return 1;
}
*callReference = connection->GetCallReference();
- if (cid_name) {
+ if (opts->cid_name) {
localAliasNames.RemoveAll();
- connection->SetLocalPartyName(PString(cid_name));
- if (cid_num) {
- localAliasNames.AppendString(PString(cid_num));
+ connection->SetLocalPartyName(PString(opts->cid_name));
+ if (opts->cid_num) {
+ localAliasNames.AppendString(PString(opts->cid_num));
}
- } else if (cid_num) {
+ } else if (opts->cid_num) {
localAliasNames.RemoveAll();
- connection->SetLocalPartyName(PString(cid_num));
+ connection->SetLocalPartyName(PString(opts->cid_num));
}
+ connection->dtmfCodec = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec;
+
if (h323debug) {
cout << "\t-- " << GetLocalUserName() << " is calling host " << fullAddress << endl;
cout << "\t--" << "Call token is " << (const char *)token << endl;
cout << "\t-- Call reference is " << *callReference << endl;
+ cout << "\t-- DTMF Payload is " << connection->dtmfCodec << endl;
}
connection->Unlock();
return 0;
@@ -259,6 +262,12 @@
void MyH323EndPoint::SetEndpointTypeInfo( H225_EndpointType & info ) const
{
H323EndPoint::SetEndpointTypeInfo(info);
+
+ if (terminalType == e_GatewayOnly){
+ info.RemoveOptionalField(H225_EndpointType::e_terminal);
+ info.IncludeOptionalField(H225_EndpointType::e_gateway);
+ }
+
info.m_gateway.IncludeOptionalField(H225_GatewayInfo::e_protocol);
info.m_gateway.m_protocol.SetSize(1);
H225_SupportedProtocols &protocol=info.m_gateway.m_protocol[0];
@@ -280,12 +289,20 @@
return capabilities;
}
+BOOL MyH323EndPoint::ClearCall(const PString & token, H323Connection::CallEndReason reason)
+{
+ if (h323debug) {
+ cout << "\t-- ClearCall: Request to clear call with token " << token << ", cause " << reason << endl;
+ }
+ return H323EndPoint::ClearCall(token, reason);
+}
+
BOOL MyH323EndPoint::ClearCall(const PString & token)
{
if (h323debug) {
cout << "\t-- ClearCall: Request to clear call with token " << token << endl;
}
- return H323EndPoint::ClearCall(token);
+ return ClearCall(token, H323Connection::EndedByLocalUser);
}
void MyH323EndPoint::SendUserTone(const PString &token, char tone)
@@ -506,29 +523,99 @@
return;
}
+BOOL MyH323Connection::OnReceivedProgress(const H323SignalPDU &pdu)
+{
+ BOOL isInband;
+ unsigned pi;
+
+ if (!H323Connection::OnReceivedProgress(pdu)) {
+ return FALSE;
+ }
+
+ if (!pdu.GetQ931().GetProgressIndicator(pi))
+ pi = 0;
+ if (h323debug) {
+ cout << "\t- Progress Indicator: " << pi << endl;
+ }
+
+ switch(pi) {
+ case Q931::ProgressNotEndToEndISDN:
+ case Q931::ProgressInbandInformationAvailable:
+ isInband = TRUE;
+ break;
+ default:
+ isInband = FALSE;
+ }
+ on_progress(GetCallReference(), (const char *)GetCallToken(), isInband);
+
+ return TRUE;
+}
+
H323Connection::AnswerCallResponse MyH323Connection::OnAnswerCall(const PString & caller,
- const H323SignalPDU & /*setupPDU*/,
+ const H323SignalPDU & setupPDU,
H323SignalPDU & /*connectPDU*/)
{
+ unsigned pi;
- if (h323debug) {
+ if (h323debug) {
cout << "\t=-= In OnAnswerCall for call " << GetCallReference() << endl;
}
+
+ if (!setupPDU.GetQ931().GetProgressIndicator(pi)) {
+ pi = 0;
+ }
+ if (h323debug) {
+ cout << "\t\t- Progress Indicator: " << pi << endl;
+ }
+ if (progressAlert) {
+ pi = progressAlert;
+ } else if (pi == Q931::ProgressOriginNotISDN) {
+ pi = Q931::ProgressInbandInformationAvailable;
+ }
+ if (pi) {
+ alertingPDU->GetQ931().SetProgressIndicator(pi);
+ }
+ if (h323debug) {
+ cout << "\t\t- Inserting PI of " << pi << " into ALERTING message" << endl;
+ }
+
if (!on_answer_call(GetCallReference(), (const char *)GetCallToken())) {
return H323Connection::AnswerCallDenied;
}
/* The call will be answered later with "AnsweringCall()" function.
*/
- return H323Connection::AnswerCallDeferred;
+ return H323Connection::AnswerCallDeferredWithMedia;
}
-BOOL MyH323Connection::OnAlerting(const H323SignalPDU & /*alertingPDU*/, const PString & username)
+BOOL MyH323Connection::OnAlerting(const H323SignalPDU & alertingPDU, const PString & username)
{
if (h323debug) {
cout << "\t=-= In OnAlerting for call " << GetCallReference()
<< ": sessionId=" << sessionId << endl;
cout << "\t-- Ringing phone for \"" << username << "\"" << endl;
- }
+ }
+
+ if (on_progress) {
+ BOOL isInband;
+ unsigned alertingPI;
+
+ if (!alertingPDU.GetQ931().GetProgressIndicator(alertingPI)) {
+ alertingPI = 0;
+ }
+ if (h323debug) {
+ cout << "\t\t- Progress Indicator: " << alertingPI << endl;
+ }
+
+ switch(alertingPI) {
+ case Q931::ProgressNotEndToEndISDN:
+ case Q931::ProgressInbandInformationAvailable:
+ isInband = TRUE;
+ break;
+ default:
+ isInband = FALSE;
+ }
+ on_progress(GetCallReference(), (const char *)GetCallToken(), isInband);
+ }
on_chan_ringing(GetCallReference(), (const char *)GetCallToken() );
return TRUE;
}
@@ -588,7 +675,7 @@
cd.sourceIp = strdup((const char *)Ip.AsString());
/* Notify Asterisk of the request */
- int res = on_incoming_call(cd);
+ call_options_t *res = on_incoming_call(cd);
if (!res) {
if (h323debug) {
@@ -596,6 +683,12 @@
}
return FALSE;
}
+
+ progressSetup = res->progress_setup;
+ progressAlert = res->progress_alert;
+ dtmfCodec = (RTP_DataFrame::PayloadTypes)res->dtmfcodec;
+
+
return H323Connection::OnReceivedSignalSetup(setupPDU);
}
@@ -646,6 +739,10 @@
}
return FALSE;
}
+
+ if (progressSetup) {
+ setupPDU.GetQ931().SetProgressIndicator(progressSetup);
+ }
return H323Connection::OnSendSignalSetup(setupPDU);
}
@@ -711,6 +808,50 @@
}
}
+void MyH323Connection::OnSendCapabilitySet(H245_TerminalCapabilitySet & pdu)
+{
+ PINDEX i;
+
+ H323Connection::OnSendCapabilitySet(pdu);
+
+ H245_ArrayOf_CapabilityTableEntry & tables = pdu.m_capabilityTable;
+ for(i = 0; i < tables.GetSize(); i++)
+ {
+ H245_CapabilityTableEntry & entry = tables[i];
+ if (entry.HasOptionalField(H245_CapabilityTableEntry::e_capability)) {
+ H245_Capability & cap = entry.m_capability;
+ if (cap.GetTag() == H245_Capability::e_receiveRTPAudioTelephonyEventCapability) {
+ H245_AudioTelephonyEventCapability & atec = cap;
+ atec.m_dynamicRTPPayloadType = dtmfCodec;
+ on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)dtmfCodec);
+ if (h323debug) {
+ cout << "\t-- Transmitting RFC2833 on payload " <<
+ atec.m_dynamicRTPPayloadType << endl;
+ }
+ }
+ }
+ }
+}
+
+BOOL MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remoteCaps,
+ const H245_MultiplexCapability * muxCap,
+ H245_TerminalCapabilitySetReject & reject)
+{
+ if (!H323Connection::OnReceivedCapabilitySet(remoteCaps, muxCap, reject)) {
+ return FALSE;
+ }
+
+ const H323Capability * cap = remoteCaps.FindCapability(H323_UserInputCapability::SubTypeNames[H323_UserInputCapability::SignalToneRFC2833]);
+ if (cap != NULL) {
+ RTP_DataFrame::PayloadTypes pt = ((H323_UserInputCapability*)cap)->GetPayloadType();
+ on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)pt);
+ if (h323debug) {
+ cout << "\t-- Inbound RFC2833 on payload " << pt << endl;
+ }
+ }
+ return TRUE;
+}
+
H323Channel * MyH323Connection::CreateRealTimeLogicalChannel(const H323Capability & capability,
H323Channel::Directions dir,
unsigned sessionID,
@@ -783,7 +924,7 @@
}
/* Collect the remote information */
- GetRemoteAddress(remoteIpAddr, remotePort);
+ H323_ExternalRTPChannel::GetRemoteAddress(remoteIpAddr, remotePort);
if (h323debug) {
cout << "\t\tExternal RTP Session Starting" << endl;
@@ -800,6 +941,28 @@
return TRUE;
}
+BOOL MyH323_ExternalRTPChannel::OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param)
+{
+ PIPSocket::Address remoteIpAddress;
+ WORD remotePort;
+
+ if (h323debug) {
+ cout << " MyH323_ExternalRTPChannel::OnReceivedAckPDU" << endl;
+ }
+
+ if (H323_ExternalRTPChannel::OnReceivedAckPDU(param)) {
+ GetRemoteAddress(remoteIpAddress, remotePort);
+ if (h323debug) {
+ cout << " -- remoteIpAddress: " << remoteIpAddress << endl;
+ cout << " -- remotePort: " << remotePort << endl;
+ }
+ on_start_rtp_channel(connection.GetCallReference(), (const char *)remoteIpAddress.AsString(),
+ remotePort, (const char *)connection.GetCallToken());
+ return TRUE;
+ }
+ return FALSE;
+}
+
/** IMPLEMENTATION OF C FUNCTIONS */
/**
@@ -859,7 +1022,9 @@
chan_ringing_cb rfunc,
con_established_cb efunc,
send_digit_cb dfunc,
- answer_call_cb acfunc)
+ answer_call_cb acfunc,
+ progress_cb pgfunc,
+ rfc2833_cb dtmffunc)
{
on_incoming_call = ifunc;
on_outgoing_call = sfunc;
@@ -870,6 +1035,8 @@
on_connection_established = efunc;
on_send_digit = dfunc;
on_answer_call = acfunc;
+ on_progress = pgfunc;
+ on_set_rfc2833_payload = dtmffunc;
}
/**
@@ -879,8 +1046,9 @@
{
H323Capabilities oldcaps;
PStringArray codecs;
- int g711Frames = 30;
+ int g711Frames = 20;
// int gsmFrames = 4;
+ PINDEX lastcap = -1; /* last common capability index */
if (!h323_end_point_exist()) {
cout << " ERROR: [h323_set_capablity] No Endpoint, this is bad" << endl;
@@ -894,12 +1062,6 @@
}
endPoint->RemoveCapabilities(codecs);
- mode = dtmfMode;
- if (dtmfMode == H323_DTMF_INBAND) {
- endPoint->SetSendUserInputMode(H323Connection::SendUserInputAsTone);
- } else {
- endPoint->SetSendUserInputMode(H323Connection::SendUserInputAsInlineRFC2833);
- }
#if 0
if (cap & AST_FORMAT_SPEEX) {
/* Not real sure if Asterisk acutally supports all
@@ -916,32 +1078,45 @@
if (cap & AST_FORMAT_G729A) {
AST_G729ACapability *g729aCap;
AST_G729Capability *g729Cap;
- endPoint->SetCapability(0, 0, g729aCap = new AST_G729ACapability);
- endPoint->SetCapability(0, 0, g729Cap = new AST_G729Capability);
+ lastcap = endPoint->SetCapability(0, 0, g729aCap = new AST_G729ACapability);
+ lastcap = endPoint->SetCapability(0, 0, g729Cap = new AST_G729Capability);
}
if (cap & AST_FORMAT_G723_1) {
H323_G7231Capability *g7231Cap;
- endPoint->SetCapability(0, 0, g7231Cap = new H323_G7231Capability);
+ lastcap = endPoint->SetCapability(0, 0, g7231Cap = new H323_G7231Capability);
}
#if 0
if (cap & AST_FORMAT_GSM) {
H323_GSM0610Capability *gsmCap;
- endPoint->SetCapability(0, 0, gsmCap = new H323_GSM0610Capability);
+ lastcap = endPoint->SetCapability(0, 0, gsmCap = new H323_GSM0610Capability);
gsmCap->SetTxFramesInPacket(gsmFrames);
}
#endif
if (cap & AST_FORMAT_ULAW) {
H323_G711Capability *g711uCap;
- endPoint->SetCapability(0, 0, g711uCap = new H323_G711Capability(H323_G711Capability::muLaw));
+ lastcap = endPoint->SetCapability(0, 0, g711uCap = new H323_G711Capability(H323_G711Capability::muLaw));
g711uCap->SetTxFramesInPacket(g711Frames);
}
if (cap & AST_FORMAT_ALAW) {
H323_G711Capability *g711aCap;
- endPoint->SetCapability(0, 0, g711aCap = new H323_G711Capability(H323_G711Capability::ALaw));
+ lastcap = endPoint->SetCapability(0, 0, g711aCap = new H323_G711Capability(H323_G711Capability::ALaw));
g711aCap->SetTxFramesInPacket(g711Frames);
- }
+ }
+
+ lastcap++;
+ lastcap = endPoint->SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::HookFlashH245));
+
+ lastcap++;
+ mode = dtmfMode;
+ if (dtmfMode == H323_DTMF_INBAND) {
+ endPoint->SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::SignalToneH245));
+ endPoint->SetSendUserInputMode(H323Connection::SendUserInputAsTone);
+ } else {
+ endPoint->SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::SignalToneRFC2833));
+ endPoint->SetSendUserInputMode(H323Connection::SendUserInputAsInlineRFC2833);
+ }
if (h323debug) {
cout << "Allowed Codecs:\n\t" << setprecision(2) << endPoint->GetCapabilities() << endl;
@@ -1086,7 +1261,7 @@
/** Make a call to the remote endpoint.
*/
-int h323_make_call(char *dest, call_details_t *cd, call_options_t call_options)
+int h323_make_call(char *dest, call_details_t *cd, call_options_t *call_options)
{
int res;
PString token;
@@ -1096,17 +1271,23 @@
return 1;
}
- res = endPoint->MakeCall(host, token, &cd->call_reference, call_options.cid_name, call_options.cid_num);
+ res = endPoint->MakeCall(host, token, &cd->call_reference, call_options);
memcpy((char *)(cd->call_token), (const unsigned char *)token, token.GetLength());
return res;
};
-int h323_clear_call(const char *call_token)
+int h323_clear_call(const char *call_token, int cause)
{
+ H225_ReleaseCompleteReason dummy;
+ H323Connection::CallEndReason r = H323Connection::NumCallEndReasons;
+
if (!h323_end_point_exist()) {
return 1;
}
- endPoint->ClearCall(PString(call_token));
+
+ r = H323TranslateToCallEndReason((Q931::CauseValues)(cause), dummy);
+
+ endPoint->ClearCall(PString(call_token), r);
return 0;
};
@@ -1184,7 +1365,7 @@
{
PString token(data);
BOOL result;
-
+ cout << "Soft hangup" << endl;
result = endPoint->ClearCall(token);
return result;
}
Index: ast_h323.h
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/h323/ast_h323.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- ast_h323.h 11 Nov 2004 21:30:30 -0000 1.29
+++ ast_h323.h 15 Dec 2004 23:24:13 -0000 1.30
@@ -128,7 +128,8 @@
PCLASSINFO(MyH323EndPoint, H323EndPoint);
public:
- int MakeCall(const PString &, PString &, unsigned int *, char *, char *);
+ int MakeCall(const PString &, PString &, unsigned int *, call_options_t *opts);
+ BOOL ClearCall(const PString &, H323Connection::CallEndReason reason);
BOOL ClearCall(const PString &);
void OnClosedLogicalChannel(H323Connection &, const H323Channel &);
@@ -170,6 +171,10 @@
void SendUserInputTone(char, unsigned);
void OnUserInputTone(char, unsigned, unsigned, unsigned);
void OnUserInputString(const PString &value);
+ BOOL OnReceivedProgress(const H323SignalPDU &);
+ void OnSendCapabilitySet(H245_TerminalCapabilitySet &);
+ BOOL OnReceivedCapabilitySet(const H323Capabilities &, const H245_MultiplexCapability *,
+ H245_TerminalCapabilitySetReject &);
PString sourceAliases;
PString destAliases;
@@ -178,6 +183,11 @@
WORD sessionId;
BOOL bridging;
+
+ unsigned progressSetup;
+ unsigned progressAlert;
+
+ RTP_DataFrame::PayloadTypes dtmfCodec;
};
class MyH323_ExternalRTPChannel : public H323_ExternalRTPChannel {
@@ -192,9 +202,10 @@
unsigned sessionID);
~MyH323_ExternalRTPChannel();
-
+
/* Overrides */
BOOL Start(void);
+ BOOL OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param);
protected:
BYTE payloadCode;
Index: chan_h323.h
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/h323/chan_h323.h,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -d -r1.34 -r1.35
--- chan_h323.h 11 Nov 2004 21:35:56 -0000 1.34
+++ chan_h323.h 15 Dec 2004 23:24:13 -0000 1.35
@@ -28,7 +28,20 @@
#include <arpa/inet.h>
-static struct sockaddr_in bindaddr;
+/** call_option struct holds various bits
+ * of information for each call */
+typedef struct call_options {
+ char *cid_num;
+ char *cid_name;
+ int noFastStart;
+ int noH245Tunneling;
+ int noSilenceSuppression;
+ unsigned int port;
+ int progress_setup;
+ int progress_alert;
+ int progress_audio;
+ int dtmfcodec;
+} call_options_t;
/* structure to hold the valid asterisk users */
struct oh323_user {
@@ -38,13 +51,11 @@
char callerid[80];
char accountcode[20];
int amaflags;
- int noFastStart;
- int noH245Tunneling;
- int noSilenceSuppression;
int bridge;
int nat;
int dtmfmode;
int host;
+ call_options_t options;
struct ast_ha *ha;
struct sockaddr_in addr;
struct oh323_user *next;
@@ -56,15 +67,13 @@
char name[80];
char mailbox[80];
int capability;
- int noFastStart;
- int noH245Tunneling;
- int noSilenceSuppression;
int bridge;
int nat;
int dtmfmode;
int delme;
struct sockaddr_in addr;
struct ast_ha *ha;
+ call_options_t options;
struct oh323_peer *next;
};
@@ -79,17 +88,6 @@
struct oh323_alias *next;
};
-/** call_option struct holds various bits
- of information for each call */
-typedef struct call_options {
- char *cid_num;
- char *cid_name;
- int noFastStart;
- int noH245Tunneling;
- int noSilenceSuppression;
- unsigned int port;
-} call_options_t;
-
/** call_details struct call detail records
to asterisk for processing and used for matching up
asterisk channels to acutal h.323 connections */
@@ -124,9 +122,14 @@
typedef void (*start_rtp_cb)(unsigned int, const char *, int, const char *);
extern start_rtp_cb on_start_rtp_channel;
+/* This is a callback that happens when call progress is
+ * made, and handles inband progress */
+typedef int (*progress_cb)(unsigned, const char *, int);
+extern progress_cb on_progress;
+
/* This is a callback prototype function, called upon
an incoming call happens. */
-typedef int (*setup_incoming_cb)(call_details_t);
+typedef call_options_t *(*setup_incoming_cb)(call_details_t);
extern setup_incoming_cb on_incoming_call;
/* This is a callback prototype function, called upon
@@ -154,12 +157,22 @@
typedef int (*answer_call_cb)(unsigned, const char *);
extern answer_call_cb on_answer_call;
+/* This is a callback prototype function, called when
+ we know which RTP payload type RFC2833 will be
+ transmitted */
+typedef void (*rfc2833_cb)(unsigned, const char *, int);
+extern rfc2833_cb on_set_rfc2833_payload;
+
/* debug flag */
extern int h323debug;
#define H323_DTMF_RFC2833 (1 << 0)
#define H323_DTMF_INBAND (1 << 1)
+#ifndef BOOL
+#define BOOL int
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -180,7 +193,9 @@
chan_ringing_cb,
con_established_cb,
send_digit_cb,
- answer_call_cb);
+ answer_call_cb,
+ progress_cb,
+ rfc2833_cb);
int h323_set_capability(int, int);
int h323_set_alias(struct oh323_alias *);
int h323_set_gk(int, char *, char *);
@@ -196,8 +211,8 @@
void h323_send_tone(const char *call_token, char tone);
/* H323 create and destroy sessions */
- int h323_make_call(char *dest, call_details_t *cd, call_options_t);
- int h323_clear_call(const char *);
+ int h323_make_call(char *dest, call_details_t *cd, call_options_t *);
+ int h323_clear_call(const char *, int cause);
/* H.323 alerting and progress */
int h323_send_alerting(const char *token);
More information about the svn-commits
mailing list