mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-29 18:19:30 +00:00
Support for negotiation and receiption of Cisco's RTP DTMF
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@43597 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -184,7 +184,7 @@ struct oh323_pvt {
|
||||
int peercapability; /* Capabilities learned from peer */
|
||||
int jointcapability; /* Common capabilities for local and remote side */
|
||||
struct ast_codec_pref peer_prefs; /* Preferenced list of codecs which remote side supports */
|
||||
int dtmf_pt; /* Payload code used for RFC2833 messages */
|
||||
int dtmf_pt[2]; /* Payload code used for RFC2833/CISCO messages */
|
||||
int curDTMF; /* DTMF tone being generated to Asterisk side */
|
||||
int DTMFsched; /* Scheduler descriptor for DTMF */
|
||||
int update_rtp_info; /* Configuration of fd's array is pending */
|
||||
@@ -515,7 +515,9 @@ static int oh323_digit_begin(struct ast_channel *c, char digit)
|
||||
return -1;
|
||||
}
|
||||
ast_mutex_lock(&pvt->lock);
|
||||
if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) {
|
||||
if (pvt->rtp &&
|
||||
(((pvt->options.dtmfmode & H323_DTMF_RFC2833) && pvt->dtmf_pt[0])
|
||||
/*|| ((pvt->options.dtmfmode & H323_DTMF_CISCO) && pvt->dtmf_pt[1]))*/)) {
|
||||
/* out-of-band DTMF */
|
||||
if (h323debug) {
|
||||
ast_log(LOG_DTMF, "Begin sending out-of-band digit %c on %s\n", digit, c->name);
|
||||
@@ -554,7 +556,7 @@ static int oh323_digit_end(struct ast_channel *c, char digit)
|
||||
return -1;
|
||||
}
|
||||
ast_mutex_lock(&pvt->lock);
|
||||
if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) {
|
||||
if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && ((pvt->dtmf_pt[0] > 0) || (pvt->dtmf_pt[0] > 0))) {
|
||||
/* out-of-band DTMF */
|
||||
if (h323debug) {
|
||||
ast_log(LOG_DTMF, "End sending out-of-band digit %c on %s\n", digit, c->name);
|
||||
@@ -644,7 +646,7 @@ static int oh323_call(struct ast_channel *c, char *dest, int timeout)
|
||||
pvt->outgoing = 1;
|
||||
|
||||
if (h323debug)
|
||||
ast_log(LOG_DEBUG, "Placing outgoing call to %s, %d\n", called_addr, pvt->options.dtmfcodec);
|
||||
ast_log(LOG_DEBUG, "Placing outgoing call to %s, %d/%d\n", called_addr, pvt->options.dtmfcodec[0], pvt->options.dtmfcodec[1]);
|
||||
ast_mutex_unlock(&pvt->lock);
|
||||
res = h323_make_call(called_addr, &(pvt->cd), &pvt->options);
|
||||
if (res) {
|
||||
@@ -757,7 +759,7 @@ static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
|
||||
|
||||
f = ast_rtp_read(pvt->rtp);
|
||||
/* Don't send RFC2833 if we're not supposed to */
|
||||
if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->options.dtmfmode & H323_DTMF_RFC2833)) {
|
||||
if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->options.dtmfmode & (H323_DTMF_RFC2833 | H323_DTMF_CISCO))) {
|
||||
return &ast_null_frame;
|
||||
}
|
||||
if (pvt->owner) {
|
||||
@@ -979,8 +981,10 @@ static int __oh323_rtp_create(struct oh323_pvt *pvt)
|
||||
ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat);
|
||||
ast_rtp_setnat(pvt->rtp, pvt->options.nat);
|
||||
|
||||
if (pvt->dtmf_pt > 0)
|
||||
ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt, "audio", "telephone-event", 0);
|
||||
if (pvt->dtmf_pt[0] > 0)
|
||||
ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt[0], "audio", "telephone-event", 0);
|
||||
if (pvt->dtmf_pt[1] > 0)
|
||||
ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt[1], "audio", "cisco-telephone-event", 0);
|
||||
|
||||
if (pvt->peercapability)
|
||||
ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs);
|
||||
@@ -1121,7 +1125,7 @@ static struct oh323_pvt *oh323_alloc(int callid)
|
||||
}
|
||||
memcpy(&pvt->options, &global_options, sizeof(pvt->options));
|
||||
pvt->jointcapability = pvt->options.capability;
|
||||
if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
|
||||
if (pvt->options.dtmfmode & (H323_DTMF_RFC2833 | H323_DTMF_CISCO)) {
|
||||
pvt->nonCodecCapability |= AST_RTP_DTMF;
|
||||
} else {
|
||||
pvt->nonCodecCapability &= ~AST_RTP_DTMF;
|
||||
@@ -1263,18 +1267,28 @@ static int update_common_options(struct ast_variable *v, struct call_options *op
|
||||
options->dtmfmode |= H323_DTMF_INBAND;
|
||||
} else if (!strcasecmp(val, "rfc2833")) {
|
||||
options->dtmfmode |= H323_DTMF_RFC2833;
|
||||
if (!opt)
|
||||
options->dtmfcodec = H323_DTMF_RFC2833_PT;
|
||||
else if ((tmp >= 96) && (tmp < 128))
|
||||
options->dtmfcodec = tmp;
|
||||
else {
|
||||
options->dtmfcodec = H323_DTMF_RFC2833_PT;
|
||||
ast_log(LOG_WARNING, "Unknown rfc2833 payload %s specified at line %d, using default %d\n", opt, v->lineno, options->dtmfcodec);
|
||||
if (!opt) {
|
||||
options->dtmfcodec[0] = H323_DTMF_RFC2833_PT;
|
||||
} else if ((tmp >= 96) && (tmp < 128)) {
|
||||
options->dtmfcodec[0] = tmp;
|
||||
} else {
|
||||
options->dtmfcodec[0] = H323_DTMF_RFC2833_PT;
|
||||
ast_log(LOG_WARNING, "Unknown rfc2833 payload %s specified at line %d, using default %d\n", opt, v->lineno, options->dtmfcodec[0]);
|
||||
}
|
||||
} else if (!strcasecmp(val, "cisco")) {
|
||||
options->dtmfmode |= H323_DTMF_CISCO;
|
||||
if (!opt) {
|
||||
options->dtmfcodec[1] = H323_DTMF_CISCO_PT;
|
||||
} else if ((tmp >= 96) && (tmp < 128)) {
|
||||
options->dtmfcodec[1] = tmp;
|
||||
} else {
|
||||
options->dtmfcodec[1] = H323_DTMF_CISCO_PT;
|
||||
ast_log(LOG_WARNING, "Unknown Cisco DTMF payload %s specified at line %d, using default %d\n", opt, v->lineno, options->dtmfcodec[1]);
|
||||
}
|
||||
} else if (!strcasecmp(v->value, "h245-signal")) {
|
||||
options->dtmfmode |= H323_DTMF_SIGNAL;
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value);
|
||||
options->dtmfmode |= H323_DTMF_RFC2833;
|
||||
options->dtmfcodec = H323_DTMF_RFC2833_PT;
|
||||
ast_log(LOG_WARNING, "Unknown dtmf mode '%s' at line %d\n", v->value, v->lineno);
|
||||
}
|
||||
} else if (!strcasecmp(v->name, "dtmfcodec")) {
|
||||
ast_log(LOG_NOTICE, "Option %s at line %d is deprecated. Use dtmfmode=rfc2833[:<payload>] instead.\n", v->name, v->lineno);
|
||||
@@ -1282,7 +1296,7 @@ static int update_common_options(struct ast_variable *v, struct call_options *op
|
||||
if (tmp < 96)
|
||||
ast_log(LOG_WARNING, "Invalid %s value %s at line %d\n", v->name, v->value, v->lineno);
|
||||
else
|
||||
options->dtmfcodec = tmp;
|
||||
options->dtmfcodec[0] = tmp;
|
||||
} else if (!strcasecmp(v->name, "bridge")) {
|
||||
options->bridge = ast_true(v->value);
|
||||
} else if (!strcasecmp(v->name, "nat")) {
|
||||
@@ -2367,21 +2381,21 @@ static void hangup_connection(unsigned int call_reference, const char *token, in
|
||||
ast_mutex_unlock(&pvt->lock);
|
||||
}
|
||||
|
||||
static void set_dtmf_payload(unsigned call_reference, const char *token, int payload)
|
||||
static void set_dtmf_payload(unsigned call_reference, const char *token, int payload, int is_cisco)
|
||||
{
|
||||
struct oh323_pvt *pvt;
|
||||
|
||||
if (h323debug)
|
||||
ast_log(LOG_DEBUG, "Setting DTMF payload to %d on %s\n", payload, token);
|
||||
ast_log(LOG_DEBUG, "Setting %s DTMF payload to %d on %s\n", (is_cisco ? "Cisco" : "RFC2833"), payload, token);
|
||||
|
||||
pvt = find_call_locked(call_reference, token);
|
||||
if (!pvt) {
|
||||
return;
|
||||
}
|
||||
if (pvt->rtp) {
|
||||
ast_rtp_set_rtpmap_type(pvt->rtp, payload, "audio", "telephone-event", 0);
|
||||
ast_rtp_set_rtpmap_type(pvt->rtp, payload, "audio", (is_cisco ? "cisco-telephone-event" : "telephone-event"), 0);
|
||||
}
|
||||
pvt->dtmf_pt = payload;
|
||||
pvt->dtmf_pt[is_cisco ? 1 : 0] = payload;
|
||||
ast_mutex_unlock(&pvt->lock);
|
||||
if (h323debug)
|
||||
ast_log(LOG_DEBUG, "DTMF payload on %s set to %d\n", token, payload);
|
||||
@@ -2750,7 +2764,8 @@ static int reload_config(int is_reload)
|
||||
memset(&global_options, 0, sizeof(global_options));
|
||||
global_options.fastStart = 1;
|
||||
global_options.h245Tunneling = 1;
|
||||
global_options.dtmfcodec = H323_DTMF_RFC2833_PT;
|
||||
global_options.dtmfcodec[0] = H323_DTMF_RFC2833_PT;
|
||||
global_options.dtmfcodec[1] = H323_DTMF_CISCO_PT;
|
||||
global_options.dtmfmode = 0;
|
||||
global_options.capability = GLOBAL_CAPABILITY;
|
||||
global_options.bridge = 1; /* Do native bridging by default */
|
||||
|
@@ -533,7 +533,7 @@ MyH323Connection::MyH323Connection(MyH323EndPoint & ep, unsigned callReference,
|
||||
bridging = FALSE;
|
||||
progressSetup = progressAlert = 0;
|
||||
dtmfMode = 0;
|
||||
dtmfCodec = (RTP_DataFrame::PayloadTypes)0;
|
||||
dtmfCodec[0] = dtmfCodec[1] = (RTP_DataFrame::PayloadTypes)0;
|
||||
redirect_reason = -1;
|
||||
#ifdef TUNNELLING
|
||||
tunnelOptions = remoteTunnelOptions = 0;
|
||||
@@ -664,7 +664,8 @@ void MyH323Connection::SetCallOptions(void *o, BOOL isIncoming)
|
||||
|
||||
progressSetup = opts->progress_setup;
|
||||
progressAlert = opts->progress_alert;
|
||||
dtmfCodec = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec;
|
||||
dtmfCodec[0] = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec[0];
|
||||
dtmfCodec[1] = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec[1];
|
||||
dtmfMode = opts->dtmfmode;
|
||||
|
||||
if (isIncoming) {
|
||||
@@ -1213,7 +1214,8 @@ void MyH323Connection::SendUserInputTone(char tone, unsigned duration, unsigned
|
||||
|
||||
void MyH323Connection::OnUserInputTone(char tone, unsigned duration, unsigned logicalChannel, unsigned rtpTimestamp)
|
||||
{
|
||||
if ((dtmfMode & H323_DTMF_RFC2833)) {
|
||||
/* Why we should check this? */
|
||||
if ((dtmfMode & (H323_DTMF_CISCO | H323_DTMF_RFC2833 | H323_DTMF_SIGNAL)) != 0) {
|
||||
if (h323debug) {
|
||||
cout << "\t-- Received user input tone (" << tone << ") from remote" << endl;
|
||||
}
|
||||
@@ -1243,10 +1245,10 @@ void MyH323Connection::OnSendCapabilitySet(H245_TerminalCapabilitySet & pdu)
|
||||
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);
|
||||
atec.m_dynamicRTPPayloadType = dtmfCodec[0];
|
||||
// on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)dtmfCodec[0]);
|
||||
if (h323debug) {
|
||||
cout << "\t-- Transmitting RFC2833 on payload " <<
|
||||
cout << "\t-- Receiving RFC2833 on payload " <<
|
||||
atec.m_dynamicRTPPayloadType << endl;
|
||||
}
|
||||
}
|
||||
@@ -1299,21 +1301,12 @@ BOOL MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remoteCa
|
||||
};
|
||||
#endif
|
||||
struct ast_codec_pref prefs;
|
||||
RTP_DataFrame::PayloadTypes pt;
|
||||
|
||||
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 ((dtmfMode & H323_DTMF_RFC2833) && (sendUserInputMode == SendUserInputAsTone))
|
||||
sendUserInputMode = SendUserInputAsInlineRFC2833;
|
||||
if (h323debug) {
|
||||
cout << "\t-- Inbound RFC2833 on payload " << pt << endl;
|
||||
}
|
||||
}
|
||||
memset(&prefs, 0, sizeof(prefs));
|
||||
int peer_capabilities = 0;
|
||||
for (int i = 0; i < remoteCapabilities.GetSize(); ++i) {
|
||||
@@ -1346,6 +1339,32 @@ BOOL MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remoteCa
|
||||
}
|
||||
}
|
||||
break;
|
||||
case H323Capability::e_Data:
|
||||
if (!strcmp((const char *)remoteCapabilities[i].GetFormatName(), CISCO_DTMF_RELAY)) {
|
||||
pt = remoteCapabilities[i].GetPayloadType();
|
||||
if ((dtmfMode & H323_DTMF_CISCO) != 0) {
|
||||
on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)pt, 1);
|
||||
// if (sendUserInputMode == SendUserInputAsTone)
|
||||
// sendUserInputMode = SendUserInputAsInlineRFC2833;
|
||||
}
|
||||
if (h323debug) {
|
||||
cout << "\t-- Outbound Cisco RTP DTMF on payload " << pt << endl;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case H323Capability::e_UserInput:
|
||||
if (!strcmp((const char *)remoteCapabilities[i].GetFormatName(), H323_UserInputCapability::SubTypeNames[H323_UserInputCapability::SignalToneRFC2833])) {
|
||||
pt = remoteCapabilities[i].GetPayloadType();
|
||||
if ((dtmfMode & H323_DTMF_RFC2833) != 0) {
|
||||
on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)pt, 0);
|
||||
// if (sendUserInputMode == SendUserInputAsTone)
|
||||
// sendUserInputMode = SendUserInputAsInlineRFC2833;
|
||||
}
|
||||
if (h323debug) {
|
||||
cout << "\t-- Outbound RFC2833 on payload " << pt << endl;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
case H323Capability::e_Video:
|
||||
for (int x = 0; vcodecs[x].asterisk_codec > 0; ++x) {
|
||||
@@ -1416,7 +1435,7 @@ BOOL MyH323Connection::OnStartLogicalChannel(H323Channel & channel)
|
||||
return connectionState != ShuttingDownConnection;
|
||||
}
|
||||
|
||||
void MyH323Connection::SetCapabilities(int cap, int dtmf_mode, void *_prefs, int pref_codec)
|
||||
void MyH323Connection::SetCapabilities(int caps, int dtmf_mode, void *_prefs, int pref_codec)
|
||||
{
|
||||
PINDEX lastcap = -1; /* last common capability index */
|
||||
int alreadysent = 0;
|
||||
@@ -1427,11 +1446,12 @@ void MyH323Connection::SetCapabilities(int cap, int dtmf_mode, void *_prefs, int
|
||||
struct ast_format_list format;
|
||||
int frames_per_packet;
|
||||
int max_frames_per_packet;
|
||||
H323Capability *cap;
|
||||
|
||||
localCapabilities.RemoveAll();
|
||||
|
||||
if (h323debug) {
|
||||
cout << "Setting capabilities to " << ast_getformatname_multiple(caps_str, sizeof(caps_str), cap) << endl;
|
||||
cout << "Setting capabilities to " << ast_getformatname_multiple(caps_str, sizeof(caps_str), caps) << endl;
|
||||
ast_codec_pref_string(prefs, caps_str, sizeof(caps_str));
|
||||
cout << "Capabilities in preference order is " << caps_str << endl;
|
||||
}
|
||||
@@ -1449,7 +1469,7 @@ void MyH323Connection::SetCapabilities(int cap, int dtmf_mode, void *_prefs, int
|
||||
y <<= 1;
|
||||
codec = y;
|
||||
}
|
||||
if (!(cap & codec) || (alreadysent & codec) || !(codec & AST_FORMAT_AUDIO_MASK))
|
||||
if (!(caps & codec) || (alreadysent & codec) || !(codec & AST_FORMAT_AUDIO_MASK))
|
||||
continue;
|
||||
alreadysent |= codec;
|
||||
format = ast_codec_pref_getsize(prefs, codec);
|
||||
@@ -1518,23 +1538,64 @@ void MyH323Connection::SetCapabilities(int cap, int dtmf_mode, void *_prefs, int
|
||||
}
|
||||
}
|
||||
|
||||
lastcap++;
|
||||
lastcap = localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::HookFlashH245));
|
||||
cap = new H323_UserInputCapability(H323_UserInputCapability::HookFlashH245);
|
||||
if (cap && cap->IsUsable(*this)) {
|
||||
lastcap++;
|
||||
lastcap = localCapabilities.SetCapability(0, lastcap, cap);
|
||||
} else if (cap)
|
||||
delete cap; /* Capability is not usable */
|
||||
|
||||
lastcap++;
|
||||
dtmfMode = dtmf_mode;
|
||||
if ((dtmfMode & H323_DTMF_INBAND)) {
|
||||
localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::BasicString));
|
||||
sendUserInputMode = SendUserInputAsString;
|
||||
} else {
|
||||
lastcap = localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::SignalToneRFC2833));
|
||||
/* Cisco sends DTMF only through h245-alphanumeric or h245-signal, no support for RFC2833 */
|
||||
lastcap = localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::SignalToneH245));
|
||||
sendUserInputMode = SendUserInputAsTone; /* RFC2833 transmission handled at Asterisk level */
|
||||
if (h323debug) {
|
||||
cout << "DTMF mode is " << (int)dtmfMode << endl;
|
||||
}
|
||||
if (dtmfMode) {
|
||||
lastcap++;
|
||||
if (dtmfMode == H323_DTMF_INBAND) {
|
||||
cap = new H323_UserInputCapability(H323_UserInputCapability::BasicString);
|
||||
if (cap && cap->IsUsable(*this)) {
|
||||
lastcap = localCapabilities.SetCapability(0, lastcap, cap);
|
||||
} else if (cap)
|
||||
delete cap; /* Capability is not usable */
|
||||
sendUserInputMode = SendUserInputAsString;
|
||||
} else {
|
||||
if ((dtmfMode & H323_DTMF_RFC2833) != 0) {
|
||||
cap = new H323_UserInputCapability(H323_UserInputCapability::SignalToneRFC2833);
|
||||
if (cap && cap->IsUsable(*this))
|
||||
lastcap = localCapabilities.SetCapability(0, lastcap, cap);
|
||||
else {
|
||||
dtmfMode |= H323_DTMF_SIGNAL;
|
||||
if (cap)
|
||||
delete cap; /* Capability is not usable */
|
||||
}
|
||||
}
|
||||
if ((dtmfMode & H323_DTMF_CISCO) != 0) {
|
||||
/* Try Cisco's RTP DTMF relay too, but prefer RFC2833 or h245-signal */
|
||||
cap = new AST_CiscoDtmfCapability();
|
||||
if (cap && cap->IsUsable(*this)) {
|
||||
lastcap = localCapabilities.SetCapability(0, lastcap, cap);
|
||||
/* We cannot send Cisco RTP DTMFs, use h245-signal instead */
|
||||
dtmfMode |= H323_DTMF_SIGNAL;
|
||||
} else {
|
||||
dtmfMode |= H323_DTMF_SIGNAL;
|
||||
if (cap)
|
||||
delete cap; /* Capability is not usable */
|
||||
}
|
||||
}
|
||||
if ((dtmfMode & H323_DTMF_SIGNAL) != 0) {
|
||||
/* Cisco usually sends DTMF correctly only through h245-alphanumeric or h245-signal */
|
||||
cap = new H323_UserInputCapability(H323_UserInputCapability::SignalToneH245);
|
||||
if (cap && cap->IsUsable(*this))
|
||||
lastcap = localCapabilities.SetCapability(0, lastcap, cap);
|
||||
else if (cap)
|
||||
delete cap; /* Capability is not usable */
|
||||
}
|
||||
sendUserInputMode = SendUserInputAsTone; /* RFC2833 transmission handled at Asterisk level */
|
||||
}
|
||||
}
|
||||
|
||||
if (h323debug) {
|
||||
cout << "Allowed Codecs:\n\t" << setprecision(2) << localCapabilities << endl;
|
||||
cout << "Allowed Codecs for " << GetCallToken() << " (" << GetSignallingChannel()->GetLocalAddress() << "):\n\t" << setprecision(2) << localCapabilities << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -112,7 +112,7 @@ public:
|
||||
unsigned progressAlert;
|
||||
int cause;
|
||||
|
||||
RTP_DataFrame::PayloadTypes dtmfCodec;
|
||||
RTP_DataFrame::PayloadTypes dtmfCodec[2];
|
||||
int dtmfMode;
|
||||
};
|
||||
|
||||
|
@@ -18,6 +18,7 @@ H323_REGISTER_CAPABILITY(AST_G729Capability, OPAL_G729);
|
||||
H323_REGISTER_CAPABILITY(AST_G729ACapability, OPAL_G729A);
|
||||
H323_REGISTER_CAPABILITY(AST_GSM0610Capability, OPAL_GSM0610);
|
||||
H323_REGISTER_CAPABILITY(AST_CiscoG726Capability, CISCO_G726r32);
|
||||
H323_REGISTER_CAPABILITY(AST_CiscoDtmfCapability, CISCO_DTMF_RELAY);
|
||||
|
||||
OPAL_MEDIA_FORMAT_DECLARE(OpalG711ALaw64kFormat,
|
||||
OPAL_G711_ALAW_64K,
|
||||
@@ -99,6 +100,18 @@ OPAL_MEDIA_FORMAT_DECLARE(OpalCiscoG726Format,
|
||||
8, // 1 millisecond
|
||||
OpalMediaFormat::AudioTimeUnits,
|
||||
0);
|
||||
#if 0
|
||||
OPAL_MEDIA_FORMAT_DECLARE(OpalCiscoDTMFRelayFormat,
|
||||
CISCO_DTMF_RELAY,
|
||||
OpalMediaFormat::DefaultAudioSessionID,
|
||||
(RTP_DataFrame::PayloadTypes)121, // Choose this for Cisco IOS compatibility
|
||||
TRUE, // Needs jitter
|
||||
100, // bits/sec
|
||||
4, // bytes/frame
|
||||
8*150, // 150 millisecond
|
||||
OpalMediaFormat::AudioTimeUnits,
|
||||
0);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Capability: G.711
|
||||
|
@@ -52,7 +52,7 @@ typedef struct call_options {
|
||||
int progress_setup;
|
||||
int progress_alert;
|
||||
int progress_audio;
|
||||
int dtmfcodec;
|
||||
int dtmfcodec[2];
|
||||
int dtmfmode;
|
||||
int capability;
|
||||
int bridge;
|
||||
@@ -172,7 +172,7 @@ 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);
|
||||
typedef void (*rfc2833_cb)(unsigned, const char *, int, int);
|
||||
extern rfc2833_cb on_set_rfc2833_payload;
|
||||
|
||||
typedef void (*hangup_cb)(unsigned, const char *, int);
|
||||
@@ -188,7 +188,9 @@ extern setpeercapabilities_cb on_setpeercapabilities;
|
||||
extern int h323debug;
|
||||
|
||||
#define H323_DTMF_RFC2833 (1 << 0)
|
||||
#define H323_DTMF_INBAND (1 << 1)
|
||||
#define H323_DTMF_CISCO (1 << 1)
|
||||
#define H323_DTMF_SIGNAL (1 << 2)
|
||||
#define H323_DTMF_INBAND (1 << 3)
|
||||
|
||||
#define H323_DTMF_RFC2833_PT 101
|
||||
#define H323_DTMF_CISCO_PT 121
|
||||
|
@@ -28,7 +28,7 @@ port = 1720
|
||||
;
|
||||
; User-Input Mode (DTMF)
|
||||
;
|
||||
; valid entries are: rfc2833, inband
|
||||
; valid entries are: rfc2833, inband, cisco, h245-signal
|
||||
; default is rfc2833
|
||||
;dtmfmode=rfc2833
|
||||
;
|
||||
@@ -38,6 +38,8 @@ port = 1720
|
||||
; To specify required payload type, put it after colon in dtmfmode
|
||||
; option like
|
||||
;dtmfmode=rfc2833:101
|
||||
; or
|
||||
;dtmfmode=cisco:121
|
||||
;
|
||||
; Set the gatekeeper
|
||||
; DISCOVER - Find the Gk address using multicast
|
||||
|
Reference in New Issue
Block a user