Introduce Cisco G.726-32 capability (g726aal2 form)
[asterisk/asterisk.git] / channels / h323 / caps_h323.cxx
1 #include <ptlib.h>
2 #include <h323.h>
3 #include "caps_h323.h"
4
5 #define DEFINE_G711_CAPABILITY(cls, code, capName) \
6 class cls : public AST_G711Capability { \
7 public: \
8         cls() : AST_G711Capability(240, code) { } \
9 }; \
10 H323_REGISTER_CAPABILITY(cls, capName) \
11
12 DEFINE_G711_CAPABILITY(AST_G711ALaw64Capability, H323_G711Capability::ALaw, OPAL_G711_ALAW_64K);
13 DEFINE_G711_CAPABILITY(AST_G711uLaw64Capability, H323_G711Capability::muLaw, OPAL_G711_ULAW_64K);
14 H323_REGISTER_CAPABILITY(AST_G7231Capability, OPAL_G7231);
15 H323_REGISTER_CAPABILITY(AST_G729Capability,  OPAL_G729);
16 H323_REGISTER_CAPABILITY(AST_G729ACapability, OPAL_G729A);
17 H323_REGISTER_CAPABILITY(AST_GSM0610Capability, OPAL_GSM0610);
18 H323_REGISTER_CAPABILITY(AST_CiscoG726Capability, CISCO_G726r32);
19
20 /*
21  * Capability: G.711
22  */
23 AST_G711Capability::AST_G711Capability(int rx_frames, H323_G711Capability::Mode m, H323_G711Capability::Speed s)
24         : H323AudioCapability(rx_frames, 30) // 240ms max, 30ms desired
25 {
26         mode = m;
27         speed = s;
28 }
29
30
31 PObject * AST_G711Capability::Clone() const
32 {
33         return new AST_G711Capability(*this);
34 }
35
36
37 unsigned AST_G711Capability::GetSubType() const
38 {
39         static const unsigned G711SubType[2][2] = {
40                 { H245_AudioCapability::e_g711Alaw64k, H245_AudioCapability::e_g711Alaw56k },
41                 { H245_AudioCapability::e_g711Ulaw64k, H245_AudioCapability::e_g711Ulaw56k }
42         };
43         return G711SubType[mode][speed];
44 }
45
46
47 PString AST_G711Capability::GetFormatName() const
48 {
49         static const char * const G711Name[2][2] = {
50                 { OPAL_G711_ALAW_64K, OPAL_G711_ALAW_56K },
51                 { OPAL_G711_ULAW_64K, OPAL_G711_ULAW_56K },
52         };
53         return G711Name[mode][speed];
54 }
55
56
57 H323Codec * AST_G711Capability::CreateCodec(H323Codec::Direction direction) const
58 {
59         return NULL;
60 }
61
62
63 /*
64  * Capability: G.723.1
65  */
66 AST_G7231Capability::AST_G7231Capability(int rx_frames, BOOL annexA_)
67         : H323AudioCapability(rx_frames, 4)
68 {
69         annexA = annexA_;
70 }
71
72 PObject::Comparison AST_G7231Capability::Compare(const PObject & obj) const
73 {
74         Comparison result = H323AudioCapability::Compare(obj);
75         if (result != EqualTo) {
76                 return result;
77         }
78         PINDEX otherAnnexA = ((const AST_G7231Capability &)obj).annexA;
79         if (annexA < otherAnnexA) {
80                 return LessThan;
81         }
82         if (annexA > otherAnnexA) {
83                 return GreaterThan;
84         }
85         return EqualTo;
86 }
87
88 PObject * AST_G7231Capability::Clone() const
89 {
90         return new AST_G7231Capability(*this);
91 }
92
93 PString AST_G7231Capability::GetFormatName() const
94 {
95         return (annexA ? OPAL_G7231 "A" : OPAL_G7231);
96 }
97
98 unsigned AST_G7231Capability::GetSubType() const
99 {
100         return H245_AudioCapability::e_g7231;
101 }
102
103 BOOL AST_G7231Capability::OnSendingPDU(H245_AudioCapability & cap,
104                                                                                 unsigned packetSize) const
105 {
106         cap.SetTag(H245_AudioCapability::e_g7231);
107         H245_AudioCapability_g7231 & g7231 = cap;
108         g7231.m_maxAl_sduAudioFrames = packetSize;
109         g7231.m_silenceSuppression = annexA;
110         return TRUE;
111 }
112
113 BOOL AST_G7231Capability::OnReceivedPDU(const H245_AudioCapability & cap,
114                                                                                 unsigned & packetSize)
115 {
116         if (cap.GetTag() != H245_AudioCapability::e_g7231) {
117                 return FALSE;
118         }
119         const H245_AudioCapability_g7231 & g7231 = cap;
120         packetSize = g7231.m_maxAl_sduAudioFrames;
121         annexA = g7231.m_silenceSuppression;
122         return TRUE;
123 }
124
125 H323Codec * AST_G7231Capability::CreateCodec(H323Codec::Direction direction) const
126 {
127         return NULL;
128 }
129
130 /*
131  * Capability: G.729
132  */
133 AST_G729Capability::AST_G729Capability(int rx_frames)
134         : H323AudioCapability(rx_frames, 2)
135 {
136 }
137
138 PObject * AST_G729Capability::Clone() const
139 {
140         return new AST_G729Capability(*this);
141 }
142
143 unsigned AST_G729Capability::GetSubType() const
144 {
145         return H245_AudioCapability::e_g729;
146 }
147
148 PString AST_G729Capability::GetFormatName() const
149 {
150         return OPAL_G729;
151 }
152
153 H323Codec * AST_G729Capability::CreateCodec(H323Codec::Direction direction) const
154 {
155         return NULL;
156 }
157
158 /*
159  * Capability: G.729A
160  */
161 AST_G729ACapability::AST_G729ACapability(int rx_frames)
162         : H323AudioCapability(rx_frames, 6)
163 {
164 }
165
166 PObject * AST_G729ACapability::Clone() const
167 {
168         return new AST_G729ACapability(*this);
169 }
170
171 unsigned AST_G729ACapability::GetSubType() const
172 {
173         return H245_AudioCapability::e_g729AnnexA;
174 }
175
176 PString AST_G729ACapability::GetFormatName() const
177 {
178         return OPAL_G729A;
179 }
180
181 H323Codec * AST_G729ACapability::CreateCodec(H323Codec::Direction direction) const
182 {
183         return NULL;
184 }
185
186 /*
187  * Capability: GSM full rate
188  */
189 AST_GSM0610Capability::AST_GSM0610Capability(int rx_frames, int comfortNoise_, int scrambled_)
190         : H323AudioCapability(rx_frames, 2)
191 {
192         comfortNoise = comfortNoise_;
193         scrambled = scrambled_;
194 }
195
196 PObject * AST_GSM0610Capability::Clone() const
197 {
198         return new AST_GSM0610Capability(*this);
199 }
200
201 unsigned AST_GSM0610Capability::GetSubType() const
202 {
203         return H245_AudioCapability::e_gsmFullRate;
204 }
205
206 BOOL AST_GSM0610Capability::OnSendingPDU(H245_AudioCapability & cap,
207                                                                                 unsigned packetSize) const
208 {
209         cap.SetTag(H245_AudioCapability::e_gsmFullRate);
210         H245_GSMAudioCapability & gsm = cap;
211         gsm.m_audioUnitSize = packetSize * 33;
212         gsm.m_comfortNoise = comfortNoise;
213         gsm.m_scrambled = scrambled;
214         return TRUE;
215 }
216
217 BOOL AST_GSM0610Capability::OnReceivedPDU(const H245_AudioCapability & cap,
218                                                                                 unsigned & packetSize)
219 {
220         if (cap.GetTag() != H245_AudioCapability::e_gsmFullRate)
221                 return FALSE;
222         const H245_GSMAudioCapability & gsm = cap;
223         packetSize = (gsm.m_audioUnitSize + 32) / 33;
224         comfortNoise = gsm.m_comfortNoise;
225         scrambled = gsm.m_scrambled;
226
227         return TRUE;
228 }
229
230 PString AST_GSM0610Capability::GetFormatName() const
231 {
232         return OPAL_GSM0610;
233 }
234
235 H323Codec * AST_GSM0610Capability::CreateCodec(H323Codec::Direction direction) const
236 {
237         return NULL;
238 }
239
240 /*
241  * Capability: G.726 32 Kbps
242  */
243 AST_CiscoG726Capability::AST_CiscoG726Capability(int rx_frames)
244         : H323NonStandardAudioCapability(rx_frames, 240,
245                 181, 0, 18,
246                 (const BYTE *)CISCO_G726r32, sizeof(CISCO_G726r32)-1, 0)
247 {
248 }
249
250 PObject *AST_CiscoG726Capability::Clone() const
251 {
252         return new AST_CiscoG726Capability(*this);
253 }
254
255 H323Codec *AST_CiscoG726Capability::CreateCodec(H323Codec::Direction direction) const
256 {
257         return NULL;
258 }
259
260 PString AST_CiscoG726Capability::GetFormatName() const
261 {
262         return PString(CISCO_G726r32);
263 }