Merged revisions 317837 via svnmerge from
[asterisk/asterisk.git] / addons / ooh323c / src / ooCapability.c
1 /*
2  * Copyright (C) 2004-2005 by Objective Systems, Inc.
3  *
4  * This software is furnished under an open source license and may be 
5  * used and copied only in accordance with the terms of this license. 
6  * The text of the license may generally be found in the root 
7  * directory of this installation in the COPYING file.  It 
8  * can also be viewed online at the following URL:
9  *
10  *   http://www.obj-sys.com/open/license.html
11  *
12  * Any redistributions of this file including modified versions must 
13  * maintain this copyright notice.
14  *
15  *****************************************************************************/
16 #include "asterisk.h"
17 #include "asterisk/lock.h"
18
19 #include "ooCapability.h"
20 #include "ootrace.h"
21 #include "ooCalls.h"
22 #include "ooh323ep.h"
23 #include "ooUtils.h"
24 /** Global endpoint structure */
25 extern OOH323EndPoint gH323ep;
26
27 static int giDynamicRTPPayloadType = 101;
28 static int gcDynamicRTPPayloadType = 121;
29
30 int ooCapabilityEnableDTMFRFC2833
31    (OOH323CallData *call, int dynamicRTPPayloadType)
32 {
33    if(!call)
34    {
35       gH323ep.dtmfmode |= OO_CAP_DTMF_RFC2833;
36       OOTRACEINFO1("Enabled RFC2833 DTMF capability for end-point\n");
37       /*Dynamic RTP payload type range is from 96 - 127 */
38       if(dynamicRTPPayloadType >= 96 && dynamicRTPPayloadType <= 127)
39         giDynamicRTPPayloadType = dynamicRTPPayloadType;
40    }
41    else{
42       call->dtmfmode |= OO_CAP_DTMF_RFC2833;
43       OOTRACEINFO3("Enabled RFC2833 DTMF capability for (%s, %s) \n", 
44                    call->callType, call->callToken);
45    if(dynamicRTPPayloadType >= 96 && dynamicRTPPayloadType <= 127)
46       call->dtmfcodec = dynamicRTPPayloadType;
47    else
48       call->dtmfcodec = giDynamicRTPPayloadType;
49    }
50
51
52    return OO_OK;
53 }
54
55 int ooCapabilityEnableDTMFCISCO
56    (OOH323CallData *call, int dynamicRTPPayloadType)
57 {
58    if(!call)
59    {
60       gH323ep.dtmfmode |= OO_CAP_DTMF_CISCO;
61       OOTRACEINFO1("Enabled RTP/CISCO DTMF capability for end-point\n");
62       /*Dynamic RTP payload type range is from 96 - 127 */
63       if(dynamicRTPPayloadType >= 96 && dynamicRTPPayloadType <= 127)
64         gcDynamicRTPPayloadType = dynamicRTPPayloadType;
65       else
66         call->dtmfcodec = dynamicRTPPayloadType;
67    }
68    else{
69       call->dtmfmode |= OO_CAP_DTMF_CISCO;
70       OOTRACEINFO3("Enabled RTP/CISCO DTMF capability for (%s, %s) \n", 
71                    call->callType, call->callToken);
72    if(dynamicRTPPayloadType >= 96 && dynamicRTPPayloadType <= 127)
73       call->dtmfcodec = dynamicRTPPayloadType;
74    else
75       call->dtmfcodec = gcDynamicRTPPayloadType;
76    }
77
78
79    return OO_OK;
80 }
81
82
83
84 int ooCapabilityDisableDTMFRFC2833(OOH323CallData *call)
85 {
86    if(!call){
87       gH323ep.dtmfmode ^= OO_CAP_DTMF_RFC2833;
88       OOTRACEINFO1("Disabled RFC2833 DTMF capability for end-point\n");
89    }
90    else{
91       call->dtmfmode ^= OO_CAP_DTMF_RFC2833;
92       OOTRACEINFO3("Disabled RFC2833 DTMF capability for (%s, %s)\n", 
93                     call->callType, call->callToken);
94    }
95
96    return OO_OK;
97 }
98
99 int ooCapabilityDisableDTMFCISCO(OOH323CallData *call)
100 {
101    if(!call){
102       gH323ep.dtmfmode ^= OO_CAP_DTMF_CISCO;
103       OOTRACEINFO1("Disabled RTP/CISCO DTMF capability for end-point\n");
104    }
105    else{
106       call->dtmfmode ^= OO_CAP_DTMF_CISCO;
107       OOTRACEINFO3("Disabled RTP/CISCO DTMF capability for (%s, %s)\n", 
108                     call->callType, call->callToken);
109    }
110
111    return OO_OK;
112 }
113
114 int ooCapabilityEnableDTMFH245Alphanumeric(OOH323CallData *call)
115 {
116    if(!call){
117       gH323ep.dtmfmode |= OO_CAP_DTMF_H245_alphanumeric;
118       OOTRACEINFO1("Dtmf mode set to H.245(alphanumeric) for endpoint\n");
119    }
120    else {
121       call->dtmfmode |= OO_CAP_DTMF_H245_alphanumeric;
122       OOTRACEINFO3("Dtmf mode set to H.245(alphanumeric) for (%s, %s)\n", 
123                     call->callType, call->callToken);
124    }
125    return OO_OK;
126 }
127
128 int ooCapabilityDisableDTMFH245Alphanumeric(OOH323CallData *call)
129 {
130    if(!call){
131       gH323ep.dtmfmode ^= OO_CAP_DTMF_H245_alphanumeric;
132       OOTRACEINFO1("Dtmf mode H.245(alphanumeric) disabled for endpoint\n");
133    }
134    else {
135       call->dtmfmode ^= OO_CAP_DTMF_H245_alphanumeric;
136       OOTRACEINFO3("Dtmf mode H.245(alphanumeric) disabled for (%s, %s)\n", 
137                     call->callType, call->callToken);
138    }
139    return OO_OK;
140 }
141
142 int ooCapabilityEnableDTMFH245Signal(OOH323CallData *call)
143 {
144    if(!call){
145       gH323ep.dtmfmode |= OO_CAP_DTMF_H245_signal;
146       OOTRACEINFO1("Dtmf mode set to H.245(signal) for endpoint\n");
147    }
148    else {
149       call->dtmfmode |= OO_CAP_DTMF_H245_signal;
150       OOTRACEINFO3("Dtmf mode set to H.245(signal) for (%s, %s)\n", 
151                     call->callType, call->callToken);
152    }
153    return OO_OK;
154 }
155
156 int ooCapabilityDisableDTMFH245Signal(OOH323CallData *call)
157 {
158    if(!call){
159       gH323ep.dtmfmode ^= OO_CAP_DTMF_H245_signal;
160       OOTRACEINFO1("Dtmf mode H.245(signal) disabled for endpoint\n");
161    }
162    else {
163       call->dtmfmode ^= OO_CAP_DTMF_H245_signal;
164       OOTRACEINFO3("Dtmf mode H.245(signal) disabled for (%s, %s)\n", 
165                     call->callType, call->callToken);
166    }
167    return OO_OK;
168 }
169
170 int ooCapabilityEnableDTMFQ931Keypad(struct OOH323CallData *call)
171 {
172    if(!call){
173       gH323ep.dtmfmode |= OO_CAP_DTMF_Q931;
174       OOTRACEINFO1("Dtmf mode set to Q.931(keypad) for the endpoint\n");
175    }
176    else {
177       call->dtmfmode |= OO_CAP_DTMF_Q931;
178       OOTRACEINFO3("Dtmf mode set to Q.931(keypad) for the call (%s, %s)\n", 
179                     call->callType, call->callToken);
180    }
181    return OO_OK;
182 }
183
184 int ooCapabilityDisableDTMFQ931Keypad(struct OOH323CallData *call)
185 {
186    if(!call){
187       gH323ep.dtmfmode ^= OO_CAP_DTMF_Q931;
188       OOTRACEINFO1("Dtmf mode Q.931(keypad) disabled for the endpoint\n");
189    }
190    else {
191       call->dtmfmode ^= OO_CAP_DTMF_Q931;
192       OOTRACEINFO3("Dtmf mode Q.931(keypad) disabled for the call (%s, %s)\n", 
193                     call->callType, call->callToken);
194    }
195    return OO_OK;
196 }
197
198 int ooCapabilityAddH263VideoCapability(ooCallData *call, 
199                               unsigned sqcifMPI, unsigned qcifMPI, 
200                               unsigned cifMPI, unsigned cif4MPI, 
201                               unsigned cif16MPI, unsigned maxBitRate, int dir, 
202                               cb_StartReceiveChannel startReceiveChannel,
203                               cb_StartTransmitChannel startTransmitChannel,
204                               cb_StopReceiveChannel stopReceiveChannel,
205                               cb_StopTransmitChannel stopTransmitChannel, 
206                               OOBOOL remote)
207 {
208    int ret = OO_OK;
209    if(sqcifMPI>0)
210    {
211       ret = ooCapabilityAddH263VideoCapability_helper(call, sqcifMPI, 0, 
212                                  0, 0, 0, maxBitRate, dir, startReceiveChannel,
213                                  startTransmitChannel, stopReceiveChannel,
214                                  stopTransmitChannel, remote);
215       if(ret != OO_OK)
216       {
217          OOTRACEERR1("Error: Failed to add H263 sqcifMPI capability\n");
218          return OO_FAILED;
219       }
220    }
221    if(qcifMPI>0)
222    {
223       ret = ooCapabilityAddH263VideoCapability_helper(call, 0, qcifMPI, 0,
224                                  0, 0, maxBitRate, dir, startReceiveChannel,
225                                  startTransmitChannel, stopReceiveChannel,
226                                  stopTransmitChannel, remote);
227       if(ret != OO_OK)
228       {
229          OOTRACEERR1("Error: Failed to add H263 qcifMPI capability\n");
230          return OO_FAILED;
231       }
232    }
233    if(cifMPI>0)
234    {
235       ret = ooCapabilityAddH263VideoCapability_helper(call, 0, 0, cifMPI, 
236                                  0, 0, maxBitRate, dir, startReceiveChannel,
237                                  startTransmitChannel, stopReceiveChannel,
238                                  stopTransmitChannel, remote);
239       if(ret != OO_OK)
240       {
241          OOTRACEERR1("Error: Failed to add H263 cifMPI capability\n");
242          return OO_FAILED;
243       }
244    }
245    if(cif4MPI>0)
246    {
247       ret = ooCapabilityAddH263VideoCapability_helper(call, 0, 0, 0, 
248                                  cif4MPI, 0, maxBitRate, dir, 
249                                  startReceiveChannel,
250                                  startTransmitChannel, stopReceiveChannel,
251                                  stopTransmitChannel, remote);
252       if(ret != OO_OK)
253       {
254          OOTRACEERR1("Error: Failed to add H263 cif4MPI capability\n");
255          return OO_FAILED;
256       }
257    }
258    if(cif16MPI>0)
259    {
260       ret = ooCapabilityAddH263VideoCapability_helper(call, dir, 0, 0, 0, 0, 
261                                  cif16MPI, maxBitRate, startReceiveChannel,
262                                  startTransmitChannel, stopReceiveChannel,
263                                  stopTransmitChannel, remote);
264       if(ret != OO_OK)
265       {
266          OOTRACEERR1("Error: Failed to add H263 cif16MPI capability\n");
267          return OO_FAILED;
268       }
269    }
270    return OO_OK;
271
272 }
273
274 int ooCapabilityAddH263VideoCapability_helper(ooCallData *call,
275                               unsigned sqcifMPI, unsigned qcifMPI, 
276                               unsigned cifMPI, unsigned cif4MPI, 
277                               unsigned cif16MPI, unsigned maxBitRate, int dir, 
278                               cb_StartReceiveChannel startReceiveChannel,
279                               cb_StartTransmitChannel startTransmitChannel,
280                               cb_StopReceiveChannel stopReceiveChannel,
281                               cb_StopTransmitChannel stopTransmitChannel, 
282                               OOBOOL remote)
283 {
284
285    ooH323EpCapability *epCap = NULL, *cur=NULL;
286    OOH263CapParams *params=NULL;   
287    OOCTXT *pctxt=NULL;
288    char *pictureType = NULL;
289    int cap = OO_H263VIDEO;
290
291    if(!call) pctxt = &gH323ep.ctxt;
292    else pctxt = call->pctxt;
293
294    epCap = (ooH323EpCapability*)memAllocZ(pctxt, sizeof(ooH323EpCapability));
295    params = (OOH263CapParams*) memAllocZ(pctxt, sizeof(OOH263CapParams));
296    if(!epCap || !params)
297    {
298       OOTRACEERR1("Error:Memory - ooCapabilityAddH263Capability - epCap/params"
299                   ".\n");
300       return OO_FAILED;
301    }
302    
303    if(sqcifMPI>0)
304    {
305       params->MPI = sqcifMPI;
306       params->picFormat = OO_PICFORMAT_SQCIF;
307       pictureType = "SQCIF";
308    }
309    if(qcifMPI>0)
310    {
311       params->MPI = qcifMPI;
312       params->picFormat =  OO_PICFORMAT_QCIF;
313       pictureType = "QCIF";
314    }
315    if(cifMPI>0)
316    {
317       params->MPI = cifMPI;
318       params->picFormat = OO_PICFORMAT_CIF;
319       pictureType = "CIF";
320    }
321    if(cif4MPI>0)
322    {
323       params->MPI = cif4MPI;
324       params->picFormat = OO_PICFORMAT_CIF4;
325       pictureType = "CIF4";
326    }
327    if(cif16MPI>0)
328    {
329       params->MPI = cif16MPI;
330       params->picFormat = OO_PICFORMAT_CIF16;
331       pictureType = "CIF16";
332    }
333
334    params->maxBitRate = maxBitRate;
335
336
337    if(dir & OORXANDTX)
338    {
339       epCap->dir = OORX;
340       epCap->dir |= OOTX;
341    }
342    else
343       epCap->dir = dir;
344    
345    epCap->cap = OO_H263VIDEO;
346    epCap->capType = OO_CAP_TYPE_VIDEO;
347    epCap->params = (void*)params;
348    epCap->startReceiveChannel = startReceiveChannel;
349    epCap->startTransmitChannel = startTransmitChannel;
350    epCap->stopReceiveChannel = stopReceiveChannel;
351    epCap->stopTransmitChannel = stopTransmitChannel;
352    
353    epCap->next = NULL;
354
355    if(!call)
356    {/*Add as local capability */
357       OOTRACEDBGC2("Adding endpoint H263 video capability %s.\n", pictureType);
358       if(!gH323ep.myCaps)
359          gH323ep.myCaps = epCap;
360       else{
361          cur = gH323ep.myCaps;
362          while(cur->next) cur = cur->next;
363          cur->next = epCap;
364       }
365       ooAppendCapToCapPrefs(NULL, cap);
366       gH323ep.noOfCaps++;
367    }
368    else{
369       if(remote)
370       {
371          /*Add as remote capability */
372          if(!call->remoteCaps)
373             call->remoteCaps = epCap;
374          else{
375             cur = call->remoteCaps;
376             while(cur->next) cur = cur->next;
377             cur->next = epCap;
378          }
379      }
380      else{
381         /*Add as our capability */
382         OOTRACEDBGC4("Adding call specific H263 video capability %s. "
383                      "(%s, %s)\n", pictureType, call->callType, 
384                      call->callToken);
385         if(!call->ourCaps){
386            call->ourCaps = epCap;
387            ooResetCapPrefs(call);
388         }else{
389            cur = call->ourCaps;
390            while(cur->next) cur = cur->next;
391            cur->next = epCap;
392         }
393         ooAppendCapToCapPrefs(call, cap);
394      }
395    }
396
397    return OO_OK;
398 }
399
400 /* Used for g711 ulaw/alaw, g728, g729 and g7231 */
401 int ooCapabilityAddSimpleCapability
402    (OOH323CallData *call, int cap, int txframes, 
403     int rxframes, OOBOOL silenceSuppression, int dir, 
404     cb_StartReceiveChannel startReceiveChannel,
405     cb_StartTransmitChannel startTransmitChannel,
406     cb_StopReceiveChannel stopReceiveChannel,
407     cb_StopTransmitChannel stopTransmitChannel,
408     OOBOOL remote)
409 {
410    ooH323EpCapability *epCap = NULL, *cur=NULL;
411    OOCapParams *params=NULL;   
412    OOCTXT *pctxt=NULL;
413    if(!call) pctxt = &gH323ep.ctxt;
414    else pctxt = call->pctxt;
415
416    epCap = (ooH323EpCapability*)memAlloc(pctxt, sizeof(ooH323EpCapability));
417    params = (OOCapParams*) memAlloc(pctxt, sizeof(OOCapParams));
418    if(!epCap || !params)
419    {
420       OOTRACEERR1("ERROR: Memory - ooCapabilityAddSimpleCapability - "
421                   "epCap/params\n");
422       return OO_FAILED;
423    }
424
425
426    params->txframes = txframes;
427    params->rxframes = rxframes;
428    /* Ignore silence suppression parameter unless cap is g7231 */
429    if(cap == OO_G7231)
430       params->silenceSuppression = silenceSuppression;
431    else
432       params->silenceSuppression = FALSE; /* Set to false for g711 and g729*/
433
434    if(dir & OORXANDTX) {
435       epCap->dir = OORX;
436       epCap->dir |= OOTX;
437    }
438    else {
439       epCap->dir = dir;
440    }
441    
442    epCap->cap = cap;
443    epCap->capType = OO_CAP_TYPE_AUDIO;
444    epCap->params = (void*)params;
445    epCap->startReceiveChannel = startReceiveChannel;
446    epCap->startTransmitChannel = startTransmitChannel;
447    epCap->stopReceiveChannel = stopReceiveChannel;
448    epCap->stopTransmitChannel = stopTransmitChannel;
449    epCap->next = NULL;
450
451    if(!call)
452    {
453       /* Add as local capability */
454       OOTRACEDBGC2("Adding endpoint capability %s. \n", 
455                      ooGetCapTypeText(epCap->cap));
456       if(!gH323ep.myCaps) {
457          gH323ep.myCaps = epCap;
458       }
459       else{
460          cur = gH323ep.myCaps;
461          while(cur->next) cur = cur->next;
462          cur->next = epCap;
463       }
464       ooAppendCapToCapPrefs(NULL, cap);
465       gH323ep.noOfCaps++;
466    }
467    else{
468       if(remote)
469       {
470          /* Add as remote capability */
471          if(!call->remoteCaps) {
472             call->remoteCaps = epCap;
473          }
474          else{
475             cur = call->remoteCaps;
476             while(cur->next) cur = cur->next;
477             cur->next = epCap;
478          }
479       }
480       else{
481          /* Add as our capability */
482          OOTRACEDBGC4("Adding call specific capability %s. (%s, %s)\n", 
483                       ooGetCapTypeText(epCap->cap), call->callType, 
484                       call->callToken);
485          if(!call->ourCaps){
486             call->ourCaps = epCap;
487             ooResetCapPrefs(call);
488          }
489          else{
490             cur = call->ourCaps;
491             while(cur->next) cur = cur->next;
492             cur->next = epCap;
493          }
494          ooAppendCapToCapPrefs(call, cap);
495       }
496    }
497            
498    return OO_OK;
499 }
500
501 int epCapIsPreferred(OOH323CallData *call, ooH323EpCapability *epCap)
502 {
503  ooH323EpCapability *curCap = call->ourCaps;
504  while (curCap) {
505   if (curCap->capType == epCap->capType) {
506    if (curCap->cap == epCap->cap)
507     return 1;
508    else
509     return 0;
510    }
511    curCap = curCap->next;
512  }
513  return 0;
514 }
515
516 int ooCapabilityAddGSMCapability(OOH323CallData *call, int cap, 
517                                 unsigned framesPerPkt, OOBOOL comfortNoise,
518                                 OOBOOL scrambled, int dir, 
519                                 cb_StartReceiveChannel startReceiveChannel,
520                                 cb_StartTransmitChannel startTransmitChannel,
521                                 cb_StopReceiveChannel stopReceiveChannel,
522                                 cb_StopTransmitChannel stopTransmitChannel, 
523                                 OOBOOL remote)
524 {
525
526    ooH323EpCapability *epCap = NULL, *cur=NULL;
527    OOGSMCapParams *params=NULL;   
528    OOCTXT *pctxt = NULL;
529  
530    if(!call) pctxt = &gH323ep.ctxt;
531    else pctxt = call->pctxt;
532
533    epCap = (ooH323EpCapability*)memAlloc(pctxt, sizeof(ooH323EpCapability));
534    params = (OOGSMCapParams*) memAlloc(pctxt, sizeof(OOGSMCapParams));
535    if(!epCap || !params)
536    {
537       OOTRACEERR1("Error:Memory - ooCapabilityAddGSMCapability - "
538                   "epCap/params\n");
539       return OO_FAILED;
540    }
541
542
543    params->rxframes = framesPerPkt;
544    params->txframes = framesPerPkt;
545    params->comfortNoise = comfortNoise;
546    params->scrambled = scrambled;
547    if(dir & OORXANDTX)
548    {
549       epCap->dir = OORX;
550       epCap->dir |= OOTX;
551    }
552    else
553       epCap->dir = dir;
554
555    epCap->cap = cap;
556    epCap->capType = OO_CAP_TYPE_AUDIO;
557    epCap->params = (void*)params;
558    epCap->startReceiveChannel = startReceiveChannel;
559    epCap->startTransmitChannel = startTransmitChannel;
560    epCap->stopReceiveChannel = stopReceiveChannel;
561    epCap->stopTransmitChannel = stopTransmitChannel;
562    
563    epCap->next = NULL;
564    /* Add as local capability */
565    if(!call)
566    {
567       if(!gH323ep.myCaps)
568          gH323ep.myCaps = epCap;
569       else{
570          cur = gH323ep.myCaps;
571          while(cur->next) cur = cur->next;
572          cur->next = epCap;
573       }
574       ooAppendCapToCapPrefs(NULL, cap);
575       gH323ep.noOfCaps++;
576    }
577    else{
578       if(remote)
579       {
580          /*Add as remote capability */
581          if(!call->remoteCaps)
582             call->remoteCaps = epCap;
583          else{
584             cur = call->remoteCaps;
585             while(cur->next) cur = cur->next;
586             cur->next = epCap;
587          }
588       }
589       else{
590          OOTRACEDBGC4("Adding call specific capability %s. (%s, %s)\n", 
591                      ooGetCapTypeText(epCap->cap), call->callType, 
592                      call->callToken);
593          /*Add as our capability */
594          if(!call->ourCaps){
595             call->ourCaps = epCap;
596             ooResetCapPrefs(call);
597          }
598          else{
599             cur = call->ourCaps;
600             while(cur->next) cur = cur->next;
601             cur->next = epCap;
602          }
603          ooAppendCapToCapPrefs(call, cap);
604       }
605    }
606
607    return OO_OK;
608 }
609
610 /* Used for T38 */
611 int ooCapabilityAddT38Capability
612    (OOH323CallData *call, int cap, int dir,
613     cb_StartReceiveChannel startReceiveChannel,
614     cb_StartTransmitChannel startTransmitChannel,
615     cb_StopReceiveChannel stopReceiveChannel,
616     cb_StopTransmitChannel stopTransmitChannel,
617     OOBOOL remote)
618 {
619    ooH323EpCapability *epCap = NULL, *cur=NULL;
620    OOCapParams *params=NULL;   
621    OOCTXT *pctxt=NULL;
622    if(!call) pctxt = &gH323ep.ctxt;
623    else pctxt = call->pctxt;
624
625    epCap = (ooH323EpCapability*)memAllocZ(pctxt, sizeof(ooH323EpCapability));
626    params = (OOCapParams*) memAlloc(pctxt, sizeof(OOCapParams));
627    memset(params, 0 , sizeof(OOCapParams));
628    if(!epCap || !params)
629    {
630       OOTRACEERR1("ERROR: Memory - ooCapabilityAddT38Capability - "
631                   "epCap/params\n");
632       return OO_FAILED;
633    }
634
635    if(dir & OORXANDTX) {
636       epCap->dir = OORX;
637       epCap->dir |= OOTX;
638    }
639    else {
640       epCap->dir = dir;
641    }
642    
643    epCap->cap = cap;
644    epCap->capType = OO_CAP_TYPE_DATA;
645    epCap->params = (void*)params;
646    epCap->startReceiveChannel = startReceiveChannel;
647    epCap->startTransmitChannel = startTransmitChannel;
648    epCap->stopReceiveChannel = stopReceiveChannel;
649    epCap->stopTransmitChannel = stopTransmitChannel;
650    epCap->next = NULL;
651
652    if(!call)
653    {
654       /* Add as local capability */
655       OOTRACEDBGC2("Adding endpoint capability %s. \n", 
656                      ooGetCapTypeText(epCap->cap));
657       if(!gH323ep.myCaps) {
658          gH323ep.myCaps = epCap;
659       }
660       else{
661          cur = gH323ep.myCaps;
662          while(cur->next) cur = cur->next;
663          cur->next = epCap;
664       }
665       ooAppendCapToCapPrefs(NULL, cap);
666       gH323ep.noOfCaps++;
667    }
668    else{
669       if(remote)
670       {
671          /* Add as remote capability */
672          if(!call->remoteCaps) {
673             call->remoteCaps = epCap;
674          }
675          else{
676             cur = call->remoteCaps;
677             while(cur->next) cur = cur->next;
678             cur->next = epCap;
679          }
680          call->t38sides |= 2;
681       }
682       else{
683          /* Add as our capability */
684          OOTRACEDBGC4("Adding call specific capability %s. (%s, %s)\n", 
685                       ooGetCapTypeText(epCap->cap), call->callType, 
686                       call->callToken);
687          if(!call->ourCaps){
688             call->ourCaps = epCap;
689             ooResetCapPrefs(call);
690          }
691          else{
692             cur = call->ourCaps;
693             while(cur->next) cur = cur->next;
694             cur->next = epCap;
695          }
696          ooAppendCapToCapPrefs(call, cap);
697          call->t38sides |= 1;
698       }
699    }
700            
701    return OO_OK;
702 }
703
704
705
706
707 struct H245VideoCapability* ooCapabilityCreateVideoCapability
708       (ooH323EpCapability *epCap, OOCTXT *pctxt, int dir)
709 {
710
711    if(!epCap)
712    {
713      OOTRACEERR1("Error:Invalid capability parameter passed to "
714                  "ooCapabilityCreateVideoCapability.\n");
715      return NULL;
716    }
717    
718    if(!(epCap->dir & dir))
719    {
720       OOTRACEERR1("Error:Failed to create capability due to direction "
721                   "mismatch.\n");
722       return NULL;
723    }
724
725    switch(epCap->cap)
726    {
727    case OO_H263VIDEO:
728      return ooCapabilityCreateH263VideoCapability(epCap, pctxt, dir);
729
730    case OO_NONSTDVIDEO:
731    case OO_H261VIDEO:
732    case OO_H262VIDEO:
733    case OO_IS11172VIDEO:
734    case OO_GENERICVIDEO:
735    case OO_EXTELEMVIDEO:
736    default:
737       OOTRACEERR2("ERROR: Don't know how to create video capability %s\n",
738                   ooGetCapTypeText(epCap->cap));
739    }
740    return NULL;
741 }
742
743
744    
745 struct H245AudioCapability* ooCapabilityCreateAudioCapability
746       (ooH323EpCapability *epCap, OOCTXT *pctxt, int dir)
747 {
748
749    if(!epCap)
750    {
751      OOTRACEERR1("Error:Invalid capability parameter passed to "
752                  "ooCapabilityCreateAudioCapability.\n");
753      return NULL;
754    }
755    
756    if(!(epCap->dir & dir))
757    {
758       OOTRACEERR1("Error:Failed to create capability due to direction "
759                   "mismatch.\n");
760       return NULL;
761    }
762
763    switch(epCap->cap)
764    {
765    case OO_G711ALAW64K:
766    case OO_G711ALAW56K:
767    case OO_G711ULAW64K:
768    case OO_G711ULAW56K:
769    case OO_G728:
770    case OO_G729:
771    case OO_G729A:
772    case OO_G729B:
773    case OO_G7231:
774      return ooCapabilityCreateSimpleCapability(epCap, pctxt, dir);
775    case OO_G726:
776    case OO_G726AAL2:
777    case OO_AMRNB:
778    case OO_SPEEX:
779      return ooCapabilityCreateNonStandardCapability(epCap, pctxt, dir);
780    case OO_GSMHALFRATE:
781    case OO_GSMENHANCEDFULLRATE:
782    case OO_GSMFULLRATE:
783       return ooCapabilityCreateGSMFullRateCapability(epCap, pctxt, dir);
784    default:
785       OOTRACEERR2("ERROR: Don't know how to create audio capability %d\n",
786                   epCap->cap);
787    }
788    return NULL;
789 }
790
791
792
793 void* ooCapabilityCreateDTMFCapability(int cap, int dtmfcodec, OOCTXT *pctxt)
794 {
795    H245AudioTelephonyEventCapability *pATECap=NULL;
796    H245DataApplicationCapability *pCSDTMFCap=NULL;
797    H245UserInputCapability *userInput = NULL;
798    char *events=NULL;
799    switch(cap)
800    {
801    case OO_CAP_DTMF_RFC2833:
802       pATECap = (H245AudioTelephonyEventCapability*)memAlloc(pctxt, 
803                                    sizeof(H245AudioTelephonyEventCapability));
804       if(!pATECap)
805       {
806          OOTRACEERR1("Error:Memory - ooCapabilityCreateDTMFCapability - pATECap\n");
807          return NULL;
808       }
809       memset(pATECap, 0, sizeof(H245AudioTelephonyEventCapability));
810       pATECap->dynamicRTPPayloadType = dtmfcodec;
811       events = (char*)memAlloc(pctxt, strlen("0-16")+1);
812       memset(events, 0, strlen("0-16")+1);
813       if(!events)
814       {
815          OOTRACEERR1("Error:Memory - ooCapabilityCreateDTMFCapability - events\n");
816          memFreePtr(pctxt, pATECap);
817          return NULL;
818       }
819       strncpy(events, "0-16", strlen("0-16"));
820       pATECap->audioTelephoneEvent = events;
821       return pATECap;
822    case OO_CAP_DTMF_CISCO:
823       pCSDTMFCap = (H245DataApplicationCapability*)memAlloc(pctxt, 
824                                    sizeof(H245DataApplicationCapability));
825       if(!pCSDTMFCap)
826       {
827          OOTRACEERR1("Error:Memory - ooCapabilityCreateDTMFCapability - pCSDTMFCap\n");
828          return NULL;
829       }
830       memset(pCSDTMFCap, 0, sizeof(H245DataApplicationCapability));
831       pCSDTMFCap->application.t = T_H245DataApplicationCapability_application_nonStandard;
832       if ( (pCSDTMFCap->application.u.nonStandard = (H245NonStandardParameter *)
833                 memAllocZ(pctxt, sizeof(H245NonStandardParameter))) == NULL) {
834         OOTRACEERR1("Error:Memory-ooCapabilityCreateDTMFCapability-H245NonStandardParameter\n");
835         memFreePtr(pctxt, pCSDTMFCap);
836         return NULL;
837       }
838
839       pCSDTMFCap->application.u.nonStandard->nonStandardIdentifier.t=T_H245NonStandardIdentifier_h221NonStandard;
840       pCSDTMFCap->application.u.nonStandard->nonStandardIdentifier.u.h221NonStandard =
841         (H245NonStandardIdentifier_h221NonStandard *) memAllocZ(pctxt,
842         sizeof(H245NonStandardIdentifier_h221NonStandard));
843       if (!pCSDTMFCap->application.u.nonStandard->nonStandardIdentifier.u.h221NonStandard) {
844          OOTRACEERR1("Error:Memory-ooCapabilityCreateDTMFCapability-H245NonStandardParameter\n");
845          memFreePtr(pctxt, pCSDTMFCap);
846          return NULL;
847       }
848
849       pCSDTMFCap->application.u.nonStandard->data.data = (unsigned char*)"RtpDtmfRelay";
850       pCSDTMFCap->application.u.nonStandard->data.numocts = sizeof("RtpDtmfRelay")-1;
851       pCSDTMFCap->application.u.nonStandard->nonStandardIdentifier.u.h221NonStandard->t35CountryCode = 181;
852       pCSDTMFCap->application.u.nonStandard->nonStandardIdentifier.u.h221NonStandard->t35Extension = 0;
853       pCSDTMFCap->application.u.nonStandard->nonStandardIdentifier.u.h221NonStandard->manufacturerCode = 18;
854       
855       return pCSDTMFCap;
856    case OO_CAP_DTMF_H245_alphanumeric:
857       userInput = (H245UserInputCapability*)memAllocZ(pctxt, 
858                                           sizeof(H245UserInputCapability));
859       if(!userInput)
860       {
861          OOTRACEERR1("Error:Memory - ooCapabilityCreateDTMFCapability - "
862                      "userInput\n");
863          return NULL;
864       }
865       userInput->t = T_H245UserInputCapability_basicString;
866       return userInput;
867    case OO_CAP_DTMF_H245_signal:
868       userInput = (H245UserInputCapability*)memAllocZ(pctxt, 
869                                           sizeof(H245UserInputCapability));
870       if(!userInput)
871       {
872          OOTRACEERR1("Error:Memory - ooCapabilityCreateDTMFCapability - "
873                      "userInput\n");
874          return NULL;
875       }
876       userInput->t = T_H245UserInputCapability_dtmf;
877       return userInput;
878    default:
879      OOTRACEERR1("Error:unknown dtmf capability type\n");
880    }
881    return NULL;
882 }
883
884
885
886 struct H245VideoCapability* ooCapabilityCreateH263VideoCapability
887    (ooH323EpCapability *epCap, OOCTXT* pctxt, int dir)
888 {
889    H245VideoCapability *pVideo=NULL;
890    OOH263CapParams *params=NULL;
891    H245H263VideoCapability *pH263Cap=NULL;
892
893    if(!epCap || !epCap->params)
894    {
895      OOTRACEERR1("Error:Invalid capability parameters to "
896                  "ooCapabilityCreateH263VideoCapability.\n");
897      return NULL;
898    }
899    params =(OOH263CapParams*)epCap->params;
900
901    pVideo = (H245VideoCapability*)memAllocZ(pctxt, 
902                                                   sizeof(H245VideoCapability));
903    pH263Cap = (H245H263VideoCapability*) memAllocZ(pctxt, 
904                                              sizeof(H245H263VideoCapability));
905    if(!pVideo || !pH263Cap)
906    {
907       OOTRACEERR1("ERROR:Memory - ooCapabilityCreateH263VideoCapability - "
908                   "pVideo/pH263Cap\n");
909       return NULL;
910    }
911
912    pVideo->t = T_H245VideoCapability_h263VideoCapability;
913    pVideo->u.h263VideoCapability = pH263Cap;
914
915
916    if(params->picFormat ==  OO_PICFORMAT_SQCIF) {
917       pH263Cap->m.sqcifMPIPresent = TRUE;
918       pH263Cap->sqcifMPI = params->MPI;
919    }
920    else if(params->picFormat == OO_PICFORMAT_QCIF) {
921       pH263Cap->m.qcifMPIPresent = TRUE;
922       pH263Cap->qcifMPI = params->MPI;
923    }
924    else if(params->picFormat == OO_PICFORMAT_CIF) {
925       pH263Cap->m.cifMPIPresent = TRUE;
926       pH263Cap->cifMPI = params->MPI;
927    }
928    else if(params->picFormat == OO_PICFORMAT_CIF4) {
929       pH263Cap->m.cif4MPIPresent  = TRUE;
930       pH263Cap->cif4MPI = params->MPI;
931    }
932    else if(params->picFormat == OO_PICFORMAT_CIF16) {
933       pH263Cap->m.cif16MPIPresent = TRUE;
934       pH263Cap->cif16MPI = params->MPI;
935    }
936
937    pH263Cap->m.errorCompensationPresent = TRUE;
938    pH263Cap->maxBitRate = params->maxBitRate;
939    pH263Cap->unrestrictedVector = FALSE;
940    pH263Cap->arithmeticCoding = FALSE;
941    pH263Cap->advancedPrediction = FALSE;
942    pH263Cap->pbFrames = FALSE;
943    pH263Cap->temporalSpatialTradeOffCapability = FALSE;
944    pH263Cap->hrd_B = 0;
945    pH263Cap->bppMaxKb = 0;
946    pH263Cap->slowSqcifMPI = FALSE;
947    pH263Cap->slowQcifMPI = FALSE;
948    pH263Cap->slowCifMPI = FALSE;
949    pH263Cap->slowCif4MPI = FALSE;
950    pH263Cap->slowCif16MPI = FALSE;
951    pH263Cap->errorCompensation = FALSE;
952    return pVideo;
953 }
954
955 struct H245AudioCapability* ooCapabilityCreateGSMFullRateCapability
956    (ooH323EpCapability *epCap, OOCTXT* pctxt, int dir)
957 {
958    H245AudioCapability *pAudio=NULL;
959    H245GSMAudioCapability *pGSMCap=NULL;
960    if(!epCap || !epCap->params)
961    {
962      OOTRACEERR1("Error:Invalid capability parameters to "
963                  "ooCapabilityCreateGSMFullRateCapability.\n");
964      return NULL;
965    }
966
967    pAudio = (H245AudioCapability*)memAlloc(pctxt, 
968                                                 sizeof(H245AudioCapability));
969    pGSMCap = (H245GSMAudioCapability*)memAlloc(pctxt, 
970                                               sizeof(H245GSMAudioCapability));
971    if(!pAudio || !pGSMCap)
972    {
973       OOTRACEERR1("ERROR:Memory - ooCapabilityCreateGSMFullRateCapability - "
974                   "pAudio/pGSMCap\n");
975       return NULL;
976    }
977    switch (epCap->cap) {
978     case OO_GSMHALFRATE:
979         pAudio->t = T_H245AudioCapability_gsmHalfRate;
980         break;
981     case OO_GSMENHANCEDFULLRATE:
982         pAudio->t = T_H245AudioCapability_gsmEnhancedFullRate;
983         break;
984     default:
985         pAudio->t = T_H245AudioCapability_gsmFullRate;
986    }
987    pAudio->u.gsmFullRate = pGSMCap;
988    if(dir & OORX)
989       pGSMCap->audioUnitSize = ((OOGSMCapParams*)epCap->params)->rxframes*OO_GSMFRAMESIZE;
990    else
991       pGSMCap->audioUnitSize = ((OOGSMCapParams*)epCap->params)->txframes*OO_GSMFRAMESIZE;
992  
993    pGSMCap->comfortNoise = ((OOGSMCapParams*)epCap->params)->comfortNoise;
994    pGSMCap->scrambled = ((OOGSMCapParams*)epCap->params)->scrambled;
995
996    return pAudio;
997 }
998
999 /* This is used for g711 ulaw/alaw, g728, g729, g729A, g7231*/
1000 struct H245AudioCapability* ooCapabilityCreateSimpleCapability
1001    (ooH323EpCapability *epCap, OOCTXT* pctxt, int dir)
1002 {
1003    H245AudioCapability *pAudio=NULL;
1004    OOCapParams *params;
1005    if(!epCap || !epCap->params)
1006    {
1007      OOTRACEERR1("Error:Invalid capability parameters to "
1008                  "ooCapabilityCreateSimpleCapability.\n");
1009      return NULL;
1010    }
1011    params =(OOCapParams*)epCap->params;
1012    pAudio = (H245AudioCapability*)memAlloc(pctxt, 
1013                                                 sizeof(H245AudioCapability));
1014    if(!pAudio)
1015    {
1016       OOTRACEERR1("ERROR:Memory - ooCapabilityCreateSimpleCapability - pAudio\n");
1017       return NULL;
1018    }
1019
1020    
1021    switch(epCap->cap)
1022    {
1023    case OO_G711ALAW64K:
1024       pAudio->t = T_H245AudioCapability_g711Alaw64k;
1025       if(dir & OORX)
1026          pAudio->u.g711Alaw64k = params->rxframes;
1027       else
1028          pAudio->u.g711Alaw64k = params->txframes;
1029       return pAudio;
1030    case OO_G711ALAW56K:
1031       pAudio->t = T_H245AudioCapability_g711Alaw56k;
1032       if(dir & OORX)
1033          pAudio->u.g711Alaw56k = params->rxframes;
1034       else
1035          pAudio->u.g711Alaw56k = params->txframes; 
1036       return pAudio;
1037    case OO_G711ULAW64K:
1038       pAudio->t = T_H245AudioCapability_g711Ulaw64k;
1039       if(dir & OORX)
1040          pAudio->u.g711Ulaw64k = params->rxframes;
1041       else
1042          pAudio->u.g711Ulaw64k = params->txframes;
1043       return pAudio;
1044    case OO_G711ULAW56K:
1045       pAudio->t = T_H245AudioCapability_g711Ulaw56k;
1046       if(dir & OORX)
1047          pAudio->u.g711Ulaw56k = params->rxframes;
1048       else
1049          pAudio->u.g711Ulaw64k = params->txframes;
1050       return pAudio;
1051    case OO_G728:
1052       pAudio->t = T_H245AudioCapability_g728;
1053       if(dir & OORX)
1054          pAudio->u.g728 = params->rxframes;
1055       else
1056          pAudio->u.g728 = params->txframes;
1057       return pAudio;
1058    case OO_G729:
1059       pAudio->t = T_H245AudioCapability_g729;
1060       if(dir & OORX)
1061          pAudio->u.g729 = params->rxframes;
1062       else
1063          pAudio->u.g729 = params->txframes;
1064       return pAudio;
1065    case OO_G729A:
1066       pAudio->t = T_H245AudioCapability_g729AnnexA;
1067       if(dir & OORX)
1068          pAudio->u.g729AnnexA = params->rxframes;
1069       else
1070          pAudio->u.g729AnnexA = params->txframes;
1071       return pAudio;
1072    case OO_G729B:
1073       pAudio->t = T_H245AudioCapability_g729wAnnexB;
1074       if(dir & OORX)
1075          pAudio->u.g729AnnexA = params->rxframes;
1076       else
1077          pAudio->u.g729AnnexA = params->txframes;
1078       return pAudio;
1079    case OO_G7231:
1080       pAudio->t = T_H245AudioCapability_g7231;
1081       pAudio->u.g7231 = (H245AudioCapability_g7231*)memAlloc(pctxt, 
1082                                            sizeof(H245AudioCapability_g7231));
1083       if(!pAudio->u.g7231)
1084       {
1085          OOTRACEERR1("Error:Memory - ooCapabilityCreateSimpleCapability - g7231\n");
1086          memFreePtr(pctxt, pAudio);
1087          return NULL;
1088       }
1089       pAudio->u.g7231->silenceSuppression = params->silenceSuppression;
1090       if(dir & OORX)
1091          pAudio->u.g7231->maxAl_sduAudioFrames = params->rxframes;
1092       else
1093          pAudio->u.g7231->maxAl_sduAudioFrames = params->txframes;
1094       return pAudio;
1095
1096    default:
1097       OOTRACEERR2("ERROR: Don't know how to create audio capability %d\n",
1098                    epCap->cap);
1099    }
1100    return NULL;
1101 }
1102 /* This is used for g726, AMRNB, Speex */
1103 struct H245AudioCapability* ooCapabilityCreateNonStandardCapability
1104    (ooH323EpCapability *epCap, OOCTXT* pctxt, int dir)
1105 {
1106    H245AudioCapability *pAudio=NULL;
1107    OOCapParams *params;
1108    if(!epCap || !epCap->params)
1109    {
1110      OOTRACEERR1("Error:Invalid capability parameters to "
1111                  "ooCapabilityCreateSimpleCapability.\n");
1112      return NULL;
1113    }
1114    params =(OOCapParams*)epCap->params;
1115    pAudio = (H245AudioCapability*)memAlloc(pctxt, 
1116                                                 sizeof(H245AudioCapability));
1117    if(!pAudio)
1118    {
1119       OOTRACEERR1("ERROR:Memory - ooCapabilityCreateSimpleCapability - pAudio\n");
1120       return NULL;
1121    }
1122
1123    
1124    switch(epCap->cap)
1125    {
1126    case OO_AMRNB:
1127    case OO_G726:
1128    case OO_G726AAL2:
1129    case OO_SPEEX:
1130       pAudio->t = T_H245AudioCapability_nonStandard;
1131       pAudio->u.nonStandard = (H245NonStandardParameter*)memAlloc(pctxt, 
1132                                            sizeof(H245NonStandardParameter));
1133       if(!pAudio->u.nonStandard)
1134       {
1135          OOTRACEERR1("Error:Memory - ooCapabilityCreateSimpleCapability - g726\n");
1136          memFreePtr(pctxt, pAudio);
1137          return NULL;
1138       }
1139
1140       pAudio->u.nonStandard->nonStandardIdentifier.t=T_H245NonStandardIdentifier_h221NonStandard;
1141       pAudio->u.nonStandard->nonStandardIdentifier.u.h221NonStandard =
1142         (H245NonStandardIdentifier_h221NonStandard *) memAlloc(pctxt, 
1143         sizeof(H245NonStandardIdentifier_h221NonStandard));
1144       if (!pAudio->u.nonStandard->nonStandardIdentifier.u.h221NonStandard) {
1145          OOTRACEERR2("Error:Memory - ooCapabilityCreateSimpleCapability - %d\n", epCap->cap);
1146          memFreePtr(pctxt, pAudio);
1147          return NULL;
1148       }
1149
1150       pAudio->u.nonStandard->nonStandardIdentifier.u.h221NonStandard->t35CountryCode =
1151                 gH323ep.t35CountryCode;
1152       pAudio->u.nonStandard->nonStandardIdentifier.u.h221NonStandard->t35Extension =
1153                 gH323ep.t35Extension;
1154       pAudio->u.nonStandard->nonStandardIdentifier.u.h221NonStandard->manufacturerCode =
1155                 gH323ep.manufacturerCode;
1156
1157       switch (epCap->cap) {
1158       case OO_G726:
1159        pAudio->u.nonStandard->data.data = (unsigned char*)"G.726-32k";
1160        pAudio->u.nonStandard->data.numocts = sizeof("G.726-32k")-1;
1161        break;
1162       case OO_G726AAL2:
1163        pAudio->u.nonStandard->data.data = (unsigned char*)"G726r32";
1164        pAudio->u.nonStandard->data.numocts = sizeof("G726r32")-1;
1165        /* Cisco G726 */
1166        pAudio->u.nonStandard->nonStandardIdentifier.u.h221NonStandard->t35CountryCode = 181;
1167        pAudio->u.nonStandard->nonStandardIdentifier.u.h221NonStandard->t35Extension = 0;
1168        pAudio->u.nonStandard->nonStandardIdentifier.u.h221NonStandard->manufacturerCode = 18;
1169
1170        break;
1171       case OO_AMRNB:
1172        pAudio->u.nonStandard->data.data = (unsigned char*)"AMRNB";
1173        pAudio->u.nonStandard->data.numocts = sizeof("AMRNB")-1;
1174        break;
1175
1176       case OO_SPEEX:
1177        pAudio->u.nonStandard->data.data = (unsigned char*)"Speex";
1178        pAudio->u.nonStandard->data.numocts = sizeof("Speex")-1;
1179        /* Equivalence OpenH323 SpeexNB */
1180        pAudio->u.nonStandard->nonStandardIdentifier.u.h221NonStandard->t35CountryCode = 9;
1181        pAudio->u.nonStandard->nonStandardIdentifier.u.h221NonStandard->t35Extension = 0;
1182        pAudio->u.nonStandard->nonStandardIdentifier.u.h221NonStandard->manufacturerCode = 61;
1183
1184        break;
1185       }
1186       return pAudio;
1187
1188    default:
1189       OOTRACEERR2("ERROR: Don't know how to create audio capability %d\n",
1190                    epCap->cap);
1191    }
1192    return NULL;
1193 }
1194
1195 /* Our t.38 params */
1196
1197 struct H245DataMode_application* ooCreateT38ApplicationData
1198                                 (OOCTXT* pctxt, H245DataMode_application *app)
1199 {
1200       app->t = T_H245DataApplicationCapability_application_t38fax;
1201       app->u.t38fax =
1202         (H245DataMode_application_t38fax *) memAlloc(pctxt, 
1203         sizeof(H245DataMode_application_t38fax));
1204       if (!app->u.t38fax) {
1205          OOTRACEERR1("Error:Memory - ooCreateT38AppData\n");
1206          return NULL;
1207       }
1208       memset(app->u.t38fax, 0, sizeof(H245DataApplicationCapability_application_t38fax));
1209       app->u.t38fax->t38FaxProtocol.t = T_H245DataProtocolCapability_udp;
1210       app->u.t38fax->t38FaxProfile.m.versionPresent = TRUE;
1211       app->u.t38fax->t38FaxProfile.version = 0;
1212       app->u.t38fax->t38FaxProfile.m.t38FaxRateManagementPresent = TRUE;
1213       app->u.t38fax->t38FaxProfile.t38FaxRateManagement.t =
1214                                                 T_H245T38FaxRateManagement_transferredTCF;
1215       app->u.t38fax->t38FaxProfile.m.t38FaxUdpOptionsPresent = TRUE;
1216       app->u.t38fax->t38FaxProfile.t38FaxUdpOptions.m.t38FaxMaxBufferPresent = TRUE;
1217       app->u.t38fax->t38FaxProfile.t38FaxUdpOptions.t38FaxMaxBuffer = 200;
1218       app->u.t38fax->t38FaxProfile.t38FaxUdpOptions.m.t38FaxMaxDatagramPresent = TRUE;
1219       app->u.t38fax->t38FaxProfile.t38FaxUdpOptions.t38FaxMaxDatagram = 72;
1220       app->u.t38fax->t38FaxProfile.t38FaxUdpOptions.t38FaxUdpEC.t =
1221                                         T_H245T38FaxUdpOptions_t38FaxUdpEC_t38UDPRedundancy;
1222
1223       return app;
1224 }
1225
1226 /* This is used for T.38 */
1227 struct H245DataApplicationCapability* ooCapabilityCreateT38Capability
1228    (ooH323EpCapability *epCap, OOCTXT* pctxt, int dir)
1229 {
1230    H245DataApplicationCapability *pT38=NULL;
1231    OOCapParams *params;
1232    H245DataMode_application *pT38app;
1233    if(!epCap || !epCap->params)
1234    {
1235      OOTRACEERR1("Error:Invalid capability parameters to "
1236                  "ooCapabilityCreateSimpleCapability.\n");
1237      return NULL;
1238    }
1239    params =(OOCapParams*)epCap->params;
1240    pT38 = (H245DataApplicationCapability*)memAlloc(pctxt, 
1241                                                 sizeof(H245DataApplicationCapability));
1242    if(!pT38)
1243    {
1244       OOTRACEERR1("ERROR:Memory - ooCapabilityCreateT38Capability - pT38\n");
1245       return NULL;
1246    }
1247    memset(pT38, 0, sizeof(H245DataApplicationCapability));
1248    pT38app = (void *)&pT38->application;
1249    
1250    switch(epCap->cap)
1251    {
1252    case OO_T38:
1253       pT38->maxBitRate = 144;
1254       if (!ooCreateT38ApplicationData(pctxt, pT38app)) {
1255          OOTRACEERR2("Error:Memory - ooCapabilityCreateT38Capability - %d\n", epCap->cap);
1256          memFreePtr(pctxt, pT38);
1257          return NULL;
1258       }
1259       return pT38;
1260
1261    default:
1262       OOTRACEERR2("ERROR: Don't know how to create T38 capability %d\n",
1263                    epCap->cap);
1264    }
1265    return NULL;
1266 }
1267
1268
1269 /* Used for g711 ulaw/alaw, g728, g729, g729a, g7231 */
1270 ASN1BOOL ooCapabilityCheckCompatibility_Simple
1271    (OOH323CallData *call, ooH323EpCapability* epCap, 
1272     H245AudioCapability* audioCap, int dir)
1273 {
1274    int noofframes=0, cap;
1275
1276    OOTRACEDBGC2("Comparing channel with codec type: %d\n", audioCap->t);
1277
1278    switch(audioCap->t)
1279    {
1280    case T_H245AudioCapability_g711Ulaw56k:
1281       cap = OO_G711ULAW56K;
1282       noofframes = audioCap->u.g711Ulaw56k;
1283       break;
1284    case T_H245AudioCapability_g711Ulaw64k:
1285       cap = OO_G711ULAW64K;
1286       noofframes = audioCap->u.g711Ulaw64k;
1287       break;
1288    case T_H245AudioCapability_g711Alaw64k:
1289       cap = OO_G711ALAW64K;
1290       noofframes = audioCap->u.g711Alaw64k;
1291       break;
1292    case T_H245AudioCapability_g711Alaw56k:
1293       cap = OO_G711ALAW56K;
1294       noofframes = audioCap->u.g711Alaw56k;
1295       break;
1296    /*case T_H245AudioCapability_g726:
1297       cap = OO_G726;
1298       noofframes = audioCap->u.g726;
1299       break;*/
1300    case T_H245AudioCapability_g728:
1301       cap = OO_G728;
1302       noofframes = audioCap->u.g728;
1303       break;
1304    case T_H245AudioCapability_g729:
1305       cap = OO_G729;
1306       noofframes = audioCap->u.g729;
1307       break;
1308    case T_H245AudioCapability_g729AnnexA:
1309       cap = OO_G729A;
1310       noofframes = audioCap->u.g729AnnexA;
1311       break;   
1312    case T_H245AudioCapability_g729wAnnexB:
1313       cap = OO_G729B;
1314       noofframes = audioCap->u.g729wAnnexB;
1315       break;   
1316    case T_H245AudioCapability_g7231:
1317      cap = OO_G7231;
1318      noofframes = audioCap->u.g7231->maxAl_sduAudioFrames;
1319      break;
1320
1321    default:
1322       return FALSE;
1323    }
1324
1325    OOTRACEDBGC3("Comparing codecs: current=%d, requested=%d\n", 
1326       epCap->cap, cap);
1327    if(cap != epCap->cap) { return FALSE; }
1328
1329    /* Can we receive this capability */
1330    if(dir & OORX)
1331    {
1332       OOTRACEDBGC3("Comparing RX frame rate: channel's=%d, requested=%d\n",
1333          ((OOCapParams*)epCap->params)->rxframes, noofframes);
1334       if(((OOCapParams*)epCap->params)->rxframes >= noofframes) {
1335          return TRUE;
1336       }
1337       //else {
1338       //  not supported, as already told other ep our max. receive rate
1339       //  our ep can't receive more rate than it
1340       //  return FALSE;
1341       //}
1342    }
1343
1344    /* Can we transmit compatible stream */
1345    if(dir & OOTX)
1346    {
1347       OOTRACEDBGC3("Comparing TX frame rate: channel's=%d, requested=%d\n",
1348          ((OOCapParams*)epCap->params)->txframes, noofframes);
1349       if(((OOCapParams*)epCap->params)->txframes <= noofframes) {
1350          return TRUE;
1351       }
1352       //else {
1353       //   TODO: reduce our ep transmission rate, as peer EP has low receive
1354       //   cap, than return TRUE
1355       //}
1356    }
1357    return FALSE;
1358
1359 }
1360 /* Used for g726, AMRNB */
1361 ASN1BOOL ooCapabilityCheckCompatibility_NonStandard
1362    (OOH323CallData *call, ooH323EpCapability* epCap, 
1363     H245AudioCapability* audioCap, int dir)
1364 {
1365    int cap;
1366
1367    OOTRACEDBGC2("Comparing channel with codec type: %d\n", audioCap->t);
1368
1369    if (audioCap->t == T_H245AudioCapability_nonStandard &&
1370        audioCap->u.nonStandard &&
1371        audioCap->u.nonStandard->nonStandardIdentifier.t == 
1372                  T_H245NonStandardIdentifier_h221NonStandard) {
1373        switch (audioCap->u.nonStandard->data.numocts) {
1374         case sizeof("G.726-32k")-1:
1375          if (!strncmp((char *)audioCap->u.nonStandard->data.data, "G.726-32k",
1376                 audioCap->u.nonStandard->data.numocts))
1377           cap = OO_G726;
1378          else
1379           return FALSE;
1380          break;
1381         case sizeof("G726r32")-1:
1382          if (!strncmp((char *)audioCap->u.nonStandard->data.data, "G726r32",
1383                 audioCap->u.nonStandard->data.numocts))
1384           cap = OO_G726AAL2;
1385          else
1386           return FALSE;
1387          break;
1388         case sizeof("AMRNB")-1: /* case sizeof("Speex")-1 */
1389          if (!strncmp((char *)audioCap->u.nonStandard->data.data, "AMRNB", 
1390                 audioCap->u.nonStandard->data.numocts))
1391           cap = OO_AMRNB;
1392          else if (!strncmp((char *)audioCap->u.nonStandard->data.data, "Speex", 
1393                 audioCap->u.nonStandard->data.numocts))
1394           cap = OO_SPEEX;
1395          else
1396           return FALSE;
1397          break;
1398         default:
1399          return FALSE;
1400        }
1401    } else
1402        return FALSE;
1403
1404    OOTRACEDBGC3("Comparing codecs: current=%d, requested=%d\n", 
1405       epCap->cap, cap);
1406    if(cap != epCap->cap) { return FALSE; }
1407
1408    return TRUE;
1409
1410 }
1411
1412
1413 OOBOOL ooCapabilityCheckCompatibility_GSM
1414    (OOH323CallData *call, ooH323EpCapability* epCap, 
1415     H245AudioCapability* audioCap, int dir)
1416 {
1417    unsigned noofframes=0, cap;
1418    switch(audioCap->t)
1419    {
1420    case T_H245AudioCapability_gsmFullRate:
1421       cap = OO_GSMFULLRATE;
1422       noofframes = (audioCap->u.gsmFullRate->audioUnitSize)/OO_GSMFRAMESIZE;
1423       break;
1424    case T_H245AudioCapability_gsmHalfRate:
1425       cap = OO_GSMHALFRATE;
1426       noofframes = (audioCap->u.gsmHalfRate->audioUnitSize)/OO_GSMFRAMESIZE;
1427       break;
1428    case T_H245AudioCapability_gsmEnhancedFullRate:
1429       cap = OO_GSMENHANCEDFULLRATE;
1430       noofframes = (audioCap->u.gsmEnhancedFullRate->audioUnitSize)/OO_GSMFRAMESIZE;
1431       break;
1432    default:
1433       return FALSE;
1434    }
1435
1436    if(cap != epCap->cap) { return FALSE; }
1437
1438    /* can we receive this capability */
1439    if(dir & OORX)
1440    {
1441       if(((OOGSMCapParams*)epCap->params)->rxframes >= noofframes)
1442          return TRUE;
1443    }
1444
1445    /* Make sure we transmit compatible stream */
1446    if(dir & OOTX)
1447    {
1448       if(((OOGSMCapParams*)epCap->params)->txframes > noofframes){
1449          OOTRACEDBGA5("Reducing txframes for GSM from %d to %d to match "
1450                       "receive capability of remote end.(%s, %s)\n", 
1451                      ((OOGSMCapParams*)epCap->params)->txframes, noofframes, 
1452                      call->callType, call->callToken);
1453          ((OOGSMCapParams*)epCap->params)->txframes = noofframes;
1454       }
1455       return TRUE;
1456    }
1457    return FALSE;
1458
1459 }
1460
1461 OOBOOL ooCapabilityCheckCompatibility_T38
1462    (OOH323CallData *call, ooH323EpCapability* epCap, 
1463     H245DataApplicationCapability* t38Cap, int dir)
1464 {
1465    unsigned cap = 0;
1466    switch(t38Cap->application.t)
1467    {
1468    case T_H245DataApplicationCapability_application_t38fax:
1469       cap = OO_T38;
1470       break;
1471    default:
1472       return FALSE;
1473    }
1474
1475    if(cap != epCap->cap) { return FALSE; }
1476
1477    return TRUE;
1478 }
1479
1480
1481 OOBOOL ooCapabilityCheckCompatibility_H263Video
1482    (struct OOH323CallData *call, ooH323EpCapability *epCap, 
1483     H245VideoCapability *pVideoCap, int dir)
1484 {
1485    H245H263VideoCapability *pH263Cap = NULL;
1486
1487    OOH263CapParams *params = epCap->params;
1488    if(!pVideoCap->u.h263VideoCapability)  
1489    {
1490       OOTRACEERR3("Error:No H263 video capability present in video capability"
1491                  "structure. (%s, %s)\n", call->callType, call->callToken);
1492       return FALSE;
1493    }
1494    pH263Cap = pVideoCap->u.h263VideoCapability;
1495    
1496    /* can we receive/transmit this capability */
1497    if(OORX & dir)
1498    {
1499       if(pH263Cap->m.sqcifMPIPresent)
1500       {
1501          if(params->picFormat != OO_PICFORMAT_SQCIF)
1502          {
1503             return FALSE;
1504          }
1505          else{
1506             if(pH263Cap->sqcifMPI >= params->MPI)
1507                return TRUE;
1508             else
1509                return FALSE;
1510          }
1511       }
1512       if(pH263Cap->m.qcifMPIPresent)
1513       {
1514          if(params->picFormat != OO_PICFORMAT_QCIF)
1515          {
1516             return FALSE;
1517          }
1518          else{
1519             if(pH263Cap->qcifMPI >= params->MPI)
1520                return TRUE;
1521             else
1522                return FALSE;
1523          }
1524       }
1525       if(pH263Cap->m.cifMPIPresent)
1526       {
1527          if(params->picFormat != OO_PICFORMAT_CIF)
1528          {
1529             return FALSE;
1530          }
1531          else{
1532             if(pH263Cap->cifMPI >= params->MPI)
1533                return TRUE;
1534             else
1535                return FALSE;
1536          }
1537       }
1538       if(pH263Cap->m.cif4MPIPresent)
1539       {
1540          if(params->picFormat != OO_PICFORMAT_CIF4)
1541          {
1542             return FALSE;
1543          }
1544          else{
1545             if(pH263Cap->cif4MPI >= params->MPI)
1546                return TRUE;
1547             else
1548                return FALSE;
1549          }
1550       }
1551       if(pH263Cap->m.cif16MPIPresent)
1552       {
1553          if(params->picFormat != OO_PICFORMAT_CIF16)
1554          {
1555             return FALSE;
1556          }
1557          else{
1558             if(pH263Cap->cif16MPI >= params->MPI)
1559                return TRUE;
1560             else
1561                return FALSE;
1562          }
1563       }
1564    }
1565
1566    /* Can we transmit */
1567    if(OOTX & dir)
1568    {
1569        if(pH263Cap->m.sqcifMPIPresent)
1570       {
1571          if(params->picFormat != OO_PICFORMAT_SQCIF)
1572          {
1573             return FALSE;
1574          }
1575          else{
1576             if(pH263Cap->sqcifMPI <= params->MPI)
1577                return TRUE;
1578             else
1579                return FALSE;
1580          }
1581       }
1582       if(pH263Cap->m.qcifMPIPresent)
1583       {
1584          if(params->picFormat != OO_PICFORMAT_QCIF)
1585          {
1586             return FALSE;
1587          }
1588          else{
1589             if(pH263Cap->qcifMPI <= params->MPI)
1590                return TRUE;
1591             else
1592                return FALSE;
1593          }
1594       }
1595       if(pH263Cap->m.cifMPIPresent)
1596       {
1597          if(params->picFormat != OO_PICFORMAT_CIF)
1598          {
1599             return FALSE;
1600          }
1601          else{
1602             if(pH263Cap->cifMPI <= params->MPI)
1603                return TRUE;
1604             else
1605                return FALSE;
1606          }
1607       }
1608       if(pH263Cap->m.cif4MPIPresent)
1609       {
1610          if(params->picFormat != OO_PICFORMAT_CIF4)
1611          {
1612             return FALSE;
1613          }
1614          else{
1615             if(pH263Cap->cif4MPI <= params->MPI)
1616                return TRUE;
1617             else
1618                return FALSE;
1619          }
1620       }
1621       if(pH263Cap->m.cif16MPIPresent)
1622       {
1623          if(params->picFormat != OO_PICFORMAT_CIF16)
1624          {
1625             return FALSE;
1626          }
1627          else{
1628             if(pH263Cap->cif16MPI <= params->MPI)
1629                return TRUE;
1630             else
1631                return FALSE;
1632          }
1633       }
1634    }
1635    
1636    return FALSE;
1637
1638 }
1639
1640
1641 OOBOOL ooCapabilityCheckCompatibility_Audio
1642    (OOH323CallData *call, ooH323EpCapability* epCap, 
1643     H245AudioCapability* audioCap, int dir)
1644 {
1645
1646    switch(audioCap->t)
1647    {
1648    case T_H245AudioCapability_g711Ulaw56k:
1649    case T_H245AudioCapability_g711Ulaw64k:
1650    case T_H245AudioCapability_g711Alaw64k:
1651    case T_H245AudioCapability_g711Alaw56k:
1652    /*case T_H245AudioCapability_g726:*/
1653    case T_H245AudioCapability_g728:
1654    case T_H245AudioCapability_g729:
1655    case T_H245AudioCapability_g729AnnexA:
1656    case T_H245AudioCapability_g729wAnnexB:
1657    case T_H245AudioCapability_g7231:
1658       return ooCapabilityCheckCompatibility_Simple(call, epCap, audioCap, dir);
1659    case T_H245AudioCapability_nonStandard:
1660       return ooCapabilityCheckCompatibility_NonStandard(call, epCap, audioCap, dir);
1661    case T_H245AudioCapability_gsmHalfRate:
1662    case T_H245AudioCapability_gsmEnhancedFullRate:
1663    case T_H245AudioCapability_gsmFullRate:
1664       return ooCapabilityCheckCompatibility_GSM(call, epCap, audioCap, dir);
1665    default:
1666       return FALSE;
1667    }
1668
1669    return FALSE;  
1670 }
1671
1672 OOBOOL ooCapabilityCheckCompatibility_Video
1673    (OOH323CallData *call, ooH323EpCapability* epCap, 
1674     H245VideoCapability* videoCap, int dir)
1675 {
1676    switch(videoCap->t)
1677    {
1678    case T_H245VideoCapability_h263VideoCapability:
1679       return ooCapabilityCheckCompatibility_H263Video(call, epCap, 
1680                                                               videoCap, dir);
1681    default:
1682      OOTRACEDBGC3("ooCapabilityCheckCompatibility_Video - Unsupported video "
1683                   "capability. (%s, %s)\n", call->callType, call->callToken);
1684    }
1685    return FALSE;
1686 }
1687 /*
1688    Note: In faststart if we sent transmit rate (x>y) and remote
1689          can receive only y, then we can't reduce our transmit rate
1690 */
1691 OOBOOL ooCapabilityCheckCompatibility
1692    (struct OOH323CallData *call, ooH323EpCapability* epCap, 
1693     H245DataType* dataType, int dir)
1694 {
1695    switch(dataType->t)
1696    {
1697    case T_H245DataType_audioData:
1698       if(epCap->capType == OO_CAP_TYPE_AUDIO)
1699          return ooCapabilityCheckCompatibility_Audio(call, epCap, 
1700                                                    dataType->u.audioData, dir);
1701       break;
1702    case T_H245DataType_videoData:
1703       if(epCap->capType == OO_CAP_TYPE_VIDEO)
1704          return ooCapabilityCheckCompatibility_Video(call, epCap, 
1705                                                    dataType->u.videoData, dir);
1706       break;
1707    case T_H245DataType_data:
1708       if(epCap->capType == OO_CAP_TYPE_DATA)
1709         return ooCapabilityCheckCompatibility_T38(call, epCap, dataType->u.data, dir);
1710    default:
1711       OOTRACEDBGC3("ooCapabilityCheckCompatibility - Unsupported  "
1712                   "capability. (%s, %s)\n", call->callType, call->callToken);
1713    }
1714
1715    return FALSE;
1716 }
1717
1718 #if 0
1719 /**
1720   TODO: If txCap is local and number of txframes is greater than remote can
1721   receive, we should automatically decrease it. And logical channel cap should
1722   be the one where it should be decreased. The start logical channel will
1723   indicate the application that it is supposed to tx and a reduced rate.
1724  */
1725 ASN1BOOL ooCheckCompatibility
1726    (OOH323CallData *call, ooH323EpCapability *txCap, ooH323EpCapability *rxCap)
1727 {
1728
1729    if(txCap->cap != rxCap->cap) return FALSE;
1730
1731    if(!(txCap->dir & OOTX)) return FALSE;
1732    
1733    if(!(rxCap->dir & OORX)) return FALSE;
1734
1735    switch(txCap->cap)
1736    {   
1737    case OO_G711ALAW64K:
1738    case OO_G711ALAW56K:
1739    case OO_G711ULAW64K:
1740    case OO_G711ULAW56K:
1741    case OO_G728:
1742    case OO_G729:
1743    case OO_G729A:
1744    case OO_G729B:
1745    case OO_G7231:
1746      if(((OOCapParams*)txCap->params)->txframes <= 
1747                                 ((OOCapParams*)rxCap->params)->rxframes)
1748        return TRUE;
1749      else{
1750        OOTRACEDBGA4("Simple caps %s are not compatible.(%s, %s)\n", 
1751                     ooGetCapTypeText(txCap->cap), call->callType, 
1752                     call->callToken);
1753        return FALSE;
1754      }
1755    case OO_GSMFULLRATE:
1756    case OO_GSMHALFRATE:
1757    case OO_GSMENHANCEDFULLRATE:
1758      if(((OOGSMCapParams*)txCap->params)->txframes <= 
1759                                 ((OOGSMCapParams*)rxCap->params)->rxframes)
1760        return TRUE;
1761      else{
1762        OOTRACEDBGA3("GSM caps are not compatible. (%s, %s)\n", call->callType,
1763                      call->callToken);
1764        return FALSE;
1765      }  
1766    default:
1767      OOTRACEWARN3("WARN: Unsupported capabilities being compared. (%s, %s)\n",
1768                    call->callType, call->callToken);
1769    }
1770    return FALSE;
1771
1772 }
1773
1774 #endif
1775
1776 ooH323EpCapability* ooIsAudioDataTypeGSMSupported
1777    (OOH323CallData *call, H245AudioCapability* audioCap, int dir)
1778 {
1779    unsigned framesPerPkt=0;
1780    int cap=0;
1781    ooH323EpCapability *cur = NULL, *epCap=NULL;
1782    OOGSMCapParams *params = NULL;
1783
1784    switch(audioCap->t)
1785    {
1786    case T_H245AudioCapability_gsmFullRate:
1787       framesPerPkt = (audioCap->u.gsmFullRate->audioUnitSize)/OO_GSMFRAMESIZE;
1788       cap = OO_GSMFULLRATE;
1789       break;
1790    case T_H245AudioCapability_gsmHalfRate:
1791       framesPerPkt = (audioCap->u.gsmHalfRate->audioUnitSize)/OO_GSMFRAMESIZE;
1792       cap = OO_GSMHALFRATE;
1793       break;
1794    case T_H245AudioCapability_gsmEnhancedFullRate:
1795       framesPerPkt = (audioCap->u.gsmEnhancedFullRate->audioUnitSize)/OO_GSMFRAMESIZE;
1796       cap = OO_GSMENHANCEDFULLRATE;
1797       break;
1798    default:
1799       OOTRACEERR3("Error:Invalid GSM capability type.(%s, %s)\n", 
1800                                            call->callType, call->callToken);
1801      return NULL;
1802    }
1803
1804    OOTRACEDBGC4("Determined audio data type to be of type %d. Searching"
1805                 " for matching capability.(%s, %s)\n", cap, call->callType, 
1806                 call->callToken);
1807
1808    /* If we have call specific caps then we use them, otherwise we use
1809       general endpoint caps*/
1810    if(call->ourCaps)   
1811       cur = call->ourCaps;
1812    else
1813       cur = gH323ep.myCaps;
1814
1815    while(cur)
1816    {
1817       OOTRACEDBGC4("Local cap being compared %d. (%s, %s)\n", cur->cap,
1818                      call->callType, call->callToken);
1819       
1820       if(cur->cap == cap && (cur->dir & dir))
1821          break;
1822       cur = cur->next;
1823    }
1824    
1825    if(!cur) return NULL;
1826    
1827    OOTRACEDBGC4("Found matching audio capability type %d. Comparing"
1828                 " other parameters. (%s, %s)\n", cap, call->callType, 
1829                 call->callToken);
1830    
1831    /* can we receive this capability */
1832    if(dir & OORX)
1833    {
1834       if(((OOGSMCapParams*)cur->params)->rxframes < framesPerPkt)
1835          return NULL;
1836       else{
1837          epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
1838                                                  sizeof(ooH323EpCapability));
1839          params =(OOGSMCapParams*)memAlloc(call->pctxt,sizeof(OOGSMCapParams));
1840          if(!epCap || !params)
1841          {
1842             OOTRACEERR3("Error:Memory - ooIsAudioDataTypeGSMSupported - "
1843                         "epCap/params (%s, %s)\n", call->callType, 
1844                         call->callToken);
1845             return NULL;
1846          }
1847          epCap->params = params;
1848          epCap->cap = cur->cap;
1849          epCap->dir = cur->dir;
1850          epCap->capType = cur->capType;
1851          epCap->startReceiveChannel = cur->startReceiveChannel;
1852          epCap->startTransmitChannel= cur->startTransmitChannel;
1853          epCap->stopReceiveChannel = cur->stopReceiveChannel;
1854          epCap->stopTransmitChannel = cur->stopTransmitChannel;
1855          epCap->next = NULL;
1856          memcpy(epCap->params, cur->params, sizeof(OOGSMCapParams));
1857          return epCap;
1858       }
1859    }
1860
1861    /* Can we transmit compatible stream */
1862    if(dir & OOTX)
1863    {
1864       epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
1865                                                 sizeof(ooH323EpCapability));
1866       params =(OOGSMCapParams*)memAlloc(call->pctxt,sizeof(OOGSMCapParams));
1867       if(!epCap || !params)
1868       {
1869          OOTRACEERR3("Error:Memory - ooIsAudioDataTypeGSMSupported - "
1870                      "epCap/params (%s, %s)\n", call->callType, 
1871                      call->callToken);
1872          return NULL;
1873       }
1874       epCap->params = params;
1875       epCap->cap = cur->cap;
1876       epCap->dir = cur->dir;
1877       epCap->capType = cur->capType;
1878       epCap->startReceiveChannel = cur->startReceiveChannel;
1879       epCap->startTransmitChannel= cur->startTransmitChannel;
1880       epCap->stopReceiveChannel = cur->stopReceiveChannel;
1881       epCap->stopTransmitChannel = cur->stopTransmitChannel;
1882       epCap->next = NULL;
1883       memcpy(epCap->params, cur->params, sizeof(OOGSMCapParams));
1884       if(params->txframes > framesPerPkt)
1885       {
1886          OOTRACEINFO5("Reducing framesPerPkt for transmission of GSM "
1887                       "capability from %d to %d to match receive capability of"
1888                       " remote endpoint.(%s, %s)\n", params->txframes, 
1889                       framesPerPkt, call->callType, call->callToken);
1890          params->txframes = framesPerPkt;
1891       }
1892
1893       return epCap;
1894
1895    }
1896    return NULL;
1897
1898 }
1899
1900 /* used for g711 ulaw/alaw, g728, g729, g729a, g7231 */
1901 ooH323EpCapability* ooIsAudioDataTypeSimpleSupported
1902    (OOH323CallData *call, H245AudioCapability* audioCap, int dir)
1903 {
1904    int cap, framesPerPkt=0;
1905    ooH323EpCapability *cur=NULL, *epCap=NULL;
1906    OOCapParams * params= NULL;
1907
1908    /* Find similar capability */
1909    switch(audioCap->t)
1910    {
1911       case T_H245AudioCapability_g711Alaw64k:
1912          framesPerPkt = audioCap->u.g711Alaw64k;
1913          cap = OO_G711ALAW64K;
1914          break;
1915       case T_H245AudioCapability_g711Alaw56k:
1916          framesPerPkt = audioCap->u.g711Alaw56k;
1917          cap = OO_G711ALAW56K;
1918          break;
1919       case T_H245AudioCapability_g711Ulaw56k:
1920          framesPerPkt = audioCap->u.g711Ulaw56k;
1921          cap = OO_G711ULAW56K;
1922          break;
1923       case T_H245AudioCapability_g711Ulaw64k:
1924          framesPerPkt = audioCap->u.g711Ulaw64k;
1925          cap = OO_G711ULAW64K;
1926          break;
1927
1928 /*      case T_H245AudioCapability_g726:
1929          framesPerPkt = audioCap->u.g726;
1930          cap = OO_G726;
1931          break;
1932 */
1933       case T_H245AudioCapability_g728:
1934          framesPerPkt = audioCap->u.g728;
1935          cap = OO_G728;
1936          break;
1937
1938       case T_H245AudioCapability_g729:
1939          framesPerPkt = audioCap->u.g729;
1940          cap = OO_G729;
1941          break;
1942       case T_H245AudioCapability_g729AnnexA:
1943          framesPerPkt = audioCap->u.g729AnnexA;
1944          cap = OO_G729A;
1945          break;
1946       case T_H245AudioCapability_g729wAnnexB:
1947          framesPerPkt = audioCap->u.g729wAnnexB;
1948          cap = OO_G729B;
1949          break;
1950       case T_H245AudioCapability_g7231:
1951          framesPerPkt = audioCap->u.g7231->maxAl_sduAudioFrames;
1952          cap = OO_G7231;
1953          break;
1954
1955       default:
1956          return NULL;
1957    }
1958
1959    OOTRACEDBGC4("Determined Simple audio data type to be of type %s. Searching"
1960                 " for matching capability.(%s, %s)\n", 
1961                 ooGetCapTypeText(cap), call->callType, call->callToken);
1962
1963    /* If we have call specific caps, we use them; otherwise use general
1964       endpoint caps
1965    */   
1966    if(call->ourCaps)
1967      cur = call->ourCaps;
1968    else
1969      cur = gH323ep.myCaps;
1970
1971    while(cur)
1972    {
1973       OOTRACEDBGC4("Local cap being compared %s. (%s, %s)\n", 
1974          ooGetCapTypeText(cur->cap),call->callType, call->callToken);
1975       
1976       if(cur->cap == cap && (cur->dir & dir))
1977          break;
1978       cur = cur->next;
1979    }
1980    
1981    if(!cur) return NULL;
1982    
1983    OOTRACEDBGC4("Found matching simple audio capability type %s. Comparing"
1984                 " other parameters. (%s, %s)\n", ooGetCapTypeText(cap), 
1985                 call->callType, call->callToken);
1986    
1987    /* can we receive this capability */
1988    if(dir & OORX)
1989    {
1990      if(((OOCapParams*)cur->params)->rxframes < framesPerPkt)
1991          return NULL;
1992      if(((OOCapParams*)cur->params)->rxframes > framesPerPkt) 
1993          ((OOCapParams*)cur->params)->rxframes = framesPerPkt;
1994
1995         OOTRACEDBGC4("We can receive Simple capability %s. (%s, %s)\n", 
1996                       ooGetCapTypeText(cur->cap), call->callType, 
1997                       call->callToken);
1998         epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
1999                                                  sizeof(ooH323EpCapability));
2000         params=(OOCapParams*)memAlloc(call->pctxt,sizeof(OOCapParams));
2001         if(!epCap || !params)
2002         {
2003            OOTRACEERR3("Error:Memory - ooIsAudioDataTypeSimpleSupported - "
2004                        "epCap/params (%s, %s)\n", call->callType, 
2005                        call->callToken);
2006            return NULL;
2007         }
2008         epCap->params = params;
2009         epCap->cap = cur->cap;
2010         epCap->dir = cur->dir;
2011         epCap->capType = cur->capType;
2012         epCap->startReceiveChannel = cur->startReceiveChannel;
2013         epCap->startTransmitChannel= cur->startTransmitChannel;
2014         epCap->stopReceiveChannel = cur->stopReceiveChannel;
2015         epCap->stopTransmitChannel = cur->stopTransmitChannel;
2016         epCap->next = NULL;
2017         memcpy(epCap->params, cur->params, sizeof(OOCapParams));
2018         OOTRACEDBGC4("Returning copy of matched receive capability %s. "
2019                      "(%s, %s)\n", 
2020                      ooGetCapTypeText(cur->cap), call->callType, 
2021                      call->callToken);
2022         return epCap;
2023    }
2024
2025    /* Can we transmit compatible stream */
2026    if(dir & OOTX)
2027    {
2028       OOTRACEDBGC4("We can transmit Simple capability %s. (%s, %s)\n", 
2029                    ooGetCapTypeText(cur->cap), call->callType, 
2030                    call->callToken);
2031       epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
2032                                                 sizeof(ooH323EpCapability));
2033       params =(OOCapParams*)memAlloc(call->pctxt,sizeof(OOCapParams));
2034       if(!epCap || !params)
2035       {
2036          OOTRACEERR3("Error:Memory - ooIsAudioDataTypeSimpleSupported - "
2037                      "epCap/params (%s, %s)\n", call->callType, 
2038                      call->callToken);
2039          return NULL;
2040       }
2041       epCap->params = params;
2042       epCap->cap = cur->cap;
2043       epCap->dir = cur->dir;
2044       epCap->capType = cur->capType;
2045       epCap->startReceiveChannel = cur->startReceiveChannel;
2046       epCap->startTransmitChannel= cur->startTransmitChannel;
2047       epCap->stopReceiveChannel = cur->stopReceiveChannel;
2048       epCap->stopTransmitChannel = cur->stopTransmitChannel;
2049       epCap->next = NULL;
2050       memcpy(epCap->params, cur->params, sizeof(OOCapParams));
2051       if(params->txframes > framesPerPkt)
2052       {
2053          OOTRACEINFO5("Reducing framesPerPkt for transmission of Simple "
2054                       "capability from %d to %d to match receive capability of"
2055                       " remote endpoint.(%s, %s)\n", params->txframes, 
2056                       framesPerPkt, call->callType, call->callToken);
2057          params->txframes = framesPerPkt;
2058       }
2059       OOTRACEDBGC4("Returning copy of matched transmit capability %s."
2060                    "(%s, %s)\n", 
2061                    ooGetCapTypeText(cur->cap), call->callType, 
2062                    call->callToken);
2063       return epCap;
2064    }
2065    return NULL;
2066 }
2067
2068 /* used for g726, AMRNB */
2069 ooH323EpCapability* ooIsAudioDataTypeNonStandardSupported
2070    (OOH323CallData *call, H245AudioCapability* audioCap, int dir)
2071 {
2072    int cap;
2073    ooH323EpCapability *cur=NULL, *epCap=NULL;
2074    OOCapParams * params= NULL;
2075
2076    if (audioCap->t == T_H245AudioCapability_nonStandard &&
2077        audioCap->u.nonStandard && 
2078        audioCap->u.nonStandard->nonStandardIdentifier.t == 
2079                  T_H245NonStandardIdentifier_h221NonStandard) {
2080        switch (audioCap->u.nonStandard->data.numocts) {
2081         case sizeof("G.726-32k")-1:
2082          if (!strncmp((char *)audioCap->u.nonStandard->data.data, "G.726-32k",
2083                 audioCap->u.nonStandard->data.numocts))
2084           cap = OO_G726;
2085          else
2086           return NULL;
2087          break;
2088         case sizeof("G726r32")-1:
2089          if (!strncmp((char *)audioCap->u.nonStandard->data.data, "G726r32",
2090                 audioCap->u.nonStandard->data.numocts))
2091           cap = OO_G726AAL2;
2092          else
2093           return NULL;
2094          break;
2095         case sizeof("AMRNB")-1: /* sizeof("Speex") */
2096          if (!strncmp((char *)audioCap->u.nonStandard->data.data, "AMRNB",
2097                 audioCap->u.nonStandard->data.numocts))
2098           cap = OO_AMRNB;
2099          else if (!strncmp((char *)audioCap->u.nonStandard->data.data, "Speex",
2100                 audioCap->u.nonStandard->data.numocts))
2101           cap = OO_SPEEX;
2102          else
2103           return NULL;
2104          break;
2105         default:
2106          return NULL;
2107        }
2108    } else
2109        return NULL;
2110
2111    OOTRACEDBGC4("Determined Simple audio data type to be of type %s. Searching"
2112                 " for matching capability.(%s, %s)\n", 
2113                 ooGetCapTypeText(cap), call->callType, call->callToken);
2114
2115    /* If we have call specific caps, we use them; otherwise use general
2116       endpoint caps
2117    */   
2118    if(call->ourCaps)
2119      cur = call->ourCaps;
2120    else
2121      cur = gH323ep.myCaps;
2122
2123    while(cur)
2124    {
2125       OOTRACEDBGC4("Local cap being compared %s. (%s, %s)\n", 
2126          ooGetCapTypeText(cur->cap),call->callType, call->callToken);
2127       
2128       if(cur->cap == cap && (cur->dir & dir))
2129          break;
2130       cur = cur->next;
2131    }
2132    
2133    if(!cur) return NULL;
2134    
2135    OOTRACEDBGC4("Found matching simple audio capability type %s. Comparing"
2136                 " other parameters. (%s, %s)\n", ooGetCapTypeText(cap), 
2137                 call->callType, call->callToken);
2138    
2139    /* can we receive this capability */
2140    if(dir & OORX)
2141    {
2142         OOTRACEDBGC4("We can receive Simple capability %s. (%s, %s)\n", 
2143                       ooGetCapTypeText(cur->cap), call->callType, 
2144                       call->callToken);
2145         epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
2146                                                  sizeof(ooH323EpCapability));
2147         params=(OOCapParams*)memAlloc(call->pctxt,sizeof(OOCapParams));
2148         if(!epCap || !params)
2149         {
2150            OOTRACEERR3("Error:Memory - ooIsAudioDataTypeSimpleSupported - "
2151                        "epCap/params (%s, %s)\n", call->callType, 
2152                        call->callToken);
2153            return NULL;
2154         }
2155         epCap->params = params;
2156         epCap->cap = cur->cap;
2157         epCap->dir = cur->dir;
2158         epCap->capType = cur->capType;
2159         epCap->startReceiveChannel = cur->startReceiveChannel;
2160         epCap->startTransmitChannel= cur->startTransmitChannel;
2161         epCap->stopReceiveChannel = cur->stopReceiveChannel;
2162         epCap->stopTransmitChannel = cur->stopTransmitChannel;
2163         epCap->next = NULL;
2164         memcpy(epCap->params, cur->params, sizeof(OOCapParams));
2165         OOTRACEDBGC4("Returning copy of matched receive capability %s. "
2166                      "(%s, %s)\n", 
2167                      ooGetCapTypeText(cur->cap), call->callType, 
2168                      call->callToken);
2169         return epCap;
2170    }
2171
2172    /* Can we transmit compatible stream */
2173    if(dir & OOTX)
2174    {
2175       OOTRACEDBGC4("We can transmit Simple capability %s. (%s, %s)\n", 
2176                    ooGetCapTypeText(cur->cap), call->callType, 
2177                    call->callToken);
2178       epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
2179                                                 sizeof(ooH323EpCapability));
2180       params =(OOCapParams*)memAlloc(call->pctxt,sizeof(OOCapParams));
2181       if(!epCap || !params)
2182       {
2183          OOTRACEERR3("Error:Memory - ooIsAudioDataTypeSimpleSupported - "
2184                      "epCap/params (%s, %s)\n", call->callType, 
2185                      call->callToken);
2186          return NULL;
2187       }
2188       epCap->params = params;
2189       epCap->cap = cur->cap;
2190       epCap->dir = cur->dir;
2191       epCap->capType = cur->capType;
2192       epCap->startReceiveChannel = cur->startReceiveChannel;
2193       epCap->startTransmitChannel= cur->startTransmitChannel;
2194       epCap->stopReceiveChannel = cur->stopReceiveChannel;
2195       epCap->stopTransmitChannel = cur->stopTransmitChannel;
2196       epCap->next = NULL;
2197       memcpy(epCap->params, cur->params, sizeof(OOCapParams));
2198       OOTRACEDBGC4("Returning copy of matched transmit capability %s."
2199                    "(%s, %s)\n", 
2200                    ooGetCapTypeText(cur->cap), call->callType, 
2201                    call->callToken);
2202       return epCap;
2203    }
2204    return NULL;
2205 }
2206
2207
2208
2209 ooH323EpCapability* ooIsAudioDataTypeSupported
2210    (OOH323CallData *call, H245AudioCapability* audioCap, int dir)
2211 {
2212    /* Find similar capability */
2213    switch(audioCap->t)
2214    {
2215       case T_H245AudioCapability_g711Alaw64k:
2216       case T_H245AudioCapability_g711Alaw56k:
2217       case T_H245AudioCapability_g711Ulaw56k:
2218       case T_H245AudioCapability_g711Ulaw64k:
2219       /*case T_H245AudioCapability_g726:*/
2220       case T_H245AudioCapability_g728:
2221       case T_H245AudioCapability_g729:
2222       case T_H245AudioCapability_g729AnnexA:
2223       case T_H245AudioCapability_g729wAnnexB:
2224       case T_H245AudioCapability_g7231:
2225          return ooIsAudioDataTypeSimpleSupported(call, audioCap, dir);
2226       case T_H245AudioCapability_nonStandard:
2227          return ooIsAudioDataTypeNonStandardSupported(call, audioCap, dir);
2228       case T_H245AudioCapability_gsmFullRate:
2229       case T_H245AudioCapability_gsmHalfRate:
2230       case T_H245AudioCapability_gsmEnhancedFullRate:
2231          return ooIsAudioDataTypeGSMSupported(call, audioCap, dir);   
2232       default:
2233          return NULL;
2234    }   
2235 }
2236
2237 ooH323EpCapability* ooIsT38Supported
2238    (OOH323CallData *call, H245DataApplicationCapability* t38Cap, int dir)
2239 {
2240    int cap = 0;
2241    ooH323EpCapability *cur=NULL, *epCap=NULL;
2242    OOCapParams *params= NULL;
2243    /* Find similar capability */
2244    switch(t38Cap->application.t)
2245    {
2246       case T_H245DataApplicationCapability_application_t38fax:
2247          cap = OO_T38;
2248          break;
2249       default:
2250          return NULL;
2251    }   
2252
2253    if(call->ourCaps)
2254      cur = call->ourCaps;
2255    else
2256      cur = gH323ep.myCaps;
2257
2258    while(cur)
2259    {
2260       OOTRACEDBGC4("Local cap being compared %s. (%s, %s)\n", 
2261          ooGetCapTypeText(cur->cap),call->callType, call->callToken);
2262       
2263       if(cur->cap == cap && (cur->dir & dir))
2264          break;
2265       cur = cur->next;
2266    }
2267    
2268    if(!cur) return NULL;
2269    
2270    OOTRACEDBGC4("Found matching t38 capability type %s. Comparing"
2271                 " other parameters. (%s, %s)\n", ooGetCapTypeText(cap), 
2272                 call->callType, call->callToken);
2273    
2274    /* can we receive this capability */
2275    if(dir & OORX)
2276    {
2277         OOTRACEDBGC4("We can receive Simple capability %s. (%s, %s)\n", 
2278                       ooGetCapTypeText(cur->cap), call->callType, 
2279                       call->callToken);
2280         epCap = (ooH323EpCapability*)memAllocZ(call->pctxt, 
2281                                                  sizeof(ooH323EpCapability));
2282         params=(OOCapParams*)memAlloc(call->pctxt,sizeof(OOCapParams));
2283         if(!epCap || !params)
2284         {
2285            OOTRACEERR3("Error:Memory - ooIsT38Supported - "
2286                        "epCap/params (%s, %s)\n", call->callType, 
2287                        call->callToken);
2288            return NULL;
2289         }
2290         epCap->params = params;
2291         epCap->cap = cur->cap;
2292         epCap->dir = cur->dir;
2293         epCap->capType = cur->capType;
2294         epCap->startReceiveChannel = cur->startReceiveChannel;
2295         epCap->startTransmitChannel= cur->startTransmitChannel;
2296         epCap->stopReceiveChannel = cur->stopReceiveChannel;
2297         epCap->stopTransmitChannel = cur->stopTransmitChannel;
2298         epCap->next = NULL;
2299         memcpy(epCap->params, cur->params, sizeof(OOCapParams));
2300         OOTRACEDBGC4("Returning copy of matched receive capability %s. "
2301                      "(%s, %s)\n", 
2302                      ooGetCapTypeText(cur->cap), call->callType, 
2303                      call->callToken);
2304         return epCap;
2305    }
2306
2307    /* Can we transmit compatible stream */
2308    if(dir & OOTX)
2309    {
2310       OOTRACEDBGC4("We can transmit Simple capability %s. (%s, %s)\n", 
2311                    ooGetCapTypeText(cur->cap), call->callType, 
2312                    call->callToken);
2313       epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
2314                                                 sizeof(ooH323EpCapability));
2315       params =(OOCapParams*)memAllocZ(call->pctxt,sizeof(OOCapParams));
2316       if(!epCap || !params)
2317       {
2318          OOTRACEERR3("Error:Memory - ooIsAudioDataTypeSimpleSupported - "
2319                      "epCap/params (%s, %s)\n", call->callType, 
2320                      call->callToken);
2321          return NULL;
2322       }
2323       epCap->params = params;
2324       epCap->cap = cur->cap;
2325       epCap->dir = cur->dir;
2326       epCap->capType = cur->capType;
2327       epCap->startReceiveChannel = cur->startReceiveChannel;
2328       epCap->startTransmitChannel= cur->startTransmitChannel;
2329       epCap->stopReceiveChannel = cur->stopReceiveChannel;
2330       epCap->stopTransmitChannel = cur->stopTransmitChannel;
2331       epCap->next = NULL;
2332       memcpy(epCap->params, cur->params, sizeof(OOCapParams));
2333       OOTRACEDBGC4("Returning copy of matched transmit capability %s."
2334                    "(%s, %s)\n", 
2335                    ooGetCapTypeText(cur->cap), call->callType, 
2336                    call->callToken);
2337       return epCap;
2338    }
2339    return NULL;
2340 }
2341
2342 ooH323EpCapability* ooIsVideoDataTypeH263Supported
2343    (OOH323CallData *call, H245H263VideoCapability* pH263Cap, int dir, 
2344     OOPictureFormat picFormat)
2345 {
2346    int cap;
2347    ooH323EpCapability *cur=NULL, *epCap=NULL;
2348    OOH263CapParams *params= NULL;   
2349    char *pictureType=NULL;
2350    unsigned mpi=0;
2351    cap = OO_H263VIDEO;
2352
2353    if(picFormat == OO_PICFORMAT_SQCIF && pH263Cap->m.sqcifMPIPresent)
2354    {
2355       pictureType = "SQCIF";
2356       mpi = pH263Cap->sqcifMPI;
2357    }
2358    if(picFormat == OO_PICFORMAT_QCIF && pH263Cap->m.qcifMPIPresent)
2359    {
2360       pictureType = "QCIF";
2361       mpi = pH263Cap->qcifMPI;
2362    }
2363    if(picFormat == OO_PICFORMAT_CIF && pH263Cap->m.cifMPIPresent)
2364    {
2365       pictureType = "CIF";
2366       mpi = pH263Cap->cifMPI;
2367    }
2368    if(picFormat == OO_PICFORMAT_CIF4 && pH263Cap->m.cif4MPIPresent)
2369    {
2370       pictureType = "CIF4";
2371       mpi = pH263Cap->cif4MPI;
2372    }
2373    if(picFormat == OO_PICFORMAT_CIF16 && pH263Cap->m.cif16MPIPresent)
2374    {
2375       pictureType = "CIF16";
2376       mpi = pH263Cap->cif16MPI;
2377    }
2378    
2379
2380    OOTRACEDBGA4("Looking for H263 video capability(%s). (%s, %s)\n", 
2381                  pictureType, call->callType, call->callToken);
2382
2383   /* If we have call specific caps, we use them; otherwise use general
2384       endpoint caps
2385    */   
2386    if(call->ourCaps)
2387      cur = call->ourCaps;
2388    else
2389      cur = gH323ep.myCaps;
2390
2391    while(cur)
2392    {
2393       OOTRACEDBGC4("Local cap being compared %s. (%s, %s)\n", 
2394               ooGetCapTypeText(cur->cap),call->callType, call->callToken);
2395       
2396       if(cur->cap == cap && (cur->dir & dir))
2397       {
2398          if(((OOH263CapParams*)cur->params)->picFormat == picFormat)
2399             break;
2400       }
2401       cur = cur->next;
2402    }
2403    
2404    if(!cur) return NULL;
2405    
2406    OOTRACEDBGC4("Found matching H.263 video capability type %s. Comparing"
2407                 " other parameters. (%s, %s)\n", ooGetCapTypeText(cap), 
2408                 call->callType, call->callToken);   
2409    if(dir & OORX)
2410    {
2411       if(mpi < ((OOH263CapParams*)cur->params)->MPI)
2412          return NULL;
2413       else{
2414          epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
2415                                                    sizeof(ooH323EpCapability));
2416          params = (OOH263CapParams*) memAlloc(call->pctxt, 
2417                                                       sizeof(OOH263CapParams));
2418          if(!epCap || !params)
2419          {
2420             OOTRACEERR3("Error:Memory - ooIsVideoDataTypeH263Supported - "
2421                        "epCap/params. (%s, %s)\n", call->callType, 
2422                         call->callToken);
2423             return NULL;
2424          }
2425          epCap->params = params;
2426          epCap->cap = cur->cap;
2427          epCap->dir = cur->dir;
2428          epCap->capType = cur->capType;
2429          epCap->startReceiveChannel = cur->startReceiveChannel;
2430          epCap->startTransmitChannel= cur->startTransmitChannel;
2431          epCap->stopReceiveChannel = cur->stopReceiveChannel;
2432          epCap->stopTransmitChannel = cur->stopTransmitChannel;
2433          epCap->next = NULL;
2434          memcpy(epCap->params, cur->params, sizeof(OOH263CapParams));
2435          OOTRACEDBGC4("Returning copy of matched receive capability %s. "
2436                      "(%s, %s)\n", ooGetCapTypeText(cur->cap), call->callType, 
2437                      call->callToken);
2438          return epCap;
2439       }
2440    }
2441    if(dir & OOTX)
2442    {
2443       epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
2444                                                   sizeof(ooH323EpCapability));
2445       params = (OOH263CapParams*) memAlloc(call->pctxt, 
2446                                                       sizeof(OOH263CapParams));
2447       if(!epCap || !params)
2448       {
2449          OOTRACEERR3("Error:Memory - ooIsVideoDataTypeH263Supported - "
2450                      "epCap/params. (%s, %s)\n", call->callType, 
2451                      call->callToken);
2452          return NULL;
2453       }
2454       epCap->params = params;
2455       epCap->cap = cur->cap;
2456       epCap->dir = cur->dir;
2457       epCap->capType = cur->capType;
2458       epCap->startReceiveChannel = cur->startReceiveChannel;
2459       epCap->startTransmitChannel= cur->startTransmitChannel;
2460       epCap->stopReceiveChannel = cur->stopReceiveChannel;
2461       epCap->stopTransmitChannel = cur->stopTransmitChannel;
2462       epCap->next = NULL;
2463       memcpy(epCap->params, cur->params, sizeof(OOH263CapParams));
2464       if(params->MPI < mpi)
2465       {
2466          OOTRACEINFO5("Increasing minimum picture interval for transmission of"
2467                       " H263 video capability from %d to %d to match receive "
2468                       "capability of remote endpoint.(%s, %s)\n", params->MPI, 
2469                       mpi, call->callType, call->callToken);
2470          params->MPI = mpi;
2471       }
2472       OOTRACEDBGC4("Returning copy of matched receive capability %s. "
2473                   "(%s, %s)\n", ooGetCapTypeText(cur->cap), call->callType, 
2474                   call->callToken);
2475       return epCap;
2476    }
2477    return NULL;
2478
2479 }
2480
2481 ooH323EpCapability* ooIsVideoDataTypeSupported
2482    (OOH323CallData *call, H245VideoCapability* pVideoCap, int dir)
2483 {
2484    switch(pVideoCap->t)   
2485    {
2486    case T_H245VideoCapability_h263VideoCapability:
2487       if(pVideoCap->u.h263VideoCapability->m.sqcifMPIPresent)
2488          return ooIsVideoDataTypeH263Supported(call, 
2489                     pVideoCap->u.h263VideoCapability, dir, OO_PICFORMAT_SQCIF);
2490       else if(pVideoCap->u.h263VideoCapability->m.qcifMPIPresent)
2491          return ooIsVideoDataTypeH263Supported(call, 
2492                      pVideoCap->u.h263VideoCapability, dir, OO_PICFORMAT_QCIF);
2493       else if(pVideoCap->u.h263VideoCapability->m.cifMPIPresent)
2494         return ooIsVideoDataTypeH263Supported(call, 
2495                       pVideoCap->u.h263VideoCapability, dir, OO_PICFORMAT_CIF);
2496       else if(pVideoCap->u.h263VideoCapability->m.cif4MPIPresent)
2497         return ooIsVideoDataTypeH263Supported(call, 
2498                      pVideoCap->u.h263VideoCapability, dir, OO_PICFORMAT_CIF4);
2499       else if(pVideoCap->u.h263VideoCapability->m.cif16MPIPresent)
2500         return ooIsVideoDataTypeH263Supported(call, 
2501                     pVideoCap->u.h263VideoCapability, dir, OO_PICFORMAT_CIF16);
2502       break;  
2503    case T_H245VideoCapability_nonStandard:
2504    case T_H245VideoCapability_h261VideoCapability:
2505    case T_H245VideoCapability_h262VideoCapability:
2506    case T_H245VideoCapability_is11172VideoCapability:
2507    case T_H245VideoCapability_genericVideoCapability:
2508    case T_H245VideoCapability_extElem1:
2509    default:
2510      OOTRACEDBGA1("Unsupported video capability type in "
2511                   "ooIsVideoDataTypeSupported\n");
2512       return NULL;
2513    }
2514    return NULL;
2515 }
2516
2517 ooH323EpCapability* ooIsDataTypeSupported
2518                    (OOH323CallData *call, H245DataType *data, int dir)
2519 {
2520    OOTRACEDBGC3("Looking for data type support. (%s, %s)\n", call->callType, 
2521                  call->callToken);
2522     
2523    switch(data->t)
2524    {
2525    case T_H245DataType_nonStandard:
2526       OOTRACEDBGC3("NonStandard data type not supported.(%s, %s)\n", 
2527                    call->callType, call->callToken);
2528       return NULL;
2529    case T_H245DataType_nullData:
2530       OOTRACEDBGC3("Null data type not supported.(%s, %s)\n", 
2531                    call->callType, call->callToken);
2532       return NULL;
2533    case T_H245DataType_videoData:
2534       OOTRACEDBGC3("Looking for video dataType support. (%s, %s)\n",
2535                     call->callType, call->callToken);
2536       return ooIsVideoDataTypeSupported(call, data->u.videoData, dir);
2537    case T_H245DataType_audioData:
2538       OOTRACEDBGC3("Looking for audio dataType support. (%s, %s)\n",
2539                     call->callType, call->callToken);
2540       return ooIsAudioDataTypeSupported(call, data->u.audioData, dir);
2541
2542    case T_H245DataType_data:
2543      OOTRACEDBGC3("Looking for application data dataType support.(%s, %s)\n", 
2544                    call->callType, call->callToken);
2545      return ooIsT38Supported(call, data->u.data, dir);
2546
2547    case T_H245DataType_encryptionData:
2548      OOTRACEDBGC3("Encryption data type not supported.(%s, %s)\n", 
2549                    call->callType, call->callToken);
2550      return NULL;
2551    case T_H245DataType_h235Control:
2552      return NULL;
2553    case T_H245DataType_h235Media:
2554      return NULL;
2555    case T_H245DataType_multiplexedStream:
2556      return NULL;
2557    default:
2558       OOTRACEINFO3("Unknown data type (%s, %s)\n", call->callType, 
2559                     call->callToken);
2560    }
2561    return NULL;
2562 }
2563
2564 int ooResetCapPrefs(OOH323CallData *call)
2565 {
2566    OOCapPrefs *capPrefs=NULL;
2567    if(call)
2568       capPrefs = &call->capPrefs;
2569    else
2570       capPrefs = &gH323ep.capPrefs;
2571    memset(capPrefs, 0, sizeof(OOCapPrefs));
2572    return OO_OK;
2573 }
2574
2575 int ooRemoveCapFromCapPrefs(OOH323CallData *call, int cap)
2576 {
2577    int i=0, j=0;
2578    OOCapPrefs *capPrefs=NULL, oldPrefs;
2579    if(call)
2580       capPrefs = &call->capPrefs;
2581    else
2582       capPrefs = &gH323ep.capPrefs;
2583
2584    memcpy(&oldPrefs, capPrefs, sizeof(OOCapPrefs));
2585    memset(capPrefs, 0, sizeof(OOCapPrefs));
2586    for(i=0; i<oldPrefs.index; i++)
2587    {  
2588       if(oldPrefs.order[i] != cap) 
2589          capPrefs->order[j++] = oldPrefs.order[i];
2590    }
2591    capPrefs->index = j;
2592    return OO_OK;
2593 }
2594
2595  
2596 int ooAppendCapToCapPrefs(OOH323CallData *call, int cap)
2597 {
2598    OOCapPrefs *capPrefs=NULL;
2599    if(call)
2600       capPrefs = &call->capPrefs;
2601    else
2602       capPrefs = &gH323ep.capPrefs;
2603
2604    capPrefs->order[capPrefs->index++] = cap;
2605    return OO_OK;
2606 }
2607
2608 int ooChangeCapPrefOrder(OOH323CallData *call, int cap, int pos)
2609 {
2610    int i=0, j=0;
2611    OOCapPrefs *capPrefs = NULL;
2612
2613    /* Whether to change prefs for call or for endpoint as a whole */
2614    if(call)
2615       capPrefs = &call->capPrefs;
2616    else
2617       capPrefs = &gH323ep.capPrefs;
2618
2619    /* check whether cap exists, cap must exist */
2620    for(i=0; i<capPrefs->index; i++)
2621    {
2622       if(capPrefs->order[i] == cap)
2623          break;
2624    }
2625    if(i == capPrefs->index) return OO_FAILED;
2626
2627    if(i==pos) return OO_OK; /* No need to change */
2628
2629    /* Decrease Pref order */
2630    if(i < pos)
2631    {
2632       for( ; i<pos; i++) 
2633          capPrefs->order[i] = capPrefs->order[i+1];
2634       capPrefs->order[i]=cap;
2635       return OO_OK;
2636    }
2637    /* Increase Pref order */
2638    if(i>pos)
2639    {
2640      for(j=i; j>pos; j--)
2641        capPrefs->order[j] = capPrefs->order[j-1];
2642      capPrefs->order[j] = cap;
2643      return OO_OK;
2644    }
2645
2646    return OO_FAILED;
2647
2648 }
2649
2650 int ooPreppendCapToCapPrefs(OOH323CallData *call, int cap)
2651 {
2652    int i=0, j=0;
2653    OOCapPrefs *capPrefs=NULL, oldPrefs;
2654    if(call)
2655       capPrefs = &call->capPrefs;
2656    else
2657       capPrefs = &gH323ep.capPrefs;
2658
2659    memcpy(&oldPrefs, capPrefs, sizeof(OOCapPrefs));
2660
2661  
2662    capPrefs->order[j++] = cap;
2663
2664    for(i=0; i<oldPrefs.index; i++)
2665    {  
2666       if(oldPrefs.order[i] != cap) 
2667          capPrefs->order[j++] = oldPrefs.order[i];
2668    }
2669    capPrefs->index = j;
2670    return OO_OK;
2671 }
2672
2673 int ooAddRemoteCapability(OOH323CallData *call, H245Capability *cap)
2674 {
2675    switch(cap->t)
2676    {
2677    case T_H245Capability_receiveAudioCapability:
2678      return ooAddRemoteAudioCapability(call, cap->u.receiveAudioCapability, 
2679                                        OORX);
2680    case T_H245Capability_transmitAudioCapability:
2681      return ooAddRemoteAudioCapability(call, cap->u.transmitAudioCapability, 
2682                                        OOTX);
2683    case T_H245Capability_receiveAndTransmitAudioCapability:
2684      return ooAddRemoteAudioCapability(call, 
2685                              cap->u.receiveAndTransmitAudioCapability, OORXTX);
2686
2687
2688    case T_H245Capability_receiveDataApplicationCapability:
2689      return ooAddRemoteDataApplicationCapability(call, cap->u.receiveDataApplicationCapability, 
2690                                        OORX);
2691    case T_H245Capability_transmitDataApplicationCapability:
2692      return ooAddRemoteDataApplicationCapability(call, cap->u.transmitDataApplicationCapability, 
2693                                        OOTX);
2694    case T_H245Capability_receiveAndTransmitDataApplicationCapability:
2695      return ooAddRemoteDataApplicationCapability(call, 
2696                              cap->u.receiveAndTransmitDataApplicationCapability, OORXTX);
2697
2698
2699    default:
2700      OOTRACEDBGA3("Unsupported cap type encountered. Ignoring. (%s, %s)\n", 
2701                    call->callType, call->callToken);
2702    }
2703    return OO_OK;
2704 }
2705
2706 int ooAddRemoteDataApplicationCapability(OOH323CallData *call, 
2707                                H245DataApplicationCapability *dataCap,
2708                                int dir)
2709 {
2710    switch(dataCap->application.t)
2711    {
2712    case T_H245DataApplicationCapability_application_t38fax:
2713       if (dataCap->application.u.t38fax->t38FaxProfile.m.t38FaxUdpOptionsPresent) {
2714         call->T38FarMaxDatagram = dataCap->application.u.t38fax->t38FaxProfile.t38FaxUdpOptions.t38FaxMaxDatagram;
2715       }
2716       if (dataCap->application.u.t38fax->t38FaxProfile.m.versionPresent) {
2717         call->T38Version = dataCap->application.u.t38fax->t38FaxProfile.version;
2718       }
2719       return ooCapabilityAddT38Capability(call, OO_T38,
2720                                              dir, NULL, NULL, NULL, NULL,TRUE);
2721    default:
2722      OOTRACEDBGA1("Unsupported data capability type\n");
2723    
2724    }
2725    return OO_OK;
2726 }
2727
2728
2729 int ooAddRemoteAudioCapability(OOH323CallData *call, 
2730                                H245AudioCapability *audioCap,
2731                                int dir)
2732 {
2733    int rxframes=0, txframes=0;
2734   
2735    switch(audioCap->t)
2736    {
2737    case T_H245AudioCapability_g711Alaw64k:
2738       if(dir&OOTX) txframes = audioCap->u.g711Alaw64k;
2739       else if(dir&OORX) rxframes = audioCap->u.g711Alaw64k;
2740       else{ 
2741          txframes = audioCap->u.g711Alaw64k; 
2742          rxframes = audioCap->u.g711Alaw64k; 
2743       }
2744       return ooCapabilityAddSimpleCapability(call, OO_G711ALAW64K, txframes, 
2745                             rxframes, FALSE, dir, NULL, NULL, NULL, NULL,TRUE);
2746    case T_H245AudioCapability_g711Alaw56k:
2747       if(dir&OOTX) txframes = audioCap->u.g711Alaw56k;
2748       else if(dir&OORX) rxframes = audioCap->u.g711Alaw56k;
2749       else{ 
2750          txframes = audioCap->u.g711Alaw56k; 
2751          rxframes = audioCap->u.g711Alaw56k; 
2752       }
2753       return ooCapabilityAddSimpleCapability(call, OO_G711ALAW56K, txframes, 
2754                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2755    case T_H245AudioCapability_g711Ulaw64k:
2756       if(dir&OOTX) txframes = audioCap->u.g711Ulaw64k;
2757       else if(dir&OORX) rxframes = audioCap->u.g711Ulaw64k;
2758       else{ 
2759          txframes = audioCap->u.g711Ulaw64k; 
2760          rxframes = audioCap->u.g711Ulaw64k; 
2761       }
2762       return ooCapabilityAddSimpleCapability(call, OO_G711ULAW64K, txframes, 
2763                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2764    case T_H245AudioCapability_g711Ulaw56k:
2765       if(dir&OOTX) txframes = audioCap->u.g711Ulaw56k;
2766       else if(dir&OORX) rxframes = audioCap->u.g711Ulaw56k;
2767       else{ 
2768          txframes = audioCap->u.g711Ulaw56k; 
2769          rxframes = audioCap->u.g711Ulaw56k; 
2770       }
2771       return ooCapabilityAddSimpleCapability(call, OO_G711ULAW56K, txframes, 
2772                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2773
2774 /*   case T_H245AudioCapability_g726:
2775       if(dir&OOTX) txframes = audioCap->u.g726;
2776       else if(dir&OORX) rxframes = audioCap->u.g726;
2777       else{ 
2778          txframes = audioCap->u.g726; 
2779          rxframes = audioCap->u.g726; 
2780       }
2781       return ooCapabilityAddSimpleCapability(call, OO_G726, txframes, 
2782                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2783 */
2784    case T_H245AudioCapability_nonStandard:
2785       if (audioCap->u.nonStandard && 
2786           audioCap->u.nonStandard->nonStandardIdentifier.t == 
2787            T_H245NonStandardIdentifier_h221NonStandard &&
2788           audioCap->u.nonStandard->data.numocts == sizeof("G.726-32k")-1 &&
2789           !strncmp((char *)audioCap->u.nonStandard->data.data, "G.726-32k", 
2790                    audioCap->u.nonStandard->data.numocts))
2791       return ooCapabilityAddSimpleCapability(call, OO_G726, 20, 
2792                            240, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2793
2794       if (audioCap->u.nonStandard && 
2795           audioCap->u.nonStandard->nonStandardIdentifier.t == 
2796            T_H245NonStandardIdentifier_h221NonStandard &&
2797           audioCap->u.nonStandard->data.numocts == sizeof("G726r32")-1 &&
2798           !strncmp((char *)audioCap->u.nonStandard->data.data, "G726r32", 
2799                    audioCap->u.nonStandard->data.numocts))
2800       return ooCapabilityAddSimpleCapability(call, OO_G726AAL2, 20, 
2801                            240, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2802
2803       if (audioCap->u.nonStandard && 
2804           audioCap->u.nonStandard->nonStandardIdentifier.t == 
2805            T_H245NonStandardIdentifier_h221NonStandard &&
2806           audioCap->u.nonStandard->data.numocts == sizeof("AMRNB")-1 &&
2807           !strncmp((char *)audioCap->u.nonStandard->data.data, "AMRNB", 
2808                    audioCap->u.nonStandard->data.numocts))
2809       return ooCapabilityAddSimpleCapability(call, OO_AMRNB, 4, 
2810                            4, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2811
2812       if (audioCap->u.nonStandard && 
2813           audioCap->u.nonStandard->nonStandardIdentifier.t == 
2814            T_H245NonStandardIdentifier_h221NonStandard &&
2815           audioCap->u.nonStandard->data.numocts == sizeof("Speex")-1 &&
2816           !strncmp((char *)audioCap->u.nonStandard->data.data, "Speex", 
2817                    audioCap->u.nonStandard->data.numocts))
2818       return ooCapabilityAddSimpleCapability(call, OO_SPEEX, 4, 
2819                            4, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2820       break;
2821
2822    case T_H245AudioCapability_g728:
2823       if(dir&OOTX) txframes = audioCap->u.g728;
2824       else if(dir&OORX) rxframes = audioCap->u.g728;
2825       else{ 
2826          txframes = audioCap->u.g728; 
2827          rxframes = audioCap->u.g728; 
2828       }
2829       return ooCapabilityAddSimpleCapability(call, OO_G728, txframes, 
2830                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2831
2832    case T_H245AudioCapability_g729:
2833       if(dir&OOTX) txframes = audioCap->u.g729;
2834       else if(dir&OORX) rxframes = audioCap->u.g729;
2835       else{ 
2836          txframes = audioCap->u.g729; 
2837          rxframes = audioCap->u.g729; 
2838       }
2839       return ooCapabilityAddSimpleCapability(call, OO_G729, txframes, 
2840                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2841
2842    case T_H245AudioCapability_g729AnnexA:
2843       if(dir&OOTX) txframes = audioCap->u.g729AnnexA;
2844       else if(dir&OORX) rxframes = audioCap->u.g729AnnexA;
2845       else{ 
2846          txframes = audioCap->u.g729AnnexA; 
2847          rxframes = audioCap->u.g729AnnexA; 
2848       }
2849       return ooCapabilityAddSimpleCapability(call, OO_G729A, txframes, 
2850                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2851
2852    case T_H245AudioCapability_g729wAnnexB:
2853       if(dir&OOTX) txframes = audioCap->u.g729wAnnexB;
2854       else if(dir&OORX) rxframes = audioCap->u.g729wAnnexB;
2855       else{ 
2856          txframes = audioCap->u.g729wAnnexB; 
2857          rxframes = audioCap->u.g729wAnnexB; 
2858       }
2859       return ooCapabilityAddSimpleCapability(call, OO_G729B, txframes, 
2860                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2861
2862    case T_H245AudioCapability_g7231:
2863       if(dir&OOTX) txframes = audioCap->u.g7231->maxAl_sduAudioFrames;
2864       else if(dir&OORX) rxframes = audioCap->u.g7231->maxAl_sduAudioFrames;
2865       else{ 
2866          txframes = audioCap->u.g7231->maxAl_sduAudioFrames; 
2867          rxframes = audioCap->u.g7231->maxAl_sduAudioFrames; 
2868       }
2869       return ooCapabilityAddSimpleCapability(call, OO_G7231, txframes,rxframes,
2870                                          audioCap->u.g7231->silenceSuppression,
2871                                          dir, NULL, NULL, NULL, NULL, TRUE); 
2872    case T_H245AudioCapability_gsmFullRate:
2873       return ooCapabilityAddGSMCapability(call, OO_GSMFULLRATE, 
2874             (unsigned)(audioCap->u.gsmFullRate->audioUnitSize/OO_GSMFRAMESIZE),
2875                                         audioCap->u.gsmFullRate->comfortNoise,
2876                                         audioCap->u.gsmFullRate->scrambled, 
2877                                         dir, NULL, NULL, NULL, NULL, TRUE);
2878    case T_H245AudioCapability_gsmHalfRate:
2879       return ooCapabilityAddGSMCapability(call, OO_GSMHALFRATE,
2880             (unsigned)(audioCap->u.gsmHalfRate->audioUnitSize/OO_GSMFRAMESIZE),
2881                                         audioCap->u.gsmHalfRate->comfortNoise,
2882                                         audioCap->u.gsmHalfRate->scrambled, 
2883                                         dir, NULL, NULL, NULL, NULL, TRUE);
2884    case T_H245AudioCapability_gsmEnhancedFullRate:
2885       return ooCapabilityAddGSMCapability(call, OO_GSMENHANCEDFULLRATE, 
2886    (unsigned)(audioCap->u.gsmEnhancedFullRate->audioUnitSize/OO_GSMFRAMESIZE),
2887                                 audioCap->u.gsmEnhancedFullRate->comfortNoise,
2888                                 audioCap->u.gsmEnhancedFullRate->scrambled, 
2889                                 dir, NULL, NULL, NULL, NULL, TRUE);
2890
2891    default:
2892      OOTRACEDBGA1("Unsupported audio capability type\n");
2893    
2894    }
2895
2896    return OO_OK;
2897 }
2898
2899 int ooCapabilityUpdateJointCapabilities
2900    (OOH323CallData* call, H245Capability *cap)
2901 {
2902    ooH323EpCapability * epCap = NULL, *cur = NULL;
2903    OOTRACEDBGC3("checking whether we need to add cap to joint capabilities"
2904                 "(%s, %s)\n", call->callType, call->callToken);
2905             
2906    switch(cap->t)
2907    {
2908    case T_H245Capability_receiveAudioCapability:
2909       epCap= ooIsAudioDataTypeSupported(call, cap->u.receiveAudioCapability, 
2910                                         OOTX);
2911       break;
2912    case T_H245Capability_transmitAudioCapability:
2913       epCap = ooIsAudioDataTypeSupported(call, cap->u.transmitAudioCapability,
2914                                         OORX);
2915       break;
2916    case T_H245Capability_receiveAndTransmitAudioCapability:
2917       epCap = ooIsAudioDataTypeSupported(call, cap->u.receiveAudioCapability, OOTX);
2918       if (!epCap)
2919        epCap = ooIsAudioDataTypeSupported(call, cap->u.transmitAudioCapability, OORX);
2920       break;
2921    case T_H245Capability_receiveVideoCapability:
2922       return ooCapabilityUpdateJointCapabilitiesVideo(call, 
2923                                           cap->u.receiveVideoCapability, OOTX);
2924    case T_H245Capability_transmitVideoCapability:
2925       return ooCapabilityUpdateJointCapabilitiesVideo(call, 
2926                                          cap->u.transmitVideoCapability, OORX);
2927
2928    case T_H245Capability_receiveDataApplicationCapability:
2929       epCap= ooIsT38Supported(call, cap->u.receiveDataApplicationCapability, 
2930                                         OOTX);
2931       break;
2932    case T_H245Capability_transmitDataApplicationCapability:
2933       epCap = ooIsT38Supported(call, cap->u.transmitDataApplicationCapability,
2934                                         OORX);
2935       break;
2936    case T_H245Capability_receiveAndTransmitDataApplicationCapability:
2937       epCap = ooIsT38Supported(call, cap->u.receiveAndTransmitDataApplicationCapability, OOTX);
2938       if (!epCap)
2939        epCap = ooIsT38Supported(call, cap->u.receiveAndTransmitDataApplicationCapability, OORX);
2940       break;
2941
2942
2943    case T_H245Capability_receiveUserInputCapability:
2944       if((cap->u.receiveUserInputCapability->t == 
2945                                  T_H245UserInputCapability_basicString) &&
2946          (call->dtmfmode & OO_CAP_DTMF_H245_alphanumeric))
2947       {
2948          call->jointDtmfMode |= OO_CAP_DTMF_H245_alphanumeric;
2949          return OO_OK;
2950       }
2951       else if((cap->u.receiveUserInputCapability->t ==
2952                T_H245UserInputCapability_dtmf) &&
2953                (call->dtmfmode & OO_CAP_DTMF_H245_signal))
2954       {
2955          call->jointDtmfMode |= OO_CAP_DTMF_H245_signal;
2956          return OO_OK;
2957       }
2958       //break;
2959    default:
2960      OOTRACEDBGA3("Unsupported cap type encountered. Ignoring. (%s, %s)\n", 
2961                    call->callType, call->callToken);
2962    }
2963
2964    if(epCap)
2965    {
2966       OOTRACEDBGC3("Adding cap to joint capabilities(%s, %s)\n",call->callType,
2967                    call->callToken);
2968       /* Note:we add jointCaps in remote endpoints preference order.*/
2969       if(!call->jointCaps)
2970          call->jointCaps = epCap;
2971       else {
2972          cur = call->jointCaps;
2973          while(cur->next) cur = cur->next;
2974          cur->next = epCap;
2975       }
2976
2977       return OO_OK;
2978    }
2979
2980    OOTRACEDBGC3("Not adding to joint capabilities. (%s, %s)\n", call->callType,
2981                 call->callToken);
2982    return OO_OK;
2983 }
2984
2985
2986
2987 int ooCapabilityUpdateJointCapabilitiesVideo
2988    (OOH323CallData *call, H245VideoCapability *videoCap, int dir)
2989 {
2990    switch(videoCap->t)
2991    {
2992    case T_H245VideoCapability_h263VideoCapability:
2993       return ooCapabilityUpdateJointCapabilitiesVideoH263(call, 
2994                                         videoCap->u.h263VideoCapability, dir);
2995    default:
2996       OOTRACEDBGC3("ooCapabilityUpdateJointCapabilitiesVideo - Unsupported"
2997                    "capability type. (%s, %s)\n", call->callType, 
2998                    call->callToken);
2999    }
3000    return OO_OK;
3001 }
3002
3003
3004 int ooCapabilityUpdateJointCapabilitiesVideoH263
3005    (OOH323CallData *call, H245H263VideoCapability *pH263Cap, int dir)
3006 {
3007    ooH323EpCapability *epCap = NULL, *cur = NULL;
3008    if(pH263Cap->m.sqcifMPIPresent)
3009    {
3010       epCap =  ooIsVideoDataTypeH263Supported(call, pH263Cap, dir, 
3011                                                           OO_PICFORMAT_SQCIF);
3012       if(epCap)
3013       {
3014          OOTRACEDBGC3("Adding H263-SQCIF to joint capabilities(%s, %s)\n",
3015                       call->callType, call->callToken);
3016          /* Note:we add jointCaps in remote endpoints preference order.*/
3017          if(!call->jointCaps)
3018             call->jointCaps = epCap;
3019          else {
3020             cur = call->jointCaps;
3021             while(cur->next) cur = cur->next;
3022             cur->next = epCap;
3023          }
3024
3025       }     
3026    }
3027
3028    epCap = NULL;
3029
3030    if(pH263Cap->m.qcifMPIPresent)
3031    {
3032       epCap =  ooIsVideoDataTypeH263Supported(call, pH263Cap, dir, 
3033                                                           OO_PICFORMAT_QCIF);
3034       if(epCap)
3035       {
3036          OOTRACEDBGC3("Adding H263-QCIF to joint capabilities(%s, %s)\n",
3037                       call->callType, call->callToken);
3038          /* Note:we add jointCaps in remote endpoints preference order.*/
3039          if(!call->jointCaps)
3040             call->jointCaps = epCap;
3041          else {
3042             cur = call->jointCaps;
3043             while(cur->next) cur = cur->next;
3044             cur->next = epCap;
3045          }
3046
3047       }     
3048    }
3049
3050    epCap = NULL;
3051
3052    if(pH263Cap->m.cifMPIPresent)
3053    {
3054       epCap =  ooIsVideoDataTypeH263Supported(call, pH263Cap, dir, 
3055                                                           OO_PICFORMAT_CIF);
3056       if(epCap)
3057       {
3058          OOTRACEDBGC3("Adding H263-CIF to joint capabilities(%s, %s)\n",
3059                       call->callType, call->callToken);
3060          /* Note:we add jointCaps in remote endpoints preference order.*/
3061          if(!call->jointCaps)
3062             call->jointCaps = epCap;
3063          else {
3064             cur = call->jointCaps;
3065             while(cur->next) cur = cur->next;
3066             cur->next = epCap;
3067          }
3068
3069       }     
3070    }
3071
3072    epCap = NULL;
3073
3074    if(pH263Cap->m.cif4MPIPresent)
3075    {
3076       epCap =  ooIsVideoDataTypeH263Supported(call, pH263Cap, dir, 
3077                                                           OO_PICFORMAT_CIF4);
3078       if(epCap)
3079       {
3080          OOTRACEDBGC3("Adding H263-CIF4 to joint capabilities(%s, %s)\n",
3081                       call->callType, call->callToken);
3082          /* Note:we add jointCaps in remote endpoints preference order.*/
3083          if(!call->jointCaps)
3084             call->jointCaps = epCap;
3085          else {
3086             cur = call->jointCaps;
3087             while(cur->next) cur = cur->next;
3088             cur->next = epCap;
3089          }
3090       }     
3091    }
3092
3093    epCap = NULL;
3094
3095    if(pH263Cap->m.cif16MPIPresent)
3096    {
3097       epCap =  ooIsVideoDataTypeH263Supported(call, pH263Cap, dir, 
3098                                                           OO_PICFORMAT_CIF16);
3099       if(epCap)
3100       {
3101          OOTRACEDBGC3("Adding H263-CIF16 to joint capabilities(%s, %s)\n",
3102                       call->callType, call->callToken);
3103          /* Note:we add jointCaps in remote endpoints preference order.*/
3104          if(!call->jointCaps)
3105             call->jointCaps = epCap;
3106          else {
3107             cur = call->jointCaps;
3108             while(cur->next) cur = cur->next;
3109             cur->next = epCap;
3110          }
3111
3112       }     
3113    }
3114
3115    return OO_OK;
3116 }
3117
3118 const char* ooGetCapTypeText (OOCapabilities cap)
3119 {
3120    static const char *capTypes[]={
3121       "unknown",
3122       "OO_G726",
3123       "OO_G711ALAW64K",
3124       "OO_G711ALAW56K",
3125       "OO_G711ULAW64K",
3126       "OO_G711ULAW56K",
3127       "OO_G72264K",
3128       "OO_G72256K",
3129       "OO_G72248K",
3130       "OO_G7231",
3131       "OO_G728",
3132       "OO_G729",
3133       "OO_G729ANNEXA",
3134       "OO_AMRNB",
3135       "OO_G726AAL2",
3136       "OO_G729WANNEXB",
3137       "OO_G729ANNEXAWANNEXB",
3138       "OO_G7231ANNEXC",
3139       "OO_GSMFULLRATE",
3140       "OO_GSMHALFRATE",
3141       "OO_GSMENHANCEDFULLRATE",
3142       "OO_GENERICAUDIO",
3143       "OO_G729EXTENSIONS",
3144       "OO_SPEEX",
3145       "OO_AUDIOTELEPHONYEVENT",
3146       "OO_AUDIOTONE",
3147       "OO_EXTELEM1",
3148       "OO_VIDEO_BASE",
3149       "OO_NONSTDVIDEO",
3150       "OO_H261VIDEO",
3151       "OO_H262VIDEO",
3152       "OO_H263VIDEO",
3153       "OO_IS11172VIDEO",  /* mpeg */
3154       "OO_GENERICVIDEO",
3155       "OO_EXTELEMVIDEO",
3156       "OO_T38"            /* T.38 */
3157    };
3158    return ooUtilsGetText (cap, capTypes, OONUMBEROF(capTypes));
3159 }