diff --git a/channels/chan_h323.c b/channels/chan_h323.c index 529a00b513..cbd017360f 100644 --- a/channels/chan_h323.c +++ b/channels/chan_h323.c @@ -137,7 +137,7 @@ static const char config[] = "h323.conf"; static char default_context[AST_MAX_CONTEXT] = "default"; static struct sockaddr_in bindaddr; -#define GLOBAL_CAPABILITY (AST_FORMAT_G723_1 | AST_FORMAT_GSM | AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_G729A | AST_FORMAT_H261) +#define GLOBAL_CAPABILITY (AST_FORMAT_G723_1 | AST_FORMAT_GSM | AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_G729A | AST_FORMAT_G726_AAL2 | AST_FORMAT_H261) /** H.323 configuration values */ static int h323_signalling_port = 1720; @@ -1902,6 +1902,10 @@ static void setup_rtp_connection(unsigned call_reference, const char *remoteIp, if (!pvt->rtp) __oh323_rtp_create(pvt); + if ((pt == 2) && (pvt->jointcapability & AST_FORMAT_G726_AAL2)) { + ast_rtp_set_rtpmap_type(pvt->rtp, pt, "audio", "G726-32", AST_RTP_OPT_G726_NONSTANDARD); + } + them.sin_family = AF_INET; /* only works for IPv4 */ them.sin_addr.s_addr = inet_addr(remoteIp); diff --git a/channels/h323/ast_h323.cxx b/channels/h323/ast_h323.cxx index 55af0d216e..63b1f18594 100644 --- a/channels/h323/ast_h323.cxx +++ b/channels/h323/ast_h323.cxx @@ -1259,6 +1259,7 @@ BOOL MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remoteCa unsigned int asterisk_codec; unsigned int h245_cap; const char *oid; + const char *formatName; }; static const struct __codec__ codecs[] = { { AST_FORMAT_G723_1, H245_AudioCapability::e_g7231 }, @@ -1267,6 +1268,7 @@ BOOL MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remoteCa { AST_FORMAT_ALAW, H245_AudioCapability::e_g711Alaw64k }, { AST_FORMAT_G729A, H245_AudioCapability::e_g729AnnexA }, { AST_FORMAT_G729A, H245_AudioCapability::e_g729 }, + { AST_FORMAT_G726_AAL2, H245_AudioCapability::e_nonStandard, NULL, CISCO_G726r32 }, #ifdef AST_FORMAT_MODEM { AST_FORMAT_MODEM, H245_DataApplicationCapability_application::e_t38fax }, #endif @@ -1313,7 +1315,7 @@ BOOL MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remoteCa switch(remoteCapabilities[i].GetMainType()) { case H323Capability::e_Audio: for (int x = 0; codecs[x].asterisk_codec > 0; ++x) { - if (subType == codecs[x].h245_cap) { + if ((subType == codecs[x].h245_cap) && (!codecs[x].formatName || (!strcmp(codecs[x].formatName, (const char *)remoteCapabilities[i].GetFormatName())))) { int ast_codec = codecs[x].asterisk_codec; int ms = 0; if (!(peer_capabilities & ast_codec)) { @@ -1495,6 +1497,12 @@ void MyH323Connection::SetCapabilities(int cap, int dtmf_mode, void *_prefs, int if (format.max_ms) g711aCap->SetTxFramesInPacket(format.max_ms); break; + case AST_FORMAT_G726_AAL2: + AST_CiscoG726Capability *g726Cap; + lastcap = localCapabilities.SetCapability(0, 0, g726Cap = new AST_CiscoG726Capability(frames_per_packet)); + if (max_frames_per_packet) + g726Cap->SetTxFramesInPacket(max_frames_per_packet); + break; default: alreadysent &= ~codec; break; diff --git a/channels/h323/caps_h323.cxx b/channels/h323/caps_h323.cxx index 7e9420691f..f200a64716 100644 --- a/channels/h323/caps_h323.cxx +++ b/channels/h323/caps_h323.cxx @@ -4,8 +4,8 @@ #define DEFINE_G711_CAPABILITY(cls, code, capName) \ class cls : public AST_G711Capability { \ - public: \ - cls() : AST_G711Capability(240, code) { } \ +public: \ + cls() : AST_G711Capability(240, code) { } \ }; \ H323_REGISTER_CAPABILITY(cls, capName) \ @@ -15,6 +15,7 @@ H323_REGISTER_CAPABILITY(AST_G7231Capability, OPAL_G7231); 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); /* * Capability: G.711 @@ -235,3 +236,28 @@ H323Codec * AST_GSM0610Capability::CreateCodec(H323Codec::Direction direction) c { return NULL; } + +/* + * Capability: G.726 32 Kbps + */ +AST_CiscoG726Capability::AST_CiscoG726Capability(int rx_frames) + : H323NonStandardAudioCapability(rx_frames, 240, + 181, 0, 18, + (const BYTE *)CISCO_G726r32, sizeof(CISCO_G726r32)-1, 0) +{ +} + +PObject *AST_CiscoG726Capability::Clone() const +{ + return new AST_CiscoG726Capability(*this); +} + +H323Codec *AST_CiscoG726Capability::CreateCodec(H323Codec::Direction direction) const +{ + return NULL; +} + +PString AST_CiscoG726Capability::GetFormatName() const +{ + return PString(CISCO_G726r32); +} diff --git a/channels/h323/caps_h323.h b/channels/h323/caps_h323.h index be63e02300..3238dd5c6b 100644 --- a/channels/h323/caps_h323.h +++ b/channels/h323/caps_h323.h @@ -121,4 +121,23 @@ protected: int comfortNoise; int scrambled; }; + +#define CISCO_G726r32 "G726r32" + +class AST_CiscoG726Capability : public H323NonStandardAudioCapability { + PCLASSINFO(AST_CiscoG726Capability, H323NonStandardAudioCapability); + +public: + /* Create a new Cisco G.726 capability */ + AST_CiscoG726Capability(int rx_frames = 80); + + /* Create a copy of the object. */ + virtual PObject * Clone() const; + + /* Create the codec instance, allocating resources as required. */ + virtual H323Codec * CreateCodec(H323Codec::Direction direction) const; + + /* Get the name of the media data format this class represents. */ + virtual PString GetFormatName() const; +}; #endif /* __AST_H323CAPS_H */