summaryrefslogtreecommitdiff
path: root/channels/h323/ast_h323.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'channels/h323/ast_h323.cpp')
-rwxr-xr-xchannels/h323/ast_h323.cpp253
1 files changed, 217 insertions, 36 deletions
diff --git a/channels/h323/ast_h323.cpp b/channels/h323/ast_h323.cpp
index 6abfff932..616b7381b 100755
--- a/channels/h323/ast_h323.cpp
+++ b/channels/h323/ast_h323.cpp
@@ -156,7 +156,7 @@ H323Codec * H323_G7231Capability::CreateCodec(H323Codec::Direction direction) co
}
AST_G729Capability::AST_G729Capability()
- : H323AudioCapability(24, 6)
+ : H323AudioCapability(24, 2)
{
}
@@ -213,7 +213,7 @@ H323Codec * AST_G729ACapability::CreateCodec(H323Codec::Direction direction) con
* 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 @@ int MyH323EndPoint::MakeCall(const PString & dest, PString & token, unsigned int
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 @@ int MyH323EndPoint::MakeCall(const PString & dest, PString & token, unsigned int
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 @@ H323Capabilities MyH323EndPoint::GetCapabilities(void)
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 @@ MyH323Connection::~MyH323Connection()
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 @@ BOOL MyH323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU)
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 @@ BOOL MyH323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU)
}
return FALSE;
}
+
+ progressSetup = res->progress_setup;
+ progressAlert = res->progress_alert;
+ dtmfCodec = (RTP_DataFrame::PayloadTypes)res->dtmfcodec;
+
+
return H323Connection::OnReceivedSignalSetup(setupPDU);
}
@@ -646,6 +739,10 @@ BOOL MyH323Connection::OnSendSignalSetup(H323SignalPDU & setupPDU)
}
return FALSE;
}
+
+ if (progressSetup) {
+ setupPDU.GetQ931().SetProgressIndicator(progressSetup);
+ }
return H323Connection::OnSendSignalSetup(setupPDU);
}
@@ -711,6 +808,50 @@ void MyH323Connection::OnUserInputString(const PString &value)
}
}
+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 @@ BOOL MyH323_ExternalRTPChannel::Start(void)
}
/* 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 @@ BOOL MyH323_ExternalRTPChannel::Start(void)
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 @@ void h323_callback_register(setup_incoming_cb ifunc,
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 @@ void h323_callback_register(setup_incoming_cb ifunc,
on_connection_established = efunc;
on_send_digit = dfunc;
on_answer_call = acfunc;
+ on_progress = pgfunc;
+ on_set_rfc2833_payload = dtmffunc;
}
/**
@@ -879,8 +1046,9 @@ int h323_set_capability(int cap, int dtmfMode)
{
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 @@ int h323_set_capability(int cap, int dtmfMode)
}
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 @@ int h323_set_capability(int cap, int dtmfMode)
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 @@ void h323_send_tone(const char *call_token, char tone)
/** 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 @@ int h323_make_call(char *dest, call_details_t *cd, call_options_t call_options)
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 @@ int h323_soft_hangup(const char *data)
{
PString token(data);
BOOL result;
-
+ cout << "Soft hangup" << endl;
result = endPoint->ClearCall(token);
return result;
}